diff --git a/.babelrc.json b/.babelrc.json deleted file mode 100644 index 5471b198..00000000 --- a/.babelrc.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "exclude": "node_modules/**", - "presets": [ - [ - "@babel/preset-env", - { - "targets": "> 1%, not dead", - "useBuiltIns": "usage", - "corejs": 3 - } - ] - ] -} \ No newline at end of file diff --git a/.gitignore b/.gitignore index f16721ed..9c30299a 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,4 @@ node_modules /dev/Figure_S20_geo.json /dev/issue_360.html /package-lock.json +dist/ diff --git a/css/_igv-menu-popup.scss b/css/_igv-menu-popup.scss index 742f2ebd..6a3144c6 100644 --- a/css/_igv-menu-popup.scss +++ b/css/_igv-menu-popup.scss @@ -1,3 +1,8 @@ +// Variables with defaults - can be overridden via @use ... with +$igv-trackgear-grey-color: #7F7F7F !default; +$igv-trackgear-popover-border-radius: 4px !default; +$igv-trackgear-font-color: #4b4b4b !default; +$igv-trackgear-default-font-face: 'Open Sans', sans-serif !default; .jb-igv-menu-popup { position: absolute; diff --git a/css/juicebox.css b/css/juicebox.css index ee0d9def..cccc6595 100644 --- a/css/juicebox.css +++ b/css/juicebox.css @@ -1,16 +1,3 @@ -:root { - --nav-bar-label-height: 36px; - --nav-bar-widget-container-height: 36px; - --nav-bar-widget-container-margin: 4px; - --hic-scrollbar-height: 20px; - --hic-axis-height: 40px; - --track-margin: 2px; - --track-height: 36px; - --hic-viewport-width: 640px; - --hic-viewport-height: 640px; - --hic-viewport-spinner-size: 120px; -} - .jb-igv-menu-popup { position: absolute; top: 0; @@ -146,6 +133,19 @@ background-color: rgb(209, 113, 5); } +:root { + --nav-bar-label-height: 36px; + --nav-bar-widget-container-height: 36px; + --nav-bar-widget-container-margin: 4px; + --hic-scrollbar-height: 20px; + --hic-axis-height: 40px; + --track-margin: 2px; + --track-height: 36px; + --hic-viewport-width: 640px; + --hic-viewport-height: 640px; + --hic-viewport-spinner-size: 120px; +} + .hic-igv-right-hand-gutter { position: absolute; top: 0; @@ -1103,6 +1103,25 @@ div[id$=content-container] div[id$=y-tracks-y-axis-viewport-y-scrollbar] div[id$ overflow-x: hidden; overflow-y: hidden; } +div[id$=content-container] div[id$=y-tracks-y-axis-viewport-y-scrollbar] div[id$=viewport] div[id$=contact-map-canvas-container], +div[id$=content-container] div[id$=y-tracks-y-axis-viewport-y-scrollbar] div[id$=viewport] div[id$=live-contact-map-canvas-container], +div[id$=content-container] div[id$=y-tracks-y-axis-viewport-y-scrollbar] div[id$=viewport] div[id$=live-distance-map-canvas-container] { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; +} +div[id$=content-container] div[id$=y-tracks-y-axis-viewport-y-scrollbar] div[id$=viewport] div[id$=contact-map-canvas-container] canvas, +div[id$=content-container] div[id$=y-tracks-y-axis-viewport-y-scrollbar] div[id$=viewport] div[id$=live-contact-map-canvas-container] canvas, +div[id$=content-container] div[id$=y-tracks-y-axis-viewport-y-scrollbar] div[id$=viewport] div[id$=live-distance-map-canvas-container] canvas { + width: 100%; + height: 100%; +} +div[id$=content-container] div[id$=y-tracks-y-axis-viewport-y-scrollbar] div[id$=viewport] div[id$=live-contact-map-canvas-container], +div[id$=content-container] div[id$=y-tracks-y-axis-viewport-y-scrollbar] div[id$=viewport] div[id$=live-distance-map-canvas-container] { + display: none; +} div[id$=content-container] div[id$=y-tracks-y-axis-viewport-y-scrollbar] div[id$=viewport] div[id$=viewport-spinner-container] { display: table-cell; margin: auto; @@ -1265,6 +1284,4 @@ div[id$=content-container] div[id$=x-scrollbar-container] div[id$=x-axis-scrollb .igv-trackgear-container:hover { cursor: pointer; color: #444; -} - -/*# sourceMappingURL=juicebox.css.map */ +} \ No newline at end of file diff --git a/css/juicebox.css.map b/css/juicebox.css.map index 7e626521..ee8ee948 100644 --- a/css/juicebox.css.map +++ b/css/juicebox.css.map @@ -1 +1 @@ -{"version":3,"sourceRoot":"","sources":["juicebox.scss","_igv-menu-popup.scss"],"names":[],"mappings":"AAAA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;ACTF;EACE;EACA;EACA;EAEA;EAEA;EAEA;EAEA,aDgBgC;ECfhC;EACA;EACA,ODYyB;ECVzB;EAEA,eDOoC;ECNpC,cDKyB;ECJzB;EACA;EAEA;EACA;EACA;EACA;EACA;EAEA;;AAEA;EACE;;AAEA;EACE;;AAGF;EACE;EACA;;AAGF;EACE,2BDnBgC;ECoBhC,4BDpBgC;ECqBhC;EACA;EACA;;AAGF;EACE;;;AAON;EACE;EACA;EACA;;;AAGF;EAEE;EACA;EACA;EACA;EAEA;EACA,wBDhDoC;ECiDpC,yBDjDoC;ECmDpC,qBDpDyB;ECqDzB;EACA;EAEA;EAEA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA,ODpEuB;;ACuEzB;EACE;EACA;;;AAKJ;EAEE;EACA;EACA;EACA;EACA;EAEA;EACA;EAEA;;AAEA;EACE;EACA;;AAGF;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;;;AAON;EAEE;EACA;EACA;EACA;EACA;EAEA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAIF;EACE;;AAIF;EACE;;AAIF;EACE;;AAIF;EACE;;;ADUJ;EACE;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AACA;EACE;;AAEF;EACE;;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AACA;EACE;EACA;;;AAIJ;EACE;EACA;;;AAGF;EACE;EACA;EACA;EACA,OAhLe;EAiLf,QAhLgB;EAiLhB;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA,kBA1LgB;EA2LhB;EACA;EACA,oBAnMmB;EAoMnB;EACA;EACA;EACA;EACA;;AACA;EAlGA;EACA;EACA;EACA;EACA;EACA;EACA,cA7HsB;EA8HtB,YA7HgB;EA8HhB,eA9HgB;EA+HhB;;AA2FE;EACE;EACA;;AAEF;EACE;EACA;EACA;EACA;EACA;;AACA;EACE;EACA;EACA;EACA,QA/PgB;EAgQhB;EACA;;AAEF;EACE;EACA;EACA;EACA;;AAEF;AAAA;AAAA;EAGE;EACA;;AAIN;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA,eAnQoB;;AAoGtB;EACE;EACA;EACA;EACA;EACA;EACA,aAlFkB;EAmFlB;EACA,OA5FiB;EA6FjB;EACA;EACA;EACA;EACA,cAlGmB;EAmGnB;;AAmJA;EACE;EACA;EACA;EACA,OAzPe;;AA2PjB;AAAA;AAAA;EAGE;EACA,OA5PgB;;AA+PpB;EA3JA;EACA;EACA;EACA;EACA;EACA;EACA,cA7HsB;EA8HtB,YA7HgB;EA8HhB,eA9HgB;EA+HhB;;AAzDA;EACE;EACA;EACA;EACA,aAnDkB;EAoDlB;EACA,OA7DiB;;AAqQjB;EACE;;AAGJ;EAlKA;EACA;EACA;EACA;EACA;EACA;EACA,cA7HsB;EA8HtB,YA7HgB;EA8HhB,eA9HgB;EA+HhB;;AA2JE;EACE;EACA;EACA;EACA;EACA;;AACA;EACE;EACA;EACA;EACA;;AAEF;AAAA;AAAA;EAGE;EACA,OAxRc;;AAoDpB;EACE;EACA;EACA;EACA,aAnDkB;EAoDlB;EACA,OA7DiB;;AA+RjB;EACE;;AAGJ;EA5LA;EACA;EACA;EACA;EACA;EACA;EACA,cA7HsB;EA8HtB,YA7HgB;EA8HhB,eA9HgB;EA+HhB;;AAqLE;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA,cA9SiB;EA+SjB;;AAEF;AAAA;EAEE;EACA;;AAEF;EACE;;;AAIN;AAAA;AAAA;EAGE;;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,eAxVgB;;AAyVhB;EACE;EACA;EACA;EACA,OA9UiB;;AAgVnB;AAAA;AAAA;EAGE;EACA,OAjVkB;;;AAoVtB;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,cAlWmB;EAmWnB;EACA;EACA;EACA,aA9VoB;EA+VpB;EACA;;AACA;EACE;EACA;EACA;EACA;EACA;EACA;EACA,QA7ZoB;EA8ZpB;EACA;EACA;EACA;;AACA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEF;EACE;EACA;EACA,OAlYe;;AAoYjB;AAAA;AAAA;EAGE;EACA,OArYgB;;AAwYpB;EACE;EACA;EACA;EACA;EACA;EACA;EACA,QAzZ8B;EA0Z9B;EACA;EACA;EACA;EACA;;AACA;EACE;EACA;;AAGJ;EACE;EACA;EACA;EACA;EACA;EACA;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AACA;EACE;EACA;EACA;EACA;EACA;EACA;;AAEF;EACE;EACA,OAzbe;;AA2bjB;EACE;;AAEF;EACE;EACA,OArckC;EAsclC,QAtckC;EAuclC;EACA;;AAEF;EACE;;AAEF;EACE;;AAEF;EACE;;AAEF;EACE;EACA;EACA;EACA;EACA;;AACA;EACE;EACA;EACA;EACA,OAxda;;AA0df;EACE;EACA;EACA;EACA,OA9da;;AAkenB;AAAA;AAAA;EAGE;;;AAGJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AACA;EACE;EACA;EACA;EACA;EACA;EACA;EACA,QAtiBoB;;AAuiBpB;EACE;EACA;EACA,OA7fe;;AA+fjB;AAAA;AAAA;EAGE;EACA,OAhgBgB;;;AAogBtB;EACE;EACA;EACA;EACA;EACA;EACA;EACA,OA9gBmB;EA+gBnB,aAvgBoB;EAwgBpB;EACA;EACA,kBAphBoB;;AAqhBpB;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AACA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;EACA,OA3iBe;;AA4iBf;EACE;EACA;;AAEF;EACE;;AAEF;EACE;;AAEF;EACE;EACA,OArjBc;;AAyjBpB;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGJ;EACE;;AAvgBA;EACE;EACA;EACA;EACA;EACA,aA/DkB;EAgElB;EACA,OAzEiB;EA0EjB;EACA;EACA;EACA;EACA,cA/EmB;EAgFnB;;;AA6fJ;EACE;EACA;EACA;EACA;EACA;EACA;;AACA;EACE;EACA;EACA;EACA,OAvlBiB;;AAylBnB;EACE;EACA;EACA;EACA,OA7lBiB;;AAoFnB;EACE;EACA;EACA;EACA;EACA;EACA,aAlFkB;EAmFlB;EACA,OA5FiB;EA6FjB;EACA;EACA;EACA;EACA,cAlGmB;EAmGnB;;AA8fF;EACE;EACA;;AAEF;EACE;EACA;EACA;EACA,OAxmBiB;;AA0mBnB;AAAA;AAAA;EAGE;EACA,OA3mBkB;;AA6mBpB;EACE;EACA;EACA;EACA,OApnBiB;;AAsnBnB;AAAA;AAAA;EAGE;EACA,OAvnBkB;;;AA0nBtB;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AA7kBA;EACE;EACA;EACA;EACA,aAnDkB;EAoDlB;EACA,OA7DiB;;AAsoBnB;EACE;EACA;EACA;;;AAGJ;EACE;EACA;EACA;EACA;EACA;EACA;;AACA;EACE;EACA;;AA9lBF;EACE;EACA;EACA;EACA,aAnDkB;EAoDlB;EACA,OA7DiB;;AAwpBnB;EACE;;;AAGJ;EACE;EACA;EACA;EACA;EACA;EACA;;AACA;EACE;EACA;EACA;EACA;EACA;EACA;;AACA;EACE;EACA;EACA;EACA;;AAEF;AAAA;AAAA;EAGE;EACA,OAjrBgB;;AAoDpB;EACE;EACA;EACA;EACA,aAnDkB;EAoDlB;EACA,OA7DiB;;AAwrBnB;EACE;;;AAGJ;EACE;EACA;EACA;EACA;EACA;EACA,QAztBuB;EA0tBvB;;AACA;EACE,OA5tBqB;EA6tBrB;EACA;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AACA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEF;EACE;EACA;EACA;EACA;EACA;;AACA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AACA;EACE;EACA;EACA;;AAEF;EACE;EACA;;AAEF;EACE;EACA;;AAGJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,aAhwBc;EAiwBd;EACA;EACA;EACA;EACA;EACA;EACA;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAKR;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AACA;EACE;EACA;EACA;EACA;EACA;EACA;;AACA;EACE;EACA;EACA;EACA;;AACA;EACE;EACA;EACA;EACA;EACA;EACA;;AACA;EACE,aAjzBY;EAkzBZ;EACA;EACA;EACA;EACA;EACA;EACA;;AACA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAMV;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AACA;EACE;EACA;EACA;EACA;EACA;EACA,OAt3BmB;EAu3BnB;EACA;;AACA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEF;EACE;EACA;EACA;EACA;EACA;;AACA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAIN;EACE;EACA;EACA;EACA;;AACA;EACE;EACA;EACA;EACA;EACA;EACA;;AACA;EACE,aAv4BY;EAw4BZ;EACA;EACA;EACA;EACA;EACA;EACA;;AACA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAKR;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AACA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGJ;EACE;EACA;EACA;EACA;EACA,kBAl+BY;;AAm+BZ;EACE;EACA;EACA;EACA;EACA;EACA,kBA1+BiB;;AA+BvB;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,aAvCkB;EAwClB;EACA;EACA;;AAk8BF;EACE;EACA;EACA;EACA;EACA;EACA;;AACA;EACE;EACA;EACA;EACA;EACA;EACA,kBA3/BY;;AA4/BZ;EACE;EACA;EACA;EACA;EACA;EACA,kBAngCiB;;AAQvB;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,aApBkB;EAqBlB;EACA;EACA;;;AA++BJ;EACE;;;AAEF;EACE;EACA;EACA;EACA;EACA;;;AAEF;EACE;;;AAEF;EACE;EACA;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;EACA;EACA,OAllCyB;;;AAolC3B;EACE;EACA","file":"juicebox.css"} \ No newline at end of file +{"version":3,"sourceRoot":"","sources":["juicebox.scss","_igv-menu-popup.scss"],"names":[],"mappings":"AAAA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;ACTF;EACE;EACA;EACA;EAEA;EAEA;EAEA;EAEA,aDgBgC;ECfhC;EACA;EACA,ODYyB;ECVzB;EAEA,eDOoC;ECNpC,cDKyB;ECJzB;EACA;EAEA;EACA;EACA;EACA;EACA;EAEA;;AAEA;EACE;;AAEA;EACE;;AAGF;EACE;EACA;;AAGF;EACE,2BDnBgC;ECoBhC,4BDpBgC;ECqBhC;EACA;EACA;;AAGF;EACE;;;AAON;EACE;EACA;EACA;;;AAGF;EAEE;EACA;EACA;EACA;EAEA;EACA,wBDhDoC;ECiDpC,yBDjDoC;ECmDpC,qBDpDyB;ECqDzB;EACA;EAEA;EAEA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA,ODpEuB;;ACuEzB;EACE;EACA;;;AAKJ;EAEE;EACA;EACA;EACA;EACA;EAEA;EACA;EAEA;;AAEA;EACE;EACA;;AAGF;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;;;AAON;EAEE;EACA;EACA;EACA;EACA;EAEA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAIF;EACE;;AAIF;EACE;;AAIF;EACE;;AAIF;EACE;;;ADUJ;EACE;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AACA;EACE;;AAEF;EACE;;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AACA;EACE;EACA;;;AAIJ;EACE;EACA;;;AAGF;EACE;EACA;EACA;EACA,OAhLe;EAiLf,QAhLgB;EAiLhB;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA,kBA1LgB;EA2LhB;EACA;EACA,oBAnMmB;EAoMnB;EACA;EACA;EACA;EACA;;AACA;EAlGA;EACA;EACA;EACA;EACA;EACA;EACA,cA7HsB;EA8HtB,YA7HgB;EA8HhB,eA9HgB;EA+HhB;;AA2FE;EACE;EACA;;AAEF;EACE;EACA;EACA;EACA;EACA;;AACA;EACE;EACA;EACA;EACA,QA/PgB;EAgQhB;EACA;;AAEF;EACE;EACA;EACA;EACA;;AAEF;AAAA;AAAA;EAGE;EACA;;AAIN;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA,eAnQoB;;AAoGtB;EACE;EACA;EACA;EACA;EACA;EACA,aAlFkB;EAmFlB;EACA,OA5FiB;EA6FjB;EACA;EACA;EACA;EACA,cAlGmB;EAmGnB;;AAmJA;EACE;EACA;EACA;EACA,OAzPe;;AA2PjB;AAAA;AAAA;EAGE;EACA,OA5PgB;;AA+PpB;EA3JA;EACA;EACA;EACA;EACA;EACA;EACA,cA7HsB;EA8HtB,YA7HgB;EA8HhB,eA9HgB;EA+HhB;;AAzDA;EACE;EACA;EACA;EACA,aAnDkB;EAoDlB;EACA,OA7DiB;;AAqQjB;EACE;;AAGJ;EAlKA;EACA;EACA;EACA;EACA;EACA;EACA,cA7HsB;EA8HtB,YA7HgB;EA8HhB,eA9HgB;EA+HhB;;AA2JE;EACE;EACA;EACA;EACA;EACA;;AACA;EACE;EACA;EACA;EACA;;AAEF;AAAA;AAAA;EAGE;EACA,OAxRc;;AAoDpB;EACE;EACA;EACA;EACA,aAnDkB;EAoDlB;EACA,OA7DiB;;AA+RjB;EACE;;AAGJ;EA5LA;EACA;EACA;EACA;EACA;EACA;EACA,cA7HsB;EA8HtB,YA7HgB;EA8HhB,eA9HgB;EA+HhB;;AAqLE;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA,cA9SiB;EA+SjB;;AAEF;AAAA;EAEE;EACA;;AAEF;EACE;;;AAIN;AAAA;AAAA;EAGE;;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,eAxVgB;;AAyVhB;EACE;EACA;EACA;EACA,OA9UiB;;AAgVnB;AAAA;AAAA;EAGE;EACA,OAjVkB;;;AAoVtB;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,cAlWmB;EAmWnB;EACA;EACA;EACA,aA9VoB;EA+VpB;EACA;;AACA;EACE;EACA;EACA;EACA;EACA;EACA;EACA,QA7ZoB;EA8ZpB;EACA;EACA;EACA;;AACA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEF;EACE;EACA;EACA,OAlYe;;AAoYjB;AAAA;AAAA;EAGE;EACA,OArYgB;;AAwYpB;EACE;EACA;EACA;EACA;EACA;EACA;EACA,QAzZ8B;EA0Z9B;EACA;EACA;EACA;EACA;;AACA;EACE;EACA;;AAGJ;EACE;EACA;EACA;EACA;EACA;EACA;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AACA;EACE;EACA;EACA;EACA;EACA;EACA;;AAEF;EACE;EACA,OAzbe;;AA2bjB;EACE;;AAEF;EACE;EACA,OArckC;EAsclC,QAtckC;EAuclC;EACA;;AAEF;EACE;;AAEF;EACE;;AAEF;EACE;;AAEF;EACE;EACA;EACA;EACA;EACA;;AACA;EACE;EACA;EACA;EACA,OAxda;;AA0df;EACE;EACA;EACA;EACA,OA9da;;AAkenB;AAAA;AAAA;EAGE;;;AAGJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AACA;EACE;EACA;EACA;EACA;EACA;EACA;EACA,QAtiBoB;;AAuiBpB;EACE;EACA;EACA,OA7fe;;AA+fjB;AAAA;AAAA;EAGE;EACA,OAhgBgB;;;AAogBtB;EACE;EACA;EACA;EACA;EACA;EACA;EACA,OA9gBmB;EA+gBnB,aAvgBoB;EAwgBpB;EACA;EACA,kBAphBoB;;AAqhBpB;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AACA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;EACA,OA3iBe;;AA4iBf;EACE;EACA;;AAEF;EACE;;AAEF;EACE;;AAEF;EACE;EACA,OArjBc;;AAyjBpB;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGJ;EACE;;AAvgBA;EACE;EACA;EACA;EACA;EACA,aA/DkB;EAgElB;EACA,OAzEiB;EA0EjB;EACA;EACA;EACA;EACA,cA/EmB;EAgFnB;;;AA6fJ;EACE;EACA;EACA;EACA;EACA;EACA;;AACA;EACE;EACA;EACA;EACA,OAvlBiB;;AAylBnB;EACE;EACA;EACA;EACA,OA7lBiB;;AAoFnB;EACE;EACA;EACA;EACA;EACA;EACA,aAlFkB;EAmFlB;EACA,OA5FiB;EA6FjB;EACA;EACA;EACA;EACA,cAlGmB;EAmGnB;;AA8fF;EACE;EACA;;AAEF;EACE;EACA;EACA;EACA,OAxmBiB;;AA0mBnB;AAAA;AAAA;EAGE;EACA,OA3mBkB;;AA6mBpB;EACE;EACA;EACA;EACA,OApnBiB;;AAsnBnB;AAAA;AAAA;EAGE;EACA,OAvnBkB;;;AA0nBtB;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AA7kBA;EACE;EACA;EACA;EACA,aAnDkB;EAoDlB;EACA,OA7DiB;;AAsoBnB;EACE;EACA;EACA;;;AAGJ;EACE;EACA;EACA;EACA;EACA;EACA;;AACA;EACE;EACA;;AA9lBF;EACE;EACA;EACA;EACA,aAnDkB;EAoDlB;EACA,OA7DiB;;AAwpBnB;EACE;;;AAGJ;EACE;EACA;EACA;EACA;EACA;EACA;;AACA;EACE;EACA;EACA;EACA;EACA;EACA;;AACA;EACE;EACA;EACA;EACA;;AAEF;AAAA;AAAA;EAGE;EACA,OAjrBgB;;AAoDpB;EACE;EACA;EACA;EACA,aAnDkB;EAoDlB;EACA,OA7DiB;;AAwrBnB;EACE;;;AAGJ;EACE;EACA;EACA;EACA;EACA;EACA,QAztBuB;EA0tBvB;;AACA;EACE,OA5tBqB;EA6tBrB;EACA;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AACA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEF;EACE;EACA;EACA;EACA;EACA;;AACA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AACA;EACE;EACA;EACA;;AAEF;EACE;EACA;;AAEF;EACE;EACA;;AAGJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,aAhwBc;EAiwBd;EACA;EACA;EACA;EACA;EACA;EACA;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAKR;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AACA;EACE;EACA;EACA;EACA;EACA;EACA;;AACA;EACE;EACA;EACA;EACA;;AACA;EACE;EACA;EACA;EACA;EACA;EACA;;AACA;EACE,aAjzBY;EAkzBZ;EACA;EACA;EACA;EACA;EACA;EACA;;AACA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAMV;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AACA;EACE;EACA;EACA;EACA;EACA;EACA,OAt3BmB;EAu3BnB;EACA;;AACA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEF;EACE;EACA;EACA;EACA;EACA;;AACA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAIN;EACE;EACA;EACA;EACA;;AACA;EACE;EACA;EACA;EACA;EACA;EACA;;AACA;EACE,aAv4BY;EAw4BZ;EACA;EACA;EACA;EACA;EACA;EACA;;AACA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAKR;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AACA;AAAA;AAAA;EAGE;EACA;EACA;EACA;EACA;;AACA;AAAA;AAAA;EACE;EACA;;AAGJ;AAAA;EAEE;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGJ;EACE;EACA;EACA;EACA;EACA,kBAn/BY;;AAo/BZ;EACE;EACA;EACA;EACA;EACA;EACA,kBA3/BiB;;AA+BvB;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,aAvCkB;EAwClB;EACA;EACA;;AAm9BF;EACE;EACA;EACA;EACA;EACA;EACA;;AACA;EACE;EACA;EACA;EACA;EACA;EACA,kBA5gCY;;AA6gCZ;EACE;EACA;EACA;EACA;EACA;EACA,kBAphCiB;;AAQvB;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,aApBkB;EAqBlB;EACA;EACA;;;AAggCJ;EACE;;;AAEF;EACE;EACA;EACA;EACA;EACA;;;AAEF;EACE;;;AAEF;EACE;EACA;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;EACA;EACA,OAnmCyB;;;AAqmC3B;EACE;EACA","file":"juicebox.css"} \ No newline at end of file diff --git a/css/juicebox.scss b/css/juicebox.scss index d81d1c5a..bf0545ab 100644 --- a/css/juicebox.scss +++ b/css/juicebox.scss @@ -1,3 +1,10 @@ +@use "igv-menu-popup" as * with ( + $igv-trackgear-grey-color: #7F7F7F, + $igv-trackgear-popover-border-radius: 4px, + $igv-trackgear-font-color: #4b4b4b, + $igv-trackgear-default-font-face: ('Open Sans', sans-serif) +); + :root { --nav-bar-label-height: 36px; --nav-bar-widget-container-height: 36px; @@ -23,11 +30,6 @@ $track-height: var(--track-height); // $hic-color-swatch-size: 24px; -$igv-trackgear-grey-color: #7F7F7F; -$igv-trackgear-popover-border-radius: 4px; -$igv-trackgear-font-color: #4b4b4b; -$igv-trackgear-default-font-face: 'Open Sans', sans-serif; - $nav-bar-widget-height: 24px; // ::::::::::::::: Used by layoutController.js ::::::::::::::: @@ -76,8 +78,6 @@ $scrollbar-color: #efefef; $default-font-family: 'Open Sans', sans-serif; -@import "igv-menu-popup"; - @mixin x-scrollbar-label { div { display: inline-block; @@ -1009,6 +1009,23 @@ div[id$="content-container"] { height: 100%; overflow-x: hidden; overflow-y: hidden; + div[id$="contact-map-canvas-container"], + div[id$="live-contact-map-canvas-container"], + div[id$="live-distance-map-canvas-container"] { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + canvas { + width: 100%; + height: 100%; + } + } + div[id$="live-contact-map-canvas-container"], + div[id$="live-distance-map-canvas-container"] { + display: none; + } div[id$="viewport-spinner-container"] { display: table-cell; margin: auto; diff --git a/dashboard.html b/dashboard.html new file mode 100644 index 00000000..8b73e49a --- /dev/null +++ b/dashboard.html @@ -0,0 +1,202 @@ + + + + + + Juicebox.js Launch Dashboard + + + +
+
+

🚀 Juicebox.js Launch Dashboard

+

Select an example or dev file to launch

+
+ +
+
+

📚 Examples

+
    + +
+
+ +
+

🛠️ Dev Files

+
    + +
+
+
+
+ + + + + diff --git a/dist/css/img/circular-arrows-24-blue.png b/dist/css/img/circular-arrows-24-blue.png deleted file mode 100644 index e9f8c383..00000000 Binary files a/dist/css/img/circular-arrows-24-blue.png and /dev/null differ diff --git a/dist/css/img/circular-arrows-24-grey.png b/dist/css/img/circular-arrows-24-grey.png deleted file mode 100644 index bca82558..00000000 Binary files a/dist/css/img/circular-arrows-24-grey.png and /dev/null differ diff --git a/dist/css/img/matrix-diagonal-all.svg b/dist/css/img/matrix-diagonal-all.svg deleted file mode 100644 index ccb28a2f..00000000 --- a/dist/css/img/matrix-diagonal-all.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - matrix-diagonal-widget - Created with Sketch. - - diff --git a/dist/css/img/matrix-diagonal-lower.svg b/dist/css/img/matrix-diagonal-lower.svg deleted file mode 100644 index db46f82f..00000000 --- a/dist/css/img/matrix-diagonal-lower.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - matrix-diagonal-widget - Created with Sketch. - - - diff --git a/dist/css/img/matrix-diagonal-upper.svg b/dist/css/img/matrix-diagonal-upper.svg deleted file mode 100644 index 04a96351..00000000 --- a/dist/css/img/matrix-diagonal-upper.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - matrix-diagonal-widget - Created with Sketch. - - - diff --git a/dist/css/juicebox.css b/dist/css/juicebox.css deleted file mode 100644 index ee0d9def..00000000 --- a/dist/css/juicebox.css +++ /dev/null @@ -1,1270 +0,0 @@ -:root { - --nav-bar-label-height: 36px; - --nav-bar-widget-container-height: 36px; - --nav-bar-widget-container-margin: 4px; - --hic-scrollbar-height: 20px; - --hic-axis-height: 40px; - --track-margin: 2px; - --track-height: 36px; - --hic-viewport-width: 640px; - --hic-viewport-height: 640px; - --hic-viewport-spinner-size: 120px; -} - -.jb-igv-menu-popup { - position: absolute; - top: 0; - left: 0; - min-width: 132px; - z-index: 4096; - cursor: pointer; - font-family: "Open Sans", sans-serif; - font-size: small; - font-weight: 400; - color: #4b4b4b; - background: white; - border-radius: 4px; - border-color: #7F7F7F; - border-style: solid; - border-width: thin; - display: flex; - flex-flow: column; - flex-wrap: nowrap; - justify-content: flex-start; - align-items: flex-end; - text-align: left; -} -.jb-igv-menu-popup > div:not(:first-child) { - width: 100%; -} -.jb-igv-menu-popup > div:not(:first-child) > div { - background: white; -} -.jb-igv-menu-popup > div:not(:first-child) > div.context-menu { - padding-left: 4px; - padding-right: 4px; -} -.jb-igv-menu-popup > div:not(:first-child) > div:last-child { - border-bottom-left-radius: 4px; - border-bottom-right-radius: 4px; - border-bottom-color: transparent; - border-bottom-style: solid; - border-bottom-width: thin; -} -.jb-igv-menu-popup > div:not(:first-child) > div:hover { - background: #efefef; -} - -.jb-igv-menu-popup-shim { - padding-left: 8px; - padding-right: 8px; - width: unset !important; -} - -.jb-igv-menu-popup-header { - position: relative; - width: 100%; - height: 24px; - cursor: move; - border-top-color: transparent; - border-top-left-radius: 4px; - border-top-right-radius: 4px; - border-bottom-color: #7F7F7F; - border-bottom-style: solid; - border-bottom-width: thin; - background-color: #eee; - display: flex; - flex-flow: row; - flex-wrap: nowrap; - justify-content: flex-end; - align-items: center; -} -.jb-igv-menu-popup-header div { - margin-right: 4px; - height: 12px; - width: 12px; - color: #7F7F7F; -} -.jb-igv-menu-popup-header div:hover { - cursor: pointer; - color: #444; -} - -.jb-igv-menu-popup-check-container { - display: flex; - flex-flow: row; - flex-wrap: nowrap; - justify-content: flex-start; - align-items: center; - width: 100%; - height: 20px; - background-color: transparent; -} -.jb-igv-menu-popup-check-container div { - padding-top: 2px; - padding-left: 8px; -} -.jb-igv-menu-popup-check-container div:first-child { - position: relative; - width: 12px; - height: 12px; -} -.jb-igv-menu-popup-check-container div:first-child svg { - position: absolute; - width: 12px; - height: 12px; -} - -.jb-igv-menu-popup-chart { - display: flex; - flex-flow: row; - flex-wrap: nowrap; - justify-content: space-evenly; - align-items: center; - height: 16px; -} -.jb-igv-menu-popup-chart > div { - font-size: 0.75rem; - font-weight: 800; - width: 16px; - height: 16px; - line-height: 16px; - color: white; - text-align: center; - vertical-align: middle; -} -.jb-igv-menu-popup-chart > div:nth-child(1) { - background-color: rgb(0, 200, 0); -} -.jb-igv-menu-popup-chart > div:nth-child(2) { - background-color: rgb(0, 0, 200); -} -.jb-igv-menu-popup-chart > div:nth-child(3) { - background-color: rgb(255, 0, 0); -} -.jb-igv-menu-popup-chart > div:nth-child(4) { - background-color: rgb(209, 113, 5); -} - -.hic-igv-right-hand-gutter { - position: absolute; - top: 0; - right: -16px; - margin-top: 4px; - background-color: transparent; - width: unset; -} - -.igv-app-dropdown-item-cloud-storage { - display: flex; - flex-direction: row; - flex-wrap: nowrap; - justify-content: flex-start; - align-items: center; - height: 18px; - margin-top: 4px; - margin-bottom: 4px; -} -.igv-app-dropdown-item-cloud-storage div:first-child { - margin-right: 4px; -} -.igv-app-dropdown-item-cloud-storage div:last-child { - margin-left: 4px; -} - -#hic-modal-button-container { - display: flex; - flex-flow: row; - flex-wrap: nowrap; - justify-content: flex-start; - align-items: center; - margin-top: 64px; - margin-left: 32px; - height: 64px; -} -#hic-modal-button-container > div { - margin-left: 12px; - margin-right: 12px; -} - -#hic-encode-modal > .modal-dialog { - max-width: 90% !important; - width: 90% !important; -} - -.hic-root { - position: relative; - left: 0; - right: 0; - width: calc(var(--hic-scrollbar-height) + var(--hic-axis-height) + var(--hic-viewport-width)); - height: calc(var(--hic-scrollbar-height) + var(--hic-axis-height) + calc(2 * (var(--nav-bar-label-height) + var(--nav-bar-widget-container-height) + 2 * var(--nav-bar-widget-container-margin))) + var(--hic-viewport-height)); - margin: 4px; - background-color: white; - border-style: solid; - border-width: 2px; - border-color: #bfbfbf; -} - -.hic-root-prevent-interaction { - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - background-color: rgba(99, 99, 99, 0.25); - z-index: 1024; -} - -.hic-menu { - position: absolute; - bottom: 0; - left: 0; - width: 200px; - height: 100%; - z-index: 4096; - background-color: #efefef; - border-right-style: solid; - border-right-width: thin; - border-right-color: #5f5f5f; - display: flex; - flex-flow: column; - flex-wrap: nowrap; - justify-content: flex-start; - align-items: center; -} -.hic-menu .hic-chromosome-selector-widget-container { - display: flex; - flex-flow: column; - flex-wrap: nowrap; - justify-content: space-around; - align-items: flex-start; - width: 100%; - padding-left: 8px; - margin-top: 8px; - margin-bottom: 8px; - background-color: transparent; -} -.hic-menu .hic-chromosome-selector-widget-container div { - padding-top: 2px; - padding-bottom: 4px; -} -.hic-menu .hic-chromosome-selector-widget-container div { - display: flex; - flex-flow: row; - flex-wrap: nowrap; - justify-content: space-between; - align-items: flex-start; -} -.hic-menu .hic-chromosome-selector-widget-container div select { - display: block; - cursor: pointer; - width: 64px; - height: 24px; - margin-right: 8px; - direction: rtl; -} -.hic-menu .hic-chromosome-selector-widget-container div div { - width: 24px; - height: 24px; - background-image: url("img/circular-arrows-24-grey.png"); - background-repeat: no-repeat; -} -.hic-menu .hic-chromosome-selector-widget-container div div:hover, -.hic-menu .hic-chromosome-selector-widget-container div div:focus, -.hic-menu .hic-chromosome-selector-widget-container div div:active { - cursor: pointer; - background-image: url("img/circular-arrows-24-blue.png"); -} -.hic-menu .hic-colorscale-widget-container { - display: flex; - flex-flow: row; - flex-wrap: nowrap; - justify-content: space-around; - align-items: center; - width: 95%; - margin-top: calc(2 * 8px); - margin-bottom: 8px; -} -.hic-menu .hic-colorscale-widget-container input { - display: block; - margin-right: 4px; - height: calc(var(--nav-bar-widget-container-height) - 4px); - width: 96px; - padding: 4px; - font-family: "Open Sans", sans-serif; - font-weight: 400; - color: #5f5f5f; - text-align: left; - outline: none; - border-style: solid; - border-width: thin; - border-color: #a6a6a6; - background-color: white; -} -.hic-menu .hic-colorscale-widget-container i.fa { - display: block; - margin-left: 4px; - margin-right: 4px; - color: #5f5f5f; -} -.hic-menu .hic-colorscale-widget-container i.fa:hover, -.hic-menu .hic-colorscale-widget-container i.fa:focus, -.hic-menu .hic-colorscale-widget-container i.fa:active { - cursor: pointer; - color: #0f0f0f; -} -.hic-menu .hic-normalization-selector-container { - display: flex; - flex-flow: column; - flex-wrap: nowrap; - justify-content: space-around; - align-items: flex-start; - width: 100%; - padding-left: 8px; - margin-top: 8px; - margin-bottom: 8px; - background-color: transparent; -} -.hic-menu .hic-normalization-selector-container select { - display: block; - height: calc(var(--nav-bar-widget-container-height) - 4px); - width: 96px; - font-family: "Open Sans", sans-serif; - font-weight: 400; - color: #5f5f5f; -} -.hic-menu .hic-normalization-selector-container select { - width: 95%; -} -.hic-menu .hic-resolution-selector-container { - display: flex; - flex-flow: column; - flex-wrap: nowrap; - justify-content: space-around; - align-items: flex-start; - width: 100%; - padding-left: 8px; - margin-top: 8px; - margin-bottom: 8px; - background-color: transparent; -} -.hic-menu .hic-resolution-selector-container div#hic-resolution-label-container { - display: flex; - flex-flow: row; - flex-wrap: nowrap; - align-items: flex-start; - cursor: pointer; -} -.hic-menu .hic-resolution-selector-container div#hic-resolution-label-container i.fa#hic-resolution-lock { - display: block; - font-size: 12px; - padding-top: 4px; - padding-left: 5px; -} -.hic-menu .hic-resolution-selector-container div#hic-resolution-label-container i.fa:hover, -.hic-menu .hic-resolution-selector-container div#hic-resolution-label-container i.fa:focus, -.hic-menu .hic-resolution-selector-container div#hic-resolution-label-container i.fa:active { - cursor: pointer; - color: #0f0f0f; -} -.hic-menu .hic-resolution-selector-container select { - display: block; - height: calc(var(--nav-bar-widget-container-height) - 4px); - width: 96px; - font-family: "Open Sans", sans-serif; - font-weight: 400; - color: #5f5f5f; -} -.hic-menu .hic-resolution-selector-container select { - width: 95%; -} -.hic-menu .hic-annotation-presentation-button-container { - display: flex; - flex-flow: column; - flex-wrap: nowrap; - justify-content: space-around; - align-items: flex-start; - width: 100%; - padding-left: 8px; - margin-top: 8px; - margin-bottom: 8px; - background-color: transparent; -} -.hic-menu .hic-annotation-presentation-button-container button { - display: block; - width: 90%; - padding: 8px; - box-shadow: none; - border-radius: 0; - border-style: solid; - border-width: thin; - border-color: #a6a6a6; - background-color: transparent; -} -.hic-menu .hic-annotation-presentation-button-container button:hover, -.hic-menu .hic-annotation-presentation-button-container button:active { - cursor: pointer; - background-color: #dfdfdf; -} -.hic-menu .hic-annotation-presentation-button-container button:focus { - outline: none; -} - -.hic-menu > div:hover, -.hic-menu > div:focus, -.hic-menu > div:active { - cursor: pointer; -} - -.hic-menu-close-button { - display: flex; - flex-flow: row; - flex-wrap: nowrap; - justify-content: flex-end; - align-items: center; - width: 100%; - height: calc(64px / 2); - margin-top: calc(8px / 2); - margin-bottom: calc(8px / 2); - padding-right: 8px; -} -.hic-menu-close-button i.fa { - display: block; - margin-left: 4px; - margin-right: 4px; - color: #5f5f5f; -} -.hic-menu-close-button i.fa:hover, -.hic-menu-close-button i.fa:focus, -.hic-menu-close-button i.fa:active { - cursor: pointer; - color: #0f0f0f; -} - -.hic-annotation-panel-container { - display: flex; - flex-flow: column; - flex-wrap: nowrap; - align-items: flex-start; - position: absolute; - top: 25%; - left: 15%; - width: 700px; - border-style: solid; - border-width: thin; - border-color: #5f5f5f; - background-color: white; - z-index: 5000; - color: #0f0f0f; - font-family: "Open Sans", sans-serif; - font-size: 12px; - font-weight: 600; -} -.hic-annotation-panel-container .hic-annotation-panel-header { - display: flex; - flex-flow: row; - flex-wrap: nowrap; - justify-content: space-between; - align-items: center; - width: 100%; - height: 24px; - border-bottom-style: solid; - border-bottom-width: thin; - border-bottom-color: #dddddd; - background-color: #dddddd; -} -.hic-annotation-panel-container .hic-annotation-panel-header div:first-child { - display: block; - margin-top: 2px; - margin-left: 8px; - margin-right: 4px; - text-align: left; - text-overflow: ellipsis; - width: 200px; - height: 100%; -} -.hic-annotation-panel-container .hic-annotation-panel-header i.fa { - display: block; - margin-right: 4px; - color: #5f5f5f; -} -.hic-annotation-panel-container .hic-annotation-panel-header i.fa:hover, -.hic-annotation-panel-container .hic-annotation-panel-header i.fa:focus, -.hic-annotation-panel-container .hic-annotation-panel-header i.fa:active { - cursor: pointer; - color: #0f0f0f; -} -.hic-annotation-panel-container .hic-annotation-panel-load-container { - display: flex; - flex-flow: row; - flex-wrap: nowrap; - justify-content: flex-start; - align-items: center; - width: 100%; - height: 40px; - border-bottom-style: solid; - border-bottom-width: thin; - border-bottom-color: #dddddd; - font-size: 14px; - font-weight: 400; -} -.hic-annotation-panel-container .hic-annotation-panel-load-container div { - margin-left: 8px; - background-color: rgba(94, 219, 255, 0.51); -} -.hic-annotation-panel-container .hic-annotation-row-container { - display: flex; - flex-flow: column; - flex-wrap: nowrap; - justify-content: flex-start; - align-items: center; - width: 100%; -} -.hic-annotation-panel-container .hic-annotation-modal-row { - display: flex; - flex-flow: row; - flex-wrap: nowrap; - justify-content: space-between; - align-items: center; - width: 100%; - height: 40px; - background-color: white; - cursor: default; -} -.hic-annotation-panel-container .hic-annotation-modal-row > div:first-child { - display: block; - margin-left: 8px; - margin-right: 4px; - text-align: left; - text-overflow: ellipsis; - width: 384px; -} -.hic-annotation-panel-container .hic-annotation-modal-row > i.fa { - display: block; - color: #5f5f5f; -} -.hic-annotation-panel-container .hic-annotation-modal-row > i.fa:last-child { - margin-right: 32px; -} -.hic-annotation-panel-container .hic-annotation-modal-row .matrix-diagonal-widget-container { - cursor: pointer; - width: 16px; - height: 16px; - background-repeat: no-repeat; - background-size: 16px 16px; -} -.hic-annotation-panel-container .hic-annotation-modal-row .matrix-diagonal-widget-all { - background: url(img/matrix-diagonal-all.svg); -} -.hic-annotation-panel-container .hic-annotation-modal-row .matrix-diagonal-widget-lower { - background: url(img/matrix-diagonal-lower.svg); -} -.hic-annotation-panel-container .hic-annotation-modal-row .matrix-diagonal-widget-upper { - background: url(img/matrix-diagonal-upper.svg); -} -.hic-annotation-panel-container .hic-annotation-modal-row .up-down-arrow-container { - display: flex; - flex-flow: row; - flex-wrap: nowrap; - justify-content: flex-end; - align-items: center; -} -.hic-annotation-panel-container .hic-annotation-modal-row .up-down-arrow-container i.fa:first-child { - display: block; - margin-left: 32px; - margin-right: 8px; - color: #5f5f5f; -} -.hic-annotation-panel-container .hic-annotation-modal-row .up-down-arrow-container i.fa:last-child { - display: block; - margin-left: 8px; - margin-right: 32px; - color: #5f5f5f; -} -.hic-annotation-panel-container .hic-annotation-modal-row:hover, -.hic-annotation-panel-container .hic-annotation-modal-row:focus, -.hic-annotation-panel-container .hic-annotation-modal-row:active { - background-color: #f7f7f7; -} - -.hic-color-swatch-container { - position: absolute; - z-index: 4096; - display: flex; - flex-direction: row; - flex-wrap: wrap; - justify-content: flex-start; - align-items: center; - width: 100%; - background-color: white; -} -.hic-color-swatch-container div:first-child { - display: flex; - flex-flow: row; - flex-wrap: nowrap; - justify-content: flex-end; - align-items: center; - width: 100%; - height: 24px; -} -.hic-color-swatch-container div:first-child i.fa { - display: block; - margin-right: 4px; - color: #5f5f5f; -} -.hic-color-swatch-container div:first-child i.fa:hover, -.hic-color-swatch-container div:first-child i.fa:focus, -.hic-color-swatch-container div:first-child i.fa:active { - cursor: pointer; - color: #0f0f0f; -} - -.hic-navbar-container { - display: flex; - flex-flow: column; - flex-wrap: nowrap; - justify-content: flex-start; - align-items: center; - width: 100%; - color: #5f5f5f; - font-family: "Open Sans", sans-serif; - font-size: 14px; - font-weight: 400; - background-color: #f7f7f7; -} -.hic-navbar-container div[id$=hic-nav-bar-map-container] { - display: flex; - flex-flow: row; - flex-wrap: nowrap; - justify-content: space-between; - align-items: center; - width: 95%; - height: var(--nav-bar-label-height); -} -.hic-navbar-container div[id$=hic-nav-bar-map-container] div[id$=hic-nav-bar-map-label] { - height: 100%; - text-overflow: ellipsis; - white-space: nowrap; - overflow: hidden; - vertical-align: middle; - line-height: var(--nav-bar-label-height); - background-color: transparent; -} -.hic-navbar-container div[id$=hic-nav-bar-map-container] .hic-nav-bar-button-container { - height: 100%; - display: flex; - flex-flow: row; - flex-wrap: nowrap; - justify-content: flex-end; - align-items: center; - color: #5f5f5f; -} -.hic-navbar-container div[id$=hic-nav-bar-map-container] .hic-nav-bar-button-container i { - display: block; - margin-top: 8px; -} -.hic-navbar-container div[id$=hic-nav-bar-map-container] .hic-nav-bar-button-container i:first-child { - margin-right: 4px; -} -.hic-navbar-container div[id$=hic-nav-bar-map-container] .hic-nav-bar-button-container i:last-child { - margin-left: 4px; -} -.hic-navbar-container div[id$=hic-nav-bar-map-container] .hic-nav-bar-button-container i:hover { - cursor: pointer; - color: #0f0f0f; -} -.hic-navbar-container div[id$=hic-nav-bar-widget-container] { - display: flex; - flex-flow: row; - flex-wrap: nowrap; - justify-content: space-between; - align-items: center; - width: 95%; - height: var(--nav-bar-widget-container-height); - margin-top: var(--nav-bar-widget-container-margin); - margin-bottom: var(--nav-bar-widget-container-margin); -} - -.hic-chromosome-goto-container { - width: 75%; -} -.hic-chromosome-goto-container input { - display: block; - height: calc(var(--nav-bar-widget-container-height) - 4px); - width: 100%; - padding-left: 4px; - font-family: "Open Sans", sans-serif; - font-weight: 400; - color: #5f5f5f; - text-align: left; - outline: none; - border-style: solid; - border-width: thin; - border-color: #a6a6a6; - background-color: white; -} - -.hic-colorscale-widget-container { - width: 30%; - display: flex; - flex-flow: row; - flex-wrap: nowrap; - justify-content: space-between; - align-items: center; -} -.hic-colorscale-widget-container > i.fa-minus { - display: block; - margin-left: 1%; - margin-right: 1%; - color: #5f5f5f; -} -.hic-colorscale-widget-container > i.fa-plus { - display: block; - margin-left: 1%; - margin-right: 1%; - color: #5f5f5f; -} -.hic-colorscale-widget-container input { - display: block; - margin-right: 4px; - height: calc(var(--nav-bar-widget-container-height) - 4px); - width: 96px; - padding: 4px; - font-family: "Open Sans", sans-serif; - font-weight: 400; - color: #5f5f5f; - text-align: left; - outline: none; - border-style: solid; - border-width: thin; - border-color: #a6a6a6; - background-color: white; -} -.hic-colorscale-widget-container input { - width: 30%; - height: 32px; -} -.hic-colorscale-widget-container i.fa-minus { - display: block; - margin-left: 2%; - margin-right: 2%; - color: #5f5f5f; -} -.hic-colorscale-widget-container i.fa-minus:hover, -.hic-colorscale-widget-container i.fa-minus:focus, -.hic-colorscale-widget-container i.fa-minus:active { - cursor: pointer; - color: #0f0f0f; -} -.hic-colorscale-widget-container i.fa-plus { - display: block; - margin-left: 2%; - margin-right: 2%; - color: #5f5f5f; -} -.hic-colorscale-widget-container i.fa-plus:hover, -.hic-colorscale-widget-container i.fa-plus:focus, -.hic-colorscale-widget-container i.fa-plus:active { - cursor: pointer; - color: #0f0f0f; -} - -.hic-control-map-selector-container { - margin-left: 40px; - width: 20%; - display: flex; - flex-flow: row; - flex-wrap: nowrap; - justify-content: flex-start; - align-items: center; -} -.hic-control-map-selector-container select { - display: block; - height: calc(var(--nav-bar-widget-container-height) - 4px); - width: 96px; - font-family: "Open Sans", sans-serif; - font-weight: 400; - color: #5f5f5f; -} -.hic-control-map-selector-container div { - cursor: pointer; - margin-left: 6px; - margin-top: 6px; -} - -.hic-normalization-selector-container { - width: 25%; - display: flex; - flex-flow: row; - flex-wrap: nowrap; - justify-content: flex-end; - align-items: center; -} -.hic-normalization-selector-container div { - display: block; - margin-right: 6px; -} -.hic-normalization-selector-container select { - display: block; - height: calc(var(--nav-bar-widget-container-height) - 4px); - width: 96px; - font-family: "Open Sans", sans-serif; - font-weight: 400; - color: #5f5f5f; -} -.hic-normalization-selector-container select { - width: 75%; -} - -.hic-resolution-selector-container { - width: 25%; - display: flex; - flex-flow: row; - flex-wrap: nowrap; - justify-content: flex-end; - align-items: center; -} -.hic-resolution-selector-container div#hic-resolution-label-container { - display: flex; - flex-flow: row; - flex-wrap: nowrap; - align-items: flex-start; - margin-right: 6px; - cursor: pointer; -} -.hic-resolution-selector-container div#hic-resolution-label-container i.fa#hic-resolution-lock { - display: block; - font-size: 12px; - padding-top: 4px; - padding-left: 5px; -} -.hic-resolution-selector-container div#hic-resolution-label-container i.fa:hover, -.hic-resolution-selector-container div#hic-resolution-label-container i.fa:focus, -.hic-resolution-selector-container div#hic-resolution-label-container i.fa:active { - cursor: pointer; - color: #0f0f0f; -} -.hic-resolution-selector-container select { - display: block; - height: calc(var(--nav-bar-widget-container-height) - 4px); - width: 96px; - font-family: "Open Sans", sans-serif; - font-weight: 400; - color: #5f5f5f; -} -.hic-resolution-selector-container select { - width: 74%; -} - -div[id$=x-track-container] { - display: flex; - flex-flow: row; - flex-wrap: nowrap; - justify-content: flex-start; - width: 100%; - height: calc(0 * var(--track-height)); - background-color: white; -} -div[id$=x-track-container] div[id$=track-shim] { - width: calc(0 * var(--track-height)); - height: 100%; - margin-right: var(--hic-axis-height); -} -div[id$=x-track-container] div[id$=x-tracks] { - position: relative; - display: flex; - flex-flow: column; - flex-wrap: nowrap; - justify-content: flex-start; - width: calc(100% - (calc(0 * var(--track-height)) + var(--hic-axis-height) + var(--hic-scrollbar-height))); - height: 100%; - margin-right: var(--hic-scrollbar-height); -} -div[id$=x-track-container] div[id$=x-tracks] div[id$=y-track-guide] { - position: absolute; - top: 0; - left: 50%; - width: 1px; - height: 100%; - border-left-style: dotted; - border-left-width: thin; - border-left-color: rgb(32, 32, 32); - user-select: none; - -moz-user-select: none; - -webkit-user-select: none; - z-index: 666; -} -div[id$=x-track-container] div[id$=x-tracks] .x-track-canvas-container { - cursor: pointer; - position: relative; - width: 100%; - margin-right: 0; - margin-bottom: var(--track-margin); -} -div[id$=x-track-container] div[id$=x-tracks] .x-track-canvas-container .x-track-reorder-handle { - display: block; - position: absolute; - top: 0; - left: -32px; - width: 16px; - height: 100%; - background-color: transparent; -} -div[id$=x-track-container] div[id$=x-tracks] .x-track-canvas-container .x-track-reorder-handle > i { - color: #7F7F7F; - font-size: 0.8rem; - display: block; -} -div[id$=x-track-container] div[id$=x-tracks] .x-track-canvas-container .x-track-reorder-handle > i:first-child { - margin-top: 2px; - margin-bottom: 1px; -} -div[id$=x-track-container] div[id$=x-tracks] .x-track-canvas-container .x-track-reorder-handle > i:last-child { - margin-top: 1px; - margin-bottom: 2px; -} -div[id$=x-track-container] div[id$=x-tracks] .x-track-canvas-container .x-track-label { - display: inline-block; - position: absolute; - top: 0; - left: 0; - height: 22px; - width: 120px; - margin-top: calc(0.125 * var(--track-height)); - padding-left: 4px; - padding-right: 4px; - padding-top: 1px; - padding-bottom: 1px; - font-family: "Open Sans", sans-serif; - font-size: 12px; - font-weight: 400; - text-align: center; - vertical-align: top; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; -} -div[id$=x-track-container] div[id$=x-tracks] .x-track-canvas-container .x-track-spinner { - position: absolute; - top: 0; - left: 50%; - width: var(--track-height); - height: var(--track-height); - margin-left: -var(--track-height)/2; - background-color: rgba(255, 255, 255, 0); -} - -div[id$=content-container] { - display: flex; - flex-flow: column; - flex-wrap: nowrap; - justify-content: space-between; - width: 100%; - height: calc(100% - (calc(2 * (var(--nav-bar-label-height) + var(--nav-bar-widget-container-height) + 2 * var(--nav-bar-widget-container-margin))) + calc(0 * var(--track-height)))); - background-color: white; -} -div[id$=content-container] div[id$=x-axis-container] { - display: flex; - flex-flow: row; - flex-wrap: nowrap; - justify-content: flex-end; - width: 100%; - height: var(--hic-axis-height); -} -div[id$=content-container] div[id$=x-axis-container] div[id$=x-axis] { - width: calc(100% - (calc(0 * var(--track-height)) + var(--hic-axis-height) + var(--hic-scrollbar-height))); - height: 100%; - margin-right: var(--hic-scrollbar-height); - background-color: white; -} -div[id$=content-container] div[id$=x-axis-container] div[id$=x-axis] div[id$=x-axis-whole-genome-container] { - width: 100%; - height: 100%; - display: flex; - flex-flow: row; - flex-wrap: nowrap; - justify-content: flex-start; -} -div[id$=content-container] div[id$=x-axis-container] div[id$=x-axis] div[id$=x-axis-whole-genome-container] .x-axis-whole-genome-chromosome-container { - font-family: "Open Sans", sans-serif; - font-size: 8px; - font-weight: 400; - color: #444; - height: 100%; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; -} -div[id$=content-container] div[id$=x-axis-container] div[id$=x-axis] div[id$=x-axis-whole-genome-container] .x-axis-whole-genome-chromosome-container > div { - display: flex; - flex-direction: column; - flex-wrap: nowrap; - justify-content: center; - align-items: center; - width: 100%; - height: 100%; - border-left-color: #868686; - border-left-style: solid; - border-left-width: thin; -} -div[id$=content-container] div[id$=y-tracks-y-axis-viewport-y-scrollbar] { - display: flex; - flex-flow: row; - flex-wrap: nowrap; - justify-content: flex-end; - width: 100%; - height: calc(100% - (var(--hic-axis-height) + var(--hic-scrollbar-height))); - background-color: white; -} -div[id$=content-container] div[id$=y-tracks-y-axis-viewport-y-scrollbar] div[id$=y-tracks] { - position: relative; - display: flex; - flex-flow: row; - flex-wrap: nowrap; - justify-content: flex-start; - width: calc(0 * var(--track-height)); - height: 100%; - background-color: white; -} -div[id$=content-container] div[id$=y-tracks-y-axis-viewport-y-scrollbar] div[id$=y-tracks] div[id$=x-track-guide] { - position: absolute; - top: 50%; - left: 0; - width: 100%; - height: 1px; - border-top-style: dotted; - border-top-width: thin; - border-top-color: rgb(32, 32, 32); - user-select: none; - -moz-user-select: none; - -webkit-user-select: none; - z-index: 666; -} -div[id$=content-container] div[id$=y-tracks-y-axis-viewport-y-scrollbar] div[id$=y-tracks] .y-track-canvas-container { - display: block; - position: relative; - height: 100%; - margin-right: var(--track-margin); - background-color: white; -} -div[id$=content-container] div[id$=y-tracks-y-axis-viewport-y-scrollbar] div[id$=y-tracks] .y-track-canvas-container .y-track-spinner { - display: block; - position: absolute; - top: 50%; - left: 0; - width: var(--track-height); - height: var(--track-height); - margin-top: -var(--track-height)/2; - background-color: rgba(255, 255, 255, 0); -} -div[id$=content-container] div[id$=y-tracks-y-axis-viewport-y-scrollbar] div[id$=y-axis] { - width: var(--hic-axis-height); - height: 100%; - margin-bottom: var(--hic-scrollbar-height); - background-color: white; -} -div[id$=content-container] div[id$=y-tracks-y-axis-viewport-y-scrollbar] div[id$=y-axis] div[id$=y-axis-whole-genome-container] { - width: 100%; - height: 100%; - display: flex; - flex-flow: column; - flex-wrap: nowrap; - justify-content: flex-start; -} -div[id$=content-container] div[id$=y-tracks-y-axis-viewport-y-scrollbar] div[id$=y-axis] div[id$=y-axis-whole-genome-container] .y-axis-whole-genome-chromosome-container { - font-family: "Open Sans", sans-serif; - font-size: 8px; - font-weight: 400; - color: #444; - width: 100%; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; -} -div[id$=content-container] div[id$=y-tracks-y-axis-viewport-y-scrollbar] div[id$=y-axis] div[id$=y-axis-whole-genome-container] .y-axis-whole-genome-chromosome-container > div { - display: flex; - flex-direction: column; - flex-wrap: nowrap; - justify-content: center; - align-items: center; - width: 100%; - height: 100%; - border-top-color: #868686; - border-top-style: solid; - border-top-width: thin; -} -div[id$=content-container] div[id$=y-tracks-y-axis-viewport-y-scrollbar] div[id$=viewport] { - display: block; - position: relative; - left: 0; - top: 0; - width: calc(100% - (calc(0 * var(--track-height)) + var(--hic-axis-height) + var(--hic-scrollbar-height))); - height: 100%; - overflow-x: hidden; - overflow-y: hidden; -} -div[id$=content-container] div[id$=y-tracks-y-axis-viewport-y-scrollbar] div[id$=viewport] div[id$=viewport-spinner-container] { - display: table-cell; - margin: auto; - position: absolute; - top: 25%; - left: 0; - right: 0; - height: var(--hic-viewport-spinner-size); - width: var(--hic-viewport-spinner-size); - z-index: 2048; - pointer-events: none; - background-color: rgba(255, 255, 255, 0); -} -div[id$=content-container] div[id$=y-tracks-y-axis-viewport-y-scrollbar] div[id$=viewport] div[id$=sweep-zoom-container] { - display: block; - position: absolute; - top: 0; - left: 0; - width: 1px; - height: 1px; - z-index: 512; - background-color: rgba(68, 134, 247, 0.25); -} -div[id$=content-container] div[id$=y-tracks-y-axis-viewport-y-scrollbar] div[id$=viewport] div[id$=x-guide] { - position: absolute; - top: 50%; - left: 0; - width: 100%; - height: 1px; - border-top-style: dotted; - border-top-width: thin; - border-top-color: rgb(32, 32, 32); - user-select: none; - -moz-user-select: none; - -webkit-user-select: none; - z-index: 555; -} -div[id$=content-container] div[id$=y-tracks-y-axis-viewport-y-scrollbar] div[id$=viewport] div[id$=y-guide] { - position: absolute; - top: 0; - left: 50%; - width: 1px; - height: 100%; - border-left-style: dotted; - border-left-width: thin; - border-left-color: rgb(32, 32, 32); - user-select: none; - -moz-user-select: none; - -webkit-user-select: none; - z-index: 666; -} -div[id$=content-container] div[id$=y-tracks-y-axis-viewport-y-scrollbar] div[id$=y-axis-scrollbar-container] { - display: block; - position: relative; - width: var(--hic-scrollbar-height); - height: 100%; - background-color: #efefef; -} -div[id$=content-container] div[id$=y-tracks-y-axis-viewport-y-scrollbar] div[id$=y-axis-scrollbar-container] div[id$=y-axis-scrollbar] { - position: relative; - top: 25%; - height: 50%; - left: 0; - width: 100%; - background-color: #a5a5a5; -} -div[id$=content-container] div[id$=y-tracks-y-axis-viewport-y-scrollbar] div[id$=y-axis-scrollbar-container] div[id$=y-axis-scrollbar] div { - display: inline-block; - position: absolute; - top: 50%; - left: 50%; - transform: translateX(-50%) translateY(-50%) rotate(-90deg); - z-index: 512; - vertical-align: middle; - text-align: center; - line-height: var(--hic-scrollbar-height); - color: #373737; - font-family: "Open Sans", sans-serif; - font-size: medium; - font-weight: 400; - white-space: nowrap; -} -div[id$=content-container] div[id$=x-scrollbar-container] { - display: flex; - flex-flow: row; - flex-wrap: nowrap; - justify-content: flex-end; - width: 100%; - height: var(--hic-scrollbar-height); -} -div[id$=content-container] div[id$=x-scrollbar-container] div[id$=x-axis-scrollbar-container] { - display: block; - position: relative; - width: calc(100% - (calc(0 * var(--track-height)) + var(--hic-axis-height) + var(--hic-scrollbar-height))); - height: 100%; - margin-right: var(--hic-scrollbar-height); - background-color: #efefef; -} -div[id$=content-container] div[id$=x-scrollbar-container] div[id$=x-axis-scrollbar-container] div[id$=x-axis-scrollbar] { - position: relative; - left: 25%; - width: 50%; - top: 0; - height: 100%; - background-color: #a5a5a5; -} -div[id$=content-container] div[id$=x-scrollbar-container] div[id$=x-axis-scrollbar-container] div[id$=x-axis-scrollbar] div { - display: inline-block; - position: absolute; - margin: auto; - left: 0; - top: 0; - right: 0; - bottom: 0; - height: var(--hic-scrollbar-height); - width: 100%; - z-index: 512; - vertical-align: middle; - text-align: center; - line-height: var(--hic-scrollbar-height); - color: #373737; - font-family: "Open Sans", sans-serif; - font-size: medium; - font-weight: 400; - white-space: nowrap; -} - -.hic-whole-genome-chromosome-highlight { - cursor: pointer; -} - -.hic-track-menu { - position: absolute; - color: white; - width: 120px; - height: 120px; - background-color: #3a8ab4; -} - -.hic-root-selected { - border-color: #5f5f5f; -} - -.unselect { - -webkit-touch-callout: none; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; -} - -.igv-trackgear-container { - position: relative; - width: 14px; - height: 14px; - margin-left: 4px; - color: #7F7F7F; -} - -.igv-trackgear-container:hover { - cursor: pointer; - color: #444; -} - -/*# sourceMappingURL=juicebox.css.map */ diff --git a/dist/juicebox.esm.js b/dist/juicebox.esm.js deleted file mode 100644 index 1a17ee34..00000000 --- a/dist/juicebox.esm.js +++ /dev/null @@ -1,91377 +0,0 @@ -/** - * Covers string literals and String objects - * @param x - * @returns {boolean} - */ -function isString$3(x) { - return typeof x === "string" || x instanceof String -} - - -// StackOverflow: http://stackoverflow.com/a/10810674/116169 -function numberFormatter$2(rawNumber) { - - var dec = String(rawNumber).split(/[.,]/), - sep = ',', - decsep = '.'; - - return dec[0].split('').reverse().reduce(function (prev, now, i) { - return i % 3 === 0 ? prev + sep + now : prev + now; - }).split('').reverse().join('') + (dec[1] ? decsep + dec[1] : ''); -} - -const numberUnFormatter = formatedNumber => formatedNumber.split(",").join().replace(",", "", "g"); - -const splitLines$6 = function (string) { - return string.split(/\n|\r\n|\r/g); -}; - -function stripQuotes$2(str) { - if(str === undefined) { - return str; - } - if(str.startsWith("'") || str.startsWith('"')) { - str = str.substring(1); - } - if (str.endsWith("'") || str.endsWith('"')) { - str = str.substring(0, str.length - 1); - } - return str; -} - -/** - * Return the filename from the path. Example - * https://foo.com/bar.bed?param=2 => bar.bed - * @param urlOrFile - */ - -function getFilename$3(urlOrFile) { - - if (urlOrFile.name !== undefined) { - return urlOrFile.name - } else if (isString$3(urlOrFile)) { - - let index = urlOrFile.lastIndexOf("/"); - let filename = index < 0 ? urlOrFile : urlOrFile.substr(index + 1); - - //Strip parameters -- handle local files later - index = filename.indexOf("?"); - if (index > 0) { - filename = filename.substr(0, index); - } - return filename - } else { - throw Error(`Expected File or string, got ${typeof urlOrFile}`) - } -} - - -/** - * Test if object is a File or File-like object. - * - * @param object - */ -function isFile$2(object) { - if(!object) { - return false; - } - return typeof object !== 'function' && - (object instanceof File || - (object.hasOwnProperty("name") && typeof object.slice === 'function' && typeof object.arrayBuffer === 'function')) -} - -if (typeof process === 'object' && typeof window === 'undefined') { - global.atob = function (str) { - return Buffer.from(str, 'base64').toString('binary'); - }; -} - - -function parseUri$1(str) { - - var o = options$1, - m = o.parser["loose"].exec(str), - uri = {}, - i = 14; - - while (i--) uri[o.key[i]] = m[i] || ""; - - uri[o.q.name] = {}; - uri[o.key[12]].replace(o.q.parser, function ($0, $1, $2) { - if ($1) uri[o.q.name][$1] = $2; - }); - - return uri; -} - -const options$1 = { - strictMode: false, - key: ["source", "protocol", "authority", "userInfo", "user", "password", "host", "port", "relative", "path", "directory", "file", "query", "anchor"], - q: { - name: "queryKey", - parser: /(?:^|&)([^&=]*)=?([^&]*)/g - }, - parser: { - strict: /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/, - loose: /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/ - } -}; - -/*! pako 2.1.0 https://github.com/nodeca/pako @license (MIT AND Zlib) */ -// (C) 1995-2013 Jean-loup Gailly and Mark Adler -// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// 3. This notice may not be removed or altered from any source distribution. - -/* eslint-disable space-unary-ops */ - -/* Public constants ==========================================================*/ -/* ===========================================================================*/ - - -//const Z_FILTERED = 1; -//const Z_HUFFMAN_ONLY = 2; -//const Z_RLE = 3; -const Z_FIXED$1$1 = 4; -//const Z_DEFAULT_STRATEGY = 0; - -/* Possible values of the data_type field (though see inflate()) */ -const Z_BINARY$1 = 0; -const Z_TEXT$1 = 1; -//const Z_ASCII = 1; // = Z_TEXT -const Z_UNKNOWN$1$1 = 2; - -/*============================================================================*/ - - -function zero$1$2(buf) { let len = buf.length; while (--len >= 0) { buf[len] = 0; } } - -// From zutil.h - -const STORED_BLOCK$1 = 0; -const STATIC_TREES$1 = 1; -const DYN_TREES$1 = 2; -/* The three kinds of block type */ - -const MIN_MATCH$1$2 = 3; -const MAX_MATCH$1$2 = 258; -/* The minimum and maximum match lengths */ - -// From deflate.h -/* =========================================================================== - * Internal compression state. - */ - -const LENGTH_CODES$1$2 = 29; -/* number of length codes, not counting the special END_BLOCK code */ - -const LITERALS$1$2 = 256; -/* number of literal bytes 0..255 */ - -const L_CODES$1$2 = LITERALS$1$2 + 1 + LENGTH_CODES$1$2; -/* number of Literal or Length codes, including the END_BLOCK code */ - -const D_CODES$1$2 = 30; -/* number of distance codes */ - -const BL_CODES$1$1 = 19; -/* number of codes used to transfer the bit lengths */ - -const HEAP_SIZE$1$1 = 2 * L_CODES$1$2 + 1; -/* maximum heap size */ - -const MAX_BITS$1$1 = 15; -/* All codes must not exceed MAX_BITS bits */ - -const Buf_size$1 = 16; -/* size of bit buffer in bi_buf */ - - -/* =========================================================================== - * Constants - */ - -const MAX_BL_BITS$1 = 7; -/* Bit length codes must not exceed MAX_BL_BITS bits */ - -const END_BLOCK$1 = 256; -/* end of block literal code */ - -const REP_3_6$1 = 16; -/* repeat previous bit length 3-6 times (2 bits of repeat count) */ - -const REPZ_3_10$1 = 17; -/* repeat a zero length 3-10 times (3 bits of repeat count) */ - -const REPZ_11_138$1 = 18; -/* repeat a zero length 11-138 times (7 bits of repeat count) */ - -/* eslint-disable comma-spacing,array-bracket-spacing */ -const extra_lbits$1 = /* extra bits for each length code */ - new Uint8Array([0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0]); - -const extra_dbits$1 = /* extra bits for each distance code */ - new Uint8Array([0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13]); - -const extra_blbits$1 = /* extra bits for each bit length code */ - new Uint8Array([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7]); - -const bl_order$1 = - new Uint8Array([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]); -/* eslint-enable comma-spacing,array-bracket-spacing */ - -/* The lengths of the bit length codes are sent in order of decreasing - * probability, to avoid transmitting the lengths for unused bit length codes. - */ - -/* =========================================================================== - * Local data. These are initialized only once. - */ - -// We pre-fill arrays with 0 to avoid uninitialized gaps - -const DIST_CODE_LEN$2 = 512; /* see definition of array dist_code below */ - -// !!!! Use flat array instead of structure, Freq = i*2, Len = i*2+1 -const static_ltree$2 = new Array((L_CODES$1$2 + 2) * 2); -zero$1$2(static_ltree$2); -/* The static literal tree. Since the bit lengths are imposed, there is no - * need for the L_CODES extra codes used during heap construction. However - * The codes 286 and 287 are needed to build a canonical tree (see _tr_init - * below). - */ - -const static_dtree$2 = new Array(D_CODES$1$2 * 2); -zero$1$2(static_dtree$2); -/* The static distance tree. (Actually a trivial tree since all codes use - * 5 bits.) - */ - -const _dist_code$2 = new Array(DIST_CODE_LEN$2); -zero$1$2(_dist_code$2); -/* Distance codes. The first 256 values correspond to the distances - * 3 .. 258, the last 256 values correspond to the top 8 bits of - * the 15 bit distances. - */ - -const _length_code$2 = new Array(MAX_MATCH$1$2 - MIN_MATCH$1$2 + 1); -zero$1$2(_length_code$2); -/* length code for each normalized match length (0 == MIN_MATCH) */ - -const base_length$2 = new Array(LENGTH_CODES$1$2); -zero$1$2(base_length$2); -/* First normalized length for each code (0 = MIN_MATCH) */ - -const base_dist$2 = new Array(D_CODES$1$2); -zero$1$2(base_dist$2); -/* First normalized distance for each code (0 = distance of 1) */ - - -function StaticTreeDesc$1(static_tree, extra_bits, extra_base, elems, max_length) { - - this.static_tree = static_tree; /* static tree or NULL */ - this.extra_bits = extra_bits; /* extra bits for each code or NULL */ - this.extra_base = extra_base; /* base index for extra_bits */ - this.elems = elems; /* max number of elements in the tree */ - this.max_length = max_length; /* max bit length for the codes */ - - // show if `static_tree` has data or dummy - needed for monomorphic objects - this.has_stree = static_tree && static_tree.length; -} - - -let static_l_desc$1; -let static_d_desc$1; -let static_bl_desc$1; - - -function TreeDesc$1(dyn_tree, stat_desc) { - this.dyn_tree = dyn_tree; /* the dynamic tree */ - this.max_code = 0; /* largest code with non zero frequency */ - this.stat_desc = stat_desc; /* the corresponding static tree */ -} - - - -const d_code$1 = (dist) => { - - return dist < 256 ? _dist_code$2[dist] : _dist_code$2[256 + (dist >>> 7)]; -}; - - -/* =========================================================================== - * Output a short LSB first on the stream. - * IN assertion: there is enough room in pendingBuf. - */ -const put_short$1 = (s, w) => { -// put_byte(s, (uch)((w) & 0xff)); -// put_byte(s, (uch)((ush)(w) >> 8)); - s.pending_buf[s.pending++] = (w) & 0xff; - s.pending_buf[s.pending++] = (w >>> 8) & 0xff; -}; - - -/* =========================================================================== - * Send a value on a given number of bits. - * IN assertion: length <= 16 and value fits in length bits. - */ -const send_bits$1 = (s, value, length) => { - - if (s.bi_valid > (Buf_size$1 - length)) { - s.bi_buf |= (value << s.bi_valid) & 0xffff; - put_short$1(s, s.bi_buf); - s.bi_buf = value >> (Buf_size$1 - s.bi_valid); - s.bi_valid += length - Buf_size$1; - } else { - s.bi_buf |= (value << s.bi_valid) & 0xffff; - s.bi_valid += length; - } -}; - - -const send_code$1 = (s, c, tree) => { - - send_bits$1(s, tree[c * 2]/*.Code*/, tree[c * 2 + 1]/*.Len*/); -}; - - -/* =========================================================================== - * Reverse the first len bits of a code, using straightforward code (a faster - * method would use a table) - * IN assertion: 1 <= len <= 15 - */ -const bi_reverse$1 = (code, len) => { - - let res = 0; - do { - res |= code & 1; - code >>>= 1; - res <<= 1; - } while (--len > 0); - return res >>> 1; -}; - - -/* =========================================================================== - * Flush the bit buffer, keeping at most 7 bits in it. - */ -const bi_flush$1 = (s) => { - - if (s.bi_valid === 16) { - put_short$1(s, s.bi_buf); - s.bi_buf = 0; - s.bi_valid = 0; - - } else if (s.bi_valid >= 8) { - s.pending_buf[s.pending++] = s.bi_buf & 0xff; - s.bi_buf >>= 8; - s.bi_valid -= 8; - } -}; - - -/* =========================================================================== - * Compute the optimal bit lengths for a tree and update the total bit length - * for the current block. - * IN assertion: the fields freq and dad are set, heap[heap_max] and - * above are the tree nodes sorted by increasing frequency. - * OUT assertions: the field len is set to the optimal bit length, the - * array bl_count contains the frequencies for each bit length. - * The length opt_len is updated; static_len is also updated if stree is - * not null. - */ -const gen_bitlen$1 = (s, desc) => { -// deflate_state *s; -// tree_desc *desc; /* the tree descriptor */ - - const tree = desc.dyn_tree; - const max_code = desc.max_code; - const stree = desc.stat_desc.static_tree; - const has_stree = desc.stat_desc.has_stree; - const extra = desc.stat_desc.extra_bits; - const base = desc.stat_desc.extra_base; - const max_length = desc.stat_desc.max_length; - let h; /* heap index */ - let n, m; /* iterate over the tree elements */ - let bits; /* bit length */ - let xbits; /* extra bits */ - let f; /* frequency */ - let overflow = 0; /* number of elements with bit length too large */ - - for (bits = 0; bits <= MAX_BITS$1$1; bits++) { - s.bl_count[bits] = 0; - } - - /* In a first pass, compute the optimal bit lengths (which may - * overflow in the case of the bit length tree). - */ - tree[s.heap[s.heap_max] * 2 + 1]/*.Len*/ = 0; /* root of the heap */ - - for (h = s.heap_max + 1; h < HEAP_SIZE$1$1; h++) { - n = s.heap[h]; - bits = tree[tree[n * 2 + 1]/*.Dad*/ * 2 + 1]/*.Len*/ + 1; - if (bits > max_length) { - bits = max_length; - overflow++; - } - tree[n * 2 + 1]/*.Len*/ = bits; - /* We overwrite tree[n].Dad which is no longer needed */ - - if (n > max_code) { continue; } /* not a leaf node */ - - s.bl_count[bits]++; - xbits = 0; - if (n >= base) { - xbits = extra[n - base]; - } - f = tree[n * 2]/*.Freq*/; - s.opt_len += f * (bits + xbits); - if (has_stree) { - s.static_len += f * (stree[n * 2 + 1]/*.Len*/ + xbits); - } - } - if (overflow === 0) { return; } - - // Tracev((stderr,"\nbit length overflow\n")); - /* This happens for example on obj2 and pic of the Calgary corpus */ - - /* Find the first bit length which could increase: */ - do { - bits = max_length - 1; - while (s.bl_count[bits] === 0) { bits--; } - s.bl_count[bits]--; /* move one leaf down the tree */ - s.bl_count[bits + 1] += 2; /* move one overflow item as its brother */ - s.bl_count[max_length]--; - /* The brother of the overflow item also moves one step up, - * but this does not affect bl_count[max_length] - */ - overflow -= 2; - } while (overflow > 0); - - /* Now recompute all bit lengths, scanning in increasing frequency. - * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all - * lengths instead of fixing only the wrong ones. This idea is taken - * from 'ar' written by Haruhiko Okumura.) - */ - for (bits = max_length; bits !== 0; bits--) { - n = s.bl_count[bits]; - while (n !== 0) { - m = s.heap[--h]; - if (m > max_code) { continue; } - if (tree[m * 2 + 1]/*.Len*/ !== bits) { - // Tracev((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits)); - s.opt_len += (bits - tree[m * 2 + 1]/*.Len*/) * tree[m * 2]/*.Freq*/; - tree[m * 2 + 1]/*.Len*/ = bits; - } - n--; - } - } -}; - - -/* =========================================================================== - * Generate the codes for a given tree and bit counts (which need not be - * optimal). - * IN assertion: the array bl_count contains the bit length statistics for - * the given tree and the field len is set for all tree elements. - * OUT assertion: the field code is set for all tree elements of non - * zero code length. - */ -const gen_codes$1 = (tree, max_code, bl_count) => { -// ct_data *tree; /* the tree to decorate */ -// int max_code; /* largest code with non zero frequency */ -// ushf *bl_count; /* number of codes at each bit length */ - - const next_code = new Array(MAX_BITS$1$1 + 1); /* next code value for each bit length */ - let code = 0; /* running code value */ - let bits; /* bit index */ - let n; /* code index */ - - /* The distribution counts are first used to generate the code values - * without bit reversal. - */ - for (bits = 1; bits <= MAX_BITS$1$1; bits++) { - code = (code + bl_count[bits - 1]) << 1; - next_code[bits] = code; - } - /* Check that the bit counts in bl_count are consistent. The last code - * must be all ones. - */ - //Assert (code + bl_count[MAX_BITS]-1 == (1< { - - let n; /* iterates over tree elements */ - let bits; /* bit counter */ - let length; /* length value */ - let code; /* code value */ - let dist; /* distance index */ - const bl_count = new Array(MAX_BITS$1$1 + 1); - /* number of codes at each bit length for an optimal tree */ - - // do check in _tr_init() - //if (static_init_done) return; - - /* For some embedded targets, global variables are not initialized: */ -/*#ifdef NO_INIT_GLOBAL_POINTERS - static_l_desc.static_tree = static_ltree; - static_l_desc.extra_bits = extra_lbits; - static_d_desc.static_tree = static_dtree; - static_d_desc.extra_bits = extra_dbits; - static_bl_desc.extra_bits = extra_blbits; -#endif*/ - - /* Initialize the mapping length (0..255) -> length code (0..28) */ - length = 0; - for (code = 0; code < LENGTH_CODES$1$2 - 1; code++) { - base_length$2[code] = length; - for (n = 0; n < (1 << extra_lbits$1[code]); n++) { - _length_code$2[length++] = code; - } - } - //Assert (length == 256, "tr_static_init: length != 256"); - /* Note that the length 255 (match length 258) can be represented - * in two different ways: code 284 + 5 bits or code 285, so we - * overwrite length_code[255] to use the best encoding: - */ - _length_code$2[length - 1] = code; - - /* Initialize the mapping dist (0..32K) -> dist code (0..29) */ - dist = 0; - for (code = 0; code < 16; code++) { - base_dist$2[code] = dist; - for (n = 0; n < (1 << extra_dbits$1[code]); n++) { - _dist_code$2[dist++] = code; - } - } - //Assert (dist == 256, "tr_static_init: dist != 256"); - dist >>= 7; /* from now on, all distances are divided by 128 */ - for (; code < D_CODES$1$2; code++) { - base_dist$2[code] = dist << 7; - for (n = 0; n < (1 << (extra_dbits$1[code] - 7)); n++) { - _dist_code$2[256 + dist++] = code; - } - } - //Assert (dist == 256, "tr_static_init: 256+dist != 512"); - - /* Construct the codes of the static literal tree */ - for (bits = 0; bits <= MAX_BITS$1$1; bits++) { - bl_count[bits] = 0; - } - - n = 0; - while (n <= 143) { - static_ltree$2[n * 2 + 1]/*.Len*/ = 8; - n++; - bl_count[8]++; - } - while (n <= 255) { - static_ltree$2[n * 2 + 1]/*.Len*/ = 9; - n++; - bl_count[9]++; - } - while (n <= 279) { - static_ltree$2[n * 2 + 1]/*.Len*/ = 7; - n++; - bl_count[7]++; - } - while (n <= 287) { - static_ltree$2[n * 2 + 1]/*.Len*/ = 8; - n++; - bl_count[8]++; - } - /* Codes 286 and 287 do not exist, but we must include them in the - * tree construction to get a canonical Huffman tree (longest code - * all ones) - */ - gen_codes$1(static_ltree$2, L_CODES$1$2 + 1, bl_count); - - /* The static distance tree is trivial: */ - for (n = 0; n < D_CODES$1$2; n++) { - static_dtree$2[n * 2 + 1]/*.Len*/ = 5; - static_dtree$2[n * 2]/*.Code*/ = bi_reverse$1(n, 5); - } - - // Now data ready and we can init static trees - static_l_desc$1 = new StaticTreeDesc$1(static_ltree$2, extra_lbits$1, LITERALS$1$2 + 1, L_CODES$1$2, MAX_BITS$1$1); - static_d_desc$1 = new StaticTreeDesc$1(static_dtree$2, extra_dbits$1, 0, D_CODES$1$2, MAX_BITS$1$1); - static_bl_desc$1 = new StaticTreeDesc$1(new Array(0), extra_blbits$1, 0, BL_CODES$1$1, MAX_BL_BITS$1); - - //static_init_done = true; -}; - - -/* =========================================================================== - * Initialize a new block. - */ -const init_block$1 = (s) => { - - let n; /* iterates over tree elements */ - - /* Initialize the trees. */ - for (n = 0; n < L_CODES$1$2; n++) { s.dyn_ltree[n * 2]/*.Freq*/ = 0; } - for (n = 0; n < D_CODES$1$2; n++) { s.dyn_dtree[n * 2]/*.Freq*/ = 0; } - for (n = 0; n < BL_CODES$1$1; n++) { s.bl_tree[n * 2]/*.Freq*/ = 0; } - - s.dyn_ltree[END_BLOCK$1 * 2]/*.Freq*/ = 1; - s.opt_len = s.static_len = 0; - s.sym_next = s.matches = 0; -}; - - -/* =========================================================================== - * Flush the bit buffer and align the output on a byte boundary - */ -const bi_windup$1 = (s) => -{ - if (s.bi_valid > 8) { - put_short$1(s, s.bi_buf); - } else if (s.bi_valid > 0) { - //put_byte(s, (Byte)s->bi_buf); - s.pending_buf[s.pending++] = s.bi_buf; - } - s.bi_buf = 0; - s.bi_valid = 0; -}; - -/* =========================================================================== - * Compares to subtrees, using the tree depth as tie breaker when - * the subtrees have equal frequency. This minimizes the worst case length. - */ -const smaller$1 = (tree, n, m, depth) => { - - const _n2 = n * 2; - const _m2 = m * 2; - return (tree[_n2]/*.Freq*/ < tree[_m2]/*.Freq*/ || - (tree[_n2]/*.Freq*/ === tree[_m2]/*.Freq*/ && depth[n] <= depth[m])); -}; - -/* =========================================================================== - * Restore the heap property by moving down the tree starting at node k, - * exchanging a node with the smallest of its two sons if necessary, stopping - * when the heap property is re-established (each father smaller than its - * two sons). - */ -const pqdownheap$1 = (s, tree, k) => { -// deflate_state *s; -// ct_data *tree; /* the tree to restore */ -// int k; /* node to move down */ - - const v = s.heap[k]; - let j = k << 1; /* left son of k */ - while (j <= s.heap_len) { - /* Set j to the smallest of the two sons: */ - if (j < s.heap_len && - smaller$1(tree, s.heap[j + 1], s.heap[j], s.depth)) { - j++; - } - /* Exit if v is smaller than both sons */ - if (smaller$1(tree, v, s.heap[j], s.depth)) { break; } - - /* Exchange v with the smallest son */ - s.heap[k] = s.heap[j]; - k = j; - - /* And continue down the tree, setting j to the left son of k */ - j <<= 1; - } - s.heap[k] = v; -}; - - -// inlined manually -// const SMALLEST = 1; - -/* =========================================================================== - * Send the block data compressed using the given Huffman trees - */ -const compress_block$1 = (s, ltree, dtree) => { -// deflate_state *s; -// const ct_data *ltree; /* literal tree */ -// const ct_data *dtree; /* distance tree */ - - let dist; /* distance of matched string */ - let lc; /* match length or unmatched char (if dist == 0) */ - let sx = 0; /* running index in sym_buf */ - let code; /* the code to send */ - let extra; /* number of extra bits to send */ - - if (s.sym_next !== 0) { - do { - dist = s.pending_buf[s.sym_buf + sx++] & 0xff; - dist += (s.pending_buf[s.sym_buf + sx++] & 0xff) << 8; - lc = s.pending_buf[s.sym_buf + sx++]; - if (dist === 0) { - send_code$1(s, lc, ltree); /* send a literal byte */ - //Tracecv(isgraph(lc), (stderr," '%c' ", lc)); - } else { - /* Here, lc is the match length - MIN_MATCH */ - code = _length_code$2[lc]; - send_code$1(s, code + LITERALS$1$2 + 1, ltree); /* send the length code */ - extra = extra_lbits$1[code]; - if (extra !== 0) { - lc -= base_length$2[code]; - send_bits$1(s, lc, extra); /* send the extra length bits */ - } - dist--; /* dist is now the match distance - 1 */ - code = d_code$1(dist); - //Assert (code < D_CODES, "bad d_code"); - - send_code$1(s, code, dtree); /* send the distance code */ - extra = extra_dbits$1[code]; - if (extra !== 0) { - dist -= base_dist$2[code]; - send_bits$1(s, dist, extra); /* send the extra distance bits */ - } - } /* literal or match pair ? */ - - /* Check that the overlay between pending_buf and sym_buf is ok: */ - //Assert(s->pending < s->lit_bufsize + sx, "pendingBuf overflow"); - - } while (sx < s.sym_next); - } - - send_code$1(s, END_BLOCK$1, ltree); -}; - - -/* =========================================================================== - * Construct one Huffman tree and assigns the code bit strings and lengths. - * Update the total bit length for the current block. - * IN assertion: the field freq is set for all tree elements. - * OUT assertions: the fields len and code are set to the optimal bit length - * and corresponding code. The length opt_len is updated; static_len is - * also updated if stree is not null. The field max_code is set. - */ -const build_tree$1 = (s, desc) => { -// deflate_state *s; -// tree_desc *desc; /* the tree descriptor */ - - const tree = desc.dyn_tree; - const stree = desc.stat_desc.static_tree; - const has_stree = desc.stat_desc.has_stree; - const elems = desc.stat_desc.elems; - let n, m; /* iterate over heap elements */ - let max_code = -1; /* largest code with non zero frequency */ - let node; /* new node being created */ - - /* Construct the initial heap, with least frequent element in - * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. - * heap[0] is not used. - */ - s.heap_len = 0; - s.heap_max = HEAP_SIZE$1$1; - - for (n = 0; n < elems; n++) { - if (tree[n * 2]/*.Freq*/ !== 0) { - s.heap[++s.heap_len] = max_code = n; - s.depth[n] = 0; - - } else { - tree[n * 2 + 1]/*.Len*/ = 0; - } - } - - /* The pkzip format requires that at least one distance code exists, - * and that at least one bit should be sent even if there is only one - * possible code. So to avoid special checks later on we force at least - * two codes of non zero frequency. - */ - while (s.heap_len < 2) { - node = s.heap[++s.heap_len] = (max_code < 2 ? ++max_code : 0); - tree[node * 2]/*.Freq*/ = 1; - s.depth[node] = 0; - s.opt_len--; - - if (has_stree) { - s.static_len -= stree[node * 2 + 1]/*.Len*/; - } - /* node is 0 or 1 so it does not have extra bits */ - } - desc.max_code = max_code; - - /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, - * establish sub-heaps of increasing lengths: - */ - for (n = (s.heap_len >> 1/*int /2*/); n >= 1; n--) { pqdownheap$1(s, tree, n); } - - /* Construct the Huffman tree by repeatedly combining the least two - * frequent nodes. - */ - node = elems; /* next internal node of the tree */ - do { - //pqremove(s, tree, n); /* n = node of least frequency */ - /*** pqremove ***/ - n = s.heap[1/*SMALLEST*/]; - s.heap[1/*SMALLEST*/] = s.heap[s.heap_len--]; - pqdownheap$1(s, tree, 1/*SMALLEST*/); - /***/ - - m = s.heap[1/*SMALLEST*/]; /* m = node of next least frequency */ - - s.heap[--s.heap_max] = n; /* keep the nodes sorted by frequency */ - s.heap[--s.heap_max] = m; - - /* Create a new node father of n and m */ - tree[node * 2]/*.Freq*/ = tree[n * 2]/*.Freq*/ + tree[m * 2]/*.Freq*/; - s.depth[node] = (s.depth[n] >= s.depth[m] ? s.depth[n] : s.depth[m]) + 1; - tree[n * 2 + 1]/*.Dad*/ = tree[m * 2 + 1]/*.Dad*/ = node; - - /* and insert the new node in the heap */ - s.heap[1/*SMALLEST*/] = node++; - pqdownheap$1(s, tree, 1/*SMALLEST*/); - - } while (s.heap_len >= 2); - - s.heap[--s.heap_max] = s.heap[1/*SMALLEST*/]; - - /* At this point, the fields freq and dad are set. We can now - * generate the bit lengths. - */ - gen_bitlen$1(s, desc); - - /* The field len is now set, we can generate the bit codes */ - gen_codes$1(tree, max_code, s.bl_count); -}; - - -/* =========================================================================== - * Scan a literal or distance tree to determine the frequencies of the codes - * in the bit length tree. - */ -const scan_tree$1 = (s, tree, max_code) => { -// deflate_state *s; -// ct_data *tree; /* the tree to be scanned */ -// int max_code; /* and its largest code of non zero frequency */ - - let n; /* iterates over all tree elements */ - let prevlen = -1; /* last emitted length */ - let curlen; /* length of current code */ - - let nextlen = tree[0 * 2 + 1]/*.Len*/; /* length of next code */ - - let count = 0; /* repeat count of the current code */ - let max_count = 7; /* max repeat count */ - let min_count = 4; /* min repeat count */ - - if (nextlen === 0) { - max_count = 138; - min_count = 3; - } - tree[(max_code + 1) * 2 + 1]/*.Len*/ = 0xffff; /* guard */ - - for (n = 0; n <= max_code; n++) { - curlen = nextlen; - nextlen = tree[(n + 1) * 2 + 1]/*.Len*/; - - if (++count < max_count && curlen === nextlen) { - continue; - - } else if (count < min_count) { - s.bl_tree[curlen * 2]/*.Freq*/ += count; - - } else if (curlen !== 0) { - - if (curlen !== prevlen) { s.bl_tree[curlen * 2]/*.Freq*/++; } - s.bl_tree[REP_3_6$1 * 2]/*.Freq*/++; - - } else if (count <= 10) { - s.bl_tree[REPZ_3_10$1 * 2]/*.Freq*/++; - - } else { - s.bl_tree[REPZ_11_138$1 * 2]/*.Freq*/++; - } - - count = 0; - prevlen = curlen; - - if (nextlen === 0) { - max_count = 138; - min_count = 3; - - } else if (curlen === nextlen) { - max_count = 6; - min_count = 3; - - } else { - max_count = 7; - min_count = 4; - } - } -}; - - -/* =========================================================================== - * Send a literal or distance tree in compressed form, using the codes in - * bl_tree. - */ -const send_tree$1 = (s, tree, max_code) => { -// deflate_state *s; -// ct_data *tree; /* the tree to be scanned */ -// int max_code; /* and its largest code of non zero frequency */ - - let n; /* iterates over all tree elements */ - let prevlen = -1; /* last emitted length */ - let curlen; /* length of current code */ - - let nextlen = tree[0 * 2 + 1]/*.Len*/; /* length of next code */ - - let count = 0; /* repeat count of the current code */ - let max_count = 7; /* max repeat count */ - let min_count = 4; /* min repeat count */ - - /* tree[max_code+1].Len = -1; */ /* guard already set */ - if (nextlen === 0) { - max_count = 138; - min_count = 3; - } - - for (n = 0; n <= max_code; n++) { - curlen = nextlen; - nextlen = tree[(n + 1) * 2 + 1]/*.Len*/; - - if (++count < max_count && curlen === nextlen) { - continue; - - } else if (count < min_count) { - do { send_code$1(s, curlen, s.bl_tree); } while (--count !== 0); - - } else if (curlen !== 0) { - if (curlen !== prevlen) { - send_code$1(s, curlen, s.bl_tree); - count--; - } - //Assert(count >= 3 && count <= 6, " 3_6?"); - send_code$1(s, REP_3_6$1, s.bl_tree); - send_bits$1(s, count - 3, 2); - - } else if (count <= 10) { - send_code$1(s, REPZ_3_10$1, s.bl_tree); - send_bits$1(s, count - 3, 3); - - } else { - send_code$1(s, REPZ_11_138$1, s.bl_tree); - send_bits$1(s, count - 11, 7); - } - - count = 0; - prevlen = curlen; - if (nextlen === 0) { - max_count = 138; - min_count = 3; - - } else if (curlen === nextlen) { - max_count = 6; - min_count = 3; - - } else { - max_count = 7; - min_count = 4; - } - } -}; - - -/* =========================================================================== - * Construct the Huffman tree for the bit lengths and return the index in - * bl_order of the last bit length code to send. - */ -const build_bl_tree$1 = (s) => { - - let max_blindex; /* index of last bit length code of non zero freq */ - - /* Determine the bit length frequencies for literal and distance trees */ - scan_tree$1(s, s.dyn_ltree, s.l_desc.max_code); - scan_tree$1(s, s.dyn_dtree, s.d_desc.max_code); - - /* Build the bit length tree: */ - build_tree$1(s, s.bl_desc); - /* opt_len now includes the length of the tree representations, except - * the lengths of the bit lengths codes and the 5+5+4 bits for the counts. - */ - - /* Determine the number of bit length codes to send. The pkzip format - * requires that at least 4 bit length codes be sent. (appnote.txt says - * 3 but the actual value used is 4.) - */ - for (max_blindex = BL_CODES$1$1 - 1; max_blindex >= 3; max_blindex--) { - if (s.bl_tree[bl_order$1[max_blindex] * 2 + 1]/*.Len*/ !== 0) { - break; - } - } - /* Update opt_len to include the bit length tree and counts */ - s.opt_len += 3 * (max_blindex + 1) + 5 + 5 + 4; - //Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", - // s->opt_len, s->static_len)); - - return max_blindex; -}; - - -/* =========================================================================== - * Send the header for a block using dynamic Huffman trees: the counts, the - * lengths of the bit length codes, the literal tree and the distance tree. - * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. - */ -const send_all_trees$1 = (s, lcodes, dcodes, blcodes) => { -// deflate_state *s; -// int lcodes, dcodes, blcodes; /* number of codes for each tree */ - - let rank; /* index in bl_order */ - - //Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); - //Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, - // "too many codes"); - //Tracev((stderr, "\nbl counts: ")); - send_bits$1(s, lcodes - 257, 5); /* not +255 as stated in appnote.txt */ - send_bits$1(s, dcodes - 1, 5); - send_bits$1(s, blcodes - 4, 4); /* not -3 as stated in appnote.txt */ - for (rank = 0; rank < blcodes; rank++) { - //Tracev((stderr, "\nbl code %2d ", bl_order[rank])); - send_bits$1(s, s.bl_tree[bl_order$1[rank] * 2 + 1]/*.Len*/, 3); - } - //Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent)); - - send_tree$1(s, s.dyn_ltree, lcodes - 1); /* literal tree */ - //Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent)); - - send_tree$1(s, s.dyn_dtree, dcodes - 1); /* distance tree */ - //Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent)); -}; - - -/* =========================================================================== - * Check if the data type is TEXT or BINARY, using the following algorithm: - * - TEXT if the two conditions below are satisfied: - * a) There are no non-portable control characters belonging to the - * "block list" (0..6, 14..25, 28..31). - * b) There is at least one printable character belonging to the - * "allow list" (9 {TAB}, 10 {LF}, 13 {CR}, 32..255). - * - BINARY otherwise. - * - The following partially-portable control characters form a - * "gray list" that is ignored in this detection algorithm: - * (7 {BEL}, 8 {BS}, 11 {VT}, 12 {FF}, 26 {SUB}, 27 {ESC}). - * IN assertion: the fields Freq of dyn_ltree are set. - */ -const detect_data_type$1 = (s) => { - /* block_mask is the bit mask of block-listed bytes - * set bits 0..6, 14..25, and 28..31 - * 0xf3ffc07f = binary 11110011111111111100000001111111 - */ - let block_mask = 0xf3ffc07f; - let n; - - /* Check for non-textual ("block-listed") bytes. */ - for (n = 0; n <= 31; n++, block_mask >>>= 1) { - if ((block_mask & 1) && (s.dyn_ltree[n * 2]/*.Freq*/ !== 0)) { - return Z_BINARY$1; - } - } - - /* Check for textual ("allow-listed") bytes. */ - if (s.dyn_ltree[9 * 2]/*.Freq*/ !== 0 || s.dyn_ltree[10 * 2]/*.Freq*/ !== 0 || - s.dyn_ltree[13 * 2]/*.Freq*/ !== 0) { - return Z_TEXT$1; - } - for (n = 32; n < LITERALS$1$2; n++) { - if (s.dyn_ltree[n * 2]/*.Freq*/ !== 0) { - return Z_TEXT$1; - } - } - - /* There are no "block-listed" or "allow-listed" bytes: - * this stream either is empty or has tolerated ("gray-listed") bytes only. - */ - return Z_BINARY$1; -}; - - -let static_init_done$1 = false; - -/* =========================================================================== - * Initialize the tree data structures for a new zlib stream. - */ -const _tr_init$1$1 = (s) => -{ - - if (!static_init_done$1) { - tr_static_init$1(); - static_init_done$1 = true; - } - - s.l_desc = new TreeDesc$1(s.dyn_ltree, static_l_desc$1); - s.d_desc = new TreeDesc$1(s.dyn_dtree, static_d_desc$1); - s.bl_desc = new TreeDesc$1(s.bl_tree, static_bl_desc$1); - - s.bi_buf = 0; - s.bi_valid = 0; - - /* Initialize the first block of the first file: */ - init_block$1(s); -}; - - -/* =========================================================================== - * Send a stored block - */ -const _tr_stored_block$1$1 = (s, buf, stored_len, last) => { -//DeflateState *s; -//charf *buf; /* input block */ -//ulg stored_len; /* length of input block */ -//int last; /* one if this is the last block for a file */ - - send_bits$1(s, (STORED_BLOCK$1 << 1) + (last ? 1 : 0), 3); /* send block type */ - bi_windup$1(s); /* align on byte boundary */ - put_short$1(s, stored_len); - put_short$1(s, ~stored_len); - if (stored_len) { - s.pending_buf.set(s.window.subarray(buf, buf + stored_len), s.pending); - } - s.pending += stored_len; -}; - - -/* =========================================================================== - * Send one empty static block to give enough lookahead for inflate. - * This takes 10 bits, of which 7 may remain in the bit buffer. - */ -const _tr_align$1$1 = (s) => { - send_bits$1(s, STATIC_TREES$1 << 1, 3); - send_code$1(s, END_BLOCK$1, static_ltree$2); - bi_flush$1(s); -}; - - -/* =========================================================================== - * Determine the best encoding for the current block: dynamic trees, static - * trees or store, and write out the encoded block. - */ -const _tr_flush_block$1$1 = (s, buf, stored_len, last) => { -//DeflateState *s; -//charf *buf; /* input block, or NULL if too old */ -//ulg stored_len; /* length of input block */ -//int last; /* one if this is the last block for a file */ - - let opt_lenb, static_lenb; /* opt_len and static_len in bytes */ - let max_blindex = 0; /* index of last bit length code of non zero freq */ - - /* Build the Huffman trees unless a stored block is forced */ - if (s.level > 0) { - - /* Check if the file is binary or text */ - if (s.strm.data_type === Z_UNKNOWN$1$1) { - s.strm.data_type = detect_data_type$1(s); - } - - /* Construct the literal and distance trees */ - build_tree$1(s, s.l_desc); - // Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len, - // s->static_len)); - - build_tree$1(s, s.d_desc); - // Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len, - // s->static_len)); - /* At this point, opt_len and static_len are the total bit lengths of - * the compressed block data, excluding the tree representations. - */ - - /* Build the bit length tree for the above two trees, and get the index - * in bl_order of the last bit length code to send. - */ - max_blindex = build_bl_tree$1(s); - - /* Determine the best encoding. Compute the block lengths in bytes. */ - opt_lenb = (s.opt_len + 3 + 7) >>> 3; - static_lenb = (s.static_len + 3 + 7) >>> 3; - - // Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ", - // opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len, - // s->sym_next / 3)); - - if (static_lenb <= opt_lenb) { opt_lenb = static_lenb; } - - } else { - // Assert(buf != (char*)0, "lost buf"); - opt_lenb = static_lenb = stored_len + 5; /* force a stored block */ - } - - if ((stored_len + 4 <= opt_lenb) && (buf !== -1)) { - /* 4: two words for the lengths */ - - /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. - * Otherwise we can't have processed more than WSIZE input bytes since - * the last block flush, because compression would have been - * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to - * transform a block into a stored block. - */ - _tr_stored_block$1$1(s, buf, stored_len, last); - - } else if (s.strategy === Z_FIXED$1$1 || static_lenb === opt_lenb) { - - send_bits$1(s, (STATIC_TREES$1 << 1) + (last ? 1 : 0), 3); - compress_block$1(s, static_ltree$2, static_dtree$2); - - } else { - send_bits$1(s, (DYN_TREES$1 << 1) + (last ? 1 : 0), 3); - send_all_trees$1(s, s.l_desc.max_code + 1, s.d_desc.max_code + 1, max_blindex + 1); - compress_block$1(s, s.dyn_ltree, s.dyn_dtree); - } - // Assert (s->compressed_len == s->bits_sent, "bad compressed size"); - /* The above check is made mod 2^32, for files larger than 512 MB - * and uLong implemented on 32 bits. - */ - init_block$1(s); - - if (last) { - bi_windup$1(s); - } - // Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3, - // s->compressed_len-7*last)); -}; - -/* =========================================================================== - * Save the match info and tally the frequency counts. Return true if - * the current block must be flushed. - */ -const _tr_tally$1$1 = (s, dist, lc) => { -// deflate_state *s; -// unsigned dist; /* distance of matched string */ -// unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */ - - s.pending_buf[s.sym_buf + s.sym_next++] = dist; - s.pending_buf[s.sym_buf + s.sym_next++] = dist >> 8; - s.pending_buf[s.sym_buf + s.sym_next++] = lc; - if (dist === 0) { - /* lc is the unmatched char */ - s.dyn_ltree[lc * 2]/*.Freq*/++; - } else { - s.matches++; - /* Here, lc is the match length - MIN_MATCH */ - dist--; /* dist = match distance - 1 */ - //Assert((ush)dist < (ush)MAX_DIST(s) && - // (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) && - // (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match"); - - s.dyn_ltree[(_length_code$2[lc] + LITERALS$1$2 + 1) * 2]/*.Freq*/++; - s.dyn_dtree[d_code$1(dist) * 2]/*.Freq*/++; - } - - return (s.sym_next === s.sym_end); -}; - -var _tr_init_1$1 = _tr_init$1$1; -var _tr_stored_block_1$1 = _tr_stored_block$1$1; -var _tr_flush_block_1$1 = _tr_flush_block$1$1; -var _tr_tally_1$1 = _tr_tally$1$1; -var _tr_align_1$1 = _tr_align$1$1; - -var trees$1 = { - _tr_init: _tr_init_1$1, - _tr_stored_block: _tr_stored_block_1$1, - _tr_flush_block: _tr_flush_block_1$1, - _tr_tally: _tr_tally_1$1, - _tr_align: _tr_align_1$1 -}; - -// Note: adler32 takes 12% for level 0 and 2% for level 6. -// It isn't worth it to make additional optimizations as in original. -// Small size is preferable. - -// (C) 1995-2013 Jean-loup Gailly and Mark Adler -// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// 3. This notice may not be removed or altered from any source distribution. - -const adler32$2 = (adler, buf, len, pos) => { - let s1 = (adler & 0xffff) |0, - s2 = ((adler >>> 16) & 0xffff) |0, - n = 0; - - while (len !== 0) { - // Set limit ~ twice less than 5552, to keep - // s2 in 31-bits, because we force signed ints. - // in other case %= will fail. - n = len > 2000 ? 2000 : len; - len -= n; - - do { - s1 = (s1 + buf[pos++]) |0; - s2 = (s2 + s1) |0; - } while (--n); - - s1 %= 65521; - s2 %= 65521; - } - - return (s1 | (s2 << 16)) |0; -}; - - -var adler32_1$2 = adler32$2; - -// Note: we can't get significant speed boost here. -// So write code to minimize size - no pregenerated tables -// and array tools dependencies. - -// (C) 1995-2013 Jean-loup Gailly and Mark Adler -// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// 3. This notice may not be removed or altered from any source distribution. - -// Use ordinary array, since untyped makes no boost here -const makeTable$2 = () => { - let c, table = []; - - for (var n = 0; n < 256; n++) { - c = n; - for (var k = 0; k < 8; k++) { - c = ((c & 1) ? (0xEDB88320 ^ (c >>> 1)) : (c >>> 1)); - } - table[n] = c; - } - - return table; -}; - -// Create table on load. Just 255 signed longs. Not a problem. -const crcTable$2 = new Uint32Array(makeTable$2()); - - -const crc32$2 = (crc, buf, len, pos) => { - const t = crcTable$2; - const end = pos + len; - - crc ^= -1; - - for (let i = pos; i < end; i++) { - crc = (crc >>> 8) ^ t[(crc ^ buf[i]) & 0xFF]; - } - - return (crc ^ (-1)); // >>> 0; -}; - - -var crc32_1$2 = crc32$2; - -// (C) 1995-2013 Jean-loup Gailly and Mark Adler -// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// 3. This notice may not be removed or altered from any source distribution. - -var messages$2 = { - 2: 'need dictionary', /* Z_NEED_DICT 2 */ - 1: 'stream end', /* Z_STREAM_END 1 */ - 0: '', /* Z_OK 0 */ - '-1': 'file error', /* Z_ERRNO (-1) */ - '-2': 'stream error', /* Z_STREAM_ERROR (-2) */ - '-3': 'data error', /* Z_DATA_ERROR (-3) */ - '-4': 'insufficient memory', /* Z_MEM_ERROR (-4) */ - '-5': 'buffer error', /* Z_BUF_ERROR (-5) */ - '-6': 'incompatible version' /* Z_VERSION_ERROR (-6) */ -}; - -// (C) 1995-2013 Jean-loup Gailly and Mark Adler -// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// 3. This notice may not be removed or altered from any source distribution. - -var constants$2$2 = { - - /* Allowed flush values; see deflate() and inflate() below for details */ - Z_NO_FLUSH: 0, - Z_PARTIAL_FLUSH: 1, - Z_SYNC_FLUSH: 2, - Z_FULL_FLUSH: 3, - Z_FINISH: 4, - Z_BLOCK: 5, - Z_TREES: 6, - - /* Return codes for the compression/decompression functions. Negative values - * are errors, positive values are used for special but normal events. - */ - Z_OK: 0, - Z_STREAM_END: 1, - Z_NEED_DICT: 2, - Z_ERRNO: -1, - Z_STREAM_ERROR: -2, - Z_DATA_ERROR: -3, - Z_MEM_ERROR: -4, - Z_BUF_ERROR: -5, - //Z_VERSION_ERROR: -6, - - /* compression levels */ - Z_NO_COMPRESSION: 0, - Z_BEST_SPEED: 1, - Z_BEST_COMPRESSION: 9, - Z_DEFAULT_COMPRESSION: -1, - - - Z_FILTERED: 1, - Z_HUFFMAN_ONLY: 2, - Z_RLE: 3, - Z_FIXED: 4, - Z_DEFAULT_STRATEGY: 0, - - /* Possible values of the data_type field (though see inflate()) */ - Z_BINARY: 0, - Z_TEXT: 1, - //Z_ASCII: 1, // = Z_TEXT (deprecated) - Z_UNKNOWN: 2, - - /* The deflate compression method */ - Z_DEFLATED: 8 - //Z_NULL: null // Use -1 or null inline, depending on var type -}; - -// (C) 1995-2013 Jean-loup Gailly and Mark Adler -// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// 3. This notice may not be removed or altered from any source distribution. - -const { _tr_init: _tr_init$2, _tr_stored_block: _tr_stored_block$2, _tr_flush_block: _tr_flush_block$2, _tr_tally: _tr_tally$2, _tr_align: _tr_align$2 } = trees$1; - - - - -/* Public constants ==========================================================*/ -/* ===========================================================================*/ - -const { - Z_NO_FLUSH: Z_NO_FLUSH$2$1, Z_PARTIAL_FLUSH: Z_PARTIAL_FLUSH$1, Z_FULL_FLUSH: Z_FULL_FLUSH$1$1, Z_FINISH: Z_FINISH$3$1, Z_BLOCK: Z_BLOCK$1$1, - Z_OK: Z_OK$3$1, Z_STREAM_END: Z_STREAM_END$3$1, Z_STREAM_ERROR: Z_STREAM_ERROR$2$1, Z_DATA_ERROR: Z_DATA_ERROR$2$1, Z_BUF_ERROR: Z_BUF_ERROR$1$1, - Z_DEFAULT_COMPRESSION: Z_DEFAULT_COMPRESSION$1$1, - Z_FILTERED: Z_FILTERED$1, Z_HUFFMAN_ONLY: Z_HUFFMAN_ONLY$1, Z_RLE: Z_RLE$1, Z_FIXED: Z_FIXED$2, Z_DEFAULT_STRATEGY: Z_DEFAULT_STRATEGY$1$1, - Z_UNKNOWN: Z_UNKNOWN$2, - Z_DEFLATED: Z_DEFLATED$2$1 -} = constants$2$2; - -/*============================================================================*/ - - -const MAX_MEM_LEVEL$1 = 9; -/* Maximum value for memLevel in deflateInit2 */ -const MAX_WBITS$1$1 = 15; -/* 32K LZ77 window */ -const DEF_MEM_LEVEL$1 = 8; - - -const LENGTH_CODES$2 = 29; -/* number of length codes, not counting the special END_BLOCK code */ -const LITERALS$2 = 256; -/* number of literal bytes 0..255 */ -const L_CODES$2 = LITERALS$2 + 1 + LENGTH_CODES$2; -/* number of Literal or Length codes, including the END_BLOCK code */ -const D_CODES$2 = 30; -/* number of distance codes */ -const BL_CODES$2 = 19; -/* number of codes used to transfer the bit lengths */ -const HEAP_SIZE$2 = 2 * L_CODES$2 + 1; -/* maximum heap size */ -const MAX_BITS$2 = 15; -/* All codes must not exceed MAX_BITS bits */ - -const MIN_MATCH$2 = 3; -const MAX_MATCH$2 = 258; -const MIN_LOOKAHEAD$1 = (MAX_MATCH$2 + MIN_MATCH$2 + 1); - -const PRESET_DICT$1 = 0x20; - -const INIT_STATE$1 = 42; /* zlib header -> BUSY_STATE */ -//#ifdef GZIP -const GZIP_STATE$1 = 57; /* gzip header -> BUSY_STATE | EXTRA_STATE */ -//#endif -const EXTRA_STATE$1 = 69; /* gzip extra block -> NAME_STATE */ -const NAME_STATE$1 = 73; /* gzip file name -> COMMENT_STATE */ -const COMMENT_STATE$1 = 91; /* gzip comment -> HCRC_STATE */ -const HCRC_STATE$1 = 103; /* gzip header CRC -> BUSY_STATE */ -const BUSY_STATE$1 = 113; /* deflate -> FINISH_STATE */ -const FINISH_STATE$1 = 666; /* stream complete */ - -const BS_NEED_MORE$1 = 1; /* block not completed, need more input or more output */ -const BS_BLOCK_DONE$1 = 2; /* block flush performed */ -const BS_FINISH_STARTED$1 = 3; /* finish started, need only more output at next deflate */ -const BS_FINISH_DONE$1 = 4; /* finish done, accept no more input or output */ - -const OS_CODE$1 = 0x03; // Unix :) . Don't detect, use this default. - -const err$1 = (strm, errorCode) => { - strm.msg = messages$2[errorCode]; - return errorCode; -}; - -const rank$1 = (f) => { - return ((f) * 2) - ((f) > 4 ? 9 : 0); -}; - -const zero$2 = (buf) => { - let len = buf.length; while (--len >= 0) { buf[len] = 0; } -}; - -/* =========================================================================== - * Slide the hash table when sliding the window down (could be avoided with 32 - * bit values at the expense of memory usage). We slide even when level == 0 to - * keep the hash table consistent if we switch back to level > 0 later. - */ -const slide_hash$1 = (s) => { - let n, m; - let p; - let wsize = s.w_size; - - n = s.hash_size; - p = n; - do { - m = s.head[--p]; - s.head[p] = (m >= wsize ? m - wsize : 0); - } while (--n); - n = wsize; -//#ifndef FASTEST - p = n; - do { - m = s.prev[--p]; - s.prev[p] = (m >= wsize ? m - wsize : 0); - /* If n is not on any hash chain, prev[n] is garbage but - * its value will never be used. - */ - } while (--n); -//#endif -}; - -/* eslint-disable new-cap */ -let HASH_ZLIB$1 = (s, prev, data) => ((prev << s.hash_shift) ^ data) & s.hash_mask; -// This hash causes less collisions, https://github.com/nodeca/pako/issues/135 -// But breaks binary compatibility -//let HASH_FAST = (s, prev, data) => ((prev << 8) + (prev >> 8) + (data << 4)) & s.hash_mask; -let HASH$1 = HASH_ZLIB$1; - - -/* ========================================================================= - * Flush as much pending output as possible. All deflate() output, except for - * some deflate_stored() output, goes through this function so some - * applications may wish to modify it to avoid allocating a large - * strm->next_out buffer and copying into it. (See also read_buf()). - */ -const flush_pending$1 = (strm) => { - const s = strm.state; - - //_tr_flush_bits(s); - let len = s.pending; - if (len > strm.avail_out) { - len = strm.avail_out; - } - if (len === 0) { return; } - - strm.output.set(s.pending_buf.subarray(s.pending_out, s.pending_out + len), strm.next_out); - strm.next_out += len; - s.pending_out += len; - strm.total_out += len; - strm.avail_out -= len; - s.pending -= len; - if (s.pending === 0) { - s.pending_out = 0; - } -}; - - -const flush_block_only$1 = (s, last) => { - _tr_flush_block$2(s, (s.block_start >= 0 ? s.block_start : -1), s.strstart - s.block_start, last); - s.block_start = s.strstart; - flush_pending$1(s.strm); -}; - - -const put_byte$1 = (s, b) => { - s.pending_buf[s.pending++] = b; -}; - - -/* ========================================================================= - * Put a short in the pending buffer. The 16-bit value is put in MSB order. - * IN assertion: the stream state is correct and there is enough room in - * pending_buf. - */ -const putShortMSB$1 = (s, b) => { - - // put_byte(s, (Byte)(b >> 8)); -// put_byte(s, (Byte)(b & 0xff)); - s.pending_buf[s.pending++] = (b >>> 8) & 0xff; - s.pending_buf[s.pending++] = b & 0xff; -}; - - -/* =========================================================================== - * Read a new buffer from the current input stream, update the adler32 - * and total number of bytes read. All deflate() input goes through - * this function so some applications may wish to modify it to avoid - * allocating a large strm->input buffer and copying from it. - * (See also flush_pending()). - */ -const read_buf$1 = (strm, buf, start, size) => { - - let len = strm.avail_in; - - if (len > size) { len = size; } - if (len === 0) { return 0; } - - strm.avail_in -= len; - - // zmemcpy(buf, strm->next_in, len); - buf.set(strm.input.subarray(strm.next_in, strm.next_in + len), start); - if (strm.state.wrap === 1) { - strm.adler = adler32_1$2(strm.adler, buf, len, start); - } - - else if (strm.state.wrap === 2) { - strm.adler = crc32_1$2(strm.adler, buf, len, start); - } - - strm.next_in += len; - strm.total_in += len; - - return len; -}; - - -/* =========================================================================== - * Set match_start to the longest match starting at the given string and - * return its length. Matches shorter or equal to prev_length are discarded, - * in which case the result is equal to prev_length and match_start is - * garbage. - * IN assertions: cur_match is the head of the hash chain for the current - * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 - * OUT assertion: the match length is not greater than s->lookahead. - */ -const longest_match$1 = (s, cur_match) => { - - let chain_length = s.max_chain_length; /* max hash chain length */ - let scan = s.strstart; /* current string */ - let match; /* matched string */ - let len; /* length of current match */ - let best_len = s.prev_length; /* best match length so far */ - let nice_match = s.nice_match; /* stop if match long enough */ - const limit = (s.strstart > (s.w_size - MIN_LOOKAHEAD$1)) ? - s.strstart - (s.w_size - MIN_LOOKAHEAD$1) : 0/*NIL*/; - - const _win = s.window; // shortcut - - const wmask = s.w_mask; - const prev = s.prev; - - /* Stop when cur_match becomes <= limit. To simplify the code, - * we prevent matches with the string of window index 0. - */ - - const strend = s.strstart + MAX_MATCH$2; - let scan_end1 = _win[scan + best_len - 1]; - let scan_end = _win[scan + best_len]; - - /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. - * It is easy to get rid of this optimization if necessary. - */ - // Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); - - /* Do not waste too much time if we already have a good match: */ - if (s.prev_length >= s.good_match) { - chain_length >>= 2; - } - /* Do not look for matches beyond the end of the input. This is necessary - * to make deflate deterministic. - */ - if (nice_match > s.lookahead) { nice_match = s.lookahead; } - - // Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); - - do { - // Assert(cur_match < s->strstart, "no future"); - match = cur_match; - - /* Skip to next match if the match length cannot increase - * or if the match length is less than 2. Note that the checks below - * for insufficient lookahead only occur occasionally for performance - * reasons. Therefore uninitialized memory will be accessed, and - * conditional jumps will be made that depend on those values. - * However the length of the match is limited to the lookahead, so - * the output of deflate is not affected by the uninitialized values. - */ - - if (_win[match + best_len] !== scan_end || - _win[match + best_len - 1] !== scan_end1 || - _win[match] !== _win[scan] || - _win[++match] !== _win[scan + 1]) { - continue; - } - - /* The check at best_len-1 can be removed because it will be made - * again later. (This heuristic is not always a win.) - * It is not necessary to compare scan[2] and match[2] since they - * are always equal when the other bytes match, given that - * the hash keys are equal and that HASH_BITS >= 8. - */ - scan += 2; - match++; - // Assert(*scan == *match, "match[2]?"); - - /* We check for insufficient lookahead only every 8th comparison; - * the 256th check will be made at strstart+258. - */ - do { - /*jshint noempty:false*/ - } while (_win[++scan] === _win[++match] && _win[++scan] === _win[++match] && - _win[++scan] === _win[++match] && _win[++scan] === _win[++match] && - _win[++scan] === _win[++match] && _win[++scan] === _win[++match] && - _win[++scan] === _win[++match] && _win[++scan] === _win[++match] && - scan < strend); - - // Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); - - len = MAX_MATCH$2 - (strend - scan); - scan = strend - MAX_MATCH$2; - - if (len > best_len) { - s.match_start = cur_match; - best_len = len; - if (len >= nice_match) { - break; - } - scan_end1 = _win[scan + best_len - 1]; - scan_end = _win[scan + best_len]; - } - } while ((cur_match = prev[cur_match & wmask]) > limit && --chain_length !== 0); - - if (best_len <= s.lookahead) { - return best_len; - } - return s.lookahead; -}; - - -/* =========================================================================== - * Fill the window when the lookahead becomes insufficient. - * Updates strstart and lookahead. - * - * IN assertion: lookahead < MIN_LOOKAHEAD - * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD - * At least one byte has been read, or avail_in == 0; reads are - * performed for at least two bytes (required for the zip translate_eol - * option -- not supported here). - */ -const fill_window$1 = (s) => { - - const _w_size = s.w_size; - let n, more, str; - - //Assert(s->lookahead < MIN_LOOKAHEAD, "already enough lookahead"); - - do { - more = s.window_size - s.lookahead - s.strstart; - - // JS ints have 32 bit, block below not needed - /* Deal with !@#$% 64K limit: */ - //if (sizeof(int) <= 2) { - // if (more == 0 && s->strstart == 0 && s->lookahead == 0) { - // more = wsize; - // - // } else if (more == (unsigned)(-1)) { - // /* Very unlikely, but possible on 16 bit machine if - // * strstart == 0 && lookahead == 1 (input done a byte at time) - // */ - // more--; - // } - //} - - - /* If the window is almost full and there is insufficient lookahead, - * move the upper half to the lower one to make room in the upper half. - */ - if (s.strstart >= _w_size + (_w_size - MIN_LOOKAHEAD$1)) { - - s.window.set(s.window.subarray(_w_size, _w_size + _w_size - more), 0); - s.match_start -= _w_size; - s.strstart -= _w_size; - /* we now have strstart >= MAX_DIST */ - s.block_start -= _w_size; - if (s.insert > s.strstart) { - s.insert = s.strstart; - } - slide_hash$1(s); - more += _w_size; - } - if (s.strm.avail_in === 0) { - break; - } - - /* If there was no sliding: - * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && - * more == window_size - lookahead - strstart - * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) - * => more >= window_size - 2*WSIZE + 2 - * In the BIG_MEM or MMAP case (not yet supported), - * window_size == input_size + MIN_LOOKAHEAD && - * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. - * Otherwise, window_size == 2*WSIZE so more >= 2. - * If there was sliding, more >= WSIZE. So in all cases, more >= 2. - */ - //Assert(more >= 2, "more < 2"); - n = read_buf$1(s.strm, s.window, s.strstart + s.lookahead, more); - s.lookahead += n; - - /* Initialize the hash value now that we have some input: */ - if (s.lookahead + s.insert >= MIN_MATCH$2) { - str = s.strstart - s.insert; - s.ins_h = s.window[str]; - - /* UPDATE_HASH(s, s->ins_h, s->window[str + 1]); */ - s.ins_h = HASH$1(s, s.ins_h, s.window[str + 1]); -//#if MIN_MATCH != 3 -// Call update_hash() MIN_MATCH-3 more times -//#endif - while (s.insert) { - /* UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); */ - s.ins_h = HASH$1(s, s.ins_h, s.window[str + MIN_MATCH$2 - 1]); - - s.prev[str & s.w_mask] = s.head[s.ins_h]; - s.head[s.ins_h] = str; - str++; - s.insert--; - if (s.lookahead + s.insert < MIN_MATCH$2) { - break; - } - } - } - /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage, - * but this is not important since only literal bytes will be emitted. - */ - - } while (s.lookahead < MIN_LOOKAHEAD$1 && s.strm.avail_in !== 0); - - /* If the WIN_INIT bytes after the end of the current data have never been - * written, then zero those bytes in order to avoid memory check reports of - * the use of uninitialized (or uninitialised as Julian writes) bytes by - * the longest match routines. Update the high water mark for the next - * time through here. WIN_INIT is set to MAX_MATCH since the longest match - * routines allow scanning to strstart + MAX_MATCH, ignoring lookahead. - */ -// if (s.high_water < s.window_size) { -// const curr = s.strstart + s.lookahead; -// let init = 0; -// -// if (s.high_water < curr) { -// /* Previous high water mark below current data -- zero WIN_INIT -// * bytes or up to end of window, whichever is less. -// */ -// init = s.window_size - curr; -// if (init > WIN_INIT) -// init = WIN_INIT; -// zmemzero(s->window + curr, (unsigned)init); -// s->high_water = curr + init; -// } -// else if (s->high_water < (ulg)curr + WIN_INIT) { -// /* High water mark at or above current data, but below current data -// * plus WIN_INIT -- zero out to current data plus WIN_INIT, or up -// * to end of window, whichever is less. -// */ -// init = (ulg)curr + WIN_INIT - s->high_water; -// if (init > s->window_size - s->high_water) -// init = s->window_size - s->high_water; -// zmemzero(s->window + s->high_water, (unsigned)init); -// s->high_water += init; -// } -// } -// -// Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD, -// "not enough room for search"); -}; - -/* =========================================================================== - * Copy without compression as much as possible from the input stream, return - * the current block state. - * - * In case deflateParams() is used to later switch to a non-zero compression - * level, s->matches (otherwise unused when storing) keeps track of the number - * of hash table slides to perform. If s->matches is 1, then one hash table - * slide will be done when switching. If s->matches is 2, the maximum value - * allowed here, then the hash table will be cleared, since two or more slides - * is the same as a clear. - * - * deflate_stored() is written to minimize the number of times an input byte is - * copied. It is most efficient with large input and output buffers, which - * maximizes the opportunites to have a single copy from next_in to next_out. - */ -const deflate_stored$1 = (s, flush) => { - - /* Smallest worthy block size when not flushing or finishing. By default - * this is 32K. This can be as small as 507 bytes for memLevel == 1. For - * large input and output buffers, the stored block size will be larger. - */ - let min_block = s.pending_buf_size - 5 > s.w_size ? s.w_size : s.pending_buf_size - 5; - - /* Copy as many min_block or larger stored blocks directly to next_out as - * possible. If flushing, copy the remaining available input to next_out as - * stored blocks, if there is enough space. - */ - let len, left, have, last = 0; - let used = s.strm.avail_in; - do { - /* Set len to the maximum size block that we can copy directly with the - * available input data and output space. Set left to how much of that - * would be copied from what's left in the window. - */ - len = 65535/* MAX_STORED */; /* maximum deflate stored block length */ - have = (s.bi_valid + 42) >> 3; /* number of header bytes */ - if (s.strm.avail_out < have) { /* need room for header */ - break; - } - /* maximum stored block length that will fit in avail_out: */ - have = s.strm.avail_out - have; - left = s.strstart - s.block_start; /* bytes left in window */ - if (len > left + s.strm.avail_in) { - len = left + s.strm.avail_in; /* limit len to the input */ - } - if (len > have) { - len = have; /* limit len to the output */ - } - - /* If the stored block would be less than min_block in length, or if - * unable to copy all of the available input when flushing, then try - * copying to the window and the pending buffer instead. Also don't - * write an empty block when flushing -- deflate() does that. - */ - if (len < min_block && ((len === 0 && flush !== Z_FINISH$3$1) || - flush === Z_NO_FLUSH$2$1 || - len !== left + s.strm.avail_in)) { - break; - } - - /* Make a dummy stored block in pending to get the header bytes, - * including any pending bits. This also updates the debugging counts. - */ - last = flush === Z_FINISH$3$1 && len === left + s.strm.avail_in ? 1 : 0; - _tr_stored_block$2(s, 0, 0, last); - - /* Replace the lengths in the dummy stored block with len. */ - s.pending_buf[s.pending - 4] = len; - s.pending_buf[s.pending - 3] = len >> 8; - s.pending_buf[s.pending - 2] = ~len; - s.pending_buf[s.pending - 1] = ~len >> 8; - - /* Write the stored block header bytes. */ - flush_pending$1(s.strm); - -//#ifdef ZLIB_DEBUG -// /* Update debugging counts for the data about to be copied. */ -// s->compressed_len += len << 3; -// s->bits_sent += len << 3; -//#endif - - /* Copy uncompressed bytes from the window to next_out. */ - if (left) { - if (left > len) { - left = len; - } - //zmemcpy(s->strm->next_out, s->window + s->block_start, left); - s.strm.output.set(s.window.subarray(s.block_start, s.block_start + left), s.strm.next_out); - s.strm.next_out += left; - s.strm.avail_out -= left; - s.strm.total_out += left; - s.block_start += left; - len -= left; - } - - /* Copy uncompressed bytes directly from next_in to next_out, updating - * the check value. - */ - if (len) { - read_buf$1(s.strm, s.strm.output, s.strm.next_out, len); - s.strm.next_out += len; - s.strm.avail_out -= len; - s.strm.total_out += len; - } - } while (last === 0); - - /* Update the sliding window with the last s->w_size bytes of the copied - * data, or append all of the copied data to the existing window if less - * than s->w_size bytes were copied. Also update the number of bytes to - * insert in the hash tables, in the event that deflateParams() switches to - * a non-zero compression level. - */ - used -= s.strm.avail_in; /* number of input bytes directly copied */ - if (used) { - /* If any input was used, then no unused input remains in the window, - * therefore s->block_start == s->strstart. - */ - if (used >= s.w_size) { /* supplant the previous history */ - s.matches = 2; /* clear hash */ - //zmemcpy(s->window, s->strm->next_in - s->w_size, s->w_size); - s.window.set(s.strm.input.subarray(s.strm.next_in - s.w_size, s.strm.next_in), 0); - s.strstart = s.w_size; - s.insert = s.strstart; - } - else { - if (s.window_size - s.strstart <= used) { - /* Slide the window down. */ - s.strstart -= s.w_size; - //zmemcpy(s->window, s->window + s->w_size, s->strstart); - s.window.set(s.window.subarray(s.w_size, s.w_size + s.strstart), 0); - if (s.matches < 2) { - s.matches++; /* add a pending slide_hash() */ - } - if (s.insert > s.strstart) { - s.insert = s.strstart; - } - } - //zmemcpy(s->window + s->strstart, s->strm->next_in - used, used); - s.window.set(s.strm.input.subarray(s.strm.next_in - used, s.strm.next_in), s.strstart); - s.strstart += used; - s.insert += used > s.w_size - s.insert ? s.w_size - s.insert : used; - } - s.block_start = s.strstart; - } - if (s.high_water < s.strstart) { - s.high_water = s.strstart; - } - - /* If the last block was written to next_out, then done. */ - if (last) { - return BS_FINISH_DONE$1; - } - - /* If flushing and all input has been consumed, then done. */ - if (flush !== Z_NO_FLUSH$2$1 && flush !== Z_FINISH$3$1 && - s.strm.avail_in === 0 && s.strstart === s.block_start) { - return BS_BLOCK_DONE$1; - } - - /* Fill the window with any remaining input. */ - have = s.window_size - s.strstart; - if (s.strm.avail_in > have && s.block_start >= s.w_size) { - /* Slide the window down. */ - s.block_start -= s.w_size; - s.strstart -= s.w_size; - //zmemcpy(s->window, s->window + s->w_size, s->strstart); - s.window.set(s.window.subarray(s.w_size, s.w_size + s.strstart), 0); - if (s.matches < 2) { - s.matches++; /* add a pending slide_hash() */ - } - have += s.w_size; /* more space now */ - if (s.insert > s.strstart) { - s.insert = s.strstart; - } - } - if (have > s.strm.avail_in) { - have = s.strm.avail_in; - } - if (have) { - read_buf$1(s.strm, s.window, s.strstart, have); - s.strstart += have; - s.insert += have > s.w_size - s.insert ? s.w_size - s.insert : have; - } - if (s.high_water < s.strstart) { - s.high_water = s.strstart; - } - - /* There was not enough avail_out to write a complete worthy or flushed - * stored block to next_out. Write a stored block to pending instead, if we - * have enough input for a worthy block, or if flushing and there is enough - * room for the remaining input as a stored block in the pending buffer. - */ - have = (s.bi_valid + 42) >> 3; /* number of header bytes */ - /* maximum stored block length that will fit in pending: */ - have = s.pending_buf_size - have > 65535/* MAX_STORED */ ? 65535/* MAX_STORED */ : s.pending_buf_size - have; - min_block = have > s.w_size ? s.w_size : have; - left = s.strstart - s.block_start; - if (left >= min_block || - ((left || flush === Z_FINISH$3$1) && flush !== Z_NO_FLUSH$2$1 && - s.strm.avail_in === 0 && left <= have)) { - len = left > have ? have : left; - last = flush === Z_FINISH$3$1 && s.strm.avail_in === 0 && - len === left ? 1 : 0; - _tr_stored_block$2(s, s.block_start, len, last); - s.block_start += len; - flush_pending$1(s.strm); - } - - /* We've done all we can with the available input and output. */ - return last ? BS_FINISH_STARTED$1 : BS_NEED_MORE$1; -}; - - -/* =========================================================================== - * Compress as much as possible from the input stream, return the current - * block state. - * This function does not perform lazy evaluation of matches and inserts - * new strings in the dictionary only for unmatched strings or for short - * matches. It is used only for the fast compression options. - */ -const deflate_fast$1 = (s, flush) => { - - let hash_head; /* head of the hash chain */ - let bflush; /* set if current block must be flushed */ - - for (;;) { - /* Make sure that we always have enough lookahead, except - * at the end of the input file. We need MAX_MATCH bytes - * for the next match, plus MIN_MATCH bytes to insert the - * string following the next match. - */ - if (s.lookahead < MIN_LOOKAHEAD$1) { - fill_window$1(s); - if (s.lookahead < MIN_LOOKAHEAD$1 && flush === Z_NO_FLUSH$2$1) { - return BS_NEED_MORE$1; - } - if (s.lookahead === 0) { - break; /* flush the current block */ - } - } - - /* Insert the string window[strstart .. strstart+2] in the - * dictionary, and set hash_head to the head of the hash chain: - */ - hash_head = 0/*NIL*/; - if (s.lookahead >= MIN_MATCH$2) { - /*** INSERT_STRING(s, s.strstart, hash_head); ***/ - s.ins_h = HASH$1(s, s.ins_h, s.window[s.strstart + MIN_MATCH$2 - 1]); - hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h]; - s.head[s.ins_h] = s.strstart; - /***/ - } - - /* Find the longest match, discarding those <= prev_length. - * At this point we have always match_length < MIN_MATCH - */ - if (hash_head !== 0/*NIL*/ && ((s.strstart - hash_head) <= (s.w_size - MIN_LOOKAHEAD$1))) { - /* To simplify the code, we prevent matches with the string - * of window index 0 (in particular we have to avoid a match - * of the string with itself at the start of the input file). - */ - s.match_length = longest_match$1(s, hash_head); - /* longest_match() sets match_start */ - } - if (s.match_length >= MIN_MATCH$2) { - // check_match(s, s.strstart, s.match_start, s.match_length); // for debug only - - /*** _tr_tally_dist(s, s.strstart - s.match_start, - s.match_length - MIN_MATCH, bflush); ***/ - bflush = _tr_tally$2(s, s.strstart - s.match_start, s.match_length - MIN_MATCH$2); - - s.lookahead -= s.match_length; - - /* Insert new strings in the hash table only if the match length - * is not too large. This saves time but degrades compression. - */ - if (s.match_length <= s.max_lazy_match/*max_insert_length*/ && s.lookahead >= MIN_MATCH$2) { - s.match_length--; /* string at strstart already in table */ - do { - s.strstart++; - /*** INSERT_STRING(s, s.strstart, hash_head); ***/ - s.ins_h = HASH$1(s, s.ins_h, s.window[s.strstart + MIN_MATCH$2 - 1]); - hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h]; - s.head[s.ins_h] = s.strstart; - /***/ - /* strstart never exceeds WSIZE-MAX_MATCH, so there are - * always MIN_MATCH bytes ahead. - */ - } while (--s.match_length !== 0); - s.strstart++; - } else - { - s.strstart += s.match_length; - s.match_length = 0; - s.ins_h = s.window[s.strstart]; - /* UPDATE_HASH(s, s.ins_h, s.window[s.strstart+1]); */ - s.ins_h = HASH$1(s, s.ins_h, s.window[s.strstart + 1]); - -//#if MIN_MATCH != 3 -// Call UPDATE_HASH() MIN_MATCH-3 more times -//#endif - /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not - * matter since it will be recomputed at next deflate call. - */ - } - } else { - /* No match, output a literal byte */ - //Tracevv((stderr,"%c", s.window[s.strstart])); - /*** _tr_tally_lit(s, s.window[s.strstart], bflush); ***/ - bflush = _tr_tally$2(s, 0, s.window[s.strstart]); - - s.lookahead--; - s.strstart++; - } - if (bflush) { - /*** FLUSH_BLOCK(s, 0); ***/ - flush_block_only$1(s, false); - if (s.strm.avail_out === 0) { - return BS_NEED_MORE$1; - } - /***/ - } - } - s.insert = ((s.strstart < (MIN_MATCH$2 - 1)) ? s.strstart : MIN_MATCH$2 - 1); - if (flush === Z_FINISH$3$1) { - /*** FLUSH_BLOCK(s, 1); ***/ - flush_block_only$1(s, true); - if (s.strm.avail_out === 0) { - return BS_FINISH_STARTED$1; - } - /***/ - return BS_FINISH_DONE$1; - } - if (s.sym_next) { - /*** FLUSH_BLOCK(s, 0); ***/ - flush_block_only$1(s, false); - if (s.strm.avail_out === 0) { - return BS_NEED_MORE$1; - } - /***/ - } - return BS_BLOCK_DONE$1; -}; - -/* =========================================================================== - * Same as above, but achieves better compression. We use a lazy - * evaluation for matches: a match is finally adopted only if there is - * no better match at the next window position. - */ -const deflate_slow$1 = (s, flush) => { - - let hash_head; /* head of hash chain */ - let bflush; /* set if current block must be flushed */ - - let max_insert; - - /* Process the input block. */ - for (;;) { - /* Make sure that we always have enough lookahead, except - * at the end of the input file. We need MAX_MATCH bytes - * for the next match, plus MIN_MATCH bytes to insert the - * string following the next match. - */ - if (s.lookahead < MIN_LOOKAHEAD$1) { - fill_window$1(s); - if (s.lookahead < MIN_LOOKAHEAD$1 && flush === Z_NO_FLUSH$2$1) { - return BS_NEED_MORE$1; - } - if (s.lookahead === 0) { break; } /* flush the current block */ - } - - /* Insert the string window[strstart .. strstart+2] in the - * dictionary, and set hash_head to the head of the hash chain: - */ - hash_head = 0/*NIL*/; - if (s.lookahead >= MIN_MATCH$2) { - /*** INSERT_STRING(s, s.strstart, hash_head); ***/ - s.ins_h = HASH$1(s, s.ins_h, s.window[s.strstart + MIN_MATCH$2 - 1]); - hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h]; - s.head[s.ins_h] = s.strstart; - /***/ - } - - /* Find the longest match, discarding those <= prev_length. - */ - s.prev_length = s.match_length; - s.prev_match = s.match_start; - s.match_length = MIN_MATCH$2 - 1; - - if (hash_head !== 0/*NIL*/ && s.prev_length < s.max_lazy_match && - s.strstart - hash_head <= (s.w_size - MIN_LOOKAHEAD$1)/*MAX_DIST(s)*/) { - /* To simplify the code, we prevent matches with the string - * of window index 0 (in particular we have to avoid a match - * of the string with itself at the start of the input file). - */ - s.match_length = longest_match$1(s, hash_head); - /* longest_match() sets match_start */ - - if (s.match_length <= 5 && - (s.strategy === Z_FILTERED$1 || (s.match_length === MIN_MATCH$2 && s.strstart - s.match_start > 4096/*TOO_FAR*/))) { - - /* If prev_match is also MIN_MATCH, match_start is garbage - * but we will ignore the current match anyway. - */ - s.match_length = MIN_MATCH$2 - 1; - } - } - /* If there was a match at the previous step and the current - * match is not better, output the previous match: - */ - if (s.prev_length >= MIN_MATCH$2 && s.match_length <= s.prev_length) { - max_insert = s.strstart + s.lookahead - MIN_MATCH$2; - /* Do not insert strings in hash table beyond this. */ - - //check_match(s, s.strstart-1, s.prev_match, s.prev_length); - - /***_tr_tally_dist(s, s.strstart - 1 - s.prev_match, - s.prev_length - MIN_MATCH, bflush);***/ - bflush = _tr_tally$2(s, s.strstart - 1 - s.prev_match, s.prev_length - MIN_MATCH$2); - /* Insert in hash table all strings up to the end of the match. - * strstart-1 and strstart are already inserted. If there is not - * enough lookahead, the last two strings are not inserted in - * the hash table. - */ - s.lookahead -= s.prev_length - 1; - s.prev_length -= 2; - do { - if (++s.strstart <= max_insert) { - /*** INSERT_STRING(s, s.strstart, hash_head); ***/ - s.ins_h = HASH$1(s, s.ins_h, s.window[s.strstart + MIN_MATCH$2 - 1]); - hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h]; - s.head[s.ins_h] = s.strstart; - /***/ - } - } while (--s.prev_length !== 0); - s.match_available = 0; - s.match_length = MIN_MATCH$2 - 1; - s.strstart++; - - if (bflush) { - /*** FLUSH_BLOCK(s, 0); ***/ - flush_block_only$1(s, false); - if (s.strm.avail_out === 0) { - return BS_NEED_MORE$1; - } - /***/ - } - - } else if (s.match_available) { - /* If there was no match at the previous position, output a - * single literal. If there was a match but the current match - * is longer, truncate the previous match to a single literal. - */ - //Tracevv((stderr,"%c", s->window[s->strstart-1])); - /*** _tr_tally_lit(s, s.window[s.strstart-1], bflush); ***/ - bflush = _tr_tally$2(s, 0, s.window[s.strstart - 1]); - - if (bflush) { - /*** FLUSH_BLOCK_ONLY(s, 0) ***/ - flush_block_only$1(s, false); - /***/ - } - s.strstart++; - s.lookahead--; - if (s.strm.avail_out === 0) { - return BS_NEED_MORE$1; - } - } else { - /* There is no previous match to compare with, wait for - * the next step to decide. - */ - s.match_available = 1; - s.strstart++; - s.lookahead--; - } - } - //Assert (flush != Z_NO_FLUSH, "no flush?"); - if (s.match_available) { - //Tracevv((stderr,"%c", s->window[s->strstart-1])); - /*** _tr_tally_lit(s, s.window[s.strstart-1], bflush); ***/ - bflush = _tr_tally$2(s, 0, s.window[s.strstart - 1]); - - s.match_available = 0; - } - s.insert = s.strstart < MIN_MATCH$2 - 1 ? s.strstart : MIN_MATCH$2 - 1; - if (flush === Z_FINISH$3$1) { - /*** FLUSH_BLOCK(s, 1); ***/ - flush_block_only$1(s, true); - if (s.strm.avail_out === 0) { - return BS_FINISH_STARTED$1; - } - /***/ - return BS_FINISH_DONE$1; - } - if (s.sym_next) { - /*** FLUSH_BLOCK(s, 0); ***/ - flush_block_only$1(s, false); - if (s.strm.avail_out === 0) { - return BS_NEED_MORE$1; - } - /***/ - } - - return BS_BLOCK_DONE$1; -}; - - -/* =========================================================================== - * For Z_RLE, simply look for runs of bytes, generate matches only of distance - * one. Do not maintain a hash table. (It will be regenerated if this run of - * deflate switches away from Z_RLE.) - */ -const deflate_rle$1 = (s, flush) => { - - let bflush; /* set if current block must be flushed */ - let prev; /* byte at distance one to match */ - let scan, strend; /* scan goes up to strend for length of run */ - - const _win = s.window; - - for (;;) { - /* Make sure that we always have enough lookahead, except - * at the end of the input file. We need MAX_MATCH bytes - * for the longest run, plus one for the unrolled loop. - */ - if (s.lookahead <= MAX_MATCH$2) { - fill_window$1(s); - if (s.lookahead <= MAX_MATCH$2 && flush === Z_NO_FLUSH$2$1) { - return BS_NEED_MORE$1; - } - if (s.lookahead === 0) { break; } /* flush the current block */ - } - - /* See how many times the previous byte repeats */ - s.match_length = 0; - if (s.lookahead >= MIN_MATCH$2 && s.strstart > 0) { - scan = s.strstart - 1; - prev = _win[scan]; - if (prev === _win[++scan] && prev === _win[++scan] && prev === _win[++scan]) { - strend = s.strstart + MAX_MATCH$2; - do { - /*jshint noempty:false*/ - } while (prev === _win[++scan] && prev === _win[++scan] && - prev === _win[++scan] && prev === _win[++scan] && - prev === _win[++scan] && prev === _win[++scan] && - prev === _win[++scan] && prev === _win[++scan] && - scan < strend); - s.match_length = MAX_MATCH$2 - (strend - scan); - if (s.match_length > s.lookahead) { - s.match_length = s.lookahead; - } - } - //Assert(scan <= s->window+(uInt)(s->window_size-1), "wild scan"); - } - - /* Emit match if have run of MIN_MATCH or longer, else emit literal */ - if (s.match_length >= MIN_MATCH$2) { - //check_match(s, s.strstart, s.strstart - 1, s.match_length); - - /*** _tr_tally_dist(s, 1, s.match_length - MIN_MATCH, bflush); ***/ - bflush = _tr_tally$2(s, 1, s.match_length - MIN_MATCH$2); - - s.lookahead -= s.match_length; - s.strstart += s.match_length; - s.match_length = 0; - } else { - /* No match, output a literal byte */ - //Tracevv((stderr,"%c", s->window[s->strstart])); - /*** _tr_tally_lit(s, s.window[s.strstart], bflush); ***/ - bflush = _tr_tally$2(s, 0, s.window[s.strstart]); - - s.lookahead--; - s.strstart++; - } - if (bflush) { - /*** FLUSH_BLOCK(s, 0); ***/ - flush_block_only$1(s, false); - if (s.strm.avail_out === 0) { - return BS_NEED_MORE$1; - } - /***/ - } - } - s.insert = 0; - if (flush === Z_FINISH$3$1) { - /*** FLUSH_BLOCK(s, 1); ***/ - flush_block_only$1(s, true); - if (s.strm.avail_out === 0) { - return BS_FINISH_STARTED$1; - } - /***/ - return BS_FINISH_DONE$1; - } - if (s.sym_next) { - /*** FLUSH_BLOCK(s, 0); ***/ - flush_block_only$1(s, false); - if (s.strm.avail_out === 0) { - return BS_NEED_MORE$1; - } - /***/ - } - return BS_BLOCK_DONE$1; -}; - -/* =========================================================================== - * For Z_HUFFMAN_ONLY, do not look for matches. Do not maintain a hash table. - * (It will be regenerated if this run of deflate switches away from Huffman.) - */ -const deflate_huff$1 = (s, flush) => { - - let bflush; /* set if current block must be flushed */ - - for (;;) { - /* Make sure that we have a literal to write. */ - if (s.lookahead === 0) { - fill_window$1(s); - if (s.lookahead === 0) { - if (flush === Z_NO_FLUSH$2$1) { - return BS_NEED_MORE$1; - } - break; /* flush the current block */ - } - } - - /* Output a literal byte */ - s.match_length = 0; - //Tracevv((stderr,"%c", s->window[s->strstart])); - /*** _tr_tally_lit(s, s.window[s.strstart], bflush); ***/ - bflush = _tr_tally$2(s, 0, s.window[s.strstart]); - s.lookahead--; - s.strstart++; - if (bflush) { - /*** FLUSH_BLOCK(s, 0); ***/ - flush_block_only$1(s, false); - if (s.strm.avail_out === 0) { - return BS_NEED_MORE$1; - } - /***/ - } - } - s.insert = 0; - if (flush === Z_FINISH$3$1) { - /*** FLUSH_BLOCK(s, 1); ***/ - flush_block_only$1(s, true); - if (s.strm.avail_out === 0) { - return BS_FINISH_STARTED$1; - } - /***/ - return BS_FINISH_DONE$1; - } - if (s.sym_next) { - /*** FLUSH_BLOCK(s, 0); ***/ - flush_block_only$1(s, false); - if (s.strm.avail_out === 0) { - return BS_NEED_MORE$1; - } - /***/ - } - return BS_BLOCK_DONE$1; -}; - -/* Values for max_lazy_match, good_match and max_chain_length, depending on - * the desired pack level (0..9). The values given below have been tuned to - * exclude worst case performance for pathological files. Better values may be - * found for specific files. - */ -function Config$1(good_length, max_lazy, nice_length, max_chain, func) { - - this.good_length = good_length; - this.max_lazy = max_lazy; - this.nice_length = nice_length; - this.max_chain = max_chain; - this.func = func; -} - -const configuration_table$1 = [ - /* good lazy nice chain */ - new Config$1(0, 0, 0, 0, deflate_stored$1), /* 0 store only */ - new Config$1(4, 4, 8, 4, deflate_fast$1), /* 1 max speed, no lazy matches */ - new Config$1(4, 5, 16, 8, deflate_fast$1), /* 2 */ - new Config$1(4, 6, 32, 32, deflate_fast$1), /* 3 */ - - new Config$1(4, 4, 16, 16, deflate_slow$1), /* 4 lazy matches */ - new Config$1(8, 16, 32, 32, deflate_slow$1), /* 5 */ - new Config$1(8, 16, 128, 128, deflate_slow$1), /* 6 */ - new Config$1(8, 32, 128, 256, deflate_slow$1), /* 7 */ - new Config$1(32, 128, 258, 1024, deflate_slow$1), /* 8 */ - new Config$1(32, 258, 258, 4096, deflate_slow$1) /* 9 max compression */ -]; - - -/* =========================================================================== - * Initialize the "longest match" routines for a new zlib stream - */ -const lm_init$1 = (s) => { - - s.window_size = 2 * s.w_size; - - /*** CLEAR_HASH(s); ***/ - zero$2(s.head); // Fill with NIL (= 0); - - /* Set the default configuration parameters: - */ - s.max_lazy_match = configuration_table$1[s.level].max_lazy; - s.good_match = configuration_table$1[s.level].good_length; - s.nice_match = configuration_table$1[s.level].nice_length; - s.max_chain_length = configuration_table$1[s.level].max_chain; - - s.strstart = 0; - s.block_start = 0; - s.lookahead = 0; - s.insert = 0; - s.match_length = s.prev_length = MIN_MATCH$2 - 1; - s.match_available = 0; - s.ins_h = 0; -}; - - -function DeflateState$1() { - this.strm = null; /* pointer back to this zlib stream */ - this.status = 0; /* as the name implies */ - this.pending_buf = null; /* output still pending */ - this.pending_buf_size = 0; /* size of pending_buf */ - this.pending_out = 0; /* next pending byte to output to the stream */ - this.pending = 0; /* nb of bytes in the pending buffer */ - this.wrap = 0; /* bit 0 true for zlib, bit 1 true for gzip */ - this.gzhead = null; /* gzip header information to write */ - this.gzindex = 0; /* where in extra, name, or comment */ - this.method = Z_DEFLATED$2$1; /* can only be DEFLATED */ - this.last_flush = -1; /* value of flush param for previous deflate call */ - - this.w_size = 0; /* LZ77 window size (32K by default) */ - this.w_bits = 0; /* log2(w_size) (8..16) */ - this.w_mask = 0; /* w_size - 1 */ - - this.window = null; - /* Sliding window. Input bytes are read into the second half of the window, - * and move to the first half later to keep a dictionary of at least wSize - * bytes. With this organization, matches are limited to a distance of - * wSize-MAX_MATCH bytes, but this ensures that IO is always - * performed with a length multiple of the block size. - */ - - this.window_size = 0; - /* Actual size of window: 2*wSize, except when the user input buffer - * is directly used as sliding window. - */ - - this.prev = null; - /* Link to older string with same hash index. To limit the size of this - * array to 64K, this link is maintained only for the last 32K strings. - * An index in this array is thus a window index modulo 32K. - */ - - this.head = null; /* Heads of the hash chains or NIL. */ - - this.ins_h = 0; /* hash index of string to be inserted */ - this.hash_size = 0; /* number of elements in hash table */ - this.hash_bits = 0; /* log2(hash_size) */ - this.hash_mask = 0; /* hash_size-1 */ - - this.hash_shift = 0; - /* Number of bits by which ins_h must be shifted at each input - * step. It must be such that after MIN_MATCH steps, the oldest - * byte no longer takes part in the hash key, that is: - * hash_shift * MIN_MATCH >= hash_bits - */ - - this.block_start = 0; - /* Window position at the beginning of the current output block. Gets - * negative when the window is moved backwards. - */ - - this.match_length = 0; /* length of best match */ - this.prev_match = 0; /* previous match */ - this.match_available = 0; /* set if previous match exists */ - this.strstart = 0; /* start of string to insert */ - this.match_start = 0; /* start of matching string */ - this.lookahead = 0; /* number of valid bytes ahead in window */ - - this.prev_length = 0; - /* Length of the best match at previous step. Matches not greater than this - * are discarded. This is used in the lazy match evaluation. - */ - - this.max_chain_length = 0; - /* To speed up deflation, hash chains are never searched beyond this - * length. A higher limit improves compression ratio but degrades the - * speed. - */ - - this.max_lazy_match = 0; - /* Attempt to find a better match only when the current match is strictly - * smaller than this value. This mechanism is used only for compression - * levels >= 4. - */ - // That's alias to max_lazy_match, don't use directly - //this.max_insert_length = 0; - /* Insert new strings in the hash table only if the match length is not - * greater than this length. This saves time but degrades compression. - * max_insert_length is used only for compression levels <= 3. - */ - - this.level = 0; /* compression level (1..9) */ - this.strategy = 0; /* favor or force Huffman coding*/ - - this.good_match = 0; - /* Use a faster search when the previous match is longer than this */ - - this.nice_match = 0; /* Stop searching when current match exceeds this */ - - /* used by trees.c: */ - - /* Didn't use ct_data typedef below to suppress compiler warning */ - - // struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */ - // struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */ - // struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */ - - // Use flat array of DOUBLE size, with interleaved fata, - // because JS does not support effective - this.dyn_ltree = new Uint16Array(HEAP_SIZE$2 * 2); - this.dyn_dtree = new Uint16Array((2 * D_CODES$2 + 1) * 2); - this.bl_tree = new Uint16Array((2 * BL_CODES$2 + 1) * 2); - zero$2(this.dyn_ltree); - zero$2(this.dyn_dtree); - zero$2(this.bl_tree); - - this.l_desc = null; /* desc. for literal tree */ - this.d_desc = null; /* desc. for distance tree */ - this.bl_desc = null; /* desc. for bit length tree */ - - //ush bl_count[MAX_BITS+1]; - this.bl_count = new Uint16Array(MAX_BITS$2 + 1); - /* number of codes at each bit length for an optimal tree */ - - //int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */ - this.heap = new Uint16Array(2 * L_CODES$2 + 1); /* heap used to build the Huffman trees */ - zero$2(this.heap); - - this.heap_len = 0; /* number of elements in the heap */ - this.heap_max = 0; /* element of largest frequency */ - /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. - * The same heap array is used to build all trees. - */ - - this.depth = new Uint16Array(2 * L_CODES$2 + 1); //uch depth[2*L_CODES+1]; - zero$2(this.depth); - /* Depth of each subtree used as tie breaker for trees of equal frequency - */ - - this.sym_buf = 0; /* buffer for distances and literals/lengths */ - - this.lit_bufsize = 0; - /* Size of match buffer for literals/lengths. There are 4 reasons for - * limiting lit_bufsize to 64K: - * - frequencies can be kept in 16 bit counters - * - if compression is not successful for the first block, all input - * data is still in the window so we can still emit a stored block even - * when input comes from standard input. (This can also be done for - * all blocks if lit_bufsize is not greater than 32K.) - * - if compression is not successful for a file smaller than 64K, we can - * even emit a stored file instead of a stored block (saving 5 bytes). - * This is applicable only for zip (not gzip or zlib). - * - creating new Huffman trees less frequently may not provide fast - * adaptation to changes in the input data statistics. (Take for - * example a binary file with poorly compressible code followed by - * a highly compressible string table.) Smaller buffer sizes give - * fast adaptation but have of course the overhead of transmitting - * trees more frequently. - * - I can't count above 4 - */ - - this.sym_next = 0; /* running index in sym_buf */ - this.sym_end = 0; /* symbol table full when sym_next reaches this */ - - this.opt_len = 0; /* bit length of current block with optimal trees */ - this.static_len = 0; /* bit length of current block with static trees */ - this.matches = 0; /* number of string matches in current block */ - this.insert = 0; /* bytes at end of window left to insert */ - - - this.bi_buf = 0; - /* Output buffer. bits are inserted starting at the bottom (least - * significant bits). - */ - this.bi_valid = 0; - /* Number of valid bits in bi_buf. All bits above the last valid bit - * are always zero. - */ - - // Used for window memory init. We safely ignore it for JS. That makes - // sense only for pointers and memory check tools. - //this.high_water = 0; - /* High water mark offset in window for initialized bytes -- bytes above - * this are set to zero in order to avoid memory check warnings when - * longest match routines access bytes past the input. This is then - * updated to the new high water mark. - */ -} - - -/* ========================================================================= - * Check for a valid deflate stream state. Return 0 if ok, 1 if not. - */ -const deflateStateCheck$1 = (strm) => { - - if (!strm) { - return 1; - } - const s = strm.state; - if (!s || s.strm !== strm || (s.status !== INIT_STATE$1 && -//#ifdef GZIP - s.status !== GZIP_STATE$1 && -//#endif - s.status !== EXTRA_STATE$1 && - s.status !== NAME_STATE$1 && - s.status !== COMMENT_STATE$1 && - s.status !== HCRC_STATE$1 && - s.status !== BUSY_STATE$1 && - s.status !== FINISH_STATE$1)) { - return 1; - } - return 0; -}; - - -const deflateResetKeep$1 = (strm) => { - - if (deflateStateCheck$1(strm)) { - return err$1(strm, Z_STREAM_ERROR$2$1); - } - - strm.total_in = strm.total_out = 0; - strm.data_type = Z_UNKNOWN$2; - - const s = strm.state; - s.pending = 0; - s.pending_out = 0; - - if (s.wrap < 0) { - s.wrap = -s.wrap; - /* was made negative by deflate(..., Z_FINISH); */ - } - s.status = -//#ifdef GZIP - s.wrap === 2 ? GZIP_STATE$1 : -//#endif - s.wrap ? INIT_STATE$1 : BUSY_STATE$1; - strm.adler = (s.wrap === 2) ? - 0 // crc32(0, Z_NULL, 0) - : - 1; // adler32(0, Z_NULL, 0) - s.last_flush = -2; - _tr_init$2(s); - return Z_OK$3$1; -}; - - -const deflateReset$1 = (strm) => { - - const ret = deflateResetKeep$1(strm); - if (ret === Z_OK$3$1) { - lm_init$1(strm.state); - } - return ret; -}; - - -const deflateSetHeader$1 = (strm, head) => { - - if (deflateStateCheck$1(strm) || strm.state.wrap !== 2) { - return Z_STREAM_ERROR$2$1; - } - strm.state.gzhead = head; - return Z_OK$3$1; -}; - - -const deflateInit2$1 = (strm, level, method, windowBits, memLevel, strategy) => { - - if (!strm) { // === Z_NULL - return Z_STREAM_ERROR$2$1; - } - let wrap = 1; - - if (level === Z_DEFAULT_COMPRESSION$1$1) { - level = 6; - } - - if (windowBits < 0) { /* suppress zlib wrapper */ - wrap = 0; - windowBits = -windowBits; - } - - else if (windowBits > 15) { - wrap = 2; /* write gzip wrapper instead */ - windowBits -= 16; - } - - - if (memLevel < 1 || memLevel > MAX_MEM_LEVEL$1 || method !== Z_DEFLATED$2$1 || - windowBits < 8 || windowBits > 15 || level < 0 || level > 9 || - strategy < 0 || strategy > Z_FIXED$2 || (windowBits === 8 && wrap !== 1)) { - return err$1(strm, Z_STREAM_ERROR$2$1); - } - - - if (windowBits === 8) { - windowBits = 9; - } - /* until 256-byte window bug fixed */ - - const s = new DeflateState$1(); - - strm.state = s; - s.strm = strm; - s.status = INIT_STATE$1; /* to pass state test in deflateReset() */ - - s.wrap = wrap; - s.gzhead = null; - s.w_bits = windowBits; - s.w_size = 1 << s.w_bits; - s.w_mask = s.w_size - 1; - - s.hash_bits = memLevel + 7; - s.hash_size = 1 << s.hash_bits; - s.hash_mask = s.hash_size - 1; - s.hash_shift = ~~((s.hash_bits + MIN_MATCH$2 - 1) / MIN_MATCH$2); - - s.window = new Uint8Array(s.w_size * 2); - s.head = new Uint16Array(s.hash_size); - s.prev = new Uint16Array(s.w_size); - - // Don't need mem init magic for JS. - //s.high_water = 0; /* nothing written to s->window yet */ - - s.lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */ - - /* We overlay pending_buf and sym_buf. This works since the average size - * for length/distance pairs over any compressed block is assured to be 31 - * bits or less. - * - * Analysis: The longest fixed codes are a length code of 8 bits plus 5 - * extra bits, for lengths 131 to 257. The longest fixed distance codes are - * 5 bits plus 13 extra bits, for distances 16385 to 32768. The longest - * possible fixed-codes length/distance pair is then 31 bits total. - * - * sym_buf starts one-fourth of the way into pending_buf. So there are - * three bytes in sym_buf for every four bytes in pending_buf. Each symbol - * in sym_buf is three bytes -- two for the distance and one for the - * literal/length. As each symbol is consumed, the pointer to the next - * sym_buf value to read moves forward three bytes. From that symbol, up to - * 31 bits are written to pending_buf. The closest the written pending_buf - * bits gets to the next sym_buf symbol to read is just before the last - * code is written. At that time, 31*(n-2) bits have been written, just - * after 24*(n-2) bits have been consumed from sym_buf. sym_buf starts at - * 8*n bits into pending_buf. (Note that the symbol buffer fills when n-1 - * symbols are written.) The closest the writing gets to what is unread is - * then n+14 bits. Here n is lit_bufsize, which is 16384 by default, and - * can range from 128 to 32768. - * - * Therefore, at a minimum, there are 142 bits of space between what is - * written and what is read in the overlain buffers, so the symbols cannot - * be overwritten by the compressed data. That space is actually 139 bits, - * due to the three-bit fixed-code block header. - * - * That covers the case where either Z_FIXED is specified, forcing fixed - * codes, or when the use of fixed codes is chosen, because that choice - * results in a smaller compressed block than dynamic codes. That latter - * condition then assures that the above analysis also covers all dynamic - * blocks. A dynamic-code block will only be chosen to be emitted if it has - * fewer bits than a fixed-code block would for the same set of symbols. - * Therefore its average symbol length is assured to be less than 31. So - * the compressed data for a dynamic block also cannot overwrite the - * symbols from which it is being constructed. - */ - - s.pending_buf_size = s.lit_bufsize * 4; - s.pending_buf = new Uint8Array(s.pending_buf_size); - - // It is offset from `s.pending_buf` (size is `s.lit_bufsize * 2`) - //s->sym_buf = s->pending_buf + s->lit_bufsize; - s.sym_buf = s.lit_bufsize; - - //s->sym_end = (s->lit_bufsize - 1) * 3; - s.sym_end = (s.lit_bufsize - 1) * 3; - /* We avoid equality with lit_bufsize*3 because of wraparound at 64K - * on 16 bit machines and because stored blocks are restricted to - * 64K-1 bytes. - */ - - s.level = level; - s.strategy = strategy; - s.method = method; - - return deflateReset$1(strm); -}; - -const deflateInit$1 = (strm, level) => { - - return deflateInit2$1(strm, level, Z_DEFLATED$2$1, MAX_WBITS$1$1, DEF_MEM_LEVEL$1, Z_DEFAULT_STRATEGY$1$1); -}; - - -/* ========================================================================= */ -const deflate$2$1 = (strm, flush) => { - - if (deflateStateCheck$1(strm) || flush > Z_BLOCK$1$1 || flush < 0) { - return strm ? err$1(strm, Z_STREAM_ERROR$2$1) : Z_STREAM_ERROR$2$1; - } - - const s = strm.state; - - if (!strm.output || - (strm.avail_in !== 0 && !strm.input) || - (s.status === FINISH_STATE$1 && flush !== Z_FINISH$3$1)) { - return err$1(strm, (strm.avail_out === 0) ? Z_BUF_ERROR$1$1 : Z_STREAM_ERROR$2$1); - } - - const old_flush = s.last_flush; - s.last_flush = flush; - - /* Flush as much pending output as possible */ - if (s.pending !== 0) { - flush_pending$1(strm); - if (strm.avail_out === 0) { - /* Since avail_out is 0, deflate will be called again with - * more output space, but possibly with both pending and - * avail_in equal to zero. There won't be anything to do, - * but this is not an error situation so make sure we - * return OK instead of BUF_ERROR at next call of deflate: - */ - s.last_flush = -1; - return Z_OK$3$1; - } - - /* Make sure there is something to do and avoid duplicate consecutive - * flushes. For repeated and useless calls with Z_FINISH, we keep - * returning Z_STREAM_END instead of Z_BUF_ERROR. - */ - } else if (strm.avail_in === 0 && rank$1(flush) <= rank$1(old_flush) && - flush !== Z_FINISH$3$1) { - return err$1(strm, Z_BUF_ERROR$1$1); - } - - /* User must not provide more input after the first FINISH: */ - if (s.status === FINISH_STATE$1 && strm.avail_in !== 0) { - return err$1(strm, Z_BUF_ERROR$1$1); - } - - /* Write the header */ - if (s.status === INIT_STATE$1 && s.wrap === 0) { - s.status = BUSY_STATE$1; - } - if (s.status === INIT_STATE$1) { - /* zlib header */ - let header = (Z_DEFLATED$2$1 + ((s.w_bits - 8) << 4)) << 8; - let level_flags = -1; - - if (s.strategy >= Z_HUFFMAN_ONLY$1 || s.level < 2) { - level_flags = 0; - } else if (s.level < 6) { - level_flags = 1; - } else if (s.level === 6) { - level_flags = 2; - } else { - level_flags = 3; - } - header |= (level_flags << 6); - if (s.strstart !== 0) { header |= PRESET_DICT$1; } - header += 31 - (header % 31); - - putShortMSB$1(s, header); - - /* Save the adler32 of the preset dictionary: */ - if (s.strstart !== 0) { - putShortMSB$1(s, strm.adler >>> 16); - putShortMSB$1(s, strm.adler & 0xffff); - } - strm.adler = 1; // adler32(0L, Z_NULL, 0); - s.status = BUSY_STATE$1; - - /* Compression must start with an empty pending buffer */ - flush_pending$1(strm); - if (s.pending !== 0) { - s.last_flush = -1; - return Z_OK$3$1; - } - } -//#ifdef GZIP - if (s.status === GZIP_STATE$1) { - /* gzip header */ - strm.adler = 0; //crc32(0L, Z_NULL, 0); - put_byte$1(s, 31); - put_byte$1(s, 139); - put_byte$1(s, 8); - if (!s.gzhead) { // s->gzhead == Z_NULL - put_byte$1(s, 0); - put_byte$1(s, 0); - put_byte$1(s, 0); - put_byte$1(s, 0); - put_byte$1(s, 0); - put_byte$1(s, s.level === 9 ? 2 : - (s.strategy >= Z_HUFFMAN_ONLY$1 || s.level < 2 ? - 4 : 0)); - put_byte$1(s, OS_CODE$1); - s.status = BUSY_STATE$1; - - /* Compression must start with an empty pending buffer */ - flush_pending$1(strm); - if (s.pending !== 0) { - s.last_flush = -1; - return Z_OK$3$1; - } - } - else { - put_byte$1(s, (s.gzhead.text ? 1 : 0) + - (s.gzhead.hcrc ? 2 : 0) + - (!s.gzhead.extra ? 0 : 4) + - (!s.gzhead.name ? 0 : 8) + - (!s.gzhead.comment ? 0 : 16) - ); - put_byte$1(s, s.gzhead.time & 0xff); - put_byte$1(s, (s.gzhead.time >> 8) & 0xff); - put_byte$1(s, (s.gzhead.time >> 16) & 0xff); - put_byte$1(s, (s.gzhead.time >> 24) & 0xff); - put_byte$1(s, s.level === 9 ? 2 : - (s.strategy >= Z_HUFFMAN_ONLY$1 || s.level < 2 ? - 4 : 0)); - put_byte$1(s, s.gzhead.os & 0xff); - if (s.gzhead.extra && s.gzhead.extra.length) { - put_byte$1(s, s.gzhead.extra.length & 0xff); - put_byte$1(s, (s.gzhead.extra.length >> 8) & 0xff); - } - if (s.gzhead.hcrc) { - strm.adler = crc32_1$2(strm.adler, s.pending_buf, s.pending, 0); - } - s.gzindex = 0; - s.status = EXTRA_STATE$1; - } - } - if (s.status === EXTRA_STATE$1) { - if (s.gzhead.extra/* != Z_NULL*/) { - let beg = s.pending; /* start of bytes to update crc */ - let left = (s.gzhead.extra.length & 0xffff) - s.gzindex; - while (s.pending + left > s.pending_buf_size) { - let copy = s.pending_buf_size - s.pending; - // zmemcpy(s.pending_buf + s.pending, - // s.gzhead.extra + s.gzindex, copy); - s.pending_buf.set(s.gzhead.extra.subarray(s.gzindex, s.gzindex + copy), s.pending); - s.pending = s.pending_buf_size; - //--- HCRC_UPDATE(beg) ---// - if (s.gzhead.hcrc && s.pending > beg) { - strm.adler = crc32_1$2(strm.adler, s.pending_buf, s.pending - beg, beg); - } - //---// - s.gzindex += copy; - flush_pending$1(strm); - if (s.pending !== 0) { - s.last_flush = -1; - return Z_OK$3$1; - } - beg = 0; - left -= copy; - } - // JS specific: s.gzhead.extra may be TypedArray or Array for backward compatibility - // TypedArray.slice and TypedArray.from don't exist in IE10-IE11 - let gzhead_extra = new Uint8Array(s.gzhead.extra); - // zmemcpy(s->pending_buf + s->pending, - // s->gzhead->extra + s->gzindex, left); - s.pending_buf.set(gzhead_extra.subarray(s.gzindex, s.gzindex + left), s.pending); - s.pending += left; - //--- HCRC_UPDATE(beg) ---// - if (s.gzhead.hcrc && s.pending > beg) { - strm.adler = crc32_1$2(strm.adler, s.pending_buf, s.pending - beg, beg); - } - //---// - s.gzindex = 0; - } - s.status = NAME_STATE$1; - } - if (s.status === NAME_STATE$1) { - if (s.gzhead.name/* != Z_NULL*/) { - let beg = s.pending; /* start of bytes to update crc */ - let val; - do { - if (s.pending === s.pending_buf_size) { - //--- HCRC_UPDATE(beg) ---// - if (s.gzhead.hcrc && s.pending > beg) { - strm.adler = crc32_1$2(strm.adler, s.pending_buf, s.pending - beg, beg); - } - //---// - flush_pending$1(strm); - if (s.pending !== 0) { - s.last_flush = -1; - return Z_OK$3$1; - } - beg = 0; - } - // JS specific: little magic to add zero terminator to end of string - if (s.gzindex < s.gzhead.name.length) { - val = s.gzhead.name.charCodeAt(s.gzindex++) & 0xff; - } else { - val = 0; - } - put_byte$1(s, val); - } while (val !== 0); - //--- HCRC_UPDATE(beg) ---// - if (s.gzhead.hcrc && s.pending > beg) { - strm.adler = crc32_1$2(strm.adler, s.pending_buf, s.pending - beg, beg); - } - //---// - s.gzindex = 0; - } - s.status = COMMENT_STATE$1; - } - if (s.status === COMMENT_STATE$1) { - if (s.gzhead.comment/* != Z_NULL*/) { - let beg = s.pending; /* start of bytes to update crc */ - let val; - do { - if (s.pending === s.pending_buf_size) { - //--- HCRC_UPDATE(beg) ---// - if (s.gzhead.hcrc && s.pending > beg) { - strm.adler = crc32_1$2(strm.adler, s.pending_buf, s.pending - beg, beg); - } - //---// - flush_pending$1(strm); - if (s.pending !== 0) { - s.last_flush = -1; - return Z_OK$3$1; - } - beg = 0; - } - // JS specific: little magic to add zero terminator to end of string - if (s.gzindex < s.gzhead.comment.length) { - val = s.gzhead.comment.charCodeAt(s.gzindex++) & 0xff; - } else { - val = 0; - } - put_byte$1(s, val); - } while (val !== 0); - //--- HCRC_UPDATE(beg) ---// - if (s.gzhead.hcrc && s.pending > beg) { - strm.adler = crc32_1$2(strm.adler, s.pending_buf, s.pending - beg, beg); - } - //---// - } - s.status = HCRC_STATE$1; - } - if (s.status === HCRC_STATE$1) { - if (s.gzhead.hcrc) { - if (s.pending + 2 > s.pending_buf_size) { - flush_pending$1(strm); - if (s.pending !== 0) { - s.last_flush = -1; - return Z_OK$3$1; - } - } - put_byte$1(s, strm.adler & 0xff); - put_byte$1(s, (strm.adler >> 8) & 0xff); - strm.adler = 0; //crc32(0L, Z_NULL, 0); - } - s.status = BUSY_STATE$1; - - /* Compression must start with an empty pending buffer */ - flush_pending$1(strm); - if (s.pending !== 0) { - s.last_flush = -1; - return Z_OK$3$1; - } - } -//#endif - - /* Start a new block or continue the current one. - */ - if (strm.avail_in !== 0 || s.lookahead !== 0 || - (flush !== Z_NO_FLUSH$2$1 && s.status !== FINISH_STATE$1)) { - let bstate = s.level === 0 ? deflate_stored$1(s, flush) : - s.strategy === Z_HUFFMAN_ONLY$1 ? deflate_huff$1(s, flush) : - s.strategy === Z_RLE$1 ? deflate_rle$1(s, flush) : - configuration_table$1[s.level].func(s, flush); - - if (bstate === BS_FINISH_STARTED$1 || bstate === BS_FINISH_DONE$1) { - s.status = FINISH_STATE$1; - } - if (bstate === BS_NEED_MORE$1 || bstate === BS_FINISH_STARTED$1) { - if (strm.avail_out === 0) { - s.last_flush = -1; - /* avoid BUF_ERROR next call, see above */ - } - return Z_OK$3$1; - /* If flush != Z_NO_FLUSH && avail_out == 0, the next call - * of deflate should use the same flush parameter to make sure - * that the flush is complete. So we don't have to output an - * empty block here, this will be done at next call. This also - * ensures that for a very small output buffer, we emit at most - * one empty block. - */ - } - if (bstate === BS_BLOCK_DONE$1) { - if (flush === Z_PARTIAL_FLUSH$1) { - _tr_align$2(s); - } - else if (flush !== Z_BLOCK$1$1) { /* FULL_FLUSH or SYNC_FLUSH */ - - _tr_stored_block$2(s, 0, 0, false); - /* For a full flush, this empty block will be recognized - * as a special marker by inflate_sync(). - */ - if (flush === Z_FULL_FLUSH$1$1) { - /*** CLEAR_HASH(s); ***/ /* forget history */ - zero$2(s.head); // Fill with NIL (= 0); - - if (s.lookahead === 0) { - s.strstart = 0; - s.block_start = 0; - s.insert = 0; - } - } - } - flush_pending$1(strm); - if (strm.avail_out === 0) { - s.last_flush = -1; /* avoid BUF_ERROR at next call, see above */ - return Z_OK$3$1; - } - } - } - - if (flush !== Z_FINISH$3$1) { return Z_OK$3$1; } - if (s.wrap <= 0) { return Z_STREAM_END$3$1; } - - /* Write the trailer */ - if (s.wrap === 2) { - put_byte$1(s, strm.adler & 0xff); - put_byte$1(s, (strm.adler >> 8) & 0xff); - put_byte$1(s, (strm.adler >> 16) & 0xff); - put_byte$1(s, (strm.adler >> 24) & 0xff); - put_byte$1(s, strm.total_in & 0xff); - put_byte$1(s, (strm.total_in >> 8) & 0xff); - put_byte$1(s, (strm.total_in >> 16) & 0xff); - put_byte$1(s, (strm.total_in >> 24) & 0xff); - } - else - { - putShortMSB$1(s, strm.adler >>> 16); - putShortMSB$1(s, strm.adler & 0xffff); - } - - flush_pending$1(strm); - /* If avail_out is zero, the application will call deflate again - * to flush the rest. - */ - if (s.wrap > 0) { s.wrap = -s.wrap; } - /* write the trailer only once! */ - return s.pending !== 0 ? Z_OK$3$1 : Z_STREAM_END$3$1; -}; - - -const deflateEnd$1 = (strm) => { - - if (deflateStateCheck$1(strm)) { - return Z_STREAM_ERROR$2$1; - } - - const status = strm.state.status; - - strm.state = null; - - return status === BUSY_STATE$1 ? err$1(strm, Z_DATA_ERROR$2$1) : Z_OK$3$1; -}; - - -/* ========================================================================= - * Initializes the compression dictionary from the given byte - * sequence without producing any compressed output. - */ -const deflateSetDictionary$1 = (strm, dictionary) => { - - let dictLength = dictionary.length; - - if (deflateStateCheck$1(strm)) { - return Z_STREAM_ERROR$2$1; - } - - const s = strm.state; - const wrap = s.wrap; - - if (wrap === 2 || (wrap === 1 && s.status !== INIT_STATE$1) || s.lookahead) { - return Z_STREAM_ERROR$2$1; - } - - /* when using zlib wrappers, compute Adler-32 for provided dictionary */ - if (wrap === 1) { - /* adler32(strm->adler, dictionary, dictLength); */ - strm.adler = adler32_1$2(strm.adler, dictionary, dictLength, 0); - } - - s.wrap = 0; /* avoid computing Adler-32 in read_buf */ - - /* if dictionary would fill window, just replace the history */ - if (dictLength >= s.w_size) { - if (wrap === 0) { /* already empty otherwise */ - /*** CLEAR_HASH(s); ***/ - zero$2(s.head); // Fill with NIL (= 0); - s.strstart = 0; - s.block_start = 0; - s.insert = 0; - } - /* use the tail */ - // dictionary = dictionary.slice(dictLength - s.w_size); - let tmpDict = new Uint8Array(s.w_size); - tmpDict.set(dictionary.subarray(dictLength - s.w_size, dictLength), 0); - dictionary = tmpDict; - dictLength = s.w_size; - } - /* insert dictionary into window and hash */ - const avail = strm.avail_in; - const next = strm.next_in; - const input = strm.input; - strm.avail_in = dictLength; - strm.next_in = 0; - strm.input = dictionary; - fill_window$1(s); - while (s.lookahead >= MIN_MATCH$2) { - let str = s.strstart; - let n = s.lookahead - (MIN_MATCH$2 - 1); - do { - /* UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); */ - s.ins_h = HASH$1(s, s.ins_h, s.window[str + MIN_MATCH$2 - 1]); - - s.prev[str & s.w_mask] = s.head[s.ins_h]; - - s.head[s.ins_h] = str; - str++; - } while (--n); - s.strstart = str; - s.lookahead = MIN_MATCH$2 - 1; - fill_window$1(s); - } - s.strstart += s.lookahead; - s.block_start = s.strstart; - s.insert = s.lookahead; - s.lookahead = 0; - s.match_length = s.prev_length = MIN_MATCH$2 - 1; - s.match_available = 0; - strm.next_in = next; - strm.input = input; - strm.avail_in = avail; - s.wrap = wrap; - return Z_OK$3$1; -}; - - -var deflateInit_1$1 = deflateInit$1; -var deflateInit2_1$1 = deflateInit2$1; -var deflateReset_1$1 = deflateReset$1; -var deflateResetKeep_1$1 = deflateResetKeep$1; -var deflateSetHeader_1$1 = deflateSetHeader$1; -var deflate_2$1$1 = deflate$2$1; -var deflateEnd_1$1 = deflateEnd$1; -var deflateSetDictionary_1$1 = deflateSetDictionary$1; -var deflateInfo$1 = 'pako deflate (from Nodeca project)'; - -/* Not implemented -module.exports.deflateBound = deflateBound; -module.exports.deflateCopy = deflateCopy; -module.exports.deflateGetDictionary = deflateGetDictionary; -module.exports.deflateParams = deflateParams; -module.exports.deflatePending = deflatePending; -module.exports.deflatePrime = deflatePrime; -module.exports.deflateTune = deflateTune; -*/ - -var deflate_1$2$1 = { - deflateInit: deflateInit_1$1, - deflateInit2: deflateInit2_1$1, - deflateReset: deflateReset_1$1, - deflateResetKeep: deflateResetKeep_1$1, - deflateSetHeader: deflateSetHeader_1$1, - deflate: deflate_2$1$1, - deflateEnd: deflateEnd_1$1, - deflateSetDictionary: deflateSetDictionary_1$1, - deflateInfo: deflateInfo$1 -}; - -const _has$2 = (obj, key) => { - return Object.prototype.hasOwnProperty.call(obj, key); -}; - -var assign$2 = function (obj /*from1, from2, from3, ...*/) { - const sources = Array.prototype.slice.call(arguments, 1); - while (sources.length) { - const source = sources.shift(); - if (!source) { continue; } - - if (typeof source !== 'object') { - throw new TypeError(source + 'must be non-object'); - } - - for (const p in source) { - if (_has$2(source, p)) { - obj[p] = source[p]; - } - } - } - - return obj; -}; - - -// Join array of chunks to single array. -var flattenChunks$2 = (chunks) => { - // calculate data length - let len = 0; - - for (let i = 0, l = chunks.length; i < l; i++) { - len += chunks[i].length; - } - - // join chunks - const result = new Uint8Array(len); - - for (let i = 0, pos = 0, l = chunks.length; i < l; i++) { - let chunk = chunks[i]; - result.set(chunk, pos); - pos += chunk.length; - } - - return result; -}; - -var common$2 = { - assign: assign$2, - flattenChunks: flattenChunks$2 -}; - -// String encode/decode helpers - - -// Quick check if we can use fast array to bin string conversion -// -// - apply(Array) can fail on Android 2.2 -// - apply(Uint8Array) can fail on iOS 5.1 Safari -// -let STR_APPLY_UIA_OK$2 = true; - -try { String.fromCharCode.apply(null, new Uint8Array(1)); } catch (__) { STR_APPLY_UIA_OK$2 = false; } - - -// Table with utf8 lengths (calculated by first byte of sequence) -// Note, that 5 & 6-byte values and some 4-byte values can not be represented in JS, -// because max possible codepoint is 0x10ffff -const _utf8len$2 = new Uint8Array(256); -for (let q = 0; q < 256; q++) { - _utf8len$2[q] = (q >= 252 ? 6 : q >= 248 ? 5 : q >= 240 ? 4 : q >= 224 ? 3 : q >= 192 ? 2 : 1); -} -_utf8len$2[254] = _utf8len$2[254] = 1; // Invalid sequence start - - -// convert string to array (typed, when possible) -var string2buf$2 = (str) => { - if (typeof TextEncoder === 'function' && TextEncoder.prototype.encode) { - return new TextEncoder().encode(str); - } - - let buf, c, c2, m_pos, i, str_len = str.length, buf_len = 0; - - // count binary size - for (m_pos = 0; m_pos < str_len; m_pos++) { - c = str.charCodeAt(m_pos); - if ((c & 0xfc00) === 0xd800 && (m_pos + 1 < str_len)) { - c2 = str.charCodeAt(m_pos + 1); - if ((c2 & 0xfc00) === 0xdc00) { - c = 0x10000 + ((c - 0xd800) << 10) + (c2 - 0xdc00); - m_pos++; - } - } - buf_len += c < 0x80 ? 1 : c < 0x800 ? 2 : c < 0x10000 ? 3 : 4; - } - - // allocate buffer - buf = new Uint8Array(buf_len); - - // convert - for (i = 0, m_pos = 0; i < buf_len; m_pos++) { - c = str.charCodeAt(m_pos); - if ((c & 0xfc00) === 0xd800 && (m_pos + 1 < str_len)) { - c2 = str.charCodeAt(m_pos + 1); - if ((c2 & 0xfc00) === 0xdc00) { - c = 0x10000 + ((c - 0xd800) << 10) + (c2 - 0xdc00); - m_pos++; - } - } - if (c < 0x80) { - /* one byte */ - buf[i++] = c; - } else if (c < 0x800) { - /* two bytes */ - buf[i++] = 0xC0 | (c >>> 6); - buf[i++] = 0x80 | (c & 0x3f); - } else if (c < 0x10000) { - /* three bytes */ - buf[i++] = 0xE0 | (c >>> 12); - buf[i++] = 0x80 | (c >>> 6 & 0x3f); - buf[i++] = 0x80 | (c & 0x3f); - } else { - /* four bytes */ - buf[i++] = 0xf0 | (c >>> 18); - buf[i++] = 0x80 | (c >>> 12 & 0x3f); - buf[i++] = 0x80 | (c >>> 6 & 0x3f); - buf[i++] = 0x80 | (c & 0x3f); - } - } - - return buf; -}; - -// Helper -const buf2binstring$2 = (buf, len) => { - // On Chrome, the arguments in a function call that are allowed is `65534`. - // If the length of the buffer is smaller than that, we can use this optimization, - // otherwise we will take a slower path. - if (len < 65534) { - if (buf.subarray && STR_APPLY_UIA_OK$2) { - return String.fromCharCode.apply(null, buf.length === len ? buf : buf.subarray(0, len)); - } - } - - let result = ''; - for (let i = 0; i < len; i++) { - result += String.fromCharCode(buf[i]); - } - return result; -}; - - -// convert array to string -var buf2string$2 = (buf, max) => { - const len = max || buf.length; - - if (typeof TextDecoder === 'function' && TextDecoder.prototype.decode) { - return new TextDecoder().decode(buf.subarray(0, max)); - } - - let i, out; - - // Reserve max possible length (2 words per char) - // NB: by unknown reasons, Array is significantly faster for - // String.fromCharCode.apply than Uint16Array. - const utf16buf = new Array(len * 2); - - for (out = 0, i = 0; i < len;) { - let c = buf[i++]; - // quick process ascii - if (c < 0x80) { utf16buf[out++] = c; continue; } - - let c_len = _utf8len$2[c]; - // skip 5 & 6 byte codes - if (c_len > 4) { utf16buf[out++] = 0xfffd; i += c_len - 1; continue; } - - // apply mask on first byte - c &= c_len === 2 ? 0x1f : c_len === 3 ? 0x0f : 0x07; - // join the rest - while (c_len > 1 && i < len) { - c = (c << 6) | (buf[i++] & 0x3f); - c_len--; - } - - // terminated by end of string? - if (c_len > 1) { utf16buf[out++] = 0xfffd; continue; } - - if (c < 0x10000) { - utf16buf[out++] = c; - } else { - c -= 0x10000; - utf16buf[out++] = 0xd800 | ((c >> 10) & 0x3ff); - utf16buf[out++] = 0xdc00 | (c & 0x3ff); - } - } - - return buf2binstring$2(utf16buf, out); -}; - - -// Calculate max possible position in utf8 buffer, -// that will not break sequence. If that's not possible -// - (very small limits) return max size as is. -// -// buf[] - utf8 bytes array -// max - length limit (mandatory); -var utf8border$2 = (buf, max) => { - - max = max || buf.length; - if (max > buf.length) { max = buf.length; } - - // go back from last position, until start of sequence found - let pos = max - 1; - while (pos >= 0 && (buf[pos] & 0xC0) === 0x80) { pos--; } - - // Very small and broken sequence, - // return max, because we should return something anyway. - if (pos < 0) { return max; } - - // If we came to start of buffer - that means buffer is too small, - // return max too. - if (pos === 0) { return max; } - - return (pos + _utf8len$2[buf[pos]] > max) ? pos : max; -}; - -var strings$2 = { - string2buf: string2buf$2, - buf2string: buf2string$2, - utf8border: utf8border$2 -}; - -// (C) 1995-2013 Jean-loup Gailly and Mark Adler -// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// 3. This notice may not be removed or altered from any source distribution. - -function ZStream$2() { - /* next input byte */ - this.input = null; // JS specific, because we have no pointers - this.next_in = 0; - /* number of bytes available at input */ - this.avail_in = 0; - /* total number of input bytes read so far */ - this.total_in = 0; - /* next output byte should be put there */ - this.output = null; // JS specific, because we have no pointers - this.next_out = 0; - /* remaining free space at output */ - this.avail_out = 0; - /* total number of bytes output so far */ - this.total_out = 0; - /* last error message, NULL if no error */ - this.msg = ''/*Z_NULL*/; - /* not visible by applications */ - this.state = null; - /* best guess about the data type: binary or text */ - this.data_type = 2/*Z_UNKNOWN*/; - /* adler32 value of the uncompressed data */ - this.adler = 0; -} - -var zstream$2 = ZStream$2; - -const toString$1$1 = Object.prototype.toString; - -/* Public constants ==========================================================*/ -/* ===========================================================================*/ - -const { - Z_NO_FLUSH: Z_NO_FLUSH$1$1, Z_SYNC_FLUSH: Z_SYNC_FLUSH$1, Z_FULL_FLUSH: Z_FULL_FLUSH$2, Z_FINISH: Z_FINISH$2$1, - Z_OK: Z_OK$2$1, Z_STREAM_END: Z_STREAM_END$2$1, - Z_DEFAULT_COMPRESSION: Z_DEFAULT_COMPRESSION$2, - Z_DEFAULT_STRATEGY: Z_DEFAULT_STRATEGY$2, - Z_DEFLATED: Z_DEFLATED$1$1 -} = constants$2$2; - -/* ===========================================================================*/ - - -/** - * class Deflate - * - * Generic JS-style wrapper for zlib calls. If you don't need - * streaming behaviour - use more simple functions: [[deflate]], - * [[deflateRaw]] and [[gzip]]. - **/ - -/* internal - * Deflate.chunks -> Array - * - * Chunks of output data, if [[Deflate#onData]] not overridden. - **/ - -/** - * Deflate.result -> Uint8Array - * - * Compressed result, generated by default [[Deflate#onData]] - * and [[Deflate#onEnd]] handlers. Filled after you push last chunk - * (call [[Deflate#push]] with `Z_FINISH` / `true` param). - **/ - -/** - * Deflate.err -> Number - * - * Error code after deflate finished. 0 (Z_OK) on success. - * You will not need it in real life, because deflate errors - * are possible only on wrong options or bad `onData` / `onEnd` - * custom handlers. - **/ - -/** - * Deflate.msg -> String - * - * Error message, if [[Deflate.err]] != 0 - **/ - - -/** - * new Deflate(options) - * - options (Object): zlib deflate options. - * - * Creates new deflator instance with specified params. Throws exception - * on bad params. Supported options: - * - * - `level` - * - `windowBits` - * - `memLevel` - * - `strategy` - * - `dictionary` - * - * [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced) - * for more information on these. - * - * Additional options, for internal needs: - * - * - `chunkSize` - size of generated data chunks (16K by default) - * - `raw` (Boolean) - do raw deflate - * - `gzip` (Boolean) - create gzip wrapper - * - `header` (Object) - custom header for gzip - * - `text` (Boolean) - true if compressed data believed to be text - * - `time` (Number) - modification time, unix timestamp - * - `os` (Number) - operation system code - * - `extra` (Array) - array of bytes with extra data (max 65536) - * - `name` (String) - file name (binary string) - * - `comment` (String) - comment (binary string) - * - `hcrc` (Boolean) - true if header crc should be added - * - * ##### Example: - * - * ```javascript - * const pako = require('pako') - * , chunk1 = new Uint8Array([1,2,3,4,5,6,7,8,9]) - * , chunk2 = new Uint8Array([10,11,12,13,14,15,16,17,18,19]); - * - * const deflate = new pako.Deflate({ level: 3}); - * - * deflate.push(chunk1, false); - * deflate.push(chunk2, true); // true -> last chunk - * - * if (deflate.err) { throw new Error(deflate.err); } - * - * console.log(deflate.result); - * ``` - **/ -function Deflate$1$1(options) { - this.options = common$2.assign({ - level: Z_DEFAULT_COMPRESSION$2, - method: Z_DEFLATED$1$1, - chunkSize: 16384, - windowBits: 15, - memLevel: 8, - strategy: Z_DEFAULT_STRATEGY$2 - }, options || {}); - - let opt = this.options; - - if (opt.raw && (opt.windowBits > 0)) { - opt.windowBits = -opt.windowBits; - } - - else if (opt.gzip && (opt.windowBits > 0) && (opt.windowBits < 16)) { - opt.windowBits += 16; - } - - this.err = 0; // error code, if happens (0 = Z_OK) - this.msg = ''; // error message - this.ended = false; // used to avoid multiple onEnd() calls - this.chunks = []; // chunks of compressed data - - this.strm = new zstream$2(); - this.strm.avail_out = 0; - - let status = deflate_1$2$1.deflateInit2( - this.strm, - opt.level, - opt.method, - opt.windowBits, - opt.memLevel, - opt.strategy - ); - - if (status !== Z_OK$2$1) { - throw new Error(messages$2[status]); - } - - if (opt.header) { - deflate_1$2$1.deflateSetHeader(this.strm, opt.header); - } - - if (opt.dictionary) { - let dict; - // Convert data if needed - if (typeof opt.dictionary === 'string') { - // If we need to compress text, change encoding to utf8. - dict = strings$2.string2buf(opt.dictionary); - } else if (toString$1$1.call(opt.dictionary) === '[object ArrayBuffer]') { - dict = new Uint8Array(opt.dictionary); - } else { - dict = opt.dictionary; - } - - status = deflate_1$2$1.deflateSetDictionary(this.strm, dict); - - if (status !== Z_OK$2$1) { - throw new Error(messages$2[status]); - } - - this._dict_set = true; - } -} - -/** - * Deflate#push(data[, flush_mode]) -> Boolean - * - data (Uint8Array|ArrayBuffer|String): input data. Strings will be - * converted to utf8 byte sequence. - * - flush_mode (Number|Boolean): 0..6 for corresponding Z_NO_FLUSH..Z_TREE modes. - * See constants. Skipped or `false` means Z_NO_FLUSH, `true` means Z_FINISH. - * - * Sends input data to deflate pipe, generating [[Deflate#onData]] calls with - * new compressed chunks. Returns `true` on success. The last data block must - * have `flush_mode` Z_FINISH (or `true`). That will flush internal pending - * buffers and call [[Deflate#onEnd]]. - * - * On fail call [[Deflate#onEnd]] with error code and return false. - * - * ##### Example - * - * ```javascript - * push(chunk, false); // push one of data chunks - * ... - * push(chunk, true); // push last chunk - * ``` - **/ -Deflate$1$1.prototype.push = function (data, flush_mode) { - const strm = this.strm; - const chunkSize = this.options.chunkSize; - let status, _flush_mode; - - if (this.ended) { return false; } - - if (flush_mode === ~~flush_mode) _flush_mode = flush_mode; - else _flush_mode = flush_mode === true ? Z_FINISH$2$1 : Z_NO_FLUSH$1$1; - - // Convert data if needed - if (typeof data === 'string') { - // If we need to compress text, change encoding to utf8. - strm.input = strings$2.string2buf(data); - } else if (toString$1$1.call(data) === '[object ArrayBuffer]') { - strm.input = new Uint8Array(data); - } else { - strm.input = data; - } - - strm.next_in = 0; - strm.avail_in = strm.input.length; - - for (;;) { - if (strm.avail_out === 0) { - strm.output = new Uint8Array(chunkSize); - strm.next_out = 0; - strm.avail_out = chunkSize; - } - - // Make sure avail_out > 6 to avoid repeating markers - if ((_flush_mode === Z_SYNC_FLUSH$1 || _flush_mode === Z_FULL_FLUSH$2) && strm.avail_out <= 6) { - this.onData(strm.output.subarray(0, strm.next_out)); - strm.avail_out = 0; - continue; - } - - status = deflate_1$2$1.deflate(strm, _flush_mode); - - // Ended => flush and finish - if (status === Z_STREAM_END$2$1) { - if (strm.next_out > 0) { - this.onData(strm.output.subarray(0, strm.next_out)); - } - status = deflate_1$2$1.deflateEnd(this.strm); - this.onEnd(status); - this.ended = true; - return status === Z_OK$2$1; - } - - // Flush if out buffer full - if (strm.avail_out === 0) { - this.onData(strm.output); - continue; - } - - // Flush if requested and has data - if (_flush_mode > 0 && strm.next_out > 0) { - this.onData(strm.output.subarray(0, strm.next_out)); - strm.avail_out = 0; - continue; - } - - if (strm.avail_in === 0) break; - } - - return true; -}; - - -/** - * Deflate#onData(chunk) -> Void - * - chunk (Uint8Array): output data. - * - * By default, stores data blocks in `chunks[]` property and glue - * those in `onEnd`. Override this handler, if you need another behaviour. - **/ -Deflate$1$1.prototype.onData = function (chunk) { - this.chunks.push(chunk); -}; - - -/** - * Deflate#onEnd(status) -> Void - * - status (Number): deflate status. 0 (Z_OK) on success, - * other if not. - * - * Called once after you tell deflate that the input stream is - * complete (Z_FINISH). By default - join collected chunks, - * free memory and fill `results` / `err` properties. - **/ -Deflate$1$1.prototype.onEnd = function (status) { - // On success - join - if (status === Z_OK$2$1) { - this.result = common$2.flattenChunks(this.chunks); - } - this.chunks = []; - this.err = status; - this.msg = this.strm.msg; -}; - - -/** - * deflate(data[, options]) -> Uint8Array - * - data (Uint8Array|ArrayBuffer|String): input data to compress. - * - options (Object): zlib deflate options. - * - * Compress `data` with deflate algorithm and `options`. - * - * Supported options are: - * - * - level - * - windowBits - * - memLevel - * - strategy - * - dictionary - * - * [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced) - * for more information on these. - * - * Sugar (options): - * - * - `raw` (Boolean) - say that we work with raw stream, if you don't wish to specify - * negative windowBits implicitly. - * - * ##### Example: - * - * ```javascript - * const pako = require('pako') - * const data = new Uint8Array([1,2,3,4,5,6,7,8,9]); - * - * console.log(pako.deflate(data)); - * ``` - **/ -function deflate$1$1(input, options) { - const deflator = new Deflate$1$1(options); - - deflator.push(input, true); - - // That will never happens, if you don't cheat with options :) - if (deflator.err) { throw deflator.msg || messages$2[deflator.err]; } - - return deflator.result; -} - - -/** - * deflateRaw(data[, options]) -> Uint8Array - * - data (Uint8Array|ArrayBuffer|String): input data to compress. - * - options (Object): zlib deflate options. - * - * The same as [[deflate]], but creates raw data, without wrapper - * (header and adler32 crc). - **/ -function deflateRaw$1$1(input, options) { - options = options || {}; - options.raw = true; - return deflate$1$1(input, options); -} - - -/** - * gzip(data[, options]) -> Uint8Array - * - data (Uint8Array|ArrayBuffer|String): input data to compress. - * - options (Object): zlib deflate options. - * - * The same as [[deflate]], but create gzip wrapper instead of - * deflate one. - **/ -function gzip$1$1(input, options) { - options = options || {}; - options.gzip = true; - return deflate$1$1(input, options); -} - - -var Deflate_1$1$1 = Deflate$1$1; -var deflate_2$2 = deflate$1$1; -var deflateRaw_1$1$1 = deflateRaw$1$1; -var gzip_1$1$1 = gzip$1$1; -var constants$1$1 = constants$2$2; - -var deflate_1$1$1 = { - Deflate: Deflate_1$1$1, - deflate: deflate_2$2, - deflateRaw: deflateRaw_1$1$1, - gzip: gzip_1$1$1, - constants: constants$1$1 -}; - -// (C) 1995-2013 Jean-loup Gailly and Mark Adler -// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// 3. This notice may not be removed or altered from any source distribution. - -// See state defs from inflate.js -const BAD$1$2 = 16209; /* got a data error -- remain here until reset */ -const TYPE$1$2 = 16191; /* i: waiting for type bits, including last-flag bit */ - -/* - Decode literal, length, and distance codes and write out the resulting - literal and match bytes until either not enough input or output is - available, an end-of-block is encountered, or a data error is encountered. - When large enough input and output buffers are supplied to inflate(), for - example, a 16K input buffer and a 64K output buffer, more than 95% of the - inflate execution time is spent in this routine. - - Entry assumptions: - - state.mode === LEN - strm.avail_in >= 6 - strm.avail_out >= 258 - start >= strm.avail_out - state.bits < 8 - - On return, state.mode is one of: - - LEN -- ran out of enough output space or enough available input - TYPE -- reached end of block code, inflate() to interpret next block - BAD -- error in block data - - Notes: - - - The maximum input bits used by a length/distance pair is 15 bits for the - length code, 5 bits for the length extra, 15 bits for the distance code, - and 13 bits for the distance extra. This totals 48 bits, or six bytes. - Therefore if strm.avail_in >= 6, then there is enough input to avoid - checking for available input while decoding. - - - The maximum bytes that a single length/distance pair can output is 258 - bytes, which is the maximum length that can be coded. inflate_fast() - requires strm.avail_out >= 258 for each loop to avoid checking for - output space. - */ -var inffast$2 = function inflate_fast(strm, start) { - let _in; /* local strm.input */ - let last; /* have enough input while in < last */ - let _out; /* local strm.output */ - let beg; /* inflate()'s initial strm.output */ - let end; /* while out < end, enough space available */ -//#ifdef INFLATE_STRICT - let dmax; /* maximum distance from zlib header */ -//#endif - let wsize; /* window size or zero if not using window */ - let whave; /* valid bytes in the window */ - let wnext; /* window write index */ - // Use `s_window` instead `window`, avoid conflict with instrumentation tools - let s_window; /* allocated sliding window, if wsize != 0 */ - let hold; /* local strm.hold */ - let bits; /* local strm.bits */ - let lcode; /* local strm.lencode */ - let dcode; /* local strm.distcode */ - let lmask; /* mask for first level of length codes */ - let dmask; /* mask for first level of distance codes */ - let here; /* retrieved table entry */ - let op; /* code bits, operation, extra bits, or */ - /* window position, window bytes to copy */ - let len; /* match length, unused bytes */ - let dist; /* match distance */ - let from; /* where to copy match from */ - let from_source; - - - let input, output; // JS specific, because we have no pointers - - /* copy state to local variables */ - const state = strm.state; - //here = state.here; - _in = strm.next_in; - input = strm.input; - last = _in + (strm.avail_in - 5); - _out = strm.next_out; - output = strm.output; - beg = _out - (start - strm.avail_out); - end = _out + (strm.avail_out - 257); -//#ifdef INFLATE_STRICT - dmax = state.dmax; -//#endif - wsize = state.wsize; - whave = state.whave; - wnext = state.wnext; - s_window = state.window; - hold = state.hold; - bits = state.bits; - lcode = state.lencode; - dcode = state.distcode; - lmask = (1 << state.lenbits) - 1; - dmask = (1 << state.distbits) - 1; - - - /* decode literals and length/distances until end-of-block or not enough - input data or output space */ - - top: - do { - if (bits < 15) { - hold += input[_in++] << bits; - bits += 8; - hold += input[_in++] << bits; - bits += 8; - } - - here = lcode[hold & lmask]; - - dolen: - for (;;) { // Goto emulation - op = here >>> 24/*here.bits*/; - hold >>>= op; - bits -= op; - op = (here >>> 16) & 0xff/*here.op*/; - if (op === 0) { /* literal */ - //Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? - // "inflate: literal '%c'\n" : - // "inflate: literal 0x%02x\n", here.val)); - output[_out++] = here & 0xffff/*here.val*/; - } - else if (op & 16) { /* length base */ - len = here & 0xffff/*here.val*/; - op &= 15; /* number of extra bits */ - if (op) { - if (bits < op) { - hold += input[_in++] << bits; - bits += 8; - } - len += hold & ((1 << op) - 1); - hold >>>= op; - bits -= op; - } - //Tracevv((stderr, "inflate: length %u\n", len)); - if (bits < 15) { - hold += input[_in++] << bits; - bits += 8; - hold += input[_in++] << bits; - bits += 8; - } - here = dcode[hold & dmask]; - - dodist: - for (;;) { // goto emulation - op = here >>> 24/*here.bits*/; - hold >>>= op; - bits -= op; - op = (here >>> 16) & 0xff/*here.op*/; - - if (op & 16) { /* distance base */ - dist = here & 0xffff/*here.val*/; - op &= 15; /* number of extra bits */ - if (bits < op) { - hold += input[_in++] << bits; - bits += 8; - if (bits < op) { - hold += input[_in++] << bits; - bits += 8; - } - } - dist += hold & ((1 << op) - 1); -//#ifdef INFLATE_STRICT - if (dist > dmax) { - strm.msg = 'invalid distance too far back'; - state.mode = BAD$1$2; - break top; - } -//#endif - hold >>>= op; - bits -= op; - //Tracevv((stderr, "inflate: distance %u\n", dist)); - op = _out - beg; /* max distance in output */ - if (dist > op) { /* see if copy from window */ - op = dist - op; /* distance back in window */ - if (op > whave) { - if (state.sane) { - strm.msg = 'invalid distance too far back'; - state.mode = BAD$1$2; - break top; - } - -// (!) This block is disabled in zlib defaults, -// don't enable it for binary compatibility -//#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR -// if (len <= op - whave) { -// do { -// output[_out++] = 0; -// } while (--len); -// continue top; -// } -// len -= op - whave; -// do { -// output[_out++] = 0; -// } while (--op > whave); -// if (op === 0) { -// from = _out - dist; -// do { -// output[_out++] = output[from++]; -// } while (--len); -// continue top; -// } -//#endif - } - from = 0; // window index - from_source = s_window; - if (wnext === 0) { /* very common case */ - from += wsize - op; - if (op < len) { /* some from window */ - len -= op; - do { - output[_out++] = s_window[from++]; - } while (--op); - from = _out - dist; /* rest from output */ - from_source = output; - } - } - else if (wnext < op) { /* wrap around window */ - from += wsize + wnext - op; - op -= wnext; - if (op < len) { /* some from end of window */ - len -= op; - do { - output[_out++] = s_window[from++]; - } while (--op); - from = 0; - if (wnext < len) { /* some from start of window */ - op = wnext; - len -= op; - do { - output[_out++] = s_window[from++]; - } while (--op); - from = _out - dist; /* rest from output */ - from_source = output; - } - } - } - else { /* contiguous in window */ - from += wnext - op; - if (op < len) { /* some from window */ - len -= op; - do { - output[_out++] = s_window[from++]; - } while (--op); - from = _out - dist; /* rest from output */ - from_source = output; - } - } - while (len > 2) { - output[_out++] = from_source[from++]; - output[_out++] = from_source[from++]; - output[_out++] = from_source[from++]; - len -= 3; - } - if (len) { - output[_out++] = from_source[from++]; - if (len > 1) { - output[_out++] = from_source[from++]; - } - } - } - else { - from = _out - dist; /* copy direct from output */ - do { /* minimum length is three */ - output[_out++] = output[from++]; - output[_out++] = output[from++]; - output[_out++] = output[from++]; - len -= 3; - } while (len > 2); - if (len) { - output[_out++] = output[from++]; - if (len > 1) { - output[_out++] = output[from++]; - } - } - } - } - else if ((op & 64) === 0) { /* 2nd level distance code */ - here = dcode[(here & 0xffff)/*here.val*/ + (hold & ((1 << op) - 1))]; - continue dodist; - } - else { - strm.msg = 'invalid distance code'; - state.mode = BAD$1$2; - break top; - } - - break; // need to emulate goto via "continue" - } - } - else if ((op & 64) === 0) { /* 2nd level length code */ - here = lcode[(here & 0xffff)/*here.val*/ + (hold & ((1 << op) - 1))]; - continue dolen; - } - else if (op & 32) { /* end-of-block */ - //Tracevv((stderr, "inflate: end of block\n")); - state.mode = TYPE$1$2; - break top; - } - else { - strm.msg = 'invalid literal/length code'; - state.mode = BAD$1$2; - break top; - } - - break; // need to emulate goto via "continue" - } - } while (_in < last && _out < end); - - /* return unused bytes (on entry, bits < 8, so in won't go too far back) */ - len = bits >> 3; - _in -= len; - bits -= len << 3; - hold &= (1 << bits) - 1; - - /* update state and return */ - strm.next_in = _in; - strm.next_out = _out; - strm.avail_in = (_in < last ? 5 + (last - _in) : 5 - (_in - last)); - strm.avail_out = (_out < end ? 257 + (end - _out) : 257 - (_out - end)); - state.hold = hold; - state.bits = bits; - return; -}; - -// (C) 1995-2013 Jean-loup Gailly and Mark Adler -// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// 3. This notice may not be removed or altered from any source distribution. - -const MAXBITS$2 = 15; -const ENOUGH_LENS$1$2 = 852; -const ENOUGH_DISTS$1$2 = 592; -//const ENOUGH = (ENOUGH_LENS+ENOUGH_DISTS); - -const CODES$1$2 = 0; -const LENS$1$2 = 1; -const DISTS$1$2 = 2; - -const lbase$2 = new Uint16Array([ /* Length codes 257..285 base */ - 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, - 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0 -]); - -const lext$2 = new Uint8Array([ /* Length codes 257..285 extra */ - 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, - 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 72, 78 -]); - -const dbase$2 = new Uint16Array([ /* Distance codes 0..29 base */ - 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, - 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, - 8193, 12289, 16385, 24577, 0, 0 -]); - -const dext$2 = new Uint8Array([ /* Distance codes 0..29 extra */ - 16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, - 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, - 28, 28, 29, 29, 64, 64 -]); - -const inflate_table$2 = (type, lens, lens_index, codes, table, table_index, work, opts) => -{ - const bits = opts.bits; - //here = opts.here; /* table entry for duplication */ - - let len = 0; /* a code's length in bits */ - let sym = 0; /* index of code symbols */ - let min = 0, max = 0; /* minimum and maximum code lengths */ - let root = 0; /* number of index bits for root table */ - let curr = 0; /* number of index bits for current table */ - let drop = 0; /* code bits to drop for sub-table */ - let left = 0; /* number of prefix codes available */ - let used = 0; /* code entries in table used */ - let huff = 0; /* Huffman code */ - let incr; /* for incrementing code, index */ - let fill; /* index for replicating entries */ - let low; /* low bits for current root entry */ - let mask; /* mask for low root bits */ - let next; /* next available space in table */ - let base = null; /* base value table to use */ -// let shoextra; /* extra bits table to use */ - let match; /* use base and extra for symbol >= match */ - const count = new Uint16Array(MAXBITS$2 + 1); //[MAXBITS+1]; /* number of codes of each length */ - const offs = new Uint16Array(MAXBITS$2 + 1); //[MAXBITS+1]; /* offsets in table for each length */ - let extra = null; - - let here_bits, here_op, here_val; - - /* - Process a set of code lengths to create a canonical Huffman code. The - code lengths are lens[0..codes-1]. Each length corresponds to the - symbols 0..codes-1. The Huffman code is generated by first sorting the - symbols by length from short to long, and retaining the symbol order - for codes with equal lengths. Then the code starts with all zero bits - for the first code of the shortest length, and the codes are integer - increments for the same length, and zeros are appended as the length - increases. For the deflate format, these bits are stored backwards - from their more natural integer increment ordering, and so when the - decoding tables are built in the large loop below, the integer codes - are incremented backwards. - - This routine assumes, but does not check, that all of the entries in - lens[] are in the range 0..MAXBITS. The caller must assure this. - 1..MAXBITS is interpreted as that code length. zero means that that - symbol does not occur in this code. - - The codes are sorted by computing a count of codes for each length, - creating from that a table of starting indices for each length in the - sorted table, and then entering the symbols in order in the sorted - table. The sorted table is work[], with that space being provided by - the caller. - - The length counts are used for other purposes as well, i.e. finding - the minimum and maximum length codes, determining if there are any - codes at all, checking for a valid set of lengths, and looking ahead - at length counts to determine sub-table sizes when building the - decoding tables. - */ - - /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */ - for (len = 0; len <= MAXBITS$2; len++) { - count[len] = 0; - } - for (sym = 0; sym < codes; sym++) { - count[lens[lens_index + sym]]++; - } - - /* bound code lengths, force root to be within code lengths */ - root = bits; - for (max = MAXBITS$2; max >= 1; max--) { - if (count[max] !== 0) { break; } - } - if (root > max) { - root = max; - } - if (max === 0) { /* no symbols to code at all */ - //table.op[opts.table_index] = 64; //here.op = (var char)64; /* invalid code marker */ - //table.bits[opts.table_index] = 1; //here.bits = (var char)1; - //table.val[opts.table_index++] = 0; //here.val = (var short)0; - table[table_index++] = (1 << 24) | (64 << 16) | 0; - - - //table.op[opts.table_index] = 64; - //table.bits[opts.table_index] = 1; - //table.val[opts.table_index++] = 0; - table[table_index++] = (1 << 24) | (64 << 16) | 0; - - opts.bits = 1; - return 0; /* no symbols, but wait for decoding to report error */ - } - for (min = 1; min < max; min++) { - if (count[min] !== 0) { break; } - } - if (root < min) { - root = min; - } - - /* check for an over-subscribed or incomplete set of lengths */ - left = 1; - for (len = 1; len <= MAXBITS$2; len++) { - left <<= 1; - left -= count[len]; - if (left < 0) { - return -1; - } /* over-subscribed */ - } - if (left > 0 && (type === CODES$1$2 || max !== 1)) { - return -1; /* incomplete set */ - } - - /* generate offsets into symbol table for each length for sorting */ - offs[1] = 0; - for (len = 1; len < MAXBITS$2; len++) { - offs[len + 1] = offs[len] + count[len]; - } - - /* sort symbols by length, by symbol order within each length */ - for (sym = 0; sym < codes; sym++) { - if (lens[lens_index + sym] !== 0) { - work[offs[lens[lens_index + sym]]++] = sym; - } - } - - /* - Create and fill in decoding tables. In this loop, the table being - filled is at next and has curr index bits. The code being used is huff - with length len. That code is converted to an index by dropping drop - bits off of the bottom. For codes where len is less than drop + curr, - those top drop + curr - len bits are incremented through all values to - fill the table with replicated entries. - - root is the number of index bits for the root table. When len exceeds - root, sub-tables are created pointed to by the root entry with an index - of the low root bits of huff. This is saved in low to check for when a - new sub-table should be started. drop is zero when the root table is - being filled, and drop is root when sub-tables are being filled. - - When a new sub-table is needed, it is necessary to look ahead in the - code lengths to determine what size sub-table is needed. The length - counts are used for this, and so count[] is decremented as codes are - entered in the tables. - - used keeps track of how many table entries have been allocated from the - provided *table space. It is checked for LENS and DIST tables against - the constants ENOUGH_LENS and ENOUGH_DISTS to guard against changes in - the initial root table size constants. See the comments in inftrees.h - for more information. - - sym increments through all symbols, and the loop terminates when - all codes of length max, i.e. all codes, have been processed. This - routine permits incomplete codes, so another loop after this one fills - in the rest of the decoding tables with invalid code markers. - */ - - /* set up for code type */ - // poor man optimization - use if-else instead of switch, - // to avoid deopts in old v8 - if (type === CODES$1$2) { - base = extra = work; /* dummy value--not used */ - match = 20; - - } else if (type === LENS$1$2) { - base = lbase$2; - extra = lext$2; - match = 257; - - } else { /* DISTS */ - base = dbase$2; - extra = dext$2; - match = 0; - } - - /* initialize opts for loop */ - huff = 0; /* starting code */ - sym = 0; /* starting code symbol */ - len = min; /* starting code length */ - next = table_index; /* current table to fill in */ - curr = root; /* current table index bits */ - drop = 0; /* current bits to drop from code for index */ - low = -1; /* trigger new sub-table when len > root */ - used = 1 << root; /* use root table entries */ - mask = used - 1; /* mask for comparing low */ - - /* check available table space */ - if ((type === LENS$1$2 && used > ENOUGH_LENS$1$2) || - (type === DISTS$1$2 && used > ENOUGH_DISTS$1$2)) { - return 1; - } - - /* process all codes and make table entries */ - for (;;) { - /* create table entry */ - here_bits = len - drop; - if (work[sym] + 1 < match) { - here_op = 0; - here_val = work[sym]; - } - else if (work[sym] >= match) { - here_op = extra[work[sym] - match]; - here_val = base[work[sym] - match]; - } - else { - here_op = 32 + 64; /* end of block */ - here_val = 0; - } - - /* replicate for those indices with low len bits equal to huff */ - incr = 1 << (len - drop); - fill = 1 << curr; - min = fill; /* save offset to next table */ - do { - fill -= incr; - table[next + (huff >> drop) + fill] = (here_bits << 24) | (here_op << 16) | here_val |0; - } while (fill !== 0); - - /* backwards increment the len-bit code huff */ - incr = 1 << (len - 1); - while (huff & incr) { - incr >>= 1; - } - if (incr !== 0) { - huff &= incr - 1; - huff += incr; - } else { - huff = 0; - } - - /* go to next symbol, update count, len */ - sym++; - if (--count[len] === 0) { - if (len === max) { break; } - len = lens[lens_index + work[sym]]; - } - - /* create new sub-table if needed */ - if (len > root && (huff & mask) !== low) { - /* if first time, transition to sub-tables */ - if (drop === 0) { - drop = root; - } - - /* increment past last table */ - next += min; /* here min is 1 << curr */ - - /* determine length of next table */ - curr = len - drop; - left = 1 << curr; - while (curr + drop < max) { - left -= count[curr + drop]; - if (left <= 0) { break; } - curr++; - left <<= 1; - } - - /* check for enough space */ - used += 1 << curr; - if ((type === LENS$1$2 && used > ENOUGH_LENS$1$2) || - (type === DISTS$1$2 && used > ENOUGH_DISTS$1$2)) { - return 1; - } - - /* point entry in root table to sub-table */ - low = huff & mask; - /*table.op[low] = curr; - table.bits[low] = root; - table.val[low] = next - opts.table_index;*/ - table[low] = (root << 24) | (curr << 16) | (next - table_index) |0; - } - } - - /* fill in remaining table entry if code is incomplete (guaranteed to have - at most one remaining entry, since if the code is incomplete, the - maximum code length that was allowed to get this far is one bit) */ - if (huff !== 0) { - //table.op[next + huff] = 64; /* invalid code marker */ - //table.bits[next + huff] = len - drop; - //table.val[next + huff] = 0; - table[next + huff] = ((len - drop) << 24) | (64 << 16) |0; - } - - /* set return parameters */ - //opts.table_index += used; - opts.bits = root; - return 0; -}; - - -var inftrees$2 = inflate_table$2; - -// (C) 1995-2013 Jean-loup Gailly and Mark Adler -// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// 3. This notice may not be removed or altered from any source distribution. - - - - - - -const CODES$3 = 0; -const LENS$3 = 1; -const DISTS$3 = 2; - -/* Public constants ==========================================================*/ -/* ===========================================================================*/ - -const { - Z_FINISH: Z_FINISH$1$2, Z_BLOCK: Z_BLOCK$3, Z_TREES: Z_TREES$2, - Z_OK: Z_OK$1$2, Z_STREAM_END: Z_STREAM_END$1$2, Z_NEED_DICT: Z_NEED_DICT$1$2, Z_STREAM_ERROR: Z_STREAM_ERROR$1$2, Z_DATA_ERROR: Z_DATA_ERROR$1$2, Z_MEM_ERROR: Z_MEM_ERROR$1$2, Z_BUF_ERROR: Z_BUF_ERROR$3, - Z_DEFLATED: Z_DEFLATED$4 -} = constants$2$2; - - -/* STATES ====================================================================*/ -/* ===========================================================================*/ - - -const HEAD$2 = 16180; /* i: waiting for magic header */ -const FLAGS$2 = 16181; /* i: waiting for method and flags (gzip) */ -const TIME$2 = 16182; /* i: waiting for modification time (gzip) */ -const OS$2 = 16183; /* i: waiting for extra flags and operating system (gzip) */ -const EXLEN$2 = 16184; /* i: waiting for extra length (gzip) */ -const EXTRA$2 = 16185; /* i: waiting for extra bytes (gzip) */ -const NAME$2 = 16186; /* i: waiting for end of file name (gzip) */ -const COMMENT$2 = 16187; /* i: waiting for end of comment (gzip) */ -const HCRC$2 = 16188; /* i: waiting for header crc (gzip) */ -const DICTID$2 = 16189; /* i: waiting for dictionary check value */ -const DICT$2 = 16190; /* waiting for inflateSetDictionary() call */ -const TYPE$3 = 16191; /* i: waiting for type bits, including last-flag bit */ -const TYPEDO$2 = 16192; /* i: same, but skip check to exit inflate on new block */ -const STORED$2 = 16193; /* i: waiting for stored size (length and complement) */ -const COPY_$2 = 16194; /* i/o: same as COPY below, but only first time in */ -const COPY$2 = 16195; /* i/o: waiting for input or output to copy stored block */ -const TABLE$2 = 16196; /* i: waiting for dynamic block table lengths */ -const LENLENS$2 = 16197; /* i: waiting for code length code lengths */ -const CODELENS$2 = 16198; /* i: waiting for length/lit and distance code lengths */ -const LEN_$2 = 16199; /* i: same as LEN below, but only first time in */ -const LEN$2 = 16200; /* i: waiting for length/lit/eob code */ -const LENEXT$2 = 16201; /* i: waiting for length extra bits */ -const DIST$2 = 16202; /* i: waiting for distance code */ -const DISTEXT$2 = 16203; /* i: waiting for distance extra bits */ -const MATCH$2 = 16204; /* o: waiting for output space to copy string */ -const LIT$2 = 16205; /* o: waiting for output space to write literal */ -const CHECK$2 = 16206; /* i: waiting for 32-bit check value */ -const LENGTH$2 = 16207; /* i: waiting for 32-bit length (gzip) */ -const DONE$2 = 16208; /* finished check, done -- remain here until reset */ -const BAD$3 = 16209; /* got a data error -- remain here until reset */ -const MEM$2 = 16210; /* got an inflate() memory error -- remain here until reset */ -const SYNC$2 = 16211; /* looking for synchronization bytes to restart inflate() */ - -/* ===========================================================================*/ - - - -const ENOUGH_LENS$3 = 852; -const ENOUGH_DISTS$3 = 592; -//const ENOUGH = (ENOUGH_LENS+ENOUGH_DISTS); - -const MAX_WBITS$3 = 15; -/* 32K LZ77 window */ -const DEF_WBITS$2 = MAX_WBITS$3; - - -const zswap32$2 = (q) => { - - return (((q >>> 24) & 0xff) + - ((q >>> 8) & 0xff00) + - ((q & 0xff00) << 8) + - ((q & 0xff) << 24)); -}; - - -function InflateState$2() { - this.strm = null; /* pointer back to this zlib stream */ - this.mode = 0; /* current inflate mode */ - this.last = false; /* true if processing last block */ - this.wrap = 0; /* bit 0 true for zlib, bit 1 true for gzip, - bit 2 true to validate check value */ - this.havedict = false; /* true if dictionary provided */ - this.flags = 0; /* gzip header method and flags (0 if zlib), or - -1 if raw or no header yet */ - this.dmax = 0; /* zlib header max distance (INFLATE_STRICT) */ - this.check = 0; /* protected copy of check value */ - this.total = 0; /* protected copy of output count */ - // TODO: may be {} - this.head = null; /* where to save gzip header information */ - - /* sliding window */ - this.wbits = 0; /* log base 2 of requested window size */ - this.wsize = 0; /* window size or zero if not using window */ - this.whave = 0; /* valid bytes in the window */ - this.wnext = 0; /* window write index */ - this.window = null; /* allocated sliding window, if needed */ - - /* bit accumulator */ - this.hold = 0; /* input bit accumulator */ - this.bits = 0; /* number of bits in "in" */ - - /* for string and stored block copying */ - this.length = 0; /* literal or length of data to copy */ - this.offset = 0; /* distance back to copy string from */ - - /* for table and code decoding */ - this.extra = 0; /* extra bits needed */ - - /* fixed and dynamic code tables */ - this.lencode = null; /* starting table for length/literal codes */ - this.distcode = null; /* starting table for distance codes */ - this.lenbits = 0; /* index bits for lencode */ - this.distbits = 0; /* index bits for distcode */ - - /* dynamic table building */ - this.ncode = 0; /* number of code length code lengths */ - this.nlen = 0; /* number of length code lengths */ - this.ndist = 0; /* number of distance code lengths */ - this.have = 0; /* number of code lengths in lens[] */ - this.next = null; /* next available space in codes[] */ - - this.lens = new Uint16Array(320); /* temporary storage for code lengths */ - this.work = new Uint16Array(288); /* work area for code table building */ - - /* - because we don't have pointers in js, we use lencode and distcode directly - as buffers so we don't need codes - */ - //this.codes = new Int32Array(ENOUGH); /* space for code tables */ - this.lendyn = null; /* dynamic table for length/literal codes (JS specific) */ - this.distdyn = null; /* dynamic table for distance codes (JS specific) */ - this.sane = 0; /* if false, allow invalid distance too far */ - this.back = 0; /* bits back of last unprocessed length/lit */ - this.was = 0; /* initial length of match */ -} - - -const inflateStateCheck$1 = (strm) => { - - if (!strm) { - return 1; - } - const state = strm.state; - if (!state || state.strm !== strm || - state.mode < HEAD$2 || state.mode > SYNC$2) { - return 1; - } - return 0; -}; - - -const inflateResetKeep$2 = (strm) => { - - if (inflateStateCheck$1(strm)) { return Z_STREAM_ERROR$1$2; } - const state = strm.state; - strm.total_in = strm.total_out = state.total = 0; - strm.msg = ''; /*Z_NULL*/ - if (state.wrap) { /* to support ill-conceived Java test suite */ - strm.adler = state.wrap & 1; - } - state.mode = HEAD$2; - state.last = 0; - state.havedict = 0; - state.flags = -1; - state.dmax = 32768; - state.head = null/*Z_NULL*/; - state.hold = 0; - state.bits = 0; - //state.lencode = state.distcode = state.next = state.codes; - state.lencode = state.lendyn = new Int32Array(ENOUGH_LENS$3); - state.distcode = state.distdyn = new Int32Array(ENOUGH_DISTS$3); - - state.sane = 1; - state.back = -1; - //Tracev((stderr, "inflate: reset\n")); - return Z_OK$1$2; -}; - - -const inflateReset$2 = (strm) => { - - if (inflateStateCheck$1(strm)) { return Z_STREAM_ERROR$1$2; } - const state = strm.state; - state.wsize = 0; - state.whave = 0; - state.wnext = 0; - return inflateResetKeep$2(strm); - -}; - - -const inflateReset2$2 = (strm, windowBits) => { - let wrap; - - /* get the state */ - if (inflateStateCheck$1(strm)) { return Z_STREAM_ERROR$1$2; } - const state = strm.state; - - /* extract wrap request from windowBits parameter */ - if (windowBits < 0) { - wrap = 0; - windowBits = -windowBits; - } - else { - wrap = (windowBits >> 4) + 5; - if (windowBits < 48) { - windowBits &= 15; - } - } - - /* set number of window bits, free window if different */ - if (windowBits && (windowBits < 8 || windowBits > 15)) { - return Z_STREAM_ERROR$1$2; - } - if (state.window !== null && state.wbits !== windowBits) { - state.window = null; - } - - /* update state and reset the rest of it */ - state.wrap = wrap; - state.wbits = windowBits; - return inflateReset$2(strm); -}; - - -const inflateInit2$2 = (strm, windowBits) => { - - if (!strm) { return Z_STREAM_ERROR$1$2; } - //strm.msg = Z_NULL; /* in case we return an error */ - - const state = new InflateState$2(); - - //if (state === Z_NULL) return Z_MEM_ERROR; - //Tracev((stderr, "inflate: allocated\n")); - strm.state = state; - state.strm = strm; - state.window = null/*Z_NULL*/; - state.mode = HEAD$2; /* to pass state test in inflateReset2() */ - const ret = inflateReset2$2(strm, windowBits); - if (ret !== Z_OK$1$2) { - strm.state = null/*Z_NULL*/; - } - return ret; -}; - - -const inflateInit$2 = (strm) => { - - return inflateInit2$2(strm, DEF_WBITS$2); -}; - - -/* - Return state with length and distance decoding tables and index sizes set to - fixed code decoding. Normally this returns fixed tables from inffixed.h. - If BUILDFIXED is defined, then instead this routine builds the tables the - first time it's called, and returns those tables the first time and - thereafter. This reduces the size of the code by about 2K bytes, in - exchange for a little execution time. However, BUILDFIXED should not be - used for threaded applications, since the rewriting of the tables and virgin - may not be thread-safe. - */ -let virgin$2 = true; - -let lenfix$2, distfix$2; // We have no pointers in JS, so keep tables separate - - -const fixedtables$2 = (state) => { - - /* build fixed huffman tables if first call (may not be thread safe) */ - if (virgin$2) { - lenfix$2 = new Int32Array(512); - distfix$2 = new Int32Array(32); - - /* literal/length table */ - let sym = 0; - while (sym < 144) { state.lens[sym++] = 8; } - while (sym < 256) { state.lens[sym++] = 9; } - while (sym < 280) { state.lens[sym++] = 7; } - while (sym < 288) { state.lens[sym++] = 8; } - - inftrees$2(LENS$3, state.lens, 0, 288, lenfix$2, 0, state.work, { bits: 9 }); - - /* distance table */ - sym = 0; - while (sym < 32) { state.lens[sym++] = 5; } - - inftrees$2(DISTS$3, state.lens, 0, 32, distfix$2, 0, state.work, { bits: 5 }); - - /* do this just once */ - virgin$2 = false; - } - - state.lencode = lenfix$2; - state.lenbits = 9; - state.distcode = distfix$2; - state.distbits = 5; -}; - - -/* - Update the window with the last wsize (normally 32K) bytes written before - returning. If window does not exist yet, create it. This is only called - when a window is already in use, or when output has been written during this - inflate call, but the end of the deflate stream has not been reached yet. - It is also called to create a window for dictionary data when a dictionary - is loaded. - - Providing output buffers larger than 32K to inflate() should provide a speed - advantage, since only the last 32K of output is copied to the sliding window - upon return from inflate(), and since all distances after the first 32K of - output will fall in the output data, making match copies simpler and faster. - The advantage may be dependent on the size of the processor's data caches. - */ -const updatewindow$2 = (strm, src, end, copy) => { - - let dist; - const state = strm.state; - - /* if it hasn't been done already, allocate space for the window */ - if (state.window === null) { - state.wsize = 1 << state.wbits; - state.wnext = 0; - state.whave = 0; - - state.window = new Uint8Array(state.wsize); - } - - /* copy state->wsize or less output bytes into the circular window */ - if (copy >= state.wsize) { - state.window.set(src.subarray(end - state.wsize, end), 0); - state.wnext = 0; - state.whave = state.wsize; - } - else { - dist = state.wsize - state.wnext; - if (dist > copy) { - dist = copy; - } - //zmemcpy(state->window + state->wnext, end - copy, dist); - state.window.set(src.subarray(end - copy, end - copy + dist), state.wnext); - copy -= dist; - if (copy) { - //zmemcpy(state->window, end - copy, copy); - state.window.set(src.subarray(end - copy, end), 0); - state.wnext = copy; - state.whave = state.wsize; - } - else { - state.wnext += dist; - if (state.wnext === state.wsize) { state.wnext = 0; } - if (state.whave < state.wsize) { state.whave += dist; } - } - } - return 0; -}; - - -const inflate$2$2 = (strm, flush) => { - - let state; - let input, output; // input/output buffers - let next; /* next input INDEX */ - let put; /* next output INDEX */ - let have, left; /* available input and output */ - let hold; /* bit buffer */ - let bits; /* bits in bit buffer */ - let _in, _out; /* save starting available input and output */ - let copy; /* number of stored or match bytes to copy */ - let from; /* where to copy match bytes from */ - let from_source; - let here = 0; /* current decoding table entry */ - let here_bits, here_op, here_val; // paked "here" denormalized (JS specific) - //let last; /* parent table entry */ - let last_bits, last_op, last_val; // paked "last" denormalized (JS specific) - let len; /* length to copy for repeats, bits to drop */ - let ret; /* return code */ - const hbuf = new Uint8Array(4); /* buffer for gzip header crc calculation */ - let opts; - - let n; // temporary variable for NEED_BITS - - const order = /* permutation of code lengths */ - new Uint8Array([ 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 ]); - - - if (inflateStateCheck$1(strm) || !strm.output || - (!strm.input && strm.avail_in !== 0)) { - return Z_STREAM_ERROR$1$2; - } - - state = strm.state; - if (state.mode === TYPE$3) { state.mode = TYPEDO$2; } /* skip check */ - - - //--- LOAD() --- - put = strm.next_out; - output = strm.output; - left = strm.avail_out; - next = strm.next_in; - input = strm.input; - have = strm.avail_in; - hold = state.hold; - bits = state.bits; - //--- - - _in = have; - _out = left; - ret = Z_OK$1$2; - - inf_leave: // goto emulation - for (;;) { - switch (state.mode) { - case HEAD$2: - if (state.wrap === 0) { - state.mode = TYPEDO$2; - break; - } - //=== NEEDBITS(16); - while (bits < 16) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - if ((state.wrap & 2) && hold === 0x8b1f) { /* gzip header */ - if (state.wbits === 0) { - state.wbits = 15; - } - state.check = 0/*crc32(0L, Z_NULL, 0)*/; - //=== CRC2(state.check, hold); - hbuf[0] = hold & 0xff; - hbuf[1] = (hold >>> 8) & 0xff; - state.check = crc32_1$2(state.check, hbuf, 2, 0); - //===// - - //=== INITBITS(); - hold = 0; - bits = 0; - //===// - state.mode = FLAGS$2; - break; - } - if (state.head) { - state.head.done = false; - } - if (!(state.wrap & 1) || /* check if zlib header allowed */ - (((hold & 0xff)/*BITS(8)*/ << 8) + (hold >> 8)) % 31) { - strm.msg = 'incorrect header check'; - state.mode = BAD$3; - break; - } - if ((hold & 0x0f)/*BITS(4)*/ !== Z_DEFLATED$4) { - strm.msg = 'unknown compression method'; - state.mode = BAD$3; - break; - } - //--- DROPBITS(4) ---// - hold >>>= 4; - bits -= 4; - //---// - len = (hold & 0x0f)/*BITS(4)*/ + 8; - if (state.wbits === 0) { - state.wbits = len; - } - if (len > 15 || len > state.wbits) { - strm.msg = 'invalid window size'; - state.mode = BAD$3; - break; - } - - // !!! pako patch. Force use `options.windowBits` if passed. - // Required to always use max window size by default. - state.dmax = 1 << state.wbits; - //state.dmax = 1 << len; - - state.flags = 0; /* indicate zlib header */ - //Tracev((stderr, "inflate: zlib header ok\n")); - strm.adler = state.check = 1/*adler32(0L, Z_NULL, 0)*/; - state.mode = hold & 0x200 ? DICTID$2 : TYPE$3; - //=== INITBITS(); - hold = 0; - bits = 0; - //===// - break; - case FLAGS$2: - //=== NEEDBITS(16); */ - while (bits < 16) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - state.flags = hold; - if ((state.flags & 0xff) !== Z_DEFLATED$4) { - strm.msg = 'unknown compression method'; - state.mode = BAD$3; - break; - } - if (state.flags & 0xe000) { - strm.msg = 'unknown header flags set'; - state.mode = BAD$3; - break; - } - if (state.head) { - state.head.text = ((hold >> 8) & 1); - } - if ((state.flags & 0x0200) && (state.wrap & 4)) { - //=== CRC2(state.check, hold); - hbuf[0] = hold & 0xff; - hbuf[1] = (hold >>> 8) & 0xff; - state.check = crc32_1$2(state.check, hbuf, 2, 0); - //===// - } - //=== INITBITS(); - hold = 0; - bits = 0; - //===// - state.mode = TIME$2; - /* falls through */ - case TIME$2: - //=== NEEDBITS(32); */ - while (bits < 32) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - if (state.head) { - state.head.time = hold; - } - if ((state.flags & 0x0200) && (state.wrap & 4)) { - //=== CRC4(state.check, hold) - hbuf[0] = hold & 0xff; - hbuf[1] = (hold >>> 8) & 0xff; - hbuf[2] = (hold >>> 16) & 0xff; - hbuf[3] = (hold >>> 24) & 0xff; - state.check = crc32_1$2(state.check, hbuf, 4, 0); - //=== - } - //=== INITBITS(); - hold = 0; - bits = 0; - //===// - state.mode = OS$2; - /* falls through */ - case OS$2: - //=== NEEDBITS(16); */ - while (bits < 16) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - if (state.head) { - state.head.xflags = (hold & 0xff); - state.head.os = (hold >> 8); - } - if ((state.flags & 0x0200) && (state.wrap & 4)) { - //=== CRC2(state.check, hold); - hbuf[0] = hold & 0xff; - hbuf[1] = (hold >>> 8) & 0xff; - state.check = crc32_1$2(state.check, hbuf, 2, 0); - //===// - } - //=== INITBITS(); - hold = 0; - bits = 0; - //===// - state.mode = EXLEN$2; - /* falls through */ - case EXLEN$2: - if (state.flags & 0x0400) { - //=== NEEDBITS(16); */ - while (bits < 16) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - state.length = hold; - if (state.head) { - state.head.extra_len = hold; - } - if ((state.flags & 0x0200) && (state.wrap & 4)) { - //=== CRC2(state.check, hold); - hbuf[0] = hold & 0xff; - hbuf[1] = (hold >>> 8) & 0xff; - state.check = crc32_1$2(state.check, hbuf, 2, 0); - //===// - } - //=== INITBITS(); - hold = 0; - bits = 0; - //===// - } - else if (state.head) { - state.head.extra = null/*Z_NULL*/; - } - state.mode = EXTRA$2; - /* falls through */ - case EXTRA$2: - if (state.flags & 0x0400) { - copy = state.length; - if (copy > have) { copy = have; } - if (copy) { - if (state.head) { - len = state.head.extra_len - state.length; - if (!state.head.extra) { - // Use untyped array for more convenient processing later - state.head.extra = new Uint8Array(state.head.extra_len); - } - state.head.extra.set( - input.subarray( - next, - // extra field is limited to 65536 bytes - // - no need for additional size check - next + copy - ), - /*len + copy > state.head.extra_max - len ? state.head.extra_max : copy,*/ - len - ); - //zmemcpy(state.head.extra + len, next, - // len + copy > state.head.extra_max ? - // state.head.extra_max - len : copy); - } - if ((state.flags & 0x0200) && (state.wrap & 4)) { - state.check = crc32_1$2(state.check, input, copy, next); - } - have -= copy; - next += copy; - state.length -= copy; - } - if (state.length) { break inf_leave; } - } - state.length = 0; - state.mode = NAME$2; - /* falls through */ - case NAME$2: - if (state.flags & 0x0800) { - if (have === 0) { break inf_leave; } - copy = 0; - do { - // TODO: 2 or 1 bytes? - len = input[next + copy++]; - /* use constant limit because in js we should not preallocate memory */ - if (state.head && len && - (state.length < 65536 /*state.head.name_max*/)) { - state.head.name += String.fromCharCode(len); - } - } while (len && copy < have); - - if ((state.flags & 0x0200) && (state.wrap & 4)) { - state.check = crc32_1$2(state.check, input, copy, next); - } - have -= copy; - next += copy; - if (len) { break inf_leave; } - } - else if (state.head) { - state.head.name = null; - } - state.length = 0; - state.mode = COMMENT$2; - /* falls through */ - case COMMENT$2: - if (state.flags & 0x1000) { - if (have === 0) { break inf_leave; } - copy = 0; - do { - len = input[next + copy++]; - /* use constant limit because in js we should not preallocate memory */ - if (state.head && len && - (state.length < 65536 /*state.head.comm_max*/)) { - state.head.comment += String.fromCharCode(len); - } - } while (len && copy < have); - if ((state.flags & 0x0200) && (state.wrap & 4)) { - state.check = crc32_1$2(state.check, input, copy, next); - } - have -= copy; - next += copy; - if (len) { break inf_leave; } - } - else if (state.head) { - state.head.comment = null; - } - state.mode = HCRC$2; - /* falls through */ - case HCRC$2: - if (state.flags & 0x0200) { - //=== NEEDBITS(16); */ - while (bits < 16) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - if ((state.wrap & 4) && hold !== (state.check & 0xffff)) { - strm.msg = 'header crc mismatch'; - state.mode = BAD$3; - break; - } - //=== INITBITS(); - hold = 0; - bits = 0; - //===// - } - if (state.head) { - state.head.hcrc = ((state.flags >> 9) & 1); - state.head.done = true; - } - strm.adler = state.check = 0; - state.mode = TYPE$3; - break; - case DICTID$2: - //=== NEEDBITS(32); */ - while (bits < 32) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - strm.adler = state.check = zswap32$2(hold); - //=== INITBITS(); - hold = 0; - bits = 0; - //===// - state.mode = DICT$2; - /* falls through */ - case DICT$2: - if (state.havedict === 0) { - //--- RESTORE() --- - strm.next_out = put; - strm.avail_out = left; - strm.next_in = next; - strm.avail_in = have; - state.hold = hold; - state.bits = bits; - //--- - return Z_NEED_DICT$1$2; - } - strm.adler = state.check = 1/*adler32(0L, Z_NULL, 0)*/; - state.mode = TYPE$3; - /* falls through */ - case TYPE$3: - if (flush === Z_BLOCK$3 || flush === Z_TREES$2) { break inf_leave; } - /* falls through */ - case TYPEDO$2: - if (state.last) { - //--- BYTEBITS() ---// - hold >>>= bits & 7; - bits -= bits & 7; - //---// - state.mode = CHECK$2; - break; - } - //=== NEEDBITS(3); */ - while (bits < 3) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - state.last = (hold & 0x01)/*BITS(1)*/; - //--- DROPBITS(1) ---// - hold >>>= 1; - bits -= 1; - //---// - - switch ((hold & 0x03)/*BITS(2)*/) { - case 0: /* stored block */ - //Tracev((stderr, "inflate: stored block%s\n", - // state.last ? " (last)" : "")); - state.mode = STORED$2; - break; - case 1: /* fixed block */ - fixedtables$2(state); - //Tracev((stderr, "inflate: fixed codes block%s\n", - // state.last ? " (last)" : "")); - state.mode = LEN_$2; /* decode codes */ - if (flush === Z_TREES$2) { - //--- DROPBITS(2) ---// - hold >>>= 2; - bits -= 2; - //---// - break inf_leave; - } - break; - case 2: /* dynamic block */ - //Tracev((stderr, "inflate: dynamic codes block%s\n", - // state.last ? " (last)" : "")); - state.mode = TABLE$2; - break; - case 3: - strm.msg = 'invalid block type'; - state.mode = BAD$3; - } - //--- DROPBITS(2) ---// - hold >>>= 2; - bits -= 2; - //---// - break; - case STORED$2: - //--- BYTEBITS() ---// /* go to byte boundary */ - hold >>>= bits & 7; - bits -= bits & 7; - //---// - //=== NEEDBITS(32); */ - while (bits < 32) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - if ((hold & 0xffff) !== ((hold >>> 16) ^ 0xffff)) { - strm.msg = 'invalid stored block lengths'; - state.mode = BAD$3; - break; - } - state.length = hold & 0xffff; - //Tracev((stderr, "inflate: stored length %u\n", - // state.length)); - //=== INITBITS(); - hold = 0; - bits = 0; - //===// - state.mode = COPY_$2; - if (flush === Z_TREES$2) { break inf_leave; } - /* falls through */ - case COPY_$2: - state.mode = COPY$2; - /* falls through */ - case COPY$2: - copy = state.length; - if (copy) { - if (copy > have) { copy = have; } - if (copy > left) { copy = left; } - if (copy === 0) { break inf_leave; } - //--- zmemcpy(put, next, copy); --- - output.set(input.subarray(next, next + copy), put); - //---// - have -= copy; - next += copy; - left -= copy; - put += copy; - state.length -= copy; - break; - } - //Tracev((stderr, "inflate: stored end\n")); - state.mode = TYPE$3; - break; - case TABLE$2: - //=== NEEDBITS(14); */ - while (bits < 14) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - state.nlen = (hold & 0x1f)/*BITS(5)*/ + 257; - //--- DROPBITS(5) ---// - hold >>>= 5; - bits -= 5; - //---// - state.ndist = (hold & 0x1f)/*BITS(5)*/ + 1; - //--- DROPBITS(5) ---// - hold >>>= 5; - bits -= 5; - //---// - state.ncode = (hold & 0x0f)/*BITS(4)*/ + 4; - //--- DROPBITS(4) ---// - hold >>>= 4; - bits -= 4; - //---// -//#ifndef PKZIP_BUG_WORKAROUND - if (state.nlen > 286 || state.ndist > 30) { - strm.msg = 'too many length or distance symbols'; - state.mode = BAD$3; - break; - } -//#endif - //Tracev((stderr, "inflate: table sizes ok\n")); - state.have = 0; - state.mode = LENLENS$2; - /* falls through */ - case LENLENS$2: - while (state.have < state.ncode) { - //=== NEEDBITS(3); - while (bits < 3) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - state.lens[order[state.have++]] = (hold & 0x07);//BITS(3); - //--- DROPBITS(3) ---// - hold >>>= 3; - bits -= 3; - //---// - } - while (state.have < 19) { - state.lens[order[state.have++]] = 0; - } - // We have separate tables & no pointers. 2 commented lines below not needed. - //state.next = state.codes; - //state.lencode = state.next; - // Switch to use dynamic table - state.lencode = state.lendyn; - state.lenbits = 7; - - opts = { bits: state.lenbits }; - ret = inftrees$2(CODES$3, state.lens, 0, 19, state.lencode, 0, state.work, opts); - state.lenbits = opts.bits; - - if (ret) { - strm.msg = 'invalid code lengths set'; - state.mode = BAD$3; - break; - } - //Tracev((stderr, "inflate: code lengths ok\n")); - state.have = 0; - state.mode = CODELENS$2; - /* falls through */ - case CODELENS$2: - while (state.have < state.nlen + state.ndist) { - for (;;) { - here = state.lencode[hold & ((1 << state.lenbits) - 1)];/*BITS(state.lenbits)*/ - here_bits = here >>> 24; - here_op = (here >>> 16) & 0xff; - here_val = here & 0xffff; - - if ((here_bits) <= bits) { break; } - //--- PULLBYTE() ---// - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - //---// - } - if (here_val < 16) { - //--- DROPBITS(here.bits) ---// - hold >>>= here_bits; - bits -= here_bits; - //---// - state.lens[state.have++] = here_val; - } - else { - if (here_val === 16) { - //=== NEEDBITS(here.bits + 2); - n = here_bits + 2; - while (bits < n) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - //--- DROPBITS(here.bits) ---// - hold >>>= here_bits; - bits -= here_bits; - //---// - if (state.have === 0) { - strm.msg = 'invalid bit length repeat'; - state.mode = BAD$3; - break; - } - len = state.lens[state.have - 1]; - copy = 3 + (hold & 0x03);//BITS(2); - //--- DROPBITS(2) ---// - hold >>>= 2; - bits -= 2; - //---// - } - else if (here_val === 17) { - //=== NEEDBITS(here.bits + 3); - n = here_bits + 3; - while (bits < n) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - //--- DROPBITS(here.bits) ---// - hold >>>= here_bits; - bits -= here_bits; - //---// - len = 0; - copy = 3 + (hold & 0x07);//BITS(3); - //--- DROPBITS(3) ---// - hold >>>= 3; - bits -= 3; - //---// - } - else { - //=== NEEDBITS(here.bits + 7); - n = here_bits + 7; - while (bits < n) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - //--- DROPBITS(here.bits) ---// - hold >>>= here_bits; - bits -= here_bits; - //---// - len = 0; - copy = 11 + (hold & 0x7f);//BITS(7); - //--- DROPBITS(7) ---// - hold >>>= 7; - bits -= 7; - //---// - } - if (state.have + copy > state.nlen + state.ndist) { - strm.msg = 'invalid bit length repeat'; - state.mode = BAD$3; - break; - } - while (copy--) { - state.lens[state.have++] = len; - } - } - } - - /* handle error breaks in while */ - if (state.mode === BAD$3) { break; } - - /* check for end-of-block code (better have one) */ - if (state.lens[256] === 0) { - strm.msg = 'invalid code -- missing end-of-block'; - state.mode = BAD$3; - break; - } - - /* build code tables -- note: do not change the lenbits or distbits - values here (9 and 6) without reading the comments in inftrees.h - concerning the ENOUGH constants, which depend on those values */ - state.lenbits = 9; - - opts = { bits: state.lenbits }; - ret = inftrees$2(LENS$3, state.lens, 0, state.nlen, state.lencode, 0, state.work, opts); - // We have separate tables & no pointers. 2 commented lines below not needed. - // state.next_index = opts.table_index; - state.lenbits = opts.bits; - // state.lencode = state.next; - - if (ret) { - strm.msg = 'invalid literal/lengths set'; - state.mode = BAD$3; - break; - } - - state.distbits = 6; - //state.distcode.copy(state.codes); - // Switch to use dynamic table - state.distcode = state.distdyn; - opts = { bits: state.distbits }; - ret = inftrees$2(DISTS$3, state.lens, state.nlen, state.ndist, state.distcode, 0, state.work, opts); - // We have separate tables & no pointers. 2 commented lines below not needed. - // state.next_index = opts.table_index; - state.distbits = opts.bits; - // state.distcode = state.next; - - if (ret) { - strm.msg = 'invalid distances set'; - state.mode = BAD$3; - break; - } - //Tracev((stderr, 'inflate: codes ok\n')); - state.mode = LEN_$2; - if (flush === Z_TREES$2) { break inf_leave; } - /* falls through */ - case LEN_$2: - state.mode = LEN$2; - /* falls through */ - case LEN$2: - if (have >= 6 && left >= 258) { - //--- RESTORE() --- - strm.next_out = put; - strm.avail_out = left; - strm.next_in = next; - strm.avail_in = have; - state.hold = hold; - state.bits = bits; - //--- - inffast$2(strm, _out); - //--- LOAD() --- - put = strm.next_out; - output = strm.output; - left = strm.avail_out; - next = strm.next_in; - input = strm.input; - have = strm.avail_in; - hold = state.hold; - bits = state.bits; - //--- - - if (state.mode === TYPE$3) { - state.back = -1; - } - break; - } - state.back = 0; - for (;;) { - here = state.lencode[hold & ((1 << state.lenbits) - 1)]; /*BITS(state.lenbits)*/ - here_bits = here >>> 24; - here_op = (here >>> 16) & 0xff; - here_val = here & 0xffff; - - if (here_bits <= bits) { break; } - //--- PULLBYTE() ---// - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - //---// - } - if (here_op && (here_op & 0xf0) === 0) { - last_bits = here_bits; - last_op = here_op; - last_val = here_val; - for (;;) { - here = state.lencode[last_val + - ((hold & ((1 << (last_bits + last_op)) - 1))/*BITS(last.bits + last.op)*/ >> last_bits)]; - here_bits = here >>> 24; - here_op = (here >>> 16) & 0xff; - here_val = here & 0xffff; - - if ((last_bits + here_bits) <= bits) { break; } - //--- PULLBYTE() ---// - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - //---// - } - //--- DROPBITS(last.bits) ---// - hold >>>= last_bits; - bits -= last_bits; - //---// - state.back += last_bits; - } - //--- DROPBITS(here.bits) ---// - hold >>>= here_bits; - bits -= here_bits; - //---// - state.back += here_bits; - state.length = here_val; - if (here_op === 0) { - //Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? - // "inflate: literal '%c'\n" : - // "inflate: literal 0x%02x\n", here.val)); - state.mode = LIT$2; - break; - } - if (here_op & 32) { - //Tracevv((stderr, "inflate: end of block\n")); - state.back = -1; - state.mode = TYPE$3; - break; - } - if (here_op & 64) { - strm.msg = 'invalid literal/length code'; - state.mode = BAD$3; - break; - } - state.extra = here_op & 15; - state.mode = LENEXT$2; - /* falls through */ - case LENEXT$2: - if (state.extra) { - //=== NEEDBITS(state.extra); - n = state.extra; - while (bits < n) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - state.length += hold & ((1 << state.extra) - 1)/*BITS(state.extra)*/; - //--- DROPBITS(state.extra) ---// - hold >>>= state.extra; - bits -= state.extra; - //---// - state.back += state.extra; - } - //Tracevv((stderr, "inflate: length %u\n", state.length)); - state.was = state.length; - state.mode = DIST$2; - /* falls through */ - case DIST$2: - for (;;) { - here = state.distcode[hold & ((1 << state.distbits) - 1)];/*BITS(state.distbits)*/ - here_bits = here >>> 24; - here_op = (here >>> 16) & 0xff; - here_val = here & 0xffff; - - if ((here_bits) <= bits) { break; } - //--- PULLBYTE() ---// - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - //---// - } - if ((here_op & 0xf0) === 0) { - last_bits = here_bits; - last_op = here_op; - last_val = here_val; - for (;;) { - here = state.distcode[last_val + - ((hold & ((1 << (last_bits + last_op)) - 1))/*BITS(last.bits + last.op)*/ >> last_bits)]; - here_bits = here >>> 24; - here_op = (here >>> 16) & 0xff; - here_val = here & 0xffff; - - if ((last_bits + here_bits) <= bits) { break; } - //--- PULLBYTE() ---// - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - //---// - } - //--- DROPBITS(last.bits) ---// - hold >>>= last_bits; - bits -= last_bits; - //---// - state.back += last_bits; - } - //--- DROPBITS(here.bits) ---// - hold >>>= here_bits; - bits -= here_bits; - //---// - state.back += here_bits; - if (here_op & 64) { - strm.msg = 'invalid distance code'; - state.mode = BAD$3; - break; - } - state.offset = here_val; - state.extra = (here_op) & 15; - state.mode = DISTEXT$2; - /* falls through */ - case DISTEXT$2: - if (state.extra) { - //=== NEEDBITS(state.extra); - n = state.extra; - while (bits < n) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - state.offset += hold & ((1 << state.extra) - 1)/*BITS(state.extra)*/; - //--- DROPBITS(state.extra) ---// - hold >>>= state.extra; - bits -= state.extra; - //---// - state.back += state.extra; - } -//#ifdef INFLATE_STRICT - if (state.offset > state.dmax) { - strm.msg = 'invalid distance too far back'; - state.mode = BAD$3; - break; - } -//#endif - //Tracevv((stderr, "inflate: distance %u\n", state.offset)); - state.mode = MATCH$2; - /* falls through */ - case MATCH$2: - if (left === 0) { break inf_leave; } - copy = _out - left; - if (state.offset > copy) { /* copy from window */ - copy = state.offset - copy; - if (copy > state.whave) { - if (state.sane) { - strm.msg = 'invalid distance too far back'; - state.mode = BAD$3; - break; - } -// (!) This block is disabled in zlib defaults, -// don't enable it for binary compatibility -//#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR -// Trace((stderr, "inflate.c too far\n")); -// copy -= state.whave; -// if (copy > state.length) { copy = state.length; } -// if (copy > left) { copy = left; } -// left -= copy; -// state.length -= copy; -// do { -// output[put++] = 0; -// } while (--copy); -// if (state.length === 0) { state.mode = LEN; } -// break; -//#endif - } - if (copy > state.wnext) { - copy -= state.wnext; - from = state.wsize - copy; - } - else { - from = state.wnext - copy; - } - if (copy > state.length) { copy = state.length; } - from_source = state.window; - } - else { /* copy from output */ - from_source = output; - from = put - state.offset; - copy = state.length; - } - if (copy > left) { copy = left; } - left -= copy; - state.length -= copy; - do { - output[put++] = from_source[from++]; - } while (--copy); - if (state.length === 0) { state.mode = LEN$2; } - break; - case LIT$2: - if (left === 0) { break inf_leave; } - output[put++] = state.length; - left--; - state.mode = LEN$2; - break; - case CHECK$2: - if (state.wrap) { - //=== NEEDBITS(32); - while (bits < 32) { - if (have === 0) { break inf_leave; } - have--; - // Use '|' instead of '+' to make sure that result is signed - hold |= input[next++] << bits; - bits += 8; - } - //===// - _out -= left; - strm.total_out += _out; - state.total += _out; - if ((state.wrap & 4) && _out) { - strm.adler = state.check = - /*UPDATE_CHECK(state.check, put - _out, _out);*/ - (state.flags ? crc32_1$2(state.check, output, _out, put - _out) : adler32_1$2(state.check, output, _out, put - _out)); - - } - _out = left; - // NB: crc32 stored as signed 32-bit int, zswap32 returns signed too - if ((state.wrap & 4) && (state.flags ? hold : zswap32$2(hold)) !== state.check) { - strm.msg = 'incorrect data check'; - state.mode = BAD$3; - break; - } - //=== INITBITS(); - hold = 0; - bits = 0; - //===// - //Tracev((stderr, "inflate: check matches trailer\n")); - } - state.mode = LENGTH$2; - /* falls through */ - case LENGTH$2: - if (state.wrap && state.flags) { - //=== NEEDBITS(32); - while (bits < 32) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - if ((state.wrap & 4) && hold !== (state.total & 0xffffffff)) { - strm.msg = 'incorrect length check'; - state.mode = BAD$3; - break; - } - //=== INITBITS(); - hold = 0; - bits = 0; - //===// - //Tracev((stderr, "inflate: length matches trailer\n")); - } - state.mode = DONE$2; - /* falls through */ - case DONE$2: - ret = Z_STREAM_END$1$2; - break inf_leave; - case BAD$3: - ret = Z_DATA_ERROR$1$2; - break inf_leave; - case MEM$2: - return Z_MEM_ERROR$1$2; - case SYNC$2: - /* falls through */ - default: - return Z_STREAM_ERROR$1$2; - } - } - - // inf_leave <- here is real place for "goto inf_leave", emulated via "break inf_leave" - - /* - Return from inflate(), updating the total counts and the check value. - If there was no progress during the inflate() call, return a buffer - error. Call updatewindow() to create and/or update the window state. - Note: a memory error from inflate() is non-recoverable. - */ - - //--- RESTORE() --- - strm.next_out = put; - strm.avail_out = left; - strm.next_in = next; - strm.avail_in = have; - state.hold = hold; - state.bits = bits; - //--- - - if (state.wsize || (_out !== strm.avail_out && state.mode < BAD$3 && - (state.mode < CHECK$2 || flush !== Z_FINISH$1$2))) { - if (updatewindow$2(strm, strm.output, strm.next_out, _out - strm.avail_out)) ; - } - _in -= strm.avail_in; - _out -= strm.avail_out; - strm.total_in += _in; - strm.total_out += _out; - state.total += _out; - if ((state.wrap & 4) && _out) { - strm.adler = state.check = /*UPDATE_CHECK(state.check, strm.next_out - _out, _out);*/ - (state.flags ? crc32_1$2(state.check, output, _out, strm.next_out - _out) : adler32_1$2(state.check, output, _out, strm.next_out - _out)); - } - strm.data_type = state.bits + (state.last ? 64 : 0) + - (state.mode === TYPE$3 ? 128 : 0) + - (state.mode === LEN_$2 || state.mode === COPY_$2 ? 256 : 0); - if (((_in === 0 && _out === 0) || flush === Z_FINISH$1$2) && ret === Z_OK$1$2) { - ret = Z_BUF_ERROR$3; - } - return ret; -}; - - -const inflateEnd$2 = (strm) => { - - if (inflateStateCheck$1(strm)) { - return Z_STREAM_ERROR$1$2; - } - - let state = strm.state; - if (state.window) { - state.window = null; - } - strm.state = null; - return Z_OK$1$2; -}; - - -const inflateGetHeader$2 = (strm, head) => { - - /* check state */ - if (inflateStateCheck$1(strm)) { return Z_STREAM_ERROR$1$2; } - const state = strm.state; - if ((state.wrap & 2) === 0) { return Z_STREAM_ERROR$1$2; } - - /* save header structure */ - state.head = head; - head.done = false; - return Z_OK$1$2; -}; - - -const inflateSetDictionary$2 = (strm, dictionary) => { - const dictLength = dictionary.length; - - let state; - let dictid; - let ret; - - /* check state */ - if (inflateStateCheck$1(strm)) { return Z_STREAM_ERROR$1$2; } - state = strm.state; - - if (state.wrap !== 0 && state.mode !== DICT$2) { - return Z_STREAM_ERROR$1$2; - } - - /* check for correct dictionary identifier */ - if (state.mode === DICT$2) { - dictid = 1; /* adler32(0, null, 0)*/ - /* dictid = adler32(dictid, dictionary, dictLength); */ - dictid = adler32_1$2(dictid, dictionary, dictLength, 0); - if (dictid !== state.check) { - return Z_DATA_ERROR$1$2; - } - } - /* copy dictionary to window using updatewindow(), which will amend the - existing dictionary if appropriate */ - ret = updatewindow$2(strm, dictionary, dictLength, dictLength); - if (ret) { - state.mode = MEM$2; - return Z_MEM_ERROR$1$2; - } - state.havedict = 1; - // Tracev((stderr, "inflate: dictionary set\n")); - return Z_OK$1$2; -}; - - -var inflateReset_1$2 = inflateReset$2; -var inflateReset2_1$2 = inflateReset2$2; -var inflateResetKeep_1$2 = inflateResetKeep$2; -var inflateInit_1$2 = inflateInit$2; -var inflateInit2_1$2 = inflateInit2$2; -var inflate_2$1$2 = inflate$2$2; -var inflateEnd_1$2 = inflateEnd$2; -var inflateGetHeader_1$2 = inflateGetHeader$2; -var inflateSetDictionary_1$2 = inflateSetDictionary$2; -var inflateInfo$2 = 'pako inflate (from Nodeca project)'; - -/* Not implemented -module.exports.inflateCodesUsed = inflateCodesUsed; -module.exports.inflateCopy = inflateCopy; -module.exports.inflateGetDictionary = inflateGetDictionary; -module.exports.inflateMark = inflateMark; -module.exports.inflatePrime = inflatePrime; -module.exports.inflateSync = inflateSync; -module.exports.inflateSyncPoint = inflateSyncPoint; -module.exports.inflateUndermine = inflateUndermine; -module.exports.inflateValidate = inflateValidate; -*/ - -var inflate_1$2$2 = { - inflateReset: inflateReset_1$2, - inflateReset2: inflateReset2_1$2, - inflateResetKeep: inflateResetKeep_1$2, - inflateInit: inflateInit_1$2, - inflateInit2: inflateInit2_1$2, - inflate: inflate_2$1$2, - inflateEnd: inflateEnd_1$2, - inflateGetHeader: inflateGetHeader_1$2, - inflateSetDictionary: inflateSetDictionary_1$2, - inflateInfo: inflateInfo$2 -}; - -// (C) 1995-2013 Jean-loup Gailly and Mark Adler -// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// 3. This notice may not be removed or altered from any source distribution. - -function GZheader$2() { - /* true if compressed data believed to be text */ - this.text = 0; - /* modification time */ - this.time = 0; - /* extra flags (not used when writing a gzip file) */ - this.xflags = 0; - /* operating system */ - this.os = 0; - /* pointer to extra field or Z_NULL if none */ - this.extra = null; - /* extra field length (valid if extra != Z_NULL) */ - this.extra_len = 0; // Actually, we don't need it in JS, - // but leave for few code modifications - - // - // Setup limits is not necessary because in js we should not preallocate memory - // for inflate use constant limit in 65536 bytes - // - - /* space at extra (only when reading header) */ - // this.extra_max = 0; - /* pointer to zero-terminated file name or Z_NULL */ - this.name = ''; - /* space at name (only when reading header) */ - // this.name_max = 0; - /* pointer to zero-terminated comment or Z_NULL */ - this.comment = ''; - /* space at comment (only when reading header) */ - // this.comm_max = 0; - /* true if there was or will be a header crc */ - this.hcrc = 0; - /* true when done reading gzip header (not used when writing a gzip file) */ - this.done = false; -} - -var gzheader$2 = GZheader$2; - -const toString$4 = Object.prototype.toString; - -/* Public constants ==========================================================*/ -/* ===========================================================================*/ - -const { - Z_NO_FLUSH: Z_NO_FLUSH$4, Z_FINISH: Z_FINISH$5, - Z_OK: Z_OK$5, Z_STREAM_END: Z_STREAM_END$5, Z_NEED_DICT: Z_NEED_DICT$3, Z_STREAM_ERROR: Z_STREAM_ERROR$4, Z_DATA_ERROR: Z_DATA_ERROR$4, Z_MEM_ERROR: Z_MEM_ERROR$3 -} = constants$2$2; - -/* ===========================================================================*/ - - -/** - * class Inflate - * - * Generic JS-style wrapper for zlib calls. If you don't need - * streaming behaviour - use more simple functions: [[inflate]] - * and [[inflateRaw]]. - **/ - -/* internal - * inflate.chunks -> Array - * - * Chunks of output data, if [[Inflate#onData]] not overridden. - **/ - -/** - * Inflate.result -> Uint8Array|String - * - * Uncompressed result, generated by default [[Inflate#onData]] - * and [[Inflate#onEnd]] handlers. Filled after you push last chunk - * (call [[Inflate#push]] with `Z_FINISH` / `true` param). - **/ - -/** - * Inflate.err -> Number - * - * Error code after inflate finished. 0 (Z_OK) on success. - * Should be checked if broken data possible. - **/ - -/** - * Inflate.msg -> String - * - * Error message, if [[Inflate.err]] != 0 - **/ - - -/** - * new Inflate(options) - * - options (Object): zlib inflate options. - * - * Creates new inflator instance with specified params. Throws exception - * on bad params. Supported options: - * - * - `windowBits` - * - `dictionary` - * - * [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced) - * for more information on these. - * - * Additional options, for internal needs: - * - * - `chunkSize` - size of generated data chunks (16K by default) - * - `raw` (Boolean) - do raw inflate - * - `to` (String) - if equal to 'string', then result will be converted - * from utf8 to utf16 (javascript) string. When string output requested, - * chunk length can differ from `chunkSize`, depending on content. - * - * By default, when no options set, autodetect deflate/gzip data format via - * wrapper header. - * - * ##### Example: - * - * ```javascript - * const pako = require('pako') - * const chunk1 = new Uint8Array([1,2,3,4,5,6,7,8,9]) - * const chunk2 = new Uint8Array([10,11,12,13,14,15,16,17,18,19]); - * - * const inflate = new pako.Inflate({ level: 3}); - * - * inflate.push(chunk1, false); - * inflate.push(chunk2, true); // true -> last chunk - * - * if (inflate.err) { throw new Error(inflate.err); } - * - * console.log(inflate.result); - * ``` - **/ -function Inflate$1$2(options) { - this.options = common$2.assign({ - chunkSize: 1024 * 64, - windowBits: 15, - to: '' - }, options || {}); - - const opt = this.options; - - // Force window size for `raw` data, if not set directly, - // because we have no header for autodetect. - if (opt.raw && (opt.windowBits >= 0) && (opt.windowBits < 16)) { - opt.windowBits = -opt.windowBits; - if (opt.windowBits === 0) { opt.windowBits = -15; } - } - - // If `windowBits` not defined (and mode not raw) - set autodetect flag for gzip/deflate - if ((opt.windowBits >= 0) && (opt.windowBits < 16) && - !(options && options.windowBits)) { - opt.windowBits += 32; - } - - // Gzip header has no info about windows size, we can do autodetect only - // for deflate. So, if window size not set, force it to max when gzip possible - if ((opt.windowBits > 15) && (opt.windowBits < 48)) { - // bit 3 (16) -> gzipped data - // bit 4 (32) -> autodetect gzip/deflate - if ((opt.windowBits & 15) === 0) { - opt.windowBits |= 15; - } - } - - this.err = 0; // error code, if happens (0 = Z_OK) - this.msg = ''; // error message - this.ended = false; // used to avoid multiple onEnd() calls - this.chunks = []; // chunks of compressed data - - this.strm = new zstream$2(); - this.strm.avail_out = 0; - - let status = inflate_1$2$2.inflateInit2( - this.strm, - opt.windowBits - ); - - if (status !== Z_OK$5) { - throw new Error(messages$2[status]); - } - - this.header = new gzheader$2(); - - inflate_1$2$2.inflateGetHeader(this.strm, this.header); - - // Setup dictionary - if (opt.dictionary) { - // Convert data if needed - if (typeof opt.dictionary === 'string') { - opt.dictionary = strings$2.string2buf(opt.dictionary); - } else if (toString$4.call(opt.dictionary) === '[object ArrayBuffer]') { - opt.dictionary = new Uint8Array(opt.dictionary); - } - if (opt.raw) { //In raw mode we need to set the dictionary early - status = inflate_1$2$2.inflateSetDictionary(this.strm, opt.dictionary); - if (status !== Z_OK$5) { - throw new Error(messages$2[status]); - } - } - } -} - -/** - * Inflate#push(data[, flush_mode]) -> Boolean - * - data (Uint8Array|ArrayBuffer): input data - * - flush_mode (Number|Boolean): 0..6 for corresponding Z_NO_FLUSH..Z_TREE - * flush modes. See constants. Skipped or `false` means Z_NO_FLUSH, - * `true` means Z_FINISH. - * - * Sends input data to inflate pipe, generating [[Inflate#onData]] calls with - * new output chunks. Returns `true` on success. If end of stream detected, - * [[Inflate#onEnd]] will be called. - * - * `flush_mode` is not needed for normal operation, because end of stream - * detected automatically. You may try to use it for advanced things, but - * this functionality was not tested. - * - * On fail call [[Inflate#onEnd]] with error code and return false. - * - * ##### Example - * - * ```javascript - * push(chunk, false); // push one of data chunks - * ... - * push(chunk, true); // push last chunk - * ``` - **/ -Inflate$1$2.prototype.push = function (data, flush_mode) { - const strm = this.strm; - const chunkSize = this.options.chunkSize; - const dictionary = this.options.dictionary; - let status, _flush_mode, last_avail_out; - - if (this.ended) return false; - - if (flush_mode === ~~flush_mode) _flush_mode = flush_mode; - else _flush_mode = flush_mode === true ? Z_FINISH$5 : Z_NO_FLUSH$4; - - // Convert data if needed - if (toString$4.call(data) === '[object ArrayBuffer]') { - strm.input = new Uint8Array(data); - } else { - strm.input = data; - } - - strm.next_in = 0; - strm.avail_in = strm.input.length; - - for (;;) { - if (strm.avail_out === 0) { - strm.output = new Uint8Array(chunkSize); - strm.next_out = 0; - strm.avail_out = chunkSize; - } - - status = inflate_1$2$2.inflate(strm, _flush_mode); - - if (status === Z_NEED_DICT$3 && dictionary) { - status = inflate_1$2$2.inflateSetDictionary(strm, dictionary); - - if (status === Z_OK$5) { - status = inflate_1$2$2.inflate(strm, _flush_mode); - } else if (status === Z_DATA_ERROR$4) { - // Replace code with more verbose - status = Z_NEED_DICT$3; - } - } - - // Skip snyc markers if more data follows and not raw mode - while (strm.avail_in > 0 && - status === Z_STREAM_END$5 && - strm.state.wrap > 0 && - data[strm.next_in] !== 0) - { - inflate_1$2$2.inflateReset(strm); - status = inflate_1$2$2.inflate(strm, _flush_mode); - } - - switch (status) { - case Z_STREAM_ERROR$4: - case Z_DATA_ERROR$4: - case Z_NEED_DICT$3: - case Z_MEM_ERROR$3: - this.onEnd(status); - this.ended = true; - return false; - } - - // Remember real `avail_out` value, because we may patch out buffer content - // to align utf8 strings boundaries. - last_avail_out = strm.avail_out; - - if (strm.next_out) { - if (strm.avail_out === 0 || status === Z_STREAM_END$5) { - - if (this.options.to === 'string') { - - let next_out_utf8 = strings$2.utf8border(strm.output, strm.next_out); - - let tail = strm.next_out - next_out_utf8; - let utf8str = strings$2.buf2string(strm.output, next_out_utf8); - - // move tail & realign counters - strm.next_out = tail; - strm.avail_out = chunkSize - tail; - if (tail) strm.output.set(strm.output.subarray(next_out_utf8, next_out_utf8 + tail), 0); - - this.onData(utf8str); - - } else { - this.onData(strm.output.length === strm.next_out ? strm.output : strm.output.subarray(0, strm.next_out)); - } - } - } - - // Must repeat iteration if out buffer is full - if (status === Z_OK$5 && last_avail_out === 0) continue; - - // Finalize if end of stream reached. - if (status === Z_STREAM_END$5) { - status = inflate_1$2$2.inflateEnd(this.strm); - this.onEnd(status); - this.ended = true; - return true; - } - - if (strm.avail_in === 0) break; - } - - return true; -}; - - -/** - * Inflate#onData(chunk) -> Void - * - chunk (Uint8Array|String): output data. When string output requested, - * each chunk will be string. - * - * By default, stores data blocks in `chunks[]` property and glue - * those in `onEnd`. Override this handler, if you need another behaviour. - **/ -Inflate$1$2.prototype.onData = function (chunk) { - this.chunks.push(chunk); -}; - - -/** - * Inflate#onEnd(status) -> Void - * - status (Number): inflate status. 0 (Z_OK) on success, - * other if not. - * - * Called either after you tell inflate that the input stream is - * complete (Z_FINISH). By default - join collected chunks, - * free memory and fill `results` / `err` properties. - **/ -Inflate$1$2.prototype.onEnd = function (status) { - // On success - join - if (status === Z_OK$5) { - if (this.options.to === 'string') { - this.result = this.chunks.join(''); - } else { - this.result = common$2.flattenChunks(this.chunks); - } - } - this.chunks = []; - this.err = status; - this.msg = this.strm.msg; -}; - - -/** - * inflate(data[, options]) -> Uint8Array|String - * - data (Uint8Array|ArrayBuffer): input data to decompress. - * - options (Object): zlib inflate options. - * - * Decompress `data` with inflate/ungzip and `options`. Autodetect - * format via wrapper header by default. That's why we don't provide - * separate `ungzip` method. - * - * Supported options are: - * - * - windowBits - * - * [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced) - * for more information. - * - * Sugar (options): - * - * - `raw` (Boolean) - say that we work with raw stream, if you don't wish to specify - * negative windowBits implicitly. - * - `to` (String) - if equal to 'string', then result will be converted - * from utf8 to utf16 (javascript) string. When string output requested, - * chunk length can differ from `chunkSize`, depending on content. - * - * - * ##### Example: - * - * ```javascript - * const pako = require('pako'); - * const input = pako.deflate(new Uint8Array([1,2,3,4,5,6,7,8,9])); - * let output; - * - * try { - * output = pako.inflate(input); - * } catch (err) { - * console.log(err); - * } - * ``` - **/ -function inflate$1$2(input, options) { - const inflator = new Inflate$1$2(options); - - inflator.push(input); - - // That will never happens, if you don't cheat with options :) - if (inflator.err) throw inflator.msg || messages$2[inflator.err]; - - return inflator.result; -} - - -/** - * inflateRaw(data[, options]) -> Uint8Array|String - * - data (Uint8Array|ArrayBuffer): input data to decompress. - * - options (Object): zlib inflate options. - * - * The same as [[inflate]], but creates raw data, without wrapper - * (header and adler32 crc). - **/ -function inflateRaw$1$2(input, options) { - options = options || {}; - options.raw = true; - return inflate$1$2(input, options); -} - - -/** - * ungzip(data[, options]) -> Uint8Array|String - * - data (Uint8Array|ArrayBuffer): input data to decompress. - * - options (Object): zlib inflate options. - * - * Just shortcut to [[inflate]], because it autodetects format - * by header.content. Done for convenience. - **/ - - -var Inflate_1$1$2 = Inflate$1$2; -var inflate_2$3 = inflate$1$2; -var inflateRaw_1$1$2 = inflateRaw$1$2; -var ungzip$1$2 = inflate$1$2; -var constants$4 = constants$2$2; - -var inflate_1$1$2 = { - Inflate: Inflate_1$1$2, - inflate: inflate_2$3, - inflateRaw: inflateRaw_1$1$2, - ungzip: ungzip$1$2, - constants: constants$4 -}; - -const { Deflate: Deflate$2, deflate: deflate$3, deflateRaw: deflateRaw$2, gzip: gzip$2 } = deflate_1$1$1; - -const { Inflate: Inflate$3, inflate: inflate$4, inflateRaw: inflateRaw$3, ungzip: ungzip$3 } = inflate_1$1$2; -var deflateRaw_1$2 = deflateRaw$2; -var inflateRaw_1$2 = inflateRaw$3; -var ungzip_1$2 = ungzip$3; - -const FEXTRA$1 = 4; // gzip spec F.EXTRA flag - -function isgzipped$1(data) { - const b = ArrayBuffer.isView(data) ? data : new Uint8Array(data); - return b[0] ===31 && b[1] === 139; -} - -/** - * Pako does not properly ungzip block compressed files if > 1 block is present. Test for bgzip and use wrapper. - */ -function ungzip_blocks$1(data) { - const ba = ArrayBuffer.isView(data) ? data : new Uint8Array(data); - const b = ba[3] & FEXTRA$1; - if (b !== 0 && ba[12] === 66 && ba[13] === 67) { - return unbgzf$1(ba.buffer); - } else { - return ungzip_1$2(ba); - } -} - -// Uncompress data, assumed to be series of bgzipped blocks -function unbgzf$1(data, lim) { - - const oBlockList = []; - let ptr = 0; - let totalSize = 0; - - lim = lim || data.byteLength - 18; - - while (ptr < lim) { - try { - const ba = ArrayBuffer.isView(data) ? data : new Uint8Array(data, ptr, 18); - const xlen = (ba[11] << 8) | (ba[10]); - const flg = ba[3]; - const fextra = flg & FEXTRA$1; - const si1 = ba[12]; - const si2 = ba[13]; - const slen = (ba[15] << 8) | (ba[14]); - const bsize = ((ba[17] << 8) | (ba[16])) + 1; - const start = 12 + xlen + ptr; // Start of CDATA - const bytesLeft = data.byteLength - start; - const cDataSize = bsize - xlen - 19; - if (bytesLeft < cDataSize || cDataSize <= 0) break; - - const a = new Uint8Array(data, start, cDataSize); - const unc = inflateRaw_1$2(a); - - // const inflate = new Zlib.RawInflate(a); - // const unc = inflate.decompress(); - - ptr += (cDataSize - 1) + 26; //inflate.ip + 26 - totalSize += unc.byteLength; - oBlockList.push(unc); - } catch (e) { - console.error(e); - break; - } - } - - // Concatenate decompressed blocks - if (oBlockList.length === 1) { - return oBlockList[0]; - } else { - const out = new Uint8Array(totalSize); - let cursor = 0; - for (let i = 0; i < oBlockList.length; ++i) { - var b = new Uint8Array(oBlockList[i]); - arrayCopy$1(b, 0, out, cursor, b.length); - cursor += b.length; - } - return out; - } -} - -// From Thomas Down's zlib implementation - -const testArray$1 = new Uint8Array(1); -const hasSubarray$1 = (typeof testArray$1.subarray === 'function'); - -function arrayCopy$1(src, srcOffset, dest, destOffset, count) { - if (count === 0) { - return; - } - if (!src) { - throw "Undef src"; - } else if (!dest) { - throw "Undef dest"; - } - if (srcOffset === 0 && count === src.length) { - arrayCopy_fast$1(src, dest, destOffset); - } else if (hasSubarray$1) { - arrayCopy_fast$1(src.subarray(srcOffset, srcOffset + count), dest, destOffset); - } else if (src.BYTES_PER_ELEMENT === 1 && count > 100) { - arrayCopy_fast$1(new Uint8Array(src.buffer, src.byteOffset + srcOffset, count), dest, destOffset); - } else { - arrayCopy_slow$1(src, srcOffset, dest, destOffset, count); - } -} - -function arrayCopy_slow$1(src, srcOffset, dest, destOffset, count) { - for (let i = 0; i < count; ++i) { - dest[destOffset + i] = src[srcOffset + i]; - } -} - -function arrayCopy_fast$1(src, dest, destOffset) { - dest.set(src, destOffset); -} - - -/** - * Compress string and encode in a url safe form - * @param s - */ -function compressString$1(str) { - - const bytes = new Uint8Array(str.length); - for (var i = 0; i < str.length; i++) { - bytes[i] = str.charCodeAt(i); - } - const compressedBytes = new deflateRaw_1$2(bytes); // UInt8Arry - const compressedString = String.fromCharCode.apply(null, compressedBytes); // Convert to string - let enc = btoa(compressedString); - return enc.replace(/\+/g, '.').replace(/\//g, '_').replace(/=/g, '-'); // URL safe -} - -/** - * Uncompress the url-safe encoded compressed string, presumably created by compressString above - * - * @param enc - * @returns {string} - */ -function uncompressString$1(enc) { - - enc = enc.replace(/\./g, '+').replace(/_/g, '/').replace(/-/g, '='); - - const compressedString = atob(enc); - const compressedBytes = []; - for (let i = 0; i < compressedString.length; i++) { - compressedBytes.push(compressedString.charCodeAt(i)); - } - //const bytes = new Zlib.RawInflate(compressedBytes).decompress(); - const bytes = inflateRaw_1$2(compressedBytes); - - let str = ''; - for (let b of bytes) { - str += String.fromCharCode(b); - } - return str; -} - - -/** - * @param dataURI - * @returns {Array|Uint8Array} - */ -function decodeDataURI$2(dataURI, gzip) { - - const split = dataURI.split(','); - const info = split[0].split(':')[1]; - let dataString = split[1]; - - if (info.indexOf('base64') >= 0) { - dataString = atob(dataString); - - const bytes = new Uint8Array(dataString.length); - for (let i = 0; i < dataString.length; i++) { - bytes[i] = dataString.charCodeAt(i); - } - - let plain; - if (gzip || info.indexOf('gzip') > 0) { - plain = ungzip_1$2(bytes); - } else { - plain = bytes; - } - return plain - } else { - return decodeURIComponent(dataString); // URL encoded string -- not currently used or tested - } -} - -/* - * The MIT License (MIT) - * - * Copyright (c) 2016-2017 The Regents of the University of California - * Author: Jim Robinson - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -const IGVMath$1 = { - - lerp: (v0, v1, t) => { - return (1 - t) * v0 + t * v1; - }, - - mean: function (array) { - - var t = 0, n = 0, - i; - for (i = 0; i < array.length; i++) { - if (!isNaN(array[i])) { - t += array[i]; - n++; - } - } - return n > 0 ? t / n : 0; - }, - - meanAndStdev: function (array) { - - var v, t = 0, t2 = 0, n = 0, i; - - for (i = 0; i < array.length; i++) { - - v = array[i]; - - if (!isNaN(v)) { - t += v; - t2 += v * v; - n++; - } - } - return n > 0 ? {mean: t / n, stdev: Math.sqrt(t2 - t * t / n)} : {mean: 0, stdev: 0}; - }, - - median: function (numbers) { - // median of [3, 5, 4, 4, 1, 1, 2, 3] = 3 - var median = 0, numsLen = numbers.length; - numbers.sort(); - - if ( - numsLen % 2 === 0 // is even - ) { - // average of two middle numbers - median = (numbers[numsLen / 2 - 1] + numbers[numsLen / 2]) / 2; - } else { // is odd - // middle number only - median = numbers[(numsLen - 1) / 2]; - } - - return median; - }, - - // Fast percentile function for "p" near edges. This needs profiled for p in middle (e.g. median) - percentile: function (array, p) { - - if (array.length === 0) return undefined; - - var k = Math.floor(array.length * ((100 - p) / 100)); - if (k === 0) { - array.sort(function (a, b) { - return b - a - }); - return array[k]; - } else { - return selectElement$1(array, k); - } - - }, - - - clamp: function (value, min, max) { - return Math.min(Math.max(value, min), max); - }, - - log2: function (x) { - return Math.log(x) / Math.LN2; - } - -}; - -function selectElement$1(array, k) { - - // Credit Steve Hanov http://stevehanov.ca/blog/index.php?id=122 - var heap = new BinaryHeap$1(), - i; - - for (i = 0; i < array.length; i++) { - - var item = array[i]; - - // If we have not yet found k items, or the current item is larger than - // the smallest item on the heap, add current item - if (heap.content.length < k || item > heap.content[0]) { - // If the heap is full, remove the smallest element on the heap. - if (heap.content.length === k) { - heap.pop(); - } - heap.push(item); - } - } - - return heap.content[0]; -} - - -function BinaryHeap$1() { - this.content = []; -} - -BinaryHeap$1.prototype = { - push: function (element) { - // Add the new element to the end of the array. - this.content.push(element); - // Allow it to bubble up. - this.bubbleUp(this.content.length - 1); - }, - - pop: function () { - // Store the first element so we can return it later. - var result = this.content[0]; - // Get the element at the end of the array. - var end = this.content.pop(); - // If there are any elements left, put the end element at the - // start, and let it sink down. - if (this.content.length > 0) { - this.content[0] = end; - this.sinkDown(0); - } - return result; - }, - - remove: function (node) { - var length = this.content.length; - // To remove a value, we must search through the array to find - // it. - for (var i = 0; i < length; i++) { - if (this.content[i] !== node) continue; - // When it is found, the process seen in 'pop' is repeated - // to fill up the hole. - var end = this.content.pop(); - // If the element we popped was the one we needed to remove, - // we're done. - if (i === length - 1) break; - // Otherwise, we replace the removed element with the popped - // one, and allow it to float up or sink down as appropriate. - this.content[i] = end; - this.bubbleUp(i); - this.sinkDown(i); - break; - } - }, - - size: function () { - return this.content.length; - }, - - bubbleUp: function (n) { - // Fetch the element that has to be moved. - var element = this.content[n], score = element; - // When at 0, an element can not go up any further. - while (n > 0) { - // Compute the parent element's index, and fetch it. - var parentN = Math.floor((n + 1) / 2) - 1, - parent = this.content[parentN]; - // If the parent has a lesser score, things are in order and we - // are done. - if (score >= parent) - break; - - // Otherwise, swap the parent with the current element and - // continue. - this.content[parentN] = element; - this.content[n] = parent; - n = parentN; - } - }, - - sinkDown: function (n) { - // Look up the target element and its score. - var length = this.content.length, - element = this.content[n], - elemScore = element; - - while (true) { - // Compute the indices of the child elements. - var child2N = (n + 1) * 2, child1N = child2N - 1; - // This is used to store the new position of the element, - // if any. - var swap = null; - // If the first child exists (is inside the array)... - if (child1N < length) { - // Look it up and compute its score. - var child1 = this.content[child1N], - child1Score = child1; - // If the score is less than our element's, we need to swap. - if (child1Score < elemScore) - swap = child1N; - } - // Do the same checks for the other child. - if (child2N < length) { - var child2 = this.content[child2N], - child2Score = child2; - if (child2Score < (swap == null ? elemScore : child1Score)) - swap = child2N; - } - - // No need to swap further, we are done. - if (swap == null) break; - - // Otherwise, swap and continue. - this.content[n] = this.content[swap]; - this.content[swap] = element; - n = swap; - } - } -}; - -/* - * The MIT License (MIT) - * - * Copyright (c) 2014 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -function _random$1(min, max) { - return Math.random() * (max - min) + min; -} - -const IGVColor$1 = { - - rgbListFromHSV: () => { - - let s = 1; - let accumulation = []; - for (let v = 1; v >= 0.5; v -= .1) { - for (let h = 0; h < 1; h += 1 / 28) { - const r = "rgb(" + IGVColor$1.hsvToRgb(h, s, v).join(",") + ")"; - accumulation.push(r); - } - } - - // add black - accumulation.pop(); - accumulation.push(IGVColor$1.rgbColor(16, 16, 16)); - - return accumulation; - }, - - rgbToHex: function (rgb) { - rgb = rgb.match(/^rgba?[\s+]?\([\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?/i); - return (rgb && rgb.length === 4) ? "#" + - ("0" + parseInt(rgb[1], 10).toString(16)).slice(-2) + - ("0" + parseInt(rgb[2], 10).toString(16)).slice(-2) + - ("0" + parseInt(rgb[3], 10).toString(16)).slice(-2) : ''; - }, - - hexToRgb: function (hex) { - - var cooked = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex); - - if (null === cooked) { - return undefined; - } - - return "rgb(" + parseInt(cooked[1], 16) + "," + parseInt(cooked[2], 16) + "," + parseInt(cooked[3], 16) + ")"; - }, - - /** - * Converts an HSV color value to RGB. Conversion formula - * adapted from http://en.wikipedia.org/wiki/HSV_color_space. - * Assumes h, s, and v are contained in the set [0, 1] and - * returns r, g, and b in the set [0, 255]. - * - * Credit: https://gist.githubusercontent.com/mjackson/5311256 - * - * @param h The hue - * @param s The saturation - * @param v The value - * @return Array The RGB representation - */ - hsvToRgb: function (h, s, v) { - var r, g, b; - - var i = Math.floor(h * 6); - var f = h * 6 - i; - var p = v * (1 - s); - var q = v * (1 - f * s); - var t = v * (1 - (1 - f) * s); - - switch (i % 6) { - case 0: - r = v, g = t, b = p; - break; - case 1: - r = q, g = v, b = p; - break; - case 2: - r = p, g = v, b = t; - break; - case 3: - r = p, g = q, b = v; - break; - case 4: - r = t, g = p, b = v; - break; - case 5: - r = v, g = p, b = q; - break; - } - - return [Math.floor(r * 255), Math.floor(g * 255), Math.floor(b * 255)]; - }, - - /** - * Converts an HSL color value to RGB. Conversion formula - * adapted from http://en.wikipedia.org/wiki/HSL_color_space. - * Assumes h, s, and l are contained in the set [0, 1] and - * returns r, g, and b in the set [0, 255]. - * - * Credit: https://gist.githubusercontent.com/mjackson/5311256 - * - * @param h The hue - * @param s The saturation - * @param l The lightness - * @return Array The RGB representation - */ - hslToRgb: function (h, s, l) { - var r, g, b; - - if (s === 0) { - r = g = b = l; // achromatic - } else { - - - var q = l < 0.5 ? l * (1 + s) : l + s - l * s; - var p = 2 * l - q; - - r = IGVColor$1.hue2rgb(p, q, h + 1 / 3); - g = IGVColor$1.hue2rgb(p, q, h); - b = IGVColor$1.hue2rgb(p, q, h - 1 / 3); - } - - return [r * 255, g * 255, b * 255]; - }, - - hue2rgb: (p, q, t) => { - if (t < 0) t += 1; - if (t > 1) t -= 1; - if (t < 1 / 6) return p + (q - p) * 6 * t; - if (t < 1 / 2) return q; - if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6; - return p; - }, - - rgbaColor: function (r, g, b, a) { - - r = IGVMath$1.clamp(r, 0, 255); - g = IGVMath$1.clamp(g, 0, 255); - b = IGVMath$1.clamp(b, 0, 255); - a = IGVMath$1.clamp(a, 0.0, 1.0); - - return "rgba(" + r + "," + g + "," + b + "," + a + ")"; - }, - - rgbColor: function (r, g, b) { - - r = IGVMath$1.clamp(r, 0, 255); - g = IGVMath$1.clamp(g, 0, 255); - b = IGVMath$1.clamp(b, 0, 255); - - return "rgb(" + r + "," + g + "," + b + ")"; - }, - - greyScale: function (value) { - - var grey = IGVMath$1.clamp(value, 0, 255); - - return "rgb(" + grey + "," + grey + "," + grey + ")"; - }, - - randomGrey: function (min, max) { - - min = IGVMath$1.clamp(min, 0, 255); - max = IGVMath$1.clamp(max, 0, 255); - - var g = Math.round(_random$1(min, max)).toString(10); - - return "rgb(" + g + "," + g + "," + g + ")"; - }, - - randomRGB: function (min, max) { - - min = IGVMath$1.clamp(min, 0, 255); - max = IGVMath$1.clamp(max, 0, 255); - - var r = Math.round(_random$1(min, max)).toString(10); - var g = Math.round(_random$1(min, max)).toString(10); - var b = Math.round(_random$1(min, max)).toString(10); - - return "rgb(" + r + "," + g + "," + b + ")"; - }, - - randomRGBConstantAlpha: function (min, max, alpha) { - - min = IGVMath$1.clamp(min, 0, 255); - max = IGVMath$1.clamp(max, 0, 255); - - var r = Math.round(_random$1(min, max)).toString(10); - var g = Math.round(_random$1(min, max)).toString(10); - var b = Math.round(_random$1(min, max)).toString(10); - - return "rgba(" + r + "," + g + "," + b + "," + alpha + ")"; - }, - - addAlpha: function (color, alpha) { - - if(color === "0" || color === ".") { - color = "rgb(0,0,0)"; - } else { - const c = this.colorNameToHex(color); - if (c) { - color = c; - } - } - - var isHex = /(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(color); - - if (color.startsWith("rgba")) { - const idx = color.lastIndexOf(","); - return color.substring(0, idx+1) + alpha.toString() + ")"; - } - - if (isHex) { - color = IGVColor$1.hexToRgb(color); - } - - if (color.startsWith("rgb")) { - return color.replace("rgb", "rgba").replace(")", ", " + alpha + ")"); - } else { - console.log(color + " is not an rgb style string"); - return color; - } - }, - - rgbComponents: function (color) { - - if(color === "0" || color === ".") { - return [0,0,0]; - } - const isHex = /(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(color); - if (isHex) { - color = IGVColor$1.hexToRgb(color); - } else { - if(!color.startsWith("rgb")) { - const hex = this.colorNameToHex(color); - color = this.hexToRgb(hex); - } - } - - if (color.startsWith("rgb(")) { - return color.substring(4, color.length-1).split(",").map(s => Number.parseInt(s.trim())); - } else if (color.startsWith("rgba(")) { - return color.substring(5, color.length-1).split(",").map((s, i) => { - s = s.trim(); - return i === 3 ? Number.parseFloat(s) : Number.parseInt(s) - }); - } - else { - throw Error("Unrecognized color string: color"); - } - }, - - /** - * - * @param dest RGB components as an array - * @param src RGB components as an array - * @param alpha alpha transparancy in the range 0-1 - * @returns {} - */ - getCompositeColor: function (dest, src, alpha) { - - var r = Math.floor(alpha * src[0] + (1 - alpha) * dest[0]), - g = Math.floor(alpha * src[1] + (1 - alpha) * dest[1]), - b = Math.floor(alpha * src[2] + (1 - alpha) * dest[2]); - - return "rgb(" + r + "," + g + "," + b + ")"; - - }, - - - createColorString: function (str) { - // Excel will quote color strings, strip all quotes - str = stripQuotes$2(str); - - if (str.includes(",")) { - return str.startsWith("rgb") ? str : "rgb(" + str + ")"; - } else { - return str; - } - }, - - darkenLighten: function (color, amt) { - - let src; - let hexColor = this.colorNameToHex(color); - if(hexColor) { - src = IGVColor$1.hexToRgb(hexColor); - } else { - src = color.startsWith('rgb(') ? color : IGVColor$1.hexToRgb(color); - } - - const components = src.replace(")", "").substring(4).split(","); - - const r = Math.max(0, Math.min(255, Number.parseInt(components[0].trim()) + amt)); - const g = Math.max(0, Math.min(255, Number.parseInt(components[1].trim()) + amt)); - const b = Math.max(0, Math.min(255, Number.parseInt(components[2].trim()) + amt)); - - return 'rgb(' + r.toString() + ',' + g.toString() + ',' + b.toString() + ')'; - - }, - - /** - * Convert html/css color name to hex value. Adapted from https://gist.github.com/mxfh/4719348 - * @param colorName - * @returns {*} - */ - colorNameToHex: function (colorName) { // color list from http://stackoverflow.com/q/1573053/731179 with added gray/gray - const definedColorNames = { - "aliceblue": "#f0f8ff", - "antiquewhite": "#faebd7", - "aqua": "#00ffff", - "aquamarine": "#7fffd4", - "azure": "#f0ffff", - "beige": "#f5f5dc", - "bisque": "#ffe4c4", - "black": "#000000", - "blanchedalmond": "#ffebcd", - "blue": "#0000ff", - "blueviolet": "#8a2be2", - "brown": "#a52a2a", - "burlywood": "#deb887", - "cadetblue": "#5f9ea0", - "chartreuse": "#7fff00", - "chocolate": "#d2691e", - "coral": "#ff7f50", - "cornflowerblue": "#6495ed", - "cornsilk": "#fff8dc", - "crimson": "#dc143c", - "cyan": "#00ffff", - "darkblue": "#00008b", - "darkcyan": "#008b8b", - "darkgoldenrod": "#b8860b", - "darkgray": "#a9a9a9", - "darkgreen": "#006400", - "darkkhaki": "#bdb76b", - "darkmagenta": "#8b008b", - "darkolivegreen": "#556b2f", - "darkorange": "#ff8c00", - "darkorchid": "#9932cc", - "darkred": "#8b0000", - "darksalmon": "#e9967a", - "darkseagreen": "#8fbc8f", - "darkslateblue": "#483d8b", - "darkslategray": "#2f4f4f", - "darkturquoise": "#00ced1", - "darkviolet": "#9400d3", - "deeppink": "#ff1493", - "deepskyblue": "#00bfff", - "dimgray": "#696969", - "dodgerblue": "#1e90ff", - "firebrick": "#b22222", - "floralwhite": "#fffaf0", - "forestgreen": "#228b22", - "fuchsia": "#ff00ff", - "gainsboro": "#dcdcdc", - "ghostwhite": "#f8f8ff", - "gold": "#ffd700", - "goldenrod": "#daa520", - "gray": "#808080", - "green": "#008000", - "greenyellow": "#adff2f", - "honeydew": "#f0fff0", - "hotpink": "#ff69b4", - "indianred ": "#cd5c5c", - "indigo ": "#4b0082", - "ivory": "#fffff0", - "khaki": "#f0e68c", - "lavender": "#e6e6fa", - "lavenderblush": "#fff0f5", - "lawngreen": "#7cfc00", - "lemonchiffon": "#fffacd", - "lightblue": "#add8e6", - "lightcoral": "#f08080", - "lightcyan": "#e0ffff", - "lightgoldenrodyellow": "#fafad2", - "lightgrey": "#d3d3d3", - "lightgreen": "#90ee90", - "lightpink": "#ffb6c1", - "lightsalmon": "#ffa07a", - "lightseagreen": "#20b2aa", - "lightskyblue": "#87cefa", - "lightslategray": "#778899", - "lightsteelblue": "#b0c4de", - "lightyellow": "#ffffe0", - "lime": "#00ff00", - "limegreen": "#32cd32", - "linen": "#faf0e6", - "magenta": "#ff00ff", - "maroon": "#800000", - "mediumaquamarine": "#66cdaa", - "mediumblue": "#0000cd", - "mediumorchid": "#ba55d3", - "mediumpurple": "#9370d8", - "mediumseagreen": "#3cb371", - "mediumslateblue": "#7b68ee", - "mediumspringgreen": "#00fa9a", - "mediumturquoise": "#48d1cc", - "mediumvioletred": "#c71585", - "midnightblue": "#191970", - "mintcream": "#f5fffa", - "mistyrose": "#ffe4e1", - "moccasin": "#ffe4b5", - "navajowhite": "#ffdead", - "navy": "#000080", - "oldlace": "#fdf5e6", - "olive": "#808000", - "olivedrab": "#6b8e23", - "orange": "#ffa500", - "orangered": "#ff4500", - "orchid": "#da70d6", - "palegoldenrod": "#eee8aa", - "palegreen": "#98fb98", - "paleturquoise": "#afeeee", - "palevioletred": "#d87093", - "papayawhip": "#ffefd5", - "peachpuff": "#ffdab9", - "peru": "#cd853f", - "pink": "#ffc0cb", - "plum": "#dda0dd", - "powderblue": "#b0e0e6", - "purple": "#800080", - "red": "#ff0000", - "rosybrown": "#bc8f8f", - "royalblue": "#4169e1", - "saddlebrown": "#8b4513", - "salmon": "#fa8072", - "sandybrown": "#f4a460", - "seagreen": "#2e8b57", - "seashell": "#fff5ee", - "sienna": "#a0522d", - "silver": "#c0c0c0", - "skyblue": "#87ceeb", - "slateblue": "#6a5acd", - "slategray": "#708090", - "snow": "#fffafa", - "springgreen": "#00ff7f", - "steelblue": "#4682b4", - "tan": "#d2b48c", - "teal": "#008080", - "thistle": "#d8bfd8", - "tomato": "#ff6347", - "turquoise": "#40e0d0", - "violet": "#ee82ee", - "wheat": "#f5deb3", - "white": "#ffffff", - "whitesmoke": "#f5f5f5", - "yellow": "#ffff00", - "yellowgreen": "#9acd32", - "darkgrey": "#a9a9a9", - "darkslategrey": "#2f4f4f", - "dimgrey": "#696969", - "grey": "#808080", - "lightgray": "#d3d3d3", - "lightslategrey": "#778899", - "slategrey": "#708090" - }; - return definedColorNames[colorName]; - } -}; - -// Support for oauth token based authorization -// This class supports explicit setting of an oauth token either globally or for specific hosts. -// -// The variable oauth.google.access_token, which becomes igv.oauth.google.access_token on ES5 conversion is -// supported for backward compatibility - -const DEFAULT_HOST$1 = "googleapis"; - -class Oauth$1 { - - constructor() { - this.oauthTokens = {}; - } - - - setToken(token, host) { - host = host || DEFAULT_HOST$1; - this.oauthTokens[host] = token; - } - - getToken(host) { - host = host || DEFAULT_HOST$1; - let token; - for (let key of Object.keys(this.oauthTokens)) { - const regex = wildcardToRegExp$1(key); - if (regex.test(host)) { - token = this.oauthTokens[key]; - break - } - } - return token - } - - removeToken(host) { - host = host || DEFAULT_HOST$1; - for (let key of Object.keys(this.oauthTokens)) { - const regex = wildcardToRegExp$1(key); - if (regex.test(host)) { - this.oauthTokens[key] = undefined; - } - } - } - - // Special object for google -- legacy support - // google: { - // setToken: function (token) { - // oauth.setToken(token); - // } - // } -} - - -/** - * Creates a RegExp from the given string, converting asterisks to .* expressions, - * and escaping all other characters. - * - * credit https://gist.github.com/donmccurdy/6d073ce2c6f3951312dfa45da14a420f - */ -function wildcardToRegExp$1(s) { - return new RegExp('^' + s.split(/\*+/).map(regExpEscape$1).join('.*') + '$') -} - -/** - * RegExp-escapes all characters in the given string. - * - * credit https://gist.github.com/donmccurdy/6d073ce2c6f3951312dfa45da14a420f - */ -function regExpEscape$1(s) { - return s.replace(/[|\\{}()[\]^$+*?.]/g, '\\$&') -} - -function isGoogleURL$2(url) { - return (url.includes("googleapis") && !url.includes("urlshortener")) || - isGoogleStorageURL$2(url) || - isGoogleDriveURL$2(url) -} - -function isGoogleStorageURL$2(url) { - return url.startsWith("gs://") || - url.startsWith("https://www.googleapis.com/storage") || - url.startsWith("https://storage.cloud.google.com") || - url.startsWith("https://storage.googleapis.com"); -} - -function isGoogleDriveURL$2(url) { - return url.indexOf("drive.google.com") >= 0 || url.indexOf("www.googleapis.com/drive") > 0 -} - -/** - * Translate gs:// urls to https - * See https://cloud.google.com/storage/docs/json_api/v1 - * @param gsUrl - * @returns {string|*} - */ -function translateGoogleCloudURL$1(gsUrl) { - - let {bucket, object} = parseBucketName$1(gsUrl); - object = encode$1(object); - - const qIdx = gsUrl.indexOf('?'); - const paramString = (qIdx > 0) ? gsUrl.substring(qIdx) + "&alt=media" : "?alt=media"; - - return `https://storage.googleapis.com/storage/v1/b/${bucket}/o/${object}${paramString}` -} - -/** - * Parse a google bucket and object name from a google storage URL. Known forms include - * - * gs://BUCKET_NAME/OBJECT_NAME - * https://storage.googleapis.com/BUCKET_NAME/OBJECT_NAME - * https://storage.googleapis.com/storage/v1/b/BUCKET_NAME/o/OBJECT_NAME - * https://www.googleapis.com/storage/v1/b/BUCKET_NAME/o/OBJECT_NAME" - * https://storage.googleapis.com/download/storage/v1/b/BUCKET_NAME/o/OBJECT_NAME - * - * @param url - */ -function parseBucketName$1(url) { - - let bucket; - let object; - - if (url.startsWith("gs://")) { - const i = url.indexOf('/', 5); - if (i >= 0) { - bucket = url.substring(5, i); - const qIdx = url.indexOf('?'); - object = (qIdx < 0) ? url.substring(i + 1) : url.substring(i + 1, qIdx); - } - - } else if (url.startsWith("https://storage.googleapis.com") || url.startsWith("https://storage.cloud.google.com")) { - const bucketIdx = url.indexOf("/v1/b/", 8); - if (bucketIdx > 0) { - const objIdx = url.indexOf("/o/", bucketIdx); - if (objIdx > 0) { - const queryIdx = url.indexOf("?", objIdx); - bucket = url.substring(bucketIdx + 6, objIdx); - object = queryIdx > 0 ? url.substring(objIdx + 3, queryIdx) : url.substring(objIdx + 3); - } - - } else { - const idx1 = url.indexOf("/", 8); - const idx2 = url.indexOf("/", idx1+1); - const idx3 = url.indexOf("?", idx2); - if (idx2 > 0) { - bucket = url.substring(idx1+1, idx2); - object = idx3 < 0 ? url.substring(idx2+1) : url.substring(idx2+1, idx3); - } - } - - } else if (url.startsWith("https://www.googleapis.com/storage/v1/b")) { - const bucketIdx = url.indexOf("/v1/b/", 8); - const objIdx = url.indexOf("/o/", bucketIdx); - if (objIdx > 0) { - const queryIdx = url.indexOf("?", objIdx); - bucket = url.substring(bucketIdx + 6, objIdx); - object = queryIdx > 0 ? url.substring(objIdx + 3, queryIdx) : url.substring(objIdx + 3); - } - } - - if (bucket && object) { - return { - bucket, object - } - } else { - throw Error(`Unrecognized Google Storage URI: ${url}`) - } - -} - -/** - * Percent a GCS object name. See https://cloud.google.com/storage/docs/request-endpoints - * Specific characters to encode: - * !, #, $, &, ', (, ), *, +, ,, /, :, ;, =, ?, @, [, ], and space characters. - * @param obj - */ - -function encode$1(objectName) { - - let result = ''; - objectName.split('').forEach(function(letter) { - if(encodings$3.has(letter)) { - result += encodings$3.get(letter); - } else { - result += letter; - } - }); - return result; -} - -// %23 %24 %25 %26 %27 %28 %29 %2A %2B %2C %2F %3A %3B %3D %3F %40 %5B %5D -const encodings$3 = new Map(); -encodings$3.set("!", "%21"); -encodings$3.set("#", "%23"); -encodings$3.set("$", "%24"); -encodings$3.set("%", "%25"); -encodings$3.set("&", "%26"); -encodings$3.set("'", "%27"); -encodings$3.set("(", "%28"); -encodings$3.set(")", "%29"); -encodings$3.set("*", "%2A"); -encodings$3.set("+", "%2B"); -encodings$3.set(",", "%2C"); -encodings$3.set("/", "%2F"); -encodings$3.set(":", "%3A"); -encodings$3.set(";", "%3B"); -encodings$3.set("=", "%3D"); -encodings$3.set("?", "%3F"); -encodings$3.set("@", "%40"); -encodings$3.set("[", "%5B"); -encodings$3.set("]", "%5D"); -encodings$3.set(" ", "%20"); - -// Convenience functions for the gapi oAuth library. - -function isInitialized$1() { - return window.google && window.google.igv -} - -/** - * Return the current access token if the user is signed in, or undefined otherwise. This function does not - * attempt a signIn or request any specfic scopes. - * - * @returns access_token || undefined - */ -function getCurrentAccessToken$1() { - return (isInitialized$1() && google.igv.tokenResponse && Date.now() < google.igv.tokenExpiresAt) ? - google.igv.tokenResponse.access_token : - undefined -} - - -/** - * Return a promise for an access token for the given scope. If the user hasn't authorized the scope request it - * - * @param scope - * @returns {Promise} - */ -async function getAccessToken$1(scope) { - - if (!isInitialized$1()) { - throw Error("Google oAuth has not been initialized") - } - - if (google.igv.tokenResponse && - Date.now() < google.igv.tokenExpiresAt && - google.accounts.oauth2.hasGrantedAllScopes(google.igv.tokenResponse, scope)) { - return google.igv.tokenResponse.access_token - } else { - const tokenClient = google.igv.tokenClient; - return new Promise((resolve, reject) => { - try { - // Settle this promise in the response callback for requestAccessToken() - tokenClient.callback = (tokenResponse) => { - if (tokenResponse.error !== undefined) { - reject(tokenResponse); - } - google.igv.tokenResponse = tokenResponse; - google.igv.tokenExpiresAt = Date.now() + tokenResponse.expires_in * 1000; - resolve(tokenResponse.access_token); - }; - tokenClient.requestAccessToken({scope}); - } catch (err) { - console.log(err); - } - }) - } -} - -// gapi.auth2.getAuthInstance().isSignedIn.listen(status => { -// const user = gapi.auth2.getAuthInstance().currentUser.get() -// queryGoogleAuthenticationStatus(user, status) -// }) - -function getScopeForURL$1(url) { - if (isGoogleDriveURL$2(url)) { - return "https://www.googleapis.com/auth/drive.readonly" - } else if (isGoogleStorageURL$2(url)) { - return "https://www.googleapis.com/auth/devstorage.read_only" - } else { - return 'https://www.googleapis.com/auth/userinfo.profile' - } -} - -function getDriveDownloadURL$2(link) { - // Return a google drive download url for the sharable link - //https://drive.google.com/open?id=0B-lleX9c2pZFbDJ4VVRxakJzVGM - //https://drive.google.com/file/d/1_FC4kCeO8E3V4dJ1yIW7A0sn1yURKIX-/view?usp=sharing - var id = getGoogleDriveFileID$2(link); - return id ? "https://www.googleapis.com/drive/v3/files/" + id + "?alt=media&supportsTeamDrives=true" : link; -} - -function getGoogleDriveFileID$2(link) { - - //https://drive.google.com/file/d/1_FC4kCeO8E3V4dJ1yIW7A0sn1yURKIX-/view?usp=sharing - //https://www.googleapis.com/drive/v3/files/1w-tvo6p1SH4p1OaQSVxpkV_EJgGIstWF?alt=media&supportsTeamDrives=true" - - if (link.includes("/open?id=")) { - const i1 = link.indexOf("/open?id=") + 9; - const i2 = link.indexOf("&"); - if (i1 > 0 && i2 > i1) { - return link.substring(i1, i2) - } else if (i1 > 0) { - return link.substring(i1); - } - - } else if (link.includes("/file/d/")) { - const i1 = link.indexOf("/file/d/") + 8; - const i2 = link.lastIndexOf("/"); - return link.substring(i1, i2); - - } else if (link.startsWith("https://www.googleapis.com/drive")) { - let i1 = link.indexOf("/files/"); - const i2 = link.indexOf("?"); - if (i1 > 0) { - i1 += 7; - return i2 > 0 ? - link.substring(i1, i2) : - link.substring(i1) - } - } - - throw Error("Unknown Google Drive url format: " + link); - - -} - -// The MIT License (MIT) - -/** - * @constructor - * @param {Object} options A set op options to pass to the throttle function - * @param {number} requestsPerSecond The amount of requests per second - * the library will limit to - */ -class Throttle$1 { - constructor(options) { - this.requestsPerSecond = options.requestsPerSecond || 10; - this.lastStartTime = 0; - this.queued = []; - } - - /** - * Adds a promise - * @param {Function} async function to be executed - * @param {Object} options A set of options. - * @return {Promise} A promise - */ - add(asyncFunction, options) { - - var self = this; - return new Promise(function (resolve, reject) { - self.queued.push({ - resolve: resolve, - reject: reject, - asyncFunction: asyncFunction, - }); - self.dequeue(); - }); - } - - /** - * Adds all the promises passed as parameters - * @param {Function} promises An array of functions that return a promise - * @param {Object} options A set of options. - * @param {number} options.signal An AbortSignal object that can be used to abort the returned promise - * @param {number} options.weight A "weight" of each operation resolving by array of promises - * @return {Promise} A promise that succeeds when all the promises passed as options do - */ - addAll(promises, options) { - var addedPromises = promises.map(function (promise) { - return this.add(promise, options); - }.bind(this)); - - return Promise.all(addedPromises); - }; - - /** - * Dequeues a promise - * @return {void} - */ - dequeue() { - if (this.queued.length > 0) { - var now = new Date(), - inc = (1000 / this.requestsPerSecond) + 1, - elapsed = now - this.lastStartTime; - - if (elapsed >= inc) { - this._execute(); - } else { - // we have reached the limit, schedule a dequeue operation - setTimeout(function () { - this.dequeue(); - }.bind(this), inc - elapsed); - } - } - } - - /** - * Executes the promise - * @private - * @return {void} - */ - async _execute() { - this.lastStartTime = new Date(); - var candidate = this.queued.shift(); - const f = candidate.asyncFunction; - try { - const r = await f(); - candidate.resolve(r); - } catch (e) { - candidate.reject(e); - } - - } - - -} - -/* - * The MIT License (MIT) - * - * Copyright (c) 2014 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -class IGVXhr$1 { - - constructor() { - this.apiKey = undefined; - this.googleThrottle = new Throttle$1({ - requestsPerSecond: 8 - }); - this.RANGE_WARNING_GIVEN = false; - this.oauth = new Oauth$1(); - this.contentLengthMap = new Map(); - } - - setApiKey(key) { - this.apiKey = key; - } - - async loadArrayBuffer(url, options) { - options = options || {}; - if (!options.responseType) { - options.responseType = "arraybuffer"; - } - if (isFile$2(url)) { - return this._loadFileSlice(url, options) - } else { - return this.load(url, options) - } - } - - async loadJson(url, options) { - options = options || {}; - const method = options.method || (options.sendData ? "POST" : "GET"); - if (method === "POST") { - options.contentType = "application/json"; - } - const result = await this.loadString(url, options); - if (result) { - return JSON.parse(result) - } else { - return result - } - } - - async loadString(path, options) { - options = options || {}; - if (path instanceof File) { - return this._loadStringFromFile(path, options) - } else { - return this._loadStringFromUrl(path, options) - } - } - - async load(url, options) { - - options = options || {}; - const urlType = typeof url; - - // Resolve functions, promises, and functions that return promises - url = await (typeof url === 'function' ? url() : url); - - if (isFile$2(url)) { - return this._loadFileSlice(url, options) - } else if (typeof url.startsWith === 'function') { // Test for string - if (url.startsWith("data:")) { - const buffer = decodeDataURI$2(url).buffer; - if (options.range) { - const rangeEnd = options.range.size ? options.range.start + options.range.size : buffer.byteLength; - return buffer.slice(options.range.start, rangeEnd) - } else { - return buffer - } - } else { - if (url.startsWith("https://drive.google.com")) { - url = getDriveDownloadURL$2(url); - } - if (isGoogleDriveURL$2(url) || url.startsWith("https://www.dropbox.com")) { - return this.googleThrottle.add(async () => { - return this._loadURL(url, options) - }) - } else { - return this._loadURL(url, options) - } - } - } else { - throw Error(`url must be either a 'File', 'string', 'function', or 'Promise'. Actual type: ${urlType}`) - } - } - - async getContentLength(url, options) { - if (!this.contentLengthMap.has(url)) { - options = options || {}; - options.method = 'HEAD'; - options.GET_CONTENT_LENGTH = true; - const contentLengthString = await this._loadURL(url, options); - const contentLength = contentLengthString ? Number.parseInt(contentLengthString) : -1; - this.contentLengthMap.set(url, contentLength); - } - return this.contentLengthMap.get(url) - } - - async _loadURL(url, options) { - - const self = this; - - //console.log(`${Date.now()} ${url}`) - url = mapUrl$3(url); - - options = options || {}; - - let oauthToken = options.oauthToken || this.getOauthToken(url); - if (oauthToken) { - oauthToken = await (typeof oauthToken === 'function' ? oauthToken() : oauthToken); - } - - let contentLength = -1; - if (options.range && !isAmazonV4Signed(url) && !isGoogleStorageSigned$1(url)) { - contentLength = await this.getContentLength(url); - } - - return new Promise(function (resolve, reject) { - - // Various Google tansformations - if (isGoogleURL$2(url) && !isGoogleStorageSigned$1(url)) { - if (isGoogleStorageURL$2(url)) { - url = translateGoogleCloudURL$1(url); - } - url = addApiKey$1(url); - - if (isGoogleDriveURL$2(url)) { - addTeamDrive$1(url); - } - - // If we have an access token try it, but don't force a signIn or request for scopes yet - if (!oauthToken) { - oauthToken = getCurrentGoogleAccessToken$1(); - } - } - - const headers = options.headers || {}; - if (oauthToken) { - addOauthHeaders$1(headers, oauthToken); - } - const range = options.range; - - - const xhr = new XMLHttpRequest(); - const sendData = options.sendData || options.body; - const method = options.method || (sendData ? "POST" : "GET"); - const responseType = options.responseType; - const contentType = options.contentType; - const mimeType = options.mimeType; - - xhr.open(method, url); - - if (options.timeout) { - xhr.timeout = options.timeout; - } - - if (range) { - let rangeEnd = ""; - if (range.size) { - rangeEnd = range.start + range.size - 1; - if (contentLength > 0) { - rangeEnd = Math.min(rangeEnd, contentLength - 1); - } - } - xhr.setRequestHeader("Range", "bytes=" + range.start + "-" + rangeEnd); - // xhr.setRequestHeader("Cache-Control", "no-cache"); <= This can cause CORS issues, disabled for now - } - if (contentType) { - xhr.setRequestHeader("Content-Type", contentType); - } - if (mimeType) { - xhr.overrideMimeType(mimeType); - } - if (responseType) { - xhr.responseType = responseType; - } - if (headers) { - for (let key of Object.keys(headers)) { - const value = headers[key]; - xhr.setRequestHeader(key, value); - } - } - - // NOTE: using withCredentials with servers that return "*" for access-allowed-origin will fail - if (options.withCredentials === true) { - xhr.withCredentials = true; - } - - xhr.onload = async function (event) { - - if (options.GET_CONTENT_LENGTH) { - resolve(xhr.getResponseHeader('content-length')); - } - - // when the url points to a local file, the status is 0 but that is not an error - if (xhr.status === 0 || (xhr.status >= 200 && xhr.status <= 300)) { - if (range && xhr.status !== 206 && range.start !== 0) { - // For small files a range starting at 0 can return the whole file => 200 - // Provide just the slice we asked for, throw out the rest quietly - // If file is large warn user - if (xhr.response.length > 100000 && !self.RANGE_WARNING_GIVEN) { - alert(`Warning: Range header ignored for URL: ${url}. This can have severe performance impacts.`); - } - resolve(xhr.response.slice(range.start, range.start + range.size)); - - } else { - resolve(xhr.response); - } - } else if ((typeof gapi !== "undefined") && - ((xhr.status === 404 || xhr.status === 401 || xhr.status === 403) && - isGoogleURL$2(url)) && - !options.retries) { - tryGoogleAuth(); - - } else { - if (xhr.status === 403) { - handleError("Access forbidden: " + url); - } else if (xhr.status === 416) { - // Tried to read off the end of the file. This shouldn't happen, but if it does return an - handleError("Unsatisfiable range"); - } else { - handleError(xhr.status); - } - } - }; - - - xhr.onerror = function (event) { - if (isGoogleURL$2(url) && !options.retries) { - tryGoogleAuth(); - } else { - handleError("Error accessing resource: " + url + " Status: " + xhr.status); - } - }; - - xhr.ontimeout = function (event) { - handleError("Timed out"); - }; - - xhr.onabort = function (event) { - console.log("Aborted"); - reject(event); - }; - - try { - xhr.send(sendData); - } catch (e) { - if (isGoogleURL$2(url) && !options.retries) { - tryGoogleAuth(); - } else { - handleError(e); - } - } - - - function handleError(error) { - if (reject) { - reject(error); - } else { - throw error - } - } - - async function tryGoogleAuth() { - try { - const accessToken = await fetchGoogleAccessToken$1(url); - options.retries = 1; - options.oauthToken = accessToken; - const response = await self.load(url, options); - resolve(response); - } catch (e) { - if (e.error) { - const msg = e.error.startsWith("popup_blocked") ? - "Google login popup blocked by browser." : - e.error; - alert(msg); - } else { - handleError(e); - } - } - } - }) - - } - - async _loadFileSlice(localfile, options) { - - let blob = (options && options.range) ? - localfile.slice(options.range.start, options.range.start + options.range.size) : - localfile; - - const arrayBuffer = await blob.arrayBuffer(); - - if ("arraybuffer" === options.responseType) { - return arrayBuffer - } else { - return arrayBufferToString$1(arrayBuffer) - } - } - - async _loadStringFromFile(localfile, options) { - - const blob = options.range ? localfile.slice(options.range.start, options.range.start + options.range.size) : localfile; - const arrayBuffer = await blob.arrayBuffer(); - return arrayBufferToString$1(arrayBuffer) - } - - async _loadStringFromUrl(url, options) { - - options = options || {}; - options.responseType = "arraybuffer"; - const data = await this.load(url, options); - return arrayBufferToString$1(data) - } - - /** - * Explicity set an oAuth token for use with given host. If host is undefined token is used for google api access* - * @param token - * @param host - */ - setOauthToken(token, host) { - this.oauth.setToken(token, host); - } - - /** - * Return an oauth token for the URL if we have one. This method does not force sign-in, and the token may - * or may not be valid. Sign-in is triggered on request failure. - * * - * @param url - * @returns {*} - */ - getOauthToken(url) { - - // Google is the default provider, don't try to parse host for google URLs - const host = isGoogleURL$2(url) ? - undefined : - parseUri$1(url).host; - - // First check the explicit settings (i.e. token set through the API) - let token = this.oauth.getToken(host); - if (token) { - return token - } else if (host === undefined) { - // Now try Google oauth tokens previously obtained. This will return undefined if google oauth is not - // configured. - const googleToken = getCurrentGoogleAccessToken$1(); - if (googleToken && googleToken.expires_at > Date.now()) { - return googleToken.access_token - } - } - } -} - -function isGoogleStorageSigned$1(url) { - return url.indexOf("X-Goog-Signature") > -1 -} - - -/** - * Return a Google oAuth token, triggering a sign in if required. This method should not be called until we know - * a token is required, that is until we've tried the url and received a 401, 403, or 404. - * - * @param url - * @returns the oauth token - */ -async function fetchGoogleAccessToken$1(url) { - if (isInitialized$1()) { - const scope = getScopeForURL$1(url); - const access_token = await getAccessToken$1(scope); - return access_token - } else { - throw Error( - `Authorization is required, but Google oAuth has not been initalized. Contact your site administrator for assistance.`) - } -} - -/** - * Return the current google access token, if one exists. Do not triger signOn or request additional scopes. - * @returns {undefined|access_token} - */ -function getCurrentGoogleAccessToken$1() { - if (isInitialized$1()) { - const access_token = getCurrentAccessToken$1(); - return access_token - } else { - return undefined - } -} - -function addOauthHeaders$1(headers, acToken) { - if (acToken) { - headers["Cache-Control"] = "no-cache"; - headers["Authorization"] = "Bearer " + acToken; - } - return headers -} - - -function addApiKey$1(url) { - let apiKey = igvxhr$1.apiKey; - if (!apiKey && typeof gapi !== "undefined") { - apiKey = gapi.apiKey; - } - if (apiKey !== undefined && !url.includes("key=")) { - const paramSeparator = url.includes("?") ? "&" : "?"; - url = url + paramSeparator + "key=" + apiKey; - } - return url -} - -function addTeamDrive$1(url) { - if (url.includes("supportsTeamDrive")) { - return url - } else { - const paramSeparator = url.includes("?") ? "&" : "?"; - url = url + paramSeparator + "supportsTeamDrive=true"; - } -} - -/** - * Perform some well-known url mappings. - * @param url - */ -function mapUrl$3(url) { - - if (url.startsWith("https://www.dropbox.com")) { - return url.replace("//www.dropbox.com", "//dl.dropboxusercontent.com") - } else if (url.startsWith("https://drive.google.com")) { - return getDriveDownloadURL$2(url) - } else if (url.includes("//www.broadinstitute.org/igvdata")) { - return url.replace("//www.broadinstitute.org/igvdata", "//data.broadinstitute.org/igvdata") - } else if (url.includes("//igvdata.broadinstitute.org")) { - return url.replace("//igvdata.broadinstitute.org", "//s3.amazonaws.com/igv.broadinstitute.org") - } else if (url.includes("//igv.genepattern.org")) { - return url.replace("//igv.genepattern.org", "//igv-genepattern-org.s3.amazonaws.com") - } else if (url.startsWith("ftp://ftp.ncbi.nlm.nih.gov/geo")) { - return url.replace("ftp://", "https://") - } else { - return url - } -} - - -function arrayBufferToString$1(arraybuffer) { - - let plain; - if (isgzipped$1(arraybuffer)) { - plain = ungzip_blocks$1(arraybuffer); - } else { - plain = new Uint8Array(arraybuffer); - } - - if ('TextDecoder' in getGlobalObject$1()) { - return new TextDecoder().decode(plain) - } else { - return decodeUTF8$1(plain) - } -} - -/** - * Use when TextDecoder is not available (primarily IE). - * - * From: https://gist.github.com/Yaffle/5458286 - * - * @param octets - * @returns {string} - */ -function decodeUTF8$1(octets) { - var string = ""; - var i = 0; - while (i < octets.length) { - var octet = octets[i]; - var bytesNeeded = 0; - var codePoint = 0; - if (octet <= 0x7F) { - bytesNeeded = 0; - codePoint = octet & 0xFF; - } else if (octet <= 0xDF) { - bytesNeeded = 1; - codePoint = octet & 0x1F; - } else if (octet <= 0xEF) { - bytesNeeded = 2; - codePoint = octet & 0x0F; - } else if (octet <= 0xF4) { - bytesNeeded = 3; - codePoint = octet & 0x07; - } - if (octets.length - i - bytesNeeded > 0) { - var k = 0; - while (k < bytesNeeded) { - octet = octets[i + k + 1]; - codePoint = (codePoint << 6) | (octet & 0x3F); - k += 1; - } - } else { - codePoint = 0xFFFD; - bytesNeeded = octets.length - i; - } - string += String.fromCodePoint(codePoint); - i += bytesNeeded + 1; - } - return string -} - - -function getGlobalObject$1() { - if (typeof self !== 'undefined') { - return self - } - if (typeof global !== 'undefined') { - return global - } else { - return window - } -} - -function isAmazonV4Signed(url) { - return url.indexOf("X-Amz-Signature") > -1 -} - - -const igvxhr$1 = new IGVXhr$1(); - -/* - * The MIT License (MIT) - * - * Copyright (c) 2014 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -/** An implementation of an interval tree, following the explanation. - * from CLR. - * - * Public interface: - * Constructor IntervalTree - * Insertion insert - * Search findOverlapping - */ - -var BLACK$1 = 1; - -var NIL$1 = {}; -NIL$1.color = BLACK$1; -NIL$1.parent = NIL$1; -NIL$1.left = NIL$1; -NIL$1.right = NIL$1; - -/*! - * jQuery JavaScript Library v3.3.1 -ajax,-ajax/jsonp,-ajax/load,-ajax/parseXML,-ajax/script,-ajax/var/location,-ajax/var/nonce,-ajax/var/rquery,-ajax/xhr,-manipulation/_evalUrl,-event/ajax,-effects,-effects/Tween,-effects/animatedSelector - * https://jquery.com/ - * - * Includes Sizzle.js - * https://sizzlejs.com/ - * - * Copyright JS Foundation and other contributors - * Released under the MIT license - * https://jquery.org/license - * - * Date: 2018-01-20T17:24Z - */ - -var arr = []; - -var document$1 = window.document; - -var getProto = Object.getPrototypeOf; - -var slice = arr.slice; - -var concat = arr.concat; - -var push = arr.push; - -var indexOf = arr.indexOf; - -var class2type = {}; - -var toString$3 = class2type.toString; - -var hasOwn = class2type.hasOwnProperty; - -var fnToString = hasOwn.toString; - -var ObjectFunctionString = fnToString.call(Object); - -var support = {}; - -var isFunction = function isFunction(obj) { - - // Support: Chrome <=57, Firefox <=52 - // In some browsers, typeof returns "function" for HTML elements - // (i.e., `typeof document.createElement( "object" ) === "function"`). - // We don't want to classify *any* DOM node as a function. - return typeof obj === "function" && typeof obj.nodeType !== "number"; -}; - - -var isWindow = function isWindow(obj) { - return obj != null && obj === obj.window; -}; - - -var preservedScriptAttributes = { - type: true, - src: true, - noModule: true -}; - -function DOMEval(code, doc, node) { - doc = doc || document$1; - - var i, - script = doc.createElement("script"); - - script.text = code; - if (node) { - for (i in preservedScriptAttributes) { - if (node[i]) { - script[i] = node[i]; - } - } - } - doc.head.appendChild(script).parentNode.removeChild(script); -} - - -function toType(obj) { - if (obj == null) { - return obj + ""; - } - - // Support: Android <=2.3 only (functionish RegExp) - return typeof obj === "object" || typeof obj === "function" ? - class2type[toString$3.call(obj)] || "object" : - typeof obj; -} - -// global Symbol -// Defining this global in .eslintrc.json would create a danger of using the global -// unguarded in another place, it seems safer to define global only for this module - - -var - version$1 = "3.3.1 -ajax,-ajax/jsonp,-ajax/load,-ajax/parseXML,-ajax/script,-ajax/var/location,-ajax/var/nonce,-ajax/var/rquery,-ajax/xhr,-manipulation/_evalUrl,-event/ajax,-effects,-effects/Tween,-effects/animatedSelector", - - // Define a local copy of jQuery - jQuery = function (selector, context) { - - // The jQuery object is actually just the init constructor 'enhanced' - // Need init if jQuery is called (just allow error to be thrown if not included) - return new jQuery.fn.init(selector, context); - }, - - // Support: Android <=4.0 only - // Make sure we trim BOM and NBSP - rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g; - -jQuery.fn = jQuery.prototype = { - - // The current version of jQuery being used - jquery: version$1, - - constructor: jQuery, - - // The default length of a jQuery object is 0 - length: 0, - - toArray: function () { - return slice.call(this); - }, - - // Get the Nth element in the matched element set OR - // Get the whole matched element set as a clean array - get: function (num) { - - // Return all the elements in a clean array - if (num == null) { - return slice.call(this); - } - - // Return just the one element from the set - return num < 0 ? this[num + this.length] : this[num]; - }, - - // Take an array of elements and push it onto the stack - // (returning the new matched element set) - pushStack: function (elems) { - - // Build a new jQuery matched element set - var ret = jQuery.merge(this.constructor(), elems); - - // Add the old object onto the stack (as a reference) - ret.prevObject = this; - - // Return the newly-formed element set - return ret; - }, - - // Execute a callback for every element in the matched set. - each: function (callback) { - return jQuery.each(this, callback); - }, - - map: function (callback) { - return this.pushStack(jQuery.map(this, function (elem, i) { - return callback.call(elem, i, elem); - })); - }, - - slice: function () { - return this.pushStack(slice.apply(this, arguments)); - }, - - first: function () { - return this.eq(0); - }, - - last: function () { - return this.eq(-1); - }, - - eq: function (i) { - var len = this.length, - j = +i + (i < 0 ? len : 0); - return this.pushStack(j >= 0 && j < len ? [this[j]] : []); - }, - - end: function () { - return this.prevObject || this.constructor(); - }, - - // For internal use only. - // Behaves like an Array's method, not like a jQuery method. - push: push, - sort: arr.sort, - splice: arr.splice -}; - -jQuery.extend = jQuery.fn.extend = function () { - var options, name, src, copy, copyIsArray, clone, - target = arguments[0] || {}, - i = 1, - length = arguments.length, - deep = false; - - // Handle a deep copy situation - if (typeof target === "boolean") { - deep = target; - - // Skip the boolean and the target - target = arguments[i] || {}; - i++; - } - - // Handle case when target is a string or something (possible in deep copy) - if (typeof target !== "object" && !isFunction(target)) { - target = {}; - } - - // Extend jQuery itself if only one argument is passed - if (i === length) { - target = this; - i--; - } - - for (; i < length; i++) { - - // Only deal with non-null/undefined values - if ((options = arguments[i]) != null) { - - // Extend the base object - for (name in options) { - src = target[name]; - copy = options[name]; - - // Prevent never-ending loop - if (target === copy) { - continue; - } - - // Recurse if we're merging plain objects or arrays - if (deep && copy && (jQuery.isPlainObject(copy) || - (copyIsArray = Array.isArray(copy)))) { - - if (copyIsArray) { - copyIsArray = false; - clone = src && Array.isArray(src) ? src : []; - - } else { - clone = src && jQuery.isPlainObject(src) ? src : {}; - } - - // Never move original objects, clone them - target[name] = jQuery.extend(deep, clone, copy); - - // Don't bring in undefined values - } else if (copy !== undefined) { - target[name] = copy; - } - } - } - } - - // Return the modified object - return target; -}; - -jQuery.extend({ - - // Unique for each copy of jQuery on the page - expando: "jQuery" + (version$1 + Math.random()).replace(/\D/g, ""), - - // Assume jQuery is ready without the ready module - isReady: true, - - error: function (msg) { - throw new Error(msg); - }, - - noop: function () { - }, - - isPlainObject: function (obj) { - var proto, Ctor; - - // Detect obvious negatives - // Use toString instead of jQuery.type to catch host objects - if (!obj || toString$3.call(obj) !== "[object Object]") { - return false; - } - - proto = getProto(obj); - - // Objects with no prototype (e.g., `Object.create( null )`) are plain - if (!proto) { - return true; - } - - // Objects with prototype are plain iff they were constructed by a global Object function - Ctor = hasOwn.call(proto, "constructor") && proto.constructor; - return typeof Ctor === "function" && fnToString.call(Ctor) === ObjectFunctionString; - }, - - isEmptyObject: function (obj) { - - /* eslint-disable no-unused-vars */ - // See https://github.com/eslint/eslint/issues/6125 - var name; - - for (name in obj) { - return false; - } - return true; - }, - - // Evaluates a script in a global context - globalEval: function (code) { - DOMEval(code); - }, - - each: function (obj, callback) { - var length, i = 0; - - if (isArrayLike(obj)) { - length = obj.length; - for (; i < length; i++) { - if (callback.call(obj[i], i, obj[i]) === false) { - break; - } - } - } else { - for (i in obj) { - if (callback.call(obj[i], i, obj[i]) === false) { - break; - } - } - } - - return obj; - }, - - // Support: Android <=4.0 only - trim: function (text) { - return text == null ? - "" : - (text + "").replace(rtrim, ""); - }, - - // results is for internal usage only - makeArray: function (arr, results) { - var ret = results || []; - - if (arr != null) { - if (isArrayLike(Object(arr))) { - jQuery.merge(ret, - typeof arr === "string" ? - [arr] : arr - ); - } else { - push.call(ret, arr); - } - } - - return ret; - }, - - inArray: function (elem, arr, i) { - return arr == null ? -1 : indexOf.call(arr, elem, i); - }, - - // Support: Android <=4.0 only, PhantomJS 1 only - // push.apply(_, arraylike) throws on ancient WebKit - merge: function (first, second) { - var len = +second.length, - j = 0, - i = first.length; - - for (; j < len; j++) { - first[i++] = second[j]; - } - - first.length = i; - - return first; - }, - - grep: function (elems, callback, invert) { - var callbackInverse, - matches = [], - i = 0, - length = elems.length, - callbackExpect = !invert; - - // Go through the array, only saving the items - // that pass the validator function - for (; i < length; i++) { - callbackInverse = !callback(elems[i], i); - if (callbackInverse !== callbackExpect) { - matches.push(elems[i]); - } - } - - return matches; - }, - - // arg is for internal usage only - map: function (elems, callback, arg) { - var length, value, - i = 0, - ret = []; - - // Go through the array, translating each of the items to their new values - if (isArrayLike(elems)) { - length = elems.length; - for (; i < length; i++) { - value = callback(elems[i], i, arg); - - if (value != null) { - ret.push(value); - } - } - - // Go through every key on the object, - } else { - for (i in elems) { - value = callback(elems[i], i, arg); - - if (value != null) { - ret.push(value); - } - } - } - - // Flatten any nested arrays - return concat.apply([], ret); - }, - - // A global GUID counter for objects - guid: 1, - - // jQuery.support is not used in Core but other projects attach their - // properties to it so it needs to exist. - support: support -}); - -if (typeof Symbol === "function") { - jQuery.fn[Symbol.iterator] = arr[Symbol.iterator]; -} - -// Populate the class2type map -jQuery.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "), - function (i, name) { - class2type["[object " + name + "]"] = name.toLowerCase(); - }); - -function isArrayLike(obj) { - - // Support: real iOS 8.2 only (not reproducible in simulator) - // `in` check used to prevent JIT error (gh-2145) - // hasOwn isn't used here due to false negatives - // regarding Nodelist length in IE - var length = !!obj && "length" in obj && obj.length, - type = toType(obj); - - if (isFunction(obj) || isWindow(obj)) { - return false; - } - - return type === "array" || length === 0 || - typeof length === "number" && length > 0 && (length - 1) in obj; -} - -var Sizzle = - /*! - * Sizzle CSS Selector Engine v2.3.3 - * https://sizzlejs.com/ - * - * Copyright jQuery Foundation and other contributors - * Released under the MIT license - * http://jquery.org/license - * - * Date: 2016-08-08 - */ - (function (window) { - - var i, - support, - Expr, - getText, - isXML, - tokenize, - compile, - select, - outermostContext, - sortInput, - hasDuplicate, - - // Local document vars - setDocument, - document, - docElem, - documentIsHTML, - rbuggyQSA, - rbuggyMatches, - matches, - contains, - - // Instance-specific data - expando = "sizzle" + 1 * new Date(), - preferredDoc = window.document, - dirruns = 0, - done = 0, - classCache = createCache(), - tokenCache = createCache(), - compilerCache = createCache(), - sortOrder = function (a, b) { - if (a === b) { - hasDuplicate = true; - } - return 0; - }, - - // Instance methods - hasOwn = ({}).hasOwnProperty, - arr = [], - pop = arr.pop, - push_native = arr.push, - push = arr.push, - slice = arr.slice, - // Use a stripped-down indexOf as it's faster than native - // https://jsperf.com/thor-indexof-vs-for/5 - indexOf = function (list, elem) { - var i = 0, - len = list.length; - for (; i < len; i++) { - if (list[i] === elem) { - return i; - } - } - return -1; - }, - - booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped", - - // Regular expressions - - // http://www.w3.org/TR/css3-selectors/#whitespace - whitespace = "[\\x20\\t\\r\\n\\f]", - - // http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier - identifier = "(?:\\\\.|[\\w-]|[^\0-\\xa0])+", - - // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors - attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace + - // Operator (capture 2) - "*([*^$|!~]?=)" + whitespace + - // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]" - "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace + - "*\\]", - - pseudos = ":(" + identifier + ")(?:\\((" + - // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments: - // 1. quoted (capture 3; capture 4 or capture 5) - "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + - // 2. simple (capture 6) - "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" + - // 3. anything else (capture 2) - ".*" + - ")\\)|)", - - // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter - rwhitespace = new RegExp(whitespace + "+", "g"), - rtrim = new RegExp("^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g"), - - rcomma = new RegExp("^" + whitespace + "*," + whitespace + "*"), - rcombinators = new RegExp("^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*"), - - rattributeQuotes = new RegExp("=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g"), - - rpseudo = new RegExp(pseudos), - ridentifier = new RegExp("^" + identifier + "$"), - - matchExpr = { - "ID": new RegExp("^#(" + identifier + ")"), - "CLASS": new RegExp("^\\.(" + identifier + ")"), - "TAG": new RegExp("^(" + identifier + "|[*])"), - "ATTR": new RegExp("^" + attributes), - "PSEUDO": new RegExp("^" + pseudos), - "CHILD": new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace + - "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace + - "*(\\d+)|))" + whitespace + "*\\)|)", "i"), - "bool": new RegExp("^(?:" + booleans + ")$", "i"), - // For use in libraries implementing .is() - // We use this for POS matching in `select` - "needsContext": new RegExp("^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + - whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i") - }, - - rinputs = /^(?:input|select|textarea|button)$/i, - rheader = /^h\d$/i, - - rnative = /^[^{]+\{\s*\[native \w/, - - // Easily-parseable/retrievable ID or TAG or CLASS selectors - rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, - - rsibling = /[+~]/, - - // CSS escapes - // http://www.w3.org/TR/CSS21/syndata.html#escaped-characters - runescape = new RegExp("\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig"), - funescape = function (_, escaped, escapedWhitespace) { - var high = "0x" + escaped - 0x10000; - // NaN means non-codepoint - // Support: Firefox<24 - // Workaround erroneous numeric interpretation of +"0x" - return high !== high || escapedWhitespace ? - escaped : - high < 0 ? - // BMP codepoint - String.fromCharCode(high + 0x10000) : - // Supplemental Plane codepoint (surrogate pair) - String.fromCharCode(high >> 10 | 0xD800, high & 0x3FF | 0xDC00); - }, - - // CSS string/identifier serialization - // https://drafts.csswg.org/cssom/#common-serializing-idioms - // eslint-disable-next-line no-control-regex - rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g, - fcssescape = function (ch, asCodePoint) { - if (asCodePoint) { - - // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER - if (ch === "\0") { - return "\uFFFD"; - } - - // Control characters and (dependent upon position) numbers get escaped as code points - return ch.slice(0, -1) + "\\" + ch.charCodeAt(ch.length - 1).toString(16) + " "; - } - - // Other potentially-special ASCII characters get backslash-escaped - return "\\" + ch; - }, - - // Used for iframes - // See setDocument() - // Removing the function wrapper causes a "Permission Denied" - // error in IE - unloadHandler = function () { - setDocument(); - }, - - disabledAncestor = addCombinator( - function (elem) { - return elem.disabled === true && ("form" in elem || "label" in elem); - }, - {dir: "parentNode", next: "legend"} - ); - -// Optimize for push.apply( _, NodeList ) - try { - push.apply( - (arr = slice.call(preferredDoc.childNodes)), - preferredDoc.childNodes - ); - // Support: Android<4.0 - // Detect silently failing push.apply - arr[preferredDoc.childNodes.length].nodeType; - } catch (e) { - push = { - apply: arr.length ? - - // Leverage slice if possible - function (target, els) { - push_native.apply(target, slice.call(els)); - } : - - // Support: IE<9 - // Otherwise append directly - function (target, els) { - var j = target.length, - i = 0; - // Can't trust NodeList.length - while ((target[j++] = els[i++])) { - } - target.length = j - 1; - } - }; - } - - function Sizzle(selector, context, results, seed) { - var m, i, elem, nid, match, groups, newSelector, - newContext = context && context.ownerDocument, - - // nodeType defaults to 9, since context defaults to document - nodeType = context ? context.nodeType : 9; - - results = results || []; - - // Return early from calls with invalid selector or context - if (typeof selector !== "string" || !selector || - nodeType !== 1 && nodeType !== 9 && nodeType !== 11) { - - return results; - } - - // Try to shortcut find operations (as opposed to filters) in HTML documents - if (!seed) { - - if ((context ? context.ownerDocument || context : preferredDoc) !== document) { - setDocument(context); - } - context = context || document; - - if (documentIsHTML) { - - // If the selector is sufficiently simple, try using a "get*By*" DOM method - // (excepting DocumentFragment context, where the methods don't exist) - if (nodeType !== 11 && (match = rquickExpr.exec(selector))) { - - // ID selector - if ((m = match[1])) { - - // Document context - if (nodeType === 9) { - if ((elem = context.getElementById(m))) { - - // Support: IE, Opera, Webkit - // TODO: identify versions - // getElementById can match elements by name instead of ID - if (elem.id === m) { - results.push(elem); - return results; - } - } else { - return results; - } - - // Element context - } else { - - // Support: IE, Opera, Webkit - // TODO: identify versions - // getElementById can match elements by name instead of ID - if (newContext && (elem = newContext.getElementById(m)) && - contains(context, elem) && - elem.id === m) { - - results.push(elem); - return results; - } - } - - // Type selector - } else if (match[2]) { - push.apply(results, context.getElementsByTagName(selector)); - return results; - - // Class selector - } else if ((m = match[3]) && support.getElementsByClassName && - context.getElementsByClassName) { - - push.apply(results, context.getElementsByClassName(m)); - return results; - } - } - - // Take advantage of querySelectorAll - if (support.qsa && - !compilerCache[selector + " "] && - (!rbuggyQSA || !rbuggyQSA.test(selector))) { - - if (nodeType !== 1) { - newContext = context; - newSelector = selector; - - // qSA looks outside Element context, which is not what we want - // Thanks to Andrew Dupont for this workaround technique - // Support: IE <=8 - // Exclude object elements - } else if (context.nodeName.toLowerCase() !== "object") { - - // Capture the context ID, setting it first if necessary - if ((nid = context.getAttribute("id"))) { - nid = nid.replace(rcssescape, fcssescape); - } else { - context.setAttribute("id", (nid = expando)); - } - - // Prefix every selector in the list - groups = tokenize(selector); - i = groups.length; - while (i--) { - groups[i] = "#" + nid + " " + toSelector(groups[i]); - } - newSelector = groups.join(","); - - // Expand context for sibling selectors - newContext = rsibling.test(selector) && testContext(context.parentNode) || - context; - } - - if (newSelector) { - try { - push.apply(results, - newContext.querySelectorAll(newSelector) - ); - return results; - } catch (qsaError) { - } finally { - if (nid === expando) { - context.removeAttribute("id"); - } - } - } - } - } - } - - // All others - return select(selector.replace(rtrim, "$1"), context, results, seed); - } - - /** - * Create key-value caches of limited size - * @returns {function(string, object)} Returns the Object data after storing it on itself with - * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) - * deleting the oldest entry - */ - function createCache() { - var keys = []; - - function cache(key, value) { - // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) - if (keys.push(key + " ") > Expr.cacheLength) { - // Only keep the most recent entries - delete cache[keys.shift()]; - } - return (cache[key + " "] = value); - } - - return cache; - } - - /** - * Mark a function for special use by Sizzle - * @param {Function} fn The function to mark - */ - function markFunction(fn) { - fn[expando] = true; - return fn; - } - - /** - * Support testing using an element - * @param {Function} fn Passed the created element and returns a boolean result - */ - function assert(fn) { - var el = document.createElement("fieldset"); - - try { - return !!fn(el); - } catch (e) { - return false; - } finally { - // Remove from its parent by default - if (el.parentNode) { - el.parentNode.removeChild(el); - } - // release memory in IE - el = null; - } - } - - /** - * Checks document order of two siblings - * @param {Element} a - * @param {Element} b - * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b - */ - function siblingCheck(a, b) { - var cur = b && a, - diff = cur && a.nodeType === 1 && b.nodeType === 1 && - a.sourceIndex - b.sourceIndex; - - // Use IE sourceIndex if available on both nodes - if (diff) { - return diff; - } - - // Check if b follows a - if (cur) { - while ((cur = cur.nextSibling)) { - if (cur === b) { - return -1; - } - } - } - - return a ? 1 : -1; - } - - /** - * Returns a function to use in pseudos for input types - * @param {String} type - */ - function createInputPseudo(type) { - return function (elem) { - var name = elem.nodeName.toLowerCase(); - return name === "input" && elem.type === type; - }; - } - - /** - * Returns a function to use in pseudos for buttons - * @param {String} type - */ - function createButtonPseudo(type) { - return function (elem) { - var name = elem.nodeName.toLowerCase(); - return (name === "input" || name === "button") && elem.type === type; - }; - } - - /** - * Returns a function to use in pseudos for :enabled/:disabled - * @param {Boolean} disabled true for :disabled; false for :enabled - */ - function createDisabledPseudo(disabled) { - - // Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable - return function (elem) { - - // Only certain elements can match :enabled or :disabled - // https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled - // https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled - if ("form" in elem) { - - // Check for inherited disabledness on relevant non-disabled elements: - // * listed form-associated elements in a disabled fieldset - // https://html.spec.whatwg.org/multipage/forms.html#category-listed - // https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled - // * option elements in a disabled optgroup - // https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled - // All such elements have a "form" property. - if (elem.parentNode && elem.disabled === false) { - - // Option elements defer to a parent optgroup if present - if ("label" in elem) { - if ("label" in elem.parentNode) { - return elem.parentNode.disabled === disabled; - } else { - return elem.disabled === disabled; - } - } - - // Support: IE 6 - 11 - // Use the isDisabled shortcut property to check for disabled fieldset ancestors - return elem.isDisabled === disabled || - - // Where there is no isDisabled, check manually - /* jshint -W018 */ - elem.isDisabled !== !disabled && - disabledAncestor(elem) === disabled; - } - - return elem.disabled === disabled; - - // Try to winnow out elements that can't be disabled before trusting the disabled property. - // Some victims get caught in our net (label, legend, menu, track), but it shouldn't - // even exist on them, let alone have a boolean value. - } else if ("label" in elem) { - return elem.disabled === disabled; - } - - // Remaining elements are neither :enabled nor :disabled - return false; - }; - } - - /** - * Returns a function to use in pseudos for positionals - * @param {Function} fn - */ - function createPositionalPseudo(fn) { - return markFunction(function (argument) { - argument = +argument; - return markFunction(function (seed, matches) { - var j, - matchIndexes = fn([], seed.length, argument), - i = matchIndexes.length; - - // Match elements found at the specified indexes - while (i--) { - if (seed[(j = matchIndexes[i])]) { - seed[j] = !(matches[j] = seed[j]); - } - } - }); - }); - } - - /** - * Checks a node for validity as a Sizzle context - * @param {Element|Object=} context - * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value - */ - function testContext(context) { - return context && typeof context.getElementsByTagName !== "undefined" && context; - } - -// Expose support vars for convenience - support = Sizzle.support = {}; - - /** - * Detects XML nodes - * @param {Element|Object} elem An element or a document - * @returns {Boolean} True iff elem is a non-HTML XML node - */ - isXML = Sizzle.isXML = function (elem) { - // documentElement is verified for cases where it doesn't yet exist - // (such as loading iframes in IE - #4833) - var documentElement = elem && (elem.ownerDocument || elem).documentElement; - return documentElement ? documentElement.nodeName !== "HTML" : false; - }; - - /** - * Sets document-related variables once based on the current document - * @param {Element|Object} [doc] An element or document object to use to set the document - * @returns {Object} Returns the current document - */ - setDocument = Sizzle.setDocument = function (node) { - var hasCompare, subWindow, - doc = node ? node.ownerDocument || node : preferredDoc; - - // Return early if doc is invalid or already selected - if (doc === document || doc.nodeType !== 9 || !doc.documentElement) { - return document; - } - - // Update global variables - document = doc; - docElem = document.documentElement; - documentIsHTML = !isXML(document); - - // Support: IE 9-11, Edge - // Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936) - if (preferredDoc !== document && - (subWindow = document.defaultView) && subWindow.top !== subWindow) { - - // Support: IE 11, Edge - if (subWindow.addEventListener) { - subWindow.addEventListener("unload", unloadHandler, false); - - // Support: IE 9 - 10 only - } else if (subWindow.attachEvent) { - subWindow.attachEvent("onunload", unloadHandler); - } - } - - /* Attributes - ---------------------------------------------------------------------- */ - - // Support: IE<8 - // Verify that getAttribute really returns attributes and not properties - // (excepting IE8 booleans) - support.attributes = assert(function (el) { - el.className = "i"; - return !el.getAttribute("className"); - }); - - /* getElement(s)By* - ---------------------------------------------------------------------- */ - - // Check if getElementsByTagName("*") returns only elements - support.getElementsByTagName = assert(function (el) { - el.appendChild(document.createComment("")); - return !el.getElementsByTagName("*").length; - }); - - // Support: IE<9 - support.getElementsByClassName = rnative.test(document.getElementsByClassName); - - // Support: IE<10 - // Check if getElementById returns elements by name - // The broken getElementById methods don't pick up programmatically-set names, - // so use a roundabout getElementsByName test - support.getById = assert(function (el) { - docElem.appendChild(el).id = expando; - return !document.getElementsByName || !document.getElementsByName(expando).length; - }); - - // ID filter and find - if (support.getById) { - Expr.filter["ID"] = function (id) { - var attrId = id.replace(runescape, funescape); - return function (elem) { - return elem.getAttribute("id") === attrId; - }; - }; - Expr.find["ID"] = function (id, context) { - if (typeof context.getElementById !== "undefined" && documentIsHTML) { - var elem = context.getElementById(id); - return elem ? [elem] : []; - } - }; - } else { - Expr.filter["ID"] = function (id) { - var attrId = id.replace(runescape, funescape); - return function (elem) { - var node = typeof elem.getAttributeNode !== "undefined" && - elem.getAttributeNode("id"); - return node && node.value === attrId; - }; - }; - - // Support: IE 6 - 7 only - // getElementById is not reliable as a find shortcut - Expr.find["ID"] = function (id, context) { - if (typeof context.getElementById !== "undefined" && documentIsHTML) { - var node, i, elems, - elem = context.getElementById(id); - - if (elem) { - - // Verify the id attribute - node = elem.getAttributeNode("id"); - if (node && node.value === id) { - return [elem]; - } - - // Fall back on getElementsByName - elems = context.getElementsByName(id); - i = 0; - while ((elem = elems[i++])) { - node = elem.getAttributeNode("id"); - if (node && node.value === id) { - return [elem]; - } - } - } - - return []; - } - }; - } - - // Tag - Expr.find["TAG"] = support.getElementsByTagName ? - function (tag, context) { - if (typeof context.getElementsByTagName !== "undefined") { - return context.getElementsByTagName(tag); - - // DocumentFragment nodes don't have gEBTN - } else if (support.qsa) { - return context.querySelectorAll(tag); - } - } : - - function (tag, context) { - var elem, - tmp = [], - i = 0, - // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too - results = context.getElementsByTagName(tag); - - // Filter out possible comments - if (tag === "*") { - while ((elem = results[i++])) { - if (elem.nodeType === 1) { - tmp.push(elem); - } - } - - return tmp; - } - return results; - }; - - // Class - Expr.find["CLASS"] = support.getElementsByClassName && function (className, context) { - if (typeof context.getElementsByClassName !== "undefined" && documentIsHTML) { - return context.getElementsByClassName(className); - } - }; - - /* QSA/matchesSelector - ---------------------------------------------------------------------- */ - - // QSA and matchesSelector support - - // matchesSelector(:active) reports false when true (IE9/Opera 11.5) - rbuggyMatches = []; - - // qSa(:focus) reports false when true (Chrome 21) - // We allow this because of a bug in IE8/9 that throws an error - // whenever `document.activeElement` is accessed on an iframe - // So, we allow :focus to pass through QSA all the time to avoid the IE error - // See https://bugs.jquery.com/ticket/13378 - rbuggyQSA = []; - - if ((support.qsa = rnative.test(document.querySelectorAll))) { - // Build QSA regex - // Regex strategy adopted from Diego Perini - assert(function (el) { - // Select is set to empty string on purpose - // This is to test IE's treatment of not explicitly - // setting a boolean content attribute, - // since its presence should be enough - // https://bugs.jquery.com/ticket/12359 - docElem.appendChild(el).innerHTML = "" + - ""; - - // Support: IE8, Opera 11-12.16 - // Nothing should be selected when empty strings follow ^= or $= or *= - // The test attribute must be unknown in Opera but "safe" for WinRT - // https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section - if (el.querySelectorAll("[msallowcapture^='']").length) { - rbuggyQSA.push("[*^$]=" + whitespace + "*(?:''|\"\")"); - } - - // Support: IE8 - // Boolean attributes and "value" are not treated correctly - if (!el.querySelectorAll("[selected]").length) { - rbuggyQSA.push("\\[" + whitespace + "*(?:value|" + booleans + ")"); - } - - // Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+ - if (!el.querySelectorAll("[id~=" + expando + "-]").length) { - rbuggyQSA.push("~="); - } - - // Webkit/Opera - :checked should return selected option elements - // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked - // IE8 throws error here and will not see later tests - if (!el.querySelectorAll(":checked").length) { - rbuggyQSA.push(":checked"); - } - - // Support: Safari 8+, iOS 8+ - // https://bugs.webkit.org/show_bug.cgi?id=136851 - // In-page `selector#id sibling-combinator selector` fails - if (!el.querySelectorAll("a#" + expando + "+*").length) { - rbuggyQSA.push(".#.+[+~]"); - } - }); - - assert(function (el) { - el.innerHTML = "" + - ""; - - // Support: Windows 8 Native Apps - // The type and name attributes are restricted during .innerHTML assignment - var input = document.createElement("input"); - input.setAttribute("type", "hidden"); - el.appendChild(input).setAttribute("name", "D"); - - // Support: IE8 - // Enforce case-sensitivity of name attribute - if (el.querySelectorAll("[name=d]").length) { - rbuggyQSA.push("name" + whitespace + "*[*^$|!~]?="); - } - - // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) - // IE8 throws error here and will not see later tests - if (el.querySelectorAll(":enabled").length !== 2) { - rbuggyQSA.push(":enabled", ":disabled"); - } - - // Support: IE9-11+ - // IE's :disabled selector does not pick up the children of disabled fieldsets - docElem.appendChild(el).disabled = true; - if (el.querySelectorAll(":disabled").length !== 2) { - rbuggyQSA.push(":enabled", ":disabled"); - } - - // Opera 10-11 does not throw on post-comma invalid pseudos - el.querySelectorAll("*,:x"); - rbuggyQSA.push(",.*:"); - }); - } - - if ((support.matchesSelector = rnative.test((matches = docElem.matches || - docElem.webkitMatchesSelector || - docElem.mozMatchesSelector || - docElem.oMatchesSelector || - docElem.msMatchesSelector)))) { - - assert(function (el) { - // Check to see if it's possible to do matchesSelector - // on a disconnected node (IE 9) - support.disconnectedMatch = matches.call(el, "*"); - - // This should fail with an exception - // Gecko does not error, returns false instead - matches.call(el, "[s!='']:x"); - rbuggyMatches.push("!=", pseudos); - }); - } - - rbuggyQSA = rbuggyQSA.length && new RegExp(rbuggyQSA.join("|")); - rbuggyMatches = rbuggyMatches.length && new RegExp(rbuggyMatches.join("|")); - - /* Contains - ---------------------------------------------------------------------- */ - hasCompare = rnative.test(docElem.compareDocumentPosition); - - // Element contains another - // Purposefully self-exclusive - // As in, an element does not contain itself - contains = hasCompare || rnative.test(docElem.contains) ? - function (a, b) { - var adown = a.nodeType === 9 ? a.documentElement : a, - bup = b && b.parentNode; - return a === bup || !!(bup && bup.nodeType === 1 && ( - adown.contains ? - adown.contains(bup) : - a.compareDocumentPosition && a.compareDocumentPosition(bup) & 16 - )); - } : - function (a, b) { - if (b) { - while ((b = b.parentNode)) { - if (b === a) { - return true; - } - } - } - return false; - }; - - /* Sorting - ---------------------------------------------------------------------- */ - - // Document order sorting - sortOrder = hasCompare ? - function (a, b) { - - // Flag for duplicate removal - if (a === b) { - hasDuplicate = true; - return 0; - } - - // Sort on method existence if only one input has compareDocumentPosition - var compare = !a.compareDocumentPosition - !b.compareDocumentPosition; - if (compare) { - return compare; - } - - // Calculate position if both inputs belong to the same document - compare = (a.ownerDocument || a) === (b.ownerDocument || b) ? - a.compareDocumentPosition(b) : - - // Otherwise we know they are disconnected - 1; - - // Disconnected nodes - if (compare & 1 || - (!support.sortDetached && b.compareDocumentPosition(a) === compare)) { - - // Choose the first element that is related to our preferred document - if (a === document || a.ownerDocument === preferredDoc && contains(preferredDoc, a)) { - return -1; - } - if (b === document || b.ownerDocument === preferredDoc && contains(preferredDoc, b)) { - return 1; - } - - // Maintain original order - return sortInput ? - (indexOf(sortInput, a) - indexOf(sortInput, b)) : - 0; - } - - return compare & 4 ? -1 : 1; - } : - function (a, b) { - // Exit early if the nodes are identical - if (a === b) { - hasDuplicate = true; - return 0; - } - - var cur, - i = 0, - aup = a.parentNode, - bup = b.parentNode, - ap = [a], - bp = [b]; - - // Parentless nodes are either documents or disconnected - if (!aup || !bup) { - return a === document ? -1 : - b === document ? 1 : - aup ? -1 : - bup ? 1 : - sortInput ? - (indexOf(sortInput, a) - indexOf(sortInput, b)) : - 0; - - // If the nodes are siblings, we can do a quick check - } else if (aup === bup) { - return siblingCheck(a, b); - } - - // Otherwise we need full lists of their ancestors for comparison - cur = a; - while ((cur = cur.parentNode)) { - ap.unshift(cur); - } - cur = b; - while ((cur = cur.parentNode)) { - bp.unshift(cur); - } - - // Walk down the tree looking for a discrepancy - while (ap[i] === bp[i]) { - i++; - } - - return i ? - // Do a sibling check if the nodes have a common ancestor - siblingCheck(ap[i], bp[i]) : - - // Otherwise nodes in our document sort first - ap[i] === preferredDoc ? -1 : - bp[i] === preferredDoc ? 1 : - 0; - }; - - return document; - }; - - Sizzle.matches = function (expr, elements) { - return Sizzle(expr, null, null, elements); - }; - - Sizzle.matchesSelector = function (elem, expr) { - // Set document vars if needed - if ((elem.ownerDocument || elem) !== document) { - setDocument(elem); - } - - // Make sure that attribute selectors are quoted - expr = expr.replace(rattributeQuotes, "='$1']"); - - if (support.matchesSelector && documentIsHTML && - !compilerCache[expr + " "] && - (!rbuggyMatches || !rbuggyMatches.test(expr)) && - (!rbuggyQSA || !rbuggyQSA.test(expr))) { - - try { - var ret = matches.call(elem, expr); - - // IE 9's matchesSelector returns false on disconnected nodes - if (ret || support.disconnectedMatch || - // As well, disconnected nodes are said to be in a document - // fragment in IE 9 - elem.document && elem.document.nodeType !== 11) { - return ret; - } - } catch (e) { - } - } - - return Sizzle(expr, document, null, [elem]).length > 0; - }; - - Sizzle.contains = function (context, elem) { - // Set document vars if needed - if ((context.ownerDocument || context) !== document) { - setDocument(context); - } - return contains(context, elem); - }; - - Sizzle.attr = function (elem, name) { - // Set document vars if needed - if ((elem.ownerDocument || elem) !== document) { - setDocument(elem); - } - - var fn = Expr.attrHandle[name.toLowerCase()], - // Don't get fooled by Object.prototype properties (jQuery #13807) - val = fn && hasOwn.call(Expr.attrHandle, name.toLowerCase()) ? - fn(elem, name, !documentIsHTML) : - undefined; - - return val !== undefined ? - val : - support.attributes || !documentIsHTML ? - elem.getAttribute(name) : - (val = elem.getAttributeNode(name)) && val.specified ? - val.value : - null; - }; - - Sizzle.escape = function (sel) { - return (sel + "").replace(rcssescape, fcssescape); - }; - - Sizzle.error = function (msg) { - throw new Error("Syntax error, unrecognized expression: " + msg); - }; - - /** - * Document sorting and removing duplicates - * @param {ArrayLike} results - */ - Sizzle.uniqueSort = function (results) { - var elem, - duplicates = [], - j = 0, - i = 0; - - // Unless we *know* we can detect duplicates, assume their presence - hasDuplicate = !support.detectDuplicates; - sortInput = !support.sortStable && results.slice(0); - results.sort(sortOrder); - - if (hasDuplicate) { - while ((elem = results[i++])) { - if (elem === results[i]) { - j = duplicates.push(i); - } - } - while (j--) { - results.splice(duplicates[j], 1); - } - } - - // Clear input after sorting to release objects - // See https://github.com/jquery/sizzle/pull/225 - sortInput = null; - - return results; - }; - - /** - * Utility function for retrieving the text value of an array of DOM nodes - * @param {Array|Element} elem - */ - getText = Sizzle.getText = function (elem) { - var node, - ret = "", - i = 0, - nodeType = elem.nodeType; - - if (!nodeType) { - // If no nodeType, this is expected to be an array - while ((node = elem[i++])) { - // Do not traverse comment nodes - ret += getText(node); - } - } else if (nodeType === 1 || nodeType === 9 || nodeType === 11) { - // Use textContent for elements - // innerText usage removed for consistency of new lines (jQuery #11153) - if (typeof elem.textContent === "string") { - return elem.textContent; - } else { - // Traverse its children - for (elem = elem.firstChild; elem; elem = elem.nextSibling) { - ret += getText(elem); - } - } - } else if (nodeType === 3 || nodeType === 4) { - return elem.nodeValue; - } - // Do not include comment or processing instruction nodes - - return ret; - }; - - Expr = Sizzle.selectors = { - - // Can be adjusted by the user - cacheLength: 50, - - createPseudo: markFunction, - - match: matchExpr, - - attrHandle: {}, - - find: {}, - - relative: { - ">": {dir: "parentNode", first: true}, - " ": {dir: "parentNode"}, - "+": {dir: "previousSibling", first: true}, - "~": {dir: "previousSibling"} - }, - - preFilter: { - "ATTR": function (match) { - match[1] = match[1].replace(runescape, funescape); - - // Move the given value to match[3] whether quoted or unquoted - match[3] = (match[3] || match[4] || match[5] || "").replace(runescape, funescape); - - if (match[2] === "~=") { - match[3] = " " + match[3] + " "; - } - - return match.slice(0, 4); - }, - - "CHILD": function (match) { - /* matches from matchExpr["CHILD"] - 1 type (only|nth|...) - 2 what (child|of-type) - 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) - 4 xn-component of xn+y argument ([+-]?\d*n|) - 5 sign of xn-component - 6 x of xn-component - 7 sign of y-component - 8 y of y-component - */ - match[1] = match[1].toLowerCase(); - - if (match[1].slice(0, 3) === "nth") { - // nth-* requires argument - if (!match[3]) { - Sizzle.error(match[0]); - } - - // numeric x and y parameters for Expr.filter.CHILD - // remember that false/true cast respectively to 0/1 - match[4] = +(match[4] ? match[5] + (match[6] || 1) : 2 * (match[3] === "even" || match[3] === "odd")); - match[5] = +((match[7] + match[8]) || match[3] === "odd"); - - // other types prohibit arguments - } else if (match[3]) { - Sizzle.error(match[0]); - } - - return match; - }, - - "PSEUDO": function (match) { - var excess, - unquoted = !match[6] && match[2]; - - if (matchExpr["CHILD"].test(match[0])) { - return null; - } - - // Accept quoted arguments as-is - if (match[3]) { - match[2] = match[4] || match[5] || ""; - - // Strip excess characters from unquoted arguments - } else if (unquoted && rpseudo.test(unquoted) && - // Get excess from tokenize (recursively) - (excess = tokenize(unquoted, true)) && - // advance to the next closing parenthesis - (excess = unquoted.indexOf(")", unquoted.length - excess) - unquoted.length)) { - - // excess is a negative index - match[0] = match[0].slice(0, excess); - match[2] = unquoted.slice(0, excess); - } - - // Return only captures needed by the pseudo filter method (type and argument) - return match.slice(0, 3); - } - }, - - filter: { - - "TAG": function (nodeNameSelector) { - var nodeName = nodeNameSelector.replace(runescape, funescape).toLowerCase(); - return nodeNameSelector === "*" ? - function () { - return true; - } : - function (elem) { - return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; - }; - }, - - "CLASS": function (className) { - var pattern = classCache[className + " "]; - - return pattern || - (pattern = new RegExp("(^|" + whitespace + ")" + className + "(" + whitespace + "|$)")) && - classCache(className, function (elem) { - return pattern.test(typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || ""); - }); - }, - - "ATTR": function (name, operator, check) { - return function (elem) { - var result = Sizzle.attr(elem, name); - - if (result == null) { - return operator === "!="; - } - if (!operator) { - return true; - } - - result += ""; - - return operator === "=" ? result === check : - operator === "!=" ? result !== check : - operator === "^=" ? check && result.indexOf(check) === 0 : - operator === "*=" ? check && result.indexOf(check) > -1 : - operator === "$=" ? check && result.slice(-check.length) === check : - operator === "~=" ? (" " + result.replace(rwhitespace, " ") + " ").indexOf(check) > -1 : - operator === "|=" ? result === check || result.slice(0, check.length + 1) === check + "-" : - false; - }; - }, - - "CHILD": function (type, what, argument, first, last) { - var simple = type.slice(0, 3) !== "nth", - forward = type.slice(-4) !== "last", - ofType = what === "of-type"; - - return first === 1 && last === 0 ? - - // Shortcut for :nth-*(n) - function (elem) { - return !!elem.parentNode; - } : - - function (elem, context, xml) { - var cache, uniqueCache, outerCache, node, nodeIndex, start, - dir = simple !== forward ? "nextSibling" : "previousSibling", - parent = elem.parentNode, - name = ofType && elem.nodeName.toLowerCase(), - useCache = !xml && !ofType, - diff = false; - - if (parent) { - - // :(first|last|only)-(child|of-type) - if (simple) { - while (dir) { - node = elem; - while ((node = node[dir])) { - if (ofType ? - node.nodeName.toLowerCase() === name : - node.nodeType === 1) { - - return false; - } - } - // Reverse direction for :only-* (if we haven't yet done so) - start = dir = type === "only" && !start && "nextSibling"; - } - return true; - } - - start = [forward ? parent.firstChild : parent.lastChild]; - - // non-xml :nth-child(...) stores cache data on `parent` - if (forward && useCache) { - - // Seek `elem` from a previously-cached index - - // ...in a gzip-friendly way - node = parent; - outerCache = node[expando] || (node[expando] = {}); - - // Support: IE <9 only - // Defend against cloned attroperties (jQuery gh-1709) - uniqueCache = outerCache[node.uniqueID] || - (outerCache[node.uniqueID] = {}); - - cache = uniqueCache[type] || []; - nodeIndex = cache[0] === dirruns && cache[1]; - diff = nodeIndex && cache[2]; - node = nodeIndex && parent.childNodes[nodeIndex]; - - while ((node = ++nodeIndex && node && node[dir] || - - // Fallback to seeking `elem` from the start - (diff = nodeIndex = 0) || start.pop())) { - - // When found, cache indexes on `parent` and break - if (node.nodeType === 1 && ++diff && node === elem) { - uniqueCache[type] = [dirruns, nodeIndex, diff]; - break; - } - } - - } else { - // Use previously-cached element index if available - if (useCache) { - // ...in a gzip-friendly way - node = elem; - outerCache = node[expando] || (node[expando] = {}); - - // Support: IE <9 only - // Defend against cloned attroperties (jQuery gh-1709) - uniqueCache = outerCache[node.uniqueID] || - (outerCache[node.uniqueID] = {}); - - cache = uniqueCache[type] || []; - nodeIndex = cache[0] === dirruns && cache[1]; - diff = nodeIndex; - } - - // xml :nth-child(...) - // or :nth-last-child(...) or :nth(-last)?-of-type(...) - if (diff === false) { - // Use the same loop as above to seek `elem` from the start - while ((node = ++nodeIndex && node && node[dir] || - (diff = nodeIndex = 0) || start.pop())) { - - if ((ofType ? - node.nodeName.toLowerCase() === name : - node.nodeType === 1) && - ++diff) { - - // Cache the index of each encountered element - if (useCache) { - outerCache = node[expando] || (node[expando] = {}); - - // Support: IE <9 only - // Defend against cloned attroperties (jQuery gh-1709) - uniqueCache = outerCache[node.uniqueID] || - (outerCache[node.uniqueID] = {}); - - uniqueCache[type] = [dirruns, diff]; - } - - if (node === elem) { - break; - } - } - } - } - } - - // Incorporate the offset, then check against cycle size - diff -= last; - return diff === first || (diff % first === 0 && diff / first >= 0); - } - }; - }, - - "PSEUDO": function (pseudo, argument) { - // pseudo-class names are case-insensitive - // http://www.w3.org/TR/selectors/#pseudo-classes - // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters - // Remember that setFilters inherits from pseudos - var args, - fn = Expr.pseudos[pseudo] || Expr.setFilters[pseudo.toLowerCase()] || - Sizzle.error("unsupported pseudo: " + pseudo); - - // The user may use createPseudo to indicate that - // arguments are needed to create the filter function - // just as Sizzle does - if (fn[expando]) { - return fn(argument); - } - - // But maintain support for old signatures - if (fn.length > 1) { - args = [pseudo, pseudo, "", argument]; - return Expr.setFilters.hasOwnProperty(pseudo.toLowerCase()) ? - markFunction(function (seed, matches) { - var idx, - matched = fn(seed, argument), - i = matched.length; - while (i--) { - idx = indexOf(seed, matched[i]); - seed[idx] = !(matches[idx] = matched[i]); - } - }) : - function (elem) { - return fn(elem, 0, args); - }; - } - - return fn; - } - }, - - pseudos: { - // Potentially complex pseudos - "not": markFunction(function (selector) { - // Trim the selector passed to compile - // to avoid treating leading and trailing - // spaces as combinators - var input = [], - results = [], - matcher = compile(selector.replace(rtrim, "$1")); - - return matcher[expando] ? - markFunction(function (seed, matches, context, xml) { - var elem, - unmatched = matcher(seed, null, xml, []), - i = seed.length; - - // Match elements unmatched by `matcher` - while (i--) { - if ((elem = unmatched[i])) { - seed[i] = !(matches[i] = elem); - } - } - }) : - function (elem, context, xml) { - input[0] = elem; - matcher(input, null, xml, results); - // Don't keep the element (issue #299) - input[0] = null; - return !results.pop(); - }; - }), - - "has": markFunction(function (selector) { - return function (elem) { - return Sizzle(selector, elem).length > 0; - }; - }), - - "contains": markFunction(function (text) { - text = text.replace(runescape, funescape); - return function (elem) { - return (elem.textContent || elem.innerText || getText(elem)).indexOf(text) > -1; - }; - }), - - // "Whether an element is represented by a :lang() selector - // is based solely on the element's language value - // being equal to the identifier C, - // or beginning with the identifier C immediately followed by "-". - // The matching of C against the element's language value is performed case-insensitively. - // The identifier C does not have to be a valid language name." - // http://www.w3.org/TR/selectors/#lang-pseudo - "lang": markFunction(function (lang) { - // lang value must be a valid identifier - if (!ridentifier.test(lang || "")) { - Sizzle.error("unsupported lang: " + lang); - } - lang = lang.replace(runescape, funescape).toLowerCase(); - return function (elem) { - var elemLang; - do { - if ((elemLang = documentIsHTML ? - elem.lang : - elem.getAttribute("xml:lang") || elem.getAttribute("lang"))) { - - elemLang = elemLang.toLowerCase(); - return elemLang === lang || elemLang.indexOf(lang + "-") === 0; - } - } while ((elem = elem.parentNode) && elem.nodeType === 1); - return false; - }; - }), - - // Miscellaneous - "target": function (elem) { - var hash = window.location && window.location.hash; - return hash && hash.slice(1) === elem.id; - }, - - "root": function (elem) { - return elem === docElem; - }, - - "focus": function (elem) { - return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex); - }, - - // Boolean properties - "enabled": createDisabledPseudo(false), - "disabled": createDisabledPseudo(true), - - "checked": function (elem) { - // In CSS3, :checked should return both checked and selected elements - // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked - var nodeName = elem.nodeName.toLowerCase(); - return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected); - }, - - "selected": function (elem) { - // Accessing this property makes selected-by-default - // options in Safari work properly - if (elem.parentNode) { - elem.parentNode.selectedIndex; - } - - return elem.selected === true; - }, - - // Contents - "empty": function (elem) { - // http://www.w3.org/TR/selectors/#empty-pseudo - // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5), - // but not by others (comment: 8; processing instruction: 7; etc.) - // nodeType < 6 works because attributes (2) do not appear as children - for (elem = elem.firstChild; elem; elem = elem.nextSibling) { - if (elem.nodeType < 6) { - return false; - } - } - return true; - }, - - "parent": function (elem) { - return !Expr.pseudos["empty"](elem); - }, - - // Element/input types - "header": function (elem) { - return rheader.test(elem.nodeName); - }, - - "input": function (elem) { - return rinputs.test(elem.nodeName); - }, - - "button": function (elem) { - var name = elem.nodeName.toLowerCase(); - return name === "input" && elem.type === "button" || name === "button"; - }, - - "text": function (elem) { - var attr; - return elem.nodeName.toLowerCase() === "input" && - elem.type === "text" && - - // Support: IE<8 - // New HTML5 attribute values (e.g., "search") appear with elem.type === "text" - ((attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text"); - }, - - // Position-in-collection - "first": createPositionalPseudo(function () { - return [0]; - }), - - "last": createPositionalPseudo(function (matchIndexes, length) { - return [length - 1]; - }), - - "eq": createPositionalPseudo(function (matchIndexes, length, argument) { - return [argument < 0 ? argument + length : argument]; - }), - - "even": createPositionalPseudo(function (matchIndexes, length) { - var i = 0; - for (; i < length; i += 2) { - matchIndexes.push(i); - } - return matchIndexes; - }), - - "odd": createPositionalPseudo(function (matchIndexes, length) { - var i = 1; - for (; i < length; i += 2) { - matchIndexes.push(i); - } - return matchIndexes; - }), - - "lt": createPositionalPseudo(function (matchIndexes, length, argument) { - var i = argument < 0 ? argument + length : argument; - for (; --i >= 0;) { - matchIndexes.push(i); - } - return matchIndexes; - }), - - "gt": createPositionalPseudo(function (matchIndexes, length, argument) { - var i = argument < 0 ? argument + length : argument; - for (; ++i < length;) { - matchIndexes.push(i); - } - return matchIndexes; - }) - } - }; - - Expr.pseudos["nth"] = Expr.pseudos["eq"]; - -// Add button/input type pseudos - for (i in {radio: true, checkbox: true, file: true, password: true, image: true}) { - Expr.pseudos[i] = createInputPseudo(i); - } - for (i in {submit: true, reset: true}) { - Expr.pseudos[i] = createButtonPseudo(i); - } - -// Easy API for creating new setFilters - function setFilters() { - } - - setFilters.prototype = Expr.filters = Expr.pseudos; - Expr.setFilters = new setFilters(); - - tokenize = Sizzle.tokenize = function (selector, parseOnly) { - var matched, match, tokens, type, - soFar, groups, preFilters, - cached = tokenCache[selector + " "]; - - if (cached) { - return parseOnly ? 0 : cached.slice(0); - } - - soFar = selector; - groups = []; - preFilters = Expr.preFilter; - - while (soFar) { - - // Comma and first run - if (!matched || (match = rcomma.exec(soFar))) { - if (match) { - // Don't consume trailing commas as valid - soFar = soFar.slice(match[0].length) || soFar; - } - groups.push((tokens = [])); - } - - matched = false; - - // Combinators - if ((match = rcombinators.exec(soFar))) { - matched = match.shift(); - tokens.push({ - value: matched, - // Cast descendant combinators to space - type: match[0].replace(rtrim, " ") - }); - soFar = soFar.slice(matched.length); - } - - // Filters - for (type in Expr.filter) { - if ((match = matchExpr[type].exec(soFar)) && (!preFilters[type] || - (match = preFilters[type](match)))) { - matched = match.shift(); - tokens.push({ - value: matched, - type: type, - matches: match - }); - soFar = soFar.slice(matched.length); - } - } - - if (!matched) { - break; - } - } - - // Return the length of the invalid excess - // if we're just parsing - // Otherwise, throw an error or return tokens - return parseOnly ? - soFar.length : - soFar ? - Sizzle.error(selector) : - // Cache the tokens - tokenCache(selector, groups).slice(0); - }; - - function toSelector(tokens) { - var i = 0, - len = tokens.length, - selector = ""; - for (; i < len; i++) { - selector += tokens[i].value; - } - return selector; - } - - function addCombinator(matcher, combinator, base) { - var dir = combinator.dir, - skip = combinator.next, - key = skip || dir, - checkNonElements = base && key === "parentNode", - doneName = done++; - - return combinator.first ? - // Check against closest ancestor/preceding element - function (elem, context, xml) { - while ((elem = elem[dir])) { - if (elem.nodeType === 1 || checkNonElements) { - return matcher(elem, context, xml); - } - } - return false; - } : - - // Check against all ancestor/preceding elements - function (elem, context, xml) { - var oldCache, uniqueCache, outerCache, - newCache = [dirruns, doneName]; - - // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching - if (xml) { - while ((elem = elem[dir])) { - if (elem.nodeType === 1 || checkNonElements) { - if (matcher(elem, context, xml)) { - return true; - } - } - } - } else { - while ((elem = elem[dir])) { - if (elem.nodeType === 1 || checkNonElements) { - outerCache = elem[expando] || (elem[expando] = {}); - - // Support: IE <9 only - // Defend against cloned attroperties (jQuery gh-1709) - uniqueCache = outerCache[elem.uniqueID] || (outerCache[elem.uniqueID] = {}); - - if (skip && skip === elem.nodeName.toLowerCase()) { - elem = elem[dir] || elem; - } else if ((oldCache = uniqueCache[key]) && - oldCache[0] === dirruns && oldCache[1] === doneName) { - - // Assign to newCache so results back-propagate to previous elements - return (newCache[2] = oldCache[2]); - } else { - // Reuse newcache so results back-propagate to previous elements - uniqueCache[key] = newCache; - - // A match means we're done; a fail means we have to keep checking - if ((newCache[2] = matcher(elem, context, xml))) { - return true; - } - } - } - } - } - return false; - }; - } - - function elementMatcher(matchers) { - return matchers.length > 1 ? - function (elem, context, xml) { - var i = matchers.length; - while (i--) { - if (!matchers[i](elem, context, xml)) { - return false; - } - } - return true; - } : - matchers[0]; - } - - function multipleContexts(selector, contexts, results) { - var i = 0, - len = contexts.length; - for (; i < len; i++) { - Sizzle(selector, contexts[i], results); - } - return results; - } - - function condense(unmatched, map, filter, context, xml) { - var elem, - newUnmatched = [], - i = 0, - len = unmatched.length, - mapped = map != null; - - for (; i < len; i++) { - if ((elem = unmatched[i])) { - if (!filter || filter(elem, context, xml)) { - newUnmatched.push(elem); - if (mapped) { - map.push(i); - } - } - } - } - - return newUnmatched; - } - - function setMatcher(preFilter, selector, matcher, postFilter, postFinder, postSelector) { - if (postFilter && !postFilter[expando]) { - postFilter = setMatcher(postFilter); - } - if (postFinder && !postFinder[expando]) { - postFinder = setMatcher(postFinder, postSelector); - } - return markFunction(function (seed, results, context, xml) { - var temp, i, elem, - preMap = [], - postMap = [], - preexisting = results.length, - - // Get initial elements from seed or context - elems = seed || multipleContexts(selector || "*", context.nodeType ? [context] : context, []), - - // Prefilter to get matcher input, preserving a map for seed-results synchronization - matcherIn = preFilter && (seed || !selector) ? - condense(elems, preMap, preFilter, context, xml) : - elems, - - matcherOut = matcher ? - // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, - postFinder || (seed ? preFilter : preexisting || postFilter) ? - - // ...intermediate processing is necessary - [] : - - // ...otherwise use results directly - results : - matcherIn; - - // Find primary matches - if (matcher) { - matcher(matcherIn, matcherOut, context, xml); - } - - // Apply postFilter - if (postFilter) { - temp = condense(matcherOut, postMap); - postFilter(temp, [], context, xml); - - // Un-match failing elements by moving them back to matcherIn - i = temp.length; - while (i--) { - if ((elem = temp[i])) { - matcherOut[postMap[i]] = !(matcherIn[postMap[i]] = elem); - } - } - } - - if (seed) { - if (postFinder || preFilter) { - if (postFinder) { - // Get the final matcherOut by condensing this intermediate into postFinder contexts - temp = []; - i = matcherOut.length; - while (i--) { - if ((elem = matcherOut[i])) { - // Restore matcherIn since elem is not yet a final match - temp.push((matcherIn[i] = elem)); - } - } - postFinder(null, (matcherOut = []), temp, xml); - } - - // Move matched elements from seed to results to keep them synchronized - i = matcherOut.length; - while (i--) { - if ((elem = matcherOut[i]) && - (temp = postFinder ? indexOf(seed, elem) : preMap[i]) > -1) { - - seed[temp] = !(results[temp] = elem); - } - } - } - - // Add elements to results, through postFinder if defined - } else { - matcherOut = condense( - matcherOut === results ? - matcherOut.splice(preexisting, matcherOut.length) : - matcherOut - ); - if (postFinder) { - postFinder(null, results, matcherOut, xml); - } else { - push.apply(results, matcherOut); - } - } - }); - } - - function matcherFromTokens(tokens) { - var checkContext, matcher, j, - len = tokens.length, - leadingRelative = Expr.relative[tokens[0].type], - implicitRelative = leadingRelative || Expr.relative[" "], - i = leadingRelative ? 1 : 0, - - // The foundational matcher ensures that elements are reachable from top-level context(s) - matchContext = addCombinator(function (elem) { - return elem === checkContext; - }, implicitRelative, true), - matchAnyContext = addCombinator(function (elem) { - return indexOf(checkContext, elem) > -1; - }, implicitRelative, true), - matchers = [function (elem, context, xml) { - var ret = (!leadingRelative && (xml || context !== outermostContext)) || ( - (checkContext = context).nodeType ? - matchContext(elem, context, xml) : - matchAnyContext(elem, context, xml)); - // Avoid hanging onto element (issue #299) - checkContext = null; - return ret; - }]; - - for (; i < len; i++) { - if ((matcher = Expr.relative[tokens[i].type])) { - matchers = [addCombinator(elementMatcher(matchers), matcher)]; - } else { - matcher = Expr.filter[tokens[i].type].apply(null, tokens[i].matches); - - // Return special upon seeing a positional matcher - if (matcher[expando]) { - // Find the next relative operator (if any) for proper handling - j = ++i; - for (; j < len; j++) { - if (Expr.relative[tokens[j].type]) { - break; - } - } - return setMatcher( - i > 1 && elementMatcher(matchers), - i > 1 && toSelector( - // If the preceding token was a descendant combinator, insert an implicit any-element `*` - tokens.slice(0, i - 1).concat({value: tokens[i - 2].type === " " ? "*" : ""}) - ).replace(rtrim, "$1"), - matcher, - i < j && matcherFromTokens(tokens.slice(i, j)), - j < len && matcherFromTokens((tokens = tokens.slice(j))), - j < len && toSelector(tokens) - ); - } - matchers.push(matcher); - } - } - - return elementMatcher(matchers); - } - - function matcherFromGroupMatchers(elementMatchers, setMatchers) { - var bySet = setMatchers.length > 0, - byElement = elementMatchers.length > 0, - superMatcher = function (seed, context, xml, results, outermost) { - var elem, j, matcher, - matchedCount = 0, - i = "0", - unmatched = seed && [], - setMatched = [], - contextBackup = outermostContext, - // We must always have either seed elements or outermost context - elems = seed || byElement && Expr.find["TAG"]("*", outermost), - // Use integer dirruns iff this is the outermost matcher - dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1), - len = elems.length; - - if (outermost) { - outermostContext = context === document || context || outermost; - } - - // Add elements passing elementMatchers directly to results - // Support: IE<9, Safari - // Tolerate NodeList properties (IE: "length"; Safari: ) matching elements by id - for (; i !== len && (elem = elems[i]) != null; i++) { - if (byElement && elem) { - j = 0; - if (!context && elem.ownerDocument !== document) { - setDocument(elem); - xml = !documentIsHTML; - } - while ((matcher = elementMatchers[j++])) { - if (matcher(elem, context || document, xml)) { - results.push(elem); - break; - } - } - if (outermost) { - dirruns = dirrunsUnique; - } - } - - // Track unmatched elements for set filters - if (bySet) { - // They will have gone through all possible matchers - if ((elem = !matcher && elem)) { - matchedCount--; - } - - // Lengthen the array for every element, matched or not - if (seed) { - unmatched.push(elem); - } - } - } - - // `i` is now the count of elements visited above, and adding it to `matchedCount` - // makes the latter nonnegative. - matchedCount += i; - - // Apply set filters to unmatched elements - // NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount` - // equals `i`), unless we didn't visit _any_ elements in the above loop because we have - // no element matchers and no seed. - // Incrementing an initially-string "0" `i` allows `i` to remain a string only in that - // case, which will result in a "00" `matchedCount` that differs from `i` but is also - // numerically zero. - if (bySet && i !== matchedCount) { - j = 0; - while ((matcher = setMatchers[j++])) { - matcher(unmatched, setMatched, context, xml); - } - - if (seed) { - // Reintegrate element matches to eliminate the need for sorting - if (matchedCount > 0) { - while (i--) { - if (!(unmatched[i] || setMatched[i])) { - setMatched[i] = pop.call(results); - } - } - } - - // Discard index placeholder values to get only actual matches - setMatched = condense(setMatched); - } - - // Add matches to results - push.apply(results, setMatched); - - // Seedless set matches succeeding multiple successful matchers stipulate sorting - if (outermost && !seed && setMatched.length > 0 && - (matchedCount + setMatchers.length) > 1) { - - Sizzle.uniqueSort(results); - } - } - - // Override manipulation of globals by nested matchers - if (outermost) { - dirruns = dirrunsUnique; - outermostContext = contextBackup; - } - - return unmatched; - }; - - return bySet ? - markFunction(superMatcher) : - superMatcher; - } - - compile = Sizzle.compile = function (selector, match /* Internal Use Only */) { - var i, - setMatchers = [], - elementMatchers = [], - cached = compilerCache[selector + " "]; - - if (!cached) { - // Generate a function of recursive functions that can be used to check each element - if (!match) { - match = tokenize(selector); - } - i = match.length; - while (i--) { - cached = matcherFromTokens(match[i]); - if (cached[expando]) { - setMatchers.push(cached); - } else { - elementMatchers.push(cached); - } - } - - // Cache the compiled function - cached = compilerCache(selector, matcherFromGroupMatchers(elementMatchers, setMatchers)); - - // Save selector and tokenization - cached.selector = selector; - } - return cached; - }; - - /** - * A low-level selection function that works with Sizzle's compiled - * selector functions - * @param {String|Function} selector A selector or a pre-compiled - * selector function built with Sizzle.compile - * @param {Element} context - * @param {Array} [results] - * @param {Array} [seed] A set of elements to match against - */ - select = Sizzle.select = function (selector, context, results, seed) { - var i, tokens, token, type, find, - compiled = typeof selector === "function" && selector, - match = !seed && tokenize((selector = compiled.selector || selector)); - - results = results || []; - - // Try to minimize operations if there is only one selector in the list and no seed - // (the latter of which guarantees us context) - if (match.length === 1) { - - // Reduce context if the leading compound selector is an ID - tokens = match[0] = match[0].slice(0); - if (tokens.length > 2 && (token = tokens[0]).type === "ID" && - context.nodeType === 9 && documentIsHTML && Expr.relative[tokens[1].type]) { - - context = (Expr.find["ID"](token.matches[0].replace(runescape, funescape), context) || [])[0]; - if (!context) { - return results; - - // Precompiled matchers will still verify ancestry, so step up a level - } else if (compiled) { - context = context.parentNode; - } - - selector = selector.slice(tokens.shift().value.length); - } - - // Fetch a seed set for right-to-left matching - i = matchExpr["needsContext"].test(selector) ? 0 : tokens.length; - while (i--) { - token = tokens[i]; - - // Abort if we hit a combinator - if (Expr.relative[(type = token.type)]) { - break; - } - if ((find = Expr.find[type])) { - // Search, expanding context for leading sibling combinators - if ((seed = find( - token.matches[0].replace(runescape, funescape), - rsibling.test(tokens[0].type) && testContext(context.parentNode) || context - ))) { - - // If seed is empty or no tokens remain, we can return early - tokens.splice(i, 1); - selector = seed.length && toSelector(tokens); - if (!selector) { - push.apply(results, seed); - return results; - } - - break; - } - } - } - } - - // Compile and execute a filtering function if one is not provided - // Provide `match` to avoid retokenization if we modified the selector above - (compiled || compile(selector, match))( - seed, - context, - !documentIsHTML, - results, - !context || rsibling.test(selector) && testContext(context.parentNode) || context - ); - return results; - }; - -// One-time assignments - -// Sort stability - support.sortStable = expando.split("").sort(sortOrder).join("") === expando; - -// Support: Chrome 14-35+ -// Always assume duplicates if they aren't passed to the comparison function - support.detectDuplicates = !!hasDuplicate; - -// Initialize against the default document - setDocument(); - - return Sizzle; - - })(window); - - -jQuery.find = Sizzle; -jQuery.expr = Sizzle.selectors; - -// Deprecated -jQuery.expr[":"] = jQuery.expr.pseudos; -jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort; -jQuery.text = Sizzle.getText; -jQuery.isXMLDoc = Sizzle.isXML; -jQuery.contains = Sizzle.contains; -jQuery.escapeSelector = Sizzle.escape; - - -var dir = function (elem, dir, until) { - var matched = [], - truncate = until !== undefined; - - while ((elem = elem[dir]) && elem.nodeType !== 9) { - if (elem.nodeType === 1) { - if (truncate && jQuery(elem).is(until)) { - break; - } - matched.push(elem); - } - } - return matched; -}; - - -var siblings = function (n, elem) { - var matched = []; - - for (; n; n = n.nextSibling) { - if (n.nodeType === 1 && n !== elem) { - matched.push(n); - } - } - - return matched; -}; - - -var rneedsContext = jQuery.expr.match.needsContext; - - -function nodeName(elem, name) { - - return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); - -} -var rsingleTag = (/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i); - - -// Implement the identical functionality for filter and not -function winnow(elements, qualifier, not) { - if (isFunction(qualifier)) { - return jQuery.grep(elements, function (elem, i) { - return !!qualifier.call(elem, i, elem) !== not; - }); - } - - // Single element - if (qualifier.nodeType) { - return jQuery.grep(elements, function (elem) { - return (elem === qualifier) !== not; - }); - } - - // Arraylike of elements (jQuery, arguments, Array) - if (typeof qualifier !== "string") { - return jQuery.grep(elements, function (elem) { - return (indexOf.call(qualifier, elem) > -1) !== not; - }); - } - - // Filtered directly for both simple and complex selectors - return jQuery.filter(qualifier, elements, not); -} - -jQuery.filter = function (expr, elems, not) { - var elem = elems[0]; - - if (not) { - expr = ":not(" + expr + ")"; - } - - if (elems.length === 1 && elem.nodeType === 1) { - return jQuery.find.matchesSelector(elem, expr) ? [elem] : []; - } - - return jQuery.find.matches(expr, jQuery.grep(elems, function (elem) { - return elem.nodeType === 1; - })); -}; - -jQuery.fn.extend({ - find: function (selector) { - var i, ret, - len = this.length, - self = this; - - if (typeof selector !== "string") { - return this.pushStack(jQuery(selector).filter(function () { - for (i = 0; i < len; i++) { - if (jQuery.contains(self[i], this)) { - return true; - } - } - })); - } - - ret = this.pushStack([]); - - for (i = 0; i < len; i++) { - jQuery.find(selector, self[i], ret); - } - - return len > 1 ? jQuery.uniqueSort(ret) : ret; - }, - filter: function (selector) { - return this.pushStack(winnow(this, selector || [], false)); - }, - not: function (selector) { - return this.pushStack(winnow(this, selector || [], true)); - }, - is: function (selector) { - return !!winnow( - this, - - // If this is a positional/relative selector, check membership in the returned set - // so $("p:first").is("p:last") won't return true for a doc with two "p". - typeof selector === "string" && rneedsContext.test(selector) ? - jQuery(selector) : - selector || [], - false - ).length; - } -}); - - -// Initialize a jQuery object - - -// A central reference to the root jQuery(document) -var rootjQuery, - - // A simple way to check for HTML strings - // Prioritize #id over to avoid XSS via location.hash (#9521) - // Strict HTML recognition (#11290: must start with <) - // Shortcut simple #id case for speed - rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/, - - init$2 = jQuery.fn.init = function (selector, context, root) { - var match, elem; - - // HANDLE: $(""), $(null), $(undefined), $(false) - if (!selector) { - return this; - } - - // Method init() accepts an alternate rootjQuery - // so migrate can support jQuery.sub (gh-2101) - root = root || rootjQuery; - - // Handle HTML strings - if (typeof selector === "string") { - if (selector[0] === "<" && - selector[selector.length - 1] === ">" && - selector.length >= 3) { - - // Assume that strings that start and end with <> are HTML and skip the regex check - match = [null, selector, null]; - - } else { - match = rquickExpr.exec(selector); - } - - // Match html or make sure no context is specified for #id - if (match && (match[1] || !context)) { - - // HANDLE: $(html) -> $(array) - if (match[1]) { - context = context instanceof jQuery ? context[0] : context; - - // Option to run scripts is true for back-compat - // Intentionally let the error be thrown if parseHTML is not present - jQuery.merge(this, jQuery.parseHTML( - match[1], - context && context.nodeType ? context.ownerDocument || context : document$1, - true - )); - - // HANDLE: $(html, props) - if (rsingleTag.test(match[1]) && jQuery.isPlainObject(context)) { - for (match in context) { - - // Properties of context are called as methods if possible - if (isFunction(this[match])) { - this[match](context[match]); - - // ...and otherwise set as attributes - } else { - this.attr(match, context[match]); - } - } - } - - return this; - - // HANDLE: $(#id) - } else { - elem = document$1.getElementById(match[2]); - - if (elem) { - - // Inject the element directly into the jQuery object - this[0] = elem; - this.length = 1; - } - return this; - } - - // HANDLE: $(expr, $(...)) - } else if (!context || context.jquery) { - return (context || root).find(selector); - - // HANDLE: $(expr, context) - // (which is just equivalent to: $(context).find(expr) - } else { - return this.constructor(context).find(selector); - } - - // HANDLE: $(DOMElement) - } else if (selector.nodeType) { - this[0] = selector; - this.length = 1; - return this; - - // HANDLE: $(function) - // Shortcut for document ready - } else if (isFunction(selector)) { - return root.ready !== undefined ? - root.ready(selector) : - - // Execute immediately if ready is not present - selector(jQuery); - } - - return jQuery.makeArray(selector, this); - }; - -// Give the init function the jQuery prototype for later instantiation -init$2.prototype = jQuery.fn; - -// Initialize central reference -rootjQuery = jQuery(document$1); - - -var rparentsprev = /^(?:parents|prev(?:Until|All))/, - - // Methods guaranteed to produce a unique set when starting from a unique set - guaranteedUnique = { - children: true, - contents: true, - next: true, - prev: true - }; - -jQuery.fn.extend({ - has: function (target) { - var targets = jQuery(target, this), - l = targets.length; - - return this.filter(function () { - var i = 0; - for (; i < l; i++) { - if (jQuery.contains(this, targets[i])) { - return true; - } - } - }); - }, - - closest: function (selectors, context) { - var cur, - i = 0, - l = this.length, - matched = [], - targets = typeof selectors !== "string" && jQuery(selectors); - - // Positional selectors never match, since there's no _selection_ context - if (!rneedsContext.test(selectors)) { - for (; i < l; i++) { - for (cur = this[i]; cur && cur !== context; cur = cur.parentNode) { - - // Always skip document fragments - if (cur.nodeType < 11 && (targets ? - targets.index(cur) > -1 : - - // Don't pass non-elements to Sizzle - cur.nodeType === 1 && - jQuery.find.matchesSelector(cur, selectors))) { - - matched.push(cur); - break; - } - } - } - } - - return this.pushStack(matched.length > 1 ? jQuery.uniqueSort(matched) : matched); - }, - - // Determine the position of an element within the set - index: function (elem) { - - // No argument, return index in parent - if (!elem) { - return (this[0] && this[0].parentNode) ? this.first().prevAll().length : -1; - } - - // Index in selector - if (typeof elem === "string") { - return indexOf.call(jQuery(elem), this[0]); - } - - // Locate the position of the desired element - return indexOf.call(this, - - // If it receives a jQuery object, the first element is used - elem.jquery ? elem[0] : elem - ); - }, - - add: function (selector, context) { - return this.pushStack( - jQuery.uniqueSort( - jQuery.merge(this.get(), jQuery(selector, context)) - ) - ); - }, - - addBack: function (selector) { - return this.add(selector == null ? - this.prevObject : this.prevObject.filter(selector) - ); - } -}); - -function sibling(cur, dir) { - while ((cur = cur[dir]) && cur.nodeType !== 1) { - } - return cur; -} - -jQuery.each({ - parent: function (elem) { - var parent = elem.parentNode; - return parent && parent.nodeType !== 11 ? parent : null; - }, - parents: function (elem) { - return dir(elem, "parentNode"); - }, - parentsUntil: function (elem, i, until) { - return dir(elem, "parentNode", until); - }, - next: function (elem) { - return sibling(elem, "nextSibling"); - }, - prev: function (elem) { - return sibling(elem, "previousSibling"); - }, - nextAll: function (elem) { - return dir(elem, "nextSibling"); - }, - prevAll: function (elem) { - return dir(elem, "previousSibling"); - }, - nextUntil: function (elem, i, until) { - return dir(elem, "nextSibling", until); - }, - prevUntil: function (elem, i, until) { - return dir(elem, "previousSibling", until); - }, - siblings: function (elem) { - return siblings((elem.parentNode || {}).firstChild, elem); - }, - children: function (elem) { - return siblings(elem.firstChild); - }, - contents: function (elem) { - if (nodeName(elem, "iframe")) { - return elem.contentDocument; - } - - // Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only - // Treat the template element as a regular one in browsers that - // don't support it. - if (nodeName(elem, "template")) { - elem = elem.content || elem; - } - - return jQuery.merge([], elem.childNodes); - } -}, function (name, fn) { - jQuery.fn[name] = function (until, selector) { - var matched = jQuery.map(this, fn, until); - - if (name.slice(-5) !== "Until") { - selector = until; - } - - if (selector && typeof selector === "string") { - matched = jQuery.filter(selector, matched); - } - - if (this.length > 1) { - - // Remove duplicates - if (!guaranteedUnique[name]) { - jQuery.uniqueSort(matched); - } - - // Reverse order for parents* and prev-derivatives - if (rparentsprev.test(name)) { - matched.reverse(); - } - } - - return this.pushStack(matched); - }; -}); -var rnothtmlwhite = (/[^\x20\t\r\n\f]+/g); - - -// Convert String-formatted options into Object-formatted ones -function createOptions(options) { - var object = {}; - jQuery.each(options.match(rnothtmlwhite) || [], function (_, flag) { - object[flag] = true; - }); - return object; -} - -/* - * Create a callback list using the following parameters: - * - * options: an optional list of space-separated options that will change how - * the callback list behaves or a more traditional option object - * - * By default a callback list will act like an event callback list and can be - * "fired" multiple times. - * - * Possible options: - * - * once: will ensure the callback list can only be fired once (like a Deferred) - * - * memory: will keep track of previous values and will call any callback added - * after the list has been fired right away with the latest "memorized" - * values (like a Deferred) - * - * unique: will ensure a callback can only be added once (no duplicate in the list) - * - * stopOnFalse: interrupt callings when a callback returns false - * - */ -jQuery.Callbacks = function (options) { - - // Convert options from String-formatted to Object-formatted if needed - // (we check in cache first) - options = typeof options === "string" ? - createOptions(options) : - jQuery.extend({}, options); - - var // Flag to know if list is currently firing - firing, - - // Last fire value for non-forgettable lists - memory, - - // Flag to know if list was already fired - fired, - - // Flag to prevent firing - locked, - - // Actual callback list - list = [], - - // Queue of execution data for repeatable lists - queue = [], - - // Index of currently firing callback (modified by add/remove as needed) - firingIndex = -1, - - // Fire callbacks - fire = function () { - - // Enforce single-firing - locked = locked || options.once; - - // Execute callbacks for all pending executions, - // respecting firingIndex overrides and runtime changes - fired = firing = true; - for (; queue.length; firingIndex = -1) { - memory = queue.shift(); - while (++firingIndex < list.length) { - - // Run callback and check for early termination - if (list[firingIndex].apply(memory[0], memory[1]) === false && - options.stopOnFalse) { - - // Jump to end and forget the data so .add doesn't re-fire - firingIndex = list.length; - memory = false; - } - } - } - - // Forget the data if we're done with it - if (!options.memory) { - memory = false; - } - - firing = false; - - // Clean up if we're done firing for good - if (locked) { - - // Keep an empty list if we have data for future add calls - if (memory) { - list = []; - - // Otherwise, this object is spent - } else { - list = ""; - } - } - }, - - // Actual Callbacks object - self = { - - // Add a callback or a collection of callbacks to the list - add: function () { - if (list) { - - // If we have memory from a past run, we should fire after adding - if (memory && !firing) { - firingIndex = list.length - 1; - queue.push(memory); - } - - (function add(args) { - jQuery.each(args, function (_, arg) { - if (isFunction(arg)) { - if (!options.unique || !self.has(arg)) { - list.push(arg); - } - } else if (arg && arg.length && toType(arg) !== "string") { - - // Inspect recursively - add(arg); - } - }); - })(arguments); - - if (memory && !firing) { - fire(); - } - } - return this; - }, - - // Remove a callback from the list - remove: function () { - jQuery.each(arguments, function (_, arg) { - var index; - while ((index = jQuery.inArray(arg, list, index)) > -1) { - list.splice(index, 1); - - // Handle firing indexes - if (index <= firingIndex) { - firingIndex--; - } - } - }); - return this; - }, - - // Check if a given callback is in the list. - // If no argument is given, return whether or not list has callbacks attached. - has: function (fn) { - return fn ? - jQuery.inArray(fn, list) > -1 : - list.length > 0; - }, - - // Remove all callbacks from the list - empty: function () { - if (list) { - list = []; - } - return this; - }, - - // Disable .fire and .add - // Abort any current/pending executions - // Clear all callbacks and values - disable: function () { - locked = queue = []; - list = memory = ""; - return this; - }, - disabled: function () { - return !list; - }, - - // Disable .fire - // Also disable .add unless we have memory (since it would have no effect) - // Abort any pending executions - lock: function () { - locked = queue = []; - if (!memory && !firing) { - list = memory = ""; - } - return this; - }, - locked: function () { - return !!locked; - }, - - // Call all callbacks with the given context and arguments - fireWith: function (context, args) { - if (!locked) { - args = args || []; - args = [context, args.slice ? args.slice() : args]; - queue.push(args); - if (!firing) { - fire(); - } - } - return this; - }, - - // Call all the callbacks with the given arguments - fire: function () { - self.fireWith(this, arguments); - return this; - }, - - // To know if the callbacks have already been called at least once - fired: function () { - return !!fired; - } - }; - - return self; -}; - - -function Identity(v) { - return v; -} - -function Thrower(ex) { - throw ex; -} - -function adoptValue(value, resolve, reject, noValue) { - var method; - - try { - - // Check for promise aspect first to privilege synchronous behavior - if (value && isFunction((method = value.promise))) { - method.call(value).done(resolve).fail(reject); - - // Other thenables - } else if (value && isFunction((method = value.then))) { - method.call(value, resolve, reject); - - // Other non-thenables - } else { - - // Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer: - // * false: [ value ].slice( 0 ) => resolve( value ) - // * true: [ value ].slice( 1 ) => resolve() - resolve.apply(undefined, [value].slice(noValue)); - } - - // For Promises/A+, convert exceptions into rejections - // Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in - // Deferred#then to conditionally suppress rejection. - } catch (value) { - - // Support: Android 4.0 only - // Strict mode functions invoked without .call/.apply get global-object context - reject.apply(undefined, [value]); - } -} - -jQuery.extend({ - - Deferred: function (func) { - var tuples = [ - - // action, add listener, callbacks, - // ... .then handlers, argument index, [final state] - ["notify", "progress", jQuery.Callbacks("memory"), - jQuery.Callbacks("memory"), 2], - ["resolve", "done", jQuery.Callbacks("once memory"), - jQuery.Callbacks("once memory"), 0, "resolved"], - ["reject", "fail", jQuery.Callbacks("once memory"), - jQuery.Callbacks("once memory"), 1, "rejected"] - ], - state = "pending", - promise = { - state: function () { - return state; - }, - always: function () { - deferred.done(arguments).fail(arguments); - return this; - }, - "catch": function (fn) { - return promise.then(null, fn); - }, - - // Keep pipe for back-compat - pipe: function ( /* fnDone, fnFail, fnProgress */) { - var fns = arguments; - - return jQuery.Deferred(function (newDefer) { - jQuery.each(tuples, function (i, tuple) { - - // Map tuples (progress, done, fail) to arguments (done, fail, progress) - var fn = isFunction(fns[tuple[4]]) && fns[tuple[4]]; - - // deferred.progress(function() { bind to newDefer or newDefer.notify }) - // deferred.done(function() { bind to newDefer or newDefer.resolve }) - // deferred.fail(function() { bind to newDefer or newDefer.reject }) - deferred[tuple[1]](function () { - var returned = fn && fn.apply(this, arguments); - if (returned && isFunction(returned.promise)) { - returned.promise() - .progress(newDefer.notify) - .done(newDefer.resolve) - .fail(newDefer.reject); - } else { - newDefer[tuple[0] + "With"]( - this, - fn ? [returned] : arguments - ); - } - }); - }); - fns = null; - }).promise(); - }, - then: function (onFulfilled, onRejected, onProgress) { - var maxDepth = 0; - - function resolve(depth, deferred, handler, special) { - return function () { - var that = this, - args = arguments, - mightThrow = function () { - var returned, then; - - // Support: Promises/A+ section 2.3.3.3.3 - // https://promisesaplus.com/#point-59 - // Ignore double-resolution attempts - if (depth < maxDepth) { - return; - } - - returned = handler.apply(that, args); - - // Support: Promises/A+ section 2.3.1 - // https://promisesaplus.com/#point-48 - if (returned === deferred.promise()) { - throw new TypeError("Thenable self-resolution"); - } - - // Support: Promises/A+ sections 2.3.3.1, 3.5 - // https://promisesaplus.com/#point-54 - // https://promisesaplus.com/#point-75 - // Retrieve `then` only once - then = returned && - - // Support: Promises/A+ section 2.3.4 - // https://promisesaplus.com/#point-64 - // Only check objects and functions for thenability - (typeof returned === "object" || - typeof returned === "function") && - returned.then; - - // Handle a returned thenable - if (isFunction(then)) { - - // Special processors (notify) just wait for resolution - if (special) { - then.call( - returned, - resolve(maxDepth, deferred, Identity, special), - resolve(maxDepth, deferred, Thrower, special) - ); - - // Normal processors (resolve) also hook into progress - } else { - - // ...and disregard older resolution values - maxDepth++; - - then.call( - returned, - resolve(maxDepth, deferred, Identity, special), - resolve(maxDepth, deferred, Thrower, special), - resolve(maxDepth, deferred, Identity, - deferred.notifyWith) - ); - } - - // Handle all other returned values - } else { - - // Only substitute handlers pass on context - // and multiple values (non-spec behavior) - if (handler !== Identity) { - that = undefined; - args = [returned]; - } - - // Process the value(s) - // Default process is resolve - (special || deferred.resolveWith)(that, args); - } - }, - - // Only normal processors (resolve) catch and reject exceptions - process = special ? - mightThrow : - function () { - try { - mightThrow(); - } catch (e) { - - if (jQuery.Deferred.exceptionHook) { - jQuery.Deferred.exceptionHook(e, - process.stackTrace); - } - - // Support: Promises/A+ section 2.3.3.3.4.1 - // https://promisesaplus.com/#point-61 - // Ignore post-resolution exceptions - if (depth + 1 >= maxDepth) { - - // Only substitute handlers pass on context - // and multiple values (non-spec behavior) - if (handler !== Thrower) { - that = undefined; - args = [e]; - } - - deferred.rejectWith(that, args); - } - } - }; - - // Support: Promises/A+ section 2.3.3.3.1 - // https://promisesaplus.com/#point-57 - // Re-resolve promises immediately to dodge false rejection from - // subsequent errors - if (depth) { - process(); - } else { - - // Call an optional hook to record the stack, in case of exception - // since it's otherwise lost when execution goes async - if (jQuery.Deferred.getStackHook) { - process.stackTrace = jQuery.Deferred.getStackHook(); - } - window.setTimeout(process); - } - }; - } - - return jQuery.Deferred(function (newDefer) { - - // progress_handlers.add( ... ) - tuples[0][3].add( - resolve( - 0, - newDefer, - isFunction(onProgress) ? - onProgress : - Identity, - newDefer.notifyWith - ) - ); - - // fulfilled_handlers.add( ... ) - tuples[1][3].add( - resolve( - 0, - newDefer, - isFunction(onFulfilled) ? - onFulfilled : - Identity - ) - ); - - // rejected_handlers.add( ... ) - tuples[2][3].add( - resolve( - 0, - newDefer, - isFunction(onRejected) ? - onRejected : - Thrower - ) - ); - }).promise(); - }, - - // Get a promise for this deferred - // If obj is provided, the promise aspect is added to the object - promise: function (obj) { - return obj != null ? jQuery.extend(obj, promise) : promise; - } - }, - deferred = {}; - - // Add list-specific methods - jQuery.each(tuples, function (i, tuple) { - var list = tuple[2], - stateString = tuple[5]; - - // promise.progress = list.add - // promise.done = list.add - // promise.fail = list.add - promise[tuple[1]] = list.add; - - // Handle state - if (stateString) { - list.add( - function () { - - // state = "resolved" (i.e., fulfilled) - // state = "rejected" - state = stateString; - }, - - // rejected_callbacks.disable - // fulfilled_callbacks.disable - tuples[3 - i][2].disable, - - // rejected_handlers.disable - // fulfilled_handlers.disable - tuples[3 - i][3].disable, - - // progress_callbacks.lock - tuples[0][2].lock, - - // progress_handlers.lock - tuples[0][3].lock - ); - } - - // progress_handlers.fire - // fulfilled_handlers.fire - // rejected_handlers.fire - list.add(tuple[3].fire); - - // deferred.notify = function() { deferred.notifyWith(...) } - // deferred.resolve = function() { deferred.resolveWith(...) } - // deferred.reject = function() { deferred.rejectWith(...) } - deferred[tuple[0]] = function () { - deferred[tuple[0] + "With"](this === deferred ? undefined : this, arguments); - return this; - }; - - // deferred.notifyWith = list.fireWith - // deferred.resolveWith = list.fireWith - // deferred.rejectWith = list.fireWith - deferred[tuple[0] + "With"] = list.fireWith; - }); - - // Make the deferred a promise - promise.promise(deferred); - - // Call given func if any - if (func) { - func.call(deferred, deferred); - } - - // All done! - return deferred; - }, - - // Deferred helper - when: function (singleValue) { - var - - // count of uncompleted subordinates - remaining = arguments.length, - - // count of unprocessed arguments - i = remaining, - - // subordinate fulfillment data - resolveContexts = Array(i), - resolveValues = slice.call(arguments), - - // the master Deferred - master = jQuery.Deferred(), - - // subordinate callback factory - updateFunc = function (i) { - return function (value) { - resolveContexts[i] = this; - resolveValues[i] = arguments.length > 1 ? slice.call(arguments) : value; - if (!(--remaining)) { - master.resolveWith(resolveContexts, resolveValues); - } - }; - }; - - // Single- and empty arguments are adopted like Promise.resolve - if (remaining <= 1) { - adoptValue(singleValue, master.done(updateFunc(i)).resolve, master.reject, - !remaining); - - // Use .then() to unwrap secondary thenables (cf. gh-3000) - if (master.state() === "pending" || - isFunction(resolveValues[i] && resolveValues[i].then)) { - - return master.then(); - } - } - - // Multiple arguments are aggregated like Promise.all array elements - while (i--) { - adoptValue(resolveValues[i], updateFunc(i), master.reject); - } - - return master.promise(); - } -}); - - -// These usually indicate a programmer mistake during development, -// warn about them ASAP rather than swallowing them by default. -var rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/; - -jQuery.Deferred.exceptionHook = function (error, stack) { - - // Support: IE 8 - 9 only - // Console exists when dev tools are open, which can happen at any time - if (window.console && window.console.warn && error && rerrorNames.test(error.name)) { - window.console.warn("jQuery.Deferred exception: " + error.message, error.stack, stack); - } -}; - - -jQuery.readyException = function (error) { - window.setTimeout(function () { - throw error; - }); -}; - - -// The deferred used on DOM ready -var readyList = jQuery.Deferred(); - -jQuery.fn.ready = function (fn) { - - readyList - .then(fn) - - // Wrap jQuery.readyException in a function so that the lookup - // happens at the time of error handling instead of callback - // registration. - .catch(function (error) { - jQuery.readyException(error); - }); - - return this; -}; - -jQuery.extend({ - - // Is the DOM ready to be used? Set to true once it occurs. - isReady: false, - - // A counter to track how many items to wait for before - // the ready event fires. See #6781 - readyWait: 1, - - // Handle when the DOM is ready - ready: function (wait) { - - // Abort if there are pending holds or we're already ready - if (wait === true ? --jQuery.readyWait : jQuery.isReady) { - return; - } - - // Remember that the DOM is ready - jQuery.isReady = true; - - // If a normal DOM Ready event fired, decrement, and wait if need be - if (wait !== true && --jQuery.readyWait > 0) { - return; - } - - // If there are functions bound, to execute - readyList.resolveWith(document$1, [jQuery]); - } -}); - -jQuery.ready.then = readyList.then; - -// The ready event handler and self cleanup method -function completed() { - document$1.removeEventListener("DOMContentLoaded", completed); - window.removeEventListener("load", completed); - jQuery.ready(); -} - -// Catch cases where $(document).ready() is called -// after the browser event has already occurred. -// Support: IE <=9 - 10 only -// Older IE sometimes signals "interactive" too soon -if (document$1.readyState === "complete" || - (document$1.readyState !== "loading" && !document$1.documentElement.doScroll)) { - - // Handle it asynchronously to allow scripts the opportunity to delay ready - window.setTimeout(jQuery.ready); - -} else { - - // Use the handy event callback - document$1.addEventListener("DOMContentLoaded", completed); - - // A fallback to window.onload, that will always work - window.addEventListener("load", completed); -} - - -// Multifunctional method to get and set values of a collection -// The value/s can optionally be executed if it's a function -var access = function (elems, fn, key, value, chainable, emptyGet, raw) { - var i = 0, - len = elems.length, - bulk = key == null; - - // Sets many values - if (toType(key) === "object") { - chainable = true; - for (i in key) { - access(elems, fn, i, key[i], true, emptyGet, raw); - } - - // Sets one value - } else if (value !== undefined) { - chainable = true; - - if (!isFunction(value)) { - raw = true; - } - - if (bulk) { - - // Bulk operations run against the entire set - if (raw) { - fn.call(elems, value); - fn = null; - - // ...except when executing function values - } else { - bulk = fn; - fn = function (elem, key, value) { - return bulk.call(jQuery(elem), value); - }; - } - } - - if (fn) { - for (; i < len; i++) { - fn( - elems[i], key, raw ? - value : - value.call(elems[i], i, fn(elems[i], key)) - ); - } - } - } - - if (chainable) { - return elems; - } - - // Gets - if (bulk) { - return fn.call(elems); - } - - return len ? fn(elems[0], key) : emptyGet; -}; - - -// Matches dashed string for camelizing -var rmsPrefix = /^-ms-/, - rdashAlpha = /-([a-z])/g; - -// Used by camelCase as callback to replace() -function fcamelCase(all, letter) { - return letter.toUpperCase(); -} - -// Convert dashed to camelCase; used by the css and data modules -// Support: IE <=9 - 11, Edge 12 - 15 -// Microsoft forgot to hump their vendor prefix (#9572) -function camelCase(string) { - return string.replace(rmsPrefix, "ms-").replace(rdashAlpha, fcamelCase); -} - -var acceptData = function (owner) { - - // Accepts only: - // - Node - // - Node.ELEMENT_NODE - // - Node.DOCUMENT_NODE - // - Object - // - Any - return owner.nodeType === 1 || owner.nodeType === 9 || !(+owner.nodeType); -}; - - -function Data() { - this.expando = jQuery.expando + Data.uid++; -} - -Data.uid = 1; - -Data.prototype = { - - cache: function (owner) { - - // Check if the owner object already has a cache - var value = owner[this.expando]; - - // If not, create one - if (!value) { - value = {}; - - // We can accept data for non-element nodes in modern browsers, - // but we should not, see #8335. - // Always return an empty object. - if (acceptData(owner)) { - - // If it is a node unlikely to be stringify-ed or looped over - // use plain assignment - if (owner.nodeType) { - owner[this.expando] = value; - - // Otherwise secure it in a non-enumerable property - // configurable must be true to allow the property to be - // deleted when data is removed - } else { - Object.defineProperty(owner, this.expando, { - value: value, - configurable: true - }); - } - } - } - - return value; - }, - set: function (owner, data, value) { - var prop, - cache = this.cache(owner); - - // Handle: [ owner, key, value ] args - // Always use camelCase key (gh-2257) - if (typeof data === "string") { - cache[camelCase(data)] = value; - - // Handle: [ owner, { properties } ] args - } else { - - // Copy the properties one-by-one to the cache object - for (prop in data) { - cache[camelCase(prop)] = data[prop]; - } - } - return cache; - }, - get: function (owner, key) { - return key === undefined ? - this.cache(owner) : - - // Always use camelCase key (gh-2257) - owner[this.expando] && owner[this.expando][camelCase(key)]; - }, - access: function (owner, key, value) { - - // In cases where either: - // - // 1. No key was specified - // 2. A string key was specified, but no value provided - // - // Take the "read" path and allow the get method to determine - // which value to return, respectively either: - // - // 1. The entire cache object - // 2. The data stored at the key - // - if (key === undefined || - ((key && typeof key === "string") && value === undefined)) { - - return this.get(owner, key); - } - - // When the key is not a string, or both a key and value - // are specified, set or extend (existing objects) with either: - // - // 1. An object of properties - // 2. A key and value - // - this.set(owner, key, value); - - // Since the "set" path can have two possible entry points - // return the expected data based on which path was taken[*] - return value !== undefined ? value : key; - }, - remove: function (owner, key) { - var i, - cache = owner[this.expando]; - - if (cache === undefined) { - return; - } - - if (key !== undefined) { - - // Support array or space separated string of keys - if (Array.isArray(key)) { - - // If key is an array of keys... - // We always set camelCase keys, so remove that. - key = key.map(camelCase); - } else { - key = camelCase(key); - - // If a key with the spaces exists, use it. - // Otherwise, create an array by matching non-whitespace - key = key in cache ? - [key] : - (key.match(rnothtmlwhite) || []); - } - - i = key.length; - - while (i--) { - delete cache[key[i]]; - } - } - - // Remove the expando if there's no more data - if (key === undefined || jQuery.isEmptyObject(cache)) { - - // Support: Chrome <=35 - 45 - // Webkit & Blink performance suffers when deleting properties - // from DOM nodes, so set to undefined instead - // https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted) - if (owner.nodeType) { - owner[this.expando] = undefined; - } else { - delete owner[this.expando]; - } - } - }, - hasData: function (owner) { - var cache = owner[this.expando]; - return cache !== undefined && !jQuery.isEmptyObject(cache); - } -}; -var dataPriv = new Data(); - -var dataUser = new Data(); - - -// Implementation Summary -// -// 1. Enforce API surface and semantic compatibility with 1.9.x branch -// 2. Improve the module's maintainability by reducing the storage -// paths to a single mechanism. -// 3. Use the same single mechanism to support "private" and "user" data. -// 4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData) -// 5. Avoid exposing implementation details on user objects (eg. expando properties) -// 6. Provide a clear path for implementation upgrade to WeakMap in 2014 - -var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, - rmultiDash = /[A-Z]/g; - -function getData(data) { - if (data === "true") { - return true; - } - - if (data === "false") { - return false; - } - - if (data === "null") { - return null; - } - - // Only convert to a number if it doesn't change the string - if (data === +data + "") { - return +data; - } - - if (rbrace.test(data)) { - return JSON.parse(data); - } - - return data; -} - -function dataAttr(elem, key, data) { - var name; - - // If nothing was found internally, try to fetch any - // data from the HTML5 data-* attribute - if (data === undefined && elem.nodeType === 1) { - name = "data-" + key.replace(rmultiDash, "-$&").toLowerCase(); - data = elem.getAttribute(name); - - if (typeof data === "string") { - try { - data = getData(data); - } catch (e) { - } - - // Make sure we set the data so it isn't changed later - dataUser.set(elem, key, data); - } else { - data = undefined; - } - } - return data; -} - -jQuery.extend({ - hasData: function (elem) { - return dataUser.hasData(elem) || dataPriv.hasData(elem); - }, - - data: function (elem, name, data) { - return dataUser.access(elem, name, data); - }, - - removeData: function (elem, name) { - dataUser.remove(elem, name); - }, - - // TODO: Now that all calls to _data and _removeData have been replaced - // with direct calls to dataPriv methods, these can be deprecated. - _data: function (elem, name, data) { - return dataPriv.access(elem, name, data); - }, - - _removeData: function (elem, name) { - dataPriv.remove(elem, name); - } -}); - -jQuery.fn.extend({ - data: function (key, value) { - var i, name, data, - elem = this[0], - attrs = elem && elem.attributes; - - // Gets all values - if (key === undefined) { - if (this.length) { - data = dataUser.get(elem); - - if (elem.nodeType === 1 && !dataPriv.get(elem, "hasDataAttrs")) { - i = attrs.length; - while (i--) { - - // Support: IE 11 only - // The attrs elements can be null (#14894) - if (attrs[i]) { - name = attrs[i].name; - if (name.indexOf("data-") === 0) { - name = camelCase(name.slice(5)); - dataAttr(elem, name, data[name]); - } - } - } - dataPriv.set(elem, "hasDataAttrs", true); - } - } - - return data; - } - - // Sets multiple values - if (typeof key === "object") { - return this.each(function () { - dataUser.set(this, key); - }); - } - - return access(this, function (value) { - var data; - - // The calling jQuery object (element matches) is not empty - // (and therefore has an element appears at this[ 0 ]) and the - // `value` parameter was not undefined. An empty jQuery object - // will result in `undefined` for elem = this[ 0 ] which will - // throw an exception if an attempt to read a data cache is made. - if (elem && value === undefined) { - - // Attempt to get data from the cache - // The key will always be camelCased in Data - data = dataUser.get(elem, key); - if (data !== undefined) { - return data; - } - - // Attempt to "discover" the data in - // HTML5 custom data-* attrs - data = dataAttr(elem, key); - if (data !== undefined) { - return data; - } - - // We tried really hard, but the data doesn't exist. - return; - } - - // Set the data... - this.each(function () { - - // We always store the camelCased key - dataUser.set(this, key, value); - }); - }, null, value, arguments.length > 1, null, true); - }, - - removeData: function (key) { - return this.each(function () { - dataUser.remove(this, key); - }); - } -}); - - -jQuery.extend({ - queue: function (elem, type, data) { - var queue; - - if (elem) { - type = (type || "fx") + "queue"; - queue = dataPriv.get(elem, type); - - // Speed up dequeue by getting out quickly if this is just a lookup - if (data) { - if (!queue || Array.isArray(data)) { - queue = dataPriv.access(elem, type, jQuery.makeArray(data)); - } else { - queue.push(data); - } - } - return queue || []; - } - }, - - dequeue: function (elem, type) { - type = type || "fx"; - - var queue = jQuery.queue(elem, type), - startLength = queue.length, - fn = queue.shift(), - hooks = jQuery._queueHooks(elem, type), - next = function () { - jQuery.dequeue(elem, type); - }; - - // If the fx queue is dequeued, always remove the progress sentinel - if (fn === "inprogress") { - fn = queue.shift(); - startLength--; - } - - if (fn) { - - // Add a progress sentinel to prevent the fx queue from being - // automatically dequeued - if (type === "fx") { - queue.unshift("inprogress"); - } - - // Clear up the last queue stop function - delete hooks.stop; - fn.call(elem, next, hooks); - } - - if (!startLength && hooks) { - hooks.empty.fire(); - } - }, - - // Not public - generate a queueHooks object, or return the current one - _queueHooks: function (elem, type) { - var key = type + "queueHooks"; - return dataPriv.get(elem, key) || dataPriv.access(elem, key, { - empty: jQuery.Callbacks("once memory").add(function () { - dataPriv.remove(elem, [type + "queue", key]); - }) - }); - } -}); - -jQuery.fn.extend({ - queue: function (type, data) { - var setter = 2; - - if (typeof type !== "string") { - data = type; - type = "fx"; - setter--; - } - - if (arguments.length < setter) { - return jQuery.queue(this[0], type); - } - - return data === undefined ? - this : - this.each(function () { - var queue = jQuery.queue(this, type, data); - - // Ensure a hooks for this queue - jQuery._queueHooks(this, type); - - if (type === "fx" && queue[0] !== "inprogress") { - jQuery.dequeue(this, type); - } - }); - }, - dequeue: function (type) { - return this.each(function () { - jQuery.dequeue(this, type); - }); - }, - clearQueue: function (type) { - return this.queue(type || "fx", []); - }, - - // Get a promise resolved when queues of a certain type - // are emptied (fx is the type by default) - promise: function (type, obj) { - var tmp, - count = 1, - defer = jQuery.Deferred(), - elements = this, - i = this.length, - resolve = function () { - if (!(--count)) { - defer.resolveWith(elements, [elements]); - } - }; - - if (typeof type !== "string") { - obj = type; - type = undefined; - } - type = type || "fx"; - - while (i--) { - tmp = dataPriv.get(elements[i], type + "queueHooks"); - if (tmp && tmp.empty) { - count++; - tmp.empty.add(resolve); - } - } - resolve(); - return defer.promise(obj); - } -}); -var pnum = (/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/).source; - -var rcssNum = new RegExp("^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i"); - - -var cssExpand = ["Top", "Right", "Bottom", "Left"]; - -var isHiddenWithinTree = function (elem, el) { - - // isHiddenWithinTree might be called from jQuery#filter function; - // in that case, element will be second argument - elem = el || elem; - - // Inline style trumps all - return elem.style.display === "none" || - elem.style.display === "" && - - // Otherwise, check computed style - // Support: Firefox <=43 - 45 - // Disconnected elements can have computed display: none, so first confirm that elem is - // in the document. - jQuery.contains(elem.ownerDocument, elem) && - - jQuery.css(elem, "display") === "none"; -}; - -var swap = function (elem, options, callback, args) { - var ret, name, - old = {}; - - // Remember the old values, and insert the new ones - for (name in options) { - old[name] = elem.style[name]; - elem.style[name] = options[name]; - } - - ret = callback.apply(elem, args || []); - - // Revert the old values - for (name in options) { - elem.style[name] = old[name]; - } - - return ret; -}; - - -function adjustCSS(elem, prop, valueParts, tween) { - var adjusted, scale, - maxIterations = 20, - currentValue = tween ? - function () { - return tween.cur(); - } : - function () { - return jQuery.css(elem, prop, ""); - }, - initial = currentValue(), - unit = valueParts && valueParts[3] || (jQuery.cssNumber[prop] ? "" : "px"), - - // Starting value computation is required for potential unit mismatches - initialInUnit = (jQuery.cssNumber[prop] || unit !== "px" && +initial) && - rcssNum.exec(jQuery.css(elem, prop)); - - if (initialInUnit && initialInUnit[3] !== unit) { - - // Support: Firefox <=54 - // Halve the iteration target value to prevent interference from CSS upper bounds (gh-2144) - initial = initial / 2; - - // Trust units reported by jQuery.css - unit = unit || initialInUnit[3]; - - // Iteratively approximate from a nonzero starting point - initialInUnit = +initial || 1; - - while (maxIterations--) { - - // Evaluate and update our best guess (doubling guesses that zero out). - // Finish if the scale equals or crosses 1 (making the old*new product non-positive). - jQuery.style(elem, prop, initialInUnit + unit); - if ((1 - scale) * (1 - (scale = currentValue() / initial || 0.5)) <= 0) { - maxIterations = 0; - } - initialInUnit = initialInUnit / scale; - - } - - initialInUnit = initialInUnit * 2; - jQuery.style(elem, prop, initialInUnit + unit); - - // Make sure we update the tween properties later on - valueParts = valueParts || []; - } - - if (valueParts) { - initialInUnit = +initialInUnit || +initial || 0; - - // Apply relative offset (+=/-=) if specified - adjusted = valueParts[1] ? - initialInUnit + (valueParts[1] + 1) * valueParts[2] : - +valueParts[2]; - if (tween) { - tween.unit = unit; - tween.start = initialInUnit; - tween.end = adjusted; - } - } - return adjusted; -} - - -var defaultDisplayMap = {}; - -function getDefaultDisplay(elem) { - var temp, - doc = elem.ownerDocument, - nodeName = elem.nodeName, - display = defaultDisplayMap[nodeName]; - - if (display) { - return display; - } - - temp = doc.body.appendChild(doc.createElement(nodeName)); - display = jQuery.css(temp, "display"); - - temp.parentNode.removeChild(temp); - - if (display === "none") { - display = "block"; - } - defaultDisplayMap[nodeName] = display; - - return display; -} - -function showHide(elements, show) { - var display, elem, - values = [], - index = 0, - length = elements.length; - - // Determine new display value for elements that need to change - for (; index < length; index++) { - elem = elements[index]; - if (!elem.style) { - continue; - } - - display = elem.style.display; - if (show) { - - // Since we force visibility upon cascade-hidden elements, an immediate (and slow) - // check is required in this first loop unless we have a nonempty display value (either - // inline or about-to-be-restored) - if (display === "none") { - values[index] = dataPriv.get(elem, "display") || null; - if (!values[index]) { - elem.style.display = ""; - } - } - if (elem.style.display === "" && isHiddenWithinTree(elem)) { - values[index] = getDefaultDisplay(elem); - } - } else { - if (display !== "none") { - values[index] = "none"; - - // Remember what we're overwriting - dataPriv.set(elem, "display", display); - } - } - } - - // Set the display of the elements in a second loop to avoid constant reflow - for (index = 0; index < length; index++) { - if (values[index] != null) { - elements[index].style.display = values[index]; - } - } - - return elements; -} - -jQuery.fn.extend({ - show: function () { - return showHide(this, true); - }, - hide: function () { - return showHide(this); - }, - toggle: function (state) { - if (typeof state === "boolean") { - return state ? this.show() : this.hide(); - } - - return this.each(function () { - if (isHiddenWithinTree(this)) { - jQuery(this).show(); - } else { - jQuery(this).hide(); - } - }); - } -}); -var rcheckableType = (/^(?:checkbox|radio)$/i); - -var rtagName = (/<([a-z][^\/\0>\x20\t\r\n\f]+)/i); - -var rscriptType = (/^$|^module$|\/(?:java|ecma)script/i); - - -// We have to close these tags to support XHTML (#13200) -var wrapMap = { - - // Support: IE <=9 only - option: [1, ""], - - // XHTML parsers do not magically insert elements in the - // same way that tag soup parsers do. So we cannot shorten - // this by omitting or other required elements. - thead: [1, "", "
"], - col: [2, "", "
"], - tr: [2, "", "
"], - td: [3, "", "
"], - - _default: [0, "", ""] -}; - -// Support: IE <=9 only -wrapMap.optgroup = wrapMap.option; - -wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; -wrapMap.th = wrapMap.td; - - -function getAll(context, tag) { - - // Support: IE <=9 - 11 only - // Use typeof to avoid zero-argument method invocation on host objects (#15151) - var ret; - - if (typeof context.getElementsByTagName !== "undefined") { - ret = context.getElementsByTagName(tag || "*"); - - } else if (typeof context.querySelectorAll !== "undefined") { - ret = context.querySelectorAll(tag || "*"); - - } else { - ret = []; - } - - if (tag === undefined || tag && nodeName(context, tag)) { - return jQuery.merge([context], ret); - } - - return ret; -} - - -// Mark scripts as having already been evaluated -function setGlobalEval(elems, refElements) { - var i = 0, - l = elems.length; - - for (; i < l; i++) { - dataPriv.set( - elems[i], - "globalEval", - !refElements || dataPriv.get(refElements[i], "globalEval") - ); - } -} - - -var rhtml = /<|&#?\w+;/; - -function buildFragment(elems, context, scripts, selection, ignored) { - var elem, tmp, tag, wrap, contains, j, - fragment = context.createDocumentFragment(), - nodes = [], - i = 0, - l = elems.length; - - for (; i < l; i++) { - elem = elems[i]; - - if (elem || elem === 0) { - - // Add nodes directly - if (toType(elem) === "object") { - - // Support: Android <=4.0 only, PhantomJS 1 only - // push.apply(_, arraylike) throws on ancient WebKit - jQuery.merge(nodes, elem.nodeType ? [elem] : elem); - - // Convert non-html into a text node - } else if (!rhtml.test(elem)) { - nodes.push(context.createTextNode(elem)); - - // Convert html into DOM nodes - } else { - tmp = tmp || fragment.appendChild(context.createElement("div")); - - // Deserialize a standard representation - tag = (rtagName.exec(elem) || ["", ""])[1].toLowerCase(); - wrap = wrapMap[tag] || wrapMap._default; - tmp.innerHTML = wrap[1] + jQuery.htmlPrefilter(elem) + wrap[2]; - - // Descend through wrappers to the right content - j = wrap[0]; - while (j--) { - tmp = tmp.lastChild; - } - - // Support: Android <=4.0 only, PhantomJS 1 only - // push.apply(_, arraylike) throws on ancient WebKit - jQuery.merge(nodes, tmp.childNodes); - - // Remember the top-level container - tmp = fragment.firstChild; - - // Ensure the created nodes are orphaned (#12392) - tmp.textContent = ""; - } - } - } - - // Remove wrapper from fragment - fragment.textContent = ""; - - i = 0; - while ((elem = nodes[i++])) { - - // Skip elements already in the context collection (trac-4087) - if (selection && jQuery.inArray(elem, selection) > -1) { - if (ignored) { - ignored.push(elem); - } - continue; - } - - contains = jQuery.contains(elem.ownerDocument, elem); - - // Append to fragment - tmp = getAll(fragment.appendChild(elem), "script"); - - // Preserve script evaluation history - if (contains) { - setGlobalEval(tmp); - } - - // Capture executables - if (scripts) { - j = 0; - while ((elem = tmp[j++])) { - if (rscriptType.test(elem.type || "")) { - scripts.push(elem); - } - } - } - } - - return fragment; -} - - -(function () { - var fragment = document$1.createDocumentFragment(), - div = fragment.appendChild(document$1.createElement("div")), - input = document$1.createElement("input"); - - // Support: Android 4.0 - 4.3 only - // Check state lost if the name is set (#11217) - // Support: Windows Web Apps (WWA) - // `name` and `type` must use .setAttribute for WWA (#14901) - input.setAttribute("type", "radio"); - input.setAttribute("checked", "checked"); - input.setAttribute("name", "t"); - - div.appendChild(input); - - // Support: Android <=4.1 only - // Older WebKit doesn't clone checked state correctly in fragments - support.checkClone = div.cloneNode(true).cloneNode(true).lastChild.checked; - - // Support: IE <=11 only - // Make sure textarea (and checkbox) defaultValue is properly cloned - div.innerHTML = ""; - support.noCloneChecked = !!div.cloneNode(true).lastChild.defaultValue; -})(); -var documentElement = document$1.documentElement; - - -var - rkeyEvent = /^key/, - rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/, - rtypenamespace = /^([^.]*)(?:\.(.+)|)/; - -function returnTrue() { - return true; -} - -function returnFalse() { - return false; -} - -// Support: IE <=9 only -// See #13393 for more info -function safeActiveElement() { - try { - return document$1.activeElement; - } catch (err) { - } -} - -function on(elem, types, selector, data, fn, one) { - var origFn, type; - - // Types can be a map of types/handlers - if (typeof types === "object") { - - // ( types-Object, selector, data ) - if (typeof selector !== "string") { - - // ( types-Object, data ) - data = data || selector; - selector = undefined; - } - for (type in types) { - on(elem, type, selector, data, types[type], one); - } - return elem; - } - - if (data == null && fn == null) { - - // ( types, fn ) - fn = selector; - data = selector = undefined; - } else if (fn == null) { - if (typeof selector === "string") { - - // ( types, selector, fn ) - fn = data; - data = undefined; - } else { - - // ( types, data, fn ) - fn = data; - data = selector; - selector = undefined; - } - } - if (fn === false) { - fn = returnFalse; - } else if (!fn) { - return elem; - } - - if (one === 1) { - origFn = fn; - fn = function (event) { - - // Can use an empty set, since event contains the info - jQuery().off(event); - return origFn.apply(this, arguments); - }; - - // Use same guid so caller can remove using origFn - fn.guid = origFn.guid || (origFn.guid = jQuery.guid++); - } - return elem.each(function () { - jQuery.event.add(this, types, fn, data, selector); - }); -} - -/* - * Helper functions for managing events -- not part of the public interface. - * Props to Dean Edwards' addEvent library for many of the ideas. - */ -jQuery.event = { - - global: {}, - - add: function (elem, types, handler, data, selector) { - - var handleObjIn, eventHandle, tmp, - events, t, handleObj, - special, handlers, type, namespaces, origType, - elemData = dataPriv.get(elem); - - // Don't attach events to noData or text/comment nodes (but allow plain objects) - if (!elemData) { - return; - } - - // Caller can pass in an object of custom data in lieu of the handler - if (handler.handler) { - handleObjIn = handler; - handler = handleObjIn.handler; - selector = handleObjIn.selector; - } - - // Ensure that invalid selectors throw exceptions at attach time - // Evaluate against documentElement in case elem is a non-element node (e.g., document) - if (selector) { - jQuery.find.matchesSelector(documentElement, selector); - } - - // Make sure that the handler has a unique ID, used to find/remove it later - if (!handler.guid) { - handler.guid = jQuery.guid++; - } - - // Init the element's event structure and main handler, if this is the first - if (!(events = elemData.events)) { - events = elemData.events = {}; - } - if (!(eventHandle = elemData.handle)) { - eventHandle = elemData.handle = function (e) { - - // Discard the second event of a jQuery.event.trigger() and - // when an event is called after a page has unloaded - return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ? - jQuery.event.dispatch.apply(elem, arguments) : undefined; - }; - } - - // Handle multiple events separated by a space - types = (types || "").match(rnothtmlwhite) || [""]; - t = types.length; - while (t--) { - tmp = rtypenamespace.exec(types[t]) || []; - type = origType = tmp[1]; - namespaces = (tmp[2] || "").split(".").sort(); - - // There *must* be a type, no attaching namespace-only handlers - if (!type) { - continue; - } - - // If event changes its type, use the special event handlers for the changed type - special = jQuery.event.special[type] || {}; - - // If selector defined, determine special event api type, otherwise given type - type = (selector ? special.delegateType : special.bindType) || type; - - // Update special based on newly reset type - special = jQuery.event.special[type] || {}; - - // handleObj is passed to all event handlers - handleObj = jQuery.extend({ - type: type, - origType: origType, - data: data, - handler: handler, - guid: handler.guid, - selector: selector, - needsContext: selector && jQuery.expr.match.needsContext.test(selector), - namespace: namespaces.join(".") - }, handleObjIn); - - // Init the event handler queue if we're the first - if (!(handlers = events[type])) { - handlers = events[type] = []; - handlers.delegateCount = 0; - - // Only use addEventListener if the special events handler returns false - if (!special.setup || - special.setup.call(elem, data, namespaces, eventHandle) === false) { - - if (elem.addEventListener) { - elem.addEventListener(type, eventHandle); - } - } - } - - if (special.add) { - special.add.call(elem, handleObj); - - if (!handleObj.handler.guid) { - handleObj.handler.guid = handler.guid; - } - } - - // Add to the element's handler list, delegates in front - if (selector) { - handlers.splice(handlers.delegateCount++, 0, handleObj); - } else { - handlers.push(handleObj); - } - - // Keep track of which events have ever been used, for event optimization - jQuery.event.global[type] = true; - } - - }, - - // Detach an event or set of events from an element - remove: function (elem, types, handler, selector, mappedTypes) { - - var j, origCount, tmp, - events, t, handleObj, - special, handlers, type, namespaces, origType, - elemData = dataPriv.hasData(elem) && dataPriv.get(elem); - - if (!elemData || !(events = elemData.events)) { - return; - } - - // Once for each type.namespace in types; type may be omitted - types = (types || "").match(rnothtmlwhite) || [""]; - t = types.length; - while (t--) { - tmp = rtypenamespace.exec(types[t]) || []; - type = origType = tmp[1]; - namespaces = (tmp[2] || "").split(".").sort(); - - // Unbind all events (on this namespace, if provided) for the element - if (!type) { - for (type in events) { - jQuery.event.remove(elem, type + types[t], handler, selector, true); - } - continue; - } - - special = jQuery.event.special[type] || {}; - type = (selector ? special.delegateType : special.bindType) || type; - handlers = events[type] || []; - tmp = tmp[2] && - new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)"); - - // Remove matching events - origCount = j = handlers.length; - while (j--) { - handleObj = handlers[j]; - - if ((mappedTypes || origType === handleObj.origType) && - (!handler || handler.guid === handleObj.guid) && - (!tmp || tmp.test(handleObj.namespace)) && - (!selector || selector === handleObj.selector || - selector === "**" && handleObj.selector)) { - handlers.splice(j, 1); - - if (handleObj.selector) { - handlers.delegateCount--; - } - if (special.remove) { - special.remove.call(elem, handleObj); - } - } - } - - // Remove generic event handler if we removed something and no more handlers exist - // (avoids potential for endless recursion during removal of special event handlers) - if (origCount && !handlers.length) { - if (!special.teardown || - special.teardown.call(elem, namespaces, elemData.handle) === false) { - - jQuery.removeEvent(elem, type, elemData.handle); - } - - delete events[type]; - } - } - - // Remove data and the expando if it's no longer used - if (jQuery.isEmptyObject(events)) { - dataPriv.remove(elem, "handle events"); - } - }, - - dispatch: function (nativeEvent) { - - // Make a writable jQuery.Event from the native event object - var event = jQuery.event.fix(nativeEvent); - - var i, j, ret, matched, handleObj, handlerQueue, - args = new Array(arguments.length), - handlers = (dataPriv.get(this, "events") || {})[event.type] || [], - special = jQuery.event.special[event.type] || {}; - - // Use the fix-ed jQuery.Event rather than the (read-only) native event - args[0] = event; - - for (i = 1; i < arguments.length; i++) { - args[i] = arguments[i]; - } - - event.delegateTarget = this; - - // Call the preDispatch hook for the mapped type, and let it bail if desired - if (special.preDispatch && special.preDispatch.call(this, event) === false) { - return; - } - - // Determine handlers - handlerQueue = jQuery.event.handlers.call(this, event, handlers); - - // Run delegates first; they may want to stop propagation beneath us - i = 0; - while ((matched = handlerQueue[i++]) && !event.isPropagationStopped()) { - event.currentTarget = matched.elem; - - j = 0; - while ((handleObj = matched.handlers[j++]) && - !event.isImmediatePropagationStopped()) { - - // Triggered event must either 1) have no namespace, or 2) have namespace(s) - // a subset or equal to those in the bound event (both can have no namespace). - if (!event.rnamespace || event.rnamespace.test(handleObj.namespace)) { - - event.handleObj = handleObj; - event.data = handleObj.data; - - ret = ((jQuery.event.special[handleObj.origType] || {}).handle || - handleObj.handler).apply(matched.elem, args); - - if (ret !== undefined) { - if ((event.result = ret) === false) { - event.preventDefault(); - event.stopPropagation(); - } - } - } - } - } - - // Call the postDispatch hook for the mapped type - if (special.postDispatch) { - special.postDispatch.call(this, event); - } - - return event.result; - }, - - handlers: function (event, handlers) { - var i, handleObj, sel, matchedHandlers, matchedSelectors, - handlerQueue = [], - delegateCount = handlers.delegateCount, - cur = event.target; - - // Find delegate handlers - if (delegateCount && - - // Support: IE <=9 - // Black-hole SVG instance trees (trac-13180) - cur.nodeType && - - // Support: Firefox <=42 - // Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861) - // https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click - // Support: IE 11 only - // ...but not arrow key "clicks" of radio inputs, which can have `button` -1 (gh-2343) - !(event.type === "click" && event.button >= 1)) { - - for (; cur !== this; cur = cur.parentNode || this) { - - // Don't check non-elements (#13208) - // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764) - if (cur.nodeType === 1 && !(event.type === "click" && cur.disabled === true)) { - matchedHandlers = []; - matchedSelectors = {}; - for (i = 0; i < delegateCount; i++) { - handleObj = handlers[i]; - - // Don't conflict with Object.prototype properties (#13203) - sel = handleObj.selector + " "; - - if (matchedSelectors[sel] === undefined) { - matchedSelectors[sel] = handleObj.needsContext ? - jQuery(sel, this).index(cur) > -1 : - jQuery.find(sel, this, null, [cur]).length; - } - if (matchedSelectors[sel]) { - matchedHandlers.push(handleObj); - } - } - if (matchedHandlers.length) { - handlerQueue.push({elem: cur, handlers: matchedHandlers}); - } - } - } - } - - // Add the remaining (directly-bound) handlers - cur = this; - if (delegateCount < handlers.length) { - handlerQueue.push({elem: cur, handlers: handlers.slice(delegateCount)}); - } - - return handlerQueue; - }, - - addProp: function (name, hook) { - Object.defineProperty(jQuery.Event.prototype, name, { - enumerable: true, - configurable: true, - - get: isFunction(hook) ? - function () { - if (this.originalEvent) { - return hook(this.originalEvent); - } - } : - function () { - if (this.originalEvent) { - return this.originalEvent[name]; - } - }, - - set: function (value) { - Object.defineProperty(this, name, { - enumerable: true, - configurable: true, - writable: true, - value: value - }); - } - }); - }, - - fix: function (originalEvent) { - return originalEvent[jQuery.expando] ? - originalEvent : - new jQuery.Event(originalEvent); - }, - - special: { - load: { - - // Prevent triggered image.load events from bubbling to window.load - noBubble: true - }, - focus: { - - // Fire native event if possible so blur/focus sequence is correct - trigger: function () { - if (this !== safeActiveElement() && this.focus) { - this.focus(); - return false; - } - }, - delegateType: "focusin" - }, - blur: { - trigger: function () { - if (this === safeActiveElement() && this.blur) { - this.blur(); - return false; - } - }, - delegateType: "focusout" - }, - click: { - - // For checkbox, fire native event so checked state will be right - trigger: function () { - if (this.type === "checkbox" && this.click && nodeName(this, "input")) { - this.click(); - return false; - } - }, - - // For cross-browser consistency, don't fire native .click() on links - _default: function (event) { - return nodeName(event.target, "a"); - } - }, - - beforeunload: { - postDispatch: function (event) { - - // Support: Firefox 20+ - // Firefox doesn't alert if the returnValue field is not set. - if (event.result !== undefined && event.originalEvent) { - event.originalEvent.returnValue = event.result; - } - } - } - } -}; - -jQuery.removeEvent = function (elem, type, handle) { - - // This "if" is needed for plain objects - if (elem.removeEventListener) { - elem.removeEventListener(type, handle); - } -}; - -jQuery.Event = function (src, props) { - - // Allow instantiation without the 'new' keyword - if (!(this instanceof jQuery.Event)) { - return new jQuery.Event(src, props); - } - - // Event object - if (src && src.type) { - this.originalEvent = src; - this.type = src.type; - - // Events bubbling up the document may have been marked as prevented - // by a handler lower down the tree; reflect the correct value. - this.isDefaultPrevented = src.defaultPrevented || - src.defaultPrevented === undefined && - - // Support: Android <=2.3 only - src.returnValue === false ? - returnTrue : - returnFalse; - - // Create target properties - // Support: Safari <=6 - 7 only - // Target should not be a text node (#504, #13143) - this.target = (src.target && src.target.nodeType === 3) ? - src.target.parentNode : - src.target; - - this.currentTarget = src.currentTarget; - this.relatedTarget = src.relatedTarget; - - // Event type - } else { - this.type = src; - } - - // Put explicitly provided properties onto the event object - if (props) { - jQuery.extend(this, props); - } - - // Create a timestamp if incoming event doesn't have one - this.timeStamp = src && src.timeStamp || Date.now(); - - // Mark it as fixed - this[jQuery.expando] = true; -}; - -// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding -// https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html -jQuery.Event.prototype = { - constructor: jQuery.Event, - isDefaultPrevented: returnFalse, - isPropagationStopped: returnFalse, - isImmediatePropagationStopped: returnFalse, - isSimulated: false, - - preventDefault: function () { - var e = this.originalEvent; - - this.isDefaultPrevented = returnTrue; - - if (e && !this.isSimulated) { - e.preventDefault(); - } - }, - stopPropagation: function () { - var e = this.originalEvent; - - this.isPropagationStopped = returnTrue; - - if (e && !this.isSimulated) { - e.stopPropagation(); - } - }, - stopImmediatePropagation: function () { - var e = this.originalEvent; - - this.isImmediatePropagationStopped = returnTrue; - - if (e && !this.isSimulated) { - e.stopImmediatePropagation(); - } - - this.stopPropagation(); - } -}; - -// Includes all common event props including KeyEvent and MouseEvent specific props -jQuery.each({ - altKey: true, - bubbles: true, - cancelable: true, - changedTouches: true, - ctrlKey: true, - detail: true, - eventPhase: true, - metaKey: true, - pageX: true, - pageY: true, - shiftKey: true, - view: true, - "char": true, - charCode: true, - key: true, - keyCode: true, - button: true, - buttons: true, - clientX: true, - clientY: true, - offsetX: true, - offsetY: true, - pointerId: true, - pointerType: true, - screenX: true, - screenY: true, - targetTouches: true, - toElement: true, - touches: true, - - which: function (event) { - var button = event.button; - - // Add which for key events - if (event.which == null && rkeyEvent.test(event.type)) { - return event.charCode != null ? event.charCode : event.keyCode; - } - - // Add which for click: 1 === left; 2 === middle; 3 === right - if (!event.which && button !== undefined && rmouseEvent.test(event.type)) { - if (button & 1) { - return 1; - } - - if (button & 2) { - return 3; - } - - if (button & 4) { - return 2; - } - - return 0; - } - - return event.which; - } -}, jQuery.event.addProp); - -// Create mouseenter/leave events using mouseover/out and event-time checks -// so that event delegation works in jQuery. -// Do the same for pointerenter/pointerleave and pointerover/pointerout -// -// Support: Safari 7 only -// Safari sends mouseenter too often; see: -// https://bugs.chromium.org/p/chromium/issues/detail?id=470258 -// for the description of the bug (it existed in older Chrome versions as well). -jQuery.each({ - mouseenter: "mouseover", - mouseleave: "mouseout", - pointerenter: "pointerover", - pointerleave: "pointerout" -}, function (orig, fix) { - jQuery.event.special[orig] = { - delegateType: fix, - bindType: fix, - - handle: function (event) { - var ret, - target = this, - related = event.relatedTarget, - handleObj = event.handleObj; - - // For mouseenter/leave call the handler if related is outside the target. - // NB: No relatedTarget if the mouse left/entered the browser window - if (!related || (related !== target && !jQuery.contains(target, related))) { - event.type = handleObj.origType; - ret = handleObj.handler.apply(this, arguments); - event.type = fix; - } - return ret; - } - }; -}); - -jQuery.fn.extend({ - - on: function (types, selector, data, fn) { - return on(this, types, selector, data, fn); - }, - one: function (types, selector, data, fn) { - return on(this, types, selector, data, fn, 1); - }, - off: function (types, selector, fn) { - var handleObj, type; - if (types && types.preventDefault && types.handleObj) { - - // ( event ) dispatched jQuery.Event - handleObj = types.handleObj; - jQuery(types.delegateTarget).off( - handleObj.namespace ? - handleObj.origType + "." + handleObj.namespace : - handleObj.origType, - handleObj.selector, - handleObj.handler - ); - return this; - } - if (typeof types === "object") { - - // ( types-object [, selector] ) - for (type in types) { - this.off(type, selector, types[type]); - } - return this; - } - if (selector === false || typeof selector === "function") { - - // ( types [, fn] ) - fn = selector; - selector = undefined; - } - if (fn === false) { - fn = returnFalse; - } - return this.each(function () { - jQuery.event.remove(this, types, fn, selector); - }); - } -}); - - -var - - /* eslint-disable max-len */ - - // See https://github.com/eslint/eslint/issues/3229 - rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi, - - /* eslint-enable */ - - // Support: IE <=10 - 11, Edge 12 - 13 only - // In IE/Edge using regex groups here causes severe slowdowns. - // See https://connect.microsoft.com/IE/feedback/details/1736512/ - rnoInnerhtml = /\s*$/g; - -// Prefer a tbody over its parent table for containing new rows -function manipulationTarget(elem, content) { - if (nodeName(elem, "table") && - nodeName(content.nodeType !== 11 ? content : content.firstChild, "tr")) { - - return jQuery(elem).children("tbody")[0] || elem; - } - - return elem; -} - -// Replace/restore the type attribute of script elements for safe DOM manipulation -function disableScript(elem) { - elem.type = (elem.getAttribute("type") !== null) + "/" + elem.type; - return elem; -} - -function restoreScript(elem) { - if ((elem.type || "").slice(0, 5) === "true/") { - elem.type = elem.type.slice(5); - } else { - elem.removeAttribute("type"); - } - - return elem; -} - -function cloneCopyEvent(src, dest) { - var i, l, type, pdataOld, pdataCur, udataOld, udataCur, events; - - if (dest.nodeType !== 1) { - return; - } - - // 1. Copy private data: events, handlers, etc. - if (dataPriv.hasData(src)) { - pdataOld = dataPriv.access(src); - pdataCur = dataPriv.set(dest, pdataOld); - events = pdataOld.events; - - if (events) { - delete pdataCur.handle; - pdataCur.events = {}; - - for (type in events) { - for (i = 0, l = events[type].length; i < l; i++) { - jQuery.event.add(dest, type, events[type][i]); - } - } - } - } - - // 2. Copy user data - if (dataUser.hasData(src)) { - udataOld = dataUser.access(src); - udataCur = jQuery.extend({}, udataOld); - - dataUser.set(dest, udataCur); - } -} - -// Fix IE bugs, see support tests -function fixInput(src, dest) { - var nodeName = dest.nodeName.toLowerCase(); - - // Fails to persist the checked state of a cloned checkbox or radio button. - if (nodeName === "input" && rcheckableType.test(src.type)) { - dest.checked = src.checked; - - // Fails to return the selected option to the default selected state when cloning options - } else if (nodeName === "input" || nodeName === "textarea") { - dest.defaultValue = src.defaultValue; - } -} - -function domManip(collection, args, callback, ignored) { - - // Flatten any nested arrays - args = concat.apply([], args); - - var fragment, first, scripts, hasScripts, node, doc, - i = 0, - l = collection.length, - iNoClone = l - 1, - value = args[0], - valueIsFunction = isFunction(value); - - // We can't cloneNode fragments that contain checked, in WebKit - if (valueIsFunction || - (l > 1 && typeof value === "string" && - !support.checkClone && rchecked.test(value))) { - return collection.each(function (index) { - var self = collection.eq(index); - if (valueIsFunction) { - args[0] = value.call(this, index, self.html()); - } - domManip(self, args, callback, ignored); - }); - } - - if (l) { - fragment = buildFragment(args, collection[0].ownerDocument, false, collection, ignored); - first = fragment.firstChild; - - if (fragment.childNodes.length === 1) { - fragment = first; - } - - // Require either new content or an interest in ignored elements to invoke the callback - if (first || ignored) { - scripts = jQuery.map(getAll(fragment, "script"), disableScript); - hasScripts = scripts.length; - - // Use the original fragment for the last item - // instead of the first because it can end up - // being emptied incorrectly in certain situations (#8070). - for (; i < l; i++) { - node = fragment; - - if (i !== iNoClone) { - node = jQuery.clone(node, true, true); - - // Keep references to cloned scripts for later restoration - if (hasScripts) { - - // Support: Android <=4.0 only, PhantomJS 1 only - // push.apply(_, arraylike) throws on ancient WebKit - jQuery.merge(scripts, getAll(node, "script")); - } - } - - callback.call(collection[i], node, i); - } - - if (hasScripts) { - doc = scripts[scripts.length - 1].ownerDocument; - - // Reenable scripts - jQuery.map(scripts, restoreScript); - - // Evaluate executable scripts on first document insertion - for (i = 0; i < hasScripts; i++) { - node = scripts[i]; - if (rscriptType.test(node.type || "") && - !dataPriv.access(node, "globalEval") && - jQuery.contains(doc, node)) { - - if (node.src && (node.type || "").toLowerCase() !== "module") { - - // Optional AJAX dependency, but won't run scripts if not present - if (jQuery._evalUrl) { - jQuery._evalUrl(node.src); - } - } else { - DOMEval(node.textContent.replace(rcleanScript, ""), doc, node); - } - } - } - } - } - } - - return collection; -} - -function remove(elem, selector, keepData) { - var node, - nodes = selector ? jQuery.filter(selector, elem) : elem, - i = 0; - - for (; (node = nodes[i]) != null; i++) { - if (!keepData && node.nodeType === 1) { - jQuery.cleanData(getAll(node)); - } - - if (node.parentNode) { - if (keepData && jQuery.contains(node.ownerDocument, node)) { - setGlobalEval(getAll(node, "script")); - } - node.parentNode.removeChild(node); - } - } - - return elem; -} - -jQuery.extend({ - htmlPrefilter: function (html) { - return html.replace(rxhtmlTag, "<$1>"); - }, - - clone: function (elem, dataAndEvents, deepDataAndEvents) { - var i, l, srcElements, destElements, - clone = elem.cloneNode(true), - inPage = jQuery.contains(elem.ownerDocument, elem); - - // Fix IE cloning issues - if (!support.noCloneChecked && (elem.nodeType === 1 || elem.nodeType === 11) && - !jQuery.isXMLDoc(elem)) { - - // We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/2 - destElements = getAll(clone); - srcElements = getAll(elem); - - for (i = 0, l = srcElements.length; i < l; i++) { - fixInput(srcElements[i], destElements[i]); - } - } - - // Copy the events from the original to the clone - if (dataAndEvents) { - if (deepDataAndEvents) { - srcElements = srcElements || getAll(elem); - destElements = destElements || getAll(clone); - - for (i = 0, l = srcElements.length; i < l; i++) { - cloneCopyEvent(srcElements[i], destElements[i]); - } - } else { - cloneCopyEvent(elem, clone); - } - } - - // Preserve script evaluation history - destElements = getAll(clone, "script"); - if (destElements.length > 0) { - setGlobalEval(destElements, !inPage && getAll(elem, "script")); - } - - // Return the cloned set - return clone; - }, - - cleanData: function (elems) { - var data, elem, type, - special = jQuery.event.special, - i = 0; - - for (; (elem = elems[i]) !== undefined; i++) { - if (acceptData(elem)) { - if ((data = elem[dataPriv.expando])) { - if (data.events) { - for (type in data.events) { - if (special[type]) { - jQuery.event.remove(elem, type); - - // This is a shortcut to avoid jQuery.event.remove's overhead - } else { - jQuery.removeEvent(elem, type, data.handle); - } - } - } - - // Support: Chrome <=35 - 45+ - // Assign undefined instead of using delete, see Data#remove - elem[dataPriv.expando] = undefined; - } - if (elem[dataUser.expando]) { - - // Support: Chrome <=35 - 45+ - // Assign undefined instead of using delete, see Data#remove - elem[dataUser.expando] = undefined; - } - } - } - } -}); - -jQuery.fn.extend({ - detach: function (selector) { - return remove(this, selector, true); - }, - - remove: function (selector) { - return remove(this, selector); - }, - - text: function (value) { - return access(this, function (value) { - return value === undefined ? - jQuery.text(this) : - this.empty().each(function () { - if (this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9) { - this.textContent = value; - } - }); - }, null, value, arguments.length); - }, - - append: function () { - return domManip(this, arguments, function (elem) { - if (this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9) { - var target = manipulationTarget(this, elem); - target.appendChild(elem); - } - }); - }, - - prepend: function () { - return domManip(this, arguments, function (elem) { - if (this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9) { - var target = manipulationTarget(this, elem); - target.insertBefore(elem, target.firstChild); - } - }); - }, - - before: function () { - return domManip(this, arguments, function (elem) { - if (this.parentNode) { - this.parentNode.insertBefore(elem, this); - } - }); - }, - - after: function () { - return domManip(this, arguments, function (elem) { - if (this.parentNode) { - this.parentNode.insertBefore(elem, this.nextSibling); - } - }); - }, - - empty: function () { - var elem, - i = 0; - - for (; (elem = this[i]) != null; i++) { - if (elem.nodeType === 1) { - - // Prevent memory leaks - jQuery.cleanData(getAll(elem, false)); - - // Remove any remaining nodes - elem.textContent = ""; - } - } - - return this; - }, - - clone: function (dataAndEvents, deepDataAndEvents) { - dataAndEvents = dataAndEvents == null ? false : dataAndEvents; - deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; - - return this.map(function () { - return jQuery.clone(this, dataAndEvents, deepDataAndEvents); - }); - }, - - html: function (value) { - return access(this, function (value) { - var elem = this[0] || {}, - i = 0, - l = this.length; - - if (value === undefined && elem.nodeType === 1) { - return elem.innerHTML; - } - - // See if we can take a shortcut and just use innerHTML - if (typeof value === "string" && !rnoInnerhtml.test(value) && - !wrapMap[(rtagName.exec(value) || ["", ""])[1].toLowerCase()]) { - - value = jQuery.htmlPrefilter(value); - - try { - for (; i < l; i++) { - elem = this[i] || {}; - - // Remove element nodes and prevent memory leaks - if (elem.nodeType === 1) { - jQuery.cleanData(getAll(elem, false)); - elem.innerHTML = value; - } - } - - elem = 0; - - // If using innerHTML throws an exception, use the fallback method - } catch (e) { - } - } - - if (elem) { - this.empty().append(value); - } - }, null, value, arguments.length); - }, - - replaceWith: function () { - var ignored = []; - - // Make the changes, replacing each non-ignored context element with the new content - return domManip(this, arguments, function (elem) { - var parent = this.parentNode; - - if (jQuery.inArray(this, ignored) < 0) { - jQuery.cleanData(getAll(this)); - if (parent) { - parent.replaceChild(elem, this); - } - } - - // Force callback invocation - }, ignored); - } -}); - -jQuery.each({ - appendTo: "append", - prependTo: "prepend", - insertBefore: "before", - insertAfter: "after", - replaceAll: "replaceWith" -}, function (name, original) { - jQuery.fn[name] = function (selector) { - var elems, - ret = [], - insert = jQuery(selector), - last = insert.length - 1, - i = 0; - - for (; i <= last; i++) { - elems = i === last ? this : this.clone(true); - jQuery(insert[i])[original](elems); - - // Support: Android <=4.0 only, PhantomJS 1 only - // .get() because push.apply(_, arraylike) throws on ancient WebKit - push.apply(ret, elems.get()); - } - - return this.pushStack(ret); - }; -}); -var rnumnonpx = new RegExp("^(" + pnum + ")(?!px)[a-z%]+$", "i"); - -var getStyles = function (elem) { - - // Support: IE <=11 only, Firefox <=30 (#15098, #14150) - // IE throws on elements created in popups - // FF meanwhile throws on frame elements through "defaultView.getComputedStyle" - var view = elem.ownerDocument.defaultView; - - if (!view || !view.opener) { - view = window; - } - - return view.getComputedStyle(elem); -}; - -var rboxStyle = new RegExp(cssExpand.join("|"), "i"); - - -(function () { - - // Executing both pixelPosition & boxSizingReliable tests require only one layout - // so they're executed at the same time to save the second computation. - function computeStyleTests() { - - // This is a singleton, we need to execute it only once - if (!div) { - return; - } - - container.style.cssText = "position:absolute;left:-11111px;width:60px;" + - "margin-top:1px;padding:0;border:0"; - div.style.cssText = - "position:relative;display:block;box-sizing:border-box;overflow:scroll;" + - "margin:auto;border:1px;padding:1px;" + - "width:60%;top:1%"; - documentElement.appendChild(container).appendChild(div); - - var divStyle = window.getComputedStyle(div); - pixelPositionVal = divStyle.top !== "1%"; - - // Support: Android 4.0 - 4.3 only, Firefox <=3 - 44 - reliableMarginLeftVal = roundPixelMeasures(divStyle.marginLeft) === 12; - - // Support: Android 4.0 - 4.3 only, Safari <=9.1 - 10.1, iOS <=7.0 - 9.3 - // Some styles come back with percentage values, even though they shouldn't - div.style.right = "60%"; - pixelBoxStylesVal = roundPixelMeasures(divStyle.right) === 36; - - // Support: IE 9 - 11 only - // Detect misreporting of content dimensions for box-sizing:border-box elements - boxSizingReliableVal = roundPixelMeasures(divStyle.width) === 36; - - // Support: IE 9 only - // Detect overflow:scroll screwiness (gh-3699) - div.style.position = "absolute"; - scrollboxSizeVal = div.offsetWidth === 36 || "absolute"; - - documentElement.removeChild(container); - - // Nullify the div so it wouldn't be stored in the memory and - // it will also be a sign that checks already performed - div = null; - } - - function roundPixelMeasures(measure) { - return Math.round(parseFloat(measure)); - } - - var pixelPositionVal, boxSizingReliableVal, scrollboxSizeVal, pixelBoxStylesVal, - reliableMarginLeftVal, - container = document$1.createElement("div"), - div = document$1.createElement("div"); - - // Finish early in limited (non-browser) environments - if (!div.style) { - return; - } - - // Support: IE <=9 - 11 only - // Style of cloned element affects source element cloned (#8908) - div.style.backgroundClip = "content-box"; - div.cloneNode(true).style.backgroundClip = ""; - support.clearCloneStyle = div.style.backgroundClip === "content-box"; - - jQuery.extend(support, { - boxSizingReliable: function () { - computeStyleTests(); - return boxSizingReliableVal; - }, - pixelBoxStyles: function () { - computeStyleTests(); - return pixelBoxStylesVal; - }, - pixelPosition: function () { - computeStyleTests(); - return pixelPositionVal; - }, - reliableMarginLeft: function () { - computeStyleTests(); - return reliableMarginLeftVal; - }, - scrollboxSize: function () { - computeStyleTests(); - return scrollboxSizeVal; - } - }); -})(); - - -function curCSS(elem, name, computed) { - var width, minWidth, maxWidth, ret, - - // Support: Firefox 51+ - // Retrieving style before computed somehow - // fixes an issue with getting wrong values - // on detached elements - style = elem.style; - - computed = computed || getStyles(elem); - - // getPropertyValue is needed for: - // .css('filter') (IE 9 only, #12537) - // .css('--customProperty) (#3144) - if (computed) { - ret = computed.getPropertyValue(name) || computed[name]; - - if (ret === "" && !jQuery.contains(elem.ownerDocument, elem)) { - ret = jQuery.style(elem, name); - } - - // A tribute to the "awesome hack by Dean Edwards" - // Android Browser returns percentage for some values, - // but width seems to be reliably pixels. - // This is against the CSSOM draft spec: - // https://drafts.csswg.org/cssom/#resolved-values - if (!support.pixelBoxStyles() && rnumnonpx.test(ret) && rboxStyle.test(name)) { - - // Remember the original values - width = style.width; - minWidth = style.minWidth; - maxWidth = style.maxWidth; - - // Put in the new values to get a computed value out - style.minWidth = style.maxWidth = style.width = ret; - ret = computed.width; - - // Revert the changed values - style.width = width; - style.minWidth = minWidth; - style.maxWidth = maxWidth; - } - } - - return ret !== undefined ? - - // Support: IE <=9 - 11 only - // IE returns zIndex value as an integer. - ret + "" : - ret; -} - - -function addGetHookIf(conditionFn, hookFn) { - - // Define the hook, we'll check on the first run if it's really needed. - return { - get: function () { - if (conditionFn()) { - - // Hook not needed (or it's not possible to use it due - // to missing dependency), remove it. - delete this.get; - return; - } - - // Hook needed; redefine it so that the support test is not executed again. - return (this.get = hookFn).apply(this, arguments); - } - }; -} - - -var - - // Swappable if display is none or starts with table - // except "table", "table-cell", or "table-caption" - // See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display - rdisplayswap = /^(none|table(?!-c[ea]).+)/, - rcustomProp = /^--/, - cssShow = {position: "absolute", visibility: "hidden", display: "block"}, - cssNormalTransform = { - letterSpacing: "0", - fontWeight: "400" - }, - - cssPrefixes = ["Webkit", "Moz", "ms"], - emptyStyle = document$1.createElement("div").style; - -// Return a css property mapped to a potentially vendor prefixed property -function vendorPropName(name) { - - // Shortcut for names that are not vendor prefixed - if (name in emptyStyle) { - return name; - } - - // Check for vendor prefixed names - var capName = name[0].toUpperCase() + name.slice(1), - i = cssPrefixes.length; - - while (i--) { - name = cssPrefixes[i] + capName; - if (name in emptyStyle) { - return name; - } - } -} - -// Return a property mapped along what jQuery.cssProps suggests or to -// a vendor prefixed property. -function finalPropName(name) { - var ret = jQuery.cssProps[name]; - if (!ret) { - ret = jQuery.cssProps[name] = vendorPropName(name) || name; - } - return ret; -} - -function setPositiveNumber(elem, value, subtract) { - - // Any relative (+/-) values have already been - // normalized at this point - var matches = rcssNum.exec(value); - return matches ? - - // Guard against undefined "subtract", e.g., when used as in cssHooks - Math.max(0, matches[2] - (subtract || 0)) + (matches[3] || "px") : - value; -} - -function boxModelAdjustment(elem, dimension, box, isBorderBox, styles, computedVal) { - var i = dimension === "width" ? 1 : 0, - extra = 0, - delta = 0; - - // Adjustment may not be necessary - if (box === (isBorderBox ? "border" : "content")) { - return 0; - } - - for (; i < 4; i += 2) { - - // Both box models exclude margin - if (box === "margin") { - delta += jQuery.css(elem, box + cssExpand[i], true, styles); - } - - // If we get here with a content-box, we're seeking "padding" or "border" or "margin" - if (!isBorderBox) { - - // Add padding - delta += jQuery.css(elem, "padding" + cssExpand[i], true, styles); - - // For "border" or "margin", add border - if (box !== "padding") { - delta += jQuery.css(elem, "border" + cssExpand[i] + "Width", true, styles); - - // But still keep track of it otherwise - } else { - extra += jQuery.css(elem, "border" + cssExpand[i] + "Width", true, styles); - } - - // If we get here with a border-box (content + padding + border), we're seeking "content" or - // "padding" or "margin" - } else { - - // For "content", subtract padding - if (box === "content") { - delta -= jQuery.css(elem, "padding" + cssExpand[i], true, styles); - } - - // For "content" or "padding", subtract border - if (box !== "margin") { - delta -= jQuery.css(elem, "border" + cssExpand[i] + "Width", true, styles); - } - } - } - - // Account for positive content-box scroll gutter when requested by providing computedVal - if (!isBorderBox && computedVal >= 0) { - - // offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border - // Assuming integer scroll gutter, subtract the rest and round down - delta += Math.max(0, Math.ceil( - elem["offset" + dimension[0].toUpperCase() + dimension.slice(1)] - - computedVal - - delta - - extra - - 0.5 - )); - } - - return delta; -} - -function getWidthOrHeight(elem, dimension, extra) { - - // Start with computed style - var styles = getStyles(elem), - val = curCSS(elem, dimension, styles), - isBorderBox = jQuery.css(elem, "boxSizing", false, styles) === "border-box", - valueIsBorderBox = isBorderBox; - - // Support: Firefox <=54 - // Return a confounding non-pixel value or feign ignorance, as appropriate. - if (rnumnonpx.test(val)) { - if (!extra) { - return val; - } - val = "auto"; - } - - // Check for style in case a browser which returns unreliable values - // for getComputedStyle silently falls back to the reliable elem.style - valueIsBorderBox = valueIsBorderBox && - (support.boxSizingReliable() || val === elem.style[dimension]); - - // Fall back to offsetWidth/offsetHeight when value is "auto" - // This happens for inline elements with no explicit setting (gh-3571) - // Support: Android <=4.1 - 4.3 only - // Also use offsetWidth/offsetHeight for misreported inline dimensions (gh-3602) - if (val === "auto" || - !parseFloat(val) && jQuery.css(elem, "display", false, styles) === "inline") { - - val = elem["offset" + dimension[0].toUpperCase() + dimension.slice(1)]; - - // offsetWidth/offsetHeight provide border-box values - valueIsBorderBox = true; - } - - // Normalize "" and auto - val = parseFloat(val) || 0; - - // Adjust for the element's box model - return (val + - boxModelAdjustment( - elem, - dimension, - extra || (isBorderBox ? "border" : "content"), - valueIsBorderBox, - styles, - - // Provide the current computed size to request scroll gutter calculation (gh-3589) - val - ) - ) + "px"; -} - -jQuery.extend({ - - // Add in style property hooks for overriding the default - // behavior of getting and setting a style property - cssHooks: { - opacity: { - get: function (elem, computed) { - if (computed) { - - // We should always get a number back from opacity - var ret = curCSS(elem, "opacity"); - return ret === "" ? "1" : ret; - } - } - } - }, - - // Don't automatically add "px" to these possibly-unitless properties - cssNumber: { - "animationIterationCount": true, - "columnCount": true, - "fillOpacity": true, - "flexGrow": true, - "flexShrink": true, - "fontWeight": true, - "lineHeight": true, - "opacity": true, - "order": true, - "orphans": true, - "widows": true, - "zIndex": true, - "zoom": true - }, - - // Add in properties whose names you wish to fix before - // setting or getting the value - cssProps: {}, - - // Get and set the style property on a DOM Node - style: function (elem, name, value, extra) { - - // Don't set styles on text and comment nodes - if (!elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style) { - return; - } - - // Make sure that we're working with the right name - var ret, type, hooks, - origName = camelCase(name), - isCustomProp = rcustomProp.test(name), - style = elem.style; - - // Make sure that we're working with the right name. We don't - // want to query the value if it is a CSS custom property - // since they are user-defined. - if (!isCustomProp) { - name = finalPropName(origName); - } - - // Gets hook for the prefixed version, then unprefixed version - hooks = jQuery.cssHooks[name] || jQuery.cssHooks[origName]; - - // Check if we're setting a value - if (value !== undefined) { - type = typeof value; - - // Convert "+=" or "-=" to relative numbers (#7345) - if (type === "string" && (ret = rcssNum.exec(value)) && ret[1]) { - value = adjustCSS(elem, name, ret); - - // Fixes bug #9237 - type = "number"; - } - - // Make sure that null and NaN values aren't set (#7116) - if (value == null || value !== value) { - return; - } - - // If a number was passed in, add the unit (except for certain CSS properties) - if (type === "number") { - value += ret && ret[3] || (jQuery.cssNumber[origName] ? "" : "px"); - } - - // background-* props affect original clone's values - if (!support.clearCloneStyle && value === "" && name.indexOf("background") === 0) { - style[name] = "inherit"; - } - - // If a hook was provided, use that value, otherwise just set the specified value - if (!hooks || !("set" in hooks) || - (value = hooks.set(elem, value, extra)) !== undefined) { - - if (isCustomProp) { - style.setProperty(name, value); - } else { - style[name] = value; - } - } - - } else { - - // If a hook was provided get the non-computed value from there - if (hooks && "get" in hooks && - (ret = hooks.get(elem, false, extra)) !== undefined) { - - return ret; - } - - // Otherwise just get the value from the style object - return style[name]; - } - }, - - css: function (elem, name, extra, styles) { - var val, num, hooks, - origName = camelCase(name), - isCustomProp = rcustomProp.test(name); - - // Make sure that we're working with the right name. We don't - // want to modify the value if it is a CSS custom property - // since they are user-defined. - if (!isCustomProp) { - name = finalPropName(origName); - } - - // Try prefixed name followed by the unprefixed name - hooks = jQuery.cssHooks[name] || jQuery.cssHooks[origName]; - - // If a hook was provided get the computed value from there - if (hooks && "get" in hooks) { - val = hooks.get(elem, true, extra); - } - - // Otherwise, if a way to get the computed value exists, use that - if (val === undefined) { - val = curCSS(elem, name, styles); - } - - // Convert "normal" to computed value - if (val === "normal" && name in cssNormalTransform) { - val = cssNormalTransform[name]; - } - - // Make numeric if forced or a qualifier was provided and val looks numeric - if (extra === "" || extra) { - num = parseFloat(val); - return extra === true || isFinite(num) ? num || 0 : val; - } - - return val; - } -}); - -jQuery.each(["height", "width"], function (i, dimension) { - jQuery.cssHooks[dimension] = { - get: function (elem, computed, extra) { - if (computed) { - - // Certain elements can have dimension info if we invisibly show them - // but it must have a current display style that would benefit - return rdisplayswap.test(jQuery.css(elem, "display")) && - - // Support: Safari 8+ - // Table columns in Safari have non-zero offsetWidth & zero - // getBoundingClientRect().width unless display is changed. - // Support: IE <=11 only - // Running getBoundingClientRect on a disconnected node - // in IE throws an error. - (!elem.getClientRects().length || !elem.getBoundingClientRect().width) ? - swap(elem, cssShow, function () { - return getWidthOrHeight(elem, dimension, extra); - }) : - getWidthOrHeight(elem, dimension, extra); - } - }, - - set: function (elem, value, extra) { - var matches, - styles = getStyles(elem), - isBorderBox = jQuery.css(elem, "boxSizing", false, styles) === "border-box", - subtract = extra && boxModelAdjustment( - elem, - dimension, - extra, - isBorderBox, - styles - ); - - // Account for unreliable border-box dimensions by comparing offset* to computed and - // faking a content-box to get border and padding (gh-3699) - if (isBorderBox && support.scrollboxSize() === styles.position) { - subtract -= Math.ceil( - elem["offset" + dimension[0].toUpperCase() + dimension.slice(1)] - - parseFloat(styles[dimension]) - - boxModelAdjustment(elem, dimension, "border", false, styles) - - 0.5 - ); - } - - // Convert to pixels if value adjustment is needed - if (subtract && (matches = rcssNum.exec(value)) && - (matches[3] || "px") !== "px") { - - elem.style[dimension] = value; - value = jQuery.css(elem, dimension); - } - - return setPositiveNumber(elem, value, subtract); - } - }; -}); - -jQuery.cssHooks.marginLeft = addGetHookIf(support.reliableMarginLeft, - function (elem, computed) { - if (computed) { - return (parseFloat(curCSS(elem, "marginLeft")) || - elem.getBoundingClientRect().left - - swap(elem, {marginLeft: 0}, function () { - return elem.getBoundingClientRect().left; - }) - ) + "px"; - } - } -); - -// These hooks are used by animate to expand properties -jQuery.each({ - margin: "", - padding: "", - border: "Width" -}, function (prefix, suffix) { - jQuery.cssHooks[prefix + suffix] = { - expand: function (value) { - var i = 0, - expanded = {}, - - // Assumes a single number if not a string - parts = typeof value === "string" ? value.split(" ") : [value]; - - for (; i < 4; i++) { - expanded[prefix + cssExpand[i] + suffix] = - parts[i] || parts[i - 2] || parts[0]; - } - - return expanded; - } - }; - - if (prefix !== "margin") { - jQuery.cssHooks[prefix + suffix].set = setPositiveNumber; - } -}); - -jQuery.fn.extend({ - css: function (name, value) { - return access(this, function (elem, name, value) { - var styles, len, - map = {}, - i = 0; - - if (Array.isArray(name)) { - styles = getStyles(elem); - len = name.length; - - for (; i < len; i++) { - map[name[i]] = jQuery.css(elem, name[i], false, styles); - } - - return map; - } - - return value !== undefined ? - jQuery.style(elem, name, value) : - jQuery.css(elem, name); - }, name, value, arguments.length > 1); - } -}); - - -// Based off of the plugin by Clint Helfers, with permission. -// https://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/ -jQuery.fn.delay = function (time, type) { - time = jQuery.fx ? jQuery.fx.speeds[time] || time : time; - type = type || "fx"; - - return this.queue(type, function (next, hooks) { - var timeout = window.setTimeout(next, time); - hooks.stop = function () { - window.clearTimeout(timeout); - }; - }); -}; - - -(function () { - var input = document$1.createElement("input"), - select = document$1.createElement("select"), - opt = select.appendChild(document$1.createElement("option")); - - input.type = "checkbox"; - - // Support: Android <=4.3 only - // Default value for a checkbox should be "on" - support.checkOn = input.value !== ""; - - // Support: IE <=11 only - // Must access selectedIndex to make default options select - support.optSelected = opt.selected; - - // Support: IE <=11 only - // An input loses its value after becoming a radio - input = document$1.createElement("input"); - input.value = "t"; - input.type = "radio"; - support.radioValue = input.value === "t"; -})(); - - -var boolHook, - attrHandle = jQuery.expr.attrHandle; - -jQuery.fn.extend({ - attr: function (name, value) { - return access(this, jQuery.attr, name, value, arguments.length > 1); - }, - - removeAttr: function (name) { - return this.each(function () { - jQuery.removeAttr(this, name); - }); - } -}); - -jQuery.extend({ - attr: function (elem, name, value) { - var ret, hooks, - nType = elem.nodeType; - - // Don't get/set attributes on text, comment and attribute nodes - if (nType === 3 || nType === 8 || nType === 2) { - return; - } - - // Fallback to prop when attributes are not supported - if (typeof elem.getAttribute === "undefined") { - return jQuery.prop(elem, name, value); - } - - // Attribute hooks are determined by the lowercase version - // Grab necessary hook if one is defined - if (nType !== 1 || !jQuery.isXMLDoc(elem)) { - hooks = jQuery.attrHooks[name.toLowerCase()] || - (jQuery.expr.match.bool.test(name) ? boolHook : undefined); - } - - if (value !== undefined) { - if (value === null) { - jQuery.removeAttr(elem, name); - return; - } - - if (hooks && "set" in hooks && - (ret = hooks.set(elem, value, name)) !== undefined) { - return ret; - } - - elem.setAttribute(name, value + ""); - return value; - } - - if (hooks && "get" in hooks && (ret = hooks.get(elem, name)) !== null) { - return ret; - } - - ret = jQuery.find.attr(elem, name); - - // Non-existent attributes return null, we normalize to undefined - return ret == null ? undefined : ret; - }, - - attrHooks: { - type: { - set: function (elem, value) { - if (!support.radioValue && value === "radio" && - nodeName(elem, "input")) { - var val = elem.value; - elem.setAttribute("type", value); - if (val) { - elem.value = val; - } - return value; - } - } - } - }, - - removeAttr: function (elem, value) { - var name, - i = 0, - - // Attribute names can contain non-HTML whitespace characters - // https://html.spec.whatwg.org/multipage/syntax.html#attributes-2 - attrNames = value && value.match(rnothtmlwhite); - - if (attrNames && elem.nodeType === 1) { - while ((name = attrNames[i++])) { - elem.removeAttribute(name); - } - } - } -}); - -// Hooks for boolean attributes -boolHook = { - set: function (elem, value, name) { - if (value === false) { - - // Remove boolean attributes when set to false - jQuery.removeAttr(elem, name); - } else { - elem.setAttribute(name, name); - } - return name; - } -}; - -jQuery.each(jQuery.expr.match.bool.source.match(/\w+/g), function (i, name) { - var getter = attrHandle[name] || jQuery.find.attr; - - attrHandle[name] = function (elem, name, isXML) { - var ret, handle, - lowercaseName = name.toLowerCase(); - - if (!isXML) { - - // Avoid an infinite loop by temporarily removing this function from the getter - handle = attrHandle[lowercaseName]; - attrHandle[lowercaseName] = ret; - ret = getter(elem, name, isXML) != null ? - lowercaseName : - null; - attrHandle[lowercaseName] = handle; - } - return ret; - }; -}); - - -var rfocusable = /^(?:input|select|textarea|button)$/i, - rclickable = /^(?:a|area)$/i; - -jQuery.fn.extend({ - prop: function (name, value) { - return access(this, jQuery.prop, name, value, arguments.length > 1); - }, - - removeProp: function (name) { - return this.each(function () { - delete this[jQuery.propFix[name] || name]; - }); - } -}); - -jQuery.extend({ - prop: function (elem, name, value) { - var ret, hooks, - nType = elem.nodeType; - - // Don't get/set properties on text, comment and attribute nodes - if (nType === 3 || nType === 8 || nType === 2) { - return; - } - - if (nType !== 1 || !jQuery.isXMLDoc(elem)) { - - // Fix name and attach hooks - name = jQuery.propFix[name] || name; - hooks = jQuery.propHooks[name]; - } - - if (value !== undefined) { - if (hooks && "set" in hooks && - (ret = hooks.set(elem, value, name)) !== undefined) { - return ret; - } - - return (elem[name] = value); - } - - if (hooks && "get" in hooks && (ret = hooks.get(elem, name)) !== null) { - return ret; - } - - return elem[name]; - }, - - propHooks: { - tabIndex: { - get: function (elem) { - - // Support: IE <=9 - 11 only - // elem.tabIndex doesn't always return the - // correct value when it hasn't been explicitly set - // https://web.archive.org/web/20141116233347/http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ - // Use proper attribute retrieval(#12072) - var tabindex = jQuery.find.attr(elem, "tabindex"); - - if (tabindex) { - return parseInt(tabindex, 10); - } - - if ( - rfocusable.test(elem.nodeName) || - rclickable.test(elem.nodeName) && - elem.href - ) { - return 0; - } - - return -1; - } - } - }, - - propFix: { - "for": "htmlFor", - "class": "className" - } -}); - -// Support: IE <=11 only -// Accessing the selectedIndex property -// forces the browser to respect setting selected -// on the option -// The getter ensures a default option is selected -// when in an optgroup -// eslint rule "no-unused-expressions" is disabled for this code -// since it considers such accessions noop -if (!support.optSelected) { - jQuery.propHooks.selected = { - get: function (elem) { - - /* eslint no-unused-expressions: "off" */ - - var parent = elem.parentNode; - if (parent && parent.parentNode) { - parent.parentNode.selectedIndex; - } - return null; - }, - set: function (elem) { - - /* eslint no-unused-expressions: "off" */ - - var parent = elem.parentNode; - if (parent) { - parent.selectedIndex; - - if (parent.parentNode) { - parent.parentNode.selectedIndex; - } - } - } - }; -} - -jQuery.each([ - "tabIndex", - "readOnly", - "maxLength", - "cellSpacing", - "cellPadding", - "rowSpan", - "colSpan", - "useMap", - "frameBorder", - "contentEditable" -], function () { - jQuery.propFix[this.toLowerCase()] = this; -}); - - -// Strip and collapse whitespace according to HTML spec -// https://infra.spec.whatwg.org/#strip-and-collapse-ascii-whitespace -function stripAndCollapse(value) { - var tokens = value.match(rnothtmlwhite) || []; - return tokens.join(" "); -} - - -function getClass(elem) { - return elem.getAttribute && elem.getAttribute("class") || ""; -} - -function classesToArray(value) { - if (Array.isArray(value)) { - return value; - } - if (typeof value === "string") { - return value.match(rnothtmlwhite) || []; - } - return []; -} - -jQuery.fn.extend({ - addClass: function (value) { - var classes, elem, cur, curValue, clazz, j, finalValue, - i = 0; - - if (isFunction(value)) { - return this.each(function (j) { - jQuery(this).addClass(value.call(this, j, getClass(this))); - }); - } - - classes = classesToArray(value); - - if (classes.length) { - while ((elem = this[i++])) { - curValue = getClass(elem); - cur = elem.nodeType === 1 && (" " + stripAndCollapse(curValue) + " "); - - if (cur) { - j = 0; - while ((clazz = classes[j++])) { - if (cur.indexOf(" " + clazz + " ") < 0) { - cur += clazz + " "; - } - } - - // Only assign if different to avoid unneeded rendering. - finalValue = stripAndCollapse(cur); - if (curValue !== finalValue) { - elem.setAttribute("class", finalValue); - } - } - } - } - - return this; - }, - - removeClass: function (value) { - var classes, elem, cur, curValue, clazz, j, finalValue, - i = 0; - - if (isFunction(value)) { - return this.each(function (j) { - jQuery(this).removeClass(value.call(this, j, getClass(this))); - }); - } - - if (!arguments.length) { - return this.attr("class", ""); - } - - classes = classesToArray(value); - - if (classes.length) { - while ((elem = this[i++])) { - curValue = getClass(elem); - - // This expression is here for better compressibility (see addClass) - cur = elem.nodeType === 1 && (" " + stripAndCollapse(curValue) + " "); - - if (cur) { - j = 0; - while ((clazz = classes[j++])) { - - // Remove *all* instances - while (cur.indexOf(" " + clazz + " ") > -1) { - cur = cur.replace(" " + clazz + " ", " "); - } - } - - // Only assign if different to avoid unneeded rendering. - finalValue = stripAndCollapse(cur); - if (curValue !== finalValue) { - elem.setAttribute("class", finalValue); - } - } - } - } - - return this; - }, - - toggleClass: function (value, stateVal) { - var type = typeof value, - isValidValue = type === "string" || Array.isArray(value); - - if (typeof stateVal === "boolean" && isValidValue) { - return stateVal ? this.addClass(value) : this.removeClass(value); - } - - if (isFunction(value)) { - return this.each(function (i) { - jQuery(this).toggleClass( - value.call(this, i, getClass(this), stateVal), - stateVal - ); - }); - } - - return this.each(function () { - var className, i, self, classNames; - - if (isValidValue) { - - // Toggle individual class names - i = 0; - self = jQuery(this); - classNames = classesToArray(value); - - while ((className = classNames[i++])) { - - // Check each className given, space separated list - if (self.hasClass(className)) { - self.removeClass(className); - } else { - self.addClass(className); - } - } - - // Toggle whole class name - } else if (value === undefined || type === "boolean") { - className = getClass(this); - if (className) { - - // Store className if set - dataPriv.set(this, "__className__", className); - } - - // If the element has a class name or if we're passed `false`, - // then remove the whole classname (if there was one, the above saved it). - // Otherwise bring back whatever was previously saved (if anything), - // falling back to the empty string if nothing was stored. - if (this.setAttribute) { - this.setAttribute("class", - className || value === false ? - "" : - dataPriv.get(this, "__className__") || "" - ); - } - } - }); - }, - - hasClass: function (selector) { - var className, elem, - i = 0; - - className = " " + selector + " "; - while ((elem = this[i++])) { - if (elem.nodeType === 1 && - (" " + stripAndCollapse(getClass(elem)) + " ").indexOf(className) > -1) { - return true; - } - } - - return false; - } -}); - - -var rreturn = /\r/g; - -jQuery.fn.extend({ - val: function (value) { - var hooks, ret, valueIsFunction, - elem = this[0]; - - if (!arguments.length) { - if (elem) { - hooks = jQuery.valHooks[elem.type] || - jQuery.valHooks[elem.nodeName.toLowerCase()]; - - if (hooks && - "get" in hooks && - (ret = hooks.get(elem, "value")) !== undefined - ) { - return ret; - } - - ret = elem.value; - - // Handle most common string cases - if (typeof ret === "string") { - return ret.replace(rreturn, ""); - } - - // Handle cases where value is null/undef or number - return ret == null ? "" : ret; - } - - return; - } - - valueIsFunction = isFunction(value); - - return this.each(function (i) { - var val; - - if (this.nodeType !== 1) { - return; - } - - if (valueIsFunction) { - val = value.call(this, i, jQuery(this).val()); - } else { - val = value; - } - - // Treat null/undefined as ""; convert numbers to string - if (val == null) { - val = ""; - - } else if (typeof val === "number") { - val += ""; - - } else if (Array.isArray(val)) { - val = jQuery.map(val, function (value) { - return value == null ? "" : value + ""; - }); - } - - hooks = jQuery.valHooks[this.type] || jQuery.valHooks[this.nodeName.toLowerCase()]; - - // If set returns undefined, fall back to normal setting - if (!hooks || !("set" in hooks) || hooks.set(this, val, "value") === undefined) { - this.value = val; - } - }); - } -}); - -jQuery.extend({ - valHooks: { - option: { - get: function (elem) { - - var val = jQuery.find.attr(elem, "value"); - return val != null ? - val : - - // Support: IE <=10 - 11 only - // option.text throws exceptions (#14686, #14858) - // Strip and collapse whitespace - // https://html.spec.whatwg.org/#strip-and-collapse-whitespace - stripAndCollapse(jQuery.text(elem)); - } - }, - select: { - get: function (elem) { - var value, option, i, - options = elem.options, - index = elem.selectedIndex, - one = elem.type === "select-one", - values = one ? null : [], - max = one ? index + 1 : options.length; - - if (index < 0) { - i = max; - - } else { - i = one ? index : 0; - } - - // Loop through all the selected options - for (; i < max; i++) { - option = options[i]; - - // Support: IE <=9 only - // IE8-9 doesn't update selected after form reset (#2551) - if ((option.selected || i === index) && - - // Don't return options that are disabled or in a disabled optgroup - !option.disabled && - (!option.parentNode.disabled || - !nodeName(option.parentNode, "optgroup"))) { - - // Get the specific value for the option - value = jQuery(option).val(); - - // We don't need an array for one selects - if (one) { - return value; - } - - // Multi-Selects return an array - values.push(value); - } - } - - return values; - }, - - set: function (elem, value) { - var optionSet, option, - options = elem.options, - values = jQuery.makeArray(value), - i = options.length; - - while (i--) { - option = options[i]; - - /* eslint-disable no-cond-assign */ - - if (option.selected = - jQuery.inArray(jQuery.valHooks.option.get(option), values) > -1 - ) { - optionSet = true; - } - - /* eslint-enable no-cond-assign */ - } - - // Force browsers to behave consistently when non-matching value is set - if (!optionSet) { - elem.selectedIndex = -1; - } - return values; - } - } - } -}); - -// Radios and checkboxes getter/setter -jQuery.each(["radio", "checkbox"], function () { - jQuery.valHooks[this] = { - set: function (elem, value) { - if (Array.isArray(value)) { - return (elem.checked = jQuery.inArray(jQuery(elem).val(), value) > -1); - } - } - }; - if (!support.checkOn) { - jQuery.valHooks[this].get = function (elem) { - return elem.getAttribute("value") === null ? "on" : elem.value; - }; - } -}); - - -// Return jQuery for attributes-only inclusion - - -support.focusin = "onfocusin" in window; - - -var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, - stopPropagationCallback = function (e) { - e.stopPropagation(); - }; - -jQuery.extend(jQuery.event, { - - trigger: function (event, data, elem, onlyHandlers) { - - var i, cur, tmp, bubbleType, ontype, handle, special, lastElement, - eventPath = [elem || document$1], - type = hasOwn.call(event, "type") ? event.type : event, - namespaces = hasOwn.call(event, "namespace") ? event.namespace.split(".") : []; - - cur = lastElement = tmp = elem = elem || document$1; - - // Don't do events on text and comment nodes - if (elem.nodeType === 3 || elem.nodeType === 8) { - return; - } - - // focus/blur morphs to focusin/out; ensure we're not firing them right now - if (rfocusMorph.test(type + jQuery.event.triggered)) { - return; - } - - if (type.indexOf(".") > -1) { - - // Namespaced trigger; create a regexp to match event type in handle() - namespaces = type.split("."); - type = namespaces.shift(); - namespaces.sort(); - } - ontype = type.indexOf(":") < 0 && "on" + type; - - // Caller can pass in a jQuery.Event object, Object, or just an event type string - event = event[jQuery.expando] ? - event : - new jQuery.Event(type, typeof event === "object" && event); - - // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true) - event.isTrigger = onlyHandlers ? 2 : 3; - event.namespace = namespaces.join("."); - event.rnamespace = event.namespace ? - new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)") : - null; - - // Clean up the event in case it is being reused - event.result = undefined; - if (!event.target) { - event.target = elem; - } - - // Clone any incoming data and prepend the event, creating the handler arg list - data = data == null ? - [event] : - jQuery.makeArray(data, [event]); - - // Allow special events to draw outside the lines - special = jQuery.event.special[type] || {}; - if (!onlyHandlers && special.trigger && special.trigger.apply(elem, data) === false) { - return; - } - - // Determine event propagation path in advance, per W3C events spec (#9951) - // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) - if (!onlyHandlers && !special.noBubble && !isWindow(elem)) { - - bubbleType = special.delegateType || type; - if (!rfocusMorph.test(bubbleType + type)) { - cur = cur.parentNode; - } - for (; cur; cur = cur.parentNode) { - eventPath.push(cur); - tmp = cur; - } - - // Only add window if we got to document (e.g., not plain obj or detached DOM) - if (tmp === (elem.ownerDocument || document$1)) { - eventPath.push(tmp.defaultView || tmp.parentWindow || window); - } - } - - // Fire handlers on the event path - i = 0; - while ((cur = eventPath[i++]) && !event.isPropagationStopped()) { - lastElement = cur; - event.type = i > 1 ? - bubbleType : - special.bindType || type; - - // jQuery handler - handle = (dataPriv.get(cur, "events") || {})[event.type] && - dataPriv.get(cur, "handle"); - if (handle) { - handle.apply(cur, data); - } - - // Native handler - handle = ontype && cur[ontype]; - if (handle && handle.apply && acceptData(cur)) { - event.result = handle.apply(cur, data); - if (event.result === false) { - event.preventDefault(); - } - } - } - event.type = type; - - // If nobody prevented the default action, do it now - if (!onlyHandlers && !event.isDefaultPrevented()) { - - if ((!special._default || - special._default.apply(eventPath.pop(), data) === false) && - acceptData(elem)) { - - // Call a native DOM method on the target with the same name as the event. - // Don't do default actions on window, that's where global variables be (#6170) - if (ontype && isFunction(elem[type]) && !isWindow(elem)) { - - // Don't re-trigger an onFOO event when we call its FOO() method - tmp = elem[ontype]; - - if (tmp) { - elem[ontype] = null; - } - - // Prevent re-triggering of the same event, since we already bubbled it above - jQuery.event.triggered = type; - - if (event.isPropagationStopped()) { - lastElement.addEventListener(type, stopPropagationCallback); - } - - elem[type](); - - if (event.isPropagationStopped()) { - lastElement.removeEventListener(type, stopPropagationCallback); - } - - jQuery.event.triggered = undefined; - - if (tmp) { - elem[ontype] = tmp; - } - } - } - } - - return event.result; - }, - - // Piggyback on a donor event to simulate a different one - // Used only for `focus(in | out)` events - simulate: function (type, elem, event) { - var e = jQuery.extend( - new jQuery.Event(), - event, - { - type: type, - isSimulated: true - } - ); - - jQuery.event.trigger(e, null, elem); - } - -}); - -jQuery.fn.extend({ - - trigger: function (type, data) { - return this.each(function () { - jQuery.event.trigger(type, data, this); - }); - }, - triggerHandler: function (type, data) { - var elem = this[0]; - if (elem) { - return jQuery.event.trigger(type, data, elem, true); - } - } -}); - - -// Support: Firefox <=44 -// Firefox doesn't have focus(in | out) events -// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787 -// -// Support: Chrome <=48 - 49, Safari <=9.0 - 9.1 -// focus(in | out) events fire after focus & blur events, -// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order -// Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857 -if (!support.focusin) { - jQuery.each({focus: "focusin", blur: "focusout"}, function (orig, fix) { - - // Attach a single capturing handler on the document while someone wants focusin/focusout - var handler = function (event) { - jQuery.event.simulate(fix, event.target, jQuery.event.fix(event)); - }; - - jQuery.event.special[fix] = { - setup: function () { - var doc = this.ownerDocument || this, - attaches = dataPriv.access(doc, fix); - - if (!attaches) { - doc.addEventListener(orig, handler, true); - } - dataPriv.access(doc, fix, (attaches || 0) + 1); - }, - teardown: function () { - var doc = this.ownerDocument || this, - attaches = dataPriv.access(doc, fix) - 1; - - if (!attaches) { - doc.removeEventListener(orig, handler, true); - dataPriv.remove(doc, fix); - - } else { - dataPriv.access(doc, fix, attaches); - } - } - }; - }); -} - - -var - rbracket = /\[\]$/, - rCRLF = /\r?\n/g, - rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i, - rsubmittable = /^(?:input|select|textarea|keygen)/i; - -function buildParams(prefix, obj, traditional, add) { - var name; - - if (Array.isArray(obj)) { - - // Serialize array item. - jQuery.each(obj, function (i, v) { - if (traditional || rbracket.test(prefix)) { - - // Treat each array item as a scalar. - add(prefix, v); - - } else { - - // Item is non-scalar (array or object), encode its numeric index. - buildParams( - prefix + "[" + (typeof v === "object" && v != null ? i : "") + "]", - v, - traditional, - add - ); - } - }); - - } else if (!traditional && toType(obj) === "object") { - - // Serialize object item. - for (name in obj) { - buildParams(prefix + "[" + name + "]", obj[name], traditional, add); - } - - } else { - - // Serialize scalar item. - add(prefix, obj); - } -} - -// Serialize an array of form elements or a set of -// key/values into a query string -jQuery.param = function (a, traditional) { - var prefix, - s = [], - add = function (key, valueOrFunction) { - - // If value is a function, invoke it and use its return value - var value = isFunction(valueOrFunction) ? - valueOrFunction() : - valueOrFunction; - - s[s.length] = encodeURIComponent(key) + "=" + - encodeURIComponent(value == null ? "" : value); - }; - - // If an array was passed in, assume that it is an array of form elements. - if (Array.isArray(a) || (a.jquery && !jQuery.isPlainObject(a))) { - - // Serialize the form elements - jQuery.each(a, function () { - add(this.name, this.value); - }); - - } else { - - // If traditional, encode the "old" way (the way 1.3.2 or older - // did it), otherwise encode params recursively. - for (prefix in a) { - buildParams(prefix, a[prefix], traditional, add); - } - } - - // Return the resulting serialization - return s.join("&"); -}; - -jQuery.fn.extend({ - serialize: function () { - return jQuery.param(this.serializeArray()); - }, - serializeArray: function () { - return this.map(function () { - - // Can add propHook for "elements" to filter or add form elements - var elements = jQuery.prop(this, "elements"); - return elements ? jQuery.makeArray(elements) : this; - }) - .filter(function () { - var type = this.type; - - // Use .is( ":disabled" ) so that fieldset[disabled] works - return this.name && !jQuery(this).is(":disabled") && - rsubmittable.test(this.nodeName) && !rsubmitterTypes.test(type) && - (this.checked || !rcheckableType.test(type)); - }) - .map(function (i, elem) { - var val = jQuery(this).val(); - - if (val == null) { - return null; - } - - if (Array.isArray(val)) { - return jQuery.map(val, function (val) { - return {name: elem.name, value: val.replace(rCRLF, "\r\n")}; - }); - } - - return {name: elem.name, value: val.replace(rCRLF, "\r\n")}; - }).get(); - } -}); - - -jQuery.fn.extend({ - wrapAll: function (html) { - var wrap; - - if (this[0]) { - if (isFunction(html)) { - html = html.call(this[0]); - } - - // The elements to wrap the target around - wrap = jQuery(html, this[0].ownerDocument).eq(0).clone(true); - - if (this[0].parentNode) { - wrap.insertBefore(this[0]); - } - - wrap.map(function () { - var elem = this; - - while (elem.firstElementChild) { - elem = elem.firstElementChild; - } - - return elem; - }).append(this); - } - - return this; - }, - - wrapInner: function (html) { - if (isFunction(html)) { - return this.each(function (i) { - jQuery(this).wrapInner(html.call(this, i)); - }); - } - - return this.each(function () { - var self = jQuery(this), - contents = self.contents(); - - if (contents.length) { - contents.wrapAll(html); - - } else { - self.append(html); - } - }); - }, - - wrap: function (html) { - var htmlIsFunction = isFunction(html); - - return this.each(function (i) { - jQuery(this).wrapAll(htmlIsFunction ? html.call(this, i) : html); - }); - }, - - unwrap: function (selector) { - this.parent(selector).not("body").each(function () { - jQuery(this).replaceWith(this.childNodes); - }); - return this; - } -}); - - -jQuery.expr.pseudos.hidden = function (elem) { - return !jQuery.expr.pseudos.visible(elem); -}; -jQuery.expr.pseudos.visible = function (elem) { - return !!(elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length); -}; - - -// Support: Safari 8 only -// In Safari 8 documents created via document.implementation.createHTMLDocument -// collapse sibling forms: the second one becomes a child of the first one. -// Because of that, this security measure has to be disabled in Safari 8. -// https://bugs.webkit.org/show_bug.cgi?id=137337 -support.createHTMLDocument = (function () { - var body = document$1.implementation.createHTMLDocument("").body; - body.innerHTML = "
"; - return body.childNodes.length === 2; -})(); - - -// Argument "data" should be string of html -// context (optional): If specified, the fragment will be created in this context, -// defaults to document -// keepScripts (optional): If true, will include scripts passed in the html string -jQuery.parseHTML = function (data, context, keepScripts) { - if (typeof data !== "string") { - return []; - } - if (typeof context === "boolean") { - keepScripts = context; - context = false; - } - - var base, parsed, scripts; - - if (!context) { - - // Stop scripts or inline event handlers from being executed immediately - // by using document.implementation - if (support.createHTMLDocument) { - context = document$1.implementation.createHTMLDocument(""); - - // Set the base href for the created document - // so any parsed elements with URLs - // are based on the document's URL (gh-2965) - base = context.createElement("base"); - base.href = document$1.location.href; - context.head.appendChild(base); - } else { - context = document$1; - } - } - - parsed = rsingleTag.exec(data); - scripts = !keepScripts && []; - - // Single tag - if (parsed) { - return [context.createElement(parsed[1])]; - } - - parsed = buildFragment([data], context, scripts); - - if (scripts && scripts.length) { - jQuery(scripts).remove(); - } - - return jQuery.merge([], parsed.childNodes); -}; - - -jQuery.offset = { - setOffset: function (elem, options, i) { - var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition, - position = jQuery.css(elem, "position"), - curElem = jQuery(elem), - props = {}; - - // Set position first, in-case top/left are set even on static elem - if (position === "static") { - elem.style.position = "relative"; - } - - curOffset = curElem.offset(); - curCSSTop = jQuery.css(elem, "top"); - curCSSLeft = jQuery.css(elem, "left"); - calculatePosition = (position === "absolute" || position === "fixed") && - (curCSSTop + curCSSLeft).indexOf("auto") > -1; - - // Need to be able to calculate position if either - // top or left is auto and position is either absolute or fixed - if (calculatePosition) { - curPosition = curElem.position(); - curTop = curPosition.top; - curLeft = curPosition.left; - - } else { - curTop = parseFloat(curCSSTop) || 0; - curLeft = parseFloat(curCSSLeft) || 0; - } - - if (isFunction(options)) { - - // Use jQuery.extend here to allow modification of coordinates argument (gh-1848) - options = options.call(elem, i, jQuery.extend({}, curOffset)); - } - - if (options.top != null) { - props.top = (options.top - curOffset.top) + curTop; - } - if (options.left != null) { - props.left = (options.left - curOffset.left) + curLeft; - } - - if ("using" in options) { - options.using.call(elem, props); - - } else { - curElem.css(props); - } - } -}; - -jQuery.fn.extend({ - - // offset() relates an element's border box to the document origin - offset: function (options) { - - // Preserve chaining for setter - if (arguments.length) { - return options === undefined ? - this : - this.each(function (i) { - jQuery.offset.setOffset(this, options, i); - }); - } - - var rect, win, - elem = this[0]; - - if (!elem) { - return; - } - - // Return zeros for disconnected and hidden (display: none) elements (gh-2310) - // Support: IE <=11 only - // Running getBoundingClientRect on a - // disconnected node in IE throws an error - if (!elem.getClientRects().length) { - return {top: 0, left: 0}; - } - - // Get document-relative position by adding viewport scroll to viewport-relative gBCR - rect = elem.getBoundingClientRect(); - win = elem.ownerDocument.defaultView; - return { - top: rect.top + win.pageYOffset, - left: rect.left + win.pageXOffset - }; - }, - - // position() relates an element's margin box to its offset parent's padding box - // This corresponds to the behavior of CSS absolute positioning - position: function () { - if (!this[0]) { - return; - } - - var offsetParent, offset, doc, - elem = this[0], - parentOffset = {top: 0, left: 0}; - - // position:fixed elements are offset from the viewport, which itself always has zero offset - if (jQuery.css(elem, "position") === "fixed") { - - // Assume position:fixed implies availability of getBoundingClientRect - offset = elem.getBoundingClientRect(); - - } else { - offset = this.offset(); - - // Account for the *real* offset parent, which can be the document or its root element - // when a statically positioned element is identified - doc = elem.ownerDocument; - offsetParent = elem.offsetParent || doc.documentElement; - while (offsetParent && - (offsetParent === doc.body || offsetParent === doc.documentElement) && - jQuery.css(offsetParent, "position") === "static") { - - offsetParent = offsetParent.parentNode; - } - if (offsetParent && offsetParent !== elem && offsetParent.nodeType === 1) { - - // Incorporate borders into its offset, since they are outside its content origin - parentOffset = jQuery(offsetParent).offset(); - parentOffset.top += jQuery.css(offsetParent, "borderTopWidth", true); - parentOffset.left += jQuery.css(offsetParent, "borderLeftWidth", true); - } - } - - // Subtract parent offsets and element margins - return { - top: offset.top - parentOffset.top - jQuery.css(elem, "marginTop", true), - left: offset.left - parentOffset.left - jQuery.css(elem, "marginLeft", true) - }; - }, - - // This method will return documentElement in the following cases: - // 1) For the element inside the iframe without offsetParent, this method will return - // documentElement of the parent window - // 2) For the hidden or detached element - // 3) For body or html element, i.e. in case of the html node - it will return itself - // - // but those exceptions were never presented as a real life use-cases - // and might be considered as more preferable results. - // - // This logic, however, is not guaranteed and can change at any point in the future - offsetParent: function () { - return this.map(function () { - var offsetParent = this.offsetParent; - - while (offsetParent && jQuery.css(offsetParent, "position") === "static") { - offsetParent = offsetParent.offsetParent; - } - - return offsetParent || documentElement; - }); - } -}); - -// Create scrollLeft and scrollTop methods -jQuery.each({scrollLeft: "pageXOffset", scrollTop: "pageYOffset"}, function (method, prop) { - var top = "pageYOffset" === prop; - - jQuery.fn[method] = function (val) { - return access(this, function (elem, method, val) { - - // Coalesce documents and windows - var win; - if (isWindow(elem)) { - win = elem; - } else if (elem.nodeType === 9) { - win = elem.defaultView; - } - - if (val === undefined) { - return win ? win[prop] : elem[method]; - } - - if (win) { - win.scrollTo( - !top ? val : win.pageXOffset, - top ? val : win.pageYOffset - ); - - } else { - elem[method] = val; - } - }, method, val, arguments.length); - }; -}); - -// Support: Safari <=7 - 9.1, Chrome <=37 - 49 -// Add the top/left cssHooks using jQuery.fn.position -// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084 -// Blink bug: https://bugs.chromium.org/p/chromium/issues/detail?id=589347 -// getComputedStyle returns percent when specified for top/left/bottom/right; -// rather than make the css module depend on the offset module, just check for it here -jQuery.each(["top", "left"], function (i, prop) { - jQuery.cssHooks[prop] = addGetHookIf(support.pixelPosition, - function (elem, computed) { - if (computed) { - computed = curCSS(elem, prop); - - // If curCSS returns percentage, fallback to offset - return rnumnonpx.test(computed) ? - jQuery(elem).position()[prop] + "px" : - computed; - } - } - ); -}); - - -// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods -jQuery.each({Height: "height", Width: "width"}, function (name, type) { - jQuery.each({padding: "inner" + name, content: type, "": "outer" + name}, - function (defaultExtra, funcName) { - - // Margin is only for outerHeight, outerWidth - jQuery.fn[funcName] = function (margin, value) { - var chainable = arguments.length && (defaultExtra || typeof margin !== "boolean"), - extra = defaultExtra || (margin === true || value === true ? "margin" : "border"); - - return access(this, function (elem, type, value) { - var doc; - - if (isWindow(elem)) { - - // $( window ).outerWidth/Height return w/h including scrollbars (gh-1729) - return funcName.indexOf("outer") === 0 ? - elem["inner" + name] : - elem.document.documentElement["client" + name]; - } - - // Get document width or height - if (elem.nodeType === 9) { - doc = elem.documentElement; - - // Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height], - // whichever is greatest - return Math.max( - elem.body["scroll" + name], doc["scroll" + name], - elem.body["offset" + name], doc["offset" + name], - doc["client" + name] - ); - } - - return value === undefined ? - - // Get width or height on the element, requesting but not forcing parseFloat - jQuery.css(elem, type, extra) : - - // Set width or height on the element - jQuery.style(elem, type, value, extra); - }, type, chainable ? margin : undefined, chainable); - }; - }); -}); - - -jQuery.each(("blur focus focusin focusout resize scroll click dblclick " + - "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " + - "change select submit keydown keypress keyup contextmenu").split(" "), - function (i, name) { - - // Handle event binding - jQuery.fn[name] = function (data, fn) { - return arguments.length > 0 ? - this.on(name, null, data, fn) : - this.trigger(name); - }; - }); - -jQuery.fn.extend({ - hover: function (fnOver, fnOut) { - return this.mouseenter(fnOver).mouseleave(fnOut || fnOver); - } -}); - - -jQuery.fn.extend({ - - bind: function (types, data, fn) { - return this.on(types, null, data, fn); - }, - unbind: function (types, fn) { - return this.off(types, null, fn); - }, - - delegate: function (selector, types, data, fn) { - return this.on(types, selector, data, fn); - }, - undelegate: function (selector, types, fn) { - - // ( namespace ) or ( selector, types [, fn] ) - return arguments.length === 1 ? - this.off(selector, "**") : - this.off(types, selector || "**", fn); - } -}); - -// Bind a function to a context, optionally partially applying any -// arguments. -// jQuery.proxy is deprecated to promote standards (specifically Function#bind) -// However, it is not slated for removal any time soon -jQuery.proxy = function (fn, context) { - var tmp, args, proxy; - - if (typeof context === "string") { - tmp = fn[context]; - context = fn; - fn = tmp; - } - - // Quick check to determine if target is callable, in the spec - // this throws a TypeError, but we will just return undefined. - if (!isFunction(fn)) { - return undefined; - } - - // Simulated bind - args = slice.call(arguments, 2); - proxy = function () { - return fn.apply(context || this, args.concat(slice.call(arguments))); - }; - - // Set the guid of unique handler to the same of original handler, so it can be removed - proxy.guid = fn.guid = fn.guid || jQuery.guid++; - - return proxy; -}; - -jQuery.holdReady = function (hold) { - if (hold) { - jQuery.readyWait++; - } else { - jQuery.ready(true); - } -}; -jQuery.isArray = Array.isArray; -jQuery.parseJSON = JSON.parse; -jQuery.nodeName = nodeName; -jQuery.isFunction = isFunction; -jQuery.isWindow = isWindow; -jQuery.camelCase = camelCase; -jQuery.type = toType; - -jQuery.now = Date.now; - -jQuery.isNumeric = function (obj) { - - // As of jQuery 3.0, isNumeric is limited to - // strings and numbers (primitives or objects) - // that can be coerced to finite numbers (gh-2662) - var type = jQuery.type(obj); - return (type === "number" || type === "string") && - - // parseFloat NaNs numeric-cast false positives ("") - // ...but misinterprets leading-number strings, particularly hex literals ("0x...") - // subtraction forces infinities to NaN - !isNaN(obj - parseFloat(obj)); -}; - -const $$1 = jQuery; - -function div$1(options) { - return create$1("div", options); -} - -function create$1(tag, options) { - const elem = document.createElement(tag); - if (options) { - if (options.class) { - elem.classList.add(options.class); - } - if (options.id) { - elem.id = options.id; - } - if(options.style) { - applyStyle$1(elem, options.style); - } - } - return elem; -} - -function hide$1(elem) { - const cssStyle = getComputedStyle(elem); - if(cssStyle.display !== "none") { - elem._initialDisplay = cssStyle.display; - } - elem.style.display = "none"; -} - -function show$1(elem) { - const currentDisplay = getComputedStyle(elem).display; - if (currentDisplay === "none") { - const d = elem._initialDisplay || "block"; - elem.style.display = d; - } -} - -function hideAll$1(selector) { - document.querySelectorAll(selector).forEach(elem => { hide$1(elem); }); -} - -function empty$1(elem) { - while(elem.firstChild){ - elem.removeChild(elem.firstChild); - } -} - -function offset$1(elem) { - // Return zeros for disconnected and hidden (display: none) elements (gh-2310) - // Support: IE <=11 only - // Running getBoundingClientRect on a - // disconnected node in IE throws an error - if (!elem.getClientRects().length) { - return {top: 0, left: 0}; - } - - // Get document-relative position by adding viewport scroll to viewport-relative gBCR - const rect = elem.getBoundingClientRect(); - const win = elem.ownerDocument.defaultView; - return { - top: rect.top + win.pageYOffset, - left: rect.left + win.pageXOffset - }; -} - -function pageCoordinates$1(e) { - - if (e.type.startsWith("touch")) { - const touch = e.touches[0]; - return {x: touch.pageX, y: touch.pageY}; - } else { - return {x: e.pageX, y: e.pageY} - } -} - -const relativeDOMBBox$1 = (parentElement, childElement) => { - const { x: x_p, y: y_p, width: width_p, height: height_p } = parentElement.getBoundingClientRect(); - const { x: x_c, y: y_c, width: width_c, height: height_c } = childElement.getBoundingClientRect(); - return { x: (x_c - x_p), y: (y_c - y_p), width: width_c, height:height_c }; -}; - -function applyStyle$1(elem, style) { - for (let key of Object.keys(style)) { - elem.style[key] = style[key]; - } -} - -function guid$2 () { - return ("0000" + (Math.random() * Math.pow(36, 4) << 0).toString(36)).slice(-4); -} - -let getMouseXY$1 = (domElement, { clientX, clientY }) => { - - // DOMRect object with eight properties: left, top, right, bottom, x, y, width, height - const { left, top, width, height } = domElement.getBoundingClientRect(); - - const x = clientX - left; - const y = clientY - top; - return { x, y, xNormalized: x/width, yNormalized: y/height, width, height }; - -}; - -/** - * Translate the mouse coordinates for the event to the coordinates for the given target element - * @param event - * @param domElement - * @returns {{x: number, y: number}} - */ -function translateMouseCoordinates$1(event, domElement) { - - const { clientX, clientY } = event; - return getMouseXY$1(domElement, { clientX, clientY }); - -} - -var domUtils$1 = /*#__PURE__*/Object.freeze({ - __proto__: null, - applyStyle: applyStyle$1, - create: create$1, - div: div$1, - empty: empty$1, - guid: guid$2, - hide: hide$1, - hideAll: hideAll$1, - offset: offset$1, - pageCoordinates: pageCoordinates$1, - relativeDOMBBox: relativeDOMBBox$1, - show: show$1, - translateMouseCoordinates: translateMouseCoordinates$1 -}); - -/*! @license DOMPurify 3.0.5 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/3.0.5/LICENSE */ - -const { - entries, - setPrototypeOf, - isFrozen, - getPrototypeOf, - getOwnPropertyDescriptor -} = Object; -let { - freeze, - seal, - create: create$2 -} = Object; // eslint-disable-line import/no-mutable-exports - -let { - apply, - construct -} = typeof Reflect !== 'undefined' && Reflect; - -if (!apply) { - apply = function apply(fun, thisValue, args) { - return fun.apply(thisValue, args); - }; -} - -if (!freeze) { - freeze = function freeze(x) { - return x; - }; -} - -if (!seal) { - seal = function seal(x) { - return x; - }; -} - -if (!construct) { - construct = function construct(Func, args) { - return new Func(...args); - }; -} - -const arrayForEach = unapply(Array.prototype.forEach); -const arrayPop = unapply(Array.prototype.pop); -const arrayPush = unapply(Array.prototype.push); -const stringToLowerCase = unapply(String.prototype.toLowerCase); -const stringToString = unapply(String.prototype.toString); -const stringMatch = unapply(String.prototype.match); -const stringReplace = unapply(String.prototype.replace); -const stringIndexOf = unapply(String.prototype.indexOf); -const stringTrim = unapply(String.prototype.trim); -const regExpTest = unapply(RegExp.prototype.test); -const typeErrorCreate = unconstruct(TypeError); -function unapply(func) { - return function (thisArg) { - for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { - args[_key - 1] = arguments[_key]; - } - - return apply(func, thisArg, args); - }; -} -function unconstruct(func) { - return function () { - for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { - args[_key2] = arguments[_key2]; - } - - return construct(func, args); - }; -} -/* Add properties to a lookup table */ - -function addToSet(set, array, transformCaseFunc) { - var _transformCaseFunc; - - transformCaseFunc = (_transformCaseFunc = transformCaseFunc) !== null && _transformCaseFunc !== void 0 ? _transformCaseFunc : stringToLowerCase; - - if (setPrototypeOf) { - // Make 'in' and truthy checks like Boolean(set.constructor) - // independent of any properties defined on Object.prototype. - // Prevent prototype setters from intercepting set as a this value. - setPrototypeOf(set, null); - } - - let l = array.length; - - while (l--) { - let element = array[l]; - - if (typeof element === 'string') { - const lcElement = transformCaseFunc(element); - - if (lcElement !== element) { - // Config presets (e.g. tags.js, attrs.js) are immutable. - if (!isFrozen(array)) { - array[l] = lcElement; - } - - element = lcElement; - } - } - - set[element] = true; - } - - return set; -} -/* Shallow clone an object */ - -function clone(object) { - const newObject = create$2(null); - - for (const [property, value] of entries(object)) { - newObject[property] = value; - } - - return newObject; -} -/* This method automatically checks if the prop is function - * or getter and behaves accordingly. */ - -function lookupGetter(object, prop) { - while (object !== null) { - const desc = getOwnPropertyDescriptor(object, prop); - - if (desc) { - if (desc.get) { - return unapply(desc.get); - } - - if (typeof desc.value === 'function') { - return unapply(desc.value); - } - } - - object = getPrototypeOf(object); - } - - function fallbackValue(element) { - console.warn('fallback value for', element); - return null; - } - - return fallbackValue; -} - -const html$1 = freeze(['a', 'abbr', 'acronym', 'address', 'area', 'article', 'aside', 'audio', 'b', 'bdi', 'bdo', 'big', 'blink', 'blockquote', 'body', 'br', 'button', 'canvas', 'caption', 'center', 'cite', 'code', 'col', 'colgroup', 'content', 'data', 'datalist', 'dd', 'decorator', 'del', 'details', 'dfn', 'dialog', 'dir', 'div', 'dl', 'dt', 'element', 'em', 'fieldset', 'figcaption', 'figure', 'font', 'footer', 'form', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'header', 'hgroup', 'hr', 'html', 'i', 'img', 'input', 'ins', 'kbd', 'label', 'legend', 'li', 'main', 'map', 'mark', 'marquee', 'menu', 'menuitem', 'meter', 'nav', 'nobr', 'ol', 'optgroup', 'option', 'output', 'p', 'picture', 'pre', 'progress', 'q', 'rp', 'rt', 'ruby', 's', 'samp', 'section', 'select', 'shadow', 'small', 'source', 'spacer', 'span', 'strike', 'strong', 'style', 'sub', 'summary', 'sup', 'table', 'tbody', 'td', 'template', 'textarea', 'tfoot', 'th', 'thead', 'time', 'tr', 'track', 'tt', 'u', 'ul', 'var', 'video', 'wbr']); // SVG - -const svg$1 = freeze(['svg', 'a', 'altglyph', 'altglyphdef', 'altglyphitem', 'animatecolor', 'animatemotion', 'animatetransform', 'circle', 'clippath', 'defs', 'desc', 'ellipse', 'filter', 'font', 'g', 'glyph', 'glyphref', 'hkern', 'image', 'line', 'lineargradient', 'marker', 'mask', 'metadata', 'mpath', 'path', 'pattern', 'polygon', 'polyline', 'radialgradient', 'rect', 'stop', 'style', 'switch', 'symbol', 'text', 'textpath', 'title', 'tref', 'tspan', 'view', 'vkern']); -const svgFilters = freeze(['feBlend', 'feColorMatrix', 'feComponentTransfer', 'feComposite', 'feConvolveMatrix', 'feDiffuseLighting', 'feDisplacementMap', 'feDistantLight', 'feDropShadow', 'feFlood', 'feFuncA', 'feFuncB', 'feFuncG', 'feFuncR', 'feGaussianBlur', 'feImage', 'feMerge', 'feMergeNode', 'feMorphology', 'feOffset', 'fePointLight', 'feSpecularLighting', 'feSpotLight', 'feTile', 'feTurbulence']); // List of SVG elements that are disallowed by default. -// We still need to know them so that we can do namespace -// checks properly in case one wants to add them to -// allow-list. - -const svgDisallowed = freeze(['animate', 'color-profile', 'cursor', 'discard', 'font-face', 'font-face-format', 'font-face-name', 'font-face-src', 'font-face-uri', 'foreignobject', 'hatch', 'hatchpath', 'mesh', 'meshgradient', 'meshpatch', 'meshrow', 'missing-glyph', 'script', 'set', 'solidcolor', 'unknown', 'use']); -const mathMl$1 = freeze(['math', 'menclose', 'merror', 'mfenced', 'mfrac', 'mglyph', 'mi', 'mlabeledtr', 'mmultiscripts', 'mn', 'mo', 'mover', 'mpadded', 'mphantom', 'mroot', 'mrow', 'ms', 'mspace', 'msqrt', 'mstyle', 'msub', 'msup', 'msubsup', 'mtable', 'mtd', 'mtext', 'mtr', 'munder', 'munderover', 'mprescripts']); // Similarly to SVG, we want to know all MathML elements, -// even those that we disallow by default. - -const mathMlDisallowed = freeze(['maction', 'maligngroup', 'malignmark', 'mlongdiv', 'mscarries', 'mscarry', 'msgroup', 'mstack', 'msline', 'msrow', 'semantics', 'annotation', 'annotation-xml', 'mprescripts', 'none']); -const text = freeze(['#text']); - -const html = freeze(['accept', 'action', 'align', 'alt', 'autocapitalize', 'autocomplete', 'autopictureinpicture', 'autoplay', 'background', 'bgcolor', 'border', 'capture', 'cellpadding', 'cellspacing', 'checked', 'cite', 'class', 'clear', 'color', 'cols', 'colspan', 'controls', 'controlslist', 'coords', 'crossorigin', 'datetime', 'decoding', 'default', 'dir', 'disabled', 'disablepictureinpicture', 'disableremoteplayback', 'download', 'draggable', 'enctype', 'enterkeyhint', 'face', 'for', 'headers', 'height', 'hidden', 'high', 'href', 'hreflang', 'id', 'inputmode', 'integrity', 'ismap', 'kind', 'label', 'lang', 'list', 'loading', 'loop', 'low', 'max', 'maxlength', 'media', 'method', 'min', 'minlength', 'multiple', 'muted', 'name', 'nonce', 'noshade', 'novalidate', 'nowrap', 'open', 'optimum', 'pattern', 'placeholder', 'playsinline', 'poster', 'preload', 'pubdate', 'radiogroup', 'readonly', 'rel', 'required', 'rev', 'reversed', 'role', 'rows', 'rowspan', 'spellcheck', 'scope', 'selected', 'shape', 'size', 'sizes', 'span', 'srclang', 'start', 'src', 'srcset', 'step', 'style', 'summary', 'tabindex', 'title', 'translate', 'type', 'usemap', 'valign', 'value', 'width', 'xmlns', 'slot']); -const svg = freeze(['accent-height', 'accumulate', 'additive', 'alignment-baseline', 'ascent', 'attributename', 'attributetype', 'azimuth', 'basefrequency', 'baseline-shift', 'begin', 'bias', 'by', 'class', 'clip', 'clippathunits', 'clip-path', 'clip-rule', 'color', 'color-interpolation', 'color-interpolation-filters', 'color-profile', 'color-rendering', 'cx', 'cy', 'd', 'dx', 'dy', 'diffuseconstant', 'direction', 'display', 'divisor', 'dur', 'edgemode', 'elevation', 'end', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'filterunits', 'flood-color', 'flood-opacity', 'font-family', 'font-size', 'font-size-adjust', 'font-stretch', 'font-style', 'font-variant', 'font-weight', 'fx', 'fy', 'g1', 'g2', 'glyph-name', 'glyphref', 'gradientunits', 'gradienttransform', 'height', 'href', 'id', 'image-rendering', 'in', 'in2', 'k', 'k1', 'k2', 'k3', 'k4', 'kerning', 'keypoints', 'keysplines', 'keytimes', 'lang', 'lengthadjust', 'letter-spacing', 'kernelmatrix', 'kernelunitlength', 'lighting-color', 'local', 'marker-end', 'marker-mid', 'marker-start', 'markerheight', 'markerunits', 'markerwidth', 'maskcontentunits', 'maskunits', 'max', 'mask', 'media', 'method', 'mode', 'min', 'name', 'numoctaves', 'offset', 'operator', 'opacity', 'order', 'orient', 'orientation', 'origin', 'overflow', 'paint-order', 'path', 'pathlength', 'patterncontentunits', 'patterntransform', 'patternunits', 'points', 'preservealpha', 'preserveaspectratio', 'primitiveunits', 'r', 'rx', 'ry', 'radius', 'refx', 'refy', 'repeatcount', 'repeatdur', 'restart', 'result', 'rotate', 'scale', 'seed', 'shape-rendering', 'specularconstant', 'specularexponent', 'spreadmethod', 'startoffset', 'stddeviation', 'stitchtiles', 'stop-color', 'stop-opacity', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke', 'stroke-width', 'style', 'surfacescale', 'systemlanguage', 'tabindex', 'targetx', 'targety', 'transform', 'transform-origin', 'text-anchor', 'text-decoration', 'text-rendering', 'textlength', 'type', 'u1', 'u2', 'unicode', 'values', 'viewbox', 'visibility', 'version', 'vert-adv-y', 'vert-origin-x', 'vert-origin-y', 'width', 'word-spacing', 'wrap', 'writing-mode', 'xchannelselector', 'ychannelselector', 'x', 'x1', 'x2', 'xmlns', 'y', 'y1', 'y2', 'z', 'zoomandpan']); -const mathMl = freeze(['accent', 'accentunder', 'align', 'bevelled', 'close', 'columnsalign', 'columnlines', 'columnspan', 'denomalign', 'depth', 'dir', 'display', 'displaystyle', 'encoding', 'fence', 'frame', 'height', 'href', 'id', 'largeop', 'length', 'linethickness', 'lspace', 'lquote', 'mathbackground', 'mathcolor', 'mathsize', 'mathvariant', 'maxsize', 'minsize', 'movablelimits', 'notation', 'numalign', 'open', 'rowalign', 'rowlines', 'rowspacing', 'rowspan', 'rspace', 'rquote', 'scriptlevel', 'scriptminsize', 'scriptsizemultiplier', 'selection', 'separator', 'separators', 'stretchy', 'subscriptshift', 'supscriptshift', 'symmetric', 'voffset', 'width', 'xmlns']); -const xml = freeze(['xlink:href', 'xml:id', 'xlink:title', 'xml:space', 'xmlns:xlink']); - -const MUSTACHE_EXPR = seal(/\{\{[\w\W]*|[\w\W]*\}\}/gm); // Specify template detection regex for SAFE_FOR_TEMPLATES mode - -const ERB_EXPR = seal(/<%[\w\W]*|[\w\W]*%>/gm); -const TMPLIT_EXPR = seal(/\${[\w\W]*}/gm); -const DATA_ATTR = seal(/^data-[\-\w.\u00B7-\uFFFF]/); // eslint-disable-line no-useless-escape - -const ARIA_ATTR = seal(/^aria-[\-\w]+$/); // eslint-disable-line no-useless-escape - -const IS_ALLOWED_URI = seal(/^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i // eslint-disable-line no-useless-escape -); -const IS_SCRIPT_OR_DATA = seal(/^(?:\w+script|data):/i); -const ATTR_WHITESPACE = seal(/[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g // eslint-disable-line no-control-regex -); -const DOCTYPE_NAME = seal(/^html$/i); - -var EXPRESSIONS = /*#__PURE__*/Object.freeze({ - __proto__: null, - MUSTACHE_EXPR: MUSTACHE_EXPR, - ERB_EXPR: ERB_EXPR, - TMPLIT_EXPR: TMPLIT_EXPR, - DATA_ATTR: DATA_ATTR, - ARIA_ATTR: ARIA_ATTR, - IS_ALLOWED_URI: IS_ALLOWED_URI, - IS_SCRIPT_OR_DATA: IS_SCRIPT_OR_DATA, - ATTR_WHITESPACE: ATTR_WHITESPACE, - DOCTYPE_NAME: DOCTYPE_NAME -}); - -const getGlobal = () => typeof window === 'undefined' ? null : window; -/** - * Creates a no-op policy for internal use only. - * Don't export this function outside this module! - * @param {?TrustedTypePolicyFactory} trustedTypes The policy factory. - * @param {HTMLScriptElement} purifyHostElement The Script element used to load DOMPurify (to determine policy name suffix). - * @return {?TrustedTypePolicy} The policy created (or null, if Trusted Types - * are not supported or creating the policy failed). - */ - - -const _createTrustedTypesPolicy = function _createTrustedTypesPolicy(trustedTypes, purifyHostElement) { - if (typeof trustedTypes !== 'object' || typeof trustedTypes.createPolicy !== 'function') { - return null; - } // Allow the callers to control the unique policy name - // by adding a data-tt-policy-suffix to the script element with the DOMPurify. - // Policy creation with duplicate names throws in Trusted Types. - - - let suffix = null; - const ATTR_NAME = 'data-tt-policy-suffix'; - - if (purifyHostElement && purifyHostElement.hasAttribute(ATTR_NAME)) { - suffix = purifyHostElement.getAttribute(ATTR_NAME); - } - - const policyName = 'dompurify' + (suffix ? '#' + suffix : ''); - - try { - return trustedTypes.createPolicy(policyName, { - createHTML(html) { - return html; - }, - - createScriptURL(scriptUrl) { - return scriptUrl; - } - - }); - } catch (_) { - // Policy creation failed (most likely another DOMPurify script has - // already run). Skip creating the policy, as this will only cause errors - // if TT are enforced. - console.warn('TrustedTypes policy ' + policyName + ' could not be created.'); - return null; - } -}; - -function createDOMPurify() { - let window = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : getGlobal(); - - const DOMPurify = root => createDOMPurify(root); - /** - * Version label, exposed for easier checks - * if DOMPurify is up to date or not - */ - - - DOMPurify.version = '3.0.5'; - /** - * Array of elements that DOMPurify removed during sanitation. - * Empty if nothing was removed. - */ - - DOMPurify.removed = []; - - if (!window || !window.document || window.document.nodeType !== 9) { - // Not running in a browser, provide a factory function - // so that you can pass your own Window - DOMPurify.isSupported = false; - return DOMPurify; - } - - const originalDocument = window.document; - const currentScript = originalDocument.currentScript; - let { - document - } = window; - const { - DocumentFragment, - HTMLTemplateElement, - Node, - Element, - NodeFilter, - NamedNodeMap = window.NamedNodeMap || window.MozNamedAttrMap, - HTMLFormElement, - DOMParser, - trustedTypes - } = window; - const ElementPrototype = Element.prototype; - const cloneNode = lookupGetter(ElementPrototype, 'cloneNode'); - const getNextSibling = lookupGetter(ElementPrototype, 'nextSibling'); - const getChildNodes = lookupGetter(ElementPrototype, 'childNodes'); - const getParentNode = lookupGetter(ElementPrototype, 'parentNode'); // As per issue #47, the web-components registry is inherited by a - // new document created via createHTMLDocument. As per the spec - // (http://w3c.github.io/webcomponents/spec/custom/#creating-and-passing-registries) - // a new empty registry is used when creating a template contents owner - // document, so we use that as our parent document to ensure nothing - // is inherited. - - if (typeof HTMLTemplateElement === 'function') { - const template = document.createElement('template'); - - if (template.content && template.content.ownerDocument) { - document = template.content.ownerDocument; - } - } - - let trustedTypesPolicy; - let emptyHTML = ''; - const { - implementation, - createNodeIterator, - createDocumentFragment, - getElementsByTagName - } = document; - const { - importNode - } = originalDocument; - let hooks = {}; - /** - * Expose whether this browser supports running the full DOMPurify. - */ - - DOMPurify.isSupported = typeof entries === 'function' && typeof getParentNode === 'function' && implementation && implementation.createHTMLDocument !== undefined; - const { - MUSTACHE_EXPR, - ERB_EXPR, - TMPLIT_EXPR, - DATA_ATTR, - ARIA_ATTR, - IS_SCRIPT_OR_DATA, - ATTR_WHITESPACE - } = EXPRESSIONS; - let { - IS_ALLOWED_URI: IS_ALLOWED_URI$1 - } = EXPRESSIONS; - /** - * We consider the elements and attributes below to be safe. Ideally - * don't add any new ones but feel free to remove unwanted ones. - */ - - /* allowed element names */ - - let ALLOWED_TAGS = null; - const DEFAULT_ALLOWED_TAGS = addToSet({}, [...html$1, ...svg$1, ...svgFilters, ...mathMl$1, ...text]); - /* Allowed attribute names */ - - let ALLOWED_ATTR = null; - const DEFAULT_ALLOWED_ATTR = addToSet({}, [...html, ...svg, ...mathMl, ...xml]); - /* - * Configure how DOMPUrify should handle custom elements and their attributes as well as customized built-in elements. - * @property {RegExp|Function|null} tagNameCheck one of [null, regexPattern, predicate]. Default: `null` (disallow any custom elements) - * @property {RegExp|Function|null} attributeNameCheck one of [null, regexPattern, predicate]. Default: `null` (disallow any attributes not on the allow list) - * @property {boolean} allowCustomizedBuiltInElements allow custom elements derived from built-ins if they pass CUSTOM_ELEMENT_HANDLING.tagNameCheck. Default: `false`. - */ - - let CUSTOM_ELEMENT_HANDLING = Object.seal(Object.create(null, { - tagNameCheck: { - writable: true, - configurable: false, - enumerable: true, - value: null - }, - attributeNameCheck: { - writable: true, - configurable: false, - enumerable: true, - value: null - }, - allowCustomizedBuiltInElements: { - writable: true, - configurable: false, - enumerable: true, - value: false - } - })); - /* Explicitly forbidden tags (overrides ALLOWED_TAGS/ADD_TAGS) */ - - let FORBID_TAGS = null; - /* Explicitly forbidden attributes (overrides ALLOWED_ATTR/ADD_ATTR) */ - - let FORBID_ATTR = null; - /* Decide if ARIA attributes are okay */ - - let ALLOW_ARIA_ATTR = true; - /* Decide if custom data attributes are okay */ - - let ALLOW_DATA_ATTR = true; - /* Decide if unknown protocols are okay */ - - let ALLOW_UNKNOWN_PROTOCOLS = false; - /* Decide if self-closing tags in attributes are allowed. - * Usually removed due to a mXSS issue in jQuery 3.0 */ - - let ALLOW_SELF_CLOSE_IN_ATTR = true; - /* Output should be safe for common template engines. - * This means, DOMPurify removes data attributes, mustaches and ERB - */ - - let SAFE_FOR_TEMPLATES = false; - /* Decide if document with ... should be returned */ - - let WHOLE_DOCUMENT = false; - /* Track whether config is already set on this instance of DOMPurify. */ - - let SET_CONFIG = false; - /* Decide if all elements (e.g. style, script) must be children of - * document.body. By default, browsers might move them to document.head */ - - let FORCE_BODY = false; - /* Decide if a DOM `HTMLBodyElement` should be returned, instead of a html - * string (or a TrustedHTML object if Trusted Types are supported). - * If `WHOLE_DOCUMENT` is enabled a `HTMLHtmlElement` will be returned instead - */ - - let RETURN_DOM = false; - /* Decide if a DOM `DocumentFragment` should be returned, instead of a html - * string (or a TrustedHTML object if Trusted Types are supported) */ - - let RETURN_DOM_FRAGMENT = false; - /* Try to return a Trusted Type object instead of a string, return a string in - * case Trusted Types are not supported */ - - let RETURN_TRUSTED_TYPE = false; - /* Output should be free from DOM clobbering attacks? - * This sanitizes markups named with colliding, clobberable built-in DOM APIs. - */ - - let SANITIZE_DOM = true; - /* Achieve full DOM Clobbering protection by isolating the namespace of named - * properties and JS variables, mitigating attacks that abuse the HTML/DOM spec rules. - * - * HTML/DOM spec rules that enable DOM Clobbering: - * - Named Access on Window (§7.3.3) - * - DOM Tree Accessors (§3.1.5) - * - Form Element Parent-Child Relations (§4.10.3) - * - Iframe srcdoc / Nested WindowProxies (§4.8.5) - * - HTMLCollection (§4.2.10.2) - * - * Namespace isolation is implemented by prefixing `id` and `name` attributes - * with a constant string, i.e., `user-content-` - */ - - let SANITIZE_NAMED_PROPS = false; - const SANITIZE_NAMED_PROPS_PREFIX = 'user-content-'; - /* Keep element content when removing element? */ - - let KEEP_CONTENT = true; - /* If a `Node` is passed to sanitize(), then performs sanitization in-place instead - * of importing it into a new Document and returning a sanitized copy */ - - let IN_PLACE = false; - /* Allow usage of profiles like html, svg and mathMl */ - - let USE_PROFILES = {}; - /* Tags to ignore content of when KEEP_CONTENT is true */ - - let FORBID_CONTENTS = null; - const DEFAULT_FORBID_CONTENTS = addToSet({}, ['annotation-xml', 'audio', 'colgroup', 'desc', 'foreignobject', 'head', 'iframe', 'math', 'mi', 'mn', 'mo', 'ms', 'mtext', 'noembed', 'noframes', 'noscript', 'plaintext', 'script', 'style', 'svg', 'template', 'thead', 'title', 'video', 'xmp']); - /* Tags that are safe for data: URIs */ - - let DATA_URI_TAGS = null; - const DEFAULT_DATA_URI_TAGS = addToSet({}, ['audio', 'video', 'img', 'source', 'image', 'track']); - /* Attributes safe for values like "javascript:" */ - - let URI_SAFE_ATTRIBUTES = null; - const DEFAULT_URI_SAFE_ATTRIBUTES = addToSet({}, ['alt', 'class', 'for', 'id', 'label', 'name', 'pattern', 'placeholder', 'role', 'summary', 'title', 'value', 'style', 'xmlns']); - const MATHML_NAMESPACE = 'http://www.w3.org/1998/Math/MathML'; - const SVG_NAMESPACE = 'http://www.w3.org/2000/svg'; - const HTML_NAMESPACE = 'http://www.w3.org/1999/xhtml'; - /* Document namespace */ - - let NAMESPACE = HTML_NAMESPACE; - let IS_EMPTY_INPUT = false; - /* Allowed XHTML+XML namespaces */ - - let ALLOWED_NAMESPACES = null; - const DEFAULT_ALLOWED_NAMESPACES = addToSet({}, [MATHML_NAMESPACE, SVG_NAMESPACE, HTML_NAMESPACE], stringToString); - /* Parsing of strict XHTML documents */ - - let PARSER_MEDIA_TYPE; - const SUPPORTED_PARSER_MEDIA_TYPES = ['application/xhtml+xml', 'text/html']; - const DEFAULT_PARSER_MEDIA_TYPE = 'text/html'; - let transformCaseFunc; - /* Keep a reference to config to pass to hooks */ - - let CONFIG = null; - /* Ideally, do not touch anything below this line */ - - /* ______________________________________________ */ - - const formElement = document.createElement('form'); - - const isRegexOrFunction = function isRegexOrFunction(testValue) { - return testValue instanceof RegExp || testValue instanceof Function; - }; - /** - * _parseConfig - * - * @param {Object} cfg optional config literal - */ - // eslint-disable-next-line complexity - - - const _parseConfig = function _parseConfig(cfg) { - if (CONFIG && CONFIG === cfg) { - return; - } - /* Shield configuration object from tampering */ - - - if (!cfg || typeof cfg !== 'object') { - cfg = {}; - } - /* Shield configuration object from prototype pollution */ - - - cfg = clone(cfg); - PARSER_MEDIA_TYPE = // eslint-disable-next-line unicorn/prefer-includes - SUPPORTED_PARSER_MEDIA_TYPES.indexOf(cfg.PARSER_MEDIA_TYPE) === -1 ? PARSER_MEDIA_TYPE = DEFAULT_PARSER_MEDIA_TYPE : PARSER_MEDIA_TYPE = cfg.PARSER_MEDIA_TYPE; // HTML tags and attributes are not case-sensitive, converting to lowercase. Keeping XHTML as is. - - transformCaseFunc = PARSER_MEDIA_TYPE === 'application/xhtml+xml' ? stringToString : stringToLowerCase; - /* Set configuration parameters */ - - ALLOWED_TAGS = 'ALLOWED_TAGS' in cfg ? addToSet({}, cfg.ALLOWED_TAGS, transformCaseFunc) : DEFAULT_ALLOWED_TAGS; - ALLOWED_ATTR = 'ALLOWED_ATTR' in cfg ? addToSet({}, cfg.ALLOWED_ATTR, transformCaseFunc) : DEFAULT_ALLOWED_ATTR; - ALLOWED_NAMESPACES = 'ALLOWED_NAMESPACES' in cfg ? addToSet({}, cfg.ALLOWED_NAMESPACES, stringToString) : DEFAULT_ALLOWED_NAMESPACES; - URI_SAFE_ATTRIBUTES = 'ADD_URI_SAFE_ATTR' in cfg ? addToSet(clone(DEFAULT_URI_SAFE_ATTRIBUTES), // eslint-disable-line indent - cfg.ADD_URI_SAFE_ATTR, // eslint-disable-line indent - transformCaseFunc // eslint-disable-line indent - ) // eslint-disable-line indent - : DEFAULT_URI_SAFE_ATTRIBUTES; - DATA_URI_TAGS = 'ADD_DATA_URI_TAGS' in cfg ? addToSet(clone(DEFAULT_DATA_URI_TAGS), // eslint-disable-line indent - cfg.ADD_DATA_URI_TAGS, // eslint-disable-line indent - transformCaseFunc // eslint-disable-line indent - ) // eslint-disable-line indent - : DEFAULT_DATA_URI_TAGS; - FORBID_CONTENTS = 'FORBID_CONTENTS' in cfg ? addToSet({}, cfg.FORBID_CONTENTS, transformCaseFunc) : DEFAULT_FORBID_CONTENTS; - FORBID_TAGS = 'FORBID_TAGS' in cfg ? addToSet({}, cfg.FORBID_TAGS, transformCaseFunc) : {}; - FORBID_ATTR = 'FORBID_ATTR' in cfg ? addToSet({}, cfg.FORBID_ATTR, transformCaseFunc) : {}; - USE_PROFILES = 'USE_PROFILES' in cfg ? cfg.USE_PROFILES : false; - ALLOW_ARIA_ATTR = cfg.ALLOW_ARIA_ATTR !== false; // Default true - - ALLOW_DATA_ATTR = cfg.ALLOW_DATA_ATTR !== false; // Default true - - ALLOW_UNKNOWN_PROTOCOLS = cfg.ALLOW_UNKNOWN_PROTOCOLS || false; // Default false - - ALLOW_SELF_CLOSE_IN_ATTR = cfg.ALLOW_SELF_CLOSE_IN_ATTR !== false; // Default true - - SAFE_FOR_TEMPLATES = cfg.SAFE_FOR_TEMPLATES || false; // Default false - - WHOLE_DOCUMENT = cfg.WHOLE_DOCUMENT || false; // Default false - - RETURN_DOM = cfg.RETURN_DOM || false; // Default false - - RETURN_DOM_FRAGMENT = cfg.RETURN_DOM_FRAGMENT || false; // Default false - - RETURN_TRUSTED_TYPE = cfg.RETURN_TRUSTED_TYPE || false; // Default false - - FORCE_BODY = cfg.FORCE_BODY || false; // Default false - - SANITIZE_DOM = cfg.SANITIZE_DOM !== false; // Default true - - SANITIZE_NAMED_PROPS = cfg.SANITIZE_NAMED_PROPS || false; // Default false - - KEEP_CONTENT = cfg.KEEP_CONTENT !== false; // Default true - - IN_PLACE = cfg.IN_PLACE || false; // Default false - - IS_ALLOWED_URI$1 = cfg.ALLOWED_URI_REGEXP || IS_ALLOWED_URI; - NAMESPACE = cfg.NAMESPACE || HTML_NAMESPACE; - CUSTOM_ELEMENT_HANDLING = cfg.CUSTOM_ELEMENT_HANDLING || {}; - - if (cfg.CUSTOM_ELEMENT_HANDLING && isRegexOrFunction(cfg.CUSTOM_ELEMENT_HANDLING.tagNameCheck)) { - CUSTOM_ELEMENT_HANDLING.tagNameCheck = cfg.CUSTOM_ELEMENT_HANDLING.tagNameCheck; - } - - if (cfg.CUSTOM_ELEMENT_HANDLING && isRegexOrFunction(cfg.CUSTOM_ELEMENT_HANDLING.attributeNameCheck)) { - CUSTOM_ELEMENT_HANDLING.attributeNameCheck = cfg.CUSTOM_ELEMENT_HANDLING.attributeNameCheck; - } - - if (cfg.CUSTOM_ELEMENT_HANDLING && typeof cfg.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements === 'boolean') { - CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements = cfg.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements; - } - - if (SAFE_FOR_TEMPLATES) { - ALLOW_DATA_ATTR = false; - } - - if (RETURN_DOM_FRAGMENT) { - RETURN_DOM = true; - } - /* Parse profile info */ - - - if (USE_PROFILES) { - ALLOWED_TAGS = addToSet({}, [...text]); - ALLOWED_ATTR = []; - - if (USE_PROFILES.html === true) { - addToSet(ALLOWED_TAGS, html$1); - addToSet(ALLOWED_ATTR, html); - } - - if (USE_PROFILES.svg === true) { - addToSet(ALLOWED_TAGS, svg$1); - addToSet(ALLOWED_ATTR, svg); - addToSet(ALLOWED_ATTR, xml); - } - - if (USE_PROFILES.svgFilters === true) { - addToSet(ALLOWED_TAGS, svgFilters); - addToSet(ALLOWED_ATTR, svg); - addToSet(ALLOWED_ATTR, xml); - } - - if (USE_PROFILES.mathMl === true) { - addToSet(ALLOWED_TAGS, mathMl$1); - addToSet(ALLOWED_ATTR, mathMl); - addToSet(ALLOWED_ATTR, xml); - } - } - /* Merge configuration parameters */ - - - if (cfg.ADD_TAGS) { - if (ALLOWED_TAGS === DEFAULT_ALLOWED_TAGS) { - ALLOWED_TAGS = clone(ALLOWED_TAGS); - } - - addToSet(ALLOWED_TAGS, cfg.ADD_TAGS, transformCaseFunc); - } - - if (cfg.ADD_ATTR) { - if (ALLOWED_ATTR === DEFAULT_ALLOWED_ATTR) { - ALLOWED_ATTR = clone(ALLOWED_ATTR); - } - - addToSet(ALLOWED_ATTR, cfg.ADD_ATTR, transformCaseFunc); - } - - if (cfg.ADD_URI_SAFE_ATTR) { - addToSet(URI_SAFE_ATTRIBUTES, cfg.ADD_URI_SAFE_ATTR, transformCaseFunc); - } - - if (cfg.FORBID_CONTENTS) { - if (FORBID_CONTENTS === DEFAULT_FORBID_CONTENTS) { - FORBID_CONTENTS = clone(FORBID_CONTENTS); - } - - addToSet(FORBID_CONTENTS, cfg.FORBID_CONTENTS, transformCaseFunc); - } - /* Add #text in case KEEP_CONTENT is set to true */ - - - if (KEEP_CONTENT) { - ALLOWED_TAGS['#text'] = true; - } - /* Add html, head and body to ALLOWED_TAGS in case WHOLE_DOCUMENT is true */ - - - if (WHOLE_DOCUMENT) { - addToSet(ALLOWED_TAGS, ['html', 'head', 'body']); - } - /* Add tbody to ALLOWED_TAGS in case tables are permitted, see #286, #365 */ - - - if (ALLOWED_TAGS.table) { - addToSet(ALLOWED_TAGS, ['tbody']); - delete FORBID_TAGS.tbody; - } - - if (cfg.TRUSTED_TYPES_POLICY) { - if (typeof cfg.TRUSTED_TYPES_POLICY.createHTML !== 'function') { - throw typeErrorCreate('TRUSTED_TYPES_POLICY configuration option must provide a "createHTML" hook.'); - } - - if (typeof cfg.TRUSTED_TYPES_POLICY.createScriptURL !== 'function') { - throw typeErrorCreate('TRUSTED_TYPES_POLICY configuration option must provide a "createScriptURL" hook.'); - } // Overwrite existing TrustedTypes policy. - - - trustedTypesPolicy = cfg.TRUSTED_TYPES_POLICY; // Sign local variables required by `sanitize`. - - emptyHTML = trustedTypesPolicy.createHTML(''); - } else { - // Uninitialized policy, attempt to initialize the internal dompurify policy. - if (trustedTypesPolicy === undefined) { - trustedTypesPolicy = _createTrustedTypesPolicy(trustedTypes, currentScript); - } // If creating the internal policy succeeded sign internal variables. - - - if (trustedTypesPolicy !== null && typeof emptyHTML === 'string') { - emptyHTML = trustedTypesPolicy.createHTML(''); - } - } // Prevent further manipulation of configuration. - // Not available in IE8, Safari 5, etc. - - - if (freeze) { - freeze(cfg); - } - - CONFIG = cfg; - }; - - const MATHML_TEXT_INTEGRATION_POINTS = addToSet({}, ['mi', 'mo', 'mn', 'ms', 'mtext']); - const HTML_INTEGRATION_POINTS = addToSet({}, ['foreignobject', 'desc', 'title', 'annotation-xml']); // Certain elements are allowed in both SVG and HTML - // namespace. We need to specify them explicitly - // so that they don't get erroneously deleted from - // HTML namespace. - - const COMMON_SVG_AND_HTML_ELEMENTS = addToSet({}, ['title', 'style', 'font', 'a', 'script']); - /* Keep track of all possible SVG and MathML tags - * so that we can perform the namespace checks - * correctly. */ - - const ALL_SVG_TAGS = addToSet({}, svg$1); - addToSet(ALL_SVG_TAGS, svgFilters); - addToSet(ALL_SVG_TAGS, svgDisallowed); - const ALL_MATHML_TAGS = addToSet({}, mathMl$1); - addToSet(ALL_MATHML_TAGS, mathMlDisallowed); - /** - * - * - * @param {Element} element a DOM element whose namespace is being checked - * @returns {boolean} Return false if the element has a - * namespace that a spec-compliant parser would never - * return. Return true otherwise. - */ - - const _checkValidNamespace = function _checkValidNamespace(element) { - let parent = getParentNode(element); // In JSDOM, if we're inside shadow DOM, then parentNode - // can be null. We just simulate parent in this case. - - if (!parent || !parent.tagName) { - parent = { - namespaceURI: NAMESPACE, - tagName: 'template' - }; - } - - const tagName = stringToLowerCase(element.tagName); - const parentTagName = stringToLowerCase(parent.tagName); - - if (!ALLOWED_NAMESPACES[element.namespaceURI]) { - return false; - } - - if (element.namespaceURI === SVG_NAMESPACE) { - // The only way to switch from HTML namespace to SVG - // is via . If it happens via any other tag, then - // it should be killed. - if (parent.namespaceURI === HTML_NAMESPACE) { - return tagName === 'svg'; - } // The only way to switch from MathML to SVG is via` - // svg if parent is either or MathML - // text integration points. - - - if (parent.namespaceURI === MATHML_NAMESPACE) { - return tagName === 'svg' && (parentTagName === 'annotation-xml' || MATHML_TEXT_INTEGRATION_POINTS[parentTagName]); - } // We only allow elements that are defined in SVG - // spec. All others are disallowed in SVG namespace. - - - return Boolean(ALL_SVG_TAGS[tagName]); - } - - if (element.namespaceURI === MATHML_NAMESPACE) { - // The only way to switch from HTML namespace to MathML - // is via . If it happens via any other tag, then - // it should be killed. - if (parent.namespaceURI === HTML_NAMESPACE) { - return tagName === 'math'; - } // The only way to switch from SVG to MathML is via - // and HTML integration points - - - if (parent.namespaceURI === SVG_NAMESPACE) { - return tagName === 'math' && HTML_INTEGRATION_POINTS[parentTagName]; - } // We only allow elements that are defined in MathML - // spec. All others are disallowed in MathML namespace. - - - return Boolean(ALL_MATHML_TAGS[tagName]); - } - - if (element.namespaceURI === HTML_NAMESPACE) { - // The only way to switch from SVG to HTML is via - // HTML integration points, and from MathML to HTML - // is via MathML text integration points - if (parent.namespaceURI === SVG_NAMESPACE && !HTML_INTEGRATION_POINTS[parentTagName]) { - return false; - } - - if (parent.namespaceURI === MATHML_NAMESPACE && !MATHML_TEXT_INTEGRATION_POINTS[parentTagName]) { - return false; - } // We disallow tags that are specific for MathML - // or SVG and should never appear in HTML namespace - - - return !ALL_MATHML_TAGS[tagName] && (COMMON_SVG_AND_HTML_ELEMENTS[tagName] || !ALL_SVG_TAGS[tagName]); - } // For XHTML and XML documents that support custom namespaces - - - if (PARSER_MEDIA_TYPE === 'application/xhtml+xml' && ALLOWED_NAMESPACES[element.namespaceURI]) { - return true; - } // The code should never reach this place (this means - // that the element somehow got namespace that is not - // HTML, SVG, MathML or allowed via ALLOWED_NAMESPACES). - // Return false just in case. - - - return false; - }; - /** - * _forceRemove - * - * @param {Node} node a DOM node - */ - - - const _forceRemove = function _forceRemove(node) { - arrayPush(DOMPurify.removed, { - element: node - }); - - try { - // eslint-disable-next-line unicorn/prefer-dom-node-remove - node.parentNode.removeChild(node); - } catch (_) { - node.remove(); - } - }; - /** - * _removeAttribute - * - * @param {String} name an Attribute name - * @param {Node} node a DOM node - */ - - - const _removeAttribute = function _removeAttribute(name, node) { - try { - arrayPush(DOMPurify.removed, { - attribute: node.getAttributeNode(name), - from: node - }); - } catch (_) { - arrayPush(DOMPurify.removed, { - attribute: null, - from: node - }); - } - - node.removeAttribute(name); // We void attribute values for unremovable "is"" attributes - - if (name === 'is' && !ALLOWED_ATTR[name]) { - if (RETURN_DOM || RETURN_DOM_FRAGMENT) { - try { - _forceRemove(node); - } catch (_) {} - } else { - try { - node.setAttribute(name, ''); - } catch (_) {} - } - } - }; - /** - * _initDocument - * - * @param {String} dirty a string of dirty markup - * @return {Document} a DOM, filled with the dirty markup - */ - - - const _initDocument = function _initDocument(dirty) { - /* Create a HTML document */ - let doc; - let leadingWhitespace; - - if (FORCE_BODY) { - dirty = '' + dirty; - } else { - /* If FORCE_BODY isn't used, leading whitespace needs to be preserved manually */ - const matches = stringMatch(dirty, /^[\r\n\t ]+/); - leadingWhitespace = matches && matches[0]; - } - - if (PARSER_MEDIA_TYPE === 'application/xhtml+xml' && NAMESPACE === HTML_NAMESPACE) { - // Root of XHTML doc must contain xmlns declaration (see https://www.w3.org/TR/xhtml1/normative.html#strict) - dirty = '' + dirty + ''; - } - - const dirtyPayload = trustedTypesPolicy ? trustedTypesPolicy.createHTML(dirty) : dirty; - /* - * Use the DOMParser API by default, fallback later if needs be - * DOMParser not work for svg when has multiple root element. - */ - - if (NAMESPACE === HTML_NAMESPACE) { - try { - doc = new DOMParser().parseFromString(dirtyPayload, PARSER_MEDIA_TYPE); - } catch (_) {} - } - /* Use createHTMLDocument in case DOMParser is not available */ - - - if (!doc || !doc.documentElement) { - doc = implementation.createDocument(NAMESPACE, 'template', null); - - try { - doc.documentElement.innerHTML = IS_EMPTY_INPUT ? emptyHTML : dirtyPayload; - } catch (_) {// Syntax error if dirtyPayload is invalid xml - } - } - - const body = doc.body || doc.documentElement; - - if (dirty && leadingWhitespace) { - body.insertBefore(document.createTextNode(leadingWhitespace), body.childNodes[0] || null); - } - /* Work on whole document or just its body */ - - - if (NAMESPACE === HTML_NAMESPACE) { - return getElementsByTagName.call(doc, WHOLE_DOCUMENT ? 'html' : 'body')[0]; - } - - return WHOLE_DOCUMENT ? doc.documentElement : body; - }; - /** - * _createIterator - * - * @param {Document} root document/fragment to create iterator for - * @return {Iterator} iterator instance - */ - - - const _createIterator = function _createIterator(root) { - return createNodeIterator.call(root.ownerDocument || root, root, // eslint-disable-next-line no-bitwise - NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_COMMENT | NodeFilter.SHOW_TEXT, null, false); - }; - /** - * _isClobbered - * - * @param {Node} elm element to check for clobbering attacks - * @return {Boolean} true if clobbered, false if safe - */ - - - const _isClobbered = function _isClobbered(elm) { - return elm instanceof HTMLFormElement && (typeof elm.nodeName !== 'string' || typeof elm.textContent !== 'string' || typeof elm.removeChild !== 'function' || !(elm.attributes instanceof NamedNodeMap) || typeof elm.removeAttribute !== 'function' || typeof elm.setAttribute !== 'function' || typeof elm.namespaceURI !== 'string' || typeof elm.insertBefore !== 'function' || typeof elm.hasChildNodes !== 'function'); - }; - /** - * _isNode - * - * @param {Node} obj object to check whether it's a DOM node - * @return {Boolean} true is object is a DOM node - */ - - - const _isNode = function _isNode(object) { - return typeof Node === 'object' ? object instanceof Node : object && typeof object === 'object' && typeof object.nodeType === 'number' && typeof object.nodeName === 'string'; - }; - /** - * _executeHook - * Execute user configurable hooks - * - * @param {String} entryPoint Name of the hook's entry point - * @param {Node} currentNode node to work on with the hook - * @param {Object} data additional hook parameters - */ - - - const _executeHook = function _executeHook(entryPoint, currentNode, data) { - if (!hooks[entryPoint]) { - return; - } - - arrayForEach(hooks[entryPoint], hook => { - hook.call(DOMPurify, currentNode, data, CONFIG); - }); - }; - /** - * _sanitizeElements - * - * @protect nodeName - * @protect textContent - * @protect removeChild - * - * @param {Node} currentNode to check for permission to exist - * @return {Boolean} true if node was killed, false if left alive - */ - - - const _sanitizeElements = function _sanitizeElements(currentNode) { - let content; - /* Execute a hook if present */ - - _executeHook('beforeSanitizeElements', currentNode, null); - /* Check if element is clobbered or can clobber */ - - - if (_isClobbered(currentNode)) { - _forceRemove(currentNode); - - return true; - } - /* Now let's check the element's type and name */ - - - const tagName = transformCaseFunc(currentNode.nodeName); - /* Execute a hook if present */ - - _executeHook('uponSanitizeElement', currentNode, { - tagName, - allowedTags: ALLOWED_TAGS - }); - /* Detect mXSS attempts abusing namespace confusion */ - - - if (currentNode.hasChildNodes() && !_isNode(currentNode.firstElementChild) && (!_isNode(currentNode.content) || !_isNode(currentNode.content.firstElementChild)) && regExpTest(/<[/\w]/g, currentNode.innerHTML) && regExpTest(/<[/\w]/g, currentNode.textContent)) { - _forceRemove(currentNode); - - return true; - } - /* Remove element if anything forbids its presence */ - - - if (!ALLOWED_TAGS[tagName] || FORBID_TAGS[tagName]) { - /* Check if we have a custom element to handle */ - if (!FORBID_TAGS[tagName] && _basicCustomElementTest(tagName)) { - if (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, tagName)) return false; - if (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(tagName)) return false; - } - /* Keep content except for bad-listed elements */ - - - if (KEEP_CONTENT && !FORBID_CONTENTS[tagName]) { - const parentNode = getParentNode(currentNode) || currentNode.parentNode; - const childNodes = getChildNodes(currentNode) || currentNode.childNodes; - - if (childNodes && parentNode) { - const childCount = childNodes.length; - - for (let i = childCount - 1; i >= 0; --i) { - parentNode.insertBefore(cloneNode(childNodes[i], true), getNextSibling(currentNode)); - } - } - } - - _forceRemove(currentNode); - - return true; - } - /* Check whether element has a valid namespace */ - - - if (currentNode instanceof Element && !_checkValidNamespace(currentNode)) { - _forceRemove(currentNode); - - return true; - } - /* Make sure that older browsers don't get fallback-tag mXSS */ - - - if ((tagName === 'noscript' || tagName === 'noembed' || tagName === 'noframes') && regExpTest(/<\/no(script|embed|frames)/i, currentNode.innerHTML)) { - _forceRemove(currentNode); - - return true; - } - /* Sanitize element content to be template-safe */ - - - if (SAFE_FOR_TEMPLATES && currentNode.nodeType === 3) { - /* Get the element's text content */ - content = currentNode.textContent; - content = stringReplace(content, MUSTACHE_EXPR, ' '); - content = stringReplace(content, ERB_EXPR, ' '); - content = stringReplace(content, TMPLIT_EXPR, ' '); - - if (currentNode.textContent !== content) { - arrayPush(DOMPurify.removed, { - element: currentNode.cloneNode() - }); - currentNode.textContent = content; - } - } - /* Execute a hook if present */ - - - _executeHook('afterSanitizeElements', currentNode, null); - - return false; - }; - /** - * _isValidAttribute - * - * @param {string} lcTag Lowercase tag name of containing element. - * @param {string} lcName Lowercase attribute name. - * @param {string} value Attribute value. - * @return {Boolean} Returns true if `value` is valid, otherwise false. - */ - // eslint-disable-next-line complexity - - - const _isValidAttribute = function _isValidAttribute(lcTag, lcName, value) { - /* Make sure attribute cannot clobber */ - if (SANITIZE_DOM && (lcName === 'id' || lcName === 'name') && (value in document || value in formElement)) { - return false; - } - /* Allow valid data-* attributes: At least one character after "-" - (https://html.spec.whatwg.org/multipage/dom.html#embedding-custom-non-visible-data-with-the-data-*-attributes) - XML-compatible (https://html.spec.whatwg.org/multipage/infrastructure.html#xml-compatible and http://www.w3.org/TR/xml/#d0e804) - We don't need to check the value; it's always URI safe. */ - - - if (ALLOW_DATA_ATTR && !FORBID_ATTR[lcName] && regExpTest(DATA_ATTR, lcName)) ; else if (ALLOW_ARIA_ATTR && regExpTest(ARIA_ATTR, lcName)) ; else if (!ALLOWED_ATTR[lcName] || FORBID_ATTR[lcName]) { - if ( // First condition does a very basic check if a) it's basically a valid custom element tagname AND - // b) if the tagName passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.tagNameCheck - // and c) if the attribute name passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.attributeNameCheck - _basicCustomElementTest(lcTag) && (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, lcTag) || CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(lcTag)) && (CUSTOM_ELEMENT_HANDLING.attributeNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.attributeNameCheck, lcName) || CUSTOM_ELEMENT_HANDLING.attributeNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.attributeNameCheck(lcName)) || // Alternative, second condition checks if it's an `is`-attribute, AND - // the value passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.tagNameCheck - lcName === 'is' && CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements && (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, value) || CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(value))) ; else { - return false; - } - /* Check value is safe. First, is attr inert? If so, is safe */ - - } else if (URI_SAFE_ATTRIBUTES[lcName]) ; else if (regExpTest(IS_ALLOWED_URI$1, stringReplace(value, ATTR_WHITESPACE, ''))) ; else if ((lcName === 'src' || lcName === 'xlink:href' || lcName === 'href') && lcTag !== 'script' && stringIndexOf(value, 'data:') === 0 && DATA_URI_TAGS[lcTag]) ; else if (ALLOW_UNKNOWN_PROTOCOLS && !regExpTest(IS_SCRIPT_OR_DATA, stringReplace(value, ATTR_WHITESPACE, ''))) ; else if (value) { - return false; - } else ; - - return true; - }; - /** - * _basicCustomElementCheck - * checks if at least one dash is included in tagName, and it's not the first char - * for more sophisticated checking see https://github.com/sindresorhus/validate-element-name - * @param {string} tagName name of the tag of the node to sanitize - */ - - - const _basicCustomElementTest = function _basicCustomElementTest(tagName) { - return tagName.indexOf('-') > 0; - }; - /** - * _sanitizeAttributes - * - * @protect attributes - * @protect nodeName - * @protect removeAttribute - * @protect setAttribute - * - * @param {Node} currentNode to sanitize - */ - - - const _sanitizeAttributes = function _sanitizeAttributes(currentNode) { - let attr; - let value; - let lcName; - let l; - /* Execute a hook if present */ - - _executeHook('beforeSanitizeAttributes', currentNode, null); - - const { - attributes - } = currentNode; - /* Check if we have attributes; if not we might have a text node */ - - if (!attributes) { - return; - } - - const hookEvent = { - attrName: '', - attrValue: '', - keepAttr: true, - allowedAttributes: ALLOWED_ATTR - }; - l = attributes.length; - /* Go backwards over all attributes; safely remove bad ones */ - - while (l--) { - attr = attributes[l]; - const { - name, - namespaceURI - } = attr; - value = name === 'value' ? attr.value : stringTrim(attr.value); - lcName = transformCaseFunc(name); - /* Execute a hook if present */ - - hookEvent.attrName = lcName; - hookEvent.attrValue = value; - hookEvent.keepAttr = true; - hookEvent.forceKeepAttr = undefined; // Allows developers to see this is a property they can set - - _executeHook('uponSanitizeAttribute', currentNode, hookEvent); - - value = hookEvent.attrValue; - /* Did the hooks approve of the attribute? */ - - if (hookEvent.forceKeepAttr) { - continue; - } - /* Remove attribute */ - - - _removeAttribute(name, currentNode); - /* Did the hooks approve of the attribute? */ - - - if (!hookEvent.keepAttr) { - continue; - } - /* Work around a security issue in jQuery 3.0 */ - - - if (!ALLOW_SELF_CLOSE_IN_ATTR && regExpTest(/\/>/i, value)) { - _removeAttribute(name, currentNode); - - continue; - } - /* Sanitize attribute content to be template-safe */ - - - if (SAFE_FOR_TEMPLATES) { - value = stringReplace(value, MUSTACHE_EXPR, ' '); - value = stringReplace(value, ERB_EXPR, ' '); - value = stringReplace(value, TMPLIT_EXPR, ' '); - } - /* Is `value` valid for this attribute? */ - - - const lcTag = transformCaseFunc(currentNode.nodeName); - - if (!_isValidAttribute(lcTag, lcName, value)) { - continue; - } - /* Full DOM Clobbering protection via namespace isolation, - * Prefix id and name attributes with `user-content-` - */ - - - if (SANITIZE_NAMED_PROPS && (lcName === 'id' || lcName === 'name')) { - // Remove the attribute with this value - _removeAttribute(name, currentNode); // Prefix the value and later re-create the attribute with the sanitized value - - - value = SANITIZE_NAMED_PROPS_PREFIX + value; - } - /* Handle attributes that require Trusted Types */ - - - if (trustedTypesPolicy && typeof trustedTypes === 'object' && typeof trustedTypes.getAttributeType === 'function') { - if (namespaceURI) ; else { - switch (trustedTypes.getAttributeType(lcTag, lcName)) { - case 'TrustedHTML': - { - value = trustedTypesPolicy.createHTML(value); - break; - } - - case 'TrustedScriptURL': - { - value = trustedTypesPolicy.createScriptURL(value); - break; - } - } - } - } - /* Handle invalid data-* attribute set by try-catching it */ - - - try { - if (namespaceURI) { - currentNode.setAttributeNS(namespaceURI, name, value); - } else { - /* Fallback to setAttribute() for browser-unrecognized namespaces e.g. "x-schema". */ - currentNode.setAttribute(name, value); - } - - arrayPop(DOMPurify.removed); - } catch (_) {} - } - /* Execute a hook if present */ - - - _executeHook('afterSanitizeAttributes', currentNode, null); - }; - /** - * _sanitizeShadowDOM - * - * @param {DocumentFragment} fragment to iterate over recursively - */ - - - const _sanitizeShadowDOM = function _sanitizeShadowDOM(fragment) { - let shadowNode; - - const shadowIterator = _createIterator(fragment); - /* Execute a hook if present */ - - - _executeHook('beforeSanitizeShadowDOM', fragment, null); - - while (shadowNode = shadowIterator.nextNode()) { - /* Execute a hook if present */ - _executeHook('uponSanitizeShadowNode', shadowNode, null); - /* Sanitize tags and elements */ - - - if (_sanitizeElements(shadowNode)) { - continue; - } - /* Deep shadow DOM detected */ - - - if (shadowNode.content instanceof DocumentFragment) { - _sanitizeShadowDOM(shadowNode.content); - } - /* Check attributes, sanitize if necessary */ - - - _sanitizeAttributes(shadowNode); - } - /* Execute a hook if present */ - - - _executeHook('afterSanitizeShadowDOM', fragment, null); - }; - /** - * Sanitize - * Public method providing core sanitation functionality - * - * @param {String|Node} dirty string or DOM node - * @param {Object} configuration object - */ - // eslint-disable-next-line complexity - - - DOMPurify.sanitize = function (dirty) { - let cfg = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - let body; - let importedNode; - let currentNode; - let returnNode; - /* Make sure we have a string to sanitize. - DO NOT return early, as this will return the wrong type if - the user has requested a DOM object rather than a string */ - - IS_EMPTY_INPUT = !dirty; - - if (IS_EMPTY_INPUT) { - dirty = ''; - } - /* Stringify, in case dirty is an object */ - - - if (typeof dirty !== 'string' && !_isNode(dirty)) { - if (typeof dirty.toString === 'function') { - dirty = dirty.toString(); - - if (typeof dirty !== 'string') { - throw typeErrorCreate('dirty is not a string, aborting'); - } - } else { - throw typeErrorCreate('toString is not a function'); - } - } - /* Return dirty HTML if DOMPurify cannot run */ - - - if (!DOMPurify.isSupported) { - return dirty; - } - /* Assign config vars */ - - - if (!SET_CONFIG) { - _parseConfig(cfg); - } - /* Clean up removed elements */ - - - DOMPurify.removed = []; - /* Check if dirty is correctly typed for IN_PLACE */ - - if (typeof dirty === 'string') { - IN_PLACE = false; - } - - if (IN_PLACE) { - /* Do some early pre-sanitization to avoid unsafe root nodes */ - if (dirty.nodeName) { - const tagName = transformCaseFunc(dirty.nodeName); - - if (!ALLOWED_TAGS[tagName] || FORBID_TAGS[tagName]) { - throw typeErrorCreate('root node is forbidden and cannot be sanitized in-place'); - } - } - } else if (dirty instanceof Node) { - /* If dirty is a DOM element, append to an empty document to avoid - elements being stripped by the parser */ - body = _initDocument(''); - importedNode = body.ownerDocument.importNode(dirty, true); - - if (importedNode.nodeType === 1 && importedNode.nodeName === 'BODY') { - /* Node is already a body, use as is */ - body = importedNode; - } else if (importedNode.nodeName === 'HTML') { - body = importedNode; - } else { - // eslint-disable-next-line unicorn/prefer-dom-node-append - body.appendChild(importedNode); - } - } else { - /* Exit directly if we have nothing to do */ - if (!RETURN_DOM && !SAFE_FOR_TEMPLATES && !WHOLE_DOCUMENT && // eslint-disable-next-line unicorn/prefer-includes - dirty.indexOf('<') === -1) { - return trustedTypesPolicy && RETURN_TRUSTED_TYPE ? trustedTypesPolicy.createHTML(dirty) : dirty; - } - /* Initialize the document to work on */ - - - body = _initDocument(dirty); - /* Check we have a DOM node from the data */ - - if (!body) { - return RETURN_DOM ? null : RETURN_TRUSTED_TYPE ? emptyHTML : ''; - } - } - /* Remove first element node (ours) if FORCE_BODY is set */ - - - if (body && FORCE_BODY) { - _forceRemove(body.firstChild); - } - /* Get node iterator */ - - - const nodeIterator = _createIterator(IN_PLACE ? dirty : body); - /* Now start iterating over the created document */ - - - while (currentNode = nodeIterator.nextNode()) { - /* Sanitize tags and elements */ - if (_sanitizeElements(currentNode)) { - continue; - } - /* Shadow DOM detected, sanitize it */ - - - if (currentNode.content instanceof DocumentFragment) { - _sanitizeShadowDOM(currentNode.content); - } - /* Check attributes, sanitize if necessary */ - - - _sanitizeAttributes(currentNode); - } - /* If we sanitized `dirty` in-place, return it. */ - - - if (IN_PLACE) { - return dirty; - } - /* Return sanitized string or DOM */ - - - if (RETURN_DOM) { - if (RETURN_DOM_FRAGMENT) { - returnNode = createDocumentFragment.call(body.ownerDocument); - - while (body.firstChild) { - // eslint-disable-next-line unicorn/prefer-dom-node-append - returnNode.appendChild(body.firstChild); - } - } else { - returnNode = body; - } - - if (ALLOWED_ATTR.shadowroot || ALLOWED_ATTR.shadowrootmode) { - /* - AdoptNode() is not used because internal state is not reset - (e.g. the past names map of a HTMLFormElement), this is safe - in theory but we would rather not risk another attack vector. - The state that is cloned by importNode() is explicitly defined - by the specs. - */ - returnNode = importNode.call(originalDocument, returnNode, true); - } - - return returnNode; - } - - let serializedHTML = WHOLE_DOCUMENT ? body.outerHTML : body.innerHTML; - /* Serialize doctype if allowed */ - - if (WHOLE_DOCUMENT && ALLOWED_TAGS['!doctype'] && body.ownerDocument && body.ownerDocument.doctype && body.ownerDocument.doctype.name && regExpTest(DOCTYPE_NAME, body.ownerDocument.doctype.name)) { - serializedHTML = '\n' + serializedHTML; - } - /* Sanitize final string template-safe */ - - - if (SAFE_FOR_TEMPLATES) { - serializedHTML = stringReplace(serializedHTML, MUSTACHE_EXPR, ' '); - serializedHTML = stringReplace(serializedHTML, ERB_EXPR, ' '); - serializedHTML = stringReplace(serializedHTML, TMPLIT_EXPR, ' '); - } - - return trustedTypesPolicy && RETURN_TRUSTED_TYPE ? trustedTypesPolicy.createHTML(serializedHTML) : serializedHTML; - }; - /** - * Public method to set the configuration once - * setConfig - * - * @param {Object} cfg configuration object - */ - - - DOMPurify.setConfig = function (cfg) { - _parseConfig(cfg); - - SET_CONFIG = true; - }; - /** - * Public method to remove the configuration - * clearConfig - * - */ - - - DOMPurify.clearConfig = function () { - CONFIG = null; - SET_CONFIG = false; - }; - /** - * Public method to check if an attribute value is valid. - * Uses last set config, if any. Otherwise, uses config defaults. - * isValidAttribute - * - * @param {string} tag Tag name of containing element. - * @param {string} attr Attribute name. - * @param {string} value Attribute value. - * @return {Boolean} Returns true if `value` is valid. Otherwise, returns false. - */ - - - DOMPurify.isValidAttribute = function (tag, attr, value) { - /* Initialize shared config vars if necessary. */ - if (!CONFIG) { - _parseConfig({}); - } - - const lcTag = transformCaseFunc(tag); - const lcName = transformCaseFunc(attr); - return _isValidAttribute(lcTag, lcName, value); - }; - /** - * AddHook - * Public method to add DOMPurify hooks - * - * @param {String} entryPoint entry point for the hook to add - * @param {Function} hookFunction function to execute - */ - - - DOMPurify.addHook = function (entryPoint, hookFunction) { - if (typeof hookFunction !== 'function') { - return; - } - - hooks[entryPoint] = hooks[entryPoint] || []; - arrayPush(hooks[entryPoint], hookFunction); - }; - /** - * RemoveHook - * Public method to remove a DOMPurify hook at a given entryPoint - * (pops it from the stack of hooks if more are present) - * - * @param {String} entryPoint entry point for the hook to remove - * @return {Function} removed(popped) hook - */ - - - DOMPurify.removeHook = function (entryPoint) { - if (hooks[entryPoint]) { - return arrayPop(hooks[entryPoint]); - } - }; - /** - * RemoveHooks - * Public method to remove all DOMPurify hooks at a given entryPoint - * - * @param {String} entryPoint entry point for the hooks to remove - */ - - - DOMPurify.removeHooks = function (entryPoint) { - if (hooks[entryPoint]) { - hooks[entryPoint] = []; - } - }; - /** - * RemoveAllHooks - * Public method to remove all DOMPurify hooks - * - */ - - - DOMPurify.removeAllHooks = function () { - hooks = {}; - }; - - return DOMPurify; -} - -var purify = createDOMPurify(); - -function createCheckbox$1(name, initialState) { - const container = div$1({class: 'igv-ui-trackgear-popover-check-container'}); - const svg = iconMarkup$2('check', (true === initialState ? '#444' : 'transparent')); - svg.style.borderColor = 'gray'; - svg.style.borderWidth = '1px'; - svg.style.borderStyle = 'solid'; - - container.appendChild(svg); - let label = div$1(); //{ class: 'igv-some-label-class' }); - label.textContent = name; - container.appendChild(label); - - return container; -} - -function createIcon$2(name, color) { - return iconMarkup$2(name, color); -} - -function iconMarkup$2(name, color) { - color = color || "currentColor"; - let icon = icons$2[name]; - if (!icon) { - console.error(`No icon named: ${name}`); - icon = icons$2["question"]; - } - - const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg"); - svg.setAttributeNS(null,'viewBox', '0 0 ' + icon[0] + ' ' + icon[1]); - const path = document.createElementNS("http://www.w3.org/2000/svg", "path"); - path.setAttributeNS(null,'fill', color ); - path.setAttributeNS(null,'d', icon[4]); - svg.appendChild(path); - return svg; -} - -const icons$2 = { - "check": [512, 512, [], "f00c", "M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z"], - "cog": [512, 512, [], "f013", "M444.788 291.1l42.616 24.599c4.867 2.809 7.126 8.618 5.459 13.985-11.07 35.642-29.97 67.842-54.689 94.586a12.016 12.016 0 0 1-14.832 2.254l-42.584-24.595a191.577 191.577 0 0 1-60.759 35.13v49.182a12.01 12.01 0 0 1-9.377 11.718c-34.956 7.85-72.499 8.256-109.219.007-5.49-1.233-9.403-6.096-9.403-11.723v-49.184a191.555 191.555 0 0 1-60.759-35.13l-42.584 24.595a12.016 12.016 0 0 1-14.832-2.254c-24.718-26.744-43.619-58.944-54.689-94.586-1.667-5.366.592-11.175 5.459-13.985L67.212 291.1a193.48 193.48 0 0 1 0-70.199l-42.616-24.599c-4.867-2.809-7.126-8.618-5.459-13.985 11.07-35.642 29.97-67.842 54.689-94.586a12.016 12.016 0 0 1 14.832-2.254l42.584 24.595a191.577 191.577 0 0 1 60.759-35.13V25.759a12.01 12.01 0 0 1 9.377-11.718c34.956-7.85 72.499-8.256 109.219-.007 5.49 1.233 9.403 6.096 9.403 11.723v49.184a191.555 191.555 0 0 1 60.759 35.13l42.584-24.595a12.016 12.016 0 0 1 14.832 2.254c24.718 26.744 43.619 58.944 54.689 94.586 1.667 5.366-.592 11.175-5.459 13.985L444.788 220.9a193.485 193.485 0 0 1 0 70.2zM336 256c0-44.112-35.888-80-80-80s-80 35.888-80 80 35.888 80 80 80 80-35.888 80-80z"], - "exclamation": [192, 512, [], "f12a", "M176 432c0 44.112-35.888 80-80 80s-80-35.888-80-80 35.888-80 80-80 80 35.888 80 80zM25.26 25.199l13.6 272C39.499 309.972 50.041 320 62.83 320h66.34c12.789 0 23.331-10.028 23.97-22.801l13.6-272C167.425 11.49 156.496 0 142.77 0H49.23C35.504 0 24.575 11.49 25.26 25.199z"], - "exclamation-circle": [512, 512, [], "f06a", "M504 256c0 136.997-111.043 248-248 248S8 392.997 8 256C8 119.083 119.043 8 256 8s248 111.083 248 248zm-248 50c-25.405 0-46 20.595-46 46s20.595 46 46 46 46-20.595 46-46-20.595-46-46-46zm-43.673-165.346l7.418 136c.347 6.364 5.609 11.346 11.982 11.346h48.546c6.373 0 11.635-4.982 11.982-11.346l7.418-136c.375-6.874-5.098-12.654-11.982-12.654h-63.383c-6.884 0-12.356 5.78-11.981 12.654z"], - "exclamation-triangle": [576, 512, [], "f071", "M569.517 440.013C587.975 472.007 564.806 512 527.94 512H48.054c-36.937 0-59.999-40.055-41.577-71.987L246.423 23.985c18.467-32.009 64.72-31.951 83.154 0l239.94 416.028zM288 354c-25.405 0-46 20.595-46 46s20.595 46 46 46 46-20.595 46-46-20.595-46-46-46zm-43.673-165.346l7.418 136c.347 6.364 5.609 11.346 11.982 11.346h48.546c6.373 0 11.635-4.982 11.982-11.346l7.418-136c.375-6.874-5.098-12.654-11.982-12.654h-63.383c-6.884 0-12.356 5.78-11.981 12.654z"], - "minus": [448, 512, [], "f068", "M424 318.2c13.3 0 24-10.7 24-24v-76.4c0-13.3-10.7-24-24-24H24c-13.3 0-24 10.7-24 24v76.4c0 13.3 10.7 24 24 24h400z"], - "minus-circle": [512, 512, [], "f056", "M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zM124 296c-6.6 0-12-5.4-12-12v-56c0-6.6 5.4-12 12-12h264c6.6 0 12 5.4 12 12v56c0 6.6-5.4 12-12 12H124z"], - "minus-square": [448, 512, [], "f146", "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM92 296c-6.6 0-12-5.4-12-12v-56c0-6.6 5.4-12 12-12h264c6.6 0 12 5.4 12 12v56c0 6.6-5.4 12-12 12H92z"], - "plus": [448, 512, [], "f067", "M448 294.2v-76.4c0-13.3-10.7-24-24-24H286.2V56c0-13.3-10.7-24-24-24h-76.4c-13.3 0-24 10.7-24 24v137.8H24c-13.3 0-24 10.7-24 24v76.4c0 13.3 10.7 24 24 24h137.8V456c0 13.3 10.7 24 24 24h76.4c13.3 0 24-10.7 24-24V318.2H424c13.3 0 24-10.7 24-24z"], - "plus-circle": [512, 512, [], "f055", "M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm144 276c0 6.6-5.4 12-12 12h-92v92c0 6.6-5.4 12-12 12h-56c-6.6 0-12-5.4-12-12v-92h-92c-6.6 0-12-5.4-12-12v-56c0-6.6 5.4-12 12-12h92v-92c0-6.6 5.4-12 12-12h56c6.6 0 12 5.4 12 12v92h92c6.6 0 12 5.4 12 12v56z"], - "plus-square": [448, 512, [], "f0fe", "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-32 252c0 6.6-5.4 12-12 12h-92v92c0 6.6-5.4 12-12 12h-56c-6.6 0-12-5.4-12-12v-92H92c-6.6 0-12-5.4-12-12v-56c0-6.6 5.4-12 12-12h92v-92c0-6.6 5.4-12 12-12h56c6.6 0 12 5.4 12 12v92h92c6.6 0 12 5.4 12 12v56z"], - "question": [384, 512, [], "f128", "M202.021 0C122.202 0 70.503 32.703 29.914 91.026c-7.363 10.58-5.093 25.086 5.178 32.874l43.138 32.709c10.373 7.865 25.132 6.026 33.253-4.148 25.049-31.381 43.63-49.449 82.757-49.449 30.764 0 68.816 19.799 68.816 49.631 0 22.552-18.617 34.134-48.993 51.164-35.423 19.86-82.299 44.576-82.299 106.405V320c0 13.255 10.745 24 24 24h72.471c13.255 0 24-10.745 24-24v-5.773c0-42.86 125.268-44.645 125.268-160.627C377.504 66.256 286.902 0 202.021 0zM192 373.459c-38.196 0-69.271 31.075-69.271 69.271 0 38.195 31.075 69.27 69.271 69.27s69.271-31.075 69.271-69.271-31.075-69.27-69.271-69.27z"], - "save": [448, 512, [], "f0c7", "M433.941 129.941l-83.882-83.882A48 48 0 0 0 316.118 32H48C21.49 32 0 53.49 0 80v352c0 26.51 21.49 48 48 48h352c26.51 0 48-21.49 48-48V163.882a48 48 0 0 0-14.059-33.941zM224 416c-35.346 0-64-28.654-64-64 0-35.346 28.654-64 64-64s64 28.654 64 64c0 35.346-28.654 64-64 64zm96-304.52V212c0 6.627-5.373 12-12 12H76c-6.627 0-12-5.373-12-12V108c0-6.627 5.373-12 12-12h228.52c3.183 0 6.235 1.264 8.485 3.515l3.48 3.48A11.996 11.996 0 0 1 320 111.48z"], - "search": [512, 512, [], "f002", "M505 442.7L405.3 343c-4.5-4.5-10.6-7-17-7H372c27.6-35.3 44-79.7 44-128C416 93.1 322.9 0 208 0S0 93.1 0 208s93.1 208 208 208c48.3 0 92.7-16.4 128-44v16.3c0 6.4 2.5 12.5 7 17l99.7 99.7c9.4 9.4 24.6 9.4 33.9 0l28.3-28.3c9.4-9.4 9.4-24.6.1-34zM208 336c-70.7 0-128-57.2-128-128 0-70.7 57.2-128 128-128 70.7 0 128 57.2 128 128 0 70.7-57.2 128-128 128z"], - "share": [512, 512, [], "f064", "M503.691 189.836L327.687 37.851C312.281 24.546 288 35.347 288 56.015v80.053C127.371 137.907 0 170.1 0 322.326c0 61.441 39.581 122.309 83.333 154.132 13.653 9.931 33.111-2.533 28.077-18.631C66.066 312.814 132.917 274.316 288 272.085V360c0 20.7 24.3 31.453 39.687 18.164l176.004-152c11.071-9.562 11.086-26.753 0-36.328z"], - "spinner": [512, 512, [], "f110", "M304 48c0 26.51-21.49 48-48 48s-48-21.49-48-48 21.49-48 48-48 48 21.49 48 48zm-48 368c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48-21.49-48-48-48zm208-208c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48-21.49-48-48-48zM96 256c0-26.51-21.49-48-48-48S0 229.49 0 256s21.49 48 48 48 48-21.49 48-48zm12.922 99.078c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48c0-26.509-21.491-48-48-48zm294.156 0c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48c0-26.509-21.49-48-48-48zM108.922 60.922c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48-21.491-48-48-48z"], - "square": [448, 512, [], "f0c8", "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48z"], - "square-full": [512, 512, [], "f45c", "M512 512H0V0h512v512z"], - "times": [384, 512, [], "f00d", "M323.1 441l53.9-53.9c9.4-9.4 9.4-24.5 0-33.9L279.8 256l97.2-97.2c9.4-9.4 9.4-24.5 0-33.9L323.1 71c-9.4-9.4-24.5-9.4-33.9 0L192 168.2 94.8 71c-9.4-9.4-24.5-9.4-33.9 0L7 124.9c-9.4 9.4-9.4 24.5 0 33.9l97.2 97.2L7 353.2c-9.4 9.4-9.4 24.5 0 33.9L60.9 441c9.4 9.4 24.5 9.4 33.9 0l97.2-97.2 97.2 97.2c9.3 9.3 24.5 9.3 33.9 0z"], - "times-circle": [512, 512, [], "f057", "M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm121.6 313.1c4.7 4.7 4.7 12.3 0 17L338 377.6c-4.7 4.7-12.3 4.7-17 0L256 312l-65.1 65.6c-4.7 4.7-12.3 4.7-17 0L134.4 338c-4.7-4.7-4.7-12.3 0-17l65.6-65-65.6-65.1c-4.7-4.7-4.7-12.3 0-17l39.6-39.6c4.7-4.7 12.3-4.7 17 0l65 65.7 65.1-65.6c4.7-4.7 12.3-4.7 17 0l39.6 39.6c4.7 4.7 4.7 12.3 0 17L312 256l65.6 65.1z"], - "wrench": [512, 512, [], "f0ad", "M481.156 200c9.3 0 15.12 10.155 10.325 18.124C466.295 259.992 420.419 288 368 288c-79.222 0-143.501-63.974-143.997-143.079C223.505 65.469 288.548-.001 368.002 0c52.362.001 98.196 27.949 123.4 69.743C496.24 77.766 490.523 88 481.154 88H376l-40 56 40 56h105.156zm-171.649 93.003L109.255 493.255c-24.994 24.993-65.515 24.994-90.51 0-24.993-24.994-24.993-65.516 0-90.51L218.991 202.5c16.16 41.197 49.303 74.335 90.516 90.503zM104 432c0-13.255-10.745-24-24-24s-24 10.745-24 24 10.745 24 24 24 24-10.745 24-24z"], -}; - -var icons$1$1 = /*#__PURE__*/Object.freeze({ - __proto__: null, - createCheckbox: createCheckbox$1, - createIcon: createIcon$2 -}); - -function attachDialogCloseHandlerWithParent$1(parent, closeHandler) { - - var container = document.createElement("div"); - parent.appendChild(container); - container.appendChild(createIcon$2("times")); - container.addEventListener('click', function (e) { - e.preventDefault(); - e.stopPropagation(); - closeHandler(); - }); -} - -var uiUtils$1 = /*#__PURE__*/Object.freeze({ - __proto__: null, - attachDialogCloseHandlerWithParent: attachDialogCloseHandlerWithParent$1 -}); - -/** - * Make the target element movable by clicking and dragging on the handle. This is not a general purprose function, - * it makes several options specific to igv dialogs, the primary one being that the - * target is absolutely positioned in pixel coordinates - - */ - -let dragData$1; // Its assumed we are only dragging one element at a time. - -function makeDraggable$1(target, handle, constraint) { - - handle.addEventListener('mousedown', dragStart.bind(target)); - - function dragStart(event) { - - event.stopPropagation(); - event.preventDefault(); - - const dragFunction = drag$1.bind(this); - const dragEndFunction = dragEnd$1.bind(this); - const computedStyle = getComputedStyle(this); - - dragData$1 = - { - constraint, - dragFunction, - dragEndFunction, - screenX: event.screenX, - screenY: event.screenY, - top: parseInt(computedStyle.top.replace("px", "")), - left: parseInt(computedStyle.left.replace("px", "")) - }; - - document.addEventListener('mousemove', dragFunction); - document.addEventListener('mouseup', dragEndFunction); - document.addEventListener('mouseleave', dragEndFunction); - document.addEventListener('mouseexit', dragEndFunction); - } -} - -function drag$1(event) { - - if (!dragData$1) { - console.error("No drag data!"); - return; - } - event.stopPropagation(); - event.preventDefault(); - const dx = event.screenX - dragData$1.screenX; - const dy = event.screenY - dragData$1.screenY; - - const left = dragData$1.left + dx; - const top = dragData$1.constraint ? Math.max(dragData$1.constraint.minY, dragData$1.top + dy) : dragData$1.top + dy; - - this.style.left = `${ left }px`; - this.style.top = `${ top }px`; -} - -function dragEnd$1(event) { - - if (!dragData$1) { - console.error("No drag data!"); - return; - } - event.stopPropagation(); - event.preventDefault(); - - const dragFunction = dragData$1.dragFunction; - const dragEndFunction = dragData$1.dragEndFunction; - document.removeEventListener('mousemove', dragFunction); - document.removeEventListener('mouseup', dragEndFunction); - document.removeEventListener('mouseleave', dragEndFunction); - document.removeEventListener('mouseexit', dragEndFunction); - dragData$1 = undefined; -} - -const httpMessages$1 = - { - "401": "Access unauthorized", - "403": "Access forbidden", - "404": "Not found" - }; - - -class AlertDialog$1 { - /** - * Initialize a new alert dialog - * @param parent - * @param alertProps - Optional - properties such as scroll to error - */ - constructor(parent, alertProps) { - this.alertProps = Object.assign({ - /** When an alert is presented - focus occur */ - shouldFocus: true, - /** When focus occur - scroll into that element in the view */ - preventScroll: false - }, alertProps); - - // container - this.container = div$1({class: "igv-ui-alert-dialog-container"}); - parent.appendChild(this.container); - this.container.setAttribute('tabIndex', '-1'); - - // header - const header = div$1(); - this.container.appendChild(header); - - this.errorHeadline = div$1(); - header.appendChild(this.errorHeadline); - this.errorHeadline.textContent = ''; - - // body container - let bodyContainer = div$1({class: 'igv-ui-alert-dialog-body'}); - this.container.appendChild(bodyContainer); - - // body copy - this.body = div$1({class: 'igv-ui-alert-dialog-body-copy'}); - bodyContainer.appendChild(this.body); - - // ok container - let ok_container = div$1(); - this.container.appendChild(ok_container); - - // ok - this.ok = div$1(); - ok_container.appendChild(this.ok); - this.ok.textContent = 'OK'; - - const okHandler = () => { - - if (typeof this.callback === 'function') { - this.callback("OK"); - this.callback = undefined; - } - this.body.innerHTML = ''; - hide$1(this.container); - }; - - this.ok.addEventListener('click', event => { - - event.stopPropagation(); - - okHandler(); - }); - - this.container.addEventListener('keypress', event => { - - event.stopPropagation(); - - if ('Enter' === event.key) { - okHandler(); - } - }); - - makeDraggable$1(this.container, header); - - hide$1(this.container); - } - - present(alert, callback) { - - this.errorHeadline.textContent = alert.message ? 'ERROR' : ''; - let string = alert.message || alert; - - if (httpMessages$1.hasOwnProperty(string)) { - string = httpMessages$1[string]; - } - - const clean = purify.sanitize(string); - - this.body.innerHTML = clean; - this.callback = callback; - show$1(this.container); - if (this.alertProps.shouldFocus) { - this.container.focus( - { preventScroll: this.alertProps.preventScroll } - ); - } - } -} - -class InputDialog$1 { - - constructor(parent) { - - this.parent = parent; - - // dialog container - this.container = div$1({class: 'igv-ui-generic-dialog-container'}); - parent.appendChild(this.container); - - // const { x, y, width, height } = this.container.getBoundingClientRect(); - // console.log(`InputDialog - x ${ x } y ${ y } width ${ width } height ${ height }`) - - // dialog header - const header = div$1({class: 'igv-ui-generic-dialog-header'}); - this.container.appendChild(header); - - // dialog label - this.label = div$1({class: 'igv-ui-generic-dialog-one-liner'}); - this.container.appendChild(this.label); - this.label.text = 'Unlabeled'; - - // input container - this.input_container = div$1({class: 'igv-ui-generic-dialog-input'}); - this.container.appendChild(this.input_container); - // - this.input = document.createElement("input"); - this.input_container.appendChild(this.input); - - - // ok | cancel - const buttons = div$1({class: 'igv-ui-generic-dialog-ok-cancel'}); - this.container.appendChild(buttons); - - // ok - this.ok = div$1(); - buttons.appendChild(this.ok); - this.ok.textContent = 'OK'; - - // cancel - this.cancel = div$1(); - buttons.appendChild(this.cancel); - this.cancel.textContent = 'Cancel'; - - hide$1(this.container); - - this.input.addEventListener('keyup', e => { - if (13 === e.keyCode) { - if (typeof this.callback === 'function') { - this.callback(this.input.value); - this.callback = undefined; - } - this.input.value = undefined; - hide$1(this.container); - } - }); - - this.ok.addEventListener('click', () => { - if (typeof this.callback === 'function') { - this.callback(this.input.value); - this.callback = undefined; - } - this.input.value = undefined; - hide$1(this.container); - }); - - const cancel = () => { - this.input.value = ''; - hide$1(this.container); - }; - - this.cancel.addEventListener('click', cancel); - - attachDialogCloseHandlerWithParent$1(header, cancel); - makeDraggable$1(this.container, header); - - } - - get value() { - return purify.sanitize(this.input.value) - } - - present(options, e) { - - this.label.textContent = options.label; - this.input.value = options.value; - this.callback = options.callback || options.click; - - show$1(this.container); - this.clampLocation(e.clientX, e.clientY); - - } - - clampLocation(clientX, clientY) { - - const {width: w, height: h} = this.container.getBoundingClientRect(); - const wh = window.innerHeight; - const ww = window.innerWidth; - - const y = Math.min(wh - h, clientY); - const x = Math.min(ww - w, clientX); - this.container.style.left = `${x}px`; - this.container.style.top = `${y}px`; - - } -} - -const appleCrayonPalette$1 = - { - licorice: "#000000", - lead: "#1e1e1e", - tungsten: "#3a3a3a", - iron: "#545453", - steel: "#6e6e6e", - tin: "#878687", - nickel: "#888787", - aluminum: "#a09fa0", - magnesium: "#b8b8b8", - silver: "#d0d0d0", - mercury: "#e8e8e8", - snow: "#ffffff", - // - cayenne: "#891100", - mocha: "#894800", - aspargus: "#888501", - fern: "#458401", - clover: "#028401", - moss: "#018448", - teal: "#008688", - ocean: "#004a88", - midnight: "#001888", - eggplant: "#491a88", - plum: "#891e88", - maroon: "#891648", - // - maraschino: "#ff2101", - tangerine: "#ff8802", - lemon: "#fffa03", - lime: "#83f902", - spring: "#05f802", - seam_foam: "#03f987", - turquoise: "#00fdff", - aqua: "#008cff", - blueberry: "#002eff", - grape: "#8931ff", - magenta: "#ff39ff", - strawberry: "#ff2987", - // - salmon: "#ff726e", - cantaloupe: "#ffce6e", - banana: "#fffb6d", - honeydew: "#cefa6e", - flora: "#68f96e", - spindrift: "#68fbd0", - ice: "#68fdff", - sky: "#6acfff", - orchid: "#6e76ff", - lavender: "#d278ff", - bubblegum: "#ff7aff", - carnation: "#ff7fd3" - }; - -class GenericContainer$1 { - - constructor({parent, top, left, width, height, border, closeHandler}) { - - let container = div$1({class: 'igv-ui-generic-container'}); - parent.appendChild(container); - hide$1(container); - this.container = container; - - if(top !== undefined) { - this.container.style.top = `${ top }px`; - } - if(left !== undefined) { - this.container.style.left = `${ left }px`; - } - if (width !== undefined) { - this.container.style.width = `${ width }px`; - } - if (height !== undefined) { - this.container.style.height = `${ height }px`; - } - if(border) { - this.container.style.border = border; - } - // - // let bbox = parent.getBoundingClientRect(); - // this.origin = {x: bbox.x, y: bbox.y}; - // this.container.offset({left: this.origin.x, top: this.origin.y}); - - // header - const header = div$1(); - this.container.appendChild(header); - - // close button - attachDialogCloseHandlerWithParent$1(header, (e) => { - hide$1(this.container); - if(typeof closeHandler === "function") { - closeHandler(e); - } - }); - - makeDraggable$1(this.container, header); - } - - show() { - show$1(this.container); - } - - hide() { - hide$1(this.container); - } - - dispose() { - if(this.container.parent) { - this.container.parent.removeChild(this.container); - } - } -} - -class ColorPicker$1 extends GenericContainer$1 { - - constructor({parent, top, left, width, height, defaultColors, colorHandler}) { - - super({ parent, top, left, width, height, border: '1px solid gray'}); - - createColorSwatchSelector$1(this.container, colorHandler, defaultColors); - } - -} - -const createColorSwatchSelector$1 = (container, colorHandler, defaultColors) => { - - const hexColorStrings = Object.values(appleCrayonPalette$1); - - for (let hexColorString of hexColorStrings) { - const swatch = div$1({ class: 'igv-ui-color-swatch' }); - container.appendChild(swatch); - decorateSwatch$1(swatch, hexColorString, colorHandler); - } - - if (defaultColors) { - for (let hexColorString of defaultColors) { - const swatch = div$1({ class: 'igv-ui-color-swatch' }); - container.appendChild(swatch); - decorateSwatch$1(swatch, hexColorString, colorHandler); - } - } - -}; - -const decorateSwatch$1 = (swatch, hexColorString, colorHandler) => { - - swatch.style.backgroundColor = hexColorString; - - swatch.addEventListener('mouseenter', e => swatch.style.borderColor = hexColorString); - - swatch.addEventListener('mouseleave', e => swatch.style.borderColor = 'white'); - - swatch.addEventListener('click', event => { - event.stopPropagation(); - colorHandler(hexColorString); - }); - - swatch.addEventListener('touchend', event => { - event.stopPropagation(); - colorHandler(hexColorString); - }); - -}; - -class Popover { - - constructor(parent, title) { - - this.parent = parent; - - // popover - this.popover = div$1({ class: "igv-ui-popover" }); - parent.appendChild(this.popover); - - // header - const popoverHeader = div$1(); - this.popover.appendChild(popoverHeader); - - const titleElement = div$1(); - popoverHeader.appendChild(titleElement); - if (title) { - titleElement.textContent = title; - } - - attachDialogCloseHandlerWithParent$1(popoverHeader, () => this.hide()); - makeDraggable$1(this.popover, popoverHeader); - - // content - this.popoverContent = div$1(); - this.popover.appendChild(this.popoverContent); - - this.popover.style.display = 'none'; - - - } - - presentContentWithEvent(e, content) { - - this.popover.style.display = 'block'; - - this.popoverContent.innerHTML = content; - - present$1(e, this.popover, this.popoverContent); - - } - - presentMenu(e, menuItems) { - - if (0 === menuItems.length) { - return - } - - this.popover.style.display = 'block'; - - const menuElements = createMenuElements$1(menuItems, this.popover); - for (let item of menuElements) { - this.popoverContent.appendChild(item.object); - } - - present$1(e, this.popover, this.popoverContent); - } - - hide() { - this.popover.style.display = 'none'; - this.dispose(); - } - - dispose() { - - if (this.popover) { - this.popover.parentNode.removeChild(this.popover); - } - - const keys = Object.keys(this); - for (let key of keys) { - this[ key ] = undefined; - } - } - -} - -function present$1(e, popover, popoverContent) { - - const { x, y, width } = translateMouseCoordinates$1(e, popover.parentNode); - popover.style.top = `${ y }px`; - - const { width: w } = popover.getBoundingClientRect(); - - const xmax = x + w; - const delta = xmax - width; - - popover.style.left = `${ xmax > width ? (x - delta) : x }px`; - popoverContent.style.maxWidth = `${ Math.min(w, width) }px`; - - -} - -function createMenuElements$1(itemList, popover) { - - const list = itemList.map(function (item, i) { - let elem; - - if (typeof item === 'string') { - elem = div$1(); - elem.innerHTML = item; - } else if (typeof item === 'Node') { - elem = item; - } else { - if (typeof item.init === 'function') { - item.init(); - } - - if ("checkbox" === item.type) { - elem = createCheckbox$1("Show all bases", item.value); - } else if("color" === item.type) { - const colorPicker = new ColorPicker$1({ - parent: popover.parentElement, - width: 364, - //defaultColor: 'aqua', - colorHandler: (color) => item.click(color) - }); - elem = div$1(); - if (typeof item.label === 'string') { - elem.innerHTML = item.label; - } - const clickHandler = e => { - colorPicker.show(); - hide$1(popover); - e.preventDefault(); - e.stopPropagation(); - }; - elem.addEventListener('click', clickHandler); - elem.addEventListener('touchend', clickHandler); - elem.addEventListener('mouseup', function (e) { - e.preventDefault(); - e.stopPropagation(); - }); - } - - else { - elem = div$1(); - if (typeof item.label === 'string') { - elem.innerHTML = item.label; - } - } - - if (item.click && "color" !== item.type) { - elem.addEventListener('click', handleClick); - elem.addEventListener('touchend', handleClick); - elem.addEventListener('mouseup', function (e) { - e.preventDefault(); - e.stopPropagation(); - }); - - // eslint-disable-next-line no-inner-declarations - function handleClick(e) { - item.click(); - hide$1(popover); - e.preventDefault(); - e.stopPropagation(); - } - } - } - - - return { object: elem, init: item.init }; - }); - - return list; -} - -class GenericColorPicker extends GenericContainer$1 { - - constructor({parent, width}) { - super({parent, width, border: '1px solid gray'}); - } - - configure(defaultColors, colorHandlers) { - - this.colorHandlers = colorHandlers; - - // active color handler defaults to handler with 'color' as key - this.setActiveColorHandler('color'); - - this.createSwatches(defaultColors); - - } - - setActiveColorHandler(option) { - this.activeColorHandler = this.colorHandlers[option]; - } - - createSwatches(defaultColors) { - - this.container.querySelectorAll('.igv-ui-color-swatch').forEach(swatch => swatch.remove()); - - const hexColorStrings = Object.values(appleCrayonPalette$1); - - for (let hexColorString of hexColorStrings) { - const swatch = div$1({class: 'igv-ui-color-swatch'}); - this.container.appendChild(swatch); - this.decorateSwatch(swatch, hexColorString); - } - - if (defaultColors) { - for (let hexColorString of defaultColors) { - const swatch = div$1({class: 'igv-ui-color-swatch'}); - this.container.appendChild(swatch); - this.decorateSwatch(swatch, hexColorString); - } - } - - } - - decorateSwatch(swatch, hexColorString) { - - swatch.style.backgroundColor = hexColorString; - - swatch.addEventListener('mouseenter', () => swatch.style.borderColor = hexColorString); - - swatch.addEventListener('mouseleave', () => swatch.style.borderColor = 'white'); - - swatch.addEventListener('click', event => { - event.stopPropagation(); - this.activeColorHandler(hexColorString); - }); - - swatch.addEventListener('touchend', event => { - event.stopPropagation(); - this.activeColorHandler(hexColorString); - }); - - } - -} - -function embedCSS$2() { - const style = document.createElement('style'); - style.setAttribute('type', 'text/css'); - style.setAttribute('title', 'igv-ui.css'); - style.innerHTML = `.igv-ui-popover { - cursor: default; - position: absolute; - z-index: 2048; - border-color: #7F7F7F; - border-radius: 4px; - border-style: solid; - border-width: 1px; - font-family: "Open Sans", sans-serif; - font-size: small; - background-color: white; -} -.igv-ui-popover > div:first-child { - display: flex; - flex-direction: row; - flex-wrap: nowrap; - justify-content: space-between; - align-items: center; - width: 100%; - height: 24px; - cursor: move; - border-top-left-radius: 4px; - border-top-right-radius: 4px; - border-bottom-color: #7F7F7F; - border-bottom-style: solid; - border-bottom-width: thin; - background-color: #eee; -} -.igv-ui-popover > div:first-child > div:first-child { - margin-left: 4px; -} -.igv-ui-popover > div:first-child > div:last-child { - margin-right: 4px; - height: 12px; - width: 12px; - color: #7F7F7F; -} -.igv-ui-popover > div:first-child > div:last-child:hover { - cursor: pointer; - color: #444; -} -.igv-ui-popover > div:last-child { - overflow-y: auto; - overflow-x: hidden; - max-height: 400px; - max-width: 800px; - background-color: white; -} -.igv-ui-popover > div:last-child > div { - user-select: all; - margin-left: 4px; - margin-right: 4px; - min-width: 220px; - overflow-x: hidden; - text-overflow: ellipsis; - white-space: nowrap; -} -.igv-ui-popover > div:last-child > div > span { - font-weight: bolder; -} -.igv-ui-popover > div:last-child hr { - width: 100%; -} - -.igv-ui-alert-dialog-container { - box-sizing: content-box; - position: absolute; - z-index: 2048; - top: 50%; - left: 50%; - width: 400px; - height: 200px; - border-color: #7F7F7F; - border-radius: 4px; - border-style: solid; - border-width: thin; - outline: none; - font-family: "Open Sans", sans-serif; - font-size: 15px; - font-weight: 400; - background-color: white; - display: flex; - flex-flow: column; - flex-wrap: nowrap; - justify-content: space-between; - align-items: center; -} -.igv-ui-alert-dialog-container > div:first-child { - display: flex; - flex-flow: row; - flex-wrap: nowrap; - justify-content: flex-start; - align-items: center; - width: 100%; - height: 24px; - cursor: move; - border-top-left-radius: 4px; - border-top-right-radius: 4px; - border-bottom-color: #7F7F7F; - border-bottom-style: solid; - border-bottom-width: thin; - background-color: #eee; -} -.igv-ui-alert-dialog-container > div:first-child div:first-child { - padding-left: 8px; -} -.igv-ui-alert-dialog-container .igv-ui-alert-dialog-body { - -webkit-user-select: text; - -moz-user-select: text; - -ms-user-select: text; - user-select: text; - color: #373737; - width: 100%; - height: calc(100% - 24px - 64px); - overflow-y: scroll; -} -.igv-ui-alert-dialog-container .igv-ui-alert-dialog-body .igv-ui-alert-dialog-body-copy { - margin: 16px; - width: auto; - height: auto; - overflow-wrap: break-word; - word-break: break-word; - background-color: white; - border: unset; -} -.igv-ui-alert-dialog-container > div:last-child { - width: 100%; - margin-bottom: 10px; - background-color: white; - display: flex; - flex-flow: row; - flex-wrap: nowrap; - justify-content: center; - align-items: center; -} -.igv-ui-alert-dialog-container > div:last-child div { - margin: unset; - width: 40px; - height: 30px; - line-height: 30px; - text-align: center; - color: white; - font-family: "Open Sans", sans-serif; - font-size: small; - font-weight: 400; - border-color: #2B81AF; - border-style: solid; - border-width: thin; - border-radius: 4px; - background-color: #2B81AF; -} -.igv-ui-alert-dialog-container > div:last-child div:hover { - cursor: pointer; - border-color: #25597f; - background-color: #25597f; -} - -.igv-ui-color-swatch { - position: relative; - box-sizing: content-box; - display: flex; - flex-flow: row; - flex-wrap: wrap; - justify-content: center; - align-items: center; - width: 32px; - height: 32px; - border-style: solid; - border-width: 2px; - border-color: white; - border-radius: 4px; -} - -.igv-ui-color-swatch:hover { - border-color: dimgray; -} - -.igv-ui-colorpicker-menu-close-button { - display: flex; - flex-flow: row; - flex-wrap: nowrap; - justify-content: flex-end; - align-items: center; - width: 100%; - height: 32px; - margin-top: 4px; - margin-bottom: 4px; - padding-right: 8px; -} -.igv-ui-colorpicker-menu-close-button i.fa { - display: block; - margin-left: 4px; - margin-right: 4px; - color: #5f5f5f; -} -.igv-ui-colorpicker-menu-close-button i.fa:hover, -.igv-ui-colorpicker-menu-close-button i.fa:focus, -.igv-ui-colorpicker-menu-close-button i.fa:active { - cursor: pointer; - color: #0f0f0f; -} - -.igv-ui-generic-dialog-container { - box-sizing: content-box; - position: fixed; - top: 0; - left: 0; - width: 300px; - height: 200px; - border-color: #7F7F7F; - border-radius: 4px; - border-style: solid; - border-width: thin; - font-family: "Open Sans", sans-serif; - font-size: medium; - font-weight: 400; - z-index: 2048; - background-color: white; - display: flex; - flex-flow: column; - flex-wrap: nowrap; - justify-content: flex-start; - align-items: center; -} -.igv-ui-generic-dialog-container .igv-ui-generic-dialog-header { - display: flex; - flex-flow: row; - flex-wrap: nowrap; - justify-content: flex-end; - align-items: center; - width: 100%; - height: 24px; - cursor: move; - border-top-left-radius: 4px; - border-top-right-radius: 4px; - border-bottom-color: #7F7F7F; - border-bottom-style: solid; - border-bottom-width: thin; - background-color: #eee; -} -.igv-ui-generic-dialog-container .igv-ui-generic-dialog-header div { - margin-right: 4px; - margin-bottom: 2px; - height: 12px; - width: 12px; - color: #7F7F7F; -} -.igv-ui-generic-dialog-container .igv-ui-generic-dialog-header div:hover { - cursor: pointer; - color: #444; -} -.igv-ui-generic-dialog-container .igv-ui-generic-dialog-one-liner { - color: #373737; - width: 95%; - height: 24px; - line-height: 24px; - text-align: left; - margin-top: 8px; - padding-left: 8px; - overflow-wrap: break-word; - background-color: white; -} -.igv-ui-generic-dialog-container .igv-ui-generic-dialog-label-input { - margin-top: 8px; - width: 95%; - height: 24px; - color: #373737; - line-height: 24px; - padding-left: 8px; - background-color: white; - display: flex; - flex-flow: row; - flex-wrap: nowrap; - justify-content: flex-start; - align-items: center; -} -.igv-ui-generic-dialog-container .igv-ui-generic-dialog-label-input div { - width: 30%; - height: 100%; - font-size: 16px; - text-align: right; - padding-right: 8px; - background-color: white; -} -.igv-ui-generic-dialog-container .igv-ui-generic-dialog-label-input input { - display: block; - height: 100%; - width: 100%; - padding-left: 4px; - font-family: "Open Sans", sans-serif; - font-weight: 400; - color: #373737; - text-align: left; - outline: none; - border-style: solid; - border-width: thin; - border-color: #7F7F7F; - background-color: white; -} -.igv-ui-generic-dialog-container .igv-ui-generic-dialog-label-input input { - width: 50%; - font-size: 16px; -} -.igv-ui-generic-dialog-container .igv-ui-generic-dialog-input { - margin-top: 8px; - width: calc(100% - 16px); - height: 24px; - color: #373737; - line-height: 24px; - display: flex; - flex-flow: row; - flex-wrap: nowrap; - justify-content: space-around; - align-items: center; -} -.igv-ui-generic-dialog-container .igv-ui-generic-dialog-input input { - display: block; - height: 100%; - width: 100%; - padding-left: 4px; - font-family: "Open Sans", sans-serif; - font-weight: 400; - color: #373737; - text-align: left; - outline: none; - border-style: solid; - border-width: thin; - border-color: #7F7F7F; - background-color: white; -} -.igv-ui-generic-dialog-container .igv-ui-generic-dialog-input input { - font-size: 16px; -} -.igv-ui-generic-dialog-container .igv-ui-generic-dialog-ok-cancel { - width: 100%; - height: 28px; - display: flex; - flex-flow: row; - flex-wrap: nowrap; - justify-content: space-around; - align-items: center; -} -.igv-ui-generic-dialog-container .igv-ui-generic-dialog-ok-cancel div { - margin-top: 32px; - color: white; - font-family: "Open Sans", sans-serif; - font-size: 14px; - font-weight: 400; - width: 75px; - height: 28px; - line-height: 28px; - text-align: center; - border-color: transparent; - border-style: solid; - border-width: thin; - border-radius: 2px; -} -.igv-ui-generic-dialog-container .igv-ui-generic-dialog-ok-cancel div:first-child { - margin-left: 32px; - margin-right: 0; - background-color: #5ea4e0; -} -.igv-ui-generic-dialog-container .igv-ui-generic-dialog-ok-cancel div:last-child { - margin-left: 0; - margin-right: 32px; - background-color: #c4c4c4; -} -.igv-ui-generic-dialog-container .igv-ui-generic-dialog-ok-cancel div:first-child:hover { - cursor: pointer; - background-color: #3b5c7f; -} -.igv-ui-generic-dialog-container .igv-ui-generic-dialog-ok-cancel div:last-child:hover { - cursor: pointer; - background-color: #7f7f7f; -} -.igv-ui-generic-dialog-container .igv-ui-generic-dialog-ok { - width: 100%; - height: 36px; - margin-top: 32px; - display: flex; - flex-flow: row; - flex-wrap: nowrap; - justify-content: space-around; - align-items: center; -} -.igv-ui-generic-dialog-container .igv-ui-generic-dialog-ok div { - width: 98px; - height: 36px; - line-height: 36px; - text-align: center; - color: white; - font-family: "Open Sans", sans-serif; - font-size: medium; - font-weight: 400; - border-color: white; - border-style: solid; - border-width: thin; - border-radius: 4px; - background-color: #2B81AF; -} -.igv-ui-generic-dialog-container .igv-ui-generic-dialog-ok div:hover { - cursor: pointer; - background-color: #25597f; -} - -.igv-ui-generic-container { - box-sizing: content-box; - position: absolute; - z-index: 2048; - background-color: white; - cursor: pointer; - display: flex; - flex-direction: row; - flex-wrap: wrap; - justify-content: flex-start; - align-items: center; -} -.igv-ui-generic-container > div:first-child { - cursor: move; - display: flex; - flex-flow: row; - flex-wrap: nowrap; - justify-content: flex-end; - align-items: center; - height: 24px; - width: 100%; - background-color: #dddddd; -} -.igv-ui-generic-container > div:first-child > div { - display: block; - color: #5f5f5f; - cursor: pointer; - width: 14px; - height: 14px; - margin-right: 8px; - margin-bottom: 4px; -} - -.igv-ui-dialog { - z-index: 2048; - position: fixed; - width: fit-content; - height: fit-content; - display: flex; - flex-flow: column; - flex-wrap: nowrap; - justify-content: flex-start; - background-color: white; - border-color: #7F7F7F; - border-radius: 4px; - border-style: solid; - border-width: thin; - font-family: "Open Sans", sans-serif; - font-size: medium; - font-weight: 400; -} -.igv-ui-dialog .igv-ui-dialog-header { - display: flex; - flex-flow: row; - flex-wrap: nowrap; - justify-content: flex-end; - align-items: center; - width: 100%; - height: 24px; - cursor: move; - border-top-left-radius: 4px; - border-top-right-radius: 4px; - border-bottom-color: #7F7F7F; - border-bottom-style: solid; - border-bottom-width: thin; - background-color: #eee; -} -.igv-ui-dialog .igv-ui-dialog-header div { - margin-right: 4px; - margin-bottom: 2px; - height: 12px; - width: 12px; - color: #7F7F7F; -} -.igv-ui-dialog .igv-ui-dialog-header div:hover { - cursor: pointer; - color: #444; -} -.igv-ui-dialog .igv-ui-dialog-one-liner { - width: 95%; - height: 24px; - line-height: 24px; - text-align: left; - margin: 8px; - overflow-wrap: break-word; - background-color: white; - font-weight: bold; -} -.igv-ui-dialog .igv-ui-dialog-ok-cancel { - width: 100%; - display: flex; - flex-flow: row; - flex-wrap: nowrap; - justify-content: space-around; - align-items: center; -} -.igv-ui-dialog .igv-ui-dialog-ok-cancel div { - margin: 16px; - margin-top: 32px; - color: white; - font-family: "Open Sans", sans-serif; - font-size: 14px; - font-weight: 400; - width: 75px; - height: 28px; - line-height: 28px; - text-align: center; - border-color: transparent; - border-style: solid; - border-width: thin; - border-radius: 2px; -} -.igv-ui-dialog .igv-ui-dialog-ok-cancel div:first-child { - background-color: #5ea4e0; -} -.igv-ui-dialog .igv-ui-dialog-ok-cancel div:last-child { - background-color: #c4c4c4; -} -.igv-ui-dialog .igv-ui-dialog-ok-cancel div:first-child:hover { - cursor: pointer; - background-color: #3b5c7f; -} -.igv-ui-dialog .igv-ui-dialog-ok-cancel div:last-child:hover { - cursor: pointer; - background-color: #7f7f7f; -} -.igv-ui-dialog .igv-ui-dialog-ok { - width: 100%; - height: 36px; - margin-top: 32px; - display: flex; - flex-flow: row; - flex-wrap: nowrap; - justify-content: space-around; - align-items: center; -} -.igv-ui-dialog .igv-ui-dialog-ok div { - width: 98px; - height: 36px; - line-height: 36px; - text-align: center; - color: white; - font-family: "Open Sans", sans-serif; - font-size: medium; - font-weight: 400; - border-color: white; - border-style: solid; - border-width: thin; - border-radius: 4px; - background-color: #2B81AF; -} -.igv-ui-dialog .igv-ui-dialog-ok div:hover { - cursor: pointer; - background-color: #25597f; -} - -.igv-ui-panel, .igv-ui-panel-row, .igv-ui-panel-column { - z-index: 2048; - background-color: white; - font-family: "Open Sans", sans-serif; - font-size: medium; - font-weight: 400; - display: flex; - justify-content: flex-start; - align-items: flex-start; -} - -.igv-ui-panel-column { - display: flex; - flex-direction: column; -} - -.igv-ui-panel-row { - display: flex; - flex-direction: row; -} - -.igv-ui-textbox { - background-color: white; - font-family: "Open Sans", sans-serif; - font-size: medium; - font-weight: 400; - display: flex; - justify-content: flex-start; - align-items: flex-start; -} - -.igv-ui-table { - background-color: white; -} - -.igv-ui-table thead { - position: sticky; - top: 0; -} - -.igv-ui-table th { - text-align: left; -} - -.igv-ui-table td { - padding-right: 20px; -} - -.igv-ui-table tr:hover { - background-color: lightblue; -} - -/*# sourceMappingURL=igv-ui.css.map */ -`; - document.head.append(style); -} - -if (typeof document !== 'undefined') { - - if (!stylesheetExists("igv-ui.css")) { - embedCSS$2(); - } - - function stylesheetExists(stylesheetName) { - for (let ss of document.styleSheets) { - ss = ss.href ? ss.href.replace(/^.*[\\\/]/, '') : ''; - if (ss === stylesheetName) { - return true - } - } - return false - } -} - -function createCheckbox$2(name, initialState) { - - const container = domUtils$1.div({class: 'igv-menu-popup-check-container'}); - - const div = domUtils$1.div(); - container.appendChild(div); - - const svg = icons$1$1.createIcon('check', (true === initialState ? '#444' : 'transparent')); - div.appendChild(svg); - - const label = domUtils$1.div(); - label.innerText = name; - container.appendChild(label); - - return container -} - -/** - * Configure item list for track "gear" menu. - * @param trackView - */ -const MenuUtils$1 = { - - trackMenuItemList: function (trackView) { - - const vizWindowTypes = new Set(['alignment', 'annotation', 'variant', 'eqtl', 'snp']); - - const hasVizWindow = trackView.track.config && trackView.track.config.visibilityWindow !== undefined; - - let menuItems = []; - - if (trackView.track.config.type !== 'sequence') { - menuItems.push(trackRenameMenuItem$1(trackView)); - menuItems.push(trackHeightMenuItem(trackView)); - } - - if (this.showColorPicker(trackView.track)) { - menuItems.push('
'); - menuItems.push(colorPickerMenuItem$1({trackView, label: "Set track color", option: "color"})); - menuItems.push(unsetColorMenuItem$1({trackView, label: "Unset track color"})); - if(trackView.track.config.type === 'wig' || trackView.track.config.type === 'annotation') { - menuItems.push(colorPickerMenuItem$1({trackView, label: "Set alt color", option: "altColor"})); - menuItems.push(unsetAltColorMenuItem({trackView, label: "Unset alt color"})); - } - } - - if (trackView.track.menuItemList) { - menuItems = menuItems.concat(trackView.track.menuItemList()); - } - - if (hasVizWindow || vizWindowTypes.has(trackView.track.type)) { - menuItems.push('
'); - menuItems.push(visibilityWindowMenuItem(trackView)); - } - - if (trackView.track.removable !== false) { - menuItems.push('
'); - menuItems.push(trackRemovalMenuItem$1(trackView)); - } - - return menuItems - }, - - numericDataMenuItems: function (trackView) { - - const menuItems = []; - - menuItems.push('
'); - - // Data range - const object = $$1('
'); - object.text('Set data range'); - - const click = () => { - trackView.browser.dataRangeDialog.configure(trackView); - trackView.browser.dataRangeDialog.present($$1(trackView.browser.columnContainer)); - }; - menuItems.push({object, click}); - - if (trackView.track.logScale !== undefined) { - menuItems.push({ - object: $$1(createCheckbox$2("Log scale", trackView.track.logScale)), - click: () => { - trackView.track.logScale = !trackView.track.logScale; - trackView.repaintViews(); - } - } - ); - } - - menuItems.push({ - object: $$1(createCheckbox$2("Autoscale", trackView.track.autoscale)), - click: () => { - trackView.track.autoscale = !trackView.track.autoscale; - trackView.updateViews(); - } - } - ); - - - return menuItems - }, - - trackMenuItemListHelper: function (itemList, menuPopup) { - - var list = []; - - if (itemList.length > 0) { - - list = itemList.map(function (item, i) { - var $e; - - // name and object fields checked for backward compatibility - if (item.name) { - $e = $$1('
'); - $e.text(item.name); - } else if (item.object) { - $e = item.object; - } else if (typeof item.label === 'string') { - $e = $$1('
'); - $e.html(item.label); - } else if (typeof item === 'string') { - - if (item.startsWith("<")) { - $e = $$1(item); - } else { - $e = $$1("
" + item + "
"); - } - } - - if (0 === i) { - $e.addClass('igv-track-menu-border-top'); - } - - if (item.click) { - $e.on('click', handleClick); - $e.on('touchend', function (e) { - handleClick(e); - }); - $e.on('mouseup', function (e) { - e.preventDefault(); - e.stopPropagation(); - }); - - // eslint-disable-next-line no-inner-declarations - function handleClick(e) { - item.click(e); - menuPopup.hide(); - e.preventDefault(); - e.stopPropagation(); - } - } - - return {object: $e, init: (item.init || undefined)} - }); - } - - return list - }, - - showColorPicker(track) { - return ( - undefined === track.type || - "bedtype" === track.type || - "alignment" === track.type || - "annotation" === track.type || - "variant" === track.type || - "wig" === track.type) || - 'interact' === track.type - }, - - createMenuItem(label, action) { - const object = $$1('
'); - object.text(label); - return {object, click: action} - } -}; - - -function visibilityWindowMenuItem(trackView) { - - const click = e => { - - const callback = () => { - - let value = trackView.browser.inputDialog.value; - value = '' === value || undefined === value ? -1 : value.trim(); - - trackView.track.visibilityWindow = Number.parseInt(value); - trackView.track.config.visibilityWindow = Number.parseInt(value); - - trackView.updateViews(); - }; - - const config = - { - label: 'Visibility Window', - value: (trackView.track.visibilityWindow), - callback - }; - trackView.browser.inputDialog.present(config, e); - - }; - - const object = $$1('
'); - object.text('Set visibility window'); - return {object, click} - -} - -function trackRemovalMenuItem$1(trackView) { - - const object = $$1('
'); - object.text('Remove track'); - - return {object, click: () => trackView.browser.removeTrack(trackView.track)} - -} - -function colorPickerMenuItem$1({trackView, label, option}) { - - const $e = $$1('
'); - $e.text(label); - - return { - object: $e, - click: () => trackView.presentColorPicker(option) - } -} - -function unsetColorMenuItem$1({trackView, label}) { - - const $e = $$1('
'); - $e.text(label); - - return { - object: $e, - click: () => { - trackView.track.color = undefined; - trackView.repaintViews(); - } - } -} - -function unsetAltColorMenuItem({trackView, label}) { - - const $e = $$1('
'); - $e.text(label); - - return { - object: $e, - click: () => { - trackView.track.altColor = undefined; - trackView.repaintViews(); - } - } -} - -function trackRenameMenuItem$1(trackView) { - - const click = e => { - - const callback = function () { - let value = trackView.browser.inputDialog.value; - value = ('' === value || undefined === value) ? 'untitled' : value.trim(); - trackView.track.name = value; - }; - - const config = - { - label: 'Track Name', - value: (getTrackLabelText(trackView.track) || 'unnamed'), - callback - }; - - trackView.browser.inputDialog.present(config, e); - - }; - - const object = $$1('
'); - object.text('Set track name'); - return {object, click} - - -} - -function trackHeightMenuItem(trackView) { - - const click = e => { - - const callback = () => { - - const number = Number(trackView.browser.inputDialog.value, 10); - - if (undefined !== number) { - - // If explicitly setting the height adust min or max, if neccessary. - if (trackView.track.minHeight !== undefined && trackView.track.minHeight > number) { - trackView.track.minHeight = number; - } - if (trackView.track.maxHeight !== undefined && trackView.track.maxHeight < number) { - trackView.track.minHeight = number; - } - trackView.setTrackHeight(number, true); - - trackView.checkContentHeight(); - trackView.repaintViews(); - - - // Explicitly setting track height turns off autoHeight - trackView.track.autoHeight = false; - } - - }; - - const config = - { - label: 'Track Height', - value: trackView.track.height, - callback - }; - - trackView.browser.inputDialog.present(config, e); - - }; - - const object = $$1('
'); - object.text('Set track height'); - return {object, click} - - -} - -function getTrackLabelText(track) { - var vp, - txt; - - vp = track.trackView.viewports[0]; - txt = vp.$trackLabel.text(); - - return txt -} - -class DataRangeDialog$1 { - - constructor(browser, $parent, alert) { - - this.browser = browser; - - // dialog container - this.$container = $$1("
", {class: 'igv-generic-dialog-container'}); - $parent.append(this.$container); - this.$container.offset({left: 0, top: 0}); - - // dialog header - const $header = $$1("
", {class: 'igv-generic-dialog-header'}); - this.$container.append($header); - uiUtils$1.attachDialogCloseHandlerWithParent($header[0], () => { - this.$minimum_input.val(undefined); - this.$maximum_input.val(undefined); - this.$container.offset({left: 0, top: 0}); - this.$container.hide(); - }); - - - // minimun - this.$minimum = $$1("
", {class: 'igv-generic-dialog-label-input'}); - this.$container.append(this.$minimum); - const $mindiv = $$1('
'); - $mindiv.text('Minimum'); - this.$minimum.append($mindiv); - this.$minimum_input = $$1(""); - this.$minimum.append(this.$minimum_input); - - - // maximum - this.$maximum = $$1("
", {class: 'igv-generic-dialog-label-input'}); - this.$container.append(this.$maximum); - const $maxdiv = $$1('
'); - $maxdiv.text('Maximum'); - this.$maximum.append($maxdiv); - this.$maximum_input = $$1(""); - this.$maximum.append(this.$maximum_input); - - // ok | cancel - const $buttons = $$1("
", {class: 'igv-generic-dialog-ok-cancel'}); - this.$container.append($buttons); - - // ok - this.$ok = $$1("
"); - $buttons.append(this.$ok); - this.$ok.text('OK'); - - // cancel - this.$cancel = $$1("
"); - $buttons.append(this.$cancel); - this.$cancel.text('Cancel'); - - this.$cancel.on('click', () => { - this.$minimum_input.val(undefined); - this.$maximum_input.val(undefined); - this.$container.offset({left: 0, top: 0}); - this.$container.hide(); - }); - - //this.$container.draggable({ handle:$header.get(0) }); - makeDraggable$1(this.$container.get(0), $header.get(0)); - - this.$container.hide(); - } - - configure(trackView) { - - const dataRange = trackView.dataRange(); - let min; - let max; - if (dataRange) { - min = dataRange.min; - max = dataRange.max; - } else { - min = 0; - max = 100; - } - - this.$minimum_input.val(min); - this.$maximum_input.val(max); - - this.$minimum_input.unbind(); - this.$minimum_input.on('keyup', (e) => { - if (13 === e.keyCode) { - this.processResults(trackView); - } - }); - - this.$maximum_input.unbind(); - this.$maximum_input.on('keyup', (e) => { - if (13 === e.keyCode) { - this.processResults(trackView); - } - }); - - this.$ok.unbind(); - this.$ok.on('click', (e) => { - this.processResults(trackView); - }); - } - - - processResults(trackView) { - - const min = Number(this.$minimum_input.val()); - const max = Number(this.$maximum_input.val()); - if (isNaN(min) || isNaN(max)) { - this.browser.alert.present(new Error('Must input numeric values'), undefined); - } else { - trackView.setDataRange(min, max); - } - - this.$minimum_input.val(undefined); - this.$maximum_input.val(undefined); - this.$container.offset({left: 0, top: 0}); - this.$container.hide(); - } - - present($parent) { - - const offset_top = $parent.offset().top; - const scroll_top = $$1('body').scrollTop(); - - this.$container.offset({left: $parent.width() - this.$container.width(), top: (offset_top + scroll_top)}); - this.$container.show(); - } -} - -/** - * Covers string literals and String objects - * @param x - * @returns {boolean} - */ -function isString$2(x) { - return typeof x === "string" || x instanceof String -} - - -// StackOverflow: http://stackoverflow.com/a/10810674/116169 -function numberFormatter$1(rawNumber) { - - var dec = String(rawNumber).split(/[.,]/), - sep = ',', - decsep = '.'; - - return dec[0].split('').reverse().reduce(function (prev, now, i) { - return i % 3 === 0 ? prev + sep + now : prev + now; - }).split('').reverse().join('') + (dec[1] ? decsep + dec[1] : ''); -} - -const splitLines$5 = function (string) { - return string.split(/\n|\r\n|\r/g); -}; - - -function splitStringRespectingQuotes(string, delim) { - - var tokens = [], - len = string.length, - i, - n = 0, - quote = false, - c; - - if (len > 0) { - - tokens[n] = string.charAt(0); - for (i = 1; i < len; i++) { - c = string.charAt(i); - if (c === '"') { - quote = !quote; - } else if (!quote && c === delim) { - n++; - tokens[n] = ""; - } else { - tokens[n] += c; - } - } - } - return tokens; -} - -function stripQuotes$1(str) { - if(str === undefined) { - return str; - } - if(str.startsWith("'") || str.startsWith('"')) { - str = str.substring(1); - } - if (str.endsWith("'") || str.endsWith('"')) { - str = str.substring(0, str.length - 1); - } - return str; -} - -function capitalize(str) { - return str.length > 0 ? str.charAt(0).toUpperCase() + str.slice(1) : str; -} - - -/** - * Parse a locus string and return a range object. Locus string is of the form chr:start-end. End is optional - * - */ -function parseLocusString$1(string) { - - const t1 = string.split(":"); - const t2 = t1[1].split("-"); - - const range = { - chr: t1[0], - start: Number.parseInt(t2[0].replace(/,/g, '')) - 1 - }; - - if (t2.length > 1) { - range.end = Number.parseInt(t2[1].replace(/,/g, '')); - } else { - range.end = range.start + 1; - } - - return range; -} - -/** - * Return the filename from the path. Example - * https://foo.com/bar.bed?param=2 => bar.bed - * @param urlOrFile - */ - -function getFilename$2(urlOrFile) { - - if (urlOrFile.name !== undefined) { - return urlOrFile.name - } else if (isString$2(urlOrFile)) { - - let index = urlOrFile.lastIndexOf("/"); - let filename = index < 0 ? urlOrFile : urlOrFile.substr(index + 1); - - //Strip parameters -- handle local files later - index = filename.indexOf("?"); - if (index > 0) { - filename = filename.substr(0, index); - } - return filename - } else { - throw Error(`Expected File or string, got ${typeof urlOrFile}`) - } -} - - -/** - * Test if object is a File or File-like object. - * - * @param object - */ -function isFile$1(object) { - if(!object) { - return false; - } - return typeof object !== 'function' && - (object instanceof File || - (object.hasOwnProperty("name") && typeof object.slice === 'function' && typeof object.arrayBuffer === 'function')) -} - -function download(filename, data) { - - const element = document.createElement('a'); - element.setAttribute('href', data); - element.setAttribute('download', filename); - element.style.display = 'none'; - document.body.appendChild(element); - element.click(); - document.body.removeChild(element); -} - -if (typeof process === 'object' && typeof window === 'undefined') { - global.atob = function (str) { - return Buffer.from(str, 'base64').toString('binary'); - }; -} - - -function parseUri(str) { - - var o = options, - m = o.parser["loose"].exec(str), - uri = {}, - i = 14; - - while (i--) uri[o.key[i]] = m[i] || ""; - - uri[o.q.name] = {}; - uri[o.key[12]].replace(o.q.parser, function ($0, $1, $2) { - if ($1) uri[o.q.name][$1] = $2; - }); - - return uri; -} - -const options = { - strictMode: false, - key: ["source", "protocol", "authority", "userInfo", "user", "password", "host", "port", "relative", "path", "directory", "file", "query", "anchor"], - q: { - name: "queryKey", - parser: /(?:^|&)([^&=]*)=?([^&]*)/g - }, - parser: { - strict: /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/, - loose: /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/ - } -}; - -/** - * Resolve a url, which might be a string, function (that returns a string or Promse), or Promise (that resolves to a string) - * - * @param url - * @returns {Promise<*>} - */ -async function resolveURL(url) { - return (typeof url === 'function') ? url() : url; -} - -/*! pako 2.1.0 https://github.com/nodeca/pako @license (MIT AND Zlib) */ -// (C) 1995-2013 Jean-loup Gailly and Mark Adler -// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// 3. This notice may not be removed or altered from any source distribution. - -/* eslint-disable space-unary-ops */ - -/* Public constants ==========================================================*/ -/* ===========================================================================*/ - - -//const Z_FILTERED = 1; -//const Z_HUFFMAN_ONLY = 2; -//const Z_RLE = 3; -const Z_FIXED$1 = 4; -//const Z_DEFAULT_STRATEGY = 0; - -/* Possible values of the data_type field (though see inflate()) */ -const Z_BINARY = 0; -const Z_TEXT = 1; -//const Z_ASCII = 1; // = Z_TEXT -const Z_UNKNOWN$1 = 2; - -/*============================================================================*/ - - -function zero$1$1(buf) { let len = buf.length; while (--len >= 0) { buf[len] = 0; } } - -// From zutil.h - -const STORED_BLOCK = 0; -const STATIC_TREES = 1; -const DYN_TREES = 2; -/* The three kinds of block type */ - -const MIN_MATCH$1$1 = 3; -const MAX_MATCH$1$1 = 258; -/* The minimum and maximum match lengths */ - -// From deflate.h -/* =========================================================================== - * Internal compression state. - */ - -const LENGTH_CODES$1$1 = 29; -/* number of length codes, not counting the special END_BLOCK code */ - -const LITERALS$1$1 = 256; -/* number of literal bytes 0..255 */ - -const L_CODES$1$1 = LITERALS$1$1 + 1 + LENGTH_CODES$1$1; -/* number of Literal or Length codes, including the END_BLOCK code */ - -const D_CODES$1$1 = 30; -/* number of distance codes */ - -const BL_CODES$1 = 19; -/* number of codes used to transfer the bit lengths */ - -const HEAP_SIZE$1 = 2 * L_CODES$1$1 + 1; -/* maximum heap size */ - -const MAX_BITS$1 = 15; -/* All codes must not exceed MAX_BITS bits */ - -const Buf_size = 16; -/* size of bit buffer in bi_buf */ - - -/* =========================================================================== - * Constants - */ - -const MAX_BL_BITS = 7; -/* Bit length codes must not exceed MAX_BL_BITS bits */ - -const END_BLOCK = 256; -/* end of block literal code */ - -const REP_3_6 = 16; -/* repeat previous bit length 3-6 times (2 bits of repeat count) */ - -const REPZ_3_10 = 17; -/* repeat a zero length 3-10 times (3 bits of repeat count) */ - -const REPZ_11_138 = 18; -/* repeat a zero length 11-138 times (7 bits of repeat count) */ - -/* eslint-disable comma-spacing,array-bracket-spacing */ -const extra_lbits = /* extra bits for each length code */ - new Uint8Array([0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0]); - -const extra_dbits = /* extra bits for each distance code */ - new Uint8Array([0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13]); - -const extra_blbits = /* extra bits for each bit length code */ - new Uint8Array([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7]); - -const bl_order = - new Uint8Array([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]); -/* eslint-enable comma-spacing,array-bracket-spacing */ - -/* The lengths of the bit length codes are sent in order of decreasing - * probability, to avoid transmitting the lengths for unused bit length codes. - */ - -/* =========================================================================== - * Local data. These are initialized only once. - */ - -// We pre-fill arrays with 0 to avoid uninitialized gaps - -const DIST_CODE_LEN$1 = 512; /* see definition of array dist_code below */ - -// !!!! Use flat array instead of structure, Freq = i*2, Len = i*2+1 -const static_ltree$1 = new Array((L_CODES$1$1 + 2) * 2); -zero$1$1(static_ltree$1); -/* The static literal tree. Since the bit lengths are imposed, there is no - * need for the L_CODES extra codes used during heap construction. However - * The codes 286 and 287 are needed to build a canonical tree (see _tr_init - * below). - */ - -const static_dtree$1 = new Array(D_CODES$1$1 * 2); -zero$1$1(static_dtree$1); -/* The static distance tree. (Actually a trivial tree since all codes use - * 5 bits.) - */ - -const _dist_code$1 = new Array(DIST_CODE_LEN$1); -zero$1$1(_dist_code$1); -/* Distance codes. The first 256 values correspond to the distances - * 3 .. 258, the last 256 values correspond to the top 8 bits of - * the 15 bit distances. - */ - -const _length_code$1 = new Array(MAX_MATCH$1$1 - MIN_MATCH$1$1 + 1); -zero$1$1(_length_code$1); -/* length code for each normalized match length (0 == MIN_MATCH) */ - -const base_length$1 = new Array(LENGTH_CODES$1$1); -zero$1$1(base_length$1); -/* First normalized length for each code (0 = MIN_MATCH) */ - -const base_dist$1 = new Array(D_CODES$1$1); -zero$1$1(base_dist$1); -/* First normalized distance for each code (0 = distance of 1) */ - - -function StaticTreeDesc(static_tree, extra_bits, extra_base, elems, max_length) { - - this.static_tree = static_tree; /* static tree or NULL */ - this.extra_bits = extra_bits; /* extra bits for each code or NULL */ - this.extra_base = extra_base; /* base index for extra_bits */ - this.elems = elems; /* max number of elements in the tree */ - this.max_length = max_length; /* max bit length for the codes */ - - // show if `static_tree` has data or dummy - needed for monomorphic objects - this.has_stree = static_tree && static_tree.length; -} - - -let static_l_desc; -let static_d_desc; -let static_bl_desc; - - -function TreeDesc(dyn_tree, stat_desc) { - this.dyn_tree = dyn_tree; /* the dynamic tree */ - this.max_code = 0; /* largest code with non zero frequency */ - this.stat_desc = stat_desc; /* the corresponding static tree */ -} - - - -const d_code = (dist) => { - - return dist < 256 ? _dist_code$1[dist] : _dist_code$1[256 + (dist >>> 7)]; -}; - - -/* =========================================================================== - * Output a short LSB first on the stream. - * IN assertion: there is enough room in pendingBuf. - */ -const put_short = (s, w) => { -// put_byte(s, (uch)((w) & 0xff)); -// put_byte(s, (uch)((ush)(w) >> 8)); - s.pending_buf[s.pending++] = (w) & 0xff; - s.pending_buf[s.pending++] = (w >>> 8) & 0xff; -}; - - -/* =========================================================================== - * Send a value on a given number of bits. - * IN assertion: length <= 16 and value fits in length bits. - */ -const send_bits = (s, value, length) => { - - if (s.bi_valid > (Buf_size - length)) { - s.bi_buf |= (value << s.bi_valid) & 0xffff; - put_short(s, s.bi_buf); - s.bi_buf = value >> (Buf_size - s.bi_valid); - s.bi_valid += length - Buf_size; - } else { - s.bi_buf |= (value << s.bi_valid) & 0xffff; - s.bi_valid += length; - } -}; - - -const send_code = (s, c, tree) => { - - send_bits(s, tree[c * 2]/*.Code*/, tree[c * 2 + 1]/*.Len*/); -}; - - -/* =========================================================================== - * Reverse the first len bits of a code, using straightforward code (a faster - * method would use a table) - * IN assertion: 1 <= len <= 15 - */ -const bi_reverse = (code, len) => { - - let res = 0; - do { - res |= code & 1; - code >>>= 1; - res <<= 1; - } while (--len > 0); - return res >>> 1; -}; - - -/* =========================================================================== - * Flush the bit buffer, keeping at most 7 bits in it. - */ -const bi_flush = (s) => { - - if (s.bi_valid === 16) { - put_short(s, s.bi_buf); - s.bi_buf = 0; - s.bi_valid = 0; - - } else if (s.bi_valid >= 8) { - s.pending_buf[s.pending++] = s.bi_buf & 0xff; - s.bi_buf >>= 8; - s.bi_valid -= 8; - } -}; - - -/* =========================================================================== - * Compute the optimal bit lengths for a tree and update the total bit length - * for the current block. - * IN assertion: the fields freq and dad are set, heap[heap_max] and - * above are the tree nodes sorted by increasing frequency. - * OUT assertions: the field len is set to the optimal bit length, the - * array bl_count contains the frequencies for each bit length. - * The length opt_len is updated; static_len is also updated if stree is - * not null. - */ -const gen_bitlen = (s, desc) => { -// deflate_state *s; -// tree_desc *desc; /* the tree descriptor */ - - const tree = desc.dyn_tree; - const max_code = desc.max_code; - const stree = desc.stat_desc.static_tree; - const has_stree = desc.stat_desc.has_stree; - const extra = desc.stat_desc.extra_bits; - const base = desc.stat_desc.extra_base; - const max_length = desc.stat_desc.max_length; - let h; /* heap index */ - let n, m; /* iterate over the tree elements */ - let bits; /* bit length */ - let xbits; /* extra bits */ - let f; /* frequency */ - let overflow = 0; /* number of elements with bit length too large */ - - for (bits = 0; bits <= MAX_BITS$1; bits++) { - s.bl_count[bits] = 0; - } - - /* In a first pass, compute the optimal bit lengths (which may - * overflow in the case of the bit length tree). - */ - tree[s.heap[s.heap_max] * 2 + 1]/*.Len*/ = 0; /* root of the heap */ - - for (h = s.heap_max + 1; h < HEAP_SIZE$1; h++) { - n = s.heap[h]; - bits = tree[tree[n * 2 + 1]/*.Dad*/ * 2 + 1]/*.Len*/ + 1; - if (bits > max_length) { - bits = max_length; - overflow++; - } - tree[n * 2 + 1]/*.Len*/ = bits; - /* We overwrite tree[n].Dad which is no longer needed */ - - if (n > max_code) { continue; } /* not a leaf node */ - - s.bl_count[bits]++; - xbits = 0; - if (n >= base) { - xbits = extra[n - base]; - } - f = tree[n * 2]/*.Freq*/; - s.opt_len += f * (bits + xbits); - if (has_stree) { - s.static_len += f * (stree[n * 2 + 1]/*.Len*/ + xbits); - } - } - if (overflow === 0) { return; } - - // Tracev((stderr,"\nbit length overflow\n")); - /* This happens for example on obj2 and pic of the Calgary corpus */ - - /* Find the first bit length which could increase: */ - do { - bits = max_length - 1; - while (s.bl_count[bits] === 0) { bits--; } - s.bl_count[bits]--; /* move one leaf down the tree */ - s.bl_count[bits + 1] += 2; /* move one overflow item as its brother */ - s.bl_count[max_length]--; - /* The brother of the overflow item also moves one step up, - * but this does not affect bl_count[max_length] - */ - overflow -= 2; - } while (overflow > 0); - - /* Now recompute all bit lengths, scanning in increasing frequency. - * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all - * lengths instead of fixing only the wrong ones. This idea is taken - * from 'ar' written by Haruhiko Okumura.) - */ - for (bits = max_length; bits !== 0; bits--) { - n = s.bl_count[bits]; - while (n !== 0) { - m = s.heap[--h]; - if (m > max_code) { continue; } - if (tree[m * 2 + 1]/*.Len*/ !== bits) { - // Tracev((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits)); - s.opt_len += (bits - tree[m * 2 + 1]/*.Len*/) * tree[m * 2]/*.Freq*/; - tree[m * 2 + 1]/*.Len*/ = bits; - } - n--; - } - } -}; - - -/* =========================================================================== - * Generate the codes for a given tree and bit counts (which need not be - * optimal). - * IN assertion: the array bl_count contains the bit length statistics for - * the given tree and the field len is set for all tree elements. - * OUT assertion: the field code is set for all tree elements of non - * zero code length. - */ -const gen_codes = (tree, max_code, bl_count) => { -// ct_data *tree; /* the tree to decorate */ -// int max_code; /* largest code with non zero frequency */ -// ushf *bl_count; /* number of codes at each bit length */ - - const next_code = new Array(MAX_BITS$1 + 1); /* next code value for each bit length */ - let code = 0; /* running code value */ - let bits; /* bit index */ - let n; /* code index */ - - /* The distribution counts are first used to generate the code values - * without bit reversal. - */ - for (bits = 1; bits <= MAX_BITS$1; bits++) { - code = (code + bl_count[bits - 1]) << 1; - next_code[bits] = code; - } - /* Check that the bit counts in bl_count are consistent. The last code - * must be all ones. - */ - //Assert (code + bl_count[MAX_BITS]-1 == (1< { - - let n; /* iterates over tree elements */ - let bits; /* bit counter */ - let length; /* length value */ - let code; /* code value */ - let dist; /* distance index */ - const bl_count = new Array(MAX_BITS$1 + 1); - /* number of codes at each bit length for an optimal tree */ - - // do check in _tr_init() - //if (static_init_done) return; - - /* For some embedded targets, global variables are not initialized: */ -/*#ifdef NO_INIT_GLOBAL_POINTERS - static_l_desc.static_tree = static_ltree; - static_l_desc.extra_bits = extra_lbits; - static_d_desc.static_tree = static_dtree; - static_d_desc.extra_bits = extra_dbits; - static_bl_desc.extra_bits = extra_blbits; -#endif*/ - - /* Initialize the mapping length (0..255) -> length code (0..28) */ - length = 0; - for (code = 0; code < LENGTH_CODES$1$1 - 1; code++) { - base_length$1[code] = length; - for (n = 0; n < (1 << extra_lbits[code]); n++) { - _length_code$1[length++] = code; - } - } - //Assert (length == 256, "tr_static_init: length != 256"); - /* Note that the length 255 (match length 258) can be represented - * in two different ways: code 284 + 5 bits or code 285, so we - * overwrite length_code[255] to use the best encoding: - */ - _length_code$1[length - 1] = code; - - /* Initialize the mapping dist (0..32K) -> dist code (0..29) */ - dist = 0; - for (code = 0; code < 16; code++) { - base_dist$1[code] = dist; - for (n = 0; n < (1 << extra_dbits[code]); n++) { - _dist_code$1[dist++] = code; - } - } - //Assert (dist == 256, "tr_static_init: dist != 256"); - dist >>= 7; /* from now on, all distances are divided by 128 */ - for (; code < D_CODES$1$1; code++) { - base_dist$1[code] = dist << 7; - for (n = 0; n < (1 << (extra_dbits[code] - 7)); n++) { - _dist_code$1[256 + dist++] = code; - } - } - //Assert (dist == 256, "tr_static_init: 256+dist != 512"); - - /* Construct the codes of the static literal tree */ - for (bits = 0; bits <= MAX_BITS$1; bits++) { - bl_count[bits] = 0; - } - - n = 0; - while (n <= 143) { - static_ltree$1[n * 2 + 1]/*.Len*/ = 8; - n++; - bl_count[8]++; - } - while (n <= 255) { - static_ltree$1[n * 2 + 1]/*.Len*/ = 9; - n++; - bl_count[9]++; - } - while (n <= 279) { - static_ltree$1[n * 2 + 1]/*.Len*/ = 7; - n++; - bl_count[7]++; - } - while (n <= 287) { - static_ltree$1[n * 2 + 1]/*.Len*/ = 8; - n++; - bl_count[8]++; - } - /* Codes 286 and 287 do not exist, but we must include them in the - * tree construction to get a canonical Huffman tree (longest code - * all ones) - */ - gen_codes(static_ltree$1, L_CODES$1$1 + 1, bl_count); - - /* The static distance tree is trivial: */ - for (n = 0; n < D_CODES$1$1; n++) { - static_dtree$1[n * 2 + 1]/*.Len*/ = 5; - static_dtree$1[n * 2]/*.Code*/ = bi_reverse(n, 5); - } - - // Now data ready and we can init static trees - static_l_desc = new StaticTreeDesc(static_ltree$1, extra_lbits, LITERALS$1$1 + 1, L_CODES$1$1, MAX_BITS$1); - static_d_desc = new StaticTreeDesc(static_dtree$1, extra_dbits, 0, D_CODES$1$1, MAX_BITS$1); - static_bl_desc = new StaticTreeDesc(new Array(0), extra_blbits, 0, BL_CODES$1, MAX_BL_BITS); - - //static_init_done = true; -}; - - -/* =========================================================================== - * Initialize a new block. - */ -const init_block = (s) => { - - let n; /* iterates over tree elements */ - - /* Initialize the trees. */ - for (n = 0; n < L_CODES$1$1; n++) { s.dyn_ltree[n * 2]/*.Freq*/ = 0; } - for (n = 0; n < D_CODES$1$1; n++) { s.dyn_dtree[n * 2]/*.Freq*/ = 0; } - for (n = 0; n < BL_CODES$1; n++) { s.bl_tree[n * 2]/*.Freq*/ = 0; } - - s.dyn_ltree[END_BLOCK * 2]/*.Freq*/ = 1; - s.opt_len = s.static_len = 0; - s.sym_next = s.matches = 0; -}; - - -/* =========================================================================== - * Flush the bit buffer and align the output on a byte boundary - */ -const bi_windup = (s) => -{ - if (s.bi_valid > 8) { - put_short(s, s.bi_buf); - } else if (s.bi_valid > 0) { - //put_byte(s, (Byte)s->bi_buf); - s.pending_buf[s.pending++] = s.bi_buf; - } - s.bi_buf = 0; - s.bi_valid = 0; -}; - -/* =========================================================================== - * Compares to subtrees, using the tree depth as tie breaker when - * the subtrees have equal frequency. This minimizes the worst case length. - */ -const smaller = (tree, n, m, depth) => { - - const _n2 = n * 2; - const _m2 = m * 2; - return (tree[_n2]/*.Freq*/ < tree[_m2]/*.Freq*/ || - (tree[_n2]/*.Freq*/ === tree[_m2]/*.Freq*/ && depth[n] <= depth[m])); -}; - -/* =========================================================================== - * Restore the heap property by moving down the tree starting at node k, - * exchanging a node with the smallest of its two sons if necessary, stopping - * when the heap property is re-established (each father smaller than its - * two sons). - */ -const pqdownheap = (s, tree, k) => { -// deflate_state *s; -// ct_data *tree; /* the tree to restore */ -// int k; /* node to move down */ - - const v = s.heap[k]; - let j = k << 1; /* left son of k */ - while (j <= s.heap_len) { - /* Set j to the smallest of the two sons: */ - if (j < s.heap_len && - smaller(tree, s.heap[j + 1], s.heap[j], s.depth)) { - j++; - } - /* Exit if v is smaller than both sons */ - if (smaller(tree, v, s.heap[j], s.depth)) { break; } - - /* Exchange v with the smallest son */ - s.heap[k] = s.heap[j]; - k = j; - - /* And continue down the tree, setting j to the left son of k */ - j <<= 1; - } - s.heap[k] = v; -}; - - -// inlined manually -// const SMALLEST = 1; - -/* =========================================================================== - * Send the block data compressed using the given Huffman trees - */ -const compress_block = (s, ltree, dtree) => { -// deflate_state *s; -// const ct_data *ltree; /* literal tree */ -// const ct_data *dtree; /* distance tree */ - - let dist; /* distance of matched string */ - let lc; /* match length or unmatched char (if dist == 0) */ - let sx = 0; /* running index in sym_buf */ - let code; /* the code to send */ - let extra; /* number of extra bits to send */ - - if (s.sym_next !== 0) { - do { - dist = s.pending_buf[s.sym_buf + sx++] & 0xff; - dist += (s.pending_buf[s.sym_buf + sx++] & 0xff) << 8; - lc = s.pending_buf[s.sym_buf + sx++]; - if (dist === 0) { - send_code(s, lc, ltree); /* send a literal byte */ - //Tracecv(isgraph(lc), (stderr," '%c' ", lc)); - } else { - /* Here, lc is the match length - MIN_MATCH */ - code = _length_code$1[lc]; - send_code(s, code + LITERALS$1$1 + 1, ltree); /* send the length code */ - extra = extra_lbits[code]; - if (extra !== 0) { - lc -= base_length$1[code]; - send_bits(s, lc, extra); /* send the extra length bits */ - } - dist--; /* dist is now the match distance - 1 */ - code = d_code(dist); - //Assert (code < D_CODES, "bad d_code"); - - send_code(s, code, dtree); /* send the distance code */ - extra = extra_dbits[code]; - if (extra !== 0) { - dist -= base_dist$1[code]; - send_bits(s, dist, extra); /* send the extra distance bits */ - } - } /* literal or match pair ? */ - - /* Check that the overlay between pending_buf and sym_buf is ok: */ - //Assert(s->pending < s->lit_bufsize + sx, "pendingBuf overflow"); - - } while (sx < s.sym_next); - } - - send_code(s, END_BLOCK, ltree); -}; - - -/* =========================================================================== - * Construct one Huffman tree and assigns the code bit strings and lengths. - * Update the total bit length for the current block. - * IN assertion: the field freq is set for all tree elements. - * OUT assertions: the fields len and code are set to the optimal bit length - * and corresponding code. The length opt_len is updated; static_len is - * also updated if stree is not null. The field max_code is set. - */ -const build_tree = (s, desc) => { -// deflate_state *s; -// tree_desc *desc; /* the tree descriptor */ - - const tree = desc.dyn_tree; - const stree = desc.stat_desc.static_tree; - const has_stree = desc.stat_desc.has_stree; - const elems = desc.stat_desc.elems; - let n, m; /* iterate over heap elements */ - let max_code = -1; /* largest code with non zero frequency */ - let node; /* new node being created */ - - /* Construct the initial heap, with least frequent element in - * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. - * heap[0] is not used. - */ - s.heap_len = 0; - s.heap_max = HEAP_SIZE$1; - - for (n = 0; n < elems; n++) { - if (tree[n * 2]/*.Freq*/ !== 0) { - s.heap[++s.heap_len] = max_code = n; - s.depth[n] = 0; - - } else { - tree[n * 2 + 1]/*.Len*/ = 0; - } - } - - /* The pkzip format requires that at least one distance code exists, - * and that at least one bit should be sent even if there is only one - * possible code. So to avoid special checks later on we force at least - * two codes of non zero frequency. - */ - while (s.heap_len < 2) { - node = s.heap[++s.heap_len] = (max_code < 2 ? ++max_code : 0); - tree[node * 2]/*.Freq*/ = 1; - s.depth[node] = 0; - s.opt_len--; - - if (has_stree) { - s.static_len -= stree[node * 2 + 1]/*.Len*/; - } - /* node is 0 or 1 so it does not have extra bits */ - } - desc.max_code = max_code; - - /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, - * establish sub-heaps of increasing lengths: - */ - for (n = (s.heap_len >> 1/*int /2*/); n >= 1; n--) { pqdownheap(s, tree, n); } - - /* Construct the Huffman tree by repeatedly combining the least two - * frequent nodes. - */ - node = elems; /* next internal node of the tree */ - do { - //pqremove(s, tree, n); /* n = node of least frequency */ - /*** pqremove ***/ - n = s.heap[1/*SMALLEST*/]; - s.heap[1/*SMALLEST*/] = s.heap[s.heap_len--]; - pqdownheap(s, tree, 1/*SMALLEST*/); - /***/ - - m = s.heap[1/*SMALLEST*/]; /* m = node of next least frequency */ - - s.heap[--s.heap_max] = n; /* keep the nodes sorted by frequency */ - s.heap[--s.heap_max] = m; - - /* Create a new node father of n and m */ - tree[node * 2]/*.Freq*/ = tree[n * 2]/*.Freq*/ + tree[m * 2]/*.Freq*/; - s.depth[node] = (s.depth[n] >= s.depth[m] ? s.depth[n] : s.depth[m]) + 1; - tree[n * 2 + 1]/*.Dad*/ = tree[m * 2 + 1]/*.Dad*/ = node; - - /* and insert the new node in the heap */ - s.heap[1/*SMALLEST*/] = node++; - pqdownheap(s, tree, 1/*SMALLEST*/); - - } while (s.heap_len >= 2); - - s.heap[--s.heap_max] = s.heap[1/*SMALLEST*/]; - - /* At this point, the fields freq and dad are set. We can now - * generate the bit lengths. - */ - gen_bitlen(s, desc); - - /* The field len is now set, we can generate the bit codes */ - gen_codes(tree, max_code, s.bl_count); -}; - - -/* =========================================================================== - * Scan a literal or distance tree to determine the frequencies of the codes - * in the bit length tree. - */ -const scan_tree = (s, tree, max_code) => { -// deflate_state *s; -// ct_data *tree; /* the tree to be scanned */ -// int max_code; /* and its largest code of non zero frequency */ - - let n; /* iterates over all tree elements */ - let prevlen = -1; /* last emitted length */ - let curlen; /* length of current code */ - - let nextlen = tree[0 * 2 + 1]/*.Len*/; /* length of next code */ - - let count = 0; /* repeat count of the current code */ - let max_count = 7; /* max repeat count */ - let min_count = 4; /* min repeat count */ - - if (nextlen === 0) { - max_count = 138; - min_count = 3; - } - tree[(max_code + 1) * 2 + 1]/*.Len*/ = 0xffff; /* guard */ - - for (n = 0; n <= max_code; n++) { - curlen = nextlen; - nextlen = tree[(n + 1) * 2 + 1]/*.Len*/; - - if (++count < max_count && curlen === nextlen) { - continue; - - } else if (count < min_count) { - s.bl_tree[curlen * 2]/*.Freq*/ += count; - - } else if (curlen !== 0) { - - if (curlen !== prevlen) { s.bl_tree[curlen * 2]/*.Freq*/++; } - s.bl_tree[REP_3_6 * 2]/*.Freq*/++; - - } else if (count <= 10) { - s.bl_tree[REPZ_3_10 * 2]/*.Freq*/++; - - } else { - s.bl_tree[REPZ_11_138 * 2]/*.Freq*/++; - } - - count = 0; - prevlen = curlen; - - if (nextlen === 0) { - max_count = 138; - min_count = 3; - - } else if (curlen === nextlen) { - max_count = 6; - min_count = 3; - - } else { - max_count = 7; - min_count = 4; - } - } -}; - - -/* =========================================================================== - * Send a literal or distance tree in compressed form, using the codes in - * bl_tree. - */ -const send_tree = (s, tree, max_code) => { -// deflate_state *s; -// ct_data *tree; /* the tree to be scanned */ -// int max_code; /* and its largest code of non zero frequency */ - - let n; /* iterates over all tree elements */ - let prevlen = -1; /* last emitted length */ - let curlen; /* length of current code */ - - let nextlen = tree[0 * 2 + 1]/*.Len*/; /* length of next code */ - - let count = 0; /* repeat count of the current code */ - let max_count = 7; /* max repeat count */ - let min_count = 4; /* min repeat count */ - - /* tree[max_code+1].Len = -1; */ /* guard already set */ - if (nextlen === 0) { - max_count = 138; - min_count = 3; - } - - for (n = 0; n <= max_code; n++) { - curlen = nextlen; - nextlen = tree[(n + 1) * 2 + 1]/*.Len*/; - - if (++count < max_count && curlen === nextlen) { - continue; - - } else if (count < min_count) { - do { send_code(s, curlen, s.bl_tree); } while (--count !== 0); - - } else if (curlen !== 0) { - if (curlen !== prevlen) { - send_code(s, curlen, s.bl_tree); - count--; - } - //Assert(count >= 3 && count <= 6, " 3_6?"); - send_code(s, REP_3_6, s.bl_tree); - send_bits(s, count - 3, 2); - - } else if (count <= 10) { - send_code(s, REPZ_3_10, s.bl_tree); - send_bits(s, count - 3, 3); - - } else { - send_code(s, REPZ_11_138, s.bl_tree); - send_bits(s, count - 11, 7); - } - - count = 0; - prevlen = curlen; - if (nextlen === 0) { - max_count = 138; - min_count = 3; - - } else if (curlen === nextlen) { - max_count = 6; - min_count = 3; - - } else { - max_count = 7; - min_count = 4; - } - } -}; - - -/* =========================================================================== - * Construct the Huffman tree for the bit lengths and return the index in - * bl_order of the last bit length code to send. - */ -const build_bl_tree = (s) => { - - let max_blindex; /* index of last bit length code of non zero freq */ - - /* Determine the bit length frequencies for literal and distance trees */ - scan_tree(s, s.dyn_ltree, s.l_desc.max_code); - scan_tree(s, s.dyn_dtree, s.d_desc.max_code); - - /* Build the bit length tree: */ - build_tree(s, s.bl_desc); - /* opt_len now includes the length of the tree representations, except - * the lengths of the bit lengths codes and the 5+5+4 bits for the counts. - */ - - /* Determine the number of bit length codes to send. The pkzip format - * requires that at least 4 bit length codes be sent. (appnote.txt says - * 3 but the actual value used is 4.) - */ - for (max_blindex = BL_CODES$1 - 1; max_blindex >= 3; max_blindex--) { - if (s.bl_tree[bl_order[max_blindex] * 2 + 1]/*.Len*/ !== 0) { - break; - } - } - /* Update opt_len to include the bit length tree and counts */ - s.opt_len += 3 * (max_blindex + 1) + 5 + 5 + 4; - //Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", - // s->opt_len, s->static_len)); - - return max_blindex; -}; - - -/* =========================================================================== - * Send the header for a block using dynamic Huffman trees: the counts, the - * lengths of the bit length codes, the literal tree and the distance tree. - * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. - */ -const send_all_trees = (s, lcodes, dcodes, blcodes) => { -// deflate_state *s; -// int lcodes, dcodes, blcodes; /* number of codes for each tree */ - - let rank; /* index in bl_order */ - - //Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); - //Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, - // "too many codes"); - //Tracev((stderr, "\nbl counts: ")); - send_bits(s, lcodes - 257, 5); /* not +255 as stated in appnote.txt */ - send_bits(s, dcodes - 1, 5); - send_bits(s, blcodes - 4, 4); /* not -3 as stated in appnote.txt */ - for (rank = 0; rank < blcodes; rank++) { - //Tracev((stderr, "\nbl code %2d ", bl_order[rank])); - send_bits(s, s.bl_tree[bl_order[rank] * 2 + 1]/*.Len*/, 3); - } - //Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent)); - - send_tree(s, s.dyn_ltree, lcodes - 1); /* literal tree */ - //Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent)); - - send_tree(s, s.dyn_dtree, dcodes - 1); /* distance tree */ - //Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent)); -}; - - -/* =========================================================================== - * Check if the data type is TEXT or BINARY, using the following algorithm: - * - TEXT if the two conditions below are satisfied: - * a) There are no non-portable control characters belonging to the - * "block list" (0..6, 14..25, 28..31). - * b) There is at least one printable character belonging to the - * "allow list" (9 {TAB}, 10 {LF}, 13 {CR}, 32..255). - * - BINARY otherwise. - * - The following partially-portable control characters form a - * "gray list" that is ignored in this detection algorithm: - * (7 {BEL}, 8 {BS}, 11 {VT}, 12 {FF}, 26 {SUB}, 27 {ESC}). - * IN assertion: the fields Freq of dyn_ltree are set. - */ -const detect_data_type = (s) => { - /* block_mask is the bit mask of block-listed bytes - * set bits 0..6, 14..25, and 28..31 - * 0xf3ffc07f = binary 11110011111111111100000001111111 - */ - let block_mask = 0xf3ffc07f; - let n; - - /* Check for non-textual ("block-listed") bytes. */ - for (n = 0; n <= 31; n++, block_mask >>>= 1) { - if ((block_mask & 1) && (s.dyn_ltree[n * 2]/*.Freq*/ !== 0)) { - return Z_BINARY; - } - } - - /* Check for textual ("allow-listed") bytes. */ - if (s.dyn_ltree[9 * 2]/*.Freq*/ !== 0 || s.dyn_ltree[10 * 2]/*.Freq*/ !== 0 || - s.dyn_ltree[13 * 2]/*.Freq*/ !== 0) { - return Z_TEXT; - } - for (n = 32; n < LITERALS$1$1; n++) { - if (s.dyn_ltree[n * 2]/*.Freq*/ !== 0) { - return Z_TEXT; - } - } - - /* There are no "block-listed" or "allow-listed" bytes: - * this stream either is empty or has tolerated ("gray-listed") bytes only. - */ - return Z_BINARY; -}; - - -let static_init_done = false; - -/* =========================================================================== - * Initialize the tree data structures for a new zlib stream. - */ -const _tr_init$1 = (s) => -{ - - if (!static_init_done) { - tr_static_init(); - static_init_done = true; - } - - s.l_desc = new TreeDesc(s.dyn_ltree, static_l_desc); - s.d_desc = new TreeDesc(s.dyn_dtree, static_d_desc); - s.bl_desc = new TreeDesc(s.bl_tree, static_bl_desc); - - s.bi_buf = 0; - s.bi_valid = 0; - - /* Initialize the first block of the first file: */ - init_block(s); -}; - - -/* =========================================================================== - * Send a stored block - */ -const _tr_stored_block$1 = (s, buf, stored_len, last) => { -//DeflateState *s; -//charf *buf; /* input block */ -//ulg stored_len; /* length of input block */ -//int last; /* one if this is the last block for a file */ - - send_bits(s, (STORED_BLOCK << 1) + (last ? 1 : 0), 3); /* send block type */ - bi_windup(s); /* align on byte boundary */ - put_short(s, stored_len); - put_short(s, ~stored_len); - if (stored_len) { - s.pending_buf.set(s.window.subarray(buf, buf + stored_len), s.pending); - } - s.pending += stored_len; -}; - - -/* =========================================================================== - * Send one empty static block to give enough lookahead for inflate. - * This takes 10 bits, of which 7 may remain in the bit buffer. - */ -const _tr_align$1 = (s) => { - send_bits(s, STATIC_TREES << 1, 3); - send_code(s, END_BLOCK, static_ltree$1); - bi_flush(s); -}; - - -/* =========================================================================== - * Determine the best encoding for the current block: dynamic trees, static - * trees or store, and write out the encoded block. - */ -const _tr_flush_block$1 = (s, buf, stored_len, last) => { -//DeflateState *s; -//charf *buf; /* input block, or NULL if too old */ -//ulg stored_len; /* length of input block */ -//int last; /* one if this is the last block for a file */ - - let opt_lenb, static_lenb; /* opt_len and static_len in bytes */ - let max_blindex = 0; /* index of last bit length code of non zero freq */ - - /* Build the Huffman trees unless a stored block is forced */ - if (s.level > 0) { - - /* Check if the file is binary or text */ - if (s.strm.data_type === Z_UNKNOWN$1) { - s.strm.data_type = detect_data_type(s); - } - - /* Construct the literal and distance trees */ - build_tree(s, s.l_desc); - // Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len, - // s->static_len)); - - build_tree(s, s.d_desc); - // Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len, - // s->static_len)); - /* At this point, opt_len and static_len are the total bit lengths of - * the compressed block data, excluding the tree representations. - */ - - /* Build the bit length tree for the above two trees, and get the index - * in bl_order of the last bit length code to send. - */ - max_blindex = build_bl_tree(s); - - /* Determine the best encoding. Compute the block lengths in bytes. */ - opt_lenb = (s.opt_len + 3 + 7) >>> 3; - static_lenb = (s.static_len + 3 + 7) >>> 3; - - // Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ", - // opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len, - // s->sym_next / 3)); - - if (static_lenb <= opt_lenb) { opt_lenb = static_lenb; } - - } else { - // Assert(buf != (char*)0, "lost buf"); - opt_lenb = static_lenb = stored_len + 5; /* force a stored block */ - } - - if ((stored_len + 4 <= opt_lenb) && (buf !== -1)) { - /* 4: two words for the lengths */ - - /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. - * Otherwise we can't have processed more than WSIZE input bytes since - * the last block flush, because compression would have been - * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to - * transform a block into a stored block. - */ - _tr_stored_block$1(s, buf, stored_len, last); - - } else if (s.strategy === Z_FIXED$1 || static_lenb === opt_lenb) { - - send_bits(s, (STATIC_TREES << 1) + (last ? 1 : 0), 3); - compress_block(s, static_ltree$1, static_dtree$1); - - } else { - send_bits(s, (DYN_TREES << 1) + (last ? 1 : 0), 3); - send_all_trees(s, s.l_desc.max_code + 1, s.d_desc.max_code + 1, max_blindex + 1); - compress_block(s, s.dyn_ltree, s.dyn_dtree); - } - // Assert (s->compressed_len == s->bits_sent, "bad compressed size"); - /* The above check is made mod 2^32, for files larger than 512 MB - * and uLong implemented on 32 bits. - */ - init_block(s); - - if (last) { - bi_windup(s); - } - // Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3, - // s->compressed_len-7*last)); -}; - -/* =========================================================================== - * Save the match info and tally the frequency counts. Return true if - * the current block must be flushed. - */ -const _tr_tally$1 = (s, dist, lc) => { -// deflate_state *s; -// unsigned dist; /* distance of matched string */ -// unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */ - - s.pending_buf[s.sym_buf + s.sym_next++] = dist; - s.pending_buf[s.sym_buf + s.sym_next++] = dist >> 8; - s.pending_buf[s.sym_buf + s.sym_next++] = lc; - if (dist === 0) { - /* lc is the unmatched char */ - s.dyn_ltree[lc * 2]/*.Freq*/++; - } else { - s.matches++; - /* Here, lc is the match length - MIN_MATCH */ - dist--; /* dist = match distance - 1 */ - //Assert((ush)dist < (ush)MAX_DIST(s) && - // (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) && - // (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match"); - - s.dyn_ltree[(_length_code$1[lc] + LITERALS$1$1 + 1) * 2]/*.Freq*/++; - s.dyn_dtree[d_code(dist) * 2]/*.Freq*/++; - } - - return (s.sym_next === s.sym_end); -}; - -var _tr_init_1 = _tr_init$1; -var _tr_stored_block_1 = _tr_stored_block$1; -var _tr_flush_block_1 = _tr_flush_block$1; -var _tr_tally_1 = _tr_tally$1; -var _tr_align_1 = _tr_align$1; - -var trees = { - _tr_init: _tr_init_1, - _tr_stored_block: _tr_stored_block_1, - _tr_flush_block: _tr_flush_block_1, - _tr_tally: _tr_tally_1, - _tr_align: _tr_align_1 -}; - -// Note: adler32 takes 12% for level 0 and 2% for level 6. -// It isn't worth it to make additional optimizations as in original. -// Small size is preferable. - -// (C) 1995-2013 Jean-loup Gailly and Mark Adler -// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// 3. This notice may not be removed or altered from any source distribution. - -const adler32$1 = (adler, buf, len, pos) => { - let s1 = (adler & 0xffff) |0, - s2 = ((adler >>> 16) & 0xffff) |0, - n = 0; - - while (len !== 0) { - // Set limit ~ twice less than 5552, to keep - // s2 in 31-bits, because we force signed ints. - // in other case %= will fail. - n = len > 2000 ? 2000 : len; - len -= n; - - do { - s1 = (s1 + buf[pos++]) |0; - s2 = (s2 + s1) |0; - } while (--n); - - s1 %= 65521; - s2 %= 65521; - } - - return (s1 | (s2 << 16)) |0; -}; - - -var adler32_1$1 = adler32$1; - -// Note: we can't get significant speed boost here. -// So write code to minimize size - no pregenerated tables -// and array tools dependencies. - -// (C) 1995-2013 Jean-loup Gailly and Mark Adler -// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// 3. This notice may not be removed or altered from any source distribution. - -// Use ordinary array, since untyped makes no boost here -const makeTable$1 = () => { - let c, table = []; - - for (var n = 0; n < 256; n++) { - c = n; - for (var k = 0; k < 8; k++) { - c = ((c & 1) ? (0xEDB88320 ^ (c >>> 1)) : (c >>> 1)); - } - table[n] = c; - } - - return table; -}; - -// Create table on load. Just 255 signed longs. Not a problem. -const crcTable$1 = new Uint32Array(makeTable$1()); - - -const crc32$1 = (crc, buf, len, pos) => { - const t = crcTable$1; - const end = pos + len; - - crc ^= -1; - - for (let i = pos; i < end; i++) { - crc = (crc >>> 8) ^ t[(crc ^ buf[i]) & 0xFF]; - } - - return (crc ^ (-1)); // >>> 0; -}; - - -var crc32_1$1 = crc32$1; - -// (C) 1995-2013 Jean-loup Gailly and Mark Adler -// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// 3. This notice may not be removed or altered from any source distribution. - -var messages$1 = { - 2: 'need dictionary', /* Z_NEED_DICT 2 */ - 1: 'stream end', /* Z_STREAM_END 1 */ - 0: '', /* Z_OK 0 */ - '-1': 'file error', /* Z_ERRNO (-1) */ - '-2': 'stream error', /* Z_STREAM_ERROR (-2) */ - '-3': 'data error', /* Z_DATA_ERROR (-3) */ - '-4': 'insufficient memory', /* Z_MEM_ERROR (-4) */ - '-5': 'buffer error', /* Z_BUF_ERROR (-5) */ - '-6': 'incompatible version' /* Z_VERSION_ERROR (-6) */ -}; - -// (C) 1995-2013 Jean-loup Gailly and Mark Adler -// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// 3. This notice may not be removed or altered from any source distribution. - -var constants$2$1 = { - - /* Allowed flush values; see deflate() and inflate() below for details */ - Z_NO_FLUSH: 0, - Z_PARTIAL_FLUSH: 1, - Z_SYNC_FLUSH: 2, - Z_FULL_FLUSH: 3, - Z_FINISH: 4, - Z_BLOCK: 5, - Z_TREES: 6, - - /* Return codes for the compression/decompression functions. Negative values - * are errors, positive values are used for special but normal events. - */ - Z_OK: 0, - Z_STREAM_END: 1, - Z_NEED_DICT: 2, - Z_ERRNO: -1, - Z_STREAM_ERROR: -2, - Z_DATA_ERROR: -3, - Z_MEM_ERROR: -4, - Z_BUF_ERROR: -5, - //Z_VERSION_ERROR: -6, - - /* compression levels */ - Z_NO_COMPRESSION: 0, - Z_BEST_SPEED: 1, - Z_BEST_COMPRESSION: 9, - Z_DEFAULT_COMPRESSION: -1, - - - Z_FILTERED: 1, - Z_HUFFMAN_ONLY: 2, - Z_RLE: 3, - Z_FIXED: 4, - Z_DEFAULT_STRATEGY: 0, - - /* Possible values of the data_type field (though see inflate()) */ - Z_BINARY: 0, - Z_TEXT: 1, - //Z_ASCII: 1, // = Z_TEXT (deprecated) - Z_UNKNOWN: 2, - - /* The deflate compression method */ - Z_DEFLATED: 8 - //Z_NULL: null // Use -1 or null inline, depending on var type -}; - -// (C) 1995-2013 Jean-loup Gailly and Mark Adler -// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// 3. This notice may not be removed or altered from any source distribution. - -const { _tr_init, _tr_stored_block, _tr_flush_block, _tr_tally, _tr_align } = trees; - - - - -/* Public constants ==========================================================*/ -/* ===========================================================================*/ - -const { - Z_NO_FLUSH: Z_NO_FLUSH$2, Z_PARTIAL_FLUSH, Z_FULL_FLUSH: Z_FULL_FLUSH$1, Z_FINISH: Z_FINISH$3, Z_BLOCK: Z_BLOCK$1, - Z_OK: Z_OK$3, Z_STREAM_END: Z_STREAM_END$3, Z_STREAM_ERROR: Z_STREAM_ERROR$2, Z_DATA_ERROR: Z_DATA_ERROR$2, Z_BUF_ERROR: Z_BUF_ERROR$1, - Z_DEFAULT_COMPRESSION: Z_DEFAULT_COMPRESSION$1, - Z_FILTERED, Z_HUFFMAN_ONLY, Z_RLE, Z_FIXED, Z_DEFAULT_STRATEGY: Z_DEFAULT_STRATEGY$1, - Z_UNKNOWN, - Z_DEFLATED: Z_DEFLATED$2 -} = constants$2$1; - -/*============================================================================*/ - - -const MAX_MEM_LEVEL = 9; -/* Maximum value for memLevel in deflateInit2 */ -const MAX_WBITS$1 = 15; -/* 32K LZ77 window */ -const DEF_MEM_LEVEL = 8; - - -const LENGTH_CODES = 29; -/* number of length codes, not counting the special END_BLOCK code */ -const LITERALS = 256; -/* number of literal bytes 0..255 */ -const L_CODES = LITERALS + 1 + LENGTH_CODES; -/* number of Literal or Length codes, including the END_BLOCK code */ -const D_CODES = 30; -/* number of distance codes */ -const BL_CODES = 19; -/* number of codes used to transfer the bit lengths */ -const HEAP_SIZE = 2 * L_CODES + 1; -/* maximum heap size */ -const MAX_BITS = 15; -/* All codes must not exceed MAX_BITS bits */ - -const MIN_MATCH = 3; -const MAX_MATCH = 258; -const MIN_LOOKAHEAD = (MAX_MATCH + MIN_MATCH + 1); - -const PRESET_DICT = 0x20; - -const INIT_STATE = 42; /* zlib header -> BUSY_STATE */ -//#ifdef GZIP -const GZIP_STATE = 57; /* gzip header -> BUSY_STATE | EXTRA_STATE */ -//#endif -const EXTRA_STATE = 69; /* gzip extra block -> NAME_STATE */ -const NAME_STATE = 73; /* gzip file name -> COMMENT_STATE */ -const COMMENT_STATE = 91; /* gzip comment -> HCRC_STATE */ -const HCRC_STATE = 103; /* gzip header CRC -> BUSY_STATE */ -const BUSY_STATE = 113; /* deflate -> FINISH_STATE */ -const FINISH_STATE = 666; /* stream complete */ - -const BS_NEED_MORE = 1; /* block not completed, need more input or more output */ -const BS_BLOCK_DONE = 2; /* block flush performed */ -const BS_FINISH_STARTED = 3; /* finish started, need only more output at next deflate */ -const BS_FINISH_DONE = 4; /* finish done, accept no more input or output */ - -const OS_CODE = 0x03; // Unix :) . Don't detect, use this default. - -const err = (strm, errorCode) => { - strm.msg = messages$1[errorCode]; - return errorCode; -}; - -const rank = (f) => { - return ((f) * 2) - ((f) > 4 ? 9 : 0); -}; - -const zero = (buf) => { - let len = buf.length; while (--len >= 0) { buf[len] = 0; } -}; - -/* =========================================================================== - * Slide the hash table when sliding the window down (could be avoided with 32 - * bit values at the expense of memory usage). We slide even when level == 0 to - * keep the hash table consistent if we switch back to level > 0 later. - */ -const slide_hash = (s) => { - let n, m; - let p; - let wsize = s.w_size; - - n = s.hash_size; - p = n; - do { - m = s.head[--p]; - s.head[p] = (m >= wsize ? m - wsize : 0); - } while (--n); - n = wsize; -//#ifndef FASTEST - p = n; - do { - m = s.prev[--p]; - s.prev[p] = (m >= wsize ? m - wsize : 0); - /* If n is not on any hash chain, prev[n] is garbage but - * its value will never be used. - */ - } while (--n); -//#endif -}; - -/* eslint-disable new-cap */ -let HASH_ZLIB = (s, prev, data) => ((prev << s.hash_shift) ^ data) & s.hash_mask; -// This hash causes less collisions, https://github.com/nodeca/pako/issues/135 -// But breaks binary compatibility -//let HASH_FAST = (s, prev, data) => ((prev << 8) + (prev >> 8) + (data << 4)) & s.hash_mask; -let HASH = HASH_ZLIB; - - -/* ========================================================================= - * Flush as much pending output as possible. All deflate() output, except for - * some deflate_stored() output, goes through this function so some - * applications may wish to modify it to avoid allocating a large - * strm->next_out buffer and copying into it. (See also read_buf()). - */ -const flush_pending = (strm) => { - const s = strm.state; - - //_tr_flush_bits(s); - let len = s.pending; - if (len > strm.avail_out) { - len = strm.avail_out; - } - if (len === 0) { return; } - - strm.output.set(s.pending_buf.subarray(s.pending_out, s.pending_out + len), strm.next_out); - strm.next_out += len; - s.pending_out += len; - strm.total_out += len; - strm.avail_out -= len; - s.pending -= len; - if (s.pending === 0) { - s.pending_out = 0; - } -}; - - -const flush_block_only = (s, last) => { - _tr_flush_block(s, (s.block_start >= 0 ? s.block_start : -1), s.strstart - s.block_start, last); - s.block_start = s.strstart; - flush_pending(s.strm); -}; - - -const put_byte = (s, b) => { - s.pending_buf[s.pending++] = b; -}; - - -/* ========================================================================= - * Put a short in the pending buffer. The 16-bit value is put in MSB order. - * IN assertion: the stream state is correct and there is enough room in - * pending_buf. - */ -const putShortMSB = (s, b) => { - - // put_byte(s, (Byte)(b >> 8)); -// put_byte(s, (Byte)(b & 0xff)); - s.pending_buf[s.pending++] = (b >>> 8) & 0xff; - s.pending_buf[s.pending++] = b & 0xff; -}; - - -/* =========================================================================== - * Read a new buffer from the current input stream, update the adler32 - * and total number of bytes read. All deflate() input goes through - * this function so some applications may wish to modify it to avoid - * allocating a large strm->input buffer and copying from it. - * (See also flush_pending()). - */ -const read_buf = (strm, buf, start, size) => { - - let len = strm.avail_in; - - if (len > size) { len = size; } - if (len === 0) { return 0; } - - strm.avail_in -= len; - - // zmemcpy(buf, strm->next_in, len); - buf.set(strm.input.subarray(strm.next_in, strm.next_in + len), start); - if (strm.state.wrap === 1) { - strm.adler = adler32_1$1(strm.adler, buf, len, start); - } - - else if (strm.state.wrap === 2) { - strm.adler = crc32_1$1(strm.adler, buf, len, start); - } - - strm.next_in += len; - strm.total_in += len; - - return len; -}; - - -/* =========================================================================== - * Set match_start to the longest match starting at the given string and - * return its length. Matches shorter or equal to prev_length are discarded, - * in which case the result is equal to prev_length and match_start is - * garbage. - * IN assertions: cur_match is the head of the hash chain for the current - * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 - * OUT assertion: the match length is not greater than s->lookahead. - */ -const longest_match = (s, cur_match) => { - - let chain_length = s.max_chain_length; /* max hash chain length */ - let scan = s.strstart; /* current string */ - let match; /* matched string */ - let len; /* length of current match */ - let best_len = s.prev_length; /* best match length so far */ - let nice_match = s.nice_match; /* stop if match long enough */ - const limit = (s.strstart > (s.w_size - MIN_LOOKAHEAD)) ? - s.strstart - (s.w_size - MIN_LOOKAHEAD) : 0/*NIL*/; - - const _win = s.window; // shortcut - - const wmask = s.w_mask; - const prev = s.prev; - - /* Stop when cur_match becomes <= limit. To simplify the code, - * we prevent matches with the string of window index 0. - */ - - const strend = s.strstart + MAX_MATCH; - let scan_end1 = _win[scan + best_len - 1]; - let scan_end = _win[scan + best_len]; - - /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. - * It is easy to get rid of this optimization if necessary. - */ - // Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); - - /* Do not waste too much time if we already have a good match: */ - if (s.prev_length >= s.good_match) { - chain_length >>= 2; - } - /* Do not look for matches beyond the end of the input. This is necessary - * to make deflate deterministic. - */ - if (nice_match > s.lookahead) { nice_match = s.lookahead; } - - // Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); - - do { - // Assert(cur_match < s->strstart, "no future"); - match = cur_match; - - /* Skip to next match if the match length cannot increase - * or if the match length is less than 2. Note that the checks below - * for insufficient lookahead only occur occasionally for performance - * reasons. Therefore uninitialized memory will be accessed, and - * conditional jumps will be made that depend on those values. - * However the length of the match is limited to the lookahead, so - * the output of deflate is not affected by the uninitialized values. - */ - - if (_win[match + best_len] !== scan_end || - _win[match + best_len - 1] !== scan_end1 || - _win[match] !== _win[scan] || - _win[++match] !== _win[scan + 1]) { - continue; - } - - /* The check at best_len-1 can be removed because it will be made - * again later. (This heuristic is not always a win.) - * It is not necessary to compare scan[2] and match[2] since they - * are always equal when the other bytes match, given that - * the hash keys are equal and that HASH_BITS >= 8. - */ - scan += 2; - match++; - // Assert(*scan == *match, "match[2]?"); - - /* We check for insufficient lookahead only every 8th comparison; - * the 256th check will be made at strstart+258. - */ - do { - /*jshint noempty:false*/ - } while (_win[++scan] === _win[++match] && _win[++scan] === _win[++match] && - _win[++scan] === _win[++match] && _win[++scan] === _win[++match] && - _win[++scan] === _win[++match] && _win[++scan] === _win[++match] && - _win[++scan] === _win[++match] && _win[++scan] === _win[++match] && - scan < strend); - - // Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); - - len = MAX_MATCH - (strend - scan); - scan = strend - MAX_MATCH; - - if (len > best_len) { - s.match_start = cur_match; - best_len = len; - if (len >= nice_match) { - break; - } - scan_end1 = _win[scan + best_len - 1]; - scan_end = _win[scan + best_len]; - } - } while ((cur_match = prev[cur_match & wmask]) > limit && --chain_length !== 0); - - if (best_len <= s.lookahead) { - return best_len; - } - return s.lookahead; -}; - - -/* =========================================================================== - * Fill the window when the lookahead becomes insufficient. - * Updates strstart and lookahead. - * - * IN assertion: lookahead < MIN_LOOKAHEAD - * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD - * At least one byte has been read, or avail_in == 0; reads are - * performed for at least two bytes (required for the zip translate_eol - * option -- not supported here). - */ -const fill_window = (s) => { - - const _w_size = s.w_size; - let n, more, str; - - //Assert(s->lookahead < MIN_LOOKAHEAD, "already enough lookahead"); - - do { - more = s.window_size - s.lookahead - s.strstart; - - // JS ints have 32 bit, block below not needed - /* Deal with !@#$% 64K limit: */ - //if (sizeof(int) <= 2) { - // if (more == 0 && s->strstart == 0 && s->lookahead == 0) { - // more = wsize; - // - // } else if (more == (unsigned)(-1)) { - // /* Very unlikely, but possible on 16 bit machine if - // * strstart == 0 && lookahead == 1 (input done a byte at time) - // */ - // more--; - // } - //} - - - /* If the window is almost full and there is insufficient lookahead, - * move the upper half to the lower one to make room in the upper half. - */ - if (s.strstart >= _w_size + (_w_size - MIN_LOOKAHEAD)) { - - s.window.set(s.window.subarray(_w_size, _w_size + _w_size - more), 0); - s.match_start -= _w_size; - s.strstart -= _w_size; - /* we now have strstart >= MAX_DIST */ - s.block_start -= _w_size; - if (s.insert > s.strstart) { - s.insert = s.strstart; - } - slide_hash(s); - more += _w_size; - } - if (s.strm.avail_in === 0) { - break; - } - - /* If there was no sliding: - * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && - * more == window_size - lookahead - strstart - * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) - * => more >= window_size - 2*WSIZE + 2 - * In the BIG_MEM or MMAP case (not yet supported), - * window_size == input_size + MIN_LOOKAHEAD && - * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. - * Otherwise, window_size == 2*WSIZE so more >= 2. - * If there was sliding, more >= WSIZE. So in all cases, more >= 2. - */ - //Assert(more >= 2, "more < 2"); - n = read_buf(s.strm, s.window, s.strstart + s.lookahead, more); - s.lookahead += n; - - /* Initialize the hash value now that we have some input: */ - if (s.lookahead + s.insert >= MIN_MATCH) { - str = s.strstart - s.insert; - s.ins_h = s.window[str]; - - /* UPDATE_HASH(s, s->ins_h, s->window[str + 1]); */ - s.ins_h = HASH(s, s.ins_h, s.window[str + 1]); -//#if MIN_MATCH != 3 -// Call update_hash() MIN_MATCH-3 more times -//#endif - while (s.insert) { - /* UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); */ - s.ins_h = HASH(s, s.ins_h, s.window[str + MIN_MATCH - 1]); - - s.prev[str & s.w_mask] = s.head[s.ins_h]; - s.head[s.ins_h] = str; - str++; - s.insert--; - if (s.lookahead + s.insert < MIN_MATCH) { - break; - } - } - } - /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage, - * but this is not important since only literal bytes will be emitted. - */ - - } while (s.lookahead < MIN_LOOKAHEAD && s.strm.avail_in !== 0); - - /* If the WIN_INIT bytes after the end of the current data have never been - * written, then zero those bytes in order to avoid memory check reports of - * the use of uninitialized (or uninitialised as Julian writes) bytes by - * the longest match routines. Update the high water mark for the next - * time through here. WIN_INIT is set to MAX_MATCH since the longest match - * routines allow scanning to strstart + MAX_MATCH, ignoring lookahead. - */ -// if (s.high_water < s.window_size) { -// const curr = s.strstart + s.lookahead; -// let init = 0; -// -// if (s.high_water < curr) { -// /* Previous high water mark below current data -- zero WIN_INIT -// * bytes or up to end of window, whichever is less. -// */ -// init = s.window_size - curr; -// if (init > WIN_INIT) -// init = WIN_INIT; -// zmemzero(s->window + curr, (unsigned)init); -// s->high_water = curr + init; -// } -// else if (s->high_water < (ulg)curr + WIN_INIT) { -// /* High water mark at or above current data, but below current data -// * plus WIN_INIT -- zero out to current data plus WIN_INIT, or up -// * to end of window, whichever is less. -// */ -// init = (ulg)curr + WIN_INIT - s->high_water; -// if (init > s->window_size - s->high_water) -// init = s->window_size - s->high_water; -// zmemzero(s->window + s->high_water, (unsigned)init); -// s->high_water += init; -// } -// } -// -// Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD, -// "not enough room for search"); -}; - -/* =========================================================================== - * Copy without compression as much as possible from the input stream, return - * the current block state. - * - * In case deflateParams() is used to later switch to a non-zero compression - * level, s->matches (otherwise unused when storing) keeps track of the number - * of hash table slides to perform. If s->matches is 1, then one hash table - * slide will be done when switching. If s->matches is 2, the maximum value - * allowed here, then the hash table will be cleared, since two or more slides - * is the same as a clear. - * - * deflate_stored() is written to minimize the number of times an input byte is - * copied. It is most efficient with large input and output buffers, which - * maximizes the opportunites to have a single copy from next_in to next_out. - */ -const deflate_stored = (s, flush) => { - - /* Smallest worthy block size when not flushing or finishing. By default - * this is 32K. This can be as small as 507 bytes for memLevel == 1. For - * large input and output buffers, the stored block size will be larger. - */ - let min_block = s.pending_buf_size - 5 > s.w_size ? s.w_size : s.pending_buf_size - 5; - - /* Copy as many min_block or larger stored blocks directly to next_out as - * possible. If flushing, copy the remaining available input to next_out as - * stored blocks, if there is enough space. - */ - let len, left, have, last = 0; - let used = s.strm.avail_in; - do { - /* Set len to the maximum size block that we can copy directly with the - * available input data and output space. Set left to how much of that - * would be copied from what's left in the window. - */ - len = 65535/* MAX_STORED */; /* maximum deflate stored block length */ - have = (s.bi_valid + 42) >> 3; /* number of header bytes */ - if (s.strm.avail_out < have) { /* need room for header */ - break; - } - /* maximum stored block length that will fit in avail_out: */ - have = s.strm.avail_out - have; - left = s.strstart - s.block_start; /* bytes left in window */ - if (len > left + s.strm.avail_in) { - len = left + s.strm.avail_in; /* limit len to the input */ - } - if (len > have) { - len = have; /* limit len to the output */ - } - - /* If the stored block would be less than min_block in length, or if - * unable to copy all of the available input when flushing, then try - * copying to the window and the pending buffer instead. Also don't - * write an empty block when flushing -- deflate() does that. - */ - if (len < min_block && ((len === 0 && flush !== Z_FINISH$3) || - flush === Z_NO_FLUSH$2 || - len !== left + s.strm.avail_in)) { - break; - } - - /* Make a dummy stored block in pending to get the header bytes, - * including any pending bits. This also updates the debugging counts. - */ - last = flush === Z_FINISH$3 && len === left + s.strm.avail_in ? 1 : 0; - _tr_stored_block(s, 0, 0, last); - - /* Replace the lengths in the dummy stored block with len. */ - s.pending_buf[s.pending - 4] = len; - s.pending_buf[s.pending - 3] = len >> 8; - s.pending_buf[s.pending - 2] = ~len; - s.pending_buf[s.pending - 1] = ~len >> 8; - - /* Write the stored block header bytes. */ - flush_pending(s.strm); - -//#ifdef ZLIB_DEBUG -// /* Update debugging counts for the data about to be copied. */ -// s->compressed_len += len << 3; -// s->bits_sent += len << 3; -//#endif - - /* Copy uncompressed bytes from the window to next_out. */ - if (left) { - if (left > len) { - left = len; - } - //zmemcpy(s->strm->next_out, s->window + s->block_start, left); - s.strm.output.set(s.window.subarray(s.block_start, s.block_start + left), s.strm.next_out); - s.strm.next_out += left; - s.strm.avail_out -= left; - s.strm.total_out += left; - s.block_start += left; - len -= left; - } - - /* Copy uncompressed bytes directly from next_in to next_out, updating - * the check value. - */ - if (len) { - read_buf(s.strm, s.strm.output, s.strm.next_out, len); - s.strm.next_out += len; - s.strm.avail_out -= len; - s.strm.total_out += len; - } - } while (last === 0); - - /* Update the sliding window with the last s->w_size bytes of the copied - * data, or append all of the copied data to the existing window if less - * than s->w_size bytes were copied. Also update the number of bytes to - * insert in the hash tables, in the event that deflateParams() switches to - * a non-zero compression level. - */ - used -= s.strm.avail_in; /* number of input bytes directly copied */ - if (used) { - /* If any input was used, then no unused input remains in the window, - * therefore s->block_start == s->strstart. - */ - if (used >= s.w_size) { /* supplant the previous history */ - s.matches = 2; /* clear hash */ - //zmemcpy(s->window, s->strm->next_in - s->w_size, s->w_size); - s.window.set(s.strm.input.subarray(s.strm.next_in - s.w_size, s.strm.next_in), 0); - s.strstart = s.w_size; - s.insert = s.strstart; - } - else { - if (s.window_size - s.strstart <= used) { - /* Slide the window down. */ - s.strstart -= s.w_size; - //zmemcpy(s->window, s->window + s->w_size, s->strstart); - s.window.set(s.window.subarray(s.w_size, s.w_size + s.strstart), 0); - if (s.matches < 2) { - s.matches++; /* add a pending slide_hash() */ - } - if (s.insert > s.strstart) { - s.insert = s.strstart; - } - } - //zmemcpy(s->window + s->strstart, s->strm->next_in - used, used); - s.window.set(s.strm.input.subarray(s.strm.next_in - used, s.strm.next_in), s.strstart); - s.strstart += used; - s.insert += used > s.w_size - s.insert ? s.w_size - s.insert : used; - } - s.block_start = s.strstart; - } - if (s.high_water < s.strstart) { - s.high_water = s.strstart; - } - - /* If the last block was written to next_out, then done. */ - if (last) { - return BS_FINISH_DONE; - } - - /* If flushing and all input has been consumed, then done. */ - if (flush !== Z_NO_FLUSH$2 && flush !== Z_FINISH$3 && - s.strm.avail_in === 0 && s.strstart === s.block_start) { - return BS_BLOCK_DONE; - } - - /* Fill the window with any remaining input. */ - have = s.window_size - s.strstart; - if (s.strm.avail_in > have && s.block_start >= s.w_size) { - /* Slide the window down. */ - s.block_start -= s.w_size; - s.strstart -= s.w_size; - //zmemcpy(s->window, s->window + s->w_size, s->strstart); - s.window.set(s.window.subarray(s.w_size, s.w_size + s.strstart), 0); - if (s.matches < 2) { - s.matches++; /* add a pending slide_hash() */ - } - have += s.w_size; /* more space now */ - if (s.insert > s.strstart) { - s.insert = s.strstart; - } - } - if (have > s.strm.avail_in) { - have = s.strm.avail_in; - } - if (have) { - read_buf(s.strm, s.window, s.strstart, have); - s.strstart += have; - s.insert += have > s.w_size - s.insert ? s.w_size - s.insert : have; - } - if (s.high_water < s.strstart) { - s.high_water = s.strstart; - } - - /* There was not enough avail_out to write a complete worthy or flushed - * stored block to next_out. Write a stored block to pending instead, if we - * have enough input for a worthy block, or if flushing and there is enough - * room for the remaining input as a stored block in the pending buffer. - */ - have = (s.bi_valid + 42) >> 3; /* number of header bytes */ - /* maximum stored block length that will fit in pending: */ - have = s.pending_buf_size - have > 65535/* MAX_STORED */ ? 65535/* MAX_STORED */ : s.pending_buf_size - have; - min_block = have > s.w_size ? s.w_size : have; - left = s.strstart - s.block_start; - if (left >= min_block || - ((left || flush === Z_FINISH$3) && flush !== Z_NO_FLUSH$2 && - s.strm.avail_in === 0 && left <= have)) { - len = left > have ? have : left; - last = flush === Z_FINISH$3 && s.strm.avail_in === 0 && - len === left ? 1 : 0; - _tr_stored_block(s, s.block_start, len, last); - s.block_start += len; - flush_pending(s.strm); - } - - /* We've done all we can with the available input and output. */ - return last ? BS_FINISH_STARTED : BS_NEED_MORE; -}; - - -/* =========================================================================== - * Compress as much as possible from the input stream, return the current - * block state. - * This function does not perform lazy evaluation of matches and inserts - * new strings in the dictionary only for unmatched strings or for short - * matches. It is used only for the fast compression options. - */ -const deflate_fast = (s, flush) => { - - let hash_head; /* head of the hash chain */ - let bflush; /* set if current block must be flushed */ - - for (;;) { - /* Make sure that we always have enough lookahead, except - * at the end of the input file. We need MAX_MATCH bytes - * for the next match, plus MIN_MATCH bytes to insert the - * string following the next match. - */ - if (s.lookahead < MIN_LOOKAHEAD) { - fill_window(s); - if (s.lookahead < MIN_LOOKAHEAD && flush === Z_NO_FLUSH$2) { - return BS_NEED_MORE; - } - if (s.lookahead === 0) { - break; /* flush the current block */ - } - } - - /* Insert the string window[strstart .. strstart+2] in the - * dictionary, and set hash_head to the head of the hash chain: - */ - hash_head = 0/*NIL*/; - if (s.lookahead >= MIN_MATCH) { - /*** INSERT_STRING(s, s.strstart, hash_head); ***/ - s.ins_h = HASH(s, s.ins_h, s.window[s.strstart + MIN_MATCH - 1]); - hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h]; - s.head[s.ins_h] = s.strstart; - /***/ - } - - /* Find the longest match, discarding those <= prev_length. - * At this point we have always match_length < MIN_MATCH - */ - if (hash_head !== 0/*NIL*/ && ((s.strstart - hash_head) <= (s.w_size - MIN_LOOKAHEAD))) { - /* To simplify the code, we prevent matches with the string - * of window index 0 (in particular we have to avoid a match - * of the string with itself at the start of the input file). - */ - s.match_length = longest_match(s, hash_head); - /* longest_match() sets match_start */ - } - if (s.match_length >= MIN_MATCH) { - // check_match(s, s.strstart, s.match_start, s.match_length); // for debug only - - /*** _tr_tally_dist(s, s.strstart - s.match_start, - s.match_length - MIN_MATCH, bflush); ***/ - bflush = _tr_tally(s, s.strstart - s.match_start, s.match_length - MIN_MATCH); - - s.lookahead -= s.match_length; - - /* Insert new strings in the hash table only if the match length - * is not too large. This saves time but degrades compression. - */ - if (s.match_length <= s.max_lazy_match/*max_insert_length*/ && s.lookahead >= MIN_MATCH) { - s.match_length--; /* string at strstart already in table */ - do { - s.strstart++; - /*** INSERT_STRING(s, s.strstart, hash_head); ***/ - s.ins_h = HASH(s, s.ins_h, s.window[s.strstart + MIN_MATCH - 1]); - hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h]; - s.head[s.ins_h] = s.strstart; - /***/ - /* strstart never exceeds WSIZE-MAX_MATCH, so there are - * always MIN_MATCH bytes ahead. - */ - } while (--s.match_length !== 0); - s.strstart++; - } else - { - s.strstart += s.match_length; - s.match_length = 0; - s.ins_h = s.window[s.strstart]; - /* UPDATE_HASH(s, s.ins_h, s.window[s.strstart+1]); */ - s.ins_h = HASH(s, s.ins_h, s.window[s.strstart + 1]); - -//#if MIN_MATCH != 3 -// Call UPDATE_HASH() MIN_MATCH-3 more times -//#endif - /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not - * matter since it will be recomputed at next deflate call. - */ - } - } else { - /* No match, output a literal byte */ - //Tracevv((stderr,"%c", s.window[s.strstart])); - /*** _tr_tally_lit(s, s.window[s.strstart], bflush); ***/ - bflush = _tr_tally(s, 0, s.window[s.strstart]); - - s.lookahead--; - s.strstart++; - } - if (bflush) { - /*** FLUSH_BLOCK(s, 0); ***/ - flush_block_only(s, false); - if (s.strm.avail_out === 0) { - return BS_NEED_MORE; - } - /***/ - } - } - s.insert = ((s.strstart < (MIN_MATCH - 1)) ? s.strstart : MIN_MATCH - 1); - if (flush === Z_FINISH$3) { - /*** FLUSH_BLOCK(s, 1); ***/ - flush_block_only(s, true); - if (s.strm.avail_out === 0) { - return BS_FINISH_STARTED; - } - /***/ - return BS_FINISH_DONE; - } - if (s.sym_next) { - /*** FLUSH_BLOCK(s, 0); ***/ - flush_block_only(s, false); - if (s.strm.avail_out === 0) { - return BS_NEED_MORE; - } - /***/ - } - return BS_BLOCK_DONE; -}; - -/* =========================================================================== - * Same as above, but achieves better compression. We use a lazy - * evaluation for matches: a match is finally adopted only if there is - * no better match at the next window position. - */ -const deflate_slow = (s, flush) => { - - let hash_head; /* head of hash chain */ - let bflush; /* set if current block must be flushed */ - - let max_insert; - - /* Process the input block. */ - for (;;) { - /* Make sure that we always have enough lookahead, except - * at the end of the input file. We need MAX_MATCH bytes - * for the next match, plus MIN_MATCH bytes to insert the - * string following the next match. - */ - if (s.lookahead < MIN_LOOKAHEAD) { - fill_window(s); - if (s.lookahead < MIN_LOOKAHEAD && flush === Z_NO_FLUSH$2) { - return BS_NEED_MORE; - } - if (s.lookahead === 0) { break; } /* flush the current block */ - } - - /* Insert the string window[strstart .. strstart+2] in the - * dictionary, and set hash_head to the head of the hash chain: - */ - hash_head = 0/*NIL*/; - if (s.lookahead >= MIN_MATCH) { - /*** INSERT_STRING(s, s.strstart, hash_head); ***/ - s.ins_h = HASH(s, s.ins_h, s.window[s.strstart + MIN_MATCH - 1]); - hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h]; - s.head[s.ins_h] = s.strstart; - /***/ - } - - /* Find the longest match, discarding those <= prev_length. - */ - s.prev_length = s.match_length; - s.prev_match = s.match_start; - s.match_length = MIN_MATCH - 1; - - if (hash_head !== 0/*NIL*/ && s.prev_length < s.max_lazy_match && - s.strstart - hash_head <= (s.w_size - MIN_LOOKAHEAD)/*MAX_DIST(s)*/) { - /* To simplify the code, we prevent matches with the string - * of window index 0 (in particular we have to avoid a match - * of the string with itself at the start of the input file). - */ - s.match_length = longest_match(s, hash_head); - /* longest_match() sets match_start */ - - if (s.match_length <= 5 && - (s.strategy === Z_FILTERED || (s.match_length === MIN_MATCH && s.strstart - s.match_start > 4096/*TOO_FAR*/))) { - - /* If prev_match is also MIN_MATCH, match_start is garbage - * but we will ignore the current match anyway. - */ - s.match_length = MIN_MATCH - 1; - } - } - /* If there was a match at the previous step and the current - * match is not better, output the previous match: - */ - if (s.prev_length >= MIN_MATCH && s.match_length <= s.prev_length) { - max_insert = s.strstart + s.lookahead - MIN_MATCH; - /* Do not insert strings in hash table beyond this. */ - - //check_match(s, s.strstart-1, s.prev_match, s.prev_length); - - /***_tr_tally_dist(s, s.strstart - 1 - s.prev_match, - s.prev_length - MIN_MATCH, bflush);***/ - bflush = _tr_tally(s, s.strstart - 1 - s.prev_match, s.prev_length - MIN_MATCH); - /* Insert in hash table all strings up to the end of the match. - * strstart-1 and strstart are already inserted. If there is not - * enough lookahead, the last two strings are not inserted in - * the hash table. - */ - s.lookahead -= s.prev_length - 1; - s.prev_length -= 2; - do { - if (++s.strstart <= max_insert) { - /*** INSERT_STRING(s, s.strstart, hash_head); ***/ - s.ins_h = HASH(s, s.ins_h, s.window[s.strstart + MIN_MATCH - 1]); - hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h]; - s.head[s.ins_h] = s.strstart; - /***/ - } - } while (--s.prev_length !== 0); - s.match_available = 0; - s.match_length = MIN_MATCH - 1; - s.strstart++; - - if (bflush) { - /*** FLUSH_BLOCK(s, 0); ***/ - flush_block_only(s, false); - if (s.strm.avail_out === 0) { - return BS_NEED_MORE; - } - /***/ - } - - } else if (s.match_available) { - /* If there was no match at the previous position, output a - * single literal. If there was a match but the current match - * is longer, truncate the previous match to a single literal. - */ - //Tracevv((stderr,"%c", s->window[s->strstart-1])); - /*** _tr_tally_lit(s, s.window[s.strstart-1], bflush); ***/ - bflush = _tr_tally(s, 0, s.window[s.strstart - 1]); - - if (bflush) { - /*** FLUSH_BLOCK_ONLY(s, 0) ***/ - flush_block_only(s, false); - /***/ - } - s.strstart++; - s.lookahead--; - if (s.strm.avail_out === 0) { - return BS_NEED_MORE; - } - } else { - /* There is no previous match to compare with, wait for - * the next step to decide. - */ - s.match_available = 1; - s.strstart++; - s.lookahead--; - } - } - //Assert (flush != Z_NO_FLUSH, "no flush?"); - if (s.match_available) { - //Tracevv((stderr,"%c", s->window[s->strstart-1])); - /*** _tr_tally_lit(s, s.window[s.strstart-1], bflush); ***/ - bflush = _tr_tally(s, 0, s.window[s.strstart - 1]); - - s.match_available = 0; - } - s.insert = s.strstart < MIN_MATCH - 1 ? s.strstart : MIN_MATCH - 1; - if (flush === Z_FINISH$3) { - /*** FLUSH_BLOCK(s, 1); ***/ - flush_block_only(s, true); - if (s.strm.avail_out === 0) { - return BS_FINISH_STARTED; - } - /***/ - return BS_FINISH_DONE; - } - if (s.sym_next) { - /*** FLUSH_BLOCK(s, 0); ***/ - flush_block_only(s, false); - if (s.strm.avail_out === 0) { - return BS_NEED_MORE; - } - /***/ - } - - return BS_BLOCK_DONE; -}; - - -/* =========================================================================== - * For Z_RLE, simply look for runs of bytes, generate matches only of distance - * one. Do not maintain a hash table. (It will be regenerated if this run of - * deflate switches away from Z_RLE.) - */ -const deflate_rle = (s, flush) => { - - let bflush; /* set if current block must be flushed */ - let prev; /* byte at distance one to match */ - let scan, strend; /* scan goes up to strend for length of run */ - - const _win = s.window; - - for (;;) { - /* Make sure that we always have enough lookahead, except - * at the end of the input file. We need MAX_MATCH bytes - * for the longest run, plus one for the unrolled loop. - */ - if (s.lookahead <= MAX_MATCH) { - fill_window(s); - if (s.lookahead <= MAX_MATCH && flush === Z_NO_FLUSH$2) { - return BS_NEED_MORE; - } - if (s.lookahead === 0) { break; } /* flush the current block */ - } - - /* See how many times the previous byte repeats */ - s.match_length = 0; - if (s.lookahead >= MIN_MATCH && s.strstart > 0) { - scan = s.strstart - 1; - prev = _win[scan]; - if (prev === _win[++scan] && prev === _win[++scan] && prev === _win[++scan]) { - strend = s.strstart + MAX_MATCH; - do { - /*jshint noempty:false*/ - } while (prev === _win[++scan] && prev === _win[++scan] && - prev === _win[++scan] && prev === _win[++scan] && - prev === _win[++scan] && prev === _win[++scan] && - prev === _win[++scan] && prev === _win[++scan] && - scan < strend); - s.match_length = MAX_MATCH - (strend - scan); - if (s.match_length > s.lookahead) { - s.match_length = s.lookahead; - } - } - //Assert(scan <= s->window+(uInt)(s->window_size-1), "wild scan"); - } - - /* Emit match if have run of MIN_MATCH or longer, else emit literal */ - if (s.match_length >= MIN_MATCH) { - //check_match(s, s.strstart, s.strstart - 1, s.match_length); - - /*** _tr_tally_dist(s, 1, s.match_length - MIN_MATCH, bflush); ***/ - bflush = _tr_tally(s, 1, s.match_length - MIN_MATCH); - - s.lookahead -= s.match_length; - s.strstart += s.match_length; - s.match_length = 0; - } else { - /* No match, output a literal byte */ - //Tracevv((stderr,"%c", s->window[s->strstart])); - /*** _tr_tally_lit(s, s.window[s.strstart], bflush); ***/ - bflush = _tr_tally(s, 0, s.window[s.strstart]); - - s.lookahead--; - s.strstart++; - } - if (bflush) { - /*** FLUSH_BLOCK(s, 0); ***/ - flush_block_only(s, false); - if (s.strm.avail_out === 0) { - return BS_NEED_MORE; - } - /***/ - } - } - s.insert = 0; - if (flush === Z_FINISH$3) { - /*** FLUSH_BLOCK(s, 1); ***/ - flush_block_only(s, true); - if (s.strm.avail_out === 0) { - return BS_FINISH_STARTED; - } - /***/ - return BS_FINISH_DONE; - } - if (s.sym_next) { - /*** FLUSH_BLOCK(s, 0); ***/ - flush_block_only(s, false); - if (s.strm.avail_out === 0) { - return BS_NEED_MORE; - } - /***/ - } - return BS_BLOCK_DONE; -}; - -/* =========================================================================== - * For Z_HUFFMAN_ONLY, do not look for matches. Do not maintain a hash table. - * (It will be regenerated if this run of deflate switches away from Huffman.) - */ -const deflate_huff = (s, flush) => { - - let bflush; /* set if current block must be flushed */ - - for (;;) { - /* Make sure that we have a literal to write. */ - if (s.lookahead === 0) { - fill_window(s); - if (s.lookahead === 0) { - if (flush === Z_NO_FLUSH$2) { - return BS_NEED_MORE; - } - break; /* flush the current block */ - } - } - - /* Output a literal byte */ - s.match_length = 0; - //Tracevv((stderr,"%c", s->window[s->strstart])); - /*** _tr_tally_lit(s, s.window[s.strstart], bflush); ***/ - bflush = _tr_tally(s, 0, s.window[s.strstart]); - s.lookahead--; - s.strstart++; - if (bflush) { - /*** FLUSH_BLOCK(s, 0); ***/ - flush_block_only(s, false); - if (s.strm.avail_out === 0) { - return BS_NEED_MORE; - } - /***/ - } - } - s.insert = 0; - if (flush === Z_FINISH$3) { - /*** FLUSH_BLOCK(s, 1); ***/ - flush_block_only(s, true); - if (s.strm.avail_out === 0) { - return BS_FINISH_STARTED; - } - /***/ - return BS_FINISH_DONE; - } - if (s.sym_next) { - /*** FLUSH_BLOCK(s, 0); ***/ - flush_block_only(s, false); - if (s.strm.avail_out === 0) { - return BS_NEED_MORE; - } - /***/ - } - return BS_BLOCK_DONE; -}; - -/* Values for max_lazy_match, good_match and max_chain_length, depending on - * the desired pack level (0..9). The values given below have been tuned to - * exclude worst case performance for pathological files. Better values may be - * found for specific files. - */ -function Config(good_length, max_lazy, nice_length, max_chain, func) { - - this.good_length = good_length; - this.max_lazy = max_lazy; - this.nice_length = nice_length; - this.max_chain = max_chain; - this.func = func; -} - -const configuration_table = [ - /* good lazy nice chain */ - new Config(0, 0, 0, 0, deflate_stored), /* 0 store only */ - new Config(4, 4, 8, 4, deflate_fast), /* 1 max speed, no lazy matches */ - new Config(4, 5, 16, 8, deflate_fast), /* 2 */ - new Config(4, 6, 32, 32, deflate_fast), /* 3 */ - - new Config(4, 4, 16, 16, deflate_slow), /* 4 lazy matches */ - new Config(8, 16, 32, 32, deflate_slow), /* 5 */ - new Config(8, 16, 128, 128, deflate_slow), /* 6 */ - new Config(8, 32, 128, 256, deflate_slow), /* 7 */ - new Config(32, 128, 258, 1024, deflate_slow), /* 8 */ - new Config(32, 258, 258, 4096, deflate_slow) /* 9 max compression */ -]; - - -/* =========================================================================== - * Initialize the "longest match" routines for a new zlib stream - */ -const lm_init = (s) => { - - s.window_size = 2 * s.w_size; - - /*** CLEAR_HASH(s); ***/ - zero(s.head); // Fill with NIL (= 0); - - /* Set the default configuration parameters: - */ - s.max_lazy_match = configuration_table[s.level].max_lazy; - s.good_match = configuration_table[s.level].good_length; - s.nice_match = configuration_table[s.level].nice_length; - s.max_chain_length = configuration_table[s.level].max_chain; - - s.strstart = 0; - s.block_start = 0; - s.lookahead = 0; - s.insert = 0; - s.match_length = s.prev_length = MIN_MATCH - 1; - s.match_available = 0; - s.ins_h = 0; -}; - - -function DeflateState() { - this.strm = null; /* pointer back to this zlib stream */ - this.status = 0; /* as the name implies */ - this.pending_buf = null; /* output still pending */ - this.pending_buf_size = 0; /* size of pending_buf */ - this.pending_out = 0; /* next pending byte to output to the stream */ - this.pending = 0; /* nb of bytes in the pending buffer */ - this.wrap = 0; /* bit 0 true for zlib, bit 1 true for gzip */ - this.gzhead = null; /* gzip header information to write */ - this.gzindex = 0; /* where in extra, name, or comment */ - this.method = Z_DEFLATED$2; /* can only be DEFLATED */ - this.last_flush = -1; /* value of flush param for previous deflate call */ - - this.w_size = 0; /* LZ77 window size (32K by default) */ - this.w_bits = 0; /* log2(w_size) (8..16) */ - this.w_mask = 0; /* w_size - 1 */ - - this.window = null; - /* Sliding window. Input bytes are read into the second half of the window, - * and move to the first half later to keep a dictionary of at least wSize - * bytes. With this organization, matches are limited to a distance of - * wSize-MAX_MATCH bytes, but this ensures that IO is always - * performed with a length multiple of the block size. - */ - - this.window_size = 0; - /* Actual size of window: 2*wSize, except when the user input buffer - * is directly used as sliding window. - */ - - this.prev = null; - /* Link to older string with same hash index. To limit the size of this - * array to 64K, this link is maintained only for the last 32K strings. - * An index in this array is thus a window index modulo 32K. - */ - - this.head = null; /* Heads of the hash chains or NIL. */ - - this.ins_h = 0; /* hash index of string to be inserted */ - this.hash_size = 0; /* number of elements in hash table */ - this.hash_bits = 0; /* log2(hash_size) */ - this.hash_mask = 0; /* hash_size-1 */ - - this.hash_shift = 0; - /* Number of bits by which ins_h must be shifted at each input - * step. It must be such that after MIN_MATCH steps, the oldest - * byte no longer takes part in the hash key, that is: - * hash_shift * MIN_MATCH >= hash_bits - */ - - this.block_start = 0; - /* Window position at the beginning of the current output block. Gets - * negative when the window is moved backwards. - */ - - this.match_length = 0; /* length of best match */ - this.prev_match = 0; /* previous match */ - this.match_available = 0; /* set if previous match exists */ - this.strstart = 0; /* start of string to insert */ - this.match_start = 0; /* start of matching string */ - this.lookahead = 0; /* number of valid bytes ahead in window */ - - this.prev_length = 0; - /* Length of the best match at previous step. Matches not greater than this - * are discarded. This is used in the lazy match evaluation. - */ - - this.max_chain_length = 0; - /* To speed up deflation, hash chains are never searched beyond this - * length. A higher limit improves compression ratio but degrades the - * speed. - */ - - this.max_lazy_match = 0; - /* Attempt to find a better match only when the current match is strictly - * smaller than this value. This mechanism is used only for compression - * levels >= 4. - */ - // That's alias to max_lazy_match, don't use directly - //this.max_insert_length = 0; - /* Insert new strings in the hash table only if the match length is not - * greater than this length. This saves time but degrades compression. - * max_insert_length is used only for compression levels <= 3. - */ - - this.level = 0; /* compression level (1..9) */ - this.strategy = 0; /* favor or force Huffman coding*/ - - this.good_match = 0; - /* Use a faster search when the previous match is longer than this */ - - this.nice_match = 0; /* Stop searching when current match exceeds this */ - - /* used by trees.c: */ - - /* Didn't use ct_data typedef below to suppress compiler warning */ - - // struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */ - // struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */ - // struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */ - - // Use flat array of DOUBLE size, with interleaved fata, - // because JS does not support effective - this.dyn_ltree = new Uint16Array(HEAP_SIZE * 2); - this.dyn_dtree = new Uint16Array((2 * D_CODES + 1) * 2); - this.bl_tree = new Uint16Array((2 * BL_CODES + 1) * 2); - zero(this.dyn_ltree); - zero(this.dyn_dtree); - zero(this.bl_tree); - - this.l_desc = null; /* desc. for literal tree */ - this.d_desc = null; /* desc. for distance tree */ - this.bl_desc = null; /* desc. for bit length tree */ - - //ush bl_count[MAX_BITS+1]; - this.bl_count = new Uint16Array(MAX_BITS + 1); - /* number of codes at each bit length for an optimal tree */ - - //int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */ - this.heap = new Uint16Array(2 * L_CODES + 1); /* heap used to build the Huffman trees */ - zero(this.heap); - - this.heap_len = 0; /* number of elements in the heap */ - this.heap_max = 0; /* element of largest frequency */ - /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. - * The same heap array is used to build all trees. - */ - - this.depth = new Uint16Array(2 * L_CODES + 1); //uch depth[2*L_CODES+1]; - zero(this.depth); - /* Depth of each subtree used as tie breaker for trees of equal frequency - */ - - this.sym_buf = 0; /* buffer for distances and literals/lengths */ - - this.lit_bufsize = 0; - /* Size of match buffer for literals/lengths. There are 4 reasons for - * limiting lit_bufsize to 64K: - * - frequencies can be kept in 16 bit counters - * - if compression is not successful for the first block, all input - * data is still in the window so we can still emit a stored block even - * when input comes from standard input. (This can also be done for - * all blocks if lit_bufsize is not greater than 32K.) - * - if compression is not successful for a file smaller than 64K, we can - * even emit a stored file instead of a stored block (saving 5 bytes). - * This is applicable only for zip (not gzip or zlib). - * - creating new Huffman trees less frequently may not provide fast - * adaptation to changes in the input data statistics. (Take for - * example a binary file with poorly compressible code followed by - * a highly compressible string table.) Smaller buffer sizes give - * fast adaptation but have of course the overhead of transmitting - * trees more frequently. - * - I can't count above 4 - */ - - this.sym_next = 0; /* running index in sym_buf */ - this.sym_end = 0; /* symbol table full when sym_next reaches this */ - - this.opt_len = 0; /* bit length of current block with optimal trees */ - this.static_len = 0; /* bit length of current block with static trees */ - this.matches = 0; /* number of string matches in current block */ - this.insert = 0; /* bytes at end of window left to insert */ - - - this.bi_buf = 0; - /* Output buffer. bits are inserted starting at the bottom (least - * significant bits). - */ - this.bi_valid = 0; - /* Number of valid bits in bi_buf. All bits above the last valid bit - * are always zero. - */ - - // Used for window memory init. We safely ignore it for JS. That makes - // sense only for pointers and memory check tools. - //this.high_water = 0; - /* High water mark offset in window for initialized bytes -- bytes above - * this are set to zero in order to avoid memory check warnings when - * longest match routines access bytes past the input. This is then - * updated to the new high water mark. - */ -} - - -/* ========================================================================= - * Check for a valid deflate stream state. Return 0 if ok, 1 if not. - */ -const deflateStateCheck = (strm) => { - - if (!strm) { - return 1; - } - const s = strm.state; - if (!s || s.strm !== strm || (s.status !== INIT_STATE && -//#ifdef GZIP - s.status !== GZIP_STATE && -//#endif - s.status !== EXTRA_STATE && - s.status !== NAME_STATE && - s.status !== COMMENT_STATE && - s.status !== HCRC_STATE && - s.status !== BUSY_STATE && - s.status !== FINISH_STATE)) { - return 1; - } - return 0; -}; - - -const deflateResetKeep = (strm) => { - - if (deflateStateCheck(strm)) { - return err(strm, Z_STREAM_ERROR$2); - } - - strm.total_in = strm.total_out = 0; - strm.data_type = Z_UNKNOWN; - - const s = strm.state; - s.pending = 0; - s.pending_out = 0; - - if (s.wrap < 0) { - s.wrap = -s.wrap; - /* was made negative by deflate(..., Z_FINISH); */ - } - s.status = -//#ifdef GZIP - s.wrap === 2 ? GZIP_STATE : -//#endif - s.wrap ? INIT_STATE : BUSY_STATE; - strm.adler = (s.wrap === 2) ? - 0 // crc32(0, Z_NULL, 0) - : - 1; // adler32(0, Z_NULL, 0) - s.last_flush = -2; - _tr_init(s); - return Z_OK$3; -}; - - -const deflateReset = (strm) => { - - const ret = deflateResetKeep(strm); - if (ret === Z_OK$3) { - lm_init(strm.state); - } - return ret; -}; - - -const deflateSetHeader = (strm, head) => { - - if (deflateStateCheck(strm) || strm.state.wrap !== 2) { - return Z_STREAM_ERROR$2; - } - strm.state.gzhead = head; - return Z_OK$3; -}; - - -const deflateInit2 = (strm, level, method, windowBits, memLevel, strategy) => { - - if (!strm) { // === Z_NULL - return Z_STREAM_ERROR$2; - } - let wrap = 1; - - if (level === Z_DEFAULT_COMPRESSION$1) { - level = 6; - } - - if (windowBits < 0) { /* suppress zlib wrapper */ - wrap = 0; - windowBits = -windowBits; - } - - else if (windowBits > 15) { - wrap = 2; /* write gzip wrapper instead */ - windowBits -= 16; - } - - - if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method !== Z_DEFLATED$2 || - windowBits < 8 || windowBits > 15 || level < 0 || level > 9 || - strategy < 0 || strategy > Z_FIXED || (windowBits === 8 && wrap !== 1)) { - return err(strm, Z_STREAM_ERROR$2); - } - - - if (windowBits === 8) { - windowBits = 9; - } - /* until 256-byte window bug fixed */ - - const s = new DeflateState(); - - strm.state = s; - s.strm = strm; - s.status = INIT_STATE; /* to pass state test in deflateReset() */ - - s.wrap = wrap; - s.gzhead = null; - s.w_bits = windowBits; - s.w_size = 1 << s.w_bits; - s.w_mask = s.w_size - 1; - - s.hash_bits = memLevel + 7; - s.hash_size = 1 << s.hash_bits; - s.hash_mask = s.hash_size - 1; - s.hash_shift = ~~((s.hash_bits + MIN_MATCH - 1) / MIN_MATCH); - - s.window = new Uint8Array(s.w_size * 2); - s.head = new Uint16Array(s.hash_size); - s.prev = new Uint16Array(s.w_size); - - // Don't need mem init magic for JS. - //s.high_water = 0; /* nothing written to s->window yet */ - - s.lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */ - - /* We overlay pending_buf and sym_buf. This works since the average size - * for length/distance pairs over any compressed block is assured to be 31 - * bits or less. - * - * Analysis: The longest fixed codes are a length code of 8 bits plus 5 - * extra bits, for lengths 131 to 257. The longest fixed distance codes are - * 5 bits plus 13 extra bits, for distances 16385 to 32768. The longest - * possible fixed-codes length/distance pair is then 31 bits total. - * - * sym_buf starts one-fourth of the way into pending_buf. So there are - * three bytes in sym_buf for every four bytes in pending_buf. Each symbol - * in sym_buf is three bytes -- two for the distance and one for the - * literal/length. As each symbol is consumed, the pointer to the next - * sym_buf value to read moves forward three bytes. From that symbol, up to - * 31 bits are written to pending_buf. The closest the written pending_buf - * bits gets to the next sym_buf symbol to read is just before the last - * code is written. At that time, 31*(n-2) bits have been written, just - * after 24*(n-2) bits have been consumed from sym_buf. sym_buf starts at - * 8*n bits into pending_buf. (Note that the symbol buffer fills when n-1 - * symbols are written.) The closest the writing gets to what is unread is - * then n+14 bits. Here n is lit_bufsize, which is 16384 by default, and - * can range from 128 to 32768. - * - * Therefore, at a minimum, there are 142 bits of space between what is - * written and what is read in the overlain buffers, so the symbols cannot - * be overwritten by the compressed data. That space is actually 139 bits, - * due to the three-bit fixed-code block header. - * - * That covers the case where either Z_FIXED is specified, forcing fixed - * codes, or when the use of fixed codes is chosen, because that choice - * results in a smaller compressed block than dynamic codes. That latter - * condition then assures that the above analysis also covers all dynamic - * blocks. A dynamic-code block will only be chosen to be emitted if it has - * fewer bits than a fixed-code block would for the same set of symbols. - * Therefore its average symbol length is assured to be less than 31. So - * the compressed data for a dynamic block also cannot overwrite the - * symbols from which it is being constructed. - */ - - s.pending_buf_size = s.lit_bufsize * 4; - s.pending_buf = new Uint8Array(s.pending_buf_size); - - // It is offset from `s.pending_buf` (size is `s.lit_bufsize * 2`) - //s->sym_buf = s->pending_buf + s->lit_bufsize; - s.sym_buf = s.lit_bufsize; - - //s->sym_end = (s->lit_bufsize - 1) * 3; - s.sym_end = (s.lit_bufsize - 1) * 3; - /* We avoid equality with lit_bufsize*3 because of wraparound at 64K - * on 16 bit machines and because stored blocks are restricted to - * 64K-1 bytes. - */ - - s.level = level; - s.strategy = strategy; - s.method = method; - - return deflateReset(strm); -}; - -const deflateInit = (strm, level) => { - - return deflateInit2(strm, level, Z_DEFLATED$2, MAX_WBITS$1, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY$1); -}; - - -/* ========================================================================= */ -const deflate$2 = (strm, flush) => { - - if (deflateStateCheck(strm) || flush > Z_BLOCK$1 || flush < 0) { - return strm ? err(strm, Z_STREAM_ERROR$2) : Z_STREAM_ERROR$2; - } - - const s = strm.state; - - if (!strm.output || - (strm.avail_in !== 0 && !strm.input) || - (s.status === FINISH_STATE && flush !== Z_FINISH$3)) { - return err(strm, (strm.avail_out === 0) ? Z_BUF_ERROR$1 : Z_STREAM_ERROR$2); - } - - const old_flush = s.last_flush; - s.last_flush = flush; - - /* Flush as much pending output as possible */ - if (s.pending !== 0) { - flush_pending(strm); - if (strm.avail_out === 0) { - /* Since avail_out is 0, deflate will be called again with - * more output space, but possibly with both pending and - * avail_in equal to zero. There won't be anything to do, - * but this is not an error situation so make sure we - * return OK instead of BUF_ERROR at next call of deflate: - */ - s.last_flush = -1; - return Z_OK$3; - } - - /* Make sure there is something to do and avoid duplicate consecutive - * flushes. For repeated and useless calls with Z_FINISH, we keep - * returning Z_STREAM_END instead of Z_BUF_ERROR. - */ - } else if (strm.avail_in === 0 && rank(flush) <= rank(old_flush) && - flush !== Z_FINISH$3) { - return err(strm, Z_BUF_ERROR$1); - } - - /* User must not provide more input after the first FINISH: */ - if (s.status === FINISH_STATE && strm.avail_in !== 0) { - return err(strm, Z_BUF_ERROR$1); - } - - /* Write the header */ - if (s.status === INIT_STATE && s.wrap === 0) { - s.status = BUSY_STATE; - } - if (s.status === INIT_STATE) { - /* zlib header */ - let header = (Z_DEFLATED$2 + ((s.w_bits - 8) << 4)) << 8; - let level_flags = -1; - - if (s.strategy >= Z_HUFFMAN_ONLY || s.level < 2) { - level_flags = 0; - } else if (s.level < 6) { - level_flags = 1; - } else if (s.level === 6) { - level_flags = 2; - } else { - level_flags = 3; - } - header |= (level_flags << 6); - if (s.strstart !== 0) { header |= PRESET_DICT; } - header += 31 - (header % 31); - - putShortMSB(s, header); - - /* Save the adler32 of the preset dictionary: */ - if (s.strstart !== 0) { - putShortMSB(s, strm.adler >>> 16); - putShortMSB(s, strm.adler & 0xffff); - } - strm.adler = 1; // adler32(0L, Z_NULL, 0); - s.status = BUSY_STATE; - - /* Compression must start with an empty pending buffer */ - flush_pending(strm); - if (s.pending !== 0) { - s.last_flush = -1; - return Z_OK$3; - } - } -//#ifdef GZIP - if (s.status === GZIP_STATE) { - /* gzip header */ - strm.adler = 0; //crc32(0L, Z_NULL, 0); - put_byte(s, 31); - put_byte(s, 139); - put_byte(s, 8); - if (!s.gzhead) { // s->gzhead == Z_NULL - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, s.level === 9 ? 2 : - (s.strategy >= Z_HUFFMAN_ONLY || s.level < 2 ? - 4 : 0)); - put_byte(s, OS_CODE); - s.status = BUSY_STATE; - - /* Compression must start with an empty pending buffer */ - flush_pending(strm); - if (s.pending !== 0) { - s.last_flush = -1; - return Z_OK$3; - } - } - else { - put_byte(s, (s.gzhead.text ? 1 : 0) + - (s.gzhead.hcrc ? 2 : 0) + - (!s.gzhead.extra ? 0 : 4) + - (!s.gzhead.name ? 0 : 8) + - (!s.gzhead.comment ? 0 : 16) - ); - put_byte(s, s.gzhead.time & 0xff); - put_byte(s, (s.gzhead.time >> 8) & 0xff); - put_byte(s, (s.gzhead.time >> 16) & 0xff); - put_byte(s, (s.gzhead.time >> 24) & 0xff); - put_byte(s, s.level === 9 ? 2 : - (s.strategy >= Z_HUFFMAN_ONLY || s.level < 2 ? - 4 : 0)); - put_byte(s, s.gzhead.os & 0xff); - if (s.gzhead.extra && s.gzhead.extra.length) { - put_byte(s, s.gzhead.extra.length & 0xff); - put_byte(s, (s.gzhead.extra.length >> 8) & 0xff); - } - if (s.gzhead.hcrc) { - strm.adler = crc32_1$1(strm.adler, s.pending_buf, s.pending, 0); - } - s.gzindex = 0; - s.status = EXTRA_STATE; - } - } - if (s.status === EXTRA_STATE) { - if (s.gzhead.extra/* != Z_NULL*/) { - let beg = s.pending; /* start of bytes to update crc */ - let left = (s.gzhead.extra.length & 0xffff) - s.gzindex; - while (s.pending + left > s.pending_buf_size) { - let copy = s.pending_buf_size - s.pending; - // zmemcpy(s.pending_buf + s.pending, - // s.gzhead.extra + s.gzindex, copy); - s.pending_buf.set(s.gzhead.extra.subarray(s.gzindex, s.gzindex + copy), s.pending); - s.pending = s.pending_buf_size; - //--- HCRC_UPDATE(beg) ---// - if (s.gzhead.hcrc && s.pending > beg) { - strm.adler = crc32_1$1(strm.adler, s.pending_buf, s.pending - beg, beg); - } - //---// - s.gzindex += copy; - flush_pending(strm); - if (s.pending !== 0) { - s.last_flush = -1; - return Z_OK$3; - } - beg = 0; - left -= copy; - } - // JS specific: s.gzhead.extra may be TypedArray or Array for backward compatibility - // TypedArray.slice and TypedArray.from don't exist in IE10-IE11 - let gzhead_extra = new Uint8Array(s.gzhead.extra); - // zmemcpy(s->pending_buf + s->pending, - // s->gzhead->extra + s->gzindex, left); - s.pending_buf.set(gzhead_extra.subarray(s.gzindex, s.gzindex + left), s.pending); - s.pending += left; - //--- HCRC_UPDATE(beg) ---// - if (s.gzhead.hcrc && s.pending > beg) { - strm.adler = crc32_1$1(strm.adler, s.pending_buf, s.pending - beg, beg); - } - //---// - s.gzindex = 0; - } - s.status = NAME_STATE; - } - if (s.status === NAME_STATE) { - if (s.gzhead.name/* != Z_NULL*/) { - let beg = s.pending; /* start of bytes to update crc */ - let val; - do { - if (s.pending === s.pending_buf_size) { - //--- HCRC_UPDATE(beg) ---// - if (s.gzhead.hcrc && s.pending > beg) { - strm.adler = crc32_1$1(strm.adler, s.pending_buf, s.pending - beg, beg); - } - //---// - flush_pending(strm); - if (s.pending !== 0) { - s.last_flush = -1; - return Z_OK$3; - } - beg = 0; - } - // JS specific: little magic to add zero terminator to end of string - if (s.gzindex < s.gzhead.name.length) { - val = s.gzhead.name.charCodeAt(s.gzindex++) & 0xff; - } else { - val = 0; - } - put_byte(s, val); - } while (val !== 0); - //--- HCRC_UPDATE(beg) ---// - if (s.gzhead.hcrc && s.pending > beg) { - strm.adler = crc32_1$1(strm.adler, s.pending_buf, s.pending - beg, beg); - } - //---// - s.gzindex = 0; - } - s.status = COMMENT_STATE; - } - if (s.status === COMMENT_STATE) { - if (s.gzhead.comment/* != Z_NULL*/) { - let beg = s.pending; /* start of bytes to update crc */ - let val; - do { - if (s.pending === s.pending_buf_size) { - //--- HCRC_UPDATE(beg) ---// - if (s.gzhead.hcrc && s.pending > beg) { - strm.adler = crc32_1$1(strm.adler, s.pending_buf, s.pending - beg, beg); - } - //---// - flush_pending(strm); - if (s.pending !== 0) { - s.last_flush = -1; - return Z_OK$3; - } - beg = 0; - } - // JS specific: little magic to add zero terminator to end of string - if (s.gzindex < s.gzhead.comment.length) { - val = s.gzhead.comment.charCodeAt(s.gzindex++) & 0xff; - } else { - val = 0; - } - put_byte(s, val); - } while (val !== 0); - //--- HCRC_UPDATE(beg) ---// - if (s.gzhead.hcrc && s.pending > beg) { - strm.adler = crc32_1$1(strm.adler, s.pending_buf, s.pending - beg, beg); - } - //---// - } - s.status = HCRC_STATE; - } - if (s.status === HCRC_STATE) { - if (s.gzhead.hcrc) { - if (s.pending + 2 > s.pending_buf_size) { - flush_pending(strm); - if (s.pending !== 0) { - s.last_flush = -1; - return Z_OK$3; - } - } - put_byte(s, strm.adler & 0xff); - put_byte(s, (strm.adler >> 8) & 0xff); - strm.adler = 0; //crc32(0L, Z_NULL, 0); - } - s.status = BUSY_STATE; - - /* Compression must start with an empty pending buffer */ - flush_pending(strm); - if (s.pending !== 0) { - s.last_flush = -1; - return Z_OK$3; - } - } -//#endif - - /* Start a new block or continue the current one. - */ - if (strm.avail_in !== 0 || s.lookahead !== 0 || - (flush !== Z_NO_FLUSH$2 && s.status !== FINISH_STATE)) { - let bstate = s.level === 0 ? deflate_stored(s, flush) : - s.strategy === Z_HUFFMAN_ONLY ? deflate_huff(s, flush) : - s.strategy === Z_RLE ? deflate_rle(s, flush) : - configuration_table[s.level].func(s, flush); - - if (bstate === BS_FINISH_STARTED || bstate === BS_FINISH_DONE) { - s.status = FINISH_STATE; - } - if (bstate === BS_NEED_MORE || bstate === BS_FINISH_STARTED) { - if (strm.avail_out === 0) { - s.last_flush = -1; - /* avoid BUF_ERROR next call, see above */ - } - return Z_OK$3; - /* If flush != Z_NO_FLUSH && avail_out == 0, the next call - * of deflate should use the same flush parameter to make sure - * that the flush is complete. So we don't have to output an - * empty block here, this will be done at next call. This also - * ensures that for a very small output buffer, we emit at most - * one empty block. - */ - } - if (bstate === BS_BLOCK_DONE) { - if (flush === Z_PARTIAL_FLUSH) { - _tr_align(s); - } - else if (flush !== Z_BLOCK$1) { /* FULL_FLUSH or SYNC_FLUSH */ - - _tr_stored_block(s, 0, 0, false); - /* For a full flush, this empty block will be recognized - * as a special marker by inflate_sync(). - */ - if (flush === Z_FULL_FLUSH$1) { - /*** CLEAR_HASH(s); ***/ /* forget history */ - zero(s.head); // Fill with NIL (= 0); - - if (s.lookahead === 0) { - s.strstart = 0; - s.block_start = 0; - s.insert = 0; - } - } - } - flush_pending(strm); - if (strm.avail_out === 0) { - s.last_flush = -1; /* avoid BUF_ERROR at next call, see above */ - return Z_OK$3; - } - } - } - - if (flush !== Z_FINISH$3) { return Z_OK$3; } - if (s.wrap <= 0) { return Z_STREAM_END$3; } - - /* Write the trailer */ - if (s.wrap === 2) { - put_byte(s, strm.adler & 0xff); - put_byte(s, (strm.adler >> 8) & 0xff); - put_byte(s, (strm.adler >> 16) & 0xff); - put_byte(s, (strm.adler >> 24) & 0xff); - put_byte(s, strm.total_in & 0xff); - put_byte(s, (strm.total_in >> 8) & 0xff); - put_byte(s, (strm.total_in >> 16) & 0xff); - put_byte(s, (strm.total_in >> 24) & 0xff); - } - else - { - putShortMSB(s, strm.adler >>> 16); - putShortMSB(s, strm.adler & 0xffff); - } - - flush_pending(strm); - /* If avail_out is zero, the application will call deflate again - * to flush the rest. - */ - if (s.wrap > 0) { s.wrap = -s.wrap; } - /* write the trailer only once! */ - return s.pending !== 0 ? Z_OK$3 : Z_STREAM_END$3; -}; - - -const deflateEnd = (strm) => { - - if (deflateStateCheck(strm)) { - return Z_STREAM_ERROR$2; - } - - const status = strm.state.status; - - strm.state = null; - - return status === BUSY_STATE ? err(strm, Z_DATA_ERROR$2) : Z_OK$3; -}; - - -/* ========================================================================= - * Initializes the compression dictionary from the given byte - * sequence without producing any compressed output. - */ -const deflateSetDictionary = (strm, dictionary) => { - - let dictLength = dictionary.length; - - if (deflateStateCheck(strm)) { - return Z_STREAM_ERROR$2; - } - - const s = strm.state; - const wrap = s.wrap; - - if (wrap === 2 || (wrap === 1 && s.status !== INIT_STATE) || s.lookahead) { - return Z_STREAM_ERROR$2; - } - - /* when using zlib wrappers, compute Adler-32 for provided dictionary */ - if (wrap === 1) { - /* adler32(strm->adler, dictionary, dictLength); */ - strm.adler = adler32_1$1(strm.adler, dictionary, dictLength, 0); - } - - s.wrap = 0; /* avoid computing Adler-32 in read_buf */ - - /* if dictionary would fill window, just replace the history */ - if (dictLength >= s.w_size) { - if (wrap === 0) { /* already empty otherwise */ - /*** CLEAR_HASH(s); ***/ - zero(s.head); // Fill with NIL (= 0); - s.strstart = 0; - s.block_start = 0; - s.insert = 0; - } - /* use the tail */ - // dictionary = dictionary.slice(dictLength - s.w_size); - let tmpDict = new Uint8Array(s.w_size); - tmpDict.set(dictionary.subarray(dictLength - s.w_size, dictLength), 0); - dictionary = tmpDict; - dictLength = s.w_size; - } - /* insert dictionary into window and hash */ - const avail = strm.avail_in; - const next = strm.next_in; - const input = strm.input; - strm.avail_in = dictLength; - strm.next_in = 0; - strm.input = dictionary; - fill_window(s); - while (s.lookahead >= MIN_MATCH) { - let str = s.strstart; - let n = s.lookahead - (MIN_MATCH - 1); - do { - /* UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); */ - s.ins_h = HASH(s, s.ins_h, s.window[str + MIN_MATCH - 1]); - - s.prev[str & s.w_mask] = s.head[s.ins_h]; - - s.head[s.ins_h] = str; - str++; - } while (--n); - s.strstart = str; - s.lookahead = MIN_MATCH - 1; - fill_window(s); - } - s.strstart += s.lookahead; - s.block_start = s.strstart; - s.insert = s.lookahead; - s.lookahead = 0; - s.match_length = s.prev_length = MIN_MATCH - 1; - s.match_available = 0; - strm.next_in = next; - strm.input = input; - strm.avail_in = avail; - s.wrap = wrap; - return Z_OK$3; -}; - - -var deflateInit_1 = deflateInit; -var deflateInit2_1 = deflateInit2; -var deflateReset_1 = deflateReset; -var deflateResetKeep_1 = deflateResetKeep; -var deflateSetHeader_1 = deflateSetHeader; -var deflate_2$1 = deflate$2; -var deflateEnd_1 = deflateEnd; -var deflateSetDictionary_1 = deflateSetDictionary; -var deflateInfo = 'pako deflate (from Nodeca project)'; - -/* Not implemented -module.exports.deflateBound = deflateBound; -module.exports.deflateCopy = deflateCopy; -module.exports.deflateGetDictionary = deflateGetDictionary; -module.exports.deflateParams = deflateParams; -module.exports.deflatePending = deflatePending; -module.exports.deflatePrime = deflatePrime; -module.exports.deflateTune = deflateTune; -*/ - -var deflate_1$2 = { - deflateInit: deflateInit_1, - deflateInit2: deflateInit2_1, - deflateReset: deflateReset_1, - deflateResetKeep: deflateResetKeep_1, - deflateSetHeader: deflateSetHeader_1, - deflate: deflate_2$1, - deflateEnd: deflateEnd_1, - deflateSetDictionary: deflateSetDictionary_1, - deflateInfo: deflateInfo -}; - -const _has$1 = (obj, key) => { - return Object.prototype.hasOwnProperty.call(obj, key); -}; - -var assign$1 = function (obj /*from1, from2, from3, ...*/) { - const sources = Array.prototype.slice.call(arguments, 1); - while (sources.length) { - const source = sources.shift(); - if (!source) { continue; } - - if (typeof source !== 'object') { - throw new TypeError(source + 'must be non-object'); - } - - for (const p in source) { - if (_has$1(source, p)) { - obj[p] = source[p]; - } - } - } - - return obj; -}; - - -// Join array of chunks to single array. -var flattenChunks$1 = (chunks) => { - // calculate data length - let len = 0; - - for (let i = 0, l = chunks.length; i < l; i++) { - len += chunks[i].length; - } - - // join chunks - const result = new Uint8Array(len); - - for (let i = 0, pos = 0, l = chunks.length; i < l; i++) { - let chunk = chunks[i]; - result.set(chunk, pos); - pos += chunk.length; - } - - return result; -}; - -var common$1 = { - assign: assign$1, - flattenChunks: flattenChunks$1 -}; - -// String encode/decode helpers - - -// Quick check if we can use fast array to bin string conversion -// -// - apply(Array) can fail on Android 2.2 -// - apply(Uint8Array) can fail on iOS 5.1 Safari -// -let STR_APPLY_UIA_OK$1 = true; - -try { String.fromCharCode.apply(null, new Uint8Array(1)); } catch (__) { STR_APPLY_UIA_OK$1 = false; } - - -// Table with utf8 lengths (calculated by first byte of sequence) -// Note, that 5 & 6-byte values and some 4-byte values can not be represented in JS, -// because max possible codepoint is 0x10ffff -const _utf8len$1 = new Uint8Array(256); -for (let q = 0; q < 256; q++) { - _utf8len$1[q] = (q >= 252 ? 6 : q >= 248 ? 5 : q >= 240 ? 4 : q >= 224 ? 3 : q >= 192 ? 2 : 1); -} -_utf8len$1[254] = _utf8len$1[254] = 1; // Invalid sequence start - - -// convert string to array (typed, when possible) -var string2buf$1 = (str) => { - if (typeof TextEncoder === 'function' && TextEncoder.prototype.encode) { - return new TextEncoder().encode(str); - } - - let buf, c, c2, m_pos, i, str_len = str.length, buf_len = 0; - - // count binary size - for (m_pos = 0; m_pos < str_len; m_pos++) { - c = str.charCodeAt(m_pos); - if ((c & 0xfc00) === 0xd800 && (m_pos + 1 < str_len)) { - c2 = str.charCodeAt(m_pos + 1); - if ((c2 & 0xfc00) === 0xdc00) { - c = 0x10000 + ((c - 0xd800) << 10) + (c2 - 0xdc00); - m_pos++; - } - } - buf_len += c < 0x80 ? 1 : c < 0x800 ? 2 : c < 0x10000 ? 3 : 4; - } - - // allocate buffer - buf = new Uint8Array(buf_len); - - // convert - for (i = 0, m_pos = 0; i < buf_len; m_pos++) { - c = str.charCodeAt(m_pos); - if ((c & 0xfc00) === 0xd800 && (m_pos + 1 < str_len)) { - c2 = str.charCodeAt(m_pos + 1); - if ((c2 & 0xfc00) === 0xdc00) { - c = 0x10000 + ((c - 0xd800) << 10) + (c2 - 0xdc00); - m_pos++; - } - } - if (c < 0x80) { - /* one byte */ - buf[i++] = c; - } else if (c < 0x800) { - /* two bytes */ - buf[i++] = 0xC0 | (c >>> 6); - buf[i++] = 0x80 | (c & 0x3f); - } else if (c < 0x10000) { - /* three bytes */ - buf[i++] = 0xE0 | (c >>> 12); - buf[i++] = 0x80 | (c >>> 6 & 0x3f); - buf[i++] = 0x80 | (c & 0x3f); - } else { - /* four bytes */ - buf[i++] = 0xf0 | (c >>> 18); - buf[i++] = 0x80 | (c >>> 12 & 0x3f); - buf[i++] = 0x80 | (c >>> 6 & 0x3f); - buf[i++] = 0x80 | (c & 0x3f); - } - } - - return buf; -}; - -// Helper -const buf2binstring$1 = (buf, len) => { - // On Chrome, the arguments in a function call that are allowed is `65534`. - // If the length of the buffer is smaller than that, we can use this optimization, - // otherwise we will take a slower path. - if (len < 65534) { - if (buf.subarray && STR_APPLY_UIA_OK$1) { - return String.fromCharCode.apply(null, buf.length === len ? buf : buf.subarray(0, len)); - } - } - - let result = ''; - for (let i = 0; i < len; i++) { - result += String.fromCharCode(buf[i]); - } - return result; -}; - - -// convert array to string -var buf2string$1 = (buf, max) => { - const len = max || buf.length; - - if (typeof TextDecoder === 'function' && TextDecoder.prototype.decode) { - return new TextDecoder().decode(buf.subarray(0, max)); - } - - let i, out; - - // Reserve max possible length (2 words per char) - // NB: by unknown reasons, Array is significantly faster for - // String.fromCharCode.apply than Uint16Array. - const utf16buf = new Array(len * 2); - - for (out = 0, i = 0; i < len;) { - let c = buf[i++]; - // quick process ascii - if (c < 0x80) { utf16buf[out++] = c; continue; } - - let c_len = _utf8len$1[c]; - // skip 5 & 6 byte codes - if (c_len > 4) { utf16buf[out++] = 0xfffd; i += c_len - 1; continue; } - - // apply mask on first byte - c &= c_len === 2 ? 0x1f : c_len === 3 ? 0x0f : 0x07; - // join the rest - while (c_len > 1 && i < len) { - c = (c << 6) | (buf[i++] & 0x3f); - c_len--; - } - - // terminated by end of string? - if (c_len > 1) { utf16buf[out++] = 0xfffd; continue; } - - if (c < 0x10000) { - utf16buf[out++] = c; - } else { - c -= 0x10000; - utf16buf[out++] = 0xd800 | ((c >> 10) & 0x3ff); - utf16buf[out++] = 0xdc00 | (c & 0x3ff); - } - } - - return buf2binstring$1(utf16buf, out); -}; - - -// Calculate max possible position in utf8 buffer, -// that will not break sequence. If that's not possible -// - (very small limits) return max size as is. -// -// buf[] - utf8 bytes array -// max - length limit (mandatory); -var utf8border$1 = (buf, max) => { - - max = max || buf.length; - if (max > buf.length) { max = buf.length; } - - // go back from last position, until start of sequence found - let pos = max - 1; - while (pos >= 0 && (buf[pos] & 0xC0) === 0x80) { pos--; } - - // Very small and broken sequence, - // return max, because we should return something anyway. - if (pos < 0) { return max; } - - // If we came to start of buffer - that means buffer is too small, - // return max too. - if (pos === 0) { return max; } - - return (pos + _utf8len$1[buf[pos]] > max) ? pos : max; -}; - -var strings$1 = { - string2buf: string2buf$1, - buf2string: buf2string$1, - utf8border: utf8border$1 -}; - -// (C) 1995-2013 Jean-loup Gailly and Mark Adler -// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// 3. This notice may not be removed or altered from any source distribution. - -function ZStream$1() { - /* next input byte */ - this.input = null; // JS specific, because we have no pointers - this.next_in = 0; - /* number of bytes available at input */ - this.avail_in = 0; - /* total number of input bytes read so far */ - this.total_in = 0; - /* next output byte should be put there */ - this.output = null; // JS specific, because we have no pointers - this.next_out = 0; - /* remaining free space at output */ - this.avail_out = 0; - /* total number of bytes output so far */ - this.total_out = 0; - /* last error message, NULL if no error */ - this.msg = ''/*Z_NULL*/; - /* not visible by applications */ - this.state = null; - /* best guess about the data type: binary or text */ - this.data_type = 2/*Z_UNKNOWN*/; - /* adler32 value of the uncompressed data */ - this.adler = 0; -} - -var zstream$1 = ZStream$1; - -const toString$1 = Object.prototype.toString; - -/* Public constants ==========================================================*/ -/* ===========================================================================*/ - -const { - Z_NO_FLUSH: Z_NO_FLUSH$1, Z_SYNC_FLUSH, Z_FULL_FLUSH, Z_FINISH: Z_FINISH$2, - Z_OK: Z_OK$2, Z_STREAM_END: Z_STREAM_END$2, - Z_DEFAULT_COMPRESSION, - Z_DEFAULT_STRATEGY, - Z_DEFLATED: Z_DEFLATED$1 -} = constants$2$1; - -/* ===========================================================================*/ - - -/** - * class Deflate - * - * Generic JS-style wrapper for zlib calls. If you don't need - * streaming behaviour - use more simple functions: [[deflate]], - * [[deflateRaw]] and [[gzip]]. - **/ - -/* internal - * Deflate.chunks -> Array - * - * Chunks of output data, if [[Deflate#onData]] not overridden. - **/ - -/** - * Deflate.result -> Uint8Array - * - * Compressed result, generated by default [[Deflate#onData]] - * and [[Deflate#onEnd]] handlers. Filled after you push last chunk - * (call [[Deflate#push]] with `Z_FINISH` / `true` param). - **/ - -/** - * Deflate.err -> Number - * - * Error code after deflate finished. 0 (Z_OK) on success. - * You will not need it in real life, because deflate errors - * are possible only on wrong options or bad `onData` / `onEnd` - * custom handlers. - **/ - -/** - * Deflate.msg -> String - * - * Error message, if [[Deflate.err]] != 0 - **/ - - -/** - * new Deflate(options) - * - options (Object): zlib deflate options. - * - * Creates new deflator instance with specified params. Throws exception - * on bad params. Supported options: - * - * - `level` - * - `windowBits` - * - `memLevel` - * - `strategy` - * - `dictionary` - * - * [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced) - * for more information on these. - * - * Additional options, for internal needs: - * - * - `chunkSize` - size of generated data chunks (16K by default) - * - `raw` (Boolean) - do raw deflate - * - `gzip` (Boolean) - create gzip wrapper - * - `header` (Object) - custom header for gzip - * - `text` (Boolean) - true if compressed data believed to be text - * - `time` (Number) - modification time, unix timestamp - * - `os` (Number) - operation system code - * - `extra` (Array) - array of bytes with extra data (max 65536) - * - `name` (String) - file name (binary string) - * - `comment` (String) - comment (binary string) - * - `hcrc` (Boolean) - true if header crc should be added - * - * ##### Example: - * - * ```javascript - * const pako = require('pako') - * , chunk1 = new Uint8Array([1,2,3,4,5,6,7,8,9]) - * , chunk2 = new Uint8Array([10,11,12,13,14,15,16,17,18,19]); - * - * const deflate = new pako.Deflate({ level: 3}); - * - * deflate.push(chunk1, false); - * deflate.push(chunk2, true); // true -> last chunk - * - * if (deflate.err) { throw new Error(deflate.err); } - * - * console.log(deflate.result); - * ``` - **/ -function Deflate$1(options) { - this.options = common$1.assign({ - level: Z_DEFAULT_COMPRESSION, - method: Z_DEFLATED$1, - chunkSize: 16384, - windowBits: 15, - memLevel: 8, - strategy: Z_DEFAULT_STRATEGY - }, options || {}); - - let opt = this.options; - - if (opt.raw && (opt.windowBits > 0)) { - opt.windowBits = -opt.windowBits; - } - - else if (opt.gzip && (opt.windowBits > 0) && (opt.windowBits < 16)) { - opt.windowBits += 16; - } - - this.err = 0; // error code, if happens (0 = Z_OK) - this.msg = ''; // error message - this.ended = false; // used to avoid multiple onEnd() calls - this.chunks = []; // chunks of compressed data - - this.strm = new zstream$1(); - this.strm.avail_out = 0; - - let status = deflate_1$2.deflateInit2( - this.strm, - opt.level, - opt.method, - opt.windowBits, - opt.memLevel, - opt.strategy - ); - - if (status !== Z_OK$2) { - throw new Error(messages$1[status]); - } - - if (opt.header) { - deflate_1$2.deflateSetHeader(this.strm, opt.header); - } - - if (opt.dictionary) { - let dict; - // Convert data if needed - if (typeof opt.dictionary === 'string') { - // If we need to compress text, change encoding to utf8. - dict = strings$1.string2buf(opt.dictionary); - } else if (toString$1.call(opt.dictionary) === '[object ArrayBuffer]') { - dict = new Uint8Array(opt.dictionary); - } else { - dict = opt.dictionary; - } - - status = deflate_1$2.deflateSetDictionary(this.strm, dict); - - if (status !== Z_OK$2) { - throw new Error(messages$1[status]); - } - - this._dict_set = true; - } -} - -/** - * Deflate#push(data[, flush_mode]) -> Boolean - * - data (Uint8Array|ArrayBuffer|String): input data. Strings will be - * converted to utf8 byte sequence. - * - flush_mode (Number|Boolean): 0..6 for corresponding Z_NO_FLUSH..Z_TREE modes. - * See constants. Skipped or `false` means Z_NO_FLUSH, `true` means Z_FINISH. - * - * Sends input data to deflate pipe, generating [[Deflate#onData]] calls with - * new compressed chunks. Returns `true` on success. The last data block must - * have `flush_mode` Z_FINISH (or `true`). That will flush internal pending - * buffers and call [[Deflate#onEnd]]. - * - * On fail call [[Deflate#onEnd]] with error code and return false. - * - * ##### Example - * - * ```javascript - * push(chunk, false); // push one of data chunks - * ... - * push(chunk, true); // push last chunk - * ``` - **/ -Deflate$1.prototype.push = function (data, flush_mode) { - const strm = this.strm; - const chunkSize = this.options.chunkSize; - let status, _flush_mode; - - if (this.ended) { return false; } - - if (flush_mode === ~~flush_mode) _flush_mode = flush_mode; - else _flush_mode = flush_mode === true ? Z_FINISH$2 : Z_NO_FLUSH$1; - - // Convert data if needed - if (typeof data === 'string') { - // If we need to compress text, change encoding to utf8. - strm.input = strings$1.string2buf(data); - } else if (toString$1.call(data) === '[object ArrayBuffer]') { - strm.input = new Uint8Array(data); - } else { - strm.input = data; - } - - strm.next_in = 0; - strm.avail_in = strm.input.length; - - for (;;) { - if (strm.avail_out === 0) { - strm.output = new Uint8Array(chunkSize); - strm.next_out = 0; - strm.avail_out = chunkSize; - } - - // Make sure avail_out > 6 to avoid repeating markers - if ((_flush_mode === Z_SYNC_FLUSH || _flush_mode === Z_FULL_FLUSH) && strm.avail_out <= 6) { - this.onData(strm.output.subarray(0, strm.next_out)); - strm.avail_out = 0; - continue; - } - - status = deflate_1$2.deflate(strm, _flush_mode); - - // Ended => flush and finish - if (status === Z_STREAM_END$2) { - if (strm.next_out > 0) { - this.onData(strm.output.subarray(0, strm.next_out)); - } - status = deflate_1$2.deflateEnd(this.strm); - this.onEnd(status); - this.ended = true; - return status === Z_OK$2; - } - - // Flush if out buffer full - if (strm.avail_out === 0) { - this.onData(strm.output); - continue; - } - - // Flush if requested and has data - if (_flush_mode > 0 && strm.next_out > 0) { - this.onData(strm.output.subarray(0, strm.next_out)); - strm.avail_out = 0; - continue; - } - - if (strm.avail_in === 0) break; - } - - return true; -}; - - -/** - * Deflate#onData(chunk) -> Void - * - chunk (Uint8Array): output data. - * - * By default, stores data blocks in `chunks[]` property and glue - * those in `onEnd`. Override this handler, if you need another behaviour. - **/ -Deflate$1.prototype.onData = function (chunk) { - this.chunks.push(chunk); -}; - - -/** - * Deflate#onEnd(status) -> Void - * - status (Number): deflate status. 0 (Z_OK) on success, - * other if not. - * - * Called once after you tell deflate that the input stream is - * complete (Z_FINISH). By default - join collected chunks, - * free memory and fill `results` / `err` properties. - **/ -Deflate$1.prototype.onEnd = function (status) { - // On success - join - if (status === Z_OK$2) { - this.result = common$1.flattenChunks(this.chunks); - } - this.chunks = []; - this.err = status; - this.msg = this.strm.msg; -}; - - -/** - * deflate(data[, options]) -> Uint8Array - * - data (Uint8Array|ArrayBuffer|String): input data to compress. - * - options (Object): zlib deflate options. - * - * Compress `data` with deflate algorithm and `options`. - * - * Supported options are: - * - * - level - * - windowBits - * - memLevel - * - strategy - * - dictionary - * - * [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced) - * for more information on these. - * - * Sugar (options): - * - * - `raw` (Boolean) - say that we work with raw stream, if you don't wish to specify - * negative windowBits implicitly. - * - * ##### Example: - * - * ```javascript - * const pako = require('pako') - * const data = new Uint8Array([1,2,3,4,5,6,7,8,9]); - * - * console.log(pako.deflate(data)); - * ``` - **/ -function deflate$1(input, options) { - const deflator = new Deflate$1(options); - - deflator.push(input, true); - - // That will never happens, if you don't cheat with options :) - if (deflator.err) { throw deflator.msg || messages$1[deflator.err]; } - - return deflator.result; -} - - -/** - * deflateRaw(data[, options]) -> Uint8Array - * - data (Uint8Array|ArrayBuffer|String): input data to compress. - * - options (Object): zlib deflate options. - * - * The same as [[deflate]], but creates raw data, without wrapper - * (header and adler32 crc). - **/ -function deflateRaw$1(input, options) { - options = options || {}; - options.raw = true; - return deflate$1(input, options); -} - - -/** - * gzip(data[, options]) -> Uint8Array - * - data (Uint8Array|ArrayBuffer|String): input data to compress. - * - options (Object): zlib deflate options. - * - * The same as [[deflate]], but create gzip wrapper instead of - * deflate one. - **/ -function gzip$1(input, options) { - options = options || {}; - options.gzip = true; - return deflate$1(input, options); -} - - -var Deflate_1$1 = Deflate$1; -var deflate_2 = deflate$1; -var deflateRaw_1$1 = deflateRaw$1; -var gzip_1$1 = gzip$1; -var constants$1 = constants$2$1; - -var deflate_1$1 = { - Deflate: Deflate_1$1, - deflate: deflate_2, - deflateRaw: deflateRaw_1$1, - gzip: gzip_1$1, - constants: constants$1 -}; - -// (C) 1995-2013 Jean-loup Gailly and Mark Adler -// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// 3. This notice may not be removed or altered from any source distribution. - -// See state defs from inflate.js -const BAD$1$1 = 16209; /* got a data error -- remain here until reset */ -const TYPE$1$1 = 16191; /* i: waiting for type bits, including last-flag bit */ - -/* - Decode literal, length, and distance codes and write out the resulting - literal and match bytes until either not enough input or output is - available, an end-of-block is encountered, or a data error is encountered. - When large enough input and output buffers are supplied to inflate(), for - example, a 16K input buffer and a 64K output buffer, more than 95% of the - inflate execution time is spent in this routine. - - Entry assumptions: - - state.mode === LEN - strm.avail_in >= 6 - strm.avail_out >= 258 - start >= strm.avail_out - state.bits < 8 - - On return, state.mode is one of: - - LEN -- ran out of enough output space or enough available input - TYPE -- reached end of block code, inflate() to interpret next block - BAD -- error in block data - - Notes: - - - The maximum input bits used by a length/distance pair is 15 bits for the - length code, 5 bits for the length extra, 15 bits for the distance code, - and 13 bits for the distance extra. This totals 48 bits, or six bytes. - Therefore if strm.avail_in >= 6, then there is enough input to avoid - checking for available input while decoding. - - - The maximum bytes that a single length/distance pair can output is 258 - bytes, which is the maximum length that can be coded. inflate_fast() - requires strm.avail_out >= 258 for each loop to avoid checking for - output space. - */ -var inffast$1 = function inflate_fast(strm, start) { - let _in; /* local strm.input */ - let last; /* have enough input while in < last */ - let _out; /* local strm.output */ - let beg; /* inflate()'s initial strm.output */ - let end; /* while out < end, enough space available */ -//#ifdef INFLATE_STRICT - let dmax; /* maximum distance from zlib header */ -//#endif - let wsize; /* window size or zero if not using window */ - let whave; /* valid bytes in the window */ - let wnext; /* window write index */ - // Use `s_window` instead `window`, avoid conflict with instrumentation tools - let s_window; /* allocated sliding window, if wsize != 0 */ - let hold; /* local strm.hold */ - let bits; /* local strm.bits */ - let lcode; /* local strm.lencode */ - let dcode; /* local strm.distcode */ - let lmask; /* mask for first level of length codes */ - let dmask; /* mask for first level of distance codes */ - let here; /* retrieved table entry */ - let op; /* code bits, operation, extra bits, or */ - /* window position, window bytes to copy */ - let len; /* match length, unused bytes */ - let dist; /* match distance */ - let from; /* where to copy match from */ - let from_source; - - - let input, output; // JS specific, because we have no pointers - - /* copy state to local variables */ - const state = strm.state; - //here = state.here; - _in = strm.next_in; - input = strm.input; - last = _in + (strm.avail_in - 5); - _out = strm.next_out; - output = strm.output; - beg = _out - (start - strm.avail_out); - end = _out + (strm.avail_out - 257); -//#ifdef INFLATE_STRICT - dmax = state.dmax; -//#endif - wsize = state.wsize; - whave = state.whave; - wnext = state.wnext; - s_window = state.window; - hold = state.hold; - bits = state.bits; - lcode = state.lencode; - dcode = state.distcode; - lmask = (1 << state.lenbits) - 1; - dmask = (1 << state.distbits) - 1; - - - /* decode literals and length/distances until end-of-block or not enough - input data or output space */ - - top: - do { - if (bits < 15) { - hold += input[_in++] << bits; - bits += 8; - hold += input[_in++] << bits; - bits += 8; - } - - here = lcode[hold & lmask]; - - dolen: - for (;;) { // Goto emulation - op = here >>> 24/*here.bits*/; - hold >>>= op; - bits -= op; - op = (here >>> 16) & 0xff/*here.op*/; - if (op === 0) { /* literal */ - //Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? - // "inflate: literal '%c'\n" : - // "inflate: literal 0x%02x\n", here.val)); - output[_out++] = here & 0xffff/*here.val*/; - } - else if (op & 16) { /* length base */ - len = here & 0xffff/*here.val*/; - op &= 15; /* number of extra bits */ - if (op) { - if (bits < op) { - hold += input[_in++] << bits; - bits += 8; - } - len += hold & ((1 << op) - 1); - hold >>>= op; - bits -= op; - } - //Tracevv((stderr, "inflate: length %u\n", len)); - if (bits < 15) { - hold += input[_in++] << bits; - bits += 8; - hold += input[_in++] << bits; - bits += 8; - } - here = dcode[hold & dmask]; - - dodist: - for (;;) { // goto emulation - op = here >>> 24/*here.bits*/; - hold >>>= op; - bits -= op; - op = (here >>> 16) & 0xff/*here.op*/; - - if (op & 16) { /* distance base */ - dist = here & 0xffff/*here.val*/; - op &= 15; /* number of extra bits */ - if (bits < op) { - hold += input[_in++] << bits; - bits += 8; - if (bits < op) { - hold += input[_in++] << bits; - bits += 8; - } - } - dist += hold & ((1 << op) - 1); -//#ifdef INFLATE_STRICT - if (dist > dmax) { - strm.msg = 'invalid distance too far back'; - state.mode = BAD$1$1; - break top; - } -//#endif - hold >>>= op; - bits -= op; - //Tracevv((stderr, "inflate: distance %u\n", dist)); - op = _out - beg; /* max distance in output */ - if (dist > op) { /* see if copy from window */ - op = dist - op; /* distance back in window */ - if (op > whave) { - if (state.sane) { - strm.msg = 'invalid distance too far back'; - state.mode = BAD$1$1; - break top; - } - -// (!) This block is disabled in zlib defaults, -// don't enable it for binary compatibility -//#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR -// if (len <= op - whave) { -// do { -// output[_out++] = 0; -// } while (--len); -// continue top; -// } -// len -= op - whave; -// do { -// output[_out++] = 0; -// } while (--op > whave); -// if (op === 0) { -// from = _out - dist; -// do { -// output[_out++] = output[from++]; -// } while (--len); -// continue top; -// } -//#endif - } - from = 0; // window index - from_source = s_window; - if (wnext === 0) { /* very common case */ - from += wsize - op; - if (op < len) { /* some from window */ - len -= op; - do { - output[_out++] = s_window[from++]; - } while (--op); - from = _out - dist; /* rest from output */ - from_source = output; - } - } - else if (wnext < op) { /* wrap around window */ - from += wsize + wnext - op; - op -= wnext; - if (op < len) { /* some from end of window */ - len -= op; - do { - output[_out++] = s_window[from++]; - } while (--op); - from = 0; - if (wnext < len) { /* some from start of window */ - op = wnext; - len -= op; - do { - output[_out++] = s_window[from++]; - } while (--op); - from = _out - dist; /* rest from output */ - from_source = output; - } - } - } - else { /* contiguous in window */ - from += wnext - op; - if (op < len) { /* some from window */ - len -= op; - do { - output[_out++] = s_window[from++]; - } while (--op); - from = _out - dist; /* rest from output */ - from_source = output; - } - } - while (len > 2) { - output[_out++] = from_source[from++]; - output[_out++] = from_source[from++]; - output[_out++] = from_source[from++]; - len -= 3; - } - if (len) { - output[_out++] = from_source[from++]; - if (len > 1) { - output[_out++] = from_source[from++]; - } - } - } - else { - from = _out - dist; /* copy direct from output */ - do { /* minimum length is three */ - output[_out++] = output[from++]; - output[_out++] = output[from++]; - output[_out++] = output[from++]; - len -= 3; - } while (len > 2); - if (len) { - output[_out++] = output[from++]; - if (len > 1) { - output[_out++] = output[from++]; - } - } - } - } - else if ((op & 64) === 0) { /* 2nd level distance code */ - here = dcode[(here & 0xffff)/*here.val*/ + (hold & ((1 << op) - 1))]; - continue dodist; - } - else { - strm.msg = 'invalid distance code'; - state.mode = BAD$1$1; - break top; - } - - break; // need to emulate goto via "continue" - } - } - else if ((op & 64) === 0) { /* 2nd level length code */ - here = lcode[(here & 0xffff)/*here.val*/ + (hold & ((1 << op) - 1))]; - continue dolen; - } - else if (op & 32) { /* end-of-block */ - //Tracevv((stderr, "inflate: end of block\n")); - state.mode = TYPE$1$1; - break top; - } - else { - strm.msg = 'invalid literal/length code'; - state.mode = BAD$1$1; - break top; - } - - break; // need to emulate goto via "continue" - } - } while (_in < last && _out < end); - - /* return unused bytes (on entry, bits < 8, so in won't go too far back) */ - len = bits >> 3; - _in -= len; - bits -= len << 3; - hold &= (1 << bits) - 1; - - /* update state and return */ - strm.next_in = _in; - strm.next_out = _out; - strm.avail_in = (_in < last ? 5 + (last - _in) : 5 - (_in - last)); - strm.avail_out = (_out < end ? 257 + (end - _out) : 257 - (_out - end)); - state.hold = hold; - state.bits = bits; - return; -}; - -// (C) 1995-2013 Jean-loup Gailly and Mark Adler -// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// 3. This notice may not be removed or altered from any source distribution. - -const MAXBITS$1 = 15; -const ENOUGH_LENS$1$1 = 852; -const ENOUGH_DISTS$1$1 = 592; -//const ENOUGH = (ENOUGH_LENS+ENOUGH_DISTS); - -const CODES$1$1 = 0; -const LENS$1$1 = 1; -const DISTS$1$1 = 2; - -const lbase$1 = new Uint16Array([ /* Length codes 257..285 base */ - 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, - 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0 -]); - -const lext$1 = new Uint8Array([ /* Length codes 257..285 extra */ - 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, - 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 72, 78 -]); - -const dbase$1 = new Uint16Array([ /* Distance codes 0..29 base */ - 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, - 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, - 8193, 12289, 16385, 24577, 0, 0 -]); - -const dext$1 = new Uint8Array([ /* Distance codes 0..29 extra */ - 16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, - 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, - 28, 28, 29, 29, 64, 64 -]); - -const inflate_table$1 = (type, lens, lens_index, codes, table, table_index, work, opts) => -{ - const bits = opts.bits; - //here = opts.here; /* table entry for duplication */ - - let len = 0; /* a code's length in bits */ - let sym = 0; /* index of code symbols */ - let min = 0, max = 0; /* minimum and maximum code lengths */ - let root = 0; /* number of index bits for root table */ - let curr = 0; /* number of index bits for current table */ - let drop = 0; /* code bits to drop for sub-table */ - let left = 0; /* number of prefix codes available */ - let used = 0; /* code entries in table used */ - let huff = 0; /* Huffman code */ - let incr; /* for incrementing code, index */ - let fill; /* index for replicating entries */ - let low; /* low bits for current root entry */ - let mask; /* mask for low root bits */ - let next; /* next available space in table */ - let base = null; /* base value table to use */ -// let shoextra; /* extra bits table to use */ - let match; /* use base and extra for symbol >= match */ - const count = new Uint16Array(MAXBITS$1 + 1); //[MAXBITS+1]; /* number of codes of each length */ - const offs = new Uint16Array(MAXBITS$1 + 1); //[MAXBITS+1]; /* offsets in table for each length */ - let extra = null; - - let here_bits, here_op, here_val; - - /* - Process a set of code lengths to create a canonical Huffman code. The - code lengths are lens[0..codes-1]. Each length corresponds to the - symbols 0..codes-1. The Huffman code is generated by first sorting the - symbols by length from short to long, and retaining the symbol order - for codes with equal lengths. Then the code starts with all zero bits - for the first code of the shortest length, and the codes are integer - increments for the same length, and zeros are appended as the length - increases. For the deflate format, these bits are stored backwards - from their more natural integer increment ordering, and so when the - decoding tables are built in the large loop below, the integer codes - are incremented backwards. - - This routine assumes, but does not check, that all of the entries in - lens[] are in the range 0..MAXBITS. The caller must assure this. - 1..MAXBITS is interpreted as that code length. zero means that that - symbol does not occur in this code. - - The codes are sorted by computing a count of codes for each length, - creating from that a table of starting indices for each length in the - sorted table, and then entering the symbols in order in the sorted - table. The sorted table is work[], with that space being provided by - the caller. - - The length counts are used for other purposes as well, i.e. finding - the minimum and maximum length codes, determining if there are any - codes at all, checking for a valid set of lengths, and looking ahead - at length counts to determine sub-table sizes when building the - decoding tables. - */ - - /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */ - for (len = 0; len <= MAXBITS$1; len++) { - count[len] = 0; - } - for (sym = 0; sym < codes; sym++) { - count[lens[lens_index + sym]]++; - } - - /* bound code lengths, force root to be within code lengths */ - root = bits; - for (max = MAXBITS$1; max >= 1; max--) { - if (count[max] !== 0) { break; } - } - if (root > max) { - root = max; - } - if (max === 0) { /* no symbols to code at all */ - //table.op[opts.table_index] = 64; //here.op = (var char)64; /* invalid code marker */ - //table.bits[opts.table_index] = 1; //here.bits = (var char)1; - //table.val[opts.table_index++] = 0; //here.val = (var short)0; - table[table_index++] = (1 << 24) | (64 << 16) | 0; - - - //table.op[opts.table_index] = 64; - //table.bits[opts.table_index] = 1; - //table.val[opts.table_index++] = 0; - table[table_index++] = (1 << 24) | (64 << 16) | 0; - - opts.bits = 1; - return 0; /* no symbols, but wait for decoding to report error */ - } - for (min = 1; min < max; min++) { - if (count[min] !== 0) { break; } - } - if (root < min) { - root = min; - } - - /* check for an over-subscribed or incomplete set of lengths */ - left = 1; - for (len = 1; len <= MAXBITS$1; len++) { - left <<= 1; - left -= count[len]; - if (left < 0) { - return -1; - } /* over-subscribed */ - } - if (left > 0 && (type === CODES$1$1 || max !== 1)) { - return -1; /* incomplete set */ - } - - /* generate offsets into symbol table for each length for sorting */ - offs[1] = 0; - for (len = 1; len < MAXBITS$1; len++) { - offs[len + 1] = offs[len] + count[len]; - } - - /* sort symbols by length, by symbol order within each length */ - for (sym = 0; sym < codes; sym++) { - if (lens[lens_index + sym] !== 0) { - work[offs[lens[lens_index + sym]]++] = sym; - } - } - - /* - Create and fill in decoding tables. In this loop, the table being - filled is at next and has curr index bits. The code being used is huff - with length len. That code is converted to an index by dropping drop - bits off of the bottom. For codes where len is less than drop + curr, - those top drop + curr - len bits are incremented through all values to - fill the table with replicated entries. - - root is the number of index bits for the root table. When len exceeds - root, sub-tables are created pointed to by the root entry with an index - of the low root bits of huff. This is saved in low to check for when a - new sub-table should be started. drop is zero when the root table is - being filled, and drop is root when sub-tables are being filled. - - When a new sub-table is needed, it is necessary to look ahead in the - code lengths to determine what size sub-table is needed. The length - counts are used for this, and so count[] is decremented as codes are - entered in the tables. - - used keeps track of how many table entries have been allocated from the - provided *table space. It is checked for LENS and DIST tables against - the constants ENOUGH_LENS and ENOUGH_DISTS to guard against changes in - the initial root table size constants. See the comments in inftrees.h - for more information. - - sym increments through all symbols, and the loop terminates when - all codes of length max, i.e. all codes, have been processed. This - routine permits incomplete codes, so another loop after this one fills - in the rest of the decoding tables with invalid code markers. - */ - - /* set up for code type */ - // poor man optimization - use if-else instead of switch, - // to avoid deopts in old v8 - if (type === CODES$1$1) { - base = extra = work; /* dummy value--not used */ - match = 20; - - } else if (type === LENS$1$1) { - base = lbase$1; - extra = lext$1; - match = 257; - - } else { /* DISTS */ - base = dbase$1; - extra = dext$1; - match = 0; - } - - /* initialize opts for loop */ - huff = 0; /* starting code */ - sym = 0; /* starting code symbol */ - len = min; /* starting code length */ - next = table_index; /* current table to fill in */ - curr = root; /* current table index bits */ - drop = 0; /* current bits to drop from code for index */ - low = -1; /* trigger new sub-table when len > root */ - used = 1 << root; /* use root table entries */ - mask = used - 1; /* mask for comparing low */ - - /* check available table space */ - if ((type === LENS$1$1 && used > ENOUGH_LENS$1$1) || - (type === DISTS$1$1 && used > ENOUGH_DISTS$1$1)) { - return 1; - } - - /* process all codes and make table entries */ - for (;;) { - /* create table entry */ - here_bits = len - drop; - if (work[sym] + 1 < match) { - here_op = 0; - here_val = work[sym]; - } - else if (work[sym] >= match) { - here_op = extra[work[sym] - match]; - here_val = base[work[sym] - match]; - } - else { - here_op = 32 + 64; /* end of block */ - here_val = 0; - } - - /* replicate for those indices with low len bits equal to huff */ - incr = 1 << (len - drop); - fill = 1 << curr; - min = fill; /* save offset to next table */ - do { - fill -= incr; - table[next + (huff >> drop) + fill] = (here_bits << 24) | (here_op << 16) | here_val |0; - } while (fill !== 0); - - /* backwards increment the len-bit code huff */ - incr = 1 << (len - 1); - while (huff & incr) { - incr >>= 1; - } - if (incr !== 0) { - huff &= incr - 1; - huff += incr; - } else { - huff = 0; - } - - /* go to next symbol, update count, len */ - sym++; - if (--count[len] === 0) { - if (len === max) { break; } - len = lens[lens_index + work[sym]]; - } - - /* create new sub-table if needed */ - if (len > root && (huff & mask) !== low) { - /* if first time, transition to sub-tables */ - if (drop === 0) { - drop = root; - } - - /* increment past last table */ - next += min; /* here min is 1 << curr */ - - /* determine length of next table */ - curr = len - drop; - left = 1 << curr; - while (curr + drop < max) { - left -= count[curr + drop]; - if (left <= 0) { break; } - curr++; - left <<= 1; - } - - /* check for enough space */ - used += 1 << curr; - if ((type === LENS$1$1 && used > ENOUGH_LENS$1$1) || - (type === DISTS$1$1 && used > ENOUGH_DISTS$1$1)) { - return 1; - } - - /* point entry in root table to sub-table */ - low = huff & mask; - /*table.op[low] = curr; - table.bits[low] = root; - table.val[low] = next - opts.table_index;*/ - table[low] = (root << 24) | (curr << 16) | (next - table_index) |0; - } - } - - /* fill in remaining table entry if code is incomplete (guaranteed to have - at most one remaining entry, since if the code is incomplete, the - maximum code length that was allowed to get this far is one bit) */ - if (huff !== 0) { - //table.op[next + huff] = 64; /* invalid code marker */ - //table.bits[next + huff] = len - drop; - //table.val[next + huff] = 0; - table[next + huff] = ((len - drop) << 24) | (64 << 16) |0; - } - - /* set return parameters */ - //opts.table_index += used; - opts.bits = root; - return 0; -}; - - -var inftrees$1 = inflate_table$1; - -// (C) 1995-2013 Jean-loup Gailly and Mark Adler -// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// 3. This notice may not be removed or altered from any source distribution. - - - - - - -const CODES$2 = 0; -const LENS$2 = 1; -const DISTS$2 = 2; - -/* Public constants ==========================================================*/ -/* ===========================================================================*/ - -const { - Z_FINISH: Z_FINISH$1$1, Z_BLOCK: Z_BLOCK$2, Z_TREES: Z_TREES$1, - Z_OK: Z_OK$1$1, Z_STREAM_END: Z_STREAM_END$1$1, Z_NEED_DICT: Z_NEED_DICT$1$1, Z_STREAM_ERROR: Z_STREAM_ERROR$1$1, Z_DATA_ERROR: Z_DATA_ERROR$1$1, Z_MEM_ERROR: Z_MEM_ERROR$1$1, Z_BUF_ERROR: Z_BUF_ERROR$2, - Z_DEFLATED: Z_DEFLATED$3 -} = constants$2$1; - - -/* STATES ====================================================================*/ -/* ===========================================================================*/ - - -const HEAD$1 = 16180; /* i: waiting for magic header */ -const FLAGS$1 = 16181; /* i: waiting for method and flags (gzip) */ -const TIME$1 = 16182; /* i: waiting for modification time (gzip) */ -const OS$1 = 16183; /* i: waiting for extra flags and operating system (gzip) */ -const EXLEN$1 = 16184; /* i: waiting for extra length (gzip) */ -const EXTRA$1 = 16185; /* i: waiting for extra bytes (gzip) */ -const NAME$1 = 16186; /* i: waiting for end of file name (gzip) */ -const COMMENT$1 = 16187; /* i: waiting for end of comment (gzip) */ -const HCRC$1 = 16188; /* i: waiting for header crc (gzip) */ -const DICTID$1 = 16189; /* i: waiting for dictionary check value */ -const DICT$1 = 16190; /* waiting for inflateSetDictionary() call */ -const TYPE$2 = 16191; /* i: waiting for type bits, including last-flag bit */ -const TYPEDO$1 = 16192; /* i: same, but skip check to exit inflate on new block */ -const STORED$1 = 16193; /* i: waiting for stored size (length and complement) */ -const COPY_$1 = 16194; /* i/o: same as COPY below, but only first time in */ -const COPY$1 = 16195; /* i/o: waiting for input or output to copy stored block */ -const TABLE$1 = 16196; /* i: waiting for dynamic block table lengths */ -const LENLENS$1 = 16197; /* i: waiting for code length code lengths */ -const CODELENS$1 = 16198; /* i: waiting for length/lit and distance code lengths */ -const LEN_$1 = 16199; /* i: same as LEN below, but only first time in */ -const LEN$1 = 16200; /* i: waiting for length/lit/eob code */ -const LENEXT$1 = 16201; /* i: waiting for length extra bits */ -const DIST$1 = 16202; /* i: waiting for distance code */ -const DISTEXT$1 = 16203; /* i: waiting for distance extra bits */ -const MATCH$1 = 16204; /* o: waiting for output space to copy string */ -const LIT$1 = 16205; /* o: waiting for output space to write literal */ -const CHECK$1 = 16206; /* i: waiting for 32-bit check value */ -const LENGTH$1 = 16207; /* i: waiting for 32-bit length (gzip) */ -const DONE$1 = 16208; /* finished check, done -- remain here until reset */ -const BAD$2 = 16209; /* got a data error -- remain here until reset */ -const MEM$1 = 16210; /* got an inflate() memory error -- remain here until reset */ -const SYNC$1 = 16211; /* looking for synchronization bytes to restart inflate() */ - -/* ===========================================================================*/ - - - -const ENOUGH_LENS$2 = 852; -const ENOUGH_DISTS$2 = 592; -//const ENOUGH = (ENOUGH_LENS+ENOUGH_DISTS); - -const MAX_WBITS$2 = 15; -/* 32K LZ77 window */ -const DEF_WBITS$1 = MAX_WBITS$2; - - -const zswap32$1 = (q) => { - - return (((q >>> 24) & 0xff) + - ((q >>> 8) & 0xff00) + - ((q & 0xff00) << 8) + - ((q & 0xff) << 24)); -}; - - -function InflateState$1() { - this.strm = null; /* pointer back to this zlib stream */ - this.mode = 0; /* current inflate mode */ - this.last = false; /* true if processing last block */ - this.wrap = 0; /* bit 0 true for zlib, bit 1 true for gzip, - bit 2 true to validate check value */ - this.havedict = false; /* true if dictionary provided */ - this.flags = 0; /* gzip header method and flags (0 if zlib), or - -1 if raw or no header yet */ - this.dmax = 0; /* zlib header max distance (INFLATE_STRICT) */ - this.check = 0; /* protected copy of check value */ - this.total = 0; /* protected copy of output count */ - // TODO: may be {} - this.head = null; /* where to save gzip header information */ - - /* sliding window */ - this.wbits = 0; /* log base 2 of requested window size */ - this.wsize = 0; /* window size or zero if not using window */ - this.whave = 0; /* valid bytes in the window */ - this.wnext = 0; /* window write index */ - this.window = null; /* allocated sliding window, if needed */ - - /* bit accumulator */ - this.hold = 0; /* input bit accumulator */ - this.bits = 0; /* number of bits in "in" */ - - /* for string and stored block copying */ - this.length = 0; /* literal or length of data to copy */ - this.offset = 0; /* distance back to copy string from */ - - /* for table and code decoding */ - this.extra = 0; /* extra bits needed */ - - /* fixed and dynamic code tables */ - this.lencode = null; /* starting table for length/literal codes */ - this.distcode = null; /* starting table for distance codes */ - this.lenbits = 0; /* index bits for lencode */ - this.distbits = 0; /* index bits for distcode */ - - /* dynamic table building */ - this.ncode = 0; /* number of code length code lengths */ - this.nlen = 0; /* number of length code lengths */ - this.ndist = 0; /* number of distance code lengths */ - this.have = 0; /* number of code lengths in lens[] */ - this.next = null; /* next available space in codes[] */ - - this.lens = new Uint16Array(320); /* temporary storage for code lengths */ - this.work = new Uint16Array(288); /* work area for code table building */ - - /* - because we don't have pointers in js, we use lencode and distcode directly - as buffers so we don't need codes - */ - //this.codes = new Int32Array(ENOUGH); /* space for code tables */ - this.lendyn = null; /* dynamic table for length/literal codes (JS specific) */ - this.distdyn = null; /* dynamic table for distance codes (JS specific) */ - this.sane = 0; /* if false, allow invalid distance too far */ - this.back = 0; /* bits back of last unprocessed length/lit */ - this.was = 0; /* initial length of match */ -} - - -const inflateStateCheck = (strm) => { - - if (!strm) { - return 1; - } - const state = strm.state; - if (!state || state.strm !== strm || - state.mode < HEAD$1 || state.mode > SYNC$1) { - return 1; - } - return 0; -}; - - -const inflateResetKeep$1 = (strm) => { - - if (inflateStateCheck(strm)) { return Z_STREAM_ERROR$1$1; } - const state = strm.state; - strm.total_in = strm.total_out = state.total = 0; - strm.msg = ''; /*Z_NULL*/ - if (state.wrap) { /* to support ill-conceived Java test suite */ - strm.adler = state.wrap & 1; - } - state.mode = HEAD$1; - state.last = 0; - state.havedict = 0; - state.flags = -1; - state.dmax = 32768; - state.head = null/*Z_NULL*/; - state.hold = 0; - state.bits = 0; - //state.lencode = state.distcode = state.next = state.codes; - state.lencode = state.lendyn = new Int32Array(ENOUGH_LENS$2); - state.distcode = state.distdyn = new Int32Array(ENOUGH_DISTS$2); - - state.sane = 1; - state.back = -1; - //Tracev((stderr, "inflate: reset\n")); - return Z_OK$1$1; -}; - - -const inflateReset$1 = (strm) => { - - if (inflateStateCheck(strm)) { return Z_STREAM_ERROR$1$1; } - const state = strm.state; - state.wsize = 0; - state.whave = 0; - state.wnext = 0; - return inflateResetKeep$1(strm); - -}; - - -const inflateReset2$1 = (strm, windowBits) => { - let wrap; - - /* get the state */ - if (inflateStateCheck(strm)) { return Z_STREAM_ERROR$1$1; } - const state = strm.state; - - /* extract wrap request from windowBits parameter */ - if (windowBits < 0) { - wrap = 0; - windowBits = -windowBits; - } - else { - wrap = (windowBits >> 4) + 5; - if (windowBits < 48) { - windowBits &= 15; - } - } - - /* set number of window bits, free window if different */ - if (windowBits && (windowBits < 8 || windowBits > 15)) { - return Z_STREAM_ERROR$1$1; - } - if (state.window !== null && state.wbits !== windowBits) { - state.window = null; - } - - /* update state and reset the rest of it */ - state.wrap = wrap; - state.wbits = windowBits; - return inflateReset$1(strm); -}; - - -const inflateInit2$1 = (strm, windowBits) => { - - if (!strm) { return Z_STREAM_ERROR$1$1; } - //strm.msg = Z_NULL; /* in case we return an error */ - - const state = new InflateState$1(); - - //if (state === Z_NULL) return Z_MEM_ERROR; - //Tracev((stderr, "inflate: allocated\n")); - strm.state = state; - state.strm = strm; - state.window = null/*Z_NULL*/; - state.mode = HEAD$1; /* to pass state test in inflateReset2() */ - const ret = inflateReset2$1(strm, windowBits); - if (ret !== Z_OK$1$1) { - strm.state = null/*Z_NULL*/; - } - return ret; -}; - - -const inflateInit$1 = (strm) => { - - return inflateInit2$1(strm, DEF_WBITS$1); -}; - - -/* - Return state with length and distance decoding tables and index sizes set to - fixed code decoding. Normally this returns fixed tables from inffixed.h. - If BUILDFIXED is defined, then instead this routine builds the tables the - first time it's called, and returns those tables the first time and - thereafter. This reduces the size of the code by about 2K bytes, in - exchange for a little execution time. However, BUILDFIXED should not be - used for threaded applications, since the rewriting of the tables and virgin - may not be thread-safe. - */ -let virgin$1 = true; - -let lenfix$1, distfix$1; // We have no pointers in JS, so keep tables separate - - -const fixedtables$1 = (state) => { - - /* build fixed huffman tables if first call (may not be thread safe) */ - if (virgin$1) { - lenfix$1 = new Int32Array(512); - distfix$1 = new Int32Array(32); - - /* literal/length table */ - let sym = 0; - while (sym < 144) { state.lens[sym++] = 8; } - while (sym < 256) { state.lens[sym++] = 9; } - while (sym < 280) { state.lens[sym++] = 7; } - while (sym < 288) { state.lens[sym++] = 8; } - - inftrees$1(LENS$2, state.lens, 0, 288, lenfix$1, 0, state.work, { bits: 9 }); - - /* distance table */ - sym = 0; - while (sym < 32) { state.lens[sym++] = 5; } - - inftrees$1(DISTS$2, state.lens, 0, 32, distfix$1, 0, state.work, { bits: 5 }); - - /* do this just once */ - virgin$1 = false; - } - - state.lencode = lenfix$1; - state.lenbits = 9; - state.distcode = distfix$1; - state.distbits = 5; -}; - - -/* - Update the window with the last wsize (normally 32K) bytes written before - returning. If window does not exist yet, create it. This is only called - when a window is already in use, or when output has been written during this - inflate call, but the end of the deflate stream has not been reached yet. - It is also called to create a window for dictionary data when a dictionary - is loaded. - - Providing output buffers larger than 32K to inflate() should provide a speed - advantage, since only the last 32K of output is copied to the sliding window - upon return from inflate(), and since all distances after the first 32K of - output will fall in the output data, making match copies simpler and faster. - The advantage may be dependent on the size of the processor's data caches. - */ -const updatewindow$1 = (strm, src, end, copy) => { - - let dist; - const state = strm.state; - - /* if it hasn't been done already, allocate space for the window */ - if (state.window === null) { - state.wsize = 1 << state.wbits; - state.wnext = 0; - state.whave = 0; - - state.window = new Uint8Array(state.wsize); - } - - /* copy state->wsize or less output bytes into the circular window */ - if (copy >= state.wsize) { - state.window.set(src.subarray(end - state.wsize, end), 0); - state.wnext = 0; - state.whave = state.wsize; - } - else { - dist = state.wsize - state.wnext; - if (dist > copy) { - dist = copy; - } - //zmemcpy(state->window + state->wnext, end - copy, dist); - state.window.set(src.subarray(end - copy, end - copy + dist), state.wnext); - copy -= dist; - if (copy) { - //zmemcpy(state->window, end - copy, copy); - state.window.set(src.subarray(end - copy, end), 0); - state.wnext = copy; - state.whave = state.wsize; - } - else { - state.wnext += dist; - if (state.wnext === state.wsize) { state.wnext = 0; } - if (state.whave < state.wsize) { state.whave += dist; } - } - } - return 0; -}; - - -const inflate$2$1 = (strm, flush) => { - - let state; - let input, output; // input/output buffers - let next; /* next input INDEX */ - let put; /* next output INDEX */ - let have, left; /* available input and output */ - let hold; /* bit buffer */ - let bits; /* bits in bit buffer */ - let _in, _out; /* save starting available input and output */ - let copy; /* number of stored or match bytes to copy */ - let from; /* where to copy match bytes from */ - let from_source; - let here = 0; /* current decoding table entry */ - let here_bits, here_op, here_val; // paked "here" denormalized (JS specific) - //let last; /* parent table entry */ - let last_bits, last_op, last_val; // paked "last" denormalized (JS specific) - let len; /* length to copy for repeats, bits to drop */ - let ret; /* return code */ - const hbuf = new Uint8Array(4); /* buffer for gzip header crc calculation */ - let opts; - - let n; // temporary variable for NEED_BITS - - const order = /* permutation of code lengths */ - new Uint8Array([ 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 ]); - - - if (inflateStateCheck(strm) || !strm.output || - (!strm.input && strm.avail_in !== 0)) { - return Z_STREAM_ERROR$1$1; - } - - state = strm.state; - if (state.mode === TYPE$2) { state.mode = TYPEDO$1; } /* skip check */ - - - //--- LOAD() --- - put = strm.next_out; - output = strm.output; - left = strm.avail_out; - next = strm.next_in; - input = strm.input; - have = strm.avail_in; - hold = state.hold; - bits = state.bits; - //--- - - _in = have; - _out = left; - ret = Z_OK$1$1; - - inf_leave: // goto emulation - for (;;) { - switch (state.mode) { - case HEAD$1: - if (state.wrap === 0) { - state.mode = TYPEDO$1; - break; - } - //=== NEEDBITS(16); - while (bits < 16) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - if ((state.wrap & 2) && hold === 0x8b1f) { /* gzip header */ - if (state.wbits === 0) { - state.wbits = 15; - } - state.check = 0/*crc32(0L, Z_NULL, 0)*/; - //=== CRC2(state.check, hold); - hbuf[0] = hold & 0xff; - hbuf[1] = (hold >>> 8) & 0xff; - state.check = crc32_1$1(state.check, hbuf, 2, 0); - //===// - - //=== INITBITS(); - hold = 0; - bits = 0; - //===// - state.mode = FLAGS$1; - break; - } - if (state.head) { - state.head.done = false; - } - if (!(state.wrap & 1) || /* check if zlib header allowed */ - (((hold & 0xff)/*BITS(8)*/ << 8) + (hold >> 8)) % 31) { - strm.msg = 'incorrect header check'; - state.mode = BAD$2; - break; - } - if ((hold & 0x0f)/*BITS(4)*/ !== Z_DEFLATED$3) { - strm.msg = 'unknown compression method'; - state.mode = BAD$2; - break; - } - //--- DROPBITS(4) ---// - hold >>>= 4; - bits -= 4; - //---// - len = (hold & 0x0f)/*BITS(4)*/ + 8; - if (state.wbits === 0) { - state.wbits = len; - } - if (len > 15 || len > state.wbits) { - strm.msg = 'invalid window size'; - state.mode = BAD$2; - break; - } - - // !!! pako patch. Force use `options.windowBits` if passed. - // Required to always use max window size by default. - state.dmax = 1 << state.wbits; - //state.dmax = 1 << len; - - state.flags = 0; /* indicate zlib header */ - //Tracev((stderr, "inflate: zlib header ok\n")); - strm.adler = state.check = 1/*adler32(0L, Z_NULL, 0)*/; - state.mode = hold & 0x200 ? DICTID$1 : TYPE$2; - //=== INITBITS(); - hold = 0; - bits = 0; - //===// - break; - case FLAGS$1: - //=== NEEDBITS(16); */ - while (bits < 16) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - state.flags = hold; - if ((state.flags & 0xff) !== Z_DEFLATED$3) { - strm.msg = 'unknown compression method'; - state.mode = BAD$2; - break; - } - if (state.flags & 0xe000) { - strm.msg = 'unknown header flags set'; - state.mode = BAD$2; - break; - } - if (state.head) { - state.head.text = ((hold >> 8) & 1); - } - if ((state.flags & 0x0200) && (state.wrap & 4)) { - //=== CRC2(state.check, hold); - hbuf[0] = hold & 0xff; - hbuf[1] = (hold >>> 8) & 0xff; - state.check = crc32_1$1(state.check, hbuf, 2, 0); - //===// - } - //=== INITBITS(); - hold = 0; - bits = 0; - //===// - state.mode = TIME$1; - /* falls through */ - case TIME$1: - //=== NEEDBITS(32); */ - while (bits < 32) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - if (state.head) { - state.head.time = hold; - } - if ((state.flags & 0x0200) && (state.wrap & 4)) { - //=== CRC4(state.check, hold) - hbuf[0] = hold & 0xff; - hbuf[1] = (hold >>> 8) & 0xff; - hbuf[2] = (hold >>> 16) & 0xff; - hbuf[3] = (hold >>> 24) & 0xff; - state.check = crc32_1$1(state.check, hbuf, 4, 0); - //=== - } - //=== INITBITS(); - hold = 0; - bits = 0; - //===// - state.mode = OS$1; - /* falls through */ - case OS$1: - //=== NEEDBITS(16); */ - while (bits < 16) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - if (state.head) { - state.head.xflags = (hold & 0xff); - state.head.os = (hold >> 8); - } - if ((state.flags & 0x0200) && (state.wrap & 4)) { - //=== CRC2(state.check, hold); - hbuf[0] = hold & 0xff; - hbuf[1] = (hold >>> 8) & 0xff; - state.check = crc32_1$1(state.check, hbuf, 2, 0); - //===// - } - //=== INITBITS(); - hold = 0; - bits = 0; - //===// - state.mode = EXLEN$1; - /* falls through */ - case EXLEN$1: - if (state.flags & 0x0400) { - //=== NEEDBITS(16); */ - while (bits < 16) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - state.length = hold; - if (state.head) { - state.head.extra_len = hold; - } - if ((state.flags & 0x0200) && (state.wrap & 4)) { - //=== CRC2(state.check, hold); - hbuf[0] = hold & 0xff; - hbuf[1] = (hold >>> 8) & 0xff; - state.check = crc32_1$1(state.check, hbuf, 2, 0); - //===// - } - //=== INITBITS(); - hold = 0; - bits = 0; - //===// - } - else if (state.head) { - state.head.extra = null/*Z_NULL*/; - } - state.mode = EXTRA$1; - /* falls through */ - case EXTRA$1: - if (state.flags & 0x0400) { - copy = state.length; - if (copy > have) { copy = have; } - if (copy) { - if (state.head) { - len = state.head.extra_len - state.length; - if (!state.head.extra) { - // Use untyped array for more convenient processing later - state.head.extra = new Uint8Array(state.head.extra_len); - } - state.head.extra.set( - input.subarray( - next, - // extra field is limited to 65536 bytes - // - no need for additional size check - next + copy - ), - /*len + copy > state.head.extra_max - len ? state.head.extra_max : copy,*/ - len - ); - //zmemcpy(state.head.extra + len, next, - // len + copy > state.head.extra_max ? - // state.head.extra_max - len : copy); - } - if ((state.flags & 0x0200) && (state.wrap & 4)) { - state.check = crc32_1$1(state.check, input, copy, next); - } - have -= copy; - next += copy; - state.length -= copy; - } - if (state.length) { break inf_leave; } - } - state.length = 0; - state.mode = NAME$1; - /* falls through */ - case NAME$1: - if (state.flags & 0x0800) { - if (have === 0) { break inf_leave; } - copy = 0; - do { - // TODO: 2 or 1 bytes? - len = input[next + copy++]; - /* use constant limit because in js we should not preallocate memory */ - if (state.head && len && - (state.length < 65536 /*state.head.name_max*/)) { - state.head.name += String.fromCharCode(len); - } - } while (len && copy < have); - - if ((state.flags & 0x0200) && (state.wrap & 4)) { - state.check = crc32_1$1(state.check, input, copy, next); - } - have -= copy; - next += copy; - if (len) { break inf_leave; } - } - else if (state.head) { - state.head.name = null; - } - state.length = 0; - state.mode = COMMENT$1; - /* falls through */ - case COMMENT$1: - if (state.flags & 0x1000) { - if (have === 0) { break inf_leave; } - copy = 0; - do { - len = input[next + copy++]; - /* use constant limit because in js we should not preallocate memory */ - if (state.head && len && - (state.length < 65536 /*state.head.comm_max*/)) { - state.head.comment += String.fromCharCode(len); - } - } while (len && copy < have); - if ((state.flags & 0x0200) && (state.wrap & 4)) { - state.check = crc32_1$1(state.check, input, copy, next); - } - have -= copy; - next += copy; - if (len) { break inf_leave; } - } - else if (state.head) { - state.head.comment = null; - } - state.mode = HCRC$1; - /* falls through */ - case HCRC$1: - if (state.flags & 0x0200) { - //=== NEEDBITS(16); */ - while (bits < 16) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - if ((state.wrap & 4) && hold !== (state.check & 0xffff)) { - strm.msg = 'header crc mismatch'; - state.mode = BAD$2; - break; - } - //=== INITBITS(); - hold = 0; - bits = 0; - //===// - } - if (state.head) { - state.head.hcrc = ((state.flags >> 9) & 1); - state.head.done = true; - } - strm.adler = state.check = 0; - state.mode = TYPE$2; - break; - case DICTID$1: - //=== NEEDBITS(32); */ - while (bits < 32) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - strm.adler = state.check = zswap32$1(hold); - //=== INITBITS(); - hold = 0; - bits = 0; - //===// - state.mode = DICT$1; - /* falls through */ - case DICT$1: - if (state.havedict === 0) { - //--- RESTORE() --- - strm.next_out = put; - strm.avail_out = left; - strm.next_in = next; - strm.avail_in = have; - state.hold = hold; - state.bits = bits; - //--- - return Z_NEED_DICT$1$1; - } - strm.adler = state.check = 1/*adler32(0L, Z_NULL, 0)*/; - state.mode = TYPE$2; - /* falls through */ - case TYPE$2: - if (flush === Z_BLOCK$2 || flush === Z_TREES$1) { break inf_leave; } - /* falls through */ - case TYPEDO$1: - if (state.last) { - //--- BYTEBITS() ---// - hold >>>= bits & 7; - bits -= bits & 7; - //---// - state.mode = CHECK$1; - break; - } - //=== NEEDBITS(3); */ - while (bits < 3) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - state.last = (hold & 0x01)/*BITS(1)*/; - //--- DROPBITS(1) ---// - hold >>>= 1; - bits -= 1; - //---// - - switch ((hold & 0x03)/*BITS(2)*/) { - case 0: /* stored block */ - //Tracev((stderr, "inflate: stored block%s\n", - // state.last ? " (last)" : "")); - state.mode = STORED$1; - break; - case 1: /* fixed block */ - fixedtables$1(state); - //Tracev((stderr, "inflate: fixed codes block%s\n", - // state.last ? " (last)" : "")); - state.mode = LEN_$1; /* decode codes */ - if (flush === Z_TREES$1) { - //--- DROPBITS(2) ---// - hold >>>= 2; - bits -= 2; - //---// - break inf_leave; - } - break; - case 2: /* dynamic block */ - //Tracev((stderr, "inflate: dynamic codes block%s\n", - // state.last ? " (last)" : "")); - state.mode = TABLE$1; - break; - case 3: - strm.msg = 'invalid block type'; - state.mode = BAD$2; - } - //--- DROPBITS(2) ---// - hold >>>= 2; - bits -= 2; - //---// - break; - case STORED$1: - //--- BYTEBITS() ---// /* go to byte boundary */ - hold >>>= bits & 7; - bits -= bits & 7; - //---// - //=== NEEDBITS(32); */ - while (bits < 32) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - if ((hold & 0xffff) !== ((hold >>> 16) ^ 0xffff)) { - strm.msg = 'invalid stored block lengths'; - state.mode = BAD$2; - break; - } - state.length = hold & 0xffff; - //Tracev((stderr, "inflate: stored length %u\n", - // state.length)); - //=== INITBITS(); - hold = 0; - bits = 0; - //===// - state.mode = COPY_$1; - if (flush === Z_TREES$1) { break inf_leave; } - /* falls through */ - case COPY_$1: - state.mode = COPY$1; - /* falls through */ - case COPY$1: - copy = state.length; - if (copy) { - if (copy > have) { copy = have; } - if (copy > left) { copy = left; } - if (copy === 0) { break inf_leave; } - //--- zmemcpy(put, next, copy); --- - output.set(input.subarray(next, next + copy), put); - //---// - have -= copy; - next += copy; - left -= copy; - put += copy; - state.length -= copy; - break; - } - //Tracev((stderr, "inflate: stored end\n")); - state.mode = TYPE$2; - break; - case TABLE$1: - //=== NEEDBITS(14); */ - while (bits < 14) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - state.nlen = (hold & 0x1f)/*BITS(5)*/ + 257; - //--- DROPBITS(5) ---// - hold >>>= 5; - bits -= 5; - //---// - state.ndist = (hold & 0x1f)/*BITS(5)*/ + 1; - //--- DROPBITS(5) ---// - hold >>>= 5; - bits -= 5; - //---// - state.ncode = (hold & 0x0f)/*BITS(4)*/ + 4; - //--- DROPBITS(4) ---// - hold >>>= 4; - bits -= 4; - //---// -//#ifndef PKZIP_BUG_WORKAROUND - if (state.nlen > 286 || state.ndist > 30) { - strm.msg = 'too many length or distance symbols'; - state.mode = BAD$2; - break; - } -//#endif - //Tracev((stderr, "inflate: table sizes ok\n")); - state.have = 0; - state.mode = LENLENS$1; - /* falls through */ - case LENLENS$1: - while (state.have < state.ncode) { - //=== NEEDBITS(3); - while (bits < 3) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - state.lens[order[state.have++]] = (hold & 0x07);//BITS(3); - //--- DROPBITS(3) ---// - hold >>>= 3; - bits -= 3; - //---// - } - while (state.have < 19) { - state.lens[order[state.have++]] = 0; - } - // We have separate tables & no pointers. 2 commented lines below not needed. - //state.next = state.codes; - //state.lencode = state.next; - // Switch to use dynamic table - state.lencode = state.lendyn; - state.lenbits = 7; - - opts = { bits: state.lenbits }; - ret = inftrees$1(CODES$2, state.lens, 0, 19, state.lencode, 0, state.work, opts); - state.lenbits = opts.bits; - - if (ret) { - strm.msg = 'invalid code lengths set'; - state.mode = BAD$2; - break; - } - //Tracev((stderr, "inflate: code lengths ok\n")); - state.have = 0; - state.mode = CODELENS$1; - /* falls through */ - case CODELENS$1: - while (state.have < state.nlen + state.ndist) { - for (;;) { - here = state.lencode[hold & ((1 << state.lenbits) - 1)];/*BITS(state.lenbits)*/ - here_bits = here >>> 24; - here_op = (here >>> 16) & 0xff; - here_val = here & 0xffff; - - if ((here_bits) <= bits) { break; } - //--- PULLBYTE() ---// - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - //---// - } - if (here_val < 16) { - //--- DROPBITS(here.bits) ---// - hold >>>= here_bits; - bits -= here_bits; - //---// - state.lens[state.have++] = here_val; - } - else { - if (here_val === 16) { - //=== NEEDBITS(here.bits + 2); - n = here_bits + 2; - while (bits < n) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - //--- DROPBITS(here.bits) ---// - hold >>>= here_bits; - bits -= here_bits; - //---// - if (state.have === 0) { - strm.msg = 'invalid bit length repeat'; - state.mode = BAD$2; - break; - } - len = state.lens[state.have - 1]; - copy = 3 + (hold & 0x03);//BITS(2); - //--- DROPBITS(2) ---// - hold >>>= 2; - bits -= 2; - //---// - } - else if (here_val === 17) { - //=== NEEDBITS(here.bits + 3); - n = here_bits + 3; - while (bits < n) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - //--- DROPBITS(here.bits) ---// - hold >>>= here_bits; - bits -= here_bits; - //---// - len = 0; - copy = 3 + (hold & 0x07);//BITS(3); - //--- DROPBITS(3) ---// - hold >>>= 3; - bits -= 3; - //---// - } - else { - //=== NEEDBITS(here.bits + 7); - n = here_bits + 7; - while (bits < n) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - //--- DROPBITS(here.bits) ---// - hold >>>= here_bits; - bits -= here_bits; - //---// - len = 0; - copy = 11 + (hold & 0x7f);//BITS(7); - //--- DROPBITS(7) ---// - hold >>>= 7; - bits -= 7; - //---// - } - if (state.have + copy > state.nlen + state.ndist) { - strm.msg = 'invalid bit length repeat'; - state.mode = BAD$2; - break; - } - while (copy--) { - state.lens[state.have++] = len; - } - } - } - - /* handle error breaks in while */ - if (state.mode === BAD$2) { break; } - - /* check for end-of-block code (better have one) */ - if (state.lens[256] === 0) { - strm.msg = 'invalid code -- missing end-of-block'; - state.mode = BAD$2; - break; - } - - /* build code tables -- note: do not change the lenbits or distbits - values here (9 and 6) without reading the comments in inftrees.h - concerning the ENOUGH constants, which depend on those values */ - state.lenbits = 9; - - opts = { bits: state.lenbits }; - ret = inftrees$1(LENS$2, state.lens, 0, state.nlen, state.lencode, 0, state.work, opts); - // We have separate tables & no pointers. 2 commented lines below not needed. - // state.next_index = opts.table_index; - state.lenbits = opts.bits; - // state.lencode = state.next; - - if (ret) { - strm.msg = 'invalid literal/lengths set'; - state.mode = BAD$2; - break; - } - - state.distbits = 6; - //state.distcode.copy(state.codes); - // Switch to use dynamic table - state.distcode = state.distdyn; - opts = { bits: state.distbits }; - ret = inftrees$1(DISTS$2, state.lens, state.nlen, state.ndist, state.distcode, 0, state.work, opts); - // We have separate tables & no pointers. 2 commented lines below not needed. - // state.next_index = opts.table_index; - state.distbits = opts.bits; - // state.distcode = state.next; - - if (ret) { - strm.msg = 'invalid distances set'; - state.mode = BAD$2; - break; - } - //Tracev((stderr, 'inflate: codes ok\n')); - state.mode = LEN_$1; - if (flush === Z_TREES$1) { break inf_leave; } - /* falls through */ - case LEN_$1: - state.mode = LEN$1; - /* falls through */ - case LEN$1: - if (have >= 6 && left >= 258) { - //--- RESTORE() --- - strm.next_out = put; - strm.avail_out = left; - strm.next_in = next; - strm.avail_in = have; - state.hold = hold; - state.bits = bits; - //--- - inffast$1(strm, _out); - //--- LOAD() --- - put = strm.next_out; - output = strm.output; - left = strm.avail_out; - next = strm.next_in; - input = strm.input; - have = strm.avail_in; - hold = state.hold; - bits = state.bits; - //--- - - if (state.mode === TYPE$2) { - state.back = -1; - } - break; - } - state.back = 0; - for (;;) { - here = state.lencode[hold & ((1 << state.lenbits) - 1)]; /*BITS(state.lenbits)*/ - here_bits = here >>> 24; - here_op = (here >>> 16) & 0xff; - here_val = here & 0xffff; - - if (here_bits <= bits) { break; } - //--- PULLBYTE() ---// - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - //---// - } - if (here_op && (here_op & 0xf0) === 0) { - last_bits = here_bits; - last_op = here_op; - last_val = here_val; - for (;;) { - here = state.lencode[last_val + - ((hold & ((1 << (last_bits + last_op)) - 1))/*BITS(last.bits + last.op)*/ >> last_bits)]; - here_bits = here >>> 24; - here_op = (here >>> 16) & 0xff; - here_val = here & 0xffff; - - if ((last_bits + here_bits) <= bits) { break; } - //--- PULLBYTE() ---// - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - //---// - } - //--- DROPBITS(last.bits) ---// - hold >>>= last_bits; - bits -= last_bits; - //---// - state.back += last_bits; - } - //--- DROPBITS(here.bits) ---// - hold >>>= here_bits; - bits -= here_bits; - //---// - state.back += here_bits; - state.length = here_val; - if (here_op === 0) { - //Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? - // "inflate: literal '%c'\n" : - // "inflate: literal 0x%02x\n", here.val)); - state.mode = LIT$1; - break; - } - if (here_op & 32) { - //Tracevv((stderr, "inflate: end of block\n")); - state.back = -1; - state.mode = TYPE$2; - break; - } - if (here_op & 64) { - strm.msg = 'invalid literal/length code'; - state.mode = BAD$2; - break; - } - state.extra = here_op & 15; - state.mode = LENEXT$1; - /* falls through */ - case LENEXT$1: - if (state.extra) { - //=== NEEDBITS(state.extra); - n = state.extra; - while (bits < n) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - state.length += hold & ((1 << state.extra) - 1)/*BITS(state.extra)*/; - //--- DROPBITS(state.extra) ---// - hold >>>= state.extra; - bits -= state.extra; - //---// - state.back += state.extra; - } - //Tracevv((stderr, "inflate: length %u\n", state.length)); - state.was = state.length; - state.mode = DIST$1; - /* falls through */ - case DIST$1: - for (;;) { - here = state.distcode[hold & ((1 << state.distbits) - 1)];/*BITS(state.distbits)*/ - here_bits = here >>> 24; - here_op = (here >>> 16) & 0xff; - here_val = here & 0xffff; - - if ((here_bits) <= bits) { break; } - //--- PULLBYTE() ---// - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - //---// - } - if ((here_op & 0xf0) === 0) { - last_bits = here_bits; - last_op = here_op; - last_val = here_val; - for (;;) { - here = state.distcode[last_val + - ((hold & ((1 << (last_bits + last_op)) - 1))/*BITS(last.bits + last.op)*/ >> last_bits)]; - here_bits = here >>> 24; - here_op = (here >>> 16) & 0xff; - here_val = here & 0xffff; - - if ((last_bits + here_bits) <= bits) { break; } - //--- PULLBYTE() ---// - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - //---// - } - //--- DROPBITS(last.bits) ---// - hold >>>= last_bits; - bits -= last_bits; - //---// - state.back += last_bits; - } - //--- DROPBITS(here.bits) ---// - hold >>>= here_bits; - bits -= here_bits; - //---// - state.back += here_bits; - if (here_op & 64) { - strm.msg = 'invalid distance code'; - state.mode = BAD$2; - break; - } - state.offset = here_val; - state.extra = (here_op) & 15; - state.mode = DISTEXT$1; - /* falls through */ - case DISTEXT$1: - if (state.extra) { - //=== NEEDBITS(state.extra); - n = state.extra; - while (bits < n) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - state.offset += hold & ((1 << state.extra) - 1)/*BITS(state.extra)*/; - //--- DROPBITS(state.extra) ---// - hold >>>= state.extra; - bits -= state.extra; - //---// - state.back += state.extra; - } -//#ifdef INFLATE_STRICT - if (state.offset > state.dmax) { - strm.msg = 'invalid distance too far back'; - state.mode = BAD$2; - break; - } -//#endif - //Tracevv((stderr, "inflate: distance %u\n", state.offset)); - state.mode = MATCH$1; - /* falls through */ - case MATCH$1: - if (left === 0) { break inf_leave; } - copy = _out - left; - if (state.offset > copy) { /* copy from window */ - copy = state.offset - copy; - if (copy > state.whave) { - if (state.sane) { - strm.msg = 'invalid distance too far back'; - state.mode = BAD$2; - break; - } -// (!) This block is disabled in zlib defaults, -// don't enable it for binary compatibility -//#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR -// Trace((stderr, "inflate.c too far\n")); -// copy -= state.whave; -// if (copy > state.length) { copy = state.length; } -// if (copy > left) { copy = left; } -// left -= copy; -// state.length -= copy; -// do { -// output[put++] = 0; -// } while (--copy); -// if (state.length === 0) { state.mode = LEN; } -// break; -//#endif - } - if (copy > state.wnext) { - copy -= state.wnext; - from = state.wsize - copy; - } - else { - from = state.wnext - copy; - } - if (copy > state.length) { copy = state.length; } - from_source = state.window; - } - else { /* copy from output */ - from_source = output; - from = put - state.offset; - copy = state.length; - } - if (copy > left) { copy = left; } - left -= copy; - state.length -= copy; - do { - output[put++] = from_source[from++]; - } while (--copy); - if (state.length === 0) { state.mode = LEN$1; } - break; - case LIT$1: - if (left === 0) { break inf_leave; } - output[put++] = state.length; - left--; - state.mode = LEN$1; - break; - case CHECK$1: - if (state.wrap) { - //=== NEEDBITS(32); - while (bits < 32) { - if (have === 0) { break inf_leave; } - have--; - // Use '|' instead of '+' to make sure that result is signed - hold |= input[next++] << bits; - bits += 8; - } - //===// - _out -= left; - strm.total_out += _out; - state.total += _out; - if ((state.wrap & 4) && _out) { - strm.adler = state.check = - /*UPDATE_CHECK(state.check, put - _out, _out);*/ - (state.flags ? crc32_1$1(state.check, output, _out, put - _out) : adler32_1$1(state.check, output, _out, put - _out)); - - } - _out = left; - // NB: crc32 stored as signed 32-bit int, zswap32 returns signed too - if ((state.wrap & 4) && (state.flags ? hold : zswap32$1(hold)) !== state.check) { - strm.msg = 'incorrect data check'; - state.mode = BAD$2; - break; - } - //=== INITBITS(); - hold = 0; - bits = 0; - //===// - //Tracev((stderr, "inflate: check matches trailer\n")); - } - state.mode = LENGTH$1; - /* falls through */ - case LENGTH$1: - if (state.wrap && state.flags) { - //=== NEEDBITS(32); - while (bits < 32) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - if ((state.wrap & 4) && hold !== (state.total & 0xffffffff)) { - strm.msg = 'incorrect length check'; - state.mode = BAD$2; - break; - } - //=== INITBITS(); - hold = 0; - bits = 0; - //===// - //Tracev((stderr, "inflate: length matches trailer\n")); - } - state.mode = DONE$1; - /* falls through */ - case DONE$1: - ret = Z_STREAM_END$1$1; - break inf_leave; - case BAD$2: - ret = Z_DATA_ERROR$1$1; - break inf_leave; - case MEM$1: - return Z_MEM_ERROR$1$1; - case SYNC$1: - /* falls through */ - default: - return Z_STREAM_ERROR$1$1; - } - } - - // inf_leave <- here is real place for "goto inf_leave", emulated via "break inf_leave" - - /* - Return from inflate(), updating the total counts and the check value. - If there was no progress during the inflate() call, return a buffer - error. Call updatewindow() to create and/or update the window state. - Note: a memory error from inflate() is non-recoverable. - */ - - //--- RESTORE() --- - strm.next_out = put; - strm.avail_out = left; - strm.next_in = next; - strm.avail_in = have; - state.hold = hold; - state.bits = bits; - //--- - - if (state.wsize || (_out !== strm.avail_out && state.mode < BAD$2 && - (state.mode < CHECK$1 || flush !== Z_FINISH$1$1))) { - if (updatewindow$1(strm, strm.output, strm.next_out, _out - strm.avail_out)) ; - } - _in -= strm.avail_in; - _out -= strm.avail_out; - strm.total_in += _in; - strm.total_out += _out; - state.total += _out; - if ((state.wrap & 4) && _out) { - strm.adler = state.check = /*UPDATE_CHECK(state.check, strm.next_out - _out, _out);*/ - (state.flags ? crc32_1$1(state.check, output, _out, strm.next_out - _out) : adler32_1$1(state.check, output, _out, strm.next_out - _out)); - } - strm.data_type = state.bits + (state.last ? 64 : 0) + - (state.mode === TYPE$2 ? 128 : 0) + - (state.mode === LEN_$1 || state.mode === COPY_$1 ? 256 : 0); - if (((_in === 0 && _out === 0) || flush === Z_FINISH$1$1) && ret === Z_OK$1$1) { - ret = Z_BUF_ERROR$2; - } - return ret; -}; - - -const inflateEnd$1 = (strm) => { - - if (inflateStateCheck(strm)) { - return Z_STREAM_ERROR$1$1; - } - - let state = strm.state; - if (state.window) { - state.window = null; - } - strm.state = null; - return Z_OK$1$1; -}; - - -const inflateGetHeader$1 = (strm, head) => { - - /* check state */ - if (inflateStateCheck(strm)) { return Z_STREAM_ERROR$1$1; } - const state = strm.state; - if ((state.wrap & 2) === 0) { return Z_STREAM_ERROR$1$1; } - - /* save header structure */ - state.head = head; - head.done = false; - return Z_OK$1$1; -}; - - -const inflateSetDictionary$1 = (strm, dictionary) => { - const dictLength = dictionary.length; - - let state; - let dictid; - let ret; - - /* check state */ - if (inflateStateCheck(strm)) { return Z_STREAM_ERROR$1$1; } - state = strm.state; - - if (state.wrap !== 0 && state.mode !== DICT$1) { - return Z_STREAM_ERROR$1$1; - } - - /* check for correct dictionary identifier */ - if (state.mode === DICT$1) { - dictid = 1; /* adler32(0, null, 0)*/ - /* dictid = adler32(dictid, dictionary, dictLength); */ - dictid = adler32_1$1(dictid, dictionary, dictLength, 0); - if (dictid !== state.check) { - return Z_DATA_ERROR$1$1; - } - } - /* copy dictionary to window using updatewindow(), which will amend the - existing dictionary if appropriate */ - ret = updatewindow$1(strm, dictionary, dictLength, dictLength); - if (ret) { - state.mode = MEM$1; - return Z_MEM_ERROR$1$1; - } - state.havedict = 1; - // Tracev((stderr, "inflate: dictionary set\n")); - return Z_OK$1$1; -}; - - -var inflateReset_1$1 = inflateReset$1; -var inflateReset2_1$1 = inflateReset2$1; -var inflateResetKeep_1$1 = inflateResetKeep$1; -var inflateInit_1$1 = inflateInit$1; -var inflateInit2_1$1 = inflateInit2$1; -var inflate_2$1$1 = inflate$2$1; -var inflateEnd_1$1 = inflateEnd$1; -var inflateGetHeader_1$1 = inflateGetHeader$1; -var inflateSetDictionary_1$1 = inflateSetDictionary$1; -var inflateInfo$1 = 'pako inflate (from Nodeca project)'; - -/* Not implemented -module.exports.inflateCodesUsed = inflateCodesUsed; -module.exports.inflateCopy = inflateCopy; -module.exports.inflateGetDictionary = inflateGetDictionary; -module.exports.inflateMark = inflateMark; -module.exports.inflatePrime = inflatePrime; -module.exports.inflateSync = inflateSync; -module.exports.inflateSyncPoint = inflateSyncPoint; -module.exports.inflateUndermine = inflateUndermine; -module.exports.inflateValidate = inflateValidate; -*/ - -var inflate_1$2$1 = { - inflateReset: inflateReset_1$1, - inflateReset2: inflateReset2_1$1, - inflateResetKeep: inflateResetKeep_1$1, - inflateInit: inflateInit_1$1, - inflateInit2: inflateInit2_1$1, - inflate: inflate_2$1$1, - inflateEnd: inflateEnd_1$1, - inflateGetHeader: inflateGetHeader_1$1, - inflateSetDictionary: inflateSetDictionary_1$1, - inflateInfo: inflateInfo$1 -}; - -// (C) 1995-2013 Jean-loup Gailly and Mark Adler -// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// 3. This notice may not be removed or altered from any source distribution. - -function GZheader$1() { - /* true if compressed data believed to be text */ - this.text = 0; - /* modification time */ - this.time = 0; - /* extra flags (not used when writing a gzip file) */ - this.xflags = 0; - /* operating system */ - this.os = 0; - /* pointer to extra field or Z_NULL if none */ - this.extra = null; - /* extra field length (valid if extra != Z_NULL) */ - this.extra_len = 0; // Actually, we don't need it in JS, - // but leave for few code modifications - - // - // Setup limits is not necessary because in js we should not preallocate memory - // for inflate use constant limit in 65536 bytes - // - - /* space at extra (only when reading header) */ - // this.extra_max = 0; - /* pointer to zero-terminated file name or Z_NULL */ - this.name = ''; - /* space at name (only when reading header) */ - // this.name_max = 0; - /* pointer to zero-terminated comment or Z_NULL */ - this.comment = ''; - /* space at comment (only when reading header) */ - // this.comm_max = 0; - /* true if there was or will be a header crc */ - this.hcrc = 0; - /* true when done reading gzip header (not used when writing a gzip file) */ - this.done = false; -} - -var gzheader$1 = GZheader$1; - -const toString$2 = Object.prototype.toString; - -/* Public constants ==========================================================*/ -/* ===========================================================================*/ - -const { - Z_NO_FLUSH: Z_NO_FLUSH$3, Z_FINISH: Z_FINISH$4, - Z_OK: Z_OK$4, Z_STREAM_END: Z_STREAM_END$4, Z_NEED_DICT: Z_NEED_DICT$2, Z_STREAM_ERROR: Z_STREAM_ERROR$3, Z_DATA_ERROR: Z_DATA_ERROR$3, Z_MEM_ERROR: Z_MEM_ERROR$2 -} = constants$2$1; - -/* ===========================================================================*/ - - -/** - * class Inflate - * - * Generic JS-style wrapper for zlib calls. If you don't need - * streaming behaviour - use more simple functions: [[inflate]] - * and [[inflateRaw]]. - **/ - -/* internal - * inflate.chunks -> Array - * - * Chunks of output data, if [[Inflate#onData]] not overridden. - **/ - -/** - * Inflate.result -> Uint8Array|String - * - * Uncompressed result, generated by default [[Inflate#onData]] - * and [[Inflate#onEnd]] handlers. Filled after you push last chunk - * (call [[Inflate#push]] with `Z_FINISH` / `true` param). - **/ - -/** - * Inflate.err -> Number - * - * Error code after inflate finished. 0 (Z_OK) on success. - * Should be checked if broken data possible. - **/ - -/** - * Inflate.msg -> String - * - * Error message, if [[Inflate.err]] != 0 - **/ - - -/** - * new Inflate(options) - * - options (Object): zlib inflate options. - * - * Creates new inflator instance with specified params. Throws exception - * on bad params. Supported options: - * - * - `windowBits` - * - `dictionary` - * - * [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced) - * for more information on these. - * - * Additional options, for internal needs: - * - * - `chunkSize` - size of generated data chunks (16K by default) - * - `raw` (Boolean) - do raw inflate - * - `to` (String) - if equal to 'string', then result will be converted - * from utf8 to utf16 (javascript) string. When string output requested, - * chunk length can differ from `chunkSize`, depending on content. - * - * By default, when no options set, autodetect deflate/gzip data format via - * wrapper header. - * - * ##### Example: - * - * ```javascript - * const pako = require('pako') - * const chunk1 = new Uint8Array([1,2,3,4,5,6,7,8,9]) - * const chunk2 = new Uint8Array([10,11,12,13,14,15,16,17,18,19]); - * - * const inflate = new pako.Inflate({ level: 3}); - * - * inflate.push(chunk1, false); - * inflate.push(chunk2, true); // true -> last chunk - * - * if (inflate.err) { throw new Error(inflate.err); } - * - * console.log(inflate.result); - * ``` - **/ -function Inflate$1$1(options) { - this.options = common$1.assign({ - chunkSize: 1024 * 64, - windowBits: 15, - to: '' - }, options || {}); - - const opt = this.options; - - // Force window size for `raw` data, if not set directly, - // because we have no header for autodetect. - if (opt.raw && (opt.windowBits >= 0) && (opt.windowBits < 16)) { - opt.windowBits = -opt.windowBits; - if (opt.windowBits === 0) { opt.windowBits = -15; } - } - - // If `windowBits` not defined (and mode not raw) - set autodetect flag for gzip/deflate - if ((opt.windowBits >= 0) && (opt.windowBits < 16) && - !(options && options.windowBits)) { - opt.windowBits += 32; - } - - // Gzip header has no info about windows size, we can do autodetect only - // for deflate. So, if window size not set, force it to max when gzip possible - if ((opt.windowBits > 15) && (opt.windowBits < 48)) { - // bit 3 (16) -> gzipped data - // bit 4 (32) -> autodetect gzip/deflate - if ((opt.windowBits & 15) === 0) { - opt.windowBits |= 15; - } - } - - this.err = 0; // error code, if happens (0 = Z_OK) - this.msg = ''; // error message - this.ended = false; // used to avoid multiple onEnd() calls - this.chunks = []; // chunks of compressed data - - this.strm = new zstream$1(); - this.strm.avail_out = 0; - - let status = inflate_1$2$1.inflateInit2( - this.strm, - opt.windowBits - ); - - if (status !== Z_OK$4) { - throw new Error(messages$1[status]); - } - - this.header = new gzheader$1(); - - inflate_1$2$1.inflateGetHeader(this.strm, this.header); - - // Setup dictionary - if (opt.dictionary) { - // Convert data if needed - if (typeof opt.dictionary === 'string') { - opt.dictionary = strings$1.string2buf(opt.dictionary); - } else if (toString$2.call(opt.dictionary) === '[object ArrayBuffer]') { - opt.dictionary = new Uint8Array(opt.dictionary); - } - if (opt.raw) { //In raw mode we need to set the dictionary early - status = inflate_1$2$1.inflateSetDictionary(this.strm, opt.dictionary); - if (status !== Z_OK$4) { - throw new Error(messages$1[status]); - } - } - } -} - -/** - * Inflate#push(data[, flush_mode]) -> Boolean - * - data (Uint8Array|ArrayBuffer): input data - * - flush_mode (Number|Boolean): 0..6 for corresponding Z_NO_FLUSH..Z_TREE - * flush modes. See constants. Skipped or `false` means Z_NO_FLUSH, - * `true` means Z_FINISH. - * - * Sends input data to inflate pipe, generating [[Inflate#onData]] calls with - * new output chunks. Returns `true` on success. If end of stream detected, - * [[Inflate#onEnd]] will be called. - * - * `flush_mode` is not needed for normal operation, because end of stream - * detected automatically. You may try to use it for advanced things, but - * this functionality was not tested. - * - * On fail call [[Inflate#onEnd]] with error code and return false. - * - * ##### Example - * - * ```javascript - * push(chunk, false); // push one of data chunks - * ... - * push(chunk, true); // push last chunk - * ``` - **/ -Inflate$1$1.prototype.push = function (data, flush_mode) { - const strm = this.strm; - const chunkSize = this.options.chunkSize; - const dictionary = this.options.dictionary; - let status, _flush_mode, last_avail_out; - - if (this.ended) return false; - - if (flush_mode === ~~flush_mode) _flush_mode = flush_mode; - else _flush_mode = flush_mode === true ? Z_FINISH$4 : Z_NO_FLUSH$3; - - // Convert data if needed - if (toString$2.call(data) === '[object ArrayBuffer]') { - strm.input = new Uint8Array(data); - } else { - strm.input = data; - } - - strm.next_in = 0; - strm.avail_in = strm.input.length; - - for (;;) { - if (strm.avail_out === 0) { - strm.output = new Uint8Array(chunkSize); - strm.next_out = 0; - strm.avail_out = chunkSize; - } - - status = inflate_1$2$1.inflate(strm, _flush_mode); - - if (status === Z_NEED_DICT$2 && dictionary) { - status = inflate_1$2$1.inflateSetDictionary(strm, dictionary); - - if (status === Z_OK$4) { - status = inflate_1$2$1.inflate(strm, _flush_mode); - } else if (status === Z_DATA_ERROR$3) { - // Replace code with more verbose - status = Z_NEED_DICT$2; - } - } - - // Skip snyc markers if more data follows and not raw mode - while (strm.avail_in > 0 && - status === Z_STREAM_END$4 && - strm.state.wrap > 0 && - data[strm.next_in] !== 0) - { - inflate_1$2$1.inflateReset(strm); - status = inflate_1$2$1.inflate(strm, _flush_mode); - } - - switch (status) { - case Z_STREAM_ERROR$3: - case Z_DATA_ERROR$3: - case Z_NEED_DICT$2: - case Z_MEM_ERROR$2: - this.onEnd(status); - this.ended = true; - return false; - } - - // Remember real `avail_out` value, because we may patch out buffer content - // to align utf8 strings boundaries. - last_avail_out = strm.avail_out; - - if (strm.next_out) { - if (strm.avail_out === 0 || status === Z_STREAM_END$4) { - - if (this.options.to === 'string') { - - let next_out_utf8 = strings$1.utf8border(strm.output, strm.next_out); - - let tail = strm.next_out - next_out_utf8; - let utf8str = strings$1.buf2string(strm.output, next_out_utf8); - - // move tail & realign counters - strm.next_out = tail; - strm.avail_out = chunkSize - tail; - if (tail) strm.output.set(strm.output.subarray(next_out_utf8, next_out_utf8 + tail), 0); - - this.onData(utf8str); - - } else { - this.onData(strm.output.length === strm.next_out ? strm.output : strm.output.subarray(0, strm.next_out)); - } - } - } - - // Must repeat iteration if out buffer is full - if (status === Z_OK$4 && last_avail_out === 0) continue; - - // Finalize if end of stream reached. - if (status === Z_STREAM_END$4) { - status = inflate_1$2$1.inflateEnd(this.strm); - this.onEnd(status); - this.ended = true; - return true; - } - - if (strm.avail_in === 0) break; - } - - return true; -}; - - -/** - * Inflate#onData(chunk) -> Void - * - chunk (Uint8Array|String): output data. When string output requested, - * each chunk will be string. - * - * By default, stores data blocks in `chunks[]` property and glue - * those in `onEnd`. Override this handler, if you need another behaviour. - **/ -Inflate$1$1.prototype.onData = function (chunk) { - this.chunks.push(chunk); -}; - - -/** - * Inflate#onEnd(status) -> Void - * - status (Number): inflate status. 0 (Z_OK) on success, - * other if not. - * - * Called either after you tell inflate that the input stream is - * complete (Z_FINISH). By default - join collected chunks, - * free memory and fill `results` / `err` properties. - **/ -Inflate$1$1.prototype.onEnd = function (status) { - // On success - join - if (status === Z_OK$4) { - if (this.options.to === 'string') { - this.result = this.chunks.join(''); - } else { - this.result = common$1.flattenChunks(this.chunks); - } - } - this.chunks = []; - this.err = status; - this.msg = this.strm.msg; -}; - - -/** - * inflate(data[, options]) -> Uint8Array|String - * - data (Uint8Array|ArrayBuffer): input data to decompress. - * - options (Object): zlib inflate options. - * - * Decompress `data` with inflate/ungzip and `options`. Autodetect - * format via wrapper header by default. That's why we don't provide - * separate `ungzip` method. - * - * Supported options are: - * - * - windowBits - * - * [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced) - * for more information. - * - * Sugar (options): - * - * - `raw` (Boolean) - say that we work with raw stream, if you don't wish to specify - * negative windowBits implicitly. - * - `to` (String) - if equal to 'string', then result will be converted - * from utf8 to utf16 (javascript) string. When string output requested, - * chunk length can differ from `chunkSize`, depending on content. - * - * - * ##### Example: - * - * ```javascript - * const pako = require('pako'); - * const input = pako.deflate(new Uint8Array([1,2,3,4,5,6,7,8,9])); - * let output; - * - * try { - * output = pako.inflate(input); - * } catch (err) { - * console.log(err); - * } - * ``` - **/ -function inflate$1$1(input, options) { - const inflator = new Inflate$1$1(options); - - inflator.push(input); - - // That will never happens, if you don't cheat with options :) - if (inflator.err) throw inflator.msg || messages$1[inflator.err]; - - return inflator.result; -} - - -/** - * inflateRaw(data[, options]) -> Uint8Array|String - * - data (Uint8Array|ArrayBuffer): input data to decompress. - * - options (Object): zlib inflate options. - * - * The same as [[inflate]], but creates raw data, without wrapper - * (header and adler32 crc). - **/ -function inflateRaw$1$1(input, options) { - options = options || {}; - options.raw = true; - return inflate$1$1(input, options); -} - - -/** - * ungzip(data[, options]) -> Uint8Array|String - * - data (Uint8Array|ArrayBuffer): input data to decompress. - * - options (Object): zlib inflate options. - * - * Just shortcut to [[inflate]], because it autodetects format - * by header.content. Done for convenience. - **/ - - -var Inflate_1$1$1 = Inflate$1$1; -var inflate_2$2 = inflate$1$1; -var inflateRaw_1$1$1 = inflateRaw$1$1; -var ungzip$1$1 = inflate$1$1; -var constants$3 = constants$2$1; - -var inflate_1$1$1 = { - Inflate: Inflate_1$1$1, - inflate: inflate_2$2, - inflateRaw: inflateRaw_1$1$1, - ungzip: ungzip$1$1, - constants: constants$3 -}; - -const { Deflate, deflate, deflateRaw, gzip } = deflate_1$1; - -const { Inflate: Inflate$2, inflate: inflate$3, inflateRaw: inflateRaw$2, ungzip: ungzip$2 } = inflate_1$1$1; -var deflateRaw_1 = deflateRaw; -var inflate_1$3 = inflate$3; -var inflateRaw_1 = inflateRaw$2; -var ungzip_1$1 = ungzip$2; - -const FEXTRA = 4; // gzip spec F.EXTRA flag - -function isgzipped(data) { - const b = ArrayBuffer.isView(data) ? data : new Uint8Array(data); - return b[0] ===31 && b[1] === 139; -} - -/** - * Pako does not properly ungzip block compressed files if > 1 block is present. Test for bgzip and use wrapper. - */ -function ungzip_blocks(data) { - const ba = ArrayBuffer.isView(data) ? data : new Uint8Array(data); - const b = ba[3] & FEXTRA; - if (b !== 0 && ba[12] === 66 && ba[13] === 67) { - return unbgzf(ba.buffer); - } else { - return ungzip_1$1(ba); - } -} - -// Uncompress data, assumed to be series of bgzipped blocks -function unbgzf(data, lim) { - - const oBlockList = []; - let ptr = 0; - let totalSize = 0; - - lim = lim || data.byteLength - 18; - - while (ptr < lim) { - try { - const ba = ArrayBuffer.isView(data) ? data : new Uint8Array(data, ptr, 18); - const xlen = (ba[11] << 8) | (ba[10]); - const flg = ba[3]; - const fextra = flg & FEXTRA; - const si1 = ba[12]; - const si2 = ba[13]; - const slen = (ba[15] << 8) | (ba[14]); - const bsize = ((ba[17] << 8) | (ba[16])) + 1; - const start = 12 + xlen + ptr; // Start of CDATA - const bytesLeft = data.byteLength - start; - const cDataSize = bsize - xlen - 19; - if (bytesLeft < cDataSize || cDataSize <= 0) break; - - const a = new Uint8Array(data, start, cDataSize); - const unc = inflateRaw_1(a); - - // const inflate = new Zlib.RawInflate(a); - // const unc = inflate.decompress(); - - ptr += (cDataSize - 1) + 26; //inflate.ip + 26 - totalSize += unc.byteLength; - oBlockList.push(unc); - } catch (e) { - console.error(e); - break; - } - } - - // Concatenate decompressed blocks - if (oBlockList.length === 1) { - return oBlockList[0]; - } else { - const out = new Uint8Array(totalSize); - let cursor = 0; - for (let i = 0; i < oBlockList.length; ++i) { - var b = new Uint8Array(oBlockList[i]); - arrayCopy(b, 0, out, cursor, b.length); - cursor += b.length; - } - return out; - } -} - -function bgzBlockSize$1(data) { - const ba = ArrayBuffer.isView(data) ? data : new Uint8Array(data); - const bsize = (ba[17] << 8 | ba[16]) + 1; - return bsize; -} - -// From Thomas Down's zlib implementation - -const testArray = new Uint8Array(1); -const hasSubarray = (typeof testArray.subarray === 'function'); - -function arrayCopy(src, srcOffset, dest, destOffset, count) { - if (count === 0) { - return; - } - if (!src) { - throw "Undef src"; - } else if (!dest) { - throw "Undef dest"; - } - if (srcOffset === 0 && count === src.length) { - arrayCopy_fast(src, dest, destOffset); - } else if (hasSubarray) { - arrayCopy_fast(src.subarray(srcOffset, srcOffset + count), dest, destOffset); - } else if (src.BYTES_PER_ELEMENT === 1 && count > 100) { - arrayCopy_fast(new Uint8Array(src.buffer, src.byteOffset + srcOffset, count), dest, destOffset); - } else { - arrayCopy_slow(src, srcOffset, dest, destOffset, count); - } -} - -function arrayCopy_slow(src, srcOffset, dest, destOffset, count) { - for (let i = 0; i < count; ++i) { - dest[destOffset + i] = src[srcOffset + i]; - } -} - -function arrayCopy_fast(src, dest, destOffset) { - dest.set(src, destOffset); -} - - -/** - * Compress string and encode in a url safe form - * @param s - */ -function compressString(str) { - - const bytes = new Uint8Array(str.length); - for (var i = 0; i < str.length; i++) { - bytes[i] = str.charCodeAt(i); - } - const compressedBytes = new deflateRaw_1(bytes); // UInt8Arry - const compressedString = String.fromCharCode.apply(null, compressedBytes); // Convert to string - let enc = btoa(compressedString); - return enc.replace(/\+/g, '.').replace(/\//g, '_').replace(/=/g, '-'); // URL safe -} - -/** - * Uncompress the url-safe encoded compressed string, presumably created by compressString above - * - * @param enc - * @returns {string} - */ -function uncompressString(enc) { - - enc = enc.replace(/\./g, '+').replace(/_/g, '/').replace(/-/g, '='); - - const compressedString = atob(enc); - const compressedBytes = []; - for (let i = 0; i < compressedString.length; i++) { - compressedBytes.push(compressedString.charCodeAt(i)); - } - //const bytes = new Zlib.RawInflate(compressedBytes).decompress(); - const bytes = inflateRaw_1(compressedBytes); - - let str = ''; - for (let b of bytes) { - str += String.fromCharCode(b); - } - return str; -} - - -/** - * @param dataURI - * @returns {Array|Uint8Array} - */ -function decodeDataURI$1(dataURI, gzip) { - - const split = dataURI.split(','); - const info = split[0].split(':')[1]; - let dataString = split[1]; - - if (info.indexOf('base64') >= 0) { - dataString = atob(dataString); - - const bytes = new Uint8Array(dataString.length); - for (let i = 0; i < dataString.length; i++) { - bytes[i] = dataString.charCodeAt(i); - } - - let plain; - if (gzip || info.indexOf('gzip') > 0) { - plain = ungzip_1$1(bytes); - } else { - plain = bytes; - } - return plain - } else { - return decodeURIComponent(dataString); // URL encoded string -- not currently used or tested - } -} - -/* - * The MIT License (MIT) - * - * Copyright (c) 2016-2017 The Regents of the University of California - * Author: Jim Robinson - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -const IGVMath = { - - lerp: (v0, v1, t) => { - return (1 - t) * v0 + t * v1; - }, - - mean: function (array) { - - var t = 0, n = 0, - i; - for (i = 0; i < array.length; i++) { - if (!isNaN(array[i])) { - t += array[i]; - n++; - } - } - return n > 0 ? t / n : 0; - }, - - meanAndStdev: function (array) { - - var v, t = 0, t2 = 0, n = 0, i; - - for (i = 0; i < array.length; i++) { - - v = array[i]; - - if (!isNaN(v)) { - t += v; - t2 += v * v; - n++; - } - } - return n > 0 ? {mean: t / n, stdev: Math.sqrt(t2 - t * t / n)} : {mean: 0, stdev: 0}; - }, - - median: function (numbers) { - // median of [3, 5, 4, 4, 1, 1, 2, 3] = 3 - var median = 0, numsLen = numbers.length; - numbers.sort(); - - if ( - numsLen % 2 === 0 // is even - ) { - // average of two middle numbers - median = (numbers[numsLen / 2 - 1] + numbers[numsLen / 2]) / 2; - } else { // is odd - // middle number only - median = numbers[(numsLen - 1) / 2]; - } - - return median; - }, - - // Fast percentile function for "p" near edges. This needs profiled for p in middle (e.g. median) - percentile: function (array, p) { - - if (array.length === 0) return undefined; - - var k = Math.floor(array.length * ((100 - p) / 100)); - if (k === 0) { - array.sort(function (a, b) { - return b - a - }); - return array[k]; - } else { - return selectElement(array, k); - } - - }, - - - clamp: function (value, min, max) { - return Math.min(Math.max(value, min), max); - }, - - log2: function (x) { - return Math.log(x) / Math.LN2; - } - -}; - -function selectElement(array, k) { - - // Credit Steve Hanov http://stevehanov.ca/blog/index.php?id=122 - var heap = new BinaryHeap(), - i; - - for (i = 0; i < array.length; i++) { - - var item = array[i]; - - // If we have not yet found k items, or the current item is larger than - // the smallest item on the heap, add current item - if (heap.content.length < k || item > heap.content[0]) { - // If the heap is full, remove the smallest element on the heap. - if (heap.content.length === k) { - heap.pop(); - } - heap.push(item); - } - } - - return heap.content[0]; -} - - -function BinaryHeap() { - this.content = []; -} - -BinaryHeap.prototype = { - push: function (element) { - // Add the new element to the end of the array. - this.content.push(element); - // Allow it to bubble up. - this.bubbleUp(this.content.length - 1); - }, - - pop: function () { - // Store the first element so we can return it later. - var result = this.content[0]; - // Get the element at the end of the array. - var end = this.content.pop(); - // If there are any elements left, put the end element at the - // start, and let it sink down. - if (this.content.length > 0) { - this.content[0] = end; - this.sinkDown(0); - } - return result; - }, - - remove: function (node) { - var length = this.content.length; - // To remove a value, we must search through the array to find - // it. - for (var i = 0; i < length; i++) { - if (this.content[i] !== node) continue; - // When it is found, the process seen in 'pop' is repeated - // to fill up the hole. - var end = this.content.pop(); - // If the element we popped was the one we needed to remove, - // we're done. - if (i === length - 1) break; - // Otherwise, we replace the removed element with the popped - // one, and allow it to float up or sink down as appropriate. - this.content[i] = end; - this.bubbleUp(i); - this.sinkDown(i); - break; - } - }, - - size: function () { - return this.content.length; - }, - - bubbleUp: function (n) { - // Fetch the element that has to be moved. - var element = this.content[n], score = element; - // When at 0, an element can not go up any further. - while (n > 0) { - // Compute the parent element's index, and fetch it. - var parentN = Math.floor((n + 1) / 2) - 1, - parent = this.content[parentN]; - // If the parent has a lesser score, things are in order and we - // are done. - if (score >= parent) - break; - - // Otherwise, swap the parent with the current element and - // continue. - this.content[parentN] = element; - this.content[n] = parent; - n = parentN; - } - }, - - sinkDown: function (n) { - // Look up the target element and its score. - var length = this.content.length, - element = this.content[n], - elemScore = element; - - while (true) { - // Compute the indices of the child elements. - var child2N = (n + 1) * 2, child1N = child2N - 1; - // This is used to store the new position of the element, - // if any. - var swap = null; - // If the first child exists (is inside the array)... - if (child1N < length) { - // Look it up and compute its score. - var child1 = this.content[child1N], - child1Score = child1; - // If the score is less than our element's, we need to swap. - if (child1Score < elemScore) - swap = child1N; - } - // Do the same checks for the other child. - if (child2N < length) { - var child2 = this.content[child2N], - child2Score = child2; - if (child2Score < (swap == null ? elemScore : child1Score)) - swap = child2N; - } - - // No need to swap further, we are done. - if (swap == null) break; - - // Otherwise, swap and continue. - this.content[n] = this.content[swap]; - this.content[swap] = element; - n = swap; - } - } -}; - -/* - * The MIT License (MIT) - * - * Copyright (c) 2014 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -function _random(min, max) { - return Math.random() * (max - min) + min -} - -const IGVColor = { - - rgbListFromHSV: () => { - - let s = 1; - let accumulation = []; - for (let v = 1; v >= 0.5; v -= .1) { - for (let h = 0; h < 1; h += 1 / 28) { - const r = "rgb(" + IGVColor.hsvToRgb(h, s, v).join(",") + ")"; - accumulation.push(r); - } - } - - // add black - accumulation.pop(); - accumulation.push(IGVColor.rgbColor(16, 16, 16)); - - return accumulation - }, - - rgbToHex: function (rgb) { - rgb = rgb.match(/^rgba?[\s+]?\([\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?/i); - return (rgb && rgb.length === 4) ? "#" + - ("0" + parseInt(rgb[1], 10).toString(16)).slice(-2) + - ("0" + parseInt(rgb[2], 10).toString(16)).slice(-2) + - ("0" + parseInt(rgb[3], 10).toString(16)).slice(-2) : '' - }, - - hexToRgb: function (hex) { - - var cooked = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex); - - if (null === cooked) { - return undefined - } - - return "rgb(" + parseInt(cooked[1], 16) + "," + parseInt(cooked[2], 16) + "," + parseInt(cooked[3], 16) + ")" - }, - - /** - * Converts an HSV color value to RGB. Conversion formula - * adapted from http://en.wikipedia.org/wiki/HSV_color_space. - * Assumes h, s, and v are contained in the set [0, 1] and - * returns r, g, and b in the set [0, 255]. - * - * Credit: https://gist.githubusercontent.com/mjackson/5311256 - * - * @param h The hue - * @param s The saturation - * @param v The value - * @return Array The RGB representation - */ - hsvToRgb: function (h, s, v) { - var r, g, b; - - var i = Math.floor(h * 6); - var f = h * 6 - i; - var p = v * (1 - s); - var q = v * (1 - f * s); - var t = v * (1 - (1 - f) * s); - - switch (i % 6) { - case 0: - r = v, g = t, b = p; - break - case 1: - r = q, g = v, b = p; - break - case 2: - r = p, g = v, b = t; - break - case 3: - r = p, g = q, b = v; - break - case 4: - r = t, g = p, b = v; - break - case 5: - r = v, g = p, b = q; - break - } - - return [Math.floor(r * 255), Math.floor(g * 255), Math.floor(b * 255)] - }, - - /** - * Converts an HSL color value to RGB. Conversion formula - * adapted from http://en.wikipedia.org/wiki/HSL_color_space. - * Assumes h, s, and l are contained in the set [0, 1] and - * returns r, g, and b in the set [0, 255]. - * - * Credit: https://gist.githubusercontent.com/mjackson/5311256 - * - * @param h The hue - * @param s The saturation - * @param l The lightness - * @return Array The RGB representation - */ - hslToRgb: function (h, s, l) { - var r, g, b; - - if (s === 0) { - r = g = b = l; // achromatic - } else { - - - var q = l < 0.5 ? l * (1 + s) : l + s - l * s; - var p = 2 * l - q; - - r = IGVColor.hue2rgb(p, q, h + 1 / 3); - g = IGVColor.hue2rgb(p, q, h); - b = IGVColor.hue2rgb(p, q, h - 1 / 3); - } - - return [r * 255, g * 255, b * 255] - }, - - hue2rgb: (p, q, t) => { - if (t < 0) t += 1; - if (t > 1) t -= 1; - if (t < 1 / 6) return p + (q - p) * 6 * t - if (t < 1 / 2) return q - if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6 - return p - }, - - rgbaColor: function (r, g, b, a) { - - r = IGVMath.clamp(r, 0, 255); - g = IGVMath.clamp(g, 0, 255); - b = IGVMath.clamp(b, 0, 255); - a = IGVMath.clamp(a, 0.0, 1.0); - - return "rgba(" + r + "," + g + "," + b + "," + a + ")" - }, - - rgbColor: function (r, g, b) { - - r = IGVMath.clamp(r, 0, 255); - g = IGVMath.clamp(g, 0, 255); - b = IGVMath.clamp(b, 0, 255); - - return "rgb(" + r + "," + g + "," + b + ")" - }, - - greyScale: function (value) { - - var grey = IGVMath.clamp(value, 0, 255); - - return "rgb(" + grey + "," + grey + "," + grey + ")" - }, - - randomGrey: function (min, max) { - - min = IGVMath.clamp(min, 0, 255); - max = IGVMath.clamp(max, 0, 255); - - var g = Math.round(_random(min, max)).toString(10); - - return "rgb(" + g + "," + g + "," + g + ")" - }, - - randomRGB: function (min, max) { - - min = IGVMath.clamp(min, 0, 255); - max = IGVMath.clamp(max, 0, 255); - - var r = Math.round(_random(min, max)).toString(10); - var g = Math.round(_random(min, max)).toString(10); - var b = Math.round(_random(min, max)).toString(10); - - return "rgb(" + r + "," + g + "," + b + ")" - }, - - randomRGBConstantAlpha: function (min, max, alpha) { - - min = IGVMath.clamp(min, 0, 255); - max = IGVMath.clamp(max, 0, 255); - - var r = Math.round(_random(min, max)).toString(10); - var g = Math.round(_random(min, max)).toString(10); - var b = Math.round(_random(min, max)).toString(10); - - return "rgba(" + r + "," + g + "," + b + "," + alpha + ")" - }, - - addAlpha: function (color, alpha) { - - if (color === "0" || color === ".") { - color = "rgb(0,0,0)"; - } else { - const c = this.colorNameToHex(color); - if (c) { - color = c; - } - } - - var isHex = /(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(color); - - if (color.startsWith("rgba")) { - const idx = color.lastIndexOf(","); - return color.substring(0, idx + 1) + alpha.toString() + ")" - } - - if (isHex) { - color = IGVColor.hexToRgb(color); - } - - if (color.startsWith("rgb")) { - return color.replace("rgb", "rgba").replace(")", ", " + alpha + ")") - } else { - console.log(color + " is not an rgb style string"); - return color - } - }, - - rgbComponents: function (color) { - - if (color === "0" || color === ".") { - return [0, 0, 0] - } - const isHex = /(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(color); - if (isHex) { - color = IGVColor.hexToRgb(color); - } else { - if (!color.startsWith("rgb")) { - const hex = this.colorNameToHex(color); - color = this.hexToRgb(hex); - } - } - - if (color.startsWith("rgb(")) { - return color.substring(4, color.length - 1).split(",").map(s => Number.parseInt(s.trim())) - } else if (color.startsWith("rgba(")) { - return color.substring(5, color.length - 1).split(",").map((s, i) => { - s = s.trim(); - return i === 3 ? Number.parseFloat(s) : Number.parseInt(s) - }) - } else { - throw Error("Unrecognized color string: color") - } - }, - - /** - * - * @param dest RGB components as an array - * @param src RGB components as an array - * @param alpha alpha transparancy in the range 0-1 - * @returns {} - */ - getCompositeColor: function (dest, src, alpha) { - - var r = Math.floor(alpha * src[0] + (1 - alpha) * dest[0]), - g = Math.floor(alpha * src[1] + (1 - alpha) * dest[1]), - b = Math.floor(alpha * src[2] + (1 - alpha) * dest[2]); - - return "rgb(" + r + "," + g + "," + b + ")" - - }, - - /** - * Return a color represented by the string. If the string is not a recognized color format return the - * string itself. This function exists for backward compatibility, createColorStringSafe is preferredz - * @param str - */ - createColorString: function (str) { - // Excel will quote color strings, strip all quotes - const color = this.createColorStringSafe(str); - return color ? color : str - }, - - /** - * If str is a recognized color format return a string encoding the color - * @param str - */ - createColorStringSafe: function (str) { - // Excel will quote color strings, strip all quotes - str = stripQuotes$1(str); - - if (str.startsWith('rgb(') && str.endsWith(')')) { - return str - } - if (str.startsWith('#') && str.length < 8) { - return str - } - - // See if string is a recognized web color - const hex = this.colorNameToHex(str); - if (hex) { - return hex - } - - // UCSC format (e.g. 0,0,255) - const tokens = str.split(","); - if (tokens.length === 3 && isColorComponent(tokens[0]) && isColorComponent(tokens[1]) && isColorComponent(tokens[2])) { - return `rgb(${str})` - } - }, - - darkenLighten: function (color, amt) { - - let src; - let hexColor = this.colorNameToHex(color); - if (hexColor) { - src = IGVColor.hexToRgb(hexColor); - } else { - src = color.startsWith('rgb(') ? color : IGVColor.hexToRgb(color); - } - - const components = src.replace(")", "").substring(4).split(","); - - const r = Math.max(0, Math.min(255, Number.parseInt(components[0].trim()) + amt)); - const g = Math.max(0, Math.min(255, Number.parseInt(components[1].trim()) + amt)); - const b = Math.max(0, Math.min(255, Number.parseInt(components[2].trim()) + amt)); - - return 'rgb(' + r.toString() + ',' + g.toString() + ',' + b.toString() + ')' - - }, - - /** - * Convert html/css color name to hex value. Adapted from https://gist.github.com/mxfh/4719348 - * @param colorName - * @returns {*} - */ - colorNameToHex: function (colorName) { // color list from http://stackoverflow.com/q/1573053/731179 with added gray/gray - const definedColorNames = { - "aliceblue": "#f0f8ff", - "antiquewhite": "#faebd7", - "aqua": "#00ffff", - "aquamarine": "#7fffd4", - "azure": "#f0ffff", - "beige": "#f5f5dc", - "bisque": "#ffe4c4", - "black": "#000000", - "blanchedalmond": "#ffebcd", - "blue": "#0000ff", - "blueviolet": "#8a2be2", - "brown": "#a52a2a", - "burlywood": "#deb887", - "cadetblue": "#5f9ea0", - "chartreuse": "#7fff00", - "chocolate": "#d2691e", - "coral": "#ff7f50", - "cornflowerblue": "#6495ed", - "cornsilk": "#fff8dc", - "crimson": "#dc143c", - "cyan": "#00ffff", - "darkblue": "#00008b", - "darkcyan": "#008b8b", - "darkgoldenrod": "#b8860b", - "darkgray": "#a9a9a9", - "darkgreen": "#006400", - "darkkhaki": "#bdb76b", - "darkmagenta": "#8b008b", - "darkolivegreen": "#556b2f", - "darkorange": "#ff8c00", - "darkorchid": "#9932cc", - "darkred": "#8b0000", - "darksalmon": "#e9967a", - "darkseagreen": "#8fbc8f", - "darkslateblue": "#483d8b", - "darkslategray": "#2f4f4f", - "darkturquoise": "#00ced1", - "darkviolet": "#9400d3", - "deeppink": "#ff1493", - "deepskyblue": "#00bfff", - "dimgray": "#696969", - "dodgerblue": "#1e90ff", - "firebrick": "#b22222", - "floralwhite": "#fffaf0", - "forestgreen": "#228b22", - "fuchsia": "#ff00ff", - "gainsboro": "#dcdcdc", - "ghostwhite": "#f8f8ff", - "gold": "#ffd700", - "goldenrod": "#daa520", - "gray": "#808080", - "green": "#008000", - "greenyellow": "#adff2f", - "honeydew": "#f0fff0", - "hotpink": "#ff69b4", - "indianred ": "#cd5c5c", - "indigo ": "#4b0082", - "ivory": "#fffff0", - "khaki": "#f0e68c", - "lavender": "#e6e6fa", - "lavenderblush": "#fff0f5", - "lawngreen": "#7cfc00", - "lemonchiffon": "#fffacd", - "lightblue": "#add8e6", - "lightcoral": "#f08080", - "lightcyan": "#e0ffff", - "lightgoldenrodyellow": "#fafad2", - "lightgrey": "#d3d3d3", - "lightgreen": "#90ee90", - "lightpink": "#ffb6c1", - "lightsalmon": "#ffa07a", - "lightseagreen": "#20b2aa", - "lightskyblue": "#87cefa", - "lightslategray": "#778899", - "lightsteelblue": "#b0c4de", - "lightyellow": "#ffffe0", - "lime": "#00ff00", - "limegreen": "#32cd32", - "linen": "#faf0e6", - "magenta": "#ff00ff", - "maroon": "#800000", - "mediumaquamarine": "#66cdaa", - "mediumblue": "#0000cd", - "mediumorchid": "#ba55d3", - "mediumpurple": "#9370d8", - "mediumseagreen": "#3cb371", - "mediumslateblue": "#7b68ee", - "mediumspringgreen": "#00fa9a", - "mediumturquoise": "#48d1cc", - "mediumvioletred": "#c71585", - "midnightblue": "#191970", - "mintcream": "#f5fffa", - "mistyrose": "#ffe4e1", - "moccasin": "#ffe4b5", - "navajowhite": "#ffdead", - "navy": "#000080", - "oldlace": "#fdf5e6", - "olive": "#808000", - "olivedrab": "#6b8e23", - "orange": "#ffa500", - "orangered": "#ff4500", - "orchid": "#da70d6", - "palegoldenrod": "#eee8aa", - "palegreen": "#98fb98", - "paleturquoise": "#afeeee", - "palevioletred": "#d87093", - "papayawhip": "#ffefd5", - "peachpuff": "#ffdab9", - "peru": "#cd853f", - "pink": "#ffc0cb", - "plum": "#dda0dd", - "powderblue": "#b0e0e6", - "purple": "#800080", - "red": "#ff0000", - "rosybrown": "#bc8f8f", - "royalblue": "#4169e1", - "saddlebrown": "#8b4513", - "salmon": "#fa8072", - "sandybrown": "#f4a460", - "seagreen": "#2e8b57", - "seashell": "#fff5ee", - "sienna": "#a0522d", - "silver": "#c0c0c0", - "skyblue": "#87ceeb", - "slateblue": "#6a5acd", - "slategray": "#708090", - "snow": "#fffafa", - "springgreen": "#00ff7f", - "steelblue": "#4682b4", - "tan": "#d2b48c", - "teal": "#008080", - "thistle": "#d8bfd8", - "tomato": "#ff6347", - "turquoise": "#40e0d0", - "violet": "#ee82ee", - "wheat": "#f5deb3", - "white": "#ffffff", - "whitesmoke": "#f5f5f5", - "yellow": "#ffff00", - "yellowgreen": "#9acd32", - "darkgrey": "#a9a9a9", - "darkslategrey": "#2f4f4f", - "dimgrey": "#696969", - "grey": "#808080", - "lightgray": "#d3d3d3", - "lightslategrey": "#778899", - "slategrey": "#708090" - }; - return definedColorNames[colorName] - } -}; - -function isColorComponent(str) { - const num = Number.parseInt(str); - return !Number.isNaN(num) && num >= 0 && num <= 255 -} - -// Support for oauth token based authorization -// This class supports explicit setting of an oauth token either globally or for specific hosts. -// -// The variable oauth.google.access_token, which becomes igv.oauth.google.access_token on ES5 conversion is -// supported for backward compatibility - -const DEFAULT_HOST = "googleapis"; - -class Oauth { - - constructor() { - this.oauthTokens = {}; - } - - - setToken(token, host) { - host = host || DEFAULT_HOST; - this.oauthTokens[host] = token; - } - - getToken(host) { - host = host || DEFAULT_HOST; - let token; - for (let key of Object.keys(this.oauthTokens)) { - const regex = wildcardToRegExp(key); - if (regex.test(host)) { - token = this.oauthTokens[key]; - break - } - } - return token - } - - removeToken(host) { - host = host || DEFAULT_HOST; - for (let key of Object.keys(this.oauthTokens)) { - const regex = wildcardToRegExp(key); - if (regex.test(host)) { - this.oauthTokens[key] = undefined; - } - } - } - - // Special object for google -- legacy support - // google: { - // setToken: function (token) { - // oauth.setToken(token); - // } - // } -} - - -/** - * Creates a RegExp from the given string, converting asterisks to .* expressions, - * and escaping all other characters. - * - * credit https://gist.github.com/donmccurdy/6d073ce2c6f3951312dfa45da14a420f - */ -function wildcardToRegExp(s) { - return new RegExp('^' + s.split(/\*+/).map(regExpEscape).join('.*') + '$') -} - -/** - * RegExp-escapes all characters in the given string. - * - * credit https://gist.github.com/donmccurdy/6d073ce2c6f3951312dfa45da14a420f - */ -function regExpEscape(s) { - return s.replace(/[|\\{}()[\]^$+*?.]/g, '\\$&') -} - -function isGoogleURL$1(url) { - return (url.includes("googleapis") && !url.includes("urlshortener")) || - isGoogleStorageURL$1(url) || - isGoogleDriveURL$1(url) -} - -function isGoogleStorageURL$1(url) { - return url.startsWith("gs://") || - url.startsWith("https://www.googleapis.com/storage") || - url.startsWith("https://storage.cloud.google.com") || - url.startsWith("https://storage.googleapis.com"); -} - -function isGoogleDriveURL$1(url) { - return url.indexOf("drive.google.com") >= 0 || url.indexOf("www.googleapis.com/drive") > 0 -} - -/** - * Translate gs:// urls to https - * See https://cloud.google.com/storage/docs/json_api/v1 - * @param gsUrl - * @returns {string|*} - */ -function translateGoogleCloudURL(gsUrl) { - - let {bucket, object} = parseBucketName(gsUrl); - object = encode(object); - - const qIdx = gsUrl.indexOf('?'); - const paramString = (qIdx > 0) ? gsUrl.substring(qIdx) + "&alt=media" : "?alt=media"; - - return `https://storage.googleapis.com/storage/v1/b/${bucket}/o/${object}${paramString}` -} - -/** - * Parse a google bucket and object name from a google storage URL. Known forms include - * - * gs://BUCKET_NAME/OBJECT_NAME - * https://storage.googleapis.com/BUCKET_NAME/OBJECT_NAME - * https://storage.googleapis.com/storage/v1/b/BUCKET_NAME/o/OBJECT_NAME - * https://www.googleapis.com/storage/v1/b/BUCKET_NAME/o/OBJECT_NAME" - * https://storage.googleapis.com/download/storage/v1/b/BUCKET_NAME/o/OBJECT_NAME - * - * @param url - */ -function parseBucketName(url) { - - let bucket; - let object; - - if (url.startsWith("gs://")) { - const i = url.indexOf('/', 5); - if (i >= 0) { - bucket = url.substring(5, i); - const qIdx = url.indexOf('?'); - object = (qIdx < 0) ? url.substring(i + 1) : url.substring(i + 1, qIdx); - } - - } else if (url.startsWith("https://storage.googleapis.com") || url.startsWith("https://storage.cloud.google.com")) { - const bucketIdx = url.indexOf("/v1/b/", 8); - if (bucketIdx > 0) { - const objIdx = url.indexOf("/o/", bucketIdx); - if (objIdx > 0) { - const queryIdx = url.indexOf("?", objIdx); - bucket = url.substring(bucketIdx + 6, objIdx); - object = queryIdx > 0 ? url.substring(objIdx + 3, queryIdx) : url.substring(objIdx + 3); - } - - } else { - const idx1 = url.indexOf("/", 8); - const idx2 = url.indexOf("/", idx1+1); - const idx3 = url.indexOf("?", idx2); - if (idx2 > 0) { - bucket = url.substring(idx1+1, idx2); - object = idx3 < 0 ? url.substring(idx2+1) : url.substring(idx2+1, idx3); - } - } - - } else if (url.startsWith("https://www.googleapis.com/storage/v1/b")) { - const bucketIdx = url.indexOf("/v1/b/", 8); - const objIdx = url.indexOf("/o/", bucketIdx); - if (objIdx > 0) { - const queryIdx = url.indexOf("?", objIdx); - bucket = url.substring(bucketIdx + 6, objIdx); - object = queryIdx > 0 ? url.substring(objIdx + 3, queryIdx) : url.substring(objIdx + 3); - } - } - - if (bucket && object) { - return { - bucket, object - } - } else { - throw Error(`Unrecognized Google Storage URI: ${url}`) - } - -} - -/** - * Percent a GCS object name. See https://cloud.google.com/storage/docs/request-endpoints - * Specific characters to encode: - * !, #, $, &, ', (, ), *, +, ,, /, :, ;, =, ?, @, [, ], and space characters. - * @param obj - */ - -function encode(objectName) { - - let result = ''; - objectName.split('').forEach(function(letter) { - if(encodings$1.has(letter)) { - result += encodings$1.get(letter); - } else { - result += letter; - } - }); - return result; -} - -// %23 %24 %25 %26 %27 %28 %29 %2A %2B %2C %2F %3A %3B %3D %3F %40 %5B %5D -const encodings$1 = new Map(); -encodings$1.set("!", "%21"); -encodings$1.set("#", "%23"); -encodings$1.set("$", "%24"); -encodings$1.set("%", "%25"); -encodings$1.set("&", "%26"); -encodings$1.set("'", "%27"); -encodings$1.set("(", "%28"); -encodings$1.set(")", "%29"); -encodings$1.set("*", "%2A"); -encodings$1.set("+", "%2B"); -encodings$1.set(",", "%2C"); -encodings$1.set("/", "%2F"); -encodings$1.set(":", "%3A"); -encodings$1.set(";", "%3B"); -encodings$1.set("=", "%3D"); -encodings$1.set("?", "%3F"); -encodings$1.set("@", "%40"); -encodings$1.set("[", "%5B"); -encodings$1.set("]", "%5D"); -encodings$1.set(" ", "%20"); - -// Convenience functions for the gapi oAuth library. - -async function init$1$1(config) { - - if (!(google.accounts.oauth2.initTokenClient)) { - throw new Error("Google accounts token client not loaded (https://accounts.google.com/gsi/client)") - } - - if (isInitialized()) { - throw new Error("Google client is already initialized") - } - - // Note: callback is added when accessToken is requested - const codeClientConfig = { - client_id: config.client_id || config.clientId, - scope: config.scope || 'https://www.googleapis.com/auth/userinfo.profile', - state: config.state || 'igv', - error: (err) => { - throw new Error(err.type) - }, - hint: config.hint, // Optional - hosted_domain: config.hosted_domain // Optional - }; - - const tokenClient = google.accounts.oauth2.initTokenClient(codeClientConfig); - - // Attach an object to keep igv state - google.igv = { - tokenClient: tokenClient, - apiKey: config.apiKey - }; -} - -function isInitialized() { - return window.google && window.google.igv -} - -/** - * Return the current access token if the user is signed in, or undefined otherwise. This function does not - * attempt a signIn or request any specfic scopes. - * - * @returns access_token || undefined - */ -function getCurrentAccessToken() { - return (isInitialized() && google.igv.tokenResponse && Date.now() < google.igv.tokenExpiresAt) ? - google.igv.tokenResponse.access_token : - undefined -} - - -/** - * Return a promise for an access token for the given scope. If the user hasn't authorized the scope request it - * - * @param scope - * @returns {Promise} - */ -async function getAccessToken(scope) { - - if (!isInitialized()) { - throw Error("Google oAuth has not been initialized") - } - - if (google.igv.tokenResponse && - Date.now() < google.igv.tokenExpiresAt && - google.accounts.oauth2.hasGrantedAllScopes(google.igv.tokenResponse, scope)) { - return google.igv.tokenResponse.access_token - } else { - const tokenClient = google.igv.tokenClient; - return new Promise((resolve, reject) => { - try { - // Settle this promise in the response callback for requestAccessToken() - tokenClient.callback = (tokenResponse) => { - if (tokenResponse.error !== undefined) { - reject(tokenResponse); - } - google.igv.tokenResponse = tokenResponse; - google.igv.tokenExpiresAt = Date.now() + tokenResponse.expires_in * 1000; - resolve(tokenResponse.access_token); - }; - tokenClient.requestAccessToken({scope}); - } catch (err) { - console.log(err); - } - }) - } -} - -// gapi.auth2.getAuthInstance().isSignedIn.listen(status => { -// const user = gapi.auth2.getAuthInstance().currentUser.get() -// queryGoogleAuthenticationStatus(user, status) -// }) - -function getScopeForURL(url) { - if (isGoogleDriveURL$1(url)) { - return "https://www.googleapis.com/auth/drive.file" - } else if (isGoogleStorageURL$1(url)) { - return "https://www.googleapis.com/auth/devstorage.read_only" - } else { - return 'https://www.googleapis.com/auth/userinfo.profile' - } -} - -function getApiKey() { - return google.igv.apiKey -} - -/** - * Return information about a specific google drive URL - * - * @param googleDriveURL - * @returns {Promise} - */ -async function getDriveFileInfo(googleDriveURL) { - - const id = getGoogleDriveFileID$1(googleDriveURL); - let endPoint = "https://www.googleapis.com/drive/v3/files/" + id + "?supportsTeamDrives=true"; - const apiKey = getApiKey(); - if (apiKey) { - endPoint += "&key=" + apiKey; - } - const response = await fetch(endPoint); - let json = await response.json(); - if (json.error && json.error.code === 404) { - let scope = "https://www.googleapis.com/auth/drive.readonly"; - const access_token = await getAccessToken(scope); - if (access_token) { - const response = await fetch(endPoint, { - headers: { - 'Authorization': `Bearer ${access_token}` - } - }); - json = await response.json(); - if (json.error) { - throw Error(json.error); - } - } else { - throw Error(json.error); - } - } - return json; -} - - -function getDriveDownloadURL$1(link) { - // Return a google drive download url for the sharable link - //https://drive.google.com/open?id=0B-lleX9c2pZFbDJ4VVRxakJzVGM - //https://drive.google.com/file/d/1_FC4kCeO8E3V4dJ1yIW7A0sn1yURKIX-/view?usp=sharing - var id = getGoogleDriveFileID$1(link); - return id ? "https://www.googleapis.com/drive/v3/files/" + id + "?alt=media&supportsTeamDrives=true" : link; -} - -function getGoogleDriveFileID$1(link) { - - //https://drive.google.com/file/d/1_FC4kCeO8E3V4dJ1yIW7A0sn1yURKIX-/view?usp=sharing - //https://www.googleapis.com/drive/v3/files/1w-tvo6p1SH4p1OaQSVxpkV_EJgGIstWF?alt=media&supportsTeamDrives=true" - - if (link.includes("/open?id=")) { - const i1 = link.indexOf("/open?id=") + 9; - const i2 = link.indexOf("&"); - if (i1 > 0 && i2 > i1) { - return link.substring(i1, i2) - } else if (i1 > 0) { - return link.substring(i1); - } - - } else if (link.includes("/file/d/")) { - const i1 = link.indexOf("/file/d/") + 8; - const i2 = link.lastIndexOf("/"); - return link.substring(i1, i2); - - } else if (link.startsWith("https://www.googleapis.com/drive")) { - let i1 = link.indexOf("/files/"); - const i2 = link.indexOf("?"); - if (i1 > 0) { - i1 += 7; - return i2 > 0 ? - link.substring(i1, i2) : - link.substring(i1) - } - } - - throw Error("Unknown Google Drive url format: " + link); - - -} - -// The MIT License (MIT) - -/** - * @constructor - * @param {Object} options A set op options to pass to the throttle function - * @param {number} requestsPerSecond The amount of requests per second - * the library will limit to - */ -class Throttle { - constructor(options) { - this.requestsPerSecond = options.requestsPerSecond || 10; - this.lastStartTime = 0; - this.queued = []; - } - - /** - * Adds a promise - * @param {Function} async function to be executed - * @param {Object} options A set of options. - * @return {Promise} A promise - */ - add(asyncFunction, options) { - - var self = this; - return new Promise(function (resolve, reject) { - self.queued.push({ - resolve: resolve, - reject: reject, - asyncFunction: asyncFunction, - }); - self.dequeue(); - }); - } - - /** - * Adds all the promises passed as parameters - * @param {Function} promises An array of functions that return a promise - * @param {Object} options A set of options. - * @param {number} options.signal An AbortSignal object that can be used to abort the returned promise - * @param {number} options.weight A "weight" of each operation resolving by array of promises - * @return {Promise} A promise that succeeds when all the promises passed as options do - */ - addAll(promises, options) { - var addedPromises = promises.map(function (promise) { - return this.add(promise, options); - }.bind(this)); - - return Promise.all(addedPromises); - }; - - /** - * Dequeues a promise - * @return {void} - */ - dequeue() { - if (this.queued.length > 0) { - var now = new Date(), - inc = (1000 / this.requestsPerSecond) + 1, - elapsed = now - this.lastStartTime; - - if (elapsed >= inc) { - this._execute(); - } else { - // we have reached the limit, schedule a dequeue operation - setTimeout(function () { - this.dequeue(); - }.bind(this), inc - elapsed); - } - } - } - - /** - * Executes the promise - * @private - * @return {void} - */ - async _execute() { - this.lastStartTime = new Date(); - var candidate = this.queued.shift(); - const f = candidate.asyncFunction; - try { - const r = await f(); - candidate.resolve(r); - } catch (e) { - candidate.reject(e); - } - - } - - -} - -/* - * The MIT License (MIT) - * - * Copyright (c) 2014 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -class IGVXhr { - - constructor() { - this.apiKey = undefined; - this.googleThrottle = new Throttle({ - requestsPerSecond: 8 - }); - this.RANGE_WARNING_GIVEN = false; - this.oauth = new Oauth(); - } - - setApiKey(key) { - this.apiKey = key; - } - - async loadArrayBuffer(url, options) { - options = options || {}; - if (!options.responseType) { - options.responseType = "arraybuffer"; - } - if (isFile$1(url)) { - return this._loadFileSlice(url, options) - } else { - return this.load(url, options) - } - } - - /** - * A wrapper around loadArrayBuffer that inflates gzipped data - * @param url - * @param options - * @returns {Promise} - */ - async loadByteArray(url, options) { - const arraybuffer = await this.loadArrayBuffer(url, options); - let plain; - if (isgzipped(arraybuffer)) { - plain = ungzip_blocks(arraybuffer); - } else { - plain = new Uint8Array(arraybuffer); - } - return plain - } - - - async loadJson(url, options) { - options = options || {}; - const method = options.method || (options.sendData ? "POST" : "GET"); - if (method === "POST") { - options.contentType = "application/json"; - } - const result = await this.loadString(url, options); - if (result) { - return JSON.parse(result) - } else { - return result - } - } - - async loadString(path, options) { - options = options || {}; - if (path instanceof File) { - return this._loadStringFromFile(path, options) - } else { - return this._loadStringFromUrl(path, options) - } - } - - async load(url, options) { - - options = options || {}; - const urlType = typeof url; - - // Resolve functions, promises, and functions that return promises - url = await (typeof url === 'function' ? url() : url); - - if (isFile$1(url)) { - return this._loadFileSlice(url, options) - } else if (typeof url.startsWith === 'function') { // Test for string - if (url.startsWith("data:")) { - const buffer = decodeDataURI$1(url).buffer; - if (options.range) { - const rangeEnd = options.range.size ? options.range.start + options.range.size : buffer.byteLength; - return buffer.slice(options.range.start, rangeEnd) - } else { - return buffer - } - } else { - if (url.startsWith("https://drive.google.com")) { - url = getDriveDownloadURL$1(url); - } - if (isGoogleDriveURL$1(url) || url.startsWith("https://www.dropbox.com")) { - return this.googleThrottle.add(async () => { - return this._loadURL(url, options) - }) - } else { - return this._loadURL(url, options) - } - } - } else { - throw Error(`url must be either a 'File', 'string', 'function', or 'Promise'. Actual type: ${urlType}`) - } - } - - async _loadURL(url, options) { - - const self = this; - const _url = url; // The unmodified URL, needed in case of an oAuth retry - - url = mapUrl$1(url); - - options = options || {}; - - let oauthToken = options.oauthToken || this.getOauthToken(url); - if (oauthToken) { - oauthToken = await (typeof oauthToken === 'function' ? oauthToken() : oauthToken); - } - - return new Promise(function (resolve, reject) { - - // Various Google tansformations - if (isGoogleURL$1(url) && !isGoogleStorageSigned(url)) { - if (isGoogleStorageURL$1(url)) { - url = translateGoogleCloudURL(url); - } - url = addApiKey(url); - - if (isGoogleDriveURL$1(url)) { - addTeamDrive(url); - } - - // If we have an access token try it, but don't force a signIn or request for scopes yet - if (!oauthToken) { - oauthToken = getCurrentGoogleAccessToken(); - } - } - - const headers = options.headers || {}; - if (oauthToken) { - addOauthHeaders(headers, oauthToken); - } - const range = options.range; - - - const xhr = new XMLHttpRequest(); - const sendData = options.sendData || options.body; - const method = options.method || (sendData ? "POST" : "GET"); - const responseType = options.responseType; - const contentType = options.contentType; - const mimeType = options.mimeType; - - xhr.open(method, url); - - if (options.timeout) { - xhr.timeout = options.timeout; - } - - if (range) { - let rangeEnd = ""; - if (range.size) { - rangeEnd = range.start + range.size - 1; - } - xhr.setRequestHeader("Range", "bytes=" + range.start + "-" + rangeEnd); - // xhr.setRequestHeader("Cache-Control", "no-cache"); <= This can cause CORS issues, disabled for now - } - if (contentType) { - xhr.setRequestHeader("Content-Type", contentType); - } - if (mimeType) { - xhr.overrideMimeType(mimeType); - } - if (responseType) { - xhr.responseType = responseType; - } - if (headers) { - for (let key of Object.keys(headers)) { - const value = headers[key]; - xhr.setRequestHeader(key, value); - } - } - - // NOTE: using withCredentials with servers that return "*" for access-allowed-origin will fail - if (options.withCredentials === true) { - xhr.withCredentials = true; - } - - xhr.onload = async function (event) { - - // when the url points to a local file, the status is 0 - if (xhr.status === 0 || (xhr.status >= 200 && xhr.status <= 300)) { - if ("HEAD" === options.method) { - // Support fetching specific headers. Attempting to fetch all headers can be problematic with CORS - const headers = options.requestedHeaders || ['content-length']; - const headerMap = {}; - for (let h of headers) { - headerMap[h] = xhr.getResponseHeader(h); - } - resolve(headerMap); - } else { - // Assume "GET" or "POST" - if (range && xhr.status !== 206 && range.start !== 0) { - - // For small files a range starting at 0 can return the whole file => 200 - // Provide just the slice we asked for, throw out the rest quietly - // If file is large warn user - if (xhr.response.length > 100000 && !self.RANGE_WARNING_GIVEN) { - alert(`Warning: Range header ignored for URL: ${url}. This can have severe performance impacts.`); - } - resolve(xhr.response.slice(range.start, range.start + range.size)); - } else { - resolve(xhr.response); - } - } - } else if (xhr.status === 416) { - handleError(Error(`416 Unsatisfiable Range`)); - } else if (isInitialized() && - ((xhr.status === 404 || xhr.status === 401 || xhr.status === 403) && - isGoogleURL$1(url)) && - !options.retries) { - tryGoogleAuth(); - - } else { - if (xhr.status === 403) { - handleError("Access forbidden: " + url); - } else { - handleError(xhr.status); - } - } - }; - - - xhr.onerror = function (event) { - if (isGoogleURL$1(url) && !options.retries) { - tryGoogleAuth(); - } else { - handleError("Error accessing resource: " + url + " Status: " + xhr.status); - } - }; - - xhr.ontimeout = function (event) { - handleError("Timed out"); - }; - - xhr.onabort = function (event) { - console.log("Aborted"); - reject(event); - }; - - try { - xhr.send(sendData); - } catch (e) { - if (isGoogleURL$1(url) && !options.retries) { - tryGoogleAuth(); - } else { - handleError(e); - } - } - - - function handleError(error) { - if (reject) { - reject(error); - } else { - throw error - } - } - - async function tryGoogleAuth() { - try { - const accessToken = await fetchGoogleAccessToken(_url); - options.retries = 1; - options.oauthToken = accessToken; - const response = await self.load(_url, options); - resolve(response); - } catch (e) { - if (e.error) { - const msg = e.error.startsWith("popup_blocked") ? - "Google login popup blocked by browser." : - e.error; - alert(msg); - } else { - handleError(e); - } - } - } - }) - - } - - async _loadFileSlice(localfile, options) { - - let blob = (options && options.range) ? - localfile.slice(options.range.start, options.range.start + options.range.size) : - localfile; - - const arrayBuffer = await blob.arrayBuffer(); - - if ("arraybuffer" === options.responseType) { - return arrayBuffer - } else { - return arrayBufferToString(arrayBuffer) - } - } - - async _loadStringFromFile(localfile, options) { - - const blob = options.range ? localfile.slice(options.range.start, options.range.start + options.range.size) : localfile; - const arrayBuffer = await blob.arrayBuffer(); - return arrayBufferToString(arrayBuffer) - } - - async _loadStringFromUrl(url, options) { - - options = options || {}; - options.responseType = "arraybuffer"; - const data = await this.load(url, options); - return arrayBufferToString(data) - } - - /** - * Explicity set an oAuth token for use with given host. If host is undefined token is used for google api access* - * @param token - * @param host - */ - setOauthToken(token, host) { - this.oauth.setToken(token, host); - } - - /** - * Return an oauth token for the URL if we have one. This method does not force sign-in, and the token may - * or may not be valid. Sign-in is triggered on request failure. - * * - * @param url - * @returns {*} - */ - getOauthToken(url) { - - // Google is the default provider, don't try to parse host for google URLs - const host = isGoogleURL$1(url) ? - undefined : - parseUri(url).host; - - // First check the explicit settings (i.e. token set through the API) - let token = this.oauth.getToken(host); - if (token) { - return token - } else if (host === undefined) { - // Now try Google oauth tokens previously obtained. This will return undefined if google oauth is not - // configured. - const googleToken = getCurrentGoogleAccessToken(); - if (googleToken && googleToken.expires_at > Date.now()) { - return googleToken.access_token - } - } - } - - /** - * This method should only be called when it is known the server supports HEAD requests. It is used to recover - * from 416 errors from out-of-spec WRT range request servers. Notably Globus. - * * * - * @param url - * @param options - * @returns {Promise} - */ - async getContentLength(url, options) { - options = options || {}; - options.method = 'HEAD'; - options.requestedHeaders = ['content-length']; - const headerMap = await this._loadURL(url, options); - const contentLengthString = headerMap['content-length']; - return contentLengthString ? Number.parseInt(contentLengthString) : 0 - } - -} - -function isGoogleStorageSigned(url) { - return url.indexOf("X-Goog-Signature") > -1 -} - - -/** - * Return a Google oAuth token, triggering a sign in if required. This method should not be called until we know - * a token is required, that is until we've tried the url and received a 401, 403, or 404. - * - * @param url - * @returns the oauth token - */ -async function fetchGoogleAccessToken(url) { - if (isInitialized()) { - const scope = getScopeForURL(url); - const access_token = await getAccessToken(scope); - return access_token - } else { - throw Error( - `Authorization is required, but Google oAuth has not been initalized. Contact your site administrator for assistance.`) - } -} - -/** - * Return the current google access token, if one exists. Do not triger signOn or request additional scopes. - * @returns {undefined|access_token} - */ -function getCurrentGoogleAccessToken() { - if (isInitialized()) { - const access_token = getCurrentAccessToken(); - return access_token - } else { - return undefined - } -} - -function addOauthHeaders(headers, acToken) { - if (acToken) { - headers["Cache-Control"] = "no-cache"; - headers["Authorization"] = "Bearer " + acToken; - } - return headers -} - - -function addApiKey(url) { - let apiKey = igvxhr.apiKey; - if (!apiKey && typeof gapi !== "undefined") { - apiKey = gapi.apiKey; - } - if (apiKey !== undefined && !url.includes("key=")) { - const paramSeparator = url.includes("?") ? "&" : "?"; - url = url + paramSeparator + "key=" + apiKey; - } - return url -} - -function addTeamDrive(url) { - if (url.includes("supportsTeamDrive")) { - return url - } else { - const paramSeparator = url.includes("?") ? "&" : "?"; - url = url + paramSeparator + "supportsTeamDrive=true"; - } -} - -/** - * Perform some well-known url mappings. - * @param url - */ -function mapUrl$1(url) { - - if (url.startsWith("https://www.dropbox.com")) { - return url.replace("//www.dropbox.com", "//dl.dropboxusercontent.com") - } else if (url.startsWith("https://drive.google.com")) { - return getDriveDownloadURL$1(url) - } else if (url.includes("//www.broadinstitute.org/igvdata")) { - return url.replace("//www.broadinstitute.org/igvdata", "//data.broadinstitute.org/igvdata") - } else if (url.includes("//igvdata.broadinstitute.org")) { - return url.replace("//igvdata.broadinstitute.org", "//s3.amazonaws.com/igv.broadinstitute.org") - } else if (url.includes("//igv.genepattern.org")) { - return url.replace("//igv.genepattern.org", "//igv-genepattern-org.s3.amazonaws.com") - } else if (url.startsWith("ftp://ftp.ncbi.nlm.nih.gov/geo")) { - return url.replace("ftp://", "https://") - } else { - return url - } -} - - -function arrayBufferToString(arraybuffer) { - - let plain; - if (isgzipped(arraybuffer)) { - plain = ungzip_blocks(arraybuffer); - } else { - plain = new Uint8Array(arraybuffer); - } - - if ('TextDecoder' in getGlobalObject()) { - return new TextDecoder().decode(plain) - } else { - return decodeUTF8(plain) - } -} - -/** - * Use when TextDecoder is not available (primarily IE). - * - * From: https://gist.github.com/Yaffle/5458286 - * - * @param octets - * @returns {string} - */ -function decodeUTF8(octets) { - var string = ""; - var i = 0; - while (i < octets.length) { - var octet = octets[i]; - var bytesNeeded = 0; - var codePoint = 0; - if (octet <= 0x7F) { - bytesNeeded = 0; - codePoint = octet & 0xFF; - } else if (octet <= 0xDF) { - bytesNeeded = 1; - codePoint = octet & 0x1F; - } else if (octet <= 0xEF) { - bytesNeeded = 2; - codePoint = octet & 0x0F; - } else if (octet <= 0xF4) { - bytesNeeded = 3; - codePoint = octet & 0x07; - } - if (octets.length - i - bytesNeeded > 0) { - var k = 0; - while (k < bytesNeeded) { - octet = octets[i + k + 1]; - codePoint = (codePoint << 6) | (octet & 0x3F); - k += 1; - } - } else { - codePoint = 0xFFFD; - bytesNeeded = octets.length - i; - } - string += String.fromCodePoint(codePoint); - i += bytesNeeded + 1; - } - return string -} - - -function getGlobalObject() { - if (typeof self !== 'undefined') { - return self - } - if (typeof global !== 'undefined') { - return global - } else { - return window - } -} - - -const igvxhr = new IGVXhr(); - -/* - * The MIT License (MIT) - * - * Copyright (c) 2014 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -/** An implementation of an interval tree, following the explanation. - * from CLR. - * - * Public interface: - * Constructor IntervalTree - * Insertion insert - * Search findOverlapping - */ - -var BLACK = 1; -var RED = 2; - -var NIL = {}; -NIL.color = BLACK; -NIL.parent = NIL; -NIL.left = NIL; -NIL.right = NIL; - - -class IntervalTree { - - constructor() { - this.root = NIL; - } - - insert(start, end, value) { - - var interval = new Interval(start, end, value); - var x = new Node$1(interval); - this.treeInsert(x); - x.color = RED; - while (x !== this.root && x.parent.color === RED) { - if (x.parent === x.parent.parent.left) { - let y = x.parent.parent.right; - if (y.color === RED) { - x.parent.color = BLACK; - y.color = BLACK; - x.parent.parent.color = RED; - x = x.parent.parent; - } else { - if (x === x.parent.right) { - x = x.parent; - leftRotate.call(this, x); - } - x.parent.color = BLACK; - x.parent.parent.color = RED; - rightRotate.call(this, x.parent.parent); - } - } else { - let y = x.parent.parent.left; - if (y.color === RED) { - x.parent.color = BLACK; - y.color = BLACK; - x.parent.parent.color = RED; - x = x.parent.parent; - } else { - if (x === x.parent.left) { - x = x.parent; - rightRotate.call(this, x); - } - x.parent.color = BLACK; - x.parent.parent.color = RED; - leftRotate.call(this, x.parent.parent); - } - } - } - this.root.color = BLACK; - } - - /** - * - * @param start - query interval - * @param end - query interval - * @returns Array of all intervals overlapping the query region - */ - findOverlapping(start, end) { - - - var searchInterval = new Interval(start, end, 0); - - if (this.root === NIL) return []; - - var intervals = searchAll.call(this, searchInterval, this.root, []); - - if (intervals.length > 1) { - intervals.sort(function (i1, i2) { - return i1.low - i2.low; - }); - } - - return intervals; - } - - /** - * Dump info on intervals to console. For debugging. - */ - logIntervals() { - - logNode(this.root, 0); - - function logNode(node, indent) { - - var space = ""; - for (var i = 0; i < indent; i++) space += " "; - console.log(space + node.interval.low + " " + node.interval.high); // + " " + (node.interval.value ? node.interval.value : " null")); - - indent += 5; - - if (node.left !== NIL) logNode(node.left, indent); - if (node.right !== NIL) logNode(node.right, indent); - } - - } - - mapIntervals(func) { - - applyInterval(this.root); - - function applyInterval(node) { - - func(node.interval); - - if (node.left !== NIL) applyInterval(node.left); - if (node.right !== NIL) applyInterval(node.right); - } - } - - - /** - * Note: Does not maintain RB constraints, this is done post insert - * - * @param x a Node - */ - treeInsert(x) { - var node = this.root; - var y = NIL; - while (node !== NIL) { - y = node; - if (x.interval.low <= node.interval.low) { - node = node.left; - } else { - node = node.right; - } - } - x.parent = y; - - if (y === NIL) { - this.root = x; - x.left = x.right = NIL; - } else { - if (x.interval.low <= y.interval.low) { - y.left = x; - } else { - y.right = x; - } - } - - applyUpdate.call(this, x); - } -} - -function searchAll(interval, node, results) { - - if (node.interval.overlaps(interval)) { - results.push(node.interval); - } - - if (node.left !== NIL && node.left.max >= interval.low) { - searchAll.call(this, interval, node.left, results); - } - - if (node.right !== NIL && node.right.min <= interval.high) { - searchAll.call(this, interval, node.right, results); - } - - return results; -} - -function leftRotate(x) { - var y = x.right; - x.right = y.left; - if (y.left !== NIL) { - y.left.parent = x; - } - y.parent = x.parent; - if (x.parent === NIL) { - this.root = y; - } else { - if (x.parent.left === x) { - x.parent.left = y; - } else { - x.parent.right = y; - } - } - y.left = x; - x.parent = y; - - applyUpdate.call(this, x); - // no need to apply update on y, since it'll y is an ancestor - // of x, and will be touched by applyUpdate(). -} - - -function rightRotate(x) { - var y = x.left; - x.left = y.right; - if (y.right !== NIL) { - y.right.parent = x; - } - y.parent = x.parent; - if (x.parent === NIL) { - this.root = y; - } else { - if (x.parent.right === x) { - x.parent.right = y; - } else { - x.parent.left = y; - } - } - y.right = x; - x.parent = y; - - - applyUpdate.call(this, x); - // no need to apply update on y, since it'll y is an ancestor - // of x, and will be touched by applyUpdate(). -} - - -// Applies the statistic update on the node and its ancestors. -function applyUpdate(node) { - while (node !== NIL) { - var nodeMax = node.left.max > node.right.max ? node.left.max : node.right.max; - var intervalHigh = node.interval.high; - node.max = nodeMax > intervalHigh ? nodeMax : intervalHigh; - - var nodeMin = node.left.min < node.right.min ? node.left.min : node.right.min; - var intervalLow = node.interval.low; - node.min = nodeMin < intervalLow ? nodeMin : intervalLow; - - node = node.parent; - } -} - - -class Interval { - constructor(low, high, value) { - this.low = low; - this.high = high; - this.value = value; - } - - equals(other) { - if (!other) { - return false; - } - if (this === other) { - return true; - } - return (this.low === other.low && - this.high === other.high); - - } - - compareTo(other) { - if (this.low < other.low) - return -1; - if (this.low > other.low) - return 1; - - if (this.high < other.high) - return -1; - if (this.high > other.high) - return 1; - - return 0; - } - - /** - * Returns true if this interval overlaps the other. - */ - overlaps(other) { - return (this.low <= other.high && other.low <= this.high); - } -} - -function Node$1(interval) { - this.parent = NIL; - this.left = NIL; - this.right = NIL; - this.interval = interval; - this.color = RED; -} - -/* - * The MIT License (MIT) - * - * Copyright (c) 2014 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -/** - * Object for caching lists of features. Supports effecient queries for sub-range (chr, start, end) - * - * @param featureList - * @param The genomic range spanned by featureList (optional) - * @constructor - */ - -class FeatureCache$1 { - - constructor(featureList, genome, range) { - - featureList = featureList || []; - this.treeMap = this.buildTreeMap(featureList, genome); - this.range = range; - this.count = featureList.length; - } - - containsRange(genomicRange) { - // No range means cache contains all features - return (this.range === undefined || this.range.contains(genomicRange.chr, genomicRange.start, genomicRange.end)); - } - - queryFeatures(chr, start, end) { - - const tree = this.treeMap[chr]; - - if (!tree) return []; - - const intervals = tree.findOverlapping(start, end); - - if (intervals.length === 0) { - return []; - } else { - // Trim the list of features in the intervals to those - // overlapping the requested range. - // Assumption: features are sorted by start position - - const featureList = []; - const all = this.allFeatures[chr]; - if (all) { - for (let interval of intervals) { - const indexRange = interval.value; - for (let i = indexRange.start; i < indexRange.end; i++) { - let feature = all[i]; - if (feature.start > end) break; - else if (feature.end >= start) { - featureList.push(feature); - } - } - } - featureList.sort(function (a, b) { - return a.start - b.start; - }); - } - return featureList; - } - }; - - /** - * Returns all features, unsorted. - * - * @returns {Array} - */ - getAllFeatures() { - return this.allFeatures; - } - - buildTreeMap(featureList, genome) { - - const treeMap = {}; - const chromosomes = []; - this.allFeatures = {}; - - if (featureList) { - for (let feature of featureList) { - - let chr = feature.chr; - // Translate to "official" name - if (genome) { - chr = genome.getChromosomeName(chr); - } - - let geneList = this.allFeatures[chr]; - if (!geneList) { - chromosomes.push(chr); - geneList = []; - this.allFeatures[chr] = geneList; - } - geneList.push(feature); - } - - - // Now build interval tree for each chromosome - for (let chr of chromosomes) { - const chrFeatures = this.allFeatures[chr]; - chrFeatures.sort(function (f1, f2) { - return (f1.start === f2.start ? 0 : (f1.start > f2.start ? 1 : -1)); - }); - treeMap[chr] = buildIntervalTree$1(chrFeatures); - } - } - - return treeMap; - } -} - -/** - * Build an interval tree from the feature list for fast interval based queries. We lump features in groups - * of 10, or total size / 100, to reduce size of the tree. - * - * @param featureList - */ -function buildIntervalTree$1(featureList) { - - const tree = new IntervalTree(); - const len = featureList.length; - const chunkSize = Math.max(10, Math.round(len / 10)); - - for (let i = 0; i < len; i += chunkSize) { - const e = Math.min(len, i + chunkSize); - const subArray = new IndexRange(i, e); //featureList.slice(i, e); - const iStart = featureList[i].start; - // - let iEnd = iStart; - for (let j = i; j < e; j++) { - iEnd = Math.max(iEnd, featureList[j].end); - } - tree.insert(iStart, iEnd, subArray); - } - - return tree; -} - - -class IndexRange { - constructor(start, end) { - this.start = start; - this.end = end; - } -} - -/* - * The MIT License (MIT) - * - * Copyright (c) 2016-2017 The Regents of the University of California - * Author: Jim Robinson - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -const FeatureUtils = { - - packFeatures: function (features, maxRows, sorted) { - - var start; - var end; - - if (!features) return; - - maxRows = maxRows || 10000; - - if (!sorted) { - features.sort(function (a, b) { - return a.start - b.start; - }); - } - - - if (features.length === 0) { - return []; - - } else { - - var bucketList = [], - allocatedCount = 0, - lastAllocatedCount = 0, - nextStart, - row, - index, - bucket, - feature, - gap = 2, - bucketStart; - - start = features[0].start; - end = features[features.length - 1].start; - - bucketStart = Math.max(start, features[0].start); - nextStart = bucketStart; - - features.forEach(function (alignment) { - - var buckListIndex = Math.max(0, alignment.start - bucketStart); - if (bucketList[buckListIndex] === undefined) { - bucketList[buckListIndex] = []; - } - bucketList[buckListIndex].push(alignment); - }); - - - row = 0; - - - while (allocatedCount < features.length && row <= maxRows) { - - - while (nextStart <= end) { - - bucket = undefined; - - while (!bucket && nextStart <= end) { - - index = nextStart - bucketStart; - if (bucketList[index] === undefined) { - ++nextStart; // No buckets at this index - } else { - bucket = bucketList[index]; - } - - } // while (bucket) - - if (!bucket) { - break; - } - feature = bucket.pop(); - if (0 === bucket.length) { - bucketList[index] = undefined; - } - - feature.row = row; - - nextStart = feature.end + gap; - ++allocatedCount; - - } // while (nextStart) - - row++; - nextStart = bucketStart; - - if (allocatedCount === lastAllocatedCount) break; // Protect from infinite loops - - lastAllocatedCount = allocatedCount; - - } // while (allocatedCount) - - } - }, - - - /** - * Find features overlapping the given interval. It is assumed that all features share the same chromosome. - * - * TODO -- significant overlap with FeatureCache, refactor to combine - * - * @param featureList - * @param start - * @param end - */ - findOverlapping: function (featureList, start, end) { - - if (!featureList || featureList.length === 0) { - return []; - } else { - const tree = buildIntervalTree(featureList); - const intervals = tree.findOverlapping(start, end); - - if (intervals.length === 0) { - return []; - } else { - // Trim the list of features in the intervals to those - // overlapping the requested range. - // Assumption: features are sorted by start position - - featureList = []; - - intervals.forEach(function (interval) { - const intervalFeatures = interval.value; - const len = intervalFeatures.length; - for (let i = 0; i < len; i++) { - const feature = intervalFeatures[i]; - if (feature.start > end) break; - else if (feature.end > start) { - featureList.push(feature); - } - } - }); - - featureList.sort(function (a, b) { - return a.start - b.start; - }); - - return featureList; - } - } - - } -}; - - -/** - * Build an interval tree from the feature list for fast interval based queries. We lump features in groups - * of 10, or total size / 100, to reduce size of the tree. - * - * @param featureList - */ -function buildIntervalTree(featureList) { - - const tree = new IntervalTree(); - const len = featureList.length; - const chunkSize = Math.max(10, Math.round(len / 100)); - - featureList.sort(function (f1, f2) { - return (f1.start === f2.start ? 0 : (f1.start > f2.start ? 1 : -1)); - }); - - for (let i = 0; i < len; i += chunkSize) { - const e = Math.min(len, i + chunkSize); - const subArray = featureList.slice(i, e); - const iStart = subArray[0].start; - let iEnd = iStart; - subArray.forEach(function (feature) { - iEnd = Math.max(iEnd, feature.end); - }); - tree.insert(iStart, iEnd, subArray); - } - - return tree; -} - -const appleCrayonRGBPalette = - { - cantaloupe: {r: 255, g: 206, b: 110}, - honeydew: {r: 206, g: 250, b: 110}, - spindrift: {r: 104, g: 251, b: 208}, - sky: {r: 106, g: 207, b: 255}, - lavender: {r: 210, g: 120, b: 255}, - carnation: {r: 255, g: 127, b: 211}, - licorice: {r: 0, g: 0, b: 0}, - snow: {r: 255, g: 255, b: 255}, - salmon: {r: 255, g: 114, b: 110}, - banana: {r: 255, g: 251, b: 109}, - flora: {r: 104, g: 249, b: 110}, - ice: {r: 104, g: 253, b: 255}, - orchid: {r: 110, g: 118, b: 255}, - bubblegum: {r: 255, g: 122, b: 255}, - lead: {r: 30, g: 30, b: 30}, - mercury: {r: 232, g: 232, b: 232}, - tangerine: {r: 255, g: 136, b: 2}, - lime: {r: 131, g: 249, b: 2}, - sea_foam: {r: 3, g: 249, b: 135}, - aqua: {r: 0, g: 140, b: 255}, - grape: {r: 137, g: 49, b: 255}, - strawberry: {r: 255, g: 41, b: 135}, - tungsten: {r: 58, g: 58, b: 58}, - silver: {r: 208, g: 208, b: 208}, - maraschino: {r: 255, g: 33, b: 1}, - lemon: {r: 255, g: 250, b: 3}, - spring: {r: 5, g: 248, b: 2}, - turquoise: {r: 0, g: 253, b: 255}, - blueberry: {r: 0, g: 46, b: 255}, - magenta: {r: 255, g: 57, b: 255}, - iron: {r: 84, g: 84, b: 83}, - magnesium: {r: 184, g: 184, b: 184}, - mocha: {r: 137, g: 72, b: 0}, - fern: {r: 69, g: 132, b: 1}, - moss: {r: 1, g: 132, b: 72}, - ocean: {r: 0, g: 74, b: 136}, - eggplant: {r: 73, g: 26, b: 136}, - maroon: {r: 137, g: 22, b: 72}, - steel: {r: 110, g: 110, b: 110}, - aluminum: {r: 160, g: 159, b: 160}, - cayenne: {r: 137, g: 17, b: 0}, - aspargus: {r: 136, g: 133, b: 1}, - clover: {r: 2, g: 132, b: 1}, - teal: {r: 0, g: 134, b: 136}, - midnight: {r: 0, g: 24, b: 136}, - plum: {r: 137, g: 30, b: 136}, - tin: {r: 135, g: 134, b: 135}, - nickel: {r: 136, g: 135, b: 135} - }; - -function appleCrayonRGB(name) { - const {r, g, b} = appleCrayonRGBPalette[name]; - return `rgb(${r},${g},${b})` -} - -function appleCrayonRGBA(name, alpha) { - const {r, g, b} = appleCrayonRGBPalette[name]; - return `rgba(${r},${g},${b},${alpha})` -} - -const colorPalettes = { - - Set1: - [ - "rgb(228,26,28)", - "rgb(55,126,184)", - "rgb(77,175,74)", - "rgb(166,86,40)", - "rgb(152,78,163)", - "rgb(255,127,0)", - "rgb(247,129,191)", - "rgb(153,153,153)", - "rgb(255,255,51)" - ], - - Dark2: - [ - "rgb(27,158,119)", - "rgb(217,95,2)", - "rgb(117,112,179)", - "rgb(231,41,138)", - "rgb(102,166,30)", - "rgb(230,171,2)", - "rgb(166,118,29)", - "rgb(102,102,102)" - ], - - Set2: - [ - "rgb(102, 194,165)", - "rgb(252,141,98)", - "rgb(141,160,203)", - "rgb(231,138,195)", - "rgb(166,216,84)", - "rgb(255,217,47)", - "rgb(229,196,148)", - "rgb(179,179,179)" - ], - - Set3: - [ - "rgb(141,211,199)", - "rgb(255,255,179)", - "rgb(190,186,218)", - "rgb(251,128,114)", - "rgb(128,177,211)", - "rgb(253,180,98)", - "rgb(179,222,105)", - "rgb(252,205,229)", - "rgb(217,217,217)", - "rgb(188,128,189)", - "rgb(204,235,197)", - "rgb(255,237,111)" - ], - - Pastel1: - [ - "rgb(251,180,174)", - "rgb(179,205,227)", - "rgb(204,235,197)", - "rgb(222,203,228)", - "rgb(254,217,166)", - "rgb(255,255,204)", - "rgb(229,216,189)", - "rgb(253,218,236)" - ], - - Pastel2: - [ - "rgb(173,226,207)", - "rgb(253,205,172)", - "rgb(203,213,232)", - "rgb(244,202,228)", - "rgb(230,245,201)", - "rgb(255,242,174)", - "rgb(243,225,206)" - ], - - Accent: - [ - "rgb(127,201,127)", - "rgb(190,174,212)", - "rgb(253,192,134)", - "rgb(255,255,153)", - "rgb(56,108,176)", - "rgb(240,2,127)", - "rgb(191,91,23)" - ] -}; - -class PaletteColorTable { - - constructor(palette) { - this.colors = colorPalettes[palette]; - if (!Array.isArray(this.colors)) this.colors = []; - this.colorTable = {}; - this.nextIdx = 0; - this.colorGenerator = new RandomColorGenerator(); - } - - getColor(key) { - if (!this.colorTable.hasOwnProperty(key)) { - if (this.nextIdx < this.colors.length) { - this.colorTable[key] = this.colors[this.nextIdx]; - } else { - this.colorTable[key] = this.colorGenerator.get(); - } - this.nextIdx++; - } - return this.colorTable[key] - } -} - -class ColorTable { - constructor(colors) { - this.colorTable = colors || {}; - this.nextIdx = 0; - this.colorGenerator = new RandomColorGenerator(); - } - - getColor(key) { - if (!this.colorTable.hasOwnProperty(key)) { - if (this.colorTable.hasOwnProperty("*")) { - return this.colorTable["*"] - } - this.colorTable[key] = this.colorGenerator.get(); - } - return this.colorTable[key] - } -} - -// Random color generator from https://github.com/sterlingwes/RandomColor/blob/master/rcolor.js -// Free to use & distribute under the MIT license -// Wes Johnson (@SterlingWes) -// -// inspired by http://martin.ankerl.com/2009/12/09/how-to-create-random-colors-programmatically/ -function RandomColorGenerator() { - this.hue = Math.random(); - this.goldenRatio = 0.618033988749895; - this.hexwidth = 2; -} - -RandomColorGenerator.prototype.hsvToRgb = function (h, s, v) { - var h_i = Math.floor(h * 6), - f = h * 6 - h_i, - p = v * (1 - s), - q = v * (1 - f * s), - t = v * (1 - (1 - f) * s), - r = 255, - g = 255, - b = 255; - switch (h_i) { - case 0: - r = v, g = t, b = p; - break - case 1: - r = q, g = v, b = p; - break - case 2: - r = p, g = v, b = t; - break - case 3: - r = p, g = q, b = v; - break - case 4: - r = t, g = p, b = v; - break - case 5: - r = v, g = p, b = q; - break - } - return [Math.floor(r * 256), Math.floor(g * 256), Math.floor(b * 256)] -}; - -RandomColorGenerator.prototype.padHex = function (str) { - if (str.length > this.hexwidth) return str - return new Array(this.hexwidth - str.length + 1).join('0') + str -}; - -RandomColorGenerator.prototype.get = function (saturation, value) { - this.hue += this.goldenRatio; - this.hue %= 1; - if (typeof saturation !== "number") saturation = 0.5; - if (typeof value !== "number") value = 0.95; - var rgb = this.hsvToRgb(this.hue, saturation, value); - - return "#" + this.padHex(rgb[0].toString(16)) - + this.padHex(rgb[1].toString(16)) - + this.padHex(rgb[2].toString(16)) - -}; - -new RandomColorGenerator(); - -function randomRGB$1(min, max) { - - min = IGVMath.clamp(min, 0, 255); - max = IGVMath.clamp(max, 0, 255); - - const r = Math.round(Math.random() * (max - min) + min).toString(10); - const g = Math.round(Math.random() * (max - min) + min).toString(10); - const b = Math.round(Math.random() * (max - min) + min).toString(10); - return `rgb(${r},${g},${b})` - -} - -/* - * The MIT License (MIT) - * - * Copyright (c) 2014 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of ctx software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and ctx permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - -const IGVGraphics = { - - configureHighDPICanvas: function (ctx, w, h) { - - const scaleFactor = window.devicePixelRatio; - // const scaleFactor = 1 - - ctx.canvas.style.width = (`${w}px`); - ctx.canvas.width = Math.floor(scaleFactor * w); - - ctx.canvas.style.height = (`${h}px`); - ctx.canvas.height = Math.floor(scaleFactor * h); - - ctx.scale(scaleFactor, scaleFactor); - - }, - - setProperties: function (ctx, properties) { - - for (var key in properties) { - if (properties.hasOwnProperty(key)) { - var value = properties[key]; - ctx[key] = value; - } - } - }, - - strokeLine: function (ctx, x1, y1, x2, y2, properties) { - - x1 = Math.floor(x1) + 0.5; - y1 = Math.floor(y1) + 0.5; - x2 = Math.floor(x2) + 0.5; - y2 = Math.floor(y2) + 0.5; - - if (properties) { - ctx.save(); - IGVGraphics.setProperties(ctx, properties); - } - - ctx.beginPath(); - ctx.moveTo(x1, y1); - ctx.lineTo(x2, y2); - ctx.stroke(); - - if (properties) ctx.restore(); - }, - - fillRect: function (ctx, x, y, w, h, properties) { - x = Math.round(x); - y = Math.round(y); - - if (properties) { - ctx.save(); - IGVGraphics.setProperties(ctx, properties); - } - - ctx.fillRect(x, y, w, h); - - if (properties) ctx.restore(); - }, - - fillPolygon: function (ctx, x, y, properties) { - if (properties) { - ctx.save(); - IGVGraphics.setProperties(ctx, properties); - } - doPath(ctx, x, y); - ctx.fill(); - if (properties) ctx.restore(); - }, - - strokePolygon: function (ctx, x, y, properties) { - if (properties) { - ctx.save(); - IGVGraphics.setProperties(ctx, properties); - } - doPath(ctx, x, y); - ctx.stroke(); - if (properties) ctx.restore(); - }, - - fillText: function (ctx, text, x, y, properties, transforms) { - - if (properties || transforms) { - ctx.save(); - } - - if (properties) { - IGVGraphics.setProperties(ctx, properties); - } - - if (transforms) { - // Slow path with context saving and extra translate - ctx.translate(x, y); - - for (var transform in transforms) { - var value = transforms[transform]; - - // TODO: Add error checking for robustness - if (transform === 'translate') { - ctx.translate(value['x'], value['y']); - } - if (transform === 'rotate') { - ctx.rotate(value['angle'] * Math.PI / 180); - } - } - - ctx.fillText(text, 0, 0); - } else { - ctx.fillText(text, x, y); - } - - if (properties || transforms) ctx.restore(); - }, - - strokeText: function (ctx, text, x, y, properties, transforms) { - - - if (properties || transforms) { - ctx.save(); - } - - if (properties) { - IGVGraphics.setProperties(ctx, properties); - } - - if (transforms) { - ctx.translate(x, y); - - for (var transform in transforms) { - var value = transforms[transform]; - - // TODO: Add error checking for robustness - if (transform === 'translate') { - ctx.translate(value['x'], value['y']); - } - if (transform === 'rotate') { - ctx.rotate(value['angle'] * Math.PI / 180); - } - } - - ctx.strokeText(text, 0, 0); - } else { - ctx.strokeText(text, x, y); - } - - if (properties || transforms) ctx.restore(); - }, - - strokeCircle: function (ctx, x, y, radius, properties) { - if (properties) { - ctx.save(); - IGVGraphics.setProperties(ctx, properties); - } - ctx.beginPath(); - ctx.arc(x, y, radius, 0, 2 * Math.PI); - ctx.stroke(); - if (properties) ctx.restore(); - }, - - fillCircle: function (ctx, x, y, radius, properties) { - if (properties) { - ctx.save(); - IGVGraphics.setProperties(ctx, properties); - } - ctx.beginPath(); - ctx.arc(x, y, radius, 0, 2 * Math.PI); - ctx.fill(); - if (properties) ctx.restore(); - }, - - drawArrowhead: function (ctx, x, y, size, lineWidth) { - - ctx.save(); - if (!size) { - size = 5; - } - if (lineWidth) { - ctx.lineWidth = lineWidth; - } - ctx.beginPath(); - ctx.moveTo(x, y - size / 2); - ctx.lineTo(x, y + size / 2); - ctx.lineTo(x + size, y); - ctx.lineTo(x, y - size / 2); - ctx.closePath(); - ctx.fill(); - ctx.restore(); - }, - - dashedLine: function (ctx, x1, y1, x2, y2, dashLen, properties = {}) { - if (dashLen === undefined) dashLen = 2; - ctx.setLineDash([dashLen, dashLen]); - IGVGraphics.strokeLine(ctx, x1, y1, x2, y2, properties); - ctx.setLineDash([]); - }, - - roundRect: function (ctx, x, y, width, height, radius, fill, stroke) { - - if (typeof stroke == "undefined") { - stroke = true; - } - if (typeof radius === "undefined") { - radius = 5; - } - ctx.beginPath(); - ctx.moveTo(x + radius, y); - ctx.lineTo(x + width - radius, y); - ctx.quadraticCurveTo(x + width, y, x + width, y + radius); - ctx.lineTo(x + width, y + height - radius); - ctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height); - ctx.lineTo(x + radius, y + height); - ctx.quadraticCurveTo(x, y + height, x, y + height - radius); - ctx.lineTo(x, y + radius); - ctx.quadraticCurveTo(x, y, x + radius, y); - ctx.closePath(); - if (stroke) { - ctx.stroke(); - } - if (fill) { - ctx.fill(); - } - }, - polygon: function (ctx, x, y, fill, stroke) { - - if (typeof stroke == "undefined") { - stroke = true; - } - - ctx.beginPath(); - var len = x.length; - ctx.moveTo(x[0], y[0]); - for (var i = 1; i < len; i++) { - ctx.lineTo(x[i], y[i]); - // this.moveTo(x[i], y[i]); - } - - ctx.closePath(); - if (stroke) { - ctx.stroke(); - } - if (fill) { - ctx.fill(); - } - }, - - drawRandomColorVerticalLines: ctx => { - for (let x = 0; x < ctx.canvas.width; x++) { - IGVGraphics.fillRect(ctx, x, 0, 1, ctx.canvas.height, { fillStyle: randomRGB$1(100, 250) }); - } - }, - - labelTransformWithContext: (ctx, exe) => { - ctx.translate(exe, 0); - ctx.scale(-1, 1); - ctx.translate(-exe, 0); - } - -}; - -function doPath(ctx, x, y) { - - - var i, len = x.length; - for (i = 0; i < len; i++) { - x[i] = Math.round(x[i]); - y[i] = Math.round(y[i]); - } - - ctx.beginPath(); - ctx.moveTo(x[0], y[0]); - for (i = 1; i < len; i++) { - ctx.lineTo(x[i], y[i]); - } - ctx.closePath(); -} - -class Alert$2 { - constructor(parent) { - this.dialog = new AlertDialog$1(parent); - - } - - present(alert, callback) { - this.dialog.present(alert, callback); - } -} - -const FileFormats = { - - gwascatalog: { - fields: [ - 'bin', - 'chr', - 'start', - 'end', - 'name', - 'pubMedID', - 'author', - 'pubDate', - 'journal', - 'title', - 'trait', - 'initSample', - 'replSample', - 'region', - 'genes', - 'riskAllele', - 'riskAlFreq', - 'pValue', - 'pValueDesc', - 'orOrBeta', - 'ci95', - 'platform', - 'cnv' - ] - }, - - wgrna: { - fields: - [ - 'bin', - 'chr', - 'start', - 'end', - 'name', - 'score', - 'strand', - 'thickStart', - 'thickEnd', - 'type' - ] - }, - - cpgislandext: { - fields: - - [ - 'bin', - 'chr', - 'start', - 'end', - 'name', - 'length', - 'cpgNum', - 'gcNum', - 'perCpg', - 'perGc', - 'obsExp' - ] - }, - - clinVarMain: { - fields: [ - 'chr1', - 'start', - 'end', - 'name', - 'score', - 'strand', - 'thickStart', - 'thickEnd', - 'reserved', - 'blockCount', // Number of blocks - 'blockSizes', // Comma separated list of block sizes - 'chromStarts', // Start positions relative to chromStart - 'origName', // NM_198053.2(CD247):c.462C>T (p.Asp154=) ClinVar Variation Report - 'clinSign', // Likely benign Clinical significance - 'reviewStatus', // based on: criteria provided,single submitter Review Status - 'type', // single nucleotide variant Type of Variant - 'geneId', // CD247 Gene Symbol - 'snpId', // 181656780 dbSNP ID - 'nsvId', // dbVar ID - 'rcvAcc', // RCV000642347 ClinVar Allele Submission - 'testedInGtr', // N Genetic Testing Registry - 'phenotypeList', // Immunodeficiency due to defect in cd3-zeta Phenotypes - 'phenotype', // MedGen:C1857798, OMIM:610163 Phenotype identifiers - 'origin', // germline Data origin - 'assembly', // GRCh37 Genome assembly - 'cytogenetic', // 1q24.2 Cytogenetic status - 'hgvsCod', // NM_198053.2:c.462C>T Nucleotide HGVS - 'hgvsProt', // NP_932170.1:p.Asp154= Protein HGVS - 'numSubmit', // 1 Number of submitters - 'lastEval', // Dec 19,2017 Last evaluation - 'guidelines', // Guidelines - 'otherIds' - ] - } -}; - -/* - * The MIT License (MIT) - * - * Copyright (c) 2014 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -/** - * Test if the given value is a string or number. Not using typeof as it fails on boxed primitives. - * - * @param value - * @returns boolean - */ - -function isSimpleType(value) { - const simpleTypes = new Set(["boolean", "number", "string", "symbol"]); - const valueType = typeof value; - return (value !== undefined && (simpleTypes.has(valueType) || value.substring || value.toFixed)) -} - -function buildOptions$1(config, options) { - - var defaultOptions = { - oauthToken: config.oauthToken, - headers: config.headers, - withCredentials: config.withCredentials, - filename: config.filename - }; - - return Object.assign(defaultOptions, options) -} - -/** - * isMobile test from http://detectmobilebrowsers.com - * TODO -- improve UI design so this isn't neccessary - * @returns {boolean} - */ - -// igv.isMobile = function () { -// -// const a = (navigator.userAgent || navigator.vendor || window.opera); -// return (/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(a) || -// /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0, 4))) -// -// } - -const doAutoscale$1 = function (features) { - var min, max; - - if (features && features.length > 0) { - min = Number.MAX_VALUE; - max = -Number.MAX_VALUE; - - for(let f of features) { - if (!Number.isNaN(f.value)) { - min = Math.min(min, f.value); - max = Math.max(max, f.value); - } - } - - // Insure we have a zero baseline - if (max > 0) min = Math.min(0, min); - if (max < 0) max = 0; - } else { - // No features -- default - min = 0; - max = 100; - } - - return {min: min, max: max} -}; - -const validateGenomicExtent = function (chromosomeLengthBP, genomicExtent, minimumBP) { - - let ss = genomicExtent.start; - let ee = genomicExtent.end; - - if (undefined === ee) { - - ss -= minimumBP / 2; - ee = ss + minimumBP; - - if (ee > chromosomeLengthBP) { - ee = chromosomeLengthBP; - ss = ee - minimumBP; - } else if (ss < 0) { - ss = 0; - ee = minimumBP; - } - - } else if (ee - ss < minimumBP) { - - const center = (ee + ss) / 2; - - if (center - minimumBP / 2 < 0) { - ss = 0; - ee = ss + minimumBP; - } else if (center + minimumBP / 2 > chromosomeLengthBP) { - ee = chromosomeLengthBP; - ss = ee - minimumBP; - } else { - ss = center - minimumBP / 2; - ee = ss + minimumBP; - } - } - - genomicExtent.start = Math.ceil(ss); - genomicExtent.end = Math.floor(ee); -}; - -/*! - * is-number - * - * Copyright (c) 2014-present, Jon Schlinkert. - * Released under the MIT License. - */ - -const isNumber = function (num) { - if (typeof num === 'number') { - return num - num === 0 - } - if (typeof num === 'string' && num.trim() !== '') { - return Number.isFinite ? Number.isFinite(+num) : isFinite(+num) - } - return false -}; - -async function getFilename$1(url) { - if (isString$2(url) && url.startsWith("https://drive.google.com")) { - // This will fail if Google API key is not defined - if (getApiKey() === undefined) { - throw Error("Google drive is referenced, but API key is not defined. An API key is required for Google Drive access") - } - const json = await getDriveFileInfo(url); - return json.originalFileName || json.name - } else { - return getFilename$2(url) - } -} - -function prettyBasePairNumber(raw) { - - var denom, - units, - value, - floored; - - if (raw > 1e7) { - denom = 1e6; - units = " mb"; - } else if (raw > 1e4) { - - denom = 1e3; - units = " kb"; - - value = raw / denom; - floored = Math.floor(value); - return numberFormatter$1(floored) + units - } else { - return numberFormatter$1(raw) + " bp" - } - - value = raw / denom; - floored = Math.floor(value); - - return floored.toString() + units -} - - -function isDataURL(obj) { - return (isString$2(obj) && obj.startsWith("data:")) -} - -function createColumn(columnContainer, className) { - const column = domUtils$1.div({class: className}); - columnContainer.appendChild(column); -} - - -function insertElementBefore(element, referenceNode) { - referenceNode.parentNode.insertBefore(element, referenceNode); -} - -function insertElementAfter(element, referenceNode) { - referenceNode.parentNode.insertBefore(element, referenceNode.nextSibling); -} - -/** - * Test to see if page is loaded in a secure context, that is by https or is localhost. - */ -function isSecureContext() { - return window.location.protocol === "https:" || window.location.hostname === "localhost" -} - -// reference: https://pretagteam.com/question/find-element-height-including-margin -function getElementAbsoluteHeight(element) { - - // Get the DOM Node if you pass in a string - element = (typeof element === 'string') ? document.querySelector(element) : element; - - const styles = window.getComputedStyle(element); - const margin = parseFloat(styles['marginTop']) + parseFloat(styles['marginBottom']); - const height = element.offsetHeight; - - return Math.ceil(margin + height); -} - -/** - * Decoder for bedpe records. - * - * Bedpe format was created by Aaron Quinlan et al as part of the bedtools project. - * The spec is here: https://bedtools.readthedocs.io/en/latest/content/general-usage.html, - * - * 1 2 3 4 5 6 7 8 9 10 11- - * chrom1 start1 end1 chrom2 start2 end2 name score strand1 strand2 - * - * However there are off spec variants, an important one being a 7 column format with score in place of the standard - * name column. - * - * A common variant is a "hiccups" output file, which is standard bedpe with the exception of a header line - * of the form - * - * chr1 x1 x2 chr2 y1 y2 name score strand1 strand2 color observed expectedBL expectedDonut expectedH expectedV fdrBL fdrDonut fdrH fdrV - * - * The "hiccups" output is apparently not standardized as this is found at ENCODE, with a non-helpful "tsv" extension - * - * chr1 x1 x2 chr2 y1 y2 color observed expectedBL expectedDonut expectedH expectedV fdrBL fdrDonut fdrH fdrV numCollapsed centroid1 centroid2 radius - * chr9 136790000 136795000 chr9 136990000 136995000 0,255,255 101.0 31.100368 38.40316 56.948116 34.040756 1.1876738E-13 1.05936405E-13 2.5148233E-4 1.7220993E-13 1 136792500 136992500 25590 - * - * The "hiccups" documentation specfies yet another set of column headers - * chromosome1 x1 x2 chromosome2 y1 y2 color observed expected_bottom_left expected_donut expected_horizontal expected_vertical fdr_bottom_left fdr_donut fdr_horizontal fdr_vertical number_collapsed centroid1 centroid2 radius - * - * @param tokens - * @param ignore - * @returns {{start1: number, end2: number, end1: number, chr1: *, chr2: *, start2: number}|undefined} - */ - -function decodeBedpe(tokens, header) { - - if (tokens.length < 6) { - console.log("Skipping line: " + tokens.join(' ')); - return undefined - } - - var feature = { - chr1: tokens[0], - start1: Number.parseInt(tokens[1]), - end1: Number.parseInt(tokens[2]), - chr2: tokens[3], - start2: Number.parseInt(tokens[4]), - end2: Number.parseInt(tokens[5]) - }; - - if (isNaN(feature.start1) || isNaN(feature.end1) || isNaN(feature.start2) || isNaN(feature.end2)) { - //throw Error(`Error parsing line: ${tokens.join('\t')}`); - return undefined - } - - // Determine if this is a "hiccups" file. Store result on "header" so it doesn't need repeated for every feature - if(header && header.hiccups === undefined) { - header.hiccups = header.columnNames ? isHiccups(header.columnNames) : false; - } - const hiccups = header && header.hiccups; - const stdColumns = hiccups ? 6 : 10; - - if(!hiccups) { - if (tokens.length > 6 && tokens[6] !== ".") { - feature.name = tokens[6]; - } - - if (tokens.length > 7 && tokens[7] !== ".") { - feature.score = Number(tokens[7]); - } - - if (tokens.length > 8 && tokens[8] !== ".") { - feature.strand1 = tokens[8]; - } - - if (tokens.length > 9 && tokens[9] !== ".") { - feature.strand2 = tokens[9]; - } - } - - // Optional extra columns - if (header) { - const colorColumn = header.colorColumn; - if (colorColumn && colorColumn < tokens.length) { - feature.color = IGVColor.createColorString(tokens[colorColumn]); - } - const thicknessColumn = header.thicknessColumn; - if (thicknessColumn && thicknessColumn < tokens.length) { - feature.thickness = tokens[thicknessColumn]; - } - - if (tokens.length > stdColumns && header.columnNames && header.columnNames.length === tokens.length) { - feature.extras = tokens.slice(stdColumns); - } - } - - - // Set total extent of feature - if (feature.chr1 === feature.chr2) { - feature.chr = feature.chr1; - feature.start = Math.min(feature.start1, feature.start2); - feature.end = Math.max(feature.end1, feature.end2); - - } - return feature -} - -/** - * Hack for non-standard bedPE formats, where numeric score can be in column 7 (name field from spec) - * @param features - */ -function fixBedPE(features) { - - if (features.length == 0) return - - // Assume all features have same properties - const firstFeature = features[0]; - if (firstFeature.score === undefined && firstFeature.name !== undefined) { - // Name field (col 7) is sometimes used for score. - for (let f of features) { - if (!(isNumber(f.name) || f.name === '.')) return - } - for (let f of features) { - f.score = Number(f.name); - delete f.name; - } - } - - // Make copies of inter-chr features, one for each chromosome - const interChrFeatures = features.filter(f => f.chr1 !== f.chr2); - for (let f1 of interChrFeatures) { - const f2 = Object.assign({}, f1); - f2.dup = true; - features.push(f2); - - f1.chr = f1.chr1; - f1.start = f1.start1; - f1.end = f1.end1; - - f2.chr = f2.chr2; - f2.start = f2.start2; - f2.end = f2.end2; - } -} - - -/** - * Special decoder for Hic Domain files. In these files feature1 == feature2, they are really bed records. - * @param tokens - * @param ignore - * @returns {*} - */ -function decodeBedpeDomain(tokens, header) { - - if (tokens.length < 8) return undefined - - return { - chr: tokens[0], - start: Number.parseInt(tokens[1]), - end: Number.parseInt(tokens[2]), - color: IGVColor.createColorString(tokens[6]), - value: Number(tokens[7]) - } -} - -function isHiccups(columns) { - return columns && (columns.includes("fdrDonut") || columns.includes("fdr_donut")) -} - -/* - * The MIT License (MIT) - * - * Copyright (c) 2014 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -const knownFileExtensions = new Set([ - - "narrowpeak", - "broadpeak", - "regionpeak", - "peaks", - "bedgraph", - "wig", - "gff3", - "gff", - "gtf", - "fusionjuncspan", - "refflat", - "seg", - "aed", - "bed", - "vcf", - "bb", - "bigbed", - "biginteract", - "biggenepred", - "bignarrowpeak", - "bw", - "bigwig", - "bam", - "tdf", - "refgene", - "genepred", - "genepredext", - "bedpe", - "bp", - "snp", - "rmsk", - "cram", - "gwas", - "maf", - "mut", - "tsv", - "hiccups", - "fasta", - "fa", - "fna", - "pytor" -]); - -/** - * Return a custom format object with the given name. - * @param name - * @returns {*} - */ -function getFormat(name) { - - if (FileFormats && FileFormats[name]) { - return expandFormat(FileFormats[name]) - } else { - return undefined - } - - function expandFormat(format) { - - const fields = format.fields; - const keys = ['chr', 'start', 'end']; - - for (let i = 0; i < fields.length; i++) { - for (let key of keys) { - if (key === fields[i]) { - format[key] = i; - } - } - } - - return format - } -} - -function inferFileFormat(fn) { - - var idx, ext; - - fn = fn.toLowerCase(); - - // Special case -- UCSC refgene files - if (fn.endsWith("refgene.txt.gz") || - fn.endsWith("refgene.txt.bgz") || - fn.endsWith("refgene.txt") || - fn.endsWith("refgene.sorted.txt.gz") || - fn.endsWith("refgene.sorted.txt.bgz")) { - return "refgene" - } - - - //Strip parameters -- handle local files later - idx = fn.indexOf("?"); - if (idx > 0) { - fn = fn.substr(0, idx); - } - - //Strip aux extensions .gz, .tab, and .txt - if (fn.endsWith(".gz")) { - fn = fn.substr(0, fn.length - 3); - } - - if (fn.endsWith(".txt") || fn.endsWith(".tab") || fn.endsWith(".bgz")) { - fn = fn.substr(0, fn.length - 4); - } - - - idx = fn.lastIndexOf("."); - ext = idx < 0 ? fn : fn.substr(idx + 1); - - switch (ext) { - case "bw": - return "bigwig" - case "bb": - return "bigbed" - case "fasta": - case "fa": - case "fna": - return "fasta" - default: - if (knownFileExtensions.has(ext)) { - return ext - } else { - return undefined - } - - } - -} - -function inferIndexPath(url, extension) { - - if (isString$2(url)) { - if (url.includes("?")) { - const idx = url.indexOf("?"); - return url.substring(0, idx) + "." + extension + url.substring(idx) - } else { - return url + "." + extension - } - } else { - return undefined - } -} - - -function inferTrackType(config) { - - translateDeprecatedTypes(config); - - if (config.type) { - return config.type - } - - if (config.format) { - const format = config.format.toLowerCase(); - switch (format) { - case "bw": - case "bigwig": - case "wig": - case "bedgraph": - case "tdf": - return "wig" - case "vcf": - return "variant" - case "seg": - return "seg" - case "mut": - case "maf": - return "mut" - case "bam": - case "cram": - return "alignment" - case "hiccups": - case "bedpe": - case "bedpe-loop": - case "biginteract": - return "interact" - case "bp": - return "arc" - case "gwas": - return "gwas" - case "bed": - case "bigbed": - case "bb": - case "biggenepred": - case "bignarrowpeak": - return "bedtype" - case "fasta": - return "sequence" - case "pytor": - return "cnvpytor" - default: - return "annotation" - } - } -} - -function translateDeprecatedTypes(config) { - - if (config.featureType) { // Translate deprecated "feature" type - config.type = config.type || config.featureType; - config.featureType = undefined; - } - if ("junctions" === config.type) { - config.type = "junction"; - } else if ("bed" === config.type) { - config.type = "annotation"; - config.format = config.format || "bed"; - } else if ("annotations" === config.type) { - config.type = "annotation"; - } else if ("alignments" === config.type) { - config.type = "alignment"; - } else if ("bam" === config.type) { - config.type = "alignment"; - config.format = "bam"; - } else if ("vcf" === config.type) { - config.type = "variant"; - config.format = "vcf"; - } else if ("t2d" === config.type) { - config.type = "gwas"; - } else if ("FusionJuncSpan" === config.type && !config.format) { - config.format = "fusionjuncspan"; - } else if ("aed" === config.type) { - config.type = "annotation"; - config.format = config.format || "aed"; - } -} - -/** - * Attempt to infer the file format by reading a few lines from the header. Currently this only supports "tsv" extensions, - * it was added specifically for "hiccups" type tsv files in ENCODE. Might be expanded in the future. - * - * @param url - * @returns {Promise} - */ -async function inferFileFormatFromHeader(config) { - - if (config.url) { - const firstBytes = await igvxhr.loadString(config.url, buildOptions$1(config, {range: {start: 0, size: 1000}})); - if(firstBytes) { - const columnNames = firstBytes.split('\n')[0].split('\t'); - if(isHiccups(columnNames)) { - return "hiccups" - } - } - } - - return undefined - -} - -function registerFileFormats(name, fields) { - FileFormats[name] = {fields: fields}; -} - -var TrackUtils = /*#__PURE__*/Object.freeze({ - __proto__: null, - knownFileExtensions: knownFileExtensions, - getFormat: getFormat, - inferFileFormat: inferFileFormat, - inferFileFormatFromHeader: inferFileFormatFromHeader, - inferTrackType: inferTrackType, - inferIndexPath: inferIndexPath, - registerFileFormats: registerFileFormats -}); - -const pairs = - [ - ['A', 'T'], - ['G', 'C'], - ['Y', 'R'], - ['W', 'S'], - ['K', 'M'], - ['D', 'H'], - ['B', 'V'] - ]; - -const complements = new Map(); -for (let p of pairs) { - const p1 = p[0]; - const p2 = p[1]; - complements.set(p1, p2); - complements.set(p2, p1); - complements.set(p1.toLowerCase(), p2.toLowerCase()); - complements.set(p2.toLowerCase(), p1.toLowerCase()); -} - -function reverseComplementSequence(sequence) { - - let comp = ''; - let idx = sequence.length; - while (idx-- > 0) { - const base = sequence[idx]; - comp += complements.has(base) ? complements.get(base) : base; - } - return comp -} - -class Chromosome { - constructor(name, order, bpLength) { - this.name = name; - this.order = order; - this.bpLength = bpLength; - } -} - -/* - * The MIT License (MIT) - * - * Copyright (c) 2014 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -const splitLines$4 = splitLines$5; - -const reservedProperties$1 = new Set(['fastaURL', 'indexURL', 'cytobandURL', 'indexed']); - -class NonIndexedFasta { - - - constructor(reference) { - - this.fastaURL = reference.fastaURL; - this.withCredentials = reference.withCredentials; - this.chromosomeNames = []; - this.chromosomes = {}; - this.sequences = new Map(); - - // Build a track-like config object from the referenceObject - const config = {}; - for (let key in reference) { - if (reference.hasOwnProperty(key) && !reservedProperties$1.has(key)) { - config[key] = reference[key]; - } - } - this.config = config; - } - - - async init() { - return this.loadAll() - } - - async getSequence(chr, start, end) { - - if (!this.sequences.has(chr)) { - return undefined - } - - let seqSlice = this.sequences.get(chr).find(ss => ss.contains(start, end)); - if (!seqSlice) { - seqSlice = this.sequences.get(chr).find(ss => ss.overlaps(start, end)); - if (!seqSlice) { - return undefined - } - } - - start -= seqSlice.offset; - end -= seqSlice.offset; - - let prefix = ""; - if (start < 0) { - for (let i = start; i < Math.min(end, 0); i++) { - prefix += "*"; - } - } - - if (end <= 0) { - return Promise.resolve(prefix) - } - - const seq = seqSlice.sequence; - const seqEnd = Math.min(end, seq.length); - return prefix + seq.substring(start, seqEnd) - } - - async loadAll() { - - let data; - if (isDataURL(this.fastaURL)) { - let bytes = decodeDataURI$1(this.fastaURL); - data = ""; - for (let b of bytes) { - data += String.fromCharCode(b); - } - } else { - data = await igvxhr.load(this.fastaURL, buildOptions$1(this.config)); - } - - const chrNameSet = new Set(); - const lines = splitLines$4(data); - const len = lines.length; - let lineNo = 0; - let order = 0; - let nextLine; - let current = {}; - while (lineNo < len) { - nextLine = lines[lineNo++].trim(); - if (nextLine.startsWith("#") || nextLine.length === 0) ; else if (nextLine.startsWith(">")) { - // Start the next sequence - if(current && current.seq) { - pushChromosome.call(this, current, order++); - } - - const parts = nextLine.substr(1).split(/\s+/); - - // Check for samtools style locus string. This is not perfect, and could fail on weird sequence names - const nameParts = parts[0].split(':'); - current.chr = nameParts[0]; - current.seq = ""; - current.offset = 0; - if (nameParts.length > 1 && nameParts[1].indexOf('-') > 0) { - const locusParts = nameParts[1].split('-'); - if (locusParts.length === 2 && - /^[0-9]+$/.test(locusParts[0]) && - /^[0-9]+$/.test(locusParts[1])) ; - const from = Number.parseInt(locusParts[0]); - const to = Number.parseInt(locusParts[1]); - if (to > from) { // TODO this should be an error - current.offset = from - 1; - } - - // Check for chromosome length token - if (parts.length > 1 && parts[1].startsWith("@len=")) { - try { - current.length = parseInt(parts[1].trim().substring(5)); - } catch (e) { - current.length = undefined; - console.error(`Error parsing sequence length for ${nextLine}`); - } - } else { - current.length = undefined; - } - } - } else { - current.seq += nextLine; - } - // add last seq - if (current && current.seq) { - pushChromosome.call(this, current, order); - } - } - - function pushChromosome(current, order) { - const length = current.length || (current.offset + current.seq.length); - if (!chrNameSet.has(current.chr)) { - this.chromosomeNames.push(current.chr); - this.sequences.set(current.chr, []); - this.chromosomes[current.chr] = new Chromosome(current.chr, order, length); - chrNameSet.add(current.chr); - } else { - const c = this.chromosomes[current.chr]; - c.bpLength = Math.max(c.bpLength, length); - } - this.sequences.get(current.chr).push(new SequenceSlice(current.offset, current.seq)); - } - } -} - -class SequenceSlice { - - constructor(offset, sequence) { - this.offset = offset; - this.sequence = sequence; - } - - contains(start, end) { - return this.offset <= start && this.end >= end - } - - overlaps(start, end) { - return this.offset < end && this.end > start - } - - get end() { - return this.offset + this.sequence.length - } - -} - -const GenomicInterval = function (chr, start, end, features) { - this.chr = chr; - this.start = start; - this.end = end; - this.features = features; -}; - -GenomicInterval.prototype.contains = function (chr, start, end) { - return this.chr === chr && - this.start <= start && - this.end >= end -}; - -GenomicInterval.prototype.containsRange = function (range) { - return this.chr === range.chr && - this.start <= range.start && - this.end >= range.end -}; - -/* - * The MIT License (MIT) - * - * Copyright (c) 2014 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -const splitLines$3 = splitLines$5; - -const reservedProperties = new Set(['fastaURL', 'indexURL', 'compressedIndexURL', 'cytobandURL', 'indexed']); - -class FastaSequence { - - constructor(reference) { - - this.file = reference.fastaURL; - this.indexFile = reference.indexURL || reference.indexFile || this.file + ".fai"; - this.compressedIndexFile = reference.compressedIndexURL || false; - this.withCredentials = reference.withCredentials; - this.chromosomeNames = []; - this.chromosomes = {}; - this.sequences = {}; - this.offsets = {}; - - // Build a track-like config object from the referenceObject - const config = {}; - for (let key in reference) { - if (reference.hasOwnProperty(key) && !reservedProperties.has(key)) { - config[key] = reference[key]; - } - } - this.config = config; - } - - - async init() { - return this.getIndex() - } - - async getSequence(chr, start, end) { - - const hasCachedSquence = this.interval && this.interval.contains(chr, start, end); - - if (!hasCachedSquence) { - - // Expand query, to minimum of 50kb - let qstart = start; - let qend = end; - if ((end - start) < 50000) { - const w = (end - start); - const center = Math.round(start + w / 2); - qstart = Math.max(0, center - 25000); - qend = center + 25000; - } - - const seqBytes = await this.readSequence(chr, qstart, qend); - this.interval = new GenomicInterval(chr, qstart, qend, seqBytes); - } - - const offset = start - this.interval.start; - const n = end - start; - const seq = this.interval.features ? this.interval.features.substr(offset, n) : null; - return seq - } - - async getIndex() { - - if (this.index) { - return this.index - } else { - const data = await igvxhr.load(this.indexFile, buildOptions$1(this.config)); - const lines = splitLines$3(data); - const len = lines.length; - let lineNo = 0; - let order = 0; - this.index = {}; - - while (lineNo < len) { - const tokens = lines[lineNo++].split("\t"); - const nTokens = tokens.length; - - if (nTokens === 5) { - // Parse the index line. - const chr = tokens[0]; - const size = parseInt(tokens[1]); - const position = parseInt(tokens[2]); - const basesPerLine = parseInt(tokens[3]); - const bytesPerLine = parseInt(tokens[4]); - - const indexEntry = { - size: size, - position: position, - basesPerLine: basesPerLine, - bytesPerLine: bytesPerLine - }; - - this.chromosomeNames.push(chr); - this.index[chr] = indexEntry; - this.chromosomes[chr] = new Chromosome(chr, order++, size); - } - } - return this.index - } - } - - - //Code is losely based on https://github.com/GMOD/bgzf-filehandle - //Reworked however in orde to work with the igvxhr interface for loading files - //Additionally, replaced calls to the Long.js interface with standard JS calls for ArrayBuffers and the associated views - // - //The compressed index is an array of blocks, with each block being a pair: compressed-position & uncompressed-position (both in bytes) - async getCompressedIndex() { - const GZI_NUM_BYTES_OFFSET = 8; - const GZI_NUM_BYTES_BLOCK = 8; - if (this.compressedIndex) { - return this.compressedIndex - } - if (!this.compressedIndexFile) { - this.compressedIndex = []; - return this.compressedIndex - } - //In contrast to the 'normal' reference (for which the index is chromosome based), this index is block-based - //As such there is not need to make it a hash. An array is sufficient. - this.compressedIndex = []; - const gziData = await igvxhr.loadArrayBuffer(this.compressedIndexFile, buildOptions$1(this.config)); - const givenFileSize = gziData.byteLength; - if (givenFileSize < GZI_NUM_BYTES_OFFSET) { - console.log("Cannot parse GZI index file: length (" + givenFileSize + " bytes) is insufficient to determine content of index."); - return this.compressedIndex - } - //First 8 bytes are a little endian unsigned bigint (64bit), indicating the number of blocks in the index. - const numBlocksBuffer = gziData.slice(0, GZI_NUM_BYTES_OFFSET); - const numBlocks = Number((new DataView(numBlocksBuffer)).getBigUint64(0, true)); - //The remainder of the gzi content are pairs of little endian unsigned bigint (64bit) numbers. - //The first of the pair is the compressed position of a block - //The second of the pair is the uncompressed position of a block - - //Sanity check: - //Is the size of the array-buffer (of the entire file) correct with regards to the number of blocks detailled by the first 8 bytes of the file? - //Total file-size should be: - // 8 + 2*(num_entries*8) bytes, with the first 8 bytes indicating the number of entries - const expectedFileSize = GZI_NUM_BYTES_OFFSET + numBlocks * 2 * GZI_NUM_BYTES_BLOCK; - if (givenFileSize != expectedFileSize) { - console.log("Incorrect file size of reference genome index. Expected : " + expectedFileSize + ". Received : " + givenFileSize); - return this.compressedIndex - } - - //Push the first block to the index: the first block always has positions 0 for both the compressed and uncompressed file - this.compressedIndex.push([0, 0]); - - //Further process all the blocks of the GZI index, and keep them in memory - for (let blockNumber = 0; blockNumber < numBlocks; blockNumber++) { - const bufferBlockStart = GZI_NUM_BYTES_OFFSET + blockNumber * 2 * GZI_NUM_BYTES_BLOCK; - const bufferBlockEnd = GZI_NUM_BYTES_OFFSET + blockNumber * 2 * GZI_NUM_BYTES_BLOCK + 2 * GZI_NUM_BYTES_BLOCK; - const bufferBlock = gziData.slice(bufferBlockStart, bufferBlockEnd); - const viewBlock = new DataView(bufferBlock); - const compressedPosition = Number(viewBlock.getBigUint64(0, true)); //First 8 bytes - const uncompressedPosition = Number(viewBlock.getBigUint64(GZI_NUM_BYTES_BLOCK, true)); //Last 8 bytes - this.compressedIndex.push([compressedPosition, uncompressedPosition]); - } - return this.compressedIndex - } - - //The Fasta-index gives a byte-position of the chromosomal sequences within the FASTA file. - //These locations need to be remapped to the locations within the zipped reference genome, using the GZI index - //This function provides this functionality by - //1) taking the indicated start/stop byte locations within the UNCOMPRESSED FASTA file - //2) remapping these byte locations to the correct blocks (and associated positions) within the COMPRESSED FASTA file - //Subsequently, the calling method can then extract the correct blocks from the compressed FASTA files and uncompressed the data - async getRelevantCompressedBlockNumbers(queryPositionStart, queryPositionEnd) { - const UNCOMPRESSED_POSITION = 1; - //Fallback for impossible values - if (queryPositionStart < 0 || queryPositionEnd < 0 || queryPositionEnd < queryPositionStart) { - console.log("Incompatible query positions for reference-genome. Start:" + queryPositionStart + " | End:" + queryPositionEnd); - return [] - } - //Ensure compressed index is loaded - await this.getCompressedIndex(); - let result = []; - //Now search for the correct block-numbers (going from 0 to length(compressed-index)) which overlap with the provided byte-positions - const lowestBlockNumber = 0; - const highestBlockNumber = this.compressedIndex.length - 1; - //Failsafe if for some reason the compressed index wasn't loaded or doesn't contain any data - if (this.compressedIndex.length == 0) { - console.log("Compressed index does not contain any content"); - return [] - } - //Failsafe: if the queryPositionStart is greater than the uncompressed-position of the final block, - //then this final block is the only possible result - if (queryPositionStart > (this.compressedIndex)[highestBlockNumber][UNCOMPRESSED_POSITION]) { - return [highestBlockNumber] - } - - //Rather than doing a linear search over all blocks, a binary search is done for speed considerations - //We are searching for the highest block number for which its position is smaller than the query start position - //Afterwards we will simply expand the blocks until the entire query range is covered - let searchLow = lowestBlockNumber; - let searchHigh = highestBlockNumber; - let searchPosition = Math.floor(this.compressedIndex.length / 2); - let maxIterations = this.compressedIndex.length + 1; - let solutionFound = false; - //instead of doing a while(true), this for-loop prevents eternal loops in case of issues - for (let iteration = 0; iteration < maxIterations; iteration++) { - const searchUncompressedPosition = (this.compressedIndex)[searchPosition][UNCOMPRESSED_POSITION]; - const nextSearchUncompressedPosition = (searchPosition < (this.compressedIndex.length - 1)) ? (this.compressedIndex)[searchPosition + 1][UNCOMPRESSED_POSITION] : Infinity; - //The query position lies within the current search block - if (searchUncompressedPosition <= queryPositionStart && nextSearchUncompressedPosition > queryPositionStart) { - solutionFound = true; - break //searchPosition is the correct block number index - } - //Current block lies before the query position - else if (searchUncompressedPosition < queryPositionStart) { - searchLow = searchPosition + 1; - } - //Current block lies after the query position - else { - searchHigh = searchPosition - 1; - } - searchPosition = Math.ceil((searchHigh - searchLow) / 2) + searchLow; - } - //If for some reason the binary search did not reveal a correct block index, then we return the empty result - if (!solutionFound) { - console.log("No blocks within compressed index found that correspond with query positions " + queryPositionStart + "," + queryPositionEnd); - console.log(this.compressedIndex); - return [] - } - - //Now extend the result by adding additional blocks until the entire query range is covered - result.push(searchPosition); - for (let blockIndex = searchPosition + 1; blockIndex < this.compressedIndex.length; blockIndex++) { - result.push(blockIndex); - const blockUncompressedPosition = (this.compressedIndex)[blockIndex][UNCOMPRESSED_POSITION]; - if (blockUncompressedPosition >= queryPositionEnd) { - break - } - } - - //It is possible that the query end position lies AFTER the start of the final block - //If this is the case, we add a 'fake' negative index which will be interpreted by the loadAndUncompressBlocks method as an indicator - //to read until the end of the file - const finalRelevantBlock = result[result.length - 1]; - const finalIndexBlock = this.compressedIndex.length - 1; - if (finalRelevantBlock === finalIndexBlock && (this.compressedIndex)[finalRelevantBlock][UNCOMPRESSED_POSITION] < queryPositionEnd) { - result.push(-1); - } - - return result - } - - - //Load the content from the blockIndices. - //This is done on a per-block basis - //Content of the first block will be trimmed in order to match the expected offset - async loadAndUncompressBlocks(blockIndices, startByte) { - const COMPRESSED_POSITION = 0; - const UNCOMPRESSED_POSITION = 1; - //Normally the compressed index should already exist, we're just makeing sure here - await this.getCompressedIndex(); - - if (blockIndices.length == 0) { - return "" - } - - //Storing data in seperate array with indices in order to assert order due to async behaviour of loops - let resultCache = Array(blockIndices.length - 1); - for (let i = 0; i < blockIndices.length - 1; i++) { - const currentBlockNumber = blockIndices[i]; - const currentBlockInfo = (this.compressedIndex)[currentBlockNumber]; - const currentBlockCompressedPosition = currentBlockInfo[COMPRESSED_POSITION]; - - const nextBlockNumber = blockIndices[i + 1]; - let compressedBytes = []; - if (nextBlockNumber != -1) { //default : read current entire block only - const nextBlockInfo = (this.compressedIndex)[nextBlockNumber]; - const nextBlockCompressedPosition = nextBlockInfo[COMPRESSED_POSITION]; - const compressedLength = nextBlockCompressedPosition - currentBlockCompressedPosition; - compressedBytes = await igvxhr.loadArrayBuffer(this.file, buildOptions$1(this.config, { - range: { - start: currentBlockCompressedPosition, - size: compressedLength - } - })); - } else { // special case for query within final block: read until the end of the file - compressedBytes = await igvxhr.loadArrayBuffer(this.file, buildOptions$1(this.config, { - range: { - start: currentBlockCompressedPosition - } - })); - } - //now unzip the compressed bytes, and store them in the resultCache - const uncompressedBytes = await unbgzf(compressedBytes); - resultCache[i] = uncompressedBytes; - } - - //Iterate over the result cache, create sequences from the data, and create a full sequence string from the data - let result = ""; - for (let i = 0; i < resultCache.length; i++) { - for (let j = 0; j < resultCache[i].length; j++) { - const c = String.fromCharCode(resultCache[i][j]); - result = result + c; - } - } - - //postprocess this data: because entire blocks are read we need to remove the first N bases of the first used block, - //which are not included in the original query positions - const firstBlockInfo = (this.compressedIndex)[blockIndices[0]]; - const offset = startByte - firstBlockInfo[UNCOMPRESSED_POSITION]; - result = result.substring(offset); - - return result - } - - - async readSequence(chr, qstart, qend) { - - await this.getIndex(); - await this.getCompressedIndex(); //This will work even if no compressed index file is set - - const idxEntry = this.index[chr]; - if (!idxEntry) { - console.log("No index entry for chr: " + chr); - // Tag interval with null so we don't try again - this.interval = new GenomicInterval(chr, qstart, qend, null); - return null - } - - const start = Math.max(0, qstart); // qstart should never be < 0 - const end = Math.min(idxEntry.size, qend); - const bytesPerLine = idxEntry.bytesPerLine; - const basesPerLine = idxEntry.basesPerLine; - const position = idxEntry.position; - const nEndBytes = bytesPerLine - basesPerLine; - const startLine = Math.floor(start / basesPerLine); - const endLine = Math.floor(end / basesPerLine); - const base0 = startLine * basesPerLine; // Base at beginning of start line - const offset = start - base0; - const startByte = position + startLine * bytesPerLine + offset; - const base1 = endLine * basesPerLine; - const offset1 = end - base1; - const endByte = position + endLine * bytesPerLine + offset1 - 1; - const byteCount = endByte - startByte + 1; - - if (byteCount <= 0) { - console.error("No sequence for " + chr + ":" + qstart + "-" + qend); - return null - } - - //If the compressed index file is set, then we are dealing with a compressed genome sequence - //The selection of startByte/endByte is done for the non-compressed genome sequence. - //These need to be 'converted' to the correct byte positions in the compressed genome sequence, - //by making use of the compressed index (GZI file) - let allBytes; - if (!this.compressedIndexFile) { - allBytes = await igvxhr.load(this.file, buildOptions$1(this.config, { - range: { - start: startByte, - size: byteCount - } - })); - } else { - let relevantBlockIndices = await this.getRelevantCompressedBlockNumbers(startByte, endByte); - if (relevantBlockIndices.length === 0) { - console.log("No blocks in the compressed index that correspond with the requested byte positions (" + startByte + "," + endByte + ")"); - return null - } - allBytes = await this.loadAndUncompressBlocks(relevantBlockIndices, startByte); - } - - if (!allBytes) { - return null - } - - let nBases, - seqBytes = "", - srcPos = 0, - allBytesLength = allBytes.length; - - if (offset > 0) { - nBases = Math.min(end - start, basesPerLine - offset); - seqBytes += allBytes.substr(srcPos, nBases); - srcPos += (nBases + nEndBytes); - } - - while (srcPos < allBytesLength) { - nBases = Math.min(basesPerLine, allBytesLength - srcPos); - seqBytes += allBytes.substr(srcPos, nBases); - srcPos += (nBases + nEndBytes); - } - - return seqBytes - - } -} - -/* - * The MIT License (MIT) - * - * Copyright (c) 2014 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -const splitLines$2 = splitLines$5; - -class ChromSizes { - - - constructor(url) { - this.url = url; - this.chromosomeNames = []; - this.chromosomes = {}; - } - - - async init() { - return this.loadAll() - } - - async getSequence(chr, start, end) { - - return undefined // TODO -- return array of "N"s? - } - - async loadAll() { - - let data; - if (isDataURL(this.url)) { - let bytes = decodeDataURI$1(this.fastaURL); - data = ""; - for (let b of bytes) { - data += String.fromCharCode(b); - } - } else { - data = await igvxhr.load(this.url, {}); - } - - - this.chromosomeNames = []; - this.chromosomes = {}; - - const lines = splitLines$2(data); - let order = 0; - for (let nextLine of lines) { - const tokens = nextLine.split('\t'); - this.chromosomeNames.push(tokens[0]); - const chrLength = Number.parseInt(tokens[1]); - const chromosome = new Chromosome(tokens[0], order++, chrLength); - this.chromosomes[tokens[0]] = chromosome; - - } - } - -} - -async function loadFasta(reference) { - - let fasta; - if ("chromsizes" === reference.format) { - fasta = new ChromSizes(reference.fastaURL); - } else if (isDataURL(reference.fastaURL) || reference.indexed === false) { - fasta = new NonIndexedFasta(reference); - } else { - fasta = new FastaSequence(reference); - } - await fasta.init(); - return fasta -} - -const defaultNucleotideColors = { - "A": "rgb( 0, 200, 0)", - "C": "rgb( 0,0,200)", - "T": "rgb(255,0,0)", - "G": "rgb(209,113, 5)", - "N": "rgb(80,80,80)" -}; - -/* - * The MIT License (MIT) - * - * Copyright (c) 2014 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -const defaultSequenceTrackOrder = Number.MIN_SAFE_INTEGER; - -const translationDict = { - 'TTT': 'F', - 'TTC': 'F', - 'TTA': 'L', - 'TTG': 'L', - 'CTT': 'L', - 'CTC': 'L', - 'CTA': 'L', - 'CTG': 'L', - 'ATT': 'I', - 'ATC': 'I', - 'ATA': 'I', - 'ATG': 'M', - 'GTT': 'V', - 'GTC': 'V', - 'GTA': 'V', - 'GTG': 'V', - 'TCT': 'S', - 'TCC': 'S', - 'TCA': 'S', - 'TCG': 'S', - 'CCT': 'P', - 'CCC': 'P', - 'CCA': 'P', - 'CCG': 'P', - 'ACT': 'T', - 'ACC': 'T', - 'ACA': 'T', - 'ACG': 'T', - 'GCT': 'A', - 'GCC': 'A', - 'GCA': 'A', - 'GCG': 'A', - 'TAT': 'Y', - 'TAC': 'Y', - 'TAA': 'STOP', - 'TAG': 'STOP', - 'CAT': 'H', - 'CAC': 'H', - 'CAA': 'Q', - 'CAG': 'Q', - 'AAT': 'N', - 'AAC': 'N', - 'AAA': 'K', - 'AAG': 'K', - 'GAT': 'D', - 'GAC': 'D', - 'GAA': 'E', - 'GAG': 'E', - 'TGT': 'C', - 'TGC': 'C', - 'TGA': 'STOP', - 'TGG': 'W', - 'CGT': 'R', - 'CGC': 'R', - 'CGA': 'R', - 'CGG': 'R', - 'AGT': 'S', - 'AGC': 'S', - 'AGA': 'R', - 'AGG': 'R', - 'GGT': 'G', - 'GGC': 'G', - 'GGA': 'G', - 'GGG': 'G' -}; - -const complement = {}; -const t1 = ['A', 'G', 'C', 'T', 'Y', 'R', 'W', 'S', 'K', 'M', 'D', 'V', 'H', 'B', 'N', 'X']; -const t2 = ['T', 'C', 'G', 'A', 'R', 'Y', 'W', 'S', 'M', 'K', 'H', 'B', 'D', 'V', 'N', 'X']; -for (let i = 0; i < t1.length; i++) { - complement[t1[i]] = t2[i]; - complement[t1[i].toLowerCase()] = t2[i].toLowerCase(); -} - -const DEFAULT_HEIGHT = 25; -const TRANSLATED_HEIGHT = 115; -const SEQUENCE_HEIGHT = 15; -const FRAME_HEIGHT = 25; -const FRAME_BORDER = 5; -const BP_PER_PIXEL_THRESHOLD = 1 / 10; - -const bppFeatureFetchThreshold = 10; - -class SequenceTrack { - - constructor(config, browser) { - - this.config = config; - this.browser = browser; - this.type = "sequence"; - this.removable = config.removable === undefined ? true : config.removable; // Defaults to true - this.name = config.name; - this.id = config.id; - this.sequenceType = config.sequenceType || "dna"; // dna | rna | prot - this.disableButtons = false; - this.order = config.order || defaultSequenceTrackOrder; - this.ignoreTrackMenu = false; - - this.reversed = config.reversed === true; - this.frameTranslate = config.frameTranslate === true; - this.height = this.frameTranslate ? TRANSLATED_HEIGHT : DEFAULT_HEIGHT; - - // Hack for backward compatibility - if(config.url) { - config.fastaURL = config.url; - } - - if(!config.fastaURL) { - // Mark this as the genome reference sequence ==> backward compatibility convention - this.id = config.id || "sequence"; - } - - } - - menuItemList() { - return [ - { - name: this.reversed ? "Forward" : "Reverse", - click: () => { - this.reversed = !this.reversed; - this.trackView.repaintViews(); - } - }, - { - name: this.frameTranslate ? "Close Translation" : "Three-frame Translate", - click: () => { - this.frameTranslate = !this.frameTranslate; - if (this.frameTranslate) { - for (let vp of this.trackView.viewports) { - vp.setContentHeight(TRANSLATED_HEIGHT); - } - this.trackView.setTrackHeight(TRANSLATED_HEIGHT); - } else { - for (let vp of this.trackView.viewports) { - vp.setContentHeight(DEFAULT_HEIGHT); - } - this.trackView.setTrackHeight(DEFAULT_HEIGHT); - } - this.trackView.repaintViews(); - - } - } - ] - } - - contextMenuItemList(clickState) { - const viewport = clickState.viewport; - if (viewport.referenceFrame.bpPerPixel <= 1) { - const pixelWidth = viewport.getWidth(); - const bpWindow = pixelWidth * viewport.referenceFrame.bpPerPixel; - const chr = viewport.referenceFrame.chr; - const start = Math.floor(viewport.referenceFrame.start); - const end = Math.ceil(start + bpWindow); - const items = [ - { - label: this.reversed ? 'View visible sequence (reversed)...' : 'View visible sequence...', - click: async () => { - let seq = await this.browser.genome.sequence.getSequence(chr, start, end); - if (!seq) { - seq = "Unknown sequence"; - } else if (this.reversed) { - seq = reverseComplementSequence(seq); - } - this.browser.alert.present(seq); - } - } - ]; - if (isSecureContext()) { - items.push({ - label: 'Copy visible sequence', - click: async () => { - let seq = await this.browser.genome.sequence.getSequence(chr, start, end); - if (!seq) { - seq = "Unknown sequence"; - } else if (this.reversed) { - seq = reverseComplementSequence(seq); - } - try { - await navigator.clipboard.writeText(seq); - } catch (e) { - console.error(e); - this.browser.alert.present(`error copying sequence to clipboard ${e}`); - } - } - - }); - } - items.push('
'); - - return items - } else { - return undefined - } - } - - translateSequence(seq) { - - const threeFrame = [[], [], []]; - - for (let fNum of [0, 1, 2]) { - let idx = fNum; - - while ((seq.length - idx) >= 3) { - let st = seq.slice(idx, idx + 3); - if (this.reversed) { - st = st.split('').reverse().join(''); - } - - const aa = translationDict[st.toUpperCase()] || ""; - threeFrame[fNum].push({ - codons: st, - aminoA: aa - }); - idx += 3; - } - } - - return threeFrame - } - - /** - * Return the source for sequence. If an explicit fasta url is defined, use it, otherwise fetch sequence - * from the current genome - * * - * @returns {Promise} - */ - async getSequenceSource() { - if(this.config.fastaURL) { - if(!this.fasta) { - this.fasta = new WrappedFasta(this.config, this.browser.genome); - await this.fasta.init(); - } - return this.fasta - } else { - return this.browser.genome.sequence - } - } - - async getFeatures(chr, start, end, bpPerPixel) { - - start = Math.floor(start); - end = Math.floor(end); - - if (bpPerPixel && bpPerPixel > bppFeatureFetchThreshold) { - return null - } else { - const sequenceSource = await this.getSequenceSource(); - const sequence = await sequenceSource.getSequence(chr, start, end); - return { - bpStart: start, - sequence: sequence - } - } - } - - draw(options) { - - const ctx = options.context; - - if (options.features) { - - let sequence = options.features.sequence; - if(!sequence) { - return - } - - if (this.reversed) { - sequence = sequence.split('').map(function (cv) { - return complement[cv] - }).join(''); - } - - const sequenceBpStart = options.features.bpStart; // genomic position at start of sequence - const bpEnd = 1 + options.bpStart + (options.pixelWidth * options.bpPerPixel); - - for (let bp = Math.floor(options.bpStart); bp <= bpEnd; bp++) { - - const seqIdx = Math.floor(bp - sequenceBpStart); - - if (seqIdx >= 0 && seqIdx < sequence.length) { - - const offsetBP = bp - options.bpStart; - const aPixel = offsetBP / options.bpPerPixel; - const pixelWidth = 1 / options.bpPerPixel; - const baseLetter = sequence[seqIdx]; - const color = this.fillColor(baseLetter.toUpperCase()); - - if (options.bpPerPixel > BP_PER_PIXEL_THRESHOLD) { - IGVGraphics.fillRect(ctx, aPixel, FRAME_BORDER, pixelWidth, SEQUENCE_HEIGHT - FRAME_BORDER, {fillStyle: color}); - } else { - const textPixel = aPixel + 0.5 * (pixelWidth - ctx.measureText(baseLetter).width); - - - - - if ('y' === options.axis) { - ctx.save(); - IGVGraphics.labelTransformWithContext(ctx, textPixel); - IGVGraphics.strokeText(ctx, baseLetter, textPixel, SEQUENCE_HEIGHT, {strokeStyle: color}); - ctx.restore(); - } else { - IGVGraphics.strokeText(ctx, baseLetter, textPixel, SEQUENCE_HEIGHT, {strokeStyle: color}); - } - - } - } - } - - if (this.frameTranslate) { - - let y = SEQUENCE_HEIGHT + 2 * FRAME_BORDER; - const translatedSequence = this.translateSequence(sequence); - - for (let fNum = 0; fNum < translatedSequence.length; fNum++) { // == 3, 1 for each frame - - const aaSequence = translatedSequence[fNum]; // AA sequence for this frame - - for (let idx = 0; idx < aaSequence.length; idx++) { - - let color = 0 === idx % 2 ? 'rgb(160,160,160)' : 'rgb(224,224,224)'; - const cv = aaSequence[idx]; - - const bpPos = sequenceBpStart + fNum + (idx * 3); - const bpOffset = bpPos - options.bpStart; - const p0 = Math.floor(bpOffset / options.bpPerPixel); - const p1 = Math.floor((bpOffset + 3) / options.bpPerPixel); - const pc = Math.round((p0 + p1) / 2); - - if (p1 < 0) { - continue // off left edge - } else if (p0 > options.pixelWidth) { - break // off right edge - } - - let aaLabel = cv.aminoA; - if (cv.aminoA.indexOf('STOP') > -1) { - color = 'rgb(255, 0, 0)'; - aaLabel = 'STOP'; //Color blind accessible - } else if (cv.aminoA === 'M') { - color = 'rgb(0, 153, 0)'; - aaLabel = 'START'; //Color blind accessible - } - - IGVGraphics.fillRect(ctx, p0, y, p1 - p0, FRAME_HEIGHT, {fillStyle: color}); - - if (options.bpPerPixel <= 1 / 10) { - IGVGraphics.strokeText(ctx, aaLabel, pc - (ctx.measureText(aaLabel).width / 2), y + 15); - } - } - y += (FRAME_HEIGHT + FRAME_BORDER); - } - } - } - } - - get supportsWholeGenome() { - return false - } - - computePixelHeight(ignore) { - this.height = this.frameTranslate ? TRANSLATED_HEIGHT : DEFAULT_HEIGHT; - return this.height - } - - fillColor(index) { - - if (this.color) { - return this.color - } else if ("dna" === this.sequenceType) { - // return this.browser.nucleotideColors[index] || 'gray' - return defaultNucleotideColors[index] || 'gray' - } else { - return 'rgb(0, 0, 150)' - } - } - - /** - * Return the current state of the track. Used to create sessions and bookmarks. - * - * @returns {*|{}} - */ - getState() { - const config = { - type: "sequence" - }; - if (this.order !== defaultSequenceTrackOrder) { - config.order = this.order; - } - if (this.reversed) { - config.revealed = true; - } - return config - } - -} - -/** - * Wrapper for a Fasta object that does chr name alias translation. This is not neccessary for the genome fasta, - * as it defines the reference name, but can be neccessary if loading an additional fasta as a track - * - */ -class WrappedFasta { - - constructor(config, genome) { - this.config = config; - this.genome = genome; - } - - async init() { - this.fasta = await loadFasta(this.config); - this.chrNameMap = new Map(); - for(let name of this.fasta.chromosomeNames) { - this.chrNameMap.set(this.genome.getChromosomeName(name), name); - } - } - - async getSequence(chr, start, end) { - const chrName = this.chrNameMap.has(chr) ? this.chrNameMap.get(chr) : chr; - return this.fasta.getSequence(chrName, start, end) - } - -} - -/* - * The MIT License (MIT) - * - * Copyright (c) 2014 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -class Viewport { - - constructor(trackView, viewportColumn, referenceFrame, width) { - - this.guid = domUtils$1.guid(); - this.trackView = trackView; - this.referenceFrame = referenceFrame; - - this.browser = trackView.browser; - - this.$viewport = $$1('
'); - viewportColumn.appendChild(this.$viewport.get(0)); - - if (trackView.track.height) { - this.$viewport.get(0).style.height = `${trackView.track.height}px`; - } - - // Create an alert dialog for the sequence track to copy ref sequence to. - if (trackView.track instanceof SequenceTrack) { - this.alert = new AlertDialog$1(this.$viewport.get(0)); - } - - this.contentTop = 0; - this.contentHeight = this.$viewport.height(); - - - this.$viewport.width(width); - - this.initializationHelper(); - - } - - initializationHelper() { - - } - - showMessage(message) { - if (!this.messageDiv) { - this.messageDiv = document.createElement('div'); - this.messageDiv.className = 'igv-viewport-message'; - //this.contentDiv.append(this.messageDiv) - this.$viewport.append($$1(this.messageDiv)); - } - this.messageDiv.textContent = message; - this.messageDiv.style.display = 'inline-block'; - } - - hideMessage(message) { - if (this.messageDiv) - this.messageDiv.style.display = 'none'; - } - - setTrackLabel(label) { - } - - startSpinner() { - } - - stopSpinner() { - } - - checkZoomIn() { - return true - } - - shift() { - } - - setTop(contentTop) { - - this.contentTop = contentTop; - this.$viewport.height(); - - //this.$content.css('top', `${contentTop}px`) - // - // if (undefined === this.canvasVerticalRange || this.canvasVerticalRange.bottom < viewBottom || this.canvasVerticalRange.top > viewTop) { - // console.log("Repaint " + this.canvasVerticalRange) - // this.repaint() - // } - - } - - async loadFeatures() { - return undefined - } - - clearCache() { - - } - - async repaint() { - } - - draw(drawConfiguration, features, roiFeatures) { - console.log('Viewport - draw(drawConfiguration, features, roiFeatures)'); - } - - checkContentHeight(features) { - - let track = this.trackView.track; - features = features || this.cachedFeatures; - if ("FILL" === track.displayMode) { - this.setContentHeight(this.$viewport.height()); - } else if (typeof track.computePixelHeight === 'function') { - if (features && features.length > 0) { - let requiredContentHeight = track.computePixelHeight(features); - //let currentContentHeight = this.$content.height() - let currentContentHeight = this.contentHeight; - if (requiredContentHeight !== currentContentHeight) { - this.setContentHeight(requiredContentHeight); - } - } - } - } - - getContentHeight() { - //return this.$content.height() - return this.contentHeight - } - - setContentHeight(contentHeight) { - this.contentHeight = contentHeight; - } - - isLoading() { - return false - } - - saveSVG() { - - } - - isVisible() { - return this.$viewport.width() - } - - setWidth(width) { - this.$viewport.width(width); - } - - getWidth() { - return this.$viewport.width() - } - - getContentTop() { - return this.contentTop - } - - containsPosition(chr, position) { - console.log('Viewport - containsPosition(chr, position)'); - } - - addMouseHandlers() { - } - - removeMouseHandlers() { - } - - /** - * Called when the associated track is removed. Do any needed cleanup here. - */ - dispose() { - - if (this.popover) { - this.popover.dispose(); - } - - this.$viewport.get(0).remove(); - - // Null out all properties -- this should not be neccessary, but just in case there is a - // reference to self somewhere we want to free memory. - for (let key of Object.keys(this)) { - this[key] = undefined; - } - } - -} - -/*!! - * Canvas 2 Svg v1.0.19 - * A low level canvas to SVG converter. Uses a mock canvas context to build an SVG document. - * - * Licensed under the MIT license: - * http://www.opensource.org/licenses/mit-license.php - * - * Author: - * Kerry Liu - * - * Copyright (c) 2014 Gliffy Inc. - */ - -//helper function to format a string -function format(str, args) { - var keys = Object.keys(args), i; - for (i = 0; i < keys.length; i++) { - str = str.replace(new RegExp("\\{" + keys[i] + "\\}", "gi"), args[keys[i]]); - } - return str -} - -//helper function that generates a random string -function randomString(holder) { - var chars, randomstring, i; - if (!holder) { - throw new Error("cannot create a random attribute name for an undefined object") - } - chars = "ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz"; - randomstring = ""; - do { - randomstring = ""; - for (i = 0; i < 12; i++) { - randomstring += chars[Math.floor(Math.random() * chars.length)]; - } - } while (holder[randomstring]) - return randomstring -} - -//helper function to map named to numbered entities -function createNamedToNumberedLookup(items, radix) { - var i, entity, lookup = {}, base10; - items = items.split(','); - radix = radix || 10; - // Map from named to numbered entities. - for (i = 0; i < items.length; i += 2) { - entity = '&' + items[i + 1] + ';'; - base10 = parseInt(items[i], radix); - lookup[entity] = '&#' + base10 + ';'; - } - //FF and IE need to create a regex from hex values ie   == \xa0 - lookup["\\xa0"] = ' '; - return lookup -} - -//helper function to map canvas-textAlign to svg-textAnchor -function getTextAnchor(textAlign) { - //TODO: support rtl languages - var mapping = {"left": "start", "right": "end", "center": "middle", "start": "start", "end": "end"}; - return mapping[textAlign] || mapping.start -} - -//helper function to map canvas-textBaseline to svg-dominantBaseline -function getDominantBaseline(textBaseline) { - //INFO: not supported in all browsers - var mapping = { - "alphabetic": "alphabetic", - "hanging": "hanging", - "top": "text-before-edge", - "bottom": "text-after-edge", - "middle": "central" - }; - return mapping[textBaseline] || mapping.alphabetic -} - - -/** - * Return a new normalized vector of given vector - */ -function normalize(vector) { - var len = Math.sqrt(vector[0] * vector[0] + vector[1] * vector[1]); - return [vector[0] / len, vector[1] / len] -} - - -function intersectRect(rect1, rect2) { - return (rect1.x < rect2.x + rect2.width && - rect1.x + rect1.width > rect2.x && - rect1.y < rect2.y + rect2.height && - rect1.y + rect1.height > rect2.y) -} - - -// Unpack entities lookup where the numbers are in radix 32 to reduce the size -// entity mapping courtesy of tinymce -const namedEntities = createNamedToNumberedLookup( - '50,nbsp,51,iexcl,52,cent,53,pound,54,curren,55,yen,56,brvbar,57,sect,58,uml,59,copy,' + - '5a,ordf,5b,laquo,5c,not,5d,shy,5e,reg,5f,macr,5g,deg,5h,plusmn,5i,sup2,5j,sup3,5k,acute,' + - '5l,micro,5m,para,5n,middot,5o,cedil,5p,sup1,5q,ordm,5r,raquo,5s,frac14,5t,frac12,5u,frac34,' + - '5v,iquest,60,Agrave,61,Aacute,62,Acirc,63,Atilde,64,Auml,65,Aring,66,AElig,67,Ccedil,' + - '68,Egrave,69,Eacute,6a,Ecirc,6b,Euml,6c,Igrave,6d,Iacute,6e,Icirc,6f,Iuml,6g,ETH,6h,Ntilde,' + - '6i,Ograve,6j,Oacute,6k,Ocirc,6l,Otilde,6m,Ouml,6n,times,6o,Oslash,6p,Ugrave,6q,Uacute,' + - '6r,Ucirc,6s,Uuml,6t,Yacute,6u,THORN,6v,szlig,70,agrave,71,aacute,72,acirc,73,atilde,74,auml,' + - '75,aring,76,aelig,77,ccedil,78,egrave,79,eacute,7a,ecirc,7b,euml,7c,igrave,7d,iacute,7e,icirc,' + - '7f,iuml,7g,eth,7h,ntilde,7i,ograve,7j,oacute,7k,ocirc,7l,otilde,7m,ouml,7n,divide,7o,oslash,' + - '7p,ugrave,7q,uacute,7r,ucirc,7s,uuml,7t,yacute,7u,thorn,7v,yuml,ci,fnof,sh,Alpha,si,Beta,' + - 'sj,Gamma,sk,Delta,sl,Epsilon,sm,Zeta,sn,Eta,so,Theta,sp,Iota,sq,Kappa,sr,Lambda,ss,Mu,' + - 'st,Nu,su,Xi,sv,Omicron,t0,Pi,t1,Rho,t3,Sigma,t4,Tau,t5,Upsilon,t6,Phi,t7,Chi,t8,Psi,' + - 't9,Omega,th,alpha,ti,beta,tj,gamma,tk,delta,tl,epsilon,tm,zeta,tn,eta,to,theta,tp,iota,' + - 'tq,kappa,tr,lambda,ts,mu,tt,nu,tu,xi,tv,omicron,u0,pi,u1,rho,u2,sigmaf,u3,sigma,u4,tau,' + - 'u5,upsilon,u6,phi,u7,chi,u8,psi,u9,omega,uh,thetasym,ui,upsih,um,piv,812,bull,816,hellip,' + - '81i,prime,81j,Prime,81u,oline,824,frasl,88o,weierp,88h,image,88s,real,892,trade,89l,alefsym,' + - '8cg,larr,8ch,uarr,8ci,rarr,8cj,darr,8ck,harr,8dl,crarr,8eg,lArr,8eh,uArr,8ei,rArr,8ej,dArr,' + - '8ek,hArr,8g0,forall,8g2,part,8g3,exist,8g5,empty,8g7,nabla,8g8,isin,8g9,notin,8gb,ni,8gf,prod,' + - '8gh,sum,8gi,minus,8gn,lowast,8gq,radic,8gt,prop,8gu,infin,8h0,ang,8h7,and,8h8,or,8h9,cap,8ha,cup,' + - '8hb,int,8hk,there4,8hs,sim,8i5,cong,8i8,asymp,8j0,ne,8j1,equiv,8j4,le,8j5,ge,8k2,sub,8k3,sup,8k4,' + - 'nsub,8k6,sube,8k7,supe,8kl,oplus,8kn,otimes,8l5,perp,8m5,sdot,8o8,lceil,8o9,rceil,8oa,lfloor,8ob,' + - 'rfloor,8p9,lang,8pa,rang,9ea,loz,9j0,spades,9j3,clubs,9j5,hearts,9j6,diams,ai,OElig,aj,oelig,b0,' + - 'Scaron,b1,scaron,bo,Yuml,m6,circ,ms,tilde,802,ensp,803,emsp,809,thinsp,80c,zwnj,80d,zwj,80e,lrm,' + - '80f,rlm,80j,ndash,80k,mdash,80o,lsquo,80p,rsquo,80q,sbquo,80s,ldquo,80t,rdquo,80u,bdquo,810,dagger,' + - '811,Dagger,81g,permil,81p,lsaquo,81q,rsaquo,85c,euro', 32); - - -//Some basic mappings for attributes and default values. -const STYLES = { - "strokeStyle": { - svgAttr: "stroke", //corresponding svg attribute - canvas: "#000000", //canvas default - svg: "none", //svg default - apply: "stroke" //apply on stroke() or fill() - }, - "fillStyle": { - svgAttr: "fill", - canvas: "#000000", - svg: null, //svg default is black, but we need to special case this to handle canvas stroke without fill - apply: "fill" - }, - "lineCap": { - svgAttr: "stroke-linecap", - canvas: "butt", - svg: "butt", - apply: "stroke" - }, - "lineJoin": { - svgAttr: "stroke-linejoin", - canvas: "miter", - svg: "miter", - apply: "stroke" - }, - "miterLimit": { - svgAttr: "stroke-miterlimit", - canvas: 10, - svg: 4, - apply: "stroke" - }, - "lineWidth": { - svgAttr: "stroke-width", - canvas: 1, - svg: 1, - apply: "stroke" - }, - "globalAlpha": { - svgAttr: "opacity", - canvas: 1, - svg: 1, - apply: "fill stroke" - }, - "font": { - //font converts to multiple svg attributes, there is custom logic for this - canvas: "10px sans-serif" - }, - "shadowColor": { - canvas: "#000000" - }, - "shadowOffsetX": { - canvas: 0 - }, - "shadowOffsetY": { - canvas: 0 - }, - "shadowBlur": { - canvas: 0 - }, - "textAlign": { - canvas: "start" - }, - "textBaseline": { - canvas: "alphabetic" - }, - "lineDash": { - svgAttr: "stroke-dasharray", - canvas: [], - svg: null, - apply: "stroke" - } -}; - -/** - * - * @param gradientNode - reference to the gradient - * @constructor - */ -class CanvasGradient { - constructor(gradientNode, ctx) { - this.__root = gradientNode; - this.__ctx = ctx; - } - - /** - * Adds a color stop to the gradient root - */ - addColorStop(offset, color) { - var stop = this.__ctx.__createElement("stop"), regex, matches; - stop.setAttribute("offset", offset); - if (color && color.indexOf("rgba") !== -1) { - //separate alpha value, since webkit can't handle it - regex = /rgba\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d?\.?\d*)\s*\)/gi; - matches = regex.exec(color); - stop.setAttribute("stop-color", format("rgb({r},{g},{b})", {r: matches[1], g: matches[2], b: matches[3]})); - stop.setAttribute("stop-opacity", matches[4]); - } else { - stop.setAttribute("stop-color", color); - } - this.__root.appendChild(stop); - } -} - -class CanvasPattern { - constructor(pattern, ctx) { - this.__root = pattern; - this.__ctx = ctx; - } -} - -/** - * The mock canvas context - * @param config - options include: - * ctx - existing Context2D to wrap around - * width - width of your canvas (defaults to 500) - * height - height of your canvas (defaults to 500) - * enableMirroring - enables canvas mirroring (get image data) (defaults to false) - * document - the document object (defaults to the current document) - */ -class ctx { - constructor(config) { - - if (!(this instanceof ctx)) { - //did someone call this without new? - return new ctx(config) - } - - // clone config - this.config = config; - - //setup options - this.width = config.width; - this.height = config.height; - this.enableMirroring = config.enableMirroring || false; - - this.canvas = this; ///point back to this instance! - this.__document = document; - - // allow passing in an existing context to wrap around - // if a context is passed in, we know a canvas already exist - if (config.ctx) { - this.__ctx = config.ctx; - } else { - this.__canvas = this.__document.createElement("canvas"); - this.__ctx = this.__canvas.getContext("2d"); - } - - // give this canvas a type - this.isSVG = true; - - this.__setDefaultStyles(); - this.__stack = [this.__getStyleState()]; - this.__groupStack = []; - - // root svg element - this.__root = this.__createElement("svg"); - this.__root.setAttribute("width", this.width); - this.__root.setAttribute("height", this.height); - - // allow contents to overflow svg bbox - this.__root.setAttribute('overflow', 'visible'); - - // viewbox - if (config.viewbox) { - const str = config.viewbox.x + ' ' + config.viewbox.y + ' ' + config.viewbox.width + ' ' + config.viewbox.height; - this.__root.setAttribute("viewBox", str); - - this.viewbox = config.viewbox; - } - - // make sure we don't generate the same ids in defs - this.__ids = {}; - - // defs - this.__defs = this.__createElement("defs"); - this.__root.appendChild(this.__defs); - - this.multiLocusGap = config.multiLocusGap; - - // svg background color - let backdropConfig = - { - id: 'svg_output_backdrop', - width: '100%', - height: '100%', - fill: config.backdropColor || 'white' - }; - - let backdropRect = this.__createElement('rect', backdropConfig); - this.__root.appendChild(backdropRect); - - // root group - this.__rootGroup = this.__createElement('g', {id: 'root-group'}); - this.__root.appendChild(this.__rootGroup); - - // point current element to root group - this.__currentElement = this.__rootGroup; - } - - setWidth(width) { - - this.width = width; - this.__root.setAttribute("width", this.width); - - const str = this.config.viewbox.x + ' ' + this.config.viewbox.y + ' ' + width + ' ' + this.config.viewbox.height; - this.__root.setAttribute("viewBox", str); - - }; - - setHeight(height) { - - this.height = height; - this.__root.setAttribute("height", this.height); - - const str = this.config.viewbox.x + ' ' + this.config.viewbox.y + ' ' + this.config.viewbox.width + ' ' + height; - this.__root.setAttribute("viewBox", str); - - }; - - /** - * Creates the specified svg element - * @private - */ - __createElement(elementName, properties, resetFill) { - - if (typeof properties === "undefined") { - properties = {}; - } - - let element = this.__document.createElementNS("http://www.w3.org/2000/svg", elementName); - - if (resetFill) { - //if fill or stroke is not specified, the svg element should not display. By default SVG's fill is black. - element.setAttribute("fill", "none"); - element.setAttribute("stroke", "none"); - } - - for (let key of Object.keys(properties)) { - element.setAttribute(key, properties[key]); - } - - return element - }; - - /** - * Applies default canvas styles to the context - * @private - */ - __setDefaultStyles() { - //default 2d canvas context properties see:http://www.w3.org/TR/2dcontext/ - var keys = Object.keys(STYLES), i, key; - for (i = 0; i < keys.length; i++) { - key = keys[i]; - this[key] = STYLES[key].canvas; - } - }; - - /** - * Applies styles on restore - * @param styleState - * @private - */ - __applyStyleState(styleState) { - var keys = Object.keys(styleState), i, key; - for (i = 0; i < keys.length; i++) { - key = keys[i]; - this[key] = styleState[key]; - } - }; - - /** - * Gets the current style state - * @return {Object} - * @private - */ - __getStyleState() { - var i, styleState = {}, keys = Object.keys(STYLES), key; - for (i = 0; i < keys.length; i++) { - key = keys[i]; - styleState[key] = this[key]; - } - return styleState - }; - - /** - * Apples the current styles to the current SVG element. On "ctx.fill" or "ctx.stroke" - * @param type - * @private - */ - __applyStyleToCurrentElement(type) { - var currentElement = this.__currentElement; - var currentStyleGroup = this.__currentElementsToStyle; - if (currentStyleGroup) { - currentElement.setAttribute(type, ""); - currentElement = currentStyleGroup.element; - currentStyleGroup.children.forEach(function (node) { - node.setAttribute(type, ""); - }); - } - - var keys = Object.keys(STYLES), i, style, value, id, regex, matches; - for (i = 0; i < keys.length; i++) { - style = STYLES[keys[i]]; - value = this[keys[i]]; - if (style.apply) { - //is this a gradient or pattern? - if (value instanceof CanvasPattern) { - //pattern - if (value.__ctx) { - //copy over defs - while (value.__ctx.__defs.childNodes.length) { - id = value.__ctx.__defs.childNodes[0].getAttribute("id"); - this.__ids[id] = id; - this.__defs.appendChild(value.__ctx.__defs.childNodes[0]); - } - } - currentElement.setAttribute(style.apply, format("url(#{id})", {id: value.__root.getAttribute("id")})); - } else if (value instanceof CanvasGradient) { - //gradient - currentElement.setAttribute(style.apply, format("url(#{id})", {id: value.__root.getAttribute("id")})); - } else if (style && style.apply.indexOf(type) !== -1 && style.svg !== value) { - if ((style.svgAttr === "stroke" || style.svgAttr === "fill") && value && value.indexOf("rgba") !== -1) { - //separate alpha value, since illustrator can't handle it - regex = /rgba\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d?\.?\d*)\s*\)/gi; - matches = regex.exec(value); - currentElement.setAttribute(style.svgAttr, format("rgb({r},{g},{b})", { - r: matches[1], - g: matches[2], - b: matches[3] - })); - //should take globalAlpha here - var opacity = matches[4]; - var globalAlpha = this.globalAlpha; - if (globalAlpha != null) { - opacity *= globalAlpha; - } - currentElement.setAttribute(style.svgAttr + "-opacity", opacity); - } else { - var attr = style.svgAttr; - if (keys[i] === 'globalAlpha') { - attr = type + '-' + style.svgAttr; - if (currentElement.getAttribute(attr)) { - //fill-opacity or stroke-opacity has already been set by stroke or fill. - continue - } - } - //otherwise only update attribute if right type, and not svg default - currentElement.setAttribute(attr, value); - } - } - } - } - }; - - /** - * Will return the closest group or svg node. May return the current element. - * @private - */ - __closestGroupOrSvg(node) { - node = node || this.__currentElement; - if (node.nodeName === "g" || node.nodeName === "svg") { - return node - } else { - return this.__closestGroupOrSvg(node.parentNode) - } - }; - - /** - * Returns the serialized value of the svg so far - * @param fixNamedEntities - Standalone SVG doesn't support named entities, which document.createTextNode encodes. - * If true, we attempt to find all named entities and encode it as a numeric entity. - * @return serialized svg - */ - getSerializedSvg(fixNamedEntities) { - var serialized = new XMLSerializer().serializeToString(this.__root), - keys, i, key, value, regexp; - - //IE search for a duplicate xmnls because they didn't implement setAttributeNS correctly - // xmlns = /xmlns="http:\/\/www\.w3\.org\/2000\/svg".+xmlns="http:\/\/www\.w3\.org\/2000\/svg/gi; - // if (xmlns.test(serialized)) { - // serialized = serialized.replace('xmlns="http://www.w3.org/2000/svg','xmlns:xlink="http://www.w3.org/1999/xlink'); - // } - - if (fixNamedEntities) { - keys = Object.keys(namedEntities); - //loop over each named entity and replace with the proper equivalent. - for (i = 0; i < keys.length; i++) { - key = keys[i]; - value = namedEntities[key]; - regexp = new RegExp(key, "gi"); - if (regexp.test(serialized)) { - serialized = serialized.replace(regexp, value); - } - } - } - - return serialized - }; - - - /** - * Returns the root svg - * @return - */ - getSvg() { - return this.__root - }; - - /** - * Will generate a group tag. - */ - saveWithTranslationAndClipRect(id, tx, ty, width, height, clipYOffset) { - - // clip rect - const clip_id = `${id}_clip_rect`; - let clipPath = this.__createElement('clipPath', {id: clip_id}); - - this.__defs.appendChild(clipPath); - - const config = - { - x: '0', - y: clipYOffset.toString(), - width: width.toString(), - height: height.toString() - }; - - clipPath.appendChild(this.__createElement('rect', config)); - - const group = this.__createElement("g"); - group.setAttribute('transform', format('translate({x},{y})', {x: tx, y: ty})); - group.setAttribute('clip-path', format('url(#{id})', {id: clip_id})); - - const parent = this.__closestGroupOrSvg(); - parent.appendChild(group); - this.__groupStack.push(parent); - - this.__currentElement = group; - this.__stack.push(this.__getStyleState()); - }; - - save() { - var group = this.__createElement("g"); - var parent = this.__closestGroupOrSvg(); - this.__groupStack.push(parent); - parent.appendChild(group); - this.__currentElement = group; - this.__stack.push(this.__getStyleState()); - }; - - /** - * Sets current element to parent, or just root if already root - */ - restore() { - this.__currentElement = this.__groupStack.pop(); - this.__currentElementsToStyle = null; - //Clearing canvas will make the poped group invalid, currentElement is set to the root group node. - if (!this.__currentElement) { - this.__currentElement = this.__root.childNodes[1]; - } - var state = this.__stack.pop(); - this.__applyStyleState(state); - }; - - /** - * Helper method to add transform - * @private - */ - __addTransform(t) { - //if the current element has siblings, add another group - var parent = this.__closestGroupOrSvg(); - if (parent.childNodes.length > 0) { - if (this.__currentElement.nodeName === "path") { - if (!this.__currentElementsToStyle) this.__currentElementsToStyle = {element: parent, children: []}; - this.__currentElementsToStyle.children.push(this.__currentElement); - this.__applyCurrentDefaultPath(); - } - - var group = this.__createElement("g"); - parent.appendChild(group); - this.__currentElement = group; - } - - var transform = this.__currentElement.getAttribute("transform"); - if (transform) { - transform += " "; - } else { - transform = ""; - } - transform += t; - this.__currentElement.setAttribute("transform", transform); - }; - - addTrackGroupWithTranslationAndClipRect(id, tx, ty, width, height, clipYOffset) { - - // clip rect - const clip_id = id + '_clip_rect'; - let clipPath = this.__createElement('clipPath', {id: clip_id}); - - this.__defs.appendChild(clipPath); - clipPath.appendChild(this.__createElement('rect', { - x: '0', - y: clipYOffset.toString(), - width: width.toString(), - height: height.toString() - })); - - let group = this.__createElement('g'); - this.__rootGroup.appendChild(group); - - group.setAttribute('transform', format('translate({x},{y})', {x: tx, y: ty})); - group.setAttribute('id', (id + '_group')); - - // add clip rect - group.setAttribute('clip-path', format('url(#{id})', {id: clip_id})); - - this.__currentElement = group; - }; - - /** - * scales the current element - */ - scale(x, y) { - if (y === undefined) { - y = x; - } - this.__addTransform(format("scale({x},{y})", {x: x, y: y})); - }; - - /** - * rotates the current element - */ - rotate(angle) { - var degrees = (angle * 180 / Math.PI); - this.__addTransform(format("rotate({angle},{cx},{cy})", {angle: degrees, cx: 0, cy: 0})); - }; - - /** - * translates the current element - */ - translate(x, y) { - this.__addTransform(format("translate({x},{y})", {x: x, y: y})); - }; - - /** - * applies a transform to the current element - */ - transform(a, b, c, d, e, f) { - this.__addTransform(format("matrix({a},{b},{c},{d},{e},{f})", {a: a, b: b, c: c, d: d, e: e, f: f})); - }; - - /** - * Create a new Path Element - */ - beginPath() { - var path, parent; - - // Note that there is only one current default path, it is not part of the drawing state. - // See also: https://html.spec.whatwg.org/multipage/scripting.html#current-default-path - this.__currentDefaultPath = ""; - this.__currentPosition = {}; - - path = this.__createElement("path", {}, true); - parent = this.__closestGroupOrSvg(); - parent.appendChild(path); - this.__currentElement = path; - }; - - /** - * Helper function to apply currentDefaultPath to current path element - * @private - */ - __applyCurrentDefaultPath() { - var currentElement = this.__currentElement; - if (currentElement.nodeName === "path") { - currentElement.setAttribute("d", this.__currentDefaultPath); - } else { - console.error("Attempted to apply path command to node", currentElement.nodeName); - } - }; - - /** - * Helper function to add path command - * @private - */ - __addPathCommand(command) { - this.__currentDefaultPath += " "; - this.__currentDefaultPath += command; - }; - - /** - * Adds the move command to the current path element, - * if the currentPathElement is not empty create a new path element - */ - moveTo(x, y) { - if (this.__currentElement.nodeName !== "path") { - this.beginPath(); - } - - // creates a new subpath with the given point - this.__currentPosition = {x: x, y: y}; - this.__addPathCommand(format("M {x} {y}", {x: x, y: y})); - }; - - /** - * Closes the current path - */ - closePath() { - if (this.__currentDefaultPath) { - this.__addPathCommand("Z"); - } - }; - - /** - * Adds a line to command - */ - lineTo(x, y) { - this.__currentPosition = {x: x, y: y}; - if (this.__currentDefaultPath && this.__currentDefaultPath.indexOf('M') > -1) { - this.__addPathCommand(format("L {x} {y}", {x: x, y: y})); - } else { - this.__addPathCommand(format("M {x} {y}", {x: x, y: y})); - } - }; - - /** - * Add a bezier command - */ - bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y) { - this.__currentPosition = {x: x, y: y}; - this.__addPathCommand(format("C {cp1x} {cp1y} {cp2x} {cp2y} {x} {y}", - {cp1x: cp1x, cp1y: cp1y, cp2x: cp2x, cp2y: cp2y, x: x, y: y})); - }; - - /** - * Adds a quadratic curve to command - */ - quadraticCurveTo(cpx, cpy, x, y) { - this.__currentPosition = {x: x, y: y}; - this.__addPathCommand(format("Q {cpx} {cpy} {x} {y}", {cpx: cpx, cpy: cpy, x: x, y: y})); - }; - - /** - * Adds the arcTo to the current path - * - * @see http://www.w3.org/TR/2015/WD-2dcontext-20150514/#dom-context-2d-arcto - */ - arcTo(x1, y1, x2, y2, radius) { - // Let the point (x0, y0) be the last point in the subpath. - var x0 = this.__currentPosition && this.__currentPosition.x; - var y0 = this.__currentPosition && this.__currentPosition.y; - - // First ensure there is a subpath for (x1, y1). - if (typeof x0 == "undefined" || typeof y0 == "undefined") { - return - } - - // Negative values for radius must cause the implementation to throw an IndexSizeError exception. - if (radius < 0) { - throw new Error("IndexSizeError: The radius provided (" + radius + ") is negative.") - } - - // If the point (x0, y0) is equal to the point (x1, y1), - // or if the point (x1, y1) is equal to the point (x2, y2), - // or if the radius radius is zero, - // then the method must add the point (x1, y1) to the subpath, - // and connect that point to the previous point (x0, y0) by a straight line. - if (((x0 === x1) && (y0 === y1)) - || ((x1 === x2) && (y1 === y2)) - || (radius === 0)) { - this.lineTo(x1, y1); - return - } - - // Otherwise, if the points (x0, y0), (x1, y1), and (x2, y2) all lie on a single straight line, - // then the method must add the point (x1, y1) to the subpath, - // and connect that point to the previous point (x0, y0) by a straight line. - var unit_vec_p1_p0 = normalize([x0 - x1, y0 - y1]); - var unit_vec_p1_p2 = normalize([x2 - x1, y2 - y1]); - if (unit_vec_p1_p0[0] * unit_vec_p1_p2[1] === unit_vec_p1_p0[1] * unit_vec_p1_p2[0]) { - this.lineTo(x1, y1); - return - } - - // Otherwise, let The Arc be the shortest arc given by circumference of the circle that has radius radius, - // and that has one point tangent to the half-infinite line that crosses the point (x0, y0) and ends at the point (x1, y1), - // and that has a different point tangent to the half-infinite line that ends at the point (x1, y1), and crosses the point (x2, y2). - // The points at which this circle touches these two lines are called the start and end tangent points respectively. - - // note that both vectors are unit vectors, so the length is 1 - var cos = (unit_vec_p1_p0[0] * unit_vec_p1_p2[0] + unit_vec_p1_p0[1] * unit_vec_p1_p2[1]); - var theta = Math.acos(Math.abs(cos)); - - // Calculate origin - var unit_vec_p1_origin = normalize([ - unit_vec_p1_p0[0] + unit_vec_p1_p2[0], - unit_vec_p1_p0[1] + unit_vec_p1_p2[1] - ]); - var len_p1_origin = radius / Math.sin(theta / 2); - var x = x1 + len_p1_origin * unit_vec_p1_origin[0]; - var y = y1 + len_p1_origin * unit_vec_p1_origin[1]; - - // Calculate start angle and end angle - // rotate 90deg clockwise (note that y axis points to its down) - var unit_vec_origin_start_tangent = [ - -unit_vec_p1_p0[1], - unit_vec_p1_p0[0] - ]; - // rotate 90deg counter clockwise (note that y axis points to its down) - var unit_vec_origin_end_tangent = [ - unit_vec_p1_p2[1], - -unit_vec_p1_p2[0] - ]; - var getAngle = function (vector) { - // get angle (clockwise) between vector and (1, 0) - var x = vector[0]; - var y = vector[1]; - if (y >= 0) { // note that y axis points to its down - return Math.acos(x) - } else { - return -Math.acos(x) - } - }; - var startAngle = getAngle(unit_vec_origin_start_tangent); - var endAngle = getAngle(unit_vec_origin_end_tangent); - - // Connect the point (x0, y0) to the start tangent point by a straight line - this.lineTo(x + unit_vec_origin_start_tangent[0] * radius, - y + unit_vec_origin_start_tangent[1] * radius); - - // Connect the start tangent point to the end tangent point by arc - // and adding the end tangent point to the subpath. - this.arc(x, y, radius, startAngle, endAngle); - }; - - /** - * Sets the stroke property on the current element - */ - stroke() { - if (this.__currentElement.nodeName === "path") { - this.__currentElement.setAttribute("paint-order", "fill stroke markers"); - } - this.__applyCurrentDefaultPath(); - this.__applyStyleToCurrentElement("stroke"); - }; - - /** - * Sets fill properties on the current element - */ - fill() { - if (this.__currentElement.nodeName === "path") { - this.__currentElement.setAttribute("paint-order", "stroke fill markers"); - } - this.__applyCurrentDefaultPath(); - this.__applyStyleToCurrentElement("fill"); - }; - - /** - * Adds a rectangle to the path. - */ - rect(x, y, width, height) { - if (this.__currentElement.nodeName !== "path") { - this.beginPath(); - } - this.moveTo(x, y); - this.lineTo(x + width, y); - this.lineTo(x + width, y + height); - this.lineTo(x, y + height); - this.lineTo(x, y); - this.closePath(); - }; - - - /** - * adds a rectangle element - */ - fillRect(x, y, width, height) { - - if (height < 0) { - y += height; - height = -height; - } - if (width < 0) { - x += width; - width = -width; - } - // See if rect intersects current viewbox - var r2 = { - x: x, - y: y, - width: width, - height: height - }; - - if (this.viewbox) { - if (!intersectRect(this.viewbox, r2)) { - return - } - } - - var rect, parent; - rect = this.__createElement("rect", r2, true); - parent = this.__closestGroupOrSvg(); - parent.appendChild(rect); - this.__currentElement = rect; - this.__applyStyleToCurrentElement("fill"); - }; - - /** - * Draws a rectangle with no fill - * @param x - * @param y - * @param width - * @param height - */ - strokeRect(x, y, width, height) { - var rect, parent; - rect = this.__createElement("rect", { - x: x, - y: y, - width: width, - height: height - }, true); - parent = this.__closestGroupOrSvg(); - parent.appendChild(rect); - this.__currentElement = rect; - this.__applyStyleToCurrentElement("stroke"); - }; - - // stroke ellipse - strokeEllipse(cx, cy, rx, ry, rotation, startAngle, endAngle, isCCW) { - this.__ellipse(cx, cy, rx, ry, rotation, startAngle, endAngle, isCCW, 'stroke'); - } - - // fill ellipse - fillEllipse(cx, cy, rx, ry, rotation, startAngle, endAngle, isCCW) { - this.__ellipse(cx, cy, rx, ry, rotation, startAngle, endAngle, isCCW, 'fill'); - } - - // ellipse helper - __ellipse(cx, cy, rx, ry, rotation, startAngle, endAngle, isCCW, style) { - - const config = - { - cx, - cy, - rx, - ry - }; - const element = this.__createElement('ellipse', config, true); - const parent = this.__closestGroupOrSvg(); - parent.appendChild(element); - this.__currentElement = element; - this.__applyStyleToCurrentElement(style); - } - - /** - * Clear entire canvas: - * 1. save current transforms - * 2. remove all the childNodes of the root g element - */ - __clearCanvas() { - var current = this.__closestGroupOrSvg(), - transform = current.getAttribute("transform"); - var rootGroup = this.__root.childNodes[1]; - var childNodes = rootGroup.childNodes; - for (var i = childNodes.length - 1; i >= 0; i--) { - if (childNodes[i]) { - rootGroup.removeChild(childNodes[i]); - } - } - this.__currentElement = rootGroup; - //reset __groupStack as all the child group nodes are all removed. - this.__groupStack = []; - if (transform) { - this.__addTransform(transform); - } - }; - - /** - * "Clears" a canvas by just drawing a white rectangle in the current group. - */ - clearRect(x, y, width, height) { - //clear entire canvas - if (x === 0 && y === 0 && width === this.width && height === this.height) { - this.__clearCanvas(); - return - } - var rect, parent = this.__closestGroupOrSvg(); - rect = this.__createElement("rect", { - x: x, - y: y, - width: width, - height: height, - fill: "#FFFFFF" - }, true); - parent.appendChild(rect); - }; - - /** - * Adds a linear gradient to a defs tag. - * Returns a canvas gradient object that has a reference to it's parent def - */ - createLinearGradient(x1, y1, x2, y2) { - var grad = this.__createElement("linearGradient", { - id: randomString(this.__ids), - x1: x1 + "px", - x2: x2 + "px", - y1: y1 + "px", - y2: y2 + "px", - "gradientUnits": "userSpaceOnUse" - }, false); - this.__defs.appendChild(grad); - return new CanvasGradient(grad, this) - }; - - /** - * Adds a radial gradient to a defs tag. - * Returns a canvas gradient object that has a reference to it's parent def - */ - createRadialGradient(x0, y0, r0, x1, y1, r1) { - var grad = this.__createElement("radialGradient", { - id: randomString(this.__ids), - cx: x1 + "px", - cy: y1 + "px", - r: r1 + "px", - fx: x0 + "px", - fy: y0 + "px", - "gradientUnits": "userSpaceOnUse" - }, false); - this.__defs.appendChild(grad); - return new CanvasGradient(grad, this) - - }; - - /** - * Parses the font string and returns svg mapping - * @private - */ - __parseFont() { - var regex = /^\s*(?=(?:(?:[-a-z]+\s*){0,2}(italic|oblique))?)(?=(?:(?:[-a-z]+\s*){0,2}(small-caps))?)(?=(?:(?:[-a-z]+\s*){0,2}(bold(?:er)?|lighter|[1-9]00))?)(?:(?:normal|\1|\2|\3)\s*){0,3}((?:xx?-)?(?:small|large)|medium|smaller|larger|[.\d]+(?:\%|in|[cem]m|ex|p[ctx]))(?:\s*\/\s*(normal|[.\d]+(?:\%|in|[cem]m|ex|p[ctx])))?\s*([-,\'\"\sa-z0-9]+?)\s*$/i; - var fontPart = regex.exec(this.font); - var data = { - style: fontPart[1] || 'normal', - size: fontPart[4] || '10px', - family: fontPart[6] || 'sans-serif', - weight: fontPart[3] || 'normal', - decoration: fontPart[2] || 'normal', - href: null - }; - - //canvas doesn't support underline natively, but we can pass this attribute - if (this.__fontUnderline === "underline") { - data.decoration = "underline"; - } - - //canvas also doesn't support linking, but we can pass this as well - if (this.__fontHref) { - data.href = this.__fontHref; - } - - return data - }; - - /** - * Helper to link text fragments - * @param font - * @param element - * @return {*} - * @private - */ - __wrapTextLink(font, element) { - if (font.href) { - var a = this.__createElement("a"); - a.setAttributeNS("http://www.w3.org/1999/xlink", "xlink:href", font.href); - a.appendChild(element); - return a - } - return element - }; - - /** - * Fills or strokes text - * @param text - * @param x - * @param y - * @param action - stroke or fill - * @private - */ - __applyText(text, x, y, action) { - var font = this.__parseFont(), - parent = this.__closestGroupOrSvg(), - textElement = this.__createElement("text", { - "font-family": font.family, - "font-size": font.size, - "font-style": font.style, - "font-weight": font.weight, - "text-decoration": font.decoration, - "x": x, - "y": y, - "text-anchor": getTextAnchor(this.textAlign), - "dominant-baseline": getDominantBaseline(this.textBaseline) - }, true); - - textElement.appendChild(this.__document.createTextNode(text)); - this.__currentElement = textElement; - this.__applyStyleToCurrentElement(action); - parent.appendChild(this.__wrapTextLink(font, textElement)); - }; - - /** - * Creates a text element - * @param text - * @param x - * @param y - */ - fillText(text, x, y) { - this.__applyText(text, x, y, "fill"); - }; - - /** - * Strokes text - * @param text - * @param x - * @param y - */ - strokeText(text, x, y) { - this.__applyText(text, x, y, "stroke"); - }; - - /** - * No need to implement this for svg. - * @param text - * @return {TextMetrics} - */ - measureText(text) { - this.__ctx.font = this.font; - return this.__ctx.measureText(text) - }; - - /** - * Arc command! - */ - arc(x, y, radius, startAngle, endAngle, counterClockwise) { - // in canvas no circle is drawn if no angle is provided. - if (startAngle === endAngle) { - return - } - startAngle = startAngle % (2 * Math.PI); - endAngle = endAngle % (2 * Math.PI); - if (startAngle === endAngle) { - //circle time! subtract some of the angle so svg is happy (svg elliptical arc can't draw a full circle) - endAngle = ((endAngle + (2 * Math.PI)) - 0.001 * (counterClockwise ? -1 : 1)) % (2 * Math.PI); - } - var endX = x + radius * Math.cos(endAngle), - endY = y + radius * Math.sin(endAngle), - startX = x + radius * Math.cos(startAngle), - startY = y + radius * Math.sin(startAngle), - sweepFlag = counterClockwise ? 0 : 1, - largeArcFlag = 0, - diff = endAngle - startAngle; - - // https://github.com/gliffy/canvas2svg/issues/4 - if (diff < 0) { - diff += 2 * Math.PI; - } - - if (counterClockwise) { - largeArcFlag = diff > Math.PI ? 0 : 1; - } else { - largeArcFlag = diff > Math.PI ? 1 : 0; - } - - this.lineTo(startX, startY); - this.__addPathCommand(format("A {rx} {ry} {xAxisRotation} {largeArcFlag} {sweepFlag} {endX} {endY}", - { - rx: radius, - ry: radius, - xAxisRotation: 0, - largeArcFlag: largeArcFlag, - sweepFlag: sweepFlag, - endX: endX, - endY: endY - })); - - this.__currentPosition = {x: endX, y: endY}; - }; - - /** - * The ellipse() method creates an elliptical arc centered at (x, y) with the radii radiusX and radiusY. The path - * starts at startAngle and ends at endAngle, and travels in the direction given by counterclockwise (defaulting to clockwise). - */ -// ellipse (x, y, radiusX, radiusY, rotation, startAngle, endAngle, counterclockwise) { -// // TODO -- implement -// } - - /** - * Generates a ClipPath from the clip command. - */ - clip() { - var group = this.__closestGroupOrSvg(), - clipPath = this.__createElement("clipPath"), - id = randomString(this.__ids), - newGroup = this.__createElement("g"); - - this.__applyCurrentDefaultPath(); - group.removeChild(this.__currentElement); - clipPath.setAttribute("id", id); - clipPath.appendChild(this.__currentElement); - - this.__defs.appendChild(clipPath); - - //set the clip path to this group - group.setAttribute("clip-path", format("url(#{id})", {id: id})); - - //clip paths can be scaled and transformed, we need to add another wrapper group to avoid later transformations - // to this path - group.appendChild(newGroup); - - this.__currentElement = newGroup; - - }; - - /** - * Draws a canvas, image or mock context to this canvas. - * Note that all svg dom manipulation uses node.childNodes rather than node.children for IE support. - * http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-drawimage - */ - drawImage() { - //convert arguments to a real array - var args = Array.prototype.slice.call(arguments), - image = args[0], - dx, dy, dw, dh, sx = 0, sy = 0, sw, sh, parent, svg, defs, group, - svgImage, canvas, context, id; - - if (args.length === 3) { - dx = args[1]; - dy = args[2]; - sw = image.width; - sh = image.height; - dw = sw; - dh = sh; - } else if (args.length === 5) { - dx = args[1]; - dy = args[2]; - dw = args[3]; - dh = args[4]; - sw = image.width; - sh = image.height; - } else if (args.length === 9) { - sx = args[1]; - sy = args[2]; - sw = args[3]; - sh = args[4]; - dx = args[5]; - dy = args[6]; - dw = args[7]; - dh = args[8]; - } else { - throw new Error("Invalid number of arguments passed to drawImage: " + arguments.length) - } - - parent = this.__closestGroupOrSvg(); - this.__currentElement; - var translateDirective = "translate(" + dx + ", " + dy + ")"; - if (image instanceof ctx) { - //canvas2svg mock canvas context. In the future we may want to clone nodes instead. - //also I'm currently ignoring dw, dh, sw, sh, sx, sy for a mock context. - svg = image.getSvg().cloneNode(true); - if (svg.childNodes && svg.childNodes.length > 1) { - defs = svg.childNodes[0]; - while (defs.childNodes.length) { - id = defs.childNodes[0].getAttribute("id"); - this.__ids[id] = id; - this.__defs.appendChild(defs.childNodes[0]); - } - group = svg.childNodes[1]; - if (group) { - //save original transform - var originTransform = group.getAttribute("transform"); - var transformDirective; - if (originTransform) { - transformDirective = originTransform + " " + translateDirective; - } else { - transformDirective = translateDirective; - } - group.setAttribute("transform", transformDirective); - parent.appendChild(group); - } - } - } else if (image.nodeName === "CANVAS" || image.nodeName === "IMG") { - //canvas or image - svgImage = this.__createElement("image"); - svgImage.setAttribute("width", dw); - svgImage.setAttribute("height", dh); - svgImage.setAttribute("preserveAspectRatio", "none"); - - if (sx || sy || sw !== image.width || sh !== image.height) { - //crop the image using a temporary canvas - canvas = this.__document.createElement("canvas"); - canvas.width = dw; - canvas.height = dh; - context = canvas.getContext("2d"); - context.drawImage(image, sx, sy, sw, sh, 0, 0, dw, dh); - image = canvas; - } - svgImage.setAttribute("transform", translateDirective); - svgImage.setAttributeNS("http://www.w3.org/1999/xlink", "xlink:href", - image.nodeName === "CANVAS" ? image.toDataURL() : image.getAttribute("src")); - parent.appendChild(svgImage); - } - }; - - /** - * Generates a pattern tag - */ - createPattern(image, repetition) { - - let pattern = this.__document.__createElement("pattern"); - let id = randomString(this.__ids); - let img; - - pattern.setAttribute("id", id); - pattern.setAttribute("width", image.width); - pattern.setAttribute("height", image.height); - if (image.nodeName === "CANVAS" || image.nodeName === "IMG") { - img = this.__createElement("image"); - img.setAttribute("width", image.width); - img.setAttribute("height", image.height); - img.setAttributeNS("http://www.w3.org/1999/xlink", "xlink:href", - image.nodeName === "CANVAS" ? image.toDataURL() : image.getAttribute("src")); - pattern.appendChild(img); - this.__defs.appendChild(pattern); - } else if (image instanceof ctx) { - pattern.appendChild(image.__root.childNodes[1]); - this.__defs.appendChild(pattern); - } - return new CanvasPattern(pattern, this) - }; - - setLineDash(dashArray) { - if (dashArray && dashArray.length > 0) { - this.lineDash = dashArray.join(","); - } else { - this.lineDash = null; - } - }; - - /** - * Not yet implemented - */ - drawFocusRing() { - }; - - createImageData() { - }; - - getImageData() { - }; - - putImageData() { - }; - - globalCompositeOperation() { - }; - - setTransform() { - }; -} - -const Cytoband = function (start, end, name, typestain) { - this.start = start; - this.end = end; - this.name = name; - this.stain = 0; - - // Set the type, either p, n, or c - if (typestain === 'acen') { - this.type = 'c'; - } else { - this.type = typestain.charAt(1); - if (this.type === 'p') { - this.stain = parseInt(typestain.substring(4)); - } - } -}; - -const _version = "2.15.13"; -function version$2() { - return _version -} - -/* - * The MIT License (MIT) - * - * Copyright (c) 2014 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -const DEFAULT_GENOMES_URL = "https://igv.org/genomes/genomes.json"; -const BACKUP_GENOMES_URL = "https://s3.amazonaws.com/igv.org.genomes/genomes.json"; - -const splitLines$1 = splitLines$5; - -const GenomeUtils = { - - loadGenome: async function (options) { - - const cytobandUrl = options.cytobandURL; - const aliasURL = options.aliasURL; - const sequence = await loadFasta(options); - - let aliases; - if (aliasURL) { - aliases = await loadAliases(aliasURL, sequence.config); - } - - const genome = new Genome$1(options, sequence, aliases); - - // Delay loading cytbands untils after genome initialization to use chromosome aliases (1 vs chr1, etc). - if (cytobandUrl) { - genome.cytobands = await loadCytobands(cytobandUrl, sequence.config, genome); - } - - return genome - }, - - initializeGenomes: async function (config) { - - if (!GenomeUtils.KNOWN_GENOMES) { - - const table = {}; - - // Get default genomes - if (config.loadDefaultGenomes !== false) { - try { - const url = DEFAULT_GENOMES_URL + `?randomSeed=${Math.random().toString(36)}&version=${version$2()}`; // prevent caching - const jsonArray = await igvxhr.loadJson(url, {timeout: 5000}); - processJson(jsonArray); - } catch (e) { - console.error(e); - try { - const url = BACKUP_GENOMES_URL + `?randomSeed=${Math.random().toString(36)}&version=${version$2()}`; // prevent caching - const jsonArray = await igvxhr.loadJson(url, {}); - processJson(jsonArray); - } catch (e) { - console.error(e); - console.warn("Errors loading default genome definitions."); - } - } - } - - // Add user-defined genomes - const genomeList = config.genomeList || config.genomes; - if (genomeList) { - if (typeof genomeList === 'string') { - const jsonArray = await igvxhr.loadJson(genomeList, {}); - processJson(jsonArray); - } else { - processJson(genomeList); - } - } - - GenomeUtils.KNOWN_GENOMES = table; - - function processJson(jsonArray) { - jsonArray.forEach(function (json) { - table[json.id] = json; - }); - return table - } - } - }, - - isWholeGenomeView: function (chr) { - return 'all' === chr.toLowerCase() - }, - - // Expand a genome id to a reference object, if needed - expandReference: function (alert, idOrConfig) { - - // idOrConfig might be json - if (isString$2(idOrConfig) && idOrConfig.startsWith("{")) { - try { - idOrConfig = JSON.parse(idOrConfig); - } catch (e) { - // Apparently its not json, could be an ID starting with "{". Unusual but legal. - } - } - - let genomeID; - if (isString$2(idOrConfig)) { - genomeID = idOrConfig; - } else if (idOrConfig.genome) { - genomeID = idOrConfig.genome; - } else if (idOrConfig.id !== undefined && idOrConfig.fastaURL === undefined) { - // Backward compatibility - genomeID = idOrConfig.id; - } - - if (genomeID) { - const knownGenomes = GenomeUtils.KNOWN_GENOMES; - const reference = knownGenomes[genomeID]; - if (!reference) { - alert.present(new Error(`Unknown genome id: ${genomeID}`), undefined); - } - return reference - } else { - return idOrConfig - } - } -}; - - -class Genome$1 { - - constructor(config, sequence, aliases) { - - this.config = config; - this.id = config.id || generateGenomeID(config); - this.sequence = sequence; - this.chromosomeNames = sequence.chromosomeNames; - this.chromosomes = sequence.chromosomes; // An object (functions as a dictionary) - this.featureDB = new Map(); // Hash of name -> feature, used for search function. - - this.wholeGenomeView = config.wholeGenomeView === undefined || config.wholeGenomeView; - if (this.wholeGenomeView && Object.keys(sequence.chromosomes).length > 1) { - constructWG(this, config); - } else { - this.wgChromosomeNames = sequence.chromosomeNames; - } - - /** - * Return the official chromosome name for the (possibly) alias. Deals with - * 1 <-> chr1, chrM <-> MT, IV <-> chr4, etc. - * @param str - */ - var chrAliasTable = {}, - self = this; - - - // The standard mappings - chrAliasTable["all"] = "all"; - this.chromosomeNames.forEach(function (name) { - var alias = name.startsWith("chr") ? name.substring(3) : "chr" + name; - chrAliasTable[alias.toLowerCase()] = name; - if (name === "chrM") chrAliasTable["mt"] = "chrM"; - if (name === "MT") chrAliasTable["chrm"] = "MT"; - chrAliasTable[name.toLowerCase()] = name; - }); - - // Custom mappings - if (aliases) { - aliases.forEach(function (array) { - // Find the official chr name - var defName, i; - - for (i = 0; i < array.length; i++) { - if (self.chromosomes[array[i]]) { - defName = array[i]; - break - } - } - - if (defName) { - array.forEach(function (alias) { - if (alias !== defName) { - chrAliasTable[alias.toLowerCase()] = defName; - chrAliasTable[alias] = defName; // Should not be needed - } - }); - } - - }); - } - - this.chrAliasTable = chrAliasTable; - - } - - showWholeGenomeView() { - return this.config.wholeGenomeView !== false - } - - toJSON() { - return Object.assign({}, this.config, {tracks: undefined}) - } - - getInitialLocus() { - - } - - getHomeChromosomeName() { - if (this.showWholeGenomeView() && this.chromosomes.hasOwnProperty("all")) { - return "all" - } else { - return this.chromosomeNames[0] - - } - } - - getChromosomeName(str) { - const chr = str ? this.chrAliasTable[str.toLowerCase()] : str; - return chr ? chr : str - } - - getChromosome(chr) { - chr = this.getChromosomeName(chr); - return this.chromosomes[chr] - } - - getCytobands(chr) { - return this.cytobands ? this.cytobands[chr] : null - } - - getLongestChromosome() { - - var longestChr, - chromosomes = this.chromosomes; - for (let key in chromosomes) { - if (chromosomes.hasOwnProperty(key)) { - var chr = chromosomes[key]; - if (longestChr === undefined || chr.bpLength > longestChr.bpLength) { - longestChr = chr; - } - } - return longestChr - } - } - - getChromosomes() { - return this.chromosomes - } - - /** - * Return the genome coordinate in kb for the give chromosome and position. - * NOTE: This might return undefined if the chr is filtered from whole genome view. - */ - getGenomeCoordinate(chr, bp) { - - var offset = this.getCumulativeOffset(chr); - if (offset === undefined) return undefined - - return offset + bp - } - - /** - * Return the chromosome and coordinate in bp for the given genome coordinate - */ - getChromosomeCoordinate(genomeCoordinate) { - - if (this.cumulativeOffsets === undefined) { - this.cumulativeOffsets = computeCumulativeOffsets.call(this); - } - - let lastChr = undefined; - let lastCoord = 0; - for (let name of this.wgChromosomeNames) { - - const cumulativeOffset = this.cumulativeOffsets[name]; - if (cumulativeOffset > genomeCoordinate) { - const position = genomeCoordinate - lastCoord; - return {chr: lastChr, position: position} - } - lastChr = name; - lastCoord = cumulativeOffset; - } - - // If we get here off the end - return {chr: this.wgChromosomeNames[this.wgChromosomeNames.length - 1], position: 0} - - }; - - - /** - * Return the offset in genome coordinates (kb) of the start of the given chromosome - * NOTE: This might return undefined if the chromosome is filtered from whole genome view. - */ - getCumulativeOffset(chr) { - - if (this.cumulativeOffsets === undefined) { - this.cumulativeOffsets = computeCumulativeOffsets.call(this); - } - - const queryChr = this.getChromosomeName(chr); - return this.cumulativeOffsets[queryChr] - - function computeCumulativeOffsets() { - - let self = this; - let acc = {}; - let offset = 0; - for (let name of self.wgChromosomeNames) { - - acc[name] = Math.floor(offset); - - const chromosome = self.getChromosome(name); - - offset += chromosome.bpLength; - } - - return acc - } - } - - /** - * Return the nominal genome length, this is the length of the main chromosomes (no scaffolds, etc). - */ - getGenomeLength() { - - let self = this; - - if (!this.bpLength) { - let bpLength = 0; - self.wgChromosomeNames.forEach(function (cname) { - let c = self.chromosomes[cname]; - bpLength += c.bpLength; - }); - this.bpLength = bpLength; - } - return this.bpLength - } - - async getSequence(chr, start, end) { - chr = this.getChromosomeName(chr); - return this.sequence.getSequence(chr, start, end) - } - - addFeaturesToDB(featureList, config) { - - const insertFeature = (name, feature) => { - const current = this.featureDB.get(name); - if (current) { - feature = (feature.end - feature.start) > (current.end - current.start) ? feature : current; - - } - this.featureDB.set(name, feature); - }; - - for (let feature of featureList) { - if (feature.name) { - insertFeature(feature.name.toUpperCase(), feature); - } - if (feature.gene && feature.gene.name) { - insertFeature(feature.gene.name.toUpperCase(), feature); - } - - if (config.searchableFields) { - for (let f of config.searchableFields) { - const value = feature.getAttributeValue(f); - if (value) { - if (value.indexOf(" ") > 0) { - insertFeature(value.replaceAll(" ", "+").toUpperCase(), feature); - } else { - insertFeature(value.toUpperCase(), feature); - } - } - } - } - } - } -} - -async function loadCytobands(cytobandUrl, config, genome) { - - let data; - if (isDataURL(cytobandUrl)) { - const plain = decodeDataURI$1(cytobandUrl); - data = ""; - const len = plain.length; - for (let i = 0; i < len; i++) { - data += String.fromCharCode(plain[i]); - } - } else { - data = await igvxhr.loadString(cytobandUrl, buildOptions$1(config)); - } - - // var bands = [], - // lastChr, - // n = 0, - // c = 1, - // - // len = lines.length, - const cytobands = {}; - let lastChr; - let bands = []; - const lines = splitLines$1(data); - for (let line of lines) { - var tokens = line.split("\t"); - var chr = genome.getChromosomeName(tokens[0]); - if (!lastChr) lastChr = chr; - - if (chr !== lastChr) { - cytobands[lastChr] = bands; - bands = []; - lastChr = chr; - } - - if (tokens.length === 5) { - //10 0 3000000 p15.3 gneg - var start = parseInt(tokens[1]); - var end = parseInt(tokens[2]); - var name = tokens[3]; - var stain = tokens[4]; - bands.push(new Cytoband(start, end, name, stain)); - } - } - - return cytobands -} - -function loadAliases(aliasURL, config) { - - return igvxhr.loadString(aliasURL, buildOptions$1(config)) - - .then(function (data) { - - var lines = splitLines$1(data), - aliases = []; - - lines.forEach(function (line) { - if (!line.startsWith("#") && line.length > 0) aliases.push(line.split("\t")); - }); - - return aliases - }) - -} - -function constructWG(genome, config) { - - let wgChromosomes; - if (config.chromosomeOrder) { - if (Array.isArray(config.chromosomeOrder)) { - genome.wgChromosomeNames = config.chromosomeOrder; - } else { - genome.wgChromosomeNames = config.chromosomeOrder.split(',').map(nm => nm.trim()); - } - wgChromosomes = genome.wgChromosomeNames.map(nm => genome.chromosomes[nm]).filter(chr => chr !== undefined); - - } else { - - // Trim small chromosomes. - const lengths = Object.keys(genome.chromosomes).map(key => genome.chromosomes[key].bpLength); - const median = lengths.reduce((a, b) => Math.max(a, b)); - const threshold = median / 50; - wgChromosomes = Object.values(genome.chromosomes).filter(chr => chr.bpLength > threshold); - - // Sort chromosomes. First segregate numeric and alpha names, sort numeric, leave alpha as is - const numericChromosomes = wgChromosomes.filter(chr => isDigit(chr.name.replace('chr', ''))); - const alphaChromosomes = wgChromosomes.filter(chr => !isDigit(chr.name.replace('chr', ''))); - numericChromosomes.sort((a, b) => Number.parseInt(a.name.replace('chr', '')) - Number.parseInt(b.name.replace('chr', ''))); - - const wgChromosomeNames = numericChromosomes.map(chr => chr.name); - for (let chr of alphaChromosomes) { - wgChromosomeNames.push(chr.name); - } - genome.wgChromosomeNames = wgChromosomeNames; - } - - - // Compute psuedo-chromosome "all" - const l = wgChromosomes.reduce((accumulator, currentValue) => accumulator += currentValue.bpLength, 0); - genome.chromosomes["all"] = { - name: "all", - bpLength: l - }; - - function isDigit(val) { - return /^\d+$/.test(val) - } - -} - -function generateGenomeID(config) { - if (config.id !== undefined) { - return config.id - } else if (config.fastaURL && isString$2(config.fastaURL)) { - return config.fastaURL - } else if (config.fastaURL && config.fastaURL.name) { - return config.fastaURL.name - } else { - return ("0000" + (Math.random() * Math.pow(36, 4) << 0).toString(36)).slice(-4) - } -} - -/** - * Created by dat on 9/16/16. - */ - -const NOT_LOADED_MESSAGE = 'Error loading track data'; -let lastClickTime = 0; -let lastHoverUpdateTime = 0; -let popupTimerID; - -class TrackViewport extends Viewport { - - constructor(trackView, viewportColumn, referenceFrame, width) { - super(trackView, viewportColumn, referenceFrame, width); - } - - initializationHelper() { - - this.$spinner = $$1('
', {class: 'igv-loading-spinner-container'}); - this.$viewport.append(this.$spinner); - this.$spinner.append($$1('
')); - - const track = this.trackView.track; - if ('sequence' !== track.type) { - this.$zoomInNotice = this.createZoomInNotice(this.$viewport); - } - - if (track.name && "sequence" !== track.id) { - this.$trackLabel = $$1('
'); - this.$viewport.append(this.$trackLabel); - this.setTrackLabel(track.name); - if (false === this.browser.trackLabelsVisible) { - this.$trackLabel.hide(); - } - } - - this.stopSpinner(); - this.addMouseHandlers(); - } - - setContentHeight(contentHeight) { - super.setContentHeight(contentHeight); - if (this.featureCache) this.featureCache.redraw = true; - } - - setTrackLabel(label) { - - this.$trackLabel.empty(); - this.$trackLabel.html(label); - - const txt = this.$trackLabel.text(); - this.$trackLabel.attr('title', txt); - } - - startSpinner() { - this.$spinner.show(); - } - - stopSpinner() { - if (this.$spinner) { - this.$spinner.hide(); - } - } - - /** - * Test to determine if we are zoomed in far enough to see features. Applicable to tracks with visibility windows. - * - * As a side effect the viewports canvas is removed if zoomed out. - * - * @returns {boolean} true if we are zoomed in past visibility window, false otherwise - */ - checkZoomIn() { - - const zoomedOutOfWindow = () => { - if (this.referenceFrame.chr.toLowerCase() === "all" && !this.trackView.track.supportsWholeGenome) { - return true - } else { - const visibilityWindow = this.trackView.track.visibilityWindow; - return ( - visibilityWindow !== undefined && visibilityWindow > 0 && - (this.referenceFrame.bpPerPixel * this.$viewport.width() > visibilityWindow)) - } - }; - - if (this.trackView.track && "sequence" === this.trackView.track.type && this.referenceFrame.bpPerPixel > bppFeatureFetchThreshold) { - $$1(this.canvas).remove(); - this.canvas = undefined; - //this.featureCache = undefined - return false - } - - if (!(this.viewIsReady())) { - return false - } - - - if (zoomedOutOfWindow()) { - - // Out of visibility window - if (this.canvas) { - $$1(this.canvas).remove(); - this.canvas = undefined; - //this.featureCache = undefined - } - if (this.trackView.track.autoHeight) { - const minHeight = this.trackView.minHeight || 0; - this.setContentHeight(minHeight); - } - if (this.$zoomInNotice) { - this.$zoomInNotice.show(); - } - return false - } else { - if (this.$zoomInNotice) { - this.$zoomInNotice.hide(); - } - return true - } - - } - - /** - * Adjust the canvas to the current genomic state. - */ - shift() { - const referenceFrame = this.referenceFrame; - if (this.canvas && - this.canvas._data && - this.canvas._data.referenceFrame.chr === this.referenceFrame.chr && - this.canvas._data.bpPerPixel === referenceFrame.bpPerPixel) { - const pixelOffset = Math.round((this.canvas._data.bpStart - referenceFrame.start) / referenceFrame.bpPerPixel); - this.canvas.style.left = pixelOffset + "px"; - } - } - - /** - * Set the content top of the current view. This is triggered by scrolling. If the current canvas extent is not - * sufficient to cover the new vertical range repaint. - * - * @param contentTop - the "top" property of the virtual content div, 0 unless track is scrolled vertically - * - * - */ - setTop(contentTop) { - - super.setTop(contentTop); - - if (!this.canvas) { - this.repaint(); - } else { - // See if currently painted canvas covers the vertical range of the viewport. If not repaint - const h = this.$viewport.height(); - const vt = contentTop + this.canvas._data.pixelTop; - const vb = vt + this.canvas._data.pixelHeight; - if (vt > 0 || vb < h) { - this.repaint(); - } - } - - // Now offset backing canvas to align with the contentTop visual offset. - let offset = contentTop + this.canvas._data.pixelTop; - this.canvas.style.top = `${offset}px`; - } - - async loadFeatures() { - - const referenceFrame = this.referenceFrame; - const chr = referenceFrame.chr; - - // Expand the requested range so we can pan a bit without reloading. But not beyond chromosome bounds - const chrLength = this.browser.genome.getChromosome(chr).bpLength; - const pixelWidth = this.$viewport.width();// * 3; - const bpWidth = pixelWidth * referenceFrame.bpPerPixel; - const bpStart = Math.floor(Math.max(0, referenceFrame.start - bpWidth)); - const bpEnd = Math.ceil(Math.min(chrLength, referenceFrame.start + bpWidth + bpWidth)); // Add one screen width to end - - if (this.loading && this.loading.start === bpStart && this.loading.end === bpEnd) { - return undefined - } - this.loading = {start: bpStart, end: bpEnd}; - this.startSpinner(); - - try { - const track = this.trackView.track; - const features = await this.getFeatures(track, chr, bpStart, bpEnd, referenceFrame.bpPerPixel); - if (features) { - let roiFeatures = []; - if (track.roiSets && track.roiSets.length > 0) { - for (let roiSet of track.roiSets) { - const features = await roiSet.getFeatures(chr, bpStart, bpEnd, referenceFrame.bpPerPixel); - roiFeatures.push({track: roiSet, features}); - } - } - - const mr = track && ("wig" === track.type || "merged" === track.type); // wig tracks are potentially multiresolution (e.g. bigwig) - this.featureCache = new FeatureCache(chr, bpStart, bpEnd, referenceFrame.bpPerPixel, features, roiFeatures, mr); - this.loading = false; - this.hideMessage(); - this.stopSpinner(); - return this.featureCache - } - } catch (error) { - // Track might have been removed during load - if (this.trackView && this.trackView.disposed !== true) { - this.showMessage(NOT_LOADED_MESSAGE); - this.browser.alert.present(error); - console.error(error); - } - } finally { - this.loading = false; - this.stopSpinner(); - } - } - - /** - * Compute the genomic extent and needed pixelWidth to repaint the canvas for the current genomic state. - * Normally the canvas is size 3X the width of the viewport, however there is no left-right panning for WGV so - * canvas width is viewport width. - * @returns {{bpEnd: *, pixelWidth: (*|number), bpStart: number}} - */ - repaintDimensions() { - const isWGV = GenomeUtils.isWholeGenomeView(this.referenceFrame.chr); - const pixelWidth = isWGV ? this.$viewport.width() : 3 * this.$viewport.width(); - const bpPerPixel = this.referenceFrame.bpPerPixel; - const bpStart = this.referenceFrame.start - (isWGV ? 0 : pixelWidth / 3 * bpPerPixel); - const bpEnd = this.referenceFrame.end + (isWGV ? 0 : pixelWidth / 3 * bpPerPixel); - return { - bpStart, bpEnd, pixelWidth - } - } - - /** - * Repaint the canvas using the cached features - * - */ - repaint() { - - if (undefined === this.featureCache) { - return - } - - const {features, roiFeatures} = this.featureCache; - - // Canvas dimensions. - // For deep tracks we paint a canvas == 3*viewportHeight centered on the current vertical scroll position - const {bpStart, bpEnd, pixelWidth} = this.repaintDimensions(); - const viewportHeight = this.$viewport.height(); - const contentHeight = this.getContentHeight(); - const maxHeight = roiFeatures ? Math.max(contentHeight, viewportHeight) : contentHeight; // Need to fill viewport for ROIs. - const pixelHeight = Math.min(maxHeight, 3 * viewportHeight); - if (0 === pixelWidth || 0 === pixelHeight) { - if (this.canvas) { - $$1(this.canvas).remove(); - } - return - } - const pixelTop = Math.max(0, -this.contentTop - Math.floor(pixelHeight / 3)); - - const bpPerPixel = this.referenceFrame.bpPerPixel; - const pixelXOffset = Math.round((bpStart - this.referenceFrame.start) / bpPerPixel); - const canvasTop = (this.contentTop || 0) + pixelTop; - const newCanvas = document.createElement('canvas');// $('').get(0) - newCanvas.style.position = 'relative'; - newCanvas.style.display = 'block'; - newCanvas.style.width = pixelWidth + "px"; - newCanvas.style.height = pixelHeight + "px"; - newCanvas.style.left = pixelXOffset + "px"; - newCanvas.style.top = canvasTop + "px"; - - // Always use high DPI if in "FILL" display mode, otherwise use track setting; - const devicePixelRatio = ("FILL" === this.trackView.track.displayMode || this.trackView.track.supportHiDPI !== false) ? - window.devicePixelRatio : 1; - newCanvas.width = devicePixelRatio * pixelWidth; - newCanvas.height = devicePixelRatio * pixelHeight; - - const ctx = newCanvas.getContext("2d"); - ctx.scale(devicePixelRatio, devicePixelRatio); - ctx.translate(0, -pixelTop); - - const drawConfiguration = - { - context: ctx, - pixelXOffset, - pixelWidth, - pixelHeight, - pixelTop, - bpStart, - bpEnd: bpEnd, - bpPerPixel, - referenceFrame: this.referenceFrame, - selection: this.selection, - viewport: this, - viewportWidth: this.$viewport.width() - }; - - this.draw(drawConfiguration, features, roiFeatures); - - if (this.canvas) { - $$1(this.canvas).remove(); - } - newCanvas._data = drawConfiguration; - this.canvas = newCanvas; - this.$viewport.append($$1(newCanvas)); - - } - - refresh() { - if (!(this.canvas && this.featureCache)) return - - const drawConfiguration = this.canvas._data; - drawConfiguration.context.clearRect(0, 0, this.canvas.width, this.canvas.height); - const {features, roiFeatures} = this.featureCache; - this.draw(drawConfiguration, features, roiFeatures); - } - - /** - * Draw the associated track. - * - * @param drawConfiguration - * @param features - * @param roiFeatures - */ - draw(drawConfiguration, features, roiFeatures) { - - if (features) { - drawConfiguration.features = features; - this.trackView.track.draw(drawConfiguration); - } - if (roiFeatures && roiFeatures.length > 0) { - for (let r of roiFeatures) { - drawConfiguration.features = r.features; - r.track.draw(drawConfiguration); - } - } - } - - containsPosition(chr, position) { - if (this.referenceFrame.chr === chr && position >= this.referenceFrame.start) { - return position <= this.referenceFrame.calculateEnd(this.getWidth()) - } else { - return false - } - } - - isLoading() { - return this.loading - } - - savePNG() { - - if (!this.canvas) return - - const canvasMetadata = this.canvas._data; - const canvasTop = canvasMetadata ? canvasMetadata.pixelTop : 0; - const devicePixelRatio = window.devicePixelRatio; - const w = this.$viewport.width() * devicePixelRatio; - const h = this.$viewport.height() * devicePixelRatio; - const x = -$$1(this.canvas).position().left * devicePixelRatio; - const y = (-this.contentTop - canvasTop) * devicePixelRatio; - - const ctx = this.canvas.getContext("2d"); - const imageData = ctx.getImageData(x, y, w, h); - const exportCanvas = document.createElement('canvas'); - const exportCtx = exportCanvas.getContext('2d'); - exportCanvas.width = imageData.width; - exportCanvas.height = imageData.height; - exportCtx.putImageData(imageData, 0, 0); - - // filename = this.trackView.track.name + ".png"; - const filename = (this.$trackLabel.text() ? this.$trackLabel.text() : "image") + ".png"; - const data = exportCanvas.toDataURL("image/png"); - download(filename, data); - } - - saveSVG() { - - const marginTop = 32; - const marginLeft = 32; - - let {width, height} = this.browser.columnContainer.getBoundingClientRect(); - - const h_render = 8000; - - const config = - { - - width, - height: h_render, - - backdropColor: 'white', - - multiLocusGap: 0, - - viewbox: - { - x: 0, - y: 0, - width, - height: h_render - } - - }; - - const context = new ctx(config); - - const delta = - { - deltaX: marginLeft, - deltaY: marginTop - }; - - this.renderViewportToSVG(context, delta); - - // reset height to trim away unneeded svg canvas real estate. Yes, a bit of a hack. - context.setHeight(height); - - const str = (this.trackView.track.name || this.trackView.track.id).replace(/\W/g, ''); - const index = this.browser.referenceFrameList.indexOf(this.referenceFrame); - - const svg = context.getSerializedSvg(true); - const data = URL.createObjectURL(new Blob([svg], {type: "application/octet-stream"})); - - const id = `${str}_referenceFrame_${index}_guid_${domUtils$1.guid()}`; - download(`${id}.svg`, data); - - } - - // called by trackView.renderSVGContext() when rendering - // entire browser as SVG - - renderViewportToSVG(context, {deltaX, deltaY}) { - - if (this.$zoomInNotice && this.$zoomInNotice.is(":visible")) { - return - } - - const {width, height} = this.$viewport.get(0).getBoundingClientRect(); - - const str = (this.trackView.track.name || this.trackView.track.id).replace(/\W/g, ''); - const index = this.browser.referenceFrameList.indexOf(this.referenceFrame); - const id = `${str}_referenceFrame_${index}_guid_${domUtils$1.guid()}`; - this.drawSVGWithContext(context, width, height, id, deltaX, deltaY + this.contentTop, -this.contentTop); - - } - - renderSVGContext(context, {deltaX, deltaY}) { - - this.renderViewportToSVG(context, {deltaX, deltaY}); - - if (this.$zoomInNotice && this.$zoomInNotice.is(":visible")) { - return - } - - if (this.$trackLabel && true === this.browser.trackLabelsVisible) { - const {x, y, width, height} = domUtils$1.relativeDOMBBox(this.$viewport.get(0), this.$trackLabel.get(0)); - this.renderTrackLabelSVG(context, deltaX + x, deltaY + y, width, height); - } - - } - - // render track label element called from renderSVGContext() - renderTrackLabelSVG(context, tx, ty, width, height) { - - const str = (this.trackView.track.name || this.trackView.track.id).replace(/\W/g, ''); - const id = `${str}_track_label_guid_${domUtils$1.guid()}`; - - context.saveWithTranslationAndClipRect(id, tx, ty, width, height, 0); - - context.fillStyle = "white"; - context.fillRect(0, 0, width, height); - - context.font = "12px Arial"; - context.fillStyle = 'rgb(68, 68, 68)'; - - const {width: stringWidth} = context.measureText(this.$trackLabel.text()); - const dx = 0.25 * (width - stringWidth); - const dy = 0.7 * (height - 12); - context.fillText(this.$trackLabel.text(), dx, height - dy); - - context.strokeStyle = 'rgb(68, 68, 68)'; - context.strokeRect(0, 0, width, height); - - context.restore(); - - } - - // called by renderSVGContext() - drawSVGWithContext(context, width, height, id, x, y, yClipOffset) { - - context.saveWithTranslationAndClipRect(id, x, y, width, height, yClipOffset); - - let {start, bpPerPixel} = this.referenceFrame; - - const config = - { - context, - viewport: this, - referenceFrame: this.referenceFrame, - top: yClipOffset, - pixelTop: yClipOffset, - pixelWidth: width, - pixelHeight: height, - bpStart: start, - bpEnd: start + (width * bpPerPixel), - bpPerPixel, - viewportWidth: width, - selection: this.selection - }; - - const features = this.featureCache ? this.featureCache.features : undefined; - const roiFeatures = this.featureCache ? this.featureCache.roiFeatures : undefined; - this.draw(config, features, roiFeatures); - - context.restore(); - - } - - get cachedFeatures() { - return this.featureCache ? this.featureCache.features : [] - } - - clearCache() { - this.featureCache = undefined; - if (this.canvas) this.canvas._data = undefined; - } - - async getFeatures(track, chr, start, end, bpPerPixel) { - if (this.featureCache && this.featureCache.containsRange(chr, start, end, bpPerPixel)) { - return this.featureCache.features - } else if (typeof track.getFeatures === "function") { - const features = await track.getFeatures(chr, start, end, bpPerPixel, this); - this.checkContentHeight(features); - return features - } else { - return undefined - } - } - - needsRepaint() { - - if (!this.canvas) return true - - const data = this.canvas._data; - return !data || - this.referenceFrame.start < data.bpStart || - this.referenceFrame.end > data.bpEnd || - this.referenceFrame.chr !== data.referenceFrame.chr || - this.referenceFrame.bpPerPixel != data.bpPerPixel - } - - needsReload() { - if (!this.featureCache) return true - const {chr, bpPerPixel} = this.referenceFrame; - const {bpStart, bpEnd} = this.repaintDimensions(); - return (!this.featureCache.containsRange(chr, bpStart, bpEnd, bpPerPixel)) - } - - createZoomInNotice($parent) { - - const $container = $$1('
', {class: 'igv-zoom-in-notice-container'}); - $parent.append($container); - - const $e = $$1('
'); - $container.append($e); - - $e.text('Zoom in to see features'); - - $container.hide(); - - return $container - } - - viewIsReady() { - return this.browser && this.browser.referenceFrameList && this.referenceFrame - } - - addMouseHandlers() { - - const viewport = this.$viewport.get(0); - - this.addViewportContextMenuHandler(viewport); - - // Mouse down - const md = (event) => { - this.enableClick = true; - this.browser.mouseDownOnViewport(event, this); - domUtils$1.pageCoordinates(event); - }; - viewport.addEventListener('mousedown', md); - viewport.addEventListener('touchstart', md); - - // Mouse up - const mu = (event) => { - // Any mouse up cancels drag and scrolling - if (this.browser.dragObject || this.browser.isScrolling) { - this.browser.cancelTrackPan(); - // event.preventDefault(); - // event.stopPropagation(); - this.enableClick = false; // Until next mouse down - } else { - this.browser.cancelTrackPan(); - this.browser.endTrackDrag(); - } - }; - viewport.addEventListener('mouseup', mu); - viewport.addEventListener('touchend', mu); - - // Mouse move - if (typeof this.trackView.track.hoverText === 'function') { - viewport.addEventListener('mousemove', (event => { - if (event.buttons === 0 && (Date.now() - lastHoverUpdateTime > 100)) { - lastHoverUpdateTime = Date.now(); - const clickState = this.createClickState(event); - if (clickState) { - const tooltip = this.trackView.track.hoverText(clickState); - if (tooltip) { - this.$viewport[0].setAttribute("title", tooltip); - } else { - this.$viewport[0].removeAttribute("title"); - } - } - } - })); - } - - this.addViewportClickHandler(this.$viewport.get(0)); - - if (this.trackView.track.name && "sequence" !== this.trackView.track.config.type) { - this.addTrackLabelClickHandler(this.$trackLabel.get(0)); - } - - } - - addViewportContextMenuHandler(viewport) { - - viewport.addEventListener('contextmenu', (event) => { - - // Ignore if we are doing a drag. This can happen with touch events. - if (this.browser.dragObject) { - return false - } - - const clickState = this.createClickState(event); - - if (undefined === clickState) { - return false - } - - event.preventDefault(); - - // Track specific items - let menuItems = []; - if (typeof this.trackView.track.contextMenuItemList === "function") { - const trackMenuItems = this.trackView.track.contextMenuItemList(clickState); - if (trackMenuItems) { - menuItems = trackMenuItems; - } - } - - // Add items common to all tracks - if (menuItems.length > 0) { - menuItems.push({label: $$1('
')}); - } - - menuItems.push({label: 'Save Image (PNG)', click: () => this.savePNG()}); - menuItems.push({label: 'Save Image (SVG)', click: () => this.saveSVG()}); - - this.browser.menuPopup.presentTrackContextMenu(event, menuItems); - }); - - } - - - addViewportClickHandler(viewport) { - - viewport.addEventListener('click', (event) => { - - if (this.enableClick && this.canvas) { - if (3 === event.which || event.ctrlKey) { - return - } - - // Close any currently open popups - $$1('.igv-popover').hide(); - - - if (this.browser.dragObject || this.browser.isScrolling) { - return - } - - // Treat as a mouse click, its either a single or double click. - // Handle here and stop propogation / default - event.preventDefault(); - - const mouseX = domUtils$1.translateMouseCoordinates(event, this.$viewport.get(0)).x; - const mouseXCanvas = domUtils$1.translateMouseCoordinates(event, this.canvas).x; - const referenceFrame = this.referenceFrame; - const xBP = Math.floor((referenceFrame.start) + referenceFrame.toBP(mouseXCanvas)); - - const time = Date.now(); - - if (time - lastClickTime < this.browser.constants.doubleClickDelay) { - - // double-click - if (popupTimerID) { - window.clearTimeout(popupTimerID); - popupTimerID = undefined; - } - - const centerBP = Math.round(referenceFrame.start + referenceFrame.toBP(mouseX)); - - let string; - - if ('all' === this.referenceFrame.chr.toLowerCase()) { - - const chr = this.browser.genome.getChromosomeCoordinate(centerBP).chr; - - if (1 === this.browser.referenceFrameList.length) { - string = chr; - } else { - const loci = this.browser.referenceFrameList.map(({locusSearchString}) => locusSearchString); - const index = this.browser.referenceFrameList.indexOf(this.referenceFrame); - loci[index] = chr; - string = loci.join(' '); - } - - this.browser.search(string); - - } else { - this.browser.zoomWithScaleFactor(0.5, centerBP, this.referenceFrame); - } - - - } else { - // single-click - - if (event.shiftKey && typeof this.trackView.track.shiftClick === "function") { - - this.trackView.track.shiftClick(xBP, event); - - } else if (typeof this.trackView.track.popupData === "function") { - - popupTimerID = setTimeout(() => { - - const content = this.getPopupContent(event); - if (content) { - if (this.popover) this.popover.dispose(); - this.popover = new Popover(this.browser.columnContainer); - this.popover.presentContentWithEvent(event, content); - } - window.clearTimeout(popupTimerID); - popupTimerID = undefined; - }, - this.browser.constants.doubleClickDelay); - } - } - - lastClickTime = time; - - } - }); - } - - addTrackLabelClickHandler(trackLabel) { - - trackLabel.addEventListener('click', (event) => { - - event.stopPropagation(); - - const {track} = this.trackView; - - let str; - if (typeof track.description === 'function') { - str = track.description(); - } else if (track.description) { - str = `
${track.description}
`; - } - - if (str) { - if (this.popover) { - this.popover.dispose(); - } - this.popover = new Popover(this.browser.columnContainer, (track.name || '')); - this.popover.presentContentWithEvent(event, str); - } - }); - } - - createClickState(event) { - - if (!this.canvas) return // Can happen during initialization - - const referenceFrame = this.referenceFrame; - const viewportCoords = domUtils$1.translateMouseCoordinates(event, this.$viewport.get(0)); - const canvasCoords = domUtils$1.translateMouseCoordinates(event, this.canvas); - const genomicLocation = ((referenceFrame.start) + referenceFrame.toBP(viewportCoords.x)); - - return { - event, - viewport: this, - referenceFrame, - genomicLocation, - y: viewportCoords.y - this.contentTop, - canvasX: canvasCoords.x, - canvasY: canvasCoords.y - } - - } - - getPopupContent(event) { - - const clickState = this.createClickState(event); - - if (undefined === clickState) { - return - } - - let track = this.trackView.track; - const dataList = track.popupData(clickState); - - const popupClickHandlerResult = this.browser.fireEvent('trackclick', [track, dataList]); - - let content; - if (undefined === popupClickHandlerResult || true === popupClickHandlerResult) { - // Indicates handler did not handle the result, or the handler wishes default behavior to occur - if (dataList && dataList.length > 0) { - content = formatPopoverText(dataList); - } - - } else if (typeof popupClickHandlerResult === 'string') { - content = popupClickHandlerResult; - } - - return content - } - - -} - - -function formatPopoverText(nameValues) { - - const rows = nameValues.map(nameValue => { - - if (nameValue.name) { - const str = `${nameValue.name}   ${nameValue.value}`; - return `
${str}
` - } else if ('
' === nameValue) { // this can be retired if nameValue.html is allowed. - return nameValue - } else if (nameValue.html) { - return nameValue.html - } else { - return `
${nameValue}
` - } - - }); - - return rows.join('') -} - -class FeatureCache { - - constructor(chr, tileStart, tileEnd, bpPerPixel, features, roiFeatures, multiresolution) { - this.chr = chr; - this.bpStart = tileStart; - this.bpEnd = tileEnd; - this.bpPerPixel = bpPerPixel; - this.features = features; - this.roiFeatures = roiFeatures; - this.multiresolution = multiresolution; - } - - containsRange(chr, start, end, bpPerPixel) { - - // For multi-resolution tracks allow for a 2X change in bpPerPixel - const r = this.multiresolution ? this.bpPerPixel / bpPerPixel : 1; - - return start >= this.bpStart && end <= this.bpEnd && chr === this.chr && r > 0.5 && r < 2 - } - - overlapsRange(chr, start, end) { - return this.chr === chr && end >= this.bpStart && start <= this.bpEnd - } -} - -/** - * Decode UCSC "interact" files. See https://genome.ucsc.edu/goldenpath/help/interact.html - * - 0 string chrom; "Chromosome (or contig, scaffold, etc.). For interchromosomal, use 2 records" - 1 uint chromStart; "Start position of lower region. For interchromosomal, set to chromStart of this region" - 2 uint chromEnd; "End position of upper region. For interchromosomal, set to chromEnd of this region" - 3 string name; "Name of item, for display. Usually 'sourceName/targetName/exp' or empty" - 4 uint score; "Score (0-1000)" - 5 double value; "Strength of interaction or other data value. Typically basis for score" - 6 string exp; "Experiment name (metadata for filtering). Use . if not applicable" - 7 string color; "Item color. Specified as r,g,b or hexadecimal #RRGGBB or html color name, as in //www.w3.org/TR/css3-color/#html4. Use 0 and spectrum setting to shade by score" - 8 string sourceChrom; "Chromosome of source region (directional) or lower region. For non-directional interchromosomal, chrom of this region." - 9 uint sourceStart; "Start position in chromosome of source/lower/this region" - 10 uint sourceEnd; "End position in chromosome of source/lower/this region" - 11 string sourceName; "Identifier of source/lower/this region" - 12 string sourceStrand; "Orientation of source/lower/this region: + or -. Use . if not applicable" - 13 string targetChrom; "Chromosome of target region (directional) or upper region. For non-directional interchromosomal, chrom of other region" - 14 uint targetStart; "Start position in chromosome of target/upper/this region" - 15 uint targetEnd; "End position in chromosome of target/upper/this region" - 16 string targetName; "Identifier of target/upper/this region" - 17 string targetStrand; "Orientation of target/upper/this region: + or -. Use . if not applicable" - * - * @param tokens - * @param ignore - * @returns {*} - */ -function decodeInteract(tokens, header) { - - if (tokens.length < 6) { - console.log("Skipping line: " + tokens.join(' ')); - return undefined - } - - var feature = { - chr: tokens[0], - start: tokens[1], - end: tokens[2], - - chr1: tokens[8], - start1: Number.parseInt(tokens[9]), - end1: Number.parseInt(tokens[10]), - - chr2: tokens[13], - start2: Number.parseInt(tokens[14]), - end2: Number.parseInt(tokens[15]), - - name: tokens[3], - score: Number(tokens[4]), - value: Number(tokens[5]), - color: tokens[7] === '.' ? undefined : tokens[7] === "0" ? "rgb(0,0,0)" : tokens[7], - - }; - - return feature -} - -/** - * Some interpretations of the sequence ontology needed to assemble GFF transcripts. - * - */ - -const transcriptTypes = new Set(['transcript', 'primary_transcript', 'processed_transcript', 'mRNA', 'mrna', - 'lnc_RNA', 'miRNA', 'ncRNA', 'rRNA', 'scRNA', 'snRNA', 'snoRNA', 'tRNA']); -const cdsTypes = new Set(['CDS', 'cds']); -const codonTypes = new Set(['start_codon', 'stop_codon']); -const utrTypes = new Set(['5UTR', '3UTR', 'UTR', 'five_prime_UTR', 'three_prime_UTR', "3'-UTR", "5'-UTR"]); -const exonTypes = new Set(['exon', 'coding-exon']); - -const transcriptPartTypes = new Set(); -for (let cltn of [cdsTypes, codonTypes, utrTypes, exonTypes]) { - for (let t of cltn) { - transcriptPartTypes.add(t); - } -} - -function isExon(type) { - return exonTypes.has(type) -} - -function isIntron(type) { - return type.includes("intron") -} - -function isCoding(type) { - return cdsTypes.has(type) || codonTypes.has(type) -} - -function isUTR(type) { - return utrTypes.has(type) -} - -function isTranscript(type) { - return transcriptTypes.has(type) || type.endsWith("RNA") || type.endsWith("transcript") -} - -function isTranscriptPart(type) { - return transcriptPartTypes.has(type) || type.endsWith("RNA") || isIntron(type) -} - -const filterPopupProperties = new Set(["id", "parent", "name"]); - -class GFFFeature { - - constructor(properties) { - Object.assign(this, properties); - } - - popupData(genomicLocation) { - - const pd = this.geneObject ? this.geneObject.popupData() : []; - - if (this.geneObject) { - pd.push('
'); - } - - if (this.name) { - pd.push({name: 'Name', value: this.name}); - } - - pd.push({name: 'Type', value: this.type}); - pd.push({name: 'Source', value: this.source}); - if (this.score !== undefined) { - pd.push({name: 'Score', value: this.score}); - } - - if (this.attributeString) { - const atts = parseAttributeString(this.attributeString, this.delim); - for (let [key, value] of atts) { - if (value !== undefined && value.length > 0 && !filterPopupProperties.has(key.toLowerCase())) { - pd.push({name: key + ":", value: value}); - } - } - } - pd.push({ - name: 'Location', - value: `${this.chr}:${numberFormatter$1(this.start + 1)}-${numberFormatter$1(this.end)}` - }); - return pd - } - - getAttributeValue(attributeName) { - if (this.hasOwnProperty(attributeName)) { - return this[attributeName] - } else { - // TODO -- fetch from attribute string and cache - if (!this._attributeCache) { - this._attributeCache = new Map(); - } - if (this._attributeCache.has(attributeName)) { - return this._attributeCache.get(attributeName) - } else { - const atts = parseAttributeString(this.attributeString, this.delim); - let v; - for (let [key, value] of atts) { - if (key === attributeName) { - v = value; - break - } - } - this._attributeCache.set(attributeName, v); - return v - } - } - } -} - -class GFFTranscript extends GFFFeature { - - constructor(feature) { - super(feature); - this.exons = []; - this.parts = []; - } - - addExon(feature) { - - this.exons.push(feature); - - // Expand feature -- for transcripts not explicitly represented in the file (gtf) - this.start = Math.min(this.start, feature.start); - this.end = Math.max(this.end, feature.end); - } - - addPart(feature) { - this.parts.push(feature); - } - - assembleParts() { - - if (this.parts.length === 0) return - - this.parts.sort(function (a, b) { - return a.start - b.start - }); - - // Create exons, if neccessary - let lastStart = this.parts[0].start; - let lastEnd = this.parts[0].end; - for (let i = 1; i < this.parts.length; i++) { - const part = this.parts[i]; - if (isIntron(part.type)) { - continue - } - if (part.start <= lastEnd) { - lastEnd = Math.max(lastEnd, part.end); - } else { - let exon = this.findExonContaining({start: lastStart, end: lastEnd}); - if (!exon) { - this.exons.push({start: lastStart, end: lastEnd, psuedo: true}); - } - lastStart = part.start; - lastEnd = part.end; - } - } - let exon = this.findExonContaining({start: lastStart, end: lastEnd}); - if (!exon) { - this.exons.push({start: lastStart, end: lastEnd, psuedo: true}); - this.start = Math.min(this.start, lastStart); - this.end = Math.max(this.end, lastEnd); - } - - - for (let part of this.parts) { - const type = part.type; - if (isCoding(type)) { - this.addCDS(part); - } else if (isUTR(type)) { - this.addUTR(part); - } - } - } - - findExonContaining({start, end}) { - for (let exon of this.exons) { - if (exon.end >= end && exon.start <= start) { - return exon - } - } - return undefined - } - - addCDS(cds) { - - let exon; - const exons = this.exons; - - for (let e of exons) { - if (e.start <= cds.start && e.end >= cds.end) { - exon = e; - break - } - } - - if (exon) { - exon.cdStart = exon.cdStart ? Math.min(cds.start, exon.cdStart) : cds.start; - exon.cdEnd = exon.cdEnd ? Math.max(cds.end, exon.cdEnd) : cds.end; - } else { - // cds.cdStart = cds.start - // cds.cdEnd = cds.end - // exons.push(cds) - console.error("No exon found spanning " + cds.start + "-" + cds.end); - } - - // Expand feature -- for transcripts not explicitly represented in the file (gtf files) - // this.start = Math.min(this.start, cds.start); - // this.end = Math.max(this.end, cds.end); - - this.cdStart = this.cdStart ? Math.min(cds.start, this.cdStart) : cds.start; - this.cdEnd = this.cdEnd ? Math.max(cds.end, this.cdEnd) : cds.end; - } - - addUTR(utr) { - - let exon; - const exons = this.exons; - - // Find exon containing CDS - for (let i = 0; i < exons.length; i++) { - if (exons[i].start <= utr.start && exons[i].end >= utr.end) { - exon = exons[i]; - break - } - } - - if (exon) { - if (utr.start === exon.start && utr.end === exon.end) { - exon.utr = true; - } else { - if (utr.end < exon.end) { - exon.cdStart = utr.end; - } - if (utr.start > exon.start) { - exon.cdEnd = utr.start; - } - } - - } else { - // utr.utr = true - // exons.push(utr) - console.error("No exon found spanning " + cds.start + "-" + cds.end); - } - - // Expand feature -- for transcripts not explicitly represented in the file - // this.start = Math.min(this.start, utr.start); - // this.end = Math.max(this.end, utr.end); - - } - - finish() { - - this.assembleParts(); - - var cdStart = this.cdStart; - var cdEnd = this.cdEnd; - - this.exons.sort(function (a, b) { - return a.start - b.start - }); - - // Search for UTR exons that were not explicitly tagged - if (cdStart) { - this.exons.forEach(function (exon) { - if (exon.end < cdStart || exon.start > cdEnd) exon.utr = true; - }); - } - } - - popupData(genomicLocation) { - - const pd = super.popupData(genomicLocation); - - // If clicked over an exon add its attributes - for (let exon of this.exons) { - if (exon.pseudo) continue // An implicit exon - if (genomicLocation >= exon.start && genomicLocation < exon.end && typeof exon.popupData === 'function') { - pd.push('
'); - const exonData = exon.popupData(genomicLocation); - for (let att of exonData) { - pd.push(att); - } - } - } - - for (let part of this.parts) { - if (genomicLocation >= part.start && genomicLocation < part.end && typeof part.popupData === 'function') { - pd.push('
'); - const partData = part.popupData(genomicLocation); - for (let att of partData) { - pd.push(att); - } - } - } - - - return pd - } -} - -function decode(tokens, header) { - - const format = header.format; - if (tokens.length < 9) { - return undefined // Not a valid gff record - } - - const delim = ('gff3' === format) ? '=' : ' '; - return new GFFFeature({ - source: decodeGFFAttribute(tokens[1]), - type: tokens[2], - chr: tokens[0], - start: parseInt(tokens[3]) - 1, - end: parseInt(tokens[4]), - score: "." === tokens[5] ? undefined : Number(tokens[5]), - strand: tokens[6], - phase: "." === tokens[7] ? 0 : parseInt(tokens[7]), - attributeString: tokens[8], - delim: delim - }) -} - - -/** - * Decode a single gff record (1 line in file). Aggregations such as gene models are constructed at a higher level. - * ctg123 . mRNA 1050 9000 . + . ID=mRNA00001;Parent=gene00001 - * @param tokens - * @param ignore - * @returns {*} - */ -function decodeGFF3(tokens, header) { - - const feature = decode(tokens, header); - - if (!feature) { - return - } - - const attributes = parseAttributeString(feature.attributeString, feature.delim); - - // Search for color value as case insenstivie key - for (let [key, value] of attributes) { - const keyLower = key.toLowerCase(); - if ("color" === keyLower || "colour" === keyLower) { - feature.color = IGVColor.createColorString(value); - } else if (key === "ID") { - feature.id = value; - } else if (key === "Parent") { - feature.parent = value; - } - } - return feature -} - -/** - * GTF format example: - NC_000008.11 BestRefSeq gene 127735434 127742951 . + . gene_id "MYC"; transcript_id ""; db_xref "GeneID:4609"; db_xref "HGNC:HGNC:7553"; db_xref "MIM:190080"; description "MYC proto-oncogene, bHLH transcription factor"; gbkey "Gene"; gene "MYC"; gene_biotype "protein_coding"; gene_synonym "bHLHe39"; gene_synonym "c-Myc"; gene_synonym "MRTL"; gene_synonym "MYCC"; - NC_000008.11 BestRefSeq transcript 127735434 127742951 . + . gene_id "MYC"; transcript_id "NM_001354870.1"; db_xref "GeneID:4609"; gbkey "mRNA"; gene "MYC"; product "MYC proto-oncogene, bHLH transcription factor, transcript variant 2"; transcript_biotype "mRNA"; - NC_000008.11 BestRefSeq exon 127735434 127736623 . + . gene_id "MYC"; transcript_id "NM_001354870.1"; db_xref "GeneID:4609"; gene "MYC"; product "MYC proto-oncogene, bHLH transcription factor, transcript variant 2"; transcript_biotype "mRNA"; exon_number "1"; - * - * @param tokens - * @param ignore - * @returns {*} - */ -function decodeGTF(tokens, header) { - - const feature = decode(tokens, header); - - if (!feature) { - return - } - - const attributes = parseAttributeString(feature.attributeString, feature.delim); - - // GTF files specify neither ID nor parent fields, but they can be inferred from common conventions - let idField; - let parentField; - switch (feature.type) { - case "gene": - idField = "gene_id"; - break - case "transcript": - idField = "transcript_id"; - parentField = "gene_id"; - break - default: - parentField = "transcript_id"; - } - - for (let [key, value] of attributes) { - const keyLower = key.toLowerCase(); - if ("color" === keyLower || "colour" === keyLower) { - feature.color = IGVColor.createColorString(value); - } else if (key === idField) { - feature.id = value; - } else if (key === parentField) { - feature.parent = value; - } - } - return feature - -} - - -/** - * Parse the attribute string, returning an array of key-value pairs. An array is used rather than a map as attribute - * keys are not required to be unique. - * - * @param attributeString - * @param keyValueDelim - * @returns {[]} - */ -function parseAttributeString(attributeString, keyValueDelim, relaxed = false) { - // parse 'attributes' string (see column 9 docs in https://github.com/The-Sequence-Ontology/Specifications/blob/master/gff3.md) - var attributes = []; - for (let kv of attributeString.split(';')) { - kv = kv.trim(); - const idx = kv.indexOf(keyValueDelim); - if (idx > 0 && idx < kv.length - 1) { - const key = stripQuotes(decodeGFFAttribute(kv.substring(0, idx).trim(), relaxed)); - let value = stripQuotes(decodeGFFAttribute(kv.substring(idx + 1).trim(), relaxed)); - attributes.push([key, value]); - } - } - return attributes -} - -function stripQuotes(value) { - if (value.startsWith('"') && value.endsWith('"')) { - value = value.substr(1, value.length - 2); - } - return value -} - -// GFF3 attributes have specific percent encoding rules, the list below are required, all others are forbidden -/* -tab (%09) -newline (%0A) -carriage return (%0D) -% percent (%25) -control characters (%00 through %1F, %7F) -In addition, the following characters have reserved meanings in column 9 and must be escaped when used in other contexts: -; semicolon (%3B) -= equals (%3D) -& ampersand (%26) -, comma (%2C) - */ - -const encodings$2 = new Map([ - ["%09", "\t"], - ["%0A", "\n"], - ["%0D", "\r"], - ["%25", "%"], - ["%3B", ";"], - ["%3D", "="], - ["%26", "&"], - ["%2C", ","] -]); - -function decodeGFFAttribute(str, relaxed = false) { - - if (!str.includes("%")) { - return str - } - if (relaxed) { - return decodeURIComponent(str); - } - let decoded = ""; - for (let i = 0; i < str.length; i++) { - - if (str.charCodeAt(i) === 37 && i < str.length - 2) { - const key = str.substring(i, i + 3); - if (encodings$2.has(key)) { - decoded += encodings$2.get(key); - } else { - decoded += key; - } - i += 2; - } else { - decoded += str.charAt(i); - } - } - return decoded - -} - -/** - * Wrapper class to record a decoding error. - */ - -class DecodeError { - constructor(message) { - this.message = message; - } -} - -/** - * Decode the UCSC bed format. Only the first 3 columns (chr, start, end) are required. The remaining columns - * must follow standard bed order, but we will tolerate deviations after column 3. - * - * @param tokens - * @param ignore - * @returns decoded feature, or null if this is not a valid record - */ -function decodeBed(tokens, header) { - - - if (tokens.length < 3) return undefined - - header && header.gffTags; - - const chr = tokens[0]; - const start = parseInt(tokens[1]); - const end = tokens.length > 2 ? parseInt(tokens[2]) : start + 1; - if (isNaN(start) || isNaN(end)) { - return new DecodeError(`Unparsable bed record.`) - } - const feature = new UCSCBedFeature({chr: chr, start: start, end: end, score: 1000}); - - try { - if (tokens.length > 3) { - - // Potentially parse name field as GFF column 9 style streng. - if (tokens[3].indexOf(';') > 0 && tokens[3].indexOf('=') > 0) { - const attributeKVs = parseAttributeString(tokens[3], '=', true); - feature.attributes = {}; - for (let kv of attributeKVs) { - feature.attributes[kv[0]] = kv[1]; - if (header.nameField != undefined && kv[0] === header.nameField) { - feature.name = kv[1]; - } - } - } - if (!feature.name) { - feature.name = tokens[3] === '.' ? '' : tokens[3]; - } - } - - if (tokens.length > 4) { - feature.score = tokens[4] === '.' ? 0 : Number(tokens[4]); - if (isNaN(feature.score)) { - return feature - } - } - - if (tokens.length > 5) { - feature.strand = tokens[5]; - if (!(feature.strand === '.' || feature.strand === '+' || feature.strand === '-')) { - return feature - } - } - - if (tokens.length > 6) { - feature.cdStart = parseInt(tokens[6]); - if (isNaN(feature.cdStart)) { - return feature - } - } - - if (tokens.length > 7) { - feature.cdEnd = parseInt(tokens[7]); - if (isNaN(feature.cdEnd)) { - return feature - } - } - - if (tokens.length > 8) { - if (tokens[8] !== "." && tokens[8] !== "0") - feature.color = IGVColor.createColorString(tokens[8]); - } - - if (tokens.length > 11) { - const exonCount = parseInt(tokens[9]); - // Some basic validation - if (exonCount > 1000) { - // unlikely - return feature - } - - const exonSizes = tokens[10].replace(/,$/, '').split(','); - const exonStarts = tokens[11].replace(/,$/, '').split(','); - if (!(exonSizes.length === exonStarts.length && exonCount === exonSizes.length)) { - return feature - } - - const exons = []; - for (let i = 0; i < exonCount; i++) { - const eStart = start + parseInt(exonStarts[i]); - const eEnd = eStart + parseInt(exonSizes[i]); - exons.push({start: eStart, end: eEnd}); - } - if (exons.length > 0) { - findUTRs$1(exons, feature.cdStart, feature.cdEnd); - feature.exons = exons; - } - } - - // Optional extra columns - if (header) { - let thicknessColumn = header.thicknessColumn; - let colorColumn = header.colorColumn; - if (colorColumn && colorColumn < tokens.length) { - feature.color = IGVColor.createColorString(tokens[colorColumn]); - } - if (thicknessColumn && thicknessColumn < tokens.length) { - feature.thickness = tokens[thicknessColumn]; - } - } - } catch - (e) { - - } - - return feature -} - -/** - * Decode a UCSC repeat masker record. - */ -function decodeRepeatMasker(tokens, header) { - - /** - * Columns, from UCSC documentation - * - * 0 bin 585 smallint(5) unsigned Indexing field to speed chromosome range queries. - * 1 swScore 1504 int(10) unsigned Smith Waterman alignment score - * 2 milliDiv 13 int(10) unsigned Base mismatches in parts per thousand - * 3 milliDel 4 int(10) unsigned Bases deleted in parts per thousand - * 4 milliIns 13 int(10) unsigned Bases inserted in parts per thousand - * 5 genoName chr1 varchar(255) Genomic sequence name - * 6 genoStart 10000 int(10) unsigned Start in genomic sequence - * 7 genoEnd 10468 int(10) unsigned End in genomic sequence - * 8 genoLeft -249240153 int(11) -#bases after match in genomic sequence - * 9 strand + char(1) Relative orientation + or - - * 10 repName (CCCTAA)n varchar(255) Name of repeat - * 11 repClass Simple_repeat varchar(255) Class of repeat - * 12 repFamily Simple_repeat varchar(255) Family of repeat - * 13 repStart 1 int(11) Start (if strand is +) or -#bases after match (if strand is -) in repeat sequence - * 14 repEnd 463 int(11) End in repeat sequence - * 15 repLeft 0 int(11) -#bases after match (if strand is +) or start (if strand is -) in repeat sequence - * 16 id 1 char(1) First digit of id field in RepeatMasker .out file. Best ignored. - */ - if (tokens.length <= 15) return undefined - - const feature = { - swScore: Number.parseInt(tokens[1]), - milliDiv: Number.parseInt(tokens[2]), - milliDel: Number.parseInt(tokens[3]), - milliIns: Number.parseInt(tokens[4]), - chr: tokens[5], - start: Number.parseInt(tokens[6]), - end: Number.parseInt(tokens[7]), - //genoLeft: tokens[8], - strand: tokens[9], - repName: tokens[10], - repClass: tokens[11], - repFamily: tokens[12], - repStart: Number.parseInt(tokens[13]), - repEnd: Number.parseInt(tokens[14]), - repLeft: Number.parseInt(tokens[15]) - }; - - return feature - -} - -/** - * Decode a UCSC "genePred" record. - * - * @param tokens - * @param ignore - * @returns {*} - */ -function decodeGenePred(tokens, header) { - - var shift = header.shift === undefined ? 0 : 1; - - if (tokens.length <= 9 + shift) return undefined - - const cdStart = parseInt(tokens[5 + shift]); - const cdEnd = parseInt(tokens[6 + shift]); - var feature = { - name: tokens[0 + shift], - chr: tokens[1 + shift], - strand: tokens[2 + shift], - start: parseInt(tokens[3 + shift]), - end: parseInt(tokens[4 + shift]), - cdStart: cdStart, - cdEnd: cdEnd, - id: tokens[0 + shift] - }; - const exons = decodeExons(parseInt(tokens[7 + shift]), tokens[8 + shift], tokens[9 + shift]); - findUTRs$1(exons, cdStart, cdEnd); - - feature.exons = exons; - - return feature - -} - -/** - * Decode a UCSC "genePredExt" record. refGene files are in this format. - * - * @param tokens - * @param ignore - * @returns {*} - */ -function decodeGenePredExt(tokens, header) { - - var shift = header.shift === undefined ? 0 : 1; - - if (tokens.length <= 11 + shift) return undefined - - const cdStart = parseInt(tokens[5 + shift]); - const cdEnd = parseInt(tokens[6 + shift]); - const feature = { - name: tokens[11 + shift], - chr: tokens[1 + shift], - strand: tokens[2 + shift], - start: parseInt(tokens[3 + shift]), - end: parseInt(tokens[4 + shift]), - cdStart: cdStart, - cdEnd: cdEnd, - id: tokens[0 + shift] - }; - - const exons = decodeExons(parseInt(tokens[7 + shift]), tokens[8 + shift], tokens[9 + shift]); - findUTRs$1(exons, cdStart, cdEnd); - - feature.exons = exons; - - return feature -} - -/** - * Decode a UCSC "refFlat" record - * @param tokens - * @param ignore - * @returns {*} - */ -function decodeReflat(tokens, header) { - - var shift = header.shift === undefined ? 0 : 1; - - if (tokens.length <= 10 + shift) return undefined - - const cdStart = parseInt(tokens[6 + shift]); - const cdEnd = parseInt(tokens[7 + shift]); - var feature = { - name: tokens[0 + shift], - id: tokens[1 + shift], - chr: tokens[2 + shift], - strand: tokens[3 + shift], - start: parseInt(tokens[4 + shift]), - end: parseInt(tokens[5 + shift]), - cdStart: cdStart, - cdEnd: cdEnd - }; - - const exons = decodeExons(parseInt(tokens[8 + shift]), tokens[9 + shift], tokens[10 + shift]); - findUTRs$1(exons, cdStart, cdEnd); - feature.exons = exons; - - return feature -} - -/** - * Decode a UCS PSL record * - * @param tokens - * @param header - * @returns {DecodeError|UCSCBedFeature|undefined} - */ -function decodePSL(tokens, header) { - - /* - * 0 matches - Number of bases that match that aren't repeats - * 1 misMatches - Number of bases that don't match - * 2 repMatches - Number of bases that match but are part of repeats - * 3 nCount - Number of "N" bases - * 4 qNumInsert - Number of inserts in query - * 5 qBaseInsert - Number of bases inserted in query - * 6 tNumInsert - Number of inserts in target - * 7 tBaseInsert - Number of bases inserted in target - * 8 strand - "+" or "-" for query strand. For translated alignments, second "+"or "-" is for target genomic strand. - * 9 qName - Query sequence name - * 10 qSize - Query sequence size. - * 11 qStart - Alignment start position in query - * 12 qEnd - Alignment end position in query - * 13 tName - Target sequence name - * 14 tSize - Target sequence size - * 15 tStart - Alignment start position in target - * 16 tEnd - Alignment end position in target - * 17 blockCount - Number of blocks in the alignment (a block contains no gaps) - * 18 blockSizes - Comma-separated list of sizes of each block. If the query is a protein and the target the genome, blockSizes are in amino acids. See below for more information on protein query PSLs. - * 19 qStarts - Comma-separated list of starting positions of each block in query - * 20 tStarts - Comma-separated list of starting positions of each block in target - */ - - - if (tokens.length < 21) return undefined - - const chr = tokens[13]; - const start = parseInt(tokens[15]); - const end = parseInt(tokens[16]); - const strand = tokens[8].charAt(0); - const exonCount = parseInt(tokens[17]); - const exons = []; - const exonStarts = tokens[20].replace(/,$/, '').split(','); - const exonSizes = tokens[18].replace(/,$/, '').split(','); - - for (let i = 0; i < exonCount; i++) { - const start = parseInt(exonStarts[i]); - const end = start + parseInt(exonSizes[i]); - exons.push({start: start, end: end}); - } - - return new PSLFeature({chr, start, end, strand, exons, tokens}) -} - - -function decodeExons(exonCountToken, exonStartsToken, exonEndsToken) { - - const exonCount = parseInt(exonCountToken); - const exonStarts = exonStartsToken.replace(/,$/, '').split(','); - const exonEnds = exonEndsToken.replace(/,$/, '').split(','); - const exons = []; - for (let i = 0; i < exonCount; i++) { - const start = parseInt(exonStarts[i]); - const end = parseInt(exonEnds[i]); - exons.push({start: start, end: end}); - } - return exons - -} - -function findUTRs$1(exons, cdStart, cdEnd) { - - for (let exon of exons) { - const end = exon.end; - const start = exon.start; - if (end < cdStart || start > cdEnd) { - exon.utr = true; - } else { - if (cdStart >= start && cdStart <= end) { - exon.cdStart = cdStart; - } - if (cdEnd >= start && cdEnd <= end) { - exon.cdEnd = cdEnd; - } - } - } - -} - -function decodePeak(tokens, header) { - - var tokenCount, chr, start, end, strand, name, score, qValue, signal, pValue; - - tokenCount = tokens.length; - if (tokenCount < 9) { - return undefined - } - - chr = tokens[0]; - start = parseInt(tokens[1]); - end = parseInt(tokens[2]); - name = tokens[3]; - score = Number(tokens[4]); - strand = tokens[5].trim(); - signal = Number(tokens[6]); - pValue = Number(tokens[7]); - qValue = Number(tokens[8]); - - if (score === 0) score = signal; - - return { - chr: chr, start: start, end: end, name: name, score: score, strand: strand, signal: signal, - pValue: pValue, qValue: qValue - } -} - -function decodeBedGraph(tokens, header) { - - var chr, start, end, value; - - if (tokens.length <= 3) return undefined - - chr = tokens[0]; - start = parseInt(tokens[1]); - end = parseInt(tokens[2]); - value = Number(tokens[3]); - const feature = {chr: chr, start: start, end: end, value: value}; - - // Optional extra columns - if (header) { - let colorColumn = header.colorColumn; - if (colorColumn && colorColumn < tokens.length) { - feature.color = IGVColor.createColorString(tokens[colorColumn]); - } - } - - return feature -} - -function decodeWig(tokens, header) { - - const wig = header.wig; - - if (wig && wig.format === "fixedStep") { - const ss = (wig.index * wig.step) + wig.start; - const ee = ss + wig.span; - const value = Number(tokens[0]); - ++(wig.index); - return isNaN(value) ? null : {chr: wig.chrom, start: ss, end: ee, value: value} - } else if (wig && wig.format === "variableStep") { - - if (tokens.length < 2) return null - const ss = parseInt(tokens[0], 10) - 1; - const ee = ss + wig.span; - const value = Number(tokens[1]); - return isNaN(value) ? null : {chr: wig.chrom, start: ss, end: ee, value: value} - - } else { - return decodeBedGraph(tokens) - } -} - -function decodeSNP(tokens, header) { - - if (tokens.length < 6) return undefined - - const autoSql = [ - 'bin', - 'chr', - 'start', - 'end', - 'name', - 'score', - 'strand', - 'refNCBI', - 'refUCSC', - 'observed', - 'molType', - 'class', - 'valid', - 'avHet', - 'avHetSE', - 'func', - 'locType', - 'weight', - 'exceptions', - 'submitterCount', - 'submitters', - 'alleleFreqCount', - 'alleles', - 'alleleNs', - 'alleleFreqs', - 'bitfields' - ]; - - - const feature = { - chr: tokens[1], - start: Number.parseInt(tokens[2]), - end: Number.parseInt(tokens[3]), - name: tokens[4], - score: Number.parseInt(tokens[5]) - }; - - const n = Math.min(tokens.length, autoSql.length); - for (let i = 6; i < n; i++) { - feature[autoSql[i]] = tokens[i]; - } - return feature - -} - -class UCSCBedFeature { - - constructor(properties) { - Object.assign(this, properties); - } - - getAttributeValue(attributeName) { - if (this.hasOwnProperty(attributeName)) { - return this[attributeName] - } else if (this.attributes) { - return this.attributes[attributeName] - } - } -} - -/* -* 0 matches - Number of bases that match that aren't repeats -* 1 misMatches - Number of bases that don't match -* 2 repMatches - Number of bases that match but are part of repeats -* 3 nCount - Number of "N" bases -* 4 qNumInsert - Number of inserts in query -* 5 qBaseInsert - Number of bases inserted in query -* 6 tNumInsert - Number of inserts in target -* 7 tBaseInsert - Number of bases inserted in target -* 8 strand - "+" or "-" for query strand. For translated alignments, second "+"or "-" is for target genomic strand. -* 9 qName - Query sequence name -* 10 qSize - Query sequence size. -* 11 qStart - Alignment start position in query -* 12 qEnd - Alignment end position in query -* 13 tName - Target sequence name -* 14 tSize - Target sequence size -* 15 tStart - Alignment start position in target -* 16 tEnd - Alignment end position in target -* 17 blockCount - Number of blocks in the alignment (a block contains no gaps) -* 18 blockSizes - Comma-separated list of sizes of each block. If the query is a protein and the target the genome, blockSizes are in amino acids. See below for more information on protein query PSLs. -* 19 qStarts - Comma-separated list of starting positions of each block in query -* 20 tStarts - Comma-separated list of starting positions of each block in target - */ - -class PSLFeature { - - - constructor(properties) { - Object.assign(this, properties); - } - - get score() { - const tokens = this.tokens; - const match = parseInt(tokens[0]); - const repMatch = parseInt(tokens[2]); - const misMatch = parseInt(tokens[1]); - const qGapCount = parseInt(tokens[4]); - const tGapCount = parseInt(tokens[6]); - const qSize = parseInt(tokens[10]); - return Math.floor((1000 * (match + repMatch - misMatch - qGapCount - tGapCount)) / qSize) - } - - get matches() { - return this.tokens[0] - } - - get misMatches() { - return this.tokens[1] - } - - get repMatches() { - return this.tokens[2] - } - - get nCount() { - return this.tokens[3] - } - - get qNumInsert() { - return this.tokens[4] - } - - get qBaseInsert() { - return this.tokens[5] - } - - get tNumInsert() { - return this.tokens[6] - } - - get tBaseInsert() { - return this.tokens[7] - - } - - popupData() { - return [ - {name: 'chr', value: this.chr}, - {name: 'start', value: this.start + 1}, - {name: 'end', value: this.end}, - {name: 'strand', value: this.strand}, - {name: 'score', value: this.score}, - {name: 'match', value: this.matches}, - {name: "mis-match", value: this.misMatches}, - {name: "rep. match", value: this.repMatches}, - {name: "N's", value: this.nCount}, - {name: 'Q gap count', value: this.qNumInsert}, - {name: 'Q gap bases', value: this.qBaseInsert}, - {name: 'T gap count', value: this.tNumInsert}, - {name: 'T gap bases', value: this.tBaseInsert}, - ] - } - -} - -function decodeFusionJuncSpan(tokens, header) { - - /* - Format: - - 0 #scaffold - 1 fusion_break_name - 2 break_left - 3 break_right - 4 num_junction_reads - 5 num_spanning_frags - 6 spanning_frag_coords - - 0 B3GNT1--NPSR1 - 1 B3GNT1--NPSR1|2203-10182 - 2 2203 - 3 10182 - 4 189 - 5 1138 - 6 1860-13757,1798-13819,1391-18127,1443-17174,... - - */ - - - if (tokens.length < 7) return undefined - - var chr = tokens[0]; - var fusion_name = tokens[1]; - var junction_left = parseInt(tokens[2]); - var junction_right = parseInt(tokens[3]); - var num_junction_reads = parseInt(tokens[4]); - var num_spanning_frags = parseInt(tokens[5]); - - var spanning_frag_coords_text = tokens[6]; - - var feature = { - chr: chr, - name: fusion_name, - junction_left: junction_left, - junction_right: junction_right, - num_junction_reads: num_junction_reads, - num_spanning_frags: num_spanning_frags, - spanning_frag_coords: [], - - start: -1, - end: -1 - }; // set start and end later based on min/max of span coords - - var min_coord = junction_left; - var max_coord = junction_right; - - if (num_spanning_frags > 0) { - - var coord_pairs = spanning_frag_coords_text.split(','); - - for (var i = 0; i < coord_pairs.length; i++) { - var split_coords = coord_pairs[i].split('-'); - - var span_left = split_coords[0]; - var span_right = split_coords[1]; - - if (span_left < min_coord) { - min_coord = span_left; - } - if (span_right > max_coord) { - max_coord = span_right; - } - feature.spanning_frag_coords.push({left: span_left, right: span_right}); - - } - } - - feature.start = min_coord; - feature.end = max_coord; - - - return feature - -} - -function decodeGtexGWAS(tokens, header) { - //chrom chromStart chromEnd Strongest SNP-risk allele Disease/Phenotype P-value Odds ratio or beta PUBMEDID - //1 1247493 1247494 rs12103-A Inflammatory bowel disease 8.00E-13 1.1 23128233 - - const tokenCount = tokens.length; - if (tokenCount < 7) { - return null - } - const feature = { - chr: tokens[0], - start: parseInt(tokens[1]) - 1, - end: parseInt(tokens[2]), - 'Strongest SNP-risk allele': tokens[3], - 'Disease/Phenotype': tokens[4], - 'P-value': tokens[5], - 'Odds ratio or beta': tokens[6], - }; - if (tokens.length > 6) { - feature['PUBMEDID'] = `${tokens[7]}`; - } - return feature -} - -/** - * Decode a custom columnar format. Required columns are 'chr' and 'start' - * - * @param tokens - * @param ignore - * @returns decoded feature, or null if this is not a valid record - */ -function decodeCustom(tokens, header) { - - const format = header.customFormat; - - if (tokens.length < format.fields.length) return undefined - - const coords = format.coords || 0; - - const chr = tokens[format.chr]; - const start = parseInt(tokens[format.start]) - coords; - const end = format.end !== undefined ? parseInt(tokens[format.end]) : start + 1; - - const feature = {chr: chr, start: start, end: end}; - - if (format.fields) { - format.fields.forEach(function (field, index) { - - if (index !== format.chr && - index !== format.start && - index !== format.end) { - - feature[field] = tokens[index]; - } - }); - } - - return feature - -} - -/** - * Decode a gcnv record, a bed style format encoding copy number variation - * - * @param tokens - * @param header - */ - -function decodeGcnv(tokens, header) { - - const columnNames = header.columnNames; - if (!columnNames) { - throw Error("Sample names are not defined. Missing column headers?") - } - const sampleCount = columnNames.length - 3; - - const chr = tokens[0]; - const start = parseInt(tokens[1]); - const end = parseInt(tokens[2]); - const values = tokens.slice(3).map(Number); - - if (values.length == sampleCount) { - return { - chr: chr, - start: start, - end: end, - values: values, - } - } else { - // TODO Throw error? - console.warn(`${chr}:${start}-${end} row contains ${values.length} sample columns instead of the expected ${sampleCount} columns. Skipping...`); - return undefined - } -} - -/* - * The MIT License (MIT) - * - * Copyright (c) 2014 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -/** - * Parser for column style (tab delimited, etc) text file formats (bed, gff, vcf, etc). - * - * - */ - - -/** - * Return a parser for the given file format. - */ -class FeatureParser { - - constructor(config) { - - this.config = config; - this.header = {}; - if (config.nameField) { - this.header.nameField = config.nameField; - } - - this.skipRows = 0; // The number of fixed header rows to skip. Override for specific types as needed - - if (config.decode) { - this.decode = config.decode; - this.delimiter = config.delimiter || "\t"; - } else if (config.format) { - this.header.format = config.format.toLowerCase(); - this.setDecoder(this.header.format); - } - - if (!this.delimiter) { - this.delimiter = "\t"; - } - } - - /** - * Parse metadata from the file. A variety of conventions are in use to supply metadata about file contents - * through header lines (e.g. 'track') and # directives. This method unifies metadata as properties of a - * 'header' object. - * - * @param data - * @returns {{}} - */ - async parseHeader(dataWrapper) { - - let header = this.header; - let columnNames; - let line; - while ((line = await dataWrapper.nextLine()) !== undefined) { - if (line.startsWith("track") || line.startsWith("#track")) { - let h = parseTrackLine$1(line); - Object.assign(header, h); - } else if (line.startsWith("browser")) ; else if (line.startsWith("#columns")) { - let h = parseColumnsDirective$1(line); - Object.assign(header, h); - } else if (line.startsWith("##gff-version 3")) { - header.format = "gff3"; - } else if (line.startsWith("#gffTags")) { - header.gffTags = true; - } else if (line.startsWith("fixedStep") || line.startsWith("variableStep")) { - // Wig directives -- we are in the data section - break - } else if (line.startsWith("#")) { - const tokens = line.split(this.delimiter || "\t"); - if (tokens.length > 1) { - columnNames = tokens; // Possible column names - } - } else { - // All directives that could change the format, and thus decoder, should have been read by now. - this.setDecoder(header.format); - - // If the line can be parsed as a feature assume we are beyond the header, if any - const tokens = line.split(this.delimiter || "\t"); - try { - const tmpHeader = Object.assign({columnNames}, header); - if (this.decode(tokens, tmpHeader)) { - break - } else { - if (tokens.length > 1) { - columnNames = tokens; // possible column names - } - } - } catch (e) { - // Not a feature - if (tokens.length > 1) { - columnNames = tokens; // possible column names - } - } - } - } - - if (columnNames) { - header.columnNames = columnNames; - for (let n = 0; n < columnNames.length; n++) { - if (columnNames[n] === "color" || columnNames[n] === "colour") { - header.colorColumn = n; - } else if (columnNames[n] === "thickness") { - header.thicknessColumn = n; - } - } - } - - this.header = header; // Directives might be needed for parsing lines - return header - } - - async parseFeatures(dataWrapper) { - - const allFeatures = []; - const decode = this.decode; - const format = this.header.format; - const delimiter = this.delimiter || "\t"; - let i = 0; - let errorCount = 0; - let line; - while ((line = await dataWrapper.nextLine()) !== undefined) { - i++; - if (i <= this.skipRows) continue - - if (!line || line.startsWith("track") || line.startsWith("#") || line.startsWith("browser")) { - continue - } else if (format === "wig" && line.startsWith("fixedStep")) { - this.header.wig = parseFixedStep(line); - continue - } else if (format === "wig" && line.startsWith("variableStep")) { - this.header.wig = parseVariableStep(line); - continue - } - - const tokens = line.split(delimiter); - if (tokens.length < 1) { - continue - } - - const feature = decode(tokens, this.header); - - if (feature instanceof DecodeError) { - errorCount++; - if (errorCount > 0) { - console.error(`Error parsing line '${line}': ${feature.message}`); - } - continue - } - - if (feature) { - allFeatures.push(feature); - } - } - - // Special hack for bedPE - if (decode === decodeBedpe) { - fixBedPE(allFeatures); - } - - return allFeatures - - } - - setDecoder(format) { - - switch (format) { - case "narrowpeak": - case "broadpeak": - case "regionpeak": - case "peaks": - this.decode = decodePeak; - this.delimiter = this.config.delimiter || /\s+/; - break - case "bedgraph": - this.decode = decodeBedGraph; - this.delimiter = /\s+/; - break - case "wig": - this.decode = decodeWig; - this.delimiter = this.config.delimiter || /\s+/; - break - case "gff3" : - case "gff": - this.decode = decodeGFF3; - this.delimiter = "\t"; - break - case "gtf" : - this.decode = decodeGTF; - this.delimiter = "\t"; - break - case "fusionjuncspan": - // bhaas, needed for FusionInspector view - this.decode = decodeFusionJuncSpan; - this.delimiter = this.config.delimiter || /\s+/; - break - case "gtexgwas": - this.skipRows = 1; - this.decode = decodeGtexGWAS; - this.delimiter = "\t"; - break - case "refflat": - this.decode = decodeReflat; - this.delimiter = this.config.delimiter || /\s+/; - break - case "genepred": - this.decode = decodeGenePred; - this.delimiter = this.config.delimiter || /\s+/; - break - case "genepredext": - this.decode = decodeGenePredExt; - this.delimiter = this.config.delimiter || /\s+/; - break - case "ensgene": - this.decode = decodeGenePred; - this.header.shift = 1; - this.delimiter = this.config.delimiter || /\s+/; - break - case "refgene": - this.decode = decodeGenePredExt; - this.delimiter = this.config.delimiter || /\s+/; - this.header.shift = 1; - break - case "bed": - this.decode = decodeBed; - this.delimiter = this.config.delimiter || /\s+/; - break - case "bedpe": - case "hiccups": - this.decode = decodeBedpe; - this.delimiter = this.config.delimiter || "\t"; - break - case "bedpe-domain": - this.decode = decodeBedpeDomain; - this.headerLine = true; - this.delimiter = this.config.delimiter || "\t"; - break - case "bedpe-loop": - this.decode = decodeBedpe; - this.delimiter = this.config.delimiter || "\t"; - this.header = {colorColumn: 7}; - break - case "interact": - this.decode = decodeInteract; - this.delimiter = this.config.delimiter || /\s+/; - break - case "snp": - this.decode = decodeSNP; - this.delimiter = "\t"; - break - case "rmsk": - this.decode = decodeRepeatMasker; - this.delimiter = "\t"; - break - case "gcnv": - this.decode = decodeGcnv; - this.delimiter = "\t"; - break - default: - const customFormat = getFormat(format); - if (customFormat !== undefined) { - this.decode = decodeCustom; - this.header.customFormat = customFormat; - this.delimiter = customFormat.delimiter || "\t"; - } else { - this.decode = decodeBed; - this.delimiter = this.config.delimiter || /\s+/; - } - } - - } -} - -function parseTrackLine$1(line) { - - const properties = {}; - const tokens = line.split(/(?:")([^"]+)(?:")|([^\s"]+)(?=\s+|$)/g); - - // Clean up tokens array - let curr; - const tmp = []; - for (let tk of tokens) { - if (!tk || tk.trim().length === 0) continue - if (tk.endsWith("=")) { - curr = tk; - } else if (curr) { - tmp.push(curr + tk); - curr = undefined; - } else { - tmp.push(tk); - } - } - - for (let str of tmp) { - if (!str) return - var kv = str.split('=', 2); - if (kv.length === 2) { - const key = kv[0].trim(); - const value = kv[1].trim(); - if (properties.hasOwnProperty(key)) { - let currentValue = properties[key]; - if (Array.isArray(currentValue)) { - currentValue.push(value); - } else { - properties[key] = [currentValue, value]; - } - } else { - properties[key] = value; - } - } - } - if ("interact" == properties["type"]) { - properties["format"] = "interact"; - } else if ("gcnv" === properties["type"]) { - properties["format"] = "gcnv"; - } - return properties -} - -function parseColumnsDirective$1(line) { - - let properties = {}; - let t1 = line.split(/\s+/); - - if (t1.length === 2) { - let t2 = t1[1].split(";"); - t2.forEach(function (keyValue) { - let t = keyValue.split("="); - if (t[0] === "color") { - properties.colorColumn = Number.parseInt(t[1]) - 1; - } else if (t[0] === "thickness") { - properties.thicknessColumn = Number.parseInt(t[1]) - 1; - } - }); - } - - return properties -} - -function parseFixedStep(line) { - const tokens = line.split(/\s+/); - const chrom = tokens[1].split("=")[1]; - const start = parseInt(tokens[2].split("=")[1], 10) - 1; - const step = parseInt(tokens[3].split("=")[1], 10); - const span = (tokens.length > 4) ? parseInt(tokens[4].split("=")[1], 10) : 1; - return {format: "fixedStep", chrom, start, step, span, index: 0} -} - -function parseVariableStep(line) { - const tokens = line.split(/\s+/); - const chrom = tokens[1].split("=")[1]; - const span = tokens.length > 2 ? parseInt(tokens[2].split("=")[1], 10) : 1; - return {format: "variableStep", chrom, span} -} - -/* - * The MIT License (MIT) - * - * Copyright (c) 2018 Regents of the University of California - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -const fixColor = (colorString) => { - if (isString$2(colorString)) { - return (colorString.indexOf(",") > 0 && !(colorString.startsWith("rgb(") || colorString.startsWith("rgba("))) ? - `rgb(${colorString})` : colorString - } else { - return colorString - } -}; - -/** - * A collection of properties and methods shared by all (or most) track types. - * - * @param config - * @param browser - * @constructor - */ -class TrackBase { - - static defaults = { - height: 50, - autoHeight: false, - visibilityWindow: undefined, // Identifies property that should be copied from config - color: undefined, // Identifies property that should be copied from config - altColor: undefined, // Identifies property that should be copied from config - supportHiDPI: true - } - - constructor(config, browser) { - this.browser = browser; - this.init(config); - } - - /** - * Initialize track properties from the config object. This method is typically overriden in subclasses, which - * will call this implementation as super.init(config). - * - * @param config - */ - init(config) { - - this.config = config; - - if (config.displayMode) { - config.displayMode = config.displayMode.toUpperCase(); - } - - // Set default properties - const defaults = Object.assign({}, TrackBase.defaults); - if(this.constructor.defaults) { - for(let key of Object.keys(this.constructor.defaults)) { - defaults[key] = this.constructor.defaults[key]; - } - } - for(let key of Object.keys(defaults)) { - this[key] = config.hasOwnProperty(key) ? config[key] : defaults[key]; - if(key === 'color' || key === 'altColor') { - this[key] = fixColor(this[key]); - } - } - - if (config.name || config.label) { - this.name = config.name || config.label; - } else if (isFile$1(config.url)) { - this.name = config.url.name; - } else if (isString$2(config.url) && !config.url.startsWith("data:")) { - this.name = getFilename$2(config.url); - } - - this.url = config.url; - if(this.config.type) this.type = this.config.type; - this.id = this.config.id === undefined ? this.name : this.config.id; - this.order = config.order; - this.autoscaleGroup = config.autoscaleGroup; - this.removable = config.removable === undefined ? true : config.removable; // Defaults to true - this.minHeight = config.minHeight || Math.min(25, this.height); - this.maxHeight = config.maxHeight || Math.max(1000, this.height); - - if (config.onclick) { - this.onclick = config.onclick; - config.onclick = undefined; // functions cannot be saved in sessions, clear it here. - } - - if (config.description) { - // Override description -- displayed when clicking on track label. Convert to function if neccessary - if (typeof config.description === 'function') { - this.description = config.description; - } else { - this.description = () => config.description; - } - } - - // Support for mouse hover text. This can be expensive, off by default. - // this.hoverText = function(clickState) => return tool tip text - if (config.hoverTextFields) { - this.hoverText = hoverText.bind(this); - } else if (typeof this.config.hoverText === 'function') { - this.hoverText = this.config.hoverText; - } - } - - get name() { - return this._name - } - - set name(name) { - this._name = name; - if (this.trackView) { - this.trackView.setTrackLabelName(name); - } - } - - /** - * Update track properties from the config object. - * - * @param config - */ - updateConfig(config) { - this.init(config); - } - - clearCachedFeatures() { - if (this.trackView) { - this.trackView.clearCachedFeatures(); - } - } - - updateViews() { - if (this.trackView) { - this.trackView.updateViews(); - } - } - - /** - * Used to create session object for bookmarking, sharing. Only simple property values (string, number, boolean) - * are saved. - */ - getState() { - - const jsonable = (v) => !(v === undefined || typeof v === 'function' || v instanceof File || v instanceof Promise); - - // Create copy of config, minus transient properties (convention is name starts with '_'). Also, all - // function properties are transient as they cannot be saved in json - const state = {}; - for (let key of Object.keys(this.config)) { - if (!key.startsWith("_") && jsonable(this.config[key])) { - state[key] = this.config[key]; - } - } - - // Update original config values with any changes - for (let key of Object.keys(state)) { - if (key.startsWith("_")) continue // transient property - const value = this[key]; - if (value && (isSimpleType(value) || typeof value === "boolean" || key === "metadata")) { - state[key] = value; - } - } - - // If user has changed other properties from defaults update state. - const defs = TrackBase.defaults; - if (this.constructor.defaults) { - for (let key of Object.keys(this.constructor.defaults)) { - defs[key] = this.constructor.defaults[key]; - } - } - for (let key of Object.keys(defs)) { - if (undefined !== this[key] && defs[key] !== this[key]) { - state[key] = this[key]; - } - } - - // Flatten dataRange if present - if (!this.autoscale && this.dataRange) { - state.min = this.dataRange.min; - state.max = this.dataRange.max; - } - - return state - } - - get supportsWholeGenome() { - return this.config.supportsWholeGenome === true - } - - /** - * Does the track support sample names. Current sample aware tracks include VCF (with genotypes), MUT, MAF, and SEG - * @returns {boolean} - */ - hasSamples() { - return false - } - - getGenomeId() { - return this.browser.genome ? this.browser.genome.id : undefined - } - - /** - * Set certain track properties, usually from a "track" line. Not all UCSC properties are supported. - * - * Track configuration settings have precendence over track line properties, so if both are present ignore the - * track line. - * - * @param properties - */ - setTrackProperties(properties) { - - if (this.disposed) return // This track was removed during async load - - const tracklineConfg = {}; - let tokens; - for (let key of Object.keys(properties)) { - switch (key.toLowerCase()) { - case "usescore": - tracklineConfg.useScore = ( - properties[key] === 1 || properties[key] === "1" || properties[key] === "on" || properties[key] === true); - break - case "visibility": - //0 - hide, 1 - dense, 2 - full, 3 - pack, and 4 - squish - switch (properties[key]) { - case "2": - case "3": - case "pack": - case "full": - tracklineConfg.displayMode = "EXPANDED"; - break - case "4": - case "squish": - tracklineConfg.displayMode = "SQUISHED"; - break - case "1": - case "dense": - tracklineConfg.displayMode = "COLLAPSED"; - } - break - case "color": - case "altcolor": - tracklineConfg[key] = properties[key].startsWith("rgb(") ? properties[key] : "rgb(" + properties[key] + ")"; - break - case "featurevisiblitywindow": - case "visibilitywindow": - tracklineConfg.visibilityWindow = Number.parseInt(properties[key]); - break - case "maxheightpixels": - tokens = properties[key].split(":"); - if (tokens.length === 3) { - tracklineConfg.minHeight = Number.parseInt(tokens[2]); - tracklineConfg.height = Number.parseInt(tokens[1]); - tracklineConfg.maxHeight = Number.parseInt(tokens[0]); - } - break - case "viewlimits": - if (!this.config.autoscale) { // autoscale in the config has precedence - tokens = properties[key].split(":"); - let min = 0; - let max; - if (tokens.length == 1) { - max = Number(tokens[0]); - } else if (tokens.length == 2) { - min = Number(tokens[0]); - max = Number(tokens[1]); - } - tracklineConfg.autoscale = false; - tracklineConfg.dataRange = {min, max}; - this.viewLimitMin = min; - this.viewLimitMax = max; - } - case "name": - tracklineConfg[key] = properties[key]; - break - case "url": - tracklineConfg["infoURL"] = properties[key]; - break - case "type": - const v = properties[key]; - if (UCSCTypeMappings.has(v)) { - tracklineConfg[key] = UCSCTypeMappings.get(v); - } else { - tracklineConfg[key] = v; - } - break - case "graphtype": - tracklineConfg["graphType"] = properties[key]; - break - default: - tracklineConfg[key] = properties[key]; - } - } - - // Track configuration objects have precedence over track line properties in general. The "name" property - // is an exception if it was derived and not explicitly entered (that is derived from the web app from filename). - for (let key of Object.keys(tracklineConfg)) { - - if (!this.config.hasOwnProperty(key) || (key === "name" && this.config._derivedName)) { - let value = tracklineConfg[key]; - if ("true" === value) value = true; - if ("false" === value) value = false; - - this[key] = value; - if (key === "height" && this.trackView) { - try { - const h = Number.parseInt(value); - this.trackView.setTrackHeight(h); - } catch (e) { - console.error(e); - } - } - } - } - } - - /** - * Return the features clicked over. Default implementation assumes an array of features and only considers - * the genomic location. Overriden by most subclasses. - * - * @param clickState - * @param features - * @returns {[]|*[]} - */ - clickedFeatures(clickState) { - - // We use the cached features rather than method to avoid async load. If the - // feature is not already loaded this won't work, but the user wouldn't be mousing over it either. - const features = clickState.viewport.cachedFeatures; - - if (!features || !Array.isArray(features) || features.length === 0) { - return [] - } - - const genomicLocation = clickState.genomicLocation; - - // When zoomed out we need some tolerance around genomicLocation - const tolerance = (clickState.referenceFrame.bpPerPixel > 0.2) ? 3 * clickState.referenceFrame.bpPerPixel : 0.2; - const ss = genomicLocation - tolerance; - const ee = genomicLocation + tolerance; - return (FeatureUtils.findOverlapping(features, ss, ee)) - } - - /** - * Default popup text function -- just extracts string and number properties in random order. - * @param feature - * @returns {Array} - */ - extractPopupData(feature, genomeId) { - - const filteredProperties = new Set(['row', 'color', 'chr', 'start', 'end', 'cdStart', 'cdEnd', 'strand', 'alpha']); - const data = []; - - let alleles, alleleFreqs; - for (let property in feature) { - - if (feature.hasOwnProperty(property) && - !filteredProperties.has(property) && - isSimpleType(feature[property])) { - - let value = feature[property]; - data.push({name: capitalize(property), value: value}); - - if (property === "alleles") { - alleles = feature[property]; - } else if (property === "alleleFreqs") { - alleleFreqs = feature[property]; - } - } - } - - if (alleles && alleleFreqs) { - - if (alleles.endsWith(",")) { - alleles = alleles.substr(0, alleles.length - 1); - } - if (alleleFreqs.endsWith(",")) { - alleleFreqs = alleleFreqs.substr(0, alleleFreqs.length - 1); - } - - let a = alleles.split(","); - let af = alleleFreqs.split(","); - if (af.length > 1) { - let b = []; - for (let i = 0; i < af.length; i++) { - b.push({a: a[i], af: Number(af[i])}); - } - b.sort(function (x, y) { - return x.af - y.af - }); - - let ref = b[b.length - 1].a; - if (ref.length === 1) { - for (let i = b.length - 2; i >= 0; i--) { - let alt = b[i].a; - if (alt.length === 1) { - if (!genomeId) genomeId = this.getGenomeId(); - const cravatLink = TrackBase.getCravatLink(feature.chr, feature.start + 1, ref, alt, genomeId); - console.log(cravatLink); - if (cravatLink) { - data.push('
'); - data.push({html: cravatLink}); - data.push('
'); - } - } - } - } - } - } - - if (feature.attributes) { - for (let key of Object.keys(feature.attributes)) { - data.push({name: key, value: feature.attributes[key]}); - } - } - - // final chr position - let posString = `${feature.chr}:${numberFormatter$1(feature.start + 1)}-${numberFormatter$1(feature.end)}`; - if (feature.strand) { - posString += ` (${feature.strand})`; - } - - data.push({name: 'Location', value: posString}); - - return data - - } - - - /** - * Default track description -- displayed on click of track label. This can be overriden in the track - * configuration, or in subclasses. - */ - description() { - - const wrapKeyValue = (k, v) => `
${k}: ${v}
`; - - let str = '
'; - if (this.url) { - if (isFile$1(this.url)) { - str += wrapKeyValue('Filename', this.url.name); - } else { - str += wrapKeyValue('URL', this.url); - } - } else { - str = this.name; - } - if (this.config) { - if (this.config.metadata) { - for (let key of Object.keys(this.config.metadata)) { - const value = this.config.metadata[key]; - str += wrapKeyValue(key, value); - } - } - - // Add any config properties that are capitalized - for (let key of Object.keys(this.config)) { - if (key.startsWith("_")) continue // transient property - let first = key.substr(0, 1); - if (first !== first.toLowerCase()) { - const value = this.config[key]; - if (value && isSimpleType(value)) { - str += wrapKeyValue(key, value); - } - } - } - - } - str += '
'; - return str - } - - /** - * Return color for a specific feature of this track. This default implementation is overriden by subclasses* - * @param f - * @returns {*|string|string} - */ - getColorForFeature(f) { - return (typeof this.color === "function") ? this.color(feature) : this.color - } - - /** - * Track has been permanently removed. Release resources and other cleanup - */ - dispose() { - - this.disposed = true; - - // This should not be neccessary, but in case there is some unknown reference holding onto this track object, - // for example in client code, release any resources here. - for (let key of Object.keys(this)) { - this[key] = undefined; - } - } - - static getCravatLink(chr, position, ref, alt, genomeID) { - - if ("hg38" === genomeID || "GRCh38" === genomeID) { - - const cravatChr = chr.startsWith("chr") ? chr : "chr" + chr; - return `Cravat ${ref}->${alt}` - - } else { - return undefined - } - } -} - -function hoverText(clickState) { - - if (!this.hoverTextFields) return - - const features = this.clickedFeatures(clickState); - - if (features && features.length > 0) { - let str = ""; - for (let i = 0; i < features.length; i++) { - if (i === 10) { - str += "; ..."; - break - } - if (!features[i]) continue - - const f = features[i]._f || features[i]; - if (str.length > 0) str += "\n"; - - str = ""; - for (let field of this.hoverTextFields) { - if (str.length > 0) str += "\n"; - if (f.hasOwnProperty(field)) { - str += f[field]; - } else if (typeof f.getAttribute === "function") { - str += f.getAttribute(field); - } - } - - } - return str - } -} - -/** - * Map UCSC track line "type" setting to file format. In igv.js "type" refers to the track type, not the input file format - * @type {Map} - */ -const UCSCTypeMappings = new Map([ - ["wiggle_0", "wig"], - ["bed", "bed"], - ["bigBed", "bigBed"], - ["bigWig", "bigWig"] -]); - -/* - * The MIT License (MIT) - * - * Copyright (c) 2014 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - -/** - * Define parser for seg files (.bed, .gff, .vcf, etc). A parser should implement 2 methods - * - * parseHeader(data) - return an object representing a header. Details are format specific - * - * parseFeatures(data) - return a list of features - * - */ - - -class SegParser { - - constructor(type) { - this.type = type || 'seg'; // One of seg, mut, or maf - - switch (this.type) { - case 'mut': - this.sampleColumn = 3; - this.chrColumn = 0; - this.startColumn = 1; - this.endColumn = 2; - this.dataColumn = 4; - break - case 'maf': - this.sampleColumn = 15; - this.chrColumn = 4; - this.startColumn = 5; - this.endColumn = 6; - this.dataColumn = 8; - break - default: - this.sampleColumn = 0; - this.chrColumn = 1; - this.startColumn = 2; - this.endColumn = 3; - // Data column determined after reading header - } - } - - async parseHeader(dataWrapper) { - let line; - while ((line = await dataWrapper.nextLine()) !== undefined) { - if (line.startsWith("#")) ; else { - const tokens = line.split("\t"); - this.header = {headings: tokens}; - break - } - } - return this.header - } - - async parseFeatures(dataWrapper) { - - const allFeatures = []; - let extraHeaders; - if (!this.header) { - this.header = await this.parseHeader(dataWrapper); // This will only work for non-indexed files - } - if ('seg' === this.type) { - this.dataColumn = this.header.headings.length - 1; - } - if (this.header.headings.length > 5) { - extraHeaders = this.extractExtraColumns(this.header.headings); - } - const valueColumnName = this.header.headings[this.dataColumn]; - - let line; - while ((line = await dataWrapper.nextLine()) !== undefined) { - const tokens = line.split("\t"); - const value = ('seg' === this.type) ? Number(tokens[this.dataColumn]) : tokens[this.dataColumn]; - if (tokens.length > this.dataColumn) { - const feature = new SegFeature({ - sample: tokens[this.sampleColumn], - chr: tokens[this.chrColumn], - start: parseInt(tokens[this.startColumn]) - 1, - end: parseInt(tokens[this.endColumn]), - value, - valueColumnName - }); - if (extraHeaders) { - const extraValues = this.extractExtraColumns(tokens); - feature.setAttributes({names: extraHeaders, values: extraValues}); - } - allFeatures.push(feature); - } - } - return allFeatures - } - - extractExtraColumns(tokens) { - const extras = []; - for (let i = 0; i < tokens.length; i++) { - if (i !== this.chrColumn && i !== this.startColumn && i !== this.endColumn && i !== this.sampleColumn) { - extras.push(tokens[i]); - } - } - return extras - } - -} - -class SegFeature { - - constructor({sample, chr, start, end, value, valueColumnName}) { - this.sample = sample; - this.chr = chr; - this.start = start; - this.end = end; - this.value = value; - this.valueColumnName = valueColumnName; - } - - setAttributes({names, values}) { - this.attributeNames = names; - this.attributeValues = values; - } - - getAttribute(name) { - if (this.attributeNames) { - const idx = this.attributeNames.indexOf(name); - if (idx >= 0) { - return this.attributeValues[idx] - } - } - return undefined - } - - - popupData(type, genomeID) { - const filteredProperties = new Set(['chr', 'start', 'end', 'sample', 'value', 'row', 'color', 'sampleKey', - 'uniqueSampleKey', 'sampleId', 'chromosome', 'uniquePatientKey']); - const locationString = (this.chr + ":" + - numberFormatter$1(this.start + 1) + "-" + - numberFormatter$1(this.end)); - const pd = [ - {name: "Sample", value: this.sample}, - {name: "Location", value: locationString}, - {name: this.valueColumnName ? capitalize(this.valueColumnName) : "Value", value: this.value} - ]; - - // TODO -- the Cravat stuff should probably be in the track (SegTrack) - if ("mut" === type && "hg38" === genomeID) { - const l = this.extractCravatLink(genomeID); - if (l) { - pd.push('
'); - pd.push({html: l}); - pd.push('
'); - } - } - - if (this.attributeNames && this.attributeNames.length > 0) { - for (let i = 0; i < this.attributeNames.length; i++) { - if (!filteredProperties.has(this.attributeNames[i]) & this.valueColumnName !== this.attributeNames[i]) { - pd.push({name: capitalize(this.attributeNames[i]), value: this.attributeValues[i]}); - } - } - } - return pd - } - - extractCravatLink(genomeId) { - - let ref, alt; - if (this.attributeNames && this.attributeNames.length > 0) { - for (let i = 0; i < this.attributeNames.length; i++) { - if (!ref && "Reference_Allele" === this.attributeNames[i]) { - ref = this.attributeValues[i]; - } - if (!alt && this.attributeNames[i].startsWith("Tumor_Seq_Allele") && this.attributeValues[i] !== ref) { - alt = this.attributeValues[i]; - } - if (ref && alt) { - return TrackBase.getCravatLink(this.chr, this.start + 1, ref, alt, genomeId) - } - } - } - - } -} - -/* - * The MIT License (MIT) - * - * Copyright (c) 2014 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -/** - * Create a variant from an array of tokens representing a line in a "VCF" file - * @param tokens - */ -function createVCFVariant(tokens) { - const variant = new Variant(); - variant.chr = tokens[0]; // TODO -- use genome aliases - variant.pos = parseInt(tokens[1]); - variant.names = tokens[2]; // id in VCF - variant.referenceBases = tokens[3]; - variant.alternateBases = tokens[4]; - variant.quality = tokens[5]; - variant.filter = tokens[6]; - variant.info = {}; - const infoStr = tokens[7]; - if (infoStr) { - for (let elem of infoStr.split(';')) { - var element = elem.split('='); - variant.info[element[0]] = element[1]; - } - } - variant.init(); - return variant -} - - -/** - * @deprecated - the GA4GH API has been deprecated. This code no longer maintained. - * @param json - * @returns {Variant} - */ -function createGAVariant(json) { - - var variant = new Variant(); - - variant.chr = json.referenceName; - variant.start = parseInt(json.start); // Might get overriden below - variant.end = parseInt(json.end); // Might get overriden below - variant.pos = variant.start + 1; // GA4GH is 0 based. - variant.names = arrayToString(json.names, "; "); - variant.referenceBases = json.referenceBases; - variant.alternateBases = arrayToString(json.alternateBases); - variant.quality = json.quality; - variant.filter = arrayToString(json.filter); - - - // Flatten GA4GH attributes array - variant.info = {}; - if (json.info) { - Object.keys(json.info).forEach(function (key) { - var value, - valueArray = json.info[key]; - - if (Array.isArray(valueArray)) { - value = valueArray.join(","); - } else { - value = valueArray; - } - variant.info[key] = value; - }); - } - - - // Need to build a hash of calls for fast lookup - // Note from the GA4GH spec on call ID: - // - // The ID of the call set this variant call belongs to. If this field is not present, - // the ordering of the call sets from a SearchCallSetsRequest over this GAVariantSet - // is guaranteed to match the ordering of the calls on this GAVariant. - // The number of results will also be the same. - variant.calls = {}; - var id; - if (json.calls) { - json.calls.forEach(function (call) { - id = call.callSetId; - variant.calls[id] = call; - - }); - } - - init(variant); - - return variant - -} - - -class Variant { - - init() { - - const ref = this.referenceBases; - const altBases = this.alternateBases; - - if (this.info) { - if (this.info["VT"]) { - this.type = this.info["VT"]; - } else if (this.info["SVTYPE"]) { - this.type = "SV"; - } else if (this.info["PERIOD"]) { - this.type = "STR"; - } - } - if (this.type === undefined) { - this.type = determineType(ref, altBases); - } - if (this.type === "NONVARIANT") { - this.heterozygosity = 0; - } - - // Determine start/end coordinates -- these are the coordinates representing the actual variant, - // not the leading or trailing reference - if (this.info["END"]) { - this.start = this.pos - 1; - if (this.info["CHR2"] && this.info["CHR2"] !== this.chr) { - this.end = this.start + 1; - } else { - this.end = Number.parseInt(this.info["END"]); - } - } else { - if (this.type === "NONVARIANT") { - this.start = this.pos - 1; // convert to 0-based coordinate convention - this.end = this.start + ref.length; - } else { - - const altTokens = altBases.split(",").filter(token => token.length > 0); - this.alleles = []; - this.start = undefined; - this.end = undefined; - - for (let alt of altTokens) { - - this.alleles.push(alt); - - // We don't yet handle SV and other special alt representations - if ("SV" !== this.type && isKnownAlt(alt)) { - - let altLength = alt.length; - let lengthOnRef = ref.length; - const lmin = Math.min(altLength, lengthOnRef); - - // Trim off matching bases. Try first match, then right -> left, then any remaining left -> right - let s = 0; - - while (s < lmin && (ref.charCodeAt(s) === alt.charCodeAt(s))) { - s++; - altLength--; - lengthOnRef--; - } - - // right -> left from end - while (altLength > 0 && lengthOnRef > 0) { - const altIdx = s + altLength - 1; - const refIdx = s + lengthOnRef - 1; - if (alt.charCodeAt(altIdx) === ref.charCodeAt(refIdx)) { - altLength--; - lengthOnRef--; - } else { - break - } - } - - // if any remaining, left -> right - while (altLength > 0 && lengthOnRef > 0) { - const altIdx = s; - const refIdx = s; - if (alt.charCodeAt(altIdx) === ref.charCodeAt(refIdx)) { - s++; - altLength--; - lengthOnRef--; - } else { - break - } - } - - const alleleStart = this.pos + s - 1; // -1 for zero based coordinates - const alleleEnd = alleleStart + lengthOnRef; - this.start = this.start === undefined ? alleleStart : Math.min(this.start, alleleStart); - this.end = this.end === undefined ? alleleEnd : Math.max(this.end, alleleEnd); - } - } - - // Default to single base representation @ position for variant types not otherwise handled - if (this.start === undefined) { - this.start = this.pos - 1; - this.end = this.pos; - } - } - } - } - - popupData(genomicLocation, genomeId) { - - const posString = `${numberFormatter$1(this.pos)}`; - const locString = this.start === this.end ? - `${numberFormatter$1(this.start)} | ${numberFormatter$1(this.start + 1)}` : - `${numberFormatter$1(this.start + 1)}-${numberFormatter$1(this.end)}`; - const fields = [ - {name: "Chr", value: this.chr}, - {name: "Pos", value: posString}, - {name: "Loc", value: locString}, - {name: "ID", value: this.names ? this.names : ""}, - {name: "Ref", value: this.referenceBases}, - {name: "Alt", value: this.alternateBases.replace("<", "<")}, - {name: "Qual", value: this.quality}, - {name: "Filter", value: this.filter} - ]; - - if ("SNP" === this.type) { - let ref = this.referenceBases; - if (ref.length === 1) { - let altArray = this.alternateBases.split(","); - for (let alt of altArray) { - if (alt.length === 1) { - let l = TrackBase.getCravatLink(this.chr, this.pos, ref, alt, genomeId); - if (l) { - fields.push('
'); - fields.push({html: l}); - } - } - } - } - } - - if (this.hasOwnProperty("heterozygosity")) { - fields.push({name: "Heterozygosity", value: this.heterozygosity}); - } - - if (this.info) { - fields.push({html: '
'}); - for (let key of Object.keys(this.info)) { - fields.push({name: key, value: arrayToString(decodeURIComponent(this.info[key]))}); - } - } - - return fields - } - - getInfo(tag) { - return this.info ? this.info[tag] : undefined; - } - - isRefBlock() { - return "NONVARIANT" === this.type - } - -} - -const knownAltBases = new Set(["A", "C", "T", "G"].map(c => c.charCodeAt(0))); - -function isKnownAlt(alt) { - for (let i = 0; i < alt.length; i++) { - if (!knownAltBases.has(alt.charCodeAt(i))) { - return false - } - } - return true -} - - -function determineType(ref, altAlleles) { - const refLength = ref.length; - if (altAlleles === undefined) { - return "UNKNOWN" - } else if (altAlleles.trim().length === 0 || - altAlleles === "" || - altAlleles === "<*>" || - altAlleles === ".") { - return "NONVARIANT" - } else { - const alleles = altAlleles.split(","); - const types = alleles.map(function (a) { - if (refLength === 1 && a.length === 1) { - return "SNP" - } else { - return "" === a ? "NONVARIANT" : "OTHER" - } - }); - let type = types[0]; - for (let t of types) { - if (t !== type) { - return "MIXED" - } - } - return type - } -} - -function arrayToString(value, delim) { - - if (delim === undefined) delim = ","; - - if (!(Array.isArray(value))) { - return value - } - return value.join(delim) -} - -/* - * The MIT License (MIT) - * - * Copyright (c) 2014 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -/** - * Parser for VCF files. - */ - -class VcfParser { - - construtor() { - } - - async parseHeader(dataWrapper, genome) { - - const header = {}; - - header.chrAliasTable = new Map(); - - // First line must be file format - let line = await dataWrapper.nextLine(); - if (line.startsWith("##fileformat")) { - header.version = line.substr(13); - } else { - throw new Error("Invalid VCF file: missing fileformat line") - } - - while ((line = await dataWrapper.nextLine()) !== undefined) { - - if (line.startsWith("#")) { - - let id; - const values = {}; - - if (line.startsWith("##")) { - - if (line.startsWith("##INFO") || line.startsWith("##FILTER") || line.startsWith("##FORMAT")) { - - const ltIdx = line.indexOf("<"); - const gtIdx = line.lastIndexOf(">"); - - if (!(ltIdx > 2 && gtIdx > 0)) { - console.log("Malformed VCF header line: " + line); - continue - } - - const type = line.substring(2, ltIdx - 1); - if (!header[type]) header[type] = {}; - - //##INFO= - // ##FILTER= - // ##FORMAT= - - const tokens = splitStringRespectingQuotes(line.substring(ltIdx + 1, gtIdx - 1), ","); - - for (let token of tokens) { - var kv = token.split("="); - if (kv.length > 1) { - if (kv[0] === "ID") { - id = kv[1]; - } else { - values[kv[0]] = kv[1]; - } - } - } - - if (id) { - header[type][id] = values; - } - } else if (line.startsWith("##contig") && genome) { - const idx1 = line.indexOf("", idx1); - } - const chr = line.substring(idx1 + 4, idx2); - const canonicalChromosome = genome.getChromosomeName(chr); - header.chrAliasTable.set(canonicalChromosome, chr); - } else ; - } else if (line.startsWith("#CHROM")) { - const tokens = line.split("\t"); - - if (tokens.length > 8) { - - // call set names -- use column index for id - header.callSets = []; - for (let j = 9; j < tokens.length; j++) { - header.callSets.push({id: j, name: tokens[j]}); - } - } - } - - } else { - break - } - - } - - this.header = header; // Will need to intrepret genotypes and info field - - return header - } - - - /** - * Parse data as a collection of Variant objects. - * - * @param data - * @returns {Array} - */ - async parseFeatures(dataWrapper) { - - const allFeatures = []; - const callSets = this.header.callSets; - const nExpectedColumns = 8 + (callSets ? callSets.length + 1 : 0); - let line; - while ((line = await dataWrapper.nextLine()) !== undefined) { - if (line && !line.startsWith("#")) { - - const tokens = line.split("\t"); - if (tokens.length === nExpectedColumns) { - const variant = createVCFVariant(tokens); - variant.header = this.header; // Keep a pointer to the header to interpret fields for popup text - //variant.line = line // Uncomment for debugging - allFeatures.push(variant); - - if (tokens.length > 9) { - - // Format - const callFields = extractCallFields(tokens[8].split(":")); - - variant.calls = {}; - for (let index = 9; index < tokens.length; index++) { - - const token = tokens[index]; - - const callSet = callSets[index - 9]; - const call = { - callSetName: callSet.name, - info: {} - }; - - variant.calls[callSet.id] = call; - - token.split(":").forEach(function (callToken, idx) { - - switch (idx) { - case callFields.genotypeIndex: - call.genotype = []; - callToken.split(/[\|\/]/).forEach(function (s) { - call.genotype.push('.' === s ? s : parseInt(s)); - }); - break - - default: - call.info[callFields.fields[idx]] = callToken; - } - }); - } - } - - // If this is a structural variant create a complement of this variant for the other end - // The test for "SV" is not comprehensive, there is not yet a standard for this - if (variant.info && variant.info.CHR2 && variant.info.END) { - allFeatures.push(svComplement(variant)); - } - } - } - } - - return allFeatures - } -} - -function extractCallFields(tokens) { - - const callFields = { - genotypeIndex: -1, - fields: tokens - }; - for (let i = 0; i < tokens.length; i++) { - if ("GT" === tokens[i]) { - callFields.genotypeIndex = i; - } - } - return callFields -} - -function svComplement(v) { - - const chr2 = v.info.CHR2; - const pos2 = Number.parseInt(v.info.END); - return { - chr: chr2, - start: pos2 - 1, - end: pos2, - _f: v - } - -} - -/** - * Parser for IGV desktop GWAS files. See http://software.broadinstitute.org/software/igv/GWAS - */ -class GWASParser { - - constructor(config) { - // Defaults - can be overriden by header - this.config = config; - if (config.columns) { - if (config.columns.chromosome === undefined || - config.columns.position === undefined || - config.columns.value === undefined) { - throw Error("columns property must define chrCol, posCol, and valueCol") - } - this.posCol = config.columns.position - 1; - this.chrCol = config.columns.chromosome - 1; - this.valueCol = config.columns.value - 1; - } else { - // Defaults -- can be overriden in header - this.posCol = 2; - this.chrCol = 1; - this.valueCol = 3; - } - } - - async parseHeader(dataWrapper) { - const headerLine = await dataWrapper.nextLine(); - return this.parseHeaderLine(headerLine) - } - - parseHeaderLine(headerLine) { - this.columns = headerLine.split(/\t/); - if (!this.config.columns) { - for (let i = 0; i < this.columns.length; i++) { - const c = this.columns[i].toLowerCase(); - switch (c) { - case 'chr': - case 'chromosome': - case 'chr_id': - this.chrCol = i; - break - case 'bp': - case 'pos': - case 'position': - case 'chr_pos': - this.posCol = i; - break - case 'p': - case 'pval': - case 'pvalue': - case 'p-value': - case 'p.value': - this.valueCol = i; - break - } - } - } - return this.columns - } - - async parseFeatures(dataWrapper) { - - const allFeatures = []; - const headerLine = dataWrapper.nextLine(); - if (!this.columns) { - this.parseHeaderLine(headerLine); - } - let line; - while ((line = dataWrapper.nextLine()) !== undefined) { - const tokens = line.split(/\t/); - if (tokens.length === this.columns.length) { - const chr = tokens[this.chrCol]; - const start = parseInt(tokens[this.posCol]) - 1; - const end = start + 1; - const value = Number(tokens[this.valueCol]); - allFeatures.push(new GWASFeature({ - chr: chr, - start: start, - end: end, - value: value, - line: line, - columns: this.columns - })); - } - } - return allFeatures - } -} - -class GWASFeature { - - constructor({chr, start, end, value, line, columns}) { - this.chr = chr; - this.start = start; - this.end = end; - this.value = value; - this.line = line; - this.columns = columns; - } - - popupData() { - const tokens = this.line.split(/\t/); - return this.columns.map(function (c, index) { - return {name: c, value: tokens[index]} - }) - } - - getAttribute(attrName) { - const tokens = this.line.split(/\t/); - for (let i = 0; i < this.columns.length; i++) { - if (this.columns[i] === attrName) { - return tokens[i] - } - } - return undefined - } - -} - -/* - * The MIT License (MIT) - * - * Copyright (c) 2014 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -/** - * Define parsers for bed-like files (.bed, .gff, .vcf, etc). A parser should implement 2 methods - * - * parseHeader(data) - return an object representing a header or metadata. Details are format specific - * - * parseFeatures(data) - return an array of features - * - */ - -var aedRegexpNoNamespace = new RegExp("([^:]*)\\(([^)]*)\\)"); // name(type) for AED parsing (namespace undefined) -var aedRegexpNamespace = new RegExp("([^:]*):([^(]*)\\(([^)]*)\\)"); // namespace:name(type) for AED parsing - - -class AEDParser { - - constructor(config) { - const decode = config ? config.decode : undefined; - this.nameField = config ? config.nameField : undefined; - this.skipRows = 0; // The number of fixed header rows to skip. Override for specific types as needed - if (decode) { - this.decode = decode; - } else { - this.decode = decodeAed; - } - this.delimiter = "\t"; - } - - async parseHeader(dataWrapper) { - let line; - let header; - while (line = await dataWrapper.nextLine()) { - if (line.startsWith("track") || line.startsWith("#") || line.startsWith("browser")) { - if (line.startsWith("track") || line.startsWith("#track")) { - let h = parseTrackLine(line); - if (header) { - Object.assign(header, h); - } else { - header = h; - } - } else if (line.startsWith("#columns")) { - let h = parseColumnsDirective(line); - if (header) { - Object.assign(header, h); - } else { - header = h; - } - } else if (line.startsWith("##gff-version 3")) { - this.format = "gff3"; - if (!header) header = {}; - header["format"] = "gff3"; - } - } else { - break - } - } - this.header = header; // Directives might be needed for parsing lines - return header - } - - async parseFeatures(dataWrapper) { - - const allFeatures = []; - const decode = this.decode; - const delimiter = this.delimiter || "\t"; - let i = 0; - let line; - let wig; - - while ((line = dataWrapper.nextLine()) !== undefined) { - i++; - if (i <= this.skipRows || line.startsWith("track") || line.startsWith("#") || line.startsWith("browser")) { - continue - } - - let tokens = readTokensAed(); - if (tokens.length < 1) { - continue - } - - if (!this.aed) { - // Store information about the aed header in the parser itself - // This is done only once - on the first row - this.aed = parseAedHeaderRow(tokens); - continue - } - - const feature = decode.call(this, tokens, wig); - if (feature) { - allFeatures.push(feature); - } - } - - return allFeatures - - // Double quoted strings can contain newlines in AED - // "" is an escape for a ". - // Parse all this, clean it up, split into tokens in a custom way - function readTokensAed() { - var tokens = [], - token = "", - quotedString = false, - n, - c; - - while (line || line === '') { - for (n = 0; n < line.length; n++) { - c = line.charAt(n); - if (c === delimiter) { - if (!quotedString) { - tokens.push(token); - token = ""; - } else { - token += c; - } - } else if (c === "\"") { - // Look ahead to the next character - if (n + 1 < line.length && line.charAt(n + 1) === "\"") { - if (quotedString) { - // Turn "" into a single " in the output string - token += "\""; - } - // Skip the next double quote - n++; - } else { - // We know the next character is NOT a double quote, flip our state - quotedString = !quotedString; - } - } else { - token += c; - } - } - // We are at the end of the line - if (quotedString) { - token += '\n'; // Add newline to the token - line = nextLine(); // Keep going - } else { - // We can end the loop - break - } - } - // Push the last token - tokens.push(token); - return tokens - } - } -} - - -function parseAedToken(value) { - // Example: refseq:accessionNumber(aed:String) - // refseq - namespace, will be declared later - // accessionNumber - name of the field - // aed:String - type of the field - // The namespace part may be missing - var match = aedRegexpNamespace.exec(value); - if (match) { - return { - namespace: match[1], - name: match[2], - type: match[3] - } - } - - match = aedRegexpNoNamespace.exec(value); - if (match) { - return { - namespace: '?', - name: match[1], - type: match[2] - } - } else { - throw new Error("Error parsing the header row of AED file - column not in ns:name(ns:type) format") - } -} - -function parseAedHeaderRow(tokens) { - // First row of AED file defines column names - // Each header item is an aed token - see parseAedToken - var aed, - k, - token, - aedToken; - - // Initialize aed section to be filled in - aed = { - columns: [ // Information about the namespace, name and type of each column - // Example entry: - // { namespace: 'bio', name: 'start', type: 'aed:Integer' } - ], - metadata: { // Metadata about the entire AED file - // Example: - // { - // aed: { - // application: { value: "CHaS Browser 3.3.0.139 (r10838)", type: "aed:String" }, - // created: { value: "2018-01-02T10:20:30.123+01:00", type: "aed:DateTime" }, - // modified: { value: "2018-03-04T11:22:33.456+01:00", type: "aed:DateTime" }, - // } - // affx: { - // ucscGenomeVersion: { value: "hg19", type: "aed:String" } - // }, - // namespace: { - // omim: { value: "http://affymetrix.com/ontology/www.ncbi.nlm.nih.gov/omim/", type: "aed:URI" }, - // affx: { value: "http://affymetrix.com/ontology/", type: "aed:URI" }, - // refseq: { value: "http://affymetrix.com/ontology/www.ncbi.nlm.nih.gov/RefSeq/", type: "aed:URI" } - // } - // } - } - }; - for (k = 0; k < tokens.length; k++) { - token = tokens[k]; - aedToken = parseAedToken(token); - aed.columns.push(aedToken); - } - - return aed -} - -function parseTrackLine(line) { - - const properties = {}; - const tokens = line.split(/(?:")([^"]+)(?:")|([^\s"]+)(?=\s+|$)/g); - - - // Clean up tokens array - let curr; - const tmp = []; - for (let tk of tokens) { - if (!tk || tk.trim().length === 0) continue - if (tk.endsWith("=") > 0) { - curr = tk; - } else if (curr) { - tmp.push(curr + tk); - curr = undefined; - } else { - tmp.push(tk); - } - } - for (let str of tmp) { - if (!str) return - var kv = str.split('=', 2); - if (kv.length === 2) { - const key = kv[0].trim(); - const value = kv[1].trim(); - properties[key] = value; - } - - } - - return properties -} - -function parseColumnsDirective(line) { - - let properties = {}; - let t1 = line.split(/\s+/); - - if (t1.length === 2) { - - let t2 = t1[1].split(";"); - - t2.forEach(function (keyValue) { - - let t = keyValue.split("="); - - if (t[0] === "color") { - properties.colorColumn = Number.parseInt(t[1]) - 1; - } else if (t[0] === "thickness") { - properties.thicknessColumn = Number.parseInt(t[1]) - 1; - } - }); - } - - return properties -} - -/** - * AED file feature. - * - * @param aed link to the AED file object containing file-level metadata and column descriptors - * @param allColumns All columns as parsed from the AED - * - * Other values are parsed one by one - */ -function AedFeature(aed, allColumns) { - var token, aedColumn, aedColumns = aed.columns; - - // Link to AED file (for metadata) - this.aed = aed; - - // Unparsed columns from AED file - this.allColumns = allColumns; - - // Prepare space for the parsed values - this.chr = null; - this.start = null; - this.end = null; - this.score = 1000; - this.strand = '.'; - this.cdStart = null; - this.cdEnd = null; - this.name = null; - this.color = null; - - for (let i = 0; i < allColumns.length; i++) { - token = allColumns[i]; - if (!token) { - // Skip empty fields - continue - } - aedColumn = aedColumns[i]; - if (aedColumn.type === 'aed:Integer') { - token = parseInt(token); - } - var arr = []; - if (aedColumn.namespace.length > 0) { - for (let j = 0; j < aedColumn.namespace.length; j++) { - arr.push(aedColumn.namespace.charCodeAt(j)); - } - } - if (aedColumn.namespace.trim() === 'bio') { - if (aedColumn.name === 'sequence') { - this.chr = token; - } else if (aedColumn.name === 'start') { - this.start = token; - } else if (aedColumn.name === 'end') { - this.end = token; - } else if (aedColumn.name === 'cdsMin') { - this.cdStart = token; - } else if (aedColumn.name === 'cdsMax') { - this.cdEnd = token; - } else if (aedColumn.name === 'strand') { - this.strand = token; - } - } else if (aedColumn.namespace === 'aed') { - if (aedColumn.name === 'name') { - this.name = token; - } - } else if (aedColumn.namespace === 'style') { - if (aedColumn.name === 'color') { - this.color = IGVColor.createColorString(token); - } - } - } -} - -AedFeature.prototype.popupData = function () { - var data = [], - aed = this.aed; - // Just dump everything we have for now - for (var i = 0; i < this.allColumns.length; i++) { - var featureValue = this.allColumns[i]; - var name = aed.columns[i].name; - // Skip columns that are not interesting - you know the sequence, and you can see color - if (name !== 'sequence' && name !== 'color') { - if (featureValue) { - data.push({name: name, value: featureValue}); - } - } - } - return data -}; - -/** - * Decode the AED file format - * @param tokens - * @param ignore - * @returns decoded feature, or null if this is not a valid record - */ -function decodeAed(tokens, ignore) { - var name, value, token, - nonEmptyTokens = 0, - aedColumns = this.aed.columns, - aedColumn, - aedKey, - i; - - // Each aed row must match the exact number of columns or we skip it - if (tokens.length !== aedColumns.length) { - console.log('Corrupted AED file row: ' + tokens.join(',')); - return undefined - } - - for (i = 0; i < tokens.length; i++) { - aedColumn = aedColumns[i]; - token = tokens[i]; - if (token !== '') { - nonEmptyTokens++; - } - if (aedColumn.name === 'name' && aedColumn.namespace === 'aed') { - name = token; - } else if (aedColumn.name === 'value' && aedColumn.namespace === 'aed') { - value = token; - } - } - - if (nonEmptyTokens === 2 && name && value) { - // Special row that defines metadata for the entire file - aedKey = parseAedToken(name); - // Store in the metadata section - if (!this.aed.metadata[aedKey.namespace]) { - this.aed.metadata[aedKey.namespace] = {}; - } - if (!this.aed.metadata[aedKey.namespace][aedKey.name]) { - this.aed.metadata[aedKey.namespace][aedKey.name] = { - type: aedKey.type, - value: value - }; - } - // Ignore this value - return undefined - } - - var feature = new AedFeature(this.aed, tokens); - - if (!feature.chr || (!feature.start && feature.start !== 0) || !feature.end) { - console.log('Cannot parse feature: ' + tokens.join(',')); - return undefined - } - - return feature -} - -/* - * The MIT License (MIT) - * - * Copyright (c) 2014 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - -// TODO -- big endian? - -class BinaryParser$1 { - constructor(dataView, littleEndian) { - - this.littleEndian = littleEndian !== undefined ? littleEndian : true; - this.position = 0; - this.view = dataView; - this.length = dataView.byteLength; - } - - available() { - return this.length - this.position - } - - remLength() { - return this.length - this.position - } - - hasNext() { - return this.position < this.length - 1 - } - - getByte() { - var retValue = this.view.getUint8(this.position, this.littleEndian); - this.position++; - return retValue - } - - getShort() { - - var retValue = this.view.getInt16(this.position, this.littleEndian); - this.position += 2; - return retValue - } - - getUShort() { - - // var byte1 = this.getByte(), - // byte2 = this.getByte(), - // retValue = ((byte2 << 24 >>> 16) + (byte1 << 24 >>> 24)); - // return retValue; - - // - var retValue = this.view.getUint16(this.position, this.littleEndian); - this.position += 2; - return retValue - } - - - getInt() { - - var retValue = this.view.getInt32(this.position, this.littleEndian); - this.position += 4; - return retValue - } - - - getUInt() { - var retValue = this.view.getUint32(this.position, this.littleEndian); - this.position += 4; - return retValue - } - - getLong() { - - // DataView doesn't support long. So we'll try manually - - var b = []; - b[0] = this.view.getUint8(this.position); - b[1] = this.view.getUint8(this.position + 1); - b[2] = this.view.getUint8(this.position + 2); - b[3] = this.view.getUint8(this.position + 3); - b[4] = this.view.getUint8(this.position + 4); - b[5] = this.view.getUint8(this.position + 5); - b[6] = this.view.getUint8(this.position + 6); - b[7] = this.view.getUint8(this.position + 7); - - var value = 0; - if (this.littleEndian) { - for (let i = b.length - 1; i >= 0; i--) { - value = (value * 256) + b[i]; - } - } else { - for (let i = 0; i < b.length; i++) { - value = (value * 256) + b[i]; - } - } - - - this.position += 8; - return value - } - - getString(len) { - - var s = ""; - var c; - while ((c = this.view.getUint8(this.position++)) !== 0) { - s += String.fromCharCode(c); - if (len && s.length === len) break - } - return s - } - - getFixedLengthString(len) { - - var s = ""; - var i; - var c; - for (i = 0; i < len; i++) { - c = this.view.getUint8(this.position++); - if (c > 0) { - s += String.fromCharCode(c); - } - } - return s - } - - getFixedLengthTrimmedString(len) { - - var s = ""; - var i; - var c; - for (i = 0; i < len; i++) { - c = this.view.getUint8(this.position++); - if (c > 32) { - s += String.fromCharCode(c); - } - } - return s - } - - getFloat() { - - var retValue = this.view.getFloat32(this.position, this.littleEndian); - this.position += 4; - return retValue - - - } - - getDouble() { - - var retValue = this.view.getFloat64(this.position, this.littleEndian); - this.position += 8; - return retValue - } - - skip(n) { - - this.position += n; - return this.position - } - - - /** - * Return a BGZip (bam and tabix) virtual pointer - * TODO -- why isn't 8th byte used ? - * @returns {*} - */ - getVPointer() { - - var position = this.position, - offset = (this.view.getUint8(position + 1) << 8) | (this.view.getUint8(position)), - byte6 = ((this.view.getUint8(position + 6) & 0xff) * 0x100000000), - byte5 = ((this.view.getUint8(position + 5) & 0xff) * 0x1000000), - byte4 = ((this.view.getUint8(position + 4) & 0xff) * 0x10000), - byte3 = ((this.view.getUint8(position + 3) & 0xff) * 0x100), - byte2 = ((this.view.getUint8(position + 2) & 0xff)), - block = byte6 + byte5 + byte4 + byte3 + byte2; - this.position += 8; - - // if (block == 0 && offset == 0) { - // return null; - // } else { - return new VPointer$1(block, offset) - // } - } -} - -class VPointer$1 { - constructor(block, offset) { - this.block = block; - this.offset = offset; - } - - isLessThan(vp) { - return this.block < vp.block || - (this.block === vp.block && this.offset < vp.offset) - } - - isGreaterThan(vp) { - return this.block > vp.block || - (this.block === vp.block && this.offset > vp.offset) - } - - isEqualTo(vp) { - return this.block === vp.block && this.offset === vp.offset - } - - print() { - return "" + this.block + ":" + this.offset - } -} - -function optimizeChunks(chunks, lowest) { - - if (chunks.length === 0) return chunks - - chunks.sort(function (c0, c1) { - - const dif = c0.minv.block - c1.minv.block; - if (dif !== 0) { - return dif - } else { - return c0.minv.offset - c1.minv.offset - } - }); - - if(chunks.length <= 1) { - return chunks - } - - // console.log("Before trimming " + chunks.length) - // for (let c of chunks) { - // console.log(`${c.minv.block} ${c.minv.offset} - ${c.maxv.block} ${c.maxv.offset}`) - // } - - if (lowest) { - chunks = chunks.filter(c => c.maxv.isGreaterThan(lowest)); - } - - // console.log("Before merging " + chunks.length) - // for (let c of chunks) { - // console.log(`${c.minv.block} ${c.minv.offset} - ${c.maxv.block} ${c.maxv.offset}`) - // } - - const mergedChunks = []; - let lastChunk; - for (let chunk of chunks) { - - if (!lastChunk) { - mergedChunks.push(chunk); - lastChunk = chunk; - } else { - if (canMerge(lastChunk, chunk)) { - if (chunk.maxv.isGreaterThan(lastChunk.maxv)) { - lastChunk.maxv = chunk.maxv; - } - } else { - mergedChunks.push(chunk); - lastChunk = chunk; - } - } - } - - // console.log("After merging " + mergedChunks.length) - // for (let c of mergedChunks) { - // console.log(`${c.minv.block} ${c.minv.offset} - ${c.maxv.block} ${c.maxv.offset}`) - // } - - return mergedChunks -} - - -/** - * Merge 2 blocks if the file position gap between them is < 16 kb, and the total size is < ~5 mb - * @param chunk1 - * @param chunk2 - * @returns {boolean|boolean} - */ -function canMerge(chunk1, chunk2) { - chunk2.minv.block - chunk1.maxv.block; - const sizeEstimate = chunk1.maxv.block - chunk1.minv.block; - return sizeEstimate < 5000000 -} - -// Represents a CSI Bam or Tabix index - -const CSI1_MAGIC$1 = 21582659; // CSI\1 -const CSI2_MAGIC$1 = 38359875; // CSI\2 - -async function parseCsiIndex(arrayBuffer, genome) { - - const idx = new CSIIndex(); - idx.parse(arrayBuffer, genome); - return idx -} - -class CSIIndex { - - constructor(tabix) { - this.tabix = true; // Means whatever is indexed is BGZipped - } - - parse(arrayBuffer, genome) { - const parser = new BinaryParser$1(new DataView(arrayBuffer)); - - const magic = parser.getInt(); - - if (magic !== CSI1_MAGIC$1) { - if (magic === CSI2_MAGIC$1) { - throw Error("CSI version 2 is not supported. Please enter an issue at https://github.com/igvteam/igv.js") - } else { - throw Error("Not a CSI index") - } - } - - this.indices = []; - this.blockMin = Number.MAX_SAFE_INTEGER; - this.lastBlockPosition = []; - this.sequenceIndexMap = {}; - - this.minShift = parser.getInt(); - this.depth = parser.getInt(); - const lAux = parser.getInt(); - const seqNames = []; - let bmax = 0; - - if (lAux >= 28) { - // Tabix header parameters aren't used, but they must be read to advance the pointer - parser.getInt(); - parser.getInt(); - parser.getInt(); - parser.getInt(); - parser.getInt(); - parser.getInt(); - const l_nm = parser.getInt(); - const nameEndPos = parser.position + l_nm; - let i = 0; - while (parser.position < nameEndPos) { - let seq_name = parser.getString(); - // Translate to "official" chr name. - if (genome) { - seq_name = genome.getChromosomeName(seq_name); - } - this.sequenceIndexMap[seq_name] = i; - seqNames[i] = seq_name; - i++; - } - } - - const MAX_BIN = this.bin_limit() + 1; - const nref = parser.getInt(); - for (let ref = 0; ref < nref; ref++) { - const binIndex = []; - const loffset = []; - const nbin = parser.getInt(); - for (let b = 0; b < nbin; b++) { - - const binNumber = parser.getInt(); - loffset[binNumber] = parser.getVPointer(); - - if (binNumber > MAX_BIN) { - // This is a psuedo bin, not used but we have to consume the bytes - parser.getInt(); // # of chunks for this bin - parser.getVPointer(); // unmapped beg - parser.getVPointer(); // unmapped end - parser.getLong(); - parser.getLong(); - - } else { - - binIndex[binNumber] = []; - const nchnk = parser.getInt(); // # of chunks for this bin - - for (let i = 0; i < nchnk; i++) { - const cs = parser.getVPointer(); //chunk_beg - const ce = parser.getVPointer(); //chunk_end - if (cs && ce) { - if (cs.block < this.blockMin) { - this.blockMin = cs.block; // Block containing first alignment - } - if (ce.block > bmax) { - bmax = ce.block; - } - binIndex[binNumber].push([cs, ce]); - } - } - } - } - - if (nbin > 0) { - this.indices[ref] = { - binIndex: binIndex, - loffset: loffset - }; - } - } - this.lastBlockPosition = bmax; - } - - get chromosomeNames() { - return Object.keys(this.sequenceIndexMap) - } - - /** - * Fetch blocks for a particular genomic range. This method is public so it can be unit-tested. - * - * @param refId the sequence dictionary index of the chromosome - * @param min genomic start position - * @param max genomic end position - * @param return an array of {minv: {filePointer, offset}, {maxv: {filePointer, offset}} - */ - chunksForRange(refId, min, max) { - - const ba = this.indices[refId]; - if (!ba) { - return [] - } else { - const overlappingBins = this.reg2bins(min, max); // List of bin #s that overlap min, max - if (overlappingBins.length == 0) return [] - - const chunks = []; - // Find chunks in overlapping bins. Leaf bins (< 4681) are not pruned - for (let binRange of overlappingBins) { - for (let bin = binRange[0]; bin <= binRange[1]; bin++) { - if (ba.binIndex[bin]) { - const binChunks = ba.binIndex[bin]; - for (let c of binChunks) { - const cs = c[0]; - const ce = c[1]; - chunks.push({minv: cs, maxv: ce, bin: bin}); - } - } - } - } - - const lowestOffset = ba.loffset[overlappingBins[0]]; - - return optimizeChunks(chunks, lowestOffset) - } - - } - - // reg2bins implementation adapted from GMOD/tabix-js https://github.com/GMOD/tabix-js/blob/master/src/csi.ts - reg2bins(beg, end) { - beg -= 1; // < convert to 1-based closed - if (beg < 1) beg = 1; - if (end > 2 ** 34) end = 2 ** 34; // 17 GiB ought to be enough for anybody - end -= 1; - let l = 0; - let t = 0; - let s = this.minShift + this.depth * 3; - const bins = []; - for (; l <= this.depth; s -= 3, t += (1 << l * 3), l += 1) { - const b = t + (beg >> s); - const e = t + (end >> s); - // - // ITS NOT CLEAR WHERE THIS TEST CAME FROM, but maxBinNumber is never set, and its not clear what it represents. - // if (e - b + bins.length > this.maxBinNumber) - // throw new Error( - // `query ${beg}-${end} is too large for current binning scheme (shift ${this.minShift}, depth ${this.depth}), try a smaller query or a coarser index binning scheme`, - // ) - // - bins.push([b, e]); - } - return bins - } - - - bin_limit() { - return ((1 << (this.depth + 1) * 3) - 1) / 7 - } - -} - -// Represents a BAM or Tabix index. - -const BAI_MAGIC$1 = 21578050; -const TABIX_MAGIC$1 = 21578324; - - -async function parseBamIndex(arrayBuffer, genome) { - const index = new BamIndex(); - await index.parse(arrayBuffer, false, genome); - return index -} - -async function parseTabixIndex(arrayBuffer, genome) { - const index = new BamIndex(); - await index.parse(arrayBuffer, true, genome); - return index -} - -class BamIndex { - - constructor() { - - } - - async parse(arrayBuffer, tabix, genome) { - - const indices = []; - let blockMin = Number.MAX_SAFE_INTEGER; - let blockMax = 0; - - const parser = new BinaryParser$1(new DataView(arrayBuffer)); - const magic = parser.getInt(); - const sequenceIndexMap = {}; - if (magic === BAI_MAGIC$1 || (tabix && magic === TABIX_MAGIC$1)) { - - const nref = parser.getInt(); - if (tabix) { - // Tabix header parameters aren't used, but they must be read to advance the pointer - parser.getInt(); - parser.getInt(); - parser.getInt(); - parser.getInt(); - parser.getInt(); - parser.getInt(); - parser.getInt(); - - for (let i = 0; i < nref; i++) { - let seq_name = parser.getString(); - // Translate to "official" chr name. - if (genome) { - seq_name = genome.getChromosomeName(seq_name); - } - sequenceIndexMap[seq_name] = i; - } - } - - // Loop through sequences - for (let ref = 0; ref < nref; ref++) { - - const binIndex = {}; - const linearIndex = []; - const nbin = parser.getInt(); - - for (let b = 0; b < nbin; b++) { - const binNumber = parser.getInt(); - if (binNumber === 37450) { - // This is a psuedo bin, not used but we have to consume the bytes - parser.getInt(); // # of chunks for this bin - parser.getVPointer(); // unmapped beg - parser.getVPointer(); // unmapped end - parser.getLong(); - parser.getLong(); - - } else { - - binIndex[binNumber] = []; - const nchnk = parser.getInt(); // # of chunks for this bin - - for (let i = 0; i < nchnk; i++) { - const cs = parser.getVPointer(); //chunk_beg - const ce = parser.getVPointer(); //chunk_end - if (cs && ce) { - if (cs.block < blockMin) { - blockMin = cs.block; // Block containing first alignment - } - if (ce.block > blockMax) { - blockMax = ce.block; - } - binIndex[binNumber].push([cs, ce]); - } - } - } - } - - const nintv = parser.getInt(); - for (let i = 0; i < nintv; i++) { - const cs = parser.getVPointer(); - linearIndex.push(cs); // Might be null - } - - if (nbin > 0) { - indices[ref] = { - binIndex: binIndex, - linearIndex: linearIndex - }; - } - } - - this.firstBlockPosition = blockMin; - this.lastBlockPosition = blockMax; - this.indices = indices; - this.sequenceIndexMap = sequenceIndexMap; - this.tabix = tabix; - - } else { - throw new Error(indexURL + " is not a " + (tabix ? "tabix" : "bai") + " file") - } - - - } - - get chromosomeNames() { - return Object.keys(this.sequenceIndexMap) - } - - /** - * Fetch chunks for a particular genomic range. This method is public so it can be unit-tested. - * - * @param refId the sequence dictionary index of the chromosome - * @param min genomic start position - * @param max genomic end position - * @param return an array of objects representing chunks (file spans) {minv: {block, offset}, {maxv: {block, offset}} - */ - chunksForRange(refId, min, max) { - - const bam = this; - const ba = bam.indices[refId]; - - if (!ba) { - return [] - } else { - const overlappingBins = reg2bins(min, max); // List of bin #s that overlap min, max - - //console.log("bin ranges") - //for(let b of overlappingBins) { - // console.log(`${b[0]} - ${b[1]}`) - //} - - const chunks = []; - // Find chunks in overlapping bins. Leaf bins (< 4681) are not pruned - for (let binRange of overlappingBins) { - for (let bin = binRange[0]; bin <= binRange[1]; bin++) { - if (ba.binIndex[bin]) { - const binChunks = ba.binIndex[bin]; - for (let c of binChunks) { - const cs = c[0]; - const ce = c[1]; - chunks.push({minv: cs, maxv: ce}); - } - } - } - } - - // Use the linear index to find minimum file position of chunks that could contain alignments in the region - const nintv = ba.linearIndex.length; - - let lowest; - const minLin = Math.min(min >> 14, nintv - 1); // i.e. min / 16384 - const maxLin = Math.min(max >> 14, nintv - 1); - for (let i = minLin; i <= maxLin; i++) { - const vp = ba.linearIndex[i]; - if (vp) { - lowest = vp; // lowest file offset that contains alignments overlapping (min, max) - break - } - } - - return optimizeChunks(chunks, lowest) - } - } -} - - - -/** - * Calculate the list of bins that overlap with region [beg, end] - * - */ -function reg2bins(beg, end) { - const list = []; - if (end >= 1 << 29) end = 1 << 29; - --end; - list.push([0, 0]); - list.push([1 + (beg >> 26), 1 + (end >> 26)]); - list.push([9 + (beg >> 23), 9 + (end >> 23)]); - list.push([73 + (beg >> 20), 73 + (end >> 20)]); - list.push([585 + (beg >> 17), 585 + (end >> 17)]); - list.push([4681 + (beg >> 14), 4681 + (end >> 14)]); - - // for (k = 1 + (beg >> 26); k <= 1 + (end >> 26); ++k) list.push(k); - // for (k = 9 + (beg >> 23); k <= 9 + (end >> 23); ++k) list.push(k); - // for (k = 73 + (beg >> 20); k <= 73 + (end >> 20); ++k) list.push(k); - // for (k = 585 + (beg >> 17); k <= 585 + (end >> 17); ++k) list.push(k); - // for (k = 4681 + (beg >> 14); k <= 4681 + (end >> 14); ++k) list.push(k); - return list -} - -/* - * The MIT License (MIT) - * - * Copyright (c) 2014 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -async function parseTribbleIndex(arrayBuffer, genome) { - - const index = new TribbleIndex(); - index.parse(arrayBuffer, genome); - return index -} - -class TribbleIndex { - - constructor() { - - } - - async parse(arrayBuffer, genome) { - - let blockMax = 0; - this.chrIndex = {}; - this.lastBlockPosition = []; - const parser = new BinaryParser$1(new DataView(arrayBuffer)); - readHeader(parser); - - let nChrs = parser.getInt(); - while (nChrs-- > 0) { - - // todo -- support interval tree index, we're assuming its a linear index - - let chr = parser.getString(); - if (genome) chr = genome.getChromosomeName(chr); // Translate to canonical name - - const binWidth = parser.getInt(); - const nBins = parser.getInt(); - const longestFeature = parser.getInt(); - parser.getInt() > 0; - parser.getInt(); - - // note the code below accounts for > 60% of the total time to read an index - let pos = parser.getLong(); - const blocks = []; - for (let binNumber = 0; binNumber < nBins; binNumber++) { - const nextPos = parser.getLong(); - blocks.push({min: pos, max: nextPos}); // {position: pos, size: size}); - pos = nextPos; - if (nextPos > blockMax) { - blockMax = nextPos; - } - } - this.chrIndex[chr] = {chr: chr, blocks: blocks, longestFeature: longestFeature, binWidth: binWidth}; - } - - this.lastBlockPosition = blockMax; - - - /** - * Read the header . Data here is not used in igv.js but we need to read it to advance the pointer. - * @param parser - */ - function readHeader(parser) { - - parser.getInt(); // view._getInt32(offset += 32, true); - parser.getInt(); - const version = parser.getInt(); - parser.getString(); - parser.getLong(); - parser.getLong(); - parser.getString(); - parser.getInt(); - if (version >= 3) { - let nProperties = parser.getInt(); - while (nProperties-- > 0) { - parser.getString(); - parser.getString(); - } - } - } - } - - get chromosomeNames() { - return Object.keys(this.chrIndex) - } - - - /** - * Fetch blocks for a particular genomic range. - * - * @param queryChr the sequence dictionary index of the chromosome - * @param min genomic start position - * @param max genomic end position - */ - chunksForRange(queryChr, min, max) { //function (refId, min, max) { - const chrIdx = this.chrIndex[queryChr]; - - if (chrIdx) { - const blocks = chrIdx.blocks; - const longestFeature = chrIdx.longestFeature; - const binWidth = chrIdx.binWidth; - const adjustedPosition = Math.max(min - longestFeature, 0); - const startBinNumber = Math.floor(adjustedPosition / binWidth); - - if (startBinNumber >= blocks.length) // are we off the end of the bin list, so return nothing - return [] - else { - const endBinNumber = Math.min(Math.floor((max - 1) / binWidth), blocks.length - 1); - - // By definition blocks are adjacent in the file for the liner index. Combine them into one merged block - const startPos = blocks[startBinNumber].min; - const endPos = blocks[endBinNumber].max; - const size = endPos - startPos; - if (size === 0) { - return [] - } else { - const mergedBlock = {minv: {block: startPos, offset: 0}, maxv: {block: endPos, offset: 0}}; - return [mergedBlock] - } - } - } else { - return undefined - } - } -} - -const CSI1_MAGIC = 21582659; // CSI\1 -const CSI2_MAGIC = 38359875; // CSI\2 -const BAI_MAGIC = 21578050; -const TABIX_MAGIC = 21578324; -const TRIBBLE_MAGIC = 1480870228; // byte[]{'T', 'I', 'D', 'X'}; - -/** - * @param indexURL - * @param config - * @param tabix - * - */ -async function loadIndex(indexURL, config, genome) { - - let arrayBuffer = await igvxhr.loadArrayBuffer(indexURL, buildOptions$1(config)); - let dv = new DataView(arrayBuffer); - - // Some indexs are bgzipped, specifically tabix, and csi. Bam (bai) are not. Tribble is usually not. - // Check first 2 bytes of file for gzip magic number, and inflate if neccessary - if (dv.getUint8(0) === 0x1f && dv.getUint8(1) === 0x8b) { // gzipped - const inflate = unbgzf(arrayBuffer); - arrayBuffer = inflate.buffer; - dv = new DataView(arrayBuffer); - } - - const magic = dv.getInt32(0, true); - switch (magic) { - case BAI_MAGIC: - return parseBamIndex(arrayBuffer, genome) - case TABIX_MAGIC: - return parseTabixIndex(arrayBuffer, genome) - case CSI1_MAGIC: - return parseCsiIndex(arrayBuffer, genome) - case TRIBBLE_MAGIC: - return parseTribbleIndex(arrayBuffer, genome) - case CSI2_MAGIC: - throw Error("CSI version 2 is not supported.") - default: - throw Error(`Unrecognized index type: ${indexURL}`) - } -} - -/* - * The MIT License (MIT) - * - * Copyright (c) 2016-2017 The Regents of the University of California - * Author: Jim Robinson - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -function getDataWrapper(data) { - - if (typeof (data) == 'string' || data instanceof String) { - return new StringDataWrapper(data) - } else { - return new ByteArrayDataWrapper(data) - } -} - - -// Data might be a string, or an UInt8Array -class StringDataWrapper { - - constructor(string) { - this.data = string; - this.ptr = 0; - } - - nextLine() { - var start = this.ptr, - idx = this.data.indexOf('\n', start), - data = this.data; - - if (idx > 0) { - this.ptr = idx + 1; // Advance pointer for next line - if (idx > start && data.charAt(idx - 1) === '\r') { - // Trim CR manually in CR/LF sequence - return data.substring(start, idx - 1) - } - return data.substring(start, idx) - } else { - var length = data.length; - this.ptr = length; - // Return undefined only at the very end of the data - return (start >= length) ? undefined : data.substring(start) - } - } -} - -class ByteArrayDataWrapper { - - constructor(array) { - this.data = array; - this.length = this.data.length; - this.ptr = 0; - } - - nextLine() { - - var c, result; - result = ""; - - if (this.ptr >= this.length) return undefined - - for (var i = this.ptr; i < this.length; i++) { - c = String.fromCharCode(this.data[i]); - if (c === '\r') continue - if (c === '\n') break - result = result + c; - } - - this.ptr = i + 1; - return result - } - -} - -/** - * Class to iterate line-by-line over a BGZipped text file. This class is useful for iterating from the start of - * the file. Not useful for indexed queries. - */ - -class BGZLineReader { - - constructor(config) { - this.config = config; - this.filePtr = 0; - this.bufferPtr = 0; - this.buffer; - } - - async nextLine() { - - let result = undefined; - - try { - while (true) { - const length = this.buffer ? this.buffer.length : 0; - while (this.bufferPtr < length) { - const c = String.fromCharCode(this.buffer[this.bufferPtr++]); - if (c === '\r') continue - if (c === '\n') { - return result - } - result = result ? result + c : c; - } - if (this.eof) { - return result - } else { - await this.readNextBlock(); - } - } - } catch (e) { - console.warn(e); - this.eof = true; - return result - } - } - - async readNextBlock() { - - const bsizeOptions = buildOptions$1(this.config, { - range: { - start: this.filePtr, - size: 26 - } - }); - const abuffer = await igvxhr.loadArrayBuffer(this.config.url, bsizeOptions); - const bufferSize = bgzBlockSize$1(abuffer); - - if (bufferSize === 0) { - this.eof = true; - this.buffer = undefined; - } else { - - const options = buildOptions$1(this.config, {range: {start: this.filePtr, size: bufferSize}}); - const data = await igvxhr.loadArrayBuffer(this.config.url, options); - if (data.byteLength < bufferSize) { - this.eof = true; // Assumption - } - this.buffer = unbgzf(data); - if(this.buffer.byteLength == 0) { - this.eof = true; - } - this.bufferPtr = 0; - this.filePtr += data.byteLength; //data.byteLength; - } - } - -} - -function concatenateArrayBuffers(arrayBuffers) { - - if (arrayBuffers.length === 1) { - return arrayBuffers[0] - } - - let len = 0; - for (const b of arrayBuffers) { - len += b.byteLength; - } - const c = new Uint8Array(len); - let offset = 0; - for (const b of arrayBuffers) { - c.set(new Uint8Array(b), offset); - offset += b.byteLength; - } - return c.buffer -} - -/** - * Return the block size for the data buffer. - * @param data - * @returns {number} - */ -const bgzBlockSize = (data) => { - const ba = ArrayBuffer.isView(data) ? data : new Uint8Array(data); - const bsize = (ba[17] << 8 | ba[16]) + 1; - return bsize -}; - -class BGZBlockLoader { - - constructor(config) { - this.config = config; - this.cacheBlocks = false != config.cacheBlocks; // Default to true - this.cache = undefined; - } - - /** - * Return inflated data from startBlock through endBlock as an UInt8Array - * - * @param minv minimum virtual pointer {block, offset} - * @param maxv maximum virtual pointer {block, offset} - * @returns {Promise} - */ - async getData(minv, maxv) { - - const startBlock = minv.block; - const endBlock = maxv.block; - const skipEnd = maxv.offset === 0; - - const blocks = await this.getInflatedBlocks(startBlock, endBlock, skipEnd); - if (blocks.length === 1) { - return blocks[0] - } - - let len = 0; - for (const b of blocks) { - len += b.byteLength; - } - const c = new Uint8Array(len); - let offset = 0; - for (const b of blocks) { - c.set(b, offset); - offset += b.byteLength; - } - return c - } - - /** - * Return the inflated data for the specified blocks as an array of Uint8Arrays. This method is public so - * it can be unit tested. * - * @param startBlock - * @param endBlock - * @returns {Promise<*[Uint8Array]>} - */ - async getInflatedBlocks(startBlock, endBlock, skipEnd) { - - if (!this.cacheBlocks) { - const buffer = await this.loadBLockData(startBlock, endBlock, {skipEnd}); - return inflateBlocks(buffer) - } else { - - const c = this.cache; - if (c && - c.startBlock <= startBlock && - (c.endBlock >= endBlock || skipEnd && c.nextEndBlock === endBlock)) { - //console.log("Complete overlap") - const startOffset = startBlock - c.startBlock; - const endOffset = endBlock - c.startBlock; - return inflateBlocks(c.buffer, startOffset, endOffset) - // Don't update cache, still valid - } else { - - let buffer; - if (!c || (c.startBlock > endBlock || c.endBlock < startBlock)) { - // no overlap with cache - buffer = await this.loadBLockData(startBlock, endBlock, {skipEnd}); - } else { - - //console.log("Some overlap") - const arrayBuffers = []; - - // Load blocks preceding cache start, if any - if (startBlock < c.startBlock) { - // load first blocks - const startBuffer = await this.loadBLockData(startBlock, c.startBlock, {skipEnd: true}); - arrayBuffers.push(startBuffer); - } - - // Slice cached buffer as needed - let cachedBuffer; - if (startBlock <= c.startBlock && endBlock >= c.endBlock) { - cachedBuffer = c.buffer; - } else { - const start = Math.max(0, startBlock - c.startBlock); - let end; - if (endBlock >= c.endBlock) { - end = c.buffer.byteLength; - } else { - // We need to find the byte position of the end of "endBlock" - const boundaries = findBlockBoundaries(c.buffer); - for (let i = 0; i < boundaries.length - 1; i++) { - if (c.startBlock + boundaries[i] === endBlock) { - end = boundaries[i + 1]; - break - } - } - // Do something if end not found - } - cachedBuffer = c.buffer.slice(start, end); - } - arrayBuffers.push(cachedBuffer); - - // Load end blocks, if any - if (endBlock > c.endBlock) { - const endBuffer = await this.loadBLockData(c.endBlock, endBlock, {skipStart: true, skipEnd}); - arrayBuffers.push(endBuffer); - } - - buffer = concatenateArrayBuffers(arrayBuffers); - } - - // If skipEnd === true we need to find boundary of last block in cache - let nextEndBlock = endBlock; - if(skipEnd) { - const boundaries = findBlockBoundaries(buffer); - endBlock = boundaries[boundaries.length - 1]; - } - - this.cache = {startBlock, endBlock, nextEndBlock, buffer}; - return inflateBlocks(buffer) - } - } - } - - async loadBLockData(startBlock, endBlock, options) { - - const config = this.config; - const skipStart = options && options.skipStart; - const skipEnd = options && options.skipEnd; - - // Get size of last block if not skipped - let lastBlockSize = 0; - if (!skipEnd) { - const bsizeOptions = buildOptions$1(config, {range: {start: endBlock, size: 26}}); - const abuffer = await igvxhr.loadArrayBuffer(config.url, bsizeOptions); - lastBlockSize = bgzBlockSize(abuffer); - } - - if (skipStart) { - const bsizeOptions = buildOptions$1(config, {range: {start: startBlock, size: 26}}); - const abuffer = await igvxhr.loadArrayBuffer(config.url, bsizeOptions); - startBlock += bgzBlockSize(abuffer); - } - - // Load data for all blocks - const loadOptions = buildOptions$1(config, { - range: { - start: startBlock, - size: endBlock + lastBlockSize - startBlock - } - }); - - //console.log(`${this.config.name} Loaded ${startBlock} - ${endBlock + lastBlockSize} (${(endBlock + lastBlockSize - startBlock) / 1000} kb)`) - - return igvxhr.loadArrayBuffer(config.url, loadOptions) - } -} - -function findBlockBoundaries(arrayBuffer) { - - const byteLengh = arrayBuffer.byteLength; - let offset = 0; - const blockBoundaries = [0]; - while (offset < byteLengh) { - //console.log("Cache block " + offset) - const ba = new Uint8Array(arrayBuffer, offset); - const bsize = (ba[17] << 8 | ba[16]) + 1; - offset += bsize; - if (offset < byteLengh) { - blockBoundaries.push(offset); - } - } - return blockBoundaries -} - - -/** - * Inflate compressed blocks within the data buffer* - * @param data - * @param startBlock - optional file location for start block. Default == 0 - * @param endBlock - optional file location for last block to decompress. - * @returns {*[]} - */ -function inflateBlocks(data, startBlock, endBlock) { - - startBlock = startBlock || 0; - - const oBlockList = []; - let ptr = startBlock; - - const lim = data.byteLength - 18; - while (ptr < lim) { - try { - //console.log(113873 + ptr) - const header = new Uint8Array(data, ptr, 18); - const xlen = (header[11] << 8) | (header[10]); - const bsize = ((header[17] << 8) | (header[16])); // Total block size, including header, minus 1 - const start = 12 + xlen + ptr; // Start of CDATA - const bytesLeft = data.byteLength - start; - const cDataSize = bsize - xlen - 18; - - if (bytesLeft < cDataSize || cDataSize <= 0) { - // This is unexpected. Throw error? - break - } - - const cdata = new Uint8Array(data, start, cDataSize); - const unc = inflateRaw_1(cdata); - oBlockList.push(unc); - - if (endBlock === ptr) { - break - } else { - // Advance to next block - ptr += bsize + 1; - } - - } catch (e) { - console.error(e); - break - } - } - return oBlockList -} - -/* - * The MIT License (MIT) - * - * Copyright (c) 2014 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -/** - * Reader for "bed like" files (tab delimited files with 1 feature per line: bed, gff, vcf, etc) - * - * @param config - * @constructor - */ -class FeatureFileReader { - - constructor(config, genome) { - - var uriParts; - - this.config = config || {}; - this.genome = genome; - this.indexURL = config.indexURL; - this.indexed = config.indexed || this.indexURL !== undefined; - this.queryable = this.indexed; - - if (isFile$1(this.config.url)) { - this.filename = this.config.url.name; - } else if (isDataURL(this.config.url)) { - this.indexed = false; // by definition - this.dataURI = config.url; - } else { - uriParts = parseUri(this.config.url); - this.filename = config.filename || uriParts.file; - } - - this.parser = this.getParser(this.config); - - if (this.config.format === "vcf" && !this.config.indexURL) { - console.warn("Warning: index file not specified. The entire vcf file will be loaded."); - } - - } - - async defaultVisibilityWindow() { - if (this.config.indexURL) { - const index = await this.getIndex(); - if (index && index.lastBlockPosition) { - let gl = 0; - const s = 10000; - for (let c of index.chromosomeNames) { - const chromosome = this.genome.getChromosome(c); - if (chromosome) { - gl += chromosome.bpLength; - } - } - return Math.round((gl / index.lastBlockPosition) * s) - } - } - } - - /** - * Return a promise to load features for the genomic interval - * @param chr - * @param start - * @param end - */ - async readFeatures(chr, start, end) { - - const index = await this.getIndex(); - if (index) { - this.indexed = true; - return this.loadFeaturesWithIndex(chr, start, end) - } else if (this.dataURI) { - this.indexed = false; - return this.loadFeaturesFromDataURI() - } else { - this.indexed = false; - return this.loadFeaturesNoIndex() - } - - } - - async readHeader() { - - if (this.dataURI) { - await this.loadFeaturesFromDataURI(this.dataURI); - return this.header - } else { - - if (this.config.indexURL) { - const index = await this.getIndex(); - if (!index) { - // Note - it should be impossible to get here - throw new Error("Unable to load index: " + this.config.indexURL) - } - - let dataWrapper; - if (index.tabix) { - this._blockLoader = new BGZBlockLoader(this.config); - dataWrapper = new BGZLineReader(this.config); - } else { - // Tribble - const maxSize = Object.values(index.chrIndex) - .flatMap(chr => chr.blocks) - .map(block => block.max) - .reduce((previous, current) => - Math.min(previous, current), Number.MAX_SAFE_INTEGER); - - const options = buildOptions$1(this.config, {bgz: index.tabix, range: {start: 0, size: maxSize}}); - const data = await igvxhr.loadString(this.config.url, options); - dataWrapper = getDataWrapper(data); - } - - - this.header = await this.parser.parseHeader(dataWrapper); // Cache header, might be needed to parse features - return this.header - - } else { - // If this is a non-indexed file we will load all features in advance - const options = buildOptions$1(this.config); - const data = await igvxhr.loadString(this.config.url, options); - let dataWrapper = getDataWrapper(data); - this.header = await this.parser.parseHeader(dataWrapper); - - // Reset data wrapper and parse features - dataWrapper = getDataWrapper(data); - this.features = await this.parser.parseFeatures(dataWrapper); // cache features - return this.header - } - } - } - - - getParser(config) { - - switch (config.format) { - case "vcf": - return new VcfParser(config) - case "seg" : - return new SegParser("seg") - case "mut": - return new SegParser("mut") - case "maf": - return new SegParser("maf") - case "gwas" : - return new GWASParser(config) - case "aed" : - return new AEDParser(config) - default: - return new FeatureParser(config) - } - } - - async loadFeaturesNoIndex() { - - if (this.features) { - // An optimization hack for non-indexed files, features are temporarily cached when header is read. - const tmp = this.features; - delete this.features; - return tmp - } else { - const options = buildOptions$1(this.config); // Add oauth token, if any - const data = await igvxhr.loadString(this.config.url, options); - if (!this.header) { - const dataWrapper = getDataWrapper(data); - this.header = await this.parser.parseHeader(dataWrapper); - } - const dataWrapper = getDataWrapper(data); - const features = await this.parser.parseFeatures(dataWrapper); // <= PARSING DONE HERE - return features - } - } - - async loadFeaturesWithIndex(chr, start, end) { - - // insure that header has been loaded -- tabix _blockLoader is initialized as side effect - if(!this.dataURI && !this.header) { - await this.readHeader(); - } - - //console.log("Using index" - const config = this.config; - const parser = this.parser; - const tabix = this.index.tabix; - const refId = tabix ? this.index.sequenceIndexMap[chr] : chr; - if (refId === undefined) { - return [] - } - - const genome = this.genome; - const chunks = this.index.chunksForRange(refId, start, end); - if (!chunks || chunks.length === 0) { - return [] - } else { - const allFeatures = []; - for (let chunk of chunks) { - - let inflated; - if (tabix) { - inflated = await this._blockLoader.getData(chunk.minv, chunk.maxv); - } else { - const options = buildOptions$1(config, { - range: { - start: chunk.minv.block, - size: chunk.maxv.block - chunk.minv.block + 1 - } - }); - inflated = await igvxhr.loadString(config.url, options); - } - - const slicedData = chunk.minv.offset ? inflated.slice(chunk.minv.offset) : inflated; - const dataWrapper = getDataWrapper(slicedData); - let slicedFeatures = await parser.parseFeatures(dataWrapper); - - // Filter psuedo-features (e.g. created mates for VCF SV records) - slicedFeatures = slicedFeatures.filter(f => f._f === undefined); - - // Filter features not in requested range. - let inInterval = false; - for (let i = 0; i < slicedFeatures.length; i++) { - const f = slicedFeatures[i]; - - const canonicalChromosome = genome ? genome.getChromosomeName(f.chr) : f.chr; - if (canonicalChromosome !== chr) { - if (allFeatures.length === 0) { - continue //adjacent chr to the left - } else { - break //adjacent chr to the right - } - } - if (f.start > end) { - allFeatures.push(f); // First feature beyond interval - break - } - if (f.end >= start && f.start <= end) { - if (!inInterval) { - inInterval = true; - if (i > 0) { - allFeatures.push(slicedFeatures[i - 1]); - } - } - allFeatures.push(f); - } - } - - } - allFeatures.sort(function (a, b) { - return a.start - b.start - }); - - return allFeatures - } - } - - async getIndex() { - if (this.index) { - return this.index - } else if (this.config.indexURL) { - this.index = await this.loadIndex(); - return this.index - } - } - - /** - * Return a Promise for the async loaded index - */ - async loadIndex() { - const indexURL = this.config.indexURL; - return loadIndex(indexURL, this.config, this.genome) - } - - async loadFeaturesFromDataURI() { - - if (this.features) { - // An optimization hack for non-indexed files, features are temporarily cached when header is read. - const tmp = this.features; - delete this.features; - return tmp - } else { - const plain = decodeDataURI$1(this.dataURI); - let dataWrapper = getDataWrapper(plain); - this.header = await this.parser.parseHeader(dataWrapper); - if (this.header instanceof String && this.header.startsWith("##gff-version 3")) { - this.format = 'gff3'; - } - - dataWrapper = getDataWrapper(plain); - this.features = await this.parser.parseFeatures(dataWrapper); - return this.features - } - } - -} - -/* - * The MIT License (MIT) - * - * Copyright (c) 2016 University of California San Diego - * Author: Jim Robinson - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -const isString$1 = isString$2; - - -class CustomServiceReader { - constructor(config) { - this.config = config; - } - - async readFeatures(chr, start, end) { - - let url; - if (typeof this.config.url === 'function') { - url = this.config.url({chr, start, end}); - } else { - url = this.config.url - .replace("$CHR", chr) - .replace("$START", start) - .replace("$END", end); - } - - let config = Object.assign({}, this.config); - if (this.config.body !== undefined) { - if (typeof this.config.body === 'function') { - config.body = this.config.body({chr, start, end}); - } else { - config.body = - this.config.body - .replace("$CHR", chr) - .replace("$START", start) - .replace("$END", end); - } - } - - - let features; - const data = await igvxhr.load(url, config); - if (data) { - if (typeof this.config.parser === "function") { - features = this.config.parser(data); - } else if (isString$1(data)) { - features = JSON.parse(data); - } else { - features = data; - } - } - if (this.config.mappings) { - let mappingKeys = Object.keys(this.config.mappings); - for (let f of features) { - for (let key of mappingKeys) { - f[key] = f[this.config.mappings[key]]; - } - } - } - return features - } -} - -/* - * The MIT License (MIT) - * - * Copyright (c) 2016-2017 The Regents of the University of California - * Author: Jim Robinson - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -const UCSCServiceReader = function (config, genome) { - this.config = config; - this.genome = genome; - this.expandQueryInterval = false; -}; - -UCSCServiceReader.prototype.readFeatures = function (chr, start, end) { - - const s = Math.max(0, Math.floor(start)); - let e = Math.ceil(end); - - if (this.genome) { - const c = this.genome.getChromosome(chr); - if (c && e > c.bpLength) { - e = c.bpLength; - } - } - - - const url = this.config.url + '?db=' + this.config.db + '&table=' + this.config.tableName + '&chr=' + chr + '&start=' + s + '&end=' + e; - - return igvxhr.loadJson(url, this.config) - .then(function (data) { - if (data) { - data.forEach(function (sample) { - if (sample.hasOwnProperty('exonStarts') && - sample.hasOwnProperty('exonEnds') && - sample.hasOwnProperty('exonCount') && - sample.hasOwnProperty('cdsStart') && - sample.hasOwnProperty('cdsEnd')) { - addExons(sample); - } - }); - return data - } else { - return null - } - }) -}; - -function addExons(sample) { - var exonCount, exonStarts, exonEnds, exons, eStart, eEnd; - exonCount = sample['exonCount']; - exonStarts = sample['exonStarts'].split(','); - exonEnds = sample['exonEnds'].split(','); - exons = []; - - for (var i = 0; i < exonCount; i++) { - eStart = parseInt(exonStarts[i]); - eEnd = parseInt(exonEnds[i]); - var exon = {start: eStart, end: eEnd}; - - if (sample.cdsStart > eEnd || sample.cdsEnd < sample.cdsStart) exon.utr = true; // Entire exon is UTR - if (sample.cdsStart >= eStart && sample.cdsStart <= eEnd) exon.cdStart = sample.cdsStart; - if (sample.cdsEnd >= eStart && sample.cdsEnd <= eEnd) exon.cdEnd = sample.cdsEnd; - - exons.push(exon); - } - - sample.exons = exons; -} - -/* - * The MIT License (MIT) - * - * Copyright (c) 2021 University of California San Diego - * Author: Jim Robinson - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -const gffNameFields = ["Name", "gene_name", "gene", "gene_id", "alias", "locus", "name"]; - -class GFFHelper { - - constructor(options) { - this.format = options.format; - this.nameField = options.nameField; - this.filterTypes = options.filterTypes === undefined ? - new Set(['chromosome']) : - new Set(options.filterTypes); - } - - combineFeatures(features, genomicInterval) { - - let combinedFeatures; - - const filterTypes = this.filterTypes; - features = features.filter(f => filterTypes === undefined || !filterTypes.has(f.type)); - - if ("gff3" === this.format) { - const tmp = this.combineFeaturesById(features); - combinedFeatures = this.combineFeaturesByType(tmp); - } else { - combinedFeatures = this.combineFeaturesByType(features); - } - combinedFeatures.sort(function (a, b) { - return a.start - b.start - }); - this.numberExons(combinedFeatures, genomicInterval); - this.nameFeatures(combinedFeatures); - return combinedFeatures - } - - /** - * Combine multiple non-transcript model features with the same ID on the same chromosome into a single feature. - * Features that are part of the transcript model (e.g. exon, mRNA, etc) are combined later. - * - * @param features - * @returns {[]} - */ - combineFeaturesById(features) { - - const chrIdMap = new Map(); - const combinedFeatures = []; - - for (let f of features) { - if (isTranscriptPart(f.type) || isTranscript(f.type) || !f.id) { - combinedFeatures.push(f); - } else { - let idMap = chrIdMap.get(f.chr); - if (!idMap) { - idMap = new Map(); - chrIdMap.set(f.chr, idMap); - } - - let featureArray = idMap.get(f.id); - if (featureArray) { - featureArray.push(f); - } else { - idMap.set(f.id, [f]); - } - } - } - - for (let idMap of chrIdMap.values()) { - for (let featureArray of idMap.values()) { - if (featureArray.length > 1) { - // Use the first feature as prototypical (for column 9 attributes), and adjust start/end - // Parts are represented as "exons", as that is how they are presented visually - const cf = featureArray[0]; - cf.exons = []; - for (let f of featureArray) { - cf.start = Math.min(cf.start, f.start); - cf.end = Math.max(cf.end, f.end); - cf.exons.push({ - start: f.start, - end: f.end - }); - } - combinedFeatures.push(cf); - } else { - combinedFeatures.push(featureArray[0]); - } - } - } - - return combinedFeatures - } - - combineFeaturesByType(features) { - - // Build dictionary of genes - const genes = features.filter(f => "gene" === f.type || f.type.endsWith("_gene")); - const geneMap = Object.create(null); - for (let g of genes) { - geneMap[g.id] = g; - } - - // 1. Build dictionary of transcripts - const transcripts = Object.create(null); - const combinedFeatures = []; - const consumedFeatures = new Set(); - const filterTypes = this.filterTypes; - - features = features.filter(f => filterTypes === undefined || !filterTypes.has(f.type)); - - for (let f of features) { - - if (f.type === "biological_region") { - console.log(); - } - - if (isTranscript(f.type)) { - const transcriptId = f.id; // getAttribute(f.attributeString, "transcript_id", /\s+/); - if (undefined !== transcriptId) { - const gffTranscript = new GFFTranscript(f); - transcripts[transcriptId] = gffTranscript; - combinedFeatures.push(gffTranscript); - consumedFeatures.add(f); - const g = geneMap[f.parent]; - if (g) { - gffTranscript.geneObject = g; - consumedFeatures.add(g); - } - } - } - } - - // Add exons and transcript parts - for (let f of features) { - if (isTranscriptPart(f.type)) { - const parents = getParents(f); - if (parents) { - for (let id of parents) { - - let transcript = transcripts[id]; - if (!transcript && this.format === "gtf") { - // GTF does not require explicit transcript record, start one with this feature. - const psuedoTranscript = Object.assign({}, f); - psuedoTranscript.type = "transcript"; - transcript = new GFFTranscript(psuedoTranscript); - transcripts[id] = transcript; - combinedFeatures.push(transcript); - } - if (transcript !== undefined) { - - if (isExon(f.type)) { - if (parents.length > 1) { - // Make a copy as exon can be modified differently by CDS, etc, for each transcript - const e2 = new GFFFeature(f); - transcript.addExon(e2); - } else { - transcript.addExon(f); - } - } else { - transcript.addPart(f); - } - consumedFeatures.add(f); - } - } - } - } - } - - // Finish transcripts - combinedFeatures.forEach(function (f) { - if (typeof f.finish === "function") { - f.finish(); - } - }); - - // Add other features - const others = features.filter(f => !consumedFeatures.has(f)); - for (let f of others) { - combinedFeatures.push(f); - } - - return combinedFeatures - - function getParents(f) { - if (f.parent && f.parent.trim() !== "") { - return f.parent.trim().split(",") - } else { - return null - } - } - } - - numberExons(features, genomicInterval) { - - for (let f of features) { - if (f.exons && - (!genomicInterval || - (f.end <= genomicInterval.end && f.start > genomicInterval.start))) { - for (let i = 0; i < f.exons.length; i++) { - const exon = f.exons[i]; - exon.number = f.strand === "-" ? f.exons.length - i : i + 1; - } - } - } - } - - nameFeatures(features) { - // Find name (label) property - for (let f of features) { - if (f.attributeString) { - const delim = ('gff3' === this.format) ? '=' : ' '; - const attributes = parseAttributeString(f.attributeString, delim); - const attributesMap = new Map(attributes); - if (this.nameField) { - f.name = attributesMap.get(this.nameField); - } else { - for (let nameField of gffNameFields) { - if (attributesMap.has(nameField)) { - f.name = attributesMap.get(nameField); - break - } - } - } - } - } - } -} - -/* - * The MIT License (MIT) - * - * Copyright (c) 2015 UC San Diego - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -const GtexReader = function (config) { - - this.config = config; - this.url = config.url; - this.tissueId = config.tissueSiteDetailId; - this.indexed = true; - this.datasetId = config.datasetId || "gtex_v8"; -}; - -GtexReader.prototype.readFeatures = async function (chr, bpStart, bpEnd) { - - - let self = this, - queryChr = chr.startsWith("chr") ? chr : "chr" + chr, - queryStart = Math.floor(bpStart), - queryEnd = Math.ceil(bpEnd), - datasetId = this.datasetId, - queryURL = this.url + "?chromosome=" + queryChr + "&start=" + queryStart + "&end=" + queryEnd + - "&tissueSiteDetailId=" + this.tissueId + "&datasetId=" + datasetId; - - const json = await igvxhr.loadJson(queryURL, { - withCredentials: self.config.withCredentials - }); - if (json && json.singleTissueEqtl) { - //variants = json.variants; - //variants.sort(function (a, b) { - // return a.POS - b.POS; - //}); - //source.cache = new FeatureCache(chr, queryStart, queryEnd, variants); - - json.singleTissueEqtl.forEach(function (eqtl) { - eqtl.chr = eqtl.chromosome; - eqtl.position = eqtl.pos; - eqtl.start = eqtl.pos - 1; - eqtl.end = eqtl.start + 1; - eqtl.snp = eqtl.snpId; - eqtl.geneName = eqtl.geneSymbol; - eqtl.geneId = eqtl.gencodeId; - - }); - - return json.singleTissueEqtl - } else { - return undefined - } -}; - -/* - * The MIT License (MIT) - * - * Copyright (c) 2014 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -// Experimental class for fetching features from an mpg webservice. -// http://immvar.broadinstitute.org:3000/load_data?chromosome=&start=&end=&categories= - -const ImmVarReader = function (config) { - - this.config = config; - this.url = config.url; - this.cellConditionId = config.cellConditionId; - this.valueThreshold = config.valueThreshold ? config.valueThreshold : 5E-2; - -}; - -ImmVarReader.prototype.readFeatures = function (queryChr, queryStart, queryEnd) { - - var self = this, - queryURL = this.url + "?chromosome=" + queryChr + "&start=" + queryStart + "&end=" + queryEnd + - "&cell_condition_id=" + this.cellConditionId; - - return new Promise(function (fulfill, reject) { - igvxhr.loadJson(queryURL, { - withCredentials: self.config.withCredentials - }).then(function (json) { - - if (json) { - //variants = json.variants; - //variants.sort(function (a, b) { - // return a.POS - b.POS; - //}); - //source.cache = new FeatureCache(chr, queryStart, queryEnd, variants); - - json.eqtls.forEach(function (eqtl) { - eqtl.chr = eqtl.chromosome; - eqtl.start = eqtl.position; - eqtl.end = eqtl.position + 1; - }); - - fulfill(json.eqtls); - } else { - fulfill(null); - } - - }).catch(function (error) { - reject(error); - }); - - }) -}; - -/* - * The MIT License (MIT) - * - * Copyright (c) 2014 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -const apiKey = igvxhr.apiKey; - -function ga4ghGet(options) { - var url = options.url + "/" + options.entity + "/" + options.entityId; - options.headers = ga4ghHeaders(); - return igvxhr.loadJson(url, options) // Returns a promise -} - -function ga4ghSearch(options) { - - return new Promise(function (fulfill, reject) { - var results = options.results ? options.results : [], - url = options.url, - body = options.body, - decode = options.decode, - paramSeparator = "?", - fields = options.fields; // Partial response - - - if (apiKey) { - url = url + paramSeparator + "key=" + apiKey; - paramSeparator = "&"; - } - - if (fields) { - url = url + paramSeparator + "fields=" + fields; - } - - - // Start the recursive load cycle. Data is fetched in chunks, if more data is available a "nextPageToken" is returned. - return loadChunk() - - function loadChunk(pageToken) { - - if (pageToken) { - body.pageToken = pageToken; - } else { - if (body.pageToken !== undefined) delete body.pageToken; // Remove previous page token, if any - } - - var sendData = JSON.stringify(body); - - igvxhr.loadJson(url, { - sendData: sendData, - contentType: "application/json", - headers: ga4ghHeaders(), - // oauthToken: ga4ghToken() - }) - .then(function (json) { - var nextPageToken, tmp; - - if (json) { - - tmp = decode ? decode(json) : json; - - if (tmp) { - - tmp.forEach(function (a) { - { - results.push(a); - } - }); - } - - - nextPageToken = json["nextPageToken"]; - - if (nextPageToken) { - loadChunk(nextPageToken); - } else { - fulfill(results); - } - } else { - fulfill(results); - } - - }) - .catch(function (error) { - reject(error); - }); - } - - }) - - -} - -function ga4ghHeaders() { - return { - "Cache-Control": "no-cache" - } -} - -/* - * The MIT License (MIT) - * - * Copyright (c) 2014 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -const Ga4ghVariantReader = function (config, genome) { - - this.config = config; - this.genome = genome; - this.url = config.url; - this.variantSetId = config.variantSetId; - this.callSetIds = config.callSetIds; - this.includeCalls = (config.includeCalls === undefined ? true : config.includeCalls); - -}; - -// Simulate a VCF file header -Ga4ghVariantReader.prototype.readHeader = function () { - - var self = this; - - - if (self.header) { - return Promise.resolve(self.header) - } else { - - self.header = {}; - - if (self.includeCalls === false) { - return Promise.resolve(self.header) - } else { - - var readURL = self.url + "/callsets/search"; - - return ga4ghSearch({ - url: readURL, - fields: "nextPageToken,callSets(id,name)", - body: { - "variantSetIds": (Array.isArray(self.variantSetId) ? self.variantSetId : [self.variantSetId]), - "pageSize": "10000" - }, - decode: function (json) { - // If specific callSetIds are specified filter to those - if (self.callSetIds) { - var callSets = [], - csIdSet = new Set(); - - self.callSetIds.forEach(function (csid) { - csIdSet.add(csid); - }); - - json.callSets.forEach(function (cs) { - if (csIdSet.has(cs.id)) { - callSets.push(cs); - } - }); - return callSets - } else { - return json.callSets - } - } - }) - .then(function (callSets) { - self.header.callSets = callSets; - return self.header - }) - } - } -}; - - -Ga4ghVariantReader.prototype.readFeatures = function (chr, bpStart, bpEnd) { - - const self = this; - const genome = this.genome; - - return self.readHeader() - - .then(function (header) { - return getChrAliasTable() - }) - - .then(function (chrAliasTable) { - - var queryChr = chrAliasTable.hasOwnProperty(chr) ? chrAliasTable[chr] : chr, - readURL = self.url + "/variants/search"; - - return ga4ghSearch({ - url: readURL, - fields: (self.includeCalls ? undefined : "nextPageToken,variants(id,variantSetId,names,referenceName,start,end,referenceBases,alternateBases,quality,filter,info)"), - body: { - "variantSetIds": (Array.isArray(self.variantSetId) ? self.variantSetId : [self.variantSetId]), - "callSetIds": (self.callSetIds ? self.callSetIds : undefined), - "referenceName": queryChr, - "start": bpStart.toString(), - "end": bpEnd.toString(), - "pageSize": "10000" - }, - decode: function (json) { - - var v; - - var variants = []; - - json.variants.forEach(function (json) { - - v = createGAVariant(json); - - if (!v.isRefBlock()) { - variants.push(v); - } - }); - - return variants - } - }) - }) - - - function getChrAliasTable() { - - return new Promise(function (fulfill, reject) { - - if (self.chrAliasTable) { - fulfill(self.chrAliasTable); - } else { - self.readMetadata().then(function (json) { - - self.metadata = json.metadata; - self.chrAliasTable = {}; - - if (json.referenceBounds && genome) { - - json.referenceBounds.forEach(function (rb) { - var refName = rb.referenceName, - alias = genome.getChromosomeName(refName); - self.chrAliasTable[alias] = refName; - - }); - } - fulfill(self.chrAliasTable); - - }); - } - - }) - } - -}; - - -Ga4ghVariantReader.prototype.readMetadata = function () { - - return ga4ghGet({ - url: this.url, - entity: "variantsets", - entityId: this.variantSetId - }) -}; - -class CivicReader { - - constructor(config) { - this.config = config; - } - - async readFeatures(chr, start, end) { - - const json = await igvxhr.loadJson(this.config.url + "/variants/?count=50000"); - const records = json.records; - const features = []; - - for (let record of records) { - - if (record.coordinates) { - - record.id; - const coordinates = record.coordinates; - - if (coordinates.chromosome) { - features.push( - new CivicVariant( - coordinates.chromosome, - coordinates.start - 1, // UCSC 0 convention - coordinates.stop, - record - )); - } - - if (coordinates.chromosome2) { - features.push( - new CivicVariant( - coordinates.chromosome2, - coordinates.start2 - 1, // UCSC 0 convention - coordinates.stop2, - record - )); - } - } - - } - return features - - } -} - -class CivicVariant { - - constructor(chr, start, end, record) { - this.chr = chr; - this.start = start; - this.end = end; - this.id = record.id; - this.entrezName = record.entrez_name; - this.name = record.name; - this.actionabilityScore = record.civic_actionability_score; - - if (record.coordinates.reference_bases) { - this.refBases = record.coordinates.reference_bases; - } - if (record.coordinates.variant_bases) { - this.altBases = record.coordinates.variant_bases; - } - if (record.variant_types) { - this.variant_types = record.variant_types; - } - - this.locationString = (this.chr + ":" + - numberFormatter$1(this.start + 1) + "-" + - numberFormatter$1(this.end)); - - // Color based on actionability score - if (this.actionabilityScore !== undefined) { - let alpha; - if (this.actionabilityScore <= 10) { - alpha = 0.2; - } else { - const v = Math.min(30, this.actionabilityScore); - alpha = 0.2 + 0.8 * Math.log10((v - 10) / 2); - } - this.alpha = alpha; - } - - - } - - popupData() { - - - const link = createLink("CIViC", "https://civicdb.org/links/variants/" + this.id); - this.refBases !== this.altBases && - this.refBases && this.refBases.length === 1 && - this.altBases && this.altBases.length === 1; - - - const pd = [link]; - pd.push({ - name: "Entrez", - value: createLink(this.entrezName, "https://ghr.nlm.nih.gov/gene/" + this.entrezName) - }); - pd.push({name: "Name", value: this.name}); - - if (this.variant_types && this.variant_types.length > 0) { - - const name = this.variant_types.length === 1 ? "Type" : "Types"; - let typeString; - for (let vt of this.variant_types) { - if (!typeString) typeString = vt.display_name; - else typeString += ", " + vt.display_name; - } - - pd.push({name: name, value: typeString}); - } - - pd.push({name: "Actionability", value: this.actionabilityScore}); - - - pd.push({name: "Location", value: this.locationString}); - - return pd - - - function createLink(text, href) { - return "" + text + "" - } - - } -} - -/* - * The MIT License (MIT) - * - * Copyright (c) 2016-2017 The Regents of the University of California - * Author: Jim Robinson - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -class HtsgetReader { - - constructor(config, genome) { - this.config = config; - this.genome = genome; - this.format = config.format ? config.format.toUpperCase() : "BAM"; // Backward compatibility - if (!(this.format === "BAM" || this.format === "VCF")) { - throw Error(`htsget format ${config.format} is not supported`) - } - } - - async readHeaderData() { - const url = `${getUrl(this.config)}?class=header&format=${this.format}`; - const ticket = await igvxhr.loadJson(url, buildOptions$1(this.config)); - return await this.loadUrls(ticket.htsget.urls) - } - - async readData(chr, start, end) { - const url = `${getUrl(this.config)}?format=${this.format}&referenceName=${chr}&start=${Math.floor(start)}&end=${Math.ceil(end)}`; - const ticket = await igvxhr.loadJson(url, buildOptions$1(this.config)); - return this.loadUrls(ticket.htsget.urls) - } - - async loadUrls(urls) { - - const promiseArray = []; - for (let urlData of urls) { - - if (urlData.url.startsWith('data:')) { - // this is a data-uri - promiseArray.push(Promise.resolve(dataUriToBytes(urlData.url))); - - } else { - - const options = buildOptions$1(this.config || {}); - - if (urlData.headers) { - options.headers = Object.assign(options.headers || {}, urlData.headers); - } - - promiseArray.push(igvxhr.loadArrayBuffer(urlData.url, options)); - } - } - const arrayBuffers = await Promise.all(promiseArray); - return concatArrays(arrayBuffers) - } - - - static async inferFormat(config) { - try { - const url = getUrl(config); - const headerURL = `${url}${url.includes("?") ? "&" : "?"}class=header`; - const ticket = await igvxhr.loadJson(headerURL, buildOptions$1(config)); - if (ticket.htsget) { - const format = ticket.htsget.format; - if (!(format === "BAM" || format === "VCF")) { - throw Error(`htsget format ${format} is not supported`) - } - config.format = format.toLowerCase(); - config.sourceType = "htsget"; - if (!config.name) { - config.name = await getFilename$1(config.url); - } - } - } catch (e) { - // Errors => this is not an htsget source, not an application error. Ignore - } - } -} - -/** - * Extract the full url from the config. Striving for backward compatibility, "endpoint" and "id" are deprecated. - * - * @param config - */ -function getUrl(config) { - if (config.url && config.endpoint && config.id) { - return config.url + config.endpoint + config.id // Deprecated - } else if (config.endpoint && config.id) { - return config.endpoint + config.id // Deprecated - } else if (config.url) { - if (config.url.startsWith("htsget://")) { - return config.url.replace("htsget://", "https://") // htsget -> http not supported - } else { - return config.url - } - } else { - throw Error("Must specify either 'url', or 'endpoint' and 'id") - } - - -} - -/** - * Concatenate a list of array buffers, returning an UInt8Array - * @param arrayBuffers - */ -function concatArrays(arrayBuffers) { - - let len = 0; - for (let a of arrayBuffers) { - len += a.byteLength; - } - - let offset = 0; - const newArray = new Uint8Array(len); - for (let buf of arrayBuffers) { - const a = new Uint8Array(buf); - newArray.set(a, offset); - offset += a.length; - } - - return newArray -} - -function dataUriToBytes(dataUri) { - - const split = dataUri.split(','); - const info = split[0].split(':')[1]; - let dataString = split[1]; - - if (info.indexOf('base64') >= 0) { - dataString = atob(dataString); - } else { - dataString = decodeURI(dataString); - } - - const bytes = new Uint8Array(dataString.length); - for (var i = 0; i < dataString.length; i++) { - bytes[i] = dataString.charCodeAt(i); - } - - return bytes -} - -/* - * The MIT License (MIT) - * - * Copyright (c) 2016-2017 The Regents of the University of California - * Author: Jim Robinson - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -class HtsgetVariantReader extends HtsgetReader { - - constructor(config, genome) { - super(config, genome); - this.parser = new VcfParser(); - } - - async readHeader() { - if (!this.header) { - const data = await this.readHeaderData(); - const dataWrapper = getDataWrapper(data); - this.header = await this.parser.parseHeader(dataWrapper, this.genome); - this.chrAliasTable = this.header.chrAliasTable; - } - return this.header - } - - async readFeatures(chr, start, end) { - - if (this.config.format && this.config.format.toUpperCase() !== "VCF") { - throw Error(`htsget format ${this.config.format} is not supported`) - } - - if (!this.chrAliasTable) { - await this.readHeader(); - } - - let queryChr = this.chrAliasTable.has(chr) ? this.chrAliasTable.get(chr) : chr; - - const data = await this.readData(queryChr, start, end); - - const dataWrapper = getDataWrapper(data); - - return this.parser.parseFeatures(dataWrapper) - - // return dataWrapper; - - } - -} - -// Assigns a row # to each feature. If the feature does not fit in any row and #rows == maxRows no -// row number is assigned. -function pack(featureList, maxRows) { - - maxRows = maxRows || Number.MAX_SAFE_INTEGER; - const rows = []; - featureList.sort(function (a, b) { - return a.start - b.start - }); - rows.push(-1000); - - for (let feature of featureList) { - let r = 0; - const len = Math.min(rows.length, maxRows); - for (r = 0; r < len; r++) { - if (feature.start >= rows[r]) { - feature.row = r; - rows[r] = feature.end; - break - } - } - feature.row = r; - rows[r] = feature.end; - } -} - -const DEFAULT_MAX_WG_COUNT$1 = 10000; - -/** - * Return a collection of "whole genome" features wrapping the supplied features, possibly downsampled. The purpose - * is to support painting features in "whole genome view". - * - * @param allFeatures - dictionary (object), keys are chromosome names, values are lists of features - * @param genome - * @param maxWGCount - optional, maximum # of whole genome features to computer - * @returns {*[]} - */ -function computeWGFeatures(allFeatures, genome, maxWGCount) { - - const max = maxWGCount || DEFAULT_MAX_WG_COUNT$1; - - const makeWGFeature = (f) => { - const wg = Object.assign({}, f); - wg.chr = "all"; - wg.start = genome.getGenomeCoordinate(f.chr, f.start); - wg.end = genome.getGenomeCoordinate(f.chr, f.end); - wg._f = f; - // Don't draw exons in whole genome view - if (wg["exons"]) delete wg["exons"]; - return wg - }; - - const wgChromosomeNames = new Set(genome.wgChromosomeNames); - const wgFeatures = []; - let count = 0; - for (let c of genome.wgChromosomeNames) { - - if(Array.isArray(allFeatures)) { - const featureDict = {}; - for(let f of allFeatures) { - const chr = genome.getChromosomeName(f.chr); - if(!featureDict.hasOwnProperty(chr)) { - featureDict[chr] = []; - } - featureDict[chr].push(f); - } - allFeatures = featureDict; - } - - const features = allFeatures[c]; - - if (features) { - for (let f of features) { - let queryChr = genome.getChromosomeName(f.chr); - if (wgChromosomeNames.has(queryChr)) { - if (wgFeatures.length < max) { - wgFeatures.push(makeWGFeature(f)); - } else { - //Reservoir sampling - const samplingProb = max / (count + 1); - if (Math.random() < samplingProb) { - const idx = Math.floor(Math.random() * (max - 1)); - wgFeatures[idx] = makeWGFeature(f); - } - } - } - count++; - } - } - } - - wgFeatures.sort(function (a, b) { - return a.start - b.start - }); - - return wgFeatures -} - -function packFeatures(features, maxRows) { - - maxRows = maxRows || 1000; - if (features == null || features.length === 0) { - return - } - // Segregate by chromosome - const chrFeatureMap = {}; - const chrs = []; - for (let feature of features) { - const chr = feature.chr; - let flist = chrFeatureMap[chr]; - if (!flist) { - flist = []; - chrFeatureMap[chr] = flist; - chrs.push(chr); - } - flist.push(feature); - } - - // Loop through chrosomosomes and pack features; - for (let chr of chrs) { - pack(chrFeatureMap[chr], maxRows); - } -} - -/* - * The MIT License (MIT) - * - * Copyright (c) 2014-2015 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -const DEFAULT_MAX_WG_COUNT = 10000; - -/** - * feature source for "bed like" files (tab or whitespace delimited files with 1 feature per line: bed, gff, vcf, etc) - * - * @param config - * @constructor - */ -class TextFeatureSource { - - constructor(config, genome) { - - this.config = config || {}; - this.genome = genome; - this.sourceType = (config.sourceType === undefined ? "file" : config.sourceType); - this.maxWGCount = config.maxWGCount || DEFAULT_MAX_WG_COUNT; - - const queryableFormats = new Set(["bigwig", "bw", "bigbed", "bb", "biginteract", "biggenepred", "bignarrowpeak", "tdf"]); - - this.queryable = config.indexURL || config.queryable === true; // False by default, unless explicitly set - if (config.reader) { - // Explicit reader implementation - this.reader = config.reader; - this.queryable = config.queryable !== false; - } else if (config.sourceType === "ga4gh") { - this.reader = new Ga4ghVariantReader(config, genome); - this.queryable = true; - } else if (config.sourceType === "immvar") { - this.reader = new ImmVarReader(config); - this.queryable = true; - } else if (config.type === "eqtl" && config.sourceType === "gtex-ws") { - this.reader = new GtexReader(config); - this.queryable = true; - } else if ("htsget" === config.sourceType) { - this.reader = new HtsgetVariantReader(config, genome); - this.queryable = true; - } else if (config.sourceType === 'ucscservice') { - this.reader = new UCSCServiceReader(config.source); - this.queryable = true; - } else if (config.sourceType === 'custom') { - this.reader = new CustomServiceReader(config.source); - this.queryable = false !== config.source.queryable; - } else if ("civic-ws" === config.sourceType) { - this.reader = new CivicReader(config); - this.queryable = false; - } else { - // File of some type (i.e. not a webservice) - this.reader = new FeatureFileReader(config, genome); - if (config.queryable !== undefined) { - this.queryable = config.queryable; - } else if (queryableFormats.has(config.format) || this.reader.indexed) { - this.queryable = true; - } else ; - } - - // Set searchable unless explicitly turned off, or track uses in indexed or otherwise queryable - // feature source. queryable => features loaded on demand (by query) - this.searchable = config.searchable === true || config.searchableFields || (config.searchable !== false && !this.queryable); - - } - - async defaultVisibilityWindow() { - if (this.reader && typeof this.reader.defaultVisibilityWindow === 'function') { - return this.reader.defaultVisibilityWindow() - } - } - - async trackType() { - const header = await this.getHeader(); - if (header) { - return header.type - } else { - return undefined // Convention for unknown or unspecified - } - } - - async getHeader() { - if (!this.header) { - - if (this.reader && typeof this.reader.readHeader === "function") { - const header = await this.reader.readHeader(); - if (header) { - this.header = header; - if (header.format) { - this.config.format = header.format; - } - } else { - this.header = {}; - } - } else { - this.header = {}; - } - } - return this.header - } - - /** - * Required function for all data source objects. Fetches features for the - * range requested. - * - * This function is quite complex due to the variety of reader types backing it, some indexed, some queryable, - * some not. - * - * @param chr - * @param start - * @param end - * @param bpPerPixel - */ - async getFeatures({chr, start, end, bpPerPixel, visibilityWindow}) { - - const genome = this.genome; - const queryChr = genome ? genome.getChromosomeName(chr) : chr; - const isWholeGenome = ("all" === queryChr.toLowerCase()); - - // Various conditions that can require a feature load - // * view is "whole genome" but no features are loaded - // * cache is disabled - // * cache does not contain requested range - // const containsRange = this.featureCache.containsRange(new GenomicInterval(queryChr, start, end)) - if ((isWholeGenome && !this.wgFeatures && this.supportsWholeGenome()) || - this.config.disableCache || - !this.featureCache || - !this.featureCache.containsRange(new GenomicInterval(queryChr, start, end))) { - await this.loadFeatures(queryChr, start, end, visibilityWindow); - } - - if (isWholeGenome) { - if (!this.wgFeatures) { - if (this.supportsWholeGenome()) { - this.wgFeatures = computeWGFeatures(this.featureCache.getAllFeatures(), this.genome, this.maxWGCount); - } else { - this.wgFeatures = []; - } - } - return this.wgFeatures - } else { - return this.featureCache.queryFeatures(queryChr, start, end) - } - } - - supportsWholeGenome() { - return !this.queryable // queryable (indexed, web services) sources don't support whole genome view - } - - // TODO -- experimental, will only work for non-indexed sources - getAllFeatures() { - if (this.queryable || !this.featureCache) { // queryable sources don't support all features - return [] - } else { - return this.featureCache.getAllFeatures() - } - } - - - async loadFeatures(queryChr, start, end, visibilityWindow) { - - const reader = this.reader; - let intervalStart = start; - let intervalEnd = end; - - // Use visibility window to potentially expand query interval. - // This can save re-queries as we zoom out. Visibility window <= 0 is a special case - // indicating whole chromosome should be read at once. - if ((!visibilityWindow || visibilityWindow <= 0) && this.config.expandQuery !== false) { - // Whole chromosome - const chromosome = this.genome ? this.genome.getChromosome(queryChr) : undefined; - intervalStart = 0; - intervalEnd = Math.max(chromosome ? chromosome.bpLength : Number.MAX_SAFE_INTEGER, end); - } else if (visibilityWindow > (end - start) && this.config.expandQuery !== false) { - const expansionWindow = Math.min(4.1 * (end - start), visibilityWindow); - intervalStart = Math.max(0, (start + end) / 2 - expansionWindow); - intervalEnd = start + expansionWindow; - } - - let features = await reader.readFeatures(queryChr, intervalStart, intervalEnd); - if (this.queryable === undefined) { - this.queryable = reader.indexed; - } - - const genomicInterval = this.queryable ? - new GenomicInterval(queryChr, intervalStart, intervalEnd) : - undefined; - - if (features) { - - if (this.config.assembleGFF !== false && - ("gtf" === this.config.format || "gff3" === this.config.format || "gff" === this.config.format)) { - features = (new GFFHelper(this.config)).combineFeatures(features, genomicInterval); - } - - // Assign overlapping features to rows - if (this.config.format !== "wig" && this.config.type !== "junctions") { - const maxRows = this.config.maxRows || Number.MAX_SAFE_INTEGER; - packFeatures(features, maxRows); - } - - // Note - replacing previous cache with new one. genomicInterval is optional (might be undefined => includes all features) - this.featureCache = new FeatureCache$1(features, this.genome, genomicInterval); - - // If track is marked "searchable"< cache features by name -- use this with caution, memory intensive - if (this.searchable) { - this.genome.addFeaturesToDB(features, this.config); - } - } else { - this.featureCache = new FeatureCache$1([], genomicInterval); // Empty cache - } - } -} - -/* - * The MIT License (MIT) - * - * Copyright (c) 2014 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -class BufferedReader { - - constructor(config, contentLength, bufferSize) { - this.path = config.url; - this.bufferSize = bufferSize ? bufferSize : 512000; - this.range = {start: -1, size: -1}; - this.config = config; - } - - /** - * - * @param requestedRange - byte rangeas {start, size} - * @param fulfill - function to receive result - * @param asUint8 - optional flag to return result as an UInt8Array - */ - async dataViewForRange(requestedRange, asUint8, retries = 0) { - try { - - const hasData = (this.data && (this.range.start <= requestedRange.start) && - ((this.range.start + this.range.size) >= (requestedRange.start + requestedRange.size))); - - if (!hasData) { - let bufferSize; - // If requested range size is specified, potentially expand buffer size - if (requestedRange.size) { - bufferSize = Math.max(this.bufferSize, requestedRange.size); - } else { - bufferSize = this.bufferSize; - } - if (this.contentLength) { - bufferSize = Math.min(bufferSize, this.contentLength - requestedRange.start); - } - const loadRange = {start: requestedRange.start, size: bufferSize}; - const arrayBuffer = await igvxhr.loadArrayBuffer(this.path, buildOptions$1(this.config, {range: loadRange})); - this.data = arrayBuffer; - this.range = loadRange; - } - - const len = this.data.byteLength; - const bufferStart = requestedRange.start - this.range.start; - return asUint8 ? - new Uint8Array(this.data, bufferStart, len - bufferStart) : - new DataView(this.data, bufferStart, len - bufferStart) - } catch (e) { - if (retries === 0 && e.message && e.message.startsWith("416")) { - try { - this.contentLength = await igvxhr.getContentLength(this.path, buildOptions$1(this.config)); - return this.dataViewForRange(requestedRange, asUint8, ++retries) - } catch (e1) { - console.error(e1); - } - throw e - } - } - } -} - -function getDecoder(definedFieldCount, fieldCount, autoSql, format) { - - if ("biginteract" === format || (autoSql && ('chromatinInteract' === autoSql.table) || 'interact' === autoSql.table)) { - return decodeInteract - } else { - const standardFieldCount = definedFieldCount - 3; - return function (feature, tokens) { - - if (standardFieldCount > 0) { - feature.name = tokens[0]; - } - if (standardFieldCount > 1) { - feature.score = Number(tokens[1]); - } - if (standardFieldCount > 2) { - feature.strand = tokens[2]; - } - if (standardFieldCount > 3) { - feature.cdStart = parseInt(tokens[3]); - } - if (standardFieldCount > 4) { - feature.cdEnd = parseInt(tokens[4]); - } - if (standardFieldCount > 5) { - if (tokens[5] !== "." && tokens[5] !== "0" && tokens[5] !== "-1") { - const c = IGVColor.createColorString(tokens[5]); - feature.color = c.startsWith("rgb") ? c : undefined; - } - } - if (standardFieldCount > 8) { - const exonCount = parseInt(tokens[6]); - const exonSizes = tokens[7].split(','); - const exonStarts = tokens[8].split(','); - const exons = []; - for (let i = 0; i < exonCount; i++) { - const eStart = feature.start + parseInt(exonStarts[i]); - const eEnd = eStart + parseInt(exonSizes[i]); - exons.push({start: eStart, end: eEnd}); - } - findUTRs(exons, feature.cdStart, feature.cdEnd); - feature.exons = exons; - } - - if (autoSql) { - // TODO -- these should be equal, validate? fieldCount-definedFieldCount, as.fields.length, tokens.length-3 - const extraStart = definedFieldCount; - for (let i = extraStart; i < fieldCount; i++) { - if (i < autoSql.fields.length) { - const name = autoSql.fields[i].name; - const value = tokens[i - 3]; - feature[name] = value; - } - } - } - } - } - - //table chromatinInteract -// "Chromatin interaction between two regions" -// ( -// string chrom; "Chromosome (or contig, scaffold, etc.). For interchromosomal, use 2 records" -// uint chromStart; "Start position of lower region. For interchromosomal, set to chromStart of this region" -// uint chromEnd; "End position of upper region. For interchromosomal, set to chromEnd of this region" -// string name; "Name of item, for display" -// uint score; "Score from 0-1000" -// double value; "Strength of interaction or other data value. Typically basis for score" -// string exp; "Experiment name (metadata for filtering). Use . if not applicable" -// string color; "Item color. Specified as r,g,b or hexadecimal #RRGGBB or html color name, as in //www.w3.org/TR/css3-color/#html4." -// string region1Chrom; "Chromosome of lower region. For non-directional interchromosomal, chrom of this region." -// uint region1Start; "Start position of lower/this region" -// uint region1End; "End position in chromosome of lower/this region" -// string region1Name; "Identifier of lower/this region" -// string region1Strand; "Orientation of lower/this region: + or -. Use . if not applicable" -// string region2Chrom; "Chromosome of upper region. For non-directional interchromosomal, chrom of other region" -// uint region2Start; "Start position in chromosome of upper/this region" -// uint region2End; "End position in chromosome of upper/this region" -// string region2Name; "Identifier of upper/this region" -// string region2Strand; "Orientation of upper/this region: + or -. Use . if not applicable" -// ) - function decodeInteract(feature, tokens) { - - feature.chr1 = tokens[5]; - feature.start1 = Number.parseInt(tokens[6]); - feature.end1 = Number.parseInt(tokens[7]); - - feature.chr2 = tokens[10]; - feature.start2 = Number.parseInt(tokens[11]); - feature.end2 = Number.parseInt(tokens[12]); - - feature.name = tokens[0]; - feature.score = Number(tokens[1]); - feature.value = Number(tokens[2]); - feature.color = tokens[4] === '.' ? undefined : tokens[4] === "0" ? "rgb(0,0,0)" : tokens[4]; - - return feature - } -} - -function findUTRs(exons, cdStart, cdEnd) { - - for (let exon of exons) { - const end = exon.end; - const start = exon.start; - if (end < cdStart || start > cdEnd) { - exon.utr = true; - } else { - if (cdStart >= start && cdStart <= end) { - exon.cdStart = cdStart; - } - if (cdEnd >= start && cdEnd <= end) { - exon.cdEnd = cdEnd; - } - } - } -} - -function scoreShade(score, color) { - const alpha = Math.min(1, 0.11 + 0.89 * (score / 779)); - return alpha.toString() -} - -function parseAutoSQL(str) { - - let table; - const fields = []; - let startDecoding = false; - const lines = str.trim().split(/\s*[\r\n]+\s*/g); - for (let line of lines) { - if (line.startsWith('table')) { - table = line.split(/\s+/)[1].trim(); - } else if (line.startsWith('(')) { - startDecoding = true; - } else if (line.startsWith(')')) ; else if (startDecoding) { - if (line.length > 0) { - const idx = line.indexOf(';'); - const tokens = line.substr(0, idx).split(/\s+/); - const description = line.substr(idx + 1).replace(/"/g, '').trim(); - fields.push({ - type: tokens[0], - name: tokens[1], - description: description - }); - } - } - } - return { - table: table, - fields: fields - } -} - -/* - * The MIT License (MIT) - * - * Copyright (c) 2014 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -let BIGWIG_MAGIC_LTH = 0x888FFC26; // BigWig Magic Low to High -let BIGWIG_MAGIC_HTL = 0x26FC8F66; // BigWig Magic High to Low -let BIGBED_MAGIC_LTH = 0x8789F2EB; // BigBed Magic Low to High -let BIGBED_MAGIC_HTL = 0xEBF28987; // BigBed Magic High to Low -let BBFILE_HEADER_SIZE = 64; -let RPTREE_HEADER_SIZE = 48; -let RPTREE_NODE_LEAF_ITEM_SIZE = 32; // leaf item size -let RPTREE_NODE_CHILD_ITEM_SIZE = 24; // child item size -let BUFFER_SIZE = 512000; // buffer - -class BWReader { - - constructor(config, genome) { - this.path = config.url; - this.format = config.format || "bigwig"; - this.genome = genome; - this.rpTreeCache = {}; - this.config = config; - this.loader = isDataURL(this.path) ? new DataBuffer(this.path) : igvxhr; - } - - async readWGFeatures(bpPerPixel, windowFunction) { - await this.loadHeader(); - const chrIdx1 = 0; - const chrIdx2 = this.chromTree.idToChrom.length - 1; - const chr1 = this.chromTree.idToChrom[chrIdx1]; - const chr2 = this.chromTree.idToChrom[chrIdx2]; - return this.readFeatures(chr1, 0, chr2, Number.MAX_VALUE, bpPerPixel, windowFunction) - } - - async readFeatures(chr1, bpStart, chr2, bpEnd, bpPerPixel, windowFunction) { - - await this.loadHeader(); - const chrIdx1 = this.chromTree.chromToID[chr1]; - const chrIdx2 = this.chromTree.chromToID[chr2]; - if (chrIdx1 === undefined || chrIdx2 === undefined) { - return [] - } - - let treeOffset; - let decodeFunction; - if (this.type === "bigwig") { - // Select a biwig "zoom level" appropriate for the current resolution. - const zoomLevelHeaders = await this.getZoomHeaders(); - let zoomLevelHeader = bpPerPixel ? zoomLevelForScale$1(bpPerPixel, zoomLevelHeaders) : undefined; - if (zoomLevelHeader) { - treeOffset = zoomLevelHeader.indexOffset; - decodeFunction = decodeZoomData; - } else { - treeOffset = this.header.fullIndexOffset; - decodeFunction = decodeWigData; - } - } else { - // bigbed, zoom data is not currently used in igv for bed type features - treeOffset = this.header.fullIndexOffset; - decodeFunction = getBedDataDecoder.call(this); - } - - - // Load the R Tree and fine leaf items - const rpTree = await this.loadRPTree(treeOffset); - const leafItems = await rpTree.findLeafItemsOverlapping(chrIdx1, bpStart, chrIdx2, bpEnd); - if (!leafItems || leafItems.length === 0) { - return [] - } else { - - // Consolidate leaf items and get all data at once - let start = Number.MAX_VALUE; - let end = 0; - for (let item of leafItems) { - start = Math.min(start, item.dataOffset); - end = Math.max(end, item.dataOffset + item.dataSize); - } - const size = end - start; - const arrayBuffer = await this.loader.loadArrayBuffer(this.config.url, buildOptions$1(this.config, { - range: { - start: start, - size: size - } - })); - - // Parse data and return features - const allFeatures = []; - for (let item of leafItems) { - const uint8Array = new Uint8Array(arrayBuffer, item.dataOffset - start, item.dataSize); - let plain; - const isCompressed = this.header.uncompressBuffSize > 0; - if (isCompressed) { - plain = inflate_1$3(uint8Array); - } else { - plain = uint8Array; - } - decodeFunction.call(this, new DataView(plain.buffer), chrIdx1, bpStart, chrIdx2, bpEnd, allFeatures, this.chromTree.idToChrom, windowFunction); - } - - allFeatures.sort(function (a, b) { - return a.start - b.start - }); - - return allFeatures - } - } - - async getZoomHeaders() { - if (this.zoomLevelHeaders) { - return this.zoomLevelHeaders - } else { - await this.loadHeader(); - return this.zoomLevelHeaders - } - } - - async loadHeader() { - - if (this.header) { - return this.header - } else { - let data = await this.loader.loadArrayBuffer(this.path, buildOptions$1(this.config, { - range: { - start: 0, - size: BBFILE_HEADER_SIZE - } - })); - - let header; - - // Assume low-to-high unless proven otherwise - this.littleEndian = true; - - let binaryParser = new BinaryParser$1(new DataView(data)); - let magic = binaryParser.getUInt(); - if (magic === BIGWIG_MAGIC_LTH) { - this.type = "bigwig"; - } else if (magic === BIGBED_MAGIC_LTH) { - this.type = "bigbed"; - } else { - //Try big endian order - this.littleEndian = false; - - binaryParser.littleEndian = false; - binaryParser.position = 0; - let magic = binaryParser.getUInt(); - - if (magic === BIGWIG_MAGIC_HTL) { - this.type = "bigwig"; - } else if (magic === BIGBED_MAGIC_HTL) { - this.type = "bigbed"; - } else ; - } - // Table 5 "Common header for bigwig and bigbed files" - header = { - bwVersion: binaryParser.getUShort(), - nZoomLevels: binaryParser.getUShort(), - chromTreeOffset: binaryParser.getLong(), - fullDataOffset: binaryParser.getLong(), - fullIndexOffset: binaryParser.getLong(), - fieldCount: binaryParser.getUShort(), - definedFieldCount: binaryParser.getUShort(), - autoSqlOffset: binaryParser.getLong(), - totalSummaryOffset: binaryParser.getLong(), - uncompressBuffSize: binaryParser.getInt(), - extensionOffset: binaryParser.getLong() - }; - - /////////// - - const startOffset = BBFILE_HEADER_SIZE; - let range = {start: startOffset, size: (header.fullDataOffset - startOffset + 5)}; - data = await this.loader.loadArrayBuffer(this.path, buildOptions$1(this.config, {range: range})); - - const nZooms = header.nZoomLevels; - binaryParser = new BinaryParser$1(new DataView(data)); - - this.zoomLevelHeaders = []; - this.firstZoomDataOffset = Number.MAX_SAFE_INTEGER; - for (let i = 1; i <= nZooms; i++) { - const zoomNumber = nZooms - i; - const zlh = new ZoomLevelHeader(zoomNumber, binaryParser); - this.firstZoomDataOffset = Math.min(zlh.dataOffset, this.firstZoomDataOffset); - this.zoomLevelHeaders[zoomNumber] = zlh; - } - - // Autosql - if (header.autoSqlOffset > 0) { - binaryParser.position = header.autoSqlOffset - startOffset; - const autoSqlString = binaryParser.getString(); - if (autoSqlString) { - this.autoSql = parseAutoSQL(autoSqlString); - } - } - - // Total summary - if (header.totalSummaryOffset > 0) { - binaryParser.position = header.totalSummaryOffset - startOffset; - this.totalSummary = new BWTotalSummary(binaryParser); - } - - // Chrom data index - if (header.chromTreeOffset > 0) { - binaryParser.position = header.chromTreeOffset - startOffset; - this.chromTree = new BPTree(binaryParser, startOffset, this.genome); - } else { - // TODO -- this is an error, not expected - throw "BigWig chromosome tree offset <= 0" - } - - //Finally total data count - binaryParser.position = header.fullDataOffset - startOffset; - header.dataCount = binaryParser.getInt(); - /////////// - - this.setDefaultVisibilityWindow(header); - - this.header = header; - return this.header - - } - } - - async loadRPTree(offset) { - - let rpTree = this.rpTreeCache[offset]; - if (rpTree) { - return rpTree - } else { - rpTree = new RPTree(offset, this.config, this.littleEndian, this.loader); - await rpTree.load(); - this.rpTreeCache[offset] = rpTree; - return rpTree - } - } - - async getType() { - await this.loadHeader(); - return this.type - } - - async getTrackType() { - await this.loadHeader(); - if (this.type === "bigwig") { - return "wig" - } else { - return this.autoSql && this.autoSql.table === "chromatinInteract" ? "interact" : "annotation" - } - } - - setDefaultVisibilityWindow(header) { - if (this.type === "bigwig") { - this.visibilityWindow = -1; - } else { - // bigbed - let genomeSize = this.genome ? this.genome.getGenomeLength() : 3088286401; - // Estimate window size to return ~ 1,000 features, assuming even distribution across the genome - this.visibilityWindow = header.dataCount < 1000 ? -1 : 1000 * (genomeSize / header.dataCount); - - } - } -} - - -class ZoomLevelHeader { - constructor(index, byteBuffer) { - this.index = index; - this.reductionLevel = byteBuffer.getInt(); - this.reserved = byteBuffer.getInt(); - this.dataOffset = byteBuffer.getLong(); - this.indexOffset = byteBuffer.getLong(); - } -} - -class RPTree { - - constructor(fileOffset, config, littleEndian, loader) { - - this.config = config; - this.loader = loader; - this.fileOffset = fileOffset; // File offset to beginning of tree - this.path = config.url; - this.littleEndian = littleEndian; - } - - async load() { - const rootNodeOffset = this.fileOffset + RPTREE_HEADER_SIZE; - const bufferedReader = isDataURL(this.path) ? - this.loader : - new BufferedReader(this.config, BUFFER_SIZE); - this.rootNode = await this.readNode(rootNodeOffset, bufferedReader); - return this - } - - async readNode(filePosition, bufferedReader) { - - let dataView = await bufferedReader.dataViewForRange({start: filePosition, size: 4}, false); - let binaryParser = new BinaryParser$1(dataView, this.littleEndian); - const type = binaryParser.getByte(); - const isLeaf = (type === 1); - binaryParser.getByte(); - const count = binaryParser.getUShort(); - filePosition += 4; - - let bytesRequired = count * (isLeaf ? RPTREE_NODE_LEAF_ITEM_SIZE : RPTREE_NODE_CHILD_ITEM_SIZE); - let range2 = {start: filePosition, size: bytesRequired}; - dataView = await bufferedReader.dataViewForRange(range2, false); - const items = new Array(count); - binaryParser = new BinaryParser$1(dataView); - - if (isLeaf) { - for (let i = 0; i < count; i++) { - let item = { - isLeaf: true, - startChrom: binaryParser.getInt(), - startBase: binaryParser.getInt(), - endChrom: binaryParser.getInt(), - endBase: binaryParser.getInt(), - dataOffset: binaryParser.getLong(), - dataSize: binaryParser.getLong() - }; - items[i] = item; - - } - return new RPTreeNode(items) - } else { // non-leaf - for (let i = 0; i < count; i++) { - - let item = { - isLeaf: false, - startChrom: binaryParser.getInt(), - startBase: binaryParser.getInt(), - endChrom: binaryParser.getInt(), - endBase: binaryParser.getInt(), - childOffset: binaryParser.getLong() - }; - items[i] = item; - } - - return new RPTreeNode(items) - } - - } - - async findLeafItemsOverlapping(chrIdx1, startBase, chrIdx2, endBase) { - - let self = this; - - return new Promise(function (fulfill, reject) { - - let leafItems = [], - processing = new Set(), - bufferedReader = isDataURL(self.path) ? - self.loader : - new BufferedReader(self.config, BUFFER_SIZE); - - processing.add(0); // Zero represents the root node - findLeafItems(self.rootNode, 0); - - function findLeafItems(node, nodeId) { - - if (overlaps(node, chrIdx1, startBase, chrIdx2, endBase)) { - - let items = node.items; - - items.forEach(function (item) { - - if (overlaps(item, chrIdx1, startBase, chrIdx2, endBase)) { - - if (item.isLeaf) { - leafItems.push(item); - } else { - if (item.childNode) { - findLeafItems(item.childNode); - } else { - processing.add(item.childOffset); // Represent node to-be-loaded by its file position - - self.readNode(item.childOffset, bufferedReader) - .then(function (node) { - item.childNode = node; - findLeafItems(node, item.childOffset); - }) - .catch(reject); - } - } - } - }); - - } - - if (nodeId !== undefined) processing.delete(nodeId); - - // Wait until all nodes are processed - if (processing.size === 0) { - fulfill(leafItems); - } - } - }) - } -} - -class RPTreeNode { - - constructor(items) { - - this.items = items; - - let minChromId = Number.MAX_SAFE_INTEGER, - maxChromId = 0, - minStartBase = Number.MAX_SAFE_INTEGER, - maxEndBase = 0, - i, - item; - - for (i = 0; i < items.length; i++) { - item = items[i]; - minChromId = Math.min(minChromId, item.startChrom); - maxChromId = Math.max(maxChromId, item.endChrom); - minStartBase = Math.min(minStartBase, item.startBase); - maxEndBase = Math.max(maxEndBase, item.endBase); - } - - this.startChrom = minChromId; - this.endChrom = maxChromId; - this.startBase = minStartBase; - this.endBase = maxEndBase; - } -} - -class BPTree { - - constructor(binaryParser, startOffset, genome) { - - let magic = binaryParser.getInt(); - let blockSize = binaryParser.getInt(); - let keySize = binaryParser.getInt(); - let valSize = binaryParser.getInt(); - let itemCount = binaryParser.getLong(); - let reserved = binaryParser.getLong(); - let chromToId = {}; - let idToChrom = []; - - this.header = { - magic: magic, - blockSize: blockSize, - keySize: keySize, - valSize: valSize, - itemCount: itemCount, - reserved: reserved - }; - this.chromToID = chromToId; - this.idToChrom = idToChrom; - - // Recursively walk tree to populate dictionary - readTreeNode(binaryParser, -1); - - - function readTreeNode(byteBuffer, offset) { - - if (offset >= 0) byteBuffer.position = offset; - - let type = byteBuffer.getByte(); - byteBuffer.getByte(); - let count = byteBuffer.getUShort(), - i, - key, - chromId, - childOffset, - bufferOffset, - currOffset; - - - if (type === 1) { - - for (i = 0; i < count; i++) { - - key = byteBuffer.getFixedLengthTrimmedString(keySize); - chromId = byteBuffer.getInt(); - byteBuffer.getInt(); - - if (genome) key = genome.getChromosomeName(key); // Translate to canonical chr name - chromToId[key] = chromId; - idToChrom[chromId] = key; - - } - } else { // non-leaf - - for (i = 0; i < count; i++) { - - key = byteBuffer.getFixedLengthTrimmedString(keySize); - childOffset = byteBuffer.getLong(); - bufferOffset = childOffset - startOffset; - currOffset = byteBuffer.position; - readTreeNode(byteBuffer, bufferOffset); - byteBuffer.position = currOffset; - } - } - - } - } -} - -/** - * Return true if {chrIdx1:startBase-chrIdx2:endBase} overlaps item's interval - * @returns {boolean} - */ -function overlaps(item, chrIdx1, startBase, chrIdx2, endBase) { - - if (!item) { - console.log("null item for " + chrIdx1 + " " + startBase + " " + endBase); - return false - } - - return ((chrIdx2 > item.startChrom) || (chrIdx2 === item.startChrom && endBase >= item.startBase)) && - ((chrIdx1 < item.endChrom) || (chrIdx1 === item.endChrom && startBase <= item.endBase)) - - -} - -class BWTotalSummary { - - constructor(byteBuffer) { - if (byteBuffer) { - this.basesCovered = byteBuffer.getLong(); - this.minVal = byteBuffer.getDouble(); - this.maxVal = byteBuffer.getDouble(); - this.sumData = byteBuffer.getDouble(); - this.sumSquares = byteBuffer.getDouble(); - computeStats.call(this); - } else { - this.basesCovered = 0; - this.minVal = 0; - this.maxVal = 0; - this.sumData = 0; - this.sumSquares = 0; - this.mean = 0; - this.stddev = 0; - } - } -} - -function computeStats() { - let n = this.basesCovered; - if (n > 0) { - this.mean = this.sumData / n; - this.stddev = Math.sqrt(this.sumSquares / (n - 1)); - - let min = this.minVal < 0 ? this.mean - 2 * this.stddev : 0, - max = this.maxVal > 0 ? this.mean + 2 * this.stddev : 0; - - this.defaultRange = { - min: min, - max: max - }; - } -} - -function zoomLevelForScale$1(bpPerPixel, zoomLevelHeaders) { - let level; - for (let i = 0; i < zoomLevelHeaders.length; i++) { - const zl = zoomLevelHeaders[i]; - if (zl.reductionLevel < bpPerPixel) { - level = zl; - break - } - } - return level -} - - -function decodeWigData(data, chrIdx1, bpStart, chrIdx2, bpEnd, featureArray, chrDict) { - - const binaryParser = new BinaryParser$1(data); - const chromId = binaryParser.getInt(); - const blockStart = binaryParser.getInt(); - let chromStart = blockStart; - let chromEnd = binaryParser.getInt(); - const itemStep = binaryParser.getInt(); - const itemSpan = binaryParser.getInt(); - const type = binaryParser.getByte(); - binaryParser.getByte(); - let itemCount = binaryParser.getUShort(); - - if (chromId >= chrIdx1 && chromId <= chrIdx2) { - - let idx = 0; - while (itemCount-- > 0) { - let value; - switch (type) { - case 1: - chromStart = binaryParser.getInt(); - chromEnd = binaryParser.getInt(); - value = binaryParser.getFloat(); - break - case 2: - chromStart = binaryParser.getInt(); - value = binaryParser.getFloat(); - chromEnd = chromStart + itemSpan; - break - case 3: // Fixed step - value = binaryParser.getFloat(); - chromStart = blockStart + idx * itemStep; - chromEnd = chromStart + itemSpan; - idx++; - break - } - - if (chromId < chrIdx1 || (chromId === chrIdx1 && chromEnd < bpStart)) continue - else if (chromId > chrIdx2 || (chromId === chrIdx2 && chromStart >= bpEnd)) break - - if (Number.isFinite(value)) { - const chr = chrDict[chromId]; - featureArray.push({chr: chr, start: chromStart, end: chromEnd, value: value}); - } - - } - } -} - -function getBedDataDecoder() { - - const minSize = 3 * 4 + 1; // Minimum # of bytes required for a bed record - const decoder = getDecoder(this.header.definedFieldCount, this.header.fieldCount, this.autoSql, this.format); - return function (data, chrIdx1, bpStart, chrIdx2, bpEnd, featureArray, chrDict) { - const binaryParser = new BinaryParser$1(data); - while (binaryParser.remLength() >= minSize) { - - const chromId = binaryParser.getInt(); - const chr = chrDict[chromId]; - const chromStart = binaryParser.getInt(); - const chromEnd = binaryParser.getInt(); - const rest = binaryParser.getString(); - if (chromId < chrIdx1 || (chromId === chrIdx1 && chromEnd < bpStart)) continue - else if (chromId > chrIdx2 || (chromId === chrIdx2 && chromStart >= bpEnd)) break - - if (chromEnd > 0) { - const feature = {chr: chr, start: chromStart, end: chromEnd}; - featureArray.push(feature); - const tokens = rest.split("\t"); - decoder(feature, tokens); - } - } - } -} - - -function decodeZoomData(data, chrIdx1, bpStart, chrIdx2, bpEnd, featureArray, chrDict, windowFunction) { - - const binaryParser = new BinaryParser$1(data); - const minSize = 8 * 4; // Minimum # of bytes required for a zoom record - - - while (binaryParser.remLength() >= minSize) { - const chromId = binaryParser.getInt(); - const chr = chrDict[chromId]; - const chromStart = binaryParser.getInt(); - const chromEnd = binaryParser.getInt(); - const validCount = binaryParser.getInt(); - const minVal = binaryParser.getFloat(); - const maxVal = binaryParser.getFloat(); - const sumData = binaryParser.getFloat(); - binaryParser.getFloat(); - let value; - switch (windowFunction) { - case "min": - value = minVal; - break - case "max": - value = maxVal; - break - default: - value = validCount === 0 ? 0 : sumData / validCount; - } - - if (chromId < chrIdx1 || (chromId === chrIdx1 && chromEnd < bpStart)) continue - else if (chromId > chrIdx2 || (chromId === chrIdx2 && chromStart >= bpEnd)) break - - - if (Number.isFinite(value)) { - featureArray.push({chr: chr, start: chromStart, end: chromEnd, value: value}); - - - } - } -} - -class DataBuffer { - - constructor(dataURI) { - this.data = decodeDataURI$1(dataURI).buffer; - } - - /** - * igvxhr interface - * @param ignore - * @param options - * @returns {any} - */ - loadArrayBuffer(ignore, options) { - const range = options.range; - return range ? this.data.slice(range.start, range.start + range.size) : this.data - } - - /** - * BufferedReader interface - * - * @param requestedRange - byte rangeas {start, size} - * @param fulfill - function to receive result - * @param asUint8 - optional flag to return result as an UInt8Array - */ - async dataViewForRange(requestedRange, asUint8) { - const len = Math.min(this.data.byteLength - requestedRange.start, requestedRange.size); - return asUint8 ? - new Uint8Array(this.data, requestedRange.start, len) : - new DataView(this.data, requestedRange.start, len) - } -} - -/* - * The MIT License (MIT) - * - * Copyright (c) 2014 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -class BWSource { - - constructor(config, genome) { - this.reader = new BWReader(config, genome); - this.genome = genome; - this.format = config.format || "bigwig"; - this.wgValues = {}; - this.queryable = true; - } - - async getFeatures({chr, start, end, bpPerPixel, windowFunction}) { - - const isBigWig = this.reader.type === "bigwig"; - - const features = (chr.toLowerCase() === "all") ? - (isBigWig ? await this.getWGValues(windowFunction) : []) : - await this.reader.readFeatures(chr, start, chr, end, bpPerPixel, windowFunction); - - if (!isBigWig) { - pack(features); - } - return features - } - - async getHeader() { - return this.reader.loadHeader() - } - - getDefaultRange() { - if (this.reader.totalSummary !== undefined) { - return this.reader.totalSummary.defaultRange - } else { - return undefined - } - } - - async defaultVisibilityWindow() { - return this.reader.defaultVisibilityWindow - } - - async getWGValues(windowFunction) { - - const nominalScreenWidth = 1000; // This doesn't need to be precise - const genome = this.genome; - - if (this.wgValues[windowFunction]) { - return this.wgValues[windowFunction] - } else { - - const bpPerPixel = genome.getGenomeLength() / nominalScreenWidth; - const features = await this.reader.readWGFeatures(bpPerPixel, windowFunction); - let wgValues = []; - for (let f of features) { - const chr = f.chr; - const offset = genome.getCumulativeOffset(chr); - const wgFeature = Object.assign({}, f); - wgFeature.chr = "all"; - wgFeature.start = offset + f.start; - wgFeature.end = offset + f.end; - wgValues.push(wgFeature); - } - this.wgValues[windowFunction] = wgValues; - return wgValues - } - } - - supportsWholeGenome() { - return this.reader.type === "bigwig" - } - - async trackType() { - return this.reader.getTrackType() - } -} - -/* - * The MIT License (MIT) - * - * Copyright (c) 2016 University of California San Diego - * Author: Jim Robinson - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -const GZIP_FLAG = 0x1; - -class TDFReader { - - constructor(config, genome) { - this.config = config; - this.genome = genome; - this.path = config.url; - this.groupCache = {}; - this.datasetCache = {}; - } - - - async readHeader() { - - if (this.magic !== undefined) { - return this // Already read - } - - let data = await igvxhr.loadArrayBuffer(this.path, buildOptions$1(this.config, {range: {start: 0, size: 64000}})); - let binaryParser = new BinaryParser$1(new DataView(data)); - this.magic = binaryParser.getInt(); - this.version = binaryParser.getInt(); - this.indexPos = binaryParser.getLong(); - this.indexSize = binaryParser.getInt(); - binaryParser.getInt(); - - - if (this.version >= 2) { - let nWindowFunctions = binaryParser.getInt(); - this.windowFunctions = []; - while (nWindowFunctions-- > 0) { - this.windowFunctions.push(binaryParser.getString()); - } - } - - this.trackType = binaryParser.getString(); - this.trackLine = binaryParser.getString(); - - let nTracks = binaryParser.getInt(); - this.trackNames = []; - while (nTracks-- > 0) { - this.trackNames.push(binaryParser.getString()); - } - this.genomeID = binaryParser.getString(); - this.flags = binaryParser.getInt(); - this.compressed = (this.flags & GZIP_FLAG) !== 0; - - // Now read index - data = await igvxhr.loadArrayBuffer(this.path, buildOptions$1(this.config, { - range: { - start: this.indexPos, - size: this.indexSize - } - })); - binaryParser = new BinaryParser$1(new DataView(data)); - this.datasetIndex = {}; - let nEntries = binaryParser.getInt(); - while (nEntries-- > 0) { - const name = binaryParser.getString(); - const pos = binaryParser.getLong(); - const size = binaryParser.getInt(); - this.datasetIndex[name] = {position: pos, size: size}; - } - - this.groupIndex = {}; - nEntries = binaryParser.getInt(); - while (nEntries-- > 0) { - const name = binaryParser.getString(); - const pos = binaryParser.getLong(); - const size = binaryParser.getInt(); - this.groupIndex[name] = {position: pos, size: size}; - } - - return this - } - - async readDataset(chr, windowFunction, zoom) { - - const key = chr + "_" + windowFunction + "_" + zoom; - - if (this.datasetCache[key]) { - return this.datasetCache[key] - - } else { - await this.readHeader(); - const wf = (this.version < 2) ? "" : "/" + windowFunction; - const zoomString = (chr.toLowerCase() === "all" || zoom === undefined) ? "0" : zoom.toString(); - - let dsName; - if (windowFunction === "raw") { - dsName = "/" + chr + "/raw"; - } else { - dsName = "/" + chr + "/z" + zoomString + wf; - } - const indexEntry = this.datasetIndex[dsName]; - - if (indexEntry === undefined) { - return undefined - } - - const data = await igvxhr.loadArrayBuffer(this.path, buildOptions$1(this.config, { - range: { - start: indexEntry.position, - size: indexEntry.size - } - })); - - if (!data) { - return undefined - } - - const binaryParser = new BinaryParser$1(new DataView(data)); - let nAttributes = binaryParser.getInt(); - const attributes = {}; - while (nAttributes-- > 0) { - attributes[binaryParser.getString()] = binaryParser.getString(); - } - const dataType = binaryParser.getString(); - const tileWidth = binaryParser.getFloat(); - let nTiles = binaryParser.getInt(); - const tiles = []; - while (nTiles-- > 0) { - tiles.push({position: binaryParser.getLong(), size: binaryParser.getInt()}); - } - - const dataset = { - name: dsName, - attributes: attributes, - dataType: dataType, - tileWidth: tileWidth, - tiles: tiles - }; - - this.datasetCache[key] = dataset; - return dataset - } - } - - async readRootGroup() { - - const genome = this.genome; - const rootGroup = this.groupCache["/"]; - if (rootGroup) { - return rootGroup - } else { - - const group = await this.readGroup("/"); - const names = group["chromosomes"]; - const maxZoomString = group["maxZoom"]; - - // Now parse out interesting attributes. - if (maxZoomString) { - this.maxZoom = Number(maxZoomString); - } - - const totalCountString = group["totalCount"]; - if (totalCountString) { - group.totalCount = Number(totalCountString); - } - - // Chromosome names - const chrAliasTable = {}; - if (names) { - names.split(",").forEach(function (chr) { - const canonicalName = genome.getChromosomeName(chr); - chrAliasTable[canonicalName] = chr; - }); - } - this.chrAliasTable = chrAliasTable; - - this.groupCache["/"] = group; - return group - } - } - - async readGroup(name) { - - const group = this.groupCache[name]; - if (group) { - return group - } else { - - await this.readHeader(); - const indexEntry = this.groupIndex[name]; - if (indexEntry === undefined) { - return undefined - } - - const data = await igvxhr.loadArrayBuffer(this.path, buildOptions$1(this.config, { - range: { - start: indexEntry.position, - size: indexEntry.size - } - })); - - if (!data) { - return undefined - } - - const binaryParser = new BinaryParser$1(new DataView(data)); - const group = {name: name}; - let nAttributes = binaryParser.getInt(); - while (nAttributes-- > 0) { - const key = binaryParser.getString(); - const value = binaryParser.getString(); - group[key] = value; - } - this.groupCache[name] = group; - return group - } - } - - - async readTiles(tileIndeces, nTracks) { - - tileIndeces.sort(function (a, b) { - return a.position - b.position - }); - - tileIndeces = tileIndeces.filter(function (idx) { - return idx.size > 0 - }); - - if (tileIndeces.length === 0) { - return Promise.resolve([]) - } - - const firstEntry = tileIndeces[0]; - const lastEntry = tileIndeces[tileIndeces.length - 1]; - const position = firstEntry.position; - const size = (lastEntry.position + lastEntry.size) - position; - const data = await igvxhr.loadArrayBuffer(this.path, buildOptions$1(this.config, { - range: { - start: position, - size: size - } - })); - - const tiles = []; - - // Loop through and decode tiles - for (let indexEntry of tileIndeces) { - const start = indexEntry.position - position; - const size = indexEntry.size; - if (size > 0) { - let tileData; - if (this.compressed) { - const plain = inflate_1$3(data.slice(start, start + size)); - tileData = plain.buffer; - } else { - tileData = data.slice(start, start + size); - } - - const binaryParser = new BinaryParser$1(new DataView(tileData)); - const type = binaryParser.getString(); - let tile; - switch (type) { - case "fixedStep": - tile = createFixedStep(binaryParser, nTracks); - break - case "variableStep": - tile = createVariableStep(binaryParser, nTracks); - break - case "bed": - case "bedWithName": - tile = createBed(binaryParser, nTracks, type); - break - default: - throw "Unknown tile type: " + type - } - tiles.push(tile); - } - } - return tiles - } - - async readTile(indexEntry, nTracks) { - - let data = await igvxhr.loadArrayBuffer(this.path, buildOptions$1(this.config, { - range: { - start: indexEntry.position, - size: indexEntry.size - } - })); - - if (this.compressed) { - const plain = inflate_1$3(data); - data = plain.buffer; - } - - const binaryParser = new BinaryParser$1(new DataView(data)); - const type = binaryParser.getString(); - switch (type) { - case "fixedStep": - return createFixedStep(binaryParser, nTracks) - case "variableStep": - return createVariableStep(binaryParser, nTracks) - case "bed": - case "bedWithName": - return createBed(binaryParser, nTracks, type) - default: - throw "Unknown tile type: " + type - } - } - -} - -function createFixedStep(binaryParser, nTracks) { - const nPositions = binaryParser.getInt(); - const start = binaryParser.getInt(); - const span = binaryParser.getFloat(); - - const data = []; - let nt = nTracks; - while (nt-- > 0) { - let np = nPositions; - const dtrack = []; - while (np-- > 0) { - dtrack.push(binaryParser.getFloat()); - } - data.push(dtrack); - } - - return { - type: "fixedStep", - start: start, - span: span, - data: data, - nTracks: nTracks, - nPositions: nPositions - } -} - -function createVariableStep(binaryParser, nTracks) { - - const tileStart = binaryParser.getInt(); - const span = binaryParser.getFloat(); - const nPositions = binaryParser.getInt(); - const start = []; - - let np = nPositions; - while (np-- > 0) { - start.push(binaryParser.getInt()); - } - binaryParser.getInt(); // # of samples, ignored but should === nTracks - - const data = []; - let nt = nTracks; - while (nt-- > 0) { - np = nPositions; - const dtrack = []; - while (np-- > 0) { - dtrack.push(binaryParser.getFloat()); - } - data.push(dtrack); - } - - return { - type: "variableStep", - tileStart: tileStart, - span: span, - start: start, - data: data, - nTracks: nTracks, - nPositions: nPositions - } -} - -function createBed(binaryParser, nTracks, type) { - - const nPositions = binaryParser.getInt(); - - let n = nPositions; - const start = []; - while (n-- > 0) { - start.push(binaryParser.getInt()); - } - - n = nPositions; - const end = []; - while (n-- > 0) { - end.push(binaryParser.getInt()); - } - - binaryParser.getInt(); // # of samples, ignored but should === nTracks - const data = []; - let nt = nTracks; - while (nt-- > 0) { - let np = nPositions; - const dtrack = []; - while (np-- > 0) { - dtrack.push(binaryParser.getFloat()); - } - data.push(dtrack); - } - - if (type === "bedWithName") { - n = nPositions; - const name = []; - while (n-- > 0) { - name.push(binaryParser.getString()); - } - } - - return { - type: type, - start: start, - end: end, - data: data, - nTracks: nTracks, - nPositions: nPositions - } - -} - -/* - * The MIT License (MIT) - * - * Copyright (c) 2016 University of California San Diego - * Author: Jim Robinson - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -class TDFSource { - - constructor(config, genome) { - this.genome = genome; - this.windowFunction = config.windowFunction || "mean"; - this.reader = new TDFReader(config, genome); - this.queryable = true; - } - - async getFeatures({chr, start, end, bpPerPixel}) { - - if (chr.toLowerCase() === "all") { - const wgFeatures = []; - const genome = this.genome; - const chrNames = this.genome.wgChromosomeNames; - if (chrNames) { - for (let c of genome.wgChromosomeNames) { - const len = genome.getChromosome(c).bpLength; - bpPerPixel = len / 1000; - const chrFeatures = await this._getFeatures(c, 0, len, bpPerPixel); - if (chrFeatures) { - for (let f of chrFeatures) { - const wg = Object.assign({}, f); - wg.chr = "all"; - wg.start = genome.getGenomeCoordinate(f.chr, f.start); - wg.end = genome.getGenomeCoordinate(f.chr, f.end); - wg._f = f; - wgFeatures.push(wg); - } - } - } - } - return wgFeatures - - } else { - return this._getFeatures(chr, start, end, bpPerPixel) - } - } - - async _getFeatures(chr, start, end, bpPerPixel) { - const genomicInterval = new GenomicInterval(chr, start, end); - const genome = this.genome; - - - if (!this.rootGroup) { - this.rootGroup = await this.reader.readRootGroup(); - if (!this.normalizationFactor) { - const totalCount = this.rootGroup.totalCount; - if (totalCount) { - this.normalizationFactor = 1.0e6 / totalCount; - } - } - } - - genomicInterval.bpPerPixel = bpPerPixel; - const zoom = zoomLevelForScale(chr, bpPerPixel, genome); - let queryChr = this.reader.chrAliasTable[chr]; - let maxZoom = this.reader.maxZoom; - if (queryChr === undefined) queryChr = chr; - if (maxZoom === undefined) maxZoom = -1; - - const wf = zoom > maxZoom ? "raw" : this.windowFunction; - const dataset = await this.reader.readDataset(queryChr, wf, zoom); - if (dataset == null) { - return [] - } - - const tileWidth = dataset.tileWidth; - const startTile = Math.floor(start / tileWidth); - const endTile = Math.floor(end / tileWidth); - const NTRACKS = 1; // TODO read this - const tiles = await this.reader.readTiles(dataset.tiles.slice(startTile, endTile + 1), NTRACKS); - const features = []; - for (let tile of tiles) { - switch (tile.type) { - case "bed": - decodeBedTile(tile, chr, start, end, bpPerPixel, features); - break - case "variableStep": - decodeVaryTile(tile, chr, start, end, bpPerPixel, features); - break - case "fixedStep": - decodeFixedTile(tile, chr, start, end, bpPerPixel, features); - break - default: - throw ("Unknown tile type: " + tile.type) - } - } - features.sort(function (a, b) { - return a.start - b.start - }); - - return features - } - - get supportsWholeGenome() { - return true - } -} - -function decodeBedTile(tile, chr, bpStart, bpEnd, bpPerPixel, features) { - - const nPositions = tile.nPositions; - const starts = tile.start; - const ends = tile.end; - const data = tile.data[0]; // Single track for now - for (let i = 0; i < nPositions; i++) { - const s = starts[i]; - const e = ends[i]; - if (e < bpStart) continue - if (s > bpEnd) break - features.push({ - chr: chr, - start: s, - end: e, - value: data[i] - }); - } -} - -function decodeVaryTile(tile, chr, bpStart, bpEnd, bpPerPixel, features) { - - const nPositions = tile.nPositions; - const starts = tile.start; - const span = tile.span; - const data = tile.data[0]; // Single track for now - for (let i = 0; i < nPositions; i++) { - const s = starts[i]; - const e = s + span; - if (e < bpStart) continue - if (s > bpEnd) break - features.push({ - chr: chr, - start: s, - end: e, - value: data[i] - }); - } -} - -function decodeFixedTile(tile, chr, bpStart, bpEnd, bpPerPixel, features) { - - const nPositions = tile.nPositions; - let s = tile.start; - const span = tile.span; - const data = tile.data[0]; // Single track for now - - for (let i = 0; i < nPositions; i++) { - const e = s + span; - if (s > bpEnd) break - if (e >= bpStart) { - if (!Number.isNaN(data[i])) { - features.push({ - chr: chr, - start: s, - end: e, - value: data[i] - }); - } - } - s = e; - } -} - - -var log2 = Math.log(2); - -function zoomLevelForScale(chr, bpPerPixel, genome) { - - // Convert bpPerPixel to IGV "zoom" level. This is a bit convoluted, IGV computes zoom levels assuming - // display in a 700 pixel window. The fully zoomed out view of a chromosome is zoom level "0". - // Zoom level 1 is magnified 2X, and so forth - - var chrSize = genome.getChromosome(chr).bpLength; - - return Math.ceil(Math.log(Math.max(0, (chrSize / (bpPerPixel * 700)))) / log2) -} - -/* - * The MIT License (MIT) - * - * Copyright (c) 2014-2015 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -/** - * feature source for features supplied directly, as opposed to reading and parsing from a file or webservice - * - * @param config - * @constructor - */ -class StaticFeatureSource { - - constructor(config, genome) { - - this.config = config; - this.genome = genome; - this.queryable = false; - this.searchable = config.searchable !== false; // searchable by default - this.updateFeatures(config.features); - } - - updateFeatures(features) { - features = fixFeatures(features, this.genome); - packFeatures(features); - if (this.config.mappings) { - mapProperties(features, this.config.mappings); - } - this.featureCache = new FeatureCache$1(features, this.genome); - - if (this.searchable || this.config.searchableFields) { - this.genome.addFeaturesToDB(features, this.config); - } - } - - /** - * Required function for all data source objects. Fetches features for the - * range requested. - * - * This function is complex due to the variety of reader types backing it, some indexed, some queryable, - * some not. - * - * @param chr - * @param start - * @param end - * @param bpPerPixel - */ - async getFeatures({chr, start, end, bpPerPixel, visibilityWindow}) { - - const genome = this.genome; - const queryChr = genome ? genome.getChromosomeName(chr) : chr; - const isWholeGenome = ("all" === queryChr.toLowerCase()); - - // Various conditions that can require a feature load - // * view is "whole genome" but no features are loaded - // * cache is disabled - // * cache does not contain requested range - if (isWholeGenome) { - return computeWGFeatures(this.featureCache.getAllFeatures(), this.genome, this.maxWGCount) - } else { - return this.featureCache.queryFeatures(queryChr, start, end) - } - } - - // - // supportsWholeGenome() { - // return true - // } - - getAllFeatures() { - return this.featureCache.getAllFeatures() - } - - supportsWholeGenome() { - return true - } - - -} - - -/** - * This function is used to apply properties normally added during parsing to features supplied directly in the - * config as an array of objects. At the moment the only application is bedpe type features. - * @param features - */ -function fixFeatures(features, genome) { - - if (genome) { - for (let feature of features) { - feature.chr = genome.getChromosomeName(feature.chr); - } - } - - return features -} - - - -function mapProperties(features, mappings) { - let mappingKeys = Object.keys(mappings); - features.forEach(function (f) { - mappingKeys.forEach(function (key) { - f[key] = f[mappings[key]]; - }); - }); -} - -/* - * The MIT License (MIT) - * - * Copyright (c) 2014-2015 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -const bbFormats = new Set(['bigwig', 'bw', 'bigbed', 'bb', 'biginteract', 'biggenepred', 'bignarrowpeak']); - -function FeatureSource(config, genome) { - - const format = config.format ? config.format.toLowerCase() : undefined; - - if (config.features) { - return new StaticFeatureSource(config, genome) - } else if (bbFormats.has(format)) { - return new BWSource(config, genome) - } else if ("tdf" === format) { - return new TDFSource(config, genome) - } else { - return new TextFeatureSource(config, genome) - } -} - -const appleCrayonColorName = 'nickel'; - -const ROI_DEFAULT_ALPHA = 2 / 16; - -const ROI_DEFAULT_COLOR = appleCrayonRGBA(appleCrayonColorName, ROI_DEFAULT_ALPHA); -const ROI_DEFAULT_HEADER_COLOR = 'rgb(190,190,190)'; - -const ROI_USER_HEADER_DEFINED_COLOR = 'rgba(155,185,129)'; -const ROI_USER_DEFINED_COLOR = ROI_DEFAULT_COLOR; - -class ROISet { - - constructor(config, genome) { - - this.url = config.url; - - if (config.name) { - this.name = config.name; - } else if (config.url && isFile$1(config.url)) { - this.name = config.url.name; - } else if (config.url && isString$2(config.url) && !config.url.startsWith("data:")) { - this.name = getFilename$2(config.url); - } - - this.isUserDefined = config.isUserDefined; - - if (config.features) { - this.featureSource = new DynamicFeatureSource(config.features, genome); - } else { - if (config.format) { - config.format = config.format.toLowerCase(); - } else { - const filename = getFilename$2(config.url); - config.format = inferFileFormat(filename); - } - this.featureSource = config.featureSource || FeatureSource(config, genome); - } - - if (true === this.isUserDefined) { - this.color = config.color || ROI_USER_DEFINED_COLOR; - this.headerColor = ROI_USER_HEADER_DEFINED_COLOR; - - } else { - - this.color = config.color || ROI_DEFAULT_COLOR; - this.headerColor = ROI_DEFAULT_HEADER_COLOR; - - // Use body color with alpha pinned to 1 - // const [ r, g, b, discard ] = rgbaStringTokens(this.color) - // this.headerColor = `rgba(${ r },${ g },${ b },${ 1.0 })` - - } - } - - async getFeatures(chr, start, end) { - return this.featureSource.getFeatures({chr, start, end}) - } - - async getAllFeatures() { - return typeof this.featureSource.getAllFeatures === 'function' ? await this.featureSource.getAllFeatures() : {} - } - - addFeature(feature) { - if (this.isUserDefined) { - this.featureSource.addFeature(feature); - } else { - console.error("Attempt to add ROI to non user-defined set"); - } - } - - removeFeature(feature) { - if (this.isUserDefined) { - this.featureSource.removeFeature(feature); - } else { - console.error("Attempt to remove ROI from non user-defined set"); - } - } - - toJSON() { - if (this.url) { - return {name: this.name, color: this.color, url: this.url, isUserDefined: this.isUserDefined} - } else { - const featureMap = this.featureSource.getAllFeatures(); - const features = []; - for (let chr of Object.keys(featureMap)) { - for (let f of featureMap[chr]) { - features.push(f); - } - } - return {name: this.name, color: this.color, features: features, isUserDefined: this.isUserDefined} - } - } - - dispose() { - for (let key of Object.keys(this)) { - this[key] = undefined; - } - } - -} - -const SCREEN_COORDS_WIDTH_THRESHOLD = 3; - -function screenCoordinates(regionStartBP, regionEndBP, bpStart, bpp) { - - let xStart = Math.round((regionStartBP - bpStart) / bpp); - const xEnd = Math.round((regionEndBP - bpStart) / bpp); - - let width = xEnd - xStart; - - if (width < SCREEN_COORDS_WIDTH_THRESHOLD) { - width = SCREEN_COORDS_WIDTH_THRESHOLD; - xStart -= 1; - } - - return {x: xStart, width} -} - - -/** - * Special feature source that allows addition of features dynamically - */ -class DynamicFeatureSource { - - constructor(features, genome) { - this.featureMap = {}; - this.genome = genome; - - for (let feature of features) { - - // Store as canonical chr name (i.e. translate aliases) - const chrKey = genome ? genome.getChromosomeName(feature.chr) : feature.chr; - - let featureList = this.featureMap[chrKey]; - if (!featureList) { - featureList = []; - this.featureMap[chrKey] = featureList; - } - featureList.push(feature); - } - - for (let key of Object.keys(this.featureMap)) { - this.featureMap[key].sort((a, b) => a.start - b.start); - } - } - - getFeatures({chr, start, end}) { - if (chr.toLowerCase() === 'all') { - return computeWGFeatures(this.featureMap, this.genome) - } else { - // TODO -- this use of filter is O(N), and might not scale well for large feature lists. - const featureList = this.featureMap[chr]; - return featureList ? featureList.filter(feature => feature.end > start && feature.start < end) : [] - } - } - - getAllFeatures() { - return this.featureMap - } - - supportsWholeGenome() { - return true - } - - addFeature(feature) { - let featureList = this.featureMap[feature.chr]; - if (!featureList) { - featureList = []; - this.featureMap[feature.chr] = featureList; - } - featureList.push(feature); - featureList.sort((a, b) => a.start - b.start); - } - - removeFeature({chr, start, end}) { - - if (this.featureMap[chr]) { - const match = `${chr}-${start}-${end}`; - this.featureMap[chr] = this.featureMap[chr].filter(feature => match !== `${feature.chr}-${feature.start}-${feature.end}`); - } - } -} - -/* - * The MIT License (MIT) - * - * Copyright (c) 2016-2017 The Regents of the University of California - * Author: Jim Robinson - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -const RULER_SWEEPER_COLOR = 'rgba(68, 134, 247, 0.25)'; - -class RulerSweeper { - - constructor(rulerViewport, column, browser, referenceFrame) { - - this.rulerViewport = rulerViewport; - - this.rulerSweeper = domUtils$1.div({class: 'igv-ruler-sweeper'}); - column.appendChild(this.rulerSweeper); - - this.browser = browser; - this.referenceFrame = referenceFrame; - - this.isMouseHandlers = undefined; - - this.addBrowserObserver(); - } - - addBrowserObserver() { - - const observerHandler = () => { - if (this.referenceFrame) { - GenomeUtils.isWholeGenomeView(this.referenceFrame.chr) ? this.removeMouseHandlers() : this.addMouseHandlers(); - } - }; - - // Viewport Content - this.boundObserverHandler = observerHandler.bind(this); - this.browser.on('locuschange', this.boundObserverHandler); - - } - - removeBrowserObserver() { - this.browser.off('locuschange', this.boundObserverHandler); - } - - addMouseHandlers() { - - if (true === this.isMouseHandlers) { - return - } - - const threshold = 1; - - let isMouseDown; - let isMouseIn; - let mouseDownX; - let left; - let width; - let dx; - - // Viewport Content - this.boundContentMouseDownHandler = contentMouseDownHandler.bind(this); - this.rulerViewport.contentDiv.addEventListener('mousedown', this.boundContentMouseDownHandler); - - function contentMouseDownHandler(event) { - - isMouseDown = true; - isMouseIn = true; - - const {x} = domUtils$1.translateMouseCoordinates(event, this.rulerViewport.contentDiv); - left = mouseDownX = x; - - width = threshold; - - - this.rulerSweeper.style.display = 'block'; - this.rulerSweeper.style.backgroundColor = true === event.shiftKey ? ROI_USER_DEFINED_COLOR : RULER_SWEEPER_COLOR; - - this.rulerSweeper.style.left = `${left}px`; - this.rulerSweeper.style.width = `${width}px`; - - } - - // Document - this.boundDocumentMouseMoveHandler = documentMouseMoveHandler.bind(this); - document.addEventListener('mousemove', this.boundDocumentMouseMoveHandler); - - function documentMouseMoveHandler(event) { - - let mouseCurrentX; - - if (isMouseDown && isMouseIn) { - - const {x} = domUtils$1.translateMouseCoordinates(event, this.rulerViewport.contentDiv); - mouseCurrentX = Math.max(Math.min(x, this.rulerViewport.contentDiv.clientWidth), 0); - - dx = mouseCurrentX - mouseDownX; - - width = Math.abs(dx); - this.rulerSweeper.style.width = `${width}px`; - - if (dx < 0) { - left = mouseDownX + dx; - this.rulerSweeper.style.left = `${left}px`; - } - - } - - } - - this.boundDocumentMouseUpHandler = documentMouseUpHandler.bind(this); - document.addEventListener('mouseup', this.boundDocumentMouseUpHandler); - - function documentMouseUpHandler(event) { - - let genomicExtent; - - if (true === isMouseDown && true === isMouseIn) { - - isMouseDown = isMouseIn = undefined; - - this.rulerSweeper.style.display = 'none'; - - if (width > threshold) { - - genomicExtent = - { - start: Math.floor(this.referenceFrame.calculateEnd(left)), - end: Math.floor(this.referenceFrame.calculateEnd(left + width)), - }; - - - const shiftKeyPressed = event.shiftKey; - - if (true === shiftKeyPressed) { - this.browser.roiManager.updateUserDefinedROISet(Object.assign({chr: this.referenceFrame.chr}, genomicExtent)); - } else { - - validateGenomicExtent(this.browser.genome.getChromosome(this.referenceFrame.chr).bpLength, genomicExtent, this.browser.minimumBases()); - updateReferenceFrame(this.referenceFrame, genomicExtent, this.rulerViewport.contentDiv.clientWidth); - this.browser.updateViews(this.referenceFrame); - - } - - } - - } - - } - - this.isMouseHandlers = true; - } - - removeMouseHandlers() { - this.rulerViewport.contentDiv.removeEventListener('mousedown', this.boundContentMouseDownHandler); - document.removeEventListener('mousemove', this.boundDocumentMouseMoveHandler); - document.removeEventListener('mouseup', this.boundDocumentMouseUpHandler); - this.isMouseHandlers = false; - } - - dispose() { - this.removeBrowserObserver(); - this.removeMouseHandlers(); - this.rulerSweeper.remove(); - } - -} - -function updateReferenceFrame(referenceFrame, genomicExtent, pixelWidth) { - referenceFrame.start = Math.round(genomicExtent.start); - referenceFrame.end = Math.round(genomicExtent.end); - referenceFrame.bpPerPixel = (referenceFrame.end - referenceFrame.start) / pixelWidth; -} - -/* - * The MIT License (MIT) - * - * Copyright (c) 2016 University of California San Diego - * Author: Jim Robinson - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - -class PairedAlignment { - - constructor(firstAlignment) { - - this.paired = true; - this.firstAlignment = firstAlignment; - this.chr = firstAlignment.chr; - this.readName = firstAlignment.readName; - - if (firstAlignment.start < firstAlignment.mate.position) { - this.start = firstAlignment.start; - this.scStart = firstAlignment.scStart; - this.connectingStart = firstAlignment.start + firstAlignment.lengthOnRef; - this.connectingEnd = firstAlignment.mate.position; - } else { - this.start = firstAlignment.mate.position; - this.scStart = this.start; - this.connectingStart = firstAlignment.mate.position; - this.connectingEnd = firstAlignment.start; - } - - this.end = Math.max(firstAlignment.mate.position, firstAlignment.start + firstAlignment.lengthOnRef); // Approximate - this.lengthOnRef = this.end - this.start; - - let scEnd = Math.max(this.end, firstAlignment.scStart + firstAlignment.scLengthOnRef); - this.scLengthOnRef = scEnd - this.scStart; - - } - - setSecondAlignment(secondAlignment) { - - // TODO -- check the chrs are equal, error otherwise - this.secondAlignment = secondAlignment; - const firstAlignment = this.firstAlignment; - - if (secondAlignment.start > firstAlignment.start) { - this.connectingEnd = secondAlignment.start; - } else { - this.connectingStart = secondAlignment.start + secondAlignment.lengthOnRef; - } - - this.start = Math.min(firstAlignment.start, secondAlignment.start); - this.end = Math.max(firstAlignment.start + firstAlignment.lengthOnRef, secondAlignment.start + secondAlignment.lengthOnRef); - this.lengthOnRef = this.end - this.start; - - this.scStart = Math.min(firstAlignment.scStart, secondAlignment.scStart); - const scEnd = Math.max(firstAlignment.scStart + firstAlignment.scLengthOnRef, secondAlignment.scStart + secondAlignment.scLengthOnRef); - this.scLengthOnRef = scEnd - this.scStart; - - } - - containsLocation(genomicLocation, showSoftClips) { - const s = showSoftClips ? this.scStart : this.start; - const l = showSoftClips ? this.scLengthOnRef : this.lengthOnRef; - return (genomicLocation >= s && genomicLocation <= (s + l)) - } - - alignmentContaining(genomicLocation, showSoftClips) { - if (this.firstAlignment.containsLocation(genomicLocation, showSoftClips)) { - return this.firstAlignment - } else if (this.secondAlignment && this.secondAlignment.containsLocation(genomicLocation, showSoftClips)) { - return this.secondAlignment - } else { - return undefined - } - } - - popupData(genomicLocation) { - - let nameValues = this.firstAlignment.popupData(genomicLocation); - - if (this.secondAlignment) { - nameValues.push("-------------------------------"); - nameValues = nameValues.concat(this.secondAlignment.popupData(genomicLocation)); - } - return nameValues - } - - isPaired() { - return true // By definition - } - - isMateMapped() { - return true // By definition - } - - isProperPair() { - return this.firstAlignment.isProperPair() - } - - get fragmentLength() { - return Math.abs(this.firstAlignment.fragmentLength) - } - - firstOfPairStrand() { - - if (this.firstAlignment.isFirstOfPair()) { - return this.firstAlignment.strand - } else if (this.secondAlignment && this.secondAlignment.isFirstOfPair()) { - return this.secondAlignment.strand - } else { - return this.firstAlignment.mate.strand // Assumption is mate is first-of-pair - } - } - - hasTag(str) { - return this.firstAlignment.hasTag(str) || (this.secondAlignment && this.secondAlignment.hasTag(str)) - } -} - -/* - * The MIT License (MIT) - * - * Copyright (c) 2014 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -class BamAlignmentRow { - - constructor() { - - this.alignments = []; - this.score = undefined; - } - - findAlignment(genomicLocation) { - - const alignmentContains = (a, genomicLocation) => { - return genomicLocation >= a.start && genomicLocation < a.start + a.lengthOnRef - }; - - // find single alignment that overlaps sort location - let centerAlignment; - for (let i = 0; i < this.alignments.length; i++) { - const a = this.alignments[i]; - if (genomicLocation >= a.start && genomicLocation < a.start + a.lengthOnRef) { - if (a.paired) { - if (a.firstAlignment && alignmentContains(a.firstAlignment, genomicLocation)) { - centerAlignment = a.firstAlignment; - } else if (a.secondAlignment && alignmentContains(a.secondAlignment, genomicLocation)) { - centerAlignment = a.secondAlignment; - } - } else { - centerAlignment = a; - } - break - } - } - - return centerAlignment - - } - - getSortValue({position, option, tag}, alignmentContainer) { - - if (!option) option = "BASE"; - - const alignment = this.findAlignment(position); - if (undefined === alignment) { // This condition should never occur - return Number.MAX_VALUE - } - - switch (option) { - case "NUCLEOTIDE": - case "BASE": { - return calculateBaseScore(alignment, alignmentContainer, position) - } - case "STRAND": - return alignment.strand ? 1 : -1 - case "START": - return alignment.start - case "TAG": { - return alignment.tags()[tag] - } - case "READ_NAME": - return alignment.readName - case "INSERT_SIZE": - return -Math.abs(alignment.fragmentLength) - case "GAP_SIZE": - return -alignment.gapSizeAt(position) - case "MATE_CHR": - return alignment.mate - case "MQ": - return alignment.mq === undefined ? Number.MAX_VALUE : -alignment.mq - case "ALIGNED_READ_LENGTH": - return -alignment.lengthOnRef - default: - return Number.MAX_VALUE - } - - - function calculateBaseScore(alignment, alignmentContainer, genomicLocation) { - - let reference; - const idx = Math.floor(genomicLocation) - alignmentContainer.start; - if (idx < alignmentContainer.sequence.length) { - reference = alignmentContainer.sequence.charAt(idx); - } - if (!reference) { - return 0 - } - const base = alignment.readBaseAt(genomicLocation); - const quality = alignment.readBaseQualityAt(genomicLocation); - - const coverageMap = alignmentContainer.coverageMap; - const coverageMapIndex = Math.floor(genomicLocation - coverageMap.bpStart); - const coverage = coverageMap.coverage[coverageMapIndex]; - - // Insertions. These are additive with base scores as they occur between bases, so you can have a - // base mismatch AND an insertion - let baseScore = 0; - if (alignment.insertions) { - for (let ins of alignment.insertions) { - if (ins.start === genomicLocation) { - baseScore = -coverage.ins; - } - } - } - - - if (!base) { - // Either deletion or skipped (splice junction) - const delCount = coverage.del; - if (delCount > 0) { - baseScore -= delCount; - } else if (baseScore === 0) { // Don't modify insertion score, if any - baseScore = 1; - } - } else { - reference = reference.toUpperCase(); - if ('N' === base && baseScore === 0) { - baseScore = 2; - } else if ((reference === base || '=' === base) && baseScore === 0) { - baseScore = 4 - quality / 1000; - } else if ("X" === base || reference !== base) { - const count = coverage["pos" + base] + coverage["neg" + base]; - baseScore -= (count + (quality / 1000)); - } - } - - - return baseScore - } - } - - -} - -const alignmentSpace = 2; - -function canBePaired(alignment) { - return alignment.isPaired() && - alignment.mate && - alignment.isMateMapped() && - alignment.chr === alignment.mate.chr && - (alignment.isFirstOfPair() || alignment.isSecondOfPair()) && !(alignment.isSecondary() || alignment.isSupplementary()) -} - - -function pairAlignments(rows) { - - const pairCache = {}; - const result = []; - - for (let row of rows) { - for (let alignment of row.alignments) { - if (canBePaired(alignment)) { - let pairedAlignment = pairCache[alignment.readName]; - if (pairedAlignment) { - pairedAlignment.setSecondAlignment(alignment); - pairCache[alignment.readName] = undefined; // Don't need to track this anymore. - } else { - pairedAlignment = new PairedAlignment(alignment); - pairCache[alignment.readName] = pairedAlignment; - result.push(pairedAlignment); - } - } else { - result.push(alignment); - } - } - } - return result -} - -function unpairAlignments(rows) { - const result = []; - for (let row of rows) { - for (let alignment of row.alignments) { - if (alignment instanceof PairedAlignment) { - if (alignment.firstAlignment) result.push(alignment.firstAlignment); // shouldn't need the null test - if (alignment.secondAlignment) result.push(alignment.secondAlignment); - } else { - result.push(alignment); - } - } - } - return result -} - -function packAlignmentRows(alignments, start, end, showSoftClips) { - - //console.log(`packAlignmentRows ${start} ${end}`) - //const t0 = Date.now() - - if (!alignments) { - return undefined - } else if (alignments.length === 0) { - return [] - } else { - alignments.sort(function (a, b) { - return showSoftClips ? a.scStart - b.scStart : a.start - b.start - }); - - const packedAlignmentRows = []; - let alignmentRow; - let nextStart = 0; - let nextIDX = 0; - const allocated = new Set(); - const startNewRow = () => { - alignmentRow = new BamAlignmentRow(); - packedAlignmentRows.push(alignmentRow); - nextStart = 0; - nextIDX = 0; - allocated.clear(); - }; - startNewRow(); - - while (alignments.length > 0) { - if (nextIDX >= 0 && nextIDX < alignments.length) { - const alignment = alignments[nextIDX]; - allocated.add(alignment); - alignmentRow.alignments.push(alignment); - nextStart = showSoftClips ? - alignment.scStart + alignment.scLengthOnRef + alignmentSpace : - alignment.start + alignment.lengthOnRef + alignmentSpace; - nextIDX = binarySearch$1(alignments, (a) => (showSoftClips ? a.scStart : a.start) > nextStart, nextIDX); - } else { - // Remove allocated alignments and start new row - alignments = alignments.filter(a => !allocated.has(a)); - startNewRow(); - } - } - //console.log(`Done in ${Date.now() - t0} ms`) - return packedAlignmentRows - } -} - - -/** - * Return 0 <= i <= array.length such that !pred(array[i - 1]) && pred(array[i]). - * - * returns an index 0 ≤ i ≤ array.length such that the given predicate is false for array[i - 1] and true for array[i]* * - */ -function binarySearch$1(array, pred, min) { - let lo = min - 1, hi = array.length; - while (1 + lo < hi) { - const mi = lo + ((hi - lo) >> 1); - if (pred(array[mi])) { - hi = mi; - } else { - lo = mi; - } - } - return hi -} - -/* - * The MIT License (MIT) - * - * Copyright (c) 2016 University of California San Diego - * Author: Jim Robinson - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - -class AlignmentContainer { - - // this.config.samplingWindowSize, this.config.samplingDepth, - // this.config.pairsSupported, this.config.alleleFreqThreshold) - constructor(chr, start, end, {samplingWindowSize, samplingDepth, pairsSupported, alleleFreqThreshold}) { - - this.chr = chr; - this.start = Math.floor(start); - this.end = Math.ceil(end); - this.length = (end - start); - - this.alleleFreqThreshold = alleleFreqThreshold === undefined ? 0.2 : alleleFreqThreshold; - - this.coverageMap = new CoverageMap(chr, start, end, this.alleleFreqThreshold); - this.alignments = []; - this.downsampledIntervals = []; - - this.samplingWindowSize = samplingWindowSize === undefined ? 100 : samplingWindowSize; - this.samplingDepth = samplingDepth === undefined ? 1000 : samplingDepth; - - this.pairsSupported = pairsSupported === undefined ? true : pairsSupported; - this.paired = false; // false until proven otherwise - this.pairsCache = {}; // working cache of paired alignments by read name - - this.downsampledReads = new Set(); - - this.currentBucket = new DownsampleBucket(this.start, this.start + this.samplingWindowSize, this); - - this.filter = function filter(alignment) { // TODO -- pass this in - return alignment.isMapped() && !alignment.isFailsVendorQualityCheck() - }; - - } - - push(alignment) { - - if (this.filter(alignment) === false) return - - this.coverageMap.incCounts(alignment); // Count coverage before any downsampling - - if (this.pairsSupported && this.downsampledReads.has(alignment.readName)) { - return // Mate already downsampled -- pairs are treated as a single alignment for downsampling - } - - if (alignment.start >= this.currentBucket.end) { - this.finishBucket(); - this.currentBucket = new DownsampleBucket(alignment.start, alignment.start + this.samplingWindowSize, this); - } - - this.currentBucket.addAlignment(alignment); - - } - - forEach(callback) { - this.alignments.forEach(callback); - } - - finish() { - - if (this.currentBucket !== undefined) { - this.finishBucket(); - } - - this.alignments.sort(function (a, b) { - return a.start - b.start - }); - - this.pairsCache = undefined; - this.downsampledReads = undefined; - } - - contains(chr, start, end) { - return this.chr === chr && - this.start <= start && - this.end >= end - } - - hasDownsampledIntervals() { - return this.downsampledIntervals && this.downsampledIntervals.length > 0 - } - - finishBucket() { - this.alignments = this.alignments.concat(this.currentBucket.alignments); - if (this.currentBucket.downsampledCount > 0) { - this.downsampledIntervals.push(new DownsampledInterval( - this.currentBucket.start, - this.currentBucket.end, - this.currentBucket.downsampledCount)); - } - this.paired = this.paired || this.currentBucket.paired; - } - - setViewAsPairs(bool) { - let alignments; - if (bool) { - alignments = pairAlignments(this.packedAlignmentRows); - } else { - alignments = unpairAlignments(this.packedAlignmentRows); - } - this.packedAlignmentRows = packAlignmentRows(alignments, this.start, this.end); - } - - setShowSoftClips(bool) { - const alignments = this.allAlignments(); - this.packedAlignmentRows = packAlignmentRows(alignments, this.start, this.end, bool); - } - - repack(bpPerPixel, showSoftClips) { - const alignments = this.allAlignments(); - this.packedAlignmentRows = packAlignmentRows(alignments, this.start, this.end, showSoftClips); - - } - - allAlignments() { - const alignments = []; - for (let row of this.packedAlignmentRows) { - for (let alignment of row.alignments) { - alignments.push(alignment); - } - } - return alignments - } - - getMax(start, end) { - return this.coverageMap.getMax(start, end) - } - - sortRows(options) { - - const newRows = []; - const undefinedRow = []; - for (let row of this.packedAlignmentRows) { - const alignment = row.findAlignment(options.position); - if (undefined !== alignment) { - newRows.push(row); - } else { - undefinedRow.push(row); - } - } - - newRows.sort((rowA, rowB) => { - const direction = options.direction; - const rowAValue = rowA.getSortValue(options, this); - const rowBValue = rowB.getSortValue(options, this); - - if (rowBValue === undefined && rowBValue !== undefined) return 1 - else if (rowAValue !== undefined && rowBValue === undefined) return -1 - - const i = rowAValue > rowBValue ? 1 : (rowAValue < rowBValue ? -1 : 0); - return true === direction ? i : -i - }); - - for (let row of undefinedRow) { - newRows.push(row); - } - - this.packedAlignmentRows = newRows; - } - -} - - -class DownsampleBucket { - - constructor(start, end, alignmentContainer) { - - this.start = start; - this.end = end; - this.alignments = []; - this.downsampledCount = 0; - this.samplingDepth = alignmentContainer.samplingDepth; - this.pairsSupported = alignmentContainer.pairsSupported; - this.downsampledReads = alignmentContainer.downsampledReads; - this.pairsCache = alignmentContainer.pairsCache; - } - - addAlignment(alignment) { - - var idx, replacedAlignment, pairedAlignment; - - if (this.pairsSupported && canBePaired(alignment)) { - pairedAlignment = this.pairsCache[alignment.readName]; - if (pairedAlignment) { - // Not subject to downsampling, just update the existing alignment - pairedAlignment.setSecondAlignment(alignment); - this.pairsCache[alignment.readName] = undefined; // Don't need to track this anymore. NOTE: Don't "delete", causes runtime performance issues - return - } - } - - if (this.alignments.length < this.samplingDepth) { - - if (this.pairsSupported && canBePaired(alignment)) { - - // First alignment in a pair - pairedAlignment = new PairedAlignment(alignment); - this.paired = true; - this.pairsCache[alignment.readName] = pairedAlignment; - this.alignments.push(pairedAlignment); - - } else { - this.alignments.push(alignment); - } - - } else { - - idx = Math.floor(Math.random() * (this.samplingDepth + this.downsampledCount - 1)); - - if (idx < this.samplingDepth) { - - // Keep the new item - // idx = Math.floor(Math.random() * (this.alignments.length - 1)); - replacedAlignment = this.alignments[idx]; // To be replaced - - if (this.pairsSupported && canBePaired(alignment)) { - - if (this.pairsCache[replacedAlignment.readName] !== undefined) { - this.pairsCache[replacedAlignment.readName] = undefined; - } - - pairedAlignment = new PairedAlignment(alignment); - this.paired = true; - this.pairsCache[alignment.readName] = pairedAlignment; - this.alignments[idx] = pairedAlignment; - - } else { - this.alignments[idx] = alignment; - } - this.downsampledReads.add(replacedAlignment.readName); - - } else { - this.downsampledReads.add(alignment.readName); - } - - this.downsampledCount++; - } - - - } -} - -class CoverageMap { - - constructor(chr, start, end, alleleFreqThreshold) { - - this.chr = chr; - this.bpStart = start; - this.length = (end - start); - - this.coverage = new Array(this.length); - this.maximum = 0; - - this.threshold = alleleFreqThreshold; - this.qualityWeight = true; - } - - /** - * Return the maximum coverage value between start and end. This is used for autoscaling. - * @param start - * @param end - */ - getMax(start, end) { - let max = 0; - const len = this.coverage.length; - for (let i = 0; i < len; i++) { - const pos = this.bpStart + i; - if (pos > end) break - const cov = this.coverage[i]; - if (pos >= start && cov) { - max = Math.max(max, cov.total); - } - } - return max - } - - incCounts(alignment) { - - var self = this; - - if (alignment.blocks === undefined) { - incBlockCount(alignment); - } else { - alignment.blocks.forEach(function (block) { - incBlockCount(block); - }); - } - - if (alignment.gaps) { - for (let del of alignment.gaps) { - if (del.type === 'D') { - const offset = del.start - self.bpStart; - for (let i = offset; i < offset + del.len; i++) { - if (i < 0) continue - if (!this.coverage[i]) { - this.coverage[i] = new Coverage(self.threshold); - } - this.coverage[i].del++; - } - } - } - } - - if (alignment.insertions) { - for (let del of alignment.insertions) { - const i = del.start - this.bpStart; - if (i < 0) continue - if (!this.coverage[i]) { - this.coverage[i] = new Coverage(self.threshold); - } - this.coverage[i].ins++; - } - } - - function incBlockCount(block) { - - if ('S' === block.type) return - - const seq = alignment.seq; - const qual = alignment.qual; - const seqOffset = block.seqOffset; - - for (let i = block.start - self.bpStart, j = 0; j < block.len; i++, j++) { - - if (!self.coverage[i]) { - self.coverage[i] = new Coverage(self.threshold); - } - - const base = (seq == undefined) ? "N" : seq.charAt(seqOffset + j); - const key = (alignment.strand) ? "pos" + base : "neg" + base; - const q = qual && seqOffset + j < qual.length ? qual[seqOffset + j] : 30; - - self.coverage[i][key] += 1; - self.coverage[i]["qual" + base] += q; - - self.coverage[i].total += 1; - self.coverage[i].qual += q; - - self.maximum = Math.max(self.coverage[i].total, self.maximum); - - } - } - } -} - - -class Coverage { - - constructor(alleleThreshold) { - - this.qualityWeight = true; - - this.posA = 0; - this.negA = 0; - - this.posT = 0; - this.negT = 0; - - this.posC = 0; - this.negC = 0; - this.posG = 0; - - this.negG = 0; - - this.posN = 0; - this.negN = 0; - - this.pos = 0; - this.neg = 0; - - this.qualA = 0; - this.qualT = 0; - this.qualC = 0; - this.qualG = 0; - this.qualN = 0; - - this.qual = 0; - - this.total = 0; - this.del = 0; - this.ins = 0; - - this.threshold = alleleThreshold; - } - - hoverText() { - const pos = this.posA + this.posT + this.posC + this.posG + this.posN; - const neg = this.negA + this.negT + this.negC + this.negG + this.negN; - return `${this.total} (${pos}+, ${neg}-)` - } - - isMismatch(refBase) { - const threshold = this.threshold * ((this.qualityWeight && this.qual) ? this.qual : this.total); - let mismatchQualitySum = 0; - for (let base of ["A", "T", "C", "G"]) { - if (base !== refBase) { - mismatchQualitySum += ((this.qualityWeight && this.qual) ? this["qual" + base] : (this["pos" + base] + this["neg" + base])); - } - } - return mismatchQualitySum >= threshold - } -} - -class DownsampledInterval { - - constructor(start, end, counts) { - this.start = start; - this.end = end; - this.counts = counts; - } - - popupData(genomicLocation) { - return [ - {name: "start", value: this.start + 1}, - {name: "end", value: this.end}, - {name: "# downsampled:", value: this.counts}] - } -} - -class SupplementaryAlignment { - - constructor(rec) { - const tokens = rec.split(','); - this.chr = tokens[0]; - this.start = parseInt(tokens[1]); - this.strand = tokens[2].charAt(0); - this.mapQ = parseInt(tokens[4]); - this.numMismatches = parseInt(tokens[5]); - this.lenOnRef = BamUtils.computeLengthOnReference(tokens[3]); - } - - printString() { - return this.chr + ":" + numberFormatter$1(this.start) + "-" + numberFormatter$1(this.start + this.lenOnRef) - + " (" + this.strand + ") = " + numberFormatter$1(this.lenOnRef) + "bp @MAPQ: " + this.mapQ + " NM: " + this.numMismatches - } -} - -function createSupplementaryAlignments(str) { - const tokens = str.split(';'); - return tokens.filter(t => t.length > 0).map(str => new SupplementaryAlignment(str)) -} - -/* - * The MIT License (MIT) - * - * Copyright (c) 2014 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -const READ_PAIRED_FLAG = 0x1; -const PROPER_PAIR_FLAG = 0x2; -const READ_UNMAPPED_FLAG = 0x4; -const MATE_UNMAPPED_FLAG = 0x8; -const READ_STRAND_FLAG$2 = 0x10; -const MATE_STRAND_FLAG$2 = 0x20; -const FIRST_OF_PAIR_FLAG = 0x40; -const SECOND_OF_PAIR_FLAG = 0x80; -const SECONDARY_ALIGNMNET_FLAG = 0x100; -const READ_FAILS_VENDOR_QUALITY_CHECK_FLAG = 0x200; -const DUPLICATE_READ_FLAG = 0x400; -const SUPPLEMENTARY_ALIGNMENT_FLAG = 0x800; -const ELEMENT_SIZE = { - c: 1, - C: 1, - s: 2, - S: 2, - i: 4, - I: 4, - f: 4 -}; - -const MAX_CIGAR = 50; - -/** - * readName - * chr - * cigar - * lengthOnRef - * start - * seq - * qual - * mq - * strand - * blocks - */ - -class BamAlignment { - - constructor() { - this.hidden = false; - } - - isMapped() { - return (this.flags & READ_UNMAPPED_FLAG) === 0 - } - - isPaired() { - return (this.flags & READ_PAIRED_FLAG) !== 0 - } - - isProperPair() { - return (this.flags & PROPER_PAIR_FLAG) !== 0 - } - - isFirstOfPair() { - return (this.flags & FIRST_OF_PAIR_FLAG) !== 0 - } - - isSecondOfPair() { - return (this.flags & SECOND_OF_PAIR_FLAG) !== 0 - } - - isSecondary() { - return (this.flags & SECONDARY_ALIGNMNET_FLAG) !== 0 - } - - isSupplementary() { - return (this.flags & SUPPLEMENTARY_ALIGNMENT_FLAG) !== 0 - } - - isFailsVendorQualityCheck() { - return (this.flags & READ_FAILS_VENDOR_QUALITY_CHECK_FLAG) !== 0 - } - - isDuplicate() { - return (this.flags & DUPLICATE_READ_FLAG) !== 0 - } - - isMateMapped() { - return (this.flags & MATE_UNMAPPED_FLAG) === 0 - } - - isNegativeStrand() { - return (this.flags & READ_STRAND_FLAG$2) !== 0 - } - - isMateNegativeStrand() { - return (this.flags & MATE_STRAND_FLAG$2) !== 0 - } - - hasTag(tag) { - const tmpTags = this.tagDict || decodeTags(this.tagBA); - return tmpTags.hasOwnProperty(tag) - } - - tags() { - if (!this.tagDict) { - if (this.tagBA) { - this.tagDict = decodeTags(this.tagBA); - this.tagBA = undefined; - } else { - this.tagDict = {}; // Mark so we don't try again. The record has no tags - } - } - return this.tagDict - } - - /** - * Does alignment (or alignment extended by soft clips) contain the genomic location? - * - * @param genomicLocation - * @param showSoftClips - * @returns {boolean|boolean} - */ - containsLocation(genomicLocation, showSoftClips) { - const s = showSoftClips ? this.scStart : this.start; - const l = showSoftClips ? this.scLengthOnRef : this.lengthOnRef; - return (genomicLocation >= s && genomicLocation <= (s + l)) - } - - popupData(genomicLocation) { - - // if the user clicks on a base next to an insertion, show just the - // inserted bases in a popup (like in desktop IGV). - const nameValues = []; - - // Consert genomic location to int - genomicLocation = Math.floor(genomicLocation); - - if (this.insertions) { - - const seq = this.seq; - - for (let insertion of this.insertions) { - var ins_start = insertion.start; - if (genomicLocation === ins_start || genomicLocation === ins_start - 1) { - nameValues.push({name: 'Insertion', value: seq.substr(insertion.seqOffset, insertion.len)}); - nameValues.push({name: 'Location', value: ins_start}); - return nameValues - } - } - } - - nameValues.push({name: 'Read Name', value: this.readName}); - - // Sample - // Read group - nameValues.push('
'); - - // Add 1 to genomic location to map from 0-based computer units to user-based units - nameValues.push({name: 'Alignment Start', value: numberFormatter$1(1 + this.start), borderTop: true}); - nameValues.push({name: 'Read Strand', value: (true === this.strand ? '(+)' : '(-)'), borderTop: true}); - - // Abbreviate long cigar strings, keeping the beginning and end to show cliping - let cigar = this.cigar; - if (cigar && cigar.length > MAX_CIGAR) { - const half = MAX_CIGAR / 2; - cigar = `${cigar.substring(0, half - 2)} ... ${cigar.substring(cigar.length - half + 2)}`; - } - nameValues.push({name: 'Cigar', value: cigar}); - - nameValues.push({name: 'Mapping Quality', value: this.mq}); - nameValues.push({name: 'Secondary', value: yesNo(this.isSecondary())}); - nameValues.push({name: 'Supplementary', value: yesNo(this.isSupplementary())}); - nameValues.push({name: 'Duplicate', value: yesNo(this.isDuplicate())}); - nameValues.push({name: 'Failed QC', value: yesNo(this.isFailsVendorQualityCheck())}); - - if (this.isPaired()) { - nameValues.push('
'); - nameValues.push({name: 'First in Pair', value: !this.isSecondOfPair(), borderTop: true}); - nameValues.push({name: 'Mate is Mapped', value: yesNo(this.isMateMapped())}); - if (this.pairOrientation) { - nameValues.push({name: 'Pair Orientation', value: this.pairOrientation}); - } - if (this.isMateMapped()) { - nameValues.push({name: 'Mate Chromosome', value: this.mate.chr}); - nameValues.push({name: 'Mate Start', value: (this.mate.position + 1)}); - nameValues.push({name: 'Mate Strand', value: (true === this.mate.strand ? '(+)' : '(-)')}); - nameValues.push({name: 'Insert Size', value: this.fragmentLength}); - // Mate Start - // Mate Strand - // Insert Size - } - // First in Pair - // Pair Orientation - - } - - const tagDict = this.tags(); - - if (tagDict.hasOwnProperty('SA')) { - nameValues.push('
'); - nameValues.push({name: 'Supplementary Alignments', value: ''}); - const sa = createSupplementaryAlignments(tagDict['SA']); - if (sa) { - nameValues.push('
    '); - for (let s of sa) { - nameValues.push(`
  • ${s.printString()}
  • `); - } - nameValues.push('
'); - } - } - - const hiddenTags = new Set(['SA', 'MD']); - nameValues.push('
'); - for (let key in tagDict) { - if (!hiddenTags.has(key)) { - nameValues.push({name: key, value: tagDict[key]}); - } - } - - nameValues.push({name: 'Hidden Tags', value: 'SA, MD'}); - - nameValues.push('
'); - nameValues.push({name: 'Genomic Location: ', value: numberFormatter$1(1 + genomicLocation)}); - nameValues.push({name: 'Read Base:', value: this.readBaseAt(genomicLocation)}); - nameValues.push({name: 'Base Quality:', value: this.readBaseQualityAt(genomicLocation)}); - - return nameValues - - - function yesNo(bool) { - return bool ? 'Yes' : 'No' - } - } - - readBaseAt(genomicLocation) { - - const block = blockAtGenomicLocation(this.blocks, genomicLocation); - if (block) { - if ("*" === this.seq) { - return "*" - } else { - const idx = block.seqIndexAt(genomicLocation); - // if (idx >= 0 && idx < this.seq.length) { - return this.seq[idx] - // } - } - } else { - return undefined - } - } - - readBaseQualityAt(genomicLocation) { - - const block = blockAtGenomicLocation(this.blocks, genomicLocation); - if (block) { - if ("*" === this.qual) { - return 30 - } else { - const idx = block.seqIndexAt(genomicLocation); - if (idx >= 0 && this.qual && idx < this.qual.length) { - return this.qual[idx] - } else { - return 30 - } - } - } else { - return undefined - } - } - - gapSizeAt(genomicLocation) { - if (this.gaps) { - for (let gap of this.gaps) { - if (genomicLocation >= gap.start && genomicLocation < gap.start + gap.len) { - return gap.len - } - } - } - return 0 - } - - /** - * Return soft clipped blocks, if they exist, keyed by alignment end (left or right) - */ - softClippedBlocks() { - let left; - let right; - let interiorSeen; - for(let b of this.blocks) { - if('S' === b.type) { - if(interiorSeen) { - right = b; - } else { - left = b; - } - } else if('H' !== b.type) { - interiorSeen = true; - } - } - return {left, right} - } - -} - -function blockAtGenomicLocation(blocks, genomicLocation) { - - for (let i = 0; i < blocks.length; i++) { - const block = blocks[i]; - if (genomicLocation >= block.start && genomicLocation < block.start + block.len) { - return block - } - } - return undefined -} - -function decodeTags(ba) { - - let p = 0; - const len = ba.length; - const tags = {}; - - while (p < len) { - const tag = String.fromCharCode(ba[p]) + String.fromCharCode(ba[p + 1]); - p += 2; - - const type = String.fromCharCode(ba[p++]); - let value; - if (type === 'A') { - value = String.fromCharCode(ba[p]); - p++; - } else if (type === 'i' || type === 'I') { - value = readInt$1(ba, p); - p += 4; - } else if (type === 'c') { - value = readInt8(ba, p); - p++; - } else if (type === 'C') { - value = readUInt8(ba, p); - p++; - } else if (type === 's' || type === 'S') { - value = readShort(ba, p); - p += 2; - } else if (type === 'f') { - value = readFloat(ba, p); - p += 4; - } else if (type === 'Z') { - value = ''; - for (; ;) { - var cc = ba[p++]; - if (cc === 0) { - break - } else { - value += String.fromCharCode(cc); - } - } - } else if (type === 'B') { - const elementType = String.fromCharCode(ba[p++]); - let elementSize = ELEMENT_SIZE[elementType]; - if (elementSize === undefined) { - tags[tag] = `Error: unknown element type '${elementType}'`; - break - } - const numElements = readInt$1(ba, p); - p += (4 + numElements * elementSize); - value = '[not shown]'; - } else { - //'Unknown type ' + type; - value = 'Error unknown type: ' + type; - tags[tag] = value; - break - } - tags[tag] = value; - } - return tags -} - - -function readInt$1(ba, offset) { - return (ba[offset + 3] << 24) | (ba[offset + 2] << 16) | (ba[offset + 1] << 8) | (ba[offset]) -} - -function readShort(ba, offset) { - return (ba[offset + 1] << 8) | (ba[offset]) -} - -function readFloat(ba, offset) { - const dataView = new DataView(ba.buffer); - return dataView.getFloat32(offset) -} - -function readInt8(ba, offset) { - const dataView = new DataView(ba.buffer); - return dataView.getInt8(offset) -} - -function readUInt8(ba, offset) { - const dataView = new DataView(ba.buffer); - return dataView.getUint8(offset) -} - -/* - * The MIT License (MIT) - * - * Copyright (c) 2016-2017 The Regents of the University of California - * Author: Jim Robinson - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -/** - * Created by jrobinso on 4/5/18. - */ - - -class AlignmentBlock { - constructor(b) { - if (b) { - Object.assign(this, b); - } - } - - seqIndexAt(genomicLocation) { - return Math.floor(genomicLocation) - this.start + this.seqOffset - } -} - -class BamFilter { - constructor(options) { - if (!options) options = {}; - this.vendorFailed = options.vendorFailed === undefined ? true : options.vendorFailed; - this.duplicates = options.duplicates === undefined ? true : options.duplicates; - this.secondary = options.secondary || false; - this.supplementary = options.supplementary || false; - this.mqThreshold = options.mqThreshold === undefined ? 0 : options.mqThreshold; - if (options.readgroups) { - this.readgroups = new Set(options.readgroups); - } - } - - pass(alignment) { - if (this.vendorFailed && alignment.isFailsVendorQualityCheck()) return false - if (this.duplicates && alignment.isDuplicate()) return false - if (this.secondary && alignment.isSecondary()) return false - if (this.supplementary && alignment.isSupplementary()) return false - if (alignment.mq < this.mqThreshold) return false - if (this.readgroups) { - var rg = alignment.tags()['RG']; - return this.readgroups.has(rg) - } - return true - } -} - -/* - * The MIT License (MIT) - * - * Copyright (c) 2016-2017 The Regents of the University of California - * Author: Jim Robinson - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - -/** - * This code is based on the Biodalliance BAM reader by Thomas Down, 2011 - * - * https://github.com/dasmoth/dalliance/blob/master/js/bam.js - */ - -const SEQ_DECODER = ['=', 'A', 'C', 'x', 'G', 'x', 'x', 'x', 'T', 'x', 'x', 'x', 'x', 'x', 'x', 'N']; -const CIGAR_DECODER = ['M', 'I', 'D', 'N', 'S', 'H', 'P', '=', 'X', '?', '?', '?', '?', '?', '?', '?']; -const READ_STRAND_FLAG$1 = 0x10; -const MATE_STRAND_FLAG$1 = 0x20; - -const BAM1_MAGIC_BYTES = new Uint8Array([0x42, 0x41, 0x4d, 0x01]); // BAM\1 -const BAM1_MAGIC_NUMBER = readInt(BAM1_MAGIC_BYTES, 0); - -const DEFAULT_ALLELE_FREQ_THRESHOLD = 0.2; -const DEFAULT_SAMPLING_WINDOW_SIZE = 100; -const DEFAULT_SAMPLING_DEPTH = 500; -const MAXIMUM_SAMPLING_DEPTH = 10000; - -const BamUtils = { - - readHeader: function (url, options, genome) { - - return igvxhr.loadArrayBuffer(url, options) - - .then(function (compressedBuffer) { - - var header, unc, uncba; - - unc = unbgzf(compressedBuffer); - uncba = unc; - - header = BamUtils.decodeBamHeader(uncba, genome); - - return header - - }) - - }, - - /** - * - * @param ba bytes to decode as a UInt8Array - * @param genome optional igv genome object - * @returns {{ magicNumer: number, size: number, chrNames: Array, chrToIndex: ({}|*), chrAliasTable: ({}|*) }} - */ - decodeBamHeader: function (ba, genome) { - - var magic, samHeaderLen, samHeader, chrToIndex, chrNames, chrAliasTable, alias; - - magic = readInt(ba, 0); - if (magic !== BAM1_MAGIC_NUMBER) { - throw new Error('BAM header errror: bad magic number. This could be caused by either a corrupt or missing file.') - } - - samHeaderLen = readInt(ba, 4); - samHeader = ''; - - for (var i = 0; i < samHeaderLen; ++i) { - samHeader += String.fromCharCode(ba[i + 8]); - } - - var nRef = readInt(ba, samHeaderLen + 8); - var p = samHeaderLen + 12; - - chrToIndex = {}; - chrNames = []; - chrAliasTable = {}; - - for (i = 0; i < nRef; ++i) { - var lName = readInt(ba, p); - var name = ''; - for (var j = 0; j < lName - 1; ++j) { - name += String.fromCharCode(ba[p + 4 + j]); - } - readInt(ba, p + lName + 4); - //dlog(name + ': ' + lRef); - - chrToIndex[name] = i; - chrNames[i] = name; - - if (genome) { - alias = genome.getChromosomeName(name); - chrAliasTable[alias] = name; - } - - p = p + 8 + lName; - } - - return { - magicNumber: magic, - size: p, - chrNames: chrNames, - chrToIndex: chrToIndex, - chrAliasTable: chrAliasTable - } - - }, - - bam_tag2cigar: function (ba, block_end, seq_offset, lseq, al, cigarArray) { - - function type2size(x) { - if (x === 'C' || x === 'c' || x === 'A') return 1 - else if (x === 'S' || x === 's') return 2 - else if (x === 'I' || x === 'i' || x === 'f') return 4 - else return 0 - } - - // test if the real CIGAR is encoded in a CG:B,I tag - if (cigarArray.length !== 1 || al.start < 0) return false - var p = seq_offset + ((lseq + 1) >> 1) + lseq; - while (p + 4 < block_end) { - var tag = String.fromCharCode(ba[p]) + String.fromCharCode(ba[p + 1]); - if (tag === 'CG') break - var type = String.fromCharCode(ba[p + 2]); - if (type === 'B') { // the binary array type - type = String.fromCharCode(ba[p + 3]); - var size = type2size(type); - var len = readInt(ba, p + 4); - p += 8 + size * len; - } else if (type === 'Z' || type === 'H') { // 0-terminated string - p += 3; - while (ba[p++] !== 0) { - } - } else { // other atomic types - p += 3 + type2size(type); - } - } - if (p >= block_end) return false // no CG tag - if (String.fromCharCode(ba[p + 2]) !== 'B' || String.fromCharCode(ba[p + 3]) !== 'I') return false // not of type B,I - - // now we know the real CIGAR length and its offset in the binary array - var cigar_len = readInt(ba, p + 4); - var cigar_offset = p + 8; // 4 for "CGBI" and 4 for length - if (cigar_offset + cigar_len * 4 > block_end) return false // out of bound - - // decode CIGAR - var cigar = ''; - var lengthOnRef = 0; - cigarArray.length = 0; // empty the old array - p = cigar_offset; - for (var k = 0; k < cigar_len; ++k, p += 4) { - var cigop = readInt(ba, p); - var opLen = (cigop >> 4); - var opLtr = CIGAR_DECODER[cigop & 0xf]; - if (opLtr === 'M' || opLtr === 'EQ' || opLtr === 'X' || opLtr === 'D' || opLtr === 'N' || opLtr === '=') - lengthOnRef += opLen; - cigar = cigar + opLen + opLtr; - cigarArray.push({len: opLen, ltr: opLtr}); - } - - // update alignment record. We are not updating bin, as apparently it is not used. - al.cigar = cigar; - al.lengthOnRef = lengthOnRef; - return true - }, - - /** - * - * @param ba bytes to decode as an UInt8Array - * @param offset offset position of ba array to start decoding - * @param alignmentContainer container to receive the decoded alignments - * @param min minimum genomic position - * @param max maximum genomic position - * @param chrIdx chromosome index - * @param chrNames array of chromosome names - * @param filter a BamFilter object - * - * @return true if we have moved beyond the right end of the genomic range. - */ - decodeBamRecords: function (ba, offset, alignmentContainer, chrNames, chrIdx, min, max, filter) { - - while (offset < ba.length) { - - const blockSize = readInt(ba, offset); - const blockEnd = offset + blockSize + 4; - const alignment = new BamAlignment(); - const refID = readInt(ba, offset + 4); - const pos = readInt(ba, offset + 8); - - if (blockEnd > ba.length) { - return - } - if (refID < 0) { - offset = blockEnd; - continue // unmapped read - } else if (chrIdx !== undefined && (refID > chrIdx || pos > max)) { - return true // off right edge, we're done - } else if (chrIdx !== undefined && (refID < chrIdx)) { - offset = blockEnd; - continue // ref ID to left of start, not sure this is possible - } - - const bin_mq_nl = readInt(ba, offset + 12); - const mq = (bin_mq_nl & 0xff00) >> 8; - const nl = bin_mq_nl & 0xff; - - const flag_nc = readInt(ba, offset + 16); - const flag = (flag_nc & 0xffff0000) >> 16; - const nc = flag_nc & 0xffff; - - const lseq = readInt(ba, offset + 20); - const mateChrIdx = readInt(ba, offset + 24); - const matePos = readInt(ba, offset + 28); - const fragmentLength = readInt(ba, offset + 32); - - let readName = []; - for (let j = 0; j < nl - 1; ++j) { - readName.push(String.fromCharCode(ba[offset + 36 + j])); - } - readName = readName.join(''); - - let lengthOnRef = 0; - let cigar = ''; - let p = offset + 36 + nl; - const cigarArray = []; - // concatenate M,=,EQ,and X - - let lastCigRecord; - for (let c = 0; c < nc; ++c) { - var cigop = readInt(ba, p); - var opLen = (cigop >> 4); - var opLtr = CIGAR_DECODER[cigop & 0xf]; - if (opLtr === 'M' || opLtr === 'EQ' || opLtr === 'X' || opLtr === 'D' || opLtr === 'N' || opLtr === '=') - lengthOnRef += opLen; - cigar = cigar + opLen + opLtr; - p += 4; - - // if(mOperators.has(opLtr) && mOperators.has(lastCigRecord.ltr)) { - // lastCigRecord.len += opLen; - // lastCigRecord.ltr = 'M' - // } - // else { - lastCigRecord = {len: opLen, ltr: opLtr}; - cigarArray.push(lastCigRecord); - //} - } - - alignment.chr = chrNames[refID]; - alignment.start = pos; - alignment.flags = flag; - alignment.strand = !(flag & READ_STRAND_FLAG$1); - alignment.readName = readName; - alignment.cigar = cigar; - alignment.lengthOnRef = lengthOnRef; - alignment.fragmentLength = fragmentLength; - alignment.mq = mq; - - BamUtils.bam_tag2cigar(ba, blockEnd, p, lseq, alignment, cigarArray); - - alignment.end = alignment.start + alignment.lengthOnRef; - - if (alignment.end < min) { - offset = blockEnd; - continue - } // Record out-of-range "to the left", skip to next one - - - let seq = []; - const seqBytes = (lseq + 1) >> 1; - for (let j = 0; j < seqBytes; ++j) { - var sb = ba[p + j]; - seq.push(SEQ_DECODER[(sb & 0xf0) >> 4]); - seq.push(SEQ_DECODER[(sb & 0x0f)]); - } - seq = seq.slice(0, lseq).join(''); // seq might have one extra character (if lseq is an odd number) - p += seqBytes; - - - const qualArray = []; - for (let j = 0; j < lseq; ++j) { - qualArray.push(ba[p + j]); - } - p += lseq; - - if (mateChrIdx >= 0) { - alignment.mate = { - chr: chrNames[mateChrIdx], - position: matePos, - strand: !(flag & MATE_STRAND_FLAG$1) - }; - } - - alignment.seq = seq; - alignment.qual = qualArray; - alignment.tagBA = new Uint8Array(ba.buffer.slice(p, blockEnd)); // decode these on demand - - this.setPairOrientation(alignment); - - if ((undefined === filter || filter.pass(alignment))) { - makeBlocks(alignment, cigarArray); - alignmentContainer.push(alignment); - } - offset = blockEnd; - } - }, - - decodeSamRecords: function (sam, alignmentContainer, chr, min, max, filter) { - - var lines, i, j, len, tokens, qualString, rnext, lengthOnRef, - alignment, cigarArray, started; - - lines = splitLines$5(sam); - len = lines.length; - started = false; - - for (i = 0; i < len; i++) { - - tokens = lines[i].split('\t'); - - alignment = new BamAlignment(); - - alignment.chr = tokens[2]; - alignment.start = Number.parseInt(tokens[3]) - 1; - alignment.flags = Number.parseInt(tokens[1]); - alignment.readName = tokens[0]; - alignment.strand = !(alignment.flags & READ_STRAND_FLAG$1); - alignment.mq = Number.parseInt(tokens[4]); - alignment.cigar = tokens[5]; - alignment.fragmentLength = Number.parseInt(tokens[8]); - alignment.seq = tokens[9]; - - if (alignment.chr === '*' || !alignment.isMapped()) continue // Unmapped - - if (alignment.chr !== chr) { - if (started) break // Off the right edge, we're done - else continue // Possibly to the left, skip but keep looping - } else if (alignment.start > max) { - break // off right edge, we're done - } - - lengthOnRef = 0; - cigarArray = buildOperators(alignment.cigar); - cigarArray.forEach(function (op) { - var opLen = op.len; - var opLtr = op.ltr; - if (opLtr === 'M' || opLtr === 'EQ' || opLtr === 'X' || opLtr === 'D' || opLtr === 'N' || opLtr === '=') - lengthOnRef += opLen; - }); - alignment.lengthOnRef = lengthOnRef; - // TODO for lh3: parse the CG:B,I tag in SAM here - - if (alignment.start + lengthOnRef < min) { - continue // To the left, skip and continue - } - - - qualString = tokens[10]; - alignment.qual = []; - for (j = 0; j < qualString.length; j++) { - alignment.qual[j] = qualString.charCodeAt(j) - 33; - } - alignment.tagDict = tokens.length < 11 ? {} : decodeSamTags(tokens.slice(11)); - - if (alignment.isMateMapped()) { - rnext = tokens[6]; - alignment.mate = { - chr: (rnext === '=') ? alignment.chr : rnext, - position: Number.parseInt(tokens[7]), - strand: !(alignment.flags & MATE_STRAND_FLAG$1) - }; - } - - this.setPairOrientation(alignment); - - if (undefined === filter || filter.pass(alignment)) { - makeBlocks(alignment, cigarArray); - alignmentContainer.push(alignment); - } - } - }, - - setReaderDefaults: function (reader, config) { - - reader.filter = new BamFilter(config.filter); - - if (config.readgroup) { - reader.filter.readgroups = new Set([config.readgroup]); - } - - reader.alleleFreqThreshold = config.alleleFreqThreshold === undefined ? DEFAULT_ALLELE_FREQ_THRESHOLD : config.alleleFreqThreshold; - - reader.samplingWindowSize = config.samplingWindowSize === undefined ? DEFAULT_SAMPLING_WINDOW_SIZE : config.samplingWindowSize; - reader.samplingDepth = config.samplingDepth === undefined ? DEFAULT_SAMPLING_DEPTH : config.samplingDepth; - - if (reader.samplingDepth > MAXIMUM_SAMPLING_DEPTH) { - console.log("Warning: attempt to set sampling depth > maximum value of " + MAXIMUM_SAMPLING_DEPTH); - reader.samplingDepth = MAXIMUM_SAMPLING_DEPTH; - } - - if (config.viewAsPairs) { - reader.pairsSupported = true; - } else { - reader.pairsSupported = config.pairsSupported === undefined ? true : config.pairsSupported; - } - }, - - setPairOrientation: function (alignment) { - - if (alignment.isMapped() && alignment.mate && alignment.isMateMapped() && alignment.mate.chr === alignment.chr) { - var s1 = alignment.strand ? 'F' : 'R'; - - var mate = alignment.mate; - var s2 = mate.strand ? 'F' : 'R'; - var o1 = ' '; - var o2 = ' '; - if (alignment.isFirstOfPair()) { - o1 = '1'; - o2 = '2'; - } else if (alignment.isSecondOfPair()) { - o1 = '2'; - o2 = '1'; - } - - var tmp = []; - var isize = alignment.fragmentLength; - var estReadLen = alignment.end - alignment.start; - if (isize === 0) { - //isize not recorded. Need to estimate. This calculation was validated against an Illumina - // -> <- library bam. - var estMateEnd = alignment.start < mate.position ? - mate.position + estReadLen : mate.position - estReadLen; - isize = estMateEnd - alignment.start; - } - - //if (isize > estReadLen) { - if (isize > 0) { - tmp[0] = s1; - tmp[1] = o1; - tmp[2] = s2; - tmp[3] = o2; - - } else { - tmp[2] = s1; - tmp[3] = o1; - tmp[0] = s2; - tmp[1] = o2; - } - // } - alignment.pairOrientation = tmp.join(''); - } - }, - - computeLengthOnReference: function (cigarString) { - - let len = 0; - let buf = ''; - - for (let i = 0; i < cigarString.length; i++) { - const c = cigarString.charCodeAt(i); - if (c > 47 && c < 58) { - buf += cigarString.charAt(i); - } else { - switch (c) { - case 78: // N - case 68: // D - case 77: // M - case 61: // = - case 88: // X - len += parseInt(buf.toString()); - } - buf = ''; - } - } - return len - } -}; - - -/** - * Split the alignment record into blocks as specified in the cigarArray. Each aligned block contains - * its portion of the read sequence and base quality strings. A read sequence or base quality string - * of "*" indicates the value is not recorded. In all other cases the length of the block sequence (block.seq) - * and quality string (block.qual) must == the block length. - * - * @param alignment - * @param cigarArray - * @returns array of blocks - */ -function makeBlocks(alignment, cigarArray) { - - const blocks = []; - - let insertions; - let gaps; - let seqOffset = 0; - let pos = alignment.start; - - alignment.scStart = alignment.start; - alignment.scLengthOnRef = alignment.lengthOnRef; - - for (let c of cigarArray) { - - let scPos; - switch (c.ltr) { - case 'H' : - break // ignore hard clips - case 'P' : - break // ignore pads - case 'S' : - - scPos = pos; - alignment.scLengthOnRef += c.len; - if (blocks.length === 0) { - alignment.scStart -= c.len; - scPos -= c.len; - } - blocks.push(new AlignmentBlock({ - start: scPos, - seqOffset: seqOffset, - len: c.len, - type: 'S' - })); - seqOffset += c.len; - break // soft clip read bases - case 'N' : - case 'D': - if (gaps === undefined) { - gaps = []; - } - gaps.push({ - start: pos, - len: c.len, - type: c.ltr - }); - pos += c.len; - break - case 'I' : - - if (insertions === undefined) { - insertions = []; - } - insertions.push(new AlignmentBlock({ - start: pos, - len: c.len, - seqOffset: seqOffset, - type: 'I' - })); - seqOffset += c.len; - break - case 'M' : - case 'EQ' : - case '=' : - case 'X' : - blocks.push(new AlignmentBlock({ - start: pos, - seqOffset: seqOffset, - len: c.len, - type: 'M' - })); - seqOffset += c.len; - pos += c.len; - - break - - default : - console.log('Error processing cigar element: ' + c.len + c.ltr); - } - } - - alignment.blocks = blocks; - alignment.insertions = insertions; - alignment.gaps = gaps; - -} - -function readInt(ba, offset) { - return (ba[offset + 3] << 24) | (ba[offset + 2] << 16) | (ba[offset + 1] << 8) | (ba[offset]) -} - -/** - * Build a list of cigar operators from a cigarString. Removes padding operators and concatenates consecutive - * operators of the same type - * - * @param cigarString - * @return - */ -function buildOperators(cigarString) { - - var operators, buffer, i, len, prevOp, next, op, nBases; - - operators = []; - buffer = []; - - // Create list of cigar operators - prevOp = null; - len = cigarString.length; - for (i = 0; i < len; i++) { - next = cigarString.charAt(i); - if (isDigit(next)) { - buffer.push(next); - } else { - op = next; - nBases = Number.parseInt(buffer.join('')); - buffer = []; - - if (prevOp !== null && prevOp.ltr === op) { - prevOp.len += nBases; - } else { - prevOp = {len: nBases, ltr: op}; - operators.push(prevOp); - } - } - } - return operators - -} - -function isDigit(a) { - var charCode = a.charCodeAt(0); - return (charCode >= 48 && charCode <= 57) // 0-9 -} - -function decodeSamTags(tags) { - - var tagDict = {}; - tags.forEach(function (tag) { - var tokens = tag.split(':'); - tagDict[tokens[0]] = tokens[2]; - }); - - return tagDict -} - -/* - * The MIT License (MIT) - * - * Copyright (c) 2016-2017 The Regents of the University of California - * Author: Jim Robinson - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -/** - * Class for reading a bam file - * - * @param config - * @constructor - */ -class BamReaderNonIndexed { - - constructor(config, genome) { - this.config = config; - this.genome = genome; - this.bamPath = config.url; - this.isDataUri = isDataURL(config.url); - BamUtils.setReaderDefaults(this, config); - } - - // Return an alignment container - async readAlignments(chr, bpStart, bpEnd) { - - if (this.alignmentCache) { - const header = this.header; - const queryChr = header.chrAliasTable.hasOwnProperty(chr) ? header.chrAliasTable[chr] : chr; - const qAlignments = this.alignmentCache.queryFeatures(queryChr, bpStart, bpEnd); - const alignmentContainer = new AlignmentContainer(chr, bpStart, bpEnd, this.config); - for (let a of qAlignments) { - alignmentContainer.push(a); - } - alignmentContainer.finish(); - return alignmentContainer - - } else { - if (this.isDataUri) { - const data = decodeDataURI(this.bamPath); - const unc = unbgzf(data.buffer); - this.parseAlignments(unc); - return this.fetchAlignments(chr, bpStart, bpEnd) - } else { - const arrayBuffer = await igvxhr.loadArrayBuffer(this.bamPath, buildOptions$1(this.config)); - const unc = unbgzf(arrayBuffer); - this.parseAlignments(unc); - return this.fetchAlignments(chr, bpStart, bpEnd) - } - } - - } - - parseAlignments(data) { - const alignments = []; - this.header = BamUtils.decodeBamHeader(data); - BamUtils.decodeBamRecords(data, this.header.size, alignments, this.header.chrNames); - this.alignmentCache = new FeatureCache$1(alignments, this.genome); - } - - fetchAlignments(chr, bpStart, bpEnd) { - const queryChr = this.header.chrAliasTable.hasOwnProperty(chr) ? this.header.chrAliasTable[chr] : chr; - const features = this.alignmentCache.queryFeatures(queryChr, bpStart, bpEnd); - const alignmentContainer = new AlignmentContainer(chr, bpStart, bpEnd, this.config); - for (let feature of features) { - alignmentContainer.push(feature); - } - alignmentContainer.finish(); - return alignmentContainer - } - -} - -function decodeDataURI(dataURI) { - - const split = dataURI.split(','); - const info = split[0].split(':')[1]; - let dataString = split[1]; - - if (info.indexOf('base64') >= 0) { - dataString = atob(dataString); - } else { - dataString = decodeURI(dataString); - } - - const bytes = new Uint8Array(dataString.length); - for (var i = 0; i < dataString.length; i++) { - bytes[i] = dataString.charCodeAt(i); - } - return bytes -} - -/* - * The MIT License (MIT) - * - * Copyright (c) 2016-2017 The Regents of the University of California - * Author: Jim Robinson - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -/** - * Class for reading a bam file - * - * @param config - * @constructor - */ -class BamReader { - - constructor(config, genome) { - this.config = config; - this.genome = genome; - this.bamPath = config.url; - this.baiPath = config.indexURL; - BamUtils.setReaderDefaults(this, config); - - this._blockLoader = new BGZBlockLoader(config); - } - - async readAlignments(chr, bpStart, bpEnd) { - - const chrToIndex = await this.getChrIndex(); - const queryChr = this.chrAliasTable.hasOwnProperty(chr) ? this.chrAliasTable[chr] : chr; - const chrId = chrToIndex[queryChr]; - const alignmentContainer = new AlignmentContainer(chr, bpStart, bpEnd, this.config); - - if (chrId === undefined) { - return alignmentContainer - - } else { - - const bamIndex = await this.getIndex(); - const chunks = bamIndex.chunksForRange(chrId, bpStart, bpEnd); - - if (!chunks || chunks.length === 0) { - return alignmentContainer - } - - for (let c of chunks) { - const ba = await this._blockLoader.getData(c.minv, c.maxv); - const done = BamUtils.decodeBamRecords(ba, c.minv.offset, alignmentContainer, this.indexToChr, chrId, bpStart, bpEnd, this.filter); - if (done) { - break - } - } - alignmentContainer.finish(); - return alignmentContainer - } - } - - async getHeader() { - if (!this.header) { - const genome = this.genome; - const index = await this.getIndex(); - let len; - if (index.firstBlockPosition) { - const bsizeOptions = buildOptions$1(this.config, {range: {start: index.firstBlockPosition, size: 26}}); - const abuffer = await igvxhr.loadArrayBuffer(this.bamPath, bsizeOptions); - const bsize = bgzBlockSize$1(abuffer); - len = index.firstBlockPosition + bsize; // Insure we get the complete compressed block containing the header - } else { - len = 64000; - } - - const options = buildOptions$1(this.config, {range: {start: 0, size: len}}); - this.header = await BamUtils.readHeader(this.bamPath, options, genome); - } - return this.header - } - - async getIndex() { - const genome = this.genome; - if (!this.index) { - this.index = await loadIndex(this.baiPath, this.config, genome); - } - return this.index - } - - async getChrIndex() { - if (this.chrToIndex) { - return this.chrToIndex - } else { - const header = await this.getHeader(); - this.chrToIndex = header.chrToIndex; - this.indexToChr = header.chrNames; - this.chrAliasTable = header.chrAliasTable; - return this.chrToIndex - - } - } -} - -/* - * The MIT License (MIT) - * - * Copyright (c) 2016-2017 The Regents of the University of California - * Author: Jim Robinson - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -class ShardedBamReader { - - constructor(config, genome) { - - this.config = config; - this.genome = genome; - - const bamReaders = {}; - - config.sources.sequences.forEach(function (chr) { - const queryChr = genome ? genome.getChromosomeName(chr) : chr; - bamReaders[queryChr] = getReader(config, genome, chr); - }); - - this.bamReaders = bamReaders; - - BamUtils.setReaderDefaults(this, config); - } - - async readAlignments(chr, start, end) { - - if (!this.bamReaders.hasOwnProperty(chr)) { - return new AlignmentContainer(chr, start, end, this.config) - } else { - - let reader = this.bamReaders[chr]; - const a = await reader.readAlignments(chr, start, end); - return a - } - } -} - -function getReader(config, genome, chr) { - const tmp = { - url: config.sources.url.replace("$CHR", chr) - }; - if (config.sources.indexURL) { - tmp.indexURL = config.sources.indexURL.replace("$CHR", chr); - } - const bamConfig = Object.assign(config, tmp); - - // TODO -- support non-indexed, htsget, etc - return new BamReader(bamConfig, genome) -} - -/* - * The MIT License (MIT) - * - * Copyright (c) 2016-2017 The Regents of the University of California - * Author: Jim Robinson - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -/** - * Class for reading bam records from an igv.js-flask server backed by pysam. Deprecated. - * - * @param config - * @constructor - */ -const BamWebserviceReader = function (config, genome) { - - this.config = config; - this.genome = genome; - BamUtils.setReaderDefaults(this, config); - -}; - -// Example http://localhost:5000/alignments/?reference=/Users/jrobinso/hg19mini.fa&file=/Users/jrobinso/cram_with_crai_index.cram®ion=1:100-2000 - -BamWebserviceReader.prototype.readAlignments = function (chr, bpStart, bpEnd) { - - var self = this; - - return getHeader.call(self) - - .then(function (header) { - - var queryChr, url; - - queryChr = header.chrAliasTable.hasOwnProperty(chr) ? header.chrAliasTable[chr] : chr; - - url = self.config.url + - "?reference=" + self.config.referenceFile + - "&file=" + self.config.alignmentFile + "" + - "®ion=" + queryChr + ":" + bpStart + "-" + bpEnd; - - - return igvxhr.loadString(url, buildOptions$1(self.config)) - - .then(function (sam) { - - var alignmentContainer; - - header.chrToIndex[queryChr]; - - alignmentContainer = new AlignmentContainer(chr, bpStart, bpEnd, self.config); - - BamUtils.decodeSamRecords(sam, alignmentContainer, queryChr, bpStart, bpEnd, self.filter); - - return alignmentContainer - - }) - - }) -}; - - -// Example http://localhost:5000/alignments/?reference=/Users/jrobinso/hg19mini.fa&file=/Users/jrobinso/cram_with_crai_index.cram&options=-b%20-H -function getHeader() { - - const self = this; - const genome = this.genome; - - if (this.header) { - - return Promise.resolve(this.header) - - } else { - - const url = this.config.url + "?file=" + this.config.alignmentFile + "&options=-b,-H"; - const options = buildOptions$1(this.config); - - return BamUtils.readHeader(url, options, genome) - - .then(function (header) { - - self.header = header; - return header - - }) - } - -} - -/* - * The MIT License (MIT) - * - * Copyright (c) 2016-2017 The Regents of the University of California - * Author: Jim Robinson - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -class HtsgetBamReader extends HtsgetReader { - - constructor(config, genome) { - super(config, genome); - BamUtils.setReaderDefaults(this, config); - } - - - async readAlignments(chr, start, end) { - - if (!this.header) { - const compressedData = await this.readHeaderData(); - const ba = unbgzf(compressedData.buffer); - this.header = BamUtils.decodeBamHeader(ba, this.genome); - this.chrAliasTable = new Map(); - for (let key of Object.keys(this.header.chrAliasTable)) { - this.chrAliasTable.set(key, this.header.chrAliasTable[key]); - } - } - - let queryChr = this.chrAliasTable.has(chr) ? this.chrAliasTable.get(chr) : chr; - - const compressedData = await this.readData(queryChr, start, end); - - // BAM decoding - const ba = unbgzf(compressedData.buffer); - - const chrIdx = this.header.chrToIndex[chr]; - const alignmentContainer = new AlignmentContainer(chr, start, end, this.config); - BamUtils.decodeBamRecords(ba, this.header.size, alignmentContainer, this.header.chrNames, chrIdx, start, end); - alignmentContainer.finish(); - - return alignmentContainer - - } - -} - -/*! For license information please see cram-bundle.js.LICENSE.txt */ -const fn = ()=>{var e={368:function(e,t,r){var n=this&&this.__awaiter||function(e,t,r,n){return new(r||(r=Promise))((function(i,o){function s(e){try{f(n.next(e));}catch(e){o(e);}}function a(e){try{f(n.throw(e));}catch(e){o(e);}}function f(e){var t;e.done?i(e.value):(t=e.value,t instanceof r?t:new r((function(e){e(t);}))).then(s,a);}f((n=n.apply(e,t||[])).next());}))},i=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const o=i(r(4105)),s=i(r(1269)),a=r(597),f=r(3427),h=r(8577);function l(e,t){if(t.some((e=>void 0===e)))throw new h.CramMalformedError("invalid .crai index file");const[r,n,i,o,s,a]=t;e[r]||(e[r]=[]),e[r].push({start:n,span:i,containerStart:o,sliceStart:s,sliceBytes:a});}t.default=class{constructor(e){this.filehandle=(0, f.open)(e.url,e.path,e.filehandle),this._parseCache=new o.default({cache:new s.default({maxSize:1}),fill:(e,t)=>this.parseIndex()});}parseIndex(){const e={};return this.filehandle.readFile().then((e=>31===e[0]&&139===e[1]?(0, a.unzip)(e):e)).then((t=>{if(t.length>4&&21578050===t.readUInt32LE(0))throw new h.CramMalformedError("invalid .crai index file. note: file appears to be a .bai index. this is technically legal but please open a github issue if you need support");let r=[],n="";for(let i=0;i=48&&o<=57||!n&&45===o)n+=String.fromCharCode(o);else if(9===o)r.push(Number.parseInt(n,10)),n="";else if(10===o)r.push(Number.parseInt(n,10)),n="",l(e,r),r=[];else if(13!==o&&32!==o)throw new h.CramMalformedError("invalid .crai index file")}return n&&r.push(Number.parseInt(n,10)),6===r.length&&l(e,r),Object.entries(e).forEach((([t,r])=>{e[t]=r.sort(((e,t)=>e.start-t.start||e.span-t.span));})),e}))}getIndex(e={}){return this._parseCache.get("index",null,e.signal)}hasDataForReferenceSequence(e){return n(this,void 0,void 0,(function*(){return !!(yield this.getIndex())[e]}))}getEntriesForRange(e,t,r){return n(this,void 0,void 0,(function*(){const n=(yield this.getIndex())[e];if(!n)return [];const i=e=>{const n=e.start,i=e.start+e.span;return n>r?-1:i<=t?1:0},o=[];for(let e=0;e{Object.defineProperty(t,"__esModule",{value:!0}),t.default=class{constructor(e,t){this.parameters=e,this.dataType=t;}};},4863:function(e,t,r){var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const i=r(8577),o=n(r(1050)),s=r(1074);class a extends o.default{constructor(e,t){if(super(e,t),"int"!==this.dataType)throw new i.CramUnimplementedError(`${this.dataType} decoding not yet implemented by BETA codec`)}decode(e,t,r,n){return (0, s.getBits)(t.content,n.coreBlock,this.parameters.length)-this.parameters.offset}}t.default=a;},1738:function(e,t,r){var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const i=r(9488),o=n(r(1050));class s extends o.default{constructor(e,t,r){if(super(e,t),this.instantiateCodec=r,"byteArray"!==t)throw new TypeError(`byteArrayLength does not support data type ${t}`)}decode(e,t,r,n){const i=this._getLengthCodec().decode(e,t,r,n),o=this._getDataCodec(),s=new Uint8Array(i);for(let a=0;a(0, i.tinyMemoize)(s,e)));},1405:function(e,t,r){var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const i=r(8577),o=n(r(1050)),s=r(1074);class a extends o.default{constructor(e,t){if(super(e,t),"byteArray"!==t)throw new TypeError(`byteArrayStop codec does not support data type ${t}`)}decode(e,t,r,n){const{blockContentId:o}=this.parameters,s=r[o];if(!s)throw new i.CramMalformedError(`no block found with content ID ${o}`);const a=n.externalBlocks.getCursor(o);return this._decodeByteArray(s,a)}_decodeByteArray(e,t){const r=e.content,{stopByte:n}=this.parameters,i=t.bytePosition;let o=t.bytePosition;for(;r[o]!==n&&o=e.content.length)throw new a.CramBufferOverrunError("attempted to read beyond end of block. this file seems truncated.");return e.content[t.bytePosition++]}}t.default=f;},4229:function(e,t,r){var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const i=r(8577),o=n(r(1050)),s=r(1074);class a extends o.default{constructor(e,t){if(super(e,t),"int"!==this.dataType)throw new i.CramUnimplementedError(`${this.dataType} decoding not yet implemented by GAMMA codec`)}decode(e,t,r,n){let i=1;for(;0===(0, s.getBits)(t.content,n.coreBlock,1);)i+=1;return ((0, s.getBits)(t.content,n.coreBlock,i-1)|1<{Object.defineProperty(t,"__esModule",{value:!0}),t.getBits=t.CramBufferOverrunError=void 0;class r extends Error{}t.CramBufferOverrunError=r,t.getBits=function(e,t,n){let i=0;if(t.bytePosition+(7-t.bitPosition+n)/8>e.length)throw new r("read error during decoding. the file seems to be truncated.");for(let r=n;r;r--)i<<=1,i|=e[t.bytePosition]>>t.bitPosition&1,t.bitPosition-=1,t.bitPosition<0&&(t.bytePosition+=1),t.bitPosition&=7;return i};},2082:function(e,t,r){var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const i=r(8577),o=n(r(1050)),s=r(1074);class a extends o.default{constructor(e,t){if(super(e,t),this.codes={},this.codeBook={},this.sortedByValue=[],this.sortedCodes=[],this.sortedValuesByBitCode=[],this.sortedBitCodes=[],this.sortedBitLengthsByBitCode=[],this.bitCodeToValue=[],!["byte","int"].includes(this.dataType))throw new TypeError(`${this.dataType} decoding not yet implemented by HUFFMAN_INT codec`);this.buildCodeBook(),this.buildCodes(),this.buildCaches(),0===this.sortedCodes[0].bitLength&&(this._decode=this._decodeZeroLengthCode);}buildCodeBook(){let e=new Array(this.parameters.numCodes);for(let t=0;te.bitLength-t.bitLength||e.symbol-t.symbol)),this.codeBook={},e.forEach((e=>{this.codeBook[e.bitLength]||(this.codeBook[e.bitLength]=[]),this.codeBook[e.bitLength].push(e.symbol);}));}buildCodes(){this.codes={};let e=0,t=-1;Object.entries(this.codeBook).forEach((([r,n])=>{const o=parseInt(r,10);n.forEach((r=>{const n={bitLength:o,value:r,bitCode:0};t+=1;const s=o-e;if(t<<=s,n.bitCode=t,e+=s,function(e){let t=e-(e>>1)&1431655765;return t=(858993459&t)+(t>>2&858993459),16843009*(t+(t>>4)&252645135)>>24}(t)>o)throw new i.CramMalformedError("Symbol out of range");this.codes[r]=n;}));}));}buildCaches(){this.sortedCodes=Object.values(this.codes).sort(((e,t)=>e.bitLength-t.bitLength||e.bitCode-t.bitCode)),this.sortedByValue=Object.values(this.codes).sort(((e,t)=>e.value-t.value)),this.sortedValuesByBitCode=this.sortedCodes.map((e=>e.value)),this.sortedBitCodes=this.sortedCodes.map((e=>e.bitCode)),this.sortedBitLengthsByBitCode=this.sortedCodes.map((e=>e.bitLength));const e=Math.max(...this.sortedBitCodes);this.bitCodeToValue=new Array(e+1).fill(-1);for(let e=0;e-1&&this.sortedBitLengthsByBitCode[r]===t)return this.sortedValuesByBitCode[r];for(let r=e;this.sortedCodes[r+1].bitLength===t&&r{Object.defineProperty(t,"__esModule",{value:!0}),t.default={CRAM_FLAG_PRESERVE_QUAL_SCORES:1,CRAM_FLAG_DETACHED:2,CRAM_FLAG_MATE_DOWNSTREAM:4,CRAM_FLAG_NO_SEQ:8,CRAM_FLAG_MASK:15,CRAM_M_REVERSE:1,CRAM_M_UNMAP:2,BAM_FPAIRED:1,BAM_FPROPER_PAIR:2,BAM_FUNMAP:4,BAM_FMUNMAP:8,BAM_FREVERSE:16,BAM_FMREVERSE:32,BAM_FREAD1:64,BAM_FREAD2:128,BAM_FSECONDARY:256,BAM_FQCFAIL:512,BAM_FDUP:1024,BAM_FSUPPLEMENTARY:2048,BAM_CMATCH:0,BAM_CINS:1,BAM_CDEL:2,BAM_CREF_SKIP:3,BAM_CSOFT_CLIP:4,BAM_CHARD_CLIP:5,BAM_CPAD:6,BAM_CEQUAL:7,BAM_CDIFF:8,BAM_CBACK:9,BAM_CIGAR_STR:"MIDNSHP:XB",BAM_CIGAR_SHIFT:4,BAM_CIGAR_MASK:15,BAM_CIGAR_TYPE:246183};},8543:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:!0});const n=r(8772),i=r(8577),o={BF:"int",CF:"int",RI:"int",RL:"int",AP:"int",RG:"int",MF:"int",NS:"int",NP:"int",TS:"int",NF:"int",TC:"byte",TN:"int",FN:"int",FC:"byte",FP:"int",BS:"byte",IN:"byteArray",SC:"byteArray",DL:"int",BA:"byte",BB:"byteArray",RS:"int",PD:"int",HC:"int",MQ:"int",RN:"byteArray",QS:"byte",QQ:"byteArray",TL:"int"};t.default=class{constructor(e){this.dataSeriesCodecCache={},this.tagCodecCache={},this.tagEncoding={},this.readNamesIncluded=e.preservation.RN,this.APdelta=e.preservation.AP,this.referenceRequired=!!e.preservation.RR,this.tagIdsDictionary=e.preservation.TD,this.substitutionMatrix=function(e){const t=new Array(5);for(let e=0;e<5;e+=1)t[e]=new Array(4);return t[0][e[0]>>6&3]="C",t[0][e[0]>>4&3]="G",t[0][e[0]>>2&3]="T",t[0][e[0]>>0&3]="N",t[1][e[1]>>6&3]="A",t[1][e[1]>>4&3]="G",t[1][e[1]>>2&3]="T",t[1][e[1]>>0&3]="N",t[2][e[2]>>6&3]="A",t[2][e[2]>>4&3]="C",t[2][e[2]>>2&3]="T",t[2][e[2]>>0&3]="N",t[3][e[3]>>6&3]="A",t[3][e[3]>>4&3]="C",t[3][e[3]>>2&3]="G",t[3][e[3]>>0&3]="N",t[4][e[4]>>6&3]="A",t[4][e[4]>>4&3]="C",t[4][e[4]>>2&3]="G",t[4][e[4]>>0&3]="T",t}(e.preservation.SM),this.dataSeriesEncoding=e.dataSeriesEncoding,this.tagEncoding=e.tagEncoding,this.preservation=e.preservation,this._size=e._size,this._endPosition=e._endPosition;}getCodecForTag(e){if(!this.tagCodecCache[e]){const t=this.tagEncoding[e];t&&(this.tagCodecCache[e]=(0, n.instantiateCodec)(t,"byteArray"));}return this.tagCodecCache[e]}getTagNames(e){return this.tagIdsDictionary[e]}getCodecForDataSeries(e){let t=this.dataSeriesCodecCache[e];if(void 0===t){const r=this.dataSeriesEncoding[e];if(r){const s=o[e];if(!s)throw new i.CramMalformedError(`data series name ${e} not defined in file compression header`);t=(0, n.instantiateCodec)(r,s),this.dataSeriesCodecCache[e]=t;}}return t}toJSON(){const e={};return Object.keys(this).forEach((t=>{/Cache$/.test(t)||(e[t]=this[t]);})),e}};},6284:function(e,t,r){var n=this&&this.__awaiter||function(e,t,r,n){return new(r||(r=Promise))((function(i,o){function s(e){try{f(n.next(e));}catch(e){o(e);}}function a(e){try{f(n.throw(e));}catch(e){o(e);}}function f(e){var t;e.done?i(e.value):(t=e.value,t instanceof r?t:new r((function(e){e(t);}))).then(s,a);}f((n=n.apply(e,t||[])).next());}))},i=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const o=r(8577),s=r(9488),a=i(r(6601)),f=i(r(8543));class h{constructor(e,t){this.file=e,this.filePosition=t;}getHeader(){return this._readContainerHeader(this.filePosition)}getCompressionHeaderBlock(){return n(this,void 0,void 0,(function*(){if(!(yield this.getHeader()).numRecords)return null;const e=yield this.file.getSectionParsers(),t=yield this.getFirstBlock();if(void 0===t)return;if("COMPRESSION_HEADER"!==t.contentType)throw new o.CramMalformedError(`invalid content type ${t.contentType} in what is supposed to be the compression header block`);const r=(0, s.parseItem)(t.content,e.cramCompressionHeader.parser,0,t.contentPosition);return Object.assign(Object.assign({},t),{parsedContent:r})}))}getFirstBlock(){return n(this,void 0,void 0,(function*(){const e=yield this.getHeader();return this.file.readBlock(e._endPosition)}))}getCompressionScheme(){return n(this,void 0,void 0,(function*(){const e=yield this.getCompressionHeaderBlock();if(e)return new f.default(e.parsedContent)}))}getSlice(e,t){return new a.default(this,e,t)}_readContainerHeader(e){return n(this,void 0,void 0,(function*(){const t=yield this.file.getSectionParsers(),{cramContainerHeader1:r,cramContainerHeader2:n}=t,{size:i}=yield this.file.stat();if(e>=i)return;const o=Buffer.allocUnsafe(r.maxLength);yield this.file.read(o,0,r.maxLength,e);const a=(0, s.parseItem)(o,r.parser),f=(0, s.itf8Size)(a.numLandmarks);if(e+a.length>=i)return void console.warn(`${this.file}: container header at ${e} indicates that the container has length ${a.length}, which extends beyond the length of the file. Skipping this container.`);const h=Buffer.allocUnsafe(n.maxLength(a.numLandmarks));yield this.file.read(h,0,n.maxLength(a.numLandmarks),e+a._size-f);const l=(0, s.parseItem)(h,n.parser);return this.file.validateChecksums&&void 0!==l.crc32&&(yield this.file.checkCrc32(e,a._size+l._size-f-4,l.crc32,`container header beginning at position ${e}`)),Object.assign(a,l,{_size:a._size+l._size-f,_endPosition:a._size+l._size-f+e})}))}}t.default=h,"getHeader getCompressionHeaderBlock getCompressionScheme".split(" ").forEach((e=>(0, s.tinyMemoize)(h,e)));},5457:function(e,t,r){var n=this&&this.__awaiter||function(e,t,r,n){return new(r||(r=Promise))((function(i,o){function s(e){try{f(n.next(e));}catch(e){o(e);}}function a(e){try{f(n.throw(e));}catch(e){o(e);}}function f(e){var t;e.done?i(e.value):(t=e.value,t instanceof r?t:new r((function(e){e(t);}))).then(s,a);}f((n=n.apply(e,t||[])).next());}))},i=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const o=r(597),s=i(r(2779)),a=i(r(1269)),f=r(8577),h=i(r(9675)),l=r(6141),u=i(r(3498)),c=i(r(6284)),d=r(3427),p=r(9488),g=r(7578);class m{constructor(e){var t;if(this.file=(0, d.open)(e.url,e.path,e.filehandle),this.validateChecksums=!0,this.fetchReferenceSequenceCallback=e.seqFetch,this.options={checkSequenceMD5:e.checkSequenceMD5,cacheSize:null!==(t=e.cacheSize)&&void 0!==t?t:2e4},this.featureCache=new a.default({maxSize:this.options.cacheSize}),function(){const e=new Uint32Array([287454020]),t=new Uint8Array(e.buffer);return 68===t[0]?0:17===t[0]?1:2}()>0)throw new Error("Detected big-endian machine, may be unable to run")}read(e,t,r,n){return this.file.read(e,t,r,n)}stat(){return this.file.stat()}getDefinition(){return n(this,void 0,void 0,(function*(){const e=Buffer.allocUnsafe(l.cramFileDefinition.maxLength);yield this.file.read(e,0,l.cramFileDefinition.maxLength,0);const t=l.cramFileDefinition.parser.parse(e).result;if(2!==t.majorVersion&&3!==t.majorVersion)throw new f.CramUnimplementedError(`CRAM version ${t.majorVersion} not supported`);return t}))}getSamHeader(){return n(this,void 0,void 0,(function*(){const e=yield this.getContainerById(0);if(!e)throw new f.CramMalformedError("file contains no containers");const t=yield e.getFirstBlock();if(void 0===t)return (0, g.parseHeaderText)("");const r=t.content,n=r.readInt32LE(0),i=r.toString("utf8",4,4+n);return this.header=i,(0, g.parseHeaderText)(i)}))}getHeaderText(){return n(this,void 0,void 0,(function*(){return yield this.getSamHeader(),this.header}))}getSectionParsers(){return n(this,void 0,void 0,(function*(){const{majorVersion:e}=yield this.getDefinition();return (0, l.getSectionParsers)(e)}))}getContainerById(e){return n(this,void 0,void 0,(function*(){const t=yield this.getSectionParsers();let r=t.cramFileDefinition.maxLength;const{size:n}=yield this.file.stat(),{cramContainerHeader1:i}=t;let o;for(let t=0;t<=e;t+=1){if(r+i.maxLength+8>=n)return;o=this.getContainerAtPosition(r);const s=yield o.getHeader();if(!s)throw new f.CramMalformedError(`container ${e} not found in file`);if(0===t){r=s._endPosition;for(let e=0;e=n)return;const i=Buffer.allocUnsafe(r.maxLength);return yield this.file.read(i,0,r.maxLength,e),(0, p.parseItem)(i,r.parser,0,e)}))}_parseSection(e,t,r=e.maxLength,i){return n(this,void 0,void 0,(function*(){let n;if(i)n=i;else {const{size:e}=yield this.file.stat();if(t+r>=e)return;n=Buffer.allocUnsafe(r),yield this.file.read(n,0,r,t);}const o=(0, p.parseItem)(n,e.parser,0,t);if(o._size!==r)throw new f.CramMalformedError(`section read error: requested size ${r} does not equal parsed size ${o._size}`);return o}))}_uncompress(e,t,r){if("gzip"===e)(0, o.unzip)(t).copy(r);else if("bzip2"===e){const e=bzip2.array(t);let n,i=bzip2.header(e),o=0;do{n=bzip2.decompress(e,i),-1!=n&&(Buffer.from(n).copy(r,o),o+=n.length,i-=n.length);}while(-1!=n)}else if("rans"===e)(0, h.default)(t,r);else if("rans4x16"===e)u.default.r4x16_uncompress(t,r);else if("arith"===e)u.default.arith_uncompress(t,r);else if("fqzcomp"===e)u.default.fqzcomp_uncompress(t,r);else {if("tok3"!==e)throw new f.CramUnimplementedError(`${e} decompression not yet implemented`);u.default.tok3_uncompress(t,r);}}readBlock(e){return n(this,void 0,void 0,(function*(){const{majorVersion:t}=yield this.getDefinition(),r=yield this.getSectionParsers(),n=yield this.readBlockHeader(e);if(void 0===n)return;const i=n._endPosition,o=Buffer.allocUnsafe(n.uncompressedSize),s=Object.assign(Object.assign({},n),{_endPosition:i,contentPosition:i,content:o});if("raw"!==n.compressionMethod){const e=Buffer.allocUnsafe(n.compressedSize);yield this.read(e,0,n.compressedSize,i),this._uncompress(n.compressionMethod,e,o);}else yield this.read(o,0,n.uncompressedSize,i);if(t>=3){const t=yield this._parseSection(r.cramBlockCrc32,i+n.compressedSize);if(void 0===t)return;s.crc32=t.crc32,this.validateChecksums&&(yield this.checkCrc32(e,n._size+n.compressedSize,t.crc32,"block data")),s._endPosition=t._endPosition,s._size=s.compressedSize+r.cramBlockCrc32.maxLength;}else s._endPosition=i+s.compressedSize,s._size=s.compressedSize;return s}))}}t.default=m,"getDefinition getSectionParsers getSamHeader".split(" ").forEach((e=>(0, p.tinyMemoize)(m,e)));},8222:function(e,t,r){var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0}),t.CramRecord=void 0;const i=n(r(5457));var o=r(8631);Object.defineProperty(t,"CramRecord",{enumerable:!0,get:function(){return n(o).default}}),t.default=i.default;},8631:function(e,t,r){var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0}),t.MateFlagsDecoder=t.CramFlagsDecoder=t.BamFlagsDecoder=t.MateFlags=t.CramFlags=t.BamFlags=void 0;const i=n(r(2615)),o={a:0,A:0,c:1,C:1,g:2,G:2,t:3,T:3,n:4,N:4};function s(e){const t={};for(const[r,n]of e)t["is"+n]=e=>!!(e&r),t["set"+n]=e=>e|r;return t}t.BamFlags=[[1,"Paired"],[2,"ProperlyPaired"],[4,"SegmentUnmapped"],[8,"MateUnmapped"],[16,"ReverseComplemented"],[32,"MateReverseComplemented"],[64,"Read1"],[128,"Read2"],[256,"Secondary"],[512,"FailedQc"],[1024,"Duplicate"],[2048,"Supplementary"]],t.CramFlags=[[1,"PreservingQualityScores"],[2,"Detached"],[4,"WithMateDownstream"],[8,"DecodeSequenceAsStar"]],t.MateFlags=[[1,"OnNegativeStrand"],[2,"Unmapped"]],t.BamFlagsDecoder=s(t.BamFlags),t.CramFlagsDecoder=s(t.CramFlags),t.MateFlagsDecoder=s(t.MateFlags),t.default=class{constructor({flags:e,cramFlags:t,readLength:r,mappingQuality:n,lengthOnRef:i,qualityScores:o,mateRecordNumber:s,readBases:a,readFeatures:f,mateToUse:h,readGroupId:l,readName:u,sequenceId:c,uniqueId:d,templateSize:p,alignmentStart:g,tags:m}){this.flags=e,this.cramFlags=t,this.readLength=r,this.mappingQuality=n,this.lengthOnRef=i,this.qualityScores=o,a&&(this.readBases=a),this.readGroupId=l,this.readName=u,this.sequenceId=c,this.uniqueId=d,this.templateSize=p,this.alignmentStart=g,this.tags=m,f&&(this.readFeatures=f),h&&(this.mate={flags:h.mateFlags,readName:h.mateReadName,sequenceId:h.mateSequenceId,alignmentStart:h.mateAlignmentStart}),s&&(this.mateRecordNumber=s);}isPaired(){return !!(this.flags&i.default.BAM_FPAIRED)}isProperlyPaired(){return !!(this.flags&i.default.BAM_FPROPER_PAIR)}isSegmentUnmapped(){return !!(this.flags&i.default.BAM_FUNMAP)}isMateUnmapped(){return !!(this.flags&i.default.BAM_FMUNMAP)}isReverseComplemented(){return !!(this.flags&i.default.BAM_FREVERSE)}isMateReverseComplemented(){return !!(this.flags&i.default.BAM_FMREVERSE)}isRead1(){return !!(this.flags&i.default.BAM_FREAD1)}isRead2(){return !!(this.flags&i.default.BAM_FREAD2)}isSecondary(){return !!(this.flags&i.default.BAM_FSECONDARY)}isFailedQc(){return !!(this.flags&i.default.BAM_FQCFAIL)}isDuplicate(){return !!(this.flags&i.default.BAM_FDUP)}isSupplementary(){return !!(this.flags&i.default.BAM_FSUPPLEMENTARY)}isDetached(){return !!(this.cramFlags&i.default.CRAM_FLAG_DETACHED)}hasMateDownStream(){return !!(this.cramFlags&i.default.CRAM_FLAG_MATE_DOWNSTREAM)}isPreservingQualityScores(){return !!(this.cramFlags&i.default.CRAM_FLAG_PRESERVE_QUAL_SCORES)}isUnknownBases(){return !!(this.cramFlags&i.default.CRAM_FLAG_NO_SEQ)}getReadBases(){if(!this.readBases&&this._refRegion){const e=function(e,t){if(!e.lengthOnRef&&!e.readLength)return null;if(e.isUnknownBases())return null;const r=e.alignmentStart-t.start;if(!e.readFeatures)return t.seq.substr(r,e.lengthOnRef).toUpperCase();let n="",i=r,o=0;for(;n.lengththis.mate.alignmentStart&&o>0&&(o=-o),o>0?(i[0]=e,i[1]=r,i[2]=t,i[3]=n):(i[2]=e,i[3]=r,i[0]=t,i[1]=n),i.join("")}return null}addReferenceSequence(e,t){this.readFeatures&&this.readFeatures.forEach((r=>{"X"===r.code&&function(e,t,r,n){if(!t)return;const i=n.refPos-t.start,s=t.seq.charAt(i);s&&(n.ref=s);let a=o[s];void 0===a&&(a=4);const f=r.substitutionMatrix[a][n.data];f&&(n.sub=f);}(0,e,t,r);})),!this.readBases&&e.start<=this.alignmentStart&&e.end>=this.alignmentStart+(this.lengthOnRef||this.readLength)-1&&(this._refRegion=e);}toJSON(){const e={};return Object.keys(this).forEach((t=>{"_"!==t.charAt(0)&&(e[t]=this[t]);})),e.readBases=this.getReadBases(),e}};},6141:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.getSectionParsers=t.cramFileDefinition=t.isMappedSliceHeader=void 0;const n=r(9996),i=(new n.Parser).itf8(),o={parser:(new n.Parser).string("magic",{length:4}).uint8("majorVersion").uint8("minorVersion").string("fileId",{length:20,stripNull:!0}),maxLength:26};t.cramFileDefinition=o;const s={parser:(new n.Parser).uint8("compressionMethod",{formatter:e=>{const t=["raw","gzip","bzip2","lzma","rans","rans4x16","arith","fqzcomp","tok3"][e];if(!t)throw new Error(`compression method number ${e} not implemented`);return t}}).uint8("contentType",{formatter:e=>{const t=["FILE_HEADER","COMPRESSION_HEADER","MAPPED_SLICE_HEADER","UNMAPPED_SLICE_HEADER","EXTERNAL_DATA","CORE_DATA"][e];if(!t)throw new Error(`invalid block content type id ${e}`);return t}}).itf8("contentId").itf8("compressedSize").itf8("uncompressedSize"),maxLength:17},a={parser:(new n.Parser).uint32("crc32"),maxLength:4},f=(new n.Parser).itf8("size").buffer("ents",{length:"size",formatter:e=>{function t(t,r){const n=e.toString("utf8",t,r),i=[];for(let e=0;ei&&n.push(t(i,r)),n}}),h=(new n.Parser).uint8(null,{formatter:e=>!!e}),l=(new n.Parser).itf8("mapSize").itf8("mapCount").array("ents",{length:"mapCount",type:(new n.Parser).string("key",{length:2,stripNull:!1}).choice("value",{tag:"key",choices:{MI:h,UI:h,PI:h,RN:h,AP:h,RR:h,SM:(new n.Parser).array(null,{type:"uint8",length:5}),TD:(new n.Parser).nest(null,{type:f,formatter:e=>e.ents})}})});function u(e){const t={};for(let r=0;r=3?(r=r.ltf8("recordCounter"),t+=9):2===e&&(r=r.itf8("recordCounter"),t+=5),r=r.itf8("numBlocks").itf8("numContentIds").array("contentIds",{type:i,length:"numContentIds"}),t+=10,e>=2&&(r=r.array("md5",{type:"uint8",length:16}),t+=16),{parser:r,maxLength:e=>t+5*e}},cramMappedSliceHeader(e){let t=(new n.Parser).itf8("refSeqId").itf8("refSeqStart").itf8("refSeqSpan").itf8("numRecords"),r=20;return e>=3?(t=t.ltf8("recordCounter"),r+=9):2===e&&(t=t.itf8("recordCounter"),r+=5),t=t.itf8("numBlocks").itf8("numContentIds").array("contentIds",{type:i,length:"numContentIds"}).itf8("refBaseBlockId"),r+=15,e>=2&&(t=t.array("md5",{type:"uint8",length:16}),r+=16),{parser:t,maxLength:e=>r+5*e}},cramEncoding:e=>({parser:(new n.Parser).namely("cramEncoding").itf8("codecId").itf8("parametersBytes").choice("parameters",{tag:"codecId",choices:{0:new n.Parser,1:(new n.Parser).itf8("blockContentId"),2:(new n.Parser).itf8("offset").itf8("M"),3:n.Parser.start().itf8("numCodes").array("symbols",{length:"numCodes",type:i}).itf8("numLengths").array("bitLengths",{length:"numLengths",type:i}),4:n.Parser.start().nest("lengthsEncoding",{type:"cramEncoding"}).nest("valuesEncoding",{type:"cramEncoding"}),5:(new n.Parser).uint8("stopByte").itf8("blockContentId"),6:(new n.Parser).itf8("offset").itf8("length"),7:(new n.Parser).itf8("offset").itf8("K"),8:(new n.Parser).itf8("offset").itf8("log2m"),9:(new n.Parser).itf8("offset")}})}),cramDataSeriesEncodingMap(e){return (new n.Parser).itf8("mapSize").itf8("mapCount").array("ents",{length:"mapCount",type:(new n.Parser).string("key",{length:2,stripNull:!1}).nest("value",{type:this.cramEncoding(e).parser})})},cramTagEncodingMap(e){return (new n.Parser).itf8("mapSize").itf8("mapCount").array("ents",{length:"mapCount",type:(new n.Parser).itf8("key",{formatter:e=>String.fromCharCode(e>>16&255)+String.fromCharCode(e>>8&255)+String.fromCharCode(255&e)}).nest("value",{type:this.cramEncoding(e).parser})})},cramCompressionHeader(e){let t=new n.Parser;return t=t.nest("preservation",{type:l,formatter:u}).nest("dataSeriesEncoding",{type:this.cramDataSeriesEncodingMap(e),formatter:u}).nest("tagEncoding",{type:this.cramTagEncodingMap(e),formatter:u}),{parser:t}},cramContainerHeader1(e){let t=(new n.Parser).int32("length").itf8("refSeqId").itf8("refSeqStart").itf8("alignmentSpan").itf8("numRecords"),r=24;return e>=3?(t=t.ltf8("recordCounter"),r+=9):2===e&&(t=t.itf8("recordCounter"),r+=5),e>1&&(t=t.ltf8("numBases"),r+=9),t=t.itf8("numBlocks").itf8("numLandmarks"),r+=10,{parser:t,maxLength:r}},cramContainerHeader2(e){let t=(new n.Parser).itf8("numLandmarks").array("landmarks",{type:(new n.Parser).itf8(),length:"numLandmarks"}),r=0;return e>=3&&(t=t.uint32("crc32"),r=4),{parser:t,maxLength:e=>5+5*e+r}}};t.getSectionParsers=function(e){const t=Object.assign({},c);return Object.keys(d).forEach((r=>{t[r]=d[r](e);})),t};},3757:function(e,t,r){var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const i=n(r(3720)),o=r(8577),s=r(8631),a=r(6141);function f(e){let t="";for(let r=0;r1&&-2===n.parsedContent.refSeqId?t("RI"):n.parsedContent.refSeqId;const y=t("RL");let b=t("AP");r.APdelta&&(b+=u.lastAlignmentStart),u.lastAlignmentStart=b;const v=t("RG");let w,_,B,E;if(r.readNamesIncluded&&(w=f(t("RN"))),s.CramFlagsDecoder.isDetached(g)){const e=t("MF");let n;r.readNamesIncluded||(n=f(t("RN")),w=n);const i=t("NS"),o=t("NP");(e||i>-1)&&(_={mateFlags:e,mateSequenceId:i,mateAlignmentStart:o,mateReadName:n}),B=t("TS"),s.MateFlagsDecoder.isUnmapped(e)&&(p=s.BamFlagsDecoder.setMateUnmapped(p)),s.MateFlagsDecoder.isOnNegativeStrand(e)&&(p=s.BamFlagsDecoder.setMateReverseComplemented(p));}else s.CramFlagsDecoder.isWithMateDownstream(g)&&(E=t("NF")+d+1);const S=t("TL");if(S<0)throw new o.CramMalformedError("invalid TL index");const A={},C=r.getTagNames(S),R=C.length;for(let t=0;t1?"SC":"IN"],X:["number","BS"],D:["number","DL"],I:["string","IN"],i:["character","BA"],b:["string","BB"],q:["numArray","QQ"],Q:["number","QS"],H:["number","HC"],P:["number","PD"],N:["number","RS"]}[t];if(!l)throw new o.CramMalformedError(`invalid read feature code "${t}"`);let u=h(l);const c={B:["number","QS"]}[t];c&&(u=[u,h(c)]),s+=n;const d=s;a+=n;const p=a;"D"===t||"N"===t?a+=u:"I"===t||"S"===t?a-=u.length:"i"===t&&(a-=1),f[e]={code:t,pos:d,refPos:p,data:u};}return f}(b,e,t,0,c)),x=y,k)for(const{code:e,data:t}of k)"D"===e||"N"===e?x+=t:"I"===e||"S"===e?x-=t.length:"i"===e&&(x-=1);if(Number.isNaN(x)&&(console.warn(`${w||`${m}:${b}`} record has invalid read features`),x=y),I=t("MQ"),s.CramFlagsDecoder.isPreservingQualityScores(g)){M=new Array(y);for(let e=0;e=0){const i=e[r.mateRecordNumber];if(!i)throw new o.CramMalformedError("intra-slice mate record not found, this file seems malformed");n.push(...t(i));}return n}(r),i=n.map((e=>e.alignmentStart)),s=n.map((e=>e.alignmentStart+e.readLength-1)),a=Math.max(...s)-Math.min(...i)+1;a>=0&&n.forEach((e=>{if(void 0!==e.templateLength)throw new o.CramMalformedError("mate pair group has some members that have template lengths already, this file seems malformed");e.templateLength=a;}));}(e,0,r):function(e,t){const r=Math.min(e.alignmentStart,t.alignmentStart),n=Math.max(e.alignmentStart+e.readLength-1,t.alignmentStart+t.readLength-1)-r+1;e.templateLength=n,t.templateLength=n;}(r,n)),delete r.mateRecordNumber;}class d{constructor(e,t,r){this.container=e,this.containerPosition=t,this.file=e.file;}getHeader(){return n(this,void 0,void 0,(function*(){const e=yield this.file.getSectionParsers(),t=yield this.container.getHeader(),r=yield this.file.readBlock(t._endPosition+this.containerPosition);if(void 0===r)throw new Error;if("MAPPED_SLICE_HEADER"===r.contentType){const n=(0, s.parseItem)(r.content,e.cramMappedSliceHeader.parser,0,t._endPosition);return Object.assign(Object.assign({},r),{parsedContent:n})}if("UNMAPPED_SLICE_HEADER"===r.contentType){const n=(0, s.parseItem)(r.content,e.cramUnmappedSliceHeader.parser,0,t._endPosition);return Object.assign(Object.assign({},r),{parsedContent:n})}throw new o.CramMalformedError(`error reading slice header block, invalid content type ${r.contentType}`)}))}getBlocks(){return n(this,void 0,void 0,(function*(){const e=yield this.getHeader();let t=e._endPosition;const r=new Array(e.parsedContent.numBlocks);for(let e=0;e{"EXTERNAL_DATA"===e.contentType&&(t[e.contentId]=e);})),t}))}getBlockByContentId(e){return n(this,void 0,void 0,(function*(){return (yield this._getBlocksContentIdIndex())[e]}))}getReferenceRegion(){return n(this,void 0,void 0,(function*(){const e=(yield this.getHeader()).parsedContent;if(!(0, l.isMappedSliceHeader)(e))throw new Error;if(e.refSeqId<0)return;const t=yield this.container.getCompressionScheme();if(void 0===t)throw new Error;if(e.refBaseBlockId>=0){const t=yield this.getBlockByContentId(e.refBaseBlockId);if(!t)throw new o.CramMalformedError("embedded reference specified, but reference block does not exist");return {seq:t.data.toString("utf8"),start:e.refSeqStart,end:e.refSeqStart+e.refSeqSpan-1,span:e.refSeqSpan}}if(t.referenceRequired||this.file.fetchReferenceSequenceCallback){if(!this.file.fetchReferenceSequenceCallback)throw new Error("reference sequence not embedded, and seqFetch callback not provided, cannot fetch reference sequence");const t=yield this.file.fetchReferenceSequenceCallback(e.refSeqId,e.refSeqStart,e.refSeqStart+e.refSeqSpan-1);if(t.length!==e.refSeqSpan)throw new o.CramArgumentError("seqFetch callback returned a reference sequence of the wrong length");return {seq:t,start:e.refSeqStart,end:e.refSeqStart+e.refSeqSpan-1,span:e.refSeqSpan}}}))}getAllRecords(){return this.getRecords((()=>!0))}_fetchRecords(){return n(this,void 0,void 0,(function*(){const{majorVersion:e}=yield this.file.getDefinition(),t=yield this.container.getCompressionScheme();if(void 0===t)throw new Error;const r=yield this.getHeader();if(void 0===r)throw new Error;const n=yield this._getBlocksContentIdIndex();if(e>1&&this.file.options.checkSequenceMD5&&(0, l.isMappedSliceHeader)(r.parsedContent)&&r.parsedContent.refSeqId>=0&&"0000000000000000"!==r.parsedContent.md5.join("")){const e=yield this.getReferenceRegion();if(e){const{seq:t,start:n,end:i}=e,a=(0, s.sequenceMD5)(t),f=r.parsedContent.md5.map((e=>(e<16?"0":"")+e.toString(16))).join("");if(a!==f)throw new o.CramMalformedError(`MD5 checksum reference mismatch for ref ${r.parsedContent.refSeqId} pos ${n}..${i}. recorded MD5: ${f}, calculated MD5: ${a}`)}}const i=yield this.getCoreDataBlock(),a={lastAlignmentStart:(0, l.isMappedSliceHeader)(r.parsedContent)?r.parsedContent.refSeqStart:0,coreBlock:{bitPosition:7,bytePosition:0},externalBlocks:{map:new Map,getCursor(e){let t=this.map.get(e);return void 0===t&&(t={bitPosition:7,bytePosition:0},this.map.set(e,t)),t}}},d=e=>{const r=t.getCodecForDataSeries(e);if(!r)throw new o.CramMalformedError(`no codec defined for ${e} data series`);return r.decode(this,i,n,a)};let p=new Array(r.parsedContent.numRecords);for(let o=0;o!!e));break}throw e}for(let e=0;e=0&&c(p,e,p[e],p[t]);}return p}))}getRecords(e){return n(this,void 0,void 0,(function*(){const t=this.container.filePosition+this.containerPosition;let r=this.file.featureCache.get(t.toString());r||(r=this._fetchRecords(),this.file.featureCache.set(t.toString(),r));const i=(yield r).filter(e);if(i.length&&this.file.fetchReferenceSequenceCallback){const e=yield this.getHeader();if((0, l.isMappedSliceHeader)(e.parsedContent)&&(e.parsedContent.refSeqId>=0||-2===e.parsedContent.refSeqId)){const t=e.parsedContent.refSeqId>=0?e.parsedContent.refSeqId:void 0,r=yield this.container.getCompressionScheme();if(void 0===r)throw new Error;const o={};for(let e=0;en.end&&(n.end=s),i[e].alignmentStartn(this,void 0,void 0,(function*(){-1!==e.id&&e.start<=e.end&&(e.seq=yield this.file.fetchReferenceSequenceCallback(e.id,e.start,e.end));})))));for(let e=0;e(0, s.tinyMemoize)(d,e)));},9488:function(e,t,r){var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0}),t.sequenceMD5=t.tinyMemoize=t.parseItem=t.parseItf8=t.itf8Size=void 0;const i=n(r(2568)),o=r(1074);t.itf8Size=function(e){return -128&e?-16384&e?-2097152&e?-268435456&e?5:4:3:2:1},t.parseItf8=function(e,t){let r=t;const n=e[r];let i;if(n<128?(i=n,r+=1):n<192?(i=16383&(n<<8|e[r+1]),r+=2):n<224?(i=2097151&(n<<16|e[r+1]<<8|e[r+2]),r+=3):n<240?(i=268435455&(n<<24|e[r+1]<<16|e[r+2]<<8|e[r+3]),r+=4):(i=(15&n)<<28|e[r+1]<<20|e[r+2]<<12|e[r+3]<<4|15&e[r+4],r+=5),r>e.length)throw new o.CramBufferOverrunError("Attempted to read beyond end of buffer; this file seems truncated.");return [i,r-t]},t.parseItem=function(e,t,r=0,n=0){const{offset:i,result:o}=t.parse(e);return Object.assign(Object.assign({},o),{_endPosition:i+n,_size:i-r})},t.tinyMemoize=function(e,t){const r=e.prototype[t],n=`_memo_${t}`;e.prototype[t]=function(){if(!(n in this)){const e=r.call(this);this[n]=e,Promise.resolve(e).catch((()=>{delete this[n];}));}return this[n]};},t.sequenceMD5=function(e){return (0, i.default)(e.toUpperCase().replace(/[^\x21-\x7e]/g,""))};},8577:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.CramArgumentError=t.CramSizeLimitError=t.CramMalformedError=t.CramUnimplementedError=t.CramError=void 0;class r extends Error{}t.CramError=r;class n extends Error{}t.CramUnimplementedError=n,t.CramMalformedError=class extends r{},t.CramSizeLimitError=class extends r{},t.CramArgumentError=class extends r{};},5590:function(e,t,r){var n=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r);var i=Object.getOwnPropertyDescriptor(t,r);i&&!("get"in i?!t.__esModule:i.writable||i.configurable)||(i={enumerable:!0,get:function(){return t[r]}}),Object.defineProperty(e,n,i);}:function(e,t,r,n){void 0===n&&(n=r),e[n]=t[r];}),i=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t});}:function(e,t){e.default=t;}),o=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var r in e)"default"!==r&&Object.prototype.hasOwnProperty.call(e,r)&&n(t,e,r);return i(t,e),t},s=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0}),t.CramRecord=t.CraiIndex=t.IndexedCramFile=t.CramFile=void 0;const a=o(r(8222));t.CramFile=a.default,Object.defineProperty(t,"CramRecord",{enumerable:!0,get:function(){return a.CramRecord}});const f=s(r(946));t.IndexedCramFile=f.default;const h=s(r(368));t.CraiIndex=h.default;},946:function(e,t,r){var n=this&&this.__awaiter||function(e,t,r,n){return new(r||(r=Promise))((function(i,o){function s(e){try{f(n.next(e));}catch(e){o(e);}}function a(e){try{f(n.throw(e));}catch(e){o(e);}}function f(e){var t;e.done?i(e.value):(t=e.value,t instanceof r?t:new r((function(e){e(t);}))).then(s,a);}f((n=n.apply(e,t||[])).next());}))},i=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const o=r(8577),s=i(r(8222));t.default=class{constructor(e){if(e.cram?this.cram=e.cram:this.cram=new s.default({url:e.cramUrl,path:e.cramPath,filehandle:e.cramFilehandle,seqFetch:e.seqFetch,checkSequenceMD5:e.checkSequenceMD5,cacheSize:e.cacheSize}),!(this.cram instanceof s.default))throw new Error("invalid arguments: no cramfile");if(this.index=e.index,!this.index.getEntriesForRange)throw new Error("invalid arguments: not an index");this.fetchSizeLimit=e.fetchSizeLimit||3e6;}getRecordsForRange(e,t,r,i={}){return n(this,void 0,void 0,(function*(){if(i.viewAsPairs=i.viewAsPairs||!1,i.pairAcrossChr=i.pairAcrossChr||!1,i.maxInsertSize=i.maxInsertSize||2e5,"string"==typeof e)throw new o.CramUnimplementedError("string sequence names not yet supported");const n=e,s=yield this.index.getEntriesForRange(n,t,r),a=s.map((e=>e.sliceBytes)).reduce(((e,t)=>e+t),0);if(a>this.fetchSizeLimit)throw new o.CramSizeLimitError(`data size of ${a.toLocaleString()} bytes exceeded fetch size limit of ${this.fetchSizeLimit.toLocaleString()} bytes`);const f=n=>n.sequenceId===e&&n.alignmentStart<=r&&void 0!==n.lengthOnRef&&n.alignmentStart+n.lengthOnRef-1>=t,h=yield Promise.all(s.map((e=>this.getRecordsInSlice(e,f))));let l=Array.prototype.concat(...h);if(i.viewAsPairs){const e={},t={};for(let r=0;r{1===t&&(r[e]=!0);}));const o=[];for(let e=0;ee.toString().localeCompare(t.toString()))).filter(((e,t,r)=>!t||e.toString()!==r[t-1].toString()));const h=[],u=a.map((e=>e.sliceBytes)).reduce(((e,t)=>e+t),0);if(u>this.fetchSizeLimit)throw new Error(`mate data size of ${u.toLocaleString()} bytes exceeded fetch size limit of ${this.fetchSizeLimit.toLocaleString()} bytes`);a.forEach((e=>{let n=this.cram.featureCache.get(e.toString());n||(n=this.getRecordsInSlice(e,(()=>!0)),this.cram.featureCache.set(e.toString(),n));const i=n.then((e=>{const n=[];for(let i=0;ie.concat(t)));l=l.concat(e);}}return l}))}getRecordsInSlice({containerStart:e,sliceStart:t,sliceBytes:r},n){return this.cram.getContainerAtPosition(e).getSlice(t,r).getRecords(n)}hasDataForReferenceSequence(e){return this.index.hasDataForReferenceSequence(e)}};},3427:function(e,t,r){var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0}),t.open=t.fromUrl=t.RemoteFile=t.LocalFile=void 0;const i=n(r(8575)),o=r(4319),s=r(2949);function a(e){const{protocol:t,pathname:r}=i.default.parse(e);return "file:"===t?new s.LocalFile(unescape((0, o.ensureNotNullish)(r))):new s.RemoteFile(e)}Object.defineProperty(t,"LocalFile",{enumerable:!0,get:function(){return s.LocalFile}}),Object.defineProperty(t,"RemoteFile",{enumerable:!0,get:function(){return s.RemoteFile}}),t.fromUrl=a,t.open=function(e,t,r){if(r)return r;if(e)return a(e);if(t)return new s.LocalFile(t);throw new Error("no url, path, or filehandle provided, cannot open")};},5702:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.RANS_BYTE_L=t.TOTFREQ=t.TF_SHIFT=void 0,t.TF_SHIFT=12,t.TOTFREQ=4096,t.RANS_BYTE_L=1<<23;},6484:function(e,t,r){var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const i=r(8577),o=r(5702),s=n(r(7634));t.default=function(e,t,r,n){let a=e.getInt(),f=e.getInt(),h=e.getInt(),l=e.getInt();const u=n.remaining(),c=-4&u;for(let i=0;i>2;let c=0,d=u,p=2*u,g=3*u,m=0,y=0,b=0,v=0;for(;c{Object.defineProperty(t,"__esModule",{value:!0});const n=r(8577),i=r(5702);class o{constructor(){this.F=void 0,this.C=void 0;}}function s(e,t,r,n){return r*(e>>n)+(e&(1<>o)+(e&(1<=128&&(t.fc[f].F&=-129,t.fc[f].F=(127&t.fc[f].F)<<8|255&e.get()),t.fc[f].C=i,s.default.symbolInit(r[f],t.fc[f].C,t.fc[f].F),t.R||(t.R=new Array(o.TOTFREQ)),t.R.fill(f,i,i+t.fc[f].F),i+=t.fc[f].F,0===n&&f+1===(255&e.getByteAt(e.position()))?(f=255&e.get(),n=255&e.get()):0!==n?(n-=1,f+=1):f=255&e.get();}while(0!==f);a(i=128&&(t[i].fc[l].F&=-129,t[i].fc[l].F=(127&t[i].fc[l].F)<<8|255&e.get()),t[i].fc[l].C=h,0===t[i].fc[l].F&&(t[i].fc[l].F=o.TOTFREQ),null==r[i][l]&&(r[i][l]=new s.default.RansDecSymbol),s.default.symbolInit(r[i][l],t[i].fc[l].C,t[i].fc[l].F),null==t[i].R&&(t[i].R=new Array(o.TOTFREQ)),t[i].R.fill(l,h,h+t[i].fc[l].F),h+=t[i].fc[l].F,a(h<=o.TOTFREQ),0===f&&l+1===(255&e.getByteAt(e.position()))?(l=255&e.get(),f=255&e.get()):0!==f?(f-=1,l+=1):l=255&e.get();}while(0!==l);0===n&&i+1===(255&e.getByteAt(e.position()))?(i=255&e.get(),n=255&e.get()):0!==n?(n-=1,i+=1):i=255&e.get();}while(0!==i)};},9675:function(e,t,r){var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const i=r(8577),o=n(r(7634)),s=r(696),a=n(r(6484)),f=n(r(7121));class h{constructor(e,t=0){this._buffer=e,this._position=t,this.length=e.length;}get(){const e=this._buffer[this._position];return this._position+=1,e}getByte(){return this.get()}getByteAt(e){return this._buffer[e]}position(){return this._position}put(e){return this._buffer[this._position]=e,this._position+=1,e}putAt(e,t){return this._buffer[e]=t,t}setPosition(e){return this._position=e,e}getInt(){const e=this._buffer.readInt32LE(this._position);return this._position+=4,e}remaining(){return this._buffer.length-this._position}}t.default=function(e,t,r=0){if(0===e.length)return t.fill(0),t;const n=new h(e,r),l=n.get();if(0!==l&&1!==l)throw new i.CramMalformedError(`Invalid rANS order ${l}`);if(n.getInt()!==n.remaining()-4)throw new i.CramMalformedError("Incorrect input length.");const u=n.getInt(),c=new h(t||Buffer.allocUnsafe(u));if(c.length{Object.defineProperty(t,"__esModule",{value:!0}),t.parseHeaderText=void 0,t.parseHeaderText=function(e){const t=e.split(/\r?\n/),r=[];return t.forEach((e=>{const[t,...n]=e.split(/\t/),i=n.map((e=>{const[t,r]=e.split(":",2);return {tag:t,value:r}}));t&&r.push({tag:t.substr(1),data:i});})),r};},4319:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.ensureNotNullish=void 0,t.ensureNotNullish=function(e){if(null==e)throw new Error("Value must not be nullish.");return e};},597:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.unzip=void 0;const n=r(9591);t.unzip=function(e){return Buffer.from((0, n.inflate)(e))};},9996:(e,t,r)=>{function n(e){return n="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},n(e)}var i=r(8764).Buffer,o=r(22),s=r(2961)._,a=r(3720);"undefined"!=typeof window&&(window.Buffer=i),"undefined"!=typeof self&&(self.Buffer=i);var f={UInt8:1,UInt16LE:2,UInt16BE:2,UInt32LE:4,UInt32BE:4,Int8:1,Int16LE:2,Int16BE:2,Int32LE:4,Int32BE:4,FloatLE:4,FloatBE:4,DoubleLE:8,DoubleBE:8,UInt64:8,Int64:8},h={},l="___parser_",u=[];!function(){var e;for(e=1;e<=32;e++)u.push(e);}();var c={};Object.keys(f).concat(Object.keys({String:null,Buffer:null,Array:null,Skip:null,Choice:null,Nest:null,Bit:null,Itf8:null,Ltf8:null})).forEach((function(e){c[e.toLowerCase()]=e;}));var d=function(){this.varName="",this.type="",this.options={},this.next=null,this.head=null,this.compiled=null,this.endian="le",this.constructorFn=null,this.alias=null;};d.start=function(){return new d},Object.keys(f).forEach((function(e){d.prototype[e.toLowerCase()]=function(t,r){return this.setNextParser(e.toLowerCase(),t,r)};var t=e.replace(/BE|LE/,"").toLowerCase();t in d.prototype||(d.prototype[t]=function(e,r){return this[t+this.endian](e,r)});})),u.forEach((function(e){d.prototype["bit".concat(e.toString())]=function(t,r){return r||(r={}),r.length=e,this.setNextParser("bit",t,r)};})),d.prototype.namely=function(e){return h[e]=this,this.alias=e,this},d.prototype.skip=function(e,t){if(t&&t.assert)throw new Error("assert option on skip is not allowed.");return this.setNextParser("skip","",{length:e})},d.prototype.string=function(e,t){if(!t.zeroTerminated&&!t.length&&!t.greedy)throw new Error("Neither length, zeroTerminated, nor greedy is defined for string.");if((t.zeroTerminated||t.length)&&t.greedy)throw new Error("greedy is mutually exclusive with length and zeroTerminated for string.");if(t.stripNull&&!t.length&&!t.greedy)throw new Error("Length or greedy must be defined if stripNull is defined.");return t.encoding=t.encoding||"utf8",this.setNextParser("string",e,t)},d.prototype.buffer=function(e,t){if(!t.length&&!t.readUntil)throw new Error("Length nor readUntil is defined in buffer parser");return this.setNextParser("buffer",e,t)},d.prototype.array=function(e,t){if(!t.readUntil&&!t.length&&!t.lengthInBytes)throw new Error("Length option of array is not defined.");if(!t.type)throw new Error("Type option of array is not defined.");if("string"==typeof t.type&&!h[t.type]&&Object.keys(f).indexOf(c[t.type])<0)throw new Error('Specified primitive type "'.concat(t.type,'" is not supported.'));return this.setNextParser("array",e,t)},d.prototype.choice=function(e,t){if(1===arguments.length&&"object"===n(e)&&(t=e,e=null),!t.tag)throw new Error("Tag option of array is not defined.");if(!t.choices)throw new Error("Choices option of array is not defined.");return Object.keys(t.choices).forEach((function(r){if(!t.choices[r])throw new Error("Choice Case ".concat(r," of ").concat(e," is not valid."));if("string"==typeof t.choices[r]&&!h[t.choices[r]]&&Object.keys(f).indexOf(c[t.choices[r]])<0)throw new Error('Specified primitive type "'.concat(t.choices[r],'" is not supported.'))}),this),this.setNextParser("choice",e,t)},d.prototype.nest=function(e,t){if(1===arguments.length&&"object"===n(e)&&(t=e,e=null),!t.type)throw new Error("Type option of nest is not defined.");if(!(t.type instanceof d||h[t.type]))throw new Error("Type option of nest must be a Parser object.");if(!(t.type instanceof d||e))throw new Error("options.type must be a object if variable name is omitted.");return this.setNextParser("nest",e,t)},d.prototype.endianess=function(e){switch(e.toLowerCase()){case"little":this.endian="le";break;case"big":this.endian="be";break;default:throw new Error("Invalid endianess: ".concat(e))}return this},d.prototype.create=function(e){if(!(e instanceof Function))throw new Error("Constructor must be a Function object.");return this.constructorFn=e,this},d.prototype.getCode=function(){var e=new s;return e.pushCode("if (!Buffer.isBuffer(buffer)) {"),e.generateError('"argument buffer is not a Buffer object"'),e.pushCode("}"),this.alias?this.addAliasedCode(e):this.addRawCode(e),this.alias?e.pushCode("return {0}(0)",l+this.alias):e.pushCode("return { offset: offset, result: vars };"),e.code},d.prototype.addRawCode=function(e){e.pushCode("var offset = 0;"),this.constructorFn?e.pushCode("var vars = new constructorFn();"):e.pushCode("var vars = {};"),this.generate(e),this.resolveReferences(e),e.pushCode("return { offset: offset, result: vars };");},d.prototype.addAliasedCode=function(e){return e.pushCode("function {0}(offset) {",l+this.alias),this.constructorFn?e.pushCode("var vars = new constructorFn();"):e.pushCode("var vars = {};"),this.generate(e),e.markResolved(this.alias),this.resolveReferences(e),e.pushCode("return { offset: offset, result: vars };"),e.pushCode("}"),e},d.prototype.resolveReferences=function(e){var t=e.getUnresolvedReferences();e.markRequested(t),t.forEach((function(t){h[t].addAliasedCode(e);}));},d.prototype.compile=function(){var e="(function(buffer, constructorFn, Long) { ".concat(this.getCode()," })");this.compiled=o.runInThisContext(e);},d.prototype.sizeOf=function(){var e=NaN;if(Object.keys(f).indexOf(this.type)>=0)e=f[this.type];else if("String"===this.type&&"number"==typeof this.options.length)e=this.options.length;else if("Buffer"===this.type&&"number"==typeof this.options.length)e=this.options.length;else if("Array"===this.type&&"number"==typeof this.options.length){var t=NaN;"string"==typeof this.options.type?t=f[c[this.options.type]]:this.options.type instanceof d&&(t=this.options.type.sizeOf()),e=this.options.length*t;}else "Skip"===this.type?e=this.options.length:"Nest"===this.type?e=this.options.type.sizeOf():this.type||(e=0);return this.next&&(e+=this.next.sizeOf()),e},d.prototype.parse=function(e){return this.compiled||this.compile(),this.compiled(e,this.constructorFn,a)},d.prototype.setNextParser=function(e,t,r){var n=new d;return n.type=c[e],n.varName=t,n.options=r||n.options,n.endian=this.endian,this.head?this.head.next=n:this.next=n,this.head=n,this},d.prototype.generate=function(e){this.type&&(this["generate".concat(this.type)](e),this.generateAssert(e));var t=e.generateVariable(this.varName);return this.options.formatter&&this.generateFormatter(e,t,this.options.formatter),this.generateNext(e)},d.prototype.generateAssert=function(e){if(this.options.assert){var t=e.generateVariable(this.varName);switch(n(this.options.assert)){case"function":e.pushCode("if (!({0}).call(vars, {1})) {",this.options.assert,t);break;case"number":e.pushCode("if ({0} !== {1}) {",this.options.assert,t);break;case"string":e.pushCode('if ("{0}" !== {1}) {',this.options.assert,t);break;default:throw new Error("Assert option supports only strings, numbers and assert functions.")}e.generateError('"Assert error: {0} is " + {0}',t),e.pushCode("}");}},d.prototype.generateNext=function(e){return this.next&&(e=this.next.generate(e)),e},Object.keys(f).forEach((function(e){d.prototype["generate".concat(e)]=function(t){"UInt64"===e?t.pushCode("{0} = Long.fromBytes(buffer.slice(offset,offset+8), true, this.endian === 'le').toNumber();",t.generateVariable(this.varName),e):"Int64"===e?t.pushCode("{0} = Long.fromBytes(buffer.slice(offset,offset+8), false, this.endian === 'le').toNumber();",t.generateVariable(this.varName),e):t.pushCode("{0} = buffer.read{1}(offset);",t.generateVariable(this.varName),e),t.pushCode("offset += {0};",f[e]);};})),d.prototype.generateBit=function(e){var t=JSON.parse(JSON.stringify(this));if(t.varName=e.generateVariable(t.varName),e.bitFields.push(t),!this.next||this.next&&["Bit","Nest"].indexOf(this.next.type)<0){var r=0;e.bitFields.forEach((function(e){r+=e.options.length;}));var n=e.generateTmpVariable();if(r<=8)e.pushCode("var {0} = buffer.readUInt8(offset);",n),r=8;else if(r<=16)e.pushCode("var {0} = buffer.readUInt16BE(offset);",n),r=16;else if(r<=24){var i=e.generateTmpVariable(),o=e.generateTmpVariable();e.pushCode("var {0} = buffer.readUInt16BE(offset);",i),e.pushCode("var {0} = buffer.readUInt8(offset + 2);",o),e.pushCode("var {2} = ({0} << 8) | {1};",i,o,n),r=24;}else {if(!(r<=32))throw new Error("Currently, bit field sequence longer than 4-bytes is not supported.");e.pushCode("var {0} = buffer.readUInt32BE(offset);",n),r=32;}e.pushCode("offset += {0};",r/8);var s=0,a="be"===this.endian;e.bitFields.forEach((function(t){e.pushCode("{0} = {1} >> {2} & {3};",t.varName,n,a?r-s-t.options.length:s,(1< offset++);"),e.pushCode("{0} = buffer.toString('{1}', {2}, offset);",t,this.options.encoding,r)),this.options.stripNull&&e.pushCode("{0} = {0}.replace(/\\x00+$/g, '')",t);},d.prototype.generateBuffer=function(e){"eof"===this.options.readUntil?e.pushCode("{0} = buffer.slice(offset);",e.generateVariable(this.varName)):(e.pushCode("{0} = buffer.slice(offset, offset + {1});",e.generateVariable(this.varName),e.generateOption(this.options.length)),e.pushCode("offset += {0};",e.generateOption(this.options.length))),this.options.clone&&e.pushCode("{0} = Buffer.from({0});",e.generateVariable(this.varName));},d.prototype.generateArray=function(e){var t=e.generateOption(this.options.length),r=e.generateOption(this.options.lengthInBytes),n=this.options.type,i=e.generateTmpVariable(),o=e.generateVariable(this.varName),s=e.generateTmpVariable(),a=this.options.key,u="string"==typeof a;if(u?e.pushCode("{0} = {};",o):e.pushCode("{0} = [];",o),"function"==typeof this.options.readUntil?e.pushCode("do {"):"eof"===this.options.readUntil?e.pushCode("for (var {0} = 0; offset < buffer.length; {0}++) {",i):void 0!==r?e.pushCode("for (var {0} = offset; offset - {0} < {1}; ) {",i,r):e.pushCode("for (var {0} = 0; {0} < {1}; {0}++) {",i,t),"string"==typeof n)if(h[n]){var p=e.generateTmpVariable();e.pushCode("var {0} = {1}(offset);",p,l+n),e.pushCode("var {0} = {1}.result; offset = {1}.offset;",s,p),n!==this.alias&&e.addReference(n);}else e.pushCode("var {0} = buffer.read{1}(offset);",s,c[n]),e.pushCode("offset += {0};",f[c[n]]);else n instanceof d&&(e.pushCode("var {0} = {};",s),e.pushScope(s),n.generate(e),e.popScope());u?e.pushCode("{0}[{2}.{1}] = {2};",o,a,s):e.pushCode("{0}.push({1});",o,s),e.pushCode("}"),"function"==typeof this.options.readUntil&&e.pushCode(" while (!({0}).call(this, {1}, buffer.slice(offset)));",this.options.readUntil,s);},d.prototype.generateChoiceCase=function(e,t,r){if("string"==typeof r)if(h[r]){var n=e.generateTmpVariable();e.pushCode("var {0} = {1}(offset);",n,l+r),e.pushCode("{0} = {1}.result; offset = {1}.offset;",e.generateVariable(this.varName),n),r!==this.alias&&e.addReference(r);}else e.pushCode("{0} = buffer.read{1}(offset);",e.generateVariable(this.varName),c[r]),e.pushCode("offset += {0};",f[c[r]]);else r instanceof d&&(e.pushPath(t),r.generate(e),e.popPath(t));},d.prototype.generateChoice=function(e){var t=e.generateOption(this.options.tag);this.varName&&e.pushCode("{0} = {};",e.generateVariable(this.varName)),e.pushCode("switch({0}) {",t),Object.keys(this.options.choices).forEach((function(t){var r=this.options.choices[t];Number.isNaN(parseInt(t,10))?e.pushCode("case '{0}':",t):e.pushCode("case {0}:",t),this.generateChoiceCase(e,this.varName,r),e.pushCode("break;");}),this),e.pushCode("default:"),this.options.defaultChoice?this.generateChoiceCase(e,this.varName,this.options.defaultChoice):e.generateError('"Met undefined tag value " + {0} + " at choice"',t),e.pushCode("}");},d.prototype.generateNest=function(e){var t=e.generateVariable(this.varName);if(this.options.type instanceof d)this.varName&&e.pushCode("{0} = {};",t),e.pushPath(this.varName),this.options.type.generate(e),e.popPath(this.varName);else if(h[this.options.type]){var r=e.generateTmpVariable();e.pushCode("var {0} = {1}(offset);",r,l+this.options.type),e.pushCode("{0} = {1}.result; offset = {1}.offset;",t,r),this.options.type!==this.alias&&e.addReference(this.options.type);}},d.prototype.generateFormatter=function(e,t,r){"function"==typeof r&&e.pushCode("{0} = ({1}).call(this, {0});",t,r);},d.prototype.isInteger=function(){return !!this.type.match(/U?Int[8|16|32][BE|LE]?|Bit\d+/)},d.prototype.itf8=function(e,t){return this.setNextParser("itf8",e,t)},d.prototype.itf8=function(e,t){return this.setNextParser("itf8",e,t)},d.prototype.generateItf8=function(e){var t=e.generateVariable(this.varName),r=e.generateTmpVariable();e.pushCode("\n var ".concat(r," = buffer[offset];\n if (").concat(r," < 0x80) {\n ").concat(t," = ").concat(r,";\n offset += 1;\n } else if (").concat(r," < 0xc0) {\n ").concat(t," = ((").concat(r,"<<8) | buffer[offset+1]) & 0x3fff;\n offset += 2;\n } else if (").concat(r," < 0xe0) {\n ").concat(t," = ((").concat(r,"<<16) | (buffer[offset+1]<< 8) | buffer[offset+2]) & 0x1fffff;\n offset += 3;\n } else if (").concat(r," < 0xf0) {\n ").concat(t," = ((").concat(r,"<<24) | (buffer[offset+1]<<16) | (buffer[offset+2]<<8) | buffer[offset+3]) & 0x0fffffff;\n offset += 4\n } else {\n ").concat(t," = ((").concat(r," & 0x0f)<<28) | (buffer[offset+1]<<20) | (buffer[offset+2]<<12) | (buffer[offset+3]<<4) | (buffer[offset+4] & 0x0f);\n // x=((0xff & 0x0f)<<28) | (0xff<<20) | (0xff<<12) | (0xff<<4) | (0x0f & 0x0f);\n // TODO *val_p = uv < 0x80000000UL ? uv : -((int32_t) (0xffffffffUL - uv)) - 1;\n offset += 5\n }\n "));},d.prototype.ltf8=function(e,t){return this.setNextParser("ltf8",e,t)},d.prototype.generateLtf8=function(e){var t=e.generateVariable(this.varName),r=e.generateTmpVariable();e.pushCode("\n var ".concat(r," = buffer[offset];\n if (").concat(r," < 0x80) {\n ").concat(t," = ").concat(r,";\n offset += 1;\n } else if (").concat(r," < 0xc0) {\n ").concat(t," = ((buffer[offset]<<8) | buffer[offset+1]) & 0x3fff;\n offset += 2;\n } else if (").concat(r," < 0xe0) {\n ").concat(t," = ((buffer[offset]<<16) | (buffer[offset+1]<<8) | buffer[offset+2]) & 0x1fffff;\n ").concat(t," = (((").concat(r," & 63) << 16) | buffer.readUInt16LE(offset + 1));\n offset += 3;\n } else if (").concat(r," < 0xf0) {\n ").concat(t," = ((buffer[offset]<<24) | (buffer[offset+1]<<16) | (buffer[offset+2]<<8) | buffer[offset+3]) & 0x0fffffff;\n offset += 4;\n } else if (").concat(r," < 0xf8) {\n ").concat(t," = (((buffer[offset] & 15) * Math.pow(2,32))) +\n (buffer[offset+1]<<24) | (buffer[offset+2]<<16 | buffer[offset+3]<<8 | buffer[offset+4])\n // TODO *val_p = uv < 0x80000000UL ? uv : -((int32_t) (0xffffffffUL - uv)) - 1;\n offset += 5;\n } else if (").concat(r," < 0xfc) {\n ").concat(t," = ((((buffer[offset] & 7) << 8) | buffer[offset+1] )) * Math.pow(2,32) +\n (buffer[offset+2]<<24) | (buffer[offset+3]<<16 | buffer[offset+4]<<8 | buffer[offset+5])\n offset += 6;\n } else if (").concat(r," < 0xfe) {\n ").concat(t," = ((((buffer[offset] & 3) << 16) | buffer[offset+1]<<8 | buffer[offset+2])) * Math.pow(2,32) +\n (buffer[offset+3]<<24) | (buffer[offset+4]<<16 | buffer[offset+5]<<8 | buffer[offset+6])\n offset += 7;\n } else if (").concat(r," < 0xff) {\n ").concat(t," = Long.fromBytesBE(buffer.slice(offset+1,offset+8));\n if (").concat(t,".greaterThan(Number.MAX_SAFE_INTEGER) || ").concat(t,".lessThan(Number.MIN_SAFE_INTEGER))\n throw new Error('integer overflow')\n ").concat(t," = ").concat(t,".toNumber()\n offset += 8;\n } else {\n ").concat(t," = Long.fromBytesBE(buffer.slice(offset+1,offset+9));\n if (").concat(t,".greaterThan(Number.MAX_SAFE_INTEGER) || ").concat(t,".lessThan(Number.MIN_SAFE_INTEGER))\n throw new Error('integer overflow')\n ").concat(t," = ").concat(t,".toNumber()\n offset += 9;\n }\n "));},t.Parser=d;},2961:(e,t)=>{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},r(e)}var n=function(){this.code="",this.scopes=[["vars"]],this.isAsync=!1,this.bitFields=[],this.tmpVariableCount=0,this.references={};};n.prototype.generateVariable=function(e){var t=[];for(Array.prototype.push.apply(t,this.scopes[this.scopes.length-1]);/^\$parent\./.test(e);)t.pop(),e=e.replace(/^\$parent\./,"");return e&&t.push(e),t.join(".")},n.prototype.generateOption=function(e){switch(r(e)){case"number":return e.toString();case"string":return this.generateVariable(e);case"function":return "(".concat(e,").call(").concat(this.generateVariable(),", vars)");default:return}},n.prototype.generateError=function(){var e=Array.prototype.slice.call(arguments),t=n.interpolate.apply(this,e);this.isAsync?this.pushCode("return process.nextTick(function() { callback(new Error(".concat(t,"), vars); });")):this.pushCode("throw new Error(".concat(t,");"));},n.prototype.generateTmpVariable=function(){return "$tmp".concat(this.tmpVariableCount++)},n.prototype.pushCode=function(){var e=Array.prototype.slice.call(arguments);this.code+="".concat(n.interpolate.apply(this,e),"\n");},n.prototype.pushPath=function(e){e&&this.scopes[this.scopes.length-1].push(e);},n.prototype.popPath=function(e){e&&this.scopes[this.scopes.length-1].pop();},n.prototype.pushScope=function(e){this.scopes.push([e]);},n.prototype.popScope=function(){this.scopes.pop();},n.prototype.addReference=function(e){this.references[e]||(this.references[e]={resolved:!1,requested:!1});},n.prototype.markResolved=function(e){this.references[e].resolved=!0;},n.prototype.markRequested=function(e){e.forEach(function(e){this.references[e].requested=!0;}.bind(this));},n.prototype.getUnresolvedReferences=function(){var e=this.references;return Object.keys(this.references).filter((function(t){return !e[t].resolved&&!e[t].requested}))},n.interpolate=function(e){var t=/{\d+}/g,r=e.match(t),n=Array.prototype.slice.call(arguments,1);return r&&r.forEach((function(t){var r=parseInt(t.substr(1,t.length-2),10);e=e.replace(t,n[r].toString());})),e},t._=n;},22:e=>{e.exports.runInThisContext=function(e){return new Function("code","return eval(code);").call(globalThis,e)};},445:(e,t,r)=>{const n=r(7381),i=r(9260),o=r(576),s=r(4693),a=128;e.exports=class{decode(e){return this.stream=new i(e),this.decodeStream(this.stream)}decodeStream(e,t=0){var r=this.stream.ReadByte();16&r||(t=this.stream.ReadUint7());var n,i=t,o=1&r;if(8&r)return this.decodeStripe(this.stream,t);if(r&a&&([n,i]=this.decodePackMeta(this.stream)),32&r)var s=this.decodeCat(this.stream,i);else s=4&r?this.decodeExt(this.stream,i):64&r?o?this.decodeRLE1(this.stream,i):this.decodeRLE0(this.stream,i):o?this.decode1(this.stream,i):this.decode0(this.stream,i);return r&a&&(s=this.decodePack(s,n,t)),s}encode(e,t){if(this.stream=new i("",0,1.1*e.length+100),this.stream.WriteByte(t),16&t||this.stream.WriteUint7(e.length),8&t)return Buffer.concat([this.stream.buf.slice(0,this.stream.pos),this.encodeStripe(this.stream,e,t>>8)]);var r,n=1&t,o=e.length;return t&a&&([r,e,o]=this.encodePack(e)),t&a&&this.stream.WriteStream(r),64&t?n?this.encodeRLE1(e,o,this.stream):this.encodeRLE0(e,o,this.stream):n?this.encode1(e,o,this.stream):this.encode0(e,o,this.stream)}decode0(e,t){var r=new Buffer.allocUnsafe(t),i=e.ReadByte();0==i&&(i=256);var s=new o(i),a=new n(e);a.RangeStartDecode(e);for(var f=0;f=3?3:l;for(f[u].ModelEncode(r,h,c),l-=c,u=256;3==c;)c=l>=3?3:l,f[u].ModelEncode(r,h,c),u=257,l-=c;}return h.RangeFinishEncode(r),r.buf.slice(0,r.pos)}decodeRLE1(e,t){var r=new Buffer.allocUnsafe(t),i=e.ReadByte();0==i&&(i=256);for(var s=new Array(i),a=0;a=3?3:u;for(f[c].ModelEncode(r,h,d),u-=d,c=256;3==d;)d=u>=3?3:u,f[c].ModelEncode(r,h,d),c=257,u-=d;}return h.RangeFinishEncode(r),r.buf.slice(0,r.pos)}decodePackMeta(e){this.nsym=e.ReadByte();for(var t=new Array(this.nsym),r=0;r>=1;}}else if(this.nsym<=4)for(i=0,o=0;i>=2;else {if(!(this.nsym<=16))return e;for(i=0,o=0;i>=4;}return n}packMeta(e){for(var t=new i("",0,1024),r=new Array(256),n=0;ns),n[s]=new Array(o[s]);for(var a=0,f=0;fo),s[o]=this.decodeStream(e,i[o]);var a=new Buffer.allocUnsafe(t);for(o=0;o{e.exports=class{constructor(e){this.low=0,this.range=4294967295,this.code=0,this.FFnum=0,this.carry=0,this.cache=0;}RangeStartDecode(e){for(var t=0;t<5;t++)this.code=(this.code<<8)+e.ReadByte();this.code&=4294967295,this.code>>>=0;}RangeGetFrequency(e){return this.range=Math.floor(this.range/e),Math.floor(this.code/this.range)}RangeDecode(e,t,r,n){for(this.code-=t*this.range,this.range*=r;this.range<1<<24;)this.range*=256,this.code=256*this.code+e.ReadByte();}RangeShiftLow(e){if(this.low<4278190080|this.carry){for(e.WriteByte(this.cache+this.carry);this.FFnum;)e.WriteByte(this.carry-1),this.FFnum--;this.cache=this.low>>>24,this.carry=0;}else this.FFnum++;this.low<<=8,this.low>>>=0;}RangeEncode(e,t,r,n){var i=this.low;for(this.range=Math.floor(this.range/n),this.low+=t*this.range,this.low>>>=0,this.range*=r,this.low{e.exports=class{constructor(e=256){this.total_freq=e,this.max_sym=e-1,this.S=new Array,this.F=new Array;for(var t=0;t<=this.max_sym;t++)this.S[t]=t,this.F[t]=1;}ModelDecode(e,t){for(var r=t.RangeGetFrequency(this.total_freq),n=0,i=0;n+this.F[i]<=r;)n+=this.F[i++];t.RangeDecode(e,n,this.F[i],this.total_freq),this.F[i]+=16,this.total_freq+=16,this.total_freq>65519&&this.ModelRenormalise();var o=this.S[i];if(i>0&&this.F[i]>this.F[i-1]){var s=this.F[i];this.F[i]=this.F[i-1],this.F[i-1]=s,s=this.S[i],this.S[i]=this.S[i-1],this.S[i-1]=s;}return o}ModelRenormalise(){this.total_freq=0;for(var e=0;e<=this.max_sym;e++)this.F[e]-=Math.floor(this.F[e]/2),this.total_freq+=this.F[e];}ModelEncode(e,t,r){for(var n=0,i=0;this.S[i]!=r;i++)n+=this.F[i];if(t.RangeEncode(e,n,this.F[i],this.total_freq),this.F[i]+=16,this.total_freq+=16,this.total_freq>65519&&this.ModelRenormalise(),r=this.S[i],i>0&&this.F[i]>this.F[i-1]){var o=this.F[i];this.F[i]=this.F[i-1],this.F[i-1]=o,o=this.S[i],this.S[i]=this.S[i-1],this.S[i-1]=o;}}};},5260:(e,t,r)=>{const n=r(9260),i=r(576),o=r(7381);function s(e,t,r){for(var n=0,i=0,o=-1,s=new Array(1024);i>4,t.qshift=15&r,r=e.ReadByte(),t.qloc=r>>4,t.sloc=15&r,r=e.ReadByte(),t.ploc=r>>4,t.dloc=15&r,t.qmap=new Array(256),16&t.pflags)for(var n=0;n0&&128&t.pflags)s(e,t.qtab,256);else for(n=0;n<256;n++)t.qtab[n]=n;return t.ptab=new Array(1024),32&t.pflags&&s(e,t.ptab,1024),t.dtab=new Array(256),64&t.pflags&&s(e,t.dtab,256),t}function h(e,t,r,n,i,o){r.max_sel>0?i.s=n.sel.ModelDecode(e,t):i.s=0,i.x=r.stab[i.s];var s=r.params[i.x];if(s.fixed_len>=0){var a=n.len[0].ModelDecode(e,t);a|=n.len[1].ModelDecode(e,t)<<8,a|=n.len[2].ModelDecode(e,t)<<16,a|=n.len[3].ModelDecode(e,t)<<24,s.fixed_len>0&&(s.fixed_len=-a);}else a=-s.fixed_len;i.len=a,r.do_rev&&(o[i.rec]=n.rev.ModelDecode(e,t)),i.is_dup=0,2&s.pflags&&n.dup.ModelDecode(e,t)&&(i.is_dup=1),i.p=a,i.delta=0,i.qctx=0,i.prevq=0,i.rec++;}function l(e,t,r){for(var n=0,i=0,o=new Array(2*r),s=0;n1?r.nparam-1:0,o=new Array(256);if(2&r)i=e.ReadByte(),s(e,o,256);else {for(var a=0;a0&&(t.sel=new i(e.max_sel+1)),t}(n),d=new o(e);d.RangeStartDecode(e);for(var p=new Buffer.allocUnsafe(r),g={qctx:0,prevq:0,delta:0,p:0,s:0,x:0,len:0,is_dup:0,rec:0},m=0;m0&&c.dup.ModelDecode(e,d)){for(var y=0;y4),qshift:u,qloc:7,pbits:7,pshift:t[0]>128?1:0,ploc:0,dbits:u>4?0:1,dshift:3,dloc:15,sbits:0,sloc:15,do_stab:0,context:0,max_sym:f,nsym:a,do_qmap:c,do_dedup:0,fixed_len:1==t.length?1:0,do_sel:0,do_rev:0,do_pos:1,do_delta:u<=4?1:0,do_qtab:0,qbits:8+(u>4)-(0==s),sbits:1,sloc:15-(u<=4),do_stab:1,do_sel:1}]}(e,t,r,s),p=function(e,t,r,n,i,o,s){for(var a=[0,1,1,1,2,2,2,2,2,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7],f=0;f1?1:0)|(t[0].do_stab?2:0);if(e.WriteByte(h),1&h&&e.WriteByte(t.length),2&h){var u=1<0&&u--,e.WriteByte(u),l(e,s,256);}for(var c=0;c0){for(f=0;f<256;f++)n[c][f]=f;t[c].do_qtab&&l(e,n[c],256);}if(t[c].pbits>0){for(f=0;f<1024;f++)i[c][f]=Math.min((1<>t[c].pshift);l(e,i[c],1024);}if(t[c].dbits>0){for(f=0;f<256;f++)a[f]>(1<>t[c].dshift)];l(e,o[c],256);}}return e}(p,d,s,a,f,h,u);return function(e,t,r,n,s,a,f,h,l,u){var c=1<0&&c--;for(var d=t.length,p=0,g=0;g0&&v.ModelEncode(e,w,B);var E=u[B],S=r[Math.min(r.length-1,_++)];s[E].fixed_len?s[E].fixed_len>0&&(b[0].ModelEncode(e,w,255&S),b[1].ModelEncode(e,w,S>>8&255),b[2].ModelEncode(e,w,S>>16&255),b[3].ModelEncode(e,w,S>>24&255),s[E].fixed_len=-1):(b[0].ModelEncode(e,w,255&S),b[1].ModelEncode(e,w,S>>8&255),b[2].ModelEncode(e,w,S>>16&255),b[3].ModelEncode(e,w,S>>24&255)),s[E].do_dedup&&process.exit(1),g=S;var A=0,C=s[E].context,R=0,k=0;}var x=t[y++],I=a[E][x];m[C].ModelEncode(e,w,I),R=(R<0&&(C+=h[E][Math.min(g,1023)]<0&&(C+=l[E][Math.min(A,255)]<{var n=r(4459),i=r(594),o=r(445),s=r(5260),a=r(2881);e.exports={r4x8_uncompress:function(e,t){n.decode(e).copy(t,0,0);},r4x16_uncompress:function(e,t){i.decode(e).copy(t,0,0);},arith_uncompress:function(e,t){o.decode(e).copy(t,0,0);},fqzcomp_uncompress:function(e,t){var r=new Array;s.decode(e,r).copy(t,0,0);},tok3_uncompress:function(e,t){var r=a.decode(e,0,"\0");Buffer.from(r,"binary").copy(t,0,0);}};},9260:e=>{e.exports=class{constructor(e,t=0,r=0){0!=r?(this.buf=Buffer.allocUnsafe(r),this.length=r):(this.buf=e,this.length=e.length),this.pos=t;}EOF(){return this.pos>=this.length}ReadData(e){var t=this.buf.slice(this.pos,this.pos+e);return this.pos+=e,t}ReadByte(){const e=this.buf[this.pos];return this.pos++,e}ReadChar(){const e=this.buf[this.pos];return this.pos++,String.fromCharCode(e)}ReadUint16(){return this.ReadByte()|this.ReadByte()<<8}ReadUint32(){const e=this.buf.readInt32LE(this.pos);return this.pos+=4,e}ReadString(){var e="";do{var t=this.buf[this.pos++];t&&(e+=String.fromCharCode(t));}while(t);return e}ReadUint7(){var e=0;do{var t=this.ReadByte();e=e<<7|127&t;}while(128&t);return e}ReadITF8(){var e=this.buf[this.pos];return this.pos++,e>=240?(e=(15&e)<<28,e+=(this.buf[this.pos+0]<<20)+(this.buf[this.pos+1]<<12)+(this.buf[this.pos+2]<<4)+(this.buf[this.pos+3]>>4),this.pos+=4):e>=224?(e=(15&e)<<24,e+=(this.buf[this.pos+0]<<16)+(this.buf[this.pos+1]<<8)+(this.buf[this.pos+2]<<0),this.pos+=3):e>=192?(e=(31&e)<<16,e+=(this.buf[this.pos+0]<<8)+(this.buf[this.pos+1]<<0),this.pos+=2):e>=128&&(e=(63&e)<<8,e+=this.buf[this.pos],this.pos++),e}WriteByte(e){this.buf[this.pos++]=e;}WriteChar(e){this.buf[this.pos++]=e.charCodeAt(0);}WriteString(e){for(var t=0;t>8&255);}WriteUint32(e){this.buf.writeInt32LE(e,this.pos),this.pos+=4;}WriteUint7(e){var t=0,r=e;do{t+=7,r>>=7;}while(r>0);do{t-=7,this.WriteByte((e>>t&127)+((t>0)<<7));}while(t>0)}WriteITF8(e){e<0&&(e=1+e),e<=127?this.buf[this.pos++]=e:e<=16383?(this.buf[this.pos++]=128|Math.floor(e/256),this.buf[this.pos++]=255&e):e<131071?(this.buf[this.pos++]=192|Math.floor(e/65536),this.buf[this.pos++]=255&Math.floor(e/256),this.buf[this.pos++]=255&e):e<268435455?(this.buf[this.pos++]=224|Math.floor(e/16777216),this.buf[this.pos++]=255&Math.floor(e/65536),this.buf[this.pos++]=255&Math.floor(e/256),this.buf[this.pos++]=255&e):(this.buf[this.pos++]=240|Math.floor(e/268435456),this.buf[this.pos++]=255&Math.floor(e/1048576),this.buf[this.pos++]=255&Math.floor(e/4096),this.buf[this.pos++]=255&Math.floor(e/4),this.buf[this.pos++]=15&e);}WriteByteNeg(e){this.buf[--this.pos]=e;}};},4459:(e,t,r)=>{const n=r(9260);function i(e){return 4095&e}function o(e,t){for(var r=0;t>=e[r+1];)r++;return r}function s(e){for(var t=new Array(4096),r=0,n=0;n<4096;n++){for(;n>=e[r+1];)r++;t[n]=r;}return t}function a(e,t,r){return r*(e>>12)+(4095&e)-t}function f(e,t){for(;t<1<<23;)t=(t<<8)+e.ReadByte();return t}function h(e,t){t.WriteByteNeg(e>>24&255),t.WriteByteNeg(e>>16&255),t.WriteByteNeg(e>>8&255),t.WriteByteNeg(e>>0&255);}function l(e,t,r,n,i){return e=function(e,t,r,n){for(var i=(1<<23>>n<<8)*r;e>=i;)t.WriteByteNeg(255&e),e>>=8;return e}(e,t,n,i),(Math.floor(e/n)<0?(s--,i++):(i=e.ReadByte())==o+1&&(s=e.ReadByte()),o=i;}while(0!=i);for(r[0]=0,n=0;n<=255;n++)r[n+1]=r[n]+t[n];}function c(e){for(var t=0,r=0;r<256;r++)t+=e[r];const n=4096;var i=n/t;do{var o=0,s=0,a=0;for(t=0,r=0;r<256;r++)0!=e[r]&&(o2?e[s]-=t-n:t!=n&&(i*=.99,a=1);}while(a)}function d(e,t){for(var r=0,n=0;n<256;n++)if(t[n]){if(r>0)r--;else if(e.WriteByte(n),n>0&&t[n-1]>0){for(r=n+1;r<256&&t[r];r++);r-=n+1,e.WriteByte(r);}e.WriteITF8(t[n]);}e.WriteByte(0);}e.exports={decode:function(e){var t=new n(e),r=t.ReadByte(),h=(t.ReadUint32(),t.ReadUint32());return 0==r?function(e,t){var r=new Array(256),n=new Array(256);u(e,r,n);for(var o=s(n),h=new Array(4),l=0;l<4;l++)h[l]=e.ReadUint32();var c=new Buffer.allocUnsafe(t);for(l=0;l0?(a--,o++):(o=e.ReadByte())==s+1&&(a=e.ReadByte()),s=o;}while(0!=o)}(e,r,n);for(var h=new Array(256),l=0;l<256;l++)h[l]=s(n[l]);for(var c=new Array(4),d=new Array(4),p=0;p<4;p++)c[p]=e.ReadUint32(),d[p]=0;var g=new Buffer.allocUnsafe(t),m=Math.floor(t/4);for(l=0;l=0;s--)a[s%4]=l(a[s%4],u,o[e[s]],i[e[s]],12);for(s=3;s>=0;s--)h(a[s],u);var p=r.pos;return r.buf.writeInt32LE(p-9+(u.length-u.pos),1),r.buf.writeInt32LE(t,5),Buffer.concat([r.buf.slice(0,r.pos),u.buf.slice(u.pos,u.length)],r.pos+u.length-u.pos)}(e):function(e){const t=e.length;var r=new n("",0,198156);r.WriteByte(1),r.WriteUint32(0),r.WriteUint32(0);for(var i=new Array(256),o=new Array(256),s=new Array(256),a=0;a<256;a++)o[a]=new Array(256),s[a]=new Array(256);for(function(e,t,r){for(var n=0;n<256;n++){r[n]=0;for(var i=0;i<256;i++)t[n][i]=0;}var o=0;for(n=0;n>2)]]++,t[0][e[2*(e.length>>2)]]++,t[0][e[3*(e.length>>2)]]++,r[0]+=3;}(e,o,i),function(e,t){for(var r=0;r<256;r++)t[r]&&c(e[r]);}(o,i),function(e,t,r){for(var n=0,i=0;i<256;i++)if(r[i]){if(n>0)n--;else if(e.WriteByte(i),i>0&&r[i-1]>0){for(n=i+1;n<256&&r[n];n++);n-=i+1,e.WriteByte(n);}d(e,t[i]);}e.WriteByte(0);}(r,o,i),a=0;a<256;a++)if(i[a]){s[a][0]=0;for(var f=1;f<256;f++)s[a][f]=s[a][f-1]+o[a][f-1];}var u=new Array(4),p=new Array(4);for(f=0;f<4;f++)u[f]=1<<23,p[f]=0;var g=new n("",t,t),m=Math.floor(t/4),y=new Array(4),b=new Array(4);for(f=0;f<4;f++)y[f]=(f+1)*m-2,b[f]=e[y[f]+1];for(b[3]=e[t-1],a=t-2;a>4*m-2;a--)u[3]=l(u[3],g,s[e[a]][b[3]],o[e[a]][b[3]],12),b[3]=e[a];for(;y[0]>=0;)for(f=3;f>=0;f--){var v=e[y[f]];u[f]=l(u[f],g,s[v][b[f]],o[v][b[f]],12),b[f]=v,y[f]--;}for(f=3;f>=0;f--)u[f]=l(u[f],g,s[0][b[f]],o[0][b[f]],12);for(a=3;a>=0;a--)h(u[a],g);var w=r.pos;return r.buf.writeInt32LE(w-9+(g.length-g.pos),1),r.buf.writeInt32LE(t,5),Buffer.concat([r.buf.slice(0,r.pos),g.buf.slice(g.pos,g.length)],r.pos+g.length-g.pos)}(e)}};},594:(e,t,r)=>{const n=r(9260);function i(e,t){return e&(1<=e[r+1];)r++;return r}function s(e,t){for(var r=1<=e[i+1];)i++;n[o]=i;}return n}function a(e,t,r,n){return r*(e>>n)+(e&(1<>24&255),t.WriteByteNeg(e>>16&255),t.WriteByteNeg(e>>8&255),t.WriteByteNeg(e>>0&255);}function l(e,t,r,n,i){return e=function(e,t,r,n){for(var i=(1<<31-n)*r;e>=i;)t.WriteByteNeg(e>>8&255),t.WriteByteNeg(255&e),e>>=16;return e}(e,t,n,i),(Math.floor(e/n)<s),i[s]=new Array(o[s]);for(var a=0,f=0;fo),s[o]=c(e,i[o]);var a=new Buffer.allocUnsafe(t);for(o=0;o>4,h=e;if(1&c){var l=e.ReadUint7(),u=e.ReadUint7(),c=new n(e.ReadData(u));h=new n(g(c,l));}var d=new Array(256),m=new Array(256);!function(e,t,r,n){for(var i=0;i<256;i++){t[i]=new Array(256),r[i]=new Array(256);for(var o=0;o<256;o++)t[i][o]=0;}var s=p(e);for(i=0;i<256;i++)if(s[i]){var a=0;for(o=0;o<256;o++)s[o]&&(a>0?a--:(t[i][o]=e.ReadUint7(),0==t[i][o]&&(a=e.ReadByte())));for(y(t[i],n),r[i][0]=0,o=0;o<256;o++)r[i][o+1]=r[i][o]+t[i][o];}}(h,d,m,r);for(var b=new Array(256),v=0;v<256;v++)b[v]=s(m[v],r);for(var w=new Array(4),_=new Array(4),B=0;B<4;B++)w[B]=e.ReadUint32(),_[B]=0;var E=new Buffer.allocUnsafe(t),S=Math.floor(t/4);for(v=0;v>=1;}else if(r<=4)for(s=0;s>=2;else if(r<=16)for(s=0;s>=4;return i}(S,v,w,b)),S}function d(e,t){var r=new n("",0,10);r.WriteByte(t);var i=1&t,o=8&t,s=32&t,a=64&t,f=128&t,c=t>>8;if(16&t||r.WriteUint7(e.length),o)return Buffer.concat([r.buf.slice(0,r.pos),u(0,e,c)]);var d=new Buffer.alloc(0);f&&([d,e]=function(e){for(var t=new Array(256),r=0;r<256;r++)t[r]=0;for(r=0;r0&&(i[r]=o++);if(!(o>16)){if(o<=1)var s=new Buffer.allocUnsafe(0);else if(o<=2){s=new Buffer.allocUnsafe(Math.ceil(e.length/8));var a=-1;for(r=0;r0&&(t[r]=a++,f.WriteByte(r));return f.WriteUint7(s.length),[f.buf.slice(0,f.pos),s]}}(e));var p=new Buffer.alloc(0);if(a&&([p,e]=function(e){for(var t=new Array(256),r=0;r<256;r++)t[r]=0;var i=-1;for(r=0;r0&&o++;for(o||(o=1,t[0]=1),(h=new n("",0,o+1+e.length)).WriteByte(o),r=0;r<256;r++)t[r]>0&&h.WriteByte(r);var s=new Buffer.allocUnsafe(e.length),a=0;for(r=0;r0){i=e[r];for(var f=0;r+f+1>2)]]++,t[0][e[2*(e.length>>2)]]++,t[0][e[3*(e.length>>2)]]++,r[0]+=3;})))(e,o,i),function(e,t,r){for(var n=0;n<256;n++)if(t[n]){var i=Math.ceil(Math.log2(t[n]));i>12&&(i=12),m(e[n],i);}}(o,i);var u=new n("",0,198156);!function(e,t,r){b(e,r);for(var n=0;n<256;n++)if(r[n])for(var i=0,o=0;o<256;o++)if(r[o])if(i)i--;else if(e.WriteUint7(t[n][o]),!t[n][o]){for(var s=o+1;s<256;s++)if(r[s]){if(0!=t[n][s])break;i++;}e.WriteByte(i);}}(u,o,i);var c=v(u.buf.slice(0,u.pos));for(c.length>0,1.05*t+100>>0),_=Math.floor(t/4),B=new Array(4),E=new Array(4);for(d=0;d<4;d++)B[d]=(d+1)*_-2,E[d]=e[B[d]+1];for(E[3]=e[t-1],a=t-2;a>4*_-2;a--)p[3]=l(p[3],w,s[e[a]][E[3]],o[e[a]][E[3]],f),E[3]=e[a];for(;B[0]>=0;)for(d=3;d>=0;d--){var S=e[B[d]];p[d]=l(p[d],w,s[S][E[d]],o[S][E[d]],f),E[d]=S,B[d]--;}for(d=3;d>=0;d--)p[d]=l(p[d],w,s[0][E[d]],o[0][E[d]],f);for(a=3;a>=0;a--)h(p[a],w);return Buffer.concat([r.buf.slice(0,r.pos),w.buf.slice(w.pos,w.length)],r.pos+w.length-w.pos)}(e);return Buffer.concat([r.buf.slice(0,r.pos),d,p,g])}function p(e){for(var t=new Array(256),r=0;r<256;r++)t[r]=0;var n=0,i=e.ReadByte(),o=i;do{t[i]=1,n>0?(n--,i++):(i=e.ReadByte())==o+1&&(n=e.ReadByte()),o=i;}while(0!=i);return t}function g(e,t){var r=new Array(256),n=new Array(256);!function(e,t,r){for(var n=0;n<256;n++)t[n]=0;var i=p(e);for(n=0;n<256;n++)i[n]>0&&(t[n]=e.ReadUint7());for(y(t,12),r[0]=0,n=0;n<=255;n++)r[n+1]=r[n]+t[n];}(e,r,n);for(var o=s(n,12),h=new Array(4),l=0;l<4;l++)h[l]=e.ReadUint32();var u=new Buffer.allocUnsafe(t);for(l=0;l2?e[a]-=r-i:r!=i&&(o=i/r,f=1);}while(f)}function y(e,t){for(var r=0,n=0;n<256;n++)r+=e[n];if(0!=r&&r!=1<0)r--;else if(e.WriteByte(n),n>0&&t[n-1]>0){for(r=n+1;r<256&&t[r];r++);r-=n+1,e.WriteByte(r);}e.WriteByte(0);}function v(e){const t=e.length;var r=new n("",0,780),i=new Array(256);!function(e,t){for(var r=0;r<256;r++)t[r]=0;for(r=0;r12&&(o=12),m(i,o),function(e,t){b(e,t);for(var r=0;r<256;r++)t[r]&&e.WriteUint7(t[r]);}(r,i),m(i,12);var s=new Array(256);s[0]=0;for(var a=1;a<256;a++)s[a]=s[a-1]+i[a-1];var f=new Array(4);for(a=0;a<4;a++)f[a]=32768;var u=new n("",1.05*t+100>>0,1.05*t+100>>0);for(a=t-1;a>=0;a--)f[a%4]=l(f[a%4],u,s[e[a]],i[e[a]],12);for(a=3;a>=0;a--)h(f[a],u);return Buffer.concat([r.buf.slice(0,r.pos),u.buf.slice(u.pos,u.length)],r.pos+u.length-u.pos)}e.exports={decode:function(e){return c(new n(e),0)},encode:d};},2881:(e,t,r)=>{const n=r(9260),i=r(594);var o=new(r(445));function s(e,t){for(var r=e+"";r.length>0)+e[a][8].ReadByte();break;case 9:f=(r[o][a]>>0)+e[a][9].ReadByte(),h=r[o][a].length,r[n][a]=s(f,h);break;case 10:r[n][a]=r[o][a];break;default:r[n][a]="";}t[n]+=r[n][a++];}while(12!=i);return t[n]}function f(e,t,r,n,i,o){for(var s=0;s0&&5==t[s][0].type)&&t[s][r])switch(e[0].WriteByte(t[s][r].type),t[s][r].type){case 6:e[6].WriteUint32(t[s][r].val);break;case 5:e[5].WriteUint32(t[s][r].val);break;case 1:e[1].WriteString(t[s][r].val);break;case 2:e[2].WriteChar(t[s][r].val);break;case 7:e[7].WriteUint32(t[s][r].val);break;case 3:e[3].WriteUint32(t[s][r].val),e[4].WriteByte(t[s][r].val.length);break;case 8:case 9:e[t[s][r].type].WriteByte(t[s][r].val);}}function h(e,t,r,n){for(var i=0;i<=12;i++)if(!(e[i].pos<=0)){n.WriteByte(i+(0==i?128:0)),e[i]=e[i].buf.slice(0,e[i].pos);var o=l(e[i],r);n.WriteUint7(o.length),n.WriteData(o,o.length);}}function l(e,t){var r,n=1<<30,s=[0,1,64,65,128,129,201];for(var a in s){var f=s[a];if(!(1&f&&e.length<100||8&f&&e.length%4!=0)){try{var h=t?o.encode(e,f):i.encode(e,f);}catch(e){h=0;}h&&n>h.length&&(n=h.length,r=h);}}return r}function u(e,t,r,n,i){var o=0,s=i-1;e[i]=new Array(256),t[n]?e[i][0]={type:5,val:i-t[n]}:e[i][0]={type:6,val:0==i?0:1},t[n]=i;for(var a=n.match(/([a-zA-Z0-9]{1,9})|([^a-zA-Z0-9]+)/g),f=0;f=0&&e[s][h])if(e[s][h].str==a[f])l=10,u="";else if(7==e[s][h].type||8==e[s][h].type){var c=u-e[s][h].str;r[h]++,c>=0&&c<256&&r[h]>i/2&&(l=8,u=c);}else 3!=e[s][h].type&&9!=e[s][h].type||e[s][h].str.length!=u.length||(c=u-e[s][h].str,r[h]++,c>=0&&c<256&&r[h]>i/2&&(l=9,u=c));e[i][h]={str:a[f],val:u,type:l},o{a.callback(e);})),settled:!1,statusReporter:a,get aborted(){return this.aborter.signal.aborted}};f.aborter.addSignal(r),f.aborter.signal.addEventListener("abort",(()=>{f.settled||this.evict(e,f);})),f.promise.then((()=>{f.settled=!0;}),(()=>{f.settled=!0,this.evict(e,f);})).catch((e=>{throw console.error(e),e})),this.cache.set(e,f);}static checkSinglePromise(e,t){function r(){if(t&&t.aborted)throw Object.assign(new Error("aborted"),{code:"ERR_ABORTED"})}return e.then((e=>(r(),e)),(e=>{throw r(),e}))}has(e){return this.cache.has(e)}get(e,t,r,n){if(!r&&t instanceof i.AbortSignal)throw new TypeError("second get argument appears to be an AbortSignal, perhaps you meant to pass `null` for the fill data?");const o=this.cache.get(e);return o?o.aborted&&!o.settled?(this.evict(e,o),this.get(e,t,r,n)):o.settled?o.promise:(o.aborter.addSignal(r),o.statusReporter.addCallback(n),a.checkSinglePromise(o.promise,r)):(this.fill(e,t,r,n),a.checkSinglePromise(this.cache.get(e).promise,r))}delete(e){const t=this.cache.get(e);t&&(t.settled||t.aborter.abort(),this.cache.delete(e));}clear(){const e=this.cache.keys();let t=0;for(let r=e.next();!r.done;r=e.next())this.delete(r.value),t+=1;return t}}t.default=a;},9049:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:!0});const n=r(8904);class i{}t.default=class{constructor(){this.signals=new Set,this.abortController=new n.AbortController;}addSignal(e=new i){if(this.signal.aborted)throw new Error("cannot add a signal, already aborted!");this.signals.add(e),e.aborted?this.handleAborted(e):"function"==typeof e.addEventListener&&e.addEventListener("abort",(()=>{this.handleAborted(e);}));}handleAborted(e){this.signals.delete(e),0===this.signals.size&&this.abortController.abort();}get signal(){return this.abortController.signal}abort(){this.abortController.abort();}};},450:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.default=class{constructor(){this.callbacks=new Set;}addCallback(e=(()=>{})){this.callbacks.add(e),e(this.currentMessage);}callback(e){this.currentMessage=e,this.callbacks.forEach((t=>{t(e);}));}};},8904:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.AbortSignal=t.AbortController=void 0;const n=r(5988);var i=function(){if("undefined"!=typeof self)return self;if("undefined"!=typeof window)return window;if(void 0!==r.g)return r.g;throw new Error("unable to locate global object")};let o=void 0===i().AbortController?n.AbortController:i().AbortController;t.AbortController=o;let s=void 0===i().AbortController?n.AbortSignal:i().AbortSignal;t.AbortSignal=s;},4105:function(e,t,r){var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const i=n(r(1422));t.default=i.default;},5988:(e,t)=>{function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function n(e,t){for(var r=0;r{t.byteLength=function(e){var t=f(e),r=t[0],n=t[1];return 3*(r+n)/4-n},t.toByteArray=function(e){var t,r,o=f(e),s=o[0],a=o[1],h=new i(function(e,t,r){return 3*(t+r)/4-r}(0,s,a)),l=0,u=a>0?s-4:s;for(r=0;r>16&255,h[l++]=t>>8&255,h[l++]=255&t;return 2===a&&(t=n[e.charCodeAt(r)]<<2|n[e.charCodeAt(r+1)]>>4,h[l++]=255&t),1===a&&(t=n[e.charCodeAt(r)]<<10|n[e.charCodeAt(r+1)]<<4|n[e.charCodeAt(r+2)]>>2,h[l++]=t>>8&255,h[l++]=255&t),h},t.fromByteArray=function(e){for(var t,n=e.length,i=n%3,o=[],s=16383,a=0,f=n-i;af?f:a+s));return 1===i?(t=e[n-1],o.push(r[t>>2]+r[t<<4&63]+"==")):2===i&&(t=(e[n-2]<<8)+e[n-1],o.push(r[t>>10]+r[t>>4&63]+r[t<<2&63]+"=")),o.join("")};for(var r=[],n=[],i="undefined"!=typeof Uint8Array?Uint8Array:Array,o="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",s=0,a=o.length;s0)throw new Error("Invalid string. Length must be a multiple of 4");var r=e.indexOf("=");return -1===r&&(r=t),[r,r===t?0:4-r%4]}function h(e,t,n){for(var i,o,s=[],a=t;a>18&63]+r[o>>12&63]+r[o>>6&63]+r[63&o]);return s.join("")}n["-".charCodeAt(0)]=62,n["_".charCodeAt(0)]=63;},2779:(e,t,r)=>{var n=r(8764).Buffer,i=[0,1996959894,3993919788,2567524794,124634137,1886057615,3915621685,2657392035,249268274,2044508324,3772115230,2547177864,162941995,2125561021,3887607047,2428444049,498536548,1789927666,4089016648,2227061214,450548861,1843258603,4107580753,2211677639,325883990,1684777152,4251122042,2321926636,335633487,1661365465,4195302755,2366115317,997073096,1281953886,3579855332,2724688242,1006888145,1258607687,3524101629,2768942443,901097722,1119000684,3686517206,2898065728,853044451,1172266101,3705015759,2882616665,651767980,1373503546,3369554304,3218104598,565507253,1454621731,3485111705,3099436303,671266974,1594198024,3322730930,2970347812,795835527,1483230225,3244367275,3060149565,1994146192,31158534,2563907772,4023717930,1907459465,112637215,2680153253,3904427059,2013776290,251722036,2517215374,3775830040,2137656763,141376813,2439277719,3865271297,1802195444,476864866,2238001368,4066508878,1812370925,453092731,2181625025,4111451223,1706088902,314042704,2344532202,4240017532,1658658271,366619977,2362670323,4224994405,1303535960,984961486,2747007092,3569037538,1256170817,1037604311,2765210733,3554079995,1131014506,879679996,2909243462,3663771856,1141124467,855842277,2852801631,3708648649,1342533948,654459306,3188396048,3373015174,1466479909,544179635,3110523913,3462522015,1591671054,702138776,2966460450,3352799412,1504918807,783551873,3082640443,3233442989,3988292384,2596254646,62317068,1957810842,3939845945,2647816111,81470997,1943803523,3814918930,2489596804,225274430,2053790376,3826175755,2466906013,167816743,2097651377,4027552580,2265490386,503444072,1762050814,4150417245,2154129355,426522225,1852507879,4275313526,2312317920,282753626,1742555852,4189708143,2394877945,397917763,1622183637,3604390888,2714866558,953729732,1340076626,3518719985,2797360999,1068828381,1219638859,3624741850,2936675148,906185462,1090812512,3747672003,2825379669,829329135,1181335161,3412177804,3160834842,628085408,1382605366,3423369109,3138078467,570562233,1426400815,3317316542,2998733608,733239954,1555261956,3268935591,3050360625,752459403,1541320221,2607071920,3965973030,1969922972,40735498,2617837225,3943577151,1913087877,83908371,2512341634,3803740692,2075208622,213261112,2463272603,3855990285,2094854071,198958881,2262029012,4057260610,1759359992,534414190,2176718541,4139329115,1873836001,414664567,2282248934,4279200368,1711684554,285281116,2405801727,4167216745,1634467795,376229701,2685067896,3608007406,1308918612,956543938,2808555105,3495958263,1231636301,1047427035,2932959818,3654703836,1088359270,936918e3,2847714899,3736837829,1202900863,817233897,3183342108,3401237130,1404277552,615818150,3134207493,3453421203,1423857449,601450431,3009837614,3294710456,1567103746,711928724,3020668471,3272380065,1510334235,755167117];function o(e){if(n.isBuffer(e))return e;var t="function"==typeof n.alloc&&"function"==typeof n.from;if("number"==typeof e)return t?n.alloc(e):new n(e);if("string"==typeof e)return t?n.from(e):new n(e);throw new Error("input must be buffer, number, or string, received "+typeof e)}function s(e){var t=o(4);return t.writeInt32BE(e,0),t}function a(e,t){e=o(e),n.isBuffer(t)&&(t=t.readUInt32BE(0));for(var r=-1^~~t,s=0;s>>8;return -1^r}function f(){return s(a.apply(null,arguments))}"undefined"!=typeof Int32Array&&(i=new Int32Array(i)),f.signed=function(){return a.apply(null,arguments)},f.unsigned=function(){return a.apply(null,arguments)>>>0},e.exports=f;},8764:(e,t,r)=>{const n=r(9742),i=r(645),o="function"==typeof Symbol&&"function"==typeof Symbol.for?Symbol.for("nodejs.util.inspect.custom"):null;t.Buffer=f,t.SlowBuffer=function(e){return +e!=e&&(e=0),f.alloc(+e)},t.INSPECT_MAX_BYTES=50;const s=2147483647;function a(e){if(e>s)throw new RangeError('The value "'+e+'" is invalid for option "size"');const t=new Uint8Array(e);return Object.setPrototypeOf(t,f.prototype),t}function f(e,t,r){if("number"==typeof e){if("string"==typeof t)throw new TypeError('The "string" argument must be of type string. Received type number');return u(e)}return h(e,t,r)}function h(e,t,r){if("string"==typeof e)return function(e,t){if("string"==typeof t&&""!==t||(t="utf8"),!f.isEncoding(t))throw new TypeError("Unknown encoding: "+t);const r=0|g(e,t);let n=a(r);const i=n.write(e,t);return i!==r&&(n=n.slice(0,i)),n}(e,t);if(ArrayBuffer.isView(e))return function(e){if(Q(e,Uint8Array)){const t=new Uint8Array(e);return d(t.buffer,t.byteOffset,t.byteLength)}return c(e)}(e);if(null==e)throw new TypeError("The first argument must be one of type string, Buffer, ArrayBuffer, Array, or Array-like Object. Received type "+typeof e);if(Q(e,ArrayBuffer)||e&&Q(e.buffer,ArrayBuffer))return d(e,t,r);if("undefined"!=typeof SharedArrayBuffer&&(Q(e,SharedArrayBuffer)||e&&Q(e.buffer,SharedArrayBuffer)))return d(e,t,r);if("number"==typeof e)throw new TypeError('The "value" argument must not be of type number. Received type number');const n=e.valueOf&&e.valueOf();if(null!=n&&n!==e)return f.from(n,t,r);const i=function(e){if(f.isBuffer(e)){const t=0|p(e.length),r=a(t);return 0===r.length||e.copy(r,0,0,t),r}return void 0!==e.length?"number"!=typeof e.length||Y(e.length)?a(0):c(e):"Buffer"===e.type&&Array.isArray(e.data)?c(e.data):void 0}(e);if(i)return i;if("undefined"!=typeof Symbol&&null!=Symbol.toPrimitive&&"function"==typeof e[Symbol.toPrimitive])return f.from(e[Symbol.toPrimitive]("string"),t,r);throw new TypeError("The first argument must be one of type string, Buffer, ArrayBuffer, Array, or Array-like Object. Received type "+typeof e)}function l(e){if("number"!=typeof e)throw new TypeError('"size" argument must be of type number');if(e<0)throw new RangeError('The value "'+e+'" is invalid for option "size"')}function u(e){return l(e),a(e<0?0:0|p(e))}function c(e){const t=e.length<0?0:0|p(e.length),r=a(t);for(let n=0;n=s)throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+s.toString(16)+" bytes");return 0|e}function g(e,t){if(f.isBuffer(e))return e.length;if(ArrayBuffer.isView(e)||Q(e,ArrayBuffer))return e.byteLength;if("string"!=typeof e)throw new TypeError('The "string" argument must be one of type string, Buffer, or ArrayBuffer. Received type '+typeof e);const r=e.length,n=arguments.length>2&&!0===arguments[2];if(!n&&0===r)return 0;let i=!1;for(;;)switch(t){case"ascii":case"latin1":case"binary":return r;case"utf8":case"utf-8":return V(e).length;case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return 2*r;case"hex":return r>>>1;case"base64":return Z(e).length;default:if(i)return n?-1:V(e).length;t=(""+t).toLowerCase(),i=!0;}}function m(e,t,r){let n=!1;if((void 0===t||t<0)&&(t=0),t>this.length)return "";if((void 0===r||r>this.length)&&(r=this.length),r<=0)return "";if((r>>>=0)<=(t>>>=0))return "";for(e||(e="utf8");;)switch(e){case"hex":return I(this,t,r);case"utf8":case"utf-8":return C(this,t,r);case"ascii":return k(this,t,r);case"latin1":case"binary":return x(this,t,r);case"base64":return A(this,t,r);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return M(this,t,r);default:if(n)throw new TypeError("Unknown encoding: "+e);e=(e+"").toLowerCase(),n=!0;}}function y(e,t,r){const n=e[t];e[t]=e[r],e[r]=n;}function b(e,t,r,n,i){if(0===e.length)return -1;if("string"==typeof r?(n=r,r=0):r>2147483647?r=2147483647:r<-2147483648&&(r=-2147483648),Y(r=+r)&&(r=i?0:e.length-1),r<0&&(r=e.length+r),r>=e.length){if(i)return -1;r=e.length-1;}else if(r<0){if(!i)return -1;r=0;}if("string"==typeof t&&(t=f.from(t,n)),f.isBuffer(t))return 0===t.length?-1:v(e,t,r,n,i);if("number"==typeof t)return t&=255,"function"==typeof Uint8Array.prototype.indexOf?i?Uint8Array.prototype.indexOf.call(e,t,r):Uint8Array.prototype.lastIndexOf.call(e,t,r):v(e,[t],r,n,i);throw new TypeError("val must be string, number or Buffer")}function v(e,t,r,n,i){let o,s=1,a=e.length,f=t.length;if(void 0!==n&&("ucs2"===(n=String(n).toLowerCase())||"ucs-2"===n||"utf16le"===n||"utf-16le"===n)){if(e.length<2||t.length<2)return -1;s=2,a/=2,f/=2,r/=2;}function h(e,t){return 1===s?e[t]:e.readUInt16BE(t*s)}if(i){let n=-1;for(o=r;oa&&(r=a-f),o=r;o>=0;o--){let r=!0;for(let n=0;ni&&(n=i):n=i;const o=t.length;let s;for(n>o/2&&(n=o/2),s=0;s>8,i=r%256,o.push(i),o.push(n);return o}(t,e.length-r),e,r,n)}function A(e,t,r){return 0===t&&r===e.length?n.fromByteArray(e):n.fromByteArray(e.slice(t,r))}function C(e,t,r){r=Math.min(e.length,r);const n=[];let i=t;for(;i239?4:t>223?3:t>191?2:1;if(i+s<=r){let r,n,a,f;switch(s){case 1:t<128&&(o=t);break;case 2:r=e[i+1],128==(192&r)&&(f=(31&t)<<6|63&r,f>127&&(o=f));break;case 3:r=e[i+1],n=e[i+2],128==(192&r)&&128==(192&n)&&(f=(15&t)<<12|(63&r)<<6|63&n,f>2047&&(f<55296||f>57343)&&(o=f));break;case 4:r=e[i+1],n=e[i+2],a=e[i+3],128==(192&r)&&128==(192&n)&&128==(192&a)&&(f=(15&t)<<18|(63&r)<<12|(63&n)<<6|63&a,f>65535&&f<1114112&&(o=f));}}null===o?(o=65533,s=1):o>65535&&(o-=65536,n.push(o>>>10&1023|55296),o=56320|1023&o),n.push(o),i+=s;}return function(e){const t=e.length;if(t<=R)return String.fromCharCode.apply(String,e);let r="",n=0;for(;nn.length?(f.isBuffer(t)||(t=f.from(t)),t.copy(n,i)):Uint8Array.prototype.set.call(n,t,i);else {if(!f.isBuffer(t))throw new TypeError('"list" argument must be an Array of Buffers');t.copy(n,i);}i+=t.length;}return n},f.byteLength=g,f.prototype._isBuffer=!0,f.prototype.swap16=function(){const e=this.length;if(e%2!=0)throw new RangeError("Buffer size must be a multiple of 16-bits");for(let t=0;tr&&(e+=" ... "),""},o&&(f.prototype[o]=f.prototype.inspect),f.prototype.compare=function(e,t,r,n,i){if(Q(e,Uint8Array)&&(e=f.from(e,e.offset,e.byteLength)),!f.isBuffer(e))throw new TypeError('The "target" argument must be one of type Buffer or Uint8Array. Received type '+typeof e);if(void 0===t&&(t=0),void 0===r&&(r=e?e.length:0),void 0===n&&(n=0),void 0===i&&(i=this.length),t<0||r>e.length||n<0||i>this.length)throw new RangeError("out of range index");if(n>=i&&t>=r)return 0;if(n>=i)return -1;if(t>=r)return 1;if(this===e)return 0;let o=(i>>>=0)-(n>>>=0),s=(r>>>=0)-(t>>>=0);const a=Math.min(o,s),h=this.slice(n,i),l=e.slice(t,r);for(let e=0;e>>=0,isFinite(r)?(r>>>=0,void 0===n&&(n="utf8")):(n=r,r=void 0);}const i=this.length-t;if((void 0===r||r>i)&&(r=i),e.length>0&&(r<0||t<0)||t>this.length)throw new RangeError("Attempt to write outside buffer bounds");n||(n="utf8");let o=!1;for(;;)switch(n){case"hex":return w(this,e,t,r);case"utf8":case"utf-8":return _(this,e,t,r);case"ascii":case"latin1":case"binary":return B(this,e,t,r);case"base64":return E(this,e,t,r);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return S(this,e,t,r);default:if(o)throw new TypeError("Unknown encoding: "+n);n=(""+n).toLowerCase(),o=!0;}},f.prototype.toJSON=function(){return {type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}};const R=4096;function k(e,t,r){let n="";r=Math.min(e.length,r);for(let i=t;in)&&(r=n);let i="";for(let n=t;nr)throw new RangeError("Trying to access beyond buffer length")}function O(e,t,r,n,i,o){if(!f.isBuffer(e))throw new TypeError('"buffer" argument must be a Buffer instance');if(t>i||te.length)throw new RangeError("Index out of range")}function T(e,t,r,n,i){j(t,n,i,e,r,7);let o=Number(t&BigInt(4294967295));e[r++]=o,o>>=8,e[r++]=o,o>>=8,e[r++]=o,o>>=8,e[r++]=o;let s=Number(t>>BigInt(32)&BigInt(4294967295));return e[r++]=s,s>>=8,e[r++]=s,s>>=8,e[r++]=s,s>>=8,e[r++]=s,r}function U(e,t,r,n,i){j(t,n,i,e,r,7);let o=Number(t&BigInt(4294967295));e[r+7]=o,o>>=8,e[r+6]=o,o>>=8,e[r+5]=o,o>>=8,e[r+4]=o;let s=Number(t>>BigInt(32)&BigInt(4294967295));return e[r+3]=s,s>>=8,e[r+2]=s,s>>=8,e[r+1]=s,s>>=8,e[r]=s,r+8}function P(e,t,r,n,i,o){if(r+n>e.length)throw new RangeError("Index out of range");if(r<0)throw new RangeError("Index out of range")}function N(e,t,r,n,o){return t=+t,r>>>=0,o||P(e,0,r,4),i.write(e,t,r,n,23,4),r+4}function L(e,t,r,n,o){return t=+t,r>>>=0,o||P(e,0,r,8),i.write(e,t,r,n,52,8),r+8}f.prototype.slice=function(e,t){const r=this.length;(e=~~e)<0?(e+=r)<0&&(e=0):e>r&&(e=r),(t=void 0===t?r:~~t)<0?(t+=r)<0&&(t=0):t>r&&(t=r),t>>=0,t>>>=0,r||F(e,t,this.length);let n=this[e],i=1,o=0;for(;++o>>=0,t>>>=0,r||F(e,t,this.length);let n=this[e+--t],i=1;for(;t>0&&(i*=256);)n+=this[e+--t]*i;return n},f.prototype.readUint8=f.prototype.readUInt8=function(e,t){return e>>>=0,t||F(e,1,this.length),this[e]},f.prototype.readUint16LE=f.prototype.readUInt16LE=function(e,t){return e>>>=0,t||F(e,2,this.length),this[e]|this[e+1]<<8},f.prototype.readUint16BE=f.prototype.readUInt16BE=function(e,t){return e>>>=0,t||F(e,2,this.length),this[e]<<8|this[e+1]},f.prototype.readUint32LE=f.prototype.readUInt32LE=function(e,t){return e>>>=0,t||F(e,4,this.length),(this[e]|this[e+1]<<8|this[e+2]<<16)+16777216*this[e+3]},f.prototype.readUint32BE=f.prototype.readUInt32BE=function(e,t){return e>>>=0,t||F(e,4,this.length),16777216*this[e]+(this[e+1]<<16|this[e+2]<<8|this[e+3])},f.prototype.readBigUInt64LE=X((function(e){H(e>>>=0,"offset");const t=this[e],r=this[e+7];void 0!==t&&void 0!==r||W(e,this.length-8);const n=t+256*this[++e]+65536*this[++e]+this[++e]*2**24,i=this[++e]+256*this[++e]+65536*this[++e]+r*2**24;return BigInt(n)+(BigInt(i)<>>=0,"offset");const t=this[e],r=this[e+7];void 0!==t&&void 0!==r||W(e,this.length-8);const n=t*2**24+65536*this[++e]+256*this[++e]+this[++e],i=this[++e]*2**24+65536*this[++e]+256*this[++e]+r;return (BigInt(n)<>>=0,t>>>=0,r||F(e,t,this.length);let n=this[e],i=1,o=0;for(;++o=i&&(n-=Math.pow(2,8*t)),n},f.prototype.readIntBE=function(e,t,r){e>>>=0,t>>>=0,r||F(e,t,this.length);let n=t,i=1,o=this[e+--n];for(;n>0&&(i*=256);)o+=this[e+--n]*i;return i*=128,o>=i&&(o-=Math.pow(2,8*t)),o},f.prototype.readInt8=function(e,t){return e>>>=0,t||F(e,1,this.length),128&this[e]?-1*(255-this[e]+1):this[e]},f.prototype.readInt16LE=function(e,t){e>>>=0,t||F(e,2,this.length);const r=this[e]|this[e+1]<<8;return 32768&r?4294901760|r:r},f.prototype.readInt16BE=function(e,t){e>>>=0,t||F(e,2,this.length);const r=this[e+1]|this[e]<<8;return 32768&r?4294901760|r:r},f.prototype.readInt32LE=function(e,t){return e>>>=0,t||F(e,4,this.length),this[e]|this[e+1]<<8|this[e+2]<<16|this[e+3]<<24},f.prototype.readInt32BE=function(e,t){return e>>>=0,t||F(e,4,this.length),this[e]<<24|this[e+1]<<16|this[e+2]<<8|this[e+3]},f.prototype.readBigInt64LE=X((function(e){H(e>>>=0,"offset");const t=this[e],r=this[e+7];void 0!==t&&void 0!==r||W(e,this.length-8);const n=this[e+4]+256*this[e+5]+65536*this[e+6]+(r<<24);return (BigInt(n)<>>=0,"offset");const t=this[e],r=this[e+7];void 0!==t&&void 0!==r||W(e,this.length-8);const n=(t<<24)+65536*this[++e]+256*this[++e]+this[++e];return (BigInt(n)<>>=0,t||F(e,4,this.length),i.read(this,e,!0,23,4)},f.prototype.readFloatBE=function(e,t){return e>>>=0,t||F(e,4,this.length),i.read(this,e,!1,23,4)},f.prototype.readDoubleLE=function(e,t){return e>>>=0,t||F(e,8,this.length),i.read(this,e,!0,52,8)},f.prototype.readDoubleBE=function(e,t){return e>>>=0,t||F(e,8,this.length),i.read(this,e,!1,52,8)},f.prototype.writeUintLE=f.prototype.writeUIntLE=function(e,t,r,n){e=+e,t>>>=0,r>>>=0,n||O(this,e,t,r,Math.pow(2,8*r)-1,0);let i=1,o=0;for(this[t]=255&e;++o>>=0,r>>>=0,n||O(this,e,t,r,Math.pow(2,8*r)-1,0);let i=r-1,o=1;for(this[t+i]=255&e;--i>=0&&(o*=256);)this[t+i]=e/o&255;return t+r},f.prototype.writeUint8=f.prototype.writeUInt8=function(e,t,r){return e=+e,t>>>=0,r||O(this,e,t,1,255,0),this[t]=255&e,t+1},f.prototype.writeUint16LE=f.prototype.writeUInt16LE=function(e,t,r){return e=+e,t>>>=0,r||O(this,e,t,2,65535,0),this[t]=255&e,this[t+1]=e>>>8,t+2},f.prototype.writeUint16BE=f.prototype.writeUInt16BE=function(e,t,r){return e=+e,t>>>=0,r||O(this,e,t,2,65535,0),this[t]=e>>>8,this[t+1]=255&e,t+2},f.prototype.writeUint32LE=f.prototype.writeUInt32LE=function(e,t,r){return e=+e,t>>>=0,r||O(this,e,t,4,4294967295,0),this[t+3]=e>>>24,this[t+2]=e>>>16,this[t+1]=e>>>8,this[t]=255&e,t+4},f.prototype.writeUint32BE=f.prototype.writeUInt32BE=function(e,t,r){return e=+e,t>>>=0,r||O(this,e,t,4,4294967295,0),this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e,t+4},f.prototype.writeBigUInt64LE=X((function(e,t=0){return T(this,e,t,BigInt(0),BigInt("0xffffffffffffffff"))})),f.prototype.writeBigUInt64BE=X((function(e,t=0){return U(this,e,t,BigInt(0),BigInt("0xffffffffffffffff"))})),f.prototype.writeIntLE=function(e,t,r,n){if(e=+e,t>>>=0,!n){const n=Math.pow(2,8*r-1);O(this,e,t,r,n-1,-n);}let i=0,o=1,s=0;for(this[t]=255&e;++i>0)-s&255;return t+r},f.prototype.writeIntBE=function(e,t,r,n){if(e=+e,t>>>=0,!n){const n=Math.pow(2,8*r-1);O(this,e,t,r,n-1,-n);}let i=r-1,o=1,s=0;for(this[t+i]=255&e;--i>=0&&(o*=256);)e<0&&0===s&&0!==this[t+i+1]&&(s=1),this[t+i]=(e/o>>0)-s&255;return t+r},f.prototype.writeInt8=function(e,t,r){return e=+e,t>>>=0,r||O(this,e,t,1,127,-128),e<0&&(e=255+e+1),this[t]=255&e,t+1},f.prototype.writeInt16LE=function(e,t,r){return e=+e,t>>>=0,r||O(this,e,t,2,32767,-32768),this[t]=255&e,this[t+1]=e>>>8,t+2},f.prototype.writeInt16BE=function(e,t,r){return e=+e,t>>>=0,r||O(this,e,t,2,32767,-32768),this[t]=e>>>8,this[t+1]=255&e,t+2},f.prototype.writeInt32LE=function(e,t,r){return e=+e,t>>>=0,r||O(this,e,t,4,2147483647,-2147483648),this[t]=255&e,this[t+1]=e>>>8,this[t+2]=e>>>16,this[t+3]=e>>>24,t+4},f.prototype.writeInt32BE=function(e,t,r){return e=+e,t>>>=0,r||O(this,e,t,4,2147483647,-2147483648),e<0&&(e=4294967295+e+1),this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e,t+4},f.prototype.writeBigInt64LE=X((function(e,t=0){return T(this,e,t,-BigInt("0x8000000000000000"),BigInt("0x7fffffffffffffff"))})),f.prototype.writeBigInt64BE=X((function(e,t=0){return U(this,e,t,-BigInt("0x8000000000000000"),BigInt("0x7fffffffffffffff"))})),f.prototype.writeFloatLE=function(e,t,r){return N(this,e,t,!0,r)},f.prototype.writeFloatBE=function(e,t,r){return N(this,e,t,!1,r)},f.prototype.writeDoubleLE=function(e,t,r){return L(this,e,t,!0,r)},f.prototype.writeDoubleBE=function(e,t,r){return L(this,e,t,!1,r)},f.prototype.copy=function(e,t,r,n){if(!f.isBuffer(e))throw new TypeError("argument should be a Buffer");if(r||(r=0),n||0===n||(n=this.length),t>=e.length&&(t=e.length),t||(t=0),n>0&&n=this.length)throw new RangeError("Index out of range");if(n<0)throw new RangeError("sourceEnd out of bounds");n>this.length&&(n=this.length),e.length-t>>=0,r=void 0===r?this.length:r>>>0,e||(e=0),"number"==typeof e)for(i=t;i=n+4;r-=3)t=`_${e.slice(r-3,r)}${t}`;return `${e.slice(0,r)}${t}`}function j(e,t,r,n,i,o){if(e>r||e3?0===t||t===BigInt(0)?`>= 0${n} and < 2${n} ** ${8*(o+1)}${n}`:`>= -(2${n} ** ${8*(o+1)-1}${n}) and < 2 ** ${8*(o+1)-1}${n}`:`>= ${t}${n} and <= ${r}${n}`,new z.ERR_OUT_OF_RANGE("value",i,e)}!function(e,t,r){H(t,"offset"),void 0!==e[t]&&void 0!==e[t+r]||W(t,e.length-(r+1));}(n,i,o);}function H(e,t){if("number"!=typeof e)throw new z.ERR_INVALID_ARG_TYPE(t,"number",e)}function W(e,t,r){if(Math.floor(e)!==e)throw H(e,r),new z.ERR_OUT_OF_RANGE(r||"offset","an integer",e);if(t<0)throw new z.ERR_BUFFER_OUT_OF_BOUNDS;throw new z.ERR_OUT_OF_RANGE(r||"offset",`>= ${r?1:0} and <= ${t}`,e)}D("ERR_BUFFER_OUT_OF_BOUNDS",(function(e){return e?`${e} is outside of buffer bounds`:"Attempt to access memory outside buffer bounds"}),RangeError),D("ERR_INVALID_ARG_TYPE",(function(e,t){return `The "${e}" argument must be of type number. Received type ${typeof t}`}),TypeError),D("ERR_OUT_OF_RANGE",(function(e,t,r){let n=`The value of "${e}" is out of range.`,i=r;return Number.isInteger(r)&&Math.abs(r)>2**32?i=q(String(r)):"bigint"==typeof r&&(i=String(r),(r>BigInt(2)**BigInt(32)||r<-(BigInt(2)**BigInt(32)))&&(i=q(i)),i+="n"),n+=` It must be ${t}. Received ${i}`,n}),RangeError);const $=/[^+/0-9A-Za-z-_]/g;function V(e,t){let r;t=t||1/0;const n=e.length;let i=null;const o=[];for(let s=0;s55295&&r<57344){if(!i){if(r>56319){(t-=3)>-1&&o.push(239,191,189);continue}if(s+1===n){(t-=3)>-1&&o.push(239,191,189);continue}i=r;continue}if(r<56320){(t-=3)>-1&&o.push(239,191,189),i=r;continue}r=65536+(i-55296<<10|r-56320);}else i&&(t-=3)>-1&&o.push(239,191,189);if(i=null,r<128){if((t-=1)<0)break;o.push(r);}else if(r<2048){if((t-=2)<0)break;o.push(r>>6|192,63&r|128);}else if(r<65536){if((t-=3)<0)break;o.push(r>>12|224,r>>6&63|128,63&r|128);}else {if(!(r<1114112))throw new Error("Invalid code point");if((t-=4)<0)break;o.push(r>>18|240,r>>12&63|128,r>>6&63|128,63&r|128);}}return o}function Z(e){return n.toByteArray(function(e){if((e=(e=e.split("=")[0]).trim().replace($,"")).length<2)return "";for(;e.length%4!=0;)e+="=";return e}(e))}function G(e,t,r,n){let i;for(i=0;i=t.length||i>=e.length);++i)t[i+r]=e[i];return i}function Q(e,t){return e instanceof t||null!=e&&null!=e.constructor&&null!=e.constructor.name&&e.constructor.name===t.name}function Y(e){return e!=e}const K=function(){const e="0123456789abcdef",t=new Array(256);for(let r=0;r<16;++r){const n=16*r;for(let i=0;i<16;++i)t[n+i]=e[r]+e[i];}return t}();function X(e){return "undefined"==typeof BigInt?J:e}function J(){throw new Error("BigInt not supported")}},4693:e=>{var t={array:function(e){var t=0,r=0,n=[0,1,3,7,15,31,63,127,255];return function(i){for(var o=0;i>0;){var s=8-t;i>=s?(o<<=s,o|=n[s]&e[r++],t=0,i-=s):(o<<=i,o|=(e[r]&n[i]<<8-i-t)>>8-i-t,t+=i,i=0);}return o}},simple:function(e){var r,n,i=t.header(e),o=[],s=0;do{-1!=(n=t.decompress(e,i))&&(o.push(n),s+=n.byteLength);}while(-1!=n);r=new Uint8Array(s),s=0;for(var a=0;a9)throw "Not a BZIP archive";return t},decompress:function(e,t,r){for(var n=9e5,i="",o=0;o<6;o++)i+=e(8).toString(16);if("177245385090"==i)return -1;if("314159265359"!=i)throw "eek not valid bzip data";if(e(32),e(1))throw "unsupported obsolete version";var s=e(24);if(s>n)throw "Initial position larger than buffer size";var a=e(16),f=new Uint8Array(256),h=0;for(o=0;o<16;o++)if(a&1<<15-o){var l=e(16);for(g=0;g<16;g++)l&1<<15-g&&(f[h++]=16*o+g);}var u=e(3);if(u<2||u>6)throw "another error";var c=e(15);if(0==c)throw "meh";var d=[];for(o=0;o=u)throw "whoops another error";var m=d[g];d.splice(g,1),d.splice(0,0,m),p[o]=m;}var y=h+2,b=[];for(g=0;g20)throw "I gave up a while ago on writing error messages";if(!e(1))break;e(1)?a--:a++;}B[o]=a;}for(v=w=B[0],o=1;ow?w=B[o]:B[o]=c)throw "meow i'm a kitty, that's an error";S=(_=b[p[x++]]).base.subarray(1),A=_.limit.subarray(1);}for(g=e(o=_.minLen);;){if(o>_.maxLen)throw "rawr i'm a dinosaur";if(g<=A[o])break;o++,g=g<<1|e(1);}if((g-=S[o])<0||g>=258)throw "moo i'm a cow";var F=_.permute[g];if(0!=F&&1!=F){if(R){if(R=0,k+a>=n)throw "Boom.";for(I[m=f[d[0]]]+=a;a--;)M[k++]=m;}if(F>h)break;if(k>=n)throw "I can't think of anything. Error";m=d[o=F-1],d.splice(o,1),d.splice(0,0,m),I[m=f[m]]++,M[k++]=m;}else R||(R=1,a=0),a+=0==F?R:2*R,R<<=1;}if(s<0||s>=k)throw "I'm a monkey and I'm throwing something at someone, namely you";for(g=0,o=0;o<256;o++)l=g+I[o],I[o]=g,g=l;for(o=0;o>=8,U=-1);var P,N,L,z=new Uint8Array(n),D=0;for(r||(r=1/0);k;){for(k--,N=T,T=255&(O=M[O]),O>>=8,3==U++?(P=T,L=N,T=-1):(P=1,L=T);P--;)if(z[D++]=L,!--r)return z;T!=N&&(U=0);}return z.subarray(0,D)}};e.exports=t;},487:e=>{var t={utf8:{stringToBytes:function(e){return t.bin.stringToBytes(unescape(encodeURIComponent(e)))},bytesToString:function(e){return decodeURIComponent(escape(t.bin.bytesToString(e)))}},bin:{stringToBytes:function(e){for(var t=[],r=0;r{var t,r;t="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",r={rotl:function(e,t){return e<>>32-t},rotr:function(e,t){return e<<32-t|e>>>t},endian:function(e){if(e.constructor==Number)return 16711935&r.rotl(e,8)|4278255360&r.rotl(e,24);for(var t=0;t0;e--)t.push(Math.floor(256*Math.random()));return t},bytesToWords:function(e){for(var t=[],r=0,n=0;r>>5]|=e[r]<<24-n%32;return t},wordsToBytes:function(e){for(var t=[],r=0;r<32*e.length;r+=8)t.push(e[r>>>5]>>>24-r%32&255);return t},bytesToHex:function(e){for(var t=[],r=0;r>>4).toString(16)),t.push((15&e[r]).toString(16));return t.join("")},hexToBytes:function(e){for(var t=[],r=0;r>>6*(3-o)&63)):r.push("=");return r.join("")},base64ToBytes:function(e){e=e.replace(/[^A-Z0-9+\/]/gi,"");for(var r=[],n=0,i=0;n>>6-2*i);return r}},e.exports=r;},2949:(e,t,r)=>{r.r(t),r.d(t,{BlobFile:()=>h,LocalFile:()=>i(),RemoteFile:()=>a,fromUrl:()=>l,open:()=>u});var n=r(7067),i=r.n(n),o=r(8764);const s="undefined"!=typeof window?window:"undefined"!=typeof self?self:{fetch:void 0};class a{constructor(e,t={}){this.baseOverrides={},this.url=e;const r=t.fetch||s.fetch&&s.fetch.bind(s);if(!r)throw new TypeError("no fetch function supplied, and none found in global environment");t.overrides&&(this.baseOverrides=t.overrides),this.fetchImplementation=r;}async getBufferFromResponse(e){if("function"==typeof e.buffer)return e.buffer();if("function"==typeof e.arrayBuffer){const t=await e.arrayBuffer();return o.Buffer.from(t)}throw new TypeError("invalid HTTP response object, has no buffer method, and no arrayBuffer method")}async fetch(e,t){let r;try{r=await this.fetchImplementation(e,t);}catch(n){if(!`${n}`.includes("Failed to fetch"))throw n;console.warn(`generic-filehandle: refetching ${e} to attempt to work around chrome CORS header caching bug`),r=await this.fetchImplementation(e,{...t,cache:"reload"});}return r}async read(e,t=0,r,n=0,i={}){const{headers:o={},signal:s,overrides:a={}}=i;r<1/0?o.range=`bytes=${n}-${n+r}`:r===1/0&&0!==n&&(o.range=`bytes=${n}-`);const f={...this.baseOverrides,...a,headers:{...o,...a.headers,...this.baseOverrides.headers},method:"GET",redirect:"follow",mode:"cors",signal:s},h=await this.fetch(this.url,f);if(!h.ok)throw new Error(`HTTP ${h.status} ${h.statusText} ${this.url}`);if(200===h.status&&0===n||206===h.status){const n=await this.getBufferFromResponse(h),i=n.copy(e,t,0,Math.min(r,n.length)),o=h.headers.get("content-range"),s=/\/(\d+)$/.exec(o||"");return s&&s[1]&&(this._stat={size:parseInt(s[1],10)}),{bytesRead:i,buffer:e}}if(200===h.status)throw new Error("${this.url} fetch returned status 200, expected 206");throw new Error(`HTTP ${h.status} fetching ${this.url}`)}async readFile(e={}){let t,r;"string"==typeof e?(t=e,r={}):(t=e.encoding,r=e,delete r.encoding);const{headers:n={},signal:i,overrides:o={}}=r,s={headers:n,method:"GET",redirect:"follow",mode:"cors",signal:i,...this.baseOverrides,...o},a=await this.fetch(this.url,s);if(!a)throw new Error("generic-filehandle failed to fetch");if(200!==a.status)throw Object.assign(new Error(`HTTP ${a.status} fetching ${this.url}`),{status:a.status});if("utf8"===t)return a.text();if(t)throw new Error(`unsupported encoding: ${t}`);return this.getBufferFromResponse(a)}async stat(){if(!this._stat){const e=o.Buffer.allocUnsafe(10);if(await this.read(e,0,10,0),!this._stat)throw new Error(`unable to determine size of file at ${this.url}`)}return this._stat}async close(){}}function f(e){const t=new FileReader;return new Promise(((r,n)=>{t.onerror=()=>{t.abort(),n(new Error("problem reading blob"));},t.onabort=()=>{n(new Error("blob reading was aborted"));},t.onload=()=>{t.result&&"string"!=typeof t.result?r(t.result):n(new Error("unknown error reading blob"));},t.readAsArrayBuffer(e);}))}class h{constructor(e){this.blob=e,this.size=e.size;}async read(e,t=0,r,n=0){if(!r)return {bytesRead:0,buffer:e};const i=n,s=i+r,a=await f(this.blob.slice(i,s)),h=o.Buffer.from(a);return {bytesRead:h.copy(e,t),buffer:h}}async readFile(e){let t;if(t="string"==typeof e?e:e&&e.encoding,"utf8"===t)return function(e){const t=new FileReader;return new Promise(((r,n)=>{t.onerror=()=>{t.abort(),n(new Error("problem reading blob"));},t.onabort=()=>{n(new Error("blob reading was aborted"));},t.onload=()=>{t.result&&"string"==typeof t.result?r(t.result):n(new Error("unknown error reading blob"));},t.readAsText(e);}))}(this.blob);if(t)throw new Error(`unsupported encoding: ${t}`);const r=await f(this.blob);return o.Buffer.from(r)}async stat(){return {size:this.size}}async close(){}}function l(e,t={}){return new a(e,t)}function u(e,t,r,n={}){if(void 0!==r)return r;if(void 0!==e)return l(e,n);if(void 0!==t)return new(i())(t,n);throw new Error("no url, path, or filehandle provided, cannot open")}},645:(e,t)=>{t.read=function(e,t,r,n,i){var o,s,a=8*i-n-1,f=(1<>1,l=-7,u=r?i-1:0,c=r?-1:1,d=e[t+u];for(u+=c,o=d&(1<<-l)-1,d>>=-l,l+=a;l>0;o=256*o+e[t+u],u+=c,l-=8);for(s=o&(1<<-l)-1,o>>=-l,l+=n;l>0;s=256*s+e[t+u],u+=c,l-=8);if(0===o)o=1-h;else {if(o===f)return s?NaN:1/0*(d?-1:1);s+=Math.pow(2,n),o-=h;}return (d?-1:1)*s*Math.pow(2,o-n)},t.write=function(e,t,r,n,i,o){var s,a,f,h=8*o-i-1,l=(1<>1,c=23===i?Math.pow(2,-24)-Math.pow(2,-77):0,d=n?0:o-1,p=n?1:-1,g=t<0||0===t&&1/t<0?1:0;for(t=Math.abs(t),isNaN(t)||t===1/0?(a=isNaN(t)?1:0,s=l):(s=Math.floor(Math.log(t)/Math.LN2),t*(f=Math.pow(2,-s))<1&&(s--,f*=2),(t+=s+u>=1?c/f:c*Math.pow(2,1-u))*f>=2&&(s++,f/=2),s+u>=l?(a=0,s=l):s+u>=1?(a=(t*f-1)*Math.pow(2,i),s+=u):(a=t*Math.pow(2,u-1)*Math.pow(2,i),s=0));i>=8;e[r+d]=255&a,d+=p,a/=256,i-=8);for(s=s<0;e[r+d]=255&s,d+=p,s/=256,h-=8);e[r+d-p]|=128*g;};},8738:e=>{function t(e){return !!e.constructor&&"function"==typeof e.constructor.isBuffer&&e.constructor.isBuffer(e)}e.exports=function(e){return null!=e&&(t(e)||function(e){return "function"==typeof e.readFloatLE&&"function"==typeof e.slice&&t(e.slice(0,0))}(e)||!!e._isBuffer)};},3720:e=>{e.exports=r;var t=null;try{t=new WebAssembly.Instance(new WebAssembly.Module(new Uint8Array([0,97,115,109,1,0,0,0,1,13,2,96,0,1,127,96,4,127,127,127,127,1,127,3,7,6,0,1,1,1,1,1,6,6,1,127,1,65,0,11,7,50,6,3,109,117,108,0,1,5,100,105,118,95,115,0,2,5,100,105,118,95,117,0,3,5,114,101,109,95,115,0,4,5,114,101,109,95,117,0,5,8,103,101,116,95,104,105,103,104,0,0,10,191,1,6,4,0,35,0,11,36,1,1,126,32,0,173,32,1,173,66,32,134,132,32,2,173,32,3,173,66,32,134,132,126,34,4,66,32,135,167,36,0,32,4,167,11,36,1,1,126,32,0,173,32,1,173,66,32,134,132,32,2,173,32,3,173,66,32,134,132,127,34,4,66,32,135,167,36,0,32,4,167,11,36,1,1,126,32,0,173,32,1,173,66,32,134,132,32,2,173,32,3,173,66,32,134,132,128,34,4,66,32,135,167,36,0,32,4,167,11,36,1,1,126,32,0,173,32,1,173,66,32,134,132,32,2,173,32,3,173,66,32,134,132,129,34,4,66,32,135,167,36,0,32,4,167,11,36,1,1,126,32,0,173,32,1,173,66,32,134,132,32,2,173,32,3,173,66,32,134,132,130,34,4,66,32,135,167,36,0,32,4,167,11])),{}).exports;}catch(e){}function r(e,t,r){this.low=0|e,this.high=0|t,this.unsigned=!!r;}function n(e){return !0===(e&&e.__isLong__)}r.prototype.__isLong__,Object.defineProperty(r.prototype,"__isLong__",{value:!0}),r.isLong=n;var i={},o={};function s(e,t){var r,n,s;return t?(s=0<=(e>>>=0)&&e<256)&&(n=o[e])?n:(r=f(e,(0|e)<0?-1:0,!0),s&&(o[e]=r),r):(s=-128<=(e|=0)&&e<128)&&(n=i[e])?n:(r=f(e,e<0?-1:0,!1),s&&(i[e]=r),r)}function a(e,t){if(isNaN(e))return t?y:m;if(t){if(e<0)return y;if(e>=d)return B}else {if(e<=-p)return E;if(e+1>=p)return _}return e<0?a(-e,t).neg():f(e%c|0,e/c|0,t)}function f(e,t,n){return new r(e,t,n)}r.fromInt=s,r.fromNumber=a,r.fromBits=f;var h=Math.pow;function l(e,t,r){if(0===e.length)throw Error("empty string");if("NaN"===e||"Infinity"===e||"+Infinity"===e||"-Infinity"===e)return m;if("number"==typeof t?(r=t,t=!1):t=!!t,(r=r||10)<2||360)throw Error("interior hyphen");if(0===n)return l(e.substring(1),t,r).neg();for(var i=a(h(r,8)),o=m,s=0;s>>0:this.low},S.toNumber=function(){return this.unsigned?(this.high>>>0)*c+(this.low>>>0):this.high*c+(this.low>>>0)},S.toString=function(e){if((e=e||10)<2||36>>0).toString(e);if((o=f).isZero())return l+s;for(;l.length<6;)l="0"+l;s=""+l+s;}},S.getHighBits=function(){return this.high},S.getHighBitsUnsigned=function(){return this.high>>>0},S.getLowBits=function(){return this.low},S.getLowBitsUnsigned=function(){return this.low>>>0},S.getNumBitsAbs=function(){if(this.isNegative())return this.eq(E)?64:this.neg().getNumBitsAbs();for(var e=0!=this.high?this.high:this.low,t=31;t>0&&0==(e&1<=0},S.isOdd=function(){return 1==(1&this.low)},S.isEven=function(){return 0==(1&this.low)},S.equals=function(e){return n(e)||(e=u(e)),(this.unsigned===e.unsigned||this.high>>>31!=1||e.high>>>31!=1)&&this.high===e.high&&this.low===e.low},S.eq=S.equals,S.notEquals=function(e){return !this.eq(e)},S.neq=S.notEquals,S.ne=S.notEquals,S.lessThan=function(e){return this.comp(e)<0},S.lt=S.lessThan,S.lessThanOrEqual=function(e){return this.comp(e)<=0},S.lte=S.lessThanOrEqual,S.le=S.lessThanOrEqual,S.greaterThan=function(e){return this.comp(e)>0},S.gt=S.greaterThan,S.greaterThanOrEqual=function(e){return this.comp(e)>=0},S.gte=S.greaterThanOrEqual,S.ge=S.greaterThanOrEqual,S.compare=function(e){if(n(e)||(e=u(e)),this.eq(e))return 0;var t=this.isNegative(),r=e.isNegative();return t&&!r?-1:!t&&r?1:this.unsigned?e.high>>>0>this.high>>>0||e.high===this.high&&e.low>>>0>this.low>>>0?-1:1:this.sub(e).isNegative()?-1:1},S.comp=S.compare,S.negate=function(){return !this.unsigned&&this.eq(E)?E:this.not().add(b)},S.neg=S.negate,S.add=function(e){n(e)||(e=u(e));var t=this.high>>>16,r=65535&this.high,i=this.low>>>16,o=65535&this.low,s=e.high>>>16,a=65535&e.high,h=e.low>>>16,l=0,c=0,d=0,p=0;return d+=(p+=o+(65535&e.low))>>>16,c+=(d+=i+h)>>>16,l+=(c+=r+a)>>>16,l+=t+s,f((d&=65535)<<16|(p&=65535),(l&=65535)<<16|(c&=65535),this.unsigned)},S.subtract=function(e){return n(e)||(e=u(e)),this.add(e.neg())},S.sub=S.subtract,S.multiply=function(e){if(this.isZero())return m;if(n(e)||(e=u(e)),t)return f(t.mul(this.low,this.high,e.low,e.high),t.get_high(),this.unsigned);if(e.isZero())return m;if(this.eq(E))return e.isOdd()?E:m;if(e.eq(E))return this.isOdd()?E:m;if(this.isNegative())return e.isNegative()?this.neg().mul(e.neg()):this.neg().mul(e).neg();if(e.isNegative())return this.mul(e.neg()).neg();if(this.lt(g)&&e.lt(g))return a(this.toNumber()*e.toNumber(),this.unsigned);var r=this.high>>>16,i=65535&this.high,o=this.low>>>16,s=65535&this.low,h=e.high>>>16,l=65535&e.high,c=e.low>>>16,d=65535&e.low,p=0,y=0,b=0,v=0;return b+=(v+=s*d)>>>16,y+=(b+=o*d)>>>16,b&=65535,y+=(b+=s*c)>>>16,p+=(y+=i*d)>>>16,y&=65535,p+=(y+=o*c)>>>16,y&=65535,p+=(y+=s*l)>>>16,p+=r*d+i*c+o*l+s*h,f((b&=65535)<<16|(v&=65535),(p&=65535)<<16|(y&=65535),this.unsigned)},S.mul=S.multiply,S.divide=function(e){if(n(e)||(e=u(e)),e.isZero())throw Error("division by zero");var r,i,o;if(t)return this.unsigned||-2147483648!==this.high||-1!==e.low||-1!==e.high?f((this.unsigned?t.div_u:t.div_s)(this.low,this.high,e.low,e.high),t.get_high(),this.unsigned):this;if(this.isZero())return this.unsigned?y:m;if(this.unsigned){if(e.unsigned||(e=e.toUnsigned()),e.gt(this))return y;if(e.gt(this.shru(1)))return v;o=y;}else {if(this.eq(E))return e.eq(b)||e.eq(w)?E:e.eq(E)?b:(r=this.shr(1).div(e).shl(1)).eq(m)?e.isNegative()?b:w:(i=this.sub(e.mul(r)),o=r.add(i.div(e)));if(e.eq(E))return this.unsigned?y:m;if(this.isNegative())return e.isNegative()?this.neg().div(e.neg()):this.neg().div(e).neg();if(e.isNegative())return this.div(e.neg()).neg();o=m;}for(i=this;i.gte(e);){r=Math.max(1,Math.floor(i.toNumber()/e.toNumber()));for(var s=Math.ceil(Math.log(r)/Math.LN2),l=s<=48?1:h(2,s-48),c=a(r),d=c.mul(e);d.isNegative()||d.gt(i);)d=(c=a(r-=l,this.unsigned)).mul(e);c.isZero()&&(c=b),o=o.add(c),i=i.sub(d);}return o},S.div=S.divide,S.modulo=function(e){return n(e)||(e=u(e)),t?f((this.unsigned?t.rem_u:t.rem_s)(this.low,this.high,e.low,e.high),t.get_high(),this.unsigned):this.sub(this.div(e).mul(e))},S.mod=S.modulo,S.rem=S.modulo,S.not=function(){return f(~this.low,~this.high,this.unsigned)},S.and=function(e){return n(e)||(e=u(e)),f(this.low&e.low,this.high&e.high,this.unsigned)},S.or=function(e){return n(e)||(e=u(e)),f(this.low|e.low,this.high|e.high,this.unsigned)},S.xor=function(e){return n(e)||(e=u(e)),f(this.low^e.low,this.high^e.high,this.unsigned)},S.shiftLeft=function(e){return n(e)&&(e=e.toInt()),0==(e&=63)?this:e<32?f(this.low<>>32-e,this.unsigned):f(0,this.low<>>e|this.high<<32-e,this.high>>e,this.unsigned):f(this.high>>e-32,this.high>=0?0:-1,this.unsigned)},S.shr=S.shiftRight,S.shiftRightUnsigned=function(e){if(n(e)&&(e=e.toInt()),0==(e&=63))return this;var t=this.high;return e<32?f(this.low>>>e|t<<32-e,t>>>e,this.unsigned):f(32===e?t:t>>>e-32,0,this.unsigned)},S.shru=S.shiftRightUnsigned,S.shr_u=S.shiftRightUnsigned,S.toSigned=function(){return this.unsigned?f(this.low,this.high,!1):this},S.toUnsigned=function(){return this.unsigned?this:f(this.low,this.high,!0)},S.toBytes=function(e){return e?this.toBytesLE():this.toBytesBE()},S.toBytesLE=function(){var e=this.high,t=this.low;return [255&t,t>>>8&255,t>>>16&255,t>>>24,255&e,e>>>8&255,e>>>16&255,e>>>24]},S.toBytesBE=function(){var e=this.high,t=this.low;return [e>>>24,e>>>16&255,e>>>8&255,255&e,t>>>24,t>>>16&255,t>>>8&255,255&t]},r.fromBytes=function(e,t,n){return n?r.fromBytesLE(e,t):r.fromBytesBE(e,t)},r.fromBytesLE=function(e,t){return new r(e[0]|e[1]<<8|e[2]<<16|e[3]<<24,e[4]|e[5]<<8|e[6]<<16|e[7]<<24,t)},r.fromBytesBE=function(e,t){return new r(e[4]<<24|e[5]<<16|e[6]<<8|e[7],e[0]<<24|e[1]<<16|e[2]<<8|e[3],t)};},2568:(e,t,r)=>{var n,i,o,s,a;n=r(1012),i=r(487).utf8,o=r(8738),s=r(487).bin,(a=function(e,t){e.constructor==String?e=t&&"binary"===t.encoding?s.stringToBytes(e):i.stringToBytes(e):o(e)?e=Array.prototype.slice.call(e,0):Array.isArray(e)||e.constructor===Uint8Array||(e=e.toString());for(var r=n.bytesToWords(e),f=8*e.length,h=1732584193,l=-271733879,u=-1732584194,c=271733878,d=0;d>>24)|4278255360&(r[d]<<24|r[d]>>>8);r[f>>>5]|=128<>>9<<4)]=f;var p=a._ff,g=a._gg,m=a._hh,y=a._ii;for(d=0;d>>0,l=l+v>>>0,u=u+w>>>0,c=c+_>>>0;}return n.endian([h,l,u,c])})._ff=function(e,t,r,n,i,o,s){var a=e+(t&r|~t&n)+(i>>>0)+s;return (a<>>32-o)+t},a._gg=function(e,t,r,n,i,o,s){var a=e+(t&n|r&~n)+(i>>>0)+s;return (a<>>32-o)+t},a._hh=function(e,t,r,n,i,o,s){var a=e+(t^r^n)+(i>>>0)+s;return (a<>>32-o)+t},a._ii=function(e,t,r,n,i,o,s){var a=e+(r^(t|~n))+(i>>>0)+s;return (a<>>32-o)+t},a._blocksize=16,a._digestsize=16,e.exports=function(e,t){if(null==e)throw new Error("Illegal argument "+e);var r=n.wordsToBytes(a(e,t));return t&&t.asBytes?r:t&&t.asString?s.bytesToString(r):n.bytesToHex(r)};},9591:(e,t,r)=>{var n={};(0, r(4236).assign)(n,r(4555),r(8843),r(1619)),e.exports=n;},4555:(e,t,r)=>{var n=r(405),i=r(4236),o=r(9373),s=r(8898),a=r(2292),f=Object.prototype.toString;function h(e){if(!(this instanceof h))return new h(e);this.options=i.assign({level:-1,method:8,chunkSize:16384,windowBits:15,memLevel:8,strategy:0,to:""},e||{});var t=this.options;t.raw&&t.windowBits>0?t.windowBits=-t.windowBits:t.gzip&&t.windowBits>0&&t.windowBits<16&&(t.windowBits+=16),this.err=0,this.msg="",this.ended=!1,this.chunks=[],this.strm=new a,this.strm.avail_out=0;var r=n.deflateInit2(this.strm,t.level,t.method,t.windowBits,t.memLevel,t.strategy);if(0!==r)throw new Error(s[r]);if(t.header&&n.deflateSetHeader(this.strm,t.header),t.dictionary){var l;if(l="string"==typeof t.dictionary?o.string2buf(t.dictionary):"[object ArrayBuffer]"===f.call(t.dictionary)?new Uint8Array(t.dictionary):t.dictionary,0!==(r=n.deflateSetDictionary(this.strm,l)))throw new Error(s[r]);this._dict_set=!0;}}function l(e,t){var r=new h(t);if(r.push(e,!0),r.err)throw r.msg||s[r.err];return r.result}h.prototype.push=function(e,t){var r,s,a=this.strm,h=this.options.chunkSize;if(this.ended)return !1;s=t===~~t?t:!0===t?4:0,"string"==typeof e?a.input=o.string2buf(e):"[object ArrayBuffer]"===f.call(e)?a.input=new Uint8Array(e):a.input=e,a.next_in=0,a.avail_in=a.input.length;do{if(0===a.avail_out&&(a.output=new i.Buf8(h),a.next_out=0,a.avail_out=h),1!==(r=n.deflate(a,s))&&0!==r)return this.onEnd(r),this.ended=!0,!1;0!==a.avail_out&&(0!==a.avail_in||4!==s&&2!==s)||("string"===this.options.to?this.onData(o.buf2binstring(i.shrinkBuf(a.output,a.next_out))):this.onData(i.shrinkBuf(a.output,a.next_out)));}while((a.avail_in>0||0===a.avail_out)&&1!==r);return 4===s?(r=n.deflateEnd(this.strm),this.onEnd(r),this.ended=!0,0===r):2!==s||(this.onEnd(0),a.avail_out=0,!0)},h.prototype.onData=function(e){this.chunks.push(e);},h.prototype.onEnd=function(e){0===e&&("string"===this.options.to?this.result=this.chunks.join(""):this.result=i.flattenChunks(this.chunks)),this.chunks=[],this.err=e,this.msg=this.strm.msg;},t.Deflate=h,t.deflate=l,t.deflateRaw=function(e,t){return (t=t||{}).raw=!0,l(e,t)},t.gzip=function(e,t){return (t=t||{}).gzip=!0,l(e,t)};},8843:(e,t,r)=>{var n=r(7948),i=r(4236),o=r(9373),s=r(1619),a=r(8898),f=r(2292),h=r(2401),l=Object.prototype.toString;function u(e){if(!(this instanceof u))return new u(e);this.options=i.assign({chunkSize:16384,windowBits:0,to:""},e||{});var t=this.options;t.raw&&t.windowBits>=0&&t.windowBits<16&&(t.windowBits=-t.windowBits,0===t.windowBits&&(t.windowBits=-15)),!(t.windowBits>=0&&t.windowBits<16)||e&&e.windowBits||(t.windowBits+=32),t.windowBits>15&&t.windowBits<48&&0==(15&t.windowBits)&&(t.windowBits|=15),this.err=0,this.msg="",this.ended=!1,this.chunks=[],this.strm=new f,this.strm.avail_out=0;var r=n.inflateInit2(this.strm,t.windowBits);if(r!==s.Z_OK)throw new Error(a[r]);if(this.header=new h,n.inflateGetHeader(this.strm,this.header),t.dictionary&&("string"==typeof t.dictionary?t.dictionary=o.string2buf(t.dictionary):"[object ArrayBuffer]"===l.call(t.dictionary)&&(t.dictionary=new Uint8Array(t.dictionary)),t.raw&&(r=n.inflateSetDictionary(this.strm,t.dictionary))!==s.Z_OK))throw new Error(a[r])}function c(e,t){var r=new u(t);if(r.push(e,!0),r.err)throw r.msg||a[r.err];return r.result}u.prototype.push=function(e,t){var r,a,f,h,u,c=this.strm,d=this.options.chunkSize,p=this.options.dictionary,g=!1;if(this.ended)return !1;a=t===~~t?t:!0===t?s.Z_FINISH:s.Z_NO_FLUSH,"string"==typeof e?c.input=o.binstring2buf(e):"[object ArrayBuffer]"===l.call(e)?c.input=new Uint8Array(e):c.input=e,c.next_in=0,c.avail_in=c.input.length;do{if(0===c.avail_out&&(c.output=new i.Buf8(d),c.next_out=0,c.avail_out=d),(r=n.inflate(c,s.Z_NO_FLUSH))===s.Z_NEED_DICT&&p&&(r=n.inflateSetDictionary(this.strm,p)),r===s.Z_BUF_ERROR&&!0===g&&(r=s.Z_OK,g=!1),r!==s.Z_STREAM_END&&r!==s.Z_OK)return this.onEnd(r),this.ended=!0,!1;c.next_out&&(0!==c.avail_out&&r!==s.Z_STREAM_END&&(0!==c.avail_in||a!==s.Z_FINISH&&a!==s.Z_SYNC_FLUSH)||("string"===this.options.to?(f=o.utf8border(c.output,c.next_out),h=c.next_out-f,u=o.buf2string(c.output,f),c.next_out=h,c.avail_out=d-h,h&&i.arraySet(c.output,c.output,f,h,0),this.onData(u)):this.onData(i.shrinkBuf(c.output,c.next_out)))),0===c.avail_in&&0===c.avail_out&&(g=!0);}while((c.avail_in>0||0===c.avail_out)&&r!==s.Z_STREAM_END);return r===s.Z_STREAM_END&&(a=s.Z_FINISH),a===s.Z_FINISH?(r=n.inflateEnd(this.strm),this.onEnd(r),this.ended=!0,r===s.Z_OK):a!==s.Z_SYNC_FLUSH||(this.onEnd(s.Z_OK),c.avail_out=0,!0)},u.prototype.onData=function(e){this.chunks.push(e);},u.prototype.onEnd=function(e){e===s.Z_OK&&("string"===this.options.to?this.result=this.chunks.join(""):this.result=i.flattenChunks(this.chunks)),this.chunks=[],this.err=e,this.msg=this.strm.msg;},t.Inflate=u,t.inflate=c,t.inflateRaw=function(e,t){return (t=t||{}).raw=!0,c(e,t)},t.ungzip=c;},4236:(e,t)=>{var r="undefined"!=typeof Uint8Array&&"undefined"!=typeof Uint16Array&&"undefined"!=typeof Int32Array;function n(e,t){return Object.prototype.hasOwnProperty.call(e,t)}t.assign=function(e){for(var t=Array.prototype.slice.call(arguments,1);t.length;){var r=t.shift();if(r){if("object"!=typeof r)throw new TypeError(r+"must be non-object");for(var i in r)n(r,i)&&(e[i]=r[i]);}}return e},t.shrinkBuf=function(e,t){return e.length===t?e:e.subarray?e.subarray(0,t):(e.length=t,e)};var i={arraySet:function(e,t,r,n,i){if(t.subarray&&e.subarray)e.set(t.subarray(r,r+n),i);else for(var o=0;o{var n=r(4236),i=!0,o=!0;try{String.fromCharCode.apply(null,[0]);}catch(e){i=!1;}try{String.fromCharCode.apply(null,new Uint8Array(1));}catch(e){o=!1;}for(var s=new n.Buf8(256),a=0;a<256;a++)s[a]=a>=252?6:a>=248?5:a>=240?4:a>=224?3:a>=192?2:1;function f(e,t){if(t<65534&&(e.subarray&&o||!e.subarray&&i))return String.fromCharCode.apply(null,n.shrinkBuf(e,t));for(var r="",s=0;s>>6,t[s++]=128|63&r):r<65536?(t[s++]=224|r>>>12,t[s++]=128|r>>>6&63,t[s++]=128|63&r):(t[s++]=240|r>>>18,t[s++]=128|r>>>12&63,t[s++]=128|r>>>6&63,t[s++]=128|63&r);return t},t.buf2binstring=function(e){return f(e,e.length)},t.binstring2buf=function(e){for(var t=new n.Buf8(e.length),r=0,i=t.length;r4)h[n++]=65533,r+=o-1;else {for(i&=2===o?31:3===o?15:7;o>1&&r1?h[n++]=65533:i<65536?h[n++]=i:(i-=65536,h[n++]=55296|i>>10&1023,h[n++]=56320|1023&i);}return f(h,n)},t.utf8border=function(e,t){var r;for((t=t||e.length)>e.length&&(t=e.length),r=t-1;r>=0&&128==(192&e[r]);)r--;return r<0||0===r?t:r+s[e[r]]>t?r:t};},6069:e=>{e.exports=function(e,t,r,n){for(var i=65535&e|0,o=e>>>16&65535|0,s=0;0!==r;){r-=s=r>2e3?2e3:r;do{o=o+(i=i+t[n++]|0)|0;}while(--s);i%=65521,o%=65521;}return i|o<<16|0};},1619:e=>{e.exports={Z_NO_FLUSH:0,Z_PARTIAL_FLUSH:1,Z_SYNC_FLUSH:2,Z_FULL_FLUSH:3,Z_FINISH:4,Z_BLOCK:5,Z_TREES:6,Z_OK:0,Z_STREAM_END:1,Z_NEED_DICT:2,Z_ERRNO:-1,Z_STREAM_ERROR:-2,Z_DATA_ERROR:-3,Z_BUF_ERROR:-5,Z_NO_COMPRESSION:0,Z_BEST_SPEED:1,Z_BEST_COMPRESSION:9,Z_DEFAULT_COMPRESSION:-1,Z_FILTERED:1,Z_HUFFMAN_ONLY:2,Z_RLE:3,Z_FIXED:4,Z_DEFAULT_STRATEGY:0,Z_BINARY:0,Z_TEXT:1,Z_UNKNOWN:2,Z_DEFLATED:8};},2869:e=>{var t=function(){for(var e,t=[],r=0;r<256;r++){e=r;for(var n=0;n<8;n++)e=1&e?3988292384^e>>>1:e>>>1;t[r]=e;}return t}();e.exports=function(e,r,n,i){var o=t,s=i+n;e^=-1;for(var a=i;a>>8^o[255&(e^r[a])];return -1^e};},405:(e,t,r)=>{var n,i=r(4236),o=r(342),s=r(6069),a=r(2869),f=r(8898),h=-2,l=258,u=262,c=103,d=113,p=666;function g(e,t){return e.msg=f[t],t}function m(e){return (e<<1)-(e>4?9:0)}function y(e){for(var t=e.length;--t>=0;)e[t]=0;}function b(e){var t=e.state,r=t.pending;r>e.avail_out&&(r=e.avail_out),0!==r&&(i.arraySet(e.output,t.pending_buf,t.pending_out,r,e.next_out),e.next_out+=r,t.pending_out+=r,e.total_out+=r,e.avail_out-=r,t.pending-=r,0===t.pending&&(t.pending_out=0));}function v(e,t){o._tr_flush_block(e,e.block_start>=0?e.block_start:-1,e.strstart-e.block_start,t),e.block_start=e.strstart,b(e.strm);}function w(e,t){e.pending_buf[e.pending++]=t;}function _(e,t){e.pending_buf[e.pending++]=t>>>8&255,e.pending_buf[e.pending++]=255&t;}function B(e,t,r,n){var o=e.avail_in;return o>n&&(o=n),0===o?0:(e.avail_in-=o,i.arraySet(t,e.input,e.next_in,o,r),1===e.state.wrap?e.adler=s(e.adler,t,o,r):2===e.state.wrap&&(e.adler=a(e.adler,t,o,r)),e.next_in+=o,e.total_in+=o,o)}function E(e,t){var r,n,i=e.max_chain_length,o=e.strstart,s=e.prev_length,a=e.nice_match,f=e.strstart>e.w_size-u?e.strstart-(e.w_size-u):0,h=e.window,c=e.w_mask,d=e.prev,p=e.strstart+l,g=h[o+s-1],m=h[o+s];e.prev_length>=e.good_match&&(i>>=2),a>e.lookahead&&(a=e.lookahead);do{if(h[(r=t)+s]===m&&h[r+s-1]===g&&h[r]===h[o]&&h[++r]===h[o+1]){o+=2,r++;do{}while(h[++o]===h[++r]&&h[++o]===h[++r]&&h[++o]===h[++r]&&h[++o]===h[++r]&&h[++o]===h[++r]&&h[++o]===h[++r]&&h[++o]===h[++r]&&h[++o]===h[++r]&&os){if(e.match_start=t,s=n,n>=a)break;g=h[o+s-1],m=h[o+s];}}}while((t=d[t&c])>f&&0!=--i);return s<=e.lookahead?s:e.lookahead}function S(e){var t,r,n,o,s,a=e.w_size;do{if(o=e.window_size-e.lookahead-e.strstart,e.strstart>=a+(a-u)){i.arraySet(e.window,e.window,a,a,0),e.match_start-=a,e.strstart-=a,e.block_start-=a,t=r=e.hash_size;do{n=e.head[--t],e.head[t]=n>=a?n-a:0;}while(--r);t=r=a;do{n=e.prev[--t],e.prev[t]=n>=a?n-a:0;}while(--r);o+=a;}if(0===e.strm.avail_in)break;if(r=B(e.strm,e.window,e.strstart+e.lookahead,o),e.lookahead+=r,e.lookahead+e.insert>=3)for(s=e.strstart-e.insert,e.ins_h=e.window[s],e.ins_h=(e.ins_h<=3&&(e.ins_h=(e.ins_h<=3)if(n=o._tr_tally(e,e.strstart-e.match_start,e.match_length-3),e.lookahead-=e.match_length,e.match_length<=e.max_lazy_match&&e.lookahead>=3){e.match_length--;do{e.strstart++,e.ins_h=(e.ins_h<=3&&(e.ins_h=(e.ins_h<4096)&&(e.match_length=2)),e.prev_length>=3&&e.match_length<=e.prev_length){i=e.strstart+e.lookahead-3,n=o._tr_tally(e,e.strstart-1-e.prev_match,e.prev_length-3),e.lookahead-=e.prev_length-1,e.prev_length-=2;do{++e.strstart<=i&&(e.ins_h=(e.ins_h<15&&(a=2,n-=16),o<1||o>9||8!==r||n<8||n>15||t<0||t>9||s<0||s>4)return g(e,h);8===n&&(n=9);var f=new k;return e.state=f,f.strm=e,f.wrap=a,f.gzhead=null,f.w_bits=n,f.w_size=1<e.pending_buf_size-5&&(r=e.pending_buf_size-5);;){if(e.lookahead<=1){if(S(e),0===e.lookahead&&0===t)return 1;if(0===e.lookahead)break}e.strstart+=e.lookahead,e.lookahead=0;var n=e.block_start+r;if((0===e.strstart||e.strstart>=n)&&(e.lookahead=e.strstart-n,e.strstart=n,v(e,!1),0===e.strm.avail_out))return 1;if(e.strstart-e.block_start>=e.w_size-u&&(v(e,!1),0===e.strm.avail_out))return 1}return e.insert=0,4===t?(v(e,!0),0===e.strm.avail_out?3:4):(e.strstart>e.block_start&&(v(e,!1),e.strm.avail_out),1)})),new R(4,4,8,4,A),new R(4,5,16,8,A),new R(4,6,32,32,A),new R(4,4,16,16,C),new R(8,16,32,32,C),new R(8,16,128,128,C),new R(8,32,128,256,C),new R(32,128,258,1024,C),new R(32,258,258,4096,C)],t.deflateInit=function(e,t){return M(e,t,8,15,8,0)},t.deflateInit2=M,t.deflateReset=I,t.deflateResetKeep=x,t.deflateSetHeader=function(e,t){return e&&e.state?2!==e.state.wrap?h:(e.state.gzhead=t,0):h},t.deflate=function(e,t){var r,i,s,f;if(!e||!e.state||t>5||t<0)return e?g(e,h):h;if(i=e.state,!e.output||!e.input&&0!==e.avail_in||i.status===p&&4!==t)return g(e,0===e.avail_out?-5:h);if(i.strm=e,r=i.last_flush,i.last_flush=t,42===i.status)if(2===i.wrap)e.adler=0,w(i,31),w(i,139),w(i,8),i.gzhead?(w(i,(i.gzhead.text?1:0)+(i.gzhead.hcrc?2:0)+(i.gzhead.extra?4:0)+(i.gzhead.name?8:0)+(i.gzhead.comment?16:0)),w(i,255&i.gzhead.time),w(i,i.gzhead.time>>8&255),w(i,i.gzhead.time>>16&255),w(i,i.gzhead.time>>24&255),w(i,9===i.level?2:i.strategy>=2||i.level<2?4:0),w(i,255&i.gzhead.os),i.gzhead.extra&&i.gzhead.extra.length&&(w(i,255&i.gzhead.extra.length),w(i,i.gzhead.extra.length>>8&255)),i.gzhead.hcrc&&(e.adler=a(e.adler,i.pending_buf,i.pending,0)),i.gzindex=0,i.status=69):(w(i,0),w(i,0),w(i,0),w(i,0),w(i,0),w(i,9===i.level?2:i.strategy>=2||i.level<2?4:0),w(i,3),i.status=d);else {var u=8+(i.w_bits-8<<4)<<8;u|=(i.strategy>=2||i.level<2?0:i.level<6?1:6===i.level?2:3)<<6,0!==i.strstart&&(u|=32),u+=31-u%31,i.status=d,_(i,u),0!==i.strstart&&(_(i,e.adler>>>16),_(i,65535&e.adler)),e.adler=1;}if(69===i.status)if(i.gzhead.extra){for(s=i.pending;i.gzindex<(65535&i.gzhead.extra.length)&&(i.pending!==i.pending_buf_size||(i.gzhead.hcrc&&i.pending>s&&(e.adler=a(e.adler,i.pending_buf,i.pending-s,s)),b(e),s=i.pending,i.pending!==i.pending_buf_size));)w(i,255&i.gzhead.extra[i.gzindex]),i.gzindex++;i.gzhead.hcrc&&i.pending>s&&(e.adler=a(e.adler,i.pending_buf,i.pending-s,s)),i.gzindex===i.gzhead.extra.length&&(i.gzindex=0,i.status=73);}else i.status=73;if(73===i.status)if(i.gzhead.name){s=i.pending;do{if(i.pending===i.pending_buf_size&&(i.gzhead.hcrc&&i.pending>s&&(e.adler=a(e.adler,i.pending_buf,i.pending-s,s)),b(e),s=i.pending,i.pending===i.pending_buf_size)){f=1;break}f=i.gzindexs&&(e.adler=a(e.adler,i.pending_buf,i.pending-s,s)),0===f&&(i.gzindex=0,i.status=91);}else i.status=91;if(91===i.status)if(i.gzhead.comment){s=i.pending;do{if(i.pending===i.pending_buf_size&&(i.gzhead.hcrc&&i.pending>s&&(e.adler=a(e.adler,i.pending_buf,i.pending-s,s)),b(e),s=i.pending,i.pending===i.pending_buf_size)){f=1;break}f=i.gzindexs&&(e.adler=a(e.adler,i.pending_buf,i.pending-s,s)),0===f&&(i.status=c);}else i.status=c;if(i.status===c&&(i.gzhead.hcrc?(i.pending+2>i.pending_buf_size&&b(e),i.pending+2<=i.pending_buf_size&&(w(i,255&e.adler),w(i,e.adler>>8&255),e.adler=0,i.status=d)):i.status=d),0!==i.pending){if(b(e),0===e.avail_out)return i.last_flush=-1,0}else if(0===e.avail_in&&m(t)<=m(r)&&4!==t)return g(e,-5);if(i.status===p&&0!==e.avail_in)return g(e,-5);if(0!==e.avail_in||0!==i.lookahead||0!==t&&i.status!==p){var B=2===i.strategy?function(e,t){for(var r;;){if(0===e.lookahead&&(S(e),0===e.lookahead)){if(0===t)return 1;break}if(e.match_length=0,r=o._tr_tally(e,0,e.window[e.strstart]),e.lookahead--,e.strstart++,r&&(v(e,!1),0===e.strm.avail_out))return 1}return e.insert=0,4===t?(v(e,!0),0===e.strm.avail_out?3:4):e.last_lit&&(v(e,!1),0===e.strm.avail_out)?1:2}(i,t):3===i.strategy?function(e,t){for(var r,n,i,s,a=e.window;;){if(e.lookahead<=l){if(S(e),e.lookahead<=l&&0===t)return 1;if(0===e.lookahead)break}if(e.match_length=0,e.lookahead>=3&&e.strstart>0&&(n=a[i=e.strstart-1])===a[++i]&&n===a[++i]&&n===a[++i]){s=e.strstart+l;do{}while(n===a[++i]&&n===a[++i]&&n===a[++i]&&n===a[++i]&&n===a[++i]&&n===a[++i]&&n===a[++i]&&n===a[++i]&&ie.lookahead&&(e.match_length=e.lookahead);}if(e.match_length>=3?(r=o._tr_tally(e,1,e.match_length-3),e.lookahead-=e.match_length,e.strstart+=e.match_length,e.match_length=0):(r=o._tr_tally(e,0,e.window[e.strstart]),e.lookahead--,e.strstart++),r&&(v(e,!1),0===e.strm.avail_out))return 1}return e.insert=0,4===t?(v(e,!0),0===e.strm.avail_out?3:4):e.last_lit&&(v(e,!1),0===e.strm.avail_out)?1:2}(i,t):n[i.level].func(i,t);if(3!==B&&4!==B||(i.status=p),1===B||3===B)return 0===e.avail_out&&(i.last_flush=-1),0;if(2===B&&(1===t?o._tr_align(i):5!==t&&(o._tr_stored_block(i,0,0,!1),3===t&&(y(i.head),0===i.lookahead&&(i.strstart=0,i.block_start=0,i.insert=0))),b(e),0===e.avail_out))return i.last_flush=-1,0}return 4!==t?0:i.wrap<=0?1:(2===i.wrap?(w(i,255&e.adler),w(i,e.adler>>8&255),w(i,e.adler>>16&255),w(i,e.adler>>24&255),w(i,255&e.total_in),w(i,e.total_in>>8&255),w(i,e.total_in>>16&255),w(i,e.total_in>>24&255)):(_(i,e.adler>>>16),_(i,65535&e.adler)),b(e),i.wrap>0&&(i.wrap=-i.wrap),0!==i.pending?0:1)},t.deflateEnd=function(e){var t;return e&&e.state?42!==(t=e.state.status)&&69!==t&&73!==t&&91!==t&&t!==c&&t!==d&&t!==p?g(e,h):(e.state=null,t===d?g(e,-3):0):h},t.deflateSetDictionary=function(e,t){var r,n,o,a,f,l,u,c,d=t.length;if(!e||!e.state)return h;if(2===(a=(r=e.state).wrap)||1===a&&42!==r.status||r.lookahead)return h;for(1===a&&(e.adler=s(e.adler,t,d,0)),r.wrap=0,d>=r.w_size&&(0===a&&(y(r.head),r.strstart=0,r.block_start=0,r.insert=0),c=new i.Buf8(r.w_size),i.arraySet(c,t,d-r.w_size,r.w_size,0),t=c,d=r.w_size),f=e.avail_in,l=e.next_in,u=e.input,e.avail_in=d,e.next_in=0,e.input=t,S(r);r.lookahead>=3;){n=r.strstart,o=r.lookahead-2;do{r.ins_h=(r.ins_h<{e.exports=function(){this.text=0,this.time=0,this.xflags=0,this.os=0,this.extra=null,this.extra_len=0,this.name="",this.comment="",this.hcrc=0,this.done=!1;};},4264:e=>{e.exports=function(e,t){var r,n,i,o,s,a,f,h,l,u,c,d,p,g,m,y,b,v,w,_,B,E,S,A,C;r=e.state,n=e.next_in,A=e.input,i=n+(e.avail_in-5),o=e.next_out,C=e.output,s=o-(t-e.avail_out),a=o+(e.avail_out-257),f=r.dmax,h=r.wsize,l=r.whave,u=r.wnext,c=r.window,d=r.hold,p=r.bits,g=r.lencode,m=r.distcode,y=(1<>>=w=v>>>24,p-=w,0==(w=v>>>16&255))C[o++]=65535&v;else {if(!(16&w)){if(0==(64&w)){v=g[(65535&v)+(d&(1<>>=w,p-=w),p<15&&(d+=A[n++]<>>=w=v>>>24,p-=w,!(16&(w=v>>>16&255))){if(0==(64&w)){v=m[(65535&v)+(d&(1<f){e.msg="invalid distance too far back",r.mode=30;break e}if(d>>>=w,p-=w,B>(w=o-s)){if((w=B-w)>l&&r.sane){e.msg="invalid distance too far back",r.mode=30;break e}if(E=0,S=c,0===u){if(E+=h-w,w<_){_-=w;do{C[o++]=c[E++];}while(--w);E=o-B,S=C;}}else if(u2;)C[o++]=S[E++],C[o++]=S[E++],C[o++]=S[E++],_-=3;_&&(C[o++]=S[E++],_>1&&(C[o++]=S[E++]));}else {E=o-B;do{C[o++]=C[E++],C[o++]=C[E++],C[o++]=C[E++],_-=3;}while(_>2);_&&(C[o++]=C[E++],_>1&&(C[o++]=C[E++]));}break}}break}}while(n>3,d&=(1<<(p-=_<<3))-1,e.next_in=n,e.next_out=o,e.avail_in=n{var n=r(4236),i=r(6069),o=r(2869),s=r(4264),a=r(9241),f=-2,h=12,l=30;function u(e){return (e>>>24&255)+(e>>>8&65280)+((65280&e)<<8)+((255&e)<<24)}function c(){this.mode=0,this.last=!1,this.wrap=0,this.havedict=!1,this.flags=0,this.dmax=0,this.check=0,this.total=0,this.head=null,this.wbits=0,this.wsize=0,this.whave=0,this.wnext=0,this.window=null,this.hold=0,this.bits=0,this.length=0,this.offset=0,this.extra=0,this.lencode=null,this.distcode=null,this.lenbits=0,this.distbits=0,this.ncode=0,this.nlen=0,this.ndist=0,this.have=0,this.next=null,this.lens=new n.Buf16(320),this.work=new n.Buf16(288),this.lendyn=null,this.distdyn=null,this.sane=0,this.back=0,this.was=0;}function d(e){var t;return e&&e.state?(t=e.state,e.total_in=e.total_out=t.total=0,e.msg="",t.wrap&&(e.adler=1&t.wrap),t.mode=1,t.last=0,t.havedict=0,t.dmax=32768,t.head=null,t.hold=0,t.bits=0,t.lencode=t.lendyn=new n.Buf32(852),t.distcode=t.distdyn=new n.Buf32(592),t.sane=1,t.back=-1,0):f}function p(e){var t;return e&&e.state?((t=e.state).wsize=0,t.whave=0,t.wnext=0,d(e)):f}function g(e,t){var r,n;return e&&e.state?(n=e.state,t<0?(r=0,t=-t):(r=1+(t>>4),t<48&&(t&=15)),t&&(t<8||t>15)?f:(null!==n.window&&n.wbits!==t&&(n.window=null),n.wrap=r,n.wbits=t,p(e))):f}function m(e,t){var r,n;return e?(n=new c,e.state=n,n.window=null,0!==(r=g(e,t))&&(e.state=null),r):f}var y,b,v=!0;function w(e){if(v){var t;for(y=new n.Buf32(512),b=new n.Buf32(32),t=0;t<144;)e.lens[t++]=8;for(;t<256;)e.lens[t++]=9;for(;t<280;)e.lens[t++]=7;for(;t<288;)e.lens[t++]=8;for(a(1,e.lens,0,288,y,0,e.work,{bits:9}),t=0;t<32;)e.lens[t++]=5;a(2,e.lens,0,32,b,0,e.work,{bits:5}),v=!1;}e.lencode=y,e.lenbits=9,e.distcode=b,e.distbits=5;}function _(e,t,r,i){var o,s=e.state;return null===s.window&&(s.wsize=1<=s.wsize?(n.arraySet(s.window,t,r-s.wsize,s.wsize,0),s.wnext=0,s.whave=s.wsize):((o=s.wsize-s.wnext)>i&&(o=i),n.arraySet(s.window,t,r-i,o,s.wnext),(i-=o)?(n.arraySet(s.window,t,r-i,i,0),s.wnext=i,s.whave=s.wsize):(s.wnext+=o,s.wnext===s.wsize&&(s.wnext=0),s.whave>>8&255,r.check=o(r.check,L,2,0),b=0,v=0,r.mode=2;break}if(r.flags=0,r.head&&(r.head.done=!1),!(1&r.wrap)||(((255&b)<<8)+(b>>8))%31){e.msg="incorrect header check",r.mode=l;break}if(8!=(15&b)){e.msg="unknown compression method",r.mode=l;break}if(v-=4,O=8+(15&(b>>>=4)),0===r.wbits)r.wbits=O;else if(O>r.wbits){e.msg="invalid window size",r.mode=l;break}r.dmax=1<>8&1),512&r.flags&&(L[0]=255&b,L[1]=b>>>8&255,r.check=o(r.check,L,2,0)),b=0,v=0,r.mode=3;case 3:for(;v<32;){if(0===m)break e;m--,b+=c[p++]<>>8&255,L[2]=b>>>16&255,L[3]=b>>>24&255,r.check=o(r.check,L,4,0)),b=0,v=0,r.mode=4;case 4:for(;v<16;){if(0===m)break e;m--,b+=c[p++]<>8),512&r.flags&&(L[0]=255&b,L[1]=b>>>8&255,r.check=o(r.check,L,2,0)),b=0,v=0,r.mode=5;case 5:if(1024&r.flags){for(;v<16;){if(0===m)break e;m--,b+=c[p++]<>>8&255,r.check=o(r.check,L,2,0)),b=0,v=0;}else r.head&&(r.head.extra=null);r.mode=6;case 6:if(1024&r.flags&&((S=r.length)>m&&(S=m),S&&(r.head&&(O=r.head.extra_len-r.length,r.head.extra||(r.head.extra=new Array(r.head.extra_len)),n.arraySet(r.head.extra,c,p,S,O)),512&r.flags&&(r.check=o(r.check,c,S,p)),m-=S,p+=S,r.length-=S),r.length))break e;r.length=0,r.mode=7;case 7:if(2048&r.flags){if(0===m)break e;S=0;do{O=c[p+S++],r.head&&O&&r.length<65536&&(r.head.name+=String.fromCharCode(O));}while(O&&S>9&1,r.head.done=!0),e.adler=r.check=0,r.mode=h;break;case 10:for(;v<32;){if(0===m)break e;m--,b+=c[p++]<>>=7&v,v-=7&v,r.mode=27;break}for(;v<3;){if(0===m)break e;m--,b+=c[p++]<>>=1)){case 0:r.mode=14;break;case 1:if(w(r),r.mode=20,6===t){b>>>=2,v-=2;break e}break;case 2:r.mode=17;break;case 3:e.msg="invalid block type",r.mode=l;}b>>>=2,v-=2;break;case 14:for(b>>>=7&v,v-=7&v;v<32;){if(0===m)break e;m--,b+=c[p++]<>>16^65535)){e.msg="invalid stored block lengths",r.mode=l;break}if(r.length=65535&b,b=0,v=0,r.mode=15,6===t)break e;case 15:r.mode=16;case 16:if(S=r.length){if(S>m&&(S=m),S>y&&(S=y),0===S)break e;n.arraySet(d,c,p,S,g),m-=S,p+=S,y-=S,g+=S,r.length-=S;break}r.mode=h;break;case 17:for(;v<14;){if(0===m)break e;m--,b+=c[p++]<>>=5,v-=5,r.ndist=1+(31&b),b>>>=5,v-=5,r.ncode=4+(15&b),b>>>=4,v-=4,r.nlen>286||r.ndist>30){e.msg="too many length or distance symbols",r.mode=l;break}r.have=0,r.mode=18;case 18:for(;r.have>>=3,v-=3;}for(;r.have<19;)r.lens[z[r.have++]]=0;if(r.lencode=r.lendyn,r.lenbits=7,U={bits:r.lenbits},T=a(0,r.lens,0,19,r.lencode,0,r.work,U),r.lenbits=U.bits,T){e.msg="invalid code lengths set",r.mode=l;break}r.have=0,r.mode=19;case 19:for(;r.have>>16&255,x=65535&N,!((R=N>>>24)<=v);){if(0===m)break e;m--,b+=c[p++]<>>=R,v-=R,r.lens[r.have++]=x;else {if(16===x){for(P=R+2;v>>=R,v-=R,0===r.have){e.msg="invalid bit length repeat",r.mode=l;break}O=r.lens[r.have-1],S=3+(3&b),b>>>=2,v-=2;}else if(17===x){for(P=R+3;v>>=R)),b>>>=3,v-=3;}else {for(P=R+7;v>>=R)),b>>>=7,v-=7;}if(r.have+S>r.nlen+r.ndist){e.msg="invalid bit length repeat",r.mode=l;break}for(;S--;)r.lens[r.have++]=O;}}if(r.mode===l)break;if(0===r.lens[256]){e.msg="invalid code -- missing end-of-block",r.mode=l;break}if(r.lenbits=9,U={bits:r.lenbits},T=a(1,r.lens,0,r.nlen,r.lencode,0,r.work,U),r.lenbits=U.bits,T){e.msg="invalid literal/lengths set",r.mode=l;break}if(r.distbits=6,r.distcode=r.distdyn,U={bits:r.distbits},T=a(2,r.lens,r.nlen,r.ndist,r.distcode,0,r.work,U),r.distbits=U.bits,T){e.msg="invalid distances set",r.mode=l;break}if(r.mode=20,6===t)break e;case 20:r.mode=21;case 21:if(m>=6&&y>=258){e.next_out=g,e.avail_out=y,e.next_in=p,e.avail_in=m,r.hold=b,r.bits=v,s(e,E),g=e.next_out,d=e.output,y=e.avail_out,p=e.next_in,c=e.input,m=e.avail_in,b=r.hold,v=r.bits,r.mode===h&&(r.back=-1);break}for(r.back=0;k=(N=r.lencode[b&(1<>>16&255,x=65535&N,!((R=N>>>24)<=v);){if(0===m)break e;m--,b+=c[p++]<>I)])>>>16&255,x=65535&N,!(I+(R=N>>>24)<=v);){if(0===m)break e;m--,b+=c[p++]<>>=I,v-=I,r.back+=I;}if(b>>>=R,v-=R,r.back+=R,r.length=x,0===k){r.mode=26;break}if(32&k){r.back=-1,r.mode=h;break}if(64&k){e.msg="invalid literal/length code",r.mode=l;break}r.extra=15&k,r.mode=22;case 22:if(r.extra){for(P=r.extra;v>>=r.extra,v-=r.extra,r.back+=r.extra;}r.was=r.length,r.mode=23;case 23:for(;k=(N=r.distcode[b&(1<>>16&255,x=65535&N,!((R=N>>>24)<=v);){if(0===m)break e;m--,b+=c[p++]<>I)])>>>16&255,x=65535&N,!(I+(R=N>>>24)<=v);){if(0===m)break e;m--,b+=c[p++]<>>=I,v-=I,r.back+=I;}if(b>>>=R,v-=R,r.back+=R,64&k){e.msg="invalid distance code",r.mode=l;break}r.offset=x,r.extra=15&k,r.mode=24;case 24:if(r.extra){for(P=r.extra;v>>=r.extra,v-=r.extra,r.back+=r.extra;}if(r.offset>r.dmax){e.msg="invalid distance too far back",r.mode=l;break}r.mode=25;case 25:if(0===y)break e;if(S=E-y,r.offset>S){if((S=r.offset-S)>r.whave&&r.sane){e.msg="invalid distance too far back",r.mode=l;break}S>r.wnext?(S-=r.wnext,A=r.wsize-S):A=r.wnext-S,S>r.length&&(S=r.length),C=r.window;}else C=d,A=g-r.offset,S=r.length;S>y&&(S=y),y-=S,r.length-=S;do{d[g++]=C[A++];}while(--S);0===r.length&&(r.mode=21);break;case 26:if(0===y)break e;d[g++]=r.length,y--,r.mode=21;break;case 27:if(r.wrap){for(;v<32;){if(0===m)break e;m--,b|=c[p++]<{var n=r(4236),i=[3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258,0,0],o=[16,16,16,16,16,16,16,16,17,17,17,17,18,18,18,18,19,19,19,19,20,20,20,20,21,21,21,21,16,72,78],s=[1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,0,0],a=[16,16,16,16,17,17,18,18,19,19,20,20,21,21,22,22,23,23,24,24,25,25,26,26,27,27,28,28,29,29,64,64];e.exports=function(e,t,r,f,h,l,u,c){var d,p,g,m,y,b,v,w,_,B=c.bits,E=0,S=0,A=0,C=0,R=0,k=0,x=0,I=0,M=0,F=0,O=null,T=0,U=new n.Buf16(16),P=new n.Buf16(16),N=null,L=0;for(E=0;E<=15;E++)U[E]=0;for(S=0;S=1&&0===U[C];C--);if(R>C&&(R=C),0===C)return h[l++]=20971520,h[l++]=20971520,c.bits=1,0;for(A=1;A0&&(0===e||1!==C))return -1;for(P[1]=0,E=1;E<15;E++)P[E+1]=P[E]+U[E];for(S=0;S852||2===e&&M>592)return 1;for(;;){v=E-x,u[S]b?(w=N[L+u[S]],_=O[T+u[S]]):(w=96,_=0),d=1<>x)+(p-=d)]=v<<24|w<<16|_|0;}while(0!==p);for(d=1<>=1;if(0!==d?(F&=d-1,F+=d):F=0,S++,0==--U[E]){if(E===C)break;E=t[r+u[S]];}if(E>R&&(F&m)!==g){for(0===x&&(x=R),y+=A,I=1<<(k=E-x);k+x852||2===e&&M>592)return 1;h[g=F&m]=R<<24|k<<16|y-l|0;}}return 0!==F&&(h[y+F]=E-x<<24|64<<16|0),c.bits=R,0};},8898:e=>{e.exports={2:"need dictionary",1:"stream end",0:"","-1":"file error","-2":"stream error","-3":"data error","-4":"insufficient memory","-5":"buffer error","-6":"incompatible version"};},342:(e,t,r)=>{var n=r(4236);function i(e){for(var t=e.length;--t>=0;)e[t]=0;}var o=[0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0],s=[0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13],a=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7],f=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15],h=new Array(576);i(h);var l=new Array(60);i(l);var u=new Array(512);i(u);var c=new Array(256);i(c);var d=new Array(29);i(d);var p,g,m,y=new Array(30);function b(e,t,r,n,i){this.static_tree=e,this.extra_bits=t,this.extra_base=r,this.elems=n,this.max_length=i,this.has_stree=e&&e.length;}function v(e,t){this.dyn_tree=e,this.max_code=0,this.stat_desc=t;}function w(e){return e<256?u[e]:u[256+(e>>>7)]}function _(e,t){e.pending_buf[e.pending++]=255&t,e.pending_buf[e.pending++]=t>>>8&255;}function B(e,t,r){e.bi_valid>16-r?(e.bi_buf|=t<>16-e.bi_valid,e.bi_valid+=r-16):(e.bi_buf|=t<>>=1,r<<=1;}while(--t>0);return r>>>1}function A(e,t,r){var n,i,o=new Array(16),s=0;for(n=1;n<=15;n++)o[n]=s=s+r[n-1]<<1;for(i=0;i<=t;i++){var a=e[2*i+1];0!==a&&(e[2*i]=S(o[a]++,a));}}function C(e){var t;for(t=0;t<286;t++)e.dyn_ltree[2*t]=0;for(t=0;t<30;t++)e.dyn_dtree[2*t]=0;for(t=0;t<19;t++)e.bl_tree[2*t]=0;e.dyn_ltree[512]=1,e.opt_len=e.static_len=0,e.last_lit=e.matches=0;}function R(e){e.bi_valid>8?_(e,e.bi_buf):e.bi_valid>0&&(e.pending_buf[e.pending++]=e.bi_buf),e.bi_buf=0,e.bi_valid=0;}function k(e,t,r,n){var i=2*t,o=2*r;return e[i]>1;r>=1;r--)x(e,o,r);i=f;do{r=e.heap[1],e.heap[1]=e.heap[e.heap_len--],x(e,o,1),n=e.heap[1],e.heap[--e.heap_max]=r,e.heap[--e.heap_max]=n,o[2*i]=o[2*r]+o[2*n],e.depth[i]=(e.depth[r]>=e.depth[n]?e.depth[r]:e.depth[n])+1,o[2*r+1]=o[2*n+1]=i,e.heap[1]=i++,x(e,o,1);}while(e.heap_len>=2);e.heap[--e.heap_max]=e.heap[1],function(e,t){var r,n,i,o,s,a,f=t.dyn_tree,h=t.max_code,l=t.stat_desc.static_tree,u=t.stat_desc.has_stree,c=t.stat_desc.extra_bits,d=t.stat_desc.extra_base,p=t.stat_desc.max_length,g=0;for(o=0;o<=15;o++)e.bl_count[o]=0;for(f[2*e.heap[e.heap_max]+1]=0,r=e.heap_max+1;r<573;r++)(o=f[2*f[2*(n=e.heap[r])+1]+1]+1)>p&&(o=p,g++),f[2*n+1]=o,n>h||(e.bl_count[o]++,s=0,n>=d&&(s=c[n-d]),a=f[2*n],e.opt_len+=a*(o+s),u&&(e.static_len+=a*(l[2*n+1]+s)));if(0!==g){do{for(o=p-1;0===e.bl_count[o];)o--;e.bl_count[o]--,e.bl_count[o+1]+=2,e.bl_count[p]--,g-=2;}while(g>0);for(o=p;0!==o;o--)for(n=e.bl_count[o];0!==n;)(i=e.heap[--r])>h||(f[2*i+1]!==o&&(e.opt_len+=(o-f[2*i+1])*f[2*i],f[2*i+1]=o),n--);}}(e,t),A(o,h,e.bl_count);}function F(e,t,r){var n,i,o=-1,s=t[1],a=0,f=7,h=4;for(0===s&&(f=138,h=3),t[2*(r+1)+1]=65535,n=0;n<=r;n++)i=s,s=t[2*(n+1)+1],++a>=7;n<30;n++)for(y[n]=i<<7,e=0;e<1<0?(2===e.strm.data_type&&(e.strm.data_type=function(e){var t,r=4093624447;for(t=0;t<=31;t++,r>>>=1)if(1&r&&0!==e.dyn_ltree[2*t])return 0;if(0!==e.dyn_ltree[18]||0!==e.dyn_ltree[20]||0!==e.dyn_ltree[26])return 1;for(t=32;t<256;t++)if(0!==e.dyn_ltree[2*t])return 1;return 0}(e)),M(e,e.l_desc),M(e,e.d_desc),s=function(e){var t;for(F(e,e.dyn_ltree,e.l_desc.max_code),F(e,e.dyn_dtree,e.d_desc.max_code),M(e,e.bl_desc),t=18;t>=3&&0===e.bl_tree[2*f[t]+1];t--);return e.opt_len+=3*(t+1)+5+5+4,t}(e),i=e.opt_len+3+7>>>3,(o=e.static_len+3+7>>>3)<=i&&(i=o)):i=o=r+5,r+4<=i&&-1!==t?U(e,t,r,n):4===e.strategy||o===i?(B(e,2+(n?1:0),3),I(e,h,l)):(B(e,4+(n?1:0),3),function(e,t,r,n){var i;for(B(e,t-257,5),B(e,r-1,5),B(e,n-4,4),i=0;i>>8&255,e.pending_buf[e.d_buf+2*e.last_lit+1]=255&t,e.pending_buf[e.l_buf+e.last_lit]=255&r,e.last_lit++,0===t?e.dyn_ltree[2*r]++:(e.matches++,t--,e.dyn_ltree[2*(c[r]+256+1)]++,e.dyn_dtree[2*w(t)]++),e.last_lit===e.lit_bufsize-1},t._tr_align=function(e){B(e,2,3),E(e,256,h),function(e){16===e.bi_valid?(_(e,e.bi_buf),e.bi_buf=0,e.bi_valid=0):e.bi_valid>=8&&(e.pending_buf[e.pending++]=255&e.bi_buf,e.bi_buf>>=8,e.bi_valid-=8);}(e);};},2292:e=>{e.exports=function(){this.input=null,this.next_in=0,this.avail_in=0,this.total_in=0,this.output=null,this.next_out=0,this.avail_out=0,this.total_out=0,this.msg="",this.state=null,this.data_type=2,this.adler=0;};},2587:e=>{function t(e,t){return Object.prototype.hasOwnProperty.call(e,t)}e.exports=function(e,r,n,i){r=r||"&",n=n||"=";var o={};if("string"!=typeof e||0===e.length)return o;var s=/\+/g;e=e.split(r);var a=1e3;i&&"number"==typeof i.maxKeys&&(a=i.maxKeys);var f=e.length;a>0&&f>a&&(f=a);for(var h=0;h=0?(l=p.substr(0,g),u=p.substr(g+1)):(l=p,u=""),c=decodeURIComponent(l),d=decodeURIComponent(u),t(o,c)?Array.isArray(o[c])?o[c].push(d):o[c]=[o[c],d]:o[c]=d;}return o};},2361:e=>{var t=function(e){switch(typeof e){case"string":return e;case"boolean":return e?"true":"false";case"number":return isFinite(e)?e:"";default:return ""}};e.exports=function(e,r,n,i){return r=r||"&",n=n||"=",null===e&&(e=void 0),"object"==typeof e?Object.keys(e).map((function(i){var o=encodeURIComponent(t(i))+n;return Array.isArray(e[i])?e[i].map((function(e){return o+encodeURIComponent(t(e))})).join(r):o+encodeURIComponent(t(e[i]))})).join(r):i?encodeURIComponent(t(i))+n+encodeURIComponent(t(e)):""};},7673:(e,t,r)=>{t.decode=t.parse=r(2587),t.encode=t.stringify=r(2361);},1269:e=>{class t{constructor(e={}){if(!(e.maxSize&&e.maxSize>0))throw new TypeError("`maxSize` must be a number greater than 0");this.maxSize=e.maxSize,this.cache=new Map,this.oldCache=new Map,this._size=0;}_set(e,t){this.cache.set(e,t),this._size++,this._size>=this.maxSize&&(this._size=0,this.oldCache=this.cache,this.cache=new Map);}get(e){if(this.cache.has(e))return this.cache.get(e);if(this.oldCache.has(e)){const t=this.oldCache.get(e);return this.oldCache.delete(e),this._set(e,t),t}}set(e,t){return this.cache.has(e)?this.cache.set(e,t):this._set(e,t),this}has(e){return this.cache.has(e)||this.oldCache.has(e)}peek(e){return this.cache.has(e)?this.cache.get(e):this.oldCache.has(e)?this.oldCache.get(e):void 0}delete(e){const t=this.cache.delete(e);return t&&this._size--,this.oldCache.delete(e)||t}clear(){this.cache.clear(),this.oldCache.clear(),this._size=0;}*keys(){for(const[e]of this)yield e;}*values(){for(const[,e]of this)yield e;}*[Symbol.iterator](){for(const e of this.cache)yield e;for(const e of this.oldCache){const[t]=e;this.cache.has(t)||(yield e);}}get size(){let e=0;for(const t of this.oldCache.keys())this.cache.has(t)||e++;return this._size+e}}e.exports=t;},2511:function(e,t,r){var n;e=r.nmd(e),function(i){t&&t.nodeType,e&&e.nodeType;var o="object"==typeof r.g&&r.g;o.global!==o&&o.window!==o&&o.self;var s,a=2147483647,f=36,h=/^xn--/,l=/[^\x20-\x7E]/,u=/[\x2E\u3002\uFF0E\uFF61]/g,c={overflow:"Overflow: input needs wider integers to process","not-basic":"Illegal input >= 0x80 (not a basic code point)","invalid-input":"Invalid input"},d=Math.floor,p=String.fromCharCode;function g(e){throw RangeError(c[e])}function m(e,t){for(var r=e.length,n=[];r--;)n[r]=t(e[r]);return n}function y(e,t){var r=e.split("@"),n="";return r.length>1&&(n=r[0]+"@",e=r[1]),n+m((e=e.replace(u,".")).split("."),t).join(".")}function b(e){for(var t,r,n=[],i=0,o=e.length;i=55296&&t<=56319&&i65535&&(t+=p((e-=65536)>>>10&1023|55296),e=56320|1023&e),t+p(e)})).join("")}function w(e,t){return e+22+75*(e<26)-((0!=t)<<5)}function _(e,t,r){var n=0;for(e=r?d(e/700):e>>1,e+=d(e/t);e>455;n+=f)e=d(e/35);return d(n+36*e/(e+38))}function B(e){var t,r,n,i,o,s,h,l,u,c,p,m=[],y=e.length,b=0,w=128,B=72;for((r=e.lastIndexOf("-"))<0&&(r=0),n=0;n=128&&g("not-basic"),m.push(e.charCodeAt(n));for(i=r>0?r+1:0;i=y&&g("invalid-input"),((l=(p=e.charCodeAt(i++))-48<10?p-22:p-65<26?p-65:p-97<26?p-97:f)>=f||l>d((a-b)/s))&&g("overflow"),b+=l*s,!(l<(u=h<=B?1:h>=B+26?26:h-B));h+=f)s>d(a/(c=f-u))&&g("overflow"),s*=c;B=_(b-o,t=m.length+1,0==o),d(b/t)>a-w&&g("overflow"),w+=d(b/t),b%=t,m.splice(b++,0,w);}return v(m)}function E(e){var t,r,n,i,o,s,h,l,u,c,m,y,v,B,E,S=[];for(y=(e=b(e)).length,t=128,r=0,o=72,s=0;s=t&&md((a-r)/(v=n+1))&&g("overflow"),r+=(h-t)*v,t=h,s=0;sa&&g("overflow"),m==t){for(l=r,u=f;!(l<(c=u<=o?1:u>=o+26?26:u-o));u+=f)E=l-c,B=f-c,S.push(p(w(c+E%B,0))),l=d(E/B);S.push(p(w(l,0))),o=_(r,v,n==i),r=0,++n;}++r,++t;}return S.join("")}s={version:"1.3.2",ucs2:{decode:b,encode:v},decode:B,encode:E,toASCII:function(e){return y(e,(function(e){return l.test(e)?"xn--"+E(e):e}))},toUnicode:function(e){return y(e,(function(e){return h.test(e)?B(e.slice(4).toLowerCase()):e}))}},void 0===(n=function(){return s}.call(t,r,t,e))||(e.exports=n);}();},8575:(e,t,r)=>{var n=r(2511),i=r(2502);function o(){this.protocol=null,this.slashes=null,this.auth=null,this.host=null,this.port=null,this.hostname=null,this.hash=null,this.search=null,this.query=null,this.pathname=null,this.path=null,this.href=null;}t.parse=v,t.resolve=function(e,t){return v(e,!1,!0).resolve(t)},t.resolveObject=function(e,t){return e?v(e,!1,!0).resolveObject(t):t},t.format=function(e){return i.isString(e)&&(e=v(e)),e instanceof o?e.format():o.prototype.format.call(e)},t.Url=o;var s=/^([a-z0-9.+-]+:)/i,a=/:[0-9]*$/,f=/^(\/\/?(?!\/)[^\?\s]*)(\?[^\s]*)?$/,h=["{","}","|","\\","^","`"].concat(["<",">",'"',"`"," ","\r","\n","\t"]),l=["'"].concat(h),u=["%","/","?",";","#"].concat(l),c=["/","?","#"],d=/^[+a-z0-9A-Z_-]{0,63}$/,p=/^([+a-z0-9A-Z_-]{0,63})(.*)$/,g={javascript:!0,"javascript:":!0},m={javascript:!0,"javascript:":!0},y={http:!0,https:!0,ftp:!0,gopher:!0,file:!0,"http:":!0,"https:":!0,"ftp:":!0,"gopher:":!0,"file:":!0},b=r(7673);function v(e,t,r){if(e&&i.isObject(e)&&e instanceof o)return e;var n=new o;return n.parse(e,t,r),n}o.prototype.parse=function(e,t,r){if(!i.isString(e))throw new TypeError("Parameter 'url' must be a string, not "+typeof e);var o=e.indexOf("?"),a=-1!==o&&o127?O+="x":O+=F[T];if(!O.match(d)){var P=I.slice(0,R),N=I.slice(R+1),L=F.match(p);L&&(P.push(L[1]),N.unshift(L[2])),N.length&&(v="/"+N.join(".")+v),this.hostname=P.join(".");break}}}this.hostname.length>255?this.hostname="":this.hostname=this.hostname.toLowerCase(),x||(this.hostname=n.toASCII(this.hostname));var z=this.port?":"+this.port:"",D=this.hostname||"";this.host=D+z,this.href+=this.host,x&&(this.hostname=this.hostname.substr(1,this.hostname.length-2),"/"!==v[0]&&(v="/"+v));}if(!g[B])for(R=0,M=l.length;R0)&&r.host.split("@"))&&(r.auth=x.shift(),r.host=r.hostname=x.shift())),r.search=e.search,r.query=e.query,i.isNull(r.pathname)&&i.isNull(r.search)||(r.path=(r.pathname?r.pathname:"")+(r.search?r.search:"")),r.href=r.format(),r;if(!E.length)return r.pathname=null,r.search?r.path="/"+r.search:r.path=null,r.href=r.format(),r;for(var A=E.slice(-1)[0],C=(r.host||e.host||E.length>1)&&("."===A||".."===A)||""===A,R=0,k=E.length;k>=0;k--)"."===(A=E[k])?E.splice(k,1):".."===A?(E.splice(k,1),R++):R&&(E.splice(k,1),R--);if(!_&&!B)for(;R--;R)E.unshift("..");!_||""===E[0]||E[0]&&"/"===E[0].charAt(0)||E.unshift(""),C&&"/"!==E.join("/").substr(-1)&&E.push("");var x,I=""===E[0]||E[0]&&"/"===E[0].charAt(0);return S&&(r.hostname=r.host=I?"":E.length?E.shift():"",(x=!!(r.host&&r.host.indexOf("@")>0)&&r.host.split("@"))&&(r.auth=x.shift(),r.host=r.hostname=x.shift())),(_=_||r.host&&E.length)&&!I&&E.unshift(""),E.length?r.pathname=E.join("/"):(r.pathname=null,r.path=null),i.isNull(r.pathname)&&i.isNull(r.search)||(r.path=(r.pathname?r.pathname:"")+(r.search?r.search:"")),r.auth=e.auth||r.auth,r.slashes=r.slashes||e.slashes,r.href=r.format(),r},o.prototype.parseHost=function(){var e=this.host,t=a.exec(e);t&&(":"!==(t=t[0])&&(this.port=t.substr(1)),e=e.substr(0,e.length-t.length)),e&&(this.hostname=e);};},2502:e=>{e.exports={isString:function(e){return "string"==typeof e},isObject:function(e){return "object"==typeof e&&null!==e},isNull:function(e){return null===e},isNullOrUndefined:function(e){return null==e}};},7067:()=>{}},t={};function r(n){var i=t[n];if(void 0!==i)return i.exports;var o=t[n]={id:n,loaded:!1,exports:{}};return e[n].call(o.exports,o,o.exports,r),o.loaded=!0,o.exports}r.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return r.d(t,{a:t}),t},r.d=(e,t)=>{for(var n in t)r.o(t,n)&&!r.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]});},r.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),r.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),r.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0});},r.nmd=e=>(e.paths=[],e.children||(e.children=[]),e);var n=r(5590); - //window.gmodCRAM=n - return n; -}; - -const gmodCRAM = fn(); - -/* - * The MIT License (MIT) - * - * Copyright (c) 2018 The Regents of the University of California - * Author: Jim Robinson - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -const READ_STRAND_FLAG = 0x10; -const MATE_STRAND_FLAG = 0x20; - -const CRAM_MATE_STRAND_FLAG = 0x1; - -/** - * Class for reading a cram file. Wraps the gMOD Cram package. - * - * @param config - * @constructor - */ -class CramReader { - - constructor(config, genome, browser) { - - this.config = config; - this.browser = browser; - this.genome = genome; - - this.cramFile = new gmodCRAM.CramFile({ - filehandle: new FileHandler(config.url, config), - seqFetch: config.seqFetch || seqFetch.bind(this), - checkSequenceMD5: config.checkSequenceMD5 !== undefined ? config.checkSequenceMD5 : true - }); - - const indexFileHandle = new FileHandler(config.indexURL, config); - this.indexedCramFile = new gmodCRAM.IndexedCramFile({ - cram: this.cramFile, - index: new gmodCRAM.CraiIndex({ - filehandle: indexFileHandle - }), - fetchSizeLimit: 30000000 - }); - - BamUtils.setReaderDefaults(this, config); - - function seqFetch(seqID, start, end) { - - const sequence = this.genome.sequence; - const genome = this.genome; - - return this.getHeader() - .then(function (header) { - const chr = genome.getChromosomeName(header.chrNames[seqID]); - return sequence.getSequence(chr, start - 1, end) - }) - } - } - - - /** - * Parse the sequence dictionary from the SAM header and build chr name tables. This function - * is public so it can be unit tested. - * - * @returns {PromiseLike} - */ - - async getHeader() { - - if (!this.header) { - const genome = this.genome; - const samHeader = await this.cramFile.getSamHeader(); - const chrToIndex = {}; - const chrNames = []; - const chrAliasTable = {}; - const readGroups = []; - - for (let line of samHeader) { - if ('SQ' === line.tag) { - for (let d of line.data) { - if (d.tag === "SN") { - const seq = d.value; - chrToIndex[seq] = chrNames.length; - chrNames.push(seq); - if (genome) { - const alias = genome.getChromosomeName(seq); - chrAliasTable[alias] = seq; - } - break - } - } - } else if ('RG' === line.tag) { - readGroups.push(line.data); - } - } - - this.header = { - chrNames: chrNames, - chrToIndex: chrToIndex, - chrAliasTable: chrAliasTable, - readGroups: readGroups - }; - } - - return this.header - } - - async readAlignments(chr, bpStart, bpEnd) { - - this.browser; - const header = await this.getHeader(); - const queryChr = header.chrAliasTable.hasOwnProperty(chr) ? header.chrAliasTable[chr] : chr; - const chrIdx = header.chrToIndex[queryChr]; - const alignmentContainer = new AlignmentContainer(chr, bpStart, bpEnd, this.config); - - if (chrIdx === undefined) { - return alignmentContainer - - } else { - - try { - const records = await this.indexedCramFile.getRecordsForRange(chrIdx, bpStart, bpEnd); - - for (let record of records) { - - const refID = record.sequenceId; - const pos = record.alignmentStart; - const alignmentEnd = pos + record.lengthOnRef; - - if (refID < 0) { - continue // unmapped read - } else if (refID > chrIdx || pos > bpEnd) { - return // off right edge, we're done - } else if (refID < chrIdx) { - continue // Sequence to left of start, not sure this is possible - } - if (alignmentEnd < bpStart) { - continue - } // Record out-of-range "to the left", skip to next one - - const alignment = decodeCramRecord(record, header.chrNames); - - if (this.filter.pass(alignment)) { - alignmentContainer.push(alignment); - } - } - - alignmentContainer.finish(); - return alignmentContainer - } catch (error) { - let message = error.message; - if (message && message.indexOf("MD5") >= 0) { - message = "Sequence mismatch. Is this the correct genome for the loaded CRAM?"; - } - this.browser.alert.present(new Error(message)); - throw error - } - } - - function decodeCramRecord(record, chrNames) { - - const alignment = new BamAlignment(); - - alignment.chr = chrNames[record.sequenceId]; - alignment.start = record.alignmentStart - 1; - alignment.lengthOnRef = record.lengthOnRef; - alignment.flags = record.flags; - alignment.strand = !(record.flags & READ_STRAND_FLAG); - alignment.fragmentLength = record.templateLength || record.templateSize; - alignment.mq = record.mappingQuality; - alignment.end = record.alignmentStart + record.lengthOnRef; - alignment.readGroupId = record.readGroupId; - - if (record.mate && record.mate.sequenceId !== undefined) { - const strand = record.mate.flags !== undefined ? - !(record.mate.flags & CRAM_MATE_STRAND_FLAG) : - !(record.flags & MATE_STRAND_FLAG); - - alignment.mate = { - chr: chrNames[record.mate.sequenceId], - position: record.mate.alignmentStart, - strand: strand - }; - } - - alignment.seq = record.getReadBases(); - alignment.qual = record.qualityScores; - alignment.tagDict = record.tags; - alignment.readName = record.readName; - - // TODO -- cigar encoded in tag? - // BamUtils.bam_tag2cigar(ba, blockEnd, p, lseq, alignment, cigarArray); - - makeBlocks(record, alignment); - - if (alignment.mate && alignment.start > alignment.mate.position && alignment.fragmentLength > 0) { - alignment.fragmentLength = -alignment.fragmentLength; - } - - BamUtils.setPairOrientation(alignment); - - return alignment - - } - - function makeBlocks(cramRecord, alignment) { - - const blocks = []; - let insertions; - let gaps; - let basesUsed = 0; - let cigarString = ''; - - alignment.scStart = alignment.start; - alignment.scLengthOnRef = alignment.lengthOnRef; - - if (cramRecord.readFeatures) { - - for (let feature of cramRecord.readFeatures) { - - const code = feature.code; - const data = feature.data; - const readPos = feature.pos - 1; - const refPos = feature.refPos - 1; - - switch (code) { - case 'S' : - case 'I': - case 'i': - case 'N': - case 'D': - if (readPos > basesUsed) { - const len = readPos - basesUsed; - blocks.push(new AlignmentBlock({ - start: refPos - len, - seqOffset: basesUsed, - len: len, - type: 'M' - })); - basesUsed += len; - cigarString += len + 'M'; - } - - if ('S' === code) { - let scPos = refPos; - alignment.scLengthOnRef += data.length; - if (readPos === 0) { - alignment.scStart -= data.length; - scPos -= data.length; - } - const len = data.length; - blocks.push(new AlignmentBlock({ - start: scPos, - seqOffset: basesUsed, - len: len, - type: 'S' - })); - basesUsed += len; - cigarString += len + code; - } else if ('I' === code || 'i' === code) { - if (insertions === undefined) { - insertions = []; - } - const len = 'i' === code ? 1 : data.length; - insertions.push(new AlignmentBlock({ - start: refPos, - len: len, - seqOffset: basesUsed, - type: 'I' - })); - basesUsed += len; - cigarString += len + code; - } else if ('D' === code || 'N' === code) { - if (!gaps) { - gaps = []; - } - gaps.push({ - start: refPos, - len: data, - type: code - }); - cigarString += data + code; - } - break - - case 'H': - case 'P': - cigarString += data + code; - break - // Ignore - } - } - } - - // Last block - const len = cramRecord.readLength - basesUsed; - if (len > 0) { - blocks.push(new AlignmentBlock({ - start: cramRecord.alignmentStart + cramRecord.lengthOnRef - len - 1, - seqOffset: basesUsed, - len: len, - type: 'M' - })); - - cigarString += len + 'M'; - } - - alignment.blocks = blocks; - alignment.insertions = insertions; - alignment.gaps = gaps; - alignment.cigar = cigarString; - - } - - } -} - -class FileHandler { - - constructor(source, config) { - this.position = 0; - this.url = source; - this.config = config; - this.cache = new BufferCache({ - fetch: (start, length) => this._fetch(start, length), - }); - } - - async _fetch(position, length) { - - const loadRange = {start: position, size: length}; - this._stat = {size: undefined}; - const arrayBuffer = await igvxhr.loadArrayBuffer(this.url, buildOptions$1(this.config, {range: loadRange})); - return Buffer.from(arrayBuffer) - } - - async read(buffer, offset = 0, length = Infinity, position = 0) { - let readPosition = position; - if (readPosition === null) { - readPosition = this.position; - this.position += length; - } - return this.cache.get(buffer, offset, length, position) - } - - async readFile() { - const arrayBuffer = await igvxhr.loadArrayBuffer(this.url, buildOptions$1(this.config)); - return Buffer.from(arrayBuffer) - } - - async stat() { - if (!this._stat) { - const buf = Buffer.allocUnsafe(10); - await this.read(buf, 0, 10, 0); - if (!this._stat) - throw new Error(`unable to determine size of file at ${this.url}`) - } - return this._stat - } -} - -class BufferCache { - - constructor({fetch, size = 10000000, chunkSize = 32768}) { - - this.fetch = fetch; - this.chunkSize = chunkSize; - this.lruCache = new QuickLRU({maxSize: Math.floor(size / chunkSize)}); - } - - async get(outputBuffer, offset, length, position) { - if (outputBuffer.length < offset + length) - throw new Error('output buffer not big enough for request') - - // calculate the list of chunks involved in this fetch - const firstChunk = Math.floor(position / this.chunkSize); - const lastChunk = Math.floor((position + length) / this.chunkSize); - - // fetch them all as necessary - const fetches = new Array(lastChunk - firstChunk + 1); - for (let chunk = firstChunk; chunk <= lastChunk; chunk += 1) { - fetches[chunk - firstChunk] = this._getChunk(chunk).then(data => ({ - data, - chunkNumber: chunk, - })); - } - - // stitch together the response buffer using them - const chunks = await Promise.all(fetches); - const chunksOffset = position - chunks[0].chunkNumber * this.chunkSize; - chunks.forEach(({data, chunkNumber}) => { - const chunkPositionStart = chunkNumber * this.chunkSize; - let copyStart = 0; - let copyEnd = this.chunkSize; - let copyOffset = - offset + (chunkNumber - firstChunk) * this.chunkSize - chunksOffset; - - if (chunkNumber === firstChunk) { - copyOffset = offset; - copyStart = chunksOffset; - } - if (chunkNumber === lastChunk) { - copyEnd = position + length - chunkPositionStart; - } - - data.copy(outputBuffer, copyOffset, copyStart, copyEnd); - }); - } - - _getChunk(chunkNumber) { - const cachedPromise = this.lruCache.get(chunkNumber); - if (cachedPromise) return cachedPromise - - const freshPromise = this.fetch( - chunkNumber * this.chunkSize, - this.chunkSize, - ); - this.lruCache.set(chunkNumber, freshPromise); - return freshPromise - } -} - -class QuickLRU { - constructor(options = {}) { - if (!(options.maxSize && options.maxSize > 0)) { - throw new TypeError('`maxSize` must be a number greater than 0') - } - - this.maxSize = options.maxSize; - this.cache = new Map(); - this.oldCache = new Map(); - this._size = 0; - } - - _set(key, value) { - this.cache.set(key, value); - this._size++; - - if (this._size >= this.maxSize) { - this._size = 0; - this.oldCache = this.cache; - this.cache = new Map(); - } - } - - get(key) { - if (this.cache.has(key)) { - return this.cache.get(key) - } - - if (this.oldCache.has(key)) { - const value = this.oldCache.get(key); - this._set(key, value); - return value - } - } - - set(key, value) { - if (this.cache.has(key)) { - this.cache.set(key, value); - } else { - this._set(key, value); - } - - return this - } - - has(key) { - return this.cache.has(key) || this.oldCache.has(key) - } - - peek(key) { - if (this.cache.has(key)) { - return this.cache.get(key) - } - - if (this.oldCache.has(key)) { - return this.oldCache.get(key) - } - } - - delete(key) { - const deleted = this.cache.delete(key); - if (deleted) { - this._size--; - } - - return this.oldCache.delete(key) || deleted - } - - clear() { - this.cache.clear(); - this.oldCache.clear(); - this._size = 0; - } - - * keys() { - for (const [key] of this) { - yield key; - } - } - - * values() { - for (const [, value] of this) { - yield value; - } - } - - * [Symbol.iterator]() { - for (const item of this.cache) { - yield item; - } - - for (const item of this.oldCache) { - const [key] = item; - if (!this.cache.has(key)) { - yield item; - } - } - } - - get size() { - let oldCacheSize = 0; - for (const key of this.oldCache.keys()) { - if (!this.cache.has(key)) { - oldCacheSize++; - } - } - - return this._size + oldCacheSize - } -} - -/* - * The MIT License (MIT) - * - * Copyright (c) 2014 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -var CigarOperationTable = { - "ALIGNMENT_MATCH": "M", - "INSERT": "I", - "DELETE": "D", - "SKIP": "N", - "CLIP_SOFT": "S", - "CLIP_HARD": "H", - "PAD": "P", - "SEQUENCE_MATCH": "=", - "SEQUENCE_MISMATCH": "X" -}; - -const Ga4ghAlignmentReader = function (config, genome) { - - this.config = config; - this.genome = genome; - this.url = config.url; - this.filter = new BamFilter(config.filter); - this.readGroupSetIds = config.readGroupSetIds; - this.authKey = config.authKey; // Might be undefined or nill - - this.samplingWindowSize = config.samplingWindowSize === undefined ? 100 : config.samplingWindowSize; - this.samplingDepth = config.samplingDepth === undefined ? 1000 : config.samplingDepth; - if (config.viewAsPairs) { - this.pairsSupported = true; - } else { - this.pairsSupported = config.pairsSupported === undefined ? true : config.pairsSupported; - } -}; - - -Ga4ghAlignmentReader.prototype.readAlignments = function (chr, bpStart, bpEnd) { - - const genome = this.genome; - const self = this; - - return getChrAliasTable() - - .then(function (chrAliasTable) { - - var queryChr = chrAliasTable.hasOwnProperty(chr) ? chrAliasTable[chr] : chr, - readURL = self.url + "/reads/search"; - - return ga4ghSearch({ - url: readURL, - body: { - "readGroupSetIds": [self.readGroupSetIds], - "referenceName": queryChr, - "start": bpStart, - "end": bpEnd, - "pageSize": "10000" - }, - decode: decodeGa4ghReads, - results: new AlignmentContainer(chr, bpStart, bpEnd, self.config) - }) - }) - - - function getChrAliasTable() { - - if (self.chrAliasTable) { - - return Promise.resolve(self.chrAliasTable) - - } else { - - return self.readMetadata() - - .then(function (json) { - - self.chrAliasTable = {}; - - if (genome && json.readGroups && json.readGroups.length > 0) { - - var referenceSetId = json.readGroups[0].referenceSetId; - - if (referenceSetId) { - - // Query for reference names to build an alias table (map of genome ref names -> dataset ref names) - var readURL = self.url + "/references/search"; - - return ga4ghSearch({ - url: readURL, - body: { - "referenceSetId": referenceSetId - }, - decode: function (j) { - return j.references - } - }) - .then(function (references) { - - - references.forEach(function (ref) { - var refName = ref.name, - alias = genome.getChromosomeName(refName); - self.chrAliasTable[alias] = refName; - }); - - - return self.chrAliasTable - - }) - } else { - - // Try hardcoded constants -- workaround for non-compliant data at Google - populateChrAliasTable(self.chrAliasTable, self.config.datasetId); - - return self.chrAliasTable - } - } else { - // No browser object, can't build map. This can occur when run from unit tests - return self.chrAliasTable - } - }) - } - } - - /** - * Decode an array of ga4gh read records - * - - */ - function decodeGa4ghReads(j) { - - var i, - jsonRecords = j.alignments, - len = jsonRecords.length, - alignment, - jsonAlignment, - cigarDecoded, - alignments = [], - mate, - blocks; - - for (i = 0; i < len; i++) { - - let record = jsonRecords[i]; - - alignment = new BamAlignment(); - - alignment.readName = record.fragmentName; - alignment.properPlacement = record.properPlacement; - alignment.duplicateFragment = record.duplicateFragment; - alignment.numberReads = record.numberReads; - alignment.fragmentLength = record.fragmentLength; - alignment.readNumber = record.readNumber; - alignment.failedVendorQualityChecks = record.failedVendorQualityChecks; - alignment.secondaryAlignment = record.secondaryAlignment; - alignment.supplementaryAlignment = record.supplementaryAlignment; - alignment.seq = record.alignedSequence; - alignment.qual = record.alignedQuality; - alignment.matePos = record.nextMatePosition; - alignment.tagDict = record.info; - alignment.flags = encodeFlags(); - - - jsonAlignment = record.alignment; - if (jsonAlignment) { - alignment.mapped = true; - - alignment.chr = record.alignment.position.referenceName; - if (genome) alignment.chr = genome.getChromosomeName(alignment.chr); - - alignment.start = parseInt(record.alignment.position.position); - alignment.strand = !(record.alignment.position.reverseStrand); - alignment.mq = record.alignment.mappingQuality; - alignment.cigar = encodeCigar(record.alignment.cigar); - cigarDecoded = translateCigar(record.alignment.cigar); - - alignment.lengthOnRef = cigarDecoded.lengthOnRef; - - blocks = makeBlocks(alignment, cigarDecoded.array); - alignment.blocks = blocks.blocks; - alignment.insertions = blocks.insertions; - - } else { - alignment.mapped = false; - } - - mate = record.nextMatePosition; - if (mate) { - alignment.mate = { - chr: mate.referenceFrame, - position: parseInt(mate.position), - strand: !mate.reverseStrand - }; - } - - if (self.filter.pass(alignment)) { - alignments.push(alignment); - } - - - } - - return alignments - - - // Encode a cigar string -- used for popup text - function encodeCigar(cigarArray) { - - var cigarString = ""; - cigarArray.forEach(function (cigarUnit) { - var op = CigarOperationTable[cigarUnit.operation], - len = cigarUnit.operationLength; - cigarString = cigarString + (len + op); - }); - - return cigarString - } - - // TODO -- implement me - function encodeFlags(json) { - return 0 - } - - function translateCigar(cigar) { - - var cigarUnit, opLen, opLtr, - lengthOnRef = 0, - cigarArray = [], - i; - - for (i = 0; i < cigar.length; i++) { - - cigarUnit = cigar[i]; - - opLtr = CigarOperationTable[cigarUnit.operation]; - opLen = parseInt(cigarUnit.operationLength); // Google represents long as a String - - if (opLtr === 'M' || opLtr === 'EQ' || opLtr === 'X' || opLtr === 'D' || opLtr === 'N' || opLtr === '=') - lengthOnRef += opLen; - - cigarArray.push({len: opLen, ltr: opLtr}); - - } - - return {lengthOnRef: lengthOnRef, array: cigarArray} - } - - - /** - * Split the alignment record into blocks as specified in the cigarArray. Each aligned block contains - * its portion of the read sequence and base quality strings. A read sequence or base quality string - * of "*" indicates the value is not recorded. In all other cases the length of the block sequence (block.seq) - * and quality string (block.qual) must == the block length. - * - * NOTE: Insertions are not yet treated // TODO - * - * @param record - * @param cigarArray - * @returns array of blocks - */ - function makeBlocks(record, cigarArray) { - - - var blocks = [], - gaps, - insertions, - seqOffset = 0, - pos = record.start, - len = cigarArray.length, - gapType; - - for (var i = 0; i < len; i++) { - - var c = cigarArray[i]; - - switch (c.ltr) { - case 'H' : - break // ignore hard clips - case 'P' : - break // ignore pads - case 'S' : - seqOffset += c.len; - gapType = 'S'; - break // soft clip read bases - case 'N' : - case 'D' : - if (gaps === undefined) { - gaps = []; - } - gaps.push({ - start: pos, - len: c.len, - type: c.ltr - }); - pos += c.len; - break - case 'I' : - if (insertions === undefined) insertions = []; - insertions.push(new AlignmentBlock({ - start: pos, - len: c.len, - seqOffset: seqOffset - })); - seqOffset += c.len; - break - case 'M' : - case 'EQ' : - case '=' : - case 'X' : - blocks.push( - new AlignmentBlock({ - start: pos, - len: c.len, - seqOffset: seqOffset, - gapType: gapType - })); - seqOffset += c.len; - pos += c.len; - - break - - default : - console.log("Error processing cigar element: " + c.len + c.ltr); - } - } - - return {blocks: blocks, insertions: insertions, gaps: gaps} - } - } -}; - - -Ga4ghAlignmentReader.prototype.readMetadata = function () { - - return ga4ghGet({ - url: this.url, - entity: "readgroupsets", - entityId: this.readGroupSetIds - }) -}; - -/** - * Hardcoded hack to work around some non-compliant google datasets - * - * @param chrAliasTable - * @param datasetId - */ -function populateChrAliasTable(chrAliasTable, datasetId) { - var i; - if ("461916304629" === datasetId || "337315832689" === datasetId) { - for (i = 1; i < 23; i++) { - chrAliasTable["chr" + i] = i; - } - chrAliasTable["chrX"] = "X"; - chrAliasTable["chrY"] = "Y"; - chrAliasTable["chrM"] = "MT"; - } -} - -/* - * The MIT License (MIT) - * - * Copyright (c) 2014 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -class BamSource { - - constructor(config, browser) { - - const genome = browser.genome; - - this.config = config; - this.genome = genome; - - if (isDataURL(config.url)) { - this.config.indexed = false; - } - - if ("ga4gh" === config.sourceType) { - this.bamReader = new Ga4ghAlignmentReader(config, genome); - } else if ("pysam" === config.sourceType) { - this.bamReader = new BamWebserviceReader(config, genome); - } else if ("htsget" === config.sourceType) { - this.bamReader = new HtsgetBamReader(config, genome); - } else if ("shardedBam" === config.sourceType) { - this.bamReader = new ShardedBamReader(config, genome); - } else if ("cram" === config.format) { - this.bamReader = new CramReader(config, genome, browser); - } else { - if (!this.config.indexURL && config.indexed !== false) { - if (isString$2(this.config.url)) { - const inferIndexPath$1 = inferIndexPath(this.config.url, "bai"); - if (inferIndexPath$1) { - console.error(`Warning: no indexURL specified for ${this.config.url}. Guessing ${this.baiPath}`); - this.config.indexURL = inferIndexPath$1; - } else { - console.error(`Warning: no indexURL specified for ${this.config.url}.`); - this.config.indexed = false; - } - } else { - console.error(`Warning: no indexURL specified for ${this.config.name}.`); - this.config.indexed = false; - } - } - - if (this.config.indexed !== false) { // && this.config.indexURL) { - this.bamReader = new BamReader(config, genome); - } else { - this.bamReader = new BamReaderNonIndexed(config, genome); - } - } - - this.viewAsPairs = config.viewAsPairs; - this.showSoftClips = config.showSoftClips; - } - - setViewAsPairs(bool) { - this.viewAsPairs = bool; - } - - setShowSoftClips(bool) { - this.showSoftClips = bool; - } - - async getAlignments(chr, bpStart, bpEnd) { - - const genome = this.genome; - const showSoftClips = this.showSoftClips; - - const alignmentContainer = await this.bamReader.readAlignments(chr, bpStart, bpEnd); - let alignments = alignmentContainer.alignments; - if (!this.viewAsPairs) { - alignments = unpairAlignments([{alignments: alignments}]); - } - const hasAlignments = alignments.length > 0; - alignmentContainer.packedAlignmentRows = packAlignmentRows(alignments, alignmentContainer.start, alignmentContainer.end, showSoftClips); - - this.alignmentContainer = alignmentContainer; - - if (hasAlignments) { - const sequence = await genome.sequence.getSequence(chr, alignmentContainer.start, alignmentContainer.end); - if (sequence) { - alignmentContainer.coverageMap.refSeq = sequence; // TODO -- fix this - alignmentContainer.sequence = sequence; // TODO -- fix this - return alignmentContainer - } else { - console.error("No sequence for: " + chr + ":" + alignmentContainer.start + "-" + alignmentContainer.end); - } - } - return alignmentContainer - - } -} - -function paintAxis(ctx, pixelWidth, pixelHeight) { - - var x1, - x2, - y1, - y2, - a, - b, - reference, - shim, - font = { - 'font': 'normal 10px Arial', - 'textAlign': 'right', - 'strokeStyle': "black" - }; - - if (undefined === this.dataRange || undefined === this.dataRange.max || undefined === this.dataRange.min) { - return - } - - let flipAxis = (undefined === this.flipAxis) ? false : this.flipAxis; - - IGVGraphics.fillRect(ctx, 0, 0, pixelWidth, pixelHeight, {'fillStyle': "rgb(255, 255, 255)"}); - - reference = 0.95 * pixelWidth; - x1 = reference - 8; - x2 = reference; - - //shim = 0.5 * 0.125; - shim = .01; - y1 = y2 = shim * pixelHeight; - - a = {x: x2, y: y1}; - - // tick - IGVGraphics.strokeLine(ctx, x1, y1, x2, y2, font); - IGVGraphics.fillText(ctx, prettyPrint(flipAxis ? this.dataRange.min : this.dataRange.max), x1 + 4, y1 + 12, font); - - //shim = 0.25 * 0.125; - y1 = y2 = (1.0 - shim) * pixelHeight; - - b = {x: x2, y: y1}; - - // tick - IGVGraphics.strokeLine(ctx, x1, y1, x2, y2, font); - IGVGraphics.fillText(ctx, prettyPrint(flipAxis ? this.dataRange.max : this.dataRange.min), x1 + 4, y1 - 4, font); - - IGVGraphics.strokeLine(ctx, a.x, a.y, b.x, b.y, font); - - function prettyPrint(number) { - // if number >= 100, show whole number - // if >= 1 show 1 significant digits - // if < 1 show 2 significant digits - - if (number === 0) { - return "0" - } else if (Math.abs(number) >= 10) { - return number.toFixed() - } else if (Math.abs(number) >= 1) { - return number.toFixed(1) - } else { - return number.toFixed(2) - } - } -} - -class Locus { - - constructor({chr, start, end}) { - this.chr = chr; - this.start = start; - this.end = end; - } - - - contains(locus) { - return locus.chr === this.chr && locus.start >= this.start && locus.end <= this.end - } - - overlaps(locus) { - return locus.chr === this.chr && !(locus.end < this.start || locus.start > this.end) - } - - extend(l) { - if (l.chr !== this.chr) return - this.start = Math.min(l.start, this.start); - this.end = Math.max(l.end, this.end); - } - - getLocusString() { - if ('all' === this.chr) { - return 'all' - } else { - const ss = numberFormatter$1(Math.floor(this.start) + 1); - const ee = numberFormatter$1(Math.round(this.end)); - return `${this.chr}:${ss}-${ee}` - } - } - - static fromLocusString(str) { - if ('all' === str) { - return new Locus({chr: 'all'}) - } - const parts = str.split(':'); - const chr = parts[0]; - const se = parts[1].split("-"); - const start = Number.parseInt(se[0].replace(/,/g, "")) - 1; - const end = Number.parseInt(se[1].replace(/,/g, "")); - return new Locus({chr, start, end}) - } -} - -/*! - * vanilla-picker v2.12.1 - * https://vanilla-picker.js.org - * - * Copyright 2017-2021 Andreas Borgen (https://github.com/Sphinxxxx), Adam Brooks (https://github.com/dissimulate) - * Released under the ISC license. - */ -var classCallCheck = function (instance, Constructor) { - if (!(instance instanceof Constructor)) { - throw new TypeError("Cannot call a class as a function"); - } -}; - -var createClass = function () { - function defineProperties(target, props) { - for (var i = 0; i < props.length; i++) { - var descriptor = props[i]; - descriptor.enumerable = descriptor.enumerable || false; - descriptor.configurable = true; - if ("value" in descriptor) descriptor.writable = true; - Object.defineProperty(target, descriptor.key, descriptor); - } - } - - return function (Constructor, protoProps, staticProps) { - if (protoProps) defineProperties(Constructor.prototype, protoProps); - if (staticProps) defineProperties(Constructor, staticProps); - return Constructor; - }; -}(); - -var slicedToArray = function () { - function sliceIterator(arr, i) { - var _arr = []; - var _n = true; - var _d = false; - var _e = undefined; - - try { - for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { - _arr.push(_s.value); - - if (i && _arr.length === i) break; - } - } catch (err) { - _d = true; - _e = err; - } finally { - try { - if (!_n && _i["return"]) _i["return"](); - } finally { - if (_d) throw _e; - } - } - - return _arr; - } - - return function (arr, i) { - if (Array.isArray(arr)) { - return arr; - } else if (Symbol.iterator in Object(arr)) { - return sliceIterator(arr, i); - } else { - throw new TypeError("Invalid attempt to destructure non-iterable instance"); - } - }; -}(); - -String.prototype.startsWith = String.prototype.startsWith || function (needle) { - return this.indexOf(needle) === 0; -}; -String.prototype.padStart = String.prototype.padStart || function (len, pad) { - var str = this;while (str.length < len) { - str = pad + str; - }return str; -}; - -var colorNames = { cb: '0f8ff', tqw: 'aebd7', q: '-ffff', qmrn: '7fffd4', zr: '0ffff', bg: '5f5dc', bsq: 'e4c4', bck: '---', nch: 'ebcd', b: '--ff', bvt: '8a2be2', brwn: 'a52a2a', brw: 'deb887', ctb: '5f9ea0', hrt: '7fff-', chcT: 'd2691e', cr: '7f50', rnw: '6495ed', crns: '8dc', crms: 'dc143c', cn: '-ffff', Db: '--8b', Dcn: '-8b8b', Dgnr: 'b8860b', Dgr: 'a9a9a9', Dgrn: '-64-', Dkhk: 'bdb76b', Dmgn: '8b-8b', Dvgr: '556b2f', Drng: '8c-', Drch: '9932cc', Dr: '8b--', Dsmn: 'e9967a', Dsgr: '8fbc8f', DsTb: '483d8b', DsTg: '2f4f4f', Dtrq: '-ced1', Dvt: '94-d3', ppnk: '1493', pskb: '-bfff', mgr: '696969', grb: '1e90ff', rbrc: 'b22222', rwht: 'af0', stg: '228b22', chs: '-ff', gnsb: 'dcdcdc', st: '8f8ff', g: 'd7-', gnr: 'daa520', gr: '808080', grn: '-8-0', grnw: 'adff2f', hnw: '0fff0', htpn: '69b4', nnr: 'cd5c5c', ng: '4b-82', vr: '0', khk: '0e68c', vnr: 'e6e6fa', nrb: '0f5', wngr: '7cfc-', mnch: 'acd', Lb: 'add8e6', Lcr: '08080', Lcn: 'e0ffff', Lgnr: 'afad2', Lgr: 'd3d3d3', Lgrn: '90ee90', Lpnk: 'b6c1', Lsmn: 'a07a', Lsgr: '20b2aa', Lskb: '87cefa', LsTg: '778899', Lstb: 'b0c4de', Lw: 'e0', m: '-ff-', mgrn: '32cd32', nn: 'af0e6', mgnt: '-ff', mrn: '8--0', mqm: '66cdaa', mmb: '--cd', mmrc: 'ba55d3', mmpr: '9370db', msg: '3cb371', mmsT: '7b68ee', '': '-fa9a', mtr: '48d1cc', mmvt: 'c71585', mnLb: '191970', ntc: '5fffa', mstr: 'e4e1', mccs: 'e4b5', vjw: 'dead', nv: '--80', c: 'df5e6', v: '808-0', vrb: '6b8e23', rng: 'a5-', rngr: '45-', rch: 'da70d6', pgnr: 'eee8aa', pgrn: '98fb98', ptrq: 'afeeee', pvtr: 'db7093', ppwh: 'efd5', pchp: 'dab9', pr: 'cd853f', pnk: 'c0cb', pm: 'dda0dd', pwrb: 'b0e0e6', prp: '8-080', cc: '663399', r: '--', sbr: 'bc8f8f', rb: '4169e1', sbrw: '8b4513', smn: 'a8072', nbr: '4a460', sgrn: '2e8b57', ssh: '5ee', snn: 'a0522d', svr: 'c0c0c0', skb: '87ceeb', sTb: '6a5acd', sTgr: '708090', snw: 'afa', n: '-ff7f', stb: '4682b4', tn: 'd2b48c', t: '-8080', thst: 'd8bfd8', tmT: '6347', trqs: '40e0d0', vt: 'ee82ee', whT: '5deb3', wht: '', hts: '5f5f5', w: '-', wgrn: '9acd32' }; - -function printNum(num) { - var decs = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1; - - var str = decs > 0 ? num.toFixed(decs).replace(/0+$/, '').replace(/\.$/, '') : num.toString(); - return str || '0'; -} - -var Color = function () { - function Color(r, g, b, a) { - classCallCheck(this, Color); - - - var that = this; - function parseString(input) { - - if (input.startsWith('hsl')) { - var _input$match$map = input.match(/([\-\d\.e]+)/g).map(Number), - _input$match$map2 = slicedToArray(_input$match$map, 4), - h = _input$match$map2[0], - s = _input$match$map2[1], - l = _input$match$map2[2], - _a = _input$match$map2[3]; - - if (_a === undefined) { - _a = 1; - } - - h /= 360; - s /= 100; - l /= 100; - that.hsla = [h, s, l, _a]; - } else if (input.startsWith('rgb')) { - var _input$match$map3 = input.match(/([\-\d\.e]+)/g).map(Number), - _input$match$map4 = slicedToArray(_input$match$map3, 4), - _r = _input$match$map4[0], - _g = _input$match$map4[1], - _b = _input$match$map4[2], - _a2 = _input$match$map4[3]; - - if (_a2 === undefined) { - _a2 = 1; - } - - that.rgba = [_r, _g, _b, _a2]; - } else { - if (input.startsWith('#')) { - that.rgba = Color.hexToRgb(input); - } else { - that.rgba = Color.nameToRgb(input) || Color.hexToRgb(input); - } - } - } - - if (r === undefined) ; else if (Array.isArray(r)) { - this.rgba = r; - } else if (b === undefined) { - var color = r && '' + r; - if (color) { - parseString(color.toLowerCase()); - } - } else { - this.rgba = [r, g, b, a === undefined ? 1 : a]; - } - } - - createClass(Color, [{ - key: 'printRGB', - value: function printRGB(alpha) { - var rgb = alpha ? this.rgba : this.rgba.slice(0, 3), - vals = rgb.map(function (x, i) { - return printNum(x, i === 3 ? 3 : 0); - }); - - return alpha ? 'rgba(' + vals + ')' : 'rgb(' + vals + ')'; - } - }, { - key: 'printHSL', - value: function printHSL(alpha) { - var mults = [360, 100, 100, 1], - suff = ['', '%', '%', '']; - - var hsl = alpha ? this.hsla : this.hsla.slice(0, 3), - vals = hsl.map(function (x, i) { - return printNum(x * mults[i], i === 3 ? 3 : 1) + suff[i]; - }); - - return alpha ? 'hsla(' + vals + ')' : 'hsl(' + vals + ')'; - } - }, { - key: 'printHex', - value: function printHex(alpha) { - var hex = this.hex; - return alpha ? hex : hex.substring(0, 7); - } - }, { - key: 'rgba', - get: function get() { - if (this._rgba) { - return this._rgba; - } - if (!this._hsla) { - throw new Error('No color is set'); - } - - return this._rgba = Color.hslToRgb(this._hsla); - }, - set: function set(rgb) { - if (rgb.length === 3) { - rgb[3] = 1; - } - - this._rgba = rgb; - this._hsla = null; - } - }, { - key: 'rgbString', - get: function get() { - return this.printRGB(); - } - }, { - key: 'rgbaString', - get: function get() { - return this.printRGB(true); - } - }, { - key: 'hsla', - get: function get() { - if (this._hsla) { - return this._hsla; - } - if (!this._rgba) { - throw new Error('No color is set'); - } - - return this._hsla = Color.rgbToHsl(this._rgba); - }, - set: function set(hsl) { - if (hsl.length === 3) { - hsl[3] = 1; - } - - this._hsla = hsl; - this._rgba = null; - } - }, { - key: 'hslString', - get: function get() { - return this.printHSL(); - } - }, { - key: 'hslaString', - get: function get() { - return this.printHSL(true); - } - }, { - key: 'hex', - get: function get() { - var rgb = this.rgba, - hex = rgb.map(function (x, i) { - return i < 3 ? x.toString(16) : Math.round(x * 255).toString(16); - }); - - return '#' + hex.map(function (x) { - return x.padStart(2, '0'); - }).join(''); - }, - set: function set(hex) { - this.rgba = Color.hexToRgb(hex); - } - }], [{ - key: 'hexToRgb', - value: function hexToRgb(input) { - - var hex = (input.startsWith('#') ? input.slice(1) : input).replace(/^(\w{3})$/, '$1F').replace(/^(\w)(\w)(\w)(\w)$/, '$1$1$2$2$3$3$4$4').replace(/^(\w{6})$/, '$1FF'); - - if (!hex.match(/^([0-9a-fA-F]{8})$/)) { - throw new Error('Unknown hex color; ' + input); - } - - var rgba = hex.match(/^(\w\w)(\w\w)(\w\w)(\w\w)$/).slice(1).map(function (x) { - return parseInt(x, 16); - }); - - rgba[3] = rgba[3] / 255; - return rgba; - } - }, { - key: 'nameToRgb', - value: function nameToRgb(input) { - - var hash = input.toLowerCase().replace('at', 'T').replace(/[aeiouyldf]/g, '').replace('ght', 'L').replace('rk', 'D').slice(-5, 4), - hex = colorNames[hash]; - return hex === undefined ? hex : Color.hexToRgb(hex.replace(/\-/g, '00').padStart(6, 'f')); - } - }, { - key: 'rgbToHsl', - value: function rgbToHsl(_ref) { - var _ref2 = slicedToArray(_ref, 4), - r = _ref2[0], - g = _ref2[1], - b = _ref2[2], - a = _ref2[3]; - - r /= 255; - g /= 255; - b /= 255; - - var max = Math.max(r, g, b), - min = Math.min(r, g, b); - var h = void 0, - s = void 0, - l = (max + min) / 2; - - if (max === min) { - h = s = 0; - } else { - var d = max - min; - s = l > 0.5 ? d / (2 - max - min) : d / (max + min); - switch (max) { - case r: - h = (g - b) / d + (g < b ? 6 : 0);break; - case g: - h = (b - r) / d + 2;break; - case b: - h = (r - g) / d + 4;break; - } - - h /= 6; - } - - return [h, s, l, a]; - } - }, { - key: 'hslToRgb', - value: function hslToRgb(_ref3) { - var _ref4 = slicedToArray(_ref3, 4), - h = _ref4[0], - s = _ref4[1], - l = _ref4[2], - a = _ref4[3]; - - var r = void 0, - g = void 0, - b = void 0; - - if (s === 0) { - r = g = b = l; - } else { - var hue2rgb = function hue2rgb(p, q, t) { - if (t < 0) t += 1; - if (t > 1) t -= 1; - if (t < 1 / 6) return p + (q - p) * 6 * t; - if (t < 1 / 2) return q; - if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6; - return p; - }; - - var q = l < 0.5 ? l * (1 + s) : l + s - l * s, - p = 2 * l - q; - - r = hue2rgb(p, q, h + 1 / 3); - g = hue2rgb(p, q, h); - b = hue2rgb(p, q, h - 1 / 3); - } - - var rgba = [r * 255, g * 255, b * 255].map(Math.round); - rgba[3] = a; - - return rgba; - } - }]); - return Color; -}(); - -var EventBucket = function () { - function EventBucket() { - classCallCheck(this, EventBucket); - - this._events = []; - } - - createClass(EventBucket, [{ - key: 'add', - value: function add(target, type, handler) { - target.addEventListener(type, handler, false); - this._events.push({ - target: target, - type: type, - handler: handler - }); - } - }, { - key: 'remove', - value: function remove(target, type, handler) { - this._events = this._events.filter(function (e) { - var isMatch = true; - if (target && target !== e.target) { - isMatch = false; - } - if (type && type !== e.type) { - isMatch = false; - } - if (handler && handler !== e.handler) { - isMatch = false; - } - - if (isMatch) { - EventBucket._doRemove(e.target, e.type, e.handler); - } - return !isMatch; - }); - } - }, { - key: 'destroy', - value: function destroy() { - this._events.forEach(function (e) { - return EventBucket._doRemove(e.target, e.type, e.handler); - }); - this._events = []; - } - }], [{ - key: '_doRemove', - value: function _doRemove(target, type, handler) { - target.removeEventListener(type, handler, false); - } - }]); - return EventBucket; -}(); - -function parseHTML(htmlString) { - - var div = document.createElement('div'); - div.innerHTML = htmlString; - return div.firstElementChild; -} - -function dragTrack(eventBucket, area, callback) { - var dragging = false; - - function clamp(val, min, max) { - return Math.max(min, Math.min(val, max)); - } - - function onMove(e, info, starting) { - if (starting) { - dragging = true; - } - if (!dragging) { - return; - } - - e.preventDefault(); - - var bounds = area.getBoundingClientRect(), - w = bounds.width, - h = bounds.height, - x = info.clientX, - y = info.clientY; - - var relX = clamp(x - bounds.left, 0, w), - relY = clamp(y - bounds.top, 0, h); - - callback(relX / w, relY / h); - } - - function onMouse(e, starting) { - var button = e.buttons === undefined ? e.which : e.buttons; - if (button === 1) { - onMove(e, e, starting); - } else { - dragging = false; - } - } - - function onTouch(e, starting) { - if (e.touches.length === 1) { - onMove(e, e.touches[0], starting); - } else { - dragging = false; - } - } - - eventBucket.add(area, 'mousedown', function (e) { - onMouse(e, true); - }); - eventBucket.add(area, 'touchstart', function (e) { - onTouch(e, true); - }); - eventBucket.add(window, 'mousemove', onMouse); - eventBucket.add(area, 'touchmove', onTouch); - eventBucket.add(window, 'mouseup', function (e) { - dragging = false; - }); - eventBucket.add(area, 'touchend', function (e) { - dragging = false; - }); - eventBucket.add(area, 'touchcancel', function (e) { - dragging = false; - }); -} - -var BG_TRANSP = 'linear-gradient(45deg, lightgrey 25%, transparent 25%, transparent 75%, lightgrey 75%) 0 0 / 2em 2em,\n linear-gradient(45deg, lightgrey 25%, white 25%, white 75%, lightgrey 75%) 1em 1em / 2em 2em'; -var HUES = 360; - -var EVENT_KEY = 'keydown', - EVENT_CLICK_OUTSIDE = 'mousedown', - EVENT_TAB_MOVE = 'focusin'; - -function $(selector, context) { - return (context || document).querySelector(selector); -} - -function stopEvent(e) { - - e.preventDefault(); - e.stopPropagation(); -} -function onKey(bucket, target, keys, handler, stop) { - bucket.add(target, EVENT_KEY, function (e) { - if (keys.indexOf(e.key) >= 0) { - if (stop) { - stopEvent(e); - } - handler(e); - } - }); -} - -var Picker = function () { - function Picker(options) { - classCallCheck(this, Picker); - - - this.settings = { - - popup: 'right', - layout: 'default', - alpha: true, - editor: true, - editorFormat: 'hex', - cancelButton: false, - defaultColor: '#0cf' - }; - - this._events = new EventBucket(); - - this.onChange = null; - - this.onDone = null; - - this.onOpen = null; - - this.onClose = null; - - this.setOptions(options); - } - - createClass(Picker, [{ - key: 'setOptions', - value: function setOptions(options) { - var _this = this; - - if (!options) { - return; - } - var settings = this.settings; - - function transfer(source, target, skipKeys) { - for (var key in source) { - if (skipKeys && skipKeys.indexOf(key) >= 0) { - continue; - } - - target[key] = source[key]; - } - } - - if (options instanceof HTMLElement) { - settings.parent = options; - } else { - - if (settings.parent && options.parent && settings.parent !== options.parent) { - this._events.remove(settings.parent); - this._popupInited = false; - } - - transfer(options, settings); - - if (options.onChange) { - this.onChange = options.onChange; - } - if (options.onDone) { - this.onDone = options.onDone; - } - if (options.onOpen) { - this.onOpen = options.onOpen; - } - if (options.onClose) { - this.onClose = options.onClose; - } - - var col = options.color || options.colour; - if (col) { - this._setColor(col); - } - } - - var parent = settings.parent; - if (parent && settings.popup && !this._popupInited) { - - var openProxy = function openProxy(e) { - return _this.openHandler(e); - }; - - this._events.add(parent, 'click', openProxy); - - onKey(this._events, parent, [' ', 'Spacebar', 'Enter'], openProxy); - - this._popupInited = true; - } else if (options.parent && !settings.popup) { - this.show(); - } - } - }, { - key: 'openHandler', - value: function openHandler(e) { - if (this.show()) { - - e && e.preventDefault(); - - this.settings.parent.style.pointerEvents = 'none'; - - var toFocus = e && e.type === EVENT_KEY ? this._domEdit : this.domElement; - setTimeout(function () { - return toFocus.focus(); - }, 100); - - if (this.onOpen) { - this.onOpen(this.colour); - } - } - } - }, { - key: 'closeHandler', - value: function closeHandler(e) { - var event = e && e.type; - var doHide = false; - - if (!e) { - doHide = true; - } else if (event === EVENT_CLICK_OUTSIDE || event === EVENT_TAB_MOVE) { - - var knownTime = (this.__containedEvent || 0) + 100; - if (e.timeStamp > knownTime) { - doHide = true; - } - } else { - - stopEvent(e); - - doHide = true; - } - - if (doHide && this.hide()) { - this.settings.parent.style.pointerEvents = ''; - - if (event !== EVENT_CLICK_OUTSIDE) { - this.settings.parent.focus(); - } - - if (this.onClose) { - this.onClose(this.colour); - } - } - } - }, { - key: 'movePopup', - value: function movePopup(options, open) { - - this.closeHandler(); - - this.setOptions(options); - if (open) { - this.openHandler(); - } - } - }, { - key: 'setColor', - value: function setColor(color, silent) { - this._setColor(color, { silent: silent }); - } - }, { - key: '_setColor', - value: function _setColor(color, flags) { - if (typeof color === 'string') { - color = color.trim(); - } - if (!color) { - return; - } - - flags = flags || {}; - var c = void 0; - try { - - c = new Color(color); - } catch (ex) { - if (flags.failSilently) { - return; - } - throw ex; - } - - if (!this.settings.alpha) { - var hsla = c.hsla; - hsla[3] = 1; - c.hsla = hsla; - } - this.colour = this.color = c; - this._setHSLA(null, null, null, null, flags); - } - }, { - key: 'setColour', - value: function setColour(colour, silent) { - this.setColor(colour, silent); - } - }, { - key: 'show', - value: function show() { - var parent = this.settings.parent; - if (!parent) { - return false; - } - - if (this.domElement) { - var toggled = this._toggleDOM(true); - - this._setPosition(); - - return toggled; - } - - var html = this.settings.template || '
'; - var wrapper = parseHTML(html); - - this.domElement = wrapper; - this._domH = $('.picker_hue', wrapper); - this._domSL = $('.picker_sl', wrapper); - this._domA = $('.picker_alpha', wrapper); - this._domEdit = $('.picker_editor input', wrapper); - this._domSample = $('.picker_sample', wrapper); - this._domOkay = $('.picker_done button', wrapper); - this._domCancel = $('.picker_cancel button', wrapper); - - wrapper.classList.add('layout_' + this.settings.layout); - if (!this.settings.alpha) { - wrapper.classList.add('no_alpha'); - } - if (!this.settings.editor) { - wrapper.classList.add('no_editor'); - } - if (!this.settings.cancelButton) { - wrapper.classList.add('no_cancel'); - } - this._ifPopup(function () { - return wrapper.classList.add('popup'); - }); - - this._setPosition(); - - if (this.colour) { - this._updateUI(); - } else { - this._setColor(this.settings.defaultColor); - } - this._bindEvents(); - - return true; - } - }, { - key: 'hide', - value: function hide() { - return this._toggleDOM(false); - } - }, { - key: 'destroy', - value: function destroy() { - this._events.destroy(); - if (this.domElement) { - this.settings.parent.removeChild(this.domElement); - } - } - }, { - key: '_bindEvents', - value: function _bindEvents() { - var _this2 = this; - - var that = this, - dom = this.domElement, - events = this._events; - - function addEvent(target, type, handler) { - events.add(target, type, handler); - } - - addEvent(dom, 'click', function (e) { - return e.preventDefault(); - }); - - dragTrack(events, this._domH, function (x, y) { - return that._setHSLA(x); - }); - - dragTrack(events, this._domSL, function (x, y) { - return that._setHSLA(null, x, 1 - y); - }); - - if (this.settings.alpha) { - dragTrack(events, this._domA, function (x, y) { - return that._setHSLA(null, null, null, 1 - y); - }); - } - - var editInput = this._domEdit; - { - addEvent(editInput, 'input', function (e) { - that._setColor(this.value, { fromEditor: true, failSilently: true }); - }); - - addEvent(editInput, 'focus', function (e) { - var input = this; - - if (input.selectionStart === input.selectionEnd) { - input.select(); - } - }); - } - - this._ifPopup(function () { - - var popupCloseProxy = function popupCloseProxy(e) { - return _this2.closeHandler(e); - }; - - addEvent(window, EVENT_CLICK_OUTSIDE, popupCloseProxy); - addEvent(window, EVENT_TAB_MOVE, popupCloseProxy); - onKey(events, dom, ['Esc', 'Escape'], popupCloseProxy); - - var timeKeeper = function timeKeeper(e) { - _this2.__containedEvent = e.timeStamp; - }; - addEvent(dom, EVENT_CLICK_OUTSIDE, timeKeeper); - - addEvent(dom, EVENT_TAB_MOVE, timeKeeper); - - addEvent(_this2._domCancel, 'click', popupCloseProxy); - }); - - var onDoneProxy = function onDoneProxy(e) { - _this2._ifPopup(function () { - return _this2.closeHandler(e); - }); - if (_this2.onDone) { - _this2.onDone(_this2.colour); - } - }; - addEvent(this._domOkay, 'click', onDoneProxy); - onKey(events, dom, ['Enter'], onDoneProxy); - } - }, { - key: '_setPosition', - value: function _setPosition() { - var parent = this.settings.parent, - elm = this.domElement; - - if (parent !== elm.parentNode) { - parent.appendChild(elm); - } - - this._ifPopup(function (popup) { - - if (getComputedStyle(parent).position === 'static') { - parent.style.position = 'relative'; - } - - var cssClass = popup === true ? 'popup_right' : 'popup_' + popup; - - ['popup_top', 'popup_bottom', 'popup_left', 'popup_right'].forEach(function (c) { - - if (c === cssClass) { - elm.classList.add(c); - } else { - elm.classList.remove(c); - } - }); - - elm.classList.add(cssClass); - }); - } - }, { - key: '_setHSLA', - value: function _setHSLA(h, s, l, a, flags) { - flags = flags || {}; - - var col = this.colour, - hsla = col.hsla; - - [h, s, l, a].forEach(function (x, i) { - if (x || x === 0) { - hsla[i] = x; - } - }); - col.hsla = hsla; - - this._updateUI(flags); - - if (this.onChange && !flags.silent) { - this.onChange(col); - } - } - }, { - key: '_updateUI', - value: function _updateUI(flags) { - if (!this.domElement) { - return; - } - flags = flags || {}; - - var col = this.colour, - hsl = col.hsla, - cssHue = 'hsl(' + hsl[0] * HUES + ', 100%, 50%)', - cssHSL = col.hslString, - cssHSLA = col.hslaString; - - var uiH = this._domH, - uiSL = this._domSL, - uiA = this._domA, - thumbH = $('.picker_selector', uiH), - thumbSL = $('.picker_selector', uiSL), - thumbA = $('.picker_selector', uiA); - - function posX(parent, child, relX) { - child.style.left = relX * 100 + '%'; - } - function posY(parent, child, relY) { - child.style.top = relY * 100 + '%'; - } - - posX(uiH, thumbH, hsl[0]); - - this._domSL.style.backgroundColor = this._domH.style.color = cssHue; - - posX(uiSL, thumbSL, hsl[1]); - posY(uiSL, thumbSL, 1 - hsl[2]); - - uiSL.style.color = cssHSL; - - posY(uiA, thumbA, 1 - hsl[3]); - - var opaque = cssHSL, - transp = opaque.replace('hsl', 'hsla').replace(')', ', 0)'), - bg = 'linear-gradient(' + [opaque, transp] + ')'; - - this._domA.style.background = bg + ', ' + BG_TRANSP; - - if (!flags.fromEditor) { - var format = this.settings.editorFormat, - alpha = this.settings.alpha; - - var value = void 0; - switch (format) { - case 'rgb': - value = col.printRGB(alpha);break; - case 'hsl': - value = col.printHSL(alpha);break; - default: - value = col.printHex(alpha); - } - this._domEdit.value = value; - } - - this._domSample.style.color = cssHSLA; - } - }, { - key: '_ifPopup', - value: function _ifPopup(actionIf, actionElse) { - if (this.settings.parent && this.settings.popup) { - actionIf && actionIf(this.settings.popup); - } else { - actionElse && actionElse(); - } - } - }, { - key: '_toggleDOM', - value: function _toggleDOM(toVisible) { - var dom = this.domElement; - if (!dom) { - return false; - } - - var displayStyle = toVisible ? '' : 'none', - toggle = dom.style.display !== displayStyle; - - if (toggle) { - dom.style.display = displayStyle; - } - return toggle; - } - }]); - return Picker; -}(); - -{ - var style = document.createElement('style'); - style.textContent = '.picker_wrapper.no_alpha .picker_alpha{display:none}.picker_wrapper.no_editor .picker_editor{position:absolute;z-index:-1;opacity:0}.picker_wrapper.no_cancel .picker_cancel{display:none}.layout_default.picker_wrapper{display:flex;flex-flow:row wrap;justify-content:space-between;align-items:stretch;font-size:10px;width:25em;padding:.5em}.layout_default.picker_wrapper input,.layout_default.picker_wrapper button{font-size:1rem}.layout_default.picker_wrapper>*{margin:.5em}.layout_default.picker_wrapper::before{content:"";display:block;width:100%;height:0;order:1}.layout_default .picker_slider,.layout_default .picker_selector{padding:1em}.layout_default .picker_hue{width:100%}.layout_default .picker_sl{flex:1 1 auto}.layout_default .picker_sl::before{content:"";display:block;padding-bottom:100%}.layout_default .picker_editor{order:1;width:6.5rem}.layout_default .picker_editor input{width:100%;height:100%}.layout_default .picker_sample{order:1;flex:1 1 auto}.layout_default .picker_done,.layout_default .picker_cancel{order:1}.picker_wrapper{box-sizing:border-box;background:#f2f2f2;box-shadow:0 0 0 1px silver;cursor:default;font-family:sans-serif;color:#444;pointer-events:auto}.picker_wrapper:focus{outline:none}.picker_wrapper button,.picker_wrapper input{box-sizing:border-box;border:none;box-shadow:0 0 0 1px silver;outline:none}.picker_wrapper button:focus,.picker_wrapper button:active,.picker_wrapper input:focus,.picker_wrapper input:active{box-shadow:0 0 2px 1px #1e90ff}.picker_wrapper button{padding:.4em .6em;cursor:pointer;background-color:#f5f5f5;background-image:linear-gradient(0deg, gainsboro, transparent)}.picker_wrapper button:active{background-image:linear-gradient(0deg, transparent, gainsboro)}.picker_wrapper button:hover{background-color:#fff}.picker_selector{position:absolute;z-index:1;display:block;-webkit-transform:translate(-50%, -50%);transform:translate(-50%, -50%);border:2px solid #fff;border-radius:100%;box-shadow:0 0 3px 1px #67b9ff;background:currentColor;cursor:pointer}.picker_slider .picker_selector{border-radius:2px}.picker_hue{position:relative;background-image:linear-gradient(90deg, red, yellow, lime, cyan, blue, magenta, red);box-shadow:0 0 0 1px silver}.picker_sl{position:relative;box-shadow:0 0 0 1px silver;background-image:linear-gradient(180deg, white, rgba(255, 255, 255, 0) 50%),linear-gradient(0deg, black, rgba(0, 0, 0, 0) 50%),linear-gradient(90deg, #808080, rgba(128, 128, 128, 0))}.picker_alpha,.picker_sample{position:relative;background:linear-gradient(45deg, lightgrey 25%, transparent 25%, transparent 75%, lightgrey 75%) 0 0/2em 2em,linear-gradient(45deg, lightgrey 25%, white 25%, white 75%, lightgrey 75%) 1em 1em/2em 2em;box-shadow:0 0 0 1px silver}.picker_alpha .picker_selector,.picker_sample .picker_selector{background:none}.picker_editor input{font-family:monospace;padding:.2em .4em}.picker_sample::before{content:"";position:absolute;display:block;width:100%;height:100%;background:currentColor}.picker_arrow{position:absolute;z-index:-1}.picker_wrapper.popup{position:absolute;z-index:2;margin:1.5em}.picker_wrapper.popup,.picker_wrapper.popup .picker_arrow::before,.picker_wrapper.popup .picker_arrow::after{background:#f2f2f2;box-shadow:0 0 10px 1px rgba(0,0,0,.4)}.picker_wrapper.popup .picker_arrow{width:3em;height:3em;margin:0}.picker_wrapper.popup .picker_arrow::before,.picker_wrapper.popup .picker_arrow::after{content:"";display:block;position:absolute;top:0;left:0;z-index:-99}.picker_wrapper.popup .picker_arrow::before{width:100%;height:100%;-webkit-transform:skew(45deg);transform:skew(45deg);-webkit-transform-origin:0 100%;transform-origin:0 100%}.picker_wrapper.popup .picker_arrow::after{width:150%;height:150%;box-shadow:none}.popup.popup_top{bottom:100%;left:0}.popup.popup_top .picker_arrow{bottom:0;left:0;-webkit-transform:rotate(-90deg);transform:rotate(-90deg)}.popup.popup_bottom{top:100%;left:0}.popup.popup_bottom .picker_arrow{top:0;left:0;-webkit-transform:rotate(90deg) scale(1, -1);transform:rotate(90deg) scale(1, -1)}.popup.popup_left{top:0;right:100%}.popup.popup_left .picker_arrow{top:0;right:0;-webkit-transform:scale(-1, 1);transform:scale(-1, 1)}.popup.popup_right{top:0;left:100%}.popup.popup_right .picker_arrow{top:0;left:0}'; - document.documentElement.firstElementChild.appendChild(style); - - Picker.StyleElement = style; -} - -function getChrColor$1(chr) { - if (chrColorMap$1[chr]) { - return chrColorMap$1[chr]; - } else if (chrColorMap$1["chr" + chr]) { - const color = chrColorMap$1["chr" + chr]; - chrColorMap$1[chr] = color; - return color; - } else { - const color = randomRGB(); - chrColorMap$1[chr] = color; - return color; - } -} - -function randomRGB (min, max) { - - var r = Math.round(Math.random() * 255).toString(10); - var g = Math.round(Math.random() * 255).toString(10); - var b = Math.round(Math.random() * 255).toString(10); - return "rgb(" + r + "," + g + "," + b + ")"; -} - -const chrColorMap$1 = { - "chrX": "rgb(204, 153, 0)", - "chrY": "rgb(153, 204, 0", - "chrUn": "rgb(50, 50, 50)", - "chr1": "rgb(80, 80, 255)", - "chrI": "rgb(139, 155, 187)", - "chr2": "rgb(206, 61, 50)", - "chrII": "rgb(206, 61, 50)", - "chr2a": "rgb(216, 71, 60)", - "chr2b": "rgb(226, 81, 70)", - "chr3": "rgb(116, 155, 88)", - "chrIII": "rgb(116, 155, 88)", - "chr4": "rgb(240, 230, 133)", - "chrIV": "rgb(240, 230, 133)", - "chr5": "rgb(70, 105, 131)", - "chr6": "rgb(186, 99, 56)", - "chr7": "rgb(93, 177, 221)", - "chr8": "rgb(128, 34, 104)", - "chr9": "rgb(107, 215, 107)", - "chr10": "rgb(213, 149, 167)", - "chr11": "rgb(146, 72, 34)", - "chr12": "rgb(131, 123, 141)", - "chr13": "rgb(199, 81, 39)", - "chr14": "rgb(213, 143, 92)", - "chr15": "rgb(122, 101, 165)", - "chr16": "rgb(228, 175, 105)", - "chr17": "rgb(59, 27, 83)", - "chr18": "rgb(205, 222, 183)", - "chr19": "rgb(97, 42, 121)", - "chr20": "rgb(174, 31, 99)", - "chr21": "rgb(231, 199, 111)", - "chr22": "rgb(90, 101, 94)", - "chr23": "rgb(204, 153, 0)", - "chr24": "rgb(153, 204, 0)", - "chr25": "rgb(51, 204, 0)", - "chr26": "rgb(0, 204, 51)", - "chr27": "rgb(0, 204, 153)", - "chr28": "rgb(0, 153, 204)", - "chr29": "rgb(10, 71, 255)", - "chr30": "rgb(71, 117, 255)", - "chr31": "rgb(255, 194, 10)", - "chr32": "rgb(255, 209, 71)", - "chr33": "rgb(153, 0, 51)", - "chr34": "rgb(153, 26, 0)", - "chr35": "rgb(153, 102, 0)", - "chr36": "rgb(128, 153, 0)", - "chr37": "rgb(51, 153, 0)", - "chr38": "rgb(0, 153, 26)", - "chr39": "rgb(0, 153, 102)", - "chr40": "rgb(0, 128, 153)", - "chr41": "rgb(0, 51, 153)", - "chr42": "rgb(26, 0, 153)", - "chr43": "rgb(102, 0, 153)", - "chr44": "rgb(153, 0, 128)", - "chr45": "rgb(214, 0, 71)", - "chr46": "rgb(255, 20, 99)", - "chr47": "rgb(0, 214, 143)", - "chr48": "rgb(20, 255, 177)", -}; - -class ChordSetManager { - - constructor(config) { - this.tracks = []; - this.chordSets = []; - } - - addChordSet(chordSet) { - - // If a chord set with this name exists replace it (same track, same region) - this.chordSets = this.chordSets.filter(g => g.name !== chordSet.name); - this.chordSets.push(chordSet); - - let track = this.tracks.find(t => chordSet.trackName === t.name); - if (track) { - track.chordSets = track.chordSets.filter(cs => cs.name !== chordSet.name); - track.chordSets.push(chordSet); - } - if (!track) { - track = new IGVTrack(chordSet); - this.tracks.push(track); - } - } - - clearChords() { - this.tracks = []; - this.chordSets = []; - } - - getTrack(name) { - return this.tracks.find(t => name === t.name) - } - - getChordSet(name) { - return this.chordSets.find(cs => name === cs.name) - } - -} - -class IGVTrack { - constructor(chordSet) { - this.name = chordSet.trackName; - this.color = chordSet.trackColor; - this.visible = true; - this.chordSets = [chordSet]; - this.id = guid$1(); - } - - get chords() { - if (this.chordSets.length === 1) { - return this.chordSets[0].chords - } - const chords = []; - for (let cs of this.chordSets) { - for (let c of cs.chords) { - chords.push(c); - } - } - return chords - } -} - - -function guid$1() { - return ("0000" + (Math.random() * Math.pow(36, 4) << 0).toString(36)).slice(-4) -} - -const EXP5 = Math.exp(5); - -class CircularView { - - static isInstalled() { - return window["JBrowseReactCircularGenomeView"] !== undefined && window["React"] !== undefined && window["ReactDOM"] !== undefined - } - - /** - * Create a new CircularView - * - * @param parent - * @param config - configuration options - * { - * assembly: {name: string, id: string, chromosomes: [{name: string, bpLength: integer, color: string}] - * onChordClick: function called upon chord click with chord feature as argument - * } - */ - constructor(parent, config) { - - config = config || {}; - this.config = config; - - if (CircularView.isInstalled()) { - - this.parent = parent; - this.groupByTrack = config.groupByTrack === true; - this.chordManager = new ChordSetManager(config); - - // wrapper for toolbar and circular-view container - const wrapper = document.createElement('div'); - wrapper.className = 'igv-circview-container'; - parent.appendChild(wrapper); - - // toolbar - this.createControls(wrapper); - this.resetControlPanel(); - - // circular view container - const element = document.createElement('div'); - element.className = 'igv-circview-circular-genome-view'; - wrapper.appendChild(element); - this.container = element; - - if (config.assembly) { - this.setAssembly(config.assembly); - } - - this.width = config.width || 500; - this.height = config.height || 500; - this.setSize(this.width, this.height); - - } else { - console.error("JBrowse circular view is not installed"); - } - } - - createControls(parent) { - - // toolbar - const toolbarDiv = document.createElement('div'); - toolbarDiv.className = 'igv-circview-toolbar'; - parent.appendChild(toolbarDiv); - this.toolbar = toolbarDiv; - - // control panel - const controlPanelDiv = document.createElement('div'); - controlPanelDiv.className = 'igv-circview-track-panel'; - parent.appendChild(controlPanelDiv); - this.controlPanel = controlPanelDiv; - this.controlPanel.style.display = 'none'; - - - // toolbar button container - Track Options - Clear All - const buttonContainer = document.createElement('div'); - buttonContainer.className = 'igv-circview-toolbar-button-container'; - this.toolbar.appendChild(buttonContainer); - - // Show Controls - this.showControlsButton = document.createElement('div'); - this.showControlsButton.className = 'igv-circview-button'; - buttonContainer.appendChild(this.showControlsButton); - this.showControlsButton.innerText = 'none' === this.controlPanel.style.display ? 'Show Controls' : 'Hide Controls'; - this.showControlsButton.addEventListener('click', (event) => { - const panelRows = this.controlPanel.querySelectorAll('div'); - if (panelRows.length > 0) { - if ('none' === this.controlPanel.style.display) { - this.controlPanel.style.display = 'flex'; - event.target.innerText = 'Hide Controls'; - } else { - this.controlPanel.style.display = 'none'; - event.target.innerText = 'Show Controls'; - } - } - }); - - // Clear All - let button = document.createElement('div'); - button.className = 'igv-circview-button'; - buttonContainer.appendChild(button); - button.innerText = 'Clear All'; - button.addEventListener('click', () => { - this.clearChords(); - }); - - // Close - if (false !== this.config.showCloseButton) { - button = document.createElement('div'); - button.className = 'igv-circview-button'; - buttonContainer.appendChild(button); - button.innerText = 'Close'; - button.addEventListener('click', () => { - this.visible = false; - }); - } - } - - resetControlPanel() { - this.controlPanel.innerHTML = ''; - this.controlPanel.appendChild(this.createGroupByCB()); - const chordSets = this.groupByTrack ? this.chordManager.tracks : this.chordManager.chordSets; - for(let cs of chordSets) { - this.addToControlPanel(cs); - } - } - - createGroupByCB() { - const groupByCB = document.createElement('input'); - groupByCB.type = 'checkbox'; - groupByCB.id = 'groupByCB'; - groupByCB.style.width = '1.4em'; - groupByCB.style.height = '1.4em'; - groupByCB.checked = this.groupByTrack; - - groupByCB.onclick = (evt) => { - this.groupByTrack = evt.target.checked; - this.resetControlPanel(); - this.render(); - }; - - const groupByLabel = document.createElement('label'); - groupByLabel.for = 'groupByCB'; - groupByLabel.innerText = 'Group by track'; - groupByLabel.style.color = 'black'; - groupByLabel.style.paddingLeft = '10px'; - const trackPanelRow = document.createElement('div'); - trackPanelRow.style.width = '100%'; - trackPanelRow.style.paddingTop = '5px'; - trackPanelRow.style.paddingBottom = '5px'; - trackPanelRow.style.background = 'rgb(216, 230, 234)'; - trackPanelRow.appendChild(groupByCB); - trackPanelRow.appendChild(groupByLabel); - return trackPanelRow - } - - addToControlPanel(chordSet) { - - // single track row - container for hide-button | color-picker-swatch | track-name - const row = document.createElement('div'); - this.controlPanel.appendChild(row); - - - // track hide|show - const hideShowButton = document.createElement('div'); - hideShowButton.className = 'igv-circview-button'; - row.appendChild(hideShowButton); - hideShowButton.innerText = true === chordSet.visible ? 'Hide' : 'Show'; - hideShowButton.addEventListener('click', event => { - if (true === chordSet.visible) { - this.hideChordSet(chordSet.name); - event.target.innerText = "Show"; - } else { - this.showChordSet(chordSet.name); - event.target.innerText = "Hide"; - } - }); - - // The alpha range slider. Create this here so we can reference it from the color picker - const alphaSlider = document.createElement('input'); - const valueToAlpha = (value) => Math.exp(value / 200) / EXP5; - const alphaToValue = (alpha) => 200 * Math.log(alpha * EXP5); - - // color - const colorPickerButton = document.createElement('div'); - colorPickerButton.className = 'igv-circview-button'; - colorPickerButton.innerHTML = '    '; // <- important for button to size properly - row.appendChild(colorPickerButton); - colorPickerButton.style.backgroundColor = setAlpha(chordSet.color, 1); - const pickerConfig = - { - parent: colorPickerButton, - popup: 'right', - editorFormat: 'rgb', - color: chordSet.color, - onChange: ({rgbaString}) => { - colorPickerButton.style.backgroundColor = setAlpha(rgbaString, 1); - this.setColor(chordSet.name, rgbaString); - alphaSlider.value = alphaToValue(getAlpha(chordSet.color)); - } - }; - const picker = new Picker(pickerConfig); - - // alpha transparency - alphaSlider.setAttribute('title', 'Adjust transparency of arcs'); - alphaSlider.type = 'range'; - //alphaSlider.className = 'igv-circview-alpha-slider' - alphaSlider.style.width = '100px'; - alphaSlider.style.marginRight = '10px'; - alphaSlider.setAttribute('class', 'range'); - alphaSlider.setAttribute('min', '0'); - alphaSlider.setAttribute('max', '1000'); - alphaSlider.value = alphaToValue(getAlpha(chordSet.color)); - alphaSlider.oninput = () => { - const v = valueToAlpha(alphaSlider.value); - this.setColor(chordSet.name, setAlpha(chordSet.color, v)); - picker.setColor(chordSet.color); - }; - row.appendChild(alphaSlider); - - // track name - const trackNameDive = document.createElement('div'); - trackNameDive.style.color = 'black'; - row.appendChild(trackNameDive); - trackNameDive.innerText = trackNameDive.title = chordSet.name; - - } - - /** - * Reset view with a new set of chromosomes. - * - * @param igvGenome {name: string, id: string, chromosomes: [{name: string, bpLength: integer, color: string} - */ - setAssembly(igvGenome) { - - const id = this.genomeId || guid$3(); - - if (this.genomeId === id) { - return - } - this.chordManager.clearChords(); - this.genomeId = id; - this.chrNames = new Set(igvGenome.chromosomes.map(chr => shortChrName$1(chr.name))); - - const regions = []; - const colors = []; - for (let chr of igvGenome.chromosomes) { - const shortName = shortChrName$1(chr.name); - colors.push(chr.color || getChrColor$1(shortName)); - regions.push( - { - refName: shortName, - uniqueId: shortName, - start: 0, - end: chr.bpLength - } - ); - } - - this.assembly = { - name: igvGenome.name, - sequence: { - trackId: id, - type: 'ReferenceSequenceTrack', - adapter: { - type: 'FromConfigSequenceAdapter', - features: regions, - }, - }, - refNameColors: colors - }; - - this.render(); - - } - - /** - * Append or replace current set of chords to the global set or a specific track. - * - * @param newChords array of chord feature objects. Example: - * [ - * { - * "uniqueId": "chr1:129763372-129763376_chr1:129806775-129806790", - * "color": "rgba(0, 0, 255, 0.1)", - * "refName": "1", - * "start": 129763372, - * "end": 129763376, - * "mate": { - * "refName": "2", - * "start": 129806775, - * "end": 129806790 - * } - * } - * ] - * @param options { - * name: string, // Track name - * color: string, // Track color - * append: boolean // Replace or append chords to current set. Default is append (true) - * } - */ - - addChords(newChords, options = {}) { - - const tmp = options.name || options.track || "*"; - const trackName = tmp.split(' ')[0].replaceAll("%20", " "); - const chordSetName = tmp.replaceAll("%20", " "); - - const chordSet = { - name: chordSetName, - trackName: trackName, - chords: newChords, - color: options.color || "black", - trackColor: options.trackColor || options.color || "black", - visible: true, - id: options.id || guid$3() - }; - - this.chordManager.addChordSet(chordSet); - - this.resetControlPanel(); - - this.render(); - } - - /** - * Set the nominal size of the view in pixels. Size is reduced some aribtrary amount to account for borders and margins - */ - setSize(width, height) { - - height = height || width; - - this.width = width; - this.height = height; - if (this.viewState) { - const view = this.viewState.session.view; - view.setWidth(width); - view.setHeight(height /* this is the height of the area inside the border in pixels */); - view.setBpPerPx(view.minBpPerPx); - } - } - - getSize() { - return Math.min(this.width, this.height) - } - - clearChords() { - //this.tracks = [] - this.chordManager.clearChords(); - this.resetControlPanel(); - this.render(); - } - - clearSelection() { - this.viewState.pluginManager.rootModel.session.clearSelection(); - } - - /** - * Deprecated, use "visible" property - */ - show() { - this.parent.style.display = 'block'; - } - - /** - * Deprecated, use "visible" property - */ - hide() { - this.parent.style.display = 'none'; - } - - get visible() { - return this.parent.style.display !== 'none' - } - - set visible(isVisible) { - this.parent.style.display = isVisible ? 'block' : 'none'; - } - - hideChordSet(trackName) { - let cs = this.getChordSet(trackName); - if (cs) { - cs.visible = false; - this.render(); - } else { - console.warn(`No track with name: ${name}`); - } - } - - showChordSet(name) { - let cs = this.getChordSet(name); - if (cs) { - cs.visible = true; - this.render(); - } else { - console.warn(`No track with name: ${name}`); - } - } - - // showTrack(trackID) { - // let idx = this.tracks.findIndex(t => trackID === t.id) - // if (idx >= 0) { - // const track = this.tracks[idx] - // track.visible = true - // this.tracks.splice(idx, 1) // Change z-order - // this.tracks.push(track) - // this.render() - // } else { - // console.warn(`No track with name: ${name}`) - // } - // } - - // TODO -- remove corresponding row from track panel - deleteTrack(trackID) { - let idx = this.tracks.findIndex(t => trackID === t.name); - if (idx >= 0) { - this.tracks.splice(idx, 1); - } - this.render(); - } - - getChordSet(name) { - return this.groupByTrack ? this.chordManager.getTrack(name) : this.chordManager.getChordSet(name) - } - - setColor(name, color) { - const t = this.getChordSet(name); - if (t) { - t.color = color; - const trackID = t.id; - for (let jbrowseTrack of this.viewState.config.tracks) { - if (trackID === jbrowseTrack.trackId) { - jbrowseTrack.displays[0].renderer.strokeColor.set(color); - break - } - } - } - } - - /** - * The main render function. Render here means build the React DOM. Trying to change react state dynamically - * has been buggy, so we completely rebuild the DOM ("render") on any state change. - */ - render() { - - const { - createViewState, - JBrowseCircularGenomeView, - } = JBrowseReactCircularGenomeView; - - // Remove all children from possible previous renders. React might do this for us when we render, but just in case. - ReactDOM.unmountComponentAtNode(this.container); - - const visibleChordSets = - (this.groupByTrack ? this.chordManager.tracks : this.chordManager.chordSets).filter(t => t.visible); - - const jbrowseTracks = []; - const colors = []; - - for (let chordSet of visibleChordSets) { - - jbrowseTracks.push({ - trackId: chordSet.id, - name: chordSet.name, - assemblyNames: ['forIGV'], - type: 'VariantTrack', - adapter: { - type: 'FromConfigAdapter', - features: chordSet.chords, - } - }); - colors.push(chordSet.color); - } - - this.viewState = createViewState({ - assembly: this.assembly, - tracks: jbrowseTracks, - }); - - // Set view colors - for (let i = 0; i < visibleChordSets.length; i++) { - this.viewState.config.tracks[i].displays[0].renderer.strokeColor.set(colors[i]); - //this.viewState.config.tracks[i].displays[0].renderer.strokeColor.set("jexl:get(feature, 'color') || 'black'"); - //this.viewState.config.tracks[i].displays[0].renderer.strokeColorSelected.set("jexl:get(feature, 'highlightColor') || 'red'"); - } - - this.element = React.createElement(JBrowseCircularGenomeView, {viewState: this.viewState}); - this.setSize(this.width, this.height); - - ReactDOM.render(this.element, this.container); - - const onChordClick = this.config.onChordClick || defaultOnChordClick; - for (let i = 0; i < visibleChordSets.length; i++) { - this.viewState.session.view.showTrack(this.viewState.config.tracks[i].trackId); - if (onChordClick) { - this.viewState.pluginManager.jexl.addFunction('onChordClick', onChordClick); - this.viewState.config.tracks[i].displays[0].onChordClick.set( - 'jexl:onChordClick(feature, track, pluginManager)' - ); - } - } - } -} - -function setAlpha(rgba, alpha) { - const [a, b, c, ignore] = rgba.split(','); // rgba(r g b alpha) - return `${a},${b},${c},${alpha})` -} - -function getAlpha(rgba) { - if (rgba.startsWith("rgba(")) { - return Number(rgba.split(',')[3].replace(')', '')) - } else { - return 1 - } -} - -function shortChrName$1(chrName) { - return chrName.startsWith("chr") ? chrName.substring(3) : chrName -} - -function defaultOnChordClick(feature, chordTrack, pluginManager) { - console.log(feature); -} - -function guid$3() { - return ("0000" + (Math.random() * Math.pow(36, 4) << 0).toString(36)).slice(-4) -} - -function embedCSS$1() { - - const css = '.igv-circview-container {\n width: fit-content;\n height: fit-content;\n box-sizing: content-box;\n color: dimgray;\n font-family: \"Open Sans\", sans-serif;\n font-size: 12px;\n background-color: white;\n border-color: dimgray;\n border-style: solid;\n border-width: thin;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: flex-start;\n}\n\n.igv-circview-toolbar {\n position: relative;\n width: 100%;\n height: 32px;\n background-color: lightgrey;\n border-bottom-style: solid;\n border-bottom-color: dimgray;\n border-bottom-width: thin;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-between;\n align-items: center;\n}\n\n.igv-circview-toolbar-button-container {\n height: 100%;\n width: fit-content;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n}\n.igv-circview-toolbar-button-container > div {\n margin: 4px;\n}\n\n.igv-circview-track-panel {\n z-index: 1024;\n position: absolute;\n top: 33px;\n left: 0;\n width: 100%;\n height: fit-content;\n border-bottom-style: solid;\n border-bottom-color: dimgray;\n border-bottom-width: thin;\n background-color: white;\n display: flex;\n flex-flow: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: flex-start;\n}\n.igv-circview-track-panel > div {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n}\n.igv-circview-track-panel > div > div {\n margin: 4px;\n}\n\n.igv-circview-swatch-button {\n cursor: pointer;\n padding: 5px;\n width: 8px;\n height: 8px;\n border: 1px solid #8d8b8b;\n border-radius: 16px;\n}\n\n.igv-circview-button {\n cursor: pointer;\n padding: 5px;\n color: #444;\n vertical-align: middle;\n text-align: center;\n font-family: \"Open Sans\", sans-serif;\n font-size: 12px;\n border: 1px solid #8d8b8b;\n border-radius: 4px;\n background: #efefef;\n box-shadow: 0 0 5px -1px rgba(0, 0, 0, 0.2);\n}\n\n.igv-circview-button:hover {\n background: #efefef;\n box-shadow: 0 0 5px -1px rgba(0, 0, 0, 0.6);\n}\n\n.igv-circview-button:active {\n color: #007bff;\n box-shadow: 0 0 5px -1px rgba(0, 0, 0, 0.6);\n}\n\n/*# sourceMappingURL=circular-view.css.map */\n'; - - const style = document.createElement('style'); - style.setAttribute('type', 'text/css'); - style.innerHTML = css; - document.head.insertBefore(style, document.head.childNodes[ document.head.childNodes.length - 1 ]); -} - -if(typeof document !== 'undefined') { - - if (!stylesheetExists("circular-view.css")) { - embedCSS$1(); - } - - function stylesheetExists(stylesheetName) { - for (let ss of document.styleSheets) { - ss = ss.href ? ss.href.replace(/^.*[\\\/]/, '') : ''; - if (ss === stylesheetName) { - return true; - } - } - return false; - } -} - -/** - * The minimum length for a VCF structural variant. VCF records < this length are ignored in the circular view - * @type {number} - */ -const MINIMUM_SV_LENGTH = 1000000; - -const shortChrName = (chrName) => { - return chrName.startsWith("chr") ? chrName.substring(3) : chrName -}; - -const makePairedAlignmentChords = (alignments) => { - - const chords = []; - for (let a of alignments) { - - if(a.paired) { - if(a.firstAlignment && a.secondAlignment) { - chords.push({ - uniqueId: a.readName, - refName: shortChrName(a.firstAlignment.chr), - start: a.firstAlignment.start, - end: a.firstAlignment.end, - mate: { - refName: shortChrName(a.secondAlignment.chr), - start: a.secondAlignment.start, - end: a.secondAlignment.end, - } - }); - } - } - else { - const mate = a.mate; - if (mate && mate.chr && mate.position) { - chords.push({ - uniqueId: a.readName, - refName: shortChrName(a.chr), - start: a.start, - end: a.end, - mate: { - refName: shortChrName(mate.chr), - start: mate.position - 1, - end: mate.position, - } - }); - } - } - } - return chords -}; - -const makeSupplementalAlignmentChords = (alignments) => { - - const makeChords = (a) => { - const sa = a.tags()['SA']; - const supAl = createSupplementaryAlignments(sa); - let n = 0; - for (let s of supAl) { - if (s.start !== a.start) { - chords.push({ - uniqueId: `${a.readName}_${n++}`, - refName: shortChrName(a.chr), - start: a.start, - end: a.end, - mate: { - refName: shortChrName(s.chr), - start: s.start, - end: s.start + s.lenOnRef - } - }); - } - } - }; - - const chords = []; - for (let a of alignments) { - if(a.paired) { - makeChords(a.firstAlignment); - if(a.secondAlignment) { - makeChords(a.secondAlignment); - } - } else { - makeChords(a); - } - } - return chords -}; - -const makeBedPEChords = (features) => { - - return features.map(v => { - - // If v is a whole-genome feature, get the true underlying variant. - const f = v._f || v; - - return { - uniqueId: `${f.chr1}:${f.start1}-${f.end1}_${f.chr2}:${f.start2}-${f.end2}`, - refName: shortChrName(f.chr1), - start: f.start1, - end: f.end1, - mate: { - refName: shortChrName(f.chr2), - start: f.start2, - end: f.end2, - } - } - }) -}; - - -const makeVCFChords = (features) => { - - const svFeatures = features.filter(v => { - const f = v._f || v; - const isLargeEnough = f.info && f.info.CHR2 && f.info.END && - (f.info.CHR2 !== f.chr || Math.abs(Number.parseInt(f.info.END) - f.pos) > MINIMUM_SV_LENGTH); - return isLargeEnough - }); - return svFeatures.map(v => { - - // If v is a whole-genome feature, get the true underlying variant. - const f = v._f || v; - - const pos2 = Number.parseInt(f.info.END); - const start2 = pos2 - 100; - const end2 = pos2 + 100; - - return { - uniqueId: `${f.chr}:${f.start}-${f.end}_${f.info.CHR2}:${f.info.END}`, - refName: shortChrName(f.chr), - start: f.start, - end: f.end, - mate: { - refName: shortChrName(f.info.CHR2), - start: start2, - end: end2 - } - } - }) -}; - -function makeCircViewChromosomes(genome) { - const regions = []; - const colors = []; - for (let chrName of genome.wgChromosomeNames) { - const chr = genome.getChromosome(chrName); - colors.push(getChrColor(chr.name)); - regions.push( - { - name: chr.name, - bpLength: chr.bpLength - } - ); - } - return regions -} - -function sendChords(chords, track, refFrame, alpha) { - - const baseColor = track.color || 'rgb(0,0,255)'; - - const chordSetColor = IGVColor.addAlpha("all" === refFrame.chr ? baseColor : getChrColor(refFrame.chr), alpha); - const trackColor = IGVColor.addAlpha(baseColor, alpha); - - // name the chord set to include locus and filtering information - const encodedName = track.name.replaceAll(' ', '%20'); - const chordSetName = "all" === refFrame.chr ? encodedName : - `${encodedName} ${refFrame.chr}:${refFrame.start}-${refFrame.end}`; - track.browser.circularView.addChords(chords, {track: chordSetName, color: chordSetColor, trackColor: trackColor}); - - // show circular view if hidden - if(!track.browser.circularViewVisible) track.browser.circularViewVisible = true; - -} - - -function createCircularView(el, browser) { - - const circularView = new CircularView(el, { - - onChordClick: (feature, chordTrack, pluginManager) => { - - const f1 = feature.data; - const f2 = f1.mate; - addFrameForFeature(f1); - addFrameForFeature(f2); - - function addFrameForFeature(feature) { - - feature.chr = browser.genome.getChromosomeName(feature.refName); - let frameFound = false; - for (let referenceFrame of browser.referenceFrameList) { - const l = Locus.fromLocusString(referenceFrame.getLocusString()); - if (l.contains(feature)) { - frameFound = true; - break - } else if (l.overlaps(feature)) { - referenceFrame.extend(feature); - frameFound = true; - break - } - } - if (!frameFound) { - const flanking = 2000; - const center = (feature.start + feature.end) / 2; - browser.addMultiLocusPanel(feature.chr, center - flanking, center + flanking); - - } - } - } - }); - - return circularView -} - -class PairedEndStats { - - constructor(alignments, {minTLENPercentile, maxTLENPercentile}) { - this.totalCount = 0; - this.frCount = 0; - this.rfCount = 0; - this.ffCount = 0; - this.sumF = 0; - this.sumF2 = 0; - this.lp = minTLENPercentile === undefined ? 0.1 : minTLENPercentile; - this.up = maxTLENPercentile === undefined ? 99.5 : maxTLENPercentile; - this.isizes = []; - this.compute(alignments); - } - - compute(alignments) { - - for (let alignment of alignments) { - if (alignment.isProperPair()) { - var tlen = Math.abs(alignment.fragmentLength); - this.sumF += tlen; - this.sumF2 += tlen * tlen; - this.isizes.push(tlen); - - var po = alignment.pairOrientation; - - if (typeof po === "string" && po.length === 4) { - var tmp = '' + po.charAt(0) + po.charAt(2); - switch (tmp) { - case 'FF': - case 'RR': - this.ffCount++; - break - case "FR": - this.frCount++; - break - case"RF": - this.rfCount++; - } - } - this.totalCount++; - } - } - - if (this.ffCount / this.totalCount > 0.9) this.orienation = "ff"; - else if (this.frCount / this.totalCount > 0.9) this.orienation = "fr"; - else if (this.rfCount / this.totalCount > 0.9) this.orienation = "rf"; - - this.minTLEN = this.lp === 0 ? 0 : percentile(this.isizes, this.lp); - this.maxTLEN = percentile(this.isizes, this.up); - - // var fMean = this.sumF / this.totalCount - // var stdDev = Math.sqrt((this.totalCount * this.sumF2 - this.sumF * this.sumF) / (this.totalCount * this.totalCount)) - // this.minTLEN = fMean - 3 * stdDev - // this.maxTLEN = fMean + 3 * stdDev - - } -} - -function percentile(array, p) { - - if (array.length === 0) return undefined - var k = Math.floor(array.length * (p / 100)); - array.sort(function (a, b) { - return a - b - }); - return array[k] - -} - -const GtexUtils = { - - getTissueInfo: function (datasetId, baseURL) { - datasetId = datasetId || 'gtex_v8'; - baseURL = baseURL || 'https://gtexportal.org/rest/v1'; - let url = baseURL + '/dataset/tissueInfo?datasetId=' + datasetId; - return igvxhr.loadJson(url, {}) - }, - - //https://gtexportal.org/rest/v1/association/singleTissueEqtlByLocation?chromosome=7&start=98358766&end=101523798&tissueName=Liver&datasetId=gtex_v7 - //https://gtexportal.org/rest/v1/association/singleTissueEqtlByLocation?chromosome=7&start=98358766&end=101523798&tissueSiteDetailId=Liver&datasetId=gtex_v8 - trackConfiguration: function (tissueSummary, baseURL) { - baseURL = baseURL || 'https://gtexportal.org/rest/v1'; - return { - type: "eqtl", - sourceType: "gtex-ws", - url: baseURL + '/association/singleTissueEqtlByLocation', - tissueSiteDetailId: tissueSummary.tissueSiteDetailId, - name: (tissueSummary.tissueSiteDetailId.split('_').join(' ')), - visibilityWindow: 250000 - } - } -}; - -/** - * @param feature - * @param bpStart genomic location of the left edge of the current canvas - * @param xScale scale in base-pairs per pixel - * @returns {{px: number, px1: number, pw: number, h: number, py: number}} - */ -function calculateFeatureCoordinates(feature, bpStart, xScale) { - let px = (feature.start - bpStart) / xScale; - let px1 = (feature.end - bpStart) / xScale; - //px = Math.round((feature.start - bpStart) / xScale), - //px1 = Math.round((feature.end - bpStart) / xScale), - let pw = px1 - px; - - if (pw < 3) { - pw = 3; - px -= 1.5; - } - - return { - px: px, - px1: px1, - pw: pw - } -} - -/** - * - * @param feature - * @param bpStart genomic location of the left edge of the current canvas - * @param xScale scale in base-pairs per pixel - * @param pixelHeight pixel height of the current canvas - * @param ctx the canvas 2d context - * @param options genomic state - */ -function renderFeature(feature, bpStart, xScale, pixelHeight, ctx, options) { - - try { - ctx.save(); - - // Set ctx color to a known valid color. If getColorForFeature returns an invalid color string it is ignored, and - // this default will be used. - ctx.fillStyle = this.color; - ctx.strokeStyle = this.color; - - const color = this.getColorForFeature(feature); - ctx.fillStyle = color; - ctx.strokeStyle = color; - - let h; - let py; - if (this.displayMode === "SQUISHED" && feature.row !== undefined) { - h = this.featureHeight / 2; - py = this.margin + this.squishedRowHeight * feature.row; - } else if (this.displayMode === "EXPANDED" && feature.row !== undefined) { - h = this.featureHeight; - py = this.margin + this.expandedRowHeight * feature.row; - } else { // collapsed - h = this.featureHeight; - py = this.margin; - } - - const pixelWidth = options.pixelWidth; // typical 3*viewportWidth - - const cy = py + h / 2; - const h2 = h / 2; - const py2 = cy - h2 / 2; - - const exonCount = feature.exons ? feature.exons.length : 0; - const coord = calculateFeatureCoordinates(feature, bpStart, xScale); - const step = this.arrowSpacing; - const direction = feature.strand === '+' ? 1 : feature.strand === '-' ? -1 : 0; - - if (exonCount === 0) { - // single-exon transcript - const xLeft = Math.max(0, coord.px); - const xRight = Math.min(pixelWidth, coord.px1); - const width = xRight - xLeft; - ctx.fillRect(xLeft, py, width, h); - - // Arrows - // Do not draw if strand is not +/- - if (direction !== 0) { - ctx.fillStyle = "white"; - ctx.strokeStyle = "white"; - for (let x = xLeft + step / 2; x < xRight; x += step) { - // draw arrowheads along central line indicating transcribed orientation - IGVGraphics.strokeLine(ctx, x - direction * 2, cy - 2, x, cy); - IGVGraphics.strokeLine(ctx, x - direction * 2, cy + 2, x, cy); - } - ctx.fillStyle = color; - ctx.strokeStyle = color; - } - } else { - // multi-exon transcript - IGVGraphics.strokeLine(ctx, coord.px + 1, cy, coord.px1 - 1, cy); // center line for introns - - - const xLeft = Math.max(0, coord.px) + step / 2; - const xRight = Math.min(pixelWidth, coord.px1); - for (let x = xLeft; x < xRight; x += step) { - // draw arrowheads along central line indicating transcribed orientation - IGVGraphics.strokeLine(ctx, x - direction * 2, cy - 2, x, cy); - IGVGraphics.strokeLine(ctx, x - direction * 2, cy + 2, x, cy); - } - for (let e = 0; e < exonCount; e++) { - // draw the exons - const exon = feature.exons[e]; - let ePx = Math.round((exon.start - bpStart) / xScale); - let ePx1 = Math.round((exon.end - bpStart) / xScale); - let ePw = Math.max(1, ePx1 - ePx); - let ePxU; - - if (ePx + ePw < 0) { - continue // Off the left edge - } - if (ePx > pixelWidth) { - break // Off the right edge - } - - if (exon.utr) { - ctx.fillRect(ePx, py2, ePw, h2); // Entire exon is UTR - } else { - if (exon.cdStart) { - ePxU = Math.round((exon.cdStart - bpStart) / xScale); - ctx.fillRect(ePx, py2, ePxU - ePx, h2); // start is UTR - ePw -= (ePxU - ePx); - ePx = ePxU; - - } - if (exon.cdEnd) { - ePxU = Math.round((exon.cdEnd - bpStart) / xScale); - ctx.fillRect(ePxU, py2, ePx1 - ePxU, h2); // start is UTR - ePw -= (ePx1 - ePxU); - ePx1 = ePxU; - } - - ePw = Math.max(ePw, 1); - ctx.fillRect(ePx, py, ePw, h); - - // Arrows - if (ePw > step + 5 && direction !== 0) { - ctx.fillStyle = "white"; - ctx.strokeStyle = "white"; - for (let x = ePx + step / 2; x < ePx1; x += step) { - // draw arrowheads along central line indicating transcribed orientation - IGVGraphics.strokeLine(ctx, x - direction * 2, cy - 2, x, cy); - IGVGraphics.strokeLine(ctx, x - direction * 2, cy + 2, x, cy); - } - ctx.fillStyle = color; - ctx.strokeStyle = color; - - } - } - } - } - - if (options.drawLabel && this.displayMode !== "SQUISHED") { - renderFeatureLabel.call(this, ctx, feature, coord.px, coord.px1, py, options.referenceFrame, options); - } - } finally { - ctx.restore(); - } -} - -/** - * @param ctx the canvas 2d context - * @param feature - * @param featureX feature start in pixel coordinates - * @param featureX1 feature end in pixel coordinates - * @param featureY feature y-coordinate - * @param windowX visible window start x-coordinate - * @param windowX1 visible window end x-coordinate - * @param referenceFrame genomic state - * @param options options - */ -function renderFeatureLabel(ctx, feature, featureX, featureX1, featureY, referenceFrame, options) { - - try { - ctx.save(); - - let name = feature.name; - if (name === undefined && feature.gene) name = feature.gene.name; - if (name === undefined) name = feature.id || feature.ID; - if (!name || name === '.') return - - let centerX = (featureX + featureX1) / 2; - - let transform; - if (this.displayMode === "COLLAPSED" && this.labelDisplayMode === "SLANT") { - transform = {rotate: {angle: 45}}; - } - const labelY = getFeatureLabelY(featureY, transform); - - let color = this.getColorForFeature(feature); - let geneColor; - let gtexSelection = false; - if (referenceFrame.selection && GtexUtils.gtexLoaded) { - // TODO -- for gtex, figure out a better way to do this - gtexSelection = true; - geneColor = referenceFrame.selection.colorForGene(name); - } - - const geneFontStyle = { - textAlign: "SLANT" === this.labelDisplayMode ? undefined : 'center', - fillStyle: geneColor || color, - strokeStyle: geneColor || color - }; - - const textBox = ctx.measureText(name); - const xleft = centerX - textBox.width / 2; - const xright = centerX + textBox.width / 2; - const lastLabelX = options.rowLastLabelX[feature.row] || -Number.MAX_SAFE_INTEGER; - if (options.labelAllFeatures || xleft > lastLabelX || gtexSelection) { - options.rowLastLabelX[feature.row] = xright; - - if ('y' === options.axis) { - ctx.save(); - IGVGraphics.labelTransformWithContext(ctx, centerX); - IGVGraphics.fillText(ctx, name, centerX, labelY, geneFontStyle, transform); - ctx.restore(); - } else { - IGVGraphics.fillText(ctx, name, centerX, labelY, geneFontStyle, transform); - } - } - - } finally { - ctx.restore(); - } -} - -function getFeatureLabelY(featureY, transform) { - return transform ? featureY + 20 : featureY + 25 -} - -// SNP constants - -const codingNonSynonSet = new Set(['nonsense', 'missense', 'stop-loss', 'frameshift', 'cds-indel']); -const codingSynonSet = new Set(['coding-synon']); -const spliceSiteSet = new Set(['splice-3', 'splice-5']); -const untranslatedSet = new Set(['untranslated-5', 'untranslated-3']); - - -/** - * Renderer for a UCSC snp track - * - * @param snp - * @param bpStart genomic location of the left edge of the current canvas - * @param xScale scale in base-pairs per pixel - * @param pixelHeight pixel height of the current canvas - * @param ctx the canvas 2d context - */ -function renderSnp(snp, bpStart, xScale, pixelHeight, ctx) { - - var coord = calculateFeatureCoordinates(snp, bpStart, xScale), - py = this.margin, - h, - colorArrLength = this.snpColors.length, - colorPriority; - - h = this.displayMode === "squished" ? this.squishedRowHeight : this.expandedRowHeight; - - switch (this.colorBy) { - case 'function': - colorPriority = colorByFunc(snp.func); - break - case 'class': - colorPriority = colorByClass(snp['class']); - } - - ctx.fillStyle = this.snpColors[colorPriority]; - ctx.fillRect(coord.px, py, coord.pw, h); - - // Coloring functions, convert a value to a priority - - function colorByFunc(theFunc) { - var priorities; - var funcArray = theFunc.split(','); - // possible func values - - - priorities = funcArray.map(function (func) { - if (codingNonSynonSet.has(func) || spliceSiteSet.has(func)) { - return colorArrLength - 1 - } else if (codingSynonSet.has(func)) { - return colorArrLength - 2 - } else if (untranslatedSet.has(func)) { - return colorArrLength - 3 - } else { // locusSet.has(func) || intronSet.has(func) - return 0 - } - }); - - return priorities.reduce(function (a, b) { - return Math.max(a, b) - }) - } - - function colorByClass(cls) { - if (cls === 'deletion') { - return colorArrLength - 1 - } else if (cls === 'mnp') { - return colorArrLength - 2 - } else if (cls === 'microsatellite' || cls === 'named') { - return colorArrLength - 3 - } else { // cls === 'single' || cls === 'in-del' || cls === 'insertion' - return 0 - } - } -} - -/** - * - * @param feature - * @param bpStart genomic location of the left edge of the current canvas - * @param xScale scale in base-pairs per pixel - * @param pixelHeight pixel height of the current canvas - * @param ctx the canvas 2d context - */ -function renderFusionJuncSpan(feature, bpStart, xScale, pixelHeight, ctx) { - - const rowHeight = (this.displayMode === "EXPANDED") ? this.expandedRowHeight : this.squishedRowHeight; - let py = this.margin; - if (this.displayMode !== "COLLAPSED" && feature.row !== undefined) { - py += feature.row * rowHeight; - } - - const cy = py + 0.5 * rowHeight; - const topY = cy - 0.5 * rowHeight; - const bottomY = cy + 0.5 * rowHeight; - - // draw the junction arc - const junctionLeftPx = Math.round((feature.junction_left - bpStart) / xScale); - const junctionRightPx = Math.round((feature.junction_right - bpStart) / xScale); - - ctx.beginPath(); - ctx.moveTo(junctionLeftPx, cy); - ctx.bezierCurveTo(junctionLeftPx, topY, junctionRightPx, topY, junctionRightPx, cy); - - ctx.lineWidth = 1 + Math.log(feature.num_junction_reads) / Math.log(2); - ctx.strokeStyle = 'blue'; - ctx.stroke(); - - // draw the spanning arcs - const spanningCoords = feature.spanning_frag_coords; - for (let i = 0; i < spanningCoords.length; i++) { - - const spanningInfo = spanningCoords[i]; - const spanLeftPx = Math.round((spanningInfo.left - bpStart) / xScale); - const spanRightPx = Math.round((spanningInfo.right - bpStart) / xScale); - - ctx.beginPath(); - ctx.moveTo(spanLeftPx, cy); - ctx.bezierCurveTo(spanLeftPx, bottomY, spanRightPx, bottomY, spanRightPx, cy); - - ctx.lineWidth = 1; - ctx.strokeStyle = 'purple'; - ctx.stroke(); - } -} - -const DEFAULT_COLOR$2 = 'rgb(0, 0, 150)'; - - -class FeatureTrack extends TrackBase { - - static defaults = { - type: "annotation", - maxRows: 1000, // protects against pathological feature packing cases (# of rows of overlapping feaures) - displayMode: "EXPANDED", // COLLAPSED | EXPANDED | SQUISHED - margin: 10, - featureHeight: 14, - autoHeight: false, - useScore: false - } - - - constructor(config, browser) { - super(config, browser); - } - - init(config) { - super.init(config); - - - // Obscure option, not common or supoorted, included for backward compatibility - this.labelDisplayMode = config.labelDisplayMode; - - if (config._featureSource) { - this.featureSource = config._featureSource; - delete config._featureSource; - } else { - this.featureSource = config.featureSource ? - config.featureSource : - FeatureSource(config, this.browser.genome); - } - - if ("FusionJuncSpan" === config.type) { - this.render = config.render || renderFusionJuncSpan; - this.squishedRowHeight = config.squishedRowHeight || 50; - this.expandedRowHeight = config.expandedRowHeight || 50; - this.height = config.height || this.margin + 2 * this.expandedRowHeight; - } else if ('snp' === config.type) { - this.render = config.render || renderSnp; - // colors ordered based on priority least to greatest - this.snpColors = ['rgb(0,0,0)', 'rgb(0,0,255)', 'rgb(0,255,0)', 'rgb(255,0,0)']; - this.colorBy = 'function'; - this.expandedRowHeight = config.expandedRowHeight || 10; - this.squishedRowHeight = config.squishedRowHeight || 5; - this.height = config.height || 30; - } else { - this.render = config.render || renderFeature; - this.arrowSpacing = 30; - // adjust label positions to make sure they're always visible - monitorTrackDrag(this); - this.squishedRowHeight = config.squishedRowHeight || 15; - this.expandedRowHeight = config.expandedRowHeight || 30; - this.height = config.height || this.margin + 2 * this.expandedRowHeight; - - // Set colorBy fields considering legacy options for backward compatibility - if (config.colorBy) { - if (config.colorBy.field) { - config.colorTable = config.colorBy.pallete || config.colorBy.palette; - config.colorBy = config.colorBy.field; - } - this.colorBy = config.colorBy; // Can be undefined => default - if (config.colorTable) { - this.colorTable = new ColorTable(config.colorTable); - } else { - this.colorTable = new PaletteColorTable("Set1"); - } - } - } - } - - async postInit() { - - if (typeof this.featureSource.getHeader === "function") { - this.header = await this.featureSource.getHeader(); - if (this.disposed) return // This track was removed during async load - } - - // Set properties from track line - if (this.header) { - this.setTrackProperties(this.header); - } - - if (this.visibilityWindow === undefined && typeof this.featureSource.defaultVisibilityWindow === 'function') { - this.visibilityWindow = await this.featureSource.defaultVisibilityWindow(); - } - - return this - - } - - get supportsWholeGenome() { - if (this.config.supportsWholeGenome !== undefined) { - return this.config.supportsWholeGenome - } else if (this.featureSource && typeof this.featureSource.supportsWholeGenome === 'function') { - return this.featureSource.supportsWholeGenome() - } else { - if (this.visibilityWindow === undefined && (this.config.indexed === false || !this.config.indexURL)) { - return true - } - } - } - - async getFeatures(chr, start, end, bpPerPixel) { - const visibilityWindow = this.visibilityWindow; - return this.featureSource.getFeatures({chr, start, end, bpPerPixel, visibilityWindow}) - }; - - - /** - * The required height in pixels required for the track content. This is not the visible track height, which - * can be smaller (with a scrollbar) or larger. - * - * @param features - * @returns {*} - */ - computePixelHeight(features) { - - if (this.displayMode === "COLLAPSED") { - return this.margin + this.expandedRowHeight - } else { - let maxRow = 0; - if (features && (typeof features.forEach === "function")) { - for (let feature of features) { - if (feature.row && feature.row > maxRow) { - maxRow = feature.row; - } - } - } - - const height = this.margin + (maxRow + 1) * ("SQUISHED" === this.displayMode ? this.squishedRowHeight : this.expandedRowHeight); - return height - - } - }; - - draw(options) { - - const featureList = options.features; - const ctx = options.context; - const bpPerPixel = options.bpPerPixel; - const bpStart = options.bpStart; - const pixelWidth = options.pixelWidth; - const pixelHeight = options.pixelHeight; - const bpEnd = bpStart + pixelWidth * bpPerPixel + 1; - - - if (!this.config.isMergedTrack) { - IGVGraphics.fillRect(ctx, 0, options.pixelTop, pixelWidth, pixelHeight, {'fillStyle': "rgb(255, 255, 255)"}); - } - - if (featureList) { - - const rowFeatureCount = []; - options.rowLastX = []; - options.rowLastLabelX = []; - for (let feature of featureList) { - if (feature.start > bpStart && feature.end < bpEnd) { - const row = this.displayMode === "COLLAPSED" ? 0 : feature.row || 0; - if (rowFeatureCount[row] === undefined) { - rowFeatureCount[row] = 1; - } else { - rowFeatureCount[row]++; - } - options.rowLastX[row] = -Number.MAX_SAFE_INTEGER; - options.rowLastLabelX[row] = -Number.MAX_SAFE_INTEGER; - } - } - const maxFeatureCount = Math.max(1, Math.max(...rowFeatureCount)); - const pixelsPerFeature = pixelWidth / maxFeatureCount; - - let lastPxEnd = []; - for (let feature of featureList) { - if (feature.end < bpStart) continue - if (feature.start > bpEnd) break - const row = this.displayMode === 'COLLAPSED' ? 0 : feature.row; - options.drawLabel = options.labelAllFeatures || pixelsPerFeature > 10; - const pxEnd = Math.ceil((feature.end - bpStart) / bpPerPixel); - const last = lastPxEnd[row]; - if (!last || pxEnd > last) { - this.render.call(this, feature, bpStart, bpPerPixel, pixelHeight, ctx, options); - - // Ensure a visible gap between features - const pxStart = Math.floor((feature.start - bpStart) / bpPerPixel); - if (last && pxStart - last <= 0) { - ctx.globalAlpha = 0.5; - IGVGraphics.strokeLine(ctx, pxStart, 0, pxStart, pixelHeight, {'strokeStyle': "rgb(255, 255, 255)"}); - ctx.globalAlpha = 1.0; - } - lastPxEnd[row] = pxEnd; - } - } - - } else { - console.log("No feature list"); - } - - }; - - clickedFeatures(clickState) { - - const y = clickState.y - this.margin; - const allFeatures = super.clickedFeatures(clickState); - - let row; - switch (this.displayMode) { - case 'SQUISHED': - row = Math.floor(y / this.squishedRowHeight); - break - case 'EXPANDED': - row = Math.floor(y / this.expandedRowHeight); - break - default: - row = undefined; - } - - return allFeatures.filter(function (feature) { - return (row === undefined || feature.row === undefined || row === feature.row) - }) - } - - /** - * Return "popup data" for feature @ genomic location. Data is an array of key-value pairs - */ - popupData(clickState, features) { - - if (features === undefined) features = this.clickedFeatures(clickState); - const genomicLocation = clickState.genomicLocation; - const data = []; - for (let feature of features) { - - // Whole genome hack, whole-genome psuedo features store the "real" feature in an _f field - const f = feature._f || feature; - - const featureData = (typeof f.popupData === "function") ? - f.popupData(genomicLocation) : - this.extractPopupData(f); - - if (featureData) { - - if (data.length > 0) { - data.push("

"); - } - - // If we have an infoURL, find the name property and create the link. We do this at this level - // to catch name properties in both custom popupData functions and the generic extractPopupData function - - const infoURL = this.infoURL || this.config.infoURL; - for (let fd of featureData) { - data.push(fd); - if (infoURL && - fd.name && - fd.name.toLowerCase() === "name" && - fd.value && - isString$2(fd.value) && - !fd.value.startsWith("<")) { - const href = infoURL.replace("$$", feature.name); - fd.value = `${fd.value}`; - } - } - - - //Array.prototype.push.apply(data, featureData); - - // If we have clicked over an exon number it. - // Disabled for GFF and GTF files if the visibility window is < the feature length since we don't know if we have all exons - const isGFF = "gff" === this.config.format || "gff3" === this.config.format || "gtf" === this.config.format; - if (f.exons) { - for (let i = 0; i < f.exons.length; i++) { - const exon = f.exons[i]; - if (genomicLocation >= exon.start && genomicLocation <= exon.end) { - const exonNumber = isGFF ? - exon.number : - f.strand === "-" ? f.exons.length - i : i + 1; - if (exonNumber) { - data.push('
'); - data.push({name: "Exon Number", value: exonNumber}); - } - break - } - } - } - } - } - - return data - - } - - menuItemList() { - - const menuItems = []; - - if (this.render === renderSnp) { - menuItems.push('
'); - for (let colorScheme of ["function", "class"]) { - menuItems.push({ - object: $$1(createCheckbox$2('Color by ' + colorScheme, colorScheme === this.colorBy)), - click: () => { - this.colorBy = colorScheme; - this.trackView.repaintViews(); - } - }); - } - } - - menuItems.push('
'); - for (let displayMode of ["COLLAPSED", "SQUISHED", "EXPANDED"]) { - const lut = - { - "COLLAPSED": "Collapse", - "SQUISHED": "Squish", - "EXPANDED": "Expand" - }; - - menuItems.push( - { - object: $$1(createCheckbox$2(lut[displayMode], displayMode === this.displayMode)), - click: () => { - this.displayMode = displayMode; - this.config.displayMode = displayMode; - this.trackView.checkContentHeight(); - this.trackView.repaintViews(); - } - }); - } - - return menuItems - - }; - - - contextMenuItemList(clickState) { - - const features = this.clickedFeatures(clickState); - - if (undefined === features || 0 === features.length) { - return undefined - } - - if (features.length > 1) { - features.sort((a, b) => (b.end - b.start) - (a.end - a.start)); - } - const f = features[0]; // The shortest clicked feature - - if ((f.end - f.start) <= 1000000) { - const list = [{ - label: 'View feature sequence', - click: async () => { - let seq = await this.browser.genome.getSequence(f.chr, f.start, f.end); - if (!seq) { - seq = "Unknown sequence"; - } else if (f.strand === '-') { - seq = reverseComplementSequence(seq); - } - this.browser.alert.present(seq); - - } - }]; - - if (isSecureContext() && navigator.clipboard !== undefined) { - list.push( - { - label: 'Copy feature sequence', - click: async () => { - let seq = await this.browser.genome.getSequence(f.chr, f.start, f.end); - if (!seq) { - seq = "Unknown sequence"; - } else if (f.strand === '-') { - seq = reverseComplementSequence(seq); - } - try { - await navigator.clipboard.writeText(seq); - } catch (e) { - console.error(e); - this.browser.alert.present(`error copying sequence to clipboard ${e}`); - } - } - } - ); - } - list.push('
'); - return list - } else { - return undefined - } - } - - description() { - - // if('snp' === this.type) { - if (renderSnp === this.render) { - let desc = "" + this.name + '
'; - desc += 'Color By Function:
'; - desc += 'Red: Coding-Non-Synonymous, Splice Site
'; - desc += 'Green: Coding-Synonymous
'; - desc += 'Blue: Untranslated
'; - desc += 'Black: Intron, Locus, Unknown

'; - desc += 'Color By Class:
'; - desc += 'Red: Deletion
'; - desc += 'Green: MNP
'; - desc += 'Blue: Microsatellite, Named
'; - desc += 'Black: Indel, Insertion, SNP'; - desc += ""; - return desc - } else { - return super.description() - } - - }; - - /** - * Return color for feature. - * @param feature - * @returns {string} - */ - - getColorForFeature(feature) { - - let color; - if (this.altColor && "-" === feature.strand) { - color = (typeof this.altColor === "function") ? this.altColor(feature) : this.altColor; - } else if (this.color) { - color = (typeof this.color === "function") ? this.color(feature) : this.color; // Explicit setting via menu, or possibly track line if !config.color - } else if (this.colorBy) { - const value = feature.getAttributeValue ? - feature.getAttributeValue(this.colorBy) : - feature[this.colorBy]; - color = this.colorTable.getColor(value); - } else if (feature.color) { - color = feature.color; // Explicit color for feature - } - - // If no explicit setting use the default - if (!color) { - color = DEFAULT_COLOR$2; // Track default - } - - if (feature.alpha && feature.alpha !== 1) { - color = IGVColor.addAlpha(color, feature.alpha); - } else if (this.useScore && feature.score && !Number.isNaN(feature.score)) { - // UCSC useScore option, for scores between 0-1000. See https://genome.ucsc.edu/goldenPath/help/customTrack.html#TRACK - const min = this.config.min ? this.config.min : this.viewLimitMin ? this.viewLimitMin : 0; - const max = this.config.max ? this.config.max : this.viewLimitMax ? this.viewLimitMax : 1000; - const alpha = getAlpha(min, max, feature.score); - feature.alpha = alpha; // Avoid computing again - color = IGVColor.addAlpha(color, alpha); - } - - - function getAlpha(min, max, score) { - const binWidth = (max - min) / 9; - const binNumber = Math.floor((score - min) / binWidth); - return Math.min(1.0, 0.2 + (binNumber * 0.8) / 9) - } - - return color - } - - - /** - * Called when the track is removed. Do any needed cleanup here - */ - dispose() { - this.trackView = undefined; - } -} - -/** - * Monitors track drag events, updates label position to ensure that they're always visible. - * @param track - */ -function monitorTrackDrag(track) { - - if (track.browser.on) { - track.browser.on('trackdragend', onDragEnd); - track.browser.on('trackremoved', unSubscribe); - } - - function onDragEnd() { - if (track.trackView && track.displayMode !== "SQUISHED") { - track.trackView.updateViews(); // TODO -- refine this to the viewport that was dragged after DOM refactor - } - } - - function unSubscribe(removedTrack) { - if (track.browser.un && track === removedTrack) { - track.browser.un('trackdragend', onDragEnd); - track.browser.un('trackremoved', unSubscribe); - } - } - -} - -class RegionTableBase { - constructor(config) { - - this.config = config; - - this.browser = config.browser; - - this.columnFormat = config.columnFormat; - - this.tableRowSelectionList = []; - - this.tableDOM = domUtils$1.div({ class: 'igv-roi-table' }); - // if(config.width) { - // let [ w ] = config.width.split('px') - // w = parseInt(w, 10) - // this.tableDOM.style.width = `${Math.min(w, 1600)}px` - // - // } - - config.parent.appendChild(this.tableDOM); - - this.headerDOM = config; - - this.tableColumnTitles = this.tableDOM; - - this.tableRowContainer = this.tableDOM; - - this.footerDOM = config.gotoButtonHandler; - - } - - set headerDOM({ browser, parent, headerTitle, dismissHandler }) { - - // header - const dom = domUtils$1.div(); - this.tableDOM.appendChild(dom); - - // header title - const div = domUtils$1.div(); - dom.appendChild(div); - div.innerHTML = headerTitle; - - // table dismiss button - const dismiss = domUtils$1.div(); - dom.appendChild(dismiss); - dismiss.appendChild(icons$1$1.createIcon('times')); - - this.boundDismissHandler = mouseClickHandler.bind(this); - - dismiss.addEventListener('click', this.boundDismissHandler); - - function mouseClickHandler (event) { - event.stopPropagation(); - dismissHandler(); - } - - const { y:y_root } = browser.root.getBoundingClientRect(); - const { y:y_parent } = parent.getBoundingClientRect(); - const constraint = -(y_parent - y_root); - makeDraggable$1(this.tableDOM, dom, { minX:0, minY:constraint }); - - this.tableDOM.style.display = 'none'; - - this._headerDOM = dom; - - } - - set tableColumnTitles(tableDOM) { - - const tblColumnTitles = domUtils$1.div({ class: 'igv-roi-table-column-titles' }); - tableDOM.appendChild(tblColumnTitles); - - for (const { label, width } of this.columnFormat) { - const col = domUtils$1.div(); - tblColumnTitles.appendChild(col); - col.style.width = width; - col.innerText = label; - } - - this._tableColumnTitlesDOM = tblColumnTitles; - - } - - get tableColumnTitles() { - return this._tableColumnTitlesDOM - } - - set tableRowContainer(container) { - - const tblRowContainer = domUtils$1.div({ class: 'igv-roi-table-row-container' }); - container.appendChild(tblRowContainer); - - this._tableRowContainerDOM = tblRowContainer; - - } - - get tableRowContainer() { - return this._tableRowContainerDOM - } - - set footerDOM(gotoButtonHandler) { - - const dom = domUtils$1.div(); - this.tableDOM.appendChild(dom); - - // Go To Button - const gotoButton = domUtils$1.div({class: 'igv-roi-table-button'}); - dom.appendChild(gotoButton); - - gotoButton.id = 'igv-roi-table-view-button'; - gotoButton.textContent = 'Go To'; - gotoButton.style.pointerEvents = 'none'; - - this._footerDOM = dom; - - this.gotoButton = gotoButton; - - this.boundGotoButtonHandler = gotoButtonHandler.bind(this); - - this.gotoButton.addEventListener('click', this.boundGotoButtonHandler); - - } - - tableRowDOMHelper(dom) { - - dom.addEventListener('mousedown', event => { - event.stopPropagation(); - - dom.classList.toggle('igv-roi-table-row-selected'); - dom.classList.contains('igv-roi-table-row-selected') ? dom.classList.remove('igv-roi-table-row-hover') : dom.classList.add('igv-roi-table-row-hover'); - - this.setTableRowSelectionState(dom.classList.contains('igv-roi-table-row-selected')); - }); - - dom.addEventListener('mouseover', e => { - dom.classList.contains('igv-roi-table-row-selected') ? dom.classList.remove('igv-roi-table-row-hover') : dom.classList.add('igv-roi-table-row-hover'); - }); - - dom.addEventListener('mouseout', e => { - dom.classList.remove('igv-roi-table-row-hover'); - }); - - } - - clearTable() { - const elements = this.tableRowContainer.querySelectorAll('.igv-roi-table-row'); - for (let el of elements) { - el.remove(); - } - } - - setTableRowSelectionState(isTableRowSelected) { - isTableRowSelected ? this.tableRowSelectionList.push(1) : this.tableRowSelectionList.pop(); - this.gotoButton.style.pointerEvents = this.tableRowSelectionList.length > 0 ? 'auto' : 'none'; - } - - present() { - this.tableDOM.style.left = `${ 0 }px`; - - const { y:y_root } = this.browser.root.getBoundingClientRect(); - const { y:y_parent } = this.config.parent.getBoundingClientRect(); - - this.tableDOM.style.top = `${ y_root - y_parent }px`; - this.tableDOM.style.display = 'flex'; - } - - dismiss() { - this.tableDOM.style.display = 'none'; - } - - dispose() { - - this.tableDOM.innerHTML = ''; - this.tableDOM.remove(); - - for (const key of Object.keys(this)) { - this[key] = undefined; - } - - document.removeEventListener('click', this.boundDismissHandler); - - } - -} - -class BlatTable extends RegionTableBase { - - constructor(config) { - - const cooked = Object.assign({ 'width':'1024px' }, config); - super(cooked); - - this.descriptionDOM = config; - - } - - set descriptionDOM(config) { - - if (config.description) { - - let dom; - - // BLAT result for query sequence - dom = domUtils$1.div({ class: 'igv-roi-table-description' }); - this.tableDOM.insertBefore(dom, this.tableColumnTitles); - dom.style.height = 'auto'; - dom.innerHTML = `BLAT result for query sequence:`; - - // CTAATCAtctacactggtttctactg ... - dom = domUtils$1.div({ class: 'igv-roi-table-description' }); - this.tableDOM.insertBefore(dom, this.tableColumnTitles); - dom.style.height = 'auto'; - dom.style.maxHeight = '128px'; - dom.innerHTML = config.description; - - // Select one or more rows ... - dom = domUtils$1.div({ class: 'igv-roi-table-goto-explainer' }); - this.tableDOM.insertBefore(dom, this.tableColumnTitles); - dom.innerHTML = `Select one or more rows and click Go To to view the regions`; - - } - - } - - tableRowDOM(record) { - - const dom = domUtils$1.div({ class: 'igv-roi-table-row' }); - - const pretty = record.map(item => isFinite(item) ? numberFormatter$1(item) : item); - - for (let i = 0; i < pretty.length; i++) { - - const el = domUtils$1.div(); - dom.appendChild(el); - - const format = this.columnFormat[ i ]; - el.style.width = format.width || 'fit-content'; - el.innerText = pretty[ i ]; - } - - this.tableRowDOMHelper(dom); - - return dom - } - - renderTable(records) { - - Array.from(this.tableRowContainer.querySelectorAll('.igv-roi-table-row')).forEach(el => el.remove()); - - if (records.length > 0) { - - for (let record of records) { - const row = this.tableRowDOM(record); - this.tableRowContainer.appendChild(row); - } - - } - - } - - static getColumnFormatConfiguration() { - - /* - return [ - { label: 'chr', width: '60px' }, - { label: 'start', width: '100px' }, - { label: 'end', width: '100px' }, - { label: 'strand', width: '50px' }, - { label: 'score', width: '50px' }, - { label: 'match', width: '50px' }, - { label: "mis-match", width: '70px' }, - { label: "rep. match", width: '70px' }, - { label: "N's", width: '32px' }, - { label: 'Q gap count', width: '90px' }, - { label: 'Q gap bases', width: '90px' }, - { label: 'T gap count', width: '90px' }, - { label: 'T gap bases', width: '90px' }, - ] - */ - - return [ - { label: 'chr', width: '7%' }, - { label: 'start', width: '12%' }, - { label: 'end', width: '12%' }, - { label: 'strand', width: '5%' }, - { label: 'score', width: '5%' }, - { label: 'match', width: '5%' }, - { label: "mis-match", width: '7%' }, - { label: "rep. match", width: '7%' }, - { label: "N's", width: '3%' }, - { label: 'Q gap count', width: '9%' }, - { label: 'Q gap bases', width: '9%' }, - { label: 'T gap count', width: '9%' }, - { label: 'T gap bases', width: '9%' }, - ] - } - - static gotoButtonHandler (event) { - - event.stopPropagation(); - - const selectedRows = this.tableDOM.querySelectorAll('.igv-roi-table-row-selected'); - - const loci = []; - for (const row of selectedRows) { - - const record = []; - row.querySelectorAll('div').forEach(el => record.push(el.innerText)); - - const [ chr, start, end ] = record; - loci.push(`${ chr }:${ start }-${ end }`); - } - - for (const el of this.tableDOM.querySelectorAll('.igv-roi-table-row')) { - el.classList.remove('igv-roi-table-row-selected'); - } - - this.setTableRowSelectionState(false); - - this.browser.search(loci.join(' ')); - - // console.log(`browser search( ${loci.join(' ')} )`) - - } - -} - -/* -http://genome.ucsc.edu/cgi-bin/hgBlat -?userSeq=CTAATCAtctacactggtttctactgaaatgtctgttgtcatagacttaattgtgtcttcagatacagcagttctgttatttctgagttttacctggggcaagagaatctttagcaagtttaaaggcacctatatctggaatcacccctccctccagatgaatatcacagactctcccattaaaggtcttgccTTCCTTGATAGCATCATCACTCCA -&type=DNA -&db=hg38 -&output=json - */ - -//const blatServer = "https://genome.ucsc.edu/cgi-bin/hgBlat" -const defaultBlatServer = "https://igv.org/services/blatUCSC.php"; -//const blatServer = "http://localhost:8000/blatUCSC.php" - - -async function blat({url, userSeq, db}) { - - url = url || defaultBlatServer; - - const results = await postData(url, userSeq, db); - - results.fields; - - const features = results.blat.map(decodePSL); - - return features -} - -async function postData(url = "", userSeq, db) { - - const data = new URLSearchParams(); - data.append("userSeq", userSeq); - data.append("db", db); - - const response = await fetch(url, { method: "post", body: data }); - return response.json(); // parses JSON response into native JavaScript objects -} - -const maxSequenceSize = 25000; - -class BlatTrack extends FeatureTrack { - - constructor(config, browser) { - super(config, browser); - if (!this.name) { - this.name = 'Blat Results'; - } - this.sequence = config.sequence; - this.table = undefined; - } - - openTableView() { - - if (undefined === this.table) { - - const rows = this.config.features.map(f => [ - f.chr, - (f.start + 1), - f.end, - f.strand, - f.score, - f.matches, - f.misMatches, - f.repMatches, - f.nCount, - f.qNumInsert, - f.qBaseInsert, - f.tNumInsert, - f.tBaseInsert - ]); - - const config = - { - browser: this.browser, - parent: this.browser.parent, - headerTitle: this.config.title, - description: this.sequence, - dismissHandler: () => { - this.table.dismiss(); - this.table.dispose(); - this.table = undefined; - }, - columnFormat: BlatTable.getColumnFormatConfiguration(), - gotoButtonHandler: BlatTable.gotoButtonHandler - }; - - this.table = new BlatTable(config); - this.table.renderTable(rows); - } - - this.table.present(); - - } - - menuItemList() { - - const menuItems = super.menuItemList(); - - menuItems.push('
'); - menuItems.push({ - label: 'Open table view', - click: () => this.openTableView() - }); - return menuItems - } - - - /** - * Track has been permanently removed. Release resources and other cleanup - */ - dispose() { - super.dispose(); - // Release DOM element for table - if (this.table) { - this.table.popover.parentElement.removeChild(this.table.popover); - - } - - - } -} - - -async function createBlatTrack({sequence, browser, name, title}) { - - if (sequence.length > maxSequenceSize) { - browser.alert.present(`Sequence size exceeds maximum allowed length (${sequence.length} > ${maxSequenceSize})`); - return - } - - const db = browser.genome.id; // TODO -- blat specific property - - const url = browser.config["blatServerURL"]; - - try { - - const features = await blat({url, userSeq: sequence, db}); - const trackConfig = { - type: 'blat', - name: name || 'blat results', - title: title || 'blat results', - sequence: sequence, - altColor: 'rgb(176, 176, 236)', - color: 'rgb(236, 176, 176)', - features: features - }; - - const track = await browser.loadTrack(trackConfig); - track.openTableView(); - - } catch (e) { - browser.alert.present(`Error performing blat search: ${e}`); - } - -} - -/* - * The MIT License (MIT) - * - * Copyright (c) 2014 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -const alignmentStartGap = 5; -const downsampleRowHeight = 5; -const DEFAULT_ALIGNMENT_COLOR = "rgb(185, 185, 185)"; -const DEFAULT_COVERAGE_COLOR = "rgb(150, 150, 150)"; -const DEFAULT_CONNECTOR_COLOR = "rgb(200, 200, 200)"; -const MINIMUM_BLAT_LENGTH = 20; - -class BAMTrack extends TrackBase { - - static defaults = { - alleleFreqThreshold: 0.2, - visibilityWindow: 30000, - showCoverage: true, - showAlignments: true, - viewAsPairs: false, - pairsSupported: true, - showSoftClips: false, - showAllBases: false, - showInsertions: true, - showMismatches: true, - height: 300, - coverageTrackHeight: 50 - } - - constructor(config, browser) { - super(config, browser); - } - - init(config) { - - this.type = "alignment"; - this.featureSource = new BamSource(config, this.browser); - this.coverageTrack = new CoverageTrack(config, this); - this.alignmentTrack = new AlignmentTrack(config, this); - - super.init(config); - - this.alignmentTrack.setTop(this.coverageTrack, this.showCoverage); - - if(!this.showAlignments) { - this._height = this.coverageTrackHeight; - } - - // The sort object can be an array in the case of multi-locus view, however if multiple sort positions - // are present for a given reference frame the last one will take precedence - if (config.sort) { - if (Array.isArray(config.sort)) { - // Legacy support - this.assignSort(config.sort[0]); - } else { - this.assignSort(config.sort); - } - } - - } - - set height(h) { - this._height = h; - if (this.showAlignments) { - this.alignmentTrack.height = this.showCoverage ? h - this.coverageTrackHeight : h; - } - } - - get height() { - return this._height - } - - get minTemplateLength() { - const configMinTLEN = this.config.minTLEN !== undefined ? this.config.minTLEN : this.config.minFragmentLength; - return (configMinTLEN !== undefined) ? configMinTLEN : - this._pairedEndStats ? this._pairedEndStats.minTLEN : 0 - } - - get maxTemplateLength() { - const configMaxTLEN = this.config.maxTLEN !== undefined ? this.config.maxTLEN : this.config.maxFragmentLength; - return (configMaxTLEN !== undefined) ? configMaxTLEN : - this._pairedEndStats ? this._pairedEndStats.maxTLEN : 1000 - } - - sort(options) { - options = this.assignSort(options); - - for (let vp of this.trackView.viewports) { - if (vp.containsPosition(options.chr, options.position)) { - const alignmentContainer = vp.cachedFeatures; - if (alignmentContainer) { - alignmentContainer.sortRows(options); - vp.repaint(); - } - } - } - } - - /** - * Fix syntax problems for sort options. - * @param options - */ - assignSort(options) { - // convert old syntax - if (options.locus) { - const range = parseLocusString$1(options.locus); - options.chr = range.chr; - options.position = range.start; - } else { - options.position--; - } - options.direction = options.direction === "ASC" || options.direction === true; - - // chr aliasing - options.chr = this.browser.genome.getChromosomeName(options.chr); - this.sortObject = options; - - return this.sortObject - } - - async getFeatures(chr, bpStart, bpEnd, bpPerPixel, viewport) { - - const alignmentContainer = await this.featureSource.getAlignments(chr, bpStart, bpEnd); - - if (alignmentContainer.paired && !this._pairedEndStats && !this.config.maxFragmentLength) { - const pairedEndStats = new PairedEndStats(alignmentContainer.alignments, this.config); - if (pairedEndStats.totalCount > 99) { - this._pairedEndStats = pairedEndStats; - } - } - alignmentContainer.alignments = undefined; // Don't need to hold onto these anymore - - const sort = this.sortObject; - if (sort) { - if (sort.chr === chr && sort.position >= bpStart && sort.position <= bpEnd) { - alignmentContainer.sortRows(sort); - } - } - - return alignmentContainer - } - - - /** - * Compute the pixel height required to display all content. This is not the same as the viewport height - * (track.height) which might include a scrollbar. - * - * @param alignmentContainer - * @returns {number} - */ - computePixelHeight(alignmentContainer) { - return (this.showCoverage ? this.coverageTrackHeight : 0) + - (this.showAlignments ? this.alignmentTrack.computePixelHeight(alignmentContainer) : 0) - } - - draw(options) { - - IGVGraphics.fillRect(options.context, 0, options.pixelTop, options.pixelWidth, options.pixelHeight, {'fillStyle': "rgb(255, 255, 255)"}); - - if (true === this.showCoverage && this.coverageTrackHeight > 0) { - this.trackView.axisCanvas.style.display = 'block'; - this.coverageTrack.draw(options); - } else { - this.trackView.axisCanvas.style.display = 'none'; - } - - if (true === this.showAlignments) { - this.alignmentTrack.setTop(this.coverageTrack, this.showCoverage); - this.alignmentTrack.draw(options); - } - } - - paintAxis(ctx, pixelWidth, pixelHeight) { - - this.coverageTrack.paintAxis(ctx, pixelWidth, this.coverageTrackHeight); - - // if (this.browser.isMultiLocusMode()) { - // ctx.clearRect(0, 0, pixelWidth, pixelHeight); - // } else { - // this.coverageTrack.paintAxis(ctx, pixelWidth, this.coverageTrackHeight); - // } - } - - contextMenuItemList(config) { - return this.alignmentTrack.contextMenuItemList(config) - } - - popupData(clickState) { - if (true === this.showCoverage && clickState.y >= this.coverageTrack.top && clickState.y < this.coverageTrackHeight) { - return this.coverageTrack.popupData(clickState) - } else { - return this.alignmentTrack.popupData(clickState) - } - } - - /** - * Return the features (alignment, coverage, downsampled interval) clicked on. Needed for "onclick" event. - * @param clickState - * @param features - */ - clickedFeatures(clickState) { - - let clickedObject; - if (true === this.showCoverage && clickState.y >= this.coverageTrack.top && clickState.y < this.coverageTrackHeight) { - clickedObject = this.coverageTrack.getClickedObject(clickState); - } else { - clickedObject = this.alignmentTrack.getClickedObject(clickState); - } - return clickedObject ? [clickedObject] : undefined - } - - hoverText(clickState) { - if (true === this.showCoverage && clickState.y >= this.coverageTrack.top && clickState.y < this.coverageTrackHeight) { - const clickedObject = this.coverageTrack.getClickedObject(clickState); - if (clickedObject) { - return clickedObject.hoverText() - } - } - - } - - menuItemList() { - - - // Start with overage track items - let menuItems = []; - - menuItems = menuItems.concat(MenuUtils$1.numericDataMenuItems(this.trackView)); - - // Color by items - menuItems.push('
'); - const $e = $$1('
'); - $e.text('Color by:'); - menuItems.push({name: undefined, object: $e, click: undefined, init: undefined}); - - const colorByMenuItems = [{key: 'strand', label: 'read strand'}]; - if (this.alignmentTrack.hasPairs) { - colorByMenuItems.push({key: 'firstOfPairStrand', label: 'first-of-pair strand'}); - colorByMenuItems.push({key: 'pairOrientation', label: 'pair orientation'}); - colorByMenuItems.push({key: 'tlen', label: 'insert size (TLEN)'}); - colorByMenuItems.push({key: 'unexpectedPair', label: 'pair orientation & insert size (TLEN)'}); - } - const tagLabel = 'tag' + (this.alignmentTrack.colorByTag ? ' (' + this.alignmentTrack.colorByTag + ')' : ''); - colorByMenuItems.push({key: 'tag', label: tagLabel}); - for (let item of colorByMenuItems) { - const selected = (this.alignmentTrack.colorBy === item.key); - menuItems.push(this.colorByCB(item, selected)); - } - - // Show coverage / alignment options - const adjustTrackHeight = () => { - if (!this.autoHeight) { - const h = - (this.showCoverage ? this.coverageTrackHeight : 0) + - (this.showAlignments ? this.alignmentTrack.height : 0); - this.trackView.setTrackHeight(h); - } - }; - - menuItems.push('
'); - menuItems.push({ - object: $$1(createCheckbox$2("Show Coverage", this.showCoverage)), - click: () => { - this.showCoverage = !this.showCoverage; - adjustTrackHeight(); - this.trackView.checkContentHeight(); - this.trackView.repaintViews(); - } - }); - menuItems.push({ - object: $$1(createCheckbox$2("Show Alignments", this.showAlignments)), - click: () => { - this.showAlignments = !this.showAlignments; - adjustTrackHeight(); - this.trackView.checkContentHeight(); - this.trackView.repaintViews(); - } - }); - - // Show all bases - menuItems.push('
'); - menuItems.push({ - object: $$1(createCheckbox$2("Show all bases", this.showAllBases)), - click: () => { - this.showAllBases = !this.showAllBases; - this.config.showAllBases = this.showAllBases; - this.trackView.repaintViews(); - } - }); - - // Show mismatches - menuItems.push('
'); - menuItems.push({ - object: $$1(createCheckbox$2("Show mismatches", this.showMismatches)), - click: () => { - this.showMismatches = !this.showMismatches; - this.config.showMismatches = this.showMismatches; - this.trackView.repaintViews(); - } - }); - - // Insertions - menuItems.push({ - object: $$1(createCheckbox$2("Show insertions", this.showInsertions)), - click: () => { - this.showInsertions = !this.showInsertions; - this.config.showInsertions = this.showInsertions; - this.getCachedAlignmentContainers(); - this.trackView.repaintViews(); - } - }); - - // Soft clips - menuItems.push({ - object: $$1(createCheckbox$2("Show soft clips", this.showSoftClips)), - click: () => { - this.showSoftClips = !this.showSoftClips; - this.config.showSoftClips = this.showSoftClips; - this.featureSource.setShowSoftClips(this.showSoftClips); - const alignmentContainers = this.getCachedAlignmentContainers(); - for (let ac of alignmentContainers) { - ac.setShowSoftClips(this.showSoftClips); - } - this.trackView.repaintViews(); - } - }); - - // View as pairs - if (this.pairsSupported && this.alignmentTrack.hasPairs) { - menuItems.push('
'); - menuItems.push({ - object: $$1(createCheckbox$2("View as pairs", this.viewAsPairs)), - click: () => { - this.viewAsPairs = !this.viewAsPairs; - this.config.viewAsPairs = this.viewAsPairs; - this.featureSource.setViewAsPairs(this.viewAsPairs); - const alignmentContainers = this.getCachedAlignmentContainers(); - for (let ac of alignmentContainers) { - ac.setViewAsPairs(this.viewAsPairs); - } - this.trackView.repaintViews(); - } - }); - } - - // Add chords to JBrowse circular view, if present - if (this.browser.circularView && - (this.alignmentTrack.hasPairs || this.alignmentTrack.hasSupplemental)) { - menuItems.push('
'); - if (this.alignmentTrack.hasPairs) { - menuItems.push({ - label: 'Add discordant pairs to circular view', - click: () => { - for (let viewport of this.trackView.viewports) { - this.addPairedChordsForViewport(viewport); - } - } - }); - } - if (this.alignmentTrack.hasSupplemental) { - menuItems.push({ - label: 'Add split reads to circular view', - click: () => { - for (let viewport of this.trackView.viewports) { - this.addSplitChordsForViewport(viewport); - } - } - }); - } - } - - - // Display mode - menuItems.push('
'); - const $dml = $$1('
'); - $dml.text('Display mode:'); - menuItems.push({name: undefined, object: $dml, click: undefined, init: undefined}); - - menuItems.push({ - object: $$1(createCheckbox$2("expand", this.alignmentTrack.displayMode === "EXPANDED")), - click: () => { - this.alignmentTrack.displayMode = "EXPANDED"; - this.config.displayMode = "EXPANDED"; - this.trackView.checkContentHeight(); - this.trackView.repaintViews(); - } - }); - - menuItems.push({ - object: $$1(createCheckbox$2("squish", this.alignmentTrack.displayMode === "SQUISHED")), - click: () => { - this.alignmentTrack.displayMode = "SQUISHED"; - this.config.displayMode = "SQUISHED"; - this.trackView.checkContentHeight(); - this.trackView.repaintViews(); - } - }); - - return menuItems - } - - - /** - * Create a "color by" checkbox menu item, optionally initially checked - * @param menuItem - * @param showCheck - * @returns {{init: undefined, name: undefined, click: clickHandler, object: (jQuery|HTMLElement|jQuery.fn.init)}} - */ - colorByCB(menuItem, showCheck) { - const $e = $$1(createCheckbox$2(menuItem.label, showCheck)); - const clickHandler = (ev) => { - - if (menuItem.key !== 'tag') { - if (menuItem.key === this.alignmentTrack.colorBy) { - this.alignmentTrack.colorBy = 'none'; - this.config.colorBy = 'none'; - this.trackView.repaintViews(); - } else { - this.alignmentTrack.colorBy = menuItem.key; - this.config.colorBy = menuItem.key; - this.trackView.repaintViews(); - } - } else { - this.browser.inputDialog.present({ - label: 'Tag Name', - value: this.alignmentTrack.colorByTag ? this.alignmentTrack.colorByTag : '', - callback: (tag) => { - if (tag) { - this.alignmentTrack.colorBy = 'tag'; - this.alignmentTrack.colorByTag = tag; - if (!this.alignmentTrack.tagColors) { - this.alignmentTrack.tagColors = new PaletteColorTable("Set1"); - } - } else { - this.alignmentTrack.colorBy = 'none'; - this.alignmentTrack.colorByTag = ''; - } - this.trackView.repaintViews(); - } - }, ev); - - } - - }; - - return {name: undefined, object: $e, click: clickHandler, init: undefined} - } - - /** - * Return the current state of the track. Used to create sessions and bookmarks. - * - * @returns {*|{}} - */ - getState() { - - const config = super.getState(); - - if (this.sortObject) { - config.sort = { - chr: this.sortObject.chr, - position: this.sortObject.position + 1, - option: this.sortObject.option, - direction: this.sortObject.direction ? "ASC" : "DESC" - }; - } - - return config - } - - getCachedAlignmentContainers() { - return this.trackView.viewports.map(vp => vp.cachedFeatures) - } - - get dataRange() { - return this.coverageTrack.dataRange - } - - set dataRange(dataRange) { - this.coverageTrack.dataRange = dataRange; - } - - get logScale() { - return this.coverageTrack.logScale - } - - set logScale(logScale) { - this.coverageTrack.logScale = logScale; - } - - get autoscale() { - return this.coverageTrack.autoscale - } - - set autoscale(autoscale) { - this.coverageTrack.autoscale = autoscale; - } - - /** - * Add chords to the circular view for the given viewport, represented by its reference frame - * @param refFrame - */ - addPairedChordsForViewport(viewport) { - - const maxTemplateLength = this.maxTemplateLength; - const inView = []; - const refFrame = viewport.referenceFrame; - for (let a of viewport.cachedFeatures.allAlignments()) { - if (a.end >= refFrame.start - && a.start <= refFrame.end) { - if (a.paired) { - if (a.end - a.start > maxTemplateLength) { - inView.push(a); - } - } else { - if (a.mate - && a.mate.chr - && (a.mate.chr !== a.chr || Math.max(a.fragmentLength) > maxTemplateLength)) { - inView.push(a); - } - } - } - } - const chords = makePairedAlignmentChords(inView); - sendChords(chords, this, refFrame, 0.02); - } - - addSplitChordsForViewport(viewport) { - - const inView = []; - const refFrame = viewport.referenceFrame; - for (let a of viewport.cachedFeatures.allAlignments()) { - - const sa = a.hasTag('SA'); - if (a.end >= refFrame.start && a.start <= refFrame.end && sa) { - inView.push(a); - } - } - - const chords = makeSupplementalAlignmentChords(inView); - sendChords(chords, this, refFrame, 0.02); - } -} - - -class CoverageTrack { - - constructor(config, parent) { - this.parent = parent; - this.featureSource = parent.featureSource; - - this.paintAxis = paintAxis; - this.top = 0; - - this.autoscale = config.autoscale || config.max === undefined; - if (!this.autoscale) { - this.dataRange = { - min: config.min || 0, - max: config.max - }; - } - - } - - get height() { - return this.parent.coverageTrackHeight - } - - draw(options) { - - const pixelTop = options.pixelTop; - pixelTop + options.pixelHeight; - const nucleotideColors = this.parent.browser.nucleotideColors; - - if (pixelTop > this.height) { - return //scrolled out of view - } - - const ctx = options.context; - const alignmentContainer = options.features; - const coverageMap = alignmentContainer.coverageMap; - - let sequence; - if (coverageMap.refSeq) { - sequence = coverageMap.refSeq.toUpperCase(); - } - - const bpPerPixel = options.bpPerPixel; - const bpStart = options.bpStart; - const pixelWidth = options.pixelWidth; - const bpEnd = bpStart + pixelWidth * bpPerPixel + 1; - - // paint for all coverage buckets - // If alignment track color is != default, use it - let color; - if (this.parent.coverageColor) { - color = this.parent.coverageColor; - } else if (this.parent.color && typeof this.parent.color !== "function") { - color = IGVColor.darkenLighten(this.parent.color, -35); - } else { - color = DEFAULT_COVERAGE_COLOR; - } - IGVGraphics.setProperties(ctx, { - fillStyle: color, - strokeStyle: color - }); - - const w = Math.max(1, Math.ceil(1.0 / bpPerPixel)); - for (let i = 0, len = coverageMap.coverage.length; i < len; i++) { - - const bp = (coverageMap.bpStart + i); - if (bp < bpStart) continue - if (bp > bpEnd) break - - const item = coverageMap.coverage[i]; - if (!item) continue - - const h = Math.round((item.total / this.dataRange.max) * this.height); - const y = this.height - h; - const x = Math.floor((bp - bpStart) / bpPerPixel); - - - // IGVGraphics.setProperties(ctx, {fillStyle: "rgba(0, 200, 0, 0.25)", strokeStyle: "rgba(0, 200, 0, 0.25)" }); - IGVGraphics.fillRect(ctx, x, y, w, h); - } - - // coverage mismatch coloring -- don't try to do this in above loop, color bar will be overwritten when w<1 - if (sequence) { - for (let i = 0, len = coverageMap.coverage.length; i < len; i++) { - - const bp = (coverageMap.bpStart + i); - if (bp < bpStart) continue - if (bp > bpEnd) break - - const item = coverageMap.coverage[i]; - if (!item) continue - - const h = (item.total / this.dataRange.max) * this.height; - let y = this.height - h; - const x = Math.floor((bp - bpStart) / bpPerPixel); - - const refBase = sequence[i]; - if (item.isMismatch(refBase)) { - IGVGraphics.setProperties(ctx, {fillStyle: nucleotideColors[refBase]}); - IGVGraphics.fillRect(ctx, x, y, w, h); - - let accumulatedHeight = 0.0; - for (let nucleotide of ["A", "C", "T", "G"]) { - - const count = item["pos" + nucleotide] + item["neg" + nucleotide]; - - // non-logoritmic - const hh = (count / this.dataRange.max) * this.height; - y = (this.height - hh) - accumulatedHeight; - accumulatedHeight += hh; - IGVGraphics.setProperties(ctx, {fillStyle: nucleotideColors[nucleotide]}); - IGVGraphics.fillRect(ctx, x, y, w, hh); - } - } - } - } - } - - getClickedObject(clickState) { - - let features = clickState.viewport.cachedFeatures; - if (!features || features.length === 0) return - - const genomicLocation = Math.floor(clickState.genomicLocation); - const coverageMap = features.coverageMap; - const coverageMapIndex = Math.floor(genomicLocation - coverageMap.bpStart); - return coverageMap.coverage[coverageMapIndex] - } - - popupData(clickState) { - - const nameValues = []; - - const coverage = this.getClickedObject(clickState); - if (coverage) { - const genomicLocation = Math.floor(clickState.genomicLocation); - const referenceFrame = clickState.viewport.referenceFrame; - - nameValues.push(referenceFrame.chr + ":" + numberFormatter$1(1 + genomicLocation)); - - nameValues.push({name: 'Total Count', value: coverage.total}); - - // A - let tmp = coverage.posA + coverage.negA; - if (tmp > 0) tmp = tmp.toString() + " (" + Math.round((tmp / coverage.total) * 100.0) + "%, " + coverage.posA + "+, " + coverage.negA + "- )"; - nameValues.push({name: 'A', value: tmp}); - - // C - tmp = coverage.posC + coverage.negC; - if (tmp > 0) tmp = tmp.toString() + " (" + Math.round((tmp / coverage.total) * 100.0) + "%, " + coverage.posC + "+, " + coverage.negC + "- )"; - nameValues.push({name: 'C', value: tmp}); - - // G - tmp = coverage.posG + coverage.negG; - if (tmp > 0) tmp = tmp.toString() + " (" + Math.round((tmp / coverage.total) * 100.0) + "%, " + coverage.posG + "+, " + coverage.negG + "- )"; - nameValues.push({name: 'G', value: tmp}); - - // T - tmp = coverage.posT + coverage.negT; - if (tmp > 0) tmp = tmp.toString() + " (" + Math.round((tmp / coverage.total) * 100.0) + "%, " + coverage.posT + "+, " + coverage.negT + "- )"; - nameValues.push({name: 'T', value: tmp}); - - // N - tmp = coverage.posN + coverage.negN; - if (tmp > 0) tmp = tmp.toString() + " (" + Math.round((tmp / coverage.total) * 100.0) + "%, " + coverage.posN + "+, " + coverage.negN + "- )"; - nameValues.push({name: 'N', value: tmp}); - - nameValues.push('
'); - nameValues.push({name: 'DEL', value: coverage.del.toString()}); - nameValues.push({name: 'INS', value: coverage.ins.toString()}); - } - - return nameValues - - } - -} - -class AlignmentTrack { - - constructor(config, parent) { - - this.parent = parent; - this.browser = parent.browser; - this.featureSource = parent.featureSource; - this.top = 0 === config.coverageTrackHeight ? 0 : config.coverageTrackHeight + 5; - this.displayMode = config.displayMode || "EXPANDED"; - this.alignmentRowHeight = config.alignmentRowHeight || 14; - this.squishedRowHeight = config.squishedRowHeight || 3; - - this.negStrandColor = config.negStrandColor || "rgba(150, 150, 230, 0.75)"; - this.posStrandColor = config.posStrandColor || "rgba(230, 150, 150, 0.75)"; - this.insertionColor = config.insertionColor || "rgb(138, 94, 161)"; - this.insertionTextColor = config.insertionTextColor || "white"; - this.showInsertionText = config.showInsertionText === undefined ? false : !!config.showInsertionText; - this.deletionColor = config.deletionColor || "black"; - this.deletionTextColor = config.deletionTextColor || "black"; - this.showDeletionText = config.showDeletionText === undefined ? false : !!config.showDeletionText; - this.skippedColor = config.skippedColor || "rgb(150, 170, 170)"; - this.pairConnectorColor = config.pairConnectorColor; - - this.smallTLENColor = config.smallTLENColor || config.smallFragmentLengthColor || "rgb(0, 0, 150)"; - this.largeTLENColor = config.largeTLENColor || config.largeFragmentLengthColor || "rgb(200, 0, 0)"; - - this.pairOrientation = config.pairOrienation || 'fr'; - this.pairColors = {}; - this.pairColors["RL"] = config.rlColor || "rgb(0, 150, 0)"; - this.pairColors["RR"] = config.rrColor || "rgb(20, 50, 200)"; - this.pairColors["LL"] = config.llColor || "rgb(0, 150, 150)"; - - this.colorBy = config.colorBy || "unexpectedPair"; - this.colorByTag = config.colorByTag ? config.colorByTag.toUpperCase() : undefined; - this.bamColorTag = config.bamColorTag === undefined ? "YC" : config.bamColorTag; - - this.hideSmallIndels = config.hideSmallIndels; - this.indelSizeThreshold = config.indelSizeThreshold || 1; - - this.hasPairs = false; // Until proven otherwise - this.hasSupplemental = false; - } - - setTop(coverageTrack, showCoverage) { - this.top = (0 === coverageTrack.height || false === showCoverage) ? 0 : (5 + coverageTrack.height); - } - - /** - * Compute the pixel height required to display all content. - * - * @param alignmentContainer - * @returns {number|*} - */ - computePixelHeight(alignmentContainer) { - - if (alignmentContainer.packedAlignmentRows) { - const h = alignmentContainer.hasDownsampledIntervals() ? downsampleRowHeight + alignmentStartGap : 0; - const alignmentRowHeight = this.displayMode === "SQUISHED" ? - this.squishedRowHeight : - this.alignmentRowHeight; - return h + (alignmentRowHeight * alignmentContainer.packedAlignmentRows.length) + 5 - } else { - return 0 - } - } - - draw(options) { - - const alignmentContainer = options.features; - const ctx = options.context; - const bpPerPixel = options.bpPerPixel; - const bpStart = options.bpStart; - const pixelWidth = options.pixelWidth; - const bpEnd = bpStart + pixelWidth * bpPerPixel + 1; - const showSoftClips = this.parent.showSoftClips; - const showAllBases = this.parent.showAllBases; - const nucleotideColors = this.browser.nucleotideColors; - - //alignmentContainer.repack(bpPerPixel, showSoftClips); - const packedAlignmentRows = alignmentContainer.packedAlignmentRows; - - - ctx.save(); - - let referenceSequence = alignmentContainer.sequence; - if (referenceSequence) { - referenceSequence = referenceSequence.toUpperCase(); - } - let alignmentRowYInset = 0; - - let pixelTop = options.pixelTop; - if (this.top) { - ctx.translate(0, this.top); - } - const pixelBottom = pixelTop + options.pixelHeight; - - if (alignmentContainer.hasDownsampledIntervals()) { - alignmentRowYInset = downsampleRowHeight + alignmentStartGap; - - alignmentContainer.downsampledIntervals.forEach(function (interval) { - var xBlockStart = (interval.start - bpStart) / bpPerPixel, - xBlockEnd = (interval.end - bpStart) / bpPerPixel; - - if (xBlockEnd - xBlockStart > 5) { - xBlockStart += 1; - xBlockEnd -= 1; - } - IGVGraphics.fillRect(ctx, xBlockStart, 2, (xBlockEnd - xBlockStart), downsampleRowHeight - 2, {fillStyle: "black"}); - }); - - } else { - alignmentRowYInset = 0; - } - - // Transient variable -- rewritten on every draw, used for click object selection - this.alignmentsYOffset = alignmentRowYInset; - const alignmentRowHeight = this.displayMode === "SQUISHED" ? - this.squishedRowHeight : - this.alignmentRowHeight; - - if (packedAlignmentRows) { - - const nRows = packedAlignmentRows.length; - - for (let rowIndex = 0; rowIndex < nRows; rowIndex++) { - - const alignmentRow = packedAlignmentRows[rowIndex]; - const alignmentY = alignmentRowYInset + (alignmentRowHeight * rowIndex); - const alignmentHeight = alignmentRowHeight <= 4 ? alignmentRowHeight : alignmentRowHeight - 2; - - if (alignmentY > pixelBottom) { - break - } else if (alignmentY + alignmentHeight < pixelTop) { - continue - } - - for (let alignment of alignmentRow.alignments) { - - this.hasPairs = this.hasPairs || alignment.isPaired(); - if (this.browser.circularView) { - // This is an expensive check, only do it if needed - this.hasSupplemental = this.hasSupplemental || alignment.hasTag('SA'); - } - - if ((alignment.start + alignment.lengthOnRef) < bpStart) continue - if (alignment.start > bpEnd) break - if (true === alignment.hidden) { - continue - } - - if (alignment instanceof PairedAlignment) { - - drawPairConnector.call(this, alignment, alignmentY, alignmentHeight); - - drawSingleAlignment.call(this, alignment.firstAlignment, alignmentY, alignmentHeight); - - if (alignment.secondAlignment) { - drawSingleAlignment.call(this, alignment.secondAlignment, alignmentY, alignmentHeight); - } - - } else { - drawSingleAlignment.call(this, alignment, alignmentY, alignmentHeight); - } - - } - } - } - ctx.restore(); - - // alignment is a PairedAlignment - function drawPairConnector(alignment, yRect, alignmentHeight) { - - var connectorColor = this.getConnectorColor(alignment.firstAlignment), - xBlockStart = (alignment.connectingStart - bpStart) / bpPerPixel, - xBlockEnd = (alignment.connectingEnd - bpStart) / bpPerPixel, - yStrokedLine = yRect + alignmentHeight / 2; - - if ((alignment.connectingEnd) < bpStart || alignment.connectingStart > bpEnd) { - return - } - if (alignment.mq <= 0) { - connectorColor = IGVColor.addAlpha(connectorColor, 0.15); - } - IGVGraphics.setProperties(ctx, {fillStyle: connectorColor, strokeStyle: connectorColor}); - IGVGraphics.strokeLine(ctx, xBlockStart, yStrokedLine, xBlockEnd, yStrokedLine); - - } - - function drawSingleAlignment(alignment, yRect, alignmentHeight) { - - - if ((alignment.start + alignment.lengthOnRef) < bpStart || alignment.start > bpEnd) { - return - } - - const blocks = showSoftClips ? alignment.blocks : alignment.blocks.filter(b => 'S' !== b.type); - - let alignmentColor = this.getAlignmentColor(alignment); - const outlineColor = alignmentColor; - if (alignment.mq <= 0) { - alignmentColor = IGVColor.addAlpha(alignmentColor, 0.15); - } - IGVGraphics.setProperties(ctx, {fillStyle: alignmentColor, strokeStyle: outlineColor}); - - // Save bases to draw into an array for later drawing, so they can be overlaid on insertion blocks, - // which is relevant if we have insertions with size label - const basesToDraw = []; - - for (let b = 0; b < blocks.length; b++) { // Can't use forEach here -- we need ability to break - - const block = blocks[b]; - - // Somewhat complex test, neccessary to insure gaps are drawn. - // If this is not the last block, and the next block starts before the orign (off screen to left) then skip. - if ((b !== blocks.length - 1) && blocks[b + 1].start < bpStart) continue - - // drawBlock returns bases to draw, which are drawn on top of insertion blocks (if they're wider than - // the space between two bases) like in Java IGV - basesToDraw.push(...drawBlock.call(this, block, b)); - - if ((block.start + block.len) > bpEnd) { - // Do this after drawBlock to insure gaps are drawn - break - } - } - - if (alignment.gaps) { - const yStrokedLine = yRect + alignmentHeight / 2; - for (let gap of alignment.gaps) { - const sPixel = (gap.start - bpStart) / bpPerPixel; - const ePixel = ((gap.start + gap.len) - bpStart) / bpPerPixel; - const lineWidth = ePixel - sPixel; - const gapLenText = gap.len.toString(); - const gapTextWidth = gapLenText.length * 6; - const gapCenter = sPixel + (lineWidth / 2); - - const color = ("D" === gap.type) ? this.deletionColor : this.skippedColor; - - IGVGraphics.strokeLine(ctx, sPixel, yStrokedLine, ePixel, yStrokedLine, { - strokeStyle: color, - lineWidth: 2, - }); - - // Add gap width as text like Java IGV if it fits nicely and is a multi-base gap - if (this.showDeletionText && gap.len > 1 && lineWidth >= gapTextWidth + 8) { - const textStart = gapCenter - (gapTextWidth / 2); - IGVGraphics.fillRect(ctx, textStart - 1, yRect - 1, gapTextWidth + 2, 12, {fillStyle: "white"}); - IGVGraphics.fillText(ctx, gapLenText, textStart, yRect + 10, { - 'font': 'normal 10px monospace', - 'fillStyle': this.deletionTextColor, - }); - } - } - } - - if (alignment.insertions && this.parent.showInsertions) { - let lastXBlockStart = -1; - for (let insertionBlock of alignment.insertions) { - if (this.hideSmallIndels && insertionBlock.len <= this.indelSizeThreshold) { - continue - } - if (insertionBlock.start < bpStart) { - continue - } - if (insertionBlock.start > bpEnd) { - break - } - - const refOffset = insertionBlock.start - bpStart; - const insertLenText = insertionBlock.len.toString(); - - const textPixelWidth = 2 + (insertLenText.length * 6); - const basePixelWidth = (!this.showInsertionText || insertionBlock.len === 1) - ? 2 - : Math.round(insertionBlock.len / bpPerPixel); - const widthBlock = Math.max(Math.min(textPixelWidth, basePixelWidth), 2); - - const xBlockStart = (refOffset / bpPerPixel) - (widthBlock / 2); - if ((xBlockStart - lastXBlockStart) > 2) { - const props = {fillStyle: this.insertionColor}; - - // Draw decorations like Java IGV to make an 'I' shape - IGVGraphics.fillRect(ctx, xBlockStart - 2, yRect, widthBlock + 4, 2, props); - IGVGraphics.fillRect(ctx, xBlockStart, yRect + 2, widthBlock, alignmentHeight - 4, props); - IGVGraphics.fillRect(ctx, xBlockStart - 2, yRect + alignmentHeight - 2, widthBlock + 4, 2, props); - - // Show # of inserted bases as text if it's a multi-base insertion and the insertion block - // is wide enough to hold text (its size is capped at the text label size, but can be smaller - // if the browser is zoomed out and the insertion is small) - if (this.showInsertionText && insertionBlock.len > 1 && basePixelWidth > textPixelWidth) { - IGVGraphics.fillText(ctx, insertLenText, xBlockStart + 1, yRect + 10, { - 'font': 'normal 10px monospace', - 'fillStyle': this.insertionTextColor, - }); - } - lastXBlockStart = xBlockStart; - } - } - } - - basesToDraw.forEach(({bbox, baseColor, readChar}) => { - renderBlockOrReadChar(ctx, bpPerPixel, bbox, baseColor, readChar); - }); - - - function drawBlock(block, b) { - // Collect bases to draw for later rendering - const blockBasesToDraw = []; - - const offsetBP = block.start - alignmentContainer.start; - const blockStartPixel = (block.start - bpStart) / bpPerPixel; - const blockEndPixel = ((block.start + block.len) - bpStart) / bpPerPixel; - const blockWidthPixel = Math.max(1, blockEndPixel - blockStartPixel); - - //const arrowHeadWidthPixel = alignmentRowHeight / 2.0; - const nomPixelWidthOnRef = 100 / bpPerPixel; - const arrowHeadWidthPixel = Math.min(alignmentRowHeight / 2.0, nomPixelWidthOnRef / 6); - - const isSoftClip = 'S' === block.type; - - const strokeOutline = - alignment.mq <= 0 || - this.highlightedAlignmentReadNamed === alignment.readName || - isSoftClip; - - let blockOutlineColor = outlineColor; - if (this.highlightedAlignmentReadNamed === alignment.readName) blockOutlineColor = 'red'; - else if (isSoftClip) blockOutlineColor = 'rgb(50,50,50)'; - - const lastBlockPositiveStrand = (true === alignment.strand && b === blocks.length - 1); - const lastBlockReverseStrand = (false === alignment.strand && b === 0); - const lastBlock = lastBlockPositiveStrand | lastBlockReverseStrand; - - if (lastBlock) { - let xListPixel; - let yListPixel; - if (lastBlockPositiveStrand) { - xListPixel = [ - blockStartPixel, - blockEndPixel, - blockEndPixel + arrowHeadWidthPixel, - blockEndPixel, - blockStartPixel, - blockStartPixel]; - yListPixel = [ - yRect, - yRect, - yRect + (alignmentHeight / 2.0), - yRect + alignmentHeight, - yRect + alignmentHeight, - yRect]; - - } - - // Last block on - strand ? - else if (lastBlockReverseStrand) { - xListPixel = [ - blockEndPixel, - blockStartPixel, - blockStartPixel - arrowHeadWidthPixel, - blockStartPixel, - blockEndPixel, - blockEndPixel]; - yListPixel = [ - yRect, - yRect, - yRect + (alignmentHeight / 2.0), - yRect + alignmentHeight, - yRect + alignmentHeight, - yRect]; - - } - IGVGraphics.fillPolygon(ctx, xListPixel, yListPixel, {fillStyle: alignmentColor}); - - if (strokeOutline) { - IGVGraphics.strokePolygon(ctx, xListPixel, yListPixel, {strokeStyle: blockOutlineColor}); - } - } - - // Internal block - else { - IGVGraphics.fillRect(ctx, blockStartPixel, yRect, blockWidthPixel, alignmentHeight, {fillStyle: alignmentColor}); - - if (strokeOutline) { - ctx.save(); - ctx.strokeStyle = blockOutlineColor; - ctx.strokeRect(blockStartPixel, yRect, blockWidthPixel, alignmentHeight); - ctx.restore(); - } - } - - - // Read base coloring - - if (isSoftClip || - showAllBases || - this.parent.showMismatches && (referenceSequence && alignment.seq && alignment.seq !== "*")) { - - const seq = alignment.seq ? alignment.seq.toUpperCase() : undefined; - const qual = alignment.qual; - const seqOffset = block.seqOffset; - const widthPixel = Math.max(1, 1 / bpPerPixel); - - - for (let i = 0, len = block.len; i < len; i++) { - - const xPixel = ((block.start + i) - bpStart) / bpPerPixel; - - if (xPixel + widthPixel < 0) continue // Off left edge - if (xPixel > pixelWidth) break // Off right edge - - let readChar = seq ? seq.charAt(seqOffset + i) : ''; - const refChar = offsetBP + i >= 0 ? referenceSequence.charAt(offsetBP + i) : ''; - - if (readChar === "=") { - readChar = refChar; - } - if (readChar === "X" || refChar !== readChar || isSoftClip || showAllBases) { - - let baseColor; - if (!isSoftClip && qual !== undefined && qual.length > seqOffset + i) { - const readQual = qual[seqOffset + i]; - baseColor = shadedBaseColor(readQual, nucleotideColors[readChar]); - } else { - baseColor = nucleotideColors[readChar]; - } - if (baseColor) { - blockBasesToDraw.push({ - bbox: { - x: xPixel, - y: yRect, - width: widthPixel, - height: alignmentHeight - }, - baseColor, - readChar, - }); - } - } - } - } - - return blockBasesToDraw - } - - function renderBlockOrReadChar(context, bpp, bbox, color, char) { - var threshold, - center; - - threshold = 1.0 / 10.0; - if (bpp <= threshold && bbox.height >= 8) { - - // render letter - const fontHeight = Math.min(10, bbox.height); - context.font = '' + fontHeight + 'px sans-serif'; - center = bbox.x + (bbox.width / 2.0); - IGVGraphics.strokeText(context, char, center - (context.measureText(char).width / 2), fontHeight - 1 + bbox.y, {strokeStyle: color}); - } else { - - // render colored block - IGVGraphics.fillRect(context, bbox.x, bbox.y, bbox.width, bbox.height, {fillStyle: color}); - } - } - } - - }; - - popupData(clickState) { - const clickedObject = this.getClickedObject(clickState); - return clickedObject ? clickedObject.popupData(clickState.genomicLocation) : undefined - }; - - contextMenuItemList(clickState) { - - const viewport = clickState.viewport; - const list = []; - - const sortByOption = (option) => { - const cs = this.parent.sortObject; - const direction = (cs && cs.position === Math.floor(clickState.genomicLocation)) ? !cs.direction : true; - const newSortObject = { - chr: viewport.referenceFrame.chr, - position: Math.floor(clickState.genomicLocation), - option: option, - direction: direction - }; - this.parent.sortObject = newSortObject; - viewport.cachedFeatures.sortRows(newSortObject); - viewport.repaint(); - }; - list.push('Sort by...'); - list.push({label: '  base', click: () => sortByOption("BASE")}); - list.push({label: '  read strand', click: () => sortByOption("STRAND")}); - list.push({label: '  insert size', click: () => sortByOption("INSERT_SIZE")}); - list.push({label: '  gap size', click: () => sortByOption("GAP_SIZE")}); - list.push({label: '  chromosome of mate', click: () => sortByOption("MATE_CHR")}); - list.push({label: '  mapping quality', click: () => sortByOption("MQ")}); - list.push({label: '  read name', click: () => sortByOption("READ_NAME")}); - list.push({label: '  aligned read length', click: () => sortByOption("ALIGNED_READ_LENGTH")}); - list.push({ - label: '  tag', click: () => { - const cs = this.parent.sortObject; - const direction = (cs && cs.position === Math.floor(clickState.genomicLocation)) ? !cs.direction : true; - const config = - { - label: 'Tag Name', - value: this.sortByTag ? this.sortByTag : '', - callback: (tag) => { - if (tag) { - const newSortObject = { - chr: viewport.referenceFrame.chr, - position: Math.floor(clickState.genomicLocation), - option: "TAG", - tag: tag, - direction: direction - }; - this.sortByTag = tag; - this.parent.sortObject = newSortObject; - viewport.cachedFeatures.sortRows(newSortObject); - viewport.repaint(); - } - } - }; - this.browser.inputDialog.present(config, clickState.event); - } - }); - list.push('
'); - - const clickedObject = this.getClickedObject(clickState); - - if (clickedObject) { - - const showSoftClips = this.parent.showSoftClips; - const clickedAlignment = (typeof clickedObject.alignmentContaining === 'function') ? - clickedObject.alignmentContaining(clickState.genomicLocation, showSoftClips) : - clickedObject; - if (clickedAlignment) { - if (clickedAlignment.isPaired() && clickedAlignment.isMateMapped()) { - list.push({ - label: 'View mate in split screen', - click: () => { - if (clickedAlignment.mate) { - const referenceFrame = clickState.viewport.referenceFrame; - if (this.browser.genome.getChromosome(clickedAlignment.mate.chr)) { - this.highlightedAlignmentReadNamed = clickedAlignment.readName; - //this.browser.presentMultiLocusPanel(clickedAlignment, referenceFrame) - const bpWidth = referenceFrame.end - referenceFrame.start; - const frameStart = clickedAlignment.mate.position - bpWidth / 2; - const frameEnd = clickedAlignment.mate.position + bpWidth / 2; - this.browser.addMultiLocusPanel(clickedAlignment.mate.chr, frameStart, frameEnd, referenceFrame); - } else { - this.browser.alert.present(`Reference does not contain chromosome: ${clickedAlignment.mate.chr}`); - } - } - }, - init: undefined - }); - } - - list.push({ - label: 'View read sequence', - click: () => { - const seqstring = clickedAlignment.seq; //.map(b => String.fromCharCode(b)).join(""); - if (!seqstring || "*" === seqstring) { - this.browser.alert.present("Read sequence: *"); - } else { - this.browser.alert.present(seqstring); - } - } - }); - - if (isSecureContext()) { - list.push({ - label: 'Copy read sequence', - click: async () => { - const seq = clickedAlignment.seq; //.map(b => String.fromCharCode(b)).join(""); - try { - //console.log(`seq: ${seq}`) - await navigator.clipboard.writeText(seq); - } catch (e) { - console.error(e); - this.browser.alert.present(`error copying sequence to clipboard ${e}`); - } - - } - }); - } - - // TODO if genome supports blat - const seqstring = clickedAlignment.seq; - if (seqstring && "*" != seqstring) { - - if (seqstring.length < maxSequenceSize) { - list.push({ - label: 'BLAT read sequence', - click: () => { - const sequence = clickedAlignment.isNegativeStrand() ? reverseComplementSequence(seqstring) : seqstring; - const name = `${clickedAlignment.readName} - blat`; - const title = `${this.parent.name} - ${name}`; - createBlatTrack({sequence, browser: this.browser, name, title}); - } - }); - } - - const softClips = clickedAlignment.softClippedBlocks(); - if (softClips.left && softClips.left.len > MINIMUM_BLAT_LENGTH && softClips.left.len < maxSequenceSize) { - list.push({ - label: 'BLAT left soft-clipped sequence', - click: () => { - const clippedSequence = seqstring.substr(softClips.left.seqOffset, softClips.left.len); - const sequence = clickedAlignment.isNegativeStrand() ? reverseComplementSequence(clippedSequence) : clippedSequence; - const name = `${clickedAlignment.readName} - blat left clip`; - const title = `${this.parent.name} - ${name}`; - createBlatTrack({sequence, browser: this.browser, name, title}); - } - }); - } - if (softClips.right && softClips.right.len > MINIMUM_BLAT_LENGTH && softClips.right.len < maxSequenceSize) { - list.push({ - label: 'BLAT right soft-clipped sequence', - click: () => { - const clippedSequence = seqstring.substr(softClips.right.seqOffset, softClips.right.len); - const sequence = clickedAlignment.isNegativeStrand() ? reverseComplementSequence(clippedSequence) : clippedSequence; - const name = `${clickedAlignment.readName} - blat right clip`; - const title = `${this.parent.name} - ${name}`; - createBlatTrack({sequence, browser: this.browser, name, title}); - } - }); - } - } - - list.push('
'); - } - } - - // Experimental JBrowse feature - if (this.browser.circularView && (this.hasPairs || this.hasSupplemental)) { - if (this.hasPairs) { - list.push({ - label: 'Add discordant pairs to circular view', - click: () => { - this.parent.addPairedChordsForViewport(viewport); - } - }); - } - if (this.hasSupplemental) { - list.push({ - label: 'Add split reads to circular view', - click: () => { - this.parent.addSplitChordsForViewport(viewport); - } - }); - } - list.push('
'); - } - - return list - - } - - getClickedObject(clickState) { - - const viewport = clickState.viewport; - const y = clickState.y; - const genomicLocation = clickState.genomicLocation; - - const showSoftClips = this.parent.showSoftClips; - - let features = viewport.cachedFeatures; - if (!features || features.length === 0) return - - let packedAlignmentRows = features.packedAlignmentRows; - let downsampledIntervals = features.downsampledIntervals; - const alignmentRowHeight = this.displayMode === "SQUISHED" ? - this.squishedRowHeight : - this.alignmentRowHeight; - - let packedAlignmentsIndex = Math.floor((y - this.top - this.alignmentsYOffset) / alignmentRowHeight); - - if (packedAlignmentsIndex < 0) { - for (let i = 0; i < downsampledIntervals.length; i++) { - if (downsampledIntervals[i].start <= genomicLocation && (downsampledIntervals[i].end >= genomicLocation)) { - return downsampledIntervals[i] - } - } - } else if (packedAlignmentsIndex < packedAlignmentRows.length) { - const alignmentRow = packedAlignmentRows[packedAlignmentsIndex]; - const clicked = alignmentRow.alignments.filter(alignment => alignment.containsLocation(genomicLocation, showSoftClips)); - if (clicked.length > 0) return clicked[0] - } - - return undefined - - }; - - /** - * Return the color for connectors in paired alignment view. If explicitly set return that, otherwise return - * the alignment color, unless the color option can result in split colors (separte color for each mate). - * - * @param alignment - * @returns {string} - */ - getConnectorColor(alignment) { - - if (this.pairConnectorColor) { - return this.pairConnectorColor - } - - switch (this.colorBy) { - case "strand": - case "firstOfPairStrand": - case "pairOrientation": - case "tag": - if (this.parent.color) { - return (typeof this.parent.color === "function") ? this.parent.color(alignment) : this.parent.color - } else { - return DEFAULT_CONNECTOR_COLOR - } - default: - return this.getAlignmentColor(alignment) - - } - } - - getAlignmentColor(alignment) { - - let color = DEFAULT_ALIGNMENT_COLOR; // The default color if nothing else applies - if (this.parent.color) { - color = (typeof this.parent.color === "function") ? this.parent.color(alignment) : this.parent.color; - } else { - color = DEFAULT_ALIGNMENT_COLOR; - } - const option = this.colorBy; - switch (option) { - case "strand": - color = alignment.strand ? this.posStrandColor : this.negStrandColor; - break - - case "firstOfPairStrand": - - if (alignment instanceof PairedAlignment) { - color = alignment.firstOfPairStrand() ? this.posStrandColor : this.negStrandColor; - } else if (alignment.isPaired()) { - - if (alignment.isFirstOfPair()) { - color = alignment.strand ? this.posStrandColor : this.negStrandColor; - } else if (alignment.isSecondOfPair()) { - color = alignment.strand ? this.negStrandColor : this.posStrandColor; - } else { - console.error("ERROR. Paired alignments are either first or second."); - } - } - break - - case "unexpectedPair": - case "pairOrientation": - - if (this.pairOrientation && alignment.pairOrientation) { - const oTypes = orientationTypes[this.pairOrientation]; - if (oTypes) { - const pairColor = this.pairColors[oTypes[alignment.pairOrientation]]; - if (pairColor) { - color = pairColor; - break - } - } - } - if ("pairOrientation" === option) { - break - } - - case "tlen": - case "fragmentLength": - - if (alignment.mate && alignment.isMateMapped()) { - if (alignment.mate.chr !== alignment.chr) { - color = getChrColor(alignment.mate.chr); - } else if (this.parent.minTemplateLength && Math.abs(alignment.fragmentLength) < this.parent.minTemplateLength) { - color = this.smallTLENColor; - } else if (this.parent.maxTemplateLength && Math.abs(alignment.fragmentLength) > this.parent.maxTemplateLength) { - color = this.largeTLENColor; - } - } - break - - case "tag": - const tagValue = alignment.tags()[this.colorByTag]; - if (tagValue !== undefined) { - if (this.bamColorTag === this.colorByTag) { - // UCSC style color option - color = "rgb(" + tagValue + ")"; - } else { - - if (!this.tagColors) { - this.tagColors = new PaletteColorTable("Set1"); - } - color = this.tagColors.getColor(tagValue); - } - } - break - } - - return color - - } -} - -function shadedBaseColor(qual, baseColor) { - - const minQ = 5; //prefs.getAsInt(PreferenceManager.SAM_BASE_QUALITY_MIN), - const maxQ = 20; //prefs.getAsInt(PreferenceManager.SAM_BASE_QUALITY_MAX); - - let alpha; - if (qual < minQ) { - alpha = 0.1; - } else { - alpha = Math.max(0.1, Math.min(1.0, 0.1 + 0.9 * (qual - minQ) / (maxQ - minQ))); - } - // Round alpha to nearest 0.1 - alpha = Math.round(alpha * 10) / 10.0; - - if (alpha < 1) { - baseColor = IGVColor.addAlpha(baseColor, alpha); - } - return baseColor -} - -const orientationTypes = { - - "fr": { - "F1R2": "LR", - "F2R1": "LR", - "F1F2": "LL", - "F2F1": "LL", - "R1R2": "RR", - "R2R1": "RR", - "R1F2": "RL", - "R2F1": "RL" - }, - - "rf": { - "R1F2": "LR", - "R2F1": "LR", - "R1R2": "LL", - "R2R1": "LL", - "F1F2": "RR", - "F2F1": "RR", - "F1R2": "RL", - "F2R1": "RL" - }, - - "ff": { - "F2F1": "LR", - "R1R2": "LR", - "F2R1": "LL", - "R1F2": "LL", - "R2F1": "RR", - "F1R2": "RR", - "R2R1": "RL", - "F1F2": "RL" - } -}; - -function getChrColor(chr) { - if (chrColorMap[chr]) { - return chrColorMap[chr] - } else if (chrColorMap["chr" + chr]) { - const color = chrColorMap["chr" + chr]; - chrColorMap[chr] = color; - return color - } else { - const color = IGVColor.randomRGB(0, 255); - chrColorMap[chr] = color; - return color - } -} - -const chrColorMap = { - "chrX": "rgb(204, 153, 0)", - "chrY": "rgb(153, 204, 0)", - "chrUn": "rgb(50, 50, 50)", - "chr1": "rgb(80, 80, 255)", - "chrI": "rgb(139, 155, 187)", - "chr2": "rgb(206, 61, 50)", - "chrII": "rgb(206, 61, 50)", - "chr2a": "rgb(216, 71, 60)", - "chr2b": "rgb(226, 81, 70)", - "chr3": "rgb(116, 155, 88)", - "chrIII": "rgb(116, 155, 88)", - "chr4": "rgb(240, 230, 133)", - "chrIV": "rgb(240, 230, 133)", - "chr5": "rgb(70, 105, 131)", - "chr6": "rgb(186, 99, 56)", - "chr7": "rgb(93, 177, 221)", - "chr8": "rgb(128, 34, 104)", - "chr9": "rgb(107, 215, 107)", - "chr10": "rgb(213, 149, 167)", - "chr11": "rgb(146, 72, 34)", - "chr12": "rgb(131, 123, 141)", - "chr13": "rgb(199, 81, 39)", - "chr14": "rgb(213, 143, 92)", - "chr15": "rgb(122, 101, 165)", - "chr16": "rgb(228, 175, 105)", - "chr17": "rgb(59, 27, 83)", - "chr18": "rgb(205, 222, 183)", - "chr19": "rgb(97, 42, 121)", - "chr20": "rgb(174, 31, 99)", - "chr21": "rgb(231, 199, 111)", - "chr22": "rgb(90, 101, 94)", - "chr23": "rgb(204, 153, 0)", - "chr24": "rgb(153, 204, 0)", - "chr25": "rgb(51, 204, 0)", - "chr26": "rgb(0, 204, 51)", - "chr27": "rgb(0, 204, 153)", - "chr28": "rgb(0, 153, 204)", - "chr29": "rgb(10, 71, 255)", - "chr30": "rgb(71, 117, 255)", - "chr31": "rgb(255, 194, 10)", - "chr32": "rgb(255, 209, 71)", - "chr33": "rgb(153, 0, 51)", - "chr34": "rgb(153, 26, 0)", - "chr35": "rgb(153, 102, 0)", - "chr36": "rgb(128, 153, 0)", - "chr37": "rgb(51, 153, 0)", - "chr38": "rgb(0, 153, 26)", - "chr39": "rgb(0, 153, 102)", - "chr40": "rgb(0, 128, 153)", - "chr41": "rgb(0, 51, 153)", - "chr42": "rgb(26, 0, 153)", - "chr43": "rgb(102, 0, 153)", - "chr44": "rgb(153, 0, 128)", - "chr45": "rgb(214, 0, 71)", - "chr46": "rgb(255, 20, 99)", - "chr47": "rgb(0, 214, 143)", - "chr48": "rgb(20, 255, 177)", -}; - -let timer; -let currentViewport = undefined; -const toolTipTimeout = 1e4; - -class RulerViewport extends TrackViewport { - - constructor(trackView, $viewportColumn, referenceFrame, width) { - super(trackView, $viewportColumn, referenceFrame, width); - } - - get contentDiv() { - return this.$viewport.get(0) - } - - initializationHelper() { - - this.$multiLocusCloseButton = $$1('
', {class: 'igv-multi-locus-close-button'}); - this.$viewport.append(this.$multiLocusCloseButton); - this.$multiLocusCloseButton.get(0).appendChild(icons$1$1.createIcon("times-circle")); - - this.$multiLocusCloseButton.click(() => { - this.browser.removeMultiLocusPanel(this.referenceFrame); - }); - - this.$rulerLabel = $$1('
', {class: 'igv-multi-locus-ruler-label'}); - this.$viewport.append(this.$rulerLabel); - - let div; - div = document.createElement('div'); - this.$rulerLabel.append($$1(div)); - - this.$rulerLabel.get(0).addEventListener('click', async event => { - event.stopPropagation(); - await this.browser.gotoMultilocusPanel(this.referenceFrame); - }); - - this.$tooltip = $$1('
', {class: 'igv-ruler-tooltip'}); - this.$tooltip.height(this.$viewport.height()); - - this.$viewport.append(this.$tooltip); - - this.$tooltipContent = $$1('
'); - this.$tooltip.append(this.$tooltipContent); - - this.rulerSweeper = new RulerSweeper(this, this.$viewport.get(0).parentElement, this.browser, this.referenceFrame); - - this.attachMouseHandlers(GenomeUtils.isWholeGenomeView(this.referenceFrame.chr)); - - this.$tooltip.hide(); - - this.dismissLocusLabel(); - } - - presentLocusLabel(viewportWidth) { - - this.$multiLocusCloseButton.show(); - - this.$rulerLabel.show(); - this.$rulerLabel.get(0).style.backgroundColor = getChrColor(this.referenceFrame.chr); - - const textDiv = this.$rulerLabel.get(0).querySelector('div'); - - const { width } = this.$rulerLabel.get(0).getBoundingClientRect(); - - textDiv.innerHTML = `${ this.referenceFrame.getMultiLocusLabel(viewportWidth) }`; - const { width:textDivWidth } = textDiv.getBoundingClientRect(); - - if (textDivWidth/width > 0.5) { - textDiv.innerHTML = `${ this.referenceFrame.getMultiLocusLabelBPLengthOnly(viewportWidth) }`; - } - - //console.log(`${ Date.now() } textDiv ${ StringUtils.numberFormatter(Math.floor(textDivWidth)) }`) - - } - - // Use in conjuction with .igv-multi-locus-ruler-label-square-dot css class (_dom-misc.scss) - dismissLocusLabel() { - this.$rulerLabel.hide(); - this.$multiLocusCloseButton.hide(); - } - - attachMouseHandlers(isWholeGenomeView) { - - this.namespace = `.ruler_track_viewport_${this.browser.referenceFrameList.indexOf(this.referenceFrame)}`; - - this.$viewport.off(this.namespace); - - if (true === isWholeGenomeView) { - - const index = this.browser.referenceFrameList.indexOf(this.referenceFrame); - - const click = `click${this.namespace}`; - this.$viewport.on(click, (e) => { - - const {x: pixel} = domUtils$1.translateMouseCoordinates(e, this.$viewport.get(0)); - const bp = Math.round(this.referenceFrame.start + this.referenceFrame.toBP(pixel)); - - let searchString; - - const {chr} = this.browser.genome.getChromosomeCoordinate(bp); - - if (1 === this.browser.referenceFrameList.length) { - searchString = chr; - } else { - - let loci = this.browser.referenceFrameList.map(({locusSearchString}) => locusSearchString); - - loci[index] = chr; - - searchString = loci.join(' '); - } - - this.browser.search(searchString); - }); - - this.$viewport.get(0).style.cursor = 'pointer'; - } else { - this.$viewport.get(0).style.cursor = 'default'; - } - - } - - mouseMove(event) { - - if (true === this.browser.cursorGuideVisible) { - - if (undefined === currentViewport) { - currentViewport = this; - this.$tooltip.show(); - } else if (currentViewport.guid !== this.guid) { - if (currentViewport.$tooltip) { - currentViewport.$tooltip.hide(); - } - this.$tooltip.show(); - currentViewport = this; - } else { - this.$tooltip.show(); - } - - const isWholeGenome = (this.browser.isMultiLocusWholeGenomeView() || GenomeUtils.isWholeGenomeView(this.referenceFrame.chr)); - - if (isWholeGenome) { - this.$tooltip.hide(); - return - } - - const {x} = domUtils$1.translateMouseCoordinates(event, this.$viewport.get(0)); - const {start, bpPerPixel} = this.referenceFrame; - const bp = Math.round(0.5 + start + Math.max(0, x) * bpPerPixel); - - this.$tooltipContent.text(numberFormatter$1(bp)); - - const {width: ww} = this.$tooltipContent.get(0).getBoundingClientRect(); - const {width: w} = this.$viewport.get(0).getBoundingClientRect(); - - this.$tooltip.css({left: `${IGVMath.clamp(x, 0, w - ww)}px`}); - - // hide tooltip when movement stops - clearTimeout(timer); - timer = setTimeout(() => { - if (this.$tooltip) this.$tooltip.hide(); - }, toolTipTimeout); - - } - - } - - startSpinner() { - } - - stopSpinner() { - } - - dispose() { - this.rulerSweeper.dispose(); - super.dispose(); - } - -} - -/* - * The MIT License (MIT) - * - * Copyright (c) 2014 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -class IdeogramViewport extends TrackViewport { - - constructor(trackView, viewportColumn, referenceFrame, width) { - super(trackView, viewportColumn, referenceFrame, width); - } - - initializationHelper() { - - this.canvas = document.createElement('canvas'); - this.canvas.className = 'igv-ideogram-canvas'; - //this.$content.append($(this.canvas)) - this.$viewport.append($$1(this.canvas)); - this.ideogram_ctx = this.canvas.getContext('2d'); - - this.addMouseHandlers(); - } - - addMouseHandlers() { - this.addViewportClickHandler(this.$viewport.get(0)); - } - - addViewportClickHandler(viewport) { - - this.boundClickHandler = clickHandler.bind(this); - viewport.addEventListener('click', this.boundClickHandler); - - function clickHandler(event) { - - const {xNormalized, width} = domUtils$1.translateMouseCoordinates(event, this.ideogram_ctx.canvas); - const {bpLength} = this.browser.genome.getChromosome(this.referenceFrame.chr); - const locusLength = this.referenceFrame.bpPerPixel * width; - const chrCoveragePercentage = locusLength / bpLength; - - let xPercentage = xNormalized; - if (xPercentage - (chrCoveragePercentage / 2.0) < 0) { - xPercentage = chrCoveragePercentage / 2.0; - } - - if (xPercentage + (chrCoveragePercentage / 2.0) > 1.0) { - xPercentage = 1.0 - chrCoveragePercentage / 2.0; - } - - const ss = Math.round((xPercentage - (chrCoveragePercentage / 2.0)) * bpLength); - const ee = Math.round((xPercentage + (chrCoveragePercentage / 2.0)) * bpLength); - - this.referenceFrame.start = ss; - this.referenceFrame.end = ee; - this.referenceFrame.bpPerPixel = (ee - ss) / width; - - this.browser.updateViews(this.referenceFrame, this.browser.trackViews, true); - - } - - } - - setWidth(width) { - this.$viewport.width(width); - } - - drawSVGWithContext(context, width, height, id, x, y, yClipOffset) { - - context.saveWithTranslationAndClipRect(id, x, y, width, height, yClipOffset); - - this.trackView.track.draw({ - context, - referenceFrame: this.referenceFrame, - pixelWidth: width, - pixelHeight: height - }); - - context.restore(); - } - - repaint() { - this.draw({referenceFrame: this.referenceFrame}); - } - - draw({referenceFrame}) { - - IGVGraphics.configureHighDPICanvas(this.ideogram_ctx, this.$viewport.width(), this.$viewport.height()); - - this.trackView.track.draw({ - context: this.ideogram_ctx, - referenceFrame, - pixelWidth: this.$viewport.width(), - pixelHeight: this.$viewport.height() - }); - } - - startSpinner() { - } - - stopSpinner() { - } - -} - -/* - * The MIT License (MIT) - * - * Copyright (c) 2014 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - -function createViewport(trackView, column, referenceFrame, width) { - - if ('ruler' === trackView.track.type) { - return new RulerViewport(trackView, column, referenceFrame, width) - } else if ('ideogram' === trackView.track.id) { - return new IdeogramViewport(trackView, column, referenceFrame, width) - } else { - const viewportObject = new TrackViewport(trackView, column, referenceFrame, width); - - // if ('sequence' === trackView.track.type) { - // viewportObject.$viewport.get(0).style.marginTop = '0px' - // } - - return viewportObject - } -} - -const maxFontSize = 10; - -const fontConfigureTemplate = - { - // font: '2pt sans-serif', - textAlign: 'start', - textBaseline: 'bottom', - strokeStyle: 'black', - fillStyle: 'black' - }; - -class SampleNameViewport { - - constructor(trackView, column, unused, width) { - - this.guid = domUtils$1.guid(); - this.trackView = trackView; - - this.browser = trackView.browser; - - this.viewport = domUtils$1.div({class: 'igv-viewport'}); - - column.appendChild(this.viewport); - - if (trackView.track.height) { - this.viewport.style.height = `${trackView.track.height}px`; - } - - this.canvas = document.createElement('canvas'); - this.viewport.appendChild(this.canvas); - this.ctx = this.canvas.getContext("2d"); - - this.trackScrollDelta = 0; - - this.contentTop = 0; - - this.setWidth(width); - - if (false === this.browser.showSampleNames) { - this.hide(); - } - - this.addMouseHandlers(); - } - - checkCanvas() { - - const dpi = window.devicePixelRatio; - const requiredHeight = this.viewport.clientHeight; - const requiredWidth = this.browser.sampleNameViewportWidth; - - if (this.canvas.width !== requiredWidth * dpi || this.canvas.height !== requiredHeight * dpi) { - const canvas = this.canvas; - canvas.width = requiredWidth * dpi; - canvas.height = requiredHeight * dpi; - canvas.style.width = `${requiredWidth}px`; - canvas.style.height = `${requiredHeight}px`; - this.ctx = this.canvas.getContext("2d"); - this.ctx.scale(dpi, dpi); - } - - } - - setTop(contentTop) { - - if (typeof this.trackView.track.getSamples === 'function') { - this.contentTop = contentTop; - const samples = this.trackView.track.getSamples(); - this.repaint(samples); - } - - } - - setWidth(width) { - this.viewport.innerWidth = width; - this.checkCanvas(); - } - - show() { - this.viewport.style.display = 'block'; - } - - hide() { - this.viewport.style.display = 'none'; - } - - async repaint(samples) { - - this.checkCanvas(); - this.draw({context: this.ctx, samples}); - } - - draw({context, samples}) { - - if (!samples || samples.names.length === 0/* || samples.height < 1*/) { - return - } - - configureFont(context, fontConfigureTemplate, samples.height); - const sampleNameXShim = 4; - - context.clearRect(0, 0, context.canvas.width, context.canvas.height); - - context.fillStyle = appleCrayonRGB('lead'); - - const viewportHeight = this.viewport.getBoundingClientRect().height; - let y = (samples.yOffset || 0) + this.contentTop; // contentTop will always be a negative number (top relative to viewport) - - for (let name of samples.names) { - if (y > viewportHeight) { - break - } - if (y + samples.height > 0) { - const text = name; - const yFont = getYFont(context, text, y, samples.height); - context.fillText(text, sampleNameXShim, yFont); - - } - y += samples.height; - } - } - - renderSVGContext(context, {deltaX, deltaY}) { - - if (typeof this.trackView.track.getSamples === 'function') { - - const samples = this.trackView.track.getSamples(); - - const yScrollDelta = 0; // This is not relevant, scrolling is handled in "draw" - - const {width, height} = this.viewport.getBoundingClientRect(); - - const str = (this.trackView.track.name || this.trackView.track.id).replace(/\W/g, ''); - const id = `${str}_sample_names_guid_${domUtils$1.guid()}`; - - context.saveWithTranslationAndClipRect(id, deltaX, deltaY + yScrollDelta, width, height, -yScrollDelta); - - this.draw({context, samples}); - - context.restore(); - } - } - - addMouseHandlers() { - this.addViewportContextMenuHandler(this.viewport); - } - - removeMouseHandlers() { - this.removeViewportContextMenuHandler(this.viewport); - } - - addViewportContextMenuHandler(viewport) { - this.boundContextMenuHandler = contextMenuHandler.bind(this); - viewport.addEventListener('contextmenu', this.boundContextMenuHandler); - - function contextMenuHandler(event) { - - event.preventDefault(); - event.stopPropagation(); - - const config = - { - label: 'Name Panel Width', - value: this.browser.sampleNameViewportWidth, - callback: newWidth => { - this.browser.sampleNameViewportWidth = parseInt(newWidth); - for (let {sampleNameViewport} of this.browser.trackViews) { - sampleNameViewport.setWidth(this.browser.sampleNameViewportWidth); - } - this.browser.layoutChange(); - } - }; - - this.browser.inputDialog.present(config, event); - } - - } - - removeViewportContextMenuHandler(viewport) { - viewport.removeEventListener('contextmenu', this.boundContextMenuHandler); - } - - dispose() { - this.removeMouseHandlers(); - this.viewport.remove(); - } -} - -function getYFont(context, text, y, height) { - return y + height - getSampleNameYShim(context, text, height) -} - -function getSampleNameYShim(context, text, h) { - const {actualBoundingBoxAscent, actualBoundingBoxDescent} = context.measureText(text); - return (h - (actualBoundingBoxAscent + actualBoundingBoxDescent)) / 2 -} - -function configureFont(ctx, {textAlign, textBaseline, strokeStyle, fillStyle}, sampleHeight) { - const pixels = Math.min(sampleHeight, maxFontSize); - ctx.font = `${pixels}px sans-serif`; - ctx.textAlign = textAlign; - ctx.textBaseline = textBaseline; - ctx.fillStyle = fillStyle; -} - -const MenuPopup = function (parent) { - - this.popover = domUtils$1.div({class: 'igv-menu-popup'}); - parent.appendChild(this.popover); - - const header = domUtils$1.div({class: 'igv-menu-popup-header'}); - this.popover.appendChild(header); - - uiUtils$1.attachDialogCloseHandlerWithParent(header, () => this.hide()); - - this.popoverContent = domUtils$1.div(); - this.popover.appendChild(this.popoverContent); - - makeDraggable$1(this.popover, header); - - header.addEventListener('click', e => { - e.stopPropagation(); - e.preventDefault(); - // absorb click to prevent it leaking through to parent DOM element - }); - - this.hide(); - -}; - -MenuPopup.prototype.hide = function () { - this.popover.style.display = 'none'; -}; - -MenuPopup.prototype.presentMenuList = function (menuList) { - - hideAllMenuPopups(); - - if (menuList.length > 0) { - - this.popoverContent.innerHTML = ''; - - menuList = MenuUtils$1.trackMenuItemListHelper(menuList, this); - - for (let item of menuList) { - - if (item.init) { - item.init(); - } - - let $e = item.object; - if (0 === menuList.indexOf(item)) { - $e.removeClass('igv-track-menu-border-top'); - } - - if ($e.hasClass('igv-track-menu-border-top') || $e.hasClass('igv-menu-popup-check-container')) ; else if ($e.is('div')) { - $e.addClass('igv-menu-popup-shim'); - } - - this.popoverContent.appendChild($e.get(0)); - - } - - // NOTE: style.display most NOT be 'none' when calculating width. a display = 'none' will always - // yield a width of zero (0). - this.popover.style.display = 'flex'; - - const {width} = this.popover.getBoundingClientRect(); - - this.popover.style.left = `${-width}px`; - this.popover.style.top = `${0}px`; - - } -}; - -MenuPopup.prototype.presentTrackContextMenu = function (e, menuItems) { - - this.popoverContent.innerHTML = ''; - - const menuElements = createMenuElements(menuItems, this.popover); - for (let {el} of menuElements) { - this.popoverContent.appendChild(el); - } - - present(e, this.popover); - -}; - -MenuPopup.prototype.dispose = function () { - - this.popoverContent.innerHTML = ''; - this.popover.innerHTML = ''; - - Object.keys(this).forEach(function (key) { - this[key] = undefined; - }); -}; - -function createMenuElements(itemList, popover) { - - return itemList.map(item => { - - let el; - - if (typeof item === 'string' && '
' === item) { - el = document.createElement('hr'); - } else if (typeof item === 'string') { - el = domUtils$1.div({class: 'context-menu'}); - el.innerHTML = item; - } else if (typeof item === 'Node') { - el = item; - } else { - if (typeof item.init === 'function') { - item.init(); - } - - if ("checkbox" === item.type) { - el = createCheckbox$2("Show all bases", item.value); - } else if ("color" === item.type) { - - const colorPicker = new GenericColorPicker({parent: popover.parentElement, width: 364}); - colorPicker.configure(undefined, {color: color => item.click(color)}); - - el = domUtils$1.div({class: 'context-menu'}); - if (typeof item.label === 'string') { - el.innerHTML = item.label; - } - const clickHandler = e => { - colorPicker.show(); - domUtils$1.hide(popover); - e.preventDefault(); - e.stopPropagation(); - }; - el.addEventListener('click', clickHandler); - el.addEventListener('touchend', clickHandler); - el.addEventListener('mouseup', function (e) { - e.preventDefault(); - e.stopPropagation(); - }); - } else { - el = domUtils$1.div({class: 'context-menu'}); - if (typeof item.label === 'string') { - el.innerHTML = item.label; - } - } - - if (item.click && "color" !== item.type) { - el.addEventListener('click', handleClick); - el.addEventListener('touchend', handleClick); - el.addEventListener('mouseup', function (e) { - e.preventDefault(); - e.stopPropagation(); - }); - - // eslint-disable-next-line no-inner-declarations - function handleClick(e) { - item.click(); - domUtils$1.hide(popover); - e.preventDefault(); - e.stopPropagation(); - } - } - } - - return {el, init: item.init} - }) - -} - -function present(e, popover) { - - // NOTE: style.display most NOT be 'none' when calculating width. a display = 'none' will always - // yield a width of zero (0). - popover.style.display = 'flex'; - - const {x, y} = domUtils$1.translateMouseCoordinates(e, popover.parentNode); - const {width} = popover.getBoundingClientRect(); - const xmax = x + width; - - const {width: parentWidth} = popover.parentNode.getBoundingClientRect(); - - popover.style.left = `${xmax > parentWidth ? (x - (xmax - parentWidth)) : x}px`; - popover.style.top = `${y}px`; - -} - -const hideAllMenuPopups = () => { - - const menus = document.querySelectorAll('.igv-menu-popup'); - for (let i = 0; i < menus.length; i++) { - menus[i].style.display = 'none'; - } - -}; - -/* - * The MIT License (MIT) - * - * Copyright (c) 2014 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -const igv_axis_column_width = 50; -const scrollbarExclusionTypes = new Set(['ruler', 'ideogram']); -const colorPickerExclusionTypes = new Set(['ruler', 'sequence', 'ideogram']); - -class TrackView { - - constructor(browser, columnContainer, track) { - this.browser = browser; - this.track = track; - track.trackView = this; - this.addDOMToColumnContainer(browser, columnContainer, browser.referenceFrameList); - } - - /** - * Start a spinner for the track on any of its viewports. In practice this is called during initialization - * when there is only one. - */ - startSpinner() { - if (this.viewports && this.viewports.length > 0) { - this.viewports[0].startSpinner(); - } - } - - stopSpinner() { - if (this.viewports && this.viewports.length > 0) { - this.viewports[0].stopSpinner(); - } - } - - addDOMToColumnContainer(browser, columnContainer, referenceFrameList) { - - // Axis - this.axis = this.createAxis(browser, this.track); - - // Create a viewport for each reference frame - this.viewports = []; - const viewportWidth = browser.calculateViewportWidth(referenceFrameList.length); - const viewportColumns = columnContainer.querySelectorAll('.igv-column'); - for (let i = 0; i < viewportColumns.length; i++) { - const viewport = createViewport(this, viewportColumns[i], referenceFrameList[i], viewportWidth); - this.viewports.push(viewport); - } - - // SampleName Viewport - this.sampleNameViewport = new SampleNameViewport(this, browser.columnContainer.querySelector('.igv-sample-name-column'), undefined, browser.sampleNameViewportWidth); - - // Track Scrollbar - this.createTrackScrollbar(browser); - - // Track Drag - this.createTrackDragHandle(browser); - - // Track Gear - this.createTrackGearPopup(browser); - - } - - createAxis(browser, track) { - - const axis = domUtils$1.div(); - browser.columnContainer.querySelector('.igv-axis-column').appendChild(axis); - - axis.style.height = `${track.height}px`; - - if (typeof track.paintAxis === 'function') { - if (track.dataRange) { - axis.addEventListener('click', () => { - browser.dataRangeDialog.configure(this); - browser.dataRangeDialog.present($$1(browser.columnContainer)); - }); - } - - - const {width, height} = axis.getBoundingClientRect(); - this.axisCanvas = document.createElement('canvas'); - this.axisCanvas.style.width = `${width}px`; - this.axisCanvas.style.height = `${height}px`; - axis.appendChild(this.axisCanvas); - } - - return axis - - } - - resizeAxisCanvas(width, height) { - - this.axis.style.width = `${width}px`; - this.axis.style.height = `${height}px`; - - if (typeof this.track.paintAxis === 'function') { - // Size the canvas in CSS (logical) pixels. The buffer size will be set when painted. - this.axisCanvas.style.width = `${width}px`; - this.axisCanvas.style.height = `${height}px`; - - } - } - - removeDOMFromColumnContainer() { - - // Axis - if (this.boundAxisClickHander) { - this.removeAxisEventListener(this.axis); - } - this.axis.remove(); - - // Track Viewports - for (let viewport of this.viewports) { - viewport.$viewport.remove(); - } - - // SampleName Viewport - this.sampleNameViewport.dispose(); - - // empty trackScrollbar Column - this.removeTrackScrollMouseHandlers(); - this.outerScroll.remove(); - - // empty trackDrag Column - this.removeTrackDragMouseHandlers(); - this.dragHandle.remove(); - - // empty trackGear Column - this.removeTrackGearMouseHandlers(); - this.gearContainer.remove(); - - } - - renderSVGContext(context, {deltaX, deltaY}) { - - renderSVGAxis(context, this.track, this.axisCanvas, deltaX, deltaY); - - const {width: axisWidth} = this.axis.getBoundingClientRect(); - - const {y} = this.viewports[0].$viewport.get(0).getBoundingClientRect(); - - let delta = - { - deltaX: axisWidth + deltaX, - deltaY: y + deltaY - }; - - for (let viewport of this.viewports) { - viewport.renderSVGContext(context, delta); - const {width} = viewport.$viewport.get(0).getBoundingClientRect(); - delta.deltaX += width; - } - - if (true === this.browser.showSampleNames) { - this.sampleNameViewport.renderSVGContext(context, delta); - } - } - - dataRange() { - return this.track.dataRange ? this.track.dataRange : undefined - } - - setDataRange(min, max) { - if (min !== undefined) { - this.track.dataRange.min = min; - } - if (max !== undefined) { - this.track.dataRange.max = max; - } - this.track.autoscale = false; - this.repaintViews(); - } - - presentColorPicker(key) { - - if (false === colorPickerExclusionTypes.has(this.track.type)) { - - const trackColors = []; - const color = this.track.color || this.track.defaultColor; - if (isString$2(color)) { - trackColors.push(color); - } - if (this.track.altColor && isString$2(this.track.altColor)) { - trackColors.push(this.track.altColor); - } - const defaultColors = trackColors.map(c => c.startsWith("#") ? c : c.startsWith("rgb(") ? IGVColor.rgbToHex(c) : IGVColor.colorNameToHex(c)); - const colorHandlers = - { - color: color => { - this.track.color = color; - this.repaintViews(); - }, - altColor: color => { - this.track.altColor = color; - this.repaintViews(); - } - - }; - this.browser.genericColorPicker.configure(defaultColors, colorHandlers); - this.browser.genericColorPicker.setActiveColorHandler(key); - this.browser.genericColorPicker.show(); - } - - } - - setTrackHeight(newHeight, force) { - - if (!force) { - if (this.track.minHeight) { - newHeight = Math.max(this.track.minHeight, newHeight); - } - if (this.track.maxHeight) { - newHeight = Math.min(this.track.maxHeight, newHeight); - } - } - - this.track.height = newHeight; - - this.resizeAxisCanvas(this.axis.clientWidth, this.track.height); - - if (typeof this.track.paintAxis === 'function') { - this.paintAxis(); - } - - for (let {$viewport} of this.viewports) { - $viewport.height(newHeight); - } - - this.sampleNameViewport.viewport.style.height = `${newHeight}px`; - - // If the track does not manage its own content height set it equal to the viewport height here - if (typeof this.track.computePixelHeight !== "function") { - for (let vp of this.viewports) { - vp.setContentHeight(newHeight); - } - } - - this.repaintViews(); - - if (false === scrollbarExclusionTypes.has(this.track.type)) { - this.updateScrollbar(); - } - - this.dragHandle.style.height = `${newHeight}px`; - this.gearContainer.style.height = `${newHeight}px`; - - } - - updateScrollbar() { - - const viewportHeight = this.viewports[0].$viewport.height(); - this.outerScroll.style.height = `${viewportHeight}px`; - - const viewportContentHeight = this.maxViewportContentHeight(); - const innerScrollHeight = Math.round((viewportHeight / viewportContentHeight) * viewportHeight); - - if (viewportContentHeight > viewportHeight) { - this.innerScroll.style.display = 'block'; - this.innerScroll.style.height = `${innerScrollHeight}px`; - } else { - this.innerScroll.style.display = 'none'; - } - } - - moveScroller(delta) { - - const y = $$1(this.innerScroll).position().top + delta; - const top = Math.min(Math.max(0, y), this.outerScroll.clientHeight - this.innerScroll.clientHeight); - $$1(this.innerScroll).css('top', `${top}px`); - - const contentHeight = this.maxViewportContentHeight(); - const contentTop = -Math.round(top * (contentHeight / this.viewports[0].$viewport.height())); - - for (let viewport of this.viewports) { - viewport.setTop(contentTop); - } - - this.sampleNameViewport.trackScrollDelta = delta; - this.sampleNameViewport.setTop(contentTop); - - } - - isLoading() { - for (let viewport of this.viewports) { - if (viewport.isLoading()) return true - } - } - - /** - * Repaint all viewports without loading any new data. Use this for events that change visual aspect of data, - * e.g. color, sort order, etc, but do not change the genomic state. - */ - repaintViews() { - - for (let viewport of this.viewports) { - if (viewport.isVisible()) { - viewport.repaint(); - } - } - - if (typeof this.track.paintAxis === 'function') { - this.paintAxis(); - } - - // Repaint sample names last - this.repaintSamples(); - } - - repaintSamples() { - - if (typeof this.track.getSamples === 'function') { - const samples = this.track.getSamples(); - this.sampleNameViewport.repaint(samples); - } - } - - // track labels - setTrackLabelName(name) { - this.viewports.forEach(viewport => viewport.setTrackLabel(name)); - } - - /** - * Called in response to a window resize event, change in # of multilocus panels, or other event that changes - * the width of the track view. - * - * @param viewportWidth The width of each viewport in this track view. - */ - resize(viewportWidth) { - for (let viewport of this.viewports) { - viewport.setWidth(viewportWidth); - } - } - - /** - * Update viewports to reflect current genomic state, possibly loading additional data. - * - * @param force - if true, force a repaint even if no new data is loaded - * @returns {Promise} - */ - async updateViews() { - - if (!(this.browser && this.browser.referenceFrameList)) return - - const visibleViewports = this.viewports.filter(viewport => viewport.isVisible()); - - // Shift viewports left/right to current genomic state (pans canvas) - visibleViewports.forEach(viewport => viewport.shift()); - - // If dragging (panning) return - if (this.browser.dragObject) { - return - } - - // Filter zoomed out views. This has the side effect or turning off or no the zoomed out notice - const viewportsToRepaint = visibleViewports.filter(vp => vp.needsRepaint()).filter(viewport => viewport.checkZoomIn()); - - // Get viewports that require a data load - const viewportsToReload = viewportsToRepaint.filter(viewport => viewport.needsReload()); - - // Trigger viewport to load features needed to cover current genomic range - // NOTE: these must be loaded synchronously, do not user Promise.all, not all file readers are thread safe - for (let viewport of viewportsToReload) { - await viewport.loadFeatures(); - } - - if (this.disposed) return // Track was removed during load - - // Special case for variant tracks in multilocus view. The # of rows to allocate to the variant (site) - // section depends on data from all the views. We only need to adjust this however if any data was loaded - // (i.e. reloadableViewports.length > 0) - if (this.track && typeof this.track.variantRowCount === 'function' && viewportsToReload.length > 0) { - let maxRow = 0; - for (let viewport of this.viewports) { - if (viewport.featureCache && viewport.featureCache.features) { - maxRow = Math.max(maxRow, viewport.featureCache.features.reduce((a, f) => Math.max(a, f.row || 0), 0)); - } - } - const current = this.track.nVariantRows; - if (current !== maxRow + 1) { - this.track.variantRowCount(maxRow + 1); - for (let viewport of this.viewports) { - viewport.checkContentHeight(); - } - } - } - - if (this.track.autoscale) { - let allFeatures = []; - for (let visibleViewport of visibleViewports) { - const referenceFrame = visibleViewport.referenceFrame; - const start = referenceFrame.start; - const end = start + referenceFrame.toBP(visibleViewport.getWidth()); - if (visibleViewport.featureCache && visibleViewport.featureCache.features) { - // If the "features" object has a getMax function use it. Currently only alignmentContainer implements this, for coverage. - if (typeof visibleViewport.featureCache.features.getMax === 'function') { - const max = visibleViewport.featureCache.features.getMax(start, end); - allFeatures.push({value: max}); - } else { - const viewFeatures = FeatureUtils.findOverlapping(visibleViewport.featureCache.features, start, end); - for (let f of viewFeatures) { - allFeatures.push(f); - } - } - } - } - if (typeof this.track.doAutoscale === 'function') { - this.track.dataRange = this.track.doAutoscale(allFeatures); - } else { - this.track.dataRange = doAutoscale$1(allFeatures); - } - } - - const refreshView = (this.track.autoscale || this.track.autoscaleGroup || this.track.type === 'ruler'); - for (let vp of visibleViewports) { - if (viewportsToRepaint.includes(vp)) { - vp.repaint(); - } else if (refreshView) { - vp.refresh(); - } - } - - this.adjustTrackHeight(); - - // Repaint sample names last - this.repaintSamples(); - - this.updateRulerViewportLabels(); - } - - clearCachedFeatures() { - for (let viewport of this.viewports) { - viewport.clearCache(); - } - } - - updateRulerViewportLabels() { - - const viewportWidth = this.browser.calculateViewportWidth(this.viewports.length); - - for (let viewport of this.viewports) { - if ('ruler' === this.track.type) { - if (this.viewports.length > 1) { - viewport.presentLocusLabel(viewportWidth); - } else { - viewport.dismissLocusLabel(); - } - } - } - - } - - /** - * Return a promise to get all in-view features across all viewports. Used for group autoscaling. - */ - async getInViewFeatures() { - - if (!(this.browser && this.browser.referenceFrameList)) { - return [] - } - - let allFeatures = []; - const visibleViewports = this.viewports.filter(viewport => viewport.isVisible()); - for (let vp of visibleViewports) { - - const referenceFrame = vp.referenceFrame; - const {chr, start, bpPerPixel} = vp.referenceFrame; - const end = start + referenceFrame.toBP(vp.getWidth()); - const needsReload = !vp.featureCache || !vp.featureCache.containsRange(chr, start, end, bpPerPixel); - - if (needsReload) { - await vp.loadFeatures(); - } - if (vp.featureCache && vp.featureCache.features) { - - if (typeof vp.featureCache.features.getMax === 'function') { - const max = vp.featureCache.features.getMax(start, end); - allFeatures.push({value: max}); - } else { - const vpFeatures = typeof vp.featureCache.queryFeatures === 'function' ? - vp.featureCache.queryFeatures(chr, start, end) : - FeatureUtils.findOverlapping(vp.featureCache.features, start, end); - allFeatures = allFeatures.concat(vpFeatures); - } - } - } - return allFeatures - } - - checkContentHeight() { - - for (let viewport of this.viewports) { - viewport.checkContentHeight(); - } - this.adjustTrackHeight(); - - } - - adjustTrackHeight() { - - var contentHeight = this.maxViewportContentHeight(); - if (this.track.autoHeight) { - this.setTrackHeight(contentHeight, false); - } else if (this.track.paintAxis) { // Avoid duplication, paintAxis is already called in setTrackHeight - this.paintAxis(); - } - - if (false === scrollbarExclusionTypes.has(this.track.type)) { - - // Adjust scrollbar, if needed, to insure content is in view - const currentTop = this.viewports[0].getContentTop(); - const viewportHeight = this.viewports[0].$viewport.height(); - const minTop = Math.min(0, viewportHeight - contentHeight); - if(currentTop < minTop) { - for (let viewport of this.viewports) { - viewport.setTop(minTop); - } - } - this.updateScrollbar(); - } - } - - createTrackScrollbar(browser) { - - const outerScroll = domUtils$1.div(); - browser.columnContainer.querySelector('.igv-scrollbar-column').appendChild(outerScroll); - outerScroll.style.height = `${this.track.height}px`; - this.outerScroll = outerScroll; - - if (false === scrollbarExclusionTypes.has(this.track.type)) { - const innerScroll = domUtils$1.div(); - outerScroll.appendChild(innerScroll); - this.innerScroll = innerScroll; - - this.addTrackScrollMouseHandlers(browser); - } - - } - - createTrackDragHandle(browser) { - - const className = 'ideogram' === this.track.type || 'ruler' === this.track.type ? 'igv-track-drag-shim' : 'igv-track-drag-handle'; - this.dragHandle = domUtils$1.div({class: className}); - browser.columnContainer.querySelector('.igv-track-drag-column').appendChild(this.dragHandle); - this.dragHandle.style.height = `${this.track.height}px`; - - this.addTrackDragMouseHandlers(browser); - - } - - createTrackGearPopup(browser) { - - this.gearContainer = domUtils$1.div(); - browser.columnContainer.querySelector('.igv-gear-menu-column').appendChild(this.gearContainer); - this.gearContainer.style.height = `${this.track.height}px`; - - if (true === this.track.ignoreTrackMenu) ; else { - - this.gear = domUtils$1.div(); - this.gearContainer.appendChild(this.gear); - this.gear.appendChild(icons$1$1.createIcon('cog')); - - this.trackGearPopup = new MenuPopup(this.gear); - - this.addTrackGearMouseHandlers(); - } - - } - - addAxisEventListener(axis) { - - this.boundAxisClickHander = axisClickHandler.bind(this); - axis.addEventListener('click', this.boundAxisClickHander); - - function axisClickHandler(event) { - this.browser.dataRangeDialog.configure(this); - this.browser.dataRangeDialog.present($$1(this.browser.columnContainer)); - } - - } - - removeAxisEventListener(axis) { - axis.removeEventListener('click', this.boundAxisClickHander); - } - - addTrackScrollMouseHandlers(browser) { - - // Mouse Down - this.boundTrackScrollMouseDownHandler = trackScrollMouseDownHandler.bind(this); - this.innerScroll.addEventListener('mousedown', this.boundTrackScrollMouseDownHandler); - - function trackScrollMouseDownHandler(event) { - - event.stopPropagation(); - - const {y} = domUtils$1.pageCoordinates(event); - - $$1(this.innerScroll).data('yDown', y.toString()); - - this.boundColumnContainerMouseMoveHandler = columnContainerMouseMoveHandler.bind(this); - browser.columnContainer.addEventListener('mousemove', this.boundColumnContainerMouseMoveHandler); - - function columnContainerMouseMoveHandler(event) { - - event.stopPropagation(); - - const {y} = domUtils$1.pageCoordinates(event); - - this.moveScroller(y - parseInt($$1(this.innerScroll).data('yDown'))); - - $$1(this.innerScroll).data('yDown', y.toString()); - - } - } - - this.boundColumnContainerMouseUpHandler = columnContainerMouseUpHandler.bind(this); - browser.columnContainer.addEventListener('mouseup', this.boundColumnContainerMouseUpHandler); - - function columnContainerMouseUpHandler(event) { - browser.columnContainer.removeEventListener('mousemove', this.boundColumnContainerMouseMoveHandler); - } - - } - - removeTrackScrollMouseHandlers() { - if (false === scrollbarExclusionTypes.has(this.track.type)) { - this.innerScroll.removeEventListener('mousedown', this.boundTrackScrollMouseDownHandler); - this.browser.columnContainer.removeEventListener('mouseup', this.boundColumnContainerMouseUpHandler); - this.browser.columnContainer.removeEventListener('mousemove', this.boundColumnContainerMouseMoveHandler); - } - } - - addTrackDragMouseHandlers(browser) { - - if ('ideogram' === this.track.id || 'ruler' === this.track.id) ; else { - - let currentDragHandle = undefined; - - // Mouse Down - this.boundTrackDragMouseDownHandler = trackDragMouseDownHandler.bind(this); - this.dragHandle.addEventListener('mousedown', this.boundTrackDragMouseDownHandler); - - function trackDragMouseDownHandler(event) { - - event.preventDefault(); - - currentDragHandle = event.target; - currentDragHandle.classList.add('igv-track-drag-handle-hover'); - - browser.startTrackDrag(this); - - } - - // Mouse Up - this.boundDocumentTrackDragMouseUpHandler = documentTrackDragMouseUpHandler.bind(this); - document.addEventListener('mouseup', this.boundDocumentTrackDragMouseUpHandler); - - function documentTrackDragMouseUpHandler(event) { - - browser.endTrackDrag(); - - if (currentDragHandle && event.target !== currentDragHandle) { - currentDragHandle.classList.remove('igv-track-drag-handle-hover'); - } - - currentDragHandle = undefined; - } - - // Mouse Enter - this.boundTrackDragMouseEnterHandler = trackDragMouseEnterHandler.bind(this); - this.dragHandle.addEventListener('mouseenter', this.boundTrackDragMouseEnterHandler); - - function trackDragMouseEnterHandler(event) { - event.preventDefault(); - - if (undefined === currentDragHandle) { - event.target.classList.add('igv-track-drag-handle-hover'); - } - - browser.updateTrackDrag(this); - - } - - // Mouse Out - this.dragHandle.addEventListener('mouseout', e => { - e.preventDefault(); - - if (undefined === currentDragHandle) { - e.target.classList.remove('igv-track-drag-handle-hover'); - } - }); - - this.boundTrackDragMouseOutHandler = trackDragMouseOutHandler.bind(this); - this.dragHandle.addEventListener('mouseout', this.boundTrackDragMouseOutHandler); - - function trackDragMouseOutHandler(event) { - event.preventDefault(); - - if (undefined === currentDragHandle) { - event.target.classList.remove('igv-track-drag-handle-hover'); - } - } - - } - - } - - removeTrackDragMouseHandlers() { - - if ('ideogram' === this.track.id || 'ruler' === this.track.id) ; else { - this.dragHandle.removeEventListener('mousedown', this.boundTrackDragMouseDownHandler); - document.removeEventListener('mouseup', this.boundDocumentTrackDragMouseUpHandler); - this.dragHandle.removeEventListener('mouseup', this.boundTrackDragMouseEnterHandler); - this.dragHandle.removeEventListener('mouseout', this.boundTrackDragMouseOutHandler); - } - - } - - addTrackGearMouseHandlers() { - if (true === this.track.ignoreTrackMenu) ; else { - - this.boundTrackGearClickHandler = trackGearClickHandler.bind(this); - this.gear.addEventListener('click', this.boundTrackGearClickHandler); - - function trackGearClickHandler(event) { - event.preventDefault(); - event.stopPropagation(); - this.trackGearPopup.presentMenuList(MenuUtils$1.trackMenuItemList(this)); - } - - } - - } - - removeTrackGearMouseHandlers() { - if (true === this.track.ignoreTrackMenu) ; else { - this.gear.removeEventListener('click', this.boundTrackGearClickHandler); - } - - } - - /** - * Do any cleanup here - */ - dispose() { - - this.removeAxisEventListener(this.axis); - this.axis.remove(); - - for (let viewport of this.viewports) { - viewport.dispose(); - } - - this.sampleNameViewport.dispose(); - - this.removeTrackScrollMouseHandlers(); - this.outerScroll.remove(); - - this.removeTrackDragMouseHandlers(); - this.dragHandle.remove(); - - this.removeTrackGearMouseHandlers(); - this.gearContainer.remove(); - - if (typeof this.track.dispose === "function") { - this.track.dispose(); - } - - for (let key of Object.keys(this)) { - this[key] = undefined; - } - - if (this.alert) { - this.alert.container.remove(); // This is quite obviously a hack, need a "dispose" method on AlertDialog - } - - this.disposed = true; - } - - paintAxis() { - - if (typeof this.track.paintAxis === 'function') { - - // Set the canvas buffer size, this is the resolution it is drawn at. This is done here in case the browser - // has been drug between screens at different dpi resolutions since the last repaint - const {width, height} = this.axisCanvas.getBoundingClientRect(); - const dpi = window.devicePixelRatio || 1; - this.axisCanvas.height = dpi * height; - this.axisCanvas.width = dpi * width; - - // Get a scaled context to draw aon - const axisCanvasContext = this.axisCanvas.getContext('2d'); - axisCanvasContext.scale(dpi, dpi); - - this.track.paintAxis(axisCanvasContext, width, height); - } - } - - maxViewportContentHeight() { - return Math.max(this.viewports.map(viewport => viewport.getContentHeight())) - } - -} - -function renderSVGAxis(context, track, axisCanvas, deltaX, deltaY) { - - if (typeof track.paintAxis === 'function') { - - const {y, width, height} = axisCanvas.getBoundingClientRect(); - - const str = (track.name || track.id).replace(/\W/g, ''); - const id = `${str}_axis_guid_${domUtils$1.guid()}`; - - context.saveWithTranslationAndClipRect(id, deltaX, y + deltaY, width, height, 0); - - track.paintAxis(context, width, height); - - context.restore(); - } - -} - -/* - * The MIT License (MIT) - * - * Copyright (c) 2014 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -const DEFAULT_COLOR$1 = 'rgb(150, 150, 150)'; - -class WigTrack extends TrackBase { - - static defaults = { - height: 50, - flipAxis: false, - logScale: false, - windowFunction: 'mean', - graphType: 'bar', - autoscale: true, - normalize: undefined, - scaleFactor: undefined - } - - constructor(config, browser) { - super(config, browser); - } - - init(config) { - - super.init(config); - - this.type = "wig"; - this.featureType = 'numeric'; - this.paintAxis = paintAxis; - - const format = config.format ? config.format.toLowerCase() : config.format; - if (config.featureSource) { - this.featureSource = config.featureSource; - delete config.featureSource; - } else if ("bigwig" === format) { - this.featureSource = new BWSource(config, this.browser.genome); - } else if ("tdf" === format) { - this.featureSource = new TDFSource(config, this.browser.genome); - } else { - this.featureSource = FeatureSource(config, this.browser.genome); - } - - - // Override autoscale default - if(config.max === undefined || config.autoscale === true) { - this.autoscale = true; - } else { - this.dataRange = { - min: config.min || 0, - max: config.max - }; - } - } - - async postInit() { - const header = await this.getHeader(); - if (this.disposed) return // This track was removed during async load - if (header) this.setTrackProperties(header); - } - - async getFeatures(chr, start, end, bpPerPixel) { - const features = await this.featureSource.getFeatures({ - chr, - start, - end, - bpPerPixel, - visibilityWindow: this.visibilityWindow, - windowFunction: this.windowFunction - }); - if (this.normalize && this.featureSource.normalizationFactor) { - const scaleFactor = this.featureSource.normalizationFactor; - for (let f of features) { - f.value *= scaleFactor; - } - } - if (this.scaleFactor) { - const scaleFactor = this.scaleFactor; - for (let f of features) { - f.value *= scaleFactor; - } - } - return features - } - - menuItemList() { - let items = []; - - if (this.flipAxis !== undefined) { - items.push('
'); - items.push({ - label: "Flip y-axis", - click: () => { - this.flipAxis = !this.flipAxis; - this.trackView.repaintViews(); - } - }); - } - - items = items.concat(MenuUtils$1.numericDataMenuItems(this.trackView)); - - return items - } - - async getHeader() { - - if (typeof this.featureSource.getHeader === "function") { - this.header = await this.featureSource.getHeader(); - } - return this.header - } - - // TODO: refactor to igvUtils.js - getScaleFactor(min, max, height, logScale) { - const scale = logScale ? height / (Math.log10(max + 1) - (min <= 0 ? 0 : Math.log10(min + 1))) : height / (max - min); - return scale - } - - computeYPixelValue(yValue, yScaleFactor) { - return (this.flipAxis ? (yValue - this.dataRange.min) : (this.dataRange.max - yValue)) * yScaleFactor - } - - computeYPixelValueInLogScale(yValue, yScaleFactor) { - let maxValue = this.dataRange.max; - let minValue = this.dataRange.min; - if (maxValue <= 0) return 0 // TODO: - if (minValue <= -1) minValue = 0; - minValue = (minValue <= 0) ? 0 : Math.log10(minValue + 1); - maxValue = Math.log10(maxValue + 1); - yValue = Math.log10(yValue + 1); - return ((this.flipAxis ? (yValue - minValue) : (maxValue - yValue)) * yScaleFactor) - } - - draw(options) { - - const features = options.features; - const ctx = options.context; - const bpPerPixel = options.bpPerPixel; - const bpStart = options.bpStart; - const pixelWidth = options.pixelWidth; - options.pixelHeight; - const bpEnd = bpStart + pixelWidth * bpPerPixel + 1; - const posColor = this.color || DEFAULT_COLOR$1; - - let baselineColor; - if (typeof posColor === "string" && posColor.startsWith("rgb(")) { - baselineColor = IGVColor.addAlpha(posColor, 0.1); - } - const scaleFactor = this.getScaleFactor(this.dataRange.min, this.dataRange.max, options.pixelHeight, this.logScale); - const yScale = (yValue) => this.logScale - ? this.computeYPixelValueInLogScale(yValue, scaleFactor) - : this.computeYPixelValue(yValue, scaleFactor); - - if (features && features.length > 0) { - - if (this.dataRange.min === undefined) this.dataRange.min = 0; - - // Max can be less than min if config.min is set but max left to autoscale. If that's the case there is - // nothing to paint. - if (this.dataRange.max > this.dataRange.min) { - - let lastPixelEnd = -1; - let lastY; - const y0 = yScale(0); - for (let f of features) { - - if (f.end < bpStart) continue - if (f.start > bpEnd) break - - const x = Math.floor((f.start - bpStart) / bpPerPixel); - if (isNaN(x)) continue - - let y = yScale(f.value); - - const rectEnd = Math.ceil((f.end - bpStart) / bpPerPixel); - const width = Math.max(1, rectEnd - x); - - const color = this.getColorForFeature(f); - - if (this.graphType === "points") { - const pointSize = this.config.pointSize || 3; - const px = x + width / 2; - IGVGraphics.fillCircle(ctx, px, y, pointSize / 2, {"fillStyle": color, "strokeStyle": color}); - - } else if (this.graphType === "line") { - if (lastY != undefined) { - IGVGraphics.strokeLine(ctx, lastPixelEnd, lastY, x, y, { - "fillStyle": color, - "strokeStyle": color - }); - } - IGVGraphics.strokeLine(ctx, x, y, x + width, y, {"fillStyle": color, "strokeStyle": color}); - } else { - const height = y - y0; - IGVGraphics.fillRect(ctx, x, y0, width, height, {fillStyle: color}); - - } - lastPixelEnd = x + width; - lastY = y; - } - - // If the track includes negative values draw a baseline - if (this.dataRange.min < 0) { - const basepx = (this.dataRange.max / (this.dataRange.max - this.dataRange.min)) * options.pixelHeight; - IGVGraphics.strokeLine(ctx, 0, basepx, options.pixelWidth, basepx, {strokeStyle: baselineColor}); - } - } - } - - // Draw guidelines - if (this.config.hasOwnProperty('guideLines')) { - for (let line of this.config.guideLines) { - if (line.hasOwnProperty('color') && line.hasOwnProperty('y') && line.hasOwnProperty('dotted')) { - let y = yScale(line.y); - let props = { - 'strokeStyle': line['color'], - 'strokeWidth': 2 - }; - if (line['dotted']) IGVGraphics.dashedLine(options.context, 0, y, options.pixelWidth, y, 5, props); - else IGVGraphics.strokeLine(options.context, 0, y, options.pixelWidth, y, props); - } - } - } - } - - popupData(clickState, features) { - - if (features === undefined) features = this.clickedFeatures(clickState); - - if (features && features.length > 0) { - - const genomicLocation = clickState.genomicLocation; - const popupData = []; - - // Sort features based on distance from click - features.sort(function (a, b) { - const distA = Math.abs((a.start + a.end) / 2 - genomicLocation); - const distB = Math.abs((b.start + b.end) / 2 - genomicLocation); - return distA - distB - }); - - // Display closest 10 - const displayFeatures = features.length > 10 ? features.slice(0, 10) : features; - - // Resort in ascending order - displayFeatures.sort(function (a, b) { - return a.start - b.start - }); - - for (let selectedFeature of displayFeatures) { - if (selectedFeature) { - if (popupData.length > 0) { - popupData.push('
'); - } - let posString = (selectedFeature.end - selectedFeature.start) === 1 ? - numberFormatter$1(selectedFeature.start + 1) - : numberFormatter$1(selectedFeature.start + 1) + "-" + numberFormatter$1(selectedFeature.end); - popupData.push({name: "Position:", value: posString}); - popupData.push({ - name: "Value:     ", - value: numberFormatter$1(selectedFeature.value) - }); - } - } - if (displayFeatures.length < features.length) { - popupData.push("
..."); - } - - return popupData - - } else { - return [] - } - } - - get supportsWholeGenome() { - return !this.config.indexURL && this.config.supportsWholeGenome !== false - } - - /** - * Return color for feature. - * @param feature - * @returns {string} - */ - - getColorForFeature(f) { - let c = (f.value < 0 && this.altColor) ? this.altColor : this.color || DEFAULT_COLOR$1; - return (typeof c === "function") ? c(f.value) : c - } - - /** - * Called when the track is removed. Do any needed cleanup here - */ - dispose() { - this.trackView = undefined; - } - -} - -/** - * - * @param cs - object containing - * 1) array of threshold values defining bin boundaries in ascending order - * 2) array of colors for bins (length == thresholds.length + 1) - * @constructor - */ -function BinnedColorScale(cs) { - this.thresholds = cs.thresholds; - this.colors = cs.colors; -} - -BinnedColorScale.prototype.getColor = function (value) { - - for (let threshold of this.thresholds) { - if (value < threshold) { - return this.colors[this.thresholds.indexOf(threshold)] - } - } - - return this.colors[this.colors.length - 1] - -}; - -/** - * - * @param scale - object with the following properties - * low - * lowR - * lowG - * lowB - * high - * highR - * highG - * highB - * - * @constructor - */ -function GradientColorScale(scale) { - - this.scale = scale; - this.lowColor = "rgb(" + scale.lowR + "," + scale.lowG + "," + scale.lowB + ")"; - this.highColor = "rgb(" + scale.highR + "," + scale.highG + "," + scale.highB + ")"; - this.diff = scale.high - scale.low; - -} - -GradientColorScale.prototype.getColor = function (value) { - - var scale = this.scale, r, g, b, frac; - - if (value <= scale.low) return this.lowColor - else if (value >= scale.high) return this.highColor - - frac = (value - scale.low) / this.diff; - r = Math.floor(scale.lowR + frac * (scale.highR - scale.lowR)); - g = Math.floor(scale.lowG + frac * (scale.highG - scale.lowG)); - b = Math.floor(scale.lowB + frac * (scale.highB - scale.lowB)); - - return "rgb(" + r + "," + g + "," + b + ")" -}; - -class ConstantColorScale { - constructor(color) { - this.color = color; - } - - getColor() { - return this.color - } -} - -/* - * The MIT License (MIT) - * - * Copyright (c) 2014 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -class SegTrack extends TrackBase { - - constructor(config, browser) { - super(config, browser); - } - - init(config) { - super.init(config); - - this.type = config.type || "seg"; - if (this.type === 'maf') this.type = 'mut'; - this.isLog = config.isLog; - this.displayMode = config.displayMode || "EXPANDED"; // EXPANDED | SQUISHED - this.height = config.height || 300; - this.maxHeight = config.maxHeight || 500; - this.squishedRowHeight = config.sampleSquishHeight || config.squishedRowHeight || 2; - this.expandedRowHeight = config.sampleExpandHeight || config.expandedRowHeight || 13; - this.sampleHeight = this.squishedRowHeight; // Initial value, will get overwritten when rendered - - if (config.color) { - this.color = config.color; - } else { - // Color scales for "seg" (copy number) tracks. - this.posColorScale = config.posColorScale || - new GradientColorScale({ - low: 0.1, - lowR: 255, - lowG: 255, - lowB: 255, - high: 1.5, - highR: 255, - highG: 0, - highB: 0 - }); - this.negColorScale = config.negColorScale || - new GradientColorScale({ - low: -1.5, - lowR: 0, - lowG: 0, - lowB: 255, - high: -0.1, - highR: 255, - highG: 255, - highB: 255 - }); - - // Default color table for mutation (mut and maf) tracks - if (this.type === "mut") { - this.colorTable = new ColorTable(config.colorTable || MUT_COLORS); - } - } - - this.sampleKeys = []; - this.sampleNames = new Map(); - if (config.samples) { - // Explicit setting, keys == names - for (let s of config.samples) { - this.sampleKeys.push(s); - this.sampleNames.set(s, s); - } - this.explicitSamples = true; - } - - // this.featureSource = config.sourceType === "bigquery" ? - // new igv.BigQueryFeatureSource(this.config) : - - // Disable whole genome downsampling unless explicitly. - const configCopy = Object.assign({}, this.config); - configCopy.maxWGCount = configCopy.maxWGCount || Number.MAX_SAFE_INTEGER; - this.featureSource = FeatureSource(configCopy, this.browser.genome); - - this.initialSort = config.sort; - } - - async postInit() { - if (typeof this.featureSource.getHeader === "function") { - this.header = await this.featureSource.getHeader(); - if(this.disposed) return; // This track was removed during async load - } - // Set properties from track line - if (this.header) { - this.setTrackProperties(this.header); - } - } - - - menuItemList() { - - const menuItems = []; - const lut = - { - "SQUISHED": "Squish", - "EXPANDED": "Expand", - "FILL": "Fill" - }; - - menuItems.push('
'); - menuItems.push("DisplayMode:"); - - const displayOptions = this.type === 'seg' ? ["SQUISHED", "EXPANDED", "FILL"] : ["SQUISHED", "EXPANDED"]; - - for (let displayMode of displayOptions) { - - const checkBox = createCheckbox$2(lut[displayMode], displayMode === this.displayMode); - menuItems.push( - { - object: $$1(checkBox), - click: () => { - this.displayMode = displayMode; - this.config.displayMode = displayMode; - this.trackView.checkContentHeight(); - this.trackView.repaintViews(); - this.trackView.moveScroller(this.trackView.sampleNameViewport.trackScrollDelta); - } - }); - } - - return menuItems - - } - - hasSamples() { - return true // SEG, MUT, and MAF tracks have samples by definition - } - - getSamples() { - return { - names: this.sampleKeys.map(key => this.sampleNames.get(key)), - height: this.sampleHeight, - yOffset: 0 - } - } - - async getFeatures(chr, start, end) { - const features = await this.featureSource.getFeatures({chr, start, end}); - if (this.initialSort) { - const sort = this.initialSort; - this.sortSamples(sort.chr, sort.start, sort.end, sort.direction, features); - this.initialSort = undefined; // Sample order is sorted, - } - return features - } - - - draw({context, renderSVG, pixelTop, pixelWidth, pixelHeight, features, bpPerPixel, bpStart}) { - - IGVGraphics.fillRect(context, 0, pixelTop, pixelWidth, pixelHeight, {'fillStyle': "rgb(255, 255, 255)"}); - - if (features && features.length > 0) { - - this.checkForLog(features); - - // New segments could conceivably add new samples - this.updateSampleKeys(features); - - // Create a map for fast id -> row lookup - const samples = {}; - this.sampleKeys.forEach(function (id, index) { - samples[id] = index; - }); - - let border; - switch (this.displayMode) { - case "FILL": - this.sampleHeight = pixelHeight / this.sampleKeys.length; - border = 0; - break - - case "SQUISHED": - this.sampleHeight = this.squishedRowHeight; - border = 0; - break - default: // EXPANDED - this.sampleHeight = this.expandedRowHeight; - border = 1; - } - const rowHeight = this.sampleHeight; - - - // this.featureMap = new Map() - - for (let segment of features) { - segment.pixelRect = undefined; // !important, reset this in case segment is not drawn - } - - const pixelBottom = pixelTop + pixelHeight; - const bpEnd = bpStart + pixelWidth * bpPerPixel + 1; - const xScale = bpPerPixel; - - this.sampleYStart = undefined; - for (let f of features) { - - if (f.end < bpStart) continue - if (f.start > bpEnd) break - - const sampleKey = f.sampleKey || f.sample; - f.row = samples[sampleKey]; - const y = f.row * rowHeight + border; - - if (undefined === this.sampleYStart) { - this.sampleYStart = y; - } - - const bottom = y + rowHeight; - - if (bottom < pixelTop || y > pixelBottom) { - continue - } - - const segmentStart = Math.max(f.start, bpStart); - // const segmentStart = segment.start; - let x = Math.round((segmentStart - bpStart) / xScale); - - const segmentEnd = Math.min(f.end, bpEnd); - // const segmentEnd = segment.end; - const x1 = Math.round((segmentEnd - bpStart) / xScale); - let w = Math.max(1, x1 - x); - - let color; - if (this.color) { - if (typeof this.color === "function") { - color = this.color(f); - } else { - color = this.color; - } - } else if (this.colorTable) { - color = this.colorTable.getColor(f.value.toLowerCase()); - } - - let h; - if ("mut" === this.type) { - h = rowHeight - 2 * border; - if (w < 3) { - w = 3; - x -= 1; - } - } else { - // Assume seg track - let value = f.value; - if (!this.isLog) { - value = IGVMath.log2(value / 2); - } - if (value < -0.1) { - color = this.negColorScale.getColor(value); - } else if (value > 0.1) { - color = this.posColorScale.getColor(value); - } else { - color = "white"; - } - - let sh = rowHeight; - if (rowHeight < 0.25) { - const f = 0.1 + 2 * Math.abs(value); - sh = Math.min(1, f * rowHeight); - } - h = sh - 2 * border; - } - - - f.pixelRect = {x, y, w, h}; - - // Use for diagnostic rendering - // context.fillStyle = randomRGB(180, 240) - // context.fillStyle = randomGrey(200, 255) - context.fillStyle = color; - context.fillRect(x, y, w, h); - } - - } - - } - - - checkForLog(features) { - if (this.isLog === undefined) { - this.isLog = false; - for (let feature of features) { - if (feature.value < 0) { - this.isLog = true; - return - } - } - } - } - - /** - * Optional method to compute pixel height to accomodate the list of features. The implementation below - * has side effects (modifiying the samples hash). This is unfortunate, but harmless. - * - * Note displayMode "FILL" is handled by the viewport - * - * @param features - * @returns {number} - */ - computePixelHeight(features) { - if (!features) return 0 - const sampleHeight = ("SQUISHED" === this.displayMode) ? this.squishedRowHeight : this.expandedRowHeight; - this.updateSampleKeys(features); - return this.sampleKeys.length * sampleHeight - } - - /** - * Sort samples by the average value over the genomic range in the direction indicated (1 = ascending, -1 descending) - */ - async sortSamples(chr, start, end, direction, featureList) { - - if (!featureList) { - featureList = await this.featureSource.getFeatures({chr, start, end}); - } - if (!featureList) return - - this.updateSampleKeys(featureList); - - const scores = {}; - const d2 = (direction === "ASC" ? 1 : -1); - - const sortSeg = () => { - // Compute weighted average score for each sample - const bpLength = end - start + 1; - for (let segment of featureList) { - if (segment.end < start) continue - if (segment.start > end) break - const min = Math.max(start, segment.start); - const max = Math.min(end, segment.end); - const f = (max - min) / bpLength; - const sampleKey = segment.sampleKey || segment.sample; - const s = scores[sampleKey] || 0; - scores[sampleKey] = s + f * segment.value; - } - - // Now sort sample names by score - this.sampleKeys.sort(function (a, b) { - let s1 = scores[a]; - let s2 = scores[b]; - if (!s1) s1 = d2 * Number.MAX_VALUE; - if (!s2) s2 = d2 * Number.MAX_VALUE; - if (s1 === s2) return 0 - else if (s1 > s2) return d2 - else return d2 * -1 - }); - }; - - const sortMut = () => { - // Compute weighted average score for each sample - for (let segment of featureList) { - if (segment.end < start) continue - if (segment.start > end) break - const sampleKey = segment.sampleKey || segment.sample; - if (!scores.hasOwnProperty(sampleKey) || segment.value.localeCompare(scores[sampleKey]) > 0) { - scores[sampleKey] = segment.value; - } - } - // Now sort sample names by score - this.sampleKeys.sort(function (a, b) { - let sa = scores[a] || ""; - let sb = scores[b] || ""; - return d2 * (sa.localeCompare(sb)) - }); - }; - - if ("mut" === this.type) { - sortMut(); - } else { - sortSeg(); - } - - this.trackView.repaintViews(); - - } - - clickedFeatures(clickState) { - - const allFeatures = super.clickedFeatures(clickState); - const y = clickState.y; - return allFeatures.filter(function (feature) { - const rect = feature.pixelRect; - return rect && y >= rect.y && y <= (rect.y + rect.h) - }) - - } - - hoverText(clickState) { - const features = this.clickedFeatures(clickState); - if(features && features.length > 0) { - return `${features[0].sample}: ${features[0].value}` - } - } - - popupData(clickState, featureList) { - - if(featureList === undefined) featureList = this.clickedFeatures(clickState); - - const items = []; - - for (let feature of featureList) { - - // Double line divider between features - if (items.length > 0) { - items.push('
'); - items.push('
'); - } - - // hack for whole genome features, which save the original feature as "_f" - const f = feature._f || feature; - - const data = (typeof f.popupData === 'function') ? - f.popupData(this.type, this.browser.genome.id) : - this.extractPopupData(f); - Array.prototype.push.apply(items, data); - - } - - return items - } - - contextMenuItemList(clickState) { - - const referenceFrame = clickState.viewport.referenceFrame; - const genomicLocation = clickState.genomicLocation; - - // Define a region 5 "pixels" wide in genomic coordinates - const sortDirection = this.config.sort ? - (this.config.sort.direction === "ASC" ? "DESC" : "ASC") : // Toggle from previous sort - "DESC"; - const bpWidth = referenceFrame.toBP(2.5); - - const sortHandler = (sort) => { - const viewport = clickState.viewport; - const features = viewport.cachedFeatures; - this.sortSamples(sort.chr, sort.start, sort.end, sort.direction, features); - }; - - const sortLabel = this.type === 'seg' ? 'Sort by value' : 'Sort by type'; - - return [ - { - label: sortLabel, click: (e) => { - - - const sort = { - direction: sortDirection, - chr: clickState.viewport.referenceFrame.chr, - start: genomicLocation - bpWidth, - end: genomicLocation + bpWidth - - }; - - sortHandler(sort); - - this.config.sort = sort; - - } - }] - - } - - get supportsWholeGenome() { - return (this.config.indexed === false || !this.config.indexURL) && this.config.supportsWholeGenome !== false - } - - updateSampleKeys(featureList) { - - if (this.explicitSamples) return - - for (let feature of featureList) { - const sampleKey = feature.sampleKey || feature.sample; - if (!this.sampleNames.has(sampleKey)) { - this.sampleNames.set(sampleKey, feature.sample); - this.sampleKeys.push(sampleKey); - } - } - } -} - -// Mut and MAF file default color table - -const MUT_COLORS = { - - "indel": "rgb(0,200,0)", - "targeted region": "rgb(236,155,43)", - "truncating": "rgb( 150,0,0)", - "non-coding transcript": "rgb(0,0,150)", - - // Colors from https://www.nature.com/articles/nature11404 - "synonymous": "rgb(109,165,95)", - "silent": "rgb(109,135,80)", - "missense_mutation": "rgb(72,130,187)", - "missense": "rgb(72,130,187)", - "splice site": "rgb(143,83,155)", - "splice_region": "rgb(143,83,155)", - "nonsense": "rgb(216, 57,81)", - "nonsense_mutation": "rgb(216, 57,81)", - "frame_shift_del": "rgb(226,135,65)", - "frame_shift_ins": "rgb(226,135,65)", - "in_frame_del": "rgb(247,235,94)", - "in_frame_ins": "rgb(247,235,94)", - "*other*": "rgb(159,91,50)" - // - // 3'Flank - // 3'UTR - // 5'Flank - // 5'UTR - // Frame_Shift_Del - // Frame_Shift_Ins - // IGR - // In_Frame_Del - // In_Frame_Ins - // Intron - // Missense_Mutation - // Nonsense_Mutation - // Nonstop_Mutation - // RNA - // Silent - // Splice_Region - // Splice_Site - // Translation_Start_Site - // Variant_Classification - -}; - -/* - * The MIT License (MIT) - * - * Copyright (c) 2016-2017 The Regents of the University of California - * Author: Jim Robinson - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - -/** - * Represents 2 or more wig tracks overlaid on a common viewport. - */ -class MergedTrack extends TrackBase { - - constructor(config, browser) { - super(config, browser); - this.type = "merged"; - this.featureType = 'numeric'; - this.paintAxis = paintAxis; - this.graphType = config.graphType; - } - - init(config) { - if (!config.tracks) { - throw Error("Error: no tracks defined for merged track" + config) - } - - super.init(config); - } - - async postInit() { - - this.tracks = []; - const p = []; - for (let tconf of this.config.tracks) { - tconf.isMergedTrack = true; - const t = await this.browser.createTrack(tconf); - if (t) { - t.autoscale = false; // Scaling done from merged track - this.tracks.push(t); - } else { - console.warn("Could not create track " + tconf); - } - - if (typeof t.postInit === 'function') { - p.push(t.postInit()); - } - } - - this.flipAxis = this.config.flipAxis ? this.config.flipAxis : false; - this.logScale = this.config.logScale ? this.config.logScale : false; - this.autoscale = this.config.autoscale || this.config.max === undefined; - if (!this.autoscale) { - this.dataRange = { - min: this.config.min || 0, - max: this.config.max - }; - } - for (let t of this.tracks) { - t.autoscale = false; - t.dataRange = this.dataRange; - } - - this.height = this.config.height || 50; - - return Promise.all(p) - } - - get height() { - return this._height - } - - set height(h) { - this._height = h; - if (this.tracks) { - for (let t of this.tracks) { - t.height = h; - t.config.height = h; - } - } - } - - menuItemList() { - let items = []; - if (this.flipAxis !== undefined) { - items.push({ - label: "Flip y-axis", - click: () => { - this.flipAxis = !this.flipAxis; - this.trackView.repaintViews(); - } - }); - } - - items = items.concat(MenuUtils$1.numericDataMenuItems(this.trackView)); - - return items - } - - /** - * Returns a MergedFeatureCollection containing an array of features for the specified range, 1 for each track. - */ - async getFeatures(chr, bpStart, bpEnd, bpPerPixel) { - - const promises = this.tracks.map((t) => t.getFeatures(chr, bpStart, bpEnd, bpPerPixel)); - const featureArrays = await Promise.all(promises); - return new MergedFeatureCollection(featureArrays) - } - - draw(options) { - - const mergedFeatures = options.features; // A MergedFeatureCollection - - for (let i = 0, len = this.tracks.length; i < len; i++) { - const trackOptions = Object.assign({}, options); - trackOptions.features = mergedFeatures.featureArrays[i]; - this.tracks[i].dataRange = this.dataRange; - this.tracks[i].flipAxis = this.flipAxis; - this.tracks[i].logScale = this.logScale; - if (this.graphType) { - this.tracks[i].graphType = this.graphType; - } - this.tracks[i].draw(trackOptions); - } - } - - popupData(clickState) { - - if(clickState.viewport && clickState.viewport.cachedFeatures) { - - const featuresArray = clickState.viewport.cachedFeatures.featureArrays; - - if (featuresArray && featuresArray.length === this.tracks.length) { - // Array of feature arrays, 1 for each track - const popupData = []; - for (let i = 0; i < this.tracks.length; i++) { - if (i > 0) popupData.push('
'); - popupData.push(`
${this.tracks[i].name}
`); - const trackPopupData = this.tracks[i].popupData(clickState, featuresArray[i]); - popupData.push(...trackPopupData); - - } - return popupData - } - } - } - - clickedFeatures(clickState) { - - - // We use the cached features rather than method to avoid async load. If the - // feature is not already loaded this won't work, but the user wouldn't be mousing over it either. - const mergedFeaturesCollection = clickState.viewport.cachedFeatures; - - if(!mergedFeaturesCollection) { - return []; - } - - const genomicLocation = clickState.genomicLocation; - const clickedFeatures = []; - for(let features of mergedFeaturesCollection.featureArrays) { - // When zoomed out we need some tolerance around genomicLocation - const tolerance = (clickState.referenceFrame.bpPerPixel > 0.2) ? 3 * clickState.referenceFrame.bpPerPixel : 0.2; - const ss = genomicLocation - tolerance; - const ee = genomicLocation + tolerance; - const tmp = (FeatureUtils.findOverlapping(features, ss, ee)); - for(let f of tmp) { - clickedFeatures.push(f); - } - } - return clickedFeatures; - } - - - get supportsWholeGenome() { - return this.tracks.every(track => track.supportsWholeGenome) - } -} - - -class MergedFeatureCollection { - - constructor(featureArrays) { - this.featureArrays = featureArrays; - } - - getMax(start, end) { - let max = -Number.MAX_VALUE; - for (let a of this.featureArrays) { - for (let f of a) { - if (typeof f.value !== 'undefined' && !Number.isNaN(f.value)) { - if (f.end < start) { - continue - } - if (f.start > end) { - break - } - max = Math.max(max, f.value); - } - } - } - return max - } - -} - -/* - * The MIT License (MIT) - * - * Copyright (c) 2016-2018 The Regents of the University of California - * Author: Jim Robinson - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -function getArcType(config) { - if (!config.arcType) { - return "nested" - } - switch (config.arcType) { - case "chiapet": - return "inView" - case "chiapetoutbound": - return "partialInView" - default: - return config.arcType - } -} - -const DEFAULT_ARC_COLOR = "rgb(180,25,137)"; - -class InteractionTrack extends TrackBase { - - static defaults = { - height: 250, - theta: Math.PI / 4, - arcOrientation: true, - showBlocks: true, - blockHeight: 3, - thickness: 1, - alpha: 0.02, - logScale: true, - } - - constructor(config, browser) { - super(config, browser); - } - - init(config) { - - super.init(config); - - this.sinTheta = Math.sin(this.theta); - this.cosTheta = Math.cos(this.theta); - this.arcType = getArcType(config); // nested | proportional | inView | partialInView - this.alpha = config.alpha || 0.02; // was: 0.15 - this.painter = {flipAxis: !this.arcOrientation, dataRange: this.dataRange, paintAxis: paintAxis}; - - if (config.valueColumn) { - this.valueColumn = config.valueColumn; - this.hasValue = true; - } else if (config.useScore) { - this.hasValue = true; - this.valueColumn = "score"; - } - - if (config.max) { - this.dataRange = { - min: config.min || 0, - max: config.max - }; - this.autoscale = false; - } else { - this.autoscale = true; - } - - // Create the FeatureSource and override the default whole genome method - if (config.featureSource) { - this.featureSource = config.featureSource; - delete config._featureSource; - } else { - this.featureSource = FeatureSource(config, this.browser.genome); - this.featureSource.getWGFeatures = getWGFeatures; - } - } - - async postInit() { - - if (typeof this.featureSource.getHeader === "function") { - this.header = await this.featureSource.getHeader(); - if (this.disposed) return; // This track was removed during async load - } - - // Set properties from track line - if (this.header) { - this.setTrackProperties(this.header); - } - - if (this.visibilityWindow === undefined && typeof this.featureSource.defaultVisibilityWindow === 'function') { - this.visibilityWindow = await this.featureSource.defaultVisibilityWindow(); - this.featureSource.visibilityWindow = this.visibilityWindow; // <- this looks odd - } - - return this - } - - get supportsWholeGenome() { - return true - } - - async getFeatures(chr, start, end) { - const visibilityWindow = this.visibilityWindow; - const features = await this.featureSource.getFeatures({chr, start, end, visibilityWindow}); - - // Check for score or value - if (this.hasValue === undefined && features && features.length > 0) { - this.hasValue = features[0].score !== undefined; - } - - return features - } - - draw(options) { - - if (this.arcType === "proportional") { - this.drawProportional(options); - } else if (this.arcType === "inView" || this.arcType === "partialInView") { - this.drawProportional(options); - } else { - this.drawNested(options); - } - } - - drawNested(options) { - - const ctx = options.context; - const pixelWidth = options.pixelWidth; - const pixelHeight = options.pixelHeight; - const viewportWidth = options.viewportWidth; - const bpPerPixel = options.bpPerPixel; - const bpStart = options.bpStart; - const xScale = bpPerPixel; - - IGVGraphics.fillRect(ctx, 0, options.pixelTop, pixelWidth, pixelHeight, {'fillStyle': "rgb(255, 255, 255)"}); - - const featureList = options.features; - - if (featureList) { - - // Autoscale theta - autoscaleNested.call(this); - const y = this.arcOrientation ? options.pixelHeight : 0; - const direction = this.arcOrientation; - - ctx.font = "8px sans-serif"; - ctx.textAlign = "center"; - - for (let feature of featureList) { - - // Reset transient property drawState. An undefined value => feature has not been drawn. - feature.drawState = undefined; - - let color; - if (typeof this.color === 'function') { - color = this.color(feature); - } else { - color = this.color || feature.color || DEFAULT_ARC_COLOR; - if (color && this.config.useScore) { - color = getAlphaColor(color, scoreShade(feature.score)); - } - } - - ctx.lineWidth = feature.thickness || this.thickness || 1; - - if (feature.chr1 === feature.chr2 || feature.chr === 'all') { - - const {m1, m2} = getMidpoints(feature, this.browser.genome); - - let pixelStart = Math.round((m1 - bpStart) / xScale); - let pixelEnd = Math.round((m2 - bpStart) / xScale); - if (pixelEnd < 0 || pixelStart > pixelWidth) continue - - let w = (pixelEnd - pixelStart); - if (w < 3) { - w = 3; - pixelStart--; - } - - const a = w / 2; - const r = a / this.sinTheta; - const b = this.cosTheta * r; - const xc = pixelStart + a; - - let yc, startAngle, endAngle; - if (direction) { // UP - yc = this.height + b; - startAngle = Math.PI + Math.PI / 2 - this.theta; - endAngle = Math.PI + Math.PI / 2 + this.theta; - } else { // DOWN - yc = -b; - startAngle = Math.PI / 2 - this.theta; - endAngle = Math.PI / 2 + this.theta; - } - - if (this.showBlocks && feature.chr !== 'all') { - const s1 = (feature.start1 - bpStart) / xScale; - const e1 = (feature.end1 - bpStart) / xScale; - const s2 = (feature.start2 - bpStart) / xScale; - const e2 = (feature.end2 - bpStart) / xScale; - const hb = this.arcOrientation ? -this.blockHeight : this.blockHeight; - ctx.fillRect(s1, y, e1 - s1, hb); - ctx.fillRect(s2, y, e2 - s2, hb); - } - - // Alpha shade (de-emphasize) arcs that extend beyond viewport, unless alpha shading is used for score. - if (color && !this.config.useScore && w > viewportWidth) { - color = getAlphaColor(color, this.alpha); - } - ctx.strokeStyle = color; - ctx.fillStyle = color; - ctx.beginPath(); - ctx.arc(xc, yc, r, startAngle, endAngle, false); - ctx.stroke(); - feature.drawState = {xc, yc, r}; - } else { - - let pixelStart = Math.round((feature.start - bpStart) / xScale); - let pixelEnd = Math.round((feature.end - bpStart) / xScale); - if (pixelEnd < 0 || pixelStart > pixelWidth) continue - - let w = (pixelEnd - pixelStart); - if (w < 3) { - w = 3; - pixelStart--; - } - const otherChr = feature.chr === feature.chr1 ? feature.chr2 : feature.chr1; - ctx.strokeStyle = color; - // get a sense of trans "spread" - ctx.fillStyle = getAlphaColor(getChrColor(otherChr), 0.5); - // ctx.fillStyle = color - - if (direction) { - // UP - ctx.fillRect(pixelStart, this.height / 2, w, this.height / 2); - ctx.fillText(otherChr, pixelStart + w / 2, this.height / 2 - 5); - feature.drawState = {x: pixelStart, y: this.height / 2, w: w, h: this.height / 2}; - } else { - ctx.fillRect(pixelStart, 0, w, this.height / 2); - ctx.fillText(otherChr, pixelStart + w / 2, this.height / 2 + 13); - feature.drawState = {x: pixelStart, y: 0, w: w, h: this.height / 2}; - } - } - } - } - - function autoscaleNested() { - let max = 0; - for (let feature of featureList) { - let pixelStart = (feature.start - bpStart) / xScale; - let pixelEnd = (feature.end - bpStart) / xScale; - if (pixelStart >= 0 && pixelEnd <= pixelWidth) { - max = Math.max(max, pixelEnd - pixelStart); - } - } - let a = Math.min(viewportWidth, max) / 2; - if (max > 0) { - let coa = (pixelHeight - 10) / a; - this.theta = estimateTheta(coa); - this.sinTheta = Math.sin(this.theta); - this.cosTheta = Math.cos(this.theta); - } - } - } - - getScaleFactor(min, max, height, logScale) { - const scale = logScale ? height / (Math.log10(max + 1) - (min <= 0 ? 0 : Math.log10(min + 1))) : height / (max - min); - return scale - } - - drawProportional(options) { - - const ctx = options.context; - const pixelWidth = options.pixelWidth; - const pixelHeight = options.pixelHeight; - const bpPerPixel = options.bpPerPixel; - const bpStart = options.bpStart; - const xScale = bpPerPixel; - const refStart = options.referenceFrame.start; - const refEnd = options.referenceFrame.end; - - - IGVGraphics.fillRect(ctx, 0, options.pixelTop, pixelWidth, pixelHeight, {'fillStyle': "rgb(255, 255, 255)"}); - - const featureList = options.features; - - if (featureList && featureList.length > 0) { - - // we use the min as a filter but not moving the axis - const effectiveMin = 0; - const yScale = this.getScaleFactor(effectiveMin, this.dataRange.max, options.pixelHeight - 1, this.logScale); - const y = this.arcOrientation ? options.pixelHeight : 0; - - for (let feature of featureList) { - - // Reset transient property drawState. An undefined value => feature has not been drawn. - feature.drawState = undefined; - - const value = this.valueColumn ? feature[this.valueColumn] : feature.score; - if (value === undefined || Number.isNaN(value)) continue - - const radiusY = Math.round((this.logScale ? Math.log10(value + 1) : value) * yScale); - - if (feature.chr1 === feature.chr2 || feature.chr === 'all') { - - const {m1, m2} = getMidpoints(feature, this.browser.genome); - - let pixelStart = Math.round((m1 - bpStart) / xScale); - let pixelEnd = Math.round((m2 - bpStart) / xScale); - let w = (pixelEnd - pixelStart); - if (w < 3) { - w = 3; - pixelStart--; - } - - // Various filters - if (value < this.dataRange.min || value > this.dataRange.max) continue - if ("proportional" !== this.arcType) { - const showOutbound = (this.arcType === "partialInView"); - const within = (m1 >= refStart && m2 <= refEnd); - let outBound = false; - let inBound = false; - if (!within && showOutbound) { - outBound = (refStart <= m1 && m1 <= refEnd); - if (!outBound) inBound = (refStart <= m2 && m2 <= refEnd); - } - if (!(within || outBound || inBound)) continue - } - - - const radiusX = w / 2; - const xc = pixelStart + w / 2; - feature.drawState = {xc, yc: y, radiusX, radiusY}; - - // const arcKey = ((pixelStart << 16) | pixelEnd) - // let arc = arcCaches.get(arcKey) - // if (arc !== undefined) { - // if (arc.has(radiusY)) { - // continue - // } - // arc.add(radiusY) - // } else { - // let arcHeights = new Set() - // arcHeights.add(radiusY) - // arcCaches.set(arcKey, arcHeights) - // } - - const counterClockwise = this.arcOrientation ? true : false; - const color = feature.color || this.color; - ctx.strokeStyle = color; - ctx.lineWidth = feature.thickness || this.thickness || 1; - - if (true === ctx.isSVG) { - ctx.strokeEllipse(xc, y, radiusX, radiusY, 0, 0, Math.PI, counterClockwise); - } else { - ctx.beginPath(); - ctx.ellipse(xc, y, radiusX, radiusY, 0, 0, Math.PI, counterClockwise); - ctx.stroke(); - } - - if (this.alpha) { - ctx.fillStyle = getAlphaColor(color, this.alpha); - if (true === ctx.isSVG) { - ctx.fillEllipse(xc, y, radiusX, radiusY, 0, 0, Math.PI, counterClockwise); - } else { - ctx.fill(); - } - } - - if (this.showBlocks && feature.chr !== 'all') { - ctx.fillStyle = color; - const s1 = (feature.start1 - bpStart) / xScale; - const e1 = (feature.end1 - bpStart) / xScale; - const s2 = (feature.start2 - bpStart) / xScale; - const e2 = (feature.end2 - bpStart) / xScale; - const hb = this.arcOrientation ? -this.blockHeight : this.blockHeight; - ctx.fillRect(s1, y, e1 - s1, hb); - ctx.fillRect(s2, y, e2 - s2, hb); - } - - } else { - // Inter chromosome - let pixelStart = Math.round((feature.start - bpStart) / xScale); - let pixelEnd = Math.round((feature.end - bpStart) / xScale); - if (pixelEnd < 0 || pixelStart > pixelWidth || value < this.dataRange.min || value > this.dataRange.max) continue - - const h = Math.min(radiusY, this.height - 13); // Leave room for text - let w = (pixelEnd - pixelStart); - if (w < 3) { - w = 3; - pixelStart--; - } - const otherChr = feature.chr === feature.chr1 ? feature.chr2 : feature.chr1; - ctx.font = "8px sans-serif"; - ctx.textAlign = "center"; - // get a sense of trans "spread" - ctx.fillStyle = getAlphaColor(getChrColor(otherChr), 0.5); - if (this.arcOrientation) { - // UP - const y = this.height - h; - ctx.fillRect(pixelStart, y, w, h); - ctx.fillText(otherChr, pixelStart + w / 2, y - 5); - feature.drawState = {x: pixelStart, y, w, h}; - } else { - ctx.fillRect(pixelStart, 0, w, h); - ctx.fillText(otherChr, pixelStart + w / 2, h + 13); - feature.drawState = {x: pixelStart, y: 0, w, h}; - } - } - } - } - } - - clearAxis(ctx, pixelWidth, pixelHeight) { - IGVGraphics.fillRect(ctx, 0, 0, pixelWidth, pixelHeight, {'fillStyle': "rgb(255, 255, 255)"}); - } - - paintAxis(ctx, pixelWidth, pixelHeight) { - // dataRane is interpreted differently for interactino tracks -- all arcs are drawn from "zero", irrespective of dataRange.min - const axisRange = {min: 0, max: this.dataRange.max}; - if (this.arcType === "proportional") { - this.painter.flipAxis = !this.arcOrientation; - this.painter.dataRange = axisRange; - this.painter.paintAxis(ctx, pixelWidth, pixelHeight); - } else if (this.arcType === "inView" || this.arcType === "partialInView") { - this.painter.flipAxis = !this.arcOrientation; - this.painter.dataRange = axisRange; - this.painter.paintAxis(ctx, pixelWidth, pixelHeight); - } else { - this.clearAxis(ctx, pixelWidth, pixelHeight); - } - } - - menuItemList() { - - let items = []; - - if (this.hasValue) { - items.push("
"); - const lut = - { - "nested": "Nested", - "proportional": "Proportional - All", - "inView": "Proportional - Both Ends in View", - "partialInView": "Proportional - One End in View" - }; - items.push("Arc Type"); - for (let arcType of ["nested", "proportional", "inView", "partialInView"]) { - items.push( - { - object: $$1(createCheckbox$2(lut[arcType], arcType === this.arcType)), - click: () => { - this.arcType = arcType; - this.trackView.repaintViews(); - } - }); - } - } - items.push("
"); - - items.push({ - name: "Toggle arc direction", - click: () => { - this.arcOrientation = !this.arcOrientation; - this.trackView.repaintViews(); - } - }); - items.push({ - name: this.showBlocks ? "Hide Blocks" : "Show Blocks", - click: () => { - this.showBlocks = !this.showBlocks; - this.trackView.repaintViews(); - } - }); - - - if (this.arcType === "proportional" || this.arcType === "inView" || this.arcType === "partialInView") { - // MenuUtils.numericDataMenuItems(this.trackView).forEach(item => items.push(item)) - items = items.concat(MenuUtils$1.numericDataMenuItems(this.trackView)); - } - - if (this.browser.circularView) { - items.push('
'); - items.push({ - label: 'Add interactions to circular view', - click: () => { - for (let viewport of this.trackView.viewports) { - this.addChordsForViewport(viewport.referenceFrame); - } - } - }); - } - - return items - } - - contextMenuItemList(clickState) { - - // Experimental JBrowse feature - if (this.browser.circularView) { - const viewport = clickState.viewport; - const list = []; - - list.push({ - label: 'Add interactions to circular view', - click: () => { - const refFrame = viewport.referenceFrame; - // first pass: to get all the relevant features - this.addChordsForViewport(refFrame); - } - }); - - list.push('
'); - return list - } - } - - /** - * Add chords to the circular view for the given viewport, represented by its reference frame - * @param refFrame - */ - addChordsForViewport(refFrame) { - const cachedFeatures = "all" === refFrame.chr ? - this.featureSource.getAllFeatures() : - this.featureSource.featureCache.queryFeatures(refFrame.chr, refFrame.start, refFrame.end); - - // inView features are simply features that have been drawn, i.e. have a drawState - const inView = cachedFeatures.filter(f => f.drawState); - if (inView.length === 0) return; - - const chords = makeBedPEChords(inView); - sendChords(chords, this, refFrame, 0.5); - // - // - // // for filtered set, distinguishing the chromosomes is more critical than tracks - // const chordSetColor = IGVColor.addAlpha("all" === refFrame.chr ? this.color : getChrColor(refFrame.chr), 0.5) - // const trackColor = IGVColor.addAlpha(this.color, 0.5) - // - // // name the chord set to include locus and filtering information - // const encodedName = this.name.replaceAll(' ', '%20') - // const chordSetName = "all" === refFrame.chr ? - // encodedName : - // `${encodedName} (${refFrame.chr}:${refFrame.start}-${refFrame.end} ; range:${this.dataRange.min}-${this.dataRange.max})` - // this.browser.circularView.addChords(chords, {track: chordSetName, color: chordSetColor, trackColor: trackColor}) - } - - doAutoscale(features) { - - // if ("proportional" === this.arcType) { - let max = 0; - if (features) { - for (let f of features) { - const v = this.valueColumn ? f[this.valueColumn] : f.score; - if (!Number.isNaN(v)) { - max = Math.max(max, v); - } - } - } - return {min: 0, max: max} - // } - } - - popupData(clickState, features) { - - if (features === undefined) features = this.clickedFeatures(clickState); - - const data = []; - for (let feature of features) { - - const f = feature._ || feature; // For "whole genome" features, which keeps a pointer to the original - - data.push({name: "Region 1", value: positionString(f.chr1, f.start1, f.end1, f.strand1)}); - data.push({name: "Region 2", value: positionString(f.chr2, f.start2, f.end2, f.strand2)}); - if (f.name) { - data.push({name: "Name", value: f.name}); - } - if (f.value !== undefined) { - data.push({name: "Value", value: f.value}); - } - if (f.score !== undefined) { - data.push({name: "Score", value: f.score}); - } - - - if (f.extras && this.header && this.header.columnNames) { - const columnNames = this.header.columnNames; - const stdColumns = this.header.hiccups ? 6 : 10; - for (let i = stdColumns; i < columnNames.length; i++) { - if (this.header.colorColumn === i) continue; - if (columnNames[i] === 'info') { - extractInfoColumn(data, f.extras[i - stdColumns]); - } else { - data.push({name: columnNames[i], value: f.extras[i - stdColumns]}); - } - } - } - // For now just return the top hit - break - - //if (data.length > 0) { - // data.push("
"); - // } - } - return data - } - - clickedFeatures(clickState) { - - // We use the cached features rather than method to avoid async load. If the - // feature is not already loaded this won't work, but the user wouldn't be mousing over it either. - const featureList = clickState.viewport.cachedFeatures; - const candidates = []; - if (featureList) { - const proportional = (this.arcType === "proportional" || this.arcType === "inView" || this.arcType === "partialInView"); - - for (let feature of featureList) { - - if (!feature.drawState) continue - - if (feature.chr1 === feature.chr2 || feature.chr === 'all') { - if (proportional) { - //(x-xc)^2/radiusX^2 + (y-yc)^2/radiusY^2 <= 1 - const {xc, yc, radiusX, radiusY} = feature.drawState; - const dx = clickState.canvasX - xc; - const dy = clickState.canvasY - yc; - const score = (dx / radiusX) * (dx / radiusX) + (dy / radiusY) * (dy / radiusY); - if (score <= 1) { - candidates.push({score: 1 / score, feature}); - } - } else { - const {xc, yc, r} = feature.drawState; - const dx = clickState.canvasX - xc; - const dy = clickState.canvasY - yc; - const score = Math.abs(Math.sqrt(dx * dx + dy * dy) - r); - if (score < 5) { - candidates.push({score, feature}); - } - } - } else { - const {x, y, w, h} = feature.drawState; - const tolerance = 5; - if (clickState.canvasX >= x - tolerance && clickState.canvasX <= x + w + tolerance && - clickState.canvasY >= y && clickState.canvasY <= y + h) { - const score = -Math.abs(clickState.canvasX - (x + w / 2)); - candidates.push({score, feature}); - break - } - } - } - } - - if (candidates.length > 1) { - candidates.sort((a, b) => a.score - b.score); - } - return candidates.map((c) => c.feature) - } -} - -function getMidpoints(feature, genome) { - let m1 = (feature.start1 + feature.end1) / 2; - let m2 = (feature.start2 + feature.end2) / 2; - if (feature.chr === 'all') { - m1 = genome.getGenomeCoordinate(feature.chr1, m1); - m2 = genome.getGenomeCoordinate(feature.chr2, m2); - } - if (m1 > m2) { - const tmp = m1; - m1 = m2; - m2 = tmp; - } - return {m1, m2} -} - -function positionString(chr, start, end, strand) { - - return strand && strand !== '.' ? - `${chr}:${numberFormatter$1(start + 1)}-${numberFormatter$1(end)} (${strand})` : - `${chr}:${numberFormatter$1(start + 1)}-${numberFormatter$1(end)}` -} - -/** - * Estimate theta given the ratio of track height to 1/2 the feature width (coa). This relationship is approximately linear. - */ -function estimateTheta(x) { - let coa = [0.01570925532366355, 0.15838444032453644, 0.3249196962329063, 0.5095254494944288, 0.7265425280053609, 0.9999999999999999]; - let theta = [0.031415926535897934, 0.3141592653589793, 0.6283185307179586, 0.9424777960769379, 1.2566370614359172, 1.5707963267948966]; - let idx; - - for (idx = 0; idx < coa.length; idx++) { - if (coa[idx] > x) { - break - } - } - - let left = idx === 0 ? 0 : coa[idx - 1]; - let right = idx < coa.length ? coa[idx] : 1; - let r = (x - left) / (right - left); - - let thetaLeft = idx === 0 ? 0 : theta[idx - 1]; - let thetaRight = idx < theta.length ? theta[idx] : Math.PI / 2; - - return Math.min(Math.PI/2, (thetaLeft + r * (thetaRight - thetaLeft))) - -} - -const colorAlphaCache = new Map(); - -function getAlphaColor(color, alpha) { - const key = `${color}_${alpha}`; - let c = colorAlphaCache.get(key); - if (!c) { - c = IGVColor.addAlpha(color, alpha); - colorAlphaCache.set(key, c); - } - return c -} - - -/** - * Called in the context of FeatureSource (i.e. this == the feature source (a TextFeatureSource) for the track - * - * @param allFeatures - * @returns {[]} - */ -function getWGFeatures(allFeatures) { - - const makeWGFeature = (f) => { - const wg = Object.assign({}, f); - wg.chr = "all"; - wg.start = genome.getGenomeCoordinate(f.chr1, f.start1); - wg.end = genome.getGenomeCoordinate(f.chr2, f.end2); - return wg - }; - - const genome = this.genome; - - // First pass -- find the max score feature - let maxScoreFeature; - let totalFeatureCount = 0; - for (let c of genome.wgChromosomeNames) { - let chrFeatures = allFeatures[c]; - if (chrFeatures) { - for (let f of chrFeatures) { - if (!f.dup) { - totalFeatureCount++; - if (f.score && (!maxScoreFeature || f.score > maxScoreFeature.score)) { - maxScoreFeature = f; - } - } - } - } - } - - const maxCount = this.maxWGCount; - const nBins = maxScoreFeature && maxScoreFeature.score > 0 && totalFeatureCount > maxCount ? 5 : 1; // TODO make a function of total # of features & maxCount? - const featuresPerBin = Math.floor(maxCount / nBins); - const binSize = maxScoreFeature && maxScoreFeature.score > 0 ? Math.log(maxScoreFeature.score) / nBins : Number.MAX_SAFE_INTEGER; - - let binnedFeatures = []; - let counts = []; - for (let i = 0; i < nBins; i++) { - counts.push([0]); - binnedFeatures.push([]); - } - - for (let c of genome.wgChromosomeNames) { - let chrFeatures = allFeatures[c]; - if (chrFeatures) { - for (let f of chrFeatures) { - if (!f.dup) { - const bin = f.score ? Math.max(0, Math.min(nBins - 1, Math.floor(Math.log(f.score) / binSize))) : 0; - if (binnedFeatures[bin].length < featuresPerBin) { - binnedFeatures[bin].push(makeWGFeature(f)); - } else { - //Reservoir sampling - const samplingProb = featuresPerBin / (counts[bin] + 1); - if (Math.random() < samplingProb) { - const idx = Math.floor(Math.random() * (featuresPerBin - 1)); - binnedFeatures[bin][idx] = makeWGFeature(f); - } - } - counts[bin]++; - } - } - } - } - - let wgFeatures; - if (nBins === 1) { - wgFeatures = binnedFeatures[0]; - } else { - wgFeatures = []; - for (let bf of binnedFeatures) { - for (let f of bf) wgFeatures.push(f); - } - // Keep the feature with max score - if (maxScoreFeature) { - wgFeatures.push(makeWGFeature(maxScoreFeature)); - } - wgFeatures.sort(function (a, b) { - return a.start - b.start - }); - console.log(wgFeatures.length); - } - - - return wgFeatures -} - -/** - * Extract a gff style info column for popup text. This convention used by 10X for bedpe files - * ALLELIC_FRAC=0.0375670840787;BLACK1=.;BLACK2=.;... - * @param data - * @param str - */ -function extractInfoColumn(data, str) { - const kvs = str.split(';'); - for (let t of kvs) { - const kv = t.split('='); - if (kv.length === 2) { - data.push({name: kv[0], value: kv[1]}); - } - } - -} - -/* - * The MIT License (MIT) - * - * Copyright (c) 2016 University of California San Diego - * Author: Jim Robinson - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -const isString = isString$2; - -const DEFAULT_COLOR = "rgb(0,0,150)"; -const DEFAULT_VISIBILITY_WINDOW = 1000000; -const TOP_MARGIN = 10; -const STANDARD_FIELDS = new Map([["REF", "referenceBases"], ["ALT", "alternateBases"], ["QUAL", "quality"], ["FILTER", "filter"]]); - - -class VariantTrack extends TrackBase { - - static defaults = { - displayMode: "EXPANDED", - sortDirection: "ASC", - showGenotypes: true, - squishedVariantHeight: 2, - squishedCallHeight: 1, - expandedCallHeight: 10, - expandedVGap: 2, - squishedVGap: 1, - expandedGroupGap: 10, - squishedGroupGap: 5, - featureHeight: 14, - noGenotypeColor: "rgb(200,180,180)", - noCallColor: "rgb(225, 225, 225)", - nonRefColor: "rgb(200, 200, 215)", - mixedColor: "rgb(200, 220, 200)", - homrefColor: "rgb(200, 200, 200)", - homvarColor: "rgb(17,248,254)", - hetvarColor: "rgb(34,12,253)", - colorBy: undefined, - visibilityWindow: undefined, - labelDisplayMode: undefined, - type: "variant" - } - - constructor(config, browser) { - super(config, browser); - } - - init(config) { - - super.init(config); - - this.expandedVariantHeight = config.expandedVariantHeight || config.variantHeight || 10; - - this.featureSource = FeatureSource(config, this.browser.genome); - - this._initColorBy = config.colorBy; - if (config.colorTable) { - this.colorTables = new Map(); - this.colorTables.set(config.colorBy, new ColorTable(config.colorTable)); - } - this._color = config.color; - this._strokecolor = config.strokecolor; - this._context_hook = config.context_hook; - - - // The number of variant rows are computed dynamically, but start with "1" by default - this.variantRowCount(1); - - } - - async postInit() { - - this.header = await this.getHeader(); // cricital, don't remove' - if (this.disposed) return // This track was removed during async load - if (undefined === this.visibilityWindow && this.config.indexed !== false) { - const fn = isFile$1(this.config.url) ? this.config.url.name : this.config.url; - if (isString(fn) && fn.toLowerCase().includes("gnomad")) { - this.visibilityWindow = 1000; // these are known to be very dense - } else if (typeof this.featureSource.defaultVisibilityWindow === 'function') { - this.visibilityWindow = await this.featureSource.defaultVisibilityWindow(); - } else { - this.visibilityWindow = DEFAULT_VISIBILITY_WINDOW; - } - } - return this - - } - - get supportsWholeGenome() { - return this.config.indexed === false || this.config.supportsWholeGenome === true - } - - get color() { - return this._color || DEFAULT_COLOR - } - - set color(c) { - this._color = c; - this.colorBy = undefined; - } - - async getHeader() { - - if (!this.header) { - if (typeof this.featureSource.getHeader === "function") { - const header = await this.featureSource.getHeader(); - if (header) { - this.callSets = header.callSets || []; - } - this.header = header; - } - this.sampleNames = this.callSets ? this.callSets.map(cs => cs.name) : []; - } - - return this.header - } - - getCallsetsLength() { - return this.callSets ? this.callSets.length : 0 - } - - async getFeatures(chr, start, end, bpPerPixel) { - - if (this.header === undefined) { - this.header = await this.getHeader(); - } - return this.featureSource.getFeatures({chr, start, end, bpPerPixel, visibilityWindow: this.visibilityWindow}) - } - - hasSamples() { - return this.getCallsetsLength() > 0 - } - - getSamples() { - return { - yOffset: this.sampleYOffset, - names: this.sampleNames, - height: this.sampleHeight - } - } - - /** - * The required height in pixels required for the track content. This is not the visible track height, which - * can be smaller (with a scrollbar) or larger. - * - * @param features - * @returns {*} - */ - computePixelHeight(features) { - - if (!features || features.length == 0) return TOP_MARGIN - - const nVariantRows = (this.displayMode === "COLLAPSED") ? 1 : this.nVariantRows; - const vGap = (this.displayMode === "SQUISHED") ? this.squishedVGap : this.expandedVGap; - const variantHeight = (this.displayMode === "SQUISHED") ? this.squishedVariantHeight : this.expandedVariantHeight; - const callHeight = (this.displayMode === "SQUISHED") ? this.squishedCallHeight : this.expandedCallHeight; - const nCalls = this.showGenotypes === false ? 0 : this.getCallsetsLength() * nVariantRows; - const h = TOP_MARGIN + nVariantRows * (variantHeight + vGap); - return h + vGap + (nCalls + 1) * (callHeight + vGap) - - } - - variantRowCount(count) { - this.nVariantRows = count; - } - - draw({context, pixelWidth, pixelHeight, bpPerPixel, bpStart, pixelTop, features}) { - - IGVGraphics.fillRect(context, 0, pixelTop, pixelWidth, pixelHeight, {'fillStyle': "rgb(255, 255, 255)"}); - - const vGap = ("SQUISHED" === this.displayMode) ? this.squishedVGap : this.expandedVGap; - const rowCount = ("COLLAPSED" === this.displayMode) ? 1 : this.nVariantRows; - const variantHeight = ("SQUISHED" === this.displayMode) ? this.squishedVariantHeight : this.expandedVariantHeight; - this.variantBandHeight = TOP_MARGIN + rowCount * (variantHeight + vGap); - - let callSets = this.callSets; - if (!callSets && this._f) { - callSets = this._f.callSets; // "Complementary" variant for structural variants - } - const nCalls = this.getCallsetsLength(); - if (callSets && nCalls > 0 && this.showGenotypes !== false) { - IGVGraphics.strokeLine(context, 0, this.variantBandHeight, pixelWidth, this.variantBandHeight, {strokeStyle: 'rgb(224,224,224) '}); - } - - if (features) { - - const callHeight = ("SQUISHED" === this.displayMode) ? this.squishedCallHeight : this.expandedCallHeight; - const vGap = ("SQUISHED" === this.displayMode) ? this.squishedVGap : this.expandedVGap; - const bpEnd = bpStart + pixelWidth * bpPerPixel + 1; - - // Loop through variants. A variant == a row in a VCF file - for (let variant of features) { - - if (variant.end < bpStart) continue - if (variant.start > bpEnd) break - - const variantHeight = ("SQUISHED" === this.displayMode) ? this.squishedVariantHeight : this.expandedVariantHeight; - const y = TOP_MARGIN + ("COLLAPSED" === this.displayMode ? 0 : variant.row * (variantHeight + vGap)); - const h = variantHeight; - - // Compute pixel width. Minimum width is 3 pixels, if > 5 pixels create gap between variants - let x = Math.round((variant.start - bpStart) / bpPerPixel); - let x1 = Math.round((variant.end - bpStart) / bpPerPixel); - let w = Math.max(1, x1 - x); - if (w < 3) { - w = 3; - x -= 1; - } else if (w > 5) { - x += 1; - w -= 2; - } - context.fillStyle = this.getColorForFeature(variant); - context.fillRect(x, y, w, h); - - //only paint stroke if a color is defined - let strokecolor = this.getVariantStrokecolor(variant); - if (strokecolor) { - context.strokeStyle = strokecolor; - context.strokeRect(x, y, w, h); - } - - // call hook if _context_hook fn is defined - this.callContextHook(variant, context, x, y, w, h); - - variant.pixelRect = {x, y, w, h}; - - // Loop though the calls for this variant. There will potentially be a call for each sample. - if (nCalls > 0 && this.showGenotypes !== false) { - - const nVariantRows = "COLLAPSED" === this.displayMode ? 1 : this.nVariantRows; - this.sampleYOffset = this.variantBandHeight + vGap; - this.sampleHeight = nVariantRows * (callHeight + vGap); // For each sample, there is a call for each variant at this position - - let sampleNumber = 0; - if (callSets && variant.calls) { - for (let callSet of callSets) { - const call = variant.calls[callSet.id]; - if (call) { - const row = "COLLAPSED" === this.displayMode ? 0 : variant.row; - const py = this.sampleYOffset + sampleNumber * this.sampleHeight + row * (callHeight + vGap); - let allVar = true; // until proven otherwise - let allRef = true; - let noCall = false; - - if (call.genotype) { - for (let g of call.genotype) { - if ('.' === g) { - noCall = true; - break - } else { - if (g !== 0) allRef = false; - if (g === 0) allVar = false; - } - } - } - - if (!call.genotype) { - context.fillStyle = this.noGenotypeColor; - } else if (noCall) { - context.fillStyle = this.noCallColor; - } else if (allRef) { - context.fillStyle = this.homrefColor; - } else if (allVar) { - context.fillStyle = this.homvarColor; - } else { - context.fillStyle = this.hetvarColor; - } - - context.fillRect(x, py, w, callHeight); - - callSet.pixelRect = {x, y: py, w, h: callHeight}; - } - sampleNumber++; - } - } - } - } - - } else { - console.log("No feature list"); - } - }; - - - getColorForFeature(variant) { - - const v = variant._f || variant; - let variantColor; - - if (this.colorBy) { - const colorBy = this.colorBy; - let value; - if (v.info.hasOwnProperty(colorBy)) { - value = v.info[colorBy]; - } else if (STANDARD_FIELDS.has(colorBy)) { - const key = STANDARD_FIELDS.get(colorBy); - value = v[key]; - } - variantColor = this.getVariantColorTable(colorBy).getColor(value); - if (!variantColor) { - variantColor = "gray"; - } - - } else if (this._color) { - variantColor = (typeof this._color === "function") ? this._color(variant) : this._color; - } else if ("NONVARIANT" === v.type) { - variantColor = this.nonRefColor; - } else if ("MIXED" === v.type) { - variantColor = this.mixedColor; - } else { - variantColor = this.color; - } - return variantColor - } - - - getVariantStrokecolor(variant) { - - const v = variant._f || variant; - let variantStrokeColor; - - if (this._strokecolor) { - variantStrokeColor = (typeof this._strokecolor === "function") ? this._strokecolor(v) : this._strokecolor; - } else { - variantStrokeColor = undefined; - } - return variantStrokeColor - } - - callContextHook(variant, context, x, y, w, h) { - if (this._context_hook) { - if (typeof this._context_hook === "function") { - const v = variant._f || variant; - - context.save(); - this._context_hook(v, context, x, y, w, h); - context.restore(); - } - } - } - - clickedFeatures(clickState) { - - let featureList = super.clickedFeatures(clickState); - - const vGap = (this.displayMode === 'EXPANDED') ? this.expandedVGap : this.squishedVGap; - const callHeight = vGap + ("SQUISHED" === this.displayMode ? this.squishedCallHeight : this.expandedCallHeight); - // Find the variant row (i.e. row assigned during feature packing) - const yOffset = clickState.y; - if (yOffset <= this.variantBandHeight) { - // Variant - const variantHeight = ("SQUISHED" === this.displayMode) ? this.squishedVariantHeight : this.expandedVariantHeight; - const variantRow = Math.floor((yOffset - TOP_MARGIN) / (variantHeight + vGap)); - if ("COLLAPSED" !== this.displayMode) { - featureList = featureList.filter(f => f.row === variantRow); - } - } else if (this.callSets) { - const callSets = this.callSets; - const sampleY = yOffset - this.variantBandHeight; - const sampleRow = Math.floor(sampleY / this.sampleHeight); - if (sampleRow >= 0 && sampleRow < callSets.length) { - const variantRow = Math.floor((sampleY - sampleRow * this.sampleHeight) / callHeight); - const variants = "COLLAPSED" === this.displayMode ? featureList : featureList.filter(f => f.row === variantRow); - const cs = callSets[sampleRow]; - featureList = variants.map(v => { - const call = v.calls[cs.id]; - expandGenotype(call, v); - return call - }); - } - } - - return featureList - } - - - /** - * Return "popup data" for feature @ genomic location. Data is an array of key-value pairs - */ - popupData(clickState, featureList) { - - if (featureList === undefined) featureList = this.clickedFeatures(clickState); - const genomicLocation = clickState.genomicLocation; - const genomeID = this.browser.genome.id; - const sampleInformation = this.browser.sampleInformation; - - let popupData = []; - for (let v of featureList) { - - const f = v._f || v; // Get real variant from psuedo-variant, e.g. whole genome or SV mate - - if (popupData.length > 0) { - popupData.push({html: '
'}); - } - - if (typeof f.popupData === 'function') { - const v = f.popupData(genomicLocation, genomeID); - Array.prototype.push.apply(popupData, v); - } else { - // Assume this is a call (genotype) - const call = f; - - if (call.callSetName !== undefined) { - popupData.push({name: 'Name', value: call.callSetName}); - } - - if (call.genotypeName) { - popupData.push({name: 'Genotype', value: call.genotypeName}); - } - - if (call.phaseset !== undefined) { - popupData.push({name: 'Phase set', value: call.phaseset}); - } - if (call.genotypeLikelihood !== undefined) { - popupData.push({name: 'genotypeLikelihood', value: call.genotypeLikelihood.toString()}); - } - - if (sampleInformation) { - var attr = sampleInformation.getAttributes(call.callSetName); - if (attr) { - Object.keys(attr).forEach(function (attrName) { - var displayText = attrName.replace(/([A-Z])/g, " $1"); - displayText = displayText.charAt(0).toUpperCase() + displayText.slice(1); - popupData.push({name: displayText, value: attr[attrName]}); - }); - } - } - - var infoKeys = Object.keys(call.info); - if (infoKeys.length) { - popupData.push('
'); - } - infoKeys.forEach(function (key) { - popupData.push({name: key, value: decodeURIComponent(call.info[key])}); - }); - } - } - return popupData - - } - - -// VariantTrack.prototype.contextMenuItemList = function (clickState) { -// -// const self = this; -// const menuItems = []; -// -// const featureList = this.clickedFeatures(clickState); -// -// if (this.callSets && featureList && featureList.length > 0) { -// -// featureList.forEach(function (variant) { -// -// if ('str' === variant.type) { -// -// menuItems.push({ -// label: 'Sort by allele length', -// click: function () { -// sortCallSetsByAlleleLength(self.callSets, variant, self.sortDirection); -// self.sortDirection = (self.sortDirection === "ASC") ? "DESC" : "ASC"; -// self.trackView.repaintViews(); -// } -// }); -// -// } -// -// }); -// } -// -// -// function sortCallSetsByAlleleLength(callSets, variant, direction) { -// var d = (direction === "DESC") ? 1 : -1; -// Object.keys(callSets).forEach(function (property) { -// callSets[property].sort(function (a, b) { -// var aNan = isNaN(variant.calls[a.id].genotype[0]); -// var bNan = isNaN(variant.calls[b.id].genotype[0]); -// if (aNan && bNan) { -// return 0; -// } else if (aNan) { -// return 1; -// } else if (bNan) { -// return -1; -// } else { -// var a0 = getAlleleString(variant.calls[a.id], variant, 0); -// var a1 = getAlleleString(variant.calls[a.id], variant, 1); -// var b0 = getAlleleString(variant.calls[b.id], variant, 0); -// var b1 = getAlleleString(variant.calls[b.id], variant, 1); -// var result = Math.max(b0.length, b1.length) - Math.max(a0.length, a1.length); -// if (result === 0) { -// result = Math.min(b0.length, b1.length) - Math.min(a0.length, a1.length); -// } -// return d * result; -// } -// }); -// }); -// } -// -// -// return menuItems; -// -// }; - - menuItemList() { - - const menuItems = []; - - // color-by INFO attribute - if (this.header.INFO) { - //Code below will present checkboxes for all info fields of type "String". Wait until this is requested - //const stringInfoKeys = Object.keys(this.header.INFO).filter(key => "String" === this.header.INFO[key].Type); - - // For now stick to explicit info fields (well, exactly 1 for starters) - if (this.header.INFO) { - //const stringInfoKeys = Object.keys(this.header.INFO).filter(key => this.header.INFO[key].Type === "String") - const stringInfoKeys = this.header.INFO.SVTYPE ? ['SVTYPE'] : []; - if (this._initColorBy && this._initColorBy !== 'SVTYPE') { - stringInfoKeys.push(this._initColorBy); - } - if (stringInfoKeys.length > 0) { - menuItems.push('
'); - const $e = $$1('
'); - $e.text('Color by:'); - menuItems.push({name: undefined, object: $e, click: undefined, init: undefined}); - stringInfoKeys.sort(); - for (let item of stringInfoKeys) { - const selected = (this.colorBy === item); - const label = item ? item : 'None'; - menuItems.push(this.colorByCB({key: item, label: label}, selected)); - } - menuItems.push(this.colorByCB({key: undefined, label: 'None'}, this.colorBy === undefined)); - menuItems.push('
'); - } - } - } - - if (this.getCallsetsLength() > 0) { - menuItems.push({object: $$1('
')}); - menuItems.push({ - object: $$1(createCheckbox$2("Show Genotypes", this.showGenotypes)), - click: () => { - this.showGenotypes = !this.showGenotypes; - //adjustTrackHeight(); - this.trackView.checkContentHeight(); - this.trackView.repaintViews(); - } - }); - } - - menuItems.push({object: $$1('
')}); - for (let displayMode of ["COLLAPSED", "SQUISHED", "EXPANDED"]) { - var lut = - { - "COLLAPSED": "Collapse", - "SQUISHED": "Squish", - "EXPANDED": "Expand" - }; - - menuItems.push( - { - object: $$1(createCheckbox$2(lut[displayMode], displayMode === this.displayMode)), - click: () => { - this.displayMode = displayMode; - this.trackView.checkContentHeight(); - this.trackView.repaintViews(); - } - }); - } - - // Experimental JBrowse circular view integration - if (this.browser.circularView) { - - menuItems.push('
'); - menuItems.push({ - label: 'Add SVs to circular view', - click: () => { - for (let viewport of this.trackView.viewports) { - this.sendChordsForViewport(viewport); - } - } - }); - } - - return menuItems - } - - - contextMenuItemList(clickState) { - - // Experimental JBrowse circular view integration - if (this.browser.circularView) { - const viewport = clickState.viewport; - const list = []; - - list.push({ - label: 'Add SVs to Circular View', - click: () => { - this.sendChordsForViewport(viewport); - } - }); - - list.push('
'); - return list - } - } - - - sendChordsForViewport(viewport) { - const refFrame = viewport.referenceFrame; - let inView; - if ("all" === refFrame.chr) { - const all = this.featureSource.getAllFeatures(); - const arrays = Object.keys(all).map(k => all[k]); - inView = [].concat(...arrays); - } else { - inView = this.featureSource.featureCache.queryFeatures(refFrame.chr, refFrame.start, refFrame.end); - - } - - const chords = makeVCFChords(inView); - sendChords(chords, this, refFrame, 0.5); - } - - /** - * Create a "color by" checkbox menu item, optionally initially checked - * @param menuItem - * @param showCheck - * @returns {{init: undefined, name: undefined, click: clickHandler, object: (jQuery|HTMLElement|jQuery.fn.init)}} - */ - colorByCB(menuItem, showCheck) { - - const $e = $$1(createCheckbox$2(menuItem.label, showCheck)); - const clickHandler = () => { - - if (menuItem.key === this.colorBy) { - this.colorBy = undefined; - delete this.config.colorBy; - this.trackView.repaintViews(); - } else { - this.colorBy = menuItem.key; - this.config.colorBy = menuItem.key; - this.trackView.repaintViews(); - } - - }; - - return {name: undefined, object: $e, click: clickHandler, init: undefined} - } - - getState() { - - const config = super.getState(); - if (this._color && typeof this._color !== "function") { - config.color = this._color; - } - return config - - } - - getVariantColorTable(key) { - - if (!this.colorTables) { - this.colorTables = new Map(); - } - - if (!this.colorTables.has(key)) { - let tbl; - switch (key) { - case "SVTYPE" : - tbl = SV_COLOR_TABLE; - break - default: - tbl = new PaletteColorTable("Set1"); - } - this.colorTables.set(key, tbl); - } - return this.colorTables.get(key) - } -} - - -function expandGenotype(call, variant) { - - if (call.genotype) { - let gt = ''; - if (variant.alternateBases === ".") { - gt = "No Call"; - } else { - const altArray = variant.alternateBases.split(","); - for (let allele of call.genotype) { - if (gt.length > 0) { - gt += "|"; - } - if ('.' === allele) { - gt += '.'; - } else if (allele === 0) { - gt += variant.referenceBases; - } else { - let alt = altArray[allele - 1].replace("<", "<"); - gt += alt; - } - } - } - call.genotypeName = gt; - } -} - - -const SV_COLOR_TABLE = new ColorTable({ - 'DEL': '#ff2101', - 'INS': '#001888', - 'DUP': '#028401', - 'INV': '#008688', - 'CNV': '#8931ff', - 'BND': '#891100', - '*': '#002eff' -}); - -/* - * The MIT License (MIT) - * - * Copyright (c) 2014 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -class EqtlTrack extends TrackBase { - - constructor(config, browser) { - - super(config, browser); - } - - init(config) { - super.init(config); - - this.name = config.name; - this.pValueField = config.pValueField || "pValue"; - this.geneField = config.geneField || "geneSymbol"; - this.snpField = config.snpField || "snp"; - - const min = config.minLogP || config.min; - const max = config.maxLogP || config.max; - this.dataRange = { - min: min || 3.5, - max: max || 25 - }; - if (!max) { - this.autoscale = true; - } else { - this.autoscale = config.autoscale; - } - this.autoscalePercentile = (config.autoscalePercentile === undefined ? 98 : config.autoscalePercentile); - - - this.background = config.background; // No default - this.divider = config.divider || "rgb(225,225,225)"; - this.dotSize = config.dotSize || 2; - this.height = config.height || 100; - this.autoHeight = false; - this.disableButtons = config.disableButtons; - - // Limit visibility window to 2 mb, gtex server gets flaky beyond that - this.visibilityWindow = config.visibilityWindow === undefined ? - 2000000 : config.visibilityWindow >= 0 ? Math.min(2000000, config.visibilityWindow) : 2000000; - - this.featureSource = FeatureSource(config, this.browser.genome); - - GtexUtils.gtexLoaded = true; - } - - paintAxis(ctx, pixelWidth, pixelHeight) { - - const yScale = (this.dataRange.max - this.dataRange.min) / pixelHeight; - - const font = { - 'font': 'normal 10px Arial', - 'textAlign': 'right', - 'strokeStyle': "black" - }; - - IGVGraphics.fillRect(ctx, 0, 0, pixelWidth, pixelHeight, {'fillStyle': "rgb(255, 255, 255)"}); - - // Determine a tick spacing such that there is at least 10 pixels between ticks - - const n = Math.ceil((this.dataRange.max - this.dataRange.min) * 10 / pixelHeight); - - for (let p = 4; p <= this.dataRange.max; p += n) { - - // TODO: Dashes may not actually line up with correct scale. Ask Jim about this - - const ref = 0.85 * pixelWidth; - const x1 = ref - 5; - const x2 = ref; - const y = pixelHeight - (p - this.dataRange.min) / yScale; - - IGVGraphics.strokeLine(ctx, x1, y, x2, y, font); // Offset dashes up by 2 pixel - - if (y > 8) { - IGVGraphics.fillText(ctx, p, x1 - 1, y + 2, font); - } // Offset numbers down by 2 pixels; - } - - font['textAlign'] = 'center'; - - IGVGraphics.fillText(ctx, "-log10(pvalue)", pixelWidth / 4, pixelHeight / 2, font, {rotate: {angle: -90}}); - - }; - - async getFeatures(chr, start, end) { - - const pValueField = this.pValueField; - const visibilityWindow = this.visibilityWindow; - const features = await this.featureSource.getFeatures({chr, start, end, visibilityWindow}); - features.forEach(function (f) { - f.value = f[pValueField]; - }); - return features - } - - draw(options) { - - const ctx = options.context; - - const pixelWidth = options.pixelWidth; - const pixelHeight = options.pixelHeight; - - if (this.background) { - IGVGraphics.fillRect(ctx, 0, 0, pixelWidth, pixelHeight, {'fillStyle': this.background}); - } - IGVGraphics.strokeLine(ctx, 0, pixelHeight - 1, pixelWidth, pixelHeight - 1, {'strokeStyle': this.divider}); - - const drawEqtls = (drawSelected) => { - - const radius = drawSelected ? 2 * this.dotSize : this.dotSize; - const bpStart = options.bpStart; - const yScale = (this.dataRange.max - this.dataRange.min) / pixelHeight; - const selection = options.referenceFrame.selection; - - for (let eqtl of options.features) { - - const px = (eqtl.start - bpStart + 0.5) / options.bpPerPixel; - if (px < 0) continue - else if (px > pixelWidth) break - - const snp = eqtl.snp.toUpperCase(); - const geneName = eqtl[this.geneField].toUpperCase(); - - const isSelected = selection && - (selection.snp === snp || selection.gene === geneName); - - if (!drawSelected || isSelected) { - - // Add eqtl's gene to the selection if this is the selected snp. - // TODO -- this should not be done here in the rendering code. - if (selection && selection.snp === snp) { - selection.addGene(geneName); - } - - var mLogP = -Math.log(eqtl[this.pValueField]) / Math.LN10; - if (mLogP >= this.dataRange.min) { - let capped; - if (mLogP > this.dataRange.max) { - mLogP = this.dataRange.max; - capped = true; - } else { - capped = false; - - } - - const py = Math.max(0 + radius, pixelHeight - Math.round((mLogP - this.dataRange.min) / yScale)); - eqtl.px = px; - eqtl.py = py; - eqtl.radius = radius; - - let color; - if (drawSelected && selection) { - color = selection.colorForGene(geneName); - IGVGraphics.setProperties(ctx, {fillStyle: color, strokeStyle: "black"}); - } else { - color = capped ? "rgb(150, 150, 150)" : "rgb(180, 180, 180)"; - IGVGraphics.setProperties(ctx, {fillStyle: color, strokeStyle: color}); - } - - IGVGraphics.fillCircle(ctx, px, py, radius); - IGVGraphics.strokeCircle(ctx, px, py, radius); - } - } - } - }; - - // Draw in two passes, with "selected" eqtls drawn last - drawEqtls(false); - drawEqtls(true); - - } - - /** - * Return "popup data" for feature @ genomic location. Data is an array of key-value pairs - */ - popupData(clickState, features) { - - if(features === undefined) features = clickState.viewport.cachedFeatures; - if (!features || features.length === 0) return [] - - const tolerance = 3; - const tissue = this.name; - const popupData = []; - - for (let feature of features) { - // Hit test --use square vs circle for efficiency (no sqrt) - if (Math.abs(feature.px - clickState.canvasX) < (feature.radius + tolerance) && - Math.abs(feature.py - clickState.canvasY) < (feature.radius + tolerance)) { - - if (popupData.length > 0) { - popupData.push('
'); - } - popupData.push( - {name: "snp id", value: feature.snp}, - {name: "gene id", value: feature.geneId}, - {name: "gene name", value: feature.geneName}, - {name: "p value", value: feature.pValue}, - {name: "tissue", value: tissue}); - - } - } - - return popupData - } - - menuItemList() { - return MenuUtils$1.numericDataMenuItems(this.trackView) - } - - doAutoscale(featureList) { - - if (featureList.length > 0) { - - var values = featureList - .map(function (eqtl) { - return -Math.log(eqtl.value) / Math.LN10 - }); - - this.dataRange.max = IGVMath.percentile(values, this.autoscalePercentile); - } else { - // No features -- default - const max = this.config.maxLogP || this.config.max; - this.dataRange.max = max || 25; - } - - return this.dataRange - } - -} - -/** - * Colors used for coding omosomes - */ - -const GWASColors = { - "X": "rgb(204, 153, 0)", - "Y": "rgb(153, 204, 0)", - "Un": "darkGray)", - "1": "rgb(80, 80, 255)", - "2": "rgb(206, 61, 50)", - "2a": "rgb(210, 65, 55)", - "2b": "rgb(215, 70, 60)", - "3": "rgb(116, 155, 88)", - "4": "rgb(240, 230, 133)", - "5": "rgb(70, 105, 131)", - "6": "rgb(186, 99, 56)", - "7": "rgb(93, 177, 221)", - "8": "rgb(128, 34, 104)", - "9": "rgb(107, 215, 107)", - "10": "rgb(213, 149, 167)", - "11": "rgb(146, 72, 34)", - "12": "rgb(131, 123, 141)", - "13": "rgb(199, 81, 39)", - "14": "rgb(213, 143, 92)", - "15": "rgb(122, 101, 165)", - "16": "rgb(228, 175, 105)", - "17": "rgb(59, 27, 83)", - "18": "rgb(205, 222, 183)", - "19": "rgb(97, 42, 121)", - "20": "rgb(174, 31, 99)", - "21": "rgb(231, 199, 111)", - "22": "rgb(90, 101, 94)", - "23": "rgb(204, 153, 0)", - "24": "rgb(153, 204, 0)", - "25": "rgb(51, 204, 0)", - "26": "rgb(0, 204, 51)", - "27": "rgb(0, 204, 153)", - "28": "rgb(0, 153, 204)", - "29": "rgb(10, 71, 255)", - "30": "rgb(71, 117, 255)", - "31": "rgb(255, 194, 10)", - "32": "rgb(255, 209, 71)", - "33": "rgb(153, 0, 51)", - "34": "rgb(153, 26, 0)", - "35": "rgb(153, 102, 0)", - "36": "rgb(128, 153, 0)", - "37": "rgb(51, 153, 0)", - "38": "rgb(0, 153, 26)", - "39": "rgb(0, 153, 102)", - "40": "rgb(0, 128, 153)", - "41": "rgb(0, 51, 153)", - "42": "rgb(26, 0, 153)", - "43": "rgb(102, 0, 153)", - "44": "rgb(153, 0, 128)", - "45": "rgb(214, 0, 71)", - "46": "rgb(255, 20, 99)", - "47": "rgb(0, 214, 143)", - "48": "rgb(20, 255, 177)" -}; - -// aliasing -for (let key of Object.keys(GWASColors)) { - const altName = "chr" + key; - GWASColors[altName] = GWASColors[key]; -} - -// romanizing -for(let a = 1; a <= 48; a++) { - if(a === 10) continue // Don't overide "X" - const roman = romanize(a); - GWASColors[roman] = GWASColors[a.toString()]; -} - - -function romanize (num) { - if (!+num) return false; - var digits = String(+num).split(''); - var key = ['','C','CC','CCC','CD','D','DC','DCC','DCCC','CM', - '','X','XX','XXX','XL','L','LX','LXX','LXXX','XC', - '','I','II','III','IV','V','VI','VII','VIII','IX']; - var roman = '', i = 3; - while (i--) roman = (key[+digits.pop() + (i * 10)] || '') + roman; - return Array(+digits.join('') + 1).join('M') + roman; -} - -/* - * The MIT License (MIT) - * - * Copyright (c) 2014 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -const DEFAULT_POPOVER_WINDOW = 100000000; - -//const type = "gwas"; - -class GWASTrack extends TrackBase { - - constructor(config, browser) { - - super(config, browser); - } - - init(config) { - - super.init(config); - - this.useChrColors = config.useChrColors === undefined ? true : config.useChrColors; - this.trait = config.trait; - this.posteriorProbability = config.posteriorProbability; - this.valueProperty = "bed" === config.format ? "score" : "value"; - this.height = config.height || 100; // The preferred height - this.autoscale = config.autoscale; - this.autoscalePercentile = config.autoscalePercentile === undefined ? 98 : config.autoscalePercentile; - this.background = config.background; // No default - this.divider = config.divider || "rgb(225,225,225)"; - this.dotSize = config.dotSize || 3; - this.popoverWindow = (config.popoverWindow === undefined ? DEFAULT_POPOVER_WINDOW : config.popoverWindow); - - // Color settings - if (this.useChrColors) { - this.colorScale = new ColorTable(config.colorTable || GWASColors); - } else if (config.color) { - this.colorScale = new ConstantColorScale(config.color); - } else { - this.colorScale = - new BinnedColorScale(config.colorScale || - { - thresholds: [5e-8, 5e-4, 0.5], - colors: ["rgb(255,50,50)", "rgb(251,100,100)", "rgb(251,170,170)", "rgb(227,238,249)"], - }); - } - - this.featureSource = FeatureSource(config, this.browser.genome); - } - - async postInit() { - - if (typeof this.featureSource.getHeader === "function") { - this.header = await this.featureSource.getHeader(); - if (this.disposed) return // This track was removed during async load - } - - // Set properties from track line - if (this.header) { - this.setTrackProperties(this.header); // setTrackProperties defined in TrackBase - } - - // Set initial range if specfied, unless autoscale == true - if (!this.autoscale) { - if (this.posteriorProbability) { - this.dataRange = { - min: this.config.min === undefined ? 0 : this.config.min, - max: this.config.max === undefined ? 1 : this.config.max - }; - } else { - this.dataRange = { - min: this.config.min === undefined ? 0 : this.config.min, - max: this.config.max === undefined ? 25 : this.config.max - }; - } - } - - return this - - } - - - get supportsWholeGenome() { - return true - } - - async getFeatures(chr, start, end) { - const visibilityWindow = this.visibilityWindow; - return this.featureSource.getFeatures({chr, start, end, visibilityWindow}) - } - - draw(options) { - - const featureList = options.features; - const ctx = options.context; - const pixelWidth = options.pixelWidth; - const pixelHeight = options.pixelHeight; - if (this.background) { - IGVGraphics.fillRect(ctx, 0, 0, pixelWidth, pixelHeight, {'fillStyle': this.background}); - } - IGVGraphics.strokeLine(ctx, 0, pixelHeight - 1, pixelWidth, pixelHeight - 1, {'strokeStyle': this.divider}); - - if (featureList) { - - const bpPerPixel = options.bpPerPixel; - const bpStart = options.bpStart; - const bpEnd = bpStart + pixelWidth * bpPerPixel + 1; - for (let variant of featureList) { - const pos = variant.start; - if (pos < bpStart) continue - if (pos > bpEnd) break - - let val; - if (this.posteriorProbability) { - val = variant[this.valueProperty]; - } else { - const pvalue = variant[this.valueProperty]; - if (!pvalue) continue - val = -Math.log10(pvalue); - } - - const colorKey = this.useChrColors ? - variant._f ? variant._f.chr : variant.chr : - val; - - const color = this.colorScale.getColor(colorKey); - const yScale = (this.dataRange.max - this.dataRange.min) / pixelHeight; - const px = Math.round((pos - bpStart) / bpPerPixel); - const py = Math.max(this.dotSize, pixelHeight - Math.round((val - this.dataRange.min) / yScale)); - - if (color) { - IGVGraphics.setProperties(ctx, {fillStyle: color, strokeStyle: "black"}); - } - IGVGraphics.fillCircle(ctx, px, py, this.dotSize); - variant.px = px; - variant.py = py; - } - } - } - - paintAxis(ctx, pixelWidth, pixelHeight) { - - IGVGraphics.fillRect(ctx, 0, 0, pixelWidth, pixelHeight, {'fillStyle': "rgb(255, 255, 255)"}); - var font = { - 'font': 'normal 10px Arial', - 'textAlign': 'right', - 'strokeStyle': "black" - }; - - const yScale = (this.dataRange.max - this.dataRange.min) / pixelHeight; - if (this.posteriorProbability) { - const n = 0.1; - for (let p = this.dataRange.min; p < this.dataRange.max; p += n) { - const yp = pixelHeight - Math.round((p - this.dataRange.min) / yScale); - IGVGraphics.strokeLine(ctx, 45, yp - 2, 50, yp - 2, font); // Offset dashes up by 2 pixel - IGVGraphics.fillText(ctx, p.toFixed(1), 44, yp + 2, font); // Offset numbers down by 2 pixels; - } - } else { - const n = Math.ceil((this.dataRange.max - this.dataRange.min) * 10 / pixelHeight); - for (let p = this.dataRange.min; p < this.dataRange.max; p += n) { - const yp = pixelHeight - Math.round((p - this.dataRange.min) / yScale); - IGVGraphics.strokeLine(ctx, 45, yp, 50, yp, font); // Offset dashes up by 2 pixel - IGVGraphics.fillText(ctx, Math.floor(p), 44, yp + 4, font); // Offset numbers down by 2 pixels; - } - } - - font['textAlign'] = 'center'; - if (this.posteriorProbability) { - IGVGraphics.fillText(ctx, "PPA", pixelWidth / 2, pixelHeight / 2, font, {rotate: {angle: -90}}); - } else { - IGVGraphics.fillText(ctx, "-log10(pvalue)", pixelWidth / 2, pixelHeight / 2, font, {rotate: {angle: -90}}); - } - } - - popupData(clickState, features) { - - if (features === undefined) features = clickState.viewport.cachedFeatures; - - let data = []; - const track = clickState.viewport.trackView.track; - - if (features) { - let count = 0; - for (let f of features) { - const xDelta = Math.abs(clickState.canvasX - f.px); - const yDelta = Math.abs(clickState.canvasY - f.py); - const value = f[this.valueProperty]; - if (xDelta < this.dotSize && yDelta < this.dotSize) { - if (count > 0) { - data.push("
"); - } - if (count == 5) { - data.push("..."); - break - } - if (typeof f.popupData === 'function') { - data = data.concat(f.popupData()); - } else { - const chr = f.realChr || f.chr; - const pos = (f.realStart || f.start) + 1; - data.push({name: 'chromosome', value: chr}); - data.push({name: 'position', value: pos}); - data.push({name: 'name', value: f.name}); - if (track.posteriorProbability) { - data.push({name: 'posterior probability', value: value}); - } else { - data.push({name: 'pValue', value: value}); - } - } - count++; - } - } - } - - return data - } - - menuItemList() { - return MenuUtils$1.numericDataMenuItems(this.trackView) - } - - doAutoscale(featureList) { - - if (featureList.length > 0) { - // posterior probabilities are treated without modification, but we need to take a negative logarithm of P values - const valueProperty = this.valueProperty; - const posterior = this.posteriorProbability; - const features = - featureList.map(function (feature) { - const v = feature[valueProperty]; - return {value: posterior ? v : -Math.log(v) / Math.LN10} - }); - this.dataRange = doAutoscale$1(features); - - } else { - // No features -- pick something reasonable for PPAs and p-values - if (this.posteriorProbability) { - this.dataRange = {min: this.config.min || 0, max: this.config.max || 1}; - } else { - this.dataRange = {min: this.config.max || 25, max: this.config.min || 0}; - } - } - - return this.dataRange - } - -} - -const X_PIXEL_DIFF_THRESHOLD = 1; - -class GCNVTrack extends TrackBase { - - constructor(config, browser) { - super(config, browser); - } - - init(config) { - super.init(config); - - this.autoscale = config.autoscale || config.max === undefined; - this.dataRange = { - min: config.min || 0, - max: config.max - }; - - this.windowFunction = config.windowFunction || "mean"; - this.paintAxis = paintAxis; - this.graphType = config.graphType || "bar"; - - //hack to avoid creating feature source multiple times. If config.type is not set the file must be read - //to determine type, which results in creation of a feature source. - if (config._featureSource) { - this.featureSource = config._featureSource; - delete config._featureSource; - } else { - this.featureSource = FeatureSource(this.config, this.browser.genome); - } - - // Visibility window hardcoded to -1 (== whole chromosome). Draw method needs feature beyond current view, - // when/if this is resolved visibilityWindow can be used. - this.visibilityWindow = -1; - this.featureSource.visibilityWindow = this.visibilityWindow; - } - - async postInit() { - - if (typeof this.featureSource.getHeader === "function") { - this.header = await this.featureSource.getHeader(); - if(this.disposed) return; // This track was removed during async load - this.sampleNames = this.header.columnNames.slice(3); - - // Set generic properties from track line - this.setTrackProperties(this.header); // setTrackProperties defined in TrackBase - - // set option to highlight sample track line on click - if (this.header.hasOwnProperty("clickToHighlight")) { - let colour = this.header["clickToHighlight"]; - this.config.clickToHighlight = colour; - this.config.samplesClickedToHighlight = {}; - } - - // Special track line properties - if (this.header.hasOwnProperty("highlight")) { - this.config.highlightSamples = {}; - let v = this.header["highlight"]; - if (!Array.isArray(v)) v = [v]; - for (let h of v) { - const tokens = h.split(";"); - if (tokens.length === 2) { - this.config.highlightSamples[tokens[0]] = tokens[1]; - } - - } - } - } - } - - menuItemList() { - return MenuUtils$1.numericDataMenuItems(this.trackView) - } - - async getFeatures(chr, start, end) { - const chrFeatures = await this.featureSource.getFeatures({ - chr, - start: 0, - end: Number.MAX_SAFE_INTEGER, - visibilityWindow: this.visibilityWindow - }); - let prevIndex = undefined; - let nextIndex = undefined; - for (let i = 1; i < chrFeatures.length - 1; i++) { - if (prevIndex === undefined && chrFeatures[i].end > start) { - prevIndex = i - 1; - } - if (nextIndex === undefined && chrFeatures[i].start > end) { - nextIndex = i + 1; - break - } - } - if (prevIndex === undefined) prevIndex = 0; - if (nextIndex === undefined) nextIndex = chrFeatures.length; - return chrFeatures.slice(prevIndex, nextIndex) - } - - draw(options) { - - const {features, context, bpPerPixel, bpStart, pixelWidth, pixelHeight} = options; - - ///let baselineColor; - //if (typeof self.color === "string" && self.color.startsWith("rgb(")) { - // baselineColor = IGVColor.addAlpha(self.color, 0.1); - //} - - const yScale = (yValue) => { - return ((this.dataRange.max - yValue) / (this.dataRange.max - this.dataRange.min)) * pixelHeight - }; - - const getX = function (bpPosition) { - let x = Math.floor((bpPosition - bpStart) / bpPerPixel); - if (isNaN(x)) console.warn('isNaN(x). feature start ' + numberFormatter$1(bpPosition) + - ' bp start ' + numberFormatter$1(bpStart)); - return x - }; - - const drawGuideLines = (options) => { - if (this.config.hasOwnProperty('guideLines')) { - for (let line of this.config.guideLines) { - if (line.hasOwnProperty('color') && line.hasOwnProperty('y') && line.hasOwnProperty('dotted')) { - let y = yScale(line.y); - let props = { - 'strokeStyle': line['color'], - 'strokeWidth': 2 - }; - if (line['dotted']) IGVGraphics.dashedLine(options.context, 0, y, options.pixelWidth, y, 5, props); - else IGVGraphics.strokeLine(options.context, 0, y, options.pixelWidth, y, props); - } - } - } - }; - - if (features && features.length > 0) { - - if (this.dataRange.min === undefined) this.dataRange.min = 0; - - // Max can be less than min if config.min is set but max left to autoscale. If that's the case there is - // nothing to paint. - if (this.dataRange.max > this.dataRange.min) { - const highlightSamples = this.config.highlightSamples; - const onlyHandleClicksForHighlightedSamples = this.config.onlyHandleClicksForHighlightedSamples; - const clickToHighlight = this.config.clickToHighlight; - - let previousEnd = -1; - let previousValues = {}; - - let highlightConnectorLines = []; - let highlightFeatureLines = []; - - // clickDetectorCache allows fast retrieval of whether a mouse click hits a rendered line segment - // by storing lists of rendered line segments, keyed by their right x coordinate in canvas pixel space. - // this cache is regenerated on every draw. - this.clickDetectorCache = {}; - - for (let feature of features) { - const x1 = getX(feature.start); - const x2 = getX(feature.end); - const previousX = previousEnd >= 0 ? getX(previousEnd) : x1; - - if (isNaN(x1) || isNaN(x2)) continue - // if ((x1 - previousX < X_PIXEL_DIFF_THRESHOLD) && (x2 - x1 < X_PIXEL_DIFF_THRESHOLD)) continue; - - this.clickDetectorCache[x1] = []; - this.clickDetectorCache[x2] = []; - for (let i = 0; i < feature.values.length; i++) { - const sampleName = this.sampleNames[i]; - const value = feature.values[i]; - const y = yScale(value); - if (x1 - previousX >= X_PIXEL_DIFF_THRESHOLD) { - const previousValue = previousValues[sampleName]; - const previousY = yScale(previousValue); - const highlightColor = highlightSamples && highlightSamples[sampleName]; - - - if (highlightColor) { - highlightConnectorLines.push([previousX, previousY, x1, y, highlightColor]); - } else if (clickToHighlight && sampleName in this.config.samplesClickedToHighlight) { - highlightConnectorLines.push([previousX, previousY, x1, y, this.config.samplesClickedToHighlight[sampleName]]); - } else { - IGVGraphics.strokeLine(context, previousX, previousY, x1, y, {strokeStyle: '#D9D9D9'}); - } - if (!onlyHandleClicksForHighlightedSamples || sampleName in highlightSamples) { - this.clickDetectorCache[x1].push([previousX, previousY, x1, y, sampleName, highlightColor || 'gray']); - } - } - - if (x2 - x1 >= X_PIXEL_DIFF_THRESHOLD) { - const highlightColor = highlightSamples && highlightSamples[sampleName]; - if (highlightColor) { - highlightFeatureLines.push([x1, y, x2, y, highlightColor]); - } else if (clickToHighlight && sampleName in this.config.samplesClickedToHighlight) { - highlightFeatureLines.push([x1, y, x2, y, this.config.samplesClickedToHighlight[sampleName]]); - } else { - IGVGraphics.strokeLine(context, x1, y, x2, y, {strokeStyle: 'gray'}); - } - if (!onlyHandleClicksForHighlightedSamples || sampleName in highlightSamples) { - this.clickDetectorCache[x2].push([x1, y, x2, y, sampleName, highlightColor || 'gray']); - } - } - - previousValues[sampleName] = value; - - //IGVGraphics.fillCircle(ctx, px, y, pointSize / 2, {"fillStyle": color, "strokeStyle": color}); - //IGVGraphics.fillRect(ctx, x, y, width, height, {fillStyle: color}); - } - previousEnd = feature.end; - } - - for (let f of highlightConnectorLines) { - IGVGraphics.strokeLine(context, f[0], f[1], f[2], f[3], {strokeStyle: f[4], lineWidth: 1.3}); - } - for (let f of highlightFeatureLines) { - IGVGraphics.strokeLine(context, f[0], f[1], f[2], f[3], {strokeStyle: f[4], lineWidth: 2}); - } - - /* - // If the track includes negative values draw a baseline - if (this.dataRange.min < 0) { - const basepx = (self.dataRange.max / (this.dataRange.max - this.dataRange.min)) * options.pixelHeight; - IGVGraphics.strokeLine(context, 0, basepx, options.pixelWidth, basepx, {strokeStyle: baselineColor}); - } - */ - } - } - - drawGuideLines(options); - } - - doAutoscale(features) { - - let min, max; - if (features.length > 0) { - min = Number.MAX_VALUE; - max = -Number.MAX_VALUE; - - features.forEach(function (feature) { - min = Math.min(min, ...feature.values); - max = Math.max(max, ...feature.values); - }); - - min -= 0.01; - max += 0.01; - } else { - // No features -- default - min = 0; - max = 100; - } - - return {min: min, max: max} - } - - clickedFeatures(clickState) { - //console.warn('click', clickState.canvasX, clickState.canvasY, clickState) - - const BOUNDING_BOX_PADDING = 10; - const MIN_DISTANCE_TO_SEGMENT = 5; - - const clickX = clickState.canvasX; - const clickY = clickState.canvasY; - - let key = null; - for (key of Object.keys(this.clickDetectorCache)) { - key = parseInt(key); - if (key >= clickX) { - break - } - } - - - if (key) { - let closestDistanceSoFar = Number.MAX_VALUE; - let closestResult = []; - const segments = this.clickDetectorCache[key]; - for (let segment of segments) { - const x1 = segment[0]; - const x2 = segment[2]; - if (clickX < x1 || clickX > x2) return [] - - const y1 = segment[1]; - const y2 = segment[3]; - - if ((clickY < Math.min(y1, y2) - BOUNDING_BOX_PADDING) || (clickY > Math.max(y1, y2) + BOUNDING_BOX_PADDING)) continue - - const distance = distanceToLine(clickX, clickY, x1, y1, x2, y2); - if (distance < closestDistanceSoFar) { - closestResult = [{'name': segment[4], 'color': segment[5]}]; - closestDistanceSoFar = distance; - //console.warn('closest:', 'name', segment[4], 'color', segment[5], distance); - } - } - - if (closestDistanceSoFar < MIN_DISTANCE_TO_SEGMENT) { - // clickToHighlight set, add sample to dict of clicked lines - if (this.config.clickToHighlight) { - if (closestResult[0]['name'] in this.config.samplesClickedToHighlight) { - // clicked sample already highlighted => remove if clicked again - delete this.config.samplesClickedToHighlight[closestResult[0]['name']]; - } else if (this.config.clickToHighlight === 'any') { - var colourList = [ - 'red', 'darkblue', 'green', 'teal', 'olivedrab', - 'orange', 'maroon', 'purple', 'blue', 'gold', - ]; - var colour = colourList[Math.floor(Math.random() * (colourList.length + 1))]; - this.config.samplesClickedToHighlight[closestResult[0]['name']] = colour; - } else { - this.config.samplesClickedToHighlight[closestResult[0]['name']] = this.config.clickToHighlight; - } - this.trackView.repaintViews(); // prompt redraw to change colour of clicked sample - } - return closestResult - } - } - - return [] - } - - popupData(clickState, features) { - - if(features === undefined) features = this.clickedFeatures(clickState); - - const items = []; - features.forEach(function (f) { - for (let property of Object.keys(f)) { - if (isSimpleType(f[property])) { - items.push({name: property, value: f[property]}); - } - } - }); - - return items - } - - get supportsWholeGenome() { - return false - } -} - - -function distanceToLine(x, y, ax, ay, bx, by) { - /* - Finds distance between point (x, y) and line defined by points (ax, ay) (bx, by) - based on http://mathworld.wolfram.com/Point-LineDistance2-Dimensional.html - */ - - const bx_minus_ax = bx - ax; - const by_minus_ay = by - ay; - const v = Math.abs(bx_minus_ax * (ay - y) - (ax - x) * by_minus_ay); - const r = Math.sqrt(bx_minus_ax * bx_minus_ax + by_minus_ay * by_minus_ay); - - const distance = r > 0 ? v / r : 0; - //console.warn('Check if', x, y, 'is within', ax, ay, bx, by, '. Distance from line: ', distance); - - return distance -} - -/* - * The MIT License (MIT) - * - * Copyright (c) 2014 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -class RnaStructTrack extends TrackBase { - - constructor(config, browser) { - - super(config, browser); - - // Set defaults - if (!config.height) { - this.height = 300; - } - - this.arcOrientation = false; - - this.theta = Math.PI / 2; - - if ("bp" === config.format) { - this.featureSource = new RNAFeatureSource(config, browser.genome); - } else { - this.featureSource = new TextFeatureSource(config, browser.genome); - } - } - - async getFeatures(chr, start, end) { - const visibilityWindow = this.visibilityWindow; - return this.featureSource.getFeatures({chr, start, end, visibilityWindow}) - } - - draw(options) { - - const ctx = options.context; - - const theta = Math.PI / 2; - const pixelWidth = options.pixelWidth; - const pixelHeight = options.pixelHeight; - options.viewportWidth; - const bpPerPixel = options.bpPerPixel; - const bpStart = options.bpStart; - const xScale = bpPerPixel; - const orienation = this.arcOrientation; - - IGVGraphics.fillRect(ctx, 0, options.pixelTop, pixelWidth, pixelHeight, {'fillStyle': "rgb(255, 255, 255)"}); - - const featureList = options.features; - - if (featureList) { - - // Sort by score -- draw lowest scored features first - sortByScore(featureList, 1); - - for (let feature of featureList) { - - if (feature.startLeft) { - - let sl = Math.round((feature.startLeft - bpStart) / xScale); - let sr = Math.round((feature.startRight - bpStart) / xScale); - let el = Math.round((feature.endLeft - bpStart) / xScale); - let er = Math.round((feature.endRight - bpStart) / xScale); - - ctx.fillStyle = feature.color; - ctx.strokeStyle = feature.color; - ctx.beginPath(); - - // First arc - let x1 = (sl + er) / 2; - let r1 = (er - sl) / 2; - let y1 = this.height; - let sa = Math.PI + (Math.PI / 2 - theta); - let ea = 2 * Math.PI - (Math.PI / 2 - theta); - - if (orienation) { - y1 = 0; - ctx.arc(x1, y1, r1, ea, sa); - ctx.lineTo(er, y1); - } else { - ctx.arc(x1, y1, r1, sa, ea); - ctx.lineTo(el, y1); - } - - // Second arc - const x2 = (sr + el) / 2; - const r2 = (el - sr) / 2; - const y2 = y1; // Only for theta == pi/2 - - if (orienation) { - ctx.arc(x2, y2, r2, sa, ea, true); - ctx.lineTo(el, y2); - } else { - ctx.arc(x2, y2, r2, ea, sa, true); - ctx.lineTo(sl, y2); - } - - ctx.stroke(); - ctx.fill(); - - feature.drawState = {x1: x1, y1: y1, r1: r1, x2: x2, y2: y2, r2: r2, sa: sa, ea: ea}; - } else { - let s = Math.round((feature.start - bpStart) / xScale); - let e = Math.round((feature.end - bpStart) / xScale); - - ctx.strokeStyle = feature.color; - - ctx.beginPath(); - - // First arc - let x = (s + e) / 2; - let r = (e - s) / 2; - let y = this.height; - let sa = Math.PI + (Math.PI / 2 - theta); - let ea = 2 * Math.PI - (Math.PI / 2 - theta); - - if (orienation) { - y = 0; - ctx.arc(x, y, r, ea, sa); - } else { - ctx.arc(x, y, r, sa, ea); - } - - ctx.stroke(); - - feature.drawState = {x1: x, y1: y, r1: r, sa: sa, ea: ea}; - - } - - } - } - } - - clickedFeatures(clickState) { - - const features = super.clickedFeatures(clickState); - - const clicked = []; - - // Sort by score in descending order (opposite order than drawn) - sortByScore(features, -1); - - for (let f of features) { - const ds = f.drawState; - - // Distance from arc radius, or outer arc for type ".bp" - const dx1 = (clickState.canvasX - ds.x1); - const dy1 = (clickState.canvasY - ds.y1); - const d1 = Math.sqrt(dx1 * dx1 + dy1 * dy1); - const outerLim = ds.r1 + 3; - - - let d2; - let innerLim; - if (ds.x2 === undefined) { - d2 = d1; - innerLim = ds.r1 - 3; - - } else { - const dx2 = (clickState.canvasX - ds.x2); - const dy2 = (clickState.canvasY - ds.y2); - d2 = Math.sqrt(dx2 * dx2 + dy2 * dy2); - innerLim = ds.r2 - 3; - } - - - // Between outer and inner arcs, with some tolerance - if (d1 < outerLim && d2 > innerLim) { - clicked.push(f); - break - } - } - return clicked - } - - popupData(clickState, features) { - - if(features === undefined) features = this.clickedFeatures(clickState); - - if (features && features.length > 0) { - - return this.extractPopupData(features[0], this.getGenomeId()) - - } - } - - menuItemList() { - - var self = this; - - return [ - { - name: "Toggle arc direction", - click: function () { - self.arcOrientation = !self.arcOrientation; - self.trackView.repaintViews(); - } - } - ] - - }; - - -} - -function sortByScore(featureList, direction) { - - featureList.sort(function (a, b) { - const s1 = a.score === undefined ? -Number.MAX_VALUE : a.score; - const s2 = b.score === undefined ? -Number.MAX_VALUE : b.score; - const d = direction === undefined ? 1 : direction; - - return d * (s1 - s2) - }); -} - - -class RNAFeatureSource { - - constructor(config, genome) { - this.config = config; - this.genome = genome; - } - - async getFeatures({chr, start, end, bpPerPixel, visibilityWindow}) { - - - const genome = this.genome; - - if (!this.featureCache) { - - const options = buildOptions$1(this.config); - - const data = await igvxhr.loadString(this.config.url, options); - - this.featureCache = new FeatureCache$1(parseBP(data), genome); - - return this.featureCache.queryFeatures(chr, start, end) - - } else { - return this.featureCache.queryFeatures(chr, start, end) - } - - function parseBP(data) { - - if (!data) return null - - const dataWrapper = getDataWrapper(data); - - let header = true; - let line; - const colors = []; - const descriptors = []; - const features = []; - - while ((line = dataWrapper.nextLine()) !== undefined) { - - const tokens = line.split('\t'); - - if (header && line.startsWith("color:")) { - const color = "rgb(" + tokens[1] + "," + tokens[2] + "," + tokens[3] + ")"; - colors.push(color); - if (tokens.length > 4) { - descriptors.push(tokens[4]); - } - // TODO - use label - } else { - header = false; - - const chr = tokens[0]; - const startLeftNuc = Number.parseInt(tokens[1]) - 1; - const startRightNuc = Number.parseInt(tokens[2]) - 1; - const endLeftNuc = Number.parseInt(tokens[3]); - const endRightNuc = Number.parseInt(tokens[4]); - var colorIdx = Number.parseInt(tokens[5]); - const color = colors[colorIdx]; - - - let feature; - if (startLeftNuc <= endRightNuc) { - feature = { - chr: chr, - startLeft: Math.min(startLeftNuc, startRightNuc), - startRight: Math.max(startLeftNuc, startRightNuc), - endLeft: Math.min(endLeftNuc, endRightNuc), - endRight: Math.max(endLeftNuc, endRightNuc), - color: color, - score: colorIdx - }; - } else { - feature = { - chr: chr, - startLeft: Math.min(endLeftNuc, endRightNuc), - startRight: Math.max(endLeftNuc, endRightNuc), - endLeft: Math.min(startLeftNuc, startRightNuc), - endRight: Math.max(startLeftNuc, startRightNuc), - color: color, - score: colorIdx - }; - } - - feature.start = feature.startLeft; - feature.end = feature.endRight; - - if (descriptors.length > colorIdx) { - feature.description = descriptors[colorIdx]; - } - - features.push(feature); - } - } - - return features - } - } -} - -/* - * The MIT License (MIT) - * - * Copyright (c) 2014 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -/** - * Class represents an ideogram of a chromsome cytobands. It is used for the header of a track panel. - * - */ -class IdeogramTrack { - constructor(browser) { - this.browser = browser; - this.type = 'ideogram'; - this.height = 16; - this.order = Number.MIN_SAFE_INTEGER; - this.disableButtons = true; - this.ignoreTrackMenu = true; - } - - async getFeatures(chr, start, end) { - return [] - } - - computePixelHeight(ignore) { - return this.height - } - - draw({context, referenceFrame, pixelWidth, pixelHeight}) { - - const chr = referenceFrame.chr; - const chromosome = referenceFrame.genome.getChromosome(chr); - - if (undefined === chromosome || pixelWidth <= 0 || pixelHeight <= 0 || 'all' === chr.toLowerCase()) { - return - } - - const stainColors = []; - - drawIdeogram({ - ctx: context, - chr, - referenceFrame, - genome: referenceFrame.genome, - width: pixelWidth, - height: pixelHeight, - stainColors - }); - - const widthBP = Math.round(referenceFrame.bpPerPixel * pixelWidth); - const xBP = referenceFrame.start; - - // Total chromosome length can be > chromosome.bpLength for partial fastas. - let chrLength = chromosome.bpLength; - const cytobands = referenceFrame.genome.getCytobands(chr); - if (cytobands && cytobands.length > 0 && cytobands[cytobands.length - 1].end) { - chrLength = Math.max(chrLength, cytobands[cytobands.length - 1].end); - chromosome.bpLength = chrLength; // Correct bp length, bit of a hack - } - - if (widthBP < chrLength) { - - const percentWidth = widthBP / chrLength; - const percentX = xBP / chrLength; - - let x = Math.floor(percentX * pixelWidth); - let ww = Math.floor(percentWidth * pixelWidth); - - x = Math.max(0, x); - x = Math.min(pixelWidth - ww, x); - - // Push current context - context.save(); - - // Draw red box - context.strokeStyle = "red"; - context.lineWidth = (ww < 2) ? 1 : 2; - - const xx = x + (context.lineWidth) / 2; - ww = (ww < 2) ? 1 : ww - context.lineWidth; - - const yy = context.lineWidth / 2; - const hh = pixelHeight - context.lineWidth; - - context.strokeRect(xx, yy, ww, hh); - - // Pop current context - context.restore(); - } - - } - - dispose() { - this.trackView = undefined; - } -} - -function drawIdeogram({ctx, chr, referenceFrame, genome, width, height, stainColors}) { - - const shim = 1; - const shim2 = 0.5 * shim; - const ideogramTop = 0; - - if (undefined === genome) { - return - } - - IGVGraphics.fillRect(ctx, 0, 0, width, height, {fillStyle: IGVColor.greyScale(255)}); - - const cytobands = genome.getCytobands(chr); - if (cytobands) { - - const center = (ideogramTop + height / 2); - - const xC = []; - const yC = []; - - if (0 === cytobands.length) { - return - } - - // Get chrLength from the cytobands -- chromsome.bpLength might not work for igv-reports fasta files, which - // contain only a portion of the chromosome sequence - // *DOESNT WORK* const chrLength = referenceFrame.genome.getChromosome(chr).bpLength; - - const chrLength = cytobands[cytobands.length - 1].end; - const scale = width / chrLength; - - // round rect clipping path - ctx.beginPath(); - IGVGraphics.roundRect(ctx, shim2, shim2 + ideogramTop, width - 2 * shim2, height - 2 * shim2, (height - 2 * shim2) / 2, 0, 1); - ctx.clip(); - - for (let i = 0; i < cytobands.length; i++) { - - const cytoband = cytobands[i]; - const start = scale * cytoband.start; - const end = scale * cytoband.end; - - if (cytoband.type === 'c') { - - if (cytoband.name.charAt(0) === 'p') { - xC[0] = start; - yC[0] = height + ideogramTop; - xC[1] = start; - yC[1] = ideogramTop; - xC[2] = end; - yC[2] = center; - } else { - xC[0] = end; - yC[0] = height + ideogramTop; - xC[1] = end; - yC[1] = ideogramTop; - xC[2] = start; - yC[2] = center; - } - - ctx.fillStyle = "rgb(150, 0, 0)"; - ctx.strokeStyle = "rgb(150, 0, 0)"; - IGVGraphics.polygon(ctx, xC, yC, 1, 0); - } else { - - ctx.fillStyle = getCytobandColor(stainColors, cytoband); - IGVGraphics.fillRect(ctx, start, shim + ideogramTop, (end - start), height - 2 * shim); - } - } - } - - // round rect border - ctx.strokeStyle = IGVColor.greyScale(41); - IGVGraphics.roundRect(ctx, shim2, shim2 + ideogramTop, width - 2 * shim2, height - 2 * shim2, (height - 2 * shim2) / 2, 0, 1); -} - -function getCytobandColor(colors, data) { - - if (data.type === 'c') { // centermere: "acen" - return "rgb(150, 10, 10)" - } else { - var stain = data.stain; // + 4; - - var shade = 230; - if (data.type === 'p') { - shade = Math.floor(230 - stain / 100.0 * 230); - } - var c = colors[shade]; - if (!c) { - c = "rgb(" + shade + "," + shade + "," + shade + ")"; - colors[shade] = c; - } - return c - - } -} - -/* - * The MIT License (MIT) - * - * Copyright (c) 2014 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -let JUNCTION_MOTIF_PALETTE = new PaletteColorTable("Dark2"); - -// Lock in color-to-motif mapping so it's independent of data loading order. This list may not include all possible -// motif values as this varies depending on the RNA-seq pipeline. The current list is based on STAR v2.4 docs. -const someMotifValues = ['GT/AG', 'CT/AC', 'GC/AG', 'CT/GC', 'AT/AC', 'GT/AT', 'non-canonical']; -someMotifValues.forEach(motif => { - JUNCTION_MOTIF_PALETTE.getColor(motif); -}); - -// rendering context with values that only need to be computed once per render, rather than for each splice junction -const junctionRenderingContext = {}; - -class SpliceJunctionTrack extends TrackBase { - - constructor(config, browser) { - super(config, browser); - } - - - init(config) { - - super.init(config); - - this.type = config.type || 'junctions'; - - if (config._featureSource) { - this.featureSource = config._featureSource; - delete config._featureSource; - } else { - this.featureSource = config.featureSource ? - config.featureSource : - FeatureSource(config, this.browser.genome); - } - - this.margin = config.margin === undefined ? 10 : config.margin; - - if (!this.height) { - this.height = 100; - } - - //set defaults - if (config.colorByNumReadsThreshold === undefined) { - config.colorByNumReadsThreshold = 5; - } - } - - async postInit() { - - if (typeof this.featureSource.getHeader === "function") { - this.header = await this.featureSource.getHeader(); - if (this.disposed) return // This track was removed during async load - } - - // Set properties from track line - if (this.header) { - this.setTrackProperties(this.header); - } - - if (this.visibilityWindow === undefined && typeof this.featureSource.defaultVisibilityWindow === 'function') { - this.visibilityWindow = await this.featureSource.defaultVisibilityWindow(); - } - - return this - - } - - get supportsWholeGenome() { - return false - } - - async getFeatures(chr, start, end, bpPerPixel) { - const visibilityWindow = this.visibilityWindow; - return this.featureSource.getFeatures({chr, start, end, bpPerPixel, visibilityWindow}) - }; - - - /** - * The required height in pixels required for the track content. This is not the visible track height, which - * can be smaller (with a scrollbar) or larger. - * - * @param features - * @returns {*} - */ - computePixelHeight(features) { - return this.height - }; - - draw(options) { - - const featureList = options.features; - const ctx = options.context; - const bpPerPixel = options.bpPerPixel; - const bpStart = options.bpStart; - const pixelWidth = options.pixelWidth; - const pixelHeight = options.pixelHeight; - const bpEnd = bpStart + pixelWidth * bpPerPixel + 1; - - - if (!this.config.isMergedTrack) { - IGVGraphics.fillRect(ctx, 0, options.pixelTop, pixelWidth, pixelHeight, {'fillStyle': "rgb(255, 255, 255)"}); - } - - if (featureList) { - - - junctionRenderingContext.referenceFrame = options.viewport.referenceFrame; - junctionRenderingContext.referenceFrameStart = junctionRenderingContext.referenceFrame.start; - junctionRenderingContext.referenceFrameEnd = junctionRenderingContext.referenceFrameStart + - junctionRenderingContext.referenceFrame.toBP(options.viewport.getWidth()); - - // For a given viewport, records where features that are < 2px in width have been rendered already. - // This prevents wasteful rendering of multiple such features onto the same pixels. - junctionRenderingContext.featureZoomOutTracker = {}; - - for (let feature of featureList) { - if (feature.end < bpStart) continue - if (feature.start > bpEnd) break - this.renderJunction(feature, bpStart, bpPerPixel, pixelHeight, ctx); - } - - } else { - console.log("No feature list"); - } - - }; - - /** - * - * @param feature - * @param bpStart genomic location of the left edge of the current canvas - * @param xScale scale in base-pairs per pixel - * @param pixelHeight pixel height of the current canvas - * @param ctx the canvas 2d context - */ - renderJunction(feature, bpStart, xScale, pixelHeight, ctx) { - // cache whether this junction is rendered or filtered out. Use later to exclude non-rendered junctions from click detection. - feature.isVisible = false; - - const junctionLeftPx = Math.round((feature.start - bpStart) / xScale); - const junctionRightPx = Math.round((feature.end - bpStart) / xScale); - const junctionMiddlePx = (junctionLeftPx + junctionRightPx) / 2; - if (junctionRightPx - junctionLeftPx <= 3) { - if (junctionMiddlePx in junctionRenderingContext.featureZoomOutTracker) { - return - } - junctionRenderingContext.featureZoomOutTracker[junctionMiddlePx] = true; - } - - // TODO: cache filter and pixel calculations by doing them earlier when features are initially parsed? - if (this.config.hideAnnotatedJunctions && feature.attributes.annotated_junction === "true") { - return - } - if (this.config.hideUnannotatedJunctions && feature.attributes.annotated_junction === "false") { - return - } - if (this.config.hideMotifs && this.config.hideMotifs.includes(feature.attributes.motif)) { - return - } - if (this.config.hideStrand === feature.strand) { - return - } - - // check if splice junction is inside viewport - if (this.config.minJunctionEndsVisible) { - let numJunctionEndsVisible = 0; - if (feature.start >= junctionRenderingContext.referenceFrameStart && feature.start <= junctionRenderingContext.referenceFrameEnd) { - numJunctionEndsVisible += 1; - } - if (feature.end >= junctionRenderingContext.referenceFrameStart && feature.end <= junctionRenderingContext.referenceFrameEnd) { - numJunctionEndsVisible += 1; - } - if (numJunctionEndsVisible < this.config.minJunctionEndsVisible) { - return - } - } - - let uniquelyMappedReadCount; - let multiMappedReadCount; - let totalReadCount; - if (feature.attributes.uniquely_mapped) { - uniquelyMappedReadCount = parseInt(feature.attributes.uniquely_mapped); - if (uniquelyMappedReadCount < this.config.minUniquelyMappedReads) { - return - } - multiMappedReadCount = parseInt(feature.attributes.multi_mapped); - totalReadCount = uniquelyMappedReadCount + multiMappedReadCount; - if (totalReadCount < this.config.minTotalReads) { - return - } - if (totalReadCount > 0 && multiMappedReadCount / totalReadCount > this.config.maxFractionMultiMappedReads) { - return - } - if (feature.attributes.maximum_spliced_alignment_overhang && parseInt(feature.attributes.maximum_spliced_alignment_overhang) < this.config.minSplicedAlignmentOverhang) { - return - } - } - - let numSamplesWithThisJunction; - if (feature.attributes.num_samples_with_this_junction) { - numSamplesWithThisJunction = parseInt(feature.attributes.num_samples_with_this_junction); - if (this.config.minSamplesWithThisJunction && numSamplesWithThisJunction < this.config.minSamplesWithThisJunction) { - return - } - if (this.config.maxSamplesWithThisJunction && numSamplesWithThisJunction > this.config.maxSamplesWithThisJunction) { - return - } - if (feature.attributes.num_samples_total) { - feature.attributes.percent_samples_with_this_junction = 100 * numSamplesWithThisJunction / Number(feature.attributes.num_samples_total); - if (this.config.minPercentSamplesWithThisJunction) { - if (feature.attributes.percent_samples_with_this_junction < this.config.minPercentSamplesWithThisJunction || - feature.attributes.percent_samples_with_this_junction > this.config.maxPercentSamplesWithThisJunction) { - return - } - } - } - } - - const py = this.margin; - const rowHeight = this.height; - - const cy = py + 0.5 * rowHeight; - let topY = py; - const bottomY = py + rowHeight; - const bezierBottomY = bottomY - 10; - - // draw the junction arc - const bezierControlLeftPx = (junctionLeftPx + junctionMiddlePx) / 2; - const bezierControlRightPx = (junctionMiddlePx + junctionRightPx) / 2; - - let lineWidth = 1; - if (feature.attributes.line_width) { - lineWidth = Number(feature.attributes.line_width); - } else { - if (this.config.thicknessBasedOn === undefined || this.config.thicknessBasedOn === 'numUniqueReads') { - lineWidth = uniquelyMappedReadCount; - } else if (this.config.thicknessBasedOn === 'numReads') { - lineWidth = totalReadCount; - } else if (this.config.thicknessBasedOn === 'numSamplesWithThisJunction') { - if (numSamplesWithThisJunction !== undefined) { - lineWidth = numSamplesWithThisJunction; - } - } - lineWidth = 1 + Math.log(lineWidth + 1) / Math.log(12); - } - - let bounceHeight; - if (this.config.bounceHeightBasedOn === undefined || this.config.bounceHeightBasedOn === 'random') { - // randomly but deterministically stagger topY coordinates to reduce overlap - bounceHeight = (feature.start + feature.end) % 7; - } else if (this.config.bounceHeightBasedOn === 'distance') { - bounceHeight = 6 * (feature.end - feature.start) / (junctionRenderingContext.referenceFrameEnd - junctionRenderingContext.referenceFrameStart); - } else if (this.config.bounceHeightBasedOn === 'thickness') { - bounceHeight = 2 * lineWidth; - } - topY += rowHeight * Math.max(7 - bounceHeight, 0) / 10; - - let color; - if (feature.attributes.color) { - color = feature.attributes.color; // Explicit setting - } else if (this.config.colorBy === undefined || this.config.colorBy === 'numUniqueReads') { - color = uniquelyMappedReadCount > this.config.colorByNumReadsThreshold ? 'blue' : '#AAAAAA'; // color gradient? - } else if (this.config.colorBy === 'numReads') { - color = totalReadCount > this.config.colorByNumReadsThreshold ? 'blue' : '#AAAAAA'; - } else if (this.config.colorBy === 'isAnnotatedJunction') { - color = feature.attributes.annotated_junction === "true" ? '#b0b0ec' : 'orange'; - } else if (this.config.colorBy === 'strand') { - color = feature.strand === "+" ? '#b0b0ec' : '#ecb0b0'; - } else if (this.config.colorBy === 'motif') { - color = JUNCTION_MOTIF_PALETTE.getColor(feature.attributes.motif); - } else { - color = '#AAAAAA'; - } - - let label = ""; - if (feature.attributes.label) { - label = feature.attributes.label.replace(/_/g, " "); - } else if (this.config.labelWith === undefined || this.config.labelWith === 'uniqueReadCount') { - //default label - label = uniquelyMappedReadCount; - } else if (this.config.labelWith === 'totalReadCount') { - label = totalReadCount; - } else if (this.config.labelWith === 'numSamplesWithThisJunction') { - if (numSamplesWithThisJunction !== undefined) { - label = numSamplesWithThisJunction; - } - } else if (this.config.labelWith === 'percentSamplesWithThisJunction') { - if (feature.attributes.percent_samples_with_this_junction !== undefined) { - label = feature.attributes.percent_samples_with_this_junction.toFixed(0) + '%'; - } - } else if (this.config.labelWith === 'motif') { - if (feature.attributes.motif !== undefined) { - label += feature.attributes.motif; - } - } - - if (this.config.labelWithInParen === 'uniqueReadCount') { - label += ' (' + uniquelyMappedReadCount + ')'; - } else if (this.config.labelWithInParen === 'totalReadCount') { - label += ' (' + totalReadCount + ')'; - } else if (this.config.labelWithInParen === 'multiMappedReadCount') { - if (multiMappedReadCount > 0) { - label += ' (+' + multiMappedReadCount + ')'; - } - } else if (this.config.labelWithInParen === 'numSamplesWithThisJunction') { - if (numSamplesWithThisJunction !== undefined) { - label += ' (' + numSamplesWithThisJunction + ')'; - } - } else if (this.config.labelWithInParen === 'percentSamplesWithThisJunction') { - if (feature.attributes.percent_samples_with_this_junction !== undefined) { - label += ' (' + feature.attributes.percent_samples_with_this_junction.toFixed(0) + '%)'; - } - } else if (this.config.labelWithInParen === 'motif') { - if (feature.attributes.motif !== undefined) { - label += ` ${feature.attributes.motif}`; - } - } - - // data source: STAR splice junctions (eg. SJ.out.tab file converted to bed). - // .bed "name" field used to store unique + multi-mapped read counts, so: - // feature.score: unique spanning read counts - // feature.name: unique + multi-mapped spanning read counts - //example feature: { chr: "chr17", start: 39662344, end: 39662803, name: "59", row: 0, score: 38, strand: "+"} - feature.isVisible = true; - ctx.beginPath(); - ctx.moveTo(junctionLeftPx, bezierBottomY); - ctx.bezierCurveTo(bezierControlLeftPx, topY, bezierControlRightPx, topY, junctionRightPx, bezierBottomY); - - ctx.lineWidth = lineWidth; - ctx.strokeStyle = color; - ctx.stroke(); - - const drawArrowhead = (ctx, x, y, size) => { - //TODO draw better arrow heads: https://stackoverflow.com/questions/21052972/curved-thick-arrows-on-canvas - ctx.beginPath(); - ctx.moveTo(x, y); - ctx.lineTo(x - size / 2, y - size); - ctx.lineTo(x + size / 2, y - size); - ctx.lineTo(x, y); - ctx.closePath(); - ctx.fill(); - }; - - if (feature.attributes.left_shape || feature.attributes.right_shape) { - ctx.fillStyle = color; - const arrowSize = ctx.lineWidth > 2 ? 10 : 7; - if (feature.attributes.left_shape) { - drawArrowhead(ctx, junctionLeftPx, bezierBottomY, arrowSize); - } - if (feature.attributes.right_shape) { - drawArrowhead(ctx, junctionRightPx, bezierBottomY, arrowSize); - } - } - - ctx.fillText(label, junctionMiddlePx - ctx.measureText(label).width / 2, (7 * topY + cy) / 8); - } - - clickedFeatures(clickState) { - - const allFeatures = super.clickedFeatures(clickState); - - return allFeatures.filter(function (feature) { - return (feature.isVisible && feature.attributes) - }) - } - - /** - * Return "popup data" for feature @ genomic location. Data is an array of key-value pairs - */ - popupData(clickState, features) { - - if (features === undefined) features = this.clickedFeatures(clickState); - const genomicLocation = clickState.genomicLocation; - - const data = []; - for (let feature of features) { - - const featureData = (typeof feature.popupData === "function") ? - feature.popupData(genomicLocation) : - this.extractPopupData(feature._f || feature, this.getGenomeId()); - - if (featureData) { - if (data.length > 0) { - data.push("

"); - } - - Array.prototype.push.apply(data, featureData); - } - } - - return data - } - - /** - * Called when the track is removed. Do any needed cleanup here - */ - dispose() { - this.trackView = undefined; - } -} - -class RemoteFile$1 { - - constructor(args) { - this.config = args; - this.url = mapUrl$2(args.path || args.url); - } - - - async read(position, length) { - - //console.log(`${position} - ${position + length} (${length})`) - - const headers = this.config.headers || {}; - - if (position !== undefined && length) { - const rangeString = "bytes=" + position + "-" + (position + length - 1); - headers['Range'] = rangeString; - } - - let url = this.url.slice(); // slice => copy - if (this.config.oauthToken) { - const token = resolveToken(this.config.oauthToken); - headers['Authorization'] = `Bearer ${token}`; - } - - if (this.config.apiKey) { - url = addParameter$1(url, "key", this.config.apiKey); - } - - const response = await fetch(url, { - method: 'GET', - headers: headers, - redirect: 'follow', - mode: 'cors', - }); - - const status = response.status; - - if (status >= 400) { - const err = Error(response.statusText); - err.code = status; - throw err - } else { - return response.arrayBuffer() - } - - /** - * token can be a string, a function that returns a string, or a function that returns a Promise for a string - * @param token - * @returns {Promise<*>} - */ - async function resolveToken(token) { - if (typeof token === 'function') { - return await Promise.resolve(token()) // Normalize the result to a promise, since we don't know what the function returns - } else { - return token - } - } - - } -} - - -function mapUrl$2(url) { - - if (url.includes("//www.dropbox.com")) { - return url.replace("//www.dropbox.com", "//dl.dropboxusercontent.com") - } else if (url.startsWith("ftp://ftp.ncbi.nlm.nih.gov")) { - return url.replace("ftp://", "https://") - } else { - return url - } -} - - -function addParameter$1(url, name, value) { - const paramSeparator = url.includes("?") ? "&" : "?"; - return url + paramSeparator + name + "=" + value -} - -class BufferedFile$1 { - - constructor(args) { - this.file = args.file; - this.fetchSize = args.fetchSize || 16000; - this.maxSize = args.maxSize || 1000000; - this.buffers = []; - } - - async read(position, length) { - - - let overlappingBuffers = this.buffers.filter( b => b.overlaps(position, position + length)); - - // See if any buffers completely contain request, if so we're done - for(let buffer of overlappingBuffers) { - if(buffer.contains(position, position + length)) { - return buffer.slice(position, position + length) - } - } - - - if(overlappingBuffers.length === 0) { - - // No overlap with any existing buffer - let size = Math.max(length, this.fetchSize); - - // Find index of first buffer to the right, if any, to potentially limit size - this.buffers.sort((a, b) => a.start - b.start); - const idx = binarySearch(this.buffers, (b) => b.start > position, 0); - if(idx < this.buffers.length) { - size = Math.min(size, this.buffers[idx].start - position); - } - - const bufferStart = position; - const bufferData = await this.file.read(bufferStart, size); - const buffer = new Buffer$1(bufferStart, bufferData); - this.addBuffer(buffer); - - return buffer.slice(position, position + length) - } else { - - // console.log("Cache hit") - // Some overlap. Fill gaps - overlappingBuffers.sort((a, b) => a.start - b.start); - const allBuffers = []; - let currentEnd = position; - for (let ob of overlappingBuffers) { - if (currentEnd < ob.start) { - const bufferStart = currentEnd; - const bufferSize = ob.start - currentEnd; - const bufferData = await this.file.read(bufferStart, bufferSize); - const buffer = new Buffer$1(bufferStart, bufferData); - allBuffers.push(buffer); - } - allBuffers.push(ob); - currentEnd = ob.end; - } - - // Check end - const requestedEnd = position + length; - if (requestedEnd > currentEnd) { - const bufferStart = currentEnd; - const bufferSize = requestedEnd - bufferStart; - const bufferData = await this.file.read(bufferStart, bufferSize); - const buffer = new Buffer$1(bufferStart, bufferData); - allBuffers.push(buffer); - } - - const newStart = allBuffers[0].start; - const newArrayBuffer = concatArrayBuffers(allBuffers.map(b => b.buffer)); - const newBuffer = new Buffer$1(newStart, newArrayBuffer); - - // Replace the overlapping buffers with the new composite one - const tmp = new Set(overlappingBuffers); - this.buffers = this.buffers.filter(b => !tmp.has(b)); - this.addBuffer(newBuffer); - - return newBuffer.slice(position, position + length) - } - - } - - addBuffer(buffer) { - - const size = this.buffers.reduce((a,b) => a + b.size, 0) + buffer.size; - if(size > this.maxSize) { - // console.log(`max buffer size exceeded`) - const overage = size - this.maxSize; - this.buffers.sort((a,b) => a.creationTime - b.creationTime); - let sum = 0; - let i; - for(i=0; i overage) { - break - } - } - // console.log('removing buffers') - // for(let j=0; j this.buffer.byteLength) { - throw Error("buffer bounds error") - } - return this.buffer.slice(start - this.start, end - this.start) - } - - get end() { - return this.start + this.buffer.byteLength - } - - get size() { - return this.buffer.byteLength - } - - contains(start, end) { - return start >= this.start && end <= this.end - } - - overlaps(start, end) { - return (start > this.start && start < this.end) || (end > this.start && end < this.end) - } - - toString() { - return `Buffer ${this.creationTime} ${this.start} - ${this.end}` - } - -} - -/** - * concatenates 2 array buffers. - * Credit: https://gist.github.com/72lions/4528834 - * - * @private - * @param {ArrayBuffers} buffer1 The first buffer. - * @param {ArrayBuffers} buffer2 The second buffer. - * @return {ArrayBuffers} The new ArrayBuffer created out of the two. - */ -function concatArrayBuffers(buffers) { - const size = buffers.reduce((a,b) => a + b.byteLength, 0); - const tmp = new Uint8Array(size); - let offset = 0; - for(let b of buffers) { - tmp.set(new Uint8Array(b), offset); - offset += b.byteLength; - } - return tmp.buffer -} - -/** - * Return 0 <= i <= array.length such that !pred(array[i - 1]) && pred(array[i]). - * - * returns an index 0 ≤ i ≤ array.length such that the given predicate is false for array[i - 1] and true for array[i]* * - */ -function binarySearch(array, pred, min) { - let lo = min - 1, hi = array.length; - while (1 + lo < hi) { - const mi = lo + ((hi - lo) >> 1); - if (pred(array[mi])) { - hi = mi; - } else { - lo = mi; - } - } - return hi -} - -class BlobFile { - - constructor(blob) { - this.file = blob; - } - - async read(position, length) { - - if(length === 0) { - return new ArrayBuffer() - } - - const blob = (position != undefined && length) ? - this.file.slice(position, position + length) : - this.file; - - return blob.arrayBuffer() - } -} - -var __defProp = Object.defineProperty; -var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; -var __publicField = (obj, key, value) => { - __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value); - return value; -}; - -// esm/core.js -async function _unpack_struct_from_async(structure, async_buf, offset = 0) { - var output = /* @__PURE__ */ new Map(); - for (let [key, fmt] of structure.entries()) { - let value = await struct.unpack_from_async("<" + fmt, async_buf, offset); - offset += struct.calcsize(fmt); - if (value.length == 1) { - value = value[0]; - } - output.set(key, value); - } - return output; -} -function _unpack_struct_from(structure, buf, offset = 0) { - var output = /* @__PURE__ */ new Map(); - for (let [key, fmt] of structure.entries()) { - let value = struct.unpack_from("<" + fmt, buf, offset); - offset += struct.calcsize(fmt); - if (value.length == 1) { - value = value[0]; - } - output.set(key, value); - } - return output; -} -function assert(thing) { - if (!thing) { - thing(); - } -} -function _structure_size(structure) { - var fmt = "<" + Array.from(structure.values()).join(""); - return struct.calcsize(fmt); -} -function _padded_size(size, padding_multiple = 8) { - return Math.ceil(size / padding_multiple) * padding_multiple; -} -var dtype_to_format = { - "u": "Uint", - "i": "Int", - "f": "Float" -}; -function dtype_getter(dtype_str) { - var big_endian = struct._is_big_endian(dtype_str); - var getter, nbytes; - if (/S/.test(dtype_str)) { - getter = "getString"; - nbytes = ((dtype_str.match(/S(\d*)/) || [])[1] || 1) | 0; - } else { - let [_, fstr, bytestr] = dtype_str.match(/[<>=!@]?(i|u|f)(\d*)/); - nbytes = parseInt(bytestr || 4, 10); - let nbits = nbytes * 8; - getter = "get" + dtype_to_format[fstr] + nbits.toFixed(); - } - return [getter, big_endian, nbytes]; -} -var Struct = class { - constructor() { - this.big_endian = isBigEndian(); - this.getters = { - "s": "getUint8", - "b": "getInt8", - "B": "getUint8", - "h": "getInt16", - "H": "getUint16", - "i": "getInt32", - "I": "getUint32", - "l": "getInt32", - "L": "getUint32", - "q": "getInt64", - "Q": "getUint64", - "f": "getFloat32", - "d": "getFloat64" - }; - this.byte_lengths = { - "s": 1, - "b": 1, - "B": 1, - "h": 2, - "H": 2, - "i": 4, - "I": 4, - "l": 4, - "L": 4, - "q": 8, - "Q": 8, - "f": 4, - "d": 8 - }; - let all_formats = Object.keys(this.byte_lengths).join(""); - this.fmt_size_regex = "(\\d*)([" + all_formats + "])"; - } - calcsize(fmt) { - var size = 0; - var match; - var regex = new RegExp(this.fmt_size_regex, "g"); - while ((match = regex.exec(fmt)) !== null) { - let n = parseInt(match[1] || 1, 10); - let f = match[2]; - let subsize = this.byte_lengths[f]; - size += n * subsize; - } - return size; - } - _is_big_endian(fmt) { - var big_endian; - if (/^)/.test(fmt)) { - big_endian = true; - } else { - big_endian = this.big_endian; - } - return big_endian; - } - async unpack_from_async(fmt, async_buf, offset) { - offset = Number.parseInt(offset || 0); - const total_size = this.calcsize(fmt); - const local_buffer = await async_buf.slice(offset, offset + total_size); - let local_offset = 0; - var view = new DataView64(local_buffer); - var output = []; - var big_endian = this._is_big_endian(fmt); - var match; - var regex = new RegExp(this.fmt_size_regex, "g"); - while ((match = regex.exec(fmt)) !== null) { - let n = parseInt(match[1] || 1, 10); - let f = match[2]; - let getter = this.getters[f]; - let size = this.byte_lengths[f]; - if (f == "s") { - output.push(new TextDecoder().decode(local_buffer.slice(local_offset, local_offset + n))); - local_offset += n; - } else { - for (var i = 0; i < n; i++) { - output.push(view[getter](local_offset, !big_endian)); - local_offset += size; - } - } - } - return output; - } - unpack_from(fmt, buffer, offset) { - offset = Number.parseInt(offset || 0); - const total_size = this.calcsize(fmt); - const local_buffer = buffer.slice(offset, offset + total_size); - let local_offset = 0; - var view = new DataView64(local_buffer); - var output = []; - var big_endian = this._is_big_endian(fmt); - var match; - var regex = new RegExp(this.fmt_size_regex, "g"); - while ((match = regex.exec(fmt)) !== null) { - let n = parseInt(match[1] || 1, 10); - let f = match[2]; - let getter = this.getters[f]; - let size = this.byte_lengths[f]; - if (f == "s") { - output.push(new TextDecoder().decode(local_buffer.slice(local_offset, local_offset + n))); - local_offset += n; - } else { - for (var i = 0; i < n; i++) { - output.push(view[getter](local_offset, !big_endian)); - local_offset += size; - } - } - } - return output; - } -}; -var struct = new Struct(); -function isBigEndian() { - const array = new Uint8Array(4); - const view = new Uint32Array(array.buffer); - return !((view[0] = 1) & array[0]); -} -var DataView64 = class extends DataView { - getUint64(byteOffset, littleEndian) { - const left = BigInt(this.getUint32(byteOffset, littleEndian)); - const right = BigInt(this.getUint32(byteOffset + 4, littleEndian)); - let combined = littleEndian ? left + (right << 32n) : (left << 32n) + right; - return Number.parseInt(combined); - } - getInt64(byteOffset, littleEndian) { - var low, high; - if (littleEndian) { - low = this.getUint32(byteOffset, true); - high = this.getInt32(byteOffset + 4, true); - } else { - high = this.getInt32(byteOffset, false); - low = this.getUint32(byteOffset + 4, false); - } - let combined = BigInt(low) + (BigInt(high) << 32n); - return Number.parseInt(combined); - } - getString(byteOffset, littleEndian, length) { - const str_buffer = this.buffer.slice(byteOffset, byteOffset + length); - const decoder = new TextDecoder(); - return decoder.decode(str_buffer); - } - getVLENStruct(byteOffset, littleEndian, length) { - let item_size = this.getUint32(byteOffset, littleEndian); - let collection_address = this.getUint64(byteOffset + 4, littleEndian); - let object_index = this.getUint32(byteOffset + 12, littleEndian); - return [item_size, collection_address, object_index]; - } -}; -function bitSize(integer) { - return integer.toString(2).length; -} -function _unpack_integer(nbytes, buf, offset = 0, littleEndian = true) { - const local_buffer = buf.slice(offset, offset + nbytes); - let bytes = new Uint8Array(local_buffer); - if (!littleEndian) { - bytes.reverse(); - } - let integer = bytes.reduce((accumulator, currentValue, index) => accumulator + (currentValue << index * 8), 0); - return integer; -} - -// esm/datatype-msg.js -var DatatypeMessage = class { - constructor(buf, offset) { - this.buf = buf; - this.offset = offset; - this.dtype = this.determine_dtype(); - } - async determine_dtype() { - let datatype_msg = await _unpack_struct_from_async(DATATYPE_MSG, this.buf, this.offset); - this.offset += DATATYPE_MSG_SIZE; - let datatype_class = datatype_msg.get("class_and_version") & 15; - if (datatype_class == DATATYPE_FIXED_POINT) { - return this._determine_dtype_fixed_point(datatype_msg); - } else if (datatype_class == DATATYPE_FLOATING_POINT) { - return this._determine_dtype_floating_point(datatype_msg); - } else if (datatype_class == DATATYPE_TIME) { - throw "Time datatype class not supported."; - } else if (datatype_class == DATATYPE_STRING) { - return this._determine_dtype_string(datatype_msg); - } else if (datatype_class == DATATYPE_BITFIELD) { - throw "Bitfield datatype class not supported."; - } else if (datatype_class == DATATYPE_OPAQUE) { - return { - datatype_class: DATATYPE_OPAQUE, - size: datatype_msg.get("size") - }; - } else if (datatype_class == DATATYPE_COMPOUND) { - return this._determine_dtype_compound(datatype_msg); - } else if (datatype_class == DATATYPE_REFERENCE) { - return ["REFERENCE", datatype_msg.get("size")]; - } else if (datatype_class == DATATYPE_ENUMERATED) { - return this.determine_dtype(); - } else if (datatype_class == DATATYPE_ARRAY) { - throw "Array datatype class not supported."; - } else if (datatype_class == DATATYPE_VARIABLE_LENGTH) { - let vlen_type = this._determine_dtype_vlen(datatype_msg); - if (vlen_type[0] == "VLEN_SEQUENCE") { - let base_type = this.determine_dtype(); - vlen_type = ["VLEN_SEQUENCE", base_type]; - } - return vlen_type; - } else { - throw "Invalid datatype class " + datatype_class; - } - } - _determine_dtype_fixed_point(datatype_msg) { - let length_in_bytes = datatype_msg.get("size"); - if (![1, 2, 4, 8].includes(length_in_bytes)) { - throw "Unsupported datatype size"; - } - let signed = datatype_msg.get("class_bit_field_0") & 8; - var dtype_char; - if (signed > 0) { - dtype_char = "i"; - } else { - dtype_char = "u"; - } - let byte_order = datatype_msg.get("class_bit_field_0") & 1; - var byte_order_char; - if (byte_order == 0) { - byte_order_char = "<"; - } else { - byte_order_char = ">"; - } - this.offset += 4; - return byte_order_char + dtype_char + length_in_bytes.toFixed(); - } - _determine_dtype_floating_point(datatype_msg) { - let length_in_bytes = datatype_msg.get("size"); - if (![1, 2, 4, 8].includes(length_in_bytes)) { - throw "Unsupported datatype size"; - } - let dtype_char = "f"; - let byte_order = datatype_msg.get("class_bit_field_0") & 1; - var byte_order_char; - if (byte_order == 0) { - byte_order_char = "<"; - } else { - byte_order_char = ">"; - } - this.offset += 12; - return byte_order_char + dtype_char + length_in_bytes.toFixed(); - } - _determine_dtype_string(datatype_msg) { - return "S" + datatype_msg.get("size").toFixed(); - } - _determine_dtype_vlen(datatype_msg) { - let vlen_type = datatype_msg.get("class_bit_field_0") & 1; - if (vlen_type != 1) { - return ["VLEN_SEQUENCE", 0, 0]; - } - let padding_type = datatype_msg.get("class_bit_field_0") >> 4; - let character_set = datatype_msg.get("class_bit_field_1") & 1; - return ["VLEN_STRING", padding_type, character_set]; - } - _determine_dtype_compound(datatype_msg) { - throw "Compound type not yet implemented!"; - } -}; -var DATATYPE_MSG = /* @__PURE__ */ new Map([ - ["class_and_version", "B"], - ["class_bit_field_0", "B"], - ["class_bit_field_1", "B"], - ["class_bit_field_2", "B"], - ["size", "I"] -]); -var DATATYPE_MSG_SIZE = _structure_size(DATATYPE_MSG); -var COMPOUND_PROP_DESC_V1 = /* @__PURE__ */ new Map([ - ["offset", "I"], - ["dimensionality", "B"], - ["reserved_0", "B"], - ["reserved_1", "B"], - ["reserved_2", "B"], - ["permutation", "I"], - ["reserved_3", "I"], - ["dim_size_1", "I"], - ["dim_size_2", "I"], - ["dim_size_3", "I"], - ["dim_size_4", "I"] -]); -_structure_size(COMPOUND_PROP_DESC_V1); -var DATATYPE_FIXED_POINT = 0; -var DATATYPE_FLOATING_POINT = 1; -var DATATYPE_TIME = 2; -var DATATYPE_STRING = 3; -var DATATYPE_BITFIELD = 4; -var DATATYPE_OPAQUE = 5; -var DATATYPE_COMPOUND = 6; -var DATATYPE_REFERENCE = 7; -var DATATYPE_ENUMERATED = 8; -var DATATYPE_VARIABLE_LENGTH = 9; -var DATATYPE_ARRAY = 10; -function zero$1(buf) { - let len = buf.length; - while (--len >= 0) { - buf[len] = 0; - } -} -var MIN_MATCH$1 = 3; -var MAX_MATCH$1 = 258; -var LENGTH_CODES$1 = 29; -var LITERALS$1 = 256; -var L_CODES$1 = LITERALS$1 + 1 + LENGTH_CODES$1; -var D_CODES$1 = 30; -var DIST_CODE_LEN = 512; -var static_ltree = new Array((L_CODES$1 + 2) * 2); -zero$1(static_ltree); -var static_dtree = new Array(D_CODES$1 * 2); -zero$1(static_dtree); -var _dist_code = new Array(DIST_CODE_LEN); -zero$1(_dist_code); -var _length_code = new Array(MAX_MATCH$1 - MIN_MATCH$1 + 1); -zero$1(_length_code); -var base_length = new Array(LENGTH_CODES$1); -zero$1(base_length); -var base_dist = new Array(D_CODES$1); -zero$1(base_dist); -var adler32 = (adler, buf, len, pos) => { - let s1 = adler & 65535 | 0, s2 = adler >>> 16 & 65535 | 0, n = 0; - while (len !== 0) { - n = len > 2e3 ? 2e3 : len; - len -= n; - do { - s1 = s1 + buf[pos++] | 0; - s2 = s2 + s1 | 0; - } while (--n); - s1 %= 65521; - s2 %= 65521; - } - return s1 | s2 << 16 | 0; -}; -var adler32_1 = adler32; -var makeTable = () => { - let c, table = []; - for (var n = 0; n < 256; n++) { - c = n; - for (var k = 0; k < 8; k++) { - c = c & 1 ? 3988292384 ^ c >>> 1 : c >>> 1; - } - table[n] = c; - } - return table; -}; -var crcTable = new Uint32Array(makeTable()); -var crc32 = (crc, buf, len, pos) => { - const t = crcTable; - const end = pos + len; - crc ^= -1; - for (let i = pos; i < end; i++) { - crc = crc >>> 8 ^ t[(crc ^ buf[i]) & 255]; - } - return crc ^ -1; -}; -var crc32_1 = crc32; -var messages = { - 2: "need dictionary", - 1: "stream end", - 0: "", - "-1": "file error", - "-2": "stream error", - "-3": "data error", - "-4": "insufficient memory", - "-5": "buffer error", - "-6": "incompatible version" -}; -var constants$2 = { - Z_NO_FLUSH: 0, - Z_PARTIAL_FLUSH: 1, - Z_SYNC_FLUSH: 2, - Z_FULL_FLUSH: 3, - Z_FINISH: 4, - Z_BLOCK: 5, - Z_TREES: 6, - Z_OK: 0, - Z_STREAM_END: 1, - Z_NEED_DICT: 2, - Z_ERRNO: -1, - Z_STREAM_ERROR: -2, - Z_DATA_ERROR: -3, - Z_MEM_ERROR: -4, - Z_BUF_ERROR: -5, - Z_NO_COMPRESSION: 0, - Z_BEST_SPEED: 1, - Z_BEST_COMPRESSION: 9, - Z_DEFAULT_COMPRESSION: -1, - Z_FILTERED: 1, - Z_HUFFMAN_ONLY: 2, - Z_RLE: 3, - Z_FIXED: 4, - Z_DEFAULT_STRATEGY: 0, - Z_BINARY: 0, - Z_TEXT: 1, - Z_UNKNOWN: 2, - Z_DEFLATED: 8 -}; -var _has = (obj, key) => { - return Object.prototype.hasOwnProperty.call(obj, key); -}; -var assign = function(obj) { - const sources = Array.prototype.slice.call(arguments, 1); - while (sources.length) { - const source = sources.shift(); - if (!source) { - continue; - } - if (typeof source !== "object") { - throw new TypeError(source + "must be non-object"); - } - for (const p in source) { - if (_has(source, p)) { - obj[p] = source[p]; - } - } - } - return obj; -}; -var flattenChunks = (chunks) => { - let len = 0; - for (let i = 0, l = chunks.length; i < l; i++) { - len += chunks[i].length; - } - const result = new Uint8Array(len); - for (let i = 0, pos = 0, l = chunks.length; i < l; i++) { - let chunk = chunks[i]; - result.set(chunk, pos); - pos += chunk.length; - } - return result; -}; -var common = { - assign, - flattenChunks -}; -var STR_APPLY_UIA_OK = true; -try { - String.fromCharCode.apply(null, new Uint8Array(1)); -} catch (__) { - STR_APPLY_UIA_OK = false; -} -var _utf8len = new Uint8Array(256); -for (let q = 0; q < 256; q++) { - _utf8len[q] = q >= 252 ? 6 : q >= 248 ? 5 : q >= 240 ? 4 : q >= 224 ? 3 : q >= 192 ? 2 : 1; -} -_utf8len[254] = _utf8len[254] = 1; -var string2buf = (str) => { - if (typeof TextEncoder === "function" && TextEncoder.prototype.encode) { - return new TextEncoder().encode(str); - } - let buf, c, c2, m_pos, i, str_len = str.length, buf_len = 0; - for (m_pos = 0; m_pos < str_len; m_pos++) { - c = str.charCodeAt(m_pos); - if ((c & 64512) === 55296 && m_pos + 1 < str_len) { - c2 = str.charCodeAt(m_pos + 1); - if ((c2 & 64512) === 56320) { - c = 65536 + (c - 55296 << 10) + (c2 - 56320); - m_pos++; - } - } - buf_len += c < 128 ? 1 : c < 2048 ? 2 : c < 65536 ? 3 : 4; - } - buf = new Uint8Array(buf_len); - for (i = 0, m_pos = 0; i < buf_len; m_pos++) { - c = str.charCodeAt(m_pos); - if ((c & 64512) === 55296 && m_pos + 1 < str_len) { - c2 = str.charCodeAt(m_pos + 1); - if ((c2 & 64512) === 56320) { - c = 65536 + (c - 55296 << 10) + (c2 - 56320); - m_pos++; - } - } - if (c < 128) { - buf[i++] = c; - } else if (c < 2048) { - buf[i++] = 192 | c >>> 6; - buf[i++] = 128 | c & 63; - } else if (c < 65536) { - buf[i++] = 224 | c >>> 12; - buf[i++] = 128 | c >>> 6 & 63; - buf[i++] = 128 | c & 63; - } else { - buf[i++] = 240 | c >>> 18; - buf[i++] = 128 | c >>> 12 & 63; - buf[i++] = 128 | c >>> 6 & 63; - buf[i++] = 128 | c & 63; - } - } - return buf; -}; -var buf2binstring = (buf, len) => { - if (len < 65534) { - if (buf.subarray && STR_APPLY_UIA_OK) { - return String.fromCharCode.apply(null, buf.length === len ? buf : buf.subarray(0, len)); - } - } - let result = ""; - for (let i = 0; i < len; i++) { - result += String.fromCharCode(buf[i]); - } - return result; -}; -var buf2string = (buf, max) => { - const len = max || buf.length; - if (typeof TextDecoder === "function" && TextDecoder.prototype.decode) { - return new TextDecoder().decode(buf.subarray(0, max)); - } - let i, out; - const utf16buf = new Array(len * 2); - for (out = 0, i = 0; i < len; ) { - let c = buf[i++]; - if (c < 128) { - utf16buf[out++] = c; - continue; - } - let c_len = _utf8len[c]; - if (c_len > 4) { - utf16buf[out++] = 65533; - i += c_len - 1; - continue; - } - c &= c_len === 2 ? 31 : c_len === 3 ? 15 : 7; - while (c_len > 1 && i < len) { - c = c << 6 | buf[i++] & 63; - c_len--; - } - if (c_len > 1) { - utf16buf[out++] = 65533; - continue; - } - if (c < 65536) { - utf16buf[out++] = c; - } else { - c -= 65536; - utf16buf[out++] = 55296 | c >> 10 & 1023; - utf16buf[out++] = 56320 | c & 1023; - } - } - return buf2binstring(utf16buf, out); -}; -var utf8border = (buf, max) => { - max = max || buf.length; - if (max > buf.length) { - max = buf.length; - } - let pos = max - 1; - while (pos >= 0 && (buf[pos] & 192) === 128) { - pos--; - } - if (pos < 0) { - return max; - } - if (pos === 0) { - return max; - } - return pos + _utf8len[buf[pos]] > max ? pos : max; -}; -var strings = { - string2buf, - buf2string, - utf8border -}; -function ZStream() { - this.input = null; - this.next_in = 0; - this.avail_in = 0; - this.total_in = 0; - this.output = null; - this.next_out = 0; - this.avail_out = 0; - this.total_out = 0; - this.msg = ""; - this.state = null; - this.data_type = 2; - this.adler = 0; -} -var zstream = ZStream; -var BAD$1 = 30; -var TYPE$1 = 12; -var inffast = function inflate_fast(strm, start) { - let _in; - let last; - let _out; - let beg; - let end; - let dmax; - let wsize; - let whave; - let wnext; - let s_window; - let hold; - let bits; - let lcode; - let dcode; - let lmask; - let dmask; - let here; - let op; - let len; - let dist; - let from; - let from_source; - let input, output; - const state = strm.state; - _in = strm.next_in; - input = strm.input; - last = _in + (strm.avail_in - 5); - _out = strm.next_out; - output = strm.output; - beg = _out - (start - strm.avail_out); - end = _out + (strm.avail_out - 257); - dmax = state.dmax; - wsize = state.wsize; - whave = state.whave; - wnext = state.wnext; - s_window = state.window; - hold = state.hold; - bits = state.bits; - lcode = state.lencode; - dcode = state.distcode; - lmask = (1 << state.lenbits) - 1; - dmask = (1 << state.distbits) - 1; - top: - do { - if (bits < 15) { - hold += input[_in++] << bits; - bits += 8; - hold += input[_in++] << bits; - bits += 8; - } - here = lcode[hold & lmask]; - dolen: - for (; ; ) { - op = here >>> 24; - hold >>>= op; - bits -= op; - op = here >>> 16 & 255; - if (op === 0) { - output[_out++] = here & 65535; - } else if (op & 16) { - len = here & 65535; - op &= 15; - if (op) { - if (bits < op) { - hold += input[_in++] << bits; - bits += 8; - } - len += hold & (1 << op) - 1; - hold >>>= op; - bits -= op; - } - if (bits < 15) { - hold += input[_in++] << bits; - bits += 8; - hold += input[_in++] << bits; - bits += 8; - } - here = dcode[hold & dmask]; - dodist: - for (; ; ) { - op = here >>> 24; - hold >>>= op; - bits -= op; - op = here >>> 16 & 255; - if (op & 16) { - dist = here & 65535; - op &= 15; - if (bits < op) { - hold += input[_in++] << bits; - bits += 8; - if (bits < op) { - hold += input[_in++] << bits; - bits += 8; - } - } - dist += hold & (1 << op) - 1; - if (dist > dmax) { - strm.msg = "invalid distance too far back"; - state.mode = BAD$1; - break top; - } - hold >>>= op; - bits -= op; - op = _out - beg; - if (dist > op) { - op = dist - op; - if (op > whave) { - if (state.sane) { - strm.msg = "invalid distance too far back"; - state.mode = BAD$1; - break top; - } - } - from = 0; - from_source = s_window; - if (wnext === 0) { - from += wsize - op; - if (op < len) { - len -= op; - do { - output[_out++] = s_window[from++]; - } while (--op); - from = _out - dist; - from_source = output; - } - } else if (wnext < op) { - from += wsize + wnext - op; - op -= wnext; - if (op < len) { - len -= op; - do { - output[_out++] = s_window[from++]; - } while (--op); - from = 0; - if (wnext < len) { - op = wnext; - len -= op; - do { - output[_out++] = s_window[from++]; - } while (--op); - from = _out - dist; - from_source = output; - } - } - } else { - from += wnext - op; - if (op < len) { - len -= op; - do { - output[_out++] = s_window[from++]; - } while (--op); - from = _out - dist; - from_source = output; - } - } - while (len > 2) { - output[_out++] = from_source[from++]; - output[_out++] = from_source[from++]; - output[_out++] = from_source[from++]; - len -= 3; - } - if (len) { - output[_out++] = from_source[from++]; - if (len > 1) { - output[_out++] = from_source[from++]; - } - } - } else { - from = _out - dist; - do { - output[_out++] = output[from++]; - output[_out++] = output[from++]; - output[_out++] = output[from++]; - len -= 3; - } while (len > 2); - if (len) { - output[_out++] = output[from++]; - if (len > 1) { - output[_out++] = output[from++]; - } - } - } - } else if ((op & 64) === 0) { - here = dcode[(here & 65535) + (hold & (1 << op) - 1)]; - continue dodist; - } else { - strm.msg = "invalid distance code"; - state.mode = BAD$1; - break top; - } - break; - } - } else if ((op & 64) === 0) { - here = lcode[(here & 65535) + (hold & (1 << op) - 1)]; - continue dolen; - } else if (op & 32) { - state.mode = TYPE$1; - break top; - } else { - strm.msg = "invalid literal/length code"; - state.mode = BAD$1; - break top; - } - break; - } - } while (_in < last && _out < end); - len = bits >> 3; - _in -= len; - bits -= len << 3; - hold &= (1 << bits) - 1; - strm.next_in = _in; - strm.next_out = _out; - strm.avail_in = _in < last ? 5 + (last - _in) : 5 - (_in - last); - strm.avail_out = _out < end ? 257 + (end - _out) : 257 - (_out - end); - state.hold = hold; - state.bits = bits; - return; -}; -var MAXBITS = 15; -var ENOUGH_LENS$1 = 852; -var ENOUGH_DISTS$1 = 592; -var CODES$1 = 0; -var LENS$1 = 1; -var DISTS$1 = 2; -var lbase = new Uint16Array([ - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 11, - 13, - 15, - 17, - 19, - 23, - 27, - 31, - 35, - 43, - 51, - 59, - 67, - 83, - 99, - 115, - 131, - 163, - 195, - 227, - 258, - 0, - 0 -]); -var lext = new Uint8Array([ - 16, - 16, - 16, - 16, - 16, - 16, - 16, - 16, - 17, - 17, - 17, - 17, - 18, - 18, - 18, - 18, - 19, - 19, - 19, - 19, - 20, - 20, - 20, - 20, - 21, - 21, - 21, - 21, - 16, - 72, - 78 -]); -var dbase = new Uint16Array([ - 1, - 2, - 3, - 4, - 5, - 7, - 9, - 13, - 17, - 25, - 33, - 49, - 65, - 97, - 129, - 193, - 257, - 385, - 513, - 769, - 1025, - 1537, - 2049, - 3073, - 4097, - 6145, - 8193, - 12289, - 16385, - 24577, - 0, - 0 -]); -var dext = new Uint8Array([ - 16, - 16, - 16, - 16, - 17, - 17, - 18, - 18, - 19, - 19, - 20, - 20, - 21, - 21, - 22, - 22, - 23, - 23, - 24, - 24, - 25, - 25, - 26, - 26, - 27, - 27, - 28, - 28, - 29, - 29, - 64, - 64 -]); -var inflate_table = (type, lens, lens_index, codes, table, table_index, work, opts) => { - const bits = opts.bits; - let len = 0; - let sym = 0; - let min = 0, max = 0; - let root = 0; - let curr = 0; - let drop = 0; - let left = 0; - let used = 0; - let huff = 0; - let incr; - let fill; - let low; - let mask; - let next; - let base = null; - let base_index = 0; - let end; - const count = new Uint16Array(MAXBITS + 1); - const offs = new Uint16Array(MAXBITS + 1); - let extra = null; - let extra_index = 0; - let here_bits, here_op, here_val; - for (len = 0; len <= MAXBITS; len++) { - count[len] = 0; - } - for (sym = 0; sym < codes; sym++) { - count[lens[lens_index + sym]]++; - } - root = bits; - for (max = MAXBITS; max >= 1; max--) { - if (count[max] !== 0) { - break; - } - } - if (root > max) { - root = max; - } - if (max === 0) { - table[table_index++] = 1 << 24 | 64 << 16 | 0; - table[table_index++] = 1 << 24 | 64 << 16 | 0; - opts.bits = 1; - return 0; - } - for (min = 1; min < max; min++) { - if (count[min] !== 0) { - break; - } - } - if (root < min) { - root = min; - } - left = 1; - for (len = 1; len <= MAXBITS; len++) { - left <<= 1; - left -= count[len]; - if (left < 0) { - return -1; - } - } - if (left > 0 && (type === CODES$1 || max !== 1)) { - return -1; - } - offs[1] = 0; - for (len = 1; len < MAXBITS; len++) { - offs[len + 1] = offs[len] + count[len]; - } - for (sym = 0; sym < codes; sym++) { - if (lens[lens_index + sym] !== 0) { - work[offs[lens[lens_index + sym]]++] = sym; - } - } - if (type === CODES$1) { - base = extra = work; - end = 19; - } else if (type === LENS$1) { - base = lbase; - base_index -= 257; - extra = lext; - extra_index -= 257; - end = 256; - } else { - base = dbase; - extra = dext; - end = -1; - } - huff = 0; - sym = 0; - len = min; - next = table_index; - curr = root; - drop = 0; - low = -1; - used = 1 << root; - mask = used - 1; - if (type === LENS$1 && used > ENOUGH_LENS$1 || type === DISTS$1 && used > ENOUGH_DISTS$1) { - return 1; - } - for (; ; ) { - here_bits = len - drop; - if (work[sym] < end) { - here_op = 0; - here_val = work[sym]; - } else if (work[sym] > end) { - here_op = extra[extra_index + work[sym]]; - here_val = base[base_index + work[sym]]; - } else { - here_op = 32 + 64; - here_val = 0; - } - incr = 1 << len - drop; - fill = 1 << curr; - min = fill; - do { - fill -= incr; - table[next + (huff >> drop) + fill] = here_bits << 24 | here_op << 16 | here_val | 0; - } while (fill !== 0); - incr = 1 << len - 1; - while (huff & incr) { - incr >>= 1; - } - if (incr !== 0) { - huff &= incr - 1; - huff += incr; - } else { - huff = 0; - } - sym++; - if (--count[len] === 0) { - if (len === max) { - break; - } - len = lens[lens_index + work[sym]]; - } - if (len > root && (huff & mask) !== low) { - if (drop === 0) { - drop = root; - } - next += min; - curr = len - drop; - left = 1 << curr; - while (curr + drop < max) { - left -= count[curr + drop]; - if (left <= 0) { - break; - } - curr++; - left <<= 1; - } - used += 1 << curr; - if (type === LENS$1 && used > ENOUGH_LENS$1 || type === DISTS$1 && used > ENOUGH_DISTS$1) { - return 1; - } - low = huff & mask; - table[low] = root << 24 | curr << 16 | next - table_index | 0; - } - } - if (huff !== 0) { - table[next + huff] = len - drop << 24 | 64 << 16 | 0; - } - opts.bits = root; - return 0; -}; -var inftrees = inflate_table; -var CODES = 0; -var LENS = 1; -var DISTS = 2; -var { - Z_FINISH: Z_FINISH$1, - Z_BLOCK, - Z_TREES, - Z_OK: Z_OK$1, - Z_STREAM_END: Z_STREAM_END$1, - Z_NEED_DICT: Z_NEED_DICT$1, - Z_STREAM_ERROR: Z_STREAM_ERROR$1, - Z_DATA_ERROR: Z_DATA_ERROR$1, - Z_MEM_ERROR: Z_MEM_ERROR$1, - Z_BUF_ERROR, - Z_DEFLATED -} = constants$2; -var HEAD = 1; -var FLAGS = 2; -var TIME = 3; -var OS = 4; -var EXLEN = 5; -var EXTRA = 6; -var NAME = 7; -var COMMENT = 8; -var HCRC = 9; -var DICTID = 10; -var DICT = 11; -var TYPE = 12; -var TYPEDO = 13; -var STORED = 14; -var COPY_ = 15; -var COPY = 16; -var TABLE = 17; -var LENLENS = 18; -var CODELENS = 19; -var LEN_ = 20; -var LEN = 21; -var LENEXT = 22; -var DIST = 23; -var DISTEXT = 24; -var MATCH = 25; -var LIT = 26; -var CHECK = 27; -var LENGTH = 28; -var DONE = 29; -var BAD = 30; -var MEM = 31; -var SYNC = 32; -var ENOUGH_LENS = 852; -var ENOUGH_DISTS = 592; -var MAX_WBITS = 15; -var DEF_WBITS = MAX_WBITS; -var zswap32 = (q) => { - return (q >>> 24 & 255) + (q >>> 8 & 65280) + ((q & 65280) << 8) + ((q & 255) << 24); -}; -function InflateState() { - this.mode = 0; - this.last = false; - this.wrap = 0; - this.havedict = false; - this.flags = 0; - this.dmax = 0; - this.check = 0; - this.total = 0; - this.head = null; - this.wbits = 0; - this.wsize = 0; - this.whave = 0; - this.wnext = 0; - this.window = null; - this.hold = 0; - this.bits = 0; - this.length = 0; - this.offset = 0; - this.extra = 0; - this.lencode = null; - this.distcode = null; - this.lenbits = 0; - this.distbits = 0; - this.ncode = 0; - this.nlen = 0; - this.ndist = 0; - this.have = 0; - this.next = null; - this.lens = new Uint16Array(320); - this.work = new Uint16Array(288); - this.lendyn = null; - this.distdyn = null; - this.sane = 0; - this.back = 0; - this.was = 0; -} -var inflateResetKeep = (strm) => { - if (!strm || !strm.state) { - return Z_STREAM_ERROR$1; - } - const state = strm.state; - strm.total_in = strm.total_out = state.total = 0; - strm.msg = ""; - if (state.wrap) { - strm.adler = state.wrap & 1; - } - state.mode = HEAD; - state.last = 0; - state.havedict = 0; - state.dmax = 32768; - state.head = null; - state.hold = 0; - state.bits = 0; - state.lencode = state.lendyn = new Int32Array(ENOUGH_LENS); - state.distcode = state.distdyn = new Int32Array(ENOUGH_DISTS); - state.sane = 1; - state.back = -1; - return Z_OK$1; -}; -var inflateReset = (strm) => { - if (!strm || !strm.state) { - return Z_STREAM_ERROR$1; - } - const state = strm.state; - state.wsize = 0; - state.whave = 0; - state.wnext = 0; - return inflateResetKeep(strm); -}; -var inflateReset2 = (strm, windowBits) => { - let wrap; - if (!strm || !strm.state) { - return Z_STREAM_ERROR$1; - } - const state = strm.state; - if (windowBits < 0) { - wrap = 0; - windowBits = -windowBits; - } else { - wrap = (windowBits >> 4) + 1; - if (windowBits < 48) { - windowBits &= 15; - } - } - if (windowBits && (windowBits < 8 || windowBits > 15)) { - return Z_STREAM_ERROR$1; - } - if (state.window !== null && state.wbits !== windowBits) { - state.window = null; - } - state.wrap = wrap; - state.wbits = windowBits; - return inflateReset(strm); -}; -var inflateInit2 = (strm, windowBits) => { - if (!strm) { - return Z_STREAM_ERROR$1; - } - const state = new InflateState(); - strm.state = state; - state.window = null; - const ret = inflateReset2(strm, windowBits); - if (ret !== Z_OK$1) { - strm.state = null; - } - return ret; -}; -var inflateInit = (strm) => { - return inflateInit2(strm, DEF_WBITS); -}; -var virgin = true; -var lenfix; -var distfix; -var fixedtables = (state) => { - if (virgin) { - lenfix = new Int32Array(512); - distfix = new Int32Array(32); - let sym = 0; - while (sym < 144) { - state.lens[sym++] = 8; - } - while (sym < 256) { - state.lens[sym++] = 9; - } - while (sym < 280) { - state.lens[sym++] = 7; - } - while (sym < 288) { - state.lens[sym++] = 8; - } - inftrees(LENS, state.lens, 0, 288, lenfix, 0, state.work, { bits: 9 }); - sym = 0; - while (sym < 32) { - state.lens[sym++] = 5; - } - inftrees(DISTS, state.lens, 0, 32, distfix, 0, state.work, { bits: 5 }); - virgin = false; - } - state.lencode = lenfix; - state.lenbits = 9; - state.distcode = distfix; - state.distbits = 5; -}; -var updatewindow = (strm, src, end, copy) => { - let dist; - const state = strm.state; - if (state.window === null) { - state.wsize = 1 << state.wbits; - state.wnext = 0; - state.whave = 0; - state.window = new Uint8Array(state.wsize); - } - if (copy >= state.wsize) { - state.window.set(src.subarray(end - state.wsize, end), 0); - state.wnext = 0; - state.whave = state.wsize; - } else { - dist = state.wsize - state.wnext; - if (dist > copy) { - dist = copy; - } - state.window.set(src.subarray(end - copy, end - copy + dist), state.wnext); - copy -= dist; - if (copy) { - state.window.set(src.subarray(end - copy, end), 0); - state.wnext = copy; - state.whave = state.wsize; - } else { - state.wnext += dist; - if (state.wnext === state.wsize) { - state.wnext = 0; - } - if (state.whave < state.wsize) { - state.whave += dist; - } - } - } - return 0; -}; -var inflate$2 = (strm, flush) => { - let state; - let input, output; - let next; - let put; - let have, left; - let hold; - let bits; - let _in, _out; - let copy; - let from; - let from_source; - let here = 0; - let here_bits, here_op, here_val; - let last_bits, last_op, last_val; - let len; - let ret; - const hbuf = new Uint8Array(4); - let opts; - let n; - const order = new Uint8Array([16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15]); - if (!strm || !strm.state || !strm.output || !strm.input && strm.avail_in !== 0) { - return Z_STREAM_ERROR$1; - } - state = strm.state; - if (state.mode === TYPE) { - state.mode = TYPEDO; - } - put = strm.next_out; - output = strm.output; - left = strm.avail_out; - next = strm.next_in; - input = strm.input; - have = strm.avail_in; - hold = state.hold; - bits = state.bits; - _in = have; - _out = left; - ret = Z_OK$1; - inf_leave: - for (; ; ) { - switch (state.mode) { - case HEAD: - if (state.wrap === 0) { - state.mode = TYPEDO; - break; - } - while (bits < 16) { - if (have === 0) { - break inf_leave; - } - have--; - hold += input[next++] << bits; - bits += 8; - } - if (state.wrap & 2 && hold === 35615) { - state.check = 0; - hbuf[0] = hold & 255; - hbuf[1] = hold >>> 8 & 255; - state.check = crc32_1(state.check, hbuf, 2, 0); - hold = 0; - bits = 0; - state.mode = FLAGS; - break; - } - state.flags = 0; - if (state.head) { - state.head.done = false; - } - if (!(state.wrap & 1) || (((hold & 255) << 8) + (hold >> 8)) % 31) { - strm.msg = "incorrect header check"; - state.mode = BAD; - break; - } - if ((hold & 15) !== Z_DEFLATED) { - strm.msg = "unknown compression method"; - state.mode = BAD; - break; - } - hold >>>= 4; - bits -= 4; - len = (hold & 15) + 8; - if (state.wbits === 0) { - state.wbits = len; - } else if (len > state.wbits) { - strm.msg = "invalid window size"; - state.mode = BAD; - break; - } - state.dmax = 1 << state.wbits; - strm.adler = state.check = 1; - state.mode = hold & 512 ? DICTID : TYPE; - hold = 0; - bits = 0; - break; - case FLAGS: - while (bits < 16) { - if (have === 0) { - break inf_leave; - } - have--; - hold += input[next++] << bits; - bits += 8; - } - state.flags = hold; - if ((state.flags & 255) !== Z_DEFLATED) { - strm.msg = "unknown compression method"; - state.mode = BAD; - break; - } - if (state.flags & 57344) { - strm.msg = "unknown header flags set"; - state.mode = BAD; - break; - } - if (state.head) { - state.head.text = hold >> 8 & 1; - } - if (state.flags & 512) { - hbuf[0] = hold & 255; - hbuf[1] = hold >>> 8 & 255; - state.check = crc32_1(state.check, hbuf, 2, 0); - } - hold = 0; - bits = 0; - state.mode = TIME; - case TIME: - while (bits < 32) { - if (have === 0) { - break inf_leave; - } - have--; - hold += input[next++] << bits; - bits += 8; - } - if (state.head) { - state.head.time = hold; - } - if (state.flags & 512) { - hbuf[0] = hold & 255; - hbuf[1] = hold >>> 8 & 255; - hbuf[2] = hold >>> 16 & 255; - hbuf[3] = hold >>> 24 & 255; - state.check = crc32_1(state.check, hbuf, 4, 0); - } - hold = 0; - bits = 0; - state.mode = OS; - case OS: - while (bits < 16) { - if (have === 0) { - break inf_leave; - } - have--; - hold += input[next++] << bits; - bits += 8; - } - if (state.head) { - state.head.xflags = hold & 255; - state.head.os = hold >> 8; - } - if (state.flags & 512) { - hbuf[0] = hold & 255; - hbuf[1] = hold >>> 8 & 255; - state.check = crc32_1(state.check, hbuf, 2, 0); - } - hold = 0; - bits = 0; - state.mode = EXLEN; - case EXLEN: - if (state.flags & 1024) { - while (bits < 16) { - if (have === 0) { - break inf_leave; - } - have--; - hold += input[next++] << bits; - bits += 8; - } - state.length = hold; - if (state.head) { - state.head.extra_len = hold; - } - if (state.flags & 512) { - hbuf[0] = hold & 255; - hbuf[1] = hold >>> 8 & 255; - state.check = crc32_1(state.check, hbuf, 2, 0); - } - hold = 0; - bits = 0; - } else if (state.head) { - state.head.extra = null; - } - state.mode = EXTRA; - case EXTRA: - if (state.flags & 1024) { - copy = state.length; - if (copy > have) { - copy = have; - } - if (copy) { - if (state.head) { - len = state.head.extra_len - state.length; - if (!state.head.extra) { - state.head.extra = new Uint8Array(state.head.extra_len); - } - state.head.extra.set(input.subarray(next, next + copy), len); - } - if (state.flags & 512) { - state.check = crc32_1(state.check, input, copy, next); - } - have -= copy; - next += copy; - state.length -= copy; - } - if (state.length) { - break inf_leave; - } - } - state.length = 0; - state.mode = NAME; - case NAME: - if (state.flags & 2048) { - if (have === 0) { - break inf_leave; - } - copy = 0; - do { - len = input[next + copy++]; - if (state.head && len && state.length < 65536) { - state.head.name += String.fromCharCode(len); - } - } while (len && copy < have); - if (state.flags & 512) { - state.check = crc32_1(state.check, input, copy, next); - } - have -= copy; - next += copy; - if (len) { - break inf_leave; - } - } else if (state.head) { - state.head.name = null; - } - state.length = 0; - state.mode = COMMENT; - case COMMENT: - if (state.flags & 4096) { - if (have === 0) { - break inf_leave; - } - copy = 0; - do { - len = input[next + copy++]; - if (state.head && len && state.length < 65536) { - state.head.comment += String.fromCharCode(len); - } - } while (len && copy < have); - if (state.flags & 512) { - state.check = crc32_1(state.check, input, copy, next); - } - have -= copy; - next += copy; - if (len) { - break inf_leave; - } - } else if (state.head) { - state.head.comment = null; - } - state.mode = HCRC; - case HCRC: - if (state.flags & 512) { - while (bits < 16) { - if (have === 0) { - break inf_leave; - } - have--; - hold += input[next++] << bits; - bits += 8; - } - if (hold !== (state.check & 65535)) { - strm.msg = "header crc mismatch"; - state.mode = BAD; - break; - } - hold = 0; - bits = 0; - } - if (state.head) { - state.head.hcrc = state.flags >> 9 & 1; - state.head.done = true; - } - strm.adler = state.check = 0; - state.mode = TYPE; - break; - case DICTID: - while (bits < 32) { - if (have === 0) { - break inf_leave; - } - have--; - hold += input[next++] << bits; - bits += 8; - } - strm.adler = state.check = zswap32(hold); - hold = 0; - bits = 0; - state.mode = DICT; - case DICT: - if (state.havedict === 0) { - strm.next_out = put; - strm.avail_out = left; - strm.next_in = next; - strm.avail_in = have; - state.hold = hold; - state.bits = bits; - return Z_NEED_DICT$1; - } - strm.adler = state.check = 1; - state.mode = TYPE; - case TYPE: - if (flush === Z_BLOCK || flush === Z_TREES) { - break inf_leave; - } - case TYPEDO: - if (state.last) { - hold >>>= bits & 7; - bits -= bits & 7; - state.mode = CHECK; - break; - } - while (bits < 3) { - if (have === 0) { - break inf_leave; - } - have--; - hold += input[next++] << bits; - bits += 8; - } - state.last = hold & 1; - hold >>>= 1; - bits -= 1; - switch (hold & 3) { - case 0: - state.mode = STORED; - break; - case 1: - fixedtables(state); - state.mode = LEN_; - if (flush === Z_TREES) { - hold >>>= 2; - bits -= 2; - break inf_leave; - } - break; - case 2: - state.mode = TABLE; - break; - case 3: - strm.msg = "invalid block type"; - state.mode = BAD; - } - hold >>>= 2; - bits -= 2; - break; - case STORED: - hold >>>= bits & 7; - bits -= bits & 7; - while (bits < 32) { - if (have === 0) { - break inf_leave; - } - have--; - hold += input[next++] << bits; - bits += 8; - } - if ((hold & 65535) !== (hold >>> 16 ^ 65535)) { - strm.msg = "invalid stored block lengths"; - state.mode = BAD; - break; - } - state.length = hold & 65535; - hold = 0; - bits = 0; - state.mode = COPY_; - if (flush === Z_TREES) { - break inf_leave; - } - case COPY_: - state.mode = COPY; - case COPY: - copy = state.length; - if (copy) { - if (copy > have) { - copy = have; - } - if (copy > left) { - copy = left; - } - if (copy === 0) { - break inf_leave; - } - output.set(input.subarray(next, next + copy), put); - have -= copy; - next += copy; - left -= copy; - put += copy; - state.length -= copy; - break; - } - state.mode = TYPE; - break; - case TABLE: - while (bits < 14) { - if (have === 0) { - break inf_leave; - } - have--; - hold += input[next++] << bits; - bits += 8; - } - state.nlen = (hold & 31) + 257; - hold >>>= 5; - bits -= 5; - state.ndist = (hold & 31) + 1; - hold >>>= 5; - bits -= 5; - state.ncode = (hold & 15) + 4; - hold >>>= 4; - bits -= 4; - if (state.nlen > 286 || state.ndist > 30) { - strm.msg = "too many length or distance symbols"; - state.mode = BAD; - break; - } - state.have = 0; - state.mode = LENLENS; - case LENLENS: - while (state.have < state.ncode) { - while (bits < 3) { - if (have === 0) { - break inf_leave; - } - have--; - hold += input[next++] << bits; - bits += 8; - } - state.lens[order[state.have++]] = hold & 7; - hold >>>= 3; - bits -= 3; - } - while (state.have < 19) { - state.lens[order[state.have++]] = 0; - } - state.lencode = state.lendyn; - state.lenbits = 7; - opts = { bits: state.lenbits }; - ret = inftrees(CODES, state.lens, 0, 19, state.lencode, 0, state.work, opts); - state.lenbits = opts.bits; - if (ret) { - strm.msg = "invalid code lengths set"; - state.mode = BAD; - break; - } - state.have = 0; - state.mode = CODELENS; - case CODELENS: - while (state.have < state.nlen + state.ndist) { - for (; ; ) { - here = state.lencode[hold & (1 << state.lenbits) - 1]; - here_bits = here >>> 24; - here_op = here >>> 16 & 255; - here_val = here & 65535; - if (here_bits <= bits) { - break; - } - if (have === 0) { - break inf_leave; - } - have--; - hold += input[next++] << bits; - bits += 8; - } - if (here_val < 16) { - hold >>>= here_bits; - bits -= here_bits; - state.lens[state.have++] = here_val; - } else { - if (here_val === 16) { - n = here_bits + 2; - while (bits < n) { - if (have === 0) { - break inf_leave; - } - have--; - hold += input[next++] << bits; - bits += 8; - } - hold >>>= here_bits; - bits -= here_bits; - if (state.have === 0) { - strm.msg = "invalid bit length repeat"; - state.mode = BAD; - break; - } - len = state.lens[state.have - 1]; - copy = 3 + (hold & 3); - hold >>>= 2; - bits -= 2; - } else if (here_val === 17) { - n = here_bits + 3; - while (bits < n) { - if (have === 0) { - break inf_leave; - } - have--; - hold += input[next++] << bits; - bits += 8; - } - hold >>>= here_bits; - bits -= here_bits; - len = 0; - copy = 3 + (hold & 7); - hold >>>= 3; - bits -= 3; - } else { - n = here_bits + 7; - while (bits < n) { - if (have === 0) { - break inf_leave; - } - have--; - hold += input[next++] << bits; - bits += 8; - } - hold >>>= here_bits; - bits -= here_bits; - len = 0; - copy = 11 + (hold & 127); - hold >>>= 7; - bits -= 7; - } - if (state.have + copy > state.nlen + state.ndist) { - strm.msg = "invalid bit length repeat"; - state.mode = BAD; - break; - } - while (copy--) { - state.lens[state.have++] = len; - } - } - } - if (state.mode === BAD) { - break; - } - if (state.lens[256] === 0) { - strm.msg = "invalid code -- missing end-of-block"; - state.mode = BAD; - break; - } - state.lenbits = 9; - opts = { bits: state.lenbits }; - ret = inftrees(LENS, state.lens, 0, state.nlen, state.lencode, 0, state.work, opts); - state.lenbits = opts.bits; - if (ret) { - strm.msg = "invalid literal/lengths set"; - state.mode = BAD; - break; - } - state.distbits = 6; - state.distcode = state.distdyn; - opts = { bits: state.distbits }; - ret = inftrees(DISTS, state.lens, state.nlen, state.ndist, state.distcode, 0, state.work, opts); - state.distbits = opts.bits; - if (ret) { - strm.msg = "invalid distances set"; - state.mode = BAD; - break; - } - state.mode = LEN_; - if (flush === Z_TREES) { - break inf_leave; - } - case LEN_: - state.mode = LEN; - case LEN: - if (have >= 6 && left >= 258) { - strm.next_out = put; - strm.avail_out = left; - strm.next_in = next; - strm.avail_in = have; - state.hold = hold; - state.bits = bits; - inffast(strm, _out); - put = strm.next_out; - output = strm.output; - left = strm.avail_out; - next = strm.next_in; - input = strm.input; - have = strm.avail_in; - hold = state.hold; - bits = state.bits; - if (state.mode === TYPE) { - state.back = -1; - } - break; - } - state.back = 0; - for (; ; ) { - here = state.lencode[hold & (1 << state.lenbits) - 1]; - here_bits = here >>> 24; - here_op = here >>> 16 & 255; - here_val = here & 65535; - if (here_bits <= bits) { - break; - } - if (have === 0) { - break inf_leave; - } - have--; - hold += input[next++] << bits; - bits += 8; - } - if (here_op && (here_op & 240) === 0) { - last_bits = here_bits; - last_op = here_op; - last_val = here_val; - for (; ; ) { - here = state.lencode[last_val + ((hold & (1 << last_bits + last_op) - 1) >> last_bits)]; - here_bits = here >>> 24; - here_op = here >>> 16 & 255; - here_val = here & 65535; - if (last_bits + here_bits <= bits) { - break; - } - if (have === 0) { - break inf_leave; - } - have--; - hold += input[next++] << bits; - bits += 8; - } - hold >>>= last_bits; - bits -= last_bits; - state.back += last_bits; - } - hold >>>= here_bits; - bits -= here_bits; - state.back += here_bits; - state.length = here_val; - if (here_op === 0) { - state.mode = LIT; - break; - } - if (here_op & 32) { - state.back = -1; - state.mode = TYPE; - break; - } - if (here_op & 64) { - strm.msg = "invalid literal/length code"; - state.mode = BAD; - break; - } - state.extra = here_op & 15; - state.mode = LENEXT; - case LENEXT: - if (state.extra) { - n = state.extra; - while (bits < n) { - if (have === 0) { - break inf_leave; - } - have--; - hold += input[next++] << bits; - bits += 8; - } - state.length += hold & (1 << state.extra) - 1; - hold >>>= state.extra; - bits -= state.extra; - state.back += state.extra; - } - state.was = state.length; - state.mode = DIST; - case DIST: - for (; ; ) { - here = state.distcode[hold & (1 << state.distbits) - 1]; - here_bits = here >>> 24; - here_op = here >>> 16 & 255; - here_val = here & 65535; - if (here_bits <= bits) { - break; - } - if (have === 0) { - break inf_leave; - } - have--; - hold += input[next++] << bits; - bits += 8; - } - if ((here_op & 240) === 0) { - last_bits = here_bits; - last_op = here_op; - last_val = here_val; - for (; ; ) { - here = state.distcode[last_val + ((hold & (1 << last_bits + last_op) - 1) >> last_bits)]; - here_bits = here >>> 24; - here_op = here >>> 16 & 255; - here_val = here & 65535; - if (last_bits + here_bits <= bits) { - break; - } - if (have === 0) { - break inf_leave; - } - have--; - hold += input[next++] << bits; - bits += 8; - } - hold >>>= last_bits; - bits -= last_bits; - state.back += last_bits; - } - hold >>>= here_bits; - bits -= here_bits; - state.back += here_bits; - if (here_op & 64) { - strm.msg = "invalid distance code"; - state.mode = BAD; - break; - } - state.offset = here_val; - state.extra = here_op & 15; - state.mode = DISTEXT; - case DISTEXT: - if (state.extra) { - n = state.extra; - while (bits < n) { - if (have === 0) { - break inf_leave; - } - have--; - hold += input[next++] << bits; - bits += 8; - } - state.offset += hold & (1 << state.extra) - 1; - hold >>>= state.extra; - bits -= state.extra; - state.back += state.extra; - } - if (state.offset > state.dmax) { - strm.msg = "invalid distance too far back"; - state.mode = BAD; - break; - } - state.mode = MATCH; - case MATCH: - if (left === 0) { - break inf_leave; - } - copy = _out - left; - if (state.offset > copy) { - copy = state.offset - copy; - if (copy > state.whave) { - if (state.sane) { - strm.msg = "invalid distance too far back"; - state.mode = BAD; - break; - } - } - if (copy > state.wnext) { - copy -= state.wnext; - from = state.wsize - copy; - } else { - from = state.wnext - copy; - } - if (copy > state.length) { - copy = state.length; - } - from_source = state.window; - } else { - from_source = output; - from = put - state.offset; - copy = state.length; - } - if (copy > left) { - copy = left; - } - left -= copy; - state.length -= copy; - do { - output[put++] = from_source[from++]; - } while (--copy); - if (state.length === 0) { - state.mode = LEN; - } - break; - case LIT: - if (left === 0) { - break inf_leave; - } - output[put++] = state.length; - left--; - state.mode = LEN; - break; - case CHECK: - if (state.wrap) { - while (bits < 32) { - if (have === 0) { - break inf_leave; - } - have--; - hold |= input[next++] << bits; - bits += 8; - } - _out -= left; - strm.total_out += _out; - state.total += _out; - if (_out) { - strm.adler = state.check = state.flags ? crc32_1(state.check, output, _out, put - _out) : adler32_1(state.check, output, _out, put - _out); - } - _out = left; - if ((state.flags ? hold : zswap32(hold)) !== state.check) { - strm.msg = "incorrect data check"; - state.mode = BAD; - break; - } - hold = 0; - bits = 0; - } - state.mode = LENGTH; - case LENGTH: - if (state.wrap && state.flags) { - while (bits < 32) { - if (have === 0) { - break inf_leave; - } - have--; - hold += input[next++] << bits; - bits += 8; - } - if (hold !== (state.total & 4294967295)) { - strm.msg = "incorrect length check"; - state.mode = BAD; - break; - } - hold = 0; - bits = 0; - } - state.mode = DONE; - case DONE: - ret = Z_STREAM_END$1; - break inf_leave; - case BAD: - ret = Z_DATA_ERROR$1; - break inf_leave; - case MEM: - return Z_MEM_ERROR$1; - case SYNC: - default: - return Z_STREAM_ERROR$1; - } - } - strm.next_out = put; - strm.avail_out = left; - strm.next_in = next; - strm.avail_in = have; - state.hold = hold; - state.bits = bits; - if (state.wsize || _out !== strm.avail_out && state.mode < BAD && (state.mode < CHECK || flush !== Z_FINISH$1)) { - if (updatewindow(strm, strm.output, strm.next_out, _out - strm.avail_out)) - ; - } - _in -= strm.avail_in; - _out -= strm.avail_out; - strm.total_in += _in; - strm.total_out += _out; - state.total += _out; - if (state.wrap && _out) { - strm.adler = state.check = state.flags ? crc32_1(state.check, output, _out, strm.next_out - _out) : adler32_1(state.check, output, _out, strm.next_out - _out); - } - strm.data_type = state.bits + (state.last ? 64 : 0) + (state.mode === TYPE ? 128 : 0) + (state.mode === LEN_ || state.mode === COPY_ ? 256 : 0); - if ((_in === 0 && _out === 0 || flush === Z_FINISH$1) && ret === Z_OK$1) { - ret = Z_BUF_ERROR; - } - return ret; -}; -var inflateEnd = (strm) => { - if (!strm || !strm.state) { - return Z_STREAM_ERROR$1; - } - let state = strm.state; - if (state.window) { - state.window = null; - } - strm.state = null; - return Z_OK$1; -}; -var inflateGetHeader = (strm, head) => { - if (!strm || !strm.state) { - return Z_STREAM_ERROR$1; - } - const state = strm.state; - if ((state.wrap & 2) === 0) { - return Z_STREAM_ERROR$1; - } - state.head = head; - head.done = false; - return Z_OK$1; -}; -var inflateSetDictionary = (strm, dictionary) => { - const dictLength = dictionary.length; - let state; - let dictid; - let ret; - if (!strm || !strm.state) { - return Z_STREAM_ERROR$1; - } - state = strm.state; - if (state.wrap !== 0 && state.mode !== DICT) { - return Z_STREAM_ERROR$1; - } - if (state.mode === DICT) { - dictid = 1; - dictid = adler32_1(dictid, dictionary, dictLength, 0); - if (dictid !== state.check) { - return Z_DATA_ERROR$1; - } - } - ret = updatewindow(strm, dictionary, dictLength, dictLength); - if (ret) { - state.mode = MEM; - return Z_MEM_ERROR$1; - } - state.havedict = 1; - return Z_OK$1; -}; -var inflateReset_1 = inflateReset; -var inflateReset2_1 = inflateReset2; -var inflateResetKeep_1 = inflateResetKeep; -var inflateInit_1 = inflateInit; -var inflateInit2_1 = inflateInit2; -var inflate_2$1 = inflate$2; -var inflateEnd_1 = inflateEnd; -var inflateGetHeader_1 = inflateGetHeader; -var inflateSetDictionary_1 = inflateSetDictionary; -var inflateInfo = "pako inflate (from Nodeca project)"; -var inflate_1$2 = { - inflateReset: inflateReset_1, - inflateReset2: inflateReset2_1, - inflateResetKeep: inflateResetKeep_1, - inflateInit: inflateInit_1, - inflateInit2: inflateInit2_1, - inflate: inflate_2$1, - inflateEnd: inflateEnd_1, - inflateGetHeader: inflateGetHeader_1, - inflateSetDictionary: inflateSetDictionary_1, - inflateInfo -}; -function GZheader() { - this.text = 0; - this.time = 0; - this.xflags = 0; - this.os = 0; - this.extra = null; - this.extra_len = 0; - this.name = ""; - this.comment = ""; - this.hcrc = 0; - this.done = false; -} -var gzheader = GZheader; -var toString = Object.prototype.toString; -var { - Z_NO_FLUSH, - Z_FINISH, - Z_OK, - Z_STREAM_END, - Z_NEED_DICT, - Z_STREAM_ERROR, - Z_DATA_ERROR, - Z_MEM_ERROR -} = constants$2; -function Inflate$1(options) { - this.options = common.assign({ - chunkSize: 1024 * 64, - windowBits: 15, - to: "" - }, options || {}); - const opt = this.options; - if (opt.raw && opt.windowBits >= 0 && opt.windowBits < 16) { - opt.windowBits = -opt.windowBits; - if (opt.windowBits === 0) { - opt.windowBits = -15; - } - } - if (opt.windowBits >= 0 && opt.windowBits < 16 && !(options && options.windowBits)) { - opt.windowBits += 32; - } - if (opt.windowBits > 15 && opt.windowBits < 48) { - if ((opt.windowBits & 15) === 0) { - opt.windowBits |= 15; - } - } - this.err = 0; - this.msg = ""; - this.ended = false; - this.chunks = []; - this.strm = new zstream(); - this.strm.avail_out = 0; - let status = inflate_1$2.inflateInit2(this.strm, opt.windowBits); - if (status !== Z_OK) { - throw new Error(messages[status]); - } - this.header = new gzheader(); - inflate_1$2.inflateGetHeader(this.strm, this.header); - if (opt.dictionary) { - if (typeof opt.dictionary === "string") { - opt.dictionary = strings.string2buf(opt.dictionary); - } else if (toString.call(opt.dictionary) === "[object ArrayBuffer]") { - opt.dictionary = new Uint8Array(opt.dictionary); - } - if (opt.raw) { - status = inflate_1$2.inflateSetDictionary(this.strm, opt.dictionary); - if (status !== Z_OK) { - throw new Error(messages[status]); - } - } - } -} -Inflate$1.prototype.push = function(data, flush_mode) { - const strm = this.strm; - const chunkSize = this.options.chunkSize; - const dictionary = this.options.dictionary; - let status, _flush_mode, last_avail_out; - if (this.ended) - return false; - if (flush_mode === ~~flush_mode) - _flush_mode = flush_mode; - else - _flush_mode = flush_mode === true ? Z_FINISH : Z_NO_FLUSH; - if (toString.call(data) === "[object ArrayBuffer]") { - strm.input = new Uint8Array(data); - } else { - strm.input = data; - } - strm.next_in = 0; - strm.avail_in = strm.input.length; - for (; ; ) { - if (strm.avail_out === 0) { - strm.output = new Uint8Array(chunkSize); - strm.next_out = 0; - strm.avail_out = chunkSize; - } - status = inflate_1$2.inflate(strm, _flush_mode); - if (status === Z_NEED_DICT && dictionary) { - status = inflate_1$2.inflateSetDictionary(strm, dictionary); - if (status === Z_OK) { - status = inflate_1$2.inflate(strm, _flush_mode); - } else if (status === Z_DATA_ERROR) { - status = Z_NEED_DICT; - } - } - while (strm.avail_in > 0 && status === Z_STREAM_END && strm.state.wrap > 0 && data[strm.next_in] !== 0) { - inflate_1$2.inflateReset(strm); - status = inflate_1$2.inflate(strm, _flush_mode); - } - switch (status) { - case Z_STREAM_ERROR: - case Z_DATA_ERROR: - case Z_NEED_DICT: - case Z_MEM_ERROR: - this.onEnd(status); - this.ended = true; - return false; - } - last_avail_out = strm.avail_out; - if (strm.next_out) { - if (strm.avail_out === 0 || status === Z_STREAM_END) { - if (this.options.to === "string") { - let next_out_utf8 = strings.utf8border(strm.output, strm.next_out); - let tail = strm.next_out - next_out_utf8; - let utf8str = strings.buf2string(strm.output, next_out_utf8); - strm.next_out = tail; - strm.avail_out = chunkSize - tail; - if (tail) - strm.output.set(strm.output.subarray(next_out_utf8, next_out_utf8 + tail), 0); - this.onData(utf8str); - } else { - this.onData(strm.output.length === strm.next_out ? strm.output : strm.output.subarray(0, strm.next_out)); - } - } - } - if (status === Z_OK && last_avail_out === 0) - continue; - if (status === Z_STREAM_END) { - status = inflate_1$2.inflateEnd(this.strm); - this.onEnd(status); - this.ended = true; - return true; - } - if (strm.avail_in === 0) - break; - } - return true; -}; -Inflate$1.prototype.onData = function(chunk) { - this.chunks.push(chunk); -}; -Inflate$1.prototype.onEnd = function(status) { - if (status === Z_OK) { - if (this.options.to === "string") { - this.result = this.chunks.join(""); - } else { - this.result = common.flattenChunks(this.chunks); - } - } - this.chunks = []; - this.err = status; - this.msg = this.strm.msg; -}; -function inflate$1(input, options) { - const inflator = new Inflate$1(options); - inflator.push(input); - if (inflator.err) - throw inflator.msg || messages[inflator.err]; - return inflator.result; -} -function inflateRaw$1(input, options) { - options = options || {}; - options.raw = true; - return inflate$1(input, options); -} -var Inflate_1$1 = Inflate$1; -var inflate_2 = inflate$1; -var inflateRaw_1$1 = inflateRaw$1; -var ungzip$1 = inflate$1; -var constants = constants$2; -var inflate_1$1 = { - Inflate: Inflate_1$1, - inflate: inflate_2, - inflateRaw: inflateRaw_1$1, - ungzip: ungzip$1, - constants -}; -var { Inflate, inflate, inflateRaw, ungzip } = inflate_1$1; -var inflate_1 = inflate; -var ungzip_1 = ungzip; - -// esm/filters.js -var zlib_decompress = function(buf, itemsize) { - let input_array = new Uint8Array(buf); - return inflate_1(input_array).buffer; -}; -var unshuffle = function(buf, itemsize) { - let buffer_size = buf.byteLength; - let unshuffled_view = new Uint8Array(buffer_size); - let step = Math.floor(buffer_size / itemsize); - let shuffled_view = new DataView(buf); - for (var j = 0; j < itemsize; j++) { - for (var i = 0; i < step; i++) { - unshuffled_view[j + i * itemsize] = shuffled_view.getUint8(j * step + i); - } - } - return unshuffled_view.buffer; -}; -var fletch32 = function(buf, itemsize) { - _verify_fletcher32(buf); - return buf.slice(0, -4); -}; -function _verify_fletcher32(chunk_buffer) { - var odd_chunk_buffer = chunk_buffer.byteLength % 2 != 0; - var data_length = chunk_buffer.byteLength - 4; - var view = new DataView(chunk_buffer); - var sum1 = 0; - var sum2 = 0; - for (var offset = 0; offset < data_length - 1; offset += 2) { - let datum = view.getUint16(offset, true); - sum1 = (sum1 + datum) % 65535; - sum2 = (sum2 + sum1) % 65535; - } - if (odd_chunk_buffer) { - let datum = view.getUint8(data_length - 1); - sum1 = (sum1 + datum) % 65535; - sum2 = (sum2 + sum1) % 65535; - } - var [ref_sum1, ref_sum2] = struct.unpack_from(">HH", chunk_buffer, data_length); - ref_sum1 = ref_sum1 % 65535; - ref_sum2 = ref_sum2 % 65535; - if (sum1 != ref_sum1 || sum2 != ref_sum2) { - throw 'ValueError("fletcher32 checksum invalid")'; - } - return true; -} -var GZIP_DEFLATE_FILTER = 1; -var SHUFFLE_FILTER = 2; -var FLETCH32_FILTER = 3; -var Filters = /* @__PURE__ */ new Map([ - [GZIP_DEFLATE_FILTER, zlib_decompress], - [SHUFFLE_FILTER, unshuffle], - [FLETCH32_FILTER, fletch32] -]); - -// esm/btree.js -var AbstractBTree = class { - constructor(fh, offset) { - this.fh = fh; - this.offset = offset; - this.depth = null; - } - async init() { - this.all_nodes = /* @__PURE__ */ new Map(); - await this._read_root_node(); - await this._read_children(); - } - async _read_children() { - let node_level = this.depth; - while (node_level > 0) { - for (var parent_node of this.all_nodes.get(node_level)) { - for (var child_addr of parent_node.get("addresses")) { - this._add_node(await this._read_node(child_addr, node_level - 1)); - } - } - node_level--; - } - } - async _read_root_node() { - let root_node = await this._read_node(this.offset, null); - this._add_node(root_node); - this.depth = root_node.get("node_level"); - } - _add_node(node) { - let node_level = node.get("node_level"); - if (this.all_nodes.has(node_level)) { - this.all_nodes.get(node_level).push(node); - } else { - this.all_nodes.set(node_level, [node]); - } - } - async _read_node(offset, node_level) { - let node = await this._read_node_header(offset, node_level); - node.set("keys", []); - node.set("addresses", []); - return node; - } - async _read_node_header(offset) { - throw "NotImplementedError: must define _read_node_header in implementation class"; - } -}; -var BTreeV1 = class extends AbstractBTree { - constructor() { - super(...arguments); - __publicField(this, "B_LINK_NODE", /* @__PURE__ */ new Map([ - ["signature", "4s"], - ["node_type", "B"], - ["node_level", "B"], - ["entries_used", "H"], - ["left_sibling", "Q"], - ["right_sibling", "Q"] - ])); - } - async _read_node_header(offset, node_level) { - let node = await _unpack_struct_from_async(this.B_LINK_NODE, this.fh, offset); - if (node_level != null) { - if (node.get("node_level") != node_level) { - throw "node level does not match"; - } - } - return node; - } -}; -var BTreeV1Groups = class extends BTreeV1 { - constructor(fh, offset) { - super(fh, offset); - __publicField(this, "NODE_TYPE", 0); - this.ready = this.init(); - } - async _read_node(offset, node_level) { - let node = await this._read_node_header(offset, node_level); - offset += _structure_size(this.B_LINK_NODE); - let keys = []; - let addresses = []; - let entries_used = node.get("entries_used"); - for (var i = 0; i < entries_used; i++) { - let key = (await struct.unpack_from_async("= 0; d--) { - if (cpos[d] >= chunk_shape[d]) { - cpos[d] = 0; - apos[d] = chunk_offset[d]; - if (d > 0) { - cpos[d - 1] += 1; - apos[d - 1] += 1; - } - } else { - break; - } - } - let inbounds = apos.slice(0, -1).every(function(p, d2) { - return p < data_shape[d2]; - }); - if (inbounds) { - let cb_offset = ci * item_size; - let datum = cview[item_getter](cb_offset, !item_big_endian, item_size); - let ai = apos.slice(0, -1).reduce(function(prev, curr, index) { - return curr * data_strides[index] + prev; - }, 0); - data[ai] = datum; - } - cpos[dims - 1] += 1; - apos[dims - 1] += 1; - } - } - } - return data; - } - _filter_chunk(chunk_buffer, filter_mask, filter_pipeline, itemsize) { - let num_filters = filter_pipeline.length; - let buf = chunk_buffer.slice(); - for (var filter_index = num_filters - 1; filter_index >= 0; filter_index--) { - if (filter_mask & 1 << filter_index) { - continue; - } - let pipeline_entry = filter_pipeline[filter_index]; - let filter_id = pipeline_entry.get("filter_id"); - let client_data = pipeline_entry.get("client_data"); - if (Filters.has(filter_id)) { - buf = Filters.get(filter_id)(buf, itemsize, client_data); - } else { - throw 'NotImplementedError("Filter with id:' + filter_id.toFixed() + ' not supported")'; - } - } - return buf; - } -}; -var BTreeV2 = class extends AbstractBTree { - constructor(fh, offset) { - super(fh, offset); - __publicField(this, "B_TREE_HEADER", /* @__PURE__ */ new Map([ - ["signature", "4s"], - ["version", "B"], - ["node_type", "B"], - ["node_size", "I"], - ["record_size", "H"], - ["depth", "H"], - ["split_percent", "B"], - ["merge_percent", "B"], - ["root_address", "Q"], - ["root_nrecords", "H"], - ["total_nrecords", "Q"] - ])); - __publicField(this, "B_LINK_NODE", /* @__PURE__ */ new Map([ - ["signature", "4s"], - ["version", "B"], - ["node_type", "B"] - ])); - this.ready = this.init(); - } - async _read_root_node() { - let h = await this._read_tree_header(this.offset); - this.address_formats = this._calculate_address_formats(h); - this.header = h; - this.depth = h.get("depth"); - let address = [h.get("root_address"), h.get("root_nrecords"), h.get("total_nrecords")]; - let root_node = await this._read_node(address, this.depth); - this._add_node(root_node); - } - async _read_tree_header(offset) { - let header = await _unpack_struct_from_async(this.B_TREE_HEADER, this.fh, this.offset); - return header; - } - _calculate_address_formats(header) { - let node_size = header.get("node_size"); - let record_size = header.get("record_size"); - let nrecords_max = 0; - let ntotalrecords_max = 0; - let address_formats = /* @__PURE__ */ new Map(); - let max_depth = header.get("depth"); - for (var node_level = 0; node_level <= max_depth; node_level++) { - let offset_fmt = ""; - let num1_fmt = ""; - let num2_fmt = ""; - let offset_size, num1_size, num2_size; - if (node_level == 0) { - offset_size = 0; - num1_size = 0; - num2_size = 0; - } else if (node_level == 1) { - offset_size = 8; - offset_fmt = " 0) { - ntotalrecords_max *= nrecords_max; - } else { - ntotalrecords_max = nrecords_max; - } - } - } - return address_formats; - } - _nrecords_max(node_size, record_size, addr_size) { - return Math.floor((node_size - 10 - addr_size) / (record_size + addr_size)); - } - _required_bytes(integer) { - return Math.ceil(bitSize(integer) / 8); - } - _int_format(bytelength) { - return [" 0) { - num2 = (await struct.unpack_from_async(num2_fmt, this.fh, offset))[0]; - offset += num2_size; - } - addresses.push([address_offset, num1, num2]); - } - } - node.set("keys", keys); - node.set("addresses", addresses); - return node; - } - async _read_node_header(offset, node_level) { - let node = await _unpack_struct_from_async(this.B_LINK_NODE, this.fh, offset); - node.set("node_level", node_level); - return node; - } - *iter_records() { - for (let nodelist of this.all_nodes.values()) { - for (let node of nodelist) { - for (let key of node.get("keys")) { - yield key; - } - } - } - } - _parse_record(record) { - throw "NotImplementedError"; - } -}; -var BTreeV2GroupNames = class extends BTreeV2 { - constructor() { - super(...arguments); - __publicField(this, "NODE_TYPE", 5); - } - async _parse_record(buf, offset, size) { - let namehash = (await struct.unpack_from_async(" 0) { - throw "Filter info size not supported on FractalHeap"; - } - if (header.get("btree_address_huge_objects") == UNDEFINED_ADDRESS) { - header.set("btree_address_huge_objects", null); - } else { - throw "Huge objects not implemented in FractalHeap"; - } - if (header.get("root_block_address") == UNDEFINED_ADDRESS) { - header.set("root_block_address", null); - } - let nbits = header.get("log2_maximum_heap_size"); - let block_offset_size = this._min_size_nbits(nbits); - let h = /* @__PURE__ */ new Map([ - ["signature", "4s"], - ["version", "B"], - ["heap_header_adddress", "Q"], - ["block_offset", `${block_offset_size}B`] - ]); - this.indirect_block_header = new Map(h); - this.indirect_block_header_size = _structure_size(h); - if ((header.get("flags") & 2) == 2) { - h.set("checksum", "I"); - } - this.direct_block_header = h; - this.direct_block_header_size = _structure_size(h); - let maximum_dblock_size = header.get("maximum_direct_block_size"); - this._managed_object_offset_size = this._min_size_nbits(nbits); - let value = Math.min(maximum_dblock_size, header.get("max_managed_object_size")); - this._managed_object_length_size = this._min_size_integer(value); - let start_block_size = header.get("starting_block_size"); - let table_width = header.get("table_width"); - if (!(start_block_size > 0)) { - throw "Starting block size == 0 not implemented"; - } - let log2_maximum_dblock_size = Number(Math.floor(Math.log2(maximum_dblock_size))); - assert(1n << BigInt(log2_maximum_dblock_size) == maximum_dblock_size); - let log2_start_block_size = Number(Math.floor(Math.log2(start_block_size))); - assert(1n << BigInt(log2_start_block_size) == start_block_size); - this._max_direct_nrows = log2_maximum_dblock_size - log2_start_block_size + 2; - let log2_table_width = Math.floor(Math.log2(table_width)); - assert(1 << log2_table_width == table_width); - this._indirect_nrows_sub = log2_table_width + log2_start_block_size - 1; - this.header = header; - this.nobjects = header.get("managed_object_count") + header.get("huge_object_count") + header.get("tiny_object_count"); - let managed = []; - let root_address = header.get("root_block_address"); - let nrows = 0; - if (root_address != null) { - nrows = header.get("indirect_current_rows_count"); - } - if (nrows > 0) { - for await (let data of this._iter_indirect_block(this.fh, root_address, nrows)) { - managed.push(data); - } - } else { - let data = await this._read_direct_block(this.fh, root_address, start_block_size); - managed.push(data); - } - let data_size = managed.reduce((p, c) => p + c.byteLength, 0); - let combined = new Uint8Array(data_size); - let moffset = 0; - managed.forEach((m) => { - combined.set(new Uint8Array(m), moffset); - moffset += m.byteLength; - }); - this.managed = combined.buffer; - } - async _read_direct_block(fh, offset, block_size) { - let data = await fh.slice(offset, offset + block_size); - let header = _unpack_struct_from(this.direct_block_header, data); - assert(header.get("signature") == "FHDB"); - return data; - } - get_data(heapid) { - let firstbyte = struct.unpack_from("> 4 & 3; - let version = firstbyte >> 6; - let data_offset = 1; - if (idtype == 0) { - assert(version == 0); - let nbytes = this._managed_object_offset_size; - let offset = _unpack_integer(nbytes, heapid, data_offset); - data_offset += nbytes; - nbytes = this._managed_object_length_size; - let size = _unpack_integer(nbytes, heapid, data_offset); - return this.managed.slice(offset, offset + size); - } else if (idtype == 1) { - throw "tiny objectID not supported in FractalHeap"; - } else if (idtype == 2) { - throw "huge objectID not supported in FractalHeap"; - } else { - throw "unknown objectID type in FractalHeap"; - } - } - _min_size_integer(integer) { - return this._min_size_nbits(bitSize(integer)); - } - _min_size_nbits(nbits) { - return Math.ceil(nbits / 8); - } - async *_iter_indirect_block(fh, offset, nrows) { - let header = await _unpack_struct_from_async(this.indirect_block_header, fh, offset); - offset += this.indirect_block_header_size; - assert(header.get("signature") == "FHIB"); - let block_offset_bytes = header.get("block_offset"); - let block_offset = block_offset_bytes.reduce((p, c, i) => p + (c << i * 8), 0); - header.set("block_offset", block_offset); - let [ndirect, nindirect] = this._indirect_info(nrows); - let direct_blocks = []; - for (let i = 0; i < ndirect; i++) { - let address = (await struct.unpack_from_async(" { - return this._chunks; - }); - } - get shape() { - let msg = this.find_msg_type(DATASPACE_MSG_TYPE)[0]; - let msg_offset = msg.get("offset_to_message"); - return determine_data_shape(this.fh, msg_offset); - } - async get_filter_pipeline() { - if (this._filter_pipeline != null) { - return this._filter_pipeline; - } - let filter_msgs = this.find_msg_type(DATA_STORAGE_FILTER_PIPELINE_MSG_TYPE); - if (!filter_msgs.length) { - this._filter_pipeline = null; - return this._filter_pipeline; - } - var offset = filter_msgs[0].get("offset_to_message"); - let [version, nfilters] = await struct.unpack_from_async(" 255) { - name_length = (await struct.unpack_from_async(" 0; - filter_info.set("optional", optional); - let num_client_values = (await struct.unpack_from_async(" 0) { - name = (await struct.unpack_from_async(`${name_length}s`, buf, offset))[0]; - offset += name_length; - } - filter_info.set("name", name); - let client_values = await struct.unpack_from_async(`<${num_client_values}i`, buf, offset); - offset += 4 * num_client_values; - filter_info.set("client_data_values", client_values); - filters.push(filter_info); - } - } else { - throw `version ${version} is not supported`; - } - this._filter_pipeline = filters; - return this._filter_pipeline; - } - find_msg_type(msg_type) { - return this.msgs.filter(function(m) { - return m.get("type") == msg_type; - }); - } - async get_attributes() { - let attrs = {}; - let attr_msgs = this.find_msg_type(ATTRIBUTE_MSG_TYPE); - for (let msg of attr_msgs) { - let offset = msg.get("offset_to_message"); - let [name, value] = await this.unpack_attribute(offset); - attrs[name] = value; - } - return attrs; - } - async get_fillvalue() { - let msg = this.find_msg_type(FILLVALUE_MSG_TYPE)[0]; - var offset = msg.get("offset_to_message"); - var is_defined; - let version = (await struct.unpack_from_async("= block_size) { - [block_offset, block_size] = object_header_blocks[++current_block]; - local_offset = 0; - } - let msg = await _unpack_struct_from_async(HEADER_MSG_INFO_V1, fh, block_offset + local_offset); - let offset_to_message = block_offset + local_offset + HEADER_MSG_INFO_V1_SIZE; - msg.set("offset_to_message", offset_to_message); - if (msg.get("type") == OBJECT_CONTINUATION_MSG_TYPE) { - var [fh_off, size] = await struct.unpack_from_async("= block_size - HEADER_MSG_INFO_V2_SIZE) { - let next_block = object_header_blocks[++current_block]; - if (next_block == null) { - break; - } - [block_offset, block_size] = next_block; - local_offset = 0; - } - let msg = await _unpack_struct_from_async(HEADER_MSG_INFO_V2, buf, block_offset + local_offset); - let offset_to_message = block_offset + local_offset + HEADER_MSG_INFO_V2_SIZE + creation_order_size; - msg.set("offset_to_message", offset_to_message); - if (msg.get("type") == OBJECT_CONTINUATION_MSG_TYPE) { - var [fh_off, size] = await struct.unpack_from_async(" 0; - let link_name_character_set_field_present = (flags & 2 ** 4) > 0; - let ordered = (flags & 2 ** 2) > 0; - let link_type; - if (link_type_field_present) { - link_type = (await struct.unpack_from_async(" 0) { - offset += 8; - } - let fmt = (flags & 2) > 0 ? LINK_INFO_MSG2 : LINK_INFO_MSG1; - let link_info = await _unpack_struct_from_async(fmt, data, offset); - let output = /* @__PURE__ */ new Map(); - for (let [k, v] of link_info.entries()) { - output.set(k, v == UNDEFINED_ADDRESS2 ? null : v); - } - return output; - } - get is_dataset() { - return this.find_msg_type(DATASPACE_MSG_TYPE).length > 0; - } - async get_data() { - let msg = this.find_msg_type(DATA_STORAGE_MSG_TYPE)[0]; - let msg_offset = msg.get("offset_to_message"); - var [version, dims, layout_class, property_offset] = await this._get_data_message_properties(msg_offset); - if (layout_class == 0) { - throw "Compact storage of DataObject not implemented"; - } else if (layout_class == 1) { - return this._get_contiguous_data(property_offset); - } else if (layout_class == 2) { - return this._get_chunked_data(msg_offset); - } - } - async _get_data_message_properties(msg_offset) { - let dims, layout_class, property_offset; - let [version, arg1, arg2] = await struct.unpack_from_async("= 1 && version <= 4); - return [version, dims, layout_class, property_offset]; - } - async _get_contiguous_data(property_offset) { - let [data_offset] = await struct.unpack_from_async("=!@\|]?(i|u|f|S)(\d*)/.test(dtype)) { - let [item_getter, item_is_big_endian, item_size] = dtype_getter(dtype); - let output = new Array(fullsize); - const local_buffer = await this.fh.slice(data_offset, data_offset + item_size * fullsize); - let view = new DataView64(local_buffer); - for (var i = 0; i < fullsize; i++) { - output[i] = view[item_getter](i * item_size, !item_is_big_endian, item_size); - } - return output; - } else if (dtype.datatype_class === 5) { - return this.fh.slice(data_offset, data_offset + dtype.size); - } else { - throw "not Implemented - no proper dtype defined"; - } - } else { - let dtype_class = dtype[0]; - if (dtype_class == "REFERENCE") { - let size = dtype[1]; - if (size != 8) { - throw "NotImplementedError('Unsupported Reference type')"; - } - let ref_addresses = await this.fh.slice(data_offset, data_offset + fullsize); - return ref_addresses; - } else if (dtype_class == "VLEN_STRING") { - let character_set = dtype[2]; - const encoding = character_set == 0 ? "ascii" : "utf-8"; - const decoder = new TextDecoder(encoding); - var value = []; - for (var i = 0; i < fullsize; i++) { - const [vlen, vlen_data] = await this._vlen_size_and_data(this.fh, data_offset); - value[i] = decoder.decode(vlen_data); - data_offset += 16; - } - return value; - } else { - throw "NotImplementedError('datatype not implemented')"; - } - } - } - async _get_chunked_data(offset) { - await this._get_chunk_params(); - if (this._chunk_address == UNDEFINED_ADDRESS2) { - return []; - } - var chunk_btree = new BTreeV1RawDataChunks(this.fh, this._chunk_address, this._chunk_dims); - await chunk_btree.ready; - const dtype = await this.dtype; - const shape = await this.shape; - const chunks = await this.chunks; - const filter_pipeline = await this.get_filter_pipeline(); - let data = await chunk_btree.construct_data_from_chunks(chunks, shape, dtype, filter_pipeline); - if (dtype instanceof Array && /^VLEN/.test(dtype[0])) { - let dtype_class = dtype[0]; - for (var i = 0; i < data.length; i++) { - let [item_size, gheap_address, object_index] = data[i]; - var gheap; - if (!(gheap_address in this._global_heaps)) { - gheap = new GlobalHeap(this.fh, gheap_address); - await gheap.ready; - this._global_heaps[gheap_address] = gheap; - } else { - gheap = this._global_heaps[gheap_address]; - } - let vlen_data = gheap.objects.get(object_index); - if (dtype_class == "VLEN_STRING") { - let character_set = dtype[2]; - const encoding = character_set == 0 ? "ascii" : "utf-8"; - const decoder = new TextDecoder(encoding); - data[i] = decoder.decode(vlen_data); - } - } - } - return data; - } - async _get_chunk_params() { - if (this._chunk_params_set) { - return; - } - this._chunk_params_set = true; - var msg = this.find_msg_type(DATA_STORAGE_MSG_TYPE)[0]; - var offset = msg.get("offset_to_message"); - var [version, dims, layout_class, property_offset] = await this._get_data_message_properties(offset); - if (layout_class != 2) { - return; - } - var data_offset; - if (version == 1 || version == 2) { - var address = (await struct.unpack_from_async("= 1 && version <= 3); - var fmt = "<" + (dims - 1).toFixed() + "I"; - var chunk_shape = await struct.unpack_from_async(fmt, this.fh, data_offset); - this._chunks = chunk_shape; - this._chunk_dims = dims; - this._chunk_address = address; - return; - } -}; -async function determine_data_shape(buf, offset) { - let version = (await struct.unpack_from_async(" this.get(k)); - } - length() { - return this.keys.length; - } - _dereference(ref) { - if (!ref) { - throw "cannot deference null reference"; - } - let obj = this.file._get_object_by_address(ref); - if (obj == null) { - throw "reference not found in file"; - } - return obj; - } - async get(y) { - if (typeof y == "number") { - return this._dereference(y); - } - var path = normpath(y); - if (path == "/") { - return this.file; - } - if (path == ".") { - return this; - } - if (/^\//.test(path)) { - return this.file.get(path.slice(1)); - } - if (posix_dirname(path) != "") { - var [next_obj, additional_obj] = path.split(/\/(.*)/); - } else { - var next_obj = path; - var additional_obj = "."; - } - if (!(next_obj in this._links)) { - throw next_obj + " not found in group"; - } - var obj_name = normpath(this.name + "/" + next_obj); - let link_target = this._links[next_obj]; - if (typeof link_target == "string") { - try { - return this.get(link_target); - } catch (error) { - return null; - } - } - var dataobjs = new DataObjects(this.file._fh, link_target); - await dataobjs.ready; - if (dataobjs.is_dataset) { - if (additional_obj != ".") { - throw obj_name + " is a dataset, not a group"; - } - return new Dataset$1(obj_name, dataobjs, this); - } else { - var new_group = new Group(obj_name, this); - await new_group.init(dataobjs); - return new_group.get(additional_obj); - } - } - visit(func) { - return this.visititems((name, obj) => func(name)); - } - visititems(func) { - var root_name_length = this.name.length; - if (!/\/$/.test(this.name)) { - root_name_length += 1; - } - var queue = this.values.slice(); - while (queue) { - let obj = queue.shift(); - if (queue.length == 1) - console.log(obj); - let name = obj.name.slice(root_name_length); - let ret = func(name, obj); - if (ret != null) { - return ret; - } - if (obj instanceof Group) { - queue = queue.concat(obj.values); - } - } - return null; - } - get attrs() { - if (this._attrs == null) { - this._attrs = this._dataobjects.get_attributes(); - } - return this._attrs; - } -}; -var File$1 = class extends Group { - constructor(fh, filename, options) { - super("/", null); - this.ready = this.init(fh, filename, options); - } - async init(fh, filename, options) { - var superblock = new SuperBlock(fh, 0); - await superblock.ready; - var offset = await superblock.get_offset_to_dataobjects(); - var dataobjects = new DataObjects(fh, offset); - await dataobjects.ready; - this.parent = this; - this.file = this; - this.name = "/"; - this._dataobjects = dataobjects; - this._attrs = null; - this._keys = null; - this._fh = fh; - this.filename = filename || ""; - this.mode = "r"; - this.userblock_size = 0; - if (options && options.index) { - this.index = options.index; - } else { - let index_offset; - if (options && options.indexOffset) { - index_offset = options.indexOffset; - } else { - const attrs = await this.attrs; - if (attrs.hasOwnProperty("_index_offset")) { - index_offset = attrs["_index_offset"]; - } else { - const indexName = this.indexName || "_index"; - const index_link = await dataobjects.find_link(indexName); - if (index_link) { - index_offset = index_link[1]; - } - } - } - if (index_offset) { - try { - const dataobject = new DataObjects(fh, index_offset); - await dataobject.ready; - const comp_index_data = await dataobject.get_data(); - const inflated = ungzip_1(comp_index_data); - const json = new TextDecoder().decode(inflated); - this.index = JSON.parse(json); - } catch (e) { - console.error(`Error loading index by offset ${e}`); - } - } - } - if (this.index && this.name in this.index) { - this._links = this.index[this.name]; - } else { - this._links = await dataobjects.get_links(); - } - } - _get_object_by_address(obj_addr) { - if (this._dataobjects.offset == obj_addr) { - return this; - } - return this.visititems((y) => { - y._dataobjects.offset == obj_addr ? y : null; - }); - } -}; -var Dataset$1 = class extends Array { - constructor(name, dataobjects, parent) { - super(); - this.parent = parent; - this.file = parent.file; - this.name = name; - this._dataobjects = dataobjects; - this._attrs = null; - this._astype = null; - } - get value() { - var data = this._dataobjects.get_data(); - if (this._astype == null) { - return this.getValue(data); - } - return data.astype(this._astype); - } - get shape() { - return this._dataobjects.shape; - } - get attrs() { - return this._dataobjects.get_attributes(); - } - get dtype() { - return this._dataobjects.dtype; - } - get fillvalue() { - return this._dataobjects.get_fillvalue(); - } - async to_array() { - const value = await this.value; - const shape = await this.shape; - return create_nested_array(value, shape); - } - async getValue(data) { - const dtype = await this.dtype; - if ((typeof dtype === "string" || dtype instanceof String) && dtype.startsWith("S")) { - return (await data).map((s) => { - let idx = s.indexOf("\0"); - return idx >= 0 ? s.substring(0, idx) : s; - }); - } else { - return data; - } - } -}; -function posix_dirname(p) { - let sep = "/"; - let i = p.lastIndexOf(sep) + 1; - let head = p.slice(0, i); - let all_sep = new RegExp("^" + sep + "+$"); - let end_sep = new RegExp(sep + "$"); - if (head && !all_sep.test(head)) { - head = head.replace(end_sep, ""); - } - return head; -} -function normpath(path) { - return path.replace(/\/(\/)+/g, "/"); -} -function create_nested_array(value, shape) { - const total_length = value.length; - const dims_product = shape.reduce((previous, current) => previous * current, 1); - if (total_length !== dims_product) { - console.warn(`shape product: ${dims_product} does not match length of flattened array: ${total_length}`); - } - let output = value; - const subdims = shape.slice(1).reverse(); - for (let dim of subdims) { - const new_output = []; - const { length } = output; - let cursor = 0; - while (cursor < length) { - new_output.push(output.slice(cursor, cursor += dim)); - } - output = new_output; - } - return output; -} -/*! pako 2.0.4 https://github.com/nodeca/pako @license (MIT AND Zlib) */ - -async function openH5File(options) { - - // Some clients (notably igv-webapp) pass a File reference in the url field. Fix this - if(options.url && isBlobLike(options.url)) { - options.file = options.url; - options.url = undefined; - } - - const isRemote = options.url !== undefined; - let fileReader = options.reader ? options.reader : getReaderFor(options); - - // Set default options appropriate for spacewalk - const fetchSize = options.fetchSize || 2000; - const maxSize = options.maxSize || 200000; - - if (isRemote) { - fileReader = new BufferedFile$1({file: fileReader, fetchSize, maxSize}); - } - const asyncBuffer = new AsyncBuffer(fileReader); - - // Optional external index -- this is not common - const index = await readExternalIndex(options); - const indexOffset = options.indexOffset; - - // Create HDF5 file - const filename = getFilenameFor(options); - const hdfFile = new File$1(asyncBuffer, filename, {index, indexOffset}); - await hdfFile.ready; - return hdfFile -} - -async function readExternalIndex(options) { - - let indexReader; - if(options.indexReader) { - indexReader = options.indexReader; - } - else if(options.index) { - return options.index - } else if (options.indexURL) { - indexReader = new RemoteFile$1({url: options.indexURL}); - } else if (options.indexPath) { - indexReader = new NodeLocalFile({path: options.indexPath}); - } else if (options.indexFile) { - indexReader = new BlobFile({file: options.indexFile}); - } - if (indexReader) { - const indexFileContents = await indexReader.read(); - const indexFileJson = new TextDecoder().decode(indexFileContents); - return JSON.parse(indexFileJson) - } else { - return undefined - } -} - - -function getReaderFor(options) { - if (options.url) { // An absolute or relative URL - return new RemoteFile$1(options) - } else if (options.path) { // A file path - return new NodeLocalFile(options) - } else if (options.file) { // A Browser file blob - return new BlobFile(options.file) - } else { - throw Error("One of 'url', 'path (node only)', or 'file (browser only)' must be specified") - } -} - -function getFilenameFor(options) { - if (options.url) { - return getFilename(options.url) - } else if (options.path) { - return getFilename(options.path) - } else if (options.file) { - return options.file.name - } -} - -/** - * Wraps an io.Reader in an interface jsfive-async expects* - */ -class AsyncBuffer { - constructor(fileReader) { - this.fileReader = fileReader; - } - - async slice(start, end) { - return this.fileReader.read(start, end - start) - } -} - -function getFilename(pathOrURL) { - const idx = pathOrURL.lastIndexOf("/"); - return idx > 0 ? pathOrURL.substring(idx + 1) : pathOrURL -} - -function isBlobLike(obj) { - return typeof obj.slice === 'function' && typeof obj.arrayBuffer === 'function' -} - -class HDF5Reader { - - constructor(h5_file, bin_size=100000){ - - this.h5_file = h5_file; - this.bin_size = bin_size; - this.h5_obj = undefined; - } - - async fetch(){ - - if(!this.h5_obj) { - this.h5_obj = await openH5File({ - url: this.h5_file, - fetchSize: 1000000, - maxSize: 200000000 - }); - } - return this.h5_obj - } - - async get_keys(){ - /* returns a list of keys of the pytor file*/ - let h5_obj = await this.fetch(); - - return h5_obj.keys - } - - async get_rd_signal(bin_size=this.bin_size){ - - let h5_obj = await this.fetch(); - let h5_obj_keys = h5_obj.keys; - - // console.log(h5_obj_keys) - let signal_bin = new ParseSignals(h5_obj_keys); - let rd_bins = signal_bin.get_rd_bins(); - let snp_bins = signal_bin.get_snp_bins(); - this.available_bins = [...new Set(rd_bins, snp_bins)]; - - // let bin_size = this.bin_size - if(! this.available_bins.includes(bin_size)){ - bin_size = this.available_bins.at(-1); - } - - const chr_ds = await h5_obj.get("rd_chromosomes"); - await chr_ds.dtype; - let rd_chromosomes = await chr_ds.value; - //console.log(`get_rd_signal rd_chromosomes ${Date.now() - t0}`) - //rd_chromosomes = fixString(rd_chromosomes) - let rd_flag = ""; - - // get rd stat - let rd_stat = await this.rd_stat(h5_obj, h5_obj_keys, bin_size); - - var wigFeatures = []; - var wigFeatures_gc = []; - var wigFeatures_rd_call_meanshift = []; - var wigFeatures_rd_call_combined = []; - var wigFeatures_baf1 = []; - var wigFeatures_baf2 = []; - - for (let chrom of rd_chromosomes) { - // for normal rd signal - var signal_rd = `his_rd_p_${chrom}_${bin_size}${rd_flag}`; - let chr_wig = await this.get_chr_signal(h5_obj, h5_obj_keys, chrom, bin_size, signal_rd, rd_stat); - wigFeatures = wigFeatures.concat(chr_wig); - - // rd gc corrected - var signal_rd_gc = `his_rd_p_${chrom}_${bin_size}_GC`; - let chr_wig_gc = await this.get_chr_signal(h5_obj, h5_obj_keys, chrom, bin_size, signal_rd_gc, rd_stat); - wigFeatures_gc = wigFeatures_gc.concat(chr_wig_gc); - - // rd call MeanShift - - let signal_rd_call = `his_rd_p_${chrom}_${bin_size}_partition_GC_merge`; - let chr_wig_rd_call_meanshift = await this.get_chr_signal(h5_obj, h5_obj_keys, chrom, bin_size, signal_rd_call, rd_stat); - wigFeatures_rd_call_meanshift = wigFeatures_rd_call_meanshift.concat(chr_wig_rd_call_meanshift); - - let chr_wig_rd_call = await this.rd_call_combined(h5_obj, h5_obj_keys, chrom, bin_size, rd_stat); - wigFeatures_rd_call_combined = wigFeatures_rd_call_combined.concat(chr_wig_rd_call); - - // baf likelihood - let signal_baf_1 = `snp_likelihood_${chrom}_${bin_size}_mask`; - let chr_wig_bafs = await this.get_baf_signals(h5_obj, h5_obj_keys, chrom, bin_size, signal_baf_1); - - // let signal_baf_1 = `snp_i1_${chrom}_${bin_size}_mask` - // let chr_wig_bafs = await this.get_baf_signals_v2(h5_obj, h5_obj_keys, chrom, bin_size, signal_baf_1) - - wigFeatures_baf1 = wigFeatures_baf1.concat(chr_wig_bafs[0]); - wigFeatures_baf2 = wigFeatures_baf2.concat(chr_wig_bafs[1]); - // this.rd_call_combined(h5_obj, h5_obj_keys, chrom, bin_size, rd_stat) - } - this.callers = []; - if (wigFeatures_rd_call_combined.length != 0){ - this.callers.push('ReadDepth'); - } - if (wigFeatures_rd_call_combined.length != 0){ - this.callers.push('2D'); - } - - var obj = {}; - var signal_obj = { - "RD_Raw": wigFeatures, - "RD_Raw_gc_coor" : wigFeatures_gc, - "ReadDepth": wigFeatures_rd_call_meanshift, - "2D": wigFeatures_rd_call_combined, - "BAF1": wigFeatures_baf1, - "BAF2": wigFeatures_baf2 - }; - obj[bin_size] = signal_obj; - return obj - } - - decode_segments(segments_arr){ - let max = 2 ** 32 - 1; - let segments = []; - let l = []; - for (let x of segments_arr){ - if(x == max){ - segments.push(l); - l = []; - } else { - l.push(x); - } - } - return segments - } - - async rd_call_combined(h5_obj, h5_obj_keys, chrom, bin_size, rd_stat){ - let chr_wig = []; - - let segments; - let mosaic_call_segments = `his_rd_p_${chrom}_${bin_size}_partition_GC_mosaic_segments_2d`; - if (h5_obj_keys.includes(mosaic_call_segments)){ - const chrom_dataset = await h5_obj.get(mosaic_call_segments); - let chrom_data = await chrom_dataset.value; - //console.log(`rd_call_combined ${mosaic_call_segments} ${Date.now() - t0}`) - segments = this.decode_segments(chrom_data); - - } - - let mosaic_calls = `his_rd_p_${chrom}_${bin_size}_partition_GC_mosaic_call_2d`; - if (h5_obj_keys.includes(mosaic_calls)){ - const segments_call_dataset = await h5_obj.get(mosaic_calls); - let segments_call = await segments_call_dataset.to_array(); //create_nested_array(value, shape) - segments.forEach((ind_segment, segment_idx) => { - ind_segment.forEach((bin_value, bin_idx) =>{ - chr_wig.push({chr:chrom, start: bin_value*bin_size, end: (bin_value+1) * bin_size, value: (segments_call[0][segment_idx]/rd_stat[4]) *2}); - }); - }); - } - - return chr_wig - - } - - async rd_stat(h5_obj, h5_obj_keys, bin_size){ - /* - returns a list for rd statistics information - paramter - --------- - h5_obj: cnvpytor read object - h5_obj_keys: a list of available signal names - bin_size: bin size - - */ - - let rd_stat_signal = `rd_stat_${bin_size}_auto`; - let rd_stat; - if (h5_obj_keys.includes(rd_stat_signal)){ - const rd_stat_dataset = await h5_obj.get(rd_stat_signal); - rd_stat = await rd_stat_dataset.value; - //console.log(`rd_stat_signal ${rd_stat_signal} ${Date.now() - t0}`) - } - return rd_stat - } - - - async get_chr_signal(h5_obj, h5_obj_keys, chrom, bin_size, signal_name, rd_stat){ - /* return a list of dictionary for a chromosome */ - let chr_wig = []; - - if (h5_obj_keys.includes(signal_name)){ - const chrom_dataset = await h5_obj.get(signal_name); - let chrom_data = await chrom_dataset.value; - //console.log(`chr_signal ${signal_name} ${Date.now() - t0}`) - chrom_data.forEach((bin_value, bin_idx) => { - chr_wig.push({chr:chrom, start: bin_idx*bin_size, end: (bin_idx+1) * bin_size, value: (bin_value/rd_stat[4]) *2}); - }); - } - return chr_wig - } - - async get_baf_signals(h5_obj, h5_obj_keys, chrom, bin_size, signal_name){ - /* return two list of dictionary*/ - let chr_wig_1 = []; - let chr_wig_2 = []; - if (h5_obj_keys.includes(signal_name)){ - let chrom_dataset = await h5_obj.get(signal_name); - let chrom_data = await chrom_dataset.to_array(); //create_nested_array(value, shape) - chrom_data.forEach((bin_value, bin_idx) => { - let max_value = Math.max(...bin_value); - const res = bin_value.indexOf(max_value); - let lh = Math.max(res / 200, 1 - res / 200); - chr_wig_1.push({chr:chrom, start: bin_idx*bin_size, end: (bin_idx+1) * bin_size, value: -2 * lh}); - if(lh != 0.5){ - chr_wig_2.push({chr:chrom, start: bin_idx*bin_size, end: (bin_idx+1) * bin_size, value: -2 *(1-lh)}); - } - }); - } - return [chr_wig_1, chr_wig_2] - } - - async get_baf_signals_v2(h5_obj, h5_obj_keys, chrom, bin_size, signal_name){ - - /* return two list of dictionary*/ - let chr_wig_1 = []; - let chr_wig_2 = []; - if (h5_obj_keys.includes(signal_name)){ - let chrom_dataset = await h5_obj.get(signal_name); - let chrom_data = await chrom_dataset.to_array(); //create_nested_array(value, shape) - chrom_data.forEach((lh, bin_idx) => { - if (!isNaN(lh)){ - chr_wig_1.push({chr:chrom, start: bin_idx*bin_size, end: (bin_idx+1) * bin_size, value: -2 * ( 0.5 - lh )}); - if(lh != 0.5){ - chr_wig_2.push({chr:chrom, start: bin_idx*bin_size, end: (bin_idx+1) * bin_size, value: -2 * ( 0.5 + lh )}); - } - } - }); - } - console.log(chrom, chr_wig_1, chr_wig_2); - return [chr_wig_1, chr_wig_2] - - } -} - -class ParseSignals{ - - constructor(signals){ - /* - Parse a signal names - - parameter - --------- - signals: List of keys in pytor files - */ - this.signals = signals; - } - - get_rd_bins(){ - /* return list of rd bins */ - let rd_keys = []; - this.signals.forEach( val => { - let match = val.match(/^his_rd_p_(.*)_(\d+)$/); - if(match){ - rd_keys.push({chr:match[1], bin_size:match[2]}); - }}); - const rd_bins = [...new Set(rd_keys.map(item => Number(item.bin_size)))]; - return rd_bins - } - - get_snp_bins(){ - /* return list of snp bins */ - let slected_signals = []; - this.signals.forEach( val => { - let match = val.match(/^snp_likelihood_(.*)_(\d+)_mask$/); - if(match){ - slected_signals.push({chr:match[1], bin_size:match[2]}); - }}); - const bins = [...new Set(slected_signals.map(item => Number(item.bin_size)))]; - return bins - } -} - -class GetFit { - constructor(allBins) { - this.allBins = allBins; - } - getValues() { - const bins = Object.values(this.allBins).reduce( - (binResult, bin) => { return binResult.concat(bin.filter(a => a.binScore > 0).map(a => a.binScore)) }, []); - return bins - } - getMean(data) { - return (data.reduce(function (a, b) { return a + b; }) / data.length); - } - fit_data() { - let rd_list = this.getValues(); - let distParmas = getDistParams(rd_list); - return distParmas - } - - histogram(data, bins) { - const step = bins[1] - bins[0]; - const hist_bins = []; - - data.forEach((value, index) => { - bins.forEach((bin_value, bin_index) => { - if (!hist_bins[bin_value]) { - hist_bins[bin_value] = { count: 0 }; - } - if (bin_value <= value && value < bin_value + step) { - hist_bins[bin_value].count++; - return false; - } - }); - }); - const dist_p = []; - hist_bins.forEach((bin, index) => { dist_p.push(bin.count); }); - return dist_p - } - -} - -function range_function(start, stop, step) { - const data_array = Array(Math.ceil((stop - start) / step)) - .fill(start) - .map((x, y) => x + y * step); - return data_array; -} - -function filterOutliers(someArray) { - - if (someArray.length < 4) - return someArray; - - let values, q1, q3, iqr, maxValue, minValue; - - values = someArray.slice().sort((a, b) => a - b); //copy array fast and sort - - if ((values.length / 4) % 1 === 0) { //find quartiles - q1 = 1 / 2 * (values[(values.length / 4)] + values[(values.length / 4) + 1]); - q3 = 1 / 2 * (values[(values.length * (3 / 4))] + values[(values.length * (3 / 4)) + 1]); - } else { - q1 = values[Math.floor(values.length / 4 + 1)]; - q3 = values[Math.ceil(values.length * (3 / 4) + 1)]; - } - - iqr = q3 - q1; - maxValue = q3 + iqr * 1.5; - minValue = q1 - iqr * 1.5; - - return values.filter((x) => (x >= minValue) && (x <= maxValue)); -} - -function getDistParams(bins) { - let filteredBins = filterOutliers(bins); - const n = filteredBins.length; - const mean = filteredBins.reduce((a, b) => a + b) / n; - const std = Math.sqrt(filteredBins.map(x => Math.pow(x - mean, 2)).reduce((a, b) => a + b) / n); - return [mean, std] -} - -function linspace(a, b, n) { - if (typeof n === "undefined") n = Math.max(Math.round(b - a) + 1, 1); - if (n < 2) { - return n === 1 ? [a] : []; - } - var ret = Array(n); - n--; - for (let i = n; i >= 0; i--) { - ret[i] = (i * b + (n - i) * a) / n; - } - return ret; -} - -var g_utils = { range_function, getDistParams, linspace, GetFit}; - -/** -* Evaluates the cumulative distribution function (CDF) for a Student's t distribution with degrees of freedom `v` at a value `t`. -* -* @params {number} t - value for the t test -* @params {PositiveNumber} v - degree of freedom -* @returns {Probability} evaluated CDF -*/ -function TdistributionCDF(t, v){ - if (isNaN( t ) || isNaN( v ) || v <= 0.0) { - return NaN; - } - if ( t === 0.0 ) { - return 0.5; - } - return 1/2 + (1/2 * (incompbeta(1/2*v, 1/2, 1) - incompbeta(1/2*v, 1/2, v/(v+t*t)))) * Math.sign( t) - -} - - -/** -* incompbeta(a,b,x) evaluates incomplete beta function, here a, b > 0 and 0 <= x <= 1. This function requires contfractbeta(a,b,x, ITMAX = 200) -* code translated from https://malishoaib.wordpress.com/2014/04/15/the-beautiful-beta-functions-in-raw-python/ -* -* @params -* @params -* @params -* @returns -*/ -function incompbeta(a, b, x){ - - if(x == 0){ - return 0; - } - else if (x == 1){ - return 1; - }else - { - let lbeta = lgamma(a+b) - lgamma(a) - lgamma(b) + a * Math.log(x) + b * Math.log(1-x); - if (x < (a+1) / (a+b+2)){ - return Math.exp(lbeta) * contfractbeta(a, b, x) / a; - } - else { - return 1 - Math.exp(lbeta) * contfractbeta(b, a, 1-x) / b; - } - } -} - -/** - * contfractbeta() evaluates the continued fraction form of the incomplete Beta function; incompbeta(). - * (Code translated from: Numerical Recipes in C.) - * - * @param {*} a - * @param {*} b - * @param {*} x - * @param {*} ITMAX - * @returns - */ -function contfractbeta(a,b,x, ITMAX = 1000){ - - let EPS = 3.0e-7; - let az = 1.0; - let am = 1.0; - let bm = 1.0; - let qab = a + b; - let qap = a + 1.0; - let qam = a-1.0; - let bz = 1.0 - qab*x/qap; - - //for i in range(ITMAX): - for(let i =0; i<= ITMAX; i++){ - let em = parseFloat(i+1); - let tem = em + em; - let d = em*(b-em)*x/((qam+tem)*(a+tem)); - let ap = az + d*am; - let bp = bz+d*bm; - d = -(a+em)*(qab+em)*x/((qap+tem)*(a+tem)); - let app = ap+d*az; - let bpp = bp+d*bz; - let aold = az; - am = ap/bpp; - bm = bp/bpp; - az = app/bpp; - bz = 1.0; - if (Math.abs(az-aold)<(EPS * Math.abs(az))){ - return az - } - } -} - -/** - * Evaluates factorial of a number - * - * @param {Number} xf - Integer number - * @returns factorial of the number - */ -function factorial(xf) { - if ((xf == 0) || (xf == 1)) return 1; - else { - let result = (xf * factorial(xf - 1)); - return result - } -} - -/** - * Evalues factorial for an integer or fraction using either either factorial or gamma function - * - * @param {Number} a - integar or fraction number - * @returns value of a gamma function - */ -function gamma(a){ - let gamma; - - var qc = [75122.6331530, 80916.6278952, 36308.2951477, 8687.24529705, 1168.92649479, 83.8676043424, 2.50662827511]; - - var sum1 = 0; - var prod1 = 1; - if (a == 0) { - gamma = 1e99; - }else { - if ((a % 1) == 0) {//if integer - gamma = factorial(a - 1); - } - else { //not integer - for (let j = 0; j < qc.length; j++) { - sum1 = sum1 + qc[j] * Math.pow(a, j); - prod1 = prod1 * (a + j); - } - gamma = (sum1 * Math.pow((a + 5.5), (a + 0.5))) * Math.exp(-(a + 5.5)) / prod1; - } - } - - return gamma -} - -/** - * - * @param {Number} xg - integar or fraction number - * @returns natural log of gamma function - */ - -function lgamma(xg){ - return Math.log(gamma(xg)) -} - -function t_test_1_sample$1(mean, m, s, n) { - if (s == 0) s = 1; - var t = ((mean - m) / s) * Math.sqrt(n); - var p = 1.0 - TdistributionCDF(Math.abs(t), (n - 1)); - return p -} - -function t_test_2_samples$1(m1, s1, n1, m2, s2, n2) { - if (s1 == 0) s1 = 1; - if (s2 == 0) s2 = 1; - var t = (m1 - m2) / Math.sqrt(s1 ** 2 / n1 + s2 ** 2 / n2); - var df = ((s1 ** 2 / n1 + s2 ** 2 / n2) ** 2 * (n1 - 1) * (n2 - 1)) / - ((s1 ** 4 * (n2 - 1)) / n1 ** 2 + (s2 ** 4 * (n1 - 1)) / n2 ** 2); - - var p = 1.0 - TdistributionCDF(Math.abs(t), parseInt(df + 0.5)); - - return p -} - -var t_dist = {TdistributionCDF, gamma, t_test_1_sample: t_test_1_sample$1, t_test_2_samples: t_test_2_samples$1}; - -class CombinedCaller{ - constructor(wigFeatures, binSize) { - this.wigFeatures = wigFeatures; - this.binSize = binSize; - // let fit_obj = this.get_fit() - // this.globalMean = fit_obj.globalMean - // this.globalStd = fit_obj.globalStd - } - get_fit(){ - var fit_info = new g_utils.GetFit(this.wigFeatures); - var [globalMean, globalStd] = fit_info.fit_data(); - - return {globalMean:globalMean, globalStd:globalStd} - - } - async call_2d(omin=null, mcount=null, event_type="both", max_distance=0.1, baf_threshold=0, max_copy_number=10, min_cell_fraction=0.0){ - - let fit_obj = this.get_fit(); - this.globalMean = fit_obj.globalMean; - this.globalStd = fit_obj.globalStd; - - let overlap_min = omin==null ? 0.05 * this.binSize / 3e9: omin ; - let min_count = mcount == null ? parseInt(this.binSize / 10000) : mcount ; - - let gstat_rd0 = []; - let gstat_rd_all = []; - let gstat_rd = []; - let gstat_error = []; - let gstat_lh = []; - let gstat_n = []; - - for (const [chr, wig] of Object.entries(this.wigFeatures)) { - let segments = []; - let levels = []; - let likelihoods = []; - - wig.forEach((bin, bin_idx) => { - if (bin.hets_count > 4 ){ - - if( bin.dp_count > min_count ){ - segments.push([bin_idx]); - levels.push(bin.binScore); - likelihoods.push(bin.likelihood_score); - delete bin.likelihood_score; - - } - } - }); - - let diff_level = []; - for(let i=1; i {return Math.sqrt(Math.sqrt(x) ** 2 + this.globalStd ** 2 + Math.pow(min_flank[x_idx]/2, 2));}); - - let overlaps = []; - - for(let i=0; i< segments.length-1; i++){ - - let lh_overlap = 0; - try{ - lh_overlap = likelihood_overlap(likelihoods[i], likelihoods[i+1]); - }catch{ - console.log("Overlap failed: ", i, likelihoods[i], segments[i+1], likelihoods[i+1]); - } - - let rd_overlap = normal_overlap_approx(levels[i], error[i], levels[i+1], error[i+1]); - overlaps.push(rd_overlap * lh_overlap); - - } - - while(overlaps.length >0) { - overlaps = overlaps.filter(num => typeof num === "number"); - - let max_overlap = arrayMax(overlaps); - if(isNaN(max_overlap)){ - console.log('NaN value', overlaps); - } - if(max_overlap < overlap_min){ - // console.log("maxoverlap ",max_overlap, "is smaller than overlap min") - break - } - let i = overlaps.indexOf(max_overlap); - - let merge_level = normal_merge(levels[i], error[i], levels[i + 1], error[i + 1]); - - let nlh; - let nlh_sum; - try{ - nlh = likelihoods[i].map((l_value, l_idx) => { return l_value * likelihoods[i+1][l_idx]}); - - nlh_sum = nlh.reduce((a, c_value) => {return a + c_value}); - - }catch{ - console.log(likelihoods); - console.log('max_overlap:', max_overlap, i, overlaps.length); - console.log('likelihood: ', i ,likelihoods[i], likelihoods[i+1]); - console.log('nlh: ', nlh_sum); - } - // nlh_sum = nlh.reduce((a, c_value) => {return a + c_value}); - - levels[i] = merge_level.nl; - error[i] = merge_level.ne; - - likelihoods[i] = nlh.map(function(item) { return item/nlh_sum } ); - - segments[i].push(...segments[i+1]); - - levels.splice(i + 1, 1); - error.splice(i + 1, 1); - segments.splice(i + 1, 1); - likelihoods.splice(i + 1, 1); - overlaps.splice(i, 1); - - if(i < overlaps.length){ - - let rd_overlap = normal_overlap_approx(levels[i], error[i], levels[i+1], error[i+1]); - let new_overlap = rd_overlap * likelihood_overlap(likelihoods[i], likelihoods[i + 1]); - - overlaps[i] = new_overlap; - } - if(i > 0){ - let new_overlap = normal_overlap_approx(levels[i - 1], error[i - 1], levels[i], error[i]) - * likelihood_overlap(likelihoods[i - 1], likelihoods[i]); - overlaps[i - 1] = new_overlap; - } - - } - let ons = -1; - while(true){ - overlaps = []; - for(let i=0; i< levels.length; i++){ - for(let j=i; j { return l_value * likelihoods[i+1][l_idx]}); - let nlh_sum = nlh.reduce((a, c_value) => {return a + c_value}); - likelihoods[i] = nlh.map(function(item) { return item/nlh_sum } ); - - - segments[i].push(...segments[i+1]); - segments[i] = segments[i].sort((a,b) => a-b); - - levels.splice(j, 1); - error.splice(j, 1); - segments.splice(j, 1); - likelihoods.splice(j, 1); - - if(j >= segments.length){ - i += 1; - j = i + 1; - } - - }else { - j += 1; - if(j >= segments.length){ - i += 1; - j = i + 1; - } - } - } - if(ons == segments.length){ - break - } - ons = segments.length; - } - // console.log('final segments', segments) - - segments.forEach((seg_value, seg_idx) => { - let baf_info = likelihood_baf_pval(likelihoods[seg_idx]); - if(seg_value.length > 1){ - - seg_value.forEach((bin, bin_idx) =>{ - gstat_rd_all.push(wig[bin]); - if(baf_info.mean <= baf_threshold){ - gstat_rd0.push(wig[bin]); - } - wig[bin].segment_score = levels[seg_idx]; - }); - gstat_rd.push(levels[seg_idx]); - gstat_error.push(error[seg_idx]); - gstat_lh.push(likelihoods[seg_idx]); - - } - - }); - - continue - } - - // Third stage for call - - // let data = gstat_rd0.lengthn == 0 ? gstat_rd_all: gstat_rd0 ; - - let points = parseInt(1000 * (1 - min_cell_fraction)); - if(points == 0){ - points = 1; - } - let x = g_utils.linspace(min_cell_fraction, 1, points); - let master_lh = {}; - let germline_lh = {}; - for(let cn=10; cn > -1; cn--){ - for(let h1=0; h1 < (cn/2+1); h1++){ - let h2 = cn - h1; - let mrd = x.map((v, idx) => {return 1-v +v*cn/2}); - let g_mrd = cn / 2; - let g_mbaf; - let mbaf; - if(cn > 0){ - g_mbaf = 0.5 - (h1 / (h1 + h2)); - mbaf = x.map((v, idx) => {return 0.5 - (1 - v + v * h1) / (2 - 2 * v + (h1 + h2) * v)}); - - }else { - g_mbaf = 0; - mbaf = x.map((v, idx) => {return 0*v}); - } - - for( let ei=0; ei < gstat_rd.length; ei++){ - - let g_lh = normal(g_mrd * this.globalMean, 1, gstat_rd[ei], gstat_error[ei]) * likelihood_of_baf(gstat_lh[ei], 0.5 + g_mbaf); - if(ei in germline_lh){ - germline_lh[ei].push([cn, h1, h2, g_lh, 1.0]); - }else { - germline_lh[ei] = [cn, h1, h2, g_lh, 1.0]; - } - let slh = 0; - let max_lh = 0; - let max_x = 0; - mrd.forEach((mi, idx) => { - if(!isNaN(mbaf[idx])){ - let tmpl = normal(mi * this.globalMean, 1, gstat_rd[ei], gstat_error[ei]) * likelihood_of_baf(gstat_lh[ei], 0.5 + mbaf[idx]); - slh += tmpl; - if(tmpl > max_lh){ - max_lh = tmpl; - max_x = x[idx]; - } - } - }); - if(ei in master_lh){ - master_lh[ei].push([cn, h1, h2, slh / x.length, max_x]); - }else { - master_lh[ei] = [cn, h1, h2, slh / x.length, max_x]; - } - } - - for( let ei=0; ei < gstat_rd.length; ei++){ - if(event_type == "germline"){ - master_lh[ei].sort((a, b) => a[3] - b[3]); - } - else { - master_lh[ei].sort((a, b) => a[3] - b[3]); - if(event_type == "both"){ - - germline_lh[ei].sort((a, b) => a[3] - b[3]); - if(germline_lh[ei][0][3] > master_lh[ei][0][3]){ - //let tmp_list = list(filter( lambda x: x[0] != germline_lh[ei][0][0] and x[1] != germline_lh[ei][0][1], master_lh[ei])) - let tmp_list = master_lh[ei].filter((x) => (x[0] != germline_lh[ei][0][0]) && (x[1] <= germline_lh[ei][0][1])); - // console.log('tmp_list', tmp_list) - // master_lh[ei] = [germline_lh[ei][0]] + tmp_list - master_lh[ei] = [germline_lh[ei][0]].push(...tmp_list); - } - } - } - } - for( let ei=0; ei < gstat_rd.length; ei++){ - if(master_lh[ei][0][0] > 2); - if(master_lh[ei][0][0] < 2); - gstat_rd[ei] / this.globalMean; - t_dist.t_test_1_sample(this.globalMean, gstat_rd[ei], gstat_error[ei], gstat_n[ei]); - // console.log(etype) - - } - - - // break - } - - } - - var rawbinScore = this.formatDataStructure(this.wigFeatures, 'binScore', this.globalMean); - var callScore = this.formatDataStructure(this.wigFeatures, 'segment_score', this.globalMean); - - return {binScore: rawbinScore, segment_score: callScore} - - } - - formatDataStructure(wigFeatures, feature_column, scaling_factor = 1) { - const results = []; - for (const [chr, wig] of Object.entries(wigFeatures)) { - - wig.forEach(sample => { - var new_sample = { ...sample }; - if (scaling_factor != 1) { - new_sample.value = sample[feature_column] / scaling_factor * 2; - } - results.push(new_sample); - }); - } - - return results - } - - formatDataStructure_BAF(feature_column, scaling_factor = 2) { - const baf1 = []; - const baf2 = []; - for (const [chr, wig] of Object.entries(this.wigFeatures)) { - - wig.forEach(sample => { - - var baf1_value = { ...sample }; - var baf2_value = { ...sample }; - - let value = sample[feature_column]; - if (value != 0.5){ - baf2_value.value = -2 * (1 - value); - baf2.push(baf2_value); - } - baf1_value.value = -2 * value; - baf1.push(baf1_value); - - }); - } - - - return [baf1, baf2] - } -} - -function arrayMax(arr) { - return arr.reduce(function (p, v) { - return ( p > v ? p : v ); - }); - } - -/** - * Normal distribution. - * - * @param {float} x - Variable. - * @param {float} a - area - * @param {float} x0 - Mean value - * @param {float} sigma - Sigma - * @returns {float} - Value of distribution in x. - */ -function normal(x, a, x0, sigma){ - - return a * Math.exp(-1* (x - x0) ** 2 / (2 * sigma ** 2)) / Math.sqrt(2 * Math.PI) / sigma - -} - -/** - * Calculates two normal distributions overlap area. - * - * @param {float} m1 - Mean value of the first distribution - * @param {float} s1 - Sigma of the first distribution - * @param {float} m2 - Mean value for second distribution - * @param {float} s2 - Sigma of the second distribution - * - * @returns {float} area - Area of overlap - */ -function normal_overlap_approx(m1, s1, m2, s2){ - - return Math.exp(-1* (m1-m2)**2/ (s1**2+s2**2)) -} - - -/** - * Returns overlap area of two likelihood functions. - * - * @param {*} lk1 - First likelihood function. - * @param {*} lk2 - Second likelihood function. - * - * @returns {float} - Overlap area. - */ -function likelihood_overlap(likelihood_1, likelihood_2){ - let sum; - try{ - sum = likelihood_1.reduce((accumulator, currentValue, currentIndex) => {return accumulator + Math.min(currentValue, likelihood_2[currentIndex])}); - }catch{ - console.log("Failed to find likelihood overlap: ", likelihood_1, likelihood_2); - return 0 - } - - return sum -} - -/** - * Calculates normal distribution that is product of two given normal distributions. - * - * @param {float} m1 - Mean value of the first distribution - * @param {float} s1 - Sigma of the first distribution - * @param {float} m2 - Mean value for second distribution - * @param {float} s2 - Sigma of the second distribution - * @returns {Object} An object representing the first distribution - * @property {float} nl - Mean value of the first distribution - * @property {float} ne - Sigma of the first distribution - */ -function normal_merge(m1, s1, m2, s2){ - - if((s1 == 0) && (s2 == 0)){ - return {nl: 0.5 * (m1 + m2), ne: 0} - } - else { - return {nl: (m1 * s2 * s2 + m2 * s1 * s1) / (s1 * s1 + s2 * s2), ne: Math.sqrt(s1 * s1 * s2 * s2 / (s1 * s1 + s2 * s2))} - } -} - -/** - * Calculates likelihood for given baf - * @param {*} likelihood - * @param {*} baf - * @returns {float} likelihood value - */ -function likelihood_of_baf(likelihood, baf){ - - let bin = parseInt(baf * (likelihood.length - 1)); - let fr = baf * (likelihood.length - 1) - bin; - if(bin < likelihood.length - 1){ - return likelihood[bin] * (1 - fr) + likelihood[bin + 1] * fr - } - else { - return likelihood[bin] - } -} - -/** - * - * Calculates baf level and p-value for given likelihood function. - * - * @param {*} likelihood - * @returns {Object} An object representing BAF - * @property {float} mean BAF level (difference from 1/2) - * @property {float} p p-value for event different than 1/2 - */ -function likelihood_baf_pval(likelihood) { - const res = likelihood.length; - const max_lh = Math.max(...likelihood); - let ix = likelihood.indexOf(max_lh); - if (ix > Math.floor(res / 2)) { - ix = res - 1 - ix; - } - const b = (res / 2 - ix) / (res + 1); - - const ix1 = Math.floor((res / 2 + ix) / 2); - const ix2 = res - 1 - ix1; - let p = likelihood.slice(ix1, ix2 + 1).reduce((acc, val) => acc + val, 0) / likelihood.reduce((acc, val) => acc + val, 0); - if (ix === Math.floor(res / 2)) { - p = 1.0; - } - return {mean:b, p:p}; - } - - var combined_caller = {CombinedCaller}; - -function erf(x) { - var m = 1.0, s = 1.0, sum = x * 1.0; - for (var i = 1; i < 50; i++) { - m *= i; - s *= -1; - sum += (s * Math.pow(x, 2.0 * i + 1.0)) / (m * (2.0 * i + 1.0)); - } - return (2 * sum) / Math.sqrt(3.14159265358979) -} - -function getEValue(mean, sigma, rd, start, end) { - var arr = new DataStat(rd.slice(start, end)); - if (arr.std == 0) { - if (sigma > 0) { arr.std = (sigma * arr.mean) / mean; } - else { arr.std = 1; } - } - var p_val = t_test_1_sample(mean, arr.mean, arr.std, end - start) / (end - start); - return p_val -} - -function gaussianEValue(mean, sigma, rd, start, end) { - var arr = new DataStat(rd.slice(start, end)); - - if (arr.mean < mean) { - var x = (arr.max - arr.mean) / (sigma * Math.sqrt(2)); - return Math.pow(0.5 * (1 + erf(x)), end - start) - } - var x = (arr.min - arr.mean) / (sigma * Math.sqrt(2)); - return Math.pow(0.5 * (1 - erf(x)), end - start) -} - -function adjustToEvalue(mean, sigma, rd, start, end, pval, max_steps = 1000) { - var val = getEValue(mean, sigma, rd, start, end); - var step = 0, done = false; - while ((val > pval) & !done & (step < max_steps)) { - done = true; - step += 1; - var [v1, v2, v3, v4] = [1e10, 1e10, 1e10, 1e10]; - if (start > 0) v1 = getEValue(mean, sigma, rd, start - 1, end); - if (end - start > 2) { - var v2 = getEValue(mean, sigma, rd, start + 1, end); - var v3 = getEValue(mean, sigma, rd, start, end - 1); - } - if (end < rd.length) { var v4 = getEValue(mean, sigma, rd, start, end + 1); } - if (Math.min[(v4)] < val) { - done = false; - if (v1 == Math.min[(v4)]) { - start -= 1; - val = v1; - } - elif(v2 == Math.min[(v4)]); { - start += 1; - val = v2; - } - elif(v3 == Math.min[(v4)]); { - end -= 1; - val = v3; - } - elif(v4 == Math.min[(v4)]); { - end += 1; - val = v4; - } - } - } - if (val <= pval) { return end } - return 0; -} - -class DataStat { - constructor(data_array) { - this.data = data_array; - this.mean = data_array.reduce((acc, n) => acc + n) / data_array.length; - this.std = Math.sqrt(data_array.reduce((acc, n) => (n - this.mean) ** 2) / data_array.length); - } -} - -function t_test_1_sample(mean, m, s, n) { - if (s == 0) s = 1; - var t = ((mean - m) / s) * Math.sqrt(n); - var p = 1.0 - t_dist.TdistributionCDF(Math.abs(t), (n - 1)); - return p -} - -function t_test_2_samples(m1, s1, n1, m2, s2, n2) { - if (s1 == 0) s1 = 1; - if (s2 == 0) s2 = 1; - var t = (m1 - m2) / Math.sqrt(s1 ** 2 / n1 + s2 ** 2 / n2); - var df = ((s1 ** 2 / n1 + s2 ** 2 / n2) ** 2 * (n1 - 1) * (n2 - 1)) / - ((s1 ** 4 * (n2 - 1)) / n1 ** 2 + (s2 ** 4 * (n1 - 1)) / n2 ** 2); - - var p = 1.0 - t_dist.TdistributionCDF(Math.abs(t), parseInt(df + 0.5)); - - return p -} - -class Partition { - - constructor(rd, mean, std) { - this.rd = rd; - this.mean = mean; - this.std = std; - this.bin_bands = [2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, 64, 80, 96, 112, 128]; - } - - get_rd_signal_bandwidth(data_array) { - var new_array = []; - - data_array.forEach((value, index) => { - var tmp_value = 0; - if (value > this.mean / 4) { - tmp_value = this.mean / (this.std ** 2 * value); - } else { - tmp_value = 4 / this.std ** 2; - } - new_array.push(tmp_value); - }); - return new_array - } - - meanShiftCaller(repeats = 3) { - var ChrLevels = {}; - - Object.entries(this.rd).forEach(([chr, chr_rd]) => { - var masked = new Array(chr_rd.length).fill(false); - - // set the level - var levels = new Array(chr_rd.length); - - for (let b = 0; b < chr_rd.length; b++) { - if (!masked[b]) { levels[b] = chr_rd[b]; } - } - - this.bin_bands.forEach((bin_band, bin_band_index) => { - // not masked levels at current bin - // get boolean values - var not_masked = masked.map((value, index) => { return !value; }); - - // not masked level at current bin - var nm_levels = []; - - Object.entries(chr_rd).forEach(([k, v]) => { nm_levels.push(v.binScore); }); - - // set the mask border - var mask_borders = [0]; - var count = 0; - - for (let i = 0; i < masked.length; i++) { - if (masked[i]) { - if (count > 0) { - mask_borders.push(mask_borders[mask_borders.length - 1] + count - 1); - count = 0; - } - } else { count += 1; } - } - - mask_borders.shift(); - - // repeating steps - for (let step = 0; step < repeats; step++) { - var isig = this.get_rd_signal_bandwidth(nm_levels); - var grad = new Array(nm_levels.length).fill(0); - - for (let i = 0; i < nm_levels.length; i++) { - for (let j = i - 3 * bin_band; j <= i + 3 * bin_band + 1; j++) { - if (j < 0 || j >= nm_levels.length) continue; - if (Math.abs(i - j) >= nm_levels.length) continue; - - var g_value = (j - i) * Math.exp((-0.5 * (j - i) ** 2) / bin_band ** 2) * - Math.exp(-0.5 * (nm_levels[i] - nm_levels[j]) ** 2 * isig[i]); - - grad[i] += g_value; - } - } - - // get the border - var border = new Array(); - for (var i = 0; i < grad.length - 1; i++) { - if ((grad[i] < 0) & (grad[i + 1] >= 0)) border.push(i); - } - - border.push(grad.length - 1); - border = border.concat(mask_borders).sort((a, b) => a - b); - border = Array.from(new Set(border)); - - var pb = 0; - for (var i = 0; i < border.length; i++) { - var range_array = nm_levels.slice(pb, border[i] + 1); - var range_mean = range_array.reduce((acc, n) => acc + n) / range_array.length; - - nm_levels.fill(range_mean, pb, border[i] + 1); - pb = border[i] + 1; - } - } - - for (var i = 0, j = 0; i < levels.length; i++) { - if (not_masked[i]) { - levels[i] = nm_levels[j]; - j++; - } - } - - //get the border - var border = new Array(); - for (var i = 0; i < levels.length - 1; i++) { - //if(i == levels.length -1) continue; - var diff = Math.abs(levels[i + 1] - levels[i]); - - if (diff > 0.01) border.push(i + 1); - } - - border.unshift(0); - border.push(levels.length); - - // reset the mask - masked = new Array(this.rd.length).fill(false); - - // check the borders - for (var i = 1; i < border.length; i++) { - var seg = [border[i - 1], border[i]]; - var seg_left = [border[i - 1], border[i - 1]]; - if (i > 1) { seg_left[0] = border[i - 2]; } else continue; - - var seg_right = [border[i], border[i]]; - if (i < border.length - 1) { seg_right[1] = border[i + 1]; } else continue; - - var n = seg[1] - seg[0]; - var n_left = seg_left[1] - seg_left[0]; - var n_right = seg_right[1] - seg_right[0]; - if (n <= 1) continue; - var seg_array = new DataStat(levels.slice(seg[0], seg[1])); - - if (n_right <= 15 || n_left <= 15 || n <= 15) { - var ns = 1.8 * Math.sqrt(levels[seg_left[0]] / this.mean) * this.std; - if (Math.abs(levels[seg_left[0]] - levels[seg[0]]) < ns) { continue } - - ns = 1.8 * Math.sqrt(levels[seg_right[0]] / this.mean) * this.std; - if (Math.abs(levels[seg_right[0]] - levels[seg[0]]) < ns) { continue } - } else { - var seg_left_array = levels.slice(seg_left[0], seg_left[1]); - var seg_left_1 = new DataStat(seg_left_array); - - var seg_right_array = levels.slice(seg_right[0], seg_right[1]); - var seg_right_1 = new DataStat(seg_right_array); - - var ttest_2sample_1 = t_test_2_samples(seg_array.mean, seg_array.std, seg_array.data.length, - seg_left_1.mean, seg_left_1.std, seg_left_1.data.length); - if (ttest_2sample_1 > (0.01 / genome_size) * bin_size * (n + n_left)) { continue } - - var ttest_2sample_2 = t_test_2_samples(seg_array.mean, seg_array.std, seg_array.data.length, - seg_right_1.mean, seg_right_1.std, seg_right_1.data.length); - if (ttest_2sample_2 > (0.01 / genome_size) * bin_size * (n + n_right)) { continue } - } - - var ttest_1sample_1 = t_test_1_sample(this.mean, seg_array.mean, seg_array.std, seg_array.data.length); - if (ttest_1sample_1 > 0.05) { continue } - let segments_rd = nm_levels.slice(seg[0], seg[1]); - var raw_seg_data = new DataStat(segments_rd); - - masked.fill(true, seg[0], seg[1]); - levels.fill(raw_seg_data.mean, seg[0], seg[1]); - } - }); - - ChrLevels[chr] = levels; - - }); - return ChrLevels - } - call_mean_shift(repeats = 3) { - const bin_size = 1000; - // const genome_size = bin_size * this.rd.length; - const genome_size = 2871000000; - var masked = new Array(this.rd.length).fill(false); - - // set the level - var levels = new Array(this.rd.length); - for (var b = 0; b < this.rd.length; b++) { - if (!masked[b]) { - levels[b] = this.rd[b]; - } - } - this.bin_bands.forEach((bin_band, bin_band_index) => { - // not masked levels at current bin - // get boolean values - var not_masked = masked.map((value, index) => { - return !value; - }); - - // not masked level at current bin - // var nm_levels = not_masked.map((value, index) => {if(value) return this.rd[index]}); - var nm_levels = []; - not_masked.forEach((value, index) => { - if (value) nm_levels.push(this.rd[index]); - }); - - // console.log(bin_band, nm_levels); - - // set the mask border - var mask_borders = [0]; - var count = 0; - - for (var i = 0; i < masked.length; i++) { - if (masked[i]) { - if (count > 0) { - mask_borders.push( - mask_borders[mask_borders.length - 1] + count - 1, - ); - count = 0; - } - } else { - count += 1; - } - } - - mask_borders.shift(); - // repeating steps - for (var step = 0; step < repeats; step++) { - var isig = this.get_rd_signal_bandwidth(nm_levels); - // console.log(isig); - var grad = new Array(nm_levels.length).fill(0); - - for (var i = 0; i < nm_levels.length; i++) { - for (var j = i - 3 * bin_band; j <= i + 3 * bin_band + 1; j++) { - if (j < 0 || j >= nm_levels.length) continue; - if (Math.abs(i - j) >= nm_levels.length) continue; - - var g_value = - (j - i) * - Math.exp((-0.5 * (j - i) ** 2) / bin_band ** 2) * - Math.exp(-0.5 * (nm_levels[i] - nm_levels[j]) ** 2 * isig[i]); - // console.log(g_value); - grad[i] += g_value; - } - } - // console.log(grad); - - // get the border - var border = new Array(); - for (var i = 0; i < grad.length - 1; i++) { - if ((grad[i] < 0) & (grad[i + 1] >= 0)) border.push(i); - } - - border.push(grad.length - 1); - border = border.concat(mask_borders).sort((a, b) => a - b); - border = Array.from(new Set(border)); - - var pb = 0; - for (var i = 0; i < border.length; i++) { - var range_array = nm_levels.slice(pb, border[i] + 1); - var range_mean = - range_array.reduce((acc, n) => acc + n) / range_array.length; - - nm_levels.fill(range_mean, pb, border[i] + 1); - pb = border[i] + 1; - } - } - - for (var i = 0, j = 0; i < levels.length; i++) { - if (not_masked[i]) { - levels[i] = nm_levels[j]; - j++; - } - } - - //get the border - var border = new Array(); - for (var i = 0; i < levels.length - 1; i++) { - //if(i == levels.length -1) continue; - var diff = Math.abs(levels[i + 1] - levels[i]); - - if (diff > 0.01) border.push(i + 1); - } - - border.unshift(0); - border.push(levels.length); - - // reset the mask - masked = new Array(this.rd.length).fill(false); - - // check the borders - for (var i = 1; i < border.length; i++) { - var seg = [border[i - 1], border[i]]; - var seg_left = [border[i - 1], border[i - 1]]; - if (i > 1) { - seg_left[0] = border[i - 2]; - } else continue; - - var seg_right = [border[i], border[i]]; - if (i < border.length - 1) { - seg_right[1] = border[i + 1]; - } else continue; - - var n = seg[1] - seg[0]; - var n_left = seg_left[1] - seg_left[0]; - var n_right = seg_right[1] - seg_right[0]; - if (n <= 1) continue; - var seg_array = new DataStat(levels.slice(seg[0], seg[1])); - - if (n_right <= 15 || n_left <= 15 || n <= 15) { - var ns = 1.8 * Math.sqrt(levels[seg_left[0]] / this.mean) * this.std; - if (Math.abs(levels[seg_left[0]] - levels[seg[0]]) < ns) { - continue; - } - - ns = 1.8 * Math.sqrt(levels[seg_right[0]] / this.mean) * this.std; - if (Math.abs(levels[seg_right[0]] - levels[seg[0]]) < ns) { - continue; - } - } else { - var seg_left_array = levels.slice(seg_left[0], seg_left[1]); - var seg_left_1 = new DataStat(seg_left_array); - - var seg_right_array = levels.slice(seg_right[0], seg_right[1]); - var seg_right_1 = new DataStat(seg_right_array); - - var ttest_2sample_1 = t_test_2_samples( - seg_array.mean, - seg_array.std, - seg_array.data.length, - seg_left_1.mean, - seg_left_1.std, - seg_left_1.data.length, - ); - if ( - ttest_2sample_1 > - (0.01 / genome_size) * bin_size * (n + n_left) - ) { - continue; - } - - var ttest_2sample_2 = t_test_2_samples( - seg_array.mean, - seg_array.std, - seg_array.data.length, - seg_right_1.mean, - seg_right_1.std, - seg_right_1.data.length, - ); - if ( - ttest_2sample_2 > - (0.01 / genome_size) * bin_size * (n + n_right) - ) { - continue; - } - } - - var ttest_1sample_1 = t_test_1_sample( - this.mean, - seg_array.mean, - seg_array.std, - seg_array.data.length, - ); - if (ttest_1sample_1 > 0.05) { - continue; - } - var raw_seg_data = new DataStat(this.rd.slice(seg[0], seg[1])); - - masked.fill(true, seg[0], seg[1]); - levels.fill(raw_seg_data.mean, seg[0], seg[1]); - } - }); - return levels; - } - - cnv_calling(bin_size = 100000) { - var delta = 0.25; - var delta = delta * this.mean; - - var min = this.mean - delta, max = this.mean + delta; - // console.log('min: ', min, ', Max: ', max) - - // console.log('delta', delta) - var normal_genome_size = 2971000000; - - var levels = this.meanShiftCaller(); - - - var merged_level = {}; - var cnv_levels = []; - // var t_value = cdf(Math.abs(10), (5)) - // console.log('Testing student t test:', t_value) - - Object.entries(levels).forEach(([chr, chr_levels]) => { - - var done = false; - while (!done) { - done = true; - - // - // get the borders - // - var borders = new Array(1).fill(0); - for (let i = 0; i < chr_levels.length - 1; i++) { - var diff = Math.abs(chr_levels[i + 1] - chr_levels[i]); - if (diff > 0.01) borders.push(i + 1); - } - borders.push(chr_levels.length); - - for (let ix = 0; ix < borders.length - 2; ix++) { - var v1 = Math.abs(chr_levels[borders[ix]] - chr_levels[borders[ix + 1]]); - // console.log(ix, v1); - if (v1 < delta) { - var v2 = v1 + 1, v3 = v1 + 1; - - if (ix > 0) { v2 = Math.abs(chr_levels[borders[ix]] - chr_levels[borders[ix - 1]]); } - if (ix < borders.length - 3) { v3 = Math.abs(levels[borders[ix + 1]] - chr_levels[borders[ix + 2]]); } - - if (v1 < v2 && v1 < v3) { - done = false; - - var tmp_array = new DataStat(chr_levels.slice(borders[ix], borders[ix + 2])); - chr_levels.fill(tmp_array.mean, borders[ix], borders[ix + 2]); - borders.splice(ix + 1, ix + 1); - } - } - } - } - // console.log('updated levels', chr_levels) - - // var chr_rd = this.rd[chr] - var chr_rd = []; - Object.entries(this.rd[chr]).forEach(([bin, binDict]) => { chr_rd.push(binDict.binScore); }); - // console.log('cnv_calling', chr_rd) - - // - // Calling Segments - // - - //var flags = [""] * levels.length; - var flags = new Array(chr_levels.length).fill(""); - - // console.log('default levels', chr, chr_levels) - var b = 0; - var pval = (0.05 * bin_size) / normal_genome_size; - while (b < chr_levels.length) { - var b0 = b, border_start = b; - while ((b < chr_levels.length) & (chr_levels[b] < min)) { - b += 1; - } - var border_end = b; - - if (border_end > border_start + 1) { - // console.log('border min', border_start, border_end) - var adj = adjustToEvalue(this.mean, this.std, chr_rd, border_start, border_end, pval); - // console.log(adj) - if (adj) { - var border_start, border_end = adj; - flags.fill("D", border_start, border_end); - } - } - border_start = b; - while ((b < chr_levels.length) & (chr_levels[b] > max)) { b += 1; } - border_end = b; - - if (border_end > border_start + 1) { - adj = adjustToEvalue(this.mean, this.std, chr_rd, border_start, border_end, pval); - // console.log(adj) - if (adj) { - (border_end = adj); - // flags[bs:be] = ["A"] * (be - bs) - flags.fill("A", border_start, border_end); - } - } - if (b == b0) b += 1; - } - - //console.log(chr, 'segments', segments) - // - // Calling additional deletions - // - b = 0; - while (b < chr_levels.length) { - while ((b < chr_levels.length) & (flags[b] != "")) b += 1; - border_start = b; - while ((b < chr_levels.length) & (chr_levels[b] < min)) b += 1; - border_end = b; - if (border_end > border_start + 1) { - if (gaussianEValue(this.mean, this.std, chr_rd, border_start, border_end) < 0.05 / normal_genome_size) { - flags.fill(["d"] * (border_end - border_start), border_start, border_end); - } - b -= 1; - } - b += 1; - } - - b = 0; - var cf; - if (b < chr_levels.length) cf = flags[b]; - - border_start = 0; - - //var merge = [...this.rd] - var merge = [...chr_rd]; - // console.log('initial merge', merge) - while (b < chr_levels.length) { - while (flags[b] == cf) { - b += 1; - if (b >= flags.length) break; - } - if (b > border_start) { - var merge_arr = new DataStat(merge.slice(border_start, b)); - merge.fill(merge_arr.mean, border_start, b); - } - if (b < chr_levels.length) cf = flags[b]; - border_start = b; - } - - merged_level[chr] = merge; - - - // - // calculate calls - // - b = 0; - while (b < chr_levels.length) { - cf = flags[b]; - if (cf == "") { - b += 1; - continue - } - border_start = b; - while (b < chr_levels.length & cf == flags[b]) { b += 1; } - var border_arr = new DataStat(merge.slice(border_start, b)); - let cnv = border_arr.mean / this.mean; - let event_type; - if (cf == "D") { - event_type = "deletion"; - } else { - event_type = "duplication"; - } - let cnv_dict = { - chr: chr, - start: bin_size * border_start + 1, - end: bin_size * b, - size: bin_size * (b - border_start + 1), - value: cnv * 2, - event_type: event_type - }; - cnv_levels.push(cnv_dict); - - } - }); - - return [merged_level, cnv_levels] - } -} - - - -var read_depth_caller = { Partition }; - -class CNVpytorVCF { - constructor(allVariants, binSize) { - this.allVariants = allVariants; - this.rowBinSize = 10000; - this.binSize = binSize; - this.binFactor = binSize / this.rowBinSize; - - } - - async computeDepthFeatures() { - - const chromosomes = Object.keys(this.allVariants); - const wigFeatures = []; - - for (let chr of chromosomes) { - const variants = this.allVariants[chr]; - if (variants.length === 0) continue - - const firstSnp = variants[0]; - - let sum = 0; - let count = 0; - let binStart = firstSnp.start = firstSnp.start % this.binSize; // Place start at integer multiple of binSize - let binEnd = binStart + this.binSize; - let featureBin = 0; - - for (let snp of variants) { - const position = snp.start + 1; // Convert from 0-base to 1-base coords - featureBin = Math.max(Math.floor((snp.start - 1) / this.binSize), 0); - if (position > binEnd) { - - if (count > 0) { - wigFeatures.push({ chr, start: binStart, end: binEnd, value: sum, bin: featureBin, count: count }); - } - - // Start new bin - sum = 0; - //count = 0 - binStart = snp.start - snp.start % this.binSize; - binEnd = binStart + this.binSize; - } - - const dpValue = snp.calls[9].info["DP"]; - // const dpValue = snp.getInfo("DP") - - if (dpValue) { - sum += Number.parseInt(dpValue); - count++; - } - } - - // final bin - if (count > 0) { - wigFeatures.push({ chr, start: binStart, end: binEnd, value: sum, bin: featureBin, count: count }); - } - } - - return wigFeatures - } - - // for for read depth calculation - async computeReadDepth() { - const chromosomes = Object.keys(this.allVariants); - var wigFeatures = {}; - - for (let chr of chromosomes) { - const variants = this.allVariants[chr]; - var featureBin; - if (variants.length === 0) continue - for (let snp of variants) { - featureBin = Math.max(Math.floor(snp.start / this.rowBinSize), 0); - if (!wigFeatures[chr]) { wigFeatures[chr] = []; } - if (!wigFeatures[chr][featureBin]) { - - wigFeatures[chr][featureBin] = { - chr, - start: featureBin * this.rowBinSize, - end: (featureBin + 1) * this.rowBinSize, - value: 0, - sum_score: 0, - count: 0, - }; - } - const dpValue = snp.calls[9].info["DP"]; - if (dpValue) { - // sum += Number.parseInt(dpValue) - wigFeatures[chr][featureBin].sum_score += Number.parseInt(dpValue); - wigFeatures[chr][featureBin].count++; - } - - } - // for last bin - //let last_bin = wigFeatures[chr][featureBin] - //last_bin.value = parseInt(last_bin.sum_score / last_bin.count) * 100 - } - - // adjust the bin values to actual bin size - var avgbin = {}; - for (let chr of chromosomes) { - if (!avgbin[chr]) { avgbin[chr] = []; } - for (let k = 0; k < wigFeatures[chr].length / this.binFactor; k++) { - const featureBin = k; - if (!avgbin[chr][k]) { - avgbin[chr][k] = { - chr, - binScore: 0, - start: featureBin * this.binSize, - end: (featureBin + 1) * this.binSize, - }; - } - - for (var j = k * 10; j < 10 * k + 10; j++) { - if (wigFeatures[chr][j]) { - var tmp_score = parseInt(wigFeatures[chr][j].sum_score / wigFeatures[chr][j].count) * 100; - avgbin[chr][k].binScore += tmp_score; - } - } - } - } - - var finalFeatureSet = this.readDepthMeanshift(avgbin); - return finalFeatureSet - - } - readDepthMeanshift(wigFeatures) { - - // Get global mean and standrad deviation - var fit_info = new g_utils.GetFit(wigFeatures); - var [globamMean, globalStd] = fit_info.fit_data(); - - // Apply partition method - var partition = new read_depth_caller.Partition(wigFeatures, globamMean, globalStd); - var partition_array = partition.meanShiftCaller(); - var caller_array = partition.cnv_calling(); - - // Assign the partition values to each bin - Object.entries(wigFeatures).forEach(([chr, chr_rd]) => { - chr_rd.forEach((bin, index) => { - bin.partition_level = parseInt(partition_array[chr][index]); - bin.partition_call = parseInt(caller_array[0][chr][index]); - }); - }); - - var rawbinScore = this.formatDataStructure(wigFeatures, 'binScore', globamMean); - var partition_levels = this.formatDataStructure(wigFeatures, 'partition_level', globamMean); - var partition_call = this.formatDataStructure(wigFeatures, 'partition_call', globamMean); - - return [rawbinScore, partition_levels, partition_call, caller_array[1]] - - } - formatDataStructure(wigFeatures, feature_column, scaling_factor = 1) { - const results = []; - for (const [chr, wig] of Object.entries(wigFeatures)) { - - wig.forEach(sample => { - var new_sample = { ...sample }; - if (scaling_factor != 1) { - new_sample.value = sample[feature_column] / scaling_factor * 2; - } - results.push(new_sample); - }); - } - - return results - } - - async computeBAF_v2() { - - const chromosomes = Object.keys(this.allVariants); - const wigFeatures = {}; - const baf1 = [], baf2 = []; - - for (let chr of chromosomes) { - const variants = this.allVariants[chr]; - if (variants.length === 0) continue - var featureBin; - for (let snp of variants) { - featureBin = Math.max(Math.floor(snp.start / this.binSize), 0); - - if (!wigFeatures[chr]) { - wigFeatures[chr] = []; - } - if (!wigFeatures[chr][featureBin]) { - if (featureBin > 0) { - // calculating the BAF likelihood for previous bin - let previous_featureBin = featureBin - 1; - if (wigFeatures[chr][previous_featureBin]) { - - const updated_bin = this.get_max_min_score(wigFeatures[chr][previous_featureBin]); - - if (updated_bin.value != 0.5) { - let baf_wig = Object.assign({}, updated_bin); - baf_wig.value = -2 * (1 - updated_bin.value); - baf2.push(baf_wig); - } - updated_bin.value = - 2 * updated_bin.value; - wigFeatures[chr][previous_featureBin] = updated_bin; - - baf1.push(wigFeatures[chr][previous_featureBin]); - - } - } - wigFeatures[chr][featureBin] = { - chr, - start: featureBin * this.binSize, - end: (featureBin + 1) * this.binSize, - value: 0, - count: 0, - likelihood_score: [], - min_score: 0, - }; - } - const calls = snp.calls[9]; - let genotype = calls.genotype; - let ad_score = calls.info["AD"].split(','); - let ad_a = ad_score[0], ad_b = ad_score[1]; - - if ((genotype[0] == 0 && genotype[1] == 1) || (genotype[0] == 1 && genotype[1] == 0)) { - //apply the beta function - if (wigFeatures[chr][featureBin].likelihood_score.length == 0) { - wigFeatures[chr][featureBin].likelihood_score = g_utils.linspace(0, 1, 100).map((value, index) => { - return beta(ad_a, ad_b, value); - }); - } else { - var sum = 0; - - wigFeatures[chr][featureBin].likelihood_score = g_utils.linspace(0, 1, 100).map((value, index) => { - var likelihood_value = wigFeatures[chr][featureBin].likelihood_score[index] * beta(ad_a, ad_b, value); - sum = sum + likelihood_value; - return likelihood_value; - }); - - wigFeatures[chr][featureBin].likelihood_score = g_utils.linspace(0, 1, 100).map((value, index) => { - return wigFeatures[chr][featureBin].likelihood_score[index] / sum; - }); - } - wigFeatures[chr][featureBin].count++; - } - } - - // last feature bin - const updated_bin = this.get_max_min_score(wigFeatures[chr][featureBin]); - - if (updated_bin.value != 0.5) { - let baf_wig = Object.assign({}, updated_bin); - baf_wig.value = -2 * (1 - updated_bin.value); - baf2.push(baf_wig); - } - updated_bin.value = -2 * updated_bin.value; - wigFeatures[chr][featureBin] = updated_bin; - baf1.push(wigFeatures[chr][featureBin]); - } - - return [baf1, baf2] - - } - - - format_BAF_likelihood(wigFeatures) { - const results = []; - - for (const [chr, wig] of Object.entries(wigFeatures)) { - wig.forEach(sample => { - var new_sample = { ...sample }; - if (sample.value != 0.5) { - new_sample.value = 1 - sample.value; - results.push(new_sample); - } - }); - } - return results - } - - get_max_min_score(sample) { - - if (sample.likelihood_score.length > 0) { - const max = Math.max(...sample.likelihood_score); - const res = sample.likelihood_score.indexOf(max); - sample.value = Math.max(res / 100, 1 - res / 100); - sample.min_score = Math.min(res / 100, 1 - res / 100); - - } else { - sample.score = 0; - } - - return sample - } - - async getAllbins() { - const bins = await this.computeDepthFeatures(); - - //console.log('getAllbins', bins["value"]) - - const fitter = new g_utils.GetFit(bins); - - fitter.fit_data(); - // dconsole.log('rd list', distParams) - - return bins - } - - async read_rd_baf(caller='ReadDepth'){ - - const chromosomes = Object.keys(this.allVariants); - var wigFeatures = {}; - - for (let chr of chromosomes) { - const variants = this.allVariants[chr]; - var featureBin; - if (variants.length === 0) continue - for (let snp of variants) { - featureBin = Math.max(Math.floor(snp.start / this.rowBinSize), 0); - if (!wigFeatures[chr]) { wigFeatures[chr] = []; } - if (!wigFeatures[chr][featureBin]) { - - wigFeatures[chr][featureBin] = { - chr, - start: featureBin * this.rowBinSize, - end: (featureBin + 1) * this.rowBinSize, - // value: 0, - dp_sum_score: 0, - dp_count: 0, - hets_count:0, - hets: [], - //likelihood_score: [], - }; - } - const calls = snp.calls[9]; - const dpValue = calls.info["DP"]; - if (dpValue) { - - wigFeatures[chr][featureBin].dp_sum_score += Number.parseInt(dpValue); - wigFeatures[chr][featureBin].dp_count++; - } - - let ad_score = calls.info["AD"].split(','); - let genotype = calls.genotype; - if ((genotype[0] == 0 && genotype[1] == 1) || (genotype[0] == 1 && genotype[1] == 0)) { - //apply the beta function - wigFeatures[chr][featureBin].hets_count++; - let ad_a = parseInt(ad_score[0]), ad_b = parseInt(ad_score[1]); - wigFeatures[chr][featureBin].hets.push({ref:ad_a, alt:ad_b}); - } - - } - - } - - var avgbin = this.adjust_bin_size(wigFeatures); - var finalFeatureSet; - if(caller == 'ReadDepth'){ - finalFeatureSet = this.readDepthMeanshift(avgbin); - var baf = this.formatDataStructure_BAF(avgbin, 'max_likelihood'); - }else if(caller=='2D'){ - - let caller_obj = new combined_caller.CombinedCaller(avgbin, this.binSize); - let processed_bins = await caller_obj.call_2d(); - - finalFeatureSet = [processed_bins.binScore, [], processed_bins.segment_score]; - - var baf = caller_obj.formatDataStructure_BAF('max_likelihood'); - } - - - return [finalFeatureSet, baf] - } - - formatDataStructure_BAF(wigFeatures, feature_column, scaling_factor = 2) { - const baf1 = []; - const baf2 = []; - for (const [chr, wig] of Object.entries(wigFeatures)) { - - wig.forEach(sample => { - delete sample.likelihood_score; - var baf1_value = { ...sample }; - var baf2_value = { ...sample }; - - let value = sample[feature_column]; - if (value != 0.5){ - baf2_value.value = -2 * (1 - value); - baf2.push(baf2_value); - } - baf1_value.value = -2 * value; - baf1.push(baf1_value); - - }); - } - - - return [baf1, baf2] - } - - adjust_bin_size(wigFeatures){ - const chromosomes = Object.keys(this.allVariants); - // adjust the bin values to actual bin size - var avgbin = {}; - for (let chr of chromosomes) { - if (!avgbin[chr]) { avgbin[chr] = []; } - for (let k = 0; k < wigFeatures[chr].length / this.binFactor; k++) { - const featureBin = k; - if (!avgbin[chr][k]) { - avgbin[chr][k] = { - chr, - start: featureBin * this.binSize, - end: (featureBin + 1) * this.binSize, - dp_count: 0, - hets_count: 0, - binScore: 0, - likelihood_score: [], - }; - } - - for (var j = k * 10; j < 10 * k + 10; j++) { - - if (wigFeatures[chr][j]) { - var tmp_score = parseInt(wigFeatures[chr][j].dp_sum_score / wigFeatures[chr][j].dp_count) * 100; - avgbin[chr][k].binScore += tmp_score; - avgbin[chr][k].dp_count += wigFeatures[chr][j].dp_count; - avgbin[chr][k].hets_count += wigFeatures[chr][j].hets_count; - - if (wigFeatures[chr][j].hets.length != 0){ - - - wigFeatures[chr][j].hets.forEach((hets, hets_idx) => { - if(avgbin[chr][k].likelihood_score.length == 0){ - avgbin[chr][k].likelihood_score = g_utils.linspace(0, 1, 100).map((value, index) => { - return beta(hets.ref, hets.alt, value); - }); - } - else { - var likelihood_sum = 0; - avgbin[chr][k].likelihood_score = g_utils.linspace(0, 1, 100).map((value, index) => { - var likelihood_value = avgbin[chr][k].likelihood_score[index] * beta(hets.ref, hets.alt, value); - likelihood_sum += likelihood_value; - return likelihood_value; - }); - - avgbin[chr][k].likelihood_score = g_utils.linspace(0, 1, 100).map((value, index) => { - return avgbin[chr][k].likelihood_score[index] / likelihood_sum; - }); - - } - }); - - // avgbin[chr][k].likelihood_score *= wigFeatures[chr][j].likelihood_score - } - } - } - - const updated_bin = this.get_max_min_score(avgbin[chr][k]); - avgbin[chr][k].max_likelihood = updated_bin.value; - } - } - return avgbin - } - -} - -function beta(a, b, p, phased = true) { - return p ** a * (1 - p) ** b + p ** b * (1 - p) ** a; -} - -/* -* The MIT License (MIT) -* -* Copyright (c) 2016-2017 The Regents of the University of California -* Author: Arijit Panda -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -*/ - - -/** - * Represents 2 or more wig tracks overlaid on a common viewport. - */ - -const DEFAULT_TRACK_HEIGHT = 250; - -class CNVPytorTrack extends TrackBase { - - constructor(config, browser) { - super(config, browser); - this.featureType = 'numeric'; - this.paintAxis = paintAxis; - - if (!config.max) { - this.defaultScale = true; - this.autoscale = false; - } - - // Invoke height setter last to allocated to coverage and alignment tracks - this.height = (config.height !== undefined ? config.height : DEFAULT_TRACK_HEIGHT); - } - - async init(config) { - - this.type = "cnvpytor"; - this.graphType = config.graphType || "points"; - this.bin_size = config.bin_size || 100000; - this.signal_name = config.signal_name || "rd_snp"; - this.cnv_caller = config.cnv_caller || '2D'; - this.colors = config.colors || ['gray', 'black', 'green', 'blue']; - super.init(config); - - } - - get supportsWholeGenome() { - return true - } - - get_signals() { - let signals = []; - - if (this.signal_name == 'rd_snp') { - signals = ["RD_Raw", "RD_Raw_gc_coor", this.cnv_caller, "BAF1", "BAF2"]; - - } else if (this.signal_name == 'rd') { - signals = ["RD_Raw", "RD_Raw_gc_coor", this.cnv_caller]; - - } else if (this.signal_name == 'snp') { - signals = ["BAF1", "BAF2"]; - - } else if (this.signal_name == 'cnh') { - signals = [this.cnv_caller]; - } - return signals - } - - get_signal_colors() { - - let signal_colors = [ - { singal_name: 'RD_Raw', color: this.colors[0] }, - { singal_name: 'RD_Raw_gc_coor', color: this.colors[1] }, - { singal_name: 'ReadDepth', color: this.colors[2] }, - { singal_name: '2D', color: this.colors[2] }, - { singal_name: 'BAF1', color: this.colors[3] }, - { singal_name: 'BAF2', color: this.colors[3] }, - ]; - return signal_colors - } - - async postInit() { - - if (this.config.format == 'vcf') { - this.featureSource = FeatureSource(this.config, this.browser.genome); - this.header = await this.getHeader(); - - - var allVariants = this.featureSource.reader.features.reduce(function (r, a) { - r[a.chr] = r[a.chr] || []; - r[a.chr].push(a); - return r - }, Object.create(null)); - - const cnvpytor_obj = new CNVpytorVCF(allVariants, this.bin_size); - - let wigFeatures; - let bafFeatures; - this.wigFeatures_obj = {}; - this.wigFeatures_obj[this.bin_size] = {}; - - let dataWigs; - if(this.config.cnv_caller == '2D'){ - - dataWigs = await cnvpytor_obj.read_rd_baf('2D'); - - wigFeatures = dataWigs[0]; - bafFeatures = dataWigs[1]; - this.wigFeatures_obj[this.bin_size]['2D'] = wigFeatures[2]; - - this.available_callers = ['2D']; - }else { - dataWigs = await cnvpytor_obj.read_rd_baf(); - wigFeatures = dataWigs[0]; - bafFeatures = dataWigs[1]; - this.wigFeatures_obj[this.bin_size]['ReadDepth'] = wigFeatures[2]; - this.available_callers = ['ReadDepth']; - } - - this.wigFeatures_obj[this.bin_size]['RD_Raw'] = wigFeatures[0]; - this.wigFeatures_obj[this.bin_size]['RD_Raw_gc_coor'] = wigFeatures[1]; - this.wigFeatures_obj[this.bin_size]['BAF1'] = bafFeatures[0]; - this.wigFeatures_obj[this.bin_size]['BAF2'] = bafFeatures[1]; - - this.available_bins = [this.bin_size]; - - this.set_available_callers(); - - } else { - this.cnvpytor_obj = new HDF5Reader(this.config.url, this.bin_size); - this.wigFeatures_obj = await this.cnvpytor_obj.get_rd_signal(this.bin_size); - this.available_bins = this.cnvpytor_obj.available_bins; - this.available_callers = this.cnvpytor_obj.callers; - this.set_available_callers(); - } - - this.tracks = []; - const p = []; - - this.signals = this.get_signals(); - this.signal_colors = this.get_signal_colors(); - - for (let bin_size in this.wigFeatures_obj) { - - for (const [signal_name, wig] of Object.entries(this.wigFeatures_obj[bin_size])) { - - if (this.signals.includes(signal_name)) { - let tconf = {}; - tconf.type = "wig"; - tconf.isMergedTrack = true; - tconf.features = wig; - tconf.name = signal_name; - tconf.color = this.signal_colors.filter(x => x.singal_name === signal_name).map(x => x.color); - const t = await this.browser.createTrack(tconf); - if (t) { - t.autoscale = false; // Scaling done from merged track - this.tracks.push(t); - } else { - console.warn("Could not create track " + tconf); - } - - if (typeof t.postInit === 'function') { - p.push(t.postInit()); - } - } - } - - } - - - this.flipAxis = this.config.flipAxis ? this.config.flipAxis : false; - this.logScale = this.config.logScale ? this.config.logScale : false; - this.autoscale = this.config.autoscale; - if (!this.autoscale) { - this.dataRange = { - min: this.config.min || 0, - max: this.config.max - }; - } - for (let t of this.tracks) { - t.autoscale = false; - t.dataRange = this.dataRange; - } - - return Promise.all(p) - } - - set_available_callers() { - if (!this.available_callers.includes(this.cnv_caller)) { - if (this.available_callers.length > 0) { - this.cnv_caller = this.available_callers[0]; - } else { - this.cnv_caller = null; - } - } - } - - async getHeader() { - - if (!this.header) { - if (typeof this.featureSource.getHeader === "function") { - const header = await this.featureSource.getHeader(); - if (header) { - this.callSets = header.callSets || []; - } - this.header = header; - } - this.sampleNames = this.callSets ? this.callSets.map(cs => cs.name) : []; - } - - return this.header - } - - get height() { - return this._height - } - - set height(h) { - this._height = h; - if (this.tracks) { - for (let t of this.tracks) { - t.height = h; - t.config.height = h; - } - } - } - - menuItemList() { - let items = []; - - if (this.flipAxis !== undefined) { - items.push({ - label: "Flip y-axis", - click: () => { - this.flipAxis = !this.flipAxis; - this.trackView.repaintViews(); - } - }); - } - - items = items.concat(MenuUtils$1.numericDataMenuItems(this.trackView)); - - items.push('
'); - items.push("Bin Sizes"); - for (let rd_bin of this.available_bins) { - const checkBox = createCheckbox$2(rd_bin, rd_bin === this.bin_size); - items.push({ - object: $$1(checkBox), - click: async () => { - this.bin_size = rd_bin; - - await this.recreate_tracks(rd_bin); - this.clearCachedFeatures(); - this.trackView.updateViews(); - this.trackView.repaintViews(); - } - }); - } - items.push('
'); - items.push("Signal Type"); - - let signal_dct = {"rd_snp": "RD and BAF Likelihood", "rd": "RD Signal", "snp": "BAF Likelihood"}; - for (let signal_name in signal_dct) { - const checkBox = createCheckbox$2(signal_dct[signal_name], signal_name === this.signal_name); - items.push({ - object: $$1(checkBox), - click: async () => { - this.signal_name = signal_name; - await this.recreate_tracks(this.bin_size); - this.clearCachedFeatures(); - this.trackView.updateViews(); - this.trackView.repaintViews(); - - } - }); - } - - // cnv caller setting - items.push('
'); - items.push("CNV caller"); - for (let cnv_caller of this.available_callers) { - const checkBox = createCheckbox$2(cnv_caller, cnv_caller === this.cnv_caller); - items.push({ - object: $$1(checkBox), - click: async () => { - this.cnv_caller = cnv_caller; - await this.recreate_tracks(this.bin_size); - this.clearCachedFeatures(); - this.trackView.updateViews(); - this.trackView.repaintViews(); - } - }); - } - - return items - } - - async recreate_tracks(bin_size) { - this.tracks = []; - const p = []; - - if (!(bin_size in this.wigFeatures_obj)) { - this.wigFeatures_obj = {...this.wigFeatures_obj, ...await this.cnvpytor_obj.get_rd_signal(bin_size)}; - } - - this.signals = this.get_signals(); - this.signal_colors = this.get_signal_colors(); - - for (const [signal_name, wig] of Object.entries(this.wigFeatures_obj[bin_size])) { - if (this.signals.includes(signal_name)) { - let tconf = {}; - tconf.type = "wig"; - tconf.isMergedTrack = true; - tconf.features = wig; - tconf.name = signal_name; - tconf.color = this.signal_colors.filter(x => x.singal_name === signal_name).map(x => x.color); - const t = await this.browser.createTrack(tconf); - if (t) { - t.autoscale = false; // Scaling done from merged track - this.tracks.push(t); - } else { - console.warn("Could not create track " + tconf); - } - - if (typeof t.postInit === 'function') { - p.push(t.postInit()); - } - } - - } - - - this.flipAxis = this.config.flipAxis ? this.config.flipAxis : false; - this.logScale = this.config.logScale ? this.config.logScale : false; - this.autoscale = this.config.autoscale; - if (!this.autoscale) { - this.dataRange = { - min: this.config.min || 0, - max: this.config.max - }; - } - for (let t of this.tracks) { - t.autoscale = false; - t.dataRange = this.dataRange; - } - return Promise.all(p) - } - - async getFeatures(chr, bpStart, bpEnd, bpPerPixel) { - - if(this.tracks) { - const promises = this.tracks.map((t) => t.getFeatures(chr, bpStart, bpEnd, bpPerPixel)); - return Promise.all(promises) - } else { - return undefined // This can happen if a redraw is triggered before the track has initialized. - } - } - - // TODO: refactor to igvUtils.js - getScaleFactor(min, max, height, logScale) { - const scale = logScale ? height / (Math.log10(max + 1) - (min <= 0 ? 0 : Math.log10(min + 1))) : height / (max - min); - return scale - } - - computeYPixelValue(yValue, yScaleFactor) { - return (this.flipAxis ? (yValue - this.dataRange.min) : (this.dataRange.max - yValue)) * yScaleFactor - } - - computeYPixelValueInLogScale(yValue, yScaleFactor) { - let maxValue = this.dataRange.max; - let minValue = this.dataRange.min; - if (maxValue <= 0) return 0 // TODO: - if (minValue <= -1) minValue = 0; - minValue = (minValue <= 0) ? 0 : Math.log10(minValue + 1); - maxValue = Math.log10(maxValue + 1); - yValue = Math.log10(yValue + 1); - return ((this.flipAxis ? (yValue - minValue) : (maxValue - yValue)) * yScaleFactor) - } - - draw(options) { - - // const mergedFeatures = options.features // Array of feature arrays, 1 for each track - const mergedFeatures = options.features; - if(!mergedFeatures) return - - if (this.defaultScale) { - if (this.signal_name == 'rd_snp') { - this.dataRange = { - min: this.config.min || this.dataRange.min || -2, - max: this.config.max || this.dataRange.max || 6 - }; - } else if (this.signal_name == 'rd') { - this.dataRange = { - min: this.config.min || this.dataRange.min || 0, - max: this.config.max || this.dataRange.max || 6 - }; - } else if (this.signal_name == 'snp') { - this.dataRange = { - min: this.config.min || this.dataRange.min || -2, - max: this.config.max || this.dataRange.max || 0 - }; - } - } - - if (this.autoscale) { - this.dataRange = autoscale(options.referenceFrame.chr, mergedFeatures); - } - - if(this.tracks) { - for (let i = 0, len = this.tracks.length; i < len; i++) { - const trackOptions = Object.assign({}, options); - trackOptions.features = mergedFeatures[i]; - this.tracks[i].dataRange = this.dataRange; - this.tracks[i].flipAxis = this.flipAxis; - this.tracks[i].logScale = this.logScale; - if (this.graphType) { - this.tracks[i].graphType = this.graphType; - } - this.tracks[i].draw(trackOptions); - } - } - - // guides lines - const scaleFactor = this.getScaleFactor(this.dataRange.min, this.dataRange.max, options.pixelHeight, this.logScale); - const yScale = (yValue) => this.logScale - ? this.computeYPixelValueInLogScale(yValue, scaleFactor) - : this.computeYPixelValue(yValue, scaleFactor); - - // Draw guidelines - if (this.config.hasOwnProperty('guideLines')) { - for (let line of this.config.guideLines) { - if (line.hasOwnProperty('color') && line.hasOwnProperty('y') && line.hasOwnProperty('dotted')) { - let y = yScale(line.y); - let props = { - 'strokeStyle': line['color'], - 'strokeWidth': 1 - }; - if (line['dotted']) IGVGraphics.dashedLine(options.context, 0, y, options.pixelWidth, y, 5, props); - else IGVGraphics.strokeLine(options.context, 0, y, options.pixelWidth, y, props); - } - } - } - } - - popupData(clickState, features) { - - const featuresArray = features || clickState.viewport.cachedFeatures; - - if (featuresArray && featuresArray.length === this.tracks.length) { - // Array of feature arrays, 1 for each track - const popupData = []; - for (let i = 0; i < this.tracks.length; i++) { - if (i > 0) popupData.push('
'); - popupData.push(`
${this.tracks[i].name}
`); - const trackPopupData = this.tracks[i].popupData(clickState, featuresArray[i]); - popupData.push(...trackPopupData); - - } - return popupData - } - } - -} - -function autoscale(chr, featureArrays) { - - let min = 0; - let max = -Number.MAX_VALUE; - for (let features of featureArrays) { - for (let f of features) { - if (typeof f.value !== 'undefined' && !Number.isNaN(f.value)) { - min = Math.min(min, f.value); - max = Math.max(max, f.value); - } - } - } - return {min: min, max: max} -} - -//import CNVPytorTrack from "./CNVpytor/cnvpytorTrack.js" - - -const trackFunctions = - new Map([ - ['ideogram', (config, browser) => new IdeogramTrack(config, browser)], - ['sequence', (config, browser) => new SequenceTrack(config, browser)], - ['feature', (config, browser) => new FeatureTrack(config, browser)], - ['seg', (config, browser) => new SegTrack(config, browser)], - ['mut', (config, browser) => new SegTrack(config, browser)], - ['maf', (config, browser) => new SegTrack(config, browser)], - ['wig', (config, browser) => new WigTrack(config, browser)], - ['merged', (config, browser) => new MergedTrack(config, browser)], - ['alignment', (config, browser) => new BAMTrack(config, browser)], - ['interaction', (config, browser) => new InteractionTrack(config, browser)], - ['interact', (config, browser) => new InteractionTrack(config, browser)], - ['variant', (config, browser) => new VariantTrack(config, browser)], - ['eqtl', (config, browser) => new EqtlTrack(config, browser)], - ['gwas', (config, browser) => new GWASTrack(config, browser)], - ['arc', (config, browser) => new RnaStructTrack(config, browser)], - ['gcnv', (config, browser) => new GCNVTrack(config, browser)], - ['junction', (config, browser) => new SpliceJunctionTrack(config, browser)], - ['blat', (config, browser) => new BlatTrack(config, browser)], - ['cnvpytor', (config, browser) => new CNVPytorTrack(config, browser)] - ]); - - -/** - * Add a track constructor the the factory lookup table. - * - * @param type - * @param track - */ -const addTrackCreatorFunction = function (type, track) { - trackFunctions.set(type, track); -}; - -const getTrack = function (type, config, browser) { - - let trackKey; - switch (type) { - case "annotation": - case "genes": - case "fusionjuncspan": - case "snp": - trackKey = "feature"; - break - case 'seg': - case 'maf': - case 'mut': - trackKey = 'seg'; - break - case 'junctions': - case 'splicejunctions': - trackKey = 'junction'; - break - default: - trackKey = type; - } - - return trackFunctions.has(trackKey) ? - trackFunctions.get(trackKey)(config, browser) : - undefined -}; - -var TrackFactory = { - tracks: trackFunctions, - addTrack: addTrackCreatorFunction, - trackFunctions, - addTrackCreatorFunction, - getTrack -}; - -/* - * The MIT License (MIT) - * - * Copyright (c) 2016-2017 The Regents of the University of California - * Author: Jim Robinson - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - -/** - * Minimal support for the legacy IGV desktop session format. - */ - -class XMLSession { - - constructor(xmlString, knownGenomes) { - - const parser = new DOMParser(); - const xmlDoc = parser.parseFromString(xmlString, "text/xml"); - - this.processRootNode(xmlDoc, knownGenomes); - - const resourceElements = xmlDoc.getElementsByTagName("Resource"); - const trackElements = xmlDoc.getElementsByTagName("Track"); - const hasTrackElements = trackElements && trackElements.length > 0; - - const tracks = []; - this.tracks = tracks; - - const resourceMap = new Map(); - Array.from(resourceElements).forEach(function (r, idx) { - var config = { - url: r.getAttribute("path"), - indexURL: r.getAttribute("index"), - order: idx - }; - resourceMap.set(config.url, config); - if (!hasTrackElements) { - tracks.push(config); - } - }); - - // Check for optional Track section - if (hasTrackElements) { - - Array.from(trackElements).forEach(function (track) { - - const subtracks = track.getElementsByTagName("Track"); - - if (subtracks && subtracks.length > 0) { - - const mergedTrack = { - type: 'merged', - tracks: [] - }; - extractTrackAttributes(track, mergedTrack); - - tracks.push(mergedTrack); - - Array.from(subtracks).forEach(function (t) { - t.processed = true; - const id = t.getAttribute("id"); - const config = resourceMap.get(id); - if (config) { - mergedTrack.tracks.push(config); - extractTrackAttributes(t, config); - config.autoscale = false; - mergedTrack.height = config.height; - - // Add alpha for merged track colors. Alpha is not recorded by IGV desktop in XML session - //const color = t.getAttribute("color"); - //if (color) { - // config.color = "rgba(" + color + ",0.5)"; - //} - } - }); - } else if (!track.processed) { - - const id = track.getAttribute("id"); - const res = resourceMap.get(id); - if (res) { - tracks.push(res); - extractTrackAttributes(track, res); - } - - } - }); - } - } - - processRootNode(xmlDoc, knownGenomes) { - - const elements = xmlDoc.getElementsByTagName("Session"); - if (!elements || elements.length === 0) ; - const session = elements.item(0); - const genome = session.getAttribute("genome"); - const locus = session.getAttribute("locus"); - const ucscID = session.getAttribute("ucscID"); - - if (knownGenomes && knownGenomes.hasOwnProperty(genome)) { - this.genome = genome; - - } else { - this.reference = { - fastaURL: genome - }; - if (ucscID) { - this.reference.id = ucscID; - } - } - if (locus) { - this.locus = locus; - } - } - -} - - -function extractTrackAttributes(track, config) { - - - config.name = track.getAttribute("name"); - - const color = track.getAttribute("color"); - if (color) { - config.color = "rgb(" + color + ")"; - } - - const altColor = track.getAttribute("altColor"); - if (color) { - config.altColor = "rgb(" + altColor + ")"; - } - - const height = track.getAttribute("height"); - if (height) { - config.height = parseInt(height); - } - - const autoScale = track.getAttribute("autoScale"); - if (autoScale) { - config.autoscale = (autoScale === "true"); - } - - const autoscaleGroup = track.getAttribute("autoscaleGroup"); - if (autoscaleGroup) { - config.autoscaleGroup = autoscaleGroup; - } - - const windowFunction = track.getAttribute("windowFunction"); - if (windowFunction) { - config.windowFunction = windowFunction; - } - const visWindow = track.getAttribute("visibilityWindow") || track.getAttribute("featureVisibilityWindow"); - if (visWindow) { - config.visibilityWindow = visWindow; - } - - const indexed = track.getAttribute("indexed"); - if (indexed) { - config.indexed = (indexed === "true"); - } - - const normalize = track.getAttribute("normalize"); - if (normalize) { - config.normalize = normalize === "true"; - } - - const dataRangeCltn = track.getElementsByTagName("DataRange"); - if (dataRangeCltn.length > 0) { - const dataRange = dataRangeCltn.item(0); - config.min = Number(dataRange.getAttribute("minimum")); - config.max = Number(dataRange.getAttribute("maximum")); - config.logScale = dataRange.getAttribute("type") === "LOG"; - } -} - -/* - * The MIT License (MIT) - * - * Copyright (c) 2014-2015 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -const splitLines = splitLines$5; - -class SampleInformation { - constructor() { - this.attributes = {}; - this.plinkLoaded = false; - } - - async loadPlinkFile(url, config) { - - if (!config) config = {}; - - var options = buildOptions$1(config); // Add oauth token, if any - const data = await igvxhr.loadString(url, options); - var lines = splitLines(data); - - for (let line of lines) { - var line_arr = line.split(' '); - this.attributes[line_arr[1]] = { - familyId: line_arr[0], - fatherId: line_arr[2], - motherId: line_arr[3], - sex: line_arr[4], - phenotype: line_arr[5] - }; - } - this.plinkLoaded = true; - return this - } - - /** - * Return the attributes for the given sample as a map-like object (key-value pairs) - * @param sample - */ - getAttributes(sample) { - return this.attributes[sample] - }; - - getAttributeNames() { - - if (this.hasAttributes()) { - return Object.keys(this.attributes[Object.keys(this.attributes)[0]]) - } else return [] - }; - - hasAttributes() { - return Object.keys(this.attributes).length > 0 - } -} - -function loadPlinkFile(url, config) { - const si = new SampleInformation(); - return si.loadPlinkFile(url, config) -} - -/* - * The MIT License (MIT) - * - * Copyright (c) 2014 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -class GtexSelection { - - constructor(gene, snp) { - this.geneColors = {}; - this.gene = null; - this.snp = null; - this.genesCount = 0; - - if (gene) { - this.gene = gene.toUpperCase(); - this.geneColors[this.gene] = brewer[this.genesCount++]; - - } - if (snp) { - this.snp = snp.toUpperCase(); - } - } - - addGene(geneName) { - if (!this.geneColors[geneName.toUpperCase()]) { - this.geneColors[geneName.toUpperCase()] = brewer[this.genesCount++]; - } - } - - colorForGene(geneName) { - return this.geneColors[geneName.toUpperCase()] - } -} - -var brewer = []; -// Set +! -brewer.push("rgb(228,26,28)"); -brewer.push("rgb(55,126,184)"); -brewer.push("rgb(77,175,74)"); -brewer.push("rgb(166,86,40)"); -brewer.push("rgb(152,78,163)"); -brewer.push("rgb(255,127,0)"); -brewer.push("rgb(247,129,191)"); -brewer.push("rgb(153,153,153)"); -brewer.push("rgb(255,255,51)"); - -// #Set 2 -brewer.push("rgb(102, 194, 165"); -brewer.push("rgb(252, 141, 98"); -brewer.push("rgb(141, 160, 203"); -brewer.push("rgb(231, 138, 195"); -brewer.push("rgb(166, 216, 84"); -brewer.push("rgb(255, 217, 47"); -brewer.push("rgb(229, 196, 148"); -brewer.push("rgb(179, 179, 179"); - -//#Set 3 -brewer.push("rgb( 141, 211, 199"); -brewer.push("rgb(255, 255, 179"); -brewer.push("rgb(190, 186, 218"); -brewer.push("rgb(251, 128, 114"); -brewer.push("rgb(128, 177, 211"); -brewer.push("rgb(253, 180, 98"); -brewer.push("rgb(179, 222, 105"); -brewer.push("rgb(252, 205, 229"); -brewer.push("rgb(217, 217, 217"); -brewer.push("rgb(188, 128, 189"); -brewer.push("rgb(204, 235, 197"); -brewer.push("rgb(255, 237, 111"); - -/* - * The MIT License (MIT) - * - * Copyright (c) 2014 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -// Reference frame classes. Converts domain coordinates (usually genomic) to pixel coordinates - -class ReferenceFrame { - - constructor(genome, chr, start, end, bpPerPixel) { - this.genome = genome; - this.chr = chr; - - this.start = start; - - // TODO WARNING THIS IS NOT UPDATED !!! - this.end = end; - - this.bpPerPixel = bpPerPixel; - this.id = domUtils$1.guid(); - } - - /** - * Extend this frame to accomodate the given locus. Used th CircularView methods to merge 2 frames. - * @param locus - */ - extend(locus) { - const newStart = Math.min(locus.start, this.start); - const newEnd = Math.max(locus.end, this.end); - const ratio = (newEnd - newStart) / (this.end - this.start); - this.start = newStart; - this.end = newEnd; - this.bpPerPixel *= ratio; - } - - calculateEnd(pixels) { - return this.start + this.bpPerPixel * pixels - } - - calculateBPP(end, pixels) { - return (end - this.start) / pixels - } - - set(json) { - this.chr = json.chr; - this.start = json.start; - this.bpPerPixel = json.bpPerPixel; - } - - toPixels(bp) { - return bp / this.bpPerPixel - } - - toBP(pixels) { - return this.bpPerPixel * pixels - } - - /** - * Shift frame by stated pixels. Return true if view changed, false if not. - * - * @param pixels - * @param clamp -- if true "clamp" shift to prevent panning off edge of chromosome. This is disabled if "show soft clipping" is on - * @param viewportWidth - */ - shiftPixels(pixels, viewportWidth, clamp) { - - const currentStart = this.start; - const deltaBP = pixels * this.bpPerPixel; - - this.start += deltaBP; - - if(clamp) { - this.clampStart(viewportWidth); - } - - this.end = this.start + viewportWidth * this.bpPerPixel; - - return currentStart !== this.start - } - - clampStart(viewportWidth) { - // clamp left - const min = (this.genome.getChromosome(this.chr).bpStart || 0); - this.start = Math.max(min, this.start); - - // clamp right - if (viewportWidth) { - - const {bpLength} = this.genome.getChromosome(this.chr); - const maxStart = bpLength - (viewportWidth * this.bpPerPixel); - - if (this.start > maxStart) { - this.start = maxStart; - } - } - } - - async zoomWithScaleFactor(browser, scaleFactor, viewportWidth, centerBPOrUndefined) { - - const centerBP = undefined === centerBPOrUndefined ? (this.start + this.toBP(viewportWidth / 2.0)) : centerBPOrUndefined; - - // save initial start and bpp - const {start, bpPerPixel} = this.start; - - const {bpLength} = this.getChromosome(); - const bppThreshold = scaleFactor < 1.0 ? browser.minimumBases() / viewportWidth : bpLength / viewportWidth; - - // update bpp - if (scaleFactor < 1.0) { - this.bpPerPixel = Math.max(this.bpPerPixel * scaleFactor, bppThreshold); - } else { - this.bpPerPixel = Math.min(this.bpPerPixel * scaleFactor, bppThreshold); - } - - // update start and end - const widthBP = this.bpPerPixel * viewportWidth; - this.start = centerBP - 0.5 * widthBP; - this.clampStart(viewportWidth); - - this.end = this.start + widthBP; - - const viewChanged = start !== this.start || bpPerPixel !== this.bpPerPixel; - if (viewChanged) { - await browser.updateViews(true); - } - - } - - getChromosome() { - return this.genome.getChromosome(this.chr) - } - - getMultiLocusLabelBPLengthOnly(pixels) { - const margin = ' '; - const ss = Math.floor(this.start) + 1; - const ee = Math.round(this.start + this.bpPerPixel * pixels); - return `${margin}${this.chr}${margin}${prettyBasePairNumber(ee - ss)}${margin}` - } - - getMultiLocusLabelLocusOnly(pixels) { - const margin = ' '; - const {chr, start, end } = this.getPresentationLocusComponents(pixels); - return `${margin}${chr}:${start}-${end}${margin}` - } - - getMultiLocusLabel(pixels) { - const margin = ' '; - const {chr, start, end } = this.getPresentationLocusComponents(pixels); - const ss = Math.floor(this.start) + 1; - const ee = Math.round(this.start + this.bpPerPixel * pixels); - return `${margin}${chr}:${start}-${end}${margin}${margin}(${prettyBasePairNumber(ee - ss)})${margin}` - } - - getPresentationLocusComponents(pixels) { - - if ('all' === this.chr) { - return {chr: this.chr} - } else { - const ss = numberFormatter$1(Math.floor(this.start) + 1); - const ee = numberFormatter$1(Math.round(this.start + this.bpPerPixel * pixels)); - - return {chr: this.chr, start: ss, end: ee} - } - - } - - getLocusString() { - if ('all' === this.chr) { - return 'all' - } else { - const ss = numberFormatter$1(Math.floor(this.start) + 1); - const ee = numberFormatter$1(Math.round(this.end)); - return `${this.chr}:${ss}-${ee}` - } - } - - description(blurb) { - console.log(` ${blurb || ''} referenceFrame - ${this.chr} bpp ${this.bpPerPixel.toFixed(3)} start ${numberFormatter$1(Math.round(this.start))} end ${numberFormatter$1(Math.round(this.end))} `); - } -} - -function createReferenceFrameList(loci, genome, browserFlanking, minimumBases, viewportWidth, isSoftclipped) { - - return loci.map(locus => { - - // If a flanking region is defined, and the search object is a symbol ("gene") type, adjust start and end - if (browserFlanking && locus.gene) { - locus.start = Math.max(0, locus.start - browserFlanking); - locus.end += browserFlanking; - } - - // Validate the range. This potentionally modifies start & end of locus. - if(!isSoftclipped) { - const chromosome = genome.getChromosome(locus.chr); - validateGenomicExtent(chromosome.bpLength, locus, minimumBases); - } - - const referenceFrame = new ReferenceFrame(genome, - locus.chr, - locus.start, - locus.end, - (locus.end - locus.start) / viewportWidth); - - referenceFrame.locusSearchString = locus.locusSearchString; - - // GTEX hack - if (locus.gene || locus.snp) { - referenceFrame.selection = new GtexSelection(locus.gene, locus.snp); - } - - return referenceFrame - }) -} - -const DEFAULT_SEARCH_CONFIG = { - timeout: 5000, - type: "plain", // Legacy plain text support -- deprecated - url: 'https://igv.org/genomes/locus.php?genome=$GENOME$&name=$FEATURE$', - coords: 0, - chromosomeField: "chromosome", - startField: "start", - endField: "end", - geneField: "gene", - snpField: "snp" -}; - -/** - * Return an object representing the locus of the given string. Object is of the form - * { - * chr, - * start, - * end, - * locusSearchString, - * gene, - * snp - * } - * @param browser - * @param string - * @returns {Promise<*>} - */ -async function search(browser, string) { - - if (undefined === string || '' === string.trim()) { - return - } - - if (string && string.trim().toLowerCase() === "all" || string === "*") { - string = "all"; - } - - const loci = string.split(' '); - - let searchConfig = browser.searchConfig || DEFAULT_SEARCH_CONFIG; - let list = []; - - const searchLocus = async (locus) => { - let locusObject = parseLocusString(browser, locus); - - if (!locusObject) { - const feature = browser.genome.featureDB.get(locus.toUpperCase()); - if (feature) { - locusObject = { - chr: feature.chr, - start: feature.start, - end: feature.end, - gene: feature.name, - locusSearchString: string - }; - } - } - - if (!locusObject && (browser.config && false !== browser.config.search)) { - try { - locusObject = await searchWebService(browser, locus, searchConfig); - } catch (error) { - console.error(error); - throw Error("Search service currently unavailable.") - } - } - return locusObject - }; - - for (let locus of loci) { - const locusObject = await searchLocus(locus); - if (locusObject) { - locusObject.locusSearchString = locus; - list.push(locusObject); - } - } - - // If nothing is found, consider possibility that loci name itself has spaces - if (list.length === 0) { - const locusObject = await searchLocus(string); - if (locusObject) { - locusObject.locusSearchString = string; - list.push(locusObject); - } - } - - - return 0 === list.length ? undefined : list -} - -function parseLocusString(browser, locus) { - - // Check for tab delimited locus string - const tabTokens = locus.split('\t'); - if (tabTokens.length >= 3) { - // Possibly a tab-delimited locus - try { - const chr = browser.genome.getChromosomeName(tabTokens[0]); - const start = parseInt(tabTokens[1].replace(/,/g, ''), 10) - 1; - const end = parseInt(tabTokens[2].replace(/,/g, ''), 10); - if (!isNaN(start) && !isNaN(end)) { - return {chr, start, end} - } - } catch (e) { - // Not a tab delimited locus, apparently, but not really an error as that was a guess - } - - } - - const a = locus.split(':'); - const chr = a[0]; - if ('all' === chr && browser.genome.getChromosome(chr)) { - return {chr, start: 0, end: browser.genome.getChromosome(chr).bpLength} - - } else if (undefined === browser.genome.getChromosome(chr)) { - return undefined - - } else { - const queryChr = browser.genome.getChromosomeName(chr); - const extent = { - chr: queryChr, - start: 0, - end: browser.genome.getChromosome(chr).bpLength - }; - - if (a.length > 1) { - - let b = a[1].split('-'); - if (b.length > 2) { - // Allow for negative coordinates, which is possible if showing alignment soft clips - if (a[1].startsWith('-')) { - const i = a[1].indexOf('-', 1); - if (i > 0) { - const t1 = a[1].substring(0, i); - const t2 = a[1].substring(i + 1); - b = [t1, t2]; - } - } else { - return undefined - } - - } - - let numeric; - numeric = b[0].replace(/,/g, ''); - if (isNaN(numeric)) { - return undefined - } - - extent.start = parseInt(numeric, 10) - 1; - extent.end = extent.start + 1; - - if (1 === b.length) { - // Don't clamp coordinates if single coordinate is supplied. - extent.start -= 20; - extent.end += 20; - } - - if (2 === b.length) { - numeric = b[1].replace(/,/g, ''); - if (isNaN(numeric)) { - return undefined - } else { - extent.end = parseInt(numeric, 10); - } - - // Allow negative coordinates only if browser is softclipped, i.e. there is at least alignment track with softclipping on - if (extent.start < 0 && !browser.isSoftclipped()) { - const delta = -extent.start; - extent.start += delta; - extent.end += delta; - } - } - } - - return extent - } -} - -async function searchWebService(browser, locus, searchConfig) { - - let path = searchConfig.url.replace("$FEATURE$", locus.toUpperCase()); - if (path.indexOf("$GENOME$") > -1) { - path = path.replace("$GENOME$", (browser.genome.id ? browser.genome.id : "hg19")); - } - const options = searchConfig.timeout ? {timeout: searchConfig.timeout} : undefined; - const result = await igvxhr.loadString(path, options); - - const locusObject = processSearchResult(browser, result, searchConfig); - if (locusObject) { - locusObject.locusSearchString = locus; - } - return locusObject -} - -function processSearchResult(browser, result, searchConfig) { - - let results; - - if ('plain' === searchConfig.type) { - results = parseSearchResults$1(browser, result); - } else { - results = JSON.parse(result); - } - - if (searchConfig.resultsField) { - results = results[searchConfig.resultsField]; - } - - if (!results || 0 === results.length) { - return undefined - - } else { - - const chromosomeField = searchConfig.chromosomeField || "chromosome"; - const startField = searchConfig.startField || "start"; - const endField = searchConfig.endField || "end"; - const coords = searchConfig.coords || 1; - - - let result; - if (Array.isArray(results)) { - // Ignoring all but first result for now - // TODO -- present all and let user select if results.length > 1 - result = results[0]; - } else { - // When processing search results from Ensembl REST API - // Example: https://rest.ensembl.org/lookup/symbol/macaca_fascicularis/BRCA2?content-type=application/json - result = results; - } - - if (!(result.hasOwnProperty(chromosomeField) && (result.hasOwnProperty(startField)))) { - console.error("Search service results must include chromosome and start fields: " + result); - } - - const chrResult = result[chromosomeField]; - const chromosome = browser.genome.getChromosome(chrResult); - if (!chromosome) { - return undefined - } - const chr = chromosome.name; - - let start = result[startField] - coords; - let end = result[endField]; - if (undefined === end) { - end = start + 1; - } - - const locusObject = {chr, start, end}; - - // Some GTEX hacks - const type = result.type ? result.type : "gene"; - if (searchConfig.geneField && type === "gene") { - locusObject.gene = result[searchConfig.geneField]; - } - if (searchConfig.snpField && type === "snp") { - locusObject.snp = result[searchConfig.snpField]; - } - - return locusObject - } -} - -/** - * Parse the igv line-oriented (non json) search results. - * Example - * EGFR chr7:55,086,724-55,275,031 refseq - * - */ -function parseSearchResults$1(browser, data) { - - const linesTrimmed = []; - const results = []; - const lines = splitLines$5(data); - - lines.forEach(function (item) { - if ("" === item) ; else { - linesTrimmed.push(item); - } - }); - - linesTrimmed.forEach(function (line) { - - var tokens = line.split("\t"), - source, - locusTokens, - rangeTokens, - obj; - - if (tokens.length >= 3) { - - locusTokens = tokens[1].split(":"); - rangeTokens = locusTokens[1].split("-"); - source = tokens[2].trim(); - - obj = - { - gene: tokens[0], - chromosome: browser.genome.getChromosomeName(locusTokens[0].trim()), - start: parseInt(rangeTokens[0].replace(/,/g, '')), - end: parseInt(rangeTokens[1].replace(/,/g, '')), - type: ("gtex" === source ? "snp" : "gene") - }; - - results.push(obj); - - } - - }); - - return results - -} - -/* - * The MIT License (MIT) - * - * Copyright (c) 2014 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -class NavbarManager { - - constructor(browser) { - this.browser = browser; - } - - navbarDidResize(width) { - this.updateNavbar(this.createResponsiveClassSchedule(width)); - } - - updateNavbar(responsiveClassSchedule) { - - this.browser.$toggle_button_container.removeClass(); - this.browser.$toggle_button_container.addClass(responsiveClassSchedule.$toggle_button_container); - - $$1(this.browser.zoomWidget.zoomContainer).removeClass(); - $$1(this.browser.zoomWidget.zoomContainer).addClass(responsiveClassSchedule.zoomContainer); - } - - createResponsiveClassSchedule(navbarWidth) { - - let candidates = {}; - - const isWGV = this.browser.isMultiLocusWholeGenomeView() || - (this.browser.referenceFrameList && - GenomeUtils.isWholeGenomeView(this.browser.referenceFrameList[0].chr)); - - - if (isWGV) { - this.browser.windowSizePanel.hide(); - } else { - this.browser.windowSizePanel.show(); - } - - if (navbarWidth > 990) { - candidates.$toggle_button_container = 'igv-navbar-toggle-button-container'; - candidates.zoomContainer = 'igv-zoom-widget'; - } else if (navbarWidth > 860) { - candidates.$toggle_button_container = 'igv-navbar-toggle-button-container'; - candidates.zoomContainer = 'igv-zoom-widget-900'; - } else if (navbarWidth > 540) { - candidates.$toggle_button_container = 'igv-navbar-toggle-button-container-750'; - candidates.zoomContainer = 'igv-zoom-widget-900'; - } else { - candidates.$toggle_button_container = 'igv-navbar-toggle-button-container-750'; - candidates.zoomContainer = 'igv-zoom-widget-900'; - this.browser.windowSizePanel.hide(); - } - - if (isWGV) { - candidates['zoomContainer'] = 'igv-zoom-widget-hidden'; - } - - return candidates - } -} - -/* - * The MIT License (MIT) - * - * Copyright (c) 2016-2017 The Regents of the University of California - * Author: Jim Robinson - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -const ChromosomeSelectWidget = function (browser, parent) { - - this.container = domUtils$1.div({class: 'igv-chromosome-select-widget-container'}); - parent.appendChild(this.container); - - this.select = document.createElement('select'); - this.select.setAttribute('name', 'chromosome-select-widget'); - this.container.appendChild(this.select); - - this.select.addEventListener('change', () => { - this.select.blur(); - if (this.select.value !== '') { - browser.search(this.select.value); - } - }); - - this.showAllChromosomes = browser.config.showAllChromosomes !== false; // i.e. default to true - -}; - -ChromosomeSelectWidget.prototype.show = function () { - this.container.style.display = 'flex'; -}; - -ChromosomeSelectWidget.prototype.hide = function () { - this.container.style.display = 'none'; -}; - -ChromosomeSelectWidget.prototype.update = function (genome) { - - const list = this.showAllChromosomes ? genome.chromosomeNames.slice() : genome.wgChromosomeNames.slice(); - // console.log(`${ this.showAllChromosomes ? 'Do' : 'Do not'} show all chromosomes. List ${ list }`) - - if (genome.showWholeGenomeView()) { - list.unshift('all'); - list.unshift(''); - } - - this.select.innerHTML = ''; - - for (let name of list) { - const option = document.createElement('option'); - option.setAttribute('value', name); - option.innerText = name; - this.select.appendChild(option); - } - -}; - -/* - * The MIT License (MIT) - * - * Copyright (c) 2014 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -class WindowSizePanel { - constructor(parent, browser) { - - this.container = domUtils$1.div({class: 'igv-windowsize-panel-container'}); - parent.appendChild(this.container); - - browser.on('locuschange', (referenceFrameList) => { - this.updatePanel(referenceFrameList); - }); - - this.browser = browser; - - } - - show() { - this.container.style.display = 'block'; - } - - hide() { - this.container.style.display = 'none'; - } - - updatePanel(referenceFrameList) { - const width = this.browser.calculateViewportWidth(this.browser.referenceFrameList.length); - this.container.innerText = 1 === referenceFrameList.length ? prettyBasePairNumber(Math.round(width * referenceFrameList[0].bpPerPixel)) : ''; - } -} - -class CursorGuide { - - constructor(columnContainer, browser) { - this.browser = browser; - this.columnContainer = columnContainer; - - this.horizontalGuide = domUtils$1.div({class: 'igv-cursor-guide-horizontal'}); - columnContainer.appendChild(this.horizontalGuide); - - this.verticalGuide = domUtils$1.div({class: 'igv-cursor-guide-vertical'}); - columnContainer.appendChild(this.verticalGuide); - - this.addMouseHandler(browser); - - this.setVisibility(browser.config.showCursorGuide); - - } - - addMouseHandler(browser) { - - this.boundMouseMoveHandler = mouseMoveHandler.bind(this); - this.columnContainer.addEventListener('mousemove', this.boundMouseMoveHandler); - - function mouseMoveHandler(event) { - - const {x, y} = domUtils$1.translateMouseCoordinates(event, this.columnContainer); - this.horizontalGuide.style.top = `${y}px`; - - const target = document.elementFromPoint(event.clientX, event.clientY); - - const viewport = findAncestorOfClass(target, 'igv-viewport'); - - if (viewport && browser.getRulerTrackView()) { - - this.verticalGuide.style.left = `${x}px`; - - const columns = browser.root.querySelectorAll('.igv-column'); - let index = undefined; - const viewportParent = viewport.parentElement; - for (let i = 0; i < columns.length; i++) { - if (undefined === index && viewportParent === columns[i]) { - index = i; - } - } - - const rulerViewport = browser.getRulerTrackView().viewports[index]; - const result = rulerViewport.mouseMove(event); - - if (result) { - - const {start, bp, end} = result; - const interpolant = (bp - start) / (end - start); - - if (this.customMouseHandler) { - this.customMouseHandler({start, bp, end, interpolant}); - } - } - } - - } - } - - removeMouseHandler() { - this.columnContainer.removeEventListener('mousemove', this.boundMouseMoveHandler); - } - - setVisibility(showCursorGuide) { - if (true === showCursorGuide) { - this.show(); - } else { - this.hide(); - } - } - - show() { - this.verticalGuide.style.display = 'block'; - this.horizontalGuide.style.display = 'block'; - - } - - hide() { - - this.verticalGuide.style.display = 'none'; - this.horizontalGuide.style.display = 'none'; - - if (this.browser.getRulerTrackView()) { - for (let viewport of this.browser.getRulerTrackView().viewports) { - viewport.$tooltip.hide(); - } - } - - } - -} - -/** - * Walk up the tree until a parent is found with the given classname. If no ancestor is found return undefined. - * @param target - * @param classname - * @returns {*} - */ -function findAncestorOfClass(target, classname) { - - while (target.parentElement) { - if (target.parentElement.classList.contains(classname)) { - return target.parentElement - } else { - target = target.parentElement; - } - } - return undefined - -} - -/* - * The MIT License (MIT) - * - * Copyright (c) 2016 University of California San Diego - * Author: Jim Robinson - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -class CursorGuideButton { - - constructor(browser, parent) { - - this.browser = browser; - - this.button = domUtils$1.div({class: 'igv-navbar-button'}); - parent.appendChild(this.button); - - this.button.textContent = 'cursor guide'; - - this.button.addEventListener('click', () => { - browser.cursorGuideVisible = !browser.cursorGuideVisible; - browser.setCursorGuideVisibility(browser.cursorGuideVisible); - this.setButtonState(browser.cursorGuideVisible); - }); - - this.setButtonState(browser.cursorGuideVisible); - - if (browser.config.showCursorTrackingGuideButton) { - this.show(); - } else { - this.hide(); - } - - } - - setButtonState(cursorGuideVisible) { - if (true === cursorGuideVisible) { - this.button.classList.add('igv-navbar-button-clicked'); - } else { - this.button.classList.remove('igv-navbar-button-clicked'); - } - } - - show() { - this.button.style.display = 'block'; - this.setButtonState(this.browser.cursorGuideVisible); - } - - hide() { - this.button.style.display = 'none'; - } -} - -class CenterLineButton { - - constructor(browser, parent) { - - this.browser = browser; - - this.button = domUtils$1.div({class: 'igv-navbar-button'}); - parent.appendChild(this.button); - - this.button.textContent = 'center line'; - - this.button.addEventListener('click', () => { - browser.isCenterLineVisible = !browser.isCenterLineVisible; - browser.setCenterLineVisibility(browser.isCenterLineVisible); - this.setButtonState(browser.isCenterLineVisible); - }); - - this.setButtonState(browser.isCenterLineVisible); - - if (browser.config.showCenterGuideButton) { - this.show(); - } else { - this.hide(); - } - } - - setButtonState(isCenterLineVisible) { - if (true === isCenterLineVisible) { - this.button.classList.add('igv-navbar-button-clicked'); - } else { - this.button.classList.remove('igv-navbar-button-clicked'); - } - } - - show() { - this.isVisible = true; - this.button.style.display = 'block'; - this.setButtonState(this.browser.isCenterLineVisible); - } - - hide() { - this.isVisible = false; - this.button.style.display = 'none'; - } -} - -/* - * The MIT License (MIT) - * - * Copyright (c) 2016 University of California San Diego - * Author: Jim Robinson - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -class TrackLabelControl { - - constructor(parent, browser) { - - this.button = domUtils$1.div({class: 'igv-navbar-button'}); - parent.appendChild(this.button); - this.button.textContent = 'track labels'; - - this.button.addEventListener('click', () => { - browser.trackLabelsVisible = !browser.trackLabelsVisible; - this.setState(browser.trackLabelsVisible); - browser.setTrackLabelVisibility(browser.trackLabelsVisible); - }); - - this.browser = browser; - - this.setVisibility(browser.config.showTrackLabelButton); - - this.setState(browser.trackLabelsVisible); - } - - setVisibility(showTrackLabelButton) { - if (true === showTrackLabelButton) { - this.show(); - } else { - this.hide(); - } - } - - setState(trackLabelsVisible) { - if (true === trackLabelsVisible) { - this.button.classList.add('igv-navbar-button-clicked'); - } else { - this.button.classList.remove('igv-navbar-button-clicked'); - } - } - - show() { - this.button.style.display = 'block'; - this.setState(this.browser.trackLabelsVisible); - } - - hide() { - this.button.style.display = 'none'; - } -} - -/* - * The MIT License (MIT) - * - * Copyright (c) 2016 University of California San Diego - * Author: Jim Robinson - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -class SampleNameControl { - - constructor(parent, browser) { - - this.button = domUtils$1.div({class: 'igv-navbar-button'}); - parent.appendChild(this.button); - - this.button.innerText = 'Sample Names'; - - this.setState(browser.showSampleNames); - - this.setVisibility(browser.showSampleNameButton); - - this.button.addEventListener('click', () => { - - browser.showSampleNames = !browser.showSampleNames; - - this.setState(browser.showSampleNames); - - for (let {sampleNameViewport} of browser.trackViews) { - if (false === browser.showSampleNames) { - sampleNameViewport.hide(); - } else { - sampleNameViewport.show(); - } - } - - browser.layoutChange(); - - - }); - - } - - setVisibility(showSampleNameButton) { - - if (true === showSampleNameButton) { - this.show(); - } else { - this.hide(); - } - } - - setState(showSampleNames) { - if (true === showSampleNames) { - this.button.classList.add('igv-navbar-button-clicked'); - } else { - this.button.classList.remove('igv-navbar-button-clicked'); - } - } - - hide() { - this.button.style.display = 'none'; - } - - show() { - this.button.style.display = 'block'; - } - -} - -const sliderMin = 0; -let sliderMax = 23; -let sliderValueRaw = 0; - -const ZoomWidget = function (browser, parent) { - - this.browser = browser; - - this.zoomContainer = domUtils$1.div({class: 'igv-zoom-widget'}); - parent.appendChild(this.zoomContainer); - - // zoom out - this.zoomOutButton = domUtils$1.div(); - this.zoomContainer.appendChild(this.zoomOutButton); - this.zoomOutButton.appendChild(icons$1$1.createIcon('minus-circle')); - this.zoomOutButton.addEventListener('click', () => { - // browser.zoomWithScaleFactor(2.0) - browser.zoomOut(); - }); - - // Range slider - const el = domUtils$1.div(); - this.zoomContainer.appendChild(el); - this.slider = document.createElement('input'); - this.slider.type = 'range'; - - this.slider.min = `${sliderMin}`; - this.slider.max = `${sliderMax}`; - - el.appendChild(this.slider); - - this.slider.addEventListener('change', e => { - - e.preventDefault(); - e.stopPropagation(); - - const referenceFrame = browser.referenceFrameList[0]; - const {bpLength} = referenceFrame.genome.getChromosome(referenceFrame.chr); - const {end, start} = referenceFrame; - - const extent = end - start; - - // bpLength/(end - start) - const scaleFactor = Math.pow(2, e.target.valueAsNumber); - - // (end - start) = bpLength/scaleFactor - const zoomedExtent = bpLength / scaleFactor; - - // console.log(`zoom-widget - slider ${ e.target.value } scaleFactor ${ scaleFactor } extent-zoomed ${ StringUtils.numberFormatter(Math.round(zoomedExtent)) }`) - - browser.zoomWithScaleFactor(zoomedExtent / extent); - - }); - - // zoom in - this.zoomInButton = domUtils$1.div(); - this.zoomContainer.appendChild(this.zoomInButton); - this.zoomInButton.appendChild(icons$1$1.createIcon('plus-circle')); - this.zoomInButton.addEventListener('click', () => { - // browser.zoomWithScaleFactor(0.5) - browser.zoomIn(); - }); - - browser.on('locuschange', (referenceFrameList) => { - - if (this.browser.isMultiLocusMode()) { - this.disable(); - } else { - this.enable(); - this.update(referenceFrameList); - } - - }); - -}; - -ZoomWidget.prototype.update = function (referenceFrameList) { - - const referenceFrame = referenceFrameList[0]; - const {bpLength} = referenceFrame.genome.getChromosome(referenceFrame.chr); - const {start, end} = referenceFrame; - - sliderMax = Math.ceil(Math.log2(bpLength / this.browser.minimumBases())); - - this.slider.max = `${sliderMax}`; - - const scaleFactor = bpLength / (end - start); - sliderValueRaw = Math.log2(scaleFactor); - this.slider.value = `${Math.round(sliderValueRaw)}`; - - // referenceFrame.description('zoom.update') - - // console.log(`${ Date.now() } update - slider ${ this.slider.value } scaleFactor ${ Math.round(scaleFactor) } extent ${ StringUtils.numberFormatter(Math.round(extent)) }`) - - // console.log(`update - sliderMin ${ sliderMin } sliderValue ${ this.slider.value } sliderMax ${ sliderMax } scaleFactor ${ scaleFactor.toFixed(3) } derived-scaleFactor ${ derivedScalefactor.toFixed(3) }`) - -}; - -ZoomWidget.prototype.enable = function () { - - // this.zoomInButton.style.color = appleCrayonPalette[ 'steel' ]; - // this.zoomInButton.style.pointerEvents = 'auto'; - // - // this.zoomOutButton.style.color = appleCrayonPalette[ 'steel' ]; - // this.zoomOutButton.style.pointerEvents = 'auto'; - - this.slider.disabled = false; -}; - -ZoomWidget.prototype.disable = function () { - - // this.zoomInButton.style.color = appleCrayonPalette[ 'silver' ]; - // this.zoomInButton.style.pointerEvents = 'none'; - // - // this.zoomOutButton.style.color = appleCrayonPalette[ 'silver' ]; - // this.zoomOutButton.style.pointerEvents = 'none'; - - this.slider.disabled = true; -}; - -ZoomWidget.prototype.hide = function () { - this.zoomContainer.style.display = 'none'; -}; - -ZoomWidget.prototype.show = function () { - this.zoomContainer.style.display = 'block'; -}; - -ZoomWidget.prototype.hideSlider = function () { - this.slider.style.display = 'none'; -}; - -ZoomWidget.prototype.showSlider = function () { - this.slider.style.display = 'block'; -}; - -/* - * The MIT License (MIT) - * - * Copyright (c) 2016 University of California San Diego - * Author: Jim Robinson - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -const SVGSaveControl = function (parent, browser) { - const button = domUtils$1.div({class: 'igv-navbar-button'}); - parent.append(button); - - button.textContent = 'Save SVG'; - button.addEventListener('click', () => browser.saveSVGtoFile({})); -}; - -const viewportColumnManager = - { - createColumns: (columnContainer, count) => { - - for (let i = 0; i < count; i++) { - if (0 === i) { - createColumn(columnContainer, 'igv-column'); - } else { - columnContainer.appendChild(domUtils$1.div({class: 'igv-column-shim'})); - createColumn(columnContainer, 'igv-column'); - } - } - - }, - - removeColumnAtIndex: (i, column) => { - const shim = 0 === i ? column.nextElementSibling : column.previousElementSibling; - column.remove(); - shim.remove(); - }, - - insertAfter: referenceElement => { - - const shim = domUtils$1.div({class: 'igv-column-shim'}); - insertElementAfter(shim, referenceElement); - - const column = domUtils$1.div({class: 'igv-column'}); - insertElementAfter(column, shim); - - return column - }, - - insertBefore: (referenceElement, count) => { - - for (let i = 0; i < count; i++) { - - const column = domUtils$1.div({class: 'igv-column'}); - insertElementBefore(column, referenceElement); - - if (count > 1 && i > 0) { - const columnShim = domUtils$1.div({class: 'igv-column-shim'}); - insertElementBefore(columnShim, column); - } - - } - - }, - - indexOfColumn: (columnContainer, column) => { - - const allColumns = columnContainer.querySelectorAll('.igv-column'); - - for (let i = 0; i < allColumns.length; i++) { - const c = allColumns[ i ]; - if (c === column) { - return i - } - } - - return undefined - }, - }; - -/* - * The MIT License (MIT) - * - * Copyright (c) 2016 University of California San Diego - * Author: Jim Robinson - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -class ViewportCenterLine { - - constructor(browser, referenceFrame, column) { - - this.browser = browser; - this.referenceFrame = referenceFrame; - this.column = column; - - this.container = domUtils$1.div({class: 'igv-center-line'}); - column.appendChild(this.container); - - if (browser.isCenterLineVisible) { - this.show(); - } else { - this.hide(); - } - } - - repaint() { - - if (this.referenceFrame) { - - const ppb = 1.0 / this.referenceFrame.bpPerPixel; - if (ppb > 1) { - const width = Math.floor(this.referenceFrame.toPixels(1)); - this.container.style.width = `${width}px`; - this.container.classList.remove('igv-center-line-thin'); - this.container.classList.add('igv-center-line-wide'); - } else { - this.container.style.width = '1px'; - this.container.classList.remove('igv-center-line-wide'); - this.container.classList.add('igv-center-line-thin'); - } - } - } - - show() { - this.isVisible = true; - this.container.style.display = 'block'; - this.repaint(); - } - - hide() { - this.isVisible = false; - this.container.style.display = 'none'; - } - - resize() { - this.repaint(); - } -} - -/* - * The MIT License (MIT) - * - * Copyright (c) 2014 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -const numberFormatter = numberFormatter$1; - -class RulerTrack { - constructor(browser) { - - this.browser = browser; - this.height = 40; - this.name = ""; - this.id = "ruler"; - this.disableButtons = true; - this.ignoreTrackMenu = true; - this.order = Number.MIN_SAFE_INTEGER * 1e-2; - this.removable = false; - this.type = 'ruler'; - } - - async getFeatures(chr, start, end) { - return [] - }; - - computePixelHeight(ignore) { - return this.height - }; - - draw({context, referenceFrame, pixelWidth, pixelHeight, bpPerPixel, bpStart}) { - - if (GenomeUtils.isWholeGenomeView(referenceFrame.chr)) { - this.drawWholeGenome({context, pixelWidth, pixelHeight, bpPerPixel}); - } else { - this.doDraw({context, referenceFrame, pixelWidth, pixelHeight, bpStart}); - } - } - - drawWholeGenome({context, pixelWidth, pixelHeight, bpPerPixel}) { - - context.save(); - - IGVGraphics.fillRect(context, 0, 0, pixelWidth, pixelHeight, {'fillStyle': 'white'}); - - for (let name of this.browser.genome.wgChromosomeNames) { - - let xBP = this.browser.genome.getCumulativeOffset(name); - let wBP = this.browser.genome.getChromosome(name).bpLength; - - let x = Math.round(xBP / bpPerPixel); - let w = Math.round(wBP / bpPerPixel); - - this.renderChromosomeRect(context, x, 0, w, pixelHeight, name); - } - - context.restore(); - - } - - doDraw({context, referenceFrame, pixelWidth, pixelHeight, bpStart}) { - - context.clearRect(0, 0, pixelWidth, pixelHeight); - - const tickHeight = 6; - const shim = 2; - - const bpLength = Math.floor(referenceFrame.toBP(pixelWidth)); - const tick = findSpacing$1(bpLength, context.isSVG); - - let nTick = Math.floor(bpStart / tick.majorTick) - 1; - - const {tickDelta, labelLength} = calculateDeltas(context, referenceFrame, bpStart, nTick, tick); - - this.browser.referenceFrameList.indexOf(referenceFrame); - // console.log(`ruler(${ index }) label-length ${ labelLength > tickDelta ? 'clobbers' : 'less than' } tick-delta ${ StringUtils.numberFormatter(tickDelta)} `) - - let xTick; - let bp; - let accumulatedTickDelta = tickDelta; - const labelLengthShim = 0.25 * labelLength; - do { - - bp = Math.floor(nTick * tick.majorTick); - const rulerLabel = `${numberFormatter$1(Math.floor(bp / tick.unitMultiplier))} ${tick.majorUnit}`; - - xTick = Math.round(referenceFrame.toPixels((bp - 1) - bpStart + 0.5)); - const xLabel = Math.round(xTick - context.measureText(rulerLabel).width / 2); - - if (xLabel > 0 && (labelLengthShim + labelLength) <= accumulatedTickDelta) { - IGVGraphics.fillText(context, rulerLabel, xLabel, this.height - (tickHeight / 0.75)); - accumulatedTickDelta = 0; - } - - if (xTick > 0) { - IGVGraphics.strokeLine(context, xTick, this.height - tickHeight, xTick, this.height - shim); - } - - bp = Math.floor((1 + nTick) * tick.majorTick); - let pixel = Math.round(referenceFrame.toPixels((bp - 1) - bpStart + 0.5)); - let delta = (pixel - xTick) / 2; - let xx = xTick + delta; - if (xx > 0) { - IGVGraphics.strokeLine(context, xx, this.height - tickHeight, xx, this.height - shim); - } - - ++nTick; - accumulatedTickDelta += tickDelta; - - } while (xTick < pixelWidth) - - IGVGraphics.strokeLine(context, 0, this.height - shim, pixelWidth, this.height - shim); - - } - - renderChromosomeRect(ctx, x, y, w, h, name) { - - ctx.textAlign = 'center'; - ctx.textBaseline = 'middle'; - ctx.font = '12px sans-serif'; - - IGVGraphics.strokeLine(ctx, x + w, y, x + w, y + h, {strokeStyle: IGVColor.greyScale(191)}); - - const shortName = (name.startsWith("chr")) ? name.substring(3) : name; - - if (w > ctx.measureText(shortName).width) { - IGVGraphics.fillText(ctx, shortName, (x + (w / 2)), (y + (h / 2)), {fillStyle: IGVColor.greyScale(68)}); - } - } - - get supportsWholeGenome() { - return true - }; - - dispose() { - // do stuff - } -} - -function findSpacing$1(bpLength, isSVG) { - - if (bpLength < 10) { - return new Tick(1, 'bp', 1) - } - - const nZeroes = Math.floor(Math.log10(bpLength)); - - let majorUnit = 'bp'; - let unitMultiplier = 1; - - if (nZeroes > 9) { - majorUnit = 'gb'; - unitMultiplier = 1e9; - } else if (nZeroes > 6) { - majorUnit = 'mb'; - unitMultiplier = 1e6; - } else if (nZeroes > 3) { - majorUnit = 'kb'; - unitMultiplier = 1e3; - } - - const denom = Math.pow(10, nZeroes - 1); - const nMajorTicks = bpLength / denom; - - // const threshold = 25 - const threshold = 3 * 25; - - const belowThresholdTick = Math.pow(10, nZeroes - 1); - const aboveThresholdTick = Math.pow(10, nZeroes) / 2; - - // console.log(`zeros ${ nZeroes } tick-threshold ${ threshold } ticks ${ nMajorTicks } belowTick ${ StringUtils.numberFormatter(belowThresholdTick) } aboveTick ${ StringUtils.numberFormatter(aboveThresholdTick) }`) - - const majorTick = (nMajorTicks < threshold && isSVG !== true) ? belowThresholdTick : aboveThresholdTick; - - return new Tick(majorTick, majorUnit, unitMultiplier) -} - -function calculateDeltas(context, referenceFrame, bpStart, nTick, tick) { - - const tickDelta = getX(referenceFrame, getBP(1 + nTick, tick), bpStart) - getX(referenceFrame, getBP(nTick, tick), bpStart); - - const label = `${numberFormatter$1(Math.floor(getBP(nTick, tick) / tick.unitMultiplier))} ${tick.majorUnit}`; - const labelLength = Math.floor(context.measureText(label).width); - - return {tickDelta, labelLength} - - function getBP(nTick, tick) { - return Math.floor(nTick * tick.majorTick) - } - - function getX(referenceFrame, bp, bpStart) { - return Math.round(referenceFrame.toPixels((bp - 1) - bpStart + 0.5)) - } -} - -class Tick { - - constructor(majorTick, majorUnit, unitMultiplier) { - this.majorTick = majorTick; - this.minorTick = majorTick / 10.0; - this.majorUnit = majorUnit; - this.unitMultiplier = unitMultiplier; - } - - description(blurb) { - console.log((blurb || '') + ' tick ' + numberFormatter(this.majorTick) + ' label width ' + numberFormatter(this.labelWidthBP) + ' multiplier ' + this.unitMultiplier); - } -} - -/* - * The MIT License (MIT) - * - * Copyright (c) 2016 University of California San Diego - * Author: Jim Robinson - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -const CircularViewControl = function (parent, browser) { - - this.button = domUtils$1.div({class: 'igv-navbar-button'}); - parent.appendChild(this.button); - this.button.textContent = 'circular view'; - - this.button.addEventListener('click', () => { - browser.circularViewVisible = !browser.circularViewVisible; - //this.setState(browser.circularViewVisible) - }); - - this.browser = browser; - - this.setVisibility(browser.config.showCircularViewButton); - - this.setState(browser.circularViewVisible); - -}; - -CircularViewControl.prototype.setVisibility = function (showCircularViewButton) { - if (true === showCircularViewButton) { - this.show(); - } else { - this.hide(); - } -}; - -CircularViewControl.prototype.setState = function (circularViewVisible) { - if (true === circularViewVisible) { - this.button.classList.add('igv-navbar-button-clicked'); - } else { - this.button.classList.remove('igv-navbar-button-clicked'); - } -}; - -CircularViewControl.prototype.show = function () { - this.button.style.display = 'block'; - this.setState(this.browser.circularViewVisible); -}; - -CircularViewControl.prototype.hide = function () { - this.button.style.display = 'none'; -}; - -/** - * User supplied button for the navbar - */ - -const CustomButton = function (parent, browser, b) { - - const button = domUtils$1.div({class: 'igv-navbar-button'}); - parent.append(button); - button.textContent = b.label; - button.addEventListener('click', () => b.callback(browser)); -}; - -class ROIManager { - - constructor(browser, roiMenu, roiTable, top, roiSets) { - - this.browser = browser; - this.roiMenu = roiMenu; - this.roiTable = roiTable; - this.top = top; - this.roiSets = roiSets || []; - this.boundLocusChangeHandler = locusChangeHandler.bind(this); - browser.on('locuschange', this.boundLocusChangeHandler); - - } - - async initialize() { - - if (this.roiSets.length > 0) { - this.browser.showROITableButton = true; - this.browser.roiTableControl.setVisibility(this.browser.showROITableButton); - } - - const promises = this.roiSets.map(roiSet => this.renderROISet({ - browser: this.browser, - pixelTop: this.top, - roiSet - })); - - if (promises.length > 0) { - await Promise.all(promises); - } - - const records = await this.getTableRecords(); - this.roiTable.renderTable(records); - - } - - async loadROI(config, genome) { - - const configs = Array.isArray(config) ? config : [config]; - - for (let c of configs) { - this.roiSets.push(new ROISet(c, genome)); - } - - await this.initialize(); - - } - - clearROIs() { - - this.roiTable.clearTable(); - - const elements = this.browser.columnContainer.querySelectorAll('.igv-roi-region'); - for (let el of elements) { - el.remove(); - } - - for (let roiSet of this.roiSets) { - roiSet.dispose(); - } - - this.roiSets = []; - - } - - async getTableRecords() { - - const records = []; - - for (let roiSet of this.roiSets) { - const setName = roiSet.isUserDefined ? '' : (roiSet.name || ''); - const allFeatures = await roiSet.getAllFeatures(); - for (let chr of Object.keys(allFeatures)) { - for (let feature of allFeatures[chr]) { - records.push({setName, feature}); - } - } - } - - return records - } - - presentTable() { - this.roiTable.present(); - } - - async repaintTable() { - const records = await this.getTableRecords(); - this.roiTable.renderTable(records); - } - - dismissTable() { - this.roiTable.dismiss(); - } - - async updateUserDefinedROISet(feature) { - - let userDefinedROISet = await this.getUserDefinedROISet(); - - if (undefined === userDefinedROISet) { - userDefinedROISet = this.initializeUserDefinedROISet(); - } - - userDefinedROISet.addFeature(feature); - - if (false === this.browser.showROITableButton) { - this.setROITableButtonVisibility(true); - } - - await this.renderROISet({browser: this.browser, pixelTop: this.top, roiSet: userDefinedROISet}); - - const records = await this.getTableRecords(); - this.roiTable.renderTable(records); - } - - setROITableButtonVisibility(isVisible) { - this.browser.showROITableButton = isVisible; - this.browser.roiTableControl.setVisibility(this.browser.showROITableButton); - } - - async renderAllROISets() { - - for (let roiSet of this.roiSets) { - await this.renderROISet({browser: this.browser, pixelTop: this.top, roiSet}); - } - } - - async renderROISet({browser, pixelTop, roiSet}) { - - const columns = browser.columnContainer.querySelectorAll('.igv-column'); - - for (let i = 0; i < columns.length; i++) { - - let {chr, start: viewStart, end: viewEnd, bpPerPixel} = browser.referenceFrameList[i]; - - const elements = columns[i].querySelectorAll('.igv-roi-region'); - for (let el of elements) { - const regionKey = el.dataset.region; - const {chr: regionChr, start: regionStart, end: regionEnd} = parseRegionKey(regionKey); - if (regionChr !== chr || regionEnd < viewStart || regionStart > viewEnd) { - el.remove(); - } - } - - const features = await roiSet.getFeatures(chr, viewStart, viewEnd); - - if (features) { - - for (let feature of features) { - - const regionKey = createRegionKey(chr, feature.start, feature.end); - - const { - x: pixelX, - width: pixelWidth - } = screenCoordinates(Math.max(viewStart, feature.start), Math.min(viewEnd, feature.end), viewStart, bpPerPixel); - - - const el = columns[i].querySelector(createSelector(regionKey)); - - if (el) { - el.style.left = `${pixelX}px`; - el.style.width = `${pixelWidth}px`; - - } else { - const element = this.createRegionElement(browser.columnContainer, pixelTop, pixelX, pixelWidth, roiSet, regionKey, feature.name); - columns[i].appendChild(element); - } - } - } - } - } - - createRegionElement(columnContainer, pixelTop, pixelX, pixelWidth, roiSet, regionKey, name) { - - const regionElement = domUtils$1.div({class: 'igv-roi-region'}); - - regionElement.style.top = `${pixelTop}px`; - regionElement.style.left = `${pixelX}px`; - regionElement.style.width = `${pixelWidth}px`; - regionElement.style.backgroundColor = roiSet.color; - regionElement.dataset.region = regionKey; - - const header = domUtils$1.div(); - regionElement.appendChild(header); - - header.style.backgroundColor = roiSet.headerColor; - - if (true === roiSet.isUserDefined) { - header.addEventListener('click', event => { - event.preventDefault(); - event.stopPropagation(); - - const {x, y} = domUtils$1.translateMouseCoordinates(event, columnContainer); - this.roiMenu.present(x, y, this, columnContainer, regionElement); - }); - } else if (name) { - header.addEventListener('click', event => { - event.preventDefault(); - event.stopPropagation(); - if (this.popover) { - this.popover.dispose(); - } - this.popover = new Popover(columnContainer, roiSet.name); - this.popover.presentContentWithEvent(event, name); - }); - } else { - header.style.pointerEvents = 'none'; - } - - return regionElement - } - - renderSVGContext(context, {deltaX, deltaY}) { - - for (const regionElement of document.querySelectorAll('.igv-roi-region')) { - - // body - const { x, y, width, height } = regionElement.getBoundingClientRect(); - context.fillStyle = regionElement.style.backgroundColor; - context.fillRect(x+deltaX, y+deltaY, width, height); - - // header - const header = regionElement.querySelector('div'); - const { x:xx, y:yy, width:ww, height:hh } = header.getBoundingClientRect(); - context.fillStyle = header.style.backgroundColor; - context.fillRect(xx+deltaX, yy+deltaY, ww, hh); - } - } - - async getUserDefinedROISet() { - return this.roiSets.find(roiSet => true === roiSet.isUserDefined) - } - - initializeUserDefinedROISet() { - - const config = - { - isUserDefined: true, - features: [] - }; - const userDefinedROISet = new ROISet(config, this.browser.genome); - this.roiSets.push(userDefinedROISet); - - return userDefinedROISet - } - - async deleteUserDefinedRegionWithKey(regionKey, columnContainer) { - - columnContainer.querySelectorAll(createSelector(regionKey)).forEach(node => node.remove()); - - const feature = await this.findUserDefinedRegionWithKey(regionKey); - - const set = await this.getUserDefinedROISet(); - - if (set) { - set.removeFeature(feature); - } - - const records = await this.getTableRecords(); - - if (0 === records.length) { - this.browser.roiTableControl.buttonHandler(false); - this.setROITableButtonVisibility(false); - } - - } - - async findUserDefinedRegionWithKey(regionKey) { - - const {chr, start, end} = parseRegionKey(regionKey); - const set = await this.getUserDefinedROISet(); - - if (set) { - const features = await set.getFeatures(chr, start, end); - - for (let feature of features) { - if (feature.chr === chr && feature.start >= start && feature.end <= end) { - return feature - } - } - } - - return undefined - } - - toJSON() { - return this.roiSets.map(roiSet => roiSet.toJSON()) - } - - dispose() { - - this.browser.off('locuschange', this.boundLocusChangeHandler); - - const removable = this.browser.columnContainer.querySelectorAll('.igv-roi-region'); - - for (let el of removable) { - el.remove(); - } - - if (this.roiMenu) { - this.roiMenu.dispose(); - } - - if (this.roiTable) { - this.roiTable.dispose(); - } - - for (let roiSet of this.roiSets) { - roiSet.dispose(); - } - - for (let key of Object.keys(this)) { - this[key] = undefined; - } - - } -} - -function locusChangeHandler() { - this.renderAllROISets(); -} - -function createRegionKey(chr, start, end) { - return `${chr}-${start}-${end}` -} - -function createSelector(regionKey) { - return `[data-region="${regionKey}"]` -} - -function parseRegionKey(regionKey) { - let [chr, ss, ee] = regionKey.split('-'); - ss = parseInt(ss); - ee = parseInt(ee); - - return {chr, start: ss, end: ee, locus: `${chr}:${ss}-${ee}`, bedRecord: `${chr}\t${ss}\t${ee}`} -} - -class ROITable extends RegionTableBase { - constructor(config) { - - const cooked = Object.assign({ 'width':'512px' }, config); - super(cooked); - } - - tableRowDOM(record) { - - const dom = domUtils$1.div({ class: 'igv-roi-table-row' }); - - const { setName, feature } = record; - dom.dataset.region = createRegionKey(feature.chr, feature.start, feature.end); - - let strings = - [ - feature.chr, - numberFormatter$1(feature.start), - numberFormatter$1(feature.end), - feature.name || '', - setName - ]; - - if (4 === this.columnFormat.length) { - strings = strings.slice(0, 4); - } - - for (let i = 0; i < strings.length; i++) { - const el = domUtils$1.div(); - dom.appendChild(el); - el.style.width = this.columnFormat[ i ].width; - el.innerText = strings[ i ]; - } - - this.tableRowDOMHelper(dom); - - return dom - } - - renderTable(records) { - - Array.from(this.tableRowContainer.querySelectorAll('.igv-roi-table-row')).forEach(el => el.remove()); - - if (records.length > 0) { - - const sortedRecords = records.sort((a, b) => (a.feature.chr.localeCompare(b.feature.chr) || a.feature.start - b.feature.start || a.feature.end - b.feature.end)); - - for (let record of sortedRecords) { - const row = this.tableRowDOM(record); - this.tableRowContainer.appendChild(row); - } - - } - } - - dispose() { - - document.removeEventListener('click', this.boundGotoButtonHandler); - - this.browser.roiTableControl.buttonHandler(false); - super.dispose(); - } - - static getColumnFormatConfiguration(doIncludeROISetNames) { - - if (true === doIncludeROISetNames) { - - return [ - { label: 'Chr', width: '20%' }, - { label: 'Start', width: '15%' }, - { label: 'End', width: '15%' }, - { label: 'Description', width: '30%' }, - { label: 'ROI Set', width: '20%' } - ] - } else { - return [ - { label: 'Chr', width: '25%' }, - { label: 'Start', width: '20%' }, - { label: 'End', width: '20%' }, - { label: 'Description', width: '35%' } - ] - } - - } - - static gotoButtonHandler (event) { - - event.stopPropagation(); - - const selected = this.tableDOM.querySelectorAll('.igv-roi-table-row-selected'); - const loci = []; - for (let el of selected) { - const { locus } = parseRegionKey(el.dataset.region); - loci.push(locus); - } - - for (let el of this.tableDOM.querySelectorAll('.igv-roi-table-row')) { - el.classList.remove('igv-roi-table-row-selected'); - } - - this.setTableRowSelectionState(false); - - if (loci.length > 0) { - this.browser.search(loci.join(' ')); - } - - } - -} - -class ROIMenu { - constructor(browser, parent) { - - this.browser = browser; - - // container - this.container = domUtils$1.div({ class: 'igv-roi-menu-next-gen' }); - parent.appendChild(this.container); - - // header - const header = domUtils$1.div(); - this.container.appendChild(header); - - uiUtils$1.attachDialogCloseHandlerWithParent(header, () => this.container.style.display = 'none'); - - // body - this.body = domUtils$1.div(); - this.container.appendChild(this.body); - - this.container.style.display = 'none'; - - } - - async present(x, y, roiManager, columnContainer, regionElement) { - - removeAllChildNodes(this.body); - - const feature = await this.browser.roiManager.findUserDefinedRegionWithKey(regionElement.dataset.region); - - // Description Copy - const _description_copy_ = domUtils$1.div(); - this.body.appendChild(_description_copy_); - - const placeholder = 'Description'; - const str = (feature.name || placeholder); - - _description_copy_.innerText = str; - _description_copy_.setAttribute('title', str); - placeholder === str ? _description_copy_.classList.add('igv-roi-placeholder') : _description_copy_.classList.remove('igv-roi-placeholder'); - - - // Set Description - const description = domUtils$1.div(); - this.body.appendChild(description); - description.innerText = 'Set Description'; - - description.addEventListener('click', event => { - - event.stopPropagation(); - - this.container.style.display = 'none'; - - const callback = () => { - - const value = this.browser.inputDialog.value || ''; - feature.name = value.trim(); - - this.container.style.display = 'none'; - - this.browser.roiManager.repaintTable(); - }; - - const config = - { - label: 'Description', - value: (feature.name || ''), - callback - }; - - this.browser.inputDialog.present(config, event); - - }); - - - // Delete Region - const _delete_ = domUtils$1.div(); - this.body.appendChild(_delete_); - _delete_.innerText = 'Delete Region'; - - _delete_.addEventListener('click', event => { - event.stopPropagation(); - this.container.style.display = 'none'; - this.browser.roiManager.deleteUserDefinedRegionWithKey(regionElement.dataset.region, this.browser.columnContainer); - }); - - - - - - - - // columnContainer.addEventListener('click', event => { - // event.stopPropagation() - // this.container.style.display = 'none' - // }) - - this.container.style.left = `${ x }px`; - this.container.style.top = `${ y }px`; - this.container.style.display = 'flex'; - - } - - async __present(x, y, roiManager, columnContainer, regionElement) { - - removeAllChildNodes(this.container); - - const feature = await this.browser.roiManager.findUserDefinedRegionWithKey(regionElement.dataset.region); - - let row; - - // Go To - // row = DOMUtils.div({ class: 'igv-roi-menu-row' }) - // row.innerText = 'Go To' - // this.container.appendChild(row) - // - // row.addEventListener('click', event => { - // event.stopPropagation() - // this.container.style.display = 'none' - // - // const { locus } = parseRegionKey(regionElement.dataset.region) - // this.browser.search(locus) - // }) - - // Description: - row = domUtils$1.div({ class: 'igv-roi-menu-row-edit-description' }); - this.container.appendChild(row); - - row.addEventListener('click', e => { - e.stopPropagation(); - }); - - const str = 'description-input'; - - const label = document.createElement('label'); - row.appendChild(label); - - label.setAttribute('for', str); - label.innerText = 'Description:'; - - const input = document.createElement('input'); - row.appendChild(input); - - input.setAttribute('type', 'text'); - input.setAttribute('name', str); - // input.setAttribute('placeholder', feature.name || 'Edit Description') - input.setAttribute('placeholder', ''); - input.value = feature.name || ''; - - input.addEventListener('change', async e => { - - e.stopPropagation(); - - const feature = await this.browser.roiManager.findUserDefinedRegionWithKey(regionElement.dataset.region); - feature.name = input.value; - - input.blur(); - this.container.style.display = 'none'; - - await this.browser.roiManager.repaintTable(); - }); - - - // Delete - row = domUtils$1.div({ class: 'igv-roi-menu-row' }); - row.innerText = 'Delete region'; - this.container.appendChild(row); - - row.addEventListener('click', event => { - event.stopPropagation(); - this.container.style.display = 'none'; - this.browser.roiManager.deleteUserDefinedRegionWithKey(regionElement.dataset.region, this.browser.columnContainer); - }); - - this.container.style.left = `${ x }px`; - this.container.style.top = `${ y }px`; - this.container.style.display = 'flex'; - - columnContainer.addEventListener('click', event => { - event.stopPropagation(); - this.container.style.display = 'none'; - }); - - } - - dispose() { - this.container.innerHTML = ''; - } - -} - -function removeAllChildNodes(parent) { - while (parent.firstChild) { - parent.removeChild(parent.firstChild); - } -} - -class TrackROISet { - - constructor(config, genome) { - this.name = config.name; - this.featureSource = config.featureSource || FeatureSource(config, genome); - this.color = config.color || ROI_DEFAULT_COLOR; - } - - async getFeatures(chr, start, end) { - return this.featureSource.getFeatures({chr, start, end}) - } - - draw(drawConfiguration) { - - const { context, bpPerPixel, bpStart, pixelTop, pixelHeight, pixelWidth, features, } = drawConfiguration; - - if (!features) { - return - } - - const bpEnd = bpStart + (pixelWidth * bpPerPixel) + 1; - for (let { start:regionStartBP, end:regionEndBP } of features) { - - if (regionEndBP < bpStart) { - continue - } - - if (regionStartBP > bpEnd) { - break - } - - const { x, width } = screenCoordinates(regionStartBP, regionEndBP, bpStart, bpPerPixel); - IGVGraphics.fillRect(context, x, pixelTop, width, pixelHeight, { fillStyle: this.color }); - } - } -} - -/* - * The MIT License (MIT) - * - * Copyright (c) 2016 University of California San Diego - * Author: Jim Robinson - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -class ROITableControl { - - constructor(parent, browser) { - this.browser = browser; - this.button = domUtils$1.div({class: 'igv-navbar-button'}); - parent.appendChild(this.button); - this.button.textContent = 'ROI Table'; - - this.button.addEventListener('click', () => { - this.buttonHandler(!browser.roiTableVisible); - }); - - this.browser = browser; - - this.setVisibility(browser.showROITableButton); - - this.setState(browser.roiTableVisible); - } - - buttonHandler(status) { - this.browser.roiTableVisible = status; - this.setState(this.browser.roiTableVisible); - this.browser.setROITableVisibility(this.browser.roiTableVisible); - } - - setVisibility(doShowROITablelButton) { - if (true === doShowROITablelButton) { - this.show(); - } else { - this.hide(); - } - } - - setState(roiTableVisible) { - if (true === roiTableVisible) { - this.button.classList.add('igv-navbar-button-clicked'); - } else { - this.button.classList.remove('igv-navbar-button-clicked'); - } - } - - show() { - this.button.style.display = 'block'; - this.setState(this.browser.roiTableVisible); - } - - hide() { - this.button.style.display = 'none'; - } -} - -// css - $igv-scrollbar-outer-width: 14px; -const igv_scrollbar_outer_width = 14; - -// css - $igv-track-drag-column-width: 12px; -const igv_track_manipulation_handle_width = 12; - -// css - $igv-track-gear-menu-column-width: 28px; -const igv_track_gear_menu_column_width = 28; - -// $igv-column-shim-width: 1px; -// $igv-column-shim-margin: 2px; -const column_multi_locus_shim_width = 2 + 1 + 2; - -const defaultSampleNameViewportWidth = 200; - -class Browser { - - constructor(config, parentDiv) { - - this.config = config; - this.guid = domUtils$1.guid(); - this.namespace = '.browser_' + this.guid; - - this.parent = parentDiv; - - this.root = domUtils$1.div({class: 'igv-container'}); - parentDiv.appendChild(this.root); - - this.alert = new Alert$2(this.root); - - this.columnContainer = domUtils$1.div({class: 'igv-column-container'}); - this.root.appendChild(this.columnContainer); - - this.menuPopup = new MenuPopup(this.columnContainer); - - this.initialize(config); - - this.trackViews = []; - - this.constants = { - dragThreshold: 3, - scrollThreshold: 5, - defaultColor: "rgb(0,0,150)", - doubleClickDelay: config.doubleClickDelay || 500 - }; - - // Map of event name -> [ handlerFn, ... ] - this.eventHandlers = {}; - - this.addMouseHandlers(); - - this.setControls(config); - } - - initialize(config) { - - if (config.gtex) { - GtexUtils.gtexLoaded = true; - } - this.flanking = config.flanking; - this.crossDomainProxy = config.crossDomainProxy; - this.formats = config.formats; - this.trackDefaults = config.trackDefaults; - this.nucleotideColors = config.nucleotideColors || defaultNucleotideColors; - for (let key of Object.keys(this.nucleotideColors)) { - this.nucleotideColors[key.toLowerCase()] = this.nucleotideColors[key]; - } - - this.trackLabelsVisible = config.showTrackLabels; - - this.roiTableVisible = config.showROITable; - this.showROITableButton = config.showROITableButton; - - this.isCenterLineVisible = config.showCenterGuide; - - this.cursorGuideVisible = config.showCursorGuide; - - this.showSampleNames = config.showSampleNames; - this.showSampleNameButton = config.showSampleNameButton; - this.sampleNameViewportWidth = config.sampleNameViewportWidth || defaultSampleNameViewportWidth; - - if (config.search) { - this.searchConfig = { - type: "json", - url: config.search.url, - coords: config.search.coords === undefined ? 1 : config.search.coords, - chromosomeField: config.search.chromosomeField || "chromosome", - startField: config.search.startField || "start", - endField: config.search.endField || "end", - geneField: config.search.geneField || "gene", - snpField: config.search.snpField || "snp", - resultsField: config.search.resultsField - }; - } - } - - setControls(config) { - - const $navBar = this.createStandardControls(config); - $navBar.insertBefore($$1(this.columnContainer)); - this.$navigation = $navBar; - - if (false === config.showControls) { - $navBar.hide(); - } - - } - - createStandardControls(config) { - - this.navbarManager = new NavbarManager(this); - - const $navBar = $$1('
', {class: 'igv-navbar'}); - this.$navigation = $navBar; - - const $navbarLeftContainer = $$1('
', {class: 'igv-navbar-left-container'}); - $navBar.append($navbarLeftContainer); - - // IGV logo - const $logo = $$1('
', {class: 'igv-logo'}); - $navbarLeftContainer.append($logo); - - const logoSvg = logo(); - logoSvg.css("width", "34px"); - logoSvg.css("height", "32px"); - $logo.append(logoSvg); - - this.$current_genome = $$1('
', {class: 'igv-current-genome'}); - $navbarLeftContainer.append(this.$current_genome); - this.$current_genome.text(''); - - const $genomicLocation = $$1('
', {class: 'igv-navbar-genomic-location'}); - $navbarLeftContainer.append($genomicLocation); - - // chromosome select widget - this.chromosomeSelectWidget = new ChromosomeSelectWidget(this, $genomicLocation.get(0)); - if (undefined === config.showChromosomeWidget) { - config.showChromosomeWidget = true; // Default to true - } - if (true === config.showChromosomeWidget) { - this.chromosomeSelectWidget.show(); - } else { - this.chromosomeSelectWidget.hide(); - } - - const $locusSizeGroup = $$1('
', {class: 'igv-locus-size-group'}); - $genomicLocation.append($locusSizeGroup); - - const $searchContainer = $$1('
', {class: 'igv-search-container'}); - $locusSizeGroup.append($searchContainer); - - // browser.$searchInput = $(''); - this.$searchInput = $$1('', {class: 'igv-search-input', type: 'text', placeholder: 'Locus Search'}); - $searchContainer.append(this.$searchInput); - - this.$searchInput.change(() => this.doSearch(this.$searchInput.val())); - - const searchIconContainer = domUtils$1.div({class: 'igv-search-icon-container'}); - $searchContainer.append($$1(searchIconContainer)); - - searchIconContainer.appendChild(icons$1$1.createIcon("search")); - - searchIconContainer.addEventListener('click', () => this.doSearch(this.$searchInput.val())); - - this.windowSizePanel = new WindowSizePanel($locusSizeGroup.get(0), this); - - const $navbarRightContainer = $$1('
', {class: 'igv-navbar-right-container'}); - $navBar.append($navbarRightContainer); - - const $toggle_button_container = $$1('
'); - $navbarRightContainer.append($toggle_button_container); - this.$toggle_button_container = $toggle_button_container; - - this.cursorGuide = new CursorGuide(this.columnContainer, this); - - this.cursorGuideButton = new CursorGuideButton(this, $toggle_button_container.get(0)); - - this.centerLineButton = new CenterLineButton(this, $toggle_button_container.get(0)); - - this.setTrackLabelVisibility(config.showTrackLabels); - this.trackLabelControl = new TrackLabelControl($toggle_button_container.get(0), this); - - // ROI Control - this.roiTableControl = new ROITableControl($toggle_button_container.get(0), this); - - this.sampleNameControl = new SampleNameControl($toggle_button_container.get(0), this); - - if (true === config.showSVGButton) { - this.svgSaveControl = new SVGSaveControl($toggle_button_container.get(0), this); - } - - if (config.customButtons) { - for (let b of config.customButtons) { - new CustomButton($toggle_button_container.get(0), this, b); - } - } - - this.zoomWidget = new ZoomWidget(this, $navbarRightContainer.get(0)); - - if (false === config.showNavigation) { - this.$navigation.hide(); - } - - this.inputDialog = new InputDialog$1(this.root); - this.inputDialog.container.id = `igv-input-dialog-${domUtils$1.guid()}`; - - this.dataRangeDialog = new DataRangeDialog$1(this, $$1(this.root)); - this.dataRangeDialog.$container.get(0).id = `igv-data-range-dialog-${domUtils$1.guid()}`; - - this.genericColorPicker = new GenericColorPicker({parent: this.columnContainer, width: 432}); - this.genericColorPicker.container.id = `igv-track-color-picker-${domUtils$1.guid()}`; - - return $navBar - - } - - getSampleNameViewportWidth() { - return false === this.showSampleNames ? 0 : this.sampleNameViewportWidth - } - - isMultiLocusMode() { - return this.referenceFrameList && this.referenceFrameList.length > 1 - }; - - addTrackToFactory(name, track) { - TrackFactory.addTrack(name, track); - } - - isMultiLocusWholeGenomeView() { - - if (undefined === this.referenceFrameList || 1 === this.referenceFrameList.length) { - return false - } - - for (let referenceFrame of this.referenceFrameList) { - if ('all' === referenceFrame.chr.toLowerCase()) { - return true - } - } - - return false - }; - - /** - * PUBLIC API FUNCTION - * - * Return the current genomic region as a locus string, or array of locus strings if in multi-locus view - * @returns {string|*[]|*} - */ - currentLoci() { - const noCommaLocusString = (rf) => `${rf.chr}:${rf.start + 1}-${rf.end}`; - if (undefined === this.referenceFrameList || 0 === this.referenceFrameList.length) { - return "" - } else if (1 === this.referenceFrameList.length) { - return noCommaLocusString(this.referenceFrameList[0]) - } else { - return this.referenceFrameList.map(rf => noCommaLocusString(rf)) - } - } - - /** - * Render browse display as SVG - * @returns {string} - */ - toSVG() { - - const {y, width, height} = this.columnContainer.getBoundingClientRect(); - - const h_render = 8000; - - const config = - { - - width, - height: h_render, - - backdropColor: 'white', - - multiLocusGap: 0, - - viewbox: - { - x: 0, - y: 0, - width, - height: h_render - } - - }; - - const context = new ctx(config); - - // tracks -> SVG - const delta = {deltaX: 0, deltaY: -y}; - for (let trackView of this.trackViews) { - trackView.renderSVGContext(context, delta); - } - - this.roiManager.renderSVGContext(context, delta); - - // reset height to trim away unneeded svg canvas real estate. Yes, a bit of a hack. - context.setHeight(height); - - return context.getSerializedSvg(true) - - } - - renderSVG($container) { - const svg = this.toSVG(); - $container.empty(); - $container.append(svg); - - return svg - } - - saveSVGtoFile(config) { - - let svg = this.toSVG(); - - if (config.$container) { - config.$container.empty(); - config.$container.append(svg); - } - - const path = config.filename || 'igvjs.svg'; - const data = URL.createObjectURL(new Blob([svg], {type: "application/octet-stream"})); - download(path, data); - } - - /** - * Initialize a session from an object, json, or by loading from a file. - * - * TODO Really should be split into at least 2 functions, load from file and load from object/json - * - * @param options - * @returns {*} - */ - async loadSession(options) { - - // TODO: depricated - this.roiSets = []; - - let session; - if (options.url || options.file) { - session = await loadSessionFile(options); - } else { - session = options; - } - return this.loadSessionObject(session) - - - async function loadSessionFile(options) { - - const urlOrFile = options.url || options.file; - - if (options.url && (options.url.startsWith("blob:") || options.url.startsWith("data:"))) { - const json = Browser.uncompressSession(options.url); - return JSON.parse(json) - - } else { - let filename = options.filename; - if (!filename) { - filename = (options.url ? await getFilename$1(options.url) : options.file.name); - } - - if (filename.endsWith(".xml")) { - - const knownGenomes = GenomeUtils.KNOWN_GENOMES; - const string = await igvxhr.loadString(urlOrFile); - return new XMLSession(string, knownGenomes) - - } else if (filename.endsWith(".json")) { - return igvxhr.loadJson(urlOrFile) - } else { - return undefined - } - } - } - } - - - /** - * Note: public API function - * @param session - * @returns {Promise} - */ - async loadSessionObject(session) { - - // prepare to load a new session, discarding DOM and state - this.cleanHouseForSession(); - - this.showSampleNames = session.showSampleNames || false; - this.sampleNameControl.setState(this.showSampleNames === true); - - if (session.sampleNameViewportWidth) { - this.sampleNameViewportWidth = session.sampleNameViewportWidth; - } - - // axis column - createColumn(this.columnContainer, 'igv-axis-column'); - - // SampleName column - createColumn(this.columnContainer, 'igv-sample-name-column'); - - // Track scrollbar column - createColumn(this.columnContainer, 'igv-scrollbar-column'); - - // Track drag/reorder column - createColumn(this.columnContainer, 'igv-track-drag-column'); - - // Track gear column - createColumn(this.columnContainer, 'igv-gear-menu-column'); - - const genomeOrReference = session.reference || session.genome; - if(!genomeOrReference) { - console.warn("No genome or reference object specified"); - return; - } - const genomeConfig = await GenomeUtils.expandReference(this.alert, genomeOrReference); - - - await this.loadReference(genomeConfig, session.locus); - - this.centerLineList = this.createCenterLineList(this.columnContainer); - - // Create ideogram and ruler track. Really this belongs in browser initialization, but creation is - // deferred because ideogram and ruler are treated as "tracks", and tracks require a reference frame - let ideogramHeight = 0; - if (false !== session.showIdeogram) { - - const track = new IdeogramTrack(this); - track.id = 'ideogram'; - - const trackView = new TrackView(this, this.columnContainer, track); - const {$viewport} = trackView.viewports[0]; - ideogramHeight = getElementAbsoluteHeight($viewport.get(0)); - - this.trackViews.push(trackView); - } - - if (false !== session.showRuler) { - this.trackViews.push(new TrackView(this, this.columnContainer, new RulerTrack(this))); - } - - // Restore gtex selections. - if (session.gtexSelections) { - for (let referenceFrame of this.referenceFrameList) { - for (let s of Object.keys(session.gtexSelections)) { - const gene = session.gtexSelections[s].gene; - const snp = session.gtexSelections[s].snp; - referenceFrame.selection = new GtexSelection(gene, snp); - } - } - } - - if (this.roiManager) { - this.roiManager.dispose(); - } - - const roiMenu = new ROIMenu(this, this.columnContainer); - const roiTableConfig = - { - browser: this, - parent: this.columnContainer, - headerTitle: 'Regions of Interest', - dismissHandler: () => this.roiTableControl.buttonHandler(false), - gotoButtonHandler: ROITable.gotoButtonHandler - }; - if (session.roi) { - - const roiSetList = session.roi.map(c => new ROISet(c, this.genome)); - - const named = roiSetList.filter(({name}) => name !== undefined && name.length > 0); - - roiTableConfig.columnFormat = ROITable.getColumnFormatConfiguration(named.length > 0); - - const roiTable = new ROITable(roiTableConfig); - - this.roiManager = new ROIManager(this, roiMenu, roiTable, ideogramHeight, roiSetList); - } else { - - roiTableConfig.columnFormat = ROITable.getColumnFormatConfiguration(false); - - const roiTable = new ROITable(roiTableConfig); - - this.roiManager = new ROIManager(this, roiMenu, roiTable, ideogramHeight, undefined); - } - - await this.roiManager.initialize(); - - // Tracks. Start with genome tracks, if any, then append session tracks - const genomeTracks = genomeConfig.tracks || []; - const trackConfigurations = session.tracks ? genomeTracks.concat(session.tracks) : genomeTracks; - - // Ensure that we always have a sequence track with no explicit URL (=> the reference genome sequence track) - const pushSequenceTrack = trackConfigurations.filter(track => 'sequence' === track.type && !track.url && !track.fastaURL).length === 0; - if (pushSequenceTrack /*&& false !== this.config.showSequence*/) { - trackConfigurations.push({type: "sequence", order: defaultSequenceTrackOrder}); - } - - // Maintain track order unless explicitly set - let trackOrder = 1; - for (let t of trackConfigurations) { - if (undefined === t.order) { - t.order = trackOrder++; - } - } - - await this.loadTrackList(trackConfigurations); - - // The ruler and ideogram tracks are not explicitly loaded, but needs updated nonetheless. - for (let rtv of this.trackViews.filter((tv) => tv.track.type === 'ruler' || tv.track.type === 'ideogram')) { - rtv.updateViews(); - } - - this.updateUIWithReferenceFrameList(); - - } - - createCenterLineList(columnContainer) { - - const centerLines = columnContainer.querySelectorAll('.igv-center-line'); - for (let i = 0; i < centerLines.length; i++) { - centerLines[i].remove(); - } - - const centerLineList = []; - const viewportColumns = columnContainer.querySelectorAll('.igv-column'); - for (let i = 0; i < viewportColumns.length; i++) { - centerLineList.push(new ViewportCenterLine(this, this.referenceFrameList[i], viewportColumns[i])); - } - - return centerLineList - } - - /** - * Load a reference genome object. This includes the fasta, and optional cytoband, but no tracks. This method - * is used by loadGenome and loadSession. - * - * @param genomeConfig - * @param initialLocus - */ - async loadReference(genomeConfig, initialLocus) { - - const genome = await GenomeUtils.loadGenome(genomeConfig); - - const genomeChange = undefined === this.genome || (this.genome.id !== genome.id); - - this.genome = genome; - - this.updateNavbarDOMWithGenome(genome); - - if (genomeChange) { - this.removeAllTracks(); - } - - let locus = getInitialLocus(initialLocus, genome); - const locusFound = await this.search(locus, true); - if (!locusFound) { - console.log("Initial locus not found: " + locus); - locus = genome.getHomeChromosomeName(); - const locusFound = await this.search(locus, true); - if (!locusFound) { - throw new Error("Cannot set initial locus") - } - } - - if (genomeChange && this.circularView) { - this.circularView.setAssembly({ - name: this.genome.id, - id: this.genome.id, - chromosomes: makeCircViewChromosomes(this.genome) - }); - } - } - - cleanHouseForSession() { - - for (let trackView of this.trackViews) { - // empty axis column, viewport columns, sampleName column, scroll column, drag column, gear column - trackView.removeDOMFromColumnContainer(); - } - - // discard all columns - const elements = this.columnContainer.querySelectorAll('.igv-axis-column, .igv-column-shim, .igv-column, .igv-sample-name-column, .igv-scrollbar-column, .igv-track-drag-column, .igv-gear-menu-column'); - elements.forEach(column => column.remove()); - - this.trackViews = []; - - if (this.circularView) { - this.circularView.clearChords(); - } - - } - - updateNavbarDOMWithGenome(genome) { - - // If the genome is defined directly from a fasta file or data url the "id" will be the full url. Don't display - // this. - let genomeLabel = (genome.id && genome.id.length < 10 ? genome.id : ''); - this.$current_genome.text(genomeLabel); - this.$current_genome.attr('title', genome.id || ''); - this.chromosomeSelectWidget.update(genome); - } - - /** - * Load a genome, defined by a string ID or a json-like configuration object. This includes a fasta reference - * as well as optional cytoband and annotation tracks. - * - * @param idOrConfig - * @returns genome - */ - async loadGenome(idOrConfig) { - - const genomeConfig = await GenomeUtils.expandReference(this.alert, idOrConfig); - await this.loadReference(genomeConfig, undefined); - - const tracks = genomeConfig.tracks || []; - - // Insure that we always have a sequence track - const pushSequenceTrack = tracks.filter(track => track.type === 'sequence').length === 0; - if (pushSequenceTrack) { - tracks.push({type: "sequence", order: defaultSequenceTrackOrder}); - } - - await this.loadTrackList(tracks); - - await this.updateViews(); - - return this.genome - } - - /** - * Called after a session load, search, pan (horizontal drag), or resize - * - * @param referenceFrameList - */ - updateUIWithReferenceFrameList() { - - const referenceFrameList = this.referenceFrameList; - - this.updateLocusSearchWidget(); - - const isWGV = (this.isMultiLocusWholeGenomeView() || GenomeUtils.isWholeGenomeView(referenceFrameList[0].chr)); - - this.navbarManager.navbarDidResize(this.$navigation.width(), isWGV); - - toggleTrackLabels(this.trackViews, this.trackLabelsVisible); - - this.setCenterLineAndCenterLineButtonVisibility(!GenomeUtils.isWholeGenomeView(referenceFrameList[0].chr)); - - } - - setTrackLabelVisibility(isVisible) { - toggleTrackLabels(this.trackViews, isVisible); - } - - setROITableVisibility(isVisible) { - true === isVisible ? this.roiManager.presentTable() : this.roiManager.dismissTable(); - } - - // cursor guide - setCursorGuideVisibility(cursorGuideVisible) { - - if (cursorGuideVisible) { - this.cursorGuide.show(); - } else { - this.cursorGuide.hide(); - } - } - - setCustomCursorGuideMouseHandler(mouseHandler) { - this.cursorGuide.customMouseHandler = mouseHandler; - } - - // center line - setCenterLineVisibility(isCenterLineVisible) { - for (let centerLine of this.centerLineList) { - if (true === isCenterLineVisible) { - centerLine.show(); - centerLine.repaint(); - } else { - centerLine.hide(); - } - } - } - - setCenterLineAndCenterLineButtonVisibility(isCenterLineVisible) { - - for (let centerLine of this.centerLineList) { - const isShown = isCenterLineVisible && centerLine.isVisible; - isShown ? centerLine.show() : centerLine.container.style.display = 'none'; - } - - const isShown = isCenterLineVisible && this.centerLineButton.isVisible; - isShown ? this.centerLineButton.show() : this.centerLineButton.button.style.display = 'none'; - - } - - /** - * Public API function. Load a list of tracks. - * - * @param configList Array of track configurations - * @returns {Promise<*>} Promise for track objects - */ - async loadTrackList(configList) { - - const promises = []; - for (let config of configList) { - promises.push(this._loadTrack(config)); - } - - const loadedTracks = await Promise.all(promises); - const groupAutoscaleViews = this.trackViews.filter(function (trackView) { - return trackView.track.autoscaleGroup - }); - if (groupAutoscaleViews.length > 0) { - this.updateViews(); - } - return loadedTracks - } - - /** - * Public API function - * - * Load an individual track. If part of an autoscale group force a general update - * - * @param config A track configuration - * @returns {Promise<*>} Promise for track object - */ - async loadTrack(config) { - - const newTrack = this._loadTrack(config); - - if (config.autoscaleGroup) { - // Await newTrack load and update all views - await newTrack; - this.updateViews(); - } - - return newTrack - } - - /** - * Return a promise to load a track. Private function used by loadTrack() and loadTrackList() - * - * @param config - * @returns {*} - */ - - async _loadTrack(config) { - - // config might be json - if (isString$2(config)) { - config = JSON.parse(config); - } - - try { - - const newTrack = await this.createTrack(config); - - if (undefined === newTrack) { - return - } - - // Set order field of track here. Otherwise track order might get shuffled during asynchronous load - if (undefined === newTrack.order) { - newTrack.order = this.trackViews.length; - } - - const trackView = new TrackView(this, this.columnContainer, newTrack); - this.trackViews.push(trackView); - toggleTrackLabels(this.trackViews, this.trackLabelsVisible); - this.reorderTracks(); - this.fireEvent('trackorderchanged', [this.getTrackOrder()]); - - if (typeof newTrack.postInit === 'function') { - try { - trackView.startSpinner(); - await newTrack.postInit(); - } finally { - trackView.stopSpinner(); - } - } - - if (!newTrack.autoscaleGroup) { - // Group autoscale will get updated later (as a group) - if (config.sync) { - await trackView.updateViews(); - } else { - trackView.updateViews(); - } - } - - if (typeof newTrack.hasSamples === 'function' && newTrack.hasSamples()) { - if (this.config.showSampleNameButton !== false) { - this.sampleNameControl.show(); // If not explicitly set - } - } - - return newTrack - - } catch (error) { - const httpMessages = - { - "401": "Access unauthorized", - "403": "Access forbidden", - "404": "Not found" - }; - console.error(error); - let msg = error.message || error.error || error.toString(); - if (httpMessages.hasOwnProperty(msg)) { - msg = httpMessages[msg]; - } - msg += (": " + config.url); - this.alert.present(new Error(msg), undefined); - } - } - - /** - * Public API function - load a region of interest - * - * @param config A "track" configuration object, or array of objects, of type == "annotation" (bed, gff, etc) - * - * @returns {Promise} - */ - async loadROI(config) { - await this.roiManager.loadROI(config, this.genome); - } - - /** - * Public API function - clear all regions of interest (ROI), including preloaded and user-defined ROIs - */ - clearROIs() { - this.roiManager.clearROIs(); - } - - /** - * Public API function. Return a promise for the list of user-defined regions-of-interest - */ - async getUserDefinedROIs() { - - if (this.roiManager) { - - const set = await this.roiManager.getUserDefinedROISet(); - if (undefined === set) { - return [] - } - - const featureHash = await set.getAllFeatures(); - const featureList = []; - for (let value of Object.values(featureHash)) { - featureList.push(...value); - } - - return featureList - - } else { - return [] - } - } - - getRulerTrackView() { - const list = this.trackViews.filter(({track}) => 'ruler' === track.id); - return list.length > 0 ? list[0] : undefined - } - - /** - * Create a Track object. - * @param config - * @returns {Promise<*>} - */ - async createTrack(config) { - - // Resolve function and promise urls - let url = await resolveURL(config.url || config.fastaURL); - if (isString$2(url)) { - url = url.trim(); - } - - if (url) { - if (config.format) { - config.format = config.format.toLowerCase(); - } else if (config.fastaURL) { - config.format = "fasta"; // by definition - } else { - let filename = config.filename; - if (!filename) { - filename = await getFilename$1(url); - } - - const format = inferFileFormat(filename); - - if ("tsv" === format) { - config.format = await inferFileFormatFromHeader(config); - } else if (format) { - config.format = format; - } else { - if (config.sourceType === "htsget") { - // Check for htsget URL. This is a longshot - await HtsgetReader.inferFormat(config); - } - } - } - } - - - let type = config.type ? config.type.toLowerCase() : undefined; - - if (!type) { - type = inferTrackType(config); - if ("bedtype" === type) { - // Bed files must be read to determine track type - const featureSource = FeatureSource(config, this.genome); - config._featureSource = featureSource; // This is a temp variable, bit of a hack - const trackType = await featureSource.trackType(); - if (trackType) { - type = trackType; - } else { - type = "annotation"; - } - } - // Record in config to make type persistent in session - config.type = type; - } - - // Set defaults if specified - if (this.trackDefaults && type) { - const settings = this.trackDefaults[type]; - if (settings) { - for (let property in settings) { - if (settings.hasOwnProperty(property) && config[property] === undefined) { - config[property] = settings[property]; - } - } - } - } - - const track = TrackFactory.getTrack(type, config, this); - if (undefined === track) { - this.alert.present(new Error(`Error creating track. Could not determine track type for file: ${config.url || config}`), undefined); - } else { - - if (config.roi && config.roi.length > 0) { - track.roiSets = config.roi.map(r => new TrackROISet(r, this.genome)); - } - - return track - } - } - - - reorderTracks() { - - this.trackViews.sort(function (a, b) { - - const firstSortOrder = tv => { - return 'ideogram' === tv.track.id ? 1 : - 'ruler' === tv.track.id ? 2 : - 3 - }; - - const aOrder1 = firstSortOrder(a); - const bOrder1 = firstSortOrder(b); - if (aOrder1 === bOrder1) { - const aOrder2 = a.track.order || 0; - const bOrder2 = b.track.order || 0; - return aOrder2 - bOrder2 - } else { - return aOrder1 - bOrder1 - } - }); - - // discard current track order - for (let {axis, viewports, sampleNameViewport, outerScroll, dragHandle, gearContainer} of this.trackViews) { - - axis.remove(); - - for (let {$viewport} of viewports) { - $viewport.detach(); - } - - sampleNameViewport.viewport.remove(); - - outerScroll.remove(); - dragHandle.remove(); - gearContainer.remove(); - } - - // Reattach the divs to the dom in the correct order - const viewportColumns = this.columnContainer.querySelectorAll('.igv-column'); - - for (let {axis, viewports, sampleNameViewport, outerScroll, dragHandle, gearContainer} of this.trackViews) { - - this.columnContainer.querySelector('.igv-axis-column').appendChild(axis); - - for (let i = 0; i < viewportColumns.length; i++) { - const {$viewport} = viewports[i]; - viewportColumns[i].appendChild($viewport.get(0)); - } - - this.columnContainer.querySelector('.igv-sample-name-column').appendChild(sampleNameViewport.viewport); - - this.columnContainer.querySelector('.igv-scrollbar-column').appendChild(outerScroll); - - this.columnContainer.querySelector('.igv-track-drag-column').appendChild(dragHandle); - - this.columnContainer.querySelector('.igv-gear-menu-column').appendChild(gearContainer); - } - - } - - getTrackOrder() { - return this.trackViews.filter(tv => tv.track && tv.track.name).map(tv => tv.track.name) - } - - /** - * NOTE: Public API function - * - * Remove all tracks matching the given name. Usually this will be a single track, but there is no - * guarantee names are unique - * - * @param name - */ - removeTrackByName(name) { - const copy = this.trackViews.slice(); - for (let trackView of copy) { - if (name === trackView.track.name) { - this.removeTrack(trackView.track); - } - } - } - - /** - * NOTE: Public API function - * - * Remove the given track. If it has already been removed this is a no-op. - * - * @param track - */ - removeTrack(track) { - for (let trackView of this.trackViews) { - if (track === trackView.track) { - this._removeTrack(trackView.track); - break - } - } - } - - _removeTrack(track) { - if (track.disposed) return - this.trackViews.splice(this.trackViews.indexOf(track.trackView), 1); - this.fireEvent('trackremoved', [track]); - this.fireEvent('trackorderchanged', [this.getTrackOrder()]); - if (track.trackView) { - track.trackView.dispose(); - } - } - - /** - * API function - */ - removeAllTracks() { - - const remainingTrackViews = []; - - for (let trackView of this.trackViews) { - - if (trackView.track.id !== 'ruler' && trackView.track.id !== 'ideogram') { - this.fireEvent('trackremoved', [trackView.track]); - trackView.dispose(); - } else { - remainingTrackViews.push(trackView); - } - } - - this.trackViews = remainingTrackViews; - } - - /** - * - * @param property - * @param value - * @returns {Array} tracks with given property value. e.g. findTracks("type", "annotation") - */ - findTracks(property, value) { - - let f = typeof property === 'function' ? - trackView => property(trackView.track) : - trackView => value === trackView.track[property]; - - return this.trackViews.filter(f).map(tv => tv.track) - } - - /** - * Set the track height globally for all tracks. (Note: Its not clear why this is useful). - * @param newHeight - */ - setTrackHeight(newHeight) { - - this.trackHeight = newHeight; - - this.trackViews.forEach(function (trackView) { - trackView.setTrackHeight(newHeight); - }); - - } - - /** - * API function to signal that this browser visibility has changed, e.g. from hiding/showing in a tab interface. - * - * @returns {Promise} - */ - async visibilityChange() { - this.layoutChange(); - } - - async layoutChange() { - - const status = this.referenceFrameList.find(referenceFrame => referenceFrame.bpPerPixel < 0); - - if (status) { - const viewportWidth = this.calculateViewportWidth(this.referenceFrameList.length); - for (let referenceFrame of this.referenceFrameList) { - referenceFrame.bpPerPixel = (referenceFrame.end - referenceFrame.start) / viewportWidth; - } - } - - if (this.referenceFrameList) { - const isWGV = this.isMultiLocusWholeGenomeView() || GenomeUtils.isWholeGenomeView(this.referenceFrameList[0].chr); - this.navbarManager.navbarDidResize(this.$navigation.width(), isWGV); - } - - resize.call(this); - await this.updateViews(); - } - - async updateViews() { - - const trackViews = this.trackViews; - - this.updateLocusSearchWidget(); - - for (let centerGuide of this.centerLineList) { - centerGuide.repaint(); - } - - // Don't autoscale while dragging. - if (this.dragObject) { - for (let trackView of trackViews) { - await trackView.updateViews(); - } - } else { - // Group autoscale - const groupAutoscaleTracks = {}; - const otherTracks = []; - for (let trackView of trackViews) { - const group = trackView.track.autoscaleGroup; - if (group) { - var l = groupAutoscaleTracks[group]; - if (!l) { - l = []; - groupAutoscaleTracks[group] = l; - } - l.push(trackView); - } else { - otherTracks.push(trackView); - } - } - - if (Object.entries(groupAutoscaleTracks).length > 0) { - - const keys = Object.keys(groupAutoscaleTracks); - for (let group of keys) { - - const groupTrackViews = groupAutoscaleTracks[group]; - const promises = []; - - for (let trackView of groupTrackViews) { - promises.push(trackView.getInViewFeatures()); - } - - const featureArray = await Promise.all(promises); - - var allFeatures = [], dataRange; - - for (let features of featureArray) { - allFeatures = allFeatures.concat(features); - } - dataRange = doAutoscale$1(allFeatures); - - const p = []; - for (let trackView of groupTrackViews) { - trackView.track.dataRange = dataRange; - trackView.track.autoscale = false; - p.push(trackView.updateViews()); - } - await Promise.all(p); - } - - } - - await Promise.all(otherTracks.map(tv => tv.updateViews())); - // for (let trackView of otherTracks) { - // await trackView.updateViews(force); - // } - } - - } - - repaintViews() { - for (let trackView of this.trackViews) { - trackView.repaintViews(); - } - } - - updateLocusSearchWidget() { - - if(!this.referenceFrameList) return - const referenceFrameList = this.referenceFrameList; - - // Update end position of reference frames based on pixel widths. This is hacky, but its been done here - // for a long time, although indirectly. - const width = this.calculateViewportWidth(this.referenceFrameList.length); - for (let referenceFrame of referenceFrameList) { - referenceFrame.end = referenceFrame.start + referenceFrame.bpPerPixel * width; - } - - this.chromosomeSelectWidget.select.value = referenceFrameList.length === 1 ? this.referenceFrameList[0].chr : ''; - - const loc = this.referenceFrameList.map(rf => rf.getLocusString()).join(' '); - //const loc = this.referenceFrameList.length === 1 ? this.referenceFrameList[0].getLocusString() : ''; - this.$searchInput.val(loc); - - this.fireEvent('locuschange', [this.referenceFrameList]); - } - - calculateViewportWidth(columnCount) { - - let {width} = this.columnContainer.getBoundingClientRect(); - - const sampleNameViewportWidth = this.getSampleNameViewportWidth(); - - width -= igv_axis_column_width + sampleNameViewportWidth + igv_scrollbar_outer_width + igv_track_manipulation_handle_width + igv_track_gear_menu_column_width; - - width -= column_multi_locus_shim_width * (columnCount - 1); - - return Math.floor(width / columnCount) - } - - getCenterLineXOffset() { - let {width: columnContainerWidth} = this.columnContainer.getBoundingClientRect(); - columnContainerWidth -= igv_axis_column_width + this.getSampleNameViewportWidth() + igv_scrollbar_outer_width + igv_track_manipulation_handle_width + igv_track_gear_menu_column_width; - return Math.floor(columnContainerWidth / 2 + igv_axis_column_width) - } - - minimumBases() { - return this.config.minimumBases - } - - // Zoom in by a factor of 2, keeping the same center location - zoomIn() { - this.zoomWithScaleFactor(0.5); - }; - - // Zoom out by a factor of 2, keeping the same center location if possible - zoomOut() { - this.zoomWithScaleFactor(2.0); - }; - - async zoomWithScaleFactor(scaleFactor, centerBPOrUndefined, referenceFrameOrUndefined) { - - if(!this.referenceFrameList) return - - const viewportWidth = this.calculateViewportWidth(this.referenceFrameList.length); - - let referenceFrames = referenceFrameOrUndefined ? [referenceFrameOrUndefined] : this.referenceFrameList; - - for (let referenceFrame of referenceFrames) { - referenceFrame.zoomWithScaleFactor(this, scaleFactor, viewportWidth, centerBPOrUndefined); - } - } - - /** - * Add a new multi-locus panel for the specified region - * @param chr - * @param start - * @param end - * @param referenceFrameLeft - optional, if supplied new panel should be placed to the immediate right - */ - async addMultiLocusPanel(chr, start, end, referenceFrameLeft) { - - if(!this.referenceFrameList) return - - // account for reduced viewport width as a result of adding right mate pair panel - const viewportWidth = this.calculateViewportWidth(1 + this.referenceFrameList.length); - const scaleFactor = this.calculateViewportWidth(this.referenceFrameList.length) / this.calculateViewportWidth(1 + this.referenceFrameList.length); - for (let refFrame of this.referenceFrameList) { - refFrame.bpPerPixel *= scaleFactor; - } - - const bpp = (end - start) / viewportWidth; - const newReferenceFrame = new ReferenceFrame(this.genome, chr, start, end, bpp); - const indexLeft = referenceFrameLeft ? this.referenceFrameList.indexOf(referenceFrameLeft) : this.referenceFrameList.length - 1; - const indexRight = 1 + indexLeft; - - // TODO -- this is really ugly - const {$viewport} = this.trackViews[0].viewports[indexLeft]; - const viewportColumn = viewportColumnManager.insertAfter($viewport.get(0).parentElement); - - if (indexRight === this.referenceFrameList.length) { - this.referenceFrameList.push(newReferenceFrame); - for (let trackView of this.trackViews) { - const viewport = createViewport(trackView, viewportColumn, newReferenceFrame); - trackView.viewports.push(viewport); - } - } else { - this.referenceFrameList.splice(indexRight, 0, newReferenceFrame); - for (let trackView of this.trackViews) { - const viewport = createViewport(trackView, viewportColumn, newReferenceFrame); - trackView.viewports.splice(indexRight, 0, viewport); - } - } - - - this.centerLineList = this.createCenterLineList(this.columnContainer); - - resize.call(this); - await this.updateViews(true); - } - - async removeMultiLocusPanel(referenceFrame) { - - // find the $column corresponding to this referenceFrame and remove it - const index = this.referenceFrameList.indexOf(referenceFrame); - const {$viewport} = this.trackViews[0].viewports[index]; - viewportColumnManager.removeColumnAtIndex(index, $viewport.parent().get(0)); - - for (let {viewports} of this.trackViews) { - viewports[index].dispose(); - viewports.splice(index, 1); - } - - this.referenceFrameList.splice(index, 1); - - if (1 === this.referenceFrameList.length && this.getRulerTrackView()) { - for (let rulerViewport of this.getRulerTrackView().viewports) { - rulerViewport.dismissLocusLabel(); - } - } - - const scaleFactor = this.calculateViewportWidth(1 + this.referenceFrameList.length) / this.calculateViewportWidth(this.referenceFrameList.length); - - await this.rescaleForMultiLocus(scaleFactor); - - } - - /** - * Goto the locus represented by the selected referenceFrame, discarding all other panels - * - * @param referenceFrame - * @returns {Promise} - */ - async gotoMultilocusPanel(referenceFrame) { - - const referenceFrameIndex = this.referenceFrameList.indexOf(referenceFrame); - - // Remove columns for unselected panels - this.columnContainer.querySelectorAll('.igv-column').forEach((column, c) => { - if (c === referenceFrameIndex) ; else { - column.remove(); - } - }); - - // Remove all column shims - this.columnContainer.querySelectorAll('.igv-column-shim').forEach(shim => shim.remove()); - - // Discard viewports - for (let trackView of this.trackViews) { - const retain = trackView.viewports[referenceFrameIndex]; - trackView.viewports.filter((viewport, i) => i !== referenceFrameIndex).forEach(viewport => viewport.dispose()); - trackView.viewports = [retain]; - } - - const viewportWidth = this.calculateViewportWidth(1); - referenceFrame.bpPerPixel = (referenceFrame.end - referenceFrame.start) / viewportWidth; - this.referenceFrameList = [referenceFrame]; - - this.trackViews.forEach(({viewports}) => viewports.forEach(viewport => viewport.setWidth(viewportWidth))); - - this.centerLineList = this.createCenterLineList(this.columnContainer); - - this.updateUIWithReferenceFrameList(); - - await this.updateViews(true); - - } - - async rescaleForMultiLocus(scaleFactor) { - - const viewportWidth = this.calculateViewportWidth(this.referenceFrameList.length); - - for (let referenceFrame of this.referenceFrameList) { - referenceFrame.bpPerPixel *= scaleFactor; - } - - for (let {viewports} of this.trackViews) { - - for (let viewport of viewports) { - viewport.setWidth(viewportWidth); - } - } - - this.centerLineList = this.createCenterLineList(this.columnContainer); - - this.updateUIWithReferenceFrameList(); - - await this.updateViews(); - - } - - /** - * @deprecated This is a deprecated method with no known usages. To be removed in a future release. - */ - async goto(chr, start, end) { - await this.search(chr + ":" + start + "-" + end); - } - - /** - - * Search for the locus string -- this function is called from various igv.js GUI elements, and is not part of the - * API. Wraps ```search``` and presents an error dialog if false. - * - * @param string - * @param init - * @returns {Promise} - */ - async doSearch(string, init) { - const success = await this.search(string, init); - if (!success) { - this.alert.present(new Error(`Unrecognized locus: ${string} `)); - } - return success - } - - - /** - * Search for the locus string - * NOTE: This is part of the API - * @param string - * @param init true if called during browser initialization - * @returns {Promise} true if found, false if not - */ - async search(string, init) { - - const loci = await search(this, string); - - if (loci && loci.length > 0) { - - // create reference frame list based on search loci - this.referenceFrameList = createReferenceFrameList(loci, this.genome, this.flanking, this.minimumBases(), this.calculateViewportWidth(loci.length), this.isSoftclipped()); - - // discard viewport DOM elements - for (let trackView of this.trackViews) { - // empty axis column, viewport columns, sampleName column, scroll column, drag column, gear column - trackView.removeDOMFromColumnContainer(); - } - - // discard ONLY viewport columns - this.columnContainer.querySelectorAll('.igv-column-shim, .igv-column').forEach(el => el.remove()); - - // Insert viewport columns preceding the sample-name column - viewportColumnManager.insertBefore(this.columnContainer.querySelector('.igv-sample-name-column'), this.referenceFrameList.length); - - this.centerLineList = this.createCenterLineList(this.columnContainer); - - // Populate the columns - for (let trackView of this.trackViews) { - trackView.addDOMToColumnContainer(this, this.columnContainer, this.referenceFrameList); - } - - this.updateUIWithReferenceFrameList(); - - if (!init) { - await this.updateViews(); - } - return true - } else { - return false - } - } - - async loadSampleInformation(url) { - var name = url; - if (isFile$1(url)) { - name = url.name; - } - var ext = name.substr(name.lastIndexOf('.') + 1); - if (ext === 'fam') { - this.sampleInformation = await loadPlinkFile(url); - } - }; - -// EVENTS - - on(eventName, fn) { - if (!this.eventHandlers[eventName]) { - this.eventHandlers[eventName] = []; - } - this.eventHandlers[eventName].push(fn); - }; - - /** - * @deprecated use off() - * @param eventName - * @param fn - */ - un(eventName, fn) { - this.off(eventName, fn); - }; - - off(eventName, fn) { - - if (!eventName) { - this.eventHandlers = {}; // Remove all event handlers - } else if (!fn) { - this.eventHandlers[eventName] = []; // Remove all eventhandlers matching name - } else { - // Remove specific event handler - const handlers = this.eventHandlers[eventName]; - if (!handlers || handlers.length === 0) { - console.warn("No handlers to remove for event: " + eventName); - } else { - const callbackIndex = handlers.indexOf(fn); - if (callbackIndex !== -1) { - this.eventHandlers[eventName].splice(callbackIndex, 1); - } - } - } - } - - fireEvent(eventName, args, thisObj) { - - const handlers = this.eventHandlers[eventName]; - if (undefined === handlers || handlers.length === 0) { - return undefined - } - - const scope = thisObj || window; - const results = handlers.map(function (event) { - return event.apply(scope, args) - }); - - return results[0] - } - - dispose() { - this.removeMouseHandlers(); - for (let trackView of this.trackViews) { - trackView.dispose(); - } - } - - /** - * Return a json-like object (note not a json string) representing the current state. - * - */ - toJSON() { - - const json = { - "version": version$2() - }; - - if (this.showSampleNames !== undefined) { - json['showSampleNames'] = this.showSampleNames; - } - if (this.sampleNameViewportWidth !== defaultSampleNameViewportWidth) { - json['sampleNameViewportWidth'] = this.sampleNameViewportWidth; - } - - json["reference"] = this.genome.toJSON(); - if (json.reference.fastaURL instanceof File) { // Test specifically for File. Other types of File-like objects might be savable) { - throw new Error(`Error. Sessions cannot include local file references ${json.reference.fastaURL.name}.`) - } else if (json.reference.indexURL instanceof File) { // Test specifically for File. Other types of File-like objects might be savable) { - throw new Error(`Error. Sessions cannot include local file references ${json.reference.indexURL.name}.`) - } - - // Build locus array (multi-locus view). Use the first track to extract the loci, any track could be used. - const locus = []; - const gtexSelections = {}; - let hasGtexSelections = false; - let anyTrackView = this.trackViews[0]; - for (let {referenceFrame} of anyTrackView.viewports) { - const locusString = referenceFrame.getLocusString(); - locus.push(locusString); - if (referenceFrame.selection) { - const selection = { - gene: referenceFrame.selection.gene, - snp: referenceFrame.selection.snp - }; - gtexSelections[locusString] = selection; - hasGtexSelections = true; - } - } - json["locus"] = locus.length === 1 ? locus[0] : locus; - if (hasGtexSelections) { - json["gtexSelections"] = gtexSelections; - } - - json["roi"] = this.roiManager.toJSON(); - - const trackJson = []; - const errors = []; - for (let {track} of this.trackViews) { - try { - let config; - if (typeof track.getState === "function") { - config = track.getState(); - } else { - config = track.config; - } - - if (config) { - // null backpointer to browser - if (config.browser) { - delete config.browser; - } - config.order = track.order; //order++; - trackJson.push(config); - } - } catch (e) { - console.error(`Track: ${track.name}: ${e}`); - errors.push(`Track: ${track.name}: ${e}`); - } - } - - if (errors.length > 0) { - let n = 1; - let message = 'Errors encountered saving session:
'; - for (let e of errors) { - message += ` (${n++}) ${e.toString()}
`; - } - throw Error(message) - } - - - json["tracks"] = trackJson; - - return json // This is an object, not a json string - - } - - compressedSession() { - const json = JSON.stringify(this.toJSON()); - return compressString(json) - } - - sessionURL() { - const path = window.location.href.slice(); - const idx = path.indexOf("?"); - const surl = (idx > 0 ? path.substring(0, idx) : path) + "?sessionURL=blob:" + this.compressedSession(); - return surl - } - - /** - * Record a mouse click on a specific viewport. This might be the start of a drag operation. Dragging - * (panning) is handled here so that the mouse can move out of a specific viewport (e.g. stray into another - * track) without halting the drag. - * - * @param e - * @param viewport - */ - mouseDownOnViewport(e, viewport) { - - var coords; - coords = domUtils$1.pageCoordinates(e); - this.vpMouseDown = { - viewport, - lastMouseX: coords.x, - mouseDownX: coords.x, - lastMouseY: coords.y, - mouseDownY: coords.y, - referenceFrame: viewport.referenceFrame - }; - }; - - cancelTrackPan() { - - const dragObject = this.dragObject; - this.dragObject = undefined; - this.isScrolling = false; - this.vpMouseDown = undefined; - - if (dragObject && dragObject.viewport.referenceFrame.start !== dragObject.start) { - this.updateViews(); - this.fireEvent('trackdragend'); - } - } - - isTrackPanning() { - return this.dragObject - } - - isSoftclipped() { - const result = this.trackViews.find(tv => tv.track.showSoftClips === true); - return result !== undefined - } - - - /** - * Track drag here refers to vertical dragging to reorder tracks, not horizontal panning. - * - * @param trackView - */ - startTrackDrag(trackView) { - - this.dragTrack = trackView; - - } - - /** - * Track drag here refers to vertical dragging to reorder tracks, not horizontal panning. - * - * @param dragDestination - */ - updateTrackDrag(dragDestination) { - - if (dragDestination && this.dragTrack) { - - const dragged = this.dragTrack; - const indexDestination = this.trackViews.indexOf(dragDestination); - const indexDragged = this.trackViews.indexOf(dragged); - const trackViews = this.trackViews; - - trackViews[indexDestination] = dragged; - trackViews[indexDragged] = dragDestination; - - const newOrder = this.trackViews[indexDestination].track.order; - this.trackViews[indexDragged].track.order = newOrder; - - const nTracks = trackViews.length; - let lastOrder = newOrder; - - if (indexDestination < indexDragged) { - // Displace tracks below - - for (let i = indexDestination + 1; i < nTracks; i++) { - const track = trackViews[i].track; - if (track.order <= lastOrder) { - track.order = Math.min(Number.MAX_SAFE_INTEGER, lastOrder + 1); - lastOrder = track.order; - } else { - break - } - } - } else { - // Displace tracks above. First track (index 0) is "ruler" - for (let i = indexDestination - 1; i > 0; i--) { - const track = trackViews[i].track; - if (track.order >= lastOrder) { - track.order = Math.max(-Number.MAX_SAFE_INTEGER, lastOrder - 1); - lastOrder = track.order; - } else { - break - } - } - } - this.reorderTracks(); - } - } - - /** - * End vertical dragging of tracks (i.e. track re-order, not horizontal panning of data) - */ - endTrackDrag() { - if (this.dragTrack) { - // this.dragTrack.$trackDragScrim.hide(); - this.dragTrack = undefined; - this.fireEvent('trackorderchanged', [this.getTrackOrder()]); - } else { - this.dragTrack = undefined; - } - } - - /** - * Mouse handlers to support drag (pan) - */ - addMouseHandlers() { - this.addWindowResizeHandler(); - this.addRootMouseUpHandler(); - this.addRootMouseLeaveHandler(); - this.addColumnContainerEventHandlers(); - } - - removeMouseHandlers() { - this.removeWindowResizeHandler(); - this.removeRootMouseUpHandler(); - this.removeRootMouseLeaveHandler(); - this.removeColumnContainerEventHandlers(); - } - - addWindowResizeHandler() { - // Create a copy of the prototype "resize" function bound to this instance. Neccessary to support removing. - this.boundWindowResizeHandler = resize.bind(this); - window.addEventListener('resize', this.boundWindowResizeHandler); - } - - removeWindowResizeHandler() { - window.removeEventListener('resize', this.boundWindowResizeHandler); - } - - addRootMouseUpHandler() { - this.boundRootMouseUpHandler = mouseUpOrLeave.bind(this); - this.root.addEventListener('mouseup', this.boundRootMouseUpHandler); - } - - removeRootMouseUpHandler() { - this.root.removeEventListener('mouseup', this.boundRootMouseUpHandler); - } - - addRootMouseLeaveHandler() { - this.boundRootMouseLeaveHandler = mouseUpOrLeave.bind(this); - this.root.addEventListener('mouseleave', this.boundRootMouseLeaveHandler); - } - - removeRootMouseLeaveHandler() { - this.root.removeEventListener('mouseleave', this.boundRootMouseLeaveHandler); - } - - addColumnContainerEventHandlers() { - this.boundColumnContainerMouseMoveHandler = handleMouseMove.bind(this); - this.boundColumnContainerTouchMoveHandler = handleMouseMove.bind(this); - this.boundColumnContainerMouseLeaveHandler = mouseUpOrLeave.bind(this); - this.boundColumnContainerMouseUpHandler = mouseUpOrLeave.bind(this); - this.boundColumnContainerTouchEndHandler = mouseUpOrLeave.bind(this); - - this.columnContainer.addEventListener('mousemove', this.boundColumnContainerMouseMoveHandler); - this.columnContainer.addEventListener('touchmove', this.boundColumnContainerTouchMoveHandler); - - this.columnContainer.addEventListener('mouseleave', this.boundColumnContainerMouseLeaveHandler); - - this.columnContainer.addEventListener('mouseup', this.boundColumnContainerMouseUpHandler); - this.columnContainer.addEventListener('touchend', this.boundColumnContainerTouchEndHandler); - } - - removeColumnContainerEventHandlers() { - this.columnContainer.removeEventListener('mousemove', this.boundColumnContainerMouseMoveHandler); - this.columnContainer.removeEventListener('touchmove', this.boundColumnContainerTouchMoveHandler); - - this.columnContainer.removeEventListener('mouseleave', this.boundColumnContainerMouseLeaveHandler); - - this.columnContainer.removeEventListener('mouseup', this.boundColumnContainerMouseUpHandler); - this.columnContainer.removeEventListener('touchend', this.boundColumnContainerTouchEndHandler); - } - - static uncompressSession(url) { - - let bytes; - if (url.indexOf('/gzip;base64') > 0) { - //Proper dataURI - bytes = decodeDataURI$1(url); - let json = ''; - for (let b of bytes) { - json += String.fromCharCode(b); - } - return json - } else { - - let enc = url.substring(5); - return uncompressString(enc) - } - } - - createCircularView(container, show) { - show = show === true; // convert undefined to boolean - this.circularView = createCircularView(container, this); - this.circularViewControl = new CircularViewControl(this.$toggle_button_container.get(0), this); - this.circularView.setAssembly({ - name: this.genome.id, - id: this.genome.id, - chromosomes: makeCircViewChromosomes(this.genome) - }); - this.circularViewVisible = show; - return this.circularView - } - - get circularViewVisible() { - return this.circularView !== undefined && this.circularView.visible - } - - set circularViewVisible(isVisible) { - if (this.circularView) { - this.circularView.visible = isVisible; - this.circularViewControl.setState(isVisible); - } - } -} - -/** - * Function called win window is resized, or visibility changed (e.g. "show" from a tab). This is a function rather - * than class method because it needs to be copied and bound to specific instances of browser to support listener - * removal - * - * @returns {Promise} - */ -async function resize() { - - if(!this.referenceFrameList) return - - const viewportWidth = this.calculateViewportWidth(this.referenceFrameList.length); - - for (let referenceFrame of this.referenceFrameList) { - - const index = this.referenceFrameList.indexOf(referenceFrame); - - const {chr, genome} = referenceFrame; - - const {bpLength} = genome.getChromosome(referenceFrame.chr); - - const viewportWidthBP = referenceFrame.toBP(viewportWidth); - - // viewportWidthBP > bpLength occurs when locus is full chromosome and user widens browser - if (GenomeUtils.isWholeGenomeView(chr) || viewportWidthBP > bpLength) { - // console.log(`${ Date.now() } Recalc referenceFrame(${ index }) bpp. viewport ${ StringUtils.numberFormatter(viewportWidthBP) } > ${ StringUtils.numberFormatter(bpLength) }.`) - referenceFrame.bpPerPixel = bpLength / viewportWidth; - } else { - // console.log(`${ Date.now() } Recalc referenceFrame(${ index }) end.`) - referenceFrame.end = referenceFrame.start + referenceFrame.toBP(viewportWidth); - } - - for (let {viewports} of this.trackViews) { - viewports[index].setWidth(viewportWidth); - } - - } - - this.updateUIWithReferenceFrameList(); - - //TODO -- update view only if needed. Reducing size never needed. Increasing size maybe - - await this.updateViews(true); -} - - -function handleMouseMove(e) { - - e.preventDefault(); - - const {x, y} = domUtils$1.pageCoordinates(e); - - if (this.vpMouseDown) { - - const {viewport, referenceFrame} = this.vpMouseDown; - - // Determine direction, true == horizontal - const horizontal = Math.abs((x - this.vpMouseDown.mouseDownX)) > Math.abs((y - this.vpMouseDown.mouseDownY)); - - if (!this.dragObject && !this.isScrolling) { - if (horizontal) { - if (this.vpMouseDown.mouseDownX && Math.abs(x - this.vpMouseDown.mouseDownX) > this.constants.dragThreshold) { - this.dragObject = {viewport, start: referenceFrame.start}; - } - } else { - if (this.vpMouseDown.mouseDownY && - Math.abs(y - this.vpMouseDown.mouseDownY) > this.constants.scrollThreshold) { - // Scrolling => dragging track vertically - this.isScrolling = true; - const viewportHeight = viewport.$viewport.height(); - const contentHeight = viewport.trackView.maxViewportContentHeight(); - this.vpMouseDown.r = viewportHeight / contentHeight; - } - } - } - - if (this.dragObject) { - const clampDrag = !this.isSoftclipped(); - let deltaX = this.vpMouseDown.lastMouseX - x; - const viewChanged = referenceFrame.shiftPixels(deltaX, viewport.$viewport.width(), clampDrag); - if (viewChanged) { - this.updateViews(); - } - this.fireEvent('trackdrag'); - } - - - if (this.isScrolling) { - const delta = this.vpMouseDown.r * (this.vpMouseDown.lastMouseY - y); - viewport.trackView.moveScroller(delta); - } - - - this.vpMouseDown.lastMouseX = x; - this.vpMouseDown.lastMouseY = y; - } -} - -function mouseUpOrLeave(e) { - this.cancelTrackPan(); - this.endTrackDrag(); -} - - -function getInitialLocus(locus, genome) { - if (locus) { - return Array.isArray(locus) ? locus.join(' ') : locus - } else { - return genome.getHomeChromosomeName() - } -} - -function logo() { - - return $$1( - '' + - 'IGV' + - '' + - '' + - '' + - ';' + - '' + - ' ' - ) -} - -function toggleTrackLabels(trackViews, isVisible) { - - for (let {viewports} of trackViews) { - for (let viewport of viewports) { - if (viewport.$trackLabel) { - if (0 === viewports.indexOf(viewport) && true === isVisible) { - viewport.$trackLabel.show(); - } else { - viewport.$trackLabel.hide(); - } - } - } - } -} - -/* - * The MIT License (MIT) - * - * Copyright (c) 2014 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -let allBrowsers$1 = []; - -/** - * Create an igv.browser instance. This object defines the public API for interacting with the genome browser. - * - * @param parentDiv - DOM tree root - * @param config - configuration options. - * - */ -async function createBrowser$1(parentDiv, config) { - - if (undefined === config) config = {}; - - // Initialize pre-defined genomes. The genome list is shared among all browser instances - if (!GenomeUtils.KNOWN_GENOMES) { - await GenomeUtils.initializeGenomes(config); - } - - setDefaults$1(config); - - if (config.queryParametersSupported) { - extractQuery$1(config); - } - if (config.apiKey) { - igvxhr.setApiKey(config.apiKey); - } - if (config.oauthToken) { - igvxhr.setOauthToken(config.oauthToken); - } - if (config.clientId && (!isInitialized())) { - await init$1$1({ - clientId: config.clientId, - apiKey: config.apiKey, - scope: 'https://www.googleapis.com/auth/userinfo.profile' - }); - } - - // Create browser - const browser = new Browser(config, parentDiv); - allBrowsers$1.push(browser); - - // Load initial session - if (config.sessionURL) { - await browser.loadSession({ - url: config.sessionURL - }); - } else { - await browser.loadSessionObject(config); - } - - browser.navbarManager.navbarDidResize(browser.$navigation.width()); - - return browser - -} - -function removeBrowser(browser) { - browser.dispose(); - browser.root.remove(); - allBrowsers$1 = allBrowsers$1.filter(item => item !== browser); -} - -function removeAllBrowsers() { - for (let browser of allBrowsers$1) { - browser.dispose(); - browser.root.remove(); - } - allBrowsers$1 = []; -} - -/** - * This function provided so clients can inform igv of a visibility change, typically when an igv instance is - * made visible from a tab, accordion, or similar widget. - */ -async function visibilityChange() { - for (let browser of allBrowsers$1) { - await browser.visibilityChange(); - } -} - -function setDefaults$1(config) { - - if (undefined === config.minimumBases) { - config.minimumBases = 40; - } - - if (undefined === config.showIdeogram) { - config.showIdeogram = true; - } - - if (undefined === config.showCircularView) { - config.showCircularView = false; - } - - if (undefined === config.showCircularViewButton) { - config.showCircularViewButton = false; - } - - if (undefined === config.showTrackLabelButton) { - config.showTrackLabelButton = true; - } - - if (undefined === config.showTrackLabels) { - config.showTrackLabels = true; - } - - if (undefined === config.showROITableButton) { - config.showROITableButton = false; - } - - if (undefined === config.showROITable) { - config.showROITable = false; - } - - if (undefined === config.showCursorTrackingGuideButton) { - config.showCursorTrackingGuideButton = true; - } - - - if (undefined === config.showCursorGuide) { - config.showCursorGuide = config.showCursorTrackingGuide || false; // showCursorTrackingGuide is a synonym - } - - if (undefined === config.showCenterGuideButton) { - config.showCenterGuideButton = true; - } - - if (undefined === config.showCenterGuide) { - config.showCenterGuide = false; - } - - if (undefined === config.showSampleNames) { - config.showSampleNames = false; - } - - if (undefined === config.showSVGButton) { - config.showSVGButton = true; - } - - if (config.showControls === undefined) { - config.showControls = true; - } - - if (config.showNavigation === undefined) { - config.showNavigation = true; - } - - if (config.showRuler === undefined) { - config.showRuler = true; - } - - if (config.flanking === undefined) { - config.flanking = 1000; - } - - if (config.pairsSupported === undefined) { - config.pairsSupported = true; - } - - if (!config.tracks) { - config.tracks = []; - } - -} - - -function extractQuery$1(config) { - - var i1, i2, i, j, s, query, tokens, uri, key, value; - - uri = window.location.href; - - query = {}; - i1 = uri.indexOf("?"); - i2 = uri.lastIndexOf("#"); - - let files; - let indexURLs; - let names; - if (i1 >= 0) { - if (i2 < 0) i2 = uri.length; - for (i = i1 + 1; i < i2;) { - j = uri.indexOf("&", i); - if (j < 0) j = i2; - - s = uri.substring(i, j); - tokens = s.split("=", 2); - - if (tokens.length === 2) { - key = tokens[0]; - value = decodeURIComponent(tokens[1]); - - if ('file' === key) { - // IGV desktop style file parameter - files = value.split(','); - } else if ('index' === key) { - // IGV desktop style index parameter - indexURLs = value.split(','); - } else if ('name' === key) { - // IGV desktop style index parameter - names = value.split(','); - } else if ('genome' === key && ((value.startsWith("https://") || value.startsWith("http://")) && !value.endsWith(".json"))) { - // IGV desktop compatibility -- assuming url to fasta - config['reference'] = { - fastaURL: value, - indexURL: value + ".fai" - }; - } else { - config[key] = value; - } - i = j + 1; - } else { - i++; - } - } - } - - if (files) { - - if (!config.tracks) - config.tracks = []; - for (let i = 0; i < files.length; i++) { - - if (files[i].endsWith(".xml") || files[i].endsWith(".json")) { - config.sessionURL = files[i]; - break - } - - const trackConfig = {url: files[i]}; - if (indexURLs && indexURLs.length > i) { - trackConfig.indexURL = indexURLs[i]; - } - if (names && names.length > i) { - trackConfig.name = names[i]; - } - config.tracks.push(trackConfig); - } - } - - return query -} - - -async function createTrack(config, browser) { - return await Browser.prototype.createTrack.call(browser, config) -} - -function embedCSS$3() { - - var css = '.igv-navbar {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-between;\n align-items: center;\n box-sizing: border-box;\n width: 100%;\n color: #444;\n font-size: 12px;\n font-family: \"Open Sans\", sans-serif;\n font-weight: 400;\n line-height: 32px;\n padding-left: 8px;\n padding-right: 8px;\n margin-top: 2px;\n margin-bottom: 6px;\n height: 32px;\n border-style: solid;\n border-radius: 3px;\n border-width: thin;\n border-color: #bfbfbf;\n background-color: #f3f3f3;\n}\n.igv-navbar .igv-navbar-left-container {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-between;\n align-items: center;\n height: 32px;\n line-height: 32px;\n}\n.igv-navbar .igv-navbar-left-container .igv-logo {\n width: 34px;\n height: 32px;\n margin-right: 8px;\n}\n.igv-navbar .igv-navbar-left-container .igv-current-genome {\n height: 32px;\n margin-left: 4px;\n margin-right: 4px;\n user-select: none;\n line-height: 32px;\n vertical-align: middle;\n text-align: center;\n}\n.igv-navbar .igv-navbar-left-container .igv-navbar-genomic-location {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-between;\n align-items: center;\n height: 100%;\n}\n.igv-navbar .igv-navbar-left-container .igv-navbar-genomic-location .igv-chromosome-select-widget-container {\n display: flex;\n flex-flow: column;\n flex-wrap: nowrap;\n justify-content: space-around;\n align-items: center;\n height: 100%;\n width: 125px;\n margin-right: 4px;\n}\n.igv-navbar .igv-navbar-left-container .igv-navbar-genomic-location .igv-chromosome-select-widget-container select {\n display: block;\n cursor: pointer;\n width: 100px;\n height: 75%;\n outline: none;\n font-size: 12px;\n font-family: \"Open Sans\", sans-serif;\n font-weight: 400;\n}\n.igv-navbar .igv-navbar-left-container .igv-navbar-genomic-location .igv-locus-size-group {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-between;\n align-items: center;\n margin-left: 8px;\n height: 22px;\n}\n.igv-navbar .igv-navbar-left-container .igv-navbar-genomic-location .igv-locus-size-group .igv-search-container {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n width: 210px;\n height: 22px;\n line-height: 22px;\n}\n.igv-navbar .igv-navbar-left-container .igv-navbar-genomic-location .igv-locus-size-group .igv-search-container input.igv-search-input {\n cursor: text;\n width: 85%;\n height: 22px;\n line-height: 22px;\n font-size: 12px;\n font-family: \"Open Sans\", sans-serif;\n font-weight: 400;\n text-align: left;\n padding-left: 8px;\n margin-right: 8px;\n outline: none;\n border-style: solid;\n border-radius: 3px;\n border-width: thin;\n border-color: #bfbfbf;\n background-color: white;\n}\n.igv-navbar .igv-navbar-left-container .igv-navbar-genomic-location .igv-locus-size-group .igv-search-container .igv-search-icon-container {\n cursor: pointer;\n height: 16px;\n width: 16px;\n}\n.igv-navbar .igv-navbar-left-container .igv-navbar-genomic-location .igv-locus-size-group .igv-windowsize-panel-container {\n margin-left: 4px;\n user-select: none;\n}\n.igv-navbar .igv-navbar-right-container {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-between;\n align-items: center;\n height: 32px;\n line-height: 32px;\n}\n.igv-navbar .igv-navbar-right-container .igv-navbar-toggle-button-container {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-between;\n align-items: center;\n height: 100%;\n}\n.igv-navbar .igv-navbar-right-container .igv-navbar-toggle-button-container div {\n margin-left: 0;\n margin-right: 4px;\n}\n.igv-navbar .igv-navbar-right-container .igv-navbar-toggle-button-container div:last-child {\n margin-left: 0;\n margin-right: 0;\n}\n.igv-navbar .igv-navbar-right-container .igv-navbar-toggle-button-container-750 {\n display: none;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget {\n color: #737373;\n font-size: 18px;\n height: 32px;\n line-height: 32px;\n margin-left: 8px;\n user-select: none;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-end;\n align-items: center;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget div {\n cursor: pointer;\n margin-left: unset;\n margin-right: unset;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget div:first-child {\n height: 24px;\n width: 24px;\n margin-left: unset;\n margin-right: 8px;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget div:last-child {\n height: 24px;\n width: 24px;\n margin-left: 8px;\n margin-right: unset;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget div:nth-child(even) {\n display: block;\n height: fit-content;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget input {\n display: block;\n width: 125px;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget svg {\n display: block;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget-900 {\n color: #737373;\n font-size: 18px;\n height: 32px;\n line-height: 32px;\n margin-left: 8px;\n user-select: none;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-end;\n align-items: center;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget-900 div {\n cursor: pointer;\n margin-left: unset;\n margin-right: unset;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget-900 div:first-child {\n height: 24px;\n width: 24px;\n margin-left: unset;\n margin-right: 8px;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget-900 div:last-child {\n height: 24px;\n width: 24px;\n margin-left: 8px;\n margin-right: unset;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget-900 div:nth-child(even) {\n width: 0;\n height: 0;\n display: none;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget-900 input {\n width: 0;\n height: 0;\n display: none;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget-900 svg {\n display: block;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget-hidden {\n display: none;\n}\n\n.igv-navbar-button {\n display: block;\n box-sizing: unset;\n padding-left: 6px;\n padding-right: 6px;\n height: 18px;\n text-transform: capitalize;\n user-select: none;\n line-height: 18px;\n text-align: center;\n vertical-align: middle;\n font-family: \"Open Sans\", sans-serif;\n font-size: 11px;\n font-weight: 200;\n color: #737373;\n background-color: #f3f3f3;\n border-color: #737373;\n border-style: solid;\n border-width: thin;\n border-radius: 6px;\n}\n\n.igv-navbar-button-clicked {\n color: white;\n background-color: #737373;\n}\n\n.igv-navbar-button:hover {\n cursor: pointer;\n}\n\n.igv-zoom-in-notice-container {\n z-index: 1024;\n position: absolute;\n top: 8px;\n left: 50%;\n transform: translate(-50%, 0%);\n display: flex;\n flex-direction: row;\n flex-wrap: nowrap;\n justify-content: center;\n align-items: center;\n background-color: white;\n}\n.igv-zoom-in-notice-container > div {\n padding-left: 4px;\n padding-right: 4px;\n padding-top: 2px;\n padding-bottom: 2px;\n width: 100%;\n height: 100%;\n font-family: \"Open Sans\", sans-serif;\n font-size: 14px;\n font-weight: 400;\n color: #3f3f3f;\n}\n\n.igv-zoom-in-notice {\n position: absolute;\n top: 10px;\n left: 50%;\n}\n.igv-zoom-in-notice div {\n position: relative;\n left: -50%;\n font-family: \"Open Sans\", sans-serif;\n font-size: medium;\n font-weight: 400;\n color: #3f3f3f;\n background-color: rgba(255, 255, 255, 0.51);\n z-index: 64;\n}\n\n.igv-container-spinner {\n position: absolute;\n top: 90%;\n left: 50%;\n transform: translate(-50%, -50%);\n z-index: 1024;\n width: 24px;\n height: 24px;\n pointer-events: none;\n color: #737373;\n}\n\n.igv-multi-locus-close-button {\n position: absolute;\n top: 2px;\n right: 0;\n padding-left: 2px;\n padding-right: 2px;\n width: 12px;\n height: 12px;\n color: #666666;\n background-color: white;\n z-index: 1000;\n}\n.igv-multi-locus-close-button > svg {\n vertical-align: top;\n}\n\n.igv-multi-locus-close-button:hover {\n cursor: pointer;\n color: #434343;\n}\n\n.igv-multi-locus-ruler-label {\n z-index: 64;\n position: absolute;\n top: 2px;\n left: 0;\n width: 100%;\n height: 12px;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: center;\n align-items: center;\n}\n.igv-multi-locus-ruler-label > div {\n font-family: \"Open Sans\", sans-serif;\n font-size: 12px;\n color: rgb(16, 16, 16);\n background-color: white;\n}\n.igv-multi-locus-ruler-label > div {\n cursor: pointer;\n}\n\n.igv-multi-locus-ruler-label-square-dot {\n z-index: 64;\n position: absolute;\n left: 50%;\n top: 5%;\n transform: translate(-50%, 0%);\n background-color: white;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n}\n.igv-multi-locus-ruler-label-square-dot > div:first-child {\n width: 14px;\n height: 14px;\n}\n.igv-multi-locus-ruler-label-square-dot > div:last-child {\n margin-left: 16px;\n font-family: \"Open Sans\", sans-serif;\n font-size: 14px;\n font-weight: 400;\n color: rgb(16, 16, 16);\n}\n\n.igv-ruler-sweeper {\n display: none;\n pointer-events: none;\n position: absolute;\n top: 26px;\n bottom: 0;\n left: 0;\n width: 0;\n z-index: 99999;\n background-color: rgba(68, 134, 247, 0.25);\n}\n\n.igv-ruler-tooltip {\n pointer-events: none;\n z-index: 128;\n position: absolute;\n top: 0;\n left: 0;\n width: 1px;\n height: 32px;\n background-color: transparent;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n}\n.igv-ruler-tooltip > div {\n pointer-events: none;\n width: 128px;\n height: auto;\n padding: 1px;\n color: #373737;\n font-size: 10px;\n font-family: \"Open Sans\", sans-serif;\n font-weight: 400;\n background-color: white;\n border-style: solid;\n border-width: thin;\n border-color: #373737;\n}\n\n.igv-track-label {\n position: absolute;\n left: 8px;\n top: 8px;\n width: auto;\n height: auto;\n max-width: 50%;\n padding-left: 4px;\n padding-right: 4px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n font-family: \"Open Sans\", sans-serif;\n font-size: small;\n font-weight: 400;\n text-align: center;\n user-select: none;\n -moz-user-select: none;\n -webkit-user-select: none;\n border-color: #444;\n border-radius: 2px;\n border-style: solid;\n border-width: thin;\n background-color: white;\n z-index: 128;\n cursor: pointer;\n}\n\n.igv-track-label:hover,\n.igv-track-label:focus,\n.igv-track-label:active {\n background-color: #e8e8e8;\n}\n\n.igv-track-label-popup-shim {\n padding-left: 8px;\n padding-right: 8px;\n padding-top: 4px;\n}\n\n.igv-center-line {\n display: none;\n pointer-events: none;\n position: absolute;\n top: 0;\n bottom: 0;\n left: 50%;\n transform: translateX(-50%);\n z-index: 8;\n user-select: none;\n -moz-user-select: none;\n -webkit-user-select: none;\n border-left-style: dashed;\n border-left-width: thin;\n border-right-style: dashed;\n border-right-width: thin;\n}\n\n.igv-center-line-wide {\n background-color: rgba(0, 0, 0, 0);\n border-left-color: rgba(127, 127, 127, 0.51);\n border-right-color: rgba(127, 127, 127, 0.51);\n}\n\n.igv-center-line-thin {\n background-color: rgba(0, 0, 0, 0);\n border-left-color: rgba(127, 127, 127, 0.51);\n border-right-color: rgba(0, 0, 0, 0);\n}\n\n.igv-cursor-guide-horizontal {\n display: none;\n pointer-events: none;\n user-select: none;\n -moz-user-select: none;\n -webkit-user-select: none;\n position: absolute;\n left: 0;\n right: 0;\n top: 50%;\n height: 1px;\n z-index: 1;\n margin-left: 50px;\n margin-right: 54px;\n border-top-style: dotted;\n border-top-width: thin;\n border-top-color: rgba(127, 127, 127, 0.76);\n}\n\n.igv-cursor-guide-vertical {\n pointer-events: none;\n user-select: none;\n -moz-user-select: none;\n -webkit-user-select: none;\n position: absolute;\n top: 0;\n bottom: 0;\n left: 50%;\n width: 1px;\n z-index: 1;\n border-left-style: dotted;\n border-left-width: thin;\n border-left-color: rgba(127, 127, 127, 0.76);\n display: none;\n}\n\n.igv-user-feedback {\n position: fixed;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: 512px;\n height: 360px;\n z-index: 2048;\n background-color: white;\n border-color: #a2a2a2;\n border-style: solid;\n border-width: thin;\n font-family: \"Open Sans\", sans-serif;\n font-size: medium;\n font-weight: 400;\n color: #444;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n}\n.igv-user-feedback div:first-child {\n position: relative;\n height: 24px;\n width: 100%;\n background-color: white;\n border-bottom-color: #a2a2a2;\n border-bottom-style: solid;\n border-bottom-width: thin;\n}\n.igv-user-feedback div:first-child div {\n position: absolute;\n top: 2px;\n width: 16px;\n height: 16px;\n background-color: transparent;\n}\n.igv-user-feedback div:first-child div:first-child {\n left: 8px;\n}\n.igv-user-feedback div:first-child div:last-child {\n cursor: pointer;\n right: 8px;\n}\n.igv-user-feedback div:last-child {\n width: 100%;\n height: calc(100% - 24px);\n border-width: 0;\n}\n.igv-user-feedback div:last-child div {\n width: auto;\n height: auto;\n margin: 8px;\n}\n\n.igv-generic-dialog-container {\n position: absolute;\n top: 0;\n left: 0;\n width: 300px;\n height: 200px;\n border-color: #7F7F7F;\n border-radius: 4px;\n border-style: solid;\n border-width: thin;\n font-family: \"Open Sans\", sans-serif;\n font-size: medium;\n font-weight: 400;\n z-index: 2048;\n background-color: white;\n display: flex;\n flex-flow: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n}\n.igv-generic-dialog-container .igv-generic-dialog-header {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-end;\n align-items: center;\n width: 100%;\n height: 24px;\n cursor: move;\n border-top-left-radius: 4px;\n border-top-right-radius: 4px;\n border-bottom-color: #7F7F7F;\n border-bottom-style: solid;\n border-bottom-width: thin;\n background-color: #eee;\n}\n.igv-generic-dialog-container .igv-generic-dialog-header div {\n margin-right: 4px;\n margin-bottom: 2px;\n height: 12px;\n width: 12px;\n color: #7F7F7F;\n}\n.igv-generic-dialog-container .igv-generic-dialog-header div:hover {\n cursor: pointer;\n color: #444;\n}\n.igv-generic-dialog-container .igv-generic-dialog-one-liner {\n color: #373737;\n width: 95%;\n height: 24px;\n line-height: 24px;\n text-align: left;\n margin-top: 8px;\n padding-left: 8px;\n overflow-wrap: break-word;\n background-color: white;\n}\n.igv-generic-dialog-container .igv-generic-dialog-label-input {\n margin-top: 8px;\n width: 95%;\n height: 24px;\n color: #373737;\n line-height: 24px;\n padding-left: 8px;\n background-color: white;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n}\n.igv-generic-dialog-container .igv-generic-dialog-label-input div {\n width: 30%;\n height: 100%;\n font-size: 16px;\n text-align: right;\n padding-right: 8px;\n background-color: white;\n}\n.igv-generic-dialog-container .igv-generic-dialog-label-input input {\n display: block;\n height: 100%;\n width: 100%;\n padding-left: 4px;\n font-family: \"Open Sans\", sans-serif;\n font-weight: 400;\n color: #373737;\n text-align: left;\n outline: none;\n border-style: solid;\n border-width: thin;\n border-color: #7F7F7F;\n background-color: white;\n}\n.igv-generic-dialog-container .igv-generic-dialog-label-input input {\n width: 50%;\n font-size: 16px;\n}\n.igv-generic-dialog-container .igv-generic-dialog-input {\n margin-top: 8px;\n width: calc(100% - 16px);\n height: 24px;\n color: #373737;\n line-height: 24px;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-around;\n align-items: center;\n}\n.igv-generic-dialog-container .igv-generic-dialog-input input {\n display: block;\n height: 100%;\n width: 100%;\n padding-left: 4px;\n font-family: \"Open Sans\", sans-serif;\n font-weight: 400;\n color: #373737;\n text-align: left;\n outline: none;\n border-style: solid;\n border-width: thin;\n border-color: #7F7F7F;\n background-color: white;\n}\n.igv-generic-dialog-container .igv-generic-dialog-input input {\n font-size: 16px;\n}\n.igv-generic-dialog-container .igv-generic-dialog-ok-cancel {\n width: 100%;\n height: 28px;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-around;\n align-items: center;\n}\n.igv-generic-dialog-container .igv-generic-dialog-ok-cancel div {\n margin-top: 32px;\n color: white;\n font-family: \"Open Sans\", sans-serif;\n font-size: 14px;\n font-weight: 400;\n width: 75px;\n height: 28px;\n line-height: 28px;\n text-align: center;\n border-color: transparent;\n border-style: solid;\n border-width: thin;\n border-radius: 2px;\n}\n.igv-generic-dialog-container .igv-generic-dialog-ok-cancel div:first-child {\n margin-left: 32px;\n margin-right: 0;\n background-color: #5ea4e0;\n}\n.igv-generic-dialog-container .igv-generic-dialog-ok-cancel div:last-child {\n margin-left: 0;\n margin-right: 32px;\n background-color: #c4c4c4;\n}\n.igv-generic-dialog-container .igv-generic-dialog-ok-cancel div:first-child:hover {\n cursor: pointer;\n background-color: #3b5c7f;\n}\n.igv-generic-dialog-container .igv-generic-dialog-ok-cancel div:last-child:hover {\n cursor: pointer;\n background-color: #7f7f7f;\n}\n.igv-generic-dialog-container .igv-generic-dialog-ok {\n width: 100%;\n height: 36px;\n margin-top: 32px;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-around;\n align-items: center;\n}\n.igv-generic-dialog-container .igv-generic-dialog-ok div {\n width: 98px;\n height: 36px;\n line-height: 36px;\n text-align: center;\n color: white;\n font-family: \"Open Sans\", sans-serif;\n font-size: medium;\n font-weight: 400;\n border-color: white;\n border-style: solid;\n border-width: thin;\n border-radius: 4px;\n background-color: #2B81AF;\n}\n.igv-generic-dialog-container .igv-generic-dialog-ok div:hover {\n cursor: pointer;\n background-color: #25597f;\n}\n\n.igv-generic-container {\n position: absolute;\n top: 0;\n left: 0;\n z-index: 2048;\n background-color: white;\n cursor: pointer;\n display: flex;\n flex-direction: row;\n flex-wrap: wrap;\n justify-content: flex-start;\n align-items: center;\n}\n.igv-generic-container div:first-child {\n cursor: move;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-end;\n align-items: center;\n height: 24px;\n width: 100%;\n background-color: #dddddd;\n}\n.igv-generic-container div:first-child i {\n display: block;\n color: #5f5f5f;\n cursor: pointer;\n width: 14px;\n height: 14px;\n margin-right: 8px;\n margin-bottom: 4px;\n}\n\n.igv-menu-popup {\n position: absolute;\n top: 0;\n left: 0;\n width: max-content;\n z-index: 4096;\n cursor: pointer;\n font-family: \"Open Sans\", sans-serif;\n font-size: small;\n font-weight: 400;\n color: #4b4b4b;\n background: white;\n border-radius: 4px;\n border-color: #7F7F7F;\n border-style: solid;\n border-width: thin;\n display: flex;\n flex-flow: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: flex-end;\n text-align: left;\n}\n.igv-menu-popup > div:not(:first-child) {\n width: 100%;\n}\n.igv-menu-popup > div:not(:first-child) > div {\n background: white;\n}\n.igv-menu-popup > div:not(:first-child) > div.context-menu {\n padding-left: 4px;\n padding-right: 4px;\n}\n.igv-menu-popup > div:not(:first-child) > div:last-child {\n border-bottom-left-radius: 4px;\n border-bottom-right-radius: 4px;\n border-bottom-color: transparent;\n border-bottom-style: solid;\n border-bottom-width: thin;\n}\n.igv-menu-popup > div:not(:first-child) > div:hover {\n background: #efefef;\n}\n\n.igv-menu-popup-shim {\n padding-left: 8px;\n padding-right: 8px;\n padding-bottom: 1px;\n padding-top: 1px;\n}\n\n.igv-menu-popup-header {\n position: relative;\n width: 100%;\n height: 24px;\n cursor: move;\n border-top-color: transparent;\n border-top-left-radius: 4px;\n border-top-right-radius: 4px;\n border-bottom-color: #7F7F7F;\n border-bottom-style: solid;\n border-bottom-width: thin;\n background-color: #eee;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-end;\n align-items: center;\n}\n.igv-menu-popup-header div {\n margin-right: 4px;\n height: 12px;\n width: 12px;\n color: #7F7F7F;\n}\n.igv-menu-popup-header div:hover {\n cursor: pointer;\n color: #444;\n}\n\n.igv-menu-popup-check-container {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n width: 100%;\n height: 20px;\n margin-right: 4px;\n background-color: transparent;\n}\n.igv-menu-popup-check-container div {\n padding-top: 2px;\n padding-left: 8px;\n}\n.igv-menu-popup-check-container div:first-child {\n position: relative;\n width: 12px;\n height: 12px;\n}\n.igv-menu-popup-check-container div:first-child svg {\n position: absolute;\n width: 12px;\n height: 12px;\n}\n\n.igv-user-feedback {\n position: fixed;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: 512px;\n height: 360px;\n z-index: 2048;\n background-color: white;\n border-color: #a2a2a2;\n border-style: solid;\n border-width: thin;\n font-family: \"Open Sans\", sans-serif;\n font-size: medium;\n font-weight: 400;\n color: #444;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n}\n.igv-user-feedback div:first-child {\n position: relative;\n height: 24px;\n width: 100%;\n background-color: white;\n border-bottom-color: #a2a2a2;\n border-bottom-style: solid;\n border-bottom-width: thin;\n}\n.igv-user-feedback div:first-child div {\n position: absolute;\n top: 2px;\n width: 16px;\n height: 16px;\n background-color: transparent;\n}\n.igv-user-feedback div:first-child div:first-child {\n left: 8px;\n}\n.igv-user-feedback div:first-child div:last-child {\n cursor: pointer;\n right: 8px;\n}\n.igv-user-feedback div:last-child {\n width: 100%;\n height: calc(100% - 24px);\n border-width: 0;\n}\n.igv-user-feedback div:last-child div {\n width: auto;\n height: auto;\n margin: 8px;\n}\n\n.igv-loading-spinner-container {\n z-index: 1024;\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: 32px;\n height: 32px;\n display: flex;\n flex-direction: row;\n flex-wrap: nowrap;\n justify-content: center;\n align-items: center;\n}\n.igv-loading-spinner-container > div {\n box-sizing: border-box;\n width: 100%;\n height: 100%;\n border-radius: 50%;\n border: 4px solid rgba(128, 128, 128, 0.5);\n border-top-color: rgb(255, 255, 255);\n animation: spin 1s ease-in-out infinite;\n -webkit-animation: spin 1s ease-in-out infinite;\n}\n\n@keyframes spin {\n to {\n -webkit-transform: rotate(360deg);\n transform: rotate(360deg);\n }\n}\n@-webkit-keyframes spin {\n to {\n -webkit-transform: rotate(360deg);\n transform: rotate(360deg);\n }\n}\n.igv-roi-menu-next-gen {\n position: absolute;\n z-index: 512;\n font-family: \"Open Sans\", sans-serif;\n font-size: small;\n font-weight: 400;\n color: #4b4b4b;\n background-color: white;\n width: 192px;\n border-radius: 4px;\n border-color: #7F7F7F;\n border-style: solid;\n border-width: thin;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: stretch;\n}\n.igv-roi-menu-next-gen > div:first-child {\n height: 24px;\n border-top-color: transparent;\n border-top-left-radius: 4px;\n border-top-right-radius: 4px;\n border-bottom-color: #7F7F7F;\n border-bottom-style: solid;\n border-bottom-width: thin;\n background-color: #eee;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-end;\n align-items: center;\n}\n.igv-roi-menu-next-gen > div:first-child > div {\n margin-right: 4px;\n height: 12px;\n width: 12px;\n color: #7F7F7F;\n}\n.igv-roi-menu-next-gen > div:first-child > div:hover {\n cursor: pointer;\n color: #444;\n}\n.igv-roi-menu-next-gen > div:last-child {\n background-color: white;\n border-bottom-left-radius: 4px;\n border-bottom-right-radius: 4px;\n border-bottom-color: transparent;\n border-bottom-style: solid;\n border-bottom-width: 0;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: stretch;\n text-align: start;\n vertical-align: middle;\n}\n.igv-roi-menu-next-gen > div:last-child > div {\n height: 24px;\n padding-left: 4px;\n border-bottom-style: solid;\n border-bottom-width: thin;\n border-bottom-color: #7f7f7f;\n}\n.igv-roi-menu-next-gen > div:last-child > div:not(:first-child):hover {\n background-color: rgba(127, 127, 127, 0.1);\n}\n.igv-roi-menu-next-gen > div:last-child div:first-child {\n font-style: italic;\n text-align: center;\n padding-right: 4px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n.igv-roi-menu-next-gen > div:last-child > div:last-child {\n border-bottom-width: 0;\n border-bottom-color: transparent;\n}\n\n.igv-roi-placeholder {\n font-style: normal;\n color: rgba(75, 75, 75, 0.6);\n}\n\n.igv-roi-table {\n position: absolute;\n z-index: 1024;\n width: min-content;\n max-width: 1600px;\n border-color: #7f7f7f;\n border-radius: 4px;\n border-style: solid;\n border-width: thin;\n font-family: \"Open Sans\", sans-serif;\n font-size: 12px;\n font-weight: 400;\n background-color: white;\n display: flex;\n flex-flow: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: stretch;\n cursor: default;\n}\n.igv-roi-table > div {\n height: 24px;\n font-size: 14px;\n text-align: start;\n vertical-align: middle;\n line-height: 24px;\n}\n.igv-roi-table > div:first-child {\n border-color: transparent;\n border-top-left-radius: 4px;\n border-top-right-radius: 4px;\n border-top-width: 0;\n border-bottom-color: #7f7f7f;\n border-bottom-style: solid;\n border-bottom-width: thin;\n background-color: #eee;\n cursor: move;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-between;\n align-items: center;\n}\n.igv-roi-table > div:first-child > div:first-child {\n text-align: center;\n white-space: nowrap;\n text-overflow: ellipsis;\n overflow: hidden;\n margin-left: 4px;\n margin-right: 4px;\n width: calc(100% - 4px - 12px);\n}\n.igv-roi-table > div:first-child > div:last-child {\n margin-right: 4px;\n margin-bottom: 2px;\n height: 12px;\n width: 12px;\n color: #7f7f7f;\n}\n.igv-roi-table > div:first-child > div:last-child > svg {\n display: block;\n}\n.igv-roi-table > div:first-child > div:last-child:hover {\n cursor: pointer;\n color: #444;\n}\n.igv-roi-table > .igv-roi-table-description {\n padding: 4px;\n margin-left: 4px;\n word-break: break-all;\n overflow-y: auto;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n background-color: transparent;\n}\n.igv-roi-table > .igv-roi-table-goto-explainer {\n margin-top: 5px;\n margin-left: 4px;\n color: #7F7F7F;\n font-style: italic;\n height: 24px;\n border-top: solid lightgray;\n background-color: transparent;\n}\n.igv-roi-table > .igv-roi-table-column-titles {\n height: 24px;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: stretch;\n align-items: stretch;\n padding-right: 16px;\n background-color: white;\n border-top-color: #7f7f7f;\n border-top-style: solid;\n border-top-width: thin;\n border-bottom-color: #7f7f7f;\n border-bottom-style: solid;\n border-bottom-width: thin;\n}\n.igv-roi-table > .igv-roi-table-column-titles > div {\n font-size: 14px;\n vertical-align: middle;\n line-height: 24px;\n text-align: left;\n margin-left: 4px;\n height: 24px;\n overflow: hidden;\n text-overflow: ellipsis;\n border-right-color: #7f7f7f;\n border-right-style: solid;\n border-right-width: thin;\n}\n.igv-roi-table > .igv-roi-table-column-titles > div:last-child {\n border-right: unset;\n}\n.igv-roi-table > .igv-roi-table-row-container {\n overflow: auto;\n resize: both;\n max-width: 1600px;\n height: 360px;\n background-color: transparent;\n display: flex;\n flex-flow: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: stretch;\n}\n.igv-roi-table > .igv-roi-table-row-container > .igv-roi-table-row {\n height: 24px;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: stretch;\n align-items: stretch;\n}\n.igv-roi-table > .igv-roi-table-row-container > .igv-roi-table-row > div {\n font-size: 14px;\n vertical-align: middle;\n line-height: 24px;\n text-align: left;\n margin-left: 4px;\n height: 24px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n border-right-color: transparent;\n border-right-style: solid;\n border-right-width: thin;\n}\n.igv-roi-table > .igv-roi-table-row-container > .igv-roi-table-row > div:last-child {\n border-right: unset;\n}\n.igv-roi-table > .igv-roi-table-row-container > .igv-roi-table-row-hover {\n background-color: rgba(0, 0, 0, 0.04);\n}\n.igv-roi-table > div:last-child {\n height: 32px;\n line-height: 32px;\n border-top-color: #7f7f7f;\n border-top-style: solid;\n border-top-width: thin;\n border-bottom-color: transparent;\n border-bottom-left-radius: 4px;\n border-bottom-right-radius: 4px;\n border-bottom-width: 0;\n background-color: #eee;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-around;\n align-items: center;\n}\n\n.igv-roi-table-row-selected {\n background-color: rgba(0, 0, 0, 0.125);\n}\n\n.igv-roi-table-button {\n cursor: pointer;\n height: 20px;\n user-select: none;\n line-height: 20px;\n text-align: center;\n vertical-align: middle;\n font-family: \"Open Sans\", sans-serif;\n font-size: 13px;\n font-weight: 400;\n color: black;\n padding-left: 6px;\n padding-right: 6px;\n background-color: rgb(239, 239, 239);\n border-color: black;\n border-style: solid;\n border-width: thin;\n border-radius: 3px;\n}\n\n.igv-roi-table-button:hover {\n font-weight: 400;\n background-color: rgba(0, 0, 0, 0.13);\n}\n\n.igv-roi-region {\n z-index: 64;\n position: absolute;\n top: 0;\n bottom: 0;\n pointer-events: none;\n overflow: visible;\n margin-top: 44px;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: stretch;\n}\n.igv-roi-region > div {\n position: relative;\n width: 100%;\n height: 8px;\n pointer-events: auto;\n}\n\n.igv-roi-menu {\n position: absolute;\n z-index: 1024;\n width: 144px;\n border-color: #7f7f7f;\n border-radius: 4px;\n border-style: solid;\n border-width: thin;\n font-family: \"Open Sans\", sans-serif;\n background-color: white;\n display: flex;\n flex-flow: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: stretch;\n}\n.igv-roi-menu > div:not(:last-child) {\n border-bottom-color: rgba(128, 128, 128, 0.5);\n border-bottom-style: solid;\n border-bottom-width: thin;\n}\n.igv-roi-menu > div:first-child {\n border-top-left-radius: 4px;\n border-top-right-radius: 4px;\n border-top-color: transparent;\n border-top-style: solid;\n border-top-width: 0;\n}\n.igv-roi-menu > div:last-child {\n border-bottom-left-radius: 4px;\n border-bottom-right-radius: 4px;\n border-bottom-color: transparent;\n border-bottom-style: solid;\n border-bottom-width: 0;\n}\n\n.igv-roi-menu-row {\n height: 24px;\n padding-left: 8px;\n font-size: small;\n text-align: start;\n vertical-align: middle;\n line-height: 24px;\n background-color: white;\n}\n\n.igv-roi-menu-row-edit-description {\n width: -webkit-fill-available;\n font-size: small;\n text-align: start;\n vertical-align: middle;\n background-color: white;\n padding-left: 4px;\n padding-right: 4px;\n padding-bottom: 4px;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: stretch;\n align-items: stretch;\n}\n.igv-roi-menu-row-edit-description > label {\n margin-left: 2px;\n margin-bottom: 0;\n display: block;\n width: -webkit-fill-available;\n}\n.igv-roi-menu-row-edit-description > input {\n display: block;\n margin-left: 2px;\n margin-right: 2px;\n margin-bottom: 1px;\n width: -webkit-fill-available;\n}\n\n.igv-container {\n position: relative;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: flex-start;\n padding-top: 4px;\n user-select: none;\n -webkit-user-select: none;\n -ms-user-select: none;\n}\n\n.igv-viewport {\n position: relative;\n margin-top: 5px;\n line-height: 1;\n overflow-x: hidden;\n overflow-y: hidden;\n}\n\n.igv-viewport-content {\n position: relative;\n width: 100%;\n}\n.igv-viewport-content > canvas {\n position: relative;\n display: block;\n}\n\n.igv-column-container {\n position: relative;\n display: flex;\n flex-direction: row;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: stretch;\n width: 100%;\n}\n\n.igv-column-shim {\n width: 1px;\n margin-left: 2px;\n margin-right: 2px;\n background-color: #545453;\n}\n\n.igv-column {\n position: relative;\n position: relative;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: flex-start;\n box-sizing: border-box;\n height: 100%;\n}\n\n.igv-axis-column {\n position: relative;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: flex-start;\n box-sizing: border-box;\n height: 100%;\n width: 50px;\n}\n.igv-axis-column > div {\n margin-top: 5px;\n width: 100%;\n}\n\n.igv-sample-name-column {\n position: relative;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: flex-start;\n box-sizing: border-box;\n height: 100%;\n}\n\n.igv-scrollbar-column {\n position: relative;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: flex-start;\n box-sizing: border-box;\n height: 100%;\n width: 14px;\n}\n.igv-scrollbar-column > div {\n position: relative;\n margin-top: 5px;\n width: 14px;\n}\n.igv-scrollbar-column > div > div {\n cursor: pointer;\n position: absolute;\n top: 0;\n left: 2px;\n width: 8px;\n border-width: 1px;\n border-style: solid;\n border-color: #c4c4c4;\n border-top-left-radius: 4px;\n border-top-right-radius: 4px;\n border-bottom-left-radius: 4px;\n border-bottom-right-radius: 4px;\n}\n.igv-scrollbar-column > div > div:hover {\n background-color: #c4c4c4;\n}\n\n.igv-track-drag-column {\n position: relative;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: flex-start;\n box-sizing: border-box;\n height: 100%;\n width: 12px;\n background-color: white;\n}\n.igv-track-drag-column > .igv-track-drag-handle {\n z-index: 512;\n position: relative;\n cursor: pointer;\n margin-top: 5px;\n width: 100%;\n border-style: solid;\n border-width: 0;\n border-top-right-radius: 6px;\n border-bottom-right-radius: 6px;\n background-color: #c4c4c4;\n}\n.igv-track-drag-column .igv-track-drag-handle-hover {\n background-color: #787878;\n}\n.igv-track-drag-column > .igv-track-drag-shim {\n position: relative;\n margin-top: 5px;\n width: 100%;\n border-style: solid;\n border-width: 0;\n}\n\n.igv-gear-menu-column {\n position: relative;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: flex-start;\n box-sizing: border-box;\n height: 100%;\n width: 28px;\n}\n.igv-gear-menu-column > div {\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n margin-top: 5px;\n width: 100%;\n background: white;\n}\n.igv-gear-menu-column > div > div {\n position: relative;\n margin-top: 4px;\n width: 16px;\n height: 16px;\n color: #7F7F7F;\n}\n.igv-gear-menu-column > div > div:hover {\n cursor: pointer;\n color: #444;\n}\n\n/*# sourceMappingURL=dom.css.map */\n'; - - var style = document.createElement('style'); - style.setAttribute('type', 'text/css'); - style.innerHTML = css; - - document.head.append(style); - -} - -// Defines the top-level API for the igv module - -const setApiKey = igvxhr.setApiKey; - -embedCSS$3(); - -function setGoogleOauthToken(accessToken) { - return igvxhr.setOauthToken(accessToken) -} - -function setOauthToken(accessToken, host) { - return igvxhr.setOauthToken(accessToken, host) -} - -// Backward compatibility -const oauth = igvxhr.oauth; - -var index$1 = { - TrackUtils, - IGVGraphics, - MenuUtils: MenuUtils$1, - DataRangeDialog: DataRangeDialog$1, - createTrack, - createBrowser: createBrowser$1, - removeBrowser, - removeAllBrowsers, - visibilityChange, - setGoogleOauthToken, - setOauthToken, - oauth, - version: version$2, - setApiKey, - registerFileFormats -}; - -function div(options) { - return create("div", options); -} - -function create(tag, options) { - const elem = document.createElement(tag); - if (options) { - if (options.class) { - elem.classList.add(options.class); - } - if (options.id) { - elem.id = options.id; - } - if(options.style) { - applyStyle(elem, options.style); - } - } - return elem; -} - -function hide(elem) { - const cssStyle = getComputedStyle(elem); - if(cssStyle.display !== "none") { - elem._initialDisplay = cssStyle.display; - } - elem.style.display = "none"; -} - -function show(elem) { - const currentDisplay = getComputedStyle(elem).display; - if (currentDisplay === "none") { - const d = elem._initialDisplay || "block"; - elem.style.display = d; - } -} - -function hideAll(selector) { - document.querySelectorAll(selector).forEach(elem => { hide(elem); }); -} - -function empty(elem) { - while(elem.firstChild){ - elem.removeChild(elem.firstChild); - } -} - -function offset(elem) { - // Return zeros for disconnected and hidden (display: none) elements (gh-2310) - // Support: IE <=11 only - // Running getBoundingClientRect on a - // disconnected node in IE throws an error - if (!elem.getClientRects().length) { - return {top: 0, left: 0}; - } - - // Get document-relative position by adding viewport scroll to viewport-relative gBCR - const rect = elem.getBoundingClientRect(); - const win = elem.ownerDocument.defaultView; - return { - top: rect.top + win.pageYOffset, - left: rect.left + win.pageXOffset - }; -} - -function pageCoordinates(e) { - - if (e.type.startsWith("touch")) { - const touch = e.touches[0]; - return {x: touch.pageX, y: touch.pageY}; - } else { - return {x: e.pageX, y: e.pageY} - } -} - -const relativeDOMBBox = (parentElement, childElement) => { - const { x: x_p, y: y_p, width: width_p, height: height_p } = parentElement.getBoundingClientRect(); - const { x: x_c, y: y_c, width: width_c, height: height_c } = childElement.getBoundingClientRect(); - return { x: (x_c - x_p), y: (y_c - y_p), width: width_c, height:height_c }; -}; - -function applyStyle(elem, style) { - for (let key of Object.keys(style)) { - elem.style[key] = style[key]; - } -} - -function guid () { - return ("0000" + (Math.random() * Math.pow(36, 4) << 0).toString(36)).slice(-4); -} - -let getMouseXY = (domElement, { clientX, clientY }) => { - - // DOMRect object with eight properties: left, top, right, bottom, x, y, width, height - const { left, top, width, height } = domElement.getBoundingClientRect(); - - const x = clientX - left; - const y = clientY - top; - return { x, y, xNormalized: x/width, yNormalized: y/height, width, height }; - -}; - -/** - * Translate the mouse coordinates for the event to the coordinates for the given target element - * @param event - * @param domElement - * @returns {{x: number, y: number}} - */ -function translateMouseCoordinates(event, domElement) { - - const { clientX, clientY } = event; - return getMouseXY(domElement, { clientX, clientY }); - -} - -var domUtils = /*#__PURE__*/Object.freeze({ - __proto__: null, - applyStyle: applyStyle, - create: create, - div: div, - empty: empty, - guid: guid, - hide: hide, - hideAll: hideAll, - offset: offset, - pageCoordinates: pageCoordinates, - relativeDOMBBox: relativeDOMBBox, - show: show, - translateMouseCoordinates: translateMouseCoordinates -}); - -class Textbox { - - constructor({value, label, onchange}) { - - this.elem = div({class: 'igv-ui-generic-dialog-label-input'}); - - if(label) { - const div$1 = div(); - div$1.innerHTML = label; - this.elem.appendChild(div$1); - } - - this.textBox = create('input'); - if(value) { - this.textBox.value = value; - } - this.elem.appendChild(this.textBox); - - if(onchange) { - this.textBox.addEventListener('change', (e) => onchange(this.textBox.value)); - } - } - - get value() { - return this.textBox.value; - } - - set value(v) { - this.textBox.value = v; - } -} - -/** - * Generic container for UI components - */ -class Panel { - - constructor() { - - this.elem = create('div', { - class: 'igv-ui-panel-column' - }); - } - - add(component) { - - if(component instanceof Node) { - this.elem.append(component); - } - else if(typeof component === 'object') { - this.elem.append(component.elem); - } - else { - // Assuming a string, possibly html - const wrapper = div(); - wrapper.innerHTML = component; - this.elem.append(wrapper); - } - } - - -} - -function createIcon$1(name, color) { - return iconMarkup$1(name, color); -} - -function iconMarkup$1(name, color) { - color = color || "currentColor"; - let icon = icons$1[name]; - if (!icon) { - console.error(`No icon named: ${name}`); - icon = icons$1["question"]; - } - - const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg"); - svg.setAttributeNS(null,'viewBox', '0 0 ' + icon[0] + ' ' + icon[1]); - const path = document.createElementNS("http://www.w3.org/2000/svg", "path"); - path.setAttributeNS(null,'fill', color ); - path.setAttributeNS(null,'d', icon[4]); - svg.appendChild(path); - return svg; -} - -const icons$1 = { - "check": [512, 512, [], "f00c", "M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z"], - "cog": [512, 512, [], "f013", "M444.788 291.1l42.616 24.599c4.867 2.809 7.126 8.618 5.459 13.985-11.07 35.642-29.97 67.842-54.689 94.586a12.016 12.016 0 0 1-14.832 2.254l-42.584-24.595a191.577 191.577 0 0 1-60.759 35.13v49.182a12.01 12.01 0 0 1-9.377 11.718c-34.956 7.85-72.499 8.256-109.219.007-5.49-1.233-9.403-6.096-9.403-11.723v-49.184a191.555 191.555 0 0 1-60.759-35.13l-42.584 24.595a12.016 12.016 0 0 1-14.832-2.254c-24.718-26.744-43.619-58.944-54.689-94.586-1.667-5.366.592-11.175 5.459-13.985L67.212 291.1a193.48 193.48 0 0 1 0-70.199l-42.616-24.599c-4.867-2.809-7.126-8.618-5.459-13.985 11.07-35.642 29.97-67.842 54.689-94.586a12.016 12.016 0 0 1 14.832-2.254l42.584 24.595a191.577 191.577 0 0 1 60.759-35.13V25.759a12.01 12.01 0 0 1 9.377-11.718c34.956-7.85 72.499-8.256 109.219-.007 5.49 1.233 9.403 6.096 9.403 11.723v49.184a191.555 191.555 0 0 1 60.759 35.13l42.584-24.595a12.016 12.016 0 0 1 14.832 2.254c24.718 26.744 43.619 58.944 54.689 94.586 1.667 5.366-.592 11.175-5.459 13.985L444.788 220.9a193.485 193.485 0 0 1 0 70.2zM336 256c0-44.112-35.888-80-80-80s-80 35.888-80 80 35.888 80 80 80 80-35.888 80-80z"], - "exclamation": [192, 512, [], "f12a", "M176 432c0 44.112-35.888 80-80 80s-80-35.888-80-80 35.888-80 80-80 80 35.888 80 80zM25.26 25.199l13.6 272C39.499 309.972 50.041 320 62.83 320h66.34c12.789 0 23.331-10.028 23.97-22.801l13.6-272C167.425 11.49 156.496 0 142.77 0H49.23C35.504 0 24.575 11.49 25.26 25.199z"], - "exclamation-circle": [512, 512, [], "f06a", "M504 256c0 136.997-111.043 248-248 248S8 392.997 8 256C8 119.083 119.043 8 256 8s248 111.083 248 248zm-248 50c-25.405 0-46 20.595-46 46s20.595 46 46 46 46-20.595 46-46-20.595-46-46-46zm-43.673-165.346l7.418 136c.347 6.364 5.609 11.346 11.982 11.346h48.546c6.373 0 11.635-4.982 11.982-11.346l7.418-136c.375-6.874-5.098-12.654-11.982-12.654h-63.383c-6.884 0-12.356 5.78-11.981 12.654z"], - "exclamation-triangle": [576, 512, [], "f071", "M569.517 440.013C587.975 472.007 564.806 512 527.94 512H48.054c-36.937 0-59.999-40.055-41.577-71.987L246.423 23.985c18.467-32.009 64.72-31.951 83.154 0l239.94 416.028zM288 354c-25.405 0-46 20.595-46 46s20.595 46 46 46 46-20.595 46-46-20.595-46-46-46zm-43.673-165.346l7.418 136c.347 6.364 5.609 11.346 11.982 11.346h48.546c6.373 0 11.635-4.982 11.982-11.346l7.418-136c.375-6.874-5.098-12.654-11.982-12.654h-63.383c-6.884 0-12.356 5.78-11.981 12.654z"], - "minus": [448, 512, [], "f068", "M424 318.2c13.3 0 24-10.7 24-24v-76.4c0-13.3-10.7-24-24-24H24c-13.3 0-24 10.7-24 24v76.4c0 13.3 10.7 24 24 24h400z"], - "minus-circle": [512, 512, [], "f056", "M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zM124 296c-6.6 0-12-5.4-12-12v-56c0-6.6 5.4-12 12-12h264c6.6 0 12 5.4 12 12v56c0 6.6-5.4 12-12 12H124z"], - "minus-square": [448, 512, [], "f146", "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM92 296c-6.6 0-12-5.4-12-12v-56c0-6.6 5.4-12 12-12h264c6.6 0 12 5.4 12 12v56c0 6.6-5.4 12-12 12H92z"], - "plus": [448, 512, [], "f067", "M448 294.2v-76.4c0-13.3-10.7-24-24-24H286.2V56c0-13.3-10.7-24-24-24h-76.4c-13.3 0-24 10.7-24 24v137.8H24c-13.3 0-24 10.7-24 24v76.4c0 13.3 10.7 24 24 24h137.8V456c0 13.3 10.7 24 24 24h76.4c13.3 0 24-10.7 24-24V318.2H424c13.3 0 24-10.7 24-24z"], - "plus-circle": [512, 512, [], "f055", "M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm144 276c0 6.6-5.4 12-12 12h-92v92c0 6.6-5.4 12-12 12h-56c-6.6 0-12-5.4-12-12v-92h-92c-6.6 0-12-5.4-12-12v-56c0-6.6 5.4-12 12-12h92v-92c0-6.6 5.4-12 12-12h56c6.6 0 12 5.4 12 12v92h92c6.6 0 12 5.4 12 12v56z"], - "plus-square": [448, 512, [], "f0fe", "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-32 252c0 6.6-5.4 12-12 12h-92v92c0 6.6-5.4 12-12 12h-56c-6.6 0-12-5.4-12-12v-92H92c-6.6 0-12-5.4-12-12v-56c0-6.6 5.4-12 12-12h92v-92c0-6.6 5.4-12 12-12h56c6.6 0 12 5.4 12 12v92h92c6.6 0 12 5.4 12 12v56z"], - "question": [384, 512, [], "f128", "M202.021 0C122.202 0 70.503 32.703 29.914 91.026c-7.363 10.58-5.093 25.086 5.178 32.874l43.138 32.709c10.373 7.865 25.132 6.026 33.253-4.148 25.049-31.381 43.63-49.449 82.757-49.449 30.764 0 68.816 19.799 68.816 49.631 0 22.552-18.617 34.134-48.993 51.164-35.423 19.86-82.299 44.576-82.299 106.405V320c0 13.255 10.745 24 24 24h72.471c13.255 0 24-10.745 24-24v-5.773c0-42.86 125.268-44.645 125.268-160.627C377.504 66.256 286.902 0 202.021 0zM192 373.459c-38.196 0-69.271 31.075-69.271 69.271 0 38.195 31.075 69.27 69.271 69.27s69.271-31.075 69.271-69.271-31.075-69.27-69.271-69.27z"], - "save": [448, 512, [], "f0c7", "M433.941 129.941l-83.882-83.882A48 48 0 0 0 316.118 32H48C21.49 32 0 53.49 0 80v352c0 26.51 21.49 48 48 48h352c26.51 0 48-21.49 48-48V163.882a48 48 0 0 0-14.059-33.941zM224 416c-35.346 0-64-28.654-64-64 0-35.346 28.654-64 64-64s64 28.654 64 64c0 35.346-28.654 64-64 64zm96-304.52V212c0 6.627-5.373 12-12 12H76c-6.627 0-12-5.373-12-12V108c0-6.627 5.373-12 12-12h228.52c3.183 0 6.235 1.264 8.485 3.515l3.48 3.48A11.996 11.996 0 0 1 320 111.48z"], - "search": [512, 512, [], "f002", "M505 442.7L405.3 343c-4.5-4.5-10.6-7-17-7H372c27.6-35.3 44-79.7 44-128C416 93.1 322.9 0 208 0S0 93.1 0 208s93.1 208 208 208c48.3 0 92.7-16.4 128-44v16.3c0 6.4 2.5 12.5 7 17l99.7 99.7c9.4 9.4 24.6 9.4 33.9 0l28.3-28.3c9.4-9.4 9.4-24.6.1-34zM208 336c-70.7 0-128-57.2-128-128 0-70.7 57.2-128 128-128 70.7 0 128 57.2 128 128 0 70.7-57.2 128-128 128z"], - "share": [512, 512, [], "f064", "M503.691 189.836L327.687 37.851C312.281 24.546 288 35.347 288 56.015v80.053C127.371 137.907 0 170.1 0 322.326c0 61.441 39.581 122.309 83.333 154.132 13.653 9.931 33.111-2.533 28.077-18.631C66.066 312.814 132.917 274.316 288 272.085V360c0 20.7 24.3 31.453 39.687 18.164l176.004-152c11.071-9.562 11.086-26.753 0-36.328z"], - "spinner": [512, 512, [], "f110", "M304 48c0 26.51-21.49 48-48 48s-48-21.49-48-48 21.49-48 48-48 48 21.49 48 48zm-48 368c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48-21.49-48-48-48zm208-208c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48-21.49-48-48-48zM96 256c0-26.51-21.49-48-48-48S0 229.49 0 256s21.49 48 48 48 48-21.49 48-48zm12.922 99.078c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48c0-26.509-21.491-48-48-48zm294.156 0c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48c0-26.509-21.49-48-48-48zM108.922 60.922c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48-21.491-48-48-48z"], - "square": [448, 512, [], "f0c8", "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48z"], - "square-full": [512, 512, [], "f45c", "M512 512H0V0h512v512z"], - "times": [384, 512, [], "f00d", "M323.1 441l53.9-53.9c9.4-9.4 9.4-24.5 0-33.9L279.8 256l97.2-97.2c9.4-9.4 9.4-24.5 0-33.9L323.1 71c-9.4-9.4-24.5-9.4-33.9 0L192 168.2 94.8 71c-9.4-9.4-24.5-9.4-33.9 0L7 124.9c-9.4 9.4-9.4 24.5 0 33.9l97.2 97.2L7 353.2c-9.4 9.4-9.4 24.5 0 33.9L60.9 441c9.4 9.4 24.5 9.4 33.9 0l97.2-97.2 97.2 97.2c9.3 9.3 24.5 9.3 33.9 0z"], - "times-circle": [512, 512, [], "f057", "M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm121.6 313.1c4.7 4.7 4.7 12.3 0 17L338 377.6c-4.7 4.7-12.3 4.7-17 0L256 312l-65.1 65.6c-4.7 4.7-12.3 4.7-17 0L134.4 338c-4.7-4.7-4.7-12.3 0-17l65.6-65-65.6-65.1c-4.7-4.7-4.7-12.3 0-17l39.6-39.6c4.7-4.7 12.3-4.7 17 0l65 65.7 65.1-65.6c4.7-4.7 12.3-4.7 17 0l39.6 39.6c4.7 4.7 4.7 12.3 0 17L312 256l65.6 65.1z"], - "wrench": [512, 512, [], "f0ad", "M481.156 200c9.3 0 15.12 10.155 10.325 18.124C466.295 259.992 420.419 288 368 288c-79.222 0-143.501-63.974-143.997-143.079C223.505 65.469 288.548-.001 368.002 0c52.362.001 98.196 27.949 123.4 69.743C496.24 77.766 490.523 88 481.154 88H376l-40 56 40 56h105.156zm-171.649 93.003L109.255 493.255c-24.994 24.993-65.515 24.994-90.51 0-24.993-24.994-24.993-65.516 0-90.51L218.991 202.5c16.16 41.197 49.303 74.335 90.516 90.503zM104 432c0-13.255-10.745-24-24-24s-24 10.745-24 24 10.745 24 24 24 24-10.745 24-24z"], -}; - -function attachDialogCloseHandlerWithParent(parent, closeHandler) { - - var container = document.createElement("div"); - parent.appendChild(container); - container.appendChild(createIcon$1("times")); - container.addEventListener('click', function (e) { - e.preventDefault(); - e.stopPropagation(); - closeHandler(); - }); -} - -var uiUtils = /*#__PURE__*/Object.freeze({ - __proto__: null, - attachDialogCloseHandlerWithParent: attachDialogCloseHandlerWithParent -}); - -/** - * Make the target element movable by clicking and dragging on the handle. This is not a general purprose function, - * it makes several options specific to igv dialogs, the primary one being that the - * target is absolutely positioned in pixel coordinates - - */ - -let dragData; // Its assumed we are only dragging one element at a time. - -function makeDraggable(target, handle, constraint) { - - handle.addEventListener('mousedown', dragStart.bind(target)); - - function dragStart(event) { - - event.stopPropagation(); - event.preventDefault(); - - const dragFunction = drag.bind(this); - const dragEndFunction = dragEnd.bind(this); - const computedStyle = getComputedStyle(this); - - dragData = - { - constraint, - dragFunction, - dragEndFunction, - screenX: event.screenX, - screenY: event.screenY, - top: parseInt(computedStyle.top.replace("px", "")), - left: parseInt(computedStyle.left.replace("px", "")) - }; - - document.addEventListener('mousemove', dragFunction); - document.addEventListener('mouseup', dragEndFunction); - document.addEventListener('mouseleave', dragEndFunction); - document.addEventListener('mouseexit', dragEndFunction); - } -} - -function drag(event) { - - if (!dragData) { - console.error("No drag data!"); - return; - } - event.stopPropagation(); - event.preventDefault(); - const dx = event.screenX - dragData.screenX; - const dy = event.screenY - dragData.screenY; - - const left = dragData.left + dx; - const top = dragData.constraint ? Math.max(dragData.constraint.minY, dragData.top + dy) : dragData.top + dy; - - this.style.left = `${ left }px`; - this.style.top = `${ top }px`; -} - -function dragEnd(event) { - - if (!dragData) { - console.error("No drag data!"); - return; - } - event.stopPropagation(); - event.preventDefault(); - - const dragFunction = dragData.dragFunction; - const dragEndFunction = dragData.dragEndFunction; - document.removeEventListener('mousemove', dragFunction); - document.removeEventListener('mouseup', dragEndFunction); - document.removeEventListener('mouseleave', dragEndFunction); - document.removeEventListener('mouseexit', dragEndFunction); - dragData = undefined; -} - -class Dialog { - - constructor({label, content, okHandler, cancelHandler}) { - - const cancel = () => { - hide(this.elem); - if (typeof cancelHandler === 'function') { - cancelHandler(this); - } - }; - - // dialog container - this.elem = div({class: 'igv-ui-generic-dialog-container'}); - - // dialog header - const header = div({class: 'igv-ui-generic-dialog-header'}); - this.elem.appendChild(header); - - attachDialogCloseHandlerWithParent(header, cancel); - - // dialog label - if(label) { - const labelDiv = div({class: 'igv-ui-dialog-one-liner'}); - this.elem.appendChild(labelDiv); - labelDiv.innerHTML = label; - } - - // input container - content.elem.style.margin = '8px'; - this.elem.appendChild(content.elem); - - // ok | cancel - const buttons = div({class: 'igv-ui-generic-dialog-ok-cancel'}); - this.elem.appendChild(buttons); - - // ok - this.ok = div(); - buttons.appendChild(this.ok); - this.ok.textContent = 'OK'; - - // cancel - this.cancel = div(); - buttons.appendChild(this.cancel); - this.cancel.textContent = 'Cancel'; - - this.ok.addEventListener('click', (e) => { - hide(this.elem); - if (typeof okHandler === 'function') { - okHandler(this); - } - }); - - this.cancel.addEventListener('click', cancel); - - makeDraggable(this.elem, header); - - - // Consume all clicks in component - this.elem.addEventListener('click', (e) => { - e.preventDefault(); - e.stopPropagation(); - }); - - } - - present(options, e) { - - this.label.textContent = options.label; - this.input.value = options.value; - this.callback = options.callback; - - const page = pageCoordinates(e); - this.clampLocation(page.x, page.y); - - show(this.elem); - } - - clampLocation(pageX, pageY) { - - let popoverRect = this.elem.getBoundingClientRect(); - let parentRect = this.parent.getBoundingClientRect(); - const y = Math.min(Math.max(pageY, parentRect.y), parentRect.y + parentRect.height - popoverRect.height); - const x = Math.min(Math.max(pageX, parentRect.x), parentRect.x + parentRect.width - popoverRect.width); - this.elem.style.left = x + "px"; - this.elem.style.top = y + "px"; - } -} - -class DataRangeDialog { - - constructor(parent, okHandler) { - - const panel = new Panel(); - this.minbox = new Textbox({label: "Minimum", value: "0"}); - panel.add(this.minbox); - - this.maxbox = new Textbox({label: "Maximum", value: "0"}); - panel.add(this.maxbox); - - let callback; - if (okHandler) { - callback = (e) => { - okHandler(Number.parseFloat(this.minbox.value), Number.parseFloat(this.maxbox.value)); - }; - } else { - callback = (d) => { - console.log(`Minimum: ${this.minbox.value}`); - console.log(`Maximum: ${this.maxbox.value}`); - }; - } - - this.dialog = new Dialog({ - //label: 'Multi-select', - content: panel, - okHandler: callback - }); - - // Overide some css styles -- TODO redesign this. - this.dialog.elem.style.position = "absolute"; - - hide(this.dialog.elem); - parent.appendChild(this.dialog.elem); - } - - show({min, max}) { - if (min !== undefined) this.minbox.value = min.toString(); - if (max !== undefined) this.maxbox.value = max.toString(); - show(this.dialog.elem); - } -} - -const httpMessages = - { - "401": "Access unauthorized", - "403": "Access forbidden", - "404": "Not found" - }; - - -class AlertDialog { - /** - * Initialize a new alert dialog - * @param parent - * @param alertProps - Optional - properties such as scroll to error - */ - constructor(parent, alertProps) { - this.alertProps = Object.assign({ - /** When an alert is presented - focus occur */ - shouldFocus: true, - /** When focus occur - scroll into that element in the view */ - preventScroll: false - }, alertProps); - - // container - this.container = div({class: "igv-ui-alert-dialog-container"}); - parent.appendChild(this.container); - this.container.setAttribute('tabIndex', '-1'); - - // header - const header = div(); - this.container.appendChild(header); - - this.errorHeadline = div(); - header.appendChild(this.errorHeadline); - this.errorHeadline.textContent = ''; - - // body container - let bodyContainer = div({class: 'igv-ui-alert-dialog-body'}); - this.container.appendChild(bodyContainer); - - // body copy - this.body = div({class: 'igv-ui-alert-dialog-body-copy'}); - bodyContainer.appendChild(this.body); - - // ok container - let ok_container = div(); - this.container.appendChild(ok_container); - - // ok - this.ok = div(); - ok_container.appendChild(this.ok); - this.ok.textContent = 'OK'; - - const okHandler = () => { - - if (typeof this.callback === 'function') { - this.callback("OK"); - this.callback = undefined; - } - this.body.innerHTML = ''; - hide(this.container); - }; - - this.ok.addEventListener('click', event => { - - event.stopPropagation(); - - okHandler(); - }); - - this.container.addEventListener('keypress', event => { - - event.stopPropagation(); - - if ('Enter' === event.key) { - okHandler(); - } - }); - - makeDraggable(this.container, header); - - hide(this.container); - } - - present(alert, callback) { - - this.errorHeadline.textContent = alert.message ? 'ERROR' : ''; - let string = alert.message || alert; - - if (httpMessages.hasOwnProperty(string)) { - string = httpMessages[string]; - } - - this.body.innerHTML = string; - this.callback = callback; - show(this.container); - if (this.alertProps.shouldFocus) { - this.container.focus( - { preventScroll: this.alertProps.preventScroll } - ); - } - } -} - -// The global Alert dialog - -let alertDialog; - -const Alert$1 = { - - init(root, config={}) { - alertDialog = new AlertDialog(root, config); - }, - - presentAlert (alert, callback) { - if(!alertDialog) { - this.init(document.body); - } - alertDialog.present(alert, callback); - }, -}; - -class InputDialog { - - constructor(parent) { - - this.parent = parent; - - // dialog container - this.container = div({class: 'igv-ui-generic-dialog-container'}); - parent.appendChild(this.container); - - // const { x, y, width, height } = this.container.getBoundingClientRect(); - // console.log(`InputDialog - x ${ x } y ${ y } width ${ width } height ${ height }`) - - // dialog header - const header = div({class: 'igv-ui-generic-dialog-header'}); - this.container.appendChild(header); - - // dialog label - this.label = div({class: 'igv-ui-generic-dialog-one-liner'}); - this.container.appendChild(this.label); - this.label.text = 'Unlabeled'; - - // input container - this.input_container = div({class: 'igv-ui-generic-dialog-input'}); - this.container.appendChild(this.input_container); - // - this.input = document.createElement("input"); - this.input_container.appendChild(this.input); - - - // ok | cancel - const buttons = div({class: 'igv-ui-generic-dialog-ok-cancel'}); - this.container.appendChild(buttons); - - // ok - this.ok = div(); - buttons.appendChild(this.ok); - this.ok.textContent = 'OK'; - - // cancel - this.cancel = div(); - buttons.appendChild(this.cancel); - this.cancel.textContent = 'Cancel'; - - hide(this.container); - - this.input.addEventListener('keyup', e => { - if (13 === e.keyCode) { - if (typeof this.callback === 'function') { - this.callback(this.input.value); - this.callback = undefined; - } - this.input.value = undefined; - hide(this.container); - } - }); - - this.ok.addEventListener('click', () => { - if (typeof this.callback === 'function') { - this.callback(this.input.value); - this.callback = undefined; - } - this.input.value = undefined; - hide(this.container); - }); - - const cancel = () => { - this.input.value = ''; - hide(this.container); - }; - - this.cancel.addEventListener('click', cancel); - - attachDialogCloseHandlerWithParent(header, cancel); - makeDraggable(this.container, header); - - } - - present(options, e) { - - this.label.textContent = options.label; - this.input.value = options.value; - this.callback = options.callback || options.click; - - show(this.container); - this.clampLocation(e.clientX, e.clientY); - - } - - clampLocation(clientX, clientY) { - - const { width:w, height:h } = this.container.getBoundingClientRect(); - const wh = window.innerHeight; - const ww = window.innerWidth; - - const y = Math.min(wh - h, clientY); - const x = Math.min(ww - w, clientX); - this.container.style.left = `${ x }px`; - this.container.style.top = `${ y }px`; - - } -} - -const appleCrayonPalette = - { - licorice: "#000000", - lead: "#1e1e1e", - tungsten: "#3a3a3a", - iron: "#545453", - steel: "#6e6e6e", - tin: "#878687", - nickel: "#888787", - aluminum: "#a09fa0", - magnesium: "#b8b8b8", - silver: "#d0d0d0", - mercury: "#e8e8e8", - snow: "#ffffff", - // - cayenne: "#891100", - mocha: "#894800", - aspargus: "#888501", - fern: "#458401", - clover: "#028401", - moss: "#018448", - teal: "#008688", - ocean: "#004a88", - midnight: "#001888", - eggplant: "#491a88", - plum: "#891e88", - maroon: "#891648", - // - maraschino: "#ff2101", - tangerine: "#ff8802", - lemon: "#fffa03", - lime: "#83f902", - spring: "#05f802", - seam_foam: "#03f987", - turquoise: "#00fdff", - aqua: "#008cff", - blueberry: "#002eff", - grape: "#8931ff", - magenta: "#ff39ff", - strawberry: "#ff2987", - // - salmon: "#ff726e", - cantaloupe: "#ffce6e", - banana: "#fffb6d", - honeydew: "#cefa6e", - flora: "#68f96e", - spindrift: "#68fbd0", - ice: "#68fdff", - sky: "#6acfff", - orchid: "#6e76ff", - lavender: "#d278ff", - bubblegum: "#ff7aff", - carnation: "#ff7fd3" - }; - -class GenericContainer { - - constructor({parent, top, left, width, height, border, closeHandler}) { - - let container = div({class: 'igv-ui-generic-container'}); - parent.appendChild(container); - hide(container); - this.container = container; - - if(top !== undefined) { - this.container.style.top = `${ top }px`; - } - if(left !== undefined) { - this.container.style.left = `${ left }px`; - } - if (width !== undefined) { - this.container.style.width = `${ width }px`; - } - if (height !== undefined) { - this.container.style.height = `${ height }px`; - } - if(border) { - this.container.style.border = border; - } - // - // let bbox = parent.getBoundingClientRect(); - // this.origin = {x: bbox.x, y: bbox.y}; - // this.container.offset({left: this.origin.x, top: this.origin.y}); - - // header - const header = div(); - this.container.appendChild(header); - - // close button - attachDialogCloseHandlerWithParent(header, (e) => { - hide(this.container); - if(typeof closeHandler === "function") { - closeHandler(e); - } - }); - - makeDraggable(this.container, header); - } - - show() { - show(this.container); - } - - hide() { - hide(this.container); - } - - dispose() { - if(this.container.parent) { - this.container.parent.removeChild(this.container); - } - } -} - -class ColorPicker extends GenericContainer { - - constructor({parent, top, left, width, height, defaultColors, colorHandler}) { - - super({ parent, top, left, width, height, border: '1px solid gray'}); - - createColorSwatchSelector(this.container, colorHandler, defaultColors); - } - -} - -const createColorSwatchSelector = (container, colorHandler, defaultColors) => { - - const hexColorStrings = Object.values(appleCrayonPalette); - - for (let hexColorString of hexColorStrings) { - const swatch = div({ class: 'igv-ui-color-swatch' }); - container.appendChild(swatch); - decorateSwatch(swatch, hexColorString, colorHandler); - } - - if (defaultColors) { - for (let hexColorString of defaultColors) { - const swatch = div({ class: 'igv-ui-color-swatch' }); - container.appendChild(swatch); - decorateSwatch(swatch, hexColorString, colorHandler); - } - } - -}; - -const decorateSwatch = (swatch, hexColorString, colorHandler) => { - - swatch.style.backgroundColor = hexColorString; - - swatch.addEventListener('mouseenter', e => swatch.style.borderColor = hexColorString); - - swatch.addEventListener('mouseleave', e => swatch.style.borderColor = 'white'); - - swatch.addEventListener('click', event => { - event.stopPropagation(); - colorHandler(hexColorString); - }); - - swatch.addEventListener('touchend', event => { - event.stopPropagation(); - colorHandler(hexColorString); - }); - -}; - -function embedCSS() { - const style = document.createElement('style'); - style.setAttribute('type', 'text/css'); - style.setAttribute('title', 'igv-ui.css'); - style.innerHTML = `.igv-ui-popover { - cursor: default; - position: absolute; - z-index: 2048; - border-color: #7F7F7F; - border-radius: 4px; - border-style: solid; - border-width: 1px; - font-family: "Open Sans", sans-serif; - font-size: small; - background-color: white; -} -.igv-ui-popover > div:first-child { - display: flex; - flex-direction: row; - flex-wrap: nowrap; - justify-content: space-between; - align-items: center; - width: 100%; - height: 24px; - cursor: move; - border-top-left-radius: 4px; - border-top-right-radius: 4px; - border-bottom-color: #7F7F7F; - border-bottom-style: solid; - border-bottom-width: thin; - background-color: #eee; -} -.igv-ui-popover > div:first-child > div:first-child { - margin-left: 4px; -} -.igv-ui-popover > div:first-child > div:last-child { - margin-right: 4px; - height: 12px; - width: 12px; - color: #7F7F7F; -} -.igv-ui-popover > div:first-child > div:last-child:hover { - cursor: pointer; - color: #444; -} -.igv-ui-popover > div:last-child { - overflow-y: auto; - overflow-x: hidden; - max-height: 400px; - max-width: 800px; - background-color: white; -} -.igv-ui-popover > div:last-child > div { - -webkit-user-select: text; - -moz-user-select: text; - -ms-user-select: text; - user-select: text; - margin-left: 4px; - margin-right: 4px; - min-width: 220px; - overflow-x: hidden; - text-overflow: ellipsis; - white-space: nowrap; -} -.igv-ui-popover > div:last-child > div > span { - font-weight: bolder; -} -.igv-ui-popover > div:last-child hr { - width: 100%; -} - -.igv-ui-alert-dialog-container { - box-sizing: content-box; - position: absolute; - z-index: 2048; - top: 50%; - left: 50%; - width: 400px; - height: 200px; - border-color: #7F7F7F; - border-radius: 4px; - border-style: solid; - border-width: thin; - outline: none; - font-family: "Open Sans", sans-serif; - font-size: 15px; - font-weight: 400; - background-color: white; - display: flex; - flex-flow: column; - flex-wrap: nowrap; - justify-content: space-between; - align-items: center; -} -.igv-ui-alert-dialog-container > div:first-child { - display: flex; - flex-flow: row; - flex-wrap: nowrap; - justify-content: flex-start; - align-items: center; - width: 100%; - height: 24px; - cursor: move; - border-top-left-radius: 4px; - border-top-right-radius: 4px; - border-bottom-color: #7F7F7F; - border-bottom-style: solid; - border-bottom-width: thin; - background-color: #eee; -} -.igv-ui-alert-dialog-container > div:first-child div:first-child { - padding-left: 8px; -} -.igv-ui-alert-dialog-container .igv-ui-alert-dialog-body { - -webkit-user-select: text; - -moz-user-select: text; - -ms-user-select: text; - user-select: text; - color: #373737; - width: 100%; - height: calc(100% - 24px - 64px); - overflow-y: scroll; -} -.igv-ui-alert-dialog-container .igv-ui-alert-dialog-body .igv-ui-alert-dialog-body-copy { - margin: 16px; - width: auto; - height: auto; - overflow-wrap: break-word; - word-break: break-word; - background-color: white; - border: unset; -} -.igv-ui-alert-dialog-container > div:last-child { - width: 100%; - margin-bottom: 10px; - background-color: white; - display: flex; - flex-flow: row; - flex-wrap: nowrap; - justify-content: center; - align-items: center; -} -.igv-ui-alert-dialog-container > div:last-child div { - margin: unset; - width: 40px; - height: 30px; - line-height: 30px; - text-align: center; - color: white; - font-family: "Open Sans", sans-serif; - font-size: small; - font-weight: 400; - border-color: #2B81AF; - border-style: solid; - border-width: thin; - border-radius: 4px; - background-color: #2B81AF; -} -.igv-ui-alert-dialog-container > div:last-child div:hover { - cursor: pointer; - border-color: #25597f; - background-color: #25597f; -} - -.igv-ui-color-swatch { - position: relative; - box-sizing: content-box; - display: flex; - flex-flow: row; - flex-wrap: wrap; - justify-content: center; - align-items: center; - width: 32px; - height: 32px; - border-style: solid; - border-width: 2px; - border-color: white; - border-radius: 4px; -} - -.igv-ui-color-swatch:hover { - border-color: dimgray; -} - -.igv-ui-colorpicker-menu-close-button { - display: flex; - flex-flow: row; - flex-wrap: nowrap; - justify-content: flex-end; - align-items: center; - width: 100%; - height: 32px; - margin-top: 4px; - margin-bottom: 4px; - padding-right: 8px; -} -.igv-ui-colorpicker-menu-close-button i.fa { - display: block; - margin-left: 4px; - margin-right: 4px; - color: #5f5f5f; -} -.igv-ui-colorpicker-menu-close-button i.fa:hover, -.igv-ui-colorpicker-menu-close-button i.fa:focus, -.igv-ui-colorpicker-menu-close-button i.fa:active { - cursor: pointer; - color: #0f0f0f; -} - -.igv-ui-generic-dialog-container { - box-sizing: content-box; - position: fixed; - top: 0; - left: 0; - width: 300px; - height: 200px; - border-color: #7F7F7F; - border-radius: 4px; - border-style: solid; - border-width: thin; - font-family: "Open Sans", sans-serif; - font-size: medium; - font-weight: 400; - z-index: 2048; - background-color: white; - display: flex; - flex-flow: column; - flex-wrap: nowrap; - justify-content: flex-start; - align-items: center; -} -.igv-ui-generic-dialog-container .igv-ui-generic-dialog-header { - display: flex; - flex-flow: row; - flex-wrap: nowrap; - justify-content: flex-end; - align-items: center; - width: 100%; - height: 24px; - cursor: move; - border-top-left-radius: 4px; - border-top-right-radius: 4px; - border-bottom-color: #7F7F7F; - border-bottom-style: solid; - border-bottom-width: thin; - background-color: #eee; -} -.igv-ui-generic-dialog-container .igv-ui-generic-dialog-header div { - margin-right: 4px; - margin-bottom: 2px; - height: 12px; - width: 12px; - color: #7F7F7F; -} -.igv-ui-generic-dialog-container .igv-ui-generic-dialog-header div:hover { - cursor: pointer; - color: #444; -} -.igv-ui-generic-dialog-container .igv-ui-generic-dialog-one-liner { - color: #373737; - width: 95%; - height: 24px; - line-height: 24px; - text-align: left; - margin-top: 8px; - padding-left: 8px; - overflow-wrap: break-word; - background-color: white; -} -.igv-ui-generic-dialog-container .igv-ui-generic-dialog-label-input { - margin-top: 8px; - width: 95%; - height: 24px; - color: #373737; - line-height: 24px; - padding-left: 8px; - background-color: white; - display: flex; - flex-flow: row; - flex-wrap: nowrap; - justify-content: flex-start; - align-items: center; -} -.igv-ui-generic-dialog-container .igv-ui-generic-dialog-label-input div { - width: 30%; - height: 100%; - font-size: 16px; - text-align: right; - padding-right: 8px; - background-color: white; -} -.igv-ui-generic-dialog-container .igv-ui-generic-dialog-label-input input { - display: block; - height: 100%; - width: 100%; - padding-left: 4px; - font-family: "Open Sans", sans-serif; - font-weight: 400; - color: #373737; - text-align: left; - outline: none; - border-style: solid; - border-width: thin; - border-color: #7F7F7F; - background-color: white; -} -.igv-ui-generic-dialog-container .igv-ui-generic-dialog-label-input input { - width: 50%; - font-size: 16px; -} -.igv-ui-generic-dialog-container .igv-ui-generic-dialog-input { - margin-top: 8px; - width: calc(100% - 16px); - height: 24px; - color: #373737; - line-height: 24px; - display: flex; - flex-flow: row; - flex-wrap: nowrap; - justify-content: space-around; - align-items: center; -} -.igv-ui-generic-dialog-container .igv-ui-generic-dialog-input input { - display: block; - height: 100%; - width: 100%; - padding-left: 4px; - font-family: "Open Sans", sans-serif; - font-weight: 400; - color: #373737; - text-align: left; - outline: none; - border-style: solid; - border-width: thin; - border-color: #7F7F7F; - background-color: white; -} -.igv-ui-generic-dialog-container .igv-ui-generic-dialog-input input { - font-size: 16px; -} -.igv-ui-generic-dialog-container .igv-ui-generic-dialog-ok-cancel { - width: 100%; - height: 28px; - display: flex; - flex-flow: row; - flex-wrap: nowrap; - justify-content: space-around; - align-items: center; -} -.igv-ui-generic-dialog-container .igv-ui-generic-dialog-ok-cancel div { - margin-top: 32px; - color: white; - font-family: "Open Sans", sans-serif; - font-size: 14px; - font-weight: 400; - width: 75px; - height: 28px; - line-height: 28px; - text-align: center; - border-color: transparent; - border-style: solid; - border-width: thin; - border-radius: 2px; -} -.igv-ui-generic-dialog-container .igv-ui-generic-dialog-ok-cancel div:first-child { - margin-left: 32px; - margin-right: 0; - background-color: #5ea4e0; -} -.igv-ui-generic-dialog-container .igv-ui-generic-dialog-ok-cancel div:last-child { - margin-left: 0; - margin-right: 32px; - background-color: #c4c4c4; -} -.igv-ui-generic-dialog-container .igv-ui-generic-dialog-ok-cancel div:first-child:hover { - cursor: pointer; - background-color: #3b5c7f; -} -.igv-ui-generic-dialog-container .igv-ui-generic-dialog-ok-cancel div:last-child:hover { - cursor: pointer; - background-color: #7f7f7f; -} -.igv-ui-generic-dialog-container .igv-ui-generic-dialog-ok { - width: 100%; - height: 36px; - margin-top: 32px; - display: flex; - flex-flow: row; - flex-wrap: nowrap; - justify-content: space-around; - align-items: center; -} -.igv-ui-generic-dialog-container .igv-ui-generic-dialog-ok div { - width: 98px; - height: 36px; - line-height: 36px; - text-align: center; - color: white; - font-family: "Open Sans", sans-serif; - font-size: medium; - font-weight: 400; - border-color: white; - border-style: solid; - border-width: thin; - border-radius: 4px; - background-color: #2B81AF; -} -.igv-ui-generic-dialog-container .igv-ui-generic-dialog-ok div:hover { - cursor: pointer; - background-color: #25597f; -} - -.igv-ui-generic-container { - box-sizing: content-box; - position: absolute; - z-index: 2048; - background-color: white; - cursor: pointer; - display: flex; - flex-direction: row; - flex-wrap: wrap; - justify-content: flex-start; - align-items: center; -} -.igv-ui-generic-container > div:first-child { - cursor: move; - display: flex; - flex-flow: row; - flex-wrap: nowrap; - justify-content: flex-end; - align-items: center; - height: 24px; - width: 100%; - background-color: #dddddd; -} -.igv-ui-generic-container > div:first-child > div { - display: block; - color: #5f5f5f; - cursor: pointer; - width: 14px; - height: 14px; - margin-right: 8px; - margin-bottom: 4px; -} - -.igv-ui-dialog { - z-index: 2048; - position: fixed; - width: fit-content; - height: fit-content; - display: flex; - flex-flow: column; - flex-wrap: nowrap; - justify-content: flex-start; - background-color: white; - border-color: #7F7F7F; - border-radius: 4px; - border-style: solid; - border-width: thin; - font-family: "Open Sans", sans-serif; - font-size: medium; - font-weight: 400; -} -.igv-ui-dialog .igv-ui-dialog-header { - display: flex; - flex-flow: row; - flex-wrap: nowrap; - justify-content: flex-end; - align-items: center; - width: 100%; - height: 24px; - cursor: move; - border-top-left-radius: 4px; - border-top-right-radius: 4px; - border-bottom-color: #7F7F7F; - border-bottom-style: solid; - border-bottom-width: thin; - background-color: #eee; -} -.igv-ui-dialog .igv-ui-dialog-header div { - margin-right: 4px; - margin-bottom: 2px; - height: 12px; - width: 12px; - color: #7F7F7F; -} -.igv-ui-dialog .igv-ui-dialog-header div:hover { - cursor: pointer; - color: #444; -} -.igv-ui-dialog .igv-ui-dialog-one-liner { - width: 95%; - height: 24px; - line-height: 24px; - text-align: left; - margin: 8px; - overflow-wrap: break-word; - background-color: white; - font-weight: bold; -} -.igv-ui-dialog .igv-ui-dialog-ok-cancel { - width: 100%; - display: flex; - flex-flow: row; - flex-wrap: nowrap; - justify-content: space-around; - align-items: center; -} -.igv-ui-dialog .igv-ui-dialog-ok-cancel div { - margin: 16px; - margin-top: 32px; - color: white; - font-family: "Open Sans", sans-serif; - font-size: 14px; - font-weight: 400; - width: 75px; - height: 28px; - line-height: 28px; - text-align: center; - border-color: transparent; - border-style: solid; - border-width: thin; - border-radius: 2px; -} -.igv-ui-dialog .igv-ui-dialog-ok-cancel div:first-child { - background-color: #5ea4e0; -} -.igv-ui-dialog .igv-ui-dialog-ok-cancel div:last-child { - background-color: #c4c4c4; -} -.igv-ui-dialog .igv-ui-dialog-ok-cancel div:first-child:hover { - cursor: pointer; - background-color: #3b5c7f; -} -.igv-ui-dialog .igv-ui-dialog-ok-cancel div:last-child:hover { - cursor: pointer; - background-color: #7f7f7f; -} -.igv-ui-dialog .igv-ui-dialog-ok { - width: 100%; - height: 36px; - margin-top: 32px; - display: flex; - flex-flow: row; - flex-wrap: nowrap; - justify-content: space-around; - align-items: center; -} -.igv-ui-dialog .igv-ui-dialog-ok div { - width: 98px; - height: 36px; - line-height: 36px; - text-align: center; - color: white; - font-family: "Open Sans", sans-serif; - font-size: medium; - font-weight: 400; - border-color: white; - border-style: solid; - border-width: thin; - border-radius: 4px; - background-color: #2B81AF; -} -.igv-ui-dialog .igv-ui-dialog-ok div:hover { - cursor: pointer; - background-color: #25597f; -} - -.igv-ui-panel, .igv-ui-panel-row, .igv-ui-panel-column { - z-index: 2048; - background-color: white; - font-family: "Open Sans", sans-serif; - font-size: medium; - font-weight: 400; - display: flex; - justify-content: flex-start; - align-items: flex-start; -} - -.igv-ui-panel-column { - display: flex; - flex-direction: column; -} - -.igv-ui-panel-row { - display: flex; - flex-direction: row; -} - -.igv-ui-textbox { - background-color: white; - font-family: "Open Sans", sans-serif; - font-size: medium; - font-weight: 400; - display: flex; - justify-content: flex-start; - align-items: flex-start; -} - -.igv-ui-table { - background-color: white; -} - -.igv-ui-table thead { - position: sticky; - top: 0; -} - -.igv-ui-table th { - text-align: left; -} - -.igv-ui-table td { - padding-right: 20px; -} - -.igv-ui-table tr:hover { - background-color: lightblue; -} - -/*# sourceMappingURL=igv-ui.css.map */ -`; - document.head.append(style); -} - -if (typeof document !== 'undefined') { - - if (!stylesheetExists("igv-ui.css")) { - embedCSS(); - } - - function stylesheetExists(stylesheetName) { - for (let ss of document.styleSheets) { - ss = ss.href ? ss.href.replace(/^.*[\\\/]/, '') : ''; - if (ss === stylesheetName) { - return true - } - } - return false - } -} - -/* - * The MIT License (MIT) - * - * Copyright (c) 2016-2017 The Regents of the University of California - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and - * associated documentation files (the "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the - * following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING - * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - */ - -function isMobile() { - return (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)); -} - -function throttle(fn, threshhold, scope) { - var last, - deferTimer; - - threshhold || (threshhold = 200); - - return function () { - var context, - now, - args; - - context = scope || this; - now = +new Date; - args = arguments; - - if (last && now < last + threshhold) { - // hold on to it - clearTimeout(deferTimer); - deferTimer = setTimeout(function () { - last = now; - fn.apply(context, args); - }, threshhold); - } else { - last = now; - fn.apply(context, args); - } - } -} - -function getExtension(url) { - - if (undefined === url) { - return undefined - } - - let path = (isFile$2(url) || url.google_url) ? url.name : url; - let filename = path.toLowerCase(); - - //Strip parameters -- handle local files later - let index = filename.indexOf("?"); - if (index > 0) { - filename = filename.substr(0, index); - } - - //Strip aux extensions .gz, .tab, and .txt - if (filename.endsWith(".gz")) { - filename = filename.substr(0, filename.length - 3); - } else if (filename.endsWith(".txt") || filename.endsWith(".tab") || filename.endsWith(".bgz")) { - filename = filename.substr(0, filename.length - 4); - } - - index = filename.lastIndexOf("."); - - return index < 0 ? filename : filename.substr(1 + index) -} - -const Globals = {}; - -/* - * The MIT License (MIT) - * - * Copyright (c) 2016-2017 The Regents of the University of California - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and - * associated documentation files (the "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the - * following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING - * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - */ - - -/** - * @author Jim Robinson - */ - - -/** - * Barebones event bus. - */ - -class EventBus { - - constructor() { - - // Map eventType -> list of subscribers - this.subscribers = {}; - - this.stack = []; - } - - subscribe(eventType, object) { - - var subscriberList = this.subscribers[eventType]; - if (subscriberList == undefined) { - subscriberList = []; - this.subscribers[eventType] = subscriberList; - } - subscriberList.push(object); - - } - - post(event) { - - const eventType = event.type; - - if (this._hold) { - this.stack.push(event); - } else { - const subscriberList = this.subscribers[eventType]; - - if (subscriberList) { - for (let subscriber of subscriberList) { - - if ("function" === typeof subscriber.receiveEvent) { - subscriber.receiveEvent(event); - } else if ("function" === typeof subscriber) { - subscriber(event); - } - } - } - } - } - - hold() { - this._hold = true; - } - - release() { - this._hold = false; - for (let event of this.stack) { - this.post(event); - } - this.stack = []; - } -} - -// The global event bus - -EventBus.globalBus = new EventBus(); - -class Track2D { - - static DisplayModes = { - lower: 0b01, - upper: 0b10, - both: 0b01 | 0b10, - } - - constructor(config, features) { - - this.config = config; - this.name = config.name; - - if (config.color && validateColor(config.color)) { - this.color = this.color = config.color; // If specified, this will override colors of individual records. - } - - this.displayMode = config.displayMode; // Can be undefined => both - - this.isVisible = undefined === config.isVisible ? true : config.isVisible; - - this.repColor = features.length > 0 ? features[0].color : "black"; - - this.featureMap = {}; - this.featureCount = 0; - for (let f of features) { - this.featureCount++; - const key = getKey(f.chr1, f.chr2); - let list = this.featureMap[key]; - if (!list) { - list = []; - this.featureMap[key] = list; - } - list.push(f); - } - } - - static async loadTrack2D(config, genome) { - - const data = await igvxhr$1.loadString(config.url, buildOptions(config)); - const features = parseData(data, isBedPE(config), genome); - return new Track2D(config, features) - } - - getColor() { - return this.color || this.repColor - } - - getFeatures(chr1, chr2) { - const key = getKey(chr1, chr2); - return this.featureMap[key] - } - - toJSON() { - const json = - { - url: this.config.url - }; - if (this.name) { - json.name = this.name; - } - if (this.color) { - json.color = this.color; - } - if (this.displayMode) { - json.displayMode = this.displayMode; - } - if (!this.isVisible) { - json.isVisible = this.isVisible; - } - - return json - - } - -} - - -function isBedPE(config) { - - if (typeof config.url === "string") { - return config.url.toLowerCase().indexOf(".bedpe") > 0 - } else if (typeof config.name === "string") { - return config.name.toLowerCase().indexOf(".bedpe") > 0 - } else { - return true // Default - } -} - -function parseData(data, isBedPE, genome) { - - if (!data) return null - - const lines = splitLines$6(data); - const allFeatures = []; - const delimiter = "\t"; - const colorColumn = isBedPE ? 10 : 6; - - let errorCount = 0; - for (let line of lines) { - line = line.trim(); - if (line.startsWith("#") || line.startsWith("track") || line.startsWith("browser") || line.length === 0) { - continue - } - const tokens = line.split(delimiter); - if (tokens.length < 6 && errorCount <= 5) { - if (errorCount === 5) { - console.error("..."); - } else { - console.error("Could not parse line: " + line); - } - errorCount++; - continue - } - - const feature = { - chr1: genome ? genome.getChromosomeName(tokens[0]) : tokens[0], - x1: parseInt(tokens[1]), - x2: parseInt(tokens[2]), - chr2: genome ? genome.getChromosomeName(tokens[3]) : tokens[3], - y1: parseInt(tokens[4]), - y2: parseInt(tokens[5]) - }; - - if (tokens.length > colorColumn) { - feature.color = "rgb(" + tokens[colorColumn] + ")"; - } - - if (!Number.isNaN(feature.x1)) { - allFeatures.push(feature); - } - } - - return allFeatures -} - -function getKey(chr1, chr2) { - return chr1 > chr2 ? chr2 + "_" + chr1 : chr1 + "_" + chr2 -} - -function validateColor(str) { - var div = document.createElement("div"); - div.style.borderColor = str; - return div.style.borderColor !== "" -} - -function buildOptions(config, options) { - const defaultOptions = { - oauthToken: config.oauthToken, - headers: config.headers, - withCredentials: config.withCredentials, - filename: config.filename - }; - - return Object.assign(defaultOptions, options) -} - -/* - * The MIT License (MIT) - * - * Copyright (c) 2016-2017 The Regents of the University of California - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and - * associated documentation files (the "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the - * following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING - * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - */ - -class Ruler { - - constructor(browser, parentElement, axis) { - this.browser = browser; - this.axis = axis; - - this.axisElement = parentElement.querySelector(`div[id$='-axis']`); - - this.canvasElement = parentElement.querySelector("canvas"); - - this.ctx = this.canvasElement.getContext("2d"); - this.ctx.canvas.width = this.axisElement.offsetWidth; - this.ctx.canvas.height = this.axisElement.offsetHeight; - - this.wholeGenomeContainerElement = parentElement.querySelector("div[id$='-axis-whole-genome-container']"); - - this.setAxisTransform(axis); - - browser.eventBus.subscribe('MapLoad', this); - browser.eventBus.subscribe("UpdateContactMapMousePosition", this); - } - - wholeGenomeLayout(axisElement, wholeGenomeContainerElement, axisName, dataset) { - - const decorate = (div) => { - div.addEventListener('click', () => { - this.browser.parseGotoInput(div.textContent); - this.unhighlightWholeChromosome(); - this.otherRuler.unhighlightWholeChromosome(); - }); - - div.addEventListener('mouseenter', () => { - hoverHandler.call(this, div, true); - }); - - div.addEventListener('mouseleave', () => { - hoverHandler.call(this, div, false); - }); - }; - - const hoverHandler = (element, doHover) => { - const targetLabel = element.dataset.label; - - Array.from(this.otherRuler.wholeGenomeContainerElement.children).forEach(child => { - if (child.dataset.label === targetLabel) { - if (doHover) { - element.classList.add('hic-whole-genome-chromosome-highlight'); - child.classList.add('hic-whole-genome-chromosome-highlight'); - } else { - element.classList.remove('hic-whole-genome-chromosome-highlight'); - child.classList.remove('hic-whole-genome-chromosome-highlight'); - } - } - }); - }; - let list, dimen, extent, scraps, firstDivElement; - - // discard current tiles - wholeGenomeContainerElement.innerHTML = ''; - - list = dataset.chromosomes.filter(chromosome => chromosome.name.toLowerCase() !== 'all'); - - extent = list.reduce((sum, chromosome) => sum + chromosome.size, 0); - - dimen = axisName === 'x' ? axisElement.offsetWidth : axisElement.offsetHeight; - - scraps = 0; - this.bboxes = []; - firstDivElement = undefined; - - for (const chr of list) { - const percentage = chr.bpLength / extent; - - if (percentage * dimen < 1.0) { - scraps += percentage; - } else { - const divElement = document.createElement('div'); - divElement.className = `${this.axis}-axis-whole-genome-chromosome-container`; - divElement.dataset.label = chr.name; - wholeGenomeContainerElement.appendChild(divElement); - - if (!firstDivElement) { - firstDivElement = divElement; - } - - const size = Math.round(percentage * dimen); - if (axisName === 'x') { - divElement.style.width = `${size}px`; - } else { - divElement.style.height = `${size}px`; - } - - // Border - const borderElement = document.createElement('div'); - divElement.appendChild(borderElement); - - // Label - const labelElement = document.createElement('div'); - borderElement.appendChild(labelElement); - - labelElement.textContent = divElement.dataset.label; - labelElement.title = divElement.dataset.label; - - decorate(divElement); - } - } - - scraps = Math.floor(scraps * dimen); - if (scraps >= 1) { - - const divElement = document.createElement('div'); - wholeGenomeContainerElement.appendChild(divElement); - - divElement.className = `${this.axis}-axis-whole-genome-chromosome-container`; - divElement.dataset.label = '-'; - divElement.style.width = `${scraps}px`; - - decorate(divElement); - } - - for (const child of wholeGenomeContainerElement.children) { - this.bboxes.push(bbox(axisName, child, firstDivElement)); - } - - this.hideWholeGenome(); - - } - - hideWholeGenome() { - this.wholeGenomeContainerElement.style.display = 'none'; - this.canvasElement.style.display = 'block'; - } - - showWholeGenome() { - this.canvasElement.style.display = 'none'; - this.wholeGenomeContainerElement.style.display = 'flex'; - } - - setAxisTransform(axis) { - - this.canvasTransform = ('y' === axis) ? canvasTransformWithContext : identityTransformWithContext; - this.labelTransform = ('y' === axis) ? labelTransformWithContext : noopTransformWithContext; - - } - - unhighlightWholeChromosome() { - for (const child of this.wholeGenomeContainerElement.children) { - child.classList.remove('hic-whole-genome-chromosome-highlight'); - } - } - - receiveEvent(event) { - let offset, element; - - if (event.type === 'MapLoad') { - this.wholeGenomeLayout(this.axisElement, this.wholeGenomeContainerElement, this.axis, event.data); - this.update(); - } else if (event.type === 'UpdateContactMapMousePosition') { - if (this.bboxes) { - this.unhighlightWholeChromosome(); - offset = this.axis === 'x' ? event.data.x : event.data.y; - element = hitTest(this.bboxes, offset); - if (element) { - element.classList.add('hic-whole-genome-chromosome-highlight'); - } - } - } - } - - locusChange(event) { - - this.update(); - - } - - updateWidthWithCalculation(calc) { - this.axisElement.style.width = calc; - - const axisWidth = this.axisElement.offsetWidth; - this.canvasElement.width = axisWidth; - this.canvasElement.setAttribute('width', axisWidth); - - this.wholeGenomeLayout(this.axisElement, this.wholeGenomeContainerElement, this.axis, this.browser.dataset); - this.update(); - } - - updateHeight(height) { - this.canvasElement.height = height; - this.canvasElement.setAttribute('height', height); - - this.wholeGenomeLayout(this.axisElement, this.wholeGenomeContainerElement, this.axis, this.browser.dataset); - this.update(); - } - - update() { - const browser = this.browser; - const config = {}; - - if (browser.dataset.isWholeGenome(browser.state.chr1)) { - this.showWholeGenome(); - return; - } - - this.hideWholeGenome(); - - identityTransformWithContext(this.ctx); - index$1.IGVGraphics.fillRect( - this.ctx, - 0, - 0, - this.canvasElement.width, - this.canvasElement.height, - { fillStyle: IGVColor$1.rgbColor(255, 255, 255) } - ); - - this.canvasTransform(this.ctx); - - const width = this.axis === 'x' ? this.canvasElement.width : this.canvasElement.height; - const height = this.axis === 'x' ? this.canvasElement.height : this.canvasElement.width; - - index$1.IGVGraphics.fillRect( - this.ctx, - 0, - 0, - width, - height, - { fillStyle: IGVColor$1.rgbColor(255, 255, 255) } - ); - - config.bpPerPixel = browser.dataset.bpResolutions[browser.state.zoom] / browser.state.pixelSize; - const bin = this.axis === 'x' ? browser.state.x : browser.state.y; - config.bpStart = bin * browser.dataset.bpResolutions[browser.state.zoom]; - - config.rulerTickMarkReferencePixels = Math.max( - this.canvasElement.width, - this.canvasElement.height, - this.otherRulerCanvas.width, - this.otherRulerCanvas.height - ); - - config.rulerLengthPixels = width; - config.rulerHeightPixels = height; - - config.height = Math.min(this.canvasElement.width, this.canvasElement.height); - - this.draw(config); - } - - draw(options) { - const { - rulerLengthPixels, - rulerHeightPixels, - rulerTickMarkReferencePixels, - bpPerPixel, - bpStart, - chrName - } = options; - - const { chromosomes } = this.browser.dataset; - const { state } = this.browser; - const axisIsX = this.axis === 'x'; - const chr = axisIsX ? chromosomes[state.chr1] : chromosomes[state.chr2]; - const { name: chrNameSelected, size: chrSize } = chr; - - if (chrName !== "all") { - // Clear the ruler area - index$1.IGVGraphics.fillRect(this.ctx, 0, 0, rulerLengthPixels, rulerHeightPixels, { - fillStyle: IGVColor$1.rgbColor(255, 255, 255) - }); - - const fontStyle = { - textAlign: 'center', - font: '9px PT Sans', - fillStyle: "rgba(64, 64, 64, 1)", - strokeStyle: "rgba(64, 64, 64, 1)" - }; - - const tickSpec = findSpacing(Math.floor(rulerTickMarkReferencePixels * bpPerPixel)); - const majorTickSpacing = tickSpec.majorTick; - - let nTick = Math.floor(bpStart / majorTickSpacing) - 1; - let pixel = 0; - let pixelLast = 0; - - index$1.IGVGraphics.setProperties(this.ctx, fontStyle); - this.ctx.lineWidth = 1.0; - - const yShim = 1; - const tickHeight = 8; - - while (pixel < rulerLengthPixels) { - const l = Math.floor(nTick * majorTickSpacing); - pixel = Math.round(((l - 1) - bpStart + 0.5) / bpPerPixel); - - const rulerLabel = `${formatNumber(l / tickSpec.unitMultiplier, 0)} ${tickSpec.majorUnit}`; - const tickSpacingPixels = Math.abs(pixel - pixelLast); - const labelWidthPixels = this.ctx.measureText(rulerLabel).width; - - const modulo = labelWidthPixels > tickSpacingPixels - ? (tickSpacingPixels < 32 ? 4 : 2) - : 1; - - if (nTick % modulo === 0) { - if (Math.floor((pixel * bpPerPixel) + bpStart) < chrSize) { - this.ctx.save(); - this.labelTransform(this.ctx, pixel); - index$1.IGVGraphics.fillText(this.ctx, rulerLabel, pixel, options.height - (tickHeight / 0.75)); - this.ctx.restore(); - } - } - - if (Math.floor((pixel * bpPerPixel) + bpStart) < chrSize) { - index$1.IGVGraphics.strokeLine( - this.ctx, - pixel, options.height - tickHeight, - pixel, options.height - yShim - ); - } - - pixelLast = pixel; - nTick++; - } - - // Draw the baseline - index$1.IGVGraphics.strokeLine(this.ctx, 0, options.height - yShim, rulerLengthPixels, options.height - yShim); - } - } -} - -const formatNumber = (num, decimal = 0) => { - // Ensure decimal is between 0 and 3 - const precision = Math.min(Math.max(decimal, 0), 3); - - // Round the number to the desired decimal places - const roundedNum = Math.abs(num).toFixed(precision); - - // Split the integer and decimal parts - let [integerPart, decimalPart] = roundedNum.split("."); - - // Add commas to the integer part - integerPart = parseInt(integerPart, 10).toLocaleString(); - - // Pad the decimal part with zeros if necessary - if (precision > 0) { - decimalPart = decimalPart.padEnd(precision, "0"); - } - - // Combine integer and decimal parts - let formattedNum = precision > 0 ? `${integerPart}.${decimalPart}` : integerPart; - - // Wrap in parentheses if the original number was negative - if (num < 0) { - formattedNum = `(${formattedNum})`; - } - - // Optionally, prepend a dollar sign - // formattedNum = `$${formattedNum}`; - - return formattedNum; -}; - -function bbox(axis, childElement, firstChildElement) { - const offset = axis === 'x' - ? childElement.getBoundingClientRect().left - : childElement.getBoundingClientRect().top; - - const firstOffset = axis === 'x' - ? firstChildElement.getBoundingClientRect().left - : firstChildElement.getBoundingClientRect().top; - - const delta = offset - firstOffset; - const size = axis === 'x' - ? childElement.offsetWidth - : childElement.offsetHeight; - - return { element: childElement, a: delta, b: delta + size }; -} - -function hitTest(bboxes, value) { - - let hitElement = undefined; - - for (const bbox of bboxes) { - if (value >= bbox.a && value <= bbox.b) { - hitElement = bbox.element; - break; - } - } - - return hitElement; -} - -function TickSpacing(majorTick, majorUnit, unitMultiplier) { - this.majorTick = majorTick; - this.majorUnit = majorUnit; - this.unitMultiplier = unitMultiplier; -} - -function findSpacing(rulerLengthBP) { - - if (rulerLengthBP < 10) { - return new TickSpacing(1, "", 1); - } - - - // How many zeroes? - var nZeroes = Math.floor(log10(rulerLengthBP)); - var majorUnit = ""; - var unitMultiplier = 1; - if (nZeroes > 9) { - majorUnit = "gb"; - unitMultiplier = 1000000000; - } - if (nZeroes > 6) { - majorUnit = "mb"; - unitMultiplier = 1000000; - } else if (nZeroes > 3) { - majorUnit = "kb"; - unitMultiplier = 1000; - } - - var nMajorTicks = rulerLengthBP / Math.pow(10, nZeroes - 1); - if (nMajorTicks < 25) { - return new TickSpacing(Math.pow(10, nZeroes - 1), majorUnit, unitMultiplier); - } else { - return new TickSpacing(Math.pow(10, nZeroes) / 2, majorUnit, unitMultiplier); - } - - function log10(x) { - var dn = Math.log(10); - return Math.log(x) / dn; - } -} - -function canvasTransformWithContext(ctx) { - ctx.setTransform(0, 1, 1, 0, 0, 0); -} - -function labelTransformWithContext(context, exe) { - context.translate(exe, 0); - context.scale(-1, 1); - context.translate(-exe, 0); -} - -function identityTransformWithContext(context) { - // 3x2 matrix. column major. (sx 0 0 sy tx ty). - context.setTransform(1, 0, 0, 1, 0, 0); -} - -function noopTransformWithContext(ctx) { - -} - -/* - * The MIT License (MIT) - * - * Copyright (c) 2016-2017 The Regents of the University of California - * Author: Jim Robinson - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * - * This class uses icons from Font Awesome - * Font Awesome Free 5.0.8 by @fontawesome - https://fontawesome.com - * License - https://fontawesome.com/license (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) - */ - -const createCheckbox = (name, initialState) => { - // Create the container div - const container = document.createElement('div'); - container.className = 'jb-igv-menu-popup-check-container'; - - // Create the inner div - const div = document.createElement('div'); - container.appendChild(div); - - // Create the check icon using the existing iconMarkup function - const svg = iconMarkup('check', initialState === true ? '#444' : 'transparent'); - div.appendChild(svg); - - // Create the label div - const label = document.createElement('div'); - label.textContent = name; - // Optional: Add a class to the label if needed - // label.className = 'igv-some-label-class'; - - container.appendChild(label); - - return container; -}; - -function createIcon(name, color) { - return iconMarkup(name, color); -} - -const iconMarkup = (name, color = "currentColor") => { - const icon = icons[name] ?? icons["question"]; - - if (!icons[name]) { - console.error(`No icon named: ${name}`); - } - - const [width, height, , , pathData] = icon; - - // Create the SVG element with the correct namespace - const svgNS = "http://www.w3.org/2000/svg"; - const svg = document.createElementNS(svgNS, "svg"); - - // Set SVG attributes - svg.setAttribute("viewBox", `0 0 ${width} ${height}`); - svg.setAttribute("xmlns", svgNS); - svg.setAttribute("aria-label", `${name} icon`); - svg.setAttribute("role", "img"); - - // Create the path element - const path = document.createElementNS(svgNS, "path"); - path.setAttribute("fill", color); - path.setAttribute("d", pathData); - - // Append the path to the SVG - svg.appendChild(path); - - return svg; -}; - -const icons = { - "check": [512, 512, [], "f00c", "M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z"], - "cog": [512, 512, [], "f013", "M444.788 291.1l42.616 24.599c4.867 2.809 7.126 8.618 5.459 13.985-11.07 35.642-29.97 67.842-54.689 94.586a12.016 12.016 0 0 1-14.832 2.254l-42.584-24.595a191.577 191.577 0 0 1-60.759 35.13v49.182a12.01 12.01 0 0 1-9.377 11.718c-34.956 7.85-72.499 8.256-109.219.007-5.49-1.233-9.403-6.096-9.403-11.723v-49.184a191.555 191.555 0 0 1-60.759-35.13l-42.584 24.595a12.016 12.016 0 0 1-14.832-2.254c-24.718-26.744-43.619-58.944-54.689-94.586-1.667-5.366.592-11.175 5.459-13.985L67.212 291.1a193.48 193.48 0 0 1 0-70.199l-42.616-24.599c-4.867-2.809-7.126-8.618-5.459-13.985 11.07-35.642 29.97-67.842 54.689-94.586a12.016 12.016 0 0 1 14.832-2.254l42.584 24.595a191.577 191.577 0 0 1 60.759-35.13V25.759a12.01 12.01 0 0 1 9.377-11.718c34.956-7.85 72.499-8.256 109.219-.007 5.49 1.233 9.403 6.096 9.403 11.723v49.184a191.555 191.555 0 0 1 60.759 35.13l42.584-24.595a12.016 12.016 0 0 1 14.832 2.254c24.718 26.744 43.619 58.944 54.689 94.586 1.667 5.366-.592 11.175-5.459 13.985L444.788 220.9a193.485 193.485 0 0 1 0 70.2zM336 256c0-44.112-35.888-80-80-80s-80 35.888-80 80 35.888 80 80 80 80-35.888 80-80z"], - "exclamation": [192, 512, [], "f12a", "M176 432c0 44.112-35.888 80-80 80s-80-35.888-80-80 35.888-80 80-80 80 35.888 80 80zM25.26 25.199l13.6 272C39.499 309.972 50.041 320 62.83 320h66.34c12.789 0 23.331-10.028 23.97-22.801l13.6-272C167.425 11.49 156.496 0 142.77 0H49.23C35.504 0 24.575 11.49 25.26 25.199z"], - "exclamation-circle": [512, 512, [], "f06a", "M504 256c0 136.997-111.043 248-248 248S8 392.997 8 256C8 119.083 119.043 8 256 8s248 111.083 248 248zm-248 50c-25.405 0-46 20.595-46 46s20.595 46 46 46 46-20.595 46-46-20.595-46-46-46zm-43.673-165.346l7.418 136c.347 6.364 5.609 11.346 11.982 11.346h48.546c6.373 0 11.635-4.982 11.982-11.346l7.418-136c.375-6.874-5.098-12.654-11.982-12.654h-63.383c-6.884 0-12.356 5.78-11.981 12.654z"], - "exclamation-triangle": [576, 512, [], "f071", "M569.517 440.013C587.975 472.007 564.806 512 527.94 512H48.054c-36.937 0-59.999-40.055-41.577-71.987L246.423 23.985c18.467-32.009 64.72-31.951 83.154 0l239.94 416.028zM288 354c-25.405 0-46 20.595-46 46s20.595 46 46 46 46-20.595 46-46-20.595-46-46-46zm-43.673-165.346l7.418 136c.347 6.364 5.609 11.346 11.982 11.346h48.546c6.373 0 11.635-4.982 11.982-11.346l7.418-136c.375-6.874-5.098-12.654-11.982-12.654h-63.383c-6.884 0-12.356 5.78-11.981 12.654z"], - "minus": [448, 512, [], "f068", "M424 318.2c13.3 0 24-10.7 24-24v-76.4c0-13.3-10.7-24-24-24H24c-13.3 0-24 10.7-24 24v76.4c0 13.3 10.7 24 24 24h400z"], - "minus-circle": [512, 512, [], "f056", "M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zM124 296c-6.6 0-12-5.4-12-12v-56c0-6.6 5.4-12 12-12h264c6.6 0 12 5.4 12 12v56c0 6.6-5.4 12-12 12H124z"], - "minus-square": [448, 512, [], "f146", "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM92 296c-6.6 0-12-5.4-12-12v-56c0-6.6 5.4-12 12-12h264c6.6 0 12 5.4 12 12v56c0 6.6-5.4 12-12 12H92z"], - "plus": [448, 512, [], "f067", "M448 294.2v-76.4c0-13.3-10.7-24-24-24H286.2V56c0-13.3-10.7-24-24-24h-76.4c-13.3 0-24 10.7-24 24v137.8H24c-13.3 0-24 10.7-24 24v76.4c0 13.3 10.7 24 24 24h137.8V456c0 13.3 10.7 24 24 24h76.4c13.3 0 24-10.7 24-24V318.2H424c13.3 0 24-10.7 24-24z"], - "plus-circle": [512, 512, [], "f055", "M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm144 276c0 6.6-5.4 12-12 12h-92v92c0 6.6-5.4 12-12 12h-56c-6.6 0-12-5.4-12-12v-92h-92c-6.6 0-12-5.4-12-12v-56c0-6.6 5.4-12 12-12h92v-92c0-6.6 5.4-12 12-12h56c6.6 0 12 5.4 12 12v92h92c6.6 0 12 5.4 12 12v56z"], - "plus-square": [448, 512, [], "f0fe", "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-32 252c0 6.6-5.4 12-12 12h-92v92c0 6.6-5.4 12-12 12h-56c-6.6 0-12-5.4-12-12v-92H92c-6.6 0-12-5.4-12-12v-56c0-6.6 5.4-12 12-12h92v-92c0-6.6 5.4-12 12-12h56c6.6 0 12 5.4 12 12v92h92c6.6 0 12 5.4 12 12v56z"], - "question": [384, 512, [], "f128", "M202.021 0C122.202 0 70.503 32.703 29.914 91.026c-7.363 10.58-5.093 25.086 5.178 32.874l43.138 32.709c10.373 7.865 25.132 6.026 33.253-4.148 25.049-31.381 43.63-49.449 82.757-49.449 30.764 0 68.816 19.799 68.816 49.631 0 22.552-18.617 34.134-48.993 51.164-35.423 19.86-82.299 44.576-82.299 106.405V320c0 13.255 10.745 24 24 24h72.471c13.255 0 24-10.745 24-24v-5.773c0-42.86 125.268-44.645 125.268-160.627C377.504 66.256 286.902 0 202.021 0zM192 373.459c-38.196 0-69.271 31.075-69.271 69.271 0 38.195 31.075 69.27 69.271 69.27s69.271-31.075 69.271-69.271-31.075-69.27-69.271-69.27z"], - "save": [448, 512, [], "f0c7", "M433.941 129.941l-83.882-83.882A48 48 0 0 0 316.118 32H48C21.49 32 0 53.49 0 80v352c0 26.51 21.49 48 48 48h352c26.51 0 48-21.49 48-48V163.882a48 48 0 0 0-14.059-33.941zM224 416c-35.346 0-64-28.654-64-64 0-35.346 28.654-64 64-64s64 28.654 64 64c0 35.346-28.654 64-64 64zm96-304.52V212c0 6.627-5.373 12-12 12H76c-6.627 0-12-5.373-12-12V108c0-6.627 5.373-12 12-12h228.52c3.183 0 6.235 1.264 8.485 3.515l3.48 3.48A11.996 11.996 0 0 1 320 111.48z"], - "search": [512, 512, [], "f002", "M505 442.7L405.3 343c-4.5-4.5-10.6-7-17-7H372c27.6-35.3 44-79.7 44-128C416 93.1 322.9 0 208 0S0 93.1 0 208s93.1 208 208 208c48.3 0 92.7-16.4 128-44v16.3c0 6.4 2.5 12.5 7 17l99.7 99.7c9.4 9.4 24.6 9.4 33.9 0l28.3-28.3c9.4-9.4 9.4-24.6.1-34zM208 336c-70.7 0-128-57.2-128-128 0-70.7 57.2-128 128-128 70.7 0 128 57.2 128 128 0 70.7-57.2 128-128 128z"], - "share": [512, 512, [], "f064", "M503.691 189.836L327.687 37.851C312.281 24.546 288 35.347 288 56.015v80.053C127.371 137.907 0 170.1 0 322.326c0 61.441 39.581 122.309 83.333 154.132 13.653 9.931 33.111-2.533 28.077-18.631C66.066 312.814 132.917 274.316 288 272.085V360c0 20.7 24.3 31.453 39.687 18.164l176.004-152c11.071-9.562 11.086-26.753 0-36.328z"], - "spinner": [512, 512, [], "f110", "M304 48c0 26.51-21.49 48-48 48s-48-21.49-48-48 21.49-48 48-48 48 21.49 48 48zm-48 368c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48-21.49-48-48-48zm208-208c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48-21.49-48-48-48zM96 256c0-26.51-21.49-48-48-48S0 229.49 0 256s21.49 48 48 48 48-21.49 48-48zm12.922 99.078c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48c0-26.509-21.491-48-48-48zm294.156 0c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48c0-26.509-21.49-48-48-48zM108.922 60.922c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48-21.491-48-48-48z"], - "square": [448, 512, [], "f0c8", "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48z"], - "square-full": [512, 512, [], "f45c", "M512 512H0V0h512v512z"], - "times": [384, 512, [], "f00d", "M323.1 441l53.9-53.9c9.4-9.4 9.4-24.5 0-33.9L279.8 256l97.2-97.2c9.4-9.4 9.4-24.5 0-33.9L323.1 71c-9.4-9.4-24.5-9.4-33.9 0L192 168.2 94.8 71c-9.4-9.4-24.5-9.4-33.9 0L7 124.9c-9.4 9.4-9.4 24.5 0 33.9l97.2 97.2L7 353.2c-9.4 9.4-9.4 24.5 0 33.9L60.9 441c9.4 9.4 24.5 9.4 33.9 0l97.2-97.2 97.2 97.2c9.3 9.3 24.5 9.3 33.9 0z"], - "times-circle": [512, 512, [], "f057", "M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm121.6 313.1c4.7 4.7 4.7 12.3 0 17L338 377.6c-4.7 4.7-12.3 4.7-17 0L256 312l-65.1 65.6c-4.7 4.7-12.3 4.7-17 0L134.4 338c-4.7-4.7-4.7-12.3 0-17l65.6-65-65.6-65.1c-4.7-4.7-4.7-12.3 0-17l39.6-39.6c4.7-4.7 12.3-4.7 17 0l65 65.7 65.1-65.6c4.7-4.7 12.3-4.7 17 0l39.6 39.6c4.7 4.7 4.7 12.3 0 17L312 256l65.6 65.1z"], - "wrench": [512, 512, [], "f0ad", "M481.156 200c9.3 0 15.12 10.155 10.325 18.124C466.295 259.992 420.419 288 368 288c-79.222 0-143.501-63.974-143.997-143.079C223.505 65.469 288.548-.001 368.002 0c52.362.001 98.196 27.949 123.4 69.743C496.24 77.766 490.523 88 481.154 88H376l-40 56 40 56h105.156zm-171.649 93.003L109.255 493.255c-24.994 24.993-65.515 24.994-90.51 0-24.993-24.994-24.993-65.516 0-90.51L218.991 202.5c16.16 41.197 49.303 74.335 90.516 90.503zM104 432c0-13.255-10.745-24-24-24s-24 10.745-24 24 10.745 24 24 24 24-10.745 24-24z"], -}; - -/** - * Configure item list for track "gear" menu. - * @param trackRenderer - */ -const MenuUtils = { - - trackMenuItemList: trackPair => { - - const menuItems = []; - - menuItems.push(trackRenameMenuItem(trackPair)); - menuItems.push("
"); - - menuItems.push(colorPickerMenuItem({ trackPair, label: "Set color", option: "color" })); - menuItems.push(unsetColorMenuItem({ trackPair, label: "Unset color" })); - - if (trackPair.track.removable !== false) { - menuItems.push('
'); - menuItems.push(trackRemovalMenuItem(trackPair)); - } - - return menuItems - }, - - numericDataMenuItems: trackPair => { - const menuItems = []; - - // Data range - const element = document.createElement('div'); - element.textContent = 'Set data range'; - - const click = () => { - const { min, max } = trackPair.track.dataRange; - trackPair.dataRangeDialog.show({ min: min || 0, max }); - }; - - menuItems.push({ element, click }); - - if (trackPair.track.logScale !== undefined) { - menuItems.push({ - element: createCheckbox("Log scale", trackPair.track.logScale), - click: () => { - trackPair.track.logScale = !trackPair.track.logScale; - trackPair.repaintViews(); - } - }); - } - - menuItems.push({ - element: createCheckbox("Autoscale", trackPair.track.autoscale), - click: () => { - trackPair.track.autoscale = !trackPair.track.autoscale; - trackPair.repaintViews(); - } - }); - - return menuItems; - }, - - nucleotideColorChartMenuItems: trackPair => { - const menuItems = []; - menuItems.push(document.createElement('hr')); - - const element = document.createElement('div'); - element.className = 'jb-igv-menu-popup-chart'; - element.innerHTML = ` -
A
-
C
-
T
-
G
- `; - - const click = e => { - e.preventDefault(); - e.stopPropagation(); - }; - - menuItems.push({ element, click }); - - return menuItems; - } - -}; - -function trackRemovalMenuItem(trackPair) { - const element = document.createElement('div'); - element.textContent = 'Remove track'; - - const click = () => trackPair.browser.layoutController.removeTrackXYPair(trackPair); - - return { element, click }; -} - -function colorPickerMenuItem({ trackPair, label, option }) { - const element = document.createElement('div'); - element.textContent = label; - - const click = () => trackPair.colorPicker.show(); - - return { element, click }; -} - -function unsetColorMenuItem({ trackPair, label }) { - const element = document.createElement('div'); - element.textContent = label; - - const click = () => { - trackPair.track.color = undefined; - trackPair.repaintViews(); - }; - - return { element, click }; -} - -function trackRenameMenuItem(trackPair) { - const element = document.createElement('div'); - element.textContent = 'Set track name'; - - const click = e => { - const callback = value => { - let name; - if (value === '' || value === undefined) { - name = ''; - } else { - name = value.trim(); - } - trackPair.track.name = name; - }; - - const value = trackPair.track.name || ''; - trackPair.browser.inputDialog.present({ label: 'Track Name', value, callback }, e); - }; - - return { element, click }; -} - -/* - * The MIT License (MIT) - * - * Copyright (c) 2014 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -class TrackGearPopup { - - constructor(parentElement) { - // Popover container - this.popoverElement = document.createElement('div'); - this.popoverElement.className = 'jb-igv-menu-popup'; - parentElement.appendChild(this.popoverElement); - - // Popover header - const popoverHeaderElement = document.createElement('div'); - popoverHeaderElement.className = 'jb-igv-menu-popup-header'; - this.popoverElement.appendChild(popoverHeaderElement); - - // Attach close handler - uiUtils.attachDialogCloseHandlerWithParent(popoverHeaderElement, () => { - this.popoverElement.style.display = 'none'; - }); - - // Popover content - this.popoverContentElement = document.createElement('div'); - this.popoverElement.appendChild(this.popoverContentElement); - - // Make draggable - makeDraggable(this.popoverElement, popoverHeaderElement); - - // Prevent click propagation - popoverHeaderElement.addEventListener('click', (e) => { - e.stopPropagation(); - e.preventDefault(); - }); - } - - presentMenuList(dx, dy, list) { - TrackGearPopup.hideAllMenuPopups(); - - if (list.length > 0) { - // Clear popover content - this.popoverContentElement.innerHTML = ''; - - const updatedList = trackMenuItemListHelper(list, this.popoverElement); - - for (const item of updatedList) { - if (item.init) { - item.init(); - } - - - // Remove the border-top class from the first item - if (updatedList.indexOf(item) === 0) { - item.element.classList.remove('igv-track-menu-border-top'); - } - - // Add 'jb-igv-menu-popup-shim' if applicable - if ( - !item.element.classList.contains('igv-track-menu-border-top') && - !item.element.classList.contains('jb-igv-menu-popup-check-container') && - item.element.tagName === 'DIV' - ) { - item.element.classList.add('jb-igv-menu-popup-shim'); - } - - // Append element to the popover content - this.popoverContentElement.appendChild(item.element); - } - - // Position and display the popover - this.popoverElement.style.left = `${dx}px`; - this.popoverElement.style.top = `${dy}px`; - this.popoverElement.style.display = 'block'; - } - } - - dispose() { - this.popoverElement.innerHTML = ''; - this.popoverContentElement.innerHTML = ''; - - for (let key of Object.keys(this)) { - this[key] = undefined; - } - } - - static hideAllMenuPopups() { - const popups = document.querySelectorAll('.jb-igv-menu-popup'); - for (let popup of popups) { - popup.style.display = 'none'; - } - } - -} - -function trackMenuItemListHelper(itemList, popoverElement) { - - let results = []; - - if (itemList.length > 0) { - - results = itemList.map((item, i) => { - let element; - - if (item.name) { - element = document.createElement('div'); - element.textContent = item.name; - } else if (item.element) { - element = item.element instanceof HTMLElement ? item.element.cloneNode(true) : item.element; - } else if (typeof item.label === 'string') { - element = document.createElement('div'); - element.innerHTML = item.label; - } else if (typeof item === 'string') { - if (item.startsWith("<")) { - const tempDiv = document.createElement('div'); - tempDiv.innerHTML = item; - element = tempDiv.firstElementChild; - } else { - element = document.createElement('div'); - element.textContent = item; - } - } - - // Add top border class to the first item - if (i === 0 && element) { - element.classList.add('igv-track-menu-border-top'); - } - - // Add click, touchend, and mouseup event listeners if item has a click handler - if (item.click && element) { - const eventHandler = e => { - e.preventDefault(); - e.stopPropagation(); - item.click(e); - popoverElement.style.display = 'none'; - }; - - element.addEventListener('click', eventHandler); - element.addEventListener('touchend', eventHandler); - element.addEventListener('mouseup', e => { - e.preventDefault(); - e.stopPropagation(); - }); - } - - return { element, init: item.init || undefined }; - }); - } - - return results; -} - -class Tile { - - constructor(chr, startBP, endBP, bpp, buffer, features) { - this.chr = chr; - this.startBP = startBP; - this.endBP = endBP; - this.bpp = bpp; - this.buffer = buffer; - this.features = features; - } - - containsRange(chr, startBP, endBP, bpp) { - return chr === this.chr && this.bpp === bpp && this.startBP <= startBP && this.endBP >= endBP; - } -} - -/** - * Created by dat on 4/5/17. - */ - -class TrackPair { - - constructor(browser, track) { - this.browser = browser; - this.track = track; - this.x = undefined; - this.y = undefined; - } - - init() { - this.colorPicker = new ColorPicker({ - parent: this.x.viewportElement, - width: 456, - height: undefined, - colorHandler: color => this.setColor(color) - }); - this.colorPicker.hide(); - - this.dataRangeDialog = new DataRangeDialog(this.x.viewportElement, (min, max) => this.setDataRange(min, max)); - - this.appendRightHandGutter(this.x.viewportElement); - - for (const el of this.x.trackReorderHandleElement.querySelectorAll('.fa')) { - el.addEventListener('click', e => { - e.preventDefault(); - e.stopPropagation(); - - const direction = e.target.classList.contains('fa-arrow-up') ? -1 : 1; - - let order = parseInt(this.x.viewportElement.style.order); - - if (order === 0 && direction === -1) { - return; - } else if (this.browser.trackPairs.length - 1 === order && direction === 1) { - return; - } - - const newOrder = direction === -1 ? order - 1 : order + 1; - - const targetTrackPair = this.browser.trackPairs.find( - trackPair => newOrder === parseInt(trackPair.x.viewportElement.style.order) - ); - - if (targetTrackPair) { - targetTrackPair.x.viewportElement.style.order = `${order}`; - targetTrackPair.y.viewportElement.style.order = `${order}`; - } - - this.x.viewportElement.style.order = `${newOrder}`; - this.y.viewportElement.style.order = `${newOrder}`; - - const a = this.browser.trackPairs; - [a[order], a[newOrder]] = [a[newOrder], a[order]]; - - setTrackReorderArrowColors(this.browser.trackPairs); - }); - } - - // igvjs compatibility - this.track.trackView = this; - this.track.trackView.trackDiv = this.x.viewportElement; - } - - presentColorPicker() { - const bbox = this.x.trackDiv.getBoundingClientRect(); - this.colorPicker.origin = { x: bbox.x, y: 0 }; - - // Set the position of the colorPicker container - this.colorPicker.containerElement.style.left = `${this.colorPicker.origin.x}px`; - this.colorPicker.containerElement.style.top = `${this.colorPicker.origin.y}px`; - - // Show the colorPicker container - this.colorPicker.containerElement.style.display = 'block'; - } - - setTrackLabelName(name) { - this.x.labelElement.textContent = name; - this.x.labelElement.title = name; - } - - setColor(color) { - this.y.tile = undefined; - this.x.tile = undefined; - this.track.color = color; - this.repaintViews(); - } - - dataRange() { - return this.track.dataRange ? this.track.dataRange : undefined; - } - - setDataRange(min, max) { - if (min !== undefined) { - this.track.dataRange.min = min; - this.track.config.min = min; - } - if (max !== undefined) { - this.track.dataRange.max = max; - this.track.config.max = max; - } - this.track.autoscale = false; - this.track.config.autoScale = false; - this.y.tile = undefined; - this.x.tile = undefined; - this.repaintViews(); - } - - appendRightHandGutter(parentElement) { - const div = document.createElement('div'); - div.className = 'hic-igv-right-hand-gutter'; - parentElement.appendChild(div); - this.createTrackGearPopup(div); - } - - createTrackGearPopup(parentElement) { - const container = document.createElement('div'); - container.className = 'igv-trackgear-container'; - parentElement.appendChild(container); - - container.appendChild(createIcon('cog')); - - this.trackGearPopup = new TrackGearPopup(parentElement); - this.trackGearPopup.popoverElement.style.display = 'none'; - - container.addEventListener('click', e => { - e.preventDefault(); - e.stopPropagation(); - - const { trackMenuItemList, numericDataMenuItems, nucleotideColorChartMenuItems } = MenuUtils; - - const list = [...trackMenuItemList(this)]; - - if (this.track.type === 'wig') { - list.push(...numericDataMenuItems(this)); - } - - if (this.track.type === 'sequence') { - list.push(...nucleotideColorChartMenuItems(this)); - } - - const width = this.trackGearPopup.popoverElement.getBoundingClientRect().width; - - this.trackGearPopup.presentMenuList(-width, 0, list); - }); - } - - async updateViews() { - - if (this.updating) { - this.pending = true; - } else { - try { - this.updating = true; - const genomicStateX = this.browser.genomicState(this.x.axis); - let imageTileX = await this.getTileX(genomicStateX); - if (imageTileX) { - this.x.drawTile(imageTileX, genomicStateX); - } - - const genomicStateY = this.browser.genomicState(this.y.axis); - let imageTileY = await this.getTileY(genomicStateY); - if (imageTileY) { - this.y.drawTile(imageTileY, genomicStateY); - } - } finally { - this.updating = false; - if (this.pending) { - this.pending = false; - this.updateViews(); - } - } - } - } - - /** - * Repaint current tiles with cached features (due to color, scale, or other visual attribute change) - * @returns {Promise} - */ - async repaintViews() { - - const genomicStateX = this.browser.genomicState(this.x.axis); - if (this.tileX) { - this.tileX = await this.createImageTile({ axis: 'x', ...genomicStateX }, this.tileX.features); - this.x.drawTile(this.tileX, genomicStateX); - } - - const genomicStateY = this.browser.genomicState(this.y.axis); - if (this.tileY) { - this.tileY = await this.createImageTile({ axis: 'y', ...genomicStateY }, this.tileY.features); - this.y.drawTile(this.tileY, genomicStateY); - } - } - - async getTileX(genomicState) { - - const { chromosome, bpp } = genomicState; - - if (!(this.tileX && this.tileX.containsRange(chromosome.name, genomicState.startBP, genomicState.endBP, bpp))) { - this.tileX = await this.createImageTile({ axis: 'x', ...genomicState }); - } - - return this.tileX - } - - async getTileY(genomicState) { - - const { chromosome, bpp } = genomicState; - - if (!(this.tileY && this.tileY.containsRange(chromosome.name, genomicState.startBP, genomicState.endBP, bpp))) { - this.tileY = await this.createImageTile({ axis: 'y', ...genomicState }); - } - - return this.tileY - } - - async createImageTile(genomicState, tileFeatures) { - if ( - this.track.visibilityWindow > 0 && - genomicState.bpp * Math.max(this.x.canvasElement.width, this.x.canvasElement.height) > this.track.visibilityWindow - ) ; else { - // Expand the requested range so we can pan a bit without reloading - const pixelWidth = 3 * this.x.canvasElement.width; - const lengthBP = Math.round(genomicState.bpp * pixelWidth); - const bpStart = Math.max(0, Math.round(genomicState.startBP - lengthBP / 3)); - const bpEnd = bpStart + lengthBP; - - const features = tileFeatures || await this.track.getFeatures( - genomicState.chromosome.name, - bpStart, - bpEnd, - genomicState.bpp - ); - - const canvas = document.createElement('canvas'); - canvas.width = pixelWidth; - canvas.height = this.x.canvasElement.height; - - const context = canvas.getContext('2d'); - - if (features) { - const drawConfiguration = { - axis: genomicState.axis, - features, - context, - pixelWidth, - bpStart, - bpEnd, - bpPerPixel: genomicState.bpp, - genomicState, - pixelHeight: Math.min(canvas.width, canvas.height), - viewportContainerX: (genomicState.startBP - bpStart) / genomicState.bpp, - viewportContainerWidth: pixelWidth, - viewportWidth: pixelWidth, - referenceFrame: {}, - }; - - if (this.track.autoscale || !this.track.dataRange) { - if (typeof this.track.doAutoscale === 'function') { - this.track.doAutoscale(features); - } else { - this.track.dataRange = doAutoscale(features); - } - } - - this.track.draw(drawConfiguration); - } else { - const wye = canvas.height - canvas.height / 4; - index$1.IGVGraphics.fillRect(context, 0, wye, canvas.width, 2, { fillStyle: 'rgba(0,0,0,0.1)' }); - } - - this.tile = new Tile(genomicState.chromosome.name, bpStart, bpEnd, genomicState.bpp, canvas, features); - return this.tile; - } - } - - dispose() { - this.x.dispose(); - this.y.dispose(); - } -} - -function doAutoscale (features = []) { - let min = Number.MAX_VALUE; - let max = -Number.MAX_VALUE; - - if (features.length > 0) { - for (const { value } of features) { - if (!Number.isNaN(value)) { - min = Math.min(min, value); - max = Math.max(max, value); - } - } - - // Ensure we have a zero baseline - if (max > 0) min = Math.min(0, min); - if (max < 0) max = 0; - } else { - // No features -- default - min = 0; - max = 100; - } - - return { min, max }; -} - -function setTrackReorderArrowColors(trackPairs) { - - for (const trackPair of trackPairs) { - const el = trackPair.x.viewportElement; - const order = parseInt(el.style.order); - - const arrowUp = el.querySelector('.fa-arrow-up'); - const arrowDown = el.querySelector('.fa-arrow-down'); - - if (order === 0) { - arrowUp.style.color = 'rgba(0, 0, 0, 0)'; - arrowDown.style.color = '#7F7F7F'; - } else if (order === trackPairs.length - 1) { - arrowUp.style.color = '#7F7F7F'; - arrowDown.style.color = 'rgba(0, 0, 0, 0)'; - } else { - arrowUp.style.color = '#7F7F7F'; - arrowDown.style.color = '#7F7F7F'; - } - } - -} - -class TrackRenderer { - - constructor(browser, track, axis) { - this.browser = browser; - this.track = track; - this.axis = axis; - this.id = `trackRender_${domUtils.guid()}`; - } - - init(containerElement, size, order) { - this.viewportElement = document.createElement('div'); - this.viewportElement.className = (this.axis === 'x') ? 'x-track-canvas-container' : 'y-track-canvas-container'; - containerElement.appendChild(this.viewportElement); - - if (this.axis === 'x') { - this.viewportElement.style.height = `${size}px`; - } else { - this.viewportElement.style.width = `${size}px`; - } - this.viewportElement.style.order = `${order}`; - - this.canvasElement = document.createElement('canvas'); - this.viewportElement.appendChild(this.canvasElement); - this.ctx = this.canvasElement.getContext("2d"); - - if (this.axis === 'x') { - this.trackReorderHandleElement = document.createElement('div'); - this.trackReorderHandleElement.className = 'x-track-reorder-handle'; - this.viewportElement.appendChild(this.trackReorderHandleElement); - - this.trackReorderHandleElement.innerHTML = ''; - - this.labelElement = document.createElement('div'); - this.labelElement.className = 'x-track-label'; - this.viewportElement.appendChild(this.labelElement); - - const labelText = this.track.name || ''; - this.labelElement.textContent = labelText; - this.labelElement.title = labelText; - - this.labelElement.style.display = this.browser.showTrackLabelAndGutter ? 'block' : 'none'; - - this.viewportElement.addEventListener('click', (e) => { - e.preventDefault(); - e.stopPropagation(); - this.browser.toggleTrackLabelAndGutterState(); - const displayState = this.browser.showTrackLabelAndGutter ? 'block' : 'none'; - document.querySelectorAll('.x-track-label, .hic-igv-right-hand-gutter').forEach(el => { - el.style.display = displayState; - }); - }); - } - - this.spinnerElement = document.createElement('div'); - this.spinnerElement.className = (this.axis === 'x') ? 'x-track-spinner' : 'y-track-spinner'; - this.viewportElement.appendChild(this.spinnerElement); - this.stopSpinner(); - } - - dispose() { - this.tile = undefined; - this.viewportElement.remove(); - } - - syncCanvas() { - this.canvasElement.width = this.viewportElement.offsetWidth; - this.canvasElement.height = this.viewportElement.offsetHeight; - } - - drawTile(tile, genomicState) { - if (tile) { - - let w; - let h; - if (this.axis === 'x') { - w = this.canvasElement.width; - h = this.canvasElement.height; - } else { - h = this.canvasElement.width; - w = this.canvasElement.height; - this.ctx.setTransform(0, 1, 1, 0, 0, 0); - } - - this.ctx.clearRect(0, 0, w, h); - - this.offsetPixel = Math.round((tile.startBP - genomicState.startBP) / genomicState.bpp); - this.ctx.drawImage(tile.buffer, this.offsetPixel, 0); - - } - } - - startSpinner() { - this.browser.startSpinner(); - } - - stopSpinner() { - this.browser.stopSpinner(); - } - - isLoading() { - return this.loading !== undefined; - } -} - -/* - * The MIT License (MIT) - * - * Copyright (c) 2016-2017 The Regents of the University of California - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and - * associated documentation files (the "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the - * following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING - * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - */ - - -function HICEvent (type, data, propogate) { - return { - type: type, - data: data || {}, - propogate: propogate !== undefined ? propogate : true // Default to true - } -} - -/** - * Test if object is a File or File-like object. - * - * Copied from igv-utils.FileUtils version 1.3.8 - * - * @param object - */ -function isFile(object) { - if(!object) { - return false; - } - return typeof object !== 'function' && - (object instanceof File || - (object.name !== undefined && typeof object.slice === 'function' && typeof object.arrayBuffer === 'function')) -} - -function createDOMFromHTMLString(string) { - const template = document.createElement('template'); - template.innerHTML = string.trim(); // Removes whitespace to avoid unintended text nodes - return template.content.firstElementChild; -} - -function getOffset(element) { - const { top, left } = element.getBoundingClientRect(); - return { top: top + window.scrollY, left: left + window.scrollX }; -} - -function parseRgbString(rgbString) { - - // Use a regular expression to extract the numbers from the string - const match = rgbString.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/); - - // Check if the match is successful - if (!match) { - throw new Error("Invalid RGB string format"); - } - - // Convert the matched strings into integers and return them as an array - return match.slice(1, 4).map(Number); -} - -function prettyPrint(number) { - - if (typeof number !== "number") { - console.error(`${ number } must be a number`); - return - } - - const integerPart = Math.trunc(number); - return integerPart.toLocaleString() -} - -function extractName(config) { - if (config.name === undefined) { - const urlOrFile = config.url; - if (isFile(urlOrFile)) { - return urlOrFile.name - } else { - const str = urlOrFile.split('?').shift(); - const idx = urlOrFile.lastIndexOf("/"); - return idx > 0 ? str.substring(idx + 1) : str - } - } else { - return config.name - } -} - -function presentError(prefix, error) { - const httpMessages = - { - 401: "Access unauthorized", - 403: "Access forbidden", - 404: "Not found" - }; - - const msg = httpMessages[error.message] || error.message; - Alert$1.presentAlert(`${prefix}: ${msg}`); -} - -/** - * Created by dat on 4/4/17. - */ - -class LayoutController { - - constructor(browser, rootElement) { - this.browser = browser; - createNavBar(browser, rootElement); - this.createAllContainers(browser, rootElement); - } - - createAllContainers(browser, root) { - const htmlXTrackContainer = createDOMFromHTMLString(` -
-
-
- -
-
`); - - root.appendChild(htmlXTrackContainer); - - this.xTrackContainer = root.querySelector(`div[id$='x-track-container']`); - this.trackShim = this.xTrackContainer.querySelector(`div[id$='track-shim']`); - this.xTracks = this.xTrackContainer.querySelector(`div[id$='x-tracks']`); - this.yTrackGuideElement = this.xTrackContainer.querySelector(`div[id$='y-track-guide']`); - - this.contentContainer = createDOMFromHTMLString(`
`); - root.appendChild(this.contentContainer); - - const htmlXAxisContainer = createDOMFromHTMLString(` -
-
- -
-
-
`); - - this.contentContainer.appendChild(htmlXAxisContainer); - const xAxisContainer = this.contentContainer.querySelector(`div[id$='x-axis-container']`); - - this.xAxisRuler = new Ruler(browser, xAxisContainer, 'x'); - - const htmlYTracksYAxisViewportYScrollbar = createDOMFromHTMLString(` -
-
- -
-
- -
-
-
`); - - this.contentContainer.appendChild(htmlYTracksYAxisViewportYScrollbar); - const yTracksYAxisViewportYScrollbar = this.contentContainer.querySelector(`div[id$='-y-tracks-y-axis-viewport-y-scrollbar']`); - - this.yTracks = yTracksYAxisViewportYScrollbar.querySelector(`div[id$='-y-tracks']`); - this.xTrackGuideElement = this.yTracks.querySelector(`div[id$='-x-track-guide']`); - - this.yAxisRuler = new Ruler(browser, yTracksYAxisViewportYScrollbar, 'y'); - - this.xAxisRuler.otherRulerCanvas = this.yAxisRuler.canvasElement; - this.xAxisRuler.otherRuler = this.yAxisRuler; - - this.yAxisRuler.otherRulerCanvas = this.xAxisRuler.canvasElement; - this.yAxisRuler.otherRuler = this.xAxisRuler; - - const htmlViewport = createDOMFromHTMLString(` -
- - - - - -
`); - - yTracksYAxisViewportYScrollbar.appendChild(htmlViewport); - - const htmlYAxisScrollbarContainer = createDOMFromHTMLString(` -
-
-
-
-
`); - - yTracksYAxisViewportYScrollbar.appendChild(htmlYAxisScrollbarContainer); - - const htmlXAxisScrollbarContainer = createDOMFromHTMLString(` -
-
-
-
-
-
-
`); - - this.contentContainer.appendChild(htmlXAxisScrollbarContainer); - } - - getContactMatrixViewport() { - const parent = this.contentContainer.querySelector("div[id$='-y-tracks-y-axis-viewport-y-scrollbar']"); - return parent ? parent.querySelector("div[id$='-viewport']") : null; - } - - getYAxisScrollbarContainer() { - const parent = this.contentContainer.querySelector("div[id$='-y-tracks-y-axis-viewport-y-scrollbar']"); - return parent ? parent.querySelector("div[id$='-y-axis-scrollbar-container']") : null; - } - - getXAxisScrollbarContainer() { - return this.contentContainer.querySelector("div[id$='-x-axis-scrollbar-container']"); - } - - updateLayoutWithTracks(tracks) { - - const { trackHeight } = getLayoutDimensions(); - - this.resizeLayoutWithTrackXYPairCount(tracks.length + this.browser.trackPairs.length); - - for (const track of tracks) { - - const trackPair = new TrackPair(this.browser, track); - this.browser.trackPairs.unshift(trackPair); - - trackPair.x = new TrackRenderer(this.browser, track, 'x'); - trackPair.x.init(this.xTracks, trackHeight, this.browser.trackPairs.indexOf(trackPair)); - - trackPair.y = new TrackRenderer(this.browser, track, 'y'); - trackPair.y.init(this.yTracks, trackHeight, this.browser.trackPairs.indexOf(trackPair)); - - trackPair.init(); - - EventBus.globalBus.post(HICEvent("TrackXYPairLoad", trackPair)); - } - - for (const trackPair of this.browser.trackPairs) { - const order = `${ this.browser.trackPairs.indexOf(trackPair) }`; - trackPair.x.viewportElement.style.order = order; - trackPair.y.viewportElement.style.order = order; - } - - setTrackReorderArrowColors(this.browser.trackPairs); - - } - - removeAllTrackXYPairs() { - - if (this.browser.trackPairs.length === 0 ) { - return; - } - - for(let trackPair of this.browser.trackPairs) { - // discard DOM element's - trackPair.dispose(); - } - this.browser.trackPairs = []; - this.browser.updateLayout(); - this.resizeLayoutWithTrackXYPairCount(0); - - } - - removeTrackXYPair(trackXYPair) { - - if (this.browser.trackPairs.length > 0) { - - // remove DOM element - trackXYPair.x.viewportElement.remove(); - trackXYPair.y.viewportElement.remove(); - - // remove from trackPairs list - const index = this.browser.trackPairs.indexOf(trackXYPair); - this.browser.trackPairs.splice(index, 1); - - this.resizeLayoutWithTrackXYPairCount(this.browser.trackPairs.length); - - this.browser.updateLayout(); - - EventBus.globalBus.post(HICEvent("TrackXYPairRemoval", trackXYPair)); - } - } - - resizeLayoutWithTrackXYPairCount(trackXYPairCount) { - const { trackHeight, trackMargin, axisHeight, scrollbarHeight } = getLayoutDimensions(); - const trackAggregateHeight = (trackXYPairCount === 0) ? 0 : trackXYPairCount * (trackHeight + trackMargin); - - let tokens = [getNavbarHeight(), trackAggregateHeight].map(number => `${number}px`); - const heightCalc = `calc(100% - (${tokens.join(' + ')}))`; - - tokens = [trackAggregateHeight, axisHeight, scrollbarHeight].map(number => `${number}px`); - const widthCalc = `calc(100% - (${tokens.join(' + ')}))`; - - // x-track container - this.xTrackContainer.style.height = `${trackAggregateHeight}px`; - - // track labels - this.trackShim.style.width = `${trackAggregateHeight}px`; - - // x-tracks - this.xTracks.style.width = widthCalc; - - // content container - this.contentContainer.style.height = heightCalc; - - // x-axis - repaint canvas - this.xAxisRuler.updateWidthWithCalculation(widthCalc); - - // y-tracks - this.yTracks.style.width = `${trackAggregateHeight}px`; - - // y-axis - repaint canvas - this.yAxisRuler.updateHeight(this.yAxisRuler.axisElement.offsetHeight); - - // viewport - this.browser.contactMatrixView.viewportElement.style.width = widthCalc; - - // x-scrollbar - this.browser.contactMatrixView.scrollbarWidget.xAxisScrollbarContainerElement.style.width = widthCalc; - } - -} - -function getNavbarContainer(browser) { - return browser.rootElement.querySelector('.hic-navbar-container'); -} - -function getNavbarHeight() { - const { navBarLabelHeight, navBarWidgetContainerHeight, navBarWidgetContainerMargin } = getLayoutDimensions(); - return 2 * (navBarLabelHeight + navBarWidgetContainerHeight + (2 * navBarWidgetContainerMargin)); -} - -function getCSSVariable(name) { - return parseInt(getComputedStyle(document.documentElement).getPropertyValue(name)); -} - -function setCSSVariable(name, value) { - document.documentElement.style.setProperty(name, `${value}px`); -} - -function getLayoutDimensions() { - return { - navBarLabelHeight: getCSSVariable('--nav-bar-label-height'), - navBarWidgetContainerHeight: getCSSVariable('--nav-bar-widget-container-height'), - navBarWidgetContainerMargin: getCSSVariable('--nav-bar-widget-container-margin'), - scrollbarHeight: getCSSVariable('--hic-scrollbar-height'), - axisHeight: getCSSVariable('--hic-axis-height'), - trackMargin: getCSSVariable('--track-margin'), - trackHeight: getCSSVariable('--track-height') - }; -} - -function setViewportSize(width, height) { - setCSSVariable('--hic-viewport-width', width); - setCSSVariable('--hic-viewport-height', height); -} - -function createNavBar(browser, root) { - - const hicNavbarContainer = document.createElement('div'); - hicNavbarContainer.className = 'hic-navbar-container'; - root.appendChild(hicNavbarContainer); - - hicNavbarContainer.addEventListener('click', e => { - e.stopPropagation(); - e.preventDefault(); - setCurrentBrowser(browser); - }); - - const htmlContactMapHicNavBarMapContainer = - `
-
-
- - -
-
`; - - hicNavbarContainer.appendChild(createDOMFromHTMLString(htmlContactMapHicNavBarMapContainer)); - - browser.contactMapLabel = hicNavbarContainer.querySelector(`div[id$='contact-map-hic-nav-bar-map-label']`); - browser.menuPresentDismiss = hicNavbarContainer.querySelector('.fa-bars'); - browser.menuPresentDismiss.addEventListener('click', e => browser.toggleMenu()); - - browser.browserPanelDeleteButton = hicNavbarContainer.querySelector('.fa-minus-circle'); - browser.browserPanelDeleteButton.addEventListener('click', e => deleteBrowser(browser)); - - // Delete button is only visible if there is more than one browser - browser.browserPanelDeleteButton.style.display = 'none'; - - const htmlControlMapHicNavBarMapContainer = - `
-
-
`; - - hicNavbarContainer.appendChild(createDOMFromHTMLString(htmlControlMapHicNavBarMapContainer)); - - browser.controlMapLabel = hicNavbarContainer.querySelector(`div[id$='control-map-hic-nav-bar-map-label']`); - - const htmlUpperHicNavBarWidgetContainer = `
`; - hicNavbarContainer.appendChild(createDOMFromHTMLString(htmlUpperHicNavBarWidgetContainer)); - - const htmlLowerHicNavBarWidgetContainer = `
`; - hicNavbarContainer.appendChild(createDOMFromHTMLString(htmlLowerHicNavBarWidgetContainer)); -} - -// from https://github.com/imaya/zlib.js - -var Zlib = { - Huffman: {}, - Util: {}, - CRC32: {} -}; - - -/** - * Compression Method - * @enum {number} - */ -Zlib.CompressionMethod = { - DEFLATE: 8, - RESERVED: 15 -}; - - - - -/** - * @param {Object=} opt_params options. - * @constructor - */ -Zlib.Zip = function(opt_params) { - opt_params = opt_params || {}; - /** @type {Array.<{ - * buffer: !(Array.|Uint8Array), - * option: Object, - * compressed: boolean, - * encrypted: boolean, - * size: number, - * crc32: number - * }>} */ - this.files = []; - /** @type {(Array.|Uint8Array)} */ - this.comment = opt_params['comment']; - /** @type {(Array.|Uint8Array)} */ - this.password; -}; - - -/** - * @enum {number} - */ -Zlib.Zip.CompressionMethod = { - STORE: 0, - DEFLATE: 8 -}; - -/** - * @enum {number} - */ -Zlib.Zip.OperatingSystem = { - MSDOS: 0, - UNIX: 3, - MACINTOSH: 7 -}; - -/** - * @enum {number} - */ -Zlib.Zip.Flags = { - ENCRYPT: 0x0001, - DESCRIPTOR: 0x0008, - UTF8: 0x0800 -}; - -/** - * @type {Array.} - * @const - */ -Zlib.Zip.FileHeaderSignature = [0x50, 0x4b, 0x01, 0x02]; - -/** - * @type {Array.} - * @const - */ -Zlib.Zip.LocalFileHeaderSignature = [0x50, 0x4b, 0x03, 0x04]; - -/** - * @type {Array.} - * @const - */ -Zlib.Zip.CentralDirectorySignature = [0x50, 0x4b, 0x05, 0x06]; - -/** - * @param {Array.|Uint8Array} input - * @param {Object=} opt_params options. - */ -Zlib.Zip.prototype.addFile = function(input, opt_params) { - opt_params = opt_params || {}; - /** @type {string} */ - opt_params['filename']; - /** @type {boolean} */ - var compressed; - /** @type {number} */ - var size = input.length; - /** @type {number} */ - var crc32 = 0; - - if (input instanceof Array) { - input = new Uint8Array(input); - } - - // default - if (typeof opt_params['compressionMethod'] !== 'number') { - opt_params['compressionMethod'] = Zlib.Zip.CompressionMethod.DEFLATE; - } - - // その場で圧縮する場合 - if (opt_params['compress']) { - switch (opt_params['compressionMethod']) { - case Zlib.Zip.CompressionMethod.STORE: - break; - case Zlib.Zip.CompressionMethod.DEFLATE: - crc32 = Zlib.CRC32.calc(input); - input = this.deflateWithOption(input, opt_params); - compressed = true; - break; - default: - throw new Error('unknown compression method:' + opt_params['compressionMethod']); - } - } - - this.files.push({ - buffer: input, - option: opt_params, - compressed: compressed, - encrypted: false, - size: size, - crc32: crc32 - }); -}; - -/** - * @param {(Array.|Uint8Array)} password - */ -Zlib.Zip.prototype.setPassword = function(password) { - this.password = password; -}; - -Zlib.Zip.prototype.compress = function() { - /** @type {Array.<{ - * buffer: !(Array.|Uint8Array), - * option: Object, - * compressed: boolean, - * encrypted: boolean, - * size: number, - * crc32: number - * }>} */ - var files = this.files; - /** @type {{ - * buffer: !(Array.|Uint8Array), - * option: Object, - * compressed: boolean, - * encrypted: boolean, - * size: number, - * crc32: number - * }} */ - var file; - /** @type {!(Array.|Uint8Array)} */ - var output; - /** @type {number} */ - var op1; - /** @type {number} */ - var op2; - /** @type {number} */ - var op3; - /** @type {number} */ - var localFileSize = 0; - /** @type {number} */ - var centralDirectorySize = 0; - /** @type {number} */ - var endOfCentralDirectorySize; - /** @type {number} */ - var offset; - /** @type {number} */ - var needVersion; - /** @type {number} */ - var flags; - /** @type {Zlib.Zip.CompressionMethod} */ - var compressionMethod; - /** @type {Date} */ - var date; - /** @type {number} */ - var crc32; - /** @type {number} */ - var size; - /** @type {number} */ - var plainSize; - /** @type {number} */ - var filenameLength; - /** @type {number} */ - var extraFieldLength; - /** @type {number} */ - var commentLength; - /** @type {(Array.|Uint8Array)} */ - var filename; - /** @type {(Array.|Uint8Array)} */ - var extraField; - /** @type {(Array.|Uint8Array)} */ - var comment; - /** @type {(Array.|Uint8Array)} */ - var buffer; - /** @type {*} */ - var tmp; - /** @type {Array.|Uint32Array|Object} */ - var key; - /** @type {number} */ - var i; - /** @type {number} */ - var il; - /** @type {number} */ - var j; - /** @type {number} */ - var jl; - - // ファイルの圧縮 - for (i = 0, il = files.length; i < il; ++i) { - file = files[i]; - filenameLength = - (file.option['filename']) ? file.option['filename'].length : 0; - extraFieldLength = - (file.option['extraField']) ? file.option['extraField'].length : 0; - commentLength = - (file.option['comment']) ? file.option['comment'].length : 0; - - // 圧縮されていなかったら圧縮 - if (!file.compressed) { - // 圧縮前に CRC32 の計算をしておく - file.crc32 = Zlib.CRC32.calc(file.buffer); - - switch (file.option['compressionMethod']) { - case Zlib.Zip.CompressionMethod.STORE: - break; - case Zlib.Zip.CompressionMethod.DEFLATE: - file.buffer = this.deflateWithOption(file.buffer, file.option); - file.compressed = true; - break; - default: - throw new Error('unknown compression method:' + file.option['compressionMethod']); - } - } - - // encryption - if (file.option['password'] !== void 0|| this.password !== void 0) { - // init encryption - key = this.createEncryptionKey(file.option['password'] || this.password); - - // add header - buffer = file.buffer; - { - tmp = new Uint8Array(buffer.length + 12); - tmp.set(buffer, 12); - buffer = tmp; - } - - for (j = 0; j < 12; ++j) { - buffer[j] = this.encode( - key, - i === 11 ? (file.crc32 & 0xff) : (Math.random() * 256 | 0) - ); - } - - // data encryption - for (jl = buffer.length; j < jl; ++j) { - buffer[j] = this.encode(key, buffer[j]); - } - file.buffer = buffer; - } - - // 必要バッファサイズの計算 - localFileSize += - // local file header - 30 + filenameLength + - // file data - file.buffer.length; - - centralDirectorySize += - // file header - 46 + filenameLength + commentLength; - } - - // end of central directory - endOfCentralDirectorySize = 22 + (this.comment ? this.comment.length : 0); - output = new (Uint8Array )( - localFileSize + centralDirectorySize + endOfCentralDirectorySize - ); - op1 = 0; - op2 = localFileSize; - op3 = op2 + centralDirectorySize; - - // ファイルの圧縮 - for (i = 0, il = files.length; i < il; ++i) { - file = files[i]; - filenameLength = - file.option['filename'] ? file.option['filename'].length : 0; - extraFieldLength = 0; // TODO - commentLength = - file.option['comment'] ? file.option['comment'].length : 0; - - //------------------------------------------------------------------------- - // local file header & file header - //------------------------------------------------------------------------- - - offset = op1; - - // signature - // local file header - output[op1++] = Zlib.Zip.LocalFileHeaderSignature[0]; - output[op1++] = Zlib.Zip.LocalFileHeaderSignature[1]; - output[op1++] = Zlib.Zip.LocalFileHeaderSignature[2]; - output[op1++] = Zlib.Zip.LocalFileHeaderSignature[3]; - // file header - output[op2++] = Zlib.Zip.FileHeaderSignature[0]; - output[op2++] = Zlib.Zip.FileHeaderSignature[1]; - output[op2++] = Zlib.Zip.FileHeaderSignature[2]; - output[op2++] = Zlib.Zip.FileHeaderSignature[3]; - - // compressor info - needVersion = 20; - output[op2++] = needVersion & 0xff; - output[op2++] = - /** @type {Zlib.Zip.OperatingSystem} */ - (file.option['os']) || - Zlib.Zip.OperatingSystem.MSDOS; - - // need version - output[op1++] = output[op2++] = needVersion & 0xff; - output[op1++] = output[op2++] = (needVersion >> 8) & 0xff; - - // general purpose bit flag - flags = 0; - if (file.option['password'] || this.password) { - flags |= Zlib.Zip.Flags.ENCRYPT; - } - output[op1++] = output[op2++] = flags & 0xff; - output[op1++] = output[op2++] = (flags >> 8) & 0xff; - - // compression method - compressionMethod = - /** @type {Zlib.Zip.CompressionMethod} */ - (file.option['compressionMethod']); - output[op1++] = output[op2++] = compressionMethod & 0xff; - output[op1++] = output[op2++] = (compressionMethod >> 8) & 0xff; - - // date - date = /** @type {(Date|undefined)} */(file.option['date']) || new Date(); - output[op1++] = output[op2++] = - ((date.getMinutes() & 0x7) << 5) | - (date.getSeconds() / 2 | 0); - output[op1++] = output[op2++] = - (date.getHours() << 3) | - (date.getMinutes() >> 3); - // - output[op1++] = output[op2++] = - ((date.getMonth() + 1 & 0x7) << 5) | - (date.getDate()); - output[op1++] = output[op2++] = - ((date.getFullYear() - 1980 & 0x7f) << 1) | - (date.getMonth() + 1 >> 3); - - // CRC-32 - crc32 = file.crc32; - output[op1++] = output[op2++] = crc32 & 0xff; - output[op1++] = output[op2++] = (crc32 >> 8) & 0xff; - output[op1++] = output[op2++] = (crc32 >> 16) & 0xff; - output[op1++] = output[op2++] = (crc32 >> 24) & 0xff; - - // compressed size - size = file.buffer.length; - output[op1++] = output[op2++] = size & 0xff; - output[op1++] = output[op2++] = (size >> 8) & 0xff; - output[op1++] = output[op2++] = (size >> 16) & 0xff; - output[op1++] = output[op2++] = (size >> 24) & 0xff; - - // uncompressed size - plainSize = file.size; - output[op1++] = output[op2++] = plainSize & 0xff; - output[op1++] = output[op2++] = (plainSize >> 8) & 0xff; - output[op1++] = output[op2++] = (plainSize >> 16) & 0xff; - output[op1++] = output[op2++] = (plainSize >> 24) & 0xff; - - // filename length - output[op1++] = output[op2++] = filenameLength & 0xff; - output[op1++] = output[op2++] = (filenameLength >> 8) & 0xff; - - // extra field length - output[op1++] = output[op2++] = extraFieldLength & 0xff; - output[op1++] = output[op2++] = (extraFieldLength >> 8) & 0xff; - - // file comment length - output[op2++] = commentLength & 0xff; - output[op2++] = (commentLength >> 8) & 0xff; - - // disk number start - output[op2++] = 0; - output[op2++] = 0; - - // internal file attributes - output[op2++] = 0; - output[op2++] = 0; - - // external file attributes - output[op2++] = 0; - output[op2++] = 0; - output[op2++] = 0; - output[op2++] = 0; - - // relative offset of local header - output[op2++] = offset & 0xff; - output[op2++] = (offset >> 8) & 0xff; - output[op2++] = (offset >> 16) & 0xff; - output[op2++] = (offset >> 24) & 0xff; - - // filename - filename = file.option['filename']; - if (filename) { - { - output.set(filename, op1); - output.set(filename, op2); - op1 += filenameLength; - op2 += filenameLength; - } - } - - // extra field - extraField = file.option['extraField']; - if (extraField) { - { - output.set(extraField, op1); - output.set(extraField, op2); - op1 += extraFieldLength; - op2 += extraFieldLength; - } - } - - // comment - comment = file.option['comment']; - if (comment) { - { - output.set(comment, op2); - op2 += commentLength; - } - } - - //------------------------------------------------------------------------- - // file data - //------------------------------------------------------------------------- - - { - output.set(file.buffer, op1); - op1 += file.buffer.length; - } - } - - //------------------------------------------------------------------------- - // end of central directory - //------------------------------------------------------------------------- - - // signature - output[op3++] = Zlib.Zip.CentralDirectorySignature[0]; - output[op3++] = Zlib.Zip.CentralDirectorySignature[1]; - output[op3++] = Zlib.Zip.CentralDirectorySignature[2]; - output[op3++] = Zlib.Zip.CentralDirectorySignature[3]; - - // number of this disk - output[op3++] = 0; - output[op3++] = 0; - - // number of the disk with the start of the central directory - output[op3++] = 0; - output[op3++] = 0; - - // total number of entries in the central directory on this disk - output[op3++] = il & 0xff; - output[op3++] = (il >> 8) & 0xff; - - // total number of entries in the central directory - output[op3++] = il & 0xff; - output[op3++] = (il >> 8) & 0xff; - - // size of the central directory - output[op3++] = centralDirectorySize & 0xff; - output[op3++] = (centralDirectorySize >> 8) & 0xff; - output[op3++] = (centralDirectorySize >> 16) & 0xff; - output[op3++] = (centralDirectorySize >> 24) & 0xff; - - // offset of start of central directory with respect to the starting disk number - output[op3++] = localFileSize & 0xff; - output[op3++] = (localFileSize >> 8) & 0xff; - output[op3++] = (localFileSize >> 16) & 0xff; - output[op3++] = (localFileSize >> 24) & 0xff; - - // .ZIP file comment length - commentLength = this.comment ? this.comment.length : 0; - output[op3++] = commentLength & 0xff; - output[op3++] = (commentLength >> 8) & 0xff; - - // .ZIP file comment - if (this.comment) { - { - output.set(this.comment, op3); - op3 += commentLength; - } - } - - return output; -}; - -/** - * @param {!(Array.|Uint8Array)} input - * @param {Object=} opt_params options. - * @return {!(Array.|Uint8Array)} - */ -Zlib.Zip.prototype.deflateWithOption = function(input, opt_params) { - /** @type {Zlib.RawDeflate} */ - var deflator = new Zlib.RawDeflate(input, opt_params['deflateOption']); - - return deflator.compress(); -}; - -/** - * @param {(Array.|Uint32Array)} key - * @return {number} - */ -Zlib.Zip.prototype.getByte = function(key) { - /** @type {number} */ - var tmp = ((key[2] & 0xffff) | 2); - - return ((tmp * (tmp ^ 1)) >> 8) & 0xff; -}; - -/** - * @param {(Array.|Uint32Array|Object)} key - * @param {number} n - * @return {number} - */ -Zlib.Zip.prototype.encode = function(key, n) { - /** @type {number} */ - var tmp = this.getByte(/** @type {(Array.|Uint32Array)} */(key)); - - this.updateKeys(/** @type {(Array.|Uint32Array)} */(key), n); - - return tmp ^ n; -}; - -/** - * @param {(Array.|Uint32Array)} key - * @param {number} n - */ -Zlib.Zip.prototype.updateKeys = function(key, n) { - key[0] = Zlib.CRC32.single(key[0], n); - key[1] = - (((((key[1] + (key[0] & 0xff)) * 20173 >>> 0) * 6681) >>> 0) + 1) >>> 0; - key[2] = Zlib.CRC32.single(key[2], key[1] >>> 24); -}; - -/** - * @param {(Array.|Uint8Array)} password - * @return {!(Array.|Uint32Array|Object)} - */ -Zlib.Zip.prototype.createEncryptionKey = function(password) { - /** @type {!(Array.|Uint32Array)} */ - var key = [305419896, 591751049, 878082192]; - /** @type {number} */ - var i; - /** @type {number} */ - var il; - - { - key = new Uint32Array(key); - } - - for (i = 0, il = password.length; i < il; ++i) { - this.updateKeys(key, password[i] & 0xff); - } - - return key; -}; - - - -/** - * build huffman table from length list. - * @param {!(Array.|Uint8Array)} lengths length list. - * @return {!Array} huffman table. - */ -Zlib.Huffman.buildHuffmanTable = function(lengths) { - /** @type {number} length list size. */ - var listSize = lengths.length; - /** @type {number} max code length for table size. */ - var maxCodeLength = 0; - /** @type {number} min code length for table size. */ - var minCodeLength = Number.POSITIVE_INFINITY; - /** @type {number} table size. */ - var size; - /** @type {!(Array|Uint8Array)} huffman code table. */ - var table; - /** @type {number} bit length. */ - var bitLength; - /** @type {number} huffman code. */ - var code; - /** - * サイズが 2^maxlength 個のテーブルを埋めるためのスキップ長. - * @type {number} skip length for table filling. - */ - var skip; - /** @type {number} reversed code. */ - var reversed; - /** @type {number} reverse temp. */ - var rtemp; - /** @type {number} loop counter. */ - var i; - /** @type {number} loop limit. */ - var il; - /** @type {number} loop counter. */ - var j; - /** @type {number} table value. */ - var value; - - // Math.max は遅いので最長の値は for-loop で取得する - for (i = 0, il = listSize; i < il; ++i) { - if (lengths[i] > maxCodeLength) { - maxCodeLength = lengths[i]; - } - if (lengths[i] < minCodeLength) { - minCodeLength = lengths[i]; - } - } - - size = 1 << maxCodeLength; - table = new (Uint32Array )(size); - - // ビット長の短い順からハフマン符号を割り当てる - for (bitLength = 1, code = 0, skip = 2; bitLength <= maxCodeLength;) { - for (i = 0; i < listSize; ++i) { - if (lengths[i] === bitLength) { - // ビットオーダーが逆になるためビット長分並びを反転する - for (reversed = 0, rtemp = code, j = 0; j < bitLength; ++j) { - reversed = (reversed << 1) | (rtemp & 1); - rtemp >>= 1; - } - - // 最大ビット長をもとにテーブルを作るため、 - // 最大ビット長以外では 0 / 1 どちらでも良い箇所ができる - // そのどちらでも良い場所は同じ値で埋めることで - // 本来のビット長以上のビット数取得しても問題が起こらないようにする - value = (bitLength << 16) | i; - for (j = reversed; j < size; j += skip) { - table[j] = value; - } - - ++code; - } - } - - // 次のビット長へ - ++bitLength; - code <<= 1; - skip <<= 1; - } - - return [table, maxCodeLength, minCodeLength]; -}; - - - - -//----------------------------------------------------------------------------- - -/** @define {number} buffer block size. */ -var ZLIB_RAW_INFLATE_BUFFER_SIZE = 0x8000; // [ 0x8000 >= ZLIB_BUFFER_BLOCK_SIZE ] - -//----------------------------------------------------------------------------- - - -var buildHuffmanTable = Zlib.Huffman.buildHuffmanTable; - -/** - * @constructor - * @param {!(Uint8Array|Array.)} input input buffer. - * @param {Object} opt_params option parameter. - * - * opt_params は以下のプロパティを指定する事ができます。 - * - index: input buffer の deflate コンテナの開始位置. - * - blockSize: バッファのブロックサイズ. - * - bufferType: Zlib.RawInflate.BufferType の値によってバッファの管理方法を指定する. - * - resize: 確保したバッファが実際の大きさより大きかった場合に切り詰める. - */ -Zlib.RawInflate = function(input, opt_params) { - /** @type {!(Array.|Uint8Array)} inflated buffer */ - this.buffer; - /** @type {!Array.<(Array.|Uint8Array)>} */ - this.blocks = []; - /** @type {number} block size. */ - this.bufferSize = ZLIB_RAW_INFLATE_BUFFER_SIZE; - /** @type {!number} total output buffer pointer. */ - this.totalpos = 0; - /** @type {!number} input buffer pointer. */ - this.ip = 0; - /** @type {!number} bit stream reader buffer. */ - this.bitsbuf = 0; - /** @type {!number} bit stream reader buffer size. */ - this.bitsbuflen = 0; - /** @type {!(Array.|Uint8Array)} input buffer. */ - this.input = new Uint8Array(input) ; - /** @type {!(Uint8Array|Array.)} output buffer. */ - this.output; - /** @type {!number} output buffer pointer. */ - this.op; - /** @type {boolean} is final block flag. */ - this.bfinal = false; - /** @type {Zlib.RawInflate.BufferType} buffer management. */ - this.bufferType = Zlib.RawInflate.BufferType.ADAPTIVE; - /** @type {boolean} resize flag for memory size optimization. */ - this.resize = false; - - // option parameters - if (opt_params || !(opt_params = {})) { - if (opt_params['index']) { - this.ip = opt_params['index']; - } - if (opt_params['bufferSize']) { - this.bufferSize = opt_params['bufferSize']; - } - if (opt_params['bufferType']) { - this.bufferType = opt_params['bufferType']; - } - if (opt_params['resize']) { - this.resize = opt_params['resize']; - } - } - - // initialize - switch (this.bufferType) { - case Zlib.RawInflate.BufferType.BLOCK: - this.op = Zlib.RawInflate.MaxBackwardLength; - this.output = - new (Uint8Array )( - Zlib.RawInflate.MaxBackwardLength + - this.bufferSize + - Zlib.RawInflate.MaxCopyLength - ); - break; - case Zlib.RawInflate.BufferType.ADAPTIVE: - this.op = 0; - this.output = new (Uint8Array )(this.bufferSize); - break; - default: - throw new Error('invalid inflate mode'); - } -}; - -/** - * @enum {number} - */ -Zlib.RawInflate.BufferType = { - BLOCK: 0, - ADAPTIVE: 1 -}; - -/** - * decompress. - * @return {!(Uint8Array|Array.)} inflated buffer. - */ -Zlib.RawInflate.prototype.decompress = function() { - while (!this.bfinal) { - this.parseBlock(); - } - - switch (this.bufferType) { - case Zlib.RawInflate.BufferType.BLOCK: - return this.concatBufferBlock(); - case Zlib.RawInflate.BufferType.ADAPTIVE: - return this.concatBufferDynamic(); - default: - throw new Error('invalid inflate mode'); - } -}; - -/** - * @const - * @type {number} max backward length for LZ77. - */ -Zlib.RawInflate.MaxBackwardLength = 32768; - -/** - * @const - * @type {number} max copy length for LZ77. - */ -Zlib.RawInflate.MaxCopyLength = 258; - -/** - * huffman order - * @const - * @type {!(Array.|Uint8Array)} - */ -Zlib.RawInflate.Order = (function(table) { - return new Uint16Array(table) ; -})([16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15]); - -/** - * huffman length code table. - * @const - * @type {!(Array.|Uint16Array)} - */ -Zlib.RawInflate.LengthCodeTable = (function(table) { - return new Uint16Array(table) ; -})([ - 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, - 0x000d, 0x000f, 0x0011, 0x0013, 0x0017, 0x001b, 0x001f, 0x0023, 0x002b, - 0x0033, 0x003b, 0x0043, 0x0053, 0x0063, 0x0073, 0x0083, 0x00a3, 0x00c3, - 0x00e3, 0x0102, 0x0102, 0x0102 -]); - -/** - * huffman length extra-bits table. - * @const - * @type {!(Array.|Uint8Array)} - */ -Zlib.RawInflate.LengthExtraTable = (function(table) { - return new Uint8Array(table) ; -})([ - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, - 5, 5, 0, 0, 0 -]); - -/** - * huffman dist code table. - * @const - * @type {!(Array.|Uint16Array)} - */ -Zlib.RawInflate.DistCodeTable = (function(table) { - return new Uint16Array(table) ; -})([ - 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0007, 0x0009, 0x000d, 0x0011, - 0x0019, 0x0021, 0x0031, 0x0041, 0x0061, 0x0081, 0x00c1, 0x0101, 0x0181, - 0x0201, 0x0301, 0x0401, 0x0601, 0x0801, 0x0c01, 0x1001, 0x1801, 0x2001, - 0x3001, 0x4001, 0x6001 -]); - -/** - * huffman dist extra-bits table. - * @const - * @type {!(Array.|Uint8Array)} - */ -Zlib.RawInflate.DistExtraTable = (function(table) { - return new Uint8Array(table) ; -})([ - 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, - 11, 12, 12, 13, 13 -]); - -/** - * fixed huffman length code table - * @const - * @type {!Array} - */ -Zlib.RawInflate.FixedLiteralLengthTable = (function(table) { - return table; -})((function() { - var lengths = new (Uint8Array )(288); - var i, il; - - for (i = 0, il = lengths.length; i < il; ++i) { - lengths[i] = - (i <= 143) ? 8 : - (i <= 255) ? 9 : - (i <= 279) ? 7 : - 8; - } - - return buildHuffmanTable(lengths); -})()); - -/** - * fixed huffman distance code table - * @const - * @type {!Array} - */ -Zlib.RawInflate.FixedDistanceTable = (function(table) { - return table; -})((function() { - var lengths = new (Uint8Array )(30); - var i, il; - - for (i = 0, il = lengths.length; i < il; ++i) { - lengths[i] = 5; - } - - return buildHuffmanTable(lengths); -})()); - -/** - * parse deflated block. - */ -Zlib.RawInflate.prototype.parseBlock = function() { - /** @type {number} header */ - var hdr = this.readBits(3); - - // BFINAL - if (hdr & 0x1) { - this.bfinal = true; - } - - // BTYPE - hdr >>>= 1; - switch (hdr) { - // uncompressed - case 0: - this.parseUncompressedBlock(); - break; - // fixed huffman - case 1: - this.parseFixedHuffmanBlock(); - break; - // dynamic huffman - case 2: - this.parseDynamicHuffmanBlock(); - break; - // reserved or other - default: - throw new Error('unknown BTYPE: ' + hdr); - } -}; - -/** - * read inflate bits - * @param {number} length bits length. - * @return {number} read bits. - */ -Zlib.RawInflate.prototype.readBits = function(length) { - var bitsbuf = this.bitsbuf; - var bitsbuflen = this.bitsbuflen; - var input = this.input; - var ip = this.ip; - - /** @type {number} */ - var inputLength = input.length; - /** @type {number} input and output byte. */ - var octet; - - // input byte - if (ip + ((length - bitsbuflen + 7) >> 3) >= inputLength) { - throw new Error('input buffer is broken'); - } - - // not enough buffer - while (bitsbuflen < length) { - bitsbuf |= input[ip++] << bitsbuflen; - bitsbuflen += 8; - } - - // output byte - octet = bitsbuf & /* MASK */ ((1 << length) - 1); - bitsbuf >>>= length; - bitsbuflen -= length; - - this.bitsbuf = bitsbuf; - this.bitsbuflen = bitsbuflen; - this.ip = ip; - - return octet; -}; - -/** - * read huffman code using table - * @param {!(Array.|Uint8Array|Uint16Array)} table huffman code table. - * @return {number} huffman code. - */ -Zlib.RawInflate.prototype.readCodeByTable = function(table) { - var bitsbuf = this.bitsbuf; - var bitsbuflen = this.bitsbuflen; - var input = this.input; - var ip = this.ip; - - /** @type {number} */ - var inputLength = input.length; - /** @type {!(Array.|Uint8Array)} huffman code table */ - var codeTable = table[0]; - /** @type {number} */ - var maxCodeLength = table[1]; - /** @type {number} code length & code (16bit, 16bit) */ - var codeWithLength; - /** @type {number} code bits length */ - var codeLength; - - // not enough buffer - while (bitsbuflen < maxCodeLength) { - if (ip >= inputLength) { - break; - } - bitsbuf |= input[ip++] << bitsbuflen; - bitsbuflen += 8; - } - - // read max length - codeWithLength = codeTable[bitsbuf & ((1 << maxCodeLength) - 1)]; - codeLength = codeWithLength >>> 16; - - if (codeLength > bitsbuflen) { - throw new Error('invalid code length: ' + codeLength); - } - - this.bitsbuf = bitsbuf >> codeLength; - this.bitsbuflen = bitsbuflen - codeLength; - this.ip = ip; - - return codeWithLength & 0xffff; -}; - -/** - * parse uncompressed block. - */ -Zlib.RawInflate.prototype.parseUncompressedBlock = function() { - var input = this.input; - var ip = this.ip; - var output = this.output; - var op = this.op; - - /** @type {number} */ - var inputLength = input.length; - /** @type {number} block length */ - var len; - /** @type {number} number for check block length */ - var nlen; - /** @type {number} output buffer length */ - var olength = output.length; - /** @type {number} copy counter */ - var preCopy; - - // skip buffered header bits - this.bitsbuf = 0; - this.bitsbuflen = 0; - - // len - if (ip + 1 >= inputLength) { - throw new Error('invalid uncompressed block header: LEN'); - } - len = input[ip++] | (input[ip++] << 8); - - // nlen - if (ip + 1 >= inputLength) { - throw new Error('invalid uncompressed block header: NLEN'); - } - nlen = input[ip++] | (input[ip++] << 8); - - // check len & nlen - if (len === ~nlen) { - throw new Error('invalid uncompressed block header: length verify'); - } - - // check size - if (ip + len > input.length) { throw new Error('input buffer is broken'); } - - // expand buffer - switch (this.bufferType) { - case Zlib.RawInflate.BufferType.BLOCK: - // pre copy - while (op + len > output.length) { - preCopy = olength - op; - len -= preCopy; - { - output.set(input.subarray(ip, ip + preCopy), op); - op += preCopy; - ip += preCopy; - } - this.op = op; - output = this.expandBufferBlock(); - op = this.op; - } - break; - case Zlib.RawInflate.BufferType.ADAPTIVE: - while (op + len > output.length) { - output = this.expandBufferAdaptive({fixRatio: 2}); - } - break; - default: - throw new Error('invalid inflate mode'); - } - - // copy - { - output.set(input.subarray(ip, ip + len), op); - op += len; - ip += len; - } - - this.ip = ip; - this.op = op; - this.output = output; -}; - -/** - * parse fixed huffman block. - */ -Zlib.RawInflate.prototype.parseFixedHuffmanBlock = function() { - switch (this.bufferType) { - case Zlib.RawInflate.BufferType.ADAPTIVE: - this.decodeHuffmanAdaptive( - Zlib.RawInflate.FixedLiteralLengthTable, - Zlib.RawInflate.FixedDistanceTable - ); - break; - case Zlib.RawInflate.BufferType.BLOCK: - this.decodeHuffmanBlock( - Zlib.RawInflate.FixedLiteralLengthTable, - Zlib.RawInflate.FixedDistanceTable - ); - break; - default: - throw new Error('invalid inflate mode'); - } -}; - -/** - * parse dynamic huffman block. - */ -Zlib.RawInflate.prototype.parseDynamicHuffmanBlock = function() { - /** @type {number} number of literal and length codes. */ - var hlit = this.readBits(5) + 257; - /** @type {number} number of distance codes. */ - var hdist = this.readBits(5) + 1; - /** @type {number} number of code lengths. */ - var hclen = this.readBits(4) + 4; - /** @type {!(Uint8Array|Array.)} code lengths. */ - var codeLengths = - new (Uint8Array )(Zlib.RawInflate.Order.length); - /** @type {!Array} code lengths table. */ - var codeLengthsTable; - /** @type {!(Uint8Array|Array.)} literal and length code table. */ - var litlenTable; - /** @type {!(Uint8Array|Array.)} distance code table. */ - var distTable; - /** @type {!(Uint8Array|Array.)} code length table. */ - var lengthTable; - /** @type {number} */ - var code; - /** @type {number} */ - var prev; - /** @type {number} */ - var repeat; - /** @type {number} loop counter. */ - var i; - /** @type {number} loop limit. */ - var il; - - // decode code lengths - for (i = 0; i < hclen; ++i) { - codeLengths[Zlib.RawInflate.Order[i]] = this.readBits(3); - } - - // decode length table - codeLengthsTable = buildHuffmanTable(codeLengths); - lengthTable = new (Uint8Array )(hlit + hdist); - for (i = 0, il = hlit + hdist; i < il;) { - code = this.readCodeByTable(codeLengthsTable); - switch (code) { - case 16: - repeat = 3 + this.readBits(2); - while (repeat--) { lengthTable[i++] = prev; } - break; - case 17: - repeat = 3 + this.readBits(3); - while (repeat--) { lengthTable[i++] = 0; } - prev = 0; - break; - case 18: - repeat = 11 + this.readBits(7); - while (repeat--) { lengthTable[i++] = 0; } - prev = 0; - break; - default: - lengthTable[i++] = code; - prev = code; - break; - } - } - - litlenTable = buildHuffmanTable(lengthTable.subarray(0, hlit)) - ; - distTable = buildHuffmanTable(lengthTable.subarray(hlit)) - ; - - switch (this.bufferType) { - case Zlib.RawInflate.BufferType.ADAPTIVE: - this.decodeHuffmanAdaptive(litlenTable, distTable); - break; - case Zlib.RawInflate.BufferType.BLOCK: - this.decodeHuffmanBlock(litlenTable, distTable); - break; - default: - throw new Error('invalid inflate mode'); - } -}; - -/** - * decode huffman code - * @param {!(Array.|Uint16Array)} litlen literal and length code table. - * @param {!(Array.|Uint8Array)} dist distination code table. - */ -Zlib.RawInflate.prototype.decodeHuffmanBlock = function(litlen, dist) { - var output = this.output; - var op = this.op; - - this.currentLitlenTable = litlen; - - /** @type {number} output position limit. */ - var olength = output.length - Zlib.RawInflate.MaxCopyLength; - /** @type {number} huffman code. */ - var code; - /** @type {number} table index. */ - var ti; - /** @type {number} huffman code distination. */ - var codeDist; - /** @type {number} huffman code length. */ - var codeLength; - - var lengthCodeTable = Zlib.RawInflate.LengthCodeTable; - var lengthExtraTable = Zlib.RawInflate.LengthExtraTable; - var distCodeTable = Zlib.RawInflate.DistCodeTable; - var distExtraTable = Zlib.RawInflate.DistExtraTable; - - while ((code = this.readCodeByTable(litlen)) !== 256) { - // literal - if (code < 256) { - if (op >= olength) { - this.op = op; - output = this.expandBufferBlock(); - op = this.op; - } - output[op++] = code; - - continue; - } - - // length code - ti = code - 257; - codeLength = lengthCodeTable[ti]; - if (lengthExtraTable[ti] > 0) { - codeLength += this.readBits(lengthExtraTable[ti]); - } - - // dist code - code = this.readCodeByTable(dist); - codeDist = distCodeTable[code]; - if (distExtraTable[code] > 0) { - codeDist += this.readBits(distExtraTable[code]); - } - - // lz77 decode - if (op >= olength) { - this.op = op; - output = this.expandBufferBlock(); - op = this.op; - } - while (codeLength--) { - output[op] = output[(op++) - codeDist]; - } - } - - while (this.bitsbuflen >= 8) { - this.bitsbuflen -= 8; - this.ip--; - } - this.op = op; -}; - -/** - * decode huffman code (adaptive) - * @param {!(Array.|Uint16Array)} litlen literal and length code table. - * @param {!(Array.|Uint8Array)} dist distination code table. - */ -Zlib.RawInflate.prototype.decodeHuffmanAdaptive = function(litlen, dist) { - var output = this.output; - var op = this.op; - - this.currentLitlenTable = litlen; - - /** @type {number} output position limit. */ - var olength = output.length; - /** @type {number} huffman code. */ - var code; - /** @type {number} table index. */ - var ti; - /** @type {number} huffman code distination. */ - var codeDist; - /** @type {number} huffman code length. */ - var codeLength; - - var lengthCodeTable = Zlib.RawInflate.LengthCodeTable; - var lengthExtraTable = Zlib.RawInflate.LengthExtraTable; - var distCodeTable = Zlib.RawInflate.DistCodeTable; - var distExtraTable = Zlib.RawInflate.DistExtraTable; - - while ((code = this.readCodeByTable(litlen)) !== 256) { - // literal - if (code < 256) { - if (op >= olength) { - output = this.expandBufferAdaptive(); - olength = output.length; - } - output[op++] = code; - - continue; - } - - // length code - ti = code - 257; - codeLength = lengthCodeTable[ti]; - if (lengthExtraTable[ti] > 0) { - codeLength += this.readBits(lengthExtraTable[ti]); - } - - // dist code - code = this.readCodeByTable(dist); - codeDist = distCodeTable[code]; - if (distExtraTable[code] > 0) { - codeDist += this.readBits(distExtraTable[code]); - } - - // lz77 decode - if (op + codeLength > olength) { - output = this.expandBufferAdaptive(); - olength = output.length; - } - while (codeLength--) { - output[op] = output[(op++) - codeDist]; - } - } - - while (this.bitsbuflen >= 8) { - this.bitsbuflen -= 8; - this.ip--; - } - this.op = op; -}; - -/** - * expand output buffer. - * @param {Object=} opt_param option parameters. - * @return {!(Array.|Uint8Array)} output buffer. - */ -Zlib.RawInflate.prototype.expandBufferBlock = function(opt_param) { - /** @type {!(Array.|Uint8Array)} store buffer. */ - var buffer = - new (Uint8Array )( - this.op - Zlib.RawInflate.MaxBackwardLength - ); - /** @type {number} backward base point */ - var backward = this.op - Zlib.RawInflate.MaxBackwardLength; - - var output = this.output; - - // copy to output buffer - { - buffer.set(output.subarray(Zlib.RawInflate.MaxBackwardLength, buffer.length)); - } - - this.blocks.push(buffer); - this.totalpos += buffer.length; - - // copy to backward buffer - { - output.set( - output.subarray(backward, backward + Zlib.RawInflate.MaxBackwardLength) - ); - } - - this.op = Zlib.RawInflate.MaxBackwardLength; - - return output; -}; - -/** - * expand output buffer. (adaptive) - * @param {Object=} opt_param option parameters. - * @return {!(Array.|Uint8Array)} output buffer pointer. - */ -Zlib.RawInflate.prototype.expandBufferAdaptive = function(opt_param) { - /** @type {!(Array.|Uint8Array)} store buffer. */ - var buffer; - /** @type {number} expantion ratio. */ - var ratio = (this.input.length / this.ip + 1) | 0; - /** @type {number} maximum number of huffman code. */ - var maxHuffCode; - /** @type {number} new output buffer size. */ - var newSize; - /** @type {number} max inflate size. */ - var maxInflateSize; - - var input = this.input; - var output = this.output; - - if (opt_param) { - if (typeof opt_param.fixRatio === 'number') { - ratio = opt_param.fixRatio; - } - if (typeof opt_param.addRatio === 'number') { - ratio += opt_param.addRatio; - } - } - - // calculate new buffer size - if (ratio < 2) { - maxHuffCode = - (input.length - this.ip) / this.currentLitlenTable[2]; - maxInflateSize = (maxHuffCode / 2 * 258) | 0; - newSize = maxInflateSize < output.length ? - output.length + maxInflateSize : - output.length << 1; - } else { - newSize = output.length * ratio; - } - - // buffer expantion - { - buffer = new Uint8Array(newSize); - buffer.set(output); - } - - this.output = buffer; - - return this.output; -}; - -/** - * concat output buffer. - * @return {!(Array.|Uint8Array)} output buffer. - */ -Zlib.RawInflate.prototype.concatBufferBlock = function() { - /** @type {number} buffer pointer. */ - var pos = 0; - /** @type {number} buffer pointer. */ - var limit = this.totalpos + (this.op - Zlib.RawInflate.MaxBackwardLength); - /** @type {!(Array.|Uint8Array)} output block array. */ - var output = this.output; - /** @type {!Array} blocks array. */ - var blocks = this.blocks; - /** @type {!(Array.|Uint8Array)} output block array. */ - var block; - /** @type {!(Array.|Uint8Array)} output buffer. */ - var buffer = new (Uint8Array )(limit); - /** @type {number} loop counter. */ - var i; - /** @type {number} loop limiter. */ - var il; - /** @type {number} loop counter. */ - var j; - /** @type {number} loop limiter. */ - var jl; - - // single buffer - if (blocks.length === 0) { - return this.output.subarray(Zlib.RawInflate.MaxBackwardLength, this.op) ; - } - - // copy to buffer - for (i = 0, il = blocks.length; i < il; ++i) { - block = blocks[i]; - for (j = 0, jl = block.length; j < jl; ++j) { - buffer[pos++] = block[j]; - } - } - - // current buffer - for (i = Zlib.RawInflate.MaxBackwardLength, il = this.op; i < il; ++i) { - buffer[pos++] = output[i]; - } - - this.blocks = []; - this.buffer = buffer; - - return this.buffer; -}; - -/** - * concat output buffer. (dynamic) - * @return {!(Array.|Uint8Array)} output buffer. - */ -Zlib.RawInflate.prototype.concatBufferDynamic = function() { - /** @type {Array.|Uint8Array} output buffer. */ - var buffer; - var op = this.op; - - { - if (this.resize) { - buffer = new Uint8Array(op); - buffer.set(this.output.subarray(0, op)); - } else { - buffer = this.output.subarray(0, op); - } - } - - this.buffer = buffer; - - return this.buffer; -}; - - - - -var buildHuffmanTable = Zlib.Huffman.buildHuffmanTable; - -/** - * @param {!(Uint8Array|Array.)} input input buffer. - * @param {number} ip input buffer pointer. - * @param {number=} opt_buffersize buffer block size. - * @constructor - */ -Zlib.RawInflateStream = function(input, ip, opt_buffersize) { - /** @type {!Array.<(Array|Uint8Array)>} */ - this.blocks = []; - /** @type {number} block size. */ - this.bufferSize = - opt_buffersize ? opt_buffersize : ZLIB_STREAM_RAW_INFLATE_BUFFER_SIZE; - /** @type {!number} total output buffer pointer. */ - this.totalpos = 0; - /** @type {!number} input buffer pointer. */ - this.ip = ip === void 0 ? 0 : ip; - /** @type {!number} bit stream reader buffer. */ - this.bitsbuf = 0; - /** @type {!number} bit stream reader buffer size. */ - this.bitsbuflen = 0; - /** @type {!(Array|Uint8Array)} input buffer. */ - this.input = new Uint8Array(input) ; - /** @type {!(Uint8Array|Array)} output buffer. */ - this.output = new (Uint8Array )(this.bufferSize); - /** @type {!number} output buffer pointer. */ - this.op = 0; - /** @type {boolean} is final block flag. */ - this.bfinal = false; - /** @type {number} uncompressed block length. */ - this.blockLength; - /** @type {boolean} resize flag for memory size optimization. */ - this.resize = false; - /** @type {Array} */ - this.litlenTable; - /** @type {Array} */ - this.distTable; - /** @type {number} */ - this.sp = 0; // stream pointer - /** @type {Zlib.RawInflateStream.Status} */ - this.status = Zlib.RawInflateStream.Status.INITIALIZED; - - // - // backup - // - /** @type {!number} */ - this.ip_; - /** @type {!number} */ - this.bitsbuflen_; - /** @type {!number} */ - this.bitsbuf_; -}; - -/** - * @enum {number} - */ -Zlib.RawInflateStream.BlockType = { - UNCOMPRESSED: 0, - FIXED: 1, - DYNAMIC: 2 -}; - -/** - * @enum {number} - */ -Zlib.RawInflateStream.Status = { - INITIALIZED: 0, - BLOCK_HEADER_START: 1, - BLOCK_HEADER_END: 2, - BLOCK_BODY_START: 3, - BLOCK_BODY_END: 4, - DECODE_BLOCK_START: 5, - DECODE_BLOCK_END: 6 -}; - -/** - * decompress. - * @return {!(Uint8Array|Array)} inflated buffer. - */ -Zlib.RawInflateStream.prototype.decompress = function(newInput, ip) { - /** @type {boolean} */ - var stop = false; - - if (newInput !== void 0) { - this.input = newInput; - } - - if (ip !== void 0) { - this.ip = ip; - } - - // decompress - while (!stop) { - switch (this.status) { - // block header - case Zlib.RawInflateStream.Status.INITIALIZED: - case Zlib.RawInflateStream.Status.BLOCK_HEADER_START: - if (this.readBlockHeader() < 0) { - stop = true; - } - break; - // block body - case Zlib.RawInflateStream.Status.BLOCK_HEADER_END: /* FALLTHROUGH */ - case Zlib.RawInflateStream.Status.BLOCK_BODY_START: - switch(this.currentBlockType) { - case Zlib.RawInflateStream.BlockType.UNCOMPRESSED: - if (this.readUncompressedBlockHeader() < 0) { - stop = true; - } - break; - case Zlib.RawInflateStream.BlockType.FIXED: - if (this.parseFixedHuffmanBlock() < 0) { - stop = true; - } - break; - case Zlib.RawInflateStream.BlockType.DYNAMIC: - if (this.parseDynamicHuffmanBlock() < 0) { - stop = true; - } - break; - } - break; - // decode data - case Zlib.RawInflateStream.Status.BLOCK_BODY_END: - case Zlib.RawInflateStream.Status.DECODE_BLOCK_START: - switch(this.currentBlockType) { - case Zlib.RawInflateStream.BlockType.UNCOMPRESSED: - if (this.parseUncompressedBlock() < 0) { - stop = true; - } - break; - case Zlib.RawInflateStream.BlockType.FIXED: /* FALLTHROUGH */ - case Zlib.RawInflateStream.BlockType.DYNAMIC: - if (this.decodeHuffman() < 0) { - stop = true; - } - break; - } - break; - case Zlib.RawInflateStream.Status.DECODE_BLOCK_END: - if (this.bfinal) { - stop = true; - } else { - this.status = Zlib.RawInflateStream.Status.INITIALIZED; - } - break; - } - } - - return this.concatBuffer(); -}; - -/** - * @const - * @type {number} max backward length for LZ77. - */ -Zlib.RawInflateStream.MaxBackwardLength = 32768; - -/** - * @const - * @type {number} max copy length for LZ77. - */ -Zlib.RawInflateStream.MaxCopyLength = 258; - -/** - * huffman order - * @const - * @type {!(Array.|Uint8Array)} - */ -Zlib.RawInflateStream.Order = (function(table) { - return new Uint16Array(table) ; -})([16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15]); - -/** - * huffman length code table. - * @const - * @type {!(Array.|Uint16Array)} - */ -Zlib.RawInflateStream.LengthCodeTable = (function(table) { - return new Uint16Array(table) ; -})([ - 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, - 0x000d, 0x000f, 0x0011, 0x0013, 0x0017, 0x001b, 0x001f, 0x0023, 0x002b, - 0x0033, 0x003b, 0x0043, 0x0053, 0x0063, 0x0073, 0x0083, 0x00a3, 0x00c3, - 0x00e3, 0x0102, 0x0102, 0x0102 -]); - -/** - * huffman length extra-bits table. - * @const - * @type {!(Array.|Uint8Array)} - */ -Zlib.RawInflateStream.LengthExtraTable = (function(table) { - return new Uint8Array(table) ; -})([ - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, - 5, 5, 0, 0, 0 -]); - -/** - * huffman dist code table. - * @const - * @type {!(Array.|Uint16Array)} - */ -Zlib.RawInflateStream.DistCodeTable = (function(table) { - return new Uint16Array(table) ; -})([ - 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0007, 0x0009, 0x000d, 0x0011, - 0x0019, 0x0021, 0x0031, 0x0041, 0x0061, 0x0081, 0x00c1, 0x0101, 0x0181, - 0x0201, 0x0301, 0x0401, 0x0601, 0x0801, 0x0c01, 0x1001, 0x1801, 0x2001, - 0x3001, 0x4001, 0x6001 -]); - -/** - * huffman dist extra-bits table. - * @const - * @type {!(Array.|Uint8Array)} - */ -Zlib.RawInflateStream.DistExtraTable = (function(table) { - return new Uint8Array(table) ; -})([ - 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, - 11, 12, 12, 13, 13 -]); - -/** - * fixed huffman length code table - * @const - * @type {!Array} - */ -Zlib.RawInflateStream.FixedLiteralLengthTable = (function(table) { - return table; -})((function() { - var lengths = new (Uint8Array )(288); - var i, il; - - for (i = 0, il = lengths.length; i < il; ++i) { - lengths[i] = - (i <= 143) ? 8 : - (i <= 255) ? 9 : - (i <= 279) ? 7 : - 8; - } - - return buildHuffmanTable(lengths); -})()); - -/** - * fixed huffman distance code table - * @const - * @type {!Array} - */ -Zlib.RawInflateStream.FixedDistanceTable = (function(table) { - return table; -})((function() { - var lengths = new (Uint8Array )(30); - var i, il; - - for (i = 0, il = lengths.length; i < il; ++i) { - lengths[i] = 5; - } - - return buildHuffmanTable(lengths); -})()); - -/** - * parse deflated block. - */ -Zlib.RawInflateStream.prototype.readBlockHeader = function() { - /** @type {number} header */ - var hdr; - - this.status = Zlib.RawInflateStream.Status.BLOCK_HEADER_START; - - this.save_(); - if ((hdr = this.readBits(3)) < 0) { - this.restore_(); - return -1; - } - - // BFINAL - if (hdr & 0x1) { - this.bfinal = true; - } - - // BTYPE - hdr >>>= 1; - switch (hdr) { - case 0: // uncompressed - this.currentBlockType = Zlib.RawInflateStream.BlockType.UNCOMPRESSED; - break; - case 1: // fixed huffman - this.currentBlockType = Zlib.RawInflateStream.BlockType.FIXED; - break; - case 2: // dynamic huffman - this.currentBlockType = Zlib.RawInflateStream.BlockType.DYNAMIC; - break; - default: // reserved or other - throw new Error('unknown BTYPE: ' + hdr); - } - - this.status = Zlib.RawInflateStream.Status.BLOCK_HEADER_END; -}; - -/** - * read inflate bits - * @param {number} length bits length. - * @return {number} read bits. - */ -Zlib.RawInflateStream.prototype.readBits = function(length) { - var bitsbuf = this.bitsbuf; - var bitsbuflen = this.bitsbuflen; - var input = this.input; - var ip = this.ip; - - /** @type {number} input and output byte. */ - var octet; - - // not enough buffer - while (bitsbuflen < length) { - // input byte - if (input.length <= ip) { - return -1; - } - octet = input[ip++]; - - // concat octet - bitsbuf |= octet << bitsbuflen; - bitsbuflen += 8; - } - - // output byte - octet = bitsbuf & /* MASK */ ((1 << length) - 1); - bitsbuf >>>= length; - bitsbuflen -= length; - - this.bitsbuf = bitsbuf; - this.bitsbuflen = bitsbuflen; - this.ip = ip; - - return octet; -}; - -/** - * read huffman code using table - * @param {Array} table huffman code table. - * @return {number} huffman code. - */ -Zlib.RawInflateStream.prototype.readCodeByTable = function(table) { - var bitsbuf = this.bitsbuf; - var bitsbuflen = this.bitsbuflen; - var input = this.input; - var ip = this.ip; - - /** @type {!(Array|Uint8Array)} huffman code table */ - var codeTable = table[0]; - /** @type {number} */ - var maxCodeLength = table[1]; - /** @type {number} input byte */ - var octet; - /** @type {number} code length & code (16bit, 16bit) */ - var codeWithLength; - /** @type {number} code bits length */ - var codeLength; - - // not enough buffer - while (bitsbuflen < maxCodeLength) { - if (input.length <= ip) { - return -1; - } - octet = input[ip++]; - bitsbuf |= octet << bitsbuflen; - bitsbuflen += 8; - } - - // read max length - codeWithLength = codeTable[bitsbuf & ((1 << maxCodeLength) - 1)]; - codeLength = codeWithLength >>> 16; - - if (codeLength > bitsbuflen) { - throw new Error('invalid code length: ' + codeLength); - } - - this.bitsbuf = bitsbuf >> codeLength; - this.bitsbuflen = bitsbuflen - codeLength; - this.ip = ip; - - return codeWithLength & 0xffff; -}; - -/** - * read uncompressed block header - */ -Zlib.RawInflateStream.prototype.readUncompressedBlockHeader = function() { - /** @type {number} block length */ - var len; - /** @type {number} number for check block length */ - var nlen; - - var input = this.input; - var ip = this.ip; - - this.status = Zlib.RawInflateStream.Status.BLOCK_BODY_START; - - if (ip + 4 >= input.length) { - return -1; - } - - len = input[ip++] | (input[ip++] << 8); - nlen = input[ip++] | (input[ip++] << 8); - - // check len & nlen - if (len === ~nlen) { - throw new Error('invalid uncompressed block header: length verify'); - } - - // skip buffered header bits - this.bitsbuf = 0; - this.bitsbuflen = 0; - - this.ip = ip; - this.blockLength = len; - this.status = Zlib.RawInflateStream.Status.BLOCK_BODY_END; -}; - -/** - * parse uncompressed block. - */ -Zlib.RawInflateStream.prototype.parseUncompressedBlock = function() { - var input = this.input; - var ip = this.ip; - var output = this.output; - var op = this.op; - var len = this.blockLength; - - this.status = Zlib.RawInflateStream.Status.DECODE_BLOCK_START; - - // copy - // XXX: とりあえず素直にコピー - while (len--) { - if (op === output.length) { - output = this.expandBuffer({fixRatio: 2}); - } - - // not enough input buffer - if (ip >= input.length) { - this.ip = ip; - this.op = op; - this.blockLength = len + 1; // コピーしてないので戻す - return -1; - } - - output[op++] = input[ip++]; - } - - if (len < 0) { - this.status = Zlib.RawInflateStream.Status.DECODE_BLOCK_END; - } - - this.ip = ip; - this.op = op; - - return 0; -}; - -/** - * parse fixed huffman block. - */ -Zlib.RawInflateStream.prototype.parseFixedHuffmanBlock = function() { - this.status = Zlib.RawInflateStream.Status.BLOCK_BODY_START; - - this.litlenTable = Zlib.RawInflateStream.FixedLiteralLengthTable; - this.distTable = Zlib.RawInflateStream.FixedDistanceTable; - - this.status = Zlib.RawInflateStream.Status.BLOCK_BODY_END; - - return 0; -}; - -/** - * オブジェクトのコンテキストを別のプロパティに退避する. - * @private - */ -Zlib.RawInflateStream.prototype.save_ = function() { - this.ip_ = this.ip; - this.bitsbuflen_ = this.bitsbuflen; - this.bitsbuf_ = this.bitsbuf; -}; - -/** - * 別のプロパティに退避したコンテキストを復元する. - * @private - */ -Zlib.RawInflateStream.prototype.restore_ = function() { - this.ip = this.ip_; - this.bitsbuflen = this.bitsbuflen_; - this.bitsbuf = this.bitsbuf_; -}; - -/** - * parse dynamic huffman block. - */ -Zlib.RawInflateStream.prototype.parseDynamicHuffmanBlock = function() { - /** @type {number} number of literal and length codes. */ - var hlit; - /** @type {number} number of distance codes. */ - var hdist; - /** @type {number} number of code lengths. */ - var hclen; - /** @type {!(Uint8Array|Array)} code lengths. */ - var codeLengths = - new (Uint8Array )(Zlib.RawInflateStream.Order.length); - /** @type {!Array} code lengths table. */ - var codeLengthsTable; - - this.status = Zlib.RawInflateStream.Status.BLOCK_BODY_START; - - this.save_(); - hlit = this.readBits(5) + 257; - hdist = this.readBits(5) + 1; - hclen = this.readBits(4) + 4; - if (hlit < 0 || hdist < 0 || hclen < 0) { - this.restore_(); - return -1; - } - - try { - parseDynamicHuffmanBlockImpl.call(this); - } catch(e) { - this.restore_(); - return -1; - } - - function parseDynamicHuffmanBlockImpl() { - /** @type {number} */ - var bits; - var code; - var prev = 0; - var repeat; - /** @type {!(Uint8Array|Array.)} code length table. */ - var lengthTable; - /** @type {number} loop counter. */ - var i; - /** @type {number} loop limit. */ - var il; - - // decode code lengths - for (i = 0; i < hclen; ++i) { - if ((bits = this.readBits(3)) < 0) { - throw new Error('not enough input'); - } - codeLengths[Zlib.RawInflateStream.Order[i]] = bits; - } - - // decode length table - codeLengthsTable = buildHuffmanTable(codeLengths); - lengthTable = new (Uint8Array )(hlit + hdist); - for (i = 0, il = hlit + hdist; i < il;) { - code = this.readCodeByTable(codeLengthsTable); - if (code < 0) { - throw new Error('not enough input'); - } - switch (code) { - case 16: - if ((bits = this.readBits(2)) < 0) { - throw new Error('not enough input'); - } - repeat = 3 + bits; - while (repeat--) { lengthTable[i++] = prev; } - break; - case 17: - if ((bits = this.readBits(3)) < 0) { - throw new Error('not enough input'); - } - repeat = 3 + bits; - while (repeat--) { lengthTable[i++] = 0; } - prev = 0; - break; - case 18: - if ((bits = this.readBits(7)) < 0) { - throw new Error('not enough input'); - } - repeat = 11 + bits; - while (repeat--) { lengthTable[i++] = 0; } - prev = 0; - break; - default: - lengthTable[i++] = code; - prev = code; - break; - } - } - - this.litlenTable = buildHuffmanTable(lengthTable.subarray(0, hlit)) - ; - this.distTable = buildHuffmanTable(lengthTable.subarray(hlit)) - ; - } - - this.status = Zlib.RawInflateStream.Status.BLOCK_BODY_END; - - return 0; -}; - -/** - * decode huffman code (dynamic) - * @return {(number|undefined)} -1 is error. - */ -Zlib.RawInflateStream.prototype.decodeHuffman = function() { - var output = this.output; - var op = this.op; - - /** @type {number} huffman code. */ - var code; - /** @type {number} table index. */ - var ti; - /** @type {number} huffman code distination. */ - var codeDist; - /** @type {number} huffman code length. */ - var codeLength; - - var litlen = this.litlenTable; - var dist = this.distTable; - - var olength = output.length; - var bits; - - this.status = Zlib.RawInflateStream.Status.DECODE_BLOCK_START; - - while (true) { - this.save_(); - - code = this.readCodeByTable(litlen); - if (code < 0) { - this.op = op; - this.restore_(); - return -1; - } - - if (code === 256) { - break; - } - - // literal - if (code < 256) { - if (op === olength) { - output = this.expandBuffer(); - olength = output.length; - } - output[op++] = code; - - continue; - } - - // length code - ti = code - 257; - codeLength = Zlib.RawInflateStream.LengthCodeTable[ti]; - if (Zlib.RawInflateStream.LengthExtraTable[ti] > 0) { - bits = this.readBits(Zlib.RawInflateStream.LengthExtraTable[ti]); - if (bits < 0) { - this.op = op; - this.restore_(); - return -1; - } - codeLength += bits; - } - - // dist code - code = this.readCodeByTable(dist); - if (code < 0) { - this.op = op; - this.restore_(); - return -1; - } - codeDist = Zlib.RawInflateStream.DistCodeTable[code]; - if (Zlib.RawInflateStream.DistExtraTable[code] > 0) { - bits = this.readBits(Zlib.RawInflateStream.DistExtraTable[code]); - if (bits < 0) { - this.op = op; - this.restore_(); - return -1; - } - codeDist += bits; - } - - // lz77 decode - if (op + codeLength >= olength) { - output = this.expandBuffer(); - olength = output.length; - } - - while (codeLength--) { - output[op] = output[(op++) - codeDist]; - } - - // break - if (this.ip === this.input.length) { - this.op = op; - return -1; - } - } - - while (this.bitsbuflen >= 8) { - this.bitsbuflen -= 8; - this.ip--; - } - - this.op = op; - this.status = Zlib.RawInflateStream.Status.DECODE_BLOCK_END; -}; - -/** - * expand output buffer. (dynamic) - * @param {Object=} opt_param option parameters. - * @return {!(Array|Uint8Array)} output buffer pointer. - */ -Zlib.RawInflateStream.prototype.expandBuffer = function(opt_param) { - /** @type {!(Array|Uint8Array)} store buffer. */ - var buffer; - /** @type {number} expantion ratio. */ - var ratio = (this.input.length / this.ip + 1) | 0; - /** @type {number} maximum number of huffman code. */ - var maxHuffCode; - /** @type {number} new output buffer size. */ - var newSize; - /** @type {number} max inflate size. */ - var maxInflateSize; - - var input = this.input; - var output = this.output; - - if (opt_param) { - if (typeof opt_param.fixRatio === 'number') { - ratio = opt_param.fixRatio; - } - if (typeof opt_param.addRatio === 'number') { - ratio += opt_param.addRatio; - } - } - - // calculate new buffer size - if (ratio < 2) { - maxHuffCode = - (input.length - this.ip) / this.litlenTable[2]; - maxInflateSize = (maxHuffCode / 2 * 258) | 0; - newSize = maxInflateSize < output.length ? - output.length + maxInflateSize : - output.length << 1; - } else { - newSize = output.length * ratio; - } - - // buffer expantion - { - buffer = new Uint8Array(newSize); - buffer.set(output); - } - - this.output = buffer; - - return this.output; -}; - -/** - * concat output buffer. (dynamic) - * @return {!(Array|Uint8Array)} output buffer. - */ -Zlib.RawInflateStream.prototype.concatBuffer = function() { - /** @type {!(Array|Uint8Array)} output buffer. */ - var buffer; - /** @type {number} */ - var op = this.op; - /** @type {Uint8Array} */ - var tmp; - - if (this.resize) { - { - buffer = new Uint8Array(this.output.subarray(this.sp, op)); - } - } else { - buffer = - this.output.subarray(this.sp, op) ; - } - - this.sp = op; - - // compaction - if (op > Zlib.RawInflateStream.MaxBackwardLength + this.bufferSize) { - this.op = this.sp = Zlib.RawInflateStream.MaxBackwardLength; - { - tmp = /** @type {Uint8Array} */(this.output); - this.output = new Uint8Array(this.bufferSize + Zlib.RawInflateStream.MaxBackwardLength); - this.output.set(tmp.subarray(op - Zlib.RawInflateStream.MaxBackwardLength, op)); - } - } - - return buffer; -}; - - -/** - * @constructor - * @param {!(Uint8Array|Array)} input deflated buffer. - * @param {Object=} opt_params option parameters. - * - * opt_params は以下のプロパティを指定する事ができます。 - * - index: input buffer の deflate コンテナの開始位置. - * - blockSize: バッファのブロックサイズ. - * - verify: 伸張が終わった後 adler-32 checksum の検証を行うか. - * - bufferType: Zlib.Inflate.BufferType の値によってバッファの管理方法を指定する. - * Zlib.Inflate.BufferType は Zlib.RawInflate.BufferType のエイリアス. - */ -Zlib.Inflate = function(input, opt_params) { - /** @type {number} */ - var cmf; - /** @type {number} */ - var flg; - - /** @type {!(Uint8Array|Array)} */ - this.input = input; - /** @type {number} */ - this.ip = 0; - /** @type {Zlib.RawInflate} */ - this.rawinflate; - /** @type {(boolean|undefined)} verify flag. */ - this.verify; - - // option parameters - if (opt_params || !(opt_params = {})) { - if (opt_params['index']) { - this.ip = opt_params['index']; - } - if (opt_params['verify']) { - this.verify = opt_params['verify']; - } - } - - // Compression Method and Flags - cmf = input[this.ip++]; - flg = input[this.ip++]; - - // compression method - switch (cmf & 0x0f) { - case Zlib.CompressionMethod.DEFLATE: - this.method = Zlib.CompressionMethod.DEFLATE; - break; - default: - throw new Error('unsupported compression method'); - } - - // fcheck - if (((cmf << 8) + flg) % 31 !== 0) { - throw new Error('invalid fcheck flag:' + ((cmf << 8) + flg) % 31); - } - - // fdict (not supported) - if (flg & 0x20) { - throw new Error('fdict flag is not supported'); - } - - // RawInflate - this.rawinflate = new Zlib.RawInflate(input, { - 'index': this.ip, - 'bufferSize': opt_params['bufferSize'], - 'bufferType': opt_params['bufferType'], - 'resize': opt_params['resize'] - }); -}; - -/** - * @enum {number} - */ -Zlib.Inflate.BufferType = Zlib.RawInflate.BufferType; - -/** - * decompress. - * @return {!(Uint8Array|Array)} inflated buffer. - */ -Zlib.Inflate.prototype.decompress = function() { - /** @type {!(Array|Uint8Array)} input buffer. */ - var input = this.input; - /** @type {!(Uint8Array|Array)} inflated buffer. */ - var buffer; - /** @type {number} adler-32 checksum */ - var adler32; - - buffer = this.rawinflate.decompress(); - this.ip = this.rawinflate.ip; - - // verify adler-32 - if (this.verify) { - adler32 = ( - input[this.ip++] << 24 | input[this.ip++] << 16 | - input[this.ip++] << 8 | input[this.ip++] - ) >>> 0; - - if (adler32 !== Zlib.Adler32(buffer)) { - throw new Error('invalid adler-32 checksum'); - } - } - - return buffer; -}; - - -/* vim:set expandtab ts=2 sw=2 tw=80: */ - - -/** - * @param {!(Uint8Array|Array)} input deflated buffer. - * @constructor - */ -Zlib.InflateStream = function(input) { - /** @type {!(Uint8Array|Array)} */ - this.input = input === void 0 ? new (Uint8Array )() : input; - /** @type {number} */ - this.ip = 0; - /** @type {Zlib.RawInflateStream} */ - this.rawinflate = new Zlib.RawInflateStream(this.input, this.ip); - /** @type {Zlib.CompressionMethod} */ - this.method; - /** @type {!(Array|Uint8Array)} */ - this.output = this.rawinflate.output; -}; - -/** - * decompress. - * @return {!(Uint8Array|Array)} inflated buffer. - */ -Zlib.InflateStream.prototype.decompress = function(input) { - /** @type {!(Uint8Array|Array)} inflated buffer. */ - var buffer; - - // 新しい入力を入力バッファに結合する - // XXX Array, Uint8Array のチェックを行うか確認する - if (input !== void 0) { - { - var tmp = new Uint8Array(this.input.length + input.length); - tmp.set(this.input, 0); - tmp.set(input, this.input.length); - this.input = tmp; - } - } - - if (this.method === void 0) { - if(this.readHeader() < 0) { - return new (Uint8Array )(); - } - } - - buffer = this.rawinflate.decompress(this.input, this.ip); - if (this.rawinflate.ip !== 0) { - this.input = this.input.subarray(this.rawinflate.ip) ; - this.ip = 0; - } - - // verify adler-32 - /* - if (this.verify) { - adler32 = - input[this.ip++] << 24 | input[this.ip++] << 16 | - input[this.ip++] << 8 | input[this.ip++]; - - if (adler32 !== Zlib.Adler32(buffer)) { - throw new Error('invalid adler-32 checksum'); - } - } - */ - - return buffer; -}; - -Zlib.InflateStream.prototype.readHeader = function() { - var ip = this.ip; - var input = this.input; - - // Compression Method and Flags - var cmf = input[ip++]; - var flg = input[ip++]; - - if (cmf === void 0 || flg === void 0) { - return -1; - } - - // compression method - switch (cmf & 0x0f) { - case Zlib.CompressionMethod.DEFLATE: - this.method = Zlib.CompressionMethod.DEFLATE; - break; - default: - throw new Error('unsupported compression method'); - } - - // fcheck - if (((cmf << 8) + flg) % 31 !== 0) { - throw new Error('invalid fcheck flag:' + ((cmf << 8) + flg) % 31); - } - - // fdict (not supported) - if (flg & 0x20) { - throw new Error('fdict flag is not supported'); - } - - this.ip = ip; -}; - - -/** - * @fileoverview GZIP (RFC1952) 展開コンテナ実装. - */ - -/** - * @constructor - * @param {!(Array|Uint8Array)} input input buffer. - * @param {Object=} opt_params option parameters. - */ -Zlib.Gunzip = function(input, opt_params) { - /** @type {!(Array.|Uint8Array)} input buffer. */ - this.input = input; - /** @type {number} input buffer pointer. */ - this.ip = 0; - /** @type {Array.} */ - this.member = []; - /** @type {boolean} */ - this.decompressed = false; -}; - -/** - * @return {Array.} - */ -Zlib.Gunzip.prototype.getMembers = function() { - if (!this.decompressed) { - this.decompress(); - } - - return this.member.slice(); -}; - -/** - * inflate gzip data. - * @return {!(Array.|Uint8Array)} inflated buffer. - */ -Zlib.Gunzip.prototype.decompress = function() { - /** @type {number} input length. */ - var il = this.input.length; - - while (this.ip < il) { - this.decodeMember(); - } - - this.decompressed = true; - - return this.concatMember(); -}; - -/** - * decode gzip member. - */ -Zlib.Gunzip.prototype.decodeMember = function() { - /** @type {Zlib.GunzipMember} */ - var member = new Zlib.GunzipMember(); - /** @type {number} */ - var isize; - /** @type {Zlib.RawInflate} RawInflate implementation. */ - var rawinflate; - /** @type {!(Array.|Uint8Array)} inflated data. */ - var inflated; - /** @type {number} inflate size */ - var inflen; - /** @type {number} character code */ - var c; - /** @type {number} character index in string. */ - var ci; - /** @type {Array.} character array. */ - var str; - /** @type {number} modification time. */ - var mtime; - /** @type {number} */ - var crc32; - - var input = this.input; - var ip = this.ip; - - member.id1 = input[ip++]; - member.id2 = input[ip++]; - - // check signature - if (member.id1 !== 0x1f || member.id2 !== 0x8b) { - throw new Error('invalid file signature:' + member.id1 + ',' + member.id2); - } - - // check compression method - member.cm = input[ip++]; - switch (member.cm) { - case 8: /* XXX: use Zlib const */ - break; - default: - throw new Error('unknown compression method: ' + member.cm); - } - - // flags - member.flg = input[ip++]; - - // modification time - mtime = (input[ip++]) | - (input[ip++] << 8) | - (input[ip++] << 16) | - (input[ip++] << 24); - member.mtime = new Date(mtime * 1000); - - // extra flags - member.xfl = input[ip++]; - - // operating system - member.os = input[ip++]; - - // extra - if ((member.flg & Zlib.Gzip.FlagsMask.FEXTRA) > 0) { - member.xlen = input[ip++] | (input[ip++] << 8); - ip = this.decodeSubField(ip, member.xlen); - } - - // fname - if ((member.flg & Zlib.Gzip.FlagsMask.FNAME) > 0) { - for(str = [], ci = 0; (c = input[ip++]) > 0;) { - str[ci++] = String.fromCharCode(c); - } - member.name = str.join(''); - } - - // fcomment - if ((member.flg & Zlib.Gzip.FlagsMask.FCOMMENT) > 0) { - for(str = [], ci = 0; (c = input[ip++]) > 0;) { - str[ci++] = String.fromCharCode(c); - } - member.comment = str.join(''); - } - - // fhcrc - if ((member.flg & Zlib.Gzip.FlagsMask.FHCRC) > 0) { - member.crc16 = Zlib.CRC32.calc(input, 0, ip) & 0xffff; - if (member.crc16 !== (input[ip++] | (input[ip++] << 8))) { - throw new Error('invalid header crc16'); - } - } - - // isize を事前に取得すると展開後のサイズが分かるため、 - // inflate処理のバッファサイズが事前に分かり、高速になる - isize = (input[input.length - 4]) | (input[input.length - 3] << 8) | - (input[input.length - 2] << 16) | (input[input.length - 1] << 24); - - // isize の妥当性チェック - // ハフマン符号では最小 2-bit のため、最大で 1/4 になる - // LZ77 符号では 長さと距離 2-Byte で最大 258-Byte を表現できるため、 - // 1/128 になるとする - // ここから入力バッファの残りが isize の 512 倍以上だったら - // サイズ指定のバッファ確保は行わない事とする - if (input.length - ip - /* CRC-32 */4 - /* ISIZE */4 < isize * 512) { - inflen = isize; - } - - // compressed block - rawinflate = new Zlib.RawInflate(input, {'index': ip, 'bufferSize': inflen}); - member.data = inflated = rawinflate.decompress(); - ip = rawinflate.ip; - - // crc32 - member.crc32 = crc32 = - ((input[ip++]) | (input[ip++] << 8) | - (input[ip++] << 16) | (input[ip++] << 24)) >>> 0; - if (Zlib.CRC32.calc(inflated) !== crc32) { - throw new Error('invalid CRC-32 checksum: 0x' + - Zlib.CRC32.calc(inflated).toString(16) + ' / 0x' + crc32.toString(16)); - } - - // input size - member.isize = isize = - ((input[ip++]) | (input[ip++] << 8) | - (input[ip++] << 16) | (input[ip++] << 24)) >>> 0; - if ((inflated.length & 0xffffffff) !== isize) { - throw new Error('invalid input size: ' + - (inflated.length & 0xffffffff) + ' / ' + isize); - } - - this.member.push(member); - this.ip = ip; -}; - -/** - * サブフィールドのデコード - * XXX: 現在は何もせずスキップする - */ -Zlib.Gunzip.prototype.decodeSubField = function(ip, length) { - return ip + length; -}; - -/** - * @return {!(Array.|Uint8Array)} - */ -Zlib.Gunzip.prototype.concatMember = function() { - /** @type {Array.} */ - var member = this.member; - /** @type {number} */ - var i; - /** @type {number} */ - var il; - /** @type {number} */ - var p = 0; - /** @type {number} */ - var size = 0; - /** @type {!(Array.|Uint8Array)} */ - var buffer; - - for (i = 0, il = member.length; i < il; ++i) { - size += member[i].data.length; - } - - { - buffer = new Uint8Array(size); - for (i = 0; i < il; ++i) { - buffer.set(member[i].data, p); - p += member[i].data.length; - } - } - - return buffer; -}; - - - -/** - * @constructor - */ -Zlib.GunzipMember = function() { - /** @type {number} signature first byte. */ - this.id1; - /** @type {number} signature second byte. */ - this.id2; - /** @type {number} compression method. */ - this.cm; - /** @type {number} flags. */ - this.flg; - /** @type {Date} modification time. */ - this.mtime; - /** @type {number} extra flags. */ - this.xfl; - /** @type {number} operating system number. */ - this.os; - /** @type {number} CRC-16 value for FHCRC flag. */ - this.crc16; - /** @type {number} extra length. */ - this.xlen; - /** @type {number} CRC-32 value for verification. */ - this.crc32; - /** @type {number} input size modulo 32 value. */ - this.isize; - /** @type {string} filename. */ - this.name; - /** @type {string} comment. */ - this.comment; - /** @type {!(Uint8Array|Array.)} */ - this.data; -}; - -Zlib.GunzipMember.prototype.getName = function() { - return this.name; -}; - -Zlib.GunzipMember.prototype.getData = function() { - return this.data; -}; - -Zlib.GunzipMember.prototype.getMtime = function() { - return this.mtime; -}; - -/** - * @fileoverview GZIP (RFC1952) 実装. - */ - -/** - * @constructor - * @param {!(Array|Uint8Array)} input input buffer. - * @param {Object=} opt_params option parameters. - */ -Zlib.Gzip = function(input, opt_params) { - /** @type {!(Array.|Uint8Array)} input buffer. */ - this.input = input; - /** @type {number} input buffer pointer. */ - this.ip = 0; - /** @type {!(Array.|Uint8Array)} output buffer. */ - this.output; - /** @type {number} output buffer. */ - this.op = 0; - /** @type {!Object} flags option flags. */ - this.flags = {}; - /** @type {!string} filename. */ - this.filename; - /** @type {!string} comment. */ - this.comment; - /** @type {!Object} deflate options. */ - this.deflateOptions; - - // option parameters - if (opt_params) { - if (opt_params['flags']) { - this.flags = opt_params['flags']; - } - if (typeof opt_params['filename'] === 'string') { - this.filename = opt_params['filename']; - } - if (typeof opt_params['comment'] === 'string') { - this.comment = opt_params['comment']; - } - if (opt_params['deflateOptions']) { - this.deflateOptions = opt_params['deflateOptions']; - } - } - - if (!this.deflateOptions) { - this.deflateOptions = {}; - } -}; - -/** - * @type {number} - * @const - */ -Zlib.Gzip.DefaultBufferSize = 0x8000; - -/** - * encode gzip members. - * @return {!(Array|Uint8Array)} gzip binary array. - */ -Zlib.Gzip.prototype.compress = function() { - /** @type {number} flags. */ - var flg; - /** @type {number} modification time. */ - var mtime; - /** @type {number} CRC-16 value for FHCRC flag. */ - var crc16; - /** @type {number} CRC-32 value for verification. */ - var crc32; - /** @type {!Zlib.RawDeflate} raw deflate object. */ - var rawdeflate; - /** @type {number} character code */ - var c; - /** @type {number} loop counter. */ - var i; - /** @type {number} loop limiter. */ - var il; - /** @type {!(Array|Uint8Array)} output buffer. */ - var output = - new (Uint8Array )(Zlib.Gzip.DefaultBufferSize); - /** @type {number} output buffer pointer. */ - var op = 0; - - var input = this.input; - var ip = this.ip; - var filename = this.filename; - var comment = this.comment; - - // check signature - output[op++] = 0x1f; - output[op++] = 0x8b; - - // check compression method - output[op++] = 8; /* XXX: use Zlib const */ - - // flags - flg = 0; - if (this.flags['fname']) flg |= Zlib.Gzip.FlagsMask.FNAME; - if (this.flags['fcomment']) flg |= Zlib.Gzip.FlagsMask.FCOMMENT; - if (this.flags['fhcrc']) flg |= Zlib.Gzip.FlagsMask.FHCRC; - // XXX: FTEXT - // XXX: FEXTRA - output[op++] = flg; - - // modification time - mtime = (Date.now ? Date.now() : +new Date()) / 1000 | 0; - output[op++] = mtime & 0xff; - output[op++] = mtime >>> 8 & 0xff; - output[op++] = mtime >>> 16 & 0xff; - output[op++] = mtime >>> 24 & 0xff; - - // extra flags - output[op++] = 0; - - // operating system - output[op++] = Zlib.Gzip.OperatingSystem.UNKNOWN; - - // extra - /* NOP */ - - // fname - if (this.flags['fname'] !== void 0) { - for (i = 0, il = filename.length; i < il; ++i) { - c = filename.charCodeAt(i); - if (c > 0xff) { output[op++] = (c >>> 8) & 0xff; } - output[op++] = c & 0xff; - } - output[op++] = 0; // null termination - } - - // fcomment - if (this.flags['comment']) { - for (i = 0, il = comment.length; i < il; ++i) { - c = comment.charCodeAt(i); - if (c > 0xff) { output[op++] = (c >>> 8) & 0xff; } - output[op++] = c & 0xff; - } - output[op++] = 0; // null termination - } - - // fhcrc - if (this.flags['fhcrc']) { - crc16 = Zlib.CRC32.calc(output, 0, op) & 0xffff; - output[op++] = (crc16 ) & 0xff; - output[op++] = (crc16 >>> 8) & 0xff; - } - - // add compress option - this.deflateOptions['outputBuffer'] = output; - this.deflateOptions['outputIndex'] = op; - - // compress - rawdeflate = new Zlib.RawDeflate(input, this.deflateOptions); - output = rawdeflate.compress(); - op = rawdeflate.op; - - // expand buffer - { - if (op + 8 > output.buffer.byteLength) { - this.output = new Uint8Array(op + 8); - this.output.set(new Uint8Array(output.buffer)); - output = this.output; - } else { - output = new Uint8Array(output.buffer); - } - } - - // crc32 - crc32 = Zlib.CRC32.calc(input); - output[op++] = (crc32 ) & 0xff; - output[op++] = (crc32 >>> 8) & 0xff; - output[op++] = (crc32 >>> 16) & 0xff; - output[op++] = (crc32 >>> 24) & 0xff; - - // input size - il = input.length; - output[op++] = (il ) & 0xff; - output[op++] = (il >>> 8) & 0xff; - output[op++] = (il >>> 16) & 0xff; - output[op++] = (il >>> 24) & 0xff; - - this.ip = ip; - - if (op < output.length) { - this.output = output = output.subarray(0, op); - } - - return output; -}; - -/** @enum {number} */ -Zlib.Gzip.OperatingSystem = { - FAT: 0, - AMIGA: 1, - VMS: 2, - UNIX: 3, - VM_CMS: 4, - ATARI_TOS: 5, - HPFS: 6, - MACINTOSH: 7, - Z_SYSTEM: 8, - CP_M: 9, - TOPS_20: 10, - NTFS: 11, - QDOS: 12, - ACORN_RISCOS: 13, - UNKNOWN: 255 -}; - -/** @enum {number} */ -Zlib.Gzip.FlagsMask = { - FTEXT: 0x01, - FHCRC: 0x02, - FEXTRA: 0x04, - FNAME: 0x08, - FCOMMENT: 0x10 -}; - - -/** - * @fileoverview Heap Sort 実装. ハフマン符号化で使用する. - */ - -/** - * カスタムハフマン符号で使用するヒープ実装 - * @param {number} length ヒープサイズ. - * @constructor - */ -Zlib.Heap = function(length) { - this.buffer = new (Uint16Array )(length * 2); - this.length = 0; -}; - -/** - * 親ノードの index 取得 - * @param {number} index 子ノードの index. - * @return {number} 親ノードの index. - * - */ -Zlib.Heap.prototype.getParent = function(index) { - return ((index - 2) / 4 | 0) * 2; -}; - -/** - * 子ノードの index 取得 - * @param {number} index 親ノードの index. - * @return {number} 子ノードの index. - */ -Zlib.Heap.prototype.getChild = function(index) { - return 2 * index + 2; -}; - -/** - * Heap に値を追加する - * @param {number} index キー index. - * @param {number} value 値. - * @return {number} 現在のヒープ長. - */ -Zlib.Heap.prototype.push = function(index, value) { - var current, parent, - heap = this.buffer, - swap; - - current = this.length; - heap[this.length++] = value; - heap[this.length++] = index; - - // ルートノードにたどり着くまで入れ替えを試みる - while (current > 0) { - parent = this.getParent(current); - - // 親ノードと比較して親の方が小さければ入れ替える - if (heap[current] > heap[parent]) { - swap = heap[current]; - heap[current] = heap[parent]; - heap[parent] = swap; - - swap = heap[current + 1]; - heap[current + 1] = heap[parent + 1]; - heap[parent + 1] = swap; - - current = parent; - // 入れ替えが必要なくなったらそこで抜ける - } else { - break; - } - } - - return this.length; -}; - -/** - * Heapから一番大きい値を返す - * @return {{index: number, value: number, length: number}} {index: キーindex, - * value: 値, length: ヒープ長} の Object. - */ -Zlib.Heap.prototype.pop = function() { - var index, value, - heap = this.buffer, swap, - current, parent; - - value = heap[0]; - index = heap[1]; - - // 後ろから値を取る - this.length -= 2; - heap[0] = heap[this.length]; - heap[1] = heap[this.length + 1]; - - parent = 0; - // ルートノードから下がっていく - while (true) { - current = this.getChild(parent); - - // 範囲チェック - if (current >= this.length) { - break; - } - - // 隣のノードと比較して、隣の方が値が大きければ隣を現在ノードとして選択 - if (current + 2 < this.length && heap[current + 2] > heap[current]) { - current += 2; - } - - // 親ノードと比較して親の方が小さい場合は入れ替える - if (heap[current] > heap[parent]) { - swap = heap[parent]; - heap[parent] = heap[current]; - heap[current] = swap; - - swap = heap[parent + 1]; - heap[parent + 1] = heap[current + 1]; - heap[current + 1] = swap; - } else { - break; - } - - parent = current; - } - - return {index: index, value: value, length: this.length}; -}; - - -/* vim:set expandtab ts=2 sw=2 tw=80: */ - -/** - * @fileoverview Deflate (RFC1951) 符号化アルゴリズム実装. - */ - - -/** - * Raw Deflate 実装 - * - * @constructor - * @param {!(Array.|Uint8Array)} input 符号化する対象のバッファ. - * @param {Object=} opt_params option parameters. - * - * typed array が使用可能なとき、outputBuffer が Array は自動的に Uint8Array に - * 変換されます. - * 別のオブジェクトになるため出力バッファを参照している変数などは - * 更新する必要があります. - */ -Zlib.RawDeflate = function(input, opt_params) { - /** @type {Zlib.RawDeflate.CompressionType} */ - this.compressionType = Zlib.RawDeflate.CompressionType.DYNAMIC; - /** @type {number} */ - this.lazy = 0; - /** @type {!(Array.|Uint32Array)} */ - this.freqsLitLen; - /** @type {!(Array.|Uint32Array)} */ - this.freqsDist; - /** @type {!(Array.|Uint8Array)} */ - this.input = - (input instanceof Array) ? new Uint8Array(input) : input; - /** @type {!(Array.|Uint8Array)} output output buffer. */ - this.output; - /** @type {number} pos output buffer position. */ - this.op = 0; - - // option parameters - if (opt_params) { - if (opt_params['lazy']) { - this.lazy = opt_params['lazy']; - } - if (typeof opt_params['compressionType'] === 'number') { - this.compressionType = opt_params['compressionType']; - } - if (opt_params['outputBuffer']) { - this.output = - (opt_params['outputBuffer'] instanceof Array) ? - new Uint8Array(opt_params['outputBuffer']) : opt_params['outputBuffer']; - } - if (typeof opt_params['outputIndex'] === 'number') { - this.op = opt_params['outputIndex']; - } - } - - if (!this.output) { - this.output = new (Uint8Array )(0x8000); - } -}; - -/** - * @enum {number} - */ -Zlib.RawDeflate.CompressionType = { - NONE: 0, - FIXED: 1, - DYNAMIC: 2, - RESERVED: 3 -}; - - -/** - * LZ77 の最小マッチ長 - * @const - * @type {number} - */ -Zlib.RawDeflate.Lz77MinLength = 3; - -/** - * LZ77 の最大マッチ長 - * @const - * @type {number} - */ -Zlib.RawDeflate.Lz77MaxLength = 258; - -/** - * LZ77 のウィンドウサイズ - * @const - * @type {number} - */ -Zlib.RawDeflate.WindowSize = 0x8000; - -/** - * 最長の符号長 - * @const - * @type {number} - */ -Zlib.RawDeflate.MaxCodeLength = 16; - -/** - * ハフマン符号の最大数値 - * @const - * @type {number} - */ -Zlib.RawDeflate.HUFMAX = 286; - -/** - * 固定ハフマン符号の符号化テーブル - * @const - * @type {Array.>} - */ -Zlib.RawDeflate.FixedHuffmanTable = (function() { - var table = [], i; - - for (i = 0; i < 288; i++) { - switch (true) { - case (i <= 143): table.push([i + 0x030, 8]); break; - case (i <= 255): table.push([i - 144 + 0x190, 9]); break; - case (i <= 279): table.push([i - 256 + 0x000, 7]); break; - case (i <= 287): table.push([i - 280 + 0x0C0, 8]); break; - default: - throw 'invalid literal: ' + i; - } - } - - return table; -})(); - -/** - * DEFLATE ブロックの作成 - * @return {!(Array.|Uint8Array)} 圧縮済み byte array. - */ -Zlib.RawDeflate.prototype.compress = function() { - /** @type {!(Array.|Uint8Array)} */ - var blockArray; - /** @type {number} */ - var position; - /** @type {number} */ - var length; - - var input = this.input; - - // compression - switch (this.compressionType) { - case Zlib.RawDeflate.CompressionType.NONE: - // each 65535-Byte (length header: 16-bit) - for (position = 0, length = input.length; position < length;) { - blockArray = input.subarray(position, position + 0xffff) ; - position += blockArray.length; - this.makeNocompressBlock(blockArray, (position === length)); - } - break; - case Zlib.RawDeflate.CompressionType.FIXED: - this.output = this.makeFixedHuffmanBlock(input, true); - this.op = this.output.length; - break; - case Zlib.RawDeflate.CompressionType.DYNAMIC: - this.output = this.makeDynamicHuffmanBlock(input, true); - this.op = this.output.length; - break; - default: - throw 'invalid compression type'; - } - - return this.output; -}; - -/** - * 非圧縮ブロックの作成 - * @param {!(Array.|Uint8Array)} blockArray ブロックデータ byte array. - * @param {!boolean} isFinalBlock 最後のブロックならばtrue. - * @return {!(Array.|Uint8Array)} 非圧縮ブロック byte array. - */ -Zlib.RawDeflate.prototype.makeNocompressBlock = -function(blockArray, isFinalBlock) { - /** @type {number} */ - var bfinal; - /** @type {Zlib.RawDeflate.CompressionType} */ - var btype; - /** @type {number} */ - var len; - /** @type {number} */ - var nlen; - - var output = this.output; - var op = this.op; - - // expand buffer - { - output = new Uint8Array(this.output.buffer); - while (output.length <= op + blockArray.length + 5) { - output = new Uint8Array(output.length << 1); - } - output.set(this.output); - } - - // header - bfinal = isFinalBlock ? 1 : 0; - btype = Zlib.RawDeflate.CompressionType.NONE; - output[op++] = (bfinal) | (btype << 1); - - // length - len = blockArray.length; - nlen = (~len + 0x10000) & 0xffff; - output[op++] = len & 0xff; - output[op++] = (len >>> 8) & 0xff; - output[op++] = nlen & 0xff; - output[op++] = (nlen >>> 8) & 0xff; - - // copy buffer - { - output.set(blockArray, op); - op += blockArray.length; - output = output.subarray(0, op); - } - - this.op = op; - this.output = output; - - return output; -}; - -/** - * 固定ハフマンブロックの作成 - * @param {!(Array.|Uint8Array)} blockArray ブロックデータ byte array. - * @param {!boolean} isFinalBlock 最後のブロックならばtrue. - * @return {!(Array.|Uint8Array)} 固定ハフマン符号化ブロック byte array. - */ -Zlib.RawDeflate.prototype.makeFixedHuffmanBlock = -function(blockArray, isFinalBlock) { - /** @type {Zlib.BitStream} */ - var stream = new Zlib.BitStream(new Uint8Array(this.output.buffer) , this.op); - /** @type {number} */ - var bfinal; - /** @type {Zlib.RawDeflate.CompressionType} */ - var btype; - /** @type {!(Array.|Uint16Array)} */ - var data; - - // header - bfinal = isFinalBlock ? 1 : 0; - btype = Zlib.RawDeflate.CompressionType.FIXED; - - stream.writeBits(bfinal, 1, true); - stream.writeBits(btype, 2, true); - - data = this.lz77(blockArray); - this.fixedHuffman(data, stream); - - return stream.finish(); -}; - -/** - * 動的ハフマンブロックの作成 - * @param {!(Array.|Uint8Array)} blockArray ブロックデータ byte array. - * @param {!boolean} isFinalBlock 最後のブロックならばtrue. - * @return {!(Array.|Uint8Array)} 動的ハフマン符号ブロック byte array. - */ -Zlib.RawDeflate.prototype.makeDynamicHuffmanBlock = -function(blockArray, isFinalBlock) { - /** @type {Zlib.BitStream} */ - var stream = new Zlib.BitStream(new Uint8Array(this.output.buffer) , this.op); - /** @type {number} */ - var bfinal; - /** @type {Zlib.RawDeflate.CompressionType} */ - var btype; - /** @type {!(Array.|Uint16Array)} */ - var data; - /** @type {number} */ - var hlit; - /** @type {number} */ - var hdist; - /** @type {number} */ - var hclen; - /** @const @type {Array.} */ - var hclenOrder = - [16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15]; - /** @type {!(Array.|Uint8Array)} */ - var litLenLengths; - /** @type {!(Array.|Uint16Array)} */ - var litLenCodes; - /** @type {!(Array.|Uint8Array)} */ - var distLengths; - /** @type {!(Array.|Uint16Array)} */ - var distCodes; - /** @type {{ - * codes: !(Array.|Uint32Array), - * freqs: !(Array.|Uint8Array) - * }} */ - var treeSymbols; - /** @type {!(Array.|Uint8Array)} */ - var treeLengths; - /** @type {Array} */ - var transLengths = new Array(19); - /** @type {!(Array.|Uint16Array)} */ - var treeCodes; - /** @type {number} */ - var code; - /** @type {number} */ - var bitlen; - /** @type {number} */ - var i; - /** @type {number} */ - var il; - - // header - bfinal = isFinalBlock ? 1 : 0; - btype = Zlib.RawDeflate.CompressionType.DYNAMIC; - - stream.writeBits(bfinal, 1, true); - stream.writeBits(btype, 2, true); - - data = this.lz77(blockArray); - - // リテラル・長さ, 距離のハフマン符号と符号長の算出 - litLenLengths = this.getLengths_(this.freqsLitLen, 15); - litLenCodes = this.getCodesFromLengths_(litLenLengths); - distLengths = this.getLengths_(this.freqsDist, 7); - distCodes = this.getCodesFromLengths_(distLengths); - - // HLIT, HDIST の決定 - for (hlit = 286; hlit > 257 && litLenLengths[hlit - 1] === 0; hlit--) {} - for (hdist = 30; hdist > 1 && distLengths[hdist - 1] === 0; hdist--) {} - - // HCLEN - treeSymbols = - this.getTreeSymbols_(hlit, litLenLengths, hdist, distLengths); - treeLengths = this.getLengths_(treeSymbols.freqs, 7); - for (i = 0; i < 19; i++) { - transLengths[i] = treeLengths[hclenOrder[i]]; - } - for (hclen = 19; hclen > 4 && transLengths[hclen - 1] === 0; hclen--) {} - - treeCodes = this.getCodesFromLengths_(treeLengths); - - // 出力 - stream.writeBits(hlit - 257, 5, true); - stream.writeBits(hdist - 1, 5, true); - stream.writeBits(hclen - 4, 4, true); - for (i = 0; i < hclen; i++) { - stream.writeBits(transLengths[i], 3, true); - } - - // ツリーの出力 - for (i = 0, il = treeSymbols.codes.length; i < il; i++) { - code = treeSymbols.codes[i]; - - stream.writeBits(treeCodes[code], treeLengths[code], true); - - // extra bits - if (code >= 16) { - i++; - switch (code) { - case 16: bitlen = 2; break; - case 17: bitlen = 3; break; - case 18: bitlen = 7; break; - default: - throw 'invalid code: ' + code; - } - - stream.writeBits(treeSymbols.codes[i], bitlen, true); - } - } - - this.dynamicHuffman( - data, - [litLenCodes, litLenLengths], - [distCodes, distLengths], - stream - ); - - return stream.finish(); -}; - - -/** - * 動的ハフマン符号化(カスタムハフマンテーブル) - * @param {!(Array.|Uint16Array)} dataArray LZ77 符号化済み byte array. - * @param {!Zlib.BitStream} stream 書き込み用ビットストリーム. - * @return {!Zlib.BitStream} ハフマン符号化済みビットストリームオブジェクト. - */ -Zlib.RawDeflate.prototype.dynamicHuffman = -function(dataArray, litLen, dist, stream) { - /** @type {number} */ - var index; - /** @type {number} */ - var length; - /** @type {number} */ - var literal; - /** @type {number} */ - var code; - /** @type {number} */ - var litLenCodes; - /** @type {number} */ - var litLenLengths; - /** @type {number} */ - var distCodes; - /** @type {number} */ - var distLengths; - - litLenCodes = litLen[0]; - litLenLengths = litLen[1]; - distCodes = dist[0]; - distLengths = dist[1]; - - // 符号を BitStream に書き込んでいく - for (index = 0, length = dataArray.length; index < length; ++index) { - literal = dataArray[index]; - - // literal or length - stream.writeBits(litLenCodes[literal], litLenLengths[literal], true); - - // 長さ・距離符号 - if (literal > 256) { - // length extra - stream.writeBits(dataArray[++index], dataArray[++index], true); - // distance - code = dataArray[++index]; - stream.writeBits(distCodes[code], distLengths[code], true); - // distance extra - stream.writeBits(dataArray[++index], dataArray[++index], true); - // 終端 - } else if (literal === 256) { - break; - } - } - - return stream; -}; - -/** - * 固定ハフマン符号化 - * @param {!(Array.|Uint16Array)} dataArray LZ77 符号化済み byte array. - * @param {!Zlib.BitStream} stream 書き込み用ビットストリーム. - * @return {!Zlib.BitStream} ハフマン符号化済みビットストリームオブジェクト. - */ -Zlib.RawDeflate.prototype.fixedHuffman = function(dataArray, stream) { - /** @type {number} */ - var index; - /** @type {number} */ - var length; - /** @type {number} */ - var literal; - - // 符号を BitStream に書き込んでいく - for (index = 0, length = dataArray.length; index < length; index++) { - literal = dataArray[index]; - - // 符号の書き込み - Zlib.BitStream.prototype.writeBits.apply( - stream, - Zlib.RawDeflate.FixedHuffmanTable[literal] - ); - - // 長さ・距離符号 - if (literal > 0x100) { - // length extra - stream.writeBits(dataArray[++index], dataArray[++index], true); - // distance - stream.writeBits(dataArray[++index], 5); - // distance extra - stream.writeBits(dataArray[++index], dataArray[++index], true); - // 終端 - } else if (literal === 0x100) { - break; - } - } - - return stream; -}; - -/** - * マッチ情報 - * @param {!number} length マッチした長さ. - * @param {!number} backwardDistance マッチ位置との距離. - * @constructor - */ -Zlib.RawDeflate.Lz77Match = function(length, backwardDistance) { - /** @type {number} match length. */ - this.length = length; - /** @type {number} backward distance. */ - this.backwardDistance = backwardDistance; -}; - -/** - * 長さ符号テーブル. - * [コード, 拡張ビット, 拡張ビット長] の配列となっている. - * @const - * @type {!(Array.|Uint32Array)} - */ -Zlib.RawDeflate.Lz77Match.LengthCodeTable = (function(table) { - return new Uint32Array(table) ; -})((function() { - /** @type {!Array} */ - var table = []; - /** @type {number} */ - var i; - /** @type {!Array.} */ - var c; - - for (i = 3; i <= 258; i++) { - c = code(i); - table[i] = (c[2] << 24) | (c[1] << 16) | c[0]; - } - - /** - * @param {number} length lz77 length. - * @return {!Array.} lz77 codes. - */ - function code(length) { - switch (true) { - case (length === 3): return [257, length - 3, 0]; case (length === 4): return [258, length - 4, 0]; case (length === 5): return [259, length - 5, 0]; case (length === 6): return [260, length - 6, 0]; case (length === 7): return [261, length - 7, 0]; case (length === 8): return [262, length - 8, 0]; case (length === 9): return [263, length - 9, 0]; case (length === 10): return [264, length - 10, 0]; case (length <= 12): return [265, length - 11, 1]; case (length <= 14): return [266, length - 13, 1]; case (length <= 16): return [267, length - 15, 1]; case (length <= 18): return [268, length - 17, 1]; case (length <= 22): return [269, length - 19, 2]; case (length <= 26): return [270, length - 23, 2]; case (length <= 30): return [271, length - 27, 2]; case (length <= 34): return [272, length - 31, 2]; case (length <= 42): return [273, length - 35, 3]; case (length <= 50): return [274, length - 43, 3]; case (length <= 58): return [275, length - 51, 3]; case (length <= 66): return [276, length - 59, 3]; case (length <= 82): return [277, length - 67, 4]; case (length <= 98): return [278, length - 83, 4]; case (length <= 114): return [279, length - 99, 4]; case (length <= 130): return [280, length - 115, 4]; case (length <= 162): return [281, length - 131, 5]; case (length <= 194): return [282, length - 163, 5]; case (length <= 226): return [283, length - 195, 5]; case (length <= 257): return [284, length - 227, 5]; case (length === 258): return [285, length - 258, 0]; default: throw 'invalid length: ' + length; - } - } - - return table; -})()); - -/** - * 距離符号テーブル - * @param {!number} dist 距離. - * @return {!Array.} コード、拡張ビット、拡張ビット長の配列. - * @private - */ -Zlib.RawDeflate.Lz77Match.prototype.getDistanceCode_ = function(dist) { - /** @type {!Array.} distance code table. */ - var r; - - switch (true) { - case (dist === 1): r = [0, dist - 1, 0]; break; - case (dist === 2): r = [1, dist - 2, 0]; break; - case (dist === 3): r = [2, dist - 3, 0]; break; - case (dist === 4): r = [3, dist - 4, 0]; break; - case (dist <= 6): r = [4, dist - 5, 1]; break; - case (dist <= 8): r = [5, dist - 7, 1]; break; - case (dist <= 12): r = [6, dist - 9, 2]; break; - case (dist <= 16): r = [7, dist - 13, 2]; break; - case (dist <= 24): r = [8, dist - 17, 3]; break; - case (dist <= 32): r = [9, dist - 25, 3]; break; - case (dist <= 48): r = [10, dist - 33, 4]; break; - case (dist <= 64): r = [11, dist - 49, 4]; break; - case (dist <= 96): r = [12, dist - 65, 5]; break; - case (dist <= 128): r = [13, dist - 97, 5]; break; - case (dist <= 192): r = [14, dist - 129, 6]; break; - case (dist <= 256): r = [15, dist - 193, 6]; break; - case (dist <= 384): r = [16, dist - 257, 7]; break; - case (dist <= 512): r = [17, dist - 385, 7]; break; - case (dist <= 768): r = [18, dist - 513, 8]; break; - case (dist <= 1024): r = [19, dist - 769, 8]; break; - case (dist <= 1536): r = [20, dist - 1025, 9]; break; - case (dist <= 2048): r = [21, dist - 1537, 9]; break; - case (dist <= 3072): r = [22, dist - 2049, 10]; break; - case (dist <= 4096): r = [23, dist - 3073, 10]; break; - case (dist <= 6144): r = [24, dist - 4097, 11]; break; - case (dist <= 8192): r = [25, dist - 6145, 11]; break; - case (dist <= 12288): r = [26, dist - 8193, 12]; break; - case (dist <= 16384): r = [27, dist - 12289, 12]; break; - case (dist <= 24576): r = [28, dist - 16385, 13]; break; - case (dist <= 32768): r = [29, dist - 24577, 13]; break; - default: throw 'invalid distance'; - } - - return r; -}; - -/** - * マッチ情報を LZ77 符号化配列で返す. - * なお、ここでは以下の内部仕様で符号化している - * [ CODE, EXTRA-BIT-LEN, EXTRA, CODE, EXTRA-BIT-LEN, EXTRA ] - * @return {!Array.} LZ77 符号化 byte array. - */ -Zlib.RawDeflate.Lz77Match.prototype.toLz77Array = function() { - /** @type {number} */ - var length = this.length; - /** @type {number} */ - var dist = this.backwardDistance; - /** @type {Array} */ - var codeArray = []; - /** @type {number} */ - var pos = 0; - /** @type {!Array.} */ - var code; - - // length - code = Zlib.RawDeflate.Lz77Match.LengthCodeTable[length]; - codeArray[pos++] = code & 0xffff; - codeArray[pos++] = (code >> 16) & 0xff; - codeArray[pos++] = code >> 24; - - // distance - code = this.getDistanceCode_(dist); - codeArray[pos++] = code[0]; - codeArray[pos++] = code[1]; - codeArray[pos++] = code[2]; - - return codeArray; -}; - -/** - * LZ77 実装 - * @param {!(Array.|Uint8Array)} dataArray LZ77 符号化するバイト配列. - * @return {!(Array.|Uint16Array)} LZ77 符号化した配列. - */ -Zlib.RawDeflate.prototype.lz77 = function(dataArray) { - /** @type {number} input position */ - var position; - /** @type {number} input length */ - var length; - /** @type {number} loop counter */ - var i; - /** @type {number} loop limiter */ - var il; - /** @type {number} chained-hash-table key */ - var matchKey; - /** @type {Object.>} chained-hash-table */ - var table = {}; - /** @const @type {number} */ - var windowSize = Zlib.RawDeflate.WindowSize; - /** @type {Array.} match list */ - var matchList; - /** @type {Zlib.RawDeflate.Lz77Match} longest match */ - var longestMatch; - /** @type {Zlib.RawDeflate.Lz77Match} previous longest match */ - var prevMatch; - /** @type {!(Array.|Uint16Array)} lz77 buffer */ - var lz77buf = new Uint16Array(dataArray.length * 2) ; - /** @type {number} lz77 output buffer pointer */ - var pos = 0; - /** @type {number} lz77 skip length */ - var skipLength = 0; - /** @type {!(Array.|Uint32Array)} */ - var freqsLitLen = new (Uint32Array )(286); - /** @type {!(Array.|Uint32Array)} */ - var freqsDist = new (Uint32Array )(30); - /** @type {number} */ - var lazy = this.lazy; - /** @type {*} temporary variable */ - var tmp; - freqsLitLen[256] = 1; // EOB の最低出現回数は 1 - - /** - * マッチデータの書き込み - * @param {Zlib.RawDeflate.Lz77Match} match LZ77 Match data. - * @param {!number} offset スキップ開始位置(相対指定). - * @private - */ - function writeMatch(match, offset) { - /** @type {Array.} */ - var lz77Array = match.toLz77Array(); - /** @type {number} */ - var i; - /** @type {number} */ - var il; - - for (i = 0, il = lz77Array.length; i < il; ++i) { - lz77buf[pos++] = lz77Array[i]; - } - freqsLitLen[lz77Array[0]]++; - freqsDist[lz77Array[3]]++; - skipLength = match.length + offset - 1; - prevMatch = null; - } - - // LZ77 符号化 - for (position = 0, length = dataArray.length; position < length; ++position) { - // ハッシュキーの作成 - for (matchKey = 0, i = 0, il = Zlib.RawDeflate.Lz77MinLength; i < il; ++i) { - if (position + i === length) { - break; - } - matchKey = (matchKey << 8) | dataArray[position + i]; - } - - // テーブルが未定義だったら作成する - if (table[matchKey] === void 0) { table[matchKey] = []; } - matchList = table[matchKey]; - - // skip - if (skipLength-- > 0) { - matchList.push(position); - continue; - } - - // マッチテーブルの更新 (最大戻り距離を超えているものを削除する) - while (matchList.length > 0 && position - matchList[0] > windowSize) { - matchList.shift(); - } - - // データ末尾でマッチしようがない場合はそのまま流しこむ - if (position + Zlib.RawDeflate.Lz77MinLength >= length) { - if (prevMatch) { - writeMatch(prevMatch, -1); - } - - for (i = 0, il = length - position; i < il; ++i) { - tmp = dataArray[position + i]; - lz77buf[pos++] = tmp; - ++freqsLitLen[tmp]; - } - break; - } - - // マッチ候補から最長のものを探す - if (matchList.length > 0) { - longestMatch = this.searchLongestMatch_(dataArray, position, matchList); - - if (prevMatch) { - // 現在のマッチの方が前回のマッチよりも長い - if (prevMatch.length < longestMatch.length) { - // write previous literal - tmp = dataArray[position - 1]; - lz77buf[pos++] = tmp; - ++freqsLitLen[tmp]; - - // write current match - writeMatch(longestMatch, 0); - } else { - // write previous match - writeMatch(prevMatch, -1); - } - } else if (longestMatch.length < lazy) { - prevMatch = longestMatch; - } else { - writeMatch(longestMatch, 0); - } - // 前回マッチしていて今回マッチがなかったら前回のを採用 - } else if (prevMatch) { - writeMatch(prevMatch, -1); - } else { - tmp = dataArray[position]; - lz77buf[pos++] = tmp; - ++freqsLitLen[tmp]; - } - - matchList.push(position); // マッチテーブルに現在の位置を保存 - } - - // 終端処理 - lz77buf[pos++] = 256; - freqsLitLen[256]++; - this.freqsLitLen = freqsLitLen; - this.freqsDist = freqsDist; - - return /** @type {!(Uint16Array|Array.)} */ ( - lz77buf.subarray(0, pos) - ); -}; - -/** - * マッチした候補の中から最長一致を探す - * @param {!Object} data plain data byte array. - * @param {!number} position plain data byte array position. - * @param {!Array.} matchList 候補となる位置の配列. - * @return {!Zlib.RawDeflate.Lz77Match} 最長かつ最短距離のマッチオブジェクト. - * @private - */ -Zlib.RawDeflate.prototype.searchLongestMatch_ = -function(data, position, matchList) { - var match, - currentMatch, - matchMax = 0, matchLength, - i, j, l, dl = data.length; - - // 候補を後ろから 1 つずつ絞り込んでゆく - permatch: - for (i = 0, l = matchList.length; i < l; i++) { - match = matchList[l - i - 1]; - matchLength = Zlib.RawDeflate.Lz77MinLength; - - // 前回までの最長一致を末尾から一致検索する - if (matchMax > Zlib.RawDeflate.Lz77MinLength) { - for (j = matchMax; j > Zlib.RawDeflate.Lz77MinLength; j--) { - if (data[match + j - 1] !== data[position + j - 1]) { - continue permatch; - } - } - matchLength = matchMax; - } - - // 最長一致探索 - while (matchLength < Zlib.RawDeflate.Lz77MaxLength && - position + matchLength < dl && - data[match + matchLength] === data[position + matchLength]) { - ++matchLength; - } - - // マッチ長が同じ場合は後方を優先 - if (matchLength > matchMax) { - currentMatch = match; - matchMax = matchLength; - } - - // 最長が確定したら後の処理は省略 - if (matchLength === Zlib.RawDeflate.Lz77MaxLength) { - break; - } - } - - return new Zlib.RawDeflate.Lz77Match(matchMax, position - currentMatch); -}; - -/** - * Tree-Transmit Symbols の算出 - * reference: PuTTY Deflate implementation - * @param {number} hlit HLIT. - * @param {!(Array.|Uint8Array)} litlenLengths リテラルと長さ符号の符号長配列. - * @param {number} hdist HDIST. - * @param {!(Array.|Uint8Array)} distLengths 距離符号の符号長配列. - * @return {{ - * codes: !(Array.|Uint32Array), - * freqs: !(Array.|Uint8Array) - * }} Tree-Transmit Symbols. - */ -Zlib.RawDeflate.prototype.getTreeSymbols_ = -function(hlit, litlenLengths, hdist, distLengths) { - var src = new (Uint32Array )(hlit + hdist), - i, j, runLength, l, - result = new (Uint32Array )(286 + 30), - nResult, - rpt, - freqs = new (Uint8Array )(19); - - j = 0; - for (i = 0; i < hlit; i++) { - src[j++] = litlenLengths[i]; - } - for (i = 0; i < hdist; i++) { - src[j++] = distLengths[i]; - } - - // 符号化 - nResult = 0; - for (i = 0, l = src.length; i < l; i += j) { - // Run Length Encoding - for (j = 1; i + j < l && src[i + j] === src[i]; ++j) {} - - runLength = j; - - if (src[i] === 0) { - // 0 の繰り返しが 3 回未満ならばそのまま - if (runLength < 3) { - while (runLength-- > 0) { - result[nResult++] = 0; - freqs[0]++; - } - } else { - while (runLength > 0) { - // 繰り返しは最大 138 までなので切り詰める - rpt = (runLength < 138 ? runLength : 138); - - if (rpt > runLength - 3 && rpt < runLength) { - rpt = runLength - 3; - } - - // 3-10 回 -> 17 - if (rpt <= 10) { - result[nResult++] = 17; - result[nResult++] = rpt - 3; - freqs[17]++; - // 11-138 回 -> 18 - } else { - result[nResult++] = 18; - result[nResult++] = rpt - 11; - freqs[18]++; - } - - runLength -= rpt; - } - } - } else { - result[nResult++] = src[i]; - freqs[src[i]]++; - runLength--; - - // 繰り返し回数が3回未満ならばランレングス符号は要らない - if (runLength < 3) { - while (runLength-- > 0) { - result[nResult++] = src[i]; - freqs[src[i]]++; - } - // 3 回以上ならばランレングス符号化 - } else { - while (runLength > 0) { - // runLengthを 3-6 で分割 - rpt = (runLength < 6 ? runLength : 6); - - if (rpt > runLength - 3 && rpt < runLength) { - rpt = runLength - 3; - } - - result[nResult++] = 16; - result[nResult++] = rpt - 3; - freqs[16]++; - - runLength -= rpt; - } - } - } - } - - return { - codes: - result.subarray(0, nResult) , - freqs: freqs - }; -}; - -/** - * ハフマン符号の長さを取得する - * @param {!(Array.|Uint8Array|Uint32Array)} freqs 出現カウント. - * @param {number} limit 符号長の制限. - * @return {!(Array.|Uint8Array)} 符号長配列. - * @private - */ -Zlib.RawDeflate.prototype.getLengths_ = function(freqs, limit) { - /** @type {number} */ - var nSymbols = freqs.length; - /** @type {Zlib.Heap} */ - var heap = new Zlib.Heap(2 * Zlib.RawDeflate.HUFMAX); - /** @type {!(Array.|Uint8Array)} */ - var length = new (Uint8Array )(nSymbols); - /** @type {Array} */ - var nodes; - /** @type {!(Array.|Uint32Array)} */ - var values; - /** @type {!(Array.|Uint8Array)} */ - var codeLength; - /** @type {number} */ - var i; - /** @type {number} */ - var il; - - // ヒープの構築 - for (i = 0; i < nSymbols; ++i) { - if (freqs[i] > 0) { - heap.push(i, freqs[i]); - } - } - nodes = new Array(heap.length / 2); - values = new (Uint32Array )(heap.length / 2); - - // 非 0 の要素が一つだけだった場合は、そのシンボルに符号長 1 を割り当てて終了 - if (nodes.length === 1) { - length[heap.pop().index] = 1; - return length; - } - - // Reverse Package Merge Algorithm による Canonical Huffman Code の符号長決定 - for (i = 0, il = heap.length / 2; i < il; ++i) { - nodes[i] = heap.pop(); - values[i] = nodes[i].value; - } - codeLength = this.reversePackageMerge_(values, values.length, limit); - - for (i = 0, il = nodes.length; i < il; ++i) { - length[nodes[i].index] = codeLength[i]; - } - - return length; -}; - -/** - * Reverse Package Merge Algorithm. - * @param {!(Array.|Uint32Array)} freqs sorted probability. - * @param {number} symbols number of symbols. - * @param {number} limit code length limit. - * @return {!(Array.|Uint8Array)} code lengths. - */ -Zlib.RawDeflate.prototype.reversePackageMerge_ = function(freqs, symbols, limit) { - /** @type {!(Array.|Uint16Array)} */ - var minimumCost = new (Uint16Array )(limit); - /** @type {!(Array.|Uint8Array)} */ - var flag = new (Uint8Array )(limit); - /** @type {!(Array.|Uint8Array)} */ - var codeLength = new (Uint8Array )(symbols); - /** @type {Array} */ - var value = new Array(limit); - /** @type {Array} */ - var type = new Array(limit); - /** @type {Array.} */ - var currentPosition = new Array(limit); - /** @type {number} */ - var excess = (1 << limit) - symbols; - /** @type {number} */ - var half = (1 << (limit - 1)); - /** @type {number} */ - var i; - /** @type {number} */ - var j; - /** @type {number} */ - var t; - /** @type {number} */ - var weight; - /** @type {number} */ - var next; - - /** - * @param {number} j - */ - function takePackage(j) { - /** @type {number} */ - var x = type[j][currentPosition[j]]; - - if (x === symbols) { - takePackage(j+1); - takePackage(j+1); - } else { - --codeLength[x]; - } - - ++currentPosition[j]; - } - - minimumCost[limit-1] = symbols; - - for (j = 0; j < limit; ++j) { - if (excess < half) { - flag[j] = 0; - } else { - flag[j] = 1; - excess -= half; - } - excess <<= 1; - minimumCost[limit-2-j] = (minimumCost[limit-1-j] / 2 | 0) + symbols; - } - minimumCost[0] = flag[0]; - - value[0] = new Array(minimumCost[0]); - type[0] = new Array(minimumCost[0]); - for (j = 1; j < limit; ++j) { - if (minimumCost[j] > 2 * minimumCost[j-1] + flag[j]) { - minimumCost[j] = 2 * minimumCost[j-1] + flag[j]; - } - value[j] = new Array(minimumCost[j]); - type[j] = new Array(minimumCost[j]); - } - - for (i = 0; i < symbols; ++i) { - codeLength[i] = limit; - } - - for (t = 0; t < minimumCost[limit-1]; ++t) { - value[limit-1][t] = freqs[t]; - type[limit-1][t] = t; - } - - for (i = 0; i < limit; ++i) { - currentPosition[i] = 0; - } - if (flag[limit-1] === 1) { - --codeLength[0]; - ++currentPosition[limit-1]; - } - - for (j = limit-2; j >= 0; --j) { - i = 0; - weight = 0; - next = currentPosition[j+1]; - - for (t = 0; t < minimumCost[j]; t++) { - weight = value[j+1][next] + value[j+1][next+1]; - - if (weight > freqs[i]) { - value[j][t] = weight; - type[j][t] = symbols; - next += 2; - } else { - value[j][t] = freqs[i]; - type[j][t] = i; - ++i; - } - } - - currentPosition[j] = 0; - if (flag[j] === 1) { - takePackage(j); - } - } - - return codeLength; -}; - -/** - * 符号長配列からハフマン符号を取得する - * reference: PuTTY Deflate implementation - * @param {!(Array.|Uint8Array)} lengths 符号長配列. - * @return {!(Array.|Uint16Array)} ハフマン符号配列. - * @private - */ -Zlib.RawDeflate.prototype.getCodesFromLengths_ = function(lengths) { - var codes = new (Uint16Array )(lengths.length), - count = [], - startCode = [], - code = 0, i, il, j, m; - - // Count the codes of each length. - for (i = 0, il = lengths.length; i < il; i++) { - count[lengths[i]] = (count[lengths[i]] | 0) + 1; - } - - // Determine the starting code for each length block. - for (i = 1, il = Zlib.RawDeflate.MaxCodeLength; i <= il; i++) { - startCode[i] = code; - code += count[i] | 0; - code <<= 1; - } - - // Determine the code for each symbol. Mirrored, of course. - for (i = 0, il = lengths.length; i < il; i++) { - code = startCode[lengths[i]]; - startCode[lengths[i]] += 1; - codes[i] = 0; - - for (j = 0, m = lengths[i]; j < m; j++) { - codes[i] = (codes[i] << 1) | (code & 1); - code >>>= 1; - } - } - - return codes; -}; - - -/** - * @param {!(Array.|Uint8Array)} input input buffer. - * @param {Object=} opt_params options. - * @constructor - */ -Zlib.Unzip = function(input, opt_params) { - opt_params = opt_params || {}; - /** @type {!(Array.|Uint8Array)} */ - this.input = - ((input instanceof Array)) ? - new Uint8Array(input) : input; - /** @type {number} */ - this.ip = 0; - /** @type {number} */ - this.eocdrOffset; - /** @type {number} */ - this.numberOfThisDisk; - /** @type {number} */ - this.startDisk; - /** @type {number} */ - this.totalEntriesThisDisk; - /** @type {number} */ - this.totalEntries; - /** @type {number} */ - this.centralDirectorySize; - /** @type {number} */ - this.centralDirectoryOffset; - /** @type {number} */ - this.commentLength; - /** @type {(Array.|Uint8Array)} */ - this.comment; - /** @type {Array.} */ - this.fileHeaderList; - /** @type {Object.} */ - this.filenameToIndex; - /** @type {boolean} */ - this.verify = opt_params['verify'] || false; - /** @type {(Array.|Uint8Array)} */ - this.password = opt_params['password']; -}; - -Zlib.Unzip.CompressionMethod = Zlib.Zip.CompressionMethod; - -/** - * @type {Array.} - * @const - */ -Zlib.Unzip.FileHeaderSignature = Zlib.Zip.FileHeaderSignature; - -/** - * @type {Array.} - * @const - */ -Zlib.Unzip.LocalFileHeaderSignature = Zlib.Zip.LocalFileHeaderSignature; - -/** - * @type {Array.} - * @const - */ -Zlib.Unzip.CentralDirectorySignature = Zlib.Zip.CentralDirectorySignature; - -/** - * @param {!(Array.|Uint8Array)} input input buffer. - * @param {number} ip input position. - * @constructor - */ -Zlib.Unzip.FileHeader = function(input, ip) { - /** @type {!(Array.|Uint8Array)} */ - this.input = input; - /** @type {number} */ - this.offset = ip; - /** @type {number} */ - this.length; - /** @type {number} */ - this.version; - /** @type {number} */ - this.os; - /** @type {number} */ - this.needVersion; - /** @type {number} */ - this.flags; - /** @type {number} */ - this.compression; - /** @type {number} */ - this.time; - /** @type {number} */ - this.date; - /** @type {number} */ - this.crc32; - /** @type {number} */ - this.compressedSize; - /** @type {number} */ - this.plainSize; - /** @type {number} */ - this.fileNameLength; - /** @type {number} */ - this.extraFieldLength; - /** @type {number} */ - this.fileCommentLength; - /** @type {number} */ - this.diskNumberStart; - /** @type {number} */ - this.internalFileAttributes; - /** @type {number} */ - this.externalFileAttributes; - /** @type {number} */ - this.relativeOffset; - /** @type {string} */ - this.filename; - /** @type {!(Array.|Uint8Array)} */ - this.extraField; - /** @type {!(Array.|Uint8Array)} */ - this.comment; -}; - -Zlib.Unzip.FileHeader.prototype.parse = function() { - /** @type {!(Array.|Uint8Array)} */ - var input = this.input; - /** @type {number} */ - var ip = this.offset; - - // central file header signature - if (input[ip++] !== Zlib.Unzip.FileHeaderSignature[0] || - input[ip++] !== Zlib.Unzip.FileHeaderSignature[1] || - input[ip++] !== Zlib.Unzip.FileHeaderSignature[2] || - input[ip++] !== Zlib.Unzip.FileHeaderSignature[3]) { - throw new Error('invalid file header signature'); - } - - // version made by - this.version = input[ip++]; - this.os = input[ip++]; - - // version needed to extract - this.needVersion = input[ip++] | (input[ip++] << 8); - - // general purpose bit flag - this.flags = input[ip++] | (input[ip++] << 8); - - // compression method - this.compression = input[ip++] | (input[ip++] << 8); - - // last mod file time - this.time = input[ip++] | (input[ip++] << 8); - - //last mod file date - this.date = input[ip++] | (input[ip++] << 8); - - // crc-32 - this.crc32 = ( - (input[ip++] ) | (input[ip++] << 8) | - (input[ip++] << 16) | (input[ip++] << 24) - ) >>> 0; - - // compressed size - this.compressedSize = ( - (input[ip++] ) | (input[ip++] << 8) | - (input[ip++] << 16) | (input[ip++] << 24) - ) >>> 0; - - // uncompressed size - this.plainSize = ( - (input[ip++] ) | (input[ip++] << 8) | - (input[ip++] << 16) | (input[ip++] << 24) - ) >>> 0; - - // file name length - this.fileNameLength = input[ip++] | (input[ip++] << 8); - - // extra field length - this.extraFieldLength = input[ip++] | (input[ip++] << 8); - - // file comment length - this.fileCommentLength = input[ip++] | (input[ip++] << 8); - - // disk number start - this.diskNumberStart = input[ip++] | (input[ip++] << 8); - - // internal file attributes - this.internalFileAttributes = input[ip++] | (input[ip++] << 8); - - // external file attributes - this.externalFileAttributes = - (input[ip++] ) | (input[ip++] << 8) | - (input[ip++] << 16) | (input[ip++] << 24); - - // relative offset of local header - this.relativeOffset = ( - (input[ip++] ) | (input[ip++] << 8) | - (input[ip++] << 16) | (input[ip++] << 24) - ) >>> 0; - - // file name - this.filename = String.fromCharCode.apply(null, input.subarray(ip, ip += this.fileNameLength) - ); - - // extra field - this.extraField = input.subarray(ip, ip += this.extraFieldLength) ; - - // file comment - this.comment = input.subarray(ip, ip + this.fileCommentLength) ; - - this.length = ip - this.offset; -}; - -/** - * @param {!(Array.|Uint8Array)} input input buffer. - * @param {number} ip input position. - * @constructor - */ -Zlib.Unzip.LocalFileHeader = function(input, ip) { - /** @type {!(Array.|Uint8Array)} */ - this.input = input; - /** @type {number} */ - this.offset = ip; - /** @type {number} */ - this.length; - /** @type {number} */ - this.needVersion; - /** @type {number} */ - this.flags; - /** @type {number} */ - this.compression; - /** @type {number} */ - this.time; - /** @type {number} */ - this.date; - /** @type {number} */ - this.crc32; - /** @type {number} */ - this.compressedSize; - /** @type {number} */ - this.plainSize; - /** @type {number} */ - this.fileNameLength; - /** @type {number} */ - this.extraFieldLength; - /** @type {string} */ - this.filename; - /** @type {!(Array.|Uint8Array)} */ - this.extraField; -}; - -Zlib.Unzip.LocalFileHeader.Flags = Zlib.Zip.Flags; - -Zlib.Unzip.LocalFileHeader.prototype.parse = function() { - /** @type {!(Array.|Uint8Array)} */ - var input = this.input; - /** @type {number} */ - var ip = this.offset; - - // local file header signature - if (input[ip++] !== Zlib.Unzip.LocalFileHeaderSignature[0] || - input[ip++] !== Zlib.Unzip.LocalFileHeaderSignature[1] || - input[ip++] !== Zlib.Unzip.LocalFileHeaderSignature[2] || - input[ip++] !== Zlib.Unzip.LocalFileHeaderSignature[3]) { - throw new Error('invalid local file header signature'); - } - - // version needed to extract - this.needVersion = input[ip++] | (input[ip++] << 8); - - // general purpose bit flag - this.flags = input[ip++] | (input[ip++] << 8); - - // compression method - this.compression = input[ip++] | (input[ip++] << 8); - - // last mod file time - this.time = input[ip++] | (input[ip++] << 8); - - //last mod file date - this.date = input[ip++] | (input[ip++] << 8); - - // crc-32 - this.crc32 = ( - (input[ip++] ) | (input[ip++] << 8) | - (input[ip++] << 16) | (input[ip++] << 24) - ) >>> 0; - - // compressed size - this.compressedSize = ( - (input[ip++] ) | (input[ip++] << 8) | - (input[ip++] << 16) | (input[ip++] << 24) - ) >>> 0; - - // uncompressed size - this.plainSize = ( - (input[ip++] ) | (input[ip++] << 8) | - (input[ip++] << 16) | (input[ip++] << 24) - ) >>> 0; - - // file name length - this.fileNameLength = input[ip++] | (input[ip++] << 8); - - // extra field length - this.extraFieldLength = input[ip++] | (input[ip++] << 8); - - // file name - this.filename = String.fromCharCode.apply(null, input.subarray(ip, ip += this.fileNameLength) - ); - - // extra field - this.extraField = input.subarray(ip, ip += this.extraFieldLength) ; - - this.length = ip - this.offset; -}; - - -Zlib.Unzip.prototype.searchEndOfCentralDirectoryRecord = function() { - /** @type {!(Array.|Uint8Array)} */ - var input = this.input; - /** @type {number} */ - var ip; - - for (ip = input.length - 12; ip > 0; --ip) { - if (input[ip ] === Zlib.Unzip.CentralDirectorySignature[0] && - input[ip+1] === Zlib.Unzip.CentralDirectorySignature[1] && - input[ip+2] === Zlib.Unzip.CentralDirectorySignature[2] && - input[ip+3] === Zlib.Unzip.CentralDirectorySignature[3]) { - this.eocdrOffset = ip; - return; - } - } - - throw new Error('End of Central Directory Record not found'); -}; - -Zlib.Unzip.prototype.parseEndOfCentralDirectoryRecord = function() { - /** @type {!(Array.|Uint8Array)} */ - var input = this.input; - /** @type {number} */ - var ip; - - if (!this.eocdrOffset) { - this.searchEndOfCentralDirectoryRecord(); - } - ip = this.eocdrOffset; - - // signature - if (input[ip++] !== Zlib.Unzip.CentralDirectorySignature[0] || - input[ip++] !== Zlib.Unzip.CentralDirectorySignature[1] || - input[ip++] !== Zlib.Unzip.CentralDirectorySignature[2] || - input[ip++] !== Zlib.Unzip.CentralDirectorySignature[3]) { - throw new Error('invalid signature'); - } - - // number of this disk - this.numberOfThisDisk = input[ip++] | (input[ip++] << 8); - - // number of the disk with the start of the central directory - this.startDisk = input[ip++] | (input[ip++] << 8); - - // total number of entries in the central directory on this disk - this.totalEntriesThisDisk = input[ip++] | (input[ip++] << 8); - - // total number of entries in the central directory - this.totalEntries = input[ip++] | (input[ip++] << 8); - - // size of the central directory - this.centralDirectorySize = ( - (input[ip++] ) | (input[ip++] << 8) | - (input[ip++] << 16) | (input[ip++] << 24) - ) >>> 0; - - // offset of start of central directory with respect to the starting disk number - this.centralDirectoryOffset = ( - (input[ip++] ) | (input[ip++] << 8) | - (input[ip++] << 16) | (input[ip++] << 24) - ) >>> 0; - - // .ZIP file comment length - this.commentLength = input[ip++] | (input[ip++] << 8); - - // .ZIP file comment - this.comment = input.subarray(ip, ip + this.commentLength) ; -}; - -Zlib.Unzip.prototype.parseFileHeader = function() { - /** @type {Array.} */ - var filelist = []; - /** @type {Object.} */ - var filetable = {}; - /** @type {number} */ - var ip; - /** @type {Zlib.Unzip.FileHeader} */ - var fileHeader; - /*: @type {number} */ - var i; - /*: @type {number} */ - var il; - - if (this.fileHeaderList) { - return; - } - - if (this.centralDirectoryOffset === void 0) { - this.parseEndOfCentralDirectoryRecord(); - } - ip = this.centralDirectoryOffset; - - for (i = 0, il = this.totalEntries; i < il; ++i) { - fileHeader = new Zlib.Unzip.FileHeader(this.input, ip); - fileHeader.parse(); - ip += fileHeader.length; - filelist[i] = fileHeader; - filetable[fileHeader.filename] = i; - } - - if (this.centralDirectorySize < ip - this.centralDirectoryOffset) { - throw new Error('invalid file header size'); - } - - this.fileHeaderList = filelist; - this.filenameToIndex = filetable; -}; - -/** - * @param {number} index file header index. - * @param {Object=} opt_params - * @return {!(Array.|Uint8Array)} file data. - */ -Zlib.Unzip.prototype.getFileData = function(index, opt_params) { - opt_params = opt_params || {}; - /** @type {!(Array.|Uint8Array)} */ - var input = this.input; - /** @type {Array.} */ - var fileHeaderList = this.fileHeaderList; - /** @type {Zlib.Unzip.LocalFileHeader} */ - var localFileHeader; - /** @type {number} */ - var offset; - /** @type {number} */ - var length; - /** @type {!(Array.|Uint8Array)} */ - var buffer; - /** @type {number} */ - var crc32; - /** @type {Array.|Uint32Array|Object} */ - var key; - /** @type {number} */ - var i; - /** @type {number} */ - var il; - - if (!fileHeaderList) { - this.parseFileHeader(); - } - - if (fileHeaderList[index] === void 0) { - throw new Error('wrong index'); - } - - offset = fileHeaderList[index].relativeOffset; - localFileHeader = new Zlib.Unzip.LocalFileHeader(this.input, offset); - localFileHeader.parse(); - offset += localFileHeader.length; - length = localFileHeader.compressedSize; - - // decryption - if ((localFileHeader.flags & Zlib.Unzip.LocalFileHeader.Flags.ENCRYPT) !== 0) { - if (!(opt_params['password'] || this.password)) { - throw new Error('please set password'); - } - key = this.createDecryptionKey(opt_params['password'] || this.password); - - // encryption header - for(i = offset, il = offset + 12; i < il; ++i) { - this.decode(key, input[i]); - } - offset += 12; - length -= 12; - - // decryption - for (i = offset, il = offset + length; i < il; ++i) { - input[i] = this.decode(key, input[i]); - } - } - - switch (localFileHeader.compression) { - case Zlib.Unzip.CompressionMethod.STORE: - buffer = this.input.subarray(offset, offset + length) ; - break; - case Zlib.Unzip.CompressionMethod.DEFLATE: - buffer = new Zlib.RawInflate(this.input, { - 'index': offset, - 'bufferSize': localFileHeader.plainSize - }).decompress(); - break; - default: - throw new Error('unknown compression type'); - } - - if (this.verify) { - crc32 = Zlib.CRC32.calc(buffer); - if (localFileHeader.crc32 !== crc32) { - throw new Error( - 'wrong crc: file=0x' + localFileHeader.crc32.toString(16) + - ', data=0x' + crc32.toString(16) - ); - } - } - - return buffer; -}; - -/** - * @return {Array.} - */ -Zlib.Unzip.prototype.getFilenames = function() { - /** @type {Array.} */ - var filenameList = []; - /** @type {number} */ - var i; - /** @type {number} */ - var il; - /** @type {Array.} */ - var fileHeaderList; - - if (!this.fileHeaderList) { - this.parseFileHeader(); - } - fileHeaderList = this.fileHeaderList; - - for (i = 0, il = fileHeaderList.length; i < il; ++i) { - filenameList[i] = fileHeaderList[i].filename; - } - - return filenameList; -}; - -/** - * @param {string} filename extract filename. - * @param {Object=} opt_params - * @return {!(Array.|Uint8Array)} decompressed data. - */ -Zlib.Unzip.prototype.decompress = function(filename, opt_params) { - /** @type {number} */ - var index; - - if (!this.filenameToIndex) { - this.parseFileHeader(); - } - index = this.filenameToIndex[filename]; - - if (index === void 0) { - throw new Error(filename + ' not found'); - } - - return this.getFileData(index, opt_params); -}; - -/** - * @param {(Array.|Uint8Array)} password - */ -Zlib.Unzip.prototype.setPassword = function(password) { - this.password = password; -}; - -/** - * @param {(Array.|Uint32Array|Object)} key - * @param {number} n - * @return {number} - */ -Zlib.Unzip.prototype.decode = function(key, n) { - n ^= this.getByte(/** @type {(Array.|Uint32Array)} */(key)); - this.updateKeys(/** @type {(Array.|Uint32Array)} */(key), n); - - return n; -}; - -// common method -Zlib.Unzip.prototype.updateKeys = Zlib.Zip.prototype.updateKeys; -Zlib.Unzip.prototype.createDecryptionKey = Zlib.Zip.prototype.createEncryptionKey; -Zlib.Unzip.prototype.getByte = Zlib.Zip.prototype.getByte; - -/** - * @fileoverview 雑多な関数群をまとめたモジュール実装. - */ - - -/** - * Byte String から Byte Array に変換. - * @param {!string} str byte string. - * @return {!Array.} byte array. - */ -Zlib.Util.stringToByteArray = function(str) { - /** @type {!Array.<(string|number)>} */ - var tmp = str.split(''); - /** @type {number} */ - var i; - /** @type {number} */ - var il; - - for (i = 0, il = tmp.length; i < il; i++) { - tmp[i] = (tmp[i].charCodeAt(0) & 0xff) >>> 0; - } - - return tmp; -}; - - -/** - * @fileoverview Adler32 checksum 実装. - */ - - -/** - * Adler32 ハッシュ値の作成 - * @param {!(Array|Uint8Array|string)} array 算出に使用する byte array. - * @return {number} Adler32 ハッシュ値. - */ -Zlib.Adler32 = function(array) { - if (typeof(array) === 'string') { - array = Zlib.Util.stringToByteArray(array); - } - return Zlib.Adler32.update(1, array); -}; - -/** - * Adler32 ハッシュ値の更新 - * @param {number} adler 現在のハッシュ値. - * @param {!(Array|Uint8Array)} array 更新に使用する byte array. - * @return {number} Adler32 ハッシュ値. - */ -Zlib.Adler32.update = function(adler, array) { - /** @type {number} */ - var s1 = adler & 0xffff; - /** @type {number} */ - var s2 = (adler >>> 16) & 0xffff; - /** @type {number} array length */ - var len = array.length; - /** @type {number} loop length (don't overflow) */ - var tlen; - /** @type {number} array index */ - var i = 0; - - while (len > 0) { - tlen = len > Zlib.Adler32.OptimizationParameter ? - Zlib.Adler32.OptimizationParameter : len; - len -= tlen; - do { - s1 += array[i++]; - s2 += s1; - } while (--tlen); - - s1 %= 65521; - s2 %= 65521; - } - - return ((s2 << 16) | s1) >>> 0; -}; - -/** - * Adler32 最適化パラメータ - * 現状では 1024 程度が最適. - * @see http://jsperf.com/adler-32-simple-vs-optimized/3 - * @define {number} - */ -Zlib.Adler32.OptimizationParameter = 1024; - - - - -/** - * ビットストリーム - * @constructor - * @param {!(Array|Uint8Array)=} buffer output buffer. - * @param {number=} bufferPosition start buffer pointer. - */ -Zlib.BitStream = function(buffer, bufferPosition) { - /** @type {number} buffer index. */ - this.index = typeof bufferPosition === 'number' ? bufferPosition : 0; - /** @type {number} bit index. */ - this.bitindex = 0; - /** @type {!(Array|Uint8Array)} bit-stream output buffer. */ - this.buffer = buffer instanceof (Uint8Array ) ? - buffer : - new (Uint8Array )(Zlib.BitStream.DefaultBlockSize); - - // 入力された index が足りなかったら拡張するが、倍にしてもダメなら不正とする - if (this.buffer.length * 2 <= this.index) { - throw new Error("invalid index"); - } else if (this.buffer.length <= this.index) { - this.expandBuffer(); - } -}; - -/** - * デフォルトブロックサイズ. - * @const - * @type {number} - */ -Zlib.BitStream.DefaultBlockSize = 0x8000; - -/** - * expand buffer. - * @return {!(Array|Uint8Array)} new buffer. - */ -Zlib.BitStream.prototype.expandBuffer = function() { - /** @type {!(Array|Uint8Array)} old buffer. */ - var oldbuf = this.buffer; - /** @type {number} loop limiter. */ - var il = oldbuf.length; - /** @type {!(Array|Uint8Array)} new buffer. */ - var buffer = - new (Uint8Array )(il << 1); - - // copy buffer - { - buffer.set(oldbuf); - } - - return (this.buffer = buffer); -}; - - -/** - * 数値をビットで指定した数だけ書き込む. - * @param {number} number 書き込む数値. - * @param {number} n 書き込むビット数. - * @param {boolean=} reverse 逆順に書き込むならば true. - */ -Zlib.BitStream.prototype.writeBits = function(number, n, reverse) { - var buffer = this.buffer; - var index = this.index; - var bitindex = this.bitindex; - - /** @type {number} current octet. */ - var current = buffer[index]; - /** @type {number} loop counter. */ - var i; - - /** - * 32-bit 整数のビット順を逆にする - * @param {number} n 32-bit integer. - * @return {number} reversed 32-bit integer. - * @private - */ - function rev32_(n) { - return (Zlib.BitStream.ReverseTable[n & 0xFF] << 24) | - (Zlib.BitStream.ReverseTable[n >>> 8 & 0xFF] << 16) | - (Zlib.BitStream.ReverseTable[n >>> 16 & 0xFF] << 8) | - Zlib.BitStream.ReverseTable[n >>> 24 & 0xFF]; - } - - if (reverse && n > 1) { - number = n > 8 ? - rev32_(number) >> (32 - n) : - Zlib.BitStream.ReverseTable[number] >> (8 - n); - } - - // Byte 境界を超えないとき - if (n + bitindex < 8) { - current = (current << n) | number; - bitindex += n; - // Byte 境界を超えるとき - } else { - for (i = 0; i < n; ++i) { - current = (current << 1) | ((number >> n - i - 1) & 1); - - // next byte - if (++bitindex === 8) { - bitindex = 0; - buffer[index++] = Zlib.BitStream.ReverseTable[current]; - current = 0; - - // expand - if (index === buffer.length) { - buffer = this.expandBuffer(); - } - } - } - } - buffer[index] = current; - - this.buffer = buffer; - this.bitindex = bitindex; - this.index = index; -}; - - -/** - * ストリームの終端処理を行う - * @return {!(Array|Uint8Array)} 終端処理後のバッファを byte array で返す. - */ -Zlib.BitStream.prototype.finish = function() { - var buffer = this.buffer; - var index = this.index; - - /** @type {!(Array|Uint8Array)} output buffer. */ - var output; - - // bitindex が 0 の時は余分に index が進んでいる状態 - if (this.bitindex > 0) { - buffer[index] <<= 8 - this.bitindex; - buffer[index] = Zlib.BitStream.ReverseTable[buffer[index]]; - index++; - } - - // array truncation - { - output = buffer.subarray(0, index); - } - - return output; -}; - -/** - * 0-255 のビット順を反転したテーブル - * @const - * @type {!(Uint8Array|Array.)} - */ -Zlib.BitStream.ReverseTable = (function(table) { - return table; -})((function() { - /** @type {!(Array|Uint8Array)} reverse table. */ - var table = new (Uint8Array )(256); - /** @type {number} loop counter. */ - var i; - - // generate - for (i = 0; i < 256; ++i) { - table[i] = (function(n) { - var r = n; - var s = 7; - - for (n >>>= 1; n; n >>>= 1) { - r <<= 1; - r |= n & 1; - --s; - } - - return (r << s & 0xff) >>> 0; - })(i); - } - - return table; -})()); - -/** - * CRC32 ハッシュ値を取得 - * @param {!(Array.|Uint8Array)} data data byte array. - * @param {number=} pos data position. - * @param {number=} length data length. - * @return {number} CRC32. - */ -Zlib.CRC32.calc = function(data, pos, length) { - return Zlib.CRC32.update(data, 0, pos, length); -}; - -/** - * CRC32ハッシュ値を更新 - * @param {!(Array.|Uint8Array)} data data byte array. - * @param {number} crc CRC32. - * @param {number=} pos data position. - * @param {number=} length data length. - * @return {number} CRC32. - */ -Zlib.CRC32.update = function(data, crc, pos, length) { - var table = Zlib.CRC32.Table; - var i = (typeof pos === 'number') ? pos : (pos = 0); - var il = (typeof length === 'number') ? length : data.length; - - crc ^= 0xffffffff; - - // loop unrolling for performance - for (i = il & 7; i--; ++pos) { - crc = (crc >>> 8) ^ table[(crc ^ data[pos]) & 0xff]; - } - for (i = il >> 3; i--; pos += 8) { - crc = (crc >>> 8) ^ table[(crc ^ data[pos ]) & 0xff]; - crc = (crc >>> 8) ^ table[(crc ^ data[pos + 1]) & 0xff]; - crc = (crc >>> 8) ^ table[(crc ^ data[pos + 2]) & 0xff]; - crc = (crc >>> 8) ^ table[(crc ^ data[pos + 3]) & 0xff]; - crc = (crc >>> 8) ^ table[(crc ^ data[pos + 4]) & 0xff]; - crc = (crc >>> 8) ^ table[(crc ^ data[pos + 5]) & 0xff]; - crc = (crc >>> 8) ^ table[(crc ^ data[pos + 6]) & 0xff]; - crc = (crc >>> 8) ^ table[(crc ^ data[pos + 7]) & 0xff]; - } - - return (crc ^ 0xffffffff) >>> 0; -}; - -/** - * @param {number} num - * @param {number} crc - * @returns {number} - */ -Zlib.CRC32.single = function(num, crc) { - return (Zlib.CRC32.Table[(num ^ crc) & 0xff] ^ (num >>> 8)) >>> 0; -}; - -/** - * @type {Array.} - * @const - * @private - */ -Zlib.CRC32.Table_ = [ - 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, - 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, - 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2, - 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, - 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, - 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, - 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c, - 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, - 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, - 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, - 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106, - 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, - 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, - 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, - 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, - 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, - 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, - 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, - 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, - 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, - 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, - 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, - 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84, - 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, - 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, - 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, - 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e, - 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, - 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, - 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, - 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, - 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, - 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, - 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, - 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, - 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, - 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, - 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, - 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, - 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, - 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, - 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, - 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d -]; - -/** - * @type {!(Array.|Uint32Array)} CRC-32 Table. - * @const - */ -Zlib.CRC32.Table = new Uint32Array(Zlib.CRC32.Table_) ; - -/** - * @fileoverview Deflate (RFC1951) 実装. - * Deflateアルゴリズム本体は Zlib.RawDeflate で実装されている. - */ - -/** - * Zlib Deflate - * @constructor - * @param {!(Array|Uint8Array)} input 符号化する対象の byte array. - * @param {Object=} opt_params option parameters. - */ -Zlib.Deflate = function(input, opt_params) { - /** @type {!(Array|Uint8Array)} */ - this.input = input; - /** @type {!(Array|Uint8Array)} */ - this.output = - new (Uint8Array )(Zlib.Deflate.DefaultBufferSize); - /** @type {Zlib.Deflate.CompressionType} */ - this.compressionType = Zlib.Deflate.CompressionType.DYNAMIC; - /** @type {Zlib.RawDeflate} */ - this.rawDeflate; - /** @type {Object} */ - var rawDeflateOption = {}; - /** @type {string} */ - var prop; - - // option parameters - if (opt_params || !(opt_params = {})) { - if (typeof opt_params['compressionType'] === 'number') { - this.compressionType = opt_params['compressionType']; - } - } - - // copy options - for (prop in opt_params) { - rawDeflateOption[prop] = opt_params[prop]; - } - - // set raw-deflate output buffer - rawDeflateOption['outputBuffer'] = this.output; - - this.rawDeflate = new Zlib.RawDeflate(this.input, rawDeflateOption); -}; - -/** - * @const - * @type {number} デフォルトバッファサイズ. - */ -Zlib.Deflate.DefaultBufferSize = 0x8000; - -/** - * @enum {number} - */ -Zlib.Deflate.CompressionType = Zlib.RawDeflate.CompressionType; - -/** - * 直接圧縮に掛ける. - * @param {!(Array|Uint8Array)} input target buffer. - * @param {Object=} opt_params option parameters. - * @return {!(Array|Uint8Array)} compressed data byte array. - */ -Zlib.Deflate.compress = function(input, opt_params) { - return (new Zlib.Deflate(input, opt_params)).compress(); -}; - -/** - * Deflate Compression. - * @return {!(Array|Uint8Array)} compressed data byte array. - */ -Zlib.Deflate.prototype.compress = function() { - /** @type {Zlib.CompressionMethod} */ - var cm; - /** @type {number} */ - var cinfo; - /** @type {number} */ - var cmf; - /** @type {number} */ - var flg; - /** @type {number} */ - var fcheck; - /** @type {number} */ - var fdict; - /** @type {number} */ - var flevel; - /** @type {number} */ - var adler; - /** @type {!(Array|Uint8Array)} */ - var output; - /** @type {number} */ - var pos = 0; - - output = this.output; - - // Compression Method and Flags - cm = Zlib.CompressionMethod.DEFLATE; - switch (cm) { - case Zlib.CompressionMethod.DEFLATE: - cinfo = Math.LOG2E * Math.log(Zlib.RawDeflate.WindowSize) - 8; - break; - default: - throw new Error('invalid compression method'); - } - cmf = (cinfo << 4) | cm; - output[pos++] = cmf; - - // Flags - fdict = 0; - switch (cm) { - case Zlib.CompressionMethod.DEFLATE: - switch (this.compressionType) { - case Zlib.Deflate.CompressionType.NONE: flevel = 0; break; - case Zlib.Deflate.CompressionType.FIXED: flevel = 1; break; - case Zlib.Deflate.CompressionType.DYNAMIC: flevel = 2; break; - default: throw new Error('unsupported compression type'); - } - break; - default: - throw new Error('invalid compression method'); - } - flg = (flevel << 6) | (fdict << 5); - fcheck = 31 - (cmf * 256 + flg) % 31; - flg |= fcheck; - output[pos++] = flg; - - // Adler-32 checksum - adler = Zlib.Adler32(this.input); - - this.rawDeflate.op = pos; - output = this.rawDeflate.compress(); - pos = output.length; - - { - // subarray 分を元にもどす - output = new Uint8Array(output.buffer); - // expand buffer - if (output.length <= pos + 4) { - this.output = new Uint8Array(output.length + 4); - this.output.set(output); - output = this.output; - } - output = output.subarray(0, pos + 4); - } - - // adler32 - output[pos++] = (adler >> 24) & 0xff; - output[pos++] = (adler >> 16) & 0xff; - output[pos++] = (adler >> 8) & 0xff; - output[pos++] = (adler ) & 0xff; - - return output; -}; - -class BrowserLocalFile { - - constructor(blob) { - this.file = blob; - } - - async read(position, length) { - const file = this.file; - if (position !== undefined) { - return file.slice(position, position + length).arrayBuffer() - - } else { - return file.arrayBuffer() - - } - } -} - -typeof process !== 'undefined' && process.versions != null && process.versions.node != null; - -class RemoteFile { - - constructor(args) { - this.config = args; - this.url = mapUrl(args.path || args.url); - } - - - async read(position, length) { - - length = Math.ceil(length); - const headers = this.config.headers || {}; - const rangeString = "bytes=" + position + "-" + (position + length - 1); - headers['Range'] = rangeString; - - let url = this.url.slice(); // slice => copy - // headers['User-Agent'] = 'straw' - if (this.config.oauthToken) { - const token = resolveToken(this.config.oauthToken); - headers['Authorization'] = `Bearer ${token}`; - } - if (this.config.apiKey) { - url = addParameter(url, "key", this.config.apiKey); - } - - const response = await fetch(url, { - method: 'GET', - headers: headers, - redirect: 'follow', - mode: 'cors', - - }); - - const status = response.status; - - if (status >= 400) { - console.error(`${status} ${this.config.url}`); - const err = Error(response.statusText); - err.code = status; - throw err - } else { - return response.arrayBuffer() - } - - /** - * token can be a string, a function that returns a string, or a function that returns a Promise for a string - * @param token - * @returns {Promise<*>} - */ - async function resolveToken(token) { - if (typeof token === 'function') { - return await Promise.resolve(token()) // Normalize the result to a promise, since we don't know what the function returns - } else { - return token - } - } - - } -} - - -function mapUrl(url) { - - if (url.includes("//www.dropbox.com")) { - return url.replace("//www.dropbox.com", "//dl.dropboxusercontent.com") - } else if (url.startsWith("ftp://ftp.ncbi.nlm.nih.gov")) { - return url.replace("ftp://", "https://") - } else { - return url - } -} - - -function addParameter(url, name, value) { - const paramSeparator = url.includes("?") ? "&" : "?"; - return url + paramSeparator + name + "=" + value -} - -class ThrottledFile { - - constructor(file, rateLimiter) { - this.file = file; - this.rateLimiter = rateLimiter; - } - - - async read(position, length) { - - const file = this.file; - const rateLimiter = this.rateLimiter; - - return new Promise(function (fulfill, reject) { - rateLimiter.limiter(async function (f) { - try { - const result = await f.read(position, length); - fulfill(result); - } catch (e) { - reject(e); - } - })(file); - }) - } -} - -class RateLimiter { - - constructor(wait) { - this.wait = wait === undefined ? 100 : wait; - - this.isCalled = false; - this.calls = []; - } - - - limiter(fn) { - - const self = this; - - let caller = function () { - - if (self.calls.length && !self.isCalled) { - self.isCalled = true; - self.calls.shift().call(); - setTimeout(function () { - self.isCalled = false; - caller(); - }, self.wait); - } - }; - - return function () { - self.calls.push(fn.bind(this, ...arguments)); - caller(); - }; - } - -} - -class BufferedFile { - - constructor(args) { - this.file = args.file; - this.size = args.size || 64000; - this.position = 0; - this.bufferStart = 0; - this.bufferLength = 0; - this.buffer = undefined; - } - - - async read(position, length) { - - const start = position; - const end = position + length; - const bufferStart = this.bufferStart; - const bufferEnd = this.bufferStart + this.bufferLength; - - - if (length > this.size) { - // Request larger than max buffer size, pass through to underlying file - //console.log("0") - this.buffer = undefined; - this.bufferStart = 0; - this.bufferLength = 0; - return this.file.read(position, length) - } - - if (start >= bufferStart && end <= bufferEnd) { - // Request within buffer bounds - //console.log("1") - const sliceStart = start - bufferStart; - const sliceEnd = sliceStart + length; - return this.buffer.slice(sliceStart, sliceEnd) - } - - else if (start < bufferStart && end > bufferStart) { - // Overlap left, here for completness but this is an unexpected case in straw. We don't adjust the buffer. - //console.log("2") - const l1 = bufferStart - start; - const a1 = await this.file.read(position, l1); - const l2 = length - l1; - if (l2 > 0) { - //this.buffer = await this.file.read(bufferStart, this.size) - const a2 = this.buffer.slice(0, l2); - return concatBuffers(a1, a2) - } else { - return a1 - } - - } - - else if (start < bufferEnd && end > bufferEnd) { - // Overlap right - // console.log("3") - const l1 = bufferEnd - start; - const sliceStart = this.bufferLength - l1; - const a1 = this.buffer.slice(sliceStart, this.bufferLength); - - const l2 = length - l1; - if (l2 > 0) { - try { - this.buffer = await this.file.read(bufferEnd, this.size); - this.bufferStart = bufferEnd; - this.bufferLength = this.buffer.byteLength; - const a2 = this.buffer.slice(0, l2); - return concatBuffers(a1, a2) - } catch (e) { - // A "unsatisfiable range" error is expected here if we overlap past the end of file - if (e.code && e.code === 416) { - return a1 - } - else { - throw e - } - } - - } else { - return a1 - } - - } - - else { - // No overlap with buffer - // console.log("4") - this.buffer = await this.file.read(position, this.size); - this.bufferStart = position; - this.bufferLength = this.buffer.byteLength; - return this.buffer.slice(0, length) - } - - } - -} - -/** - * concatenates 2 array buffers. - * Credit: https://gist.github.com/72lions/4528834 - * - * @private - * @param {ArrayBuffers} buffer1 The first buffer. - * @param {ArrayBuffers} buffer2 The second buffer. - * @return {ArrayBuffers} The new ArrayBuffer created out of the two. - */ -var concatBuffers = function (buffer1, buffer2) { - var tmp = new Uint8Array(buffer1.byteLength + buffer2.byteLength); - tmp.set(new Uint8Array(buffer1), 0); - tmp.set(new Uint8Array(buffer2), buffer1.byteLength); - return tmp.buffer; -}; - -// TODO -- big endian - -const BinaryParser = function (dataView, littleEndian) { - - this.littleEndian = littleEndian !== undefined ? littleEndian : true; - this.position = 0; - this.view = dataView; - this.length = dataView.byteLength; -}; - -BinaryParser.prototype.available = function () { - return this.length - this.position; -}; - -BinaryParser.prototype.remLength = function () { - return this.length - this.position; -}; - -BinaryParser.prototype.hasNext = function () { - return this.position < this.length - 1; -}; - -BinaryParser.prototype.getByte = function () { - var retValue = this.view.getUint8(this.position, this.littleEndian); - this.position++; - return retValue; -}; - -BinaryParser.prototype.getShort = function () { - - var retValue = this.view.getInt16(this.position, this.littleEndian); - this.position += 2; - return retValue; -}; - -BinaryParser.prototype.getUShort = function () { - - // var byte1 = this.getByte(), - // byte2 = this.getByte(), - // retValue = ((byte2 << 24 >>> 16) + (byte1 << 24 >>> 24)); - // return retValue; - - // - var retValue = this.view.getUint16(this.position, this.littleEndian); - this.position += 2; - return retValue; -}; - - -BinaryParser.prototype.getInt = function () { - - var retValue = this.view.getInt32(this.position, this.littleEndian); - this.position += 4; - return retValue; -}; - - -BinaryParser.prototype.getUInt = function () { - var retValue = this.view.getUint32(this.position, this.littleEndian); - this.position += 4; - return retValue; -}; - -BinaryParser.prototype.getLong = function () { - - // DataView doesn't support long. So we'll try manually - - var b = []; - b[0] = this.view.getUint8(this.position); - b[1] = this.view.getUint8(this.position + 1); - b[2] = this.view.getUint8(this.position + 2); - b[3] = this.view.getUint8(this.position + 3); - b[4] = this.view.getUint8(this.position + 4); - b[5] = this.view.getUint8(this.position + 5); - b[6] = this.view.getUint8(this.position + 6); - b[7] = this.view.getUint8(this.position + 7); - - var value = 0; - if (this.littleEndian) { - for (var i = b.length - 1; i >= 0; i--) { - value = (value * 256) + b[i]; - } - } else { - for (var i = 0; i < b.length; i++) { - value = (value * 256) + b[i]; - } - } - - - this.position += 8; - return value; -}; - -BinaryParser.prototype.getString = function (len) { - - var s = ""; - var c; - while ((c = this.view.getUint8(this.position++)) != 0) { - s += String.fromCharCode(c); - if (len && s.length == len) break; - } - return s; -}; - -BinaryParser.prototype.getFixedLengthString = function (len) { - - var s = ""; - var i; - var c; - for (i = 0; i < len; i++) { - c = this.view.getUint8(this.position++); - if (c > 0) { - s += String.fromCharCode(c); - } - } - return s; -}; - -BinaryParser.prototype.getFixedLengthTrimmedString = function (len) { - - var s = ""; - var i; - var c; - for (i = 0; i < len; i++) { - c = this.view.getUint8(this.position++); - if (c > 32) { - s += String.fromCharCode(c); - } - } - return s; -}; - -BinaryParser.prototype.getFloat = function () { - - var retValue = this.view.getFloat32(this.position, this.littleEndian); - this.position += 4; - return retValue; - - -}; - -BinaryParser.prototype.getDouble = function () { - - var retValue = this.view.getFloat64(this.position, this.littleEndian); - this.position += 8; - return retValue; -}; - -BinaryParser.prototype.skip = function (n) { - - this.position += n; - return this.position; -}; - - -/** - * Return a bgzip (bam and tabix) virtual pointer - * TODO -- why isn't 8th byte used ? - * @returns {*} - */ -BinaryParser.prototype.getVPointer = function () { - - var position = this.position, - offset = (this.view.getUint8(position + 1) << 8) | (this.view.getUint8(position)), - byte6 = ((this.view.getUint8(position + 6) & 0xff) * 0x100000000), - byte5 = ((this.view.getUint8(position + 5) & 0xff) * 0x1000000), - byte4 = ((this.view.getUint8(position + 4) & 0xff) * 0x10000), - byte3 = ((this.view.getUint8(position + 3) & 0xff) * 0x100), - byte2 = ((this.view.getUint8(position + 2) & 0xff)), - block = byte6 + byte5 + byte4 + byte3 + byte2; - this.position += 8; - - // if (block == 0 && offset == 0) { - // return null; - // } else { - return new VPointer(block, offset); - // } -}; - - -function VPointer(block, offset) { - this.block = block; - this.offset = offset; -} - -VPointer.prototype.isLessThan = function (vp) { - return this.block < vp.block || - (this.block === vp.block && this.offset < vp.offset); -}; - -VPointer.prototype.isGreaterThan = function (vp) { - return this.block > vp.block || - (this.block === vp.block && this.offset > vp.offset); -}; - -VPointer.prototype.print = function () { - return "" + this.block + ":" + this.offset; -}; - -class MatrixZoomData { - - constructor(chr1, chr2) { - - this.chr1 = chr1; // chromosome index - this.chr2 = chr2; - } - - getKey () { - return this.chr1.name + "_" + this.chr2.name + "_" + this.zoom.unit + "_" + this.zoom.binSize; - } - - getBlockNumbers(region1, region2, version) { - - // Verify region chromosomes and swap if neccessary - if(region1.chr == this.chr2 && region2.chr === this.chr1) { - const tmp = region1; - region1 = region2; - region2 = tmp; - } - - const sameChr = this.chr1 === this.chr2; - const binsize = this.zoom.binSize; - const blockBinCount = this.blockBinCount; - const blockColumnCount = this.blockColumnCount; - return (version < 9 || !sameChr) ? getBlockNumbersV8() : getBlockNumbersV9(); - - function getBlockNumbersV8() - { - const x1 = region1.start / binsize; - const x2 = region1.end / binsize; - const y1 = region2.start / binsize; - const y2 = region2.end / binsize; - - const col1 = Math.floor(x1 / blockBinCount); - const col2 = Math.floor((x2 - 1) / blockBinCount); - const row1 = Math.floor(y1 / blockBinCount); - const row2 = Math.floor((y2 - 1) / blockBinCount); - - const blockNumbers = []; - for (let row = row1; row <= row2; row++) { - for (let column = col1; column <= col2; column++) { - let blockNumber; - if (sameChr && row < column) { - blockNumber = column * blockColumnCount + row; - } else { - blockNumber = row * blockColumnCount + column; - } - if (!blockNumbers.includes(blockNumber)) { // possible from transposition - blockNumbers.push(blockNumber); - } - } - } - return blockNumbers - } - - function getBlockNumbersV9() - { - - const binX1 = region1.start / binsize; - const binX2 = region1.end / binsize; - const binY1 = region2.start / binsize; - const binY2 = region2.end / binsize; - - // PAD = positionAlongDiagonal (~projected) - // Depth is axis perpendicular to diagonal; nearer means closer to diagonal - const translatedLowerPAD = Math.floor((binX1 + binY1) / 2 / blockBinCount); - const translatedHigherPAD = Math.floor((binX2 + binY2) / 2 / blockBinCount); - const translatedNearerDepth = Math.floor(Math.log2(1 + Math.abs(binX1 - binY2) / Math.sqrt(2) / blockBinCount)); - const translatedFurtherDepth = Math.floor(Math.log2(1 + Math.abs(binX2 - binY1) / Math.sqrt(2) / blockBinCount)); - - // because code above assume above diagonal; but we could be below diagonal - const containsDiagonal = (binX2 - binY1) * (binX1 - binY2) < 0; // i.e. sign of (x-y) opposite on 2 corners - const nearerDepth = containsDiagonal ? 0 : Math.min(translatedNearerDepth, translatedFurtherDepth); - const furtherDepth = Math.max(translatedNearerDepth, translatedFurtherDepth); - - const blockNumbers = []; - for (let depth = nearerDepth; depth <= furtherDepth; depth++) { - for (let pad = translatedLowerPAD; pad <= translatedHigherPAD; pad++) { - const block_number = depth * blockColumnCount + pad; - blockNumbers.push(block_number); - } - } - return blockNumbers - } - } - - static parseMatrixZoomData(chr1, chr2, dis) { - - const zd = new MatrixZoomData(chr1, chr2); - - const unit = dis.getString(); - const zoomIndex = dis.getInt(); - const sumCounts = dis.getFloat(); - const occupiedCellCount = dis.getFloat(); - const stdDev = dis.getFloat(); - const percent95 = dis.getFloat(); - const binSize = dis.getInt(); - zd. blockBinCount = dis.getInt(); - zd. blockColumnCount = dis.getInt(); - const nBlocks = dis.getInt(); - - zd. zoom = {index: zoomIndex, unit: unit, binSize: binSize}; - - zd.blockIndex = new StaticBlockIndex(nBlocks, dis); - - const nBins1 = (chr1.size / binSize); - const nBins2 = (chr2.size / binSize); - const avgCount = (sumCounts / nBins1) / nBins2; // <= trying to avoid overflows - - zd.averageCount = avgCount; - zd.sumCounts = sumCounts; - zd.stdDev = stdDev; - zd.occupiedCellCount = occupiedCellCount; - zd.percent95 = percent95; - - return zd; - } -} - - -class StaticBlockIndex { - - constructor(nBlocks, dis) { - this.blockIndex = {}; - while (nBlocks-- > 0) { - const blockNumber = dis.getInt(); - const filePosition = dis.getLong(); - const size = dis.getInt(); - this.blockIndex[blockNumber] = {filePosition, size}; - } - } - - getBlockIndexEntry(blockNumber) { - return this.blockIndex[blockNumber]; - } -} - -class Matrix { - - constructor(chr1, chr2, zoomDataList) { - this.chr1 = chr1; - this.chr2 = chr2; - this.bpZoomData = []; - this.fragZoomData = []; - for (let zd of zoomDataList) { - if (zd.zoom.unit === "BP") { - this.bpZoomData.push(zd); - } else { - this.fragZoomData.push(zd); - } - } - } - - /** - * Find the best zoom level for the given bin size - * @param binSize - * @param unit - * @returns {number} - */ - findZoomForResolution(binSize, unit) { - const zdArray = "FRAG" === unit ? this.fragZoomData : this.bpZoomData; - for (let i = 1; i < zdArray.length; i++) { - var zd = zdArray[i]; - if (zd.zoom.binSize < binSize) { - return i - 1 - } - } - return zdArray.length - 1 - } - - /** - * Fetch zoom data by bin size. If no matching level exists return undefined. - * - * @param unit - * @param binSize - * @param zoom - * @returns {undefined|*} - */ - getZoomData(binSize, unit) { - unit = unit || "BP"; - const zdArray = unit === "BP" ? this.bpZoomData : this.fragZoomData; - for (let i = 0; i < zdArray.length; i++) { - var zd = zdArray[i]; - if (binSize === zd.zoom.binSize) { - return zd - } - } - return undefined - } - - /** - * Return zoom data by resolution index. - * @param index - * @param unit - * @returns {*} - */ - getZoomDataByIndex(index, unit) { - const zdArray = "FRAG" === unit ? this.fragZoomData : this.bpZoomData; - return zdArray[index] - } - - static getKey(chrIdx1, chrIdx2) { - if (chrIdx1 > chrIdx2) { - const tmp = chrIdx1; - chrIdx1 = chrIdx2; - chrIdx2 = tmp; - } - return `${chrIdx1}_${chrIdx2}`; - } - - static parseMatrix(data, chromosomes) { - - const dis = new BinaryParser(new DataView(data)); - const c1 = dis.getInt(); // Should equal chrIdx1 - const c2 = dis.getInt(); // Should equal chrIdx2 - - // TODO validate this - const chr1 = chromosomes[c1]; - const chr2 = chromosomes[c2]; - - // # of resolution levels (bp and frags) - let nResolutions = dis.getInt(); - const zdList = []; - - while (nResolutions-- > 0) { - const zd = MatrixZoomData.parseMatrixZoomData(chr1, chr2, dis); - zdList.push(zd); - } - return new Matrix(c1, c2, zdList); - } - -} - -class ContactRecord { - - constructor(bin1, bin2, counts) { - this.bin1 = bin1; - this.bin2 = bin2; - this.counts = counts; - }; - - getKey() { - return "" + this.bin1 + "_" + this.bin2; - } -} - -class LRU { - constructor(max = 10) { - this.max = max; - this.map = new Map(); - } - - get(key) { - let item = this.map.get(key); - if (item) { - // refresh key - this.map.delete(key); - this.map.set(key, item); - } - return item; - } - - set(key, val) { - // refresh key - if (this.map.has(key)) this.map.delete(key); - // evict oldest - else if (this.map.size === this.max) { - this.map.delete(this.first()); - } - this.map.set(key, val); - } - - has(key) { - return this.map.has(key); - } - - clear() { - this.map.clear(); - } - - first() { - return this.map.keys().next().value; - } -} - -/* - * The MIT License (MIT) - * - * Copyright (c) 2016-2017 The Regents of the University of California - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and - * associated documentation files (the "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the - * following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING - * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - */ -const DOUBLE$1 = 8; - -class NormalizationVector { - - constructor(file, filePosition, nValues, dataType) { - this.file = file; - this.filePosition = filePosition; - this.nValues = nValues; - this.dataType = dataType; - this.cache = undefined; - } - - async getValues(start, end) { - - if(!this.cache || start < this.cache.start || end > this.cache.end) { - const adjustedStart = Math.max(0, start - 1000); - const adjustedEnd = Math.min(this.nValues, end + 1000); - const startPosition = this.filePosition + adjustedStart * this.dataType; - const n = adjustedEnd - adjustedStart; - const sizeInBytes = n * this.dataType; - const data = await this.file.read(startPosition, sizeInBytes); - if (!data) { - return undefined; - } - const parser = new BinaryParser(new DataView(data)); - - const values = []; - for (let i = 0; i < n; i++) { - values[i] = this.dataType === DOUBLE$1 ? parser.getDouble() : parser.getFloat(); - - } - this.cache = { - start: adjustedStart, - end: adjustedEnd, - values: values - }; - } - - const sliceStart = start - this.cache.start; - const sliceEnd = sliceStart + (end - start); - return this.cache.values.slice(sliceStart, sliceEnd); - } - - getKey() { - return NormalizationVector.getKey(this.type, this.chrIdx, this.unit, this.resolution); - } - - - static getNormalizationVectorKey(type, chrIdx, unit, resolution) { - return type + "_" + chrIdx + "_" + unit + "_" + resolution; - } -} - -// Contains "normalization vector index" (nvi values) for legacy (v8) hosted files from aidenlab, ENCODE, and 4DN. -// These values can speed up initialization by a few seconds. -var nvi$1 = { - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2Fcombined.hic": "54386046426,55860", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2Fprimary.hic": "33860030033,37504", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2Freplicate.hic": "30849652794,55832", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2Fmaternal.hic": "1380542661,17185", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2Fpaternal.hic": "1389001777,17185", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fimr90%2Fin-situ%2Fcombined.hic": "13433880319,35723", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC001.hic": "3409347253,35975", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC002.hic": "4529947083,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC003.hic": "6894962500,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC004.hic": "3395593338,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC005.hic": "5204128636,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC006.hic": "3278363811,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC007.hic": "3585547340,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC008.hic": "4134197273,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC009.hic": "2851728310,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC010.hic": "1754216102,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC011.hic": "1716829574,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC012.hic": "4367980375,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC013.hic": "2309654671,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC014.hic": "5324950266,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC015.hic": "3132333594,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC016.hic": "3159154704,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC017.hic": "3262554627,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC018.hic": "3014216364,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC019.hic": "5025753246,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC020.hic": "5861584507,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC021.hic": "3542263275,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC022.hic": "5061949378,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC023.hic": "4816423919,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC024.hic": "2683781104,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC025.hic": "6522701781,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC026.hic": "6748846520,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC027.hic": "5642693007,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC028.hic": "2098921691,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC029.hic": "3886454027,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fagar%2FHIC030.hic": "2288984204,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fagar%2FHIC031.hic": "2115342419,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fpellet%2FHIC032.hic": "2063314324,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fsupernatant%2FHIC033.hic": "1933908457,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fdilution%2FHIC034.hic": "13555514595,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fdilution%2FHIC035.hic": "6129650900,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fdilution%2FHIC036.hic": "4307445019,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fdilution%2FHIC037.hic": "9375139867,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fdilution%2Fcombined.hic": "11664249584,33929", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2Fcombined_DpnII.hic": "7003537290,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC038.hic": "2099825544,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC039.hic": "2096900138,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC040.hic": "2593642141,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC041.hic": "2263919098,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC042.hic": "2684774693,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2Fcombined_noXlink.hic": "5574807456,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC043.hic": "2986114347,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC044.hic": "1916378621,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC045.hic": "746463126,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC046.hic": "2338476164,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC047.hic": "1167496250,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC048.hic": "2231690794,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC049.hic": "2782308678,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fimr90%2Fin-situ%2FHIC050.hic": "3633531346,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fimr90%2Fin-situ%2FHIC051.hic": "4063486444,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fimr90%2Fin-situ%2FHIC052.hic": "929756278,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fimr90%2Fin-situ%2FHIC053.hic": "2489657204,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fimr90%2Fin-situ%2FHIC054.hic": "4036419444,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fimr90%2Fin-situ%2FHIC055.hic": "4284185549,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fimr90%2Fin-situ%2FHIC056.hic": "4410546240,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fimr90%2Fdilution%2FHIC057.hic": "1491998259,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fhmec%2Fin-situ%2Fcombined.hic": "7266425111,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fhmec%2Fin-situ%2FHIC058.hic": "6532635593,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fhmec%2Fin-situ%2FHIC059.hic": "400684530,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fhmec%2Fin-situ%2FHIC060.hic": "645352187,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fhmec%2Fin-situ%2FHIC061.hic": "736291871,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fhmec%2Fin-situ%2FHIC062.hic": "762731037,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fhmec%2Fin-situ%2FHIC063.hic": "682917431,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fhmec%2Fdilution%2FHIC064.hic": "4550171307,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fnhek%2Fin-situ%2Fcombined.hic": "11897184911,35789", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fnhek%2Fin-situ%2FHIC065.hic": "5425943567,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fnhek%2Fin-situ%2FHIC066.hic": "5942869818,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fnhek%2Fin-situ%2FHIC067.hic": "5191049261,35647", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fnhek%2Fdilution%2FHIC068.hic": "2713318801,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fk562%2Fin-situ%2Fcombined.hic": "12641555389,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fk562%2Fin-situ%2FHIC069.hic": "5630177461,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fk562%2Fin-situ%2FHIC070.hic": "5926611269,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fk562%2Fin-situ%2FHIC071.hic": "2486191351,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fk562%2Fin-situ%2FHIC072.hic": "2281343366,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fk562%2Fin-situ%2FHIC073.hic": "2173074239,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fk562%2Fin-situ%2FHIC074.hic": "2463700999,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fkbm7%2Fin-situ%2Fcombined.hic": "14661922519,35639", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fkbm7%2Fin-situ%2FHIC075.hic": "3685310515,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fkbm7%2Fin-situ%2FHIC076.hic": "5833658487,35891", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fkbm7%2Fin-situ%2FHIC077.hic": "2406346486,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fkbm7%2Fin-situ%2FHIC078.hic": "5241454987,35919", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fkbm7%2Fin-situ%2FHIC079.hic": "6297234263,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fhuvec%2Fin-situ%2Fcombined.hic": "9193858096,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fhuvec%2Fin-situ%2FHIC080.hic": "5171405536,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fhuvec%2Fin-situ%2FHIC081.hic": "3489767688,35891", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fhuvec%2Fin-situ%2FHIC082.hic": "4243339375,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fhuvec%2Fdilution%2FHIC083.hic": "1497495406,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fhela%2Fin-situ%2Fcombined.hic": "7923332224,35593", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fhela%2Fin-situ%2FHIC084.hic": "867699123,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fhela%2Fin-situ%2FHIC085.hic": "3669518514,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fhela%2Fin-situ%2FHIC086.hic": "5306474712,35595", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fhela%2Fin-situ%2FHIC087.hic": "1490963755,36397", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2Fcombined.hic": "8956382853,50248", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2FHIC088.hic": "1874185366,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2FHIC089.hic": "1301165236,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2FHIC090.hic": "1105246282,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2FHIC091.hic": "1338325770,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2FHIC092.hic": "1307918730,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2FHIC093.hic": "755136918,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2FHIC094.hic": "1606583694,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2FHIC095.hic": "2039711245,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2FHIC096.hic": "1909573053,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2FHIC097.hic": "1826710712,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2FHIC098.hic": "1998793575,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2FHIC099.hic": "1007740962,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2FHIC100.hic": "736464120,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2FHIC101.hic": "980505082,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2FHIC102.hic": "1116083646,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fdilution%2FHIC103.hic": "1096994310,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fdilution%2FHIC104.hic": "841063882,32102", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC105.hic": "107742864,36479", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC106.hic": "134295912,36479", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC107.hic": "110228014,36479", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC108.hic": "102761401,36479", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC109.hic": "100461491,36479", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC110.hic": "88828472,36479", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC111.hic": "81471064,36479", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC112.hic": "92297035,36479", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC113.hic": "65503916,36479", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC114.hic": "49181188,36479", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC115.hic": "46471102,36479", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC116.hic": "64284432,36479", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC117.hic": "60434076,36479", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC118.hic": "45248563,36479", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC119.hic": "60288782,36479", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC120.hic": "136888414,36479", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC121.hic": "125009003,33681", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC122.hic": "154011688,34127", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC123.hic": "177663372,35293", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC124.hic": "382186226,35245", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC125.hic": "158160717,35271", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC127.hic": "110261177,34659", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC128.hic": "246131875,35509", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC129.hic": "260160119,35667", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC130.hic": "117479562,34681", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC131.hic": "81508929,34673", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC132.hic": "105959102,34895", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC133.hic": "91504812,33451", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC134.hic": "52222546,33737", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC135.hic": "57763085,34159", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC136.hic": "50618489,33731", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC137.hic": "193163606,33363", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC138.hic": "229876152,33777", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC139.hic": "201783666,33571", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC140.hic": "281163862,34125", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC141.hic": "275969727,33935", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC142.hic": "275020431,34125", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC144.hic": "223834810,34177", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC145.hic": "296632653,33937", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC146.hic": "290945216,33961", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC147.hic": "234459964,34231", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC148.hic": "295457850,34039", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC149.hic": "113569632,35695", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC150.hic": "304381897,33963", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC151.hic": "289314545,33805", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC152.hic": "284320182,33803", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC153.hic": "401393947,34659", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC154.hic": "188065488,36479", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC155.hic": "299157119,33967", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC156.hic": "279289244,33787", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC157.hic": "254852119,33917", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC158.hic": "195969660,33477", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC159.hic": "185720388,36479", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC160.hic": "227709279,33599", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC161.hic": "157225076,33209", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC162.hic": "105703444,32033", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC163.hic": "122665658,32121", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC164.hic": "228048231,33761", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC165.hic": "114440819,32011", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC166.hic": "285147558,33891", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC167.hic": "363116754,33943", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC168.hic": "119592158,31937", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC169.hic": "236853872,33785", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC170.hic": "195187639,33395", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC171.hic": "208044058,33309", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC172.hic": "144645916,32877", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC173.hic": "119115941,32203", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC175.hic": "178030481,33525", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC176.hic": "117220136,32169", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC177.hic": "128586196,32659", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC178.hic": "191419141,33629", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC179.hic": "141556748,32959", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC180.hic": "199825102,33185", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC181.hic": "301022688,33783", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC182.hic": "185384453,33205", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC183.hic": "202189264,36367", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC184.hic": "37464475,36479", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC185.hic": "161938278,36099", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC186.hic": "133853166,36179", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC188.hic": "128068030,36237", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC189.hic": "148053886,36177", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC190.hic": "198946958,35803", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC191.hic": "226584564,36063", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC192.hic": "194412797,36341", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC193.hic": "176408194,36479", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC194.hic": "207215649,36055", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC195.hic": "175185530,36315", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC196.hic": "168969337,36479", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC197.hic": "121231252,36339", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC198.hic": "92713752,36479", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC199.hic": "105130500,36479", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC200.hic": "114526350,36479", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC201.hic": "122689717,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fhap1%2Fin-situ%2Fcombined.hic": "9614983328,36479", - "s3.amazonaws.com%2Fhicfiles%2Fexternal%2Fctbp_8_4_17%2Fall_intra_megabase_michrom.hic": "154205644,10960", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2Fdel-Xa-combined.hic": "8843305329,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FdelXa-chrX-diploid.hic": "11173520,1498", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FWT-combined.hic": "13365182403,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FWT-chrX-diploid.hic": "17343459,1498", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FHIC002.hic": "4279298739,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FHIC003.hic": "3027365532,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FHIC004.hic": "2896130835,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FHIC005.hic": "4717830071,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FHIC006.hic": "5066210154,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FHIC007.hic": "3069516128,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2Fdel-Xi-combined.hic": "14551096423,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FdelXi-chrX-diploid.hic": "17362477,1498", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FHIC008.hic": "2572386655,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FHIC009.hic": "2935931663,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FHIC010.hic": "2019085070,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FHIC011.hic": "6087610814,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FHIC012.hic": "2809618194,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FHIC013.hic": "2572386655,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fpatski%2FDarrowHuntley-2015%2Fcombined.hic": "6950423609,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fpatski%2FDarrowHuntley-2015%2Fpaternal.hic": "220592749,15691", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fpatski%2FDarrowHuntley-2015%2Fmaternal.hic": "323233095,15691", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fpatski%2FDarrowHuntley-2015%2FHIC014.hic": "3183235800,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fpatski%2FDarrowHuntley-2015%2FHIC015.hic": "1739539801,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fpatski%2FDarrowHuntley-2015%2FHIC016.hic": "1105912758,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fpatski%2FDarrowHuntley-2015%2FHIC017.hic": "1060773319,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fpatski%2FDarrowHuntley-2015%2FHIC018.hic": "1203679874,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fpatski%2FDarrowHuntley-2015%2FHIC019.hic": "3321955269,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Frhesus%2FDarrowHuntley-2015%2FHIC020.hic": "7108980626,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fcola%2FDarrowHuntley-2015%2FHIC021.hic": "3906448676,34955", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fassembly%2Faedes%2Fcombined.hic": "390780490,2245", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fassembly%2Fhs2-hic.hic": "1960284186,33561", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fassembly%2FCpipJ3.hic": "766279097,4381", - "s3.amazonaws.com%2Fhicfiles%2Fexternal%2Fphanstiel%2Fupdated_O%2FSnyder_O.hic": "8046980555,18679", - "s3.amazonaws.com%2Fhicfiles%2Fexternal%2Fphanstiel%2FA_inter.hic": "10986005145,18679", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Funtreated%2Funsynchronized%2Fcombined.hic": "30439217680,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftreated_6hr%2Funsynchronized%2Fcombined.hic": "33255540403,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2Fdeep%2F20min_withdraw_combined.hic": "11078436933,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2Fdeep%2F40min_withdraw_combined.hic": "11031830038,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2Fdeep%2F60min_withdraw_combined.hic": "10312725340,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2Fdeep%2F180min_withdraw_combined.hic": "10038610214,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Funtreated%2Funsynchronized%2FHIC001.hic": "8004335785,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Funtreated%2Funsynchronized%2FHIC002.hic": "8453215933,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Funtreated%2Funsynchronized%2FHIC003.hic": "9118406189,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Funtreated%2Funsynchronized%2FHIC004.hic": "5973342894,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Funtreated%2Funsynchronized%2FHIC005.hic": "6846576837,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Funtreated%2Funsynchronized%2FHIC006.hic": "6075148017,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Funtreated%2Funsynchronized%2FHIC007.hic": "8192366992,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftreated_6hr%2Funsynchronized%2FHIC008.hic": "6844159653,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftreated_6hr%2Funsynchronized%2FHIC009.hic": "7282063059,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftreated_6hr%2Funsynchronized%2FHIC010.hic": "10410578833,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftreated_6hr%2Funsynchronized%2FHIC011.hic": "8192366992,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftreated_6hr%2Funsynchronized%2FHIC012.hic": "7223422850,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftreated_6hr%2Funsynchronized%2FHIC013.hic": "7435986997,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftreated_6hr%2Funsynchronized%2FHIC014.hic": "9120113605,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Funtreated%2Fsynchronized%2Fcombined.hic": "4170577904,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Funtreated%2Fsynchronized%2FHIC015.hic": "1504084990,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Funtreated%2Fsynchronized%2FHIC016.hic": "1686244500,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Funtreated%2Fsynchronized%2FHIC017.hic": "1804802410,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Funtreated%2Fsynchronized%2FHIC018.hic": "1533942067,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftreated_6hr%2Fsynchronized%2Fcombined.hic": "4572390198,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftreated_6hr%2Fsynchronized%2FHIC019.hic": "1543609666,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftreated_6hr%2Fsynchronized%2FHIC020.hic": "1814133288,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftreated_6hr%2Fsynchronized%2FHIC021.hic": "1942698243,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftreated_6hr%2Fsynchronized%2FHIC022.hic": "1873587413,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2Funtreated%2FRao-2017-HIC049.hic": "405127557,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2Funtreated%2FRao-2017-HIC060.hic": "326681741,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2Funtreated%2FRao-2017-HIC061.hic": "300908673,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_20min%2FRao-2017-HIC050.hic": "481758242,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_20min%2FRao-2017-HIC051.hic": "417577401,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_40min%2FRao-2017-HIC052.hic": "419353227,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_40min%2FRao-2017-HIC053.hic": "411554953,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_60min%2FRao-2017-HIC054.hic": "386655891,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_60min%2FRao-2017-HIC055.hic": "402170701,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_240min%2FRao-2017-HIC057.hic": "735906308,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min%2FRao-2017-HIC058.hic": "443789827,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min%2FRao-2017-HIC059.hic": "491422615,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min%2FRao-2017-HIC062.hic": "320261375,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min%2FRao-2017-HIC063.hic": "306590499,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min_withdraw_20min%2FRao-2017-HIC032S.hic": "367051742,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min_withdraw_20min%2FRao-2017-HIC033S.hic": "344555339,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min_withdraw_40min%2FRao-2017-HIC036S.hic": "349392947,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min_withdraw_40min%2FRao-2017-HIC037S.hic": "317714554,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min_withdraw_60min%2FRao-2017-HIC040S.hic": "266786397,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min_withdraw_60min%2FRao-2017-HIC041S.hic": "279445530,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min_withdraw_180min%2FRao-2017-HIC044S.hic": "898418269,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min_withdraw_180min%2FRao-2017-HIC045S.hic": "961006347,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min_withdraw_360min%2FRao-2017-HIC064.hic": "833576408,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min_withdraw_360min%2FRao-2017-HIC065.hic": "840881418,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min_withdraw_1080min%2FRao-2017-HIC066.hic": "980958864,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min_withdraw_1080min%2FRao-2017-HIC067.hic": "882023129,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min_withdraw_1440min%2FRao-2017-HIC068.hic": "1110292630,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min_withdraw_1440min%2FRao-2017-HIC069.hic": "1001747023,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fexternal%2Frowley_nichols_mol_cell_2017%2FCP190_HiChIP.hic": "144107588,6976", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fexternal%2Frowley_nichols_mol_cell_2017%2FH3K27ac_HiChIP_combined.hic": "43171370,5233", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fexternal%2Frowley_nichols_mol_cell_2017%2FH3K27me3_HiChIP_combined.hic": "42906472,5233", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fexternal%2Frowley_nichols_mol_cell_2017%2FPol2_ChIAPET.hic": "41992430,6976", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fexternal%2Frowley_nichols_mol_cell_2017%2FPol2S2_HiChIP.hic": "145842743,6976", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fexternal%2Frowley_nichols_mol_cell_2017%2FArabidopsis_Wang2015_Liu2016.hic": "1134391078,4984", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fexternal%2Frowley_nichols_mol_cell_2017%2FElegans_Crane2015.hic": "387127568,8758", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fexternal%2Frowley_nichols_mol_cell_2017%2FNcrassa_Galazka2016.hic": "26555511,27725", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fexternal%2Frowley_nichols_mol_cell_2017%2FPfalciparum_trophozoite_Ay2014.hic": "15640893,13948", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fduan%2FE-Me-A.hic": "6897251,23348", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fduan%2FE-Me-B.hic": "4959088,23348", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fduan%2FE-Mp-A.hic": "5232286,23348", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fduan%2FE-Mp-B.hic": "5105292,23348", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fduan%2FH-Me-A.hic": "6900072,23348", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fduan%2FH-Me-B.hic": "8653258,23348", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fduan%2FH-Mp-A.hic": "7999058,23348", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fduan%2FH-Mp-B.hic": "8774657,23348", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fdekker%2F4dn%2Fh1hesc.hic": "23671753603,36479", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fdekker%2F4dn%2Fh1hesc_rep1.hic": "23671754721,36479", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fdekker%2F4dn%2Fh1hesc_rep2.hic": "22269909910,36479", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fdekker%2F4dn%2Fhffc6_rep1.hic": "19016661622,36479", - "hicfiles.s3.amazonaws.com%2Fexternal%2Flieberman_aiden_van_berkum%2FGM06990_NcoI.hic": "480725203,36479", - "hicfiles.s3.amazonaws.com%2Fexternal%2Flieberman_aiden_van_berkum%2F302NH.hic": "99948617,36479", - "hicfiles.s3.amazonaws.com%2Fexternal%2Flieberman_aiden_van_berkum%2FK562.hic": "470263605,36151", - "hicfiles.s3.amazonaws.com%2Fexternal%2Flieberman_aiden_van_berkum%2FGM06990_HindIII.hic": "293706559,36289", - "hicfiles.s3.amazonaws.com%2Fexternal%2Flieberman_aiden_van_berkum%2FGM06990_rep_HindIII.hic": "309673862,36087", - "hicfiles.s3.amazonaws.com%2Fexternal%2Frudan%2Fcanis-lupus-rep1.hic": "1531151371,56905", - "hicfiles.s3.amazonaws.com%2Fexternal%2Frudan%2Fcanis-lupus-rep2.hic": "2851437676,56905", - "hicfiles.s3.amazonaws.com%2Fexternal%2Frudan%2Fmouse-rep1.hic": "582052544,32102", - "hicfiles.s3.amazonaws.com%2Fexternal%2Frudan%2Fmacaque-rep1.hic": "698509182,32102", - "hicfiles.s3.amazonaws.com%2Fexternal%2Frudan%2Fmacaque-rep2.hic": "461410393,32102", - "hicfiles.s3.amazonaws.com%2Fexternal%2Frudan%2Frabbit-rep1.hic": "691045338,33561", - "hicfiles.s3.amazonaws.com%2Fexternal%2Frudan%2Frabbit-rep2.hic": "668888336,33561", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fsexton%2Fcombined.hic": "50650087,4486", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fkalhor%2Ftcc-hindiii.hic": "1071142023,16500", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fkalhor%2Ftcc-mboi.hic": "1508851093,16448", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fkalhor%2Fnon-tcc-hindiii.hic": "395179229,36093", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fkalhor%2Ftcc-combined.hic": "1050423847,36479", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fdixon%2Fmm9-hindiii%2Fsplit-read-run.hic": "9599984876,32102", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fdixon%2Fhesc-hindiii.hic": "1952555632,36479", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fdixon%2Fimr90-hindiii.hic": "9691260435,18679", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fdixon%2Fmm9-cortex.hic": "3712072953,32102", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fzhang%2Fatm-i-scei-chr18.hic": "2083350075,16438", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fzhang%2Fatm-i-scei-chr2.hic": "3362049644,16360", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fzhang%2Fatm-i-scei-chr7.hic": "1658399854,16438", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fzhang%2Fwt-i-scei-chr15.hic": "866691249,16438", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fzhang%2Fwt-i-scei-chr2.hic": "3304782795,16386", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fnagano%2Fcell-1.hic": "23673506,32102", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fnagano%2Fcell-2.hic": "26873280,30643", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fnagano%2Fcell-3.hic": "31066362,30643", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fnagano%2Fcell-4.hic": "16807724,30643", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fnagano%2Fcell-5.hic": "28665065,30643", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fnagano%2Fcell-6.hic": "13124158,30643", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fnagano%2Fcell-7.hic": "15118945,30643", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fnagano%2Fcell-8.hic": "68316814,32102", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fnagano%2Fcell-9.hic": "18965101,30643", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fnagano%2Fcell-10.hic": "17020666,30643", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fjin%2Fimr90%2Fcombined.hic": "6526601242,36427", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fjin%2Fimr90%2Frep1.hic": "1861562891,36401", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fjin%2Fimr90%2Frep2.hic": "3061013635,36479", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fjin%2Fimr90%2Frep3.hic": "1564588211,35969", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fjin%2Fimr90%2Frep4.hic": "1255543175,36153", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fjin%2Fimr90%2Frep5.hic": "974683253,36179", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fjin%2Fimr90%2Frep6.hic": "1040805629,36053", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fjin%2Fimr90-tnf-alpha%2Fcombined.hic": "8424080116,36401", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fjin%2Fimr90-tnf-alpha%2Frep1.hic": "2697976702,36295", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fjin%2Fimr90-tnf-alpha%2Frep3.hic": "1718610467,36159", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fjin%2Fimr90-tnf-alpha%2Frep4.hic": "2029519405,36101", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fjin%2Fimr90-tnf-alpha%2Frep5.hic": "985310855,36069", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fjin%2Fimr90-tnf-alpha%2Frep6.hic": "1418750480,35967", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fcheng%2Fmhh-call-4-cell-line.hic": "538380253,35351", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fcheng%2Fprimary-b-all.hic": "773764191,35793", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fcheng%2Fnormal-b-cell-line.hic": "336271459,35005", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fcheng%2Frl-cell-line.hic": "484807998,35351", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fhou%2Fkc167-biorep.hic": "135932435,8758", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fhou%2Fkc167-techrep1.hic": "160355961,8758", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fhou%2Fkc167-techrep2.hic": "188809887,8758", - "hicfiles.s3.amazonaws.com%2Fexternal%2Flin%2Fpre-prob-egs.hic": "2237792858,15483", - "hicfiles.s3.amazonaws.com%2Fexternal%2Flin%2Fprob-egs.hic": "5744720377,16438", - "hicfiles.s3.amazonaws.com%2Fexternal%2Flin%2Fprob-fa.hic": "2174866215,16438", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fli%2Fhct116-rnapii-pilot.hic": "396366166,35999", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fli%2Fhela-rnapii-pilot.hic": "882516759,35107", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fli%2Fk562-rnapii-pilot.hic": "1131576189,35969", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fli%2Fk562-rnapii-saturated.hic": "571583828,36291", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fli%2Fmcf7-rnapii-saturated.hic": "1282547841,36035", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fli%2Fnb4-rnapii-pilot.hic": "761614686,34861", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fjung%2Fmouse_sperm.hic": "1730231642,29184", - "hicfiles.s3.amazonaws.com%2Fexternal%2Ftang%2Fgm12878.hic": "1953518212,20505", - "hicfiles.s3.amazonaws.com%2Fexternal%2Frutledge%2FSRR1791299.hic": "5723484,11956", - "hicfiles.s3.amazonaws.com%2Fexternal%2Frutledge%2FSRR1791297.hic": "16534743,23348", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fzuin%2Fhek293t-rad21cv-hrv.hic": "5094525579,36289", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fzuin%2Fhek293t-rad21cv-hrv-rep1.hic": "2574358912,36373", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fzuin%2Fhek293t-rad21cv-hrv-rep2.hic": "3417099433,36243", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fzuin%2Fhek293t-rad21cv-tev.hic": "4785157552,36323", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fzuin%2Fhek293t-rad21cv-tev-rep1.hic": "2648268465,36321", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fzuin%2Fhek293t-rad21cv-tev-rep2.hic": "2994727980,36107", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fzuin%2Fhek293t-sirna-ctcf.hic": "5391791815,36063", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fzuin%2Fhek293t-sirna-ctcf-rep1.hic": "3325842095,36269", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fzuin%2Fhek293t-sirna-ctcf-rep2.hic": "3096215920,36167", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fzuin%2Fhek293t-sirna-ctrl.hic": "3830902383,36167", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fzuin%2Fhek293t-sirna-ctrl-rep1.hic": "1346712252,36079", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fzuin%2Fhek293t-sirna-ctrl_rep2.hic": "3098067367,36271", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fay%2Fp-falciparum-3d7-0h-hiseq.hic": "38174042,21889", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fay%2Fp-falciparum-3d7-18h-hiseq.hic": "26506099,21889", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fay%2Fp-falciparum-3d7-18h-hiseq-non-crosslinked_control.hic": "3545496,21889", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fay%2Fp-falciparum-3d7-36h-hiseq.hic": "70754194,21889", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fnaumova%2Fhelas3%2Fg1mid-r1.hic": "200863476,17185", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fnaumova%2Fhelas3%2Fm-r1.hic": "249021190,17185", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fnaumova%2Fhelas3%2Fm-r2.hic": "212341157,17185", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fnaumova%2Fhelas3ccl2p2%2Fg1-0-25fa.hic": "583572265,17185", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fnaumova%2Fhelas3ccl2p2%2Fg1-1fa.hic": "354502306,17185", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fnaumova%2Fhelas3ccl2p2%2Fm-0-25fa.hic": "149308791,17185", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fnaumova%2Fhelas3ccl2p2%2Fm-98percent.hic": "778175225,17185", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fnaumova%2Fhelas3ccl2p2%2Fm-1fa.hic": "158091047,17185", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fnaumova%2Fhff1%2Fcchic-hff1-ns-r1.hic": "801670039,17185", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fnaumova%2Fhff1%2Fcchic-hff1-m-r1.hic": "875922086,17185", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fnaumova%2Fk562%2Fm-r1.hic": "130959943,17185", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fnaumova%2Fk562%2Fm-r2.hic": "237861106,17185", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fsofueva%2FmAST-WT.hic": "496104039,30643", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fsofueva%2FmAST-WT-adv-cre.hic": "438608517,30643", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fsofueva%2FmAST-floxed-rep1.hic": "446205712,32102", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fsofueva%2FmAST-floxed-rep2.hic": "386354767,32102", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fsofueva%2FmAST-deleted-rep1.hic": "621998722,30643", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fsofueva%2FmAST-deleted-rep2.hic": "583840829,32102", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fsofueva%2FmNSC-floxed-rep1.hic": "801290988,30643", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fsofueva%2FmNSC-floxed-rep2.hic": "819406658,30643", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fsofueva%2FmNSC-deleted-rep1.hic": "792825269,32102", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fsofueva%2FmNSC-deleted-rep2.hic": "746189884,30643", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fsofueva%2FmNSC-WT.hic": "309353372,30643", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fsofueva%2FmNSC-WT-OHT.hic": "274229679,30643", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fseitan%2FTcell-Rad21KO-R1.hic": "1490362251,32102", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fseitan%2FTcell-Rad21KO-R3.hic": "2403664421,32102", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fseitan%2FTcell-Rad21WT-R1.hic": "1377124538,32102", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fseitan%2FTcell-Rad21WT-R3.hic": "2646201369,32102", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fmoissiard%2Fcrh6-mutant.hic": "105261071,10217", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fmoissiard%2FWT.hic": "127506388,10217", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fgrob%2FCol.hic": "153638500,10217", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fgrob%2Fcrwn1.hic": "211213220,10217", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fgrob%2Fcrwn4.hic": "134236837,10217", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fxie%2Fprimary.hic": "92936173,10217", - "hicfiles.s3.amazonaws.com%2Fexternal%2Ffeng%2F6wt-control6wt337.hic": "318737891,10217", - "hicfiles.s3.amazonaws.com%2Fexternal%2Ffeng%2F6wt-control6wt67.hic": "348123956,10217", - "hicfiles.s3.amazonaws.com%2Fexternal%2Ffeng%2F6wt337.hic": "251107279,10217", - "hicfiles.s3.amazonaws.com%2Fexternal%2Ffeng%2F6wt67.hic": "351840994,10217", - "hicfiles.s3.amazonaws.com%2Fexternal%2Ffeng%2FCol0.hic": "345969497,10217", - "hicfiles.s3.amazonaws.com%2Fexternal%2Ffeng%2Fclf28-swn7.hic": "299585025,10217", - "hicfiles.s3.amazonaws.com%2Fexternal%2Ffeng%2Fcmt3-11.hic": "253427706,10217", - "hicfiles.s3.amazonaws.com%2Fexternal%2Ffeng%2Fddm1-2.hic": "303626924,10217", - "hicfiles.s3.amazonaws.com%2Fexternal%2Ffeng%2Fmet1-3.hic": "347697973,10217", - "hicfiles.s3.amazonaws.com%2Fexternal%2Ffeng%2Fsuvh4-suvh5-suvh6.hic": "263122019,10217", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fma%2FDNase-HiC-WG-K562.hic": "892955840,18679", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fma%2FDNaseHiC-WG-H1.hic": "696922695,18679", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fma%2FtargetedDNaseHiC-lincRNA-K562-rep1.hic": "341917716,18679", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fma%2FtargeredDNaseHiC-lincRNA-K562-rep2.hic": "214841185,18679", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fma%2FtargetedDNaseHiC-lincRNA-H1-rep1.hic": "616326137,18679", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fma%2FtargetedDNaseHiC-lincRNA-H1-rep2.hic": "579654013,18679", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fma%2FtargetedDNaseHiC-pe-H1-rep1.hic": "519810544,18679", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fma%2FtargetedDNaseHiC-pe-K562-rep1.hic": "199553123,18679", - "hicfiles.s3.amazonaws.com%2Fexternal%2Frowley%2FKc167_DpnII.hic": "1319373594,6976", - "hicfiles.s3.amazonaws.com%2Fexternal%2Frowley%2FKc167_HinfI.hic": "1465493873,6976", - "hicfiles.s3.amazonaws.com%2Fexternal%2Frowley%2FKc167_DpnII_HinfI_combo.hic": "753062558,5814", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fbarutcu%2FMCF-10A.hic": "2784956115,36479", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fbarutcu%2FMCF-7.hic": "2700457411,36479", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fbatullin%2Fsperm.hic": "501052169,32102", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fminajigi%2FWT_hiC_rep1.hic": "1450697530,32102", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fminajigi%2FWT_hiC_rep2.hic": "1189371558,32102", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fminajigi%2Fcombined.hic": "2262007875,32102", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fminajigi%2Finactive.hic": "4444564,751", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fminajigi%2Factive.hic": "3993495,751", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fdeng%2Fpatski_rep1.hic": "1650838357,32102", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fdeng%2Fpatski_rep2.hic": "1258038606,32102", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fdeng%2Fpatski.hic": "499827296,16438", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fdeng%2Fpatski_active.hic": "79175714,15691", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fdeng%2Fpatski_inactive.hic": "98947881,15691", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fdeng%2Fbrain_dnase.hic": "4298088401,32102", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fdeng%2Fbrain_in_situ_dnase.hic": "609321852,32102", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fdeng%2Fbrain.hic": "1028196506,16438", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fdeng%2Fbrain_active.hic": "79175714,15691", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fdeng%2Fbrain_inactive.hic": "98947881,15691", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fle%2FBglII_rep1.hic": "1283306,1463", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fle%2FBglII_rep2.hic": "1263227,1463", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fle%2FNcoI_rep1.hic": "4380906,1463", - "hicfiles.s3.amazonaws.com%2Fexternal%2Feagen%2FGSE89112_Kc167combined.hic": "1829549643,25624", - "hicfiles.s3.amazonaws.com%2Fexternal%2Feagen%2FGSE89112_Kc167combined_randomized.hic": "1859742654,25624", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fmumbach%2FGSE80820_HiChIP_GM_cohesin.hic": "1231264781,17932", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fmumbach%2FGSE80820_HiChIP_mES_cohesin_all.hic": "1152008628,16438", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fmumbach%2FGSE80820_HiChIP_mES_Oct4.hic": "912828146,16438", - "s3.amazonaws.com%2Fhicfiles%2Fexternal%2Fwapl_hic%2FSCC4KO.hic": "1767906138,18679", - "s3.amazonaws.com%2Fhicfiles%2Fexternal%2Fwapl_hic%2FDKO.hic": "1487228787,18679", - "s3.amazonaws.com%2Fhicfiles%2Fexternal%2Fwapl_hic%2FWaplKO_1.14.hic": "1189751862,18679", - "s3.amazonaws.com%2Fhicfiles%2Fexternal%2Fwapl_hic%2FWaplKO_3.3.hic": "1155057696,18679", - "s3.amazonaws.com%2Fhicfiles%2Fexternal%2Fwapl_hic%2FWT.hic": "1522401568,18679", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fskfuwi4fnsjkdf9jekrw2%2Fmega_Liverpool%2Fmega.hic": "2612171975,4381", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fskfuwi4fnsjkdf9jekrw2%2FHIC2836_Liverpool1%2FLiverpool1.hic": "191729195,2245", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fskfuwi4fnsjkdf9jekrw2%2FHIC2861_Liverpool2%2FLiverpool2.hic": "1637096030,4381", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fskfuwi4fnsjkdf9jekrw2%2FHIC2862_Liverpool3%2FLiverpool3.hic": "1160045602,4381", - "s3.amazonaws.com%2Fhicfiles%2Fexternal%2Fgoodell%2FHSPC.hic": "11857786247,36479", - "s3.amazonaws.com%2Fhicfiles%2Fexternal%2Fgoodell%2FHSPC_CanyonDel.hic": "8139168836,36479", - "s3.amazonaws.com%2Fhicfiles%2Fexternal%2Fgoodell%2Ftcell.hic": "9871547081,36479", - "s3.amazonaws.com%2Fhicfiles%2Fexternal%2Fgoodell%2Fep.hic": "17479335373,36479", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fnagano%2FTh1_ensemble.hic": "1690592868,32102", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fbonev%2FES_mapq30.hic": "32930498831,32386", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fbonev%2FNPC_mapq30.hic": "55053730986,32386", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fbonev%2FCN_mapq30.hic": "53138031154,32386", - "hicfiles.s3.amazonaws.com%2Fhiseq%2FKieffer-Kwon_et_al_2017%2FMain_maps%2FKieffer-Kwon-2017-activated_B_cells_72_hours_WT.hic": "16492991184,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2FKieffer-Kwon_et_al_2017%2FMain_maps%2FKieffer-Kwon-2017-resting_B_cells_WT.hic": "23057795398,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2FKieffer-Kwon_et_al_2017%2FMain_maps%2FKieffer-Kwon-2017-activated_B_cells_24_hours_MYC_KO.hic": "21245554876,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2FKieffer-Kwon_et_al_2017%2FMain_maps%2FKieffer-Kwon-2017-resting_B_cells_TSA.hic": "13933346059,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2FKieffer-Kwon_et_al_2017%2FMain_maps%2FKieffer-Kwon-2017-activated_B_cells_24_hours_oligomycin.hic": "21902506832,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2FKieffer-Kwon_et_al_2017%2FMain_maps%2FKieffer-Kwon-2017-mES_WT.hic": "9451969795,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2FVian_et_al_2018%2FMain_maps%2FVian-2018-activated_B_cells_24_hours_WT.hic": "3600188564,16438", - "hicfiles.s3.amazonaws.com%2Fhiseq%2FVian_et_al_2018%2FMain_maps%2FVian-2018-activated_B_cells_30_hours_WT.hic": "1309503359,16438", - "hicfiles.s3.amazonaws.com%2Fhiseq%2FVian_et_al_2018%2FMain_maps%2FVian-2018-activated_B_cells_30_hours_HU_treated.hic": "1477252396,16438", - "hicfiles.s3.amazonaws.com%2Fhiseq%2FVian_et_al_2018%2FMain_maps%2FVian-2018-activated_B_cells_24_hours_flavopiridol.hic": "15711773490,32102", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fpgp%2FPGP1F_mega_090118%2FPGP1F_mega_090118_30.hic": "24786676166,36479", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fpgp%2FHIC7145%2FHIC7145_30.hic": "4554644616,36479", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fpgp%2FHIC7146%2FHIC7146_30.hic": "4174848944,36479", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fpgp%2FHIC7147%2FHIC7147_30.hic": "5062229182,36479", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fpgp%2FHIC7862%2FHIC7862_30.hic": "4520990620,36479", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fpgp%2FHIC7863%2FHIC7863_30.hic": "4330354773,36479", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fpgp%2FHIC7864%2FHIC7864_30.hic": "5880640268,36479", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fpgp%2FHIC7865%2FHIC7865_30.hic": "4431632469,36479", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fpgp%2FHIC7866%2FHIC7866_30.hic": "4686000222,36479", - "encode-public.s3.amazonaws.com%2F2018%2F10%2F19%2Fb122542b-306c-4631-bdc3-2e155e89af55%2FENCFF718AWL.hic": "39544267907,58932", - "encode-public.s3.amazonaws.com%2F2019%2F02%2F15%2F8e787cd8-e388-4bc2-a236-7a5e6f39e0c0%2FENCFF999YXX.hic": "9255069996,56883", - "encode-public.s3.amazonaws.com%2F2019%2F02%2F08%2Ffc1d9d5d-8fa0-4e29-9080-3da674d9490d%2FENCFF543USQ.hic": "5005263062,36479", - "s3.us-east-1.wasabisys.com%2Fhicfiles%2Finternal%2FLCL_mega_42B_500bp_30.hic": "106482584851,22829", - "www.encodeproject.org%2Ffiles%2FENCFF925QIF%2F%40%40download%2FENCFF925QIF.hic": "51712684396,54779", - "www.encodeproject.org%2Ffiles%2FENCFF259YUS%2F%40%40download%2FENCFF259YUS.hic": "24640030444,54779", - "www.encodeproject.org%2Ffiles%2FENCFF783KQI%2F%40%40download%2FENCFF783KQI.hic": "27209249856,54779", - "www.encodeproject.org%2Ffiles%2FENCFF318JAP%2F%40%40download%2FENCFF318JAP.hic": "28636979242,54779", - "www.encodeproject.org%2Ffiles%2FENCFF512PQA%2F%40%40download%2FENCFF512PQA.hic": "28124104361,54779", - "www.encodeproject.org%2Ffiles%2FENCFF591MHA%2F%40%40download%2FENCFF591MHA.hic": "37373387202,54779", - "www.encodeproject.org%2Ffiles%2FENCFF197OWW%2F%40%40download%2FENCFF197OWW.hic": "41826180893,54779", - "www.encodeproject.org%2Ffiles%2FENCFF317OIA%2F%40%40download%2FENCFF317OIA.hic": "34741636038,54779", - "www.encodeproject.org%2Ffiles%2FENCFF522YLZ%2F%40%40download%2FENCFF522YLZ.hic": "24064692329,54779", - "www.encodeproject.org%2Ffiles%2FENCFF420JTA%2F%40%40download%2FENCFF420JTA.hic": "21202405177,54779", - "www.encodeproject.org%2Ffiles%2FENCFF871ZDJ%2F%40%40download%2FENCFF871ZDJ.hic": "10124815680,18679", - "www.encodeproject.org%2Ffiles%2FENCFF349RZY%2F%40%40download%2FENCFF349RZY.hic": "4446702705,36479", - "www.encodeproject.org%2Ffiles%2FENCFF738YON%2F%40%40download%2FENCFF738YON.hic": "3338049584,35947", - "www.encodeproject.org%2Ffiles%2FENCFF406KJN%2F%40%40download%2FENCFF406KJN.hic": "4132875306,36479", - "www.encodeproject.org%2Ffiles%2FENCFF081NPN%2F%40%40download%2FENCFF081NPN.hic": "34495587443,54779", - "www.encodeproject.org%2Ffiles%2FENCFF946RZW%2F%40%40download%2FENCFF946RZW.hic": "34571955193,54779", - "www.encodeproject.org%2Ffiles%2FENCFF602CHT%2F%40%40download%2FENCFF602CHT.hic": "30674798032,54779", - "www.encodeproject.org%2Ffiles%2FENCFF150DKS%2F%40%40download%2FENCFF150DKS.hic": "12618769864,36479", - "www.encodeproject.org%2Ffiles%2FENCFF614IPZ%2F%40%40download%2FENCFF614IPZ.hic": "42450060331,54779", - "www.encodeproject.org%2Ffiles%2FENCFF571ZQR%2F%40%40download%2FENCFF571ZQR.hic": "15230068871,47429", - "www.encodeproject.org%2Ffiles%2FENCFF705MKK%2F%40%40download%2FENCFF705MKK.hic": "38686554702,54779", - "www.encodeproject.org%2Ffiles%2FENCFF658KTB%2F%40%40download%2FENCFF658KTB.hic": "13195884405,47429", - "www.encodeproject.org%2Ffiles%2FENCFF435JYN%2F%40%40download%2FENCFF435JYN.hic": "17192139674,54779", - "www.encodeproject.org%2Ffiles%2FENCFF016JKX%2F%40%40download%2FENCFF016JKX.hic": "37266736642,54779", - "www.encodeproject.org%2Ffiles%2FENCFF294GFP%2F%40%40download%2FENCFF294GFP.hic": "36389843399,54779", - "www.encodeproject.org%2Ffiles%2FENCFF700CYI%2F%40%40download%2FENCFF700CYI.hic": "60482012152,54779", - "www.encodeproject.org%2Ffiles%2FENCFF962EDB%2F%40%40download%2FENCFF962EDB.hic": "39394328182,54779", - "www.encodeproject.org%2Ffiles%2FENCFF467OGP%2F%40%40download%2FENCFF467OGP.hic": "35572788855,54779", - "www.encodeproject.org%2Ffiles%2FENCFF556RLR%2F%40%40download%2FENCFF556RLR.hic": "34826921187,54779", - "www.encodeproject.org%2Ffiles%2FENCFF309UNV%2F%40%40download%2FENCFF309UNV.hic": "48510618174,54779", - "www.encodeproject.org%2Ffiles%2FENCFF653HCO%2F%40%40download%2FENCFF653HCO.hic": "41079007620,54779", - "www.encodeproject.org%2Ffiles%2FENCFF120DSV%2F%40%40download%2FENCFF120DSV.hic": "12790195576,47429", - "www.encodeproject.org%2Ffiles%2FENCFF284OEA%2F%40%40download%2FENCFF284OEA.hic": "46007570339,54779", - "www.encodeproject.org%2Ffiles%2FENCFF035BLF%2F%40%40download%2FENCFF035BLF.hic": "63868871985,54779", - "www.encodeproject.org%2Ffiles%2FENCFF094KKX%2F%40%40download%2FENCFF094KKX.hic": "42151419971,54779", - "www.encodeproject.org%2Ffiles%2FENCFF965BPU%2F%40%40download%2FENCFF965BPU.hic": "42717376107,54779", - "www.encodeproject.org%2Ffiles%2FENCFF842DUO%2F%40%40download%2FENCFF842DUO.hic": "39553892515,54779", - "www.encodeproject.org%2Ffiles%2FENCFF417GBZ%2F%40%40download%2FENCFF417GBZ.hic": "45544785452,54779", - "www.encodeproject.org%2Ffiles%2FENCFF499BVX%2F%40%40download%2FENCFF499BVX.hic": "40900674170,54779", - "www.encodeproject.org%2Ffiles%2FENCFF136XCV%2F%40%40download%2FENCFF136XCV.hic": "47700392974,54779", - "www.encodeproject.org%2Ffiles%2FENCFF224HKR%2F%40%40download%2FENCFF224HKR.hic": "40426005932,54779", - "www.encodeproject.org%2Ffiles%2FENCFF711XSR%2F%40%40download%2FENCFF711XSR.hic": "41434581949,54779", - "www.encodeproject.org%2Ffiles%2FENCFF660JWA%2F%40%40download%2FENCFF660JWA.hic": "54201632697,54779", - "www.encodeproject.org%2Ffiles%2FENCFF081PMO%2F%40%40download%2FENCFF081PMO.hic": "53428285130,54779", - "www.encodeproject.org%2Ffiles%2FENCFF799QGA%2F%40%40download%2FENCFF799QGA.hic": "1228682189,36479", - "www.encodeproject.org%2Ffiles%2FENCFF473CAA%2F%40%40download%2FENCFF473CAA.hic": "1077514950,36479", - "www.encodeproject.org%2Ffiles%2FENCFF663FRL%2F%40%40download%2FENCFF663FRL.hic": "39843938245,54779", - "www.encodeproject.org%2Ffiles%2FENCFF341WOY%2F%40%40download%2FENCFF341WOY.hic": "34792598619,54779", - "www.encodeproject.org%2Ffiles%2FENCFF515ZBF%2F%40%40download%2FENCFF515ZBF.hic": "41779230923,54779", - "www.encodeproject.org%2Ffiles%2FENCFF545GBW%2F%40%40download%2FENCFF545GBW.hic": "38351980358,54779", - "www.encodeproject.org%2Ffiles%2FENCFF252ANV%2F%40%40download%2FENCFF252ANV.hic": "37668839771,54779", - "www.encodeproject.org%2Ffiles%2FENCFF912NDK%2F%40%40download%2FENCFF912NDK.hic": "21196851956,54779", - "www.encodeproject.org%2Ffiles%2FENCFF683PLM%2F%40%40download%2FENCFF683PLM.hic": "21849338763,54779", - "www.encodeproject.org%2Ffiles%2FENCFF355NFJ%2F%40%40download%2FENCFF355NFJ.hic": "47880627268,54779", - "www.encodeproject.org%2Ffiles%2FENCFF507WEW%2F%40%40download%2FENCFF507WEW.hic": "35777782924,54779", - "www.encodeproject.org%2Ffiles%2FENCFF241MSL%2F%40%40download%2FENCFF241MSL.hic": "22507408288,54779", - "www.encodeproject.org%2Ffiles%2FENCFF135MUT%2F%40%40download%2FENCFF135MUT.hic": "24168734040,54779", - "www.encodeproject.org%2Ffiles%2FENCFF459FRB%2F%40%40download%2FENCFF459FRB.hic": "37166770103,54779", - "www.encodeproject.org%2Ffiles%2FENCFF705YZH%2F%40%40download%2FENCFF705YZH.hic": "44679182442,54779", - "www.encodeproject.org%2Ffiles%2FENCFF395INO%2F%40%40download%2FENCFF395INO.hic": "56727346538,54779", - "www.encodeproject.org%2Ffiles%2FENCFF736ITL%2F%40%40download%2FENCFF736ITL.hic": "49036286185,54779", - "www.encodeproject.org%2Ffiles%2FENCFF546TZN%2F%40%40download%2FENCFF546TZN.hic": "33195126348,54779", - "www.encodeproject.org%2Ffiles%2FENCFF706SFK%2F%40%40download%2FENCFF706SFK.hic": "3271831702,36479", - "www.encodeproject.org%2Ffiles%2FENCFF922ERE%2F%40%40download%2FENCFF922ERE.hic": "12476647122,36479", - "www.encodeproject.org%2Ffiles%2FENCFF876OWE%2F%40%40download%2FENCFF876OWE.hic": "1538692704,47429", - "www.encodeproject.org%2Ffiles%2FENCFF227XJZ%2F%40%40download%2FENCFF227XJZ.hic": "1925617685,36479", - "www.encodeproject.org%2Ffiles%2FENCFF053BXY%2F%40%40download%2FENCFF053BXY.hic": "1032237652,36479", - "www.encodeproject.org%2Ffiles%2FENCFF014VMM%2F%40%40download%2FENCFF014VMM.hic": "1564021703,36479", - "www.encodeproject.org%2Ffiles%2FENCFF563XES%2F%40%40download%2FENCFF563XES.hic": "1489180508,36479", - "www.encodeproject.org%2Ffiles%2FENCFF482LGO%2F%40%40download%2FENCFF482LGO.hic": "1208778887,36479", - "www.encodeproject.org%2Ffiles%2FENCFF216QQM%2F%40%40download%2FENCFF216QQM.hic": "6293163571,47429", - "www.encodeproject.org%2Ffiles%2FENCFF256UOW%2F%40%40download%2FENCFF256UOW.hic": "6293163571,47429", - "www.encodeproject.org%2Ffiles%2FENCFF791UZC%2F%40%40download%2FENCFF791UZC.hic": "37029615181,54779", - "www.encodeproject.org%2Ffiles%2FENCFF911AHQ%2F%40%40download%2FENCFF911AHQ.hic": "34246649165,54779", - "www.encodeproject.org%2Ffiles%2FENCFF491AOR%2F%40%40download%2FENCFF491AOR.hic": "558663570,36479", - "www.encodeproject.org%2Ffiles%2FENCFF307PDL%2F%40%40download%2FENCFF307PDL.hic": "525321519,36479", - "www.encodeproject.org%2Ffiles%2FENCFF773ITV%2F%40%40download%2FENCFF773ITV.hic": "295464771,36479", - "www.encodeproject.org%2Ffiles%2FENCFF198SSL%2F%40%40download%2FENCFF198SSL.hic": "500142476,36479", - "www.encodeproject.org%2Ffiles%2FENCFF251UEF%2F%40%40download%2FENCFF251UEF.hic": "567443575,36479", - "www.encodeproject.org%2Ffiles%2FENCFF942LTN%2F%40%40download%2FENCFF942LTN.hic": "4430960222,36479", - "www.encodeproject.org%2Ffiles%2FENCFF543USQ%2F%40%40download%2FENCFF543USQ.hic": "5005263062,36479", - "www.encodeproject.org%2Ffiles%2FENCFF434XQU%2F%40%40download%2FENCFF434XQU.hic": "25506511674,54779", - "www.encodeproject.org%2Ffiles%2FENCFF318GOM%2F%40%40download%2FENCFF318GOM.hic": "44750824314,54779", - "www.encodeproject.org%2Ffiles%2FENCFF004TKY%2F%40%40download%2FENCFF004TKY.hic": "20705661833,54779", - "www.encodeproject.org%2Ffiles%2FENCFF493YNC%2F%40%40download%2FENCFF493YNC.hic": "53407154984,54779", - "www.encodeproject.org%2Ffiles%2FENCFF334XXU%2F%40%40download%2FENCFF334XXU.hic": "14341194962,47429", - "www.encodeproject.org%2Ffiles%2FENCFF569RJM%2F%40%40download%2FENCFF569RJM.hic": "1922066634,36479", - "www.encodeproject.org%2Ffiles%2FENCFF076LWH%2F%40%40download%2FENCFF076LWH.hic": "39406255845,54779", - "www.encodeproject.org%2Ffiles%2FENCFF977XWK%2F%40%40download%2FENCFF977XWK.hic": "20563512962,54779", - "www.encodeproject.org%2Ffiles%2FENCFF127TPS%2F%40%40download%2FENCFF127TPS.hic": "21032070512,54779", - "www.encodeproject.org%2Ffiles%2FENCFF480KLP%2F%40%40download%2FENCFF480KLP.hic": "33115569647,54779", - "www.encodeproject.org%2Ffiles%2FENCFF281ILS%2F%40%40download%2FENCFF281ILS.hic": "28236353584,54779", - "www.encodeproject.org%2Ffiles%2FENCFF129LMU%2F%40%40download%2FENCFF129LMU.hic": "35247096013,54779", - "www.encodeproject.org%2Ffiles%2FENCFF759YCW%2F%40%40download%2FENCFF759YCW.hic": "16058537743,32102", - "www.encodeproject.org%2Ffiles%2FENCFF045YOM%2F%40%40download%2FENCFF045YOM.hic": "19775445828,32102", - "www.encodeproject.org%2Ffiles%2FENCFF013TGD%2F%40%40download%2FENCFF013TGD.hic": "4208420532,36479", - "www.encodeproject.org%2Ffiles%2FENCFF929RPW%2F%40%40download%2FENCFF929RPW.hic": "1974260276,36479", - "www.encodeproject.org%2Ffiles%2FENCFF996XEO%2F%40%40download%2FENCFF996XEO.hic": "2072918865,36479", - "www.encodeproject.org%2Ffiles%2FENCFF097SKJ%2F%40%40download%2FENCFF097SKJ.hic": "1983524001,36479", - "www.encodeproject.org%2Ffiles%2FENCFF464KRA%2F%40%40download%2FENCFF464KRA.hic": "1957300131,36479", - "www.encodeproject.org%2Ffiles%2FENCFF406HHC%2F%40%40download%2FENCFF406HHC.hic": "3854527235,36479", - "www.encodeproject.org%2Ffiles%2FENCFF080DPJ%2F%40%40download%2FENCFF080DPJ.hic": "19953768024,47429", - "www.encodeproject.org%2Ffiles%2FENCFF621AIY%2F%40%40download%2FENCFF621AIY.hic": "26781700010,54779", - "www.encodeproject.org%2Ffiles%2FENCFF366ERB%2F%40%40download%2FENCFF366ERB.hic": "1049184239,36479", - "www.encodeproject.org%2Ffiles%2FENCFF997RGL%2F%40%40download%2FENCFF997RGL.hic": "2521167549,36479", - "www.encodeproject.org%2Ffiles%2FENCFF029MPB%2F%40%40download%2FENCFF029MPB.hic": "1854711185,36479", - "www.encodeproject.org%2Ffiles%2FENCFF043EEE%2F%40%40download%2FENCFF043EEE.hic": "2924133032,36479", - "www.encodeproject.org%2Ffiles%2FENCFF920CJR%2F%40%40download%2FENCFF920CJR.hic": "3011577886,36479", - "www.encodeproject.org%2Ffiles%2FENCFF928NJV%2F%40%40download%2FENCFF928NJV.hic": "2778936244,36479", - "www.encodeproject.org%2Ffiles%2FENCFF894GLR%2F%40%40download%2FENCFF894GLR.hic": "2831733099,36479", - "www.encodeproject.org%2Ffiles%2FENCFF303PCK%2F%40%40download%2FENCFF303PCK.hic": "688704435,36479", - "www.encodeproject.org%2Ffiles%2FENCFF999YXX%2F%40%40download%2FENCFF999YXX.hic": "9255069996,56883", - "www.encodeproject.org%2Ffiles%2FENCFF685BLG%2F%40%40download%2FENCFF685BLG.hic": "16797022992,47429", - "www.encodeproject.org%2Ffiles%2FENCFF188SSH%2F%40%40download%2FENCFF188SSH.hic": "16797023050,47429", - "www.encodeproject.org%2Ffiles%2FENCFF465ESX%2F%40%40download%2FENCFF465ESX.hic": "13489465953,32102", - "www.encodeproject.org%2Ffiles%2FENCFF493SFI%2F%40%40download%2FENCFF493SFI.hic": "30033046818,54779", - "www.encodeproject.org%2Ffiles%2FENCFF235LCO%2F%40%40download%2FENCFF235LCO.hic": "38572174589,54779", - "www.encodeproject.org%2Ffiles%2FENCFF625VNK%2F%40%40download%2FENCFF625VNK.hic": "45202258438,54779", - "www.encodeproject.org%2Ffiles%2FENCFF304HMS%2F%40%40download%2FENCFF304HMS.hic": "36994445315,54779", - "www.encodeproject.org%2Ffiles%2FENCFF605CEN%2F%40%40download%2FENCFF605CEN.hic": "40358346301,54779", - "www.encodeproject.org%2Ffiles%2FENCFF086ORS%2F%40%40download%2FENCFF086ORS.hic": "22650781304,54779", - "www.encodeproject.org%2Ffiles%2FENCFF237UKR%2F%40%40download%2FENCFF237UKR.hic": "41516707246,54779", - "www.encodeproject.org%2Ffiles%2FENCFF004YZQ%2F%40%40download%2FENCFF004YZQ.hic": "71900665326,54779", - "www.encodeproject.org%2Ffiles%2FENCFF104THR%2F%40%40download%2FENCFF104THR.hic": "15172410632,54779", - "www.encodeproject.org%2Ffiles%2FENCFF807IRK%2F%40%40download%2FENCFF807IRK.hic": "17346637451,54779", - "www.encodeproject.org%2Ffiles%2FENCFF193CQL%2F%40%40download%2FENCFF193CQL.hic": "55726903245,54779", - "www.encodeproject.org%2Ffiles%2FENCFF700DEX%2F%40%40download%2FENCFF700DEX.hic": "20231399798,54779", - "www.encodeproject.org%2Ffiles%2FENCFF234MDO%2F%40%40download%2FENCFF234MDO.hic": "24635312640,54779", - "www.encodeproject.org%2Ffiles%2FENCFF181ROW%2F%40%40download%2FENCFF181ROW.hic": "26883606497,54779", - "www.encodeproject.org%2Ffiles%2FENCFF896OFN%2F%40%40download%2FENCFF896OFN.hic": "36952196833,54779", - "www.encodeproject.org%2Ffiles%2FENCFF573OPJ%2F%40%40download%2FENCFF573OPJ.hic": "36685546919,54779", - "www.encodeproject.org%2Ffiles%2FENCFF028RXH%2F%40%40download%2FENCFF028RXH.hic": "31053919206,54779", - "www.encodeproject.org%2Ffiles%2FENCFF156GGD%2F%40%40download%2FENCFF156GGD.hic": "35284134289,54779", - "www.encodeproject.org%2Ffiles%2FENCFF496GEU%2F%40%40download%2FENCFF496GEU.hic": "44659660933,54779", - "www.encodeproject.org%2Ffiles%2FENCFF945TUH%2F%40%40download%2FENCFF945TUH.hic": "3898570191,35639", - "www.encodeproject.org%2Ffiles%2FENCFF698KFV%2F%40%40download%2FENCFF698KFV.hic": "4427896684,35751", - "www.encodeproject.org%2Ffiles%2FENCFF239BHZ%2F%40%40download%2FENCFF239BHZ.hic": "1718552021,36479", - "www.encodeproject.org%2Ffiles%2FENCFF277LAN%2F%40%40download%2FENCFF277LAN.hic": "4542391336,36479", - "www.encodeproject.org%2Ffiles%2FENCFF397CMD%2F%40%40download%2FENCFF397CMD.hic": "2832016430,36479", - "www.encodeproject.org%2Ffiles%2FENCFF778OYA%2F%40%40download%2FENCFF778OYA.hic": "14067187484,47429", - "www.encodeproject.org%2Ffiles%2FENCFF775VSU%2F%40%40download%2FENCFF775VSU.hic": "14067187484,47429", - "www.encodeproject.org%2Ffiles%2FENCFF812THZ%2F%40%40download%2FENCFF812THZ.hic": "9667720429,36479", - "www.encodeproject.org%2Ffiles%2FENCFF777KBU%2F%40%40download%2FENCFF777KBU.hic": "5058284320,36479", - "www.encodeproject.org%2Ffiles%2FENCFF688KOY%2F%40%40download%2FENCFF688KOY.hic": "4198695833,36479", - "www.encodeproject.org%2Ffiles%2FENCFF223UBX%2F%40%40download%2FENCFF223UBX.hic": "1206064037,36479", - "www.encodeproject.org%2Ffiles%2FENCFF273XBU%2F%40%40download%2FENCFF273XBU.hic": "44085607579,54779", - "www.encodeproject.org%2Ffiles%2FENCFF952JZV%2F%40%40download%2FENCFF952JZV.hic": "44728845246,54779", - "www.encodeproject.org%2Ffiles%2FENCFF643NDM%2F%40%40download%2FENCFF643NDM.hic": "35877886780,54779", - "www.encodeproject.org%2Ffiles%2FENCFF586MQY%2F%40%40download%2FENCFF586MQY.hic": "71158037547,54779", - "www.encodeproject.org%2Ffiles%2FENCFF251VFA%2F%40%40download%2FENCFF251VFA.hic": "40089479399,54779", - "www.encodeproject.org%2Ffiles%2FENCFF033WGK%2F%40%40download%2FENCFF033WGK.hic": "30802023728,54779", - "www.encodeproject.org%2Ffiles%2FENCFF649OHR%2F%40%40download%2FENCFF649OHR.hic": "28203184265,54779", - "www.encodeproject.org%2Ffiles%2FENCFF782WVZ%2F%40%40download%2FENCFF782WVZ.hic": "37248221674,54779", - "www.encodeproject.org%2Ffiles%2FENCFF579CAR%2F%40%40download%2FENCFF579CAR.hic": "39662025395,54779", - "www.encodeproject.org%2Ffiles%2FENCFF514XWQ%2F%40%40download%2FENCFF514XWQ.hic": "1319613701,36479", - "www.encodeproject.org%2Ffiles%2FENCFF666USK%2F%40%40download%2FENCFF666USK.hic": "15051670107,32102", - "www.encodeproject.org%2Ffiles%2FENCFF047SDP%2F%40%40download%2FENCFF047SDP.hic": "1357076705,16438", - "www.encodeproject.org%2Ffiles%2FENCFF584LEP%2F%40%40download%2FENCFF584LEP.hic": "9314176858,36479", - "www.encodeproject.org%2Ffiles%2FENCFF671SOE%2F%40%40download%2FENCFF671SOE.hic": "3273732256,16438", - "www.encodeproject.org%2Ffiles%2FENCFF702LAP%2F%40%40download%2FENCFF702LAP.hic": "1800427500,31682", - "www.encodeproject.org%2Ffiles%2FENCFF339PON%2F%40%40download%2FENCFF339PON.hic": "5394351199,31514", - "www.encodeproject.org%2Ffiles%2FENCFF741QPR%2F%40%40download%2FENCFF741QPR.hic": "4271510019,30139", - "www.encodeproject.org%2Ffiles%2FENCFF103ANX%2F%40%40download%2FENCFF103ANX.hic": "4439745804,30083", - "www.encodeproject.org%2Ffiles%2FENCFF395SBC%2F%40%40download%2FENCFF395SBC.hic": "1596732351,31850", - "www.encodeproject.org%2Ffiles%2FENCFF289WNN%2F%40%40download%2FENCFF289WNN.hic": "8632980535,32102", - "www.encodeproject.org%2Ffiles%2FENCFF381EAU%2F%40%40download%2FENCFF381EAU.hic": "1702476311,36479", - "www.encodeproject.org%2Ffiles%2FENCFF976FEY%2F%40%40download%2FENCFF976FEY.hic": "1448279040,36479", - "www.encodeproject.org%2Ffiles%2FENCFF485LVS%2F%40%40download%2FENCFF485LVS.hic": "1593610856,36479", - "www.encodeproject.org%2Ffiles%2FENCFF143VJV%2F%40%40download%2FENCFF143VJV.hic": "1422312076,36479", - "www.encodeproject.org%2Ffiles%2FENCFF588NHX%2F%40%40download%2FENCFF588NHX.hic": "3943637009,36479", - "www.encodeproject.org%2Ffiles%2FENCFF768UBD%2F%40%40download%2FENCFF768UBD.hic": "24786676166,36479", - "www.encodeproject.org%2Ffiles%2FENCFF965PEE%2F%40%40download%2FENCFF965PEE.hic": "29387092778,47429", - "www.encodeproject.org%2Ffiles%2FENCFF702IFC%2F%40%40download%2FENCFF702IFC.hic": "29387092778,47429", - "www.encodeproject.org%2Ffiles%2FENCFF288DNV%2F%40%40download%2FENCFF288DNV.hic": "10313429504,36479", - "www.encodeproject.org%2Ffiles%2FENCFF698HWZ%2F%40%40download%2FENCFF698HWZ.hic": "10962849269,47429", - "www.encodeproject.org%2Ffiles%2FENCFF355OWW%2F%40%40download%2FENCFF355OWW.hic": "3219571601,36479", - "www.encodeproject.org%2Ffiles%2FENCFF177TYX%2F%40%40download%2FENCFF177TYX.hic": "10325679706,36479", - "www.encodeproject.org%2Ffiles%2FENCFF542BHD%2F%40%40download%2FENCFF542BHD.hic": "11085397879,47429", - "www.encodeproject.org%2Ffiles%2FENCFF684IFW%2F%40%40download%2FENCFF684IFW.hic": "11085397879,47429", - "www.encodeproject.org%2Ffiles%2FENCFF592UHE%2F%40%40download%2FENCFF592UHE.hic": "21363948089,32102", - "www.encodeproject.org%2Ffiles%2FENCFF779XIS%2F%40%40download%2FENCFF779XIS.hic": "9517383271,36479", - "www.encodeproject.org%2Ffiles%2FENCFF518PSL%2F%40%40download%2FENCFF518PSL.hic": "7500581463,36479", - "www.encodeproject.org%2Ffiles%2FENCFF275GBB%2F%40%40download%2FENCFF275GBB.hic": "7889407162,36479", - "www.encodeproject.org%2Ffiles%2FENCFF634KXI%2F%40%40download%2FENCFF634KXI.hic": "6430702966,36479", - "www.encodeproject.org%2Ffiles%2FENCFF337QPM%2F%40%40download%2FENCFF337QPM.hic": "8529733887,36479", - "www.encodeproject.org%2Ffiles%2FENCFF162KMP%2F%40%40download%2FENCFF162KMP.hic": "5615896908,36479", - "www.encodeproject.org%2Ffiles%2FENCFF992VTE%2F%40%40download%2FENCFF992VTE.hic": "7328975027,36479", - "www.encodeproject.org%2Ffiles%2FENCFF464WXY%2F%40%40download%2FENCFF464WXY.hic": "5715339664,36479", - "www.encodeproject.org%2Ffiles%2FENCFF752EGH%2F%40%40download%2FENCFF752EGH.hic": "1733758743,36479", - "www.encodeproject.org%2Ffiles%2FENCFF474UJM%2F%40%40download%2FENCFF474UJM.hic": "222309548,18679", - "www.encodeproject.org%2Ffiles%2FENCFF531UPZ%2F%40%40download%2FENCFF531UPZ.hic": "1827756846,36479", - "www.encodeproject.org%2Ffiles%2FENCFF022VHA%2F%40%40download%2FENCFF022VHA.hic": "244983451,18679", - "www.encodeproject.org%2Ffiles%2FENCFF732NGR%2F%40%40download%2FENCFF732NGR.hic": "1679484567,36479", - "www.encodeproject.org%2Ffiles%2FENCFF513VSF%2F%40%40download%2FENCFF513VSF.hic": "28397932940,36479", - "www.encodeproject.org%2Ffiles%2FENCFF750AOC%2F%40%40download%2FENCFF750AOC.hic": "36471430712,47429", - "www.encodeproject.org%2Ffiles%2FENCFF219YOB%2F%40%40download%2FENCFF219YOB.hic": "2859767211,26979", - "www.encodeproject.org%2Ffiles%2FENCFF604YDD%2F%40%40download%2FENCFF604YDD.hic": "3549694085,26979", - "www.encodeproject.org%2Ffiles%2FENCFF746AMV%2F%40%40download%2FENCFF746AMV.hic": "2954867135,26979", - "www.encodeproject.org%2Ffiles%2FENCFF845ZEB%2F%40%40download%2FENCFF845ZEB.hic": "2763039282,26979", - "www.encodeproject.org%2Ffiles%2FENCFF570LWS%2F%40%40download%2FENCFF570LWS.hic": "2861588289,26979", - "www.encodeproject.org%2Ffiles%2FENCFF883YVR%2F%40%40download%2FENCFF883YVR.hic": "2433679887,26979", - "www.encodeproject.org%2Ffiles%2FENCFF056VLK%2F%40%40download%2FENCFF056VLK.hic": "2502986910,26979", - "www.encodeproject.org%2Ffiles%2FENCFF532DUQ%2F%40%40download%2FENCFF532DUQ.hic": "3172615899,26979", - "www.encodeproject.org%2Ffiles%2FENCFF723PYJ%2F%40%40download%2FENCFF723PYJ.hic": "10292839095,36479", - "www.encodeproject.org%2Ffiles%2FENCFF991SGJ%2F%40%40download%2FENCFF991SGJ.hic": "13072407683,32102", - "www.encodeproject.org%2Ffiles%2FENCFF885UZI%2F%40%40download%2FENCFF885UZI.hic": "1201881201,16438", - "www.encodeproject.org%2Ffiles%2FENCFF287KXA%2F%40%40download%2FENCFF287KXA.hic": "14705801988,32102", - "www.encodeproject.org%2Ffiles%2FENCFF335HYI%2F%40%40download%2FENCFF335HYI.hic": "20366756545,32102", - "www.encodeproject.org%2Ffiles%2FENCFF121YPY%2F%40%40download%2FENCFF121YPY.hic": "2760104016,26979", - "www.encodeproject.org%2Ffiles%2FENCFF675SJE%2F%40%40download%2FENCFF675SJE.hic": "3751779995,26979", - "www.encodeproject.org%2Ffiles%2FENCFF876LAW%2F%40%40download%2FENCFF876LAW.hic": "4032376256,26979", - "www.encodeproject.org%2Ffiles%2FENCFF740KVX%2F%40%40download%2FENCFF740KVX.hic": "3202490322,26979", - "www.encodeproject.org%2Ffiles%2FENCFF977OQV%2F%40%40download%2FENCFF977OQV.hic": "2919735477,26979", - "www.encodeproject.org%2Ffiles%2FENCFF525EFN%2F%40%40download%2FENCFF525EFN.hic": "2394748073,26979", - "www.encodeproject.org%2Ffiles%2FENCFF690QRC%2F%40%40download%2FENCFF690QRC.hic": "3183023394,26979", - "www.encodeproject.org%2Ffiles%2FENCFF452FWS%2F%40%40download%2FENCFF452FWS.hic": "2951805127,26979", - "www.encodeproject.org%2Ffiles%2FENCFF089KBG%2F%40%40download%2FENCFF089KBG.hic": "2531936700,26979", - "www.encodeproject.org%2Ffiles%2FENCFF939ARM%2F%40%40download%2FENCFF939ARM.hic": "3066385212,26979", - "www.encodeproject.org%2Ffiles%2FENCFF401ZAN%2F%40%40download%2FENCFF401ZAN.hic": "3008677144,26979", - "www.encodeproject.org%2Ffiles%2FENCFF378RZT%2F%40%40download%2FENCFF378RZT.hic": "2830232168,26979", - "www.encodeproject.org%2Ffiles%2FENCFF304AVD%2F%40%40download%2FENCFF304AVD.hic": "6164439305,50358", - "www.encodeproject.org%2Ffiles%2FENCFF453DBX%2F%40%40download%2FENCFF453DBX.hic": "6775246670,36479", - "www.encodeproject.org%2Ffiles%2FENCFF590VOM%2F%40%40download%2FENCFF590VOM.hic": "6443478922,36479", - "www.encodeproject.org%2Ffiles%2FENCFF246DOF%2F%40%40download%2FENCFF246DOF.hic": "6837914659,36479", - "www.encodeproject.org%2Ffiles%2FENCFF125FXX%2F%40%40download%2FENCFF125FXX.hic": "9736232550,36479", - "www.encodeproject.org%2Ffiles%2FENCFF241RAY%2F%40%40download%2FENCFF241RAY.hic": "7686758397,36479", - "www.encodeproject.org%2Ffiles%2FENCFF415XWQ%2F%40%40download%2FENCFF415XWQ.hic": "6973092068,36479", - "www.encodeproject.org%2Ffiles%2FENCFF374EBH%2F%40%40download%2FENCFF374EBH.hic": "8557459058,36479", - "www.encodeproject.org%2Ffiles%2FENCFF263YWR%2F%40%40download%2FENCFF263YWR.hic": "331586820,18679", - "www.encodeproject.org%2Ffiles%2FENCFF280CGS%2F%40%40download%2FENCFF280CGS.hic": "1743569614,36479", - "www.encodeproject.org%2Ffiles%2FENCFF553ZNS%2F%40%40download%2FENCFF553ZNS.hic": "1717253636,36479", - "www.encodeproject.org%2Ffiles%2FENCFF451VOI%2F%40%40download%2FENCFF451VOI.hic": "1626927468,36479", - "www.encodeproject.org%2Ffiles%2FENCFF420MQO%2F%40%40download%2FENCFF420MQO.hic": "31055961677,36479", - "www.encodeproject.org%2Ffiles%2FENCFF301BWY%2F%40%40download%2FENCFF301BWY.hic": "38902429246,47429", - "www.encodeproject.org%2Ffiles%2FENCFF606XNW%2F%40%40download%2FENCFF606XNW.hic": "1009699327,36479", - "www.encodeproject.org%2Ffiles%2FENCFF439ZOU%2F%40%40download%2FENCFF439ZOU.hic": "12381714313,36479", - "www.encodeproject.org%2Ffiles%2FENCFF499SYK%2F%40%40download%2FENCFF499SYK.hic": "13182654663,47429", - "www.encodeproject.org%2Ffiles%2FENCFF532LFI%2F%40%40download%2FENCFF532LFI.hic": "8286030286,36479", - "www.encodeproject.org%2Ffiles%2FENCFF020DPP%2F%40%40download%2FENCFF020DPP.hic": "23521952420,47429", - "www.encodeproject.org%2Ffiles%2FENCFF306VTV%2F%40%40download%2FENCFF306VTV.hic": "23521952480,47429", - "www.encodeproject.org%2Ffiles%2FENCFF399IHE%2F%40%40download%2FENCFF399IHE.hic": "10216571232,36479", - "www.encodeproject.org%2Ffiles%2FENCFF944AII%2F%40%40download%2FENCFF944AII.hic": "12567308552,47429", - "www.encodeproject.org%2Ffiles%2FENCFF230HVV%2F%40%40download%2FENCFF230HVV.hic": "8629849711,36479", - "www.encodeproject.org%2Ffiles%2FENCFF174LAF%2F%40%40download%2FENCFF174LAF.hic": "9446506633,47429", - "www.encodeproject.org%2Ffiles%2FENCFF898HRO%2F%40%40download%2FENCFF898HRO.hic": "9446506633,47429", - "www.encodeproject.org%2Ffiles%2FENCFF429MOR%2F%40%40download%2FENCFF429MOR.hic": "1455757398,36479", - "www.encodeproject.org%2Ffiles%2FENCFF061NXV%2F%40%40download%2FENCFF061NXV.hic": "1710915891,36479", - "www.encodeproject.org%2Ffiles%2FENCFF434PYS%2F%40%40download%2FENCFF434PYS.hic": "1832274903,36479", - "www.encodeproject.org%2Ffiles%2FENCFF704HHX%2F%40%40download%2FENCFF704HHX.hic": "1768142834,36479", - "www.encodeproject.org%2Ffiles%2FENCFF349DPM%2F%40%40download%2FENCFF349DPM.hic": "4316041260,36479", - "www.encodeproject.org%2Ffiles%2FENCFF718AWL%2F%40%40download%2FENCFF718AWL.hic": "39544267907,58932", - "www.encodeproject.org%2Ffiles%2FENCFF065LSP%2F%40%40download%2FENCFF065LSP.hic": "24929805283,55874", - "www.encodeproject.org%2Ffiles%2FENCFF632MFV%2F%40%40download%2FENCFF632MFV.hic": "22333105467,55798", - "www.encodeproject.org%2Ffiles%2FENCFF179HVU%2F%40%40download%2FENCFF179HVU.hic": "2659219603,36479", - "www.encodeproject.org%2Ffiles%2FENCFF791SPZ%2F%40%40download%2FENCFF791SPZ.hic": "2537491657,36479", - "www.encodeproject.org%2Ffiles%2FENCFF211ZWF%2F%40%40download%2FENCFF211ZWF.hic": "3512141227,36479", - "www.encodeproject.org%2Ffiles%2FENCFF614BNU%2F%40%40download%2FENCFF614BNU.hic": "5252155462,36479", - "www.encodeproject.org%2Ffiles%2FENCFF891DLM%2F%40%40download%2FENCFF891DLM.hic": "2549095612,36479", - "www.encodeproject.org%2Ffiles%2FENCFF056EXT%2F%40%40download%2FENCFF056EXT.hic": "2219014704,36479", - "www.encodeproject.org%2Ffiles%2FENCFF776DSS%2F%40%40download%2FENCFF776DSS.hic": "3920308353,36479", - "www.encodeproject.org%2Ffiles%2FENCFF814LQF%2F%40%40download%2FENCFF814LQF.hic": "1349480197,36479", - "www.encodeproject.org%2Ffiles%2FENCFF513ZNA%2F%40%40download%2FENCFF513ZNA.hic": "2638868195,36479", - "www.encodeproject.org%2Ffiles%2FENCFF692IOL%2F%40%40download%2FENCFF692IOL.hic": "3106768498,36479", - "www.encodeproject.org%2Ffiles%2FENCFF294WZY%2F%40%40download%2FENCFF294WZY.hic": "2211089761,36479", - "www.encodeproject.org%2Ffiles%2FENCFF339UWS%2F%40%40download%2FENCFF339UWS.hic": "2142759055,36479", - "www.encodeproject.org%2Ffiles%2FENCFF835FSK%2F%40%40download%2FENCFF835FSK.hic": "3919821739,36479", - "www.encodeproject.org%2Ffiles%2FENCFF328BMB%2F%40%40download%2FENCFF328BMB.hic": "2550686152,36479", - "www.encodeproject.org%2Ffiles%2FENCFF897RTY%2F%40%40download%2FENCFF897RTY.hic": "1323294397,36479", - "www.encodeproject.org%2Ffiles%2FENCFF306MWH%2F%40%40download%2FENCFF306MWH.hic": "1665386199,36479", - "www.encodeproject.org%2Ffiles%2FENCFF039YUJ%2F%40%40download%2FENCFF039YUJ.hic": "2335679939,36479", - "www.encodeproject.org%2Ffiles%2FENCFF468QIN%2F%40%40download%2FENCFF468QIN.hic": "3352516594,36479", - "www.encodeproject.org%2Ffiles%2FENCFF364WXU%2F%40%40download%2FENCFF364WXU.hic": "3959043175,36479", - "www.encodeproject.org%2Ffiles%2FENCFF373MSH%2F%40%40download%2FENCFF373MSH.hic": "4429550624,36479", - "www.encodeproject.org%2Ffiles%2FENCFF959EGQ%2F%40%40download%2FENCFF959EGQ.hic": "2475218228,36479", - "www.encodeproject.org%2Ffiles%2FENCFF624XMK%2F%40%40download%2FENCFF624XMK.hic": "3527855681,36479", - "www.encodeproject.org%2Ffiles%2FENCFF445OKS%2F%40%40download%2FENCFF445OKS.hic": "3369125589,36479", - "www.encodeproject.org%2Ffiles%2FENCFF239QDV%2F%40%40download%2FENCFF239QDV.hic": "1960069888,36479", - "www.encodeproject.org%2Ffiles%2FENCFF645AVM%2F%40%40download%2FENCFF645AVM.hic": "4969006589,36479", - "www.encodeproject.org%2Ffiles%2FENCFF494IPI%2F%40%40download%2FENCFF494IPI.hic": "1565483792,36479", - "www.encodeproject.org%2Ffiles%2FENCFF753IXE%2F%40%40download%2FENCFF753IXE.hic": "2892400648,36479", - "www.encodeproject.org%2Ffiles%2FENCFF731GXX%2F%40%40download%2FENCFF731GXX.hic": "5131381303,36479", - "www.encodeproject.org%2Ffiles%2FENCFF369CAQ%2F%40%40download%2FENCFF369CAQ.hic": "4236629448,36479", - "www.encodeproject.org%2Ffiles%2FENCFF053VBX%2F%40%40download%2FENCFF053VBX.hic": "54305946375,47429", - "www.encodeproject.org%2Ffiles%2FENCFF555ISR%2F%40%40download%2FENCFF555ISR.hic": "54305946434,47429", - "www.encodeproject.org%2Ffiles%2FENCFF964RSP%2F%40%40download%2FENCFF964RSP.hic": "12065485229,36479", - "www.encodeproject.org%2Ffiles%2FENCFF234MZQ%2F%40%40download%2FENCFF234MZQ.hic": "17507142760,47429", - "www.encodeproject.org%2Ffiles%2FENCFF994CEG%2F%40%40download%2FENCFF994CEG.hic": "17507142760,47429", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fb068e787-bbdd-49e2-9f6d-7a0e9f065d6e%2F4DNFIHSUIRFY.hic": "2701182442,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3768b89a-e124-40eb-8acd-94a4fdd35807%2F4DNFIXTAS6EE.hic": "3283740601,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F9c513602-5abb-4088-8415-c827c381ab0d%2F4DNFIC3JD6O2.hic": "4896075767,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fde954dad-1849-4c23-beb4-bf893b7d76c9%2F4DNFIGY85S4W.hic": "3364151996,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fe1befa6e-8067-4296-8db2-67d2a2458985%2F4DNFI2LTNXME.hic": "3699291418,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fbb3307fd-7162-477a-87c5-52f12d03befc%2F4DNFID162B9J.hic": "3576428773,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8597cdae-8319-42d9-9175-3f77aaee34e1%2F4DNFIQWS3632.hic": "4022561190,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F327f091d-6a63-47c4-9752-2dff303a13d9%2F4DNFI6GFHB6G.hic": "4239331168,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd70dc3b8-48a7-42c2-bd23-80bc44fc2266%2F4DNFIS5F6EBL.hic": "4404671861,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F77df7bf8-6a3d-407a-8968-4ca1e78d2269%2F4DNFIF2D3TL9.hic": "4793989394,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc8f7cc35-d2ef-4717-9009-c02154050fbf%2F4DNFI6EIFUZI.hic": "3370273763,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F98449d79-30d1-4e32-801d-07435819a42f%2F4DNFIRKGMZRQ.hic": "4669813207,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd4fe1844-2493-4722-8b98-34a93a4bb7d8%2F4DNFIQWD8ZYD.hic": "5379889057,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F1ee40499-1de4-47ff-b540-d9a65943c6b8%2F4DNFIX7H3CE2.hic": "4857679239,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fac016170-23a7-4111-8773-353d6c150f34%2F4DNFIO21YDCV.hic": "4695989644,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F1faea4e7-9a32-466e-a826-0bfdab6cd915%2F4DNFIUE5RAS6.hic": "4788044799,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fcbd396ed-11bb-404f-aed9-ef10abc258e6%2F4DNFIFI6NIKJ.hic": "2069414927,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Faf3f78db-ae92-4215-bcae-76d30c617e5d%2F4DNFIL5K3MA1.hic": "2585598247,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F66fc2893-224e-48b4-bdb0-25e022dedd03%2F4DNFIPV5KFMK.hic": "2060965679,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F2b39781d-aadc-434f-abe3-562d61308fdd%2F4DNFIW8TIFI5.hic": "1694424195,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fb6d28f7b-27d3-486f-b5ac-32567416560d%2F4DNFIA6NSSBJ.hic": "2219532611,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F08785616-722e-46bb-ade2-2fdd21324e11%2F4DNFIBKZK63V.hic": "2429136232,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F904b13d3-1203-42a4-812c-963e80c159b1%2F4DNFI3CFMRID.hic": "1233390166,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fb0ed4afe-5ecf-451d-bb1f-444697e3f558%2F4DNFIYIAUEPW.hic": "1753567534,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F4bb9a9b3-12a8-4d2f-8071-4722294c88ea%2F4DNFIC3HAU11.hic": "2271375254,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F5abf9c36-c1d1-44dc-8197-74d860d896c0%2F4DNFIM2BMJ33.hic": "1770471113,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fa68475db-7816-4cec-b2da-d4ce4a0c7a0e%2F4DNFIBY3UHJB.hic": "2095528423,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F07c40943-0d0b-4b3e-94a0-8583b0e00b47%2F4DNFIWZEN3FF.hic": "1558559508,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd8a39553-2718-4866-9b2a-45d8e9c5ac6f%2F4DNFIE5TEYK7.hic": "1323063102,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F294b61ef-5565-4f04-ade9-f921a6686cce%2F4DNFI7H4II2V.hic": "1436947982,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F87a70ad7-7d34-4302-9c03-eb824bd4e633%2F4DNFIAS8LV1C.hic": "1263105698,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F9db804c6-5a91-4cf5-8ae9-e054223afb77%2F4DNFIBXWIH8J.hic": "1587059951,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd1e55906-ec8f-444b-8ce1-2de22a431a76%2F4DNFIO2HBDAI.hic": "1666436393,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F7a4b9b37-8e38-470c-8190-fd4d513c0bbb%2F4DNFIXWCLD4M.hic": "1513511880,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F6c7615b2-5310-4bbf-a605-98761d3a3079%2F4DNFINASC4NQ.hic": "1420358914,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F20454014-49cd-4e2d-93da-f40ad52776d5%2F4DNFIZF1KI43.hic": "1377041630,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F5df04e86-ee2a-45f2-b878-bf1648e2cca5%2F4DNFIQBHR9XC.hic": "1179502734,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F9d1cc910-bb3f-4106-802a-73184c58d5ba%2F4DNFIQVMVRP6.hic": "1811976991,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fe431986b-0732-460f-92ff-0abd1694d2d0%2F4DNFIJ7OAIFQ.hic": "1685503856,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F56d0c575-4962-4ea3-92c3-55bd0e17c096%2F4DNFIE8E4ANZ.hic": "1598369564,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fdb1502fb-a989-4ef9-b800-7eaa7be172ae%2F4DNFIOUSETUP.hic": "1493294709,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Facc2f1c3-8c96-4d21-814a-3a8ba81e7741%2F4DNFIVJ3IIQL.hic": "1472376655,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F037fb4c3-8641-4953-a977-cc71f2137582%2F4DNFIHN2QSMX.hic": "1179632606,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F16d2c3c0-6d29-4815-b074-b142af90b615%2F4DNFIILDWK8M.hic": "2280059989,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F31789849-e4db-45d8-9730-66a048c02d8a%2F4DNFI6XD6JAQ.hic": "2253961696,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fff04947e-e6e8-4d62-8374-ef2ee4104809%2F4DNFIALNLR78.hic": "1914687914,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F53e6c1e7-9410-4158-84e6-57c2e683b095%2F4DNFIBT4EAKN.hic": "2296378356,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F0127900a-258f-4815-97d2-6fd2b043d853%2F4DNFIDJ2JZ7Q.hic": "2558945393,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F89f95693-3d28-44eb-9d45-14932f8e258c%2F4DNFI8JFOAJT.hic": "1726440253,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd803d818-b0d4-4796-8d61-a9f3943f3b10%2F4DNFIRZA6EV6.hic": "1805017504,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff9165fb1-0782-4757-a740-5b929e0252bb%2F4DNFIB7QTIMH.hic": "2541020707,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff8d916b2-b58e-4cdf-894c-ffcb3bf6ebd9%2F4DNFIJ5DQZVK.hic": "2445734043,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F14066a5b-e01a-43c2-a468-b18826174df3%2F4DNFISTWNV9C.hic": "2499319890,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd0692151-7f9a-4475-b059-f8802616dded%2F4DNFIBN9K4V9.hic": "1591570769,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F70a7ef36-a514-4e45-918f-47c4e9e30ef4%2F4DNFIR8OU6QJ.hic": "1689882108,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F180306cd-8593-413a-ae83-24f19209c5d2%2F4DNFIDSWKFF5.hic": "1596696630,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F6e7b9be7-f465-4434-8e9c-68d1e44a76af%2F4DNFIV239W4L.hic": "2345867406,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F55df948c-941d-4930-854c-6a07557a0c1d%2F4DNFIREVU1Z5.hic": "2254683002,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3f590cb7-df3a-498f-81c3-d5ed4179b8ad%2F4DNFIFHU75I5.hic": "2497670883,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8f064770-6008-4f74-bfca-268d4a22d745%2F4DNFIMROE6N4.hic": "9850583704,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fa93d0588-76b7-4ccf-933c-4325876b0a53%2F4DNFI5SUHCGZ.hic": "10364705187,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F2f5f0d6b-0b22-4936-93c9-0944d49c037b%2F4DNFII84FBKM.hic": "8836986129,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F12e90fc5-0b76-4e42-b346-58d267f9ad6e%2F4DNFI2J1ODWB.hic": "13410858286,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff2702a45-3e8b-4980-bcd5-6bb0e291614f%2F4DNFIJWBWE41.hic": "20515676755,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fa0859349-5f06-4ad3-b56f-b1166b34a9eb%2F4DNFIIMZB6Y9.hic": "15350325963,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F12685c57-d54a-46fa-9efb-acf34ed77574%2F4DNFICJECID5.hic": "1525002266,26979", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd101a58e-89aa-44fd-96c5-6bf1e2476272%2F4DNFIR6UW2QA.hic": "1264999913,26979", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3d8c73bf-1335-4af4-b124-e3622d48c5f6%2F4DNFIGOEKBUZ.hic": "1905947578,26979", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fcd2477cf-6ed0-4d7b-b4e9-88fb38b0df48%2F4DNFIMDNAEW4.hic": "996444147,26979", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F0f03953e-29da-4f2e-8c05-572d0edf4525%2F4DNFI5OSZ3JC.hic": "369361754,22829", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F29d95dbb-005a-4ae1-8b9c-0fec9ec0bbd0%2F4DNFI7KOUGFM.hic": "1227434049,26979", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fa441ab7b-afbe-437d-bf98-b6b916558642%2F4DNFIGKX4A32.hic": "883933242,26979", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F941b2f94-2fff-4d3c-aceb-fee4a5ae41a9%2F4DNFI1ORHOTA.hic": "1140970677,26979", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8720ede9-093f-4c00-912f-373283260a16%2F4DNFIWSVLZED.hic": "458091151,26979", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fe9e17155-2b62-4a68-afb2-31dfa674e169%2F4DNFI6H926RO.hic": "3552863515,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F22f22778-987a-4dc0-97bc-f26eae0156d9%2F4DNFIKTYSPOF.hic": "2939475400,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F40f40192-0acb-44cb-8778-8d21afe593fb%2F4DNFIZ4S52BV.hic": "3067438113,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd8767374-7018-4e11-9226-bf5612d39ebb%2F4DNFI3APMXHF.hic": "3258874744,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8c5140ec-a65a-4186-8c59-2927233eecaa%2F4DNFIQLIKDSD.hic": "2746398416,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8cdedda6-d7d8-4231-a85b-d56fcd962366%2F4DNFIKYXMF1E.hic": "14442148774,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Faa4d4497-7c6c-4dad-8040-be13ba07ea32%2F4DNFI9815EEJ.hic": "17960817603,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fe9b7b95f-190b-49fe-8047-ef4a8fc59746%2F4DNFIQ2687RT.hic": "15954277087,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F59863d3a-8d7c-49c7-9a41-7f2a58ad24d1%2F4DNFIYDBBSE3.hic": "16499534862,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3e80ca41-b3e0-4f4f-a05e-8f95fe96d938%2F4DNFIMOCN1YS.hic": "863725312,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F96f97a01-0020-4f09-93e8-fc8a9fd07218%2F4DNFI6558CM8.hic": "1597967345,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fce9e9334-ee0b-4549-a845-110470ba5986%2F4DNFIQZRKS7Y.hic": "907626411,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fdaac8209-1015-48da-9e31-2e252dfd8fe0%2F4DNFIX4DLXSE.hic": "1369766288,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F268b7d52-9655-474c-9467-8ba31bb2195c%2F4DNFII3JV8I1.hic": "856656441,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F9681f9b5-335a-4f56-afa1-15b58bbb41e8%2F4DNFI5IAH9H1.hic": "1495185175,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3e082eab-95aa-4677-88ed-9d7adcc1effb%2F4DNFIK5HY1GP.hic": "2135337789,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F31af1ead-4520-4669-957e-424b4b197c33%2F4DNFIFA89L5B.hic": "1975593640,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fcc2b78fd-52d4-4e0c-ac93-b84ee82daf7e%2F4DNFICXCFGEI.hic": "2628202920,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff54efece-280f-46ca-95e3-1f8a3cd18820%2F4DNFIK4CECUH.hic": "1901129375,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F1181c0c4-afb7-4b6a-9fdc-d868fb2253fc%2F4DNFI1EYIGOC.hic": "1947135384,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F1d3e2905-b9b9-4b91-bcb4-8d34746e78f6%2F4DNFI7TLEWUI.hic": "1185758726,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Faba3d42f-39cd-4a85-9d3f-835aefb5c803%2F4DNFIVCJKHMN.hic": "687240974,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F27f54fcb-54fe-41a4-b25a-2f8944c89044%2F4DNFIN8F14CS.hic": "1304082029,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fb75fedb5-88f4-4bc0-8e38-298df7847a7f%2F4DNFI5LCW273.hic": "12497258313,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F2f22b2a0-3712-496e-92d2-63775ec0e421%2F4DNFIVSCH2CH.hic": "12594733778,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F07e47261-5863-44f5-9198-76e263081bea%2F4DNFIZ268JGC.hic": "1499059135,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F682b1ae1-3ac3-40e4-a330-c49f63946952%2F4DNFIJ1P4HBI.hic": "1190211725,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F197e7c89-ea73-41de-8cb2-8c0b1e3bb945%2F4DNFITEGKBIW.hic": "2061501971,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F191f6928-c9a8-44b2-8516-ee4d6005f24b%2F4DNFIE1P6RVH.hic": "1711447310,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F94435086-3701-4b28-a6d0-4a59b24d7615%2F4DNFICJ6I4DO.hic": "1557899940,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Faa9ac173-d233-41c7-8985-ca91949664e4%2F4DNFIKUG8MEW.hic": "1339072088,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fba6d8ab6-ee18-4ba2-8da9-d631888dd50a%2F4DNFICFZGFAV.hic": "1261083478,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F87a3ab04-7094-4673-81e4-ac8c9add8eb5%2F4DNFIQXCZVVA.hic": "1084913802,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fbc1ff488-82af-4579-9424-959184edb139%2F4DNFIB6PJFJ3.hic": "1114571343,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F1f7026ee-987a-41e7-8a61-45510ee3f86b%2F4DNFIX97731O.hic": "1246860402,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F6186787c-2e72-4925-9729-02121e2e4597%2F4DNFIYQYZOTO.hic": "1212210849,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3b98a946-0109-4efa-a13e-cc7a36772125%2F4DNFIPXU7V25.hic": "1696288217,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fea17d041-c6ed-43a1-8047-535f3d19ad44%2F4DNFIL39PR76.hic": "1719284710,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F72774afe-f166-42ac-9849-4070b0dadf6d%2F4DNFIYLJ3R3B.hic": "1106419640,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F4a45e733-55f8-4a8e-be24-2ef34c976e25%2F4DNFIL51WBN6.hic": "1327651164,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F086c62b0-a26f-41ae-a5ff-88b8be2bd2aa%2F4DNFI6SFPUDA.hic": "1336964405,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F4d9b79c7-af62-4070-84a9-b953903f2732%2F4DNFI2KM22QR.hic": "953067310,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3c9889d1-f49e-4639-8e15-2d99d6cd22e7%2F4DNFIVF8Q45U.hic": "984193565,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fa080dd7b-b7bb-4eae-a275-572a8b45b2d0%2F4DNFI2RN3WFP.hic": "1046525527,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fb81860ca-c227-4b68-a298-1907fd32300a%2F4DNFI4TJTL7A.hic": "1160373401,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F74ab47dc-7b52-421c-845e-6feb33457adf%2F4DNFIYJ4TWB8.hic": "1268416204,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc6582128-a930-4bcc-941e-5c0733bdd4d5%2F4DNFIM6RGKPV.hic": "863347067,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F11a75514-4450-4295-9eda-18e3678a575a%2F4DNFIL2VWWL5.hic": "860731581,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F5eb52a8c-bf14-4225-bf34-14a0aa47c369%2F4DNFIX6ZXCA8.hic": "893462267,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F66aaa4c0-1f62-4040-8ecc-4e95da23cd18%2F4DNFIEVR81FS.hic": "879736207,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F821c6e7f-96f7-47de-b7d9-4970562b3c8e%2F4DNFIAUI6BBI.hic": "996313881,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F9252c362-31ab-413d-a47a-cc97bdbf243a%2F4DNFIAFEE9G2.hic": "1103265750,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc1a0bf52-2e65-4deb-871f-ede736babd41%2F4DNFIPZBEXCP.hic": "1081257762,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F729f5ce3-d7e0-466d-b781-d18049e63bfa%2F4DNFIWPKRZGU.hic": "973779283,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F80b769ee-a717-4825-9db0-dca86f913173%2F4DNFIMD9QNDX.hic": "1158688208,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F266290c0-2767-4158-85ab-7274368905b9%2F4DNFIATA1HD5.hic": "1073361089,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc46f18a8-eb24-4d35-b112-36db72bde2f5%2F4DNFIH9U4I7I.hic": "1111124316,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fec91a79e-7de7-49f7-9b3d-d28313aeddc8%2F4DNFIZ95S6TR.hic": "1242494051,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F9e9390b9-da20-43bb-a8f4-9830f354ddf9%2F4DNFI5ERM9J7.hic": "1271051397,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fee8ea82e-b9e4-41ad-bced-5f4fbdaa4fec%2F4DNFI15FPSQL.hic": "1216714120,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fbed7eb86-8990-42f2-b3ee-5992d6361f7c%2F4DNFIJ3DZPGM.hic": "1035089437,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fdaa8a324-3bf8-424c-8a86-b8ad325cc20d%2F4DNFINW9P6XF.hic": "1215712740,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F70631758-6bf8-47a0-92b6-132574886faa%2F4DNFITS16HW8.hic": "1105283847,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fe473304b-7bc8-49b8-bba1-ecb9f06914ee%2F4DNFIS3DIH4V.hic": "1036056660,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F10f9224a-111c-402a-ac25-e221ad0af9ef%2F4DNFIY3KDHP6.hic": "1071761024,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F17519b96-2bdd-4294-98f0-1535f1aef28e%2F4DNFIO8HVKOL.hic": "953793750,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ffb18f896-4730-4909-86a3-867fc8e76cd6%2F4DNFIMF6CFOM.hic": "708717889,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fcfee4d87-0873-40b0-b79f-35dcc8669c1c%2F4DNFIZZ77KD2.hic": "732668723,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fb8b5d909-8a1b-41bb-bcdd-d108a0bde762%2F4DNFIOLO226X.hic": "951271932,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F9ce81f6e-b9cf-4ec9-8bd3-517539e4b662%2F4DNFIJMS2ODT.hic": "932509067,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F506aa952-5d41-49ff-b658-916bcf88a395%2F4DNFI49F3LJ4.hic": "1208494817,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fe4dc392d-ca36-4bdf-a27d-173cae34f520%2F4DNFI65MQOIJ.hic": "854630155,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F149ef8d7-e0b4-4e4f-b7e5-7226e2603746%2F4DNFIM4KEPRD.hic": "882790622,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fa436f0a8-4f9a-4524-90ac-795c5b8491cf%2F4DNFIIXBIZFC.hic": "848244425,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fbc8a05dc-7449-4b01-8330-a55db37ca8e6%2F4DNFIWDOOBVE.hic": "1116239020,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Faef8b881-28fe-4694-9a95-1d31940e6726%2F4DNFIDT9EB5M.hic": "888289053,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff66f3162-a53d-46f2-8800-3752935d5400%2F4DNFIX2VUNV8.hic": "1226661451,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F36c782e6-2c48-4298-aa43-bd6624da003d%2F4DNFIEQHTV1R.hic": "804665819,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff15d571e-605d-4bcc-a359-0350b57a6815%2F4DNFIFW7GA64.hic": "901568712,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc2aa2e8b-ac7f-4acb-b4b5-ac5f845840fe%2F4DNFIXGXD67I.hic": "970995551,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F71b6fd7d-b249-4d65-a597-b80b95845399%2F4DNFIA7GB1NB.hic": "956785837,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F6cbb1418-34db-427f-9273-5174eac81529%2F4DNFIVOJGWNP.hic": "890415052,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc69c2ee7-b6c3-4a62-8d4f-913491c9dab8%2F4DNFIW22BNB5.hic": "1075499540,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fa268f28f-c6d9-4324-8989-75d2d317af1b%2F4DNFIIFBC8WN.hic": "1045459440,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F6c7361d4-60a6-440b-b5be-072cada98663%2F4DNFI9ZBEBJH.hic": "759395398,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fcceaad1a-e01e-4430-8bd6-24ffa6891802%2F4DNFID4SLU53.hic": "921288444,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F9eee5854-b33e-4d5a-9ba8-ceffd47e7488%2F4DNFIODI1NUJ.hic": "733159777,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F5e1089b0-42e8-441c-99bb-4be99bcec28b%2F4DNFIJL26LFN.hic": "723567970,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F298a429e-ea29-49d3-bfed-fa851e1e7c4c%2F4DNFI5KTF553.hic": "2213661745,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F965d29f0-e4a3-477c-8ae4-faf4a654e69a%2F4DNFIYSPGFGV.hic": "2274989349,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd88acbc1-37b9-4266-9f97-d8fed576d0f3%2F4DNFILOR6D2D.hic": "2595459358,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F7b6ddbce-0ed1-4272-b8ae-32793e4ea4e4%2F4DNFI1WMMPJQ.hic": "2262433890,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fedc0c8c4-97d8-4372-9a4f-5e0cdf09d7d0%2F4DNFI47P5978.hic": "2146314403,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F0edcc389-43a4-44d7-b946-fe3496f93d56%2F4DNFI7XGW6IH.hic": "2302805723,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F0a802926-e235-4c80-b521-83a1774dfb46%2F4DNFIK1EJG8I.hic": "2374943035,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3c36aedb-6a58-4aa2-9b11-bb440ec174f1%2F4DNFIDQ3THN9.hic": "2341188249,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F846123cd-8828-4e51-8b8a-27deaf293858%2F4DNFI3WPNFWT.hic": "775145629,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fbd06e3ad-0e37-48a3-8367-c7d5912cab03%2F4DNFI9DCUOQ1.hic": "870487824,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc2eaf9bf-9584-4cec-8685-bd74038a6c01%2F4DNFIU8AF5ZY.hic": "1276224366,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F219497b5-3f35-473b-9d4e-e1cf21c69561%2F4DNFIHW8NTQX.hic": "28864787856,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F4be13558-114a-4f2d-abca-7598e2ff4757%2F4DNFI4OUMWZ8.hic": "17061013588,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F49aed637-87a1-4d4d-ae68-e5da82aec05b%2F4DNFIEYQ5ZIR.hic": "13555272651,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fa2f48779-4eff-44a6-8a9d-96435aca1ddc%2F4DNFIDZT7PR8.hic": "13425047093,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fb6ec6b71-27b8-4891-b10a-ab06a5270468%2F4DNFIEJEFCAM.hic": "15394960208,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F68b9a7b5-8413-44fc-8c2d-59a67b1c4166%2F4DNFIJ8JKKWJ.hic": "17012681779,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F294d45a4-8b5e-456f-a9cb-1cbbbad3a7d2%2F4DNFINEQY95T.hic": "13966775978,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fbd7f3a48-b822-41e2-bd9c-f52b3aff7b6a%2F4DNFII6AN691.hic": "12367300362,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F7da44594-0dc8-4e74-8e10-a957aeaea51a%2F4DNFIDBIEXI7.hic": "2015474981,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F085a0453-3784-4eba-80b2-3556e53e2f52%2F4DNFIDKJFK2S.hic": "1983111659,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc370c78c-0a99-4c3f-a29b-2dfafc6a3e86%2F4DNFIPAF4PYT.hic": "3041434294,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F907ce45f-baa5-416d-92de-e86db4bacff1%2F4DNFIWIYYNQ5.hic": "7082321112,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff13afc6b-cf69-4c9d-881f-eed4dd3c28ee%2F4DNFIHMCILEN.hic": "1739157603,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F7575d891-0e3d-4a77-896a-3e1b3a8d330b%2F4DNFIJBJ6QVH.hic": "5213499748,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff0daa830-60d5-4c7c-a2e1-a4ee70b3fee7%2F4DNFIH2A7IKF.hic": "4099503507,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff4970a25-91d8-49a7-9a4a-fe0f12cb2b0f%2F4DNFIOL8KGQ2.hic": "2256042055,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F879f1850-d175-4a86-8a97-12658482e3d1%2F4DNFIWILLD6C.hic": "5476286356,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F787f538e-d619-4c8f-985b-78753fb7e57c%2F4DNFIZBXXJAF.hic": "5946467856,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fb8ee785f-1016-4989-9e64-78352621d32f%2F4DNFI8PZOJHN.hic": "8307204961,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3d8997fa-528c-4531-b25b-a412de6bd472%2F4DNFIGXAMSJY.hic": "6577588285,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F87aede55-7610-4283-af0e-c6840429a31e%2F4DNFIWNNO89O.hic": "2871061417,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F93b8e020-b337-4685-81dc-40cc8a12b5e9%2F4DNFIXU2KPNQ.hic": "3401717686,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ffb5cf1bd-59d6-46fe-857d-b86d9756029d%2F4DNFIHBGD6N6.hic": "840028421,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F2d1bc088-d838-49b8-85fc-fea78a7353c4%2F4DNFI7J8NI4A.hic": "675705256,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F21a27b63-fd67-401b-9aa2-2798e6588d21%2F4DNFISFM9VFK.hic": "800145922,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F656c0a9d-7058-4c4b-a3ce-701d929561c1%2F4DNFIJU5XBK7.hic": "966593603,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F2efacfbd-9c81-4e62-8df7-847d1ab774d5%2F4DNFIPKY8ED1.hic": "3401629450,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fa50b6a26-56b5-43f2-b525-fa219fd716f1%2F4DNFIQRTP7NM.hic": "5358852759,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff5dc7a59-b998-4490-8a76-afbf3b258a49%2F4DNFIBCIA62Q.hic": "5779049277,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F62b2b237-cb02-45f7-89d9-616cf9ffb678%2F4DNFIV56OFE3.hic": "5818844506,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8ac79b4f-cfbf-4b2a-9fc2-898ed6c3e5e1%2F4DNFILIM6FDL.hic": "19637469163,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F1cff8afa-5a13-4ad4-bcad-91fc3ced759c%2F4DNFIP71EWXC.hic": "17934647326,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F000789fe-9a22-4280-a71c-7ad228fd4cac%2F4DNFIM7ZVQOQ.hic": "700134697,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8d78457f-0c2b-4358-b08c-4d4ef4d9f59d%2F4DNFIS6EYHCX.hic": "628314484,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8ca3b4a0-2478-49c9-b4a2-a28430417a32%2F4DNFIKKCMS1Q.hic": "584050634,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff5041473-18ec-439d-92b1-8ad98c9b25c0%2F4DNFIBIV8OUN.hic": "522632731,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fcf474ec6-abd4-431e-a21c-252fcf5ee6b3%2F4DNFIAUMRM2S.hic": "313395531,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F2bb1c73e-fb0f-41c4-8620-a938cc8d24a0%2F4DNFI9ZUXG61.hic": "332217525,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F26dfa41e-7e4f-457a-a3ac-72daf8059f3c%2F4DNFIDBFENL7.hic": "359604894,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8ed2e68b-189e-4988-bb6d-94e63240a231%2F4DNFI7XAZNNQ.hic": "5312422266,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F6f2b1ce0-5205-4680-981e-d91b694dc3e4%2F4DNFISNGDB53.hic": "2008546759,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F73c8147f-bc7d-4d33-8a10-a9e7b413ecc6%2F4DNFI1CIGHYC.hic": "2221847625,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F526ae3e3-32cc-4670-970f-1faa9cfafd4d%2F4DNFIQD2DP2F.hic": "5295591503,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F6e803530-47f8-4c56-bb19-fbdcd578d2f0%2F4DNFINHT8P7C.hic": "3159499486,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ffe705f38-903f-47b7-9b38-f80ebd18a479%2F4DNFIGF8EM7M.hic": "3490552542,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Faa197328-d6da-4299-a0fd-409ac9892668%2F4DNFIUPG2ZBJ.hic": "5382003751,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ffe5d52c4-2be7-4812-bca0-cd4bb3025e6b%2F4DNFIH3OTR14.hic": "3224693110,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F21935f61-daa8-4df2-aa69-fcd27953b405%2F4DNFIUATRW3Z.hic": "3835865655,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F72147527-e3e8-4967-bc45-8251249d76c9%2F4DNFI6V7ZQAE.hic": "4382708138,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F589f0919-f54d-49ff-a482-e2f453ef7f34%2F4DNFICKMT1CY.hic": "4479068191,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F861946ca-bad8-4a87-96e1-b2eb20b9ef10%2F4DNFIF9BDCNI.hic": "3698151402,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff76346ac-97ec-4893-8984-2b75ce1cdc51%2F4DNFIG5O1OQS.hic": "5704288175,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fe8b43826-f049-4c3f-b83a-e75fa7aacc85%2F4DNFIHS2SVBQ.hic": "990025510,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F46316260-f555-4dd4-9e40-8ae06ca52822%2F4DNFIU95B69H.hic": "1275878544,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff62ef491-a3ae-4f66-ab33-c5673c9e0b65%2F4DNFIYRROFCR.hic": "1522530503,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F1cd617e1-fad4-4fdc-8b4e-cb277650123c%2F4DNFIF7JN3IU.hic": "1463443128,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fdb20fe2a-0078-4d4a-8a52-d76043d06f40%2F4DNFIB2RYULQ.hic": "1269529700,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3d386fcf-1d22-47de-a0d6-0c3a641ca174%2F4DNFIMVDK3SI.hic": "1185489599,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F00e470bd-c533-41b1-923a-4b471824da12%2F4DNFIRLOTXSC.hic": "978217499,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fb8774fb3-d0c5-43cc-a6c9-eb0ca39841fb%2F4DNFIZAPX6J8.hic": "1100356082,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fab3b826e-614c-448b-860f-a3ebef68a82f%2F4DNFIQD5VCSD.hic": "1322319877,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F66c78d2b-993a-4937-95ed-9e2d302ceb3e%2F4DNFIIF6VAGN.hic": "868885799,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F5d106fe1-2d80-466e-87aa-46b38ba142c5%2F4DNFI86IEZXH.hic": "751443267,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc99490b6-faf9-413f-9c38-3f53018089d6%2F4DNFIP881SR2.hic": "754427927,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F39c7e387-e710-4b1d-b757-357dec03f6ad%2F4DNFI42NNCW8.hic": "1166392978,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F4742a211-43b1-4325-af6f-82490aeb766b%2F4DNFIEV4PKP6.hic": "1102227476,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Feaa73842-1c86-4ad9-8a9e-c189c0b4c01d%2F4DNFIF1DUQHE.hic": "1206699207,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd25f24df-0298-4079-bb6f-1c8e1e32392b%2F4DNFIGW55EAY.hic": "1033358104,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc57a7ab5-2778-4fe2-9d64-9a4e95135f12%2F4DNFISZRU6I4.hic": "1539570262,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd89f494a-27ca-46b6-89be-7583f3f6d18c%2F4DNFIBKKDTAP.hic": "350372180,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F06725280-cb24-4f22-a267-18b434bfa79e%2F4DNFIJSRQW24.hic": "314361467,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8fe5c3c5-006f-425b-ac6d-ea475e29be78%2F4DNFI3REN89E.hic": "299665258,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc8b6ac5c-13b4-427e-9158-cec0b890b6d8%2F4DNFIF5XLHKM.hic": "235668364,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F01ff33fc-fc23-48aa-a6c6-b720d6fe0768%2F4DNFIB6Q538N.hic": "316494853,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F552978c8-abbc-424a-9187-3e34cf802a97%2F4DNFI3ST3F7Y.hic": "296298411,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F72e66520-5170-4f2e-844a-fbfd0e23b480%2F4DNFIQT4M6UI.hic": "307691265,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fb3eb3953-ffe8-4d5a-970c-a16f3b7b9ec3%2F4DNFIFNCC7M2.hic": "364160436,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F37d413fb-afab-41ff-99aa-1678830f7dde%2F4DNFITM9MDJL.hic": "252412426,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Faf5db92c-aaf1-4086-a0d2-79b28648f172%2F4DNFI3NTD7B3.hic": "227586640,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff6892f7b-1f8a-4d7d-9605-c67932cd5654%2F4DNFIBED48O1.hic": "328344868,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd64afb07-5ab1-4c4f-8438-2fee37afa86a%2F4DNFISATK9PF.hic": "379669025,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fad11bb63-8692-461c-b698-89c601451321%2F4DNFISRP84FE.hic": "298491537,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F63710ec5-35d2-47dd-bf9a-08d3daa83d67%2F4DNFI2LY7B73.hic": "303150299,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F76077d9e-ca75-4301-ab79-88aa49bda495%2F4DNFIXEB4UZO.hic": "711757090,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F34dd4c0e-3487-4fb4-b95f-c4bb66e0fa31%2F4DNFIQWWATGK.hic": "221304476,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F48a8cf86-3248-4a8e-8e85-472ec219d49c%2F4DNFI44JLUSL.hic": "284772724,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fee399fbf-2a9e-46e2-8364-457713bff508%2F4DNFIM7Q2FQQ.hic": "330729464,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F124d191a-c5c7-49b6-b84b-0d1bad8bef2b%2F4DNFIZK7W8GZ.hic": "293166018,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fe351f7cc-7a2c-4515-ae0b-3bb2f91c986a%2F4DNFIMIMLMD3.hic": "240094740,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ffd1ae249-57b1-41d6-81a6-16b21dcd8f12%2F4DNFI7QUSU5J.hic": "681762505,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F46c92c5c-9ad8-4d49-beba-f35c5cd99208%2F4DNFINXUOI5H.hic": "375594313,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd7350d40-4e9e-4131-9151-bb539d39b431%2F4DNFIIJR2296.hic": "331322302,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fbfacf37b-1665-45f3-a046-e29e1544e9b0%2F4DNFIJMZUTXR.hic": "361313244,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F234e18fb-9990-43bf-9a48-f72722cfa232%2F4DNFIZQPT9EL.hic": "540421873,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F4b35ab09-2e79-4876-b2bc-d3a8faa26257%2F4DNFIZIXSZ9J.hic": "545066813,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F2ae5118e-807a-46e0-8e92-143d4b282b3d%2F4DNFIDD9IF9T.hic": "237409149,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fb34d7f6f-73f7-4b6b-80c7-c8af0f991549%2F4DNFIVC8OQPG.hic": "355121712,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F9ab169fd-cbdd-4f60-8553-a4c6912ad89e%2F4DNFITUPI4HA.hic": "313085022,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F4e53712b-d0d9-40c5-afe1-ffa0fad71e59%2F4DNFI5IZNXIO.hic": "341863906,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F7a91477f-45eb-4a16-affb-fc131f9326b8%2F4DNFII16KXA7.hic": "248904495,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F153729de-0eca-43cc-9b61-61aa8d775b38%2F4DNFIAAH19VM.hic": "668047244,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F879fd78a-7165-43d9-a0de-ca158b53df30%2F4DNFIVKIY3KV.hic": "247571318,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F67f901a4-040b-4b04-9fff-94a1780423cd%2F4DNFIVVCWL6C.hic": "198355985,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd5b30c5a-654a-463c-9474-39bdc3ce4500%2F4DNFIJRF2273.hic": "343971277,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F7070280a-8f03-40d0-9fef-e9d9f4d3dae7%2F4DNFI6FCC9ZA.hic": "312013061,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F47049719-9407-4d76-9048-26231045f642%2F4DNFI1CPQ4O3.hic": "352923267,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F862c2b5f-44c2-4bd7-9264-b3ca032d3d8d%2F4DNFISXFEDE9.hic": "271745977,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Feffbe052-39ff-4217-9871-44199ed90818%2F4DNFIF9L6QEQ.hic": "668409334,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fa7791854-1b35-4258-90fb-603c55f24642%2F4DNFIPKASX1Q.hic": "312727920,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F79cccad6-a78e-4de9-9fe7-08f7e8df663d%2F4DNFIWXZ4JQZ.hic": "151808553,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F7e86e0cc-d6f1-4ce0-aba4-c36c6ebb3c4c%2F4DNFIEMQ1O8V.hic": "700533280,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F4a1b58d3-9ae6-43e4-91cf-49f1fcbbab33%2F4DNFIYWONU7A.hic": "729050356,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F67bff264-0b0c-4c5c-9d4d-ff5abef2bbe4%2F4DNFISNIE5FH.hic": "7987657997,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3a6a943f-2cc0-4433-a27d-c89f3fdd3309%2F4DNFIV8MLWJB.hic": "6646216171,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F9e235711-ba90-404d-b4ac-b15990ea8e33%2F4DNFIXSTDPHL.hic": "3146468238,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F0c89f4bc-e9fc-4ecf-b868-26108dbb7bb2%2F4DNFIQJNOH8U.hic": "2919703928,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F1856ff9e-de7a-4fa1-ae0b-3e04b837b5e1%2F4DNFI57XB4A8.hic": "13417594377,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F099bb5b9-6315-4650-8f78-d603f5a046b3%2F4DNFIQ7UKVZV.hic": "9016468637,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Faf3c7a30-0fc4-410d-8d41-247da3eb105d%2F4DNFIWJY8GHD.hic": "7921314766,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fda99f429-20ab-4d91-bbfe-f8bdea8ed7b1%2F4DNFIN8NKRNF.hic": "4247121358,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F0ca0f4e3-30ca-4332-b735-e32dce08e1a4%2F4DNFIZYGEHNZ.hic": "4910404663,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F243f48b0-6b59-4f37-ad39-a12e0986f530%2F4DNFIRPYGAV8.hic": "4220073636,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F49f1a890-d458-42a6-9c78-99c38b6c7a8f%2F4DNFI6MZTDM1.hic": "375035361,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F76bd4768-9343-44ba-a99d-5500e184e39d%2F4DNFIG3BCGPL.hic": "2422923206,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F9d1ed866-eaf6-4906-aa8c-9e39616dde38%2F4DNFIS9YPJ3L.hic": "1593271574,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F1e7a5636-bdb6-45fb-85d8-87a7e908de43%2F4DNFIOWGA9AX.hic": "1632314387,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F5ecc552a-0a6b-49a9-9aa5-9f3fd9b535fd%2F4DNFINKEDSBF.hic": "1458761024,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F6c03f1d2-bb25-4c94-b5f5-d5cdd01c14b6%2F4DNFIVIXVUK7.hic": "1504818271,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F1a4616ff-6d04-4a6a-9773-b80e81da2471%2F4DNFIANHFY16.hic": "1850724180,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd2231870-a78d-4c8b-9cfd-084f2468acb1%2F4DNFIJ67ZFBI.hic": "1473864703,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F859c2dd3-df8a-42b7-86ea-bf6524f75e80%2F4DNFIG3YQQ4V.hic": "1539822829,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8bad667e-6003-4828-9a20-07585fa9c811%2F4DNFIOLKEOME.hic": "3036353747,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F92ea551b-5779-4d31-a0f5-621e4bd0eb21%2F4DNFIVLN8WJE.hic": "2710426318,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F61ee79fa-0617-4083-b121-f92ef3a8905c%2F4DNFI2111XQA.hic": "2589549183,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F83ebb98d-e5db-403d-aa23-875293156c0e%2F4DNFI88HXX7D.hic": "2462367030,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F6d63671a-8f1d-4159-82c0-931b43464772%2F4DNFIUBM6QK8.hic": "2486020469,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fcccb9014-ce15-4032-81ac-222b3d621cb4%2F4DNFIVILEERC.hic": "2052537210,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F21a07867-4007-4ca5-b066-25d3168208dc%2F4DNFIF7Q43N4.hic": "2091773428,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff738de0f-358b-44bf-97dd-644c8d9b1b1c%2F4DNFID56VJGW.hic": "878913568,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fda97c1d4-bb92-4a77-92a7-f7960f88b9dc%2F4DNFIYUR29KO.hic": "983915575,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F54ea363a-99e7-4f55-861e-1644acab7939%2F4DNFIUDPGHO8.hic": "905253594,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fdcd66a07-55ee-48d9-a157-419cf4ee3eef%2F4DNFISWC2N8T.hic": "1233576358,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F40363837-7466-4a1d-b20d-a66d1670b700%2F4DNFICMPHDMI.hic": "516590777,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F0b3fa4e6-caeb-40b4-8942-e9c0b03dfe4f%2F4DNFIKMKN736.hic": "634310295,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fb6a34050-d52b-4880-91cf-d3fe4b0ce982%2F4DNFIN5NLS49.hic": "650451131,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8e63a47b-9fd4-4772-8b0c-10ee589ffb16%2F4DNFI4P8UBRL.hic": "705655033,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F7d92b666-30cc-4838-9d46-c1f11cee3d3c%2F4DNFISNC3LAI.hic": "176146197,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F17f7dc63-a1bc-4970-b389-87d9ee93b753%2F4DNFIVBWPFD7.hic": "749678512,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff8897333-4791-4a83-9444-a653e24aee13%2F4DNFITMQRXB7.hic": "254477361,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8712bf31-33d0-4562-ab0b-a1e9cf4fd30c%2F4DNFIUYD3HBY.hic": "995625724,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fbfaf6383-9cc6-4b5c-9b20-d3bf2e8c3495%2F4DNFIRRSC7P9.hic": "1149985362,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fb0b70598-5d17-4e0a-8831-6cbe697e69e2%2F4DNFIWKR8FP6.hic": "1151628407,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fccc094a8-23ce-4fd8-9c4a-41f07c045c8f%2F4DNFIQ74RSUY.hic": "931695969,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8eda16f3-af5e-4f1f-b46d-c74df44b76aa%2F4DNFI9IIO5PW.hic": "1077740364,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff283637b-cf2c-4412-ba00-0e3d7e279fad%2F4DNFI8WGJG19.hic": "812086456,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F7ad8438f-d3d9-42d8-88bf-42845a0dc2d0%2F4DNFIQ5CCESJ.hic": "652559720,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F70e3bdcc-caf4-4822-b9c5-85234873db7a%2F4DNFIWTZHB4H.hic": "760694196,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F56ed767d-cd8a-4d38-8047-ed1e8bc8cd19%2F4DNFIENYQCDP.hic": "1159428005,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fa912fff9-5f90-42b1-a3a6-cbb9eb2cf861%2F4DNFIFATZWPD.hic": "1033325746,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F21338ea5-fdee-4ad8-b61c-608fc6cec4bc%2F4DNFI7YRXKEO.hic": "388142539,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff0f88647-5631-437b-b48a-4603915e3714%2F4DNFIUY3J7EW.hic": "407344788,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F16926af8-ac3b-4f32-97d5-6c0dc6f1596a%2F4DNFIRKUYKP4.hic": "893352368,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F93e39aec-6cde-4c5b-bcdf-283faa3163a2%2F4DNFIAQDBJZP.hic": "489922022,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F0dc0b1ba-5509-4464-9814-dfe103ff09a0%2F4DNFIC1CLPK7.hic": "565748333,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fb50964c7-b025-49d9-b1ed-289bedb59678%2F4DNFI3A3VYWU.hic": "4597459343,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff4390cea-b330-4022-88c1-9ff8c0a786f7%2F4DNFI6JJQKFJ.hic": "3678393678,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F70c0f730-5da1-4863-9b7a-6cdd31066cff%2F4DNFIK61ILGM.hic": "3324300994,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F14b14ac4-ab59-4754-9c43-eacd9d0638e2%2F4DNFIYD8LO9Z.hic": "3227227120,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F7386f953-8da9-47b0-acb2-931cba810544%2F4DNFIOTPSS3L.hic": "253942497,7557", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff6b5d8bd-27dc-4415-a320-53405a16db85%2F4DNFI525PKU5.hic": "305089653,7557", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F1f922dbc-637b-4c43-b816-f604f0e79ad1%2F4DNFI8Y9SRP2.hic": "1438589609,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F6a36d686-716c-4ba8-a9c3-fa8311791d3c%2F4DNFIP25GZGA.hic": "1419100109,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F0e535542-2cf2-46e4-ba10-7a0b946a7fb2%2F4DNFITPO1WTY.hic": "3885296184,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F0c17d228-5052-4c83-880e-af05118e6929%2F4DNFIG4X5Z5F.hic": "2159245890,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc3977c00-525b-4556-9a27-061707f8cb76%2F4DNFIXLYR32S.hic": "587852728,21916", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3f856506-cbc5-4211-a29d-48a7530c622e%2F4DNFIWI3V5LI.hic": "2318237793,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F38f77979-5eb7-4b6f-9a60-c2451185db98%2F4DNFI2DGL7LH.hic": "2068150664,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fe0992a75-7727-405e-95ac-aa97141b51c1%2F4DNFI1VSO8JP.hic": "1807949651,21916", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fe925f1aa-2e7b-44e7-bfa8-2084a613ab13%2F4DNFIV5O2ZYO.hic": "2242134377,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F803a6d3c-3972-4939-8ff2-d195c5192090%2F4DNFIEWEWQ8D.hic": "2981341325,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F25104375-a588-46e6-a382-663cee6c332f%2F4DNFICSTCJQZ.hic": "14592996888,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F927aa8a5-24a5-43b7-807a-1e99ac321459%2F4DNFICEGAHRC.hic": "15431307603,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8c380474-12cd-41f4-b86f-2a29faf12eec%2F4DNFIY3XPKPO.hic": "2550999291,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F77da562e-d0ec-45a8-8764-14fa16d995a1%2F4DNFIK9PS9GM.hic": "3401011629,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F11b26222-d480-40a7-8d53-3ad8500396cb%2F4DNFIF4Y74JR.hic": "2127593378,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F93df02c6-1047-43f6-afae-d3598b61eeea%2F4DNFIBBKG9KD.hic": "5724446278,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F6cd4378a-8f51-4e65-99eb-15f5c80abf8d%2F4DNFIT4I5C6Z.hic": "5419655766,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F067881e5-563d-40de-a9e3-caccad887fbc%2F4DNFI2U38HCE.hic": "14749043471,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fcb3da9ad-7afe-4d0c-9c2d-261181e7a95c%2F4DNFIETP228R.hic": "9401474797,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F185b7bcc-7bb7-41b7-9ebe-92d4fe159431%2F4DNFIXKC48TK.hic": "11624295594,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F18459b84-dd43-4af6-a05f-bcb773096322%2F4DNFIFPGOWJ6.hic": "2843730862,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ffde1e48c-4a0d-4bb1-b84a-e0e45f9a0aa3%2F4DNFIIRMBE8Y.hic": "5820677927,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fbabed539-1f0f-4e87-8815-fde596e6024c%2F4DNFIVUGNDD7.hic": "5170782436,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F7d00531a-e616-469b-af52-5b028270e2ce%2F4DNFIFLJLIS5.hic": "18917549985,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F7a9dad53-b8af-4cb6-9ce3-5c38e4a855c7%2F4DNFIOX3BGNE.hic": "5482775936,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F82fd7b7e-5f47-48d5-bf0d-daaa48a4674d%2F4DNFISPUVQHA.hic": "2177864938,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F4c6680f3-9cf6-452f-9dc5-ecebf376775d%2F4DNFI8649RQJ.hic": "3288850368,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F2395f001-19d9-4000-9f00-dae3dea708d6%2F4DNFIE8T8JZ8.hic": "1383191843,21916", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F24464fa8-bf96-483c-8e9a-c2f626ad6e19%2F4DNFIBM714BP.hic": "1765204569,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F918fc048-fa27-41d2-a63a-d50c511fbb9a%2F4DNFI6CWNUFL.hic": "2431120602,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F7ff5a0d1-8e54-4cf0-9fe7-339f147c78da%2F4DNFIZ4F74QR.hic": "3211825957,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F355f0412-cb17-452a-b15c-aba16c5a742c%2F4DNFIOUVOX3R.hic": "5547401083,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3cac91c5-160a-4b91-a91e-edc309318dd5%2F4DNFIVTDXW6X.hic": "4797344498,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fe9ac9ec5-6221-4f39-951a-1c5054fc9f1c%2F4DNFICA8Y9TN.hic": "4277557869,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F46f62222-b50a-428b-938b-5444951600eb%2F4DNFIDWM3HN5.hic": "4374808431,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F50e4f2a1-9cb6-4192-8199-64d354bfdf96%2F4DNFIBK5TB3N.hic": "3757387253,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fe4cdd5a8-1a45-4c6a-906b-a9603260d4c8%2F4DNFI3JYF9VS.hic": "5260534916,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc8164e99-5778-427d-be26-f0e1b62400f0%2F4DNFIP1GNKUO.hic": "7589365689,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F0d72e78a-fc87-4716-8b8e-6dc5650ff2ef%2F4DNFIQYQWPF5.hic": "22022259901,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fac58fc15-48c2-4eec-a689-23b677b4b6e7%2F4DNFIW6H9U3S.hic": "6810897169,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F31811e40-e3ca-4456-8ba6-2ee66d6c7104%2F4DNFI7J8BQ4P.hic": "7188744676,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F62d81a52-d2cb-4bbd-8510-0fe120e786e0%2F4DNFIA3AKFSU.hic": "1763730692,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fae0b7513-d1a0-4f27-a9d3-348837f42cb6%2F4DNFID68JQY9.hic": "2422880133,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fae6a1a7e-1d2d-4fd2-a89f-1799abac8a9c%2F4DNFIL1FQDXE.hic": "1543814834,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F80d343c9-bd60-468a-803d-c3e351a958bc%2F4DNFITSIPCSK.hic": "2344682115,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff2d61195-a3a6-4d50-b928-546ca67546cb%2F4DNFIJ88LYHR.hic": "3362742962,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F31052aba-773a-4500-961b-e0a518245b0c%2F4DNFIJIPWD63.hic": "2529548812,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc93d0710-3fbf-40cc-b0eb-878e2aa659e4%2F4DNFIZUP2BBI.hic": "491996147,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8660baeb-5be1-4ba5-93e4-66499e9a4587%2F4DNFIEBC4AF3.hic": "2993048734,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff6d08fbc-b836-4776-82ad-8b1b277ae837%2F4DNFI5VO3E1W.hic": "1949322679,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3af004a2-a6fa-46dc-8be8-898b847a77be%2F4DNFIFDGVWLU.hic": "2456400803,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fbd613b4b-2422-492c-8d8f-8afba9c8a182%2F4DNFITVGFNYZ.hic": "1411204423,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc340694f-14f3-4638-b09b-98220c20039a%2F4DNFIOW9TTC1.hic": "2611370588,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3effa71b-6aa3-4265-87ba-f8d709d778d7%2F4DNFIOAA3ZEQ.hic": "3123195980,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fde75cf8b-9ce1-44fc-8b7b-ca0adea6bae9%2F4DNFIA5ID1S6.hic": "3496246968,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F714f775d-a5a4-4314-83f8-016b9d73200b%2F4DNFIZYU7V81.hic": "4245592042,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F5ca518af-6e1e-4777-b67b-0fe7f039ce58%2F4DNFIRV6PVUX.hic": "3981520466,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc29b57d5-c263-4372-b396-ab4f55682f5d%2F4DNFIMEANFBY.hic": "3999623376,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F4196d3ef-161a-4c18-a57e-005165c6b32a%2F4DNFIGLGQXLC.hic": "4105683321,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fe10828b5-9519-4ceb-81e7-7228bfd890de%2F4DNFILS2HLXC.hic": "3804942111,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Feaac88c7-9bdc-4b1e-aa9f-e675520dfffa%2F4DNFIQS8853L.hic": "5287726781,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Faab371b1-bc8d-4e83-998e-5bb977c443ca%2F4DNFIVBYCYGS.hic": "4657988157,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fdb116add-af8c-4a3b-b106-9f704ba0a175%2F4DNFIE4WWHMF.hic": "5116727268,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F033366e2-05a2-4381-9d48-90122892a9e0%2F4DNFIKDUUC3C.hic": "45638237,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F7284a446-442d-4a46-aae5-84987e75a7af%2F4DNFIJ5HIRA2.hic": "62201052,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F876649a3-6dd3-463a-8b17-5752a98a89c5%2F4DNFIXDFC7EM.hic": "69878143,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3cb4ce4d-d474-459f-8b8a-2159d8df8068%2F4DNFIO35EOVR.hic": "70153114,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F5c5612fa-18c2-47fb-8074-693b1054e254%2F4DNFI57QGL6U.hic": "54605055,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F70c1472d-cf3a-41d7-8682-cd03b7cc978d%2F4DNFI2AGEBE5.hic": "67930121,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F2bf4cce8-6e03-422b-a190-e51d4a07d501%2F4DNFI1E6NJQJ.hic": "4893181511,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F0eb3aa56-8a23-435d-a07b-8bb545e8d708%2F4DNFI2DNFM1A.hic": "60466977,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F1201682a-a223-482d-913d-3c3972b8eb65%2F4DNFIIRIHBR2.hic": "48961678,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F6aee7913-6356-43cf-affa-f2b60dd478f6%2F4DNFIKXNMT46.hic": "39095246,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F357139a3-c9a5-4343-b0a4-b41c45fd03fd%2F4DNFIRV7IRJP.hic": "70916718,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F76be3061-6259-42be-a917-19dcba41517b%2F4DNFIFX1XYKZ.hic": "229197441,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff60c348a-a62c-43c3-ac85-f6c28b5f823f%2F4DNFI64CJUZ5.hic": "112428610,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fbd0b0a14-9703-49af-bb36-2359f96d4d0e%2F4DNFIBPL2HL1.hic": "73972428,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F79ac278d-83f7-4c1f-91b2-05c8018c1426%2F4DNFIBRSIPE4.hic": "415430378,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F0c3b8141-8e67-4211-80dd-3bae88f9e537%2F4DNFIDLDVY14.hic": "112747303,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F2ae703d2-d85c-4ac4-9ce1-14d653927675%2F4DNFI4R1II4P.hic": "210565448,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F76e641af-90be-49f8-b126-12c20f856159%2F4DNFINMLRY95.hic": "1590865292,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3b416382-ae5d-469f-9e9a-85a3e2ce9793%2F4DNFI8KBXYNL.hic": "4626496956,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fa27589a6-86b2-43a2-8218-1f2232d551e6%2F4DNFI53R5IKA.hic": "1536016455,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fdd3999f5-b36e-4154-a6b9-446656959a3a%2F4DNFIAWVDQ8C.hic": "2210273411,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc377953b-0e61-426b-a905-abab2d5a3002%2F4DNFI9VXTBE2.hic": "3384365692,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F2dbe0377-1db2-4aae-af2b-d87dff728035%2F4DNFIT96Z365.hic": "7692311974,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fdcfcb009-f006-4ab8-a4c7-af72be58c12c%2F4DNFITUOMFUQ.hic": "6592120312,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F67f9073d-b2c5-474e-b3d5-7d72cde555cd%2F4DNFIHLQKDN8.hic": "2647703964,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F76968cc8-fb9f-485b-85b2-c9289067194b%2F4DNFIL9M97T2.hic": "6186798917,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F87d9330b-8d2c-4e9d-85bb-02e572de7a68%2F4DNFIDWGZLHX.hic": "4379708168,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ffc01b381-3665-4225-88ee-2e5e9ecb7324%2F4DNFIMEG1QIC.hic": "3587146533,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3144a03c-15c3-4bf9-95f8-ffad2640a1bf%2F4DNFIWSB66VX.hic": "1529739069,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd7d3aac0-ba66-494b-ba0c-147631084b98%2F4DNFIH7TH4MF.hic": "6896300679,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F4b13bd19-fbd1-4c68-8855-4f0158d1ce47%2F4DNFIHKWIZ9T.hic": "1954878455,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3d04e286-30d4-4add-a806-7a929d36419e%2F4DNFIZBBX795.hic": "1350142414,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Faa26f261-a88a-4cac-9118-ff8e90ab6f61%2F4DNFI9ZWZ5BS.hic": "3410552807,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F24e516ce-0b49-4476-b818-cc96471d8765%2F4DNFIPAI8XB5.hic": "4168518737,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fac3b06b5-46d4-4c1e-97e9-9a4f353473a7%2F4DNFI1OUWFSC.hic": "10766406904,21916", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F76c6aa27-895f-4e82-8ed8-7a85aca84490%2F4DNFIX4PJKXZ.hic": "1463157350,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fe6fbe03a-997b-4d72-a3cc-f1ed7bd88a92%2F4DNFIZGCA8AH.hic": "1597664180,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F61d99a87-4ec6-4116-be99-b483999641c4%2F4DNFI5CGQ46V.hic": "2870576870,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F271ea8cd-53b9-44c9-9fff-1bb5c444b54c%2F4DNFIOCW5AEM.hic": "2463600138,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fa98ca64a-861a-4a8c-92e9-586af457b1fb%2F4DNFI1UEG1HD.hic": "22480709268,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F5809b32e-0aea-4cf5-a174-cf162d591a35%2F4DNFI9YAVTI1.hic": "3141182061,25900" -}; - -const isNode = typeof process !== 'undefined' && process.versions != null && process.versions.node != null; -const Short_MIN_VALUE = -32768; -const DOUBLE = 8; -const FLOAT = 4; -const INT = 4; -const GoogleRateLimiter = new RateLimiter(100); - - -class HicFile { - - constructor(args) { - - if (args.alert) { - this.alert = args.alert; - } - - this.config = args; - - this.loadFragData = args.loadFragData; - this.fragmentSitesCache = {}; - this.normVectorCache = new LRU(10); - this.normalizationTypes = ['NONE']; - this.matrixCache = new LRU(10); - this.blockCache = new BlockCache(); - - // args may specify an io.File object, a local path (Node only), or a url - if (args.file) { - this.file = args.file; - } else if (args.blob) { - this.file = new BrowserLocalFile(args.blob); - } else if (args.url || (args.path && !isNode)) { - this.url = args.url || this.path; - this.remote = true; - - // Google drive must be rate limited. Perhaps all remote files should be rate limited? - const remoteFile = new RemoteFile(args); - if (isGoogleDrive(this.url)) { - this.file = new ThrottledFile(remoteFile, GoogleRateLimiter); - } else { - this.file = remoteFile; - } - } else if (args.path) { - // path argument, assumed local file - throw Error(`path property is deprecated, use NodeLocalFile`) - } else { - throw Error("Arguments must include file, blob, url, or path") - } - } - - async init() { - - if (this.initialized) { - return; - } else { - await this.readHeaderAndFooter(); - // Footer is read with header - //await this.readFooter() - this.initialized = true; - } - } - - async getVersion() { - if (this.version === undefined) { - const data = await this.file.read(0, 128); - if (!data) { - return undefined; - } - const binaryParser = new BinaryParser(new DataView(data)); - this.magic = binaryParser.getString(); - this.version = binaryParser.getInt(); - return this.version - } else { - return this.version - } - } - - async getMetaData() { - await this.init(); - return this.meta - } - - async readHeaderAndFooter() { - - // Read initial fields magic, version, and footer position - let data = await this.file.read(0, 16); - if (!data || data.byteLength === 0) { - throw Error("File content is empty") - } - let binaryParser = new BinaryParser(new DataView(data)); - this.magic = binaryParser.getString(); - this.version = binaryParser.getInt(); - if (this.version < 5) { - throw Error("Unsupported hic version: " + this.version) - } - this.footerPosition = binaryParser.getLong(); - - // Read footer and determine file position for body section (i.e. end of header) - - await this.readFooter(); - - const bodyPostion = Object.values(this.masterIndex).reduce((min, currentValue) => { - return Math.min(min, currentValue.start) - }, Number.MAX_VALUE); - - const remainingSize = bodyPostion - 16; - data = await this.file.read(16, remainingSize); - binaryParser = new BinaryParser(new DataView(data)); - - this.genomeId = binaryParser.getString(); - - if (this.version >= 9) { - this.normVectorIndexPosition = binaryParser.getLong(); - this.normVectorIndexSize = binaryParser.getLong(); - } - - this.attributes = {}; - let nAttributes = binaryParser.getInt(); - while (nAttributes-- > 0) { - this.attributes[binaryParser.getString()] = binaryParser.getString(); - } - - this.chromosomes = []; - this.chromosomeIndexMap = {}; - let nChrs = binaryParser.getInt(); - let i = 0; - while (nChrs-- > 0) { - const chr = { - index: i, - name: binaryParser.getString(), - size: this.version < 9 ? binaryParser.getInt() : binaryParser.getLong() - }; - if (chr.name.toLowerCase() === "all") { - this.wholeGenomeChromosome = chr; - this.wholeGenomeResolution = Math.round(chr.size * (1000 / 500)); // Hardcoded in juicer - } - this.chromosomes.push(chr); - this.chromosomeIndexMap[chr.name] = chr.index; - i++; - } - - this.bpResolutions = []; - let nBpResolutions = binaryParser.getInt(); - while (nBpResolutions-- > 0) { - this.bpResolutions.push(binaryParser.getInt()); - } - - if (this.loadFragData) { - this.fragResolutions = []; - let nFragResolutions = binaryParser.getInt(); - if (nFragResolutions > 0) { - while (nFragResolutions-- > 0) { - this.fragResolutions.push(binaryParser.getInt()); - } - - // this.sites = []; - // for(let i=0; i 0) { - const key = binaryParser.getString(); - const pos = binaryParser.getLong(); - const size = binaryParser.getInt(); - this.masterIndex[key] = {start: pos, size: size}; - } - - this.expectedValueVectors = {}; - - // Expected values - // const nExpValues = binaryParser.readInt(); - // while (nExpValues-- > 0) { - // type = "NONE"; - // unit = binaryParser.getString(); - // binSize = binaryParser.getInt(); - // nValues = binaryParser.getInt(); - // values = []; - // while (nValues-- > 0) { - // values.push(binaryParser.getDouble()); - // } - // - // nChrScaleFactors = binaryParser.getInt(); - // normFactors = {}; - // while (nChrScaleFactors-- > 0) { - // normFactors[binaryParser.getInt()] = binaryParser.getDouble(); - // } - // - // // key = unit + "_" + binSize + "_" + type; - // // NOT USED YET SO DON'T STORE - // // dataset.expectedValueVectors[key] = - // // new ExpectedValueFunction(type, unit, binSize, values, normFactors); - // } - - // normalized expected values start after expected value. Add 4 for - if (this.version > 5) { - const skip = this.version < 9 ? 4 : 8; - this.normExpectedValueVectorsPosition = this.footerPosition + skip + nBytes; - } - return this; - }; - - async printIndexStats() { - - let totalSize = 0; - let maxSize = 0; - let maxKey; - await await this.init(); - for (let key of Object.keys(this.masterIndex)) { - const entry = this.masterIndex[key]; - // console.log(`${key}\t${entry.start}\t${entry.size}`) - totalSize += entry.size; - if (entry.size > maxSize) { - maxSize = entry.size; - maxKey = key; - } - } - // console.log(`Total size = ${totalSize}`); - console.log(`${maxSize} ${maxKey} ${this.config.url}`); - } - - async getMatrix(chrIdx1, chrIdx2) { - const key = Matrix.getKey(chrIdx1, chrIdx2); - if (this.matrixCache.has(key)) { - return this.matrixCache.get(key); - } else { - const matrix = await this.readMatrix(chrIdx1, chrIdx2); - this.matrixCache.set(key, matrix); - return matrix; - } - } - - async readMatrix(chrIdx1, chrIdx2) { - - await this.init(); - - if (chrIdx1 > chrIdx2) { - const tmp = chrIdx1; - chrIdx1 = chrIdx2; - chrIdx2 = tmp; - } - - const key = Matrix.getKey(chrIdx1 , chrIdx2); - const idx = this.masterIndex[key]; - if (!idx) { - return undefined - } - const data = await this.file.read(idx.start, idx.size); - if (!data) { - return undefined - } - - return Matrix.parseMatrix(data, this.chromosomes); - - } - - async getContactRecords(normalization, region1, region2, units, binsize, allRecords = false) { - - await this.init(); - - const idx1 = this.chromosomeIndexMap[this.getFileChrName(region1.chr)]; - const idx2 = this.chromosomeIndexMap[this.getFileChrName(region2.chr)]; - - const transpose = (idx1 > idx2) || (idx1 === idx2 && region1.start >= region2.end); - if (transpose) { - const tmp = region1; - region1 = region2; - region2 = tmp; - } - - const blocks = await this.getBlocks(region1, region2, units, binsize); - if (!blocks || blocks.length === 0) { - return [] - } - - const contactRecords = []; - const x1 = region1.start / binsize; - const x2 = region1.end / binsize; - const y1 = region2.start / binsize; - const y2 = region2.end / binsize; - const nvX1 = Math.floor(x1); - const nvX2 = Math.ceil(x2); - const nvY1 = Math.floor(y1); - const nvY2 = Math.ceil(y2); - for (let block of blocks) { - if (block) { // An undefined block is most likely caused by a base pair range outside the chromosome - let normVector1; - let normVector2; - let isNorm = normalization && normalization !== "NONE"; - const chr1 = this.getFileChrName(region1.chr); - const chr2 = this.getFileChrName(region2.chr); - if (isNorm) { - - const nv1 = await this.getNormalizationVector(normalization, chr1, units, binsize); - const nv2 = (chr1 === chr2) ? nv1 : await this.getNormalizationVector(normalization, chr2, units, binsize); - - if (nv1 && nv2) { - normVector1 = await nv1.getValues(nvX1, nvX2); - normVector2 = await nv2.getValues(nvY1, nvY2); - } else { - isNorm = false; - // Raise message and switch pulldown - } - } - - for (let rec of block.records) { - if (allRecords || (rec.bin1 >= x1 && rec.bin1 < x2 && rec.bin2 >= y1 && rec.bin2 < y2)) { - if (isNorm) { - const x = rec.bin1; - const y = rec.bin2; - const nvnv = normVector1[x - nvX1] * normVector2[y - nvY1]; - if (nvnv !== 0 && !isNaN(nvnv)) { - const counts = rec.counts / nvnv; - contactRecords.push(new ContactRecord(x, y, counts)); - } - } else { - contactRecords.push(rec); - } - } - } - } - } - - return contactRecords; - } - - async getBlocks(region1, region2, unit, binSize) { - - const blockKey = (blockNumber, zd) => `${zd.getKey()}_${blockNumber}`; - - await this.init(); - const chr1 = this.getFileChrName(region1.chr); - const chr2 = this.getFileChrName(region2.chr); - const idx1 = this.chromosomeIndexMap[chr1]; - const idx2 = this.chromosomeIndexMap[chr2]; - - if (idx1 === undefined) { - console.log("No chromosome named: " + region1.chr); - return [] - } - if (idx2 === undefined) { - console.log("No chromosome named: " + region2.chr); - return [] - } - - const matrix = await this.getMatrix(idx1, idx2); - if (!matrix) { - console.log("No matrix for " + region1.chr + "-" + region2.chr); - return [] - } - - const zd = matrix.getZoomData(binSize, unit); - if (!zd) { - let msg = `No data avalailble for resolution: ${binSize} for map ${region1.chr}-${region2.chr}`; - throw new Error(msg) - } - - const blockNumbers = zd.getBlockNumbers(region1, region2, this.version); - - const blocks = []; - const blockNumbersToQuery = []; - for (let num of blockNumbers) { - const key = blockKey(num, zd); - if (this.blockCache.has(binSize, key)) { - blocks.push(this.blockCache.get(binSize, key)); - } else { - blockNumbersToQuery.push(num); - } - } - - const promises = blockNumbersToQuery.map(blockNumber => this.readBlock(blockNumber, zd)); - const newBlocks = await Promise.all(promises); - for (let block of newBlocks) { - if (block) { - this.blockCache.set(binSize, blockKey(block.blockNumber, zd), block); - } - } - return blocks.concat(newBlocks); - } - - async readBlock(blockNumber, zd) { - - const idx = await zd.blockIndex.getBlockIndexEntry(blockNumber); - - if (!idx) { - return undefined - } else { - let data = await this.file.read(idx.filePosition, idx.size); - if (!data) { - return undefined; - } - - const inflate = new Zlib.Inflate(new Uint8Array(data)); - const plain = inflate.decompress(); - //var plain = zlib.inflateSync(Buffer.from(data)) //.decompress(); - data = plain.buffer; - - const parser = new BinaryParser(new DataView(data)); - const nRecords = parser.getInt(); - const records = []; - - if (this.version < 7) { - for (let i = 0; i < nRecords; i++) { - const binX = parser.getInt(); - const binY = parser.getInt(); - const counts = parser.getFloat(); - records.push(new ContactRecord(binX, binY, counts)); - } - } else { - - const binXOffset = parser.getInt(); - const binYOffset = parser.getInt(); - - const useFloatContact = parser.getByte() === 1; - const useIntXPos = this.version < 9 ? false : parser.getByte() == 1; - const useIntYPos = this.version < 9 ? false : parser.getByte() == 1; - const type = parser.getByte(); - - if (type === 1) { - // List-of-rows representation - const rowCount = useIntYPos ? parser.getInt() : parser.getShort(); - for (let i = 0; i < rowCount; i++) { - const dy = useIntYPos ? parser.getInt() : parser.getShort(); - const binY = binYOffset + dy; - const colCount = useIntXPos ? parser.getInt() : parser.getShort(); - for (let j = 0; j < colCount; j++) { - const dx = useIntXPos ? parser.getInt() : parser.getShort(); - const binX = binXOffset + dx; - const counts = useFloatContact ? parser.getFloat() : parser.getShort(); - records.push(new ContactRecord(binX, binY, counts)); - } - } - } else if (type == 2) { - - const nPts = parser.getInt(); - const w = parser.getShort(); - - for (let i = 0; i < nPts; i++) { - //int idx = (p.y - binOffset2) * w + (p.x - binOffset1); - const row = Math.floor(i / w); - const col = i - row * w; - const bin1 = binXOffset + col; - const bin2 = binYOffset + row; - - if (useFloatContact) { - const counts = parser.getFloat(); - if (!isNaN(counts)) { - records.push(new ContactRecord(bin1, bin2, counts)); - } - } else { - const counts = parser.getShort(); - if (counts != Short_MIN_VALUE) { - records.push(new ContactRecord(bin1, bin2, counts)); - } - } - } - } else { - throw new Error("Unknown block type: " + type); - } - - } - - return new Block(blockNumber, zd, records, idx); - - - } - }; - - async hasNormalizationVector(type, chr, unit, binSize) { - await this.init(); - let chrIdx; - if (Number.isInteger(chr)) { - chrIdx = chr; - } else { - const canonicalName = this.getFileChrName(chr); - chrIdx = this.chromosomeIndexMap[canonicalName]; - } - const key = getNormalizationVectorKey(type, chrIdx, unit.toString(), binSize); - const normVectorIndex = await this.getNormVectorIndex(); - return normVectorIndex && normVectorIndex[key]; - } - - async isNormalizationValueAvailableAtResolution(normalization, chr, unit, resolution) { - - let chromosomeIndex; - if (Number.isInteger(chr)) { - chromosomeIndex = chr; - } else { - const canonicalName = this.getFileChrName(chr); - chromosomeIndex = this.chromosomeIndexMap[canonicalName]; - } - - const normVectorIndex = await this.getNormVectorIndex(); - - const key = getNormalizationVectorKey(normalization, chromosomeIndex, unit.toString(), resolution); - - const index = normVectorIndex[key]; - - return undefined !== index - - } - - async getNormalizationVector(type, chr, unit, binSize) { - - await this.init(); - - let chrIdx; - if (Number.isInteger(chr)) { - chrIdx = chr; - } else { - const canonicalName = this.getFileChrName(chr); - chrIdx = this.chromosomeIndexMap[canonicalName]; - } - - const key = getNormalizationVectorKey(type, chrIdx, unit.toString(), binSize); - - if (this.normVectorCache.has(key)) { - return this.normVectorCache.get(key); - } - - const normVectorIndex = await this.getNormVectorIndex(); - - if (!normVectorIndex) { - console.log("Normalization vectors not present in this file"); - return undefined - } - - const status = await this.isNormalizationValueAvailableAtResolution(type, chr, unit, binSize); - - if (false === status) { - - const str = `Normalization option ${ type } not available at resolution ${ binSize }. Will use NONE.`; - console.log(str); - - if (this.alert) { - this.alert(str); - } - return undefined - } - - const idx = normVectorIndex[key]; - - const data = await this.file.read(idx.filePosition, 8); - - if (!data) { - return undefined; - } - - const parser = new BinaryParser(new DataView(data)); - const nValues = this.version < 9 ? parser.getInt() : parser.getLong(); - const dataType = this.version < 9 ? DOUBLE : FLOAT; - const filePosition = this.version < 9 ? idx.filePosition + 4 : idx.filePosition + 8; - const nv = new NormalizationVector(this.file, filePosition, nValues, dataType); - this.normVectorCache.set(key, nv); - return nv; - - } - - async getNormVectorIndex() { - - if (this.version < 6) { - return undefined; - } - - if (!this.normVectorIndex) { - - // If nvi is not supplied, try reading from remote lambda service - if (!this.config.nvi && this.remote && this.url) { - const url = new URL(this.url); - const key = encodeURIComponent(url.hostname + url.pathname); - if(nvi$1.hasOwnProperty(key)) { - this.config.nvi = nvi$1[key]; - } - } - - if (this.config.nvi) { - const nviArray = decodeURIComponent(this.config.nvi).split(","); - const range = {start: parseInt(nviArray[0]), size: parseInt(nviArray[1])}; - return this.readNormVectorIndex(range) - } else { - try { - await this.readNormExpectedValuesAndNormVectorIndex(); - return this.normVectorIndex - } catch (e) { - if (e.code === "416" || e.code === 416) { - // This is expected if file does not contain norm vectors - this.normExpectedValueVectorsPosition = undefined; - } else { - console.error(e); - } - } - } - } - - return this.normVectorIndex - } - - async getNormalizationOptions() { - // Normalization options are computed as a side effect of loading the index. A bit - // ugly but alternatives are worse. - await this.getNormVectorIndex(); - return this.normalizationTypes; - } - - /** - * Return a promise to load the normalization vector index - * - * @param dataset - * @param range -- file range {position, size} - * @returns Promise for the normalization vector index - */ - async readNormVectorIndex(range) { - - await this.init(); - - this.normalizationVectorIndexRange = range; - - const data = await this.file.read(range.start, range.size); - - const binaryParser = new BinaryParser(new DataView(data)); - - this.normVectorIndex = {}; - - let nEntries = binaryParser.getInt(); - while (nEntries-- > 0) { - this.parseNormVectorEntry(binaryParser); - } - - return this.normVectorIndex; - - } - - /** - * This function is used when the position of the norm vector index is unknown. We must read through the expected - * values to find the index - * - * @param dataset - * @returns {Promise} - */ - async readNormExpectedValuesAndNormVectorIndex() { - - await this.init(); - - if (this.normExpectedValueVectorsPosition === undefined) { - return; - } - - const nviStart = await this.skipExpectedValues(this.normExpectedValueVectorsPosition); - let byteCount = INT; - - let data = await this.file.read(nviStart, INT); - if (data.byteLength === 0) { - // This is possible if there are no norm vectors. Its a legal v8 file, though uncommon - return; - } - const binaryParser = new BinaryParser(new DataView(data)); - const nEntries = binaryParser.getInt(); - const sizeEstimate = nEntries * 30; - const range = {start: nviStart + byteCount, size: sizeEstimate}; - - data = await this.file.read(range.start, range.size); - this.normalizedExpectedValueVectors = {}; - this.normVectorIndex = {}; - - // Recursively process entries - await processEntries.call(this, nEntries, data); - - this.config.nvi = nviStart.toString() + "," + byteCount; - - async function processEntries(nEntries, data) { - - const binaryParser = new BinaryParser(new DataView(data)); - - while (nEntries-- > 0) { - - if (binaryParser.available() < 100) { - - nEntries++; // Reset counter as entry is not processed - - byteCount += binaryParser.position; - const sizeEstimate = Math.max(1000, nEntries * 30); - const range = {start: nviStart + byteCount, size: sizeEstimate}; - const data = await this.file.read(range.start, range.size); - return processEntries.call(this, nEntries, data); - } - - this.parseNormVectorEntry(binaryParser); - - } - byteCount += binaryParser.position; - } - } - - /** - * This function is used when the position of the norm vector index is unknown. We must read through the - * normalized expected values to find the index - * - * @param dataset - * @returns {Promise} - */ - async skipExpectedValues(start) { - - const version = this.version; - const file = new BufferedFile({file: this.file, size: 256000}); - const range = {start: start, size: INT}; - const data = await file.read(range.start, range.size); - const binaryParser = new BinaryParser(new DataView(data)); - const nEntries = binaryParser.getInt(); // Total # of expected value chunks - if (nEntries === 0) { - return start + INT; - } else { - return parseNext(start + INT, nEntries); - } // Skip 4 bytes for int - - - async function parseNext(start, nEntries) { - - let range = {start: start, size: 500}; - let chunkSize = 0; - let p0 = start; - - let data = await file.read(range.start, range.size); - let binaryParser = new BinaryParser(new DataView(data)); - binaryParser.getString(); // type - binaryParser.getString(); // unit - binaryParser.getInt(); // binSize - const nValues = version < 9 ? binaryParser.getInt() : binaryParser.getLong(); - - chunkSize += binaryParser.position + nValues * (version < 9 ? DOUBLE : FLOAT); - - range = {start: start + chunkSize, size: INT}; - data = await file.read(range.start, range.size); - binaryParser = new BinaryParser(new DataView(data)); - const nChrScaleFactors = binaryParser.getInt(); - chunkSize += (INT + nChrScaleFactors * (INT + (version < 9 ? DOUBLE : FLOAT))); - - - nEntries--; - if (nEntries === 0) { - return p0 + chunkSize; - } else { - return parseNext(p0 + chunkSize, nEntries); - } - } - } - - getZoomIndexForBinSize(binSize, unit) { - - unit = unit || "BP"; - - let resolutionArray; - if (unit === "BP") { - resolutionArray = this.bpResolutions; - } else if (unit === "FRAG") { - resolutionArray = this.fragResolutions; - } else { - throw new Error("Invalid unit: " + unit); - } - - for (let i = 0; i < resolutionArray.length; i++) { - if (resolutionArray[i] === binSize) return i; - } - - return -1; - } - - parseNormVectorEntry(binaryParser) { - const type = binaryParser.getString(); //15 - const chrIdx = binaryParser.getInt(); //4 - const unit = binaryParser.getString(); //3 - const binSize = binaryParser.getInt(); //4 - const filePosition = binaryParser.getLong(); //8 - const sizeInBytes = this.version < 9 ? binaryParser.getInt() : binaryParser.getLong(); //4:8 - const key = type + "_" + chrIdx + "_" + unit + "_" + binSize; - // TODO -- why does this not work? NormalizationVector.getNormalizationVectorKey(type, chrIdx, unit, binSize); - - if (!this.normalizationTypes.includes(type)) { - this.normalizationTypes.push(type); - } - this.normVectorIndex[key] = {filePosition: filePosition, size: sizeInBytes}; - } - - getFileChrName(chrAlias) { - if (this.chrAliasTable.hasOwnProperty(chrAlias)) { - return this.chrAliasTable[chrAlias] - } else { - return chrAlias - } - } - - - // NOTE sties are not currently used - // async getSites(chrName) { - // let sites = this.fragmentSitesCache[chrName]; - // if (!sites) { - // if (this.fragmentSitesIndex) { - // const entry = self.fragmentSitesIndex[chrName]; - // if (entry && entry.nSites > 0) { - // sites = await this.readSites(entry.position, entry.nSites) - // this.fragmentSitesCache[chrName] = sites; - // } - // } - // } - // return sites; - // } - // - -} - - -function getNormalizationVectorKey(type, chrIdx, unit, resolution) { - return type + "_" + chrIdx + "_" + unit + "_" + resolution; -} - -function isGoogleDrive(url) { - return url.indexOf("drive.google.com") >= 0 || url.indexOf("www.googleapis.com/drive") > 0 -} - -class Block { - constructor(blockNumber, zoomData, records, idx) { - this.blockNumber = blockNumber; - this.zoomData = zoomData; - this.records = records; - this.idx = idx; - } -} - - -class BlockCache { - - constructor() { - this.resolution = undefined; - this.map = new LRU(6); - } - - set(resolution, key, value) { - if (this.resolution !== resolution) { - this.map.clear(); - } - this.resolution = resolution; - this.map.set(key, value); - } - - get(resolution, key) { - return this.resolution === resolution ? this.map.get(key) : undefined; - } - - has(resolution, key) { - return this.resolution === resolution && this.map.has(key); - } -} - -class Straw { - - constructor(config) { - this.config = config; - this.hicFile = new HicFile(config); - } - - async getMetaData() { - return await this.hicFile.getMetaData() - } - - //straw [:x1:x2] [:y1:y2] - async getContactRecords(normalization, region1, region2, units, binsize) { - return this.hicFile.getContactRecords(normalization, region1, region2, units, binsize); - } - - async getNormalizationOptions() { - return this.hicFile.getNormalizationOptions() - } - - async getNVI() { - await this.hicFile.getNormVectorIndex(); - return this.hicFile.config.nvi; - } - - async printIndexStats() { - await this.hicFile.printIndexStats(); - } - - getFileChrName(chrAlias) { - if (this.hicFile.chrAliasTable.hasOwnProperty(chrAlias)) { - return this.hicFile.chrAliasTable[chrAlias] - } else { - return chrAlias - } - } -} - -function isGoogleURL(url) { - return (url.includes("googleapis") && !url.includes("urlshortener")) || - isGoogleStorageURL(url) || - isGoogleDriveURL(url) -} - -function isGoogleStorageURL(url) { - return url.startsWith("gs://") || - url.startsWith("https://www.googleapis.com/storage") || - url.startsWith("https://storage.cloud.google.com") || - url.startsWith("https://storage.googleapis.com"); -} - -function isGoogleDriveURL(url) { - return url.indexOf("drive.google.com") >= 0 || url.indexOf("www.googleapis.com/drive") > 0 -} - -// %23 %24 %25 %26 %27 %28 %29 %2A %2B %2C %2F %3A %3B %3D %3F %40 %5B %5D -const encodings = new Map(); -encodings.set("!", "%21"); -encodings.set("#", "%23"); -encodings.set("$", "%24"); -encodings.set("%", "%25"); -encodings.set("&", "%26"); -encodings.set("'", "%27"); -encodings.set("(", "%28"); -encodings.set(")", "%29"); -encodings.set("*", "%2A"); -encodings.set("+", "%2B"); -encodings.set(",", "%2C"); -encodings.set("/", "%2F"); -encodings.set(":", "%3A"); -encodings.set(";", "%3B"); -encodings.set("=", "%3D"); -encodings.set("?", "%3F"); -encodings.set("@", "%40"); -encodings.set("[", "%5B"); -encodings.set("]", "%5D"); -encodings.set(" ", "%20"); - -function getDriveDownloadURL(link) { - // Return a google drive download url for the sharable link - //https://drive.google.com/open?id=0B-lleX9c2pZFbDJ4VVRxakJzVGM - //https://drive.google.com/file/d/1_FC4kCeO8E3V4dJ1yIW7A0sn1yURKIX-/view?usp=sharing - var id = getGoogleDriveFileID(link); - return id ? "https://www.googleapis.com/drive/v3/files/" + id + "?alt=media&supportsTeamDrives=true" : link; -} - -function getGoogleDriveFileID(link) { - - //https://drive.google.com/file/d/1_FC4kCeO8E3V4dJ1yIW7A0sn1yURKIX-/view?usp=sharing - //https://www.googleapis.com/drive/v3/files/1w-tvo6p1SH4p1OaQSVxpkV_EJgGIstWF?alt=media&supportsTeamDrives=true" - - if (link.includes("/open?id=")) { - const i1 = link.indexOf("/open?id=") + 9; - const i2 = link.indexOf("&"); - if (i1 > 0 && i2 > i1) { - return link.substring(i1, i2) - } else if (i1 > 0) { - return link.substring(i1); - } - - } else if (link.includes("/file/d/")) { - const i1 = link.indexOf("/file/d/") + 8; - const i2 = link.lastIndexOf("/"); - return link.substring(i1, i2); - - } else if (link.startsWith("https://www.googleapis.com/drive")) { - let i1 = link.indexOf("/files/"); - const i2 = link.indexOf("?"); - if (i1 > 0) { - i1 += 7; - return i2 > 0 ? - link.substring(i1, i2) : - link.substring(i1) - } - } - - throw Error("Unknown Google Drive url format: " + link); - - -} - -/* - * @author Jim Robinson Dec-2020 - */ - -class IGVRemoteFile { - - - constructor(args) { - this.config = args; - this.url = args.path || args.url; - } - - - async read(position, length) { - - const range = {start: position, size: length}; - - return igvxhr$1.loadArrayBuffer(this.url, {range}); - - } -} - -/* - * The MIT License (MIT) - * - * Copyright (c) 2016-2020 The Regents of the University of California - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and - * associated documentation files (the "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the - * following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING - * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - */ - -const knownGenomes = { - - "hg19": [249250621, 243199373, 198022430], - "hg38": [248956422, 242193529, 198295559], - "mm10": [195471971, 182113224, 160039680], - "mm9": [197195432, 181748087, 159599783], - "dm6": [23513712, 25286936, 28110227] - -}; - -class Dataset { - - constructor(config) { - this.straw = new Straw(config); - } - - async init() { - - this.hicFile = this.straw.hicFile; - await this.hicFile.init(); - this.normalizationTypes = ['NONE']; - - this.genomeId = this.hicFile.genomeId; - this.chromosomes = this.hicFile.chromosomes; - this.bpResolutions = this.hicFile.bpResolutions; - this.wholeGenomeChromosome = this.hicFile.wholeGenomeChromosome; - this.wholeGenomeResolution = this.hicFile.wholeGenomeResolution; - - // Attempt to determine genomeId if not recognized - // if (!Object.keys(knownGenomes).includes(this.genomeId)) { - const tmp = matchGenome(this.chromosomes); - if (tmp) this.genomeId = tmp; - // } - } - - async getContactRecords(normalization, region1, region2, units, binsize) { - return this.straw.getContactRecords(normalization, region1, region2, units, binsize) - } - - async hasNormalizationVector(type, chr, unit, binSize) { - return this.straw.hicFile.hasNormalizationVector(type, chr, unit, binSize); - } - - clearCaches() { - this.colorScaleCache = {}; - } - - async getMatrix(chr1, chr2) { - return this.hicFile.getMatrix(chr1, chr2) - } - - getZoomIndexForBinSize(binSize, unit) { - var i, - resolutionArray; - - unit = unit || "BP"; - - if (unit === "BP") { - resolutionArray = this.bpResolutions; - } else if (unit === "FRAG") { - resolutionArray = this.fragResolutions; - } else { - throw new Error("Invalid unit: " + unit); - } - - for (i = 0; i < resolutionArray.length; i++) { - if (resolutionArray[i] === binSize) return i; - } - - return -1; - } - - getBinSizeForZoomIndex(zoomIndex, unit) { - var resolutionArray; - - unit = unit || "BP"; - - if (unit === "BP") { - resolutionArray = this.bpResolutions; - } else if (unit === "FRAG") { - resolutionArray = this.fragResolutions; - } else { - throw new Error("Invalid unit: " + unit); - } - - return resolutionArray[zoomIndex]; - } - - getChrIndexFromName(chrName) { - var i; - for (i = 0; i < this.chromosomes.length; i++) { - if (chrName === this.chromosomes[i].name) return i; - } - return undefined; - } - - compareChromosomes(otherDataset) { - const chrs = this.chromosomes; - const otherChrs = otherDataset.chromosomes; - if (chrs.length !== otherChrs.length) { - return false; - } - for (let i = 0; i < chrs.length; i++) { - if (chrs[i].size !== otherChrs[i].size) { - return false; - } - } - return true; - } - - isWholeGenome(chrIndex) { - return (this.wholeGenomeChromosome != null && this.wholeGenomeChromosome.index === chrIndex); - } - - async getNormVectorIndex() { - return this.hicFile.getNormVectorIndex() - } - - async getNormalizationOptions() { - return this.hicFile.getNormalizationOptions() - } - - /** - * Compare 2 datasets for compatibility. Compatibility is defined as from the same assembly, even if - * different IDs are used (e.g. GRCh38 vs hg38). - * - * Trust the ID for well-known assemblies (hg19, etc). However, for others compare chromosome lengths - * as its been observed that uniqueness of ID is not guaranteed. - * - * @param d1 - * @param d2 - */ - isCompatible(d2) { - const id1 = this.genomeId; - const id2 = d2.genomeId; - return ((id1 === "hg38" || id1 === "GRCh38") && (id2 === "hg38" || id2 === "GRCh38")) || - ((id1 === "hg19" || id1 === "GRCh37") && (id2 === "hg19" || id2 === "GRCh37")) || - ((id1 === "mm10" || id1 === "GRCm38") && (id2 === "mm10" || id2 === "GRCm38")) || - this.compareChromosomes(d2) - } - - static async loadDataset(config) { - - // If this is a local file, use the "blob" field for straw - if (isFile(config.url)) { - config.blob = config.url; - delete config.url; - } else { - // If this is a google url, add api KEY - if (isGoogleURL(config.url)) { - if (isGoogleDriveURL(config.url)) { - config.url = getDriveDownloadURL(config.url); - } - const copy = Object.assign({}, config); - config.file = new IGVRemoteFile(copy); - } - } - - const dataset = new Dataset(config); - await dataset.init(); - dataset.url = config.url; - return dataset - } -} - -function matchGenome(chromosomes) { - - if (chromosomes.length < 4) return undefined; - - const keys = Object.keys(knownGenomes); - - // Find a candidate - let candidate; - for (let chr of chromosomes) { - for (let key of keys) { - if (knownGenomes[key].includes(chr.size)) { - candidate = key; - break; - } - } - } - - // Confirm candidate - if (candidate) { - const chrSizes = new Set(chromosomes.map((chr) => chr.size)); - for (let sz of knownGenomes[candidate]) { - if (!chrSizes.has(sz)) { - return undefined; - } - } - return candidate; - } else { - return undefined; - } - - -} - -/* - * The MIT License (MIT) - * - * Copyright (c) 2016-2017 The Regents of the University of California - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and - * associated documentation files (the "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the - * following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING - * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - */ - - -/** - * @author Jim Robinson - */ - - -/** - * - * @param id - * @param chromosomes -- an array of hic.Chromosome objects. - * @constructor - */ -class Genome { - constructor(id, chromosomes) { - - this.id = id; - this.chromosomes = chromosomes; - - this.wgChromosomeNames = []; - this.chromosomeLookupTable = {}; - - // Alias for size for igv compatibility - this.genomeLength = 0; - for (let c of this.chromosomes) { - c.bpLength = c.size; - if ('all' !== c.name.toLowerCase()) { - this.genomeLength += c.size; - this.wgChromosomeNames.push(c.name); - } - } - - /** - * Maps chr aliases to the offical name. Deals with - * 1 <-> chr1, chrM <-> MT, IV <-> chr4, etc. - * @param str - */ - var chrAliasTable = {}; - - // The standard mappings - for (let chromosome of chromosomes) { - - const name = chromosome.name; - if (name.startsWith("arm_")) { - //Special rule for aidenlab ad-hoc names for dMel - const officialName = name.substring(4); - chrAliasTable[officialName] = name; - chrAliasTable["chr" + officialName] = name; - } else { - const alias = name.startsWith("chr") ? name.substring(3) : "chr" + name; - chrAliasTable[alias] = name; - if (name === "chrM") chrAliasTable["MT"] = "chrM"; - if (name === "MT") chrAliasTable["chrmM"] = "MT"; - } - this.chromosomeLookupTable[name.toLowerCase()] = chromosome; - } - - this.chrAliasTable = chrAliasTable; - - this.featureDB = new Map(); // Hash of name -> feature, used for search function. - - } - - getChromosomeName(str) { - var chr = this.chrAliasTable[str]; - return chr ? chr : str; - }; - - getChromosome(str) { - var chrname = this.getChromosomeName(str).toLowerCase(); - return this.chromosomeLookupTable[chrname]; - }; - - /** - * Return the genome coordinate for the give chromosome and position. - */ - getGenomeCoordinate(chr, bp) { - return this.getCumulativeOffset(chr.name) + bp; - }; - - getChromosomeForCoordinate(bp) { - var i = 0, - offset = 0, - l; - - for (i = 1; i < this.chromosomes.length; i++) { - l = this.chromosomes[i].size; - if (offset + l > bp) return this.chromosomes[i]; - offset += l; - } - return this.chromosomes[this.chromosomes.length - 1]; - } - - - /** - * Return the offset in genome coordinates (kb) of the start of the given chromosome - */ - getCumulativeOffset(chr) { - - const queryChr = this.getChromosomeName(chr); - - if (this.cumulativeOffsets === undefined) { - computeCumulativeOffsets$1.call(this); - } - return this.cumulativeOffsets[queryChr]; - } - - // Required for igv.js - getGenomeLength() { - return this.genomeLength; - } - - // Required for igv.js - addFeaturesToDB(featureList, config) { - - const insertFeature = (name, feature) => { - const current = this.featureDB.get(name); - if (current) { - feature = (feature.end - feature.start) > (current.end - current.start) ? feature : current; - } - this.featureDB.set(name, feature); - }; - - for (let feature of featureList) { - if (feature.name) { - insertFeature(feature.name.toUpperCase(), feature); - } - if (feature.gene && feature.gene.name) { - insertFeature(feature.gene.name.toUpperCase(), feature); - } - } - } -} -function computeCumulativeOffsets$1() { - - const cumulativeOffsets = {}; - let offset = 0; - // Skip first chromosome (its chr all). - for (let chromosome of this.chromosomes) { - if(chromosome.name === 'all') continue; - cumulativeOffsets[chromosome.name] = Math.floor(offset); - offset += (chromosome.size); - } - this.cumulativeOffsets = cumulativeOffsets; -} - -/* - * The MIT License (MIT) - * - * Copyright (c) 2016-2017 The Regents of the University of California - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and - * associated documentation files (the "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the - * following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING - * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - */ - -class State { - - constructor(chr1, chr2, locus, zoom, x, y, pixelSize, normalization) { - if (chr1 <= chr2) { - this.chr1 = chr1; - this['x'] = x; - - this.chr2 = chr2; - this['y'] = y; - } else { - // Transpose - this.chr1 = chr2; - this['x'] = y; - - this.chr2 = chr1; - this['y'] = x; - } - - this.zoom = zoom; - - if (undefined === normalization) { - console.warn("Normalization is undefined. Will use NONE"); - normalization = 'NONE'; - } - this.normalization = normalization; - - if (Number.isNaN(pixelSize)) { - pixelSize = 1; - } - this.pixelSize = pixelSize; - - this.locus = locus; - } - - // Getters and setters for width and height - // get width() { - // return this._width; - // } - // - // set width(value) { - // this._width = value; - // } - // - // get height() { - // return this._height; - // } - // - // set height(value) { - // this._height = value; - // } - - clampXY(dataset, viewDimensions) { - const { width, height } = viewDimensions; - const { chromosomes, bpResolutions } = dataset; - - const binSize = bpResolutions[this.zoom]; - const maxX = Math.max(0, chromosomes[this.chr1].size / binSize - width / this.pixelSize); - const maxY = Math.max(0, chromosomes[this.chr2].size / binSize - height / this.pixelSize); - - this.x = Math.min(Math.max(0, this.x), maxX); - this.y = Math.min(Math.max(0, this.y), maxY); - } - - async panWithZoom(zoom, pixelSize, anchorPx, anchorPy, binSize, browser, dataset, viewDimensions, bpResolutions){ - - const minPixelSize = await browser.minPixelSize(this.chr1, this.chr2, zoom); - pixelSize = Math.max(pixelSize, minPixelSize); - - // Genomic anchor -- this position should remain at anchorPx, anchorPy after state change - bpResolutions[this.zoom]; - const gx = (this.x + anchorPx / this.pixelSize) * bpResolutions[this.zoom].binSize; - const gy = (this.y + anchorPy / this.pixelSize) * bpResolutions[this.zoom].binSize; - - this.x = gx / binSize - anchorPx / pixelSize; - this.y = gy / binSize - anchorPy / pixelSize; - - this.zoom = zoom; - this.pixelSize = pixelSize; - - this.clampXY(dataset, viewDimensions); - - } - - panShift(dx, dy, browser, dataset, viewDimensions) { - - this.x += (dx / this.pixelSize); - this.y += (dy / this.pixelSize); - this.clampXY(dataset, viewDimensions); - - this.configureLocus(browser, dataset, viewDimensions); - - } - - async setWithZoom(zoom, viewDimensions, browser, dataset){ - - const {width, height} = viewDimensions; - - // bin = bin + pixel * bin/pixel = bin - const xCenter = this.x + (width/2) / this.pixelSize; - const yCenter = this.y + (height/2) / this.pixelSize; - - const binSize = dataset.bpResolutions[this.zoom]; - const binSizeNew = dataset.bpResolutions[zoom]; - - const scaleFactor = binSize / binSizeNew; - - const xCenterNew = xCenter * scaleFactor; - const yCenterNew = yCenter * scaleFactor; - - const minPixelSize = await browser.minPixelSize(this.chr1, this.chr2, zoom); - - this.pixelSize = Math.max(DEFAULT_PIXEL_SIZE, minPixelSize); - - const resolutionChanged = (this.zoom !== zoom); - - this.zoom = zoom; - this.x = Math.max(0, xCenterNew - width / (2 * this.pixelSize)); - this.y = Math.max(0, yCenterNew - height / (2 * this.pixelSize)); - - this.clampXY(dataset, viewDimensions); - - this.configureLocus(browser, dataset, viewDimensions); - - return resolutionChanged - } - - configureLocus(browser, dataset, viewDimensions){ - - const bpPerBin = dataset.bpResolutions[this.zoom]; - - const startBP1 = Math.round(this.x * bpPerBin); - const startBP2 = Math.round(this.y * bpPerBin); - - const chr1 = dataset.chromosomes[this.chr1]; - const chr2 = dataset.chromosomes[this.chr2]; - const pixelsPerBin = this.pixelSize; - const endBP1 = Math.min(chr1.size, Math.round(((viewDimensions.width / pixelsPerBin) * bpPerBin)) + startBP1); - const endBP2 = Math.min(chr2.size, Math.round(((viewDimensions.height / pixelsPerBin) * bpPerBin)) + startBP2); - - const x = { chr:chr1.name, start:startBP1, end:endBP1 }; - const y = { chr:chr2.name, start:startBP2, end:endBP2 }; - - this.locus = { x, y }; - } - - updateWithLoci(chr1Name, bpX, bpXMax, chr2Name, bpY, bpYMax, browser, width, height){ - - const bpResolutions = browser.getResolutions(); - - // bp/pixel - let bpPerPixelTarget = Math.max((bpXMax - bpX) / width, (bpYMax - bpY) / height); - let resolutionChanged; - let zoomNew; - if (true === browser.resolutionLocked) { - resolutionChanged = false; - zoomNew = this.zoom; - } else { - zoomNew = browser.findMatchingZoomIndex(bpPerPixelTarget, bpResolutions); - resolutionChanged = (zoomNew !== this.zoom); - } - - const { binSize:binSizeNew } = bpResolutions[zoomNew]; - const pixelSize = Math.min(MAX_PIXEL_SIZE, Math.max(1, binSizeNew / bpPerPixelTarget)); - const newXBin = bpX / binSizeNew; - const newYBin = bpY / binSizeNew; - - const { index:chr1Index } = browser.genome.getChromosome( chr1Name ); - const { index:chr2Index } = browser.genome.getChromosome( chr2Name ); - - const chrChanged = this.chr1 !== chr1Index || this.chr2 !== chr2Index; - - this.chr1 = chr1Index; - this.chr2 = chr2Index; - this.zoom = zoomNew; - this.x = newXBin; - this.y = newYBin; - this.pixelSize = pixelSize; - this.locus = - { - x: { chr: chr1Name, start: bpX, end: bpXMax }, - y: { chr: chr2Name, start: bpY, end: bpYMax } - }; - - return { chrChanged, resolutionChanged } - } - - sync(targetState, browser, genome, dataset){ - - const chr1 = genome.getChromosome(targetState.chr1Name); - const chr2 = genome.getChromosome(targetState.chr2Name); - - const bpPerPixelTarget = targetState.binSize/targetState.pixelSize; - - const zoomNew = browser.findMatchingZoomIndex(bpPerPixelTarget, dataset.bpResolutions); - const binSizeNew = dataset.bpResolutions[ zoomNew ]; - const pixelSizeNew = Math.min(MAX_PIXEL_SIZE, Math.max(1, binSizeNew / bpPerPixelTarget)); - - const xBinNew = targetState.binX * (targetState.binSize/binSizeNew); - const yBinNew = targetState.binY * (targetState.binSize/binSizeNew); - - const zoomChanged = (browser.state.zoom !== zoomNew); - const chrChanged = (browser.state.chr1 !== chr1.index || browser.state.chr2 !== chr2.index); - - this.chr1 = chr1.index; - this.chr2 = chr2.index; - this.zoom = zoomNew; - this.x = xBinNew; - this.y = yBinNew; - this.pixelSize = pixelSizeNew; - - this.configureLocus(browser, dataset, browser.contactMatrixView.getViewDimensions()); - - return { zoomChanged, chrChanged } - - } - - stringify() { - if (this.normalization) { - return `${this.chr1},${this.chr2},${this.zoom},${this.x},${this.y},0,0,${this.pixelSize},${this.normalization}` - } else { - return `${this.chr1},${this.chr2},${this.zoom},${this.x},${this.y},0,0,${this.pixelSize}` - } - } - - clone() { - return Object.assign(new State(), this); - } - - equals(state) { - const s1 = JSON.stringify(this); - const s2 = JSON.stringify(state); - return s1 === s2; - } - - async sizeBP(dataset, zoomIndex, pixels){ - const matrix = await dataset.getMatrix(this.chr1, this.chr2); - const { zoom } = matrix.getZoomDataByIndex(zoomIndex, 'BP'); - - // bp = pixel * (bp/bin) * (bin/pixel) = pixel * bp/pixel = bp - return pixels * (zoom.binSize/this.pixelSize) - } - - static parse(string) { - const tokens = string.split(","); - - if (tokens.length <= 7) { - // Backwards compatibility - return new State( - parseInt(tokens[0]), // chr1 - parseInt(tokens[1]), // chr2 - undefined, // locus - parseFloat(tokens[2]), // zoom - parseFloat(tokens[3]), // x - parseFloat(tokens[4]), // y - parseFloat(tokens[5]), // pixelSize - tokens.length > 6 ? tokens[6] : "NONE" // normalization - ) - } else { - return new State( - parseInt(tokens[0]), // chr1 - parseInt(tokens[1]), // chr2 - undefined, // locus - parseFloat(tokens[2]), // zoom - parseFloat(tokens[3]), // x - parseFloat(tokens[4]), // y - parseFloat(tokens[7]), // pixelSize - tokens.length > 8 ? tokens[8] : "NONE" // normalization - ) - } - } - - // Method 1: Convert the State object to a JSON object - toJSON() { - const json = - { - chr1: this.chr1, - chr2: this.chr2, - zoom: this.zoom, - x: this.x, - y: this.y, - pixelSize: this.pixelSize, - normalization: this.normalization || 'NONE' - }; - - if (this.locus) { - json.locus = this.locus; - } - - return json - } - - // Method 2: Parse a JSON object and create an instance of the State class - static fromJSON(json) { - return new State( - json.chr1, - json.chr2, - json.locus, - json.zoom, - json.x, - json.y, - json.pixelSize, - json.normalization - ); - } - - static default(configOrUndefined) { - const state = new State(0, 0, undefined, 0, 0, 1, "NONE"); - return state - } - -} - -/* - * The MIT License (MIT) - * - * Copyright (c) 2016-2017 The Regents of the University of California - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and - * associated documentation files (the "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the - * following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING - * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - */ - -async function geneSearch(genomeId, featureName) { - const searchServiceURL = `https://portals.broadinstitute.org/webservices/igv/locus?genome=${genomeId}&name=${encodeURIComponent(featureName)}`; - - try { - const data = await igvxhr$1.loadString(searchServiceURL); - const results = parseSearchResults(data); - - return results.length ? results[0] : undefined; - } catch (error) { - console.error(`Error fetching gene data for "${featureName}":`, error); - return undefined; - } -} - - -function parseSearchResults(data) { - const parsed = splitLines$6(data) - .filter(line => line.trim() !== '').map(line => line.split('\t')) - .filter(tokens => tokens.length >= 3).map(tokens => tokens[1]); - - return parsed -} - -// Contains "normalization vector index" (nvi values) for legacy (v8) hosted files from aidenlab, ENCODE, and 4DN. -// These values can speed up initialization by a few seconds. -var nvi = { - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2Fcombined.hic": "54386046426,55860", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2Fprimary.hic": "33860030033,37504", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2Freplicate.hic": "30849652794,55832", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2Fmaternal.hic": "1380542661,17185", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2Fpaternal.hic": "1389001777,17185", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fimr90%2Fin-situ%2Fcombined.hic": "13433880319,35723", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC001.hic": "3409347253,35975", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC002.hic": "4529947083,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC003.hic": "6894962500,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC004.hic": "3395593338,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC005.hic": "5204128636,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC006.hic": "3278363811,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC007.hic": "3585547340,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC008.hic": "4134197273,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC009.hic": "2851728310,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC010.hic": "1754216102,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC011.hic": "1716829574,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC012.hic": "4367980375,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC013.hic": "2309654671,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC014.hic": "5324950266,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC015.hic": "3132333594,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC016.hic": "3159154704,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC017.hic": "3262554627,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC018.hic": "3014216364,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC019.hic": "5025753246,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC020.hic": "5861584507,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC021.hic": "3542263275,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC022.hic": "5061949378,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC023.hic": "4816423919,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC024.hic": "2683781104,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC025.hic": "6522701781,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC026.hic": "6748846520,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC027.hic": "5642693007,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC028.hic": "2098921691,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC029.hic": "3886454027,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fagar%2FHIC030.hic": "2288984204,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fagar%2FHIC031.hic": "2115342419,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fpellet%2FHIC032.hic": "2063314324,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fsupernatant%2FHIC033.hic": "1933908457,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fdilution%2FHIC034.hic": "13555514595,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fdilution%2FHIC035.hic": "6129650900,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fdilution%2FHIC036.hic": "4307445019,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fdilution%2FHIC037.hic": "9375139867,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fdilution%2Fcombined.hic": "11664249584,33929", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2Fcombined_DpnII.hic": "7003537290,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC038.hic": "2099825544,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC039.hic": "2096900138,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC040.hic": "2593642141,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC041.hic": "2263919098,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC042.hic": "2684774693,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2Fcombined_noXlink.hic": "5574807456,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC043.hic": "2986114347,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC044.hic": "1916378621,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC045.hic": "746463126,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC046.hic": "2338476164,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC047.hic": "1167496250,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC048.hic": "2231690794,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC049.hic": "2782308678,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fimr90%2Fin-situ%2FHIC050.hic": "3633531346,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fimr90%2Fin-situ%2FHIC051.hic": "4063486444,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fimr90%2Fin-situ%2FHIC052.hic": "929756278,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fimr90%2Fin-situ%2FHIC053.hic": "2489657204,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fimr90%2Fin-situ%2FHIC054.hic": "4036419444,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fimr90%2Fin-situ%2FHIC055.hic": "4284185549,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fimr90%2Fin-situ%2FHIC056.hic": "4410546240,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fimr90%2Fdilution%2FHIC057.hic": "1491998259,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fhmec%2Fin-situ%2Fcombined.hic": "7266425111,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fhmec%2Fin-situ%2FHIC058.hic": "6532635593,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fhmec%2Fin-situ%2FHIC059.hic": "400684530,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fhmec%2Fin-situ%2FHIC060.hic": "645352187,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fhmec%2Fin-situ%2FHIC061.hic": "736291871,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fhmec%2Fin-situ%2FHIC062.hic": "762731037,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fhmec%2Fin-situ%2FHIC063.hic": "682917431,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fhmec%2Fdilution%2FHIC064.hic": "4550171307,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fnhek%2Fin-situ%2Fcombined.hic": "11897184911,35789", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fnhek%2Fin-situ%2FHIC065.hic": "5425943567,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fnhek%2Fin-situ%2FHIC066.hic": "5942869818,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fnhek%2Fin-situ%2FHIC067.hic": "5191049261,35647", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fnhek%2Fdilution%2FHIC068.hic": "2713318801,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fk562%2Fin-situ%2Fcombined.hic": "12641555389,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fk562%2Fin-situ%2FHIC069.hic": "5630177461,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fk562%2Fin-situ%2FHIC070.hic": "5926611269,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fk562%2Fin-situ%2FHIC071.hic": "2486191351,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fk562%2Fin-situ%2FHIC072.hic": "2281343366,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fk562%2Fin-situ%2FHIC073.hic": "2173074239,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fk562%2Fin-situ%2FHIC074.hic": "2463700999,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fkbm7%2Fin-situ%2Fcombined.hic": "14661922519,35639", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fkbm7%2Fin-situ%2FHIC075.hic": "3685310515,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fkbm7%2Fin-situ%2FHIC076.hic": "5833658487,35891", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fkbm7%2Fin-situ%2FHIC077.hic": "2406346486,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fkbm7%2Fin-situ%2FHIC078.hic": "5241454987,35919", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fkbm7%2Fin-situ%2FHIC079.hic": "6297234263,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fhuvec%2Fin-situ%2Fcombined.hic": "9193858096,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fhuvec%2Fin-situ%2FHIC080.hic": "5171405536,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fhuvec%2Fin-situ%2FHIC081.hic": "3489767688,35891", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fhuvec%2Fin-situ%2FHIC082.hic": "4243339375,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fhuvec%2Fdilution%2FHIC083.hic": "1497495406,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fhela%2Fin-situ%2Fcombined.hic": "7923332224,35593", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fhela%2Fin-situ%2FHIC084.hic": "867699123,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fhela%2Fin-situ%2FHIC085.hic": "3669518514,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fhela%2Fin-situ%2FHIC086.hic": "5306474712,35595", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fhela%2Fin-situ%2FHIC087.hic": "1490963755,36397", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2Fcombined.hic": "8956382853,50248", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2FHIC088.hic": "1874185366,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2FHIC089.hic": "1301165236,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2FHIC090.hic": "1105246282,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2FHIC091.hic": "1338325770,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2FHIC092.hic": "1307918730,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2FHIC093.hic": "755136918,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2FHIC094.hic": "1606583694,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2FHIC095.hic": "2039711245,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2FHIC096.hic": "1909573053,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2FHIC097.hic": "1826710712,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2FHIC098.hic": "1998793575,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2FHIC099.hic": "1007740962,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2FHIC100.hic": "736464120,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2FHIC101.hic": "980505082,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2FHIC102.hic": "1116083646,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fdilution%2FHIC103.hic": "1096994310,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fdilution%2FHIC104.hic": "841063882,32102", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC105.hic": "107742864,36479", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC106.hic": "134295912,36479", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC107.hic": "110228014,36479", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC108.hic": "102761401,36479", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC109.hic": "100461491,36479", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC110.hic": "88828472,36479", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC111.hic": "81471064,36479", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC112.hic": "92297035,36479", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC113.hic": "65503916,36479", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC114.hic": "49181188,36479", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC115.hic": "46471102,36479", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC116.hic": "64284432,36479", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC117.hic": "60434076,36479", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC118.hic": "45248563,36479", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC119.hic": "60288782,36479", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC120.hic": "136888414,36479", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC121.hic": "125009003,33681", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC122.hic": "154011688,34127", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC123.hic": "177663372,35293", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC124.hic": "382186226,35245", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC125.hic": "158160717,35271", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC127.hic": "110261177,34659", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC128.hic": "246131875,35509", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC129.hic": "260160119,35667", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC130.hic": "117479562,34681", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC131.hic": "81508929,34673", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC132.hic": "105959102,34895", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC133.hic": "91504812,33451", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC134.hic": "52222546,33737", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC135.hic": "57763085,34159", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC136.hic": "50618489,33731", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC137.hic": "193163606,33363", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC138.hic": "229876152,33777", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC139.hic": "201783666,33571", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC140.hic": "281163862,34125", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC141.hic": "275969727,33935", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC142.hic": "275020431,34125", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC144.hic": "223834810,34177", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC145.hic": "296632653,33937", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC146.hic": "290945216,33961", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC147.hic": "234459964,34231", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC148.hic": "295457850,34039", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC149.hic": "113569632,35695", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC150.hic": "304381897,33963", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC151.hic": "289314545,33805", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC152.hic": "284320182,33803", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC153.hic": "401393947,34659", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC154.hic": "188065488,36479", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC155.hic": "299157119,33967", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC156.hic": "279289244,33787", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC157.hic": "254852119,33917", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC158.hic": "195969660,33477", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC159.hic": "185720388,36479", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC160.hic": "227709279,33599", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC161.hic": "157225076,33209", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC162.hic": "105703444,32033", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC163.hic": "122665658,32121", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC164.hic": "228048231,33761", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC165.hic": "114440819,32011", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC166.hic": "285147558,33891", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC167.hic": "363116754,33943", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC168.hic": "119592158,31937", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC169.hic": "236853872,33785", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC170.hic": "195187639,33395", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC171.hic": "208044058,33309", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC172.hic": "144645916,32877", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC173.hic": "119115941,32203", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC175.hic": "178030481,33525", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC176.hic": "117220136,32169", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC177.hic": "128586196,32659", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC178.hic": "191419141,33629", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC179.hic": "141556748,32959", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC180.hic": "199825102,33185", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC181.hic": "301022688,33783", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC182.hic": "185384453,33205", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC183.hic": "202189264,36367", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC184.hic": "37464475,36479", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC185.hic": "161938278,36099", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC186.hic": "133853166,36179", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC188.hic": "128068030,36237", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC189.hic": "148053886,36177", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC190.hic": "198946958,35803", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC191.hic": "226584564,36063", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC192.hic": "194412797,36341", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC193.hic": "176408194,36479", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC194.hic": "207215649,36055", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC195.hic": "175185530,36315", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC196.hic": "168969337,36479", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC197.hic": "121231252,36339", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC198.hic": "92713752,36479", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC199.hic": "105130500,36479", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC200.hic": "114526350,36479", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC201.hic": "122689717,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fhap1%2Fin-situ%2Fcombined.hic": "9614983328,36479", - "s3.amazonaws.com%2Fhicfiles%2Fexternal%2Fctbp_8_4_17%2Fall_intra_megabase_michrom.hic": "154205644,10960", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2Fdel-Xa-combined.hic": "8843305329,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FdelXa-chrX-diploid.hic": "11173520,1498", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FWT-combined.hic": "13365182403,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FWT-chrX-diploid.hic": "17343459,1498", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FHIC002.hic": "4279298739,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FHIC003.hic": "3027365532,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FHIC004.hic": "2896130835,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FHIC005.hic": "4717830071,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FHIC006.hic": "5066210154,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FHIC007.hic": "3069516128,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2Fdel-Xi-combined.hic": "14551096423,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FdelXi-chrX-diploid.hic": "17362477,1498", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FHIC008.hic": "2572386655,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FHIC009.hic": "2935931663,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FHIC010.hic": "2019085070,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FHIC011.hic": "6087610814,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FHIC012.hic": "2809618194,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FHIC013.hic": "2572386655,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fpatski%2FDarrowHuntley-2015%2Fcombined.hic": "6950423609,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fpatski%2FDarrowHuntley-2015%2Fpaternal.hic": "220592749,15691", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fpatski%2FDarrowHuntley-2015%2Fmaternal.hic": "323233095,15691", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fpatski%2FDarrowHuntley-2015%2FHIC014.hic": "3183235800,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fpatski%2FDarrowHuntley-2015%2FHIC015.hic": "1739539801,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fpatski%2FDarrowHuntley-2015%2FHIC016.hic": "1105912758,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fpatski%2FDarrowHuntley-2015%2FHIC017.hic": "1060773319,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fpatski%2FDarrowHuntley-2015%2FHIC018.hic": "1203679874,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fpatski%2FDarrowHuntley-2015%2FHIC019.hic": "3321955269,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Frhesus%2FDarrowHuntley-2015%2FHIC020.hic": "7108980626,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fcola%2FDarrowHuntley-2015%2FHIC021.hic": "3906448676,34955", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fassembly%2Faedes%2Fcombined.hic": "390780490,2245", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fassembly%2Fhs2-hic.hic": "1960284186,33561", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fassembly%2FCpipJ3.hic": "766279097,4381", - "s3.amazonaws.com%2Fhicfiles%2Fexternal%2Fphanstiel%2Fupdated_O%2FSnyder_O.hic": "8046980555,18679", - "s3.amazonaws.com%2Fhicfiles%2Fexternal%2Fphanstiel%2FA_inter.hic": "10986005145,18679", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Funtreated%2Funsynchronized%2Fcombined.hic": "30439217680,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftreated_6hr%2Funsynchronized%2Fcombined.hic": "33255540403,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2Fdeep%2F20min_withdraw_combined.hic": "11078436933,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2Fdeep%2F40min_withdraw_combined.hic": "11031830038,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2Fdeep%2F60min_withdraw_combined.hic": "10312725340,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2Fdeep%2F180min_withdraw_combined.hic": "10038610214,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Funtreated%2Funsynchronized%2FHIC001.hic": "8004335785,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Funtreated%2Funsynchronized%2FHIC002.hic": "8453215933,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Funtreated%2Funsynchronized%2FHIC003.hic": "9118406189,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Funtreated%2Funsynchronized%2FHIC004.hic": "5973342894,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Funtreated%2Funsynchronized%2FHIC005.hic": "6846576837,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Funtreated%2Funsynchronized%2FHIC006.hic": "6075148017,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Funtreated%2Funsynchronized%2FHIC007.hic": "8192366992,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftreated_6hr%2Funsynchronized%2FHIC008.hic": "6844159653,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftreated_6hr%2Funsynchronized%2FHIC009.hic": "7282063059,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftreated_6hr%2Funsynchronized%2FHIC010.hic": "10410578833,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftreated_6hr%2Funsynchronized%2FHIC011.hic": "8192366992,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftreated_6hr%2Funsynchronized%2FHIC012.hic": "7223422850,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftreated_6hr%2Funsynchronized%2FHIC013.hic": "7435986997,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftreated_6hr%2Funsynchronized%2FHIC014.hic": "9120113605,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Funtreated%2Fsynchronized%2Fcombined.hic": "4170577904,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Funtreated%2Fsynchronized%2FHIC015.hic": "1504084990,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Funtreated%2Fsynchronized%2FHIC016.hic": "1686244500,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Funtreated%2Fsynchronized%2FHIC017.hic": "1804802410,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Funtreated%2Fsynchronized%2FHIC018.hic": "1533942067,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftreated_6hr%2Fsynchronized%2Fcombined.hic": "4572390198,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftreated_6hr%2Fsynchronized%2FHIC019.hic": "1543609666,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftreated_6hr%2Fsynchronized%2FHIC020.hic": "1814133288,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftreated_6hr%2Fsynchronized%2FHIC021.hic": "1942698243,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftreated_6hr%2Fsynchronized%2FHIC022.hic": "1873587413,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2Funtreated%2FRao-2017-HIC049.hic": "405127557,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2Funtreated%2FRao-2017-HIC060.hic": "326681741,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2Funtreated%2FRao-2017-HIC061.hic": "300908673,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_20min%2FRao-2017-HIC050.hic": "481758242,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_20min%2FRao-2017-HIC051.hic": "417577401,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_40min%2FRao-2017-HIC052.hic": "419353227,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_40min%2FRao-2017-HIC053.hic": "411554953,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_60min%2FRao-2017-HIC054.hic": "386655891,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_60min%2FRao-2017-HIC055.hic": "402170701,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_240min%2FRao-2017-HIC057.hic": "735906308,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min%2FRao-2017-HIC058.hic": "443789827,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min%2FRao-2017-HIC059.hic": "491422615,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min%2FRao-2017-HIC062.hic": "320261375,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min%2FRao-2017-HIC063.hic": "306590499,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min_withdraw_20min%2FRao-2017-HIC032S.hic": "367051742,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min_withdraw_20min%2FRao-2017-HIC033S.hic": "344555339,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min_withdraw_40min%2FRao-2017-HIC036S.hic": "349392947,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min_withdraw_40min%2FRao-2017-HIC037S.hic": "317714554,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min_withdraw_60min%2FRao-2017-HIC040S.hic": "266786397,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min_withdraw_60min%2FRao-2017-HIC041S.hic": "279445530,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min_withdraw_180min%2FRao-2017-HIC044S.hic": "898418269,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min_withdraw_180min%2FRao-2017-HIC045S.hic": "961006347,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min_withdraw_360min%2FRao-2017-HIC064.hic": "833576408,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min_withdraw_360min%2FRao-2017-HIC065.hic": "840881418,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min_withdraw_1080min%2FRao-2017-HIC066.hic": "980958864,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min_withdraw_1080min%2FRao-2017-HIC067.hic": "882023129,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min_withdraw_1440min%2FRao-2017-HIC068.hic": "1110292630,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min_withdraw_1440min%2FRao-2017-HIC069.hic": "1001747023,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fexternal%2Frowley_nichols_mol_cell_2017%2FCP190_HiChIP.hic": "144107588,6976", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fexternal%2Frowley_nichols_mol_cell_2017%2FH3K27ac_HiChIP_combined.hic": "43171370,5233", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fexternal%2Frowley_nichols_mol_cell_2017%2FH3K27me3_HiChIP_combined.hic": "42906472,5233", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fexternal%2Frowley_nichols_mol_cell_2017%2FPol2_ChIAPET.hic": "41992430,6976", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fexternal%2Frowley_nichols_mol_cell_2017%2FPol2S2_HiChIP.hic": "145842743,6976", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fexternal%2Frowley_nichols_mol_cell_2017%2FArabidopsis_Wang2015_Liu2016.hic": "1134391078,4984", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fexternal%2Frowley_nichols_mol_cell_2017%2FElegans_Crane2015.hic": "387127568,8758", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fexternal%2Frowley_nichols_mol_cell_2017%2FNcrassa_Galazka2016.hic": "26555511,27725", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fexternal%2Frowley_nichols_mol_cell_2017%2FPfalciparum_trophozoite_Ay2014.hic": "15640893,13948", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fduan%2FE-Me-A.hic": "6897251,23348", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fduan%2FE-Me-B.hic": "4959088,23348", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fduan%2FE-Mp-A.hic": "5232286,23348", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fduan%2FE-Mp-B.hic": "5105292,23348", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fduan%2FH-Me-A.hic": "6900072,23348", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fduan%2FH-Me-B.hic": "8653258,23348", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fduan%2FH-Mp-A.hic": "7999058,23348", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fduan%2FH-Mp-B.hic": "8774657,23348", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fdekker%2F4dn%2Fh1hesc.hic": "23671753603,36479", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fdekker%2F4dn%2Fh1hesc_rep1.hic": "23671754721,36479", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fdekker%2F4dn%2Fh1hesc_rep2.hic": "22269909910,36479", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fdekker%2F4dn%2Fhffc6_rep1.hic": "19016661622,36479", - "hicfiles.s3.amazonaws.com%2Fexternal%2Flieberman_aiden_van_berkum%2FGM06990_NcoI.hic": "480725203,36479", - "hicfiles.s3.amazonaws.com%2Fexternal%2Flieberman_aiden_van_berkum%2F302NH.hic": "99948617,36479", - "hicfiles.s3.amazonaws.com%2Fexternal%2Flieberman_aiden_van_berkum%2FK562.hic": "470263605,36151", - "hicfiles.s3.amazonaws.com%2Fexternal%2Flieberman_aiden_van_berkum%2FGM06990_HindIII.hic": "293706559,36289", - "hicfiles.s3.amazonaws.com%2Fexternal%2Flieberman_aiden_van_berkum%2FGM06990_rep_HindIII.hic": "309673862,36087", - "hicfiles.s3.amazonaws.com%2Fexternal%2Frudan%2Fcanis-lupus-rep1.hic": "1531151371,56905", - "hicfiles.s3.amazonaws.com%2Fexternal%2Frudan%2Fcanis-lupus-rep2.hic": "2851437676,56905", - "hicfiles.s3.amazonaws.com%2Fexternal%2Frudan%2Fmouse-rep1.hic": "582052544,32102", - "hicfiles.s3.amazonaws.com%2Fexternal%2Frudan%2Fmacaque-rep1.hic": "698509182,32102", - "hicfiles.s3.amazonaws.com%2Fexternal%2Frudan%2Fmacaque-rep2.hic": "461410393,32102", - "hicfiles.s3.amazonaws.com%2Fexternal%2Frudan%2Frabbit-rep1.hic": "691045338,33561", - "hicfiles.s3.amazonaws.com%2Fexternal%2Frudan%2Frabbit-rep2.hic": "668888336,33561", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fsexton%2Fcombined.hic": "50650087,4486", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fkalhor%2Ftcc-hindiii.hic": "1071142023,16500", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fkalhor%2Ftcc-mboi.hic": "1508851093,16448", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fkalhor%2Fnon-tcc-hindiii.hic": "395179229,36093", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fkalhor%2Ftcc-combined.hic": "1050423847,36479", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fdixon%2Fmm9-hindiii%2Fsplit-read-run.hic": "9599984876,32102", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fdixon%2Fhesc-hindiii.hic": "1952555632,36479", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fdixon%2Fimr90-hindiii.hic": "9691260435,18679", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fdixon%2Fmm9-cortex.hic": "3712072953,32102", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fzhang%2Fatm-i-scei-chr18.hic": "2083350075,16438", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fzhang%2Fatm-i-scei-chr2.hic": "3362049644,16360", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fzhang%2Fatm-i-scei-chr7.hic": "1658399854,16438", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fzhang%2Fwt-i-scei-chr15.hic": "866691249,16438", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fzhang%2Fwt-i-scei-chr2.hic": "3304782795,16386", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fnagano%2Fcell-1.hic": "23673506,32102", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fnagano%2Fcell-2.hic": "26873280,30643", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fnagano%2Fcell-3.hic": "31066362,30643", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fnagano%2Fcell-4.hic": "16807724,30643", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fnagano%2Fcell-5.hic": "28665065,30643", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fnagano%2Fcell-6.hic": "13124158,30643", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fnagano%2Fcell-7.hic": "15118945,30643", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fnagano%2Fcell-8.hic": "68316814,32102", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fnagano%2Fcell-9.hic": "18965101,30643", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fnagano%2Fcell-10.hic": "17020666,30643", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fjin%2Fimr90%2Fcombined.hic": "6526601242,36427", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fjin%2Fimr90%2Frep1.hic": "1861562891,36401", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fjin%2Fimr90%2Frep2.hic": "3061013635,36479", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fjin%2Fimr90%2Frep3.hic": "1564588211,35969", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fjin%2Fimr90%2Frep4.hic": "1255543175,36153", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fjin%2Fimr90%2Frep5.hic": "974683253,36179", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fjin%2Fimr90%2Frep6.hic": "1040805629,36053", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fjin%2Fimr90-tnf-alpha%2Fcombined.hic": "8424080116,36401", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fjin%2Fimr90-tnf-alpha%2Frep1.hic": "2697976702,36295", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fjin%2Fimr90-tnf-alpha%2Frep3.hic": "1718610467,36159", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fjin%2Fimr90-tnf-alpha%2Frep4.hic": "2029519405,36101", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fjin%2Fimr90-tnf-alpha%2Frep5.hic": "985310855,36069", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fjin%2Fimr90-tnf-alpha%2Frep6.hic": "1418750480,35967", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fcheng%2Fmhh-call-4-cell-line.hic": "538380253,35351", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fcheng%2Fprimary-b-all.hic": "773764191,35793", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fcheng%2Fnormal-b-cell-line.hic": "336271459,35005", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fcheng%2Frl-cell-line.hic": "484807998,35351", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fhou%2Fkc167-biorep.hic": "135932435,8758", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fhou%2Fkc167-techrep1.hic": "160355961,8758", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fhou%2Fkc167-techrep2.hic": "188809887,8758", - "hicfiles.s3.amazonaws.com%2Fexternal%2Flin%2Fpre-prob-egs.hic": "2237792858,15483", - "hicfiles.s3.amazonaws.com%2Fexternal%2Flin%2Fprob-egs.hic": "5744720377,16438", - "hicfiles.s3.amazonaws.com%2Fexternal%2Flin%2Fprob-fa.hic": "2174866215,16438", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fli%2Fhct116-rnapii-pilot.hic": "396366166,35999", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fli%2Fhela-rnapii-pilot.hic": "882516759,35107", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fli%2Fk562-rnapii-pilot.hic": "1131576189,35969", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fli%2Fk562-rnapii-saturated.hic": "571583828,36291", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fli%2Fmcf7-rnapii-saturated.hic": "1282547841,36035", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fli%2Fnb4-rnapii-pilot.hic": "761614686,34861", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fjung%2Fmouse_sperm.hic": "1730231642,29184", - "hicfiles.s3.amazonaws.com%2Fexternal%2Ftang%2Fgm12878.hic": "1953518212,20505", - "hicfiles.s3.amazonaws.com%2Fexternal%2Frutledge%2FSRR1791299.hic": "5723484,11956", - "hicfiles.s3.amazonaws.com%2Fexternal%2Frutledge%2FSRR1791297.hic": "16534743,23348", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fzuin%2Fhek293t-rad21cv-hrv.hic": "5094525579,36289", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fzuin%2Fhek293t-rad21cv-hrv-rep1.hic": "2574358912,36373", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fzuin%2Fhek293t-rad21cv-hrv-rep2.hic": "3417099433,36243", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fzuin%2Fhek293t-rad21cv-tev.hic": "4785157552,36323", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fzuin%2Fhek293t-rad21cv-tev-rep1.hic": "2648268465,36321", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fzuin%2Fhek293t-rad21cv-tev-rep2.hic": "2994727980,36107", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fzuin%2Fhek293t-sirna-ctcf.hic": "5391791815,36063", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fzuin%2Fhek293t-sirna-ctcf-rep1.hic": "3325842095,36269", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fzuin%2Fhek293t-sirna-ctcf-rep2.hic": "3096215920,36167", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fzuin%2Fhek293t-sirna-ctrl.hic": "3830902383,36167", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fzuin%2Fhek293t-sirna-ctrl-rep1.hic": "1346712252,36079", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fzuin%2Fhek293t-sirna-ctrl_rep2.hic": "3098067367,36271", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fay%2Fp-falciparum-3d7-0h-hiseq.hic": "38174042,21889", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fay%2Fp-falciparum-3d7-18h-hiseq.hic": "26506099,21889", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fay%2Fp-falciparum-3d7-18h-hiseq-non-crosslinked_control.hic": "3545496,21889", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fay%2Fp-falciparum-3d7-36h-hiseq.hic": "70754194,21889", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fnaumova%2Fhelas3%2Fg1mid-r1.hic": "200863476,17185", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fnaumova%2Fhelas3%2Fm-r1.hic": "249021190,17185", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fnaumova%2Fhelas3%2Fm-r2.hic": "212341157,17185", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fnaumova%2Fhelas3ccl2p2%2Fg1-0-25fa.hic": "583572265,17185", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fnaumova%2Fhelas3ccl2p2%2Fg1-1fa.hic": "354502306,17185", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fnaumova%2Fhelas3ccl2p2%2Fm-0-25fa.hic": "149308791,17185", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fnaumova%2Fhelas3ccl2p2%2Fm-98percent.hic": "778175225,17185", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fnaumova%2Fhelas3ccl2p2%2Fm-1fa.hic": "158091047,17185", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fnaumova%2Fhff1%2Fcchic-hff1-ns-r1.hic": "801670039,17185", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fnaumova%2Fhff1%2Fcchic-hff1-m-r1.hic": "875922086,17185", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fnaumova%2Fk562%2Fm-r1.hic": "130959943,17185", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fnaumova%2Fk562%2Fm-r2.hic": "237861106,17185", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fsofueva%2FmAST-WT.hic": "496104039,30643", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fsofueva%2FmAST-WT-adv-cre.hic": "438608517,30643", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fsofueva%2FmAST-floxed-rep1.hic": "446205712,32102", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fsofueva%2FmAST-floxed-rep2.hic": "386354767,32102", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fsofueva%2FmAST-deleted-rep1.hic": "621998722,30643", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fsofueva%2FmAST-deleted-rep2.hic": "583840829,32102", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fsofueva%2FmNSC-floxed-rep1.hic": "801290988,30643", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fsofueva%2FmNSC-floxed-rep2.hic": "819406658,30643", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fsofueva%2FmNSC-deleted-rep1.hic": "792825269,32102", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fsofueva%2FmNSC-deleted-rep2.hic": "746189884,30643", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fsofueva%2FmNSC-WT.hic": "309353372,30643", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fsofueva%2FmNSC-WT-OHT.hic": "274229679,30643", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fseitan%2FTcell-Rad21KO-R1.hic": "1490362251,32102", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fseitan%2FTcell-Rad21KO-R3.hic": "2403664421,32102", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fseitan%2FTcell-Rad21WT-R1.hic": "1377124538,32102", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fseitan%2FTcell-Rad21WT-R3.hic": "2646201369,32102", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fmoissiard%2Fcrh6-mutant.hic": "105261071,10217", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fmoissiard%2FWT.hic": "127506388,10217", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fgrob%2FCol.hic": "153638500,10217", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fgrob%2Fcrwn1.hic": "211213220,10217", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fgrob%2Fcrwn4.hic": "134236837,10217", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fxie%2Fprimary.hic": "92936173,10217", - "hicfiles.s3.amazonaws.com%2Fexternal%2Ffeng%2F6wt-control6wt337.hic": "318737891,10217", - "hicfiles.s3.amazonaws.com%2Fexternal%2Ffeng%2F6wt-control6wt67.hic": "348123956,10217", - "hicfiles.s3.amazonaws.com%2Fexternal%2Ffeng%2F6wt337.hic": "251107279,10217", - "hicfiles.s3.amazonaws.com%2Fexternal%2Ffeng%2F6wt67.hic": "351840994,10217", - "hicfiles.s3.amazonaws.com%2Fexternal%2Ffeng%2FCol0.hic": "345969497,10217", - "hicfiles.s3.amazonaws.com%2Fexternal%2Ffeng%2Fclf28-swn7.hic": "299585025,10217", - "hicfiles.s3.amazonaws.com%2Fexternal%2Ffeng%2Fcmt3-11.hic": "253427706,10217", - "hicfiles.s3.amazonaws.com%2Fexternal%2Ffeng%2Fddm1-2.hic": "303626924,10217", - "hicfiles.s3.amazonaws.com%2Fexternal%2Ffeng%2Fmet1-3.hic": "347697973,10217", - "hicfiles.s3.amazonaws.com%2Fexternal%2Ffeng%2Fsuvh4-suvh5-suvh6.hic": "263122019,10217", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fma%2FDNase-HiC-WG-K562.hic": "892955840,18679", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fma%2FDNaseHiC-WG-H1.hic": "696922695,18679", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fma%2FtargetedDNaseHiC-lincRNA-K562-rep1.hic": "341917716,18679", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fma%2FtargeredDNaseHiC-lincRNA-K562-rep2.hic": "214841185,18679", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fma%2FtargetedDNaseHiC-lincRNA-H1-rep1.hic": "616326137,18679", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fma%2FtargetedDNaseHiC-lincRNA-H1-rep2.hic": "579654013,18679", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fma%2FtargetedDNaseHiC-pe-H1-rep1.hic": "519810544,18679", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fma%2FtargetedDNaseHiC-pe-K562-rep1.hic": "199553123,18679", - "hicfiles.s3.amazonaws.com%2Fexternal%2Frowley%2FKc167_DpnII.hic": "1319373594,6976", - "hicfiles.s3.amazonaws.com%2Fexternal%2Frowley%2FKc167_HinfI.hic": "1465493873,6976", - "hicfiles.s3.amazonaws.com%2Fexternal%2Frowley%2FKc167_DpnII_HinfI_combo.hic": "753062558,5814", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fbarutcu%2FMCF-10A.hic": "2784956115,36479", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fbarutcu%2FMCF-7.hic": "2700457411,36479", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fbatullin%2Fsperm.hic": "501052169,32102", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fminajigi%2FWT_hiC_rep1.hic": "1450697530,32102", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fminajigi%2FWT_hiC_rep2.hic": "1189371558,32102", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fminajigi%2Fcombined.hic": "2262007875,32102", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fminajigi%2Finactive.hic": "4444564,751", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fminajigi%2Factive.hic": "3993495,751", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fdeng%2Fpatski_rep1.hic": "1650838357,32102", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fdeng%2Fpatski_rep2.hic": "1258038606,32102", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fdeng%2Fpatski.hic": "499827296,16438", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fdeng%2Fpatski_active.hic": "79175714,15691", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fdeng%2Fpatski_inactive.hic": "98947881,15691", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fdeng%2Fbrain_dnase.hic": "4298088401,32102", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fdeng%2Fbrain_in_situ_dnase.hic": "609321852,32102", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fdeng%2Fbrain.hic": "1028196506,16438", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fdeng%2Fbrain_active.hic": "79175714,15691", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fdeng%2Fbrain_inactive.hic": "98947881,15691", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fle%2FBglII_rep1.hic": "1283306,1463", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fle%2FBglII_rep2.hic": "1263227,1463", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fle%2FNcoI_rep1.hic": "4380906,1463", - "hicfiles.s3.amazonaws.com%2Fexternal%2Feagen%2FGSE89112_Kc167combined.hic": "1829549643,25624", - "hicfiles.s3.amazonaws.com%2Fexternal%2Feagen%2FGSE89112_Kc167combined_randomized.hic": "1859742654,25624", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fmumbach%2FGSE80820_HiChIP_GM_cohesin.hic": "1231264781,17932", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fmumbach%2FGSE80820_HiChIP_mES_cohesin_all.hic": "1152008628,16438", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fmumbach%2FGSE80820_HiChIP_mES_Oct4.hic": "912828146,16438", - "s3.amazonaws.com%2Fhicfiles%2Fexternal%2Fwapl_hic%2FSCC4KO.hic": "1767906138,18679", - "s3.amazonaws.com%2Fhicfiles%2Fexternal%2Fwapl_hic%2FDKO.hic": "1487228787,18679", - "s3.amazonaws.com%2Fhicfiles%2Fexternal%2Fwapl_hic%2FWaplKO_1.14.hic": "1189751862,18679", - "s3.amazonaws.com%2Fhicfiles%2Fexternal%2Fwapl_hic%2FWaplKO_3.3.hic": "1155057696,18679", - "s3.amazonaws.com%2Fhicfiles%2Fexternal%2Fwapl_hic%2FWT.hic": "1522401568,18679", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fskfuwi4fnsjkdf9jekrw2%2Fmega_Liverpool%2Fmega.hic": "2612171975,4381", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fskfuwi4fnsjkdf9jekrw2%2FHIC2836_Liverpool1%2FLiverpool1.hic": "191729195,2245", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fskfuwi4fnsjkdf9jekrw2%2FHIC2861_Liverpool2%2FLiverpool2.hic": "1637096030,4381", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fskfuwi4fnsjkdf9jekrw2%2FHIC2862_Liverpool3%2FLiverpool3.hic": "1160045602,4381", - "s3.amazonaws.com%2Fhicfiles%2Fexternal%2Fgoodell%2FHSPC.hic": "11857786247,36479", - "s3.amazonaws.com%2Fhicfiles%2Fexternal%2Fgoodell%2FHSPC_CanyonDel.hic": "8139168836,36479", - "s3.amazonaws.com%2Fhicfiles%2Fexternal%2Fgoodell%2Ftcell.hic": "9871547081,36479", - "s3.amazonaws.com%2Fhicfiles%2Fexternal%2Fgoodell%2Fep.hic": "17479335373,36479", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fnagano%2FTh1_ensemble.hic": "1690592868,32102", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fbonev%2FES_mapq30.hic": "32930498831,32386", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fbonev%2FNPC_mapq30.hic": "55053730986,32386", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fbonev%2FCN_mapq30.hic": "53138031154,32386", - "hicfiles.s3.amazonaws.com%2Fhiseq%2FKieffer-Kwon_et_al_2017%2FMain_maps%2FKieffer-Kwon-2017-activated_B_cells_72_hours_WT.hic": "16492991184,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2FKieffer-Kwon_et_al_2017%2FMain_maps%2FKieffer-Kwon-2017-resting_B_cells_WT.hic": "23057795398,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2FKieffer-Kwon_et_al_2017%2FMain_maps%2FKieffer-Kwon-2017-activated_B_cells_24_hours_MYC_KO.hic": "21245554876,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2FKieffer-Kwon_et_al_2017%2FMain_maps%2FKieffer-Kwon-2017-resting_B_cells_TSA.hic": "13933346059,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2FKieffer-Kwon_et_al_2017%2FMain_maps%2FKieffer-Kwon-2017-activated_B_cells_24_hours_oligomycin.hic": "21902506832,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2FKieffer-Kwon_et_al_2017%2FMain_maps%2FKieffer-Kwon-2017-mES_WT.hic": "9451969795,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2FVian_et_al_2018%2FMain_maps%2FVian-2018-activated_B_cells_24_hours_WT.hic": "3600188564,16438", - "hicfiles.s3.amazonaws.com%2Fhiseq%2FVian_et_al_2018%2FMain_maps%2FVian-2018-activated_B_cells_30_hours_WT.hic": "1309503359,16438", - "hicfiles.s3.amazonaws.com%2Fhiseq%2FVian_et_al_2018%2FMain_maps%2FVian-2018-activated_B_cells_30_hours_HU_treated.hic": "1477252396,16438", - "hicfiles.s3.amazonaws.com%2Fhiseq%2FVian_et_al_2018%2FMain_maps%2FVian-2018-activated_B_cells_24_hours_flavopiridol.hic": "15711773490,32102", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fpgp%2FPGP1F_mega_090118%2FPGP1F_mega_090118_30.hic": "24786676166,36479", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fpgp%2FHIC7145%2FHIC7145_30.hic": "4554644616,36479", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fpgp%2FHIC7146%2FHIC7146_30.hic": "4174848944,36479", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fpgp%2FHIC7147%2FHIC7147_30.hic": "5062229182,36479", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fpgp%2FHIC7862%2FHIC7862_30.hic": "4520990620,36479", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fpgp%2FHIC7863%2FHIC7863_30.hic": "4330354773,36479", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fpgp%2FHIC7864%2FHIC7864_30.hic": "5880640268,36479", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fpgp%2FHIC7865%2FHIC7865_30.hic": "4431632469,36479", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fpgp%2FHIC7866%2FHIC7866_30.hic": "4686000222,36479", - "encode-public.s3.amazonaws.com%2F2018%2F10%2F19%2Fb122542b-306c-4631-bdc3-2e155e89af55%2FENCFF718AWL.hic": "39544267907,58932", - "encode-public.s3.amazonaws.com%2F2019%2F02%2F15%2F8e787cd8-e388-4bc2-a236-7a5e6f39e0c0%2FENCFF999YXX.hic": "9255069996,56883", - "encode-public.s3.amazonaws.com%2F2019%2F02%2F08%2Ffc1d9d5d-8fa0-4e29-9080-3da674d9490d%2FENCFF543USQ.hic": "5005263062,36479", - "s3.us-east-1.wasabisys.com%2Fhicfiles%2Finternal%2FLCL_mega_42B_500bp_30.hic": "106482584851,22829", - "www.encodeproject.org%2Ffiles%2FENCFF925QIF%2F%40%40download%2FENCFF925QIF.hic": "51712684396,54779", - "www.encodeproject.org%2Ffiles%2FENCFF259YUS%2F%40%40download%2FENCFF259YUS.hic": "24640030444,54779", - "www.encodeproject.org%2Ffiles%2FENCFF783KQI%2F%40%40download%2FENCFF783KQI.hic": "27209249856,54779", - "www.encodeproject.org%2Ffiles%2FENCFF318JAP%2F%40%40download%2FENCFF318JAP.hic": "28636979242,54779", - "www.encodeproject.org%2Ffiles%2FENCFF512PQA%2F%40%40download%2FENCFF512PQA.hic": "28124104361,54779", - "www.encodeproject.org%2Ffiles%2FENCFF591MHA%2F%40%40download%2FENCFF591MHA.hic": "37373387202,54779", - "www.encodeproject.org%2Ffiles%2FENCFF197OWW%2F%40%40download%2FENCFF197OWW.hic": "41826180893,54779", - "www.encodeproject.org%2Ffiles%2FENCFF317OIA%2F%40%40download%2FENCFF317OIA.hic": "34741636038,54779", - "www.encodeproject.org%2Ffiles%2FENCFF522YLZ%2F%40%40download%2FENCFF522YLZ.hic": "24064692329,54779", - "www.encodeproject.org%2Ffiles%2FENCFF420JTA%2F%40%40download%2FENCFF420JTA.hic": "21202405177,54779", - "www.encodeproject.org%2Ffiles%2FENCFF871ZDJ%2F%40%40download%2FENCFF871ZDJ.hic": "10124815680,18679", - "www.encodeproject.org%2Ffiles%2FENCFF349RZY%2F%40%40download%2FENCFF349RZY.hic": "4446702705,36479", - "www.encodeproject.org%2Ffiles%2FENCFF738YON%2F%40%40download%2FENCFF738YON.hic": "3338049584,35947", - "www.encodeproject.org%2Ffiles%2FENCFF406KJN%2F%40%40download%2FENCFF406KJN.hic": "4132875306,36479", - "www.encodeproject.org%2Ffiles%2FENCFF081NPN%2F%40%40download%2FENCFF081NPN.hic": "34495587443,54779", - "www.encodeproject.org%2Ffiles%2FENCFF946RZW%2F%40%40download%2FENCFF946RZW.hic": "34571955193,54779", - "www.encodeproject.org%2Ffiles%2FENCFF602CHT%2F%40%40download%2FENCFF602CHT.hic": "30674798032,54779", - "www.encodeproject.org%2Ffiles%2FENCFF150DKS%2F%40%40download%2FENCFF150DKS.hic": "12618769864,36479", - "www.encodeproject.org%2Ffiles%2FENCFF614IPZ%2F%40%40download%2FENCFF614IPZ.hic": "42450060331,54779", - "www.encodeproject.org%2Ffiles%2FENCFF571ZQR%2F%40%40download%2FENCFF571ZQR.hic": "15230068871,47429", - "www.encodeproject.org%2Ffiles%2FENCFF705MKK%2F%40%40download%2FENCFF705MKK.hic": "38686554702,54779", - "www.encodeproject.org%2Ffiles%2FENCFF658KTB%2F%40%40download%2FENCFF658KTB.hic": "13195884405,47429", - "www.encodeproject.org%2Ffiles%2FENCFF435JYN%2F%40%40download%2FENCFF435JYN.hic": "17192139674,54779", - "www.encodeproject.org%2Ffiles%2FENCFF016JKX%2F%40%40download%2FENCFF016JKX.hic": "37266736642,54779", - "www.encodeproject.org%2Ffiles%2FENCFF294GFP%2F%40%40download%2FENCFF294GFP.hic": "36389843399,54779", - "www.encodeproject.org%2Ffiles%2FENCFF700CYI%2F%40%40download%2FENCFF700CYI.hic": "60482012152,54779", - "www.encodeproject.org%2Ffiles%2FENCFF962EDB%2F%40%40download%2FENCFF962EDB.hic": "39394328182,54779", - "www.encodeproject.org%2Ffiles%2FENCFF467OGP%2F%40%40download%2FENCFF467OGP.hic": "35572788855,54779", - "www.encodeproject.org%2Ffiles%2FENCFF556RLR%2F%40%40download%2FENCFF556RLR.hic": "34826921187,54779", - "www.encodeproject.org%2Ffiles%2FENCFF309UNV%2F%40%40download%2FENCFF309UNV.hic": "48510618174,54779", - "www.encodeproject.org%2Ffiles%2FENCFF653HCO%2F%40%40download%2FENCFF653HCO.hic": "41079007620,54779", - "www.encodeproject.org%2Ffiles%2FENCFF120DSV%2F%40%40download%2FENCFF120DSV.hic": "12790195576,47429", - "www.encodeproject.org%2Ffiles%2FENCFF284OEA%2F%40%40download%2FENCFF284OEA.hic": "46007570339,54779", - "www.encodeproject.org%2Ffiles%2FENCFF035BLF%2F%40%40download%2FENCFF035BLF.hic": "63868871985,54779", - "www.encodeproject.org%2Ffiles%2FENCFF094KKX%2F%40%40download%2FENCFF094KKX.hic": "42151419971,54779", - "www.encodeproject.org%2Ffiles%2FENCFF965BPU%2F%40%40download%2FENCFF965BPU.hic": "42717376107,54779", - "www.encodeproject.org%2Ffiles%2FENCFF842DUO%2F%40%40download%2FENCFF842DUO.hic": "39553892515,54779", - "www.encodeproject.org%2Ffiles%2FENCFF417GBZ%2F%40%40download%2FENCFF417GBZ.hic": "45544785452,54779", - "www.encodeproject.org%2Ffiles%2FENCFF499BVX%2F%40%40download%2FENCFF499BVX.hic": "40900674170,54779", - "www.encodeproject.org%2Ffiles%2FENCFF136XCV%2F%40%40download%2FENCFF136XCV.hic": "47700392974,54779", - "www.encodeproject.org%2Ffiles%2FENCFF224HKR%2F%40%40download%2FENCFF224HKR.hic": "40426005932,54779", - "www.encodeproject.org%2Ffiles%2FENCFF711XSR%2F%40%40download%2FENCFF711XSR.hic": "41434581949,54779", - "www.encodeproject.org%2Ffiles%2FENCFF660JWA%2F%40%40download%2FENCFF660JWA.hic": "54201632697,54779", - "www.encodeproject.org%2Ffiles%2FENCFF081PMO%2F%40%40download%2FENCFF081PMO.hic": "53428285130,54779", - "www.encodeproject.org%2Ffiles%2FENCFF799QGA%2F%40%40download%2FENCFF799QGA.hic": "1228682189,36479", - "www.encodeproject.org%2Ffiles%2FENCFF473CAA%2F%40%40download%2FENCFF473CAA.hic": "1077514950,36479", - "www.encodeproject.org%2Ffiles%2FENCFF663FRL%2F%40%40download%2FENCFF663FRL.hic": "39843938245,54779", - "www.encodeproject.org%2Ffiles%2FENCFF341WOY%2F%40%40download%2FENCFF341WOY.hic": "34792598619,54779", - "www.encodeproject.org%2Ffiles%2FENCFF515ZBF%2F%40%40download%2FENCFF515ZBF.hic": "41779230923,54779", - "www.encodeproject.org%2Ffiles%2FENCFF545GBW%2F%40%40download%2FENCFF545GBW.hic": "38351980358,54779", - "www.encodeproject.org%2Ffiles%2FENCFF252ANV%2F%40%40download%2FENCFF252ANV.hic": "37668839771,54779", - "www.encodeproject.org%2Ffiles%2FENCFF912NDK%2F%40%40download%2FENCFF912NDK.hic": "21196851956,54779", - "www.encodeproject.org%2Ffiles%2FENCFF683PLM%2F%40%40download%2FENCFF683PLM.hic": "21849338763,54779", - "www.encodeproject.org%2Ffiles%2FENCFF355NFJ%2F%40%40download%2FENCFF355NFJ.hic": "47880627268,54779", - "www.encodeproject.org%2Ffiles%2FENCFF507WEW%2F%40%40download%2FENCFF507WEW.hic": "35777782924,54779", - "www.encodeproject.org%2Ffiles%2FENCFF241MSL%2F%40%40download%2FENCFF241MSL.hic": "22507408288,54779", - "www.encodeproject.org%2Ffiles%2FENCFF135MUT%2F%40%40download%2FENCFF135MUT.hic": "24168734040,54779", - "www.encodeproject.org%2Ffiles%2FENCFF459FRB%2F%40%40download%2FENCFF459FRB.hic": "37166770103,54779", - "www.encodeproject.org%2Ffiles%2FENCFF705YZH%2F%40%40download%2FENCFF705YZH.hic": "44679182442,54779", - "www.encodeproject.org%2Ffiles%2FENCFF395INO%2F%40%40download%2FENCFF395INO.hic": "56727346538,54779", - "www.encodeproject.org%2Ffiles%2FENCFF736ITL%2F%40%40download%2FENCFF736ITL.hic": "49036286185,54779", - "www.encodeproject.org%2Ffiles%2FENCFF546TZN%2F%40%40download%2FENCFF546TZN.hic": "33195126348,54779", - "www.encodeproject.org%2Ffiles%2FENCFF706SFK%2F%40%40download%2FENCFF706SFK.hic": "3271831702,36479", - "www.encodeproject.org%2Ffiles%2FENCFF922ERE%2F%40%40download%2FENCFF922ERE.hic": "12476647122,36479", - "www.encodeproject.org%2Ffiles%2FENCFF876OWE%2F%40%40download%2FENCFF876OWE.hic": "1538692704,47429", - "www.encodeproject.org%2Ffiles%2FENCFF227XJZ%2F%40%40download%2FENCFF227XJZ.hic": "1925617685,36479", - "www.encodeproject.org%2Ffiles%2FENCFF053BXY%2F%40%40download%2FENCFF053BXY.hic": "1032237652,36479", - "www.encodeproject.org%2Ffiles%2FENCFF014VMM%2F%40%40download%2FENCFF014VMM.hic": "1564021703,36479", - "www.encodeproject.org%2Ffiles%2FENCFF563XES%2F%40%40download%2FENCFF563XES.hic": "1489180508,36479", - "www.encodeproject.org%2Ffiles%2FENCFF482LGO%2F%40%40download%2FENCFF482LGO.hic": "1208778887,36479", - "www.encodeproject.org%2Ffiles%2FENCFF216QQM%2F%40%40download%2FENCFF216QQM.hic": "6293163571,47429", - "www.encodeproject.org%2Ffiles%2FENCFF256UOW%2F%40%40download%2FENCFF256UOW.hic": "6293163571,47429", - "www.encodeproject.org%2Ffiles%2FENCFF791UZC%2F%40%40download%2FENCFF791UZC.hic": "37029615181,54779", - "www.encodeproject.org%2Ffiles%2FENCFF911AHQ%2F%40%40download%2FENCFF911AHQ.hic": "34246649165,54779", - "www.encodeproject.org%2Ffiles%2FENCFF491AOR%2F%40%40download%2FENCFF491AOR.hic": "558663570,36479", - "www.encodeproject.org%2Ffiles%2FENCFF307PDL%2F%40%40download%2FENCFF307PDL.hic": "525321519,36479", - "www.encodeproject.org%2Ffiles%2FENCFF773ITV%2F%40%40download%2FENCFF773ITV.hic": "295464771,36479", - "www.encodeproject.org%2Ffiles%2FENCFF198SSL%2F%40%40download%2FENCFF198SSL.hic": "500142476,36479", - "www.encodeproject.org%2Ffiles%2FENCFF251UEF%2F%40%40download%2FENCFF251UEF.hic": "567443575,36479", - "www.encodeproject.org%2Ffiles%2FENCFF942LTN%2F%40%40download%2FENCFF942LTN.hic": "4430960222,36479", - "www.encodeproject.org%2Ffiles%2FENCFF543USQ%2F%40%40download%2FENCFF543USQ.hic": "5005263062,36479", - "www.encodeproject.org%2Ffiles%2FENCFF434XQU%2F%40%40download%2FENCFF434XQU.hic": "25506511674,54779", - "www.encodeproject.org%2Ffiles%2FENCFF318GOM%2F%40%40download%2FENCFF318GOM.hic": "44750824314,54779", - "www.encodeproject.org%2Ffiles%2FENCFF004TKY%2F%40%40download%2FENCFF004TKY.hic": "20705661833,54779", - "www.encodeproject.org%2Ffiles%2FENCFF493YNC%2F%40%40download%2FENCFF493YNC.hic": "53407154984,54779", - "www.encodeproject.org%2Ffiles%2FENCFF334XXU%2F%40%40download%2FENCFF334XXU.hic": "14341194962,47429", - "www.encodeproject.org%2Ffiles%2FENCFF569RJM%2F%40%40download%2FENCFF569RJM.hic": "1922066634,36479", - "www.encodeproject.org%2Ffiles%2FENCFF076LWH%2F%40%40download%2FENCFF076LWH.hic": "39406255845,54779", - "www.encodeproject.org%2Ffiles%2FENCFF977XWK%2F%40%40download%2FENCFF977XWK.hic": "20563512962,54779", - "www.encodeproject.org%2Ffiles%2FENCFF127TPS%2F%40%40download%2FENCFF127TPS.hic": "21032070512,54779", - "www.encodeproject.org%2Ffiles%2FENCFF480KLP%2F%40%40download%2FENCFF480KLP.hic": "33115569647,54779", - "www.encodeproject.org%2Ffiles%2FENCFF281ILS%2F%40%40download%2FENCFF281ILS.hic": "28236353584,54779", - "www.encodeproject.org%2Ffiles%2FENCFF129LMU%2F%40%40download%2FENCFF129LMU.hic": "35247096013,54779", - "www.encodeproject.org%2Ffiles%2FENCFF759YCW%2F%40%40download%2FENCFF759YCW.hic": "16058537743,32102", - "www.encodeproject.org%2Ffiles%2FENCFF045YOM%2F%40%40download%2FENCFF045YOM.hic": "19775445828,32102", - "www.encodeproject.org%2Ffiles%2FENCFF013TGD%2F%40%40download%2FENCFF013TGD.hic": "4208420532,36479", - "www.encodeproject.org%2Ffiles%2FENCFF929RPW%2F%40%40download%2FENCFF929RPW.hic": "1974260276,36479", - "www.encodeproject.org%2Ffiles%2FENCFF996XEO%2F%40%40download%2FENCFF996XEO.hic": "2072918865,36479", - "www.encodeproject.org%2Ffiles%2FENCFF097SKJ%2F%40%40download%2FENCFF097SKJ.hic": "1983524001,36479", - "www.encodeproject.org%2Ffiles%2FENCFF464KRA%2F%40%40download%2FENCFF464KRA.hic": "1957300131,36479", - "www.encodeproject.org%2Ffiles%2FENCFF406HHC%2F%40%40download%2FENCFF406HHC.hic": "3854527235,36479", - "www.encodeproject.org%2Ffiles%2FENCFF080DPJ%2F%40%40download%2FENCFF080DPJ.hic": "19953768024,47429", - "www.encodeproject.org%2Ffiles%2FENCFF621AIY%2F%40%40download%2FENCFF621AIY.hic": "26781700010,54779", - "www.encodeproject.org%2Ffiles%2FENCFF366ERB%2F%40%40download%2FENCFF366ERB.hic": "1049184239,36479", - "www.encodeproject.org%2Ffiles%2FENCFF997RGL%2F%40%40download%2FENCFF997RGL.hic": "2521167549,36479", - "www.encodeproject.org%2Ffiles%2FENCFF029MPB%2F%40%40download%2FENCFF029MPB.hic": "1854711185,36479", - "www.encodeproject.org%2Ffiles%2FENCFF043EEE%2F%40%40download%2FENCFF043EEE.hic": "2924133032,36479", - "www.encodeproject.org%2Ffiles%2FENCFF920CJR%2F%40%40download%2FENCFF920CJR.hic": "3011577886,36479", - "www.encodeproject.org%2Ffiles%2FENCFF928NJV%2F%40%40download%2FENCFF928NJV.hic": "2778936244,36479", - "www.encodeproject.org%2Ffiles%2FENCFF894GLR%2F%40%40download%2FENCFF894GLR.hic": "2831733099,36479", - "www.encodeproject.org%2Ffiles%2FENCFF303PCK%2F%40%40download%2FENCFF303PCK.hic": "688704435,36479", - "www.encodeproject.org%2Ffiles%2FENCFF999YXX%2F%40%40download%2FENCFF999YXX.hic": "9255069996,56883", - "www.encodeproject.org%2Ffiles%2FENCFF685BLG%2F%40%40download%2FENCFF685BLG.hic": "16797022992,47429", - "www.encodeproject.org%2Ffiles%2FENCFF188SSH%2F%40%40download%2FENCFF188SSH.hic": "16797023050,47429", - "www.encodeproject.org%2Ffiles%2FENCFF465ESX%2F%40%40download%2FENCFF465ESX.hic": "13489465953,32102", - "www.encodeproject.org%2Ffiles%2FENCFF493SFI%2F%40%40download%2FENCFF493SFI.hic": "30033046818,54779", - "www.encodeproject.org%2Ffiles%2FENCFF235LCO%2F%40%40download%2FENCFF235LCO.hic": "38572174589,54779", - "www.encodeproject.org%2Ffiles%2FENCFF625VNK%2F%40%40download%2FENCFF625VNK.hic": "45202258438,54779", - "www.encodeproject.org%2Ffiles%2FENCFF304HMS%2F%40%40download%2FENCFF304HMS.hic": "36994445315,54779", - "www.encodeproject.org%2Ffiles%2FENCFF605CEN%2F%40%40download%2FENCFF605CEN.hic": "40358346301,54779", - "www.encodeproject.org%2Ffiles%2FENCFF086ORS%2F%40%40download%2FENCFF086ORS.hic": "22650781304,54779", - "www.encodeproject.org%2Ffiles%2FENCFF237UKR%2F%40%40download%2FENCFF237UKR.hic": "41516707246,54779", - "www.encodeproject.org%2Ffiles%2FENCFF004YZQ%2F%40%40download%2FENCFF004YZQ.hic": "71900665326,54779", - "www.encodeproject.org%2Ffiles%2FENCFF104THR%2F%40%40download%2FENCFF104THR.hic": "15172410632,54779", - "www.encodeproject.org%2Ffiles%2FENCFF807IRK%2F%40%40download%2FENCFF807IRK.hic": "17346637451,54779", - "www.encodeproject.org%2Ffiles%2FENCFF193CQL%2F%40%40download%2FENCFF193CQL.hic": "55726903245,54779", - "www.encodeproject.org%2Ffiles%2FENCFF700DEX%2F%40%40download%2FENCFF700DEX.hic": "20231399798,54779", - "www.encodeproject.org%2Ffiles%2FENCFF234MDO%2F%40%40download%2FENCFF234MDO.hic": "24635312640,54779", - "www.encodeproject.org%2Ffiles%2FENCFF181ROW%2F%40%40download%2FENCFF181ROW.hic": "26883606497,54779", - "www.encodeproject.org%2Ffiles%2FENCFF896OFN%2F%40%40download%2FENCFF896OFN.hic": "36952196833,54779", - "www.encodeproject.org%2Ffiles%2FENCFF573OPJ%2F%40%40download%2FENCFF573OPJ.hic": "36685546919,54779", - "www.encodeproject.org%2Ffiles%2FENCFF028RXH%2F%40%40download%2FENCFF028RXH.hic": "31053919206,54779", - "www.encodeproject.org%2Ffiles%2FENCFF156GGD%2F%40%40download%2FENCFF156GGD.hic": "35284134289,54779", - "www.encodeproject.org%2Ffiles%2FENCFF496GEU%2F%40%40download%2FENCFF496GEU.hic": "44659660933,54779", - "www.encodeproject.org%2Ffiles%2FENCFF945TUH%2F%40%40download%2FENCFF945TUH.hic": "3898570191,35639", - "www.encodeproject.org%2Ffiles%2FENCFF698KFV%2F%40%40download%2FENCFF698KFV.hic": "4427896684,35751", - "www.encodeproject.org%2Ffiles%2FENCFF239BHZ%2F%40%40download%2FENCFF239BHZ.hic": "1718552021,36479", - "www.encodeproject.org%2Ffiles%2FENCFF277LAN%2F%40%40download%2FENCFF277LAN.hic": "4542391336,36479", - "www.encodeproject.org%2Ffiles%2FENCFF397CMD%2F%40%40download%2FENCFF397CMD.hic": "2832016430,36479", - "www.encodeproject.org%2Ffiles%2FENCFF778OYA%2F%40%40download%2FENCFF778OYA.hic": "14067187484,47429", - "www.encodeproject.org%2Ffiles%2FENCFF775VSU%2F%40%40download%2FENCFF775VSU.hic": "14067187484,47429", - "www.encodeproject.org%2Ffiles%2FENCFF812THZ%2F%40%40download%2FENCFF812THZ.hic": "9667720429,36479", - "www.encodeproject.org%2Ffiles%2FENCFF777KBU%2F%40%40download%2FENCFF777KBU.hic": "5058284320,36479", - "www.encodeproject.org%2Ffiles%2FENCFF688KOY%2F%40%40download%2FENCFF688KOY.hic": "4198695833,36479", - "www.encodeproject.org%2Ffiles%2FENCFF223UBX%2F%40%40download%2FENCFF223UBX.hic": "1206064037,36479", - "www.encodeproject.org%2Ffiles%2FENCFF273XBU%2F%40%40download%2FENCFF273XBU.hic": "44085607579,54779", - "www.encodeproject.org%2Ffiles%2FENCFF952JZV%2F%40%40download%2FENCFF952JZV.hic": "44728845246,54779", - "www.encodeproject.org%2Ffiles%2FENCFF643NDM%2F%40%40download%2FENCFF643NDM.hic": "35877886780,54779", - "www.encodeproject.org%2Ffiles%2FENCFF586MQY%2F%40%40download%2FENCFF586MQY.hic": "71158037547,54779", - "www.encodeproject.org%2Ffiles%2FENCFF251VFA%2F%40%40download%2FENCFF251VFA.hic": "40089479399,54779", - "www.encodeproject.org%2Ffiles%2FENCFF033WGK%2F%40%40download%2FENCFF033WGK.hic": "30802023728,54779", - "www.encodeproject.org%2Ffiles%2FENCFF649OHR%2F%40%40download%2FENCFF649OHR.hic": "28203184265,54779", - "www.encodeproject.org%2Ffiles%2FENCFF782WVZ%2F%40%40download%2FENCFF782WVZ.hic": "37248221674,54779", - "www.encodeproject.org%2Ffiles%2FENCFF579CAR%2F%40%40download%2FENCFF579CAR.hic": "39662025395,54779", - "www.encodeproject.org%2Ffiles%2FENCFF514XWQ%2F%40%40download%2FENCFF514XWQ.hic": "1319613701,36479", - "www.encodeproject.org%2Ffiles%2FENCFF666USK%2F%40%40download%2FENCFF666USK.hic": "15051670107,32102", - "www.encodeproject.org%2Ffiles%2FENCFF047SDP%2F%40%40download%2FENCFF047SDP.hic": "1357076705,16438", - "www.encodeproject.org%2Ffiles%2FENCFF584LEP%2F%40%40download%2FENCFF584LEP.hic": "9314176858,36479", - "www.encodeproject.org%2Ffiles%2FENCFF671SOE%2F%40%40download%2FENCFF671SOE.hic": "3273732256,16438", - "www.encodeproject.org%2Ffiles%2FENCFF702LAP%2F%40%40download%2FENCFF702LAP.hic": "1800427500,31682", - "www.encodeproject.org%2Ffiles%2FENCFF339PON%2F%40%40download%2FENCFF339PON.hic": "5394351199,31514", - "www.encodeproject.org%2Ffiles%2FENCFF741QPR%2F%40%40download%2FENCFF741QPR.hic": "4271510019,30139", - "www.encodeproject.org%2Ffiles%2FENCFF103ANX%2F%40%40download%2FENCFF103ANX.hic": "4439745804,30083", - "www.encodeproject.org%2Ffiles%2FENCFF395SBC%2F%40%40download%2FENCFF395SBC.hic": "1596732351,31850", - "www.encodeproject.org%2Ffiles%2FENCFF289WNN%2F%40%40download%2FENCFF289WNN.hic": "8632980535,32102", - "www.encodeproject.org%2Ffiles%2FENCFF381EAU%2F%40%40download%2FENCFF381EAU.hic": "1702476311,36479", - "www.encodeproject.org%2Ffiles%2FENCFF976FEY%2F%40%40download%2FENCFF976FEY.hic": "1448279040,36479", - "www.encodeproject.org%2Ffiles%2FENCFF485LVS%2F%40%40download%2FENCFF485LVS.hic": "1593610856,36479", - "www.encodeproject.org%2Ffiles%2FENCFF143VJV%2F%40%40download%2FENCFF143VJV.hic": "1422312076,36479", - "www.encodeproject.org%2Ffiles%2FENCFF588NHX%2F%40%40download%2FENCFF588NHX.hic": "3943637009,36479", - "www.encodeproject.org%2Ffiles%2FENCFF768UBD%2F%40%40download%2FENCFF768UBD.hic": "24786676166,36479", - "www.encodeproject.org%2Ffiles%2FENCFF965PEE%2F%40%40download%2FENCFF965PEE.hic": "29387092778,47429", - "www.encodeproject.org%2Ffiles%2FENCFF702IFC%2F%40%40download%2FENCFF702IFC.hic": "29387092778,47429", - "www.encodeproject.org%2Ffiles%2FENCFF288DNV%2F%40%40download%2FENCFF288DNV.hic": "10313429504,36479", - "www.encodeproject.org%2Ffiles%2FENCFF698HWZ%2F%40%40download%2FENCFF698HWZ.hic": "10962849269,47429", - "www.encodeproject.org%2Ffiles%2FENCFF355OWW%2F%40%40download%2FENCFF355OWW.hic": "3219571601,36479", - "www.encodeproject.org%2Ffiles%2FENCFF177TYX%2F%40%40download%2FENCFF177TYX.hic": "10325679706,36479", - "www.encodeproject.org%2Ffiles%2FENCFF542BHD%2F%40%40download%2FENCFF542BHD.hic": "11085397879,47429", - "www.encodeproject.org%2Ffiles%2FENCFF684IFW%2F%40%40download%2FENCFF684IFW.hic": "11085397879,47429", - "www.encodeproject.org%2Ffiles%2FENCFF592UHE%2F%40%40download%2FENCFF592UHE.hic": "21363948089,32102", - "www.encodeproject.org%2Ffiles%2FENCFF779XIS%2F%40%40download%2FENCFF779XIS.hic": "9517383271,36479", - "www.encodeproject.org%2Ffiles%2FENCFF518PSL%2F%40%40download%2FENCFF518PSL.hic": "7500581463,36479", - "www.encodeproject.org%2Ffiles%2FENCFF275GBB%2F%40%40download%2FENCFF275GBB.hic": "7889407162,36479", - "www.encodeproject.org%2Ffiles%2FENCFF634KXI%2F%40%40download%2FENCFF634KXI.hic": "6430702966,36479", - "www.encodeproject.org%2Ffiles%2FENCFF337QPM%2F%40%40download%2FENCFF337QPM.hic": "8529733887,36479", - "www.encodeproject.org%2Ffiles%2FENCFF162KMP%2F%40%40download%2FENCFF162KMP.hic": "5615896908,36479", - "www.encodeproject.org%2Ffiles%2FENCFF992VTE%2F%40%40download%2FENCFF992VTE.hic": "7328975027,36479", - "www.encodeproject.org%2Ffiles%2FENCFF464WXY%2F%40%40download%2FENCFF464WXY.hic": "5715339664,36479", - "www.encodeproject.org%2Ffiles%2FENCFF752EGH%2F%40%40download%2FENCFF752EGH.hic": "1733758743,36479", - "www.encodeproject.org%2Ffiles%2FENCFF474UJM%2F%40%40download%2FENCFF474UJM.hic": "222309548,18679", - "www.encodeproject.org%2Ffiles%2FENCFF531UPZ%2F%40%40download%2FENCFF531UPZ.hic": "1827756846,36479", - "www.encodeproject.org%2Ffiles%2FENCFF022VHA%2F%40%40download%2FENCFF022VHA.hic": "244983451,18679", - "www.encodeproject.org%2Ffiles%2FENCFF732NGR%2F%40%40download%2FENCFF732NGR.hic": "1679484567,36479", - "www.encodeproject.org%2Ffiles%2FENCFF513VSF%2F%40%40download%2FENCFF513VSF.hic": "28397932940,36479", - "www.encodeproject.org%2Ffiles%2FENCFF750AOC%2F%40%40download%2FENCFF750AOC.hic": "36471430712,47429", - "www.encodeproject.org%2Ffiles%2FENCFF219YOB%2F%40%40download%2FENCFF219YOB.hic": "2859767211,26979", - "www.encodeproject.org%2Ffiles%2FENCFF604YDD%2F%40%40download%2FENCFF604YDD.hic": "3549694085,26979", - "www.encodeproject.org%2Ffiles%2FENCFF746AMV%2F%40%40download%2FENCFF746AMV.hic": "2954867135,26979", - "www.encodeproject.org%2Ffiles%2FENCFF845ZEB%2F%40%40download%2FENCFF845ZEB.hic": "2763039282,26979", - "www.encodeproject.org%2Ffiles%2FENCFF570LWS%2F%40%40download%2FENCFF570LWS.hic": "2861588289,26979", - "www.encodeproject.org%2Ffiles%2FENCFF883YVR%2F%40%40download%2FENCFF883YVR.hic": "2433679887,26979", - "www.encodeproject.org%2Ffiles%2FENCFF056VLK%2F%40%40download%2FENCFF056VLK.hic": "2502986910,26979", - "www.encodeproject.org%2Ffiles%2FENCFF532DUQ%2F%40%40download%2FENCFF532DUQ.hic": "3172615899,26979", - "www.encodeproject.org%2Ffiles%2FENCFF723PYJ%2F%40%40download%2FENCFF723PYJ.hic": "10292839095,36479", - "www.encodeproject.org%2Ffiles%2FENCFF991SGJ%2F%40%40download%2FENCFF991SGJ.hic": "13072407683,32102", - "www.encodeproject.org%2Ffiles%2FENCFF885UZI%2F%40%40download%2FENCFF885UZI.hic": "1201881201,16438", - "www.encodeproject.org%2Ffiles%2FENCFF287KXA%2F%40%40download%2FENCFF287KXA.hic": "14705801988,32102", - "www.encodeproject.org%2Ffiles%2FENCFF335HYI%2F%40%40download%2FENCFF335HYI.hic": "20366756545,32102", - "www.encodeproject.org%2Ffiles%2FENCFF121YPY%2F%40%40download%2FENCFF121YPY.hic": "2760104016,26979", - "www.encodeproject.org%2Ffiles%2FENCFF675SJE%2F%40%40download%2FENCFF675SJE.hic": "3751779995,26979", - "www.encodeproject.org%2Ffiles%2FENCFF876LAW%2F%40%40download%2FENCFF876LAW.hic": "4032376256,26979", - "www.encodeproject.org%2Ffiles%2FENCFF740KVX%2F%40%40download%2FENCFF740KVX.hic": "3202490322,26979", - "www.encodeproject.org%2Ffiles%2FENCFF977OQV%2F%40%40download%2FENCFF977OQV.hic": "2919735477,26979", - "www.encodeproject.org%2Ffiles%2FENCFF525EFN%2F%40%40download%2FENCFF525EFN.hic": "2394748073,26979", - "www.encodeproject.org%2Ffiles%2FENCFF690QRC%2F%40%40download%2FENCFF690QRC.hic": "3183023394,26979", - "www.encodeproject.org%2Ffiles%2FENCFF452FWS%2F%40%40download%2FENCFF452FWS.hic": "2951805127,26979", - "www.encodeproject.org%2Ffiles%2FENCFF089KBG%2F%40%40download%2FENCFF089KBG.hic": "2531936700,26979", - "www.encodeproject.org%2Ffiles%2FENCFF939ARM%2F%40%40download%2FENCFF939ARM.hic": "3066385212,26979", - "www.encodeproject.org%2Ffiles%2FENCFF401ZAN%2F%40%40download%2FENCFF401ZAN.hic": "3008677144,26979", - "www.encodeproject.org%2Ffiles%2FENCFF378RZT%2F%40%40download%2FENCFF378RZT.hic": "2830232168,26979", - "www.encodeproject.org%2Ffiles%2FENCFF304AVD%2F%40%40download%2FENCFF304AVD.hic": "6164439305,50358", - "www.encodeproject.org%2Ffiles%2FENCFF453DBX%2F%40%40download%2FENCFF453DBX.hic": "6775246670,36479", - "www.encodeproject.org%2Ffiles%2FENCFF590VOM%2F%40%40download%2FENCFF590VOM.hic": "6443478922,36479", - "www.encodeproject.org%2Ffiles%2FENCFF246DOF%2F%40%40download%2FENCFF246DOF.hic": "6837914659,36479", - "www.encodeproject.org%2Ffiles%2FENCFF125FXX%2F%40%40download%2FENCFF125FXX.hic": "9736232550,36479", - "www.encodeproject.org%2Ffiles%2FENCFF241RAY%2F%40%40download%2FENCFF241RAY.hic": "7686758397,36479", - "www.encodeproject.org%2Ffiles%2FENCFF415XWQ%2F%40%40download%2FENCFF415XWQ.hic": "6973092068,36479", - "www.encodeproject.org%2Ffiles%2FENCFF374EBH%2F%40%40download%2FENCFF374EBH.hic": "8557459058,36479", - "www.encodeproject.org%2Ffiles%2FENCFF263YWR%2F%40%40download%2FENCFF263YWR.hic": "331586820,18679", - "www.encodeproject.org%2Ffiles%2FENCFF280CGS%2F%40%40download%2FENCFF280CGS.hic": "1743569614,36479", - "www.encodeproject.org%2Ffiles%2FENCFF553ZNS%2F%40%40download%2FENCFF553ZNS.hic": "1717253636,36479", - "www.encodeproject.org%2Ffiles%2FENCFF451VOI%2F%40%40download%2FENCFF451VOI.hic": "1626927468,36479", - "www.encodeproject.org%2Ffiles%2FENCFF420MQO%2F%40%40download%2FENCFF420MQO.hic": "31055961677,36479", - "www.encodeproject.org%2Ffiles%2FENCFF301BWY%2F%40%40download%2FENCFF301BWY.hic": "38902429246,47429", - "www.encodeproject.org%2Ffiles%2FENCFF606XNW%2F%40%40download%2FENCFF606XNW.hic": "1009699327,36479", - "www.encodeproject.org%2Ffiles%2FENCFF439ZOU%2F%40%40download%2FENCFF439ZOU.hic": "12381714313,36479", - "www.encodeproject.org%2Ffiles%2FENCFF499SYK%2F%40%40download%2FENCFF499SYK.hic": "13182654663,47429", - "www.encodeproject.org%2Ffiles%2FENCFF532LFI%2F%40%40download%2FENCFF532LFI.hic": "8286030286,36479", - "www.encodeproject.org%2Ffiles%2FENCFF020DPP%2F%40%40download%2FENCFF020DPP.hic": "23521952420,47429", - "www.encodeproject.org%2Ffiles%2FENCFF306VTV%2F%40%40download%2FENCFF306VTV.hic": "23521952480,47429", - "www.encodeproject.org%2Ffiles%2FENCFF399IHE%2F%40%40download%2FENCFF399IHE.hic": "10216571232,36479", - "www.encodeproject.org%2Ffiles%2FENCFF944AII%2F%40%40download%2FENCFF944AII.hic": "12567308552,47429", - "www.encodeproject.org%2Ffiles%2FENCFF230HVV%2F%40%40download%2FENCFF230HVV.hic": "8629849711,36479", - "www.encodeproject.org%2Ffiles%2FENCFF174LAF%2F%40%40download%2FENCFF174LAF.hic": "9446506633,47429", - "www.encodeproject.org%2Ffiles%2FENCFF898HRO%2F%40%40download%2FENCFF898HRO.hic": "9446506633,47429", - "www.encodeproject.org%2Ffiles%2FENCFF429MOR%2F%40%40download%2FENCFF429MOR.hic": "1455757398,36479", - "www.encodeproject.org%2Ffiles%2FENCFF061NXV%2F%40%40download%2FENCFF061NXV.hic": "1710915891,36479", - "www.encodeproject.org%2Ffiles%2FENCFF434PYS%2F%40%40download%2FENCFF434PYS.hic": "1832274903,36479", - "www.encodeproject.org%2Ffiles%2FENCFF704HHX%2F%40%40download%2FENCFF704HHX.hic": "1768142834,36479", - "www.encodeproject.org%2Ffiles%2FENCFF349DPM%2F%40%40download%2FENCFF349DPM.hic": "4316041260,36479", - "www.encodeproject.org%2Ffiles%2FENCFF718AWL%2F%40%40download%2FENCFF718AWL.hic": "39544267907,58932", - "www.encodeproject.org%2Ffiles%2FENCFF065LSP%2F%40%40download%2FENCFF065LSP.hic": "24929805283,55874", - "www.encodeproject.org%2Ffiles%2FENCFF632MFV%2F%40%40download%2FENCFF632MFV.hic": "22333105467,55798", - "www.encodeproject.org%2Ffiles%2FENCFF179HVU%2F%40%40download%2FENCFF179HVU.hic": "2659219603,36479", - "www.encodeproject.org%2Ffiles%2FENCFF791SPZ%2F%40%40download%2FENCFF791SPZ.hic": "2537491657,36479", - "www.encodeproject.org%2Ffiles%2FENCFF211ZWF%2F%40%40download%2FENCFF211ZWF.hic": "3512141227,36479", - "www.encodeproject.org%2Ffiles%2FENCFF614BNU%2F%40%40download%2FENCFF614BNU.hic": "5252155462,36479", - "www.encodeproject.org%2Ffiles%2FENCFF891DLM%2F%40%40download%2FENCFF891DLM.hic": "2549095612,36479", - "www.encodeproject.org%2Ffiles%2FENCFF056EXT%2F%40%40download%2FENCFF056EXT.hic": "2219014704,36479", - "www.encodeproject.org%2Ffiles%2FENCFF776DSS%2F%40%40download%2FENCFF776DSS.hic": "3920308353,36479", - "www.encodeproject.org%2Ffiles%2FENCFF814LQF%2F%40%40download%2FENCFF814LQF.hic": "1349480197,36479", - "www.encodeproject.org%2Ffiles%2FENCFF513ZNA%2F%40%40download%2FENCFF513ZNA.hic": "2638868195,36479", - "www.encodeproject.org%2Ffiles%2FENCFF692IOL%2F%40%40download%2FENCFF692IOL.hic": "3106768498,36479", - "www.encodeproject.org%2Ffiles%2FENCFF294WZY%2F%40%40download%2FENCFF294WZY.hic": "2211089761,36479", - "www.encodeproject.org%2Ffiles%2FENCFF339UWS%2F%40%40download%2FENCFF339UWS.hic": "2142759055,36479", - "www.encodeproject.org%2Ffiles%2FENCFF835FSK%2F%40%40download%2FENCFF835FSK.hic": "3919821739,36479", - "www.encodeproject.org%2Ffiles%2FENCFF328BMB%2F%40%40download%2FENCFF328BMB.hic": "2550686152,36479", - "www.encodeproject.org%2Ffiles%2FENCFF897RTY%2F%40%40download%2FENCFF897RTY.hic": "1323294397,36479", - "www.encodeproject.org%2Ffiles%2FENCFF306MWH%2F%40%40download%2FENCFF306MWH.hic": "1665386199,36479", - "www.encodeproject.org%2Ffiles%2FENCFF039YUJ%2F%40%40download%2FENCFF039YUJ.hic": "2335679939,36479", - "www.encodeproject.org%2Ffiles%2FENCFF468QIN%2F%40%40download%2FENCFF468QIN.hic": "3352516594,36479", - "www.encodeproject.org%2Ffiles%2FENCFF364WXU%2F%40%40download%2FENCFF364WXU.hic": "3959043175,36479", - "www.encodeproject.org%2Ffiles%2FENCFF373MSH%2F%40%40download%2FENCFF373MSH.hic": "4429550624,36479", - "www.encodeproject.org%2Ffiles%2FENCFF959EGQ%2F%40%40download%2FENCFF959EGQ.hic": "2475218228,36479", - "www.encodeproject.org%2Ffiles%2FENCFF624XMK%2F%40%40download%2FENCFF624XMK.hic": "3527855681,36479", - "www.encodeproject.org%2Ffiles%2FENCFF445OKS%2F%40%40download%2FENCFF445OKS.hic": "3369125589,36479", - "www.encodeproject.org%2Ffiles%2FENCFF239QDV%2F%40%40download%2FENCFF239QDV.hic": "1960069888,36479", - "www.encodeproject.org%2Ffiles%2FENCFF645AVM%2F%40%40download%2FENCFF645AVM.hic": "4969006589,36479", - "www.encodeproject.org%2Ffiles%2FENCFF494IPI%2F%40%40download%2FENCFF494IPI.hic": "1565483792,36479", - "www.encodeproject.org%2Ffiles%2FENCFF753IXE%2F%40%40download%2FENCFF753IXE.hic": "2892400648,36479", - "www.encodeproject.org%2Ffiles%2FENCFF731GXX%2F%40%40download%2FENCFF731GXX.hic": "5131381303,36479", - "www.encodeproject.org%2Ffiles%2FENCFF369CAQ%2F%40%40download%2FENCFF369CAQ.hic": "4236629448,36479", - "www.encodeproject.org%2Ffiles%2FENCFF053VBX%2F%40%40download%2FENCFF053VBX.hic": "54305946375,47429", - "www.encodeproject.org%2Ffiles%2FENCFF555ISR%2F%40%40download%2FENCFF555ISR.hic": "54305946434,47429", - "www.encodeproject.org%2Ffiles%2FENCFF964RSP%2F%40%40download%2FENCFF964RSP.hic": "12065485229,36479", - "www.encodeproject.org%2Ffiles%2FENCFF234MZQ%2F%40%40download%2FENCFF234MZQ.hic": "17507142760,47429", - "www.encodeproject.org%2Ffiles%2FENCFF994CEG%2F%40%40download%2FENCFF994CEG.hic": "17507142760,47429", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fb068e787-bbdd-49e2-9f6d-7a0e9f065d6e%2F4DNFIHSUIRFY.hic": "2701182442,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3768b89a-e124-40eb-8acd-94a4fdd35807%2F4DNFIXTAS6EE.hic": "3283740601,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F9c513602-5abb-4088-8415-c827c381ab0d%2F4DNFIC3JD6O2.hic": "4896075767,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fde954dad-1849-4c23-beb4-bf893b7d76c9%2F4DNFIGY85S4W.hic": "3364151996,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fe1befa6e-8067-4296-8db2-67d2a2458985%2F4DNFI2LTNXME.hic": "3699291418,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fbb3307fd-7162-477a-87c5-52f12d03befc%2F4DNFID162B9J.hic": "3576428773,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8597cdae-8319-42d9-9175-3f77aaee34e1%2F4DNFIQWS3632.hic": "4022561190,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F327f091d-6a63-47c4-9752-2dff303a13d9%2F4DNFI6GFHB6G.hic": "4239331168,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd70dc3b8-48a7-42c2-bd23-80bc44fc2266%2F4DNFIS5F6EBL.hic": "4404671861,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F77df7bf8-6a3d-407a-8968-4ca1e78d2269%2F4DNFIF2D3TL9.hic": "4793989394,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc8f7cc35-d2ef-4717-9009-c02154050fbf%2F4DNFI6EIFUZI.hic": "3370273763,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F98449d79-30d1-4e32-801d-07435819a42f%2F4DNFIRKGMZRQ.hic": "4669813207,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd4fe1844-2493-4722-8b98-34a93a4bb7d8%2F4DNFIQWD8ZYD.hic": "5379889057,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F1ee40499-1de4-47ff-b540-d9a65943c6b8%2F4DNFIX7H3CE2.hic": "4857679239,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fac016170-23a7-4111-8773-353d6c150f34%2F4DNFIO21YDCV.hic": "4695989644,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F1faea4e7-9a32-466e-a826-0bfdab6cd915%2F4DNFIUE5RAS6.hic": "4788044799,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fcbd396ed-11bb-404f-aed9-ef10abc258e6%2F4DNFIFI6NIKJ.hic": "2069414927,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Faf3f78db-ae92-4215-bcae-76d30c617e5d%2F4DNFIL5K3MA1.hic": "2585598247,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F66fc2893-224e-48b4-bdb0-25e022dedd03%2F4DNFIPV5KFMK.hic": "2060965679,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F2b39781d-aadc-434f-abe3-562d61308fdd%2F4DNFIW8TIFI5.hic": "1694424195,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fb6d28f7b-27d3-486f-b5ac-32567416560d%2F4DNFIA6NSSBJ.hic": "2219532611,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F08785616-722e-46bb-ade2-2fdd21324e11%2F4DNFIBKZK63V.hic": "2429136232,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F904b13d3-1203-42a4-812c-963e80c159b1%2F4DNFI3CFMRID.hic": "1233390166,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fb0ed4afe-5ecf-451d-bb1f-444697e3f558%2F4DNFIYIAUEPW.hic": "1753567534,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F4bb9a9b3-12a8-4d2f-8071-4722294c88ea%2F4DNFIC3HAU11.hic": "2271375254,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F5abf9c36-c1d1-44dc-8197-74d860d896c0%2F4DNFIM2BMJ33.hic": "1770471113,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fa68475db-7816-4cec-b2da-d4ce4a0c7a0e%2F4DNFIBY3UHJB.hic": "2095528423,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F07c40943-0d0b-4b3e-94a0-8583b0e00b47%2F4DNFIWZEN3FF.hic": "1558559508,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd8a39553-2718-4866-9b2a-45d8e9c5ac6f%2F4DNFIE5TEYK7.hic": "1323063102,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F294b61ef-5565-4f04-ade9-f921a6686cce%2F4DNFI7H4II2V.hic": "1436947982,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F87a70ad7-7d34-4302-9c03-eb824bd4e633%2F4DNFIAS8LV1C.hic": "1263105698,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F9db804c6-5a91-4cf5-8ae9-e054223afb77%2F4DNFIBXWIH8J.hic": "1587059951,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd1e55906-ec8f-444b-8ce1-2de22a431a76%2F4DNFIO2HBDAI.hic": "1666436393,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F7a4b9b37-8e38-470c-8190-fd4d513c0bbb%2F4DNFIXWCLD4M.hic": "1513511880,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F6c7615b2-5310-4bbf-a605-98761d3a3079%2F4DNFINASC4NQ.hic": "1420358914,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F20454014-49cd-4e2d-93da-f40ad52776d5%2F4DNFIZF1KI43.hic": "1377041630,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F5df04e86-ee2a-45f2-b878-bf1648e2cca5%2F4DNFIQBHR9XC.hic": "1179502734,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F9d1cc910-bb3f-4106-802a-73184c58d5ba%2F4DNFIQVMVRP6.hic": "1811976991,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fe431986b-0732-460f-92ff-0abd1694d2d0%2F4DNFIJ7OAIFQ.hic": "1685503856,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F56d0c575-4962-4ea3-92c3-55bd0e17c096%2F4DNFIE8E4ANZ.hic": "1598369564,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fdb1502fb-a989-4ef9-b800-7eaa7be172ae%2F4DNFIOUSETUP.hic": "1493294709,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Facc2f1c3-8c96-4d21-814a-3a8ba81e7741%2F4DNFIVJ3IIQL.hic": "1472376655,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F037fb4c3-8641-4953-a977-cc71f2137582%2F4DNFIHN2QSMX.hic": "1179632606,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F16d2c3c0-6d29-4815-b074-b142af90b615%2F4DNFIILDWK8M.hic": "2280059989,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F31789849-e4db-45d8-9730-66a048c02d8a%2F4DNFI6XD6JAQ.hic": "2253961696,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fff04947e-e6e8-4d62-8374-ef2ee4104809%2F4DNFIALNLR78.hic": "1914687914,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F53e6c1e7-9410-4158-84e6-57c2e683b095%2F4DNFIBT4EAKN.hic": "2296378356,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F0127900a-258f-4815-97d2-6fd2b043d853%2F4DNFIDJ2JZ7Q.hic": "2558945393,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F89f95693-3d28-44eb-9d45-14932f8e258c%2F4DNFI8JFOAJT.hic": "1726440253,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd803d818-b0d4-4796-8d61-a9f3943f3b10%2F4DNFIRZA6EV6.hic": "1805017504,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff9165fb1-0782-4757-a740-5b929e0252bb%2F4DNFIB7QTIMH.hic": "2541020707,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff8d916b2-b58e-4cdf-894c-ffcb3bf6ebd9%2F4DNFIJ5DQZVK.hic": "2445734043,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F14066a5b-e01a-43c2-a468-b18826174df3%2F4DNFISTWNV9C.hic": "2499319890,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd0692151-7f9a-4475-b059-f8802616dded%2F4DNFIBN9K4V9.hic": "1591570769,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F70a7ef36-a514-4e45-918f-47c4e9e30ef4%2F4DNFIR8OU6QJ.hic": "1689882108,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F180306cd-8593-413a-ae83-24f19209c5d2%2F4DNFIDSWKFF5.hic": "1596696630,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F6e7b9be7-f465-4434-8e9c-68d1e44a76af%2F4DNFIV239W4L.hic": "2345867406,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F55df948c-941d-4930-854c-6a07557a0c1d%2F4DNFIREVU1Z5.hic": "2254683002,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3f590cb7-df3a-498f-81c3-d5ed4179b8ad%2F4DNFIFHU75I5.hic": "2497670883,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8f064770-6008-4f74-bfca-268d4a22d745%2F4DNFIMROE6N4.hic": "9850583704,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fa93d0588-76b7-4ccf-933c-4325876b0a53%2F4DNFI5SUHCGZ.hic": "10364705187,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F2f5f0d6b-0b22-4936-93c9-0944d49c037b%2F4DNFII84FBKM.hic": "8836986129,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F12e90fc5-0b76-4e42-b346-58d267f9ad6e%2F4DNFI2J1ODWB.hic": "13410858286,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff2702a45-3e8b-4980-bcd5-6bb0e291614f%2F4DNFIJWBWE41.hic": "20515676755,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fa0859349-5f06-4ad3-b56f-b1166b34a9eb%2F4DNFIIMZB6Y9.hic": "15350325963,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F12685c57-d54a-46fa-9efb-acf34ed77574%2F4DNFICJECID5.hic": "1525002266,26979", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd101a58e-89aa-44fd-96c5-6bf1e2476272%2F4DNFIR6UW2QA.hic": "1264999913,26979", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3d8c73bf-1335-4af4-b124-e3622d48c5f6%2F4DNFIGOEKBUZ.hic": "1905947578,26979", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fcd2477cf-6ed0-4d7b-b4e9-88fb38b0df48%2F4DNFIMDNAEW4.hic": "996444147,26979", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F0f03953e-29da-4f2e-8c05-572d0edf4525%2F4DNFI5OSZ3JC.hic": "369361754,22829", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F29d95dbb-005a-4ae1-8b9c-0fec9ec0bbd0%2F4DNFI7KOUGFM.hic": "1227434049,26979", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fa441ab7b-afbe-437d-bf98-b6b916558642%2F4DNFIGKX4A32.hic": "883933242,26979", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F941b2f94-2fff-4d3c-aceb-fee4a5ae41a9%2F4DNFI1ORHOTA.hic": "1140970677,26979", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8720ede9-093f-4c00-912f-373283260a16%2F4DNFIWSVLZED.hic": "458091151,26979", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fe9e17155-2b62-4a68-afb2-31dfa674e169%2F4DNFI6H926RO.hic": "3552863515,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F22f22778-987a-4dc0-97bc-f26eae0156d9%2F4DNFIKTYSPOF.hic": "2939475400,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F40f40192-0acb-44cb-8778-8d21afe593fb%2F4DNFIZ4S52BV.hic": "3067438113,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd8767374-7018-4e11-9226-bf5612d39ebb%2F4DNFI3APMXHF.hic": "3258874744,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8c5140ec-a65a-4186-8c59-2927233eecaa%2F4DNFIQLIKDSD.hic": "2746398416,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8cdedda6-d7d8-4231-a85b-d56fcd962366%2F4DNFIKYXMF1E.hic": "14442148774,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Faa4d4497-7c6c-4dad-8040-be13ba07ea32%2F4DNFI9815EEJ.hic": "17960817603,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fe9b7b95f-190b-49fe-8047-ef4a8fc59746%2F4DNFIQ2687RT.hic": "15954277087,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F59863d3a-8d7c-49c7-9a41-7f2a58ad24d1%2F4DNFIYDBBSE3.hic": "16499534862,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3e80ca41-b3e0-4f4f-a05e-8f95fe96d938%2F4DNFIMOCN1YS.hic": "863725312,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F96f97a01-0020-4f09-93e8-fc8a9fd07218%2F4DNFI6558CM8.hic": "1597967345,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fce9e9334-ee0b-4549-a845-110470ba5986%2F4DNFIQZRKS7Y.hic": "907626411,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fdaac8209-1015-48da-9e31-2e252dfd8fe0%2F4DNFIX4DLXSE.hic": "1369766288,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F268b7d52-9655-474c-9467-8ba31bb2195c%2F4DNFII3JV8I1.hic": "856656441,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F9681f9b5-335a-4f56-afa1-15b58bbb41e8%2F4DNFI5IAH9H1.hic": "1495185175,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3e082eab-95aa-4677-88ed-9d7adcc1effb%2F4DNFIK5HY1GP.hic": "2135337789,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F31af1ead-4520-4669-957e-424b4b197c33%2F4DNFIFA89L5B.hic": "1975593640,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fcc2b78fd-52d4-4e0c-ac93-b84ee82daf7e%2F4DNFICXCFGEI.hic": "2628202920,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff54efece-280f-46ca-95e3-1f8a3cd18820%2F4DNFIK4CECUH.hic": "1901129375,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F1181c0c4-afb7-4b6a-9fdc-d868fb2253fc%2F4DNFI1EYIGOC.hic": "1947135384,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F1d3e2905-b9b9-4b91-bcb4-8d34746e78f6%2F4DNFI7TLEWUI.hic": "1185758726,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Faba3d42f-39cd-4a85-9d3f-835aefb5c803%2F4DNFIVCJKHMN.hic": "687240974,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F27f54fcb-54fe-41a4-b25a-2f8944c89044%2F4DNFIN8F14CS.hic": "1304082029,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fb75fedb5-88f4-4bc0-8e38-298df7847a7f%2F4DNFI5LCW273.hic": "12497258313,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F2f22b2a0-3712-496e-92d2-63775ec0e421%2F4DNFIVSCH2CH.hic": "12594733778,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F07e47261-5863-44f5-9198-76e263081bea%2F4DNFIZ268JGC.hic": "1499059135,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F682b1ae1-3ac3-40e4-a330-c49f63946952%2F4DNFIJ1P4HBI.hic": "1190211725,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F197e7c89-ea73-41de-8cb2-8c0b1e3bb945%2F4DNFITEGKBIW.hic": "2061501971,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F191f6928-c9a8-44b2-8516-ee4d6005f24b%2F4DNFIE1P6RVH.hic": "1711447310,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F94435086-3701-4b28-a6d0-4a59b24d7615%2F4DNFICJ6I4DO.hic": "1557899940,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Faa9ac173-d233-41c7-8985-ca91949664e4%2F4DNFIKUG8MEW.hic": "1339072088,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fba6d8ab6-ee18-4ba2-8da9-d631888dd50a%2F4DNFICFZGFAV.hic": "1261083478,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F87a3ab04-7094-4673-81e4-ac8c9add8eb5%2F4DNFIQXCZVVA.hic": "1084913802,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fbc1ff488-82af-4579-9424-959184edb139%2F4DNFIB6PJFJ3.hic": "1114571343,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F1f7026ee-987a-41e7-8a61-45510ee3f86b%2F4DNFIX97731O.hic": "1246860402,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F6186787c-2e72-4925-9729-02121e2e4597%2F4DNFIYQYZOTO.hic": "1212210849,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3b98a946-0109-4efa-a13e-cc7a36772125%2F4DNFIPXU7V25.hic": "1696288217,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fea17d041-c6ed-43a1-8047-535f3d19ad44%2F4DNFIL39PR76.hic": "1719284710,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F72774afe-f166-42ac-9849-4070b0dadf6d%2F4DNFIYLJ3R3B.hic": "1106419640,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F4a45e733-55f8-4a8e-be24-2ef34c976e25%2F4DNFIL51WBN6.hic": "1327651164,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F086c62b0-a26f-41ae-a5ff-88b8be2bd2aa%2F4DNFI6SFPUDA.hic": "1336964405,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F4d9b79c7-af62-4070-84a9-b953903f2732%2F4DNFI2KM22QR.hic": "953067310,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3c9889d1-f49e-4639-8e15-2d99d6cd22e7%2F4DNFIVF8Q45U.hic": "984193565,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fa080dd7b-b7bb-4eae-a275-572a8b45b2d0%2F4DNFI2RN3WFP.hic": "1046525527,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fb81860ca-c227-4b68-a298-1907fd32300a%2F4DNFI4TJTL7A.hic": "1160373401,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F74ab47dc-7b52-421c-845e-6feb33457adf%2F4DNFIYJ4TWB8.hic": "1268416204,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc6582128-a930-4bcc-941e-5c0733bdd4d5%2F4DNFIM6RGKPV.hic": "863347067,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F11a75514-4450-4295-9eda-18e3678a575a%2F4DNFIL2VWWL5.hic": "860731581,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F5eb52a8c-bf14-4225-bf34-14a0aa47c369%2F4DNFIX6ZXCA8.hic": "893462267,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F66aaa4c0-1f62-4040-8ecc-4e95da23cd18%2F4DNFIEVR81FS.hic": "879736207,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F821c6e7f-96f7-47de-b7d9-4970562b3c8e%2F4DNFIAUI6BBI.hic": "996313881,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F9252c362-31ab-413d-a47a-cc97bdbf243a%2F4DNFIAFEE9G2.hic": "1103265750,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc1a0bf52-2e65-4deb-871f-ede736babd41%2F4DNFIPZBEXCP.hic": "1081257762,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F729f5ce3-d7e0-466d-b781-d18049e63bfa%2F4DNFIWPKRZGU.hic": "973779283,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F80b769ee-a717-4825-9db0-dca86f913173%2F4DNFIMD9QNDX.hic": "1158688208,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F266290c0-2767-4158-85ab-7274368905b9%2F4DNFIATA1HD5.hic": "1073361089,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc46f18a8-eb24-4d35-b112-36db72bde2f5%2F4DNFIH9U4I7I.hic": "1111124316,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fec91a79e-7de7-49f7-9b3d-d28313aeddc8%2F4DNFIZ95S6TR.hic": "1242494051,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F9e9390b9-da20-43bb-a8f4-9830f354ddf9%2F4DNFI5ERM9J7.hic": "1271051397,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fee8ea82e-b9e4-41ad-bced-5f4fbdaa4fec%2F4DNFI15FPSQL.hic": "1216714120,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fbed7eb86-8990-42f2-b3ee-5992d6361f7c%2F4DNFIJ3DZPGM.hic": "1035089437,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fdaa8a324-3bf8-424c-8a86-b8ad325cc20d%2F4DNFINW9P6XF.hic": "1215712740,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F70631758-6bf8-47a0-92b6-132574886faa%2F4DNFITS16HW8.hic": "1105283847,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fe473304b-7bc8-49b8-bba1-ecb9f06914ee%2F4DNFIS3DIH4V.hic": "1036056660,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F10f9224a-111c-402a-ac25-e221ad0af9ef%2F4DNFIY3KDHP6.hic": "1071761024,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F17519b96-2bdd-4294-98f0-1535f1aef28e%2F4DNFIO8HVKOL.hic": "953793750,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ffb18f896-4730-4909-86a3-867fc8e76cd6%2F4DNFIMF6CFOM.hic": "708717889,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fcfee4d87-0873-40b0-b79f-35dcc8669c1c%2F4DNFIZZ77KD2.hic": "732668723,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fb8b5d909-8a1b-41bb-bcdd-d108a0bde762%2F4DNFIOLO226X.hic": "951271932,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F9ce81f6e-b9cf-4ec9-8bd3-517539e4b662%2F4DNFIJMS2ODT.hic": "932509067,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F506aa952-5d41-49ff-b658-916bcf88a395%2F4DNFI49F3LJ4.hic": "1208494817,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fe4dc392d-ca36-4bdf-a27d-173cae34f520%2F4DNFI65MQOIJ.hic": "854630155,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F149ef8d7-e0b4-4e4f-b7e5-7226e2603746%2F4DNFIM4KEPRD.hic": "882790622,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fa436f0a8-4f9a-4524-90ac-795c5b8491cf%2F4DNFIIXBIZFC.hic": "848244425,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fbc8a05dc-7449-4b01-8330-a55db37ca8e6%2F4DNFIWDOOBVE.hic": "1116239020,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Faef8b881-28fe-4694-9a95-1d31940e6726%2F4DNFIDT9EB5M.hic": "888289053,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff66f3162-a53d-46f2-8800-3752935d5400%2F4DNFIX2VUNV8.hic": "1226661451,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F36c782e6-2c48-4298-aa43-bd6624da003d%2F4DNFIEQHTV1R.hic": "804665819,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff15d571e-605d-4bcc-a359-0350b57a6815%2F4DNFIFW7GA64.hic": "901568712,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc2aa2e8b-ac7f-4acb-b4b5-ac5f845840fe%2F4DNFIXGXD67I.hic": "970995551,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F71b6fd7d-b249-4d65-a597-b80b95845399%2F4DNFIA7GB1NB.hic": "956785837,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F6cbb1418-34db-427f-9273-5174eac81529%2F4DNFIVOJGWNP.hic": "890415052,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc69c2ee7-b6c3-4a62-8d4f-913491c9dab8%2F4DNFIW22BNB5.hic": "1075499540,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fa268f28f-c6d9-4324-8989-75d2d317af1b%2F4DNFIIFBC8WN.hic": "1045459440,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F6c7361d4-60a6-440b-b5be-072cada98663%2F4DNFI9ZBEBJH.hic": "759395398,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fcceaad1a-e01e-4430-8bd6-24ffa6891802%2F4DNFID4SLU53.hic": "921288444,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F9eee5854-b33e-4d5a-9ba8-ceffd47e7488%2F4DNFIODI1NUJ.hic": "733159777,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F5e1089b0-42e8-441c-99bb-4be99bcec28b%2F4DNFIJL26LFN.hic": "723567970,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F298a429e-ea29-49d3-bfed-fa851e1e7c4c%2F4DNFI5KTF553.hic": "2213661745,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F965d29f0-e4a3-477c-8ae4-faf4a654e69a%2F4DNFIYSPGFGV.hic": "2274989349,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd88acbc1-37b9-4266-9f97-d8fed576d0f3%2F4DNFILOR6D2D.hic": "2595459358,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F7b6ddbce-0ed1-4272-b8ae-32793e4ea4e4%2F4DNFI1WMMPJQ.hic": "2262433890,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fedc0c8c4-97d8-4372-9a4f-5e0cdf09d7d0%2F4DNFI47P5978.hic": "2146314403,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F0edcc389-43a4-44d7-b946-fe3496f93d56%2F4DNFI7XGW6IH.hic": "2302805723,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F0a802926-e235-4c80-b521-83a1774dfb46%2F4DNFIK1EJG8I.hic": "2374943035,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3c36aedb-6a58-4aa2-9b11-bb440ec174f1%2F4DNFIDQ3THN9.hic": "2341188249,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F846123cd-8828-4e51-8b8a-27deaf293858%2F4DNFI3WPNFWT.hic": "775145629,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fbd06e3ad-0e37-48a3-8367-c7d5912cab03%2F4DNFI9DCUOQ1.hic": "870487824,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc2eaf9bf-9584-4cec-8685-bd74038a6c01%2F4DNFIU8AF5ZY.hic": "1276224366,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F219497b5-3f35-473b-9d4e-e1cf21c69561%2F4DNFIHW8NTQX.hic": "28864787856,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F4be13558-114a-4f2d-abca-7598e2ff4757%2F4DNFI4OUMWZ8.hic": "17061013588,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F49aed637-87a1-4d4d-ae68-e5da82aec05b%2F4DNFIEYQ5ZIR.hic": "13555272651,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fa2f48779-4eff-44a6-8a9d-96435aca1ddc%2F4DNFIDZT7PR8.hic": "13425047093,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fb6ec6b71-27b8-4891-b10a-ab06a5270468%2F4DNFIEJEFCAM.hic": "15394960208,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F68b9a7b5-8413-44fc-8c2d-59a67b1c4166%2F4DNFIJ8JKKWJ.hic": "17012681779,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F294d45a4-8b5e-456f-a9cb-1cbbbad3a7d2%2F4DNFINEQY95T.hic": "13966775978,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fbd7f3a48-b822-41e2-bd9c-f52b3aff7b6a%2F4DNFII6AN691.hic": "12367300362,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F7da44594-0dc8-4e74-8e10-a957aeaea51a%2F4DNFIDBIEXI7.hic": "2015474981,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F085a0453-3784-4eba-80b2-3556e53e2f52%2F4DNFIDKJFK2S.hic": "1983111659,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc370c78c-0a99-4c3f-a29b-2dfafc6a3e86%2F4DNFIPAF4PYT.hic": "3041434294,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F907ce45f-baa5-416d-92de-e86db4bacff1%2F4DNFIWIYYNQ5.hic": "7082321112,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff13afc6b-cf69-4c9d-881f-eed4dd3c28ee%2F4DNFIHMCILEN.hic": "1739157603,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F7575d891-0e3d-4a77-896a-3e1b3a8d330b%2F4DNFIJBJ6QVH.hic": "5213499748,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff0daa830-60d5-4c7c-a2e1-a4ee70b3fee7%2F4DNFIH2A7IKF.hic": "4099503507,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff4970a25-91d8-49a7-9a4a-fe0f12cb2b0f%2F4DNFIOL8KGQ2.hic": "2256042055,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F879f1850-d175-4a86-8a97-12658482e3d1%2F4DNFIWILLD6C.hic": "5476286356,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F787f538e-d619-4c8f-985b-78753fb7e57c%2F4DNFIZBXXJAF.hic": "5946467856,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fb8ee785f-1016-4989-9e64-78352621d32f%2F4DNFI8PZOJHN.hic": "8307204961,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3d8997fa-528c-4531-b25b-a412de6bd472%2F4DNFIGXAMSJY.hic": "6577588285,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F87aede55-7610-4283-af0e-c6840429a31e%2F4DNFIWNNO89O.hic": "2871061417,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F93b8e020-b337-4685-81dc-40cc8a12b5e9%2F4DNFIXU2KPNQ.hic": "3401717686,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ffb5cf1bd-59d6-46fe-857d-b86d9756029d%2F4DNFIHBGD6N6.hic": "840028421,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F2d1bc088-d838-49b8-85fc-fea78a7353c4%2F4DNFI7J8NI4A.hic": "675705256,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F21a27b63-fd67-401b-9aa2-2798e6588d21%2F4DNFISFM9VFK.hic": "800145922,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F656c0a9d-7058-4c4b-a3ce-701d929561c1%2F4DNFIJU5XBK7.hic": "966593603,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F2efacfbd-9c81-4e62-8df7-847d1ab774d5%2F4DNFIPKY8ED1.hic": "3401629450,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fa50b6a26-56b5-43f2-b525-fa219fd716f1%2F4DNFIQRTP7NM.hic": "5358852759,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff5dc7a59-b998-4490-8a76-afbf3b258a49%2F4DNFIBCIA62Q.hic": "5779049277,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F62b2b237-cb02-45f7-89d9-616cf9ffb678%2F4DNFIV56OFE3.hic": "5818844506,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8ac79b4f-cfbf-4b2a-9fc2-898ed6c3e5e1%2F4DNFILIM6FDL.hic": "19637469163,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F1cff8afa-5a13-4ad4-bcad-91fc3ced759c%2F4DNFIP71EWXC.hic": "17934647326,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F000789fe-9a22-4280-a71c-7ad228fd4cac%2F4DNFIM7ZVQOQ.hic": "700134697,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8d78457f-0c2b-4358-b08c-4d4ef4d9f59d%2F4DNFIS6EYHCX.hic": "628314484,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8ca3b4a0-2478-49c9-b4a2-a28430417a32%2F4DNFIKKCMS1Q.hic": "584050634,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff5041473-18ec-439d-92b1-8ad98c9b25c0%2F4DNFIBIV8OUN.hic": "522632731,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fcf474ec6-abd4-431e-a21c-252fcf5ee6b3%2F4DNFIAUMRM2S.hic": "313395531,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F2bb1c73e-fb0f-41c4-8620-a938cc8d24a0%2F4DNFI9ZUXG61.hic": "332217525,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F26dfa41e-7e4f-457a-a3ac-72daf8059f3c%2F4DNFIDBFENL7.hic": "359604894,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8ed2e68b-189e-4988-bb6d-94e63240a231%2F4DNFI7XAZNNQ.hic": "5312422266,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F6f2b1ce0-5205-4680-981e-d91b694dc3e4%2F4DNFISNGDB53.hic": "2008546759,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F73c8147f-bc7d-4d33-8a10-a9e7b413ecc6%2F4DNFI1CIGHYC.hic": "2221847625,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F526ae3e3-32cc-4670-970f-1faa9cfafd4d%2F4DNFIQD2DP2F.hic": "5295591503,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F6e803530-47f8-4c56-bb19-fbdcd578d2f0%2F4DNFINHT8P7C.hic": "3159499486,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ffe705f38-903f-47b7-9b38-f80ebd18a479%2F4DNFIGF8EM7M.hic": "3490552542,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Faa197328-d6da-4299-a0fd-409ac9892668%2F4DNFIUPG2ZBJ.hic": "5382003751,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ffe5d52c4-2be7-4812-bca0-cd4bb3025e6b%2F4DNFIH3OTR14.hic": "3224693110,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F21935f61-daa8-4df2-aa69-fcd27953b405%2F4DNFIUATRW3Z.hic": "3835865655,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F72147527-e3e8-4967-bc45-8251249d76c9%2F4DNFI6V7ZQAE.hic": "4382708138,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F589f0919-f54d-49ff-a482-e2f453ef7f34%2F4DNFICKMT1CY.hic": "4479068191,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F861946ca-bad8-4a87-96e1-b2eb20b9ef10%2F4DNFIF9BDCNI.hic": "3698151402,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff76346ac-97ec-4893-8984-2b75ce1cdc51%2F4DNFIG5O1OQS.hic": "5704288175,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fe8b43826-f049-4c3f-b83a-e75fa7aacc85%2F4DNFIHS2SVBQ.hic": "990025510,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F46316260-f555-4dd4-9e40-8ae06ca52822%2F4DNFIU95B69H.hic": "1275878544,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff62ef491-a3ae-4f66-ab33-c5673c9e0b65%2F4DNFIYRROFCR.hic": "1522530503,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F1cd617e1-fad4-4fdc-8b4e-cb277650123c%2F4DNFIF7JN3IU.hic": "1463443128,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fdb20fe2a-0078-4d4a-8a52-d76043d06f40%2F4DNFIB2RYULQ.hic": "1269529700,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3d386fcf-1d22-47de-a0d6-0c3a641ca174%2F4DNFIMVDK3SI.hic": "1185489599,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F00e470bd-c533-41b1-923a-4b471824da12%2F4DNFIRLOTXSC.hic": "978217499,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fb8774fb3-d0c5-43cc-a6c9-eb0ca39841fb%2F4DNFIZAPX6J8.hic": "1100356082,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fab3b826e-614c-448b-860f-a3ebef68a82f%2F4DNFIQD5VCSD.hic": "1322319877,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F66c78d2b-993a-4937-95ed-9e2d302ceb3e%2F4DNFIIF6VAGN.hic": "868885799,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F5d106fe1-2d80-466e-87aa-46b38ba142c5%2F4DNFI86IEZXH.hic": "751443267,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc99490b6-faf9-413f-9c38-3f53018089d6%2F4DNFIP881SR2.hic": "754427927,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F39c7e387-e710-4b1d-b757-357dec03f6ad%2F4DNFI42NNCW8.hic": "1166392978,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F4742a211-43b1-4325-af6f-82490aeb766b%2F4DNFIEV4PKP6.hic": "1102227476,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Feaa73842-1c86-4ad9-8a9e-c189c0b4c01d%2F4DNFIF1DUQHE.hic": "1206699207,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd25f24df-0298-4079-bb6f-1c8e1e32392b%2F4DNFIGW55EAY.hic": "1033358104,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc57a7ab5-2778-4fe2-9d64-9a4e95135f12%2F4DNFISZRU6I4.hic": "1539570262,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd89f494a-27ca-46b6-89be-7583f3f6d18c%2F4DNFIBKKDTAP.hic": "350372180,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F06725280-cb24-4f22-a267-18b434bfa79e%2F4DNFIJSRQW24.hic": "314361467,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8fe5c3c5-006f-425b-ac6d-ea475e29be78%2F4DNFI3REN89E.hic": "299665258,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc8b6ac5c-13b4-427e-9158-cec0b890b6d8%2F4DNFIF5XLHKM.hic": "235668364,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F01ff33fc-fc23-48aa-a6c6-b720d6fe0768%2F4DNFIB6Q538N.hic": "316494853,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F552978c8-abbc-424a-9187-3e34cf802a97%2F4DNFI3ST3F7Y.hic": "296298411,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F72e66520-5170-4f2e-844a-fbfd0e23b480%2F4DNFIQT4M6UI.hic": "307691265,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fb3eb3953-ffe8-4d5a-970c-a16f3b7b9ec3%2F4DNFIFNCC7M2.hic": "364160436,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F37d413fb-afab-41ff-99aa-1678830f7dde%2F4DNFITM9MDJL.hic": "252412426,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Faf5db92c-aaf1-4086-a0d2-79b28648f172%2F4DNFI3NTD7B3.hic": "227586640,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff6892f7b-1f8a-4d7d-9605-c67932cd5654%2F4DNFIBED48O1.hic": "328344868,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd64afb07-5ab1-4c4f-8438-2fee37afa86a%2F4DNFISATK9PF.hic": "379669025,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fad11bb63-8692-461c-b698-89c601451321%2F4DNFISRP84FE.hic": "298491537,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F63710ec5-35d2-47dd-bf9a-08d3daa83d67%2F4DNFI2LY7B73.hic": "303150299,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F76077d9e-ca75-4301-ab79-88aa49bda495%2F4DNFIXEB4UZO.hic": "711757090,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F34dd4c0e-3487-4fb4-b95f-c4bb66e0fa31%2F4DNFIQWWATGK.hic": "221304476,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F48a8cf86-3248-4a8e-8e85-472ec219d49c%2F4DNFI44JLUSL.hic": "284772724,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fee399fbf-2a9e-46e2-8364-457713bff508%2F4DNFIM7Q2FQQ.hic": "330729464,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F124d191a-c5c7-49b6-b84b-0d1bad8bef2b%2F4DNFIZK7W8GZ.hic": "293166018,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fe351f7cc-7a2c-4515-ae0b-3bb2f91c986a%2F4DNFIMIMLMD3.hic": "240094740,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ffd1ae249-57b1-41d6-81a6-16b21dcd8f12%2F4DNFI7QUSU5J.hic": "681762505,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F46c92c5c-9ad8-4d49-beba-f35c5cd99208%2F4DNFINXUOI5H.hic": "375594313,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd7350d40-4e9e-4131-9151-bb539d39b431%2F4DNFIIJR2296.hic": "331322302,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fbfacf37b-1665-45f3-a046-e29e1544e9b0%2F4DNFIJMZUTXR.hic": "361313244,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F234e18fb-9990-43bf-9a48-f72722cfa232%2F4DNFIZQPT9EL.hic": "540421873,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F4b35ab09-2e79-4876-b2bc-d3a8faa26257%2F4DNFIZIXSZ9J.hic": "545066813,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F2ae5118e-807a-46e0-8e92-143d4b282b3d%2F4DNFIDD9IF9T.hic": "237409149,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fb34d7f6f-73f7-4b6b-80c7-c8af0f991549%2F4DNFIVC8OQPG.hic": "355121712,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F9ab169fd-cbdd-4f60-8553-a4c6912ad89e%2F4DNFITUPI4HA.hic": "313085022,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F4e53712b-d0d9-40c5-afe1-ffa0fad71e59%2F4DNFI5IZNXIO.hic": "341863906,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F7a91477f-45eb-4a16-affb-fc131f9326b8%2F4DNFII16KXA7.hic": "248904495,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F153729de-0eca-43cc-9b61-61aa8d775b38%2F4DNFIAAH19VM.hic": "668047244,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F879fd78a-7165-43d9-a0de-ca158b53df30%2F4DNFIVKIY3KV.hic": "247571318,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F67f901a4-040b-4b04-9fff-94a1780423cd%2F4DNFIVVCWL6C.hic": "198355985,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd5b30c5a-654a-463c-9474-39bdc3ce4500%2F4DNFIJRF2273.hic": "343971277,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F7070280a-8f03-40d0-9fef-e9d9f4d3dae7%2F4DNFI6FCC9ZA.hic": "312013061,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F47049719-9407-4d76-9048-26231045f642%2F4DNFI1CPQ4O3.hic": "352923267,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F862c2b5f-44c2-4bd7-9264-b3ca032d3d8d%2F4DNFISXFEDE9.hic": "271745977,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Feffbe052-39ff-4217-9871-44199ed90818%2F4DNFIF9L6QEQ.hic": "668409334,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fa7791854-1b35-4258-90fb-603c55f24642%2F4DNFIPKASX1Q.hic": "312727920,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F79cccad6-a78e-4de9-9fe7-08f7e8df663d%2F4DNFIWXZ4JQZ.hic": "151808553,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F7e86e0cc-d6f1-4ce0-aba4-c36c6ebb3c4c%2F4DNFIEMQ1O8V.hic": "700533280,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F4a1b58d3-9ae6-43e4-91cf-49f1fcbbab33%2F4DNFIYWONU7A.hic": "729050356,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F67bff264-0b0c-4c5c-9d4d-ff5abef2bbe4%2F4DNFISNIE5FH.hic": "7987657997,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3a6a943f-2cc0-4433-a27d-c89f3fdd3309%2F4DNFIV8MLWJB.hic": "6646216171,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F9e235711-ba90-404d-b4ac-b15990ea8e33%2F4DNFIXSTDPHL.hic": "3146468238,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F0c89f4bc-e9fc-4ecf-b868-26108dbb7bb2%2F4DNFIQJNOH8U.hic": "2919703928,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F1856ff9e-de7a-4fa1-ae0b-3e04b837b5e1%2F4DNFI57XB4A8.hic": "13417594377,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F099bb5b9-6315-4650-8f78-d603f5a046b3%2F4DNFIQ7UKVZV.hic": "9016468637,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Faf3c7a30-0fc4-410d-8d41-247da3eb105d%2F4DNFIWJY8GHD.hic": "7921314766,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fda99f429-20ab-4d91-bbfe-f8bdea8ed7b1%2F4DNFIN8NKRNF.hic": "4247121358,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F0ca0f4e3-30ca-4332-b735-e32dce08e1a4%2F4DNFIZYGEHNZ.hic": "4910404663,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F243f48b0-6b59-4f37-ad39-a12e0986f530%2F4DNFIRPYGAV8.hic": "4220073636,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F49f1a890-d458-42a6-9c78-99c38b6c7a8f%2F4DNFI6MZTDM1.hic": "375035361,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F76bd4768-9343-44ba-a99d-5500e184e39d%2F4DNFIG3BCGPL.hic": "2422923206,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F9d1ed866-eaf6-4906-aa8c-9e39616dde38%2F4DNFIS9YPJ3L.hic": "1593271574,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F1e7a5636-bdb6-45fb-85d8-87a7e908de43%2F4DNFIOWGA9AX.hic": "1632314387,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F5ecc552a-0a6b-49a9-9aa5-9f3fd9b535fd%2F4DNFINKEDSBF.hic": "1458761024,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F6c03f1d2-bb25-4c94-b5f5-d5cdd01c14b6%2F4DNFIVIXVUK7.hic": "1504818271,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F1a4616ff-6d04-4a6a-9773-b80e81da2471%2F4DNFIANHFY16.hic": "1850724180,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd2231870-a78d-4c8b-9cfd-084f2468acb1%2F4DNFIJ67ZFBI.hic": "1473864703,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F859c2dd3-df8a-42b7-86ea-bf6524f75e80%2F4DNFIG3YQQ4V.hic": "1539822829,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8bad667e-6003-4828-9a20-07585fa9c811%2F4DNFIOLKEOME.hic": "3036353747,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F92ea551b-5779-4d31-a0f5-621e4bd0eb21%2F4DNFIVLN8WJE.hic": "2710426318,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F61ee79fa-0617-4083-b121-f92ef3a8905c%2F4DNFI2111XQA.hic": "2589549183,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F83ebb98d-e5db-403d-aa23-875293156c0e%2F4DNFI88HXX7D.hic": "2462367030,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F6d63671a-8f1d-4159-82c0-931b43464772%2F4DNFIUBM6QK8.hic": "2486020469,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fcccb9014-ce15-4032-81ac-222b3d621cb4%2F4DNFIVILEERC.hic": "2052537210,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F21a07867-4007-4ca5-b066-25d3168208dc%2F4DNFIF7Q43N4.hic": "2091773428,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff738de0f-358b-44bf-97dd-644c8d9b1b1c%2F4DNFID56VJGW.hic": "878913568,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fda97c1d4-bb92-4a77-92a7-f7960f88b9dc%2F4DNFIYUR29KO.hic": "983915575,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F54ea363a-99e7-4f55-861e-1644acab7939%2F4DNFIUDPGHO8.hic": "905253594,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fdcd66a07-55ee-48d9-a157-419cf4ee3eef%2F4DNFISWC2N8T.hic": "1233576358,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F40363837-7466-4a1d-b20d-a66d1670b700%2F4DNFICMPHDMI.hic": "516590777,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F0b3fa4e6-caeb-40b4-8942-e9c0b03dfe4f%2F4DNFIKMKN736.hic": "634310295,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fb6a34050-d52b-4880-91cf-d3fe4b0ce982%2F4DNFIN5NLS49.hic": "650451131,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8e63a47b-9fd4-4772-8b0c-10ee589ffb16%2F4DNFI4P8UBRL.hic": "705655033,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F7d92b666-30cc-4838-9d46-c1f11cee3d3c%2F4DNFISNC3LAI.hic": "176146197,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F17f7dc63-a1bc-4970-b389-87d9ee93b753%2F4DNFIVBWPFD7.hic": "749678512,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff8897333-4791-4a83-9444-a653e24aee13%2F4DNFITMQRXB7.hic": "254477361,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8712bf31-33d0-4562-ab0b-a1e9cf4fd30c%2F4DNFIUYD3HBY.hic": "995625724,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fbfaf6383-9cc6-4b5c-9b20-d3bf2e8c3495%2F4DNFIRRSC7P9.hic": "1149985362,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fb0b70598-5d17-4e0a-8831-6cbe697e69e2%2F4DNFIWKR8FP6.hic": "1151628407,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fccc094a8-23ce-4fd8-9c4a-41f07c045c8f%2F4DNFIQ74RSUY.hic": "931695969,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8eda16f3-af5e-4f1f-b46d-c74df44b76aa%2F4DNFI9IIO5PW.hic": "1077740364,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff283637b-cf2c-4412-ba00-0e3d7e279fad%2F4DNFI8WGJG19.hic": "812086456,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F7ad8438f-d3d9-42d8-88bf-42845a0dc2d0%2F4DNFIQ5CCESJ.hic": "652559720,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F70e3bdcc-caf4-4822-b9c5-85234873db7a%2F4DNFIWTZHB4H.hic": "760694196,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F56ed767d-cd8a-4d38-8047-ed1e8bc8cd19%2F4DNFIENYQCDP.hic": "1159428005,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fa912fff9-5f90-42b1-a3a6-cbb9eb2cf861%2F4DNFIFATZWPD.hic": "1033325746,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F21338ea5-fdee-4ad8-b61c-608fc6cec4bc%2F4DNFI7YRXKEO.hic": "388142539,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff0f88647-5631-437b-b48a-4603915e3714%2F4DNFIUY3J7EW.hic": "407344788,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F16926af8-ac3b-4f32-97d5-6c0dc6f1596a%2F4DNFIRKUYKP4.hic": "893352368,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F93e39aec-6cde-4c5b-bcdf-283faa3163a2%2F4DNFIAQDBJZP.hic": "489922022,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F0dc0b1ba-5509-4464-9814-dfe103ff09a0%2F4DNFIC1CLPK7.hic": "565748333,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fb50964c7-b025-49d9-b1ed-289bedb59678%2F4DNFI3A3VYWU.hic": "4597459343,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff4390cea-b330-4022-88c1-9ff8c0a786f7%2F4DNFI6JJQKFJ.hic": "3678393678,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F70c0f730-5da1-4863-9b7a-6cdd31066cff%2F4DNFIK61ILGM.hic": "3324300994,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F14b14ac4-ab59-4754-9c43-eacd9d0638e2%2F4DNFIYD8LO9Z.hic": "3227227120,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F7386f953-8da9-47b0-acb2-931cba810544%2F4DNFIOTPSS3L.hic": "253942497,7557", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff6b5d8bd-27dc-4415-a320-53405a16db85%2F4DNFI525PKU5.hic": "305089653,7557", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F1f922dbc-637b-4c43-b816-f604f0e79ad1%2F4DNFI8Y9SRP2.hic": "1438589609,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F6a36d686-716c-4ba8-a9c3-fa8311791d3c%2F4DNFIP25GZGA.hic": "1419100109,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F0e535542-2cf2-46e4-ba10-7a0b946a7fb2%2F4DNFITPO1WTY.hic": "3885296184,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F0c17d228-5052-4c83-880e-af05118e6929%2F4DNFIG4X5Z5F.hic": "2159245890,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc3977c00-525b-4556-9a27-061707f8cb76%2F4DNFIXLYR32S.hic": "587852728,21916", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3f856506-cbc5-4211-a29d-48a7530c622e%2F4DNFIWI3V5LI.hic": "2318237793,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F38f77979-5eb7-4b6f-9a60-c2451185db98%2F4DNFI2DGL7LH.hic": "2068150664,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fe0992a75-7727-405e-95ac-aa97141b51c1%2F4DNFI1VSO8JP.hic": "1807949651,21916", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fe925f1aa-2e7b-44e7-bfa8-2084a613ab13%2F4DNFIV5O2ZYO.hic": "2242134377,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F803a6d3c-3972-4939-8ff2-d195c5192090%2F4DNFIEWEWQ8D.hic": "2981341325,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F25104375-a588-46e6-a382-663cee6c332f%2F4DNFICSTCJQZ.hic": "14592996888,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F927aa8a5-24a5-43b7-807a-1e99ac321459%2F4DNFICEGAHRC.hic": "15431307603,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8c380474-12cd-41f4-b86f-2a29faf12eec%2F4DNFIY3XPKPO.hic": "2550999291,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F77da562e-d0ec-45a8-8764-14fa16d995a1%2F4DNFIK9PS9GM.hic": "3401011629,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F11b26222-d480-40a7-8d53-3ad8500396cb%2F4DNFIF4Y74JR.hic": "2127593378,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F93df02c6-1047-43f6-afae-d3598b61eeea%2F4DNFIBBKG9KD.hic": "5724446278,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F6cd4378a-8f51-4e65-99eb-15f5c80abf8d%2F4DNFIT4I5C6Z.hic": "5419655766,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F067881e5-563d-40de-a9e3-caccad887fbc%2F4DNFI2U38HCE.hic": "14749043471,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fcb3da9ad-7afe-4d0c-9c2d-261181e7a95c%2F4DNFIETP228R.hic": "9401474797,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F185b7bcc-7bb7-41b7-9ebe-92d4fe159431%2F4DNFIXKC48TK.hic": "11624295594,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F18459b84-dd43-4af6-a05f-bcb773096322%2F4DNFIFPGOWJ6.hic": "2843730862,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ffde1e48c-4a0d-4bb1-b84a-e0e45f9a0aa3%2F4DNFIIRMBE8Y.hic": "5820677927,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fbabed539-1f0f-4e87-8815-fde596e6024c%2F4DNFIVUGNDD7.hic": "5170782436,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F7d00531a-e616-469b-af52-5b028270e2ce%2F4DNFIFLJLIS5.hic": "18917549985,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F7a9dad53-b8af-4cb6-9ce3-5c38e4a855c7%2F4DNFIOX3BGNE.hic": "5482775936,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F82fd7b7e-5f47-48d5-bf0d-daaa48a4674d%2F4DNFISPUVQHA.hic": "2177864938,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F4c6680f3-9cf6-452f-9dc5-ecebf376775d%2F4DNFI8649RQJ.hic": "3288850368,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F2395f001-19d9-4000-9f00-dae3dea708d6%2F4DNFIE8T8JZ8.hic": "1383191843,21916", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F24464fa8-bf96-483c-8e9a-c2f626ad6e19%2F4DNFIBM714BP.hic": "1765204569,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F918fc048-fa27-41d2-a63a-d50c511fbb9a%2F4DNFI6CWNUFL.hic": "2431120602,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F7ff5a0d1-8e54-4cf0-9fe7-339f147c78da%2F4DNFIZ4F74QR.hic": "3211825957,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F355f0412-cb17-452a-b15c-aba16c5a742c%2F4DNFIOUVOX3R.hic": "5547401083,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3cac91c5-160a-4b91-a91e-edc309318dd5%2F4DNFIVTDXW6X.hic": "4797344498,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fe9ac9ec5-6221-4f39-951a-1c5054fc9f1c%2F4DNFICA8Y9TN.hic": "4277557869,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F46f62222-b50a-428b-938b-5444951600eb%2F4DNFIDWM3HN5.hic": "4374808431,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F50e4f2a1-9cb6-4192-8199-64d354bfdf96%2F4DNFIBK5TB3N.hic": "3757387253,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fe4cdd5a8-1a45-4c6a-906b-a9603260d4c8%2F4DNFI3JYF9VS.hic": "5260534916,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc8164e99-5778-427d-be26-f0e1b62400f0%2F4DNFIP1GNKUO.hic": "7589365689,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F0d72e78a-fc87-4716-8b8e-6dc5650ff2ef%2F4DNFIQYQWPF5.hic": "22022259901,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fac58fc15-48c2-4eec-a689-23b677b4b6e7%2F4DNFIW6H9U3S.hic": "6810897169,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F31811e40-e3ca-4456-8ba6-2ee66d6c7104%2F4DNFI7J8BQ4P.hic": "7188744676,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F62d81a52-d2cb-4bbd-8510-0fe120e786e0%2F4DNFIA3AKFSU.hic": "1763730692,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fae0b7513-d1a0-4f27-a9d3-348837f42cb6%2F4DNFID68JQY9.hic": "2422880133,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fae6a1a7e-1d2d-4fd2-a89f-1799abac8a9c%2F4DNFIL1FQDXE.hic": "1543814834,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F80d343c9-bd60-468a-803d-c3e351a958bc%2F4DNFITSIPCSK.hic": "2344682115,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff2d61195-a3a6-4d50-b928-546ca67546cb%2F4DNFIJ88LYHR.hic": "3362742962,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F31052aba-773a-4500-961b-e0a518245b0c%2F4DNFIJIPWD63.hic": "2529548812,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc93d0710-3fbf-40cc-b0eb-878e2aa659e4%2F4DNFIZUP2BBI.hic": "491996147,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8660baeb-5be1-4ba5-93e4-66499e9a4587%2F4DNFIEBC4AF3.hic": "2993048734,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff6d08fbc-b836-4776-82ad-8b1b277ae837%2F4DNFI5VO3E1W.hic": "1949322679,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3af004a2-a6fa-46dc-8be8-898b847a77be%2F4DNFIFDGVWLU.hic": "2456400803,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fbd613b4b-2422-492c-8d8f-8afba9c8a182%2F4DNFITVGFNYZ.hic": "1411204423,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc340694f-14f3-4638-b09b-98220c20039a%2F4DNFIOW9TTC1.hic": "2611370588,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3effa71b-6aa3-4265-87ba-f8d709d778d7%2F4DNFIOAA3ZEQ.hic": "3123195980,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fde75cf8b-9ce1-44fc-8b7b-ca0adea6bae9%2F4DNFIA5ID1S6.hic": "3496246968,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F714f775d-a5a4-4314-83f8-016b9d73200b%2F4DNFIZYU7V81.hic": "4245592042,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F5ca518af-6e1e-4777-b67b-0fe7f039ce58%2F4DNFIRV6PVUX.hic": "3981520466,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc29b57d5-c263-4372-b396-ab4f55682f5d%2F4DNFIMEANFBY.hic": "3999623376,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F4196d3ef-161a-4c18-a57e-005165c6b32a%2F4DNFIGLGQXLC.hic": "4105683321,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fe10828b5-9519-4ceb-81e7-7228bfd890de%2F4DNFILS2HLXC.hic": "3804942111,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Feaac88c7-9bdc-4b1e-aa9f-e675520dfffa%2F4DNFIQS8853L.hic": "5287726781,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Faab371b1-bc8d-4e83-998e-5bb977c443ca%2F4DNFIVBYCYGS.hic": "4657988157,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fdb116add-af8c-4a3b-b106-9f704ba0a175%2F4DNFIE4WWHMF.hic": "5116727268,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F033366e2-05a2-4381-9d48-90122892a9e0%2F4DNFIKDUUC3C.hic": "45638237,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F7284a446-442d-4a46-aae5-84987e75a7af%2F4DNFIJ5HIRA2.hic": "62201052,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F876649a3-6dd3-463a-8b17-5752a98a89c5%2F4DNFIXDFC7EM.hic": "69878143,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3cb4ce4d-d474-459f-8b8a-2159d8df8068%2F4DNFIO35EOVR.hic": "70153114,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F5c5612fa-18c2-47fb-8074-693b1054e254%2F4DNFI57QGL6U.hic": "54605055,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F70c1472d-cf3a-41d7-8682-cd03b7cc978d%2F4DNFI2AGEBE5.hic": "67930121,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F2bf4cce8-6e03-422b-a190-e51d4a07d501%2F4DNFI1E6NJQJ.hic": "4893181511,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F0eb3aa56-8a23-435d-a07b-8bb545e8d708%2F4DNFI2DNFM1A.hic": "60466977,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F1201682a-a223-482d-913d-3c3972b8eb65%2F4DNFIIRIHBR2.hic": "48961678,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F6aee7913-6356-43cf-affa-f2b60dd478f6%2F4DNFIKXNMT46.hic": "39095246,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F357139a3-c9a5-4343-b0a4-b41c45fd03fd%2F4DNFIRV7IRJP.hic": "70916718,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F76be3061-6259-42be-a917-19dcba41517b%2F4DNFIFX1XYKZ.hic": "229197441,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff60c348a-a62c-43c3-ac85-f6c28b5f823f%2F4DNFI64CJUZ5.hic": "112428610,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fbd0b0a14-9703-49af-bb36-2359f96d4d0e%2F4DNFIBPL2HL1.hic": "73972428,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F79ac278d-83f7-4c1f-91b2-05c8018c1426%2F4DNFIBRSIPE4.hic": "415430378,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F0c3b8141-8e67-4211-80dd-3bae88f9e537%2F4DNFIDLDVY14.hic": "112747303,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F2ae703d2-d85c-4ac4-9ce1-14d653927675%2F4DNFI4R1II4P.hic": "210565448,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F76e641af-90be-49f8-b126-12c20f856159%2F4DNFINMLRY95.hic": "1590865292,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3b416382-ae5d-469f-9e9a-85a3e2ce9793%2F4DNFI8KBXYNL.hic": "4626496956,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fa27589a6-86b2-43a2-8218-1f2232d551e6%2F4DNFI53R5IKA.hic": "1536016455,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fdd3999f5-b36e-4154-a6b9-446656959a3a%2F4DNFIAWVDQ8C.hic": "2210273411,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc377953b-0e61-426b-a905-abab2d5a3002%2F4DNFI9VXTBE2.hic": "3384365692,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F2dbe0377-1db2-4aae-af2b-d87dff728035%2F4DNFIT96Z365.hic": "7692311974,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fdcfcb009-f006-4ab8-a4c7-af72be58c12c%2F4DNFITUOMFUQ.hic": "6592120312,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F67f9073d-b2c5-474e-b3d5-7d72cde555cd%2F4DNFIHLQKDN8.hic": "2647703964,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F76968cc8-fb9f-485b-85b2-c9289067194b%2F4DNFIL9M97T2.hic": "6186798917,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F87d9330b-8d2c-4e9d-85bb-02e572de7a68%2F4DNFIDWGZLHX.hic": "4379708168,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ffc01b381-3665-4225-88ee-2e5e9ecb7324%2F4DNFIMEG1QIC.hic": "3587146533,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3144a03c-15c3-4bf9-95f8-ffad2640a1bf%2F4DNFIWSB66VX.hic": "1529739069,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd7d3aac0-ba66-494b-ba0c-147631084b98%2F4DNFIH7TH4MF.hic": "6896300679,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F4b13bd19-fbd1-4c68-8855-4f0158d1ce47%2F4DNFIHKWIZ9T.hic": "1954878455,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3d04e286-30d4-4add-a806-7a929d36419e%2F4DNFIZBBX795.hic": "1350142414,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Faa26f261-a88a-4cac-9118-ff8e90ab6f61%2F4DNFI9ZWZ5BS.hic": "3410552807,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F24e516ce-0b49-4476-b818-cc96471d8765%2F4DNFIPAI8XB5.hic": "4168518737,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fac3b06b5-46d4-4c1e-97e9-9a4f353473a7%2F4DNFI1OUWFSC.hic": "10766406904,21916", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F76c6aa27-895f-4e82-8ed8-7a85aca84490%2F4DNFIX4PJKXZ.hic": "1463157350,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fe6fbe03a-997b-4d72-a3cc-f1ed7bd88a92%2F4DNFIZGCA8AH.hic": "1597664180,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F61d99a87-4ec6-4116-be99-b483999641c4%2F4DNFI5CGQ46V.hic": "2870576870,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F271ea8cd-53b9-44c9-9fff-1bb5c444b54c%2F4DNFIOCW5AEM.hic": "2463600138,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fa98ca64a-861a-4a8c-92e9-586af457b1fb%2F4DNFI1UEG1HD.hic": "22480709268,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F5809b32e-0aea-4cf5-a174-cf162d591a35%2F4DNFI9YAVTI1.hic": "3141182061,25900" -}; - -/* - * The MIT License (MIT) - * - * Copyright (c) 2016-2017 The Regents of the University of California - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and - * associated documentation files (the "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the - * following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING - * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - */ - -class LocusGoto { - - constructor(browser, hicNavbarContainer) { - this.browser = browser; - - const parentElement = hicNavbarContainer.querySelector("div[id$='upper-hic-nav-bar-widget-container']"); - - this.containerElement = document.createElement('div'); - this.containerElement.className = 'hic-chromosome-goto-container'; - this.containerElement.title = 'Chromosome Goto'; - parentElement.appendChild(this.containerElement); - - this.resolutionSelectorElement = document.createElement('input'); - this.resolutionSelectorElement.type = 'text'; - this.resolutionSelectorElement.placeholder = 'chr-x-axis chr-y-axis'; - this.containerElement.appendChild(this.resolutionSelectorElement); - - this.resolutionSelectorElement.addEventListener('change', (e) => { - this.browser.parseGotoInput(this.resolutionSelectorElement.value); - this.resolutionSelectorElement.blur(); - }); - - this.browser.eventBus.subscribe("LocusChange", this); - } - - receiveEvent(event) { - if (event.type === "LocusChange") { - let loci; - const state = event.data.state || this.browser.state; - const isWholeGenome = this.browser.dataset.isWholeGenome(state.chr1); - if (isWholeGenome) { - loci = 'All'; - } else { - - const { chr:chrX, start:sX, end:eX } = state.locus.x; - const strX = `${chrX}:${prettyPrint(1 + sX)}-${prettyPrint(eX)}`; - - const { chr:chrY, start:sY, end:eY } = state.locus.y; - const strY = `${chrY}:${prettyPrint(1 + sY)}-${prettyPrint(eY)}`; - - loci = `${strX} ${strY}`; - - } - this.resolutionSelectorElement.value = loci; - } - } -} - -/* - * The MIT License (MIT) - * - * Copyright (c) 2016-2017 The Regents of the University of California - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and - * associated documentation files (the "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the - * following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING - * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - */ - -class ResolutionSelector { - - constructor(browser, hicNavbarContainer) { - this.browser = browser; - - const parentElement = hicNavbarContainer.querySelector("div[id$='upper-hic-nav-bar-widget-container']"); - - this.containerElement = document.createElement('div'); - this.containerElement.className = 'hic-resolution-selector-container'; - this.containerElement.title = 'Resolution'; - parentElement.appendChild(this.containerElement); - - // label container - this.labelContainerElement = document.createElement('div'); - this.labelContainerElement.id = 'hic-resolution-label-container'; - this.containerElement.appendChild(this.labelContainerElement); - - // Resolution (kb) - this.labelElement = document.createElement('div'); - this.labelElement.textContent = 'Resolution (kb)'; - this.labelElement.style.display = 'none'; - this.labelContainerElement.appendChild(this.labelElement); - - // lock/unlock - this.resolutionLockElement = document.createElement('i'); - this.resolutionLockElement.id = 'hic-resolution-lock'; - this.resolutionLockElement.className = 'fa fa-unlock'; - this.resolutionLockElement.setAttribute('aria-hidden', 'true'); - this.labelContainerElement.appendChild(this.resolutionLockElement); - this.labelContainerElement.addEventListener('click', () => { - this.browser.resolutionLocked = !this.browser.resolutionLocked; - this.setResolutionLock(this.browser.resolutionLocked); - }); - - this.resolutionSelectorElement = document.createElement('select'); - this.resolutionSelectorElement.name = 'resolution_selector'; - this.containerElement.appendChild(this.resolutionSelectorElement); - - this.resolutionSelectorElement.addEventListener('change', () => { - const zoomIndex = parseInt(this.resolutionSelectorElement.value); - this.browser.setZoom(zoomIndex); - }); - - this.browser.eventBus.subscribe("LocusChange", this); - this.browser.eventBus.subscribe("MapLoad", this); - this.browser.eventBus.subscribe("ControlMapLoad", this); - } - - setResolutionLock(resolutionLocked) { - this.resolutionLockElement.classList.remove(resolutionLocked ? 'fa-unlock' : 'fa-lock'); - this.resolutionLockElement.classList.add(resolutionLocked ? 'fa-lock' : 'fa-unlock'); - } - - receiveEvent(event) { - const browser = this.browser; - - if (event.type === "LocusChange") { - if (event.data.resolutionChanged) { - browser.resolutionLocked = false; - this.setResolutionLock(browser.resolutionLocked); - } - - if (event.data.chrChanged !== false) { - const isWholeGenome = browser.dataset.isWholeGenome(event.data.state.chr1); - this.labelElement.textContent = isWholeGenome ? 'Resolution (mb)' : 'Resolution (kb)'; - this.updateResolutions(browser.state.zoom); - } else { - const selectedIndex = browser.state.zoom; - Array.from(this.resolutionSelectorElement.options).forEach((option, index) => { - option.selected = index === selectedIndex; - }); - } - } else if (event.type === "MapLoad") { - browser.resolutionLocked = false; - this.setResolutionLock(false); - this.updateResolutions(browser.state.zoom); - } else if (event.type === "ControlMapLoad") { - this.updateResolutions(browser.state.zoom); - } - } - - async updateResolutions(zoomIndex) { - const browser = this.browser; - const resolutions = browser.isWholeGenome() ? - [{ index: 0, binSize: browser.dataset.wholeGenomeResolution }] : - browser.getResolutions(); - this.resolutionSelectorElement.innerHTML = ''; - - resolutions.forEach(resolution => { - const binSize = resolution.binSize; - const index = resolution.index; - let divisor, unit; - if (binSize >= 1e6) { - divisor = 1e6; - unit = 'mb'; - } else if (binSize >= 1e3) { - divisor = 1e3; - unit = 'kb'; - } else { - divisor = 1; - unit = 'bp'; - } - - const pretty = `${numberFormatter$2(Math.round(binSize / divisor))} ${unit}`; - const option = document.createElement('option'); - option.dataset.resolution = binSize; - option.value = index; - option.textContent = pretty; - if (zoomIndex === index) option.selected = true; - this.resolutionSelectorElement.appendChild(option); - }); - } -} - -/* - * The MIT License (MIT) - * - * Copyright (c) 2016-2017 The Regents of the University of California - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and - * associated documentation files (the "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the - * following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING - * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - */ - -const defaultColorScaleConfig = {threshold: 2000, r: 255, g: 0, b: 0}; - -class ColorScale { - - constructor(scale) { - this.threshold = scale.threshold; - this.r = scale.r; - this.g = scale.g; - this.b = scale.b; - this.cache = []; - this.nbins = 2000; - this.binsize = this.threshold / this.nbins; - } - - setThreshold(threshold) { - this.threshold = threshold; - this.cache = []; - this.binsize = this.threshold / this.nbins; - } - - getThreshold() { - return this.threshold; - } - - setColorComponents(components) { - this.r = components.r; - this.g = components.g; - this.b = components.b; - this.cache = []; - } - - getColorComponents() { - return { - r: this.r, - g: this.g, - b: this.b - } - } - - equals(cs) { - return JSON.stringify(this) === JSON.stringify(cs); - } - - getColor(value) { - const low = 0; - const bin = Math.floor(Math.min(this.threshold, value) / this.binsize); - if (undefined === this.cache[bin]) { - const alpha = Math.floor(255 * (IGVMath$1.clamp(value, low, this.threshold) - low) / (this.threshold - low)); - this.cache[bin] = { - red: this.r, - green: this.g, - blue: this.b, - alpha, - rgbaString: `rgba(${this.r},${this.g},${this.b}, ${alpha})` - }; - } - return this.cache[bin] - } - - stringify() { - return "" + this.threshold + ',' + this.r + ',' + this.g + ',' + this.b; - } - - static parse(string) { - - var pnstr, ratioCS; - - if (string.startsWith("R:")) { - pnstr = string.substring(2).split(":"); - ratioCS = new RatioColorScale(Number.parseFloat(pnstr[0])); - ratioCS.positiveScale = foo(pnstr[1]); - ratioCS.negativeScale = foo(pnstr[2]); - return ratioCS; - } else { - return foo(string); - } - - function foo(str) { - var cs, tokens; - - tokens = str.split(","); - - cs = { - threshold: tokens[0], - r: tokens[1], - g: tokens[2], - b: tokens[3] - }; - return new ColorScale(cs); - } - } -} - -/* - * The MIT License (MIT) - * - * Copyright (c) 2016-2017 The Regents of the University of California - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and - * associated documentation files (the "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the - * following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING - * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - */ - -const defaultRatioColorScaleConfig = {threshold: 5, positive: {r: 255, g: 0, b: 0}, negative: {r: 0, g: 0, b: 255}}; - -class RatioColorScale { - - constructor(threshold) { - - this.threshold = threshold; - - this.positiveScale = new ColorScale({ - threshold: Math.log(threshold), - r: 255, - g: 0, - b: 0 - }); - this.negativeScale = new ColorScale( - { - threshold: Math.log(threshold), - r: 0, - g: 0, - b: 255 - }); - } - - setThreshold(threshold) { - this.threshold = threshold; - this.positiveScale.setThreshold(Math.log(threshold)); - this.negativeScale.setThreshold(Math.log(threshold)); - } - - getThreshold() { - return this.threshold; - } - - setColorComponents(components, plusOrMinus) { - if ('-' === plusOrMinus) { - return this.negativeScale.setColorComponents(components); - } else { - return this.positiveScale.setColorComponents(components); - } - } - - getColorComponents(plusOrMinus) { - - if ('-' === plusOrMinus) { - return this.negativeScale.getColorComponents(); - } else { - return this.positiveScale.getColorComponents(); - } - } - - getColor(score) { - - var logScore = Math.log(score); - - if (logScore < 0) { - return this.negativeScale.getColor(-logScore); - } else { - return this.positiveScale.getColor(logScore); - } - } - - stringify() { - return "R:" + this.threshold + ":" + this.positiveScale.stringify() + ":" + this.negativeScale.stringify(); - } -} - -function getLocus(dataset, state, width, height, bpPerPixel){ - - // bp/bin = (bp/pixel) * (pixel/bin) = bp - const bpPerBin = bpPerPixel * state.pixelSize; - - // bp = bin * bp / bin = bp - const xStartBP = 1 + Math.round(state.x * bpPerBin); - const yStartBP = 1 + Math.round(state.y * bpPerBin); - - const chromosome1 = dataset.chromosomes[state.chr1]; - const chromosome2 = dataset.chromosomes[state.chr2]; - - // bp = (pixel * bin/pixel) * (bp/bin) - // bp = bin * bp/bin = bp - const widthBP = Math.round(bpPerPixel * width); - const heightBP = Math.round(bpPerPixel * height); - - // bp = bp - const xEndBP = Math.min(chromosome1.size, widthBP + xStartBP - 1); - const yEndBP = Math.min(chromosome2.size, heightBP + yStartBP - 1); - - return { xStartBP, yStartBP, xEndBP, yEndBP, chromosome1, chromosome2, pixelSize:state.pixelSize } - -} - -/* - * The MIT License (MIT) - * - * Copyright (c) 2016-2017 The Regents of the University of California - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and - * associated documentation files (the "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the - * following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING - * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - */ - -const DRAG_THRESHOLD = 2; -const DOUBLE_TAP_DIST_THRESHOLD = 20; -const DOUBLE_TAP_TIME_THRESHOLD = 300; - -const imageTileDimension = 685; - -const doLegacyTrack2DRendering = false; - -class ContactMatrixView { - - constructor(browser, viewportElement, sweepZoom, scrollbarWidget, colorScale, ratioColorScale, backgroundColor) { - this.browser = browser; - this.viewportElement = viewportElement; - this.sweepZoom = sweepZoom; - this.scrollbarWidget = scrollbarWidget; - - // Set initial color scales. These might be overridden/adjusted via parameters - this.colorScale = colorScale; - this.ratioColorScale = ratioColorScale; - // this.diffColorScale = new RatioColorScale(100, false); - - this.backgroundColor = backgroundColor; - this.backgroundRGBString = IGVColor$1.rgbColor(backgroundColor.r, backgroundColor.g, backgroundColor.b); - - this.canvasElement = viewportElement.querySelector('canvas'); - this.ctx = this.canvasElement.getContext('2d'); - - this.faSpinnerElement = viewportElement.querySelector('.fa-spinner'); - this.spinnerCount = 0; - - this.xGuideElement = viewportElement.querySelector("div[id$='-x-guide']"); - this.yGuideElement = viewportElement.querySelector("div[id$='-y-guide']"); - - this.displayMode = 'A'; - this.imageTileCache = {}; - this.imageTileCacheKeys = []; - this.imageTileCacheLimit = 8; // 8 is the minimum number required to support A/B cycling - this.colorScaleThresholdCache = {}; - - this.browser.eventBus.subscribe("NormalizationChange", this); - this.browser.eventBus.subscribe("TrackLoad2D", this); - this.browser.eventBus.subscribe("TrackState2D", this); - this.browser.eventBus.subscribe("MapLoad", this); - this.browser.eventBus.subscribe("ControlMapLoad", this); - this.browser.eventBus.subscribe("ColorChange", this); - - this.drawsInProgress = new Set(); - } - - setBackgroundColor(rgb) { - this.backgroundColor = rgb; - this.backgroundRGBString = IGVColor$1.rgbColor(rgb.r, rgb.g, rgb.b); - this.update(); - } - - stringifyBackgroundColor() { - return `${this.backgroundColor.r},${this.backgroundColor.g},${this.backgroundColor.b}` - } - - static parseBackgroundColor(rgbString) { - const [r, g, b] = rgbString.split(",").map(str => parseInt(str)); - return {r, g, b} - } - - setColorScale(colorScale) { - - switch (this.displayMode) { - case 'AOB': - case 'BOA': - this.ratioColorScale = colorScale; - break - case 'AMB': - this.diffColorScale = colorScale; - break - default: - this.colorScale = colorScale; - } - this.colorScaleThresholdCache[colorScaleKey(this.browser.state, this.displayMode)] = colorScale.threshold; - } - - async setColorScaleThreshold(threshold) { - this.getColorScale().setThreshold(threshold); - this.colorScaleThresholdCache[colorScaleKey(this.browser.state, this.displayMode)] = threshold; - this.imageTileCache = {}; - await this.update(); - } - - getColorScale() { - switch (this.displayMode) { - case 'AOB': - case 'BOA': - return this.ratioColorScale - case 'AMB': - return this.diffColorScale - default: - return this.colorScale - } - } - - async setDisplayMode(mode) { - this.displayMode = mode; - this.clearImageCaches(); - await this.update(); - } - - clearImageCaches() { - this.imageTileCache = {}; - this.imageTileCacheKeys = []; - } - - getViewDimensions() { - return { - width: this.viewportElement.offsetWidth, - height: this.viewportElement.offsetHeight - }; - } - - async receiveEvent(event) { - if (event.type === "MapLoad" || event.type === "ControlMapLoad") { - // Don't enable mouse actions until we have a dataset. - if (!this.mouseHandlersEnabled) { - this.addTouchHandlers(this.viewportElement); - this.addMouseHandlers(this.viewportElement); - this.mouseHandlersEnabled = true; - } - this.clearImageCaches(); - this.colorScaleThresholdCache = {}; - } else { - if (event.type !== "LocusChange") { - this.clearImageCaches(); - } - this.update(); - } - } - - async update() { - - if (this.disableUpdates) return // This flag is set during browser startup - - await this.repaint(); - - if (this.browser.dataset && false === doLegacyTrack2DRendering){ - await this.render2DTracks(this.browser.tracks2D, this.browser.dataset, this.browser.state); - } - - } - - async repaint() { - if (!this.browser.dataset) return; - - const viewportWidth = this.viewportElement.offsetWidth; - const viewportHeight = this.viewportElement.offsetHeight; - const canvasWidth = this.canvasElement.width; - const canvasHeight = this.canvasElement.height; - - if (canvasWidth !== viewportWidth || canvasHeight !== viewportHeight) { - this.canvasElement.width = viewportWidth; - this.canvasElement.height = viewportHeight; - this.canvasElement.setAttribute('width', viewportWidth); - this.canvasElement.setAttribute('height', viewportHeight); - } - - const { state, dataset, controlDataset } = this.browser; - let ds = dataset, dsControl = null, zdControl = null; - let zoom = state.zoom, controlZoom; - - switch (this.displayMode) { - case 'B': - zoom = getBZoomIndex(state.zoom); - ds = controlDataset; - break; - case 'AOB': - case 'AMB': - controlZoom = getBZoomIndex(state.zoom); - dsControl = controlDataset; - break; - case 'BOA': - zoom = getBZoomIndex(state.zoom); - controlZoom = state.zoom; - ds = controlDataset; - dsControl = dataset; - break; - } - - const matrix = await ds.getMatrix(state.chr1, state.chr2); - const zd = matrix.getZoomDataByIndex(zoom, "BP"); - - if (dsControl) { - const matrixControl = await dsControl.getMatrix(state.chr1, state.chr2); - zdControl = matrixControl.getZoomDataByIndex(controlZoom, "BP"); - } - - const pixelSizeInt = Math.max(1, Math.floor(state.pixelSize)); - const widthInBins = viewportWidth / pixelSizeInt; - const heightInBins = viewportHeight / pixelSizeInt; - const blockCol1 = Math.floor(state.x / imageTileDimension); - const blockCol2 = Math.floor((state.x + widthInBins) / imageTileDimension); - const blockRow1 = Math.floor(state.y / imageTileDimension); - const blockRow2 = Math.floor((state.y + heightInBins) / imageTileDimension); - - if (state.normalization !== "NONE") { - if (!ds.hasNormalizationVector(state.normalization, zd.chr1.name, zd.zoom.unit, zd.zoom.binSize)) { - Alert.presentAlert(`Normalization option ${state.normalization} unavailable at this resolution.`); - this.browser.eventBus.post(new HICEvent("NormalizationExternalChange", "NONE")); - state.normalization = "NONE"; - } - } - - await this.checkColorScale(ds, zd, blockRow1, blockRow2, blockCol1, blockCol2, state.normalization); - - this.ctx.clearRect(0, 0, viewportWidth, viewportHeight); - for (let r = blockRow1; r <= blockRow2; r++) { - for (let c = blockCol1; c <= blockCol2; c++) { - const tile = await this.getImageTile(ds, dsControl, zd, zdControl, r, c, state); - if (tile.image) this.paintTile(tile); - } - } - - this.genomicExtent = { - chr1: state.chr1, - chr2: state.chr2, - x: state.x * zd.zoom.binSize, - y: state.y * zd.zoom.binSize, - w: viewportWidth * zd.zoom.binSize / state.pixelSize, - h: viewportHeight * zd.zoom.binSize / state.pixelSize - }; - - function getBZoomIndex(zoom) { - const binSize = dataset.getBinSizeForZoomIndex(zoom); - if (!binSize) throw new Error(`Invalid zoom (resolution) index: ${zoom}`); - - const bZoom = controlDataset.getZoomIndexForBinSize(binSize); - if (bZoom < 0) throw new Error(`Invalid binSize for "B" map: ${binSize}`); - - return bZoom; - } - } - - /** - * This is where the image tile is actually drawn, if not in the cache - * - * @param ds - * @param dsControl - * @param zd - * @param zdControl - * @param row - * @param column - * @param state - * @returns {Promise<{image: HTMLCanvasElement, column: *, row: *, blockBinCount}|{image, inProgress: boolean, column: *, row: *, blockBinCount}|*>} - */ - async getImageTile(ds, dsControl, zd, zdControl, row, column, state) { - - const key = `${zd.chr1.name}_${zd.chr2.name}_${zd.zoom.binSize}_${zd.zoom.unit}_${row}_${column}_${state.normalization}_${this.displayMode}`; - - if (this.imageTileCache.hasOwnProperty(key)) { - return this.imageTileCache[key] - - } else { - if (this.drawsInProgress.has(key)) { - //console.log("In progress") - const imageSize = imageTileDimension; - const image = inProgressTile(imageSize); - return { - row: row, - column: column, - blockBinCount: imageTileDimension, - image: image, - inProgress: true - } // TODO return an image at a coarser resolution if avaliable - - } - this.drawsInProgress.add(key); - - try { - this.startSpinner(); - const sameChr = zd.chr1.index === zd.chr2.index; - const transpose = sameChr && row < column; - const averageCount = zd.averageCount; - const ctrlAverageCount = zdControl ? zdControl.averageCount : 1; - const averageAcrossMapAndControl = (averageCount + ctrlAverageCount) / 2; - - const imageSize = imageTileDimension; - const image = document.createElement('canvas'); - image.width = imageSize; - image.height = imageSize; - const ctx = image.getContext('2d'); - //ctx.clearRect(0, 0, image.width, image.height); - - // Get blocks - const widthInBP = imageTileDimension * zd.zoom.binSize; - const x0bp = column * widthInBP; - const region1 = {chr: zd.chr1.name, start: x0bp, end: x0bp + widthInBP}; - const y0bp = row * widthInBP; - const region2 = {chr: zd.chr2.name, start: y0bp, end: y0bp + widthInBP}; - const records = await ds.getContactRecords(state.normalization, region1, region2, zd.zoom.unit, zd.zoom.binSize); - let cRecords; - if (zdControl) { - cRecords = await dsControl.getContactRecords(state.normalization, region1, region2, zdControl.zoom.unit, zdControl.zoom.binSize); - } - - if (records.length > 0) { - - const controlRecords = {}; - if ('AOB' === this.displayMode || 'BOA' === this.displayMode || 'AMB' === this.displayMode) { - for (let record of cRecords) { - controlRecords[record.getKey()] = record; - } - } - - let id = ctx.getImageData(0, 0, image.width, image.height); - - - const x0 = transpose ? row * imageTileDimension : column * imageTileDimension; - const y0 = transpose ? column * imageTileDimension : row * imageTileDimension; - for (let i = 0; i < records.length; i++) { - - const rec = records[i]; - let x = Math.floor((rec.bin1 - x0)); - let y = Math.floor((rec.bin2 - y0)); - - if (transpose) { - const t = y; - y = x; - x = t; - } - - let rgba; - switch (this.displayMode) { - - case 'AOB': - case 'BOA': - let key = rec.getKey(); - let controlRec = controlRecords[key]; - if (!controlRec) { - continue // Skip - } - let score = (rec.counts / averageCount) / (controlRec.counts / ctrlAverageCount); - - rgba = this.ratioColorScale.getColor(score); - - break - - case 'AMB': - key = rec.getKey(); - controlRec = controlRecords[key]; - if (!controlRec) { - continue // Skip - } - score = averageAcrossMapAndControl * ((rec.counts / averageCount) - (controlRec.counts / ctrlAverageCount)); - - rgba = this.diffColorScale.getColor(score); - - break - - default: // Either 'A' or 'B' - rgba = this.colorScale.getColor(rec.counts); - } - - // TODO -- verify that this bitblting is faster than fillRect - setPixel(id, x, y, rgba.red, rgba.green, rgba.blue, rgba.alpha); - if (sameChr && row === column) { - setPixel(id, y, x, rgba.red, rgba.green, rgba.blue, rgba.alpha); - } - - } - - ctx.putImageData(id, 0, 0); - } - - - if (true === doLegacyTrack2DRendering) ; // if (true === doLegacyTrack2DRendering) - - // Uncomment to reveal tile boundaries for debugging. - // ctx.strokeStyle = "rgb(255,255,255)" - // ctx.strokeStyle = "pink" - // ctx.strokeRect(0, 0, image.width - 1, image.height - 1) - - const imageTile = { row, column, blockBinCount: imageTileDimension, image }; - - if (this.imageTileCacheLimit > 0) { - if (this.imageTileCacheKeys.length > this.imageTileCacheLimit) { - delete this.imageTileCache[this.imageTileCacheKeys[0]]; - this.imageTileCacheKeys.shift(); - } - this.imageTileCache[key] = imageTile; - - } - - return imageTile - - } finally { - this.drawsInProgress.delete(key); - this.stopSpinner(); - } - } - - - function setPixel(imageData, x, y, r, g, b, a) { - const index = (x + y * imageData.width) * 4; - imageData.data[index + 0] = r; - imageData.data[index + 1] = g; - imageData.data[index + 2] = b; - imageData.data[index + 3] = a; - } - - } - - /** - * Return a promise to adjust the color scale, if needed. This function might need to load the contact - * data to computer scale. - * - * @param zd - * @param row1 - * @param row2 - * @param col1 - * @param col2 - * @param normalization - * @returns {*} - */ - async checkColorScale(ds, zd, row1, row2, col1, col2, normalization) { - - const colorKey = colorScaleKey(this.browser.state, this.displayMode); // This doesn't feel right, state should be an argument - if ('AOB' === this.displayMode || 'BOA' === this.displayMode) { - return this.ratioColorScale // Don't adjust color scale for A/B. - } - - if (this.colorScaleThresholdCache[colorKey]) { - const changed = this.colorScale.threshold !== this.colorScaleThresholdCache[colorKey]; - this.colorScale.setThreshold(this.colorScaleThresholdCache[colorKey]); - if (changed) { - this.browser.eventBus.post(HICEvent("ColorScale", this.colorScale)); - } - return this.colorScale - } else { - try { - const widthInBP = imageTileDimension * zd.zoom.binSize; - const x0bp = col1 * widthInBP; - const xWidthInBP = (col2 - col1 + 1) * widthInBP; - const region1 = {chr: zd.chr1.name, start: x0bp, end: x0bp + xWidthInBP}; - const y0bp = row1 * widthInBP; - const yWidthInBp = (row2 - row1 + 1) * widthInBP; - const region2 = {chr: zd.chr2.name, start: y0bp, end: y0bp + yWidthInBp}; - const records = await ds.getContactRecords(normalization, region1, region2, zd.zoom.unit, zd.zoom.binSize, true); - - let s = computePercentile(records, 95); - if (!isNaN(s)) { // Can return NaN if all blocks are empty - if (0 === zd.chr1.index) s *= 4; // Heuristic for whole genome view - this.colorScale = new ColorScale(this.colorScale); - this.colorScale.setThreshold(s); - this.computeColorScale = false; - this.browser.eventBus.post(HICEvent("ColorScale", this.colorScale)); - this.colorScaleThresholdCache[colorKey] = s; - } - - return this.colorScale - } finally { - this.stopSpinner(); - } - - - } - - } - - async zoomIn() { - const state = this.browser.state; - const viewportWidth = this.viewportElement.offsetWidth; - const viewportHeight = this.viewportElement.offsetHeight; - const matrices = await getMatrices.call(this, state.chr1, state.chr2); - - const matrix = matrices[0]; - - if (matrix) { - const unit = "BP"; - const zd = await matrix.getZoomDataByIndex(state.zoom, unit); - const newGenomicExtent = { - x: state.x * zd.zoom.binSize, - y: state.y * zd.zoom.binSize, - w: viewportWidth * zd.zoom.binSize / state.pixelSize, - h: viewportHeight * zd.zoom.binSize / state.pixelSize - }; - - // Zoom out not supported - if (newGenomicExtent.w > this.genomicExtent.w) return; - - const sx = ((newGenomicExtent.x - this.genomicExtent.x) / this.genomicExtent.w) * viewportWidth; - const sy = ((newGenomicExtent.y - this.genomicExtent.y) / this.genomicExtent.w) * viewportHeight; - const sWidth = (newGenomicExtent.w / this.genomicExtent.w) * viewportWidth; - const sHeight = (newGenomicExtent.h / this.genomicExtent.h) * viewportHeight; - const img = this.canvasElement; - - const backCanvas = document.createElement('canvas'); - backCanvas.width = img.width; - backCanvas.height = img.height; - const backCtx = backCanvas.getContext('2d'); - backCtx.drawImage(img, sx, sy, sWidth, sHeight, 0, 0, viewportWidth, viewportHeight); - - this.ctx.clearRect(0, 0, viewportWidth, viewportHeight); - this.ctx.drawImage(backCanvas, 0, 0); - } - } - - paintTile({image, row, column, blockBinCount}) { - - const x0 = blockBinCount * column; - const y0 = blockBinCount * row; - - const {x, y, pixelSize} = this.browser.state; - //const pixelSizeInt = Math.max(1, Math.floor(pixelSize)) - const offsetX = (x0 - x) * pixelSize; - const offsetY = (y0 - y) * pixelSize; - - const scale = pixelSize; // / pixelSizeInt - const scaledWidth = image.width * scale; - const scaledHeight = image.height * scale; - - if (offsetX <= this.viewportElement.offsetWidth && offsetX + scaledWidth >= 0 && offsetY <= this.viewportElement.offsetHeight && offsetY + scaledHeight >= 0) { - this.ctx.fillStyle = this.backgroundRGBString; - this.ctx.fillRect(offsetX, offsetY, scaledWidth, scaledHeight); - if (scale === 1) { - this.ctx.drawImage(image, offsetX, offsetY); - } else { - this.ctx.drawImage(image, offsetX, offsetY, scaledWidth, scaledHeight); - } - // Debugging aid, uncomment to see tile boundaries - //this.ctx.strokeRect(offsetX, offsetY, scaledWidth, scaledHeight) - //this.ctx.strokeText(`${row} ${column}`, offsetX, offsetY); - } - } - - startSpinner() { - if (this.browser.isLoadingHICFile && this.browser.userInteractionShield) { - this.browser.userInteractionShield.style.display = 'block'; - } - this.faSpinnerElement.style.display = 'inline-block'; - this.spinnerCount++; - } - - stopSpinner() { - this.spinnerCount--; - if (this.spinnerCount === 0) { - this.faSpinnerElement.style.display = 'none'; - } - this.spinnerCount = Math.max(0, this.spinnerCount); // This should not be necessary - } - - addMouseHandlers(viewportElement) { - - let startX = 0; - let startY = 0; - let currentX = 0; - let currentY = 0; - - let isMouseDown = false; - let isSweepZooming = false; - let mouseDown; - let mouseLast; - let mouseOver; - - const panMouseUpOrMouseOut = () => { - if (this.isDragging) { - this.isDragging = false; - this.browser.eventBus.post(HICEvent("DragStopped")); - } - isMouseDown = false; - mouseDown = mouseLast = undefined; - }; - - this.isDragging = false; - - if (!this.browser.isMobile) { - - viewportElement.addEventListener('mousedown', (e) => { - e.preventDefault(); - e.stopPropagation(); - - if (this.browser.menuElement?.style.display === 'block') { - this.browser.hideMenu(); - } - - mouseLast = { x: e.offsetX, y: e.offsetY }; - mouseDown = { x: e.offsetX, y: e.offsetY }; - - if (e.altKey) { - isSweepZooming = true; - - const { top, left } = viewportElement.getBoundingClientRect(); - startX = e.clientX - left; - startY = e.clientY - top; - - this.sweepZoom.initialize(startX, startY); - } - - isMouseDown = true; - }); - - viewportElement.addEventListener('mousemove', (e) => { - - e.preventDefault(); - e.stopPropagation(); - - const coords = - { - x: e.offsetX, - y: e.offsetY - }; - - const { top, left } = getOffset(viewportElement); - - const xy = - { - x: e.pageX - left, - y: e.pageY - top - }; - - const { width, height } = viewportElement.getBoundingClientRect(); - xy.xNormalized = xy.x / width; - xy.yNormalized = xy.y / height; - - this.browser.eventBus.post(HICEvent("UpdateContactMapMousePosition", xy, false)); - - if (this.willShowCrosshairs) { - this.browser.updateCrosshairs(xy); - this.browser.showCrosshairs(); - } - - if (isMouseDown) { - if (isSweepZooming) { - - const { left, top } = viewportElement.getBoundingClientRect(); - currentX = e.clientX - left; - currentY = e.clientY - top; - const width = Math.abs(currentX - startX); - const height = Math.abs(currentY - startY); - - const config = - { - left: `${Math.min(startX, currentX)}px`, - top: `${Math.min(startY, currentY)}px`, - width: `${width}px`, - height: `${height}px`, - }; - - - this.sweepZoom.update(config); - - } else if (mouseDown.x && Math.abs(coords.x - mouseDown.x) > DRAG_THRESHOLD) { - this.isDragging = true; - const dx = mouseLast.x - coords.x; - const dy = mouseLast.y - coords.y; - this.browser.shiftPixels(dx, dy); - } - mouseLast = coords; - } - }); - - viewportElement.addEventListener('mouseup', panMouseUpOrMouseOut); - - viewportElement.addEventListener('dblclick', (e) => { - e.preventDefault(); - e.stopPropagation(); - const mouseX = e.offsetX; - const mouseY = e.offsetY; - this.browser.zoomAndCenter(1, mouseX, mouseY); - }); - - viewportElement.addEventListener('mouseover', () => mouseOver = true); - viewportElement.addEventListener('mouseout', () => mouseOver = undefined); - - - viewportElement.addEventListener('mouseleave', () => { - this.browser.layoutController.xAxisRuler.unhighlightWholeChromosome(); - this.browser.layoutController.yAxisRuler.unhighlightWholeChromosome(); - panMouseUpOrMouseOut(); - }); - - document.addEventListener('keydown', (e) => { - if (!this.willShowCrosshairs && mouseOver && e.shiftKey) { - this.willShowCrosshairs = true; - this.browser.eventBus.post(HICEvent('DidShowCrosshairs', 'DidShowCrosshairs', false)); - } - }); - - document.addEventListener('keyup', () => { - this.browser.hideCrosshairs(); - this.willShowCrosshairs = undefined; - this.browser.eventBus.post(HICEvent('DidHideCrosshairs', 'DidHideCrosshairs', false)); - }); - - document.addEventListener('mouseup', (e) => { - e.preventDefault(); - e.stopPropagation(); - - if (isSweepZooming) { - isSweepZooming = false; - - const sweepRect = - { - xPixel: Math.min(startX, currentX), - yPixel: Math.min(startY, currentY), - width: Math.abs(currentX - startX), - height: Math.abs(currentY - startY) - }; - - this.sweepZoom.commit(sweepRect); - } - }); - } - } - - /** - * Add touch handlers. Touches are mapped to one of the following application level events - * - double tap, equivalent to double click - * - move - * - pinch - * - * @param $viewport - */ - - addTouchHandlers(viewportElement) { - let lastTouch, pinch; - - const translateTouchCoordinates = (e, target) => { - const rect = target.getBoundingClientRect(); - return { - x: e.pageX - rect.left, - y: e.pageY - rect.top - }; - }; - - viewportElement.ontouchstart = (ev) => { - ev.preventDefault(); - ev.stopPropagation(); - - let touchCoords = translateTouchCoordinates(ev.targetTouches[0], viewportElement); - let offsetX = touchCoords.x; - let offsetY = touchCoords.y; - const count = ev.targetTouches.length; - const timeStamp = ev.timeStamp || Date.now(); - let resolved = false; - - if (count === 2) { - touchCoords = translateTouchCoordinates(ev.targetTouches[1], viewportElement); - offsetX = (offsetX + touchCoords.x) / 2; - offsetY = (offsetY + touchCoords.y) / 2; - } - - if (lastTouch && (timeStamp - lastTouch.timeStamp < DOUBLE_TAP_TIME_THRESHOLD) && count > 1 && lastTouch.count === 1) { - lastTouch = { x: offsetX, y: offsetY, timeStamp, count }; - return; - } - - if (lastTouch && (timeStamp - lastTouch.timeStamp < DOUBLE_TAP_TIME_THRESHOLD)) { - const dx = lastTouch.x - offsetX; - const dy = lastTouch.y - offsetY; - const dist = Math.hypot(dx, dy); - const direction = (lastTouch.count === 2 || count === 2) ? -1 : 1; - - if (dist < DOUBLE_TAP_DIST_THRESHOLD) { - this.browser.zoomAndCenter(direction, offsetX, offsetY); - lastTouch = undefined; - resolved = true; - } - } - - if (!resolved) { - lastTouch = { x: offsetX, y: offsetY, timeStamp, count }; - } - }; - - viewportElement.ontouchmove = throttle((ev) => { - ev.preventDefault(); - ev.stopPropagation(); - - if (ev.targetTouches.length === 2) { - const touchCoords1 = translateTouchCoordinates(ev.targetTouches[0], viewportElement); - const touchCoords2 = translateTouchCoordinates(ev.targetTouches[1], viewportElement); - - const t = { - x1: touchCoords1.x, - y1: touchCoords1.y, - x2: touchCoords2.x, - y2: touchCoords2.y - }; - - pinch ? (pinch.end = t) : (pinch = { start: t }); - } else { - const touchCoords = translateTouchCoordinates(ev.targetTouches[0], viewportElement); - const offsetX = touchCoords.x; - const offsetY = touchCoords.y; - - if (lastTouch) { - const dx = lastTouch.x - offsetX; - const dy = lastTouch.y - offsetY; - if (!isNaN(dx) && !isNaN(dy)) { - this.isDragging = true; - this.browser.shiftPixels(dx, dy); - } - } - - lastTouch = { - x: offsetX, - y: offsetY, - timeStamp: ev.timeStamp || Date.now(), - count: ev.targetTouches.length - }; - } - }, 50); - - viewportElement.ontouchend = (ev) => { - ev.preventDefault(); - ev.stopPropagation(); - - if (pinch && pinch.end) { - const { start, end } = pinch; - const dxStart = start.x2 - start.x1; - const dyStart = start.y2 - start.y1; - const dxEnd = end.x2 - end.x1; - const dyEnd = end.y2 - end.y1; - - const distStart = Math.hypot(dxStart, dyStart); - const distEnd = Math.hypot(dxEnd, dyEnd); - const scale = distEnd / distStart; - - const anchorX = (start.x1 + start.x2) / 2; - const anchorY = (start.y1 + start.y2) / 2; - - if (scale < 0.8 || scale > 1.2) { - lastTouch = undefined; - this.browser.pinchZoom(anchorX, anchorY, scale); - } - } else if (this.isDragging) { - this.isDragging = false; - this.browser.eventBus.post(HICEvent("DragStopped")); - } - - pinch = undefined; - }; - } - - async render2DTracks(track2DList, dataset, state) { - - const matrix = await dataset.getMatrix(state.chr1, state.chr2); - const zoomData = matrix.getZoomDataByIndex(state.zoom, 'BP'); - - const { width, height } = this.getViewDimensions(); - const bpPerPixel = zoomData.zoom.binSize/state.pixelSize; - const { xStartBP, yStartBP, xEndBP, yEndBP } = getLocus(dataset, state, width, height, bpPerPixel); - - zoomData.chr1.name; - zoomData.chr2.name; - - zoomData.chr1.index === zoomData.chr2.index; - - this.ctx.save(); - this.ctx.lineWidth = 2; - - const renderFeatures = (xS, xE, yS, yE) => { - - if (xE < xStartBP || xS > xEndBP || yE < yStartBP || yS > yEndBP) ; else { - const w = Math.max(1, (xE - xS)/bpPerPixel); - const h = Math.max(1, (yE - yS)/bpPerPixel); - const x = Math.floor((xS - xStartBP)/bpPerPixel); - const y = Math.floor((yS - yStartBP)/bpPerPixel); - this.ctx.strokeRect(x, y, w, h); - } - - }; - - const renderLowerFeatures = (track2D, features) => { - for (const { chr1, x1:xS, x2:xE, y1:yS, y2:yE, color } of features) { - - this.ctx.strokeStyle = track2D.color || color; - renderFeatures(xS, xE, yS, yE); - } - }; - - const renderUpperFeatures = (track2D, features) => { - for (const { chr1, x1:yS, x2:yE, y1:xS, y2:xE, color } of features) { - - this.ctx.strokeStyle = track2D.color || color; - renderFeatures(xS, xE, yS, yE); - } - }; - - for (const track2D of track2DList) { - - if (false === track2D.isVisible) { - continue - } - - const features = track2D.getFeatures(zoomData.chr1.name, zoomData.chr1.name); - - if (features) { - - if ('COLLAPSED' === track2D.displayMode || undefined === track2D.displayMode) { - renderLowerFeatures(track2D, features); - renderUpperFeatures(track2D, features); - } else if ('lower' === track2D.displayMode) { - renderLowerFeatures(track2D, features); - } else if ('upper' === track2D.displayMode) { - renderUpperFeatures(track2D, features); - } - - } - - - } - - this.ctx.restore(); - - } -} - -ContactMatrixView.defaultBackgroundColor = {r: 255, g: 255, b: 255}; - -function colorScaleKey(state, displayMode) { - return "" + state.chr1 + "_" + state.chr2 + "_" + state.zoom + "_" + state.normalization + "_" + displayMode -} - -/** - * Returns a promise for an image tile - * - * @param zd - * @param row - * @param column - * @param state - * @returns {*} - */ - -const inProgressCache = {}; - -function inProgressTile(imageSize) { - - let image = inProgressCache[imageSize]; - if (!image) { - image = document.createElement('canvas'); - image.width = imageSize; - image.height = imageSize; - const ctx = image.getContext('2d'); - ctx.font = '24px sans-serif'; - ctx.fillStyle = 'rgb(230, 230, 230)'; - ctx.fillRect(0, 0, image.width, image.height); - ctx.fillStyle = 'black'; - for (let i = 100; i < imageSize; i += 300) { - for (let j = 100; j < imageSize; j += 300) { - ctx.fillText('Loading...', i, j); - } - } - inProgressCache[imageSize] = image; - } - return image -} - -function getMatrices(chr1, chr2) { - - var promises = []; - if ('B' === this.displayMode && this.browser.controlDataset) { - promises.push(this.browser.controlDataset.getMatrix(chr1, chr2)); - } else { - promises.push(this.browser.dataset.getMatrix(chr1, chr2)); - if (this.displayMode && 'A' !== this.displayMode && this.browser.controlDataset) { - promises.push(this.browser.controlDataset.getMatrix(chr1, chr2)); - } - } - return Promise.all(promises) -} - -function computePercentile(records, p) { - const counts = records.map(r => r.counts); - counts.sort(function (a, b) { - return a - b - }); - const idx = Math.floor((p / 100) * records.length); - return counts[idx] - - // return HICMath.percentile(array, p); -} - -/* - * The MIT License (MIT) - * - * Copyright (c) 2016-2017 The Regents of the University of California - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and - * associated documentation files (the "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the - * following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING - * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - */ - -class ColorScaleWidget { - - constructor(browser, hicNavbarContainer) { - this.browser = browser; - - const container = hicNavbarContainer.querySelector("div[id$='lower-hic-nav-bar-widget-container']"); - - this.container = document.createElement('div'); - this.container.className = 'hic-colorscale-widget-container'; - container.appendChild(this.container); - - const { r: _r, g: _g, b: _b } = ContactMatrixView.defaultBackgroundColor; - this.mapBackgroundColorpickerButton = colorSwatch(IGVColor$1.rgbColor(_r, _g, _b)); - this.container.appendChild(this.mapBackgroundColorpickerButton); - this.backgroundColorpicker = createColorPicker(browser, this.mapBackgroundColorpickerButton); - - const { r: nr, g: ng, b: nb } = defaultRatioColorScaleConfig.negative; - this.minusButton = colorSwatch(IGVColor$1.rgbColor(nr, ng, nb)); - this.container.appendChild(this.minusButton); - this.minusColorPicker = createColorPicker(browser, this.minusButton, '-'); - this.minusButton.style.display = 'none'; - - const { r, g, b } = defaultRatioColorScaleConfig.positive; - this.plusButton = colorSwatch(IGVColor$1.rgbColor(r, g, b)); - this.container.appendChild(this.plusButton); - this.plusColorPicker = createColorPicker(browser, this.plusButton, '+'); - - this.minusButton.addEventListener('click', () => presentColorPicker(this.minusColorPicker, this.plusColorPicker, this.backgroundColorpicker)); - this.plusButton.addEventListener('click', () => presentColorPicker(this.plusColorPicker, this.minusColorPicker, this.backgroundColorpicker)); - this.mapBackgroundColorpickerButton.addEventListener('click', () => presentColorPicker(this.backgroundColorpicker, this.minusColorPicker, this.plusColorPicker)); - - this.highColorscaleInput = document.createElement('input'); - this.highColorscaleInput.type = 'text'; - this.highColorscaleInput.title = 'color scale input'; - this.container.appendChild(this.highColorscaleInput); - this.highColorscaleInput.addEventListener('change', (e) => { - const numeric = numberUnFormatter(e.target.value); - if (!isNaN(numeric)) { - browser.setColorScaleThreshold(numeric); - } - }); - - const minusIcon = createIconButton('fa-minus', 'negative threshold', () => this.highColorscaleInput.value = updateThreshold(browser, 0.5)); - this.container.appendChild(minusIcon); - - const plusIcon = createIconButton('fa-plus', 'positive threshold', () => this.highColorscaleInput.value = updateThreshold(browser, 2.0)); - this.container.appendChild(plusIcon); - - browser.eventBus.subscribe("ColorScale", (event) => { - if (event.data instanceof ColorScale) { - this.highColorscaleInput.value = event.data.threshold; - paintSwatch(this.plusButton, event.data); - } else if (event.data instanceof RatioColorScale) { - this.highColorscaleInput.value = event.data.threshold; - paintSwatch(this.minusButton, event.data.negativeScale); - paintSwatch(this.plusButton, event.data.positiveScale); - } - }); - - browser.eventBus.subscribe("DisplayMode", (event) => { - if (event.data === "AOB" || event.data === "BOA") { - this.minusButton.style.display = 'block'; - paintSwatch(this.minusButton, browser.contactMatrixView.ratioColorScale.negativeScale); - paintSwatch(this.plusButton, browser.contactMatrixView.ratioColorScale.positiveScale); - } else { - this.minusButton.style.display = 'none'; - paintSwatch(this.plusButton, browser.contactMatrixView.colorScale); - } - }); - - browser.eventBus.subscribe("MapLoad", () => { - paintSwatch(this.mapBackgroundColorpickerButton, browser.contactMatrixView.backgroundColor); - }); - } -} - -function paintSwatch(swatch, { r, g, b }) { - swatch.style.backgroundColor = IGVColor$1.rgbToHex(IGVColor$1.rgbColor(r, g, b)); -} - -function updateThreshold(browser, scaleFactor) { - const colorScale = browser.getColorScale(); - browser.setColorScaleThreshold(colorScale.getThreshold() * scaleFactor); - return numberFormatter$2(colorScale.getThreshold()); -} - -function createColorPicker(browser, parent, type) { - let defaultColors, colorHandler; - if (!type) { - const { r, g, b } = ContactMatrixView.defaultBackgroundColor; - defaultColors = [IGVColor$1.rgbToHex(IGVColor$1.rgbColor(r, g, b))]; - colorHandler = (hex) => { - parent.style.backgroundColor = hex; - const rgbString = IGVColor$1.hexToRgb(hex); - const [r, g, b] = parseRgbString(rgbString); - browser.contactMatrixView.setBackgroundColor({ r, g, b }); - }; - } else { - defaultColors = [defaultRatioColorScaleConfig.negative, defaultRatioColorScaleConfig.positive].map(({ r, g, b }) => IGVColor$1.rgbToHex(IGVColor$1.rgbColor(r, g, b))); - colorHandler = (hex) => { - parent.style.backgroundColor = hex; - const rgbString = IGVColor$1.hexToRgb(hex); - const [r, g, b] = parseRgbString(rgbString); - browser.getColorScale().setColorComponents({ r, g, b }, type); - browser.repaintMatrix(); - }; - } - return new ColorPicker({ parent, top: 64, left: 64, width: 432, defaultColors, colorHandler }); -} - -function presentColorPicker(presentable, hideableA, hideableB) { - hideableA.hide(); - hideableB.hide(); - presentable.show(); -} - -function colorSwatch(rgbString) { - const swatch = domUtils.div({ class: 'igv-ui-color-swatch' }); - swatch.style.backgroundColor = IGVColor$1.rgbToHex(rgbString); - return swatch; -} - -function createIconButton(iconClass, title, onClick) { - const icon = document.createElement('i'); - icon.className = `fa ${iconClass}`; - icon.title = title; - icon.addEventListener('click', onClick); - return icon; -} - -/* - * The MIT License (MIT) - * - * Copyright (c) 2016-2017 The Regents of the University of California - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and - * associated documentation files (the "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the - * following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING - * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - */ - -/** - * Created by dat on 3/21/17. - */ - -class ControlMapWidget { - - constructor(browser, hicNavbarContainer) { - this.browser = browser; - - const parent = hicNavbarContainer.querySelector("div[id$='lower-hic-nav-bar-widget-container']"); - - this.container = document.createElement('div'); - this.container.className = 'hic-control-map-selector-container'; - this.container.style.display = 'none'; - parent.appendChild(this.container); - - this.select = document.createElement('select'); - this.select.name = 'control_map_selector'; - this.container.appendChild(this.select); - - const toggleContainer = document.createElement('div'); - this.container.appendChild(toggleContainer); - - const cycleContainer = document.createElement('div'); - this.container.appendChild(cycleContainer); - - this.controlMapHash = new ControlMapHash(browser, this.select, toggleContainer, cycleContainer, toggleArrowsUp(), toggleArrowsDown()); - - browser.eventBus.subscribe("ControlMapLoad", () => { - this.controlMapHash.updateOptions(browser.getDisplayMode()); - this.container.style.display = 'block'; - }); - - browser.eventBus.subscribe("MapLoad", () => { - if (!browser.controlDataset) { - this.container.style.display = 'none'; - } - }); - - browser.eventBus.subscribe("DisplayMode", (event) => { - this.controlMapHash.updateOptions(event.data); - }); - } - - toggleDisplayMode() { - this.controlMapHash.toggleDisplayMode(); - } - - toggleDisplayModeCycle() { - this.controlMapHash.toggleDisplayModeCycle(); - } - - getDisplayModeCycle() { - return this.controlMapHash.cycleID; - } -} - -class ControlMapHash { - - constructor(browser, select, toggle, cycle, imgA, imgB) { - this.browser = browser; - this.select = select; - this.toggle = toggle; - this.cycle = cycle; - - this.imgA = imgA; - this.toggle.appendChild(this.imgA); - - this.imgB = imgB; - this.toggle.appendChild(this.imgB); - - this.hash = { - 'A': { title: 'A', value: 'A', other: 'B', hidden: this.imgB, shown: this.imgA }, - 'B': { title: 'B', value: 'B', other: 'A', hidden: this.imgA, shown: this.imgB }, - 'AOB': { title: 'A/B', value: 'AOB', other: 'BOA', hidden: this.imgB, shown: this.imgA }, - 'BOA': { title: 'B/A', value: 'BOA', other: 'AOB', hidden: this.imgA, shown: this.imgB } - }; - - this.select.addEventListener('change', (e) => { - this.disableDisplayModeCycle(); - this.setDisplayMode(e.target.value); - }); - - this.toggle.addEventListener('click', () => { - this.disableDisplayModeCycle(); - this.toggleDisplayMode(); - }); - - this.cycleOutline = cycleOutline(); - cycle.appendChild(this.cycleOutline); - - this.cycleSolid = cycleSolid(); - cycle.appendChild(this.cycleSolid); - this.cycleSolid.style.display = 'none'; - - cycle.addEventListener('click', () => { - this.toggleDisplayModeCycle(); - }); - - cycle.style.display = 'none'; - } - - disableDisplayModeCycle() { - if (this.cycleID) { - clearTimeout(this.cycleID); - this.cycleID = undefined; - this.cycleSolid.style.display = 'none'; - this.cycleOutline.style.display = 'block'; - } - } - - toggleDisplayModeCycle() { - if (this.cycleID) { - this.disableDisplayModeCycle(); - } else { - this.doToggle(); - this.cycleSolid.style.display = 'block'; - this.cycleOutline.style.display = 'none'; - } - } - - async doToggle() { - this.cycleID = setTimeout(async () => { - await this.toggleDisplayMode(); - this.doToggle(); - }, 2500); - } - - async toggleDisplayMode() { - const oldMode = this.browser.getDisplayMode(); - const newMode = this.hash[oldMode].other; - await this.browser.setDisplayMode(newMode); - this.hash[newMode].hidden.style.display = 'none'; - this.hash[newMode].shown.style.display = 'block'; - this.select.value = newMode; - } - - setDisplayMode(mode) { - this.hash[mode].hidden.style.display = 'none'; - this.hash[mode].shown.style.display = 'block'; - this.browser.setDisplayMode(mode); - } - - updateOptions(displayMode) { - this.imgA.style.display = 'none'; - this.imgB.style.display = 'none'; - this.select.innerHTML = ''; - - Object.keys(this.hash).forEach((key) => { - const item = this.hash[key]; - const option = document.createElement('option'); - option.value = item.value; - option.textContent = item.title; - if (displayMode === item.value) { - option.selected = true; - item.shown.style.display = 'block'; - } - this.select.appendChild(option); - }); - } -} - -function toggleArrowsUp() { - const svg = document.createElement('div'); - svg.innerHTML = '...'; // Simplified for brevity - return svg; -} - -function toggleArrowsDown() { - const svg = document.createElement('div'); - svg.innerHTML = '...'; // Simplified for brevity - return svg; -} - -function cycleOutline() { - const svg = document.createElement('div'); - svg.innerHTML = '...'; // Simplified for brevity - return svg; -} - -function cycleSolid() { - const svg = document.createElement('div'); - svg.innerHTML = '...'; // Simplified for brevity - return svg; -} - -/* - * The MIT License (MIT) - * - * Copyright (c) 2016-2017 The Regents of the University of California - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and - * associated documentation files (the "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the - * following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING - * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - */ - -/** - * Created by dat on 3/21/17. - */ -class NormalizationWidget { - - constructor(browser, hicNavBarContainer) { - this.browser = browser; - - const parent = hicNavBarContainer.querySelector("div[id$='lower-hic-nav-bar-widget-container']"); - - this.container = document.createElement('div'); - this.container.className = 'hic-normalization-selector-container'; - this.container.title = 'Normalization'; - parent.appendChild(this.container); - - let label = document.createElement('div'); - label.textContent = 'Norm'; - this.container.appendChild(label); - - this.normalizationSelector = document.createElement('select'); - this.normalizationSelector.name = 'normalization_selector'; - this.normalizationSelector.addEventListener('change', () => { - this.browser.setNormalization(this.normalizationSelector.value); - }); - this.container.appendChild(this.normalizationSelector); - - this.spinner = document.createElement('div'); - this.spinner.textContent = 'Loading ...'; - this.container.appendChild(this.spinner); - this.spinner.style.display = 'none'; - - this.browser.eventBus.subscribe("MapLoad", this); - this.browser.eventBus.subscribe("NormVectorIndexLoad", this); - this.browser.eventBus.subscribe("NormalizationFileLoad", this); - this.browser.eventBus.subscribe("NormalizationExternalChange", this); - } - - startNotReady() { - this.normalizationSelector.style.display = 'none'; - this.spinner.style.display = 'block'; - } - - stopNotReady() { - this.spinner.style.display = 'none'; - this.normalizationSelector.style.display = 'block'; - } - - receiveEvent(event) { - if ("NormVectorIndexLoad" === event.type) { - this.updateOptions(); - this.stopNotReady(); - } else if ("NormalizationFileLoad" === event.type) { - if (event.data === "start") { - this.startNotReady(); - } else { - this.stopNotReady(); - } - } else if ("NormalizationExternalChange" === event.type) { - Array.from(this.normalizationSelector.options).forEach(option => { - option.selected = option.value === event.data; - }); - } - } - - async updateOptions() { - const labels = { - NONE: 'None', - VC: 'Coverage', - VC_SQRT: 'Coverage - Sqrt', - KR: 'Balanced', - INTER_VC: 'Interchromosomal Coverage', - INTER_VC_SQRT: 'Interchromosomal Coverage - Sqrt', - INTER_KR: 'Interchromosomal Balanced', - GW_VC: 'Genome-wide Coverage', - GW_VC_SQRT: 'Genome-wide Coverage - Sqrt', - GW_KR: 'Genome-wide Balanced' - }; - - const norm = this.browser.state.normalization; - const normalizationTypes = await this.browser.getNormalizationOptions(); - if (normalizationTypes) { - this.normalizationSelector.innerHTML = ''; - normalizationTypes.forEach(normalization => { - const option = document.createElement('option'); - option.value = normalization; - option.textContent = labels[normalization] || normalization; - if (norm === normalization) { - option.selected = true; - } - this.normalizationSelector.appendChild(option); - }); - } - } -} - -/* - * The MIT License (MIT) - * - * Copyright (c) 2016-2017 The Regents of the University of California - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and - * associated documentation files (the "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the - * following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING - * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - */ - -class SweepZoom { - - constructor(browser, targetElement) { - this.browser = browser; - this.targetElement = targetElement; - - this.rulerSweeperElement = targetElement.querySelector("div[id$='-sweep-zoom-container']"); - this.rulerSweeperElement.style.display = 'none'; - - this.sweepRect = {}; - } - - initialize(startX, startY) { - this.rulerSweeperElement.style.left = `${startX}px`; - this.rulerSweeperElement.style.top = `${startY}px`; - this.rulerSweeperElement.style.width = '0px'; - this.rulerSweeperElement.style.height = '0px'; - this.rulerSweeperElement.style.display = 'block'; - } - - update({ left, top, width, height }) { - this.rulerSweeperElement.style.width = width; - this.rulerSweeperElement.style.height = height; - this.rulerSweeperElement.style.left = left; - this.rulerSweeperElement.style.top = top; - } - - commit({ xPixel, yPixel, width, height }) { - - this.rulerSweeperElement.style.display = 'none'; - - const { x, y, locus, zoom, pixelSize } = this.browser.state; - - // bp-per-bin - const bpResolution = this.browser.dataset.bpResolutions[zoom]; - - // bp = ((bin + pixel/pixel-per-bin) / bp-per-bin) - const xBP = (x + (xPixel / pixelSize)) * bpResolution; - const yBP = (y + (yPixel / pixelSize)) * bpResolution; - - const widthBP = ( width / pixelSize) * bpResolution; - const heightBP = (height / pixelSize) * bpResolution; - - this.browser.goto(locus.x.chr, Math.round(xBP), Math.round(xBP + widthBP), locus.y.chr, Math.round(yBP), Math.round(yBP + heightBP)); - - } -} - -/* - * The MIT License (MIT) - * - * Copyright (c) 2016-2017 The Regents of the University of California - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and - * associated documentation files (the "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the - * following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING - * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - */ - -class ScrollbarWidget { - - constructor(browser, xAxisScrollbarContainerElement, yAxisScrollbarContainerElement) { - this.browser = browser; - this.isDragging = false; - - // x-axis - this.xAxisScrollbarContainerElement = xAxisScrollbarContainerElement; - this.xAxisScrollbarElement = xAxisScrollbarContainerElement.querySelector("div[id$='-x-axis-scrollbar']"); - this.xLabelElement = this.xAxisScrollbarElement.querySelector('div'); - this.xLabelElement.textContent = ''; - - // y-axis - this.yAxisScrollbarContainerElement = yAxisScrollbarContainerElement; - this.yAxisScrollbarElement = yAxisScrollbarContainerElement.querySelector("div[id$='-y-axis-scrollbar']"); - this.yLabelElement = this.yAxisScrollbarElement.querySelector('.scrollbar-label-rotation-in-place'); - this.yLabelElement.textContent = ''; - - this.browser.eventBus.subscribe("LocusChange", this); - } - - receiveEvent(event) { - - if (!this.isDragging && event.type === "LocusChange") { - const { state } = event.data; - const { dataset } = this.browser; - - if (state.chr1 === 0) { - this.xAxisScrollbarElement.style.display = 'none'; - this.yAxisScrollbarElement.style.display = 'none'; - } else { - this.xAxisScrollbarElement.style.display = 'block'; - this.yAxisScrollbarElement.style.display = 'block'; - - this.xAxisScrollbarContainerElement.style.display = 'block'; - this.yAxisScrollbarContainerElement.style.display = 'block'; - - const { chr1, chr2, zoom, pixelSize, x, y } = state; - - const chromosomeLengthsBin = [chr1, chr2].map(chr => dataset.chromosomes[chr].size / dataset.bpResolutions[zoom]); - const chromosomeLengthsPixel = chromosomeLengthsBin.map(bin => bin * pixelSize); - const { width, height } = this.browser.contactMatrixView.getViewDimensions(); - const pixels = [width, height]; - - const bins = pixels.map(pixel => pixel / pixelSize); - - const percentages = bins.map((bin, i) => { - const binPercentage = Math.min(bin, chromosomeLengthsBin[i]) / chromosomeLengthsBin[i]; - const pixelPercentage = Math.min(chromosomeLengthsPixel[i], pixels[i]) / pixels[i]; - return Math.max(1, Math.round(100 * binPercentage * pixelPercentage)); - }); - - this.xAxisScrollbarElement.style.width = `${percentages[0]}%`; - this.yAxisScrollbarElement.style.height = `${percentages[1]}%`; - - const xPercentage = Math.round(100 * x / chromosomeLengthsBin[0]); - this.xAxisScrollbarElement.style.left = `${xPercentage}%`; - - const yPercentage = Math.round(100 * y / chromosomeLengthsBin[1]); - this.yAxisScrollbarElement.style.top = `${yPercentage}%`; - - this.xLabelElement.textContent = dataset.chromosomes[chr1].name; - this.yLabelElement.textContent = dataset.chromosomes[chr2].name; - } - } - } - -} - -/* - * The MIT License (MIT) - * - * Copyright (c) 2016-2017 The Regents of the University of California - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and - * associated documentation files (the "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the - * following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING - * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - */ - -/** - * Creates and manages the chromosome selector UI component - */ -class ChromosomeSelector { - constructor(browser, container) { - this.browser = browser; - this.container = container; - this.xAxisSelector = container.querySelector("select[name='x-axis-selector']"); - this.yAxisSelector = container.querySelector("select[name='y-axis-selector']"); - - this.initialize(); - } - - initialize() { - // Sync selectors when either changes - this.xAxisSelector.addEventListener('change', () => this.syncSelectors(this.xAxisSelector, this.yAxisSelector)); - this.yAxisSelector.addEventListener('change', () => this.syncSelectors(this.yAxisSelector, this.xAxisSelector)); - - // Handle chromosome swap button click - const nextDiv = this.yAxisSelector.nextElementSibling; - if (nextDiv) { - nextDiv.addEventListener('click', async () => { - const chrX = this.browser.dataset.chromosomes[parseInt(this.xAxisSelector.value, 10)]; - const chrY = this.browser.dataset.chromosomes[parseInt(this.yAxisSelector.value, 10)]; - - const xLocus = this.browser.parseLocusString(chrX.name); - const yLocus = this.browser.parseLocusString(chrY.name); - - await this.browser.setChromosomes(xLocus, yLocus); - }); - } - - // Subscribe to browser events - this.browser.eventBus.subscribe("MapLoad", (event) => { - this.respondToDataLoadWithDataset(event.data); - }); - - this.browser.eventBus.subscribe("LocusChange", (event) => { - this.respondToLocusChangeWithState(event.data.state); - }); - } - - syncSelectors(sourceSelector, targetSelector) { - const value = sourceSelector.value; - if (parseInt(value, 10) === 0 || parseInt(targetSelector.value, 10) === 0) { - targetSelector.value = value; - } - } - - respondToDataLoadWithDataset(dataset) { - const { chromosomes } = dataset; - const options = chromosomes.map(({ name }, index) => ``).join(''); - this.xAxisSelector.innerHTML = options; - this.yAxisSelector.innerHTML = options; - - this.xAxisSelector.value = this.browser.state.chr1; - this.yAxisSelector.value = this.browser.state.chr2; - } - - respondToLocusChangeWithState(state) { - if (!this.xAxisSelector.options.length || !this.yAxisSelector.options.length) return; - - this.xAxisSelector.value = state.chr1; - this.yAxisSelector.value = state.chr2; - } -} - -/* - * The MIT License (MIT) - * - * Copyright (c) 2016-2017 The Regents of the University of California - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and - * associated documentation files (the "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the - * following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING - * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - */ - -class AnnotationWidget { - constructor(browser, container, { title, alertMessage }, trackListRetrievalCallback) { - this.browser = browser; - this.trackListRetrievalCallback = trackListRetrievalCallback; - - this.annotationPresentationButton(container, alertMessage); - this.annotationPanel(browser.rootElement, title); - } - - updateBody(tracks) { - - this.annotationPanelElement.querySelectorAll('.hic-annotation-row-container').forEach(el => el.remove()); - - if (tracks[0] instanceof Track2D) { - for (let i = tracks.length - 1; i >= 0; i--) { - this.annotationPanelRow(this.annotationPanelElement, tracks[i]); - } - } else { - for (const trackRenderer of tracks) { - this.annotationPanelRow(this.annotationPanelElement, trackRenderer); - } - } - } - - annotationPresentationButton(parent, alertMessage) { - const button = parent.querySelector('button'); - - button.addEventListener('click', () => { - const list = this.trackListRetrievalCallback(); - - if (list.length > 0) { - this.updateBody(this.trackListRetrievalCallback()); - this.annotationPanelElement.style.display = - this.annotationPanelElement.style.display === 'none' ? 'flex' : 'none'; - } else { - Alert$1.presentAlert(alertMessage); - } - - this.browser.hideMenu(); - }); - } - - annotationPanel(parent, title) { - this.annotationPanelElement = document.createElement('div'); - this.annotationPanelElement.className = 'hic-annotation-panel-container'; - parent.appendChild(this.annotationPanelElement); - - const panelHeader = document.createElement('div'); - panelHeader.className = 'hic-annotation-panel-header'; - this.annotationPanelElement.appendChild(panelHeader); - - const titleDiv = document.createElement('div'); - titleDiv.textContent = title; - panelHeader.appendChild(titleDiv); - - const closeButtonDiv = document.createElement('div'); - closeButtonDiv.className = 'hic-menu-close-button'; - panelHeader.appendChild(closeButtonDiv); - - const closeIcon = document.createElement('i'); - closeIcon.className = 'fa fa-times'; - closeButtonDiv.appendChild(closeIcon); - - closeIcon.addEventListener('click', () => { - this.annotationPanelElement.style.display = - this.annotationPanelElement.style.display === 'none' ? 'flex' : 'none'; - }); - - makeDraggable(this.annotationPanelElement, panelHeader); - this.annotationPanelElement.style.display = 'none'; - } - - annotationPanelRow(container, track) { - const isTrack2D = track instanceof Track2D; - const trackList = this.trackListRetrievalCallback(); - - let trackRenderer; - if (false === isTrack2D) { - trackRenderer = track.x.track.trackView; - } - - const rowContainer = document.createElement('div'); - rowContainer.className = 'hic-annotation-row-container'; - container.appendChild(rowContainer); - - const row = document.createElement('div'); - row.className = 'hic-annotation-modal-row'; - rowContainer.appendChild(row); - - const trackName = document.createElement('div'); - trackName.textContent = isTrack2D ? track.config.name : track.x.track.config.name; - row.appendChild(trackName); - - if (isTrack2D) { - const visibilityIcon = document.createElement('i'); - visibilityIcon.className = track.isVisible ? 'fa fa-eye fa-lg' : 'fa fa-eye-slash fa-lg'; - row.appendChild(visibilityIcon); - - visibilityIcon.addEventListener('click', () => { - track.isVisible = !track.isVisible; - visibilityIcon.className = track.isVisible ? 'fa fa-eye fa-lg' : 'fa fa-eye-slash fa-lg'; - - this.browser.contactMatrixView.clearImageCaches(); - this.browser.contactMatrixView.update(); - }); - } - - if (isTrack2D) { - const displayModeIcon = document.createElement('div'); - displayModeIcon.className = 'matrix-diagonal-widget-container'; - - switch (track.displayMode) { - case 'lower': - displayModeIcon.classList.add('matrix-diagonal-widget-lower'); - break; - case 'upper': - displayModeIcon.classList.add('matrix-diagonal-widget-upper'); - break; - default: - displayModeIcon.classList.add('matrix-diagonal-widget-all'); - } - - displayModeIcon.addEventListener('click', () => { - this.displayModeHandler(displayModeIcon, track); - this.browser.contactMatrixView.clearImageCaches(); - this.browser.contactMatrixView.update(); - }); - - row.appendChild(displayModeIcon); - } - - const colorpickerContainer = createAnnotationPanelColorpickerContainer(rowContainer, {width: (29 * 24 + 2)}, () => { - const nextElement = row.nextElementSibling; - if (nextElement && nextElement.classList.contains('hic-color-swatch-container')) { - nextElement.style.display = nextElement.style.display === 'none' ? 'flex' : 'none'; - } - }); - - const colorpickerButton = this.annotationColorSwatch(isTrack2D ? track.getColor() : track.x.track.color); - row.appendChild(colorpickerButton); - - colorpickerButton.addEventListener('click', () => { - const nextElement = row.nextElementSibling; - if (nextElement && nextElement.classList.contains('hic-color-swatch-container')) { - nextElement.style.display = nextElement.style.display === 'none' ? 'flex' : 'none'; - } - }); - - colorpickerContainer.style.display = 'none'; - - const colorHandler = color => { - const swatch = row.querySelector('.fa-square'); - if (swatch) { - swatch.style.color = color; - } - - if (isTrack2D) { - track.color = color; - this.browser.eventBus.post(HICEvent('TrackState2D', track)); - } else { - trackRenderer.setColor(color); - } - }; - - createColorSwatchSelector(colorpickerContainer, colorHandler); - - // track up/down - const upDownContainer = document.createElement('div'); - upDownContainer.className = 'up-down-arrow-container'; - row.appendChild(upDownContainer); - - const upTrack = document.createElement('i'); - upTrack.className = 'fa fa-arrow-up'; - upTrack.setAttribute('aria-hidden', 'true'); - upDownContainer.appendChild(upTrack); - - const downTrack = document.createElement('i'); - downTrack.className = 'fa fa-arrow-down'; - downTrack.setAttribute('aria-hidden', 'true'); - upDownContainer.appendChild(downTrack); - - const hiddenColor = '#f7f7f7'; - if (trackList.length === 1) { - upTrack.style.color = hiddenColor; - downTrack.style.color = hiddenColor; - } else if (track === trackList[0]) { - const arrow = isTrack2D ? downTrack : upTrack; - arrow.style.color = hiddenColor; - } else if (track === trackList[trackList.length - 1]) { - const arrow = isTrack2D ? upTrack : downTrack; - arrow.style.color = hiddenColor; - } - - const index = trackList.indexOf(track); - - const moveUp = () => { - const temp = trackList[index + 1]; - trackList[index + 1] = trackList[index]; - trackList[index] = temp; - - if (isTrack2D) { - this.browser.eventBus.post(HICEvent('TrackState2D', trackList)); - this.updateBody(trackList); - } else { - this.browser.updateLayout(); - this.updateBody(trackList); - } - }; - - const moveDown = () => { - const temp = trackList[index - 1]; - trackList[index - 1] = trackList[index]; - trackList[index] = temp; - - if (isTrack2D) { - this.browser.eventBus.post(HICEvent('TrackState2D', trackList)); - this.updateBody(trackList); - } else { - this.browser.updateLayout(); - this.updateBody(trackList); - } - }; - - upTrack.addEventListener('click', isTrack2D ? moveUp : moveDown); - downTrack.addEventListener('click', isTrack2D ? moveDown : moveUp); - - - const deleteIcon = document.createElement('i'); - deleteIcon.className = 'fa fa-trash-o fa-lg'; - row.appendChild(deleteIcon); - - deleteIcon.addEventListener('click', () => { - const index = trackList.indexOf(track); - if (isTrack2D) { - trackList.splice(index, 1); - this.browser.contactMatrixView.clearImageCaches(); - this.browser.contactMatrixView.update(); - this.browser.eventBus.post(HICEvent('TrackLoad2D', trackList)); - } else { - this.browser.layoutController.removeTrackXYPair(track.x.track.trackRenderPair); - } - - this.updateBody(trackList); - }); - } - - displayModeHandler(icon, track2D) { - if (icon.classList.contains('matrix-diagonal-widget-all')) { - icon.classList.replace('matrix-diagonal-widget-all', 'matrix-diagonal-widget-lower'); - track2D.displayMode = 'lower'; - } else if (icon.classList.contains('matrix-diagonal-widget-lower')) { - icon.classList.replace('matrix-diagonal-widget-lower', 'matrix-diagonal-widget-upper'); - track2D.displayMode = 'upper'; - } else { - icon.classList.replace('matrix-diagonal-widget-upper', 'matrix-diagonal-widget-all'); - track2D.displayMode = undefined; - } - } - - annotationColorSwatch(color) { - const swatch = document.createElement('div'); - swatch.className = 'igv-color-swatch'; - - const icon = document.createElement('i'); - icon.className = 'fa fa-square fa-lg'; - icon.style.color = color; - swatch.appendChild(icon); - - return swatch; - } -} - -function createAnnotationPanelColorpickerContainer(parent, size, closeHandler) { - - const container = document.createElement('div'); - container.className = 'hic-color-swatch-container'; - parent.appendChild(container); - - // width - if (size && size.width) { - container.style.width = `${size.width}px`; - } - - // height - if (size && size.height) { - container.style.height = `${size.height}px`; - } - - // header - const header = document.createElement('div'); - container.appendChild(header); - - // close button - const closeButton = document.createElement('i'); - closeButton.className = 'fa fa-times'; - header.appendChild(closeButton); - - closeButton.addEventListener('click', () => { - closeHandler(); - }); - - return container; -} - -/* - * The MIT License (MIT) - * - * Copyright (c) 2016-2017 The Regents of the University of California - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and - * associated documentation files (the "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the - * following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING - * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - */ - -class BrowserUIManager { - constructor(browser) { - this.browser = browser; - this.components = new Map(); - this.initializeComponents(); - } - - initializeComponents() { - const navContainer = getNavbarContainer(this.browser); - - // Navbar components - this.components.set('locusGoto', new LocusGoto(this.browser, navContainer)); - - this.components.set('resolutionSelector', new ResolutionSelector(this.browser, navContainer)); - this.getComponent('resolutionSelector').setResolutionLock(this.browser.resolutionLocked); - - this.components.set('colorScale', new ColorScaleWidget(this.browser, navContainer)); - - this.components.set('controlMap', new ControlMapWidget(this.browser, navContainer)); - - this.components.set('normalization', new NormalizationWidget(this.browser, navContainer)); - - const chromosomeSelectorContainer = this.browser.menuElement.querySelector('.hic-chromosome-selector-widget-container'); - this.components.set('chromosomeSelector', new ChromosomeSelector(this.browser, chromosomeSelectorContainer)); - - const annotationContainer = this.browser.menuElement.querySelector('.hic-annotation-presentation-button-container'); - const annotation2DWidgetConfig = - { - title: '2D Annotations', - alertMessage: 'No 2D annotations currently loaded for this map' - }; - this.components.set('annotationWidget', new AnnotationWidget(this.browser, annotationContainer, annotation2DWidgetConfig, () => this.browser.tracks2D)); - - const sweepZoom = new SweepZoom(this.browser, this.browser.layoutController.getContactMatrixViewport()); - const scrollbarWidget = new ScrollbarWidget( - this.browser, - this.browser.layoutController.getXAxisScrollbarContainer(), - this.browser.layoutController.getYAxisScrollbarContainer() - ); - - const colorScale = new ColorScale(defaultColorScaleConfig); - const ratioColorScale = new RatioColorScale(defaultRatioColorScaleConfig.threshold); - ratioColorScale.setColorComponents(defaultRatioColorScaleConfig.negative, '-'); - ratioColorScale.setColorComponents(defaultRatioColorScaleConfig.positive, '+'); - - this.components.set('sweepZoom', sweepZoom); - this.components.set('scrollbar', scrollbarWidget); - this.components.set('colorScale', colorScale); - this.components.set('ratioColorScale', ratioColorScale); - - // Initialize ContactMatrixView with the components - const backgroundColor = this.browser.config.backgroundColor || ContactMatrixView.defaultBackgroundColor; - this.components.set('contactMatrix', new ContactMatrixView( - this.browser, - this.browser.layoutController.getContactMatrixViewport(), - sweepZoom, - scrollbarWidget, - colorScale, - ratioColorScale, - backgroundColor - )); - } - - getComponent(name) { - return this.components.get(name); - } - -} - -/* - * The MIT License (MIT) - * - * Copyright (c) 2016-2017 The Regents of the University of California - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and - * associated documentation files (the "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the - * following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING - * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - */ - -const DEFAULT_PIXEL_SIZE = 1; -const MAX_PIXEL_SIZE = 128; -const DEFAULT_ANNOTATION_COLOR$1 = "rgb(22, 129, 198)"; - -class HICBrowser { - - constructor(appContainer, config) { - this.config = config; - this.figureMode = config.figureMode || config.miniMode; // Mini mode for backward compatibility - this.resolutionLocked = false; - this.eventBus = new EventBus(); - - this.showTrackLabelAndGutter = true; - - this.id = `browser_${domUtils.guid()}`; - this.trackPairs = []; - this.tracks2D = []; - this.normVectorFiles = []; - - this.synchable = config.synchable !== false; - this.synchedBrowsers = new Set(); - - this.isMobile = isMobile(); - - this.rootElement = document.createElement('div'); - this.rootElement.className = 'hic-root unselect'; - appContainer.appendChild(this.rootElement); - - - if (config.width && config.height) { - setViewportSize(config.width, config.height); - } - - this.layoutController = new LayoutController(this, this.rootElement); - - this.inputDialog = new InputDialog(appContainer, this); - - this.menuElement = this.createMenu(this.rootElement); - this.menuElement.style.display = 'none'; - - // Initialize UI components through BrowserUIManager - this.ui = new BrowserUIManager(this); - - // Get the contact matrix view from UI manager - this.contactMatrixView = this.ui.getComponent('contactMatrix'); - - // prevent user interaction during lengthy data loads - this.userInteractionShield = document.createElement('div'); - this.userInteractionShield.className = 'hic-root-prevent-interaction'; - this.rootElement.appendChild(this.userInteractionShield); - this.userInteractionShield.style.display = 'none'; - - this.hideCrosshairs(); - } - - async init(config) { - this.pending = new Map(); - this.eventBus.hold(); - this.contactMatrixView.disableUpdates = true; - - try { - this.contactMatrixView.startSpinner(); - this.userInteractionShield.style.display = 'block'; - - await this.loadHicFile(config, true); - - if (config.controlUrl) { - await this.loadHicControlFile({ - url: config.controlUrl, - name: config.controlName, - nvi: config.controlNvi, - isControl: true - }, true); - } - - if (config.cycle) { - config.displayMode = "A"; - } - - if (config.displayMode) { - this.contactMatrixView.displayMode = config.displayMode; - this.eventBus.post({ type: "DisplayMode", data: config.displayMode }); - } - - if (config.colorScale) { - if (config.normalization) { - this.state.normalization = config.normalization; - } - this.contactMatrixView.setColorScale(config.colorScale); - this.eventBus.post({ type: "ColorScale", data: this.contactMatrixView.getColorScale() }); - } - - const promises = []; - - if (config.tracks) { - promises.push(this.loadTracks(config.tracks)); - } - - if (config.normVectorFiles) { - config.normVectorFiles.forEach(nv => { - promises.push(this.loadNormalizationFile(nv)); - }); - } - - await Promise.all(promises); - - if (config.normalization) { - const normalizations = await this.getNormalizationOptions(); - const validNormalizations = new Set(normalizations); - this.state.normalization = validNormalizations.has(config.normalization) ? config.normalization : 'NONE'; - } - - const tmp = this.contactMatrixView.colorScaleThresholdCache; - this.eventBus.release(); - this.contactMatrixView.colorScaleThresholdCache = tmp; - - if (config.cycle) { - this.ui.getComponent('controlMap').toggleDisplayModeCycle(); - } else { - await this.update(); - } - - } finally { - this.contactMatrixView.stopSpinner(); - this.userInteractionShield.style.display = 'none'; - this.contactMatrixView.disableUpdates = false; - this.contactMatrixView.update(); - } - } - - createMenu(rootElement) { - const html = ` - `; - - const template = document.createElement('template'); - template.innerHTML = html.trim(); - const menuElement = template.content.firstChild; - - rootElement.appendChild(menuElement); - - const closeButton = menuElement.querySelector(".fa-times"); - closeButton.addEventListener('click', () => this.toggleMenu()); - - return menuElement; - } - - toggleTrackLabelAndGutterState() { - this.showTrackLabelAndGutter = !this.showTrackLabelAndGutter; - } - - toggleMenu() { - if (this.menuElement.style.display === "flex") { - this.hideMenu(); - } else { - this.showMenu(); - } - } - - showMenu() { - this.menuElement.style.display = "flex"; - } - - hideMenu() { - this.menuElement.style.display = "none"; - } - - startSpinner() { - this.contactMatrixView.startSpinner(); - } - - stopSpinner() { - this.contactMatrixView.stopSpinner(); - } - - async setDisplayMode(mode) { - await this.contactMatrixView.setDisplayMode(mode); - this.eventBus.post(HICEvent("DisplayMode", mode)); - } - - getDisplayMode() { - return this.contactMatrixView ? this.contactMatrixView.displayMode : undefined - } - - async getNormalizationOptions() { - - if (!this.dataset) return [] - - const baseOptions = await this.dataset.getNormalizationOptions(); - if (this.controlDataset) { - let controlOptions = await this.controlDataset.getNormalizationOptions(); - controlOptions = new Set(controlOptions); - return baseOptions.filter(base => controlOptions.has(base)) - } else { - return baseOptions - } - } - - /** - * Return usable resolutions, that is the union of resolutions between dataset and controlDataset. - * @returns {{index: *, binSize: *}[]|Array} - */ - getResolutions() { - if (!this.dataset) return [] - - const baseResolutions = this.dataset.bpResolutions.map(function (resolution, index) { - return {index: index, binSize: resolution} - }); - if (this.controlDataset) { - let controlResolutions = new Set(this.controlDataset.bpResolutions); - return baseResolutions.filter(base => controlResolutions.has(base.binSize)) - } else { - return baseResolutions - } - } - - isWholeGenome() { - return this.dataset && this.state && this.dataset.isWholeGenome(this.state.chr1) - } - - getColorScale() { - - if (!this.contactMatrixView) return undefined - - switch (this.getDisplayMode()) { - case 'AOB': - case 'BOA': - return this.contactMatrixView.ratioColorScale - case 'AMB': - return this.contactMatrixView.diffColorScale - default: - return this.contactMatrixView.colorScale - } - } - - setColorScaleThreshold(threshold) { - this.contactMatrixView.setColorScaleThreshold(threshold); - } - - updateCrosshairs({ x, y, xNormalized, yNormalized }) { - - const xGuide = y < 0 ? { left: '0px' } : { top: `${y}px`, left: '0px' }; - this.contactMatrixView.xGuideElement.style.left = xGuide.left; - if (xGuide.top !== undefined) this.contactMatrixView.xGuideElement.style.top = xGuide.top; - - this.layoutController.xTrackGuideElement.style.left = xGuide.left; - if (xGuide.top !== undefined) this.layoutController.xTrackGuideElement.style.top = xGuide.top; - - const yGuide = x < 0 ? { top: '0px' } : { top: '0px', left: `${x}px` }; - this.contactMatrixView.yGuideElement.style.top = yGuide.top; - if (yGuide.left !== undefined) this.contactMatrixView.yGuideElement.style.left = yGuide.left; - - this.layoutController.yTrackGuideElement.style.top = yGuide.top; - if (yGuide.left !== undefined) this.layoutController.yTrackGuideElement.style.left = yGuide.left; - - if (this.customCrosshairsHandler) { - const { x: stateX, y: stateY, pixelSize } = this.state; - const resolution = this.resolution(); - - const xBP = (stateX + (x / pixelSize)) * resolution; - const yBP = (stateY + (y / pixelSize)) * resolution; - - const { startBP: startXBP, endBP: endXBP } = this.genomicState('x'); - const { startBP: startYBP, endBP: endYBP } = this.genomicState('y'); - - this.customCrosshairsHandler({ - xBP, - yBP, - startXBP, - startYBP, - endXBP, - endYBP, - interpolantX: xNormalized, - interpolantY: yNormalized - }); - } - } - - setCustomCrosshairsHandler(crosshairsHandler) { - this.customCrosshairsHandler = crosshairsHandler; - } - - hideCrosshairs() { - this.contactMatrixView.xGuideElement.style.display = 'none'; - this.layoutController.xTrackGuideElement.style.display = 'none'; - - this.contactMatrixView.yGuideElement.style.display = 'none'; - this.layoutController.yTrackGuideElement.style.display = 'none'; - } - - showCrosshairs() { - this.contactMatrixView.xGuideElement.style.display = 'block'; - this.layoutController.xTrackGuideElement.style.display = 'block'; - - this.contactMatrixView.yGuideElement.style.display = 'block'; - this.layoutController.yTrackGuideElement.style.display = 'block'; - } - - genomicState(axis) { - - let width = this.contactMatrixView.getViewDimensions().width; - let resolution = this.dataset.bpResolutions[this.state.zoom]; - const bpp = - (this.dataset.chromosomes[this.state.chr1].name.toLowerCase() === "all") ? - this.genome.getGenomeLength() / width : - resolution / this.state.pixelSize; - - const gs = - { - bpp - }; - - if (axis === "x") { - gs.chromosome = this.dataset.chromosomes[this.state.chr1]; - gs.startBP = this.state.x * resolution; - gs.endBP = gs.startBP + bpp * width; - } else { - gs.chromosome = this.dataset.chromosomes[this.state.chr2]; - gs.startBP = this.state.y * resolution; - gs.endBP = gs.startBP + bpp * this.contactMatrixView.getViewDimensions().height; - } - return gs - } - - /** - * Load a list of 1D genome tracks (wig, etc). - * - * NOTE: public API function - * - * @param configs - */ - async loadTracks(configs) { - const errorPrefix = configs.length === 1 ? `Error loading track ${configs[0].name}` : "Error loading tracks"; - - try { - this.contactMatrixView.startSpinner(); - - const tracks = []; - const promises2D = []; - - for (let config of configs) { - const fileName = isFile(config.url) - ? config.url.name - : config.filename || await getFilename$3(config.url); - - const extension = getExtension(fileName); - - if (['fasta', 'fa'].includes(extension)) { - config.type = config.format = 'sequence'; - } - - if (!config.format) { - config.format = index$1.TrackUtils.inferFileFormat(fileName); - } - - if (config.type === 'annotation') { - config.displayMode = 'COLLAPSED'; - if (config.color === DEFAULT_ANNOTATION_COLOR$1) { - delete config.color; - } - } - - if (config.max === undefined) { - config.autoscale = true; - } - - const { trackHeight } = getLayoutDimensions(); - config.height = trackHeight; - - if (config.format === undefined || ['bedpe', 'interact'].includes(config.format)) { - promises2D.push(Track2D.loadTrack2D(config, this.genome)); - } else { - const track = await index$1.createTrack(config, this); - - if (typeof track.postInit === 'function') { - await track.postInit(); - } - - tracks.push(track); - } - } - - if (tracks.length > 0) { - this.layoutController.updateLayoutWithTracks(tracks); - - const gearContainer = document.querySelector('.hic-igv-right-hand-gutter'); - if (this.showTrackLabelAndGutter) { - gearContainer.style.display = 'block'; - } else { - gearContainer.style.display = 'none'; - } - - await this.updateLayout(); - } - - if (promises2D.length > 0) { - const tracks2D = await Promise.all(promises2D); - if (tracks2D && tracks2D.length > 0) { - this.tracks2D = this.tracks2D.concat(tracks2D); - this.eventBus.post(HICEvent("TrackLoad2D", this.tracks2D)); - } - } - - } catch (error) { - presentError(errorPrefix, error); - console.error(error); - - } finally { - this.contactMatrixView.stopSpinner(); - } - } - - async loadNormalizationFile(url) { - - if (!this.dataset) return - this.eventBus.post(HICEvent("NormalizationFileLoad", "start")); - - const normVectors = await this.dataset.hicFile.readNormalizationVectorFile(url, this.dataset.chromosomes); - for (let type of normVectors['types']) { - if (!this.dataset.normalizationTypes) { - this.dataset.normalizationTypes = []; - } - if (!this.dataset.normalizationTypes.includes(type)) { - this.dataset.normalizationTypes.push(type); - } - this.eventBus.post(HICEvent("NormVectorIndexLoad", this.dataset)); - } - - return normVectors - } - - /** - * Render the XY pair of tracks. - * - * @param xy - */ - async renderTrackXY(xy) { - - try { - this.startSpinner(); - await xy.updateViews(); - } finally { - this.stopSpinner(); - } - } - - reset() { - this.layoutController.removeAllTrackXYPairs(); - this.contactMatrixView.clearImageCaches(); - this.tracks2D = []; - this.tracks = []; - this.contactMapLabel.textContent = ""; - this.contactMapLabel.title = ""; - this.controlMapLabel.textContent = ""; - this.controlMapLabel.title = ""; - this.dataset = undefined; - this.controlDataset = undefined; - this.unsyncSelf(); - } - - clearSession() { - // Clear current datasets. - this.dataset = undefined; - this.controlDataset = undefined; - this.setDisplayMode('A'); - this.unsyncSelf(); - } - - /** - * Remove reference to self from all synchedBrowsers lists. - */ - unsyncSelf() { - const allBrowsers = getAllBrowsers(); - for (let b of allBrowsers) { - b.unsync(this); - } - } - - /** - * Remove the reference browser from this collection of synched browsers - * @param browser - */ - unsync(browser) { - const list = [...this.synchedBrowsers]; - this.synchedBrowsers = new Set(list.filter(b => b !== browser)); - } - - /** - * Load a .hic file - * - * NOTE: public API function - * - * @return a promise for a dataset - * @param config - * @param noUpdates - */ - async loadHicFile(config, noUpdates) { - - if (!config.url) { - console.log("No .hic url specified"); - return undefined - } - - this.clearSession(); - - try { - - this.contactMatrixView.startSpinner(); - if (!noUpdates) { - this.userInteractionShield.style.display = 'block'; - } - - const name = extractName(config); - const prefix = this.controlDataset ? "A: " : ""; - this.contactMapLabel.textContent = prefix + name; - this.contactMapLabel.title = name; - config.name = name; - - const hicFileAlert = str => { - this.eventBus.post(HICEvent('NormalizationExternalChange', 'NONE')); - Alert$1.presentAlert(str); - }; - - this.dataset = await Dataset.loadDataset(Object.assign({alert: hicFileAlert}, config)); - this.dataset.name = name; - - const previousGenomeId = this.genome ? this.genome.id : undefined; - this.genome = new Genome(this.dataset.genomeId, this.dataset.chromosomes); - - if (this.genome.id !== previousGenomeId) { - EventBus.globalBus.post(HICEvent("GenomeChange", this.genome.id)); - } - - if (config.locus) { - this.state = State.default(config); - await this.parseGotoInput(config.locus); - } else if (config.state) { - - if (typeof config.state === 'string') { - await this.setState( State.parse(config.state) ); - } else if (typeof config.state === 'object') { - await this.setState( State.fromJSON(config.state) ); - } else { - alert('config.state is of unknown type'); - console.error('config.state is of unknown type'); - } - - - } else if (config.synchState && this.canBeSynched(config.synchState)) { - await this.syncState(config.synchState); - } else { - await this.setState(State.default(config)); - } - - this.eventBus.post(HICEvent("MapLoad", this.dataset)); - - // Initiate loading of the norm vector index, but don't block if the "nvi" parameter is not available. - // Let it load in the background - - // If nvi is not supplied, try lookup table of known values - if (!config.nvi && typeof config.url === "string") { - const url = new URL(config.url); - const key = encodeURIComponent(url.hostname + url.pathname); - if (nvi.hasOwnProperty(key)) { - config.nvi = nvi[key]; - } - } - - if (config.nvi) { - await this.dataset.getNormVectorIndex(config); - this.eventBus.post(HICEvent("NormVectorIndexLoad", this.dataset)); - } else { - - this.dataset.getNormVectorIndex(config) - .then(normVectorIndex => { - if (!config.isControl) { - this.eventBus.post(HICEvent("NormVectorIndexLoad", this.dataset)); - } - }); - } - - syncBrowsers(); - - // Find a browser to sync with, if any - const compatibleBrowsers = getAllBrowsers().filter(b => b !== this && b.dataset && b.dataset.isCompatible(this.dataset)); - if (compatibleBrowsers.length > 0) { - await this.syncState(compatibleBrowsers[0].getSyncState()); - } - - } catch (error) { - this.contactMapLabel.textContent = ""; - this.contactMapLabel.title = ""; - config.name = name; - throw error - } finally { - this.stopSpinner(); - if (!noUpdates) { - this.userInteractionShield.style.display = 'none'; - } - } - } - - /** - * Load a .hic file for a control map - * - * NOTE: public API function - * - * @return a promise for a dataset - * @param config - */ - async loadHicControlFile(config, noUpdates) { - - try { - this.userInteractionShield.style.display = 'block'; - this.contactMatrixView.startSpinner(); - this.controlUrl = config.url; - const name = extractName(config); - config.name = name; - - const hicFileAlert = str => { - this.eventBus.post(HICEvent('NormalizationExternalChange', 'NONE')); - Alert$1.presentAlert(str); - }; - - const controlDataset = await Dataset.loadDataset(Object.assign({alert: hicFileAlert}, config)); - - controlDataset.name = name; - - if (!this.dataset || this.dataset.isCompatible(controlDataset)) { - this.controlDataset = controlDataset; - if (this.dataset) { - this.contactMapLabel.textContent = "A: " + this.dataset.name; - } - this.controlMapLabel.textContent = "B: " + controlDataset.name; - this.controlMapLabel.title = controlDataset.name; - - //For the control dataset, block until the norm vector index is loaded - await controlDataset.getNormVectorIndex(config); - this.eventBus.post(HICEvent("ControlMapLoad", this.controlDataset)); - - if (!noUpdates) { - this.update(); - } - } else { - Alert$1.presentAlert('"B" map genome (' + controlDataset.genomeId + ') does not match "A" map genome (' + this.genome.id + ')'); - } - } finally { - this.userInteractionShield.style.display = 'none'; - this.stopSpinner(); - } - } - - async parseGotoInput(input) { - const loci = input.trim().split(' '); - - let xLocus = this.parseLocusString(loci[0]) || await this.lookupFeatureOrGene(loci[0]); - - if (!xLocus) { - console.error(`No feature found with name ${loci[ 0 ]}`); - alert(`No feature found with name ${loci[ 0 ]}`); - return; - } - - let yLocus = loci[1] ? this.parseLocusString(loci[1]) : { ...xLocus }; - if (!yLocus) { - yLocus = { ...xLocus }; - } - - if (xLocus.wholeChr && yLocus.wholeChr || 'All' === xLocus.chr && 'All' === yLocus.chr) { - await this.setChromosomes(xLocus, yLocus); - } else { - this.goto(xLocus.chr, xLocus.start, xLocus.end, yLocus.chr, yLocus.start, yLocus.end); - } - } - - parseLocusString(locus) { - const [chrName, range] = locus.trim().toLowerCase().split(':'); - const chromosome = this.genome.getChromosome(chrName); - - if (!chromosome) { - return undefined; - } - - const locusObject = - { - chr: chromosome.name, - wholeChr: (undefined === range && 'All' !== chromosome.name) - }; - - if (true === locusObject.wholeChr || 'All' === chromosome.name) { - // Chromosome name only or All: Set to whole range - locusObject.start = 0; - locusObject.end = chromosome.size; - } else { - - const [startStr, endStr] = range.split('-').map(part => part.replace(/,/g, '')); - - // Internally, loci are 0-based. - locusObject.start = isNaN(startStr) ? undefined : parseInt(startStr, 10) - 1; - locusObject.end = isNaN(endStr) ? undefined : parseInt(endStr, 10); - - } - - return locusObject; - } - - async lookupFeatureOrGene(name) { - - const trimmedName = name.trim(); - const upperName = trimmedName.toUpperCase(); - - if (this.genome.featureDB.has(upperName)) { - Globals.selectedGene = trimmedName; - this.state.selectedGene = Globals.selectedGene; - const {chr, start, end } = this.genome.featureDB.get(upperName); - - // Internally, loci are 0-based. parseLocusString() assumes and user-provided locus which is 1-based - return this.parseLocusString(`${chr}:${start + 1}-${end}`) - } - - const geneResult = await geneSearch(this.genome.id, trimmedName); - if (geneResult) { - Globals.selectedGene = trimmedName; - this.state.selectedGene = Globals.selectedGene; - return this.parseLocusString(geneResult) - } - - return undefined; // No match found - } - - goto(chr1, bpX, bpXMax, chr2, bpY, bpYMax) { - - const { width, height } = this.contactMatrixView.getViewDimensions(); - const { chrChanged, resolutionChanged } = this.state.updateWithLoci(chr1, bpX, bpXMax, chr2, bpY, bpYMax, this, width, height); - - this.contactMatrixView.clearImageCaches(); - - this.update(HICEvent("LocusChange", { state: this.state, resolutionChanged, chrChanged })); - - } - - /** - * Find the closest matching zoom index (index into the dataset resolutions array) for the target resolution. - * - * resolutionAraay can be either - * (1) an array of bin sizes - * (2) an array of objects with index and bin size - * @param targetResolution - * @param resolutionArray - * @returns {number} - */ - findMatchingZoomIndex(targetResolution, resolutionArray) { - const isObject = resolutionArray.length > 0 && resolutionArray[0].index !== undefined; - for (let z = resolutionArray.length - 1; z > 0; z--) { - const binSize = isObject ? resolutionArray[z].binSize : resolutionArray[z]; - const index = isObject ? resolutionArray[z].index : z; - if (binSize >= targetResolution) { - return index - } - } - return 0 - }; - - /** - * @param scaleFactor Values range from greater then 1 to decimal values less then one - * Value > 1 are magnification (zoom in) - * Decimal values (.9, .75, .25, etc.) are minification (zoom out) - * @param anchorPx -- anchor position in pixels (should not move after transformation) - * @param anchorPy - */ - async pinchZoom(anchorPx, anchorPy, scaleFactor) { - - if (this.state.chr1 === 0) { - await this.zoomAndCenter(1, anchorPx, anchorPy); - } else { - try { - this.startSpinner(); - - const bpResolutions = this.getResolutions(); - const currentResolution = bpResolutions[this.state.zoom]; - - let newBinSize; - let newZoom; - let newPixelSize; - let resolutionChanged; - - if (this.resolutionLocked || - (this.state.zoom === bpResolutions.length - 1 && scaleFactor > 1) || - (this.state.zoom === 0 && scaleFactor < 1)) { - // Can't change resolution level, must adjust pixel size - newBinSize = currentResolution.binSize; - newPixelSize = Math.min(MAX_PIXEL_SIZE, this.state.pixelSize * scaleFactor); - newZoom = this.state.zoom; - resolutionChanged = false; - } else { - const targetBinSize = (currentResolution.binSize / this.state.pixelSize) / scaleFactor; - newZoom = this.findMatchingZoomIndex(targetBinSize, bpResolutions); - newBinSize = bpResolutions[newZoom].binSize; - resolutionChanged = newZoom !== this.state.zoom; - newPixelSize = Math.min(MAX_PIXEL_SIZE, newBinSize / targetBinSize); - } - const z = await this.minZoom(this.state.chr1, this.state.chr2); - - - if (!this.resolutionLocked && scaleFactor < 1 && newZoom < z) { - // Zoom out to whole genome - const xLocus = this.parseLocusString('1'); - const yLocus = { xLocus }; - await this.setChromosomes(xLocus, yLocus); - } else { - - await this.state.panWithZoom(newZoom, newPixelSize, anchorPx, anchorPy, newBinSize, this, this.dataset, this.contactMatrixView.getViewDimensions(), bpResolutions); - - await this.contactMatrixView.zoomIn(anchorPx, anchorPy, 1/scaleFactor); - - await this.update(HICEvent("LocusChange", { state: this.state, resolutionChanged, chrChanged: false })); - } - } finally { - this.stopSpinner(); - } - } - - } - - // Zoom in response to a double-click - /** - * Zoom and center on bins at given screen coordinates. Supports double-click zoom, pinch zoom. - * @param direction - * @param centerPX screen coordinate to center on - * @param centerPY screen coordinate to center on - * @returns {Promise} - */ - async zoomAndCenter(direction, centerPX, centerPY) { - - if (undefined === this.dataset) { - console.warn('Dataset is undefined'); - return - } - - if (this.dataset.isWholeGenome(this.state.chr1) && direction > 0) { - // jump from whole genome to chromosome - const genomeCoordX = centerPX * this.dataset.wholeGenomeResolution / this.state.pixelSize; - const genomeCoordY = centerPY * this.dataset.wholeGenomeResolution / this.state.pixelSize; - const chrX = this.genome.getChromosomeForCoordinate(genomeCoordX); - const chrY = this.genome.getChromosomeForCoordinate(genomeCoordY); - const xLocus = { chr: chrX.name, start: 0, end: chrX.size, wholeChr: true }; - const yLocus = { chr: chrY.name, start: 0, end: chrY.size, wholeChr: true }; - await this.setChromosomes(xLocus, yLocus); - } else { - - const { width, height } = this.contactMatrixView.getViewDimensions(); - - const dx = centerPX === undefined ? 0 : centerPX - width / 2; - this.state.x += (dx / this.state.pixelSize); - - const dy = centerPY === undefined ? 0 : centerPY - height / 2; - this.state.y += (dy / this.state.pixelSize); - - const resolutions = this.getResolutions(); - const directionPositive = direction > 0 && this.state.zoom === resolutions[resolutions.length - 1].index; - const directionNegative = direction < 0 && this.state.zoom === resolutions[0].index; - if (this.resolutionLocked || directionPositive || directionNegative) { - - const minPS = await this.minPixelSize(this.state.chr1, this.state.chr2, this.state.zoom); - - const newPixelSize = Math.max(Math.min(MAX_PIXEL_SIZE, this.state.pixelSize * (direction > 0 ? 2 : 0.5)), minPS); - - const shiftRatio = (newPixelSize - this.state.pixelSize) / newPixelSize; - - this.state.pixelSize = newPixelSize; - - - this.state.x += shiftRatio * (width / this.state.pixelSize); - this.state.y += shiftRatio * (height / this.state.pixelSize); - - this.state.clampXY(this.dataset, this.contactMatrixView.getViewDimensions()); - - this.state.configureLocus(this, this.dataset, { width, height }); - - this.update(HICEvent("LocusChange", {state: this.state, resolutionChanged: false, chrChanged: false})); - - } else { - let i; - for (i = 0; i < resolutions.length; i++) { - if (this.state.zoom === resolutions[i].index) break - } - if (i) { - const newZoom = resolutions[i + direction].index; - this.setZoom(newZoom); - } - } - } - } - - /** - * Set the current zoom state and opctionally center over supplied coordinates. - * @param zoom - index to the datasets resolution array (dataset.bpResolutions) - * @returns {Promise} - */ - async setZoom(zoom) { - - const resolutionChanged = await this.state.setWithZoom(zoom, this.contactMatrixView.getViewDimensions(), this, this.dataset); - - await this.contactMatrixView.zoomIn(); - - this.update(HICEvent("LocusChange", { state: this.state, resolutionChanged, chrChanged: false })); - - } - - async setChromosomes(xLocus, yLocus) { - - const { index:chr1Index } = this.genome.getChromosome(xLocus.chr); - const { index:chr2Index } = this.genome.getChromosome(yLocus.chr); - - this.state.chr1 = Math.min(chr1Index, chr2Index); - this.state.x = 0; - - this.state.chr2 = Math.max(chr1Index, chr2Index); - this.state.y = 0; - - this.state.locus = - { - x: { chr: xLocus.chr, start: xLocus.start, end: xLocus.end }, - y: { chr: yLocus.chr, start: yLocus.start, end: yLocus.end } - }; - - if (xLocus.wholeChr && yLocus.wholeChr) { - this.state.zoom = await this.minZoom(this.state.chr1, this.state.chr2); - const minPS = await this.minPixelSize(this.state.chr1, this.state.chr2, this.state.zoom); - this.state.pixelSize = Math.min(100, Math.max(DEFAULT_PIXEL_SIZE, minPS)); - } else { - // Whole Genome - this.state.zoom = 0; - const minPS = await this.minPixelSize(this.state.chr1, this.state.chr2, this.state.zoom); - this.state.pixelSize = Math.max(this.state.pixelSize, minPS); - - } - - await this.update(HICEvent("LocusChange", {state: this.state, resolutionChanged: true, chrChanged: true})); - - } - - /** - * Called on loading tracks - * @returns {Promise} - */ - async updateLayout() { - - this.state.clampXY(this.dataset, this.contactMatrixView.getViewDimensions()); - - for (const trackXYPair of this.trackPairs) { - - trackXYPair.x.viewportElement.style.order = `${this.trackPairs.indexOf(trackXYPair)}`; - trackXYPair.y.viewportElement.style.order = `${this.trackPairs.indexOf(trackXYPair)}`; - - trackXYPair.x.syncCanvas(); - trackXYPair.y.syncCanvas(); - - } - - this.layoutController.xAxisRuler.update(); - this.layoutController.yAxisRuler.update(); - - setTrackReorderArrowColors(this.trackPairs); - - await this.update(); - - } - - /** - * Set the matrix state. Used to restore state from a bookmark - * @param state browser state - */ - async setState(state) { - - const chrChanged = !this.state || this.state.chr1 !== state.chr1 || this.state.chr2 !== state.chr2; - - this.state = state.clone(); - - // Possibly adjust pixel size - const minPS = await this.minPixelSize(this.state.chr1, this.state.chr2, this.state.zoom); - this.state.pixelSize = Math.max(state.pixelSize, minPS); - - // Derive locus if none is present in source state - if (undefined === state.locus) { - const viewDimensions = this.contactMatrixView.getViewDimensions(); - this.state.configureLocus(this, this.dataset, viewDimensions); - } - - const hicEvent = new HICEvent("LocusChange", { state: this.state, resolutionChanged: true, chrChanged }); - this.update(hicEvent); - this.eventBus.post(hicEvent); - } - - /** - * Return a modified state object used for synching. Other datasets might have different chromosome ordering - * and resolution arrays - */ - getSyncState() { - return { - chr1Name: this.dataset.chromosomes[this.state.chr1].name, - chr2Name: this.dataset.chromosomes[this.state.chr2].name, - binSize: this.dataset.bpResolutions[this.state.zoom], - binX: this.state.x, // TODO: translate to lower right corner - binY: this.state.y, - pixelSize: this.state.pixelSize - } - } - - /** - * Return true if this browser can be synced to the given state - * @param syncState - */ - canBeSynched(syncState) { - - if (false === this.synchable) return false // Explicitly not synchable - - return this.dataset && - (this.dataset.getChrIndexFromName(syncState.chr1Name) !== undefined) && - (this.dataset.getChrIndexFromName(syncState.chr2Name) !== undefined) - - } - - async syncState(targetState) { - - if (!targetState || false === this.synchable) return - - if (!this.dataset) return - - const { zoomChanged, chrChanged } = this.state.sync(targetState, this, this.genome, this.dataset); - - const payload = { state: this.state, resolutionChanged: zoomChanged, chrChanged }; - this.update(HICEvent("LocusChange", payload, false)); - - } - - setNormalization(normalization) { - - this.state.normalization = normalization; - this.eventBus.post(HICEvent("NormalizationChange", this.state.normalization)); - } - - shiftPixels(dx, dy) { - - if (undefined === this.dataset) { - console.warn('dataset is undefined'); - return - } - - this.state.panShift(dx, dy, this, this.dataset, this.contactMatrixView.getViewDimensions()); - - const locusChangeEvent = HICEvent("LocusChange", { - state: this.state, - resolutionChanged: false, - dragging: true, - chrChanged: false - }); - locusChangeEvent.dragging = true; - - this.update(locusChangeEvent); - this.eventBus.post(locusChangeEvent); - } - - /** - * Update the maps and tracks. This method can be called from the browser event thread repeatedly, for example - * while mouse dragging. If called while an update is in progress queue the event for processing later. It - * is only neccessary to queue the most recent recently received event, so a simple instance variable will suffice - * for the queue. - * - * @param event - */ - async update(event) { - - if (this.updating) { - const type = event ? event.type : "NONE"; - this.pending.set(type, event); - } else { - this.updating = true; - try { - - this.startSpinner(); - if (event !== undefined && "LocusChange" === event.type) { - this.layoutController.xAxisRuler.locusChange(event); - this.layoutController.yAxisRuler.locusChange(event); - } - - const promises = []; - - for (let xyTrackRenderPair of this.trackPairs) { - promises.push(this.renderTrackXY(xyTrackRenderPair)); - } - promises.push(this.contactMatrixView.update(event)); - await Promise.all(promises); - - if (event && event.propogate) { - let syncState1 = this.getSyncState(); - for (const browser of [...this.synchedBrowsers]) { - browser.syncState(syncState1); - } - } - - } finally { - this.updating = false; - if (this.pending.size > 0) { - const events = []; - for (let [k, v] of this.pending) { - events.push(v); - } - this.pending.clear(); - for (let e of events) { - this.update(e); - } - } - if (event) { - // possibly, unless update was called from an event post (infinite loop) - this.eventBus.post(event); - } - this.stopSpinner(); - } - } - } - - repaintMatrix() { - this.contactMatrixView.imageTileCache = {}; - this.contactMatrixView.initialImage = undefined; - this.contactMatrixView.update(); - } - - resolution() { - return this.dataset.bpResolutions[this.state.zoom] - }; - - toJSON() { - - if (!(this.dataset && this.dataset.url)) return "{}" // URL is required - - const jsonOBJ = {}; - - jsonOBJ.backgroundColor = this.contactMatrixView.stringifyBackgroundColor(); - jsonOBJ.url = this.dataset.url; - if (this.dataset.name) { - jsonOBJ.name = this.dataset.name; - } - - jsonOBJ.state = this.state.toJSON(); - - jsonOBJ.colorScale = this.contactMatrixView.getColorScale().stringify(); - if (Globals.selectedGene) { - jsonOBJ.selectedGene = Globals.selectedGene; - } - let nviString = this.dataset.hicFile.config.nvi; - if (nviString) { - jsonOBJ.nvi = nviString; - } - if (this.controlDataset) { - jsonOBJ.controlUrl = this.controlUrl; - if (this.controlDataset.name) { - jsonOBJ.controlName = this.controlDataset.name; - } - const displayMode = this.getDisplayMode(); - if (displayMode) { - jsonOBJ.displayMode = this.getDisplayMode(); - } - nviString = this.controlDataset.hicFile.config.nvi; - if (nviString) { - jsonOBJ.controlNvi = nviString; - } - const controlMapWidget = this.ui.getComponent('controlMap'); - if (controlMapWidget.getDisplayModeCycle() !== undefined) { - jsonOBJ.cycle = true; - } - } - - if (this.trackPairs.length > 0 || this.tracks2D.length > 0) { - let tracks = []; - jsonOBJ.tracks = tracks; - for (let trackRenderer of this.trackPairs) { - - const track = trackRenderer.x.track; - const config = track.config; - - if (typeof config.url === "string") { - - const t = {url: config.url}; - - if (config.type) { - t.type = config.type; - } - if (config.format) { - t.format = config.format; - } - if (track.name) { - t.name = track.name; - } - if (track.dataRange) { - t.min = track.dataRange.min; - t.max = track.dataRange.max; - } - if (track.color) { - t.color = track.color; - } - tracks.push(t); - } else if ('sequence' === config.type) { - tracks.push({type: 'sequence', format: 'sequence'}); - } - - } - for (const track2D of this.tracks2D) { - if (typeof track2D.config.url === "string") { - tracks.push(track2D.toJSON()); - } - } - } - - return jsonOBJ - } - - async minZoom(chr1, chr2) { - - const chromosome1 = this.dataset.chromosomes[chr1]; - const chromosome2 = this.dataset.chromosomes[chr2]; - - const { width, height } = this.contactMatrixView.getViewDimensions(); - const binSize = Math.max(chromosome1.size / width, chromosome2.size / height); - - const matrix = await this.dataset.getMatrix(chr1, chr2); - if (!matrix) { - throw new Error(`Data not avaiable for chromosomes ${chromosome1.name} - ${chromosome2.name}`) - } - return matrix.findZoomForResolution(binSize) - } - - async minPixelSize(chr1, chr2, zoomIndex) { - - // bp - const chr1Length = this.dataset.chromosomes[chr1].size; - const chr2Length = this.dataset.chromosomes[chr2].size; - - const matrix = await this.dataset.getMatrix(chr1, chr2); - const { zoom } = matrix.getZoomDataByIndex(zoomIndex, "BP"); - - // bin = bp * bin/bp = bin - const nBins1 = chr1Length / zoom.binSize; - const nBins2 = chr2Length / zoom.binSize; - - const { width, height } = this.contactMatrixView.getViewDimensions(); - - // pixel/bin - return Math.min(width / nBins1, height / nBins2) - - } -} - -/* - * @author Jim Robinson Dec-2020 - */ - -let allBrowsers = []; -let currentBrowser; - -async function createBrowser(hicContainer, config, callback) { - setDefaults(config); - - if (isString$3(config.colorScale)) config.colorScale = ColorScale.parse(config.colorScale); - if (isString$3(config.backgroundColor)) config.backgroundColor = ContactMatrixView.parseBackgroundColor(config.backgroundColor); - - const browser = new HICBrowser(hicContainer, config); - await browser.init(config); - - if (typeof callback === "function") callback(); - - allBrowsers.push(browser); - setCurrentBrowser(browser); - - if (allBrowsers.length > 1) { - allBrowsers.forEach(b => b.browserPanelDeleteButton.style.display = 'block'); - } - - return browser; -} - -async function createBrowserList(hicContainer, session) { - const configList = session.browsers || [session]; - allBrowsers = []; - const initPromises = []; - - for (const config of configList) { - - setDefaults(config); - - if (isString$3(config.colorScale)) { - config.colorScale = ColorScale.parse(config.colorScale); - } - if (isString$3(config.backgroundColor)) { - config.backgroundColor = ContactMatrixView.parseBackgroundColor(config.backgroundColor); - } - if (session.syncDatasets === false) { - config.synchable = false; - } - - const browser = new HICBrowser(hicContainer, config); - allBrowsers.push(browser); - initPromises.push(browser.init(config)); - } - await Promise.all(initPromises); - setCurrentBrowser(allBrowsers[0]); - - if (allBrowsers.length > 1) { - allBrowsers.forEach(b => b.browserPanelDeleteButton.style.display = 'block'); - } -} - -function deleteAllBrowsers() { - for (let b of allBrowsers) { - b.rootElement.remove(); - } - allBrowsers = []; -} - -function setCurrentBrowser(browser) { - if (browser === undefined) { - currentBrowser?.rootElement.classList.remove('hic-root-selected'); - currentBrowser = browser; - return; - } - - if (browser !== currentBrowser) { - currentBrowser?.rootElement.classList.remove('hic-root-selected'); - browser.rootElement.classList.add('hic-root-selected'); - currentBrowser = browser; - EventBus.globalBus.post(HICEvent("BrowserSelect", browser)); - } -} - -function deleteBrowser(browser) { - browser.unsyncSelf(); - browser.rootElement.remove(); - allBrowsers = allBrowsers.filter(b => b !== browser); - if (allBrowsers.length <= 1) { - allBrowsers.forEach(b => b.browserPanelDeleteButton.style.display = 'none'); - } -} - -function getCurrentBrowser() { - return currentBrowser; -} - -function syncBrowsers(browsers) { - const synchableBrowsers = (browsers || allBrowsers).filter(b => b.synchable !== false && b.dataset !== undefined); - - synchableBrowsers.forEach(b1 => { - synchableBrowsers.forEach(b2 => { - if (b1 !== b2 && b1.dataset.isCompatible(b2.dataset)) { - b1.synchedBrowsers.add(b2); - b2.synchedBrowsers.add(b1); - } - }); - }); -} - -function getAllBrowsers() { - return allBrowsers; -} - -function setDefaults(config) { - - if (config.figureMode === true) { - config.showLocusGoto = false; - config.showHicContactMapLabel = false; - config.showChromosomeSelector = false; - } else { - - - config.showLocusGoto = config.showLocusGoto ?? true; - config.showHicContactMapLabel = config.showHicContactMapLabel ?? true; - config.showChromosomeSelector = config.showChromosomeSelector ?? true; - } -} - -const version = "2.5.2"; - //, commit} - -function toJSON() { - const jsonOBJ = {}; - const browserJson = []; - const allBrowsers = getAllBrowsers(); - for (let browser of allBrowsers) { - browserJson.push(browser.toJSON()); - } - jsonOBJ.browsers = browserJson; - - if (Globals.selectedGene) { - jsonOBJ["selectedGene"] = Globals.selectedGene; - } - - const captionDiv = document.getElementById('hic-caption'); - if (captionDiv) { - var captionText = captionDiv.textContent; - if (captionText) { - captionText = captionText.trim(); - if (captionText) { - jsonOBJ.caption = captionText; - } - } - } - - return jsonOBJ; -} - -function compressedSession() { - const jsonString = JSON.stringify(toJSON()); - return `session=blob:${compressString$1(jsonString)}` -} - - -async function restoreSession(container, session) { - - deleteAllBrowsers(); - - if (session.hasOwnProperty("selectedGene")) { - Globals.selectedGene = session.selectedGene; - } - if (session.hasOwnProperty("caption")) { - const captionText = session.caption; - var captionDiv = document.getElementById("hic-caption"); - if (captionDiv) { - captionDiv.textContent = captionText; - } - } - - await createBrowserList(container, session); - - if (false !== session.syncDatasets) { - syncBrowsers(); - } - -} - -/* - * The MIT License (MIT) - * - * Copyright (c) 2016-2017 The Regents of the University of California - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and - * associated documentation files (the "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the - * following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING - * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - */ - -const DEFAULT_ANNOTATION_COLOR = "rgb(22, 129, 198)"; - -const urlShortcuts = { - "*s3e/": "https://hicfiles.s3.amazonaws.com/external/", - "*s3/": "https://hicfiles.s3.amazonaws.com/", - "*s3e_/": "http://hicfiles.s3.amazonaws.com/external/", - "*s3_/": "http://hicfiles.s3.amazonaws.com/", - "*enc/": "https://www.encodeproject.org/files/" -}; - -async function extractConfig(queryString) { - - let query = extractQuery(queryString); - let sessionConfig; - - if (query.hasOwnProperty("session")) { - if (query.session.startsWith("blob:") || query.session.startsWith("data:")) { - sessionConfig = JSON.parse(uncompressString$1(query.session.substr(5))); - } - } - - if (query.hasOwnProperty("juiceboxURL")) { - const jbURL = await expandURL(query["juiceboxURL"]); // Legacy bitly urls - query = extractQuery(jbURL); - } - - if (query.hasOwnProperty("juicebox") || query.hasOwnProperty("juiceboxData")) { - let q; - if (query.hasOwnProperty("juiceboxData")) { - q = uncompressString$1(query["juiceboxData"]); - } else { - q = query["juicebox"]; - if (q.startsWith("%7B")) { - q = decodeURIComponent(q); - } - } - - q = q.substr(1, q.length - 2); // Strip leading and trailing bracket - const parts = q.split("},{"); - const browsers = []; - for (let p of parts) { - const qObj = extractQuery(decodeURIComponent(p)); - browsers.push(decodeQuery(qObj)); - } - sessionConfig = {browsers}; - } - - // Try query parameter style - const uriDecode = true; - const queryConfig = decodeQuery(query, uriDecode); - if (queryConfig.url) { - sessionConfig = queryConfig; - } - - // Fix certain defaults - if (sessionConfig) { - if (sessionConfig.browsers) { - for (let b of sessionConfig.browsers) { - fixDefaults(b); - } - } else { - fixDefaults(sessionConfig); - } - } - - return sessionConfig; - -} - -function fixDefaults(browserConfig) { - if (browserConfig.tracks) { - for (let t of browserConfig.tracks) { - if (t.color === DEFAULT_ANNOTATION_COLOR) { - delete t.color; - } - if (t.min !== undefined && Number.isNaN(t.min)) { - delete t.min; - } - if (t.max !== undefined && Number.isNaN(t.max)) { - delete t.max; - } - t.displayMode = "COLLAPSED"; - } - } -} - - -/** - * Extend config properties with query parameters - * - * @param query - * @param config - */ -function decodeQuery(query, uriDecode) { - - const config = {}; - - let hicUrl = query["hicUrl"]; - const name = query["name"]; - let stateString = query["state"]; - let colorScale = query["colorScale"]; - let trackString = query["tracks"]; - const selectedGene = query["selectedGene"]; - const nvi = query["nvi"]; - - let controlUrl = query["controlUrl"]; - const controlName = query["controlName"]; - const displayMode = query["displayMode"]; - const controlNvi = query["controlNvi"]; - const cycle = query["cycle"]; - - if (hicUrl) { - hicUrl = paramDecode(hicUrl, uriDecode); - Object.keys(urlShortcuts).forEach(function (key) { - var value = urlShortcuts[key]; - if (hicUrl.startsWith(key)) hicUrl = hicUrl.replace(key, value); - }); - config.url = hicUrl; - - } - if (name) { - config.name = paramDecode(name, uriDecode); - } - if (controlUrl) { - controlUrl = paramDecode(controlUrl, uriDecode); - Object.keys(urlShortcuts).forEach(function (key) { - var value = urlShortcuts[key]; - if (controlUrl.startsWith(key)) controlUrl = controlUrl.replace(key, value); - }); - config.controlUrl = controlUrl; - } - if (controlName) { - config.controlName = paramDecode(controlName, uriDecode); - } - - if (stateString) { - stateString = paramDecode(stateString, uriDecode); - config.state = State.parse(stateString); - } - if (colorScale) { - colorScale = paramDecode(colorScale, uriDecode); - config.colorScale = ColorScale.parse(colorScale); - } - - if (displayMode) { - config.displayMode = paramDecode(displayMode, uriDecode); - } - - if (trackString) { - trackString = paramDecode(trackString, uriDecode); - config.tracks = destringifyTracksV0(trackString); - - // If an oAuth token is provided append it to track configs. - if (config.tracks && config.oauthToken) { - config.tracks.forEach(function (t) { - t.oauthToken = config.oauthToken; - }); - } - } - - if (selectedGene) { - Globals.selectedGene = selectedGene; - } - - config.cycle = cycle; - - if (nvi) { - config.nvi = paramDecode(nvi, uriDecode); - } - if (controlNvi) { - config.controlNvi = paramDecode(controlNvi, uriDecode); - } - - return config; - - function destringifyTracksV0(tracks) { - - const trackStringList = tracks.split("|||"); - const configList = []; - for (let trackString of trackStringList) { - - const tokens = trackString.split("|"); - const color = tokens.pop(); - let url = tokens.length > 1 ? tokens[0] : trackString; - if (url && url.trim().length > 0 && "undefined" !== url) { - const keys = Object.keys(urlShortcuts); - for (let key of keys) { - var value = urlShortcuts[key]; - if (url.startsWith(key)) { - url = url.replace(key, value); - break; - } - } - const trackConfig = {url: url}; - - if (tokens.length > 1) { - trackConfig.name = replaceAll(tokens[1], "$", "|"); - } - - if (tokens.length > 2) { - const dataRangeString = tokens[2]; - if (dataRangeString.startsWith("-")) { - const r = dataRangeString.substring(1).split("-"); - trackConfig.min = -parseFloat(r[0]); - trackConfig.max = parseFloat(r[1]); - } else { - const r = dataRangeString.split("-"); - trackConfig.min = parseFloat(r[0]); - trackConfig.max = parseFloat(r[1]); - } - } - - if (color) { - trackConfig.color = color; - } - - configList.push(trackConfig); - } - } - return configList; - } - -} - - -function paramDecode(str, uriDecode) { - - if (uriDecode) { - return decodeURIComponent(str); // Still more backward compatibility - } else { - var s = replaceAll(str, '%26', '&'); - s = replaceAll(s, '%20', ' '); - s = replaceAll(s, '+', ' '); - s = replaceAll(s, "%7C", "|"); - s = replaceAll(s, "%23", "#"); - s = replaceAll(s, "%3F", "?"); - s = replaceAll(s, "%3D", "="); - return s; - } -} - - -function replaceAll(str, target, replacement) { - return str.split(target).join(replacement); -} - -function extractQuery(uri) { - var i1, i2, i, j, s, query, tokens; - - query = {}; - i1 = uri.indexOf("?"); - i2 = uri.lastIndexOf("#"); - const i3 = uri.indexOf("="); - if (i1 > i3) i1 = -1; - - if (i2 < 0) i2 = uri.length; - for (i = i1 + 1; i < i2;) { - - j = uri.indexOf("&", i); - if (j < 0) j = i2; - - s = uri.substring(i, j); - tokens = s.split("=", 2); - if (tokens.length === 2) { - query[tokens[0]] = tokens[1]; - } - - i = j + 1; - - } - return query; -} - -/** - * Expand legacy bitly URLs - * @param url - * @returns {Promise<*>} - */ -async function expandURL(url) { - - const endpoint = `https://api-ssl.bitly.com/v4/expand`; - const id = url.startsWith("http://") ? url.substring(7) : url.substring(8); - const message = { - "bitlink_id": id - }; - - const response = await fetch(endpoint, { - method: 'POST', // or 'PUT' - headers: { - 'Content-Type': 'application/json', - 'Authorization': `Bearer ${btoa("ëtá¾´ãÎtsßéÆºÙçµóf¸í¿9snéÝz")}` - }, - body: JSON.stringify(message), - }); - - if (!response.ok) { - throw new Error(`Network error (${response.status}): ${response.statusText}`) - } - const json = await response.json(); - let longUrl = json.long_url; - - // Fix some Bitly "normalization" - longUrl = longUrl.replace("{", "%7B").replace("}", "%7D"); - return longUrl; - -} - -/* - * The MIT License (MIT) - * - * Copyright (c) 2016-2017 The Regents of the University of California - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and - * associated documentation files (the "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the - * following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING - * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - */ - -async function init$1(container, config) { - - Alert$1.init(container); - - if (false !== config.queryParametersSupported) { - const queryConfig = await extractConfig(window.location.href); - if(queryConfig) { - config= queryConfig; - } - } - - await restoreSession(container, config); - - const allBrowsers = getAllBrowsers(); - - return allBrowsers.length === 1 ? allBrowsers[0] : allBrowsers -} - -/* - * The MIT License (MIT) - * - * Copyright (c) 2016-2017 The Regents of the University of California - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and - * associated documentation files (the "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the - * following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING - * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - */ - -var index = { - version, - init: init$1, - toJSON, - restoreSession, - compressedSession, - createBrowser, - getCurrentBrowser, - setCurrentBrowser, - getAllBrowsers, - igvxhr: igvxhr$1, - EventBus -}; - -export { index as default }; diff --git a/dist/juicebox.js b/dist/juicebox.js deleted file mode 100644 index e1eb5420..00000000 --- a/dist/juicebox.js +++ /dev/null @@ -1,91385 +0,0 @@ -(function (global, factory) { - typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : - typeof define === 'function' && define.amd ? define(factory) : - (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.juicebox = factory()); -})(this, (function () { 'use strict'; - - /** - * Covers string literals and String objects - * @param x - * @returns {boolean} - */ - function isString$3(x) { - return typeof x === "string" || x instanceof String - } - - - // StackOverflow: http://stackoverflow.com/a/10810674/116169 - function numberFormatter$2(rawNumber) { - - var dec = String(rawNumber).split(/[.,]/), - sep = ',', - decsep = '.'; - - return dec[0].split('').reverse().reduce(function (prev, now, i) { - return i % 3 === 0 ? prev + sep + now : prev + now; - }).split('').reverse().join('') + (dec[1] ? decsep + dec[1] : ''); - } - - const numberUnFormatter = formatedNumber => formatedNumber.split(",").join().replace(",", "", "g"); - - const splitLines$6 = function (string) { - return string.split(/\n|\r\n|\r/g); - }; - - function stripQuotes$2(str) { - if(str === undefined) { - return str; - } - if(str.startsWith("'") || str.startsWith('"')) { - str = str.substring(1); - } - if (str.endsWith("'") || str.endsWith('"')) { - str = str.substring(0, str.length - 1); - } - return str; - } - - /** - * Return the filename from the path. Example - * https://foo.com/bar.bed?param=2 => bar.bed - * @param urlOrFile - */ - - function getFilename$3(urlOrFile) { - - if (urlOrFile.name !== undefined) { - return urlOrFile.name - } else if (isString$3(urlOrFile)) { - - let index = urlOrFile.lastIndexOf("/"); - let filename = index < 0 ? urlOrFile : urlOrFile.substr(index + 1); - - //Strip parameters -- handle local files later - index = filename.indexOf("?"); - if (index > 0) { - filename = filename.substr(0, index); - } - return filename - } else { - throw Error(`Expected File or string, got ${typeof urlOrFile}`) - } - } - - - /** - * Test if object is a File or File-like object. - * - * @param object - */ - function isFile$2(object) { - if(!object) { - return false; - } - return typeof object !== 'function' && - (object instanceof File || - (object.hasOwnProperty("name") && typeof object.slice === 'function' && typeof object.arrayBuffer === 'function')) - } - - if (typeof process === 'object' && typeof window === 'undefined') { - global.atob = function (str) { - return Buffer.from(str, 'base64').toString('binary'); - }; - } - - - function parseUri$1(str) { - - var o = options$1, - m = o.parser["loose"].exec(str), - uri = {}, - i = 14; - - while (i--) uri[o.key[i]] = m[i] || ""; - - uri[o.q.name] = {}; - uri[o.key[12]].replace(o.q.parser, function ($0, $1, $2) { - if ($1) uri[o.q.name][$1] = $2; - }); - - return uri; - } - - const options$1 = { - strictMode: false, - key: ["source", "protocol", "authority", "userInfo", "user", "password", "host", "port", "relative", "path", "directory", "file", "query", "anchor"], - q: { - name: "queryKey", - parser: /(?:^|&)([^&=]*)=?([^&]*)/g - }, - parser: { - strict: /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/, - loose: /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/ - } - }; - - /*! pako 2.1.0 https://github.com/nodeca/pako @license (MIT AND Zlib) */ - // (C) 1995-2013 Jean-loup Gailly and Mark Adler - // (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin - // - // This software is provided 'as-is', without any express or implied - // warranty. In no event will the authors be held liable for any damages - // arising from the use of this software. - // - // Permission is granted to anyone to use this software for any purpose, - // including commercial applications, and to alter it and redistribute it - // freely, subject to the following restrictions: - // - // 1. The origin of this software must not be misrepresented; you must not - // claim that you wrote the original software. If you use this software - // in a product, an acknowledgment in the product documentation would be - // appreciated but is not required. - // 2. Altered source versions must be plainly marked as such, and must not be - // misrepresented as being the original software. - // 3. This notice may not be removed or altered from any source distribution. - - /* eslint-disable space-unary-ops */ - - /* Public constants ==========================================================*/ - /* ===========================================================================*/ - - - //const Z_FILTERED = 1; - //const Z_HUFFMAN_ONLY = 2; - //const Z_RLE = 3; - const Z_FIXED$1$1 = 4; - //const Z_DEFAULT_STRATEGY = 0; - - /* Possible values of the data_type field (though see inflate()) */ - const Z_BINARY$1 = 0; - const Z_TEXT$1 = 1; - //const Z_ASCII = 1; // = Z_TEXT - const Z_UNKNOWN$1$1 = 2; - - /*============================================================================*/ - - - function zero$1$2(buf) { let len = buf.length; while (--len >= 0) { buf[len] = 0; } } - - // From zutil.h - - const STORED_BLOCK$1 = 0; - const STATIC_TREES$1 = 1; - const DYN_TREES$1 = 2; - /* The three kinds of block type */ - - const MIN_MATCH$1$2 = 3; - const MAX_MATCH$1$2 = 258; - /* The minimum and maximum match lengths */ - - // From deflate.h - /* =========================================================================== - * Internal compression state. - */ - - const LENGTH_CODES$1$2 = 29; - /* number of length codes, not counting the special END_BLOCK code */ - - const LITERALS$1$2 = 256; - /* number of literal bytes 0..255 */ - - const L_CODES$1$2 = LITERALS$1$2 + 1 + LENGTH_CODES$1$2; - /* number of Literal or Length codes, including the END_BLOCK code */ - - const D_CODES$1$2 = 30; - /* number of distance codes */ - - const BL_CODES$1$1 = 19; - /* number of codes used to transfer the bit lengths */ - - const HEAP_SIZE$1$1 = 2 * L_CODES$1$2 + 1; - /* maximum heap size */ - - const MAX_BITS$1$1 = 15; - /* All codes must not exceed MAX_BITS bits */ - - const Buf_size$1 = 16; - /* size of bit buffer in bi_buf */ - - - /* =========================================================================== - * Constants - */ - - const MAX_BL_BITS$1 = 7; - /* Bit length codes must not exceed MAX_BL_BITS bits */ - - const END_BLOCK$1 = 256; - /* end of block literal code */ - - const REP_3_6$1 = 16; - /* repeat previous bit length 3-6 times (2 bits of repeat count) */ - - const REPZ_3_10$1 = 17; - /* repeat a zero length 3-10 times (3 bits of repeat count) */ - - const REPZ_11_138$1 = 18; - /* repeat a zero length 11-138 times (7 bits of repeat count) */ - - /* eslint-disable comma-spacing,array-bracket-spacing */ - const extra_lbits$1 = /* extra bits for each length code */ - new Uint8Array([0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0]); - - const extra_dbits$1 = /* extra bits for each distance code */ - new Uint8Array([0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13]); - - const extra_blbits$1 = /* extra bits for each bit length code */ - new Uint8Array([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7]); - - const bl_order$1 = - new Uint8Array([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]); - /* eslint-enable comma-spacing,array-bracket-spacing */ - - /* The lengths of the bit length codes are sent in order of decreasing - * probability, to avoid transmitting the lengths for unused bit length codes. - */ - - /* =========================================================================== - * Local data. These are initialized only once. - */ - - // We pre-fill arrays with 0 to avoid uninitialized gaps - - const DIST_CODE_LEN$2 = 512; /* see definition of array dist_code below */ - - // !!!! Use flat array instead of structure, Freq = i*2, Len = i*2+1 - const static_ltree$2 = new Array((L_CODES$1$2 + 2) * 2); - zero$1$2(static_ltree$2); - /* The static literal tree. Since the bit lengths are imposed, there is no - * need for the L_CODES extra codes used during heap construction. However - * The codes 286 and 287 are needed to build a canonical tree (see _tr_init - * below). - */ - - const static_dtree$2 = new Array(D_CODES$1$2 * 2); - zero$1$2(static_dtree$2); - /* The static distance tree. (Actually a trivial tree since all codes use - * 5 bits.) - */ - - const _dist_code$2 = new Array(DIST_CODE_LEN$2); - zero$1$2(_dist_code$2); - /* Distance codes. The first 256 values correspond to the distances - * 3 .. 258, the last 256 values correspond to the top 8 bits of - * the 15 bit distances. - */ - - const _length_code$2 = new Array(MAX_MATCH$1$2 - MIN_MATCH$1$2 + 1); - zero$1$2(_length_code$2); - /* length code for each normalized match length (0 == MIN_MATCH) */ - - const base_length$2 = new Array(LENGTH_CODES$1$2); - zero$1$2(base_length$2); - /* First normalized length for each code (0 = MIN_MATCH) */ - - const base_dist$2 = new Array(D_CODES$1$2); - zero$1$2(base_dist$2); - /* First normalized distance for each code (0 = distance of 1) */ - - - function StaticTreeDesc$1(static_tree, extra_bits, extra_base, elems, max_length) { - - this.static_tree = static_tree; /* static tree or NULL */ - this.extra_bits = extra_bits; /* extra bits for each code or NULL */ - this.extra_base = extra_base; /* base index for extra_bits */ - this.elems = elems; /* max number of elements in the tree */ - this.max_length = max_length; /* max bit length for the codes */ - - // show if `static_tree` has data or dummy - needed for monomorphic objects - this.has_stree = static_tree && static_tree.length; - } - - - let static_l_desc$1; - let static_d_desc$1; - let static_bl_desc$1; - - - function TreeDesc$1(dyn_tree, stat_desc) { - this.dyn_tree = dyn_tree; /* the dynamic tree */ - this.max_code = 0; /* largest code with non zero frequency */ - this.stat_desc = stat_desc; /* the corresponding static tree */ - } - - - - const d_code$1 = (dist) => { - - return dist < 256 ? _dist_code$2[dist] : _dist_code$2[256 + (dist >>> 7)]; - }; - - - /* =========================================================================== - * Output a short LSB first on the stream. - * IN assertion: there is enough room in pendingBuf. - */ - const put_short$1 = (s, w) => { - // put_byte(s, (uch)((w) & 0xff)); - // put_byte(s, (uch)((ush)(w) >> 8)); - s.pending_buf[s.pending++] = (w) & 0xff; - s.pending_buf[s.pending++] = (w >>> 8) & 0xff; - }; - - - /* =========================================================================== - * Send a value on a given number of bits. - * IN assertion: length <= 16 and value fits in length bits. - */ - const send_bits$1 = (s, value, length) => { - - if (s.bi_valid > (Buf_size$1 - length)) { - s.bi_buf |= (value << s.bi_valid) & 0xffff; - put_short$1(s, s.bi_buf); - s.bi_buf = value >> (Buf_size$1 - s.bi_valid); - s.bi_valid += length - Buf_size$1; - } else { - s.bi_buf |= (value << s.bi_valid) & 0xffff; - s.bi_valid += length; - } - }; - - - const send_code$1 = (s, c, tree) => { - - send_bits$1(s, tree[c * 2]/*.Code*/, tree[c * 2 + 1]/*.Len*/); - }; - - - /* =========================================================================== - * Reverse the first len bits of a code, using straightforward code (a faster - * method would use a table) - * IN assertion: 1 <= len <= 15 - */ - const bi_reverse$1 = (code, len) => { - - let res = 0; - do { - res |= code & 1; - code >>>= 1; - res <<= 1; - } while (--len > 0); - return res >>> 1; - }; - - - /* =========================================================================== - * Flush the bit buffer, keeping at most 7 bits in it. - */ - const bi_flush$1 = (s) => { - - if (s.bi_valid === 16) { - put_short$1(s, s.bi_buf); - s.bi_buf = 0; - s.bi_valid = 0; - - } else if (s.bi_valid >= 8) { - s.pending_buf[s.pending++] = s.bi_buf & 0xff; - s.bi_buf >>= 8; - s.bi_valid -= 8; - } - }; - - - /* =========================================================================== - * Compute the optimal bit lengths for a tree and update the total bit length - * for the current block. - * IN assertion: the fields freq and dad are set, heap[heap_max] and - * above are the tree nodes sorted by increasing frequency. - * OUT assertions: the field len is set to the optimal bit length, the - * array bl_count contains the frequencies for each bit length. - * The length opt_len is updated; static_len is also updated if stree is - * not null. - */ - const gen_bitlen$1 = (s, desc) => { - // deflate_state *s; - // tree_desc *desc; /* the tree descriptor */ - - const tree = desc.dyn_tree; - const max_code = desc.max_code; - const stree = desc.stat_desc.static_tree; - const has_stree = desc.stat_desc.has_stree; - const extra = desc.stat_desc.extra_bits; - const base = desc.stat_desc.extra_base; - const max_length = desc.stat_desc.max_length; - let h; /* heap index */ - let n, m; /* iterate over the tree elements */ - let bits; /* bit length */ - let xbits; /* extra bits */ - let f; /* frequency */ - let overflow = 0; /* number of elements with bit length too large */ - - for (bits = 0; bits <= MAX_BITS$1$1; bits++) { - s.bl_count[bits] = 0; - } - - /* In a first pass, compute the optimal bit lengths (which may - * overflow in the case of the bit length tree). - */ - tree[s.heap[s.heap_max] * 2 + 1]/*.Len*/ = 0; /* root of the heap */ - - for (h = s.heap_max + 1; h < HEAP_SIZE$1$1; h++) { - n = s.heap[h]; - bits = tree[tree[n * 2 + 1]/*.Dad*/ * 2 + 1]/*.Len*/ + 1; - if (bits > max_length) { - bits = max_length; - overflow++; - } - tree[n * 2 + 1]/*.Len*/ = bits; - /* We overwrite tree[n].Dad which is no longer needed */ - - if (n > max_code) { continue; } /* not a leaf node */ - - s.bl_count[bits]++; - xbits = 0; - if (n >= base) { - xbits = extra[n - base]; - } - f = tree[n * 2]/*.Freq*/; - s.opt_len += f * (bits + xbits); - if (has_stree) { - s.static_len += f * (stree[n * 2 + 1]/*.Len*/ + xbits); - } - } - if (overflow === 0) { return; } - - // Tracev((stderr,"\nbit length overflow\n")); - /* This happens for example on obj2 and pic of the Calgary corpus */ - - /* Find the first bit length which could increase: */ - do { - bits = max_length - 1; - while (s.bl_count[bits] === 0) { bits--; } - s.bl_count[bits]--; /* move one leaf down the tree */ - s.bl_count[bits + 1] += 2; /* move one overflow item as its brother */ - s.bl_count[max_length]--; - /* The brother of the overflow item also moves one step up, - * but this does not affect bl_count[max_length] - */ - overflow -= 2; - } while (overflow > 0); - - /* Now recompute all bit lengths, scanning in increasing frequency. - * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all - * lengths instead of fixing only the wrong ones. This idea is taken - * from 'ar' written by Haruhiko Okumura.) - */ - for (bits = max_length; bits !== 0; bits--) { - n = s.bl_count[bits]; - while (n !== 0) { - m = s.heap[--h]; - if (m > max_code) { continue; } - if (tree[m * 2 + 1]/*.Len*/ !== bits) { - // Tracev((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits)); - s.opt_len += (bits - tree[m * 2 + 1]/*.Len*/) * tree[m * 2]/*.Freq*/; - tree[m * 2 + 1]/*.Len*/ = bits; - } - n--; - } - } - }; - - - /* =========================================================================== - * Generate the codes for a given tree and bit counts (which need not be - * optimal). - * IN assertion: the array bl_count contains the bit length statistics for - * the given tree and the field len is set for all tree elements. - * OUT assertion: the field code is set for all tree elements of non - * zero code length. - */ - const gen_codes$1 = (tree, max_code, bl_count) => { - // ct_data *tree; /* the tree to decorate */ - // int max_code; /* largest code with non zero frequency */ - // ushf *bl_count; /* number of codes at each bit length */ - - const next_code = new Array(MAX_BITS$1$1 + 1); /* next code value for each bit length */ - let code = 0; /* running code value */ - let bits; /* bit index */ - let n; /* code index */ - - /* The distribution counts are first used to generate the code values - * without bit reversal. - */ - for (bits = 1; bits <= MAX_BITS$1$1; bits++) { - code = (code + bl_count[bits - 1]) << 1; - next_code[bits] = code; - } - /* Check that the bit counts in bl_count are consistent. The last code - * must be all ones. - */ - //Assert (code + bl_count[MAX_BITS]-1 == (1< { - - let n; /* iterates over tree elements */ - let bits; /* bit counter */ - let length; /* length value */ - let code; /* code value */ - let dist; /* distance index */ - const bl_count = new Array(MAX_BITS$1$1 + 1); - /* number of codes at each bit length for an optimal tree */ - - // do check in _tr_init() - //if (static_init_done) return; - - /* For some embedded targets, global variables are not initialized: */ - /*#ifdef NO_INIT_GLOBAL_POINTERS - static_l_desc.static_tree = static_ltree; - static_l_desc.extra_bits = extra_lbits; - static_d_desc.static_tree = static_dtree; - static_d_desc.extra_bits = extra_dbits; - static_bl_desc.extra_bits = extra_blbits; - #endif*/ - - /* Initialize the mapping length (0..255) -> length code (0..28) */ - length = 0; - for (code = 0; code < LENGTH_CODES$1$2 - 1; code++) { - base_length$2[code] = length; - for (n = 0; n < (1 << extra_lbits$1[code]); n++) { - _length_code$2[length++] = code; - } - } - //Assert (length == 256, "tr_static_init: length != 256"); - /* Note that the length 255 (match length 258) can be represented - * in two different ways: code 284 + 5 bits or code 285, so we - * overwrite length_code[255] to use the best encoding: - */ - _length_code$2[length - 1] = code; - - /* Initialize the mapping dist (0..32K) -> dist code (0..29) */ - dist = 0; - for (code = 0; code < 16; code++) { - base_dist$2[code] = dist; - for (n = 0; n < (1 << extra_dbits$1[code]); n++) { - _dist_code$2[dist++] = code; - } - } - //Assert (dist == 256, "tr_static_init: dist != 256"); - dist >>= 7; /* from now on, all distances are divided by 128 */ - for (; code < D_CODES$1$2; code++) { - base_dist$2[code] = dist << 7; - for (n = 0; n < (1 << (extra_dbits$1[code] - 7)); n++) { - _dist_code$2[256 + dist++] = code; - } - } - //Assert (dist == 256, "tr_static_init: 256+dist != 512"); - - /* Construct the codes of the static literal tree */ - for (bits = 0; bits <= MAX_BITS$1$1; bits++) { - bl_count[bits] = 0; - } - - n = 0; - while (n <= 143) { - static_ltree$2[n * 2 + 1]/*.Len*/ = 8; - n++; - bl_count[8]++; - } - while (n <= 255) { - static_ltree$2[n * 2 + 1]/*.Len*/ = 9; - n++; - bl_count[9]++; - } - while (n <= 279) { - static_ltree$2[n * 2 + 1]/*.Len*/ = 7; - n++; - bl_count[7]++; - } - while (n <= 287) { - static_ltree$2[n * 2 + 1]/*.Len*/ = 8; - n++; - bl_count[8]++; - } - /* Codes 286 and 287 do not exist, but we must include them in the - * tree construction to get a canonical Huffman tree (longest code - * all ones) - */ - gen_codes$1(static_ltree$2, L_CODES$1$2 + 1, bl_count); - - /* The static distance tree is trivial: */ - for (n = 0; n < D_CODES$1$2; n++) { - static_dtree$2[n * 2 + 1]/*.Len*/ = 5; - static_dtree$2[n * 2]/*.Code*/ = bi_reverse$1(n, 5); - } - - // Now data ready and we can init static trees - static_l_desc$1 = new StaticTreeDesc$1(static_ltree$2, extra_lbits$1, LITERALS$1$2 + 1, L_CODES$1$2, MAX_BITS$1$1); - static_d_desc$1 = new StaticTreeDesc$1(static_dtree$2, extra_dbits$1, 0, D_CODES$1$2, MAX_BITS$1$1); - static_bl_desc$1 = new StaticTreeDesc$1(new Array(0), extra_blbits$1, 0, BL_CODES$1$1, MAX_BL_BITS$1); - - //static_init_done = true; - }; - - - /* =========================================================================== - * Initialize a new block. - */ - const init_block$1 = (s) => { - - let n; /* iterates over tree elements */ - - /* Initialize the trees. */ - for (n = 0; n < L_CODES$1$2; n++) { s.dyn_ltree[n * 2]/*.Freq*/ = 0; } - for (n = 0; n < D_CODES$1$2; n++) { s.dyn_dtree[n * 2]/*.Freq*/ = 0; } - for (n = 0; n < BL_CODES$1$1; n++) { s.bl_tree[n * 2]/*.Freq*/ = 0; } - - s.dyn_ltree[END_BLOCK$1 * 2]/*.Freq*/ = 1; - s.opt_len = s.static_len = 0; - s.sym_next = s.matches = 0; - }; - - - /* =========================================================================== - * Flush the bit buffer and align the output on a byte boundary - */ - const bi_windup$1 = (s) => - { - if (s.bi_valid > 8) { - put_short$1(s, s.bi_buf); - } else if (s.bi_valid > 0) { - //put_byte(s, (Byte)s->bi_buf); - s.pending_buf[s.pending++] = s.bi_buf; - } - s.bi_buf = 0; - s.bi_valid = 0; - }; - - /* =========================================================================== - * Compares to subtrees, using the tree depth as tie breaker when - * the subtrees have equal frequency. This minimizes the worst case length. - */ - const smaller$1 = (tree, n, m, depth) => { - - const _n2 = n * 2; - const _m2 = m * 2; - return (tree[_n2]/*.Freq*/ < tree[_m2]/*.Freq*/ || - (tree[_n2]/*.Freq*/ === tree[_m2]/*.Freq*/ && depth[n] <= depth[m])); - }; - - /* =========================================================================== - * Restore the heap property by moving down the tree starting at node k, - * exchanging a node with the smallest of its two sons if necessary, stopping - * when the heap property is re-established (each father smaller than its - * two sons). - */ - const pqdownheap$1 = (s, tree, k) => { - // deflate_state *s; - // ct_data *tree; /* the tree to restore */ - // int k; /* node to move down */ - - const v = s.heap[k]; - let j = k << 1; /* left son of k */ - while (j <= s.heap_len) { - /* Set j to the smallest of the two sons: */ - if (j < s.heap_len && - smaller$1(tree, s.heap[j + 1], s.heap[j], s.depth)) { - j++; - } - /* Exit if v is smaller than both sons */ - if (smaller$1(tree, v, s.heap[j], s.depth)) { break; } - - /* Exchange v with the smallest son */ - s.heap[k] = s.heap[j]; - k = j; - - /* And continue down the tree, setting j to the left son of k */ - j <<= 1; - } - s.heap[k] = v; - }; - - - // inlined manually - // const SMALLEST = 1; - - /* =========================================================================== - * Send the block data compressed using the given Huffman trees - */ - const compress_block$1 = (s, ltree, dtree) => { - // deflate_state *s; - // const ct_data *ltree; /* literal tree */ - // const ct_data *dtree; /* distance tree */ - - let dist; /* distance of matched string */ - let lc; /* match length or unmatched char (if dist == 0) */ - let sx = 0; /* running index in sym_buf */ - let code; /* the code to send */ - let extra; /* number of extra bits to send */ - - if (s.sym_next !== 0) { - do { - dist = s.pending_buf[s.sym_buf + sx++] & 0xff; - dist += (s.pending_buf[s.sym_buf + sx++] & 0xff) << 8; - lc = s.pending_buf[s.sym_buf + sx++]; - if (dist === 0) { - send_code$1(s, lc, ltree); /* send a literal byte */ - //Tracecv(isgraph(lc), (stderr," '%c' ", lc)); - } else { - /* Here, lc is the match length - MIN_MATCH */ - code = _length_code$2[lc]; - send_code$1(s, code + LITERALS$1$2 + 1, ltree); /* send the length code */ - extra = extra_lbits$1[code]; - if (extra !== 0) { - lc -= base_length$2[code]; - send_bits$1(s, lc, extra); /* send the extra length bits */ - } - dist--; /* dist is now the match distance - 1 */ - code = d_code$1(dist); - //Assert (code < D_CODES, "bad d_code"); - - send_code$1(s, code, dtree); /* send the distance code */ - extra = extra_dbits$1[code]; - if (extra !== 0) { - dist -= base_dist$2[code]; - send_bits$1(s, dist, extra); /* send the extra distance bits */ - } - } /* literal or match pair ? */ - - /* Check that the overlay between pending_buf and sym_buf is ok: */ - //Assert(s->pending < s->lit_bufsize + sx, "pendingBuf overflow"); - - } while (sx < s.sym_next); - } - - send_code$1(s, END_BLOCK$1, ltree); - }; - - - /* =========================================================================== - * Construct one Huffman tree and assigns the code bit strings and lengths. - * Update the total bit length for the current block. - * IN assertion: the field freq is set for all tree elements. - * OUT assertions: the fields len and code are set to the optimal bit length - * and corresponding code. The length opt_len is updated; static_len is - * also updated if stree is not null. The field max_code is set. - */ - const build_tree$1 = (s, desc) => { - // deflate_state *s; - // tree_desc *desc; /* the tree descriptor */ - - const tree = desc.dyn_tree; - const stree = desc.stat_desc.static_tree; - const has_stree = desc.stat_desc.has_stree; - const elems = desc.stat_desc.elems; - let n, m; /* iterate over heap elements */ - let max_code = -1; /* largest code with non zero frequency */ - let node; /* new node being created */ - - /* Construct the initial heap, with least frequent element in - * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. - * heap[0] is not used. - */ - s.heap_len = 0; - s.heap_max = HEAP_SIZE$1$1; - - for (n = 0; n < elems; n++) { - if (tree[n * 2]/*.Freq*/ !== 0) { - s.heap[++s.heap_len] = max_code = n; - s.depth[n] = 0; - - } else { - tree[n * 2 + 1]/*.Len*/ = 0; - } - } - - /* The pkzip format requires that at least one distance code exists, - * and that at least one bit should be sent even if there is only one - * possible code. So to avoid special checks later on we force at least - * two codes of non zero frequency. - */ - while (s.heap_len < 2) { - node = s.heap[++s.heap_len] = (max_code < 2 ? ++max_code : 0); - tree[node * 2]/*.Freq*/ = 1; - s.depth[node] = 0; - s.opt_len--; - - if (has_stree) { - s.static_len -= stree[node * 2 + 1]/*.Len*/; - } - /* node is 0 or 1 so it does not have extra bits */ - } - desc.max_code = max_code; - - /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, - * establish sub-heaps of increasing lengths: - */ - for (n = (s.heap_len >> 1/*int /2*/); n >= 1; n--) { pqdownheap$1(s, tree, n); } - - /* Construct the Huffman tree by repeatedly combining the least two - * frequent nodes. - */ - node = elems; /* next internal node of the tree */ - do { - //pqremove(s, tree, n); /* n = node of least frequency */ - /*** pqremove ***/ - n = s.heap[1/*SMALLEST*/]; - s.heap[1/*SMALLEST*/] = s.heap[s.heap_len--]; - pqdownheap$1(s, tree, 1/*SMALLEST*/); - /***/ - - m = s.heap[1/*SMALLEST*/]; /* m = node of next least frequency */ - - s.heap[--s.heap_max] = n; /* keep the nodes sorted by frequency */ - s.heap[--s.heap_max] = m; - - /* Create a new node father of n and m */ - tree[node * 2]/*.Freq*/ = tree[n * 2]/*.Freq*/ + tree[m * 2]/*.Freq*/; - s.depth[node] = (s.depth[n] >= s.depth[m] ? s.depth[n] : s.depth[m]) + 1; - tree[n * 2 + 1]/*.Dad*/ = tree[m * 2 + 1]/*.Dad*/ = node; - - /* and insert the new node in the heap */ - s.heap[1/*SMALLEST*/] = node++; - pqdownheap$1(s, tree, 1/*SMALLEST*/); - - } while (s.heap_len >= 2); - - s.heap[--s.heap_max] = s.heap[1/*SMALLEST*/]; - - /* At this point, the fields freq and dad are set. We can now - * generate the bit lengths. - */ - gen_bitlen$1(s, desc); - - /* The field len is now set, we can generate the bit codes */ - gen_codes$1(tree, max_code, s.bl_count); - }; - - - /* =========================================================================== - * Scan a literal or distance tree to determine the frequencies of the codes - * in the bit length tree. - */ - const scan_tree$1 = (s, tree, max_code) => { - // deflate_state *s; - // ct_data *tree; /* the tree to be scanned */ - // int max_code; /* and its largest code of non zero frequency */ - - let n; /* iterates over all tree elements */ - let prevlen = -1; /* last emitted length */ - let curlen; /* length of current code */ - - let nextlen = tree[0 * 2 + 1]/*.Len*/; /* length of next code */ - - let count = 0; /* repeat count of the current code */ - let max_count = 7; /* max repeat count */ - let min_count = 4; /* min repeat count */ - - if (nextlen === 0) { - max_count = 138; - min_count = 3; - } - tree[(max_code + 1) * 2 + 1]/*.Len*/ = 0xffff; /* guard */ - - for (n = 0; n <= max_code; n++) { - curlen = nextlen; - nextlen = tree[(n + 1) * 2 + 1]/*.Len*/; - - if (++count < max_count && curlen === nextlen) { - continue; - - } else if (count < min_count) { - s.bl_tree[curlen * 2]/*.Freq*/ += count; - - } else if (curlen !== 0) { - - if (curlen !== prevlen) { s.bl_tree[curlen * 2]/*.Freq*/++; } - s.bl_tree[REP_3_6$1 * 2]/*.Freq*/++; - - } else if (count <= 10) { - s.bl_tree[REPZ_3_10$1 * 2]/*.Freq*/++; - - } else { - s.bl_tree[REPZ_11_138$1 * 2]/*.Freq*/++; - } - - count = 0; - prevlen = curlen; - - if (nextlen === 0) { - max_count = 138; - min_count = 3; - - } else if (curlen === nextlen) { - max_count = 6; - min_count = 3; - - } else { - max_count = 7; - min_count = 4; - } - } - }; - - - /* =========================================================================== - * Send a literal or distance tree in compressed form, using the codes in - * bl_tree. - */ - const send_tree$1 = (s, tree, max_code) => { - // deflate_state *s; - // ct_data *tree; /* the tree to be scanned */ - // int max_code; /* and its largest code of non zero frequency */ - - let n; /* iterates over all tree elements */ - let prevlen = -1; /* last emitted length */ - let curlen; /* length of current code */ - - let nextlen = tree[0 * 2 + 1]/*.Len*/; /* length of next code */ - - let count = 0; /* repeat count of the current code */ - let max_count = 7; /* max repeat count */ - let min_count = 4; /* min repeat count */ - - /* tree[max_code+1].Len = -1; */ /* guard already set */ - if (nextlen === 0) { - max_count = 138; - min_count = 3; - } - - for (n = 0; n <= max_code; n++) { - curlen = nextlen; - nextlen = tree[(n + 1) * 2 + 1]/*.Len*/; - - if (++count < max_count && curlen === nextlen) { - continue; - - } else if (count < min_count) { - do { send_code$1(s, curlen, s.bl_tree); } while (--count !== 0); - - } else if (curlen !== 0) { - if (curlen !== prevlen) { - send_code$1(s, curlen, s.bl_tree); - count--; - } - //Assert(count >= 3 && count <= 6, " 3_6?"); - send_code$1(s, REP_3_6$1, s.bl_tree); - send_bits$1(s, count - 3, 2); - - } else if (count <= 10) { - send_code$1(s, REPZ_3_10$1, s.bl_tree); - send_bits$1(s, count - 3, 3); - - } else { - send_code$1(s, REPZ_11_138$1, s.bl_tree); - send_bits$1(s, count - 11, 7); - } - - count = 0; - prevlen = curlen; - if (nextlen === 0) { - max_count = 138; - min_count = 3; - - } else if (curlen === nextlen) { - max_count = 6; - min_count = 3; - - } else { - max_count = 7; - min_count = 4; - } - } - }; - - - /* =========================================================================== - * Construct the Huffman tree for the bit lengths and return the index in - * bl_order of the last bit length code to send. - */ - const build_bl_tree$1 = (s) => { - - let max_blindex; /* index of last bit length code of non zero freq */ - - /* Determine the bit length frequencies for literal and distance trees */ - scan_tree$1(s, s.dyn_ltree, s.l_desc.max_code); - scan_tree$1(s, s.dyn_dtree, s.d_desc.max_code); - - /* Build the bit length tree: */ - build_tree$1(s, s.bl_desc); - /* opt_len now includes the length of the tree representations, except - * the lengths of the bit lengths codes and the 5+5+4 bits for the counts. - */ - - /* Determine the number of bit length codes to send. The pkzip format - * requires that at least 4 bit length codes be sent. (appnote.txt says - * 3 but the actual value used is 4.) - */ - for (max_blindex = BL_CODES$1$1 - 1; max_blindex >= 3; max_blindex--) { - if (s.bl_tree[bl_order$1[max_blindex] * 2 + 1]/*.Len*/ !== 0) { - break; - } - } - /* Update opt_len to include the bit length tree and counts */ - s.opt_len += 3 * (max_blindex + 1) + 5 + 5 + 4; - //Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", - // s->opt_len, s->static_len)); - - return max_blindex; - }; - - - /* =========================================================================== - * Send the header for a block using dynamic Huffman trees: the counts, the - * lengths of the bit length codes, the literal tree and the distance tree. - * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. - */ - const send_all_trees$1 = (s, lcodes, dcodes, blcodes) => { - // deflate_state *s; - // int lcodes, dcodes, blcodes; /* number of codes for each tree */ - - let rank; /* index in bl_order */ - - //Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); - //Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, - // "too many codes"); - //Tracev((stderr, "\nbl counts: ")); - send_bits$1(s, lcodes - 257, 5); /* not +255 as stated in appnote.txt */ - send_bits$1(s, dcodes - 1, 5); - send_bits$1(s, blcodes - 4, 4); /* not -3 as stated in appnote.txt */ - for (rank = 0; rank < blcodes; rank++) { - //Tracev((stderr, "\nbl code %2d ", bl_order[rank])); - send_bits$1(s, s.bl_tree[bl_order$1[rank] * 2 + 1]/*.Len*/, 3); - } - //Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent)); - - send_tree$1(s, s.dyn_ltree, lcodes - 1); /* literal tree */ - //Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent)); - - send_tree$1(s, s.dyn_dtree, dcodes - 1); /* distance tree */ - //Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent)); - }; - - - /* =========================================================================== - * Check if the data type is TEXT or BINARY, using the following algorithm: - * - TEXT if the two conditions below are satisfied: - * a) There are no non-portable control characters belonging to the - * "block list" (0..6, 14..25, 28..31). - * b) There is at least one printable character belonging to the - * "allow list" (9 {TAB}, 10 {LF}, 13 {CR}, 32..255). - * - BINARY otherwise. - * - The following partially-portable control characters form a - * "gray list" that is ignored in this detection algorithm: - * (7 {BEL}, 8 {BS}, 11 {VT}, 12 {FF}, 26 {SUB}, 27 {ESC}). - * IN assertion: the fields Freq of dyn_ltree are set. - */ - const detect_data_type$1 = (s) => { - /* block_mask is the bit mask of block-listed bytes - * set bits 0..6, 14..25, and 28..31 - * 0xf3ffc07f = binary 11110011111111111100000001111111 - */ - let block_mask = 0xf3ffc07f; - let n; - - /* Check for non-textual ("block-listed") bytes. */ - for (n = 0; n <= 31; n++, block_mask >>>= 1) { - if ((block_mask & 1) && (s.dyn_ltree[n * 2]/*.Freq*/ !== 0)) { - return Z_BINARY$1; - } - } - - /* Check for textual ("allow-listed") bytes. */ - if (s.dyn_ltree[9 * 2]/*.Freq*/ !== 0 || s.dyn_ltree[10 * 2]/*.Freq*/ !== 0 || - s.dyn_ltree[13 * 2]/*.Freq*/ !== 0) { - return Z_TEXT$1; - } - for (n = 32; n < LITERALS$1$2; n++) { - if (s.dyn_ltree[n * 2]/*.Freq*/ !== 0) { - return Z_TEXT$1; - } - } - - /* There are no "block-listed" or "allow-listed" bytes: - * this stream either is empty or has tolerated ("gray-listed") bytes only. - */ - return Z_BINARY$1; - }; - - - let static_init_done$1 = false; - - /* =========================================================================== - * Initialize the tree data structures for a new zlib stream. - */ - const _tr_init$1$1 = (s) => - { - - if (!static_init_done$1) { - tr_static_init$1(); - static_init_done$1 = true; - } - - s.l_desc = new TreeDesc$1(s.dyn_ltree, static_l_desc$1); - s.d_desc = new TreeDesc$1(s.dyn_dtree, static_d_desc$1); - s.bl_desc = new TreeDesc$1(s.bl_tree, static_bl_desc$1); - - s.bi_buf = 0; - s.bi_valid = 0; - - /* Initialize the first block of the first file: */ - init_block$1(s); - }; - - - /* =========================================================================== - * Send a stored block - */ - const _tr_stored_block$1$1 = (s, buf, stored_len, last) => { - //DeflateState *s; - //charf *buf; /* input block */ - //ulg stored_len; /* length of input block */ - //int last; /* one if this is the last block for a file */ - - send_bits$1(s, (STORED_BLOCK$1 << 1) + (last ? 1 : 0), 3); /* send block type */ - bi_windup$1(s); /* align on byte boundary */ - put_short$1(s, stored_len); - put_short$1(s, ~stored_len); - if (stored_len) { - s.pending_buf.set(s.window.subarray(buf, buf + stored_len), s.pending); - } - s.pending += stored_len; - }; - - - /* =========================================================================== - * Send one empty static block to give enough lookahead for inflate. - * This takes 10 bits, of which 7 may remain in the bit buffer. - */ - const _tr_align$1$1 = (s) => { - send_bits$1(s, STATIC_TREES$1 << 1, 3); - send_code$1(s, END_BLOCK$1, static_ltree$2); - bi_flush$1(s); - }; - - - /* =========================================================================== - * Determine the best encoding for the current block: dynamic trees, static - * trees or store, and write out the encoded block. - */ - const _tr_flush_block$1$1 = (s, buf, stored_len, last) => { - //DeflateState *s; - //charf *buf; /* input block, or NULL if too old */ - //ulg stored_len; /* length of input block */ - //int last; /* one if this is the last block for a file */ - - let opt_lenb, static_lenb; /* opt_len and static_len in bytes */ - let max_blindex = 0; /* index of last bit length code of non zero freq */ - - /* Build the Huffman trees unless a stored block is forced */ - if (s.level > 0) { - - /* Check if the file is binary or text */ - if (s.strm.data_type === Z_UNKNOWN$1$1) { - s.strm.data_type = detect_data_type$1(s); - } - - /* Construct the literal and distance trees */ - build_tree$1(s, s.l_desc); - // Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len, - // s->static_len)); - - build_tree$1(s, s.d_desc); - // Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len, - // s->static_len)); - /* At this point, opt_len and static_len are the total bit lengths of - * the compressed block data, excluding the tree representations. - */ - - /* Build the bit length tree for the above two trees, and get the index - * in bl_order of the last bit length code to send. - */ - max_blindex = build_bl_tree$1(s); - - /* Determine the best encoding. Compute the block lengths in bytes. */ - opt_lenb = (s.opt_len + 3 + 7) >>> 3; - static_lenb = (s.static_len + 3 + 7) >>> 3; - - // Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ", - // opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len, - // s->sym_next / 3)); - - if (static_lenb <= opt_lenb) { opt_lenb = static_lenb; } - - } else { - // Assert(buf != (char*)0, "lost buf"); - opt_lenb = static_lenb = stored_len + 5; /* force a stored block */ - } - - if ((stored_len + 4 <= opt_lenb) && (buf !== -1)) { - /* 4: two words for the lengths */ - - /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. - * Otherwise we can't have processed more than WSIZE input bytes since - * the last block flush, because compression would have been - * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to - * transform a block into a stored block. - */ - _tr_stored_block$1$1(s, buf, stored_len, last); - - } else if (s.strategy === Z_FIXED$1$1 || static_lenb === opt_lenb) { - - send_bits$1(s, (STATIC_TREES$1 << 1) + (last ? 1 : 0), 3); - compress_block$1(s, static_ltree$2, static_dtree$2); - - } else { - send_bits$1(s, (DYN_TREES$1 << 1) + (last ? 1 : 0), 3); - send_all_trees$1(s, s.l_desc.max_code + 1, s.d_desc.max_code + 1, max_blindex + 1); - compress_block$1(s, s.dyn_ltree, s.dyn_dtree); - } - // Assert (s->compressed_len == s->bits_sent, "bad compressed size"); - /* The above check is made mod 2^32, for files larger than 512 MB - * and uLong implemented on 32 bits. - */ - init_block$1(s); - - if (last) { - bi_windup$1(s); - } - // Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3, - // s->compressed_len-7*last)); - }; - - /* =========================================================================== - * Save the match info and tally the frequency counts. Return true if - * the current block must be flushed. - */ - const _tr_tally$1$1 = (s, dist, lc) => { - // deflate_state *s; - // unsigned dist; /* distance of matched string */ - // unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */ - - s.pending_buf[s.sym_buf + s.sym_next++] = dist; - s.pending_buf[s.sym_buf + s.sym_next++] = dist >> 8; - s.pending_buf[s.sym_buf + s.sym_next++] = lc; - if (dist === 0) { - /* lc is the unmatched char */ - s.dyn_ltree[lc * 2]/*.Freq*/++; - } else { - s.matches++; - /* Here, lc is the match length - MIN_MATCH */ - dist--; /* dist = match distance - 1 */ - //Assert((ush)dist < (ush)MAX_DIST(s) && - // (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) && - // (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match"); - - s.dyn_ltree[(_length_code$2[lc] + LITERALS$1$2 + 1) * 2]/*.Freq*/++; - s.dyn_dtree[d_code$1(dist) * 2]/*.Freq*/++; - } - - return (s.sym_next === s.sym_end); - }; - - var _tr_init_1$1 = _tr_init$1$1; - var _tr_stored_block_1$1 = _tr_stored_block$1$1; - var _tr_flush_block_1$1 = _tr_flush_block$1$1; - var _tr_tally_1$1 = _tr_tally$1$1; - var _tr_align_1$1 = _tr_align$1$1; - - var trees$1 = { - _tr_init: _tr_init_1$1, - _tr_stored_block: _tr_stored_block_1$1, - _tr_flush_block: _tr_flush_block_1$1, - _tr_tally: _tr_tally_1$1, - _tr_align: _tr_align_1$1 - }; - - // Note: adler32 takes 12% for level 0 and 2% for level 6. - // It isn't worth it to make additional optimizations as in original. - // Small size is preferable. - - // (C) 1995-2013 Jean-loup Gailly and Mark Adler - // (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin - // - // This software is provided 'as-is', without any express or implied - // warranty. In no event will the authors be held liable for any damages - // arising from the use of this software. - // - // Permission is granted to anyone to use this software for any purpose, - // including commercial applications, and to alter it and redistribute it - // freely, subject to the following restrictions: - // - // 1. The origin of this software must not be misrepresented; you must not - // claim that you wrote the original software. If you use this software - // in a product, an acknowledgment in the product documentation would be - // appreciated but is not required. - // 2. Altered source versions must be plainly marked as such, and must not be - // misrepresented as being the original software. - // 3. This notice may not be removed or altered from any source distribution. - - const adler32$2 = (adler, buf, len, pos) => { - let s1 = (adler & 0xffff) |0, - s2 = ((adler >>> 16) & 0xffff) |0, - n = 0; - - while (len !== 0) { - // Set limit ~ twice less than 5552, to keep - // s2 in 31-bits, because we force signed ints. - // in other case %= will fail. - n = len > 2000 ? 2000 : len; - len -= n; - - do { - s1 = (s1 + buf[pos++]) |0; - s2 = (s2 + s1) |0; - } while (--n); - - s1 %= 65521; - s2 %= 65521; - } - - return (s1 | (s2 << 16)) |0; - }; - - - var adler32_1$2 = adler32$2; - - // Note: we can't get significant speed boost here. - // So write code to minimize size - no pregenerated tables - // and array tools dependencies. - - // (C) 1995-2013 Jean-loup Gailly and Mark Adler - // (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin - // - // This software is provided 'as-is', without any express or implied - // warranty. In no event will the authors be held liable for any damages - // arising from the use of this software. - // - // Permission is granted to anyone to use this software for any purpose, - // including commercial applications, and to alter it and redistribute it - // freely, subject to the following restrictions: - // - // 1. The origin of this software must not be misrepresented; you must not - // claim that you wrote the original software. If you use this software - // in a product, an acknowledgment in the product documentation would be - // appreciated but is not required. - // 2. Altered source versions must be plainly marked as such, and must not be - // misrepresented as being the original software. - // 3. This notice may not be removed or altered from any source distribution. - - // Use ordinary array, since untyped makes no boost here - const makeTable$2 = () => { - let c, table = []; - - for (var n = 0; n < 256; n++) { - c = n; - for (var k = 0; k < 8; k++) { - c = ((c & 1) ? (0xEDB88320 ^ (c >>> 1)) : (c >>> 1)); - } - table[n] = c; - } - - return table; - }; - - // Create table on load. Just 255 signed longs. Not a problem. - const crcTable$2 = new Uint32Array(makeTable$2()); - - - const crc32$2 = (crc, buf, len, pos) => { - const t = crcTable$2; - const end = pos + len; - - crc ^= -1; - - for (let i = pos; i < end; i++) { - crc = (crc >>> 8) ^ t[(crc ^ buf[i]) & 0xFF]; - } - - return (crc ^ (-1)); // >>> 0; - }; - - - var crc32_1$2 = crc32$2; - - // (C) 1995-2013 Jean-loup Gailly and Mark Adler - // (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin - // - // This software is provided 'as-is', without any express or implied - // warranty. In no event will the authors be held liable for any damages - // arising from the use of this software. - // - // Permission is granted to anyone to use this software for any purpose, - // including commercial applications, and to alter it and redistribute it - // freely, subject to the following restrictions: - // - // 1. The origin of this software must not be misrepresented; you must not - // claim that you wrote the original software. If you use this software - // in a product, an acknowledgment in the product documentation would be - // appreciated but is not required. - // 2. Altered source versions must be plainly marked as such, and must not be - // misrepresented as being the original software. - // 3. This notice may not be removed or altered from any source distribution. - - var messages$2 = { - 2: 'need dictionary', /* Z_NEED_DICT 2 */ - 1: 'stream end', /* Z_STREAM_END 1 */ - 0: '', /* Z_OK 0 */ - '-1': 'file error', /* Z_ERRNO (-1) */ - '-2': 'stream error', /* Z_STREAM_ERROR (-2) */ - '-3': 'data error', /* Z_DATA_ERROR (-3) */ - '-4': 'insufficient memory', /* Z_MEM_ERROR (-4) */ - '-5': 'buffer error', /* Z_BUF_ERROR (-5) */ - '-6': 'incompatible version' /* Z_VERSION_ERROR (-6) */ - }; - - // (C) 1995-2013 Jean-loup Gailly and Mark Adler - // (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin - // - // This software is provided 'as-is', without any express or implied - // warranty. In no event will the authors be held liable for any damages - // arising from the use of this software. - // - // Permission is granted to anyone to use this software for any purpose, - // including commercial applications, and to alter it and redistribute it - // freely, subject to the following restrictions: - // - // 1. The origin of this software must not be misrepresented; you must not - // claim that you wrote the original software. If you use this software - // in a product, an acknowledgment in the product documentation would be - // appreciated but is not required. - // 2. Altered source versions must be plainly marked as such, and must not be - // misrepresented as being the original software. - // 3. This notice may not be removed or altered from any source distribution. - - var constants$2$2 = { - - /* Allowed flush values; see deflate() and inflate() below for details */ - Z_NO_FLUSH: 0, - Z_PARTIAL_FLUSH: 1, - Z_SYNC_FLUSH: 2, - Z_FULL_FLUSH: 3, - Z_FINISH: 4, - Z_BLOCK: 5, - Z_TREES: 6, - - /* Return codes for the compression/decompression functions. Negative values - * are errors, positive values are used for special but normal events. - */ - Z_OK: 0, - Z_STREAM_END: 1, - Z_NEED_DICT: 2, - Z_ERRNO: -1, - Z_STREAM_ERROR: -2, - Z_DATA_ERROR: -3, - Z_MEM_ERROR: -4, - Z_BUF_ERROR: -5, - //Z_VERSION_ERROR: -6, - - /* compression levels */ - Z_NO_COMPRESSION: 0, - Z_BEST_SPEED: 1, - Z_BEST_COMPRESSION: 9, - Z_DEFAULT_COMPRESSION: -1, - - - Z_FILTERED: 1, - Z_HUFFMAN_ONLY: 2, - Z_RLE: 3, - Z_FIXED: 4, - Z_DEFAULT_STRATEGY: 0, - - /* Possible values of the data_type field (though see inflate()) */ - Z_BINARY: 0, - Z_TEXT: 1, - //Z_ASCII: 1, // = Z_TEXT (deprecated) - Z_UNKNOWN: 2, - - /* The deflate compression method */ - Z_DEFLATED: 8 - //Z_NULL: null // Use -1 or null inline, depending on var type - }; - - // (C) 1995-2013 Jean-loup Gailly and Mark Adler - // (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin - // - // This software is provided 'as-is', without any express or implied - // warranty. In no event will the authors be held liable for any damages - // arising from the use of this software. - // - // Permission is granted to anyone to use this software for any purpose, - // including commercial applications, and to alter it and redistribute it - // freely, subject to the following restrictions: - // - // 1. The origin of this software must not be misrepresented; you must not - // claim that you wrote the original software. If you use this software - // in a product, an acknowledgment in the product documentation would be - // appreciated but is not required. - // 2. Altered source versions must be plainly marked as such, and must not be - // misrepresented as being the original software. - // 3. This notice may not be removed or altered from any source distribution. - - const { _tr_init: _tr_init$2, _tr_stored_block: _tr_stored_block$2, _tr_flush_block: _tr_flush_block$2, _tr_tally: _tr_tally$2, _tr_align: _tr_align$2 } = trees$1; - - - - - /* Public constants ==========================================================*/ - /* ===========================================================================*/ - - const { - Z_NO_FLUSH: Z_NO_FLUSH$2$1, Z_PARTIAL_FLUSH: Z_PARTIAL_FLUSH$1, Z_FULL_FLUSH: Z_FULL_FLUSH$1$1, Z_FINISH: Z_FINISH$3$1, Z_BLOCK: Z_BLOCK$1$1, - Z_OK: Z_OK$3$1, Z_STREAM_END: Z_STREAM_END$3$1, Z_STREAM_ERROR: Z_STREAM_ERROR$2$1, Z_DATA_ERROR: Z_DATA_ERROR$2$1, Z_BUF_ERROR: Z_BUF_ERROR$1$1, - Z_DEFAULT_COMPRESSION: Z_DEFAULT_COMPRESSION$1$1, - Z_FILTERED: Z_FILTERED$1, Z_HUFFMAN_ONLY: Z_HUFFMAN_ONLY$1, Z_RLE: Z_RLE$1, Z_FIXED: Z_FIXED$2, Z_DEFAULT_STRATEGY: Z_DEFAULT_STRATEGY$1$1, - Z_UNKNOWN: Z_UNKNOWN$2, - Z_DEFLATED: Z_DEFLATED$2$1 - } = constants$2$2; - - /*============================================================================*/ - - - const MAX_MEM_LEVEL$1 = 9; - /* Maximum value for memLevel in deflateInit2 */ - const MAX_WBITS$1$1 = 15; - /* 32K LZ77 window */ - const DEF_MEM_LEVEL$1 = 8; - - - const LENGTH_CODES$2 = 29; - /* number of length codes, not counting the special END_BLOCK code */ - const LITERALS$2 = 256; - /* number of literal bytes 0..255 */ - const L_CODES$2 = LITERALS$2 + 1 + LENGTH_CODES$2; - /* number of Literal or Length codes, including the END_BLOCK code */ - const D_CODES$2 = 30; - /* number of distance codes */ - const BL_CODES$2 = 19; - /* number of codes used to transfer the bit lengths */ - const HEAP_SIZE$2 = 2 * L_CODES$2 + 1; - /* maximum heap size */ - const MAX_BITS$2 = 15; - /* All codes must not exceed MAX_BITS bits */ - - const MIN_MATCH$2 = 3; - const MAX_MATCH$2 = 258; - const MIN_LOOKAHEAD$1 = (MAX_MATCH$2 + MIN_MATCH$2 + 1); - - const PRESET_DICT$1 = 0x20; - - const INIT_STATE$1 = 42; /* zlib header -> BUSY_STATE */ - //#ifdef GZIP - const GZIP_STATE$1 = 57; /* gzip header -> BUSY_STATE | EXTRA_STATE */ - //#endif - const EXTRA_STATE$1 = 69; /* gzip extra block -> NAME_STATE */ - const NAME_STATE$1 = 73; /* gzip file name -> COMMENT_STATE */ - const COMMENT_STATE$1 = 91; /* gzip comment -> HCRC_STATE */ - const HCRC_STATE$1 = 103; /* gzip header CRC -> BUSY_STATE */ - const BUSY_STATE$1 = 113; /* deflate -> FINISH_STATE */ - const FINISH_STATE$1 = 666; /* stream complete */ - - const BS_NEED_MORE$1 = 1; /* block not completed, need more input or more output */ - const BS_BLOCK_DONE$1 = 2; /* block flush performed */ - const BS_FINISH_STARTED$1 = 3; /* finish started, need only more output at next deflate */ - const BS_FINISH_DONE$1 = 4; /* finish done, accept no more input or output */ - - const OS_CODE$1 = 0x03; // Unix :) . Don't detect, use this default. - - const err$1 = (strm, errorCode) => { - strm.msg = messages$2[errorCode]; - return errorCode; - }; - - const rank$1 = (f) => { - return ((f) * 2) - ((f) > 4 ? 9 : 0); - }; - - const zero$2 = (buf) => { - let len = buf.length; while (--len >= 0) { buf[len] = 0; } - }; - - /* =========================================================================== - * Slide the hash table when sliding the window down (could be avoided with 32 - * bit values at the expense of memory usage). We slide even when level == 0 to - * keep the hash table consistent if we switch back to level > 0 later. - */ - const slide_hash$1 = (s) => { - let n, m; - let p; - let wsize = s.w_size; - - n = s.hash_size; - p = n; - do { - m = s.head[--p]; - s.head[p] = (m >= wsize ? m - wsize : 0); - } while (--n); - n = wsize; - //#ifndef FASTEST - p = n; - do { - m = s.prev[--p]; - s.prev[p] = (m >= wsize ? m - wsize : 0); - /* If n is not on any hash chain, prev[n] is garbage but - * its value will never be used. - */ - } while (--n); - //#endif - }; - - /* eslint-disable new-cap */ - let HASH_ZLIB$1 = (s, prev, data) => ((prev << s.hash_shift) ^ data) & s.hash_mask; - // This hash causes less collisions, https://github.com/nodeca/pako/issues/135 - // But breaks binary compatibility - //let HASH_FAST = (s, prev, data) => ((prev << 8) + (prev >> 8) + (data << 4)) & s.hash_mask; - let HASH$1 = HASH_ZLIB$1; - - - /* ========================================================================= - * Flush as much pending output as possible. All deflate() output, except for - * some deflate_stored() output, goes through this function so some - * applications may wish to modify it to avoid allocating a large - * strm->next_out buffer and copying into it. (See also read_buf()). - */ - const flush_pending$1 = (strm) => { - const s = strm.state; - - //_tr_flush_bits(s); - let len = s.pending; - if (len > strm.avail_out) { - len = strm.avail_out; - } - if (len === 0) { return; } - - strm.output.set(s.pending_buf.subarray(s.pending_out, s.pending_out + len), strm.next_out); - strm.next_out += len; - s.pending_out += len; - strm.total_out += len; - strm.avail_out -= len; - s.pending -= len; - if (s.pending === 0) { - s.pending_out = 0; - } - }; - - - const flush_block_only$1 = (s, last) => { - _tr_flush_block$2(s, (s.block_start >= 0 ? s.block_start : -1), s.strstart - s.block_start, last); - s.block_start = s.strstart; - flush_pending$1(s.strm); - }; - - - const put_byte$1 = (s, b) => { - s.pending_buf[s.pending++] = b; - }; - - - /* ========================================================================= - * Put a short in the pending buffer. The 16-bit value is put in MSB order. - * IN assertion: the stream state is correct and there is enough room in - * pending_buf. - */ - const putShortMSB$1 = (s, b) => { - - // put_byte(s, (Byte)(b >> 8)); - // put_byte(s, (Byte)(b & 0xff)); - s.pending_buf[s.pending++] = (b >>> 8) & 0xff; - s.pending_buf[s.pending++] = b & 0xff; - }; - - - /* =========================================================================== - * Read a new buffer from the current input stream, update the adler32 - * and total number of bytes read. All deflate() input goes through - * this function so some applications may wish to modify it to avoid - * allocating a large strm->input buffer and copying from it. - * (See also flush_pending()). - */ - const read_buf$1 = (strm, buf, start, size) => { - - let len = strm.avail_in; - - if (len > size) { len = size; } - if (len === 0) { return 0; } - - strm.avail_in -= len; - - // zmemcpy(buf, strm->next_in, len); - buf.set(strm.input.subarray(strm.next_in, strm.next_in + len), start); - if (strm.state.wrap === 1) { - strm.adler = adler32_1$2(strm.adler, buf, len, start); - } - - else if (strm.state.wrap === 2) { - strm.adler = crc32_1$2(strm.adler, buf, len, start); - } - - strm.next_in += len; - strm.total_in += len; - - return len; - }; - - - /* =========================================================================== - * Set match_start to the longest match starting at the given string and - * return its length. Matches shorter or equal to prev_length are discarded, - * in which case the result is equal to prev_length and match_start is - * garbage. - * IN assertions: cur_match is the head of the hash chain for the current - * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 - * OUT assertion: the match length is not greater than s->lookahead. - */ - const longest_match$1 = (s, cur_match) => { - - let chain_length = s.max_chain_length; /* max hash chain length */ - let scan = s.strstart; /* current string */ - let match; /* matched string */ - let len; /* length of current match */ - let best_len = s.prev_length; /* best match length so far */ - let nice_match = s.nice_match; /* stop if match long enough */ - const limit = (s.strstart > (s.w_size - MIN_LOOKAHEAD$1)) ? - s.strstart - (s.w_size - MIN_LOOKAHEAD$1) : 0/*NIL*/; - - const _win = s.window; // shortcut - - const wmask = s.w_mask; - const prev = s.prev; - - /* Stop when cur_match becomes <= limit. To simplify the code, - * we prevent matches with the string of window index 0. - */ - - const strend = s.strstart + MAX_MATCH$2; - let scan_end1 = _win[scan + best_len - 1]; - let scan_end = _win[scan + best_len]; - - /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. - * It is easy to get rid of this optimization if necessary. - */ - // Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); - - /* Do not waste too much time if we already have a good match: */ - if (s.prev_length >= s.good_match) { - chain_length >>= 2; - } - /* Do not look for matches beyond the end of the input. This is necessary - * to make deflate deterministic. - */ - if (nice_match > s.lookahead) { nice_match = s.lookahead; } - - // Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); - - do { - // Assert(cur_match < s->strstart, "no future"); - match = cur_match; - - /* Skip to next match if the match length cannot increase - * or if the match length is less than 2. Note that the checks below - * for insufficient lookahead only occur occasionally for performance - * reasons. Therefore uninitialized memory will be accessed, and - * conditional jumps will be made that depend on those values. - * However the length of the match is limited to the lookahead, so - * the output of deflate is not affected by the uninitialized values. - */ - - if (_win[match + best_len] !== scan_end || - _win[match + best_len - 1] !== scan_end1 || - _win[match] !== _win[scan] || - _win[++match] !== _win[scan + 1]) { - continue; - } - - /* The check at best_len-1 can be removed because it will be made - * again later. (This heuristic is not always a win.) - * It is not necessary to compare scan[2] and match[2] since they - * are always equal when the other bytes match, given that - * the hash keys are equal and that HASH_BITS >= 8. - */ - scan += 2; - match++; - // Assert(*scan == *match, "match[2]?"); - - /* We check for insufficient lookahead only every 8th comparison; - * the 256th check will be made at strstart+258. - */ - do { - /*jshint noempty:false*/ - } while (_win[++scan] === _win[++match] && _win[++scan] === _win[++match] && - _win[++scan] === _win[++match] && _win[++scan] === _win[++match] && - _win[++scan] === _win[++match] && _win[++scan] === _win[++match] && - _win[++scan] === _win[++match] && _win[++scan] === _win[++match] && - scan < strend); - - // Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); - - len = MAX_MATCH$2 - (strend - scan); - scan = strend - MAX_MATCH$2; - - if (len > best_len) { - s.match_start = cur_match; - best_len = len; - if (len >= nice_match) { - break; - } - scan_end1 = _win[scan + best_len - 1]; - scan_end = _win[scan + best_len]; - } - } while ((cur_match = prev[cur_match & wmask]) > limit && --chain_length !== 0); - - if (best_len <= s.lookahead) { - return best_len; - } - return s.lookahead; - }; - - - /* =========================================================================== - * Fill the window when the lookahead becomes insufficient. - * Updates strstart and lookahead. - * - * IN assertion: lookahead < MIN_LOOKAHEAD - * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD - * At least one byte has been read, or avail_in == 0; reads are - * performed for at least two bytes (required for the zip translate_eol - * option -- not supported here). - */ - const fill_window$1 = (s) => { - - const _w_size = s.w_size; - let n, more, str; - - //Assert(s->lookahead < MIN_LOOKAHEAD, "already enough lookahead"); - - do { - more = s.window_size - s.lookahead - s.strstart; - - // JS ints have 32 bit, block below not needed - /* Deal with !@#$% 64K limit: */ - //if (sizeof(int) <= 2) { - // if (more == 0 && s->strstart == 0 && s->lookahead == 0) { - // more = wsize; - // - // } else if (more == (unsigned)(-1)) { - // /* Very unlikely, but possible on 16 bit machine if - // * strstart == 0 && lookahead == 1 (input done a byte at time) - // */ - // more--; - // } - //} - - - /* If the window is almost full and there is insufficient lookahead, - * move the upper half to the lower one to make room in the upper half. - */ - if (s.strstart >= _w_size + (_w_size - MIN_LOOKAHEAD$1)) { - - s.window.set(s.window.subarray(_w_size, _w_size + _w_size - more), 0); - s.match_start -= _w_size; - s.strstart -= _w_size; - /* we now have strstart >= MAX_DIST */ - s.block_start -= _w_size; - if (s.insert > s.strstart) { - s.insert = s.strstart; - } - slide_hash$1(s); - more += _w_size; - } - if (s.strm.avail_in === 0) { - break; - } - - /* If there was no sliding: - * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && - * more == window_size - lookahead - strstart - * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) - * => more >= window_size - 2*WSIZE + 2 - * In the BIG_MEM or MMAP case (not yet supported), - * window_size == input_size + MIN_LOOKAHEAD && - * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. - * Otherwise, window_size == 2*WSIZE so more >= 2. - * If there was sliding, more >= WSIZE. So in all cases, more >= 2. - */ - //Assert(more >= 2, "more < 2"); - n = read_buf$1(s.strm, s.window, s.strstart + s.lookahead, more); - s.lookahead += n; - - /* Initialize the hash value now that we have some input: */ - if (s.lookahead + s.insert >= MIN_MATCH$2) { - str = s.strstart - s.insert; - s.ins_h = s.window[str]; - - /* UPDATE_HASH(s, s->ins_h, s->window[str + 1]); */ - s.ins_h = HASH$1(s, s.ins_h, s.window[str + 1]); - //#if MIN_MATCH != 3 - // Call update_hash() MIN_MATCH-3 more times - //#endif - while (s.insert) { - /* UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); */ - s.ins_h = HASH$1(s, s.ins_h, s.window[str + MIN_MATCH$2 - 1]); - - s.prev[str & s.w_mask] = s.head[s.ins_h]; - s.head[s.ins_h] = str; - str++; - s.insert--; - if (s.lookahead + s.insert < MIN_MATCH$2) { - break; - } - } - } - /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage, - * but this is not important since only literal bytes will be emitted. - */ - - } while (s.lookahead < MIN_LOOKAHEAD$1 && s.strm.avail_in !== 0); - - /* If the WIN_INIT bytes after the end of the current data have never been - * written, then zero those bytes in order to avoid memory check reports of - * the use of uninitialized (or uninitialised as Julian writes) bytes by - * the longest match routines. Update the high water mark for the next - * time through here. WIN_INIT is set to MAX_MATCH since the longest match - * routines allow scanning to strstart + MAX_MATCH, ignoring lookahead. - */ - // if (s.high_water < s.window_size) { - // const curr = s.strstart + s.lookahead; - // let init = 0; - // - // if (s.high_water < curr) { - // /* Previous high water mark below current data -- zero WIN_INIT - // * bytes or up to end of window, whichever is less. - // */ - // init = s.window_size - curr; - // if (init > WIN_INIT) - // init = WIN_INIT; - // zmemzero(s->window + curr, (unsigned)init); - // s->high_water = curr + init; - // } - // else if (s->high_water < (ulg)curr + WIN_INIT) { - // /* High water mark at or above current data, but below current data - // * plus WIN_INIT -- zero out to current data plus WIN_INIT, or up - // * to end of window, whichever is less. - // */ - // init = (ulg)curr + WIN_INIT - s->high_water; - // if (init > s->window_size - s->high_water) - // init = s->window_size - s->high_water; - // zmemzero(s->window + s->high_water, (unsigned)init); - // s->high_water += init; - // } - // } - // - // Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD, - // "not enough room for search"); - }; - - /* =========================================================================== - * Copy without compression as much as possible from the input stream, return - * the current block state. - * - * In case deflateParams() is used to later switch to a non-zero compression - * level, s->matches (otherwise unused when storing) keeps track of the number - * of hash table slides to perform. If s->matches is 1, then one hash table - * slide will be done when switching. If s->matches is 2, the maximum value - * allowed here, then the hash table will be cleared, since two or more slides - * is the same as a clear. - * - * deflate_stored() is written to minimize the number of times an input byte is - * copied. It is most efficient with large input and output buffers, which - * maximizes the opportunites to have a single copy from next_in to next_out. - */ - const deflate_stored$1 = (s, flush) => { - - /* Smallest worthy block size when not flushing or finishing. By default - * this is 32K. This can be as small as 507 bytes for memLevel == 1. For - * large input and output buffers, the stored block size will be larger. - */ - let min_block = s.pending_buf_size - 5 > s.w_size ? s.w_size : s.pending_buf_size - 5; - - /* Copy as many min_block or larger stored blocks directly to next_out as - * possible. If flushing, copy the remaining available input to next_out as - * stored blocks, if there is enough space. - */ - let len, left, have, last = 0; - let used = s.strm.avail_in; - do { - /* Set len to the maximum size block that we can copy directly with the - * available input data and output space. Set left to how much of that - * would be copied from what's left in the window. - */ - len = 65535/* MAX_STORED */; /* maximum deflate stored block length */ - have = (s.bi_valid + 42) >> 3; /* number of header bytes */ - if (s.strm.avail_out < have) { /* need room for header */ - break; - } - /* maximum stored block length that will fit in avail_out: */ - have = s.strm.avail_out - have; - left = s.strstart - s.block_start; /* bytes left in window */ - if (len > left + s.strm.avail_in) { - len = left + s.strm.avail_in; /* limit len to the input */ - } - if (len > have) { - len = have; /* limit len to the output */ - } - - /* If the stored block would be less than min_block in length, or if - * unable to copy all of the available input when flushing, then try - * copying to the window and the pending buffer instead. Also don't - * write an empty block when flushing -- deflate() does that. - */ - if (len < min_block && ((len === 0 && flush !== Z_FINISH$3$1) || - flush === Z_NO_FLUSH$2$1 || - len !== left + s.strm.avail_in)) { - break; - } - - /* Make a dummy stored block in pending to get the header bytes, - * including any pending bits. This also updates the debugging counts. - */ - last = flush === Z_FINISH$3$1 && len === left + s.strm.avail_in ? 1 : 0; - _tr_stored_block$2(s, 0, 0, last); - - /* Replace the lengths in the dummy stored block with len. */ - s.pending_buf[s.pending - 4] = len; - s.pending_buf[s.pending - 3] = len >> 8; - s.pending_buf[s.pending - 2] = ~len; - s.pending_buf[s.pending - 1] = ~len >> 8; - - /* Write the stored block header bytes. */ - flush_pending$1(s.strm); - - //#ifdef ZLIB_DEBUG - // /* Update debugging counts for the data about to be copied. */ - // s->compressed_len += len << 3; - // s->bits_sent += len << 3; - //#endif - - /* Copy uncompressed bytes from the window to next_out. */ - if (left) { - if (left > len) { - left = len; - } - //zmemcpy(s->strm->next_out, s->window + s->block_start, left); - s.strm.output.set(s.window.subarray(s.block_start, s.block_start + left), s.strm.next_out); - s.strm.next_out += left; - s.strm.avail_out -= left; - s.strm.total_out += left; - s.block_start += left; - len -= left; - } - - /* Copy uncompressed bytes directly from next_in to next_out, updating - * the check value. - */ - if (len) { - read_buf$1(s.strm, s.strm.output, s.strm.next_out, len); - s.strm.next_out += len; - s.strm.avail_out -= len; - s.strm.total_out += len; - } - } while (last === 0); - - /* Update the sliding window with the last s->w_size bytes of the copied - * data, or append all of the copied data to the existing window if less - * than s->w_size bytes were copied. Also update the number of bytes to - * insert in the hash tables, in the event that deflateParams() switches to - * a non-zero compression level. - */ - used -= s.strm.avail_in; /* number of input bytes directly copied */ - if (used) { - /* If any input was used, then no unused input remains in the window, - * therefore s->block_start == s->strstart. - */ - if (used >= s.w_size) { /* supplant the previous history */ - s.matches = 2; /* clear hash */ - //zmemcpy(s->window, s->strm->next_in - s->w_size, s->w_size); - s.window.set(s.strm.input.subarray(s.strm.next_in - s.w_size, s.strm.next_in), 0); - s.strstart = s.w_size; - s.insert = s.strstart; - } - else { - if (s.window_size - s.strstart <= used) { - /* Slide the window down. */ - s.strstart -= s.w_size; - //zmemcpy(s->window, s->window + s->w_size, s->strstart); - s.window.set(s.window.subarray(s.w_size, s.w_size + s.strstart), 0); - if (s.matches < 2) { - s.matches++; /* add a pending slide_hash() */ - } - if (s.insert > s.strstart) { - s.insert = s.strstart; - } - } - //zmemcpy(s->window + s->strstart, s->strm->next_in - used, used); - s.window.set(s.strm.input.subarray(s.strm.next_in - used, s.strm.next_in), s.strstart); - s.strstart += used; - s.insert += used > s.w_size - s.insert ? s.w_size - s.insert : used; - } - s.block_start = s.strstart; - } - if (s.high_water < s.strstart) { - s.high_water = s.strstart; - } - - /* If the last block was written to next_out, then done. */ - if (last) { - return BS_FINISH_DONE$1; - } - - /* If flushing and all input has been consumed, then done. */ - if (flush !== Z_NO_FLUSH$2$1 && flush !== Z_FINISH$3$1 && - s.strm.avail_in === 0 && s.strstart === s.block_start) { - return BS_BLOCK_DONE$1; - } - - /* Fill the window with any remaining input. */ - have = s.window_size - s.strstart; - if (s.strm.avail_in > have && s.block_start >= s.w_size) { - /* Slide the window down. */ - s.block_start -= s.w_size; - s.strstart -= s.w_size; - //zmemcpy(s->window, s->window + s->w_size, s->strstart); - s.window.set(s.window.subarray(s.w_size, s.w_size + s.strstart), 0); - if (s.matches < 2) { - s.matches++; /* add a pending slide_hash() */ - } - have += s.w_size; /* more space now */ - if (s.insert > s.strstart) { - s.insert = s.strstart; - } - } - if (have > s.strm.avail_in) { - have = s.strm.avail_in; - } - if (have) { - read_buf$1(s.strm, s.window, s.strstart, have); - s.strstart += have; - s.insert += have > s.w_size - s.insert ? s.w_size - s.insert : have; - } - if (s.high_water < s.strstart) { - s.high_water = s.strstart; - } - - /* There was not enough avail_out to write a complete worthy or flushed - * stored block to next_out. Write a stored block to pending instead, if we - * have enough input for a worthy block, or if flushing and there is enough - * room for the remaining input as a stored block in the pending buffer. - */ - have = (s.bi_valid + 42) >> 3; /* number of header bytes */ - /* maximum stored block length that will fit in pending: */ - have = s.pending_buf_size - have > 65535/* MAX_STORED */ ? 65535/* MAX_STORED */ : s.pending_buf_size - have; - min_block = have > s.w_size ? s.w_size : have; - left = s.strstart - s.block_start; - if (left >= min_block || - ((left || flush === Z_FINISH$3$1) && flush !== Z_NO_FLUSH$2$1 && - s.strm.avail_in === 0 && left <= have)) { - len = left > have ? have : left; - last = flush === Z_FINISH$3$1 && s.strm.avail_in === 0 && - len === left ? 1 : 0; - _tr_stored_block$2(s, s.block_start, len, last); - s.block_start += len; - flush_pending$1(s.strm); - } - - /* We've done all we can with the available input and output. */ - return last ? BS_FINISH_STARTED$1 : BS_NEED_MORE$1; - }; - - - /* =========================================================================== - * Compress as much as possible from the input stream, return the current - * block state. - * This function does not perform lazy evaluation of matches and inserts - * new strings in the dictionary only for unmatched strings or for short - * matches. It is used only for the fast compression options. - */ - const deflate_fast$1 = (s, flush) => { - - let hash_head; /* head of the hash chain */ - let bflush; /* set if current block must be flushed */ - - for (;;) { - /* Make sure that we always have enough lookahead, except - * at the end of the input file. We need MAX_MATCH bytes - * for the next match, plus MIN_MATCH bytes to insert the - * string following the next match. - */ - if (s.lookahead < MIN_LOOKAHEAD$1) { - fill_window$1(s); - if (s.lookahead < MIN_LOOKAHEAD$1 && flush === Z_NO_FLUSH$2$1) { - return BS_NEED_MORE$1; - } - if (s.lookahead === 0) { - break; /* flush the current block */ - } - } - - /* Insert the string window[strstart .. strstart+2] in the - * dictionary, and set hash_head to the head of the hash chain: - */ - hash_head = 0/*NIL*/; - if (s.lookahead >= MIN_MATCH$2) { - /*** INSERT_STRING(s, s.strstart, hash_head); ***/ - s.ins_h = HASH$1(s, s.ins_h, s.window[s.strstart + MIN_MATCH$2 - 1]); - hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h]; - s.head[s.ins_h] = s.strstart; - /***/ - } - - /* Find the longest match, discarding those <= prev_length. - * At this point we have always match_length < MIN_MATCH - */ - if (hash_head !== 0/*NIL*/ && ((s.strstart - hash_head) <= (s.w_size - MIN_LOOKAHEAD$1))) { - /* To simplify the code, we prevent matches with the string - * of window index 0 (in particular we have to avoid a match - * of the string with itself at the start of the input file). - */ - s.match_length = longest_match$1(s, hash_head); - /* longest_match() sets match_start */ - } - if (s.match_length >= MIN_MATCH$2) { - // check_match(s, s.strstart, s.match_start, s.match_length); // for debug only - - /*** _tr_tally_dist(s, s.strstart - s.match_start, - s.match_length - MIN_MATCH, bflush); ***/ - bflush = _tr_tally$2(s, s.strstart - s.match_start, s.match_length - MIN_MATCH$2); - - s.lookahead -= s.match_length; - - /* Insert new strings in the hash table only if the match length - * is not too large. This saves time but degrades compression. - */ - if (s.match_length <= s.max_lazy_match/*max_insert_length*/ && s.lookahead >= MIN_MATCH$2) { - s.match_length--; /* string at strstart already in table */ - do { - s.strstart++; - /*** INSERT_STRING(s, s.strstart, hash_head); ***/ - s.ins_h = HASH$1(s, s.ins_h, s.window[s.strstart + MIN_MATCH$2 - 1]); - hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h]; - s.head[s.ins_h] = s.strstart; - /***/ - /* strstart never exceeds WSIZE-MAX_MATCH, so there are - * always MIN_MATCH bytes ahead. - */ - } while (--s.match_length !== 0); - s.strstart++; - } else - { - s.strstart += s.match_length; - s.match_length = 0; - s.ins_h = s.window[s.strstart]; - /* UPDATE_HASH(s, s.ins_h, s.window[s.strstart+1]); */ - s.ins_h = HASH$1(s, s.ins_h, s.window[s.strstart + 1]); - - //#if MIN_MATCH != 3 - // Call UPDATE_HASH() MIN_MATCH-3 more times - //#endif - /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not - * matter since it will be recomputed at next deflate call. - */ - } - } else { - /* No match, output a literal byte */ - //Tracevv((stderr,"%c", s.window[s.strstart])); - /*** _tr_tally_lit(s, s.window[s.strstart], bflush); ***/ - bflush = _tr_tally$2(s, 0, s.window[s.strstart]); - - s.lookahead--; - s.strstart++; - } - if (bflush) { - /*** FLUSH_BLOCK(s, 0); ***/ - flush_block_only$1(s, false); - if (s.strm.avail_out === 0) { - return BS_NEED_MORE$1; - } - /***/ - } - } - s.insert = ((s.strstart < (MIN_MATCH$2 - 1)) ? s.strstart : MIN_MATCH$2 - 1); - if (flush === Z_FINISH$3$1) { - /*** FLUSH_BLOCK(s, 1); ***/ - flush_block_only$1(s, true); - if (s.strm.avail_out === 0) { - return BS_FINISH_STARTED$1; - } - /***/ - return BS_FINISH_DONE$1; - } - if (s.sym_next) { - /*** FLUSH_BLOCK(s, 0); ***/ - flush_block_only$1(s, false); - if (s.strm.avail_out === 0) { - return BS_NEED_MORE$1; - } - /***/ - } - return BS_BLOCK_DONE$1; - }; - - /* =========================================================================== - * Same as above, but achieves better compression. We use a lazy - * evaluation for matches: a match is finally adopted only if there is - * no better match at the next window position. - */ - const deflate_slow$1 = (s, flush) => { - - let hash_head; /* head of hash chain */ - let bflush; /* set if current block must be flushed */ - - let max_insert; - - /* Process the input block. */ - for (;;) { - /* Make sure that we always have enough lookahead, except - * at the end of the input file. We need MAX_MATCH bytes - * for the next match, plus MIN_MATCH bytes to insert the - * string following the next match. - */ - if (s.lookahead < MIN_LOOKAHEAD$1) { - fill_window$1(s); - if (s.lookahead < MIN_LOOKAHEAD$1 && flush === Z_NO_FLUSH$2$1) { - return BS_NEED_MORE$1; - } - if (s.lookahead === 0) { break; } /* flush the current block */ - } - - /* Insert the string window[strstart .. strstart+2] in the - * dictionary, and set hash_head to the head of the hash chain: - */ - hash_head = 0/*NIL*/; - if (s.lookahead >= MIN_MATCH$2) { - /*** INSERT_STRING(s, s.strstart, hash_head); ***/ - s.ins_h = HASH$1(s, s.ins_h, s.window[s.strstart + MIN_MATCH$2 - 1]); - hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h]; - s.head[s.ins_h] = s.strstart; - /***/ - } - - /* Find the longest match, discarding those <= prev_length. - */ - s.prev_length = s.match_length; - s.prev_match = s.match_start; - s.match_length = MIN_MATCH$2 - 1; - - if (hash_head !== 0/*NIL*/ && s.prev_length < s.max_lazy_match && - s.strstart - hash_head <= (s.w_size - MIN_LOOKAHEAD$1)/*MAX_DIST(s)*/) { - /* To simplify the code, we prevent matches with the string - * of window index 0 (in particular we have to avoid a match - * of the string with itself at the start of the input file). - */ - s.match_length = longest_match$1(s, hash_head); - /* longest_match() sets match_start */ - - if (s.match_length <= 5 && - (s.strategy === Z_FILTERED$1 || (s.match_length === MIN_MATCH$2 && s.strstart - s.match_start > 4096/*TOO_FAR*/))) { - - /* If prev_match is also MIN_MATCH, match_start is garbage - * but we will ignore the current match anyway. - */ - s.match_length = MIN_MATCH$2 - 1; - } - } - /* If there was a match at the previous step and the current - * match is not better, output the previous match: - */ - if (s.prev_length >= MIN_MATCH$2 && s.match_length <= s.prev_length) { - max_insert = s.strstart + s.lookahead - MIN_MATCH$2; - /* Do not insert strings in hash table beyond this. */ - - //check_match(s, s.strstart-1, s.prev_match, s.prev_length); - - /***_tr_tally_dist(s, s.strstart - 1 - s.prev_match, - s.prev_length - MIN_MATCH, bflush);***/ - bflush = _tr_tally$2(s, s.strstart - 1 - s.prev_match, s.prev_length - MIN_MATCH$2); - /* Insert in hash table all strings up to the end of the match. - * strstart-1 and strstart are already inserted. If there is not - * enough lookahead, the last two strings are not inserted in - * the hash table. - */ - s.lookahead -= s.prev_length - 1; - s.prev_length -= 2; - do { - if (++s.strstart <= max_insert) { - /*** INSERT_STRING(s, s.strstart, hash_head); ***/ - s.ins_h = HASH$1(s, s.ins_h, s.window[s.strstart + MIN_MATCH$2 - 1]); - hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h]; - s.head[s.ins_h] = s.strstart; - /***/ - } - } while (--s.prev_length !== 0); - s.match_available = 0; - s.match_length = MIN_MATCH$2 - 1; - s.strstart++; - - if (bflush) { - /*** FLUSH_BLOCK(s, 0); ***/ - flush_block_only$1(s, false); - if (s.strm.avail_out === 0) { - return BS_NEED_MORE$1; - } - /***/ - } - - } else if (s.match_available) { - /* If there was no match at the previous position, output a - * single literal. If there was a match but the current match - * is longer, truncate the previous match to a single literal. - */ - //Tracevv((stderr,"%c", s->window[s->strstart-1])); - /*** _tr_tally_lit(s, s.window[s.strstart-1], bflush); ***/ - bflush = _tr_tally$2(s, 0, s.window[s.strstart - 1]); - - if (bflush) { - /*** FLUSH_BLOCK_ONLY(s, 0) ***/ - flush_block_only$1(s, false); - /***/ - } - s.strstart++; - s.lookahead--; - if (s.strm.avail_out === 0) { - return BS_NEED_MORE$1; - } - } else { - /* There is no previous match to compare with, wait for - * the next step to decide. - */ - s.match_available = 1; - s.strstart++; - s.lookahead--; - } - } - //Assert (flush != Z_NO_FLUSH, "no flush?"); - if (s.match_available) { - //Tracevv((stderr,"%c", s->window[s->strstart-1])); - /*** _tr_tally_lit(s, s.window[s.strstart-1], bflush); ***/ - bflush = _tr_tally$2(s, 0, s.window[s.strstart - 1]); - - s.match_available = 0; - } - s.insert = s.strstart < MIN_MATCH$2 - 1 ? s.strstart : MIN_MATCH$2 - 1; - if (flush === Z_FINISH$3$1) { - /*** FLUSH_BLOCK(s, 1); ***/ - flush_block_only$1(s, true); - if (s.strm.avail_out === 0) { - return BS_FINISH_STARTED$1; - } - /***/ - return BS_FINISH_DONE$1; - } - if (s.sym_next) { - /*** FLUSH_BLOCK(s, 0); ***/ - flush_block_only$1(s, false); - if (s.strm.avail_out === 0) { - return BS_NEED_MORE$1; - } - /***/ - } - - return BS_BLOCK_DONE$1; - }; - - - /* =========================================================================== - * For Z_RLE, simply look for runs of bytes, generate matches only of distance - * one. Do not maintain a hash table. (It will be regenerated if this run of - * deflate switches away from Z_RLE.) - */ - const deflate_rle$1 = (s, flush) => { - - let bflush; /* set if current block must be flushed */ - let prev; /* byte at distance one to match */ - let scan, strend; /* scan goes up to strend for length of run */ - - const _win = s.window; - - for (;;) { - /* Make sure that we always have enough lookahead, except - * at the end of the input file. We need MAX_MATCH bytes - * for the longest run, plus one for the unrolled loop. - */ - if (s.lookahead <= MAX_MATCH$2) { - fill_window$1(s); - if (s.lookahead <= MAX_MATCH$2 && flush === Z_NO_FLUSH$2$1) { - return BS_NEED_MORE$1; - } - if (s.lookahead === 0) { break; } /* flush the current block */ - } - - /* See how many times the previous byte repeats */ - s.match_length = 0; - if (s.lookahead >= MIN_MATCH$2 && s.strstart > 0) { - scan = s.strstart - 1; - prev = _win[scan]; - if (prev === _win[++scan] && prev === _win[++scan] && prev === _win[++scan]) { - strend = s.strstart + MAX_MATCH$2; - do { - /*jshint noempty:false*/ - } while (prev === _win[++scan] && prev === _win[++scan] && - prev === _win[++scan] && prev === _win[++scan] && - prev === _win[++scan] && prev === _win[++scan] && - prev === _win[++scan] && prev === _win[++scan] && - scan < strend); - s.match_length = MAX_MATCH$2 - (strend - scan); - if (s.match_length > s.lookahead) { - s.match_length = s.lookahead; - } - } - //Assert(scan <= s->window+(uInt)(s->window_size-1), "wild scan"); - } - - /* Emit match if have run of MIN_MATCH or longer, else emit literal */ - if (s.match_length >= MIN_MATCH$2) { - //check_match(s, s.strstart, s.strstart - 1, s.match_length); - - /*** _tr_tally_dist(s, 1, s.match_length - MIN_MATCH, bflush); ***/ - bflush = _tr_tally$2(s, 1, s.match_length - MIN_MATCH$2); - - s.lookahead -= s.match_length; - s.strstart += s.match_length; - s.match_length = 0; - } else { - /* No match, output a literal byte */ - //Tracevv((stderr,"%c", s->window[s->strstart])); - /*** _tr_tally_lit(s, s.window[s.strstart], bflush); ***/ - bflush = _tr_tally$2(s, 0, s.window[s.strstart]); - - s.lookahead--; - s.strstart++; - } - if (bflush) { - /*** FLUSH_BLOCK(s, 0); ***/ - flush_block_only$1(s, false); - if (s.strm.avail_out === 0) { - return BS_NEED_MORE$1; - } - /***/ - } - } - s.insert = 0; - if (flush === Z_FINISH$3$1) { - /*** FLUSH_BLOCK(s, 1); ***/ - flush_block_only$1(s, true); - if (s.strm.avail_out === 0) { - return BS_FINISH_STARTED$1; - } - /***/ - return BS_FINISH_DONE$1; - } - if (s.sym_next) { - /*** FLUSH_BLOCK(s, 0); ***/ - flush_block_only$1(s, false); - if (s.strm.avail_out === 0) { - return BS_NEED_MORE$1; - } - /***/ - } - return BS_BLOCK_DONE$1; - }; - - /* =========================================================================== - * For Z_HUFFMAN_ONLY, do not look for matches. Do not maintain a hash table. - * (It will be regenerated if this run of deflate switches away from Huffman.) - */ - const deflate_huff$1 = (s, flush) => { - - let bflush; /* set if current block must be flushed */ - - for (;;) { - /* Make sure that we have a literal to write. */ - if (s.lookahead === 0) { - fill_window$1(s); - if (s.lookahead === 0) { - if (flush === Z_NO_FLUSH$2$1) { - return BS_NEED_MORE$1; - } - break; /* flush the current block */ - } - } - - /* Output a literal byte */ - s.match_length = 0; - //Tracevv((stderr,"%c", s->window[s->strstart])); - /*** _tr_tally_lit(s, s.window[s.strstart], bflush); ***/ - bflush = _tr_tally$2(s, 0, s.window[s.strstart]); - s.lookahead--; - s.strstart++; - if (bflush) { - /*** FLUSH_BLOCK(s, 0); ***/ - flush_block_only$1(s, false); - if (s.strm.avail_out === 0) { - return BS_NEED_MORE$1; - } - /***/ - } - } - s.insert = 0; - if (flush === Z_FINISH$3$1) { - /*** FLUSH_BLOCK(s, 1); ***/ - flush_block_only$1(s, true); - if (s.strm.avail_out === 0) { - return BS_FINISH_STARTED$1; - } - /***/ - return BS_FINISH_DONE$1; - } - if (s.sym_next) { - /*** FLUSH_BLOCK(s, 0); ***/ - flush_block_only$1(s, false); - if (s.strm.avail_out === 0) { - return BS_NEED_MORE$1; - } - /***/ - } - return BS_BLOCK_DONE$1; - }; - - /* Values for max_lazy_match, good_match and max_chain_length, depending on - * the desired pack level (0..9). The values given below have been tuned to - * exclude worst case performance for pathological files. Better values may be - * found for specific files. - */ - function Config$1(good_length, max_lazy, nice_length, max_chain, func) { - - this.good_length = good_length; - this.max_lazy = max_lazy; - this.nice_length = nice_length; - this.max_chain = max_chain; - this.func = func; - } - - const configuration_table$1 = [ - /* good lazy nice chain */ - new Config$1(0, 0, 0, 0, deflate_stored$1), /* 0 store only */ - new Config$1(4, 4, 8, 4, deflate_fast$1), /* 1 max speed, no lazy matches */ - new Config$1(4, 5, 16, 8, deflate_fast$1), /* 2 */ - new Config$1(4, 6, 32, 32, deflate_fast$1), /* 3 */ - - new Config$1(4, 4, 16, 16, deflate_slow$1), /* 4 lazy matches */ - new Config$1(8, 16, 32, 32, deflate_slow$1), /* 5 */ - new Config$1(8, 16, 128, 128, deflate_slow$1), /* 6 */ - new Config$1(8, 32, 128, 256, deflate_slow$1), /* 7 */ - new Config$1(32, 128, 258, 1024, deflate_slow$1), /* 8 */ - new Config$1(32, 258, 258, 4096, deflate_slow$1) /* 9 max compression */ - ]; - - - /* =========================================================================== - * Initialize the "longest match" routines for a new zlib stream - */ - const lm_init$1 = (s) => { - - s.window_size = 2 * s.w_size; - - /*** CLEAR_HASH(s); ***/ - zero$2(s.head); // Fill with NIL (= 0); - - /* Set the default configuration parameters: - */ - s.max_lazy_match = configuration_table$1[s.level].max_lazy; - s.good_match = configuration_table$1[s.level].good_length; - s.nice_match = configuration_table$1[s.level].nice_length; - s.max_chain_length = configuration_table$1[s.level].max_chain; - - s.strstart = 0; - s.block_start = 0; - s.lookahead = 0; - s.insert = 0; - s.match_length = s.prev_length = MIN_MATCH$2 - 1; - s.match_available = 0; - s.ins_h = 0; - }; - - - function DeflateState$1() { - this.strm = null; /* pointer back to this zlib stream */ - this.status = 0; /* as the name implies */ - this.pending_buf = null; /* output still pending */ - this.pending_buf_size = 0; /* size of pending_buf */ - this.pending_out = 0; /* next pending byte to output to the stream */ - this.pending = 0; /* nb of bytes in the pending buffer */ - this.wrap = 0; /* bit 0 true for zlib, bit 1 true for gzip */ - this.gzhead = null; /* gzip header information to write */ - this.gzindex = 0; /* where in extra, name, or comment */ - this.method = Z_DEFLATED$2$1; /* can only be DEFLATED */ - this.last_flush = -1; /* value of flush param for previous deflate call */ - - this.w_size = 0; /* LZ77 window size (32K by default) */ - this.w_bits = 0; /* log2(w_size) (8..16) */ - this.w_mask = 0; /* w_size - 1 */ - - this.window = null; - /* Sliding window. Input bytes are read into the second half of the window, - * and move to the first half later to keep a dictionary of at least wSize - * bytes. With this organization, matches are limited to a distance of - * wSize-MAX_MATCH bytes, but this ensures that IO is always - * performed with a length multiple of the block size. - */ - - this.window_size = 0; - /* Actual size of window: 2*wSize, except when the user input buffer - * is directly used as sliding window. - */ - - this.prev = null; - /* Link to older string with same hash index. To limit the size of this - * array to 64K, this link is maintained only for the last 32K strings. - * An index in this array is thus a window index modulo 32K. - */ - - this.head = null; /* Heads of the hash chains or NIL. */ - - this.ins_h = 0; /* hash index of string to be inserted */ - this.hash_size = 0; /* number of elements in hash table */ - this.hash_bits = 0; /* log2(hash_size) */ - this.hash_mask = 0; /* hash_size-1 */ - - this.hash_shift = 0; - /* Number of bits by which ins_h must be shifted at each input - * step. It must be such that after MIN_MATCH steps, the oldest - * byte no longer takes part in the hash key, that is: - * hash_shift * MIN_MATCH >= hash_bits - */ - - this.block_start = 0; - /* Window position at the beginning of the current output block. Gets - * negative when the window is moved backwards. - */ - - this.match_length = 0; /* length of best match */ - this.prev_match = 0; /* previous match */ - this.match_available = 0; /* set if previous match exists */ - this.strstart = 0; /* start of string to insert */ - this.match_start = 0; /* start of matching string */ - this.lookahead = 0; /* number of valid bytes ahead in window */ - - this.prev_length = 0; - /* Length of the best match at previous step. Matches not greater than this - * are discarded. This is used in the lazy match evaluation. - */ - - this.max_chain_length = 0; - /* To speed up deflation, hash chains are never searched beyond this - * length. A higher limit improves compression ratio but degrades the - * speed. - */ - - this.max_lazy_match = 0; - /* Attempt to find a better match only when the current match is strictly - * smaller than this value. This mechanism is used only for compression - * levels >= 4. - */ - // That's alias to max_lazy_match, don't use directly - //this.max_insert_length = 0; - /* Insert new strings in the hash table only if the match length is not - * greater than this length. This saves time but degrades compression. - * max_insert_length is used only for compression levels <= 3. - */ - - this.level = 0; /* compression level (1..9) */ - this.strategy = 0; /* favor or force Huffman coding*/ - - this.good_match = 0; - /* Use a faster search when the previous match is longer than this */ - - this.nice_match = 0; /* Stop searching when current match exceeds this */ - - /* used by trees.c: */ - - /* Didn't use ct_data typedef below to suppress compiler warning */ - - // struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */ - // struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */ - // struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */ - - // Use flat array of DOUBLE size, with interleaved fata, - // because JS does not support effective - this.dyn_ltree = new Uint16Array(HEAP_SIZE$2 * 2); - this.dyn_dtree = new Uint16Array((2 * D_CODES$2 + 1) * 2); - this.bl_tree = new Uint16Array((2 * BL_CODES$2 + 1) * 2); - zero$2(this.dyn_ltree); - zero$2(this.dyn_dtree); - zero$2(this.bl_tree); - - this.l_desc = null; /* desc. for literal tree */ - this.d_desc = null; /* desc. for distance tree */ - this.bl_desc = null; /* desc. for bit length tree */ - - //ush bl_count[MAX_BITS+1]; - this.bl_count = new Uint16Array(MAX_BITS$2 + 1); - /* number of codes at each bit length for an optimal tree */ - - //int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */ - this.heap = new Uint16Array(2 * L_CODES$2 + 1); /* heap used to build the Huffman trees */ - zero$2(this.heap); - - this.heap_len = 0; /* number of elements in the heap */ - this.heap_max = 0; /* element of largest frequency */ - /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. - * The same heap array is used to build all trees. - */ - - this.depth = new Uint16Array(2 * L_CODES$2 + 1); //uch depth[2*L_CODES+1]; - zero$2(this.depth); - /* Depth of each subtree used as tie breaker for trees of equal frequency - */ - - this.sym_buf = 0; /* buffer for distances and literals/lengths */ - - this.lit_bufsize = 0; - /* Size of match buffer for literals/lengths. There are 4 reasons for - * limiting lit_bufsize to 64K: - * - frequencies can be kept in 16 bit counters - * - if compression is not successful for the first block, all input - * data is still in the window so we can still emit a stored block even - * when input comes from standard input. (This can also be done for - * all blocks if lit_bufsize is not greater than 32K.) - * - if compression is not successful for a file smaller than 64K, we can - * even emit a stored file instead of a stored block (saving 5 bytes). - * This is applicable only for zip (not gzip or zlib). - * - creating new Huffman trees less frequently may not provide fast - * adaptation to changes in the input data statistics. (Take for - * example a binary file with poorly compressible code followed by - * a highly compressible string table.) Smaller buffer sizes give - * fast adaptation but have of course the overhead of transmitting - * trees more frequently. - * - I can't count above 4 - */ - - this.sym_next = 0; /* running index in sym_buf */ - this.sym_end = 0; /* symbol table full when sym_next reaches this */ - - this.opt_len = 0; /* bit length of current block with optimal trees */ - this.static_len = 0; /* bit length of current block with static trees */ - this.matches = 0; /* number of string matches in current block */ - this.insert = 0; /* bytes at end of window left to insert */ - - - this.bi_buf = 0; - /* Output buffer. bits are inserted starting at the bottom (least - * significant bits). - */ - this.bi_valid = 0; - /* Number of valid bits in bi_buf. All bits above the last valid bit - * are always zero. - */ - - // Used for window memory init. We safely ignore it for JS. That makes - // sense only for pointers and memory check tools. - //this.high_water = 0; - /* High water mark offset in window for initialized bytes -- bytes above - * this are set to zero in order to avoid memory check warnings when - * longest match routines access bytes past the input. This is then - * updated to the new high water mark. - */ - } - - - /* ========================================================================= - * Check for a valid deflate stream state. Return 0 if ok, 1 if not. - */ - const deflateStateCheck$1 = (strm) => { - - if (!strm) { - return 1; - } - const s = strm.state; - if (!s || s.strm !== strm || (s.status !== INIT_STATE$1 && - //#ifdef GZIP - s.status !== GZIP_STATE$1 && - //#endif - s.status !== EXTRA_STATE$1 && - s.status !== NAME_STATE$1 && - s.status !== COMMENT_STATE$1 && - s.status !== HCRC_STATE$1 && - s.status !== BUSY_STATE$1 && - s.status !== FINISH_STATE$1)) { - return 1; - } - return 0; - }; - - - const deflateResetKeep$1 = (strm) => { - - if (deflateStateCheck$1(strm)) { - return err$1(strm, Z_STREAM_ERROR$2$1); - } - - strm.total_in = strm.total_out = 0; - strm.data_type = Z_UNKNOWN$2; - - const s = strm.state; - s.pending = 0; - s.pending_out = 0; - - if (s.wrap < 0) { - s.wrap = -s.wrap; - /* was made negative by deflate(..., Z_FINISH); */ - } - s.status = - //#ifdef GZIP - s.wrap === 2 ? GZIP_STATE$1 : - //#endif - s.wrap ? INIT_STATE$1 : BUSY_STATE$1; - strm.adler = (s.wrap === 2) ? - 0 // crc32(0, Z_NULL, 0) - : - 1; // adler32(0, Z_NULL, 0) - s.last_flush = -2; - _tr_init$2(s); - return Z_OK$3$1; - }; - - - const deflateReset$1 = (strm) => { - - const ret = deflateResetKeep$1(strm); - if (ret === Z_OK$3$1) { - lm_init$1(strm.state); - } - return ret; - }; - - - const deflateSetHeader$1 = (strm, head) => { - - if (deflateStateCheck$1(strm) || strm.state.wrap !== 2) { - return Z_STREAM_ERROR$2$1; - } - strm.state.gzhead = head; - return Z_OK$3$1; - }; - - - const deflateInit2$1 = (strm, level, method, windowBits, memLevel, strategy) => { - - if (!strm) { // === Z_NULL - return Z_STREAM_ERROR$2$1; - } - let wrap = 1; - - if (level === Z_DEFAULT_COMPRESSION$1$1) { - level = 6; - } - - if (windowBits < 0) { /* suppress zlib wrapper */ - wrap = 0; - windowBits = -windowBits; - } - - else if (windowBits > 15) { - wrap = 2; /* write gzip wrapper instead */ - windowBits -= 16; - } - - - if (memLevel < 1 || memLevel > MAX_MEM_LEVEL$1 || method !== Z_DEFLATED$2$1 || - windowBits < 8 || windowBits > 15 || level < 0 || level > 9 || - strategy < 0 || strategy > Z_FIXED$2 || (windowBits === 8 && wrap !== 1)) { - return err$1(strm, Z_STREAM_ERROR$2$1); - } - - - if (windowBits === 8) { - windowBits = 9; - } - /* until 256-byte window bug fixed */ - - const s = new DeflateState$1(); - - strm.state = s; - s.strm = strm; - s.status = INIT_STATE$1; /* to pass state test in deflateReset() */ - - s.wrap = wrap; - s.gzhead = null; - s.w_bits = windowBits; - s.w_size = 1 << s.w_bits; - s.w_mask = s.w_size - 1; - - s.hash_bits = memLevel + 7; - s.hash_size = 1 << s.hash_bits; - s.hash_mask = s.hash_size - 1; - s.hash_shift = ~~((s.hash_bits + MIN_MATCH$2 - 1) / MIN_MATCH$2); - - s.window = new Uint8Array(s.w_size * 2); - s.head = new Uint16Array(s.hash_size); - s.prev = new Uint16Array(s.w_size); - - // Don't need mem init magic for JS. - //s.high_water = 0; /* nothing written to s->window yet */ - - s.lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */ - - /* We overlay pending_buf and sym_buf. This works since the average size - * for length/distance pairs over any compressed block is assured to be 31 - * bits or less. - * - * Analysis: The longest fixed codes are a length code of 8 bits plus 5 - * extra bits, for lengths 131 to 257. The longest fixed distance codes are - * 5 bits plus 13 extra bits, for distances 16385 to 32768. The longest - * possible fixed-codes length/distance pair is then 31 bits total. - * - * sym_buf starts one-fourth of the way into pending_buf. So there are - * three bytes in sym_buf for every four bytes in pending_buf. Each symbol - * in sym_buf is three bytes -- two for the distance and one for the - * literal/length. As each symbol is consumed, the pointer to the next - * sym_buf value to read moves forward three bytes. From that symbol, up to - * 31 bits are written to pending_buf. The closest the written pending_buf - * bits gets to the next sym_buf symbol to read is just before the last - * code is written. At that time, 31*(n-2) bits have been written, just - * after 24*(n-2) bits have been consumed from sym_buf. sym_buf starts at - * 8*n bits into pending_buf. (Note that the symbol buffer fills when n-1 - * symbols are written.) The closest the writing gets to what is unread is - * then n+14 bits. Here n is lit_bufsize, which is 16384 by default, and - * can range from 128 to 32768. - * - * Therefore, at a minimum, there are 142 bits of space between what is - * written and what is read in the overlain buffers, so the symbols cannot - * be overwritten by the compressed data. That space is actually 139 bits, - * due to the three-bit fixed-code block header. - * - * That covers the case where either Z_FIXED is specified, forcing fixed - * codes, or when the use of fixed codes is chosen, because that choice - * results in a smaller compressed block than dynamic codes. That latter - * condition then assures that the above analysis also covers all dynamic - * blocks. A dynamic-code block will only be chosen to be emitted if it has - * fewer bits than a fixed-code block would for the same set of symbols. - * Therefore its average symbol length is assured to be less than 31. So - * the compressed data for a dynamic block also cannot overwrite the - * symbols from which it is being constructed. - */ - - s.pending_buf_size = s.lit_bufsize * 4; - s.pending_buf = new Uint8Array(s.pending_buf_size); - - // It is offset from `s.pending_buf` (size is `s.lit_bufsize * 2`) - //s->sym_buf = s->pending_buf + s->lit_bufsize; - s.sym_buf = s.lit_bufsize; - - //s->sym_end = (s->lit_bufsize - 1) * 3; - s.sym_end = (s.lit_bufsize - 1) * 3; - /* We avoid equality with lit_bufsize*3 because of wraparound at 64K - * on 16 bit machines and because stored blocks are restricted to - * 64K-1 bytes. - */ - - s.level = level; - s.strategy = strategy; - s.method = method; - - return deflateReset$1(strm); - }; - - const deflateInit$1 = (strm, level) => { - - return deflateInit2$1(strm, level, Z_DEFLATED$2$1, MAX_WBITS$1$1, DEF_MEM_LEVEL$1, Z_DEFAULT_STRATEGY$1$1); - }; - - - /* ========================================================================= */ - const deflate$2$1 = (strm, flush) => { - - if (deflateStateCheck$1(strm) || flush > Z_BLOCK$1$1 || flush < 0) { - return strm ? err$1(strm, Z_STREAM_ERROR$2$1) : Z_STREAM_ERROR$2$1; - } - - const s = strm.state; - - if (!strm.output || - (strm.avail_in !== 0 && !strm.input) || - (s.status === FINISH_STATE$1 && flush !== Z_FINISH$3$1)) { - return err$1(strm, (strm.avail_out === 0) ? Z_BUF_ERROR$1$1 : Z_STREAM_ERROR$2$1); - } - - const old_flush = s.last_flush; - s.last_flush = flush; - - /* Flush as much pending output as possible */ - if (s.pending !== 0) { - flush_pending$1(strm); - if (strm.avail_out === 0) { - /* Since avail_out is 0, deflate will be called again with - * more output space, but possibly with both pending and - * avail_in equal to zero. There won't be anything to do, - * but this is not an error situation so make sure we - * return OK instead of BUF_ERROR at next call of deflate: - */ - s.last_flush = -1; - return Z_OK$3$1; - } - - /* Make sure there is something to do and avoid duplicate consecutive - * flushes. For repeated and useless calls with Z_FINISH, we keep - * returning Z_STREAM_END instead of Z_BUF_ERROR. - */ - } else if (strm.avail_in === 0 && rank$1(flush) <= rank$1(old_flush) && - flush !== Z_FINISH$3$1) { - return err$1(strm, Z_BUF_ERROR$1$1); - } - - /* User must not provide more input after the first FINISH: */ - if (s.status === FINISH_STATE$1 && strm.avail_in !== 0) { - return err$1(strm, Z_BUF_ERROR$1$1); - } - - /* Write the header */ - if (s.status === INIT_STATE$1 && s.wrap === 0) { - s.status = BUSY_STATE$1; - } - if (s.status === INIT_STATE$1) { - /* zlib header */ - let header = (Z_DEFLATED$2$1 + ((s.w_bits - 8) << 4)) << 8; - let level_flags = -1; - - if (s.strategy >= Z_HUFFMAN_ONLY$1 || s.level < 2) { - level_flags = 0; - } else if (s.level < 6) { - level_flags = 1; - } else if (s.level === 6) { - level_flags = 2; - } else { - level_flags = 3; - } - header |= (level_flags << 6); - if (s.strstart !== 0) { header |= PRESET_DICT$1; } - header += 31 - (header % 31); - - putShortMSB$1(s, header); - - /* Save the adler32 of the preset dictionary: */ - if (s.strstart !== 0) { - putShortMSB$1(s, strm.adler >>> 16); - putShortMSB$1(s, strm.adler & 0xffff); - } - strm.adler = 1; // adler32(0L, Z_NULL, 0); - s.status = BUSY_STATE$1; - - /* Compression must start with an empty pending buffer */ - flush_pending$1(strm); - if (s.pending !== 0) { - s.last_flush = -1; - return Z_OK$3$1; - } - } - //#ifdef GZIP - if (s.status === GZIP_STATE$1) { - /* gzip header */ - strm.adler = 0; //crc32(0L, Z_NULL, 0); - put_byte$1(s, 31); - put_byte$1(s, 139); - put_byte$1(s, 8); - if (!s.gzhead) { // s->gzhead == Z_NULL - put_byte$1(s, 0); - put_byte$1(s, 0); - put_byte$1(s, 0); - put_byte$1(s, 0); - put_byte$1(s, 0); - put_byte$1(s, s.level === 9 ? 2 : - (s.strategy >= Z_HUFFMAN_ONLY$1 || s.level < 2 ? - 4 : 0)); - put_byte$1(s, OS_CODE$1); - s.status = BUSY_STATE$1; - - /* Compression must start with an empty pending buffer */ - flush_pending$1(strm); - if (s.pending !== 0) { - s.last_flush = -1; - return Z_OK$3$1; - } - } - else { - put_byte$1(s, (s.gzhead.text ? 1 : 0) + - (s.gzhead.hcrc ? 2 : 0) + - (!s.gzhead.extra ? 0 : 4) + - (!s.gzhead.name ? 0 : 8) + - (!s.gzhead.comment ? 0 : 16) - ); - put_byte$1(s, s.gzhead.time & 0xff); - put_byte$1(s, (s.gzhead.time >> 8) & 0xff); - put_byte$1(s, (s.gzhead.time >> 16) & 0xff); - put_byte$1(s, (s.gzhead.time >> 24) & 0xff); - put_byte$1(s, s.level === 9 ? 2 : - (s.strategy >= Z_HUFFMAN_ONLY$1 || s.level < 2 ? - 4 : 0)); - put_byte$1(s, s.gzhead.os & 0xff); - if (s.gzhead.extra && s.gzhead.extra.length) { - put_byte$1(s, s.gzhead.extra.length & 0xff); - put_byte$1(s, (s.gzhead.extra.length >> 8) & 0xff); - } - if (s.gzhead.hcrc) { - strm.adler = crc32_1$2(strm.adler, s.pending_buf, s.pending, 0); - } - s.gzindex = 0; - s.status = EXTRA_STATE$1; - } - } - if (s.status === EXTRA_STATE$1) { - if (s.gzhead.extra/* != Z_NULL*/) { - let beg = s.pending; /* start of bytes to update crc */ - let left = (s.gzhead.extra.length & 0xffff) - s.gzindex; - while (s.pending + left > s.pending_buf_size) { - let copy = s.pending_buf_size - s.pending; - // zmemcpy(s.pending_buf + s.pending, - // s.gzhead.extra + s.gzindex, copy); - s.pending_buf.set(s.gzhead.extra.subarray(s.gzindex, s.gzindex + copy), s.pending); - s.pending = s.pending_buf_size; - //--- HCRC_UPDATE(beg) ---// - if (s.gzhead.hcrc && s.pending > beg) { - strm.adler = crc32_1$2(strm.adler, s.pending_buf, s.pending - beg, beg); - } - //---// - s.gzindex += copy; - flush_pending$1(strm); - if (s.pending !== 0) { - s.last_flush = -1; - return Z_OK$3$1; - } - beg = 0; - left -= copy; - } - // JS specific: s.gzhead.extra may be TypedArray or Array for backward compatibility - // TypedArray.slice and TypedArray.from don't exist in IE10-IE11 - let gzhead_extra = new Uint8Array(s.gzhead.extra); - // zmemcpy(s->pending_buf + s->pending, - // s->gzhead->extra + s->gzindex, left); - s.pending_buf.set(gzhead_extra.subarray(s.gzindex, s.gzindex + left), s.pending); - s.pending += left; - //--- HCRC_UPDATE(beg) ---// - if (s.gzhead.hcrc && s.pending > beg) { - strm.adler = crc32_1$2(strm.adler, s.pending_buf, s.pending - beg, beg); - } - //---// - s.gzindex = 0; - } - s.status = NAME_STATE$1; - } - if (s.status === NAME_STATE$1) { - if (s.gzhead.name/* != Z_NULL*/) { - let beg = s.pending; /* start of bytes to update crc */ - let val; - do { - if (s.pending === s.pending_buf_size) { - //--- HCRC_UPDATE(beg) ---// - if (s.gzhead.hcrc && s.pending > beg) { - strm.adler = crc32_1$2(strm.adler, s.pending_buf, s.pending - beg, beg); - } - //---// - flush_pending$1(strm); - if (s.pending !== 0) { - s.last_flush = -1; - return Z_OK$3$1; - } - beg = 0; - } - // JS specific: little magic to add zero terminator to end of string - if (s.gzindex < s.gzhead.name.length) { - val = s.gzhead.name.charCodeAt(s.gzindex++) & 0xff; - } else { - val = 0; - } - put_byte$1(s, val); - } while (val !== 0); - //--- HCRC_UPDATE(beg) ---// - if (s.gzhead.hcrc && s.pending > beg) { - strm.adler = crc32_1$2(strm.adler, s.pending_buf, s.pending - beg, beg); - } - //---// - s.gzindex = 0; - } - s.status = COMMENT_STATE$1; - } - if (s.status === COMMENT_STATE$1) { - if (s.gzhead.comment/* != Z_NULL*/) { - let beg = s.pending; /* start of bytes to update crc */ - let val; - do { - if (s.pending === s.pending_buf_size) { - //--- HCRC_UPDATE(beg) ---// - if (s.gzhead.hcrc && s.pending > beg) { - strm.adler = crc32_1$2(strm.adler, s.pending_buf, s.pending - beg, beg); - } - //---// - flush_pending$1(strm); - if (s.pending !== 0) { - s.last_flush = -1; - return Z_OK$3$1; - } - beg = 0; - } - // JS specific: little magic to add zero terminator to end of string - if (s.gzindex < s.gzhead.comment.length) { - val = s.gzhead.comment.charCodeAt(s.gzindex++) & 0xff; - } else { - val = 0; - } - put_byte$1(s, val); - } while (val !== 0); - //--- HCRC_UPDATE(beg) ---// - if (s.gzhead.hcrc && s.pending > beg) { - strm.adler = crc32_1$2(strm.adler, s.pending_buf, s.pending - beg, beg); - } - //---// - } - s.status = HCRC_STATE$1; - } - if (s.status === HCRC_STATE$1) { - if (s.gzhead.hcrc) { - if (s.pending + 2 > s.pending_buf_size) { - flush_pending$1(strm); - if (s.pending !== 0) { - s.last_flush = -1; - return Z_OK$3$1; - } - } - put_byte$1(s, strm.adler & 0xff); - put_byte$1(s, (strm.adler >> 8) & 0xff); - strm.adler = 0; //crc32(0L, Z_NULL, 0); - } - s.status = BUSY_STATE$1; - - /* Compression must start with an empty pending buffer */ - flush_pending$1(strm); - if (s.pending !== 0) { - s.last_flush = -1; - return Z_OK$3$1; - } - } - //#endif - - /* Start a new block or continue the current one. - */ - if (strm.avail_in !== 0 || s.lookahead !== 0 || - (flush !== Z_NO_FLUSH$2$1 && s.status !== FINISH_STATE$1)) { - let bstate = s.level === 0 ? deflate_stored$1(s, flush) : - s.strategy === Z_HUFFMAN_ONLY$1 ? deflate_huff$1(s, flush) : - s.strategy === Z_RLE$1 ? deflate_rle$1(s, flush) : - configuration_table$1[s.level].func(s, flush); - - if (bstate === BS_FINISH_STARTED$1 || bstate === BS_FINISH_DONE$1) { - s.status = FINISH_STATE$1; - } - if (bstate === BS_NEED_MORE$1 || bstate === BS_FINISH_STARTED$1) { - if (strm.avail_out === 0) { - s.last_flush = -1; - /* avoid BUF_ERROR next call, see above */ - } - return Z_OK$3$1; - /* If flush != Z_NO_FLUSH && avail_out == 0, the next call - * of deflate should use the same flush parameter to make sure - * that the flush is complete. So we don't have to output an - * empty block here, this will be done at next call. This also - * ensures that for a very small output buffer, we emit at most - * one empty block. - */ - } - if (bstate === BS_BLOCK_DONE$1) { - if (flush === Z_PARTIAL_FLUSH$1) { - _tr_align$2(s); - } - else if (flush !== Z_BLOCK$1$1) { /* FULL_FLUSH or SYNC_FLUSH */ - - _tr_stored_block$2(s, 0, 0, false); - /* For a full flush, this empty block will be recognized - * as a special marker by inflate_sync(). - */ - if (flush === Z_FULL_FLUSH$1$1) { - /*** CLEAR_HASH(s); ***/ /* forget history */ - zero$2(s.head); // Fill with NIL (= 0); - - if (s.lookahead === 0) { - s.strstart = 0; - s.block_start = 0; - s.insert = 0; - } - } - } - flush_pending$1(strm); - if (strm.avail_out === 0) { - s.last_flush = -1; /* avoid BUF_ERROR at next call, see above */ - return Z_OK$3$1; - } - } - } - - if (flush !== Z_FINISH$3$1) { return Z_OK$3$1; } - if (s.wrap <= 0) { return Z_STREAM_END$3$1; } - - /* Write the trailer */ - if (s.wrap === 2) { - put_byte$1(s, strm.adler & 0xff); - put_byte$1(s, (strm.adler >> 8) & 0xff); - put_byte$1(s, (strm.adler >> 16) & 0xff); - put_byte$1(s, (strm.adler >> 24) & 0xff); - put_byte$1(s, strm.total_in & 0xff); - put_byte$1(s, (strm.total_in >> 8) & 0xff); - put_byte$1(s, (strm.total_in >> 16) & 0xff); - put_byte$1(s, (strm.total_in >> 24) & 0xff); - } - else - { - putShortMSB$1(s, strm.adler >>> 16); - putShortMSB$1(s, strm.adler & 0xffff); - } - - flush_pending$1(strm); - /* If avail_out is zero, the application will call deflate again - * to flush the rest. - */ - if (s.wrap > 0) { s.wrap = -s.wrap; } - /* write the trailer only once! */ - return s.pending !== 0 ? Z_OK$3$1 : Z_STREAM_END$3$1; - }; - - - const deflateEnd$1 = (strm) => { - - if (deflateStateCheck$1(strm)) { - return Z_STREAM_ERROR$2$1; - } - - const status = strm.state.status; - - strm.state = null; - - return status === BUSY_STATE$1 ? err$1(strm, Z_DATA_ERROR$2$1) : Z_OK$3$1; - }; - - - /* ========================================================================= - * Initializes the compression dictionary from the given byte - * sequence without producing any compressed output. - */ - const deflateSetDictionary$1 = (strm, dictionary) => { - - let dictLength = dictionary.length; - - if (deflateStateCheck$1(strm)) { - return Z_STREAM_ERROR$2$1; - } - - const s = strm.state; - const wrap = s.wrap; - - if (wrap === 2 || (wrap === 1 && s.status !== INIT_STATE$1) || s.lookahead) { - return Z_STREAM_ERROR$2$1; - } - - /* when using zlib wrappers, compute Adler-32 for provided dictionary */ - if (wrap === 1) { - /* adler32(strm->adler, dictionary, dictLength); */ - strm.adler = adler32_1$2(strm.adler, dictionary, dictLength, 0); - } - - s.wrap = 0; /* avoid computing Adler-32 in read_buf */ - - /* if dictionary would fill window, just replace the history */ - if (dictLength >= s.w_size) { - if (wrap === 0) { /* already empty otherwise */ - /*** CLEAR_HASH(s); ***/ - zero$2(s.head); // Fill with NIL (= 0); - s.strstart = 0; - s.block_start = 0; - s.insert = 0; - } - /* use the tail */ - // dictionary = dictionary.slice(dictLength - s.w_size); - let tmpDict = new Uint8Array(s.w_size); - tmpDict.set(dictionary.subarray(dictLength - s.w_size, dictLength), 0); - dictionary = tmpDict; - dictLength = s.w_size; - } - /* insert dictionary into window and hash */ - const avail = strm.avail_in; - const next = strm.next_in; - const input = strm.input; - strm.avail_in = dictLength; - strm.next_in = 0; - strm.input = dictionary; - fill_window$1(s); - while (s.lookahead >= MIN_MATCH$2) { - let str = s.strstart; - let n = s.lookahead - (MIN_MATCH$2 - 1); - do { - /* UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); */ - s.ins_h = HASH$1(s, s.ins_h, s.window[str + MIN_MATCH$2 - 1]); - - s.prev[str & s.w_mask] = s.head[s.ins_h]; - - s.head[s.ins_h] = str; - str++; - } while (--n); - s.strstart = str; - s.lookahead = MIN_MATCH$2 - 1; - fill_window$1(s); - } - s.strstart += s.lookahead; - s.block_start = s.strstart; - s.insert = s.lookahead; - s.lookahead = 0; - s.match_length = s.prev_length = MIN_MATCH$2 - 1; - s.match_available = 0; - strm.next_in = next; - strm.input = input; - strm.avail_in = avail; - s.wrap = wrap; - return Z_OK$3$1; - }; - - - var deflateInit_1$1 = deflateInit$1; - var deflateInit2_1$1 = deflateInit2$1; - var deflateReset_1$1 = deflateReset$1; - var deflateResetKeep_1$1 = deflateResetKeep$1; - var deflateSetHeader_1$1 = deflateSetHeader$1; - var deflate_2$1$1 = deflate$2$1; - var deflateEnd_1$1 = deflateEnd$1; - var deflateSetDictionary_1$1 = deflateSetDictionary$1; - var deflateInfo$1 = 'pako deflate (from Nodeca project)'; - - /* Not implemented - module.exports.deflateBound = deflateBound; - module.exports.deflateCopy = deflateCopy; - module.exports.deflateGetDictionary = deflateGetDictionary; - module.exports.deflateParams = deflateParams; - module.exports.deflatePending = deflatePending; - module.exports.deflatePrime = deflatePrime; - module.exports.deflateTune = deflateTune; - */ - - var deflate_1$2$1 = { - deflateInit: deflateInit_1$1, - deflateInit2: deflateInit2_1$1, - deflateReset: deflateReset_1$1, - deflateResetKeep: deflateResetKeep_1$1, - deflateSetHeader: deflateSetHeader_1$1, - deflate: deflate_2$1$1, - deflateEnd: deflateEnd_1$1, - deflateSetDictionary: deflateSetDictionary_1$1, - deflateInfo: deflateInfo$1 - }; - - const _has$2 = (obj, key) => { - return Object.prototype.hasOwnProperty.call(obj, key); - }; - - var assign$2 = function (obj /*from1, from2, from3, ...*/) { - const sources = Array.prototype.slice.call(arguments, 1); - while (sources.length) { - const source = sources.shift(); - if (!source) { continue; } - - if (typeof source !== 'object') { - throw new TypeError(source + 'must be non-object'); - } - - for (const p in source) { - if (_has$2(source, p)) { - obj[p] = source[p]; - } - } - } - - return obj; - }; - - - // Join array of chunks to single array. - var flattenChunks$2 = (chunks) => { - // calculate data length - let len = 0; - - for (let i = 0, l = chunks.length; i < l; i++) { - len += chunks[i].length; - } - - // join chunks - const result = new Uint8Array(len); - - for (let i = 0, pos = 0, l = chunks.length; i < l; i++) { - let chunk = chunks[i]; - result.set(chunk, pos); - pos += chunk.length; - } - - return result; - }; - - var common$2 = { - assign: assign$2, - flattenChunks: flattenChunks$2 - }; - - // String encode/decode helpers - - - // Quick check if we can use fast array to bin string conversion - // - // - apply(Array) can fail on Android 2.2 - // - apply(Uint8Array) can fail on iOS 5.1 Safari - // - let STR_APPLY_UIA_OK$2 = true; - - try { String.fromCharCode.apply(null, new Uint8Array(1)); } catch (__) { STR_APPLY_UIA_OK$2 = false; } - - - // Table with utf8 lengths (calculated by first byte of sequence) - // Note, that 5 & 6-byte values and some 4-byte values can not be represented in JS, - // because max possible codepoint is 0x10ffff - const _utf8len$2 = new Uint8Array(256); - for (let q = 0; q < 256; q++) { - _utf8len$2[q] = (q >= 252 ? 6 : q >= 248 ? 5 : q >= 240 ? 4 : q >= 224 ? 3 : q >= 192 ? 2 : 1); - } - _utf8len$2[254] = _utf8len$2[254] = 1; // Invalid sequence start - - - // convert string to array (typed, when possible) - var string2buf$2 = (str) => { - if (typeof TextEncoder === 'function' && TextEncoder.prototype.encode) { - return new TextEncoder().encode(str); - } - - let buf, c, c2, m_pos, i, str_len = str.length, buf_len = 0; - - // count binary size - for (m_pos = 0; m_pos < str_len; m_pos++) { - c = str.charCodeAt(m_pos); - if ((c & 0xfc00) === 0xd800 && (m_pos + 1 < str_len)) { - c2 = str.charCodeAt(m_pos + 1); - if ((c2 & 0xfc00) === 0xdc00) { - c = 0x10000 + ((c - 0xd800) << 10) + (c2 - 0xdc00); - m_pos++; - } - } - buf_len += c < 0x80 ? 1 : c < 0x800 ? 2 : c < 0x10000 ? 3 : 4; - } - - // allocate buffer - buf = new Uint8Array(buf_len); - - // convert - for (i = 0, m_pos = 0; i < buf_len; m_pos++) { - c = str.charCodeAt(m_pos); - if ((c & 0xfc00) === 0xd800 && (m_pos + 1 < str_len)) { - c2 = str.charCodeAt(m_pos + 1); - if ((c2 & 0xfc00) === 0xdc00) { - c = 0x10000 + ((c - 0xd800) << 10) + (c2 - 0xdc00); - m_pos++; - } - } - if (c < 0x80) { - /* one byte */ - buf[i++] = c; - } else if (c < 0x800) { - /* two bytes */ - buf[i++] = 0xC0 | (c >>> 6); - buf[i++] = 0x80 | (c & 0x3f); - } else if (c < 0x10000) { - /* three bytes */ - buf[i++] = 0xE0 | (c >>> 12); - buf[i++] = 0x80 | (c >>> 6 & 0x3f); - buf[i++] = 0x80 | (c & 0x3f); - } else { - /* four bytes */ - buf[i++] = 0xf0 | (c >>> 18); - buf[i++] = 0x80 | (c >>> 12 & 0x3f); - buf[i++] = 0x80 | (c >>> 6 & 0x3f); - buf[i++] = 0x80 | (c & 0x3f); - } - } - - return buf; - }; - - // Helper - const buf2binstring$2 = (buf, len) => { - // On Chrome, the arguments in a function call that are allowed is `65534`. - // If the length of the buffer is smaller than that, we can use this optimization, - // otherwise we will take a slower path. - if (len < 65534) { - if (buf.subarray && STR_APPLY_UIA_OK$2) { - return String.fromCharCode.apply(null, buf.length === len ? buf : buf.subarray(0, len)); - } - } - - let result = ''; - for (let i = 0; i < len; i++) { - result += String.fromCharCode(buf[i]); - } - return result; - }; - - - // convert array to string - var buf2string$2 = (buf, max) => { - const len = max || buf.length; - - if (typeof TextDecoder === 'function' && TextDecoder.prototype.decode) { - return new TextDecoder().decode(buf.subarray(0, max)); - } - - let i, out; - - // Reserve max possible length (2 words per char) - // NB: by unknown reasons, Array is significantly faster for - // String.fromCharCode.apply than Uint16Array. - const utf16buf = new Array(len * 2); - - for (out = 0, i = 0; i < len;) { - let c = buf[i++]; - // quick process ascii - if (c < 0x80) { utf16buf[out++] = c; continue; } - - let c_len = _utf8len$2[c]; - // skip 5 & 6 byte codes - if (c_len > 4) { utf16buf[out++] = 0xfffd; i += c_len - 1; continue; } - - // apply mask on first byte - c &= c_len === 2 ? 0x1f : c_len === 3 ? 0x0f : 0x07; - // join the rest - while (c_len > 1 && i < len) { - c = (c << 6) | (buf[i++] & 0x3f); - c_len--; - } - - // terminated by end of string? - if (c_len > 1) { utf16buf[out++] = 0xfffd; continue; } - - if (c < 0x10000) { - utf16buf[out++] = c; - } else { - c -= 0x10000; - utf16buf[out++] = 0xd800 | ((c >> 10) & 0x3ff); - utf16buf[out++] = 0xdc00 | (c & 0x3ff); - } - } - - return buf2binstring$2(utf16buf, out); - }; - - - // Calculate max possible position in utf8 buffer, - // that will not break sequence. If that's not possible - // - (very small limits) return max size as is. - // - // buf[] - utf8 bytes array - // max - length limit (mandatory); - var utf8border$2 = (buf, max) => { - - max = max || buf.length; - if (max > buf.length) { max = buf.length; } - - // go back from last position, until start of sequence found - let pos = max - 1; - while (pos >= 0 && (buf[pos] & 0xC0) === 0x80) { pos--; } - - // Very small and broken sequence, - // return max, because we should return something anyway. - if (pos < 0) { return max; } - - // If we came to start of buffer - that means buffer is too small, - // return max too. - if (pos === 0) { return max; } - - return (pos + _utf8len$2[buf[pos]] > max) ? pos : max; - }; - - var strings$2 = { - string2buf: string2buf$2, - buf2string: buf2string$2, - utf8border: utf8border$2 - }; - - // (C) 1995-2013 Jean-loup Gailly and Mark Adler - // (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin - // - // This software is provided 'as-is', without any express or implied - // warranty. In no event will the authors be held liable for any damages - // arising from the use of this software. - // - // Permission is granted to anyone to use this software for any purpose, - // including commercial applications, and to alter it and redistribute it - // freely, subject to the following restrictions: - // - // 1. The origin of this software must not be misrepresented; you must not - // claim that you wrote the original software. If you use this software - // in a product, an acknowledgment in the product documentation would be - // appreciated but is not required. - // 2. Altered source versions must be plainly marked as such, and must not be - // misrepresented as being the original software. - // 3. This notice may not be removed or altered from any source distribution. - - function ZStream$2() { - /* next input byte */ - this.input = null; // JS specific, because we have no pointers - this.next_in = 0; - /* number of bytes available at input */ - this.avail_in = 0; - /* total number of input bytes read so far */ - this.total_in = 0; - /* next output byte should be put there */ - this.output = null; // JS specific, because we have no pointers - this.next_out = 0; - /* remaining free space at output */ - this.avail_out = 0; - /* total number of bytes output so far */ - this.total_out = 0; - /* last error message, NULL if no error */ - this.msg = ''/*Z_NULL*/; - /* not visible by applications */ - this.state = null; - /* best guess about the data type: binary or text */ - this.data_type = 2/*Z_UNKNOWN*/; - /* adler32 value of the uncompressed data */ - this.adler = 0; - } - - var zstream$2 = ZStream$2; - - const toString$1$1 = Object.prototype.toString; - - /* Public constants ==========================================================*/ - /* ===========================================================================*/ - - const { - Z_NO_FLUSH: Z_NO_FLUSH$1$1, Z_SYNC_FLUSH: Z_SYNC_FLUSH$1, Z_FULL_FLUSH: Z_FULL_FLUSH$2, Z_FINISH: Z_FINISH$2$1, - Z_OK: Z_OK$2$1, Z_STREAM_END: Z_STREAM_END$2$1, - Z_DEFAULT_COMPRESSION: Z_DEFAULT_COMPRESSION$2, - Z_DEFAULT_STRATEGY: Z_DEFAULT_STRATEGY$2, - Z_DEFLATED: Z_DEFLATED$1$1 - } = constants$2$2; - - /* ===========================================================================*/ - - - /** - * class Deflate - * - * Generic JS-style wrapper for zlib calls. If you don't need - * streaming behaviour - use more simple functions: [[deflate]], - * [[deflateRaw]] and [[gzip]]. - **/ - - /* internal - * Deflate.chunks -> Array - * - * Chunks of output data, if [[Deflate#onData]] not overridden. - **/ - - /** - * Deflate.result -> Uint8Array - * - * Compressed result, generated by default [[Deflate#onData]] - * and [[Deflate#onEnd]] handlers. Filled after you push last chunk - * (call [[Deflate#push]] with `Z_FINISH` / `true` param). - **/ - - /** - * Deflate.err -> Number - * - * Error code after deflate finished. 0 (Z_OK) on success. - * You will not need it in real life, because deflate errors - * are possible only on wrong options or bad `onData` / `onEnd` - * custom handlers. - **/ - - /** - * Deflate.msg -> String - * - * Error message, if [[Deflate.err]] != 0 - **/ - - - /** - * new Deflate(options) - * - options (Object): zlib deflate options. - * - * Creates new deflator instance with specified params. Throws exception - * on bad params. Supported options: - * - * - `level` - * - `windowBits` - * - `memLevel` - * - `strategy` - * - `dictionary` - * - * [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced) - * for more information on these. - * - * Additional options, for internal needs: - * - * - `chunkSize` - size of generated data chunks (16K by default) - * - `raw` (Boolean) - do raw deflate - * - `gzip` (Boolean) - create gzip wrapper - * - `header` (Object) - custom header for gzip - * - `text` (Boolean) - true if compressed data believed to be text - * - `time` (Number) - modification time, unix timestamp - * - `os` (Number) - operation system code - * - `extra` (Array) - array of bytes with extra data (max 65536) - * - `name` (String) - file name (binary string) - * - `comment` (String) - comment (binary string) - * - `hcrc` (Boolean) - true if header crc should be added - * - * ##### Example: - * - * ```javascript - * const pako = require('pako') - * , chunk1 = new Uint8Array([1,2,3,4,5,6,7,8,9]) - * , chunk2 = new Uint8Array([10,11,12,13,14,15,16,17,18,19]); - * - * const deflate = new pako.Deflate({ level: 3}); - * - * deflate.push(chunk1, false); - * deflate.push(chunk2, true); // true -> last chunk - * - * if (deflate.err) { throw new Error(deflate.err); } - * - * console.log(deflate.result); - * ``` - **/ - function Deflate$1$1(options) { - this.options = common$2.assign({ - level: Z_DEFAULT_COMPRESSION$2, - method: Z_DEFLATED$1$1, - chunkSize: 16384, - windowBits: 15, - memLevel: 8, - strategy: Z_DEFAULT_STRATEGY$2 - }, options || {}); - - let opt = this.options; - - if (opt.raw && (opt.windowBits > 0)) { - opt.windowBits = -opt.windowBits; - } - - else if (opt.gzip && (opt.windowBits > 0) && (opt.windowBits < 16)) { - opt.windowBits += 16; - } - - this.err = 0; // error code, if happens (0 = Z_OK) - this.msg = ''; // error message - this.ended = false; // used to avoid multiple onEnd() calls - this.chunks = []; // chunks of compressed data - - this.strm = new zstream$2(); - this.strm.avail_out = 0; - - let status = deflate_1$2$1.deflateInit2( - this.strm, - opt.level, - opt.method, - opt.windowBits, - opt.memLevel, - opt.strategy - ); - - if (status !== Z_OK$2$1) { - throw new Error(messages$2[status]); - } - - if (opt.header) { - deflate_1$2$1.deflateSetHeader(this.strm, opt.header); - } - - if (opt.dictionary) { - let dict; - // Convert data if needed - if (typeof opt.dictionary === 'string') { - // If we need to compress text, change encoding to utf8. - dict = strings$2.string2buf(opt.dictionary); - } else if (toString$1$1.call(opt.dictionary) === '[object ArrayBuffer]') { - dict = new Uint8Array(opt.dictionary); - } else { - dict = opt.dictionary; - } - - status = deflate_1$2$1.deflateSetDictionary(this.strm, dict); - - if (status !== Z_OK$2$1) { - throw new Error(messages$2[status]); - } - - this._dict_set = true; - } - } - - /** - * Deflate#push(data[, flush_mode]) -> Boolean - * - data (Uint8Array|ArrayBuffer|String): input data. Strings will be - * converted to utf8 byte sequence. - * - flush_mode (Number|Boolean): 0..6 for corresponding Z_NO_FLUSH..Z_TREE modes. - * See constants. Skipped or `false` means Z_NO_FLUSH, `true` means Z_FINISH. - * - * Sends input data to deflate pipe, generating [[Deflate#onData]] calls with - * new compressed chunks. Returns `true` on success. The last data block must - * have `flush_mode` Z_FINISH (or `true`). That will flush internal pending - * buffers and call [[Deflate#onEnd]]. - * - * On fail call [[Deflate#onEnd]] with error code and return false. - * - * ##### Example - * - * ```javascript - * push(chunk, false); // push one of data chunks - * ... - * push(chunk, true); // push last chunk - * ``` - **/ - Deflate$1$1.prototype.push = function (data, flush_mode) { - const strm = this.strm; - const chunkSize = this.options.chunkSize; - let status, _flush_mode; - - if (this.ended) { return false; } - - if (flush_mode === ~~flush_mode) _flush_mode = flush_mode; - else _flush_mode = flush_mode === true ? Z_FINISH$2$1 : Z_NO_FLUSH$1$1; - - // Convert data if needed - if (typeof data === 'string') { - // If we need to compress text, change encoding to utf8. - strm.input = strings$2.string2buf(data); - } else if (toString$1$1.call(data) === '[object ArrayBuffer]') { - strm.input = new Uint8Array(data); - } else { - strm.input = data; - } - - strm.next_in = 0; - strm.avail_in = strm.input.length; - - for (;;) { - if (strm.avail_out === 0) { - strm.output = new Uint8Array(chunkSize); - strm.next_out = 0; - strm.avail_out = chunkSize; - } - - // Make sure avail_out > 6 to avoid repeating markers - if ((_flush_mode === Z_SYNC_FLUSH$1 || _flush_mode === Z_FULL_FLUSH$2) && strm.avail_out <= 6) { - this.onData(strm.output.subarray(0, strm.next_out)); - strm.avail_out = 0; - continue; - } - - status = deflate_1$2$1.deflate(strm, _flush_mode); - - // Ended => flush and finish - if (status === Z_STREAM_END$2$1) { - if (strm.next_out > 0) { - this.onData(strm.output.subarray(0, strm.next_out)); - } - status = deflate_1$2$1.deflateEnd(this.strm); - this.onEnd(status); - this.ended = true; - return status === Z_OK$2$1; - } - - // Flush if out buffer full - if (strm.avail_out === 0) { - this.onData(strm.output); - continue; - } - - // Flush if requested and has data - if (_flush_mode > 0 && strm.next_out > 0) { - this.onData(strm.output.subarray(0, strm.next_out)); - strm.avail_out = 0; - continue; - } - - if (strm.avail_in === 0) break; - } - - return true; - }; - - - /** - * Deflate#onData(chunk) -> Void - * - chunk (Uint8Array): output data. - * - * By default, stores data blocks in `chunks[]` property and glue - * those in `onEnd`. Override this handler, if you need another behaviour. - **/ - Deflate$1$1.prototype.onData = function (chunk) { - this.chunks.push(chunk); - }; - - - /** - * Deflate#onEnd(status) -> Void - * - status (Number): deflate status. 0 (Z_OK) on success, - * other if not. - * - * Called once after you tell deflate that the input stream is - * complete (Z_FINISH). By default - join collected chunks, - * free memory and fill `results` / `err` properties. - **/ - Deflate$1$1.prototype.onEnd = function (status) { - // On success - join - if (status === Z_OK$2$1) { - this.result = common$2.flattenChunks(this.chunks); - } - this.chunks = []; - this.err = status; - this.msg = this.strm.msg; - }; - - - /** - * deflate(data[, options]) -> Uint8Array - * - data (Uint8Array|ArrayBuffer|String): input data to compress. - * - options (Object): zlib deflate options. - * - * Compress `data` with deflate algorithm and `options`. - * - * Supported options are: - * - * - level - * - windowBits - * - memLevel - * - strategy - * - dictionary - * - * [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced) - * for more information on these. - * - * Sugar (options): - * - * - `raw` (Boolean) - say that we work with raw stream, if you don't wish to specify - * negative windowBits implicitly. - * - * ##### Example: - * - * ```javascript - * const pako = require('pako') - * const data = new Uint8Array([1,2,3,4,5,6,7,8,9]); - * - * console.log(pako.deflate(data)); - * ``` - **/ - function deflate$1$1(input, options) { - const deflator = new Deflate$1$1(options); - - deflator.push(input, true); - - // That will never happens, if you don't cheat with options :) - if (deflator.err) { throw deflator.msg || messages$2[deflator.err]; } - - return deflator.result; - } - - - /** - * deflateRaw(data[, options]) -> Uint8Array - * - data (Uint8Array|ArrayBuffer|String): input data to compress. - * - options (Object): zlib deflate options. - * - * The same as [[deflate]], but creates raw data, without wrapper - * (header and adler32 crc). - **/ - function deflateRaw$1$1(input, options) { - options = options || {}; - options.raw = true; - return deflate$1$1(input, options); - } - - - /** - * gzip(data[, options]) -> Uint8Array - * - data (Uint8Array|ArrayBuffer|String): input data to compress. - * - options (Object): zlib deflate options. - * - * The same as [[deflate]], but create gzip wrapper instead of - * deflate one. - **/ - function gzip$1$1(input, options) { - options = options || {}; - options.gzip = true; - return deflate$1$1(input, options); - } - - - var Deflate_1$1$1 = Deflate$1$1; - var deflate_2$2 = deflate$1$1; - var deflateRaw_1$1$1 = deflateRaw$1$1; - var gzip_1$1$1 = gzip$1$1; - var constants$1$1 = constants$2$2; - - var deflate_1$1$1 = { - Deflate: Deflate_1$1$1, - deflate: deflate_2$2, - deflateRaw: deflateRaw_1$1$1, - gzip: gzip_1$1$1, - constants: constants$1$1 - }; - - // (C) 1995-2013 Jean-loup Gailly and Mark Adler - // (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin - // - // This software is provided 'as-is', without any express or implied - // warranty. In no event will the authors be held liable for any damages - // arising from the use of this software. - // - // Permission is granted to anyone to use this software for any purpose, - // including commercial applications, and to alter it and redistribute it - // freely, subject to the following restrictions: - // - // 1. The origin of this software must not be misrepresented; you must not - // claim that you wrote the original software. If you use this software - // in a product, an acknowledgment in the product documentation would be - // appreciated but is not required. - // 2. Altered source versions must be plainly marked as such, and must not be - // misrepresented as being the original software. - // 3. This notice may not be removed or altered from any source distribution. - - // See state defs from inflate.js - const BAD$1$2 = 16209; /* got a data error -- remain here until reset */ - const TYPE$1$2 = 16191; /* i: waiting for type bits, including last-flag bit */ - - /* - Decode literal, length, and distance codes and write out the resulting - literal and match bytes until either not enough input or output is - available, an end-of-block is encountered, or a data error is encountered. - When large enough input and output buffers are supplied to inflate(), for - example, a 16K input buffer and a 64K output buffer, more than 95% of the - inflate execution time is spent in this routine. - - Entry assumptions: - - state.mode === LEN - strm.avail_in >= 6 - strm.avail_out >= 258 - start >= strm.avail_out - state.bits < 8 - - On return, state.mode is one of: - - LEN -- ran out of enough output space or enough available input - TYPE -- reached end of block code, inflate() to interpret next block - BAD -- error in block data - - Notes: - - - The maximum input bits used by a length/distance pair is 15 bits for the - length code, 5 bits for the length extra, 15 bits for the distance code, - and 13 bits for the distance extra. This totals 48 bits, or six bytes. - Therefore if strm.avail_in >= 6, then there is enough input to avoid - checking for available input while decoding. - - - The maximum bytes that a single length/distance pair can output is 258 - bytes, which is the maximum length that can be coded. inflate_fast() - requires strm.avail_out >= 258 for each loop to avoid checking for - output space. - */ - var inffast$2 = function inflate_fast(strm, start) { - let _in; /* local strm.input */ - let last; /* have enough input while in < last */ - let _out; /* local strm.output */ - let beg; /* inflate()'s initial strm.output */ - let end; /* while out < end, enough space available */ - //#ifdef INFLATE_STRICT - let dmax; /* maximum distance from zlib header */ - //#endif - let wsize; /* window size or zero if not using window */ - let whave; /* valid bytes in the window */ - let wnext; /* window write index */ - // Use `s_window` instead `window`, avoid conflict with instrumentation tools - let s_window; /* allocated sliding window, if wsize != 0 */ - let hold; /* local strm.hold */ - let bits; /* local strm.bits */ - let lcode; /* local strm.lencode */ - let dcode; /* local strm.distcode */ - let lmask; /* mask for first level of length codes */ - let dmask; /* mask for first level of distance codes */ - let here; /* retrieved table entry */ - let op; /* code bits, operation, extra bits, or */ - /* window position, window bytes to copy */ - let len; /* match length, unused bytes */ - let dist; /* match distance */ - let from; /* where to copy match from */ - let from_source; - - - let input, output; // JS specific, because we have no pointers - - /* copy state to local variables */ - const state = strm.state; - //here = state.here; - _in = strm.next_in; - input = strm.input; - last = _in + (strm.avail_in - 5); - _out = strm.next_out; - output = strm.output; - beg = _out - (start - strm.avail_out); - end = _out + (strm.avail_out - 257); - //#ifdef INFLATE_STRICT - dmax = state.dmax; - //#endif - wsize = state.wsize; - whave = state.whave; - wnext = state.wnext; - s_window = state.window; - hold = state.hold; - bits = state.bits; - lcode = state.lencode; - dcode = state.distcode; - lmask = (1 << state.lenbits) - 1; - dmask = (1 << state.distbits) - 1; - - - /* decode literals and length/distances until end-of-block or not enough - input data or output space */ - - top: - do { - if (bits < 15) { - hold += input[_in++] << bits; - bits += 8; - hold += input[_in++] << bits; - bits += 8; - } - - here = lcode[hold & lmask]; - - dolen: - for (;;) { // Goto emulation - op = here >>> 24/*here.bits*/; - hold >>>= op; - bits -= op; - op = (here >>> 16) & 0xff/*here.op*/; - if (op === 0) { /* literal */ - //Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? - // "inflate: literal '%c'\n" : - // "inflate: literal 0x%02x\n", here.val)); - output[_out++] = here & 0xffff/*here.val*/; - } - else if (op & 16) { /* length base */ - len = here & 0xffff/*here.val*/; - op &= 15; /* number of extra bits */ - if (op) { - if (bits < op) { - hold += input[_in++] << bits; - bits += 8; - } - len += hold & ((1 << op) - 1); - hold >>>= op; - bits -= op; - } - //Tracevv((stderr, "inflate: length %u\n", len)); - if (bits < 15) { - hold += input[_in++] << bits; - bits += 8; - hold += input[_in++] << bits; - bits += 8; - } - here = dcode[hold & dmask]; - - dodist: - for (;;) { // goto emulation - op = here >>> 24/*here.bits*/; - hold >>>= op; - bits -= op; - op = (here >>> 16) & 0xff/*here.op*/; - - if (op & 16) { /* distance base */ - dist = here & 0xffff/*here.val*/; - op &= 15; /* number of extra bits */ - if (bits < op) { - hold += input[_in++] << bits; - bits += 8; - if (bits < op) { - hold += input[_in++] << bits; - bits += 8; - } - } - dist += hold & ((1 << op) - 1); - //#ifdef INFLATE_STRICT - if (dist > dmax) { - strm.msg = 'invalid distance too far back'; - state.mode = BAD$1$2; - break top; - } - //#endif - hold >>>= op; - bits -= op; - //Tracevv((stderr, "inflate: distance %u\n", dist)); - op = _out - beg; /* max distance in output */ - if (dist > op) { /* see if copy from window */ - op = dist - op; /* distance back in window */ - if (op > whave) { - if (state.sane) { - strm.msg = 'invalid distance too far back'; - state.mode = BAD$1$2; - break top; - } - - // (!) This block is disabled in zlib defaults, - // don't enable it for binary compatibility - //#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR - // if (len <= op - whave) { - // do { - // output[_out++] = 0; - // } while (--len); - // continue top; - // } - // len -= op - whave; - // do { - // output[_out++] = 0; - // } while (--op > whave); - // if (op === 0) { - // from = _out - dist; - // do { - // output[_out++] = output[from++]; - // } while (--len); - // continue top; - // } - //#endif - } - from = 0; // window index - from_source = s_window; - if (wnext === 0) { /* very common case */ - from += wsize - op; - if (op < len) { /* some from window */ - len -= op; - do { - output[_out++] = s_window[from++]; - } while (--op); - from = _out - dist; /* rest from output */ - from_source = output; - } - } - else if (wnext < op) { /* wrap around window */ - from += wsize + wnext - op; - op -= wnext; - if (op < len) { /* some from end of window */ - len -= op; - do { - output[_out++] = s_window[from++]; - } while (--op); - from = 0; - if (wnext < len) { /* some from start of window */ - op = wnext; - len -= op; - do { - output[_out++] = s_window[from++]; - } while (--op); - from = _out - dist; /* rest from output */ - from_source = output; - } - } - } - else { /* contiguous in window */ - from += wnext - op; - if (op < len) { /* some from window */ - len -= op; - do { - output[_out++] = s_window[from++]; - } while (--op); - from = _out - dist; /* rest from output */ - from_source = output; - } - } - while (len > 2) { - output[_out++] = from_source[from++]; - output[_out++] = from_source[from++]; - output[_out++] = from_source[from++]; - len -= 3; - } - if (len) { - output[_out++] = from_source[from++]; - if (len > 1) { - output[_out++] = from_source[from++]; - } - } - } - else { - from = _out - dist; /* copy direct from output */ - do { /* minimum length is three */ - output[_out++] = output[from++]; - output[_out++] = output[from++]; - output[_out++] = output[from++]; - len -= 3; - } while (len > 2); - if (len) { - output[_out++] = output[from++]; - if (len > 1) { - output[_out++] = output[from++]; - } - } - } - } - else if ((op & 64) === 0) { /* 2nd level distance code */ - here = dcode[(here & 0xffff)/*here.val*/ + (hold & ((1 << op) - 1))]; - continue dodist; - } - else { - strm.msg = 'invalid distance code'; - state.mode = BAD$1$2; - break top; - } - - break; // need to emulate goto via "continue" - } - } - else if ((op & 64) === 0) { /* 2nd level length code */ - here = lcode[(here & 0xffff)/*here.val*/ + (hold & ((1 << op) - 1))]; - continue dolen; - } - else if (op & 32) { /* end-of-block */ - //Tracevv((stderr, "inflate: end of block\n")); - state.mode = TYPE$1$2; - break top; - } - else { - strm.msg = 'invalid literal/length code'; - state.mode = BAD$1$2; - break top; - } - - break; // need to emulate goto via "continue" - } - } while (_in < last && _out < end); - - /* return unused bytes (on entry, bits < 8, so in won't go too far back) */ - len = bits >> 3; - _in -= len; - bits -= len << 3; - hold &= (1 << bits) - 1; - - /* update state and return */ - strm.next_in = _in; - strm.next_out = _out; - strm.avail_in = (_in < last ? 5 + (last - _in) : 5 - (_in - last)); - strm.avail_out = (_out < end ? 257 + (end - _out) : 257 - (_out - end)); - state.hold = hold; - state.bits = bits; - return; - }; - - // (C) 1995-2013 Jean-loup Gailly and Mark Adler - // (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin - // - // This software is provided 'as-is', without any express or implied - // warranty. In no event will the authors be held liable for any damages - // arising from the use of this software. - // - // Permission is granted to anyone to use this software for any purpose, - // including commercial applications, and to alter it and redistribute it - // freely, subject to the following restrictions: - // - // 1. The origin of this software must not be misrepresented; you must not - // claim that you wrote the original software. If you use this software - // in a product, an acknowledgment in the product documentation would be - // appreciated but is not required. - // 2. Altered source versions must be plainly marked as such, and must not be - // misrepresented as being the original software. - // 3. This notice may not be removed or altered from any source distribution. - - const MAXBITS$2 = 15; - const ENOUGH_LENS$1$2 = 852; - const ENOUGH_DISTS$1$2 = 592; - //const ENOUGH = (ENOUGH_LENS+ENOUGH_DISTS); - - const CODES$1$2 = 0; - const LENS$1$2 = 1; - const DISTS$1$2 = 2; - - const lbase$2 = new Uint16Array([ /* Length codes 257..285 base */ - 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, - 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0 - ]); - - const lext$2 = new Uint8Array([ /* Length codes 257..285 extra */ - 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, - 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 72, 78 - ]); - - const dbase$2 = new Uint16Array([ /* Distance codes 0..29 base */ - 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, - 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, - 8193, 12289, 16385, 24577, 0, 0 - ]); - - const dext$2 = new Uint8Array([ /* Distance codes 0..29 extra */ - 16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, - 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, - 28, 28, 29, 29, 64, 64 - ]); - - const inflate_table$2 = (type, lens, lens_index, codes, table, table_index, work, opts) => - { - const bits = opts.bits; - //here = opts.here; /* table entry for duplication */ - - let len = 0; /* a code's length in bits */ - let sym = 0; /* index of code symbols */ - let min = 0, max = 0; /* minimum and maximum code lengths */ - let root = 0; /* number of index bits for root table */ - let curr = 0; /* number of index bits for current table */ - let drop = 0; /* code bits to drop for sub-table */ - let left = 0; /* number of prefix codes available */ - let used = 0; /* code entries in table used */ - let huff = 0; /* Huffman code */ - let incr; /* for incrementing code, index */ - let fill; /* index for replicating entries */ - let low; /* low bits for current root entry */ - let mask; /* mask for low root bits */ - let next; /* next available space in table */ - let base = null; /* base value table to use */ - // let shoextra; /* extra bits table to use */ - let match; /* use base and extra for symbol >= match */ - const count = new Uint16Array(MAXBITS$2 + 1); //[MAXBITS+1]; /* number of codes of each length */ - const offs = new Uint16Array(MAXBITS$2 + 1); //[MAXBITS+1]; /* offsets in table for each length */ - let extra = null; - - let here_bits, here_op, here_val; - - /* - Process a set of code lengths to create a canonical Huffman code. The - code lengths are lens[0..codes-1]. Each length corresponds to the - symbols 0..codes-1. The Huffman code is generated by first sorting the - symbols by length from short to long, and retaining the symbol order - for codes with equal lengths. Then the code starts with all zero bits - for the first code of the shortest length, and the codes are integer - increments for the same length, and zeros are appended as the length - increases. For the deflate format, these bits are stored backwards - from their more natural integer increment ordering, and so when the - decoding tables are built in the large loop below, the integer codes - are incremented backwards. - - This routine assumes, but does not check, that all of the entries in - lens[] are in the range 0..MAXBITS. The caller must assure this. - 1..MAXBITS is interpreted as that code length. zero means that that - symbol does not occur in this code. - - The codes are sorted by computing a count of codes for each length, - creating from that a table of starting indices for each length in the - sorted table, and then entering the symbols in order in the sorted - table. The sorted table is work[], with that space being provided by - the caller. - - The length counts are used for other purposes as well, i.e. finding - the minimum and maximum length codes, determining if there are any - codes at all, checking for a valid set of lengths, and looking ahead - at length counts to determine sub-table sizes when building the - decoding tables. - */ - - /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */ - for (len = 0; len <= MAXBITS$2; len++) { - count[len] = 0; - } - for (sym = 0; sym < codes; sym++) { - count[lens[lens_index + sym]]++; - } - - /* bound code lengths, force root to be within code lengths */ - root = bits; - for (max = MAXBITS$2; max >= 1; max--) { - if (count[max] !== 0) { break; } - } - if (root > max) { - root = max; - } - if (max === 0) { /* no symbols to code at all */ - //table.op[opts.table_index] = 64; //here.op = (var char)64; /* invalid code marker */ - //table.bits[opts.table_index] = 1; //here.bits = (var char)1; - //table.val[opts.table_index++] = 0; //here.val = (var short)0; - table[table_index++] = (1 << 24) | (64 << 16) | 0; - - - //table.op[opts.table_index] = 64; - //table.bits[opts.table_index] = 1; - //table.val[opts.table_index++] = 0; - table[table_index++] = (1 << 24) | (64 << 16) | 0; - - opts.bits = 1; - return 0; /* no symbols, but wait for decoding to report error */ - } - for (min = 1; min < max; min++) { - if (count[min] !== 0) { break; } - } - if (root < min) { - root = min; - } - - /* check for an over-subscribed or incomplete set of lengths */ - left = 1; - for (len = 1; len <= MAXBITS$2; len++) { - left <<= 1; - left -= count[len]; - if (left < 0) { - return -1; - } /* over-subscribed */ - } - if (left > 0 && (type === CODES$1$2 || max !== 1)) { - return -1; /* incomplete set */ - } - - /* generate offsets into symbol table for each length for sorting */ - offs[1] = 0; - for (len = 1; len < MAXBITS$2; len++) { - offs[len + 1] = offs[len] + count[len]; - } - - /* sort symbols by length, by symbol order within each length */ - for (sym = 0; sym < codes; sym++) { - if (lens[lens_index + sym] !== 0) { - work[offs[lens[lens_index + sym]]++] = sym; - } - } - - /* - Create and fill in decoding tables. In this loop, the table being - filled is at next and has curr index bits. The code being used is huff - with length len. That code is converted to an index by dropping drop - bits off of the bottom. For codes where len is less than drop + curr, - those top drop + curr - len bits are incremented through all values to - fill the table with replicated entries. - - root is the number of index bits for the root table. When len exceeds - root, sub-tables are created pointed to by the root entry with an index - of the low root bits of huff. This is saved in low to check for when a - new sub-table should be started. drop is zero when the root table is - being filled, and drop is root when sub-tables are being filled. - - When a new sub-table is needed, it is necessary to look ahead in the - code lengths to determine what size sub-table is needed. The length - counts are used for this, and so count[] is decremented as codes are - entered in the tables. - - used keeps track of how many table entries have been allocated from the - provided *table space. It is checked for LENS and DIST tables against - the constants ENOUGH_LENS and ENOUGH_DISTS to guard against changes in - the initial root table size constants. See the comments in inftrees.h - for more information. - - sym increments through all symbols, and the loop terminates when - all codes of length max, i.e. all codes, have been processed. This - routine permits incomplete codes, so another loop after this one fills - in the rest of the decoding tables with invalid code markers. - */ - - /* set up for code type */ - // poor man optimization - use if-else instead of switch, - // to avoid deopts in old v8 - if (type === CODES$1$2) { - base = extra = work; /* dummy value--not used */ - match = 20; - - } else if (type === LENS$1$2) { - base = lbase$2; - extra = lext$2; - match = 257; - - } else { /* DISTS */ - base = dbase$2; - extra = dext$2; - match = 0; - } - - /* initialize opts for loop */ - huff = 0; /* starting code */ - sym = 0; /* starting code symbol */ - len = min; /* starting code length */ - next = table_index; /* current table to fill in */ - curr = root; /* current table index bits */ - drop = 0; /* current bits to drop from code for index */ - low = -1; /* trigger new sub-table when len > root */ - used = 1 << root; /* use root table entries */ - mask = used - 1; /* mask for comparing low */ - - /* check available table space */ - if ((type === LENS$1$2 && used > ENOUGH_LENS$1$2) || - (type === DISTS$1$2 && used > ENOUGH_DISTS$1$2)) { - return 1; - } - - /* process all codes and make table entries */ - for (;;) { - /* create table entry */ - here_bits = len - drop; - if (work[sym] + 1 < match) { - here_op = 0; - here_val = work[sym]; - } - else if (work[sym] >= match) { - here_op = extra[work[sym] - match]; - here_val = base[work[sym] - match]; - } - else { - here_op = 32 + 64; /* end of block */ - here_val = 0; - } - - /* replicate for those indices with low len bits equal to huff */ - incr = 1 << (len - drop); - fill = 1 << curr; - min = fill; /* save offset to next table */ - do { - fill -= incr; - table[next + (huff >> drop) + fill] = (here_bits << 24) | (here_op << 16) | here_val |0; - } while (fill !== 0); - - /* backwards increment the len-bit code huff */ - incr = 1 << (len - 1); - while (huff & incr) { - incr >>= 1; - } - if (incr !== 0) { - huff &= incr - 1; - huff += incr; - } else { - huff = 0; - } - - /* go to next symbol, update count, len */ - sym++; - if (--count[len] === 0) { - if (len === max) { break; } - len = lens[lens_index + work[sym]]; - } - - /* create new sub-table if needed */ - if (len > root && (huff & mask) !== low) { - /* if first time, transition to sub-tables */ - if (drop === 0) { - drop = root; - } - - /* increment past last table */ - next += min; /* here min is 1 << curr */ - - /* determine length of next table */ - curr = len - drop; - left = 1 << curr; - while (curr + drop < max) { - left -= count[curr + drop]; - if (left <= 0) { break; } - curr++; - left <<= 1; - } - - /* check for enough space */ - used += 1 << curr; - if ((type === LENS$1$2 && used > ENOUGH_LENS$1$2) || - (type === DISTS$1$2 && used > ENOUGH_DISTS$1$2)) { - return 1; - } - - /* point entry in root table to sub-table */ - low = huff & mask; - /*table.op[low] = curr; - table.bits[low] = root; - table.val[low] = next - opts.table_index;*/ - table[low] = (root << 24) | (curr << 16) | (next - table_index) |0; - } - } - - /* fill in remaining table entry if code is incomplete (guaranteed to have - at most one remaining entry, since if the code is incomplete, the - maximum code length that was allowed to get this far is one bit) */ - if (huff !== 0) { - //table.op[next + huff] = 64; /* invalid code marker */ - //table.bits[next + huff] = len - drop; - //table.val[next + huff] = 0; - table[next + huff] = ((len - drop) << 24) | (64 << 16) |0; - } - - /* set return parameters */ - //opts.table_index += used; - opts.bits = root; - return 0; - }; - - - var inftrees$2 = inflate_table$2; - - // (C) 1995-2013 Jean-loup Gailly and Mark Adler - // (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin - // - // This software is provided 'as-is', without any express or implied - // warranty. In no event will the authors be held liable for any damages - // arising from the use of this software. - // - // Permission is granted to anyone to use this software for any purpose, - // including commercial applications, and to alter it and redistribute it - // freely, subject to the following restrictions: - // - // 1. The origin of this software must not be misrepresented; you must not - // claim that you wrote the original software. If you use this software - // in a product, an acknowledgment in the product documentation would be - // appreciated but is not required. - // 2. Altered source versions must be plainly marked as such, and must not be - // misrepresented as being the original software. - // 3. This notice may not be removed or altered from any source distribution. - - - - - - - const CODES$3 = 0; - const LENS$3 = 1; - const DISTS$3 = 2; - - /* Public constants ==========================================================*/ - /* ===========================================================================*/ - - const { - Z_FINISH: Z_FINISH$1$2, Z_BLOCK: Z_BLOCK$3, Z_TREES: Z_TREES$2, - Z_OK: Z_OK$1$2, Z_STREAM_END: Z_STREAM_END$1$2, Z_NEED_DICT: Z_NEED_DICT$1$2, Z_STREAM_ERROR: Z_STREAM_ERROR$1$2, Z_DATA_ERROR: Z_DATA_ERROR$1$2, Z_MEM_ERROR: Z_MEM_ERROR$1$2, Z_BUF_ERROR: Z_BUF_ERROR$3, - Z_DEFLATED: Z_DEFLATED$4 - } = constants$2$2; - - - /* STATES ====================================================================*/ - /* ===========================================================================*/ - - - const HEAD$2 = 16180; /* i: waiting for magic header */ - const FLAGS$2 = 16181; /* i: waiting for method and flags (gzip) */ - const TIME$2 = 16182; /* i: waiting for modification time (gzip) */ - const OS$2 = 16183; /* i: waiting for extra flags and operating system (gzip) */ - const EXLEN$2 = 16184; /* i: waiting for extra length (gzip) */ - const EXTRA$2 = 16185; /* i: waiting for extra bytes (gzip) */ - const NAME$2 = 16186; /* i: waiting for end of file name (gzip) */ - const COMMENT$2 = 16187; /* i: waiting for end of comment (gzip) */ - const HCRC$2 = 16188; /* i: waiting for header crc (gzip) */ - const DICTID$2 = 16189; /* i: waiting for dictionary check value */ - const DICT$2 = 16190; /* waiting for inflateSetDictionary() call */ - const TYPE$3 = 16191; /* i: waiting for type bits, including last-flag bit */ - const TYPEDO$2 = 16192; /* i: same, but skip check to exit inflate on new block */ - const STORED$2 = 16193; /* i: waiting for stored size (length and complement) */ - const COPY_$2 = 16194; /* i/o: same as COPY below, but only first time in */ - const COPY$2 = 16195; /* i/o: waiting for input or output to copy stored block */ - const TABLE$2 = 16196; /* i: waiting for dynamic block table lengths */ - const LENLENS$2 = 16197; /* i: waiting for code length code lengths */ - const CODELENS$2 = 16198; /* i: waiting for length/lit and distance code lengths */ - const LEN_$2 = 16199; /* i: same as LEN below, but only first time in */ - const LEN$2 = 16200; /* i: waiting for length/lit/eob code */ - const LENEXT$2 = 16201; /* i: waiting for length extra bits */ - const DIST$2 = 16202; /* i: waiting for distance code */ - const DISTEXT$2 = 16203; /* i: waiting for distance extra bits */ - const MATCH$2 = 16204; /* o: waiting for output space to copy string */ - const LIT$2 = 16205; /* o: waiting for output space to write literal */ - const CHECK$2 = 16206; /* i: waiting for 32-bit check value */ - const LENGTH$2 = 16207; /* i: waiting for 32-bit length (gzip) */ - const DONE$2 = 16208; /* finished check, done -- remain here until reset */ - const BAD$3 = 16209; /* got a data error -- remain here until reset */ - const MEM$2 = 16210; /* got an inflate() memory error -- remain here until reset */ - const SYNC$2 = 16211; /* looking for synchronization bytes to restart inflate() */ - - /* ===========================================================================*/ - - - - const ENOUGH_LENS$3 = 852; - const ENOUGH_DISTS$3 = 592; - //const ENOUGH = (ENOUGH_LENS+ENOUGH_DISTS); - - const MAX_WBITS$3 = 15; - /* 32K LZ77 window */ - const DEF_WBITS$2 = MAX_WBITS$3; - - - const zswap32$2 = (q) => { - - return (((q >>> 24) & 0xff) + - ((q >>> 8) & 0xff00) + - ((q & 0xff00) << 8) + - ((q & 0xff) << 24)); - }; - - - function InflateState$2() { - this.strm = null; /* pointer back to this zlib stream */ - this.mode = 0; /* current inflate mode */ - this.last = false; /* true if processing last block */ - this.wrap = 0; /* bit 0 true for zlib, bit 1 true for gzip, - bit 2 true to validate check value */ - this.havedict = false; /* true if dictionary provided */ - this.flags = 0; /* gzip header method and flags (0 if zlib), or - -1 if raw or no header yet */ - this.dmax = 0; /* zlib header max distance (INFLATE_STRICT) */ - this.check = 0; /* protected copy of check value */ - this.total = 0; /* protected copy of output count */ - // TODO: may be {} - this.head = null; /* where to save gzip header information */ - - /* sliding window */ - this.wbits = 0; /* log base 2 of requested window size */ - this.wsize = 0; /* window size or zero if not using window */ - this.whave = 0; /* valid bytes in the window */ - this.wnext = 0; /* window write index */ - this.window = null; /* allocated sliding window, if needed */ - - /* bit accumulator */ - this.hold = 0; /* input bit accumulator */ - this.bits = 0; /* number of bits in "in" */ - - /* for string and stored block copying */ - this.length = 0; /* literal or length of data to copy */ - this.offset = 0; /* distance back to copy string from */ - - /* for table and code decoding */ - this.extra = 0; /* extra bits needed */ - - /* fixed and dynamic code tables */ - this.lencode = null; /* starting table for length/literal codes */ - this.distcode = null; /* starting table for distance codes */ - this.lenbits = 0; /* index bits for lencode */ - this.distbits = 0; /* index bits for distcode */ - - /* dynamic table building */ - this.ncode = 0; /* number of code length code lengths */ - this.nlen = 0; /* number of length code lengths */ - this.ndist = 0; /* number of distance code lengths */ - this.have = 0; /* number of code lengths in lens[] */ - this.next = null; /* next available space in codes[] */ - - this.lens = new Uint16Array(320); /* temporary storage for code lengths */ - this.work = new Uint16Array(288); /* work area for code table building */ - - /* - because we don't have pointers in js, we use lencode and distcode directly - as buffers so we don't need codes - */ - //this.codes = new Int32Array(ENOUGH); /* space for code tables */ - this.lendyn = null; /* dynamic table for length/literal codes (JS specific) */ - this.distdyn = null; /* dynamic table for distance codes (JS specific) */ - this.sane = 0; /* if false, allow invalid distance too far */ - this.back = 0; /* bits back of last unprocessed length/lit */ - this.was = 0; /* initial length of match */ - } - - - const inflateStateCheck$1 = (strm) => { - - if (!strm) { - return 1; - } - const state = strm.state; - if (!state || state.strm !== strm || - state.mode < HEAD$2 || state.mode > SYNC$2) { - return 1; - } - return 0; - }; - - - const inflateResetKeep$2 = (strm) => { - - if (inflateStateCheck$1(strm)) { return Z_STREAM_ERROR$1$2; } - const state = strm.state; - strm.total_in = strm.total_out = state.total = 0; - strm.msg = ''; /*Z_NULL*/ - if (state.wrap) { /* to support ill-conceived Java test suite */ - strm.adler = state.wrap & 1; - } - state.mode = HEAD$2; - state.last = 0; - state.havedict = 0; - state.flags = -1; - state.dmax = 32768; - state.head = null/*Z_NULL*/; - state.hold = 0; - state.bits = 0; - //state.lencode = state.distcode = state.next = state.codes; - state.lencode = state.lendyn = new Int32Array(ENOUGH_LENS$3); - state.distcode = state.distdyn = new Int32Array(ENOUGH_DISTS$3); - - state.sane = 1; - state.back = -1; - //Tracev((stderr, "inflate: reset\n")); - return Z_OK$1$2; - }; - - - const inflateReset$2 = (strm) => { - - if (inflateStateCheck$1(strm)) { return Z_STREAM_ERROR$1$2; } - const state = strm.state; - state.wsize = 0; - state.whave = 0; - state.wnext = 0; - return inflateResetKeep$2(strm); - - }; - - - const inflateReset2$2 = (strm, windowBits) => { - let wrap; - - /* get the state */ - if (inflateStateCheck$1(strm)) { return Z_STREAM_ERROR$1$2; } - const state = strm.state; - - /* extract wrap request from windowBits parameter */ - if (windowBits < 0) { - wrap = 0; - windowBits = -windowBits; - } - else { - wrap = (windowBits >> 4) + 5; - if (windowBits < 48) { - windowBits &= 15; - } - } - - /* set number of window bits, free window if different */ - if (windowBits && (windowBits < 8 || windowBits > 15)) { - return Z_STREAM_ERROR$1$2; - } - if (state.window !== null && state.wbits !== windowBits) { - state.window = null; - } - - /* update state and reset the rest of it */ - state.wrap = wrap; - state.wbits = windowBits; - return inflateReset$2(strm); - }; - - - const inflateInit2$2 = (strm, windowBits) => { - - if (!strm) { return Z_STREAM_ERROR$1$2; } - //strm.msg = Z_NULL; /* in case we return an error */ - - const state = new InflateState$2(); - - //if (state === Z_NULL) return Z_MEM_ERROR; - //Tracev((stderr, "inflate: allocated\n")); - strm.state = state; - state.strm = strm; - state.window = null/*Z_NULL*/; - state.mode = HEAD$2; /* to pass state test in inflateReset2() */ - const ret = inflateReset2$2(strm, windowBits); - if (ret !== Z_OK$1$2) { - strm.state = null/*Z_NULL*/; - } - return ret; - }; - - - const inflateInit$2 = (strm) => { - - return inflateInit2$2(strm, DEF_WBITS$2); - }; - - - /* - Return state with length and distance decoding tables and index sizes set to - fixed code decoding. Normally this returns fixed tables from inffixed.h. - If BUILDFIXED is defined, then instead this routine builds the tables the - first time it's called, and returns those tables the first time and - thereafter. This reduces the size of the code by about 2K bytes, in - exchange for a little execution time. However, BUILDFIXED should not be - used for threaded applications, since the rewriting of the tables and virgin - may not be thread-safe. - */ - let virgin$2 = true; - - let lenfix$2, distfix$2; // We have no pointers in JS, so keep tables separate - - - const fixedtables$2 = (state) => { - - /* build fixed huffman tables if first call (may not be thread safe) */ - if (virgin$2) { - lenfix$2 = new Int32Array(512); - distfix$2 = new Int32Array(32); - - /* literal/length table */ - let sym = 0; - while (sym < 144) { state.lens[sym++] = 8; } - while (sym < 256) { state.lens[sym++] = 9; } - while (sym < 280) { state.lens[sym++] = 7; } - while (sym < 288) { state.lens[sym++] = 8; } - - inftrees$2(LENS$3, state.lens, 0, 288, lenfix$2, 0, state.work, { bits: 9 }); - - /* distance table */ - sym = 0; - while (sym < 32) { state.lens[sym++] = 5; } - - inftrees$2(DISTS$3, state.lens, 0, 32, distfix$2, 0, state.work, { bits: 5 }); - - /* do this just once */ - virgin$2 = false; - } - - state.lencode = lenfix$2; - state.lenbits = 9; - state.distcode = distfix$2; - state.distbits = 5; - }; - - - /* - Update the window with the last wsize (normally 32K) bytes written before - returning. If window does not exist yet, create it. This is only called - when a window is already in use, or when output has been written during this - inflate call, but the end of the deflate stream has not been reached yet. - It is also called to create a window for dictionary data when a dictionary - is loaded. - - Providing output buffers larger than 32K to inflate() should provide a speed - advantage, since only the last 32K of output is copied to the sliding window - upon return from inflate(), and since all distances after the first 32K of - output will fall in the output data, making match copies simpler and faster. - The advantage may be dependent on the size of the processor's data caches. - */ - const updatewindow$2 = (strm, src, end, copy) => { - - let dist; - const state = strm.state; - - /* if it hasn't been done already, allocate space for the window */ - if (state.window === null) { - state.wsize = 1 << state.wbits; - state.wnext = 0; - state.whave = 0; - - state.window = new Uint8Array(state.wsize); - } - - /* copy state->wsize or less output bytes into the circular window */ - if (copy >= state.wsize) { - state.window.set(src.subarray(end - state.wsize, end), 0); - state.wnext = 0; - state.whave = state.wsize; - } - else { - dist = state.wsize - state.wnext; - if (dist > copy) { - dist = copy; - } - //zmemcpy(state->window + state->wnext, end - copy, dist); - state.window.set(src.subarray(end - copy, end - copy + dist), state.wnext); - copy -= dist; - if (copy) { - //zmemcpy(state->window, end - copy, copy); - state.window.set(src.subarray(end - copy, end), 0); - state.wnext = copy; - state.whave = state.wsize; - } - else { - state.wnext += dist; - if (state.wnext === state.wsize) { state.wnext = 0; } - if (state.whave < state.wsize) { state.whave += dist; } - } - } - return 0; - }; - - - const inflate$2$2 = (strm, flush) => { - - let state; - let input, output; // input/output buffers - let next; /* next input INDEX */ - let put; /* next output INDEX */ - let have, left; /* available input and output */ - let hold; /* bit buffer */ - let bits; /* bits in bit buffer */ - let _in, _out; /* save starting available input and output */ - let copy; /* number of stored or match bytes to copy */ - let from; /* where to copy match bytes from */ - let from_source; - let here = 0; /* current decoding table entry */ - let here_bits, here_op, here_val; // paked "here" denormalized (JS specific) - //let last; /* parent table entry */ - let last_bits, last_op, last_val; // paked "last" denormalized (JS specific) - let len; /* length to copy for repeats, bits to drop */ - let ret; /* return code */ - const hbuf = new Uint8Array(4); /* buffer for gzip header crc calculation */ - let opts; - - let n; // temporary variable for NEED_BITS - - const order = /* permutation of code lengths */ - new Uint8Array([ 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 ]); - - - if (inflateStateCheck$1(strm) || !strm.output || - (!strm.input && strm.avail_in !== 0)) { - return Z_STREAM_ERROR$1$2; - } - - state = strm.state; - if (state.mode === TYPE$3) { state.mode = TYPEDO$2; } /* skip check */ - - - //--- LOAD() --- - put = strm.next_out; - output = strm.output; - left = strm.avail_out; - next = strm.next_in; - input = strm.input; - have = strm.avail_in; - hold = state.hold; - bits = state.bits; - //--- - - _in = have; - _out = left; - ret = Z_OK$1$2; - - inf_leave: // goto emulation - for (;;) { - switch (state.mode) { - case HEAD$2: - if (state.wrap === 0) { - state.mode = TYPEDO$2; - break; - } - //=== NEEDBITS(16); - while (bits < 16) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - if ((state.wrap & 2) && hold === 0x8b1f) { /* gzip header */ - if (state.wbits === 0) { - state.wbits = 15; - } - state.check = 0/*crc32(0L, Z_NULL, 0)*/; - //=== CRC2(state.check, hold); - hbuf[0] = hold & 0xff; - hbuf[1] = (hold >>> 8) & 0xff; - state.check = crc32_1$2(state.check, hbuf, 2, 0); - //===// - - //=== INITBITS(); - hold = 0; - bits = 0; - //===// - state.mode = FLAGS$2; - break; - } - if (state.head) { - state.head.done = false; - } - if (!(state.wrap & 1) || /* check if zlib header allowed */ - (((hold & 0xff)/*BITS(8)*/ << 8) + (hold >> 8)) % 31) { - strm.msg = 'incorrect header check'; - state.mode = BAD$3; - break; - } - if ((hold & 0x0f)/*BITS(4)*/ !== Z_DEFLATED$4) { - strm.msg = 'unknown compression method'; - state.mode = BAD$3; - break; - } - //--- DROPBITS(4) ---// - hold >>>= 4; - bits -= 4; - //---// - len = (hold & 0x0f)/*BITS(4)*/ + 8; - if (state.wbits === 0) { - state.wbits = len; - } - if (len > 15 || len > state.wbits) { - strm.msg = 'invalid window size'; - state.mode = BAD$3; - break; - } - - // !!! pako patch. Force use `options.windowBits` if passed. - // Required to always use max window size by default. - state.dmax = 1 << state.wbits; - //state.dmax = 1 << len; - - state.flags = 0; /* indicate zlib header */ - //Tracev((stderr, "inflate: zlib header ok\n")); - strm.adler = state.check = 1/*adler32(0L, Z_NULL, 0)*/; - state.mode = hold & 0x200 ? DICTID$2 : TYPE$3; - //=== INITBITS(); - hold = 0; - bits = 0; - //===// - break; - case FLAGS$2: - //=== NEEDBITS(16); */ - while (bits < 16) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - state.flags = hold; - if ((state.flags & 0xff) !== Z_DEFLATED$4) { - strm.msg = 'unknown compression method'; - state.mode = BAD$3; - break; - } - if (state.flags & 0xe000) { - strm.msg = 'unknown header flags set'; - state.mode = BAD$3; - break; - } - if (state.head) { - state.head.text = ((hold >> 8) & 1); - } - if ((state.flags & 0x0200) && (state.wrap & 4)) { - //=== CRC2(state.check, hold); - hbuf[0] = hold & 0xff; - hbuf[1] = (hold >>> 8) & 0xff; - state.check = crc32_1$2(state.check, hbuf, 2, 0); - //===// - } - //=== INITBITS(); - hold = 0; - bits = 0; - //===// - state.mode = TIME$2; - /* falls through */ - case TIME$2: - //=== NEEDBITS(32); */ - while (bits < 32) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - if (state.head) { - state.head.time = hold; - } - if ((state.flags & 0x0200) && (state.wrap & 4)) { - //=== CRC4(state.check, hold) - hbuf[0] = hold & 0xff; - hbuf[1] = (hold >>> 8) & 0xff; - hbuf[2] = (hold >>> 16) & 0xff; - hbuf[3] = (hold >>> 24) & 0xff; - state.check = crc32_1$2(state.check, hbuf, 4, 0); - //=== - } - //=== INITBITS(); - hold = 0; - bits = 0; - //===// - state.mode = OS$2; - /* falls through */ - case OS$2: - //=== NEEDBITS(16); */ - while (bits < 16) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - if (state.head) { - state.head.xflags = (hold & 0xff); - state.head.os = (hold >> 8); - } - if ((state.flags & 0x0200) && (state.wrap & 4)) { - //=== CRC2(state.check, hold); - hbuf[0] = hold & 0xff; - hbuf[1] = (hold >>> 8) & 0xff; - state.check = crc32_1$2(state.check, hbuf, 2, 0); - //===// - } - //=== INITBITS(); - hold = 0; - bits = 0; - //===// - state.mode = EXLEN$2; - /* falls through */ - case EXLEN$2: - if (state.flags & 0x0400) { - //=== NEEDBITS(16); */ - while (bits < 16) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - state.length = hold; - if (state.head) { - state.head.extra_len = hold; - } - if ((state.flags & 0x0200) && (state.wrap & 4)) { - //=== CRC2(state.check, hold); - hbuf[0] = hold & 0xff; - hbuf[1] = (hold >>> 8) & 0xff; - state.check = crc32_1$2(state.check, hbuf, 2, 0); - //===// - } - //=== INITBITS(); - hold = 0; - bits = 0; - //===// - } - else if (state.head) { - state.head.extra = null/*Z_NULL*/; - } - state.mode = EXTRA$2; - /* falls through */ - case EXTRA$2: - if (state.flags & 0x0400) { - copy = state.length; - if (copy > have) { copy = have; } - if (copy) { - if (state.head) { - len = state.head.extra_len - state.length; - if (!state.head.extra) { - // Use untyped array for more convenient processing later - state.head.extra = new Uint8Array(state.head.extra_len); - } - state.head.extra.set( - input.subarray( - next, - // extra field is limited to 65536 bytes - // - no need for additional size check - next + copy - ), - /*len + copy > state.head.extra_max - len ? state.head.extra_max : copy,*/ - len - ); - //zmemcpy(state.head.extra + len, next, - // len + copy > state.head.extra_max ? - // state.head.extra_max - len : copy); - } - if ((state.flags & 0x0200) && (state.wrap & 4)) { - state.check = crc32_1$2(state.check, input, copy, next); - } - have -= copy; - next += copy; - state.length -= copy; - } - if (state.length) { break inf_leave; } - } - state.length = 0; - state.mode = NAME$2; - /* falls through */ - case NAME$2: - if (state.flags & 0x0800) { - if (have === 0) { break inf_leave; } - copy = 0; - do { - // TODO: 2 or 1 bytes? - len = input[next + copy++]; - /* use constant limit because in js we should not preallocate memory */ - if (state.head && len && - (state.length < 65536 /*state.head.name_max*/)) { - state.head.name += String.fromCharCode(len); - } - } while (len && copy < have); - - if ((state.flags & 0x0200) && (state.wrap & 4)) { - state.check = crc32_1$2(state.check, input, copy, next); - } - have -= copy; - next += copy; - if (len) { break inf_leave; } - } - else if (state.head) { - state.head.name = null; - } - state.length = 0; - state.mode = COMMENT$2; - /* falls through */ - case COMMENT$2: - if (state.flags & 0x1000) { - if (have === 0) { break inf_leave; } - copy = 0; - do { - len = input[next + copy++]; - /* use constant limit because in js we should not preallocate memory */ - if (state.head && len && - (state.length < 65536 /*state.head.comm_max*/)) { - state.head.comment += String.fromCharCode(len); - } - } while (len && copy < have); - if ((state.flags & 0x0200) && (state.wrap & 4)) { - state.check = crc32_1$2(state.check, input, copy, next); - } - have -= copy; - next += copy; - if (len) { break inf_leave; } - } - else if (state.head) { - state.head.comment = null; - } - state.mode = HCRC$2; - /* falls through */ - case HCRC$2: - if (state.flags & 0x0200) { - //=== NEEDBITS(16); */ - while (bits < 16) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - if ((state.wrap & 4) && hold !== (state.check & 0xffff)) { - strm.msg = 'header crc mismatch'; - state.mode = BAD$3; - break; - } - //=== INITBITS(); - hold = 0; - bits = 0; - //===// - } - if (state.head) { - state.head.hcrc = ((state.flags >> 9) & 1); - state.head.done = true; - } - strm.adler = state.check = 0; - state.mode = TYPE$3; - break; - case DICTID$2: - //=== NEEDBITS(32); */ - while (bits < 32) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - strm.adler = state.check = zswap32$2(hold); - //=== INITBITS(); - hold = 0; - bits = 0; - //===// - state.mode = DICT$2; - /* falls through */ - case DICT$2: - if (state.havedict === 0) { - //--- RESTORE() --- - strm.next_out = put; - strm.avail_out = left; - strm.next_in = next; - strm.avail_in = have; - state.hold = hold; - state.bits = bits; - //--- - return Z_NEED_DICT$1$2; - } - strm.adler = state.check = 1/*adler32(0L, Z_NULL, 0)*/; - state.mode = TYPE$3; - /* falls through */ - case TYPE$3: - if (flush === Z_BLOCK$3 || flush === Z_TREES$2) { break inf_leave; } - /* falls through */ - case TYPEDO$2: - if (state.last) { - //--- BYTEBITS() ---// - hold >>>= bits & 7; - bits -= bits & 7; - //---// - state.mode = CHECK$2; - break; - } - //=== NEEDBITS(3); */ - while (bits < 3) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - state.last = (hold & 0x01)/*BITS(1)*/; - //--- DROPBITS(1) ---// - hold >>>= 1; - bits -= 1; - //---// - - switch ((hold & 0x03)/*BITS(2)*/) { - case 0: /* stored block */ - //Tracev((stderr, "inflate: stored block%s\n", - // state.last ? " (last)" : "")); - state.mode = STORED$2; - break; - case 1: /* fixed block */ - fixedtables$2(state); - //Tracev((stderr, "inflate: fixed codes block%s\n", - // state.last ? " (last)" : "")); - state.mode = LEN_$2; /* decode codes */ - if (flush === Z_TREES$2) { - //--- DROPBITS(2) ---// - hold >>>= 2; - bits -= 2; - //---// - break inf_leave; - } - break; - case 2: /* dynamic block */ - //Tracev((stderr, "inflate: dynamic codes block%s\n", - // state.last ? " (last)" : "")); - state.mode = TABLE$2; - break; - case 3: - strm.msg = 'invalid block type'; - state.mode = BAD$3; - } - //--- DROPBITS(2) ---// - hold >>>= 2; - bits -= 2; - //---// - break; - case STORED$2: - //--- BYTEBITS() ---// /* go to byte boundary */ - hold >>>= bits & 7; - bits -= bits & 7; - //---// - //=== NEEDBITS(32); */ - while (bits < 32) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - if ((hold & 0xffff) !== ((hold >>> 16) ^ 0xffff)) { - strm.msg = 'invalid stored block lengths'; - state.mode = BAD$3; - break; - } - state.length = hold & 0xffff; - //Tracev((stderr, "inflate: stored length %u\n", - // state.length)); - //=== INITBITS(); - hold = 0; - bits = 0; - //===// - state.mode = COPY_$2; - if (flush === Z_TREES$2) { break inf_leave; } - /* falls through */ - case COPY_$2: - state.mode = COPY$2; - /* falls through */ - case COPY$2: - copy = state.length; - if (copy) { - if (copy > have) { copy = have; } - if (copy > left) { copy = left; } - if (copy === 0) { break inf_leave; } - //--- zmemcpy(put, next, copy); --- - output.set(input.subarray(next, next + copy), put); - //---// - have -= copy; - next += copy; - left -= copy; - put += copy; - state.length -= copy; - break; - } - //Tracev((stderr, "inflate: stored end\n")); - state.mode = TYPE$3; - break; - case TABLE$2: - //=== NEEDBITS(14); */ - while (bits < 14) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - state.nlen = (hold & 0x1f)/*BITS(5)*/ + 257; - //--- DROPBITS(5) ---// - hold >>>= 5; - bits -= 5; - //---// - state.ndist = (hold & 0x1f)/*BITS(5)*/ + 1; - //--- DROPBITS(5) ---// - hold >>>= 5; - bits -= 5; - //---// - state.ncode = (hold & 0x0f)/*BITS(4)*/ + 4; - //--- DROPBITS(4) ---// - hold >>>= 4; - bits -= 4; - //---// - //#ifndef PKZIP_BUG_WORKAROUND - if (state.nlen > 286 || state.ndist > 30) { - strm.msg = 'too many length or distance symbols'; - state.mode = BAD$3; - break; - } - //#endif - //Tracev((stderr, "inflate: table sizes ok\n")); - state.have = 0; - state.mode = LENLENS$2; - /* falls through */ - case LENLENS$2: - while (state.have < state.ncode) { - //=== NEEDBITS(3); - while (bits < 3) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - state.lens[order[state.have++]] = (hold & 0x07);//BITS(3); - //--- DROPBITS(3) ---// - hold >>>= 3; - bits -= 3; - //---// - } - while (state.have < 19) { - state.lens[order[state.have++]] = 0; - } - // We have separate tables & no pointers. 2 commented lines below not needed. - //state.next = state.codes; - //state.lencode = state.next; - // Switch to use dynamic table - state.lencode = state.lendyn; - state.lenbits = 7; - - opts = { bits: state.lenbits }; - ret = inftrees$2(CODES$3, state.lens, 0, 19, state.lencode, 0, state.work, opts); - state.lenbits = opts.bits; - - if (ret) { - strm.msg = 'invalid code lengths set'; - state.mode = BAD$3; - break; - } - //Tracev((stderr, "inflate: code lengths ok\n")); - state.have = 0; - state.mode = CODELENS$2; - /* falls through */ - case CODELENS$2: - while (state.have < state.nlen + state.ndist) { - for (;;) { - here = state.lencode[hold & ((1 << state.lenbits) - 1)];/*BITS(state.lenbits)*/ - here_bits = here >>> 24; - here_op = (here >>> 16) & 0xff; - here_val = here & 0xffff; - - if ((here_bits) <= bits) { break; } - //--- PULLBYTE() ---// - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - //---// - } - if (here_val < 16) { - //--- DROPBITS(here.bits) ---// - hold >>>= here_bits; - bits -= here_bits; - //---// - state.lens[state.have++] = here_val; - } - else { - if (here_val === 16) { - //=== NEEDBITS(here.bits + 2); - n = here_bits + 2; - while (bits < n) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - //--- DROPBITS(here.bits) ---// - hold >>>= here_bits; - bits -= here_bits; - //---// - if (state.have === 0) { - strm.msg = 'invalid bit length repeat'; - state.mode = BAD$3; - break; - } - len = state.lens[state.have - 1]; - copy = 3 + (hold & 0x03);//BITS(2); - //--- DROPBITS(2) ---// - hold >>>= 2; - bits -= 2; - //---// - } - else if (here_val === 17) { - //=== NEEDBITS(here.bits + 3); - n = here_bits + 3; - while (bits < n) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - //--- DROPBITS(here.bits) ---// - hold >>>= here_bits; - bits -= here_bits; - //---// - len = 0; - copy = 3 + (hold & 0x07);//BITS(3); - //--- DROPBITS(3) ---// - hold >>>= 3; - bits -= 3; - //---// - } - else { - //=== NEEDBITS(here.bits + 7); - n = here_bits + 7; - while (bits < n) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - //--- DROPBITS(here.bits) ---// - hold >>>= here_bits; - bits -= here_bits; - //---// - len = 0; - copy = 11 + (hold & 0x7f);//BITS(7); - //--- DROPBITS(7) ---// - hold >>>= 7; - bits -= 7; - //---// - } - if (state.have + copy > state.nlen + state.ndist) { - strm.msg = 'invalid bit length repeat'; - state.mode = BAD$3; - break; - } - while (copy--) { - state.lens[state.have++] = len; - } - } - } - - /* handle error breaks in while */ - if (state.mode === BAD$3) { break; } - - /* check for end-of-block code (better have one) */ - if (state.lens[256] === 0) { - strm.msg = 'invalid code -- missing end-of-block'; - state.mode = BAD$3; - break; - } - - /* build code tables -- note: do not change the lenbits or distbits - values here (9 and 6) without reading the comments in inftrees.h - concerning the ENOUGH constants, which depend on those values */ - state.lenbits = 9; - - opts = { bits: state.lenbits }; - ret = inftrees$2(LENS$3, state.lens, 0, state.nlen, state.lencode, 0, state.work, opts); - // We have separate tables & no pointers. 2 commented lines below not needed. - // state.next_index = opts.table_index; - state.lenbits = opts.bits; - // state.lencode = state.next; - - if (ret) { - strm.msg = 'invalid literal/lengths set'; - state.mode = BAD$3; - break; - } - - state.distbits = 6; - //state.distcode.copy(state.codes); - // Switch to use dynamic table - state.distcode = state.distdyn; - opts = { bits: state.distbits }; - ret = inftrees$2(DISTS$3, state.lens, state.nlen, state.ndist, state.distcode, 0, state.work, opts); - // We have separate tables & no pointers. 2 commented lines below not needed. - // state.next_index = opts.table_index; - state.distbits = opts.bits; - // state.distcode = state.next; - - if (ret) { - strm.msg = 'invalid distances set'; - state.mode = BAD$3; - break; - } - //Tracev((stderr, 'inflate: codes ok\n')); - state.mode = LEN_$2; - if (flush === Z_TREES$2) { break inf_leave; } - /* falls through */ - case LEN_$2: - state.mode = LEN$2; - /* falls through */ - case LEN$2: - if (have >= 6 && left >= 258) { - //--- RESTORE() --- - strm.next_out = put; - strm.avail_out = left; - strm.next_in = next; - strm.avail_in = have; - state.hold = hold; - state.bits = bits; - //--- - inffast$2(strm, _out); - //--- LOAD() --- - put = strm.next_out; - output = strm.output; - left = strm.avail_out; - next = strm.next_in; - input = strm.input; - have = strm.avail_in; - hold = state.hold; - bits = state.bits; - //--- - - if (state.mode === TYPE$3) { - state.back = -1; - } - break; - } - state.back = 0; - for (;;) { - here = state.lencode[hold & ((1 << state.lenbits) - 1)]; /*BITS(state.lenbits)*/ - here_bits = here >>> 24; - here_op = (here >>> 16) & 0xff; - here_val = here & 0xffff; - - if (here_bits <= bits) { break; } - //--- PULLBYTE() ---// - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - //---// - } - if (here_op && (here_op & 0xf0) === 0) { - last_bits = here_bits; - last_op = here_op; - last_val = here_val; - for (;;) { - here = state.lencode[last_val + - ((hold & ((1 << (last_bits + last_op)) - 1))/*BITS(last.bits + last.op)*/ >> last_bits)]; - here_bits = here >>> 24; - here_op = (here >>> 16) & 0xff; - here_val = here & 0xffff; - - if ((last_bits + here_bits) <= bits) { break; } - //--- PULLBYTE() ---// - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - //---// - } - //--- DROPBITS(last.bits) ---// - hold >>>= last_bits; - bits -= last_bits; - //---// - state.back += last_bits; - } - //--- DROPBITS(here.bits) ---// - hold >>>= here_bits; - bits -= here_bits; - //---// - state.back += here_bits; - state.length = here_val; - if (here_op === 0) { - //Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? - // "inflate: literal '%c'\n" : - // "inflate: literal 0x%02x\n", here.val)); - state.mode = LIT$2; - break; - } - if (here_op & 32) { - //Tracevv((stderr, "inflate: end of block\n")); - state.back = -1; - state.mode = TYPE$3; - break; - } - if (here_op & 64) { - strm.msg = 'invalid literal/length code'; - state.mode = BAD$3; - break; - } - state.extra = here_op & 15; - state.mode = LENEXT$2; - /* falls through */ - case LENEXT$2: - if (state.extra) { - //=== NEEDBITS(state.extra); - n = state.extra; - while (bits < n) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - state.length += hold & ((1 << state.extra) - 1)/*BITS(state.extra)*/; - //--- DROPBITS(state.extra) ---// - hold >>>= state.extra; - bits -= state.extra; - //---// - state.back += state.extra; - } - //Tracevv((stderr, "inflate: length %u\n", state.length)); - state.was = state.length; - state.mode = DIST$2; - /* falls through */ - case DIST$2: - for (;;) { - here = state.distcode[hold & ((1 << state.distbits) - 1)];/*BITS(state.distbits)*/ - here_bits = here >>> 24; - here_op = (here >>> 16) & 0xff; - here_val = here & 0xffff; - - if ((here_bits) <= bits) { break; } - //--- PULLBYTE() ---// - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - //---// - } - if ((here_op & 0xf0) === 0) { - last_bits = here_bits; - last_op = here_op; - last_val = here_val; - for (;;) { - here = state.distcode[last_val + - ((hold & ((1 << (last_bits + last_op)) - 1))/*BITS(last.bits + last.op)*/ >> last_bits)]; - here_bits = here >>> 24; - here_op = (here >>> 16) & 0xff; - here_val = here & 0xffff; - - if ((last_bits + here_bits) <= bits) { break; } - //--- PULLBYTE() ---// - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - //---// - } - //--- DROPBITS(last.bits) ---// - hold >>>= last_bits; - bits -= last_bits; - //---// - state.back += last_bits; - } - //--- DROPBITS(here.bits) ---// - hold >>>= here_bits; - bits -= here_bits; - //---// - state.back += here_bits; - if (here_op & 64) { - strm.msg = 'invalid distance code'; - state.mode = BAD$3; - break; - } - state.offset = here_val; - state.extra = (here_op) & 15; - state.mode = DISTEXT$2; - /* falls through */ - case DISTEXT$2: - if (state.extra) { - //=== NEEDBITS(state.extra); - n = state.extra; - while (bits < n) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - state.offset += hold & ((1 << state.extra) - 1)/*BITS(state.extra)*/; - //--- DROPBITS(state.extra) ---// - hold >>>= state.extra; - bits -= state.extra; - //---// - state.back += state.extra; - } - //#ifdef INFLATE_STRICT - if (state.offset > state.dmax) { - strm.msg = 'invalid distance too far back'; - state.mode = BAD$3; - break; - } - //#endif - //Tracevv((stderr, "inflate: distance %u\n", state.offset)); - state.mode = MATCH$2; - /* falls through */ - case MATCH$2: - if (left === 0) { break inf_leave; } - copy = _out - left; - if (state.offset > copy) { /* copy from window */ - copy = state.offset - copy; - if (copy > state.whave) { - if (state.sane) { - strm.msg = 'invalid distance too far back'; - state.mode = BAD$3; - break; - } - // (!) This block is disabled in zlib defaults, - // don't enable it for binary compatibility - //#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR - // Trace((stderr, "inflate.c too far\n")); - // copy -= state.whave; - // if (copy > state.length) { copy = state.length; } - // if (copy > left) { copy = left; } - // left -= copy; - // state.length -= copy; - // do { - // output[put++] = 0; - // } while (--copy); - // if (state.length === 0) { state.mode = LEN; } - // break; - //#endif - } - if (copy > state.wnext) { - copy -= state.wnext; - from = state.wsize - copy; - } - else { - from = state.wnext - copy; - } - if (copy > state.length) { copy = state.length; } - from_source = state.window; - } - else { /* copy from output */ - from_source = output; - from = put - state.offset; - copy = state.length; - } - if (copy > left) { copy = left; } - left -= copy; - state.length -= copy; - do { - output[put++] = from_source[from++]; - } while (--copy); - if (state.length === 0) { state.mode = LEN$2; } - break; - case LIT$2: - if (left === 0) { break inf_leave; } - output[put++] = state.length; - left--; - state.mode = LEN$2; - break; - case CHECK$2: - if (state.wrap) { - //=== NEEDBITS(32); - while (bits < 32) { - if (have === 0) { break inf_leave; } - have--; - // Use '|' instead of '+' to make sure that result is signed - hold |= input[next++] << bits; - bits += 8; - } - //===// - _out -= left; - strm.total_out += _out; - state.total += _out; - if ((state.wrap & 4) && _out) { - strm.adler = state.check = - /*UPDATE_CHECK(state.check, put - _out, _out);*/ - (state.flags ? crc32_1$2(state.check, output, _out, put - _out) : adler32_1$2(state.check, output, _out, put - _out)); - - } - _out = left; - // NB: crc32 stored as signed 32-bit int, zswap32 returns signed too - if ((state.wrap & 4) && (state.flags ? hold : zswap32$2(hold)) !== state.check) { - strm.msg = 'incorrect data check'; - state.mode = BAD$3; - break; - } - //=== INITBITS(); - hold = 0; - bits = 0; - //===// - //Tracev((stderr, "inflate: check matches trailer\n")); - } - state.mode = LENGTH$2; - /* falls through */ - case LENGTH$2: - if (state.wrap && state.flags) { - //=== NEEDBITS(32); - while (bits < 32) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - if ((state.wrap & 4) && hold !== (state.total & 0xffffffff)) { - strm.msg = 'incorrect length check'; - state.mode = BAD$3; - break; - } - //=== INITBITS(); - hold = 0; - bits = 0; - //===// - //Tracev((stderr, "inflate: length matches trailer\n")); - } - state.mode = DONE$2; - /* falls through */ - case DONE$2: - ret = Z_STREAM_END$1$2; - break inf_leave; - case BAD$3: - ret = Z_DATA_ERROR$1$2; - break inf_leave; - case MEM$2: - return Z_MEM_ERROR$1$2; - case SYNC$2: - /* falls through */ - default: - return Z_STREAM_ERROR$1$2; - } - } - - // inf_leave <- here is real place for "goto inf_leave", emulated via "break inf_leave" - - /* - Return from inflate(), updating the total counts and the check value. - If there was no progress during the inflate() call, return a buffer - error. Call updatewindow() to create and/or update the window state. - Note: a memory error from inflate() is non-recoverable. - */ - - //--- RESTORE() --- - strm.next_out = put; - strm.avail_out = left; - strm.next_in = next; - strm.avail_in = have; - state.hold = hold; - state.bits = bits; - //--- - - if (state.wsize || (_out !== strm.avail_out && state.mode < BAD$3 && - (state.mode < CHECK$2 || flush !== Z_FINISH$1$2))) { - if (updatewindow$2(strm, strm.output, strm.next_out, _out - strm.avail_out)) ; - } - _in -= strm.avail_in; - _out -= strm.avail_out; - strm.total_in += _in; - strm.total_out += _out; - state.total += _out; - if ((state.wrap & 4) && _out) { - strm.adler = state.check = /*UPDATE_CHECK(state.check, strm.next_out - _out, _out);*/ - (state.flags ? crc32_1$2(state.check, output, _out, strm.next_out - _out) : adler32_1$2(state.check, output, _out, strm.next_out - _out)); - } - strm.data_type = state.bits + (state.last ? 64 : 0) + - (state.mode === TYPE$3 ? 128 : 0) + - (state.mode === LEN_$2 || state.mode === COPY_$2 ? 256 : 0); - if (((_in === 0 && _out === 0) || flush === Z_FINISH$1$2) && ret === Z_OK$1$2) { - ret = Z_BUF_ERROR$3; - } - return ret; - }; - - - const inflateEnd$2 = (strm) => { - - if (inflateStateCheck$1(strm)) { - return Z_STREAM_ERROR$1$2; - } - - let state = strm.state; - if (state.window) { - state.window = null; - } - strm.state = null; - return Z_OK$1$2; - }; - - - const inflateGetHeader$2 = (strm, head) => { - - /* check state */ - if (inflateStateCheck$1(strm)) { return Z_STREAM_ERROR$1$2; } - const state = strm.state; - if ((state.wrap & 2) === 0) { return Z_STREAM_ERROR$1$2; } - - /* save header structure */ - state.head = head; - head.done = false; - return Z_OK$1$2; - }; - - - const inflateSetDictionary$2 = (strm, dictionary) => { - const dictLength = dictionary.length; - - let state; - let dictid; - let ret; - - /* check state */ - if (inflateStateCheck$1(strm)) { return Z_STREAM_ERROR$1$2; } - state = strm.state; - - if (state.wrap !== 0 && state.mode !== DICT$2) { - return Z_STREAM_ERROR$1$2; - } - - /* check for correct dictionary identifier */ - if (state.mode === DICT$2) { - dictid = 1; /* adler32(0, null, 0)*/ - /* dictid = adler32(dictid, dictionary, dictLength); */ - dictid = adler32_1$2(dictid, dictionary, dictLength, 0); - if (dictid !== state.check) { - return Z_DATA_ERROR$1$2; - } - } - /* copy dictionary to window using updatewindow(), which will amend the - existing dictionary if appropriate */ - ret = updatewindow$2(strm, dictionary, dictLength, dictLength); - if (ret) { - state.mode = MEM$2; - return Z_MEM_ERROR$1$2; - } - state.havedict = 1; - // Tracev((stderr, "inflate: dictionary set\n")); - return Z_OK$1$2; - }; - - - var inflateReset_1$2 = inflateReset$2; - var inflateReset2_1$2 = inflateReset2$2; - var inflateResetKeep_1$2 = inflateResetKeep$2; - var inflateInit_1$2 = inflateInit$2; - var inflateInit2_1$2 = inflateInit2$2; - var inflate_2$1$2 = inflate$2$2; - var inflateEnd_1$2 = inflateEnd$2; - var inflateGetHeader_1$2 = inflateGetHeader$2; - var inflateSetDictionary_1$2 = inflateSetDictionary$2; - var inflateInfo$2 = 'pako inflate (from Nodeca project)'; - - /* Not implemented - module.exports.inflateCodesUsed = inflateCodesUsed; - module.exports.inflateCopy = inflateCopy; - module.exports.inflateGetDictionary = inflateGetDictionary; - module.exports.inflateMark = inflateMark; - module.exports.inflatePrime = inflatePrime; - module.exports.inflateSync = inflateSync; - module.exports.inflateSyncPoint = inflateSyncPoint; - module.exports.inflateUndermine = inflateUndermine; - module.exports.inflateValidate = inflateValidate; - */ - - var inflate_1$2$2 = { - inflateReset: inflateReset_1$2, - inflateReset2: inflateReset2_1$2, - inflateResetKeep: inflateResetKeep_1$2, - inflateInit: inflateInit_1$2, - inflateInit2: inflateInit2_1$2, - inflate: inflate_2$1$2, - inflateEnd: inflateEnd_1$2, - inflateGetHeader: inflateGetHeader_1$2, - inflateSetDictionary: inflateSetDictionary_1$2, - inflateInfo: inflateInfo$2 - }; - - // (C) 1995-2013 Jean-loup Gailly and Mark Adler - // (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin - // - // This software is provided 'as-is', without any express or implied - // warranty. In no event will the authors be held liable for any damages - // arising from the use of this software. - // - // Permission is granted to anyone to use this software for any purpose, - // including commercial applications, and to alter it and redistribute it - // freely, subject to the following restrictions: - // - // 1. The origin of this software must not be misrepresented; you must not - // claim that you wrote the original software. If you use this software - // in a product, an acknowledgment in the product documentation would be - // appreciated but is not required. - // 2. Altered source versions must be plainly marked as such, and must not be - // misrepresented as being the original software. - // 3. This notice may not be removed or altered from any source distribution. - - function GZheader$2() { - /* true if compressed data believed to be text */ - this.text = 0; - /* modification time */ - this.time = 0; - /* extra flags (not used when writing a gzip file) */ - this.xflags = 0; - /* operating system */ - this.os = 0; - /* pointer to extra field or Z_NULL if none */ - this.extra = null; - /* extra field length (valid if extra != Z_NULL) */ - this.extra_len = 0; // Actually, we don't need it in JS, - // but leave for few code modifications - - // - // Setup limits is not necessary because in js we should not preallocate memory - // for inflate use constant limit in 65536 bytes - // - - /* space at extra (only when reading header) */ - // this.extra_max = 0; - /* pointer to zero-terminated file name or Z_NULL */ - this.name = ''; - /* space at name (only when reading header) */ - // this.name_max = 0; - /* pointer to zero-terminated comment or Z_NULL */ - this.comment = ''; - /* space at comment (only when reading header) */ - // this.comm_max = 0; - /* true if there was or will be a header crc */ - this.hcrc = 0; - /* true when done reading gzip header (not used when writing a gzip file) */ - this.done = false; - } - - var gzheader$2 = GZheader$2; - - const toString$4 = Object.prototype.toString; - - /* Public constants ==========================================================*/ - /* ===========================================================================*/ - - const { - Z_NO_FLUSH: Z_NO_FLUSH$4, Z_FINISH: Z_FINISH$5, - Z_OK: Z_OK$5, Z_STREAM_END: Z_STREAM_END$5, Z_NEED_DICT: Z_NEED_DICT$3, Z_STREAM_ERROR: Z_STREAM_ERROR$4, Z_DATA_ERROR: Z_DATA_ERROR$4, Z_MEM_ERROR: Z_MEM_ERROR$3 - } = constants$2$2; - - /* ===========================================================================*/ - - - /** - * class Inflate - * - * Generic JS-style wrapper for zlib calls. If you don't need - * streaming behaviour - use more simple functions: [[inflate]] - * and [[inflateRaw]]. - **/ - - /* internal - * inflate.chunks -> Array - * - * Chunks of output data, if [[Inflate#onData]] not overridden. - **/ - - /** - * Inflate.result -> Uint8Array|String - * - * Uncompressed result, generated by default [[Inflate#onData]] - * and [[Inflate#onEnd]] handlers. Filled after you push last chunk - * (call [[Inflate#push]] with `Z_FINISH` / `true` param). - **/ - - /** - * Inflate.err -> Number - * - * Error code after inflate finished. 0 (Z_OK) on success. - * Should be checked if broken data possible. - **/ - - /** - * Inflate.msg -> String - * - * Error message, if [[Inflate.err]] != 0 - **/ - - - /** - * new Inflate(options) - * - options (Object): zlib inflate options. - * - * Creates new inflator instance with specified params. Throws exception - * on bad params. Supported options: - * - * - `windowBits` - * - `dictionary` - * - * [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced) - * for more information on these. - * - * Additional options, for internal needs: - * - * - `chunkSize` - size of generated data chunks (16K by default) - * - `raw` (Boolean) - do raw inflate - * - `to` (String) - if equal to 'string', then result will be converted - * from utf8 to utf16 (javascript) string. When string output requested, - * chunk length can differ from `chunkSize`, depending on content. - * - * By default, when no options set, autodetect deflate/gzip data format via - * wrapper header. - * - * ##### Example: - * - * ```javascript - * const pako = require('pako') - * const chunk1 = new Uint8Array([1,2,3,4,5,6,7,8,9]) - * const chunk2 = new Uint8Array([10,11,12,13,14,15,16,17,18,19]); - * - * const inflate = new pako.Inflate({ level: 3}); - * - * inflate.push(chunk1, false); - * inflate.push(chunk2, true); // true -> last chunk - * - * if (inflate.err) { throw new Error(inflate.err); } - * - * console.log(inflate.result); - * ``` - **/ - function Inflate$1$2(options) { - this.options = common$2.assign({ - chunkSize: 1024 * 64, - windowBits: 15, - to: '' - }, options || {}); - - const opt = this.options; - - // Force window size for `raw` data, if not set directly, - // because we have no header for autodetect. - if (opt.raw && (opt.windowBits >= 0) && (opt.windowBits < 16)) { - opt.windowBits = -opt.windowBits; - if (opt.windowBits === 0) { opt.windowBits = -15; } - } - - // If `windowBits` not defined (and mode not raw) - set autodetect flag for gzip/deflate - if ((opt.windowBits >= 0) && (opt.windowBits < 16) && - !(options && options.windowBits)) { - opt.windowBits += 32; - } - - // Gzip header has no info about windows size, we can do autodetect only - // for deflate. So, if window size not set, force it to max when gzip possible - if ((opt.windowBits > 15) && (opt.windowBits < 48)) { - // bit 3 (16) -> gzipped data - // bit 4 (32) -> autodetect gzip/deflate - if ((opt.windowBits & 15) === 0) { - opt.windowBits |= 15; - } - } - - this.err = 0; // error code, if happens (0 = Z_OK) - this.msg = ''; // error message - this.ended = false; // used to avoid multiple onEnd() calls - this.chunks = []; // chunks of compressed data - - this.strm = new zstream$2(); - this.strm.avail_out = 0; - - let status = inflate_1$2$2.inflateInit2( - this.strm, - opt.windowBits - ); - - if (status !== Z_OK$5) { - throw new Error(messages$2[status]); - } - - this.header = new gzheader$2(); - - inflate_1$2$2.inflateGetHeader(this.strm, this.header); - - // Setup dictionary - if (opt.dictionary) { - // Convert data if needed - if (typeof opt.dictionary === 'string') { - opt.dictionary = strings$2.string2buf(opt.dictionary); - } else if (toString$4.call(opt.dictionary) === '[object ArrayBuffer]') { - opt.dictionary = new Uint8Array(opt.dictionary); - } - if (opt.raw) { //In raw mode we need to set the dictionary early - status = inflate_1$2$2.inflateSetDictionary(this.strm, opt.dictionary); - if (status !== Z_OK$5) { - throw new Error(messages$2[status]); - } - } - } - } - - /** - * Inflate#push(data[, flush_mode]) -> Boolean - * - data (Uint8Array|ArrayBuffer): input data - * - flush_mode (Number|Boolean): 0..6 for corresponding Z_NO_FLUSH..Z_TREE - * flush modes. See constants. Skipped or `false` means Z_NO_FLUSH, - * `true` means Z_FINISH. - * - * Sends input data to inflate pipe, generating [[Inflate#onData]] calls with - * new output chunks. Returns `true` on success. If end of stream detected, - * [[Inflate#onEnd]] will be called. - * - * `flush_mode` is not needed for normal operation, because end of stream - * detected automatically. You may try to use it for advanced things, but - * this functionality was not tested. - * - * On fail call [[Inflate#onEnd]] with error code and return false. - * - * ##### Example - * - * ```javascript - * push(chunk, false); // push one of data chunks - * ... - * push(chunk, true); // push last chunk - * ``` - **/ - Inflate$1$2.prototype.push = function (data, flush_mode) { - const strm = this.strm; - const chunkSize = this.options.chunkSize; - const dictionary = this.options.dictionary; - let status, _flush_mode, last_avail_out; - - if (this.ended) return false; - - if (flush_mode === ~~flush_mode) _flush_mode = flush_mode; - else _flush_mode = flush_mode === true ? Z_FINISH$5 : Z_NO_FLUSH$4; - - // Convert data if needed - if (toString$4.call(data) === '[object ArrayBuffer]') { - strm.input = new Uint8Array(data); - } else { - strm.input = data; - } - - strm.next_in = 0; - strm.avail_in = strm.input.length; - - for (;;) { - if (strm.avail_out === 0) { - strm.output = new Uint8Array(chunkSize); - strm.next_out = 0; - strm.avail_out = chunkSize; - } - - status = inflate_1$2$2.inflate(strm, _flush_mode); - - if (status === Z_NEED_DICT$3 && dictionary) { - status = inflate_1$2$2.inflateSetDictionary(strm, dictionary); - - if (status === Z_OK$5) { - status = inflate_1$2$2.inflate(strm, _flush_mode); - } else if (status === Z_DATA_ERROR$4) { - // Replace code with more verbose - status = Z_NEED_DICT$3; - } - } - - // Skip snyc markers if more data follows and not raw mode - while (strm.avail_in > 0 && - status === Z_STREAM_END$5 && - strm.state.wrap > 0 && - data[strm.next_in] !== 0) - { - inflate_1$2$2.inflateReset(strm); - status = inflate_1$2$2.inflate(strm, _flush_mode); - } - - switch (status) { - case Z_STREAM_ERROR$4: - case Z_DATA_ERROR$4: - case Z_NEED_DICT$3: - case Z_MEM_ERROR$3: - this.onEnd(status); - this.ended = true; - return false; - } - - // Remember real `avail_out` value, because we may patch out buffer content - // to align utf8 strings boundaries. - last_avail_out = strm.avail_out; - - if (strm.next_out) { - if (strm.avail_out === 0 || status === Z_STREAM_END$5) { - - if (this.options.to === 'string') { - - let next_out_utf8 = strings$2.utf8border(strm.output, strm.next_out); - - let tail = strm.next_out - next_out_utf8; - let utf8str = strings$2.buf2string(strm.output, next_out_utf8); - - // move tail & realign counters - strm.next_out = tail; - strm.avail_out = chunkSize - tail; - if (tail) strm.output.set(strm.output.subarray(next_out_utf8, next_out_utf8 + tail), 0); - - this.onData(utf8str); - - } else { - this.onData(strm.output.length === strm.next_out ? strm.output : strm.output.subarray(0, strm.next_out)); - } - } - } - - // Must repeat iteration if out buffer is full - if (status === Z_OK$5 && last_avail_out === 0) continue; - - // Finalize if end of stream reached. - if (status === Z_STREAM_END$5) { - status = inflate_1$2$2.inflateEnd(this.strm); - this.onEnd(status); - this.ended = true; - return true; - } - - if (strm.avail_in === 0) break; - } - - return true; - }; - - - /** - * Inflate#onData(chunk) -> Void - * - chunk (Uint8Array|String): output data. When string output requested, - * each chunk will be string. - * - * By default, stores data blocks in `chunks[]` property and glue - * those in `onEnd`. Override this handler, if you need another behaviour. - **/ - Inflate$1$2.prototype.onData = function (chunk) { - this.chunks.push(chunk); - }; - - - /** - * Inflate#onEnd(status) -> Void - * - status (Number): inflate status. 0 (Z_OK) on success, - * other if not. - * - * Called either after you tell inflate that the input stream is - * complete (Z_FINISH). By default - join collected chunks, - * free memory and fill `results` / `err` properties. - **/ - Inflate$1$2.prototype.onEnd = function (status) { - // On success - join - if (status === Z_OK$5) { - if (this.options.to === 'string') { - this.result = this.chunks.join(''); - } else { - this.result = common$2.flattenChunks(this.chunks); - } - } - this.chunks = []; - this.err = status; - this.msg = this.strm.msg; - }; - - - /** - * inflate(data[, options]) -> Uint8Array|String - * - data (Uint8Array|ArrayBuffer): input data to decompress. - * - options (Object): zlib inflate options. - * - * Decompress `data` with inflate/ungzip and `options`. Autodetect - * format via wrapper header by default. That's why we don't provide - * separate `ungzip` method. - * - * Supported options are: - * - * - windowBits - * - * [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced) - * for more information. - * - * Sugar (options): - * - * - `raw` (Boolean) - say that we work with raw stream, if you don't wish to specify - * negative windowBits implicitly. - * - `to` (String) - if equal to 'string', then result will be converted - * from utf8 to utf16 (javascript) string. When string output requested, - * chunk length can differ from `chunkSize`, depending on content. - * - * - * ##### Example: - * - * ```javascript - * const pako = require('pako'); - * const input = pako.deflate(new Uint8Array([1,2,3,4,5,6,7,8,9])); - * let output; - * - * try { - * output = pako.inflate(input); - * } catch (err) { - * console.log(err); - * } - * ``` - **/ - function inflate$1$2(input, options) { - const inflator = new Inflate$1$2(options); - - inflator.push(input); - - // That will never happens, if you don't cheat with options :) - if (inflator.err) throw inflator.msg || messages$2[inflator.err]; - - return inflator.result; - } - - - /** - * inflateRaw(data[, options]) -> Uint8Array|String - * - data (Uint8Array|ArrayBuffer): input data to decompress. - * - options (Object): zlib inflate options. - * - * The same as [[inflate]], but creates raw data, without wrapper - * (header and adler32 crc). - **/ - function inflateRaw$1$2(input, options) { - options = options || {}; - options.raw = true; - return inflate$1$2(input, options); - } - - - /** - * ungzip(data[, options]) -> Uint8Array|String - * - data (Uint8Array|ArrayBuffer): input data to decompress. - * - options (Object): zlib inflate options. - * - * Just shortcut to [[inflate]], because it autodetects format - * by header.content. Done for convenience. - **/ - - - var Inflate_1$1$2 = Inflate$1$2; - var inflate_2$3 = inflate$1$2; - var inflateRaw_1$1$2 = inflateRaw$1$2; - var ungzip$1$2 = inflate$1$2; - var constants$4 = constants$2$2; - - var inflate_1$1$2 = { - Inflate: Inflate_1$1$2, - inflate: inflate_2$3, - inflateRaw: inflateRaw_1$1$2, - ungzip: ungzip$1$2, - constants: constants$4 - }; - - const { Deflate: Deflate$2, deflate: deflate$3, deflateRaw: deflateRaw$2, gzip: gzip$2 } = deflate_1$1$1; - - const { Inflate: Inflate$3, inflate: inflate$4, inflateRaw: inflateRaw$3, ungzip: ungzip$3 } = inflate_1$1$2; - var deflateRaw_1$2 = deflateRaw$2; - var inflateRaw_1$2 = inflateRaw$3; - var ungzip_1$2 = ungzip$3; - - const FEXTRA$1 = 4; // gzip spec F.EXTRA flag - - function isgzipped$1(data) { - const b = ArrayBuffer.isView(data) ? data : new Uint8Array(data); - return b[0] ===31 && b[1] === 139; - } - - /** - * Pako does not properly ungzip block compressed files if > 1 block is present. Test for bgzip and use wrapper. - */ - function ungzip_blocks$1(data) { - const ba = ArrayBuffer.isView(data) ? data : new Uint8Array(data); - const b = ba[3] & FEXTRA$1; - if (b !== 0 && ba[12] === 66 && ba[13] === 67) { - return unbgzf$1(ba.buffer); - } else { - return ungzip_1$2(ba); - } - } - - // Uncompress data, assumed to be series of bgzipped blocks - function unbgzf$1(data, lim) { - - const oBlockList = []; - let ptr = 0; - let totalSize = 0; - - lim = lim || data.byteLength - 18; - - while (ptr < lim) { - try { - const ba = ArrayBuffer.isView(data) ? data : new Uint8Array(data, ptr, 18); - const xlen = (ba[11] << 8) | (ba[10]); - const flg = ba[3]; - const fextra = flg & FEXTRA$1; - const si1 = ba[12]; - const si2 = ba[13]; - const slen = (ba[15] << 8) | (ba[14]); - const bsize = ((ba[17] << 8) | (ba[16])) + 1; - const start = 12 + xlen + ptr; // Start of CDATA - const bytesLeft = data.byteLength - start; - const cDataSize = bsize - xlen - 19; - if (bytesLeft < cDataSize || cDataSize <= 0) break; - - const a = new Uint8Array(data, start, cDataSize); - const unc = inflateRaw_1$2(a); - - // const inflate = new Zlib.RawInflate(a); - // const unc = inflate.decompress(); - - ptr += (cDataSize - 1) + 26; //inflate.ip + 26 - totalSize += unc.byteLength; - oBlockList.push(unc); - } catch (e) { - console.error(e); - break; - } - } - - // Concatenate decompressed blocks - if (oBlockList.length === 1) { - return oBlockList[0]; - } else { - const out = new Uint8Array(totalSize); - let cursor = 0; - for (let i = 0; i < oBlockList.length; ++i) { - var b = new Uint8Array(oBlockList[i]); - arrayCopy$1(b, 0, out, cursor, b.length); - cursor += b.length; - } - return out; - } - } - - // From Thomas Down's zlib implementation - - const testArray$1 = new Uint8Array(1); - const hasSubarray$1 = (typeof testArray$1.subarray === 'function'); - - function arrayCopy$1(src, srcOffset, dest, destOffset, count) { - if (count === 0) { - return; - } - if (!src) { - throw "Undef src"; - } else if (!dest) { - throw "Undef dest"; - } - if (srcOffset === 0 && count === src.length) { - arrayCopy_fast$1(src, dest, destOffset); - } else if (hasSubarray$1) { - arrayCopy_fast$1(src.subarray(srcOffset, srcOffset + count), dest, destOffset); - } else if (src.BYTES_PER_ELEMENT === 1 && count > 100) { - arrayCopy_fast$1(new Uint8Array(src.buffer, src.byteOffset + srcOffset, count), dest, destOffset); - } else { - arrayCopy_slow$1(src, srcOffset, dest, destOffset, count); - } - } - - function arrayCopy_slow$1(src, srcOffset, dest, destOffset, count) { - for (let i = 0; i < count; ++i) { - dest[destOffset + i] = src[srcOffset + i]; - } - } - - function arrayCopy_fast$1(src, dest, destOffset) { - dest.set(src, destOffset); - } - - - /** - * Compress string and encode in a url safe form - * @param s - */ - function compressString$1(str) { - - const bytes = new Uint8Array(str.length); - for (var i = 0; i < str.length; i++) { - bytes[i] = str.charCodeAt(i); - } - const compressedBytes = new deflateRaw_1$2(bytes); // UInt8Arry - const compressedString = String.fromCharCode.apply(null, compressedBytes); // Convert to string - let enc = btoa(compressedString); - return enc.replace(/\+/g, '.').replace(/\//g, '_').replace(/=/g, '-'); // URL safe - } - - /** - * Uncompress the url-safe encoded compressed string, presumably created by compressString above - * - * @param enc - * @returns {string} - */ - function uncompressString$1(enc) { - - enc = enc.replace(/\./g, '+').replace(/_/g, '/').replace(/-/g, '='); - - const compressedString = atob(enc); - const compressedBytes = []; - for (let i = 0; i < compressedString.length; i++) { - compressedBytes.push(compressedString.charCodeAt(i)); - } - //const bytes = new Zlib.RawInflate(compressedBytes).decompress(); - const bytes = inflateRaw_1$2(compressedBytes); - - let str = ''; - for (let b of bytes) { - str += String.fromCharCode(b); - } - return str; - } - - - /** - * @param dataURI - * @returns {Array|Uint8Array} - */ - function decodeDataURI$2(dataURI, gzip) { - - const split = dataURI.split(','); - const info = split[0].split(':')[1]; - let dataString = split[1]; - - if (info.indexOf('base64') >= 0) { - dataString = atob(dataString); - - const bytes = new Uint8Array(dataString.length); - for (let i = 0; i < dataString.length; i++) { - bytes[i] = dataString.charCodeAt(i); - } - - let plain; - if (gzip || info.indexOf('gzip') > 0) { - plain = ungzip_1$2(bytes); - } else { - plain = bytes; - } - return plain - } else { - return decodeURIComponent(dataString); // URL encoded string -- not currently used or tested - } - } - - /* - * The MIT License (MIT) - * - * Copyright (c) 2016-2017 The Regents of the University of California - * Author: Jim Robinson - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - const IGVMath$1 = { - - lerp: (v0, v1, t) => { - return (1 - t) * v0 + t * v1; - }, - - mean: function (array) { - - var t = 0, n = 0, - i; - for (i = 0; i < array.length; i++) { - if (!isNaN(array[i])) { - t += array[i]; - n++; - } - } - return n > 0 ? t / n : 0; - }, - - meanAndStdev: function (array) { - - var v, t = 0, t2 = 0, n = 0, i; - - for (i = 0; i < array.length; i++) { - - v = array[i]; - - if (!isNaN(v)) { - t += v; - t2 += v * v; - n++; - } - } - return n > 0 ? {mean: t / n, stdev: Math.sqrt(t2 - t * t / n)} : {mean: 0, stdev: 0}; - }, - - median: function (numbers) { - // median of [3, 5, 4, 4, 1, 1, 2, 3] = 3 - var median = 0, numsLen = numbers.length; - numbers.sort(); - - if ( - numsLen % 2 === 0 // is even - ) { - // average of two middle numbers - median = (numbers[numsLen / 2 - 1] + numbers[numsLen / 2]) / 2; - } else { // is odd - // middle number only - median = numbers[(numsLen - 1) / 2]; - } - - return median; - }, - - // Fast percentile function for "p" near edges. This needs profiled for p in middle (e.g. median) - percentile: function (array, p) { - - if (array.length === 0) return undefined; - - var k = Math.floor(array.length * ((100 - p) / 100)); - if (k === 0) { - array.sort(function (a, b) { - return b - a - }); - return array[k]; - } else { - return selectElement$1(array, k); - } - - }, - - - clamp: function (value, min, max) { - return Math.min(Math.max(value, min), max); - }, - - log2: function (x) { - return Math.log(x) / Math.LN2; - } - - }; - - function selectElement$1(array, k) { - - // Credit Steve Hanov http://stevehanov.ca/blog/index.php?id=122 - var heap = new BinaryHeap$1(), - i; - - for (i = 0; i < array.length; i++) { - - var item = array[i]; - - // If we have not yet found k items, or the current item is larger than - // the smallest item on the heap, add current item - if (heap.content.length < k || item > heap.content[0]) { - // If the heap is full, remove the smallest element on the heap. - if (heap.content.length === k) { - heap.pop(); - } - heap.push(item); - } - } - - return heap.content[0]; - } - - - function BinaryHeap$1() { - this.content = []; - } - - BinaryHeap$1.prototype = { - push: function (element) { - // Add the new element to the end of the array. - this.content.push(element); - // Allow it to bubble up. - this.bubbleUp(this.content.length - 1); - }, - - pop: function () { - // Store the first element so we can return it later. - var result = this.content[0]; - // Get the element at the end of the array. - var end = this.content.pop(); - // If there are any elements left, put the end element at the - // start, and let it sink down. - if (this.content.length > 0) { - this.content[0] = end; - this.sinkDown(0); - } - return result; - }, - - remove: function (node) { - var length = this.content.length; - // To remove a value, we must search through the array to find - // it. - for (var i = 0; i < length; i++) { - if (this.content[i] !== node) continue; - // When it is found, the process seen in 'pop' is repeated - // to fill up the hole. - var end = this.content.pop(); - // If the element we popped was the one we needed to remove, - // we're done. - if (i === length - 1) break; - // Otherwise, we replace the removed element with the popped - // one, and allow it to float up or sink down as appropriate. - this.content[i] = end; - this.bubbleUp(i); - this.sinkDown(i); - break; - } - }, - - size: function () { - return this.content.length; - }, - - bubbleUp: function (n) { - // Fetch the element that has to be moved. - var element = this.content[n], score = element; - // When at 0, an element can not go up any further. - while (n > 0) { - // Compute the parent element's index, and fetch it. - var parentN = Math.floor((n + 1) / 2) - 1, - parent = this.content[parentN]; - // If the parent has a lesser score, things are in order and we - // are done. - if (score >= parent) - break; - - // Otherwise, swap the parent with the current element and - // continue. - this.content[parentN] = element; - this.content[n] = parent; - n = parentN; - } - }, - - sinkDown: function (n) { - // Look up the target element and its score. - var length = this.content.length, - element = this.content[n], - elemScore = element; - - while (true) { - // Compute the indices of the child elements. - var child2N = (n + 1) * 2, child1N = child2N - 1; - // This is used to store the new position of the element, - // if any. - var swap = null; - // If the first child exists (is inside the array)... - if (child1N < length) { - // Look it up and compute its score. - var child1 = this.content[child1N], - child1Score = child1; - // If the score is less than our element's, we need to swap. - if (child1Score < elemScore) - swap = child1N; - } - // Do the same checks for the other child. - if (child2N < length) { - var child2 = this.content[child2N], - child2Score = child2; - if (child2Score < (swap == null ? elemScore : child1Score)) - swap = child2N; - } - - // No need to swap further, we are done. - if (swap == null) break; - - // Otherwise, swap and continue. - this.content[n] = this.content[swap]; - this.content[swap] = element; - n = swap; - } - } - }; - - /* - * The MIT License (MIT) - * - * Copyright (c) 2014 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - function _random$1(min, max) { - return Math.random() * (max - min) + min; - } - - const IGVColor$1 = { - - rgbListFromHSV: () => { - - let s = 1; - let accumulation = []; - for (let v = 1; v >= 0.5; v -= .1) { - for (let h = 0; h < 1; h += 1 / 28) { - const r = "rgb(" + IGVColor$1.hsvToRgb(h, s, v).join(",") + ")"; - accumulation.push(r); - } - } - - // add black - accumulation.pop(); - accumulation.push(IGVColor$1.rgbColor(16, 16, 16)); - - return accumulation; - }, - - rgbToHex: function (rgb) { - rgb = rgb.match(/^rgba?[\s+]?\([\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?/i); - return (rgb && rgb.length === 4) ? "#" + - ("0" + parseInt(rgb[1], 10).toString(16)).slice(-2) + - ("0" + parseInt(rgb[2], 10).toString(16)).slice(-2) + - ("0" + parseInt(rgb[3], 10).toString(16)).slice(-2) : ''; - }, - - hexToRgb: function (hex) { - - var cooked = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex); - - if (null === cooked) { - return undefined; - } - - return "rgb(" + parseInt(cooked[1], 16) + "," + parseInt(cooked[2], 16) + "," + parseInt(cooked[3], 16) + ")"; - }, - - /** - * Converts an HSV color value to RGB. Conversion formula - * adapted from http://en.wikipedia.org/wiki/HSV_color_space. - * Assumes h, s, and v are contained in the set [0, 1] and - * returns r, g, and b in the set [0, 255]. - * - * Credit: https://gist.githubusercontent.com/mjackson/5311256 - * - * @param h The hue - * @param s The saturation - * @param v The value - * @return Array The RGB representation - */ - hsvToRgb: function (h, s, v) { - var r, g, b; - - var i = Math.floor(h * 6); - var f = h * 6 - i; - var p = v * (1 - s); - var q = v * (1 - f * s); - var t = v * (1 - (1 - f) * s); - - switch (i % 6) { - case 0: - r = v, g = t, b = p; - break; - case 1: - r = q, g = v, b = p; - break; - case 2: - r = p, g = v, b = t; - break; - case 3: - r = p, g = q, b = v; - break; - case 4: - r = t, g = p, b = v; - break; - case 5: - r = v, g = p, b = q; - break; - } - - return [Math.floor(r * 255), Math.floor(g * 255), Math.floor(b * 255)]; - }, - - /** - * Converts an HSL color value to RGB. Conversion formula - * adapted from http://en.wikipedia.org/wiki/HSL_color_space. - * Assumes h, s, and l are contained in the set [0, 1] and - * returns r, g, and b in the set [0, 255]. - * - * Credit: https://gist.githubusercontent.com/mjackson/5311256 - * - * @param h The hue - * @param s The saturation - * @param l The lightness - * @return Array The RGB representation - */ - hslToRgb: function (h, s, l) { - var r, g, b; - - if (s === 0) { - r = g = b = l; // achromatic - } else { - - - var q = l < 0.5 ? l * (1 + s) : l + s - l * s; - var p = 2 * l - q; - - r = IGVColor$1.hue2rgb(p, q, h + 1 / 3); - g = IGVColor$1.hue2rgb(p, q, h); - b = IGVColor$1.hue2rgb(p, q, h - 1 / 3); - } - - return [r * 255, g * 255, b * 255]; - }, - - hue2rgb: (p, q, t) => { - if (t < 0) t += 1; - if (t > 1) t -= 1; - if (t < 1 / 6) return p + (q - p) * 6 * t; - if (t < 1 / 2) return q; - if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6; - return p; - }, - - rgbaColor: function (r, g, b, a) { - - r = IGVMath$1.clamp(r, 0, 255); - g = IGVMath$1.clamp(g, 0, 255); - b = IGVMath$1.clamp(b, 0, 255); - a = IGVMath$1.clamp(a, 0.0, 1.0); - - return "rgba(" + r + "," + g + "," + b + "," + a + ")"; - }, - - rgbColor: function (r, g, b) { - - r = IGVMath$1.clamp(r, 0, 255); - g = IGVMath$1.clamp(g, 0, 255); - b = IGVMath$1.clamp(b, 0, 255); - - return "rgb(" + r + "," + g + "," + b + ")"; - }, - - greyScale: function (value) { - - var grey = IGVMath$1.clamp(value, 0, 255); - - return "rgb(" + grey + "," + grey + "," + grey + ")"; - }, - - randomGrey: function (min, max) { - - min = IGVMath$1.clamp(min, 0, 255); - max = IGVMath$1.clamp(max, 0, 255); - - var g = Math.round(_random$1(min, max)).toString(10); - - return "rgb(" + g + "," + g + "," + g + ")"; - }, - - randomRGB: function (min, max) { - - min = IGVMath$1.clamp(min, 0, 255); - max = IGVMath$1.clamp(max, 0, 255); - - var r = Math.round(_random$1(min, max)).toString(10); - var g = Math.round(_random$1(min, max)).toString(10); - var b = Math.round(_random$1(min, max)).toString(10); - - return "rgb(" + r + "," + g + "," + b + ")"; - }, - - randomRGBConstantAlpha: function (min, max, alpha) { - - min = IGVMath$1.clamp(min, 0, 255); - max = IGVMath$1.clamp(max, 0, 255); - - var r = Math.round(_random$1(min, max)).toString(10); - var g = Math.round(_random$1(min, max)).toString(10); - var b = Math.round(_random$1(min, max)).toString(10); - - return "rgba(" + r + "," + g + "," + b + "," + alpha + ")"; - }, - - addAlpha: function (color, alpha) { - - if(color === "0" || color === ".") { - color = "rgb(0,0,0)"; - } else { - const c = this.colorNameToHex(color); - if (c) { - color = c; - } - } - - var isHex = /(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(color); - - if (color.startsWith("rgba")) { - const idx = color.lastIndexOf(","); - return color.substring(0, idx+1) + alpha.toString() + ")"; - } - - if (isHex) { - color = IGVColor$1.hexToRgb(color); - } - - if (color.startsWith("rgb")) { - return color.replace("rgb", "rgba").replace(")", ", " + alpha + ")"); - } else { - console.log(color + " is not an rgb style string"); - return color; - } - }, - - rgbComponents: function (color) { - - if(color === "0" || color === ".") { - return [0,0,0]; - } - const isHex = /(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(color); - if (isHex) { - color = IGVColor$1.hexToRgb(color); - } else { - if(!color.startsWith("rgb")) { - const hex = this.colorNameToHex(color); - color = this.hexToRgb(hex); - } - } - - if (color.startsWith("rgb(")) { - return color.substring(4, color.length-1).split(",").map(s => Number.parseInt(s.trim())); - } else if (color.startsWith("rgba(")) { - return color.substring(5, color.length-1).split(",").map((s, i) => { - s = s.trim(); - return i === 3 ? Number.parseFloat(s) : Number.parseInt(s) - }); - } - else { - throw Error("Unrecognized color string: color"); - } - }, - - /** - * - * @param dest RGB components as an array - * @param src RGB components as an array - * @param alpha alpha transparancy in the range 0-1 - * @returns {} - */ - getCompositeColor: function (dest, src, alpha) { - - var r = Math.floor(alpha * src[0] + (1 - alpha) * dest[0]), - g = Math.floor(alpha * src[1] + (1 - alpha) * dest[1]), - b = Math.floor(alpha * src[2] + (1 - alpha) * dest[2]); - - return "rgb(" + r + "," + g + "," + b + ")"; - - }, - - - createColorString: function (str) { - // Excel will quote color strings, strip all quotes - str = stripQuotes$2(str); - - if (str.includes(",")) { - return str.startsWith("rgb") ? str : "rgb(" + str + ")"; - } else { - return str; - } - }, - - darkenLighten: function (color, amt) { - - let src; - let hexColor = this.colorNameToHex(color); - if(hexColor) { - src = IGVColor$1.hexToRgb(hexColor); - } else { - src = color.startsWith('rgb(') ? color : IGVColor$1.hexToRgb(color); - } - - const components = src.replace(")", "").substring(4).split(","); - - const r = Math.max(0, Math.min(255, Number.parseInt(components[0].trim()) + amt)); - const g = Math.max(0, Math.min(255, Number.parseInt(components[1].trim()) + amt)); - const b = Math.max(0, Math.min(255, Number.parseInt(components[2].trim()) + amt)); - - return 'rgb(' + r.toString() + ',' + g.toString() + ',' + b.toString() + ')'; - - }, - - /** - * Convert html/css color name to hex value. Adapted from https://gist.github.com/mxfh/4719348 - * @param colorName - * @returns {*} - */ - colorNameToHex: function (colorName) { // color list from http://stackoverflow.com/q/1573053/731179 with added gray/gray - const definedColorNames = { - "aliceblue": "#f0f8ff", - "antiquewhite": "#faebd7", - "aqua": "#00ffff", - "aquamarine": "#7fffd4", - "azure": "#f0ffff", - "beige": "#f5f5dc", - "bisque": "#ffe4c4", - "black": "#000000", - "blanchedalmond": "#ffebcd", - "blue": "#0000ff", - "blueviolet": "#8a2be2", - "brown": "#a52a2a", - "burlywood": "#deb887", - "cadetblue": "#5f9ea0", - "chartreuse": "#7fff00", - "chocolate": "#d2691e", - "coral": "#ff7f50", - "cornflowerblue": "#6495ed", - "cornsilk": "#fff8dc", - "crimson": "#dc143c", - "cyan": "#00ffff", - "darkblue": "#00008b", - "darkcyan": "#008b8b", - "darkgoldenrod": "#b8860b", - "darkgray": "#a9a9a9", - "darkgreen": "#006400", - "darkkhaki": "#bdb76b", - "darkmagenta": "#8b008b", - "darkolivegreen": "#556b2f", - "darkorange": "#ff8c00", - "darkorchid": "#9932cc", - "darkred": "#8b0000", - "darksalmon": "#e9967a", - "darkseagreen": "#8fbc8f", - "darkslateblue": "#483d8b", - "darkslategray": "#2f4f4f", - "darkturquoise": "#00ced1", - "darkviolet": "#9400d3", - "deeppink": "#ff1493", - "deepskyblue": "#00bfff", - "dimgray": "#696969", - "dodgerblue": "#1e90ff", - "firebrick": "#b22222", - "floralwhite": "#fffaf0", - "forestgreen": "#228b22", - "fuchsia": "#ff00ff", - "gainsboro": "#dcdcdc", - "ghostwhite": "#f8f8ff", - "gold": "#ffd700", - "goldenrod": "#daa520", - "gray": "#808080", - "green": "#008000", - "greenyellow": "#adff2f", - "honeydew": "#f0fff0", - "hotpink": "#ff69b4", - "indianred ": "#cd5c5c", - "indigo ": "#4b0082", - "ivory": "#fffff0", - "khaki": "#f0e68c", - "lavender": "#e6e6fa", - "lavenderblush": "#fff0f5", - "lawngreen": "#7cfc00", - "lemonchiffon": "#fffacd", - "lightblue": "#add8e6", - "lightcoral": "#f08080", - "lightcyan": "#e0ffff", - "lightgoldenrodyellow": "#fafad2", - "lightgrey": "#d3d3d3", - "lightgreen": "#90ee90", - "lightpink": "#ffb6c1", - "lightsalmon": "#ffa07a", - "lightseagreen": "#20b2aa", - "lightskyblue": "#87cefa", - "lightslategray": "#778899", - "lightsteelblue": "#b0c4de", - "lightyellow": "#ffffe0", - "lime": "#00ff00", - "limegreen": "#32cd32", - "linen": "#faf0e6", - "magenta": "#ff00ff", - "maroon": "#800000", - "mediumaquamarine": "#66cdaa", - "mediumblue": "#0000cd", - "mediumorchid": "#ba55d3", - "mediumpurple": "#9370d8", - "mediumseagreen": "#3cb371", - "mediumslateblue": "#7b68ee", - "mediumspringgreen": "#00fa9a", - "mediumturquoise": "#48d1cc", - "mediumvioletred": "#c71585", - "midnightblue": "#191970", - "mintcream": "#f5fffa", - "mistyrose": "#ffe4e1", - "moccasin": "#ffe4b5", - "navajowhite": "#ffdead", - "navy": "#000080", - "oldlace": "#fdf5e6", - "olive": "#808000", - "olivedrab": "#6b8e23", - "orange": "#ffa500", - "orangered": "#ff4500", - "orchid": "#da70d6", - "palegoldenrod": "#eee8aa", - "palegreen": "#98fb98", - "paleturquoise": "#afeeee", - "palevioletred": "#d87093", - "papayawhip": "#ffefd5", - "peachpuff": "#ffdab9", - "peru": "#cd853f", - "pink": "#ffc0cb", - "plum": "#dda0dd", - "powderblue": "#b0e0e6", - "purple": "#800080", - "red": "#ff0000", - "rosybrown": "#bc8f8f", - "royalblue": "#4169e1", - "saddlebrown": "#8b4513", - "salmon": "#fa8072", - "sandybrown": "#f4a460", - "seagreen": "#2e8b57", - "seashell": "#fff5ee", - "sienna": "#a0522d", - "silver": "#c0c0c0", - "skyblue": "#87ceeb", - "slateblue": "#6a5acd", - "slategray": "#708090", - "snow": "#fffafa", - "springgreen": "#00ff7f", - "steelblue": "#4682b4", - "tan": "#d2b48c", - "teal": "#008080", - "thistle": "#d8bfd8", - "tomato": "#ff6347", - "turquoise": "#40e0d0", - "violet": "#ee82ee", - "wheat": "#f5deb3", - "white": "#ffffff", - "whitesmoke": "#f5f5f5", - "yellow": "#ffff00", - "yellowgreen": "#9acd32", - "darkgrey": "#a9a9a9", - "darkslategrey": "#2f4f4f", - "dimgrey": "#696969", - "grey": "#808080", - "lightgray": "#d3d3d3", - "lightslategrey": "#778899", - "slategrey": "#708090" - }; - return definedColorNames[colorName]; - } - }; - - // Support for oauth token based authorization - // This class supports explicit setting of an oauth token either globally or for specific hosts. - // - // The variable oauth.google.access_token, which becomes igv.oauth.google.access_token on ES5 conversion is - // supported for backward compatibility - - const DEFAULT_HOST$1 = "googleapis"; - - class Oauth$1 { - - constructor() { - this.oauthTokens = {}; - } - - - setToken(token, host) { - host = host || DEFAULT_HOST$1; - this.oauthTokens[host] = token; - } - - getToken(host) { - host = host || DEFAULT_HOST$1; - let token; - for (let key of Object.keys(this.oauthTokens)) { - const regex = wildcardToRegExp$1(key); - if (regex.test(host)) { - token = this.oauthTokens[key]; - break - } - } - return token - } - - removeToken(host) { - host = host || DEFAULT_HOST$1; - for (let key of Object.keys(this.oauthTokens)) { - const regex = wildcardToRegExp$1(key); - if (regex.test(host)) { - this.oauthTokens[key] = undefined; - } - } - } - - // Special object for google -- legacy support - // google: { - // setToken: function (token) { - // oauth.setToken(token); - // } - // } - } - - - /** - * Creates a RegExp from the given string, converting asterisks to .* expressions, - * and escaping all other characters. - * - * credit https://gist.github.com/donmccurdy/6d073ce2c6f3951312dfa45da14a420f - */ - function wildcardToRegExp$1(s) { - return new RegExp('^' + s.split(/\*+/).map(regExpEscape$1).join('.*') + '$') - } - - /** - * RegExp-escapes all characters in the given string. - * - * credit https://gist.github.com/donmccurdy/6d073ce2c6f3951312dfa45da14a420f - */ - function regExpEscape$1(s) { - return s.replace(/[|\\{}()[\]^$+*?.]/g, '\\$&') - } - - function isGoogleURL$2(url) { - return (url.includes("googleapis") && !url.includes("urlshortener")) || - isGoogleStorageURL$2(url) || - isGoogleDriveURL$2(url) - } - - function isGoogleStorageURL$2(url) { - return url.startsWith("gs://") || - url.startsWith("https://www.googleapis.com/storage") || - url.startsWith("https://storage.cloud.google.com") || - url.startsWith("https://storage.googleapis.com"); - } - - function isGoogleDriveURL$2(url) { - return url.indexOf("drive.google.com") >= 0 || url.indexOf("www.googleapis.com/drive") > 0 - } - - /** - * Translate gs:// urls to https - * See https://cloud.google.com/storage/docs/json_api/v1 - * @param gsUrl - * @returns {string|*} - */ - function translateGoogleCloudURL$1(gsUrl) { - - let {bucket, object} = parseBucketName$1(gsUrl); - object = encode$1(object); - - const qIdx = gsUrl.indexOf('?'); - const paramString = (qIdx > 0) ? gsUrl.substring(qIdx) + "&alt=media" : "?alt=media"; - - return `https://storage.googleapis.com/storage/v1/b/${bucket}/o/${object}${paramString}` - } - - /** - * Parse a google bucket and object name from a google storage URL. Known forms include - * - * gs://BUCKET_NAME/OBJECT_NAME - * https://storage.googleapis.com/BUCKET_NAME/OBJECT_NAME - * https://storage.googleapis.com/storage/v1/b/BUCKET_NAME/o/OBJECT_NAME - * https://www.googleapis.com/storage/v1/b/BUCKET_NAME/o/OBJECT_NAME" - * https://storage.googleapis.com/download/storage/v1/b/BUCKET_NAME/o/OBJECT_NAME - * - * @param url - */ - function parseBucketName$1(url) { - - let bucket; - let object; - - if (url.startsWith("gs://")) { - const i = url.indexOf('/', 5); - if (i >= 0) { - bucket = url.substring(5, i); - const qIdx = url.indexOf('?'); - object = (qIdx < 0) ? url.substring(i + 1) : url.substring(i + 1, qIdx); - } - - } else if (url.startsWith("https://storage.googleapis.com") || url.startsWith("https://storage.cloud.google.com")) { - const bucketIdx = url.indexOf("/v1/b/", 8); - if (bucketIdx > 0) { - const objIdx = url.indexOf("/o/", bucketIdx); - if (objIdx > 0) { - const queryIdx = url.indexOf("?", objIdx); - bucket = url.substring(bucketIdx + 6, objIdx); - object = queryIdx > 0 ? url.substring(objIdx + 3, queryIdx) : url.substring(objIdx + 3); - } - - } else { - const idx1 = url.indexOf("/", 8); - const idx2 = url.indexOf("/", idx1+1); - const idx3 = url.indexOf("?", idx2); - if (idx2 > 0) { - bucket = url.substring(idx1+1, idx2); - object = idx3 < 0 ? url.substring(idx2+1) : url.substring(idx2+1, idx3); - } - } - - } else if (url.startsWith("https://www.googleapis.com/storage/v1/b")) { - const bucketIdx = url.indexOf("/v1/b/", 8); - const objIdx = url.indexOf("/o/", bucketIdx); - if (objIdx > 0) { - const queryIdx = url.indexOf("?", objIdx); - bucket = url.substring(bucketIdx + 6, objIdx); - object = queryIdx > 0 ? url.substring(objIdx + 3, queryIdx) : url.substring(objIdx + 3); - } - } - - if (bucket && object) { - return { - bucket, object - } - } else { - throw Error(`Unrecognized Google Storage URI: ${url}`) - } - - } - - /** - * Percent a GCS object name. See https://cloud.google.com/storage/docs/request-endpoints - * Specific characters to encode: - * !, #, $, &, ', (, ), *, +, ,, /, :, ;, =, ?, @, [, ], and space characters. - * @param obj - */ - - function encode$1(objectName) { - - let result = ''; - objectName.split('').forEach(function(letter) { - if(encodings$3.has(letter)) { - result += encodings$3.get(letter); - } else { - result += letter; - } - }); - return result; - } - - // %23 %24 %25 %26 %27 %28 %29 %2A %2B %2C %2F %3A %3B %3D %3F %40 %5B %5D - const encodings$3 = new Map(); - encodings$3.set("!", "%21"); - encodings$3.set("#", "%23"); - encodings$3.set("$", "%24"); - encodings$3.set("%", "%25"); - encodings$3.set("&", "%26"); - encodings$3.set("'", "%27"); - encodings$3.set("(", "%28"); - encodings$3.set(")", "%29"); - encodings$3.set("*", "%2A"); - encodings$3.set("+", "%2B"); - encodings$3.set(",", "%2C"); - encodings$3.set("/", "%2F"); - encodings$3.set(":", "%3A"); - encodings$3.set(";", "%3B"); - encodings$3.set("=", "%3D"); - encodings$3.set("?", "%3F"); - encodings$3.set("@", "%40"); - encodings$3.set("[", "%5B"); - encodings$3.set("]", "%5D"); - encodings$3.set(" ", "%20"); - - // Convenience functions for the gapi oAuth library. - - function isInitialized$1() { - return window.google && window.google.igv - } - - /** - * Return the current access token if the user is signed in, or undefined otherwise. This function does not - * attempt a signIn or request any specfic scopes. - * - * @returns access_token || undefined - */ - function getCurrentAccessToken$1() { - return (isInitialized$1() && google.igv.tokenResponse && Date.now() < google.igv.tokenExpiresAt) ? - google.igv.tokenResponse.access_token : - undefined - } - - - /** - * Return a promise for an access token for the given scope. If the user hasn't authorized the scope request it - * - * @param scope - * @returns {Promise} - */ - async function getAccessToken$1(scope) { - - if (!isInitialized$1()) { - throw Error("Google oAuth has not been initialized") - } - - if (google.igv.tokenResponse && - Date.now() < google.igv.tokenExpiresAt && - google.accounts.oauth2.hasGrantedAllScopes(google.igv.tokenResponse, scope)) { - return google.igv.tokenResponse.access_token - } else { - const tokenClient = google.igv.tokenClient; - return new Promise((resolve, reject) => { - try { - // Settle this promise in the response callback for requestAccessToken() - tokenClient.callback = (tokenResponse) => { - if (tokenResponse.error !== undefined) { - reject(tokenResponse); - } - google.igv.tokenResponse = tokenResponse; - google.igv.tokenExpiresAt = Date.now() + tokenResponse.expires_in * 1000; - resolve(tokenResponse.access_token); - }; - tokenClient.requestAccessToken({scope}); - } catch (err) { - console.log(err); - } - }) - } - } - - // gapi.auth2.getAuthInstance().isSignedIn.listen(status => { - // const user = gapi.auth2.getAuthInstance().currentUser.get() - // queryGoogleAuthenticationStatus(user, status) - // }) - - function getScopeForURL$1(url) { - if (isGoogleDriveURL$2(url)) { - return "https://www.googleapis.com/auth/drive.readonly" - } else if (isGoogleStorageURL$2(url)) { - return "https://www.googleapis.com/auth/devstorage.read_only" - } else { - return 'https://www.googleapis.com/auth/userinfo.profile' - } - } - - function getDriveDownloadURL$2(link) { - // Return a google drive download url for the sharable link - //https://drive.google.com/open?id=0B-lleX9c2pZFbDJ4VVRxakJzVGM - //https://drive.google.com/file/d/1_FC4kCeO8E3V4dJ1yIW7A0sn1yURKIX-/view?usp=sharing - var id = getGoogleDriveFileID$2(link); - return id ? "https://www.googleapis.com/drive/v3/files/" + id + "?alt=media&supportsTeamDrives=true" : link; - } - - function getGoogleDriveFileID$2(link) { - - //https://drive.google.com/file/d/1_FC4kCeO8E3V4dJ1yIW7A0sn1yURKIX-/view?usp=sharing - //https://www.googleapis.com/drive/v3/files/1w-tvo6p1SH4p1OaQSVxpkV_EJgGIstWF?alt=media&supportsTeamDrives=true" - - if (link.includes("/open?id=")) { - const i1 = link.indexOf("/open?id=") + 9; - const i2 = link.indexOf("&"); - if (i1 > 0 && i2 > i1) { - return link.substring(i1, i2) - } else if (i1 > 0) { - return link.substring(i1); - } - - } else if (link.includes("/file/d/")) { - const i1 = link.indexOf("/file/d/") + 8; - const i2 = link.lastIndexOf("/"); - return link.substring(i1, i2); - - } else if (link.startsWith("https://www.googleapis.com/drive")) { - let i1 = link.indexOf("/files/"); - const i2 = link.indexOf("?"); - if (i1 > 0) { - i1 += 7; - return i2 > 0 ? - link.substring(i1, i2) : - link.substring(i1) - } - } - - throw Error("Unknown Google Drive url format: " + link); - - - } - - // The MIT License (MIT) - - /** - * @constructor - * @param {Object} options A set op options to pass to the throttle function - * @param {number} requestsPerSecond The amount of requests per second - * the library will limit to - */ - class Throttle$1 { - constructor(options) { - this.requestsPerSecond = options.requestsPerSecond || 10; - this.lastStartTime = 0; - this.queued = []; - } - - /** - * Adds a promise - * @param {Function} async function to be executed - * @param {Object} options A set of options. - * @return {Promise} A promise - */ - add(asyncFunction, options) { - - var self = this; - return new Promise(function (resolve, reject) { - self.queued.push({ - resolve: resolve, - reject: reject, - asyncFunction: asyncFunction, - }); - self.dequeue(); - }); - } - - /** - * Adds all the promises passed as parameters - * @param {Function} promises An array of functions that return a promise - * @param {Object} options A set of options. - * @param {number} options.signal An AbortSignal object that can be used to abort the returned promise - * @param {number} options.weight A "weight" of each operation resolving by array of promises - * @return {Promise} A promise that succeeds when all the promises passed as options do - */ - addAll(promises, options) { - var addedPromises = promises.map(function (promise) { - return this.add(promise, options); - }.bind(this)); - - return Promise.all(addedPromises); - }; - - /** - * Dequeues a promise - * @return {void} - */ - dequeue() { - if (this.queued.length > 0) { - var now = new Date(), - inc = (1000 / this.requestsPerSecond) + 1, - elapsed = now - this.lastStartTime; - - if (elapsed >= inc) { - this._execute(); - } else { - // we have reached the limit, schedule a dequeue operation - setTimeout(function () { - this.dequeue(); - }.bind(this), inc - elapsed); - } - } - } - - /** - * Executes the promise - * @private - * @return {void} - */ - async _execute() { - this.lastStartTime = new Date(); - var candidate = this.queued.shift(); - const f = candidate.asyncFunction; - try { - const r = await f(); - candidate.resolve(r); - } catch (e) { - candidate.reject(e); - } - - } - - - } - - /* - * The MIT License (MIT) - * - * Copyright (c) 2014 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - class IGVXhr$1 { - - constructor() { - this.apiKey = undefined; - this.googleThrottle = new Throttle$1({ - requestsPerSecond: 8 - }); - this.RANGE_WARNING_GIVEN = false; - this.oauth = new Oauth$1(); - this.contentLengthMap = new Map(); - } - - setApiKey(key) { - this.apiKey = key; - } - - async loadArrayBuffer(url, options) { - options = options || {}; - if (!options.responseType) { - options.responseType = "arraybuffer"; - } - if (isFile$2(url)) { - return this._loadFileSlice(url, options) - } else { - return this.load(url, options) - } - } - - async loadJson(url, options) { - options = options || {}; - const method = options.method || (options.sendData ? "POST" : "GET"); - if (method === "POST") { - options.contentType = "application/json"; - } - const result = await this.loadString(url, options); - if (result) { - return JSON.parse(result) - } else { - return result - } - } - - async loadString(path, options) { - options = options || {}; - if (path instanceof File) { - return this._loadStringFromFile(path, options) - } else { - return this._loadStringFromUrl(path, options) - } - } - - async load(url, options) { - - options = options || {}; - const urlType = typeof url; - - // Resolve functions, promises, and functions that return promises - url = await (typeof url === 'function' ? url() : url); - - if (isFile$2(url)) { - return this._loadFileSlice(url, options) - } else if (typeof url.startsWith === 'function') { // Test for string - if (url.startsWith("data:")) { - const buffer = decodeDataURI$2(url).buffer; - if (options.range) { - const rangeEnd = options.range.size ? options.range.start + options.range.size : buffer.byteLength; - return buffer.slice(options.range.start, rangeEnd) - } else { - return buffer - } - } else { - if (url.startsWith("https://drive.google.com")) { - url = getDriveDownloadURL$2(url); - } - if (isGoogleDriveURL$2(url) || url.startsWith("https://www.dropbox.com")) { - return this.googleThrottle.add(async () => { - return this._loadURL(url, options) - }) - } else { - return this._loadURL(url, options) - } - } - } else { - throw Error(`url must be either a 'File', 'string', 'function', or 'Promise'. Actual type: ${urlType}`) - } - } - - async getContentLength(url, options) { - if (!this.contentLengthMap.has(url)) { - options = options || {}; - options.method = 'HEAD'; - options.GET_CONTENT_LENGTH = true; - const contentLengthString = await this._loadURL(url, options); - const contentLength = contentLengthString ? Number.parseInt(contentLengthString) : -1; - this.contentLengthMap.set(url, contentLength); - } - return this.contentLengthMap.get(url) - } - - async _loadURL(url, options) { - - const self = this; - - //console.log(`${Date.now()} ${url}`) - url = mapUrl$3(url); - - options = options || {}; - - let oauthToken = options.oauthToken || this.getOauthToken(url); - if (oauthToken) { - oauthToken = await (typeof oauthToken === 'function' ? oauthToken() : oauthToken); - } - - let contentLength = -1; - if (options.range && !isAmazonV4Signed(url) && !isGoogleStorageSigned$1(url)) { - contentLength = await this.getContentLength(url); - } - - return new Promise(function (resolve, reject) { - - // Various Google tansformations - if (isGoogleURL$2(url) && !isGoogleStorageSigned$1(url)) { - if (isGoogleStorageURL$2(url)) { - url = translateGoogleCloudURL$1(url); - } - url = addApiKey$1(url); - - if (isGoogleDriveURL$2(url)) { - addTeamDrive$1(url); - } - - // If we have an access token try it, but don't force a signIn or request for scopes yet - if (!oauthToken) { - oauthToken = getCurrentGoogleAccessToken$1(); - } - } - - const headers = options.headers || {}; - if (oauthToken) { - addOauthHeaders$1(headers, oauthToken); - } - const range = options.range; - - - const xhr = new XMLHttpRequest(); - const sendData = options.sendData || options.body; - const method = options.method || (sendData ? "POST" : "GET"); - const responseType = options.responseType; - const contentType = options.contentType; - const mimeType = options.mimeType; - - xhr.open(method, url); - - if (options.timeout) { - xhr.timeout = options.timeout; - } - - if (range) { - let rangeEnd = ""; - if (range.size) { - rangeEnd = range.start + range.size - 1; - if (contentLength > 0) { - rangeEnd = Math.min(rangeEnd, contentLength - 1); - } - } - xhr.setRequestHeader("Range", "bytes=" + range.start + "-" + rangeEnd); - // xhr.setRequestHeader("Cache-Control", "no-cache"); <= This can cause CORS issues, disabled for now - } - if (contentType) { - xhr.setRequestHeader("Content-Type", contentType); - } - if (mimeType) { - xhr.overrideMimeType(mimeType); - } - if (responseType) { - xhr.responseType = responseType; - } - if (headers) { - for (let key of Object.keys(headers)) { - const value = headers[key]; - xhr.setRequestHeader(key, value); - } - } - - // NOTE: using withCredentials with servers that return "*" for access-allowed-origin will fail - if (options.withCredentials === true) { - xhr.withCredentials = true; - } - - xhr.onload = async function (event) { - - if (options.GET_CONTENT_LENGTH) { - resolve(xhr.getResponseHeader('content-length')); - } - - // when the url points to a local file, the status is 0 but that is not an error - if (xhr.status === 0 || (xhr.status >= 200 && xhr.status <= 300)) { - if (range && xhr.status !== 206 && range.start !== 0) { - // For small files a range starting at 0 can return the whole file => 200 - // Provide just the slice we asked for, throw out the rest quietly - // If file is large warn user - if (xhr.response.length > 100000 && !self.RANGE_WARNING_GIVEN) { - alert(`Warning: Range header ignored for URL: ${url}. This can have severe performance impacts.`); - } - resolve(xhr.response.slice(range.start, range.start + range.size)); - - } else { - resolve(xhr.response); - } - } else if ((typeof gapi !== "undefined") && - ((xhr.status === 404 || xhr.status === 401 || xhr.status === 403) && - isGoogleURL$2(url)) && - !options.retries) { - tryGoogleAuth(); - - } else { - if (xhr.status === 403) { - handleError("Access forbidden: " + url); - } else if (xhr.status === 416) { - // Tried to read off the end of the file. This shouldn't happen, but if it does return an - handleError("Unsatisfiable range"); - } else { - handleError(xhr.status); - } - } - }; - - - xhr.onerror = function (event) { - if (isGoogleURL$2(url) && !options.retries) { - tryGoogleAuth(); - } else { - handleError("Error accessing resource: " + url + " Status: " + xhr.status); - } - }; - - xhr.ontimeout = function (event) { - handleError("Timed out"); - }; - - xhr.onabort = function (event) { - console.log("Aborted"); - reject(event); - }; - - try { - xhr.send(sendData); - } catch (e) { - if (isGoogleURL$2(url) && !options.retries) { - tryGoogleAuth(); - } else { - handleError(e); - } - } - - - function handleError(error) { - if (reject) { - reject(error); - } else { - throw error - } - } - - async function tryGoogleAuth() { - try { - const accessToken = await fetchGoogleAccessToken$1(url); - options.retries = 1; - options.oauthToken = accessToken; - const response = await self.load(url, options); - resolve(response); - } catch (e) { - if (e.error) { - const msg = e.error.startsWith("popup_blocked") ? - "Google login popup blocked by browser." : - e.error; - alert(msg); - } else { - handleError(e); - } - } - } - }) - - } - - async _loadFileSlice(localfile, options) { - - let blob = (options && options.range) ? - localfile.slice(options.range.start, options.range.start + options.range.size) : - localfile; - - const arrayBuffer = await blob.arrayBuffer(); - - if ("arraybuffer" === options.responseType) { - return arrayBuffer - } else { - return arrayBufferToString$1(arrayBuffer) - } - } - - async _loadStringFromFile(localfile, options) { - - const blob = options.range ? localfile.slice(options.range.start, options.range.start + options.range.size) : localfile; - const arrayBuffer = await blob.arrayBuffer(); - return arrayBufferToString$1(arrayBuffer) - } - - async _loadStringFromUrl(url, options) { - - options = options || {}; - options.responseType = "arraybuffer"; - const data = await this.load(url, options); - return arrayBufferToString$1(data) - } - - /** - * Explicity set an oAuth token for use with given host. If host is undefined token is used for google api access* - * @param token - * @param host - */ - setOauthToken(token, host) { - this.oauth.setToken(token, host); - } - - /** - * Return an oauth token for the URL if we have one. This method does not force sign-in, and the token may - * or may not be valid. Sign-in is triggered on request failure. - * * - * @param url - * @returns {*} - */ - getOauthToken(url) { - - // Google is the default provider, don't try to parse host for google URLs - const host = isGoogleURL$2(url) ? - undefined : - parseUri$1(url).host; - - // First check the explicit settings (i.e. token set through the API) - let token = this.oauth.getToken(host); - if (token) { - return token - } else if (host === undefined) { - // Now try Google oauth tokens previously obtained. This will return undefined if google oauth is not - // configured. - const googleToken = getCurrentGoogleAccessToken$1(); - if (googleToken && googleToken.expires_at > Date.now()) { - return googleToken.access_token - } - } - } - } - - function isGoogleStorageSigned$1(url) { - return url.indexOf("X-Goog-Signature") > -1 - } - - - /** - * Return a Google oAuth token, triggering a sign in if required. This method should not be called until we know - * a token is required, that is until we've tried the url and received a 401, 403, or 404. - * - * @param url - * @returns the oauth token - */ - async function fetchGoogleAccessToken$1(url) { - if (isInitialized$1()) { - const scope = getScopeForURL$1(url); - const access_token = await getAccessToken$1(scope); - return access_token - } else { - throw Error( - `Authorization is required, but Google oAuth has not been initalized. Contact your site administrator for assistance.`) - } - } - - /** - * Return the current google access token, if one exists. Do not triger signOn or request additional scopes. - * @returns {undefined|access_token} - */ - function getCurrentGoogleAccessToken$1() { - if (isInitialized$1()) { - const access_token = getCurrentAccessToken$1(); - return access_token - } else { - return undefined - } - } - - function addOauthHeaders$1(headers, acToken) { - if (acToken) { - headers["Cache-Control"] = "no-cache"; - headers["Authorization"] = "Bearer " + acToken; - } - return headers - } - - - function addApiKey$1(url) { - let apiKey = igvxhr$1.apiKey; - if (!apiKey && typeof gapi !== "undefined") { - apiKey = gapi.apiKey; - } - if (apiKey !== undefined && !url.includes("key=")) { - const paramSeparator = url.includes("?") ? "&" : "?"; - url = url + paramSeparator + "key=" + apiKey; - } - return url - } - - function addTeamDrive$1(url) { - if (url.includes("supportsTeamDrive")) { - return url - } else { - const paramSeparator = url.includes("?") ? "&" : "?"; - url = url + paramSeparator + "supportsTeamDrive=true"; - } - } - - /** - * Perform some well-known url mappings. - * @param url - */ - function mapUrl$3(url) { - - if (url.startsWith("https://www.dropbox.com")) { - return url.replace("//www.dropbox.com", "//dl.dropboxusercontent.com") - } else if (url.startsWith("https://drive.google.com")) { - return getDriveDownloadURL$2(url) - } else if (url.includes("//www.broadinstitute.org/igvdata")) { - return url.replace("//www.broadinstitute.org/igvdata", "//data.broadinstitute.org/igvdata") - } else if (url.includes("//igvdata.broadinstitute.org")) { - return url.replace("//igvdata.broadinstitute.org", "//s3.amazonaws.com/igv.broadinstitute.org") - } else if (url.includes("//igv.genepattern.org")) { - return url.replace("//igv.genepattern.org", "//igv-genepattern-org.s3.amazonaws.com") - } else if (url.startsWith("ftp://ftp.ncbi.nlm.nih.gov/geo")) { - return url.replace("ftp://", "https://") - } else { - return url - } - } - - - function arrayBufferToString$1(arraybuffer) { - - let plain; - if (isgzipped$1(arraybuffer)) { - plain = ungzip_blocks$1(arraybuffer); - } else { - plain = new Uint8Array(arraybuffer); - } - - if ('TextDecoder' in getGlobalObject$1()) { - return new TextDecoder().decode(plain) - } else { - return decodeUTF8$1(plain) - } - } - - /** - * Use when TextDecoder is not available (primarily IE). - * - * From: https://gist.github.com/Yaffle/5458286 - * - * @param octets - * @returns {string} - */ - function decodeUTF8$1(octets) { - var string = ""; - var i = 0; - while (i < octets.length) { - var octet = octets[i]; - var bytesNeeded = 0; - var codePoint = 0; - if (octet <= 0x7F) { - bytesNeeded = 0; - codePoint = octet & 0xFF; - } else if (octet <= 0xDF) { - bytesNeeded = 1; - codePoint = octet & 0x1F; - } else if (octet <= 0xEF) { - bytesNeeded = 2; - codePoint = octet & 0x0F; - } else if (octet <= 0xF4) { - bytesNeeded = 3; - codePoint = octet & 0x07; - } - if (octets.length - i - bytesNeeded > 0) { - var k = 0; - while (k < bytesNeeded) { - octet = octets[i + k + 1]; - codePoint = (codePoint << 6) | (octet & 0x3F); - k += 1; - } - } else { - codePoint = 0xFFFD; - bytesNeeded = octets.length - i; - } - string += String.fromCodePoint(codePoint); - i += bytesNeeded + 1; - } - return string - } - - - function getGlobalObject$1() { - if (typeof self !== 'undefined') { - return self - } - if (typeof global !== 'undefined') { - return global - } else { - return window - } - } - - function isAmazonV4Signed(url) { - return url.indexOf("X-Amz-Signature") > -1 - } - - - const igvxhr$1 = new IGVXhr$1(); - - /* - * The MIT License (MIT) - * - * Copyright (c) 2014 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - /** An implementation of an interval tree, following the explanation. - * from CLR. - * - * Public interface: - * Constructor IntervalTree - * Insertion insert - * Search findOverlapping - */ - - var BLACK$1 = 1; - - var NIL$1 = {}; - NIL$1.color = BLACK$1; - NIL$1.parent = NIL$1; - NIL$1.left = NIL$1; - NIL$1.right = NIL$1; - - /*! - * jQuery JavaScript Library v3.3.1 -ajax,-ajax/jsonp,-ajax/load,-ajax/parseXML,-ajax/script,-ajax/var/location,-ajax/var/nonce,-ajax/var/rquery,-ajax/xhr,-manipulation/_evalUrl,-event/ajax,-effects,-effects/Tween,-effects/animatedSelector - * https://jquery.com/ - * - * Includes Sizzle.js - * https://sizzlejs.com/ - * - * Copyright JS Foundation and other contributors - * Released under the MIT license - * https://jquery.org/license - * - * Date: 2018-01-20T17:24Z - */ - - var arr = []; - - var document$1 = window.document; - - var getProto = Object.getPrototypeOf; - - var slice = arr.slice; - - var concat = arr.concat; - - var push = arr.push; - - var indexOf = arr.indexOf; - - var class2type = {}; - - var toString$3 = class2type.toString; - - var hasOwn = class2type.hasOwnProperty; - - var fnToString = hasOwn.toString; - - var ObjectFunctionString = fnToString.call(Object); - - var support = {}; - - var isFunction = function isFunction(obj) { - - // Support: Chrome <=57, Firefox <=52 - // In some browsers, typeof returns "function" for HTML elements - // (i.e., `typeof document.createElement( "object" ) === "function"`). - // We don't want to classify *any* DOM node as a function. - return typeof obj === "function" && typeof obj.nodeType !== "number"; - }; - - - var isWindow = function isWindow(obj) { - return obj != null && obj === obj.window; - }; - - - var preservedScriptAttributes = { - type: true, - src: true, - noModule: true - }; - - function DOMEval(code, doc, node) { - doc = doc || document$1; - - var i, - script = doc.createElement("script"); - - script.text = code; - if (node) { - for (i in preservedScriptAttributes) { - if (node[i]) { - script[i] = node[i]; - } - } - } - doc.head.appendChild(script).parentNode.removeChild(script); - } - - - function toType(obj) { - if (obj == null) { - return obj + ""; - } - - // Support: Android <=2.3 only (functionish RegExp) - return typeof obj === "object" || typeof obj === "function" ? - class2type[toString$3.call(obj)] || "object" : - typeof obj; - } - - // global Symbol - // Defining this global in .eslintrc.json would create a danger of using the global - // unguarded in another place, it seems safer to define global only for this module - - - var - version$1 = "3.3.1 -ajax,-ajax/jsonp,-ajax/load,-ajax/parseXML,-ajax/script,-ajax/var/location,-ajax/var/nonce,-ajax/var/rquery,-ajax/xhr,-manipulation/_evalUrl,-event/ajax,-effects,-effects/Tween,-effects/animatedSelector", - - // Define a local copy of jQuery - jQuery = function (selector, context) { - - // The jQuery object is actually just the init constructor 'enhanced' - // Need init if jQuery is called (just allow error to be thrown if not included) - return new jQuery.fn.init(selector, context); - }, - - // Support: Android <=4.0 only - // Make sure we trim BOM and NBSP - rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g; - - jQuery.fn = jQuery.prototype = { - - // The current version of jQuery being used - jquery: version$1, - - constructor: jQuery, - - // The default length of a jQuery object is 0 - length: 0, - - toArray: function () { - return slice.call(this); - }, - - // Get the Nth element in the matched element set OR - // Get the whole matched element set as a clean array - get: function (num) { - - // Return all the elements in a clean array - if (num == null) { - return slice.call(this); - } - - // Return just the one element from the set - return num < 0 ? this[num + this.length] : this[num]; - }, - - // Take an array of elements and push it onto the stack - // (returning the new matched element set) - pushStack: function (elems) { - - // Build a new jQuery matched element set - var ret = jQuery.merge(this.constructor(), elems); - - // Add the old object onto the stack (as a reference) - ret.prevObject = this; - - // Return the newly-formed element set - return ret; - }, - - // Execute a callback for every element in the matched set. - each: function (callback) { - return jQuery.each(this, callback); - }, - - map: function (callback) { - return this.pushStack(jQuery.map(this, function (elem, i) { - return callback.call(elem, i, elem); - })); - }, - - slice: function () { - return this.pushStack(slice.apply(this, arguments)); - }, - - first: function () { - return this.eq(0); - }, - - last: function () { - return this.eq(-1); - }, - - eq: function (i) { - var len = this.length, - j = +i + (i < 0 ? len : 0); - return this.pushStack(j >= 0 && j < len ? [this[j]] : []); - }, - - end: function () { - return this.prevObject || this.constructor(); - }, - - // For internal use only. - // Behaves like an Array's method, not like a jQuery method. - push: push, - sort: arr.sort, - splice: arr.splice - }; - - jQuery.extend = jQuery.fn.extend = function () { - var options, name, src, copy, copyIsArray, clone, - target = arguments[0] || {}, - i = 1, - length = arguments.length, - deep = false; - - // Handle a deep copy situation - if (typeof target === "boolean") { - deep = target; - - // Skip the boolean and the target - target = arguments[i] || {}; - i++; - } - - // Handle case when target is a string or something (possible in deep copy) - if (typeof target !== "object" && !isFunction(target)) { - target = {}; - } - - // Extend jQuery itself if only one argument is passed - if (i === length) { - target = this; - i--; - } - - for (; i < length; i++) { - - // Only deal with non-null/undefined values - if ((options = arguments[i]) != null) { - - // Extend the base object - for (name in options) { - src = target[name]; - copy = options[name]; - - // Prevent never-ending loop - if (target === copy) { - continue; - } - - // Recurse if we're merging plain objects or arrays - if (deep && copy && (jQuery.isPlainObject(copy) || - (copyIsArray = Array.isArray(copy)))) { - - if (copyIsArray) { - copyIsArray = false; - clone = src && Array.isArray(src) ? src : []; - - } else { - clone = src && jQuery.isPlainObject(src) ? src : {}; - } - - // Never move original objects, clone them - target[name] = jQuery.extend(deep, clone, copy); - - // Don't bring in undefined values - } else if (copy !== undefined) { - target[name] = copy; - } - } - } - } - - // Return the modified object - return target; - }; - - jQuery.extend({ - - // Unique for each copy of jQuery on the page - expando: "jQuery" + (version$1 + Math.random()).replace(/\D/g, ""), - - // Assume jQuery is ready without the ready module - isReady: true, - - error: function (msg) { - throw new Error(msg); - }, - - noop: function () { - }, - - isPlainObject: function (obj) { - var proto, Ctor; - - // Detect obvious negatives - // Use toString instead of jQuery.type to catch host objects - if (!obj || toString$3.call(obj) !== "[object Object]") { - return false; - } - - proto = getProto(obj); - - // Objects with no prototype (e.g., `Object.create( null )`) are plain - if (!proto) { - return true; - } - - // Objects with prototype are plain iff they were constructed by a global Object function - Ctor = hasOwn.call(proto, "constructor") && proto.constructor; - return typeof Ctor === "function" && fnToString.call(Ctor) === ObjectFunctionString; - }, - - isEmptyObject: function (obj) { - - /* eslint-disable no-unused-vars */ - // See https://github.com/eslint/eslint/issues/6125 - var name; - - for (name in obj) { - return false; - } - return true; - }, - - // Evaluates a script in a global context - globalEval: function (code) { - DOMEval(code); - }, - - each: function (obj, callback) { - var length, i = 0; - - if (isArrayLike(obj)) { - length = obj.length; - for (; i < length; i++) { - if (callback.call(obj[i], i, obj[i]) === false) { - break; - } - } - } else { - for (i in obj) { - if (callback.call(obj[i], i, obj[i]) === false) { - break; - } - } - } - - return obj; - }, - - // Support: Android <=4.0 only - trim: function (text) { - return text == null ? - "" : - (text + "").replace(rtrim, ""); - }, - - // results is for internal usage only - makeArray: function (arr, results) { - var ret = results || []; - - if (arr != null) { - if (isArrayLike(Object(arr))) { - jQuery.merge(ret, - typeof arr === "string" ? - [arr] : arr - ); - } else { - push.call(ret, arr); - } - } - - return ret; - }, - - inArray: function (elem, arr, i) { - return arr == null ? -1 : indexOf.call(arr, elem, i); - }, - - // Support: Android <=4.0 only, PhantomJS 1 only - // push.apply(_, arraylike) throws on ancient WebKit - merge: function (first, second) { - var len = +second.length, - j = 0, - i = first.length; - - for (; j < len; j++) { - first[i++] = second[j]; - } - - first.length = i; - - return first; - }, - - grep: function (elems, callback, invert) { - var callbackInverse, - matches = [], - i = 0, - length = elems.length, - callbackExpect = !invert; - - // Go through the array, only saving the items - // that pass the validator function - for (; i < length; i++) { - callbackInverse = !callback(elems[i], i); - if (callbackInverse !== callbackExpect) { - matches.push(elems[i]); - } - } - - return matches; - }, - - // arg is for internal usage only - map: function (elems, callback, arg) { - var length, value, - i = 0, - ret = []; - - // Go through the array, translating each of the items to their new values - if (isArrayLike(elems)) { - length = elems.length; - for (; i < length; i++) { - value = callback(elems[i], i, arg); - - if (value != null) { - ret.push(value); - } - } - - // Go through every key on the object, - } else { - for (i in elems) { - value = callback(elems[i], i, arg); - - if (value != null) { - ret.push(value); - } - } - } - - // Flatten any nested arrays - return concat.apply([], ret); - }, - - // A global GUID counter for objects - guid: 1, - - // jQuery.support is not used in Core but other projects attach their - // properties to it so it needs to exist. - support: support - }); - - if (typeof Symbol === "function") { - jQuery.fn[Symbol.iterator] = arr[Symbol.iterator]; - } - - // Populate the class2type map - jQuery.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "), - function (i, name) { - class2type["[object " + name + "]"] = name.toLowerCase(); - }); - - function isArrayLike(obj) { - - // Support: real iOS 8.2 only (not reproducible in simulator) - // `in` check used to prevent JIT error (gh-2145) - // hasOwn isn't used here due to false negatives - // regarding Nodelist length in IE - var length = !!obj && "length" in obj && obj.length, - type = toType(obj); - - if (isFunction(obj) || isWindow(obj)) { - return false; - } - - return type === "array" || length === 0 || - typeof length === "number" && length > 0 && (length - 1) in obj; - } - - var Sizzle = - /*! - * Sizzle CSS Selector Engine v2.3.3 - * https://sizzlejs.com/ - * - * Copyright jQuery Foundation and other contributors - * Released under the MIT license - * http://jquery.org/license - * - * Date: 2016-08-08 - */ - (function (window) { - - var i, - support, - Expr, - getText, - isXML, - tokenize, - compile, - select, - outermostContext, - sortInput, - hasDuplicate, - - // Local document vars - setDocument, - document, - docElem, - documentIsHTML, - rbuggyQSA, - rbuggyMatches, - matches, - contains, - - // Instance-specific data - expando = "sizzle" + 1 * new Date(), - preferredDoc = window.document, - dirruns = 0, - done = 0, - classCache = createCache(), - tokenCache = createCache(), - compilerCache = createCache(), - sortOrder = function (a, b) { - if (a === b) { - hasDuplicate = true; - } - return 0; - }, - - // Instance methods - hasOwn = ({}).hasOwnProperty, - arr = [], - pop = arr.pop, - push_native = arr.push, - push = arr.push, - slice = arr.slice, - // Use a stripped-down indexOf as it's faster than native - // https://jsperf.com/thor-indexof-vs-for/5 - indexOf = function (list, elem) { - var i = 0, - len = list.length; - for (; i < len; i++) { - if (list[i] === elem) { - return i; - } - } - return -1; - }, - - booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped", - - // Regular expressions - - // http://www.w3.org/TR/css3-selectors/#whitespace - whitespace = "[\\x20\\t\\r\\n\\f]", - - // http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier - identifier = "(?:\\\\.|[\\w-]|[^\0-\\xa0])+", - - // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors - attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace + - // Operator (capture 2) - "*([*^$|!~]?=)" + whitespace + - // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]" - "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace + - "*\\]", - - pseudos = ":(" + identifier + ")(?:\\((" + - // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments: - // 1. quoted (capture 3; capture 4 or capture 5) - "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + - // 2. simple (capture 6) - "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" + - // 3. anything else (capture 2) - ".*" + - ")\\)|)", - - // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter - rwhitespace = new RegExp(whitespace + "+", "g"), - rtrim = new RegExp("^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g"), - - rcomma = new RegExp("^" + whitespace + "*," + whitespace + "*"), - rcombinators = new RegExp("^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*"), - - rattributeQuotes = new RegExp("=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g"), - - rpseudo = new RegExp(pseudos), - ridentifier = new RegExp("^" + identifier + "$"), - - matchExpr = { - "ID": new RegExp("^#(" + identifier + ")"), - "CLASS": new RegExp("^\\.(" + identifier + ")"), - "TAG": new RegExp("^(" + identifier + "|[*])"), - "ATTR": new RegExp("^" + attributes), - "PSEUDO": new RegExp("^" + pseudos), - "CHILD": new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace + - "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace + - "*(\\d+)|))" + whitespace + "*\\)|)", "i"), - "bool": new RegExp("^(?:" + booleans + ")$", "i"), - // For use in libraries implementing .is() - // We use this for POS matching in `select` - "needsContext": new RegExp("^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + - whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i") - }, - - rinputs = /^(?:input|select|textarea|button)$/i, - rheader = /^h\d$/i, - - rnative = /^[^{]+\{\s*\[native \w/, - - // Easily-parseable/retrievable ID or TAG or CLASS selectors - rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, - - rsibling = /[+~]/, - - // CSS escapes - // http://www.w3.org/TR/CSS21/syndata.html#escaped-characters - runescape = new RegExp("\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig"), - funescape = function (_, escaped, escapedWhitespace) { - var high = "0x" + escaped - 0x10000; - // NaN means non-codepoint - // Support: Firefox<24 - // Workaround erroneous numeric interpretation of +"0x" - return high !== high || escapedWhitespace ? - escaped : - high < 0 ? - // BMP codepoint - String.fromCharCode(high + 0x10000) : - // Supplemental Plane codepoint (surrogate pair) - String.fromCharCode(high >> 10 | 0xD800, high & 0x3FF | 0xDC00); - }, - - // CSS string/identifier serialization - // https://drafts.csswg.org/cssom/#common-serializing-idioms - // eslint-disable-next-line no-control-regex - rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g, - fcssescape = function (ch, asCodePoint) { - if (asCodePoint) { - - // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER - if (ch === "\0") { - return "\uFFFD"; - } - - // Control characters and (dependent upon position) numbers get escaped as code points - return ch.slice(0, -1) + "\\" + ch.charCodeAt(ch.length - 1).toString(16) + " "; - } - - // Other potentially-special ASCII characters get backslash-escaped - return "\\" + ch; - }, - - // Used for iframes - // See setDocument() - // Removing the function wrapper causes a "Permission Denied" - // error in IE - unloadHandler = function () { - setDocument(); - }, - - disabledAncestor = addCombinator( - function (elem) { - return elem.disabled === true && ("form" in elem || "label" in elem); - }, - {dir: "parentNode", next: "legend"} - ); - - // Optimize for push.apply( _, NodeList ) - try { - push.apply( - (arr = slice.call(preferredDoc.childNodes)), - preferredDoc.childNodes - ); - // Support: Android<4.0 - // Detect silently failing push.apply - arr[preferredDoc.childNodes.length].nodeType; - } catch (e) { - push = { - apply: arr.length ? - - // Leverage slice if possible - function (target, els) { - push_native.apply(target, slice.call(els)); - } : - - // Support: IE<9 - // Otherwise append directly - function (target, els) { - var j = target.length, - i = 0; - // Can't trust NodeList.length - while ((target[j++] = els[i++])) { - } - target.length = j - 1; - } - }; - } - - function Sizzle(selector, context, results, seed) { - var m, i, elem, nid, match, groups, newSelector, - newContext = context && context.ownerDocument, - - // nodeType defaults to 9, since context defaults to document - nodeType = context ? context.nodeType : 9; - - results = results || []; - - // Return early from calls with invalid selector or context - if (typeof selector !== "string" || !selector || - nodeType !== 1 && nodeType !== 9 && nodeType !== 11) { - - return results; - } - - // Try to shortcut find operations (as opposed to filters) in HTML documents - if (!seed) { - - if ((context ? context.ownerDocument || context : preferredDoc) !== document) { - setDocument(context); - } - context = context || document; - - if (documentIsHTML) { - - // If the selector is sufficiently simple, try using a "get*By*" DOM method - // (excepting DocumentFragment context, where the methods don't exist) - if (nodeType !== 11 && (match = rquickExpr.exec(selector))) { - - // ID selector - if ((m = match[1])) { - - // Document context - if (nodeType === 9) { - if ((elem = context.getElementById(m))) { - - // Support: IE, Opera, Webkit - // TODO: identify versions - // getElementById can match elements by name instead of ID - if (elem.id === m) { - results.push(elem); - return results; - } - } else { - return results; - } - - // Element context - } else { - - // Support: IE, Opera, Webkit - // TODO: identify versions - // getElementById can match elements by name instead of ID - if (newContext && (elem = newContext.getElementById(m)) && - contains(context, elem) && - elem.id === m) { - - results.push(elem); - return results; - } - } - - // Type selector - } else if (match[2]) { - push.apply(results, context.getElementsByTagName(selector)); - return results; - - // Class selector - } else if ((m = match[3]) && support.getElementsByClassName && - context.getElementsByClassName) { - - push.apply(results, context.getElementsByClassName(m)); - return results; - } - } - - // Take advantage of querySelectorAll - if (support.qsa && - !compilerCache[selector + " "] && - (!rbuggyQSA || !rbuggyQSA.test(selector))) { - - if (nodeType !== 1) { - newContext = context; - newSelector = selector; - - // qSA looks outside Element context, which is not what we want - // Thanks to Andrew Dupont for this workaround technique - // Support: IE <=8 - // Exclude object elements - } else if (context.nodeName.toLowerCase() !== "object") { - - // Capture the context ID, setting it first if necessary - if ((nid = context.getAttribute("id"))) { - nid = nid.replace(rcssescape, fcssescape); - } else { - context.setAttribute("id", (nid = expando)); - } - - // Prefix every selector in the list - groups = tokenize(selector); - i = groups.length; - while (i--) { - groups[i] = "#" + nid + " " + toSelector(groups[i]); - } - newSelector = groups.join(","); - - // Expand context for sibling selectors - newContext = rsibling.test(selector) && testContext(context.parentNode) || - context; - } - - if (newSelector) { - try { - push.apply(results, - newContext.querySelectorAll(newSelector) - ); - return results; - } catch (qsaError) { - } finally { - if (nid === expando) { - context.removeAttribute("id"); - } - } - } - } - } - } - - // All others - return select(selector.replace(rtrim, "$1"), context, results, seed); - } - - /** - * Create key-value caches of limited size - * @returns {function(string, object)} Returns the Object data after storing it on itself with - * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) - * deleting the oldest entry - */ - function createCache() { - var keys = []; - - function cache(key, value) { - // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) - if (keys.push(key + " ") > Expr.cacheLength) { - // Only keep the most recent entries - delete cache[keys.shift()]; - } - return (cache[key + " "] = value); - } - - return cache; - } - - /** - * Mark a function for special use by Sizzle - * @param {Function} fn The function to mark - */ - function markFunction(fn) { - fn[expando] = true; - return fn; - } - - /** - * Support testing using an element - * @param {Function} fn Passed the created element and returns a boolean result - */ - function assert(fn) { - var el = document.createElement("fieldset"); - - try { - return !!fn(el); - } catch (e) { - return false; - } finally { - // Remove from its parent by default - if (el.parentNode) { - el.parentNode.removeChild(el); - } - // release memory in IE - el = null; - } - } - - /** - * Checks document order of two siblings - * @param {Element} a - * @param {Element} b - * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b - */ - function siblingCheck(a, b) { - var cur = b && a, - diff = cur && a.nodeType === 1 && b.nodeType === 1 && - a.sourceIndex - b.sourceIndex; - - // Use IE sourceIndex if available on both nodes - if (diff) { - return diff; - } - - // Check if b follows a - if (cur) { - while ((cur = cur.nextSibling)) { - if (cur === b) { - return -1; - } - } - } - - return a ? 1 : -1; - } - - /** - * Returns a function to use in pseudos for input types - * @param {String} type - */ - function createInputPseudo(type) { - return function (elem) { - var name = elem.nodeName.toLowerCase(); - return name === "input" && elem.type === type; - }; - } - - /** - * Returns a function to use in pseudos for buttons - * @param {String} type - */ - function createButtonPseudo(type) { - return function (elem) { - var name = elem.nodeName.toLowerCase(); - return (name === "input" || name === "button") && elem.type === type; - }; - } - - /** - * Returns a function to use in pseudos for :enabled/:disabled - * @param {Boolean} disabled true for :disabled; false for :enabled - */ - function createDisabledPseudo(disabled) { - - // Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable - return function (elem) { - - // Only certain elements can match :enabled or :disabled - // https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled - // https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled - if ("form" in elem) { - - // Check for inherited disabledness on relevant non-disabled elements: - // * listed form-associated elements in a disabled fieldset - // https://html.spec.whatwg.org/multipage/forms.html#category-listed - // https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled - // * option elements in a disabled optgroup - // https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled - // All such elements have a "form" property. - if (elem.parentNode && elem.disabled === false) { - - // Option elements defer to a parent optgroup if present - if ("label" in elem) { - if ("label" in elem.parentNode) { - return elem.parentNode.disabled === disabled; - } else { - return elem.disabled === disabled; - } - } - - // Support: IE 6 - 11 - // Use the isDisabled shortcut property to check for disabled fieldset ancestors - return elem.isDisabled === disabled || - - // Where there is no isDisabled, check manually - /* jshint -W018 */ - elem.isDisabled !== !disabled && - disabledAncestor(elem) === disabled; - } - - return elem.disabled === disabled; - - // Try to winnow out elements that can't be disabled before trusting the disabled property. - // Some victims get caught in our net (label, legend, menu, track), but it shouldn't - // even exist on them, let alone have a boolean value. - } else if ("label" in elem) { - return elem.disabled === disabled; - } - - // Remaining elements are neither :enabled nor :disabled - return false; - }; - } - - /** - * Returns a function to use in pseudos for positionals - * @param {Function} fn - */ - function createPositionalPseudo(fn) { - return markFunction(function (argument) { - argument = +argument; - return markFunction(function (seed, matches) { - var j, - matchIndexes = fn([], seed.length, argument), - i = matchIndexes.length; - - // Match elements found at the specified indexes - while (i--) { - if (seed[(j = matchIndexes[i])]) { - seed[j] = !(matches[j] = seed[j]); - } - } - }); - }); - } - - /** - * Checks a node for validity as a Sizzle context - * @param {Element|Object=} context - * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value - */ - function testContext(context) { - return context && typeof context.getElementsByTagName !== "undefined" && context; - } - - // Expose support vars for convenience - support = Sizzle.support = {}; - - /** - * Detects XML nodes - * @param {Element|Object} elem An element or a document - * @returns {Boolean} True iff elem is a non-HTML XML node - */ - isXML = Sizzle.isXML = function (elem) { - // documentElement is verified for cases where it doesn't yet exist - // (such as loading iframes in IE - #4833) - var documentElement = elem && (elem.ownerDocument || elem).documentElement; - return documentElement ? documentElement.nodeName !== "HTML" : false; - }; - - /** - * Sets document-related variables once based on the current document - * @param {Element|Object} [doc] An element or document object to use to set the document - * @returns {Object} Returns the current document - */ - setDocument = Sizzle.setDocument = function (node) { - var hasCompare, subWindow, - doc = node ? node.ownerDocument || node : preferredDoc; - - // Return early if doc is invalid or already selected - if (doc === document || doc.nodeType !== 9 || !doc.documentElement) { - return document; - } - - // Update global variables - document = doc; - docElem = document.documentElement; - documentIsHTML = !isXML(document); - - // Support: IE 9-11, Edge - // Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936) - if (preferredDoc !== document && - (subWindow = document.defaultView) && subWindow.top !== subWindow) { - - // Support: IE 11, Edge - if (subWindow.addEventListener) { - subWindow.addEventListener("unload", unloadHandler, false); - - // Support: IE 9 - 10 only - } else if (subWindow.attachEvent) { - subWindow.attachEvent("onunload", unloadHandler); - } - } - - /* Attributes - ---------------------------------------------------------------------- */ - - // Support: IE<8 - // Verify that getAttribute really returns attributes and not properties - // (excepting IE8 booleans) - support.attributes = assert(function (el) { - el.className = "i"; - return !el.getAttribute("className"); - }); - - /* getElement(s)By* - ---------------------------------------------------------------------- */ - - // Check if getElementsByTagName("*") returns only elements - support.getElementsByTagName = assert(function (el) { - el.appendChild(document.createComment("")); - return !el.getElementsByTagName("*").length; - }); - - // Support: IE<9 - support.getElementsByClassName = rnative.test(document.getElementsByClassName); - - // Support: IE<10 - // Check if getElementById returns elements by name - // The broken getElementById methods don't pick up programmatically-set names, - // so use a roundabout getElementsByName test - support.getById = assert(function (el) { - docElem.appendChild(el).id = expando; - return !document.getElementsByName || !document.getElementsByName(expando).length; - }); - - // ID filter and find - if (support.getById) { - Expr.filter["ID"] = function (id) { - var attrId = id.replace(runescape, funescape); - return function (elem) { - return elem.getAttribute("id") === attrId; - }; - }; - Expr.find["ID"] = function (id, context) { - if (typeof context.getElementById !== "undefined" && documentIsHTML) { - var elem = context.getElementById(id); - return elem ? [elem] : []; - } - }; - } else { - Expr.filter["ID"] = function (id) { - var attrId = id.replace(runescape, funescape); - return function (elem) { - var node = typeof elem.getAttributeNode !== "undefined" && - elem.getAttributeNode("id"); - return node && node.value === attrId; - }; - }; - - // Support: IE 6 - 7 only - // getElementById is not reliable as a find shortcut - Expr.find["ID"] = function (id, context) { - if (typeof context.getElementById !== "undefined" && documentIsHTML) { - var node, i, elems, - elem = context.getElementById(id); - - if (elem) { - - // Verify the id attribute - node = elem.getAttributeNode("id"); - if (node && node.value === id) { - return [elem]; - } - - // Fall back on getElementsByName - elems = context.getElementsByName(id); - i = 0; - while ((elem = elems[i++])) { - node = elem.getAttributeNode("id"); - if (node && node.value === id) { - return [elem]; - } - } - } - - return []; - } - }; - } - - // Tag - Expr.find["TAG"] = support.getElementsByTagName ? - function (tag, context) { - if (typeof context.getElementsByTagName !== "undefined") { - return context.getElementsByTagName(tag); - - // DocumentFragment nodes don't have gEBTN - } else if (support.qsa) { - return context.querySelectorAll(tag); - } - } : - - function (tag, context) { - var elem, - tmp = [], - i = 0, - // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too - results = context.getElementsByTagName(tag); - - // Filter out possible comments - if (tag === "*") { - while ((elem = results[i++])) { - if (elem.nodeType === 1) { - tmp.push(elem); - } - } - - return tmp; - } - return results; - }; - - // Class - Expr.find["CLASS"] = support.getElementsByClassName && function (className, context) { - if (typeof context.getElementsByClassName !== "undefined" && documentIsHTML) { - return context.getElementsByClassName(className); - } - }; - - /* QSA/matchesSelector - ---------------------------------------------------------------------- */ - - // QSA and matchesSelector support - - // matchesSelector(:active) reports false when true (IE9/Opera 11.5) - rbuggyMatches = []; - - // qSa(:focus) reports false when true (Chrome 21) - // We allow this because of a bug in IE8/9 that throws an error - // whenever `document.activeElement` is accessed on an iframe - // So, we allow :focus to pass through QSA all the time to avoid the IE error - // See https://bugs.jquery.com/ticket/13378 - rbuggyQSA = []; - - if ((support.qsa = rnative.test(document.querySelectorAll))) { - // Build QSA regex - // Regex strategy adopted from Diego Perini - assert(function (el) { - // Select is set to empty string on purpose - // This is to test IE's treatment of not explicitly - // setting a boolean content attribute, - // since its presence should be enough - // https://bugs.jquery.com/ticket/12359 - docElem.appendChild(el).innerHTML = "" + - ""; - - // Support: IE8, Opera 11-12.16 - // Nothing should be selected when empty strings follow ^= or $= or *= - // The test attribute must be unknown in Opera but "safe" for WinRT - // https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section - if (el.querySelectorAll("[msallowcapture^='']").length) { - rbuggyQSA.push("[*^$]=" + whitespace + "*(?:''|\"\")"); - } - - // Support: IE8 - // Boolean attributes and "value" are not treated correctly - if (!el.querySelectorAll("[selected]").length) { - rbuggyQSA.push("\\[" + whitespace + "*(?:value|" + booleans + ")"); - } - - // Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+ - if (!el.querySelectorAll("[id~=" + expando + "-]").length) { - rbuggyQSA.push("~="); - } - - // Webkit/Opera - :checked should return selected option elements - // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked - // IE8 throws error here and will not see later tests - if (!el.querySelectorAll(":checked").length) { - rbuggyQSA.push(":checked"); - } - - // Support: Safari 8+, iOS 8+ - // https://bugs.webkit.org/show_bug.cgi?id=136851 - // In-page `selector#id sibling-combinator selector` fails - if (!el.querySelectorAll("a#" + expando + "+*").length) { - rbuggyQSA.push(".#.+[+~]"); - } - }); - - assert(function (el) { - el.innerHTML = "" + - ""; - - // Support: Windows 8 Native Apps - // The type and name attributes are restricted during .innerHTML assignment - var input = document.createElement("input"); - input.setAttribute("type", "hidden"); - el.appendChild(input).setAttribute("name", "D"); - - // Support: IE8 - // Enforce case-sensitivity of name attribute - if (el.querySelectorAll("[name=d]").length) { - rbuggyQSA.push("name" + whitespace + "*[*^$|!~]?="); - } - - // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) - // IE8 throws error here and will not see later tests - if (el.querySelectorAll(":enabled").length !== 2) { - rbuggyQSA.push(":enabled", ":disabled"); - } - - // Support: IE9-11+ - // IE's :disabled selector does not pick up the children of disabled fieldsets - docElem.appendChild(el).disabled = true; - if (el.querySelectorAll(":disabled").length !== 2) { - rbuggyQSA.push(":enabled", ":disabled"); - } - - // Opera 10-11 does not throw on post-comma invalid pseudos - el.querySelectorAll("*,:x"); - rbuggyQSA.push(",.*:"); - }); - } - - if ((support.matchesSelector = rnative.test((matches = docElem.matches || - docElem.webkitMatchesSelector || - docElem.mozMatchesSelector || - docElem.oMatchesSelector || - docElem.msMatchesSelector)))) { - - assert(function (el) { - // Check to see if it's possible to do matchesSelector - // on a disconnected node (IE 9) - support.disconnectedMatch = matches.call(el, "*"); - - // This should fail with an exception - // Gecko does not error, returns false instead - matches.call(el, "[s!='']:x"); - rbuggyMatches.push("!=", pseudos); - }); - } - - rbuggyQSA = rbuggyQSA.length && new RegExp(rbuggyQSA.join("|")); - rbuggyMatches = rbuggyMatches.length && new RegExp(rbuggyMatches.join("|")); - - /* Contains - ---------------------------------------------------------------------- */ - hasCompare = rnative.test(docElem.compareDocumentPosition); - - // Element contains another - // Purposefully self-exclusive - // As in, an element does not contain itself - contains = hasCompare || rnative.test(docElem.contains) ? - function (a, b) { - var adown = a.nodeType === 9 ? a.documentElement : a, - bup = b && b.parentNode; - return a === bup || !!(bup && bup.nodeType === 1 && ( - adown.contains ? - adown.contains(bup) : - a.compareDocumentPosition && a.compareDocumentPosition(bup) & 16 - )); - } : - function (a, b) { - if (b) { - while ((b = b.parentNode)) { - if (b === a) { - return true; - } - } - } - return false; - }; - - /* Sorting - ---------------------------------------------------------------------- */ - - // Document order sorting - sortOrder = hasCompare ? - function (a, b) { - - // Flag for duplicate removal - if (a === b) { - hasDuplicate = true; - return 0; - } - - // Sort on method existence if only one input has compareDocumentPosition - var compare = !a.compareDocumentPosition - !b.compareDocumentPosition; - if (compare) { - return compare; - } - - // Calculate position if both inputs belong to the same document - compare = (a.ownerDocument || a) === (b.ownerDocument || b) ? - a.compareDocumentPosition(b) : - - // Otherwise we know they are disconnected - 1; - - // Disconnected nodes - if (compare & 1 || - (!support.sortDetached && b.compareDocumentPosition(a) === compare)) { - - // Choose the first element that is related to our preferred document - if (a === document || a.ownerDocument === preferredDoc && contains(preferredDoc, a)) { - return -1; - } - if (b === document || b.ownerDocument === preferredDoc && contains(preferredDoc, b)) { - return 1; - } - - // Maintain original order - return sortInput ? - (indexOf(sortInput, a) - indexOf(sortInput, b)) : - 0; - } - - return compare & 4 ? -1 : 1; - } : - function (a, b) { - // Exit early if the nodes are identical - if (a === b) { - hasDuplicate = true; - return 0; - } - - var cur, - i = 0, - aup = a.parentNode, - bup = b.parentNode, - ap = [a], - bp = [b]; - - // Parentless nodes are either documents or disconnected - if (!aup || !bup) { - return a === document ? -1 : - b === document ? 1 : - aup ? -1 : - bup ? 1 : - sortInput ? - (indexOf(sortInput, a) - indexOf(sortInput, b)) : - 0; - - // If the nodes are siblings, we can do a quick check - } else if (aup === bup) { - return siblingCheck(a, b); - } - - // Otherwise we need full lists of their ancestors for comparison - cur = a; - while ((cur = cur.parentNode)) { - ap.unshift(cur); - } - cur = b; - while ((cur = cur.parentNode)) { - bp.unshift(cur); - } - - // Walk down the tree looking for a discrepancy - while (ap[i] === bp[i]) { - i++; - } - - return i ? - // Do a sibling check if the nodes have a common ancestor - siblingCheck(ap[i], bp[i]) : - - // Otherwise nodes in our document sort first - ap[i] === preferredDoc ? -1 : - bp[i] === preferredDoc ? 1 : - 0; - }; - - return document; - }; - - Sizzle.matches = function (expr, elements) { - return Sizzle(expr, null, null, elements); - }; - - Sizzle.matchesSelector = function (elem, expr) { - // Set document vars if needed - if ((elem.ownerDocument || elem) !== document) { - setDocument(elem); - } - - // Make sure that attribute selectors are quoted - expr = expr.replace(rattributeQuotes, "='$1']"); - - if (support.matchesSelector && documentIsHTML && - !compilerCache[expr + " "] && - (!rbuggyMatches || !rbuggyMatches.test(expr)) && - (!rbuggyQSA || !rbuggyQSA.test(expr))) { - - try { - var ret = matches.call(elem, expr); - - // IE 9's matchesSelector returns false on disconnected nodes - if (ret || support.disconnectedMatch || - // As well, disconnected nodes are said to be in a document - // fragment in IE 9 - elem.document && elem.document.nodeType !== 11) { - return ret; - } - } catch (e) { - } - } - - return Sizzle(expr, document, null, [elem]).length > 0; - }; - - Sizzle.contains = function (context, elem) { - // Set document vars if needed - if ((context.ownerDocument || context) !== document) { - setDocument(context); - } - return contains(context, elem); - }; - - Sizzle.attr = function (elem, name) { - // Set document vars if needed - if ((elem.ownerDocument || elem) !== document) { - setDocument(elem); - } - - var fn = Expr.attrHandle[name.toLowerCase()], - // Don't get fooled by Object.prototype properties (jQuery #13807) - val = fn && hasOwn.call(Expr.attrHandle, name.toLowerCase()) ? - fn(elem, name, !documentIsHTML) : - undefined; - - return val !== undefined ? - val : - support.attributes || !documentIsHTML ? - elem.getAttribute(name) : - (val = elem.getAttributeNode(name)) && val.specified ? - val.value : - null; - }; - - Sizzle.escape = function (sel) { - return (sel + "").replace(rcssescape, fcssescape); - }; - - Sizzle.error = function (msg) { - throw new Error("Syntax error, unrecognized expression: " + msg); - }; - - /** - * Document sorting and removing duplicates - * @param {ArrayLike} results - */ - Sizzle.uniqueSort = function (results) { - var elem, - duplicates = [], - j = 0, - i = 0; - - // Unless we *know* we can detect duplicates, assume their presence - hasDuplicate = !support.detectDuplicates; - sortInput = !support.sortStable && results.slice(0); - results.sort(sortOrder); - - if (hasDuplicate) { - while ((elem = results[i++])) { - if (elem === results[i]) { - j = duplicates.push(i); - } - } - while (j--) { - results.splice(duplicates[j], 1); - } - } - - // Clear input after sorting to release objects - // See https://github.com/jquery/sizzle/pull/225 - sortInput = null; - - return results; - }; - - /** - * Utility function for retrieving the text value of an array of DOM nodes - * @param {Array|Element} elem - */ - getText = Sizzle.getText = function (elem) { - var node, - ret = "", - i = 0, - nodeType = elem.nodeType; - - if (!nodeType) { - // If no nodeType, this is expected to be an array - while ((node = elem[i++])) { - // Do not traverse comment nodes - ret += getText(node); - } - } else if (nodeType === 1 || nodeType === 9 || nodeType === 11) { - // Use textContent for elements - // innerText usage removed for consistency of new lines (jQuery #11153) - if (typeof elem.textContent === "string") { - return elem.textContent; - } else { - // Traverse its children - for (elem = elem.firstChild; elem; elem = elem.nextSibling) { - ret += getText(elem); - } - } - } else if (nodeType === 3 || nodeType === 4) { - return elem.nodeValue; - } - // Do not include comment or processing instruction nodes - - return ret; - }; - - Expr = Sizzle.selectors = { - - // Can be adjusted by the user - cacheLength: 50, - - createPseudo: markFunction, - - match: matchExpr, - - attrHandle: {}, - - find: {}, - - relative: { - ">": {dir: "parentNode", first: true}, - " ": {dir: "parentNode"}, - "+": {dir: "previousSibling", first: true}, - "~": {dir: "previousSibling"} - }, - - preFilter: { - "ATTR": function (match) { - match[1] = match[1].replace(runescape, funescape); - - // Move the given value to match[3] whether quoted or unquoted - match[3] = (match[3] || match[4] || match[5] || "").replace(runescape, funescape); - - if (match[2] === "~=") { - match[3] = " " + match[3] + " "; - } - - return match.slice(0, 4); - }, - - "CHILD": function (match) { - /* matches from matchExpr["CHILD"] - 1 type (only|nth|...) - 2 what (child|of-type) - 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) - 4 xn-component of xn+y argument ([+-]?\d*n|) - 5 sign of xn-component - 6 x of xn-component - 7 sign of y-component - 8 y of y-component - */ - match[1] = match[1].toLowerCase(); - - if (match[1].slice(0, 3) === "nth") { - // nth-* requires argument - if (!match[3]) { - Sizzle.error(match[0]); - } - - // numeric x and y parameters for Expr.filter.CHILD - // remember that false/true cast respectively to 0/1 - match[4] = +(match[4] ? match[5] + (match[6] || 1) : 2 * (match[3] === "even" || match[3] === "odd")); - match[5] = +((match[7] + match[8]) || match[3] === "odd"); - - // other types prohibit arguments - } else if (match[3]) { - Sizzle.error(match[0]); - } - - return match; - }, - - "PSEUDO": function (match) { - var excess, - unquoted = !match[6] && match[2]; - - if (matchExpr["CHILD"].test(match[0])) { - return null; - } - - // Accept quoted arguments as-is - if (match[3]) { - match[2] = match[4] || match[5] || ""; - - // Strip excess characters from unquoted arguments - } else if (unquoted && rpseudo.test(unquoted) && - // Get excess from tokenize (recursively) - (excess = tokenize(unquoted, true)) && - // advance to the next closing parenthesis - (excess = unquoted.indexOf(")", unquoted.length - excess) - unquoted.length)) { - - // excess is a negative index - match[0] = match[0].slice(0, excess); - match[2] = unquoted.slice(0, excess); - } - - // Return only captures needed by the pseudo filter method (type and argument) - return match.slice(0, 3); - } - }, - - filter: { - - "TAG": function (nodeNameSelector) { - var nodeName = nodeNameSelector.replace(runescape, funescape).toLowerCase(); - return nodeNameSelector === "*" ? - function () { - return true; - } : - function (elem) { - return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; - }; - }, - - "CLASS": function (className) { - var pattern = classCache[className + " "]; - - return pattern || - (pattern = new RegExp("(^|" + whitespace + ")" + className + "(" + whitespace + "|$)")) && - classCache(className, function (elem) { - return pattern.test(typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || ""); - }); - }, - - "ATTR": function (name, operator, check) { - return function (elem) { - var result = Sizzle.attr(elem, name); - - if (result == null) { - return operator === "!="; - } - if (!operator) { - return true; - } - - result += ""; - - return operator === "=" ? result === check : - operator === "!=" ? result !== check : - operator === "^=" ? check && result.indexOf(check) === 0 : - operator === "*=" ? check && result.indexOf(check) > -1 : - operator === "$=" ? check && result.slice(-check.length) === check : - operator === "~=" ? (" " + result.replace(rwhitespace, " ") + " ").indexOf(check) > -1 : - operator === "|=" ? result === check || result.slice(0, check.length + 1) === check + "-" : - false; - }; - }, - - "CHILD": function (type, what, argument, first, last) { - var simple = type.slice(0, 3) !== "nth", - forward = type.slice(-4) !== "last", - ofType = what === "of-type"; - - return first === 1 && last === 0 ? - - // Shortcut for :nth-*(n) - function (elem) { - return !!elem.parentNode; - } : - - function (elem, context, xml) { - var cache, uniqueCache, outerCache, node, nodeIndex, start, - dir = simple !== forward ? "nextSibling" : "previousSibling", - parent = elem.parentNode, - name = ofType && elem.nodeName.toLowerCase(), - useCache = !xml && !ofType, - diff = false; - - if (parent) { - - // :(first|last|only)-(child|of-type) - if (simple) { - while (dir) { - node = elem; - while ((node = node[dir])) { - if (ofType ? - node.nodeName.toLowerCase() === name : - node.nodeType === 1) { - - return false; - } - } - // Reverse direction for :only-* (if we haven't yet done so) - start = dir = type === "only" && !start && "nextSibling"; - } - return true; - } - - start = [forward ? parent.firstChild : parent.lastChild]; - - // non-xml :nth-child(...) stores cache data on `parent` - if (forward && useCache) { - - // Seek `elem` from a previously-cached index - - // ...in a gzip-friendly way - node = parent; - outerCache = node[expando] || (node[expando] = {}); - - // Support: IE <9 only - // Defend against cloned attroperties (jQuery gh-1709) - uniqueCache = outerCache[node.uniqueID] || - (outerCache[node.uniqueID] = {}); - - cache = uniqueCache[type] || []; - nodeIndex = cache[0] === dirruns && cache[1]; - diff = nodeIndex && cache[2]; - node = nodeIndex && parent.childNodes[nodeIndex]; - - while ((node = ++nodeIndex && node && node[dir] || - - // Fallback to seeking `elem` from the start - (diff = nodeIndex = 0) || start.pop())) { - - // When found, cache indexes on `parent` and break - if (node.nodeType === 1 && ++diff && node === elem) { - uniqueCache[type] = [dirruns, nodeIndex, diff]; - break; - } - } - - } else { - // Use previously-cached element index if available - if (useCache) { - // ...in a gzip-friendly way - node = elem; - outerCache = node[expando] || (node[expando] = {}); - - // Support: IE <9 only - // Defend against cloned attroperties (jQuery gh-1709) - uniqueCache = outerCache[node.uniqueID] || - (outerCache[node.uniqueID] = {}); - - cache = uniqueCache[type] || []; - nodeIndex = cache[0] === dirruns && cache[1]; - diff = nodeIndex; - } - - // xml :nth-child(...) - // or :nth-last-child(...) or :nth(-last)?-of-type(...) - if (diff === false) { - // Use the same loop as above to seek `elem` from the start - while ((node = ++nodeIndex && node && node[dir] || - (diff = nodeIndex = 0) || start.pop())) { - - if ((ofType ? - node.nodeName.toLowerCase() === name : - node.nodeType === 1) && - ++diff) { - - // Cache the index of each encountered element - if (useCache) { - outerCache = node[expando] || (node[expando] = {}); - - // Support: IE <9 only - // Defend against cloned attroperties (jQuery gh-1709) - uniqueCache = outerCache[node.uniqueID] || - (outerCache[node.uniqueID] = {}); - - uniqueCache[type] = [dirruns, diff]; - } - - if (node === elem) { - break; - } - } - } - } - } - - // Incorporate the offset, then check against cycle size - diff -= last; - return diff === first || (diff % first === 0 && diff / first >= 0); - } - }; - }, - - "PSEUDO": function (pseudo, argument) { - // pseudo-class names are case-insensitive - // http://www.w3.org/TR/selectors/#pseudo-classes - // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters - // Remember that setFilters inherits from pseudos - var args, - fn = Expr.pseudos[pseudo] || Expr.setFilters[pseudo.toLowerCase()] || - Sizzle.error("unsupported pseudo: " + pseudo); - - // The user may use createPseudo to indicate that - // arguments are needed to create the filter function - // just as Sizzle does - if (fn[expando]) { - return fn(argument); - } - - // But maintain support for old signatures - if (fn.length > 1) { - args = [pseudo, pseudo, "", argument]; - return Expr.setFilters.hasOwnProperty(pseudo.toLowerCase()) ? - markFunction(function (seed, matches) { - var idx, - matched = fn(seed, argument), - i = matched.length; - while (i--) { - idx = indexOf(seed, matched[i]); - seed[idx] = !(matches[idx] = matched[i]); - } - }) : - function (elem) { - return fn(elem, 0, args); - }; - } - - return fn; - } - }, - - pseudos: { - // Potentially complex pseudos - "not": markFunction(function (selector) { - // Trim the selector passed to compile - // to avoid treating leading and trailing - // spaces as combinators - var input = [], - results = [], - matcher = compile(selector.replace(rtrim, "$1")); - - return matcher[expando] ? - markFunction(function (seed, matches, context, xml) { - var elem, - unmatched = matcher(seed, null, xml, []), - i = seed.length; - - // Match elements unmatched by `matcher` - while (i--) { - if ((elem = unmatched[i])) { - seed[i] = !(matches[i] = elem); - } - } - }) : - function (elem, context, xml) { - input[0] = elem; - matcher(input, null, xml, results); - // Don't keep the element (issue #299) - input[0] = null; - return !results.pop(); - }; - }), - - "has": markFunction(function (selector) { - return function (elem) { - return Sizzle(selector, elem).length > 0; - }; - }), - - "contains": markFunction(function (text) { - text = text.replace(runescape, funescape); - return function (elem) { - return (elem.textContent || elem.innerText || getText(elem)).indexOf(text) > -1; - }; - }), - - // "Whether an element is represented by a :lang() selector - // is based solely on the element's language value - // being equal to the identifier C, - // or beginning with the identifier C immediately followed by "-". - // The matching of C against the element's language value is performed case-insensitively. - // The identifier C does not have to be a valid language name." - // http://www.w3.org/TR/selectors/#lang-pseudo - "lang": markFunction(function (lang) { - // lang value must be a valid identifier - if (!ridentifier.test(lang || "")) { - Sizzle.error("unsupported lang: " + lang); - } - lang = lang.replace(runescape, funescape).toLowerCase(); - return function (elem) { - var elemLang; - do { - if ((elemLang = documentIsHTML ? - elem.lang : - elem.getAttribute("xml:lang") || elem.getAttribute("lang"))) { - - elemLang = elemLang.toLowerCase(); - return elemLang === lang || elemLang.indexOf(lang + "-") === 0; - } - } while ((elem = elem.parentNode) && elem.nodeType === 1); - return false; - }; - }), - - // Miscellaneous - "target": function (elem) { - var hash = window.location && window.location.hash; - return hash && hash.slice(1) === elem.id; - }, - - "root": function (elem) { - return elem === docElem; - }, - - "focus": function (elem) { - return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex); - }, - - // Boolean properties - "enabled": createDisabledPseudo(false), - "disabled": createDisabledPseudo(true), - - "checked": function (elem) { - // In CSS3, :checked should return both checked and selected elements - // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked - var nodeName = elem.nodeName.toLowerCase(); - return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected); - }, - - "selected": function (elem) { - // Accessing this property makes selected-by-default - // options in Safari work properly - if (elem.parentNode) { - elem.parentNode.selectedIndex; - } - - return elem.selected === true; - }, - - // Contents - "empty": function (elem) { - // http://www.w3.org/TR/selectors/#empty-pseudo - // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5), - // but not by others (comment: 8; processing instruction: 7; etc.) - // nodeType < 6 works because attributes (2) do not appear as children - for (elem = elem.firstChild; elem; elem = elem.nextSibling) { - if (elem.nodeType < 6) { - return false; - } - } - return true; - }, - - "parent": function (elem) { - return !Expr.pseudos["empty"](elem); - }, - - // Element/input types - "header": function (elem) { - return rheader.test(elem.nodeName); - }, - - "input": function (elem) { - return rinputs.test(elem.nodeName); - }, - - "button": function (elem) { - var name = elem.nodeName.toLowerCase(); - return name === "input" && elem.type === "button" || name === "button"; - }, - - "text": function (elem) { - var attr; - return elem.nodeName.toLowerCase() === "input" && - elem.type === "text" && - - // Support: IE<8 - // New HTML5 attribute values (e.g., "search") appear with elem.type === "text" - ((attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text"); - }, - - // Position-in-collection - "first": createPositionalPseudo(function () { - return [0]; - }), - - "last": createPositionalPseudo(function (matchIndexes, length) { - return [length - 1]; - }), - - "eq": createPositionalPseudo(function (matchIndexes, length, argument) { - return [argument < 0 ? argument + length : argument]; - }), - - "even": createPositionalPseudo(function (matchIndexes, length) { - var i = 0; - for (; i < length; i += 2) { - matchIndexes.push(i); - } - return matchIndexes; - }), - - "odd": createPositionalPseudo(function (matchIndexes, length) { - var i = 1; - for (; i < length; i += 2) { - matchIndexes.push(i); - } - return matchIndexes; - }), - - "lt": createPositionalPseudo(function (matchIndexes, length, argument) { - var i = argument < 0 ? argument + length : argument; - for (; --i >= 0;) { - matchIndexes.push(i); - } - return matchIndexes; - }), - - "gt": createPositionalPseudo(function (matchIndexes, length, argument) { - var i = argument < 0 ? argument + length : argument; - for (; ++i < length;) { - matchIndexes.push(i); - } - return matchIndexes; - }) - } - }; - - Expr.pseudos["nth"] = Expr.pseudos["eq"]; - - // Add button/input type pseudos - for (i in {radio: true, checkbox: true, file: true, password: true, image: true}) { - Expr.pseudos[i] = createInputPseudo(i); - } - for (i in {submit: true, reset: true}) { - Expr.pseudos[i] = createButtonPseudo(i); - } - - // Easy API for creating new setFilters - function setFilters() { - } - - setFilters.prototype = Expr.filters = Expr.pseudos; - Expr.setFilters = new setFilters(); - - tokenize = Sizzle.tokenize = function (selector, parseOnly) { - var matched, match, tokens, type, - soFar, groups, preFilters, - cached = tokenCache[selector + " "]; - - if (cached) { - return parseOnly ? 0 : cached.slice(0); - } - - soFar = selector; - groups = []; - preFilters = Expr.preFilter; - - while (soFar) { - - // Comma and first run - if (!matched || (match = rcomma.exec(soFar))) { - if (match) { - // Don't consume trailing commas as valid - soFar = soFar.slice(match[0].length) || soFar; - } - groups.push((tokens = [])); - } - - matched = false; - - // Combinators - if ((match = rcombinators.exec(soFar))) { - matched = match.shift(); - tokens.push({ - value: matched, - // Cast descendant combinators to space - type: match[0].replace(rtrim, " ") - }); - soFar = soFar.slice(matched.length); - } - - // Filters - for (type in Expr.filter) { - if ((match = matchExpr[type].exec(soFar)) && (!preFilters[type] || - (match = preFilters[type](match)))) { - matched = match.shift(); - tokens.push({ - value: matched, - type: type, - matches: match - }); - soFar = soFar.slice(matched.length); - } - } - - if (!matched) { - break; - } - } - - // Return the length of the invalid excess - // if we're just parsing - // Otherwise, throw an error or return tokens - return parseOnly ? - soFar.length : - soFar ? - Sizzle.error(selector) : - // Cache the tokens - tokenCache(selector, groups).slice(0); - }; - - function toSelector(tokens) { - var i = 0, - len = tokens.length, - selector = ""; - for (; i < len; i++) { - selector += tokens[i].value; - } - return selector; - } - - function addCombinator(matcher, combinator, base) { - var dir = combinator.dir, - skip = combinator.next, - key = skip || dir, - checkNonElements = base && key === "parentNode", - doneName = done++; - - return combinator.first ? - // Check against closest ancestor/preceding element - function (elem, context, xml) { - while ((elem = elem[dir])) { - if (elem.nodeType === 1 || checkNonElements) { - return matcher(elem, context, xml); - } - } - return false; - } : - - // Check against all ancestor/preceding elements - function (elem, context, xml) { - var oldCache, uniqueCache, outerCache, - newCache = [dirruns, doneName]; - - // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching - if (xml) { - while ((elem = elem[dir])) { - if (elem.nodeType === 1 || checkNonElements) { - if (matcher(elem, context, xml)) { - return true; - } - } - } - } else { - while ((elem = elem[dir])) { - if (elem.nodeType === 1 || checkNonElements) { - outerCache = elem[expando] || (elem[expando] = {}); - - // Support: IE <9 only - // Defend against cloned attroperties (jQuery gh-1709) - uniqueCache = outerCache[elem.uniqueID] || (outerCache[elem.uniqueID] = {}); - - if (skip && skip === elem.nodeName.toLowerCase()) { - elem = elem[dir] || elem; - } else if ((oldCache = uniqueCache[key]) && - oldCache[0] === dirruns && oldCache[1] === doneName) { - - // Assign to newCache so results back-propagate to previous elements - return (newCache[2] = oldCache[2]); - } else { - // Reuse newcache so results back-propagate to previous elements - uniqueCache[key] = newCache; - - // A match means we're done; a fail means we have to keep checking - if ((newCache[2] = matcher(elem, context, xml))) { - return true; - } - } - } - } - } - return false; - }; - } - - function elementMatcher(matchers) { - return matchers.length > 1 ? - function (elem, context, xml) { - var i = matchers.length; - while (i--) { - if (!matchers[i](elem, context, xml)) { - return false; - } - } - return true; - } : - matchers[0]; - } - - function multipleContexts(selector, contexts, results) { - var i = 0, - len = contexts.length; - for (; i < len; i++) { - Sizzle(selector, contexts[i], results); - } - return results; - } - - function condense(unmatched, map, filter, context, xml) { - var elem, - newUnmatched = [], - i = 0, - len = unmatched.length, - mapped = map != null; - - for (; i < len; i++) { - if ((elem = unmatched[i])) { - if (!filter || filter(elem, context, xml)) { - newUnmatched.push(elem); - if (mapped) { - map.push(i); - } - } - } - } - - return newUnmatched; - } - - function setMatcher(preFilter, selector, matcher, postFilter, postFinder, postSelector) { - if (postFilter && !postFilter[expando]) { - postFilter = setMatcher(postFilter); - } - if (postFinder && !postFinder[expando]) { - postFinder = setMatcher(postFinder, postSelector); - } - return markFunction(function (seed, results, context, xml) { - var temp, i, elem, - preMap = [], - postMap = [], - preexisting = results.length, - - // Get initial elements from seed or context - elems = seed || multipleContexts(selector || "*", context.nodeType ? [context] : context, []), - - // Prefilter to get matcher input, preserving a map for seed-results synchronization - matcherIn = preFilter && (seed || !selector) ? - condense(elems, preMap, preFilter, context, xml) : - elems, - - matcherOut = matcher ? - // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, - postFinder || (seed ? preFilter : preexisting || postFilter) ? - - // ...intermediate processing is necessary - [] : - - // ...otherwise use results directly - results : - matcherIn; - - // Find primary matches - if (matcher) { - matcher(matcherIn, matcherOut, context, xml); - } - - // Apply postFilter - if (postFilter) { - temp = condense(matcherOut, postMap); - postFilter(temp, [], context, xml); - - // Un-match failing elements by moving them back to matcherIn - i = temp.length; - while (i--) { - if ((elem = temp[i])) { - matcherOut[postMap[i]] = !(matcherIn[postMap[i]] = elem); - } - } - } - - if (seed) { - if (postFinder || preFilter) { - if (postFinder) { - // Get the final matcherOut by condensing this intermediate into postFinder contexts - temp = []; - i = matcherOut.length; - while (i--) { - if ((elem = matcherOut[i])) { - // Restore matcherIn since elem is not yet a final match - temp.push((matcherIn[i] = elem)); - } - } - postFinder(null, (matcherOut = []), temp, xml); - } - - // Move matched elements from seed to results to keep them synchronized - i = matcherOut.length; - while (i--) { - if ((elem = matcherOut[i]) && - (temp = postFinder ? indexOf(seed, elem) : preMap[i]) > -1) { - - seed[temp] = !(results[temp] = elem); - } - } - } - - // Add elements to results, through postFinder if defined - } else { - matcherOut = condense( - matcherOut === results ? - matcherOut.splice(preexisting, matcherOut.length) : - matcherOut - ); - if (postFinder) { - postFinder(null, results, matcherOut, xml); - } else { - push.apply(results, matcherOut); - } - } - }); - } - - function matcherFromTokens(tokens) { - var checkContext, matcher, j, - len = tokens.length, - leadingRelative = Expr.relative[tokens[0].type], - implicitRelative = leadingRelative || Expr.relative[" "], - i = leadingRelative ? 1 : 0, - - // The foundational matcher ensures that elements are reachable from top-level context(s) - matchContext = addCombinator(function (elem) { - return elem === checkContext; - }, implicitRelative, true), - matchAnyContext = addCombinator(function (elem) { - return indexOf(checkContext, elem) > -1; - }, implicitRelative, true), - matchers = [function (elem, context, xml) { - var ret = (!leadingRelative && (xml || context !== outermostContext)) || ( - (checkContext = context).nodeType ? - matchContext(elem, context, xml) : - matchAnyContext(elem, context, xml)); - // Avoid hanging onto element (issue #299) - checkContext = null; - return ret; - }]; - - for (; i < len; i++) { - if ((matcher = Expr.relative[tokens[i].type])) { - matchers = [addCombinator(elementMatcher(matchers), matcher)]; - } else { - matcher = Expr.filter[tokens[i].type].apply(null, tokens[i].matches); - - // Return special upon seeing a positional matcher - if (matcher[expando]) { - // Find the next relative operator (if any) for proper handling - j = ++i; - for (; j < len; j++) { - if (Expr.relative[tokens[j].type]) { - break; - } - } - return setMatcher( - i > 1 && elementMatcher(matchers), - i > 1 && toSelector( - // If the preceding token was a descendant combinator, insert an implicit any-element `*` - tokens.slice(0, i - 1).concat({value: tokens[i - 2].type === " " ? "*" : ""}) - ).replace(rtrim, "$1"), - matcher, - i < j && matcherFromTokens(tokens.slice(i, j)), - j < len && matcherFromTokens((tokens = tokens.slice(j))), - j < len && toSelector(tokens) - ); - } - matchers.push(matcher); - } - } - - return elementMatcher(matchers); - } - - function matcherFromGroupMatchers(elementMatchers, setMatchers) { - var bySet = setMatchers.length > 0, - byElement = elementMatchers.length > 0, - superMatcher = function (seed, context, xml, results, outermost) { - var elem, j, matcher, - matchedCount = 0, - i = "0", - unmatched = seed && [], - setMatched = [], - contextBackup = outermostContext, - // We must always have either seed elements or outermost context - elems = seed || byElement && Expr.find["TAG"]("*", outermost), - // Use integer dirruns iff this is the outermost matcher - dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1), - len = elems.length; - - if (outermost) { - outermostContext = context === document || context || outermost; - } - - // Add elements passing elementMatchers directly to results - // Support: IE<9, Safari - // Tolerate NodeList properties (IE: "length"; Safari: ) matching elements by id - for (; i !== len && (elem = elems[i]) != null; i++) { - if (byElement && elem) { - j = 0; - if (!context && elem.ownerDocument !== document) { - setDocument(elem); - xml = !documentIsHTML; - } - while ((matcher = elementMatchers[j++])) { - if (matcher(elem, context || document, xml)) { - results.push(elem); - break; - } - } - if (outermost) { - dirruns = dirrunsUnique; - } - } - - // Track unmatched elements for set filters - if (bySet) { - // They will have gone through all possible matchers - if ((elem = !matcher && elem)) { - matchedCount--; - } - - // Lengthen the array for every element, matched or not - if (seed) { - unmatched.push(elem); - } - } - } - - // `i` is now the count of elements visited above, and adding it to `matchedCount` - // makes the latter nonnegative. - matchedCount += i; - - // Apply set filters to unmatched elements - // NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount` - // equals `i`), unless we didn't visit _any_ elements in the above loop because we have - // no element matchers and no seed. - // Incrementing an initially-string "0" `i` allows `i` to remain a string only in that - // case, which will result in a "00" `matchedCount` that differs from `i` but is also - // numerically zero. - if (bySet && i !== matchedCount) { - j = 0; - while ((matcher = setMatchers[j++])) { - matcher(unmatched, setMatched, context, xml); - } - - if (seed) { - // Reintegrate element matches to eliminate the need for sorting - if (matchedCount > 0) { - while (i--) { - if (!(unmatched[i] || setMatched[i])) { - setMatched[i] = pop.call(results); - } - } - } - - // Discard index placeholder values to get only actual matches - setMatched = condense(setMatched); - } - - // Add matches to results - push.apply(results, setMatched); - - // Seedless set matches succeeding multiple successful matchers stipulate sorting - if (outermost && !seed && setMatched.length > 0 && - (matchedCount + setMatchers.length) > 1) { - - Sizzle.uniqueSort(results); - } - } - - // Override manipulation of globals by nested matchers - if (outermost) { - dirruns = dirrunsUnique; - outermostContext = contextBackup; - } - - return unmatched; - }; - - return bySet ? - markFunction(superMatcher) : - superMatcher; - } - - compile = Sizzle.compile = function (selector, match /* Internal Use Only */) { - var i, - setMatchers = [], - elementMatchers = [], - cached = compilerCache[selector + " "]; - - if (!cached) { - // Generate a function of recursive functions that can be used to check each element - if (!match) { - match = tokenize(selector); - } - i = match.length; - while (i--) { - cached = matcherFromTokens(match[i]); - if (cached[expando]) { - setMatchers.push(cached); - } else { - elementMatchers.push(cached); - } - } - - // Cache the compiled function - cached = compilerCache(selector, matcherFromGroupMatchers(elementMatchers, setMatchers)); - - // Save selector and tokenization - cached.selector = selector; - } - return cached; - }; - - /** - * A low-level selection function that works with Sizzle's compiled - * selector functions - * @param {String|Function} selector A selector or a pre-compiled - * selector function built with Sizzle.compile - * @param {Element} context - * @param {Array} [results] - * @param {Array} [seed] A set of elements to match against - */ - select = Sizzle.select = function (selector, context, results, seed) { - var i, tokens, token, type, find, - compiled = typeof selector === "function" && selector, - match = !seed && tokenize((selector = compiled.selector || selector)); - - results = results || []; - - // Try to minimize operations if there is only one selector in the list and no seed - // (the latter of which guarantees us context) - if (match.length === 1) { - - // Reduce context if the leading compound selector is an ID - tokens = match[0] = match[0].slice(0); - if (tokens.length > 2 && (token = tokens[0]).type === "ID" && - context.nodeType === 9 && documentIsHTML && Expr.relative[tokens[1].type]) { - - context = (Expr.find["ID"](token.matches[0].replace(runescape, funescape), context) || [])[0]; - if (!context) { - return results; - - // Precompiled matchers will still verify ancestry, so step up a level - } else if (compiled) { - context = context.parentNode; - } - - selector = selector.slice(tokens.shift().value.length); - } - - // Fetch a seed set for right-to-left matching - i = matchExpr["needsContext"].test(selector) ? 0 : tokens.length; - while (i--) { - token = tokens[i]; - - // Abort if we hit a combinator - if (Expr.relative[(type = token.type)]) { - break; - } - if ((find = Expr.find[type])) { - // Search, expanding context for leading sibling combinators - if ((seed = find( - token.matches[0].replace(runescape, funescape), - rsibling.test(tokens[0].type) && testContext(context.parentNode) || context - ))) { - - // If seed is empty or no tokens remain, we can return early - tokens.splice(i, 1); - selector = seed.length && toSelector(tokens); - if (!selector) { - push.apply(results, seed); - return results; - } - - break; - } - } - } - } - - // Compile and execute a filtering function if one is not provided - // Provide `match` to avoid retokenization if we modified the selector above - (compiled || compile(selector, match))( - seed, - context, - !documentIsHTML, - results, - !context || rsibling.test(selector) && testContext(context.parentNode) || context - ); - return results; - }; - - // One-time assignments - - // Sort stability - support.sortStable = expando.split("").sort(sortOrder).join("") === expando; - - // Support: Chrome 14-35+ - // Always assume duplicates if they aren't passed to the comparison function - support.detectDuplicates = !!hasDuplicate; - - // Initialize against the default document - setDocument(); - - return Sizzle; - - })(window); - - - jQuery.find = Sizzle; - jQuery.expr = Sizzle.selectors; - - // Deprecated - jQuery.expr[":"] = jQuery.expr.pseudos; - jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort; - jQuery.text = Sizzle.getText; - jQuery.isXMLDoc = Sizzle.isXML; - jQuery.contains = Sizzle.contains; - jQuery.escapeSelector = Sizzle.escape; - - - var dir = function (elem, dir, until) { - var matched = [], - truncate = until !== undefined; - - while ((elem = elem[dir]) && elem.nodeType !== 9) { - if (elem.nodeType === 1) { - if (truncate && jQuery(elem).is(until)) { - break; - } - matched.push(elem); - } - } - return matched; - }; - - - var siblings = function (n, elem) { - var matched = []; - - for (; n; n = n.nextSibling) { - if (n.nodeType === 1 && n !== elem) { - matched.push(n); - } - } - - return matched; - }; - - - var rneedsContext = jQuery.expr.match.needsContext; - - - function nodeName(elem, name) { - - return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); - - } - var rsingleTag = (/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i); - - - // Implement the identical functionality for filter and not - function winnow(elements, qualifier, not) { - if (isFunction(qualifier)) { - return jQuery.grep(elements, function (elem, i) { - return !!qualifier.call(elem, i, elem) !== not; - }); - } - - // Single element - if (qualifier.nodeType) { - return jQuery.grep(elements, function (elem) { - return (elem === qualifier) !== not; - }); - } - - // Arraylike of elements (jQuery, arguments, Array) - if (typeof qualifier !== "string") { - return jQuery.grep(elements, function (elem) { - return (indexOf.call(qualifier, elem) > -1) !== not; - }); - } - - // Filtered directly for both simple and complex selectors - return jQuery.filter(qualifier, elements, not); - } - - jQuery.filter = function (expr, elems, not) { - var elem = elems[0]; - - if (not) { - expr = ":not(" + expr + ")"; - } - - if (elems.length === 1 && elem.nodeType === 1) { - return jQuery.find.matchesSelector(elem, expr) ? [elem] : []; - } - - return jQuery.find.matches(expr, jQuery.grep(elems, function (elem) { - return elem.nodeType === 1; - })); - }; - - jQuery.fn.extend({ - find: function (selector) { - var i, ret, - len = this.length, - self = this; - - if (typeof selector !== "string") { - return this.pushStack(jQuery(selector).filter(function () { - for (i = 0; i < len; i++) { - if (jQuery.contains(self[i], this)) { - return true; - } - } - })); - } - - ret = this.pushStack([]); - - for (i = 0; i < len; i++) { - jQuery.find(selector, self[i], ret); - } - - return len > 1 ? jQuery.uniqueSort(ret) : ret; - }, - filter: function (selector) { - return this.pushStack(winnow(this, selector || [], false)); - }, - not: function (selector) { - return this.pushStack(winnow(this, selector || [], true)); - }, - is: function (selector) { - return !!winnow( - this, - - // If this is a positional/relative selector, check membership in the returned set - // so $("p:first").is("p:last") won't return true for a doc with two "p". - typeof selector === "string" && rneedsContext.test(selector) ? - jQuery(selector) : - selector || [], - false - ).length; - } - }); - - - // Initialize a jQuery object - - - // A central reference to the root jQuery(document) - var rootjQuery, - - // A simple way to check for HTML strings - // Prioritize #id over to avoid XSS via location.hash (#9521) - // Strict HTML recognition (#11290: must start with <) - // Shortcut simple #id case for speed - rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/, - - init$2 = jQuery.fn.init = function (selector, context, root) { - var match, elem; - - // HANDLE: $(""), $(null), $(undefined), $(false) - if (!selector) { - return this; - } - - // Method init() accepts an alternate rootjQuery - // so migrate can support jQuery.sub (gh-2101) - root = root || rootjQuery; - - // Handle HTML strings - if (typeof selector === "string") { - if (selector[0] === "<" && - selector[selector.length - 1] === ">" && - selector.length >= 3) { - - // Assume that strings that start and end with <> are HTML and skip the regex check - match = [null, selector, null]; - - } else { - match = rquickExpr.exec(selector); - } - - // Match html or make sure no context is specified for #id - if (match && (match[1] || !context)) { - - // HANDLE: $(html) -> $(array) - if (match[1]) { - context = context instanceof jQuery ? context[0] : context; - - // Option to run scripts is true for back-compat - // Intentionally let the error be thrown if parseHTML is not present - jQuery.merge(this, jQuery.parseHTML( - match[1], - context && context.nodeType ? context.ownerDocument || context : document$1, - true - )); - - // HANDLE: $(html, props) - if (rsingleTag.test(match[1]) && jQuery.isPlainObject(context)) { - for (match in context) { - - // Properties of context are called as methods if possible - if (isFunction(this[match])) { - this[match](context[match]); - - // ...and otherwise set as attributes - } else { - this.attr(match, context[match]); - } - } - } - - return this; - - // HANDLE: $(#id) - } else { - elem = document$1.getElementById(match[2]); - - if (elem) { - - // Inject the element directly into the jQuery object - this[0] = elem; - this.length = 1; - } - return this; - } - - // HANDLE: $(expr, $(...)) - } else if (!context || context.jquery) { - return (context || root).find(selector); - - // HANDLE: $(expr, context) - // (which is just equivalent to: $(context).find(expr) - } else { - return this.constructor(context).find(selector); - } - - // HANDLE: $(DOMElement) - } else if (selector.nodeType) { - this[0] = selector; - this.length = 1; - return this; - - // HANDLE: $(function) - // Shortcut for document ready - } else if (isFunction(selector)) { - return root.ready !== undefined ? - root.ready(selector) : - - // Execute immediately if ready is not present - selector(jQuery); - } - - return jQuery.makeArray(selector, this); - }; - - // Give the init function the jQuery prototype for later instantiation - init$2.prototype = jQuery.fn; - - // Initialize central reference - rootjQuery = jQuery(document$1); - - - var rparentsprev = /^(?:parents|prev(?:Until|All))/, - - // Methods guaranteed to produce a unique set when starting from a unique set - guaranteedUnique = { - children: true, - contents: true, - next: true, - prev: true - }; - - jQuery.fn.extend({ - has: function (target) { - var targets = jQuery(target, this), - l = targets.length; - - return this.filter(function () { - var i = 0; - for (; i < l; i++) { - if (jQuery.contains(this, targets[i])) { - return true; - } - } - }); - }, - - closest: function (selectors, context) { - var cur, - i = 0, - l = this.length, - matched = [], - targets = typeof selectors !== "string" && jQuery(selectors); - - // Positional selectors never match, since there's no _selection_ context - if (!rneedsContext.test(selectors)) { - for (; i < l; i++) { - for (cur = this[i]; cur && cur !== context; cur = cur.parentNode) { - - // Always skip document fragments - if (cur.nodeType < 11 && (targets ? - targets.index(cur) > -1 : - - // Don't pass non-elements to Sizzle - cur.nodeType === 1 && - jQuery.find.matchesSelector(cur, selectors))) { - - matched.push(cur); - break; - } - } - } - } - - return this.pushStack(matched.length > 1 ? jQuery.uniqueSort(matched) : matched); - }, - - // Determine the position of an element within the set - index: function (elem) { - - // No argument, return index in parent - if (!elem) { - return (this[0] && this[0].parentNode) ? this.first().prevAll().length : -1; - } - - // Index in selector - if (typeof elem === "string") { - return indexOf.call(jQuery(elem), this[0]); - } - - // Locate the position of the desired element - return indexOf.call(this, - - // If it receives a jQuery object, the first element is used - elem.jquery ? elem[0] : elem - ); - }, - - add: function (selector, context) { - return this.pushStack( - jQuery.uniqueSort( - jQuery.merge(this.get(), jQuery(selector, context)) - ) - ); - }, - - addBack: function (selector) { - return this.add(selector == null ? - this.prevObject : this.prevObject.filter(selector) - ); - } - }); - - function sibling(cur, dir) { - while ((cur = cur[dir]) && cur.nodeType !== 1) { - } - return cur; - } - - jQuery.each({ - parent: function (elem) { - var parent = elem.parentNode; - return parent && parent.nodeType !== 11 ? parent : null; - }, - parents: function (elem) { - return dir(elem, "parentNode"); - }, - parentsUntil: function (elem, i, until) { - return dir(elem, "parentNode", until); - }, - next: function (elem) { - return sibling(elem, "nextSibling"); - }, - prev: function (elem) { - return sibling(elem, "previousSibling"); - }, - nextAll: function (elem) { - return dir(elem, "nextSibling"); - }, - prevAll: function (elem) { - return dir(elem, "previousSibling"); - }, - nextUntil: function (elem, i, until) { - return dir(elem, "nextSibling", until); - }, - prevUntil: function (elem, i, until) { - return dir(elem, "previousSibling", until); - }, - siblings: function (elem) { - return siblings((elem.parentNode || {}).firstChild, elem); - }, - children: function (elem) { - return siblings(elem.firstChild); - }, - contents: function (elem) { - if (nodeName(elem, "iframe")) { - return elem.contentDocument; - } - - // Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only - // Treat the template element as a regular one in browsers that - // don't support it. - if (nodeName(elem, "template")) { - elem = elem.content || elem; - } - - return jQuery.merge([], elem.childNodes); - } - }, function (name, fn) { - jQuery.fn[name] = function (until, selector) { - var matched = jQuery.map(this, fn, until); - - if (name.slice(-5) !== "Until") { - selector = until; - } - - if (selector && typeof selector === "string") { - matched = jQuery.filter(selector, matched); - } - - if (this.length > 1) { - - // Remove duplicates - if (!guaranteedUnique[name]) { - jQuery.uniqueSort(matched); - } - - // Reverse order for parents* and prev-derivatives - if (rparentsprev.test(name)) { - matched.reverse(); - } - } - - return this.pushStack(matched); - }; - }); - var rnothtmlwhite = (/[^\x20\t\r\n\f]+/g); - - - // Convert String-formatted options into Object-formatted ones - function createOptions(options) { - var object = {}; - jQuery.each(options.match(rnothtmlwhite) || [], function (_, flag) { - object[flag] = true; - }); - return object; - } - - /* - * Create a callback list using the following parameters: - * - * options: an optional list of space-separated options that will change how - * the callback list behaves or a more traditional option object - * - * By default a callback list will act like an event callback list and can be - * "fired" multiple times. - * - * Possible options: - * - * once: will ensure the callback list can only be fired once (like a Deferred) - * - * memory: will keep track of previous values and will call any callback added - * after the list has been fired right away with the latest "memorized" - * values (like a Deferred) - * - * unique: will ensure a callback can only be added once (no duplicate in the list) - * - * stopOnFalse: interrupt callings when a callback returns false - * - */ - jQuery.Callbacks = function (options) { - - // Convert options from String-formatted to Object-formatted if needed - // (we check in cache first) - options = typeof options === "string" ? - createOptions(options) : - jQuery.extend({}, options); - - var // Flag to know if list is currently firing - firing, - - // Last fire value for non-forgettable lists - memory, - - // Flag to know if list was already fired - fired, - - // Flag to prevent firing - locked, - - // Actual callback list - list = [], - - // Queue of execution data for repeatable lists - queue = [], - - // Index of currently firing callback (modified by add/remove as needed) - firingIndex = -1, - - // Fire callbacks - fire = function () { - - // Enforce single-firing - locked = locked || options.once; - - // Execute callbacks for all pending executions, - // respecting firingIndex overrides and runtime changes - fired = firing = true; - for (; queue.length; firingIndex = -1) { - memory = queue.shift(); - while (++firingIndex < list.length) { - - // Run callback and check for early termination - if (list[firingIndex].apply(memory[0], memory[1]) === false && - options.stopOnFalse) { - - // Jump to end and forget the data so .add doesn't re-fire - firingIndex = list.length; - memory = false; - } - } - } - - // Forget the data if we're done with it - if (!options.memory) { - memory = false; - } - - firing = false; - - // Clean up if we're done firing for good - if (locked) { - - // Keep an empty list if we have data for future add calls - if (memory) { - list = []; - - // Otherwise, this object is spent - } else { - list = ""; - } - } - }, - - // Actual Callbacks object - self = { - - // Add a callback or a collection of callbacks to the list - add: function () { - if (list) { - - // If we have memory from a past run, we should fire after adding - if (memory && !firing) { - firingIndex = list.length - 1; - queue.push(memory); - } - - (function add(args) { - jQuery.each(args, function (_, arg) { - if (isFunction(arg)) { - if (!options.unique || !self.has(arg)) { - list.push(arg); - } - } else if (arg && arg.length && toType(arg) !== "string") { - - // Inspect recursively - add(arg); - } - }); - })(arguments); - - if (memory && !firing) { - fire(); - } - } - return this; - }, - - // Remove a callback from the list - remove: function () { - jQuery.each(arguments, function (_, arg) { - var index; - while ((index = jQuery.inArray(arg, list, index)) > -1) { - list.splice(index, 1); - - // Handle firing indexes - if (index <= firingIndex) { - firingIndex--; - } - } - }); - return this; - }, - - // Check if a given callback is in the list. - // If no argument is given, return whether or not list has callbacks attached. - has: function (fn) { - return fn ? - jQuery.inArray(fn, list) > -1 : - list.length > 0; - }, - - // Remove all callbacks from the list - empty: function () { - if (list) { - list = []; - } - return this; - }, - - // Disable .fire and .add - // Abort any current/pending executions - // Clear all callbacks and values - disable: function () { - locked = queue = []; - list = memory = ""; - return this; - }, - disabled: function () { - return !list; - }, - - // Disable .fire - // Also disable .add unless we have memory (since it would have no effect) - // Abort any pending executions - lock: function () { - locked = queue = []; - if (!memory && !firing) { - list = memory = ""; - } - return this; - }, - locked: function () { - return !!locked; - }, - - // Call all callbacks with the given context and arguments - fireWith: function (context, args) { - if (!locked) { - args = args || []; - args = [context, args.slice ? args.slice() : args]; - queue.push(args); - if (!firing) { - fire(); - } - } - return this; - }, - - // Call all the callbacks with the given arguments - fire: function () { - self.fireWith(this, arguments); - return this; - }, - - // To know if the callbacks have already been called at least once - fired: function () { - return !!fired; - } - }; - - return self; - }; - - - function Identity(v) { - return v; - } - - function Thrower(ex) { - throw ex; - } - - function adoptValue(value, resolve, reject, noValue) { - var method; - - try { - - // Check for promise aspect first to privilege synchronous behavior - if (value && isFunction((method = value.promise))) { - method.call(value).done(resolve).fail(reject); - - // Other thenables - } else if (value && isFunction((method = value.then))) { - method.call(value, resolve, reject); - - // Other non-thenables - } else { - - // Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer: - // * false: [ value ].slice( 0 ) => resolve( value ) - // * true: [ value ].slice( 1 ) => resolve() - resolve.apply(undefined, [value].slice(noValue)); - } - - // For Promises/A+, convert exceptions into rejections - // Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in - // Deferred#then to conditionally suppress rejection. - } catch (value) { - - // Support: Android 4.0 only - // Strict mode functions invoked without .call/.apply get global-object context - reject.apply(undefined, [value]); - } - } - - jQuery.extend({ - - Deferred: function (func) { - var tuples = [ - - // action, add listener, callbacks, - // ... .then handlers, argument index, [final state] - ["notify", "progress", jQuery.Callbacks("memory"), - jQuery.Callbacks("memory"), 2], - ["resolve", "done", jQuery.Callbacks("once memory"), - jQuery.Callbacks("once memory"), 0, "resolved"], - ["reject", "fail", jQuery.Callbacks("once memory"), - jQuery.Callbacks("once memory"), 1, "rejected"] - ], - state = "pending", - promise = { - state: function () { - return state; - }, - always: function () { - deferred.done(arguments).fail(arguments); - return this; - }, - "catch": function (fn) { - return promise.then(null, fn); - }, - - // Keep pipe for back-compat - pipe: function ( /* fnDone, fnFail, fnProgress */) { - var fns = arguments; - - return jQuery.Deferred(function (newDefer) { - jQuery.each(tuples, function (i, tuple) { - - // Map tuples (progress, done, fail) to arguments (done, fail, progress) - var fn = isFunction(fns[tuple[4]]) && fns[tuple[4]]; - - // deferred.progress(function() { bind to newDefer or newDefer.notify }) - // deferred.done(function() { bind to newDefer or newDefer.resolve }) - // deferred.fail(function() { bind to newDefer or newDefer.reject }) - deferred[tuple[1]](function () { - var returned = fn && fn.apply(this, arguments); - if (returned && isFunction(returned.promise)) { - returned.promise() - .progress(newDefer.notify) - .done(newDefer.resolve) - .fail(newDefer.reject); - } else { - newDefer[tuple[0] + "With"]( - this, - fn ? [returned] : arguments - ); - } - }); - }); - fns = null; - }).promise(); - }, - then: function (onFulfilled, onRejected, onProgress) { - var maxDepth = 0; - - function resolve(depth, deferred, handler, special) { - return function () { - var that = this, - args = arguments, - mightThrow = function () { - var returned, then; - - // Support: Promises/A+ section 2.3.3.3.3 - // https://promisesaplus.com/#point-59 - // Ignore double-resolution attempts - if (depth < maxDepth) { - return; - } - - returned = handler.apply(that, args); - - // Support: Promises/A+ section 2.3.1 - // https://promisesaplus.com/#point-48 - if (returned === deferred.promise()) { - throw new TypeError("Thenable self-resolution"); - } - - // Support: Promises/A+ sections 2.3.3.1, 3.5 - // https://promisesaplus.com/#point-54 - // https://promisesaplus.com/#point-75 - // Retrieve `then` only once - then = returned && - - // Support: Promises/A+ section 2.3.4 - // https://promisesaplus.com/#point-64 - // Only check objects and functions for thenability - (typeof returned === "object" || - typeof returned === "function") && - returned.then; - - // Handle a returned thenable - if (isFunction(then)) { - - // Special processors (notify) just wait for resolution - if (special) { - then.call( - returned, - resolve(maxDepth, deferred, Identity, special), - resolve(maxDepth, deferred, Thrower, special) - ); - - // Normal processors (resolve) also hook into progress - } else { - - // ...and disregard older resolution values - maxDepth++; - - then.call( - returned, - resolve(maxDepth, deferred, Identity, special), - resolve(maxDepth, deferred, Thrower, special), - resolve(maxDepth, deferred, Identity, - deferred.notifyWith) - ); - } - - // Handle all other returned values - } else { - - // Only substitute handlers pass on context - // and multiple values (non-spec behavior) - if (handler !== Identity) { - that = undefined; - args = [returned]; - } - - // Process the value(s) - // Default process is resolve - (special || deferred.resolveWith)(that, args); - } - }, - - // Only normal processors (resolve) catch and reject exceptions - process = special ? - mightThrow : - function () { - try { - mightThrow(); - } catch (e) { - - if (jQuery.Deferred.exceptionHook) { - jQuery.Deferred.exceptionHook(e, - process.stackTrace); - } - - // Support: Promises/A+ section 2.3.3.3.4.1 - // https://promisesaplus.com/#point-61 - // Ignore post-resolution exceptions - if (depth + 1 >= maxDepth) { - - // Only substitute handlers pass on context - // and multiple values (non-spec behavior) - if (handler !== Thrower) { - that = undefined; - args = [e]; - } - - deferred.rejectWith(that, args); - } - } - }; - - // Support: Promises/A+ section 2.3.3.3.1 - // https://promisesaplus.com/#point-57 - // Re-resolve promises immediately to dodge false rejection from - // subsequent errors - if (depth) { - process(); - } else { - - // Call an optional hook to record the stack, in case of exception - // since it's otherwise lost when execution goes async - if (jQuery.Deferred.getStackHook) { - process.stackTrace = jQuery.Deferred.getStackHook(); - } - window.setTimeout(process); - } - }; - } - - return jQuery.Deferred(function (newDefer) { - - // progress_handlers.add( ... ) - tuples[0][3].add( - resolve( - 0, - newDefer, - isFunction(onProgress) ? - onProgress : - Identity, - newDefer.notifyWith - ) - ); - - // fulfilled_handlers.add( ... ) - tuples[1][3].add( - resolve( - 0, - newDefer, - isFunction(onFulfilled) ? - onFulfilled : - Identity - ) - ); - - // rejected_handlers.add( ... ) - tuples[2][3].add( - resolve( - 0, - newDefer, - isFunction(onRejected) ? - onRejected : - Thrower - ) - ); - }).promise(); - }, - - // Get a promise for this deferred - // If obj is provided, the promise aspect is added to the object - promise: function (obj) { - return obj != null ? jQuery.extend(obj, promise) : promise; - } - }, - deferred = {}; - - // Add list-specific methods - jQuery.each(tuples, function (i, tuple) { - var list = tuple[2], - stateString = tuple[5]; - - // promise.progress = list.add - // promise.done = list.add - // promise.fail = list.add - promise[tuple[1]] = list.add; - - // Handle state - if (stateString) { - list.add( - function () { - - // state = "resolved" (i.e., fulfilled) - // state = "rejected" - state = stateString; - }, - - // rejected_callbacks.disable - // fulfilled_callbacks.disable - tuples[3 - i][2].disable, - - // rejected_handlers.disable - // fulfilled_handlers.disable - tuples[3 - i][3].disable, - - // progress_callbacks.lock - tuples[0][2].lock, - - // progress_handlers.lock - tuples[0][3].lock - ); - } - - // progress_handlers.fire - // fulfilled_handlers.fire - // rejected_handlers.fire - list.add(tuple[3].fire); - - // deferred.notify = function() { deferred.notifyWith(...) } - // deferred.resolve = function() { deferred.resolveWith(...) } - // deferred.reject = function() { deferred.rejectWith(...) } - deferred[tuple[0]] = function () { - deferred[tuple[0] + "With"](this === deferred ? undefined : this, arguments); - return this; - }; - - // deferred.notifyWith = list.fireWith - // deferred.resolveWith = list.fireWith - // deferred.rejectWith = list.fireWith - deferred[tuple[0] + "With"] = list.fireWith; - }); - - // Make the deferred a promise - promise.promise(deferred); - - // Call given func if any - if (func) { - func.call(deferred, deferred); - } - - // All done! - return deferred; - }, - - // Deferred helper - when: function (singleValue) { - var - - // count of uncompleted subordinates - remaining = arguments.length, - - // count of unprocessed arguments - i = remaining, - - // subordinate fulfillment data - resolveContexts = Array(i), - resolveValues = slice.call(arguments), - - // the master Deferred - master = jQuery.Deferred(), - - // subordinate callback factory - updateFunc = function (i) { - return function (value) { - resolveContexts[i] = this; - resolveValues[i] = arguments.length > 1 ? slice.call(arguments) : value; - if (!(--remaining)) { - master.resolveWith(resolveContexts, resolveValues); - } - }; - }; - - // Single- and empty arguments are adopted like Promise.resolve - if (remaining <= 1) { - adoptValue(singleValue, master.done(updateFunc(i)).resolve, master.reject, - !remaining); - - // Use .then() to unwrap secondary thenables (cf. gh-3000) - if (master.state() === "pending" || - isFunction(resolveValues[i] && resolveValues[i].then)) { - - return master.then(); - } - } - - // Multiple arguments are aggregated like Promise.all array elements - while (i--) { - adoptValue(resolveValues[i], updateFunc(i), master.reject); - } - - return master.promise(); - } - }); - - - // These usually indicate a programmer mistake during development, - // warn about them ASAP rather than swallowing them by default. - var rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/; - - jQuery.Deferred.exceptionHook = function (error, stack) { - - // Support: IE 8 - 9 only - // Console exists when dev tools are open, which can happen at any time - if (window.console && window.console.warn && error && rerrorNames.test(error.name)) { - window.console.warn("jQuery.Deferred exception: " + error.message, error.stack, stack); - } - }; - - - jQuery.readyException = function (error) { - window.setTimeout(function () { - throw error; - }); - }; - - - // The deferred used on DOM ready - var readyList = jQuery.Deferred(); - - jQuery.fn.ready = function (fn) { - - readyList - .then(fn) - - // Wrap jQuery.readyException in a function so that the lookup - // happens at the time of error handling instead of callback - // registration. - .catch(function (error) { - jQuery.readyException(error); - }); - - return this; - }; - - jQuery.extend({ - - // Is the DOM ready to be used? Set to true once it occurs. - isReady: false, - - // A counter to track how many items to wait for before - // the ready event fires. See #6781 - readyWait: 1, - - // Handle when the DOM is ready - ready: function (wait) { - - // Abort if there are pending holds or we're already ready - if (wait === true ? --jQuery.readyWait : jQuery.isReady) { - return; - } - - // Remember that the DOM is ready - jQuery.isReady = true; - - // If a normal DOM Ready event fired, decrement, and wait if need be - if (wait !== true && --jQuery.readyWait > 0) { - return; - } - - // If there are functions bound, to execute - readyList.resolveWith(document$1, [jQuery]); - } - }); - - jQuery.ready.then = readyList.then; - - // The ready event handler and self cleanup method - function completed() { - document$1.removeEventListener("DOMContentLoaded", completed); - window.removeEventListener("load", completed); - jQuery.ready(); - } - - // Catch cases where $(document).ready() is called - // after the browser event has already occurred. - // Support: IE <=9 - 10 only - // Older IE sometimes signals "interactive" too soon - if (document$1.readyState === "complete" || - (document$1.readyState !== "loading" && !document$1.documentElement.doScroll)) { - - // Handle it asynchronously to allow scripts the opportunity to delay ready - window.setTimeout(jQuery.ready); - - } else { - - // Use the handy event callback - document$1.addEventListener("DOMContentLoaded", completed); - - // A fallback to window.onload, that will always work - window.addEventListener("load", completed); - } - - - // Multifunctional method to get and set values of a collection - // The value/s can optionally be executed if it's a function - var access = function (elems, fn, key, value, chainable, emptyGet, raw) { - var i = 0, - len = elems.length, - bulk = key == null; - - // Sets many values - if (toType(key) === "object") { - chainable = true; - for (i in key) { - access(elems, fn, i, key[i], true, emptyGet, raw); - } - - // Sets one value - } else if (value !== undefined) { - chainable = true; - - if (!isFunction(value)) { - raw = true; - } - - if (bulk) { - - // Bulk operations run against the entire set - if (raw) { - fn.call(elems, value); - fn = null; - - // ...except when executing function values - } else { - bulk = fn; - fn = function (elem, key, value) { - return bulk.call(jQuery(elem), value); - }; - } - } - - if (fn) { - for (; i < len; i++) { - fn( - elems[i], key, raw ? - value : - value.call(elems[i], i, fn(elems[i], key)) - ); - } - } - } - - if (chainable) { - return elems; - } - - // Gets - if (bulk) { - return fn.call(elems); - } - - return len ? fn(elems[0], key) : emptyGet; - }; - - - // Matches dashed string for camelizing - var rmsPrefix = /^-ms-/, - rdashAlpha = /-([a-z])/g; - - // Used by camelCase as callback to replace() - function fcamelCase(all, letter) { - return letter.toUpperCase(); - } - - // Convert dashed to camelCase; used by the css and data modules - // Support: IE <=9 - 11, Edge 12 - 15 - // Microsoft forgot to hump their vendor prefix (#9572) - function camelCase(string) { - return string.replace(rmsPrefix, "ms-").replace(rdashAlpha, fcamelCase); - } - - var acceptData = function (owner) { - - // Accepts only: - // - Node - // - Node.ELEMENT_NODE - // - Node.DOCUMENT_NODE - // - Object - // - Any - return owner.nodeType === 1 || owner.nodeType === 9 || !(+owner.nodeType); - }; - - - function Data() { - this.expando = jQuery.expando + Data.uid++; - } - - Data.uid = 1; - - Data.prototype = { - - cache: function (owner) { - - // Check if the owner object already has a cache - var value = owner[this.expando]; - - // If not, create one - if (!value) { - value = {}; - - // We can accept data for non-element nodes in modern browsers, - // but we should not, see #8335. - // Always return an empty object. - if (acceptData(owner)) { - - // If it is a node unlikely to be stringify-ed or looped over - // use plain assignment - if (owner.nodeType) { - owner[this.expando] = value; - - // Otherwise secure it in a non-enumerable property - // configurable must be true to allow the property to be - // deleted when data is removed - } else { - Object.defineProperty(owner, this.expando, { - value: value, - configurable: true - }); - } - } - } - - return value; - }, - set: function (owner, data, value) { - var prop, - cache = this.cache(owner); - - // Handle: [ owner, key, value ] args - // Always use camelCase key (gh-2257) - if (typeof data === "string") { - cache[camelCase(data)] = value; - - // Handle: [ owner, { properties } ] args - } else { - - // Copy the properties one-by-one to the cache object - for (prop in data) { - cache[camelCase(prop)] = data[prop]; - } - } - return cache; - }, - get: function (owner, key) { - return key === undefined ? - this.cache(owner) : - - // Always use camelCase key (gh-2257) - owner[this.expando] && owner[this.expando][camelCase(key)]; - }, - access: function (owner, key, value) { - - // In cases where either: - // - // 1. No key was specified - // 2. A string key was specified, but no value provided - // - // Take the "read" path and allow the get method to determine - // which value to return, respectively either: - // - // 1. The entire cache object - // 2. The data stored at the key - // - if (key === undefined || - ((key && typeof key === "string") && value === undefined)) { - - return this.get(owner, key); - } - - // When the key is not a string, or both a key and value - // are specified, set or extend (existing objects) with either: - // - // 1. An object of properties - // 2. A key and value - // - this.set(owner, key, value); - - // Since the "set" path can have two possible entry points - // return the expected data based on which path was taken[*] - return value !== undefined ? value : key; - }, - remove: function (owner, key) { - var i, - cache = owner[this.expando]; - - if (cache === undefined) { - return; - } - - if (key !== undefined) { - - // Support array or space separated string of keys - if (Array.isArray(key)) { - - // If key is an array of keys... - // We always set camelCase keys, so remove that. - key = key.map(camelCase); - } else { - key = camelCase(key); - - // If a key with the spaces exists, use it. - // Otherwise, create an array by matching non-whitespace - key = key in cache ? - [key] : - (key.match(rnothtmlwhite) || []); - } - - i = key.length; - - while (i--) { - delete cache[key[i]]; - } - } - - // Remove the expando if there's no more data - if (key === undefined || jQuery.isEmptyObject(cache)) { - - // Support: Chrome <=35 - 45 - // Webkit & Blink performance suffers when deleting properties - // from DOM nodes, so set to undefined instead - // https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted) - if (owner.nodeType) { - owner[this.expando] = undefined; - } else { - delete owner[this.expando]; - } - } - }, - hasData: function (owner) { - var cache = owner[this.expando]; - return cache !== undefined && !jQuery.isEmptyObject(cache); - } - }; - var dataPriv = new Data(); - - var dataUser = new Data(); - - - // Implementation Summary - // - // 1. Enforce API surface and semantic compatibility with 1.9.x branch - // 2. Improve the module's maintainability by reducing the storage - // paths to a single mechanism. - // 3. Use the same single mechanism to support "private" and "user" data. - // 4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData) - // 5. Avoid exposing implementation details on user objects (eg. expando properties) - // 6. Provide a clear path for implementation upgrade to WeakMap in 2014 - - var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, - rmultiDash = /[A-Z]/g; - - function getData(data) { - if (data === "true") { - return true; - } - - if (data === "false") { - return false; - } - - if (data === "null") { - return null; - } - - // Only convert to a number if it doesn't change the string - if (data === +data + "") { - return +data; - } - - if (rbrace.test(data)) { - return JSON.parse(data); - } - - return data; - } - - function dataAttr(elem, key, data) { - var name; - - // If nothing was found internally, try to fetch any - // data from the HTML5 data-* attribute - if (data === undefined && elem.nodeType === 1) { - name = "data-" + key.replace(rmultiDash, "-$&").toLowerCase(); - data = elem.getAttribute(name); - - if (typeof data === "string") { - try { - data = getData(data); - } catch (e) { - } - - // Make sure we set the data so it isn't changed later - dataUser.set(elem, key, data); - } else { - data = undefined; - } - } - return data; - } - - jQuery.extend({ - hasData: function (elem) { - return dataUser.hasData(elem) || dataPriv.hasData(elem); - }, - - data: function (elem, name, data) { - return dataUser.access(elem, name, data); - }, - - removeData: function (elem, name) { - dataUser.remove(elem, name); - }, - - // TODO: Now that all calls to _data and _removeData have been replaced - // with direct calls to dataPriv methods, these can be deprecated. - _data: function (elem, name, data) { - return dataPriv.access(elem, name, data); - }, - - _removeData: function (elem, name) { - dataPriv.remove(elem, name); - } - }); - - jQuery.fn.extend({ - data: function (key, value) { - var i, name, data, - elem = this[0], - attrs = elem && elem.attributes; - - // Gets all values - if (key === undefined) { - if (this.length) { - data = dataUser.get(elem); - - if (elem.nodeType === 1 && !dataPriv.get(elem, "hasDataAttrs")) { - i = attrs.length; - while (i--) { - - // Support: IE 11 only - // The attrs elements can be null (#14894) - if (attrs[i]) { - name = attrs[i].name; - if (name.indexOf("data-") === 0) { - name = camelCase(name.slice(5)); - dataAttr(elem, name, data[name]); - } - } - } - dataPriv.set(elem, "hasDataAttrs", true); - } - } - - return data; - } - - // Sets multiple values - if (typeof key === "object") { - return this.each(function () { - dataUser.set(this, key); - }); - } - - return access(this, function (value) { - var data; - - // The calling jQuery object (element matches) is not empty - // (and therefore has an element appears at this[ 0 ]) and the - // `value` parameter was not undefined. An empty jQuery object - // will result in `undefined` for elem = this[ 0 ] which will - // throw an exception if an attempt to read a data cache is made. - if (elem && value === undefined) { - - // Attempt to get data from the cache - // The key will always be camelCased in Data - data = dataUser.get(elem, key); - if (data !== undefined) { - return data; - } - - // Attempt to "discover" the data in - // HTML5 custom data-* attrs - data = dataAttr(elem, key); - if (data !== undefined) { - return data; - } - - // We tried really hard, but the data doesn't exist. - return; - } - - // Set the data... - this.each(function () { - - // We always store the camelCased key - dataUser.set(this, key, value); - }); - }, null, value, arguments.length > 1, null, true); - }, - - removeData: function (key) { - return this.each(function () { - dataUser.remove(this, key); - }); - } - }); - - - jQuery.extend({ - queue: function (elem, type, data) { - var queue; - - if (elem) { - type = (type || "fx") + "queue"; - queue = dataPriv.get(elem, type); - - // Speed up dequeue by getting out quickly if this is just a lookup - if (data) { - if (!queue || Array.isArray(data)) { - queue = dataPriv.access(elem, type, jQuery.makeArray(data)); - } else { - queue.push(data); - } - } - return queue || []; - } - }, - - dequeue: function (elem, type) { - type = type || "fx"; - - var queue = jQuery.queue(elem, type), - startLength = queue.length, - fn = queue.shift(), - hooks = jQuery._queueHooks(elem, type), - next = function () { - jQuery.dequeue(elem, type); - }; - - // If the fx queue is dequeued, always remove the progress sentinel - if (fn === "inprogress") { - fn = queue.shift(); - startLength--; - } - - if (fn) { - - // Add a progress sentinel to prevent the fx queue from being - // automatically dequeued - if (type === "fx") { - queue.unshift("inprogress"); - } - - // Clear up the last queue stop function - delete hooks.stop; - fn.call(elem, next, hooks); - } - - if (!startLength && hooks) { - hooks.empty.fire(); - } - }, - - // Not public - generate a queueHooks object, or return the current one - _queueHooks: function (elem, type) { - var key = type + "queueHooks"; - return dataPriv.get(elem, key) || dataPriv.access(elem, key, { - empty: jQuery.Callbacks("once memory").add(function () { - dataPriv.remove(elem, [type + "queue", key]); - }) - }); - } - }); - - jQuery.fn.extend({ - queue: function (type, data) { - var setter = 2; - - if (typeof type !== "string") { - data = type; - type = "fx"; - setter--; - } - - if (arguments.length < setter) { - return jQuery.queue(this[0], type); - } - - return data === undefined ? - this : - this.each(function () { - var queue = jQuery.queue(this, type, data); - - // Ensure a hooks for this queue - jQuery._queueHooks(this, type); - - if (type === "fx" && queue[0] !== "inprogress") { - jQuery.dequeue(this, type); - } - }); - }, - dequeue: function (type) { - return this.each(function () { - jQuery.dequeue(this, type); - }); - }, - clearQueue: function (type) { - return this.queue(type || "fx", []); - }, - - // Get a promise resolved when queues of a certain type - // are emptied (fx is the type by default) - promise: function (type, obj) { - var tmp, - count = 1, - defer = jQuery.Deferred(), - elements = this, - i = this.length, - resolve = function () { - if (!(--count)) { - defer.resolveWith(elements, [elements]); - } - }; - - if (typeof type !== "string") { - obj = type; - type = undefined; - } - type = type || "fx"; - - while (i--) { - tmp = dataPriv.get(elements[i], type + "queueHooks"); - if (tmp && tmp.empty) { - count++; - tmp.empty.add(resolve); - } - } - resolve(); - return defer.promise(obj); - } - }); - var pnum = (/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/).source; - - var rcssNum = new RegExp("^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i"); - - - var cssExpand = ["Top", "Right", "Bottom", "Left"]; - - var isHiddenWithinTree = function (elem, el) { - - // isHiddenWithinTree might be called from jQuery#filter function; - // in that case, element will be second argument - elem = el || elem; - - // Inline style trumps all - return elem.style.display === "none" || - elem.style.display === "" && - - // Otherwise, check computed style - // Support: Firefox <=43 - 45 - // Disconnected elements can have computed display: none, so first confirm that elem is - // in the document. - jQuery.contains(elem.ownerDocument, elem) && - - jQuery.css(elem, "display") === "none"; - }; - - var swap = function (elem, options, callback, args) { - var ret, name, - old = {}; - - // Remember the old values, and insert the new ones - for (name in options) { - old[name] = elem.style[name]; - elem.style[name] = options[name]; - } - - ret = callback.apply(elem, args || []); - - // Revert the old values - for (name in options) { - elem.style[name] = old[name]; - } - - return ret; - }; - - - function adjustCSS(elem, prop, valueParts, tween) { - var adjusted, scale, - maxIterations = 20, - currentValue = tween ? - function () { - return tween.cur(); - } : - function () { - return jQuery.css(elem, prop, ""); - }, - initial = currentValue(), - unit = valueParts && valueParts[3] || (jQuery.cssNumber[prop] ? "" : "px"), - - // Starting value computation is required for potential unit mismatches - initialInUnit = (jQuery.cssNumber[prop] || unit !== "px" && +initial) && - rcssNum.exec(jQuery.css(elem, prop)); - - if (initialInUnit && initialInUnit[3] !== unit) { - - // Support: Firefox <=54 - // Halve the iteration target value to prevent interference from CSS upper bounds (gh-2144) - initial = initial / 2; - - // Trust units reported by jQuery.css - unit = unit || initialInUnit[3]; - - // Iteratively approximate from a nonzero starting point - initialInUnit = +initial || 1; - - while (maxIterations--) { - - // Evaluate and update our best guess (doubling guesses that zero out). - // Finish if the scale equals or crosses 1 (making the old*new product non-positive). - jQuery.style(elem, prop, initialInUnit + unit); - if ((1 - scale) * (1 - (scale = currentValue() / initial || 0.5)) <= 0) { - maxIterations = 0; - } - initialInUnit = initialInUnit / scale; - - } - - initialInUnit = initialInUnit * 2; - jQuery.style(elem, prop, initialInUnit + unit); - - // Make sure we update the tween properties later on - valueParts = valueParts || []; - } - - if (valueParts) { - initialInUnit = +initialInUnit || +initial || 0; - - // Apply relative offset (+=/-=) if specified - adjusted = valueParts[1] ? - initialInUnit + (valueParts[1] + 1) * valueParts[2] : - +valueParts[2]; - if (tween) { - tween.unit = unit; - tween.start = initialInUnit; - tween.end = adjusted; - } - } - return adjusted; - } - - - var defaultDisplayMap = {}; - - function getDefaultDisplay(elem) { - var temp, - doc = elem.ownerDocument, - nodeName = elem.nodeName, - display = defaultDisplayMap[nodeName]; - - if (display) { - return display; - } - - temp = doc.body.appendChild(doc.createElement(nodeName)); - display = jQuery.css(temp, "display"); - - temp.parentNode.removeChild(temp); - - if (display === "none") { - display = "block"; - } - defaultDisplayMap[nodeName] = display; - - return display; - } - - function showHide(elements, show) { - var display, elem, - values = [], - index = 0, - length = elements.length; - - // Determine new display value for elements that need to change - for (; index < length; index++) { - elem = elements[index]; - if (!elem.style) { - continue; - } - - display = elem.style.display; - if (show) { - - // Since we force visibility upon cascade-hidden elements, an immediate (and slow) - // check is required in this first loop unless we have a nonempty display value (either - // inline or about-to-be-restored) - if (display === "none") { - values[index] = dataPriv.get(elem, "display") || null; - if (!values[index]) { - elem.style.display = ""; - } - } - if (elem.style.display === "" && isHiddenWithinTree(elem)) { - values[index] = getDefaultDisplay(elem); - } - } else { - if (display !== "none") { - values[index] = "none"; - - // Remember what we're overwriting - dataPriv.set(elem, "display", display); - } - } - } - - // Set the display of the elements in a second loop to avoid constant reflow - for (index = 0; index < length; index++) { - if (values[index] != null) { - elements[index].style.display = values[index]; - } - } - - return elements; - } - - jQuery.fn.extend({ - show: function () { - return showHide(this, true); - }, - hide: function () { - return showHide(this); - }, - toggle: function (state) { - if (typeof state === "boolean") { - return state ? this.show() : this.hide(); - } - - return this.each(function () { - if (isHiddenWithinTree(this)) { - jQuery(this).show(); - } else { - jQuery(this).hide(); - } - }); - } - }); - var rcheckableType = (/^(?:checkbox|radio)$/i); - - var rtagName = (/<([a-z][^\/\0>\x20\t\r\n\f]+)/i); - - var rscriptType = (/^$|^module$|\/(?:java|ecma)script/i); - - - // We have to close these tags to support XHTML (#13200) - var wrapMap = { - - // Support: IE <=9 only - option: [1, ""], - - // XHTML parsers do not magically insert elements in the - // same way that tag soup parsers do. So we cannot shorten - // this by omitting or other required elements. - thead: [1, "", "
"], - col: [2, "", "
"], - tr: [2, "", "
"], - td: [3, "", "
"], - - _default: [0, "", ""] - }; - - // Support: IE <=9 only - wrapMap.optgroup = wrapMap.option; - - wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; - wrapMap.th = wrapMap.td; - - - function getAll(context, tag) { - - // Support: IE <=9 - 11 only - // Use typeof to avoid zero-argument method invocation on host objects (#15151) - var ret; - - if (typeof context.getElementsByTagName !== "undefined") { - ret = context.getElementsByTagName(tag || "*"); - - } else if (typeof context.querySelectorAll !== "undefined") { - ret = context.querySelectorAll(tag || "*"); - - } else { - ret = []; - } - - if (tag === undefined || tag && nodeName(context, tag)) { - return jQuery.merge([context], ret); - } - - return ret; - } - - - // Mark scripts as having already been evaluated - function setGlobalEval(elems, refElements) { - var i = 0, - l = elems.length; - - for (; i < l; i++) { - dataPriv.set( - elems[i], - "globalEval", - !refElements || dataPriv.get(refElements[i], "globalEval") - ); - } - } - - - var rhtml = /<|&#?\w+;/; - - function buildFragment(elems, context, scripts, selection, ignored) { - var elem, tmp, tag, wrap, contains, j, - fragment = context.createDocumentFragment(), - nodes = [], - i = 0, - l = elems.length; - - for (; i < l; i++) { - elem = elems[i]; - - if (elem || elem === 0) { - - // Add nodes directly - if (toType(elem) === "object") { - - // Support: Android <=4.0 only, PhantomJS 1 only - // push.apply(_, arraylike) throws on ancient WebKit - jQuery.merge(nodes, elem.nodeType ? [elem] : elem); - - // Convert non-html into a text node - } else if (!rhtml.test(elem)) { - nodes.push(context.createTextNode(elem)); - - // Convert html into DOM nodes - } else { - tmp = tmp || fragment.appendChild(context.createElement("div")); - - // Deserialize a standard representation - tag = (rtagName.exec(elem) || ["", ""])[1].toLowerCase(); - wrap = wrapMap[tag] || wrapMap._default; - tmp.innerHTML = wrap[1] + jQuery.htmlPrefilter(elem) + wrap[2]; - - // Descend through wrappers to the right content - j = wrap[0]; - while (j--) { - tmp = tmp.lastChild; - } - - // Support: Android <=4.0 only, PhantomJS 1 only - // push.apply(_, arraylike) throws on ancient WebKit - jQuery.merge(nodes, tmp.childNodes); - - // Remember the top-level container - tmp = fragment.firstChild; - - // Ensure the created nodes are orphaned (#12392) - tmp.textContent = ""; - } - } - } - - // Remove wrapper from fragment - fragment.textContent = ""; - - i = 0; - while ((elem = nodes[i++])) { - - // Skip elements already in the context collection (trac-4087) - if (selection && jQuery.inArray(elem, selection) > -1) { - if (ignored) { - ignored.push(elem); - } - continue; - } - - contains = jQuery.contains(elem.ownerDocument, elem); - - // Append to fragment - tmp = getAll(fragment.appendChild(elem), "script"); - - // Preserve script evaluation history - if (contains) { - setGlobalEval(tmp); - } - - // Capture executables - if (scripts) { - j = 0; - while ((elem = tmp[j++])) { - if (rscriptType.test(elem.type || "")) { - scripts.push(elem); - } - } - } - } - - return fragment; - } - - - (function () { - var fragment = document$1.createDocumentFragment(), - div = fragment.appendChild(document$1.createElement("div")), - input = document$1.createElement("input"); - - // Support: Android 4.0 - 4.3 only - // Check state lost if the name is set (#11217) - // Support: Windows Web Apps (WWA) - // `name` and `type` must use .setAttribute for WWA (#14901) - input.setAttribute("type", "radio"); - input.setAttribute("checked", "checked"); - input.setAttribute("name", "t"); - - div.appendChild(input); - - // Support: Android <=4.1 only - // Older WebKit doesn't clone checked state correctly in fragments - support.checkClone = div.cloneNode(true).cloneNode(true).lastChild.checked; - - // Support: IE <=11 only - // Make sure textarea (and checkbox) defaultValue is properly cloned - div.innerHTML = ""; - support.noCloneChecked = !!div.cloneNode(true).lastChild.defaultValue; - })(); - var documentElement = document$1.documentElement; - - - var - rkeyEvent = /^key/, - rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/, - rtypenamespace = /^([^.]*)(?:\.(.+)|)/; - - function returnTrue() { - return true; - } - - function returnFalse() { - return false; - } - - // Support: IE <=9 only - // See #13393 for more info - function safeActiveElement() { - try { - return document$1.activeElement; - } catch (err) { - } - } - - function on(elem, types, selector, data, fn, one) { - var origFn, type; - - // Types can be a map of types/handlers - if (typeof types === "object") { - - // ( types-Object, selector, data ) - if (typeof selector !== "string") { - - // ( types-Object, data ) - data = data || selector; - selector = undefined; - } - for (type in types) { - on(elem, type, selector, data, types[type], one); - } - return elem; - } - - if (data == null && fn == null) { - - // ( types, fn ) - fn = selector; - data = selector = undefined; - } else if (fn == null) { - if (typeof selector === "string") { - - // ( types, selector, fn ) - fn = data; - data = undefined; - } else { - - // ( types, data, fn ) - fn = data; - data = selector; - selector = undefined; - } - } - if (fn === false) { - fn = returnFalse; - } else if (!fn) { - return elem; - } - - if (one === 1) { - origFn = fn; - fn = function (event) { - - // Can use an empty set, since event contains the info - jQuery().off(event); - return origFn.apply(this, arguments); - }; - - // Use same guid so caller can remove using origFn - fn.guid = origFn.guid || (origFn.guid = jQuery.guid++); - } - return elem.each(function () { - jQuery.event.add(this, types, fn, data, selector); - }); - } - - /* - * Helper functions for managing events -- not part of the public interface. - * Props to Dean Edwards' addEvent library for many of the ideas. - */ - jQuery.event = { - - global: {}, - - add: function (elem, types, handler, data, selector) { - - var handleObjIn, eventHandle, tmp, - events, t, handleObj, - special, handlers, type, namespaces, origType, - elemData = dataPriv.get(elem); - - // Don't attach events to noData or text/comment nodes (but allow plain objects) - if (!elemData) { - return; - } - - // Caller can pass in an object of custom data in lieu of the handler - if (handler.handler) { - handleObjIn = handler; - handler = handleObjIn.handler; - selector = handleObjIn.selector; - } - - // Ensure that invalid selectors throw exceptions at attach time - // Evaluate against documentElement in case elem is a non-element node (e.g., document) - if (selector) { - jQuery.find.matchesSelector(documentElement, selector); - } - - // Make sure that the handler has a unique ID, used to find/remove it later - if (!handler.guid) { - handler.guid = jQuery.guid++; - } - - // Init the element's event structure and main handler, if this is the first - if (!(events = elemData.events)) { - events = elemData.events = {}; - } - if (!(eventHandle = elemData.handle)) { - eventHandle = elemData.handle = function (e) { - - // Discard the second event of a jQuery.event.trigger() and - // when an event is called after a page has unloaded - return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ? - jQuery.event.dispatch.apply(elem, arguments) : undefined; - }; - } - - // Handle multiple events separated by a space - types = (types || "").match(rnothtmlwhite) || [""]; - t = types.length; - while (t--) { - tmp = rtypenamespace.exec(types[t]) || []; - type = origType = tmp[1]; - namespaces = (tmp[2] || "").split(".").sort(); - - // There *must* be a type, no attaching namespace-only handlers - if (!type) { - continue; - } - - // If event changes its type, use the special event handlers for the changed type - special = jQuery.event.special[type] || {}; - - // If selector defined, determine special event api type, otherwise given type - type = (selector ? special.delegateType : special.bindType) || type; - - // Update special based on newly reset type - special = jQuery.event.special[type] || {}; - - // handleObj is passed to all event handlers - handleObj = jQuery.extend({ - type: type, - origType: origType, - data: data, - handler: handler, - guid: handler.guid, - selector: selector, - needsContext: selector && jQuery.expr.match.needsContext.test(selector), - namespace: namespaces.join(".") - }, handleObjIn); - - // Init the event handler queue if we're the first - if (!(handlers = events[type])) { - handlers = events[type] = []; - handlers.delegateCount = 0; - - // Only use addEventListener if the special events handler returns false - if (!special.setup || - special.setup.call(elem, data, namespaces, eventHandle) === false) { - - if (elem.addEventListener) { - elem.addEventListener(type, eventHandle); - } - } - } - - if (special.add) { - special.add.call(elem, handleObj); - - if (!handleObj.handler.guid) { - handleObj.handler.guid = handler.guid; - } - } - - // Add to the element's handler list, delegates in front - if (selector) { - handlers.splice(handlers.delegateCount++, 0, handleObj); - } else { - handlers.push(handleObj); - } - - // Keep track of which events have ever been used, for event optimization - jQuery.event.global[type] = true; - } - - }, - - // Detach an event or set of events from an element - remove: function (elem, types, handler, selector, mappedTypes) { - - var j, origCount, tmp, - events, t, handleObj, - special, handlers, type, namespaces, origType, - elemData = dataPriv.hasData(elem) && dataPriv.get(elem); - - if (!elemData || !(events = elemData.events)) { - return; - } - - // Once for each type.namespace in types; type may be omitted - types = (types || "").match(rnothtmlwhite) || [""]; - t = types.length; - while (t--) { - tmp = rtypenamespace.exec(types[t]) || []; - type = origType = tmp[1]; - namespaces = (tmp[2] || "").split(".").sort(); - - // Unbind all events (on this namespace, if provided) for the element - if (!type) { - for (type in events) { - jQuery.event.remove(elem, type + types[t], handler, selector, true); - } - continue; - } - - special = jQuery.event.special[type] || {}; - type = (selector ? special.delegateType : special.bindType) || type; - handlers = events[type] || []; - tmp = tmp[2] && - new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)"); - - // Remove matching events - origCount = j = handlers.length; - while (j--) { - handleObj = handlers[j]; - - if ((mappedTypes || origType === handleObj.origType) && - (!handler || handler.guid === handleObj.guid) && - (!tmp || tmp.test(handleObj.namespace)) && - (!selector || selector === handleObj.selector || - selector === "**" && handleObj.selector)) { - handlers.splice(j, 1); - - if (handleObj.selector) { - handlers.delegateCount--; - } - if (special.remove) { - special.remove.call(elem, handleObj); - } - } - } - - // Remove generic event handler if we removed something and no more handlers exist - // (avoids potential for endless recursion during removal of special event handlers) - if (origCount && !handlers.length) { - if (!special.teardown || - special.teardown.call(elem, namespaces, elemData.handle) === false) { - - jQuery.removeEvent(elem, type, elemData.handle); - } - - delete events[type]; - } - } - - // Remove data and the expando if it's no longer used - if (jQuery.isEmptyObject(events)) { - dataPriv.remove(elem, "handle events"); - } - }, - - dispatch: function (nativeEvent) { - - // Make a writable jQuery.Event from the native event object - var event = jQuery.event.fix(nativeEvent); - - var i, j, ret, matched, handleObj, handlerQueue, - args = new Array(arguments.length), - handlers = (dataPriv.get(this, "events") || {})[event.type] || [], - special = jQuery.event.special[event.type] || {}; - - // Use the fix-ed jQuery.Event rather than the (read-only) native event - args[0] = event; - - for (i = 1; i < arguments.length; i++) { - args[i] = arguments[i]; - } - - event.delegateTarget = this; - - // Call the preDispatch hook for the mapped type, and let it bail if desired - if (special.preDispatch && special.preDispatch.call(this, event) === false) { - return; - } - - // Determine handlers - handlerQueue = jQuery.event.handlers.call(this, event, handlers); - - // Run delegates first; they may want to stop propagation beneath us - i = 0; - while ((matched = handlerQueue[i++]) && !event.isPropagationStopped()) { - event.currentTarget = matched.elem; - - j = 0; - while ((handleObj = matched.handlers[j++]) && - !event.isImmediatePropagationStopped()) { - - // Triggered event must either 1) have no namespace, or 2) have namespace(s) - // a subset or equal to those in the bound event (both can have no namespace). - if (!event.rnamespace || event.rnamespace.test(handleObj.namespace)) { - - event.handleObj = handleObj; - event.data = handleObj.data; - - ret = ((jQuery.event.special[handleObj.origType] || {}).handle || - handleObj.handler).apply(matched.elem, args); - - if (ret !== undefined) { - if ((event.result = ret) === false) { - event.preventDefault(); - event.stopPropagation(); - } - } - } - } - } - - // Call the postDispatch hook for the mapped type - if (special.postDispatch) { - special.postDispatch.call(this, event); - } - - return event.result; - }, - - handlers: function (event, handlers) { - var i, handleObj, sel, matchedHandlers, matchedSelectors, - handlerQueue = [], - delegateCount = handlers.delegateCount, - cur = event.target; - - // Find delegate handlers - if (delegateCount && - - // Support: IE <=9 - // Black-hole SVG instance trees (trac-13180) - cur.nodeType && - - // Support: Firefox <=42 - // Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861) - // https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click - // Support: IE 11 only - // ...but not arrow key "clicks" of radio inputs, which can have `button` -1 (gh-2343) - !(event.type === "click" && event.button >= 1)) { - - for (; cur !== this; cur = cur.parentNode || this) { - - // Don't check non-elements (#13208) - // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764) - if (cur.nodeType === 1 && !(event.type === "click" && cur.disabled === true)) { - matchedHandlers = []; - matchedSelectors = {}; - for (i = 0; i < delegateCount; i++) { - handleObj = handlers[i]; - - // Don't conflict with Object.prototype properties (#13203) - sel = handleObj.selector + " "; - - if (matchedSelectors[sel] === undefined) { - matchedSelectors[sel] = handleObj.needsContext ? - jQuery(sel, this).index(cur) > -1 : - jQuery.find(sel, this, null, [cur]).length; - } - if (matchedSelectors[sel]) { - matchedHandlers.push(handleObj); - } - } - if (matchedHandlers.length) { - handlerQueue.push({elem: cur, handlers: matchedHandlers}); - } - } - } - } - - // Add the remaining (directly-bound) handlers - cur = this; - if (delegateCount < handlers.length) { - handlerQueue.push({elem: cur, handlers: handlers.slice(delegateCount)}); - } - - return handlerQueue; - }, - - addProp: function (name, hook) { - Object.defineProperty(jQuery.Event.prototype, name, { - enumerable: true, - configurable: true, - - get: isFunction(hook) ? - function () { - if (this.originalEvent) { - return hook(this.originalEvent); - } - } : - function () { - if (this.originalEvent) { - return this.originalEvent[name]; - } - }, - - set: function (value) { - Object.defineProperty(this, name, { - enumerable: true, - configurable: true, - writable: true, - value: value - }); - } - }); - }, - - fix: function (originalEvent) { - return originalEvent[jQuery.expando] ? - originalEvent : - new jQuery.Event(originalEvent); - }, - - special: { - load: { - - // Prevent triggered image.load events from bubbling to window.load - noBubble: true - }, - focus: { - - // Fire native event if possible so blur/focus sequence is correct - trigger: function () { - if (this !== safeActiveElement() && this.focus) { - this.focus(); - return false; - } - }, - delegateType: "focusin" - }, - blur: { - trigger: function () { - if (this === safeActiveElement() && this.blur) { - this.blur(); - return false; - } - }, - delegateType: "focusout" - }, - click: { - - // For checkbox, fire native event so checked state will be right - trigger: function () { - if (this.type === "checkbox" && this.click && nodeName(this, "input")) { - this.click(); - return false; - } - }, - - // For cross-browser consistency, don't fire native .click() on links - _default: function (event) { - return nodeName(event.target, "a"); - } - }, - - beforeunload: { - postDispatch: function (event) { - - // Support: Firefox 20+ - // Firefox doesn't alert if the returnValue field is not set. - if (event.result !== undefined && event.originalEvent) { - event.originalEvent.returnValue = event.result; - } - } - } - } - }; - - jQuery.removeEvent = function (elem, type, handle) { - - // This "if" is needed for plain objects - if (elem.removeEventListener) { - elem.removeEventListener(type, handle); - } - }; - - jQuery.Event = function (src, props) { - - // Allow instantiation without the 'new' keyword - if (!(this instanceof jQuery.Event)) { - return new jQuery.Event(src, props); - } - - // Event object - if (src && src.type) { - this.originalEvent = src; - this.type = src.type; - - // Events bubbling up the document may have been marked as prevented - // by a handler lower down the tree; reflect the correct value. - this.isDefaultPrevented = src.defaultPrevented || - src.defaultPrevented === undefined && - - // Support: Android <=2.3 only - src.returnValue === false ? - returnTrue : - returnFalse; - - // Create target properties - // Support: Safari <=6 - 7 only - // Target should not be a text node (#504, #13143) - this.target = (src.target && src.target.nodeType === 3) ? - src.target.parentNode : - src.target; - - this.currentTarget = src.currentTarget; - this.relatedTarget = src.relatedTarget; - - // Event type - } else { - this.type = src; - } - - // Put explicitly provided properties onto the event object - if (props) { - jQuery.extend(this, props); - } - - // Create a timestamp if incoming event doesn't have one - this.timeStamp = src && src.timeStamp || Date.now(); - - // Mark it as fixed - this[jQuery.expando] = true; - }; - - // jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding - // https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html - jQuery.Event.prototype = { - constructor: jQuery.Event, - isDefaultPrevented: returnFalse, - isPropagationStopped: returnFalse, - isImmediatePropagationStopped: returnFalse, - isSimulated: false, - - preventDefault: function () { - var e = this.originalEvent; - - this.isDefaultPrevented = returnTrue; - - if (e && !this.isSimulated) { - e.preventDefault(); - } - }, - stopPropagation: function () { - var e = this.originalEvent; - - this.isPropagationStopped = returnTrue; - - if (e && !this.isSimulated) { - e.stopPropagation(); - } - }, - stopImmediatePropagation: function () { - var e = this.originalEvent; - - this.isImmediatePropagationStopped = returnTrue; - - if (e && !this.isSimulated) { - e.stopImmediatePropagation(); - } - - this.stopPropagation(); - } - }; - - // Includes all common event props including KeyEvent and MouseEvent specific props - jQuery.each({ - altKey: true, - bubbles: true, - cancelable: true, - changedTouches: true, - ctrlKey: true, - detail: true, - eventPhase: true, - metaKey: true, - pageX: true, - pageY: true, - shiftKey: true, - view: true, - "char": true, - charCode: true, - key: true, - keyCode: true, - button: true, - buttons: true, - clientX: true, - clientY: true, - offsetX: true, - offsetY: true, - pointerId: true, - pointerType: true, - screenX: true, - screenY: true, - targetTouches: true, - toElement: true, - touches: true, - - which: function (event) { - var button = event.button; - - // Add which for key events - if (event.which == null && rkeyEvent.test(event.type)) { - return event.charCode != null ? event.charCode : event.keyCode; - } - - // Add which for click: 1 === left; 2 === middle; 3 === right - if (!event.which && button !== undefined && rmouseEvent.test(event.type)) { - if (button & 1) { - return 1; - } - - if (button & 2) { - return 3; - } - - if (button & 4) { - return 2; - } - - return 0; - } - - return event.which; - } - }, jQuery.event.addProp); - - // Create mouseenter/leave events using mouseover/out and event-time checks - // so that event delegation works in jQuery. - // Do the same for pointerenter/pointerleave and pointerover/pointerout - // - // Support: Safari 7 only - // Safari sends mouseenter too often; see: - // https://bugs.chromium.org/p/chromium/issues/detail?id=470258 - // for the description of the bug (it existed in older Chrome versions as well). - jQuery.each({ - mouseenter: "mouseover", - mouseleave: "mouseout", - pointerenter: "pointerover", - pointerleave: "pointerout" - }, function (orig, fix) { - jQuery.event.special[orig] = { - delegateType: fix, - bindType: fix, - - handle: function (event) { - var ret, - target = this, - related = event.relatedTarget, - handleObj = event.handleObj; - - // For mouseenter/leave call the handler if related is outside the target. - // NB: No relatedTarget if the mouse left/entered the browser window - if (!related || (related !== target && !jQuery.contains(target, related))) { - event.type = handleObj.origType; - ret = handleObj.handler.apply(this, arguments); - event.type = fix; - } - return ret; - } - }; - }); - - jQuery.fn.extend({ - - on: function (types, selector, data, fn) { - return on(this, types, selector, data, fn); - }, - one: function (types, selector, data, fn) { - return on(this, types, selector, data, fn, 1); - }, - off: function (types, selector, fn) { - var handleObj, type; - if (types && types.preventDefault && types.handleObj) { - - // ( event ) dispatched jQuery.Event - handleObj = types.handleObj; - jQuery(types.delegateTarget).off( - handleObj.namespace ? - handleObj.origType + "." + handleObj.namespace : - handleObj.origType, - handleObj.selector, - handleObj.handler - ); - return this; - } - if (typeof types === "object") { - - // ( types-object [, selector] ) - for (type in types) { - this.off(type, selector, types[type]); - } - return this; - } - if (selector === false || typeof selector === "function") { - - // ( types [, fn] ) - fn = selector; - selector = undefined; - } - if (fn === false) { - fn = returnFalse; - } - return this.each(function () { - jQuery.event.remove(this, types, fn, selector); - }); - } - }); - - - var - - /* eslint-disable max-len */ - - // See https://github.com/eslint/eslint/issues/3229 - rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi, - - /* eslint-enable */ - - // Support: IE <=10 - 11, Edge 12 - 13 only - // In IE/Edge using regex groups here causes severe slowdowns. - // See https://connect.microsoft.com/IE/feedback/details/1736512/ - rnoInnerhtml = /\s*$/g; - - // Prefer a tbody over its parent table for containing new rows - function manipulationTarget(elem, content) { - if (nodeName(elem, "table") && - nodeName(content.nodeType !== 11 ? content : content.firstChild, "tr")) { - - return jQuery(elem).children("tbody")[0] || elem; - } - - return elem; - } - - // Replace/restore the type attribute of script elements for safe DOM manipulation - function disableScript(elem) { - elem.type = (elem.getAttribute("type") !== null) + "/" + elem.type; - return elem; - } - - function restoreScript(elem) { - if ((elem.type || "").slice(0, 5) === "true/") { - elem.type = elem.type.slice(5); - } else { - elem.removeAttribute("type"); - } - - return elem; - } - - function cloneCopyEvent(src, dest) { - var i, l, type, pdataOld, pdataCur, udataOld, udataCur, events; - - if (dest.nodeType !== 1) { - return; - } - - // 1. Copy private data: events, handlers, etc. - if (dataPriv.hasData(src)) { - pdataOld = dataPriv.access(src); - pdataCur = dataPriv.set(dest, pdataOld); - events = pdataOld.events; - - if (events) { - delete pdataCur.handle; - pdataCur.events = {}; - - for (type in events) { - for (i = 0, l = events[type].length; i < l; i++) { - jQuery.event.add(dest, type, events[type][i]); - } - } - } - } - - // 2. Copy user data - if (dataUser.hasData(src)) { - udataOld = dataUser.access(src); - udataCur = jQuery.extend({}, udataOld); - - dataUser.set(dest, udataCur); - } - } - - // Fix IE bugs, see support tests - function fixInput(src, dest) { - var nodeName = dest.nodeName.toLowerCase(); - - // Fails to persist the checked state of a cloned checkbox or radio button. - if (nodeName === "input" && rcheckableType.test(src.type)) { - dest.checked = src.checked; - - // Fails to return the selected option to the default selected state when cloning options - } else if (nodeName === "input" || nodeName === "textarea") { - dest.defaultValue = src.defaultValue; - } - } - - function domManip(collection, args, callback, ignored) { - - // Flatten any nested arrays - args = concat.apply([], args); - - var fragment, first, scripts, hasScripts, node, doc, - i = 0, - l = collection.length, - iNoClone = l - 1, - value = args[0], - valueIsFunction = isFunction(value); - - // We can't cloneNode fragments that contain checked, in WebKit - if (valueIsFunction || - (l > 1 && typeof value === "string" && - !support.checkClone && rchecked.test(value))) { - return collection.each(function (index) { - var self = collection.eq(index); - if (valueIsFunction) { - args[0] = value.call(this, index, self.html()); - } - domManip(self, args, callback, ignored); - }); - } - - if (l) { - fragment = buildFragment(args, collection[0].ownerDocument, false, collection, ignored); - first = fragment.firstChild; - - if (fragment.childNodes.length === 1) { - fragment = first; - } - - // Require either new content or an interest in ignored elements to invoke the callback - if (first || ignored) { - scripts = jQuery.map(getAll(fragment, "script"), disableScript); - hasScripts = scripts.length; - - // Use the original fragment for the last item - // instead of the first because it can end up - // being emptied incorrectly in certain situations (#8070). - for (; i < l; i++) { - node = fragment; - - if (i !== iNoClone) { - node = jQuery.clone(node, true, true); - - // Keep references to cloned scripts for later restoration - if (hasScripts) { - - // Support: Android <=4.0 only, PhantomJS 1 only - // push.apply(_, arraylike) throws on ancient WebKit - jQuery.merge(scripts, getAll(node, "script")); - } - } - - callback.call(collection[i], node, i); - } - - if (hasScripts) { - doc = scripts[scripts.length - 1].ownerDocument; - - // Reenable scripts - jQuery.map(scripts, restoreScript); - - // Evaluate executable scripts on first document insertion - for (i = 0; i < hasScripts; i++) { - node = scripts[i]; - if (rscriptType.test(node.type || "") && - !dataPriv.access(node, "globalEval") && - jQuery.contains(doc, node)) { - - if (node.src && (node.type || "").toLowerCase() !== "module") { - - // Optional AJAX dependency, but won't run scripts if not present - if (jQuery._evalUrl) { - jQuery._evalUrl(node.src); - } - } else { - DOMEval(node.textContent.replace(rcleanScript, ""), doc, node); - } - } - } - } - } - } - - return collection; - } - - function remove(elem, selector, keepData) { - var node, - nodes = selector ? jQuery.filter(selector, elem) : elem, - i = 0; - - for (; (node = nodes[i]) != null; i++) { - if (!keepData && node.nodeType === 1) { - jQuery.cleanData(getAll(node)); - } - - if (node.parentNode) { - if (keepData && jQuery.contains(node.ownerDocument, node)) { - setGlobalEval(getAll(node, "script")); - } - node.parentNode.removeChild(node); - } - } - - return elem; - } - - jQuery.extend({ - htmlPrefilter: function (html) { - return html.replace(rxhtmlTag, "<$1>"); - }, - - clone: function (elem, dataAndEvents, deepDataAndEvents) { - var i, l, srcElements, destElements, - clone = elem.cloneNode(true), - inPage = jQuery.contains(elem.ownerDocument, elem); - - // Fix IE cloning issues - if (!support.noCloneChecked && (elem.nodeType === 1 || elem.nodeType === 11) && - !jQuery.isXMLDoc(elem)) { - - // We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/2 - destElements = getAll(clone); - srcElements = getAll(elem); - - for (i = 0, l = srcElements.length; i < l; i++) { - fixInput(srcElements[i], destElements[i]); - } - } - - // Copy the events from the original to the clone - if (dataAndEvents) { - if (deepDataAndEvents) { - srcElements = srcElements || getAll(elem); - destElements = destElements || getAll(clone); - - for (i = 0, l = srcElements.length; i < l; i++) { - cloneCopyEvent(srcElements[i], destElements[i]); - } - } else { - cloneCopyEvent(elem, clone); - } - } - - // Preserve script evaluation history - destElements = getAll(clone, "script"); - if (destElements.length > 0) { - setGlobalEval(destElements, !inPage && getAll(elem, "script")); - } - - // Return the cloned set - return clone; - }, - - cleanData: function (elems) { - var data, elem, type, - special = jQuery.event.special, - i = 0; - - for (; (elem = elems[i]) !== undefined; i++) { - if (acceptData(elem)) { - if ((data = elem[dataPriv.expando])) { - if (data.events) { - for (type in data.events) { - if (special[type]) { - jQuery.event.remove(elem, type); - - // This is a shortcut to avoid jQuery.event.remove's overhead - } else { - jQuery.removeEvent(elem, type, data.handle); - } - } - } - - // Support: Chrome <=35 - 45+ - // Assign undefined instead of using delete, see Data#remove - elem[dataPriv.expando] = undefined; - } - if (elem[dataUser.expando]) { - - // Support: Chrome <=35 - 45+ - // Assign undefined instead of using delete, see Data#remove - elem[dataUser.expando] = undefined; - } - } - } - } - }); - - jQuery.fn.extend({ - detach: function (selector) { - return remove(this, selector, true); - }, - - remove: function (selector) { - return remove(this, selector); - }, - - text: function (value) { - return access(this, function (value) { - return value === undefined ? - jQuery.text(this) : - this.empty().each(function () { - if (this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9) { - this.textContent = value; - } - }); - }, null, value, arguments.length); - }, - - append: function () { - return domManip(this, arguments, function (elem) { - if (this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9) { - var target = manipulationTarget(this, elem); - target.appendChild(elem); - } - }); - }, - - prepend: function () { - return domManip(this, arguments, function (elem) { - if (this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9) { - var target = manipulationTarget(this, elem); - target.insertBefore(elem, target.firstChild); - } - }); - }, - - before: function () { - return domManip(this, arguments, function (elem) { - if (this.parentNode) { - this.parentNode.insertBefore(elem, this); - } - }); - }, - - after: function () { - return domManip(this, arguments, function (elem) { - if (this.parentNode) { - this.parentNode.insertBefore(elem, this.nextSibling); - } - }); - }, - - empty: function () { - var elem, - i = 0; - - for (; (elem = this[i]) != null; i++) { - if (elem.nodeType === 1) { - - // Prevent memory leaks - jQuery.cleanData(getAll(elem, false)); - - // Remove any remaining nodes - elem.textContent = ""; - } - } - - return this; - }, - - clone: function (dataAndEvents, deepDataAndEvents) { - dataAndEvents = dataAndEvents == null ? false : dataAndEvents; - deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; - - return this.map(function () { - return jQuery.clone(this, dataAndEvents, deepDataAndEvents); - }); - }, - - html: function (value) { - return access(this, function (value) { - var elem = this[0] || {}, - i = 0, - l = this.length; - - if (value === undefined && elem.nodeType === 1) { - return elem.innerHTML; - } - - // See if we can take a shortcut and just use innerHTML - if (typeof value === "string" && !rnoInnerhtml.test(value) && - !wrapMap[(rtagName.exec(value) || ["", ""])[1].toLowerCase()]) { - - value = jQuery.htmlPrefilter(value); - - try { - for (; i < l; i++) { - elem = this[i] || {}; - - // Remove element nodes and prevent memory leaks - if (elem.nodeType === 1) { - jQuery.cleanData(getAll(elem, false)); - elem.innerHTML = value; - } - } - - elem = 0; - - // If using innerHTML throws an exception, use the fallback method - } catch (e) { - } - } - - if (elem) { - this.empty().append(value); - } - }, null, value, arguments.length); - }, - - replaceWith: function () { - var ignored = []; - - // Make the changes, replacing each non-ignored context element with the new content - return domManip(this, arguments, function (elem) { - var parent = this.parentNode; - - if (jQuery.inArray(this, ignored) < 0) { - jQuery.cleanData(getAll(this)); - if (parent) { - parent.replaceChild(elem, this); - } - } - - // Force callback invocation - }, ignored); - } - }); - - jQuery.each({ - appendTo: "append", - prependTo: "prepend", - insertBefore: "before", - insertAfter: "after", - replaceAll: "replaceWith" - }, function (name, original) { - jQuery.fn[name] = function (selector) { - var elems, - ret = [], - insert = jQuery(selector), - last = insert.length - 1, - i = 0; - - for (; i <= last; i++) { - elems = i === last ? this : this.clone(true); - jQuery(insert[i])[original](elems); - - // Support: Android <=4.0 only, PhantomJS 1 only - // .get() because push.apply(_, arraylike) throws on ancient WebKit - push.apply(ret, elems.get()); - } - - return this.pushStack(ret); - }; - }); - var rnumnonpx = new RegExp("^(" + pnum + ")(?!px)[a-z%]+$", "i"); - - var getStyles = function (elem) { - - // Support: IE <=11 only, Firefox <=30 (#15098, #14150) - // IE throws on elements created in popups - // FF meanwhile throws on frame elements through "defaultView.getComputedStyle" - var view = elem.ownerDocument.defaultView; - - if (!view || !view.opener) { - view = window; - } - - return view.getComputedStyle(elem); - }; - - var rboxStyle = new RegExp(cssExpand.join("|"), "i"); - - - (function () { - - // Executing both pixelPosition & boxSizingReliable tests require only one layout - // so they're executed at the same time to save the second computation. - function computeStyleTests() { - - // This is a singleton, we need to execute it only once - if (!div) { - return; - } - - container.style.cssText = "position:absolute;left:-11111px;width:60px;" + - "margin-top:1px;padding:0;border:0"; - div.style.cssText = - "position:relative;display:block;box-sizing:border-box;overflow:scroll;" + - "margin:auto;border:1px;padding:1px;" + - "width:60%;top:1%"; - documentElement.appendChild(container).appendChild(div); - - var divStyle = window.getComputedStyle(div); - pixelPositionVal = divStyle.top !== "1%"; - - // Support: Android 4.0 - 4.3 only, Firefox <=3 - 44 - reliableMarginLeftVal = roundPixelMeasures(divStyle.marginLeft) === 12; - - // Support: Android 4.0 - 4.3 only, Safari <=9.1 - 10.1, iOS <=7.0 - 9.3 - // Some styles come back with percentage values, even though they shouldn't - div.style.right = "60%"; - pixelBoxStylesVal = roundPixelMeasures(divStyle.right) === 36; - - // Support: IE 9 - 11 only - // Detect misreporting of content dimensions for box-sizing:border-box elements - boxSizingReliableVal = roundPixelMeasures(divStyle.width) === 36; - - // Support: IE 9 only - // Detect overflow:scroll screwiness (gh-3699) - div.style.position = "absolute"; - scrollboxSizeVal = div.offsetWidth === 36 || "absolute"; - - documentElement.removeChild(container); - - // Nullify the div so it wouldn't be stored in the memory and - // it will also be a sign that checks already performed - div = null; - } - - function roundPixelMeasures(measure) { - return Math.round(parseFloat(measure)); - } - - var pixelPositionVal, boxSizingReliableVal, scrollboxSizeVal, pixelBoxStylesVal, - reliableMarginLeftVal, - container = document$1.createElement("div"), - div = document$1.createElement("div"); - - // Finish early in limited (non-browser) environments - if (!div.style) { - return; - } - - // Support: IE <=9 - 11 only - // Style of cloned element affects source element cloned (#8908) - div.style.backgroundClip = "content-box"; - div.cloneNode(true).style.backgroundClip = ""; - support.clearCloneStyle = div.style.backgroundClip === "content-box"; - - jQuery.extend(support, { - boxSizingReliable: function () { - computeStyleTests(); - return boxSizingReliableVal; - }, - pixelBoxStyles: function () { - computeStyleTests(); - return pixelBoxStylesVal; - }, - pixelPosition: function () { - computeStyleTests(); - return pixelPositionVal; - }, - reliableMarginLeft: function () { - computeStyleTests(); - return reliableMarginLeftVal; - }, - scrollboxSize: function () { - computeStyleTests(); - return scrollboxSizeVal; - } - }); - })(); - - - function curCSS(elem, name, computed) { - var width, minWidth, maxWidth, ret, - - // Support: Firefox 51+ - // Retrieving style before computed somehow - // fixes an issue with getting wrong values - // on detached elements - style = elem.style; - - computed = computed || getStyles(elem); - - // getPropertyValue is needed for: - // .css('filter') (IE 9 only, #12537) - // .css('--customProperty) (#3144) - if (computed) { - ret = computed.getPropertyValue(name) || computed[name]; - - if (ret === "" && !jQuery.contains(elem.ownerDocument, elem)) { - ret = jQuery.style(elem, name); - } - - // A tribute to the "awesome hack by Dean Edwards" - // Android Browser returns percentage for some values, - // but width seems to be reliably pixels. - // This is against the CSSOM draft spec: - // https://drafts.csswg.org/cssom/#resolved-values - if (!support.pixelBoxStyles() && rnumnonpx.test(ret) && rboxStyle.test(name)) { - - // Remember the original values - width = style.width; - minWidth = style.minWidth; - maxWidth = style.maxWidth; - - // Put in the new values to get a computed value out - style.minWidth = style.maxWidth = style.width = ret; - ret = computed.width; - - // Revert the changed values - style.width = width; - style.minWidth = minWidth; - style.maxWidth = maxWidth; - } - } - - return ret !== undefined ? - - // Support: IE <=9 - 11 only - // IE returns zIndex value as an integer. - ret + "" : - ret; - } - - - function addGetHookIf(conditionFn, hookFn) { - - // Define the hook, we'll check on the first run if it's really needed. - return { - get: function () { - if (conditionFn()) { - - // Hook not needed (or it's not possible to use it due - // to missing dependency), remove it. - delete this.get; - return; - } - - // Hook needed; redefine it so that the support test is not executed again. - return (this.get = hookFn).apply(this, arguments); - } - }; - } - - - var - - // Swappable if display is none or starts with table - // except "table", "table-cell", or "table-caption" - // See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display - rdisplayswap = /^(none|table(?!-c[ea]).+)/, - rcustomProp = /^--/, - cssShow = {position: "absolute", visibility: "hidden", display: "block"}, - cssNormalTransform = { - letterSpacing: "0", - fontWeight: "400" - }, - - cssPrefixes = ["Webkit", "Moz", "ms"], - emptyStyle = document$1.createElement("div").style; - - // Return a css property mapped to a potentially vendor prefixed property - function vendorPropName(name) { - - // Shortcut for names that are not vendor prefixed - if (name in emptyStyle) { - return name; - } - - // Check for vendor prefixed names - var capName = name[0].toUpperCase() + name.slice(1), - i = cssPrefixes.length; - - while (i--) { - name = cssPrefixes[i] + capName; - if (name in emptyStyle) { - return name; - } - } - } - - // Return a property mapped along what jQuery.cssProps suggests or to - // a vendor prefixed property. - function finalPropName(name) { - var ret = jQuery.cssProps[name]; - if (!ret) { - ret = jQuery.cssProps[name] = vendorPropName(name) || name; - } - return ret; - } - - function setPositiveNumber(elem, value, subtract) { - - // Any relative (+/-) values have already been - // normalized at this point - var matches = rcssNum.exec(value); - return matches ? - - // Guard against undefined "subtract", e.g., when used as in cssHooks - Math.max(0, matches[2] - (subtract || 0)) + (matches[3] || "px") : - value; - } - - function boxModelAdjustment(elem, dimension, box, isBorderBox, styles, computedVal) { - var i = dimension === "width" ? 1 : 0, - extra = 0, - delta = 0; - - // Adjustment may not be necessary - if (box === (isBorderBox ? "border" : "content")) { - return 0; - } - - for (; i < 4; i += 2) { - - // Both box models exclude margin - if (box === "margin") { - delta += jQuery.css(elem, box + cssExpand[i], true, styles); - } - - // If we get here with a content-box, we're seeking "padding" or "border" or "margin" - if (!isBorderBox) { - - // Add padding - delta += jQuery.css(elem, "padding" + cssExpand[i], true, styles); - - // For "border" or "margin", add border - if (box !== "padding") { - delta += jQuery.css(elem, "border" + cssExpand[i] + "Width", true, styles); - - // But still keep track of it otherwise - } else { - extra += jQuery.css(elem, "border" + cssExpand[i] + "Width", true, styles); - } - - // If we get here with a border-box (content + padding + border), we're seeking "content" or - // "padding" or "margin" - } else { - - // For "content", subtract padding - if (box === "content") { - delta -= jQuery.css(elem, "padding" + cssExpand[i], true, styles); - } - - // For "content" or "padding", subtract border - if (box !== "margin") { - delta -= jQuery.css(elem, "border" + cssExpand[i] + "Width", true, styles); - } - } - } - - // Account for positive content-box scroll gutter when requested by providing computedVal - if (!isBorderBox && computedVal >= 0) { - - // offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border - // Assuming integer scroll gutter, subtract the rest and round down - delta += Math.max(0, Math.ceil( - elem["offset" + dimension[0].toUpperCase() + dimension.slice(1)] - - computedVal - - delta - - extra - - 0.5 - )); - } - - return delta; - } - - function getWidthOrHeight(elem, dimension, extra) { - - // Start with computed style - var styles = getStyles(elem), - val = curCSS(elem, dimension, styles), - isBorderBox = jQuery.css(elem, "boxSizing", false, styles) === "border-box", - valueIsBorderBox = isBorderBox; - - // Support: Firefox <=54 - // Return a confounding non-pixel value or feign ignorance, as appropriate. - if (rnumnonpx.test(val)) { - if (!extra) { - return val; - } - val = "auto"; - } - - // Check for style in case a browser which returns unreliable values - // for getComputedStyle silently falls back to the reliable elem.style - valueIsBorderBox = valueIsBorderBox && - (support.boxSizingReliable() || val === elem.style[dimension]); - - // Fall back to offsetWidth/offsetHeight when value is "auto" - // This happens for inline elements with no explicit setting (gh-3571) - // Support: Android <=4.1 - 4.3 only - // Also use offsetWidth/offsetHeight for misreported inline dimensions (gh-3602) - if (val === "auto" || - !parseFloat(val) && jQuery.css(elem, "display", false, styles) === "inline") { - - val = elem["offset" + dimension[0].toUpperCase() + dimension.slice(1)]; - - // offsetWidth/offsetHeight provide border-box values - valueIsBorderBox = true; - } - - // Normalize "" and auto - val = parseFloat(val) || 0; - - // Adjust for the element's box model - return (val + - boxModelAdjustment( - elem, - dimension, - extra || (isBorderBox ? "border" : "content"), - valueIsBorderBox, - styles, - - // Provide the current computed size to request scroll gutter calculation (gh-3589) - val - ) - ) + "px"; - } - - jQuery.extend({ - - // Add in style property hooks for overriding the default - // behavior of getting and setting a style property - cssHooks: { - opacity: { - get: function (elem, computed) { - if (computed) { - - // We should always get a number back from opacity - var ret = curCSS(elem, "opacity"); - return ret === "" ? "1" : ret; - } - } - } - }, - - // Don't automatically add "px" to these possibly-unitless properties - cssNumber: { - "animationIterationCount": true, - "columnCount": true, - "fillOpacity": true, - "flexGrow": true, - "flexShrink": true, - "fontWeight": true, - "lineHeight": true, - "opacity": true, - "order": true, - "orphans": true, - "widows": true, - "zIndex": true, - "zoom": true - }, - - // Add in properties whose names you wish to fix before - // setting or getting the value - cssProps: {}, - - // Get and set the style property on a DOM Node - style: function (elem, name, value, extra) { - - // Don't set styles on text and comment nodes - if (!elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style) { - return; - } - - // Make sure that we're working with the right name - var ret, type, hooks, - origName = camelCase(name), - isCustomProp = rcustomProp.test(name), - style = elem.style; - - // Make sure that we're working with the right name. We don't - // want to query the value if it is a CSS custom property - // since they are user-defined. - if (!isCustomProp) { - name = finalPropName(origName); - } - - // Gets hook for the prefixed version, then unprefixed version - hooks = jQuery.cssHooks[name] || jQuery.cssHooks[origName]; - - // Check if we're setting a value - if (value !== undefined) { - type = typeof value; - - // Convert "+=" or "-=" to relative numbers (#7345) - if (type === "string" && (ret = rcssNum.exec(value)) && ret[1]) { - value = adjustCSS(elem, name, ret); - - // Fixes bug #9237 - type = "number"; - } - - // Make sure that null and NaN values aren't set (#7116) - if (value == null || value !== value) { - return; - } - - // If a number was passed in, add the unit (except for certain CSS properties) - if (type === "number") { - value += ret && ret[3] || (jQuery.cssNumber[origName] ? "" : "px"); - } - - // background-* props affect original clone's values - if (!support.clearCloneStyle && value === "" && name.indexOf("background") === 0) { - style[name] = "inherit"; - } - - // If a hook was provided, use that value, otherwise just set the specified value - if (!hooks || !("set" in hooks) || - (value = hooks.set(elem, value, extra)) !== undefined) { - - if (isCustomProp) { - style.setProperty(name, value); - } else { - style[name] = value; - } - } - - } else { - - // If a hook was provided get the non-computed value from there - if (hooks && "get" in hooks && - (ret = hooks.get(elem, false, extra)) !== undefined) { - - return ret; - } - - // Otherwise just get the value from the style object - return style[name]; - } - }, - - css: function (elem, name, extra, styles) { - var val, num, hooks, - origName = camelCase(name), - isCustomProp = rcustomProp.test(name); - - // Make sure that we're working with the right name. We don't - // want to modify the value if it is a CSS custom property - // since they are user-defined. - if (!isCustomProp) { - name = finalPropName(origName); - } - - // Try prefixed name followed by the unprefixed name - hooks = jQuery.cssHooks[name] || jQuery.cssHooks[origName]; - - // If a hook was provided get the computed value from there - if (hooks && "get" in hooks) { - val = hooks.get(elem, true, extra); - } - - // Otherwise, if a way to get the computed value exists, use that - if (val === undefined) { - val = curCSS(elem, name, styles); - } - - // Convert "normal" to computed value - if (val === "normal" && name in cssNormalTransform) { - val = cssNormalTransform[name]; - } - - // Make numeric if forced or a qualifier was provided and val looks numeric - if (extra === "" || extra) { - num = parseFloat(val); - return extra === true || isFinite(num) ? num || 0 : val; - } - - return val; - } - }); - - jQuery.each(["height", "width"], function (i, dimension) { - jQuery.cssHooks[dimension] = { - get: function (elem, computed, extra) { - if (computed) { - - // Certain elements can have dimension info if we invisibly show them - // but it must have a current display style that would benefit - return rdisplayswap.test(jQuery.css(elem, "display")) && - - // Support: Safari 8+ - // Table columns in Safari have non-zero offsetWidth & zero - // getBoundingClientRect().width unless display is changed. - // Support: IE <=11 only - // Running getBoundingClientRect on a disconnected node - // in IE throws an error. - (!elem.getClientRects().length || !elem.getBoundingClientRect().width) ? - swap(elem, cssShow, function () { - return getWidthOrHeight(elem, dimension, extra); - }) : - getWidthOrHeight(elem, dimension, extra); - } - }, - - set: function (elem, value, extra) { - var matches, - styles = getStyles(elem), - isBorderBox = jQuery.css(elem, "boxSizing", false, styles) === "border-box", - subtract = extra && boxModelAdjustment( - elem, - dimension, - extra, - isBorderBox, - styles - ); - - // Account for unreliable border-box dimensions by comparing offset* to computed and - // faking a content-box to get border and padding (gh-3699) - if (isBorderBox && support.scrollboxSize() === styles.position) { - subtract -= Math.ceil( - elem["offset" + dimension[0].toUpperCase() + dimension.slice(1)] - - parseFloat(styles[dimension]) - - boxModelAdjustment(elem, dimension, "border", false, styles) - - 0.5 - ); - } - - // Convert to pixels if value adjustment is needed - if (subtract && (matches = rcssNum.exec(value)) && - (matches[3] || "px") !== "px") { - - elem.style[dimension] = value; - value = jQuery.css(elem, dimension); - } - - return setPositiveNumber(elem, value, subtract); - } - }; - }); - - jQuery.cssHooks.marginLeft = addGetHookIf(support.reliableMarginLeft, - function (elem, computed) { - if (computed) { - return (parseFloat(curCSS(elem, "marginLeft")) || - elem.getBoundingClientRect().left - - swap(elem, {marginLeft: 0}, function () { - return elem.getBoundingClientRect().left; - }) - ) + "px"; - } - } - ); - - // These hooks are used by animate to expand properties - jQuery.each({ - margin: "", - padding: "", - border: "Width" - }, function (prefix, suffix) { - jQuery.cssHooks[prefix + suffix] = { - expand: function (value) { - var i = 0, - expanded = {}, - - // Assumes a single number if not a string - parts = typeof value === "string" ? value.split(" ") : [value]; - - for (; i < 4; i++) { - expanded[prefix + cssExpand[i] + suffix] = - parts[i] || parts[i - 2] || parts[0]; - } - - return expanded; - } - }; - - if (prefix !== "margin") { - jQuery.cssHooks[prefix + suffix].set = setPositiveNumber; - } - }); - - jQuery.fn.extend({ - css: function (name, value) { - return access(this, function (elem, name, value) { - var styles, len, - map = {}, - i = 0; - - if (Array.isArray(name)) { - styles = getStyles(elem); - len = name.length; - - for (; i < len; i++) { - map[name[i]] = jQuery.css(elem, name[i], false, styles); - } - - return map; - } - - return value !== undefined ? - jQuery.style(elem, name, value) : - jQuery.css(elem, name); - }, name, value, arguments.length > 1); - } - }); - - - // Based off of the plugin by Clint Helfers, with permission. - // https://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/ - jQuery.fn.delay = function (time, type) { - time = jQuery.fx ? jQuery.fx.speeds[time] || time : time; - type = type || "fx"; - - return this.queue(type, function (next, hooks) { - var timeout = window.setTimeout(next, time); - hooks.stop = function () { - window.clearTimeout(timeout); - }; - }); - }; - - - (function () { - var input = document$1.createElement("input"), - select = document$1.createElement("select"), - opt = select.appendChild(document$1.createElement("option")); - - input.type = "checkbox"; - - // Support: Android <=4.3 only - // Default value for a checkbox should be "on" - support.checkOn = input.value !== ""; - - // Support: IE <=11 only - // Must access selectedIndex to make default options select - support.optSelected = opt.selected; - - // Support: IE <=11 only - // An input loses its value after becoming a radio - input = document$1.createElement("input"); - input.value = "t"; - input.type = "radio"; - support.radioValue = input.value === "t"; - })(); - - - var boolHook, - attrHandle = jQuery.expr.attrHandle; - - jQuery.fn.extend({ - attr: function (name, value) { - return access(this, jQuery.attr, name, value, arguments.length > 1); - }, - - removeAttr: function (name) { - return this.each(function () { - jQuery.removeAttr(this, name); - }); - } - }); - - jQuery.extend({ - attr: function (elem, name, value) { - var ret, hooks, - nType = elem.nodeType; - - // Don't get/set attributes on text, comment and attribute nodes - if (nType === 3 || nType === 8 || nType === 2) { - return; - } - - // Fallback to prop when attributes are not supported - if (typeof elem.getAttribute === "undefined") { - return jQuery.prop(elem, name, value); - } - - // Attribute hooks are determined by the lowercase version - // Grab necessary hook if one is defined - if (nType !== 1 || !jQuery.isXMLDoc(elem)) { - hooks = jQuery.attrHooks[name.toLowerCase()] || - (jQuery.expr.match.bool.test(name) ? boolHook : undefined); - } - - if (value !== undefined) { - if (value === null) { - jQuery.removeAttr(elem, name); - return; - } - - if (hooks && "set" in hooks && - (ret = hooks.set(elem, value, name)) !== undefined) { - return ret; - } - - elem.setAttribute(name, value + ""); - return value; - } - - if (hooks && "get" in hooks && (ret = hooks.get(elem, name)) !== null) { - return ret; - } - - ret = jQuery.find.attr(elem, name); - - // Non-existent attributes return null, we normalize to undefined - return ret == null ? undefined : ret; - }, - - attrHooks: { - type: { - set: function (elem, value) { - if (!support.radioValue && value === "radio" && - nodeName(elem, "input")) { - var val = elem.value; - elem.setAttribute("type", value); - if (val) { - elem.value = val; - } - return value; - } - } - } - }, - - removeAttr: function (elem, value) { - var name, - i = 0, - - // Attribute names can contain non-HTML whitespace characters - // https://html.spec.whatwg.org/multipage/syntax.html#attributes-2 - attrNames = value && value.match(rnothtmlwhite); - - if (attrNames && elem.nodeType === 1) { - while ((name = attrNames[i++])) { - elem.removeAttribute(name); - } - } - } - }); - - // Hooks for boolean attributes - boolHook = { - set: function (elem, value, name) { - if (value === false) { - - // Remove boolean attributes when set to false - jQuery.removeAttr(elem, name); - } else { - elem.setAttribute(name, name); - } - return name; - } - }; - - jQuery.each(jQuery.expr.match.bool.source.match(/\w+/g), function (i, name) { - var getter = attrHandle[name] || jQuery.find.attr; - - attrHandle[name] = function (elem, name, isXML) { - var ret, handle, - lowercaseName = name.toLowerCase(); - - if (!isXML) { - - // Avoid an infinite loop by temporarily removing this function from the getter - handle = attrHandle[lowercaseName]; - attrHandle[lowercaseName] = ret; - ret = getter(elem, name, isXML) != null ? - lowercaseName : - null; - attrHandle[lowercaseName] = handle; - } - return ret; - }; - }); - - - var rfocusable = /^(?:input|select|textarea|button)$/i, - rclickable = /^(?:a|area)$/i; - - jQuery.fn.extend({ - prop: function (name, value) { - return access(this, jQuery.prop, name, value, arguments.length > 1); - }, - - removeProp: function (name) { - return this.each(function () { - delete this[jQuery.propFix[name] || name]; - }); - } - }); - - jQuery.extend({ - prop: function (elem, name, value) { - var ret, hooks, - nType = elem.nodeType; - - // Don't get/set properties on text, comment and attribute nodes - if (nType === 3 || nType === 8 || nType === 2) { - return; - } - - if (nType !== 1 || !jQuery.isXMLDoc(elem)) { - - // Fix name and attach hooks - name = jQuery.propFix[name] || name; - hooks = jQuery.propHooks[name]; - } - - if (value !== undefined) { - if (hooks && "set" in hooks && - (ret = hooks.set(elem, value, name)) !== undefined) { - return ret; - } - - return (elem[name] = value); - } - - if (hooks && "get" in hooks && (ret = hooks.get(elem, name)) !== null) { - return ret; - } - - return elem[name]; - }, - - propHooks: { - tabIndex: { - get: function (elem) { - - // Support: IE <=9 - 11 only - // elem.tabIndex doesn't always return the - // correct value when it hasn't been explicitly set - // https://web.archive.org/web/20141116233347/http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ - // Use proper attribute retrieval(#12072) - var tabindex = jQuery.find.attr(elem, "tabindex"); - - if (tabindex) { - return parseInt(tabindex, 10); - } - - if ( - rfocusable.test(elem.nodeName) || - rclickable.test(elem.nodeName) && - elem.href - ) { - return 0; - } - - return -1; - } - } - }, - - propFix: { - "for": "htmlFor", - "class": "className" - } - }); - - // Support: IE <=11 only - // Accessing the selectedIndex property - // forces the browser to respect setting selected - // on the option - // The getter ensures a default option is selected - // when in an optgroup - // eslint rule "no-unused-expressions" is disabled for this code - // since it considers such accessions noop - if (!support.optSelected) { - jQuery.propHooks.selected = { - get: function (elem) { - - /* eslint no-unused-expressions: "off" */ - - var parent = elem.parentNode; - if (parent && parent.parentNode) { - parent.parentNode.selectedIndex; - } - return null; - }, - set: function (elem) { - - /* eslint no-unused-expressions: "off" */ - - var parent = elem.parentNode; - if (parent) { - parent.selectedIndex; - - if (parent.parentNode) { - parent.parentNode.selectedIndex; - } - } - } - }; - } - - jQuery.each([ - "tabIndex", - "readOnly", - "maxLength", - "cellSpacing", - "cellPadding", - "rowSpan", - "colSpan", - "useMap", - "frameBorder", - "contentEditable" - ], function () { - jQuery.propFix[this.toLowerCase()] = this; - }); - - - // Strip and collapse whitespace according to HTML spec - // https://infra.spec.whatwg.org/#strip-and-collapse-ascii-whitespace - function stripAndCollapse(value) { - var tokens = value.match(rnothtmlwhite) || []; - return tokens.join(" "); - } - - - function getClass(elem) { - return elem.getAttribute && elem.getAttribute("class") || ""; - } - - function classesToArray(value) { - if (Array.isArray(value)) { - return value; - } - if (typeof value === "string") { - return value.match(rnothtmlwhite) || []; - } - return []; - } - - jQuery.fn.extend({ - addClass: function (value) { - var classes, elem, cur, curValue, clazz, j, finalValue, - i = 0; - - if (isFunction(value)) { - return this.each(function (j) { - jQuery(this).addClass(value.call(this, j, getClass(this))); - }); - } - - classes = classesToArray(value); - - if (classes.length) { - while ((elem = this[i++])) { - curValue = getClass(elem); - cur = elem.nodeType === 1 && (" " + stripAndCollapse(curValue) + " "); - - if (cur) { - j = 0; - while ((clazz = classes[j++])) { - if (cur.indexOf(" " + clazz + " ") < 0) { - cur += clazz + " "; - } - } - - // Only assign if different to avoid unneeded rendering. - finalValue = stripAndCollapse(cur); - if (curValue !== finalValue) { - elem.setAttribute("class", finalValue); - } - } - } - } - - return this; - }, - - removeClass: function (value) { - var classes, elem, cur, curValue, clazz, j, finalValue, - i = 0; - - if (isFunction(value)) { - return this.each(function (j) { - jQuery(this).removeClass(value.call(this, j, getClass(this))); - }); - } - - if (!arguments.length) { - return this.attr("class", ""); - } - - classes = classesToArray(value); - - if (classes.length) { - while ((elem = this[i++])) { - curValue = getClass(elem); - - // This expression is here for better compressibility (see addClass) - cur = elem.nodeType === 1 && (" " + stripAndCollapse(curValue) + " "); - - if (cur) { - j = 0; - while ((clazz = classes[j++])) { - - // Remove *all* instances - while (cur.indexOf(" " + clazz + " ") > -1) { - cur = cur.replace(" " + clazz + " ", " "); - } - } - - // Only assign if different to avoid unneeded rendering. - finalValue = stripAndCollapse(cur); - if (curValue !== finalValue) { - elem.setAttribute("class", finalValue); - } - } - } - } - - return this; - }, - - toggleClass: function (value, stateVal) { - var type = typeof value, - isValidValue = type === "string" || Array.isArray(value); - - if (typeof stateVal === "boolean" && isValidValue) { - return stateVal ? this.addClass(value) : this.removeClass(value); - } - - if (isFunction(value)) { - return this.each(function (i) { - jQuery(this).toggleClass( - value.call(this, i, getClass(this), stateVal), - stateVal - ); - }); - } - - return this.each(function () { - var className, i, self, classNames; - - if (isValidValue) { - - // Toggle individual class names - i = 0; - self = jQuery(this); - classNames = classesToArray(value); - - while ((className = classNames[i++])) { - - // Check each className given, space separated list - if (self.hasClass(className)) { - self.removeClass(className); - } else { - self.addClass(className); - } - } - - // Toggle whole class name - } else if (value === undefined || type === "boolean") { - className = getClass(this); - if (className) { - - // Store className if set - dataPriv.set(this, "__className__", className); - } - - // If the element has a class name or if we're passed `false`, - // then remove the whole classname (if there was one, the above saved it). - // Otherwise bring back whatever was previously saved (if anything), - // falling back to the empty string if nothing was stored. - if (this.setAttribute) { - this.setAttribute("class", - className || value === false ? - "" : - dataPriv.get(this, "__className__") || "" - ); - } - } - }); - }, - - hasClass: function (selector) { - var className, elem, - i = 0; - - className = " " + selector + " "; - while ((elem = this[i++])) { - if (elem.nodeType === 1 && - (" " + stripAndCollapse(getClass(elem)) + " ").indexOf(className) > -1) { - return true; - } - } - - return false; - } - }); - - - var rreturn = /\r/g; - - jQuery.fn.extend({ - val: function (value) { - var hooks, ret, valueIsFunction, - elem = this[0]; - - if (!arguments.length) { - if (elem) { - hooks = jQuery.valHooks[elem.type] || - jQuery.valHooks[elem.nodeName.toLowerCase()]; - - if (hooks && - "get" in hooks && - (ret = hooks.get(elem, "value")) !== undefined - ) { - return ret; - } - - ret = elem.value; - - // Handle most common string cases - if (typeof ret === "string") { - return ret.replace(rreturn, ""); - } - - // Handle cases where value is null/undef or number - return ret == null ? "" : ret; - } - - return; - } - - valueIsFunction = isFunction(value); - - return this.each(function (i) { - var val; - - if (this.nodeType !== 1) { - return; - } - - if (valueIsFunction) { - val = value.call(this, i, jQuery(this).val()); - } else { - val = value; - } - - // Treat null/undefined as ""; convert numbers to string - if (val == null) { - val = ""; - - } else if (typeof val === "number") { - val += ""; - - } else if (Array.isArray(val)) { - val = jQuery.map(val, function (value) { - return value == null ? "" : value + ""; - }); - } - - hooks = jQuery.valHooks[this.type] || jQuery.valHooks[this.nodeName.toLowerCase()]; - - // If set returns undefined, fall back to normal setting - if (!hooks || !("set" in hooks) || hooks.set(this, val, "value") === undefined) { - this.value = val; - } - }); - } - }); - - jQuery.extend({ - valHooks: { - option: { - get: function (elem) { - - var val = jQuery.find.attr(elem, "value"); - return val != null ? - val : - - // Support: IE <=10 - 11 only - // option.text throws exceptions (#14686, #14858) - // Strip and collapse whitespace - // https://html.spec.whatwg.org/#strip-and-collapse-whitespace - stripAndCollapse(jQuery.text(elem)); - } - }, - select: { - get: function (elem) { - var value, option, i, - options = elem.options, - index = elem.selectedIndex, - one = elem.type === "select-one", - values = one ? null : [], - max = one ? index + 1 : options.length; - - if (index < 0) { - i = max; - - } else { - i = one ? index : 0; - } - - // Loop through all the selected options - for (; i < max; i++) { - option = options[i]; - - // Support: IE <=9 only - // IE8-9 doesn't update selected after form reset (#2551) - if ((option.selected || i === index) && - - // Don't return options that are disabled or in a disabled optgroup - !option.disabled && - (!option.parentNode.disabled || - !nodeName(option.parentNode, "optgroup"))) { - - // Get the specific value for the option - value = jQuery(option).val(); - - // We don't need an array for one selects - if (one) { - return value; - } - - // Multi-Selects return an array - values.push(value); - } - } - - return values; - }, - - set: function (elem, value) { - var optionSet, option, - options = elem.options, - values = jQuery.makeArray(value), - i = options.length; - - while (i--) { - option = options[i]; - - /* eslint-disable no-cond-assign */ - - if (option.selected = - jQuery.inArray(jQuery.valHooks.option.get(option), values) > -1 - ) { - optionSet = true; - } - - /* eslint-enable no-cond-assign */ - } - - // Force browsers to behave consistently when non-matching value is set - if (!optionSet) { - elem.selectedIndex = -1; - } - return values; - } - } - } - }); - - // Radios and checkboxes getter/setter - jQuery.each(["radio", "checkbox"], function () { - jQuery.valHooks[this] = { - set: function (elem, value) { - if (Array.isArray(value)) { - return (elem.checked = jQuery.inArray(jQuery(elem).val(), value) > -1); - } - } - }; - if (!support.checkOn) { - jQuery.valHooks[this].get = function (elem) { - return elem.getAttribute("value") === null ? "on" : elem.value; - }; - } - }); - - - // Return jQuery for attributes-only inclusion - - - support.focusin = "onfocusin" in window; - - - var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, - stopPropagationCallback = function (e) { - e.stopPropagation(); - }; - - jQuery.extend(jQuery.event, { - - trigger: function (event, data, elem, onlyHandlers) { - - var i, cur, tmp, bubbleType, ontype, handle, special, lastElement, - eventPath = [elem || document$1], - type = hasOwn.call(event, "type") ? event.type : event, - namespaces = hasOwn.call(event, "namespace") ? event.namespace.split(".") : []; - - cur = lastElement = tmp = elem = elem || document$1; - - // Don't do events on text and comment nodes - if (elem.nodeType === 3 || elem.nodeType === 8) { - return; - } - - // focus/blur morphs to focusin/out; ensure we're not firing them right now - if (rfocusMorph.test(type + jQuery.event.triggered)) { - return; - } - - if (type.indexOf(".") > -1) { - - // Namespaced trigger; create a regexp to match event type in handle() - namespaces = type.split("."); - type = namespaces.shift(); - namespaces.sort(); - } - ontype = type.indexOf(":") < 0 && "on" + type; - - // Caller can pass in a jQuery.Event object, Object, or just an event type string - event = event[jQuery.expando] ? - event : - new jQuery.Event(type, typeof event === "object" && event); - - // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true) - event.isTrigger = onlyHandlers ? 2 : 3; - event.namespace = namespaces.join("."); - event.rnamespace = event.namespace ? - new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)") : - null; - - // Clean up the event in case it is being reused - event.result = undefined; - if (!event.target) { - event.target = elem; - } - - // Clone any incoming data and prepend the event, creating the handler arg list - data = data == null ? - [event] : - jQuery.makeArray(data, [event]); - - // Allow special events to draw outside the lines - special = jQuery.event.special[type] || {}; - if (!onlyHandlers && special.trigger && special.trigger.apply(elem, data) === false) { - return; - } - - // Determine event propagation path in advance, per W3C events spec (#9951) - // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) - if (!onlyHandlers && !special.noBubble && !isWindow(elem)) { - - bubbleType = special.delegateType || type; - if (!rfocusMorph.test(bubbleType + type)) { - cur = cur.parentNode; - } - for (; cur; cur = cur.parentNode) { - eventPath.push(cur); - tmp = cur; - } - - // Only add window if we got to document (e.g., not plain obj or detached DOM) - if (tmp === (elem.ownerDocument || document$1)) { - eventPath.push(tmp.defaultView || tmp.parentWindow || window); - } - } - - // Fire handlers on the event path - i = 0; - while ((cur = eventPath[i++]) && !event.isPropagationStopped()) { - lastElement = cur; - event.type = i > 1 ? - bubbleType : - special.bindType || type; - - // jQuery handler - handle = (dataPriv.get(cur, "events") || {})[event.type] && - dataPriv.get(cur, "handle"); - if (handle) { - handle.apply(cur, data); - } - - // Native handler - handle = ontype && cur[ontype]; - if (handle && handle.apply && acceptData(cur)) { - event.result = handle.apply(cur, data); - if (event.result === false) { - event.preventDefault(); - } - } - } - event.type = type; - - // If nobody prevented the default action, do it now - if (!onlyHandlers && !event.isDefaultPrevented()) { - - if ((!special._default || - special._default.apply(eventPath.pop(), data) === false) && - acceptData(elem)) { - - // Call a native DOM method on the target with the same name as the event. - // Don't do default actions on window, that's where global variables be (#6170) - if (ontype && isFunction(elem[type]) && !isWindow(elem)) { - - // Don't re-trigger an onFOO event when we call its FOO() method - tmp = elem[ontype]; - - if (tmp) { - elem[ontype] = null; - } - - // Prevent re-triggering of the same event, since we already bubbled it above - jQuery.event.triggered = type; - - if (event.isPropagationStopped()) { - lastElement.addEventListener(type, stopPropagationCallback); - } - - elem[type](); - - if (event.isPropagationStopped()) { - lastElement.removeEventListener(type, stopPropagationCallback); - } - - jQuery.event.triggered = undefined; - - if (tmp) { - elem[ontype] = tmp; - } - } - } - } - - return event.result; - }, - - // Piggyback on a donor event to simulate a different one - // Used only for `focus(in | out)` events - simulate: function (type, elem, event) { - var e = jQuery.extend( - new jQuery.Event(), - event, - { - type: type, - isSimulated: true - } - ); - - jQuery.event.trigger(e, null, elem); - } - - }); - - jQuery.fn.extend({ - - trigger: function (type, data) { - return this.each(function () { - jQuery.event.trigger(type, data, this); - }); - }, - triggerHandler: function (type, data) { - var elem = this[0]; - if (elem) { - return jQuery.event.trigger(type, data, elem, true); - } - } - }); - - - // Support: Firefox <=44 - // Firefox doesn't have focus(in | out) events - // Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787 - // - // Support: Chrome <=48 - 49, Safari <=9.0 - 9.1 - // focus(in | out) events fire after focus & blur events, - // which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order - // Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857 - if (!support.focusin) { - jQuery.each({focus: "focusin", blur: "focusout"}, function (orig, fix) { - - // Attach a single capturing handler on the document while someone wants focusin/focusout - var handler = function (event) { - jQuery.event.simulate(fix, event.target, jQuery.event.fix(event)); - }; - - jQuery.event.special[fix] = { - setup: function () { - var doc = this.ownerDocument || this, - attaches = dataPriv.access(doc, fix); - - if (!attaches) { - doc.addEventListener(orig, handler, true); - } - dataPriv.access(doc, fix, (attaches || 0) + 1); - }, - teardown: function () { - var doc = this.ownerDocument || this, - attaches = dataPriv.access(doc, fix) - 1; - - if (!attaches) { - doc.removeEventListener(orig, handler, true); - dataPriv.remove(doc, fix); - - } else { - dataPriv.access(doc, fix, attaches); - } - } - }; - }); - } - - - var - rbracket = /\[\]$/, - rCRLF = /\r?\n/g, - rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i, - rsubmittable = /^(?:input|select|textarea|keygen)/i; - - function buildParams(prefix, obj, traditional, add) { - var name; - - if (Array.isArray(obj)) { - - // Serialize array item. - jQuery.each(obj, function (i, v) { - if (traditional || rbracket.test(prefix)) { - - // Treat each array item as a scalar. - add(prefix, v); - - } else { - - // Item is non-scalar (array or object), encode its numeric index. - buildParams( - prefix + "[" + (typeof v === "object" && v != null ? i : "") + "]", - v, - traditional, - add - ); - } - }); - - } else if (!traditional && toType(obj) === "object") { - - // Serialize object item. - for (name in obj) { - buildParams(prefix + "[" + name + "]", obj[name], traditional, add); - } - - } else { - - // Serialize scalar item. - add(prefix, obj); - } - } - - // Serialize an array of form elements or a set of - // key/values into a query string - jQuery.param = function (a, traditional) { - var prefix, - s = [], - add = function (key, valueOrFunction) { - - // If value is a function, invoke it and use its return value - var value = isFunction(valueOrFunction) ? - valueOrFunction() : - valueOrFunction; - - s[s.length] = encodeURIComponent(key) + "=" + - encodeURIComponent(value == null ? "" : value); - }; - - // If an array was passed in, assume that it is an array of form elements. - if (Array.isArray(a) || (a.jquery && !jQuery.isPlainObject(a))) { - - // Serialize the form elements - jQuery.each(a, function () { - add(this.name, this.value); - }); - - } else { - - // If traditional, encode the "old" way (the way 1.3.2 or older - // did it), otherwise encode params recursively. - for (prefix in a) { - buildParams(prefix, a[prefix], traditional, add); - } - } - - // Return the resulting serialization - return s.join("&"); - }; - - jQuery.fn.extend({ - serialize: function () { - return jQuery.param(this.serializeArray()); - }, - serializeArray: function () { - return this.map(function () { - - // Can add propHook for "elements" to filter or add form elements - var elements = jQuery.prop(this, "elements"); - return elements ? jQuery.makeArray(elements) : this; - }) - .filter(function () { - var type = this.type; - - // Use .is( ":disabled" ) so that fieldset[disabled] works - return this.name && !jQuery(this).is(":disabled") && - rsubmittable.test(this.nodeName) && !rsubmitterTypes.test(type) && - (this.checked || !rcheckableType.test(type)); - }) - .map(function (i, elem) { - var val = jQuery(this).val(); - - if (val == null) { - return null; - } - - if (Array.isArray(val)) { - return jQuery.map(val, function (val) { - return {name: elem.name, value: val.replace(rCRLF, "\r\n")}; - }); - } - - return {name: elem.name, value: val.replace(rCRLF, "\r\n")}; - }).get(); - } - }); - - - jQuery.fn.extend({ - wrapAll: function (html) { - var wrap; - - if (this[0]) { - if (isFunction(html)) { - html = html.call(this[0]); - } - - // The elements to wrap the target around - wrap = jQuery(html, this[0].ownerDocument).eq(0).clone(true); - - if (this[0].parentNode) { - wrap.insertBefore(this[0]); - } - - wrap.map(function () { - var elem = this; - - while (elem.firstElementChild) { - elem = elem.firstElementChild; - } - - return elem; - }).append(this); - } - - return this; - }, - - wrapInner: function (html) { - if (isFunction(html)) { - return this.each(function (i) { - jQuery(this).wrapInner(html.call(this, i)); - }); - } - - return this.each(function () { - var self = jQuery(this), - contents = self.contents(); - - if (contents.length) { - contents.wrapAll(html); - - } else { - self.append(html); - } - }); - }, - - wrap: function (html) { - var htmlIsFunction = isFunction(html); - - return this.each(function (i) { - jQuery(this).wrapAll(htmlIsFunction ? html.call(this, i) : html); - }); - }, - - unwrap: function (selector) { - this.parent(selector).not("body").each(function () { - jQuery(this).replaceWith(this.childNodes); - }); - return this; - } - }); - - - jQuery.expr.pseudos.hidden = function (elem) { - return !jQuery.expr.pseudos.visible(elem); - }; - jQuery.expr.pseudos.visible = function (elem) { - return !!(elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length); - }; - - - // Support: Safari 8 only - // In Safari 8 documents created via document.implementation.createHTMLDocument - // collapse sibling forms: the second one becomes a child of the first one. - // Because of that, this security measure has to be disabled in Safari 8. - // https://bugs.webkit.org/show_bug.cgi?id=137337 - support.createHTMLDocument = (function () { - var body = document$1.implementation.createHTMLDocument("").body; - body.innerHTML = "
"; - return body.childNodes.length === 2; - })(); - - - // Argument "data" should be string of html - // context (optional): If specified, the fragment will be created in this context, - // defaults to document - // keepScripts (optional): If true, will include scripts passed in the html string - jQuery.parseHTML = function (data, context, keepScripts) { - if (typeof data !== "string") { - return []; - } - if (typeof context === "boolean") { - keepScripts = context; - context = false; - } - - var base, parsed, scripts; - - if (!context) { - - // Stop scripts or inline event handlers from being executed immediately - // by using document.implementation - if (support.createHTMLDocument) { - context = document$1.implementation.createHTMLDocument(""); - - // Set the base href for the created document - // so any parsed elements with URLs - // are based on the document's URL (gh-2965) - base = context.createElement("base"); - base.href = document$1.location.href; - context.head.appendChild(base); - } else { - context = document$1; - } - } - - parsed = rsingleTag.exec(data); - scripts = !keepScripts && []; - - // Single tag - if (parsed) { - return [context.createElement(parsed[1])]; - } - - parsed = buildFragment([data], context, scripts); - - if (scripts && scripts.length) { - jQuery(scripts).remove(); - } - - return jQuery.merge([], parsed.childNodes); - }; - - - jQuery.offset = { - setOffset: function (elem, options, i) { - var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition, - position = jQuery.css(elem, "position"), - curElem = jQuery(elem), - props = {}; - - // Set position first, in-case top/left are set even on static elem - if (position === "static") { - elem.style.position = "relative"; - } - - curOffset = curElem.offset(); - curCSSTop = jQuery.css(elem, "top"); - curCSSLeft = jQuery.css(elem, "left"); - calculatePosition = (position === "absolute" || position === "fixed") && - (curCSSTop + curCSSLeft).indexOf("auto") > -1; - - // Need to be able to calculate position if either - // top or left is auto and position is either absolute or fixed - if (calculatePosition) { - curPosition = curElem.position(); - curTop = curPosition.top; - curLeft = curPosition.left; - - } else { - curTop = parseFloat(curCSSTop) || 0; - curLeft = parseFloat(curCSSLeft) || 0; - } - - if (isFunction(options)) { - - // Use jQuery.extend here to allow modification of coordinates argument (gh-1848) - options = options.call(elem, i, jQuery.extend({}, curOffset)); - } - - if (options.top != null) { - props.top = (options.top - curOffset.top) + curTop; - } - if (options.left != null) { - props.left = (options.left - curOffset.left) + curLeft; - } - - if ("using" in options) { - options.using.call(elem, props); - - } else { - curElem.css(props); - } - } - }; - - jQuery.fn.extend({ - - // offset() relates an element's border box to the document origin - offset: function (options) { - - // Preserve chaining for setter - if (arguments.length) { - return options === undefined ? - this : - this.each(function (i) { - jQuery.offset.setOffset(this, options, i); - }); - } - - var rect, win, - elem = this[0]; - - if (!elem) { - return; - } - - // Return zeros for disconnected and hidden (display: none) elements (gh-2310) - // Support: IE <=11 only - // Running getBoundingClientRect on a - // disconnected node in IE throws an error - if (!elem.getClientRects().length) { - return {top: 0, left: 0}; - } - - // Get document-relative position by adding viewport scroll to viewport-relative gBCR - rect = elem.getBoundingClientRect(); - win = elem.ownerDocument.defaultView; - return { - top: rect.top + win.pageYOffset, - left: rect.left + win.pageXOffset - }; - }, - - // position() relates an element's margin box to its offset parent's padding box - // This corresponds to the behavior of CSS absolute positioning - position: function () { - if (!this[0]) { - return; - } - - var offsetParent, offset, doc, - elem = this[0], - parentOffset = {top: 0, left: 0}; - - // position:fixed elements are offset from the viewport, which itself always has zero offset - if (jQuery.css(elem, "position") === "fixed") { - - // Assume position:fixed implies availability of getBoundingClientRect - offset = elem.getBoundingClientRect(); - - } else { - offset = this.offset(); - - // Account for the *real* offset parent, which can be the document or its root element - // when a statically positioned element is identified - doc = elem.ownerDocument; - offsetParent = elem.offsetParent || doc.documentElement; - while (offsetParent && - (offsetParent === doc.body || offsetParent === doc.documentElement) && - jQuery.css(offsetParent, "position") === "static") { - - offsetParent = offsetParent.parentNode; - } - if (offsetParent && offsetParent !== elem && offsetParent.nodeType === 1) { - - // Incorporate borders into its offset, since they are outside its content origin - parentOffset = jQuery(offsetParent).offset(); - parentOffset.top += jQuery.css(offsetParent, "borderTopWidth", true); - parentOffset.left += jQuery.css(offsetParent, "borderLeftWidth", true); - } - } - - // Subtract parent offsets and element margins - return { - top: offset.top - parentOffset.top - jQuery.css(elem, "marginTop", true), - left: offset.left - parentOffset.left - jQuery.css(elem, "marginLeft", true) - }; - }, - - // This method will return documentElement in the following cases: - // 1) For the element inside the iframe without offsetParent, this method will return - // documentElement of the parent window - // 2) For the hidden or detached element - // 3) For body or html element, i.e. in case of the html node - it will return itself - // - // but those exceptions were never presented as a real life use-cases - // and might be considered as more preferable results. - // - // This logic, however, is not guaranteed and can change at any point in the future - offsetParent: function () { - return this.map(function () { - var offsetParent = this.offsetParent; - - while (offsetParent && jQuery.css(offsetParent, "position") === "static") { - offsetParent = offsetParent.offsetParent; - } - - return offsetParent || documentElement; - }); - } - }); - - // Create scrollLeft and scrollTop methods - jQuery.each({scrollLeft: "pageXOffset", scrollTop: "pageYOffset"}, function (method, prop) { - var top = "pageYOffset" === prop; - - jQuery.fn[method] = function (val) { - return access(this, function (elem, method, val) { - - // Coalesce documents and windows - var win; - if (isWindow(elem)) { - win = elem; - } else if (elem.nodeType === 9) { - win = elem.defaultView; - } - - if (val === undefined) { - return win ? win[prop] : elem[method]; - } - - if (win) { - win.scrollTo( - !top ? val : win.pageXOffset, - top ? val : win.pageYOffset - ); - - } else { - elem[method] = val; - } - }, method, val, arguments.length); - }; - }); - - // Support: Safari <=7 - 9.1, Chrome <=37 - 49 - // Add the top/left cssHooks using jQuery.fn.position - // Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084 - // Blink bug: https://bugs.chromium.org/p/chromium/issues/detail?id=589347 - // getComputedStyle returns percent when specified for top/left/bottom/right; - // rather than make the css module depend on the offset module, just check for it here - jQuery.each(["top", "left"], function (i, prop) { - jQuery.cssHooks[prop] = addGetHookIf(support.pixelPosition, - function (elem, computed) { - if (computed) { - computed = curCSS(elem, prop); - - // If curCSS returns percentage, fallback to offset - return rnumnonpx.test(computed) ? - jQuery(elem).position()[prop] + "px" : - computed; - } - } - ); - }); - - - // Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods - jQuery.each({Height: "height", Width: "width"}, function (name, type) { - jQuery.each({padding: "inner" + name, content: type, "": "outer" + name}, - function (defaultExtra, funcName) { - - // Margin is only for outerHeight, outerWidth - jQuery.fn[funcName] = function (margin, value) { - var chainable = arguments.length && (defaultExtra || typeof margin !== "boolean"), - extra = defaultExtra || (margin === true || value === true ? "margin" : "border"); - - return access(this, function (elem, type, value) { - var doc; - - if (isWindow(elem)) { - - // $( window ).outerWidth/Height return w/h including scrollbars (gh-1729) - return funcName.indexOf("outer") === 0 ? - elem["inner" + name] : - elem.document.documentElement["client" + name]; - } - - // Get document width or height - if (elem.nodeType === 9) { - doc = elem.documentElement; - - // Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height], - // whichever is greatest - return Math.max( - elem.body["scroll" + name], doc["scroll" + name], - elem.body["offset" + name], doc["offset" + name], - doc["client" + name] - ); - } - - return value === undefined ? - - // Get width or height on the element, requesting but not forcing parseFloat - jQuery.css(elem, type, extra) : - - // Set width or height on the element - jQuery.style(elem, type, value, extra); - }, type, chainable ? margin : undefined, chainable); - }; - }); - }); - - - jQuery.each(("blur focus focusin focusout resize scroll click dblclick " + - "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " + - "change select submit keydown keypress keyup contextmenu").split(" "), - function (i, name) { - - // Handle event binding - jQuery.fn[name] = function (data, fn) { - return arguments.length > 0 ? - this.on(name, null, data, fn) : - this.trigger(name); - }; - }); - - jQuery.fn.extend({ - hover: function (fnOver, fnOut) { - return this.mouseenter(fnOver).mouseleave(fnOut || fnOver); - } - }); - - - jQuery.fn.extend({ - - bind: function (types, data, fn) { - return this.on(types, null, data, fn); - }, - unbind: function (types, fn) { - return this.off(types, null, fn); - }, - - delegate: function (selector, types, data, fn) { - return this.on(types, selector, data, fn); - }, - undelegate: function (selector, types, fn) { - - // ( namespace ) or ( selector, types [, fn] ) - return arguments.length === 1 ? - this.off(selector, "**") : - this.off(types, selector || "**", fn); - } - }); - - // Bind a function to a context, optionally partially applying any - // arguments. - // jQuery.proxy is deprecated to promote standards (specifically Function#bind) - // However, it is not slated for removal any time soon - jQuery.proxy = function (fn, context) { - var tmp, args, proxy; - - if (typeof context === "string") { - tmp = fn[context]; - context = fn; - fn = tmp; - } - - // Quick check to determine if target is callable, in the spec - // this throws a TypeError, but we will just return undefined. - if (!isFunction(fn)) { - return undefined; - } - - // Simulated bind - args = slice.call(arguments, 2); - proxy = function () { - return fn.apply(context || this, args.concat(slice.call(arguments))); - }; - - // Set the guid of unique handler to the same of original handler, so it can be removed - proxy.guid = fn.guid = fn.guid || jQuery.guid++; - - return proxy; - }; - - jQuery.holdReady = function (hold) { - if (hold) { - jQuery.readyWait++; - } else { - jQuery.ready(true); - } - }; - jQuery.isArray = Array.isArray; - jQuery.parseJSON = JSON.parse; - jQuery.nodeName = nodeName; - jQuery.isFunction = isFunction; - jQuery.isWindow = isWindow; - jQuery.camelCase = camelCase; - jQuery.type = toType; - - jQuery.now = Date.now; - - jQuery.isNumeric = function (obj) { - - // As of jQuery 3.0, isNumeric is limited to - // strings and numbers (primitives or objects) - // that can be coerced to finite numbers (gh-2662) - var type = jQuery.type(obj); - return (type === "number" || type === "string") && - - // parseFloat NaNs numeric-cast false positives ("") - // ...but misinterprets leading-number strings, particularly hex literals ("0x...") - // subtraction forces infinities to NaN - !isNaN(obj - parseFloat(obj)); - }; - - const $$1 = jQuery; - - function div$1(options) { - return create$1("div", options); - } - - function create$1(tag, options) { - const elem = document.createElement(tag); - if (options) { - if (options.class) { - elem.classList.add(options.class); - } - if (options.id) { - elem.id = options.id; - } - if(options.style) { - applyStyle$1(elem, options.style); - } - } - return elem; - } - - function hide$1(elem) { - const cssStyle = getComputedStyle(elem); - if(cssStyle.display !== "none") { - elem._initialDisplay = cssStyle.display; - } - elem.style.display = "none"; - } - - function show$1(elem) { - const currentDisplay = getComputedStyle(elem).display; - if (currentDisplay === "none") { - const d = elem._initialDisplay || "block"; - elem.style.display = d; - } - } - - function hideAll$1(selector) { - document.querySelectorAll(selector).forEach(elem => { hide$1(elem); }); - } - - function empty$1(elem) { - while(elem.firstChild){ - elem.removeChild(elem.firstChild); - } - } - - function offset$1(elem) { - // Return zeros for disconnected and hidden (display: none) elements (gh-2310) - // Support: IE <=11 only - // Running getBoundingClientRect on a - // disconnected node in IE throws an error - if (!elem.getClientRects().length) { - return {top: 0, left: 0}; - } - - // Get document-relative position by adding viewport scroll to viewport-relative gBCR - const rect = elem.getBoundingClientRect(); - const win = elem.ownerDocument.defaultView; - return { - top: rect.top + win.pageYOffset, - left: rect.left + win.pageXOffset - }; - } - - function pageCoordinates$1(e) { - - if (e.type.startsWith("touch")) { - const touch = e.touches[0]; - return {x: touch.pageX, y: touch.pageY}; - } else { - return {x: e.pageX, y: e.pageY} - } - } - - const relativeDOMBBox$1 = (parentElement, childElement) => { - const { x: x_p, y: y_p, width: width_p, height: height_p } = parentElement.getBoundingClientRect(); - const { x: x_c, y: y_c, width: width_c, height: height_c } = childElement.getBoundingClientRect(); - return { x: (x_c - x_p), y: (y_c - y_p), width: width_c, height:height_c }; - }; - - function applyStyle$1(elem, style) { - for (let key of Object.keys(style)) { - elem.style[key] = style[key]; - } - } - - function guid$2 () { - return ("0000" + (Math.random() * Math.pow(36, 4) << 0).toString(36)).slice(-4); - } - - let getMouseXY$1 = (domElement, { clientX, clientY }) => { - - // DOMRect object with eight properties: left, top, right, bottom, x, y, width, height - const { left, top, width, height } = domElement.getBoundingClientRect(); - - const x = clientX - left; - const y = clientY - top; - return { x, y, xNormalized: x/width, yNormalized: y/height, width, height }; - - }; - - /** - * Translate the mouse coordinates for the event to the coordinates for the given target element - * @param event - * @param domElement - * @returns {{x: number, y: number}} - */ - function translateMouseCoordinates$1(event, domElement) { - - const { clientX, clientY } = event; - return getMouseXY$1(domElement, { clientX, clientY }); - - } - - var domUtils$1 = /*#__PURE__*/Object.freeze({ - __proto__: null, - applyStyle: applyStyle$1, - create: create$1, - div: div$1, - empty: empty$1, - guid: guid$2, - hide: hide$1, - hideAll: hideAll$1, - offset: offset$1, - pageCoordinates: pageCoordinates$1, - relativeDOMBBox: relativeDOMBBox$1, - show: show$1, - translateMouseCoordinates: translateMouseCoordinates$1 - }); - - /*! @license DOMPurify 3.0.5 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/3.0.5/LICENSE */ - - const { - entries, - setPrototypeOf, - isFrozen, - getPrototypeOf, - getOwnPropertyDescriptor - } = Object; - let { - freeze, - seal, - create: create$2 - } = Object; // eslint-disable-line import/no-mutable-exports - - let { - apply, - construct - } = typeof Reflect !== 'undefined' && Reflect; - - if (!apply) { - apply = function apply(fun, thisValue, args) { - return fun.apply(thisValue, args); - }; - } - - if (!freeze) { - freeze = function freeze(x) { - return x; - }; - } - - if (!seal) { - seal = function seal(x) { - return x; - }; - } - - if (!construct) { - construct = function construct(Func, args) { - return new Func(...args); - }; - } - - const arrayForEach = unapply(Array.prototype.forEach); - const arrayPop = unapply(Array.prototype.pop); - const arrayPush = unapply(Array.prototype.push); - const stringToLowerCase = unapply(String.prototype.toLowerCase); - const stringToString = unapply(String.prototype.toString); - const stringMatch = unapply(String.prototype.match); - const stringReplace = unapply(String.prototype.replace); - const stringIndexOf = unapply(String.prototype.indexOf); - const stringTrim = unapply(String.prototype.trim); - const regExpTest = unapply(RegExp.prototype.test); - const typeErrorCreate = unconstruct(TypeError); - function unapply(func) { - return function (thisArg) { - for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { - args[_key - 1] = arguments[_key]; - } - - return apply(func, thisArg, args); - }; - } - function unconstruct(func) { - return function () { - for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { - args[_key2] = arguments[_key2]; - } - - return construct(func, args); - }; - } - /* Add properties to a lookup table */ - - function addToSet(set, array, transformCaseFunc) { - var _transformCaseFunc; - - transformCaseFunc = (_transformCaseFunc = transformCaseFunc) !== null && _transformCaseFunc !== void 0 ? _transformCaseFunc : stringToLowerCase; - - if (setPrototypeOf) { - // Make 'in' and truthy checks like Boolean(set.constructor) - // independent of any properties defined on Object.prototype. - // Prevent prototype setters from intercepting set as a this value. - setPrototypeOf(set, null); - } - - let l = array.length; - - while (l--) { - let element = array[l]; - - if (typeof element === 'string') { - const lcElement = transformCaseFunc(element); - - if (lcElement !== element) { - // Config presets (e.g. tags.js, attrs.js) are immutable. - if (!isFrozen(array)) { - array[l] = lcElement; - } - - element = lcElement; - } - } - - set[element] = true; - } - - return set; - } - /* Shallow clone an object */ - - function clone(object) { - const newObject = create$2(null); - - for (const [property, value] of entries(object)) { - newObject[property] = value; - } - - return newObject; - } - /* This method automatically checks if the prop is function - * or getter and behaves accordingly. */ - - function lookupGetter(object, prop) { - while (object !== null) { - const desc = getOwnPropertyDescriptor(object, prop); - - if (desc) { - if (desc.get) { - return unapply(desc.get); - } - - if (typeof desc.value === 'function') { - return unapply(desc.value); - } - } - - object = getPrototypeOf(object); - } - - function fallbackValue(element) { - console.warn('fallback value for', element); - return null; - } - - return fallbackValue; - } - - const html$1 = freeze(['a', 'abbr', 'acronym', 'address', 'area', 'article', 'aside', 'audio', 'b', 'bdi', 'bdo', 'big', 'blink', 'blockquote', 'body', 'br', 'button', 'canvas', 'caption', 'center', 'cite', 'code', 'col', 'colgroup', 'content', 'data', 'datalist', 'dd', 'decorator', 'del', 'details', 'dfn', 'dialog', 'dir', 'div', 'dl', 'dt', 'element', 'em', 'fieldset', 'figcaption', 'figure', 'font', 'footer', 'form', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'header', 'hgroup', 'hr', 'html', 'i', 'img', 'input', 'ins', 'kbd', 'label', 'legend', 'li', 'main', 'map', 'mark', 'marquee', 'menu', 'menuitem', 'meter', 'nav', 'nobr', 'ol', 'optgroup', 'option', 'output', 'p', 'picture', 'pre', 'progress', 'q', 'rp', 'rt', 'ruby', 's', 'samp', 'section', 'select', 'shadow', 'small', 'source', 'spacer', 'span', 'strike', 'strong', 'style', 'sub', 'summary', 'sup', 'table', 'tbody', 'td', 'template', 'textarea', 'tfoot', 'th', 'thead', 'time', 'tr', 'track', 'tt', 'u', 'ul', 'var', 'video', 'wbr']); // SVG - - const svg$1 = freeze(['svg', 'a', 'altglyph', 'altglyphdef', 'altglyphitem', 'animatecolor', 'animatemotion', 'animatetransform', 'circle', 'clippath', 'defs', 'desc', 'ellipse', 'filter', 'font', 'g', 'glyph', 'glyphref', 'hkern', 'image', 'line', 'lineargradient', 'marker', 'mask', 'metadata', 'mpath', 'path', 'pattern', 'polygon', 'polyline', 'radialgradient', 'rect', 'stop', 'style', 'switch', 'symbol', 'text', 'textpath', 'title', 'tref', 'tspan', 'view', 'vkern']); - const svgFilters = freeze(['feBlend', 'feColorMatrix', 'feComponentTransfer', 'feComposite', 'feConvolveMatrix', 'feDiffuseLighting', 'feDisplacementMap', 'feDistantLight', 'feDropShadow', 'feFlood', 'feFuncA', 'feFuncB', 'feFuncG', 'feFuncR', 'feGaussianBlur', 'feImage', 'feMerge', 'feMergeNode', 'feMorphology', 'feOffset', 'fePointLight', 'feSpecularLighting', 'feSpotLight', 'feTile', 'feTurbulence']); // List of SVG elements that are disallowed by default. - // We still need to know them so that we can do namespace - // checks properly in case one wants to add them to - // allow-list. - - const svgDisallowed = freeze(['animate', 'color-profile', 'cursor', 'discard', 'font-face', 'font-face-format', 'font-face-name', 'font-face-src', 'font-face-uri', 'foreignobject', 'hatch', 'hatchpath', 'mesh', 'meshgradient', 'meshpatch', 'meshrow', 'missing-glyph', 'script', 'set', 'solidcolor', 'unknown', 'use']); - const mathMl$1 = freeze(['math', 'menclose', 'merror', 'mfenced', 'mfrac', 'mglyph', 'mi', 'mlabeledtr', 'mmultiscripts', 'mn', 'mo', 'mover', 'mpadded', 'mphantom', 'mroot', 'mrow', 'ms', 'mspace', 'msqrt', 'mstyle', 'msub', 'msup', 'msubsup', 'mtable', 'mtd', 'mtext', 'mtr', 'munder', 'munderover', 'mprescripts']); // Similarly to SVG, we want to know all MathML elements, - // even those that we disallow by default. - - const mathMlDisallowed = freeze(['maction', 'maligngroup', 'malignmark', 'mlongdiv', 'mscarries', 'mscarry', 'msgroup', 'mstack', 'msline', 'msrow', 'semantics', 'annotation', 'annotation-xml', 'mprescripts', 'none']); - const text = freeze(['#text']); - - const html = freeze(['accept', 'action', 'align', 'alt', 'autocapitalize', 'autocomplete', 'autopictureinpicture', 'autoplay', 'background', 'bgcolor', 'border', 'capture', 'cellpadding', 'cellspacing', 'checked', 'cite', 'class', 'clear', 'color', 'cols', 'colspan', 'controls', 'controlslist', 'coords', 'crossorigin', 'datetime', 'decoding', 'default', 'dir', 'disabled', 'disablepictureinpicture', 'disableremoteplayback', 'download', 'draggable', 'enctype', 'enterkeyhint', 'face', 'for', 'headers', 'height', 'hidden', 'high', 'href', 'hreflang', 'id', 'inputmode', 'integrity', 'ismap', 'kind', 'label', 'lang', 'list', 'loading', 'loop', 'low', 'max', 'maxlength', 'media', 'method', 'min', 'minlength', 'multiple', 'muted', 'name', 'nonce', 'noshade', 'novalidate', 'nowrap', 'open', 'optimum', 'pattern', 'placeholder', 'playsinline', 'poster', 'preload', 'pubdate', 'radiogroup', 'readonly', 'rel', 'required', 'rev', 'reversed', 'role', 'rows', 'rowspan', 'spellcheck', 'scope', 'selected', 'shape', 'size', 'sizes', 'span', 'srclang', 'start', 'src', 'srcset', 'step', 'style', 'summary', 'tabindex', 'title', 'translate', 'type', 'usemap', 'valign', 'value', 'width', 'xmlns', 'slot']); - const svg = freeze(['accent-height', 'accumulate', 'additive', 'alignment-baseline', 'ascent', 'attributename', 'attributetype', 'azimuth', 'basefrequency', 'baseline-shift', 'begin', 'bias', 'by', 'class', 'clip', 'clippathunits', 'clip-path', 'clip-rule', 'color', 'color-interpolation', 'color-interpolation-filters', 'color-profile', 'color-rendering', 'cx', 'cy', 'd', 'dx', 'dy', 'diffuseconstant', 'direction', 'display', 'divisor', 'dur', 'edgemode', 'elevation', 'end', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'filterunits', 'flood-color', 'flood-opacity', 'font-family', 'font-size', 'font-size-adjust', 'font-stretch', 'font-style', 'font-variant', 'font-weight', 'fx', 'fy', 'g1', 'g2', 'glyph-name', 'glyphref', 'gradientunits', 'gradienttransform', 'height', 'href', 'id', 'image-rendering', 'in', 'in2', 'k', 'k1', 'k2', 'k3', 'k4', 'kerning', 'keypoints', 'keysplines', 'keytimes', 'lang', 'lengthadjust', 'letter-spacing', 'kernelmatrix', 'kernelunitlength', 'lighting-color', 'local', 'marker-end', 'marker-mid', 'marker-start', 'markerheight', 'markerunits', 'markerwidth', 'maskcontentunits', 'maskunits', 'max', 'mask', 'media', 'method', 'mode', 'min', 'name', 'numoctaves', 'offset', 'operator', 'opacity', 'order', 'orient', 'orientation', 'origin', 'overflow', 'paint-order', 'path', 'pathlength', 'patterncontentunits', 'patterntransform', 'patternunits', 'points', 'preservealpha', 'preserveaspectratio', 'primitiveunits', 'r', 'rx', 'ry', 'radius', 'refx', 'refy', 'repeatcount', 'repeatdur', 'restart', 'result', 'rotate', 'scale', 'seed', 'shape-rendering', 'specularconstant', 'specularexponent', 'spreadmethod', 'startoffset', 'stddeviation', 'stitchtiles', 'stop-color', 'stop-opacity', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke', 'stroke-width', 'style', 'surfacescale', 'systemlanguage', 'tabindex', 'targetx', 'targety', 'transform', 'transform-origin', 'text-anchor', 'text-decoration', 'text-rendering', 'textlength', 'type', 'u1', 'u2', 'unicode', 'values', 'viewbox', 'visibility', 'version', 'vert-adv-y', 'vert-origin-x', 'vert-origin-y', 'width', 'word-spacing', 'wrap', 'writing-mode', 'xchannelselector', 'ychannelselector', 'x', 'x1', 'x2', 'xmlns', 'y', 'y1', 'y2', 'z', 'zoomandpan']); - const mathMl = freeze(['accent', 'accentunder', 'align', 'bevelled', 'close', 'columnsalign', 'columnlines', 'columnspan', 'denomalign', 'depth', 'dir', 'display', 'displaystyle', 'encoding', 'fence', 'frame', 'height', 'href', 'id', 'largeop', 'length', 'linethickness', 'lspace', 'lquote', 'mathbackground', 'mathcolor', 'mathsize', 'mathvariant', 'maxsize', 'minsize', 'movablelimits', 'notation', 'numalign', 'open', 'rowalign', 'rowlines', 'rowspacing', 'rowspan', 'rspace', 'rquote', 'scriptlevel', 'scriptminsize', 'scriptsizemultiplier', 'selection', 'separator', 'separators', 'stretchy', 'subscriptshift', 'supscriptshift', 'symmetric', 'voffset', 'width', 'xmlns']); - const xml = freeze(['xlink:href', 'xml:id', 'xlink:title', 'xml:space', 'xmlns:xlink']); - - const MUSTACHE_EXPR = seal(/\{\{[\w\W]*|[\w\W]*\}\}/gm); // Specify template detection regex for SAFE_FOR_TEMPLATES mode - - const ERB_EXPR = seal(/<%[\w\W]*|[\w\W]*%>/gm); - const TMPLIT_EXPR = seal(/\${[\w\W]*}/gm); - const DATA_ATTR = seal(/^data-[\-\w.\u00B7-\uFFFF]/); // eslint-disable-line no-useless-escape - - const ARIA_ATTR = seal(/^aria-[\-\w]+$/); // eslint-disable-line no-useless-escape - - const IS_ALLOWED_URI = seal(/^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i // eslint-disable-line no-useless-escape - ); - const IS_SCRIPT_OR_DATA = seal(/^(?:\w+script|data):/i); - const ATTR_WHITESPACE = seal(/[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g // eslint-disable-line no-control-regex - ); - const DOCTYPE_NAME = seal(/^html$/i); - - var EXPRESSIONS = /*#__PURE__*/Object.freeze({ - __proto__: null, - MUSTACHE_EXPR: MUSTACHE_EXPR, - ERB_EXPR: ERB_EXPR, - TMPLIT_EXPR: TMPLIT_EXPR, - DATA_ATTR: DATA_ATTR, - ARIA_ATTR: ARIA_ATTR, - IS_ALLOWED_URI: IS_ALLOWED_URI, - IS_SCRIPT_OR_DATA: IS_SCRIPT_OR_DATA, - ATTR_WHITESPACE: ATTR_WHITESPACE, - DOCTYPE_NAME: DOCTYPE_NAME - }); - - const getGlobal = () => typeof window === 'undefined' ? null : window; - /** - * Creates a no-op policy for internal use only. - * Don't export this function outside this module! - * @param {?TrustedTypePolicyFactory} trustedTypes The policy factory. - * @param {HTMLScriptElement} purifyHostElement The Script element used to load DOMPurify (to determine policy name suffix). - * @return {?TrustedTypePolicy} The policy created (or null, if Trusted Types - * are not supported or creating the policy failed). - */ - - - const _createTrustedTypesPolicy = function _createTrustedTypesPolicy(trustedTypes, purifyHostElement) { - if (typeof trustedTypes !== 'object' || typeof trustedTypes.createPolicy !== 'function') { - return null; - } // Allow the callers to control the unique policy name - // by adding a data-tt-policy-suffix to the script element with the DOMPurify. - // Policy creation with duplicate names throws in Trusted Types. - - - let suffix = null; - const ATTR_NAME = 'data-tt-policy-suffix'; - - if (purifyHostElement && purifyHostElement.hasAttribute(ATTR_NAME)) { - suffix = purifyHostElement.getAttribute(ATTR_NAME); - } - - const policyName = 'dompurify' + (suffix ? '#' + suffix : ''); - - try { - return trustedTypes.createPolicy(policyName, { - createHTML(html) { - return html; - }, - - createScriptURL(scriptUrl) { - return scriptUrl; - } - - }); - } catch (_) { - // Policy creation failed (most likely another DOMPurify script has - // already run). Skip creating the policy, as this will only cause errors - // if TT are enforced. - console.warn('TrustedTypes policy ' + policyName + ' could not be created.'); - return null; - } - }; - - function createDOMPurify() { - let window = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : getGlobal(); - - const DOMPurify = root => createDOMPurify(root); - /** - * Version label, exposed for easier checks - * if DOMPurify is up to date or not - */ - - - DOMPurify.version = '3.0.5'; - /** - * Array of elements that DOMPurify removed during sanitation. - * Empty if nothing was removed. - */ - - DOMPurify.removed = []; - - if (!window || !window.document || window.document.nodeType !== 9) { - // Not running in a browser, provide a factory function - // so that you can pass your own Window - DOMPurify.isSupported = false; - return DOMPurify; - } - - const originalDocument = window.document; - const currentScript = originalDocument.currentScript; - let { - document - } = window; - const { - DocumentFragment, - HTMLTemplateElement, - Node, - Element, - NodeFilter, - NamedNodeMap = window.NamedNodeMap || window.MozNamedAttrMap, - HTMLFormElement, - DOMParser, - trustedTypes - } = window; - const ElementPrototype = Element.prototype; - const cloneNode = lookupGetter(ElementPrototype, 'cloneNode'); - const getNextSibling = lookupGetter(ElementPrototype, 'nextSibling'); - const getChildNodes = lookupGetter(ElementPrototype, 'childNodes'); - const getParentNode = lookupGetter(ElementPrototype, 'parentNode'); // As per issue #47, the web-components registry is inherited by a - // new document created via createHTMLDocument. As per the spec - // (http://w3c.github.io/webcomponents/spec/custom/#creating-and-passing-registries) - // a new empty registry is used when creating a template contents owner - // document, so we use that as our parent document to ensure nothing - // is inherited. - - if (typeof HTMLTemplateElement === 'function') { - const template = document.createElement('template'); - - if (template.content && template.content.ownerDocument) { - document = template.content.ownerDocument; - } - } - - let trustedTypesPolicy; - let emptyHTML = ''; - const { - implementation, - createNodeIterator, - createDocumentFragment, - getElementsByTagName - } = document; - const { - importNode - } = originalDocument; - let hooks = {}; - /** - * Expose whether this browser supports running the full DOMPurify. - */ - - DOMPurify.isSupported = typeof entries === 'function' && typeof getParentNode === 'function' && implementation && implementation.createHTMLDocument !== undefined; - const { - MUSTACHE_EXPR, - ERB_EXPR, - TMPLIT_EXPR, - DATA_ATTR, - ARIA_ATTR, - IS_SCRIPT_OR_DATA, - ATTR_WHITESPACE - } = EXPRESSIONS; - let { - IS_ALLOWED_URI: IS_ALLOWED_URI$1 - } = EXPRESSIONS; - /** - * We consider the elements and attributes below to be safe. Ideally - * don't add any new ones but feel free to remove unwanted ones. - */ - - /* allowed element names */ - - let ALLOWED_TAGS = null; - const DEFAULT_ALLOWED_TAGS = addToSet({}, [...html$1, ...svg$1, ...svgFilters, ...mathMl$1, ...text]); - /* Allowed attribute names */ - - let ALLOWED_ATTR = null; - const DEFAULT_ALLOWED_ATTR = addToSet({}, [...html, ...svg, ...mathMl, ...xml]); - /* - * Configure how DOMPUrify should handle custom elements and their attributes as well as customized built-in elements. - * @property {RegExp|Function|null} tagNameCheck one of [null, regexPattern, predicate]. Default: `null` (disallow any custom elements) - * @property {RegExp|Function|null} attributeNameCheck one of [null, regexPattern, predicate]. Default: `null` (disallow any attributes not on the allow list) - * @property {boolean} allowCustomizedBuiltInElements allow custom elements derived from built-ins if they pass CUSTOM_ELEMENT_HANDLING.tagNameCheck. Default: `false`. - */ - - let CUSTOM_ELEMENT_HANDLING = Object.seal(Object.create(null, { - tagNameCheck: { - writable: true, - configurable: false, - enumerable: true, - value: null - }, - attributeNameCheck: { - writable: true, - configurable: false, - enumerable: true, - value: null - }, - allowCustomizedBuiltInElements: { - writable: true, - configurable: false, - enumerable: true, - value: false - } - })); - /* Explicitly forbidden tags (overrides ALLOWED_TAGS/ADD_TAGS) */ - - let FORBID_TAGS = null; - /* Explicitly forbidden attributes (overrides ALLOWED_ATTR/ADD_ATTR) */ - - let FORBID_ATTR = null; - /* Decide if ARIA attributes are okay */ - - let ALLOW_ARIA_ATTR = true; - /* Decide if custom data attributes are okay */ - - let ALLOW_DATA_ATTR = true; - /* Decide if unknown protocols are okay */ - - let ALLOW_UNKNOWN_PROTOCOLS = false; - /* Decide if self-closing tags in attributes are allowed. - * Usually removed due to a mXSS issue in jQuery 3.0 */ - - let ALLOW_SELF_CLOSE_IN_ATTR = true; - /* Output should be safe for common template engines. - * This means, DOMPurify removes data attributes, mustaches and ERB - */ - - let SAFE_FOR_TEMPLATES = false; - /* Decide if document with ... should be returned */ - - let WHOLE_DOCUMENT = false; - /* Track whether config is already set on this instance of DOMPurify. */ - - let SET_CONFIG = false; - /* Decide if all elements (e.g. style, script) must be children of - * document.body. By default, browsers might move them to document.head */ - - let FORCE_BODY = false; - /* Decide if a DOM `HTMLBodyElement` should be returned, instead of a html - * string (or a TrustedHTML object if Trusted Types are supported). - * If `WHOLE_DOCUMENT` is enabled a `HTMLHtmlElement` will be returned instead - */ - - let RETURN_DOM = false; - /* Decide if a DOM `DocumentFragment` should be returned, instead of a html - * string (or a TrustedHTML object if Trusted Types are supported) */ - - let RETURN_DOM_FRAGMENT = false; - /* Try to return a Trusted Type object instead of a string, return a string in - * case Trusted Types are not supported */ - - let RETURN_TRUSTED_TYPE = false; - /* Output should be free from DOM clobbering attacks? - * This sanitizes markups named with colliding, clobberable built-in DOM APIs. - */ - - let SANITIZE_DOM = true; - /* Achieve full DOM Clobbering protection by isolating the namespace of named - * properties and JS variables, mitigating attacks that abuse the HTML/DOM spec rules. - * - * HTML/DOM spec rules that enable DOM Clobbering: - * - Named Access on Window (§7.3.3) - * - DOM Tree Accessors (§3.1.5) - * - Form Element Parent-Child Relations (§4.10.3) - * - Iframe srcdoc / Nested WindowProxies (§4.8.5) - * - HTMLCollection (§4.2.10.2) - * - * Namespace isolation is implemented by prefixing `id` and `name` attributes - * with a constant string, i.e., `user-content-` - */ - - let SANITIZE_NAMED_PROPS = false; - const SANITIZE_NAMED_PROPS_PREFIX = 'user-content-'; - /* Keep element content when removing element? */ - - let KEEP_CONTENT = true; - /* If a `Node` is passed to sanitize(), then performs sanitization in-place instead - * of importing it into a new Document and returning a sanitized copy */ - - let IN_PLACE = false; - /* Allow usage of profiles like html, svg and mathMl */ - - let USE_PROFILES = {}; - /* Tags to ignore content of when KEEP_CONTENT is true */ - - let FORBID_CONTENTS = null; - const DEFAULT_FORBID_CONTENTS = addToSet({}, ['annotation-xml', 'audio', 'colgroup', 'desc', 'foreignobject', 'head', 'iframe', 'math', 'mi', 'mn', 'mo', 'ms', 'mtext', 'noembed', 'noframes', 'noscript', 'plaintext', 'script', 'style', 'svg', 'template', 'thead', 'title', 'video', 'xmp']); - /* Tags that are safe for data: URIs */ - - let DATA_URI_TAGS = null; - const DEFAULT_DATA_URI_TAGS = addToSet({}, ['audio', 'video', 'img', 'source', 'image', 'track']); - /* Attributes safe for values like "javascript:" */ - - let URI_SAFE_ATTRIBUTES = null; - const DEFAULT_URI_SAFE_ATTRIBUTES = addToSet({}, ['alt', 'class', 'for', 'id', 'label', 'name', 'pattern', 'placeholder', 'role', 'summary', 'title', 'value', 'style', 'xmlns']); - const MATHML_NAMESPACE = 'http://www.w3.org/1998/Math/MathML'; - const SVG_NAMESPACE = 'http://www.w3.org/2000/svg'; - const HTML_NAMESPACE = 'http://www.w3.org/1999/xhtml'; - /* Document namespace */ - - let NAMESPACE = HTML_NAMESPACE; - let IS_EMPTY_INPUT = false; - /* Allowed XHTML+XML namespaces */ - - let ALLOWED_NAMESPACES = null; - const DEFAULT_ALLOWED_NAMESPACES = addToSet({}, [MATHML_NAMESPACE, SVG_NAMESPACE, HTML_NAMESPACE], stringToString); - /* Parsing of strict XHTML documents */ - - let PARSER_MEDIA_TYPE; - const SUPPORTED_PARSER_MEDIA_TYPES = ['application/xhtml+xml', 'text/html']; - const DEFAULT_PARSER_MEDIA_TYPE = 'text/html'; - let transformCaseFunc; - /* Keep a reference to config to pass to hooks */ - - let CONFIG = null; - /* Ideally, do not touch anything below this line */ - - /* ______________________________________________ */ - - const formElement = document.createElement('form'); - - const isRegexOrFunction = function isRegexOrFunction(testValue) { - return testValue instanceof RegExp || testValue instanceof Function; - }; - /** - * _parseConfig - * - * @param {Object} cfg optional config literal - */ - // eslint-disable-next-line complexity - - - const _parseConfig = function _parseConfig(cfg) { - if (CONFIG && CONFIG === cfg) { - return; - } - /* Shield configuration object from tampering */ - - - if (!cfg || typeof cfg !== 'object') { - cfg = {}; - } - /* Shield configuration object from prototype pollution */ - - - cfg = clone(cfg); - PARSER_MEDIA_TYPE = // eslint-disable-next-line unicorn/prefer-includes - SUPPORTED_PARSER_MEDIA_TYPES.indexOf(cfg.PARSER_MEDIA_TYPE) === -1 ? PARSER_MEDIA_TYPE = DEFAULT_PARSER_MEDIA_TYPE : PARSER_MEDIA_TYPE = cfg.PARSER_MEDIA_TYPE; // HTML tags and attributes are not case-sensitive, converting to lowercase. Keeping XHTML as is. - - transformCaseFunc = PARSER_MEDIA_TYPE === 'application/xhtml+xml' ? stringToString : stringToLowerCase; - /* Set configuration parameters */ - - ALLOWED_TAGS = 'ALLOWED_TAGS' in cfg ? addToSet({}, cfg.ALLOWED_TAGS, transformCaseFunc) : DEFAULT_ALLOWED_TAGS; - ALLOWED_ATTR = 'ALLOWED_ATTR' in cfg ? addToSet({}, cfg.ALLOWED_ATTR, transformCaseFunc) : DEFAULT_ALLOWED_ATTR; - ALLOWED_NAMESPACES = 'ALLOWED_NAMESPACES' in cfg ? addToSet({}, cfg.ALLOWED_NAMESPACES, stringToString) : DEFAULT_ALLOWED_NAMESPACES; - URI_SAFE_ATTRIBUTES = 'ADD_URI_SAFE_ATTR' in cfg ? addToSet(clone(DEFAULT_URI_SAFE_ATTRIBUTES), // eslint-disable-line indent - cfg.ADD_URI_SAFE_ATTR, // eslint-disable-line indent - transformCaseFunc // eslint-disable-line indent - ) // eslint-disable-line indent - : DEFAULT_URI_SAFE_ATTRIBUTES; - DATA_URI_TAGS = 'ADD_DATA_URI_TAGS' in cfg ? addToSet(clone(DEFAULT_DATA_URI_TAGS), // eslint-disable-line indent - cfg.ADD_DATA_URI_TAGS, // eslint-disable-line indent - transformCaseFunc // eslint-disable-line indent - ) // eslint-disable-line indent - : DEFAULT_DATA_URI_TAGS; - FORBID_CONTENTS = 'FORBID_CONTENTS' in cfg ? addToSet({}, cfg.FORBID_CONTENTS, transformCaseFunc) : DEFAULT_FORBID_CONTENTS; - FORBID_TAGS = 'FORBID_TAGS' in cfg ? addToSet({}, cfg.FORBID_TAGS, transformCaseFunc) : {}; - FORBID_ATTR = 'FORBID_ATTR' in cfg ? addToSet({}, cfg.FORBID_ATTR, transformCaseFunc) : {}; - USE_PROFILES = 'USE_PROFILES' in cfg ? cfg.USE_PROFILES : false; - ALLOW_ARIA_ATTR = cfg.ALLOW_ARIA_ATTR !== false; // Default true - - ALLOW_DATA_ATTR = cfg.ALLOW_DATA_ATTR !== false; // Default true - - ALLOW_UNKNOWN_PROTOCOLS = cfg.ALLOW_UNKNOWN_PROTOCOLS || false; // Default false - - ALLOW_SELF_CLOSE_IN_ATTR = cfg.ALLOW_SELF_CLOSE_IN_ATTR !== false; // Default true - - SAFE_FOR_TEMPLATES = cfg.SAFE_FOR_TEMPLATES || false; // Default false - - WHOLE_DOCUMENT = cfg.WHOLE_DOCUMENT || false; // Default false - - RETURN_DOM = cfg.RETURN_DOM || false; // Default false - - RETURN_DOM_FRAGMENT = cfg.RETURN_DOM_FRAGMENT || false; // Default false - - RETURN_TRUSTED_TYPE = cfg.RETURN_TRUSTED_TYPE || false; // Default false - - FORCE_BODY = cfg.FORCE_BODY || false; // Default false - - SANITIZE_DOM = cfg.SANITIZE_DOM !== false; // Default true - - SANITIZE_NAMED_PROPS = cfg.SANITIZE_NAMED_PROPS || false; // Default false - - KEEP_CONTENT = cfg.KEEP_CONTENT !== false; // Default true - - IN_PLACE = cfg.IN_PLACE || false; // Default false - - IS_ALLOWED_URI$1 = cfg.ALLOWED_URI_REGEXP || IS_ALLOWED_URI; - NAMESPACE = cfg.NAMESPACE || HTML_NAMESPACE; - CUSTOM_ELEMENT_HANDLING = cfg.CUSTOM_ELEMENT_HANDLING || {}; - - if (cfg.CUSTOM_ELEMENT_HANDLING && isRegexOrFunction(cfg.CUSTOM_ELEMENT_HANDLING.tagNameCheck)) { - CUSTOM_ELEMENT_HANDLING.tagNameCheck = cfg.CUSTOM_ELEMENT_HANDLING.tagNameCheck; - } - - if (cfg.CUSTOM_ELEMENT_HANDLING && isRegexOrFunction(cfg.CUSTOM_ELEMENT_HANDLING.attributeNameCheck)) { - CUSTOM_ELEMENT_HANDLING.attributeNameCheck = cfg.CUSTOM_ELEMENT_HANDLING.attributeNameCheck; - } - - if (cfg.CUSTOM_ELEMENT_HANDLING && typeof cfg.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements === 'boolean') { - CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements = cfg.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements; - } - - if (SAFE_FOR_TEMPLATES) { - ALLOW_DATA_ATTR = false; - } - - if (RETURN_DOM_FRAGMENT) { - RETURN_DOM = true; - } - /* Parse profile info */ - - - if (USE_PROFILES) { - ALLOWED_TAGS = addToSet({}, [...text]); - ALLOWED_ATTR = []; - - if (USE_PROFILES.html === true) { - addToSet(ALLOWED_TAGS, html$1); - addToSet(ALLOWED_ATTR, html); - } - - if (USE_PROFILES.svg === true) { - addToSet(ALLOWED_TAGS, svg$1); - addToSet(ALLOWED_ATTR, svg); - addToSet(ALLOWED_ATTR, xml); - } - - if (USE_PROFILES.svgFilters === true) { - addToSet(ALLOWED_TAGS, svgFilters); - addToSet(ALLOWED_ATTR, svg); - addToSet(ALLOWED_ATTR, xml); - } - - if (USE_PROFILES.mathMl === true) { - addToSet(ALLOWED_TAGS, mathMl$1); - addToSet(ALLOWED_ATTR, mathMl); - addToSet(ALLOWED_ATTR, xml); - } - } - /* Merge configuration parameters */ - - - if (cfg.ADD_TAGS) { - if (ALLOWED_TAGS === DEFAULT_ALLOWED_TAGS) { - ALLOWED_TAGS = clone(ALLOWED_TAGS); - } - - addToSet(ALLOWED_TAGS, cfg.ADD_TAGS, transformCaseFunc); - } - - if (cfg.ADD_ATTR) { - if (ALLOWED_ATTR === DEFAULT_ALLOWED_ATTR) { - ALLOWED_ATTR = clone(ALLOWED_ATTR); - } - - addToSet(ALLOWED_ATTR, cfg.ADD_ATTR, transformCaseFunc); - } - - if (cfg.ADD_URI_SAFE_ATTR) { - addToSet(URI_SAFE_ATTRIBUTES, cfg.ADD_URI_SAFE_ATTR, transformCaseFunc); - } - - if (cfg.FORBID_CONTENTS) { - if (FORBID_CONTENTS === DEFAULT_FORBID_CONTENTS) { - FORBID_CONTENTS = clone(FORBID_CONTENTS); - } - - addToSet(FORBID_CONTENTS, cfg.FORBID_CONTENTS, transformCaseFunc); - } - /* Add #text in case KEEP_CONTENT is set to true */ - - - if (KEEP_CONTENT) { - ALLOWED_TAGS['#text'] = true; - } - /* Add html, head and body to ALLOWED_TAGS in case WHOLE_DOCUMENT is true */ - - - if (WHOLE_DOCUMENT) { - addToSet(ALLOWED_TAGS, ['html', 'head', 'body']); - } - /* Add tbody to ALLOWED_TAGS in case tables are permitted, see #286, #365 */ - - - if (ALLOWED_TAGS.table) { - addToSet(ALLOWED_TAGS, ['tbody']); - delete FORBID_TAGS.tbody; - } - - if (cfg.TRUSTED_TYPES_POLICY) { - if (typeof cfg.TRUSTED_TYPES_POLICY.createHTML !== 'function') { - throw typeErrorCreate('TRUSTED_TYPES_POLICY configuration option must provide a "createHTML" hook.'); - } - - if (typeof cfg.TRUSTED_TYPES_POLICY.createScriptURL !== 'function') { - throw typeErrorCreate('TRUSTED_TYPES_POLICY configuration option must provide a "createScriptURL" hook.'); - } // Overwrite existing TrustedTypes policy. - - - trustedTypesPolicy = cfg.TRUSTED_TYPES_POLICY; // Sign local variables required by `sanitize`. - - emptyHTML = trustedTypesPolicy.createHTML(''); - } else { - // Uninitialized policy, attempt to initialize the internal dompurify policy. - if (trustedTypesPolicy === undefined) { - trustedTypesPolicy = _createTrustedTypesPolicy(trustedTypes, currentScript); - } // If creating the internal policy succeeded sign internal variables. - - - if (trustedTypesPolicy !== null && typeof emptyHTML === 'string') { - emptyHTML = trustedTypesPolicy.createHTML(''); - } - } // Prevent further manipulation of configuration. - // Not available in IE8, Safari 5, etc. - - - if (freeze) { - freeze(cfg); - } - - CONFIG = cfg; - }; - - const MATHML_TEXT_INTEGRATION_POINTS = addToSet({}, ['mi', 'mo', 'mn', 'ms', 'mtext']); - const HTML_INTEGRATION_POINTS = addToSet({}, ['foreignobject', 'desc', 'title', 'annotation-xml']); // Certain elements are allowed in both SVG and HTML - // namespace. We need to specify them explicitly - // so that they don't get erroneously deleted from - // HTML namespace. - - const COMMON_SVG_AND_HTML_ELEMENTS = addToSet({}, ['title', 'style', 'font', 'a', 'script']); - /* Keep track of all possible SVG and MathML tags - * so that we can perform the namespace checks - * correctly. */ - - const ALL_SVG_TAGS = addToSet({}, svg$1); - addToSet(ALL_SVG_TAGS, svgFilters); - addToSet(ALL_SVG_TAGS, svgDisallowed); - const ALL_MATHML_TAGS = addToSet({}, mathMl$1); - addToSet(ALL_MATHML_TAGS, mathMlDisallowed); - /** - * - * - * @param {Element} element a DOM element whose namespace is being checked - * @returns {boolean} Return false if the element has a - * namespace that a spec-compliant parser would never - * return. Return true otherwise. - */ - - const _checkValidNamespace = function _checkValidNamespace(element) { - let parent = getParentNode(element); // In JSDOM, if we're inside shadow DOM, then parentNode - // can be null. We just simulate parent in this case. - - if (!parent || !parent.tagName) { - parent = { - namespaceURI: NAMESPACE, - tagName: 'template' - }; - } - - const tagName = stringToLowerCase(element.tagName); - const parentTagName = stringToLowerCase(parent.tagName); - - if (!ALLOWED_NAMESPACES[element.namespaceURI]) { - return false; - } - - if (element.namespaceURI === SVG_NAMESPACE) { - // The only way to switch from HTML namespace to SVG - // is via . If it happens via any other tag, then - // it should be killed. - if (parent.namespaceURI === HTML_NAMESPACE) { - return tagName === 'svg'; - } // The only way to switch from MathML to SVG is via` - // svg if parent is either or MathML - // text integration points. - - - if (parent.namespaceURI === MATHML_NAMESPACE) { - return tagName === 'svg' && (parentTagName === 'annotation-xml' || MATHML_TEXT_INTEGRATION_POINTS[parentTagName]); - } // We only allow elements that are defined in SVG - // spec. All others are disallowed in SVG namespace. - - - return Boolean(ALL_SVG_TAGS[tagName]); - } - - if (element.namespaceURI === MATHML_NAMESPACE) { - // The only way to switch from HTML namespace to MathML - // is via . If it happens via any other tag, then - // it should be killed. - if (parent.namespaceURI === HTML_NAMESPACE) { - return tagName === 'math'; - } // The only way to switch from SVG to MathML is via - // and HTML integration points - - - if (parent.namespaceURI === SVG_NAMESPACE) { - return tagName === 'math' && HTML_INTEGRATION_POINTS[parentTagName]; - } // We only allow elements that are defined in MathML - // spec. All others are disallowed in MathML namespace. - - - return Boolean(ALL_MATHML_TAGS[tagName]); - } - - if (element.namespaceURI === HTML_NAMESPACE) { - // The only way to switch from SVG to HTML is via - // HTML integration points, and from MathML to HTML - // is via MathML text integration points - if (parent.namespaceURI === SVG_NAMESPACE && !HTML_INTEGRATION_POINTS[parentTagName]) { - return false; - } - - if (parent.namespaceURI === MATHML_NAMESPACE && !MATHML_TEXT_INTEGRATION_POINTS[parentTagName]) { - return false; - } // We disallow tags that are specific for MathML - // or SVG and should never appear in HTML namespace - - - return !ALL_MATHML_TAGS[tagName] && (COMMON_SVG_AND_HTML_ELEMENTS[tagName] || !ALL_SVG_TAGS[tagName]); - } // For XHTML and XML documents that support custom namespaces - - - if (PARSER_MEDIA_TYPE === 'application/xhtml+xml' && ALLOWED_NAMESPACES[element.namespaceURI]) { - return true; - } // The code should never reach this place (this means - // that the element somehow got namespace that is not - // HTML, SVG, MathML or allowed via ALLOWED_NAMESPACES). - // Return false just in case. - - - return false; - }; - /** - * _forceRemove - * - * @param {Node} node a DOM node - */ - - - const _forceRemove = function _forceRemove(node) { - arrayPush(DOMPurify.removed, { - element: node - }); - - try { - // eslint-disable-next-line unicorn/prefer-dom-node-remove - node.parentNode.removeChild(node); - } catch (_) { - node.remove(); - } - }; - /** - * _removeAttribute - * - * @param {String} name an Attribute name - * @param {Node} node a DOM node - */ - - - const _removeAttribute = function _removeAttribute(name, node) { - try { - arrayPush(DOMPurify.removed, { - attribute: node.getAttributeNode(name), - from: node - }); - } catch (_) { - arrayPush(DOMPurify.removed, { - attribute: null, - from: node - }); - } - - node.removeAttribute(name); // We void attribute values for unremovable "is"" attributes - - if (name === 'is' && !ALLOWED_ATTR[name]) { - if (RETURN_DOM || RETURN_DOM_FRAGMENT) { - try { - _forceRemove(node); - } catch (_) {} - } else { - try { - node.setAttribute(name, ''); - } catch (_) {} - } - } - }; - /** - * _initDocument - * - * @param {String} dirty a string of dirty markup - * @return {Document} a DOM, filled with the dirty markup - */ - - - const _initDocument = function _initDocument(dirty) { - /* Create a HTML document */ - let doc; - let leadingWhitespace; - - if (FORCE_BODY) { - dirty = '' + dirty; - } else { - /* If FORCE_BODY isn't used, leading whitespace needs to be preserved manually */ - const matches = stringMatch(dirty, /^[\r\n\t ]+/); - leadingWhitespace = matches && matches[0]; - } - - if (PARSER_MEDIA_TYPE === 'application/xhtml+xml' && NAMESPACE === HTML_NAMESPACE) { - // Root of XHTML doc must contain xmlns declaration (see https://www.w3.org/TR/xhtml1/normative.html#strict) - dirty = '' + dirty + ''; - } - - const dirtyPayload = trustedTypesPolicy ? trustedTypesPolicy.createHTML(dirty) : dirty; - /* - * Use the DOMParser API by default, fallback later if needs be - * DOMParser not work for svg when has multiple root element. - */ - - if (NAMESPACE === HTML_NAMESPACE) { - try { - doc = new DOMParser().parseFromString(dirtyPayload, PARSER_MEDIA_TYPE); - } catch (_) {} - } - /* Use createHTMLDocument in case DOMParser is not available */ - - - if (!doc || !doc.documentElement) { - doc = implementation.createDocument(NAMESPACE, 'template', null); - - try { - doc.documentElement.innerHTML = IS_EMPTY_INPUT ? emptyHTML : dirtyPayload; - } catch (_) {// Syntax error if dirtyPayload is invalid xml - } - } - - const body = doc.body || doc.documentElement; - - if (dirty && leadingWhitespace) { - body.insertBefore(document.createTextNode(leadingWhitespace), body.childNodes[0] || null); - } - /* Work on whole document or just its body */ - - - if (NAMESPACE === HTML_NAMESPACE) { - return getElementsByTagName.call(doc, WHOLE_DOCUMENT ? 'html' : 'body')[0]; - } - - return WHOLE_DOCUMENT ? doc.documentElement : body; - }; - /** - * _createIterator - * - * @param {Document} root document/fragment to create iterator for - * @return {Iterator} iterator instance - */ - - - const _createIterator = function _createIterator(root) { - return createNodeIterator.call(root.ownerDocument || root, root, // eslint-disable-next-line no-bitwise - NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_COMMENT | NodeFilter.SHOW_TEXT, null, false); - }; - /** - * _isClobbered - * - * @param {Node} elm element to check for clobbering attacks - * @return {Boolean} true if clobbered, false if safe - */ - - - const _isClobbered = function _isClobbered(elm) { - return elm instanceof HTMLFormElement && (typeof elm.nodeName !== 'string' || typeof elm.textContent !== 'string' || typeof elm.removeChild !== 'function' || !(elm.attributes instanceof NamedNodeMap) || typeof elm.removeAttribute !== 'function' || typeof elm.setAttribute !== 'function' || typeof elm.namespaceURI !== 'string' || typeof elm.insertBefore !== 'function' || typeof elm.hasChildNodes !== 'function'); - }; - /** - * _isNode - * - * @param {Node} obj object to check whether it's a DOM node - * @return {Boolean} true is object is a DOM node - */ - - - const _isNode = function _isNode(object) { - return typeof Node === 'object' ? object instanceof Node : object && typeof object === 'object' && typeof object.nodeType === 'number' && typeof object.nodeName === 'string'; - }; - /** - * _executeHook - * Execute user configurable hooks - * - * @param {String} entryPoint Name of the hook's entry point - * @param {Node} currentNode node to work on with the hook - * @param {Object} data additional hook parameters - */ - - - const _executeHook = function _executeHook(entryPoint, currentNode, data) { - if (!hooks[entryPoint]) { - return; - } - - arrayForEach(hooks[entryPoint], hook => { - hook.call(DOMPurify, currentNode, data, CONFIG); - }); - }; - /** - * _sanitizeElements - * - * @protect nodeName - * @protect textContent - * @protect removeChild - * - * @param {Node} currentNode to check for permission to exist - * @return {Boolean} true if node was killed, false if left alive - */ - - - const _sanitizeElements = function _sanitizeElements(currentNode) { - let content; - /* Execute a hook if present */ - - _executeHook('beforeSanitizeElements', currentNode, null); - /* Check if element is clobbered or can clobber */ - - - if (_isClobbered(currentNode)) { - _forceRemove(currentNode); - - return true; - } - /* Now let's check the element's type and name */ - - - const tagName = transformCaseFunc(currentNode.nodeName); - /* Execute a hook if present */ - - _executeHook('uponSanitizeElement', currentNode, { - tagName, - allowedTags: ALLOWED_TAGS - }); - /* Detect mXSS attempts abusing namespace confusion */ - - - if (currentNode.hasChildNodes() && !_isNode(currentNode.firstElementChild) && (!_isNode(currentNode.content) || !_isNode(currentNode.content.firstElementChild)) && regExpTest(/<[/\w]/g, currentNode.innerHTML) && regExpTest(/<[/\w]/g, currentNode.textContent)) { - _forceRemove(currentNode); - - return true; - } - /* Remove element if anything forbids its presence */ - - - if (!ALLOWED_TAGS[tagName] || FORBID_TAGS[tagName]) { - /* Check if we have a custom element to handle */ - if (!FORBID_TAGS[tagName] && _basicCustomElementTest(tagName)) { - if (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, tagName)) return false; - if (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(tagName)) return false; - } - /* Keep content except for bad-listed elements */ - - - if (KEEP_CONTENT && !FORBID_CONTENTS[tagName]) { - const parentNode = getParentNode(currentNode) || currentNode.parentNode; - const childNodes = getChildNodes(currentNode) || currentNode.childNodes; - - if (childNodes && parentNode) { - const childCount = childNodes.length; - - for (let i = childCount - 1; i >= 0; --i) { - parentNode.insertBefore(cloneNode(childNodes[i], true), getNextSibling(currentNode)); - } - } - } - - _forceRemove(currentNode); - - return true; - } - /* Check whether element has a valid namespace */ - - - if (currentNode instanceof Element && !_checkValidNamespace(currentNode)) { - _forceRemove(currentNode); - - return true; - } - /* Make sure that older browsers don't get fallback-tag mXSS */ - - - if ((tagName === 'noscript' || tagName === 'noembed' || tagName === 'noframes') && regExpTest(/<\/no(script|embed|frames)/i, currentNode.innerHTML)) { - _forceRemove(currentNode); - - return true; - } - /* Sanitize element content to be template-safe */ - - - if (SAFE_FOR_TEMPLATES && currentNode.nodeType === 3) { - /* Get the element's text content */ - content = currentNode.textContent; - content = stringReplace(content, MUSTACHE_EXPR, ' '); - content = stringReplace(content, ERB_EXPR, ' '); - content = stringReplace(content, TMPLIT_EXPR, ' '); - - if (currentNode.textContent !== content) { - arrayPush(DOMPurify.removed, { - element: currentNode.cloneNode() - }); - currentNode.textContent = content; - } - } - /* Execute a hook if present */ - - - _executeHook('afterSanitizeElements', currentNode, null); - - return false; - }; - /** - * _isValidAttribute - * - * @param {string} lcTag Lowercase tag name of containing element. - * @param {string} lcName Lowercase attribute name. - * @param {string} value Attribute value. - * @return {Boolean} Returns true if `value` is valid, otherwise false. - */ - // eslint-disable-next-line complexity - - - const _isValidAttribute = function _isValidAttribute(lcTag, lcName, value) { - /* Make sure attribute cannot clobber */ - if (SANITIZE_DOM && (lcName === 'id' || lcName === 'name') && (value in document || value in formElement)) { - return false; - } - /* Allow valid data-* attributes: At least one character after "-" - (https://html.spec.whatwg.org/multipage/dom.html#embedding-custom-non-visible-data-with-the-data-*-attributes) - XML-compatible (https://html.spec.whatwg.org/multipage/infrastructure.html#xml-compatible and http://www.w3.org/TR/xml/#d0e804) - We don't need to check the value; it's always URI safe. */ - - - if (ALLOW_DATA_ATTR && !FORBID_ATTR[lcName] && regExpTest(DATA_ATTR, lcName)) ; else if (ALLOW_ARIA_ATTR && regExpTest(ARIA_ATTR, lcName)) ; else if (!ALLOWED_ATTR[lcName] || FORBID_ATTR[lcName]) { - if ( // First condition does a very basic check if a) it's basically a valid custom element tagname AND - // b) if the tagName passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.tagNameCheck - // and c) if the attribute name passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.attributeNameCheck - _basicCustomElementTest(lcTag) && (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, lcTag) || CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(lcTag)) && (CUSTOM_ELEMENT_HANDLING.attributeNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.attributeNameCheck, lcName) || CUSTOM_ELEMENT_HANDLING.attributeNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.attributeNameCheck(lcName)) || // Alternative, second condition checks if it's an `is`-attribute, AND - // the value passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.tagNameCheck - lcName === 'is' && CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements && (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, value) || CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(value))) ; else { - return false; - } - /* Check value is safe. First, is attr inert? If so, is safe */ - - } else if (URI_SAFE_ATTRIBUTES[lcName]) ; else if (regExpTest(IS_ALLOWED_URI$1, stringReplace(value, ATTR_WHITESPACE, ''))) ; else if ((lcName === 'src' || lcName === 'xlink:href' || lcName === 'href') && lcTag !== 'script' && stringIndexOf(value, 'data:') === 0 && DATA_URI_TAGS[lcTag]) ; else if (ALLOW_UNKNOWN_PROTOCOLS && !regExpTest(IS_SCRIPT_OR_DATA, stringReplace(value, ATTR_WHITESPACE, ''))) ; else if (value) { - return false; - } else ; - - return true; - }; - /** - * _basicCustomElementCheck - * checks if at least one dash is included in tagName, and it's not the first char - * for more sophisticated checking see https://github.com/sindresorhus/validate-element-name - * @param {string} tagName name of the tag of the node to sanitize - */ - - - const _basicCustomElementTest = function _basicCustomElementTest(tagName) { - return tagName.indexOf('-') > 0; - }; - /** - * _sanitizeAttributes - * - * @protect attributes - * @protect nodeName - * @protect removeAttribute - * @protect setAttribute - * - * @param {Node} currentNode to sanitize - */ - - - const _sanitizeAttributes = function _sanitizeAttributes(currentNode) { - let attr; - let value; - let lcName; - let l; - /* Execute a hook if present */ - - _executeHook('beforeSanitizeAttributes', currentNode, null); - - const { - attributes - } = currentNode; - /* Check if we have attributes; if not we might have a text node */ - - if (!attributes) { - return; - } - - const hookEvent = { - attrName: '', - attrValue: '', - keepAttr: true, - allowedAttributes: ALLOWED_ATTR - }; - l = attributes.length; - /* Go backwards over all attributes; safely remove bad ones */ - - while (l--) { - attr = attributes[l]; - const { - name, - namespaceURI - } = attr; - value = name === 'value' ? attr.value : stringTrim(attr.value); - lcName = transformCaseFunc(name); - /* Execute a hook if present */ - - hookEvent.attrName = lcName; - hookEvent.attrValue = value; - hookEvent.keepAttr = true; - hookEvent.forceKeepAttr = undefined; // Allows developers to see this is a property they can set - - _executeHook('uponSanitizeAttribute', currentNode, hookEvent); - - value = hookEvent.attrValue; - /* Did the hooks approve of the attribute? */ - - if (hookEvent.forceKeepAttr) { - continue; - } - /* Remove attribute */ - - - _removeAttribute(name, currentNode); - /* Did the hooks approve of the attribute? */ - - - if (!hookEvent.keepAttr) { - continue; - } - /* Work around a security issue in jQuery 3.0 */ - - - if (!ALLOW_SELF_CLOSE_IN_ATTR && regExpTest(/\/>/i, value)) { - _removeAttribute(name, currentNode); - - continue; - } - /* Sanitize attribute content to be template-safe */ - - - if (SAFE_FOR_TEMPLATES) { - value = stringReplace(value, MUSTACHE_EXPR, ' '); - value = stringReplace(value, ERB_EXPR, ' '); - value = stringReplace(value, TMPLIT_EXPR, ' '); - } - /* Is `value` valid for this attribute? */ - - - const lcTag = transformCaseFunc(currentNode.nodeName); - - if (!_isValidAttribute(lcTag, lcName, value)) { - continue; - } - /* Full DOM Clobbering protection via namespace isolation, - * Prefix id and name attributes with `user-content-` - */ - - - if (SANITIZE_NAMED_PROPS && (lcName === 'id' || lcName === 'name')) { - // Remove the attribute with this value - _removeAttribute(name, currentNode); // Prefix the value and later re-create the attribute with the sanitized value - - - value = SANITIZE_NAMED_PROPS_PREFIX + value; - } - /* Handle attributes that require Trusted Types */ - - - if (trustedTypesPolicy && typeof trustedTypes === 'object' && typeof trustedTypes.getAttributeType === 'function') { - if (namespaceURI) ; else { - switch (trustedTypes.getAttributeType(lcTag, lcName)) { - case 'TrustedHTML': - { - value = trustedTypesPolicy.createHTML(value); - break; - } - - case 'TrustedScriptURL': - { - value = trustedTypesPolicy.createScriptURL(value); - break; - } - } - } - } - /* Handle invalid data-* attribute set by try-catching it */ - - - try { - if (namespaceURI) { - currentNode.setAttributeNS(namespaceURI, name, value); - } else { - /* Fallback to setAttribute() for browser-unrecognized namespaces e.g. "x-schema". */ - currentNode.setAttribute(name, value); - } - - arrayPop(DOMPurify.removed); - } catch (_) {} - } - /* Execute a hook if present */ - - - _executeHook('afterSanitizeAttributes', currentNode, null); - }; - /** - * _sanitizeShadowDOM - * - * @param {DocumentFragment} fragment to iterate over recursively - */ - - - const _sanitizeShadowDOM = function _sanitizeShadowDOM(fragment) { - let shadowNode; - - const shadowIterator = _createIterator(fragment); - /* Execute a hook if present */ - - - _executeHook('beforeSanitizeShadowDOM', fragment, null); - - while (shadowNode = shadowIterator.nextNode()) { - /* Execute a hook if present */ - _executeHook('uponSanitizeShadowNode', shadowNode, null); - /* Sanitize tags and elements */ - - - if (_sanitizeElements(shadowNode)) { - continue; - } - /* Deep shadow DOM detected */ - - - if (shadowNode.content instanceof DocumentFragment) { - _sanitizeShadowDOM(shadowNode.content); - } - /* Check attributes, sanitize if necessary */ - - - _sanitizeAttributes(shadowNode); - } - /* Execute a hook if present */ - - - _executeHook('afterSanitizeShadowDOM', fragment, null); - }; - /** - * Sanitize - * Public method providing core sanitation functionality - * - * @param {String|Node} dirty string or DOM node - * @param {Object} configuration object - */ - // eslint-disable-next-line complexity - - - DOMPurify.sanitize = function (dirty) { - let cfg = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - let body; - let importedNode; - let currentNode; - let returnNode; - /* Make sure we have a string to sanitize. - DO NOT return early, as this will return the wrong type if - the user has requested a DOM object rather than a string */ - - IS_EMPTY_INPUT = !dirty; - - if (IS_EMPTY_INPUT) { - dirty = ''; - } - /* Stringify, in case dirty is an object */ - - - if (typeof dirty !== 'string' && !_isNode(dirty)) { - if (typeof dirty.toString === 'function') { - dirty = dirty.toString(); - - if (typeof dirty !== 'string') { - throw typeErrorCreate('dirty is not a string, aborting'); - } - } else { - throw typeErrorCreate('toString is not a function'); - } - } - /* Return dirty HTML if DOMPurify cannot run */ - - - if (!DOMPurify.isSupported) { - return dirty; - } - /* Assign config vars */ - - - if (!SET_CONFIG) { - _parseConfig(cfg); - } - /* Clean up removed elements */ - - - DOMPurify.removed = []; - /* Check if dirty is correctly typed for IN_PLACE */ - - if (typeof dirty === 'string') { - IN_PLACE = false; - } - - if (IN_PLACE) { - /* Do some early pre-sanitization to avoid unsafe root nodes */ - if (dirty.nodeName) { - const tagName = transformCaseFunc(dirty.nodeName); - - if (!ALLOWED_TAGS[tagName] || FORBID_TAGS[tagName]) { - throw typeErrorCreate('root node is forbidden and cannot be sanitized in-place'); - } - } - } else if (dirty instanceof Node) { - /* If dirty is a DOM element, append to an empty document to avoid - elements being stripped by the parser */ - body = _initDocument(''); - importedNode = body.ownerDocument.importNode(dirty, true); - - if (importedNode.nodeType === 1 && importedNode.nodeName === 'BODY') { - /* Node is already a body, use as is */ - body = importedNode; - } else if (importedNode.nodeName === 'HTML') { - body = importedNode; - } else { - // eslint-disable-next-line unicorn/prefer-dom-node-append - body.appendChild(importedNode); - } - } else { - /* Exit directly if we have nothing to do */ - if (!RETURN_DOM && !SAFE_FOR_TEMPLATES && !WHOLE_DOCUMENT && // eslint-disable-next-line unicorn/prefer-includes - dirty.indexOf('<') === -1) { - return trustedTypesPolicy && RETURN_TRUSTED_TYPE ? trustedTypesPolicy.createHTML(dirty) : dirty; - } - /* Initialize the document to work on */ - - - body = _initDocument(dirty); - /* Check we have a DOM node from the data */ - - if (!body) { - return RETURN_DOM ? null : RETURN_TRUSTED_TYPE ? emptyHTML : ''; - } - } - /* Remove first element node (ours) if FORCE_BODY is set */ - - - if (body && FORCE_BODY) { - _forceRemove(body.firstChild); - } - /* Get node iterator */ - - - const nodeIterator = _createIterator(IN_PLACE ? dirty : body); - /* Now start iterating over the created document */ - - - while (currentNode = nodeIterator.nextNode()) { - /* Sanitize tags and elements */ - if (_sanitizeElements(currentNode)) { - continue; - } - /* Shadow DOM detected, sanitize it */ - - - if (currentNode.content instanceof DocumentFragment) { - _sanitizeShadowDOM(currentNode.content); - } - /* Check attributes, sanitize if necessary */ - - - _sanitizeAttributes(currentNode); - } - /* If we sanitized `dirty` in-place, return it. */ - - - if (IN_PLACE) { - return dirty; - } - /* Return sanitized string or DOM */ - - - if (RETURN_DOM) { - if (RETURN_DOM_FRAGMENT) { - returnNode = createDocumentFragment.call(body.ownerDocument); - - while (body.firstChild) { - // eslint-disable-next-line unicorn/prefer-dom-node-append - returnNode.appendChild(body.firstChild); - } - } else { - returnNode = body; - } - - if (ALLOWED_ATTR.shadowroot || ALLOWED_ATTR.shadowrootmode) { - /* - AdoptNode() is not used because internal state is not reset - (e.g. the past names map of a HTMLFormElement), this is safe - in theory but we would rather not risk another attack vector. - The state that is cloned by importNode() is explicitly defined - by the specs. - */ - returnNode = importNode.call(originalDocument, returnNode, true); - } - - return returnNode; - } - - let serializedHTML = WHOLE_DOCUMENT ? body.outerHTML : body.innerHTML; - /* Serialize doctype if allowed */ - - if (WHOLE_DOCUMENT && ALLOWED_TAGS['!doctype'] && body.ownerDocument && body.ownerDocument.doctype && body.ownerDocument.doctype.name && regExpTest(DOCTYPE_NAME, body.ownerDocument.doctype.name)) { - serializedHTML = '\n' + serializedHTML; - } - /* Sanitize final string template-safe */ - - - if (SAFE_FOR_TEMPLATES) { - serializedHTML = stringReplace(serializedHTML, MUSTACHE_EXPR, ' '); - serializedHTML = stringReplace(serializedHTML, ERB_EXPR, ' '); - serializedHTML = stringReplace(serializedHTML, TMPLIT_EXPR, ' '); - } - - return trustedTypesPolicy && RETURN_TRUSTED_TYPE ? trustedTypesPolicy.createHTML(serializedHTML) : serializedHTML; - }; - /** - * Public method to set the configuration once - * setConfig - * - * @param {Object} cfg configuration object - */ - - - DOMPurify.setConfig = function (cfg) { - _parseConfig(cfg); - - SET_CONFIG = true; - }; - /** - * Public method to remove the configuration - * clearConfig - * - */ - - - DOMPurify.clearConfig = function () { - CONFIG = null; - SET_CONFIG = false; - }; - /** - * Public method to check if an attribute value is valid. - * Uses last set config, if any. Otherwise, uses config defaults. - * isValidAttribute - * - * @param {string} tag Tag name of containing element. - * @param {string} attr Attribute name. - * @param {string} value Attribute value. - * @return {Boolean} Returns true if `value` is valid. Otherwise, returns false. - */ - - - DOMPurify.isValidAttribute = function (tag, attr, value) { - /* Initialize shared config vars if necessary. */ - if (!CONFIG) { - _parseConfig({}); - } - - const lcTag = transformCaseFunc(tag); - const lcName = transformCaseFunc(attr); - return _isValidAttribute(lcTag, lcName, value); - }; - /** - * AddHook - * Public method to add DOMPurify hooks - * - * @param {String} entryPoint entry point for the hook to add - * @param {Function} hookFunction function to execute - */ - - - DOMPurify.addHook = function (entryPoint, hookFunction) { - if (typeof hookFunction !== 'function') { - return; - } - - hooks[entryPoint] = hooks[entryPoint] || []; - arrayPush(hooks[entryPoint], hookFunction); - }; - /** - * RemoveHook - * Public method to remove a DOMPurify hook at a given entryPoint - * (pops it from the stack of hooks if more are present) - * - * @param {String} entryPoint entry point for the hook to remove - * @return {Function} removed(popped) hook - */ - - - DOMPurify.removeHook = function (entryPoint) { - if (hooks[entryPoint]) { - return arrayPop(hooks[entryPoint]); - } - }; - /** - * RemoveHooks - * Public method to remove all DOMPurify hooks at a given entryPoint - * - * @param {String} entryPoint entry point for the hooks to remove - */ - - - DOMPurify.removeHooks = function (entryPoint) { - if (hooks[entryPoint]) { - hooks[entryPoint] = []; - } - }; - /** - * RemoveAllHooks - * Public method to remove all DOMPurify hooks - * - */ - - - DOMPurify.removeAllHooks = function () { - hooks = {}; - }; - - return DOMPurify; - } - - var purify = createDOMPurify(); - - function createCheckbox$1(name, initialState) { - const container = div$1({class: 'igv-ui-trackgear-popover-check-container'}); - const svg = iconMarkup$2('check', (true === initialState ? '#444' : 'transparent')); - svg.style.borderColor = 'gray'; - svg.style.borderWidth = '1px'; - svg.style.borderStyle = 'solid'; - - container.appendChild(svg); - let label = div$1(); //{ class: 'igv-some-label-class' }); - label.textContent = name; - container.appendChild(label); - - return container; - } - - function createIcon$2(name, color) { - return iconMarkup$2(name, color); - } - - function iconMarkup$2(name, color) { - color = color || "currentColor"; - let icon = icons$2[name]; - if (!icon) { - console.error(`No icon named: ${name}`); - icon = icons$2["question"]; - } - - const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg"); - svg.setAttributeNS(null,'viewBox', '0 0 ' + icon[0] + ' ' + icon[1]); - const path = document.createElementNS("http://www.w3.org/2000/svg", "path"); - path.setAttributeNS(null,'fill', color ); - path.setAttributeNS(null,'d', icon[4]); - svg.appendChild(path); - return svg; - } - - const icons$2 = { - "check": [512, 512, [], "f00c", "M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z"], - "cog": [512, 512, [], "f013", "M444.788 291.1l42.616 24.599c4.867 2.809 7.126 8.618 5.459 13.985-11.07 35.642-29.97 67.842-54.689 94.586a12.016 12.016 0 0 1-14.832 2.254l-42.584-24.595a191.577 191.577 0 0 1-60.759 35.13v49.182a12.01 12.01 0 0 1-9.377 11.718c-34.956 7.85-72.499 8.256-109.219.007-5.49-1.233-9.403-6.096-9.403-11.723v-49.184a191.555 191.555 0 0 1-60.759-35.13l-42.584 24.595a12.016 12.016 0 0 1-14.832-2.254c-24.718-26.744-43.619-58.944-54.689-94.586-1.667-5.366.592-11.175 5.459-13.985L67.212 291.1a193.48 193.48 0 0 1 0-70.199l-42.616-24.599c-4.867-2.809-7.126-8.618-5.459-13.985 11.07-35.642 29.97-67.842 54.689-94.586a12.016 12.016 0 0 1 14.832-2.254l42.584 24.595a191.577 191.577 0 0 1 60.759-35.13V25.759a12.01 12.01 0 0 1 9.377-11.718c34.956-7.85 72.499-8.256 109.219-.007 5.49 1.233 9.403 6.096 9.403 11.723v49.184a191.555 191.555 0 0 1 60.759 35.13l42.584-24.595a12.016 12.016 0 0 1 14.832 2.254c24.718 26.744 43.619 58.944 54.689 94.586 1.667 5.366-.592 11.175-5.459 13.985L444.788 220.9a193.485 193.485 0 0 1 0 70.2zM336 256c0-44.112-35.888-80-80-80s-80 35.888-80 80 35.888 80 80 80 80-35.888 80-80z"], - "exclamation": [192, 512, [], "f12a", "M176 432c0 44.112-35.888 80-80 80s-80-35.888-80-80 35.888-80 80-80 80 35.888 80 80zM25.26 25.199l13.6 272C39.499 309.972 50.041 320 62.83 320h66.34c12.789 0 23.331-10.028 23.97-22.801l13.6-272C167.425 11.49 156.496 0 142.77 0H49.23C35.504 0 24.575 11.49 25.26 25.199z"], - "exclamation-circle": [512, 512, [], "f06a", "M504 256c0 136.997-111.043 248-248 248S8 392.997 8 256C8 119.083 119.043 8 256 8s248 111.083 248 248zm-248 50c-25.405 0-46 20.595-46 46s20.595 46 46 46 46-20.595 46-46-20.595-46-46-46zm-43.673-165.346l7.418 136c.347 6.364 5.609 11.346 11.982 11.346h48.546c6.373 0 11.635-4.982 11.982-11.346l7.418-136c.375-6.874-5.098-12.654-11.982-12.654h-63.383c-6.884 0-12.356 5.78-11.981 12.654z"], - "exclamation-triangle": [576, 512, [], "f071", "M569.517 440.013C587.975 472.007 564.806 512 527.94 512H48.054c-36.937 0-59.999-40.055-41.577-71.987L246.423 23.985c18.467-32.009 64.72-31.951 83.154 0l239.94 416.028zM288 354c-25.405 0-46 20.595-46 46s20.595 46 46 46 46-20.595 46-46-20.595-46-46-46zm-43.673-165.346l7.418 136c.347 6.364 5.609 11.346 11.982 11.346h48.546c6.373 0 11.635-4.982 11.982-11.346l7.418-136c.375-6.874-5.098-12.654-11.982-12.654h-63.383c-6.884 0-12.356 5.78-11.981 12.654z"], - "minus": [448, 512, [], "f068", "M424 318.2c13.3 0 24-10.7 24-24v-76.4c0-13.3-10.7-24-24-24H24c-13.3 0-24 10.7-24 24v76.4c0 13.3 10.7 24 24 24h400z"], - "minus-circle": [512, 512, [], "f056", "M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zM124 296c-6.6 0-12-5.4-12-12v-56c0-6.6 5.4-12 12-12h264c6.6 0 12 5.4 12 12v56c0 6.6-5.4 12-12 12H124z"], - "minus-square": [448, 512, [], "f146", "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM92 296c-6.6 0-12-5.4-12-12v-56c0-6.6 5.4-12 12-12h264c6.6 0 12 5.4 12 12v56c0 6.6-5.4 12-12 12H92z"], - "plus": [448, 512, [], "f067", "M448 294.2v-76.4c0-13.3-10.7-24-24-24H286.2V56c0-13.3-10.7-24-24-24h-76.4c-13.3 0-24 10.7-24 24v137.8H24c-13.3 0-24 10.7-24 24v76.4c0 13.3 10.7 24 24 24h137.8V456c0 13.3 10.7 24 24 24h76.4c13.3 0 24-10.7 24-24V318.2H424c13.3 0 24-10.7 24-24z"], - "plus-circle": [512, 512, [], "f055", "M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm144 276c0 6.6-5.4 12-12 12h-92v92c0 6.6-5.4 12-12 12h-56c-6.6 0-12-5.4-12-12v-92h-92c-6.6 0-12-5.4-12-12v-56c0-6.6 5.4-12 12-12h92v-92c0-6.6 5.4-12 12-12h56c6.6 0 12 5.4 12 12v92h92c6.6 0 12 5.4 12 12v56z"], - "plus-square": [448, 512, [], "f0fe", "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-32 252c0 6.6-5.4 12-12 12h-92v92c0 6.6-5.4 12-12 12h-56c-6.6 0-12-5.4-12-12v-92H92c-6.6 0-12-5.4-12-12v-56c0-6.6 5.4-12 12-12h92v-92c0-6.6 5.4-12 12-12h56c6.6 0 12 5.4 12 12v92h92c6.6 0 12 5.4 12 12v56z"], - "question": [384, 512, [], "f128", "M202.021 0C122.202 0 70.503 32.703 29.914 91.026c-7.363 10.58-5.093 25.086 5.178 32.874l43.138 32.709c10.373 7.865 25.132 6.026 33.253-4.148 25.049-31.381 43.63-49.449 82.757-49.449 30.764 0 68.816 19.799 68.816 49.631 0 22.552-18.617 34.134-48.993 51.164-35.423 19.86-82.299 44.576-82.299 106.405V320c0 13.255 10.745 24 24 24h72.471c13.255 0 24-10.745 24-24v-5.773c0-42.86 125.268-44.645 125.268-160.627C377.504 66.256 286.902 0 202.021 0zM192 373.459c-38.196 0-69.271 31.075-69.271 69.271 0 38.195 31.075 69.27 69.271 69.27s69.271-31.075 69.271-69.271-31.075-69.27-69.271-69.27z"], - "save": [448, 512, [], "f0c7", "M433.941 129.941l-83.882-83.882A48 48 0 0 0 316.118 32H48C21.49 32 0 53.49 0 80v352c0 26.51 21.49 48 48 48h352c26.51 0 48-21.49 48-48V163.882a48 48 0 0 0-14.059-33.941zM224 416c-35.346 0-64-28.654-64-64 0-35.346 28.654-64 64-64s64 28.654 64 64c0 35.346-28.654 64-64 64zm96-304.52V212c0 6.627-5.373 12-12 12H76c-6.627 0-12-5.373-12-12V108c0-6.627 5.373-12 12-12h228.52c3.183 0 6.235 1.264 8.485 3.515l3.48 3.48A11.996 11.996 0 0 1 320 111.48z"], - "search": [512, 512, [], "f002", "M505 442.7L405.3 343c-4.5-4.5-10.6-7-17-7H372c27.6-35.3 44-79.7 44-128C416 93.1 322.9 0 208 0S0 93.1 0 208s93.1 208 208 208c48.3 0 92.7-16.4 128-44v16.3c0 6.4 2.5 12.5 7 17l99.7 99.7c9.4 9.4 24.6 9.4 33.9 0l28.3-28.3c9.4-9.4 9.4-24.6.1-34zM208 336c-70.7 0-128-57.2-128-128 0-70.7 57.2-128 128-128 70.7 0 128 57.2 128 128 0 70.7-57.2 128-128 128z"], - "share": [512, 512, [], "f064", "M503.691 189.836L327.687 37.851C312.281 24.546 288 35.347 288 56.015v80.053C127.371 137.907 0 170.1 0 322.326c0 61.441 39.581 122.309 83.333 154.132 13.653 9.931 33.111-2.533 28.077-18.631C66.066 312.814 132.917 274.316 288 272.085V360c0 20.7 24.3 31.453 39.687 18.164l176.004-152c11.071-9.562 11.086-26.753 0-36.328z"], - "spinner": [512, 512, [], "f110", "M304 48c0 26.51-21.49 48-48 48s-48-21.49-48-48 21.49-48 48-48 48 21.49 48 48zm-48 368c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48-21.49-48-48-48zm208-208c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48-21.49-48-48-48zM96 256c0-26.51-21.49-48-48-48S0 229.49 0 256s21.49 48 48 48 48-21.49 48-48zm12.922 99.078c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48c0-26.509-21.491-48-48-48zm294.156 0c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48c0-26.509-21.49-48-48-48zM108.922 60.922c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48-21.491-48-48-48z"], - "square": [448, 512, [], "f0c8", "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48z"], - "square-full": [512, 512, [], "f45c", "M512 512H0V0h512v512z"], - "times": [384, 512, [], "f00d", "M323.1 441l53.9-53.9c9.4-9.4 9.4-24.5 0-33.9L279.8 256l97.2-97.2c9.4-9.4 9.4-24.5 0-33.9L323.1 71c-9.4-9.4-24.5-9.4-33.9 0L192 168.2 94.8 71c-9.4-9.4-24.5-9.4-33.9 0L7 124.9c-9.4 9.4-9.4 24.5 0 33.9l97.2 97.2L7 353.2c-9.4 9.4-9.4 24.5 0 33.9L60.9 441c9.4 9.4 24.5 9.4 33.9 0l97.2-97.2 97.2 97.2c9.3 9.3 24.5 9.3 33.9 0z"], - "times-circle": [512, 512, [], "f057", "M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm121.6 313.1c4.7 4.7 4.7 12.3 0 17L338 377.6c-4.7 4.7-12.3 4.7-17 0L256 312l-65.1 65.6c-4.7 4.7-12.3 4.7-17 0L134.4 338c-4.7-4.7-4.7-12.3 0-17l65.6-65-65.6-65.1c-4.7-4.7-4.7-12.3 0-17l39.6-39.6c4.7-4.7 12.3-4.7 17 0l65 65.7 65.1-65.6c4.7-4.7 12.3-4.7 17 0l39.6 39.6c4.7 4.7 4.7 12.3 0 17L312 256l65.6 65.1z"], - "wrench": [512, 512, [], "f0ad", "M481.156 200c9.3 0 15.12 10.155 10.325 18.124C466.295 259.992 420.419 288 368 288c-79.222 0-143.501-63.974-143.997-143.079C223.505 65.469 288.548-.001 368.002 0c52.362.001 98.196 27.949 123.4 69.743C496.24 77.766 490.523 88 481.154 88H376l-40 56 40 56h105.156zm-171.649 93.003L109.255 493.255c-24.994 24.993-65.515 24.994-90.51 0-24.993-24.994-24.993-65.516 0-90.51L218.991 202.5c16.16 41.197 49.303 74.335 90.516 90.503zM104 432c0-13.255-10.745-24-24-24s-24 10.745-24 24 10.745 24 24 24 24-10.745 24-24z"], - }; - - var icons$1$1 = /*#__PURE__*/Object.freeze({ - __proto__: null, - createCheckbox: createCheckbox$1, - createIcon: createIcon$2 - }); - - function attachDialogCloseHandlerWithParent$1(parent, closeHandler) { - - var container = document.createElement("div"); - parent.appendChild(container); - container.appendChild(createIcon$2("times")); - container.addEventListener('click', function (e) { - e.preventDefault(); - e.stopPropagation(); - closeHandler(); - }); - } - - var uiUtils$1 = /*#__PURE__*/Object.freeze({ - __proto__: null, - attachDialogCloseHandlerWithParent: attachDialogCloseHandlerWithParent$1 - }); - - /** - * Make the target element movable by clicking and dragging on the handle. This is not a general purprose function, - * it makes several options specific to igv dialogs, the primary one being that the - * target is absolutely positioned in pixel coordinates - - */ - - let dragData$1; // Its assumed we are only dragging one element at a time. - - function makeDraggable$1(target, handle, constraint) { - - handle.addEventListener('mousedown', dragStart.bind(target)); - - function dragStart(event) { - - event.stopPropagation(); - event.preventDefault(); - - const dragFunction = drag$1.bind(this); - const dragEndFunction = dragEnd$1.bind(this); - const computedStyle = getComputedStyle(this); - - dragData$1 = - { - constraint, - dragFunction, - dragEndFunction, - screenX: event.screenX, - screenY: event.screenY, - top: parseInt(computedStyle.top.replace("px", "")), - left: parseInt(computedStyle.left.replace("px", "")) - }; - - document.addEventListener('mousemove', dragFunction); - document.addEventListener('mouseup', dragEndFunction); - document.addEventListener('mouseleave', dragEndFunction); - document.addEventListener('mouseexit', dragEndFunction); - } - } - - function drag$1(event) { - - if (!dragData$1) { - console.error("No drag data!"); - return; - } - event.stopPropagation(); - event.preventDefault(); - const dx = event.screenX - dragData$1.screenX; - const dy = event.screenY - dragData$1.screenY; - - const left = dragData$1.left + dx; - const top = dragData$1.constraint ? Math.max(dragData$1.constraint.minY, dragData$1.top + dy) : dragData$1.top + dy; - - this.style.left = `${ left }px`; - this.style.top = `${ top }px`; - } - - function dragEnd$1(event) { - - if (!dragData$1) { - console.error("No drag data!"); - return; - } - event.stopPropagation(); - event.preventDefault(); - - const dragFunction = dragData$1.dragFunction; - const dragEndFunction = dragData$1.dragEndFunction; - document.removeEventListener('mousemove', dragFunction); - document.removeEventListener('mouseup', dragEndFunction); - document.removeEventListener('mouseleave', dragEndFunction); - document.removeEventListener('mouseexit', dragEndFunction); - dragData$1 = undefined; - } - - const httpMessages$1 = - { - "401": "Access unauthorized", - "403": "Access forbidden", - "404": "Not found" - }; - - - class AlertDialog$1 { - /** - * Initialize a new alert dialog - * @param parent - * @param alertProps - Optional - properties such as scroll to error - */ - constructor(parent, alertProps) { - this.alertProps = Object.assign({ - /** When an alert is presented - focus occur */ - shouldFocus: true, - /** When focus occur - scroll into that element in the view */ - preventScroll: false - }, alertProps); - - // container - this.container = div$1({class: "igv-ui-alert-dialog-container"}); - parent.appendChild(this.container); - this.container.setAttribute('tabIndex', '-1'); - - // header - const header = div$1(); - this.container.appendChild(header); - - this.errorHeadline = div$1(); - header.appendChild(this.errorHeadline); - this.errorHeadline.textContent = ''; - - // body container - let bodyContainer = div$1({class: 'igv-ui-alert-dialog-body'}); - this.container.appendChild(bodyContainer); - - // body copy - this.body = div$1({class: 'igv-ui-alert-dialog-body-copy'}); - bodyContainer.appendChild(this.body); - - // ok container - let ok_container = div$1(); - this.container.appendChild(ok_container); - - // ok - this.ok = div$1(); - ok_container.appendChild(this.ok); - this.ok.textContent = 'OK'; - - const okHandler = () => { - - if (typeof this.callback === 'function') { - this.callback("OK"); - this.callback = undefined; - } - this.body.innerHTML = ''; - hide$1(this.container); - }; - - this.ok.addEventListener('click', event => { - - event.stopPropagation(); - - okHandler(); - }); - - this.container.addEventListener('keypress', event => { - - event.stopPropagation(); - - if ('Enter' === event.key) { - okHandler(); - } - }); - - makeDraggable$1(this.container, header); - - hide$1(this.container); - } - - present(alert, callback) { - - this.errorHeadline.textContent = alert.message ? 'ERROR' : ''; - let string = alert.message || alert; - - if (httpMessages$1.hasOwnProperty(string)) { - string = httpMessages$1[string]; - } - - const clean = purify.sanitize(string); - - this.body.innerHTML = clean; - this.callback = callback; - show$1(this.container); - if (this.alertProps.shouldFocus) { - this.container.focus( - { preventScroll: this.alertProps.preventScroll } - ); - } - } - } - - class InputDialog$1 { - - constructor(parent) { - - this.parent = parent; - - // dialog container - this.container = div$1({class: 'igv-ui-generic-dialog-container'}); - parent.appendChild(this.container); - - // const { x, y, width, height } = this.container.getBoundingClientRect(); - // console.log(`InputDialog - x ${ x } y ${ y } width ${ width } height ${ height }`) - - // dialog header - const header = div$1({class: 'igv-ui-generic-dialog-header'}); - this.container.appendChild(header); - - // dialog label - this.label = div$1({class: 'igv-ui-generic-dialog-one-liner'}); - this.container.appendChild(this.label); - this.label.text = 'Unlabeled'; - - // input container - this.input_container = div$1({class: 'igv-ui-generic-dialog-input'}); - this.container.appendChild(this.input_container); - // - this.input = document.createElement("input"); - this.input_container.appendChild(this.input); - - - // ok | cancel - const buttons = div$1({class: 'igv-ui-generic-dialog-ok-cancel'}); - this.container.appendChild(buttons); - - // ok - this.ok = div$1(); - buttons.appendChild(this.ok); - this.ok.textContent = 'OK'; - - // cancel - this.cancel = div$1(); - buttons.appendChild(this.cancel); - this.cancel.textContent = 'Cancel'; - - hide$1(this.container); - - this.input.addEventListener('keyup', e => { - if (13 === e.keyCode) { - if (typeof this.callback === 'function') { - this.callback(this.input.value); - this.callback = undefined; - } - this.input.value = undefined; - hide$1(this.container); - } - }); - - this.ok.addEventListener('click', () => { - if (typeof this.callback === 'function') { - this.callback(this.input.value); - this.callback = undefined; - } - this.input.value = undefined; - hide$1(this.container); - }); - - const cancel = () => { - this.input.value = ''; - hide$1(this.container); - }; - - this.cancel.addEventListener('click', cancel); - - attachDialogCloseHandlerWithParent$1(header, cancel); - makeDraggable$1(this.container, header); - - } - - get value() { - return purify.sanitize(this.input.value) - } - - present(options, e) { - - this.label.textContent = options.label; - this.input.value = options.value; - this.callback = options.callback || options.click; - - show$1(this.container); - this.clampLocation(e.clientX, e.clientY); - - } - - clampLocation(clientX, clientY) { - - const {width: w, height: h} = this.container.getBoundingClientRect(); - const wh = window.innerHeight; - const ww = window.innerWidth; - - const y = Math.min(wh - h, clientY); - const x = Math.min(ww - w, clientX); - this.container.style.left = `${x}px`; - this.container.style.top = `${y}px`; - - } - } - - const appleCrayonPalette$1 = - { - licorice: "#000000", - lead: "#1e1e1e", - tungsten: "#3a3a3a", - iron: "#545453", - steel: "#6e6e6e", - tin: "#878687", - nickel: "#888787", - aluminum: "#a09fa0", - magnesium: "#b8b8b8", - silver: "#d0d0d0", - mercury: "#e8e8e8", - snow: "#ffffff", - // - cayenne: "#891100", - mocha: "#894800", - aspargus: "#888501", - fern: "#458401", - clover: "#028401", - moss: "#018448", - teal: "#008688", - ocean: "#004a88", - midnight: "#001888", - eggplant: "#491a88", - plum: "#891e88", - maroon: "#891648", - // - maraschino: "#ff2101", - tangerine: "#ff8802", - lemon: "#fffa03", - lime: "#83f902", - spring: "#05f802", - seam_foam: "#03f987", - turquoise: "#00fdff", - aqua: "#008cff", - blueberry: "#002eff", - grape: "#8931ff", - magenta: "#ff39ff", - strawberry: "#ff2987", - // - salmon: "#ff726e", - cantaloupe: "#ffce6e", - banana: "#fffb6d", - honeydew: "#cefa6e", - flora: "#68f96e", - spindrift: "#68fbd0", - ice: "#68fdff", - sky: "#6acfff", - orchid: "#6e76ff", - lavender: "#d278ff", - bubblegum: "#ff7aff", - carnation: "#ff7fd3" - }; - - class GenericContainer$1 { - - constructor({parent, top, left, width, height, border, closeHandler}) { - - let container = div$1({class: 'igv-ui-generic-container'}); - parent.appendChild(container); - hide$1(container); - this.container = container; - - if(top !== undefined) { - this.container.style.top = `${ top }px`; - } - if(left !== undefined) { - this.container.style.left = `${ left }px`; - } - if (width !== undefined) { - this.container.style.width = `${ width }px`; - } - if (height !== undefined) { - this.container.style.height = `${ height }px`; - } - if(border) { - this.container.style.border = border; - } - // - // let bbox = parent.getBoundingClientRect(); - // this.origin = {x: bbox.x, y: bbox.y}; - // this.container.offset({left: this.origin.x, top: this.origin.y}); - - // header - const header = div$1(); - this.container.appendChild(header); - - // close button - attachDialogCloseHandlerWithParent$1(header, (e) => { - hide$1(this.container); - if(typeof closeHandler === "function") { - closeHandler(e); - } - }); - - makeDraggable$1(this.container, header); - } - - show() { - show$1(this.container); - } - - hide() { - hide$1(this.container); - } - - dispose() { - if(this.container.parent) { - this.container.parent.removeChild(this.container); - } - } - } - - class ColorPicker$1 extends GenericContainer$1 { - - constructor({parent, top, left, width, height, defaultColors, colorHandler}) { - - super({ parent, top, left, width, height, border: '1px solid gray'}); - - createColorSwatchSelector$1(this.container, colorHandler, defaultColors); - } - - } - - const createColorSwatchSelector$1 = (container, colorHandler, defaultColors) => { - - const hexColorStrings = Object.values(appleCrayonPalette$1); - - for (let hexColorString of hexColorStrings) { - const swatch = div$1({ class: 'igv-ui-color-swatch' }); - container.appendChild(swatch); - decorateSwatch$1(swatch, hexColorString, colorHandler); - } - - if (defaultColors) { - for (let hexColorString of defaultColors) { - const swatch = div$1({ class: 'igv-ui-color-swatch' }); - container.appendChild(swatch); - decorateSwatch$1(swatch, hexColorString, colorHandler); - } - } - - }; - - const decorateSwatch$1 = (swatch, hexColorString, colorHandler) => { - - swatch.style.backgroundColor = hexColorString; - - swatch.addEventListener('mouseenter', e => swatch.style.borderColor = hexColorString); - - swatch.addEventListener('mouseleave', e => swatch.style.borderColor = 'white'); - - swatch.addEventListener('click', event => { - event.stopPropagation(); - colorHandler(hexColorString); - }); - - swatch.addEventListener('touchend', event => { - event.stopPropagation(); - colorHandler(hexColorString); - }); - - }; - - class Popover { - - constructor(parent, title) { - - this.parent = parent; - - // popover - this.popover = div$1({ class: "igv-ui-popover" }); - parent.appendChild(this.popover); - - // header - const popoverHeader = div$1(); - this.popover.appendChild(popoverHeader); - - const titleElement = div$1(); - popoverHeader.appendChild(titleElement); - if (title) { - titleElement.textContent = title; - } - - attachDialogCloseHandlerWithParent$1(popoverHeader, () => this.hide()); - makeDraggable$1(this.popover, popoverHeader); - - // content - this.popoverContent = div$1(); - this.popover.appendChild(this.popoverContent); - - this.popover.style.display = 'none'; - - - } - - presentContentWithEvent(e, content) { - - this.popover.style.display = 'block'; - - this.popoverContent.innerHTML = content; - - present$1(e, this.popover, this.popoverContent); - - } - - presentMenu(e, menuItems) { - - if (0 === menuItems.length) { - return - } - - this.popover.style.display = 'block'; - - const menuElements = createMenuElements$1(menuItems, this.popover); - for (let item of menuElements) { - this.popoverContent.appendChild(item.object); - } - - present$1(e, this.popover, this.popoverContent); - } - - hide() { - this.popover.style.display = 'none'; - this.dispose(); - } - - dispose() { - - if (this.popover) { - this.popover.parentNode.removeChild(this.popover); - } - - const keys = Object.keys(this); - for (let key of keys) { - this[ key ] = undefined; - } - } - - } - - function present$1(e, popover, popoverContent) { - - const { x, y, width } = translateMouseCoordinates$1(e, popover.parentNode); - popover.style.top = `${ y }px`; - - const { width: w } = popover.getBoundingClientRect(); - - const xmax = x + w; - const delta = xmax - width; - - popover.style.left = `${ xmax > width ? (x - delta) : x }px`; - popoverContent.style.maxWidth = `${ Math.min(w, width) }px`; - - - } - - function createMenuElements$1(itemList, popover) { - - const list = itemList.map(function (item, i) { - let elem; - - if (typeof item === 'string') { - elem = div$1(); - elem.innerHTML = item; - } else if (typeof item === 'Node') { - elem = item; - } else { - if (typeof item.init === 'function') { - item.init(); - } - - if ("checkbox" === item.type) { - elem = createCheckbox$1("Show all bases", item.value); - } else if("color" === item.type) { - const colorPicker = new ColorPicker$1({ - parent: popover.parentElement, - width: 364, - //defaultColor: 'aqua', - colorHandler: (color) => item.click(color) - }); - elem = div$1(); - if (typeof item.label === 'string') { - elem.innerHTML = item.label; - } - const clickHandler = e => { - colorPicker.show(); - hide$1(popover); - e.preventDefault(); - e.stopPropagation(); - }; - elem.addEventListener('click', clickHandler); - elem.addEventListener('touchend', clickHandler); - elem.addEventListener('mouseup', function (e) { - e.preventDefault(); - e.stopPropagation(); - }); - } - - else { - elem = div$1(); - if (typeof item.label === 'string') { - elem.innerHTML = item.label; - } - } - - if (item.click && "color" !== item.type) { - elem.addEventListener('click', handleClick); - elem.addEventListener('touchend', handleClick); - elem.addEventListener('mouseup', function (e) { - e.preventDefault(); - e.stopPropagation(); - }); - - // eslint-disable-next-line no-inner-declarations - function handleClick(e) { - item.click(); - hide$1(popover); - e.preventDefault(); - e.stopPropagation(); - } - } - } - - - return { object: elem, init: item.init }; - }); - - return list; - } - - class GenericColorPicker extends GenericContainer$1 { - - constructor({parent, width}) { - super({parent, width, border: '1px solid gray'}); - } - - configure(defaultColors, colorHandlers) { - - this.colorHandlers = colorHandlers; - - // active color handler defaults to handler with 'color' as key - this.setActiveColorHandler('color'); - - this.createSwatches(defaultColors); - - } - - setActiveColorHandler(option) { - this.activeColorHandler = this.colorHandlers[option]; - } - - createSwatches(defaultColors) { - - this.container.querySelectorAll('.igv-ui-color-swatch').forEach(swatch => swatch.remove()); - - const hexColorStrings = Object.values(appleCrayonPalette$1); - - for (let hexColorString of hexColorStrings) { - const swatch = div$1({class: 'igv-ui-color-swatch'}); - this.container.appendChild(swatch); - this.decorateSwatch(swatch, hexColorString); - } - - if (defaultColors) { - for (let hexColorString of defaultColors) { - const swatch = div$1({class: 'igv-ui-color-swatch'}); - this.container.appendChild(swatch); - this.decorateSwatch(swatch, hexColorString); - } - } - - } - - decorateSwatch(swatch, hexColorString) { - - swatch.style.backgroundColor = hexColorString; - - swatch.addEventListener('mouseenter', () => swatch.style.borderColor = hexColorString); - - swatch.addEventListener('mouseleave', () => swatch.style.borderColor = 'white'); - - swatch.addEventListener('click', event => { - event.stopPropagation(); - this.activeColorHandler(hexColorString); - }); - - swatch.addEventListener('touchend', event => { - event.stopPropagation(); - this.activeColorHandler(hexColorString); - }); - - } - - } - - function embedCSS$2() { - const style = document.createElement('style'); - style.setAttribute('type', 'text/css'); - style.setAttribute('title', 'igv-ui.css'); - style.innerHTML = `.igv-ui-popover { - cursor: default; - position: absolute; - z-index: 2048; - border-color: #7F7F7F; - border-radius: 4px; - border-style: solid; - border-width: 1px; - font-family: "Open Sans", sans-serif; - font-size: small; - background-color: white; -} -.igv-ui-popover > div:first-child { - display: flex; - flex-direction: row; - flex-wrap: nowrap; - justify-content: space-between; - align-items: center; - width: 100%; - height: 24px; - cursor: move; - border-top-left-radius: 4px; - border-top-right-radius: 4px; - border-bottom-color: #7F7F7F; - border-bottom-style: solid; - border-bottom-width: thin; - background-color: #eee; -} -.igv-ui-popover > div:first-child > div:first-child { - margin-left: 4px; -} -.igv-ui-popover > div:first-child > div:last-child { - margin-right: 4px; - height: 12px; - width: 12px; - color: #7F7F7F; -} -.igv-ui-popover > div:first-child > div:last-child:hover { - cursor: pointer; - color: #444; -} -.igv-ui-popover > div:last-child { - overflow-y: auto; - overflow-x: hidden; - max-height: 400px; - max-width: 800px; - background-color: white; -} -.igv-ui-popover > div:last-child > div { - user-select: all; - margin-left: 4px; - margin-right: 4px; - min-width: 220px; - overflow-x: hidden; - text-overflow: ellipsis; - white-space: nowrap; -} -.igv-ui-popover > div:last-child > div > span { - font-weight: bolder; -} -.igv-ui-popover > div:last-child hr { - width: 100%; -} - -.igv-ui-alert-dialog-container { - box-sizing: content-box; - position: absolute; - z-index: 2048; - top: 50%; - left: 50%; - width: 400px; - height: 200px; - border-color: #7F7F7F; - border-radius: 4px; - border-style: solid; - border-width: thin; - outline: none; - font-family: "Open Sans", sans-serif; - font-size: 15px; - font-weight: 400; - background-color: white; - display: flex; - flex-flow: column; - flex-wrap: nowrap; - justify-content: space-between; - align-items: center; -} -.igv-ui-alert-dialog-container > div:first-child { - display: flex; - flex-flow: row; - flex-wrap: nowrap; - justify-content: flex-start; - align-items: center; - width: 100%; - height: 24px; - cursor: move; - border-top-left-radius: 4px; - border-top-right-radius: 4px; - border-bottom-color: #7F7F7F; - border-bottom-style: solid; - border-bottom-width: thin; - background-color: #eee; -} -.igv-ui-alert-dialog-container > div:first-child div:first-child { - padding-left: 8px; -} -.igv-ui-alert-dialog-container .igv-ui-alert-dialog-body { - -webkit-user-select: text; - -moz-user-select: text; - -ms-user-select: text; - user-select: text; - color: #373737; - width: 100%; - height: calc(100% - 24px - 64px); - overflow-y: scroll; -} -.igv-ui-alert-dialog-container .igv-ui-alert-dialog-body .igv-ui-alert-dialog-body-copy { - margin: 16px; - width: auto; - height: auto; - overflow-wrap: break-word; - word-break: break-word; - background-color: white; - border: unset; -} -.igv-ui-alert-dialog-container > div:last-child { - width: 100%; - margin-bottom: 10px; - background-color: white; - display: flex; - flex-flow: row; - flex-wrap: nowrap; - justify-content: center; - align-items: center; -} -.igv-ui-alert-dialog-container > div:last-child div { - margin: unset; - width: 40px; - height: 30px; - line-height: 30px; - text-align: center; - color: white; - font-family: "Open Sans", sans-serif; - font-size: small; - font-weight: 400; - border-color: #2B81AF; - border-style: solid; - border-width: thin; - border-radius: 4px; - background-color: #2B81AF; -} -.igv-ui-alert-dialog-container > div:last-child div:hover { - cursor: pointer; - border-color: #25597f; - background-color: #25597f; -} - -.igv-ui-color-swatch { - position: relative; - box-sizing: content-box; - display: flex; - flex-flow: row; - flex-wrap: wrap; - justify-content: center; - align-items: center; - width: 32px; - height: 32px; - border-style: solid; - border-width: 2px; - border-color: white; - border-radius: 4px; -} - -.igv-ui-color-swatch:hover { - border-color: dimgray; -} - -.igv-ui-colorpicker-menu-close-button { - display: flex; - flex-flow: row; - flex-wrap: nowrap; - justify-content: flex-end; - align-items: center; - width: 100%; - height: 32px; - margin-top: 4px; - margin-bottom: 4px; - padding-right: 8px; -} -.igv-ui-colorpicker-menu-close-button i.fa { - display: block; - margin-left: 4px; - margin-right: 4px; - color: #5f5f5f; -} -.igv-ui-colorpicker-menu-close-button i.fa:hover, -.igv-ui-colorpicker-menu-close-button i.fa:focus, -.igv-ui-colorpicker-menu-close-button i.fa:active { - cursor: pointer; - color: #0f0f0f; -} - -.igv-ui-generic-dialog-container { - box-sizing: content-box; - position: fixed; - top: 0; - left: 0; - width: 300px; - height: 200px; - border-color: #7F7F7F; - border-radius: 4px; - border-style: solid; - border-width: thin; - font-family: "Open Sans", sans-serif; - font-size: medium; - font-weight: 400; - z-index: 2048; - background-color: white; - display: flex; - flex-flow: column; - flex-wrap: nowrap; - justify-content: flex-start; - align-items: center; -} -.igv-ui-generic-dialog-container .igv-ui-generic-dialog-header { - display: flex; - flex-flow: row; - flex-wrap: nowrap; - justify-content: flex-end; - align-items: center; - width: 100%; - height: 24px; - cursor: move; - border-top-left-radius: 4px; - border-top-right-radius: 4px; - border-bottom-color: #7F7F7F; - border-bottom-style: solid; - border-bottom-width: thin; - background-color: #eee; -} -.igv-ui-generic-dialog-container .igv-ui-generic-dialog-header div { - margin-right: 4px; - margin-bottom: 2px; - height: 12px; - width: 12px; - color: #7F7F7F; -} -.igv-ui-generic-dialog-container .igv-ui-generic-dialog-header div:hover { - cursor: pointer; - color: #444; -} -.igv-ui-generic-dialog-container .igv-ui-generic-dialog-one-liner { - color: #373737; - width: 95%; - height: 24px; - line-height: 24px; - text-align: left; - margin-top: 8px; - padding-left: 8px; - overflow-wrap: break-word; - background-color: white; -} -.igv-ui-generic-dialog-container .igv-ui-generic-dialog-label-input { - margin-top: 8px; - width: 95%; - height: 24px; - color: #373737; - line-height: 24px; - padding-left: 8px; - background-color: white; - display: flex; - flex-flow: row; - flex-wrap: nowrap; - justify-content: flex-start; - align-items: center; -} -.igv-ui-generic-dialog-container .igv-ui-generic-dialog-label-input div { - width: 30%; - height: 100%; - font-size: 16px; - text-align: right; - padding-right: 8px; - background-color: white; -} -.igv-ui-generic-dialog-container .igv-ui-generic-dialog-label-input input { - display: block; - height: 100%; - width: 100%; - padding-left: 4px; - font-family: "Open Sans", sans-serif; - font-weight: 400; - color: #373737; - text-align: left; - outline: none; - border-style: solid; - border-width: thin; - border-color: #7F7F7F; - background-color: white; -} -.igv-ui-generic-dialog-container .igv-ui-generic-dialog-label-input input { - width: 50%; - font-size: 16px; -} -.igv-ui-generic-dialog-container .igv-ui-generic-dialog-input { - margin-top: 8px; - width: calc(100% - 16px); - height: 24px; - color: #373737; - line-height: 24px; - display: flex; - flex-flow: row; - flex-wrap: nowrap; - justify-content: space-around; - align-items: center; -} -.igv-ui-generic-dialog-container .igv-ui-generic-dialog-input input { - display: block; - height: 100%; - width: 100%; - padding-left: 4px; - font-family: "Open Sans", sans-serif; - font-weight: 400; - color: #373737; - text-align: left; - outline: none; - border-style: solid; - border-width: thin; - border-color: #7F7F7F; - background-color: white; -} -.igv-ui-generic-dialog-container .igv-ui-generic-dialog-input input { - font-size: 16px; -} -.igv-ui-generic-dialog-container .igv-ui-generic-dialog-ok-cancel { - width: 100%; - height: 28px; - display: flex; - flex-flow: row; - flex-wrap: nowrap; - justify-content: space-around; - align-items: center; -} -.igv-ui-generic-dialog-container .igv-ui-generic-dialog-ok-cancel div { - margin-top: 32px; - color: white; - font-family: "Open Sans", sans-serif; - font-size: 14px; - font-weight: 400; - width: 75px; - height: 28px; - line-height: 28px; - text-align: center; - border-color: transparent; - border-style: solid; - border-width: thin; - border-radius: 2px; -} -.igv-ui-generic-dialog-container .igv-ui-generic-dialog-ok-cancel div:first-child { - margin-left: 32px; - margin-right: 0; - background-color: #5ea4e0; -} -.igv-ui-generic-dialog-container .igv-ui-generic-dialog-ok-cancel div:last-child { - margin-left: 0; - margin-right: 32px; - background-color: #c4c4c4; -} -.igv-ui-generic-dialog-container .igv-ui-generic-dialog-ok-cancel div:first-child:hover { - cursor: pointer; - background-color: #3b5c7f; -} -.igv-ui-generic-dialog-container .igv-ui-generic-dialog-ok-cancel div:last-child:hover { - cursor: pointer; - background-color: #7f7f7f; -} -.igv-ui-generic-dialog-container .igv-ui-generic-dialog-ok { - width: 100%; - height: 36px; - margin-top: 32px; - display: flex; - flex-flow: row; - flex-wrap: nowrap; - justify-content: space-around; - align-items: center; -} -.igv-ui-generic-dialog-container .igv-ui-generic-dialog-ok div { - width: 98px; - height: 36px; - line-height: 36px; - text-align: center; - color: white; - font-family: "Open Sans", sans-serif; - font-size: medium; - font-weight: 400; - border-color: white; - border-style: solid; - border-width: thin; - border-radius: 4px; - background-color: #2B81AF; -} -.igv-ui-generic-dialog-container .igv-ui-generic-dialog-ok div:hover { - cursor: pointer; - background-color: #25597f; -} - -.igv-ui-generic-container { - box-sizing: content-box; - position: absolute; - z-index: 2048; - background-color: white; - cursor: pointer; - display: flex; - flex-direction: row; - flex-wrap: wrap; - justify-content: flex-start; - align-items: center; -} -.igv-ui-generic-container > div:first-child { - cursor: move; - display: flex; - flex-flow: row; - flex-wrap: nowrap; - justify-content: flex-end; - align-items: center; - height: 24px; - width: 100%; - background-color: #dddddd; -} -.igv-ui-generic-container > div:first-child > div { - display: block; - color: #5f5f5f; - cursor: pointer; - width: 14px; - height: 14px; - margin-right: 8px; - margin-bottom: 4px; -} - -.igv-ui-dialog { - z-index: 2048; - position: fixed; - width: fit-content; - height: fit-content; - display: flex; - flex-flow: column; - flex-wrap: nowrap; - justify-content: flex-start; - background-color: white; - border-color: #7F7F7F; - border-radius: 4px; - border-style: solid; - border-width: thin; - font-family: "Open Sans", sans-serif; - font-size: medium; - font-weight: 400; -} -.igv-ui-dialog .igv-ui-dialog-header { - display: flex; - flex-flow: row; - flex-wrap: nowrap; - justify-content: flex-end; - align-items: center; - width: 100%; - height: 24px; - cursor: move; - border-top-left-radius: 4px; - border-top-right-radius: 4px; - border-bottom-color: #7F7F7F; - border-bottom-style: solid; - border-bottom-width: thin; - background-color: #eee; -} -.igv-ui-dialog .igv-ui-dialog-header div { - margin-right: 4px; - margin-bottom: 2px; - height: 12px; - width: 12px; - color: #7F7F7F; -} -.igv-ui-dialog .igv-ui-dialog-header div:hover { - cursor: pointer; - color: #444; -} -.igv-ui-dialog .igv-ui-dialog-one-liner { - width: 95%; - height: 24px; - line-height: 24px; - text-align: left; - margin: 8px; - overflow-wrap: break-word; - background-color: white; - font-weight: bold; -} -.igv-ui-dialog .igv-ui-dialog-ok-cancel { - width: 100%; - display: flex; - flex-flow: row; - flex-wrap: nowrap; - justify-content: space-around; - align-items: center; -} -.igv-ui-dialog .igv-ui-dialog-ok-cancel div { - margin: 16px; - margin-top: 32px; - color: white; - font-family: "Open Sans", sans-serif; - font-size: 14px; - font-weight: 400; - width: 75px; - height: 28px; - line-height: 28px; - text-align: center; - border-color: transparent; - border-style: solid; - border-width: thin; - border-radius: 2px; -} -.igv-ui-dialog .igv-ui-dialog-ok-cancel div:first-child { - background-color: #5ea4e0; -} -.igv-ui-dialog .igv-ui-dialog-ok-cancel div:last-child { - background-color: #c4c4c4; -} -.igv-ui-dialog .igv-ui-dialog-ok-cancel div:first-child:hover { - cursor: pointer; - background-color: #3b5c7f; -} -.igv-ui-dialog .igv-ui-dialog-ok-cancel div:last-child:hover { - cursor: pointer; - background-color: #7f7f7f; -} -.igv-ui-dialog .igv-ui-dialog-ok { - width: 100%; - height: 36px; - margin-top: 32px; - display: flex; - flex-flow: row; - flex-wrap: nowrap; - justify-content: space-around; - align-items: center; -} -.igv-ui-dialog .igv-ui-dialog-ok div { - width: 98px; - height: 36px; - line-height: 36px; - text-align: center; - color: white; - font-family: "Open Sans", sans-serif; - font-size: medium; - font-weight: 400; - border-color: white; - border-style: solid; - border-width: thin; - border-radius: 4px; - background-color: #2B81AF; -} -.igv-ui-dialog .igv-ui-dialog-ok div:hover { - cursor: pointer; - background-color: #25597f; -} - -.igv-ui-panel, .igv-ui-panel-row, .igv-ui-panel-column { - z-index: 2048; - background-color: white; - font-family: "Open Sans", sans-serif; - font-size: medium; - font-weight: 400; - display: flex; - justify-content: flex-start; - align-items: flex-start; -} - -.igv-ui-panel-column { - display: flex; - flex-direction: column; -} - -.igv-ui-panel-row { - display: flex; - flex-direction: row; -} - -.igv-ui-textbox { - background-color: white; - font-family: "Open Sans", sans-serif; - font-size: medium; - font-weight: 400; - display: flex; - justify-content: flex-start; - align-items: flex-start; -} - -.igv-ui-table { - background-color: white; -} - -.igv-ui-table thead { - position: sticky; - top: 0; -} - -.igv-ui-table th { - text-align: left; -} - -.igv-ui-table td { - padding-right: 20px; -} - -.igv-ui-table tr:hover { - background-color: lightblue; -} - -/*# sourceMappingURL=igv-ui.css.map */ -`; - document.head.append(style); - } - - if (typeof document !== 'undefined') { - - if (!stylesheetExists("igv-ui.css")) { - embedCSS$2(); - } - - function stylesheetExists(stylesheetName) { - for (let ss of document.styleSheets) { - ss = ss.href ? ss.href.replace(/^.*[\\\/]/, '') : ''; - if (ss === stylesheetName) { - return true - } - } - return false - } - } - - function createCheckbox$2(name, initialState) { - - const container = domUtils$1.div({class: 'igv-menu-popup-check-container'}); - - const div = domUtils$1.div(); - container.appendChild(div); - - const svg = icons$1$1.createIcon('check', (true === initialState ? '#444' : 'transparent')); - div.appendChild(svg); - - const label = domUtils$1.div(); - label.innerText = name; - container.appendChild(label); - - return container - } - - /** - * Configure item list for track "gear" menu. - * @param trackView - */ - const MenuUtils$1 = { - - trackMenuItemList: function (trackView) { - - const vizWindowTypes = new Set(['alignment', 'annotation', 'variant', 'eqtl', 'snp']); - - const hasVizWindow = trackView.track.config && trackView.track.config.visibilityWindow !== undefined; - - let menuItems = []; - - if (trackView.track.config.type !== 'sequence') { - menuItems.push(trackRenameMenuItem$1(trackView)); - menuItems.push(trackHeightMenuItem(trackView)); - } - - if (this.showColorPicker(trackView.track)) { - menuItems.push('
'); - menuItems.push(colorPickerMenuItem$1({trackView, label: "Set track color", option: "color"})); - menuItems.push(unsetColorMenuItem$1({trackView, label: "Unset track color"})); - if(trackView.track.config.type === 'wig' || trackView.track.config.type === 'annotation') { - menuItems.push(colorPickerMenuItem$1({trackView, label: "Set alt color", option: "altColor"})); - menuItems.push(unsetAltColorMenuItem({trackView, label: "Unset alt color"})); - } - } - - if (trackView.track.menuItemList) { - menuItems = menuItems.concat(trackView.track.menuItemList()); - } - - if (hasVizWindow || vizWindowTypes.has(trackView.track.type)) { - menuItems.push('
'); - menuItems.push(visibilityWindowMenuItem(trackView)); - } - - if (trackView.track.removable !== false) { - menuItems.push('
'); - menuItems.push(trackRemovalMenuItem$1(trackView)); - } - - return menuItems - }, - - numericDataMenuItems: function (trackView) { - - const menuItems = []; - - menuItems.push('
'); - - // Data range - const object = $$1('
'); - object.text('Set data range'); - - const click = () => { - trackView.browser.dataRangeDialog.configure(trackView); - trackView.browser.dataRangeDialog.present($$1(trackView.browser.columnContainer)); - }; - menuItems.push({object, click}); - - if (trackView.track.logScale !== undefined) { - menuItems.push({ - object: $$1(createCheckbox$2("Log scale", trackView.track.logScale)), - click: () => { - trackView.track.logScale = !trackView.track.logScale; - trackView.repaintViews(); - } - } - ); - } - - menuItems.push({ - object: $$1(createCheckbox$2("Autoscale", trackView.track.autoscale)), - click: () => { - trackView.track.autoscale = !trackView.track.autoscale; - trackView.updateViews(); - } - } - ); - - - return menuItems - }, - - trackMenuItemListHelper: function (itemList, menuPopup) { - - var list = []; - - if (itemList.length > 0) { - - list = itemList.map(function (item, i) { - var $e; - - // name and object fields checked for backward compatibility - if (item.name) { - $e = $$1('
'); - $e.text(item.name); - } else if (item.object) { - $e = item.object; - } else if (typeof item.label === 'string') { - $e = $$1('
'); - $e.html(item.label); - } else if (typeof item === 'string') { - - if (item.startsWith("<")) { - $e = $$1(item); - } else { - $e = $$1("
" + item + "
"); - } - } - - if (0 === i) { - $e.addClass('igv-track-menu-border-top'); - } - - if (item.click) { - $e.on('click', handleClick); - $e.on('touchend', function (e) { - handleClick(e); - }); - $e.on('mouseup', function (e) { - e.preventDefault(); - e.stopPropagation(); - }); - - // eslint-disable-next-line no-inner-declarations - function handleClick(e) { - item.click(e); - menuPopup.hide(); - e.preventDefault(); - e.stopPropagation(); - } - } - - return {object: $e, init: (item.init || undefined)} - }); - } - - return list - }, - - showColorPicker(track) { - return ( - undefined === track.type || - "bedtype" === track.type || - "alignment" === track.type || - "annotation" === track.type || - "variant" === track.type || - "wig" === track.type) || - 'interact' === track.type - }, - - createMenuItem(label, action) { - const object = $$1('
'); - object.text(label); - return {object, click: action} - } - }; - - - function visibilityWindowMenuItem(trackView) { - - const click = e => { - - const callback = () => { - - let value = trackView.browser.inputDialog.value; - value = '' === value || undefined === value ? -1 : value.trim(); - - trackView.track.visibilityWindow = Number.parseInt(value); - trackView.track.config.visibilityWindow = Number.parseInt(value); - - trackView.updateViews(); - }; - - const config = - { - label: 'Visibility Window', - value: (trackView.track.visibilityWindow), - callback - }; - trackView.browser.inputDialog.present(config, e); - - }; - - const object = $$1('
'); - object.text('Set visibility window'); - return {object, click} - - } - - function trackRemovalMenuItem$1(trackView) { - - const object = $$1('
'); - object.text('Remove track'); - - return {object, click: () => trackView.browser.removeTrack(trackView.track)} - - } - - function colorPickerMenuItem$1({trackView, label, option}) { - - const $e = $$1('
'); - $e.text(label); - - return { - object: $e, - click: () => trackView.presentColorPicker(option) - } - } - - function unsetColorMenuItem$1({trackView, label}) { - - const $e = $$1('
'); - $e.text(label); - - return { - object: $e, - click: () => { - trackView.track.color = undefined; - trackView.repaintViews(); - } - } - } - - function unsetAltColorMenuItem({trackView, label}) { - - const $e = $$1('
'); - $e.text(label); - - return { - object: $e, - click: () => { - trackView.track.altColor = undefined; - trackView.repaintViews(); - } - } - } - - function trackRenameMenuItem$1(trackView) { - - const click = e => { - - const callback = function () { - let value = trackView.browser.inputDialog.value; - value = ('' === value || undefined === value) ? 'untitled' : value.trim(); - trackView.track.name = value; - }; - - const config = - { - label: 'Track Name', - value: (getTrackLabelText(trackView.track) || 'unnamed'), - callback - }; - - trackView.browser.inputDialog.present(config, e); - - }; - - const object = $$1('
'); - object.text('Set track name'); - return {object, click} - - - } - - function trackHeightMenuItem(trackView) { - - const click = e => { - - const callback = () => { - - const number = Number(trackView.browser.inputDialog.value, 10); - - if (undefined !== number) { - - // If explicitly setting the height adust min or max, if neccessary. - if (trackView.track.minHeight !== undefined && trackView.track.minHeight > number) { - trackView.track.minHeight = number; - } - if (trackView.track.maxHeight !== undefined && trackView.track.maxHeight < number) { - trackView.track.minHeight = number; - } - trackView.setTrackHeight(number, true); - - trackView.checkContentHeight(); - trackView.repaintViews(); - - - // Explicitly setting track height turns off autoHeight - trackView.track.autoHeight = false; - } - - }; - - const config = - { - label: 'Track Height', - value: trackView.track.height, - callback - }; - - trackView.browser.inputDialog.present(config, e); - - }; - - const object = $$1('
'); - object.text('Set track height'); - return {object, click} - - - } - - function getTrackLabelText(track) { - var vp, - txt; - - vp = track.trackView.viewports[0]; - txt = vp.$trackLabel.text(); - - return txt - } - - class DataRangeDialog$1 { - - constructor(browser, $parent, alert) { - - this.browser = browser; - - // dialog container - this.$container = $$1("
", {class: 'igv-generic-dialog-container'}); - $parent.append(this.$container); - this.$container.offset({left: 0, top: 0}); - - // dialog header - const $header = $$1("
", {class: 'igv-generic-dialog-header'}); - this.$container.append($header); - uiUtils$1.attachDialogCloseHandlerWithParent($header[0], () => { - this.$minimum_input.val(undefined); - this.$maximum_input.val(undefined); - this.$container.offset({left: 0, top: 0}); - this.$container.hide(); - }); - - - // minimun - this.$minimum = $$1("
", {class: 'igv-generic-dialog-label-input'}); - this.$container.append(this.$minimum); - const $mindiv = $$1('
'); - $mindiv.text('Minimum'); - this.$minimum.append($mindiv); - this.$minimum_input = $$1(""); - this.$minimum.append(this.$minimum_input); - - - // maximum - this.$maximum = $$1("
", {class: 'igv-generic-dialog-label-input'}); - this.$container.append(this.$maximum); - const $maxdiv = $$1('
'); - $maxdiv.text('Maximum'); - this.$maximum.append($maxdiv); - this.$maximum_input = $$1(""); - this.$maximum.append(this.$maximum_input); - - // ok | cancel - const $buttons = $$1("
", {class: 'igv-generic-dialog-ok-cancel'}); - this.$container.append($buttons); - - // ok - this.$ok = $$1("
"); - $buttons.append(this.$ok); - this.$ok.text('OK'); - - // cancel - this.$cancel = $$1("
"); - $buttons.append(this.$cancel); - this.$cancel.text('Cancel'); - - this.$cancel.on('click', () => { - this.$minimum_input.val(undefined); - this.$maximum_input.val(undefined); - this.$container.offset({left: 0, top: 0}); - this.$container.hide(); - }); - - //this.$container.draggable({ handle:$header.get(0) }); - makeDraggable$1(this.$container.get(0), $header.get(0)); - - this.$container.hide(); - } - - configure(trackView) { - - const dataRange = trackView.dataRange(); - let min; - let max; - if (dataRange) { - min = dataRange.min; - max = dataRange.max; - } else { - min = 0; - max = 100; - } - - this.$minimum_input.val(min); - this.$maximum_input.val(max); - - this.$minimum_input.unbind(); - this.$minimum_input.on('keyup', (e) => { - if (13 === e.keyCode) { - this.processResults(trackView); - } - }); - - this.$maximum_input.unbind(); - this.$maximum_input.on('keyup', (e) => { - if (13 === e.keyCode) { - this.processResults(trackView); - } - }); - - this.$ok.unbind(); - this.$ok.on('click', (e) => { - this.processResults(trackView); - }); - } - - - processResults(trackView) { - - const min = Number(this.$minimum_input.val()); - const max = Number(this.$maximum_input.val()); - if (isNaN(min) || isNaN(max)) { - this.browser.alert.present(new Error('Must input numeric values'), undefined); - } else { - trackView.setDataRange(min, max); - } - - this.$minimum_input.val(undefined); - this.$maximum_input.val(undefined); - this.$container.offset({left: 0, top: 0}); - this.$container.hide(); - } - - present($parent) { - - const offset_top = $parent.offset().top; - const scroll_top = $$1('body').scrollTop(); - - this.$container.offset({left: $parent.width() - this.$container.width(), top: (offset_top + scroll_top)}); - this.$container.show(); - } - } - - /** - * Covers string literals and String objects - * @param x - * @returns {boolean} - */ - function isString$2(x) { - return typeof x === "string" || x instanceof String - } - - - // StackOverflow: http://stackoverflow.com/a/10810674/116169 - function numberFormatter$1(rawNumber) { - - var dec = String(rawNumber).split(/[.,]/), - sep = ',', - decsep = '.'; - - return dec[0].split('').reverse().reduce(function (prev, now, i) { - return i % 3 === 0 ? prev + sep + now : prev + now; - }).split('').reverse().join('') + (dec[1] ? decsep + dec[1] : ''); - } - - const splitLines$5 = function (string) { - return string.split(/\n|\r\n|\r/g); - }; - - - function splitStringRespectingQuotes(string, delim) { - - var tokens = [], - len = string.length, - i, - n = 0, - quote = false, - c; - - if (len > 0) { - - tokens[n] = string.charAt(0); - for (i = 1; i < len; i++) { - c = string.charAt(i); - if (c === '"') { - quote = !quote; - } else if (!quote && c === delim) { - n++; - tokens[n] = ""; - } else { - tokens[n] += c; - } - } - } - return tokens; - } - - function stripQuotes$1(str) { - if(str === undefined) { - return str; - } - if(str.startsWith("'") || str.startsWith('"')) { - str = str.substring(1); - } - if (str.endsWith("'") || str.endsWith('"')) { - str = str.substring(0, str.length - 1); - } - return str; - } - - function capitalize(str) { - return str.length > 0 ? str.charAt(0).toUpperCase() + str.slice(1) : str; - } - - - /** - * Parse a locus string and return a range object. Locus string is of the form chr:start-end. End is optional - * - */ - function parseLocusString$1(string) { - - const t1 = string.split(":"); - const t2 = t1[1].split("-"); - - const range = { - chr: t1[0], - start: Number.parseInt(t2[0].replace(/,/g, '')) - 1 - }; - - if (t2.length > 1) { - range.end = Number.parseInt(t2[1].replace(/,/g, '')); - } else { - range.end = range.start + 1; - } - - return range; - } - - /** - * Return the filename from the path. Example - * https://foo.com/bar.bed?param=2 => bar.bed - * @param urlOrFile - */ - - function getFilename$2(urlOrFile) { - - if (urlOrFile.name !== undefined) { - return urlOrFile.name - } else if (isString$2(urlOrFile)) { - - let index = urlOrFile.lastIndexOf("/"); - let filename = index < 0 ? urlOrFile : urlOrFile.substr(index + 1); - - //Strip parameters -- handle local files later - index = filename.indexOf("?"); - if (index > 0) { - filename = filename.substr(0, index); - } - return filename - } else { - throw Error(`Expected File or string, got ${typeof urlOrFile}`) - } - } - - - /** - * Test if object is a File or File-like object. - * - * @param object - */ - function isFile$1(object) { - if(!object) { - return false; - } - return typeof object !== 'function' && - (object instanceof File || - (object.hasOwnProperty("name") && typeof object.slice === 'function' && typeof object.arrayBuffer === 'function')) - } - - function download(filename, data) { - - const element = document.createElement('a'); - element.setAttribute('href', data); - element.setAttribute('download', filename); - element.style.display = 'none'; - document.body.appendChild(element); - element.click(); - document.body.removeChild(element); - } - - if (typeof process === 'object' && typeof window === 'undefined') { - global.atob = function (str) { - return Buffer.from(str, 'base64').toString('binary'); - }; - } - - - function parseUri(str) { - - var o = options, - m = o.parser["loose"].exec(str), - uri = {}, - i = 14; - - while (i--) uri[o.key[i]] = m[i] || ""; - - uri[o.q.name] = {}; - uri[o.key[12]].replace(o.q.parser, function ($0, $1, $2) { - if ($1) uri[o.q.name][$1] = $2; - }); - - return uri; - } - - const options = { - strictMode: false, - key: ["source", "protocol", "authority", "userInfo", "user", "password", "host", "port", "relative", "path", "directory", "file", "query", "anchor"], - q: { - name: "queryKey", - parser: /(?:^|&)([^&=]*)=?([^&]*)/g - }, - parser: { - strict: /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/, - loose: /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/ - } - }; - - /** - * Resolve a url, which might be a string, function (that returns a string or Promse), or Promise (that resolves to a string) - * - * @param url - * @returns {Promise<*>} - */ - async function resolveURL(url) { - return (typeof url === 'function') ? url() : url; - } - - /*! pako 2.1.0 https://github.com/nodeca/pako @license (MIT AND Zlib) */ - // (C) 1995-2013 Jean-loup Gailly and Mark Adler - // (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin - // - // This software is provided 'as-is', without any express or implied - // warranty. In no event will the authors be held liable for any damages - // arising from the use of this software. - // - // Permission is granted to anyone to use this software for any purpose, - // including commercial applications, and to alter it and redistribute it - // freely, subject to the following restrictions: - // - // 1. The origin of this software must not be misrepresented; you must not - // claim that you wrote the original software. If you use this software - // in a product, an acknowledgment in the product documentation would be - // appreciated but is not required. - // 2. Altered source versions must be plainly marked as such, and must not be - // misrepresented as being the original software. - // 3. This notice may not be removed or altered from any source distribution. - - /* eslint-disable space-unary-ops */ - - /* Public constants ==========================================================*/ - /* ===========================================================================*/ - - - //const Z_FILTERED = 1; - //const Z_HUFFMAN_ONLY = 2; - //const Z_RLE = 3; - const Z_FIXED$1 = 4; - //const Z_DEFAULT_STRATEGY = 0; - - /* Possible values of the data_type field (though see inflate()) */ - const Z_BINARY = 0; - const Z_TEXT = 1; - //const Z_ASCII = 1; // = Z_TEXT - const Z_UNKNOWN$1 = 2; - - /*============================================================================*/ - - - function zero$1$1(buf) { let len = buf.length; while (--len >= 0) { buf[len] = 0; } } - - // From zutil.h - - const STORED_BLOCK = 0; - const STATIC_TREES = 1; - const DYN_TREES = 2; - /* The three kinds of block type */ - - const MIN_MATCH$1$1 = 3; - const MAX_MATCH$1$1 = 258; - /* The minimum and maximum match lengths */ - - // From deflate.h - /* =========================================================================== - * Internal compression state. - */ - - const LENGTH_CODES$1$1 = 29; - /* number of length codes, not counting the special END_BLOCK code */ - - const LITERALS$1$1 = 256; - /* number of literal bytes 0..255 */ - - const L_CODES$1$1 = LITERALS$1$1 + 1 + LENGTH_CODES$1$1; - /* number of Literal or Length codes, including the END_BLOCK code */ - - const D_CODES$1$1 = 30; - /* number of distance codes */ - - const BL_CODES$1 = 19; - /* number of codes used to transfer the bit lengths */ - - const HEAP_SIZE$1 = 2 * L_CODES$1$1 + 1; - /* maximum heap size */ - - const MAX_BITS$1 = 15; - /* All codes must not exceed MAX_BITS bits */ - - const Buf_size = 16; - /* size of bit buffer in bi_buf */ - - - /* =========================================================================== - * Constants - */ - - const MAX_BL_BITS = 7; - /* Bit length codes must not exceed MAX_BL_BITS bits */ - - const END_BLOCK = 256; - /* end of block literal code */ - - const REP_3_6 = 16; - /* repeat previous bit length 3-6 times (2 bits of repeat count) */ - - const REPZ_3_10 = 17; - /* repeat a zero length 3-10 times (3 bits of repeat count) */ - - const REPZ_11_138 = 18; - /* repeat a zero length 11-138 times (7 bits of repeat count) */ - - /* eslint-disable comma-spacing,array-bracket-spacing */ - const extra_lbits = /* extra bits for each length code */ - new Uint8Array([0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0]); - - const extra_dbits = /* extra bits for each distance code */ - new Uint8Array([0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13]); - - const extra_blbits = /* extra bits for each bit length code */ - new Uint8Array([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7]); - - const bl_order = - new Uint8Array([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]); - /* eslint-enable comma-spacing,array-bracket-spacing */ - - /* The lengths of the bit length codes are sent in order of decreasing - * probability, to avoid transmitting the lengths for unused bit length codes. - */ - - /* =========================================================================== - * Local data. These are initialized only once. - */ - - // We pre-fill arrays with 0 to avoid uninitialized gaps - - const DIST_CODE_LEN$1 = 512; /* see definition of array dist_code below */ - - // !!!! Use flat array instead of structure, Freq = i*2, Len = i*2+1 - const static_ltree$1 = new Array((L_CODES$1$1 + 2) * 2); - zero$1$1(static_ltree$1); - /* The static literal tree. Since the bit lengths are imposed, there is no - * need for the L_CODES extra codes used during heap construction. However - * The codes 286 and 287 are needed to build a canonical tree (see _tr_init - * below). - */ - - const static_dtree$1 = new Array(D_CODES$1$1 * 2); - zero$1$1(static_dtree$1); - /* The static distance tree. (Actually a trivial tree since all codes use - * 5 bits.) - */ - - const _dist_code$1 = new Array(DIST_CODE_LEN$1); - zero$1$1(_dist_code$1); - /* Distance codes. The first 256 values correspond to the distances - * 3 .. 258, the last 256 values correspond to the top 8 bits of - * the 15 bit distances. - */ - - const _length_code$1 = new Array(MAX_MATCH$1$1 - MIN_MATCH$1$1 + 1); - zero$1$1(_length_code$1); - /* length code for each normalized match length (0 == MIN_MATCH) */ - - const base_length$1 = new Array(LENGTH_CODES$1$1); - zero$1$1(base_length$1); - /* First normalized length for each code (0 = MIN_MATCH) */ - - const base_dist$1 = new Array(D_CODES$1$1); - zero$1$1(base_dist$1); - /* First normalized distance for each code (0 = distance of 1) */ - - - function StaticTreeDesc(static_tree, extra_bits, extra_base, elems, max_length) { - - this.static_tree = static_tree; /* static tree or NULL */ - this.extra_bits = extra_bits; /* extra bits for each code or NULL */ - this.extra_base = extra_base; /* base index for extra_bits */ - this.elems = elems; /* max number of elements in the tree */ - this.max_length = max_length; /* max bit length for the codes */ - - // show if `static_tree` has data or dummy - needed for monomorphic objects - this.has_stree = static_tree && static_tree.length; - } - - - let static_l_desc; - let static_d_desc; - let static_bl_desc; - - - function TreeDesc(dyn_tree, stat_desc) { - this.dyn_tree = dyn_tree; /* the dynamic tree */ - this.max_code = 0; /* largest code with non zero frequency */ - this.stat_desc = stat_desc; /* the corresponding static tree */ - } - - - - const d_code = (dist) => { - - return dist < 256 ? _dist_code$1[dist] : _dist_code$1[256 + (dist >>> 7)]; - }; - - - /* =========================================================================== - * Output a short LSB first on the stream. - * IN assertion: there is enough room in pendingBuf. - */ - const put_short = (s, w) => { - // put_byte(s, (uch)((w) & 0xff)); - // put_byte(s, (uch)((ush)(w) >> 8)); - s.pending_buf[s.pending++] = (w) & 0xff; - s.pending_buf[s.pending++] = (w >>> 8) & 0xff; - }; - - - /* =========================================================================== - * Send a value on a given number of bits. - * IN assertion: length <= 16 and value fits in length bits. - */ - const send_bits = (s, value, length) => { - - if (s.bi_valid > (Buf_size - length)) { - s.bi_buf |= (value << s.bi_valid) & 0xffff; - put_short(s, s.bi_buf); - s.bi_buf = value >> (Buf_size - s.bi_valid); - s.bi_valid += length - Buf_size; - } else { - s.bi_buf |= (value << s.bi_valid) & 0xffff; - s.bi_valid += length; - } - }; - - - const send_code = (s, c, tree) => { - - send_bits(s, tree[c * 2]/*.Code*/, tree[c * 2 + 1]/*.Len*/); - }; - - - /* =========================================================================== - * Reverse the first len bits of a code, using straightforward code (a faster - * method would use a table) - * IN assertion: 1 <= len <= 15 - */ - const bi_reverse = (code, len) => { - - let res = 0; - do { - res |= code & 1; - code >>>= 1; - res <<= 1; - } while (--len > 0); - return res >>> 1; - }; - - - /* =========================================================================== - * Flush the bit buffer, keeping at most 7 bits in it. - */ - const bi_flush = (s) => { - - if (s.bi_valid === 16) { - put_short(s, s.bi_buf); - s.bi_buf = 0; - s.bi_valid = 0; - - } else if (s.bi_valid >= 8) { - s.pending_buf[s.pending++] = s.bi_buf & 0xff; - s.bi_buf >>= 8; - s.bi_valid -= 8; - } - }; - - - /* =========================================================================== - * Compute the optimal bit lengths for a tree and update the total bit length - * for the current block. - * IN assertion: the fields freq and dad are set, heap[heap_max] and - * above are the tree nodes sorted by increasing frequency. - * OUT assertions: the field len is set to the optimal bit length, the - * array bl_count contains the frequencies for each bit length. - * The length opt_len is updated; static_len is also updated if stree is - * not null. - */ - const gen_bitlen = (s, desc) => { - // deflate_state *s; - // tree_desc *desc; /* the tree descriptor */ - - const tree = desc.dyn_tree; - const max_code = desc.max_code; - const stree = desc.stat_desc.static_tree; - const has_stree = desc.stat_desc.has_stree; - const extra = desc.stat_desc.extra_bits; - const base = desc.stat_desc.extra_base; - const max_length = desc.stat_desc.max_length; - let h; /* heap index */ - let n, m; /* iterate over the tree elements */ - let bits; /* bit length */ - let xbits; /* extra bits */ - let f; /* frequency */ - let overflow = 0; /* number of elements with bit length too large */ - - for (bits = 0; bits <= MAX_BITS$1; bits++) { - s.bl_count[bits] = 0; - } - - /* In a first pass, compute the optimal bit lengths (which may - * overflow in the case of the bit length tree). - */ - tree[s.heap[s.heap_max] * 2 + 1]/*.Len*/ = 0; /* root of the heap */ - - for (h = s.heap_max + 1; h < HEAP_SIZE$1; h++) { - n = s.heap[h]; - bits = tree[tree[n * 2 + 1]/*.Dad*/ * 2 + 1]/*.Len*/ + 1; - if (bits > max_length) { - bits = max_length; - overflow++; - } - tree[n * 2 + 1]/*.Len*/ = bits; - /* We overwrite tree[n].Dad which is no longer needed */ - - if (n > max_code) { continue; } /* not a leaf node */ - - s.bl_count[bits]++; - xbits = 0; - if (n >= base) { - xbits = extra[n - base]; - } - f = tree[n * 2]/*.Freq*/; - s.opt_len += f * (bits + xbits); - if (has_stree) { - s.static_len += f * (stree[n * 2 + 1]/*.Len*/ + xbits); - } - } - if (overflow === 0) { return; } - - // Tracev((stderr,"\nbit length overflow\n")); - /* This happens for example on obj2 and pic of the Calgary corpus */ - - /* Find the first bit length which could increase: */ - do { - bits = max_length - 1; - while (s.bl_count[bits] === 0) { bits--; } - s.bl_count[bits]--; /* move one leaf down the tree */ - s.bl_count[bits + 1] += 2; /* move one overflow item as its brother */ - s.bl_count[max_length]--; - /* The brother of the overflow item also moves one step up, - * but this does not affect bl_count[max_length] - */ - overflow -= 2; - } while (overflow > 0); - - /* Now recompute all bit lengths, scanning in increasing frequency. - * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all - * lengths instead of fixing only the wrong ones. This idea is taken - * from 'ar' written by Haruhiko Okumura.) - */ - for (bits = max_length; bits !== 0; bits--) { - n = s.bl_count[bits]; - while (n !== 0) { - m = s.heap[--h]; - if (m > max_code) { continue; } - if (tree[m * 2 + 1]/*.Len*/ !== bits) { - // Tracev((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits)); - s.opt_len += (bits - tree[m * 2 + 1]/*.Len*/) * tree[m * 2]/*.Freq*/; - tree[m * 2 + 1]/*.Len*/ = bits; - } - n--; - } - } - }; - - - /* =========================================================================== - * Generate the codes for a given tree and bit counts (which need not be - * optimal). - * IN assertion: the array bl_count contains the bit length statistics for - * the given tree and the field len is set for all tree elements. - * OUT assertion: the field code is set for all tree elements of non - * zero code length. - */ - const gen_codes = (tree, max_code, bl_count) => { - // ct_data *tree; /* the tree to decorate */ - // int max_code; /* largest code with non zero frequency */ - // ushf *bl_count; /* number of codes at each bit length */ - - const next_code = new Array(MAX_BITS$1 + 1); /* next code value for each bit length */ - let code = 0; /* running code value */ - let bits; /* bit index */ - let n; /* code index */ - - /* The distribution counts are first used to generate the code values - * without bit reversal. - */ - for (bits = 1; bits <= MAX_BITS$1; bits++) { - code = (code + bl_count[bits - 1]) << 1; - next_code[bits] = code; - } - /* Check that the bit counts in bl_count are consistent. The last code - * must be all ones. - */ - //Assert (code + bl_count[MAX_BITS]-1 == (1< { - - let n; /* iterates over tree elements */ - let bits; /* bit counter */ - let length; /* length value */ - let code; /* code value */ - let dist; /* distance index */ - const bl_count = new Array(MAX_BITS$1 + 1); - /* number of codes at each bit length for an optimal tree */ - - // do check in _tr_init() - //if (static_init_done) return; - - /* For some embedded targets, global variables are not initialized: */ - /*#ifdef NO_INIT_GLOBAL_POINTERS - static_l_desc.static_tree = static_ltree; - static_l_desc.extra_bits = extra_lbits; - static_d_desc.static_tree = static_dtree; - static_d_desc.extra_bits = extra_dbits; - static_bl_desc.extra_bits = extra_blbits; - #endif*/ - - /* Initialize the mapping length (0..255) -> length code (0..28) */ - length = 0; - for (code = 0; code < LENGTH_CODES$1$1 - 1; code++) { - base_length$1[code] = length; - for (n = 0; n < (1 << extra_lbits[code]); n++) { - _length_code$1[length++] = code; - } - } - //Assert (length == 256, "tr_static_init: length != 256"); - /* Note that the length 255 (match length 258) can be represented - * in two different ways: code 284 + 5 bits or code 285, so we - * overwrite length_code[255] to use the best encoding: - */ - _length_code$1[length - 1] = code; - - /* Initialize the mapping dist (0..32K) -> dist code (0..29) */ - dist = 0; - for (code = 0; code < 16; code++) { - base_dist$1[code] = dist; - for (n = 0; n < (1 << extra_dbits[code]); n++) { - _dist_code$1[dist++] = code; - } - } - //Assert (dist == 256, "tr_static_init: dist != 256"); - dist >>= 7; /* from now on, all distances are divided by 128 */ - for (; code < D_CODES$1$1; code++) { - base_dist$1[code] = dist << 7; - for (n = 0; n < (1 << (extra_dbits[code] - 7)); n++) { - _dist_code$1[256 + dist++] = code; - } - } - //Assert (dist == 256, "tr_static_init: 256+dist != 512"); - - /* Construct the codes of the static literal tree */ - for (bits = 0; bits <= MAX_BITS$1; bits++) { - bl_count[bits] = 0; - } - - n = 0; - while (n <= 143) { - static_ltree$1[n * 2 + 1]/*.Len*/ = 8; - n++; - bl_count[8]++; - } - while (n <= 255) { - static_ltree$1[n * 2 + 1]/*.Len*/ = 9; - n++; - bl_count[9]++; - } - while (n <= 279) { - static_ltree$1[n * 2 + 1]/*.Len*/ = 7; - n++; - bl_count[7]++; - } - while (n <= 287) { - static_ltree$1[n * 2 + 1]/*.Len*/ = 8; - n++; - bl_count[8]++; - } - /* Codes 286 and 287 do not exist, but we must include them in the - * tree construction to get a canonical Huffman tree (longest code - * all ones) - */ - gen_codes(static_ltree$1, L_CODES$1$1 + 1, bl_count); - - /* The static distance tree is trivial: */ - for (n = 0; n < D_CODES$1$1; n++) { - static_dtree$1[n * 2 + 1]/*.Len*/ = 5; - static_dtree$1[n * 2]/*.Code*/ = bi_reverse(n, 5); - } - - // Now data ready and we can init static trees - static_l_desc = new StaticTreeDesc(static_ltree$1, extra_lbits, LITERALS$1$1 + 1, L_CODES$1$1, MAX_BITS$1); - static_d_desc = new StaticTreeDesc(static_dtree$1, extra_dbits, 0, D_CODES$1$1, MAX_BITS$1); - static_bl_desc = new StaticTreeDesc(new Array(0), extra_blbits, 0, BL_CODES$1, MAX_BL_BITS); - - //static_init_done = true; - }; - - - /* =========================================================================== - * Initialize a new block. - */ - const init_block = (s) => { - - let n; /* iterates over tree elements */ - - /* Initialize the trees. */ - for (n = 0; n < L_CODES$1$1; n++) { s.dyn_ltree[n * 2]/*.Freq*/ = 0; } - for (n = 0; n < D_CODES$1$1; n++) { s.dyn_dtree[n * 2]/*.Freq*/ = 0; } - for (n = 0; n < BL_CODES$1; n++) { s.bl_tree[n * 2]/*.Freq*/ = 0; } - - s.dyn_ltree[END_BLOCK * 2]/*.Freq*/ = 1; - s.opt_len = s.static_len = 0; - s.sym_next = s.matches = 0; - }; - - - /* =========================================================================== - * Flush the bit buffer and align the output on a byte boundary - */ - const bi_windup = (s) => - { - if (s.bi_valid > 8) { - put_short(s, s.bi_buf); - } else if (s.bi_valid > 0) { - //put_byte(s, (Byte)s->bi_buf); - s.pending_buf[s.pending++] = s.bi_buf; - } - s.bi_buf = 0; - s.bi_valid = 0; - }; - - /* =========================================================================== - * Compares to subtrees, using the tree depth as tie breaker when - * the subtrees have equal frequency. This minimizes the worst case length. - */ - const smaller = (tree, n, m, depth) => { - - const _n2 = n * 2; - const _m2 = m * 2; - return (tree[_n2]/*.Freq*/ < tree[_m2]/*.Freq*/ || - (tree[_n2]/*.Freq*/ === tree[_m2]/*.Freq*/ && depth[n] <= depth[m])); - }; - - /* =========================================================================== - * Restore the heap property by moving down the tree starting at node k, - * exchanging a node with the smallest of its two sons if necessary, stopping - * when the heap property is re-established (each father smaller than its - * two sons). - */ - const pqdownheap = (s, tree, k) => { - // deflate_state *s; - // ct_data *tree; /* the tree to restore */ - // int k; /* node to move down */ - - const v = s.heap[k]; - let j = k << 1; /* left son of k */ - while (j <= s.heap_len) { - /* Set j to the smallest of the two sons: */ - if (j < s.heap_len && - smaller(tree, s.heap[j + 1], s.heap[j], s.depth)) { - j++; - } - /* Exit if v is smaller than both sons */ - if (smaller(tree, v, s.heap[j], s.depth)) { break; } - - /* Exchange v with the smallest son */ - s.heap[k] = s.heap[j]; - k = j; - - /* And continue down the tree, setting j to the left son of k */ - j <<= 1; - } - s.heap[k] = v; - }; - - - // inlined manually - // const SMALLEST = 1; - - /* =========================================================================== - * Send the block data compressed using the given Huffman trees - */ - const compress_block = (s, ltree, dtree) => { - // deflate_state *s; - // const ct_data *ltree; /* literal tree */ - // const ct_data *dtree; /* distance tree */ - - let dist; /* distance of matched string */ - let lc; /* match length or unmatched char (if dist == 0) */ - let sx = 0; /* running index in sym_buf */ - let code; /* the code to send */ - let extra; /* number of extra bits to send */ - - if (s.sym_next !== 0) { - do { - dist = s.pending_buf[s.sym_buf + sx++] & 0xff; - dist += (s.pending_buf[s.sym_buf + sx++] & 0xff) << 8; - lc = s.pending_buf[s.sym_buf + sx++]; - if (dist === 0) { - send_code(s, lc, ltree); /* send a literal byte */ - //Tracecv(isgraph(lc), (stderr," '%c' ", lc)); - } else { - /* Here, lc is the match length - MIN_MATCH */ - code = _length_code$1[lc]; - send_code(s, code + LITERALS$1$1 + 1, ltree); /* send the length code */ - extra = extra_lbits[code]; - if (extra !== 0) { - lc -= base_length$1[code]; - send_bits(s, lc, extra); /* send the extra length bits */ - } - dist--; /* dist is now the match distance - 1 */ - code = d_code(dist); - //Assert (code < D_CODES, "bad d_code"); - - send_code(s, code, dtree); /* send the distance code */ - extra = extra_dbits[code]; - if (extra !== 0) { - dist -= base_dist$1[code]; - send_bits(s, dist, extra); /* send the extra distance bits */ - } - } /* literal or match pair ? */ - - /* Check that the overlay between pending_buf and sym_buf is ok: */ - //Assert(s->pending < s->lit_bufsize + sx, "pendingBuf overflow"); - - } while (sx < s.sym_next); - } - - send_code(s, END_BLOCK, ltree); - }; - - - /* =========================================================================== - * Construct one Huffman tree and assigns the code bit strings and lengths. - * Update the total bit length for the current block. - * IN assertion: the field freq is set for all tree elements. - * OUT assertions: the fields len and code are set to the optimal bit length - * and corresponding code. The length opt_len is updated; static_len is - * also updated if stree is not null. The field max_code is set. - */ - const build_tree = (s, desc) => { - // deflate_state *s; - // tree_desc *desc; /* the tree descriptor */ - - const tree = desc.dyn_tree; - const stree = desc.stat_desc.static_tree; - const has_stree = desc.stat_desc.has_stree; - const elems = desc.stat_desc.elems; - let n, m; /* iterate over heap elements */ - let max_code = -1; /* largest code with non zero frequency */ - let node; /* new node being created */ - - /* Construct the initial heap, with least frequent element in - * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. - * heap[0] is not used. - */ - s.heap_len = 0; - s.heap_max = HEAP_SIZE$1; - - for (n = 0; n < elems; n++) { - if (tree[n * 2]/*.Freq*/ !== 0) { - s.heap[++s.heap_len] = max_code = n; - s.depth[n] = 0; - - } else { - tree[n * 2 + 1]/*.Len*/ = 0; - } - } - - /* The pkzip format requires that at least one distance code exists, - * and that at least one bit should be sent even if there is only one - * possible code. So to avoid special checks later on we force at least - * two codes of non zero frequency. - */ - while (s.heap_len < 2) { - node = s.heap[++s.heap_len] = (max_code < 2 ? ++max_code : 0); - tree[node * 2]/*.Freq*/ = 1; - s.depth[node] = 0; - s.opt_len--; - - if (has_stree) { - s.static_len -= stree[node * 2 + 1]/*.Len*/; - } - /* node is 0 or 1 so it does not have extra bits */ - } - desc.max_code = max_code; - - /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, - * establish sub-heaps of increasing lengths: - */ - for (n = (s.heap_len >> 1/*int /2*/); n >= 1; n--) { pqdownheap(s, tree, n); } - - /* Construct the Huffman tree by repeatedly combining the least two - * frequent nodes. - */ - node = elems; /* next internal node of the tree */ - do { - //pqremove(s, tree, n); /* n = node of least frequency */ - /*** pqremove ***/ - n = s.heap[1/*SMALLEST*/]; - s.heap[1/*SMALLEST*/] = s.heap[s.heap_len--]; - pqdownheap(s, tree, 1/*SMALLEST*/); - /***/ - - m = s.heap[1/*SMALLEST*/]; /* m = node of next least frequency */ - - s.heap[--s.heap_max] = n; /* keep the nodes sorted by frequency */ - s.heap[--s.heap_max] = m; - - /* Create a new node father of n and m */ - tree[node * 2]/*.Freq*/ = tree[n * 2]/*.Freq*/ + tree[m * 2]/*.Freq*/; - s.depth[node] = (s.depth[n] >= s.depth[m] ? s.depth[n] : s.depth[m]) + 1; - tree[n * 2 + 1]/*.Dad*/ = tree[m * 2 + 1]/*.Dad*/ = node; - - /* and insert the new node in the heap */ - s.heap[1/*SMALLEST*/] = node++; - pqdownheap(s, tree, 1/*SMALLEST*/); - - } while (s.heap_len >= 2); - - s.heap[--s.heap_max] = s.heap[1/*SMALLEST*/]; - - /* At this point, the fields freq and dad are set. We can now - * generate the bit lengths. - */ - gen_bitlen(s, desc); - - /* The field len is now set, we can generate the bit codes */ - gen_codes(tree, max_code, s.bl_count); - }; - - - /* =========================================================================== - * Scan a literal or distance tree to determine the frequencies of the codes - * in the bit length tree. - */ - const scan_tree = (s, tree, max_code) => { - // deflate_state *s; - // ct_data *tree; /* the tree to be scanned */ - // int max_code; /* and its largest code of non zero frequency */ - - let n; /* iterates over all tree elements */ - let prevlen = -1; /* last emitted length */ - let curlen; /* length of current code */ - - let nextlen = tree[0 * 2 + 1]/*.Len*/; /* length of next code */ - - let count = 0; /* repeat count of the current code */ - let max_count = 7; /* max repeat count */ - let min_count = 4; /* min repeat count */ - - if (nextlen === 0) { - max_count = 138; - min_count = 3; - } - tree[(max_code + 1) * 2 + 1]/*.Len*/ = 0xffff; /* guard */ - - for (n = 0; n <= max_code; n++) { - curlen = nextlen; - nextlen = tree[(n + 1) * 2 + 1]/*.Len*/; - - if (++count < max_count && curlen === nextlen) { - continue; - - } else if (count < min_count) { - s.bl_tree[curlen * 2]/*.Freq*/ += count; - - } else if (curlen !== 0) { - - if (curlen !== prevlen) { s.bl_tree[curlen * 2]/*.Freq*/++; } - s.bl_tree[REP_3_6 * 2]/*.Freq*/++; - - } else if (count <= 10) { - s.bl_tree[REPZ_3_10 * 2]/*.Freq*/++; - - } else { - s.bl_tree[REPZ_11_138 * 2]/*.Freq*/++; - } - - count = 0; - prevlen = curlen; - - if (nextlen === 0) { - max_count = 138; - min_count = 3; - - } else if (curlen === nextlen) { - max_count = 6; - min_count = 3; - - } else { - max_count = 7; - min_count = 4; - } - } - }; - - - /* =========================================================================== - * Send a literal or distance tree in compressed form, using the codes in - * bl_tree. - */ - const send_tree = (s, tree, max_code) => { - // deflate_state *s; - // ct_data *tree; /* the tree to be scanned */ - // int max_code; /* and its largest code of non zero frequency */ - - let n; /* iterates over all tree elements */ - let prevlen = -1; /* last emitted length */ - let curlen; /* length of current code */ - - let nextlen = tree[0 * 2 + 1]/*.Len*/; /* length of next code */ - - let count = 0; /* repeat count of the current code */ - let max_count = 7; /* max repeat count */ - let min_count = 4; /* min repeat count */ - - /* tree[max_code+1].Len = -1; */ /* guard already set */ - if (nextlen === 0) { - max_count = 138; - min_count = 3; - } - - for (n = 0; n <= max_code; n++) { - curlen = nextlen; - nextlen = tree[(n + 1) * 2 + 1]/*.Len*/; - - if (++count < max_count && curlen === nextlen) { - continue; - - } else if (count < min_count) { - do { send_code(s, curlen, s.bl_tree); } while (--count !== 0); - - } else if (curlen !== 0) { - if (curlen !== prevlen) { - send_code(s, curlen, s.bl_tree); - count--; - } - //Assert(count >= 3 && count <= 6, " 3_6?"); - send_code(s, REP_3_6, s.bl_tree); - send_bits(s, count - 3, 2); - - } else if (count <= 10) { - send_code(s, REPZ_3_10, s.bl_tree); - send_bits(s, count - 3, 3); - - } else { - send_code(s, REPZ_11_138, s.bl_tree); - send_bits(s, count - 11, 7); - } - - count = 0; - prevlen = curlen; - if (nextlen === 0) { - max_count = 138; - min_count = 3; - - } else if (curlen === nextlen) { - max_count = 6; - min_count = 3; - - } else { - max_count = 7; - min_count = 4; - } - } - }; - - - /* =========================================================================== - * Construct the Huffman tree for the bit lengths and return the index in - * bl_order of the last bit length code to send. - */ - const build_bl_tree = (s) => { - - let max_blindex; /* index of last bit length code of non zero freq */ - - /* Determine the bit length frequencies for literal and distance trees */ - scan_tree(s, s.dyn_ltree, s.l_desc.max_code); - scan_tree(s, s.dyn_dtree, s.d_desc.max_code); - - /* Build the bit length tree: */ - build_tree(s, s.bl_desc); - /* opt_len now includes the length of the tree representations, except - * the lengths of the bit lengths codes and the 5+5+4 bits for the counts. - */ - - /* Determine the number of bit length codes to send. The pkzip format - * requires that at least 4 bit length codes be sent. (appnote.txt says - * 3 but the actual value used is 4.) - */ - for (max_blindex = BL_CODES$1 - 1; max_blindex >= 3; max_blindex--) { - if (s.bl_tree[bl_order[max_blindex] * 2 + 1]/*.Len*/ !== 0) { - break; - } - } - /* Update opt_len to include the bit length tree and counts */ - s.opt_len += 3 * (max_blindex + 1) + 5 + 5 + 4; - //Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", - // s->opt_len, s->static_len)); - - return max_blindex; - }; - - - /* =========================================================================== - * Send the header for a block using dynamic Huffman trees: the counts, the - * lengths of the bit length codes, the literal tree and the distance tree. - * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. - */ - const send_all_trees = (s, lcodes, dcodes, blcodes) => { - // deflate_state *s; - // int lcodes, dcodes, blcodes; /* number of codes for each tree */ - - let rank; /* index in bl_order */ - - //Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); - //Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, - // "too many codes"); - //Tracev((stderr, "\nbl counts: ")); - send_bits(s, lcodes - 257, 5); /* not +255 as stated in appnote.txt */ - send_bits(s, dcodes - 1, 5); - send_bits(s, blcodes - 4, 4); /* not -3 as stated in appnote.txt */ - for (rank = 0; rank < blcodes; rank++) { - //Tracev((stderr, "\nbl code %2d ", bl_order[rank])); - send_bits(s, s.bl_tree[bl_order[rank] * 2 + 1]/*.Len*/, 3); - } - //Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent)); - - send_tree(s, s.dyn_ltree, lcodes - 1); /* literal tree */ - //Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent)); - - send_tree(s, s.dyn_dtree, dcodes - 1); /* distance tree */ - //Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent)); - }; - - - /* =========================================================================== - * Check if the data type is TEXT or BINARY, using the following algorithm: - * - TEXT if the two conditions below are satisfied: - * a) There are no non-portable control characters belonging to the - * "block list" (0..6, 14..25, 28..31). - * b) There is at least one printable character belonging to the - * "allow list" (9 {TAB}, 10 {LF}, 13 {CR}, 32..255). - * - BINARY otherwise. - * - The following partially-portable control characters form a - * "gray list" that is ignored in this detection algorithm: - * (7 {BEL}, 8 {BS}, 11 {VT}, 12 {FF}, 26 {SUB}, 27 {ESC}). - * IN assertion: the fields Freq of dyn_ltree are set. - */ - const detect_data_type = (s) => { - /* block_mask is the bit mask of block-listed bytes - * set bits 0..6, 14..25, and 28..31 - * 0xf3ffc07f = binary 11110011111111111100000001111111 - */ - let block_mask = 0xf3ffc07f; - let n; - - /* Check for non-textual ("block-listed") bytes. */ - for (n = 0; n <= 31; n++, block_mask >>>= 1) { - if ((block_mask & 1) && (s.dyn_ltree[n * 2]/*.Freq*/ !== 0)) { - return Z_BINARY; - } - } - - /* Check for textual ("allow-listed") bytes. */ - if (s.dyn_ltree[9 * 2]/*.Freq*/ !== 0 || s.dyn_ltree[10 * 2]/*.Freq*/ !== 0 || - s.dyn_ltree[13 * 2]/*.Freq*/ !== 0) { - return Z_TEXT; - } - for (n = 32; n < LITERALS$1$1; n++) { - if (s.dyn_ltree[n * 2]/*.Freq*/ !== 0) { - return Z_TEXT; - } - } - - /* There are no "block-listed" or "allow-listed" bytes: - * this stream either is empty or has tolerated ("gray-listed") bytes only. - */ - return Z_BINARY; - }; - - - let static_init_done = false; - - /* =========================================================================== - * Initialize the tree data structures for a new zlib stream. - */ - const _tr_init$1 = (s) => - { - - if (!static_init_done) { - tr_static_init(); - static_init_done = true; - } - - s.l_desc = new TreeDesc(s.dyn_ltree, static_l_desc); - s.d_desc = new TreeDesc(s.dyn_dtree, static_d_desc); - s.bl_desc = new TreeDesc(s.bl_tree, static_bl_desc); - - s.bi_buf = 0; - s.bi_valid = 0; - - /* Initialize the first block of the first file: */ - init_block(s); - }; - - - /* =========================================================================== - * Send a stored block - */ - const _tr_stored_block$1 = (s, buf, stored_len, last) => { - //DeflateState *s; - //charf *buf; /* input block */ - //ulg stored_len; /* length of input block */ - //int last; /* one if this is the last block for a file */ - - send_bits(s, (STORED_BLOCK << 1) + (last ? 1 : 0), 3); /* send block type */ - bi_windup(s); /* align on byte boundary */ - put_short(s, stored_len); - put_short(s, ~stored_len); - if (stored_len) { - s.pending_buf.set(s.window.subarray(buf, buf + stored_len), s.pending); - } - s.pending += stored_len; - }; - - - /* =========================================================================== - * Send one empty static block to give enough lookahead for inflate. - * This takes 10 bits, of which 7 may remain in the bit buffer. - */ - const _tr_align$1 = (s) => { - send_bits(s, STATIC_TREES << 1, 3); - send_code(s, END_BLOCK, static_ltree$1); - bi_flush(s); - }; - - - /* =========================================================================== - * Determine the best encoding for the current block: dynamic trees, static - * trees or store, and write out the encoded block. - */ - const _tr_flush_block$1 = (s, buf, stored_len, last) => { - //DeflateState *s; - //charf *buf; /* input block, or NULL if too old */ - //ulg stored_len; /* length of input block */ - //int last; /* one if this is the last block for a file */ - - let opt_lenb, static_lenb; /* opt_len and static_len in bytes */ - let max_blindex = 0; /* index of last bit length code of non zero freq */ - - /* Build the Huffman trees unless a stored block is forced */ - if (s.level > 0) { - - /* Check if the file is binary or text */ - if (s.strm.data_type === Z_UNKNOWN$1) { - s.strm.data_type = detect_data_type(s); - } - - /* Construct the literal and distance trees */ - build_tree(s, s.l_desc); - // Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len, - // s->static_len)); - - build_tree(s, s.d_desc); - // Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len, - // s->static_len)); - /* At this point, opt_len and static_len are the total bit lengths of - * the compressed block data, excluding the tree representations. - */ - - /* Build the bit length tree for the above two trees, and get the index - * in bl_order of the last bit length code to send. - */ - max_blindex = build_bl_tree(s); - - /* Determine the best encoding. Compute the block lengths in bytes. */ - opt_lenb = (s.opt_len + 3 + 7) >>> 3; - static_lenb = (s.static_len + 3 + 7) >>> 3; - - // Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ", - // opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len, - // s->sym_next / 3)); - - if (static_lenb <= opt_lenb) { opt_lenb = static_lenb; } - - } else { - // Assert(buf != (char*)0, "lost buf"); - opt_lenb = static_lenb = stored_len + 5; /* force a stored block */ - } - - if ((stored_len + 4 <= opt_lenb) && (buf !== -1)) { - /* 4: two words for the lengths */ - - /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. - * Otherwise we can't have processed more than WSIZE input bytes since - * the last block flush, because compression would have been - * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to - * transform a block into a stored block. - */ - _tr_stored_block$1(s, buf, stored_len, last); - - } else if (s.strategy === Z_FIXED$1 || static_lenb === opt_lenb) { - - send_bits(s, (STATIC_TREES << 1) + (last ? 1 : 0), 3); - compress_block(s, static_ltree$1, static_dtree$1); - - } else { - send_bits(s, (DYN_TREES << 1) + (last ? 1 : 0), 3); - send_all_trees(s, s.l_desc.max_code + 1, s.d_desc.max_code + 1, max_blindex + 1); - compress_block(s, s.dyn_ltree, s.dyn_dtree); - } - // Assert (s->compressed_len == s->bits_sent, "bad compressed size"); - /* The above check is made mod 2^32, for files larger than 512 MB - * and uLong implemented on 32 bits. - */ - init_block(s); - - if (last) { - bi_windup(s); - } - // Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3, - // s->compressed_len-7*last)); - }; - - /* =========================================================================== - * Save the match info and tally the frequency counts. Return true if - * the current block must be flushed. - */ - const _tr_tally$1 = (s, dist, lc) => { - // deflate_state *s; - // unsigned dist; /* distance of matched string */ - // unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */ - - s.pending_buf[s.sym_buf + s.sym_next++] = dist; - s.pending_buf[s.sym_buf + s.sym_next++] = dist >> 8; - s.pending_buf[s.sym_buf + s.sym_next++] = lc; - if (dist === 0) { - /* lc is the unmatched char */ - s.dyn_ltree[lc * 2]/*.Freq*/++; - } else { - s.matches++; - /* Here, lc is the match length - MIN_MATCH */ - dist--; /* dist = match distance - 1 */ - //Assert((ush)dist < (ush)MAX_DIST(s) && - // (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) && - // (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match"); - - s.dyn_ltree[(_length_code$1[lc] + LITERALS$1$1 + 1) * 2]/*.Freq*/++; - s.dyn_dtree[d_code(dist) * 2]/*.Freq*/++; - } - - return (s.sym_next === s.sym_end); - }; - - var _tr_init_1 = _tr_init$1; - var _tr_stored_block_1 = _tr_stored_block$1; - var _tr_flush_block_1 = _tr_flush_block$1; - var _tr_tally_1 = _tr_tally$1; - var _tr_align_1 = _tr_align$1; - - var trees = { - _tr_init: _tr_init_1, - _tr_stored_block: _tr_stored_block_1, - _tr_flush_block: _tr_flush_block_1, - _tr_tally: _tr_tally_1, - _tr_align: _tr_align_1 - }; - - // Note: adler32 takes 12% for level 0 and 2% for level 6. - // It isn't worth it to make additional optimizations as in original. - // Small size is preferable. - - // (C) 1995-2013 Jean-loup Gailly and Mark Adler - // (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin - // - // This software is provided 'as-is', without any express or implied - // warranty. In no event will the authors be held liable for any damages - // arising from the use of this software. - // - // Permission is granted to anyone to use this software for any purpose, - // including commercial applications, and to alter it and redistribute it - // freely, subject to the following restrictions: - // - // 1. The origin of this software must not be misrepresented; you must not - // claim that you wrote the original software. If you use this software - // in a product, an acknowledgment in the product documentation would be - // appreciated but is not required. - // 2. Altered source versions must be plainly marked as such, and must not be - // misrepresented as being the original software. - // 3. This notice may not be removed or altered from any source distribution. - - const adler32$1 = (adler, buf, len, pos) => { - let s1 = (adler & 0xffff) |0, - s2 = ((adler >>> 16) & 0xffff) |0, - n = 0; - - while (len !== 0) { - // Set limit ~ twice less than 5552, to keep - // s2 in 31-bits, because we force signed ints. - // in other case %= will fail. - n = len > 2000 ? 2000 : len; - len -= n; - - do { - s1 = (s1 + buf[pos++]) |0; - s2 = (s2 + s1) |0; - } while (--n); - - s1 %= 65521; - s2 %= 65521; - } - - return (s1 | (s2 << 16)) |0; - }; - - - var adler32_1$1 = adler32$1; - - // Note: we can't get significant speed boost here. - // So write code to minimize size - no pregenerated tables - // and array tools dependencies. - - // (C) 1995-2013 Jean-loup Gailly and Mark Adler - // (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin - // - // This software is provided 'as-is', without any express or implied - // warranty. In no event will the authors be held liable for any damages - // arising from the use of this software. - // - // Permission is granted to anyone to use this software for any purpose, - // including commercial applications, and to alter it and redistribute it - // freely, subject to the following restrictions: - // - // 1. The origin of this software must not be misrepresented; you must not - // claim that you wrote the original software. If you use this software - // in a product, an acknowledgment in the product documentation would be - // appreciated but is not required. - // 2. Altered source versions must be plainly marked as such, and must not be - // misrepresented as being the original software. - // 3. This notice may not be removed or altered from any source distribution. - - // Use ordinary array, since untyped makes no boost here - const makeTable$1 = () => { - let c, table = []; - - for (var n = 0; n < 256; n++) { - c = n; - for (var k = 0; k < 8; k++) { - c = ((c & 1) ? (0xEDB88320 ^ (c >>> 1)) : (c >>> 1)); - } - table[n] = c; - } - - return table; - }; - - // Create table on load. Just 255 signed longs. Not a problem. - const crcTable$1 = new Uint32Array(makeTable$1()); - - - const crc32$1 = (crc, buf, len, pos) => { - const t = crcTable$1; - const end = pos + len; - - crc ^= -1; - - for (let i = pos; i < end; i++) { - crc = (crc >>> 8) ^ t[(crc ^ buf[i]) & 0xFF]; - } - - return (crc ^ (-1)); // >>> 0; - }; - - - var crc32_1$1 = crc32$1; - - // (C) 1995-2013 Jean-loup Gailly and Mark Adler - // (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin - // - // This software is provided 'as-is', without any express or implied - // warranty. In no event will the authors be held liable for any damages - // arising from the use of this software. - // - // Permission is granted to anyone to use this software for any purpose, - // including commercial applications, and to alter it and redistribute it - // freely, subject to the following restrictions: - // - // 1. The origin of this software must not be misrepresented; you must not - // claim that you wrote the original software. If you use this software - // in a product, an acknowledgment in the product documentation would be - // appreciated but is not required. - // 2. Altered source versions must be plainly marked as such, and must not be - // misrepresented as being the original software. - // 3. This notice may not be removed or altered from any source distribution. - - var messages$1 = { - 2: 'need dictionary', /* Z_NEED_DICT 2 */ - 1: 'stream end', /* Z_STREAM_END 1 */ - 0: '', /* Z_OK 0 */ - '-1': 'file error', /* Z_ERRNO (-1) */ - '-2': 'stream error', /* Z_STREAM_ERROR (-2) */ - '-3': 'data error', /* Z_DATA_ERROR (-3) */ - '-4': 'insufficient memory', /* Z_MEM_ERROR (-4) */ - '-5': 'buffer error', /* Z_BUF_ERROR (-5) */ - '-6': 'incompatible version' /* Z_VERSION_ERROR (-6) */ - }; - - // (C) 1995-2013 Jean-loup Gailly and Mark Adler - // (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin - // - // This software is provided 'as-is', without any express or implied - // warranty. In no event will the authors be held liable for any damages - // arising from the use of this software. - // - // Permission is granted to anyone to use this software for any purpose, - // including commercial applications, and to alter it and redistribute it - // freely, subject to the following restrictions: - // - // 1. The origin of this software must not be misrepresented; you must not - // claim that you wrote the original software. If you use this software - // in a product, an acknowledgment in the product documentation would be - // appreciated but is not required. - // 2. Altered source versions must be plainly marked as such, and must not be - // misrepresented as being the original software. - // 3. This notice may not be removed or altered from any source distribution. - - var constants$2$1 = { - - /* Allowed flush values; see deflate() and inflate() below for details */ - Z_NO_FLUSH: 0, - Z_PARTIAL_FLUSH: 1, - Z_SYNC_FLUSH: 2, - Z_FULL_FLUSH: 3, - Z_FINISH: 4, - Z_BLOCK: 5, - Z_TREES: 6, - - /* Return codes for the compression/decompression functions. Negative values - * are errors, positive values are used for special but normal events. - */ - Z_OK: 0, - Z_STREAM_END: 1, - Z_NEED_DICT: 2, - Z_ERRNO: -1, - Z_STREAM_ERROR: -2, - Z_DATA_ERROR: -3, - Z_MEM_ERROR: -4, - Z_BUF_ERROR: -5, - //Z_VERSION_ERROR: -6, - - /* compression levels */ - Z_NO_COMPRESSION: 0, - Z_BEST_SPEED: 1, - Z_BEST_COMPRESSION: 9, - Z_DEFAULT_COMPRESSION: -1, - - - Z_FILTERED: 1, - Z_HUFFMAN_ONLY: 2, - Z_RLE: 3, - Z_FIXED: 4, - Z_DEFAULT_STRATEGY: 0, - - /* Possible values of the data_type field (though see inflate()) */ - Z_BINARY: 0, - Z_TEXT: 1, - //Z_ASCII: 1, // = Z_TEXT (deprecated) - Z_UNKNOWN: 2, - - /* The deflate compression method */ - Z_DEFLATED: 8 - //Z_NULL: null // Use -1 or null inline, depending on var type - }; - - // (C) 1995-2013 Jean-loup Gailly and Mark Adler - // (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin - // - // This software is provided 'as-is', without any express or implied - // warranty. In no event will the authors be held liable for any damages - // arising from the use of this software. - // - // Permission is granted to anyone to use this software for any purpose, - // including commercial applications, and to alter it and redistribute it - // freely, subject to the following restrictions: - // - // 1. The origin of this software must not be misrepresented; you must not - // claim that you wrote the original software. If you use this software - // in a product, an acknowledgment in the product documentation would be - // appreciated but is not required. - // 2. Altered source versions must be plainly marked as such, and must not be - // misrepresented as being the original software. - // 3. This notice may not be removed or altered from any source distribution. - - const { _tr_init, _tr_stored_block, _tr_flush_block, _tr_tally, _tr_align } = trees; - - - - - /* Public constants ==========================================================*/ - /* ===========================================================================*/ - - const { - Z_NO_FLUSH: Z_NO_FLUSH$2, Z_PARTIAL_FLUSH, Z_FULL_FLUSH: Z_FULL_FLUSH$1, Z_FINISH: Z_FINISH$3, Z_BLOCK: Z_BLOCK$1, - Z_OK: Z_OK$3, Z_STREAM_END: Z_STREAM_END$3, Z_STREAM_ERROR: Z_STREAM_ERROR$2, Z_DATA_ERROR: Z_DATA_ERROR$2, Z_BUF_ERROR: Z_BUF_ERROR$1, - Z_DEFAULT_COMPRESSION: Z_DEFAULT_COMPRESSION$1, - Z_FILTERED, Z_HUFFMAN_ONLY, Z_RLE, Z_FIXED, Z_DEFAULT_STRATEGY: Z_DEFAULT_STRATEGY$1, - Z_UNKNOWN, - Z_DEFLATED: Z_DEFLATED$2 - } = constants$2$1; - - /*============================================================================*/ - - - const MAX_MEM_LEVEL = 9; - /* Maximum value for memLevel in deflateInit2 */ - const MAX_WBITS$1 = 15; - /* 32K LZ77 window */ - const DEF_MEM_LEVEL = 8; - - - const LENGTH_CODES = 29; - /* number of length codes, not counting the special END_BLOCK code */ - const LITERALS = 256; - /* number of literal bytes 0..255 */ - const L_CODES = LITERALS + 1 + LENGTH_CODES; - /* number of Literal or Length codes, including the END_BLOCK code */ - const D_CODES = 30; - /* number of distance codes */ - const BL_CODES = 19; - /* number of codes used to transfer the bit lengths */ - const HEAP_SIZE = 2 * L_CODES + 1; - /* maximum heap size */ - const MAX_BITS = 15; - /* All codes must not exceed MAX_BITS bits */ - - const MIN_MATCH = 3; - const MAX_MATCH = 258; - const MIN_LOOKAHEAD = (MAX_MATCH + MIN_MATCH + 1); - - const PRESET_DICT = 0x20; - - const INIT_STATE = 42; /* zlib header -> BUSY_STATE */ - //#ifdef GZIP - const GZIP_STATE = 57; /* gzip header -> BUSY_STATE | EXTRA_STATE */ - //#endif - const EXTRA_STATE = 69; /* gzip extra block -> NAME_STATE */ - const NAME_STATE = 73; /* gzip file name -> COMMENT_STATE */ - const COMMENT_STATE = 91; /* gzip comment -> HCRC_STATE */ - const HCRC_STATE = 103; /* gzip header CRC -> BUSY_STATE */ - const BUSY_STATE = 113; /* deflate -> FINISH_STATE */ - const FINISH_STATE = 666; /* stream complete */ - - const BS_NEED_MORE = 1; /* block not completed, need more input or more output */ - const BS_BLOCK_DONE = 2; /* block flush performed */ - const BS_FINISH_STARTED = 3; /* finish started, need only more output at next deflate */ - const BS_FINISH_DONE = 4; /* finish done, accept no more input or output */ - - const OS_CODE = 0x03; // Unix :) . Don't detect, use this default. - - const err = (strm, errorCode) => { - strm.msg = messages$1[errorCode]; - return errorCode; - }; - - const rank = (f) => { - return ((f) * 2) - ((f) > 4 ? 9 : 0); - }; - - const zero = (buf) => { - let len = buf.length; while (--len >= 0) { buf[len] = 0; } - }; - - /* =========================================================================== - * Slide the hash table when sliding the window down (could be avoided with 32 - * bit values at the expense of memory usage). We slide even when level == 0 to - * keep the hash table consistent if we switch back to level > 0 later. - */ - const slide_hash = (s) => { - let n, m; - let p; - let wsize = s.w_size; - - n = s.hash_size; - p = n; - do { - m = s.head[--p]; - s.head[p] = (m >= wsize ? m - wsize : 0); - } while (--n); - n = wsize; - //#ifndef FASTEST - p = n; - do { - m = s.prev[--p]; - s.prev[p] = (m >= wsize ? m - wsize : 0); - /* If n is not on any hash chain, prev[n] is garbage but - * its value will never be used. - */ - } while (--n); - //#endif - }; - - /* eslint-disable new-cap */ - let HASH_ZLIB = (s, prev, data) => ((prev << s.hash_shift) ^ data) & s.hash_mask; - // This hash causes less collisions, https://github.com/nodeca/pako/issues/135 - // But breaks binary compatibility - //let HASH_FAST = (s, prev, data) => ((prev << 8) + (prev >> 8) + (data << 4)) & s.hash_mask; - let HASH = HASH_ZLIB; - - - /* ========================================================================= - * Flush as much pending output as possible. All deflate() output, except for - * some deflate_stored() output, goes through this function so some - * applications may wish to modify it to avoid allocating a large - * strm->next_out buffer and copying into it. (See also read_buf()). - */ - const flush_pending = (strm) => { - const s = strm.state; - - //_tr_flush_bits(s); - let len = s.pending; - if (len > strm.avail_out) { - len = strm.avail_out; - } - if (len === 0) { return; } - - strm.output.set(s.pending_buf.subarray(s.pending_out, s.pending_out + len), strm.next_out); - strm.next_out += len; - s.pending_out += len; - strm.total_out += len; - strm.avail_out -= len; - s.pending -= len; - if (s.pending === 0) { - s.pending_out = 0; - } - }; - - - const flush_block_only = (s, last) => { - _tr_flush_block(s, (s.block_start >= 0 ? s.block_start : -1), s.strstart - s.block_start, last); - s.block_start = s.strstart; - flush_pending(s.strm); - }; - - - const put_byte = (s, b) => { - s.pending_buf[s.pending++] = b; - }; - - - /* ========================================================================= - * Put a short in the pending buffer. The 16-bit value is put in MSB order. - * IN assertion: the stream state is correct and there is enough room in - * pending_buf. - */ - const putShortMSB = (s, b) => { - - // put_byte(s, (Byte)(b >> 8)); - // put_byte(s, (Byte)(b & 0xff)); - s.pending_buf[s.pending++] = (b >>> 8) & 0xff; - s.pending_buf[s.pending++] = b & 0xff; - }; - - - /* =========================================================================== - * Read a new buffer from the current input stream, update the adler32 - * and total number of bytes read. All deflate() input goes through - * this function so some applications may wish to modify it to avoid - * allocating a large strm->input buffer and copying from it. - * (See also flush_pending()). - */ - const read_buf = (strm, buf, start, size) => { - - let len = strm.avail_in; - - if (len > size) { len = size; } - if (len === 0) { return 0; } - - strm.avail_in -= len; - - // zmemcpy(buf, strm->next_in, len); - buf.set(strm.input.subarray(strm.next_in, strm.next_in + len), start); - if (strm.state.wrap === 1) { - strm.adler = adler32_1$1(strm.adler, buf, len, start); - } - - else if (strm.state.wrap === 2) { - strm.adler = crc32_1$1(strm.adler, buf, len, start); - } - - strm.next_in += len; - strm.total_in += len; - - return len; - }; - - - /* =========================================================================== - * Set match_start to the longest match starting at the given string and - * return its length. Matches shorter or equal to prev_length are discarded, - * in which case the result is equal to prev_length and match_start is - * garbage. - * IN assertions: cur_match is the head of the hash chain for the current - * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 - * OUT assertion: the match length is not greater than s->lookahead. - */ - const longest_match = (s, cur_match) => { - - let chain_length = s.max_chain_length; /* max hash chain length */ - let scan = s.strstart; /* current string */ - let match; /* matched string */ - let len; /* length of current match */ - let best_len = s.prev_length; /* best match length so far */ - let nice_match = s.nice_match; /* stop if match long enough */ - const limit = (s.strstart > (s.w_size - MIN_LOOKAHEAD)) ? - s.strstart - (s.w_size - MIN_LOOKAHEAD) : 0/*NIL*/; - - const _win = s.window; // shortcut - - const wmask = s.w_mask; - const prev = s.prev; - - /* Stop when cur_match becomes <= limit. To simplify the code, - * we prevent matches with the string of window index 0. - */ - - const strend = s.strstart + MAX_MATCH; - let scan_end1 = _win[scan + best_len - 1]; - let scan_end = _win[scan + best_len]; - - /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. - * It is easy to get rid of this optimization if necessary. - */ - // Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); - - /* Do not waste too much time if we already have a good match: */ - if (s.prev_length >= s.good_match) { - chain_length >>= 2; - } - /* Do not look for matches beyond the end of the input. This is necessary - * to make deflate deterministic. - */ - if (nice_match > s.lookahead) { nice_match = s.lookahead; } - - // Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); - - do { - // Assert(cur_match < s->strstart, "no future"); - match = cur_match; - - /* Skip to next match if the match length cannot increase - * or if the match length is less than 2. Note that the checks below - * for insufficient lookahead only occur occasionally for performance - * reasons. Therefore uninitialized memory will be accessed, and - * conditional jumps will be made that depend on those values. - * However the length of the match is limited to the lookahead, so - * the output of deflate is not affected by the uninitialized values. - */ - - if (_win[match + best_len] !== scan_end || - _win[match + best_len - 1] !== scan_end1 || - _win[match] !== _win[scan] || - _win[++match] !== _win[scan + 1]) { - continue; - } - - /* The check at best_len-1 can be removed because it will be made - * again later. (This heuristic is not always a win.) - * It is not necessary to compare scan[2] and match[2] since they - * are always equal when the other bytes match, given that - * the hash keys are equal and that HASH_BITS >= 8. - */ - scan += 2; - match++; - // Assert(*scan == *match, "match[2]?"); - - /* We check for insufficient lookahead only every 8th comparison; - * the 256th check will be made at strstart+258. - */ - do { - /*jshint noempty:false*/ - } while (_win[++scan] === _win[++match] && _win[++scan] === _win[++match] && - _win[++scan] === _win[++match] && _win[++scan] === _win[++match] && - _win[++scan] === _win[++match] && _win[++scan] === _win[++match] && - _win[++scan] === _win[++match] && _win[++scan] === _win[++match] && - scan < strend); - - // Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); - - len = MAX_MATCH - (strend - scan); - scan = strend - MAX_MATCH; - - if (len > best_len) { - s.match_start = cur_match; - best_len = len; - if (len >= nice_match) { - break; - } - scan_end1 = _win[scan + best_len - 1]; - scan_end = _win[scan + best_len]; - } - } while ((cur_match = prev[cur_match & wmask]) > limit && --chain_length !== 0); - - if (best_len <= s.lookahead) { - return best_len; - } - return s.lookahead; - }; - - - /* =========================================================================== - * Fill the window when the lookahead becomes insufficient. - * Updates strstart and lookahead. - * - * IN assertion: lookahead < MIN_LOOKAHEAD - * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD - * At least one byte has been read, or avail_in == 0; reads are - * performed for at least two bytes (required for the zip translate_eol - * option -- not supported here). - */ - const fill_window = (s) => { - - const _w_size = s.w_size; - let n, more, str; - - //Assert(s->lookahead < MIN_LOOKAHEAD, "already enough lookahead"); - - do { - more = s.window_size - s.lookahead - s.strstart; - - // JS ints have 32 bit, block below not needed - /* Deal with !@#$% 64K limit: */ - //if (sizeof(int) <= 2) { - // if (more == 0 && s->strstart == 0 && s->lookahead == 0) { - // more = wsize; - // - // } else if (more == (unsigned)(-1)) { - // /* Very unlikely, but possible on 16 bit machine if - // * strstart == 0 && lookahead == 1 (input done a byte at time) - // */ - // more--; - // } - //} - - - /* If the window is almost full and there is insufficient lookahead, - * move the upper half to the lower one to make room in the upper half. - */ - if (s.strstart >= _w_size + (_w_size - MIN_LOOKAHEAD)) { - - s.window.set(s.window.subarray(_w_size, _w_size + _w_size - more), 0); - s.match_start -= _w_size; - s.strstart -= _w_size; - /* we now have strstart >= MAX_DIST */ - s.block_start -= _w_size; - if (s.insert > s.strstart) { - s.insert = s.strstart; - } - slide_hash(s); - more += _w_size; - } - if (s.strm.avail_in === 0) { - break; - } - - /* If there was no sliding: - * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && - * more == window_size - lookahead - strstart - * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) - * => more >= window_size - 2*WSIZE + 2 - * In the BIG_MEM or MMAP case (not yet supported), - * window_size == input_size + MIN_LOOKAHEAD && - * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. - * Otherwise, window_size == 2*WSIZE so more >= 2. - * If there was sliding, more >= WSIZE. So in all cases, more >= 2. - */ - //Assert(more >= 2, "more < 2"); - n = read_buf(s.strm, s.window, s.strstart + s.lookahead, more); - s.lookahead += n; - - /* Initialize the hash value now that we have some input: */ - if (s.lookahead + s.insert >= MIN_MATCH) { - str = s.strstart - s.insert; - s.ins_h = s.window[str]; - - /* UPDATE_HASH(s, s->ins_h, s->window[str + 1]); */ - s.ins_h = HASH(s, s.ins_h, s.window[str + 1]); - //#if MIN_MATCH != 3 - // Call update_hash() MIN_MATCH-3 more times - //#endif - while (s.insert) { - /* UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); */ - s.ins_h = HASH(s, s.ins_h, s.window[str + MIN_MATCH - 1]); - - s.prev[str & s.w_mask] = s.head[s.ins_h]; - s.head[s.ins_h] = str; - str++; - s.insert--; - if (s.lookahead + s.insert < MIN_MATCH) { - break; - } - } - } - /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage, - * but this is not important since only literal bytes will be emitted. - */ - - } while (s.lookahead < MIN_LOOKAHEAD && s.strm.avail_in !== 0); - - /* If the WIN_INIT bytes after the end of the current data have never been - * written, then zero those bytes in order to avoid memory check reports of - * the use of uninitialized (or uninitialised as Julian writes) bytes by - * the longest match routines. Update the high water mark for the next - * time through here. WIN_INIT is set to MAX_MATCH since the longest match - * routines allow scanning to strstart + MAX_MATCH, ignoring lookahead. - */ - // if (s.high_water < s.window_size) { - // const curr = s.strstart + s.lookahead; - // let init = 0; - // - // if (s.high_water < curr) { - // /* Previous high water mark below current data -- zero WIN_INIT - // * bytes or up to end of window, whichever is less. - // */ - // init = s.window_size - curr; - // if (init > WIN_INIT) - // init = WIN_INIT; - // zmemzero(s->window + curr, (unsigned)init); - // s->high_water = curr + init; - // } - // else if (s->high_water < (ulg)curr + WIN_INIT) { - // /* High water mark at or above current data, but below current data - // * plus WIN_INIT -- zero out to current data plus WIN_INIT, or up - // * to end of window, whichever is less. - // */ - // init = (ulg)curr + WIN_INIT - s->high_water; - // if (init > s->window_size - s->high_water) - // init = s->window_size - s->high_water; - // zmemzero(s->window + s->high_water, (unsigned)init); - // s->high_water += init; - // } - // } - // - // Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD, - // "not enough room for search"); - }; - - /* =========================================================================== - * Copy without compression as much as possible from the input stream, return - * the current block state. - * - * In case deflateParams() is used to later switch to a non-zero compression - * level, s->matches (otherwise unused when storing) keeps track of the number - * of hash table slides to perform. If s->matches is 1, then one hash table - * slide will be done when switching. If s->matches is 2, the maximum value - * allowed here, then the hash table will be cleared, since two or more slides - * is the same as a clear. - * - * deflate_stored() is written to minimize the number of times an input byte is - * copied. It is most efficient with large input and output buffers, which - * maximizes the opportunites to have a single copy from next_in to next_out. - */ - const deflate_stored = (s, flush) => { - - /* Smallest worthy block size when not flushing or finishing. By default - * this is 32K. This can be as small as 507 bytes for memLevel == 1. For - * large input and output buffers, the stored block size will be larger. - */ - let min_block = s.pending_buf_size - 5 > s.w_size ? s.w_size : s.pending_buf_size - 5; - - /* Copy as many min_block or larger stored blocks directly to next_out as - * possible. If flushing, copy the remaining available input to next_out as - * stored blocks, if there is enough space. - */ - let len, left, have, last = 0; - let used = s.strm.avail_in; - do { - /* Set len to the maximum size block that we can copy directly with the - * available input data and output space. Set left to how much of that - * would be copied from what's left in the window. - */ - len = 65535/* MAX_STORED */; /* maximum deflate stored block length */ - have = (s.bi_valid + 42) >> 3; /* number of header bytes */ - if (s.strm.avail_out < have) { /* need room for header */ - break; - } - /* maximum stored block length that will fit in avail_out: */ - have = s.strm.avail_out - have; - left = s.strstart - s.block_start; /* bytes left in window */ - if (len > left + s.strm.avail_in) { - len = left + s.strm.avail_in; /* limit len to the input */ - } - if (len > have) { - len = have; /* limit len to the output */ - } - - /* If the stored block would be less than min_block in length, or if - * unable to copy all of the available input when flushing, then try - * copying to the window and the pending buffer instead. Also don't - * write an empty block when flushing -- deflate() does that. - */ - if (len < min_block && ((len === 0 && flush !== Z_FINISH$3) || - flush === Z_NO_FLUSH$2 || - len !== left + s.strm.avail_in)) { - break; - } - - /* Make a dummy stored block in pending to get the header bytes, - * including any pending bits. This also updates the debugging counts. - */ - last = flush === Z_FINISH$3 && len === left + s.strm.avail_in ? 1 : 0; - _tr_stored_block(s, 0, 0, last); - - /* Replace the lengths in the dummy stored block with len. */ - s.pending_buf[s.pending - 4] = len; - s.pending_buf[s.pending - 3] = len >> 8; - s.pending_buf[s.pending - 2] = ~len; - s.pending_buf[s.pending - 1] = ~len >> 8; - - /* Write the stored block header bytes. */ - flush_pending(s.strm); - - //#ifdef ZLIB_DEBUG - // /* Update debugging counts for the data about to be copied. */ - // s->compressed_len += len << 3; - // s->bits_sent += len << 3; - //#endif - - /* Copy uncompressed bytes from the window to next_out. */ - if (left) { - if (left > len) { - left = len; - } - //zmemcpy(s->strm->next_out, s->window + s->block_start, left); - s.strm.output.set(s.window.subarray(s.block_start, s.block_start + left), s.strm.next_out); - s.strm.next_out += left; - s.strm.avail_out -= left; - s.strm.total_out += left; - s.block_start += left; - len -= left; - } - - /* Copy uncompressed bytes directly from next_in to next_out, updating - * the check value. - */ - if (len) { - read_buf(s.strm, s.strm.output, s.strm.next_out, len); - s.strm.next_out += len; - s.strm.avail_out -= len; - s.strm.total_out += len; - } - } while (last === 0); - - /* Update the sliding window with the last s->w_size bytes of the copied - * data, or append all of the copied data to the existing window if less - * than s->w_size bytes were copied. Also update the number of bytes to - * insert in the hash tables, in the event that deflateParams() switches to - * a non-zero compression level. - */ - used -= s.strm.avail_in; /* number of input bytes directly copied */ - if (used) { - /* If any input was used, then no unused input remains in the window, - * therefore s->block_start == s->strstart. - */ - if (used >= s.w_size) { /* supplant the previous history */ - s.matches = 2; /* clear hash */ - //zmemcpy(s->window, s->strm->next_in - s->w_size, s->w_size); - s.window.set(s.strm.input.subarray(s.strm.next_in - s.w_size, s.strm.next_in), 0); - s.strstart = s.w_size; - s.insert = s.strstart; - } - else { - if (s.window_size - s.strstart <= used) { - /* Slide the window down. */ - s.strstart -= s.w_size; - //zmemcpy(s->window, s->window + s->w_size, s->strstart); - s.window.set(s.window.subarray(s.w_size, s.w_size + s.strstart), 0); - if (s.matches < 2) { - s.matches++; /* add a pending slide_hash() */ - } - if (s.insert > s.strstart) { - s.insert = s.strstart; - } - } - //zmemcpy(s->window + s->strstart, s->strm->next_in - used, used); - s.window.set(s.strm.input.subarray(s.strm.next_in - used, s.strm.next_in), s.strstart); - s.strstart += used; - s.insert += used > s.w_size - s.insert ? s.w_size - s.insert : used; - } - s.block_start = s.strstart; - } - if (s.high_water < s.strstart) { - s.high_water = s.strstart; - } - - /* If the last block was written to next_out, then done. */ - if (last) { - return BS_FINISH_DONE; - } - - /* If flushing and all input has been consumed, then done. */ - if (flush !== Z_NO_FLUSH$2 && flush !== Z_FINISH$3 && - s.strm.avail_in === 0 && s.strstart === s.block_start) { - return BS_BLOCK_DONE; - } - - /* Fill the window with any remaining input. */ - have = s.window_size - s.strstart; - if (s.strm.avail_in > have && s.block_start >= s.w_size) { - /* Slide the window down. */ - s.block_start -= s.w_size; - s.strstart -= s.w_size; - //zmemcpy(s->window, s->window + s->w_size, s->strstart); - s.window.set(s.window.subarray(s.w_size, s.w_size + s.strstart), 0); - if (s.matches < 2) { - s.matches++; /* add a pending slide_hash() */ - } - have += s.w_size; /* more space now */ - if (s.insert > s.strstart) { - s.insert = s.strstart; - } - } - if (have > s.strm.avail_in) { - have = s.strm.avail_in; - } - if (have) { - read_buf(s.strm, s.window, s.strstart, have); - s.strstart += have; - s.insert += have > s.w_size - s.insert ? s.w_size - s.insert : have; - } - if (s.high_water < s.strstart) { - s.high_water = s.strstart; - } - - /* There was not enough avail_out to write a complete worthy or flushed - * stored block to next_out. Write a stored block to pending instead, if we - * have enough input for a worthy block, or if flushing and there is enough - * room for the remaining input as a stored block in the pending buffer. - */ - have = (s.bi_valid + 42) >> 3; /* number of header bytes */ - /* maximum stored block length that will fit in pending: */ - have = s.pending_buf_size - have > 65535/* MAX_STORED */ ? 65535/* MAX_STORED */ : s.pending_buf_size - have; - min_block = have > s.w_size ? s.w_size : have; - left = s.strstart - s.block_start; - if (left >= min_block || - ((left || flush === Z_FINISH$3) && flush !== Z_NO_FLUSH$2 && - s.strm.avail_in === 0 && left <= have)) { - len = left > have ? have : left; - last = flush === Z_FINISH$3 && s.strm.avail_in === 0 && - len === left ? 1 : 0; - _tr_stored_block(s, s.block_start, len, last); - s.block_start += len; - flush_pending(s.strm); - } - - /* We've done all we can with the available input and output. */ - return last ? BS_FINISH_STARTED : BS_NEED_MORE; - }; - - - /* =========================================================================== - * Compress as much as possible from the input stream, return the current - * block state. - * This function does not perform lazy evaluation of matches and inserts - * new strings in the dictionary only for unmatched strings or for short - * matches. It is used only for the fast compression options. - */ - const deflate_fast = (s, flush) => { - - let hash_head; /* head of the hash chain */ - let bflush; /* set if current block must be flushed */ - - for (;;) { - /* Make sure that we always have enough lookahead, except - * at the end of the input file. We need MAX_MATCH bytes - * for the next match, plus MIN_MATCH bytes to insert the - * string following the next match. - */ - if (s.lookahead < MIN_LOOKAHEAD) { - fill_window(s); - if (s.lookahead < MIN_LOOKAHEAD && flush === Z_NO_FLUSH$2) { - return BS_NEED_MORE; - } - if (s.lookahead === 0) { - break; /* flush the current block */ - } - } - - /* Insert the string window[strstart .. strstart+2] in the - * dictionary, and set hash_head to the head of the hash chain: - */ - hash_head = 0/*NIL*/; - if (s.lookahead >= MIN_MATCH) { - /*** INSERT_STRING(s, s.strstart, hash_head); ***/ - s.ins_h = HASH(s, s.ins_h, s.window[s.strstart + MIN_MATCH - 1]); - hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h]; - s.head[s.ins_h] = s.strstart; - /***/ - } - - /* Find the longest match, discarding those <= prev_length. - * At this point we have always match_length < MIN_MATCH - */ - if (hash_head !== 0/*NIL*/ && ((s.strstart - hash_head) <= (s.w_size - MIN_LOOKAHEAD))) { - /* To simplify the code, we prevent matches with the string - * of window index 0 (in particular we have to avoid a match - * of the string with itself at the start of the input file). - */ - s.match_length = longest_match(s, hash_head); - /* longest_match() sets match_start */ - } - if (s.match_length >= MIN_MATCH) { - // check_match(s, s.strstart, s.match_start, s.match_length); // for debug only - - /*** _tr_tally_dist(s, s.strstart - s.match_start, - s.match_length - MIN_MATCH, bflush); ***/ - bflush = _tr_tally(s, s.strstart - s.match_start, s.match_length - MIN_MATCH); - - s.lookahead -= s.match_length; - - /* Insert new strings in the hash table only if the match length - * is not too large. This saves time but degrades compression. - */ - if (s.match_length <= s.max_lazy_match/*max_insert_length*/ && s.lookahead >= MIN_MATCH) { - s.match_length--; /* string at strstart already in table */ - do { - s.strstart++; - /*** INSERT_STRING(s, s.strstart, hash_head); ***/ - s.ins_h = HASH(s, s.ins_h, s.window[s.strstart + MIN_MATCH - 1]); - hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h]; - s.head[s.ins_h] = s.strstart; - /***/ - /* strstart never exceeds WSIZE-MAX_MATCH, so there are - * always MIN_MATCH bytes ahead. - */ - } while (--s.match_length !== 0); - s.strstart++; - } else - { - s.strstart += s.match_length; - s.match_length = 0; - s.ins_h = s.window[s.strstart]; - /* UPDATE_HASH(s, s.ins_h, s.window[s.strstart+1]); */ - s.ins_h = HASH(s, s.ins_h, s.window[s.strstart + 1]); - - //#if MIN_MATCH != 3 - // Call UPDATE_HASH() MIN_MATCH-3 more times - //#endif - /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not - * matter since it will be recomputed at next deflate call. - */ - } - } else { - /* No match, output a literal byte */ - //Tracevv((stderr,"%c", s.window[s.strstart])); - /*** _tr_tally_lit(s, s.window[s.strstart], bflush); ***/ - bflush = _tr_tally(s, 0, s.window[s.strstart]); - - s.lookahead--; - s.strstart++; - } - if (bflush) { - /*** FLUSH_BLOCK(s, 0); ***/ - flush_block_only(s, false); - if (s.strm.avail_out === 0) { - return BS_NEED_MORE; - } - /***/ - } - } - s.insert = ((s.strstart < (MIN_MATCH - 1)) ? s.strstart : MIN_MATCH - 1); - if (flush === Z_FINISH$3) { - /*** FLUSH_BLOCK(s, 1); ***/ - flush_block_only(s, true); - if (s.strm.avail_out === 0) { - return BS_FINISH_STARTED; - } - /***/ - return BS_FINISH_DONE; - } - if (s.sym_next) { - /*** FLUSH_BLOCK(s, 0); ***/ - flush_block_only(s, false); - if (s.strm.avail_out === 0) { - return BS_NEED_MORE; - } - /***/ - } - return BS_BLOCK_DONE; - }; - - /* =========================================================================== - * Same as above, but achieves better compression. We use a lazy - * evaluation for matches: a match is finally adopted only if there is - * no better match at the next window position. - */ - const deflate_slow = (s, flush) => { - - let hash_head; /* head of hash chain */ - let bflush; /* set if current block must be flushed */ - - let max_insert; - - /* Process the input block. */ - for (;;) { - /* Make sure that we always have enough lookahead, except - * at the end of the input file. We need MAX_MATCH bytes - * for the next match, plus MIN_MATCH bytes to insert the - * string following the next match. - */ - if (s.lookahead < MIN_LOOKAHEAD) { - fill_window(s); - if (s.lookahead < MIN_LOOKAHEAD && flush === Z_NO_FLUSH$2) { - return BS_NEED_MORE; - } - if (s.lookahead === 0) { break; } /* flush the current block */ - } - - /* Insert the string window[strstart .. strstart+2] in the - * dictionary, and set hash_head to the head of the hash chain: - */ - hash_head = 0/*NIL*/; - if (s.lookahead >= MIN_MATCH) { - /*** INSERT_STRING(s, s.strstart, hash_head); ***/ - s.ins_h = HASH(s, s.ins_h, s.window[s.strstart + MIN_MATCH - 1]); - hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h]; - s.head[s.ins_h] = s.strstart; - /***/ - } - - /* Find the longest match, discarding those <= prev_length. - */ - s.prev_length = s.match_length; - s.prev_match = s.match_start; - s.match_length = MIN_MATCH - 1; - - if (hash_head !== 0/*NIL*/ && s.prev_length < s.max_lazy_match && - s.strstart - hash_head <= (s.w_size - MIN_LOOKAHEAD)/*MAX_DIST(s)*/) { - /* To simplify the code, we prevent matches with the string - * of window index 0 (in particular we have to avoid a match - * of the string with itself at the start of the input file). - */ - s.match_length = longest_match(s, hash_head); - /* longest_match() sets match_start */ - - if (s.match_length <= 5 && - (s.strategy === Z_FILTERED || (s.match_length === MIN_MATCH && s.strstart - s.match_start > 4096/*TOO_FAR*/))) { - - /* If prev_match is also MIN_MATCH, match_start is garbage - * but we will ignore the current match anyway. - */ - s.match_length = MIN_MATCH - 1; - } - } - /* If there was a match at the previous step and the current - * match is not better, output the previous match: - */ - if (s.prev_length >= MIN_MATCH && s.match_length <= s.prev_length) { - max_insert = s.strstart + s.lookahead - MIN_MATCH; - /* Do not insert strings in hash table beyond this. */ - - //check_match(s, s.strstart-1, s.prev_match, s.prev_length); - - /***_tr_tally_dist(s, s.strstart - 1 - s.prev_match, - s.prev_length - MIN_MATCH, bflush);***/ - bflush = _tr_tally(s, s.strstart - 1 - s.prev_match, s.prev_length - MIN_MATCH); - /* Insert in hash table all strings up to the end of the match. - * strstart-1 and strstart are already inserted. If there is not - * enough lookahead, the last two strings are not inserted in - * the hash table. - */ - s.lookahead -= s.prev_length - 1; - s.prev_length -= 2; - do { - if (++s.strstart <= max_insert) { - /*** INSERT_STRING(s, s.strstart, hash_head); ***/ - s.ins_h = HASH(s, s.ins_h, s.window[s.strstart + MIN_MATCH - 1]); - hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h]; - s.head[s.ins_h] = s.strstart; - /***/ - } - } while (--s.prev_length !== 0); - s.match_available = 0; - s.match_length = MIN_MATCH - 1; - s.strstart++; - - if (bflush) { - /*** FLUSH_BLOCK(s, 0); ***/ - flush_block_only(s, false); - if (s.strm.avail_out === 0) { - return BS_NEED_MORE; - } - /***/ - } - - } else if (s.match_available) { - /* If there was no match at the previous position, output a - * single literal. If there was a match but the current match - * is longer, truncate the previous match to a single literal. - */ - //Tracevv((stderr,"%c", s->window[s->strstart-1])); - /*** _tr_tally_lit(s, s.window[s.strstart-1], bflush); ***/ - bflush = _tr_tally(s, 0, s.window[s.strstart - 1]); - - if (bflush) { - /*** FLUSH_BLOCK_ONLY(s, 0) ***/ - flush_block_only(s, false); - /***/ - } - s.strstart++; - s.lookahead--; - if (s.strm.avail_out === 0) { - return BS_NEED_MORE; - } - } else { - /* There is no previous match to compare with, wait for - * the next step to decide. - */ - s.match_available = 1; - s.strstart++; - s.lookahead--; - } - } - //Assert (flush != Z_NO_FLUSH, "no flush?"); - if (s.match_available) { - //Tracevv((stderr,"%c", s->window[s->strstart-1])); - /*** _tr_tally_lit(s, s.window[s.strstart-1], bflush); ***/ - bflush = _tr_tally(s, 0, s.window[s.strstart - 1]); - - s.match_available = 0; - } - s.insert = s.strstart < MIN_MATCH - 1 ? s.strstart : MIN_MATCH - 1; - if (flush === Z_FINISH$3) { - /*** FLUSH_BLOCK(s, 1); ***/ - flush_block_only(s, true); - if (s.strm.avail_out === 0) { - return BS_FINISH_STARTED; - } - /***/ - return BS_FINISH_DONE; - } - if (s.sym_next) { - /*** FLUSH_BLOCK(s, 0); ***/ - flush_block_only(s, false); - if (s.strm.avail_out === 0) { - return BS_NEED_MORE; - } - /***/ - } - - return BS_BLOCK_DONE; - }; - - - /* =========================================================================== - * For Z_RLE, simply look for runs of bytes, generate matches only of distance - * one. Do not maintain a hash table. (It will be regenerated if this run of - * deflate switches away from Z_RLE.) - */ - const deflate_rle = (s, flush) => { - - let bflush; /* set if current block must be flushed */ - let prev; /* byte at distance one to match */ - let scan, strend; /* scan goes up to strend for length of run */ - - const _win = s.window; - - for (;;) { - /* Make sure that we always have enough lookahead, except - * at the end of the input file. We need MAX_MATCH bytes - * for the longest run, plus one for the unrolled loop. - */ - if (s.lookahead <= MAX_MATCH) { - fill_window(s); - if (s.lookahead <= MAX_MATCH && flush === Z_NO_FLUSH$2) { - return BS_NEED_MORE; - } - if (s.lookahead === 0) { break; } /* flush the current block */ - } - - /* See how many times the previous byte repeats */ - s.match_length = 0; - if (s.lookahead >= MIN_MATCH && s.strstart > 0) { - scan = s.strstart - 1; - prev = _win[scan]; - if (prev === _win[++scan] && prev === _win[++scan] && prev === _win[++scan]) { - strend = s.strstart + MAX_MATCH; - do { - /*jshint noempty:false*/ - } while (prev === _win[++scan] && prev === _win[++scan] && - prev === _win[++scan] && prev === _win[++scan] && - prev === _win[++scan] && prev === _win[++scan] && - prev === _win[++scan] && prev === _win[++scan] && - scan < strend); - s.match_length = MAX_MATCH - (strend - scan); - if (s.match_length > s.lookahead) { - s.match_length = s.lookahead; - } - } - //Assert(scan <= s->window+(uInt)(s->window_size-1), "wild scan"); - } - - /* Emit match if have run of MIN_MATCH or longer, else emit literal */ - if (s.match_length >= MIN_MATCH) { - //check_match(s, s.strstart, s.strstart - 1, s.match_length); - - /*** _tr_tally_dist(s, 1, s.match_length - MIN_MATCH, bflush); ***/ - bflush = _tr_tally(s, 1, s.match_length - MIN_MATCH); - - s.lookahead -= s.match_length; - s.strstart += s.match_length; - s.match_length = 0; - } else { - /* No match, output a literal byte */ - //Tracevv((stderr,"%c", s->window[s->strstart])); - /*** _tr_tally_lit(s, s.window[s.strstart], bflush); ***/ - bflush = _tr_tally(s, 0, s.window[s.strstart]); - - s.lookahead--; - s.strstart++; - } - if (bflush) { - /*** FLUSH_BLOCK(s, 0); ***/ - flush_block_only(s, false); - if (s.strm.avail_out === 0) { - return BS_NEED_MORE; - } - /***/ - } - } - s.insert = 0; - if (flush === Z_FINISH$3) { - /*** FLUSH_BLOCK(s, 1); ***/ - flush_block_only(s, true); - if (s.strm.avail_out === 0) { - return BS_FINISH_STARTED; - } - /***/ - return BS_FINISH_DONE; - } - if (s.sym_next) { - /*** FLUSH_BLOCK(s, 0); ***/ - flush_block_only(s, false); - if (s.strm.avail_out === 0) { - return BS_NEED_MORE; - } - /***/ - } - return BS_BLOCK_DONE; - }; - - /* =========================================================================== - * For Z_HUFFMAN_ONLY, do not look for matches. Do not maintain a hash table. - * (It will be regenerated if this run of deflate switches away from Huffman.) - */ - const deflate_huff = (s, flush) => { - - let bflush; /* set if current block must be flushed */ - - for (;;) { - /* Make sure that we have a literal to write. */ - if (s.lookahead === 0) { - fill_window(s); - if (s.lookahead === 0) { - if (flush === Z_NO_FLUSH$2) { - return BS_NEED_MORE; - } - break; /* flush the current block */ - } - } - - /* Output a literal byte */ - s.match_length = 0; - //Tracevv((stderr,"%c", s->window[s->strstart])); - /*** _tr_tally_lit(s, s.window[s.strstart], bflush); ***/ - bflush = _tr_tally(s, 0, s.window[s.strstart]); - s.lookahead--; - s.strstart++; - if (bflush) { - /*** FLUSH_BLOCK(s, 0); ***/ - flush_block_only(s, false); - if (s.strm.avail_out === 0) { - return BS_NEED_MORE; - } - /***/ - } - } - s.insert = 0; - if (flush === Z_FINISH$3) { - /*** FLUSH_BLOCK(s, 1); ***/ - flush_block_only(s, true); - if (s.strm.avail_out === 0) { - return BS_FINISH_STARTED; - } - /***/ - return BS_FINISH_DONE; - } - if (s.sym_next) { - /*** FLUSH_BLOCK(s, 0); ***/ - flush_block_only(s, false); - if (s.strm.avail_out === 0) { - return BS_NEED_MORE; - } - /***/ - } - return BS_BLOCK_DONE; - }; - - /* Values for max_lazy_match, good_match and max_chain_length, depending on - * the desired pack level (0..9). The values given below have been tuned to - * exclude worst case performance for pathological files. Better values may be - * found for specific files. - */ - function Config(good_length, max_lazy, nice_length, max_chain, func) { - - this.good_length = good_length; - this.max_lazy = max_lazy; - this.nice_length = nice_length; - this.max_chain = max_chain; - this.func = func; - } - - const configuration_table = [ - /* good lazy nice chain */ - new Config(0, 0, 0, 0, deflate_stored), /* 0 store only */ - new Config(4, 4, 8, 4, deflate_fast), /* 1 max speed, no lazy matches */ - new Config(4, 5, 16, 8, deflate_fast), /* 2 */ - new Config(4, 6, 32, 32, deflate_fast), /* 3 */ - - new Config(4, 4, 16, 16, deflate_slow), /* 4 lazy matches */ - new Config(8, 16, 32, 32, deflate_slow), /* 5 */ - new Config(8, 16, 128, 128, deflate_slow), /* 6 */ - new Config(8, 32, 128, 256, deflate_slow), /* 7 */ - new Config(32, 128, 258, 1024, deflate_slow), /* 8 */ - new Config(32, 258, 258, 4096, deflate_slow) /* 9 max compression */ - ]; - - - /* =========================================================================== - * Initialize the "longest match" routines for a new zlib stream - */ - const lm_init = (s) => { - - s.window_size = 2 * s.w_size; - - /*** CLEAR_HASH(s); ***/ - zero(s.head); // Fill with NIL (= 0); - - /* Set the default configuration parameters: - */ - s.max_lazy_match = configuration_table[s.level].max_lazy; - s.good_match = configuration_table[s.level].good_length; - s.nice_match = configuration_table[s.level].nice_length; - s.max_chain_length = configuration_table[s.level].max_chain; - - s.strstart = 0; - s.block_start = 0; - s.lookahead = 0; - s.insert = 0; - s.match_length = s.prev_length = MIN_MATCH - 1; - s.match_available = 0; - s.ins_h = 0; - }; - - - function DeflateState() { - this.strm = null; /* pointer back to this zlib stream */ - this.status = 0; /* as the name implies */ - this.pending_buf = null; /* output still pending */ - this.pending_buf_size = 0; /* size of pending_buf */ - this.pending_out = 0; /* next pending byte to output to the stream */ - this.pending = 0; /* nb of bytes in the pending buffer */ - this.wrap = 0; /* bit 0 true for zlib, bit 1 true for gzip */ - this.gzhead = null; /* gzip header information to write */ - this.gzindex = 0; /* where in extra, name, or comment */ - this.method = Z_DEFLATED$2; /* can only be DEFLATED */ - this.last_flush = -1; /* value of flush param for previous deflate call */ - - this.w_size = 0; /* LZ77 window size (32K by default) */ - this.w_bits = 0; /* log2(w_size) (8..16) */ - this.w_mask = 0; /* w_size - 1 */ - - this.window = null; - /* Sliding window. Input bytes are read into the second half of the window, - * and move to the first half later to keep a dictionary of at least wSize - * bytes. With this organization, matches are limited to a distance of - * wSize-MAX_MATCH bytes, but this ensures that IO is always - * performed with a length multiple of the block size. - */ - - this.window_size = 0; - /* Actual size of window: 2*wSize, except when the user input buffer - * is directly used as sliding window. - */ - - this.prev = null; - /* Link to older string with same hash index. To limit the size of this - * array to 64K, this link is maintained only for the last 32K strings. - * An index in this array is thus a window index modulo 32K. - */ - - this.head = null; /* Heads of the hash chains or NIL. */ - - this.ins_h = 0; /* hash index of string to be inserted */ - this.hash_size = 0; /* number of elements in hash table */ - this.hash_bits = 0; /* log2(hash_size) */ - this.hash_mask = 0; /* hash_size-1 */ - - this.hash_shift = 0; - /* Number of bits by which ins_h must be shifted at each input - * step. It must be such that after MIN_MATCH steps, the oldest - * byte no longer takes part in the hash key, that is: - * hash_shift * MIN_MATCH >= hash_bits - */ - - this.block_start = 0; - /* Window position at the beginning of the current output block. Gets - * negative when the window is moved backwards. - */ - - this.match_length = 0; /* length of best match */ - this.prev_match = 0; /* previous match */ - this.match_available = 0; /* set if previous match exists */ - this.strstart = 0; /* start of string to insert */ - this.match_start = 0; /* start of matching string */ - this.lookahead = 0; /* number of valid bytes ahead in window */ - - this.prev_length = 0; - /* Length of the best match at previous step. Matches not greater than this - * are discarded. This is used in the lazy match evaluation. - */ - - this.max_chain_length = 0; - /* To speed up deflation, hash chains are never searched beyond this - * length. A higher limit improves compression ratio but degrades the - * speed. - */ - - this.max_lazy_match = 0; - /* Attempt to find a better match only when the current match is strictly - * smaller than this value. This mechanism is used only for compression - * levels >= 4. - */ - // That's alias to max_lazy_match, don't use directly - //this.max_insert_length = 0; - /* Insert new strings in the hash table only if the match length is not - * greater than this length. This saves time but degrades compression. - * max_insert_length is used only for compression levels <= 3. - */ - - this.level = 0; /* compression level (1..9) */ - this.strategy = 0; /* favor or force Huffman coding*/ - - this.good_match = 0; - /* Use a faster search when the previous match is longer than this */ - - this.nice_match = 0; /* Stop searching when current match exceeds this */ - - /* used by trees.c: */ - - /* Didn't use ct_data typedef below to suppress compiler warning */ - - // struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */ - // struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */ - // struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */ - - // Use flat array of DOUBLE size, with interleaved fata, - // because JS does not support effective - this.dyn_ltree = new Uint16Array(HEAP_SIZE * 2); - this.dyn_dtree = new Uint16Array((2 * D_CODES + 1) * 2); - this.bl_tree = new Uint16Array((2 * BL_CODES + 1) * 2); - zero(this.dyn_ltree); - zero(this.dyn_dtree); - zero(this.bl_tree); - - this.l_desc = null; /* desc. for literal tree */ - this.d_desc = null; /* desc. for distance tree */ - this.bl_desc = null; /* desc. for bit length tree */ - - //ush bl_count[MAX_BITS+1]; - this.bl_count = new Uint16Array(MAX_BITS + 1); - /* number of codes at each bit length for an optimal tree */ - - //int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */ - this.heap = new Uint16Array(2 * L_CODES + 1); /* heap used to build the Huffman trees */ - zero(this.heap); - - this.heap_len = 0; /* number of elements in the heap */ - this.heap_max = 0; /* element of largest frequency */ - /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. - * The same heap array is used to build all trees. - */ - - this.depth = new Uint16Array(2 * L_CODES + 1); //uch depth[2*L_CODES+1]; - zero(this.depth); - /* Depth of each subtree used as tie breaker for trees of equal frequency - */ - - this.sym_buf = 0; /* buffer for distances and literals/lengths */ - - this.lit_bufsize = 0; - /* Size of match buffer for literals/lengths. There are 4 reasons for - * limiting lit_bufsize to 64K: - * - frequencies can be kept in 16 bit counters - * - if compression is not successful for the first block, all input - * data is still in the window so we can still emit a stored block even - * when input comes from standard input. (This can also be done for - * all blocks if lit_bufsize is not greater than 32K.) - * - if compression is not successful for a file smaller than 64K, we can - * even emit a stored file instead of a stored block (saving 5 bytes). - * This is applicable only for zip (not gzip or zlib). - * - creating new Huffman trees less frequently may not provide fast - * adaptation to changes in the input data statistics. (Take for - * example a binary file with poorly compressible code followed by - * a highly compressible string table.) Smaller buffer sizes give - * fast adaptation but have of course the overhead of transmitting - * trees more frequently. - * - I can't count above 4 - */ - - this.sym_next = 0; /* running index in sym_buf */ - this.sym_end = 0; /* symbol table full when sym_next reaches this */ - - this.opt_len = 0; /* bit length of current block with optimal trees */ - this.static_len = 0; /* bit length of current block with static trees */ - this.matches = 0; /* number of string matches in current block */ - this.insert = 0; /* bytes at end of window left to insert */ - - - this.bi_buf = 0; - /* Output buffer. bits are inserted starting at the bottom (least - * significant bits). - */ - this.bi_valid = 0; - /* Number of valid bits in bi_buf. All bits above the last valid bit - * are always zero. - */ - - // Used for window memory init. We safely ignore it for JS. That makes - // sense only for pointers and memory check tools. - //this.high_water = 0; - /* High water mark offset in window for initialized bytes -- bytes above - * this are set to zero in order to avoid memory check warnings when - * longest match routines access bytes past the input. This is then - * updated to the new high water mark. - */ - } - - - /* ========================================================================= - * Check for a valid deflate stream state. Return 0 if ok, 1 if not. - */ - const deflateStateCheck = (strm) => { - - if (!strm) { - return 1; - } - const s = strm.state; - if (!s || s.strm !== strm || (s.status !== INIT_STATE && - //#ifdef GZIP - s.status !== GZIP_STATE && - //#endif - s.status !== EXTRA_STATE && - s.status !== NAME_STATE && - s.status !== COMMENT_STATE && - s.status !== HCRC_STATE && - s.status !== BUSY_STATE && - s.status !== FINISH_STATE)) { - return 1; - } - return 0; - }; - - - const deflateResetKeep = (strm) => { - - if (deflateStateCheck(strm)) { - return err(strm, Z_STREAM_ERROR$2); - } - - strm.total_in = strm.total_out = 0; - strm.data_type = Z_UNKNOWN; - - const s = strm.state; - s.pending = 0; - s.pending_out = 0; - - if (s.wrap < 0) { - s.wrap = -s.wrap; - /* was made negative by deflate(..., Z_FINISH); */ - } - s.status = - //#ifdef GZIP - s.wrap === 2 ? GZIP_STATE : - //#endif - s.wrap ? INIT_STATE : BUSY_STATE; - strm.adler = (s.wrap === 2) ? - 0 // crc32(0, Z_NULL, 0) - : - 1; // adler32(0, Z_NULL, 0) - s.last_flush = -2; - _tr_init(s); - return Z_OK$3; - }; - - - const deflateReset = (strm) => { - - const ret = deflateResetKeep(strm); - if (ret === Z_OK$3) { - lm_init(strm.state); - } - return ret; - }; - - - const deflateSetHeader = (strm, head) => { - - if (deflateStateCheck(strm) || strm.state.wrap !== 2) { - return Z_STREAM_ERROR$2; - } - strm.state.gzhead = head; - return Z_OK$3; - }; - - - const deflateInit2 = (strm, level, method, windowBits, memLevel, strategy) => { - - if (!strm) { // === Z_NULL - return Z_STREAM_ERROR$2; - } - let wrap = 1; - - if (level === Z_DEFAULT_COMPRESSION$1) { - level = 6; - } - - if (windowBits < 0) { /* suppress zlib wrapper */ - wrap = 0; - windowBits = -windowBits; - } - - else if (windowBits > 15) { - wrap = 2; /* write gzip wrapper instead */ - windowBits -= 16; - } - - - if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method !== Z_DEFLATED$2 || - windowBits < 8 || windowBits > 15 || level < 0 || level > 9 || - strategy < 0 || strategy > Z_FIXED || (windowBits === 8 && wrap !== 1)) { - return err(strm, Z_STREAM_ERROR$2); - } - - - if (windowBits === 8) { - windowBits = 9; - } - /* until 256-byte window bug fixed */ - - const s = new DeflateState(); - - strm.state = s; - s.strm = strm; - s.status = INIT_STATE; /* to pass state test in deflateReset() */ - - s.wrap = wrap; - s.gzhead = null; - s.w_bits = windowBits; - s.w_size = 1 << s.w_bits; - s.w_mask = s.w_size - 1; - - s.hash_bits = memLevel + 7; - s.hash_size = 1 << s.hash_bits; - s.hash_mask = s.hash_size - 1; - s.hash_shift = ~~((s.hash_bits + MIN_MATCH - 1) / MIN_MATCH); - - s.window = new Uint8Array(s.w_size * 2); - s.head = new Uint16Array(s.hash_size); - s.prev = new Uint16Array(s.w_size); - - // Don't need mem init magic for JS. - //s.high_water = 0; /* nothing written to s->window yet */ - - s.lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */ - - /* We overlay pending_buf and sym_buf. This works since the average size - * for length/distance pairs over any compressed block is assured to be 31 - * bits or less. - * - * Analysis: The longest fixed codes are a length code of 8 bits plus 5 - * extra bits, for lengths 131 to 257. The longest fixed distance codes are - * 5 bits plus 13 extra bits, for distances 16385 to 32768. The longest - * possible fixed-codes length/distance pair is then 31 bits total. - * - * sym_buf starts one-fourth of the way into pending_buf. So there are - * three bytes in sym_buf for every four bytes in pending_buf. Each symbol - * in sym_buf is three bytes -- two for the distance and one for the - * literal/length. As each symbol is consumed, the pointer to the next - * sym_buf value to read moves forward three bytes. From that symbol, up to - * 31 bits are written to pending_buf. The closest the written pending_buf - * bits gets to the next sym_buf symbol to read is just before the last - * code is written. At that time, 31*(n-2) bits have been written, just - * after 24*(n-2) bits have been consumed from sym_buf. sym_buf starts at - * 8*n bits into pending_buf. (Note that the symbol buffer fills when n-1 - * symbols are written.) The closest the writing gets to what is unread is - * then n+14 bits. Here n is lit_bufsize, which is 16384 by default, and - * can range from 128 to 32768. - * - * Therefore, at a minimum, there are 142 bits of space between what is - * written and what is read in the overlain buffers, so the symbols cannot - * be overwritten by the compressed data. That space is actually 139 bits, - * due to the three-bit fixed-code block header. - * - * That covers the case where either Z_FIXED is specified, forcing fixed - * codes, or when the use of fixed codes is chosen, because that choice - * results in a smaller compressed block than dynamic codes. That latter - * condition then assures that the above analysis also covers all dynamic - * blocks. A dynamic-code block will only be chosen to be emitted if it has - * fewer bits than a fixed-code block would for the same set of symbols. - * Therefore its average symbol length is assured to be less than 31. So - * the compressed data for a dynamic block also cannot overwrite the - * symbols from which it is being constructed. - */ - - s.pending_buf_size = s.lit_bufsize * 4; - s.pending_buf = new Uint8Array(s.pending_buf_size); - - // It is offset from `s.pending_buf` (size is `s.lit_bufsize * 2`) - //s->sym_buf = s->pending_buf + s->lit_bufsize; - s.sym_buf = s.lit_bufsize; - - //s->sym_end = (s->lit_bufsize - 1) * 3; - s.sym_end = (s.lit_bufsize - 1) * 3; - /* We avoid equality with lit_bufsize*3 because of wraparound at 64K - * on 16 bit machines and because stored blocks are restricted to - * 64K-1 bytes. - */ - - s.level = level; - s.strategy = strategy; - s.method = method; - - return deflateReset(strm); - }; - - const deflateInit = (strm, level) => { - - return deflateInit2(strm, level, Z_DEFLATED$2, MAX_WBITS$1, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY$1); - }; - - - /* ========================================================================= */ - const deflate$2 = (strm, flush) => { - - if (deflateStateCheck(strm) || flush > Z_BLOCK$1 || flush < 0) { - return strm ? err(strm, Z_STREAM_ERROR$2) : Z_STREAM_ERROR$2; - } - - const s = strm.state; - - if (!strm.output || - (strm.avail_in !== 0 && !strm.input) || - (s.status === FINISH_STATE && flush !== Z_FINISH$3)) { - return err(strm, (strm.avail_out === 0) ? Z_BUF_ERROR$1 : Z_STREAM_ERROR$2); - } - - const old_flush = s.last_flush; - s.last_flush = flush; - - /* Flush as much pending output as possible */ - if (s.pending !== 0) { - flush_pending(strm); - if (strm.avail_out === 0) { - /* Since avail_out is 0, deflate will be called again with - * more output space, but possibly with both pending and - * avail_in equal to zero. There won't be anything to do, - * but this is not an error situation so make sure we - * return OK instead of BUF_ERROR at next call of deflate: - */ - s.last_flush = -1; - return Z_OK$3; - } - - /* Make sure there is something to do and avoid duplicate consecutive - * flushes. For repeated and useless calls with Z_FINISH, we keep - * returning Z_STREAM_END instead of Z_BUF_ERROR. - */ - } else if (strm.avail_in === 0 && rank(flush) <= rank(old_flush) && - flush !== Z_FINISH$3) { - return err(strm, Z_BUF_ERROR$1); - } - - /* User must not provide more input after the first FINISH: */ - if (s.status === FINISH_STATE && strm.avail_in !== 0) { - return err(strm, Z_BUF_ERROR$1); - } - - /* Write the header */ - if (s.status === INIT_STATE && s.wrap === 0) { - s.status = BUSY_STATE; - } - if (s.status === INIT_STATE) { - /* zlib header */ - let header = (Z_DEFLATED$2 + ((s.w_bits - 8) << 4)) << 8; - let level_flags = -1; - - if (s.strategy >= Z_HUFFMAN_ONLY || s.level < 2) { - level_flags = 0; - } else if (s.level < 6) { - level_flags = 1; - } else if (s.level === 6) { - level_flags = 2; - } else { - level_flags = 3; - } - header |= (level_flags << 6); - if (s.strstart !== 0) { header |= PRESET_DICT; } - header += 31 - (header % 31); - - putShortMSB(s, header); - - /* Save the adler32 of the preset dictionary: */ - if (s.strstart !== 0) { - putShortMSB(s, strm.adler >>> 16); - putShortMSB(s, strm.adler & 0xffff); - } - strm.adler = 1; // adler32(0L, Z_NULL, 0); - s.status = BUSY_STATE; - - /* Compression must start with an empty pending buffer */ - flush_pending(strm); - if (s.pending !== 0) { - s.last_flush = -1; - return Z_OK$3; - } - } - //#ifdef GZIP - if (s.status === GZIP_STATE) { - /* gzip header */ - strm.adler = 0; //crc32(0L, Z_NULL, 0); - put_byte(s, 31); - put_byte(s, 139); - put_byte(s, 8); - if (!s.gzhead) { // s->gzhead == Z_NULL - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, s.level === 9 ? 2 : - (s.strategy >= Z_HUFFMAN_ONLY || s.level < 2 ? - 4 : 0)); - put_byte(s, OS_CODE); - s.status = BUSY_STATE; - - /* Compression must start with an empty pending buffer */ - flush_pending(strm); - if (s.pending !== 0) { - s.last_flush = -1; - return Z_OK$3; - } - } - else { - put_byte(s, (s.gzhead.text ? 1 : 0) + - (s.gzhead.hcrc ? 2 : 0) + - (!s.gzhead.extra ? 0 : 4) + - (!s.gzhead.name ? 0 : 8) + - (!s.gzhead.comment ? 0 : 16) - ); - put_byte(s, s.gzhead.time & 0xff); - put_byte(s, (s.gzhead.time >> 8) & 0xff); - put_byte(s, (s.gzhead.time >> 16) & 0xff); - put_byte(s, (s.gzhead.time >> 24) & 0xff); - put_byte(s, s.level === 9 ? 2 : - (s.strategy >= Z_HUFFMAN_ONLY || s.level < 2 ? - 4 : 0)); - put_byte(s, s.gzhead.os & 0xff); - if (s.gzhead.extra && s.gzhead.extra.length) { - put_byte(s, s.gzhead.extra.length & 0xff); - put_byte(s, (s.gzhead.extra.length >> 8) & 0xff); - } - if (s.gzhead.hcrc) { - strm.adler = crc32_1$1(strm.adler, s.pending_buf, s.pending, 0); - } - s.gzindex = 0; - s.status = EXTRA_STATE; - } - } - if (s.status === EXTRA_STATE) { - if (s.gzhead.extra/* != Z_NULL*/) { - let beg = s.pending; /* start of bytes to update crc */ - let left = (s.gzhead.extra.length & 0xffff) - s.gzindex; - while (s.pending + left > s.pending_buf_size) { - let copy = s.pending_buf_size - s.pending; - // zmemcpy(s.pending_buf + s.pending, - // s.gzhead.extra + s.gzindex, copy); - s.pending_buf.set(s.gzhead.extra.subarray(s.gzindex, s.gzindex + copy), s.pending); - s.pending = s.pending_buf_size; - //--- HCRC_UPDATE(beg) ---// - if (s.gzhead.hcrc && s.pending > beg) { - strm.adler = crc32_1$1(strm.adler, s.pending_buf, s.pending - beg, beg); - } - //---// - s.gzindex += copy; - flush_pending(strm); - if (s.pending !== 0) { - s.last_flush = -1; - return Z_OK$3; - } - beg = 0; - left -= copy; - } - // JS specific: s.gzhead.extra may be TypedArray or Array for backward compatibility - // TypedArray.slice and TypedArray.from don't exist in IE10-IE11 - let gzhead_extra = new Uint8Array(s.gzhead.extra); - // zmemcpy(s->pending_buf + s->pending, - // s->gzhead->extra + s->gzindex, left); - s.pending_buf.set(gzhead_extra.subarray(s.gzindex, s.gzindex + left), s.pending); - s.pending += left; - //--- HCRC_UPDATE(beg) ---// - if (s.gzhead.hcrc && s.pending > beg) { - strm.adler = crc32_1$1(strm.adler, s.pending_buf, s.pending - beg, beg); - } - //---// - s.gzindex = 0; - } - s.status = NAME_STATE; - } - if (s.status === NAME_STATE) { - if (s.gzhead.name/* != Z_NULL*/) { - let beg = s.pending; /* start of bytes to update crc */ - let val; - do { - if (s.pending === s.pending_buf_size) { - //--- HCRC_UPDATE(beg) ---// - if (s.gzhead.hcrc && s.pending > beg) { - strm.adler = crc32_1$1(strm.adler, s.pending_buf, s.pending - beg, beg); - } - //---// - flush_pending(strm); - if (s.pending !== 0) { - s.last_flush = -1; - return Z_OK$3; - } - beg = 0; - } - // JS specific: little magic to add zero terminator to end of string - if (s.gzindex < s.gzhead.name.length) { - val = s.gzhead.name.charCodeAt(s.gzindex++) & 0xff; - } else { - val = 0; - } - put_byte(s, val); - } while (val !== 0); - //--- HCRC_UPDATE(beg) ---// - if (s.gzhead.hcrc && s.pending > beg) { - strm.adler = crc32_1$1(strm.adler, s.pending_buf, s.pending - beg, beg); - } - //---// - s.gzindex = 0; - } - s.status = COMMENT_STATE; - } - if (s.status === COMMENT_STATE) { - if (s.gzhead.comment/* != Z_NULL*/) { - let beg = s.pending; /* start of bytes to update crc */ - let val; - do { - if (s.pending === s.pending_buf_size) { - //--- HCRC_UPDATE(beg) ---// - if (s.gzhead.hcrc && s.pending > beg) { - strm.adler = crc32_1$1(strm.adler, s.pending_buf, s.pending - beg, beg); - } - //---// - flush_pending(strm); - if (s.pending !== 0) { - s.last_flush = -1; - return Z_OK$3; - } - beg = 0; - } - // JS specific: little magic to add zero terminator to end of string - if (s.gzindex < s.gzhead.comment.length) { - val = s.gzhead.comment.charCodeAt(s.gzindex++) & 0xff; - } else { - val = 0; - } - put_byte(s, val); - } while (val !== 0); - //--- HCRC_UPDATE(beg) ---// - if (s.gzhead.hcrc && s.pending > beg) { - strm.adler = crc32_1$1(strm.adler, s.pending_buf, s.pending - beg, beg); - } - //---// - } - s.status = HCRC_STATE; - } - if (s.status === HCRC_STATE) { - if (s.gzhead.hcrc) { - if (s.pending + 2 > s.pending_buf_size) { - flush_pending(strm); - if (s.pending !== 0) { - s.last_flush = -1; - return Z_OK$3; - } - } - put_byte(s, strm.adler & 0xff); - put_byte(s, (strm.adler >> 8) & 0xff); - strm.adler = 0; //crc32(0L, Z_NULL, 0); - } - s.status = BUSY_STATE; - - /* Compression must start with an empty pending buffer */ - flush_pending(strm); - if (s.pending !== 0) { - s.last_flush = -1; - return Z_OK$3; - } - } - //#endif - - /* Start a new block or continue the current one. - */ - if (strm.avail_in !== 0 || s.lookahead !== 0 || - (flush !== Z_NO_FLUSH$2 && s.status !== FINISH_STATE)) { - let bstate = s.level === 0 ? deflate_stored(s, flush) : - s.strategy === Z_HUFFMAN_ONLY ? deflate_huff(s, flush) : - s.strategy === Z_RLE ? deflate_rle(s, flush) : - configuration_table[s.level].func(s, flush); - - if (bstate === BS_FINISH_STARTED || bstate === BS_FINISH_DONE) { - s.status = FINISH_STATE; - } - if (bstate === BS_NEED_MORE || bstate === BS_FINISH_STARTED) { - if (strm.avail_out === 0) { - s.last_flush = -1; - /* avoid BUF_ERROR next call, see above */ - } - return Z_OK$3; - /* If flush != Z_NO_FLUSH && avail_out == 0, the next call - * of deflate should use the same flush parameter to make sure - * that the flush is complete. So we don't have to output an - * empty block here, this will be done at next call. This also - * ensures that for a very small output buffer, we emit at most - * one empty block. - */ - } - if (bstate === BS_BLOCK_DONE) { - if (flush === Z_PARTIAL_FLUSH) { - _tr_align(s); - } - else if (flush !== Z_BLOCK$1) { /* FULL_FLUSH or SYNC_FLUSH */ - - _tr_stored_block(s, 0, 0, false); - /* For a full flush, this empty block will be recognized - * as a special marker by inflate_sync(). - */ - if (flush === Z_FULL_FLUSH$1) { - /*** CLEAR_HASH(s); ***/ /* forget history */ - zero(s.head); // Fill with NIL (= 0); - - if (s.lookahead === 0) { - s.strstart = 0; - s.block_start = 0; - s.insert = 0; - } - } - } - flush_pending(strm); - if (strm.avail_out === 0) { - s.last_flush = -1; /* avoid BUF_ERROR at next call, see above */ - return Z_OK$3; - } - } - } - - if (flush !== Z_FINISH$3) { return Z_OK$3; } - if (s.wrap <= 0) { return Z_STREAM_END$3; } - - /* Write the trailer */ - if (s.wrap === 2) { - put_byte(s, strm.adler & 0xff); - put_byte(s, (strm.adler >> 8) & 0xff); - put_byte(s, (strm.adler >> 16) & 0xff); - put_byte(s, (strm.adler >> 24) & 0xff); - put_byte(s, strm.total_in & 0xff); - put_byte(s, (strm.total_in >> 8) & 0xff); - put_byte(s, (strm.total_in >> 16) & 0xff); - put_byte(s, (strm.total_in >> 24) & 0xff); - } - else - { - putShortMSB(s, strm.adler >>> 16); - putShortMSB(s, strm.adler & 0xffff); - } - - flush_pending(strm); - /* If avail_out is zero, the application will call deflate again - * to flush the rest. - */ - if (s.wrap > 0) { s.wrap = -s.wrap; } - /* write the trailer only once! */ - return s.pending !== 0 ? Z_OK$3 : Z_STREAM_END$3; - }; - - - const deflateEnd = (strm) => { - - if (deflateStateCheck(strm)) { - return Z_STREAM_ERROR$2; - } - - const status = strm.state.status; - - strm.state = null; - - return status === BUSY_STATE ? err(strm, Z_DATA_ERROR$2) : Z_OK$3; - }; - - - /* ========================================================================= - * Initializes the compression dictionary from the given byte - * sequence without producing any compressed output. - */ - const deflateSetDictionary = (strm, dictionary) => { - - let dictLength = dictionary.length; - - if (deflateStateCheck(strm)) { - return Z_STREAM_ERROR$2; - } - - const s = strm.state; - const wrap = s.wrap; - - if (wrap === 2 || (wrap === 1 && s.status !== INIT_STATE) || s.lookahead) { - return Z_STREAM_ERROR$2; - } - - /* when using zlib wrappers, compute Adler-32 for provided dictionary */ - if (wrap === 1) { - /* adler32(strm->adler, dictionary, dictLength); */ - strm.adler = adler32_1$1(strm.adler, dictionary, dictLength, 0); - } - - s.wrap = 0; /* avoid computing Adler-32 in read_buf */ - - /* if dictionary would fill window, just replace the history */ - if (dictLength >= s.w_size) { - if (wrap === 0) { /* already empty otherwise */ - /*** CLEAR_HASH(s); ***/ - zero(s.head); // Fill with NIL (= 0); - s.strstart = 0; - s.block_start = 0; - s.insert = 0; - } - /* use the tail */ - // dictionary = dictionary.slice(dictLength - s.w_size); - let tmpDict = new Uint8Array(s.w_size); - tmpDict.set(dictionary.subarray(dictLength - s.w_size, dictLength), 0); - dictionary = tmpDict; - dictLength = s.w_size; - } - /* insert dictionary into window and hash */ - const avail = strm.avail_in; - const next = strm.next_in; - const input = strm.input; - strm.avail_in = dictLength; - strm.next_in = 0; - strm.input = dictionary; - fill_window(s); - while (s.lookahead >= MIN_MATCH) { - let str = s.strstart; - let n = s.lookahead - (MIN_MATCH - 1); - do { - /* UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); */ - s.ins_h = HASH(s, s.ins_h, s.window[str + MIN_MATCH - 1]); - - s.prev[str & s.w_mask] = s.head[s.ins_h]; - - s.head[s.ins_h] = str; - str++; - } while (--n); - s.strstart = str; - s.lookahead = MIN_MATCH - 1; - fill_window(s); - } - s.strstart += s.lookahead; - s.block_start = s.strstart; - s.insert = s.lookahead; - s.lookahead = 0; - s.match_length = s.prev_length = MIN_MATCH - 1; - s.match_available = 0; - strm.next_in = next; - strm.input = input; - strm.avail_in = avail; - s.wrap = wrap; - return Z_OK$3; - }; - - - var deflateInit_1 = deflateInit; - var deflateInit2_1 = deflateInit2; - var deflateReset_1 = deflateReset; - var deflateResetKeep_1 = deflateResetKeep; - var deflateSetHeader_1 = deflateSetHeader; - var deflate_2$1 = deflate$2; - var deflateEnd_1 = deflateEnd; - var deflateSetDictionary_1 = deflateSetDictionary; - var deflateInfo = 'pako deflate (from Nodeca project)'; - - /* Not implemented - module.exports.deflateBound = deflateBound; - module.exports.deflateCopy = deflateCopy; - module.exports.deflateGetDictionary = deflateGetDictionary; - module.exports.deflateParams = deflateParams; - module.exports.deflatePending = deflatePending; - module.exports.deflatePrime = deflatePrime; - module.exports.deflateTune = deflateTune; - */ - - var deflate_1$2 = { - deflateInit: deflateInit_1, - deflateInit2: deflateInit2_1, - deflateReset: deflateReset_1, - deflateResetKeep: deflateResetKeep_1, - deflateSetHeader: deflateSetHeader_1, - deflate: deflate_2$1, - deflateEnd: deflateEnd_1, - deflateSetDictionary: deflateSetDictionary_1, - deflateInfo: deflateInfo - }; - - const _has$1 = (obj, key) => { - return Object.prototype.hasOwnProperty.call(obj, key); - }; - - var assign$1 = function (obj /*from1, from2, from3, ...*/) { - const sources = Array.prototype.slice.call(arguments, 1); - while (sources.length) { - const source = sources.shift(); - if (!source) { continue; } - - if (typeof source !== 'object') { - throw new TypeError(source + 'must be non-object'); - } - - for (const p in source) { - if (_has$1(source, p)) { - obj[p] = source[p]; - } - } - } - - return obj; - }; - - - // Join array of chunks to single array. - var flattenChunks$1 = (chunks) => { - // calculate data length - let len = 0; - - for (let i = 0, l = chunks.length; i < l; i++) { - len += chunks[i].length; - } - - // join chunks - const result = new Uint8Array(len); - - for (let i = 0, pos = 0, l = chunks.length; i < l; i++) { - let chunk = chunks[i]; - result.set(chunk, pos); - pos += chunk.length; - } - - return result; - }; - - var common$1 = { - assign: assign$1, - flattenChunks: flattenChunks$1 - }; - - // String encode/decode helpers - - - // Quick check if we can use fast array to bin string conversion - // - // - apply(Array) can fail on Android 2.2 - // - apply(Uint8Array) can fail on iOS 5.1 Safari - // - let STR_APPLY_UIA_OK$1 = true; - - try { String.fromCharCode.apply(null, new Uint8Array(1)); } catch (__) { STR_APPLY_UIA_OK$1 = false; } - - - // Table with utf8 lengths (calculated by first byte of sequence) - // Note, that 5 & 6-byte values and some 4-byte values can not be represented in JS, - // because max possible codepoint is 0x10ffff - const _utf8len$1 = new Uint8Array(256); - for (let q = 0; q < 256; q++) { - _utf8len$1[q] = (q >= 252 ? 6 : q >= 248 ? 5 : q >= 240 ? 4 : q >= 224 ? 3 : q >= 192 ? 2 : 1); - } - _utf8len$1[254] = _utf8len$1[254] = 1; // Invalid sequence start - - - // convert string to array (typed, when possible) - var string2buf$1 = (str) => { - if (typeof TextEncoder === 'function' && TextEncoder.prototype.encode) { - return new TextEncoder().encode(str); - } - - let buf, c, c2, m_pos, i, str_len = str.length, buf_len = 0; - - // count binary size - for (m_pos = 0; m_pos < str_len; m_pos++) { - c = str.charCodeAt(m_pos); - if ((c & 0xfc00) === 0xd800 && (m_pos + 1 < str_len)) { - c2 = str.charCodeAt(m_pos + 1); - if ((c2 & 0xfc00) === 0xdc00) { - c = 0x10000 + ((c - 0xd800) << 10) + (c2 - 0xdc00); - m_pos++; - } - } - buf_len += c < 0x80 ? 1 : c < 0x800 ? 2 : c < 0x10000 ? 3 : 4; - } - - // allocate buffer - buf = new Uint8Array(buf_len); - - // convert - for (i = 0, m_pos = 0; i < buf_len; m_pos++) { - c = str.charCodeAt(m_pos); - if ((c & 0xfc00) === 0xd800 && (m_pos + 1 < str_len)) { - c2 = str.charCodeAt(m_pos + 1); - if ((c2 & 0xfc00) === 0xdc00) { - c = 0x10000 + ((c - 0xd800) << 10) + (c2 - 0xdc00); - m_pos++; - } - } - if (c < 0x80) { - /* one byte */ - buf[i++] = c; - } else if (c < 0x800) { - /* two bytes */ - buf[i++] = 0xC0 | (c >>> 6); - buf[i++] = 0x80 | (c & 0x3f); - } else if (c < 0x10000) { - /* three bytes */ - buf[i++] = 0xE0 | (c >>> 12); - buf[i++] = 0x80 | (c >>> 6 & 0x3f); - buf[i++] = 0x80 | (c & 0x3f); - } else { - /* four bytes */ - buf[i++] = 0xf0 | (c >>> 18); - buf[i++] = 0x80 | (c >>> 12 & 0x3f); - buf[i++] = 0x80 | (c >>> 6 & 0x3f); - buf[i++] = 0x80 | (c & 0x3f); - } - } - - return buf; - }; - - // Helper - const buf2binstring$1 = (buf, len) => { - // On Chrome, the arguments in a function call that are allowed is `65534`. - // If the length of the buffer is smaller than that, we can use this optimization, - // otherwise we will take a slower path. - if (len < 65534) { - if (buf.subarray && STR_APPLY_UIA_OK$1) { - return String.fromCharCode.apply(null, buf.length === len ? buf : buf.subarray(0, len)); - } - } - - let result = ''; - for (let i = 0; i < len; i++) { - result += String.fromCharCode(buf[i]); - } - return result; - }; - - - // convert array to string - var buf2string$1 = (buf, max) => { - const len = max || buf.length; - - if (typeof TextDecoder === 'function' && TextDecoder.prototype.decode) { - return new TextDecoder().decode(buf.subarray(0, max)); - } - - let i, out; - - // Reserve max possible length (2 words per char) - // NB: by unknown reasons, Array is significantly faster for - // String.fromCharCode.apply than Uint16Array. - const utf16buf = new Array(len * 2); - - for (out = 0, i = 0; i < len;) { - let c = buf[i++]; - // quick process ascii - if (c < 0x80) { utf16buf[out++] = c; continue; } - - let c_len = _utf8len$1[c]; - // skip 5 & 6 byte codes - if (c_len > 4) { utf16buf[out++] = 0xfffd; i += c_len - 1; continue; } - - // apply mask on first byte - c &= c_len === 2 ? 0x1f : c_len === 3 ? 0x0f : 0x07; - // join the rest - while (c_len > 1 && i < len) { - c = (c << 6) | (buf[i++] & 0x3f); - c_len--; - } - - // terminated by end of string? - if (c_len > 1) { utf16buf[out++] = 0xfffd; continue; } - - if (c < 0x10000) { - utf16buf[out++] = c; - } else { - c -= 0x10000; - utf16buf[out++] = 0xd800 | ((c >> 10) & 0x3ff); - utf16buf[out++] = 0xdc00 | (c & 0x3ff); - } - } - - return buf2binstring$1(utf16buf, out); - }; - - - // Calculate max possible position in utf8 buffer, - // that will not break sequence. If that's not possible - // - (very small limits) return max size as is. - // - // buf[] - utf8 bytes array - // max - length limit (mandatory); - var utf8border$1 = (buf, max) => { - - max = max || buf.length; - if (max > buf.length) { max = buf.length; } - - // go back from last position, until start of sequence found - let pos = max - 1; - while (pos >= 0 && (buf[pos] & 0xC0) === 0x80) { pos--; } - - // Very small and broken sequence, - // return max, because we should return something anyway. - if (pos < 0) { return max; } - - // If we came to start of buffer - that means buffer is too small, - // return max too. - if (pos === 0) { return max; } - - return (pos + _utf8len$1[buf[pos]] > max) ? pos : max; - }; - - var strings$1 = { - string2buf: string2buf$1, - buf2string: buf2string$1, - utf8border: utf8border$1 - }; - - // (C) 1995-2013 Jean-loup Gailly and Mark Adler - // (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin - // - // This software is provided 'as-is', without any express or implied - // warranty. In no event will the authors be held liable for any damages - // arising from the use of this software. - // - // Permission is granted to anyone to use this software for any purpose, - // including commercial applications, and to alter it and redistribute it - // freely, subject to the following restrictions: - // - // 1. The origin of this software must not be misrepresented; you must not - // claim that you wrote the original software. If you use this software - // in a product, an acknowledgment in the product documentation would be - // appreciated but is not required. - // 2. Altered source versions must be plainly marked as such, and must not be - // misrepresented as being the original software. - // 3. This notice may not be removed or altered from any source distribution. - - function ZStream$1() { - /* next input byte */ - this.input = null; // JS specific, because we have no pointers - this.next_in = 0; - /* number of bytes available at input */ - this.avail_in = 0; - /* total number of input bytes read so far */ - this.total_in = 0; - /* next output byte should be put there */ - this.output = null; // JS specific, because we have no pointers - this.next_out = 0; - /* remaining free space at output */ - this.avail_out = 0; - /* total number of bytes output so far */ - this.total_out = 0; - /* last error message, NULL if no error */ - this.msg = ''/*Z_NULL*/; - /* not visible by applications */ - this.state = null; - /* best guess about the data type: binary or text */ - this.data_type = 2/*Z_UNKNOWN*/; - /* adler32 value of the uncompressed data */ - this.adler = 0; - } - - var zstream$1 = ZStream$1; - - const toString$1 = Object.prototype.toString; - - /* Public constants ==========================================================*/ - /* ===========================================================================*/ - - const { - Z_NO_FLUSH: Z_NO_FLUSH$1, Z_SYNC_FLUSH, Z_FULL_FLUSH, Z_FINISH: Z_FINISH$2, - Z_OK: Z_OK$2, Z_STREAM_END: Z_STREAM_END$2, - Z_DEFAULT_COMPRESSION, - Z_DEFAULT_STRATEGY, - Z_DEFLATED: Z_DEFLATED$1 - } = constants$2$1; - - /* ===========================================================================*/ - - - /** - * class Deflate - * - * Generic JS-style wrapper for zlib calls. If you don't need - * streaming behaviour - use more simple functions: [[deflate]], - * [[deflateRaw]] and [[gzip]]. - **/ - - /* internal - * Deflate.chunks -> Array - * - * Chunks of output data, if [[Deflate#onData]] not overridden. - **/ - - /** - * Deflate.result -> Uint8Array - * - * Compressed result, generated by default [[Deflate#onData]] - * and [[Deflate#onEnd]] handlers. Filled after you push last chunk - * (call [[Deflate#push]] with `Z_FINISH` / `true` param). - **/ - - /** - * Deflate.err -> Number - * - * Error code after deflate finished. 0 (Z_OK) on success. - * You will not need it in real life, because deflate errors - * are possible only on wrong options or bad `onData` / `onEnd` - * custom handlers. - **/ - - /** - * Deflate.msg -> String - * - * Error message, if [[Deflate.err]] != 0 - **/ - - - /** - * new Deflate(options) - * - options (Object): zlib deflate options. - * - * Creates new deflator instance with specified params. Throws exception - * on bad params. Supported options: - * - * - `level` - * - `windowBits` - * - `memLevel` - * - `strategy` - * - `dictionary` - * - * [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced) - * for more information on these. - * - * Additional options, for internal needs: - * - * - `chunkSize` - size of generated data chunks (16K by default) - * - `raw` (Boolean) - do raw deflate - * - `gzip` (Boolean) - create gzip wrapper - * - `header` (Object) - custom header for gzip - * - `text` (Boolean) - true if compressed data believed to be text - * - `time` (Number) - modification time, unix timestamp - * - `os` (Number) - operation system code - * - `extra` (Array) - array of bytes with extra data (max 65536) - * - `name` (String) - file name (binary string) - * - `comment` (String) - comment (binary string) - * - `hcrc` (Boolean) - true if header crc should be added - * - * ##### Example: - * - * ```javascript - * const pako = require('pako') - * , chunk1 = new Uint8Array([1,2,3,4,5,6,7,8,9]) - * , chunk2 = new Uint8Array([10,11,12,13,14,15,16,17,18,19]); - * - * const deflate = new pako.Deflate({ level: 3}); - * - * deflate.push(chunk1, false); - * deflate.push(chunk2, true); // true -> last chunk - * - * if (deflate.err) { throw new Error(deflate.err); } - * - * console.log(deflate.result); - * ``` - **/ - function Deflate$1(options) { - this.options = common$1.assign({ - level: Z_DEFAULT_COMPRESSION, - method: Z_DEFLATED$1, - chunkSize: 16384, - windowBits: 15, - memLevel: 8, - strategy: Z_DEFAULT_STRATEGY - }, options || {}); - - let opt = this.options; - - if (opt.raw && (opt.windowBits > 0)) { - opt.windowBits = -opt.windowBits; - } - - else if (opt.gzip && (opt.windowBits > 0) && (opt.windowBits < 16)) { - opt.windowBits += 16; - } - - this.err = 0; // error code, if happens (0 = Z_OK) - this.msg = ''; // error message - this.ended = false; // used to avoid multiple onEnd() calls - this.chunks = []; // chunks of compressed data - - this.strm = new zstream$1(); - this.strm.avail_out = 0; - - let status = deflate_1$2.deflateInit2( - this.strm, - opt.level, - opt.method, - opt.windowBits, - opt.memLevel, - opt.strategy - ); - - if (status !== Z_OK$2) { - throw new Error(messages$1[status]); - } - - if (opt.header) { - deflate_1$2.deflateSetHeader(this.strm, opt.header); - } - - if (opt.dictionary) { - let dict; - // Convert data if needed - if (typeof opt.dictionary === 'string') { - // If we need to compress text, change encoding to utf8. - dict = strings$1.string2buf(opt.dictionary); - } else if (toString$1.call(opt.dictionary) === '[object ArrayBuffer]') { - dict = new Uint8Array(opt.dictionary); - } else { - dict = opt.dictionary; - } - - status = deflate_1$2.deflateSetDictionary(this.strm, dict); - - if (status !== Z_OK$2) { - throw new Error(messages$1[status]); - } - - this._dict_set = true; - } - } - - /** - * Deflate#push(data[, flush_mode]) -> Boolean - * - data (Uint8Array|ArrayBuffer|String): input data. Strings will be - * converted to utf8 byte sequence. - * - flush_mode (Number|Boolean): 0..6 for corresponding Z_NO_FLUSH..Z_TREE modes. - * See constants. Skipped or `false` means Z_NO_FLUSH, `true` means Z_FINISH. - * - * Sends input data to deflate pipe, generating [[Deflate#onData]] calls with - * new compressed chunks. Returns `true` on success. The last data block must - * have `flush_mode` Z_FINISH (or `true`). That will flush internal pending - * buffers and call [[Deflate#onEnd]]. - * - * On fail call [[Deflate#onEnd]] with error code and return false. - * - * ##### Example - * - * ```javascript - * push(chunk, false); // push one of data chunks - * ... - * push(chunk, true); // push last chunk - * ``` - **/ - Deflate$1.prototype.push = function (data, flush_mode) { - const strm = this.strm; - const chunkSize = this.options.chunkSize; - let status, _flush_mode; - - if (this.ended) { return false; } - - if (flush_mode === ~~flush_mode) _flush_mode = flush_mode; - else _flush_mode = flush_mode === true ? Z_FINISH$2 : Z_NO_FLUSH$1; - - // Convert data if needed - if (typeof data === 'string') { - // If we need to compress text, change encoding to utf8. - strm.input = strings$1.string2buf(data); - } else if (toString$1.call(data) === '[object ArrayBuffer]') { - strm.input = new Uint8Array(data); - } else { - strm.input = data; - } - - strm.next_in = 0; - strm.avail_in = strm.input.length; - - for (;;) { - if (strm.avail_out === 0) { - strm.output = new Uint8Array(chunkSize); - strm.next_out = 0; - strm.avail_out = chunkSize; - } - - // Make sure avail_out > 6 to avoid repeating markers - if ((_flush_mode === Z_SYNC_FLUSH || _flush_mode === Z_FULL_FLUSH) && strm.avail_out <= 6) { - this.onData(strm.output.subarray(0, strm.next_out)); - strm.avail_out = 0; - continue; - } - - status = deflate_1$2.deflate(strm, _flush_mode); - - // Ended => flush and finish - if (status === Z_STREAM_END$2) { - if (strm.next_out > 0) { - this.onData(strm.output.subarray(0, strm.next_out)); - } - status = deflate_1$2.deflateEnd(this.strm); - this.onEnd(status); - this.ended = true; - return status === Z_OK$2; - } - - // Flush if out buffer full - if (strm.avail_out === 0) { - this.onData(strm.output); - continue; - } - - // Flush if requested and has data - if (_flush_mode > 0 && strm.next_out > 0) { - this.onData(strm.output.subarray(0, strm.next_out)); - strm.avail_out = 0; - continue; - } - - if (strm.avail_in === 0) break; - } - - return true; - }; - - - /** - * Deflate#onData(chunk) -> Void - * - chunk (Uint8Array): output data. - * - * By default, stores data blocks in `chunks[]` property and glue - * those in `onEnd`. Override this handler, if you need another behaviour. - **/ - Deflate$1.prototype.onData = function (chunk) { - this.chunks.push(chunk); - }; - - - /** - * Deflate#onEnd(status) -> Void - * - status (Number): deflate status. 0 (Z_OK) on success, - * other if not. - * - * Called once after you tell deflate that the input stream is - * complete (Z_FINISH). By default - join collected chunks, - * free memory and fill `results` / `err` properties. - **/ - Deflate$1.prototype.onEnd = function (status) { - // On success - join - if (status === Z_OK$2) { - this.result = common$1.flattenChunks(this.chunks); - } - this.chunks = []; - this.err = status; - this.msg = this.strm.msg; - }; - - - /** - * deflate(data[, options]) -> Uint8Array - * - data (Uint8Array|ArrayBuffer|String): input data to compress. - * - options (Object): zlib deflate options. - * - * Compress `data` with deflate algorithm and `options`. - * - * Supported options are: - * - * - level - * - windowBits - * - memLevel - * - strategy - * - dictionary - * - * [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced) - * for more information on these. - * - * Sugar (options): - * - * - `raw` (Boolean) - say that we work with raw stream, if you don't wish to specify - * negative windowBits implicitly. - * - * ##### Example: - * - * ```javascript - * const pako = require('pako') - * const data = new Uint8Array([1,2,3,4,5,6,7,8,9]); - * - * console.log(pako.deflate(data)); - * ``` - **/ - function deflate$1(input, options) { - const deflator = new Deflate$1(options); - - deflator.push(input, true); - - // That will never happens, if you don't cheat with options :) - if (deflator.err) { throw deflator.msg || messages$1[deflator.err]; } - - return deflator.result; - } - - - /** - * deflateRaw(data[, options]) -> Uint8Array - * - data (Uint8Array|ArrayBuffer|String): input data to compress. - * - options (Object): zlib deflate options. - * - * The same as [[deflate]], but creates raw data, without wrapper - * (header and adler32 crc). - **/ - function deflateRaw$1(input, options) { - options = options || {}; - options.raw = true; - return deflate$1(input, options); - } - - - /** - * gzip(data[, options]) -> Uint8Array - * - data (Uint8Array|ArrayBuffer|String): input data to compress. - * - options (Object): zlib deflate options. - * - * The same as [[deflate]], but create gzip wrapper instead of - * deflate one. - **/ - function gzip$1(input, options) { - options = options || {}; - options.gzip = true; - return deflate$1(input, options); - } - - - var Deflate_1$1 = Deflate$1; - var deflate_2 = deflate$1; - var deflateRaw_1$1 = deflateRaw$1; - var gzip_1$1 = gzip$1; - var constants$1 = constants$2$1; - - var deflate_1$1 = { - Deflate: Deflate_1$1, - deflate: deflate_2, - deflateRaw: deflateRaw_1$1, - gzip: gzip_1$1, - constants: constants$1 - }; - - // (C) 1995-2013 Jean-loup Gailly and Mark Adler - // (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin - // - // This software is provided 'as-is', without any express or implied - // warranty. In no event will the authors be held liable for any damages - // arising from the use of this software. - // - // Permission is granted to anyone to use this software for any purpose, - // including commercial applications, and to alter it and redistribute it - // freely, subject to the following restrictions: - // - // 1. The origin of this software must not be misrepresented; you must not - // claim that you wrote the original software. If you use this software - // in a product, an acknowledgment in the product documentation would be - // appreciated but is not required. - // 2. Altered source versions must be plainly marked as such, and must not be - // misrepresented as being the original software. - // 3. This notice may not be removed or altered from any source distribution. - - // See state defs from inflate.js - const BAD$1$1 = 16209; /* got a data error -- remain here until reset */ - const TYPE$1$1 = 16191; /* i: waiting for type bits, including last-flag bit */ - - /* - Decode literal, length, and distance codes and write out the resulting - literal and match bytes until either not enough input or output is - available, an end-of-block is encountered, or a data error is encountered. - When large enough input and output buffers are supplied to inflate(), for - example, a 16K input buffer and a 64K output buffer, more than 95% of the - inflate execution time is spent in this routine. - - Entry assumptions: - - state.mode === LEN - strm.avail_in >= 6 - strm.avail_out >= 258 - start >= strm.avail_out - state.bits < 8 - - On return, state.mode is one of: - - LEN -- ran out of enough output space or enough available input - TYPE -- reached end of block code, inflate() to interpret next block - BAD -- error in block data - - Notes: - - - The maximum input bits used by a length/distance pair is 15 bits for the - length code, 5 bits for the length extra, 15 bits for the distance code, - and 13 bits for the distance extra. This totals 48 bits, or six bytes. - Therefore if strm.avail_in >= 6, then there is enough input to avoid - checking for available input while decoding. - - - The maximum bytes that a single length/distance pair can output is 258 - bytes, which is the maximum length that can be coded. inflate_fast() - requires strm.avail_out >= 258 for each loop to avoid checking for - output space. - */ - var inffast$1 = function inflate_fast(strm, start) { - let _in; /* local strm.input */ - let last; /* have enough input while in < last */ - let _out; /* local strm.output */ - let beg; /* inflate()'s initial strm.output */ - let end; /* while out < end, enough space available */ - //#ifdef INFLATE_STRICT - let dmax; /* maximum distance from zlib header */ - //#endif - let wsize; /* window size or zero if not using window */ - let whave; /* valid bytes in the window */ - let wnext; /* window write index */ - // Use `s_window` instead `window`, avoid conflict with instrumentation tools - let s_window; /* allocated sliding window, if wsize != 0 */ - let hold; /* local strm.hold */ - let bits; /* local strm.bits */ - let lcode; /* local strm.lencode */ - let dcode; /* local strm.distcode */ - let lmask; /* mask for first level of length codes */ - let dmask; /* mask for first level of distance codes */ - let here; /* retrieved table entry */ - let op; /* code bits, operation, extra bits, or */ - /* window position, window bytes to copy */ - let len; /* match length, unused bytes */ - let dist; /* match distance */ - let from; /* where to copy match from */ - let from_source; - - - let input, output; // JS specific, because we have no pointers - - /* copy state to local variables */ - const state = strm.state; - //here = state.here; - _in = strm.next_in; - input = strm.input; - last = _in + (strm.avail_in - 5); - _out = strm.next_out; - output = strm.output; - beg = _out - (start - strm.avail_out); - end = _out + (strm.avail_out - 257); - //#ifdef INFLATE_STRICT - dmax = state.dmax; - //#endif - wsize = state.wsize; - whave = state.whave; - wnext = state.wnext; - s_window = state.window; - hold = state.hold; - bits = state.bits; - lcode = state.lencode; - dcode = state.distcode; - lmask = (1 << state.lenbits) - 1; - dmask = (1 << state.distbits) - 1; - - - /* decode literals and length/distances until end-of-block or not enough - input data or output space */ - - top: - do { - if (bits < 15) { - hold += input[_in++] << bits; - bits += 8; - hold += input[_in++] << bits; - bits += 8; - } - - here = lcode[hold & lmask]; - - dolen: - for (;;) { // Goto emulation - op = here >>> 24/*here.bits*/; - hold >>>= op; - bits -= op; - op = (here >>> 16) & 0xff/*here.op*/; - if (op === 0) { /* literal */ - //Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? - // "inflate: literal '%c'\n" : - // "inflate: literal 0x%02x\n", here.val)); - output[_out++] = here & 0xffff/*here.val*/; - } - else if (op & 16) { /* length base */ - len = here & 0xffff/*here.val*/; - op &= 15; /* number of extra bits */ - if (op) { - if (bits < op) { - hold += input[_in++] << bits; - bits += 8; - } - len += hold & ((1 << op) - 1); - hold >>>= op; - bits -= op; - } - //Tracevv((stderr, "inflate: length %u\n", len)); - if (bits < 15) { - hold += input[_in++] << bits; - bits += 8; - hold += input[_in++] << bits; - bits += 8; - } - here = dcode[hold & dmask]; - - dodist: - for (;;) { // goto emulation - op = here >>> 24/*here.bits*/; - hold >>>= op; - bits -= op; - op = (here >>> 16) & 0xff/*here.op*/; - - if (op & 16) { /* distance base */ - dist = here & 0xffff/*here.val*/; - op &= 15; /* number of extra bits */ - if (bits < op) { - hold += input[_in++] << bits; - bits += 8; - if (bits < op) { - hold += input[_in++] << bits; - bits += 8; - } - } - dist += hold & ((1 << op) - 1); - //#ifdef INFLATE_STRICT - if (dist > dmax) { - strm.msg = 'invalid distance too far back'; - state.mode = BAD$1$1; - break top; - } - //#endif - hold >>>= op; - bits -= op; - //Tracevv((stderr, "inflate: distance %u\n", dist)); - op = _out - beg; /* max distance in output */ - if (dist > op) { /* see if copy from window */ - op = dist - op; /* distance back in window */ - if (op > whave) { - if (state.sane) { - strm.msg = 'invalid distance too far back'; - state.mode = BAD$1$1; - break top; - } - - // (!) This block is disabled in zlib defaults, - // don't enable it for binary compatibility - //#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR - // if (len <= op - whave) { - // do { - // output[_out++] = 0; - // } while (--len); - // continue top; - // } - // len -= op - whave; - // do { - // output[_out++] = 0; - // } while (--op > whave); - // if (op === 0) { - // from = _out - dist; - // do { - // output[_out++] = output[from++]; - // } while (--len); - // continue top; - // } - //#endif - } - from = 0; // window index - from_source = s_window; - if (wnext === 0) { /* very common case */ - from += wsize - op; - if (op < len) { /* some from window */ - len -= op; - do { - output[_out++] = s_window[from++]; - } while (--op); - from = _out - dist; /* rest from output */ - from_source = output; - } - } - else if (wnext < op) { /* wrap around window */ - from += wsize + wnext - op; - op -= wnext; - if (op < len) { /* some from end of window */ - len -= op; - do { - output[_out++] = s_window[from++]; - } while (--op); - from = 0; - if (wnext < len) { /* some from start of window */ - op = wnext; - len -= op; - do { - output[_out++] = s_window[from++]; - } while (--op); - from = _out - dist; /* rest from output */ - from_source = output; - } - } - } - else { /* contiguous in window */ - from += wnext - op; - if (op < len) { /* some from window */ - len -= op; - do { - output[_out++] = s_window[from++]; - } while (--op); - from = _out - dist; /* rest from output */ - from_source = output; - } - } - while (len > 2) { - output[_out++] = from_source[from++]; - output[_out++] = from_source[from++]; - output[_out++] = from_source[from++]; - len -= 3; - } - if (len) { - output[_out++] = from_source[from++]; - if (len > 1) { - output[_out++] = from_source[from++]; - } - } - } - else { - from = _out - dist; /* copy direct from output */ - do { /* minimum length is three */ - output[_out++] = output[from++]; - output[_out++] = output[from++]; - output[_out++] = output[from++]; - len -= 3; - } while (len > 2); - if (len) { - output[_out++] = output[from++]; - if (len > 1) { - output[_out++] = output[from++]; - } - } - } - } - else if ((op & 64) === 0) { /* 2nd level distance code */ - here = dcode[(here & 0xffff)/*here.val*/ + (hold & ((1 << op) - 1))]; - continue dodist; - } - else { - strm.msg = 'invalid distance code'; - state.mode = BAD$1$1; - break top; - } - - break; // need to emulate goto via "continue" - } - } - else if ((op & 64) === 0) { /* 2nd level length code */ - here = lcode[(here & 0xffff)/*here.val*/ + (hold & ((1 << op) - 1))]; - continue dolen; - } - else if (op & 32) { /* end-of-block */ - //Tracevv((stderr, "inflate: end of block\n")); - state.mode = TYPE$1$1; - break top; - } - else { - strm.msg = 'invalid literal/length code'; - state.mode = BAD$1$1; - break top; - } - - break; // need to emulate goto via "continue" - } - } while (_in < last && _out < end); - - /* return unused bytes (on entry, bits < 8, so in won't go too far back) */ - len = bits >> 3; - _in -= len; - bits -= len << 3; - hold &= (1 << bits) - 1; - - /* update state and return */ - strm.next_in = _in; - strm.next_out = _out; - strm.avail_in = (_in < last ? 5 + (last - _in) : 5 - (_in - last)); - strm.avail_out = (_out < end ? 257 + (end - _out) : 257 - (_out - end)); - state.hold = hold; - state.bits = bits; - return; - }; - - // (C) 1995-2013 Jean-loup Gailly and Mark Adler - // (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin - // - // This software is provided 'as-is', without any express or implied - // warranty. In no event will the authors be held liable for any damages - // arising from the use of this software. - // - // Permission is granted to anyone to use this software for any purpose, - // including commercial applications, and to alter it and redistribute it - // freely, subject to the following restrictions: - // - // 1. The origin of this software must not be misrepresented; you must not - // claim that you wrote the original software. If you use this software - // in a product, an acknowledgment in the product documentation would be - // appreciated but is not required. - // 2. Altered source versions must be plainly marked as such, and must not be - // misrepresented as being the original software. - // 3. This notice may not be removed or altered from any source distribution. - - const MAXBITS$1 = 15; - const ENOUGH_LENS$1$1 = 852; - const ENOUGH_DISTS$1$1 = 592; - //const ENOUGH = (ENOUGH_LENS+ENOUGH_DISTS); - - const CODES$1$1 = 0; - const LENS$1$1 = 1; - const DISTS$1$1 = 2; - - const lbase$1 = new Uint16Array([ /* Length codes 257..285 base */ - 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, - 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0 - ]); - - const lext$1 = new Uint8Array([ /* Length codes 257..285 extra */ - 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, - 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 72, 78 - ]); - - const dbase$1 = new Uint16Array([ /* Distance codes 0..29 base */ - 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, - 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, - 8193, 12289, 16385, 24577, 0, 0 - ]); - - const dext$1 = new Uint8Array([ /* Distance codes 0..29 extra */ - 16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, - 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, - 28, 28, 29, 29, 64, 64 - ]); - - const inflate_table$1 = (type, lens, lens_index, codes, table, table_index, work, opts) => - { - const bits = opts.bits; - //here = opts.here; /* table entry for duplication */ - - let len = 0; /* a code's length in bits */ - let sym = 0; /* index of code symbols */ - let min = 0, max = 0; /* minimum and maximum code lengths */ - let root = 0; /* number of index bits for root table */ - let curr = 0; /* number of index bits for current table */ - let drop = 0; /* code bits to drop for sub-table */ - let left = 0; /* number of prefix codes available */ - let used = 0; /* code entries in table used */ - let huff = 0; /* Huffman code */ - let incr; /* for incrementing code, index */ - let fill; /* index for replicating entries */ - let low; /* low bits for current root entry */ - let mask; /* mask for low root bits */ - let next; /* next available space in table */ - let base = null; /* base value table to use */ - // let shoextra; /* extra bits table to use */ - let match; /* use base and extra for symbol >= match */ - const count = new Uint16Array(MAXBITS$1 + 1); //[MAXBITS+1]; /* number of codes of each length */ - const offs = new Uint16Array(MAXBITS$1 + 1); //[MAXBITS+1]; /* offsets in table for each length */ - let extra = null; - - let here_bits, here_op, here_val; - - /* - Process a set of code lengths to create a canonical Huffman code. The - code lengths are lens[0..codes-1]. Each length corresponds to the - symbols 0..codes-1. The Huffman code is generated by first sorting the - symbols by length from short to long, and retaining the symbol order - for codes with equal lengths. Then the code starts with all zero bits - for the first code of the shortest length, and the codes are integer - increments for the same length, and zeros are appended as the length - increases. For the deflate format, these bits are stored backwards - from their more natural integer increment ordering, and so when the - decoding tables are built in the large loop below, the integer codes - are incremented backwards. - - This routine assumes, but does not check, that all of the entries in - lens[] are in the range 0..MAXBITS. The caller must assure this. - 1..MAXBITS is interpreted as that code length. zero means that that - symbol does not occur in this code. - - The codes are sorted by computing a count of codes for each length, - creating from that a table of starting indices for each length in the - sorted table, and then entering the symbols in order in the sorted - table. The sorted table is work[], with that space being provided by - the caller. - - The length counts are used for other purposes as well, i.e. finding - the minimum and maximum length codes, determining if there are any - codes at all, checking for a valid set of lengths, and looking ahead - at length counts to determine sub-table sizes when building the - decoding tables. - */ - - /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */ - for (len = 0; len <= MAXBITS$1; len++) { - count[len] = 0; - } - for (sym = 0; sym < codes; sym++) { - count[lens[lens_index + sym]]++; - } - - /* bound code lengths, force root to be within code lengths */ - root = bits; - for (max = MAXBITS$1; max >= 1; max--) { - if (count[max] !== 0) { break; } - } - if (root > max) { - root = max; - } - if (max === 0) { /* no symbols to code at all */ - //table.op[opts.table_index] = 64; //here.op = (var char)64; /* invalid code marker */ - //table.bits[opts.table_index] = 1; //here.bits = (var char)1; - //table.val[opts.table_index++] = 0; //here.val = (var short)0; - table[table_index++] = (1 << 24) | (64 << 16) | 0; - - - //table.op[opts.table_index] = 64; - //table.bits[opts.table_index] = 1; - //table.val[opts.table_index++] = 0; - table[table_index++] = (1 << 24) | (64 << 16) | 0; - - opts.bits = 1; - return 0; /* no symbols, but wait for decoding to report error */ - } - for (min = 1; min < max; min++) { - if (count[min] !== 0) { break; } - } - if (root < min) { - root = min; - } - - /* check for an over-subscribed or incomplete set of lengths */ - left = 1; - for (len = 1; len <= MAXBITS$1; len++) { - left <<= 1; - left -= count[len]; - if (left < 0) { - return -1; - } /* over-subscribed */ - } - if (left > 0 && (type === CODES$1$1 || max !== 1)) { - return -1; /* incomplete set */ - } - - /* generate offsets into symbol table for each length for sorting */ - offs[1] = 0; - for (len = 1; len < MAXBITS$1; len++) { - offs[len + 1] = offs[len] + count[len]; - } - - /* sort symbols by length, by symbol order within each length */ - for (sym = 0; sym < codes; sym++) { - if (lens[lens_index + sym] !== 0) { - work[offs[lens[lens_index + sym]]++] = sym; - } - } - - /* - Create and fill in decoding tables. In this loop, the table being - filled is at next and has curr index bits. The code being used is huff - with length len. That code is converted to an index by dropping drop - bits off of the bottom. For codes where len is less than drop + curr, - those top drop + curr - len bits are incremented through all values to - fill the table with replicated entries. - - root is the number of index bits for the root table. When len exceeds - root, sub-tables are created pointed to by the root entry with an index - of the low root bits of huff. This is saved in low to check for when a - new sub-table should be started. drop is zero when the root table is - being filled, and drop is root when sub-tables are being filled. - - When a new sub-table is needed, it is necessary to look ahead in the - code lengths to determine what size sub-table is needed. The length - counts are used for this, and so count[] is decremented as codes are - entered in the tables. - - used keeps track of how many table entries have been allocated from the - provided *table space. It is checked for LENS and DIST tables against - the constants ENOUGH_LENS and ENOUGH_DISTS to guard against changes in - the initial root table size constants. See the comments in inftrees.h - for more information. - - sym increments through all symbols, and the loop terminates when - all codes of length max, i.e. all codes, have been processed. This - routine permits incomplete codes, so another loop after this one fills - in the rest of the decoding tables with invalid code markers. - */ - - /* set up for code type */ - // poor man optimization - use if-else instead of switch, - // to avoid deopts in old v8 - if (type === CODES$1$1) { - base = extra = work; /* dummy value--not used */ - match = 20; - - } else if (type === LENS$1$1) { - base = lbase$1; - extra = lext$1; - match = 257; - - } else { /* DISTS */ - base = dbase$1; - extra = dext$1; - match = 0; - } - - /* initialize opts for loop */ - huff = 0; /* starting code */ - sym = 0; /* starting code symbol */ - len = min; /* starting code length */ - next = table_index; /* current table to fill in */ - curr = root; /* current table index bits */ - drop = 0; /* current bits to drop from code for index */ - low = -1; /* trigger new sub-table when len > root */ - used = 1 << root; /* use root table entries */ - mask = used - 1; /* mask for comparing low */ - - /* check available table space */ - if ((type === LENS$1$1 && used > ENOUGH_LENS$1$1) || - (type === DISTS$1$1 && used > ENOUGH_DISTS$1$1)) { - return 1; - } - - /* process all codes and make table entries */ - for (;;) { - /* create table entry */ - here_bits = len - drop; - if (work[sym] + 1 < match) { - here_op = 0; - here_val = work[sym]; - } - else if (work[sym] >= match) { - here_op = extra[work[sym] - match]; - here_val = base[work[sym] - match]; - } - else { - here_op = 32 + 64; /* end of block */ - here_val = 0; - } - - /* replicate for those indices with low len bits equal to huff */ - incr = 1 << (len - drop); - fill = 1 << curr; - min = fill; /* save offset to next table */ - do { - fill -= incr; - table[next + (huff >> drop) + fill] = (here_bits << 24) | (here_op << 16) | here_val |0; - } while (fill !== 0); - - /* backwards increment the len-bit code huff */ - incr = 1 << (len - 1); - while (huff & incr) { - incr >>= 1; - } - if (incr !== 0) { - huff &= incr - 1; - huff += incr; - } else { - huff = 0; - } - - /* go to next symbol, update count, len */ - sym++; - if (--count[len] === 0) { - if (len === max) { break; } - len = lens[lens_index + work[sym]]; - } - - /* create new sub-table if needed */ - if (len > root && (huff & mask) !== low) { - /* if first time, transition to sub-tables */ - if (drop === 0) { - drop = root; - } - - /* increment past last table */ - next += min; /* here min is 1 << curr */ - - /* determine length of next table */ - curr = len - drop; - left = 1 << curr; - while (curr + drop < max) { - left -= count[curr + drop]; - if (left <= 0) { break; } - curr++; - left <<= 1; - } - - /* check for enough space */ - used += 1 << curr; - if ((type === LENS$1$1 && used > ENOUGH_LENS$1$1) || - (type === DISTS$1$1 && used > ENOUGH_DISTS$1$1)) { - return 1; - } - - /* point entry in root table to sub-table */ - low = huff & mask; - /*table.op[low] = curr; - table.bits[low] = root; - table.val[low] = next - opts.table_index;*/ - table[low] = (root << 24) | (curr << 16) | (next - table_index) |0; - } - } - - /* fill in remaining table entry if code is incomplete (guaranteed to have - at most one remaining entry, since if the code is incomplete, the - maximum code length that was allowed to get this far is one bit) */ - if (huff !== 0) { - //table.op[next + huff] = 64; /* invalid code marker */ - //table.bits[next + huff] = len - drop; - //table.val[next + huff] = 0; - table[next + huff] = ((len - drop) << 24) | (64 << 16) |0; - } - - /* set return parameters */ - //opts.table_index += used; - opts.bits = root; - return 0; - }; - - - var inftrees$1 = inflate_table$1; - - // (C) 1995-2013 Jean-loup Gailly and Mark Adler - // (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin - // - // This software is provided 'as-is', without any express or implied - // warranty. In no event will the authors be held liable for any damages - // arising from the use of this software. - // - // Permission is granted to anyone to use this software for any purpose, - // including commercial applications, and to alter it and redistribute it - // freely, subject to the following restrictions: - // - // 1. The origin of this software must not be misrepresented; you must not - // claim that you wrote the original software. If you use this software - // in a product, an acknowledgment in the product documentation would be - // appreciated but is not required. - // 2. Altered source versions must be plainly marked as such, and must not be - // misrepresented as being the original software. - // 3. This notice may not be removed or altered from any source distribution. - - - - - - - const CODES$2 = 0; - const LENS$2 = 1; - const DISTS$2 = 2; - - /* Public constants ==========================================================*/ - /* ===========================================================================*/ - - const { - Z_FINISH: Z_FINISH$1$1, Z_BLOCK: Z_BLOCK$2, Z_TREES: Z_TREES$1, - Z_OK: Z_OK$1$1, Z_STREAM_END: Z_STREAM_END$1$1, Z_NEED_DICT: Z_NEED_DICT$1$1, Z_STREAM_ERROR: Z_STREAM_ERROR$1$1, Z_DATA_ERROR: Z_DATA_ERROR$1$1, Z_MEM_ERROR: Z_MEM_ERROR$1$1, Z_BUF_ERROR: Z_BUF_ERROR$2, - Z_DEFLATED: Z_DEFLATED$3 - } = constants$2$1; - - - /* STATES ====================================================================*/ - /* ===========================================================================*/ - - - const HEAD$1 = 16180; /* i: waiting for magic header */ - const FLAGS$1 = 16181; /* i: waiting for method and flags (gzip) */ - const TIME$1 = 16182; /* i: waiting for modification time (gzip) */ - const OS$1 = 16183; /* i: waiting for extra flags and operating system (gzip) */ - const EXLEN$1 = 16184; /* i: waiting for extra length (gzip) */ - const EXTRA$1 = 16185; /* i: waiting for extra bytes (gzip) */ - const NAME$1 = 16186; /* i: waiting for end of file name (gzip) */ - const COMMENT$1 = 16187; /* i: waiting for end of comment (gzip) */ - const HCRC$1 = 16188; /* i: waiting for header crc (gzip) */ - const DICTID$1 = 16189; /* i: waiting for dictionary check value */ - const DICT$1 = 16190; /* waiting for inflateSetDictionary() call */ - const TYPE$2 = 16191; /* i: waiting for type bits, including last-flag bit */ - const TYPEDO$1 = 16192; /* i: same, but skip check to exit inflate on new block */ - const STORED$1 = 16193; /* i: waiting for stored size (length and complement) */ - const COPY_$1 = 16194; /* i/o: same as COPY below, but only first time in */ - const COPY$1 = 16195; /* i/o: waiting for input or output to copy stored block */ - const TABLE$1 = 16196; /* i: waiting for dynamic block table lengths */ - const LENLENS$1 = 16197; /* i: waiting for code length code lengths */ - const CODELENS$1 = 16198; /* i: waiting for length/lit and distance code lengths */ - const LEN_$1 = 16199; /* i: same as LEN below, but only first time in */ - const LEN$1 = 16200; /* i: waiting for length/lit/eob code */ - const LENEXT$1 = 16201; /* i: waiting for length extra bits */ - const DIST$1 = 16202; /* i: waiting for distance code */ - const DISTEXT$1 = 16203; /* i: waiting for distance extra bits */ - const MATCH$1 = 16204; /* o: waiting for output space to copy string */ - const LIT$1 = 16205; /* o: waiting for output space to write literal */ - const CHECK$1 = 16206; /* i: waiting for 32-bit check value */ - const LENGTH$1 = 16207; /* i: waiting for 32-bit length (gzip) */ - const DONE$1 = 16208; /* finished check, done -- remain here until reset */ - const BAD$2 = 16209; /* got a data error -- remain here until reset */ - const MEM$1 = 16210; /* got an inflate() memory error -- remain here until reset */ - const SYNC$1 = 16211; /* looking for synchronization bytes to restart inflate() */ - - /* ===========================================================================*/ - - - - const ENOUGH_LENS$2 = 852; - const ENOUGH_DISTS$2 = 592; - //const ENOUGH = (ENOUGH_LENS+ENOUGH_DISTS); - - const MAX_WBITS$2 = 15; - /* 32K LZ77 window */ - const DEF_WBITS$1 = MAX_WBITS$2; - - - const zswap32$1 = (q) => { - - return (((q >>> 24) & 0xff) + - ((q >>> 8) & 0xff00) + - ((q & 0xff00) << 8) + - ((q & 0xff) << 24)); - }; - - - function InflateState$1() { - this.strm = null; /* pointer back to this zlib stream */ - this.mode = 0; /* current inflate mode */ - this.last = false; /* true if processing last block */ - this.wrap = 0; /* bit 0 true for zlib, bit 1 true for gzip, - bit 2 true to validate check value */ - this.havedict = false; /* true if dictionary provided */ - this.flags = 0; /* gzip header method and flags (0 if zlib), or - -1 if raw or no header yet */ - this.dmax = 0; /* zlib header max distance (INFLATE_STRICT) */ - this.check = 0; /* protected copy of check value */ - this.total = 0; /* protected copy of output count */ - // TODO: may be {} - this.head = null; /* where to save gzip header information */ - - /* sliding window */ - this.wbits = 0; /* log base 2 of requested window size */ - this.wsize = 0; /* window size or zero if not using window */ - this.whave = 0; /* valid bytes in the window */ - this.wnext = 0; /* window write index */ - this.window = null; /* allocated sliding window, if needed */ - - /* bit accumulator */ - this.hold = 0; /* input bit accumulator */ - this.bits = 0; /* number of bits in "in" */ - - /* for string and stored block copying */ - this.length = 0; /* literal or length of data to copy */ - this.offset = 0; /* distance back to copy string from */ - - /* for table and code decoding */ - this.extra = 0; /* extra bits needed */ - - /* fixed and dynamic code tables */ - this.lencode = null; /* starting table for length/literal codes */ - this.distcode = null; /* starting table for distance codes */ - this.lenbits = 0; /* index bits for lencode */ - this.distbits = 0; /* index bits for distcode */ - - /* dynamic table building */ - this.ncode = 0; /* number of code length code lengths */ - this.nlen = 0; /* number of length code lengths */ - this.ndist = 0; /* number of distance code lengths */ - this.have = 0; /* number of code lengths in lens[] */ - this.next = null; /* next available space in codes[] */ - - this.lens = new Uint16Array(320); /* temporary storage for code lengths */ - this.work = new Uint16Array(288); /* work area for code table building */ - - /* - because we don't have pointers in js, we use lencode and distcode directly - as buffers so we don't need codes - */ - //this.codes = new Int32Array(ENOUGH); /* space for code tables */ - this.lendyn = null; /* dynamic table for length/literal codes (JS specific) */ - this.distdyn = null; /* dynamic table for distance codes (JS specific) */ - this.sane = 0; /* if false, allow invalid distance too far */ - this.back = 0; /* bits back of last unprocessed length/lit */ - this.was = 0; /* initial length of match */ - } - - - const inflateStateCheck = (strm) => { - - if (!strm) { - return 1; - } - const state = strm.state; - if (!state || state.strm !== strm || - state.mode < HEAD$1 || state.mode > SYNC$1) { - return 1; - } - return 0; - }; - - - const inflateResetKeep$1 = (strm) => { - - if (inflateStateCheck(strm)) { return Z_STREAM_ERROR$1$1; } - const state = strm.state; - strm.total_in = strm.total_out = state.total = 0; - strm.msg = ''; /*Z_NULL*/ - if (state.wrap) { /* to support ill-conceived Java test suite */ - strm.adler = state.wrap & 1; - } - state.mode = HEAD$1; - state.last = 0; - state.havedict = 0; - state.flags = -1; - state.dmax = 32768; - state.head = null/*Z_NULL*/; - state.hold = 0; - state.bits = 0; - //state.lencode = state.distcode = state.next = state.codes; - state.lencode = state.lendyn = new Int32Array(ENOUGH_LENS$2); - state.distcode = state.distdyn = new Int32Array(ENOUGH_DISTS$2); - - state.sane = 1; - state.back = -1; - //Tracev((stderr, "inflate: reset\n")); - return Z_OK$1$1; - }; - - - const inflateReset$1 = (strm) => { - - if (inflateStateCheck(strm)) { return Z_STREAM_ERROR$1$1; } - const state = strm.state; - state.wsize = 0; - state.whave = 0; - state.wnext = 0; - return inflateResetKeep$1(strm); - - }; - - - const inflateReset2$1 = (strm, windowBits) => { - let wrap; - - /* get the state */ - if (inflateStateCheck(strm)) { return Z_STREAM_ERROR$1$1; } - const state = strm.state; - - /* extract wrap request from windowBits parameter */ - if (windowBits < 0) { - wrap = 0; - windowBits = -windowBits; - } - else { - wrap = (windowBits >> 4) + 5; - if (windowBits < 48) { - windowBits &= 15; - } - } - - /* set number of window bits, free window if different */ - if (windowBits && (windowBits < 8 || windowBits > 15)) { - return Z_STREAM_ERROR$1$1; - } - if (state.window !== null && state.wbits !== windowBits) { - state.window = null; - } - - /* update state and reset the rest of it */ - state.wrap = wrap; - state.wbits = windowBits; - return inflateReset$1(strm); - }; - - - const inflateInit2$1 = (strm, windowBits) => { - - if (!strm) { return Z_STREAM_ERROR$1$1; } - //strm.msg = Z_NULL; /* in case we return an error */ - - const state = new InflateState$1(); - - //if (state === Z_NULL) return Z_MEM_ERROR; - //Tracev((stderr, "inflate: allocated\n")); - strm.state = state; - state.strm = strm; - state.window = null/*Z_NULL*/; - state.mode = HEAD$1; /* to pass state test in inflateReset2() */ - const ret = inflateReset2$1(strm, windowBits); - if (ret !== Z_OK$1$1) { - strm.state = null/*Z_NULL*/; - } - return ret; - }; - - - const inflateInit$1 = (strm) => { - - return inflateInit2$1(strm, DEF_WBITS$1); - }; - - - /* - Return state with length and distance decoding tables and index sizes set to - fixed code decoding. Normally this returns fixed tables from inffixed.h. - If BUILDFIXED is defined, then instead this routine builds the tables the - first time it's called, and returns those tables the first time and - thereafter. This reduces the size of the code by about 2K bytes, in - exchange for a little execution time. However, BUILDFIXED should not be - used for threaded applications, since the rewriting of the tables and virgin - may not be thread-safe. - */ - let virgin$1 = true; - - let lenfix$1, distfix$1; // We have no pointers in JS, so keep tables separate - - - const fixedtables$1 = (state) => { - - /* build fixed huffman tables if first call (may not be thread safe) */ - if (virgin$1) { - lenfix$1 = new Int32Array(512); - distfix$1 = new Int32Array(32); - - /* literal/length table */ - let sym = 0; - while (sym < 144) { state.lens[sym++] = 8; } - while (sym < 256) { state.lens[sym++] = 9; } - while (sym < 280) { state.lens[sym++] = 7; } - while (sym < 288) { state.lens[sym++] = 8; } - - inftrees$1(LENS$2, state.lens, 0, 288, lenfix$1, 0, state.work, { bits: 9 }); - - /* distance table */ - sym = 0; - while (sym < 32) { state.lens[sym++] = 5; } - - inftrees$1(DISTS$2, state.lens, 0, 32, distfix$1, 0, state.work, { bits: 5 }); - - /* do this just once */ - virgin$1 = false; - } - - state.lencode = lenfix$1; - state.lenbits = 9; - state.distcode = distfix$1; - state.distbits = 5; - }; - - - /* - Update the window with the last wsize (normally 32K) bytes written before - returning. If window does not exist yet, create it. This is only called - when a window is already in use, or when output has been written during this - inflate call, but the end of the deflate stream has not been reached yet. - It is also called to create a window for dictionary data when a dictionary - is loaded. - - Providing output buffers larger than 32K to inflate() should provide a speed - advantage, since only the last 32K of output is copied to the sliding window - upon return from inflate(), and since all distances after the first 32K of - output will fall in the output data, making match copies simpler and faster. - The advantage may be dependent on the size of the processor's data caches. - */ - const updatewindow$1 = (strm, src, end, copy) => { - - let dist; - const state = strm.state; - - /* if it hasn't been done already, allocate space for the window */ - if (state.window === null) { - state.wsize = 1 << state.wbits; - state.wnext = 0; - state.whave = 0; - - state.window = new Uint8Array(state.wsize); - } - - /* copy state->wsize or less output bytes into the circular window */ - if (copy >= state.wsize) { - state.window.set(src.subarray(end - state.wsize, end), 0); - state.wnext = 0; - state.whave = state.wsize; - } - else { - dist = state.wsize - state.wnext; - if (dist > copy) { - dist = copy; - } - //zmemcpy(state->window + state->wnext, end - copy, dist); - state.window.set(src.subarray(end - copy, end - copy + dist), state.wnext); - copy -= dist; - if (copy) { - //zmemcpy(state->window, end - copy, copy); - state.window.set(src.subarray(end - copy, end), 0); - state.wnext = copy; - state.whave = state.wsize; - } - else { - state.wnext += dist; - if (state.wnext === state.wsize) { state.wnext = 0; } - if (state.whave < state.wsize) { state.whave += dist; } - } - } - return 0; - }; - - - const inflate$2$1 = (strm, flush) => { - - let state; - let input, output; // input/output buffers - let next; /* next input INDEX */ - let put; /* next output INDEX */ - let have, left; /* available input and output */ - let hold; /* bit buffer */ - let bits; /* bits in bit buffer */ - let _in, _out; /* save starting available input and output */ - let copy; /* number of stored or match bytes to copy */ - let from; /* where to copy match bytes from */ - let from_source; - let here = 0; /* current decoding table entry */ - let here_bits, here_op, here_val; // paked "here" denormalized (JS specific) - //let last; /* parent table entry */ - let last_bits, last_op, last_val; // paked "last" denormalized (JS specific) - let len; /* length to copy for repeats, bits to drop */ - let ret; /* return code */ - const hbuf = new Uint8Array(4); /* buffer for gzip header crc calculation */ - let opts; - - let n; // temporary variable for NEED_BITS - - const order = /* permutation of code lengths */ - new Uint8Array([ 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 ]); - - - if (inflateStateCheck(strm) || !strm.output || - (!strm.input && strm.avail_in !== 0)) { - return Z_STREAM_ERROR$1$1; - } - - state = strm.state; - if (state.mode === TYPE$2) { state.mode = TYPEDO$1; } /* skip check */ - - - //--- LOAD() --- - put = strm.next_out; - output = strm.output; - left = strm.avail_out; - next = strm.next_in; - input = strm.input; - have = strm.avail_in; - hold = state.hold; - bits = state.bits; - //--- - - _in = have; - _out = left; - ret = Z_OK$1$1; - - inf_leave: // goto emulation - for (;;) { - switch (state.mode) { - case HEAD$1: - if (state.wrap === 0) { - state.mode = TYPEDO$1; - break; - } - //=== NEEDBITS(16); - while (bits < 16) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - if ((state.wrap & 2) && hold === 0x8b1f) { /* gzip header */ - if (state.wbits === 0) { - state.wbits = 15; - } - state.check = 0/*crc32(0L, Z_NULL, 0)*/; - //=== CRC2(state.check, hold); - hbuf[0] = hold & 0xff; - hbuf[1] = (hold >>> 8) & 0xff; - state.check = crc32_1$1(state.check, hbuf, 2, 0); - //===// - - //=== INITBITS(); - hold = 0; - bits = 0; - //===// - state.mode = FLAGS$1; - break; - } - if (state.head) { - state.head.done = false; - } - if (!(state.wrap & 1) || /* check if zlib header allowed */ - (((hold & 0xff)/*BITS(8)*/ << 8) + (hold >> 8)) % 31) { - strm.msg = 'incorrect header check'; - state.mode = BAD$2; - break; - } - if ((hold & 0x0f)/*BITS(4)*/ !== Z_DEFLATED$3) { - strm.msg = 'unknown compression method'; - state.mode = BAD$2; - break; - } - //--- DROPBITS(4) ---// - hold >>>= 4; - bits -= 4; - //---// - len = (hold & 0x0f)/*BITS(4)*/ + 8; - if (state.wbits === 0) { - state.wbits = len; - } - if (len > 15 || len > state.wbits) { - strm.msg = 'invalid window size'; - state.mode = BAD$2; - break; - } - - // !!! pako patch. Force use `options.windowBits` if passed. - // Required to always use max window size by default. - state.dmax = 1 << state.wbits; - //state.dmax = 1 << len; - - state.flags = 0; /* indicate zlib header */ - //Tracev((stderr, "inflate: zlib header ok\n")); - strm.adler = state.check = 1/*adler32(0L, Z_NULL, 0)*/; - state.mode = hold & 0x200 ? DICTID$1 : TYPE$2; - //=== INITBITS(); - hold = 0; - bits = 0; - //===// - break; - case FLAGS$1: - //=== NEEDBITS(16); */ - while (bits < 16) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - state.flags = hold; - if ((state.flags & 0xff) !== Z_DEFLATED$3) { - strm.msg = 'unknown compression method'; - state.mode = BAD$2; - break; - } - if (state.flags & 0xe000) { - strm.msg = 'unknown header flags set'; - state.mode = BAD$2; - break; - } - if (state.head) { - state.head.text = ((hold >> 8) & 1); - } - if ((state.flags & 0x0200) && (state.wrap & 4)) { - //=== CRC2(state.check, hold); - hbuf[0] = hold & 0xff; - hbuf[1] = (hold >>> 8) & 0xff; - state.check = crc32_1$1(state.check, hbuf, 2, 0); - //===// - } - //=== INITBITS(); - hold = 0; - bits = 0; - //===// - state.mode = TIME$1; - /* falls through */ - case TIME$1: - //=== NEEDBITS(32); */ - while (bits < 32) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - if (state.head) { - state.head.time = hold; - } - if ((state.flags & 0x0200) && (state.wrap & 4)) { - //=== CRC4(state.check, hold) - hbuf[0] = hold & 0xff; - hbuf[1] = (hold >>> 8) & 0xff; - hbuf[2] = (hold >>> 16) & 0xff; - hbuf[3] = (hold >>> 24) & 0xff; - state.check = crc32_1$1(state.check, hbuf, 4, 0); - //=== - } - //=== INITBITS(); - hold = 0; - bits = 0; - //===// - state.mode = OS$1; - /* falls through */ - case OS$1: - //=== NEEDBITS(16); */ - while (bits < 16) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - if (state.head) { - state.head.xflags = (hold & 0xff); - state.head.os = (hold >> 8); - } - if ((state.flags & 0x0200) && (state.wrap & 4)) { - //=== CRC2(state.check, hold); - hbuf[0] = hold & 0xff; - hbuf[1] = (hold >>> 8) & 0xff; - state.check = crc32_1$1(state.check, hbuf, 2, 0); - //===// - } - //=== INITBITS(); - hold = 0; - bits = 0; - //===// - state.mode = EXLEN$1; - /* falls through */ - case EXLEN$1: - if (state.flags & 0x0400) { - //=== NEEDBITS(16); */ - while (bits < 16) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - state.length = hold; - if (state.head) { - state.head.extra_len = hold; - } - if ((state.flags & 0x0200) && (state.wrap & 4)) { - //=== CRC2(state.check, hold); - hbuf[0] = hold & 0xff; - hbuf[1] = (hold >>> 8) & 0xff; - state.check = crc32_1$1(state.check, hbuf, 2, 0); - //===// - } - //=== INITBITS(); - hold = 0; - bits = 0; - //===// - } - else if (state.head) { - state.head.extra = null/*Z_NULL*/; - } - state.mode = EXTRA$1; - /* falls through */ - case EXTRA$1: - if (state.flags & 0x0400) { - copy = state.length; - if (copy > have) { copy = have; } - if (copy) { - if (state.head) { - len = state.head.extra_len - state.length; - if (!state.head.extra) { - // Use untyped array for more convenient processing later - state.head.extra = new Uint8Array(state.head.extra_len); - } - state.head.extra.set( - input.subarray( - next, - // extra field is limited to 65536 bytes - // - no need for additional size check - next + copy - ), - /*len + copy > state.head.extra_max - len ? state.head.extra_max : copy,*/ - len - ); - //zmemcpy(state.head.extra + len, next, - // len + copy > state.head.extra_max ? - // state.head.extra_max - len : copy); - } - if ((state.flags & 0x0200) && (state.wrap & 4)) { - state.check = crc32_1$1(state.check, input, copy, next); - } - have -= copy; - next += copy; - state.length -= copy; - } - if (state.length) { break inf_leave; } - } - state.length = 0; - state.mode = NAME$1; - /* falls through */ - case NAME$1: - if (state.flags & 0x0800) { - if (have === 0) { break inf_leave; } - copy = 0; - do { - // TODO: 2 or 1 bytes? - len = input[next + copy++]; - /* use constant limit because in js we should not preallocate memory */ - if (state.head && len && - (state.length < 65536 /*state.head.name_max*/)) { - state.head.name += String.fromCharCode(len); - } - } while (len && copy < have); - - if ((state.flags & 0x0200) && (state.wrap & 4)) { - state.check = crc32_1$1(state.check, input, copy, next); - } - have -= copy; - next += copy; - if (len) { break inf_leave; } - } - else if (state.head) { - state.head.name = null; - } - state.length = 0; - state.mode = COMMENT$1; - /* falls through */ - case COMMENT$1: - if (state.flags & 0x1000) { - if (have === 0) { break inf_leave; } - copy = 0; - do { - len = input[next + copy++]; - /* use constant limit because in js we should not preallocate memory */ - if (state.head && len && - (state.length < 65536 /*state.head.comm_max*/)) { - state.head.comment += String.fromCharCode(len); - } - } while (len && copy < have); - if ((state.flags & 0x0200) && (state.wrap & 4)) { - state.check = crc32_1$1(state.check, input, copy, next); - } - have -= copy; - next += copy; - if (len) { break inf_leave; } - } - else if (state.head) { - state.head.comment = null; - } - state.mode = HCRC$1; - /* falls through */ - case HCRC$1: - if (state.flags & 0x0200) { - //=== NEEDBITS(16); */ - while (bits < 16) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - if ((state.wrap & 4) && hold !== (state.check & 0xffff)) { - strm.msg = 'header crc mismatch'; - state.mode = BAD$2; - break; - } - //=== INITBITS(); - hold = 0; - bits = 0; - //===// - } - if (state.head) { - state.head.hcrc = ((state.flags >> 9) & 1); - state.head.done = true; - } - strm.adler = state.check = 0; - state.mode = TYPE$2; - break; - case DICTID$1: - //=== NEEDBITS(32); */ - while (bits < 32) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - strm.adler = state.check = zswap32$1(hold); - //=== INITBITS(); - hold = 0; - bits = 0; - //===// - state.mode = DICT$1; - /* falls through */ - case DICT$1: - if (state.havedict === 0) { - //--- RESTORE() --- - strm.next_out = put; - strm.avail_out = left; - strm.next_in = next; - strm.avail_in = have; - state.hold = hold; - state.bits = bits; - //--- - return Z_NEED_DICT$1$1; - } - strm.adler = state.check = 1/*adler32(0L, Z_NULL, 0)*/; - state.mode = TYPE$2; - /* falls through */ - case TYPE$2: - if (flush === Z_BLOCK$2 || flush === Z_TREES$1) { break inf_leave; } - /* falls through */ - case TYPEDO$1: - if (state.last) { - //--- BYTEBITS() ---// - hold >>>= bits & 7; - bits -= bits & 7; - //---// - state.mode = CHECK$1; - break; - } - //=== NEEDBITS(3); */ - while (bits < 3) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - state.last = (hold & 0x01)/*BITS(1)*/; - //--- DROPBITS(1) ---// - hold >>>= 1; - bits -= 1; - //---// - - switch ((hold & 0x03)/*BITS(2)*/) { - case 0: /* stored block */ - //Tracev((stderr, "inflate: stored block%s\n", - // state.last ? " (last)" : "")); - state.mode = STORED$1; - break; - case 1: /* fixed block */ - fixedtables$1(state); - //Tracev((stderr, "inflate: fixed codes block%s\n", - // state.last ? " (last)" : "")); - state.mode = LEN_$1; /* decode codes */ - if (flush === Z_TREES$1) { - //--- DROPBITS(2) ---// - hold >>>= 2; - bits -= 2; - //---// - break inf_leave; - } - break; - case 2: /* dynamic block */ - //Tracev((stderr, "inflate: dynamic codes block%s\n", - // state.last ? " (last)" : "")); - state.mode = TABLE$1; - break; - case 3: - strm.msg = 'invalid block type'; - state.mode = BAD$2; - } - //--- DROPBITS(2) ---// - hold >>>= 2; - bits -= 2; - //---// - break; - case STORED$1: - //--- BYTEBITS() ---// /* go to byte boundary */ - hold >>>= bits & 7; - bits -= bits & 7; - //---// - //=== NEEDBITS(32); */ - while (bits < 32) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - if ((hold & 0xffff) !== ((hold >>> 16) ^ 0xffff)) { - strm.msg = 'invalid stored block lengths'; - state.mode = BAD$2; - break; - } - state.length = hold & 0xffff; - //Tracev((stderr, "inflate: stored length %u\n", - // state.length)); - //=== INITBITS(); - hold = 0; - bits = 0; - //===// - state.mode = COPY_$1; - if (flush === Z_TREES$1) { break inf_leave; } - /* falls through */ - case COPY_$1: - state.mode = COPY$1; - /* falls through */ - case COPY$1: - copy = state.length; - if (copy) { - if (copy > have) { copy = have; } - if (copy > left) { copy = left; } - if (copy === 0) { break inf_leave; } - //--- zmemcpy(put, next, copy); --- - output.set(input.subarray(next, next + copy), put); - //---// - have -= copy; - next += copy; - left -= copy; - put += copy; - state.length -= copy; - break; - } - //Tracev((stderr, "inflate: stored end\n")); - state.mode = TYPE$2; - break; - case TABLE$1: - //=== NEEDBITS(14); */ - while (bits < 14) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - state.nlen = (hold & 0x1f)/*BITS(5)*/ + 257; - //--- DROPBITS(5) ---// - hold >>>= 5; - bits -= 5; - //---// - state.ndist = (hold & 0x1f)/*BITS(5)*/ + 1; - //--- DROPBITS(5) ---// - hold >>>= 5; - bits -= 5; - //---// - state.ncode = (hold & 0x0f)/*BITS(4)*/ + 4; - //--- DROPBITS(4) ---// - hold >>>= 4; - bits -= 4; - //---// - //#ifndef PKZIP_BUG_WORKAROUND - if (state.nlen > 286 || state.ndist > 30) { - strm.msg = 'too many length or distance symbols'; - state.mode = BAD$2; - break; - } - //#endif - //Tracev((stderr, "inflate: table sizes ok\n")); - state.have = 0; - state.mode = LENLENS$1; - /* falls through */ - case LENLENS$1: - while (state.have < state.ncode) { - //=== NEEDBITS(3); - while (bits < 3) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - state.lens[order[state.have++]] = (hold & 0x07);//BITS(3); - //--- DROPBITS(3) ---// - hold >>>= 3; - bits -= 3; - //---// - } - while (state.have < 19) { - state.lens[order[state.have++]] = 0; - } - // We have separate tables & no pointers. 2 commented lines below not needed. - //state.next = state.codes; - //state.lencode = state.next; - // Switch to use dynamic table - state.lencode = state.lendyn; - state.lenbits = 7; - - opts = { bits: state.lenbits }; - ret = inftrees$1(CODES$2, state.lens, 0, 19, state.lencode, 0, state.work, opts); - state.lenbits = opts.bits; - - if (ret) { - strm.msg = 'invalid code lengths set'; - state.mode = BAD$2; - break; - } - //Tracev((stderr, "inflate: code lengths ok\n")); - state.have = 0; - state.mode = CODELENS$1; - /* falls through */ - case CODELENS$1: - while (state.have < state.nlen + state.ndist) { - for (;;) { - here = state.lencode[hold & ((1 << state.lenbits) - 1)];/*BITS(state.lenbits)*/ - here_bits = here >>> 24; - here_op = (here >>> 16) & 0xff; - here_val = here & 0xffff; - - if ((here_bits) <= bits) { break; } - //--- PULLBYTE() ---// - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - //---// - } - if (here_val < 16) { - //--- DROPBITS(here.bits) ---// - hold >>>= here_bits; - bits -= here_bits; - //---// - state.lens[state.have++] = here_val; - } - else { - if (here_val === 16) { - //=== NEEDBITS(here.bits + 2); - n = here_bits + 2; - while (bits < n) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - //--- DROPBITS(here.bits) ---// - hold >>>= here_bits; - bits -= here_bits; - //---// - if (state.have === 0) { - strm.msg = 'invalid bit length repeat'; - state.mode = BAD$2; - break; - } - len = state.lens[state.have - 1]; - copy = 3 + (hold & 0x03);//BITS(2); - //--- DROPBITS(2) ---// - hold >>>= 2; - bits -= 2; - //---// - } - else if (here_val === 17) { - //=== NEEDBITS(here.bits + 3); - n = here_bits + 3; - while (bits < n) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - //--- DROPBITS(here.bits) ---// - hold >>>= here_bits; - bits -= here_bits; - //---// - len = 0; - copy = 3 + (hold & 0x07);//BITS(3); - //--- DROPBITS(3) ---// - hold >>>= 3; - bits -= 3; - //---// - } - else { - //=== NEEDBITS(here.bits + 7); - n = here_bits + 7; - while (bits < n) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - //--- DROPBITS(here.bits) ---// - hold >>>= here_bits; - bits -= here_bits; - //---// - len = 0; - copy = 11 + (hold & 0x7f);//BITS(7); - //--- DROPBITS(7) ---// - hold >>>= 7; - bits -= 7; - //---// - } - if (state.have + copy > state.nlen + state.ndist) { - strm.msg = 'invalid bit length repeat'; - state.mode = BAD$2; - break; - } - while (copy--) { - state.lens[state.have++] = len; - } - } - } - - /* handle error breaks in while */ - if (state.mode === BAD$2) { break; } - - /* check for end-of-block code (better have one) */ - if (state.lens[256] === 0) { - strm.msg = 'invalid code -- missing end-of-block'; - state.mode = BAD$2; - break; - } - - /* build code tables -- note: do not change the lenbits or distbits - values here (9 and 6) without reading the comments in inftrees.h - concerning the ENOUGH constants, which depend on those values */ - state.lenbits = 9; - - opts = { bits: state.lenbits }; - ret = inftrees$1(LENS$2, state.lens, 0, state.nlen, state.lencode, 0, state.work, opts); - // We have separate tables & no pointers. 2 commented lines below not needed. - // state.next_index = opts.table_index; - state.lenbits = opts.bits; - // state.lencode = state.next; - - if (ret) { - strm.msg = 'invalid literal/lengths set'; - state.mode = BAD$2; - break; - } - - state.distbits = 6; - //state.distcode.copy(state.codes); - // Switch to use dynamic table - state.distcode = state.distdyn; - opts = { bits: state.distbits }; - ret = inftrees$1(DISTS$2, state.lens, state.nlen, state.ndist, state.distcode, 0, state.work, opts); - // We have separate tables & no pointers. 2 commented lines below not needed. - // state.next_index = opts.table_index; - state.distbits = opts.bits; - // state.distcode = state.next; - - if (ret) { - strm.msg = 'invalid distances set'; - state.mode = BAD$2; - break; - } - //Tracev((stderr, 'inflate: codes ok\n')); - state.mode = LEN_$1; - if (flush === Z_TREES$1) { break inf_leave; } - /* falls through */ - case LEN_$1: - state.mode = LEN$1; - /* falls through */ - case LEN$1: - if (have >= 6 && left >= 258) { - //--- RESTORE() --- - strm.next_out = put; - strm.avail_out = left; - strm.next_in = next; - strm.avail_in = have; - state.hold = hold; - state.bits = bits; - //--- - inffast$1(strm, _out); - //--- LOAD() --- - put = strm.next_out; - output = strm.output; - left = strm.avail_out; - next = strm.next_in; - input = strm.input; - have = strm.avail_in; - hold = state.hold; - bits = state.bits; - //--- - - if (state.mode === TYPE$2) { - state.back = -1; - } - break; - } - state.back = 0; - for (;;) { - here = state.lencode[hold & ((1 << state.lenbits) - 1)]; /*BITS(state.lenbits)*/ - here_bits = here >>> 24; - here_op = (here >>> 16) & 0xff; - here_val = here & 0xffff; - - if (here_bits <= bits) { break; } - //--- PULLBYTE() ---// - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - //---// - } - if (here_op && (here_op & 0xf0) === 0) { - last_bits = here_bits; - last_op = here_op; - last_val = here_val; - for (;;) { - here = state.lencode[last_val + - ((hold & ((1 << (last_bits + last_op)) - 1))/*BITS(last.bits + last.op)*/ >> last_bits)]; - here_bits = here >>> 24; - here_op = (here >>> 16) & 0xff; - here_val = here & 0xffff; - - if ((last_bits + here_bits) <= bits) { break; } - //--- PULLBYTE() ---// - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - //---// - } - //--- DROPBITS(last.bits) ---// - hold >>>= last_bits; - bits -= last_bits; - //---// - state.back += last_bits; - } - //--- DROPBITS(here.bits) ---// - hold >>>= here_bits; - bits -= here_bits; - //---// - state.back += here_bits; - state.length = here_val; - if (here_op === 0) { - //Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? - // "inflate: literal '%c'\n" : - // "inflate: literal 0x%02x\n", here.val)); - state.mode = LIT$1; - break; - } - if (here_op & 32) { - //Tracevv((stderr, "inflate: end of block\n")); - state.back = -1; - state.mode = TYPE$2; - break; - } - if (here_op & 64) { - strm.msg = 'invalid literal/length code'; - state.mode = BAD$2; - break; - } - state.extra = here_op & 15; - state.mode = LENEXT$1; - /* falls through */ - case LENEXT$1: - if (state.extra) { - //=== NEEDBITS(state.extra); - n = state.extra; - while (bits < n) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - state.length += hold & ((1 << state.extra) - 1)/*BITS(state.extra)*/; - //--- DROPBITS(state.extra) ---// - hold >>>= state.extra; - bits -= state.extra; - //---// - state.back += state.extra; - } - //Tracevv((stderr, "inflate: length %u\n", state.length)); - state.was = state.length; - state.mode = DIST$1; - /* falls through */ - case DIST$1: - for (;;) { - here = state.distcode[hold & ((1 << state.distbits) - 1)];/*BITS(state.distbits)*/ - here_bits = here >>> 24; - here_op = (here >>> 16) & 0xff; - here_val = here & 0xffff; - - if ((here_bits) <= bits) { break; } - //--- PULLBYTE() ---// - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - //---// - } - if ((here_op & 0xf0) === 0) { - last_bits = here_bits; - last_op = here_op; - last_val = here_val; - for (;;) { - here = state.distcode[last_val + - ((hold & ((1 << (last_bits + last_op)) - 1))/*BITS(last.bits + last.op)*/ >> last_bits)]; - here_bits = here >>> 24; - here_op = (here >>> 16) & 0xff; - here_val = here & 0xffff; - - if ((last_bits + here_bits) <= bits) { break; } - //--- PULLBYTE() ---// - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - //---// - } - //--- DROPBITS(last.bits) ---// - hold >>>= last_bits; - bits -= last_bits; - //---// - state.back += last_bits; - } - //--- DROPBITS(here.bits) ---// - hold >>>= here_bits; - bits -= here_bits; - //---// - state.back += here_bits; - if (here_op & 64) { - strm.msg = 'invalid distance code'; - state.mode = BAD$2; - break; - } - state.offset = here_val; - state.extra = (here_op) & 15; - state.mode = DISTEXT$1; - /* falls through */ - case DISTEXT$1: - if (state.extra) { - //=== NEEDBITS(state.extra); - n = state.extra; - while (bits < n) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - state.offset += hold & ((1 << state.extra) - 1)/*BITS(state.extra)*/; - //--- DROPBITS(state.extra) ---// - hold >>>= state.extra; - bits -= state.extra; - //---// - state.back += state.extra; - } - //#ifdef INFLATE_STRICT - if (state.offset > state.dmax) { - strm.msg = 'invalid distance too far back'; - state.mode = BAD$2; - break; - } - //#endif - //Tracevv((stderr, "inflate: distance %u\n", state.offset)); - state.mode = MATCH$1; - /* falls through */ - case MATCH$1: - if (left === 0) { break inf_leave; } - copy = _out - left; - if (state.offset > copy) { /* copy from window */ - copy = state.offset - copy; - if (copy > state.whave) { - if (state.sane) { - strm.msg = 'invalid distance too far back'; - state.mode = BAD$2; - break; - } - // (!) This block is disabled in zlib defaults, - // don't enable it for binary compatibility - //#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR - // Trace((stderr, "inflate.c too far\n")); - // copy -= state.whave; - // if (copy > state.length) { copy = state.length; } - // if (copy > left) { copy = left; } - // left -= copy; - // state.length -= copy; - // do { - // output[put++] = 0; - // } while (--copy); - // if (state.length === 0) { state.mode = LEN; } - // break; - //#endif - } - if (copy > state.wnext) { - copy -= state.wnext; - from = state.wsize - copy; - } - else { - from = state.wnext - copy; - } - if (copy > state.length) { copy = state.length; } - from_source = state.window; - } - else { /* copy from output */ - from_source = output; - from = put - state.offset; - copy = state.length; - } - if (copy > left) { copy = left; } - left -= copy; - state.length -= copy; - do { - output[put++] = from_source[from++]; - } while (--copy); - if (state.length === 0) { state.mode = LEN$1; } - break; - case LIT$1: - if (left === 0) { break inf_leave; } - output[put++] = state.length; - left--; - state.mode = LEN$1; - break; - case CHECK$1: - if (state.wrap) { - //=== NEEDBITS(32); - while (bits < 32) { - if (have === 0) { break inf_leave; } - have--; - // Use '|' instead of '+' to make sure that result is signed - hold |= input[next++] << bits; - bits += 8; - } - //===// - _out -= left; - strm.total_out += _out; - state.total += _out; - if ((state.wrap & 4) && _out) { - strm.adler = state.check = - /*UPDATE_CHECK(state.check, put - _out, _out);*/ - (state.flags ? crc32_1$1(state.check, output, _out, put - _out) : adler32_1$1(state.check, output, _out, put - _out)); - - } - _out = left; - // NB: crc32 stored as signed 32-bit int, zswap32 returns signed too - if ((state.wrap & 4) && (state.flags ? hold : zswap32$1(hold)) !== state.check) { - strm.msg = 'incorrect data check'; - state.mode = BAD$2; - break; - } - //=== INITBITS(); - hold = 0; - bits = 0; - //===// - //Tracev((stderr, "inflate: check matches trailer\n")); - } - state.mode = LENGTH$1; - /* falls through */ - case LENGTH$1: - if (state.wrap && state.flags) { - //=== NEEDBITS(32); - while (bits < 32) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - if ((state.wrap & 4) && hold !== (state.total & 0xffffffff)) { - strm.msg = 'incorrect length check'; - state.mode = BAD$2; - break; - } - //=== INITBITS(); - hold = 0; - bits = 0; - //===// - //Tracev((stderr, "inflate: length matches trailer\n")); - } - state.mode = DONE$1; - /* falls through */ - case DONE$1: - ret = Z_STREAM_END$1$1; - break inf_leave; - case BAD$2: - ret = Z_DATA_ERROR$1$1; - break inf_leave; - case MEM$1: - return Z_MEM_ERROR$1$1; - case SYNC$1: - /* falls through */ - default: - return Z_STREAM_ERROR$1$1; - } - } - - // inf_leave <- here is real place for "goto inf_leave", emulated via "break inf_leave" - - /* - Return from inflate(), updating the total counts and the check value. - If there was no progress during the inflate() call, return a buffer - error. Call updatewindow() to create and/or update the window state. - Note: a memory error from inflate() is non-recoverable. - */ - - //--- RESTORE() --- - strm.next_out = put; - strm.avail_out = left; - strm.next_in = next; - strm.avail_in = have; - state.hold = hold; - state.bits = bits; - //--- - - if (state.wsize || (_out !== strm.avail_out && state.mode < BAD$2 && - (state.mode < CHECK$1 || flush !== Z_FINISH$1$1))) { - if (updatewindow$1(strm, strm.output, strm.next_out, _out - strm.avail_out)) ; - } - _in -= strm.avail_in; - _out -= strm.avail_out; - strm.total_in += _in; - strm.total_out += _out; - state.total += _out; - if ((state.wrap & 4) && _out) { - strm.adler = state.check = /*UPDATE_CHECK(state.check, strm.next_out - _out, _out);*/ - (state.flags ? crc32_1$1(state.check, output, _out, strm.next_out - _out) : adler32_1$1(state.check, output, _out, strm.next_out - _out)); - } - strm.data_type = state.bits + (state.last ? 64 : 0) + - (state.mode === TYPE$2 ? 128 : 0) + - (state.mode === LEN_$1 || state.mode === COPY_$1 ? 256 : 0); - if (((_in === 0 && _out === 0) || flush === Z_FINISH$1$1) && ret === Z_OK$1$1) { - ret = Z_BUF_ERROR$2; - } - return ret; - }; - - - const inflateEnd$1 = (strm) => { - - if (inflateStateCheck(strm)) { - return Z_STREAM_ERROR$1$1; - } - - let state = strm.state; - if (state.window) { - state.window = null; - } - strm.state = null; - return Z_OK$1$1; - }; - - - const inflateGetHeader$1 = (strm, head) => { - - /* check state */ - if (inflateStateCheck(strm)) { return Z_STREAM_ERROR$1$1; } - const state = strm.state; - if ((state.wrap & 2) === 0) { return Z_STREAM_ERROR$1$1; } - - /* save header structure */ - state.head = head; - head.done = false; - return Z_OK$1$1; - }; - - - const inflateSetDictionary$1 = (strm, dictionary) => { - const dictLength = dictionary.length; - - let state; - let dictid; - let ret; - - /* check state */ - if (inflateStateCheck(strm)) { return Z_STREAM_ERROR$1$1; } - state = strm.state; - - if (state.wrap !== 0 && state.mode !== DICT$1) { - return Z_STREAM_ERROR$1$1; - } - - /* check for correct dictionary identifier */ - if (state.mode === DICT$1) { - dictid = 1; /* adler32(0, null, 0)*/ - /* dictid = adler32(dictid, dictionary, dictLength); */ - dictid = adler32_1$1(dictid, dictionary, dictLength, 0); - if (dictid !== state.check) { - return Z_DATA_ERROR$1$1; - } - } - /* copy dictionary to window using updatewindow(), which will amend the - existing dictionary if appropriate */ - ret = updatewindow$1(strm, dictionary, dictLength, dictLength); - if (ret) { - state.mode = MEM$1; - return Z_MEM_ERROR$1$1; - } - state.havedict = 1; - // Tracev((stderr, "inflate: dictionary set\n")); - return Z_OK$1$1; - }; - - - var inflateReset_1$1 = inflateReset$1; - var inflateReset2_1$1 = inflateReset2$1; - var inflateResetKeep_1$1 = inflateResetKeep$1; - var inflateInit_1$1 = inflateInit$1; - var inflateInit2_1$1 = inflateInit2$1; - var inflate_2$1$1 = inflate$2$1; - var inflateEnd_1$1 = inflateEnd$1; - var inflateGetHeader_1$1 = inflateGetHeader$1; - var inflateSetDictionary_1$1 = inflateSetDictionary$1; - var inflateInfo$1 = 'pako inflate (from Nodeca project)'; - - /* Not implemented - module.exports.inflateCodesUsed = inflateCodesUsed; - module.exports.inflateCopy = inflateCopy; - module.exports.inflateGetDictionary = inflateGetDictionary; - module.exports.inflateMark = inflateMark; - module.exports.inflatePrime = inflatePrime; - module.exports.inflateSync = inflateSync; - module.exports.inflateSyncPoint = inflateSyncPoint; - module.exports.inflateUndermine = inflateUndermine; - module.exports.inflateValidate = inflateValidate; - */ - - var inflate_1$2$1 = { - inflateReset: inflateReset_1$1, - inflateReset2: inflateReset2_1$1, - inflateResetKeep: inflateResetKeep_1$1, - inflateInit: inflateInit_1$1, - inflateInit2: inflateInit2_1$1, - inflate: inflate_2$1$1, - inflateEnd: inflateEnd_1$1, - inflateGetHeader: inflateGetHeader_1$1, - inflateSetDictionary: inflateSetDictionary_1$1, - inflateInfo: inflateInfo$1 - }; - - // (C) 1995-2013 Jean-loup Gailly and Mark Adler - // (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin - // - // This software is provided 'as-is', without any express or implied - // warranty. In no event will the authors be held liable for any damages - // arising from the use of this software. - // - // Permission is granted to anyone to use this software for any purpose, - // including commercial applications, and to alter it and redistribute it - // freely, subject to the following restrictions: - // - // 1. The origin of this software must not be misrepresented; you must not - // claim that you wrote the original software. If you use this software - // in a product, an acknowledgment in the product documentation would be - // appreciated but is not required. - // 2. Altered source versions must be plainly marked as such, and must not be - // misrepresented as being the original software. - // 3. This notice may not be removed or altered from any source distribution. - - function GZheader$1() { - /* true if compressed data believed to be text */ - this.text = 0; - /* modification time */ - this.time = 0; - /* extra flags (not used when writing a gzip file) */ - this.xflags = 0; - /* operating system */ - this.os = 0; - /* pointer to extra field or Z_NULL if none */ - this.extra = null; - /* extra field length (valid if extra != Z_NULL) */ - this.extra_len = 0; // Actually, we don't need it in JS, - // but leave for few code modifications - - // - // Setup limits is not necessary because in js we should not preallocate memory - // for inflate use constant limit in 65536 bytes - // - - /* space at extra (only when reading header) */ - // this.extra_max = 0; - /* pointer to zero-terminated file name or Z_NULL */ - this.name = ''; - /* space at name (only when reading header) */ - // this.name_max = 0; - /* pointer to zero-terminated comment or Z_NULL */ - this.comment = ''; - /* space at comment (only when reading header) */ - // this.comm_max = 0; - /* true if there was or will be a header crc */ - this.hcrc = 0; - /* true when done reading gzip header (not used when writing a gzip file) */ - this.done = false; - } - - var gzheader$1 = GZheader$1; - - const toString$2 = Object.prototype.toString; - - /* Public constants ==========================================================*/ - /* ===========================================================================*/ - - const { - Z_NO_FLUSH: Z_NO_FLUSH$3, Z_FINISH: Z_FINISH$4, - Z_OK: Z_OK$4, Z_STREAM_END: Z_STREAM_END$4, Z_NEED_DICT: Z_NEED_DICT$2, Z_STREAM_ERROR: Z_STREAM_ERROR$3, Z_DATA_ERROR: Z_DATA_ERROR$3, Z_MEM_ERROR: Z_MEM_ERROR$2 - } = constants$2$1; - - /* ===========================================================================*/ - - - /** - * class Inflate - * - * Generic JS-style wrapper for zlib calls. If you don't need - * streaming behaviour - use more simple functions: [[inflate]] - * and [[inflateRaw]]. - **/ - - /* internal - * inflate.chunks -> Array - * - * Chunks of output data, if [[Inflate#onData]] not overridden. - **/ - - /** - * Inflate.result -> Uint8Array|String - * - * Uncompressed result, generated by default [[Inflate#onData]] - * and [[Inflate#onEnd]] handlers. Filled after you push last chunk - * (call [[Inflate#push]] with `Z_FINISH` / `true` param). - **/ - - /** - * Inflate.err -> Number - * - * Error code after inflate finished. 0 (Z_OK) on success. - * Should be checked if broken data possible. - **/ - - /** - * Inflate.msg -> String - * - * Error message, if [[Inflate.err]] != 0 - **/ - - - /** - * new Inflate(options) - * - options (Object): zlib inflate options. - * - * Creates new inflator instance with specified params. Throws exception - * on bad params. Supported options: - * - * - `windowBits` - * - `dictionary` - * - * [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced) - * for more information on these. - * - * Additional options, for internal needs: - * - * - `chunkSize` - size of generated data chunks (16K by default) - * - `raw` (Boolean) - do raw inflate - * - `to` (String) - if equal to 'string', then result will be converted - * from utf8 to utf16 (javascript) string. When string output requested, - * chunk length can differ from `chunkSize`, depending on content. - * - * By default, when no options set, autodetect deflate/gzip data format via - * wrapper header. - * - * ##### Example: - * - * ```javascript - * const pako = require('pako') - * const chunk1 = new Uint8Array([1,2,3,4,5,6,7,8,9]) - * const chunk2 = new Uint8Array([10,11,12,13,14,15,16,17,18,19]); - * - * const inflate = new pako.Inflate({ level: 3}); - * - * inflate.push(chunk1, false); - * inflate.push(chunk2, true); // true -> last chunk - * - * if (inflate.err) { throw new Error(inflate.err); } - * - * console.log(inflate.result); - * ``` - **/ - function Inflate$1$1(options) { - this.options = common$1.assign({ - chunkSize: 1024 * 64, - windowBits: 15, - to: '' - }, options || {}); - - const opt = this.options; - - // Force window size for `raw` data, if not set directly, - // because we have no header for autodetect. - if (opt.raw && (opt.windowBits >= 0) && (opt.windowBits < 16)) { - opt.windowBits = -opt.windowBits; - if (opt.windowBits === 0) { opt.windowBits = -15; } - } - - // If `windowBits` not defined (and mode not raw) - set autodetect flag for gzip/deflate - if ((opt.windowBits >= 0) && (opt.windowBits < 16) && - !(options && options.windowBits)) { - opt.windowBits += 32; - } - - // Gzip header has no info about windows size, we can do autodetect only - // for deflate. So, if window size not set, force it to max when gzip possible - if ((opt.windowBits > 15) && (opt.windowBits < 48)) { - // bit 3 (16) -> gzipped data - // bit 4 (32) -> autodetect gzip/deflate - if ((opt.windowBits & 15) === 0) { - opt.windowBits |= 15; - } - } - - this.err = 0; // error code, if happens (0 = Z_OK) - this.msg = ''; // error message - this.ended = false; // used to avoid multiple onEnd() calls - this.chunks = []; // chunks of compressed data - - this.strm = new zstream$1(); - this.strm.avail_out = 0; - - let status = inflate_1$2$1.inflateInit2( - this.strm, - opt.windowBits - ); - - if (status !== Z_OK$4) { - throw new Error(messages$1[status]); - } - - this.header = new gzheader$1(); - - inflate_1$2$1.inflateGetHeader(this.strm, this.header); - - // Setup dictionary - if (opt.dictionary) { - // Convert data if needed - if (typeof opt.dictionary === 'string') { - opt.dictionary = strings$1.string2buf(opt.dictionary); - } else if (toString$2.call(opt.dictionary) === '[object ArrayBuffer]') { - opt.dictionary = new Uint8Array(opt.dictionary); - } - if (opt.raw) { //In raw mode we need to set the dictionary early - status = inflate_1$2$1.inflateSetDictionary(this.strm, opt.dictionary); - if (status !== Z_OK$4) { - throw new Error(messages$1[status]); - } - } - } - } - - /** - * Inflate#push(data[, flush_mode]) -> Boolean - * - data (Uint8Array|ArrayBuffer): input data - * - flush_mode (Number|Boolean): 0..6 for corresponding Z_NO_FLUSH..Z_TREE - * flush modes. See constants. Skipped or `false` means Z_NO_FLUSH, - * `true` means Z_FINISH. - * - * Sends input data to inflate pipe, generating [[Inflate#onData]] calls with - * new output chunks. Returns `true` on success. If end of stream detected, - * [[Inflate#onEnd]] will be called. - * - * `flush_mode` is not needed for normal operation, because end of stream - * detected automatically. You may try to use it for advanced things, but - * this functionality was not tested. - * - * On fail call [[Inflate#onEnd]] with error code and return false. - * - * ##### Example - * - * ```javascript - * push(chunk, false); // push one of data chunks - * ... - * push(chunk, true); // push last chunk - * ``` - **/ - Inflate$1$1.prototype.push = function (data, flush_mode) { - const strm = this.strm; - const chunkSize = this.options.chunkSize; - const dictionary = this.options.dictionary; - let status, _flush_mode, last_avail_out; - - if (this.ended) return false; - - if (flush_mode === ~~flush_mode) _flush_mode = flush_mode; - else _flush_mode = flush_mode === true ? Z_FINISH$4 : Z_NO_FLUSH$3; - - // Convert data if needed - if (toString$2.call(data) === '[object ArrayBuffer]') { - strm.input = new Uint8Array(data); - } else { - strm.input = data; - } - - strm.next_in = 0; - strm.avail_in = strm.input.length; - - for (;;) { - if (strm.avail_out === 0) { - strm.output = new Uint8Array(chunkSize); - strm.next_out = 0; - strm.avail_out = chunkSize; - } - - status = inflate_1$2$1.inflate(strm, _flush_mode); - - if (status === Z_NEED_DICT$2 && dictionary) { - status = inflate_1$2$1.inflateSetDictionary(strm, dictionary); - - if (status === Z_OK$4) { - status = inflate_1$2$1.inflate(strm, _flush_mode); - } else if (status === Z_DATA_ERROR$3) { - // Replace code with more verbose - status = Z_NEED_DICT$2; - } - } - - // Skip snyc markers if more data follows and not raw mode - while (strm.avail_in > 0 && - status === Z_STREAM_END$4 && - strm.state.wrap > 0 && - data[strm.next_in] !== 0) - { - inflate_1$2$1.inflateReset(strm); - status = inflate_1$2$1.inflate(strm, _flush_mode); - } - - switch (status) { - case Z_STREAM_ERROR$3: - case Z_DATA_ERROR$3: - case Z_NEED_DICT$2: - case Z_MEM_ERROR$2: - this.onEnd(status); - this.ended = true; - return false; - } - - // Remember real `avail_out` value, because we may patch out buffer content - // to align utf8 strings boundaries. - last_avail_out = strm.avail_out; - - if (strm.next_out) { - if (strm.avail_out === 0 || status === Z_STREAM_END$4) { - - if (this.options.to === 'string') { - - let next_out_utf8 = strings$1.utf8border(strm.output, strm.next_out); - - let tail = strm.next_out - next_out_utf8; - let utf8str = strings$1.buf2string(strm.output, next_out_utf8); - - // move tail & realign counters - strm.next_out = tail; - strm.avail_out = chunkSize - tail; - if (tail) strm.output.set(strm.output.subarray(next_out_utf8, next_out_utf8 + tail), 0); - - this.onData(utf8str); - - } else { - this.onData(strm.output.length === strm.next_out ? strm.output : strm.output.subarray(0, strm.next_out)); - } - } - } - - // Must repeat iteration if out buffer is full - if (status === Z_OK$4 && last_avail_out === 0) continue; - - // Finalize if end of stream reached. - if (status === Z_STREAM_END$4) { - status = inflate_1$2$1.inflateEnd(this.strm); - this.onEnd(status); - this.ended = true; - return true; - } - - if (strm.avail_in === 0) break; - } - - return true; - }; - - - /** - * Inflate#onData(chunk) -> Void - * - chunk (Uint8Array|String): output data. When string output requested, - * each chunk will be string. - * - * By default, stores data blocks in `chunks[]` property and glue - * those in `onEnd`. Override this handler, if you need another behaviour. - **/ - Inflate$1$1.prototype.onData = function (chunk) { - this.chunks.push(chunk); - }; - - - /** - * Inflate#onEnd(status) -> Void - * - status (Number): inflate status. 0 (Z_OK) on success, - * other if not. - * - * Called either after you tell inflate that the input stream is - * complete (Z_FINISH). By default - join collected chunks, - * free memory and fill `results` / `err` properties. - **/ - Inflate$1$1.prototype.onEnd = function (status) { - // On success - join - if (status === Z_OK$4) { - if (this.options.to === 'string') { - this.result = this.chunks.join(''); - } else { - this.result = common$1.flattenChunks(this.chunks); - } - } - this.chunks = []; - this.err = status; - this.msg = this.strm.msg; - }; - - - /** - * inflate(data[, options]) -> Uint8Array|String - * - data (Uint8Array|ArrayBuffer): input data to decompress. - * - options (Object): zlib inflate options. - * - * Decompress `data` with inflate/ungzip and `options`. Autodetect - * format via wrapper header by default. That's why we don't provide - * separate `ungzip` method. - * - * Supported options are: - * - * - windowBits - * - * [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced) - * for more information. - * - * Sugar (options): - * - * - `raw` (Boolean) - say that we work with raw stream, if you don't wish to specify - * negative windowBits implicitly. - * - `to` (String) - if equal to 'string', then result will be converted - * from utf8 to utf16 (javascript) string. When string output requested, - * chunk length can differ from `chunkSize`, depending on content. - * - * - * ##### Example: - * - * ```javascript - * const pako = require('pako'); - * const input = pako.deflate(new Uint8Array([1,2,3,4,5,6,7,8,9])); - * let output; - * - * try { - * output = pako.inflate(input); - * } catch (err) { - * console.log(err); - * } - * ``` - **/ - function inflate$1$1(input, options) { - const inflator = new Inflate$1$1(options); - - inflator.push(input); - - // That will never happens, if you don't cheat with options :) - if (inflator.err) throw inflator.msg || messages$1[inflator.err]; - - return inflator.result; - } - - - /** - * inflateRaw(data[, options]) -> Uint8Array|String - * - data (Uint8Array|ArrayBuffer): input data to decompress. - * - options (Object): zlib inflate options. - * - * The same as [[inflate]], but creates raw data, without wrapper - * (header and adler32 crc). - **/ - function inflateRaw$1$1(input, options) { - options = options || {}; - options.raw = true; - return inflate$1$1(input, options); - } - - - /** - * ungzip(data[, options]) -> Uint8Array|String - * - data (Uint8Array|ArrayBuffer): input data to decompress. - * - options (Object): zlib inflate options. - * - * Just shortcut to [[inflate]], because it autodetects format - * by header.content. Done for convenience. - **/ - - - var Inflate_1$1$1 = Inflate$1$1; - var inflate_2$2 = inflate$1$1; - var inflateRaw_1$1$1 = inflateRaw$1$1; - var ungzip$1$1 = inflate$1$1; - var constants$3 = constants$2$1; - - var inflate_1$1$1 = { - Inflate: Inflate_1$1$1, - inflate: inflate_2$2, - inflateRaw: inflateRaw_1$1$1, - ungzip: ungzip$1$1, - constants: constants$3 - }; - - const { Deflate, deflate, deflateRaw, gzip } = deflate_1$1; - - const { Inflate: Inflate$2, inflate: inflate$3, inflateRaw: inflateRaw$2, ungzip: ungzip$2 } = inflate_1$1$1; - var deflateRaw_1 = deflateRaw; - var inflate_1$3 = inflate$3; - var inflateRaw_1 = inflateRaw$2; - var ungzip_1$1 = ungzip$2; - - const FEXTRA = 4; // gzip spec F.EXTRA flag - - function isgzipped(data) { - const b = ArrayBuffer.isView(data) ? data : new Uint8Array(data); - return b[0] ===31 && b[1] === 139; - } - - /** - * Pako does not properly ungzip block compressed files if > 1 block is present. Test for bgzip and use wrapper. - */ - function ungzip_blocks(data) { - const ba = ArrayBuffer.isView(data) ? data : new Uint8Array(data); - const b = ba[3] & FEXTRA; - if (b !== 0 && ba[12] === 66 && ba[13] === 67) { - return unbgzf(ba.buffer); - } else { - return ungzip_1$1(ba); - } - } - - // Uncompress data, assumed to be series of bgzipped blocks - function unbgzf(data, lim) { - - const oBlockList = []; - let ptr = 0; - let totalSize = 0; - - lim = lim || data.byteLength - 18; - - while (ptr < lim) { - try { - const ba = ArrayBuffer.isView(data) ? data : new Uint8Array(data, ptr, 18); - const xlen = (ba[11] << 8) | (ba[10]); - const flg = ba[3]; - const fextra = flg & FEXTRA; - const si1 = ba[12]; - const si2 = ba[13]; - const slen = (ba[15] << 8) | (ba[14]); - const bsize = ((ba[17] << 8) | (ba[16])) + 1; - const start = 12 + xlen + ptr; // Start of CDATA - const bytesLeft = data.byteLength - start; - const cDataSize = bsize - xlen - 19; - if (bytesLeft < cDataSize || cDataSize <= 0) break; - - const a = new Uint8Array(data, start, cDataSize); - const unc = inflateRaw_1(a); - - // const inflate = new Zlib.RawInflate(a); - // const unc = inflate.decompress(); - - ptr += (cDataSize - 1) + 26; //inflate.ip + 26 - totalSize += unc.byteLength; - oBlockList.push(unc); - } catch (e) { - console.error(e); - break; - } - } - - // Concatenate decompressed blocks - if (oBlockList.length === 1) { - return oBlockList[0]; - } else { - const out = new Uint8Array(totalSize); - let cursor = 0; - for (let i = 0; i < oBlockList.length; ++i) { - var b = new Uint8Array(oBlockList[i]); - arrayCopy(b, 0, out, cursor, b.length); - cursor += b.length; - } - return out; - } - } - - function bgzBlockSize$1(data) { - const ba = ArrayBuffer.isView(data) ? data : new Uint8Array(data); - const bsize = (ba[17] << 8 | ba[16]) + 1; - return bsize; - } - - // From Thomas Down's zlib implementation - - const testArray = new Uint8Array(1); - const hasSubarray = (typeof testArray.subarray === 'function'); - - function arrayCopy(src, srcOffset, dest, destOffset, count) { - if (count === 0) { - return; - } - if (!src) { - throw "Undef src"; - } else if (!dest) { - throw "Undef dest"; - } - if (srcOffset === 0 && count === src.length) { - arrayCopy_fast(src, dest, destOffset); - } else if (hasSubarray) { - arrayCopy_fast(src.subarray(srcOffset, srcOffset + count), dest, destOffset); - } else if (src.BYTES_PER_ELEMENT === 1 && count > 100) { - arrayCopy_fast(new Uint8Array(src.buffer, src.byteOffset + srcOffset, count), dest, destOffset); - } else { - arrayCopy_slow(src, srcOffset, dest, destOffset, count); - } - } - - function arrayCopy_slow(src, srcOffset, dest, destOffset, count) { - for (let i = 0; i < count; ++i) { - dest[destOffset + i] = src[srcOffset + i]; - } - } - - function arrayCopy_fast(src, dest, destOffset) { - dest.set(src, destOffset); - } - - - /** - * Compress string and encode in a url safe form - * @param s - */ - function compressString(str) { - - const bytes = new Uint8Array(str.length); - for (var i = 0; i < str.length; i++) { - bytes[i] = str.charCodeAt(i); - } - const compressedBytes = new deflateRaw_1(bytes); // UInt8Arry - const compressedString = String.fromCharCode.apply(null, compressedBytes); // Convert to string - let enc = btoa(compressedString); - return enc.replace(/\+/g, '.').replace(/\//g, '_').replace(/=/g, '-'); // URL safe - } - - /** - * Uncompress the url-safe encoded compressed string, presumably created by compressString above - * - * @param enc - * @returns {string} - */ - function uncompressString(enc) { - - enc = enc.replace(/\./g, '+').replace(/_/g, '/').replace(/-/g, '='); - - const compressedString = atob(enc); - const compressedBytes = []; - for (let i = 0; i < compressedString.length; i++) { - compressedBytes.push(compressedString.charCodeAt(i)); - } - //const bytes = new Zlib.RawInflate(compressedBytes).decompress(); - const bytes = inflateRaw_1(compressedBytes); - - let str = ''; - for (let b of bytes) { - str += String.fromCharCode(b); - } - return str; - } - - - /** - * @param dataURI - * @returns {Array|Uint8Array} - */ - function decodeDataURI$1(dataURI, gzip) { - - const split = dataURI.split(','); - const info = split[0].split(':')[1]; - let dataString = split[1]; - - if (info.indexOf('base64') >= 0) { - dataString = atob(dataString); - - const bytes = new Uint8Array(dataString.length); - for (let i = 0; i < dataString.length; i++) { - bytes[i] = dataString.charCodeAt(i); - } - - let plain; - if (gzip || info.indexOf('gzip') > 0) { - plain = ungzip_1$1(bytes); - } else { - plain = bytes; - } - return plain - } else { - return decodeURIComponent(dataString); // URL encoded string -- not currently used or tested - } - } - - /* - * The MIT License (MIT) - * - * Copyright (c) 2016-2017 The Regents of the University of California - * Author: Jim Robinson - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - const IGVMath = { - - lerp: (v0, v1, t) => { - return (1 - t) * v0 + t * v1; - }, - - mean: function (array) { - - var t = 0, n = 0, - i; - for (i = 0; i < array.length; i++) { - if (!isNaN(array[i])) { - t += array[i]; - n++; - } - } - return n > 0 ? t / n : 0; - }, - - meanAndStdev: function (array) { - - var v, t = 0, t2 = 0, n = 0, i; - - for (i = 0; i < array.length; i++) { - - v = array[i]; - - if (!isNaN(v)) { - t += v; - t2 += v * v; - n++; - } - } - return n > 0 ? {mean: t / n, stdev: Math.sqrt(t2 - t * t / n)} : {mean: 0, stdev: 0}; - }, - - median: function (numbers) { - // median of [3, 5, 4, 4, 1, 1, 2, 3] = 3 - var median = 0, numsLen = numbers.length; - numbers.sort(); - - if ( - numsLen % 2 === 0 // is even - ) { - // average of two middle numbers - median = (numbers[numsLen / 2 - 1] + numbers[numsLen / 2]) / 2; - } else { // is odd - // middle number only - median = numbers[(numsLen - 1) / 2]; - } - - return median; - }, - - // Fast percentile function for "p" near edges. This needs profiled for p in middle (e.g. median) - percentile: function (array, p) { - - if (array.length === 0) return undefined; - - var k = Math.floor(array.length * ((100 - p) / 100)); - if (k === 0) { - array.sort(function (a, b) { - return b - a - }); - return array[k]; - } else { - return selectElement(array, k); - } - - }, - - - clamp: function (value, min, max) { - return Math.min(Math.max(value, min), max); - }, - - log2: function (x) { - return Math.log(x) / Math.LN2; - } - - }; - - function selectElement(array, k) { - - // Credit Steve Hanov http://stevehanov.ca/blog/index.php?id=122 - var heap = new BinaryHeap(), - i; - - for (i = 0; i < array.length; i++) { - - var item = array[i]; - - // If we have not yet found k items, or the current item is larger than - // the smallest item on the heap, add current item - if (heap.content.length < k || item > heap.content[0]) { - // If the heap is full, remove the smallest element on the heap. - if (heap.content.length === k) { - heap.pop(); - } - heap.push(item); - } - } - - return heap.content[0]; - } - - - function BinaryHeap() { - this.content = []; - } - - BinaryHeap.prototype = { - push: function (element) { - // Add the new element to the end of the array. - this.content.push(element); - // Allow it to bubble up. - this.bubbleUp(this.content.length - 1); - }, - - pop: function () { - // Store the first element so we can return it later. - var result = this.content[0]; - // Get the element at the end of the array. - var end = this.content.pop(); - // If there are any elements left, put the end element at the - // start, and let it sink down. - if (this.content.length > 0) { - this.content[0] = end; - this.sinkDown(0); - } - return result; - }, - - remove: function (node) { - var length = this.content.length; - // To remove a value, we must search through the array to find - // it. - for (var i = 0; i < length; i++) { - if (this.content[i] !== node) continue; - // When it is found, the process seen in 'pop' is repeated - // to fill up the hole. - var end = this.content.pop(); - // If the element we popped was the one we needed to remove, - // we're done. - if (i === length - 1) break; - // Otherwise, we replace the removed element with the popped - // one, and allow it to float up or sink down as appropriate. - this.content[i] = end; - this.bubbleUp(i); - this.sinkDown(i); - break; - } - }, - - size: function () { - return this.content.length; - }, - - bubbleUp: function (n) { - // Fetch the element that has to be moved. - var element = this.content[n], score = element; - // When at 0, an element can not go up any further. - while (n > 0) { - // Compute the parent element's index, and fetch it. - var parentN = Math.floor((n + 1) / 2) - 1, - parent = this.content[parentN]; - // If the parent has a lesser score, things are in order and we - // are done. - if (score >= parent) - break; - - // Otherwise, swap the parent with the current element and - // continue. - this.content[parentN] = element; - this.content[n] = parent; - n = parentN; - } - }, - - sinkDown: function (n) { - // Look up the target element and its score. - var length = this.content.length, - element = this.content[n], - elemScore = element; - - while (true) { - // Compute the indices of the child elements. - var child2N = (n + 1) * 2, child1N = child2N - 1; - // This is used to store the new position of the element, - // if any. - var swap = null; - // If the first child exists (is inside the array)... - if (child1N < length) { - // Look it up and compute its score. - var child1 = this.content[child1N], - child1Score = child1; - // If the score is less than our element's, we need to swap. - if (child1Score < elemScore) - swap = child1N; - } - // Do the same checks for the other child. - if (child2N < length) { - var child2 = this.content[child2N], - child2Score = child2; - if (child2Score < (swap == null ? elemScore : child1Score)) - swap = child2N; - } - - // No need to swap further, we are done. - if (swap == null) break; - - // Otherwise, swap and continue. - this.content[n] = this.content[swap]; - this.content[swap] = element; - n = swap; - } - } - }; - - /* - * The MIT License (MIT) - * - * Copyright (c) 2014 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - function _random(min, max) { - return Math.random() * (max - min) + min - } - - const IGVColor = { - - rgbListFromHSV: () => { - - let s = 1; - let accumulation = []; - for (let v = 1; v >= 0.5; v -= .1) { - for (let h = 0; h < 1; h += 1 / 28) { - const r = "rgb(" + IGVColor.hsvToRgb(h, s, v).join(",") + ")"; - accumulation.push(r); - } - } - - // add black - accumulation.pop(); - accumulation.push(IGVColor.rgbColor(16, 16, 16)); - - return accumulation - }, - - rgbToHex: function (rgb) { - rgb = rgb.match(/^rgba?[\s+]?\([\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?/i); - return (rgb && rgb.length === 4) ? "#" + - ("0" + parseInt(rgb[1], 10).toString(16)).slice(-2) + - ("0" + parseInt(rgb[2], 10).toString(16)).slice(-2) + - ("0" + parseInt(rgb[3], 10).toString(16)).slice(-2) : '' - }, - - hexToRgb: function (hex) { - - var cooked = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex); - - if (null === cooked) { - return undefined - } - - return "rgb(" + parseInt(cooked[1], 16) + "," + parseInt(cooked[2], 16) + "," + parseInt(cooked[3], 16) + ")" - }, - - /** - * Converts an HSV color value to RGB. Conversion formula - * adapted from http://en.wikipedia.org/wiki/HSV_color_space. - * Assumes h, s, and v are contained in the set [0, 1] and - * returns r, g, and b in the set [0, 255]. - * - * Credit: https://gist.githubusercontent.com/mjackson/5311256 - * - * @param h The hue - * @param s The saturation - * @param v The value - * @return Array The RGB representation - */ - hsvToRgb: function (h, s, v) { - var r, g, b; - - var i = Math.floor(h * 6); - var f = h * 6 - i; - var p = v * (1 - s); - var q = v * (1 - f * s); - var t = v * (1 - (1 - f) * s); - - switch (i % 6) { - case 0: - r = v, g = t, b = p; - break - case 1: - r = q, g = v, b = p; - break - case 2: - r = p, g = v, b = t; - break - case 3: - r = p, g = q, b = v; - break - case 4: - r = t, g = p, b = v; - break - case 5: - r = v, g = p, b = q; - break - } - - return [Math.floor(r * 255), Math.floor(g * 255), Math.floor(b * 255)] - }, - - /** - * Converts an HSL color value to RGB. Conversion formula - * adapted from http://en.wikipedia.org/wiki/HSL_color_space. - * Assumes h, s, and l are contained in the set [0, 1] and - * returns r, g, and b in the set [0, 255]. - * - * Credit: https://gist.githubusercontent.com/mjackson/5311256 - * - * @param h The hue - * @param s The saturation - * @param l The lightness - * @return Array The RGB representation - */ - hslToRgb: function (h, s, l) { - var r, g, b; - - if (s === 0) { - r = g = b = l; // achromatic - } else { - - - var q = l < 0.5 ? l * (1 + s) : l + s - l * s; - var p = 2 * l - q; - - r = IGVColor.hue2rgb(p, q, h + 1 / 3); - g = IGVColor.hue2rgb(p, q, h); - b = IGVColor.hue2rgb(p, q, h - 1 / 3); - } - - return [r * 255, g * 255, b * 255] - }, - - hue2rgb: (p, q, t) => { - if (t < 0) t += 1; - if (t > 1) t -= 1; - if (t < 1 / 6) return p + (q - p) * 6 * t - if (t < 1 / 2) return q - if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6 - return p - }, - - rgbaColor: function (r, g, b, a) { - - r = IGVMath.clamp(r, 0, 255); - g = IGVMath.clamp(g, 0, 255); - b = IGVMath.clamp(b, 0, 255); - a = IGVMath.clamp(a, 0.0, 1.0); - - return "rgba(" + r + "," + g + "," + b + "," + a + ")" - }, - - rgbColor: function (r, g, b) { - - r = IGVMath.clamp(r, 0, 255); - g = IGVMath.clamp(g, 0, 255); - b = IGVMath.clamp(b, 0, 255); - - return "rgb(" + r + "," + g + "," + b + ")" - }, - - greyScale: function (value) { - - var grey = IGVMath.clamp(value, 0, 255); - - return "rgb(" + grey + "," + grey + "," + grey + ")" - }, - - randomGrey: function (min, max) { - - min = IGVMath.clamp(min, 0, 255); - max = IGVMath.clamp(max, 0, 255); - - var g = Math.round(_random(min, max)).toString(10); - - return "rgb(" + g + "," + g + "," + g + ")" - }, - - randomRGB: function (min, max) { - - min = IGVMath.clamp(min, 0, 255); - max = IGVMath.clamp(max, 0, 255); - - var r = Math.round(_random(min, max)).toString(10); - var g = Math.round(_random(min, max)).toString(10); - var b = Math.round(_random(min, max)).toString(10); - - return "rgb(" + r + "," + g + "," + b + ")" - }, - - randomRGBConstantAlpha: function (min, max, alpha) { - - min = IGVMath.clamp(min, 0, 255); - max = IGVMath.clamp(max, 0, 255); - - var r = Math.round(_random(min, max)).toString(10); - var g = Math.round(_random(min, max)).toString(10); - var b = Math.round(_random(min, max)).toString(10); - - return "rgba(" + r + "," + g + "," + b + "," + alpha + ")" - }, - - addAlpha: function (color, alpha) { - - if (color === "0" || color === ".") { - color = "rgb(0,0,0)"; - } else { - const c = this.colorNameToHex(color); - if (c) { - color = c; - } - } - - var isHex = /(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(color); - - if (color.startsWith("rgba")) { - const idx = color.lastIndexOf(","); - return color.substring(0, idx + 1) + alpha.toString() + ")" - } - - if (isHex) { - color = IGVColor.hexToRgb(color); - } - - if (color.startsWith("rgb")) { - return color.replace("rgb", "rgba").replace(")", ", " + alpha + ")") - } else { - console.log(color + " is not an rgb style string"); - return color - } - }, - - rgbComponents: function (color) { - - if (color === "0" || color === ".") { - return [0, 0, 0] - } - const isHex = /(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(color); - if (isHex) { - color = IGVColor.hexToRgb(color); - } else { - if (!color.startsWith("rgb")) { - const hex = this.colorNameToHex(color); - color = this.hexToRgb(hex); - } - } - - if (color.startsWith("rgb(")) { - return color.substring(4, color.length - 1).split(",").map(s => Number.parseInt(s.trim())) - } else if (color.startsWith("rgba(")) { - return color.substring(5, color.length - 1).split(",").map((s, i) => { - s = s.trim(); - return i === 3 ? Number.parseFloat(s) : Number.parseInt(s) - }) - } else { - throw Error("Unrecognized color string: color") - } - }, - - /** - * - * @param dest RGB components as an array - * @param src RGB components as an array - * @param alpha alpha transparancy in the range 0-1 - * @returns {} - */ - getCompositeColor: function (dest, src, alpha) { - - var r = Math.floor(alpha * src[0] + (1 - alpha) * dest[0]), - g = Math.floor(alpha * src[1] + (1 - alpha) * dest[1]), - b = Math.floor(alpha * src[2] + (1 - alpha) * dest[2]); - - return "rgb(" + r + "," + g + "," + b + ")" - - }, - - /** - * Return a color represented by the string. If the string is not a recognized color format return the - * string itself. This function exists for backward compatibility, createColorStringSafe is preferredz - * @param str - */ - createColorString: function (str) { - // Excel will quote color strings, strip all quotes - const color = this.createColorStringSafe(str); - return color ? color : str - }, - - /** - * If str is a recognized color format return a string encoding the color - * @param str - */ - createColorStringSafe: function (str) { - // Excel will quote color strings, strip all quotes - str = stripQuotes$1(str); - - if (str.startsWith('rgb(') && str.endsWith(')')) { - return str - } - if (str.startsWith('#') && str.length < 8) { - return str - } - - // See if string is a recognized web color - const hex = this.colorNameToHex(str); - if (hex) { - return hex - } - - // UCSC format (e.g. 0,0,255) - const tokens = str.split(","); - if (tokens.length === 3 && isColorComponent(tokens[0]) && isColorComponent(tokens[1]) && isColorComponent(tokens[2])) { - return `rgb(${str})` - } - }, - - darkenLighten: function (color, amt) { - - let src; - let hexColor = this.colorNameToHex(color); - if (hexColor) { - src = IGVColor.hexToRgb(hexColor); - } else { - src = color.startsWith('rgb(') ? color : IGVColor.hexToRgb(color); - } - - const components = src.replace(")", "").substring(4).split(","); - - const r = Math.max(0, Math.min(255, Number.parseInt(components[0].trim()) + amt)); - const g = Math.max(0, Math.min(255, Number.parseInt(components[1].trim()) + amt)); - const b = Math.max(0, Math.min(255, Number.parseInt(components[2].trim()) + amt)); - - return 'rgb(' + r.toString() + ',' + g.toString() + ',' + b.toString() + ')' - - }, - - /** - * Convert html/css color name to hex value. Adapted from https://gist.github.com/mxfh/4719348 - * @param colorName - * @returns {*} - */ - colorNameToHex: function (colorName) { // color list from http://stackoverflow.com/q/1573053/731179 with added gray/gray - const definedColorNames = { - "aliceblue": "#f0f8ff", - "antiquewhite": "#faebd7", - "aqua": "#00ffff", - "aquamarine": "#7fffd4", - "azure": "#f0ffff", - "beige": "#f5f5dc", - "bisque": "#ffe4c4", - "black": "#000000", - "blanchedalmond": "#ffebcd", - "blue": "#0000ff", - "blueviolet": "#8a2be2", - "brown": "#a52a2a", - "burlywood": "#deb887", - "cadetblue": "#5f9ea0", - "chartreuse": "#7fff00", - "chocolate": "#d2691e", - "coral": "#ff7f50", - "cornflowerblue": "#6495ed", - "cornsilk": "#fff8dc", - "crimson": "#dc143c", - "cyan": "#00ffff", - "darkblue": "#00008b", - "darkcyan": "#008b8b", - "darkgoldenrod": "#b8860b", - "darkgray": "#a9a9a9", - "darkgreen": "#006400", - "darkkhaki": "#bdb76b", - "darkmagenta": "#8b008b", - "darkolivegreen": "#556b2f", - "darkorange": "#ff8c00", - "darkorchid": "#9932cc", - "darkred": "#8b0000", - "darksalmon": "#e9967a", - "darkseagreen": "#8fbc8f", - "darkslateblue": "#483d8b", - "darkslategray": "#2f4f4f", - "darkturquoise": "#00ced1", - "darkviolet": "#9400d3", - "deeppink": "#ff1493", - "deepskyblue": "#00bfff", - "dimgray": "#696969", - "dodgerblue": "#1e90ff", - "firebrick": "#b22222", - "floralwhite": "#fffaf0", - "forestgreen": "#228b22", - "fuchsia": "#ff00ff", - "gainsboro": "#dcdcdc", - "ghostwhite": "#f8f8ff", - "gold": "#ffd700", - "goldenrod": "#daa520", - "gray": "#808080", - "green": "#008000", - "greenyellow": "#adff2f", - "honeydew": "#f0fff0", - "hotpink": "#ff69b4", - "indianred ": "#cd5c5c", - "indigo ": "#4b0082", - "ivory": "#fffff0", - "khaki": "#f0e68c", - "lavender": "#e6e6fa", - "lavenderblush": "#fff0f5", - "lawngreen": "#7cfc00", - "lemonchiffon": "#fffacd", - "lightblue": "#add8e6", - "lightcoral": "#f08080", - "lightcyan": "#e0ffff", - "lightgoldenrodyellow": "#fafad2", - "lightgrey": "#d3d3d3", - "lightgreen": "#90ee90", - "lightpink": "#ffb6c1", - "lightsalmon": "#ffa07a", - "lightseagreen": "#20b2aa", - "lightskyblue": "#87cefa", - "lightslategray": "#778899", - "lightsteelblue": "#b0c4de", - "lightyellow": "#ffffe0", - "lime": "#00ff00", - "limegreen": "#32cd32", - "linen": "#faf0e6", - "magenta": "#ff00ff", - "maroon": "#800000", - "mediumaquamarine": "#66cdaa", - "mediumblue": "#0000cd", - "mediumorchid": "#ba55d3", - "mediumpurple": "#9370d8", - "mediumseagreen": "#3cb371", - "mediumslateblue": "#7b68ee", - "mediumspringgreen": "#00fa9a", - "mediumturquoise": "#48d1cc", - "mediumvioletred": "#c71585", - "midnightblue": "#191970", - "mintcream": "#f5fffa", - "mistyrose": "#ffe4e1", - "moccasin": "#ffe4b5", - "navajowhite": "#ffdead", - "navy": "#000080", - "oldlace": "#fdf5e6", - "olive": "#808000", - "olivedrab": "#6b8e23", - "orange": "#ffa500", - "orangered": "#ff4500", - "orchid": "#da70d6", - "palegoldenrod": "#eee8aa", - "palegreen": "#98fb98", - "paleturquoise": "#afeeee", - "palevioletred": "#d87093", - "papayawhip": "#ffefd5", - "peachpuff": "#ffdab9", - "peru": "#cd853f", - "pink": "#ffc0cb", - "plum": "#dda0dd", - "powderblue": "#b0e0e6", - "purple": "#800080", - "red": "#ff0000", - "rosybrown": "#bc8f8f", - "royalblue": "#4169e1", - "saddlebrown": "#8b4513", - "salmon": "#fa8072", - "sandybrown": "#f4a460", - "seagreen": "#2e8b57", - "seashell": "#fff5ee", - "sienna": "#a0522d", - "silver": "#c0c0c0", - "skyblue": "#87ceeb", - "slateblue": "#6a5acd", - "slategray": "#708090", - "snow": "#fffafa", - "springgreen": "#00ff7f", - "steelblue": "#4682b4", - "tan": "#d2b48c", - "teal": "#008080", - "thistle": "#d8bfd8", - "tomato": "#ff6347", - "turquoise": "#40e0d0", - "violet": "#ee82ee", - "wheat": "#f5deb3", - "white": "#ffffff", - "whitesmoke": "#f5f5f5", - "yellow": "#ffff00", - "yellowgreen": "#9acd32", - "darkgrey": "#a9a9a9", - "darkslategrey": "#2f4f4f", - "dimgrey": "#696969", - "grey": "#808080", - "lightgray": "#d3d3d3", - "lightslategrey": "#778899", - "slategrey": "#708090" - }; - return definedColorNames[colorName] - } - }; - - function isColorComponent(str) { - const num = Number.parseInt(str); - return !Number.isNaN(num) && num >= 0 && num <= 255 - } - - // Support for oauth token based authorization - // This class supports explicit setting of an oauth token either globally or for specific hosts. - // - // The variable oauth.google.access_token, which becomes igv.oauth.google.access_token on ES5 conversion is - // supported for backward compatibility - - const DEFAULT_HOST = "googleapis"; - - class Oauth { - - constructor() { - this.oauthTokens = {}; - } - - - setToken(token, host) { - host = host || DEFAULT_HOST; - this.oauthTokens[host] = token; - } - - getToken(host) { - host = host || DEFAULT_HOST; - let token; - for (let key of Object.keys(this.oauthTokens)) { - const regex = wildcardToRegExp(key); - if (regex.test(host)) { - token = this.oauthTokens[key]; - break - } - } - return token - } - - removeToken(host) { - host = host || DEFAULT_HOST; - for (let key of Object.keys(this.oauthTokens)) { - const regex = wildcardToRegExp(key); - if (regex.test(host)) { - this.oauthTokens[key] = undefined; - } - } - } - - // Special object for google -- legacy support - // google: { - // setToken: function (token) { - // oauth.setToken(token); - // } - // } - } - - - /** - * Creates a RegExp from the given string, converting asterisks to .* expressions, - * and escaping all other characters. - * - * credit https://gist.github.com/donmccurdy/6d073ce2c6f3951312dfa45da14a420f - */ - function wildcardToRegExp(s) { - return new RegExp('^' + s.split(/\*+/).map(regExpEscape).join('.*') + '$') - } - - /** - * RegExp-escapes all characters in the given string. - * - * credit https://gist.github.com/donmccurdy/6d073ce2c6f3951312dfa45da14a420f - */ - function regExpEscape(s) { - return s.replace(/[|\\{}()[\]^$+*?.]/g, '\\$&') - } - - function isGoogleURL$1(url) { - return (url.includes("googleapis") && !url.includes("urlshortener")) || - isGoogleStorageURL$1(url) || - isGoogleDriveURL$1(url) - } - - function isGoogleStorageURL$1(url) { - return url.startsWith("gs://") || - url.startsWith("https://www.googleapis.com/storage") || - url.startsWith("https://storage.cloud.google.com") || - url.startsWith("https://storage.googleapis.com"); - } - - function isGoogleDriveURL$1(url) { - return url.indexOf("drive.google.com") >= 0 || url.indexOf("www.googleapis.com/drive") > 0 - } - - /** - * Translate gs:// urls to https - * See https://cloud.google.com/storage/docs/json_api/v1 - * @param gsUrl - * @returns {string|*} - */ - function translateGoogleCloudURL(gsUrl) { - - let {bucket, object} = parseBucketName(gsUrl); - object = encode(object); - - const qIdx = gsUrl.indexOf('?'); - const paramString = (qIdx > 0) ? gsUrl.substring(qIdx) + "&alt=media" : "?alt=media"; - - return `https://storage.googleapis.com/storage/v1/b/${bucket}/o/${object}${paramString}` - } - - /** - * Parse a google bucket and object name from a google storage URL. Known forms include - * - * gs://BUCKET_NAME/OBJECT_NAME - * https://storage.googleapis.com/BUCKET_NAME/OBJECT_NAME - * https://storage.googleapis.com/storage/v1/b/BUCKET_NAME/o/OBJECT_NAME - * https://www.googleapis.com/storage/v1/b/BUCKET_NAME/o/OBJECT_NAME" - * https://storage.googleapis.com/download/storage/v1/b/BUCKET_NAME/o/OBJECT_NAME - * - * @param url - */ - function parseBucketName(url) { - - let bucket; - let object; - - if (url.startsWith("gs://")) { - const i = url.indexOf('/', 5); - if (i >= 0) { - bucket = url.substring(5, i); - const qIdx = url.indexOf('?'); - object = (qIdx < 0) ? url.substring(i + 1) : url.substring(i + 1, qIdx); - } - - } else if (url.startsWith("https://storage.googleapis.com") || url.startsWith("https://storage.cloud.google.com")) { - const bucketIdx = url.indexOf("/v1/b/", 8); - if (bucketIdx > 0) { - const objIdx = url.indexOf("/o/", bucketIdx); - if (objIdx > 0) { - const queryIdx = url.indexOf("?", objIdx); - bucket = url.substring(bucketIdx + 6, objIdx); - object = queryIdx > 0 ? url.substring(objIdx + 3, queryIdx) : url.substring(objIdx + 3); - } - - } else { - const idx1 = url.indexOf("/", 8); - const idx2 = url.indexOf("/", idx1+1); - const idx3 = url.indexOf("?", idx2); - if (idx2 > 0) { - bucket = url.substring(idx1+1, idx2); - object = idx3 < 0 ? url.substring(idx2+1) : url.substring(idx2+1, idx3); - } - } - - } else if (url.startsWith("https://www.googleapis.com/storage/v1/b")) { - const bucketIdx = url.indexOf("/v1/b/", 8); - const objIdx = url.indexOf("/o/", bucketIdx); - if (objIdx > 0) { - const queryIdx = url.indexOf("?", objIdx); - bucket = url.substring(bucketIdx + 6, objIdx); - object = queryIdx > 0 ? url.substring(objIdx + 3, queryIdx) : url.substring(objIdx + 3); - } - } - - if (bucket && object) { - return { - bucket, object - } - } else { - throw Error(`Unrecognized Google Storage URI: ${url}`) - } - - } - - /** - * Percent a GCS object name. See https://cloud.google.com/storage/docs/request-endpoints - * Specific characters to encode: - * !, #, $, &, ', (, ), *, +, ,, /, :, ;, =, ?, @, [, ], and space characters. - * @param obj - */ - - function encode(objectName) { - - let result = ''; - objectName.split('').forEach(function(letter) { - if(encodings$1.has(letter)) { - result += encodings$1.get(letter); - } else { - result += letter; - } - }); - return result; - } - - // %23 %24 %25 %26 %27 %28 %29 %2A %2B %2C %2F %3A %3B %3D %3F %40 %5B %5D - const encodings$1 = new Map(); - encodings$1.set("!", "%21"); - encodings$1.set("#", "%23"); - encodings$1.set("$", "%24"); - encodings$1.set("%", "%25"); - encodings$1.set("&", "%26"); - encodings$1.set("'", "%27"); - encodings$1.set("(", "%28"); - encodings$1.set(")", "%29"); - encodings$1.set("*", "%2A"); - encodings$1.set("+", "%2B"); - encodings$1.set(",", "%2C"); - encodings$1.set("/", "%2F"); - encodings$1.set(":", "%3A"); - encodings$1.set(";", "%3B"); - encodings$1.set("=", "%3D"); - encodings$1.set("?", "%3F"); - encodings$1.set("@", "%40"); - encodings$1.set("[", "%5B"); - encodings$1.set("]", "%5D"); - encodings$1.set(" ", "%20"); - - // Convenience functions for the gapi oAuth library. - - async function init$1$1(config) { - - if (!(google.accounts.oauth2.initTokenClient)) { - throw new Error("Google accounts token client not loaded (https://accounts.google.com/gsi/client)") - } - - if (isInitialized()) { - throw new Error("Google client is already initialized") - } - - // Note: callback is added when accessToken is requested - const codeClientConfig = { - client_id: config.client_id || config.clientId, - scope: config.scope || 'https://www.googleapis.com/auth/userinfo.profile', - state: config.state || 'igv', - error: (err) => { - throw new Error(err.type) - }, - hint: config.hint, // Optional - hosted_domain: config.hosted_domain // Optional - }; - - const tokenClient = google.accounts.oauth2.initTokenClient(codeClientConfig); - - // Attach an object to keep igv state - google.igv = { - tokenClient: tokenClient, - apiKey: config.apiKey - }; - } - - function isInitialized() { - return window.google && window.google.igv - } - - /** - * Return the current access token if the user is signed in, or undefined otherwise. This function does not - * attempt a signIn or request any specfic scopes. - * - * @returns access_token || undefined - */ - function getCurrentAccessToken() { - return (isInitialized() && google.igv.tokenResponse && Date.now() < google.igv.tokenExpiresAt) ? - google.igv.tokenResponse.access_token : - undefined - } - - - /** - * Return a promise for an access token for the given scope. If the user hasn't authorized the scope request it - * - * @param scope - * @returns {Promise} - */ - async function getAccessToken(scope) { - - if (!isInitialized()) { - throw Error("Google oAuth has not been initialized") - } - - if (google.igv.tokenResponse && - Date.now() < google.igv.tokenExpiresAt && - google.accounts.oauth2.hasGrantedAllScopes(google.igv.tokenResponse, scope)) { - return google.igv.tokenResponse.access_token - } else { - const tokenClient = google.igv.tokenClient; - return new Promise((resolve, reject) => { - try { - // Settle this promise in the response callback for requestAccessToken() - tokenClient.callback = (tokenResponse) => { - if (tokenResponse.error !== undefined) { - reject(tokenResponse); - } - google.igv.tokenResponse = tokenResponse; - google.igv.tokenExpiresAt = Date.now() + tokenResponse.expires_in * 1000; - resolve(tokenResponse.access_token); - }; - tokenClient.requestAccessToken({scope}); - } catch (err) { - console.log(err); - } - }) - } - } - - // gapi.auth2.getAuthInstance().isSignedIn.listen(status => { - // const user = gapi.auth2.getAuthInstance().currentUser.get() - // queryGoogleAuthenticationStatus(user, status) - // }) - - function getScopeForURL(url) { - if (isGoogleDriveURL$1(url)) { - return "https://www.googleapis.com/auth/drive.file" - } else if (isGoogleStorageURL$1(url)) { - return "https://www.googleapis.com/auth/devstorage.read_only" - } else { - return 'https://www.googleapis.com/auth/userinfo.profile' - } - } - - function getApiKey() { - return google.igv.apiKey - } - - /** - * Return information about a specific google drive URL - * - * @param googleDriveURL - * @returns {Promise} - */ - async function getDriveFileInfo(googleDriveURL) { - - const id = getGoogleDriveFileID$1(googleDriveURL); - let endPoint = "https://www.googleapis.com/drive/v3/files/" + id + "?supportsTeamDrives=true"; - const apiKey = getApiKey(); - if (apiKey) { - endPoint += "&key=" + apiKey; - } - const response = await fetch(endPoint); - let json = await response.json(); - if (json.error && json.error.code === 404) { - let scope = "https://www.googleapis.com/auth/drive.readonly"; - const access_token = await getAccessToken(scope); - if (access_token) { - const response = await fetch(endPoint, { - headers: { - 'Authorization': `Bearer ${access_token}` - } - }); - json = await response.json(); - if (json.error) { - throw Error(json.error); - } - } else { - throw Error(json.error); - } - } - return json; - } - - - function getDriveDownloadURL$1(link) { - // Return a google drive download url for the sharable link - //https://drive.google.com/open?id=0B-lleX9c2pZFbDJ4VVRxakJzVGM - //https://drive.google.com/file/d/1_FC4kCeO8E3V4dJ1yIW7A0sn1yURKIX-/view?usp=sharing - var id = getGoogleDriveFileID$1(link); - return id ? "https://www.googleapis.com/drive/v3/files/" + id + "?alt=media&supportsTeamDrives=true" : link; - } - - function getGoogleDriveFileID$1(link) { - - //https://drive.google.com/file/d/1_FC4kCeO8E3V4dJ1yIW7A0sn1yURKIX-/view?usp=sharing - //https://www.googleapis.com/drive/v3/files/1w-tvo6p1SH4p1OaQSVxpkV_EJgGIstWF?alt=media&supportsTeamDrives=true" - - if (link.includes("/open?id=")) { - const i1 = link.indexOf("/open?id=") + 9; - const i2 = link.indexOf("&"); - if (i1 > 0 && i2 > i1) { - return link.substring(i1, i2) - } else if (i1 > 0) { - return link.substring(i1); - } - - } else if (link.includes("/file/d/")) { - const i1 = link.indexOf("/file/d/") + 8; - const i2 = link.lastIndexOf("/"); - return link.substring(i1, i2); - - } else if (link.startsWith("https://www.googleapis.com/drive")) { - let i1 = link.indexOf("/files/"); - const i2 = link.indexOf("?"); - if (i1 > 0) { - i1 += 7; - return i2 > 0 ? - link.substring(i1, i2) : - link.substring(i1) - } - } - - throw Error("Unknown Google Drive url format: " + link); - - - } - - // The MIT License (MIT) - - /** - * @constructor - * @param {Object} options A set op options to pass to the throttle function - * @param {number} requestsPerSecond The amount of requests per second - * the library will limit to - */ - class Throttle { - constructor(options) { - this.requestsPerSecond = options.requestsPerSecond || 10; - this.lastStartTime = 0; - this.queued = []; - } - - /** - * Adds a promise - * @param {Function} async function to be executed - * @param {Object} options A set of options. - * @return {Promise} A promise - */ - add(asyncFunction, options) { - - var self = this; - return new Promise(function (resolve, reject) { - self.queued.push({ - resolve: resolve, - reject: reject, - asyncFunction: asyncFunction, - }); - self.dequeue(); - }); - } - - /** - * Adds all the promises passed as parameters - * @param {Function} promises An array of functions that return a promise - * @param {Object} options A set of options. - * @param {number} options.signal An AbortSignal object that can be used to abort the returned promise - * @param {number} options.weight A "weight" of each operation resolving by array of promises - * @return {Promise} A promise that succeeds when all the promises passed as options do - */ - addAll(promises, options) { - var addedPromises = promises.map(function (promise) { - return this.add(promise, options); - }.bind(this)); - - return Promise.all(addedPromises); - }; - - /** - * Dequeues a promise - * @return {void} - */ - dequeue() { - if (this.queued.length > 0) { - var now = new Date(), - inc = (1000 / this.requestsPerSecond) + 1, - elapsed = now - this.lastStartTime; - - if (elapsed >= inc) { - this._execute(); - } else { - // we have reached the limit, schedule a dequeue operation - setTimeout(function () { - this.dequeue(); - }.bind(this), inc - elapsed); - } - } - } - - /** - * Executes the promise - * @private - * @return {void} - */ - async _execute() { - this.lastStartTime = new Date(); - var candidate = this.queued.shift(); - const f = candidate.asyncFunction; - try { - const r = await f(); - candidate.resolve(r); - } catch (e) { - candidate.reject(e); - } - - } - - - } - - /* - * The MIT License (MIT) - * - * Copyright (c) 2014 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - class IGVXhr { - - constructor() { - this.apiKey = undefined; - this.googleThrottle = new Throttle({ - requestsPerSecond: 8 - }); - this.RANGE_WARNING_GIVEN = false; - this.oauth = new Oauth(); - } - - setApiKey(key) { - this.apiKey = key; - } - - async loadArrayBuffer(url, options) { - options = options || {}; - if (!options.responseType) { - options.responseType = "arraybuffer"; - } - if (isFile$1(url)) { - return this._loadFileSlice(url, options) - } else { - return this.load(url, options) - } - } - - /** - * A wrapper around loadArrayBuffer that inflates gzipped data - * @param url - * @param options - * @returns {Promise} - */ - async loadByteArray(url, options) { - const arraybuffer = await this.loadArrayBuffer(url, options); - let plain; - if (isgzipped(arraybuffer)) { - plain = ungzip_blocks(arraybuffer); - } else { - plain = new Uint8Array(arraybuffer); - } - return plain - } - - - async loadJson(url, options) { - options = options || {}; - const method = options.method || (options.sendData ? "POST" : "GET"); - if (method === "POST") { - options.contentType = "application/json"; - } - const result = await this.loadString(url, options); - if (result) { - return JSON.parse(result) - } else { - return result - } - } - - async loadString(path, options) { - options = options || {}; - if (path instanceof File) { - return this._loadStringFromFile(path, options) - } else { - return this._loadStringFromUrl(path, options) - } - } - - async load(url, options) { - - options = options || {}; - const urlType = typeof url; - - // Resolve functions, promises, and functions that return promises - url = await (typeof url === 'function' ? url() : url); - - if (isFile$1(url)) { - return this._loadFileSlice(url, options) - } else if (typeof url.startsWith === 'function') { // Test for string - if (url.startsWith("data:")) { - const buffer = decodeDataURI$1(url).buffer; - if (options.range) { - const rangeEnd = options.range.size ? options.range.start + options.range.size : buffer.byteLength; - return buffer.slice(options.range.start, rangeEnd) - } else { - return buffer - } - } else { - if (url.startsWith("https://drive.google.com")) { - url = getDriveDownloadURL$1(url); - } - if (isGoogleDriveURL$1(url) || url.startsWith("https://www.dropbox.com")) { - return this.googleThrottle.add(async () => { - return this._loadURL(url, options) - }) - } else { - return this._loadURL(url, options) - } - } - } else { - throw Error(`url must be either a 'File', 'string', 'function', or 'Promise'. Actual type: ${urlType}`) - } - } - - async _loadURL(url, options) { - - const self = this; - const _url = url; // The unmodified URL, needed in case of an oAuth retry - - url = mapUrl$1(url); - - options = options || {}; - - let oauthToken = options.oauthToken || this.getOauthToken(url); - if (oauthToken) { - oauthToken = await (typeof oauthToken === 'function' ? oauthToken() : oauthToken); - } - - return new Promise(function (resolve, reject) { - - // Various Google tansformations - if (isGoogleURL$1(url) && !isGoogleStorageSigned(url)) { - if (isGoogleStorageURL$1(url)) { - url = translateGoogleCloudURL(url); - } - url = addApiKey(url); - - if (isGoogleDriveURL$1(url)) { - addTeamDrive(url); - } - - // If we have an access token try it, but don't force a signIn or request for scopes yet - if (!oauthToken) { - oauthToken = getCurrentGoogleAccessToken(); - } - } - - const headers = options.headers || {}; - if (oauthToken) { - addOauthHeaders(headers, oauthToken); - } - const range = options.range; - - - const xhr = new XMLHttpRequest(); - const sendData = options.sendData || options.body; - const method = options.method || (sendData ? "POST" : "GET"); - const responseType = options.responseType; - const contentType = options.contentType; - const mimeType = options.mimeType; - - xhr.open(method, url); - - if (options.timeout) { - xhr.timeout = options.timeout; - } - - if (range) { - let rangeEnd = ""; - if (range.size) { - rangeEnd = range.start + range.size - 1; - } - xhr.setRequestHeader("Range", "bytes=" + range.start + "-" + rangeEnd); - // xhr.setRequestHeader("Cache-Control", "no-cache"); <= This can cause CORS issues, disabled for now - } - if (contentType) { - xhr.setRequestHeader("Content-Type", contentType); - } - if (mimeType) { - xhr.overrideMimeType(mimeType); - } - if (responseType) { - xhr.responseType = responseType; - } - if (headers) { - for (let key of Object.keys(headers)) { - const value = headers[key]; - xhr.setRequestHeader(key, value); - } - } - - // NOTE: using withCredentials with servers that return "*" for access-allowed-origin will fail - if (options.withCredentials === true) { - xhr.withCredentials = true; - } - - xhr.onload = async function (event) { - - // when the url points to a local file, the status is 0 - if (xhr.status === 0 || (xhr.status >= 200 && xhr.status <= 300)) { - if ("HEAD" === options.method) { - // Support fetching specific headers. Attempting to fetch all headers can be problematic with CORS - const headers = options.requestedHeaders || ['content-length']; - const headerMap = {}; - for (let h of headers) { - headerMap[h] = xhr.getResponseHeader(h); - } - resolve(headerMap); - } else { - // Assume "GET" or "POST" - if (range && xhr.status !== 206 && range.start !== 0) { - - // For small files a range starting at 0 can return the whole file => 200 - // Provide just the slice we asked for, throw out the rest quietly - // If file is large warn user - if (xhr.response.length > 100000 && !self.RANGE_WARNING_GIVEN) { - alert(`Warning: Range header ignored for URL: ${url}. This can have severe performance impacts.`); - } - resolve(xhr.response.slice(range.start, range.start + range.size)); - } else { - resolve(xhr.response); - } - } - } else if (xhr.status === 416) { - handleError(Error(`416 Unsatisfiable Range`)); - } else if (isInitialized() && - ((xhr.status === 404 || xhr.status === 401 || xhr.status === 403) && - isGoogleURL$1(url)) && - !options.retries) { - tryGoogleAuth(); - - } else { - if (xhr.status === 403) { - handleError("Access forbidden: " + url); - } else { - handleError(xhr.status); - } - } - }; - - - xhr.onerror = function (event) { - if (isGoogleURL$1(url) && !options.retries) { - tryGoogleAuth(); - } else { - handleError("Error accessing resource: " + url + " Status: " + xhr.status); - } - }; - - xhr.ontimeout = function (event) { - handleError("Timed out"); - }; - - xhr.onabort = function (event) { - console.log("Aborted"); - reject(event); - }; - - try { - xhr.send(sendData); - } catch (e) { - if (isGoogleURL$1(url) && !options.retries) { - tryGoogleAuth(); - } else { - handleError(e); - } - } - - - function handleError(error) { - if (reject) { - reject(error); - } else { - throw error - } - } - - async function tryGoogleAuth() { - try { - const accessToken = await fetchGoogleAccessToken(_url); - options.retries = 1; - options.oauthToken = accessToken; - const response = await self.load(_url, options); - resolve(response); - } catch (e) { - if (e.error) { - const msg = e.error.startsWith("popup_blocked") ? - "Google login popup blocked by browser." : - e.error; - alert(msg); - } else { - handleError(e); - } - } - } - }) - - } - - async _loadFileSlice(localfile, options) { - - let blob = (options && options.range) ? - localfile.slice(options.range.start, options.range.start + options.range.size) : - localfile; - - const arrayBuffer = await blob.arrayBuffer(); - - if ("arraybuffer" === options.responseType) { - return arrayBuffer - } else { - return arrayBufferToString(arrayBuffer) - } - } - - async _loadStringFromFile(localfile, options) { - - const blob = options.range ? localfile.slice(options.range.start, options.range.start + options.range.size) : localfile; - const arrayBuffer = await blob.arrayBuffer(); - return arrayBufferToString(arrayBuffer) - } - - async _loadStringFromUrl(url, options) { - - options = options || {}; - options.responseType = "arraybuffer"; - const data = await this.load(url, options); - return arrayBufferToString(data) - } - - /** - * Explicity set an oAuth token for use with given host. If host is undefined token is used for google api access* - * @param token - * @param host - */ - setOauthToken(token, host) { - this.oauth.setToken(token, host); - } - - /** - * Return an oauth token for the URL if we have one. This method does not force sign-in, and the token may - * or may not be valid. Sign-in is triggered on request failure. - * * - * @param url - * @returns {*} - */ - getOauthToken(url) { - - // Google is the default provider, don't try to parse host for google URLs - const host = isGoogleURL$1(url) ? - undefined : - parseUri(url).host; - - // First check the explicit settings (i.e. token set through the API) - let token = this.oauth.getToken(host); - if (token) { - return token - } else if (host === undefined) { - // Now try Google oauth tokens previously obtained. This will return undefined if google oauth is not - // configured. - const googleToken = getCurrentGoogleAccessToken(); - if (googleToken && googleToken.expires_at > Date.now()) { - return googleToken.access_token - } - } - } - - /** - * This method should only be called when it is known the server supports HEAD requests. It is used to recover - * from 416 errors from out-of-spec WRT range request servers. Notably Globus. - * * * - * @param url - * @param options - * @returns {Promise} - */ - async getContentLength(url, options) { - options = options || {}; - options.method = 'HEAD'; - options.requestedHeaders = ['content-length']; - const headerMap = await this._loadURL(url, options); - const contentLengthString = headerMap['content-length']; - return contentLengthString ? Number.parseInt(contentLengthString) : 0 - } - - } - - function isGoogleStorageSigned(url) { - return url.indexOf("X-Goog-Signature") > -1 - } - - - /** - * Return a Google oAuth token, triggering a sign in if required. This method should not be called until we know - * a token is required, that is until we've tried the url and received a 401, 403, or 404. - * - * @param url - * @returns the oauth token - */ - async function fetchGoogleAccessToken(url) { - if (isInitialized()) { - const scope = getScopeForURL(url); - const access_token = await getAccessToken(scope); - return access_token - } else { - throw Error( - `Authorization is required, but Google oAuth has not been initalized. Contact your site administrator for assistance.`) - } - } - - /** - * Return the current google access token, if one exists. Do not triger signOn or request additional scopes. - * @returns {undefined|access_token} - */ - function getCurrentGoogleAccessToken() { - if (isInitialized()) { - const access_token = getCurrentAccessToken(); - return access_token - } else { - return undefined - } - } - - function addOauthHeaders(headers, acToken) { - if (acToken) { - headers["Cache-Control"] = "no-cache"; - headers["Authorization"] = "Bearer " + acToken; - } - return headers - } - - - function addApiKey(url) { - let apiKey = igvxhr.apiKey; - if (!apiKey && typeof gapi !== "undefined") { - apiKey = gapi.apiKey; - } - if (apiKey !== undefined && !url.includes("key=")) { - const paramSeparator = url.includes("?") ? "&" : "?"; - url = url + paramSeparator + "key=" + apiKey; - } - return url - } - - function addTeamDrive(url) { - if (url.includes("supportsTeamDrive")) { - return url - } else { - const paramSeparator = url.includes("?") ? "&" : "?"; - url = url + paramSeparator + "supportsTeamDrive=true"; - } - } - - /** - * Perform some well-known url mappings. - * @param url - */ - function mapUrl$1(url) { - - if (url.startsWith("https://www.dropbox.com")) { - return url.replace("//www.dropbox.com", "//dl.dropboxusercontent.com") - } else if (url.startsWith("https://drive.google.com")) { - return getDriveDownloadURL$1(url) - } else if (url.includes("//www.broadinstitute.org/igvdata")) { - return url.replace("//www.broadinstitute.org/igvdata", "//data.broadinstitute.org/igvdata") - } else if (url.includes("//igvdata.broadinstitute.org")) { - return url.replace("//igvdata.broadinstitute.org", "//s3.amazonaws.com/igv.broadinstitute.org") - } else if (url.includes("//igv.genepattern.org")) { - return url.replace("//igv.genepattern.org", "//igv-genepattern-org.s3.amazonaws.com") - } else if (url.startsWith("ftp://ftp.ncbi.nlm.nih.gov/geo")) { - return url.replace("ftp://", "https://") - } else { - return url - } - } - - - function arrayBufferToString(arraybuffer) { - - let plain; - if (isgzipped(arraybuffer)) { - plain = ungzip_blocks(arraybuffer); - } else { - plain = new Uint8Array(arraybuffer); - } - - if ('TextDecoder' in getGlobalObject()) { - return new TextDecoder().decode(plain) - } else { - return decodeUTF8(plain) - } - } - - /** - * Use when TextDecoder is not available (primarily IE). - * - * From: https://gist.github.com/Yaffle/5458286 - * - * @param octets - * @returns {string} - */ - function decodeUTF8(octets) { - var string = ""; - var i = 0; - while (i < octets.length) { - var octet = octets[i]; - var bytesNeeded = 0; - var codePoint = 0; - if (octet <= 0x7F) { - bytesNeeded = 0; - codePoint = octet & 0xFF; - } else if (octet <= 0xDF) { - bytesNeeded = 1; - codePoint = octet & 0x1F; - } else if (octet <= 0xEF) { - bytesNeeded = 2; - codePoint = octet & 0x0F; - } else if (octet <= 0xF4) { - bytesNeeded = 3; - codePoint = octet & 0x07; - } - if (octets.length - i - bytesNeeded > 0) { - var k = 0; - while (k < bytesNeeded) { - octet = octets[i + k + 1]; - codePoint = (codePoint << 6) | (octet & 0x3F); - k += 1; - } - } else { - codePoint = 0xFFFD; - bytesNeeded = octets.length - i; - } - string += String.fromCodePoint(codePoint); - i += bytesNeeded + 1; - } - return string - } - - - function getGlobalObject() { - if (typeof self !== 'undefined') { - return self - } - if (typeof global !== 'undefined') { - return global - } else { - return window - } - } - - - const igvxhr = new IGVXhr(); - - /* - * The MIT License (MIT) - * - * Copyright (c) 2014 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - /** An implementation of an interval tree, following the explanation. - * from CLR. - * - * Public interface: - * Constructor IntervalTree - * Insertion insert - * Search findOverlapping - */ - - var BLACK = 1; - var RED = 2; - - var NIL = {}; - NIL.color = BLACK; - NIL.parent = NIL; - NIL.left = NIL; - NIL.right = NIL; - - - class IntervalTree { - - constructor() { - this.root = NIL; - } - - insert(start, end, value) { - - var interval = new Interval(start, end, value); - var x = new Node$1(interval); - this.treeInsert(x); - x.color = RED; - while (x !== this.root && x.parent.color === RED) { - if (x.parent === x.parent.parent.left) { - let y = x.parent.parent.right; - if (y.color === RED) { - x.parent.color = BLACK; - y.color = BLACK; - x.parent.parent.color = RED; - x = x.parent.parent; - } else { - if (x === x.parent.right) { - x = x.parent; - leftRotate.call(this, x); - } - x.parent.color = BLACK; - x.parent.parent.color = RED; - rightRotate.call(this, x.parent.parent); - } - } else { - let y = x.parent.parent.left; - if (y.color === RED) { - x.parent.color = BLACK; - y.color = BLACK; - x.parent.parent.color = RED; - x = x.parent.parent; - } else { - if (x === x.parent.left) { - x = x.parent; - rightRotate.call(this, x); - } - x.parent.color = BLACK; - x.parent.parent.color = RED; - leftRotate.call(this, x.parent.parent); - } - } - } - this.root.color = BLACK; - } - - /** - * - * @param start - query interval - * @param end - query interval - * @returns Array of all intervals overlapping the query region - */ - findOverlapping(start, end) { - - - var searchInterval = new Interval(start, end, 0); - - if (this.root === NIL) return []; - - var intervals = searchAll.call(this, searchInterval, this.root, []); - - if (intervals.length > 1) { - intervals.sort(function (i1, i2) { - return i1.low - i2.low; - }); - } - - return intervals; - } - - /** - * Dump info on intervals to console. For debugging. - */ - logIntervals() { - - logNode(this.root, 0); - - function logNode(node, indent) { - - var space = ""; - for (var i = 0; i < indent; i++) space += " "; - console.log(space + node.interval.low + " " + node.interval.high); // + " " + (node.interval.value ? node.interval.value : " null")); - - indent += 5; - - if (node.left !== NIL) logNode(node.left, indent); - if (node.right !== NIL) logNode(node.right, indent); - } - - } - - mapIntervals(func) { - - applyInterval(this.root); - - function applyInterval(node) { - - func(node.interval); - - if (node.left !== NIL) applyInterval(node.left); - if (node.right !== NIL) applyInterval(node.right); - } - } - - - /** - * Note: Does not maintain RB constraints, this is done post insert - * - * @param x a Node - */ - treeInsert(x) { - var node = this.root; - var y = NIL; - while (node !== NIL) { - y = node; - if (x.interval.low <= node.interval.low) { - node = node.left; - } else { - node = node.right; - } - } - x.parent = y; - - if (y === NIL) { - this.root = x; - x.left = x.right = NIL; - } else { - if (x.interval.low <= y.interval.low) { - y.left = x; - } else { - y.right = x; - } - } - - applyUpdate.call(this, x); - } - } - - function searchAll(interval, node, results) { - - if (node.interval.overlaps(interval)) { - results.push(node.interval); - } - - if (node.left !== NIL && node.left.max >= interval.low) { - searchAll.call(this, interval, node.left, results); - } - - if (node.right !== NIL && node.right.min <= interval.high) { - searchAll.call(this, interval, node.right, results); - } - - return results; - } - - function leftRotate(x) { - var y = x.right; - x.right = y.left; - if (y.left !== NIL) { - y.left.parent = x; - } - y.parent = x.parent; - if (x.parent === NIL) { - this.root = y; - } else { - if (x.parent.left === x) { - x.parent.left = y; - } else { - x.parent.right = y; - } - } - y.left = x; - x.parent = y; - - applyUpdate.call(this, x); - // no need to apply update on y, since it'll y is an ancestor - // of x, and will be touched by applyUpdate(). - } - - - function rightRotate(x) { - var y = x.left; - x.left = y.right; - if (y.right !== NIL) { - y.right.parent = x; - } - y.parent = x.parent; - if (x.parent === NIL) { - this.root = y; - } else { - if (x.parent.right === x) { - x.parent.right = y; - } else { - x.parent.left = y; - } - } - y.right = x; - x.parent = y; - - - applyUpdate.call(this, x); - // no need to apply update on y, since it'll y is an ancestor - // of x, and will be touched by applyUpdate(). - } - - - // Applies the statistic update on the node and its ancestors. - function applyUpdate(node) { - while (node !== NIL) { - var nodeMax = node.left.max > node.right.max ? node.left.max : node.right.max; - var intervalHigh = node.interval.high; - node.max = nodeMax > intervalHigh ? nodeMax : intervalHigh; - - var nodeMin = node.left.min < node.right.min ? node.left.min : node.right.min; - var intervalLow = node.interval.low; - node.min = nodeMin < intervalLow ? nodeMin : intervalLow; - - node = node.parent; - } - } - - - class Interval { - constructor(low, high, value) { - this.low = low; - this.high = high; - this.value = value; - } - - equals(other) { - if (!other) { - return false; - } - if (this === other) { - return true; - } - return (this.low === other.low && - this.high === other.high); - - } - - compareTo(other) { - if (this.low < other.low) - return -1; - if (this.low > other.low) - return 1; - - if (this.high < other.high) - return -1; - if (this.high > other.high) - return 1; - - return 0; - } - - /** - * Returns true if this interval overlaps the other. - */ - overlaps(other) { - return (this.low <= other.high && other.low <= this.high); - } - } - - function Node$1(interval) { - this.parent = NIL; - this.left = NIL; - this.right = NIL; - this.interval = interval; - this.color = RED; - } - - /* - * The MIT License (MIT) - * - * Copyright (c) 2014 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - /** - * Object for caching lists of features. Supports effecient queries for sub-range (chr, start, end) - * - * @param featureList - * @param The genomic range spanned by featureList (optional) - * @constructor - */ - - class FeatureCache$1 { - - constructor(featureList, genome, range) { - - featureList = featureList || []; - this.treeMap = this.buildTreeMap(featureList, genome); - this.range = range; - this.count = featureList.length; - } - - containsRange(genomicRange) { - // No range means cache contains all features - return (this.range === undefined || this.range.contains(genomicRange.chr, genomicRange.start, genomicRange.end)); - } - - queryFeatures(chr, start, end) { - - const tree = this.treeMap[chr]; - - if (!tree) return []; - - const intervals = tree.findOverlapping(start, end); - - if (intervals.length === 0) { - return []; - } else { - // Trim the list of features in the intervals to those - // overlapping the requested range. - // Assumption: features are sorted by start position - - const featureList = []; - const all = this.allFeatures[chr]; - if (all) { - for (let interval of intervals) { - const indexRange = interval.value; - for (let i = indexRange.start; i < indexRange.end; i++) { - let feature = all[i]; - if (feature.start > end) break; - else if (feature.end >= start) { - featureList.push(feature); - } - } - } - featureList.sort(function (a, b) { - return a.start - b.start; - }); - } - return featureList; - } - }; - - /** - * Returns all features, unsorted. - * - * @returns {Array} - */ - getAllFeatures() { - return this.allFeatures; - } - - buildTreeMap(featureList, genome) { - - const treeMap = {}; - const chromosomes = []; - this.allFeatures = {}; - - if (featureList) { - for (let feature of featureList) { - - let chr = feature.chr; - // Translate to "official" name - if (genome) { - chr = genome.getChromosomeName(chr); - } - - let geneList = this.allFeatures[chr]; - if (!geneList) { - chromosomes.push(chr); - geneList = []; - this.allFeatures[chr] = geneList; - } - geneList.push(feature); - } - - - // Now build interval tree for each chromosome - for (let chr of chromosomes) { - const chrFeatures = this.allFeatures[chr]; - chrFeatures.sort(function (f1, f2) { - return (f1.start === f2.start ? 0 : (f1.start > f2.start ? 1 : -1)); - }); - treeMap[chr] = buildIntervalTree$1(chrFeatures); - } - } - - return treeMap; - } - } - - /** - * Build an interval tree from the feature list for fast interval based queries. We lump features in groups - * of 10, or total size / 100, to reduce size of the tree. - * - * @param featureList - */ - function buildIntervalTree$1(featureList) { - - const tree = new IntervalTree(); - const len = featureList.length; - const chunkSize = Math.max(10, Math.round(len / 10)); - - for (let i = 0; i < len; i += chunkSize) { - const e = Math.min(len, i + chunkSize); - const subArray = new IndexRange(i, e); //featureList.slice(i, e); - const iStart = featureList[i].start; - // - let iEnd = iStart; - for (let j = i; j < e; j++) { - iEnd = Math.max(iEnd, featureList[j].end); - } - tree.insert(iStart, iEnd, subArray); - } - - return tree; - } - - - class IndexRange { - constructor(start, end) { - this.start = start; - this.end = end; - } - } - - /* - * The MIT License (MIT) - * - * Copyright (c) 2016-2017 The Regents of the University of California - * Author: Jim Robinson - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - const FeatureUtils = { - - packFeatures: function (features, maxRows, sorted) { - - var start; - var end; - - if (!features) return; - - maxRows = maxRows || 10000; - - if (!sorted) { - features.sort(function (a, b) { - return a.start - b.start; - }); - } - - - if (features.length === 0) { - return []; - - } else { - - var bucketList = [], - allocatedCount = 0, - lastAllocatedCount = 0, - nextStart, - row, - index, - bucket, - feature, - gap = 2, - bucketStart; - - start = features[0].start; - end = features[features.length - 1].start; - - bucketStart = Math.max(start, features[0].start); - nextStart = bucketStart; - - features.forEach(function (alignment) { - - var buckListIndex = Math.max(0, alignment.start - bucketStart); - if (bucketList[buckListIndex] === undefined) { - bucketList[buckListIndex] = []; - } - bucketList[buckListIndex].push(alignment); - }); - - - row = 0; - - - while (allocatedCount < features.length && row <= maxRows) { - - - while (nextStart <= end) { - - bucket = undefined; - - while (!bucket && nextStart <= end) { - - index = nextStart - bucketStart; - if (bucketList[index] === undefined) { - ++nextStart; // No buckets at this index - } else { - bucket = bucketList[index]; - } - - } // while (bucket) - - if (!bucket) { - break; - } - feature = bucket.pop(); - if (0 === bucket.length) { - bucketList[index] = undefined; - } - - feature.row = row; - - nextStart = feature.end + gap; - ++allocatedCount; - - } // while (nextStart) - - row++; - nextStart = bucketStart; - - if (allocatedCount === lastAllocatedCount) break; // Protect from infinite loops - - lastAllocatedCount = allocatedCount; - - } // while (allocatedCount) - - } - }, - - - /** - * Find features overlapping the given interval. It is assumed that all features share the same chromosome. - * - * TODO -- significant overlap with FeatureCache, refactor to combine - * - * @param featureList - * @param start - * @param end - */ - findOverlapping: function (featureList, start, end) { - - if (!featureList || featureList.length === 0) { - return []; - } else { - const tree = buildIntervalTree(featureList); - const intervals = tree.findOverlapping(start, end); - - if (intervals.length === 0) { - return []; - } else { - // Trim the list of features in the intervals to those - // overlapping the requested range. - // Assumption: features are sorted by start position - - featureList = []; - - intervals.forEach(function (interval) { - const intervalFeatures = interval.value; - const len = intervalFeatures.length; - for (let i = 0; i < len; i++) { - const feature = intervalFeatures[i]; - if (feature.start > end) break; - else if (feature.end > start) { - featureList.push(feature); - } - } - }); - - featureList.sort(function (a, b) { - return a.start - b.start; - }); - - return featureList; - } - } - - } - }; - - - /** - * Build an interval tree from the feature list for fast interval based queries. We lump features in groups - * of 10, or total size / 100, to reduce size of the tree. - * - * @param featureList - */ - function buildIntervalTree(featureList) { - - const tree = new IntervalTree(); - const len = featureList.length; - const chunkSize = Math.max(10, Math.round(len / 100)); - - featureList.sort(function (f1, f2) { - return (f1.start === f2.start ? 0 : (f1.start > f2.start ? 1 : -1)); - }); - - for (let i = 0; i < len; i += chunkSize) { - const e = Math.min(len, i + chunkSize); - const subArray = featureList.slice(i, e); - const iStart = subArray[0].start; - let iEnd = iStart; - subArray.forEach(function (feature) { - iEnd = Math.max(iEnd, feature.end); - }); - tree.insert(iStart, iEnd, subArray); - } - - return tree; - } - - const appleCrayonRGBPalette = - { - cantaloupe: {r: 255, g: 206, b: 110}, - honeydew: {r: 206, g: 250, b: 110}, - spindrift: {r: 104, g: 251, b: 208}, - sky: {r: 106, g: 207, b: 255}, - lavender: {r: 210, g: 120, b: 255}, - carnation: {r: 255, g: 127, b: 211}, - licorice: {r: 0, g: 0, b: 0}, - snow: {r: 255, g: 255, b: 255}, - salmon: {r: 255, g: 114, b: 110}, - banana: {r: 255, g: 251, b: 109}, - flora: {r: 104, g: 249, b: 110}, - ice: {r: 104, g: 253, b: 255}, - orchid: {r: 110, g: 118, b: 255}, - bubblegum: {r: 255, g: 122, b: 255}, - lead: {r: 30, g: 30, b: 30}, - mercury: {r: 232, g: 232, b: 232}, - tangerine: {r: 255, g: 136, b: 2}, - lime: {r: 131, g: 249, b: 2}, - sea_foam: {r: 3, g: 249, b: 135}, - aqua: {r: 0, g: 140, b: 255}, - grape: {r: 137, g: 49, b: 255}, - strawberry: {r: 255, g: 41, b: 135}, - tungsten: {r: 58, g: 58, b: 58}, - silver: {r: 208, g: 208, b: 208}, - maraschino: {r: 255, g: 33, b: 1}, - lemon: {r: 255, g: 250, b: 3}, - spring: {r: 5, g: 248, b: 2}, - turquoise: {r: 0, g: 253, b: 255}, - blueberry: {r: 0, g: 46, b: 255}, - magenta: {r: 255, g: 57, b: 255}, - iron: {r: 84, g: 84, b: 83}, - magnesium: {r: 184, g: 184, b: 184}, - mocha: {r: 137, g: 72, b: 0}, - fern: {r: 69, g: 132, b: 1}, - moss: {r: 1, g: 132, b: 72}, - ocean: {r: 0, g: 74, b: 136}, - eggplant: {r: 73, g: 26, b: 136}, - maroon: {r: 137, g: 22, b: 72}, - steel: {r: 110, g: 110, b: 110}, - aluminum: {r: 160, g: 159, b: 160}, - cayenne: {r: 137, g: 17, b: 0}, - aspargus: {r: 136, g: 133, b: 1}, - clover: {r: 2, g: 132, b: 1}, - teal: {r: 0, g: 134, b: 136}, - midnight: {r: 0, g: 24, b: 136}, - plum: {r: 137, g: 30, b: 136}, - tin: {r: 135, g: 134, b: 135}, - nickel: {r: 136, g: 135, b: 135} - }; - - function appleCrayonRGB(name) { - const {r, g, b} = appleCrayonRGBPalette[name]; - return `rgb(${r},${g},${b})` - } - - function appleCrayonRGBA(name, alpha) { - const {r, g, b} = appleCrayonRGBPalette[name]; - return `rgba(${r},${g},${b},${alpha})` - } - - const colorPalettes = { - - Set1: - [ - "rgb(228,26,28)", - "rgb(55,126,184)", - "rgb(77,175,74)", - "rgb(166,86,40)", - "rgb(152,78,163)", - "rgb(255,127,0)", - "rgb(247,129,191)", - "rgb(153,153,153)", - "rgb(255,255,51)" - ], - - Dark2: - [ - "rgb(27,158,119)", - "rgb(217,95,2)", - "rgb(117,112,179)", - "rgb(231,41,138)", - "rgb(102,166,30)", - "rgb(230,171,2)", - "rgb(166,118,29)", - "rgb(102,102,102)" - ], - - Set2: - [ - "rgb(102, 194,165)", - "rgb(252,141,98)", - "rgb(141,160,203)", - "rgb(231,138,195)", - "rgb(166,216,84)", - "rgb(255,217,47)", - "rgb(229,196,148)", - "rgb(179,179,179)" - ], - - Set3: - [ - "rgb(141,211,199)", - "rgb(255,255,179)", - "rgb(190,186,218)", - "rgb(251,128,114)", - "rgb(128,177,211)", - "rgb(253,180,98)", - "rgb(179,222,105)", - "rgb(252,205,229)", - "rgb(217,217,217)", - "rgb(188,128,189)", - "rgb(204,235,197)", - "rgb(255,237,111)" - ], - - Pastel1: - [ - "rgb(251,180,174)", - "rgb(179,205,227)", - "rgb(204,235,197)", - "rgb(222,203,228)", - "rgb(254,217,166)", - "rgb(255,255,204)", - "rgb(229,216,189)", - "rgb(253,218,236)" - ], - - Pastel2: - [ - "rgb(173,226,207)", - "rgb(253,205,172)", - "rgb(203,213,232)", - "rgb(244,202,228)", - "rgb(230,245,201)", - "rgb(255,242,174)", - "rgb(243,225,206)" - ], - - Accent: - [ - "rgb(127,201,127)", - "rgb(190,174,212)", - "rgb(253,192,134)", - "rgb(255,255,153)", - "rgb(56,108,176)", - "rgb(240,2,127)", - "rgb(191,91,23)" - ] - }; - - class PaletteColorTable { - - constructor(palette) { - this.colors = colorPalettes[palette]; - if (!Array.isArray(this.colors)) this.colors = []; - this.colorTable = {}; - this.nextIdx = 0; - this.colorGenerator = new RandomColorGenerator(); - } - - getColor(key) { - if (!this.colorTable.hasOwnProperty(key)) { - if (this.nextIdx < this.colors.length) { - this.colorTable[key] = this.colors[this.nextIdx]; - } else { - this.colorTable[key] = this.colorGenerator.get(); - } - this.nextIdx++; - } - return this.colorTable[key] - } - } - - class ColorTable { - constructor(colors) { - this.colorTable = colors || {}; - this.nextIdx = 0; - this.colorGenerator = new RandomColorGenerator(); - } - - getColor(key) { - if (!this.colorTable.hasOwnProperty(key)) { - if (this.colorTable.hasOwnProperty("*")) { - return this.colorTable["*"] - } - this.colorTable[key] = this.colorGenerator.get(); - } - return this.colorTable[key] - } - } - - // Random color generator from https://github.com/sterlingwes/RandomColor/blob/master/rcolor.js - // Free to use & distribute under the MIT license - // Wes Johnson (@SterlingWes) - // - // inspired by http://martin.ankerl.com/2009/12/09/how-to-create-random-colors-programmatically/ - function RandomColorGenerator() { - this.hue = Math.random(); - this.goldenRatio = 0.618033988749895; - this.hexwidth = 2; - } - - RandomColorGenerator.prototype.hsvToRgb = function (h, s, v) { - var h_i = Math.floor(h * 6), - f = h * 6 - h_i, - p = v * (1 - s), - q = v * (1 - f * s), - t = v * (1 - (1 - f) * s), - r = 255, - g = 255, - b = 255; - switch (h_i) { - case 0: - r = v, g = t, b = p; - break - case 1: - r = q, g = v, b = p; - break - case 2: - r = p, g = v, b = t; - break - case 3: - r = p, g = q, b = v; - break - case 4: - r = t, g = p, b = v; - break - case 5: - r = v, g = p, b = q; - break - } - return [Math.floor(r * 256), Math.floor(g * 256), Math.floor(b * 256)] - }; - - RandomColorGenerator.prototype.padHex = function (str) { - if (str.length > this.hexwidth) return str - return new Array(this.hexwidth - str.length + 1).join('0') + str - }; - - RandomColorGenerator.prototype.get = function (saturation, value) { - this.hue += this.goldenRatio; - this.hue %= 1; - if (typeof saturation !== "number") saturation = 0.5; - if (typeof value !== "number") value = 0.95; - var rgb = this.hsvToRgb(this.hue, saturation, value); - - return "#" + this.padHex(rgb[0].toString(16)) - + this.padHex(rgb[1].toString(16)) - + this.padHex(rgb[2].toString(16)) - - }; - - new RandomColorGenerator(); - - function randomRGB$1(min, max) { - - min = IGVMath.clamp(min, 0, 255); - max = IGVMath.clamp(max, 0, 255); - - const r = Math.round(Math.random() * (max - min) + min).toString(10); - const g = Math.round(Math.random() * (max - min) + min).toString(10); - const b = Math.round(Math.random() * (max - min) + min).toString(10); - return `rgb(${r},${g},${b})` - - } - - /* - * The MIT License (MIT) - * - * Copyright (c) 2014 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of ctx software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and ctx permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - - const IGVGraphics = { - - configureHighDPICanvas: function (ctx, w, h) { - - const scaleFactor = window.devicePixelRatio; - // const scaleFactor = 1 - - ctx.canvas.style.width = (`${w}px`); - ctx.canvas.width = Math.floor(scaleFactor * w); - - ctx.canvas.style.height = (`${h}px`); - ctx.canvas.height = Math.floor(scaleFactor * h); - - ctx.scale(scaleFactor, scaleFactor); - - }, - - setProperties: function (ctx, properties) { - - for (var key in properties) { - if (properties.hasOwnProperty(key)) { - var value = properties[key]; - ctx[key] = value; - } - } - }, - - strokeLine: function (ctx, x1, y1, x2, y2, properties) { - - x1 = Math.floor(x1) + 0.5; - y1 = Math.floor(y1) + 0.5; - x2 = Math.floor(x2) + 0.5; - y2 = Math.floor(y2) + 0.5; - - if (properties) { - ctx.save(); - IGVGraphics.setProperties(ctx, properties); - } - - ctx.beginPath(); - ctx.moveTo(x1, y1); - ctx.lineTo(x2, y2); - ctx.stroke(); - - if (properties) ctx.restore(); - }, - - fillRect: function (ctx, x, y, w, h, properties) { - x = Math.round(x); - y = Math.round(y); - - if (properties) { - ctx.save(); - IGVGraphics.setProperties(ctx, properties); - } - - ctx.fillRect(x, y, w, h); - - if (properties) ctx.restore(); - }, - - fillPolygon: function (ctx, x, y, properties) { - if (properties) { - ctx.save(); - IGVGraphics.setProperties(ctx, properties); - } - doPath(ctx, x, y); - ctx.fill(); - if (properties) ctx.restore(); - }, - - strokePolygon: function (ctx, x, y, properties) { - if (properties) { - ctx.save(); - IGVGraphics.setProperties(ctx, properties); - } - doPath(ctx, x, y); - ctx.stroke(); - if (properties) ctx.restore(); - }, - - fillText: function (ctx, text, x, y, properties, transforms) { - - if (properties || transforms) { - ctx.save(); - } - - if (properties) { - IGVGraphics.setProperties(ctx, properties); - } - - if (transforms) { - // Slow path with context saving and extra translate - ctx.translate(x, y); - - for (var transform in transforms) { - var value = transforms[transform]; - - // TODO: Add error checking for robustness - if (transform === 'translate') { - ctx.translate(value['x'], value['y']); - } - if (transform === 'rotate') { - ctx.rotate(value['angle'] * Math.PI / 180); - } - } - - ctx.fillText(text, 0, 0); - } else { - ctx.fillText(text, x, y); - } - - if (properties || transforms) ctx.restore(); - }, - - strokeText: function (ctx, text, x, y, properties, transforms) { - - - if (properties || transforms) { - ctx.save(); - } - - if (properties) { - IGVGraphics.setProperties(ctx, properties); - } - - if (transforms) { - ctx.translate(x, y); - - for (var transform in transforms) { - var value = transforms[transform]; - - // TODO: Add error checking for robustness - if (transform === 'translate') { - ctx.translate(value['x'], value['y']); - } - if (transform === 'rotate') { - ctx.rotate(value['angle'] * Math.PI / 180); - } - } - - ctx.strokeText(text, 0, 0); - } else { - ctx.strokeText(text, x, y); - } - - if (properties || transforms) ctx.restore(); - }, - - strokeCircle: function (ctx, x, y, radius, properties) { - if (properties) { - ctx.save(); - IGVGraphics.setProperties(ctx, properties); - } - ctx.beginPath(); - ctx.arc(x, y, radius, 0, 2 * Math.PI); - ctx.stroke(); - if (properties) ctx.restore(); - }, - - fillCircle: function (ctx, x, y, radius, properties) { - if (properties) { - ctx.save(); - IGVGraphics.setProperties(ctx, properties); - } - ctx.beginPath(); - ctx.arc(x, y, radius, 0, 2 * Math.PI); - ctx.fill(); - if (properties) ctx.restore(); - }, - - drawArrowhead: function (ctx, x, y, size, lineWidth) { - - ctx.save(); - if (!size) { - size = 5; - } - if (lineWidth) { - ctx.lineWidth = lineWidth; - } - ctx.beginPath(); - ctx.moveTo(x, y - size / 2); - ctx.lineTo(x, y + size / 2); - ctx.lineTo(x + size, y); - ctx.lineTo(x, y - size / 2); - ctx.closePath(); - ctx.fill(); - ctx.restore(); - }, - - dashedLine: function (ctx, x1, y1, x2, y2, dashLen, properties = {}) { - if (dashLen === undefined) dashLen = 2; - ctx.setLineDash([dashLen, dashLen]); - IGVGraphics.strokeLine(ctx, x1, y1, x2, y2, properties); - ctx.setLineDash([]); - }, - - roundRect: function (ctx, x, y, width, height, radius, fill, stroke) { - - if (typeof stroke == "undefined") { - stroke = true; - } - if (typeof radius === "undefined") { - radius = 5; - } - ctx.beginPath(); - ctx.moveTo(x + radius, y); - ctx.lineTo(x + width - radius, y); - ctx.quadraticCurveTo(x + width, y, x + width, y + radius); - ctx.lineTo(x + width, y + height - radius); - ctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height); - ctx.lineTo(x + radius, y + height); - ctx.quadraticCurveTo(x, y + height, x, y + height - radius); - ctx.lineTo(x, y + radius); - ctx.quadraticCurveTo(x, y, x + radius, y); - ctx.closePath(); - if (stroke) { - ctx.stroke(); - } - if (fill) { - ctx.fill(); - } - }, - polygon: function (ctx, x, y, fill, stroke) { - - if (typeof stroke == "undefined") { - stroke = true; - } - - ctx.beginPath(); - var len = x.length; - ctx.moveTo(x[0], y[0]); - for (var i = 1; i < len; i++) { - ctx.lineTo(x[i], y[i]); - // this.moveTo(x[i], y[i]); - } - - ctx.closePath(); - if (stroke) { - ctx.stroke(); - } - if (fill) { - ctx.fill(); - } - }, - - drawRandomColorVerticalLines: ctx => { - for (let x = 0; x < ctx.canvas.width; x++) { - IGVGraphics.fillRect(ctx, x, 0, 1, ctx.canvas.height, { fillStyle: randomRGB$1(100, 250) }); - } - }, - - labelTransformWithContext: (ctx, exe) => { - ctx.translate(exe, 0); - ctx.scale(-1, 1); - ctx.translate(-exe, 0); - } - - }; - - function doPath(ctx, x, y) { - - - var i, len = x.length; - for (i = 0; i < len; i++) { - x[i] = Math.round(x[i]); - y[i] = Math.round(y[i]); - } - - ctx.beginPath(); - ctx.moveTo(x[0], y[0]); - for (i = 1; i < len; i++) { - ctx.lineTo(x[i], y[i]); - } - ctx.closePath(); - } - - class Alert$2 { - constructor(parent) { - this.dialog = new AlertDialog$1(parent); - - } - - present(alert, callback) { - this.dialog.present(alert, callback); - } - } - - const FileFormats = { - - gwascatalog: { - fields: [ - 'bin', - 'chr', - 'start', - 'end', - 'name', - 'pubMedID', - 'author', - 'pubDate', - 'journal', - 'title', - 'trait', - 'initSample', - 'replSample', - 'region', - 'genes', - 'riskAllele', - 'riskAlFreq', - 'pValue', - 'pValueDesc', - 'orOrBeta', - 'ci95', - 'platform', - 'cnv' - ] - }, - - wgrna: { - fields: - [ - 'bin', - 'chr', - 'start', - 'end', - 'name', - 'score', - 'strand', - 'thickStart', - 'thickEnd', - 'type' - ] - }, - - cpgislandext: { - fields: - - [ - 'bin', - 'chr', - 'start', - 'end', - 'name', - 'length', - 'cpgNum', - 'gcNum', - 'perCpg', - 'perGc', - 'obsExp' - ] - }, - - clinVarMain: { - fields: [ - 'chr1', - 'start', - 'end', - 'name', - 'score', - 'strand', - 'thickStart', - 'thickEnd', - 'reserved', - 'blockCount', // Number of blocks - 'blockSizes', // Comma separated list of block sizes - 'chromStarts', // Start positions relative to chromStart - 'origName', // NM_198053.2(CD247):c.462C>T (p.Asp154=) ClinVar Variation Report - 'clinSign', // Likely benign Clinical significance - 'reviewStatus', // based on: criteria provided,single submitter Review Status - 'type', // single nucleotide variant Type of Variant - 'geneId', // CD247 Gene Symbol - 'snpId', // 181656780 dbSNP ID - 'nsvId', // dbVar ID - 'rcvAcc', // RCV000642347 ClinVar Allele Submission - 'testedInGtr', // N Genetic Testing Registry - 'phenotypeList', // Immunodeficiency due to defect in cd3-zeta Phenotypes - 'phenotype', // MedGen:C1857798, OMIM:610163 Phenotype identifiers - 'origin', // germline Data origin - 'assembly', // GRCh37 Genome assembly - 'cytogenetic', // 1q24.2 Cytogenetic status - 'hgvsCod', // NM_198053.2:c.462C>T Nucleotide HGVS - 'hgvsProt', // NP_932170.1:p.Asp154= Protein HGVS - 'numSubmit', // 1 Number of submitters - 'lastEval', // Dec 19,2017 Last evaluation - 'guidelines', // Guidelines - 'otherIds' - ] - } - }; - - /* - * The MIT License (MIT) - * - * Copyright (c) 2014 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - /** - * Test if the given value is a string or number. Not using typeof as it fails on boxed primitives. - * - * @param value - * @returns boolean - */ - - function isSimpleType(value) { - const simpleTypes = new Set(["boolean", "number", "string", "symbol"]); - const valueType = typeof value; - return (value !== undefined && (simpleTypes.has(valueType) || value.substring || value.toFixed)) - } - - function buildOptions$1(config, options) { - - var defaultOptions = { - oauthToken: config.oauthToken, - headers: config.headers, - withCredentials: config.withCredentials, - filename: config.filename - }; - - return Object.assign(defaultOptions, options) - } - - /** - * isMobile test from http://detectmobilebrowsers.com - * TODO -- improve UI design so this isn't neccessary - * @returns {boolean} - */ - - // igv.isMobile = function () { - // - // const a = (navigator.userAgent || navigator.vendor || window.opera); - // return (/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(a) || - // /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0, 4))) - // - // } - - const doAutoscale$1 = function (features) { - var min, max; - - if (features && features.length > 0) { - min = Number.MAX_VALUE; - max = -Number.MAX_VALUE; - - for(let f of features) { - if (!Number.isNaN(f.value)) { - min = Math.min(min, f.value); - max = Math.max(max, f.value); - } - } - - // Insure we have a zero baseline - if (max > 0) min = Math.min(0, min); - if (max < 0) max = 0; - } else { - // No features -- default - min = 0; - max = 100; - } - - return {min: min, max: max} - }; - - const validateGenomicExtent = function (chromosomeLengthBP, genomicExtent, minimumBP) { - - let ss = genomicExtent.start; - let ee = genomicExtent.end; - - if (undefined === ee) { - - ss -= minimumBP / 2; - ee = ss + minimumBP; - - if (ee > chromosomeLengthBP) { - ee = chromosomeLengthBP; - ss = ee - minimumBP; - } else if (ss < 0) { - ss = 0; - ee = minimumBP; - } - - } else if (ee - ss < minimumBP) { - - const center = (ee + ss) / 2; - - if (center - minimumBP / 2 < 0) { - ss = 0; - ee = ss + minimumBP; - } else if (center + minimumBP / 2 > chromosomeLengthBP) { - ee = chromosomeLengthBP; - ss = ee - minimumBP; - } else { - ss = center - minimumBP / 2; - ee = ss + minimumBP; - } - } - - genomicExtent.start = Math.ceil(ss); - genomicExtent.end = Math.floor(ee); - }; - - /*! - * is-number - * - * Copyright (c) 2014-present, Jon Schlinkert. - * Released under the MIT License. - */ - - const isNumber = function (num) { - if (typeof num === 'number') { - return num - num === 0 - } - if (typeof num === 'string' && num.trim() !== '') { - return Number.isFinite ? Number.isFinite(+num) : isFinite(+num) - } - return false - }; - - async function getFilename$1(url) { - if (isString$2(url) && url.startsWith("https://drive.google.com")) { - // This will fail if Google API key is not defined - if (getApiKey() === undefined) { - throw Error("Google drive is referenced, but API key is not defined. An API key is required for Google Drive access") - } - const json = await getDriveFileInfo(url); - return json.originalFileName || json.name - } else { - return getFilename$2(url) - } - } - - function prettyBasePairNumber(raw) { - - var denom, - units, - value, - floored; - - if (raw > 1e7) { - denom = 1e6; - units = " mb"; - } else if (raw > 1e4) { - - denom = 1e3; - units = " kb"; - - value = raw / denom; - floored = Math.floor(value); - return numberFormatter$1(floored) + units - } else { - return numberFormatter$1(raw) + " bp" - } - - value = raw / denom; - floored = Math.floor(value); - - return floored.toString() + units - } - - - function isDataURL(obj) { - return (isString$2(obj) && obj.startsWith("data:")) - } - - function createColumn(columnContainer, className) { - const column = domUtils$1.div({class: className}); - columnContainer.appendChild(column); - } - - - function insertElementBefore(element, referenceNode) { - referenceNode.parentNode.insertBefore(element, referenceNode); - } - - function insertElementAfter(element, referenceNode) { - referenceNode.parentNode.insertBefore(element, referenceNode.nextSibling); - } - - /** - * Test to see if page is loaded in a secure context, that is by https or is localhost. - */ - function isSecureContext() { - return window.location.protocol === "https:" || window.location.hostname === "localhost" - } - - // reference: https://pretagteam.com/question/find-element-height-including-margin - function getElementAbsoluteHeight(element) { - - // Get the DOM Node if you pass in a string - element = (typeof element === 'string') ? document.querySelector(element) : element; - - const styles = window.getComputedStyle(element); - const margin = parseFloat(styles['marginTop']) + parseFloat(styles['marginBottom']); - const height = element.offsetHeight; - - return Math.ceil(margin + height); - } - - /** - * Decoder for bedpe records. - * - * Bedpe format was created by Aaron Quinlan et al as part of the bedtools project. - * The spec is here: https://bedtools.readthedocs.io/en/latest/content/general-usage.html, - * - * 1 2 3 4 5 6 7 8 9 10 11- - * chrom1 start1 end1 chrom2 start2 end2 name score strand1 strand2 - * - * However there are off spec variants, an important one being a 7 column format with score in place of the standard - * name column. - * - * A common variant is a "hiccups" output file, which is standard bedpe with the exception of a header line - * of the form - * - * chr1 x1 x2 chr2 y1 y2 name score strand1 strand2 color observed expectedBL expectedDonut expectedH expectedV fdrBL fdrDonut fdrH fdrV - * - * The "hiccups" output is apparently not standardized as this is found at ENCODE, with a non-helpful "tsv" extension - * - * chr1 x1 x2 chr2 y1 y2 color observed expectedBL expectedDonut expectedH expectedV fdrBL fdrDonut fdrH fdrV numCollapsed centroid1 centroid2 radius - * chr9 136790000 136795000 chr9 136990000 136995000 0,255,255 101.0 31.100368 38.40316 56.948116 34.040756 1.1876738E-13 1.05936405E-13 2.5148233E-4 1.7220993E-13 1 136792500 136992500 25590 - * - * The "hiccups" documentation specfies yet another set of column headers - * chromosome1 x1 x2 chromosome2 y1 y2 color observed expected_bottom_left expected_donut expected_horizontal expected_vertical fdr_bottom_left fdr_donut fdr_horizontal fdr_vertical number_collapsed centroid1 centroid2 radius - * - * @param tokens - * @param ignore - * @returns {{start1: number, end2: number, end1: number, chr1: *, chr2: *, start2: number}|undefined} - */ - - function decodeBedpe(tokens, header) { - - if (tokens.length < 6) { - console.log("Skipping line: " + tokens.join(' ')); - return undefined - } - - var feature = { - chr1: tokens[0], - start1: Number.parseInt(tokens[1]), - end1: Number.parseInt(tokens[2]), - chr2: tokens[3], - start2: Number.parseInt(tokens[4]), - end2: Number.parseInt(tokens[5]) - }; - - if (isNaN(feature.start1) || isNaN(feature.end1) || isNaN(feature.start2) || isNaN(feature.end2)) { - //throw Error(`Error parsing line: ${tokens.join('\t')}`); - return undefined - } - - // Determine if this is a "hiccups" file. Store result on "header" so it doesn't need repeated for every feature - if(header && header.hiccups === undefined) { - header.hiccups = header.columnNames ? isHiccups(header.columnNames) : false; - } - const hiccups = header && header.hiccups; - const stdColumns = hiccups ? 6 : 10; - - if(!hiccups) { - if (tokens.length > 6 && tokens[6] !== ".") { - feature.name = tokens[6]; - } - - if (tokens.length > 7 && tokens[7] !== ".") { - feature.score = Number(tokens[7]); - } - - if (tokens.length > 8 && tokens[8] !== ".") { - feature.strand1 = tokens[8]; - } - - if (tokens.length > 9 && tokens[9] !== ".") { - feature.strand2 = tokens[9]; - } - } - - // Optional extra columns - if (header) { - const colorColumn = header.colorColumn; - if (colorColumn && colorColumn < tokens.length) { - feature.color = IGVColor.createColorString(tokens[colorColumn]); - } - const thicknessColumn = header.thicknessColumn; - if (thicknessColumn && thicknessColumn < tokens.length) { - feature.thickness = tokens[thicknessColumn]; - } - - if (tokens.length > stdColumns && header.columnNames && header.columnNames.length === tokens.length) { - feature.extras = tokens.slice(stdColumns); - } - } - - - // Set total extent of feature - if (feature.chr1 === feature.chr2) { - feature.chr = feature.chr1; - feature.start = Math.min(feature.start1, feature.start2); - feature.end = Math.max(feature.end1, feature.end2); - - } - return feature - } - - /** - * Hack for non-standard bedPE formats, where numeric score can be in column 7 (name field from spec) - * @param features - */ - function fixBedPE(features) { - - if (features.length == 0) return - - // Assume all features have same properties - const firstFeature = features[0]; - if (firstFeature.score === undefined && firstFeature.name !== undefined) { - // Name field (col 7) is sometimes used for score. - for (let f of features) { - if (!(isNumber(f.name) || f.name === '.')) return - } - for (let f of features) { - f.score = Number(f.name); - delete f.name; - } - } - - // Make copies of inter-chr features, one for each chromosome - const interChrFeatures = features.filter(f => f.chr1 !== f.chr2); - for (let f1 of interChrFeatures) { - const f2 = Object.assign({}, f1); - f2.dup = true; - features.push(f2); - - f1.chr = f1.chr1; - f1.start = f1.start1; - f1.end = f1.end1; - - f2.chr = f2.chr2; - f2.start = f2.start2; - f2.end = f2.end2; - } - } - - - /** - * Special decoder for Hic Domain files. In these files feature1 == feature2, they are really bed records. - * @param tokens - * @param ignore - * @returns {*} - */ - function decodeBedpeDomain(tokens, header) { - - if (tokens.length < 8) return undefined - - return { - chr: tokens[0], - start: Number.parseInt(tokens[1]), - end: Number.parseInt(tokens[2]), - color: IGVColor.createColorString(tokens[6]), - value: Number(tokens[7]) - } - } - - function isHiccups(columns) { - return columns && (columns.includes("fdrDonut") || columns.includes("fdr_donut")) - } - - /* - * The MIT License (MIT) - * - * Copyright (c) 2014 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - const knownFileExtensions = new Set([ - - "narrowpeak", - "broadpeak", - "regionpeak", - "peaks", - "bedgraph", - "wig", - "gff3", - "gff", - "gtf", - "fusionjuncspan", - "refflat", - "seg", - "aed", - "bed", - "vcf", - "bb", - "bigbed", - "biginteract", - "biggenepred", - "bignarrowpeak", - "bw", - "bigwig", - "bam", - "tdf", - "refgene", - "genepred", - "genepredext", - "bedpe", - "bp", - "snp", - "rmsk", - "cram", - "gwas", - "maf", - "mut", - "tsv", - "hiccups", - "fasta", - "fa", - "fna", - "pytor" - ]); - - /** - * Return a custom format object with the given name. - * @param name - * @returns {*} - */ - function getFormat(name) { - - if (FileFormats && FileFormats[name]) { - return expandFormat(FileFormats[name]) - } else { - return undefined - } - - function expandFormat(format) { - - const fields = format.fields; - const keys = ['chr', 'start', 'end']; - - for (let i = 0; i < fields.length; i++) { - for (let key of keys) { - if (key === fields[i]) { - format[key] = i; - } - } - } - - return format - } - } - - function inferFileFormat(fn) { - - var idx, ext; - - fn = fn.toLowerCase(); - - // Special case -- UCSC refgene files - if (fn.endsWith("refgene.txt.gz") || - fn.endsWith("refgene.txt.bgz") || - fn.endsWith("refgene.txt") || - fn.endsWith("refgene.sorted.txt.gz") || - fn.endsWith("refgene.sorted.txt.bgz")) { - return "refgene" - } - - - //Strip parameters -- handle local files later - idx = fn.indexOf("?"); - if (idx > 0) { - fn = fn.substr(0, idx); - } - - //Strip aux extensions .gz, .tab, and .txt - if (fn.endsWith(".gz")) { - fn = fn.substr(0, fn.length - 3); - } - - if (fn.endsWith(".txt") || fn.endsWith(".tab") || fn.endsWith(".bgz")) { - fn = fn.substr(0, fn.length - 4); - } - - - idx = fn.lastIndexOf("."); - ext = idx < 0 ? fn : fn.substr(idx + 1); - - switch (ext) { - case "bw": - return "bigwig" - case "bb": - return "bigbed" - case "fasta": - case "fa": - case "fna": - return "fasta" - default: - if (knownFileExtensions.has(ext)) { - return ext - } else { - return undefined - } - - } - - } - - function inferIndexPath(url, extension) { - - if (isString$2(url)) { - if (url.includes("?")) { - const idx = url.indexOf("?"); - return url.substring(0, idx) + "." + extension + url.substring(idx) - } else { - return url + "." + extension - } - } else { - return undefined - } - } - - - function inferTrackType(config) { - - translateDeprecatedTypes(config); - - if (config.type) { - return config.type - } - - if (config.format) { - const format = config.format.toLowerCase(); - switch (format) { - case "bw": - case "bigwig": - case "wig": - case "bedgraph": - case "tdf": - return "wig" - case "vcf": - return "variant" - case "seg": - return "seg" - case "mut": - case "maf": - return "mut" - case "bam": - case "cram": - return "alignment" - case "hiccups": - case "bedpe": - case "bedpe-loop": - case "biginteract": - return "interact" - case "bp": - return "arc" - case "gwas": - return "gwas" - case "bed": - case "bigbed": - case "bb": - case "biggenepred": - case "bignarrowpeak": - return "bedtype" - case "fasta": - return "sequence" - case "pytor": - return "cnvpytor" - default: - return "annotation" - } - } - } - - function translateDeprecatedTypes(config) { - - if (config.featureType) { // Translate deprecated "feature" type - config.type = config.type || config.featureType; - config.featureType = undefined; - } - if ("junctions" === config.type) { - config.type = "junction"; - } else if ("bed" === config.type) { - config.type = "annotation"; - config.format = config.format || "bed"; - } else if ("annotations" === config.type) { - config.type = "annotation"; - } else if ("alignments" === config.type) { - config.type = "alignment"; - } else if ("bam" === config.type) { - config.type = "alignment"; - config.format = "bam"; - } else if ("vcf" === config.type) { - config.type = "variant"; - config.format = "vcf"; - } else if ("t2d" === config.type) { - config.type = "gwas"; - } else if ("FusionJuncSpan" === config.type && !config.format) { - config.format = "fusionjuncspan"; - } else if ("aed" === config.type) { - config.type = "annotation"; - config.format = config.format || "aed"; - } - } - - /** - * Attempt to infer the file format by reading a few lines from the header. Currently this only supports "tsv" extensions, - * it was added specifically for "hiccups" type tsv files in ENCODE. Might be expanded in the future. - * - * @param url - * @returns {Promise} - */ - async function inferFileFormatFromHeader(config) { - - if (config.url) { - const firstBytes = await igvxhr.loadString(config.url, buildOptions$1(config, {range: {start: 0, size: 1000}})); - if(firstBytes) { - const columnNames = firstBytes.split('\n')[0].split('\t'); - if(isHiccups(columnNames)) { - return "hiccups" - } - } - } - - return undefined - - } - - function registerFileFormats(name, fields) { - FileFormats[name] = {fields: fields}; - } - - var TrackUtils = /*#__PURE__*/Object.freeze({ - __proto__: null, - knownFileExtensions: knownFileExtensions, - getFormat: getFormat, - inferFileFormat: inferFileFormat, - inferFileFormatFromHeader: inferFileFormatFromHeader, - inferTrackType: inferTrackType, - inferIndexPath: inferIndexPath, - registerFileFormats: registerFileFormats - }); - - const pairs = - [ - ['A', 'T'], - ['G', 'C'], - ['Y', 'R'], - ['W', 'S'], - ['K', 'M'], - ['D', 'H'], - ['B', 'V'] - ]; - - const complements = new Map(); - for (let p of pairs) { - const p1 = p[0]; - const p2 = p[1]; - complements.set(p1, p2); - complements.set(p2, p1); - complements.set(p1.toLowerCase(), p2.toLowerCase()); - complements.set(p2.toLowerCase(), p1.toLowerCase()); - } - - function reverseComplementSequence(sequence) { - - let comp = ''; - let idx = sequence.length; - while (idx-- > 0) { - const base = sequence[idx]; - comp += complements.has(base) ? complements.get(base) : base; - } - return comp - } - - class Chromosome { - constructor(name, order, bpLength) { - this.name = name; - this.order = order; - this.bpLength = bpLength; - } - } - - /* - * The MIT License (MIT) - * - * Copyright (c) 2014 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - const splitLines$4 = splitLines$5; - - const reservedProperties$1 = new Set(['fastaURL', 'indexURL', 'cytobandURL', 'indexed']); - - class NonIndexedFasta { - - - constructor(reference) { - - this.fastaURL = reference.fastaURL; - this.withCredentials = reference.withCredentials; - this.chromosomeNames = []; - this.chromosomes = {}; - this.sequences = new Map(); - - // Build a track-like config object from the referenceObject - const config = {}; - for (let key in reference) { - if (reference.hasOwnProperty(key) && !reservedProperties$1.has(key)) { - config[key] = reference[key]; - } - } - this.config = config; - } - - - async init() { - return this.loadAll() - } - - async getSequence(chr, start, end) { - - if (!this.sequences.has(chr)) { - return undefined - } - - let seqSlice = this.sequences.get(chr).find(ss => ss.contains(start, end)); - if (!seqSlice) { - seqSlice = this.sequences.get(chr).find(ss => ss.overlaps(start, end)); - if (!seqSlice) { - return undefined - } - } - - start -= seqSlice.offset; - end -= seqSlice.offset; - - let prefix = ""; - if (start < 0) { - for (let i = start; i < Math.min(end, 0); i++) { - prefix += "*"; - } - } - - if (end <= 0) { - return Promise.resolve(prefix) - } - - const seq = seqSlice.sequence; - const seqEnd = Math.min(end, seq.length); - return prefix + seq.substring(start, seqEnd) - } - - async loadAll() { - - let data; - if (isDataURL(this.fastaURL)) { - let bytes = decodeDataURI$1(this.fastaURL); - data = ""; - for (let b of bytes) { - data += String.fromCharCode(b); - } - } else { - data = await igvxhr.load(this.fastaURL, buildOptions$1(this.config)); - } - - const chrNameSet = new Set(); - const lines = splitLines$4(data); - const len = lines.length; - let lineNo = 0; - let order = 0; - let nextLine; - let current = {}; - while (lineNo < len) { - nextLine = lines[lineNo++].trim(); - if (nextLine.startsWith("#") || nextLine.length === 0) ; else if (nextLine.startsWith(">")) { - // Start the next sequence - if(current && current.seq) { - pushChromosome.call(this, current, order++); - } - - const parts = nextLine.substr(1).split(/\s+/); - - // Check for samtools style locus string. This is not perfect, and could fail on weird sequence names - const nameParts = parts[0].split(':'); - current.chr = nameParts[0]; - current.seq = ""; - current.offset = 0; - if (nameParts.length > 1 && nameParts[1].indexOf('-') > 0) { - const locusParts = nameParts[1].split('-'); - if (locusParts.length === 2 && - /^[0-9]+$/.test(locusParts[0]) && - /^[0-9]+$/.test(locusParts[1])) ; - const from = Number.parseInt(locusParts[0]); - const to = Number.parseInt(locusParts[1]); - if (to > from) { // TODO this should be an error - current.offset = from - 1; - } - - // Check for chromosome length token - if (parts.length > 1 && parts[1].startsWith("@len=")) { - try { - current.length = parseInt(parts[1].trim().substring(5)); - } catch (e) { - current.length = undefined; - console.error(`Error parsing sequence length for ${nextLine}`); - } - } else { - current.length = undefined; - } - } - } else { - current.seq += nextLine; - } - // add last seq - if (current && current.seq) { - pushChromosome.call(this, current, order); - } - } - - function pushChromosome(current, order) { - const length = current.length || (current.offset + current.seq.length); - if (!chrNameSet.has(current.chr)) { - this.chromosomeNames.push(current.chr); - this.sequences.set(current.chr, []); - this.chromosomes[current.chr] = new Chromosome(current.chr, order, length); - chrNameSet.add(current.chr); - } else { - const c = this.chromosomes[current.chr]; - c.bpLength = Math.max(c.bpLength, length); - } - this.sequences.get(current.chr).push(new SequenceSlice(current.offset, current.seq)); - } - } - } - - class SequenceSlice { - - constructor(offset, sequence) { - this.offset = offset; - this.sequence = sequence; - } - - contains(start, end) { - return this.offset <= start && this.end >= end - } - - overlaps(start, end) { - return this.offset < end && this.end > start - } - - get end() { - return this.offset + this.sequence.length - } - - } - - const GenomicInterval = function (chr, start, end, features) { - this.chr = chr; - this.start = start; - this.end = end; - this.features = features; - }; - - GenomicInterval.prototype.contains = function (chr, start, end) { - return this.chr === chr && - this.start <= start && - this.end >= end - }; - - GenomicInterval.prototype.containsRange = function (range) { - return this.chr === range.chr && - this.start <= range.start && - this.end >= range.end - }; - - /* - * The MIT License (MIT) - * - * Copyright (c) 2014 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - const splitLines$3 = splitLines$5; - - const reservedProperties = new Set(['fastaURL', 'indexURL', 'compressedIndexURL', 'cytobandURL', 'indexed']); - - class FastaSequence { - - constructor(reference) { - - this.file = reference.fastaURL; - this.indexFile = reference.indexURL || reference.indexFile || this.file + ".fai"; - this.compressedIndexFile = reference.compressedIndexURL || false; - this.withCredentials = reference.withCredentials; - this.chromosomeNames = []; - this.chromosomes = {}; - this.sequences = {}; - this.offsets = {}; - - // Build a track-like config object from the referenceObject - const config = {}; - for (let key in reference) { - if (reference.hasOwnProperty(key) && !reservedProperties.has(key)) { - config[key] = reference[key]; - } - } - this.config = config; - } - - - async init() { - return this.getIndex() - } - - async getSequence(chr, start, end) { - - const hasCachedSquence = this.interval && this.interval.contains(chr, start, end); - - if (!hasCachedSquence) { - - // Expand query, to minimum of 50kb - let qstart = start; - let qend = end; - if ((end - start) < 50000) { - const w = (end - start); - const center = Math.round(start + w / 2); - qstart = Math.max(0, center - 25000); - qend = center + 25000; - } - - const seqBytes = await this.readSequence(chr, qstart, qend); - this.interval = new GenomicInterval(chr, qstart, qend, seqBytes); - } - - const offset = start - this.interval.start; - const n = end - start; - const seq = this.interval.features ? this.interval.features.substr(offset, n) : null; - return seq - } - - async getIndex() { - - if (this.index) { - return this.index - } else { - const data = await igvxhr.load(this.indexFile, buildOptions$1(this.config)); - const lines = splitLines$3(data); - const len = lines.length; - let lineNo = 0; - let order = 0; - this.index = {}; - - while (lineNo < len) { - const tokens = lines[lineNo++].split("\t"); - const nTokens = tokens.length; - - if (nTokens === 5) { - // Parse the index line. - const chr = tokens[0]; - const size = parseInt(tokens[1]); - const position = parseInt(tokens[2]); - const basesPerLine = parseInt(tokens[3]); - const bytesPerLine = parseInt(tokens[4]); - - const indexEntry = { - size: size, - position: position, - basesPerLine: basesPerLine, - bytesPerLine: bytesPerLine - }; - - this.chromosomeNames.push(chr); - this.index[chr] = indexEntry; - this.chromosomes[chr] = new Chromosome(chr, order++, size); - } - } - return this.index - } - } - - - //Code is losely based on https://github.com/GMOD/bgzf-filehandle - //Reworked however in orde to work with the igvxhr interface for loading files - //Additionally, replaced calls to the Long.js interface with standard JS calls for ArrayBuffers and the associated views - // - //The compressed index is an array of blocks, with each block being a pair: compressed-position & uncompressed-position (both in bytes) - async getCompressedIndex() { - const GZI_NUM_BYTES_OFFSET = 8; - const GZI_NUM_BYTES_BLOCK = 8; - if (this.compressedIndex) { - return this.compressedIndex - } - if (!this.compressedIndexFile) { - this.compressedIndex = []; - return this.compressedIndex - } - //In contrast to the 'normal' reference (for which the index is chromosome based), this index is block-based - //As such there is not need to make it a hash. An array is sufficient. - this.compressedIndex = []; - const gziData = await igvxhr.loadArrayBuffer(this.compressedIndexFile, buildOptions$1(this.config)); - const givenFileSize = gziData.byteLength; - if (givenFileSize < GZI_NUM_BYTES_OFFSET) { - console.log("Cannot parse GZI index file: length (" + givenFileSize + " bytes) is insufficient to determine content of index."); - return this.compressedIndex - } - //First 8 bytes are a little endian unsigned bigint (64bit), indicating the number of blocks in the index. - const numBlocksBuffer = gziData.slice(0, GZI_NUM_BYTES_OFFSET); - const numBlocks = Number((new DataView(numBlocksBuffer)).getBigUint64(0, true)); - //The remainder of the gzi content are pairs of little endian unsigned bigint (64bit) numbers. - //The first of the pair is the compressed position of a block - //The second of the pair is the uncompressed position of a block - - //Sanity check: - //Is the size of the array-buffer (of the entire file) correct with regards to the number of blocks detailled by the first 8 bytes of the file? - //Total file-size should be: - // 8 + 2*(num_entries*8) bytes, with the first 8 bytes indicating the number of entries - const expectedFileSize = GZI_NUM_BYTES_OFFSET + numBlocks * 2 * GZI_NUM_BYTES_BLOCK; - if (givenFileSize != expectedFileSize) { - console.log("Incorrect file size of reference genome index. Expected : " + expectedFileSize + ". Received : " + givenFileSize); - return this.compressedIndex - } - - //Push the first block to the index: the first block always has positions 0 for both the compressed and uncompressed file - this.compressedIndex.push([0, 0]); - - //Further process all the blocks of the GZI index, and keep them in memory - for (let blockNumber = 0; blockNumber < numBlocks; blockNumber++) { - const bufferBlockStart = GZI_NUM_BYTES_OFFSET + blockNumber * 2 * GZI_NUM_BYTES_BLOCK; - const bufferBlockEnd = GZI_NUM_BYTES_OFFSET + blockNumber * 2 * GZI_NUM_BYTES_BLOCK + 2 * GZI_NUM_BYTES_BLOCK; - const bufferBlock = gziData.slice(bufferBlockStart, bufferBlockEnd); - const viewBlock = new DataView(bufferBlock); - const compressedPosition = Number(viewBlock.getBigUint64(0, true)); //First 8 bytes - const uncompressedPosition = Number(viewBlock.getBigUint64(GZI_NUM_BYTES_BLOCK, true)); //Last 8 bytes - this.compressedIndex.push([compressedPosition, uncompressedPosition]); - } - return this.compressedIndex - } - - //The Fasta-index gives a byte-position of the chromosomal sequences within the FASTA file. - //These locations need to be remapped to the locations within the zipped reference genome, using the GZI index - //This function provides this functionality by - //1) taking the indicated start/stop byte locations within the UNCOMPRESSED FASTA file - //2) remapping these byte locations to the correct blocks (and associated positions) within the COMPRESSED FASTA file - //Subsequently, the calling method can then extract the correct blocks from the compressed FASTA files and uncompressed the data - async getRelevantCompressedBlockNumbers(queryPositionStart, queryPositionEnd) { - const UNCOMPRESSED_POSITION = 1; - //Fallback for impossible values - if (queryPositionStart < 0 || queryPositionEnd < 0 || queryPositionEnd < queryPositionStart) { - console.log("Incompatible query positions for reference-genome. Start:" + queryPositionStart + " | End:" + queryPositionEnd); - return [] - } - //Ensure compressed index is loaded - await this.getCompressedIndex(); - let result = []; - //Now search for the correct block-numbers (going from 0 to length(compressed-index)) which overlap with the provided byte-positions - const lowestBlockNumber = 0; - const highestBlockNumber = this.compressedIndex.length - 1; - //Failsafe if for some reason the compressed index wasn't loaded or doesn't contain any data - if (this.compressedIndex.length == 0) { - console.log("Compressed index does not contain any content"); - return [] - } - //Failsafe: if the queryPositionStart is greater than the uncompressed-position of the final block, - //then this final block is the only possible result - if (queryPositionStart > (this.compressedIndex)[highestBlockNumber][UNCOMPRESSED_POSITION]) { - return [highestBlockNumber] - } - - //Rather than doing a linear search over all blocks, a binary search is done for speed considerations - //We are searching for the highest block number for which its position is smaller than the query start position - //Afterwards we will simply expand the blocks until the entire query range is covered - let searchLow = lowestBlockNumber; - let searchHigh = highestBlockNumber; - let searchPosition = Math.floor(this.compressedIndex.length / 2); - let maxIterations = this.compressedIndex.length + 1; - let solutionFound = false; - //instead of doing a while(true), this for-loop prevents eternal loops in case of issues - for (let iteration = 0; iteration < maxIterations; iteration++) { - const searchUncompressedPosition = (this.compressedIndex)[searchPosition][UNCOMPRESSED_POSITION]; - const nextSearchUncompressedPosition = (searchPosition < (this.compressedIndex.length - 1)) ? (this.compressedIndex)[searchPosition + 1][UNCOMPRESSED_POSITION] : Infinity; - //The query position lies within the current search block - if (searchUncompressedPosition <= queryPositionStart && nextSearchUncompressedPosition > queryPositionStart) { - solutionFound = true; - break //searchPosition is the correct block number index - } - //Current block lies before the query position - else if (searchUncompressedPosition < queryPositionStart) { - searchLow = searchPosition + 1; - } - //Current block lies after the query position - else { - searchHigh = searchPosition - 1; - } - searchPosition = Math.ceil((searchHigh - searchLow) / 2) + searchLow; - } - //If for some reason the binary search did not reveal a correct block index, then we return the empty result - if (!solutionFound) { - console.log("No blocks within compressed index found that correspond with query positions " + queryPositionStart + "," + queryPositionEnd); - console.log(this.compressedIndex); - return [] - } - - //Now extend the result by adding additional blocks until the entire query range is covered - result.push(searchPosition); - for (let blockIndex = searchPosition + 1; blockIndex < this.compressedIndex.length; blockIndex++) { - result.push(blockIndex); - const blockUncompressedPosition = (this.compressedIndex)[blockIndex][UNCOMPRESSED_POSITION]; - if (blockUncompressedPosition >= queryPositionEnd) { - break - } - } - - //It is possible that the query end position lies AFTER the start of the final block - //If this is the case, we add a 'fake' negative index which will be interpreted by the loadAndUncompressBlocks method as an indicator - //to read until the end of the file - const finalRelevantBlock = result[result.length - 1]; - const finalIndexBlock = this.compressedIndex.length - 1; - if (finalRelevantBlock === finalIndexBlock && (this.compressedIndex)[finalRelevantBlock][UNCOMPRESSED_POSITION] < queryPositionEnd) { - result.push(-1); - } - - return result - } - - - //Load the content from the blockIndices. - //This is done on a per-block basis - //Content of the first block will be trimmed in order to match the expected offset - async loadAndUncompressBlocks(blockIndices, startByte) { - const COMPRESSED_POSITION = 0; - const UNCOMPRESSED_POSITION = 1; - //Normally the compressed index should already exist, we're just makeing sure here - await this.getCompressedIndex(); - - if (blockIndices.length == 0) { - return "" - } - - //Storing data in seperate array with indices in order to assert order due to async behaviour of loops - let resultCache = Array(blockIndices.length - 1); - for (let i = 0; i < blockIndices.length - 1; i++) { - const currentBlockNumber = blockIndices[i]; - const currentBlockInfo = (this.compressedIndex)[currentBlockNumber]; - const currentBlockCompressedPosition = currentBlockInfo[COMPRESSED_POSITION]; - - const nextBlockNumber = blockIndices[i + 1]; - let compressedBytes = []; - if (nextBlockNumber != -1) { //default : read current entire block only - const nextBlockInfo = (this.compressedIndex)[nextBlockNumber]; - const nextBlockCompressedPosition = nextBlockInfo[COMPRESSED_POSITION]; - const compressedLength = nextBlockCompressedPosition - currentBlockCompressedPosition; - compressedBytes = await igvxhr.loadArrayBuffer(this.file, buildOptions$1(this.config, { - range: { - start: currentBlockCompressedPosition, - size: compressedLength - } - })); - } else { // special case for query within final block: read until the end of the file - compressedBytes = await igvxhr.loadArrayBuffer(this.file, buildOptions$1(this.config, { - range: { - start: currentBlockCompressedPosition - } - })); - } - //now unzip the compressed bytes, and store them in the resultCache - const uncompressedBytes = await unbgzf(compressedBytes); - resultCache[i] = uncompressedBytes; - } - - //Iterate over the result cache, create sequences from the data, and create a full sequence string from the data - let result = ""; - for (let i = 0; i < resultCache.length; i++) { - for (let j = 0; j < resultCache[i].length; j++) { - const c = String.fromCharCode(resultCache[i][j]); - result = result + c; - } - } - - //postprocess this data: because entire blocks are read we need to remove the first N bases of the first used block, - //which are not included in the original query positions - const firstBlockInfo = (this.compressedIndex)[blockIndices[0]]; - const offset = startByte - firstBlockInfo[UNCOMPRESSED_POSITION]; - result = result.substring(offset); - - return result - } - - - async readSequence(chr, qstart, qend) { - - await this.getIndex(); - await this.getCompressedIndex(); //This will work even if no compressed index file is set - - const idxEntry = this.index[chr]; - if (!idxEntry) { - console.log("No index entry for chr: " + chr); - // Tag interval with null so we don't try again - this.interval = new GenomicInterval(chr, qstart, qend, null); - return null - } - - const start = Math.max(0, qstart); // qstart should never be < 0 - const end = Math.min(idxEntry.size, qend); - const bytesPerLine = idxEntry.bytesPerLine; - const basesPerLine = idxEntry.basesPerLine; - const position = idxEntry.position; - const nEndBytes = bytesPerLine - basesPerLine; - const startLine = Math.floor(start / basesPerLine); - const endLine = Math.floor(end / basesPerLine); - const base0 = startLine * basesPerLine; // Base at beginning of start line - const offset = start - base0; - const startByte = position + startLine * bytesPerLine + offset; - const base1 = endLine * basesPerLine; - const offset1 = end - base1; - const endByte = position + endLine * bytesPerLine + offset1 - 1; - const byteCount = endByte - startByte + 1; - - if (byteCount <= 0) { - console.error("No sequence for " + chr + ":" + qstart + "-" + qend); - return null - } - - //If the compressed index file is set, then we are dealing with a compressed genome sequence - //The selection of startByte/endByte is done for the non-compressed genome sequence. - //These need to be 'converted' to the correct byte positions in the compressed genome sequence, - //by making use of the compressed index (GZI file) - let allBytes; - if (!this.compressedIndexFile) { - allBytes = await igvxhr.load(this.file, buildOptions$1(this.config, { - range: { - start: startByte, - size: byteCount - } - })); - } else { - let relevantBlockIndices = await this.getRelevantCompressedBlockNumbers(startByte, endByte); - if (relevantBlockIndices.length === 0) { - console.log("No blocks in the compressed index that correspond with the requested byte positions (" + startByte + "," + endByte + ")"); - return null - } - allBytes = await this.loadAndUncompressBlocks(relevantBlockIndices, startByte); - } - - if (!allBytes) { - return null - } - - let nBases, - seqBytes = "", - srcPos = 0, - allBytesLength = allBytes.length; - - if (offset > 0) { - nBases = Math.min(end - start, basesPerLine - offset); - seqBytes += allBytes.substr(srcPos, nBases); - srcPos += (nBases + nEndBytes); - } - - while (srcPos < allBytesLength) { - nBases = Math.min(basesPerLine, allBytesLength - srcPos); - seqBytes += allBytes.substr(srcPos, nBases); - srcPos += (nBases + nEndBytes); - } - - return seqBytes - - } - } - - /* - * The MIT License (MIT) - * - * Copyright (c) 2014 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - const splitLines$2 = splitLines$5; - - class ChromSizes { - - - constructor(url) { - this.url = url; - this.chromosomeNames = []; - this.chromosomes = {}; - } - - - async init() { - return this.loadAll() - } - - async getSequence(chr, start, end) { - - return undefined // TODO -- return array of "N"s? - } - - async loadAll() { - - let data; - if (isDataURL(this.url)) { - let bytes = decodeDataURI$1(this.fastaURL); - data = ""; - for (let b of bytes) { - data += String.fromCharCode(b); - } - } else { - data = await igvxhr.load(this.url, {}); - } - - - this.chromosomeNames = []; - this.chromosomes = {}; - - const lines = splitLines$2(data); - let order = 0; - for (let nextLine of lines) { - const tokens = nextLine.split('\t'); - this.chromosomeNames.push(tokens[0]); - const chrLength = Number.parseInt(tokens[1]); - const chromosome = new Chromosome(tokens[0], order++, chrLength); - this.chromosomes[tokens[0]] = chromosome; - - } - } - - } - - async function loadFasta(reference) { - - let fasta; - if ("chromsizes" === reference.format) { - fasta = new ChromSizes(reference.fastaURL); - } else if (isDataURL(reference.fastaURL) || reference.indexed === false) { - fasta = new NonIndexedFasta(reference); - } else { - fasta = new FastaSequence(reference); - } - await fasta.init(); - return fasta - } - - const defaultNucleotideColors = { - "A": "rgb( 0, 200, 0)", - "C": "rgb( 0,0,200)", - "T": "rgb(255,0,0)", - "G": "rgb(209,113, 5)", - "N": "rgb(80,80,80)" - }; - - /* - * The MIT License (MIT) - * - * Copyright (c) 2014 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - const defaultSequenceTrackOrder = Number.MIN_SAFE_INTEGER; - - const translationDict = { - 'TTT': 'F', - 'TTC': 'F', - 'TTA': 'L', - 'TTG': 'L', - 'CTT': 'L', - 'CTC': 'L', - 'CTA': 'L', - 'CTG': 'L', - 'ATT': 'I', - 'ATC': 'I', - 'ATA': 'I', - 'ATG': 'M', - 'GTT': 'V', - 'GTC': 'V', - 'GTA': 'V', - 'GTG': 'V', - 'TCT': 'S', - 'TCC': 'S', - 'TCA': 'S', - 'TCG': 'S', - 'CCT': 'P', - 'CCC': 'P', - 'CCA': 'P', - 'CCG': 'P', - 'ACT': 'T', - 'ACC': 'T', - 'ACA': 'T', - 'ACG': 'T', - 'GCT': 'A', - 'GCC': 'A', - 'GCA': 'A', - 'GCG': 'A', - 'TAT': 'Y', - 'TAC': 'Y', - 'TAA': 'STOP', - 'TAG': 'STOP', - 'CAT': 'H', - 'CAC': 'H', - 'CAA': 'Q', - 'CAG': 'Q', - 'AAT': 'N', - 'AAC': 'N', - 'AAA': 'K', - 'AAG': 'K', - 'GAT': 'D', - 'GAC': 'D', - 'GAA': 'E', - 'GAG': 'E', - 'TGT': 'C', - 'TGC': 'C', - 'TGA': 'STOP', - 'TGG': 'W', - 'CGT': 'R', - 'CGC': 'R', - 'CGA': 'R', - 'CGG': 'R', - 'AGT': 'S', - 'AGC': 'S', - 'AGA': 'R', - 'AGG': 'R', - 'GGT': 'G', - 'GGC': 'G', - 'GGA': 'G', - 'GGG': 'G' - }; - - const complement = {}; - const t1 = ['A', 'G', 'C', 'T', 'Y', 'R', 'W', 'S', 'K', 'M', 'D', 'V', 'H', 'B', 'N', 'X']; - const t2 = ['T', 'C', 'G', 'A', 'R', 'Y', 'W', 'S', 'M', 'K', 'H', 'B', 'D', 'V', 'N', 'X']; - for (let i = 0; i < t1.length; i++) { - complement[t1[i]] = t2[i]; - complement[t1[i].toLowerCase()] = t2[i].toLowerCase(); - } - - const DEFAULT_HEIGHT = 25; - const TRANSLATED_HEIGHT = 115; - const SEQUENCE_HEIGHT = 15; - const FRAME_HEIGHT = 25; - const FRAME_BORDER = 5; - const BP_PER_PIXEL_THRESHOLD = 1 / 10; - - const bppFeatureFetchThreshold = 10; - - class SequenceTrack { - - constructor(config, browser) { - - this.config = config; - this.browser = browser; - this.type = "sequence"; - this.removable = config.removable === undefined ? true : config.removable; // Defaults to true - this.name = config.name; - this.id = config.id; - this.sequenceType = config.sequenceType || "dna"; // dna | rna | prot - this.disableButtons = false; - this.order = config.order || defaultSequenceTrackOrder; - this.ignoreTrackMenu = false; - - this.reversed = config.reversed === true; - this.frameTranslate = config.frameTranslate === true; - this.height = this.frameTranslate ? TRANSLATED_HEIGHT : DEFAULT_HEIGHT; - - // Hack for backward compatibility - if(config.url) { - config.fastaURL = config.url; - } - - if(!config.fastaURL) { - // Mark this as the genome reference sequence ==> backward compatibility convention - this.id = config.id || "sequence"; - } - - } - - menuItemList() { - return [ - { - name: this.reversed ? "Forward" : "Reverse", - click: () => { - this.reversed = !this.reversed; - this.trackView.repaintViews(); - } - }, - { - name: this.frameTranslate ? "Close Translation" : "Three-frame Translate", - click: () => { - this.frameTranslate = !this.frameTranslate; - if (this.frameTranslate) { - for (let vp of this.trackView.viewports) { - vp.setContentHeight(TRANSLATED_HEIGHT); - } - this.trackView.setTrackHeight(TRANSLATED_HEIGHT); - } else { - for (let vp of this.trackView.viewports) { - vp.setContentHeight(DEFAULT_HEIGHT); - } - this.trackView.setTrackHeight(DEFAULT_HEIGHT); - } - this.trackView.repaintViews(); - - } - } - ] - } - - contextMenuItemList(clickState) { - const viewport = clickState.viewport; - if (viewport.referenceFrame.bpPerPixel <= 1) { - const pixelWidth = viewport.getWidth(); - const bpWindow = pixelWidth * viewport.referenceFrame.bpPerPixel; - const chr = viewport.referenceFrame.chr; - const start = Math.floor(viewport.referenceFrame.start); - const end = Math.ceil(start + bpWindow); - const items = [ - { - label: this.reversed ? 'View visible sequence (reversed)...' : 'View visible sequence...', - click: async () => { - let seq = await this.browser.genome.sequence.getSequence(chr, start, end); - if (!seq) { - seq = "Unknown sequence"; - } else if (this.reversed) { - seq = reverseComplementSequence(seq); - } - this.browser.alert.present(seq); - } - } - ]; - if (isSecureContext()) { - items.push({ - label: 'Copy visible sequence', - click: async () => { - let seq = await this.browser.genome.sequence.getSequence(chr, start, end); - if (!seq) { - seq = "Unknown sequence"; - } else if (this.reversed) { - seq = reverseComplementSequence(seq); - } - try { - await navigator.clipboard.writeText(seq); - } catch (e) { - console.error(e); - this.browser.alert.present(`error copying sequence to clipboard ${e}`); - } - } - - }); - } - items.push('
'); - - return items - } else { - return undefined - } - } - - translateSequence(seq) { - - const threeFrame = [[], [], []]; - - for (let fNum of [0, 1, 2]) { - let idx = fNum; - - while ((seq.length - idx) >= 3) { - let st = seq.slice(idx, idx + 3); - if (this.reversed) { - st = st.split('').reverse().join(''); - } - - const aa = translationDict[st.toUpperCase()] || ""; - threeFrame[fNum].push({ - codons: st, - aminoA: aa - }); - idx += 3; - } - } - - return threeFrame - } - - /** - * Return the source for sequence. If an explicit fasta url is defined, use it, otherwise fetch sequence - * from the current genome - * * - * @returns {Promise} - */ - async getSequenceSource() { - if(this.config.fastaURL) { - if(!this.fasta) { - this.fasta = new WrappedFasta(this.config, this.browser.genome); - await this.fasta.init(); - } - return this.fasta - } else { - return this.browser.genome.sequence - } - } - - async getFeatures(chr, start, end, bpPerPixel) { - - start = Math.floor(start); - end = Math.floor(end); - - if (bpPerPixel && bpPerPixel > bppFeatureFetchThreshold) { - return null - } else { - const sequenceSource = await this.getSequenceSource(); - const sequence = await sequenceSource.getSequence(chr, start, end); - return { - bpStart: start, - sequence: sequence - } - } - } - - draw(options) { - - const ctx = options.context; - - if (options.features) { - - let sequence = options.features.sequence; - if(!sequence) { - return - } - - if (this.reversed) { - sequence = sequence.split('').map(function (cv) { - return complement[cv] - }).join(''); - } - - const sequenceBpStart = options.features.bpStart; // genomic position at start of sequence - const bpEnd = 1 + options.bpStart + (options.pixelWidth * options.bpPerPixel); - - for (let bp = Math.floor(options.bpStart); bp <= bpEnd; bp++) { - - const seqIdx = Math.floor(bp - sequenceBpStart); - - if (seqIdx >= 0 && seqIdx < sequence.length) { - - const offsetBP = bp - options.bpStart; - const aPixel = offsetBP / options.bpPerPixel; - const pixelWidth = 1 / options.bpPerPixel; - const baseLetter = sequence[seqIdx]; - const color = this.fillColor(baseLetter.toUpperCase()); - - if (options.bpPerPixel > BP_PER_PIXEL_THRESHOLD) { - IGVGraphics.fillRect(ctx, aPixel, FRAME_BORDER, pixelWidth, SEQUENCE_HEIGHT - FRAME_BORDER, {fillStyle: color}); - } else { - const textPixel = aPixel + 0.5 * (pixelWidth - ctx.measureText(baseLetter).width); - - - - - if ('y' === options.axis) { - ctx.save(); - IGVGraphics.labelTransformWithContext(ctx, textPixel); - IGVGraphics.strokeText(ctx, baseLetter, textPixel, SEQUENCE_HEIGHT, {strokeStyle: color}); - ctx.restore(); - } else { - IGVGraphics.strokeText(ctx, baseLetter, textPixel, SEQUENCE_HEIGHT, {strokeStyle: color}); - } - - } - } - } - - if (this.frameTranslate) { - - let y = SEQUENCE_HEIGHT + 2 * FRAME_BORDER; - const translatedSequence = this.translateSequence(sequence); - - for (let fNum = 0; fNum < translatedSequence.length; fNum++) { // == 3, 1 for each frame - - const aaSequence = translatedSequence[fNum]; // AA sequence for this frame - - for (let idx = 0; idx < aaSequence.length; idx++) { - - let color = 0 === idx % 2 ? 'rgb(160,160,160)' : 'rgb(224,224,224)'; - const cv = aaSequence[idx]; - - const bpPos = sequenceBpStart + fNum + (idx * 3); - const bpOffset = bpPos - options.bpStart; - const p0 = Math.floor(bpOffset / options.bpPerPixel); - const p1 = Math.floor((bpOffset + 3) / options.bpPerPixel); - const pc = Math.round((p0 + p1) / 2); - - if (p1 < 0) { - continue // off left edge - } else if (p0 > options.pixelWidth) { - break // off right edge - } - - let aaLabel = cv.aminoA; - if (cv.aminoA.indexOf('STOP') > -1) { - color = 'rgb(255, 0, 0)'; - aaLabel = 'STOP'; //Color blind accessible - } else if (cv.aminoA === 'M') { - color = 'rgb(0, 153, 0)'; - aaLabel = 'START'; //Color blind accessible - } - - IGVGraphics.fillRect(ctx, p0, y, p1 - p0, FRAME_HEIGHT, {fillStyle: color}); - - if (options.bpPerPixel <= 1 / 10) { - IGVGraphics.strokeText(ctx, aaLabel, pc - (ctx.measureText(aaLabel).width / 2), y + 15); - } - } - y += (FRAME_HEIGHT + FRAME_BORDER); - } - } - } - } - - get supportsWholeGenome() { - return false - } - - computePixelHeight(ignore) { - this.height = this.frameTranslate ? TRANSLATED_HEIGHT : DEFAULT_HEIGHT; - return this.height - } - - fillColor(index) { - - if (this.color) { - return this.color - } else if ("dna" === this.sequenceType) { - // return this.browser.nucleotideColors[index] || 'gray' - return defaultNucleotideColors[index] || 'gray' - } else { - return 'rgb(0, 0, 150)' - } - } - - /** - * Return the current state of the track. Used to create sessions and bookmarks. - * - * @returns {*|{}} - */ - getState() { - const config = { - type: "sequence" - }; - if (this.order !== defaultSequenceTrackOrder) { - config.order = this.order; - } - if (this.reversed) { - config.revealed = true; - } - return config - } - - } - - /** - * Wrapper for a Fasta object that does chr name alias translation. This is not neccessary for the genome fasta, - * as it defines the reference name, but can be neccessary if loading an additional fasta as a track - * - */ - class WrappedFasta { - - constructor(config, genome) { - this.config = config; - this.genome = genome; - } - - async init() { - this.fasta = await loadFasta(this.config); - this.chrNameMap = new Map(); - for(let name of this.fasta.chromosomeNames) { - this.chrNameMap.set(this.genome.getChromosomeName(name), name); - } - } - - async getSequence(chr, start, end) { - const chrName = this.chrNameMap.has(chr) ? this.chrNameMap.get(chr) : chr; - return this.fasta.getSequence(chrName, start, end) - } - - } - - /* - * The MIT License (MIT) - * - * Copyright (c) 2014 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - class Viewport { - - constructor(trackView, viewportColumn, referenceFrame, width) { - - this.guid = domUtils$1.guid(); - this.trackView = trackView; - this.referenceFrame = referenceFrame; - - this.browser = trackView.browser; - - this.$viewport = $$1('
'); - viewportColumn.appendChild(this.$viewport.get(0)); - - if (trackView.track.height) { - this.$viewport.get(0).style.height = `${trackView.track.height}px`; - } - - // Create an alert dialog for the sequence track to copy ref sequence to. - if (trackView.track instanceof SequenceTrack) { - this.alert = new AlertDialog$1(this.$viewport.get(0)); - } - - this.contentTop = 0; - this.contentHeight = this.$viewport.height(); - - - this.$viewport.width(width); - - this.initializationHelper(); - - } - - initializationHelper() { - - } - - showMessage(message) { - if (!this.messageDiv) { - this.messageDiv = document.createElement('div'); - this.messageDiv.className = 'igv-viewport-message'; - //this.contentDiv.append(this.messageDiv) - this.$viewport.append($$1(this.messageDiv)); - } - this.messageDiv.textContent = message; - this.messageDiv.style.display = 'inline-block'; - } - - hideMessage(message) { - if (this.messageDiv) - this.messageDiv.style.display = 'none'; - } - - setTrackLabel(label) { - } - - startSpinner() { - } - - stopSpinner() { - } - - checkZoomIn() { - return true - } - - shift() { - } - - setTop(contentTop) { - - this.contentTop = contentTop; - this.$viewport.height(); - - //this.$content.css('top', `${contentTop}px`) - // - // if (undefined === this.canvasVerticalRange || this.canvasVerticalRange.bottom < viewBottom || this.canvasVerticalRange.top > viewTop) { - // console.log("Repaint " + this.canvasVerticalRange) - // this.repaint() - // } - - } - - async loadFeatures() { - return undefined - } - - clearCache() { - - } - - async repaint() { - } - - draw(drawConfiguration, features, roiFeatures) { - console.log('Viewport - draw(drawConfiguration, features, roiFeatures)'); - } - - checkContentHeight(features) { - - let track = this.trackView.track; - features = features || this.cachedFeatures; - if ("FILL" === track.displayMode) { - this.setContentHeight(this.$viewport.height()); - } else if (typeof track.computePixelHeight === 'function') { - if (features && features.length > 0) { - let requiredContentHeight = track.computePixelHeight(features); - //let currentContentHeight = this.$content.height() - let currentContentHeight = this.contentHeight; - if (requiredContentHeight !== currentContentHeight) { - this.setContentHeight(requiredContentHeight); - } - } - } - } - - getContentHeight() { - //return this.$content.height() - return this.contentHeight - } - - setContentHeight(contentHeight) { - this.contentHeight = contentHeight; - } - - isLoading() { - return false - } - - saveSVG() { - - } - - isVisible() { - return this.$viewport.width() - } - - setWidth(width) { - this.$viewport.width(width); - } - - getWidth() { - return this.$viewport.width() - } - - getContentTop() { - return this.contentTop - } - - containsPosition(chr, position) { - console.log('Viewport - containsPosition(chr, position)'); - } - - addMouseHandlers() { - } - - removeMouseHandlers() { - } - - /** - * Called when the associated track is removed. Do any needed cleanup here. - */ - dispose() { - - if (this.popover) { - this.popover.dispose(); - } - - this.$viewport.get(0).remove(); - - // Null out all properties -- this should not be neccessary, but just in case there is a - // reference to self somewhere we want to free memory. - for (let key of Object.keys(this)) { - this[key] = undefined; - } - } - - } - - /*!! - * Canvas 2 Svg v1.0.19 - * A low level canvas to SVG converter. Uses a mock canvas context to build an SVG document. - * - * Licensed under the MIT license: - * http://www.opensource.org/licenses/mit-license.php - * - * Author: - * Kerry Liu - * - * Copyright (c) 2014 Gliffy Inc. - */ - - //helper function to format a string - function format(str, args) { - var keys = Object.keys(args), i; - for (i = 0; i < keys.length; i++) { - str = str.replace(new RegExp("\\{" + keys[i] + "\\}", "gi"), args[keys[i]]); - } - return str - } - - //helper function that generates a random string - function randomString(holder) { - var chars, randomstring, i; - if (!holder) { - throw new Error("cannot create a random attribute name for an undefined object") - } - chars = "ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz"; - randomstring = ""; - do { - randomstring = ""; - for (i = 0; i < 12; i++) { - randomstring += chars[Math.floor(Math.random() * chars.length)]; - } - } while (holder[randomstring]) - return randomstring - } - - //helper function to map named to numbered entities - function createNamedToNumberedLookup(items, radix) { - var i, entity, lookup = {}, base10; - items = items.split(','); - radix = radix || 10; - // Map from named to numbered entities. - for (i = 0; i < items.length; i += 2) { - entity = '&' + items[i + 1] + ';'; - base10 = parseInt(items[i], radix); - lookup[entity] = '&#' + base10 + ';'; - } - //FF and IE need to create a regex from hex values ie   == \xa0 - lookup["\\xa0"] = ' '; - return lookup - } - - //helper function to map canvas-textAlign to svg-textAnchor - function getTextAnchor(textAlign) { - //TODO: support rtl languages - var mapping = {"left": "start", "right": "end", "center": "middle", "start": "start", "end": "end"}; - return mapping[textAlign] || mapping.start - } - - //helper function to map canvas-textBaseline to svg-dominantBaseline - function getDominantBaseline(textBaseline) { - //INFO: not supported in all browsers - var mapping = { - "alphabetic": "alphabetic", - "hanging": "hanging", - "top": "text-before-edge", - "bottom": "text-after-edge", - "middle": "central" - }; - return mapping[textBaseline] || mapping.alphabetic - } - - - /** - * Return a new normalized vector of given vector - */ - function normalize(vector) { - var len = Math.sqrt(vector[0] * vector[0] + vector[1] * vector[1]); - return [vector[0] / len, vector[1] / len] - } - - - function intersectRect(rect1, rect2) { - return (rect1.x < rect2.x + rect2.width && - rect1.x + rect1.width > rect2.x && - rect1.y < rect2.y + rect2.height && - rect1.y + rect1.height > rect2.y) - } - - - // Unpack entities lookup where the numbers are in radix 32 to reduce the size - // entity mapping courtesy of tinymce - const namedEntities = createNamedToNumberedLookup( - '50,nbsp,51,iexcl,52,cent,53,pound,54,curren,55,yen,56,brvbar,57,sect,58,uml,59,copy,' + - '5a,ordf,5b,laquo,5c,not,5d,shy,5e,reg,5f,macr,5g,deg,5h,plusmn,5i,sup2,5j,sup3,5k,acute,' + - '5l,micro,5m,para,5n,middot,5o,cedil,5p,sup1,5q,ordm,5r,raquo,5s,frac14,5t,frac12,5u,frac34,' + - '5v,iquest,60,Agrave,61,Aacute,62,Acirc,63,Atilde,64,Auml,65,Aring,66,AElig,67,Ccedil,' + - '68,Egrave,69,Eacute,6a,Ecirc,6b,Euml,6c,Igrave,6d,Iacute,6e,Icirc,6f,Iuml,6g,ETH,6h,Ntilde,' + - '6i,Ograve,6j,Oacute,6k,Ocirc,6l,Otilde,6m,Ouml,6n,times,6o,Oslash,6p,Ugrave,6q,Uacute,' + - '6r,Ucirc,6s,Uuml,6t,Yacute,6u,THORN,6v,szlig,70,agrave,71,aacute,72,acirc,73,atilde,74,auml,' + - '75,aring,76,aelig,77,ccedil,78,egrave,79,eacute,7a,ecirc,7b,euml,7c,igrave,7d,iacute,7e,icirc,' + - '7f,iuml,7g,eth,7h,ntilde,7i,ograve,7j,oacute,7k,ocirc,7l,otilde,7m,ouml,7n,divide,7o,oslash,' + - '7p,ugrave,7q,uacute,7r,ucirc,7s,uuml,7t,yacute,7u,thorn,7v,yuml,ci,fnof,sh,Alpha,si,Beta,' + - 'sj,Gamma,sk,Delta,sl,Epsilon,sm,Zeta,sn,Eta,so,Theta,sp,Iota,sq,Kappa,sr,Lambda,ss,Mu,' + - 'st,Nu,su,Xi,sv,Omicron,t0,Pi,t1,Rho,t3,Sigma,t4,Tau,t5,Upsilon,t6,Phi,t7,Chi,t8,Psi,' + - 't9,Omega,th,alpha,ti,beta,tj,gamma,tk,delta,tl,epsilon,tm,zeta,tn,eta,to,theta,tp,iota,' + - 'tq,kappa,tr,lambda,ts,mu,tt,nu,tu,xi,tv,omicron,u0,pi,u1,rho,u2,sigmaf,u3,sigma,u4,tau,' + - 'u5,upsilon,u6,phi,u7,chi,u8,psi,u9,omega,uh,thetasym,ui,upsih,um,piv,812,bull,816,hellip,' + - '81i,prime,81j,Prime,81u,oline,824,frasl,88o,weierp,88h,image,88s,real,892,trade,89l,alefsym,' + - '8cg,larr,8ch,uarr,8ci,rarr,8cj,darr,8ck,harr,8dl,crarr,8eg,lArr,8eh,uArr,8ei,rArr,8ej,dArr,' + - '8ek,hArr,8g0,forall,8g2,part,8g3,exist,8g5,empty,8g7,nabla,8g8,isin,8g9,notin,8gb,ni,8gf,prod,' + - '8gh,sum,8gi,minus,8gn,lowast,8gq,radic,8gt,prop,8gu,infin,8h0,ang,8h7,and,8h8,or,8h9,cap,8ha,cup,' + - '8hb,int,8hk,there4,8hs,sim,8i5,cong,8i8,asymp,8j0,ne,8j1,equiv,8j4,le,8j5,ge,8k2,sub,8k3,sup,8k4,' + - 'nsub,8k6,sube,8k7,supe,8kl,oplus,8kn,otimes,8l5,perp,8m5,sdot,8o8,lceil,8o9,rceil,8oa,lfloor,8ob,' + - 'rfloor,8p9,lang,8pa,rang,9ea,loz,9j0,spades,9j3,clubs,9j5,hearts,9j6,diams,ai,OElig,aj,oelig,b0,' + - 'Scaron,b1,scaron,bo,Yuml,m6,circ,ms,tilde,802,ensp,803,emsp,809,thinsp,80c,zwnj,80d,zwj,80e,lrm,' + - '80f,rlm,80j,ndash,80k,mdash,80o,lsquo,80p,rsquo,80q,sbquo,80s,ldquo,80t,rdquo,80u,bdquo,810,dagger,' + - '811,Dagger,81g,permil,81p,lsaquo,81q,rsaquo,85c,euro', 32); - - - //Some basic mappings for attributes and default values. - const STYLES = { - "strokeStyle": { - svgAttr: "stroke", //corresponding svg attribute - canvas: "#000000", //canvas default - svg: "none", //svg default - apply: "stroke" //apply on stroke() or fill() - }, - "fillStyle": { - svgAttr: "fill", - canvas: "#000000", - svg: null, //svg default is black, but we need to special case this to handle canvas stroke without fill - apply: "fill" - }, - "lineCap": { - svgAttr: "stroke-linecap", - canvas: "butt", - svg: "butt", - apply: "stroke" - }, - "lineJoin": { - svgAttr: "stroke-linejoin", - canvas: "miter", - svg: "miter", - apply: "stroke" - }, - "miterLimit": { - svgAttr: "stroke-miterlimit", - canvas: 10, - svg: 4, - apply: "stroke" - }, - "lineWidth": { - svgAttr: "stroke-width", - canvas: 1, - svg: 1, - apply: "stroke" - }, - "globalAlpha": { - svgAttr: "opacity", - canvas: 1, - svg: 1, - apply: "fill stroke" - }, - "font": { - //font converts to multiple svg attributes, there is custom logic for this - canvas: "10px sans-serif" - }, - "shadowColor": { - canvas: "#000000" - }, - "shadowOffsetX": { - canvas: 0 - }, - "shadowOffsetY": { - canvas: 0 - }, - "shadowBlur": { - canvas: 0 - }, - "textAlign": { - canvas: "start" - }, - "textBaseline": { - canvas: "alphabetic" - }, - "lineDash": { - svgAttr: "stroke-dasharray", - canvas: [], - svg: null, - apply: "stroke" - } - }; - - /** - * - * @param gradientNode - reference to the gradient - * @constructor - */ - class CanvasGradient { - constructor(gradientNode, ctx) { - this.__root = gradientNode; - this.__ctx = ctx; - } - - /** - * Adds a color stop to the gradient root - */ - addColorStop(offset, color) { - var stop = this.__ctx.__createElement("stop"), regex, matches; - stop.setAttribute("offset", offset); - if (color && color.indexOf("rgba") !== -1) { - //separate alpha value, since webkit can't handle it - regex = /rgba\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d?\.?\d*)\s*\)/gi; - matches = regex.exec(color); - stop.setAttribute("stop-color", format("rgb({r},{g},{b})", {r: matches[1], g: matches[2], b: matches[3]})); - stop.setAttribute("stop-opacity", matches[4]); - } else { - stop.setAttribute("stop-color", color); - } - this.__root.appendChild(stop); - } - } - - class CanvasPattern { - constructor(pattern, ctx) { - this.__root = pattern; - this.__ctx = ctx; - } - } - - /** - * The mock canvas context - * @param config - options include: - * ctx - existing Context2D to wrap around - * width - width of your canvas (defaults to 500) - * height - height of your canvas (defaults to 500) - * enableMirroring - enables canvas mirroring (get image data) (defaults to false) - * document - the document object (defaults to the current document) - */ - class ctx { - constructor(config) { - - if (!(this instanceof ctx)) { - //did someone call this without new? - return new ctx(config) - } - - // clone config - this.config = config; - - //setup options - this.width = config.width; - this.height = config.height; - this.enableMirroring = config.enableMirroring || false; - - this.canvas = this; ///point back to this instance! - this.__document = document; - - // allow passing in an existing context to wrap around - // if a context is passed in, we know a canvas already exist - if (config.ctx) { - this.__ctx = config.ctx; - } else { - this.__canvas = this.__document.createElement("canvas"); - this.__ctx = this.__canvas.getContext("2d"); - } - - // give this canvas a type - this.isSVG = true; - - this.__setDefaultStyles(); - this.__stack = [this.__getStyleState()]; - this.__groupStack = []; - - // root svg element - this.__root = this.__createElement("svg"); - this.__root.setAttribute("width", this.width); - this.__root.setAttribute("height", this.height); - - // allow contents to overflow svg bbox - this.__root.setAttribute('overflow', 'visible'); - - // viewbox - if (config.viewbox) { - const str = config.viewbox.x + ' ' + config.viewbox.y + ' ' + config.viewbox.width + ' ' + config.viewbox.height; - this.__root.setAttribute("viewBox", str); - - this.viewbox = config.viewbox; - } - - // make sure we don't generate the same ids in defs - this.__ids = {}; - - // defs - this.__defs = this.__createElement("defs"); - this.__root.appendChild(this.__defs); - - this.multiLocusGap = config.multiLocusGap; - - // svg background color - let backdropConfig = - { - id: 'svg_output_backdrop', - width: '100%', - height: '100%', - fill: config.backdropColor || 'white' - }; - - let backdropRect = this.__createElement('rect', backdropConfig); - this.__root.appendChild(backdropRect); - - // root group - this.__rootGroup = this.__createElement('g', {id: 'root-group'}); - this.__root.appendChild(this.__rootGroup); - - // point current element to root group - this.__currentElement = this.__rootGroup; - } - - setWidth(width) { - - this.width = width; - this.__root.setAttribute("width", this.width); - - const str = this.config.viewbox.x + ' ' + this.config.viewbox.y + ' ' + width + ' ' + this.config.viewbox.height; - this.__root.setAttribute("viewBox", str); - - }; - - setHeight(height) { - - this.height = height; - this.__root.setAttribute("height", this.height); - - const str = this.config.viewbox.x + ' ' + this.config.viewbox.y + ' ' + this.config.viewbox.width + ' ' + height; - this.__root.setAttribute("viewBox", str); - - }; - - /** - * Creates the specified svg element - * @private - */ - __createElement(elementName, properties, resetFill) { - - if (typeof properties === "undefined") { - properties = {}; - } - - let element = this.__document.createElementNS("http://www.w3.org/2000/svg", elementName); - - if (resetFill) { - //if fill or stroke is not specified, the svg element should not display. By default SVG's fill is black. - element.setAttribute("fill", "none"); - element.setAttribute("stroke", "none"); - } - - for (let key of Object.keys(properties)) { - element.setAttribute(key, properties[key]); - } - - return element - }; - - /** - * Applies default canvas styles to the context - * @private - */ - __setDefaultStyles() { - //default 2d canvas context properties see:http://www.w3.org/TR/2dcontext/ - var keys = Object.keys(STYLES), i, key; - for (i = 0; i < keys.length; i++) { - key = keys[i]; - this[key] = STYLES[key].canvas; - } - }; - - /** - * Applies styles on restore - * @param styleState - * @private - */ - __applyStyleState(styleState) { - var keys = Object.keys(styleState), i, key; - for (i = 0; i < keys.length; i++) { - key = keys[i]; - this[key] = styleState[key]; - } - }; - - /** - * Gets the current style state - * @return {Object} - * @private - */ - __getStyleState() { - var i, styleState = {}, keys = Object.keys(STYLES), key; - for (i = 0; i < keys.length; i++) { - key = keys[i]; - styleState[key] = this[key]; - } - return styleState - }; - - /** - * Apples the current styles to the current SVG element. On "ctx.fill" or "ctx.stroke" - * @param type - * @private - */ - __applyStyleToCurrentElement(type) { - var currentElement = this.__currentElement; - var currentStyleGroup = this.__currentElementsToStyle; - if (currentStyleGroup) { - currentElement.setAttribute(type, ""); - currentElement = currentStyleGroup.element; - currentStyleGroup.children.forEach(function (node) { - node.setAttribute(type, ""); - }); - } - - var keys = Object.keys(STYLES), i, style, value, id, regex, matches; - for (i = 0; i < keys.length; i++) { - style = STYLES[keys[i]]; - value = this[keys[i]]; - if (style.apply) { - //is this a gradient or pattern? - if (value instanceof CanvasPattern) { - //pattern - if (value.__ctx) { - //copy over defs - while (value.__ctx.__defs.childNodes.length) { - id = value.__ctx.__defs.childNodes[0].getAttribute("id"); - this.__ids[id] = id; - this.__defs.appendChild(value.__ctx.__defs.childNodes[0]); - } - } - currentElement.setAttribute(style.apply, format("url(#{id})", {id: value.__root.getAttribute("id")})); - } else if (value instanceof CanvasGradient) { - //gradient - currentElement.setAttribute(style.apply, format("url(#{id})", {id: value.__root.getAttribute("id")})); - } else if (style && style.apply.indexOf(type) !== -1 && style.svg !== value) { - if ((style.svgAttr === "stroke" || style.svgAttr === "fill") && value && value.indexOf("rgba") !== -1) { - //separate alpha value, since illustrator can't handle it - regex = /rgba\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d?\.?\d*)\s*\)/gi; - matches = regex.exec(value); - currentElement.setAttribute(style.svgAttr, format("rgb({r},{g},{b})", { - r: matches[1], - g: matches[2], - b: matches[3] - })); - //should take globalAlpha here - var opacity = matches[4]; - var globalAlpha = this.globalAlpha; - if (globalAlpha != null) { - opacity *= globalAlpha; - } - currentElement.setAttribute(style.svgAttr + "-opacity", opacity); - } else { - var attr = style.svgAttr; - if (keys[i] === 'globalAlpha') { - attr = type + '-' + style.svgAttr; - if (currentElement.getAttribute(attr)) { - //fill-opacity or stroke-opacity has already been set by stroke or fill. - continue - } - } - //otherwise only update attribute if right type, and not svg default - currentElement.setAttribute(attr, value); - } - } - } - } - }; - - /** - * Will return the closest group or svg node. May return the current element. - * @private - */ - __closestGroupOrSvg(node) { - node = node || this.__currentElement; - if (node.nodeName === "g" || node.nodeName === "svg") { - return node - } else { - return this.__closestGroupOrSvg(node.parentNode) - } - }; - - /** - * Returns the serialized value of the svg so far - * @param fixNamedEntities - Standalone SVG doesn't support named entities, which document.createTextNode encodes. - * If true, we attempt to find all named entities and encode it as a numeric entity. - * @return serialized svg - */ - getSerializedSvg(fixNamedEntities) { - var serialized = new XMLSerializer().serializeToString(this.__root), - keys, i, key, value, regexp; - - //IE search for a duplicate xmnls because they didn't implement setAttributeNS correctly - // xmlns = /xmlns="http:\/\/www\.w3\.org\/2000\/svg".+xmlns="http:\/\/www\.w3\.org\/2000\/svg/gi; - // if (xmlns.test(serialized)) { - // serialized = serialized.replace('xmlns="http://www.w3.org/2000/svg','xmlns:xlink="http://www.w3.org/1999/xlink'); - // } - - if (fixNamedEntities) { - keys = Object.keys(namedEntities); - //loop over each named entity and replace with the proper equivalent. - for (i = 0; i < keys.length; i++) { - key = keys[i]; - value = namedEntities[key]; - regexp = new RegExp(key, "gi"); - if (regexp.test(serialized)) { - serialized = serialized.replace(regexp, value); - } - } - } - - return serialized - }; - - - /** - * Returns the root svg - * @return - */ - getSvg() { - return this.__root - }; - - /** - * Will generate a group tag. - */ - saveWithTranslationAndClipRect(id, tx, ty, width, height, clipYOffset) { - - // clip rect - const clip_id = `${id}_clip_rect`; - let clipPath = this.__createElement('clipPath', {id: clip_id}); - - this.__defs.appendChild(clipPath); - - const config = - { - x: '0', - y: clipYOffset.toString(), - width: width.toString(), - height: height.toString() - }; - - clipPath.appendChild(this.__createElement('rect', config)); - - const group = this.__createElement("g"); - group.setAttribute('transform', format('translate({x},{y})', {x: tx, y: ty})); - group.setAttribute('clip-path', format('url(#{id})', {id: clip_id})); - - const parent = this.__closestGroupOrSvg(); - parent.appendChild(group); - this.__groupStack.push(parent); - - this.__currentElement = group; - this.__stack.push(this.__getStyleState()); - }; - - save() { - var group = this.__createElement("g"); - var parent = this.__closestGroupOrSvg(); - this.__groupStack.push(parent); - parent.appendChild(group); - this.__currentElement = group; - this.__stack.push(this.__getStyleState()); - }; - - /** - * Sets current element to parent, or just root if already root - */ - restore() { - this.__currentElement = this.__groupStack.pop(); - this.__currentElementsToStyle = null; - //Clearing canvas will make the poped group invalid, currentElement is set to the root group node. - if (!this.__currentElement) { - this.__currentElement = this.__root.childNodes[1]; - } - var state = this.__stack.pop(); - this.__applyStyleState(state); - }; - - /** - * Helper method to add transform - * @private - */ - __addTransform(t) { - //if the current element has siblings, add another group - var parent = this.__closestGroupOrSvg(); - if (parent.childNodes.length > 0) { - if (this.__currentElement.nodeName === "path") { - if (!this.__currentElementsToStyle) this.__currentElementsToStyle = {element: parent, children: []}; - this.__currentElementsToStyle.children.push(this.__currentElement); - this.__applyCurrentDefaultPath(); - } - - var group = this.__createElement("g"); - parent.appendChild(group); - this.__currentElement = group; - } - - var transform = this.__currentElement.getAttribute("transform"); - if (transform) { - transform += " "; - } else { - transform = ""; - } - transform += t; - this.__currentElement.setAttribute("transform", transform); - }; - - addTrackGroupWithTranslationAndClipRect(id, tx, ty, width, height, clipYOffset) { - - // clip rect - const clip_id = id + '_clip_rect'; - let clipPath = this.__createElement('clipPath', {id: clip_id}); - - this.__defs.appendChild(clipPath); - clipPath.appendChild(this.__createElement('rect', { - x: '0', - y: clipYOffset.toString(), - width: width.toString(), - height: height.toString() - })); - - let group = this.__createElement('g'); - this.__rootGroup.appendChild(group); - - group.setAttribute('transform', format('translate({x},{y})', {x: tx, y: ty})); - group.setAttribute('id', (id + '_group')); - - // add clip rect - group.setAttribute('clip-path', format('url(#{id})', {id: clip_id})); - - this.__currentElement = group; - }; - - /** - * scales the current element - */ - scale(x, y) { - if (y === undefined) { - y = x; - } - this.__addTransform(format("scale({x},{y})", {x: x, y: y})); - }; - - /** - * rotates the current element - */ - rotate(angle) { - var degrees = (angle * 180 / Math.PI); - this.__addTransform(format("rotate({angle},{cx},{cy})", {angle: degrees, cx: 0, cy: 0})); - }; - - /** - * translates the current element - */ - translate(x, y) { - this.__addTransform(format("translate({x},{y})", {x: x, y: y})); - }; - - /** - * applies a transform to the current element - */ - transform(a, b, c, d, e, f) { - this.__addTransform(format("matrix({a},{b},{c},{d},{e},{f})", {a: a, b: b, c: c, d: d, e: e, f: f})); - }; - - /** - * Create a new Path Element - */ - beginPath() { - var path, parent; - - // Note that there is only one current default path, it is not part of the drawing state. - // See also: https://html.spec.whatwg.org/multipage/scripting.html#current-default-path - this.__currentDefaultPath = ""; - this.__currentPosition = {}; - - path = this.__createElement("path", {}, true); - parent = this.__closestGroupOrSvg(); - parent.appendChild(path); - this.__currentElement = path; - }; - - /** - * Helper function to apply currentDefaultPath to current path element - * @private - */ - __applyCurrentDefaultPath() { - var currentElement = this.__currentElement; - if (currentElement.nodeName === "path") { - currentElement.setAttribute("d", this.__currentDefaultPath); - } else { - console.error("Attempted to apply path command to node", currentElement.nodeName); - } - }; - - /** - * Helper function to add path command - * @private - */ - __addPathCommand(command) { - this.__currentDefaultPath += " "; - this.__currentDefaultPath += command; - }; - - /** - * Adds the move command to the current path element, - * if the currentPathElement is not empty create a new path element - */ - moveTo(x, y) { - if (this.__currentElement.nodeName !== "path") { - this.beginPath(); - } - - // creates a new subpath with the given point - this.__currentPosition = {x: x, y: y}; - this.__addPathCommand(format("M {x} {y}", {x: x, y: y})); - }; - - /** - * Closes the current path - */ - closePath() { - if (this.__currentDefaultPath) { - this.__addPathCommand("Z"); - } - }; - - /** - * Adds a line to command - */ - lineTo(x, y) { - this.__currentPosition = {x: x, y: y}; - if (this.__currentDefaultPath && this.__currentDefaultPath.indexOf('M') > -1) { - this.__addPathCommand(format("L {x} {y}", {x: x, y: y})); - } else { - this.__addPathCommand(format("M {x} {y}", {x: x, y: y})); - } - }; - - /** - * Add a bezier command - */ - bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y) { - this.__currentPosition = {x: x, y: y}; - this.__addPathCommand(format("C {cp1x} {cp1y} {cp2x} {cp2y} {x} {y}", - {cp1x: cp1x, cp1y: cp1y, cp2x: cp2x, cp2y: cp2y, x: x, y: y})); - }; - - /** - * Adds a quadratic curve to command - */ - quadraticCurveTo(cpx, cpy, x, y) { - this.__currentPosition = {x: x, y: y}; - this.__addPathCommand(format("Q {cpx} {cpy} {x} {y}", {cpx: cpx, cpy: cpy, x: x, y: y})); - }; - - /** - * Adds the arcTo to the current path - * - * @see http://www.w3.org/TR/2015/WD-2dcontext-20150514/#dom-context-2d-arcto - */ - arcTo(x1, y1, x2, y2, radius) { - // Let the point (x0, y0) be the last point in the subpath. - var x0 = this.__currentPosition && this.__currentPosition.x; - var y0 = this.__currentPosition && this.__currentPosition.y; - - // First ensure there is a subpath for (x1, y1). - if (typeof x0 == "undefined" || typeof y0 == "undefined") { - return - } - - // Negative values for radius must cause the implementation to throw an IndexSizeError exception. - if (radius < 0) { - throw new Error("IndexSizeError: The radius provided (" + radius + ") is negative.") - } - - // If the point (x0, y0) is equal to the point (x1, y1), - // or if the point (x1, y1) is equal to the point (x2, y2), - // or if the radius radius is zero, - // then the method must add the point (x1, y1) to the subpath, - // and connect that point to the previous point (x0, y0) by a straight line. - if (((x0 === x1) && (y0 === y1)) - || ((x1 === x2) && (y1 === y2)) - || (radius === 0)) { - this.lineTo(x1, y1); - return - } - - // Otherwise, if the points (x0, y0), (x1, y1), and (x2, y2) all lie on a single straight line, - // then the method must add the point (x1, y1) to the subpath, - // and connect that point to the previous point (x0, y0) by a straight line. - var unit_vec_p1_p0 = normalize([x0 - x1, y0 - y1]); - var unit_vec_p1_p2 = normalize([x2 - x1, y2 - y1]); - if (unit_vec_p1_p0[0] * unit_vec_p1_p2[1] === unit_vec_p1_p0[1] * unit_vec_p1_p2[0]) { - this.lineTo(x1, y1); - return - } - - // Otherwise, let The Arc be the shortest arc given by circumference of the circle that has radius radius, - // and that has one point tangent to the half-infinite line that crosses the point (x0, y0) and ends at the point (x1, y1), - // and that has a different point tangent to the half-infinite line that ends at the point (x1, y1), and crosses the point (x2, y2). - // The points at which this circle touches these two lines are called the start and end tangent points respectively. - - // note that both vectors are unit vectors, so the length is 1 - var cos = (unit_vec_p1_p0[0] * unit_vec_p1_p2[0] + unit_vec_p1_p0[1] * unit_vec_p1_p2[1]); - var theta = Math.acos(Math.abs(cos)); - - // Calculate origin - var unit_vec_p1_origin = normalize([ - unit_vec_p1_p0[0] + unit_vec_p1_p2[0], - unit_vec_p1_p0[1] + unit_vec_p1_p2[1] - ]); - var len_p1_origin = radius / Math.sin(theta / 2); - var x = x1 + len_p1_origin * unit_vec_p1_origin[0]; - var y = y1 + len_p1_origin * unit_vec_p1_origin[1]; - - // Calculate start angle and end angle - // rotate 90deg clockwise (note that y axis points to its down) - var unit_vec_origin_start_tangent = [ - -unit_vec_p1_p0[1], - unit_vec_p1_p0[0] - ]; - // rotate 90deg counter clockwise (note that y axis points to its down) - var unit_vec_origin_end_tangent = [ - unit_vec_p1_p2[1], - -unit_vec_p1_p2[0] - ]; - var getAngle = function (vector) { - // get angle (clockwise) between vector and (1, 0) - var x = vector[0]; - var y = vector[1]; - if (y >= 0) { // note that y axis points to its down - return Math.acos(x) - } else { - return -Math.acos(x) - } - }; - var startAngle = getAngle(unit_vec_origin_start_tangent); - var endAngle = getAngle(unit_vec_origin_end_tangent); - - // Connect the point (x0, y0) to the start tangent point by a straight line - this.lineTo(x + unit_vec_origin_start_tangent[0] * radius, - y + unit_vec_origin_start_tangent[1] * radius); - - // Connect the start tangent point to the end tangent point by arc - // and adding the end tangent point to the subpath. - this.arc(x, y, radius, startAngle, endAngle); - }; - - /** - * Sets the stroke property on the current element - */ - stroke() { - if (this.__currentElement.nodeName === "path") { - this.__currentElement.setAttribute("paint-order", "fill stroke markers"); - } - this.__applyCurrentDefaultPath(); - this.__applyStyleToCurrentElement("stroke"); - }; - - /** - * Sets fill properties on the current element - */ - fill() { - if (this.__currentElement.nodeName === "path") { - this.__currentElement.setAttribute("paint-order", "stroke fill markers"); - } - this.__applyCurrentDefaultPath(); - this.__applyStyleToCurrentElement("fill"); - }; - - /** - * Adds a rectangle to the path. - */ - rect(x, y, width, height) { - if (this.__currentElement.nodeName !== "path") { - this.beginPath(); - } - this.moveTo(x, y); - this.lineTo(x + width, y); - this.lineTo(x + width, y + height); - this.lineTo(x, y + height); - this.lineTo(x, y); - this.closePath(); - }; - - - /** - * adds a rectangle element - */ - fillRect(x, y, width, height) { - - if (height < 0) { - y += height; - height = -height; - } - if (width < 0) { - x += width; - width = -width; - } - // See if rect intersects current viewbox - var r2 = { - x: x, - y: y, - width: width, - height: height - }; - - if (this.viewbox) { - if (!intersectRect(this.viewbox, r2)) { - return - } - } - - var rect, parent; - rect = this.__createElement("rect", r2, true); - parent = this.__closestGroupOrSvg(); - parent.appendChild(rect); - this.__currentElement = rect; - this.__applyStyleToCurrentElement("fill"); - }; - - /** - * Draws a rectangle with no fill - * @param x - * @param y - * @param width - * @param height - */ - strokeRect(x, y, width, height) { - var rect, parent; - rect = this.__createElement("rect", { - x: x, - y: y, - width: width, - height: height - }, true); - parent = this.__closestGroupOrSvg(); - parent.appendChild(rect); - this.__currentElement = rect; - this.__applyStyleToCurrentElement("stroke"); - }; - - // stroke ellipse - strokeEllipse(cx, cy, rx, ry, rotation, startAngle, endAngle, isCCW) { - this.__ellipse(cx, cy, rx, ry, rotation, startAngle, endAngle, isCCW, 'stroke'); - } - - // fill ellipse - fillEllipse(cx, cy, rx, ry, rotation, startAngle, endAngle, isCCW) { - this.__ellipse(cx, cy, rx, ry, rotation, startAngle, endAngle, isCCW, 'fill'); - } - - // ellipse helper - __ellipse(cx, cy, rx, ry, rotation, startAngle, endAngle, isCCW, style) { - - const config = - { - cx, - cy, - rx, - ry - }; - const element = this.__createElement('ellipse', config, true); - const parent = this.__closestGroupOrSvg(); - parent.appendChild(element); - this.__currentElement = element; - this.__applyStyleToCurrentElement(style); - } - - /** - * Clear entire canvas: - * 1. save current transforms - * 2. remove all the childNodes of the root g element - */ - __clearCanvas() { - var current = this.__closestGroupOrSvg(), - transform = current.getAttribute("transform"); - var rootGroup = this.__root.childNodes[1]; - var childNodes = rootGroup.childNodes; - for (var i = childNodes.length - 1; i >= 0; i--) { - if (childNodes[i]) { - rootGroup.removeChild(childNodes[i]); - } - } - this.__currentElement = rootGroup; - //reset __groupStack as all the child group nodes are all removed. - this.__groupStack = []; - if (transform) { - this.__addTransform(transform); - } - }; - - /** - * "Clears" a canvas by just drawing a white rectangle in the current group. - */ - clearRect(x, y, width, height) { - //clear entire canvas - if (x === 0 && y === 0 && width === this.width && height === this.height) { - this.__clearCanvas(); - return - } - var rect, parent = this.__closestGroupOrSvg(); - rect = this.__createElement("rect", { - x: x, - y: y, - width: width, - height: height, - fill: "#FFFFFF" - }, true); - parent.appendChild(rect); - }; - - /** - * Adds a linear gradient to a defs tag. - * Returns a canvas gradient object that has a reference to it's parent def - */ - createLinearGradient(x1, y1, x2, y2) { - var grad = this.__createElement("linearGradient", { - id: randomString(this.__ids), - x1: x1 + "px", - x2: x2 + "px", - y1: y1 + "px", - y2: y2 + "px", - "gradientUnits": "userSpaceOnUse" - }, false); - this.__defs.appendChild(grad); - return new CanvasGradient(grad, this) - }; - - /** - * Adds a radial gradient to a defs tag. - * Returns a canvas gradient object that has a reference to it's parent def - */ - createRadialGradient(x0, y0, r0, x1, y1, r1) { - var grad = this.__createElement("radialGradient", { - id: randomString(this.__ids), - cx: x1 + "px", - cy: y1 + "px", - r: r1 + "px", - fx: x0 + "px", - fy: y0 + "px", - "gradientUnits": "userSpaceOnUse" - }, false); - this.__defs.appendChild(grad); - return new CanvasGradient(grad, this) - - }; - - /** - * Parses the font string and returns svg mapping - * @private - */ - __parseFont() { - var regex = /^\s*(?=(?:(?:[-a-z]+\s*){0,2}(italic|oblique))?)(?=(?:(?:[-a-z]+\s*){0,2}(small-caps))?)(?=(?:(?:[-a-z]+\s*){0,2}(bold(?:er)?|lighter|[1-9]00))?)(?:(?:normal|\1|\2|\3)\s*){0,3}((?:xx?-)?(?:small|large)|medium|smaller|larger|[.\d]+(?:\%|in|[cem]m|ex|p[ctx]))(?:\s*\/\s*(normal|[.\d]+(?:\%|in|[cem]m|ex|p[ctx])))?\s*([-,\'\"\sa-z0-9]+?)\s*$/i; - var fontPart = regex.exec(this.font); - var data = { - style: fontPart[1] || 'normal', - size: fontPart[4] || '10px', - family: fontPart[6] || 'sans-serif', - weight: fontPart[3] || 'normal', - decoration: fontPart[2] || 'normal', - href: null - }; - - //canvas doesn't support underline natively, but we can pass this attribute - if (this.__fontUnderline === "underline") { - data.decoration = "underline"; - } - - //canvas also doesn't support linking, but we can pass this as well - if (this.__fontHref) { - data.href = this.__fontHref; - } - - return data - }; - - /** - * Helper to link text fragments - * @param font - * @param element - * @return {*} - * @private - */ - __wrapTextLink(font, element) { - if (font.href) { - var a = this.__createElement("a"); - a.setAttributeNS("http://www.w3.org/1999/xlink", "xlink:href", font.href); - a.appendChild(element); - return a - } - return element - }; - - /** - * Fills or strokes text - * @param text - * @param x - * @param y - * @param action - stroke or fill - * @private - */ - __applyText(text, x, y, action) { - var font = this.__parseFont(), - parent = this.__closestGroupOrSvg(), - textElement = this.__createElement("text", { - "font-family": font.family, - "font-size": font.size, - "font-style": font.style, - "font-weight": font.weight, - "text-decoration": font.decoration, - "x": x, - "y": y, - "text-anchor": getTextAnchor(this.textAlign), - "dominant-baseline": getDominantBaseline(this.textBaseline) - }, true); - - textElement.appendChild(this.__document.createTextNode(text)); - this.__currentElement = textElement; - this.__applyStyleToCurrentElement(action); - parent.appendChild(this.__wrapTextLink(font, textElement)); - }; - - /** - * Creates a text element - * @param text - * @param x - * @param y - */ - fillText(text, x, y) { - this.__applyText(text, x, y, "fill"); - }; - - /** - * Strokes text - * @param text - * @param x - * @param y - */ - strokeText(text, x, y) { - this.__applyText(text, x, y, "stroke"); - }; - - /** - * No need to implement this for svg. - * @param text - * @return {TextMetrics} - */ - measureText(text) { - this.__ctx.font = this.font; - return this.__ctx.measureText(text) - }; - - /** - * Arc command! - */ - arc(x, y, radius, startAngle, endAngle, counterClockwise) { - // in canvas no circle is drawn if no angle is provided. - if (startAngle === endAngle) { - return - } - startAngle = startAngle % (2 * Math.PI); - endAngle = endAngle % (2 * Math.PI); - if (startAngle === endAngle) { - //circle time! subtract some of the angle so svg is happy (svg elliptical arc can't draw a full circle) - endAngle = ((endAngle + (2 * Math.PI)) - 0.001 * (counterClockwise ? -1 : 1)) % (2 * Math.PI); - } - var endX = x + radius * Math.cos(endAngle), - endY = y + radius * Math.sin(endAngle), - startX = x + radius * Math.cos(startAngle), - startY = y + radius * Math.sin(startAngle), - sweepFlag = counterClockwise ? 0 : 1, - largeArcFlag = 0, - diff = endAngle - startAngle; - - // https://github.com/gliffy/canvas2svg/issues/4 - if (diff < 0) { - diff += 2 * Math.PI; - } - - if (counterClockwise) { - largeArcFlag = diff > Math.PI ? 0 : 1; - } else { - largeArcFlag = diff > Math.PI ? 1 : 0; - } - - this.lineTo(startX, startY); - this.__addPathCommand(format("A {rx} {ry} {xAxisRotation} {largeArcFlag} {sweepFlag} {endX} {endY}", - { - rx: radius, - ry: radius, - xAxisRotation: 0, - largeArcFlag: largeArcFlag, - sweepFlag: sweepFlag, - endX: endX, - endY: endY - })); - - this.__currentPosition = {x: endX, y: endY}; - }; - - /** - * The ellipse() method creates an elliptical arc centered at (x, y) with the radii radiusX and radiusY. The path - * starts at startAngle and ends at endAngle, and travels in the direction given by counterclockwise (defaulting to clockwise). - */ - // ellipse (x, y, radiusX, radiusY, rotation, startAngle, endAngle, counterclockwise) { - // // TODO -- implement - // } - - /** - * Generates a ClipPath from the clip command. - */ - clip() { - var group = this.__closestGroupOrSvg(), - clipPath = this.__createElement("clipPath"), - id = randomString(this.__ids), - newGroup = this.__createElement("g"); - - this.__applyCurrentDefaultPath(); - group.removeChild(this.__currentElement); - clipPath.setAttribute("id", id); - clipPath.appendChild(this.__currentElement); - - this.__defs.appendChild(clipPath); - - //set the clip path to this group - group.setAttribute("clip-path", format("url(#{id})", {id: id})); - - //clip paths can be scaled and transformed, we need to add another wrapper group to avoid later transformations - // to this path - group.appendChild(newGroup); - - this.__currentElement = newGroup; - - }; - - /** - * Draws a canvas, image or mock context to this canvas. - * Note that all svg dom manipulation uses node.childNodes rather than node.children for IE support. - * http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-drawimage - */ - drawImage() { - //convert arguments to a real array - var args = Array.prototype.slice.call(arguments), - image = args[0], - dx, dy, dw, dh, sx = 0, sy = 0, sw, sh, parent, svg, defs, group, - svgImage, canvas, context, id; - - if (args.length === 3) { - dx = args[1]; - dy = args[2]; - sw = image.width; - sh = image.height; - dw = sw; - dh = sh; - } else if (args.length === 5) { - dx = args[1]; - dy = args[2]; - dw = args[3]; - dh = args[4]; - sw = image.width; - sh = image.height; - } else if (args.length === 9) { - sx = args[1]; - sy = args[2]; - sw = args[3]; - sh = args[4]; - dx = args[5]; - dy = args[6]; - dw = args[7]; - dh = args[8]; - } else { - throw new Error("Invalid number of arguments passed to drawImage: " + arguments.length) - } - - parent = this.__closestGroupOrSvg(); - this.__currentElement; - var translateDirective = "translate(" + dx + ", " + dy + ")"; - if (image instanceof ctx) { - //canvas2svg mock canvas context. In the future we may want to clone nodes instead. - //also I'm currently ignoring dw, dh, sw, sh, sx, sy for a mock context. - svg = image.getSvg().cloneNode(true); - if (svg.childNodes && svg.childNodes.length > 1) { - defs = svg.childNodes[0]; - while (defs.childNodes.length) { - id = defs.childNodes[0].getAttribute("id"); - this.__ids[id] = id; - this.__defs.appendChild(defs.childNodes[0]); - } - group = svg.childNodes[1]; - if (group) { - //save original transform - var originTransform = group.getAttribute("transform"); - var transformDirective; - if (originTransform) { - transformDirective = originTransform + " " + translateDirective; - } else { - transformDirective = translateDirective; - } - group.setAttribute("transform", transformDirective); - parent.appendChild(group); - } - } - } else if (image.nodeName === "CANVAS" || image.nodeName === "IMG") { - //canvas or image - svgImage = this.__createElement("image"); - svgImage.setAttribute("width", dw); - svgImage.setAttribute("height", dh); - svgImage.setAttribute("preserveAspectRatio", "none"); - - if (sx || sy || sw !== image.width || sh !== image.height) { - //crop the image using a temporary canvas - canvas = this.__document.createElement("canvas"); - canvas.width = dw; - canvas.height = dh; - context = canvas.getContext("2d"); - context.drawImage(image, sx, sy, sw, sh, 0, 0, dw, dh); - image = canvas; - } - svgImage.setAttribute("transform", translateDirective); - svgImage.setAttributeNS("http://www.w3.org/1999/xlink", "xlink:href", - image.nodeName === "CANVAS" ? image.toDataURL() : image.getAttribute("src")); - parent.appendChild(svgImage); - } - }; - - /** - * Generates a pattern tag - */ - createPattern(image, repetition) { - - let pattern = this.__document.__createElement("pattern"); - let id = randomString(this.__ids); - let img; - - pattern.setAttribute("id", id); - pattern.setAttribute("width", image.width); - pattern.setAttribute("height", image.height); - if (image.nodeName === "CANVAS" || image.nodeName === "IMG") { - img = this.__createElement("image"); - img.setAttribute("width", image.width); - img.setAttribute("height", image.height); - img.setAttributeNS("http://www.w3.org/1999/xlink", "xlink:href", - image.nodeName === "CANVAS" ? image.toDataURL() : image.getAttribute("src")); - pattern.appendChild(img); - this.__defs.appendChild(pattern); - } else if (image instanceof ctx) { - pattern.appendChild(image.__root.childNodes[1]); - this.__defs.appendChild(pattern); - } - return new CanvasPattern(pattern, this) - }; - - setLineDash(dashArray) { - if (dashArray && dashArray.length > 0) { - this.lineDash = dashArray.join(","); - } else { - this.lineDash = null; - } - }; - - /** - * Not yet implemented - */ - drawFocusRing() { - }; - - createImageData() { - }; - - getImageData() { - }; - - putImageData() { - }; - - globalCompositeOperation() { - }; - - setTransform() { - }; - } - - const Cytoband = function (start, end, name, typestain) { - this.start = start; - this.end = end; - this.name = name; - this.stain = 0; - - // Set the type, either p, n, or c - if (typestain === 'acen') { - this.type = 'c'; - } else { - this.type = typestain.charAt(1); - if (this.type === 'p') { - this.stain = parseInt(typestain.substring(4)); - } - } - }; - - const _version = "2.15.13"; - function version$2() { - return _version - } - - /* - * The MIT License (MIT) - * - * Copyright (c) 2014 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - const DEFAULT_GENOMES_URL = "https://igv.org/genomes/genomes.json"; - const BACKUP_GENOMES_URL = "https://s3.amazonaws.com/igv.org.genomes/genomes.json"; - - const splitLines$1 = splitLines$5; - - const GenomeUtils = { - - loadGenome: async function (options) { - - const cytobandUrl = options.cytobandURL; - const aliasURL = options.aliasURL; - const sequence = await loadFasta(options); - - let aliases; - if (aliasURL) { - aliases = await loadAliases(aliasURL, sequence.config); - } - - const genome = new Genome$1(options, sequence, aliases); - - // Delay loading cytbands untils after genome initialization to use chromosome aliases (1 vs chr1, etc). - if (cytobandUrl) { - genome.cytobands = await loadCytobands(cytobandUrl, sequence.config, genome); - } - - return genome - }, - - initializeGenomes: async function (config) { - - if (!GenomeUtils.KNOWN_GENOMES) { - - const table = {}; - - // Get default genomes - if (config.loadDefaultGenomes !== false) { - try { - const url = DEFAULT_GENOMES_URL + `?randomSeed=${Math.random().toString(36)}&version=${version$2()}`; // prevent caching - const jsonArray = await igvxhr.loadJson(url, {timeout: 5000}); - processJson(jsonArray); - } catch (e) { - console.error(e); - try { - const url = BACKUP_GENOMES_URL + `?randomSeed=${Math.random().toString(36)}&version=${version$2()}`; // prevent caching - const jsonArray = await igvxhr.loadJson(url, {}); - processJson(jsonArray); - } catch (e) { - console.error(e); - console.warn("Errors loading default genome definitions."); - } - } - } - - // Add user-defined genomes - const genomeList = config.genomeList || config.genomes; - if (genomeList) { - if (typeof genomeList === 'string') { - const jsonArray = await igvxhr.loadJson(genomeList, {}); - processJson(jsonArray); - } else { - processJson(genomeList); - } - } - - GenomeUtils.KNOWN_GENOMES = table; - - function processJson(jsonArray) { - jsonArray.forEach(function (json) { - table[json.id] = json; - }); - return table - } - } - }, - - isWholeGenomeView: function (chr) { - return 'all' === chr.toLowerCase() - }, - - // Expand a genome id to a reference object, if needed - expandReference: function (alert, idOrConfig) { - - // idOrConfig might be json - if (isString$2(idOrConfig) && idOrConfig.startsWith("{")) { - try { - idOrConfig = JSON.parse(idOrConfig); - } catch (e) { - // Apparently its not json, could be an ID starting with "{". Unusual but legal. - } - } - - let genomeID; - if (isString$2(idOrConfig)) { - genomeID = idOrConfig; - } else if (idOrConfig.genome) { - genomeID = idOrConfig.genome; - } else if (idOrConfig.id !== undefined && idOrConfig.fastaURL === undefined) { - // Backward compatibility - genomeID = idOrConfig.id; - } - - if (genomeID) { - const knownGenomes = GenomeUtils.KNOWN_GENOMES; - const reference = knownGenomes[genomeID]; - if (!reference) { - alert.present(new Error(`Unknown genome id: ${genomeID}`), undefined); - } - return reference - } else { - return idOrConfig - } - } - }; - - - class Genome$1 { - - constructor(config, sequence, aliases) { - - this.config = config; - this.id = config.id || generateGenomeID(config); - this.sequence = sequence; - this.chromosomeNames = sequence.chromosomeNames; - this.chromosomes = sequence.chromosomes; // An object (functions as a dictionary) - this.featureDB = new Map(); // Hash of name -> feature, used for search function. - - this.wholeGenomeView = config.wholeGenomeView === undefined || config.wholeGenomeView; - if (this.wholeGenomeView && Object.keys(sequence.chromosomes).length > 1) { - constructWG(this, config); - } else { - this.wgChromosomeNames = sequence.chromosomeNames; - } - - /** - * Return the official chromosome name for the (possibly) alias. Deals with - * 1 <-> chr1, chrM <-> MT, IV <-> chr4, etc. - * @param str - */ - var chrAliasTable = {}, - self = this; - - - // The standard mappings - chrAliasTable["all"] = "all"; - this.chromosomeNames.forEach(function (name) { - var alias = name.startsWith("chr") ? name.substring(3) : "chr" + name; - chrAliasTable[alias.toLowerCase()] = name; - if (name === "chrM") chrAliasTable["mt"] = "chrM"; - if (name === "MT") chrAliasTable["chrm"] = "MT"; - chrAliasTable[name.toLowerCase()] = name; - }); - - // Custom mappings - if (aliases) { - aliases.forEach(function (array) { - // Find the official chr name - var defName, i; - - for (i = 0; i < array.length; i++) { - if (self.chromosomes[array[i]]) { - defName = array[i]; - break - } - } - - if (defName) { - array.forEach(function (alias) { - if (alias !== defName) { - chrAliasTable[alias.toLowerCase()] = defName; - chrAliasTable[alias] = defName; // Should not be needed - } - }); - } - - }); - } - - this.chrAliasTable = chrAliasTable; - - } - - showWholeGenomeView() { - return this.config.wholeGenomeView !== false - } - - toJSON() { - return Object.assign({}, this.config, {tracks: undefined}) - } - - getInitialLocus() { - - } - - getHomeChromosomeName() { - if (this.showWholeGenomeView() && this.chromosomes.hasOwnProperty("all")) { - return "all" - } else { - return this.chromosomeNames[0] - - } - } - - getChromosomeName(str) { - const chr = str ? this.chrAliasTable[str.toLowerCase()] : str; - return chr ? chr : str - } - - getChromosome(chr) { - chr = this.getChromosomeName(chr); - return this.chromosomes[chr] - } - - getCytobands(chr) { - return this.cytobands ? this.cytobands[chr] : null - } - - getLongestChromosome() { - - var longestChr, - chromosomes = this.chromosomes; - for (let key in chromosomes) { - if (chromosomes.hasOwnProperty(key)) { - var chr = chromosomes[key]; - if (longestChr === undefined || chr.bpLength > longestChr.bpLength) { - longestChr = chr; - } - } - return longestChr - } - } - - getChromosomes() { - return this.chromosomes - } - - /** - * Return the genome coordinate in kb for the give chromosome and position. - * NOTE: This might return undefined if the chr is filtered from whole genome view. - */ - getGenomeCoordinate(chr, bp) { - - var offset = this.getCumulativeOffset(chr); - if (offset === undefined) return undefined - - return offset + bp - } - - /** - * Return the chromosome and coordinate in bp for the given genome coordinate - */ - getChromosomeCoordinate(genomeCoordinate) { - - if (this.cumulativeOffsets === undefined) { - this.cumulativeOffsets = computeCumulativeOffsets.call(this); - } - - let lastChr = undefined; - let lastCoord = 0; - for (let name of this.wgChromosomeNames) { - - const cumulativeOffset = this.cumulativeOffsets[name]; - if (cumulativeOffset > genomeCoordinate) { - const position = genomeCoordinate - lastCoord; - return {chr: lastChr, position: position} - } - lastChr = name; - lastCoord = cumulativeOffset; - } - - // If we get here off the end - return {chr: this.wgChromosomeNames[this.wgChromosomeNames.length - 1], position: 0} - - }; - - - /** - * Return the offset in genome coordinates (kb) of the start of the given chromosome - * NOTE: This might return undefined if the chromosome is filtered from whole genome view. - */ - getCumulativeOffset(chr) { - - if (this.cumulativeOffsets === undefined) { - this.cumulativeOffsets = computeCumulativeOffsets.call(this); - } - - const queryChr = this.getChromosomeName(chr); - return this.cumulativeOffsets[queryChr] - - function computeCumulativeOffsets() { - - let self = this; - let acc = {}; - let offset = 0; - for (let name of self.wgChromosomeNames) { - - acc[name] = Math.floor(offset); - - const chromosome = self.getChromosome(name); - - offset += chromosome.bpLength; - } - - return acc - } - } - - /** - * Return the nominal genome length, this is the length of the main chromosomes (no scaffolds, etc). - */ - getGenomeLength() { - - let self = this; - - if (!this.bpLength) { - let bpLength = 0; - self.wgChromosomeNames.forEach(function (cname) { - let c = self.chromosomes[cname]; - bpLength += c.bpLength; - }); - this.bpLength = bpLength; - } - return this.bpLength - } - - async getSequence(chr, start, end) { - chr = this.getChromosomeName(chr); - return this.sequence.getSequence(chr, start, end) - } - - addFeaturesToDB(featureList, config) { - - const insertFeature = (name, feature) => { - const current = this.featureDB.get(name); - if (current) { - feature = (feature.end - feature.start) > (current.end - current.start) ? feature : current; - - } - this.featureDB.set(name, feature); - }; - - for (let feature of featureList) { - if (feature.name) { - insertFeature(feature.name.toUpperCase(), feature); - } - if (feature.gene && feature.gene.name) { - insertFeature(feature.gene.name.toUpperCase(), feature); - } - - if (config.searchableFields) { - for (let f of config.searchableFields) { - const value = feature.getAttributeValue(f); - if (value) { - if (value.indexOf(" ") > 0) { - insertFeature(value.replaceAll(" ", "+").toUpperCase(), feature); - } else { - insertFeature(value.toUpperCase(), feature); - } - } - } - } - } - } - } - - async function loadCytobands(cytobandUrl, config, genome) { - - let data; - if (isDataURL(cytobandUrl)) { - const plain = decodeDataURI$1(cytobandUrl); - data = ""; - const len = plain.length; - for (let i = 0; i < len; i++) { - data += String.fromCharCode(plain[i]); - } - } else { - data = await igvxhr.loadString(cytobandUrl, buildOptions$1(config)); - } - - // var bands = [], - // lastChr, - // n = 0, - // c = 1, - // - // len = lines.length, - const cytobands = {}; - let lastChr; - let bands = []; - const lines = splitLines$1(data); - for (let line of lines) { - var tokens = line.split("\t"); - var chr = genome.getChromosomeName(tokens[0]); - if (!lastChr) lastChr = chr; - - if (chr !== lastChr) { - cytobands[lastChr] = bands; - bands = []; - lastChr = chr; - } - - if (tokens.length === 5) { - //10 0 3000000 p15.3 gneg - var start = parseInt(tokens[1]); - var end = parseInt(tokens[2]); - var name = tokens[3]; - var stain = tokens[4]; - bands.push(new Cytoband(start, end, name, stain)); - } - } - - return cytobands - } - - function loadAliases(aliasURL, config) { - - return igvxhr.loadString(aliasURL, buildOptions$1(config)) - - .then(function (data) { - - var lines = splitLines$1(data), - aliases = []; - - lines.forEach(function (line) { - if (!line.startsWith("#") && line.length > 0) aliases.push(line.split("\t")); - }); - - return aliases - }) - - } - - function constructWG(genome, config) { - - let wgChromosomes; - if (config.chromosomeOrder) { - if (Array.isArray(config.chromosomeOrder)) { - genome.wgChromosomeNames = config.chromosomeOrder; - } else { - genome.wgChromosomeNames = config.chromosomeOrder.split(',').map(nm => nm.trim()); - } - wgChromosomes = genome.wgChromosomeNames.map(nm => genome.chromosomes[nm]).filter(chr => chr !== undefined); - - } else { - - // Trim small chromosomes. - const lengths = Object.keys(genome.chromosomes).map(key => genome.chromosomes[key].bpLength); - const median = lengths.reduce((a, b) => Math.max(a, b)); - const threshold = median / 50; - wgChromosomes = Object.values(genome.chromosomes).filter(chr => chr.bpLength > threshold); - - // Sort chromosomes. First segregate numeric and alpha names, sort numeric, leave alpha as is - const numericChromosomes = wgChromosomes.filter(chr => isDigit(chr.name.replace('chr', ''))); - const alphaChromosomes = wgChromosomes.filter(chr => !isDigit(chr.name.replace('chr', ''))); - numericChromosomes.sort((a, b) => Number.parseInt(a.name.replace('chr', '')) - Number.parseInt(b.name.replace('chr', ''))); - - const wgChromosomeNames = numericChromosomes.map(chr => chr.name); - for (let chr of alphaChromosomes) { - wgChromosomeNames.push(chr.name); - } - genome.wgChromosomeNames = wgChromosomeNames; - } - - - // Compute psuedo-chromosome "all" - const l = wgChromosomes.reduce((accumulator, currentValue) => accumulator += currentValue.bpLength, 0); - genome.chromosomes["all"] = { - name: "all", - bpLength: l - }; - - function isDigit(val) { - return /^\d+$/.test(val) - } - - } - - function generateGenomeID(config) { - if (config.id !== undefined) { - return config.id - } else if (config.fastaURL && isString$2(config.fastaURL)) { - return config.fastaURL - } else if (config.fastaURL && config.fastaURL.name) { - return config.fastaURL.name - } else { - return ("0000" + (Math.random() * Math.pow(36, 4) << 0).toString(36)).slice(-4) - } - } - - /** - * Created by dat on 9/16/16. - */ - - const NOT_LOADED_MESSAGE = 'Error loading track data'; - let lastClickTime = 0; - let lastHoverUpdateTime = 0; - let popupTimerID; - - class TrackViewport extends Viewport { - - constructor(trackView, viewportColumn, referenceFrame, width) { - super(trackView, viewportColumn, referenceFrame, width); - } - - initializationHelper() { - - this.$spinner = $$1('
', {class: 'igv-loading-spinner-container'}); - this.$viewport.append(this.$spinner); - this.$spinner.append($$1('
')); - - const track = this.trackView.track; - if ('sequence' !== track.type) { - this.$zoomInNotice = this.createZoomInNotice(this.$viewport); - } - - if (track.name && "sequence" !== track.id) { - this.$trackLabel = $$1('
'); - this.$viewport.append(this.$trackLabel); - this.setTrackLabel(track.name); - if (false === this.browser.trackLabelsVisible) { - this.$trackLabel.hide(); - } - } - - this.stopSpinner(); - this.addMouseHandlers(); - } - - setContentHeight(contentHeight) { - super.setContentHeight(contentHeight); - if (this.featureCache) this.featureCache.redraw = true; - } - - setTrackLabel(label) { - - this.$trackLabel.empty(); - this.$trackLabel.html(label); - - const txt = this.$trackLabel.text(); - this.$trackLabel.attr('title', txt); - } - - startSpinner() { - this.$spinner.show(); - } - - stopSpinner() { - if (this.$spinner) { - this.$spinner.hide(); - } - } - - /** - * Test to determine if we are zoomed in far enough to see features. Applicable to tracks with visibility windows. - * - * As a side effect the viewports canvas is removed if zoomed out. - * - * @returns {boolean} true if we are zoomed in past visibility window, false otherwise - */ - checkZoomIn() { - - const zoomedOutOfWindow = () => { - if (this.referenceFrame.chr.toLowerCase() === "all" && !this.trackView.track.supportsWholeGenome) { - return true - } else { - const visibilityWindow = this.trackView.track.visibilityWindow; - return ( - visibilityWindow !== undefined && visibilityWindow > 0 && - (this.referenceFrame.bpPerPixel * this.$viewport.width() > visibilityWindow)) - } - }; - - if (this.trackView.track && "sequence" === this.trackView.track.type && this.referenceFrame.bpPerPixel > bppFeatureFetchThreshold) { - $$1(this.canvas).remove(); - this.canvas = undefined; - //this.featureCache = undefined - return false - } - - if (!(this.viewIsReady())) { - return false - } - - - if (zoomedOutOfWindow()) { - - // Out of visibility window - if (this.canvas) { - $$1(this.canvas).remove(); - this.canvas = undefined; - //this.featureCache = undefined - } - if (this.trackView.track.autoHeight) { - const minHeight = this.trackView.minHeight || 0; - this.setContentHeight(minHeight); - } - if (this.$zoomInNotice) { - this.$zoomInNotice.show(); - } - return false - } else { - if (this.$zoomInNotice) { - this.$zoomInNotice.hide(); - } - return true - } - - } - - /** - * Adjust the canvas to the current genomic state. - */ - shift() { - const referenceFrame = this.referenceFrame; - if (this.canvas && - this.canvas._data && - this.canvas._data.referenceFrame.chr === this.referenceFrame.chr && - this.canvas._data.bpPerPixel === referenceFrame.bpPerPixel) { - const pixelOffset = Math.round((this.canvas._data.bpStart - referenceFrame.start) / referenceFrame.bpPerPixel); - this.canvas.style.left = pixelOffset + "px"; - } - } - - /** - * Set the content top of the current view. This is triggered by scrolling. If the current canvas extent is not - * sufficient to cover the new vertical range repaint. - * - * @param contentTop - the "top" property of the virtual content div, 0 unless track is scrolled vertically - * - * - */ - setTop(contentTop) { - - super.setTop(contentTop); - - if (!this.canvas) { - this.repaint(); - } else { - // See if currently painted canvas covers the vertical range of the viewport. If not repaint - const h = this.$viewport.height(); - const vt = contentTop + this.canvas._data.pixelTop; - const vb = vt + this.canvas._data.pixelHeight; - if (vt > 0 || vb < h) { - this.repaint(); - } - } - - // Now offset backing canvas to align with the contentTop visual offset. - let offset = contentTop + this.canvas._data.pixelTop; - this.canvas.style.top = `${offset}px`; - } - - async loadFeatures() { - - const referenceFrame = this.referenceFrame; - const chr = referenceFrame.chr; - - // Expand the requested range so we can pan a bit without reloading. But not beyond chromosome bounds - const chrLength = this.browser.genome.getChromosome(chr).bpLength; - const pixelWidth = this.$viewport.width();// * 3; - const bpWidth = pixelWidth * referenceFrame.bpPerPixel; - const bpStart = Math.floor(Math.max(0, referenceFrame.start - bpWidth)); - const bpEnd = Math.ceil(Math.min(chrLength, referenceFrame.start + bpWidth + bpWidth)); // Add one screen width to end - - if (this.loading && this.loading.start === bpStart && this.loading.end === bpEnd) { - return undefined - } - this.loading = {start: bpStart, end: bpEnd}; - this.startSpinner(); - - try { - const track = this.trackView.track; - const features = await this.getFeatures(track, chr, bpStart, bpEnd, referenceFrame.bpPerPixel); - if (features) { - let roiFeatures = []; - if (track.roiSets && track.roiSets.length > 0) { - for (let roiSet of track.roiSets) { - const features = await roiSet.getFeatures(chr, bpStart, bpEnd, referenceFrame.bpPerPixel); - roiFeatures.push({track: roiSet, features}); - } - } - - const mr = track && ("wig" === track.type || "merged" === track.type); // wig tracks are potentially multiresolution (e.g. bigwig) - this.featureCache = new FeatureCache(chr, bpStart, bpEnd, referenceFrame.bpPerPixel, features, roiFeatures, mr); - this.loading = false; - this.hideMessage(); - this.stopSpinner(); - return this.featureCache - } - } catch (error) { - // Track might have been removed during load - if (this.trackView && this.trackView.disposed !== true) { - this.showMessage(NOT_LOADED_MESSAGE); - this.browser.alert.present(error); - console.error(error); - } - } finally { - this.loading = false; - this.stopSpinner(); - } - } - - /** - * Compute the genomic extent and needed pixelWidth to repaint the canvas for the current genomic state. - * Normally the canvas is size 3X the width of the viewport, however there is no left-right panning for WGV so - * canvas width is viewport width. - * @returns {{bpEnd: *, pixelWidth: (*|number), bpStart: number}} - */ - repaintDimensions() { - const isWGV = GenomeUtils.isWholeGenomeView(this.referenceFrame.chr); - const pixelWidth = isWGV ? this.$viewport.width() : 3 * this.$viewport.width(); - const bpPerPixel = this.referenceFrame.bpPerPixel; - const bpStart = this.referenceFrame.start - (isWGV ? 0 : pixelWidth / 3 * bpPerPixel); - const bpEnd = this.referenceFrame.end + (isWGV ? 0 : pixelWidth / 3 * bpPerPixel); - return { - bpStart, bpEnd, pixelWidth - } - } - - /** - * Repaint the canvas using the cached features - * - */ - repaint() { - - if (undefined === this.featureCache) { - return - } - - const {features, roiFeatures} = this.featureCache; - - // Canvas dimensions. - // For deep tracks we paint a canvas == 3*viewportHeight centered on the current vertical scroll position - const {bpStart, bpEnd, pixelWidth} = this.repaintDimensions(); - const viewportHeight = this.$viewport.height(); - const contentHeight = this.getContentHeight(); - const maxHeight = roiFeatures ? Math.max(contentHeight, viewportHeight) : contentHeight; // Need to fill viewport for ROIs. - const pixelHeight = Math.min(maxHeight, 3 * viewportHeight); - if (0 === pixelWidth || 0 === pixelHeight) { - if (this.canvas) { - $$1(this.canvas).remove(); - } - return - } - const pixelTop = Math.max(0, -this.contentTop - Math.floor(pixelHeight / 3)); - - const bpPerPixel = this.referenceFrame.bpPerPixel; - const pixelXOffset = Math.round((bpStart - this.referenceFrame.start) / bpPerPixel); - const canvasTop = (this.contentTop || 0) + pixelTop; - const newCanvas = document.createElement('canvas');// $('').get(0) - newCanvas.style.position = 'relative'; - newCanvas.style.display = 'block'; - newCanvas.style.width = pixelWidth + "px"; - newCanvas.style.height = pixelHeight + "px"; - newCanvas.style.left = pixelXOffset + "px"; - newCanvas.style.top = canvasTop + "px"; - - // Always use high DPI if in "FILL" display mode, otherwise use track setting; - const devicePixelRatio = ("FILL" === this.trackView.track.displayMode || this.trackView.track.supportHiDPI !== false) ? - window.devicePixelRatio : 1; - newCanvas.width = devicePixelRatio * pixelWidth; - newCanvas.height = devicePixelRatio * pixelHeight; - - const ctx = newCanvas.getContext("2d"); - ctx.scale(devicePixelRatio, devicePixelRatio); - ctx.translate(0, -pixelTop); - - const drawConfiguration = - { - context: ctx, - pixelXOffset, - pixelWidth, - pixelHeight, - pixelTop, - bpStart, - bpEnd: bpEnd, - bpPerPixel, - referenceFrame: this.referenceFrame, - selection: this.selection, - viewport: this, - viewportWidth: this.$viewport.width() - }; - - this.draw(drawConfiguration, features, roiFeatures); - - if (this.canvas) { - $$1(this.canvas).remove(); - } - newCanvas._data = drawConfiguration; - this.canvas = newCanvas; - this.$viewport.append($$1(newCanvas)); - - } - - refresh() { - if (!(this.canvas && this.featureCache)) return - - const drawConfiguration = this.canvas._data; - drawConfiguration.context.clearRect(0, 0, this.canvas.width, this.canvas.height); - const {features, roiFeatures} = this.featureCache; - this.draw(drawConfiguration, features, roiFeatures); - } - - /** - * Draw the associated track. - * - * @param drawConfiguration - * @param features - * @param roiFeatures - */ - draw(drawConfiguration, features, roiFeatures) { - - if (features) { - drawConfiguration.features = features; - this.trackView.track.draw(drawConfiguration); - } - if (roiFeatures && roiFeatures.length > 0) { - for (let r of roiFeatures) { - drawConfiguration.features = r.features; - r.track.draw(drawConfiguration); - } - } - } - - containsPosition(chr, position) { - if (this.referenceFrame.chr === chr && position >= this.referenceFrame.start) { - return position <= this.referenceFrame.calculateEnd(this.getWidth()) - } else { - return false - } - } - - isLoading() { - return this.loading - } - - savePNG() { - - if (!this.canvas) return - - const canvasMetadata = this.canvas._data; - const canvasTop = canvasMetadata ? canvasMetadata.pixelTop : 0; - const devicePixelRatio = window.devicePixelRatio; - const w = this.$viewport.width() * devicePixelRatio; - const h = this.$viewport.height() * devicePixelRatio; - const x = -$$1(this.canvas).position().left * devicePixelRatio; - const y = (-this.contentTop - canvasTop) * devicePixelRatio; - - const ctx = this.canvas.getContext("2d"); - const imageData = ctx.getImageData(x, y, w, h); - const exportCanvas = document.createElement('canvas'); - const exportCtx = exportCanvas.getContext('2d'); - exportCanvas.width = imageData.width; - exportCanvas.height = imageData.height; - exportCtx.putImageData(imageData, 0, 0); - - // filename = this.trackView.track.name + ".png"; - const filename = (this.$trackLabel.text() ? this.$trackLabel.text() : "image") + ".png"; - const data = exportCanvas.toDataURL("image/png"); - download(filename, data); - } - - saveSVG() { - - const marginTop = 32; - const marginLeft = 32; - - let {width, height} = this.browser.columnContainer.getBoundingClientRect(); - - const h_render = 8000; - - const config = - { - - width, - height: h_render, - - backdropColor: 'white', - - multiLocusGap: 0, - - viewbox: - { - x: 0, - y: 0, - width, - height: h_render - } - - }; - - const context = new ctx(config); - - const delta = - { - deltaX: marginLeft, - deltaY: marginTop - }; - - this.renderViewportToSVG(context, delta); - - // reset height to trim away unneeded svg canvas real estate. Yes, a bit of a hack. - context.setHeight(height); - - const str = (this.trackView.track.name || this.trackView.track.id).replace(/\W/g, ''); - const index = this.browser.referenceFrameList.indexOf(this.referenceFrame); - - const svg = context.getSerializedSvg(true); - const data = URL.createObjectURL(new Blob([svg], {type: "application/octet-stream"})); - - const id = `${str}_referenceFrame_${index}_guid_${domUtils$1.guid()}`; - download(`${id}.svg`, data); - - } - - // called by trackView.renderSVGContext() when rendering - // entire browser as SVG - - renderViewportToSVG(context, {deltaX, deltaY}) { - - if (this.$zoomInNotice && this.$zoomInNotice.is(":visible")) { - return - } - - const {width, height} = this.$viewport.get(0).getBoundingClientRect(); - - const str = (this.trackView.track.name || this.trackView.track.id).replace(/\W/g, ''); - const index = this.browser.referenceFrameList.indexOf(this.referenceFrame); - const id = `${str}_referenceFrame_${index}_guid_${domUtils$1.guid()}`; - this.drawSVGWithContext(context, width, height, id, deltaX, deltaY + this.contentTop, -this.contentTop); - - } - - renderSVGContext(context, {deltaX, deltaY}) { - - this.renderViewportToSVG(context, {deltaX, deltaY}); - - if (this.$zoomInNotice && this.$zoomInNotice.is(":visible")) { - return - } - - if (this.$trackLabel && true === this.browser.trackLabelsVisible) { - const {x, y, width, height} = domUtils$1.relativeDOMBBox(this.$viewport.get(0), this.$trackLabel.get(0)); - this.renderTrackLabelSVG(context, deltaX + x, deltaY + y, width, height); - } - - } - - // render track label element called from renderSVGContext() - renderTrackLabelSVG(context, tx, ty, width, height) { - - const str = (this.trackView.track.name || this.trackView.track.id).replace(/\W/g, ''); - const id = `${str}_track_label_guid_${domUtils$1.guid()}`; - - context.saveWithTranslationAndClipRect(id, tx, ty, width, height, 0); - - context.fillStyle = "white"; - context.fillRect(0, 0, width, height); - - context.font = "12px Arial"; - context.fillStyle = 'rgb(68, 68, 68)'; - - const {width: stringWidth} = context.measureText(this.$trackLabel.text()); - const dx = 0.25 * (width - stringWidth); - const dy = 0.7 * (height - 12); - context.fillText(this.$trackLabel.text(), dx, height - dy); - - context.strokeStyle = 'rgb(68, 68, 68)'; - context.strokeRect(0, 0, width, height); - - context.restore(); - - } - - // called by renderSVGContext() - drawSVGWithContext(context, width, height, id, x, y, yClipOffset) { - - context.saveWithTranslationAndClipRect(id, x, y, width, height, yClipOffset); - - let {start, bpPerPixel} = this.referenceFrame; - - const config = - { - context, - viewport: this, - referenceFrame: this.referenceFrame, - top: yClipOffset, - pixelTop: yClipOffset, - pixelWidth: width, - pixelHeight: height, - bpStart: start, - bpEnd: start + (width * bpPerPixel), - bpPerPixel, - viewportWidth: width, - selection: this.selection - }; - - const features = this.featureCache ? this.featureCache.features : undefined; - const roiFeatures = this.featureCache ? this.featureCache.roiFeatures : undefined; - this.draw(config, features, roiFeatures); - - context.restore(); - - } - - get cachedFeatures() { - return this.featureCache ? this.featureCache.features : [] - } - - clearCache() { - this.featureCache = undefined; - if (this.canvas) this.canvas._data = undefined; - } - - async getFeatures(track, chr, start, end, bpPerPixel) { - if (this.featureCache && this.featureCache.containsRange(chr, start, end, bpPerPixel)) { - return this.featureCache.features - } else if (typeof track.getFeatures === "function") { - const features = await track.getFeatures(chr, start, end, bpPerPixel, this); - this.checkContentHeight(features); - return features - } else { - return undefined - } - } - - needsRepaint() { - - if (!this.canvas) return true - - const data = this.canvas._data; - return !data || - this.referenceFrame.start < data.bpStart || - this.referenceFrame.end > data.bpEnd || - this.referenceFrame.chr !== data.referenceFrame.chr || - this.referenceFrame.bpPerPixel != data.bpPerPixel - } - - needsReload() { - if (!this.featureCache) return true - const {chr, bpPerPixel} = this.referenceFrame; - const {bpStart, bpEnd} = this.repaintDimensions(); - return (!this.featureCache.containsRange(chr, bpStart, bpEnd, bpPerPixel)) - } - - createZoomInNotice($parent) { - - const $container = $$1('
', {class: 'igv-zoom-in-notice-container'}); - $parent.append($container); - - const $e = $$1('
'); - $container.append($e); - - $e.text('Zoom in to see features'); - - $container.hide(); - - return $container - } - - viewIsReady() { - return this.browser && this.browser.referenceFrameList && this.referenceFrame - } - - addMouseHandlers() { - - const viewport = this.$viewport.get(0); - - this.addViewportContextMenuHandler(viewport); - - // Mouse down - const md = (event) => { - this.enableClick = true; - this.browser.mouseDownOnViewport(event, this); - domUtils$1.pageCoordinates(event); - }; - viewport.addEventListener('mousedown', md); - viewport.addEventListener('touchstart', md); - - // Mouse up - const mu = (event) => { - // Any mouse up cancels drag and scrolling - if (this.browser.dragObject || this.browser.isScrolling) { - this.browser.cancelTrackPan(); - // event.preventDefault(); - // event.stopPropagation(); - this.enableClick = false; // Until next mouse down - } else { - this.browser.cancelTrackPan(); - this.browser.endTrackDrag(); - } - }; - viewport.addEventListener('mouseup', mu); - viewport.addEventListener('touchend', mu); - - // Mouse move - if (typeof this.trackView.track.hoverText === 'function') { - viewport.addEventListener('mousemove', (event => { - if (event.buttons === 0 && (Date.now() - lastHoverUpdateTime > 100)) { - lastHoverUpdateTime = Date.now(); - const clickState = this.createClickState(event); - if (clickState) { - const tooltip = this.trackView.track.hoverText(clickState); - if (tooltip) { - this.$viewport[0].setAttribute("title", tooltip); - } else { - this.$viewport[0].removeAttribute("title"); - } - } - } - })); - } - - this.addViewportClickHandler(this.$viewport.get(0)); - - if (this.trackView.track.name && "sequence" !== this.trackView.track.config.type) { - this.addTrackLabelClickHandler(this.$trackLabel.get(0)); - } - - } - - addViewportContextMenuHandler(viewport) { - - viewport.addEventListener('contextmenu', (event) => { - - // Ignore if we are doing a drag. This can happen with touch events. - if (this.browser.dragObject) { - return false - } - - const clickState = this.createClickState(event); - - if (undefined === clickState) { - return false - } - - event.preventDefault(); - - // Track specific items - let menuItems = []; - if (typeof this.trackView.track.contextMenuItemList === "function") { - const trackMenuItems = this.trackView.track.contextMenuItemList(clickState); - if (trackMenuItems) { - menuItems = trackMenuItems; - } - } - - // Add items common to all tracks - if (menuItems.length > 0) { - menuItems.push({label: $$1('
')}); - } - - menuItems.push({label: 'Save Image (PNG)', click: () => this.savePNG()}); - menuItems.push({label: 'Save Image (SVG)', click: () => this.saveSVG()}); - - this.browser.menuPopup.presentTrackContextMenu(event, menuItems); - }); - - } - - - addViewportClickHandler(viewport) { - - viewport.addEventListener('click', (event) => { - - if (this.enableClick && this.canvas) { - if (3 === event.which || event.ctrlKey) { - return - } - - // Close any currently open popups - $$1('.igv-popover').hide(); - - - if (this.browser.dragObject || this.browser.isScrolling) { - return - } - - // Treat as a mouse click, its either a single or double click. - // Handle here and stop propogation / default - event.preventDefault(); - - const mouseX = domUtils$1.translateMouseCoordinates(event, this.$viewport.get(0)).x; - const mouseXCanvas = domUtils$1.translateMouseCoordinates(event, this.canvas).x; - const referenceFrame = this.referenceFrame; - const xBP = Math.floor((referenceFrame.start) + referenceFrame.toBP(mouseXCanvas)); - - const time = Date.now(); - - if (time - lastClickTime < this.browser.constants.doubleClickDelay) { - - // double-click - if (popupTimerID) { - window.clearTimeout(popupTimerID); - popupTimerID = undefined; - } - - const centerBP = Math.round(referenceFrame.start + referenceFrame.toBP(mouseX)); - - let string; - - if ('all' === this.referenceFrame.chr.toLowerCase()) { - - const chr = this.browser.genome.getChromosomeCoordinate(centerBP).chr; - - if (1 === this.browser.referenceFrameList.length) { - string = chr; - } else { - const loci = this.browser.referenceFrameList.map(({locusSearchString}) => locusSearchString); - const index = this.browser.referenceFrameList.indexOf(this.referenceFrame); - loci[index] = chr; - string = loci.join(' '); - } - - this.browser.search(string); - - } else { - this.browser.zoomWithScaleFactor(0.5, centerBP, this.referenceFrame); - } - - - } else { - // single-click - - if (event.shiftKey && typeof this.trackView.track.shiftClick === "function") { - - this.trackView.track.shiftClick(xBP, event); - - } else if (typeof this.trackView.track.popupData === "function") { - - popupTimerID = setTimeout(() => { - - const content = this.getPopupContent(event); - if (content) { - if (this.popover) this.popover.dispose(); - this.popover = new Popover(this.browser.columnContainer); - this.popover.presentContentWithEvent(event, content); - } - window.clearTimeout(popupTimerID); - popupTimerID = undefined; - }, - this.browser.constants.doubleClickDelay); - } - } - - lastClickTime = time; - - } - }); - } - - addTrackLabelClickHandler(trackLabel) { - - trackLabel.addEventListener('click', (event) => { - - event.stopPropagation(); - - const {track} = this.trackView; - - let str; - if (typeof track.description === 'function') { - str = track.description(); - } else if (track.description) { - str = `
${track.description}
`; - } - - if (str) { - if (this.popover) { - this.popover.dispose(); - } - this.popover = new Popover(this.browser.columnContainer, (track.name || '')); - this.popover.presentContentWithEvent(event, str); - } - }); - } - - createClickState(event) { - - if (!this.canvas) return // Can happen during initialization - - const referenceFrame = this.referenceFrame; - const viewportCoords = domUtils$1.translateMouseCoordinates(event, this.$viewport.get(0)); - const canvasCoords = domUtils$1.translateMouseCoordinates(event, this.canvas); - const genomicLocation = ((referenceFrame.start) + referenceFrame.toBP(viewportCoords.x)); - - return { - event, - viewport: this, - referenceFrame, - genomicLocation, - y: viewportCoords.y - this.contentTop, - canvasX: canvasCoords.x, - canvasY: canvasCoords.y - } - - } - - getPopupContent(event) { - - const clickState = this.createClickState(event); - - if (undefined === clickState) { - return - } - - let track = this.trackView.track; - const dataList = track.popupData(clickState); - - const popupClickHandlerResult = this.browser.fireEvent('trackclick', [track, dataList]); - - let content; - if (undefined === popupClickHandlerResult || true === popupClickHandlerResult) { - // Indicates handler did not handle the result, or the handler wishes default behavior to occur - if (dataList && dataList.length > 0) { - content = formatPopoverText(dataList); - } - - } else if (typeof popupClickHandlerResult === 'string') { - content = popupClickHandlerResult; - } - - return content - } - - - } - - - function formatPopoverText(nameValues) { - - const rows = nameValues.map(nameValue => { - - if (nameValue.name) { - const str = `${nameValue.name}   ${nameValue.value}`; - return `
${str}
` - } else if ('
' === nameValue) { // this can be retired if nameValue.html is allowed. - return nameValue - } else if (nameValue.html) { - return nameValue.html - } else { - return `
${nameValue}
` - } - - }); - - return rows.join('') - } - - class FeatureCache { - - constructor(chr, tileStart, tileEnd, bpPerPixel, features, roiFeatures, multiresolution) { - this.chr = chr; - this.bpStart = tileStart; - this.bpEnd = tileEnd; - this.bpPerPixel = bpPerPixel; - this.features = features; - this.roiFeatures = roiFeatures; - this.multiresolution = multiresolution; - } - - containsRange(chr, start, end, bpPerPixel) { - - // For multi-resolution tracks allow for a 2X change in bpPerPixel - const r = this.multiresolution ? this.bpPerPixel / bpPerPixel : 1; - - return start >= this.bpStart && end <= this.bpEnd && chr === this.chr && r > 0.5 && r < 2 - } - - overlapsRange(chr, start, end) { - return this.chr === chr && end >= this.bpStart && start <= this.bpEnd - } - } - - /** - * Decode UCSC "interact" files. See https://genome.ucsc.edu/goldenpath/help/interact.html - * - 0 string chrom; "Chromosome (or contig, scaffold, etc.). For interchromosomal, use 2 records" - 1 uint chromStart; "Start position of lower region. For interchromosomal, set to chromStart of this region" - 2 uint chromEnd; "End position of upper region. For interchromosomal, set to chromEnd of this region" - 3 string name; "Name of item, for display. Usually 'sourceName/targetName/exp' or empty" - 4 uint score; "Score (0-1000)" - 5 double value; "Strength of interaction or other data value. Typically basis for score" - 6 string exp; "Experiment name (metadata for filtering). Use . if not applicable" - 7 string color; "Item color. Specified as r,g,b or hexadecimal #RRGGBB or html color name, as in //www.w3.org/TR/css3-color/#html4. Use 0 and spectrum setting to shade by score" - 8 string sourceChrom; "Chromosome of source region (directional) or lower region. For non-directional interchromosomal, chrom of this region." - 9 uint sourceStart; "Start position in chromosome of source/lower/this region" - 10 uint sourceEnd; "End position in chromosome of source/lower/this region" - 11 string sourceName; "Identifier of source/lower/this region" - 12 string sourceStrand; "Orientation of source/lower/this region: + or -. Use . if not applicable" - 13 string targetChrom; "Chromosome of target region (directional) or upper region. For non-directional interchromosomal, chrom of other region" - 14 uint targetStart; "Start position in chromosome of target/upper/this region" - 15 uint targetEnd; "End position in chromosome of target/upper/this region" - 16 string targetName; "Identifier of target/upper/this region" - 17 string targetStrand; "Orientation of target/upper/this region: + or -. Use . if not applicable" - * - * @param tokens - * @param ignore - * @returns {*} - */ - function decodeInteract(tokens, header) { - - if (tokens.length < 6) { - console.log("Skipping line: " + tokens.join(' ')); - return undefined - } - - var feature = { - chr: tokens[0], - start: tokens[1], - end: tokens[2], - - chr1: tokens[8], - start1: Number.parseInt(tokens[9]), - end1: Number.parseInt(tokens[10]), - - chr2: tokens[13], - start2: Number.parseInt(tokens[14]), - end2: Number.parseInt(tokens[15]), - - name: tokens[3], - score: Number(tokens[4]), - value: Number(tokens[5]), - color: tokens[7] === '.' ? undefined : tokens[7] === "0" ? "rgb(0,0,0)" : tokens[7], - - }; - - return feature - } - - /** - * Some interpretations of the sequence ontology needed to assemble GFF transcripts. - * - */ - - const transcriptTypes = new Set(['transcript', 'primary_transcript', 'processed_transcript', 'mRNA', 'mrna', - 'lnc_RNA', 'miRNA', 'ncRNA', 'rRNA', 'scRNA', 'snRNA', 'snoRNA', 'tRNA']); - const cdsTypes = new Set(['CDS', 'cds']); - const codonTypes = new Set(['start_codon', 'stop_codon']); - const utrTypes = new Set(['5UTR', '3UTR', 'UTR', 'five_prime_UTR', 'three_prime_UTR', "3'-UTR", "5'-UTR"]); - const exonTypes = new Set(['exon', 'coding-exon']); - - const transcriptPartTypes = new Set(); - for (let cltn of [cdsTypes, codonTypes, utrTypes, exonTypes]) { - for (let t of cltn) { - transcriptPartTypes.add(t); - } - } - - function isExon(type) { - return exonTypes.has(type) - } - - function isIntron(type) { - return type.includes("intron") - } - - function isCoding(type) { - return cdsTypes.has(type) || codonTypes.has(type) - } - - function isUTR(type) { - return utrTypes.has(type) - } - - function isTranscript(type) { - return transcriptTypes.has(type) || type.endsWith("RNA") || type.endsWith("transcript") - } - - function isTranscriptPart(type) { - return transcriptPartTypes.has(type) || type.endsWith("RNA") || isIntron(type) - } - - const filterPopupProperties = new Set(["id", "parent", "name"]); - - class GFFFeature { - - constructor(properties) { - Object.assign(this, properties); - } - - popupData(genomicLocation) { - - const pd = this.geneObject ? this.geneObject.popupData() : []; - - if (this.geneObject) { - pd.push('
'); - } - - if (this.name) { - pd.push({name: 'Name', value: this.name}); - } - - pd.push({name: 'Type', value: this.type}); - pd.push({name: 'Source', value: this.source}); - if (this.score !== undefined) { - pd.push({name: 'Score', value: this.score}); - } - - if (this.attributeString) { - const atts = parseAttributeString(this.attributeString, this.delim); - for (let [key, value] of atts) { - if (value !== undefined && value.length > 0 && !filterPopupProperties.has(key.toLowerCase())) { - pd.push({name: key + ":", value: value}); - } - } - } - pd.push({ - name: 'Location', - value: `${this.chr}:${numberFormatter$1(this.start + 1)}-${numberFormatter$1(this.end)}` - }); - return pd - } - - getAttributeValue(attributeName) { - if (this.hasOwnProperty(attributeName)) { - return this[attributeName] - } else { - // TODO -- fetch from attribute string and cache - if (!this._attributeCache) { - this._attributeCache = new Map(); - } - if (this._attributeCache.has(attributeName)) { - return this._attributeCache.get(attributeName) - } else { - const atts = parseAttributeString(this.attributeString, this.delim); - let v; - for (let [key, value] of atts) { - if (key === attributeName) { - v = value; - break - } - } - this._attributeCache.set(attributeName, v); - return v - } - } - } - } - - class GFFTranscript extends GFFFeature { - - constructor(feature) { - super(feature); - this.exons = []; - this.parts = []; - } - - addExon(feature) { - - this.exons.push(feature); - - // Expand feature -- for transcripts not explicitly represented in the file (gtf) - this.start = Math.min(this.start, feature.start); - this.end = Math.max(this.end, feature.end); - } - - addPart(feature) { - this.parts.push(feature); - } - - assembleParts() { - - if (this.parts.length === 0) return - - this.parts.sort(function (a, b) { - return a.start - b.start - }); - - // Create exons, if neccessary - let lastStart = this.parts[0].start; - let lastEnd = this.parts[0].end; - for (let i = 1; i < this.parts.length; i++) { - const part = this.parts[i]; - if (isIntron(part.type)) { - continue - } - if (part.start <= lastEnd) { - lastEnd = Math.max(lastEnd, part.end); - } else { - let exon = this.findExonContaining({start: lastStart, end: lastEnd}); - if (!exon) { - this.exons.push({start: lastStart, end: lastEnd, psuedo: true}); - } - lastStart = part.start; - lastEnd = part.end; - } - } - let exon = this.findExonContaining({start: lastStart, end: lastEnd}); - if (!exon) { - this.exons.push({start: lastStart, end: lastEnd, psuedo: true}); - this.start = Math.min(this.start, lastStart); - this.end = Math.max(this.end, lastEnd); - } - - - for (let part of this.parts) { - const type = part.type; - if (isCoding(type)) { - this.addCDS(part); - } else if (isUTR(type)) { - this.addUTR(part); - } - } - } - - findExonContaining({start, end}) { - for (let exon of this.exons) { - if (exon.end >= end && exon.start <= start) { - return exon - } - } - return undefined - } - - addCDS(cds) { - - let exon; - const exons = this.exons; - - for (let e of exons) { - if (e.start <= cds.start && e.end >= cds.end) { - exon = e; - break - } - } - - if (exon) { - exon.cdStart = exon.cdStart ? Math.min(cds.start, exon.cdStart) : cds.start; - exon.cdEnd = exon.cdEnd ? Math.max(cds.end, exon.cdEnd) : cds.end; - } else { - // cds.cdStart = cds.start - // cds.cdEnd = cds.end - // exons.push(cds) - console.error("No exon found spanning " + cds.start + "-" + cds.end); - } - - // Expand feature -- for transcripts not explicitly represented in the file (gtf files) - // this.start = Math.min(this.start, cds.start); - // this.end = Math.max(this.end, cds.end); - - this.cdStart = this.cdStart ? Math.min(cds.start, this.cdStart) : cds.start; - this.cdEnd = this.cdEnd ? Math.max(cds.end, this.cdEnd) : cds.end; - } - - addUTR(utr) { - - let exon; - const exons = this.exons; - - // Find exon containing CDS - for (let i = 0; i < exons.length; i++) { - if (exons[i].start <= utr.start && exons[i].end >= utr.end) { - exon = exons[i]; - break - } - } - - if (exon) { - if (utr.start === exon.start && utr.end === exon.end) { - exon.utr = true; - } else { - if (utr.end < exon.end) { - exon.cdStart = utr.end; - } - if (utr.start > exon.start) { - exon.cdEnd = utr.start; - } - } - - } else { - // utr.utr = true - // exons.push(utr) - console.error("No exon found spanning " + cds.start + "-" + cds.end); - } - - // Expand feature -- for transcripts not explicitly represented in the file - // this.start = Math.min(this.start, utr.start); - // this.end = Math.max(this.end, utr.end); - - } - - finish() { - - this.assembleParts(); - - var cdStart = this.cdStart; - var cdEnd = this.cdEnd; - - this.exons.sort(function (a, b) { - return a.start - b.start - }); - - // Search for UTR exons that were not explicitly tagged - if (cdStart) { - this.exons.forEach(function (exon) { - if (exon.end < cdStart || exon.start > cdEnd) exon.utr = true; - }); - } - } - - popupData(genomicLocation) { - - const pd = super.popupData(genomicLocation); - - // If clicked over an exon add its attributes - for (let exon of this.exons) { - if (exon.pseudo) continue // An implicit exon - if (genomicLocation >= exon.start && genomicLocation < exon.end && typeof exon.popupData === 'function') { - pd.push('
'); - const exonData = exon.popupData(genomicLocation); - for (let att of exonData) { - pd.push(att); - } - } - } - - for (let part of this.parts) { - if (genomicLocation >= part.start && genomicLocation < part.end && typeof part.popupData === 'function') { - pd.push('
'); - const partData = part.popupData(genomicLocation); - for (let att of partData) { - pd.push(att); - } - } - } - - - return pd - } - } - - function decode(tokens, header) { - - const format = header.format; - if (tokens.length < 9) { - return undefined // Not a valid gff record - } - - const delim = ('gff3' === format) ? '=' : ' '; - return new GFFFeature({ - source: decodeGFFAttribute(tokens[1]), - type: tokens[2], - chr: tokens[0], - start: parseInt(tokens[3]) - 1, - end: parseInt(tokens[4]), - score: "." === tokens[5] ? undefined : Number(tokens[5]), - strand: tokens[6], - phase: "." === tokens[7] ? 0 : parseInt(tokens[7]), - attributeString: tokens[8], - delim: delim - }) - } - - - /** - * Decode a single gff record (1 line in file). Aggregations such as gene models are constructed at a higher level. - * ctg123 . mRNA 1050 9000 . + . ID=mRNA00001;Parent=gene00001 - * @param tokens - * @param ignore - * @returns {*} - */ - function decodeGFF3(tokens, header) { - - const feature = decode(tokens, header); - - if (!feature) { - return - } - - const attributes = parseAttributeString(feature.attributeString, feature.delim); - - // Search for color value as case insenstivie key - for (let [key, value] of attributes) { - const keyLower = key.toLowerCase(); - if ("color" === keyLower || "colour" === keyLower) { - feature.color = IGVColor.createColorString(value); - } else if (key === "ID") { - feature.id = value; - } else if (key === "Parent") { - feature.parent = value; - } - } - return feature - } - - /** - * GTF format example: - NC_000008.11 BestRefSeq gene 127735434 127742951 . + . gene_id "MYC"; transcript_id ""; db_xref "GeneID:4609"; db_xref "HGNC:HGNC:7553"; db_xref "MIM:190080"; description "MYC proto-oncogene, bHLH transcription factor"; gbkey "Gene"; gene "MYC"; gene_biotype "protein_coding"; gene_synonym "bHLHe39"; gene_synonym "c-Myc"; gene_synonym "MRTL"; gene_synonym "MYCC"; - NC_000008.11 BestRefSeq transcript 127735434 127742951 . + . gene_id "MYC"; transcript_id "NM_001354870.1"; db_xref "GeneID:4609"; gbkey "mRNA"; gene "MYC"; product "MYC proto-oncogene, bHLH transcription factor, transcript variant 2"; transcript_biotype "mRNA"; - NC_000008.11 BestRefSeq exon 127735434 127736623 . + . gene_id "MYC"; transcript_id "NM_001354870.1"; db_xref "GeneID:4609"; gene "MYC"; product "MYC proto-oncogene, bHLH transcription factor, transcript variant 2"; transcript_biotype "mRNA"; exon_number "1"; - * - * @param tokens - * @param ignore - * @returns {*} - */ - function decodeGTF(tokens, header) { - - const feature = decode(tokens, header); - - if (!feature) { - return - } - - const attributes = parseAttributeString(feature.attributeString, feature.delim); - - // GTF files specify neither ID nor parent fields, but they can be inferred from common conventions - let idField; - let parentField; - switch (feature.type) { - case "gene": - idField = "gene_id"; - break - case "transcript": - idField = "transcript_id"; - parentField = "gene_id"; - break - default: - parentField = "transcript_id"; - } - - for (let [key, value] of attributes) { - const keyLower = key.toLowerCase(); - if ("color" === keyLower || "colour" === keyLower) { - feature.color = IGVColor.createColorString(value); - } else if (key === idField) { - feature.id = value; - } else if (key === parentField) { - feature.parent = value; - } - } - return feature - - } - - - /** - * Parse the attribute string, returning an array of key-value pairs. An array is used rather than a map as attribute - * keys are not required to be unique. - * - * @param attributeString - * @param keyValueDelim - * @returns {[]} - */ - function parseAttributeString(attributeString, keyValueDelim, relaxed = false) { - // parse 'attributes' string (see column 9 docs in https://github.com/The-Sequence-Ontology/Specifications/blob/master/gff3.md) - var attributes = []; - for (let kv of attributeString.split(';')) { - kv = kv.trim(); - const idx = kv.indexOf(keyValueDelim); - if (idx > 0 && idx < kv.length - 1) { - const key = stripQuotes(decodeGFFAttribute(kv.substring(0, idx).trim(), relaxed)); - let value = stripQuotes(decodeGFFAttribute(kv.substring(idx + 1).trim(), relaxed)); - attributes.push([key, value]); - } - } - return attributes - } - - function stripQuotes(value) { - if (value.startsWith('"') && value.endsWith('"')) { - value = value.substr(1, value.length - 2); - } - return value - } - - // GFF3 attributes have specific percent encoding rules, the list below are required, all others are forbidden - /* - tab (%09) - newline (%0A) - carriage return (%0D) - % percent (%25) - control characters (%00 through %1F, %7F) - In addition, the following characters have reserved meanings in column 9 and must be escaped when used in other contexts: - ; semicolon (%3B) - = equals (%3D) - & ampersand (%26) - , comma (%2C) - */ - - const encodings$2 = new Map([ - ["%09", "\t"], - ["%0A", "\n"], - ["%0D", "\r"], - ["%25", "%"], - ["%3B", ";"], - ["%3D", "="], - ["%26", "&"], - ["%2C", ","] - ]); - - function decodeGFFAttribute(str, relaxed = false) { - - if (!str.includes("%")) { - return str - } - if (relaxed) { - return decodeURIComponent(str); - } - let decoded = ""; - for (let i = 0; i < str.length; i++) { - - if (str.charCodeAt(i) === 37 && i < str.length - 2) { - const key = str.substring(i, i + 3); - if (encodings$2.has(key)) { - decoded += encodings$2.get(key); - } else { - decoded += key; - } - i += 2; - } else { - decoded += str.charAt(i); - } - } - return decoded - - } - - /** - * Wrapper class to record a decoding error. - */ - - class DecodeError { - constructor(message) { - this.message = message; - } - } - - /** - * Decode the UCSC bed format. Only the first 3 columns (chr, start, end) are required. The remaining columns - * must follow standard bed order, but we will tolerate deviations after column 3. - * - * @param tokens - * @param ignore - * @returns decoded feature, or null if this is not a valid record - */ - function decodeBed(tokens, header) { - - - if (tokens.length < 3) return undefined - - header && header.gffTags; - - const chr = tokens[0]; - const start = parseInt(tokens[1]); - const end = tokens.length > 2 ? parseInt(tokens[2]) : start + 1; - if (isNaN(start) || isNaN(end)) { - return new DecodeError(`Unparsable bed record.`) - } - const feature = new UCSCBedFeature({chr: chr, start: start, end: end, score: 1000}); - - try { - if (tokens.length > 3) { - - // Potentially parse name field as GFF column 9 style streng. - if (tokens[3].indexOf(';') > 0 && tokens[3].indexOf('=') > 0) { - const attributeKVs = parseAttributeString(tokens[3], '=', true); - feature.attributes = {}; - for (let kv of attributeKVs) { - feature.attributes[kv[0]] = kv[1]; - if (header.nameField != undefined && kv[0] === header.nameField) { - feature.name = kv[1]; - } - } - } - if (!feature.name) { - feature.name = tokens[3] === '.' ? '' : tokens[3]; - } - } - - if (tokens.length > 4) { - feature.score = tokens[4] === '.' ? 0 : Number(tokens[4]); - if (isNaN(feature.score)) { - return feature - } - } - - if (tokens.length > 5) { - feature.strand = tokens[5]; - if (!(feature.strand === '.' || feature.strand === '+' || feature.strand === '-')) { - return feature - } - } - - if (tokens.length > 6) { - feature.cdStart = parseInt(tokens[6]); - if (isNaN(feature.cdStart)) { - return feature - } - } - - if (tokens.length > 7) { - feature.cdEnd = parseInt(tokens[7]); - if (isNaN(feature.cdEnd)) { - return feature - } - } - - if (tokens.length > 8) { - if (tokens[8] !== "." && tokens[8] !== "0") - feature.color = IGVColor.createColorString(tokens[8]); - } - - if (tokens.length > 11) { - const exonCount = parseInt(tokens[9]); - // Some basic validation - if (exonCount > 1000) { - // unlikely - return feature - } - - const exonSizes = tokens[10].replace(/,$/, '').split(','); - const exonStarts = tokens[11].replace(/,$/, '').split(','); - if (!(exonSizes.length === exonStarts.length && exonCount === exonSizes.length)) { - return feature - } - - const exons = []; - for (let i = 0; i < exonCount; i++) { - const eStart = start + parseInt(exonStarts[i]); - const eEnd = eStart + parseInt(exonSizes[i]); - exons.push({start: eStart, end: eEnd}); - } - if (exons.length > 0) { - findUTRs$1(exons, feature.cdStart, feature.cdEnd); - feature.exons = exons; - } - } - - // Optional extra columns - if (header) { - let thicknessColumn = header.thicknessColumn; - let colorColumn = header.colorColumn; - if (colorColumn && colorColumn < tokens.length) { - feature.color = IGVColor.createColorString(tokens[colorColumn]); - } - if (thicknessColumn && thicknessColumn < tokens.length) { - feature.thickness = tokens[thicknessColumn]; - } - } - } catch - (e) { - - } - - return feature - } - - /** - * Decode a UCSC repeat masker record. - */ - function decodeRepeatMasker(tokens, header) { - - /** - * Columns, from UCSC documentation - * - * 0 bin 585 smallint(5) unsigned Indexing field to speed chromosome range queries. - * 1 swScore 1504 int(10) unsigned Smith Waterman alignment score - * 2 milliDiv 13 int(10) unsigned Base mismatches in parts per thousand - * 3 milliDel 4 int(10) unsigned Bases deleted in parts per thousand - * 4 milliIns 13 int(10) unsigned Bases inserted in parts per thousand - * 5 genoName chr1 varchar(255) Genomic sequence name - * 6 genoStart 10000 int(10) unsigned Start in genomic sequence - * 7 genoEnd 10468 int(10) unsigned End in genomic sequence - * 8 genoLeft -249240153 int(11) -#bases after match in genomic sequence - * 9 strand + char(1) Relative orientation + or - - * 10 repName (CCCTAA)n varchar(255) Name of repeat - * 11 repClass Simple_repeat varchar(255) Class of repeat - * 12 repFamily Simple_repeat varchar(255) Family of repeat - * 13 repStart 1 int(11) Start (if strand is +) or -#bases after match (if strand is -) in repeat sequence - * 14 repEnd 463 int(11) End in repeat sequence - * 15 repLeft 0 int(11) -#bases after match (if strand is +) or start (if strand is -) in repeat sequence - * 16 id 1 char(1) First digit of id field in RepeatMasker .out file. Best ignored. - */ - if (tokens.length <= 15) return undefined - - const feature = { - swScore: Number.parseInt(tokens[1]), - milliDiv: Number.parseInt(tokens[2]), - milliDel: Number.parseInt(tokens[3]), - milliIns: Number.parseInt(tokens[4]), - chr: tokens[5], - start: Number.parseInt(tokens[6]), - end: Number.parseInt(tokens[7]), - //genoLeft: tokens[8], - strand: tokens[9], - repName: tokens[10], - repClass: tokens[11], - repFamily: tokens[12], - repStart: Number.parseInt(tokens[13]), - repEnd: Number.parseInt(tokens[14]), - repLeft: Number.parseInt(tokens[15]) - }; - - return feature - - } - - /** - * Decode a UCSC "genePred" record. - * - * @param tokens - * @param ignore - * @returns {*} - */ - function decodeGenePred(tokens, header) { - - var shift = header.shift === undefined ? 0 : 1; - - if (tokens.length <= 9 + shift) return undefined - - const cdStart = parseInt(tokens[5 + shift]); - const cdEnd = parseInt(tokens[6 + shift]); - var feature = { - name: tokens[0 + shift], - chr: tokens[1 + shift], - strand: tokens[2 + shift], - start: parseInt(tokens[3 + shift]), - end: parseInt(tokens[4 + shift]), - cdStart: cdStart, - cdEnd: cdEnd, - id: tokens[0 + shift] - }; - const exons = decodeExons(parseInt(tokens[7 + shift]), tokens[8 + shift], tokens[9 + shift]); - findUTRs$1(exons, cdStart, cdEnd); - - feature.exons = exons; - - return feature - - } - - /** - * Decode a UCSC "genePredExt" record. refGene files are in this format. - * - * @param tokens - * @param ignore - * @returns {*} - */ - function decodeGenePredExt(tokens, header) { - - var shift = header.shift === undefined ? 0 : 1; - - if (tokens.length <= 11 + shift) return undefined - - const cdStart = parseInt(tokens[5 + shift]); - const cdEnd = parseInt(tokens[6 + shift]); - const feature = { - name: tokens[11 + shift], - chr: tokens[1 + shift], - strand: tokens[2 + shift], - start: parseInt(tokens[3 + shift]), - end: parseInt(tokens[4 + shift]), - cdStart: cdStart, - cdEnd: cdEnd, - id: tokens[0 + shift] - }; - - const exons = decodeExons(parseInt(tokens[7 + shift]), tokens[8 + shift], tokens[9 + shift]); - findUTRs$1(exons, cdStart, cdEnd); - - feature.exons = exons; - - return feature - } - - /** - * Decode a UCSC "refFlat" record - * @param tokens - * @param ignore - * @returns {*} - */ - function decodeReflat(tokens, header) { - - var shift = header.shift === undefined ? 0 : 1; - - if (tokens.length <= 10 + shift) return undefined - - const cdStart = parseInt(tokens[6 + shift]); - const cdEnd = parseInt(tokens[7 + shift]); - var feature = { - name: tokens[0 + shift], - id: tokens[1 + shift], - chr: tokens[2 + shift], - strand: tokens[3 + shift], - start: parseInt(tokens[4 + shift]), - end: parseInt(tokens[5 + shift]), - cdStart: cdStart, - cdEnd: cdEnd - }; - - const exons = decodeExons(parseInt(tokens[8 + shift]), tokens[9 + shift], tokens[10 + shift]); - findUTRs$1(exons, cdStart, cdEnd); - feature.exons = exons; - - return feature - } - - /** - * Decode a UCS PSL record * - * @param tokens - * @param header - * @returns {DecodeError|UCSCBedFeature|undefined} - */ - function decodePSL(tokens, header) { - - /* - * 0 matches - Number of bases that match that aren't repeats - * 1 misMatches - Number of bases that don't match - * 2 repMatches - Number of bases that match but are part of repeats - * 3 nCount - Number of "N" bases - * 4 qNumInsert - Number of inserts in query - * 5 qBaseInsert - Number of bases inserted in query - * 6 tNumInsert - Number of inserts in target - * 7 tBaseInsert - Number of bases inserted in target - * 8 strand - "+" or "-" for query strand. For translated alignments, second "+"or "-" is for target genomic strand. - * 9 qName - Query sequence name - * 10 qSize - Query sequence size. - * 11 qStart - Alignment start position in query - * 12 qEnd - Alignment end position in query - * 13 tName - Target sequence name - * 14 tSize - Target sequence size - * 15 tStart - Alignment start position in target - * 16 tEnd - Alignment end position in target - * 17 blockCount - Number of blocks in the alignment (a block contains no gaps) - * 18 blockSizes - Comma-separated list of sizes of each block. If the query is a protein and the target the genome, blockSizes are in amino acids. See below for more information on protein query PSLs. - * 19 qStarts - Comma-separated list of starting positions of each block in query - * 20 tStarts - Comma-separated list of starting positions of each block in target - */ - - - if (tokens.length < 21) return undefined - - const chr = tokens[13]; - const start = parseInt(tokens[15]); - const end = parseInt(tokens[16]); - const strand = tokens[8].charAt(0); - const exonCount = parseInt(tokens[17]); - const exons = []; - const exonStarts = tokens[20].replace(/,$/, '').split(','); - const exonSizes = tokens[18].replace(/,$/, '').split(','); - - for (let i = 0; i < exonCount; i++) { - const start = parseInt(exonStarts[i]); - const end = start + parseInt(exonSizes[i]); - exons.push({start: start, end: end}); - } - - return new PSLFeature({chr, start, end, strand, exons, tokens}) - } - - - function decodeExons(exonCountToken, exonStartsToken, exonEndsToken) { - - const exonCount = parseInt(exonCountToken); - const exonStarts = exonStartsToken.replace(/,$/, '').split(','); - const exonEnds = exonEndsToken.replace(/,$/, '').split(','); - const exons = []; - for (let i = 0; i < exonCount; i++) { - const start = parseInt(exonStarts[i]); - const end = parseInt(exonEnds[i]); - exons.push({start: start, end: end}); - } - return exons - - } - - function findUTRs$1(exons, cdStart, cdEnd) { - - for (let exon of exons) { - const end = exon.end; - const start = exon.start; - if (end < cdStart || start > cdEnd) { - exon.utr = true; - } else { - if (cdStart >= start && cdStart <= end) { - exon.cdStart = cdStart; - } - if (cdEnd >= start && cdEnd <= end) { - exon.cdEnd = cdEnd; - } - } - } - - } - - function decodePeak(tokens, header) { - - var tokenCount, chr, start, end, strand, name, score, qValue, signal, pValue; - - tokenCount = tokens.length; - if (tokenCount < 9) { - return undefined - } - - chr = tokens[0]; - start = parseInt(tokens[1]); - end = parseInt(tokens[2]); - name = tokens[3]; - score = Number(tokens[4]); - strand = tokens[5].trim(); - signal = Number(tokens[6]); - pValue = Number(tokens[7]); - qValue = Number(tokens[8]); - - if (score === 0) score = signal; - - return { - chr: chr, start: start, end: end, name: name, score: score, strand: strand, signal: signal, - pValue: pValue, qValue: qValue - } - } - - function decodeBedGraph(tokens, header) { - - var chr, start, end, value; - - if (tokens.length <= 3) return undefined - - chr = tokens[0]; - start = parseInt(tokens[1]); - end = parseInt(tokens[2]); - value = Number(tokens[3]); - const feature = {chr: chr, start: start, end: end, value: value}; - - // Optional extra columns - if (header) { - let colorColumn = header.colorColumn; - if (colorColumn && colorColumn < tokens.length) { - feature.color = IGVColor.createColorString(tokens[colorColumn]); - } - } - - return feature - } - - function decodeWig(tokens, header) { - - const wig = header.wig; - - if (wig && wig.format === "fixedStep") { - const ss = (wig.index * wig.step) + wig.start; - const ee = ss + wig.span; - const value = Number(tokens[0]); - ++(wig.index); - return isNaN(value) ? null : {chr: wig.chrom, start: ss, end: ee, value: value} - } else if (wig && wig.format === "variableStep") { - - if (tokens.length < 2) return null - const ss = parseInt(tokens[0], 10) - 1; - const ee = ss + wig.span; - const value = Number(tokens[1]); - return isNaN(value) ? null : {chr: wig.chrom, start: ss, end: ee, value: value} - - } else { - return decodeBedGraph(tokens) - } - } - - function decodeSNP(tokens, header) { - - if (tokens.length < 6) return undefined - - const autoSql = [ - 'bin', - 'chr', - 'start', - 'end', - 'name', - 'score', - 'strand', - 'refNCBI', - 'refUCSC', - 'observed', - 'molType', - 'class', - 'valid', - 'avHet', - 'avHetSE', - 'func', - 'locType', - 'weight', - 'exceptions', - 'submitterCount', - 'submitters', - 'alleleFreqCount', - 'alleles', - 'alleleNs', - 'alleleFreqs', - 'bitfields' - ]; - - - const feature = { - chr: tokens[1], - start: Number.parseInt(tokens[2]), - end: Number.parseInt(tokens[3]), - name: tokens[4], - score: Number.parseInt(tokens[5]) - }; - - const n = Math.min(tokens.length, autoSql.length); - for (let i = 6; i < n; i++) { - feature[autoSql[i]] = tokens[i]; - } - return feature - - } - - class UCSCBedFeature { - - constructor(properties) { - Object.assign(this, properties); - } - - getAttributeValue(attributeName) { - if (this.hasOwnProperty(attributeName)) { - return this[attributeName] - } else if (this.attributes) { - return this.attributes[attributeName] - } - } - } - - /* - * 0 matches - Number of bases that match that aren't repeats - * 1 misMatches - Number of bases that don't match - * 2 repMatches - Number of bases that match but are part of repeats - * 3 nCount - Number of "N" bases - * 4 qNumInsert - Number of inserts in query - * 5 qBaseInsert - Number of bases inserted in query - * 6 tNumInsert - Number of inserts in target - * 7 tBaseInsert - Number of bases inserted in target - * 8 strand - "+" or "-" for query strand. For translated alignments, second "+"or "-" is for target genomic strand. - * 9 qName - Query sequence name - * 10 qSize - Query sequence size. - * 11 qStart - Alignment start position in query - * 12 qEnd - Alignment end position in query - * 13 tName - Target sequence name - * 14 tSize - Target sequence size - * 15 tStart - Alignment start position in target - * 16 tEnd - Alignment end position in target - * 17 blockCount - Number of blocks in the alignment (a block contains no gaps) - * 18 blockSizes - Comma-separated list of sizes of each block. If the query is a protein and the target the genome, blockSizes are in amino acids. See below for more information on protein query PSLs. - * 19 qStarts - Comma-separated list of starting positions of each block in query - * 20 tStarts - Comma-separated list of starting positions of each block in target - */ - - class PSLFeature { - - - constructor(properties) { - Object.assign(this, properties); - } - - get score() { - const tokens = this.tokens; - const match = parseInt(tokens[0]); - const repMatch = parseInt(tokens[2]); - const misMatch = parseInt(tokens[1]); - const qGapCount = parseInt(tokens[4]); - const tGapCount = parseInt(tokens[6]); - const qSize = parseInt(tokens[10]); - return Math.floor((1000 * (match + repMatch - misMatch - qGapCount - tGapCount)) / qSize) - } - - get matches() { - return this.tokens[0] - } - - get misMatches() { - return this.tokens[1] - } - - get repMatches() { - return this.tokens[2] - } - - get nCount() { - return this.tokens[3] - } - - get qNumInsert() { - return this.tokens[4] - } - - get qBaseInsert() { - return this.tokens[5] - } - - get tNumInsert() { - return this.tokens[6] - } - - get tBaseInsert() { - return this.tokens[7] - - } - - popupData() { - return [ - {name: 'chr', value: this.chr}, - {name: 'start', value: this.start + 1}, - {name: 'end', value: this.end}, - {name: 'strand', value: this.strand}, - {name: 'score', value: this.score}, - {name: 'match', value: this.matches}, - {name: "mis-match", value: this.misMatches}, - {name: "rep. match", value: this.repMatches}, - {name: "N's", value: this.nCount}, - {name: 'Q gap count', value: this.qNumInsert}, - {name: 'Q gap bases', value: this.qBaseInsert}, - {name: 'T gap count', value: this.tNumInsert}, - {name: 'T gap bases', value: this.tBaseInsert}, - ] - } - - } - - function decodeFusionJuncSpan(tokens, header) { - - /* - Format: - - 0 #scaffold - 1 fusion_break_name - 2 break_left - 3 break_right - 4 num_junction_reads - 5 num_spanning_frags - 6 spanning_frag_coords - - 0 B3GNT1--NPSR1 - 1 B3GNT1--NPSR1|2203-10182 - 2 2203 - 3 10182 - 4 189 - 5 1138 - 6 1860-13757,1798-13819,1391-18127,1443-17174,... - - */ - - - if (tokens.length < 7) return undefined - - var chr = tokens[0]; - var fusion_name = tokens[1]; - var junction_left = parseInt(tokens[2]); - var junction_right = parseInt(tokens[3]); - var num_junction_reads = parseInt(tokens[4]); - var num_spanning_frags = parseInt(tokens[5]); - - var spanning_frag_coords_text = tokens[6]; - - var feature = { - chr: chr, - name: fusion_name, - junction_left: junction_left, - junction_right: junction_right, - num_junction_reads: num_junction_reads, - num_spanning_frags: num_spanning_frags, - spanning_frag_coords: [], - - start: -1, - end: -1 - }; // set start and end later based on min/max of span coords - - var min_coord = junction_left; - var max_coord = junction_right; - - if (num_spanning_frags > 0) { - - var coord_pairs = spanning_frag_coords_text.split(','); - - for (var i = 0; i < coord_pairs.length; i++) { - var split_coords = coord_pairs[i].split('-'); - - var span_left = split_coords[0]; - var span_right = split_coords[1]; - - if (span_left < min_coord) { - min_coord = span_left; - } - if (span_right > max_coord) { - max_coord = span_right; - } - feature.spanning_frag_coords.push({left: span_left, right: span_right}); - - } - } - - feature.start = min_coord; - feature.end = max_coord; - - - return feature - - } - - function decodeGtexGWAS(tokens, header) { - //chrom chromStart chromEnd Strongest SNP-risk allele Disease/Phenotype P-value Odds ratio or beta PUBMEDID - //1 1247493 1247494 rs12103-A Inflammatory bowel disease 8.00E-13 1.1 23128233 - - const tokenCount = tokens.length; - if (tokenCount < 7) { - return null - } - const feature = { - chr: tokens[0], - start: parseInt(tokens[1]) - 1, - end: parseInt(tokens[2]), - 'Strongest SNP-risk allele': tokens[3], - 'Disease/Phenotype': tokens[4], - 'P-value': tokens[5], - 'Odds ratio or beta': tokens[6], - }; - if (tokens.length > 6) { - feature['PUBMEDID'] = `${tokens[7]}`; - } - return feature - } - - /** - * Decode a custom columnar format. Required columns are 'chr' and 'start' - * - * @param tokens - * @param ignore - * @returns decoded feature, or null if this is not a valid record - */ - function decodeCustom(tokens, header) { - - const format = header.customFormat; - - if (tokens.length < format.fields.length) return undefined - - const coords = format.coords || 0; - - const chr = tokens[format.chr]; - const start = parseInt(tokens[format.start]) - coords; - const end = format.end !== undefined ? parseInt(tokens[format.end]) : start + 1; - - const feature = {chr: chr, start: start, end: end}; - - if (format.fields) { - format.fields.forEach(function (field, index) { - - if (index !== format.chr && - index !== format.start && - index !== format.end) { - - feature[field] = tokens[index]; - } - }); - } - - return feature - - } - - /** - * Decode a gcnv record, a bed style format encoding copy number variation - * - * @param tokens - * @param header - */ - - function decodeGcnv(tokens, header) { - - const columnNames = header.columnNames; - if (!columnNames) { - throw Error("Sample names are not defined. Missing column headers?") - } - const sampleCount = columnNames.length - 3; - - const chr = tokens[0]; - const start = parseInt(tokens[1]); - const end = parseInt(tokens[2]); - const values = tokens.slice(3).map(Number); - - if (values.length == sampleCount) { - return { - chr: chr, - start: start, - end: end, - values: values, - } - } else { - // TODO Throw error? - console.warn(`${chr}:${start}-${end} row contains ${values.length} sample columns instead of the expected ${sampleCount} columns. Skipping...`); - return undefined - } - } - - /* - * The MIT License (MIT) - * - * Copyright (c) 2014 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - /** - * Parser for column style (tab delimited, etc) text file formats (bed, gff, vcf, etc). - * - * - */ - - - /** - * Return a parser for the given file format. - */ - class FeatureParser { - - constructor(config) { - - this.config = config; - this.header = {}; - if (config.nameField) { - this.header.nameField = config.nameField; - } - - this.skipRows = 0; // The number of fixed header rows to skip. Override for specific types as needed - - if (config.decode) { - this.decode = config.decode; - this.delimiter = config.delimiter || "\t"; - } else if (config.format) { - this.header.format = config.format.toLowerCase(); - this.setDecoder(this.header.format); - } - - if (!this.delimiter) { - this.delimiter = "\t"; - } - } - - /** - * Parse metadata from the file. A variety of conventions are in use to supply metadata about file contents - * through header lines (e.g. 'track') and # directives. This method unifies metadata as properties of a - * 'header' object. - * - * @param data - * @returns {{}} - */ - async parseHeader(dataWrapper) { - - let header = this.header; - let columnNames; - let line; - while ((line = await dataWrapper.nextLine()) !== undefined) { - if (line.startsWith("track") || line.startsWith("#track")) { - let h = parseTrackLine$1(line); - Object.assign(header, h); - } else if (line.startsWith("browser")) ; else if (line.startsWith("#columns")) { - let h = parseColumnsDirective$1(line); - Object.assign(header, h); - } else if (line.startsWith("##gff-version 3")) { - header.format = "gff3"; - } else if (line.startsWith("#gffTags")) { - header.gffTags = true; - } else if (line.startsWith("fixedStep") || line.startsWith("variableStep")) { - // Wig directives -- we are in the data section - break - } else if (line.startsWith("#")) { - const tokens = line.split(this.delimiter || "\t"); - if (tokens.length > 1) { - columnNames = tokens; // Possible column names - } - } else { - // All directives that could change the format, and thus decoder, should have been read by now. - this.setDecoder(header.format); - - // If the line can be parsed as a feature assume we are beyond the header, if any - const tokens = line.split(this.delimiter || "\t"); - try { - const tmpHeader = Object.assign({columnNames}, header); - if (this.decode(tokens, tmpHeader)) { - break - } else { - if (tokens.length > 1) { - columnNames = tokens; // possible column names - } - } - } catch (e) { - // Not a feature - if (tokens.length > 1) { - columnNames = tokens; // possible column names - } - } - } - } - - if (columnNames) { - header.columnNames = columnNames; - for (let n = 0; n < columnNames.length; n++) { - if (columnNames[n] === "color" || columnNames[n] === "colour") { - header.colorColumn = n; - } else if (columnNames[n] === "thickness") { - header.thicknessColumn = n; - } - } - } - - this.header = header; // Directives might be needed for parsing lines - return header - } - - async parseFeatures(dataWrapper) { - - const allFeatures = []; - const decode = this.decode; - const format = this.header.format; - const delimiter = this.delimiter || "\t"; - let i = 0; - let errorCount = 0; - let line; - while ((line = await dataWrapper.nextLine()) !== undefined) { - i++; - if (i <= this.skipRows) continue - - if (!line || line.startsWith("track") || line.startsWith("#") || line.startsWith("browser")) { - continue - } else if (format === "wig" && line.startsWith("fixedStep")) { - this.header.wig = parseFixedStep(line); - continue - } else if (format === "wig" && line.startsWith("variableStep")) { - this.header.wig = parseVariableStep(line); - continue - } - - const tokens = line.split(delimiter); - if (tokens.length < 1) { - continue - } - - const feature = decode(tokens, this.header); - - if (feature instanceof DecodeError) { - errorCount++; - if (errorCount > 0) { - console.error(`Error parsing line '${line}': ${feature.message}`); - } - continue - } - - if (feature) { - allFeatures.push(feature); - } - } - - // Special hack for bedPE - if (decode === decodeBedpe) { - fixBedPE(allFeatures); - } - - return allFeatures - - } - - setDecoder(format) { - - switch (format) { - case "narrowpeak": - case "broadpeak": - case "regionpeak": - case "peaks": - this.decode = decodePeak; - this.delimiter = this.config.delimiter || /\s+/; - break - case "bedgraph": - this.decode = decodeBedGraph; - this.delimiter = /\s+/; - break - case "wig": - this.decode = decodeWig; - this.delimiter = this.config.delimiter || /\s+/; - break - case "gff3" : - case "gff": - this.decode = decodeGFF3; - this.delimiter = "\t"; - break - case "gtf" : - this.decode = decodeGTF; - this.delimiter = "\t"; - break - case "fusionjuncspan": - // bhaas, needed for FusionInspector view - this.decode = decodeFusionJuncSpan; - this.delimiter = this.config.delimiter || /\s+/; - break - case "gtexgwas": - this.skipRows = 1; - this.decode = decodeGtexGWAS; - this.delimiter = "\t"; - break - case "refflat": - this.decode = decodeReflat; - this.delimiter = this.config.delimiter || /\s+/; - break - case "genepred": - this.decode = decodeGenePred; - this.delimiter = this.config.delimiter || /\s+/; - break - case "genepredext": - this.decode = decodeGenePredExt; - this.delimiter = this.config.delimiter || /\s+/; - break - case "ensgene": - this.decode = decodeGenePred; - this.header.shift = 1; - this.delimiter = this.config.delimiter || /\s+/; - break - case "refgene": - this.decode = decodeGenePredExt; - this.delimiter = this.config.delimiter || /\s+/; - this.header.shift = 1; - break - case "bed": - this.decode = decodeBed; - this.delimiter = this.config.delimiter || /\s+/; - break - case "bedpe": - case "hiccups": - this.decode = decodeBedpe; - this.delimiter = this.config.delimiter || "\t"; - break - case "bedpe-domain": - this.decode = decodeBedpeDomain; - this.headerLine = true; - this.delimiter = this.config.delimiter || "\t"; - break - case "bedpe-loop": - this.decode = decodeBedpe; - this.delimiter = this.config.delimiter || "\t"; - this.header = {colorColumn: 7}; - break - case "interact": - this.decode = decodeInteract; - this.delimiter = this.config.delimiter || /\s+/; - break - case "snp": - this.decode = decodeSNP; - this.delimiter = "\t"; - break - case "rmsk": - this.decode = decodeRepeatMasker; - this.delimiter = "\t"; - break - case "gcnv": - this.decode = decodeGcnv; - this.delimiter = "\t"; - break - default: - const customFormat = getFormat(format); - if (customFormat !== undefined) { - this.decode = decodeCustom; - this.header.customFormat = customFormat; - this.delimiter = customFormat.delimiter || "\t"; - } else { - this.decode = decodeBed; - this.delimiter = this.config.delimiter || /\s+/; - } - } - - } - } - - function parseTrackLine$1(line) { - - const properties = {}; - const tokens = line.split(/(?:")([^"]+)(?:")|([^\s"]+)(?=\s+|$)/g); - - // Clean up tokens array - let curr; - const tmp = []; - for (let tk of tokens) { - if (!tk || tk.trim().length === 0) continue - if (tk.endsWith("=")) { - curr = tk; - } else if (curr) { - tmp.push(curr + tk); - curr = undefined; - } else { - tmp.push(tk); - } - } - - for (let str of tmp) { - if (!str) return - var kv = str.split('=', 2); - if (kv.length === 2) { - const key = kv[0].trim(); - const value = kv[1].trim(); - if (properties.hasOwnProperty(key)) { - let currentValue = properties[key]; - if (Array.isArray(currentValue)) { - currentValue.push(value); - } else { - properties[key] = [currentValue, value]; - } - } else { - properties[key] = value; - } - } - } - if ("interact" == properties["type"]) { - properties["format"] = "interact"; - } else if ("gcnv" === properties["type"]) { - properties["format"] = "gcnv"; - } - return properties - } - - function parseColumnsDirective$1(line) { - - let properties = {}; - let t1 = line.split(/\s+/); - - if (t1.length === 2) { - let t2 = t1[1].split(";"); - t2.forEach(function (keyValue) { - let t = keyValue.split("="); - if (t[0] === "color") { - properties.colorColumn = Number.parseInt(t[1]) - 1; - } else if (t[0] === "thickness") { - properties.thicknessColumn = Number.parseInt(t[1]) - 1; - } - }); - } - - return properties - } - - function parseFixedStep(line) { - const tokens = line.split(/\s+/); - const chrom = tokens[1].split("=")[1]; - const start = parseInt(tokens[2].split("=")[1], 10) - 1; - const step = parseInt(tokens[3].split("=")[1], 10); - const span = (tokens.length > 4) ? parseInt(tokens[4].split("=")[1], 10) : 1; - return {format: "fixedStep", chrom, start, step, span, index: 0} - } - - function parseVariableStep(line) { - const tokens = line.split(/\s+/); - const chrom = tokens[1].split("=")[1]; - const span = tokens.length > 2 ? parseInt(tokens[2].split("=")[1], 10) : 1; - return {format: "variableStep", chrom, span} - } - - /* - * The MIT License (MIT) - * - * Copyright (c) 2018 Regents of the University of California - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - const fixColor = (colorString) => { - if (isString$2(colorString)) { - return (colorString.indexOf(",") > 0 && !(colorString.startsWith("rgb(") || colorString.startsWith("rgba("))) ? - `rgb(${colorString})` : colorString - } else { - return colorString - } - }; - - /** - * A collection of properties and methods shared by all (or most) track types. - * - * @param config - * @param browser - * @constructor - */ - class TrackBase { - - static defaults = { - height: 50, - autoHeight: false, - visibilityWindow: undefined, // Identifies property that should be copied from config - color: undefined, // Identifies property that should be copied from config - altColor: undefined, // Identifies property that should be copied from config - supportHiDPI: true - } - - constructor(config, browser) { - this.browser = browser; - this.init(config); - } - - /** - * Initialize track properties from the config object. This method is typically overriden in subclasses, which - * will call this implementation as super.init(config). - * - * @param config - */ - init(config) { - - this.config = config; - - if (config.displayMode) { - config.displayMode = config.displayMode.toUpperCase(); - } - - // Set default properties - const defaults = Object.assign({}, TrackBase.defaults); - if(this.constructor.defaults) { - for(let key of Object.keys(this.constructor.defaults)) { - defaults[key] = this.constructor.defaults[key]; - } - } - for(let key of Object.keys(defaults)) { - this[key] = config.hasOwnProperty(key) ? config[key] : defaults[key]; - if(key === 'color' || key === 'altColor') { - this[key] = fixColor(this[key]); - } - } - - if (config.name || config.label) { - this.name = config.name || config.label; - } else if (isFile$1(config.url)) { - this.name = config.url.name; - } else if (isString$2(config.url) && !config.url.startsWith("data:")) { - this.name = getFilename$2(config.url); - } - - this.url = config.url; - if(this.config.type) this.type = this.config.type; - this.id = this.config.id === undefined ? this.name : this.config.id; - this.order = config.order; - this.autoscaleGroup = config.autoscaleGroup; - this.removable = config.removable === undefined ? true : config.removable; // Defaults to true - this.minHeight = config.minHeight || Math.min(25, this.height); - this.maxHeight = config.maxHeight || Math.max(1000, this.height); - - if (config.onclick) { - this.onclick = config.onclick; - config.onclick = undefined; // functions cannot be saved in sessions, clear it here. - } - - if (config.description) { - // Override description -- displayed when clicking on track label. Convert to function if neccessary - if (typeof config.description === 'function') { - this.description = config.description; - } else { - this.description = () => config.description; - } - } - - // Support for mouse hover text. This can be expensive, off by default. - // this.hoverText = function(clickState) => return tool tip text - if (config.hoverTextFields) { - this.hoverText = hoverText.bind(this); - } else if (typeof this.config.hoverText === 'function') { - this.hoverText = this.config.hoverText; - } - } - - get name() { - return this._name - } - - set name(name) { - this._name = name; - if (this.trackView) { - this.trackView.setTrackLabelName(name); - } - } - - /** - * Update track properties from the config object. - * - * @param config - */ - updateConfig(config) { - this.init(config); - } - - clearCachedFeatures() { - if (this.trackView) { - this.trackView.clearCachedFeatures(); - } - } - - updateViews() { - if (this.trackView) { - this.trackView.updateViews(); - } - } - - /** - * Used to create session object for bookmarking, sharing. Only simple property values (string, number, boolean) - * are saved. - */ - getState() { - - const jsonable = (v) => !(v === undefined || typeof v === 'function' || v instanceof File || v instanceof Promise); - - // Create copy of config, minus transient properties (convention is name starts with '_'). Also, all - // function properties are transient as they cannot be saved in json - const state = {}; - for (let key of Object.keys(this.config)) { - if (!key.startsWith("_") && jsonable(this.config[key])) { - state[key] = this.config[key]; - } - } - - // Update original config values with any changes - for (let key of Object.keys(state)) { - if (key.startsWith("_")) continue // transient property - const value = this[key]; - if (value && (isSimpleType(value) || typeof value === "boolean" || key === "metadata")) { - state[key] = value; - } - } - - // If user has changed other properties from defaults update state. - const defs = TrackBase.defaults; - if (this.constructor.defaults) { - for (let key of Object.keys(this.constructor.defaults)) { - defs[key] = this.constructor.defaults[key]; - } - } - for (let key of Object.keys(defs)) { - if (undefined !== this[key] && defs[key] !== this[key]) { - state[key] = this[key]; - } - } - - // Flatten dataRange if present - if (!this.autoscale && this.dataRange) { - state.min = this.dataRange.min; - state.max = this.dataRange.max; - } - - return state - } - - get supportsWholeGenome() { - return this.config.supportsWholeGenome === true - } - - /** - * Does the track support sample names. Current sample aware tracks include VCF (with genotypes), MUT, MAF, and SEG - * @returns {boolean} - */ - hasSamples() { - return false - } - - getGenomeId() { - return this.browser.genome ? this.browser.genome.id : undefined - } - - /** - * Set certain track properties, usually from a "track" line. Not all UCSC properties are supported. - * - * Track configuration settings have precendence over track line properties, so if both are present ignore the - * track line. - * - * @param properties - */ - setTrackProperties(properties) { - - if (this.disposed) return // This track was removed during async load - - const tracklineConfg = {}; - let tokens; - for (let key of Object.keys(properties)) { - switch (key.toLowerCase()) { - case "usescore": - tracklineConfg.useScore = ( - properties[key] === 1 || properties[key] === "1" || properties[key] === "on" || properties[key] === true); - break - case "visibility": - //0 - hide, 1 - dense, 2 - full, 3 - pack, and 4 - squish - switch (properties[key]) { - case "2": - case "3": - case "pack": - case "full": - tracklineConfg.displayMode = "EXPANDED"; - break - case "4": - case "squish": - tracklineConfg.displayMode = "SQUISHED"; - break - case "1": - case "dense": - tracklineConfg.displayMode = "COLLAPSED"; - } - break - case "color": - case "altcolor": - tracklineConfg[key] = properties[key].startsWith("rgb(") ? properties[key] : "rgb(" + properties[key] + ")"; - break - case "featurevisiblitywindow": - case "visibilitywindow": - tracklineConfg.visibilityWindow = Number.parseInt(properties[key]); - break - case "maxheightpixels": - tokens = properties[key].split(":"); - if (tokens.length === 3) { - tracklineConfg.minHeight = Number.parseInt(tokens[2]); - tracklineConfg.height = Number.parseInt(tokens[1]); - tracklineConfg.maxHeight = Number.parseInt(tokens[0]); - } - break - case "viewlimits": - if (!this.config.autoscale) { // autoscale in the config has precedence - tokens = properties[key].split(":"); - let min = 0; - let max; - if (tokens.length == 1) { - max = Number(tokens[0]); - } else if (tokens.length == 2) { - min = Number(tokens[0]); - max = Number(tokens[1]); - } - tracklineConfg.autoscale = false; - tracklineConfg.dataRange = {min, max}; - this.viewLimitMin = min; - this.viewLimitMax = max; - } - case "name": - tracklineConfg[key] = properties[key]; - break - case "url": - tracklineConfg["infoURL"] = properties[key]; - break - case "type": - const v = properties[key]; - if (UCSCTypeMappings.has(v)) { - tracklineConfg[key] = UCSCTypeMappings.get(v); - } else { - tracklineConfg[key] = v; - } - break - case "graphtype": - tracklineConfg["graphType"] = properties[key]; - break - default: - tracklineConfg[key] = properties[key]; - } - } - - // Track configuration objects have precedence over track line properties in general. The "name" property - // is an exception if it was derived and not explicitly entered (that is derived from the web app from filename). - for (let key of Object.keys(tracklineConfg)) { - - if (!this.config.hasOwnProperty(key) || (key === "name" && this.config._derivedName)) { - let value = tracklineConfg[key]; - if ("true" === value) value = true; - if ("false" === value) value = false; - - this[key] = value; - if (key === "height" && this.trackView) { - try { - const h = Number.parseInt(value); - this.trackView.setTrackHeight(h); - } catch (e) { - console.error(e); - } - } - } - } - } - - /** - * Return the features clicked over. Default implementation assumes an array of features and only considers - * the genomic location. Overriden by most subclasses. - * - * @param clickState - * @param features - * @returns {[]|*[]} - */ - clickedFeatures(clickState) { - - // We use the cached features rather than method to avoid async load. If the - // feature is not already loaded this won't work, but the user wouldn't be mousing over it either. - const features = clickState.viewport.cachedFeatures; - - if (!features || !Array.isArray(features) || features.length === 0) { - return [] - } - - const genomicLocation = clickState.genomicLocation; - - // When zoomed out we need some tolerance around genomicLocation - const tolerance = (clickState.referenceFrame.bpPerPixel > 0.2) ? 3 * clickState.referenceFrame.bpPerPixel : 0.2; - const ss = genomicLocation - tolerance; - const ee = genomicLocation + tolerance; - return (FeatureUtils.findOverlapping(features, ss, ee)) - } - - /** - * Default popup text function -- just extracts string and number properties in random order. - * @param feature - * @returns {Array} - */ - extractPopupData(feature, genomeId) { - - const filteredProperties = new Set(['row', 'color', 'chr', 'start', 'end', 'cdStart', 'cdEnd', 'strand', 'alpha']); - const data = []; - - let alleles, alleleFreqs; - for (let property in feature) { - - if (feature.hasOwnProperty(property) && - !filteredProperties.has(property) && - isSimpleType(feature[property])) { - - let value = feature[property]; - data.push({name: capitalize(property), value: value}); - - if (property === "alleles") { - alleles = feature[property]; - } else if (property === "alleleFreqs") { - alleleFreqs = feature[property]; - } - } - } - - if (alleles && alleleFreqs) { - - if (alleles.endsWith(",")) { - alleles = alleles.substr(0, alleles.length - 1); - } - if (alleleFreqs.endsWith(",")) { - alleleFreqs = alleleFreqs.substr(0, alleleFreqs.length - 1); - } - - let a = alleles.split(","); - let af = alleleFreqs.split(","); - if (af.length > 1) { - let b = []; - for (let i = 0; i < af.length; i++) { - b.push({a: a[i], af: Number(af[i])}); - } - b.sort(function (x, y) { - return x.af - y.af - }); - - let ref = b[b.length - 1].a; - if (ref.length === 1) { - for (let i = b.length - 2; i >= 0; i--) { - let alt = b[i].a; - if (alt.length === 1) { - if (!genomeId) genomeId = this.getGenomeId(); - const cravatLink = TrackBase.getCravatLink(feature.chr, feature.start + 1, ref, alt, genomeId); - console.log(cravatLink); - if (cravatLink) { - data.push('
'); - data.push({html: cravatLink}); - data.push('
'); - } - } - } - } - } - } - - if (feature.attributes) { - for (let key of Object.keys(feature.attributes)) { - data.push({name: key, value: feature.attributes[key]}); - } - } - - // final chr position - let posString = `${feature.chr}:${numberFormatter$1(feature.start + 1)}-${numberFormatter$1(feature.end)}`; - if (feature.strand) { - posString += ` (${feature.strand})`; - } - - data.push({name: 'Location', value: posString}); - - return data - - } - - - /** - * Default track description -- displayed on click of track label. This can be overriden in the track - * configuration, or in subclasses. - */ - description() { - - const wrapKeyValue = (k, v) => `
${k}: ${v}
`; - - let str = '
'; - if (this.url) { - if (isFile$1(this.url)) { - str += wrapKeyValue('Filename', this.url.name); - } else { - str += wrapKeyValue('URL', this.url); - } - } else { - str = this.name; - } - if (this.config) { - if (this.config.metadata) { - for (let key of Object.keys(this.config.metadata)) { - const value = this.config.metadata[key]; - str += wrapKeyValue(key, value); - } - } - - // Add any config properties that are capitalized - for (let key of Object.keys(this.config)) { - if (key.startsWith("_")) continue // transient property - let first = key.substr(0, 1); - if (first !== first.toLowerCase()) { - const value = this.config[key]; - if (value && isSimpleType(value)) { - str += wrapKeyValue(key, value); - } - } - } - - } - str += '
'; - return str - } - - /** - * Return color for a specific feature of this track. This default implementation is overriden by subclasses* - * @param f - * @returns {*|string|string} - */ - getColorForFeature(f) { - return (typeof this.color === "function") ? this.color(feature) : this.color - } - - /** - * Track has been permanently removed. Release resources and other cleanup - */ - dispose() { - - this.disposed = true; - - // This should not be neccessary, but in case there is some unknown reference holding onto this track object, - // for example in client code, release any resources here. - for (let key of Object.keys(this)) { - this[key] = undefined; - } - } - - static getCravatLink(chr, position, ref, alt, genomeID) { - - if ("hg38" === genomeID || "GRCh38" === genomeID) { - - const cravatChr = chr.startsWith("chr") ? chr : "chr" + chr; - return `Cravat ${ref}->${alt}` - - } else { - return undefined - } - } - } - - function hoverText(clickState) { - - if (!this.hoverTextFields) return - - const features = this.clickedFeatures(clickState); - - if (features && features.length > 0) { - let str = ""; - for (let i = 0; i < features.length; i++) { - if (i === 10) { - str += "; ..."; - break - } - if (!features[i]) continue - - const f = features[i]._f || features[i]; - if (str.length > 0) str += "\n"; - - str = ""; - for (let field of this.hoverTextFields) { - if (str.length > 0) str += "\n"; - if (f.hasOwnProperty(field)) { - str += f[field]; - } else if (typeof f.getAttribute === "function") { - str += f.getAttribute(field); - } - } - - } - return str - } - } - - /** - * Map UCSC track line "type" setting to file format. In igv.js "type" refers to the track type, not the input file format - * @type {Map} - */ - const UCSCTypeMappings = new Map([ - ["wiggle_0", "wig"], - ["bed", "bed"], - ["bigBed", "bigBed"], - ["bigWig", "bigWig"] - ]); - - /* - * The MIT License (MIT) - * - * Copyright (c) 2014 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - - /** - * Define parser for seg files (.bed, .gff, .vcf, etc). A parser should implement 2 methods - * - * parseHeader(data) - return an object representing a header. Details are format specific - * - * parseFeatures(data) - return a list of features - * - */ - - - class SegParser { - - constructor(type) { - this.type = type || 'seg'; // One of seg, mut, or maf - - switch (this.type) { - case 'mut': - this.sampleColumn = 3; - this.chrColumn = 0; - this.startColumn = 1; - this.endColumn = 2; - this.dataColumn = 4; - break - case 'maf': - this.sampleColumn = 15; - this.chrColumn = 4; - this.startColumn = 5; - this.endColumn = 6; - this.dataColumn = 8; - break - default: - this.sampleColumn = 0; - this.chrColumn = 1; - this.startColumn = 2; - this.endColumn = 3; - // Data column determined after reading header - } - } - - async parseHeader(dataWrapper) { - let line; - while ((line = await dataWrapper.nextLine()) !== undefined) { - if (line.startsWith("#")) ; else { - const tokens = line.split("\t"); - this.header = {headings: tokens}; - break - } - } - return this.header - } - - async parseFeatures(dataWrapper) { - - const allFeatures = []; - let extraHeaders; - if (!this.header) { - this.header = await this.parseHeader(dataWrapper); // This will only work for non-indexed files - } - if ('seg' === this.type) { - this.dataColumn = this.header.headings.length - 1; - } - if (this.header.headings.length > 5) { - extraHeaders = this.extractExtraColumns(this.header.headings); - } - const valueColumnName = this.header.headings[this.dataColumn]; - - let line; - while ((line = await dataWrapper.nextLine()) !== undefined) { - const tokens = line.split("\t"); - const value = ('seg' === this.type) ? Number(tokens[this.dataColumn]) : tokens[this.dataColumn]; - if (tokens.length > this.dataColumn) { - const feature = new SegFeature({ - sample: tokens[this.sampleColumn], - chr: tokens[this.chrColumn], - start: parseInt(tokens[this.startColumn]) - 1, - end: parseInt(tokens[this.endColumn]), - value, - valueColumnName - }); - if (extraHeaders) { - const extraValues = this.extractExtraColumns(tokens); - feature.setAttributes({names: extraHeaders, values: extraValues}); - } - allFeatures.push(feature); - } - } - return allFeatures - } - - extractExtraColumns(tokens) { - const extras = []; - for (let i = 0; i < tokens.length; i++) { - if (i !== this.chrColumn && i !== this.startColumn && i !== this.endColumn && i !== this.sampleColumn) { - extras.push(tokens[i]); - } - } - return extras - } - - } - - class SegFeature { - - constructor({sample, chr, start, end, value, valueColumnName}) { - this.sample = sample; - this.chr = chr; - this.start = start; - this.end = end; - this.value = value; - this.valueColumnName = valueColumnName; - } - - setAttributes({names, values}) { - this.attributeNames = names; - this.attributeValues = values; - } - - getAttribute(name) { - if (this.attributeNames) { - const idx = this.attributeNames.indexOf(name); - if (idx >= 0) { - return this.attributeValues[idx] - } - } - return undefined - } - - - popupData(type, genomeID) { - const filteredProperties = new Set(['chr', 'start', 'end', 'sample', 'value', 'row', 'color', 'sampleKey', - 'uniqueSampleKey', 'sampleId', 'chromosome', 'uniquePatientKey']); - const locationString = (this.chr + ":" + - numberFormatter$1(this.start + 1) + "-" + - numberFormatter$1(this.end)); - const pd = [ - {name: "Sample", value: this.sample}, - {name: "Location", value: locationString}, - {name: this.valueColumnName ? capitalize(this.valueColumnName) : "Value", value: this.value} - ]; - - // TODO -- the Cravat stuff should probably be in the track (SegTrack) - if ("mut" === type && "hg38" === genomeID) { - const l = this.extractCravatLink(genomeID); - if (l) { - pd.push('
'); - pd.push({html: l}); - pd.push('
'); - } - } - - if (this.attributeNames && this.attributeNames.length > 0) { - for (let i = 0; i < this.attributeNames.length; i++) { - if (!filteredProperties.has(this.attributeNames[i]) & this.valueColumnName !== this.attributeNames[i]) { - pd.push({name: capitalize(this.attributeNames[i]), value: this.attributeValues[i]}); - } - } - } - return pd - } - - extractCravatLink(genomeId) { - - let ref, alt; - if (this.attributeNames && this.attributeNames.length > 0) { - for (let i = 0; i < this.attributeNames.length; i++) { - if (!ref && "Reference_Allele" === this.attributeNames[i]) { - ref = this.attributeValues[i]; - } - if (!alt && this.attributeNames[i].startsWith("Tumor_Seq_Allele") && this.attributeValues[i] !== ref) { - alt = this.attributeValues[i]; - } - if (ref && alt) { - return TrackBase.getCravatLink(this.chr, this.start + 1, ref, alt, genomeId) - } - } - } - - } - } - - /* - * The MIT License (MIT) - * - * Copyright (c) 2014 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - /** - * Create a variant from an array of tokens representing a line in a "VCF" file - * @param tokens - */ - function createVCFVariant(tokens) { - const variant = new Variant(); - variant.chr = tokens[0]; // TODO -- use genome aliases - variant.pos = parseInt(tokens[1]); - variant.names = tokens[2]; // id in VCF - variant.referenceBases = tokens[3]; - variant.alternateBases = tokens[4]; - variant.quality = tokens[5]; - variant.filter = tokens[6]; - variant.info = {}; - const infoStr = tokens[7]; - if (infoStr) { - for (let elem of infoStr.split(';')) { - var element = elem.split('='); - variant.info[element[0]] = element[1]; - } - } - variant.init(); - return variant - } - - - /** - * @deprecated - the GA4GH API has been deprecated. This code no longer maintained. - * @param json - * @returns {Variant} - */ - function createGAVariant(json) { - - var variant = new Variant(); - - variant.chr = json.referenceName; - variant.start = parseInt(json.start); // Might get overriden below - variant.end = parseInt(json.end); // Might get overriden below - variant.pos = variant.start + 1; // GA4GH is 0 based. - variant.names = arrayToString(json.names, "; "); - variant.referenceBases = json.referenceBases; - variant.alternateBases = arrayToString(json.alternateBases); - variant.quality = json.quality; - variant.filter = arrayToString(json.filter); - - - // Flatten GA4GH attributes array - variant.info = {}; - if (json.info) { - Object.keys(json.info).forEach(function (key) { - var value, - valueArray = json.info[key]; - - if (Array.isArray(valueArray)) { - value = valueArray.join(","); - } else { - value = valueArray; - } - variant.info[key] = value; - }); - } - - - // Need to build a hash of calls for fast lookup - // Note from the GA4GH spec on call ID: - // - // The ID of the call set this variant call belongs to. If this field is not present, - // the ordering of the call sets from a SearchCallSetsRequest over this GAVariantSet - // is guaranteed to match the ordering of the calls on this GAVariant. - // The number of results will also be the same. - variant.calls = {}; - var id; - if (json.calls) { - json.calls.forEach(function (call) { - id = call.callSetId; - variant.calls[id] = call; - - }); - } - - init(variant); - - return variant - - } - - - class Variant { - - init() { - - const ref = this.referenceBases; - const altBases = this.alternateBases; - - if (this.info) { - if (this.info["VT"]) { - this.type = this.info["VT"]; - } else if (this.info["SVTYPE"]) { - this.type = "SV"; - } else if (this.info["PERIOD"]) { - this.type = "STR"; - } - } - if (this.type === undefined) { - this.type = determineType(ref, altBases); - } - if (this.type === "NONVARIANT") { - this.heterozygosity = 0; - } - - // Determine start/end coordinates -- these are the coordinates representing the actual variant, - // not the leading or trailing reference - if (this.info["END"]) { - this.start = this.pos - 1; - if (this.info["CHR2"] && this.info["CHR2"] !== this.chr) { - this.end = this.start + 1; - } else { - this.end = Number.parseInt(this.info["END"]); - } - } else { - if (this.type === "NONVARIANT") { - this.start = this.pos - 1; // convert to 0-based coordinate convention - this.end = this.start + ref.length; - } else { - - const altTokens = altBases.split(",").filter(token => token.length > 0); - this.alleles = []; - this.start = undefined; - this.end = undefined; - - for (let alt of altTokens) { - - this.alleles.push(alt); - - // We don't yet handle SV and other special alt representations - if ("SV" !== this.type && isKnownAlt(alt)) { - - let altLength = alt.length; - let lengthOnRef = ref.length; - const lmin = Math.min(altLength, lengthOnRef); - - // Trim off matching bases. Try first match, then right -> left, then any remaining left -> right - let s = 0; - - while (s < lmin && (ref.charCodeAt(s) === alt.charCodeAt(s))) { - s++; - altLength--; - lengthOnRef--; - } - - // right -> left from end - while (altLength > 0 && lengthOnRef > 0) { - const altIdx = s + altLength - 1; - const refIdx = s + lengthOnRef - 1; - if (alt.charCodeAt(altIdx) === ref.charCodeAt(refIdx)) { - altLength--; - lengthOnRef--; - } else { - break - } - } - - // if any remaining, left -> right - while (altLength > 0 && lengthOnRef > 0) { - const altIdx = s; - const refIdx = s; - if (alt.charCodeAt(altIdx) === ref.charCodeAt(refIdx)) { - s++; - altLength--; - lengthOnRef--; - } else { - break - } - } - - const alleleStart = this.pos + s - 1; // -1 for zero based coordinates - const alleleEnd = alleleStart + lengthOnRef; - this.start = this.start === undefined ? alleleStart : Math.min(this.start, alleleStart); - this.end = this.end === undefined ? alleleEnd : Math.max(this.end, alleleEnd); - } - } - - // Default to single base representation @ position for variant types not otherwise handled - if (this.start === undefined) { - this.start = this.pos - 1; - this.end = this.pos; - } - } - } - } - - popupData(genomicLocation, genomeId) { - - const posString = `${numberFormatter$1(this.pos)}`; - const locString = this.start === this.end ? - `${numberFormatter$1(this.start)} | ${numberFormatter$1(this.start + 1)}` : - `${numberFormatter$1(this.start + 1)}-${numberFormatter$1(this.end)}`; - const fields = [ - {name: "Chr", value: this.chr}, - {name: "Pos", value: posString}, - {name: "Loc", value: locString}, - {name: "ID", value: this.names ? this.names : ""}, - {name: "Ref", value: this.referenceBases}, - {name: "Alt", value: this.alternateBases.replace("<", "<")}, - {name: "Qual", value: this.quality}, - {name: "Filter", value: this.filter} - ]; - - if ("SNP" === this.type) { - let ref = this.referenceBases; - if (ref.length === 1) { - let altArray = this.alternateBases.split(","); - for (let alt of altArray) { - if (alt.length === 1) { - let l = TrackBase.getCravatLink(this.chr, this.pos, ref, alt, genomeId); - if (l) { - fields.push('
'); - fields.push({html: l}); - } - } - } - } - } - - if (this.hasOwnProperty("heterozygosity")) { - fields.push({name: "Heterozygosity", value: this.heterozygosity}); - } - - if (this.info) { - fields.push({html: '
'}); - for (let key of Object.keys(this.info)) { - fields.push({name: key, value: arrayToString(decodeURIComponent(this.info[key]))}); - } - } - - return fields - } - - getInfo(tag) { - return this.info ? this.info[tag] : undefined; - } - - isRefBlock() { - return "NONVARIANT" === this.type - } - - } - - const knownAltBases = new Set(["A", "C", "T", "G"].map(c => c.charCodeAt(0))); - - function isKnownAlt(alt) { - for (let i = 0; i < alt.length; i++) { - if (!knownAltBases.has(alt.charCodeAt(i))) { - return false - } - } - return true - } - - - function determineType(ref, altAlleles) { - const refLength = ref.length; - if (altAlleles === undefined) { - return "UNKNOWN" - } else if (altAlleles.trim().length === 0 || - altAlleles === "" || - altAlleles === "<*>" || - altAlleles === ".") { - return "NONVARIANT" - } else { - const alleles = altAlleles.split(","); - const types = alleles.map(function (a) { - if (refLength === 1 && a.length === 1) { - return "SNP" - } else { - return "" === a ? "NONVARIANT" : "OTHER" - } - }); - let type = types[0]; - for (let t of types) { - if (t !== type) { - return "MIXED" - } - } - return type - } - } - - function arrayToString(value, delim) { - - if (delim === undefined) delim = ","; - - if (!(Array.isArray(value))) { - return value - } - return value.join(delim) - } - - /* - * The MIT License (MIT) - * - * Copyright (c) 2014 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - /** - * Parser for VCF files. - */ - - class VcfParser { - - construtor() { - } - - async parseHeader(dataWrapper, genome) { - - const header = {}; - - header.chrAliasTable = new Map(); - - // First line must be file format - let line = await dataWrapper.nextLine(); - if (line.startsWith("##fileformat")) { - header.version = line.substr(13); - } else { - throw new Error("Invalid VCF file: missing fileformat line") - } - - while ((line = await dataWrapper.nextLine()) !== undefined) { - - if (line.startsWith("#")) { - - let id; - const values = {}; - - if (line.startsWith("##")) { - - if (line.startsWith("##INFO") || line.startsWith("##FILTER") || line.startsWith("##FORMAT")) { - - const ltIdx = line.indexOf("<"); - const gtIdx = line.lastIndexOf(">"); - - if (!(ltIdx > 2 && gtIdx > 0)) { - console.log("Malformed VCF header line: " + line); - continue - } - - const type = line.substring(2, ltIdx - 1); - if (!header[type]) header[type] = {}; - - //##INFO= - // ##FILTER= - // ##FORMAT= - - const tokens = splitStringRespectingQuotes(line.substring(ltIdx + 1, gtIdx - 1), ","); - - for (let token of tokens) { - var kv = token.split("="); - if (kv.length > 1) { - if (kv[0] === "ID") { - id = kv[1]; - } else { - values[kv[0]] = kv[1]; - } - } - } - - if (id) { - header[type][id] = values; - } - } else if (line.startsWith("##contig") && genome) { - const idx1 = line.indexOf("", idx1); - } - const chr = line.substring(idx1 + 4, idx2); - const canonicalChromosome = genome.getChromosomeName(chr); - header.chrAliasTable.set(canonicalChromosome, chr); - } else ; - } else if (line.startsWith("#CHROM")) { - const tokens = line.split("\t"); - - if (tokens.length > 8) { - - // call set names -- use column index for id - header.callSets = []; - for (let j = 9; j < tokens.length; j++) { - header.callSets.push({id: j, name: tokens[j]}); - } - } - } - - } else { - break - } - - } - - this.header = header; // Will need to intrepret genotypes and info field - - return header - } - - - /** - * Parse data as a collection of Variant objects. - * - * @param data - * @returns {Array} - */ - async parseFeatures(dataWrapper) { - - const allFeatures = []; - const callSets = this.header.callSets; - const nExpectedColumns = 8 + (callSets ? callSets.length + 1 : 0); - let line; - while ((line = await dataWrapper.nextLine()) !== undefined) { - if (line && !line.startsWith("#")) { - - const tokens = line.split("\t"); - if (tokens.length === nExpectedColumns) { - const variant = createVCFVariant(tokens); - variant.header = this.header; // Keep a pointer to the header to interpret fields for popup text - //variant.line = line // Uncomment for debugging - allFeatures.push(variant); - - if (tokens.length > 9) { - - // Format - const callFields = extractCallFields(tokens[8].split(":")); - - variant.calls = {}; - for (let index = 9; index < tokens.length; index++) { - - const token = tokens[index]; - - const callSet = callSets[index - 9]; - const call = { - callSetName: callSet.name, - info: {} - }; - - variant.calls[callSet.id] = call; - - token.split(":").forEach(function (callToken, idx) { - - switch (idx) { - case callFields.genotypeIndex: - call.genotype = []; - callToken.split(/[\|\/]/).forEach(function (s) { - call.genotype.push('.' === s ? s : parseInt(s)); - }); - break - - default: - call.info[callFields.fields[idx]] = callToken; - } - }); - } - } - - // If this is a structural variant create a complement of this variant for the other end - // The test for "SV" is not comprehensive, there is not yet a standard for this - if (variant.info && variant.info.CHR2 && variant.info.END) { - allFeatures.push(svComplement(variant)); - } - } - } - } - - return allFeatures - } - } - - function extractCallFields(tokens) { - - const callFields = { - genotypeIndex: -1, - fields: tokens - }; - for (let i = 0; i < tokens.length; i++) { - if ("GT" === tokens[i]) { - callFields.genotypeIndex = i; - } - } - return callFields - } - - function svComplement(v) { - - const chr2 = v.info.CHR2; - const pos2 = Number.parseInt(v.info.END); - return { - chr: chr2, - start: pos2 - 1, - end: pos2, - _f: v - } - - } - - /** - * Parser for IGV desktop GWAS files. See http://software.broadinstitute.org/software/igv/GWAS - */ - class GWASParser { - - constructor(config) { - // Defaults - can be overriden by header - this.config = config; - if (config.columns) { - if (config.columns.chromosome === undefined || - config.columns.position === undefined || - config.columns.value === undefined) { - throw Error("columns property must define chrCol, posCol, and valueCol") - } - this.posCol = config.columns.position - 1; - this.chrCol = config.columns.chromosome - 1; - this.valueCol = config.columns.value - 1; - } else { - // Defaults -- can be overriden in header - this.posCol = 2; - this.chrCol = 1; - this.valueCol = 3; - } - } - - async parseHeader(dataWrapper) { - const headerLine = await dataWrapper.nextLine(); - return this.parseHeaderLine(headerLine) - } - - parseHeaderLine(headerLine) { - this.columns = headerLine.split(/\t/); - if (!this.config.columns) { - for (let i = 0; i < this.columns.length; i++) { - const c = this.columns[i].toLowerCase(); - switch (c) { - case 'chr': - case 'chromosome': - case 'chr_id': - this.chrCol = i; - break - case 'bp': - case 'pos': - case 'position': - case 'chr_pos': - this.posCol = i; - break - case 'p': - case 'pval': - case 'pvalue': - case 'p-value': - case 'p.value': - this.valueCol = i; - break - } - } - } - return this.columns - } - - async parseFeatures(dataWrapper) { - - const allFeatures = []; - const headerLine = dataWrapper.nextLine(); - if (!this.columns) { - this.parseHeaderLine(headerLine); - } - let line; - while ((line = dataWrapper.nextLine()) !== undefined) { - const tokens = line.split(/\t/); - if (tokens.length === this.columns.length) { - const chr = tokens[this.chrCol]; - const start = parseInt(tokens[this.posCol]) - 1; - const end = start + 1; - const value = Number(tokens[this.valueCol]); - allFeatures.push(new GWASFeature({ - chr: chr, - start: start, - end: end, - value: value, - line: line, - columns: this.columns - })); - } - } - return allFeatures - } - } - - class GWASFeature { - - constructor({chr, start, end, value, line, columns}) { - this.chr = chr; - this.start = start; - this.end = end; - this.value = value; - this.line = line; - this.columns = columns; - } - - popupData() { - const tokens = this.line.split(/\t/); - return this.columns.map(function (c, index) { - return {name: c, value: tokens[index]} - }) - } - - getAttribute(attrName) { - const tokens = this.line.split(/\t/); - for (let i = 0; i < this.columns.length; i++) { - if (this.columns[i] === attrName) { - return tokens[i] - } - } - return undefined - } - - } - - /* - * The MIT License (MIT) - * - * Copyright (c) 2014 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - /** - * Define parsers for bed-like files (.bed, .gff, .vcf, etc). A parser should implement 2 methods - * - * parseHeader(data) - return an object representing a header or metadata. Details are format specific - * - * parseFeatures(data) - return an array of features - * - */ - - var aedRegexpNoNamespace = new RegExp("([^:]*)\\(([^)]*)\\)"); // name(type) for AED parsing (namespace undefined) - var aedRegexpNamespace = new RegExp("([^:]*):([^(]*)\\(([^)]*)\\)"); // namespace:name(type) for AED parsing - - - class AEDParser { - - constructor(config) { - const decode = config ? config.decode : undefined; - this.nameField = config ? config.nameField : undefined; - this.skipRows = 0; // The number of fixed header rows to skip. Override for specific types as needed - if (decode) { - this.decode = decode; - } else { - this.decode = decodeAed; - } - this.delimiter = "\t"; - } - - async parseHeader(dataWrapper) { - let line; - let header; - while (line = await dataWrapper.nextLine()) { - if (line.startsWith("track") || line.startsWith("#") || line.startsWith("browser")) { - if (line.startsWith("track") || line.startsWith("#track")) { - let h = parseTrackLine(line); - if (header) { - Object.assign(header, h); - } else { - header = h; - } - } else if (line.startsWith("#columns")) { - let h = parseColumnsDirective(line); - if (header) { - Object.assign(header, h); - } else { - header = h; - } - } else if (line.startsWith("##gff-version 3")) { - this.format = "gff3"; - if (!header) header = {}; - header["format"] = "gff3"; - } - } else { - break - } - } - this.header = header; // Directives might be needed for parsing lines - return header - } - - async parseFeatures(dataWrapper) { - - const allFeatures = []; - const decode = this.decode; - const delimiter = this.delimiter || "\t"; - let i = 0; - let line; - let wig; - - while ((line = dataWrapper.nextLine()) !== undefined) { - i++; - if (i <= this.skipRows || line.startsWith("track") || line.startsWith("#") || line.startsWith("browser")) { - continue - } - - let tokens = readTokensAed(); - if (tokens.length < 1) { - continue - } - - if (!this.aed) { - // Store information about the aed header in the parser itself - // This is done only once - on the first row - this.aed = parseAedHeaderRow(tokens); - continue - } - - const feature = decode.call(this, tokens, wig); - if (feature) { - allFeatures.push(feature); - } - } - - return allFeatures - - // Double quoted strings can contain newlines in AED - // "" is an escape for a ". - // Parse all this, clean it up, split into tokens in a custom way - function readTokensAed() { - var tokens = [], - token = "", - quotedString = false, - n, - c; - - while (line || line === '') { - for (n = 0; n < line.length; n++) { - c = line.charAt(n); - if (c === delimiter) { - if (!quotedString) { - tokens.push(token); - token = ""; - } else { - token += c; - } - } else if (c === "\"") { - // Look ahead to the next character - if (n + 1 < line.length && line.charAt(n + 1) === "\"") { - if (quotedString) { - // Turn "" into a single " in the output string - token += "\""; - } - // Skip the next double quote - n++; - } else { - // We know the next character is NOT a double quote, flip our state - quotedString = !quotedString; - } - } else { - token += c; - } - } - // We are at the end of the line - if (quotedString) { - token += '\n'; // Add newline to the token - line = nextLine(); // Keep going - } else { - // We can end the loop - break - } - } - // Push the last token - tokens.push(token); - return tokens - } - } - } - - - function parseAedToken(value) { - // Example: refseq:accessionNumber(aed:String) - // refseq - namespace, will be declared later - // accessionNumber - name of the field - // aed:String - type of the field - // The namespace part may be missing - var match = aedRegexpNamespace.exec(value); - if (match) { - return { - namespace: match[1], - name: match[2], - type: match[3] - } - } - - match = aedRegexpNoNamespace.exec(value); - if (match) { - return { - namespace: '?', - name: match[1], - type: match[2] - } - } else { - throw new Error("Error parsing the header row of AED file - column not in ns:name(ns:type) format") - } - } - - function parseAedHeaderRow(tokens) { - // First row of AED file defines column names - // Each header item is an aed token - see parseAedToken - var aed, - k, - token, - aedToken; - - // Initialize aed section to be filled in - aed = { - columns: [ // Information about the namespace, name and type of each column - // Example entry: - // { namespace: 'bio', name: 'start', type: 'aed:Integer' } - ], - metadata: { // Metadata about the entire AED file - // Example: - // { - // aed: { - // application: { value: "CHaS Browser 3.3.0.139 (r10838)", type: "aed:String" }, - // created: { value: "2018-01-02T10:20:30.123+01:00", type: "aed:DateTime" }, - // modified: { value: "2018-03-04T11:22:33.456+01:00", type: "aed:DateTime" }, - // } - // affx: { - // ucscGenomeVersion: { value: "hg19", type: "aed:String" } - // }, - // namespace: { - // omim: { value: "http://affymetrix.com/ontology/www.ncbi.nlm.nih.gov/omim/", type: "aed:URI" }, - // affx: { value: "http://affymetrix.com/ontology/", type: "aed:URI" }, - // refseq: { value: "http://affymetrix.com/ontology/www.ncbi.nlm.nih.gov/RefSeq/", type: "aed:URI" } - // } - // } - } - }; - for (k = 0; k < tokens.length; k++) { - token = tokens[k]; - aedToken = parseAedToken(token); - aed.columns.push(aedToken); - } - - return aed - } - - function parseTrackLine(line) { - - const properties = {}; - const tokens = line.split(/(?:")([^"]+)(?:")|([^\s"]+)(?=\s+|$)/g); - - - // Clean up tokens array - let curr; - const tmp = []; - for (let tk of tokens) { - if (!tk || tk.trim().length === 0) continue - if (tk.endsWith("=") > 0) { - curr = tk; - } else if (curr) { - tmp.push(curr + tk); - curr = undefined; - } else { - tmp.push(tk); - } - } - for (let str of tmp) { - if (!str) return - var kv = str.split('=', 2); - if (kv.length === 2) { - const key = kv[0].trim(); - const value = kv[1].trim(); - properties[key] = value; - } - - } - - return properties - } - - function parseColumnsDirective(line) { - - let properties = {}; - let t1 = line.split(/\s+/); - - if (t1.length === 2) { - - let t2 = t1[1].split(";"); - - t2.forEach(function (keyValue) { - - let t = keyValue.split("="); - - if (t[0] === "color") { - properties.colorColumn = Number.parseInt(t[1]) - 1; - } else if (t[0] === "thickness") { - properties.thicknessColumn = Number.parseInt(t[1]) - 1; - } - }); - } - - return properties - } - - /** - * AED file feature. - * - * @param aed link to the AED file object containing file-level metadata and column descriptors - * @param allColumns All columns as parsed from the AED - * - * Other values are parsed one by one - */ - function AedFeature(aed, allColumns) { - var token, aedColumn, aedColumns = aed.columns; - - // Link to AED file (for metadata) - this.aed = aed; - - // Unparsed columns from AED file - this.allColumns = allColumns; - - // Prepare space for the parsed values - this.chr = null; - this.start = null; - this.end = null; - this.score = 1000; - this.strand = '.'; - this.cdStart = null; - this.cdEnd = null; - this.name = null; - this.color = null; - - for (let i = 0; i < allColumns.length; i++) { - token = allColumns[i]; - if (!token) { - // Skip empty fields - continue - } - aedColumn = aedColumns[i]; - if (aedColumn.type === 'aed:Integer') { - token = parseInt(token); - } - var arr = []; - if (aedColumn.namespace.length > 0) { - for (let j = 0; j < aedColumn.namespace.length; j++) { - arr.push(aedColumn.namespace.charCodeAt(j)); - } - } - if (aedColumn.namespace.trim() === 'bio') { - if (aedColumn.name === 'sequence') { - this.chr = token; - } else if (aedColumn.name === 'start') { - this.start = token; - } else if (aedColumn.name === 'end') { - this.end = token; - } else if (aedColumn.name === 'cdsMin') { - this.cdStart = token; - } else if (aedColumn.name === 'cdsMax') { - this.cdEnd = token; - } else if (aedColumn.name === 'strand') { - this.strand = token; - } - } else if (aedColumn.namespace === 'aed') { - if (aedColumn.name === 'name') { - this.name = token; - } - } else if (aedColumn.namespace === 'style') { - if (aedColumn.name === 'color') { - this.color = IGVColor.createColorString(token); - } - } - } - } - - AedFeature.prototype.popupData = function () { - var data = [], - aed = this.aed; - // Just dump everything we have for now - for (var i = 0; i < this.allColumns.length; i++) { - var featureValue = this.allColumns[i]; - var name = aed.columns[i].name; - // Skip columns that are not interesting - you know the sequence, and you can see color - if (name !== 'sequence' && name !== 'color') { - if (featureValue) { - data.push({name: name, value: featureValue}); - } - } - } - return data - }; - - /** - * Decode the AED file format - * @param tokens - * @param ignore - * @returns decoded feature, or null if this is not a valid record - */ - function decodeAed(tokens, ignore) { - var name, value, token, - nonEmptyTokens = 0, - aedColumns = this.aed.columns, - aedColumn, - aedKey, - i; - - // Each aed row must match the exact number of columns or we skip it - if (tokens.length !== aedColumns.length) { - console.log('Corrupted AED file row: ' + tokens.join(',')); - return undefined - } - - for (i = 0; i < tokens.length; i++) { - aedColumn = aedColumns[i]; - token = tokens[i]; - if (token !== '') { - nonEmptyTokens++; - } - if (aedColumn.name === 'name' && aedColumn.namespace === 'aed') { - name = token; - } else if (aedColumn.name === 'value' && aedColumn.namespace === 'aed') { - value = token; - } - } - - if (nonEmptyTokens === 2 && name && value) { - // Special row that defines metadata for the entire file - aedKey = parseAedToken(name); - // Store in the metadata section - if (!this.aed.metadata[aedKey.namespace]) { - this.aed.metadata[aedKey.namespace] = {}; - } - if (!this.aed.metadata[aedKey.namespace][aedKey.name]) { - this.aed.metadata[aedKey.namespace][aedKey.name] = { - type: aedKey.type, - value: value - }; - } - // Ignore this value - return undefined - } - - var feature = new AedFeature(this.aed, tokens); - - if (!feature.chr || (!feature.start && feature.start !== 0) || !feature.end) { - console.log('Cannot parse feature: ' + tokens.join(',')); - return undefined - } - - return feature - } - - /* - * The MIT License (MIT) - * - * Copyright (c) 2014 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - - // TODO -- big endian? - - class BinaryParser$1 { - constructor(dataView, littleEndian) { - - this.littleEndian = littleEndian !== undefined ? littleEndian : true; - this.position = 0; - this.view = dataView; - this.length = dataView.byteLength; - } - - available() { - return this.length - this.position - } - - remLength() { - return this.length - this.position - } - - hasNext() { - return this.position < this.length - 1 - } - - getByte() { - var retValue = this.view.getUint8(this.position, this.littleEndian); - this.position++; - return retValue - } - - getShort() { - - var retValue = this.view.getInt16(this.position, this.littleEndian); - this.position += 2; - return retValue - } - - getUShort() { - - // var byte1 = this.getByte(), - // byte2 = this.getByte(), - // retValue = ((byte2 << 24 >>> 16) + (byte1 << 24 >>> 24)); - // return retValue; - - // - var retValue = this.view.getUint16(this.position, this.littleEndian); - this.position += 2; - return retValue - } - - - getInt() { - - var retValue = this.view.getInt32(this.position, this.littleEndian); - this.position += 4; - return retValue - } - - - getUInt() { - var retValue = this.view.getUint32(this.position, this.littleEndian); - this.position += 4; - return retValue - } - - getLong() { - - // DataView doesn't support long. So we'll try manually - - var b = []; - b[0] = this.view.getUint8(this.position); - b[1] = this.view.getUint8(this.position + 1); - b[2] = this.view.getUint8(this.position + 2); - b[3] = this.view.getUint8(this.position + 3); - b[4] = this.view.getUint8(this.position + 4); - b[5] = this.view.getUint8(this.position + 5); - b[6] = this.view.getUint8(this.position + 6); - b[7] = this.view.getUint8(this.position + 7); - - var value = 0; - if (this.littleEndian) { - for (let i = b.length - 1; i >= 0; i--) { - value = (value * 256) + b[i]; - } - } else { - for (let i = 0; i < b.length; i++) { - value = (value * 256) + b[i]; - } - } - - - this.position += 8; - return value - } - - getString(len) { - - var s = ""; - var c; - while ((c = this.view.getUint8(this.position++)) !== 0) { - s += String.fromCharCode(c); - if (len && s.length === len) break - } - return s - } - - getFixedLengthString(len) { - - var s = ""; - var i; - var c; - for (i = 0; i < len; i++) { - c = this.view.getUint8(this.position++); - if (c > 0) { - s += String.fromCharCode(c); - } - } - return s - } - - getFixedLengthTrimmedString(len) { - - var s = ""; - var i; - var c; - for (i = 0; i < len; i++) { - c = this.view.getUint8(this.position++); - if (c > 32) { - s += String.fromCharCode(c); - } - } - return s - } - - getFloat() { - - var retValue = this.view.getFloat32(this.position, this.littleEndian); - this.position += 4; - return retValue - - - } - - getDouble() { - - var retValue = this.view.getFloat64(this.position, this.littleEndian); - this.position += 8; - return retValue - } - - skip(n) { - - this.position += n; - return this.position - } - - - /** - * Return a BGZip (bam and tabix) virtual pointer - * TODO -- why isn't 8th byte used ? - * @returns {*} - */ - getVPointer() { - - var position = this.position, - offset = (this.view.getUint8(position + 1) << 8) | (this.view.getUint8(position)), - byte6 = ((this.view.getUint8(position + 6) & 0xff) * 0x100000000), - byte5 = ((this.view.getUint8(position + 5) & 0xff) * 0x1000000), - byte4 = ((this.view.getUint8(position + 4) & 0xff) * 0x10000), - byte3 = ((this.view.getUint8(position + 3) & 0xff) * 0x100), - byte2 = ((this.view.getUint8(position + 2) & 0xff)), - block = byte6 + byte5 + byte4 + byte3 + byte2; - this.position += 8; - - // if (block == 0 && offset == 0) { - // return null; - // } else { - return new VPointer$1(block, offset) - // } - } - } - - class VPointer$1 { - constructor(block, offset) { - this.block = block; - this.offset = offset; - } - - isLessThan(vp) { - return this.block < vp.block || - (this.block === vp.block && this.offset < vp.offset) - } - - isGreaterThan(vp) { - return this.block > vp.block || - (this.block === vp.block && this.offset > vp.offset) - } - - isEqualTo(vp) { - return this.block === vp.block && this.offset === vp.offset - } - - print() { - return "" + this.block + ":" + this.offset - } - } - - function optimizeChunks(chunks, lowest) { - - if (chunks.length === 0) return chunks - - chunks.sort(function (c0, c1) { - - const dif = c0.minv.block - c1.minv.block; - if (dif !== 0) { - return dif - } else { - return c0.minv.offset - c1.minv.offset - } - }); - - if(chunks.length <= 1) { - return chunks - } - - // console.log("Before trimming " + chunks.length) - // for (let c of chunks) { - // console.log(`${c.minv.block} ${c.minv.offset} - ${c.maxv.block} ${c.maxv.offset}`) - // } - - if (lowest) { - chunks = chunks.filter(c => c.maxv.isGreaterThan(lowest)); - } - - // console.log("Before merging " + chunks.length) - // for (let c of chunks) { - // console.log(`${c.minv.block} ${c.minv.offset} - ${c.maxv.block} ${c.maxv.offset}`) - // } - - const mergedChunks = []; - let lastChunk; - for (let chunk of chunks) { - - if (!lastChunk) { - mergedChunks.push(chunk); - lastChunk = chunk; - } else { - if (canMerge(lastChunk, chunk)) { - if (chunk.maxv.isGreaterThan(lastChunk.maxv)) { - lastChunk.maxv = chunk.maxv; - } - } else { - mergedChunks.push(chunk); - lastChunk = chunk; - } - } - } - - // console.log("After merging " + mergedChunks.length) - // for (let c of mergedChunks) { - // console.log(`${c.minv.block} ${c.minv.offset} - ${c.maxv.block} ${c.maxv.offset}`) - // } - - return mergedChunks - } - - - /** - * Merge 2 blocks if the file position gap between them is < 16 kb, and the total size is < ~5 mb - * @param chunk1 - * @param chunk2 - * @returns {boolean|boolean} - */ - function canMerge(chunk1, chunk2) { - chunk2.minv.block - chunk1.maxv.block; - const sizeEstimate = chunk1.maxv.block - chunk1.minv.block; - return sizeEstimate < 5000000 - } - - // Represents a CSI Bam or Tabix index - - const CSI1_MAGIC$1 = 21582659; // CSI\1 - const CSI2_MAGIC$1 = 38359875; // CSI\2 - - async function parseCsiIndex(arrayBuffer, genome) { - - const idx = new CSIIndex(); - idx.parse(arrayBuffer, genome); - return idx - } - - class CSIIndex { - - constructor(tabix) { - this.tabix = true; // Means whatever is indexed is BGZipped - } - - parse(arrayBuffer, genome) { - const parser = new BinaryParser$1(new DataView(arrayBuffer)); - - const magic = parser.getInt(); - - if (magic !== CSI1_MAGIC$1) { - if (magic === CSI2_MAGIC$1) { - throw Error("CSI version 2 is not supported. Please enter an issue at https://github.com/igvteam/igv.js") - } else { - throw Error("Not a CSI index") - } - } - - this.indices = []; - this.blockMin = Number.MAX_SAFE_INTEGER; - this.lastBlockPosition = []; - this.sequenceIndexMap = {}; - - this.minShift = parser.getInt(); - this.depth = parser.getInt(); - const lAux = parser.getInt(); - const seqNames = []; - let bmax = 0; - - if (lAux >= 28) { - // Tabix header parameters aren't used, but they must be read to advance the pointer - parser.getInt(); - parser.getInt(); - parser.getInt(); - parser.getInt(); - parser.getInt(); - parser.getInt(); - const l_nm = parser.getInt(); - const nameEndPos = parser.position + l_nm; - let i = 0; - while (parser.position < nameEndPos) { - let seq_name = parser.getString(); - // Translate to "official" chr name. - if (genome) { - seq_name = genome.getChromosomeName(seq_name); - } - this.sequenceIndexMap[seq_name] = i; - seqNames[i] = seq_name; - i++; - } - } - - const MAX_BIN = this.bin_limit() + 1; - const nref = parser.getInt(); - for (let ref = 0; ref < nref; ref++) { - const binIndex = []; - const loffset = []; - const nbin = parser.getInt(); - for (let b = 0; b < nbin; b++) { - - const binNumber = parser.getInt(); - loffset[binNumber] = parser.getVPointer(); - - if (binNumber > MAX_BIN) { - // This is a psuedo bin, not used but we have to consume the bytes - parser.getInt(); // # of chunks for this bin - parser.getVPointer(); // unmapped beg - parser.getVPointer(); // unmapped end - parser.getLong(); - parser.getLong(); - - } else { - - binIndex[binNumber] = []; - const nchnk = parser.getInt(); // # of chunks for this bin - - for (let i = 0; i < nchnk; i++) { - const cs = parser.getVPointer(); //chunk_beg - const ce = parser.getVPointer(); //chunk_end - if (cs && ce) { - if (cs.block < this.blockMin) { - this.blockMin = cs.block; // Block containing first alignment - } - if (ce.block > bmax) { - bmax = ce.block; - } - binIndex[binNumber].push([cs, ce]); - } - } - } - } - - if (nbin > 0) { - this.indices[ref] = { - binIndex: binIndex, - loffset: loffset - }; - } - } - this.lastBlockPosition = bmax; - } - - get chromosomeNames() { - return Object.keys(this.sequenceIndexMap) - } - - /** - * Fetch blocks for a particular genomic range. This method is public so it can be unit-tested. - * - * @param refId the sequence dictionary index of the chromosome - * @param min genomic start position - * @param max genomic end position - * @param return an array of {minv: {filePointer, offset}, {maxv: {filePointer, offset}} - */ - chunksForRange(refId, min, max) { - - const ba = this.indices[refId]; - if (!ba) { - return [] - } else { - const overlappingBins = this.reg2bins(min, max); // List of bin #s that overlap min, max - if (overlappingBins.length == 0) return [] - - const chunks = []; - // Find chunks in overlapping bins. Leaf bins (< 4681) are not pruned - for (let binRange of overlappingBins) { - for (let bin = binRange[0]; bin <= binRange[1]; bin++) { - if (ba.binIndex[bin]) { - const binChunks = ba.binIndex[bin]; - for (let c of binChunks) { - const cs = c[0]; - const ce = c[1]; - chunks.push({minv: cs, maxv: ce, bin: bin}); - } - } - } - } - - const lowestOffset = ba.loffset[overlappingBins[0]]; - - return optimizeChunks(chunks, lowestOffset) - } - - } - - // reg2bins implementation adapted from GMOD/tabix-js https://github.com/GMOD/tabix-js/blob/master/src/csi.ts - reg2bins(beg, end) { - beg -= 1; // < convert to 1-based closed - if (beg < 1) beg = 1; - if (end > 2 ** 34) end = 2 ** 34; // 17 GiB ought to be enough for anybody - end -= 1; - let l = 0; - let t = 0; - let s = this.minShift + this.depth * 3; - const bins = []; - for (; l <= this.depth; s -= 3, t += (1 << l * 3), l += 1) { - const b = t + (beg >> s); - const e = t + (end >> s); - // - // ITS NOT CLEAR WHERE THIS TEST CAME FROM, but maxBinNumber is never set, and its not clear what it represents. - // if (e - b + bins.length > this.maxBinNumber) - // throw new Error( - // `query ${beg}-${end} is too large for current binning scheme (shift ${this.minShift}, depth ${this.depth}), try a smaller query or a coarser index binning scheme`, - // ) - // - bins.push([b, e]); - } - return bins - } - - - bin_limit() { - return ((1 << (this.depth + 1) * 3) - 1) / 7 - } - - } - - // Represents a BAM or Tabix index. - - const BAI_MAGIC$1 = 21578050; - const TABIX_MAGIC$1 = 21578324; - - - async function parseBamIndex(arrayBuffer, genome) { - const index = new BamIndex(); - await index.parse(arrayBuffer, false, genome); - return index - } - - async function parseTabixIndex(arrayBuffer, genome) { - const index = new BamIndex(); - await index.parse(arrayBuffer, true, genome); - return index - } - - class BamIndex { - - constructor() { - - } - - async parse(arrayBuffer, tabix, genome) { - - const indices = []; - let blockMin = Number.MAX_SAFE_INTEGER; - let blockMax = 0; - - const parser = new BinaryParser$1(new DataView(arrayBuffer)); - const magic = parser.getInt(); - const sequenceIndexMap = {}; - if (magic === BAI_MAGIC$1 || (tabix && magic === TABIX_MAGIC$1)) { - - const nref = parser.getInt(); - if (tabix) { - // Tabix header parameters aren't used, but they must be read to advance the pointer - parser.getInt(); - parser.getInt(); - parser.getInt(); - parser.getInt(); - parser.getInt(); - parser.getInt(); - parser.getInt(); - - for (let i = 0; i < nref; i++) { - let seq_name = parser.getString(); - // Translate to "official" chr name. - if (genome) { - seq_name = genome.getChromosomeName(seq_name); - } - sequenceIndexMap[seq_name] = i; - } - } - - // Loop through sequences - for (let ref = 0; ref < nref; ref++) { - - const binIndex = {}; - const linearIndex = []; - const nbin = parser.getInt(); - - for (let b = 0; b < nbin; b++) { - const binNumber = parser.getInt(); - if (binNumber === 37450) { - // This is a psuedo bin, not used but we have to consume the bytes - parser.getInt(); // # of chunks for this bin - parser.getVPointer(); // unmapped beg - parser.getVPointer(); // unmapped end - parser.getLong(); - parser.getLong(); - - } else { - - binIndex[binNumber] = []; - const nchnk = parser.getInt(); // # of chunks for this bin - - for (let i = 0; i < nchnk; i++) { - const cs = parser.getVPointer(); //chunk_beg - const ce = parser.getVPointer(); //chunk_end - if (cs && ce) { - if (cs.block < blockMin) { - blockMin = cs.block; // Block containing first alignment - } - if (ce.block > blockMax) { - blockMax = ce.block; - } - binIndex[binNumber].push([cs, ce]); - } - } - } - } - - const nintv = parser.getInt(); - for (let i = 0; i < nintv; i++) { - const cs = parser.getVPointer(); - linearIndex.push(cs); // Might be null - } - - if (nbin > 0) { - indices[ref] = { - binIndex: binIndex, - linearIndex: linearIndex - }; - } - } - - this.firstBlockPosition = blockMin; - this.lastBlockPosition = blockMax; - this.indices = indices; - this.sequenceIndexMap = sequenceIndexMap; - this.tabix = tabix; - - } else { - throw new Error(indexURL + " is not a " + (tabix ? "tabix" : "bai") + " file") - } - - - } - - get chromosomeNames() { - return Object.keys(this.sequenceIndexMap) - } - - /** - * Fetch chunks for a particular genomic range. This method is public so it can be unit-tested. - * - * @param refId the sequence dictionary index of the chromosome - * @param min genomic start position - * @param max genomic end position - * @param return an array of objects representing chunks (file spans) {minv: {block, offset}, {maxv: {block, offset}} - */ - chunksForRange(refId, min, max) { - - const bam = this; - const ba = bam.indices[refId]; - - if (!ba) { - return [] - } else { - const overlappingBins = reg2bins(min, max); // List of bin #s that overlap min, max - - //console.log("bin ranges") - //for(let b of overlappingBins) { - // console.log(`${b[0]} - ${b[1]}`) - //} - - const chunks = []; - // Find chunks in overlapping bins. Leaf bins (< 4681) are not pruned - for (let binRange of overlappingBins) { - for (let bin = binRange[0]; bin <= binRange[1]; bin++) { - if (ba.binIndex[bin]) { - const binChunks = ba.binIndex[bin]; - for (let c of binChunks) { - const cs = c[0]; - const ce = c[1]; - chunks.push({minv: cs, maxv: ce}); - } - } - } - } - - // Use the linear index to find minimum file position of chunks that could contain alignments in the region - const nintv = ba.linearIndex.length; - - let lowest; - const minLin = Math.min(min >> 14, nintv - 1); // i.e. min / 16384 - const maxLin = Math.min(max >> 14, nintv - 1); - for (let i = minLin; i <= maxLin; i++) { - const vp = ba.linearIndex[i]; - if (vp) { - lowest = vp; // lowest file offset that contains alignments overlapping (min, max) - break - } - } - - return optimizeChunks(chunks, lowest) - } - } - } - - - - /** - * Calculate the list of bins that overlap with region [beg, end] - * - */ - function reg2bins(beg, end) { - const list = []; - if (end >= 1 << 29) end = 1 << 29; - --end; - list.push([0, 0]); - list.push([1 + (beg >> 26), 1 + (end >> 26)]); - list.push([9 + (beg >> 23), 9 + (end >> 23)]); - list.push([73 + (beg >> 20), 73 + (end >> 20)]); - list.push([585 + (beg >> 17), 585 + (end >> 17)]); - list.push([4681 + (beg >> 14), 4681 + (end >> 14)]); - - // for (k = 1 + (beg >> 26); k <= 1 + (end >> 26); ++k) list.push(k); - // for (k = 9 + (beg >> 23); k <= 9 + (end >> 23); ++k) list.push(k); - // for (k = 73 + (beg >> 20); k <= 73 + (end >> 20); ++k) list.push(k); - // for (k = 585 + (beg >> 17); k <= 585 + (end >> 17); ++k) list.push(k); - // for (k = 4681 + (beg >> 14); k <= 4681 + (end >> 14); ++k) list.push(k); - return list - } - - /* - * The MIT License (MIT) - * - * Copyright (c) 2014 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - async function parseTribbleIndex(arrayBuffer, genome) { - - const index = new TribbleIndex(); - index.parse(arrayBuffer, genome); - return index - } - - class TribbleIndex { - - constructor() { - - } - - async parse(arrayBuffer, genome) { - - let blockMax = 0; - this.chrIndex = {}; - this.lastBlockPosition = []; - const parser = new BinaryParser$1(new DataView(arrayBuffer)); - readHeader(parser); - - let nChrs = parser.getInt(); - while (nChrs-- > 0) { - - // todo -- support interval tree index, we're assuming its a linear index - - let chr = parser.getString(); - if (genome) chr = genome.getChromosomeName(chr); // Translate to canonical name - - const binWidth = parser.getInt(); - const nBins = parser.getInt(); - const longestFeature = parser.getInt(); - parser.getInt() > 0; - parser.getInt(); - - // note the code below accounts for > 60% of the total time to read an index - let pos = parser.getLong(); - const blocks = []; - for (let binNumber = 0; binNumber < nBins; binNumber++) { - const nextPos = parser.getLong(); - blocks.push({min: pos, max: nextPos}); // {position: pos, size: size}); - pos = nextPos; - if (nextPos > blockMax) { - blockMax = nextPos; - } - } - this.chrIndex[chr] = {chr: chr, blocks: blocks, longestFeature: longestFeature, binWidth: binWidth}; - } - - this.lastBlockPosition = blockMax; - - - /** - * Read the header . Data here is not used in igv.js but we need to read it to advance the pointer. - * @param parser - */ - function readHeader(parser) { - - parser.getInt(); // view._getInt32(offset += 32, true); - parser.getInt(); - const version = parser.getInt(); - parser.getString(); - parser.getLong(); - parser.getLong(); - parser.getString(); - parser.getInt(); - if (version >= 3) { - let nProperties = parser.getInt(); - while (nProperties-- > 0) { - parser.getString(); - parser.getString(); - } - } - } - } - - get chromosomeNames() { - return Object.keys(this.chrIndex) - } - - - /** - * Fetch blocks for a particular genomic range. - * - * @param queryChr the sequence dictionary index of the chromosome - * @param min genomic start position - * @param max genomic end position - */ - chunksForRange(queryChr, min, max) { //function (refId, min, max) { - const chrIdx = this.chrIndex[queryChr]; - - if (chrIdx) { - const blocks = chrIdx.blocks; - const longestFeature = chrIdx.longestFeature; - const binWidth = chrIdx.binWidth; - const adjustedPosition = Math.max(min - longestFeature, 0); - const startBinNumber = Math.floor(adjustedPosition / binWidth); - - if (startBinNumber >= blocks.length) // are we off the end of the bin list, so return nothing - return [] - else { - const endBinNumber = Math.min(Math.floor((max - 1) / binWidth), blocks.length - 1); - - // By definition blocks are adjacent in the file for the liner index. Combine them into one merged block - const startPos = blocks[startBinNumber].min; - const endPos = blocks[endBinNumber].max; - const size = endPos - startPos; - if (size === 0) { - return [] - } else { - const mergedBlock = {minv: {block: startPos, offset: 0}, maxv: {block: endPos, offset: 0}}; - return [mergedBlock] - } - } - } else { - return undefined - } - } - } - - const CSI1_MAGIC = 21582659; // CSI\1 - const CSI2_MAGIC = 38359875; // CSI\2 - const BAI_MAGIC = 21578050; - const TABIX_MAGIC = 21578324; - const TRIBBLE_MAGIC = 1480870228; // byte[]{'T', 'I', 'D', 'X'}; - - /** - * @param indexURL - * @param config - * @param tabix - * - */ - async function loadIndex(indexURL, config, genome) { - - let arrayBuffer = await igvxhr.loadArrayBuffer(indexURL, buildOptions$1(config)); - let dv = new DataView(arrayBuffer); - - // Some indexs are bgzipped, specifically tabix, and csi. Bam (bai) are not. Tribble is usually not. - // Check first 2 bytes of file for gzip magic number, and inflate if neccessary - if (dv.getUint8(0) === 0x1f && dv.getUint8(1) === 0x8b) { // gzipped - const inflate = unbgzf(arrayBuffer); - arrayBuffer = inflate.buffer; - dv = new DataView(arrayBuffer); - } - - const magic = dv.getInt32(0, true); - switch (magic) { - case BAI_MAGIC: - return parseBamIndex(arrayBuffer, genome) - case TABIX_MAGIC: - return parseTabixIndex(arrayBuffer, genome) - case CSI1_MAGIC: - return parseCsiIndex(arrayBuffer, genome) - case TRIBBLE_MAGIC: - return parseTribbleIndex(arrayBuffer, genome) - case CSI2_MAGIC: - throw Error("CSI version 2 is not supported.") - default: - throw Error(`Unrecognized index type: ${indexURL}`) - } - } - - /* - * The MIT License (MIT) - * - * Copyright (c) 2016-2017 The Regents of the University of California - * Author: Jim Robinson - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - function getDataWrapper(data) { - - if (typeof (data) == 'string' || data instanceof String) { - return new StringDataWrapper(data) - } else { - return new ByteArrayDataWrapper(data) - } - } - - - // Data might be a string, or an UInt8Array - class StringDataWrapper { - - constructor(string) { - this.data = string; - this.ptr = 0; - } - - nextLine() { - var start = this.ptr, - idx = this.data.indexOf('\n', start), - data = this.data; - - if (idx > 0) { - this.ptr = idx + 1; // Advance pointer for next line - if (idx > start && data.charAt(idx - 1) === '\r') { - // Trim CR manually in CR/LF sequence - return data.substring(start, idx - 1) - } - return data.substring(start, idx) - } else { - var length = data.length; - this.ptr = length; - // Return undefined only at the very end of the data - return (start >= length) ? undefined : data.substring(start) - } - } - } - - class ByteArrayDataWrapper { - - constructor(array) { - this.data = array; - this.length = this.data.length; - this.ptr = 0; - } - - nextLine() { - - var c, result; - result = ""; - - if (this.ptr >= this.length) return undefined - - for (var i = this.ptr; i < this.length; i++) { - c = String.fromCharCode(this.data[i]); - if (c === '\r') continue - if (c === '\n') break - result = result + c; - } - - this.ptr = i + 1; - return result - } - - } - - /** - * Class to iterate line-by-line over a BGZipped text file. This class is useful for iterating from the start of - * the file. Not useful for indexed queries. - */ - - class BGZLineReader { - - constructor(config) { - this.config = config; - this.filePtr = 0; - this.bufferPtr = 0; - this.buffer; - } - - async nextLine() { - - let result = undefined; - - try { - while (true) { - const length = this.buffer ? this.buffer.length : 0; - while (this.bufferPtr < length) { - const c = String.fromCharCode(this.buffer[this.bufferPtr++]); - if (c === '\r') continue - if (c === '\n') { - return result - } - result = result ? result + c : c; - } - if (this.eof) { - return result - } else { - await this.readNextBlock(); - } - } - } catch (e) { - console.warn(e); - this.eof = true; - return result - } - } - - async readNextBlock() { - - const bsizeOptions = buildOptions$1(this.config, { - range: { - start: this.filePtr, - size: 26 - } - }); - const abuffer = await igvxhr.loadArrayBuffer(this.config.url, bsizeOptions); - const bufferSize = bgzBlockSize$1(abuffer); - - if (bufferSize === 0) { - this.eof = true; - this.buffer = undefined; - } else { - - const options = buildOptions$1(this.config, {range: {start: this.filePtr, size: bufferSize}}); - const data = await igvxhr.loadArrayBuffer(this.config.url, options); - if (data.byteLength < bufferSize) { - this.eof = true; // Assumption - } - this.buffer = unbgzf(data); - if(this.buffer.byteLength == 0) { - this.eof = true; - } - this.bufferPtr = 0; - this.filePtr += data.byteLength; //data.byteLength; - } - } - - } - - function concatenateArrayBuffers(arrayBuffers) { - - if (arrayBuffers.length === 1) { - return arrayBuffers[0] - } - - let len = 0; - for (const b of arrayBuffers) { - len += b.byteLength; - } - const c = new Uint8Array(len); - let offset = 0; - for (const b of arrayBuffers) { - c.set(new Uint8Array(b), offset); - offset += b.byteLength; - } - return c.buffer - } - - /** - * Return the block size for the data buffer. - * @param data - * @returns {number} - */ - const bgzBlockSize = (data) => { - const ba = ArrayBuffer.isView(data) ? data : new Uint8Array(data); - const bsize = (ba[17] << 8 | ba[16]) + 1; - return bsize - }; - - class BGZBlockLoader { - - constructor(config) { - this.config = config; - this.cacheBlocks = false != config.cacheBlocks; // Default to true - this.cache = undefined; - } - - /** - * Return inflated data from startBlock through endBlock as an UInt8Array - * - * @param minv minimum virtual pointer {block, offset} - * @param maxv maximum virtual pointer {block, offset} - * @returns {Promise} - */ - async getData(minv, maxv) { - - const startBlock = minv.block; - const endBlock = maxv.block; - const skipEnd = maxv.offset === 0; - - const blocks = await this.getInflatedBlocks(startBlock, endBlock, skipEnd); - if (blocks.length === 1) { - return blocks[0] - } - - let len = 0; - for (const b of blocks) { - len += b.byteLength; - } - const c = new Uint8Array(len); - let offset = 0; - for (const b of blocks) { - c.set(b, offset); - offset += b.byteLength; - } - return c - } - - /** - * Return the inflated data for the specified blocks as an array of Uint8Arrays. This method is public so - * it can be unit tested. * - * @param startBlock - * @param endBlock - * @returns {Promise<*[Uint8Array]>} - */ - async getInflatedBlocks(startBlock, endBlock, skipEnd) { - - if (!this.cacheBlocks) { - const buffer = await this.loadBLockData(startBlock, endBlock, {skipEnd}); - return inflateBlocks(buffer) - } else { - - const c = this.cache; - if (c && - c.startBlock <= startBlock && - (c.endBlock >= endBlock || skipEnd && c.nextEndBlock === endBlock)) { - //console.log("Complete overlap") - const startOffset = startBlock - c.startBlock; - const endOffset = endBlock - c.startBlock; - return inflateBlocks(c.buffer, startOffset, endOffset) - // Don't update cache, still valid - } else { - - let buffer; - if (!c || (c.startBlock > endBlock || c.endBlock < startBlock)) { - // no overlap with cache - buffer = await this.loadBLockData(startBlock, endBlock, {skipEnd}); - } else { - - //console.log("Some overlap") - const arrayBuffers = []; - - // Load blocks preceding cache start, if any - if (startBlock < c.startBlock) { - // load first blocks - const startBuffer = await this.loadBLockData(startBlock, c.startBlock, {skipEnd: true}); - arrayBuffers.push(startBuffer); - } - - // Slice cached buffer as needed - let cachedBuffer; - if (startBlock <= c.startBlock && endBlock >= c.endBlock) { - cachedBuffer = c.buffer; - } else { - const start = Math.max(0, startBlock - c.startBlock); - let end; - if (endBlock >= c.endBlock) { - end = c.buffer.byteLength; - } else { - // We need to find the byte position of the end of "endBlock" - const boundaries = findBlockBoundaries(c.buffer); - for (let i = 0; i < boundaries.length - 1; i++) { - if (c.startBlock + boundaries[i] === endBlock) { - end = boundaries[i + 1]; - break - } - } - // Do something if end not found - } - cachedBuffer = c.buffer.slice(start, end); - } - arrayBuffers.push(cachedBuffer); - - // Load end blocks, if any - if (endBlock > c.endBlock) { - const endBuffer = await this.loadBLockData(c.endBlock, endBlock, {skipStart: true, skipEnd}); - arrayBuffers.push(endBuffer); - } - - buffer = concatenateArrayBuffers(arrayBuffers); - } - - // If skipEnd === true we need to find boundary of last block in cache - let nextEndBlock = endBlock; - if(skipEnd) { - const boundaries = findBlockBoundaries(buffer); - endBlock = boundaries[boundaries.length - 1]; - } - - this.cache = {startBlock, endBlock, nextEndBlock, buffer}; - return inflateBlocks(buffer) - } - } - } - - async loadBLockData(startBlock, endBlock, options) { - - const config = this.config; - const skipStart = options && options.skipStart; - const skipEnd = options && options.skipEnd; - - // Get size of last block if not skipped - let lastBlockSize = 0; - if (!skipEnd) { - const bsizeOptions = buildOptions$1(config, {range: {start: endBlock, size: 26}}); - const abuffer = await igvxhr.loadArrayBuffer(config.url, bsizeOptions); - lastBlockSize = bgzBlockSize(abuffer); - } - - if (skipStart) { - const bsizeOptions = buildOptions$1(config, {range: {start: startBlock, size: 26}}); - const abuffer = await igvxhr.loadArrayBuffer(config.url, bsizeOptions); - startBlock += bgzBlockSize(abuffer); - } - - // Load data for all blocks - const loadOptions = buildOptions$1(config, { - range: { - start: startBlock, - size: endBlock + lastBlockSize - startBlock - } - }); - - //console.log(`${this.config.name} Loaded ${startBlock} - ${endBlock + lastBlockSize} (${(endBlock + lastBlockSize - startBlock) / 1000} kb)`) - - return igvxhr.loadArrayBuffer(config.url, loadOptions) - } - } - - function findBlockBoundaries(arrayBuffer) { - - const byteLengh = arrayBuffer.byteLength; - let offset = 0; - const blockBoundaries = [0]; - while (offset < byteLengh) { - //console.log("Cache block " + offset) - const ba = new Uint8Array(arrayBuffer, offset); - const bsize = (ba[17] << 8 | ba[16]) + 1; - offset += bsize; - if (offset < byteLengh) { - blockBoundaries.push(offset); - } - } - return blockBoundaries - } - - - /** - * Inflate compressed blocks within the data buffer* - * @param data - * @param startBlock - optional file location for start block. Default == 0 - * @param endBlock - optional file location for last block to decompress. - * @returns {*[]} - */ - function inflateBlocks(data, startBlock, endBlock) { - - startBlock = startBlock || 0; - - const oBlockList = []; - let ptr = startBlock; - - const lim = data.byteLength - 18; - while (ptr < lim) { - try { - //console.log(113873 + ptr) - const header = new Uint8Array(data, ptr, 18); - const xlen = (header[11] << 8) | (header[10]); - const bsize = ((header[17] << 8) | (header[16])); // Total block size, including header, minus 1 - const start = 12 + xlen + ptr; // Start of CDATA - const bytesLeft = data.byteLength - start; - const cDataSize = bsize - xlen - 18; - - if (bytesLeft < cDataSize || cDataSize <= 0) { - // This is unexpected. Throw error? - break - } - - const cdata = new Uint8Array(data, start, cDataSize); - const unc = inflateRaw_1(cdata); - oBlockList.push(unc); - - if (endBlock === ptr) { - break - } else { - // Advance to next block - ptr += bsize + 1; - } - - } catch (e) { - console.error(e); - break - } - } - return oBlockList - } - - /* - * The MIT License (MIT) - * - * Copyright (c) 2014 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - /** - * Reader for "bed like" files (tab delimited files with 1 feature per line: bed, gff, vcf, etc) - * - * @param config - * @constructor - */ - class FeatureFileReader { - - constructor(config, genome) { - - var uriParts; - - this.config = config || {}; - this.genome = genome; - this.indexURL = config.indexURL; - this.indexed = config.indexed || this.indexURL !== undefined; - this.queryable = this.indexed; - - if (isFile$1(this.config.url)) { - this.filename = this.config.url.name; - } else if (isDataURL(this.config.url)) { - this.indexed = false; // by definition - this.dataURI = config.url; - } else { - uriParts = parseUri(this.config.url); - this.filename = config.filename || uriParts.file; - } - - this.parser = this.getParser(this.config); - - if (this.config.format === "vcf" && !this.config.indexURL) { - console.warn("Warning: index file not specified. The entire vcf file will be loaded."); - } - - } - - async defaultVisibilityWindow() { - if (this.config.indexURL) { - const index = await this.getIndex(); - if (index && index.lastBlockPosition) { - let gl = 0; - const s = 10000; - for (let c of index.chromosomeNames) { - const chromosome = this.genome.getChromosome(c); - if (chromosome) { - gl += chromosome.bpLength; - } - } - return Math.round((gl / index.lastBlockPosition) * s) - } - } - } - - /** - * Return a promise to load features for the genomic interval - * @param chr - * @param start - * @param end - */ - async readFeatures(chr, start, end) { - - const index = await this.getIndex(); - if (index) { - this.indexed = true; - return this.loadFeaturesWithIndex(chr, start, end) - } else if (this.dataURI) { - this.indexed = false; - return this.loadFeaturesFromDataURI() - } else { - this.indexed = false; - return this.loadFeaturesNoIndex() - } - - } - - async readHeader() { - - if (this.dataURI) { - await this.loadFeaturesFromDataURI(this.dataURI); - return this.header - } else { - - if (this.config.indexURL) { - const index = await this.getIndex(); - if (!index) { - // Note - it should be impossible to get here - throw new Error("Unable to load index: " + this.config.indexURL) - } - - let dataWrapper; - if (index.tabix) { - this._blockLoader = new BGZBlockLoader(this.config); - dataWrapper = new BGZLineReader(this.config); - } else { - // Tribble - const maxSize = Object.values(index.chrIndex) - .flatMap(chr => chr.blocks) - .map(block => block.max) - .reduce((previous, current) => - Math.min(previous, current), Number.MAX_SAFE_INTEGER); - - const options = buildOptions$1(this.config, {bgz: index.tabix, range: {start: 0, size: maxSize}}); - const data = await igvxhr.loadString(this.config.url, options); - dataWrapper = getDataWrapper(data); - } - - - this.header = await this.parser.parseHeader(dataWrapper); // Cache header, might be needed to parse features - return this.header - - } else { - // If this is a non-indexed file we will load all features in advance - const options = buildOptions$1(this.config); - const data = await igvxhr.loadString(this.config.url, options); - let dataWrapper = getDataWrapper(data); - this.header = await this.parser.parseHeader(dataWrapper); - - // Reset data wrapper and parse features - dataWrapper = getDataWrapper(data); - this.features = await this.parser.parseFeatures(dataWrapper); // cache features - return this.header - } - } - } - - - getParser(config) { - - switch (config.format) { - case "vcf": - return new VcfParser(config) - case "seg" : - return new SegParser("seg") - case "mut": - return new SegParser("mut") - case "maf": - return new SegParser("maf") - case "gwas" : - return new GWASParser(config) - case "aed" : - return new AEDParser(config) - default: - return new FeatureParser(config) - } - } - - async loadFeaturesNoIndex() { - - if (this.features) { - // An optimization hack for non-indexed files, features are temporarily cached when header is read. - const tmp = this.features; - delete this.features; - return tmp - } else { - const options = buildOptions$1(this.config); // Add oauth token, if any - const data = await igvxhr.loadString(this.config.url, options); - if (!this.header) { - const dataWrapper = getDataWrapper(data); - this.header = await this.parser.parseHeader(dataWrapper); - } - const dataWrapper = getDataWrapper(data); - const features = await this.parser.parseFeatures(dataWrapper); // <= PARSING DONE HERE - return features - } - } - - async loadFeaturesWithIndex(chr, start, end) { - - // insure that header has been loaded -- tabix _blockLoader is initialized as side effect - if(!this.dataURI && !this.header) { - await this.readHeader(); - } - - //console.log("Using index" - const config = this.config; - const parser = this.parser; - const tabix = this.index.tabix; - const refId = tabix ? this.index.sequenceIndexMap[chr] : chr; - if (refId === undefined) { - return [] - } - - const genome = this.genome; - const chunks = this.index.chunksForRange(refId, start, end); - if (!chunks || chunks.length === 0) { - return [] - } else { - const allFeatures = []; - for (let chunk of chunks) { - - let inflated; - if (tabix) { - inflated = await this._blockLoader.getData(chunk.minv, chunk.maxv); - } else { - const options = buildOptions$1(config, { - range: { - start: chunk.minv.block, - size: chunk.maxv.block - chunk.minv.block + 1 - } - }); - inflated = await igvxhr.loadString(config.url, options); - } - - const slicedData = chunk.minv.offset ? inflated.slice(chunk.minv.offset) : inflated; - const dataWrapper = getDataWrapper(slicedData); - let slicedFeatures = await parser.parseFeatures(dataWrapper); - - // Filter psuedo-features (e.g. created mates for VCF SV records) - slicedFeatures = slicedFeatures.filter(f => f._f === undefined); - - // Filter features not in requested range. - let inInterval = false; - for (let i = 0; i < slicedFeatures.length; i++) { - const f = slicedFeatures[i]; - - const canonicalChromosome = genome ? genome.getChromosomeName(f.chr) : f.chr; - if (canonicalChromosome !== chr) { - if (allFeatures.length === 0) { - continue //adjacent chr to the left - } else { - break //adjacent chr to the right - } - } - if (f.start > end) { - allFeatures.push(f); // First feature beyond interval - break - } - if (f.end >= start && f.start <= end) { - if (!inInterval) { - inInterval = true; - if (i > 0) { - allFeatures.push(slicedFeatures[i - 1]); - } - } - allFeatures.push(f); - } - } - - } - allFeatures.sort(function (a, b) { - return a.start - b.start - }); - - return allFeatures - } - } - - async getIndex() { - if (this.index) { - return this.index - } else if (this.config.indexURL) { - this.index = await this.loadIndex(); - return this.index - } - } - - /** - * Return a Promise for the async loaded index - */ - async loadIndex() { - const indexURL = this.config.indexURL; - return loadIndex(indexURL, this.config, this.genome) - } - - async loadFeaturesFromDataURI() { - - if (this.features) { - // An optimization hack for non-indexed files, features are temporarily cached when header is read. - const tmp = this.features; - delete this.features; - return tmp - } else { - const plain = decodeDataURI$1(this.dataURI); - let dataWrapper = getDataWrapper(plain); - this.header = await this.parser.parseHeader(dataWrapper); - if (this.header instanceof String && this.header.startsWith("##gff-version 3")) { - this.format = 'gff3'; - } - - dataWrapper = getDataWrapper(plain); - this.features = await this.parser.parseFeatures(dataWrapper); - return this.features - } - } - - } - - /* - * The MIT License (MIT) - * - * Copyright (c) 2016 University of California San Diego - * Author: Jim Robinson - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - const isString$1 = isString$2; - - - class CustomServiceReader { - constructor(config) { - this.config = config; - } - - async readFeatures(chr, start, end) { - - let url; - if (typeof this.config.url === 'function') { - url = this.config.url({chr, start, end}); - } else { - url = this.config.url - .replace("$CHR", chr) - .replace("$START", start) - .replace("$END", end); - } - - let config = Object.assign({}, this.config); - if (this.config.body !== undefined) { - if (typeof this.config.body === 'function') { - config.body = this.config.body({chr, start, end}); - } else { - config.body = - this.config.body - .replace("$CHR", chr) - .replace("$START", start) - .replace("$END", end); - } - } - - - let features; - const data = await igvxhr.load(url, config); - if (data) { - if (typeof this.config.parser === "function") { - features = this.config.parser(data); - } else if (isString$1(data)) { - features = JSON.parse(data); - } else { - features = data; - } - } - if (this.config.mappings) { - let mappingKeys = Object.keys(this.config.mappings); - for (let f of features) { - for (let key of mappingKeys) { - f[key] = f[this.config.mappings[key]]; - } - } - } - return features - } - } - - /* - * The MIT License (MIT) - * - * Copyright (c) 2016-2017 The Regents of the University of California - * Author: Jim Robinson - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - const UCSCServiceReader = function (config, genome) { - this.config = config; - this.genome = genome; - this.expandQueryInterval = false; - }; - - UCSCServiceReader.prototype.readFeatures = function (chr, start, end) { - - const s = Math.max(0, Math.floor(start)); - let e = Math.ceil(end); - - if (this.genome) { - const c = this.genome.getChromosome(chr); - if (c && e > c.bpLength) { - e = c.bpLength; - } - } - - - const url = this.config.url + '?db=' + this.config.db + '&table=' + this.config.tableName + '&chr=' + chr + '&start=' + s + '&end=' + e; - - return igvxhr.loadJson(url, this.config) - .then(function (data) { - if (data) { - data.forEach(function (sample) { - if (sample.hasOwnProperty('exonStarts') && - sample.hasOwnProperty('exonEnds') && - sample.hasOwnProperty('exonCount') && - sample.hasOwnProperty('cdsStart') && - sample.hasOwnProperty('cdsEnd')) { - addExons(sample); - } - }); - return data - } else { - return null - } - }) - }; - - function addExons(sample) { - var exonCount, exonStarts, exonEnds, exons, eStart, eEnd; - exonCount = sample['exonCount']; - exonStarts = sample['exonStarts'].split(','); - exonEnds = sample['exonEnds'].split(','); - exons = []; - - for (var i = 0; i < exonCount; i++) { - eStart = parseInt(exonStarts[i]); - eEnd = parseInt(exonEnds[i]); - var exon = {start: eStart, end: eEnd}; - - if (sample.cdsStart > eEnd || sample.cdsEnd < sample.cdsStart) exon.utr = true; // Entire exon is UTR - if (sample.cdsStart >= eStart && sample.cdsStart <= eEnd) exon.cdStart = sample.cdsStart; - if (sample.cdsEnd >= eStart && sample.cdsEnd <= eEnd) exon.cdEnd = sample.cdsEnd; - - exons.push(exon); - } - - sample.exons = exons; - } - - /* - * The MIT License (MIT) - * - * Copyright (c) 2021 University of California San Diego - * Author: Jim Robinson - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - const gffNameFields = ["Name", "gene_name", "gene", "gene_id", "alias", "locus", "name"]; - - class GFFHelper { - - constructor(options) { - this.format = options.format; - this.nameField = options.nameField; - this.filterTypes = options.filterTypes === undefined ? - new Set(['chromosome']) : - new Set(options.filterTypes); - } - - combineFeatures(features, genomicInterval) { - - let combinedFeatures; - - const filterTypes = this.filterTypes; - features = features.filter(f => filterTypes === undefined || !filterTypes.has(f.type)); - - if ("gff3" === this.format) { - const tmp = this.combineFeaturesById(features); - combinedFeatures = this.combineFeaturesByType(tmp); - } else { - combinedFeatures = this.combineFeaturesByType(features); - } - combinedFeatures.sort(function (a, b) { - return a.start - b.start - }); - this.numberExons(combinedFeatures, genomicInterval); - this.nameFeatures(combinedFeatures); - return combinedFeatures - } - - /** - * Combine multiple non-transcript model features with the same ID on the same chromosome into a single feature. - * Features that are part of the transcript model (e.g. exon, mRNA, etc) are combined later. - * - * @param features - * @returns {[]} - */ - combineFeaturesById(features) { - - const chrIdMap = new Map(); - const combinedFeatures = []; - - for (let f of features) { - if (isTranscriptPart(f.type) || isTranscript(f.type) || !f.id) { - combinedFeatures.push(f); - } else { - let idMap = chrIdMap.get(f.chr); - if (!idMap) { - idMap = new Map(); - chrIdMap.set(f.chr, idMap); - } - - let featureArray = idMap.get(f.id); - if (featureArray) { - featureArray.push(f); - } else { - idMap.set(f.id, [f]); - } - } - } - - for (let idMap of chrIdMap.values()) { - for (let featureArray of idMap.values()) { - if (featureArray.length > 1) { - // Use the first feature as prototypical (for column 9 attributes), and adjust start/end - // Parts are represented as "exons", as that is how they are presented visually - const cf = featureArray[0]; - cf.exons = []; - for (let f of featureArray) { - cf.start = Math.min(cf.start, f.start); - cf.end = Math.max(cf.end, f.end); - cf.exons.push({ - start: f.start, - end: f.end - }); - } - combinedFeatures.push(cf); - } else { - combinedFeatures.push(featureArray[0]); - } - } - } - - return combinedFeatures - } - - combineFeaturesByType(features) { - - // Build dictionary of genes - const genes = features.filter(f => "gene" === f.type || f.type.endsWith("_gene")); - const geneMap = Object.create(null); - for (let g of genes) { - geneMap[g.id] = g; - } - - // 1. Build dictionary of transcripts - const transcripts = Object.create(null); - const combinedFeatures = []; - const consumedFeatures = new Set(); - const filterTypes = this.filterTypes; - - features = features.filter(f => filterTypes === undefined || !filterTypes.has(f.type)); - - for (let f of features) { - - if (f.type === "biological_region") { - console.log(); - } - - if (isTranscript(f.type)) { - const transcriptId = f.id; // getAttribute(f.attributeString, "transcript_id", /\s+/); - if (undefined !== transcriptId) { - const gffTranscript = new GFFTranscript(f); - transcripts[transcriptId] = gffTranscript; - combinedFeatures.push(gffTranscript); - consumedFeatures.add(f); - const g = geneMap[f.parent]; - if (g) { - gffTranscript.geneObject = g; - consumedFeatures.add(g); - } - } - } - } - - // Add exons and transcript parts - for (let f of features) { - if (isTranscriptPart(f.type)) { - const parents = getParents(f); - if (parents) { - for (let id of parents) { - - let transcript = transcripts[id]; - if (!transcript && this.format === "gtf") { - // GTF does not require explicit transcript record, start one with this feature. - const psuedoTranscript = Object.assign({}, f); - psuedoTranscript.type = "transcript"; - transcript = new GFFTranscript(psuedoTranscript); - transcripts[id] = transcript; - combinedFeatures.push(transcript); - } - if (transcript !== undefined) { - - if (isExon(f.type)) { - if (parents.length > 1) { - // Make a copy as exon can be modified differently by CDS, etc, for each transcript - const e2 = new GFFFeature(f); - transcript.addExon(e2); - } else { - transcript.addExon(f); - } - } else { - transcript.addPart(f); - } - consumedFeatures.add(f); - } - } - } - } - } - - // Finish transcripts - combinedFeatures.forEach(function (f) { - if (typeof f.finish === "function") { - f.finish(); - } - }); - - // Add other features - const others = features.filter(f => !consumedFeatures.has(f)); - for (let f of others) { - combinedFeatures.push(f); - } - - return combinedFeatures - - function getParents(f) { - if (f.parent && f.parent.trim() !== "") { - return f.parent.trim().split(",") - } else { - return null - } - } - } - - numberExons(features, genomicInterval) { - - for (let f of features) { - if (f.exons && - (!genomicInterval || - (f.end <= genomicInterval.end && f.start > genomicInterval.start))) { - for (let i = 0; i < f.exons.length; i++) { - const exon = f.exons[i]; - exon.number = f.strand === "-" ? f.exons.length - i : i + 1; - } - } - } - } - - nameFeatures(features) { - // Find name (label) property - for (let f of features) { - if (f.attributeString) { - const delim = ('gff3' === this.format) ? '=' : ' '; - const attributes = parseAttributeString(f.attributeString, delim); - const attributesMap = new Map(attributes); - if (this.nameField) { - f.name = attributesMap.get(this.nameField); - } else { - for (let nameField of gffNameFields) { - if (attributesMap.has(nameField)) { - f.name = attributesMap.get(nameField); - break - } - } - } - } - } - } - } - - /* - * The MIT License (MIT) - * - * Copyright (c) 2015 UC San Diego - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - const GtexReader = function (config) { - - this.config = config; - this.url = config.url; - this.tissueId = config.tissueSiteDetailId; - this.indexed = true; - this.datasetId = config.datasetId || "gtex_v8"; - }; - - GtexReader.prototype.readFeatures = async function (chr, bpStart, bpEnd) { - - - let self = this, - queryChr = chr.startsWith("chr") ? chr : "chr" + chr, - queryStart = Math.floor(bpStart), - queryEnd = Math.ceil(bpEnd), - datasetId = this.datasetId, - queryURL = this.url + "?chromosome=" + queryChr + "&start=" + queryStart + "&end=" + queryEnd + - "&tissueSiteDetailId=" + this.tissueId + "&datasetId=" + datasetId; - - const json = await igvxhr.loadJson(queryURL, { - withCredentials: self.config.withCredentials - }); - if (json && json.singleTissueEqtl) { - //variants = json.variants; - //variants.sort(function (a, b) { - // return a.POS - b.POS; - //}); - //source.cache = new FeatureCache(chr, queryStart, queryEnd, variants); - - json.singleTissueEqtl.forEach(function (eqtl) { - eqtl.chr = eqtl.chromosome; - eqtl.position = eqtl.pos; - eqtl.start = eqtl.pos - 1; - eqtl.end = eqtl.start + 1; - eqtl.snp = eqtl.snpId; - eqtl.geneName = eqtl.geneSymbol; - eqtl.geneId = eqtl.gencodeId; - - }); - - return json.singleTissueEqtl - } else { - return undefined - } - }; - - /* - * The MIT License (MIT) - * - * Copyright (c) 2014 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - // Experimental class for fetching features from an mpg webservice. - // http://immvar.broadinstitute.org:3000/load_data?chromosome=&start=&end=&categories= - - const ImmVarReader = function (config) { - - this.config = config; - this.url = config.url; - this.cellConditionId = config.cellConditionId; - this.valueThreshold = config.valueThreshold ? config.valueThreshold : 5E-2; - - }; - - ImmVarReader.prototype.readFeatures = function (queryChr, queryStart, queryEnd) { - - var self = this, - queryURL = this.url + "?chromosome=" + queryChr + "&start=" + queryStart + "&end=" + queryEnd + - "&cell_condition_id=" + this.cellConditionId; - - return new Promise(function (fulfill, reject) { - igvxhr.loadJson(queryURL, { - withCredentials: self.config.withCredentials - }).then(function (json) { - - if (json) { - //variants = json.variants; - //variants.sort(function (a, b) { - // return a.POS - b.POS; - //}); - //source.cache = new FeatureCache(chr, queryStart, queryEnd, variants); - - json.eqtls.forEach(function (eqtl) { - eqtl.chr = eqtl.chromosome; - eqtl.start = eqtl.position; - eqtl.end = eqtl.position + 1; - }); - - fulfill(json.eqtls); - } else { - fulfill(null); - } - - }).catch(function (error) { - reject(error); - }); - - }) - }; - - /* - * The MIT License (MIT) - * - * Copyright (c) 2014 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - const apiKey = igvxhr.apiKey; - - function ga4ghGet(options) { - var url = options.url + "/" + options.entity + "/" + options.entityId; - options.headers = ga4ghHeaders(); - return igvxhr.loadJson(url, options) // Returns a promise - } - - function ga4ghSearch(options) { - - return new Promise(function (fulfill, reject) { - var results = options.results ? options.results : [], - url = options.url, - body = options.body, - decode = options.decode, - paramSeparator = "?", - fields = options.fields; // Partial response - - - if (apiKey) { - url = url + paramSeparator + "key=" + apiKey; - paramSeparator = "&"; - } - - if (fields) { - url = url + paramSeparator + "fields=" + fields; - } - - - // Start the recursive load cycle. Data is fetched in chunks, if more data is available a "nextPageToken" is returned. - return loadChunk() - - function loadChunk(pageToken) { - - if (pageToken) { - body.pageToken = pageToken; - } else { - if (body.pageToken !== undefined) delete body.pageToken; // Remove previous page token, if any - } - - var sendData = JSON.stringify(body); - - igvxhr.loadJson(url, { - sendData: sendData, - contentType: "application/json", - headers: ga4ghHeaders(), - // oauthToken: ga4ghToken() - }) - .then(function (json) { - var nextPageToken, tmp; - - if (json) { - - tmp = decode ? decode(json) : json; - - if (tmp) { - - tmp.forEach(function (a) { - { - results.push(a); - } - }); - } - - - nextPageToken = json["nextPageToken"]; - - if (nextPageToken) { - loadChunk(nextPageToken); - } else { - fulfill(results); - } - } else { - fulfill(results); - } - - }) - .catch(function (error) { - reject(error); - }); - } - - }) - - - } - - function ga4ghHeaders() { - return { - "Cache-Control": "no-cache" - } - } - - /* - * The MIT License (MIT) - * - * Copyright (c) 2014 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - const Ga4ghVariantReader = function (config, genome) { - - this.config = config; - this.genome = genome; - this.url = config.url; - this.variantSetId = config.variantSetId; - this.callSetIds = config.callSetIds; - this.includeCalls = (config.includeCalls === undefined ? true : config.includeCalls); - - }; - - // Simulate a VCF file header - Ga4ghVariantReader.prototype.readHeader = function () { - - var self = this; - - - if (self.header) { - return Promise.resolve(self.header) - } else { - - self.header = {}; - - if (self.includeCalls === false) { - return Promise.resolve(self.header) - } else { - - var readURL = self.url + "/callsets/search"; - - return ga4ghSearch({ - url: readURL, - fields: "nextPageToken,callSets(id,name)", - body: { - "variantSetIds": (Array.isArray(self.variantSetId) ? self.variantSetId : [self.variantSetId]), - "pageSize": "10000" - }, - decode: function (json) { - // If specific callSetIds are specified filter to those - if (self.callSetIds) { - var callSets = [], - csIdSet = new Set(); - - self.callSetIds.forEach(function (csid) { - csIdSet.add(csid); - }); - - json.callSets.forEach(function (cs) { - if (csIdSet.has(cs.id)) { - callSets.push(cs); - } - }); - return callSets - } else { - return json.callSets - } - } - }) - .then(function (callSets) { - self.header.callSets = callSets; - return self.header - }) - } - } - }; - - - Ga4ghVariantReader.prototype.readFeatures = function (chr, bpStart, bpEnd) { - - const self = this; - const genome = this.genome; - - return self.readHeader() - - .then(function (header) { - return getChrAliasTable() - }) - - .then(function (chrAliasTable) { - - var queryChr = chrAliasTable.hasOwnProperty(chr) ? chrAliasTable[chr] : chr, - readURL = self.url + "/variants/search"; - - return ga4ghSearch({ - url: readURL, - fields: (self.includeCalls ? undefined : "nextPageToken,variants(id,variantSetId,names,referenceName,start,end,referenceBases,alternateBases,quality,filter,info)"), - body: { - "variantSetIds": (Array.isArray(self.variantSetId) ? self.variantSetId : [self.variantSetId]), - "callSetIds": (self.callSetIds ? self.callSetIds : undefined), - "referenceName": queryChr, - "start": bpStart.toString(), - "end": bpEnd.toString(), - "pageSize": "10000" - }, - decode: function (json) { - - var v; - - var variants = []; - - json.variants.forEach(function (json) { - - v = createGAVariant(json); - - if (!v.isRefBlock()) { - variants.push(v); - } - }); - - return variants - } - }) - }) - - - function getChrAliasTable() { - - return new Promise(function (fulfill, reject) { - - if (self.chrAliasTable) { - fulfill(self.chrAliasTable); - } else { - self.readMetadata().then(function (json) { - - self.metadata = json.metadata; - self.chrAliasTable = {}; - - if (json.referenceBounds && genome) { - - json.referenceBounds.forEach(function (rb) { - var refName = rb.referenceName, - alias = genome.getChromosomeName(refName); - self.chrAliasTable[alias] = refName; - - }); - } - fulfill(self.chrAliasTable); - - }); - } - - }) - } - - }; - - - Ga4ghVariantReader.prototype.readMetadata = function () { - - return ga4ghGet({ - url: this.url, - entity: "variantsets", - entityId: this.variantSetId - }) - }; - - class CivicReader { - - constructor(config) { - this.config = config; - } - - async readFeatures(chr, start, end) { - - const json = await igvxhr.loadJson(this.config.url + "/variants/?count=50000"); - const records = json.records; - const features = []; - - for (let record of records) { - - if (record.coordinates) { - - record.id; - const coordinates = record.coordinates; - - if (coordinates.chromosome) { - features.push( - new CivicVariant( - coordinates.chromosome, - coordinates.start - 1, // UCSC 0 convention - coordinates.stop, - record - )); - } - - if (coordinates.chromosome2) { - features.push( - new CivicVariant( - coordinates.chromosome2, - coordinates.start2 - 1, // UCSC 0 convention - coordinates.stop2, - record - )); - } - } - - } - return features - - } - } - - class CivicVariant { - - constructor(chr, start, end, record) { - this.chr = chr; - this.start = start; - this.end = end; - this.id = record.id; - this.entrezName = record.entrez_name; - this.name = record.name; - this.actionabilityScore = record.civic_actionability_score; - - if (record.coordinates.reference_bases) { - this.refBases = record.coordinates.reference_bases; - } - if (record.coordinates.variant_bases) { - this.altBases = record.coordinates.variant_bases; - } - if (record.variant_types) { - this.variant_types = record.variant_types; - } - - this.locationString = (this.chr + ":" + - numberFormatter$1(this.start + 1) + "-" + - numberFormatter$1(this.end)); - - // Color based on actionability score - if (this.actionabilityScore !== undefined) { - let alpha; - if (this.actionabilityScore <= 10) { - alpha = 0.2; - } else { - const v = Math.min(30, this.actionabilityScore); - alpha = 0.2 + 0.8 * Math.log10((v - 10) / 2); - } - this.alpha = alpha; - } - - - } - - popupData() { - - - const link = createLink("CIViC", "https://civicdb.org/links/variants/" + this.id); - this.refBases !== this.altBases && - this.refBases && this.refBases.length === 1 && - this.altBases && this.altBases.length === 1; - - - const pd = [link]; - pd.push({ - name: "Entrez", - value: createLink(this.entrezName, "https://ghr.nlm.nih.gov/gene/" + this.entrezName) - }); - pd.push({name: "Name", value: this.name}); - - if (this.variant_types && this.variant_types.length > 0) { - - const name = this.variant_types.length === 1 ? "Type" : "Types"; - let typeString; - for (let vt of this.variant_types) { - if (!typeString) typeString = vt.display_name; - else typeString += ", " + vt.display_name; - } - - pd.push({name: name, value: typeString}); - } - - pd.push({name: "Actionability", value: this.actionabilityScore}); - - - pd.push({name: "Location", value: this.locationString}); - - return pd - - - function createLink(text, href) { - return "" + text + "" - } - - } - } - - /* - * The MIT License (MIT) - * - * Copyright (c) 2016-2017 The Regents of the University of California - * Author: Jim Robinson - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - class HtsgetReader { - - constructor(config, genome) { - this.config = config; - this.genome = genome; - this.format = config.format ? config.format.toUpperCase() : "BAM"; // Backward compatibility - if (!(this.format === "BAM" || this.format === "VCF")) { - throw Error(`htsget format ${config.format} is not supported`) - } - } - - async readHeaderData() { - const url = `${getUrl(this.config)}?class=header&format=${this.format}`; - const ticket = await igvxhr.loadJson(url, buildOptions$1(this.config)); - return await this.loadUrls(ticket.htsget.urls) - } - - async readData(chr, start, end) { - const url = `${getUrl(this.config)}?format=${this.format}&referenceName=${chr}&start=${Math.floor(start)}&end=${Math.ceil(end)}`; - const ticket = await igvxhr.loadJson(url, buildOptions$1(this.config)); - return this.loadUrls(ticket.htsget.urls) - } - - async loadUrls(urls) { - - const promiseArray = []; - for (let urlData of urls) { - - if (urlData.url.startsWith('data:')) { - // this is a data-uri - promiseArray.push(Promise.resolve(dataUriToBytes(urlData.url))); - - } else { - - const options = buildOptions$1(this.config || {}); - - if (urlData.headers) { - options.headers = Object.assign(options.headers || {}, urlData.headers); - } - - promiseArray.push(igvxhr.loadArrayBuffer(urlData.url, options)); - } - } - const arrayBuffers = await Promise.all(promiseArray); - return concatArrays(arrayBuffers) - } - - - static async inferFormat(config) { - try { - const url = getUrl(config); - const headerURL = `${url}${url.includes("?") ? "&" : "?"}class=header`; - const ticket = await igvxhr.loadJson(headerURL, buildOptions$1(config)); - if (ticket.htsget) { - const format = ticket.htsget.format; - if (!(format === "BAM" || format === "VCF")) { - throw Error(`htsget format ${format} is not supported`) - } - config.format = format.toLowerCase(); - config.sourceType = "htsget"; - if (!config.name) { - config.name = await getFilename$1(config.url); - } - } - } catch (e) { - // Errors => this is not an htsget source, not an application error. Ignore - } - } - } - - /** - * Extract the full url from the config. Striving for backward compatibility, "endpoint" and "id" are deprecated. - * - * @param config - */ - function getUrl(config) { - if (config.url && config.endpoint && config.id) { - return config.url + config.endpoint + config.id // Deprecated - } else if (config.endpoint && config.id) { - return config.endpoint + config.id // Deprecated - } else if (config.url) { - if (config.url.startsWith("htsget://")) { - return config.url.replace("htsget://", "https://") // htsget -> http not supported - } else { - return config.url - } - } else { - throw Error("Must specify either 'url', or 'endpoint' and 'id") - } - - - } - - /** - * Concatenate a list of array buffers, returning an UInt8Array - * @param arrayBuffers - */ - function concatArrays(arrayBuffers) { - - let len = 0; - for (let a of arrayBuffers) { - len += a.byteLength; - } - - let offset = 0; - const newArray = new Uint8Array(len); - for (let buf of arrayBuffers) { - const a = new Uint8Array(buf); - newArray.set(a, offset); - offset += a.length; - } - - return newArray - } - - function dataUriToBytes(dataUri) { - - const split = dataUri.split(','); - const info = split[0].split(':')[1]; - let dataString = split[1]; - - if (info.indexOf('base64') >= 0) { - dataString = atob(dataString); - } else { - dataString = decodeURI(dataString); - } - - const bytes = new Uint8Array(dataString.length); - for (var i = 0; i < dataString.length; i++) { - bytes[i] = dataString.charCodeAt(i); - } - - return bytes - } - - /* - * The MIT License (MIT) - * - * Copyright (c) 2016-2017 The Regents of the University of California - * Author: Jim Robinson - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - class HtsgetVariantReader extends HtsgetReader { - - constructor(config, genome) { - super(config, genome); - this.parser = new VcfParser(); - } - - async readHeader() { - if (!this.header) { - const data = await this.readHeaderData(); - const dataWrapper = getDataWrapper(data); - this.header = await this.parser.parseHeader(dataWrapper, this.genome); - this.chrAliasTable = this.header.chrAliasTable; - } - return this.header - } - - async readFeatures(chr, start, end) { - - if (this.config.format && this.config.format.toUpperCase() !== "VCF") { - throw Error(`htsget format ${this.config.format} is not supported`) - } - - if (!this.chrAliasTable) { - await this.readHeader(); - } - - let queryChr = this.chrAliasTable.has(chr) ? this.chrAliasTable.get(chr) : chr; - - const data = await this.readData(queryChr, start, end); - - const dataWrapper = getDataWrapper(data); - - return this.parser.parseFeatures(dataWrapper) - - // return dataWrapper; - - } - - } - - // Assigns a row # to each feature. If the feature does not fit in any row and #rows == maxRows no - // row number is assigned. - function pack(featureList, maxRows) { - - maxRows = maxRows || Number.MAX_SAFE_INTEGER; - const rows = []; - featureList.sort(function (a, b) { - return a.start - b.start - }); - rows.push(-1000); - - for (let feature of featureList) { - let r = 0; - const len = Math.min(rows.length, maxRows); - for (r = 0; r < len; r++) { - if (feature.start >= rows[r]) { - feature.row = r; - rows[r] = feature.end; - break - } - } - feature.row = r; - rows[r] = feature.end; - } - } - - const DEFAULT_MAX_WG_COUNT$1 = 10000; - - /** - * Return a collection of "whole genome" features wrapping the supplied features, possibly downsampled. The purpose - * is to support painting features in "whole genome view". - * - * @param allFeatures - dictionary (object), keys are chromosome names, values are lists of features - * @param genome - * @param maxWGCount - optional, maximum # of whole genome features to computer - * @returns {*[]} - */ - function computeWGFeatures(allFeatures, genome, maxWGCount) { - - const max = maxWGCount || DEFAULT_MAX_WG_COUNT$1; - - const makeWGFeature = (f) => { - const wg = Object.assign({}, f); - wg.chr = "all"; - wg.start = genome.getGenomeCoordinate(f.chr, f.start); - wg.end = genome.getGenomeCoordinate(f.chr, f.end); - wg._f = f; - // Don't draw exons in whole genome view - if (wg["exons"]) delete wg["exons"]; - return wg - }; - - const wgChromosomeNames = new Set(genome.wgChromosomeNames); - const wgFeatures = []; - let count = 0; - for (let c of genome.wgChromosomeNames) { - - if(Array.isArray(allFeatures)) { - const featureDict = {}; - for(let f of allFeatures) { - const chr = genome.getChromosomeName(f.chr); - if(!featureDict.hasOwnProperty(chr)) { - featureDict[chr] = []; - } - featureDict[chr].push(f); - } - allFeatures = featureDict; - } - - const features = allFeatures[c]; - - if (features) { - for (let f of features) { - let queryChr = genome.getChromosomeName(f.chr); - if (wgChromosomeNames.has(queryChr)) { - if (wgFeatures.length < max) { - wgFeatures.push(makeWGFeature(f)); - } else { - //Reservoir sampling - const samplingProb = max / (count + 1); - if (Math.random() < samplingProb) { - const idx = Math.floor(Math.random() * (max - 1)); - wgFeatures[idx] = makeWGFeature(f); - } - } - } - count++; - } - } - } - - wgFeatures.sort(function (a, b) { - return a.start - b.start - }); - - return wgFeatures - } - - function packFeatures(features, maxRows) { - - maxRows = maxRows || 1000; - if (features == null || features.length === 0) { - return - } - // Segregate by chromosome - const chrFeatureMap = {}; - const chrs = []; - for (let feature of features) { - const chr = feature.chr; - let flist = chrFeatureMap[chr]; - if (!flist) { - flist = []; - chrFeatureMap[chr] = flist; - chrs.push(chr); - } - flist.push(feature); - } - - // Loop through chrosomosomes and pack features; - for (let chr of chrs) { - pack(chrFeatureMap[chr], maxRows); - } - } - - /* - * The MIT License (MIT) - * - * Copyright (c) 2014-2015 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - const DEFAULT_MAX_WG_COUNT = 10000; - - /** - * feature source for "bed like" files (tab or whitespace delimited files with 1 feature per line: bed, gff, vcf, etc) - * - * @param config - * @constructor - */ - class TextFeatureSource { - - constructor(config, genome) { - - this.config = config || {}; - this.genome = genome; - this.sourceType = (config.sourceType === undefined ? "file" : config.sourceType); - this.maxWGCount = config.maxWGCount || DEFAULT_MAX_WG_COUNT; - - const queryableFormats = new Set(["bigwig", "bw", "bigbed", "bb", "biginteract", "biggenepred", "bignarrowpeak", "tdf"]); - - this.queryable = config.indexURL || config.queryable === true; // False by default, unless explicitly set - if (config.reader) { - // Explicit reader implementation - this.reader = config.reader; - this.queryable = config.queryable !== false; - } else if (config.sourceType === "ga4gh") { - this.reader = new Ga4ghVariantReader(config, genome); - this.queryable = true; - } else if (config.sourceType === "immvar") { - this.reader = new ImmVarReader(config); - this.queryable = true; - } else if (config.type === "eqtl" && config.sourceType === "gtex-ws") { - this.reader = new GtexReader(config); - this.queryable = true; - } else if ("htsget" === config.sourceType) { - this.reader = new HtsgetVariantReader(config, genome); - this.queryable = true; - } else if (config.sourceType === 'ucscservice') { - this.reader = new UCSCServiceReader(config.source); - this.queryable = true; - } else if (config.sourceType === 'custom') { - this.reader = new CustomServiceReader(config.source); - this.queryable = false !== config.source.queryable; - } else if ("civic-ws" === config.sourceType) { - this.reader = new CivicReader(config); - this.queryable = false; - } else { - // File of some type (i.e. not a webservice) - this.reader = new FeatureFileReader(config, genome); - if (config.queryable !== undefined) { - this.queryable = config.queryable; - } else if (queryableFormats.has(config.format) || this.reader.indexed) { - this.queryable = true; - } else ; - } - - // Set searchable unless explicitly turned off, or track uses in indexed or otherwise queryable - // feature source. queryable => features loaded on demand (by query) - this.searchable = config.searchable === true || config.searchableFields || (config.searchable !== false && !this.queryable); - - } - - async defaultVisibilityWindow() { - if (this.reader && typeof this.reader.defaultVisibilityWindow === 'function') { - return this.reader.defaultVisibilityWindow() - } - } - - async trackType() { - const header = await this.getHeader(); - if (header) { - return header.type - } else { - return undefined // Convention for unknown or unspecified - } - } - - async getHeader() { - if (!this.header) { - - if (this.reader && typeof this.reader.readHeader === "function") { - const header = await this.reader.readHeader(); - if (header) { - this.header = header; - if (header.format) { - this.config.format = header.format; - } - } else { - this.header = {}; - } - } else { - this.header = {}; - } - } - return this.header - } - - /** - * Required function for all data source objects. Fetches features for the - * range requested. - * - * This function is quite complex due to the variety of reader types backing it, some indexed, some queryable, - * some not. - * - * @param chr - * @param start - * @param end - * @param bpPerPixel - */ - async getFeatures({chr, start, end, bpPerPixel, visibilityWindow}) { - - const genome = this.genome; - const queryChr = genome ? genome.getChromosomeName(chr) : chr; - const isWholeGenome = ("all" === queryChr.toLowerCase()); - - // Various conditions that can require a feature load - // * view is "whole genome" but no features are loaded - // * cache is disabled - // * cache does not contain requested range - // const containsRange = this.featureCache.containsRange(new GenomicInterval(queryChr, start, end)) - if ((isWholeGenome && !this.wgFeatures && this.supportsWholeGenome()) || - this.config.disableCache || - !this.featureCache || - !this.featureCache.containsRange(new GenomicInterval(queryChr, start, end))) { - await this.loadFeatures(queryChr, start, end, visibilityWindow); - } - - if (isWholeGenome) { - if (!this.wgFeatures) { - if (this.supportsWholeGenome()) { - this.wgFeatures = computeWGFeatures(this.featureCache.getAllFeatures(), this.genome, this.maxWGCount); - } else { - this.wgFeatures = []; - } - } - return this.wgFeatures - } else { - return this.featureCache.queryFeatures(queryChr, start, end) - } - } - - supportsWholeGenome() { - return !this.queryable // queryable (indexed, web services) sources don't support whole genome view - } - - // TODO -- experimental, will only work for non-indexed sources - getAllFeatures() { - if (this.queryable || !this.featureCache) { // queryable sources don't support all features - return [] - } else { - return this.featureCache.getAllFeatures() - } - } - - - async loadFeatures(queryChr, start, end, visibilityWindow) { - - const reader = this.reader; - let intervalStart = start; - let intervalEnd = end; - - // Use visibility window to potentially expand query interval. - // This can save re-queries as we zoom out. Visibility window <= 0 is a special case - // indicating whole chromosome should be read at once. - if ((!visibilityWindow || visibilityWindow <= 0) && this.config.expandQuery !== false) { - // Whole chromosome - const chromosome = this.genome ? this.genome.getChromosome(queryChr) : undefined; - intervalStart = 0; - intervalEnd = Math.max(chromosome ? chromosome.bpLength : Number.MAX_SAFE_INTEGER, end); - } else if (visibilityWindow > (end - start) && this.config.expandQuery !== false) { - const expansionWindow = Math.min(4.1 * (end - start), visibilityWindow); - intervalStart = Math.max(0, (start + end) / 2 - expansionWindow); - intervalEnd = start + expansionWindow; - } - - let features = await reader.readFeatures(queryChr, intervalStart, intervalEnd); - if (this.queryable === undefined) { - this.queryable = reader.indexed; - } - - const genomicInterval = this.queryable ? - new GenomicInterval(queryChr, intervalStart, intervalEnd) : - undefined; - - if (features) { - - if (this.config.assembleGFF !== false && - ("gtf" === this.config.format || "gff3" === this.config.format || "gff" === this.config.format)) { - features = (new GFFHelper(this.config)).combineFeatures(features, genomicInterval); - } - - // Assign overlapping features to rows - if (this.config.format !== "wig" && this.config.type !== "junctions") { - const maxRows = this.config.maxRows || Number.MAX_SAFE_INTEGER; - packFeatures(features, maxRows); - } - - // Note - replacing previous cache with new one. genomicInterval is optional (might be undefined => includes all features) - this.featureCache = new FeatureCache$1(features, this.genome, genomicInterval); - - // If track is marked "searchable"< cache features by name -- use this with caution, memory intensive - if (this.searchable) { - this.genome.addFeaturesToDB(features, this.config); - } - } else { - this.featureCache = new FeatureCache$1([], genomicInterval); // Empty cache - } - } - } - - /* - * The MIT License (MIT) - * - * Copyright (c) 2014 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - class BufferedReader { - - constructor(config, contentLength, bufferSize) { - this.path = config.url; - this.bufferSize = bufferSize ? bufferSize : 512000; - this.range = {start: -1, size: -1}; - this.config = config; - } - - /** - * - * @param requestedRange - byte rangeas {start, size} - * @param fulfill - function to receive result - * @param asUint8 - optional flag to return result as an UInt8Array - */ - async dataViewForRange(requestedRange, asUint8, retries = 0) { - try { - - const hasData = (this.data && (this.range.start <= requestedRange.start) && - ((this.range.start + this.range.size) >= (requestedRange.start + requestedRange.size))); - - if (!hasData) { - let bufferSize; - // If requested range size is specified, potentially expand buffer size - if (requestedRange.size) { - bufferSize = Math.max(this.bufferSize, requestedRange.size); - } else { - bufferSize = this.bufferSize; - } - if (this.contentLength) { - bufferSize = Math.min(bufferSize, this.contentLength - requestedRange.start); - } - const loadRange = {start: requestedRange.start, size: bufferSize}; - const arrayBuffer = await igvxhr.loadArrayBuffer(this.path, buildOptions$1(this.config, {range: loadRange})); - this.data = arrayBuffer; - this.range = loadRange; - } - - const len = this.data.byteLength; - const bufferStart = requestedRange.start - this.range.start; - return asUint8 ? - new Uint8Array(this.data, bufferStart, len - bufferStart) : - new DataView(this.data, bufferStart, len - bufferStart) - } catch (e) { - if (retries === 0 && e.message && e.message.startsWith("416")) { - try { - this.contentLength = await igvxhr.getContentLength(this.path, buildOptions$1(this.config)); - return this.dataViewForRange(requestedRange, asUint8, ++retries) - } catch (e1) { - console.error(e1); - } - throw e - } - } - } - } - - function getDecoder(definedFieldCount, fieldCount, autoSql, format) { - - if ("biginteract" === format || (autoSql && ('chromatinInteract' === autoSql.table) || 'interact' === autoSql.table)) { - return decodeInteract - } else { - const standardFieldCount = definedFieldCount - 3; - return function (feature, tokens) { - - if (standardFieldCount > 0) { - feature.name = tokens[0]; - } - if (standardFieldCount > 1) { - feature.score = Number(tokens[1]); - } - if (standardFieldCount > 2) { - feature.strand = tokens[2]; - } - if (standardFieldCount > 3) { - feature.cdStart = parseInt(tokens[3]); - } - if (standardFieldCount > 4) { - feature.cdEnd = parseInt(tokens[4]); - } - if (standardFieldCount > 5) { - if (tokens[5] !== "." && tokens[5] !== "0" && tokens[5] !== "-1") { - const c = IGVColor.createColorString(tokens[5]); - feature.color = c.startsWith("rgb") ? c : undefined; - } - } - if (standardFieldCount > 8) { - const exonCount = parseInt(tokens[6]); - const exonSizes = tokens[7].split(','); - const exonStarts = tokens[8].split(','); - const exons = []; - for (let i = 0; i < exonCount; i++) { - const eStart = feature.start + parseInt(exonStarts[i]); - const eEnd = eStart + parseInt(exonSizes[i]); - exons.push({start: eStart, end: eEnd}); - } - findUTRs(exons, feature.cdStart, feature.cdEnd); - feature.exons = exons; - } - - if (autoSql) { - // TODO -- these should be equal, validate? fieldCount-definedFieldCount, as.fields.length, tokens.length-3 - const extraStart = definedFieldCount; - for (let i = extraStart; i < fieldCount; i++) { - if (i < autoSql.fields.length) { - const name = autoSql.fields[i].name; - const value = tokens[i - 3]; - feature[name] = value; - } - } - } - } - } - - //table chromatinInteract - // "Chromatin interaction between two regions" - // ( - // string chrom; "Chromosome (or contig, scaffold, etc.). For interchromosomal, use 2 records" - // uint chromStart; "Start position of lower region. For interchromosomal, set to chromStart of this region" - // uint chromEnd; "End position of upper region. For interchromosomal, set to chromEnd of this region" - // string name; "Name of item, for display" - // uint score; "Score from 0-1000" - // double value; "Strength of interaction or other data value. Typically basis for score" - // string exp; "Experiment name (metadata for filtering). Use . if not applicable" - // string color; "Item color. Specified as r,g,b or hexadecimal #RRGGBB or html color name, as in //www.w3.org/TR/css3-color/#html4." - // string region1Chrom; "Chromosome of lower region. For non-directional interchromosomal, chrom of this region." - // uint region1Start; "Start position of lower/this region" - // uint region1End; "End position in chromosome of lower/this region" - // string region1Name; "Identifier of lower/this region" - // string region1Strand; "Orientation of lower/this region: + or -. Use . if not applicable" - // string region2Chrom; "Chromosome of upper region. For non-directional interchromosomal, chrom of other region" - // uint region2Start; "Start position in chromosome of upper/this region" - // uint region2End; "End position in chromosome of upper/this region" - // string region2Name; "Identifier of upper/this region" - // string region2Strand; "Orientation of upper/this region: + or -. Use . if not applicable" - // ) - function decodeInteract(feature, tokens) { - - feature.chr1 = tokens[5]; - feature.start1 = Number.parseInt(tokens[6]); - feature.end1 = Number.parseInt(tokens[7]); - - feature.chr2 = tokens[10]; - feature.start2 = Number.parseInt(tokens[11]); - feature.end2 = Number.parseInt(tokens[12]); - - feature.name = tokens[0]; - feature.score = Number(tokens[1]); - feature.value = Number(tokens[2]); - feature.color = tokens[4] === '.' ? undefined : tokens[4] === "0" ? "rgb(0,0,0)" : tokens[4]; - - return feature - } - } - - function findUTRs(exons, cdStart, cdEnd) { - - for (let exon of exons) { - const end = exon.end; - const start = exon.start; - if (end < cdStart || start > cdEnd) { - exon.utr = true; - } else { - if (cdStart >= start && cdStart <= end) { - exon.cdStart = cdStart; - } - if (cdEnd >= start && cdEnd <= end) { - exon.cdEnd = cdEnd; - } - } - } - } - - function scoreShade(score, color) { - const alpha = Math.min(1, 0.11 + 0.89 * (score / 779)); - return alpha.toString() - } - - function parseAutoSQL(str) { - - let table; - const fields = []; - let startDecoding = false; - const lines = str.trim().split(/\s*[\r\n]+\s*/g); - for (let line of lines) { - if (line.startsWith('table')) { - table = line.split(/\s+/)[1].trim(); - } else if (line.startsWith('(')) { - startDecoding = true; - } else if (line.startsWith(')')) ; else if (startDecoding) { - if (line.length > 0) { - const idx = line.indexOf(';'); - const tokens = line.substr(0, idx).split(/\s+/); - const description = line.substr(idx + 1).replace(/"/g, '').trim(); - fields.push({ - type: tokens[0], - name: tokens[1], - description: description - }); - } - } - } - return { - table: table, - fields: fields - } - } - - /* - * The MIT License (MIT) - * - * Copyright (c) 2014 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - let BIGWIG_MAGIC_LTH = 0x888FFC26; // BigWig Magic Low to High - let BIGWIG_MAGIC_HTL = 0x26FC8F66; // BigWig Magic High to Low - let BIGBED_MAGIC_LTH = 0x8789F2EB; // BigBed Magic Low to High - let BIGBED_MAGIC_HTL = 0xEBF28987; // BigBed Magic High to Low - let BBFILE_HEADER_SIZE = 64; - let RPTREE_HEADER_SIZE = 48; - let RPTREE_NODE_LEAF_ITEM_SIZE = 32; // leaf item size - let RPTREE_NODE_CHILD_ITEM_SIZE = 24; // child item size - let BUFFER_SIZE = 512000; // buffer - - class BWReader { - - constructor(config, genome) { - this.path = config.url; - this.format = config.format || "bigwig"; - this.genome = genome; - this.rpTreeCache = {}; - this.config = config; - this.loader = isDataURL(this.path) ? new DataBuffer(this.path) : igvxhr; - } - - async readWGFeatures(bpPerPixel, windowFunction) { - await this.loadHeader(); - const chrIdx1 = 0; - const chrIdx2 = this.chromTree.idToChrom.length - 1; - const chr1 = this.chromTree.idToChrom[chrIdx1]; - const chr2 = this.chromTree.idToChrom[chrIdx2]; - return this.readFeatures(chr1, 0, chr2, Number.MAX_VALUE, bpPerPixel, windowFunction) - } - - async readFeatures(chr1, bpStart, chr2, bpEnd, bpPerPixel, windowFunction) { - - await this.loadHeader(); - const chrIdx1 = this.chromTree.chromToID[chr1]; - const chrIdx2 = this.chromTree.chromToID[chr2]; - if (chrIdx1 === undefined || chrIdx2 === undefined) { - return [] - } - - let treeOffset; - let decodeFunction; - if (this.type === "bigwig") { - // Select a biwig "zoom level" appropriate for the current resolution. - const zoomLevelHeaders = await this.getZoomHeaders(); - let zoomLevelHeader = bpPerPixel ? zoomLevelForScale$1(bpPerPixel, zoomLevelHeaders) : undefined; - if (zoomLevelHeader) { - treeOffset = zoomLevelHeader.indexOffset; - decodeFunction = decodeZoomData; - } else { - treeOffset = this.header.fullIndexOffset; - decodeFunction = decodeWigData; - } - } else { - // bigbed, zoom data is not currently used in igv for bed type features - treeOffset = this.header.fullIndexOffset; - decodeFunction = getBedDataDecoder.call(this); - } - - - // Load the R Tree and fine leaf items - const rpTree = await this.loadRPTree(treeOffset); - const leafItems = await rpTree.findLeafItemsOverlapping(chrIdx1, bpStart, chrIdx2, bpEnd); - if (!leafItems || leafItems.length === 0) { - return [] - } else { - - // Consolidate leaf items and get all data at once - let start = Number.MAX_VALUE; - let end = 0; - for (let item of leafItems) { - start = Math.min(start, item.dataOffset); - end = Math.max(end, item.dataOffset + item.dataSize); - } - const size = end - start; - const arrayBuffer = await this.loader.loadArrayBuffer(this.config.url, buildOptions$1(this.config, { - range: { - start: start, - size: size - } - })); - - // Parse data and return features - const allFeatures = []; - for (let item of leafItems) { - const uint8Array = new Uint8Array(arrayBuffer, item.dataOffset - start, item.dataSize); - let plain; - const isCompressed = this.header.uncompressBuffSize > 0; - if (isCompressed) { - plain = inflate_1$3(uint8Array); - } else { - plain = uint8Array; - } - decodeFunction.call(this, new DataView(plain.buffer), chrIdx1, bpStart, chrIdx2, bpEnd, allFeatures, this.chromTree.idToChrom, windowFunction); - } - - allFeatures.sort(function (a, b) { - return a.start - b.start - }); - - return allFeatures - } - } - - async getZoomHeaders() { - if (this.zoomLevelHeaders) { - return this.zoomLevelHeaders - } else { - await this.loadHeader(); - return this.zoomLevelHeaders - } - } - - async loadHeader() { - - if (this.header) { - return this.header - } else { - let data = await this.loader.loadArrayBuffer(this.path, buildOptions$1(this.config, { - range: { - start: 0, - size: BBFILE_HEADER_SIZE - } - })); - - let header; - - // Assume low-to-high unless proven otherwise - this.littleEndian = true; - - let binaryParser = new BinaryParser$1(new DataView(data)); - let magic = binaryParser.getUInt(); - if (magic === BIGWIG_MAGIC_LTH) { - this.type = "bigwig"; - } else if (magic === BIGBED_MAGIC_LTH) { - this.type = "bigbed"; - } else { - //Try big endian order - this.littleEndian = false; - - binaryParser.littleEndian = false; - binaryParser.position = 0; - let magic = binaryParser.getUInt(); - - if (magic === BIGWIG_MAGIC_HTL) { - this.type = "bigwig"; - } else if (magic === BIGBED_MAGIC_HTL) { - this.type = "bigbed"; - } else ; - } - // Table 5 "Common header for bigwig and bigbed files" - header = { - bwVersion: binaryParser.getUShort(), - nZoomLevels: binaryParser.getUShort(), - chromTreeOffset: binaryParser.getLong(), - fullDataOffset: binaryParser.getLong(), - fullIndexOffset: binaryParser.getLong(), - fieldCount: binaryParser.getUShort(), - definedFieldCount: binaryParser.getUShort(), - autoSqlOffset: binaryParser.getLong(), - totalSummaryOffset: binaryParser.getLong(), - uncompressBuffSize: binaryParser.getInt(), - extensionOffset: binaryParser.getLong() - }; - - /////////// - - const startOffset = BBFILE_HEADER_SIZE; - let range = {start: startOffset, size: (header.fullDataOffset - startOffset + 5)}; - data = await this.loader.loadArrayBuffer(this.path, buildOptions$1(this.config, {range: range})); - - const nZooms = header.nZoomLevels; - binaryParser = new BinaryParser$1(new DataView(data)); - - this.zoomLevelHeaders = []; - this.firstZoomDataOffset = Number.MAX_SAFE_INTEGER; - for (let i = 1; i <= nZooms; i++) { - const zoomNumber = nZooms - i; - const zlh = new ZoomLevelHeader(zoomNumber, binaryParser); - this.firstZoomDataOffset = Math.min(zlh.dataOffset, this.firstZoomDataOffset); - this.zoomLevelHeaders[zoomNumber] = zlh; - } - - // Autosql - if (header.autoSqlOffset > 0) { - binaryParser.position = header.autoSqlOffset - startOffset; - const autoSqlString = binaryParser.getString(); - if (autoSqlString) { - this.autoSql = parseAutoSQL(autoSqlString); - } - } - - // Total summary - if (header.totalSummaryOffset > 0) { - binaryParser.position = header.totalSummaryOffset - startOffset; - this.totalSummary = new BWTotalSummary(binaryParser); - } - - // Chrom data index - if (header.chromTreeOffset > 0) { - binaryParser.position = header.chromTreeOffset - startOffset; - this.chromTree = new BPTree(binaryParser, startOffset, this.genome); - } else { - // TODO -- this is an error, not expected - throw "BigWig chromosome tree offset <= 0" - } - - //Finally total data count - binaryParser.position = header.fullDataOffset - startOffset; - header.dataCount = binaryParser.getInt(); - /////////// - - this.setDefaultVisibilityWindow(header); - - this.header = header; - return this.header - - } - } - - async loadRPTree(offset) { - - let rpTree = this.rpTreeCache[offset]; - if (rpTree) { - return rpTree - } else { - rpTree = new RPTree(offset, this.config, this.littleEndian, this.loader); - await rpTree.load(); - this.rpTreeCache[offset] = rpTree; - return rpTree - } - } - - async getType() { - await this.loadHeader(); - return this.type - } - - async getTrackType() { - await this.loadHeader(); - if (this.type === "bigwig") { - return "wig" - } else { - return this.autoSql && this.autoSql.table === "chromatinInteract" ? "interact" : "annotation" - } - } - - setDefaultVisibilityWindow(header) { - if (this.type === "bigwig") { - this.visibilityWindow = -1; - } else { - // bigbed - let genomeSize = this.genome ? this.genome.getGenomeLength() : 3088286401; - // Estimate window size to return ~ 1,000 features, assuming even distribution across the genome - this.visibilityWindow = header.dataCount < 1000 ? -1 : 1000 * (genomeSize / header.dataCount); - - } - } - } - - - class ZoomLevelHeader { - constructor(index, byteBuffer) { - this.index = index; - this.reductionLevel = byteBuffer.getInt(); - this.reserved = byteBuffer.getInt(); - this.dataOffset = byteBuffer.getLong(); - this.indexOffset = byteBuffer.getLong(); - } - } - - class RPTree { - - constructor(fileOffset, config, littleEndian, loader) { - - this.config = config; - this.loader = loader; - this.fileOffset = fileOffset; // File offset to beginning of tree - this.path = config.url; - this.littleEndian = littleEndian; - } - - async load() { - const rootNodeOffset = this.fileOffset + RPTREE_HEADER_SIZE; - const bufferedReader = isDataURL(this.path) ? - this.loader : - new BufferedReader(this.config, BUFFER_SIZE); - this.rootNode = await this.readNode(rootNodeOffset, bufferedReader); - return this - } - - async readNode(filePosition, bufferedReader) { - - let dataView = await bufferedReader.dataViewForRange({start: filePosition, size: 4}, false); - let binaryParser = new BinaryParser$1(dataView, this.littleEndian); - const type = binaryParser.getByte(); - const isLeaf = (type === 1); - binaryParser.getByte(); - const count = binaryParser.getUShort(); - filePosition += 4; - - let bytesRequired = count * (isLeaf ? RPTREE_NODE_LEAF_ITEM_SIZE : RPTREE_NODE_CHILD_ITEM_SIZE); - let range2 = {start: filePosition, size: bytesRequired}; - dataView = await bufferedReader.dataViewForRange(range2, false); - const items = new Array(count); - binaryParser = new BinaryParser$1(dataView); - - if (isLeaf) { - for (let i = 0; i < count; i++) { - let item = { - isLeaf: true, - startChrom: binaryParser.getInt(), - startBase: binaryParser.getInt(), - endChrom: binaryParser.getInt(), - endBase: binaryParser.getInt(), - dataOffset: binaryParser.getLong(), - dataSize: binaryParser.getLong() - }; - items[i] = item; - - } - return new RPTreeNode(items) - } else { // non-leaf - for (let i = 0; i < count; i++) { - - let item = { - isLeaf: false, - startChrom: binaryParser.getInt(), - startBase: binaryParser.getInt(), - endChrom: binaryParser.getInt(), - endBase: binaryParser.getInt(), - childOffset: binaryParser.getLong() - }; - items[i] = item; - } - - return new RPTreeNode(items) - } - - } - - async findLeafItemsOverlapping(chrIdx1, startBase, chrIdx2, endBase) { - - let self = this; - - return new Promise(function (fulfill, reject) { - - let leafItems = [], - processing = new Set(), - bufferedReader = isDataURL(self.path) ? - self.loader : - new BufferedReader(self.config, BUFFER_SIZE); - - processing.add(0); // Zero represents the root node - findLeafItems(self.rootNode, 0); - - function findLeafItems(node, nodeId) { - - if (overlaps(node, chrIdx1, startBase, chrIdx2, endBase)) { - - let items = node.items; - - items.forEach(function (item) { - - if (overlaps(item, chrIdx1, startBase, chrIdx2, endBase)) { - - if (item.isLeaf) { - leafItems.push(item); - } else { - if (item.childNode) { - findLeafItems(item.childNode); - } else { - processing.add(item.childOffset); // Represent node to-be-loaded by its file position - - self.readNode(item.childOffset, bufferedReader) - .then(function (node) { - item.childNode = node; - findLeafItems(node, item.childOffset); - }) - .catch(reject); - } - } - } - }); - - } - - if (nodeId !== undefined) processing.delete(nodeId); - - // Wait until all nodes are processed - if (processing.size === 0) { - fulfill(leafItems); - } - } - }) - } - } - - class RPTreeNode { - - constructor(items) { - - this.items = items; - - let minChromId = Number.MAX_SAFE_INTEGER, - maxChromId = 0, - minStartBase = Number.MAX_SAFE_INTEGER, - maxEndBase = 0, - i, - item; - - for (i = 0; i < items.length; i++) { - item = items[i]; - minChromId = Math.min(minChromId, item.startChrom); - maxChromId = Math.max(maxChromId, item.endChrom); - minStartBase = Math.min(minStartBase, item.startBase); - maxEndBase = Math.max(maxEndBase, item.endBase); - } - - this.startChrom = minChromId; - this.endChrom = maxChromId; - this.startBase = minStartBase; - this.endBase = maxEndBase; - } - } - - class BPTree { - - constructor(binaryParser, startOffset, genome) { - - let magic = binaryParser.getInt(); - let blockSize = binaryParser.getInt(); - let keySize = binaryParser.getInt(); - let valSize = binaryParser.getInt(); - let itemCount = binaryParser.getLong(); - let reserved = binaryParser.getLong(); - let chromToId = {}; - let idToChrom = []; - - this.header = { - magic: magic, - blockSize: blockSize, - keySize: keySize, - valSize: valSize, - itemCount: itemCount, - reserved: reserved - }; - this.chromToID = chromToId; - this.idToChrom = idToChrom; - - // Recursively walk tree to populate dictionary - readTreeNode(binaryParser, -1); - - - function readTreeNode(byteBuffer, offset) { - - if (offset >= 0) byteBuffer.position = offset; - - let type = byteBuffer.getByte(); - byteBuffer.getByte(); - let count = byteBuffer.getUShort(), - i, - key, - chromId, - childOffset, - bufferOffset, - currOffset; - - - if (type === 1) { - - for (i = 0; i < count; i++) { - - key = byteBuffer.getFixedLengthTrimmedString(keySize); - chromId = byteBuffer.getInt(); - byteBuffer.getInt(); - - if (genome) key = genome.getChromosomeName(key); // Translate to canonical chr name - chromToId[key] = chromId; - idToChrom[chromId] = key; - - } - } else { // non-leaf - - for (i = 0; i < count; i++) { - - key = byteBuffer.getFixedLengthTrimmedString(keySize); - childOffset = byteBuffer.getLong(); - bufferOffset = childOffset - startOffset; - currOffset = byteBuffer.position; - readTreeNode(byteBuffer, bufferOffset); - byteBuffer.position = currOffset; - } - } - - } - } - } - - /** - * Return true if {chrIdx1:startBase-chrIdx2:endBase} overlaps item's interval - * @returns {boolean} - */ - function overlaps(item, chrIdx1, startBase, chrIdx2, endBase) { - - if (!item) { - console.log("null item for " + chrIdx1 + " " + startBase + " " + endBase); - return false - } - - return ((chrIdx2 > item.startChrom) || (chrIdx2 === item.startChrom && endBase >= item.startBase)) && - ((chrIdx1 < item.endChrom) || (chrIdx1 === item.endChrom && startBase <= item.endBase)) - - - } - - class BWTotalSummary { - - constructor(byteBuffer) { - if (byteBuffer) { - this.basesCovered = byteBuffer.getLong(); - this.minVal = byteBuffer.getDouble(); - this.maxVal = byteBuffer.getDouble(); - this.sumData = byteBuffer.getDouble(); - this.sumSquares = byteBuffer.getDouble(); - computeStats.call(this); - } else { - this.basesCovered = 0; - this.minVal = 0; - this.maxVal = 0; - this.sumData = 0; - this.sumSquares = 0; - this.mean = 0; - this.stddev = 0; - } - } - } - - function computeStats() { - let n = this.basesCovered; - if (n > 0) { - this.mean = this.sumData / n; - this.stddev = Math.sqrt(this.sumSquares / (n - 1)); - - let min = this.minVal < 0 ? this.mean - 2 * this.stddev : 0, - max = this.maxVal > 0 ? this.mean + 2 * this.stddev : 0; - - this.defaultRange = { - min: min, - max: max - }; - } - } - - function zoomLevelForScale$1(bpPerPixel, zoomLevelHeaders) { - let level; - for (let i = 0; i < zoomLevelHeaders.length; i++) { - const zl = zoomLevelHeaders[i]; - if (zl.reductionLevel < bpPerPixel) { - level = zl; - break - } - } - return level - } - - - function decodeWigData(data, chrIdx1, bpStart, chrIdx2, bpEnd, featureArray, chrDict) { - - const binaryParser = new BinaryParser$1(data); - const chromId = binaryParser.getInt(); - const blockStart = binaryParser.getInt(); - let chromStart = blockStart; - let chromEnd = binaryParser.getInt(); - const itemStep = binaryParser.getInt(); - const itemSpan = binaryParser.getInt(); - const type = binaryParser.getByte(); - binaryParser.getByte(); - let itemCount = binaryParser.getUShort(); - - if (chromId >= chrIdx1 && chromId <= chrIdx2) { - - let idx = 0; - while (itemCount-- > 0) { - let value; - switch (type) { - case 1: - chromStart = binaryParser.getInt(); - chromEnd = binaryParser.getInt(); - value = binaryParser.getFloat(); - break - case 2: - chromStart = binaryParser.getInt(); - value = binaryParser.getFloat(); - chromEnd = chromStart + itemSpan; - break - case 3: // Fixed step - value = binaryParser.getFloat(); - chromStart = blockStart + idx * itemStep; - chromEnd = chromStart + itemSpan; - idx++; - break - } - - if (chromId < chrIdx1 || (chromId === chrIdx1 && chromEnd < bpStart)) continue - else if (chromId > chrIdx2 || (chromId === chrIdx2 && chromStart >= bpEnd)) break - - if (Number.isFinite(value)) { - const chr = chrDict[chromId]; - featureArray.push({chr: chr, start: chromStart, end: chromEnd, value: value}); - } - - } - } - } - - function getBedDataDecoder() { - - const minSize = 3 * 4 + 1; // Minimum # of bytes required for a bed record - const decoder = getDecoder(this.header.definedFieldCount, this.header.fieldCount, this.autoSql, this.format); - return function (data, chrIdx1, bpStart, chrIdx2, bpEnd, featureArray, chrDict) { - const binaryParser = new BinaryParser$1(data); - while (binaryParser.remLength() >= minSize) { - - const chromId = binaryParser.getInt(); - const chr = chrDict[chromId]; - const chromStart = binaryParser.getInt(); - const chromEnd = binaryParser.getInt(); - const rest = binaryParser.getString(); - if (chromId < chrIdx1 || (chromId === chrIdx1 && chromEnd < bpStart)) continue - else if (chromId > chrIdx2 || (chromId === chrIdx2 && chromStart >= bpEnd)) break - - if (chromEnd > 0) { - const feature = {chr: chr, start: chromStart, end: chromEnd}; - featureArray.push(feature); - const tokens = rest.split("\t"); - decoder(feature, tokens); - } - } - } - } - - - function decodeZoomData(data, chrIdx1, bpStart, chrIdx2, bpEnd, featureArray, chrDict, windowFunction) { - - const binaryParser = new BinaryParser$1(data); - const minSize = 8 * 4; // Minimum # of bytes required for a zoom record - - - while (binaryParser.remLength() >= minSize) { - const chromId = binaryParser.getInt(); - const chr = chrDict[chromId]; - const chromStart = binaryParser.getInt(); - const chromEnd = binaryParser.getInt(); - const validCount = binaryParser.getInt(); - const minVal = binaryParser.getFloat(); - const maxVal = binaryParser.getFloat(); - const sumData = binaryParser.getFloat(); - binaryParser.getFloat(); - let value; - switch (windowFunction) { - case "min": - value = minVal; - break - case "max": - value = maxVal; - break - default: - value = validCount === 0 ? 0 : sumData / validCount; - } - - if (chromId < chrIdx1 || (chromId === chrIdx1 && chromEnd < bpStart)) continue - else if (chromId > chrIdx2 || (chromId === chrIdx2 && chromStart >= bpEnd)) break - - - if (Number.isFinite(value)) { - featureArray.push({chr: chr, start: chromStart, end: chromEnd, value: value}); - - - } - } - } - - class DataBuffer { - - constructor(dataURI) { - this.data = decodeDataURI$1(dataURI).buffer; - } - - /** - * igvxhr interface - * @param ignore - * @param options - * @returns {any} - */ - loadArrayBuffer(ignore, options) { - const range = options.range; - return range ? this.data.slice(range.start, range.start + range.size) : this.data - } - - /** - * BufferedReader interface - * - * @param requestedRange - byte rangeas {start, size} - * @param fulfill - function to receive result - * @param asUint8 - optional flag to return result as an UInt8Array - */ - async dataViewForRange(requestedRange, asUint8) { - const len = Math.min(this.data.byteLength - requestedRange.start, requestedRange.size); - return asUint8 ? - new Uint8Array(this.data, requestedRange.start, len) : - new DataView(this.data, requestedRange.start, len) - } - } - - /* - * The MIT License (MIT) - * - * Copyright (c) 2014 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - class BWSource { - - constructor(config, genome) { - this.reader = new BWReader(config, genome); - this.genome = genome; - this.format = config.format || "bigwig"; - this.wgValues = {}; - this.queryable = true; - } - - async getFeatures({chr, start, end, bpPerPixel, windowFunction}) { - - const isBigWig = this.reader.type === "bigwig"; - - const features = (chr.toLowerCase() === "all") ? - (isBigWig ? await this.getWGValues(windowFunction) : []) : - await this.reader.readFeatures(chr, start, chr, end, bpPerPixel, windowFunction); - - if (!isBigWig) { - pack(features); - } - return features - } - - async getHeader() { - return this.reader.loadHeader() - } - - getDefaultRange() { - if (this.reader.totalSummary !== undefined) { - return this.reader.totalSummary.defaultRange - } else { - return undefined - } - } - - async defaultVisibilityWindow() { - return this.reader.defaultVisibilityWindow - } - - async getWGValues(windowFunction) { - - const nominalScreenWidth = 1000; // This doesn't need to be precise - const genome = this.genome; - - if (this.wgValues[windowFunction]) { - return this.wgValues[windowFunction] - } else { - - const bpPerPixel = genome.getGenomeLength() / nominalScreenWidth; - const features = await this.reader.readWGFeatures(bpPerPixel, windowFunction); - let wgValues = []; - for (let f of features) { - const chr = f.chr; - const offset = genome.getCumulativeOffset(chr); - const wgFeature = Object.assign({}, f); - wgFeature.chr = "all"; - wgFeature.start = offset + f.start; - wgFeature.end = offset + f.end; - wgValues.push(wgFeature); - } - this.wgValues[windowFunction] = wgValues; - return wgValues - } - } - - supportsWholeGenome() { - return this.reader.type === "bigwig" - } - - async trackType() { - return this.reader.getTrackType() - } - } - - /* - * The MIT License (MIT) - * - * Copyright (c) 2016 University of California San Diego - * Author: Jim Robinson - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - const GZIP_FLAG = 0x1; - - class TDFReader { - - constructor(config, genome) { - this.config = config; - this.genome = genome; - this.path = config.url; - this.groupCache = {}; - this.datasetCache = {}; - } - - - async readHeader() { - - if (this.magic !== undefined) { - return this // Already read - } - - let data = await igvxhr.loadArrayBuffer(this.path, buildOptions$1(this.config, {range: {start: 0, size: 64000}})); - let binaryParser = new BinaryParser$1(new DataView(data)); - this.magic = binaryParser.getInt(); - this.version = binaryParser.getInt(); - this.indexPos = binaryParser.getLong(); - this.indexSize = binaryParser.getInt(); - binaryParser.getInt(); - - - if (this.version >= 2) { - let nWindowFunctions = binaryParser.getInt(); - this.windowFunctions = []; - while (nWindowFunctions-- > 0) { - this.windowFunctions.push(binaryParser.getString()); - } - } - - this.trackType = binaryParser.getString(); - this.trackLine = binaryParser.getString(); - - let nTracks = binaryParser.getInt(); - this.trackNames = []; - while (nTracks-- > 0) { - this.trackNames.push(binaryParser.getString()); - } - this.genomeID = binaryParser.getString(); - this.flags = binaryParser.getInt(); - this.compressed = (this.flags & GZIP_FLAG) !== 0; - - // Now read index - data = await igvxhr.loadArrayBuffer(this.path, buildOptions$1(this.config, { - range: { - start: this.indexPos, - size: this.indexSize - } - })); - binaryParser = new BinaryParser$1(new DataView(data)); - this.datasetIndex = {}; - let nEntries = binaryParser.getInt(); - while (nEntries-- > 0) { - const name = binaryParser.getString(); - const pos = binaryParser.getLong(); - const size = binaryParser.getInt(); - this.datasetIndex[name] = {position: pos, size: size}; - } - - this.groupIndex = {}; - nEntries = binaryParser.getInt(); - while (nEntries-- > 0) { - const name = binaryParser.getString(); - const pos = binaryParser.getLong(); - const size = binaryParser.getInt(); - this.groupIndex[name] = {position: pos, size: size}; - } - - return this - } - - async readDataset(chr, windowFunction, zoom) { - - const key = chr + "_" + windowFunction + "_" + zoom; - - if (this.datasetCache[key]) { - return this.datasetCache[key] - - } else { - await this.readHeader(); - const wf = (this.version < 2) ? "" : "/" + windowFunction; - const zoomString = (chr.toLowerCase() === "all" || zoom === undefined) ? "0" : zoom.toString(); - - let dsName; - if (windowFunction === "raw") { - dsName = "/" + chr + "/raw"; - } else { - dsName = "/" + chr + "/z" + zoomString + wf; - } - const indexEntry = this.datasetIndex[dsName]; - - if (indexEntry === undefined) { - return undefined - } - - const data = await igvxhr.loadArrayBuffer(this.path, buildOptions$1(this.config, { - range: { - start: indexEntry.position, - size: indexEntry.size - } - })); - - if (!data) { - return undefined - } - - const binaryParser = new BinaryParser$1(new DataView(data)); - let nAttributes = binaryParser.getInt(); - const attributes = {}; - while (nAttributes-- > 0) { - attributes[binaryParser.getString()] = binaryParser.getString(); - } - const dataType = binaryParser.getString(); - const tileWidth = binaryParser.getFloat(); - let nTiles = binaryParser.getInt(); - const tiles = []; - while (nTiles-- > 0) { - tiles.push({position: binaryParser.getLong(), size: binaryParser.getInt()}); - } - - const dataset = { - name: dsName, - attributes: attributes, - dataType: dataType, - tileWidth: tileWidth, - tiles: tiles - }; - - this.datasetCache[key] = dataset; - return dataset - } - } - - async readRootGroup() { - - const genome = this.genome; - const rootGroup = this.groupCache["/"]; - if (rootGroup) { - return rootGroup - } else { - - const group = await this.readGroup("/"); - const names = group["chromosomes"]; - const maxZoomString = group["maxZoom"]; - - // Now parse out interesting attributes. - if (maxZoomString) { - this.maxZoom = Number(maxZoomString); - } - - const totalCountString = group["totalCount"]; - if (totalCountString) { - group.totalCount = Number(totalCountString); - } - - // Chromosome names - const chrAliasTable = {}; - if (names) { - names.split(",").forEach(function (chr) { - const canonicalName = genome.getChromosomeName(chr); - chrAliasTable[canonicalName] = chr; - }); - } - this.chrAliasTable = chrAliasTable; - - this.groupCache["/"] = group; - return group - } - } - - async readGroup(name) { - - const group = this.groupCache[name]; - if (group) { - return group - } else { - - await this.readHeader(); - const indexEntry = this.groupIndex[name]; - if (indexEntry === undefined) { - return undefined - } - - const data = await igvxhr.loadArrayBuffer(this.path, buildOptions$1(this.config, { - range: { - start: indexEntry.position, - size: indexEntry.size - } - })); - - if (!data) { - return undefined - } - - const binaryParser = new BinaryParser$1(new DataView(data)); - const group = {name: name}; - let nAttributes = binaryParser.getInt(); - while (nAttributes-- > 0) { - const key = binaryParser.getString(); - const value = binaryParser.getString(); - group[key] = value; - } - this.groupCache[name] = group; - return group - } - } - - - async readTiles(tileIndeces, nTracks) { - - tileIndeces.sort(function (a, b) { - return a.position - b.position - }); - - tileIndeces = tileIndeces.filter(function (idx) { - return idx.size > 0 - }); - - if (tileIndeces.length === 0) { - return Promise.resolve([]) - } - - const firstEntry = tileIndeces[0]; - const lastEntry = tileIndeces[tileIndeces.length - 1]; - const position = firstEntry.position; - const size = (lastEntry.position + lastEntry.size) - position; - const data = await igvxhr.loadArrayBuffer(this.path, buildOptions$1(this.config, { - range: { - start: position, - size: size - } - })); - - const tiles = []; - - // Loop through and decode tiles - for (let indexEntry of tileIndeces) { - const start = indexEntry.position - position; - const size = indexEntry.size; - if (size > 0) { - let tileData; - if (this.compressed) { - const plain = inflate_1$3(data.slice(start, start + size)); - tileData = plain.buffer; - } else { - tileData = data.slice(start, start + size); - } - - const binaryParser = new BinaryParser$1(new DataView(tileData)); - const type = binaryParser.getString(); - let tile; - switch (type) { - case "fixedStep": - tile = createFixedStep(binaryParser, nTracks); - break - case "variableStep": - tile = createVariableStep(binaryParser, nTracks); - break - case "bed": - case "bedWithName": - tile = createBed(binaryParser, nTracks, type); - break - default: - throw "Unknown tile type: " + type - } - tiles.push(tile); - } - } - return tiles - } - - async readTile(indexEntry, nTracks) { - - let data = await igvxhr.loadArrayBuffer(this.path, buildOptions$1(this.config, { - range: { - start: indexEntry.position, - size: indexEntry.size - } - })); - - if (this.compressed) { - const plain = inflate_1$3(data); - data = plain.buffer; - } - - const binaryParser = new BinaryParser$1(new DataView(data)); - const type = binaryParser.getString(); - switch (type) { - case "fixedStep": - return createFixedStep(binaryParser, nTracks) - case "variableStep": - return createVariableStep(binaryParser, nTracks) - case "bed": - case "bedWithName": - return createBed(binaryParser, nTracks, type) - default: - throw "Unknown tile type: " + type - } - } - - } - - function createFixedStep(binaryParser, nTracks) { - const nPositions = binaryParser.getInt(); - const start = binaryParser.getInt(); - const span = binaryParser.getFloat(); - - const data = []; - let nt = nTracks; - while (nt-- > 0) { - let np = nPositions; - const dtrack = []; - while (np-- > 0) { - dtrack.push(binaryParser.getFloat()); - } - data.push(dtrack); - } - - return { - type: "fixedStep", - start: start, - span: span, - data: data, - nTracks: nTracks, - nPositions: nPositions - } - } - - function createVariableStep(binaryParser, nTracks) { - - const tileStart = binaryParser.getInt(); - const span = binaryParser.getFloat(); - const nPositions = binaryParser.getInt(); - const start = []; - - let np = nPositions; - while (np-- > 0) { - start.push(binaryParser.getInt()); - } - binaryParser.getInt(); // # of samples, ignored but should === nTracks - - const data = []; - let nt = nTracks; - while (nt-- > 0) { - np = nPositions; - const dtrack = []; - while (np-- > 0) { - dtrack.push(binaryParser.getFloat()); - } - data.push(dtrack); - } - - return { - type: "variableStep", - tileStart: tileStart, - span: span, - start: start, - data: data, - nTracks: nTracks, - nPositions: nPositions - } - } - - function createBed(binaryParser, nTracks, type) { - - const nPositions = binaryParser.getInt(); - - let n = nPositions; - const start = []; - while (n-- > 0) { - start.push(binaryParser.getInt()); - } - - n = nPositions; - const end = []; - while (n-- > 0) { - end.push(binaryParser.getInt()); - } - - binaryParser.getInt(); // # of samples, ignored but should === nTracks - const data = []; - let nt = nTracks; - while (nt-- > 0) { - let np = nPositions; - const dtrack = []; - while (np-- > 0) { - dtrack.push(binaryParser.getFloat()); - } - data.push(dtrack); - } - - if (type === "bedWithName") { - n = nPositions; - const name = []; - while (n-- > 0) { - name.push(binaryParser.getString()); - } - } - - return { - type: type, - start: start, - end: end, - data: data, - nTracks: nTracks, - nPositions: nPositions - } - - } - - /* - * The MIT License (MIT) - * - * Copyright (c) 2016 University of California San Diego - * Author: Jim Robinson - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - class TDFSource { - - constructor(config, genome) { - this.genome = genome; - this.windowFunction = config.windowFunction || "mean"; - this.reader = new TDFReader(config, genome); - this.queryable = true; - } - - async getFeatures({chr, start, end, bpPerPixel}) { - - if (chr.toLowerCase() === "all") { - const wgFeatures = []; - const genome = this.genome; - const chrNames = this.genome.wgChromosomeNames; - if (chrNames) { - for (let c of genome.wgChromosomeNames) { - const len = genome.getChromosome(c).bpLength; - bpPerPixel = len / 1000; - const chrFeatures = await this._getFeatures(c, 0, len, bpPerPixel); - if (chrFeatures) { - for (let f of chrFeatures) { - const wg = Object.assign({}, f); - wg.chr = "all"; - wg.start = genome.getGenomeCoordinate(f.chr, f.start); - wg.end = genome.getGenomeCoordinate(f.chr, f.end); - wg._f = f; - wgFeatures.push(wg); - } - } - } - } - return wgFeatures - - } else { - return this._getFeatures(chr, start, end, bpPerPixel) - } - } - - async _getFeatures(chr, start, end, bpPerPixel) { - const genomicInterval = new GenomicInterval(chr, start, end); - const genome = this.genome; - - - if (!this.rootGroup) { - this.rootGroup = await this.reader.readRootGroup(); - if (!this.normalizationFactor) { - const totalCount = this.rootGroup.totalCount; - if (totalCount) { - this.normalizationFactor = 1.0e6 / totalCount; - } - } - } - - genomicInterval.bpPerPixel = bpPerPixel; - const zoom = zoomLevelForScale(chr, bpPerPixel, genome); - let queryChr = this.reader.chrAliasTable[chr]; - let maxZoom = this.reader.maxZoom; - if (queryChr === undefined) queryChr = chr; - if (maxZoom === undefined) maxZoom = -1; - - const wf = zoom > maxZoom ? "raw" : this.windowFunction; - const dataset = await this.reader.readDataset(queryChr, wf, zoom); - if (dataset == null) { - return [] - } - - const tileWidth = dataset.tileWidth; - const startTile = Math.floor(start / tileWidth); - const endTile = Math.floor(end / tileWidth); - const NTRACKS = 1; // TODO read this - const tiles = await this.reader.readTiles(dataset.tiles.slice(startTile, endTile + 1), NTRACKS); - const features = []; - for (let tile of tiles) { - switch (tile.type) { - case "bed": - decodeBedTile(tile, chr, start, end, bpPerPixel, features); - break - case "variableStep": - decodeVaryTile(tile, chr, start, end, bpPerPixel, features); - break - case "fixedStep": - decodeFixedTile(tile, chr, start, end, bpPerPixel, features); - break - default: - throw ("Unknown tile type: " + tile.type) - } - } - features.sort(function (a, b) { - return a.start - b.start - }); - - return features - } - - get supportsWholeGenome() { - return true - } - } - - function decodeBedTile(tile, chr, bpStart, bpEnd, bpPerPixel, features) { - - const nPositions = tile.nPositions; - const starts = tile.start; - const ends = tile.end; - const data = tile.data[0]; // Single track for now - for (let i = 0; i < nPositions; i++) { - const s = starts[i]; - const e = ends[i]; - if (e < bpStart) continue - if (s > bpEnd) break - features.push({ - chr: chr, - start: s, - end: e, - value: data[i] - }); - } - } - - function decodeVaryTile(tile, chr, bpStart, bpEnd, bpPerPixel, features) { - - const nPositions = tile.nPositions; - const starts = tile.start; - const span = tile.span; - const data = tile.data[0]; // Single track for now - for (let i = 0; i < nPositions; i++) { - const s = starts[i]; - const e = s + span; - if (e < bpStart) continue - if (s > bpEnd) break - features.push({ - chr: chr, - start: s, - end: e, - value: data[i] - }); - } - } - - function decodeFixedTile(tile, chr, bpStart, bpEnd, bpPerPixel, features) { - - const nPositions = tile.nPositions; - let s = tile.start; - const span = tile.span; - const data = tile.data[0]; // Single track for now - - for (let i = 0; i < nPositions; i++) { - const e = s + span; - if (s > bpEnd) break - if (e >= bpStart) { - if (!Number.isNaN(data[i])) { - features.push({ - chr: chr, - start: s, - end: e, - value: data[i] - }); - } - } - s = e; - } - } - - - var log2 = Math.log(2); - - function zoomLevelForScale(chr, bpPerPixel, genome) { - - // Convert bpPerPixel to IGV "zoom" level. This is a bit convoluted, IGV computes zoom levels assuming - // display in a 700 pixel window. The fully zoomed out view of a chromosome is zoom level "0". - // Zoom level 1 is magnified 2X, and so forth - - var chrSize = genome.getChromosome(chr).bpLength; - - return Math.ceil(Math.log(Math.max(0, (chrSize / (bpPerPixel * 700)))) / log2) - } - - /* - * The MIT License (MIT) - * - * Copyright (c) 2014-2015 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - /** - * feature source for features supplied directly, as opposed to reading and parsing from a file or webservice - * - * @param config - * @constructor - */ - class StaticFeatureSource { - - constructor(config, genome) { - - this.config = config; - this.genome = genome; - this.queryable = false; - this.searchable = config.searchable !== false; // searchable by default - this.updateFeatures(config.features); - } - - updateFeatures(features) { - features = fixFeatures(features, this.genome); - packFeatures(features); - if (this.config.mappings) { - mapProperties(features, this.config.mappings); - } - this.featureCache = new FeatureCache$1(features, this.genome); - - if (this.searchable || this.config.searchableFields) { - this.genome.addFeaturesToDB(features, this.config); - } - } - - /** - * Required function for all data source objects. Fetches features for the - * range requested. - * - * This function is complex due to the variety of reader types backing it, some indexed, some queryable, - * some not. - * - * @param chr - * @param start - * @param end - * @param bpPerPixel - */ - async getFeatures({chr, start, end, bpPerPixel, visibilityWindow}) { - - const genome = this.genome; - const queryChr = genome ? genome.getChromosomeName(chr) : chr; - const isWholeGenome = ("all" === queryChr.toLowerCase()); - - // Various conditions that can require a feature load - // * view is "whole genome" but no features are loaded - // * cache is disabled - // * cache does not contain requested range - if (isWholeGenome) { - return computeWGFeatures(this.featureCache.getAllFeatures(), this.genome, this.maxWGCount) - } else { - return this.featureCache.queryFeatures(queryChr, start, end) - } - } - - // - // supportsWholeGenome() { - // return true - // } - - getAllFeatures() { - return this.featureCache.getAllFeatures() - } - - supportsWholeGenome() { - return true - } - - - } - - - /** - * This function is used to apply properties normally added during parsing to features supplied directly in the - * config as an array of objects. At the moment the only application is bedpe type features. - * @param features - */ - function fixFeatures(features, genome) { - - if (genome) { - for (let feature of features) { - feature.chr = genome.getChromosomeName(feature.chr); - } - } - - return features - } - - - - function mapProperties(features, mappings) { - let mappingKeys = Object.keys(mappings); - features.forEach(function (f) { - mappingKeys.forEach(function (key) { - f[key] = f[mappings[key]]; - }); - }); - } - - /* - * The MIT License (MIT) - * - * Copyright (c) 2014-2015 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - const bbFormats = new Set(['bigwig', 'bw', 'bigbed', 'bb', 'biginteract', 'biggenepred', 'bignarrowpeak']); - - function FeatureSource(config, genome) { - - const format = config.format ? config.format.toLowerCase() : undefined; - - if (config.features) { - return new StaticFeatureSource(config, genome) - } else if (bbFormats.has(format)) { - return new BWSource(config, genome) - } else if ("tdf" === format) { - return new TDFSource(config, genome) - } else { - return new TextFeatureSource(config, genome) - } - } - - const appleCrayonColorName = 'nickel'; - - const ROI_DEFAULT_ALPHA = 2 / 16; - - const ROI_DEFAULT_COLOR = appleCrayonRGBA(appleCrayonColorName, ROI_DEFAULT_ALPHA); - const ROI_DEFAULT_HEADER_COLOR = 'rgb(190,190,190)'; - - const ROI_USER_HEADER_DEFINED_COLOR = 'rgba(155,185,129)'; - const ROI_USER_DEFINED_COLOR = ROI_DEFAULT_COLOR; - - class ROISet { - - constructor(config, genome) { - - this.url = config.url; - - if (config.name) { - this.name = config.name; - } else if (config.url && isFile$1(config.url)) { - this.name = config.url.name; - } else if (config.url && isString$2(config.url) && !config.url.startsWith("data:")) { - this.name = getFilename$2(config.url); - } - - this.isUserDefined = config.isUserDefined; - - if (config.features) { - this.featureSource = new DynamicFeatureSource(config.features, genome); - } else { - if (config.format) { - config.format = config.format.toLowerCase(); - } else { - const filename = getFilename$2(config.url); - config.format = inferFileFormat(filename); - } - this.featureSource = config.featureSource || FeatureSource(config, genome); - } - - if (true === this.isUserDefined) { - this.color = config.color || ROI_USER_DEFINED_COLOR; - this.headerColor = ROI_USER_HEADER_DEFINED_COLOR; - - } else { - - this.color = config.color || ROI_DEFAULT_COLOR; - this.headerColor = ROI_DEFAULT_HEADER_COLOR; - - // Use body color with alpha pinned to 1 - // const [ r, g, b, discard ] = rgbaStringTokens(this.color) - // this.headerColor = `rgba(${ r },${ g },${ b },${ 1.0 })` - - } - } - - async getFeatures(chr, start, end) { - return this.featureSource.getFeatures({chr, start, end}) - } - - async getAllFeatures() { - return typeof this.featureSource.getAllFeatures === 'function' ? await this.featureSource.getAllFeatures() : {} - } - - addFeature(feature) { - if (this.isUserDefined) { - this.featureSource.addFeature(feature); - } else { - console.error("Attempt to add ROI to non user-defined set"); - } - } - - removeFeature(feature) { - if (this.isUserDefined) { - this.featureSource.removeFeature(feature); - } else { - console.error("Attempt to remove ROI from non user-defined set"); - } - } - - toJSON() { - if (this.url) { - return {name: this.name, color: this.color, url: this.url, isUserDefined: this.isUserDefined} - } else { - const featureMap = this.featureSource.getAllFeatures(); - const features = []; - for (let chr of Object.keys(featureMap)) { - for (let f of featureMap[chr]) { - features.push(f); - } - } - return {name: this.name, color: this.color, features: features, isUserDefined: this.isUserDefined} - } - } - - dispose() { - for (let key of Object.keys(this)) { - this[key] = undefined; - } - } - - } - - const SCREEN_COORDS_WIDTH_THRESHOLD = 3; - - function screenCoordinates(regionStartBP, regionEndBP, bpStart, bpp) { - - let xStart = Math.round((regionStartBP - bpStart) / bpp); - const xEnd = Math.round((regionEndBP - bpStart) / bpp); - - let width = xEnd - xStart; - - if (width < SCREEN_COORDS_WIDTH_THRESHOLD) { - width = SCREEN_COORDS_WIDTH_THRESHOLD; - xStart -= 1; - } - - return {x: xStart, width} - } - - - /** - * Special feature source that allows addition of features dynamically - */ - class DynamicFeatureSource { - - constructor(features, genome) { - this.featureMap = {}; - this.genome = genome; - - for (let feature of features) { - - // Store as canonical chr name (i.e. translate aliases) - const chrKey = genome ? genome.getChromosomeName(feature.chr) : feature.chr; - - let featureList = this.featureMap[chrKey]; - if (!featureList) { - featureList = []; - this.featureMap[chrKey] = featureList; - } - featureList.push(feature); - } - - for (let key of Object.keys(this.featureMap)) { - this.featureMap[key].sort((a, b) => a.start - b.start); - } - } - - getFeatures({chr, start, end}) { - if (chr.toLowerCase() === 'all') { - return computeWGFeatures(this.featureMap, this.genome) - } else { - // TODO -- this use of filter is O(N), and might not scale well for large feature lists. - const featureList = this.featureMap[chr]; - return featureList ? featureList.filter(feature => feature.end > start && feature.start < end) : [] - } - } - - getAllFeatures() { - return this.featureMap - } - - supportsWholeGenome() { - return true - } - - addFeature(feature) { - let featureList = this.featureMap[feature.chr]; - if (!featureList) { - featureList = []; - this.featureMap[feature.chr] = featureList; - } - featureList.push(feature); - featureList.sort((a, b) => a.start - b.start); - } - - removeFeature({chr, start, end}) { - - if (this.featureMap[chr]) { - const match = `${chr}-${start}-${end}`; - this.featureMap[chr] = this.featureMap[chr].filter(feature => match !== `${feature.chr}-${feature.start}-${feature.end}`); - } - } - } - - /* - * The MIT License (MIT) - * - * Copyright (c) 2016-2017 The Regents of the University of California - * Author: Jim Robinson - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - const RULER_SWEEPER_COLOR = 'rgba(68, 134, 247, 0.25)'; - - class RulerSweeper { - - constructor(rulerViewport, column, browser, referenceFrame) { - - this.rulerViewport = rulerViewport; - - this.rulerSweeper = domUtils$1.div({class: 'igv-ruler-sweeper'}); - column.appendChild(this.rulerSweeper); - - this.browser = browser; - this.referenceFrame = referenceFrame; - - this.isMouseHandlers = undefined; - - this.addBrowserObserver(); - } - - addBrowserObserver() { - - const observerHandler = () => { - if (this.referenceFrame) { - GenomeUtils.isWholeGenomeView(this.referenceFrame.chr) ? this.removeMouseHandlers() : this.addMouseHandlers(); - } - }; - - // Viewport Content - this.boundObserverHandler = observerHandler.bind(this); - this.browser.on('locuschange', this.boundObserverHandler); - - } - - removeBrowserObserver() { - this.browser.off('locuschange', this.boundObserverHandler); - } - - addMouseHandlers() { - - if (true === this.isMouseHandlers) { - return - } - - const threshold = 1; - - let isMouseDown; - let isMouseIn; - let mouseDownX; - let left; - let width; - let dx; - - // Viewport Content - this.boundContentMouseDownHandler = contentMouseDownHandler.bind(this); - this.rulerViewport.contentDiv.addEventListener('mousedown', this.boundContentMouseDownHandler); - - function contentMouseDownHandler(event) { - - isMouseDown = true; - isMouseIn = true; - - const {x} = domUtils$1.translateMouseCoordinates(event, this.rulerViewport.contentDiv); - left = mouseDownX = x; - - width = threshold; - - - this.rulerSweeper.style.display = 'block'; - this.rulerSweeper.style.backgroundColor = true === event.shiftKey ? ROI_USER_DEFINED_COLOR : RULER_SWEEPER_COLOR; - - this.rulerSweeper.style.left = `${left}px`; - this.rulerSweeper.style.width = `${width}px`; - - } - - // Document - this.boundDocumentMouseMoveHandler = documentMouseMoveHandler.bind(this); - document.addEventListener('mousemove', this.boundDocumentMouseMoveHandler); - - function documentMouseMoveHandler(event) { - - let mouseCurrentX; - - if (isMouseDown && isMouseIn) { - - const {x} = domUtils$1.translateMouseCoordinates(event, this.rulerViewport.contentDiv); - mouseCurrentX = Math.max(Math.min(x, this.rulerViewport.contentDiv.clientWidth), 0); - - dx = mouseCurrentX - mouseDownX; - - width = Math.abs(dx); - this.rulerSweeper.style.width = `${width}px`; - - if (dx < 0) { - left = mouseDownX + dx; - this.rulerSweeper.style.left = `${left}px`; - } - - } - - } - - this.boundDocumentMouseUpHandler = documentMouseUpHandler.bind(this); - document.addEventListener('mouseup', this.boundDocumentMouseUpHandler); - - function documentMouseUpHandler(event) { - - let genomicExtent; - - if (true === isMouseDown && true === isMouseIn) { - - isMouseDown = isMouseIn = undefined; - - this.rulerSweeper.style.display = 'none'; - - if (width > threshold) { - - genomicExtent = - { - start: Math.floor(this.referenceFrame.calculateEnd(left)), - end: Math.floor(this.referenceFrame.calculateEnd(left + width)), - }; - - - const shiftKeyPressed = event.shiftKey; - - if (true === shiftKeyPressed) { - this.browser.roiManager.updateUserDefinedROISet(Object.assign({chr: this.referenceFrame.chr}, genomicExtent)); - } else { - - validateGenomicExtent(this.browser.genome.getChromosome(this.referenceFrame.chr).bpLength, genomicExtent, this.browser.minimumBases()); - updateReferenceFrame(this.referenceFrame, genomicExtent, this.rulerViewport.contentDiv.clientWidth); - this.browser.updateViews(this.referenceFrame); - - } - - } - - } - - } - - this.isMouseHandlers = true; - } - - removeMouseHandlers() { - this.rulerViewport.contentDiv.removeEventListener('mousedown', this.boundContentMouseDownHandler); - document.removeEventListener('mousemove', this.boundDocumentMouseMoveHandler); - document.removeEventListener('mouseup', this.boundDocumentMouseUpHandler); - this.isMouseHandlers = false; - } - - dispose() { - this.removeBrowserObserver(); - this.removeMouseHandlers(); - this.rulerSweeper.remove(); - } - - } - - function updateReferenceFrame(referenceFrame, genomicExtent, pixelWidth) { - referenceFrame.start = Math.round(genomicExtent.start); - referenceFrame.end = Math.round(genomicExtent.end); - referenceFrame.bpPerPixel = (referenceFrame.end - referenceFrame.start) / pixelWidth; - } - - /* - * The MIT License (MIT) - * - * Copyright (c) 2016 University of California San Diego - * Author: Jim Robinson - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - - class PairedAlignment { - - constructor(firstAlignment) { - - this.paired = true; - this.firstAlignment = firstAlignment; - this.chr = firstAlignment.chr; - this.readName = firstAlignment.readName; - - if (firstAlignment.start < firstAlignment.mate.position) { - this.start = firstAlignment.start; - this.scStart = firstAlignment.scStart; - this.connectingStart = firstAlignment.start + firstAlignment.lengthOnRef; - this.connectingEnd = firstAlignment.mate.position; - } else { - this.start = firstAlignment.mate.position; - this.scStart = this.start; - this.connectingStart = firstAlignment.mate.position; - this.connectingEnd = firstAlignment.start; - } - - this.end = Math.max(firstAlignment.mate.position, firstAlignment.start + firstAlignment.lengthOnRef); // Approximate - this.lengthOnRef = this.end - this.start; - - let scEnd = Math.max(this.end, firstAlignment.scStart + firstAlignment.scLengthOnRef); - this.scLengthOnRef = scEnd - this.scStart; - - } - - setSecondAlignment(secondAlignment) { - - // TODO -- check the chrs are equal, error otherwise - this.secondAlignment = secondAlignment; - const firstAlignment = this.firstAlignment; - - if (secondAlignment.start > firstAlignment.start) { - this.connectingEnd = secondAlignment.start; - } else { - this.connectingStart = secondAlignment.start + secondAlignment.lengthOnRef; - } - - this.start = Math.min(firstAlignment.start, secondAlignment.start); - this.end = Math.max(firstAlignment.start + firstAlignment.lengthOnRef, secondAlignment.start + secondAlignment.lengthOnRef); - this.lengthOnRef = this.end - this.start; - - this.scStart = Math.min(firstAlignment.scStart, secondAlignment.scStart); - const scEnd = Math.max(firstAlignment.scStart + firstAlignment.scLengthOnRef, secondAlignment.scStart + secondAlignment.scLengthOnRef); - this.scLengthOnRef = scEnd - this.scStart; - - } - - containsLocation(genomicLocation, showSoftClips) { - const s = showSoftClips ? this.scStart : this.start; - const l = showSoftClips ? this.scLengthOnRef : this.lengthOnRef; - return (genomicLocation >= s && genomicLocation <= (s + l)) - } - - alignmentContaining(genomicLocation, showSoftClips) { - if (this.firstAlignment.containsLocation(genomicLocation, showSoftClips)) { - return this.firstAlignment - } else if (this.secondAlignment && this.secondAlignment.containsLocation(genomicLocation, showSoftClips)) { - return this.secondAlignment - } else { - return undefined - } - } - - popupData(genomicLocation) { - - let nameValues = this.firstAlignment.popupData(genomicLocation); - - if (this.secondAlignment) { - nameValues.push("-------------------------------"); - nameValues = nameValues.concat(this.secondAlignment.popupData(genomicLocation)); - } - return nameValues - } - - isPaired() { - return true // By definition - } - - isMateMapped() { - return true // By definition - } - - isProperPair() { - return this.firstAlignment.isProperPair() - } - - get fragmentLength() { - return Math.abs(this.firstAlignment.fragmentLength) - } - - firstOfPairStrand() { - - if (this.firstAlignment.isFirstOfPair()) { - return this.firstAlignment.strand - } else if (this.secondAlignment && this.secondAlignment.isFirstOfPair()) { - return this.secondAlignment.strand - } else { - return this.firstAlignment.mate.strand // Assumption is mate is first-of-pair - } - } - - hasTag(str) { - return this.firstAlignment.hasTag(str) || (this.secondAlignment && this.secondAlignment.hasTag(str)) - } - } - - /* - * The MIT License (MIT) - * - * Copyright (c) 2014 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - class BamAlignmentRow { - - constructor() { - - this.alignments = []; - this.score = undefined; - } - - findAlignment(genomicLocation) { - - const alignmentContains = (a, genomicLocation) => { - return genomicLocation >= a.start && genomicLocation < a.start + a.lengthOnRef - }; - - // find single alignment that overlaps sort location - let centerAlignment; - for (let i = 0; i < this.alignments.length; i++) { - const a = this.alignments[i]; - if (genomicLocation >= a.start && genomicLocation < a.start + a.lengthOnRef) { - if (a.paired) { - if (a.firstAlignment && alignmentContains(a.firstAlignment, genomicLocation)) { - centerAlignment = a.firstAlignment; - } else if (a.secondAlignment && alignmentContains(a.secondAlignment, genomicLocation)) { - centerAlignment = a.secondAlignment; - } - } else { - centerAlignment = a; - } - break - } - } - - return centerAlignment - - } - - getSortValue({position, option, tag}, alignmentContainer) { - - if (!option) option = "BASE"; - - const alignment = this.findAlignment(position); - if (undefined === alignment) { // This condition should never occur - return Number.MAX_VALUE - } - - switch (option) { - case "NUCLEOTIDE": - case "BASE": { - return calculateBaseScore(alignment, alignmentContainer, position) - } - case "STRAND": - return alignment.strand ? 1 : -1 - case "START": - return alignment.start - case "TAG": { - return alignment.tags()[tag] - } - case "READ_NAME": - return alignment.readName - case "INSERT_SIZE": - return -Math.abs(alignment.fragmentLength) - case "GAP_SIZE": - return -alignment.gapSizeAt(position) - case "MATE_CHR": - return alignment.mate - case "MQ": - return alignment.mq === undefined ? Number.MAX_VALUE : -alignment.mq - case "ALIGNED_READ_LENGTH": - return -alignment.lengthOnRef - default: - return Number.MAX_VALUE - } - - - function calculateBaseScore(alignment, alignmentContainer, genomicLocation) { - - let reference; - const idx = Math.floor(genomicLocation) - alignmentContainer.start; - if (idx < alignmentContainer.sequence.length) { - reference = alignmentContainer.sequence.charAt(idx); - } - if (!reference) { - return 0 - } - const base = alignment.readBaseAt(genomicLocation); - const quality = alignment.readBaseQualityAt(genomicLocation); - - const coverageMap = alignmentContainer.coverageMap; - const coverageMapIndex = Math.floor(genomicLocation - coverageMap.bpStart); - const coverage = coverageMap.coverage[coverageMapIndex]; - - // Insertions. These are additive with base scores as they occur between bases, so you can have a - // base mismatch AND an insertion - let baseScore = 0; - if (alignment.insertions) { - for (let ins of alignment.insertions) { - if (ins.start === genomicLocation) { - baseScore = -coverage.ins; - } - } - } - - - if (!base) { - // Either deletion or skipped (splice junction) - const delCount = coverage.del; - if (delCount > 0) { - baseScore -= delCount; - } else if (baseScore === 0) { // Don't modify insertion score, if any - baseScore = 1; - } - } else { - reference = reference.toUpperCase(); - if ('N' === base && baseScore === 0) { - baseScore = 2; - } else if ((reference === base || '=' === base) && baseScore === 0) { - baseScore = 4 - quality / 1000; - } else if ("X" === base || reference !== base) { - const count = coverage["pos" + base] + coverage["neg" + base]; - baseScore -= (count + (quality / 1000)); - } - } - - - return baseScore - } - } - - - } - - const alignmentSpace = 2; - - function canBePaired(alignment) { - return alignment.isPaired() && - alignment.mate && - alignment.isMateMapped() && - alignment.chr === alignment.mate.chr && - (alignment.isFirstOfPair() || alignment.isSecondOfPair()) && !(alignment.isSecondary() || alignment.isSupplementary()) - } - - - function pairAlignments(rows) { - - const pairCache = {}; - const result = []; - - for (let row of rows) { - for (let alignment of row.alignments) { - if (canBePaired(alignment)) { - let pairedAlignment = pairCache[alignment.readName]; - if (pairedAlignment) { - pairedAlignment.setSecondAlignment(alignment); - pairCache[alignment.readName] = undefined; // Don't need to track this anymore. - } else { - pairedAlignment = new PairedAlignment(alignment); - pairCache[alignment.readName] = pairedAlignment; - result.push(pairedAlignment); - } - } else { - result.push(alignment); - } - } - } - return result - } - - function unpairAlignments(rows) { - const result = []; - for (let row of rows) { - for (let alignment of row.alignments) { - if (alignment instanceof PairedAlignment) { - if (alignment.firstAlignment) result.push(alignment.firstAlignment); // shouldn't need the null test - if (alignment.secondAlignment) result.push(alignment.secondAlignment); - } else { - result.push(alignment); - } - } - } - return result - } - - function packAlignmentRows(alignments, start, end, showSoftClips) { - - //console.log(`packAlignmentRows ${start} ${end}`) - //const t0 = Date.now() - - if (!alignments) { - return undefined - } else if (alignments.length === 0) { - return [] - } else { - alignments.sort(function (a, b) { - return showSoftClips ? a.scStart - b.scStart : a.start - b.start - }); - - const packedAlignmentRows = []; - let alignmentRow; - let nextStart = 0; - let nextIDX = 0; - const allocated = new Set(); - const startNewRow = () => { - alignmentRow = new BamAlignmentRow(); - packedAlignmentRows.push(alignmentRow); - nextStart = 0; - nextIDX = 0; - allocated.clear(); - }; - startNewRow(); - - while (alignments.length > 0) { - if (nextIDX >= 0 && nextIDX < alignments.length) { - const alignment = alignments[nextIDX]; - allocated.add(alignment); - alignmentRow.alignments.push(alignment); - nextStart = showSoftClips ? - alignment.scStart + alignment.scLengthOnRef + alignmentSpace : - alignment.start + alignment.lengthOnRef + alignmentSpace; - nextIDX = binarySearch$1(alignments, (a) => (showSoftClips ? a.scStart : a.start) > nextStart, nextIDX); - } else { - // Remove allocated alignments and start new row - alignments = alignments.filter(a => !allocated.has(a)); - startNewRow(); - } - } - //console.log(`Done in ${Date.now() - t0} ms`) - return packedAlignmentRows - } - } - - - /** - * Return 0 <= i <= array.length such that !pred(array[i - 1]) && pred(array[i]). - * - * returns an index 0 ≤ i ≤ array.length such that the given predicate is false for array[i - 1] and true for array[i]* * - */ - function binarySearch$1(array, pred, min) { - let lo = min - 1, hi = array.length; - while (1 + lo < hi) { - const mi = lo + ((hi - lo) >> 1); - if (pred(array[mi])) { - hi = mi; - } else { - lo = mi; - } - } - return hi - } - - /* - * The MIT License (MIT) - * - * Copyright (c) 2016 University of California San Diego - * Author: Jim Robinson - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - - class AlignmentContainer { - - // this.config.samplingWindowSize, this.config.samplingDepth, - // this.config.pairsSupported, this.config.alleleFreqThreshold) - constructor(chr, start, end, {samplingWindowSize, samplingDepth, pairsSupported, alleleFreqThreshold}) { - - this.chr = chr; - this.start = Math.floor(start); - this.end = Math.ceil(end); - this.length = (end - start); - - this.alleleFreqThreshold = alleleFreqThreshold === undefined ? 0.2 : alleleFreqThreshold; - - this.coverageMap = new CoverageMap(chr, start, end, this.alleleFreqThreshold); - this.alignments = []; - this.downsampledIntervals = []; - - this.samplingWindowSize = samplingWindowSize === undefined ? 100 : samplingWindowSize; - this.samplingDepth = samplingDepth === undefined ? 1000 : samplingDepth; - - this.pairsSupported = pairsSupported === undefined ? true : pairsSupported; - this.paired = false; // false until proven otherwise - this.pairsCache = {}; // working cache of paired alignments by read name - - this.downsampledReads = new Set(); - - this.currentBucket = new DownsampleBucket(this.start, this.start + this.samplingWindowSize, this); - - this.filter = function filter(alignment) { // TODO -- pass this in - return alignment.isMapped() && !alignment.isFailsVendorQualityCheck() - }; - - } - - push(alignment) { - - if (this.filter(alignment) === false) return - - this.coverageMap.incCounts(alignment); // Count coverage before any downsampling - - if (this.pairsSupported && this.downsampledReads.has(alignment.readName)) { - return // Mate already downsampled -- pairs are treated as a single alignment for downsampling - } - - if (alignment.start >= this.currentBucket.end) { - this.finishBucket(); - this.currentBucket = new DownsampleBucket(alignment.start, alignment.start + this.samplingWindowSize, this); - } - - this.currentBucket.addAlignment(alignment); - - } - - forEach(callback) { - this.alignments.forEach(callback); - } - - finish() { - - if (this.currentBucket !== undefined) { - this.finishBucket(); - } - - this.alignments.sort(function (a, b) { - return a.start - b.start - }); - - this.pairsCache = undefined; - this.downsampledReads = undefined; - } - - contains(chr, start, end) { - return this.chr === chr && - this.start <= start && - this.end >= end - } - - hasDownsampledIntervals() { - return this.downsampledIntervals && this.downsampledIntervals.length > 0 - } - - finishBucket() { - this.alignments = this.alignments.concat(this.currentBucket.alignments); - if (this.currentBucket.downsampledCount > 0) { - this.downsampledIntervals.push(new DownsampledInterval( - this.currentBucket.start, - this.currentBucket.end, - this.currentBucket.downsampledCount)); - } - this.paired = this.paired || this.currentBucket.paired; - } - - setViewAsPairs(bool) { - let alignments; - if (bool) { - alignments = pairAlignments(this.packedAlignmentRows); - } else { - alignments = unpairAlignments(this.packedAlignmentRows); - } - this.packedAlignmentRows = packAlignmentRows(alignments, this.start, this.end); - } - - setShowSoftClips(bool) { - const alignments = this.allAlignments(); - this.packedAlignmentRows = packAlignmentRows(alignments, this.start, this.end, bool); - } - - repack(bpPerPixel, showSoftClips) { - const alignments = this.allAlignments(); - this.packedAlignmentRows = packAlignmentRows(alignments, this.start, this.end, showSoftClips); - - } - - allAlignments() { - const alignments = []; - for (let row of this.packedAlignmentRows) { - for (let alignment of row.alignments) { - alignments.push(alignment); - } - } - return alignments - } - - getMax(start, end) { - return this.coverageMap.getMax(start, end) - } - - sortRows(options) { - - const newRows = []; - const undefinedRow = []; - for (let row of this.packedAlignmentRows) { - const alignment = row.findAlignment(options.position); - if (undefined !== alignment) { - newRows.push(row); - } else { - undefinedRow.push(row); - } - } - - newRows.sort((rowA, rowB) => { - const direction = options.direction; - const rowAValue = rowA.getSortValue(options, this); - const rowBValue = rowB.getSortValue(options, this); - - if (rowBValue === undefined && rowBValue !== undefined) return 1 - else if (rowAValue !== undefined && rowBValue === undefined) return -1 - - const i = rowAValue > rowBValue ? 1 : (rowAValue < rowBValue ? -1 : 0); - return true === direction ? i : -i - }); - - for (let row of undefinedRow) { - newRows.push(row); - } - - this.packedAlignmentRows = newRows; - } - - } - - - class DownsampleBucket { - - constructor(start, end, alignmentContainer) { - - this.start = start; - this.end = end; - this.alignments = []; - this.downsampledCount = 0; - this.samplingDepth = alignmentContainer.samplingDepth; - this.pairsSupported = alignmentContainer.pairsSupported; - this.downsampledReads = alignmentContainer.downsampledReads; - this.pairsCache = alignmentContainer.pairsCache; - } - - addAlignment(alignment) { - - var idx, replacedAlignment, pairedAlignment; - - if (this.pairsSupported && canBePaired(alignment)) { - pairedAlignment = this.pairsCache[alignment.readName]; - if (pairedAlignment) { - // Not subject to downsampling, just update the existing alignment - pairedAlignment.setSecondAlignment(alignment); - this.pairsCache[alignment.readName] = undefined; // Don't need to track this anymore. NOTE: Don't "delete", causes runtime performance issues - return - } - } - - if (this.alignments.length < this.samplingDepth) { - - if (this.pairsSupported && canBePaired(alignment)) { - - // First alignment in a pair - pairedAlignment = new PairedAlignment(alignment); - this.paired = true; - this.pairsCache[alignment.readName] = pairedAlignment; - this.alignments.push(pairedAlignment); - - } else { - this.alignments.push(alignment); - } - - } else { - - idx = Math.floor(Math.random() * (this.samplingDepth + this.downsampledCount - 1)); - - if (idx < this.samplingDepth) { - - // Keep the new item - // idx = Math.floor(Math.random() * (this.alignments.length - 1)); - replacedAlignment = this.alignments[idx]; // To be replaced - - if (this.pairsSupported && canBePaired(alignment)) { - - if (this.pairsCache[replacedAlignment.readName] !== undefined) { - this.pairsCache[replacedAlignment.readName] = undefined; - } - - pairedAlignment = new PairedAlignment(alignment); - this.paired = true; - this.pairsCache[alignment.readName] = pairedAlignment; - this.alignments[idx] = pairedAlignment; - - } else { - this.alignments[idx] = alignment; - } - this.downsampledReads.add(replacedAlignment.readName); - - } else { - this.downsampledReads.add(alignment.readName); - } - - this.downsampledCount++; - } - - - } - } - - class CoverageMap { - - constructor(chr, start, end, alleleFreqThreshold) { - - this.chr = chr; - this.bpStart = start; - this.length = (end - start); - - this.coverage = new Array(this.length); - this.maximum = 0; - - this.threshold = alleleFreqThreshold; - this.qualityWeight = true; - } - - /** - * Return the maximum coverage value between start and end. This is used for autoscaling. - * @param start - * @param end - */ - getMax(start, end) { - let max = 0; - const len = this.coverage.length; - for (let i = 0; i < len; i++) { - const pos = this.bpStart + i; - if (pos > end) break - const cov = this.coverage[i]; - if (pos >= start && cov) { - max = Math.max(max, cov.total); - } - } - return max - } - - incCounts(alignment) { - - var self = this; - - if (alignment.blocks === undefined) { - incBlockCount(alignment); - } else { - alignment.blocks.forEach(function (block) { - incBlockCount(block); - }); - } - - if (alignment.gaps) { - for (let del of alignment.gaps) { - if (del.type === 'D') { - const offset = del.start - self.bpStart; - for (let i = offset; i < offset + del.len; i++) { - if (i < 0) continue - if (!this.coverage[i]) { - this.coverage[i] = new Coverage(self.threshold); - } - this.coverage[i].del++; - } - } - } - } - - if (alignment.insertions) { - for (let del of alignment.insertions) { - const i = del.start - this.bpStart; - if (i < 0) continue - if (!this.coverage[i]) { - this.coverage[i] = new Coverage(self.threshold); - } - this.coverage[i].ins++; - } - } - - function incBlockCount(block) { - - if ('S' === block.type) return - - const seq = alignment.seq; - const qual = alignment.qual; - const seqOffset = block.seqOffset; - - for (let i = block.start - self.bpStart, j = 0; j < block.len; i++, j++) { - - if (!self.coverage[i]) { - self.coverage[i] = new Coverage(self.threshold); - } - - const base = (seq == undefined) ? "N" : seq.charAt(seqOffset + j); - const key = (alignment.strand) ? "pos" + base : "neg" + base; - const q = qual && seqOffset + j < qual.length ? qual[seqOffset + j] : 30; - - self.coverage[i][key] += 1; - self.coverage[i]["qual" + base] += q; - - self.coverage[i].total += 1; - self.coverage[i].qual += q; - - self.maximum = Math.max(self.coverage[i].total, self.maximum); - - } - } - } - } - - - class Coverage { - - constructor(alleleThreshold) { - - this.qualityWeight = true; - - this.posA = 0; - this.negA = 0; - - this.posT = 0; - this.negT = 0; - - this.posC = 0; - this.negC = 0; - this.posG = 0; - - this.negG = 0; - - this.posN = 0; - this.negN = 0; - - this.pos = 0; - this.neg = 0; - - this.qualA = 0; - this.qualT = 0; - this.qualC = 0; - this.qualG = 0; - this.qualN = 0; - - this.qual = 0; - - this.total = 0; - this.del = 0; - this.ins = 0; - - this.threshold = alleleThreshold; - } - - hoverText() { - const pos = this.posA + this.posT + this.posC + this.posG + this.posN; - const neg = this.negA + this.negT + this.negC + this.negG + this.negN; - return `${this.total} (${pos}+, ${neg}-)` - } - - isMismatch(refBase) { - const threshold = this.threshold * ((this.qualityWeight && this.qual) ? this.qual : this.total); - let mismatchQualitySum = 0; - for (let base of ["A", "T", "C", "G"]) { - if (base !== refBase) { - mismatchQualitySum += ((this.qualityWeight && this.qual) ? this["qual" + base] : (this["pos" + base] + this["neg" + base])); - } - } - return mismatchQualitySum >= threshold - } - } - - class DownsampledInterval { - - constructor(start, end, counts) { - this.start = start; - this.end = end; - this.counts = counts; - } - - popupData(genomicLocation) { - return [ - {name: "start", value: this.start + 1}, - {name: "end", value: this.end}, - {name: "# downsampled:", value: this.counts}] - } - } - - class SupplementaryAlignment { - - constructor(rec) { - const tokens = rec.split(','); - this.chr = tokens[0]; - this.start = parseInt(tokens[1]); - this.strand = tokens[2].charAt(0); - this.mapQ = parseInt(tokens[4]); - this.numMismatches = parseInt(tokens[5]); - this.lenOnRef = BamUtils.computeLengthOnReference(tokens[3]); - } - - printString() { - return this.chr + ":" + numberFormatter$1(this.start) + "-" + numberFormatter$1(this.start + this.lenOnRef) - + " (" + this.strand + ") = " + numberFormatter$1(this.lenOnRef) + "bp @MAPQ: " + this.mapQ + " NM: " + this.numMismatches - } - } - - function createSupplementaryAlignments(str) { - const tokens = str.split(';'); - return tokens.filter(t => t.length > 0).map(str => new SupplementaryAlignment(str)) - } - - /* - * The MIT License (MIT) - * - * Copyright (c) 2014 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - const READ_PAIRED_FLAG = 0x1; - const PROPER_PAIR_FLAG = 0x2; - const READ_UNMAPPED_FLAG = 0x4; - const MATE_UNMAPPED_FLAG = 0x8; - const READ_STRAND_FLAG$2 = 0x10; - const MATE_STRAND_FLAG$2 = 0x20; - const FIRST_OF_PAIR_FLAG = 0x40; - const SECOND_OF_PAIR_FLAG = 0x80; - const SECONDARY_ALIGNMNET_FLAG = 0x100; - const READ_FAILS_VENDOR_QUALITY_CHECK_FLAG = 0x200; - const DUPLICATE_READ_FLAG = 0x400; - const SUPPLEMENTARY_ALIGNMENT_FLAG = 0x800; - const ELEMENT_SIZE = { - c: 1, - C: 1, - s: 2, - S: 2, - i: 4, - I: 4, - f: 4 - }; - - const MAX_CIGAR = 50; - - /** - * readName - * chr - * cigar - * lengthOnRef - * start - * seq - * qual - * mq - * strand - * blocks - */ - - class BamAlignment { - - constructor() { - this.hidden = false; - } - - isMapped() { - return (this.flags & READ_UNMAPPED_FLAG) === 0 - } - - isPaired() { - return (this.flags & READ_PAIRED_FLAG) !== 0 - } - - isProperPair() { - return (this.flags & PROPER_PAIR_FLAG) !== 0 - } - - isFirstOfPair() { - return (this.flags & FIRST_OF_PAIR_FLAG) !== 0 - } - - isSecondOfPair() { - return (this.flags & SECOND_OF_PAIR_FLAG) !== 0 - } - - isSecondary() { - return (this.flags & SECONDARY_ALIGNMNET_FLAG) !== 0 - } - - isSupplementary() { - return (this.flags & SUPPLEMENTARY_ALIGNMENT_FLAG) !== 0 - } - - isFailsVendorQualityCheck() { - return (this.flags & READ_FAILS_VENDOR_QUALITY_CHECK_FLAG) !== 0 - } - - isDuplicate() { - return (this.flags & DUPLICATE_READ_FLAG) !== 0 - } - - isMateMapped() { - return (this.flags & MATE_UNMAPPED_FLAG) === 0 - } - - isNegativeStrand() { - return (this.flags & READ_STRAND_FLAG$2) !== 0 - } - - isMateNegativeStrand() { - return (this.flags & MATE_STRAND_FLAG$2) !== 0 - } - - hasTag(tag) { - const tmpTags = this.tagDict || decodeTags(this.tagBA); - return tmpTags.hasOwnProperty(tag) - } - - tags() { - if (!this.tagDict) { - if (this.tagBA) { - this.tagDict = decodeTags(this.tagBA); - this.tagBA = undefined; - } else { - this.tagDict = {}; // Mark so we don't try again. The record has no tags - } - } - return this.tagDict - } - - /** - * Does alignment (or alignment extended by soft clips) contain the genomic location? - * - * @param genomicLocation - * @param showSoftClips - * @returns {boolean|boolean} - */ - containsLocation(genomicLocation, showSoftClips) { - const s = showSoftClips ? this.scStart : this.start; - const l = showSoftClips ? this.scLengthOnRef : this.lengthOnRef; - return (genomicLocation >= s && genomicLocation <= (s + l)) - } - - popupData(genomicLocation) { - - // if the user clicks on a base next to an insertion, show just the - // inserted bases in a popup (like in desktop IGV). - const nameValues = []; - - // Consert genomic location to int - genomicLocation = Math.floor(genomicLocation); - - if (this.insertions) { - - const seq = this.seq; - - for (let insertion of this.insertions) { - var ins_start = insertion.start; - if (genomicLocation === ins_start || genomicLocation === ins_start - 1) { - nameValues.push({name: 'Insertion', value: seq.substr(insertion.seqOffset, insertion.len)}); - nameValues.push({name: 'Location', value: ins_start}); - return nameValues - } - } - } - - nameValues.push({name: 'Read Name', value: this.readName}); - - // Sample - // Read group - nameValues.push('
'); - - // Add 1 to genomic location to map from 0-based computer units to user-based units - nameValues.push({name: 'Alignment Start', value: numberFormatter$1(1 + this.start), borderTop: true}); - nameValues.push({name: 'Read Strand', value: (true === this.strand ? '(+)' : '(-)'), borderTop: true}); - - // Abbreviate long cigar strings, keeping the beginning and end to show cliping - let cigar = this.cigar; - if (cigar && cigar.length > MAX_CIGAR) { - const half = MAX_CIGAR / 2; - cigar = `${cigar.substring(0, half - 2)} ... ${cigar.substring(cigar.length - half + 2)}`; - } - nameValues.push({name: 'Cigar', value: cigar}); - - nameValues.push({name: 'Mapping Quality', value: this.mq}); - nameValues.push({name: 'Secondary', value: yesNo(this.isSecondary())}); - nameValues.push({name: 'Supplementary', value: yesNo(this.isSupplementary())}); - nameValues.push({name: 'Duplicate', value: yesNo(this.isDuplicate())}); - nameValues.push({name: 'Failed QC', value: yesNo(this.isFailsVendorQualityCheck())}); - - if (this.isPaired()) { - nameValues.push('
'); - nameValues.push({name: 'First in Pair', value: !this.isSecondOfPair(), borderTop: true}); - nameValues.push({name: 'Mate is Mapped', value: yesNo(this.isMateMapped())}); - if (this.pairOrientation) { - nameValues.push({name: 'Pair Orientation', value: this.pairOrientation}); - } - if (this.isMateMapped()) { - nameValues.push({name: 'Mate Chromosome', value: this.mate.chr}); - nameValues.push({name: 'Mate Start', value: (this.mate.position + 1)}); - nameValues.push({name: 'Mate Strand', value: (true === this.mate.strand ? '(+)' : '(-)')}); - nameValues.push({name: 'Insert Size', value: this.fragmentLength}); - // Mate Start - // Mate Strand - // Insert Size - } - // First in Pair - // Pair Orientation - - } - - const tagDict = this.tags(); - - if (tagDict.hasOwnProperty('SA')) { - nameValues.push('
'); - nameValues.push({name: 'Supplementary Alignments', value: ''}); - const sa = createSupplementaryAlignments(tagDict['SA']); - if (sa) { - nameValues.push('
    '); - for (let s of sa) { - nameValues.push(`
  • ${s.printString()}
  • `); - } - nameValues.push('
'); - } - } - - const hiddenTags = new Set(['SA', 'MD']); - nameValues.push('
'); - for (let key in tagDict) { - if (!hiddenTags.has(key)) { - nameValues.push({name: key, value: tagDict[key]}); - } - } - - nameValues.push({name: 'Hidden Tags', value: 'SA, MD'}); - - nameValues.push('
'); - nameValues.push({name: 'Genomic Location: ', value: numberFormatter$1(1 + genomicLocation)}); - nameValues.push({name: 'Read Base:', value: this.readBaseAt(genomicLocation)}); - nameValues.push({name: 'Base Quality:', value: this.readBaseQualityAt(genomicLocation)}); - - return nameValues - - - function yesNo(bool) { - return bool ? 'Yes' : 'No' - } - } - - readBaseAt(genomicLocation) { - - const block = blockAtGenomicLocation(this.blocks, genomicLocation); - if (block) { - if ("*" === this.seq) { - return "*" - } else { - const idx = block.seqIndexAt(genomicLocation); - // if (idx >= 0 && idx < this.seq.length) { - return this.seq[idx] - // } - } - } else { - return undefined - } - } - - readBaseQualityAt(genomicLocation) { - - const block = blockAtGenomicLocation(this.blocks, genomicLocation); - if (block) { - if ("*" === this.qual) { - return 30 - } else { - const idx = block.seqIndexAt(genomicLocation); - if (idx >= 0 && this.qual && idx < this.qual.length) { - return this.qual[idx] - } else { - return 30 - } - } - } else { - return undefined - } - } - - gapSizeAt(genomicLocation) { - if (this.gaps) { - for (let gap of this.gaps) { - if (genomicLocation >= gap.start && genomicLocation < gap.start + gap.len) { - return gap.len - } - } - } - return 0 - } - - /** - * Return soft clipped blocks, if they exist, keyed by alignment end (left or right) - */ - softClippedBlocks() { - let left; - let right; - let interiorSeen; - for(let b of this.blocks) { - if('S' === b.type) { - if(interiorSeen) { - right = b; - } else { - left = b; - } - } else if('H' !== b.type) { - interiorSeen = true; - } - } - return {left, right} - } - - } - - function blockAtGenomicLocation(blocks, genomicLocation) { - - for (let i = 0; i < blocks.length; i++) { - const block = blocks[i]; - if (genomicLocation >= block.start && genomicLocation < block.start + block.len) { - return block - } - } - return undefined - } - - function decodeTags(ba) { - - let p = 0; - const len = ba.length; - const tags = {}; - - while (p < len) { - const tag = String.fromCharCode(ba[p]) + String.fromCharCode(ba[p + 1]); - p += 2; - - const type = String.fromCharCode(ba[p++]); - let value; - if (type === 'A') { - value = String.fromCharCode(ba[p]); - p++; - } else if (type === 'i' || type === 'I') { - value = readInt$1(ba, p); - p += 4; - } else if (type === 'c') { - value = readInt8(ba, p); - p++; - } else if (type === 'C') { - value = readUInt8(ba, p); - p++; - } else if (type === 's' || type === 'S') { - value = readShort(ba, p); - p += 2; - } else if (type === 'f') { - value = readFloat(ba, p); - p += 4; - } else if (type === 'Z') { - value = ''; - for (; ;) { - var cc = ba[p++]; - if (cc === 0) { - break - } else { - value += String.fromCharCode(cc); - } - } - } else if (type === 'B') { - const elementType = String.fromCharCode(ba[p++]); - let elementSize = ELEMENT_SIZE[elementType]; - if (elementSize === undefined) { - tags[tag] = `Error: unknown element type '${elementType}'`; - break - } - const numElements = readInt$1(ba, p); - p += (4 + numElements * elementSize); - value = '[not shown]'; - } else { - //'Unknown type ' + type; - value = 'Error unknown type: ' + type; - tags[tag] = value; - break - } - tags[tag] = value; - } - return tags - } - - - function readInt$1(ba, offset) { - return (ba[offset + 3] << 24) | (ba[offset + 2] << 16) | (ba[offset + 1] << 8) | (ba[offset]) - } - - function readShort(ba, offset) { - return (ba[offset + 1] << 8) | (ba[offset]) - } - - function readFloat(ba, offset) { - const dataView = new DataView(ba.buffer); - return dataView.getFloat32(offset) - } - - function readInt8(ba, offset) { - const dataView = new DataView(ba.buffer); - return dataView.getInt8(offset) - } - - function readUInt8(ba, offset) { - const dataView = new DataView(ba.buffer); - return dataView.getUint8(offset) - } - - /* - * The MIT License (MIT) - * - * Copyright (c) 2016-2017 The Regents of the University of California - * Author: Jim Robinson - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - /** - * Created by jrobinso on 4/5/18. - */ - - - class AlignmentBlock { - constructor(b) { - if (b) { - Object.assign(this, b); - } - } - - seqIndexAt(genomicLocation) { - return Math.floor(genomicLocation) - this.start + this.seqOffset - } - } - - class BamFilter { - constructor(options) { - if (!options) options = {}; - this.vendorFailed = options.vendorFailed === undefined ? true : options.vendorFailed; - this.duplicates = options.duplicates === undefined ? true : options.duplicates; - this.secondary = options.secondary || false; - this.supplementary = options.supplementary || false; - this.mqThreshold = options.mqThreshold === undefined ? 0 : options.mqThreshold; - if (options.readgroups) { - this.readgroups = new Set(options.readgroups); - } - } - - pass(alignment) { - if (this.vendorFailed && alignment.isFailsVendorQualityCheck()) return false - if (this.duplicates && alignment.isDuplicate()) return false - if (this.secondary && alignment.isSecondary()) return false - if (this.supplementary && alignment.isSupplementary()) return false - if (alignment.mq < this.mqThreshold) return false - if (this.readgroups) { - var rg = alignment.tags()['RG']; - return this.readgroups.has(rg) - } - return true - } - } - - /* - * The MIT License (MIT) - * - * Copyright (c) 2016-2017 The Regents of the University of California - * Author: Jim Robinson - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - - /** - * This code is based on the Biodalliance BAM reader by Thomas Down, 2011 - * - * https://github.com/dasmoth/dalliance/blob/master/js/bam.js - */ - - const SEQ_DECODER = ['=', 'A', 'C', 'x', 'G', 'x', 'x', 'x', 'T', 'x', 'x', 'x', 'x', 'x', 'x', 'N']; - const CIGAR_DECODER = ['M', 'I', 'D', 'N', 'S', 'H', 'P', '=', 'X', '?', '?', '?', '?', '?', '?', '?']; - const READ_STRAND_FLAG$1 = 0x10; - const MATE_STRAND_FLAG$1 = 0x20; - - const BAM1_MAGIC_BYTES = new Uint8Array([0x42, 0x41, 0x4d, 0x01]); // BAM\1 - const BAM1_MAGIC_NUMBER = readInt(BAM1_MAGIC_BYTES, 0); - - const DEFAULT_ALLELE_FREQ_THRESHOLD = 0.2; - const DEFAULT_SAMPLING_WINDOW_SIZE = 100; - const DEFAULT_SAMPLING_DEPTH = 500; - const MAXIMUM_SAMPLING_DEPTH = 10000; - - const BamUtils = { - - readHeader: function (url, options, genome) { - - return igvxhr.loadArrayBuffer(url, options) - - .then(function (compressedBuffer) { - - var header, unc, uncba; - - unc = unbgzf(compressedBuffer); - uncba = unc; - - header = BamUtils.decodeBamHeader(uncba, genome); - - return header - - }) - - }, - - /** - * - * @param ba bytes to decode as a UInt8Array - * @param genome optional igv genome object - * @returns {{ magicNumer: number, size: number, chrNames: Array, chrToIndex: ({}|*), chrAliasTable: ({}|*) }} - */ - decodeBamHeader: function (ba, genome) { - - var magic, samHeaderLen, samHeader, chrToIndex, chrNames, chrAliasTable, alias; - - magic = readInt(ba, 0); - if (magic !== BAM1_MAGIC_NUMBER) { - throw new Error('BAM header errror: bad magic number. This could be caused by either a corrupt or missing file.') - } - - samHeaderLen = readInt(ba, 4); - samHeader = ''; - - for (var i = 0; i < samHeaderLen; ++i) { - samHeader += String.fromCharCode(ba[i + 8]); - } - - var nRef = readInt(ba, samHeaderLen + 8); - var p = samHeaderLen + 12; - - chrToIndex = {}; - chrNames = []; - chrAliasTable = {}; - - for (i = 0; i < nRef; ++i) { - var lName = readInt(ba, p); - var name = ''; - for (var j = 0; j < lName - 1; ++j) { - name += String.fromCharCode(ba[p + 4 + j]); - } - readInt(ba, p + lName + 4); - //dlog(name + ': ' + lRef); - - chrToIndex[name] = i; - chrNames[i] = name; - - if (genome) { - alias = genome.getChromosomeName(name); - chrAliasTable[alias] = name; - } - - p = p + 8 + lName; - } - - return { - magicNumber: magic, - size: p, - chrNames: chrNames, - chrToIndex: chrToIndex, - chrAliasTable: chrAliasTable - } - - }, - - bam_tag2cigar: function (ba, block_end, seq_offset, lseq, al, cigarArray) { - - function type2size(x) { - if (x === 'C' || x === 'c' || x === 'A') return 1 - else if (x === 'S' || x === 's') return 2 - else if (x === 'I' || x === 'i' || x === 'f') return 4 - else return 0 - } - - // test if the real CIGAR is encoded in a CG:B,I tag - if (cigarArray.length !== 1 || al.start < 0) return false - var p = seq_offset + ((lseq + 1) >> 1) + lseq; - while (p + 4 < block_end) { - var tag = String.fromCharCode(ba[p]) + String.fromCharCode(ba[p + 1]); - if (tag === 'CG') break - var type = String.fromCharCode(ba[p + 2]); - if (type === 'B') { // the binary array type - type = String.fromCharCode(ba[p + 3]); - var size = type2size(type); - var len = readInt(ba, p + 4); - p += 8 + size * len; - } else if (type === 'Z' || type === 'H') { // 0-terminated string - p += 3; - while (ba[p++] !== 0) { - } - } else { // other atomic types - p += 3 + type2size(type); - } - } - if (p >= block_end) return false // no CG tag - if (String.fromCharCode(ba[p + 2]) !== 'B' || String.fromCharCode(ba[p + 3]) !== 'I') return false // not of type B,I - - // now we know the real CIGAR length and its offset in the binary array - var cigar_len = readInt(ba, p + 4); - var cigar_offset = p + 8; // 4 for "CGBI" and 4 for length - if (cigar_offset + cigar_len * 4 > block_end) return false // out of bound - - // decode CIGAR - var cigar = ''; - var lengthOnRef = 0; - cigarArray.length = 0; // empty the old array - p = cigar_offset; - for (var k = 0; k < cigar_len; ++k, p += 4) { - var cigop = readInt(ba, p); - var opLen = (cigop >> 4); - var opLtr = CIGAR_DECODER[cigop & 0xf]; - if (opLtr === 'M' || opLtr === 'EQ' || opLtr === 'X' || opLtr === 'D' || opLtr === 'N' || opLtr === '=') - lengthOnRef += opLen; - cigar = cigar + opLen + opLtr; - cigarArray.push({len: opLen, ltr: opLtr}); - } - - // update alignment record. We are not updating bin, as apparently it is not used. - al.cigar = cigar; - al.lengthOnRef = lengthOnRef; - return true - }, - - /** - * - * @param ba bytes to decode as an UInt8Array - * @param offset offset position of ba array to start decoding - * @param alignmentContainer container to receive the decoded alignments - * @param min minimum genomic position - * @param max maximum genomic position - * @param chrIdx chromosome index - * @param chrNames array of chromosome names - * @param filter a BamFilter object - * - * @return true if we have moved beyond the right end of the genomic range. - */ - decodeBamRecords: function (ba, offset, alignmentContainer, chrNames, chrIdx, min, max, filter) { - - while (offset < ba.length) { - - const blockSize = readInt(ba, offset); - const blockEnd = offset + blockSize + 4; - const alignment = new BamAlignment(); - const refID = readInt(ba, offset + 4); - const pos = readInt(ba, offset + 8); - - if (blockEnd > ba.length) { - return - } - if (refID < 0) { - offset = blockEnd; - continue // unmapped read - } else if (chrIdx !== undefined && (refID > chrIdx || pos > max)) { - return true // off right edge, we're done - } else if (chrIdx !== undefined && (refID < chrIdx)) { - offset = blockEnd; - continue // ref ID to left of start, not sure this is possible - } - - const bin_mq_nl = readInt(ba, offset + 12); - const mq = (bin_mq_nl & 0xff00) >> 8; - const nl = bin_mq_nl & 0xff; - - const flag_nc = readInt(ba, offset + 16); - const flag = (flag_nc & 0xffff0000) >> 16; - const nc = flag_nc & 0xffff; - - const lseq = readInt(ba, offset + 20); - const mateChrIdx = readInt(ba, offset + 24); - const matePos = readInt(ba, offset + 28); - const fragmentLength = readInt(ba, offset + 32); - - let readName = []; - for (let j = 0; j < nl - 1; ++j) { - readName.push(String.fromCharCode(ba[offset + 36 + j])); - } - readName = readName.join(''); - - let lengthOnRef = 0; - let cigar = ''; - let p = offset + 36 + nl; - const cigarArray = []; - // concatenate M,=,EQ,and X - - let lastCigRecord; - for (let c = 0; c < nc; ++c) { - var cigop = readInt(ba, p); - var opLen = (cigop >> 4); - var opLtr = CIGAR_DECODER[cigop & 0xf]; - if (opLtr === 'M' || opLtr === 'EQ' || opLtr === 'X' || opLtr === 'D' || opLtr === 'N' || opLtr === '=') - lengthOnRef += opLen; - cigar = cigar + opLen + opLtr; - p += 4; - - // if(mOperators.has(opLtr) && mOperators.has(lastCigRecord.ltr)) { - // lastCigRecord.len += opLen; - // lastCigRecord.ltr = 'M' - // } - // else { - lastCigRecord = {len: opLen, ltr: opLtr}; - cigarArray.push(lastCigRecord); - //} - } - - alignment.chr = chrNames[refID]; - alignment.start = pos; - alignment.flags = flag; - alignment.strand = !(flag & READ_STRAND_FLAG$1); - alignment.readName = readName; - alignment.cigar = cigar; - alignment.lengthOnRef = lengthOnRef; - alignment.fragmentLength = fragmentLength; - alignment.mq = mq; - - BamUtils.bam_tag2cigar(ba, blockEnd, p, lseq, alignment, cigarArray); - - alignment.end = alignment.start + alignment.lengthOnRef; - - if (alignment.end < min) { - offset = blockEnd; - continue - } // Record out-of-range "to the left", skip to next one - - - let seq = []; - const seqBytes = (lseq + 1) >> 1; - for (let j = 0; j < seqBytes; ++j) { - var sb = ba[p + j]; - seq.push(SEQ_DECODER[(sb & 0xf0) >> 4]); - seq.push(SEQ_DECODER[(sb & 0x0f)]); - } - seq = seq.slice(0, lseq).join(''); // seq might have one extra character (if lseq is an odd number) - p += seqBytes; - - - const qualArray = []; - for (let j = 0; j < lseq; ++j) { - qualArray.push(ba[p + j]); - } - p += lseq; - - if (mateChrIdx >= 0) { - alignment.mate = { - chr: chrNames[mateChrIdx], - position: matePos, - strand: !(flag & MATE_STRAND_FLAG$1) - }; - } - - alignment.seq = seq; - alignment.qual = qualArray; - alignment.tagBA = new Uint8Array(ba.buffer.slice(p, blockEnd)); // decode these on demand - - this.setPairOrientation(alignment); - - if ((undefined === filter || filter.pass(alignment))) { - makeBlocks(alignment, cigarArray); - alignmentContainer.push(alignment); - } - offset = blockEnd; - } - }, - - decodeSamRecords: function (sam, alignmentContainer, chr, min, max, filter) { - - var lines, i, j, len, tokens, qualString, rnext, lengthOnRef, - alignment, cigarArray, started; - - lines = splitLines$5(sam); - len = lines.length; - started = false; - - for (i = 0; i < len; i++) { - - tokens = lines[i].split('\t'); - - alignment = new BamAlignment(); - - alignment.chr = tokens[2]; - alignment.start = Number.parseInt(tokens[3]) - 1; - alignment.flags = Number.parseInt(tokens[1]); - alignment.readName = tokens[0]; - alignment.strand = !(alignment.flags & READ_STRAND_FLAG$1); - alignment.mq = Number.parseInt(tokens[4]); - alignment.cigar = tokens[5]; - alignment.fragmentLength = Number.parseInt(tokens[8]); - alignment.seq = tokens[9]; - - if (alignment.chr === '*' || !alignment.isMapped()) continue // Unmapped - - if (alignment.chr !== chr) { - if (started) break // Off the right edge, we're done - else continue // Possibly to the left, skip but keep looping - } else if (alignment.start > max) { - break // off right edge, we're done - } - - lengthOnRef = 0; - cigarArray = buildOperators(alignment.cigar); - cigarArray.forEach(function (op) { - var opLen = op.len; - var opLtr = op.ltr; - if (opLtr === 'M' || opLtr === 'EQ' || opLtr === 'X' || opLtr === 'D' || opLtr === 'N' || opLtr === '=') - lengthOnRef += opLen; - }); - alignment.lengthOnRef = lengthOnRef; - // TODO for lh3: parse the CG:B,I tag in SAM here - - if (alignment.start + lengthOnRef < min) { - continue // To the left, skip and continue - } - - - qualString = tokens[10]; - alignment.qual = []; - for (j = 0; j < qualString.length; j++) { - alignment.qual[j] = qualString.charCodeAt(j) - 33; - } - alignment.tagDict = tokens.length < 11 ? {} : decodeSamTags(tokens.slice(11)); - - if (alignment.isMateMapped()) { - rnext = tokens[6]; - alignment.mate = { - chr: (rnext === '=') ? alignment.chr : rnext, - position: Number.parseInt(tokens[7]), - strand: !(alignment.flags & MATE_STRAND_FLAG$1) - }; - } - - this.setPairOrientation(alignment); - - if (undefined === filter || filter.pass(alignment)) { - makeBlocks(alignment, cigarArray); - alignmentContainer.push(alignment); - } - } - }, - - setReaderDefaults: function (reader, config) { - - reader.filter = new BamFilter(config.filter); - - if (config.readgroup) { - reader.filter.readgroups = new Set([config.readgroup]); - } - - reader.alleleFreqThreshold = config.alleleFreqThreshold === undefined ? DEFAULT_ALLELE_FREQ_THRESHOLD : config.alleleFreqThreshold; - - reader.samplingWindowSize = config.samplingWindowSize === undefined ? DEFAULT_SAMPLING_WINDOW_SIZE : config.samplingWindowSize; - reader.samplingDepth = config.samplingDepth === undefined ? DEFAULT_SAMPLING_DEPTH : config.samplingDepth; - - if (reader.samplingDepth > MAXIMUM_SAMPLING_DEPTH) { - console.log("Warning: attempt to set sampling depth > maximum value of " + MAXIMUM_SAMPLING_DEPTH); - reader.samplingDepth = MAXIMUM_SAMPLING_DEPTH; - } - - if (config.viewAsPairs) { - reader.pairsSupported = true; - } else { - reader.pairsSupported = config.pairsSupported === undefined ? true : config.pairsSupported; - } - }, - - setPairOrientation: function (alignment) { - - if (alignment.isMapped() && alignment.mate && alignment.isMateMapped() && alignment.mate.chr === alignment.chr) { - var s1 = alignment.strand ? 'F' : 'R'; - - var mate = alignment.mate; - var s2 = mate.strand ? 'F' : 'R'; - var o1 = ' '; - var o2 = ' '; - if (alignment.isFirstOfPair()) { - o1 = '1'; - o2 = '2'; - } else if (alignment.isSecondOfPair()) { - o1 = '2'; - o2 = '1'; - } - - var tmp = []; - var isize = alignment.fragmentLength; - var estReadLen = alignment.end - alignment.start; - if (isize === 0) { - //isize not recorded. Need to estimate. This calculation was validated against an Illumina - // -> <- library bam. - var estMateEnd = alignment.start < mate.position ? - mate.position + estReadLen : mate.position - estReadLen; - isize = estMateEnd - alignment.start; - } - - //if (isize > estReadLen) { - if (isize > 0) { - tmp[0] = s1; - tmp[1] = o1; - tmp[2] = s2; - tmp[3] = o2; - - } else { - tmp[2] = s1; - tmp[3] = o1; - tmp[0] = s2; - tmp[1] = o2; - } - // } - alignment.pairOrientation = tmp.join(''); - } - }, - - computeLengthOnReference: function (cigarString) { - - let len = 0; - let buf = ''; - - for (let i = 0; i < cigarString.length; i++) { - const c = cigarString.charCodeAt(i); - if (c > 47 && c < 58) { - buf += cigarString.charAt(i); - } else { - switch (c) { - case 78: // N - case 68: // D - case 77: // M - case 61: // = - case 88: // X - len += parseInt(buf.toString()); - } - buf = ''; - } - } - return len - } - }; - - - /** - * Split the alignment record into blocks as specified in the cigarArray. Each aligned block contains - * its portion of the read sequence and base quality strings. A read sequence or base quality string - * of "*" indicates the value is not recorded. In all other cases the length of the block sequence (block.seq) - * and quality string (block.qual) must == the block length. - * - * @param alignment - * @param cigarArray - * @returns array of blocks - */ - function makeBlocks(alignment, cigarArray) { - - const blocks = []; - - let insertions; - let gaps; - let seqOffset = 0; - let pos = alignment.start; - - alignment.scStart = alignment.start; - alignment.scLengthOnRef = alignment.lengthOnRef; - - for (let c of cigarArray) { - - let scPos; - switch (c.ltr) { - case 'H' : - break // ignore hard clips - case 'P' : - break // ignore pads - case 'S' : - - scPos = pos; - alignment.scLengthOnRef += c.len; - if (blocks.length === 0) { - alignment.scStart -= c.len; - scPos -= c.len; - } - blocks.push(new AlignmentBlock({ - start: scPos, - seqOffset: seqOffset, - len: c.len, - type: 'S' - })); - seqOffset += c.len; - break // soft clip read bases - case 'N' : - case 'D': - if (gaps === undefined) { - gaps = []; - } - gaps.push({ - start: pos, - len: c.len, - type: c.ltr - }); - pos += c.len; - break - case 'I' : - - if (insertions === undefined) { - insertions = []; - } - insertions.push(new AlignmentBlock({ - start: pos, - len: c.len, - seqOffset: seqOffset, - type: 'I' - })); - seqOffset += c.len; - break - case 'M' : - case 'EQ' : - case '=' : - case 'X' : - blocks.push(new AlignmentBlock({ - start: pos, - seqOffset: seqOffset, - len: c.len, - type: 'M' - })); - seqOffset += c.len; - pos += c.len; - - break - - default : - console.log('Error processing cigar element: ' + c.len + c.ltr); - } - } - - alignment.blocks = blocks; - alignment.insertions = insertions; - alignment.gaps = gaps; - - } - - function readInt(ba, offset) { - return (ba[offset + 3] << 24) | (ba[offset + 2] << 16) | (ba[offset + 1] << 8) | (ba[offset]) - } - - /** - * Build a list of cigar operators from a cigarString. Removes padding operators and concatenates consecutive - * operators of the same type - * - * @param cigarString - * @return - */ - function buildOperators(cigarString) { - - var operators, buffer, i, len, prevOp, next, op, nBases; - - operators = []; - buffer = []; - - // Create list of cigar operators - prevOp = null; - len = cigarString.length; - for (i = 0; i < len; i++) { - next = cigarString.charAt(i); - if (isDigit(next)) { - buffer.push(next); - } else { - op = next; - nBases = Number.parseInt(buffer.join('')); - buffer = []; - - if (prevOp !== null && prevOp.ltr === op) { - prevOp.len += nBases; - } else { - prevOp = {len: nBases, ltr: op}; - operators.push(prevOp); - } - } - } - return operators - - } - - function isDigit(a) { - var charCode = a.charCodeAt(0); - return (charCode >= 48 && charCode <= 57) // 0-9 - } - - function decodeSamTags(tags) { - - var tagDict = {}; - tags.forEach(function (tag) { - var tokens = tag.split(':'); - tagDict[tokens[0]] = tokens[2]; - }); - - return tagDict - } - - /* - * The MIT License (MIT) - * - * Copyright (c) 2016-2017 The Regents of the University of California - * Author: Jim Robinson - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - /** - * Class for reading a bam file - * - * @param config - * @constructor - */ - class BamReaderNonIndexed { - - constructor(config, genome) { - this.config = config; - this.genome = genome; - this.bamPath = config.url; - this.isDataUri = isDataURL(config.url); - BamUtils.setReaderDefaults(this, config); - } - - // Return an alignment container - async readAlignments(chr, bpStart, bpEnd) { - - if (this.alignmentCache) { - const header = this.header; - const queryChr = header.chrAliasTable.hasOwnProperty(chr) ? header.chrAliasTable[chr] : chr; - const qAlignments = this.alignmentCache.queryFeatures(queryChr, bpStart, bpEnd); - const alignmentContainer = new AlignmentContainer(chr, bpStart, bpEnd, this.config); - for (let a of qAlignments) { - alignmentContainer.push(a); - } - alignmentContainer.finish(); - return alignmentContainer - - } else { - if (this.isDataUri) { - const data = decodeDataURI(this.bamPath); - const unc = unbgzf(data.buffer); - this.parseAlignments(unc); - return this.fetchAlignments(chr, bpStart, bpEnd) - } else { - const arrayBuffer = await igvxhr.loadArrayBuffer(this.bamPath, buildOptions$1(this.config)); - const unc = unbgzf(arrayBuffer); - this.parseAlignments(unc); - return this.fetchAlignments(chr, bpStart, bpEnd) - } - } - - } - - parseAlignments(data) { - const alignments = []; - this.header = BamUtils.decodeBamHeader(data); - BamUtils.decodeBamRecords(data, this.header.size, alignments, this.header.chrNames); - this.alignmentCache = new FeatureCache$1(alignments, this.genome); - } - - fetchAlignments(chr, bpStart, bpEnd) { - const queryChr = this.header.chrAliasTable.hasOwnProperty(chr) ? this.header.chrAliasTable[chr] : chr; - const features = this.alignmentCache.queryFeatures(queryChr, bpStart, bpEnd); - const alignmentContainer = new AlignmentContainer(chr, bpStart, bpEnd, this.config); - for (let feature of features) { - alignmentContainer.push(feature); - } - alignmentContainer.finish(); - return alignmentContainer - } - - } - - function decodeDataURI(dataURI) { - - const split = dataURI.split(','); - const info = split[0].split(':')[1]; - let dataString = split[1]; - - if (info.indexOf('base64') >= 0) { - dataString = atob(dataString); - } else { - dataString = decodeURI(dataString); - } - - const bytes = new Uint8Array(dataString.length); - for (var i = 0; i < dataString.length; i++) { - bytes[i] = dataString.charCodeAt(i); - } - return bytes - } - - /* - * The MIT License (MIT) - * - * Copyright (c) 2016-2017 The Regents of the University of California - * Author: Jim Robinson - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - /** - * Class for reading a bam file - * - * @param config - * @constructor - */ - class BamReader { - - constructor(config, genome) { - this.config = config; - this.genome = genome; - this.bamPath = config.url; - this.baiPath = config.indexURL; - BamUtils.setReaderDefaults(this, config); - - this._blockLoader = new BGZBlockLoader(config); - } - - async readAlignments(chr, bpStart, bpEnd) { - - const chrToIndex = await this.getChrIndex(); - const queryChr = this.chrAliasTable.hasOwnProperty(chr) ? this.chrAliasTable[chr] : chr; - const chrId = chrToIndex[queryChr]; - const alignmentContainer = new AlignmentContainer(chr, bpStart, bpEnd, this.config); - - if (chrId === undefined) { - return alignmentContainer - - } else { - - const bamIndex = await this.getIndex(); - const chunks = bamIndex.chunksForRange(chrId, bpStart, bpEnd); - - if (!chunks || chunks.length === 0) { - return alignmentContainer - } - - for (let c of chunks) { - const ba = await this._blockLoader.getData(c.minv, c.maxv); - const done = BamUtils.decodeBamRecords(ba, c.minv.offset, alignmentContainer, this.indexToChr, chrId, bpStart, bpEnd, this.filter); - if (done) { - break - } - } - alignmentContainer.finish(); - return alignmentContainer - } - } - - async getHeader() { - if (!this.header) { - const genome = this.genome; - const index = await this.getIndex(); - let len; - if (index.firstBlockPosition) { - const bsizeOptions = buildOptions$1(this.config, {range: {start: index.firstBlockPosition, size: 26}}); - const abuffer = await igvxhr.loadArrayBuffer(this.bamPath, bsizeOptions); - const bsize = bgzBlockSize$1(abuffer); - len = index.firstBlockPosition + bsize; // Insure we get the complete compressed block containing the header - } else { - len = 64000; - } - - const options = buildOptions$1(this.config, {range: {start: 0, size: len}}); - this.header = await BamUtils.readHeader(this.bamPath, options, genome); - } - return this.header - } - - async getIndex() { - const genome = this.genome; - if (!this.index) { - this.index = await loadIndex(this.baiPath, this.config, genome); - } - return this.index - } - - async getChrIndex() { - if (this.chrToIndex) { - return this.chrToIndex - } else { - const header = await this.getHeader(); - this.chrToIndex = header.chrToIndex; - this.indexToChr = header.chrNames; - this.chrAliasTable = header.chrAliasTable; - return this.chrToIndex - - } - } - } - - /* - * The MIT License (MIT) - * - * Copyright (c) 2016-2017 The Regents of the University of California - * Author: Jim Robinson - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - class ShardedBamReader { - - constructor(config, genome) { - - this.config = config; - this.genome = genome; - - const bamReaders = {}; - - config.sources.sequences.forEach(function (chr) { - const queryChr = genome ? genome.getChromosomeName(chr) : chr; - bamReaders[queryChr] = getReader(config, genome, chr); - }); - - this.bamReaders = bamReaders; - - BamUtils.setReaderDefaults(this, config); - } - - async readAlignments(chr, start, end) { - - if (!this.bamReaders.hasOwnProperty(chr)) { - return new AlignmentContainer(chr, start, end, this.config) - } else { - - let reader = this.bamReaders[chr]; - const a = await reader.readAlignments(chr, start, end); - return a - } - } - } - - function getReader(config, genome, chr) { - const tmp = { - url: config.sources.url.replace("$CHR", chr) - }; - if (config.sources.indexURL) { - tmp.indexURL = config.sources.indexURL.replace("$CHR", chr); - } - const bamConfig = Object.assign(config, tmp); - - // TODO -- support non-indexed, htsget, etc - return new BamReader(bamConfig, genome) - } - - /* - * The MIT License (MIT) - * - * Copyright (c) 2016-2017 The Regents of the University of California - * Author: Jim Robinson - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - /** - * Class for reading bam records from an igv.js-flask server backed by pysam. Deprecated. - * - * @param config - * @constructor - */ - const BamWebserviceReader = function (config, genome) { - - this.config = config; - this.genome = genome; - BamUtils.setReaderDefaults(this, config); - - }; - - // Example http://localhost:5000/alignments/?reference=/Users/jrobinso/hg19mini.fa&file=/Users/jrobinso/cram_with_crai_index.cram®ion=1:100-2000 - - BamWebserviceReader.prototype.readAlignments = function (chr, bpStart, bpEnd) { - - var self = this; - - return getHeader.call(self) - - .then(function (header) { - - var queryChr, url; - - queryChr = header.chrAliasTable.hasOwnProperty(chr) ? header.chrAliasTable[chr] : chr; - - url = self.config.url + - "?reference=" + self.config.referenceFile + - "&file=" + self.config.alignmentFile + "" + - "®ion=" + queryChr + ":" + bpStart + "-" + bpEnd; - - - return igvxhr.loadString(url, buildOptions$1(self.config)) - - .then(function (sam) { - - var alignmentContainer; - - header.chrToIndex[queryChr]; - - alignmentContainer = new AlignmentContainer(chr, bpStart, bpEnd, self.config); - - BamUtils.decodeSamRecords(sam, alignmentContainer, queryChr, bpStart, bpEnd, self.filter); - - return alignmentContainer - - }) - - }) - }; - - - // Example http://localhost:5000/alignments/?reference=/Users/jrobinso/hg19mini.fa&file=/Users/jrobinso/cram_with_crai_index.cram&options=-b%20-H - function getHeader() { - - const self = this; - const genome = this.genome; - - if (this.header) { - - return Promise.resolve(this.header) - - } else { - - const url = this.config.url + "?file=" + this.config.alignmentFile + "&options=-b,-H"; - const options = buildOptions$1(this.config); - - return BamUtils.readHeader(url, options, genome) - - .then(function (header) { - - self.header = header; - return header - - }) - } - - } - - /* - * The MIT License (MIT) - * - * Copyright (c) 2016-2017 The Regents of the University of California - * Author: Jim Robinson - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - class HtsgetBamReader extends HtsgetReader { - - constructor(config, genome) { - super(config, genome); - BamUtils.setReaderDefaults(this, config); - } - - - async readAlignments(chr, start, end) { - - if (!this.header) { - const compressedData = await this.readHeaderData(); - const ba = unbgzf(compressedData.buffer); - this.header = BamUtils.decodeBamHeader(ba, this.genome); - this.chrAliasTable = new Map(); - for (let key of Object.keys(this.header.chrAliasTable)) { - this.chrAliasTable.set(key, this.header.chrAliasTable[key]); - } - } - - let queryChr = this.chrAliasTable.has(chr) ? this.chrAliasTable.get(chr) : chr; - - const compressedData = await this.readData(queryChr, start, end); - - // BAM decoding - const ba = unbgzf(compressedData.buffer); - - const chrIdx = this.header.chrToIndex[chr]; - const alignmentContainer = new AlignmentContainer(chr, start, end, this.config); - BamUtils.decodeBamRecords(ba, this.header.size, alignmentContainer, this.header.chrNames, chrIdx, start, end); - alignmentContainer.finish(); - - return alignmentContainer - - } - - } - - /*! For license information please see cram-bundle.js.LICENSE.txt */ - const fn = ()=>{var e={368:function(e,t,r){var n=this&&this.__awaiter||function(e,t,r,n){return new(r||(r=Promise))((function(i,o){function s(e){try{f(n.next(e));}catch(e){o(e);}}function a(e){try{f(n.throw(e));}catch(e){o(e);}}function f(e){var t;e.done?i(e.value):(t=e.value,t instanceof r?t:new r((function(e){e(t);}))).then(s,a);}f((n=n.apply(e,t||[])).next());}))},i=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const o=i(r(4105)),s=i(r(1269)),a=r(597),f=r(3427),h=r(8577);function l(e,t){if(t.some((e=>void 0===e)))throw new h.CramMalformedError("invalid .crai index file");const[r,n,i,o,s,a]=t;e[r]||(e[r]=[]),e[r].push({start:n,span:i,containerStart:o,sliceStart:s,sliceBytes:a});}t.default=class{constructor(e){this.filehandle=(0, f.open)(e.url,e.path,e.filehandle),this._parseCache=new o.default({cache:new s.default({maxSize:1}),fill:(e,t)=>this.parseIndex()});}parseIndex(){const e={};return this.filehandle.readFile().then((e=>31===e[0]&&139===e[1]?(0, a.unzip)(e):e)).then((t=>{if(t.length>4&&21578050===t.readUInt32LE(0))throw new h.CramMalformedError("invalid .crai index file. note: file appears to be a .bai index. this is technically legal but please open a github issue if you need support");let r=[],n="";for(let i=0;i=48&&o<=57||!n&&45===o)n+=String.fromCharCode(o);else if(9===o)r.push(Number.parseInt(n,10)),n="";else if(10===o)r.push(Number.parseInt(n,10)),n="",l(e,r),r=[];else if(13!==o&&32!==o)throw new h.CramMalformedError("invalid .crai index file")}return n&&r.push(Number.parseInt(n,10)),6===r.length&&l(e,r),Object.entries(e).forEach((([t,r])=>{e[t]=r.sort(((e,t)=>e.start-t.start||e.span-t.span));})),e}))}getIndex(e={}){return this._parseCache.get("index",null,e.signal)}hasDataForReferenceSequence(e){return n(this,void 0,void 0,(function*(){return !!(yield this.getIndex())[e]}))}getEntriesForRange(e,t,r){return n(this,void 0,void 0,(function*(){const n=(yield this.getIndex())[e];if(!n)return [];const i=e=>{const n=e.start,i=e.start+e.span;return n>r?-1:i<=t?1:0},o=[];for(let e=0;e{Object.defineProperty(t,"__esModule",{value:!0}),t.default=class{constructor(e,t){this.parameters=e,this.dataType=t;}};},4863:function(e,t,r){var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const i=r(8577),o=n(r(1050)),s=r(1074);class a extends o.default{constructor(e,t){if(super(e,t),"int"!==this.dataType)throw new i.CramUnimplementedError(`${this.dataType} decoding not yet implemented by BETA codec`)}decode(e,t,r,n){return (0, s.getBits)(t.content,n.coreBlock,this.parameters.length)-this.parameters.offset}}t.default=a;},1738:function(e,t,r){var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const i=r(9488),o=n(r(1050));class s extends o.default{constructor(e,t,r){if(super(e,t),this.instantiateCodec=r,"byteArray"!==t)throw new TypeError(`byteArrayLength does not support data type ${t}`)}decode(e,t,r,n){const i=this._getLengthCodec().decode(e,t,r,n),o=this._getDataCodec(),s=new Uint8Array(i);for(let a=0;a(0, i.tinyMemoize)(s,e)));},1405:function(e,t,r){var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const i=r(8577),o=n(r(1050)),s=r(1074);class a extends o.default{constructor(e,t){if(super(e,t),"byteArray"!==t)throw new TypeError(`byteArrayStop codec does not support data type ${t}`)}decode(e,t,r,n){const{blockContentId:o}=this.parameters,s=r[o];if(!s)throw new i.CramMalformedError(`no block found with content ID ${o}`);const a=n.externalBlocks.getCursor(o);return this._decodeByteArray(s,a)}_decodeByteArray(e,t){const r=e.content,{stopByte:n}=this.parameters,i=t.bytePosition;let o=t.bytePosition;for(;r[o]!==n&&o=e.content.length)throw new a.CramBufferOverrunError("attempted to read beyond end of block. this file seems truncated.");return e.content[t.bytePosition++]}}t.default=f;},4229:function(e,t,r){var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const i=r(8577),o=n(r(1050)),s=r(1074);class a extends o.default{constructor(e,t){if(super(e,t),"int"!==this.dataType)throw new i.CramUnimplementedError(`${this.dataType} decoding not yet implemented by GAMMA codec`)}decode(e,t,r,n){let i=1;for(;0===(0, s.getBits)(t.content,n.coreBlock,1);)i+=1;return ((0, s.getBits)(t.content,n.coreBlock,i-1)|1<{Object.defineProperty(t,"__esModule",{value:!0}),t.getBits=t.CramBufferOverrunError=void 0;class r extends Error{}t.CramBufferOverrunError=r,t.getBits=function(e,t,n){let i=0;if(t.bytePosition+(7-t.bitPosition+n)/8>e.length)throw new r("read error during decoding. the file seems to be truncated.");for(let r=n;r;r--)i<<=1,i|=e[t.bytePosition]>>t.bitPosition&1,t.bitPosition-=1,t.bitPosition<0&&(t.bytePosition+=1),t.bitPosition&=7;return i};},2082:function(e,t,r){var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const i=r(8577),o=n(r(1050)),s=r(1074);class a extends o.default{constructor(e,t){if(super(e,t),this.codes={},this.codeBook={},this.sortedByValue=[],this.sortedCodes=[],this.sortedValuesByBitCode=[],this.sortedBitCodes=[],this.sortedBitLengthsByBitCode=[],this.bitCodeToValue=[],!["byte","int"].includes(this.dataType))throw new TypeError(`${this.dataType} decoding not yet implemented by HUFFMAN_INT codec`);this.buildCodeBook(),this.buildCodes(),this.buildCaches(),0===this.sortedCodes[0].bitLength&&(this._decode=this._decodeZeroLengthCode);}buildCodeBook(){let e=new Array(this.parameters.numCodes);for(let t=0;te.bitLength-t.bitLength||e.symbol-t.symbol)),this.codeBook={},e.forEach((e=>{this.codeBook[e.bitLength]||(this.codeBook[e.bitLength]=[]),this.codeBook[e.bitLength].push(e.symbol);}));}buildCodes(){this.codes={};let e=0,t=-1;Object.entries(this.codeBook).forEach((([r,n])=>{const o=parseInt(r,10);n.forEach((r=>{const n={bitLength:o,value:r,bitCode:0};t+=1;const s=o-e;if(t<<=s,n.bitCode=t,e+=s,function(e){let t=e-(e>>1)&1431655765;return t=(858993459&t)+(t>>2&858993459),16843009*(t+(t>>4)&252645135)>>24}(t)>o)throw new i.CramMalformedError("Symbol out of range");this.codes[r]=n;}));}));}buildCaches(){this.sortedCodes=Object.values(this.codes).sort(((e,t)=>e.bitLength-t.bitLength||e.bitCode-t.bitCode)),this.sortedByValue=Object.values(this.codes).sort(((e,t)=>e.value-t.value)),this.sortedValuesByBitCode=this.sortedCodes.map((e=>e.value)),this.sortedBitCodes=this.sortedCodes.map((e=>e.bitCode)),this.sortedBitLengthsByBitCode=this.sortedCodes.map((e=>e.bitLength));const e=Math.max(...this.sortedBitCodes);this.bitCodeToValue=new Array(e+1).fill(-1);for(let e=0;e-1&&this.sortedBitLengthsByBitCode[r]===t)return this.sortedValuesByBitCode[r];for(let r=e;this.sortedCodes[r+1].bitLength===t&&r{Object.defineProperty(t,"__esModule",{value:!0}),t.default={CRAM_FLAG_PRESERVE_QUAL_SCORES:1,CRAM_FLAG_DETACHED:2,CRAM_FLAG_MATE_DOWNSTREAM:4,CRAM_FLAG_NO_SEQ:8,CRAM_FLAG_MASK:15,CRAM_M_REVERSE:1,CRAM_M_UNMAP:2,BAM_FPAIRED:1,BAM_FPROPER_PAIR:2,BAM_FUNMAP:4,BAM_FMUNMAP:8,BAM_FREVERSE:16,BAM_FMREVERSE:32,BAM_FREAD1:64,BAM_FREAD2:128,BAM_FSECONDARY:256,BAM_FQCFAIL:512,BAM_FDUP:1024,BAM_FSUPPLEMENTARY:2048,BAM_CMATCH:0,BAM_CINS:1,BAM_CDEL:2,BAM_CREF_SKIP:3,BAM_CSOFT_CLIP:4,BAM_CHARD_CLIP:5,BAM_CPAD:6,BAM_CEQUAL:7,BAM_CDIFF:8,BAM_CBACK:9,BAM_CIGAR_STR:"MIDNSHP:XB",BAM_CIGAR_SHIFT:4,BAM_CIGAR_MASK:15,BAM_CIGAR_TYPE:246183};},8543:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:!0});const n=r(8772),i=r(8577),o={BF:"int",CF:"int",RI:"int",RL:"int",AP:"int",RG:"int",MF:"int",NS:"int",NP:"int",TS:"int",NF:"int",TC:"byte",TN:"int",FN:"int",FC:"byte",FP:"int",BS:"byte",IN:"byteArray",SC:"byteArray",DL:"int",BA:"byte",BB:"byteArray",RS:"int",PD:"int",HC:"int",MQ:"int",RN:"byteArray",QS:"byte",QQ:"byteArray",TL:"int"};t.default=class{constructor(e){this.dataSeriesCodecCache={},this.tagCodecCache={},this.tagEncoding={},this.readNamesIncluded=e.preservation.RN,this.APdelta=e.preservation.AP,this.referenceRequired=!!e.preservation.RR,this.tagIdsDictionary=e.preservation.TD,this.substitutionMatrix=function(e){const t=new Array(5);for(let e=0;e<5;e+=1)t[e]=new Array(4);return t[0][e[0]>>6&3]="C",t[0][e[0]>>4&3]="G",t[0][e[0]>>2&3]="T",t[0][e[0]>>0&3]="N",t[1][e[1]>>6&3]="A",t[1][e[1]>>4&3]="G",t[1][e[1]>>2&3]="T",t[1][e[1]>>0&3]="N",t[2][e[2]>>6&3]="A",t[2][e[2]>>4&3]="C",t[2][e[2]>>2&3]="T",t[2][e[2]>>0&3]="N",t[3][e[3]>>6&3]="A",t[3][e[3]>>4&3]="C",t[3][e[3]>>2&3]="G",t[3][e[3]>>0&3]="N",t[4][e[4]>>6&3]="A",t[4][e[4]>>4&3]="C",t[4][e[4]>>2&3]="G",t[4][e[4]>>0&3]="T",t}(e.preservation.SM),this.dataSeriesEncoding=e.dataSeriesEncoding,this.tagEncoding=e.tagEncoding,this.preservation=e.preservation,this._size=e._size,this._endPosition=e._endPosition;}getCodecForTag(e){if(!this.tagCodecCache[e]){const t=this.tagEncoding[e];t&&(this.tagCodecCache[e]=(0, n.instantiateCodec)(t,"byteArray"));}return this.tagCodecCache[e]}getTagNames(e){return this.tagIdsDictionary[e]}getCodecForDataSeries(e){let t=this.dataSeriesCodecCache[e];if(void 0===t){const r=this.dataSeriesEncoding[e];if(r){const s=o[e];if(!s)throw new i.CramMalformedError(`data series name ${e} not defined in file compression header`);t=(0, n.instantiateCodec)(r,s),this.dataSeriesCodecCache[e]=t;}}return t}toJSON(){const e={};return Object.keys(this).forEach((t=>{/Cache$/.test(t)||(e[t]=this[t]);})),e}};},6284:function(e,t,r){var n=this&&this.__awaiter||function(e,t,r,n){return new(r||(r=Promise))((function(i,o){function s(e){try{f(n.next(e));}catch(e){o(e);}}function a(e){try{f(n.throw(e));}catch(e){o(e);}}function f(e){var t;e.done?i(e.value):(t=e.value,t instanceof r?t:new r((function(e){e(t);}))).then(s,a);}f((n=n.apply(e,t||[])).next());}))},i=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const o=r(8577),s=r(9488),a=i(r(6601)),f=i(r(8543));class h{constructor(e,t){this.file=e,this.filePosition=t;}getHeader(){return this._readContainerHeader(this.filePosition)}getCompressionHeaderBlock(){return n(this,void 0,void 0,(function*(){if(!(yield this.getHeader()).numRecords)return null;const e=yield this.file.getSectionParsers(),t=yield this.getFirstBlock();if(void 0===t)return;if("COMPRESSION_HEADER"!==t.contentType)throw new o.CramMalformedError(`invalid content type ${t.contentType} in what is supposed to be the compression header block`);const r=(0, s.parseItem)(t.content,e.cramCompressionHeader.parser,0,t.contentPosition);return Object.assign(Object.assign({},t),{parsedContent:r})}))}getFirstBlock(){return n(this,void 0,void 0,(function*(){const e=yield this.getHeader();return this.file.readBlock(e._endPosition)}))}getCompressionScheme(){return n(this,void 0,void 0,(function*(){const e=yield this.getCompressionHeaderBlock();if(e)return new f.default(e.parsedContent)}))}getSlice(e,t){return new a.default(this,e,t)}_readContainerHeader(e){return n(this,void 0,void 0,(function*(){const t=yield this.file.getSectionParsers(),{cramContainerHeader1:r,cramContainerHeader2:n}=t,{size:i}=yield this.file.stat();if(e>=i)return;const o=Buffer.allocUnsafe(r.maxLength);yield this.file.read(o,0,r.maxLength,e);const a=(0, s.parseItem)(o,r.parser),f=(0, s.itf8Size)(a.numLandmarks);if(e+a.length>=i)return void console.warn(`${this.file}: container header at ${e} indicates that the container has length ${a.length}, which extends beyond the length of the file. Skipping this container.`);const h=Buffer.allocUnsafe(n.maxLength(a.numLandmarks));yield this.file.read(h,0,n.maxLength(a.numLandmarks),e+a._size-f);const l=(0, s.parseItem)(h,n.parser);return this.file.validateChecksums&&void 0!==l.crc32&&(yield this.file.checkCrc32(e,a._size+l._size-f-4,l.crc32,`container header beginning at position ${e}`)),Object.assign(a,l,{_size:a._size+l._size-f,_endPosition:a._size+l._size-f+e})}))}}t.default=h,"getHeader getCompressionHeaderBlock getCompressionScheme".split(" ").forEach((e=>(0, s.tinyMemoize)(h,e)));},5457:function(e,t,r){var n=this&&this.__awaiter||function(e,t,r,n){return new(r||(r=Promise))((function(i,o){function s(e){try{f(n.next(e));}catch(e){o(e);}}function a(e){try{f(n.throw(e));}catch(e){o(e);}}function f(e){var t;e.done?i(e.value):(t=e.value,t instanceof r?t:new r((function(e){e(t);}))).then(s,a);}f((n=n.apply(e,t||[])).next());}))},i=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const o=r(597),s=i(r(2779)),a=i(r(1269)),f=r(8577),h=i(r(9675)),l=r(6141),u=i(r(3498)),c=i(r(6284)),d=r(3427),p=r(9488),g=r(7578);class m{constructor(e){var t;if(this.file=(0, d.open)(e.url,e.path,e.filehandle),this.validateChecksums=!0,this.fetchReferenceSequenceCallback=e.seqFetch,this.options={checkSequenceMD5:e.checkSequenceMD5,cacheSize:null!==(t=e.cacheSize)&&void 0!==t?t:2e4},this.featureCache=new a.default({maxSize:this.options.cacheSize}),function(){const e=new Uint32Array([287454020]),t=new Uint8Array(e.buffer);return 68===t[0]?0:17===t[0]?1:2}()>0)throw new Error("Detected big-endian machine, may be unable to run")}read(e,t,r,n){return this.file.read(e,t,r,n)}stat(){return this.file.stat()}getDefinition(){return n(this,void 0,void 0,(function*(){const e=Buffer.allocUnsafe(l.cramFileDefinition.maxLength);yield this.file.read(e,0,l.cramFileDefinition.maxLength,0);const t=l.cramFileDefinition.parser.parse(e).result;if(2!==t.majorVersion&&3!==t.majorVersion)throw new f.CramUnimplementedError(`CRAM version ${t.majorVersion} not supported`);return t}))}getSamHeader(){return n(this,void 0,void 0,(function*(){const e=yield this.getContainerById(0);if(!e)throw new f.CramMalformedError("file contains no containers");const t=yield e.getFirstBlock();if(void 0===t)return (0, g.parseHeaderText)("");const r=t.content,n=r.readInt32LE(0),i=r.toString("utf8",4,4+n);return this.header=i,(0, g.parseHeaderText)(i)}))}getHeaderText(){return n(this,void 0,void 0,(function*(){return yield this.getSamHeader(),this.header}))}getSectionParsers(){return n(this,void 0,void 0,(function*(){const{majorVersion:e}=yield this.getDefinition();return (0, l.getSectionParsers)(e)}))}getContainerById(e){return n(this,void 0,void 0,(function*(){const t=yield this.getSectionParsers();let r=t.cramFileDefinition.maxLength;const{size:n}=yield this.file.stat(),{cramContainerHeader1:i}=t;let o;for(let t=0;t<=e;t+=1){if(r+i.maxLength+8>=n)return;o=this.getContainerAtPosition(r);const s=yield o.getHeader();if(!s)throw new f.CramMalformedError(`container ${e} not found in file`);if(0===t){r=s._endPosition;for(let e=0;e=n)return;const i=Buffer.allocUnsafe(r.maxLength);return yield this.file.read(i,0,r.maxLength,e),(0, p.parseItem)(i,r.parser,0,e)}))}_parseSection(e,t,r=e.maxLength,i){return n(this,void 0,void 0,(function*(){let n;if(i)n=i;else {const{size:e}=yield this.file.stat();if(t+r>=e)return;n=Buffer.allocUnsafe(r),yield this.file.read(n,0,r,t);}const o=(0, p.parseItem)(n,e.parser,0,t);if(o._size!==r)throw new f.CramMalformedError(`section read error: requested size ${r} does not equal parsed size ${o._size}`);return o}))}_uncompress(e,t,r){if("gzip"===e)(0, o.unzip)(t).copy(r);else if("bzip2"===e){const e=bzip2.array(t);let n,i=bzip2.header(e),o=0;do{n=bzip2.decompress(e,i),-1!=n&&(Buffer.from(n).copy(r,o),o+=n.length,i-=n.length);}while(-1!=n)}else if("rans"===e)(0, h.default)(t,r);else if("rans4x16"===e)u.default.r4x16_uncompress(t,r);else if("arith"===e)u.default.arith_uncompress(t,r);else if("fqzcomp"===e)u.default.fqzcomp_uncompress(t,r);else {if("tok3"!==e)throw new f.CramUnimplementedError(`${e} decompression not yet implemented`);u.default.tok3_uncompress(t,r);}}readBlock(e){return n(this,void 0,void 0,(function*(){const{majorVersion:t}=yield this.getDefinition(),r=yield this.getSectionParsers(),n=yield this.readBlockHeader(e);if(void 0===n)return;const i=n._endPosition,o=Buffer.allocUnsafe(n.uncompressedSize),s=Object.assign(Object.assign({},n),{_endPosition:i,contentPosition:i,content:o});if("raw"!==n.compressionMethod){const e=Buffer.allocUnsafe(n.compressedSize);yield this.read(e,0,n.compressedSize,i),this._uncompress(n.compressionMethod,e,o);}else yield this.read(o,0,n.uncompressedSize,i);if(t>=3){const t=yield this._parseSection(r.cramBlockCrc32,i+n.compressedSize);if(void 0===t)return;s.crc32=t.crc32,this.validateChecksums&&(yield this.checkCrc32(e,n._size+n.compressedSize,t.crc32,"block data")),s._endPosition=t._endPosition,s._size=s.compressedSize+r.cramBlockCrc32.maxLength;}else s._endPosition=i+s.compressedSize,s._size=s.compressedSize;return s}))}}t.default=m,"getDefinition getSectionParsers getSamHeader".split(" ").forEach((e=>(0, p.tinyMemoize)(m,e)));},8222:function(e,t,r){var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0}),t.CramRecord=void 0;const i=n(r(5457));var o=r(8631);Object.defineProperty(t,"CramRecord",{enumerable:!0,get:function(){return n(o).default}}),t.default=i.default;},8631:function(e,t,r){var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0}),t.MateFlagsDecoder=t.CramFlagsDecoder=t.BamFlagsDecoder=t.MateFlags=t.CramFlags=t.BamFlags=void 0;const i=n(r(2615)),o={a:0,A:0,c:1,C:1,g:2,G:2,t:3,T:3,n:4,N:4};function s(e){const t={};for(const[r,n]of e)t["is"+n]=e=>!!(e&r),t["set"+n]=e=>e|r;return t}t.BamFlags=[[1,"Paired"],[2,"ProperlyPaired"],[4,"SegmentUnmapped"],[8,"MateUnmapped"],[16,"ReverseComplemented"],[32,"MateReverseComplemented"],[64,"Read1"],[128,"Read2"],[256,"Secondary"],[512,"FailedQc"],[1024,"Duplicate"],[2048,"Supplementary"]],t.CramFlags=[[1,"PreservingQualityScores"],[2,"Detached"],[4,"WithMateDownstream"],[8,"DecodeSequenceAsStar"]],t.MateFlags=[[1,"OnNegativeStrand"],[2,"Unmapped"]],t.BamFlagsDecoder=s(t.BamFlags),t.CramFlagsDecoder=s(t.CramFlags),t.MateFlagsDecoder=s(t.MateFlags),t.default=class{constructor({flags:e,cramFlags:t,readLength:r,mappingQuality:n,lengthOnRef:i,qualityScores:o,mateRecordNumber:s,readBases:a,readFeatures:f,mateToUse:h,readGroupId:l,readName:u,sequenceId:c,uniqueId:d,templateSize:p,alignmentStart:g,tags:m}){this.flags=e,this.cramFlags=t,this.readLength=r,this.mappingQuality=n,this.lengthOnRef=i,this.qualityScores=o,a&&(this.readBases=a),this.readGroupId=l,this.readName=u,this.sequenceId=c,this.uniqueId=d,this.templateSize=p,this.alignmentStart=g,this.tags=m,f&&(this.readFeatures=f),h&&(this.mate={flags:h.mateFlags,readName:h.mateReadName,sequenceId:h.mateSequenceId,alignmentStart:h.mateAlignmentStart}),s&&(this.mateRecordNumber=s);}isPaired(){return !!(this.flags&i.default.BAM_FPAIRED)}isProperlyPaired(){return !!(this.flags&i.default.BAM_FPROPER_PAIR)}isSegmentUnmapped(){return !!(this.flags&i.default.BAM_FUNMAP)}isMateUnmapped(){return !!(this.flags&i.default.BAM_FMUNMAP)}isReverseComplemented(){return !!(this.flags&i.default.BAM_FREVERSE)}isMateReverseComplemented(){return !!(this.flags&i.default.BAM_FMREVERSE)}isRead1(){return !!(this.flags&i.default.BAM_FREAD1)}isRead2(){return !!(this.flags&i.default.BAM_FREAD2)}isSecondary(){return !!(this.flags&i.default.BAM_FSECONDARY)}isFailedQc(){return !!(this.flags&i.default.BAM_FQCFAIL)}isDuplicate(){return !!(this.flags&i.default.BAM_FDUP)}isSupplementary(){return !!(this.flags&i.default.BAM_FSUPPLEMENTARY)}isDetached(){return !!(this.cramFlags&i.default.CRAM_FLAG_DETACHED)}hasMateDownStream(){return !!(this.cramFlags&i.default.CRAM_FLAG_MATE_DOWNSTREAM)}isPreservingQualityScores(){return !!(this.cramFlags&i.default.CRAM_FLAG_PRESERVE_QUAL_SCORES)}isUnknownBases(){return !!(this.cramFlags&i.default.CRAM_FLAG_NO_SEQ)}getReadBases(){if(!this.readBases&&this._refRegion){const e=function(e,t){if(!e.lengthOnRef&&!e.readLength)return null;if(e.isUnknownBases())return null;const r=e.alignmentStart-t.start;if(!e.readFeatures)return t.seq.substr(r,e.lengthOnRef).toUpperCase();let n="",i=r,o=0;for(;n.lengththis.mate.alignmentStart&&o>0&&(o=-o),o>0?(i[0]=e,i[1]=r,i[2]=t,i[3]=n):(i[2]=e,i[3]=r,i[0]=t,i[1]=n),i.join("")}return null}addReferenceSequence(e,t){this.readFeatures&&this.readFeatures.forEach((r=>{"X"===r.code&&function(e,t,r,n){if(!t)return;const i=n.refPos-t.start,s=t.seq.charAt(i);s&&(n.ref=s);let a=o[s];void 0===a&&(a=4);const f=r.substitutionMatrix[a][n.data];f&&(n.sub=f);}(0,e,t,r);})),!this.readBases&&e.start<=this.alignmentStart&&e.end>=this.alignmentStart+(this.lengthOnRef||this.readLength)-1&&(this._refRegion=e);}toJSON(){const e={};return Object.keys(this).forEach((t=>{"_"!==t.charAt(0)&&(e[t]=this[t]);})),e.readBases=this.getReadBases(),e}};},6141:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.getSectionParsers=t.cramFileDefinition=t.isMappedSliceHeader=void 0;const n=r(9996),i=(new n.Parser).itf8(),o={parser:(new n.Parser).string("magic",{length:4}).uint8("majorVersion").uint8("minorVersion").string("fileId",{length:20,stripNull:!0}),maxLength:26};t.cramFileDefinition=o;const s={parser:(new n.Parser).uint8("compressionMethod",{formatter:e=>{const t=["raw","gzip","bzip2","lzma","rans","rans4x16","arith","fqzcomp","tok3"][e];if(!t)throw new Error(`compression method number ${e} not implemented`);return t}}).uint8("contentType",{formatter:e=>{const t=["FILE_HEADER","COMPRESSION_HEADER","MAPPED_SLICE_HEADER","UNMAPPED_SLICE_HEADER","EXTERNAL_DATA","CORE_DATA"][e];if(!t)throw new Error(`invalid block content type id ${e}`);return t}}).itf8("contentId").itf8("compressedSize").itf8("uncompressedSize"),maxLength:17},a={parser:(new n.Parser).uint32("crc32"),maxLength:4},f=(new n.Parser).itf8("size").buffer("ents",{length:"size",formatter:e=>{function t(t,r){const n=e.toString("utf8",t,r),i=[];for(let e=0;ei&&n.push(t(i,r)),n}}),h=(new n.Parser).uint8(null,{formatter:e=>!!e}),l=(new n.Parser).itf8("mapSize").itf8("mapCount").array("ents",{length:"mapCount",type:(new n.Parser).string("key",{length:2,stripNull:!1}).choice("value",{tag:"key",choices:{MI:h,UI:h,PI:h,RN:h,AP:h,RR:h,SM:(new n.Parser).array(null,{type:"uint8",length:5}),TD:(new n.Parser).nest(null,{type:f,formatter:e=>e.ents})}})});function u(e){const t={};for(let r=0;r=3?(r=r.ltf8("recordCounter"),t+=9):2===e&&(r=r.itf8("recordCounter"),t+=5),r=r.itf8("numBlocks").itf8("numContentIds").array("contentIds",{type:i,length:"numContentIds"}),t+=10,e>=2&&(r=r.array("md5",{type:"uint8",length:16}),t+=16),{parser:r,maxLength:e=>t+5*e}},cramMappedSliceHeader(e){let t=(new n.Parser).itf8("refSeqId").itf8("refSeqStart").itf8("refSeqSpan").itf8("numRecords"),r=20;return e>=3?(t=t.ltf8("recordCounter"),r+=9):2===e&&(t=t.itf8("recordCounter"),r+=5),t=t.itf8("numBlocks").itf8("numContentIds").array("contentIds",{type:i,length:"numContentIds"}).itf8("refBaseBlockId"),r+=15,e>=2&&(t=t.array("md5",{type:"uint8",length:16}),r+=16),{parser:t,maxLength:e=>r+5*e}},cramEncoding:e=>({parser:(new n.Parser).namely("cramEncoding").itf8("codecId").itf8("parametersBytes").choice("parameters",{tag:"codecId",choices:{0:new n.Parser,1:(new n.Parser).itf8("blockContentId"),2:(new n.Parser).itf8("offset").itf8("M"),3:n.Parser.start().itf8("numCodes").array("symbols",{length:"numCodes",type:i}).itf8("numLengths").array("bitLengths",{length:"numLengths",type:i}),4:n.Parser.start().nest("lengthsEncoding",{type:"cramEncoding"}).nest("valuesEncoding",{type:"cramEncoding"}),5:(new n.Parser).uint8("stopByte").itf8("blockContentId"),6:(new n.Parser).itf8("offset").itf8("length"),7:(new n.Parser).itf8("offset").itf8("K"),8:(new n.Parser).itf8("offset").itf8("log2m"),9:(new n.Parser).itf8("offset")}})}),cramDataSeriesEncodingMap(e){return (new n.Parser).itf8("mapSize").itf8("mapCount").array("ents",{length:"mapCount",type:(new n.Parser).string("key",{length:2,stripNull:!1}).nest("value",{type:this.cramEncoding(e).parser})})},cramTagEncodingMap(e){return (new n.Parser).itf8("mapSize").itf8("mapCount").array("ents",{length:"mapCount",type:(new n.Parser).itf8("key",{formatter:e=>String.fromCharCode(e>>16&255)+String.fromCharCode(e>>8&255)+String.fromCharCode(255&e)}).nest("value",{type:this.cramEncoding(e).parser})})},cramCompressionHeader(e){let t=new n.Parser;return t=t.nest("preservation",{type:l,formatter:u}).nest("dataSeriesEncoding",{type:this.cramDataSeriesEncodingMap(e),formatter:u}).nest("tagEncoding",{type:this.cramTagEncodingMap(e),formatter:u}),{parser:t}},cramContainerHeader1(e){let t=(new n.Parser).int32("length").itf8("refSeqId").itf8("refSeqStart").itf8("alignmentSpan").itf8("numRecords"),r=24;return e>=3?(t=t.ltf8("recordCounter"),r+=9):2===e&&(t=t.itf8("recordCounter"),r+=5),e>1&&(t=t.ltf8("numBases"),r+=9),t=t.itf8("numBlocks").itf8("numLandmarks"),r+=10,{parser:t,maxLength:r}},cramContainerHeader2(e){let t=(new n.Parser).itf8("numLandmarks").array("landmarks",{type:(new n.Parser).itf8(),length:"numLandmarks"}),r=0;return e>=3&&(t=t.uint32("crc32"),r=4),{parser:t,maxLength:e=>5+5*e+r}}};t.getSectionParsers=function(e){const t=Object.assign({},c);return Object.keys(d).forEach((r=>{t[r]=d[r](e);})),t};},3757:function(e,t,r){var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const i=n(r(3720)),o=r(8577),s=r(8631),a=r(6141);function f(e){let t="";for(let r=0;r1&&-2===n.parsedContent.refSeqId?t("RI"):n.parsedContent.refSeqId;const y=t("RL");let b=t("AP");r.APdelta&&(b+=u.lastAlignmentStart),u.lastAlignmentStart=b;const v=t("RG");let w,_,B,E;if(r.readNamesIncluded&&(w=f(t("RN"))),s.CramFlagsDecoder.isDetached(g)){const e=t("MF");let n;r.readNamesIncluded||(n=f(t("RN")),w=n);const i=t("NS"),o=t("NP");(e||i>-1)&&(_={mateFlags:e,mateSequenceId:i,mateAlignmentStart:o,mateReadName:n}),B=t("TS"),s.MateFlagsDecoder.isUnmapped(e)&&(p=s.BamFlagsDecoder.setMateUnmapped(p)),s.MateFlagsDecoder.isOnNegativeStrand(e)&&(p=s.BamFlagsDecoder.setMateReverseComplemented(p));}else s.CramFlagsDecoder.isWithMateDownstream(g)&&(E=t("NF")+d+1);const S=t("TL");if(S<0)throw new o.CramMalformedError("invalid TL index");const A={},C=r.getTagNames(S),R=C.length;for(let t=0;t1?"SC":"IN"],X:["number","BS"],D:["number","DL"],I:["string","IN"],i:["character","BA"],b:["string","BB"],q:["numArray","QQ"],Q:["number","QS"],H:["number","HC"],P:["number","PD"],N:["number","RS"]}[t];if(!l)throw new o.CramMalformedError(`invalid read feature code "${t}"`);let u=h(l);const c={B:["number","QS"]}[t];c&&(u=[u,h(c)]),s+=n;const d=s;a+=n;const p=a;"D"===t||"N"===t?a+=u:"I"===t||"S"===t?a-=u.length:"i"===t&&(a-=1),f[e]={code:t,pos:d,refPos:p,data:u};}return f}(b,e,t,0,c)),x=y,k)for(const{code:e,data:t}of k)"D"===e||"N"===e?x+=t:"I"===e||"S"===e?x-=t.length:"i"===e&&(x-=1);if(Number.isNaN(x)&&(console.warn(`${w||`${m}:${b}`} record has invalid read features`),x=y),I=t("MQ"),s.CramFlagsDecoder.isPreservingQualityScores(g)){M=new Array(y);for(let e=0;e=0){const i=e[r.mateRecordNumber];if(!i)throw new o.CramMalformedError("intra-slice mate record not found, this file seems malformed");n.push(...t(i));}return n}(r),i=n.map((e=>e.alignmentStart)),s=n.map((e=>e.alignmentStart+e.readLength-1)),a=Math.max(...s)-Math.min(...i)+1;a>=0&&n.forEach((e=>{if(void 0!==e.templateLength)throw new o.CramMalformedError("mate pair group has some members that have template lengths already, this file seems malformed");e.templateLength=a;}));}(e,0,r):function(e,t){const r=Math.min(e.alignmentStart,t.alignmentStart),n=Math.max(e.alignmentStart+e.readLength-1,t.alignmentStart+t.readLength-1)-r+1;e.templateLength=n,t.templateLength=n;}(r,n)),delete r.mateRecordNumber;}class d{constructor(e,t,r){this.container=e,this.containerPosition=t,this.file=e.file;}getHeader(){return n(this,void 0,void 0,(function*(){const e=yield this.file.getSectionParsers(),t=yield this.container.getHeader(),r=yield this.file.readBlock(t._endPosition+this.containerPosition);if(void 0===r)throw new Error;if("MAPPED_SLICE_HEADER"===r.contentType){const n=(0, s.parseItem)(r.content,e.cramMappedSliceHeader.parser,0,t._endPosition);return Object.assign(Object.assign({},r),{parsedContent:n})}if("UNMAPPED_SLICE_HEADER"===r.contentType){const n=(0, s.parseItem)(r.content,e.cramUnmappedSliceHeader.parser,0,t._endPosition);return Object.assign(Object.assign({},r),{parsedContent:n})}throw new o.CramMalformedError(`error reading slice header block, invalid content type ${r.contentType}`)}))}getBlocks(){return n(this,void 0,void 0,(function*(){const e=yield this.getHeader();let t=e._endPosition;const r=new Array(e.parsedContent.numBlocks);for(let e=0;e{"EXTERNAL_DATA"===e.contentType&&(t[e.contentId]=e);})),t}))}getBlockByContentId(e){return n(this,void 0,void 0,(function*(){return (yield this._getBlocksContentIdIndex())[e]}))}getReferenceRegion(){return n(this,void 0,void 0,(function*(){const e=(yield this.getHeader()).parsedContent;if(!(0, l.isMappedSliceHeader)(e))throw new Error;if(e.refSeqId<0)return;const t=yield this.container.getCompressionScheme();if(void 0===t)throw new Error;if(e.refBaseBlockId>=0){const t=yield this.getBlockByContentId(e.refBaseBlockId);if(!t)throw new o.CramMalformedError("embedded reference specified, but reference block does not exist");return {seq:t.data.toString("utf8"),start:e.refSeqStart,end:e.refSeqStart+e.refSeqSpan-1,span:e.refSeqSpan}}if(t.referenceRequired||this.file.fetchReferenceSequenceCallback){if(!this.file.fetchReferenceSequenceCallback)throw new Error("reference sequence not embedded, and seqFetch callback not provided, cannot fetch reference sequence");const t=yield this.file.fetchReferenceSequenceCallback(e.refSeqId,e.refSeqStart,e.refSeqStart+e.refSeqSpan-1);if(t.length!==e.refSeqSpan)throw new o.CramArgumentError("seqFetch callback returned a reference sequence of the wrong length");return {seq:t,start:e.refSeqStart,end:e.refSeqStart+e.refSeqSpan-1,span:e.refSeqSpan}}}))}getAllRecords(){return this.getRecords((()=>!0))}_fetchRecords(){return n(this,void 0,void 0,(function*(){const{majorVersion:e}=yield this.file.getDefinition(),t=yield this.container.getCompressionScheme();if(void 0===t)throw new Error;const r=yield this.getHeader();if(void 0===r)throw new Error;const n=yield this._getBlocksContentIdIndex();if(e>1&&this.file.options.checkSequenceMD5&&(0, l.isMappedSliceHeader)(r.parsedContent)&&r.parsedContent.refSeqId>=0&&"0000000000000000"!==r.parsedContent.md5.join("")){const e=yield this.getReferenceRegion();if(e){const{seq:t,start:n,end:i}=e,a=(0, s.sequenceMD5)(t),f=r.parsedContent.md5.map((e=>(e<16?"0":"")+e.toString(16))).join("");if(a!==f)throw new o.CramMalformedError(`MD5 checksum reference mismatch for ref ${r.parsedContent.refSeqId} pos ${n}..${i}. recorded MD5: ${f}, calculated MD5: ${a}`)}}const i=yield this.getCoreDataBlock(),a={lastAlignmentStart:(0, l.isMappedSliceHeader)(r.parsedContent)?r.parsedContent.refSeqStart:0,coreBlock:{bitPosition:7,bytePosition:0},externalBlocks:{map:new Map,getCursor(e){let t=this.map.get(e);return void 0===t&&(t={bitPosition:7,bytePosition:0},this.map.set(e,t)),t}}},d=e=>{const r=t.getCodecForDataSeries(e);if(!r)throw new o.CramMalformedError(`no codec defined for ${e} data series`);return r.decode(this,i,n,a)};let p=new Array(r.parsedContent.numRecords);for(let o=0;o!!e));break}throw e}for(let e=0;e=0&&c(p,e,p[e],p[t]);}return p}))}getRecords(e){return n(this,void 0,void 0,(function*(){const t=this.container.filePosition+this.containerPosition;let r=this.file.featureCache.get(t.toString());r||(r=this._fetchRecords(),this.file.featureCache.set(t.toString(),r));const i=(yield r).filter(e);if(i.length&&this.file.fetchReferenceSequenceCallback){const e=yield this.getHeader();if((0, l.isMappedSliceHeader)(e.parsedContent)&&(e.parsedContent.refSeqId>=0||-2===e.parsedContent.refSeqId)){const t=e.parsedContent.refSeqId>=0?e.parsedContent.refSeqId:void 0,r=yield this.container.getCompressionScheme();if(void 0===r)throw new Error;const o={};for(let e=0;en.end&&(n.end=s),i[e].alignmentStartn(this,void 0,void 0,(function*(){-1!==e.id&&e.start<=e.end&&(e.seq=yield this.file.fetchReferenceSequenceCallback(e.id,e.start,e.end));})))));for(let e=0;e(0, s.tinyMemoize)(d,e)));},9488:function(e,t,r){var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0}),t.sequenceMD5=t.tinyMemoize=t.parseItem=t.parseItf8=t.itf8Size=void 0;const i=n(r(2568)),o=r(1074);t.itf8Size=function(e){return -128&e?-16384&e?-2097152&e?-268435456&e?5:4:3:2:1},t.parseItf8=function(e,t){let r=t;const n=e[r];let i;if(n<128?(i=n,r+=1):n<192?(i=16383&(n<<8|e[r+1]),r+=2):n<224?(i=2097151&(n<<16|e[r+1]<<8|e[r+2]),r+=3):n<240?(i=268435455&(n<<24|e[r+1]<<16|e[r+2]<<8|e[r+3]),r+=4):(i=(15&n)<<28|e[r+1]<<20|e[r+2]<<12|e[r+3]<<4|15&e[r+4],r+=5),r>e.length)throw new o.CramBufferOverrunError("Attempted to read beyond end of buffer; this file seems truncated.");return [i,r-t]},t.parseItem=function(e,t,r=0,n=0){const{offset:i,result:o}=t.parse(e);return Object.assign(Object.assign({},o),{_endPosition:i+n,_size:i-r})},t.tinyMemoize=function(e,t){const r=e.prototype[t],n=`_memo_${t}`;e.prototype[t]=function(){if(!(n in this)){const e=r.call(this);this[n]=e,Promise.resolve(e).catch((()=>{delete this[n];}));}return this[n]};},t.sequenceMD5=function(e){return (0, i.default)(e.toUpperCase().replace(/[^\x21-\x7e]/g,""))};},8577:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.CramArgumentError=t.CramSizeLimitError=t.CramMalformedError=t.CramUnimplementedError=t.CramError=void 0;class r extends Error{}t.CramError=r;class n extends Error{}t.CramUnimplementedError=n,t.CramMalformedError=class extends r{},t.CramSizeLimitError=class extends r{},t.CramArgumentError=class extends r{};},5590:function(e,t,r){var n=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r);var i=Object.getOwnPropertyDescriptor(t,r);i&&!("get"in i?!t.__esModule:i.writable||i.configurable)||(i={enumerable:!0,get:function(){return t[r]}}),Object.defineProperty(e,n,i);}:function(e,t,r,n){void 0===n&&(n=r),e[n]=t[r];}),i=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t});}:function(e,t){e.default=t;}),o=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var r in e)"default"!==r&&Object.prototype.hasOwnProperty.call(e,r)&&n(t,e,r);return i(t,e),t},s=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0}),t.CramRecord=t.CraiIndex=t.IndexedCramFile=t.CramFile=void 0;const a=o(r(8222));t.CramFile=a.default,Object.defineProperty(t,"CramRecord",{enumerable:!0,get:function(){return a.CramRecord}});const f=s(r(946));t.IndexedCramFile=f.default;const h=s(r(368));t.CraiIndex=h.default;},946:function(e,t,r){var n=this&&this.__awaiter||function(e,t,r,n){return new(r||(r=Promise))((function(i,o){function s(e){try{f(n.next(e));}catch(e){o(e);}}function a(e){try{f(n.throw(e));}catch(e){o(e);}}function f(e){var t;e.done?i(e.value):(t=e.value,t instanceof r?t:new r((function(e){e(t);}))).then(s,a);}f((n=n.apply(e,t||[])).next());}))},i=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const o=r(8577),s=i(r(8222));t.default=class{constructor(e){if(e.cram?this.cram=e.cram:this.cram=new s.default({url:e.cramUrl,path:e.cramPath,filehandle:e.cramFilehandle,seqFetch:e.seqFetch,checkSequenceMD5:e.checkSequenceMD5,cacheSize:e.cacheSize}),!(this.cram instanceof s.default))throw new Error("invalid arguments: no cramfile");if(this.index=e.index,!this.index.getEntriesForRange)throw new Error("invalid arguments: not an index");this.fetchSizeLimit=e.fetchSizeLimit||3e6;}getRecordsForRange(e,t,r,i={}){return n(this,void 0,void 0,(function*(){if(i.viewAsPairs=i.viewAsPairs||!1,i.pairAcrossChr=i.pairAcrossChr||!1,i.maxInsertSize=i.maxInsertSize||2e5,"string"==typeof e)throw new o.CramUnimplementedError("string sequence names not yet supported");const n=e,s=yield this.index.getEntriesForRange(n,t,r),a=s.map((e=>e.sliceBytes)).reduce(((e,t)=>e+t),0);if(a>this.fetchSizeLimit)throw new o.CramSizeLimitError(`data size of ${a.toLocaleString()} bytes exceeded fetch size limit of ${this.fetchSizeLimit.toLocaleString()} bytes`);const f=n=>n.sequenceId===e&&n.alignmentStart<=r&&void 0!==n.lengthOnRef&&n.alignmentStart+n.lengthOnRef-1>=t,h=yield Promise.all(s.map((e=>this.getRecordsInSlice(e,f))));let l=Array.prototype.concat(...h);if(i.viewAsPairs){const e={},t={};for(let r=0;r{1===t&&(r[e]=!0);}));const o=[];for(let e=0;ee.toString().localeCompare(t.toString()))).filter(((e,t,r)=>!t||e.toString()!==r[t-1].toString()));const h=[],u=a.map((e=>e.sliceBytes)).reduce(((e,t)=>e+t),0);if(u>this.fetchSizeLimit)throw new Error(`mate data size of ${u.toLocaleString()} bytes exceeded fetch size limit of ${this.fetchSizeLimit.toLocaleString()} bytes`);a.forEach((e=>{let n=this.cram.featureCache.get(e.toString());n||(n=this.getRecordsInSlice(e,(()=>!0)),this.cram.featureCache.set(e.toString(),n));const i=n.then((e=>{const n=[];for(let i=0;ie.concat(t)));l=l.concat(e);}}return l}))}getRecordsInSlice({containerStart:e,sliceStart:t,sliceBytes:r},n){return this.cram.getContainerAtPosition(e).getSlice(t,r).getRecords(n)}hasDataForReferenceSequence(e){return this.index.hasDataForReferenceSequence(e)}};},3427:function(e,t,r){var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0}),t.open=t.fromUrl=t.RemoteFile=t.LocalFile=void 0;const i=n(r(8575)),o=r(4319),s=r(2949);function a(e){const{protocol:t,pathname:r}=i.default.parse(e);return "file:"===t?new s.LocalFile(unescape((0, o.ensureNotNullish)(r))):new s.RemoteFile(e)}Object.defineProperty(t,"LocalFile",{enumerable:!0,get:function(){return s.LocalFile}}),Object.defineProperty(t,"RemoteFile",{enumerable:!0,get:function(){return s.RemoteFile}}),t.fromUrl=a,t.open=function(e,t,r){if(r)return r;if(e)return a(e);if(t)return new s.LocalFile(t);throw new Error("no url, path, or filehandle provided, cannot open")};},5702:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.RANS_BYTE_L=t.TOTFREQ=t.TF_SHIFT=void 0,t.TF_SHIFT=12,t.TOTFREQ=4096,t.RANS_BYTE_L=1<<23;},6484:function(e,t,r){var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const i=r(8577),o=r(5702),s=n(r(7634));t.default=function(e,t,r,n){let a=e.getInt(),f=e.getInt(),h=e.getInt(),l=e.getInt();const u=n.remaining(),c=-4&u;for(let i=0;i>2;let c=0,d=u,p=2*u,g=3*u,m=0,y=0,b=0,v=0;for(;c{Object.defineProperty(t,"__esModule",{value:!0});const n=r(8577),i=r(5702);class o{constructor(){this.F=void 0,this.C=void 0;}}function s(e,t,r,n){return r*(e>>n)+(e&(1<>o)+(e&(1<=128&&(t.fc[f].F&=-129,t.fc[f].F=(127&t.fc[f].F)<<8|255&e.get()),t.fc[f].C=i,s.default.symbolInit(r[f],t.fc[f].C,t.fc[f].F),t.R||(t.R=new Array(o.TOTFREQ)),t.R.fill(f,i,i+t.fc[f].F),i+=t.fc[f].F,0===n&&f+1===(255&e.getByteAt(e.position()))?(f=255&e.get(),n=255&e.get()):0!==n?(n-=1,f+=1):f=255&e.get();}while(0!==f);a(i=128&&(t[i].fc[l].F&=-129,t[i].fc[l].F=(127&t[i].fc[l].F)<<8|255&e.get()),t[i].fc[l].C=h,0===t[i].fc[l].F&&(t[i].fc[l].F=o.TOTFREQ),null==r[i][l]&&(r[i][l]=new s.default.RansDecSymbol),s.default.symbolInit(r[i][l],t[i].fc[l].C,t[i].fc[l].F),null==t[i].R&&(t[i].R=new Array(o.TOTFREQ)),t[i].R.fill(l,h,h+t[i].fc[l].F),h+=t[i].fc[l].F,a(h<=o.TOTFREQ),0===f&&l+1===(255&e.getByteAt(e.position()))?(l=255&e.get(),f=255&e.get()):0!==f?(f-=1,l+=1):l=255&e.get();}while(0!==l);0===n&&i+1===(255&e.getByteAt(e.position()))?(i=255&e.get(),n=255&e.get()):0!==n?(n-=1,i+=1):i=255&e.get();}while(0!==i)};},9675:function(e,t,r){var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const i=r(8577),o=n(r(7634)),s=r(696),a=n(r(6484)),f=n(r(7121));class h{constructor(e,t=0){this._buffer=e,this._position=t,this.length=e.length;}get(){const e=this._buffer[this._position];return this._position+=1,e}getByte(){return this.get()}getByteAt(e){return this._buffer[e]}position(){return this._position}put(e){return this._buffer[this._position]=e,this._position+=1,e}putAt(e,t){return this._buffer[e]=t,t}setPosition(e){return this._position=e,e}getInt(){const e=this._buffer.readInt32LE(this._position);return this._position+=4,e}remaining(){return this._buffer.length-this._position}}t.default=function(e,t,r=0){if(0===e.length)return t.fill(0),t;const n=new h(e,r),l=n.get();if(0!==l&&1!==l)throw new i.CramMalformedError(`Invalid rANS order ${l}`);if(n.getInt()!==n.remaining()-4)throw new i.CramMalformedError("Incorrect input length.");const u=n.getInt(),c=new h(t||Buffer.allocUnsafe(u));if(c.length{Object.defineProperty(t,"__esModule",{value:!0}),t.parseHeaderText=void 0,t.parseHeaderText=function(e){const t=e.split(/\r?\n/),r=[];return t.forEach((e=>{const[t,...n]=e.split(/\t/),i=n.map((e=>{const[t,r]=e.split(":",2);return {tag:t,value:r}}));t&&r.push({tag:t.substr(1),data:i});})),r};},4319:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.ensureNotNullish=void 0,t.ensureNotNullish=function(e){if(null==e)throw new Error("Value must not be nullish.");return e};},597:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.unzip=void 0;const n=r(9591);t.unzip=function(e){return Buffer.from((0, n.inflate)(e))};},9996:(e,t,r)=>{function n(e){return n="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},n(e)}var i=r(8764).Buffer,o=r(22),s=r(2961)._,a=r(3720);"undefined"!=typeof window&&(window.Buffer=i),"undefined"!=typeof self&&(self.Buffer=i);var f={UInt8:1,UInt16LE:2,UInt16BE:2,UInt32LE:4,UInt32BE:4,Int8:1,Int16LE:2,Int16BE:2,Int32LE:4,Int32BE:4,FloatLE:4,FloatBE:4,DoubleLE:8,DoubleBE:8,UInt64:8,Int64:8},h={},l="___parser_",u=[];!function(){var e;for(e=1;e<=32;e++)u.push(e);}();var c={};Object.keys(f).concat(Object.keys({String:null,Buffer:null,Array:null,Skip:null,Choice:null,Nest:null,Bit:null,Itf8:null,Ltf8:null})).forEach((function(e){c[e.toLowerCase()]=e;}));var d=function(){this.varName="",this.type="",this.options={},this.next=null,this.head=null,this.compiled=null,this.endian="le",this.constructorFn=null,this.alias=null;};d.start=function(){return new d},Object.keys(f).forEach((function(e){d.prototype[e.toLowerCase()]=function(t,r){return this.setNextParser(e.toLowerCase(),t,r)};var t=e.replace(/BE|LE/,"").toLowerCase();t in d.prototype||(d.prototype[t]=function(e,r){return this[t+this.endian](e,r)});})),u.forEach((function(e){d.prototype["bit".concat(e.toString())]=function(t,r){return r||(r={}),r.length=e,this.setNextParser("bit",t,r)};})),d.prototype.namely=function(e){return h[e]=this,this.alias=e,this},d.prototype.skip=function(e,t){if(t&&t.assert)throw new Error("assert option on skip is not allowed.");return this.setNextParser("skip","",{length:e})},d.prototype.string=function(e,t){if(!t.zeroTerminated&&!t.length&&!t.greedy)throw new Error("Neither length, zeroTerminated, nor greedy is defined for string.");if((t.zeroTerminated||t.length)&&t.greedy)throw new Error("greedy is mutually exclusive with length and zeroTerminated for string.");if(t.stripNull&&!t.length&&!t.greedy)throw new Error("Length or greedy must be defined if stripNull is defined.");return t.encoding=t.encoding||"utf8",this.setNextParser("string",e,t)},d.prototype.buffer=function(e,t){if(!t.length&&!t.readUntil)throw new Error("Length nor readUntil is defined in buffer parser");return this.setNextParser("buffer",e,t)},d.prototype.array=function(e,t){if(!t.readUntil&&!t.length&&!t.lengthInBytes)throw new Error("Length option of array is not defined.");if(!t.type)throw new Error("Type option of array is not defined.");if("string"==typeof t.type&&!h[t.type]&&Object.keys(f).indexOf(c[t.type])<0)throw new Error('Specified primitive type "'.concat(t.type,'" is not supported.'));return this.setNextParser("array",e,t)},d.prototype.choice=function(e,t){if(1===arguments.length&&"object"===n(e)&&(t=e,e=null),!t.tag)throw new Error("Tag option of array is not defined.");if(!t.choices)throw new Error("Choices option of array is not defined.");return Object.keys(t.choices).forEach((function(r){if(!t.choices[r])throw new Error("Choice Case ".concat(r," of ").concat(e," is not valid."));if("string"==typeof t.choices[r]&&!h[t.choices[r]]&&Object.keys(f).indexOf(c[t.choices[r]])<0)throw new Error('Specified primitive type "'.concat(t.choices[r],'" is not supported.'))}),this),this.setNextParser("choice",e,t)},d.prototype.nest=function(e,t){if(1===arguments.length&&"object"===n(e)&&(t=e,e=null),!t.type)throw new Error("Type option of nest is not defined.");if(!(t.type instanceof d||h[t.type]))throw new Error("Type option of nest must be a Parser object.");if(!(t.type instanceof d||e))throw new Error("options.type must be a object if variable name is omitted.");return this.setNextParser("nest",e,t)},d.prototype.endianess=function(e){switch(e.toLowerCase()){case"little":this.endian="le";break;case"big":this.endian="be";break;default:throw new Error("Invalid endianess: ".concat(e))}return this},d.prototype.create=function(e){if(!(e instanceof Function))throw new Error("Constructor must be a Function object.");return this.constructorFn=e,this},d.prototype.getCode=function(){var e=new s;return e.pushCode("if (!Buffer.isBuffer(buffer)) {"),e.generateError('"argument buffer is not a Buffer object"'),e.pushCode("}"),this.alias?this.addAliasedCode(e):this.addRawCode(e),this.alias?e.pushCode("return {0}(0)",l+this.alias):e.pushCode("return { offset: offset, result: vars };"),e.code},d.prototype.addRawCode=function(e){e.pushCode("var offset = 0;"),this.constructorFn?e.pushCode("var vars = new constructorFn();"):e.pushCode("var vars = {};"),this.generate(e),this.resolveReferences(e),e.pushCode("return { offset: offset, result: vars };");},d.prototype.addAliasedCode=function(e){return e.pushCode("function {0}(offset) {",l+this.alias),this.constructorFn?e.pushCode("var vars = new constructorFn();"):e.pushCode("var vars = {};"),this.generate(e),e.markResolved(this.alias),this.resolveReferences(e),e.pushCode("return { offset: offset, result: vars };"),e.pushCode("}"),e},d.prototype.resolveReferences=function(e){var t=e.getUnresolvedReferences();e.markRequested(t),t.forEach((function(t){h[t].addAliasedCode(e);}));},d.prototype.compile=function(){var e="(function(buffer, constructorFn, Long) { ".concat(this.getCode()," })");this.compiled=o.runInThisContext(e);},d.prototype.sizeOf=function(){var e=NaN;if(Object.keys(f).indexOf(this.type)>=0)e=f[this.type];else if("String"===this.type&&"number"==typeof this.options.length)e=this.options.length;else if("Buffer"===this.type&&"number"==typeof this.options.length)e=this.options.length;else if("Array"===this.type&&"number"==typeof this.options.length){var t=NaN;"string"==typeof this.options.type?t=f[c[this.options.type]]:this.options.type instanceof d&&(t=this.options.type.sizeOf()),e=this.options.length*t;}else "Skip"===this.type?e=this.options.length:"Nest"===this.type?e=this.options.type.sizeOf():this.type||(e=0);return this.next&&(e+=this.next.sizeOf()),e},d.prototype.parse=function(e){return this.compiled||this.compile(),this.compiled(e,this.constructorFn,a)},d.prototype.setNextParser=function(e,t,r){var n=new d;return n.type=c[e],n.varName=t,n.options=r||n.options,n.endian=this.endian,this.head?this.head.next=n:this.next=n,this.head=n,this},d.prototype.generate=function(e){this.type&&(this["generate".concat(this.type)](e),this.generateAssert(e));var t=e.generateVariable(this.varName);return this.options.formatter&&this.generateFormatter(e,t,this.options.formatter),this.generateNext(e)},d.prototype.generateAssert=function(e){if(this.options.assert){var t=e.generateVariable(this.varName);switch(n(this.options.assert)){case"function":e.pushCode("if (!({0}).call(vars, {1})) {",this.options.assert,t);break;case"number":e.pushCode("if ({0} !== {1}) {",this.options.assert,t);break;case"string":e.pushCode('if ("{0}" !== {1}) {',this.options.assert,t);break;default:throw new Error("Assert option supports only strings, numbers and assert functions.")}e.generateError('"Assert error: {0} is " + {0}',t),e.pushCode("}");}},d.prototype.generateNext=function(e){return this.next&&(e=this.next.generate(e)),e},Object.keys(f).forEach((function(e){d.prototype["generate".concat(e)]=function(t){"UInt64"===e?t.pushCode("{0} = Long.fromBytes(buffer.slice(offset,offset+8), true, this.endian === 'le').toNumber();",t.generateVariable(this.varName),e):"Int64"===e?t.pushCode("{0} = Long.fromBytes(buffer.slice(offset,offset+8), false, this.endian === 'le').toNumber();",t.generateVariable(this.varName),e):t.pushCode("{0} = buffer.read{1}(offset);",t.generateVariable(this.varName),e),t.pushCode("offset += {0};",f[e]);};})),d.prototype.generateBit=function(e){var t=JSON.parse(JSON.stringify(this));if(t.varName=e.generateVariable(t.varName),e.bitFields.push(t),!this.next||this.next&&["Bit","Nest"].indexOf(this.next.type)<0){var r=0;e.bitFields.forEach((function(e){r+=e.options.length;}));var n=e.generateTmpVariable();if(r<=8)e.pushCode("var {0} = buffer.readUInt8(offset);",n),r=8;else if(r<=16)e.pushCode("var {0} = buffer.readUInt16BE(offset);",n),r=16;else if(r<=24){var i=e.generateTmpVariable(),o=e.generateTmpVariable();e.pushCode("var {0} = buffer.readUInt16BE(offset);",i),e.pushCode("var {0} = buffer.readUInt8(offset + 2);",o),e.pushCode("var {2} = ({0} << 8) | {1};",i,o,n),r=24;}else {if(!(r<=32))throw new Error("Currently, bit field sequence longer than 4-bytes is not supported.");e.pushCode("var {0} = buffer.readUInt32BE(offset);",n),r=32;}e.pushCode("offset += {0};",r/8);var s=0,a="be"===this.endian;e.bitFields.forEach((function(t){e.pushCode("{0} = {1} >> {2} & {3};",t.varName,n,a?r-s-t.options.length:s,(1< offset++);"),e.pushCode("{0} = buffer.toString('{1}', {2}, offset);",t,this.options.encoding,r)),this.options.stripNull&&e.pushCode("{0} = {0}.replace(/\\x00+$/g, '')",t);},d.prototype.generateBuffer=function(e){"eof"===this.options.readUntil?e.pushCode("{0} = buffer.slice(offset);",e.generateVariable(this.varName)):(e.pushCode("{0} = buffer.slice(offset, offset + {1});",e.generateVariable(this.varName),e.generateOption(this.options.length)),e.pushCode("offset += {0};",e.generateOption(this.options.length))),this.options.clone&&e.pushCode("{0} = Buffer.from({0});",e.generateVariable(this.varName));},d.prototype.generateArray=function(e){var t=e.generateOption(this.options.length),r=e.generateOption(this.options.lengthInBytes),n=this.options.type,i=e.generateTmpVariable(),o=e.generateVariable(this.varName),s=e.generateTmpVariable(),a=this.options.key,u="string"==typeof a;if(u?e.pushCode("{0} = {};",o):e.pushCode("{0} = [];",o),"function"==typeof this.options.readUntil?e.pushCode("do {"):"eof"===this.options.readUntil?e.pushCode("for (var {0} = 0; offset < buffer.length; {0}++) {",i):void 0!==r?e.pushCode("for (var {0} = offset; offset - {0} < {1}; ) {",i,r):e.pushCode("for (var {0} = 0; {0} < {1}; {0}++) {",i,t),"string"==typeof n)if(h[n]){var p=e.generateTmpVariable();e.pushCode("var {0} = {1}(offset);",p,l+n),e.pushCode("var {0} = {1}.result; offset = {1}.offset;",s,p),n!==this.alias&&e.addReference(n);}else e.pushCode("var {0} = buffer.read{1}(offset);",s,c[n]),e.pushCode("offset += {0};",f[c[n]]);else n instanceof d&&(e.pushCode("var {0} = {};",s),e.pushScope(s),n.generate(e),e.popScope());u?e.pushCode("{0}[{2}.{1}] = {2};",o,a,s):e.pushCode("{0}.push({1});",o,s),e.pushCode("}"),"function"==typeof this.options.readUntil&&e.pushCode(" while (!({0}).call(this, {1}, buffer.slice(offset)));",this.options.readUntil,s);},d.prototype.generateChoiceCase=function(e,t,r){if("string"==typeof r)if(h[r]){var n=e.generateTmpVariable();e.pushCode("var {0} = {1}(offset);",n,l+r),e.pushCode("{0} = {1}.result; offset = {1}.offset;",e.generateVariable(this.varName),n),r!==this.alias&&e.addReference(r);}else e.pushCode("{0} = buffer.read{1}(offset);",e.generateVariable(this.varName),c[r]),e.pushCode("offset += {0};",f[c[r]]);else r instanceof d&&(e.pushPath(t),r.generate(e),e.popPath(t));},d.prototype.generateChoice=function(e){var t=e.generateOption(this.options.tag);this.varName&&e.pushCode("{0} = {};",e.generateVariable(this.varName)),e.pushCode("switch({0}) {",t),Object.keys(this.options.choices).forEach((function(t){var r=this.options.choices[t];Number.isNaN(parseInt(t,10))?e.pushCode("case '{0}':",t):e.pushCode("case {0}:",t),this.generateChoiceCase(e,this.varName,r),e.pushCode("break;");}),this),e.pushCode("default:"),this.options.defaultChoice?this.generateChoiceCase(e,this.varName,this.options.defaultChoice):e.generateError('"Met undefined tag value " + {0} + " at choice"',t),e.pushCode("}");},d.prototype.generateNest=function(e){var t=e.generateVariable(this.varName);if(this.options.type instanceof d)this.varName&&e.pushCode("{0} = {};",t),e.pushPath(this.varName),this.options.type.generate(e),e.popPath(this.varName);else if(h[this.options.type]){var r=e.generateTmpVariable();e.pushCode("var {0} = {1}(offset);",r,l+this.options.type),e.pushCode("{0} = {1}.result; offset = {1}.offset;",t,r),this.options.type!==this.alias&&e.addReference(this.options.type);}},d.prototype.generateFormatter=function(e,t,r){"function"==typeof r&&e.pushCode("{0} = ({1}).call(this, {0});",t,r);},d.prototype.isInteger=function(){return !!this.type.match(/U?Int[8|16|32][BE|LE]?|Bit\d+/)},d.prototype.itf8=function(e,t){return this.setNextParser("itf8",e,t)},d.prototype.itf8=function(e,t){return this.setNextParser("itf8",e,t)},d.prototype.generateItf8=function(e){var t=e.generateVariable(this.varName),r=e.generateTmpVariable();e.pushCode("\n var ".concat(r," = buffer[offset];\n if (").concat(r," < 0x80) {\n ").concat(t," = ").concat(r,";\n offset += 1;\n } else if (").concat(r," < 0xc0) {\n ").concat(t," = ((").concat(r,"<<8) | buffer[offset+1]) & 0x3fff;\n offset += 2;\n } else if (").concat(r," < 0xe0) {\n ").concat(t," = ((").concat(r,"<<16) | (buffer[offset+1]<< 8) | buffer[offset+2]) & 0x1fffff;\n offset += 3;\n } else if (").concat(r," < 0xf0) {\n ").concat(t," = ((").concat(r,"<<24) | (buffer[offset+1]<<16) | (buffer[offset+2]<<8) | buffer[offset+3]) & 0x0fffffff;\n offset += 4\n } else {\n ").concat(t," = ((").concat(r," & 0x0f)<<28) | (buffer[offset+1]<<20) | (buffer[offset+2]<<12) | (buffer[offset+3]<<4) | (buffer[offset+4] & 0x0f);\n // x=((0xff & 0x0f)<<28) | (0xff<<20) | (0xff<<12) | (0xff<<4) | (0x0f & 0x0f);\n // TODO *val_p = uv < 0x80000000UL ? uv : -((int32_t) (0xffffffffUL - uv)) - 1;\n offset += 5\n }\n "));},d.prototype.ltf8=function(e,t){return this.setNextParser("ltf8",e,t)},d.prototype.generateLtf8=function(e){var t=e.generateVariable(this.varName),r=e.generateTmpVariable();e.pushCode("\n var ".concat(r," = buffer[offset];\n if (").concat(r," < 0x80) {\n ").concat(t," = ").concat(r,";\n offset += 1;\n } else if (").concat(r," < 0xc0) {\n ").concat(t," = ((buffer[offset]<<8) | buffer[offset+1]) & 0x3fff;\n offset += 2;\n } else if (").concat(r," < 0xe0) {\n ").concat(t," = ((buffer[offset]<<16) | (buffer[offset+1]<<8) | buffer[offset+2]) & 0x1fffff;\n ").concat(t," = (((").concat(r," & 63) << 16) | buffer.readUInt16LE(offset + 1));\n offset += 3;\n } else if (").concat(r," < 0xf0) {\n ").concat(t," = ((buffer[offset]<<24) | (buffer[offset+1]<<16) | (buffer[offset+2]<<8) | buffer[offset+3]) & 0x0fffffff;\n offset += 4;\n } else if (").concat(r," < 0xf8) {\n ").concat(t," = (((buffer[offset] & 15) * Math.pow(2,32))) +\n (buffer[offset+1]<<24) | (buffer[offset+2]<<16 | buffer[offset+3]<<8 | buffer[offset+4])\n // TODO *val_p = uv < 0x80000000UL ? uv : -((int32_t) (0xffffffffUL - uv)) - 1;\n offset += 5;\n } else if (").concat(r," < 0xfc) {\n ").concat(t," = ((((buffer[offset] & 7) << 8) | buffer[offset+1] )) * Math.pow(2,32) +\n (buffer[offset+2]<<24) | (buffer[offset+3]<<16 | buffer[offset+4]<<8 | buffer[offset+5])\n offset += 6;\n } else if (").concat(r," < 0xfe) {\n ").concat(t," = ((((buffer[offset] & 3) << 16) | buffer[offset+1]<<8 | buffer[offset+2])) * Math.pow(2,32) +\n (buffer[offset+3]<<24) | (buffer[offset+4]<<16 | buffer[offset+5]<<8 | buffer[offset+6])\n offset += 7;\n } else if (").concat(r," < 0xff) {\n ").concat(t," = Long.fromBytesBE(buffer.slice(offset+1,offset+8));\n if (").concat(t,".greaterThan(Number.MAX_SAFE_INTEGER) || ").concat(t,".lessThan(Number.MIN_SAFE_INTEGER))\n throw new Error('integer overflow')\n ").concat(t," = ").concat(t,".toNumber()\n offset += 8;\n } else {\n ").concat(t," = Long.fromBytesBE(buffer.slice(offset+1,offset+9));\n if (").concat(t,".greaterThan(Number.MAX_SAFE_INTEGER) || ").concat(t,".lessThan(Number.MIN_SAFE_INTEGER))\n throw new Error('integer overflow')\n ").concat(t," = ").concat(t,".toNumber()\n offset += 9;\n }\n "));},t.Parser=d;},2961:(e,t)=>{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},r(e)}var n=function(){this.code="",this.scopes=[["vars"]],this.isAsync=!1,this.bitFields=[],this.tmpVariableCount=0,this.references={};};n.prototype.generateVariable=function(e){var t=[];for(Array.prototype.push.apply(t,this.scopes[this.scopes.length-1]);/^\$parent\./.test(e);)t.pop(),e=e.replace(/^\$parent\./,"");return e&&t.push(e),t.join(".")},n.prototype.generateOption=function(e){switch(r(e)){case"number":return e.toString();case"string":return this.generateVariable(e);case"function":return "(".concat(e,").call(").concat(this.generateVariable(),", vars)");default:return}},n.prototype.generateError=function(){var e=Array.prototype.slice.call(arguments),t=n.interpolate.apply(this,e);this.isAsync?this.pushCode("return process.nextTick(function() { callback(new Error(".concat(t,"), vars); });")):this.pushCode("throw new Error(".concat(t,");"));},n.prototype.generateTmpVariable=function(){return "$tmp".concat(this.tmpVariableCount++)},n.prototype.pushCode=function(){var e=Array.prototype.slice.call(arguments);this.code+="".concat(n.interpolate.apply(this,e),"\n");},n.prototype.pushPath=function(e){e&&this.scopes[this.scopes.length-1].push(e);},n.prototype.popPath=function(e){e&&this.scopes[this.scopes.length-1].pop();},n.prototype.pushScope=function(e){this.scopes.push([e]);},n.prototype.popScope=function(){this.scopes.pop();},n.prototype.addReference=function(e){this.references[e]||(this.references[e]={resolved:!1,requested:!1});},n.prototype.markResolved=function(e){this.references[e].resolved=!0;},n.prototype.markRequested=function(e){e.forEach(function(e){this.references[e].requested=!0;}.bind(this));},n.prototype.getUnresolvedReferences=function(){var e=this.references;return Object.keys(this.references).filter((function(t){return !e[t].resolved&&!e[t].requested}))},n.interpolate=function(e){var t=/{\d+}/g,r=e.match(t),n=Array.prototype.slice.call(arguments,1);return r&&r.forEach((function(t){var r=parseInt(t.substr(1,t.length-2),10);e=e.replace(t,n[r].toString());})),e},t._=n;},22:e=>{e.exports.runInThisContext=function(e){return new Function("code","return eval(code);").call(globalThis,e)};},445:(e,t,r)=>{const n=r(7381),i=r(9260),o=r(576),s=r(4693),a=128;e.exports=class{decode(e){return this.stream=new i(e),this.decodeStream(this.stream)}decodeStream(e,t=0){var r=this.stream.ReadByte();16&r||(t=this.stream.ReadUint7());var n,i=t,o=1&r;if(8&r)return this.decodeStripe(this.stream,t);if(r&a&&([n,i]=this.decodePackMeta(this.stream)),32&r)var s=this.decodeCat(this.stream,i);else s=4&r?this.decodeExt(this.stream,i):64&r?o?this.decodeRLE1(this.stream,i):this.decodeRLE0(this.stream,i):o?this.decode1(this.stream,i):this.decode0(this.stream,i);return r&a&&(s=this.decodePack(s,n,t)),s}encode(e,t){if(this.stream=new i("",0,1.1*e.length+100),this.stream.WriteByte(t),16&t||this.stream.WriteUint7(e.length),8&t)return Buffer.concat([this.stream.buf.slice(0,this.stream.pos),this.encodeStripe(this.stream,e,t>>8)]);var r,n=1&t,o=e.length;return t&a&&([r,e,o]=this.encodePack(e)),t&a&&this.stream.WriteStream(r),64&t?n?this.encodeRLE1(e,o,this.stream):this.encodeRLE0(e,o,this.stream):n?this.encode1(e,o,this.stream):this.encode0(e,o,this.stream)}decode0(e,t){var r=new Buffer.allocUnsafe(t),i=e.ReadByte();0==i&&(i=256);var s=new o(i),a=new n(e);a.RangeStartDecode(e);for(var f=0;f=3?3:l;for(f[u].ModelEncode(r,h,c),l-=c,u=256;3==c;)c=l>=3?3:l,f[u].ModelEncode(r,h,c),u=257,l-=c;}return h.RangeFinishEncode(r),r.buf.slice(0,r.pos)}decodeRLE1(e,t){var r=new Buffer.allocUnsafe(t),i=e.ReadByte();0==i&&(i=256);for(var s=new Array(i),a=0;a=3?3:u;for(f[c].ModelEncode(r,h,d),u-=d,c=256;3==d;)d=u>=3?3:u,f[c].ModelEncode(r,h,d),c=257,u-=d;}return h.RangeFinishEncode(r),r.buf.slice(0,r.pos)}decodePackMeta(e){this.nsym=e.ReadByte();for(var t=new Array(this.nsym),r=0;r>=1;}}else if(this.nsym<=4)for(i=0,o=0;i>=2;else {if(!(this.nsym<=16))return e;for(i=0,o=0;i>=4;}return n}packMeta(e){for(var t=new i("",0,1024),r=new Array(256),n=0;ns),n[s]=new Array(o[s]);for(var a=0,f=0;fo),s[o]=this.decodeStream(e,i[o]);var a=new Buffer.allocUnsafe(t);for(o=0;o{e.exports=class{constructor(e){this.low=0,this.range=4294967295,this.code=0,this.FFnum=0,this.carry=0,this.cache=0;}RangeStartDecode(e){for(var t=0;t<5;t++)this.code=(this.code<<8)+e.ReadByte();this.code&=4294967295,this.code>>>=0;}RangeGetFrequency(e){return this.range=Math.floor(this.range/e),Math.floor(this.code/this.range)}RangeDecode(e,t,r,n){for(this.code-=t*this.range,this.range*=r;this.range<1<<24;)this.range*=256,this.code=256*this.code+e.ReadByte();}RangeShiftLow(e){if(this.low<4278190080|this.carry){for(e.WriteByte(this.cache+this.carry);this.FFnum;)e.WriteByte(this.carry-1),this.FFnum--;this.cache=this.low>>>24,this.carry=0;}else this.FFnum++;this.low<<=8,this.low>>>=0;}RangeEncode(e,t,r,n){var i=this.low;for(this.range=Math.floor(this.range/n),this.low+=t*this.range,this.low>>>=0,this.range*=r,this.low{e.exports=class{constructor(e=256){this.total_freq=e,this.max_sym=e-1,this.S=new Array,this.F=new Array;for(var t=0;t<=this.max_sym;t++)this.S[t]=t,this.F[t]=1;}ModelDecode(e,t){for(var r=t.RangeGetFrequency(this.total_freq),n=0,i=0;n+this.F[i]<=r;)n+=this.F[i++];t.RangeDecode(e,n,this.F[i],this.total_freq),this.F[i]+=16,this.total_freq+=16,this.total_freq>65519&&this.ModelRenormalise();var o=this.S[i];if(i>0&&this.F[i]>this.F[i-1]){var s=this.F[i];this.F[i]=this.F[i-1],this.F[i-1]=s,s=this.S[i],this.S[i]=this.S[i-1],this.S[i-1]=s;}return o}ModelRenormalise(){this.total_freq=0;for(var e=0;e<=this.max_sym;e++)this.F[e]-=Math.floor(this.F[e]/2),this.total_freq+=this.F[e];}ModelEncode(e,t,r){for(var n=0,i=0;this.S[i]!=r;i++)n+=this.F[i];if(t.RangeEncode(e,n,this.F[i],this.total_freq),this.F[i]+=16,this.total_freq+=16,this.total_freq>65519&&this.ModelRenormalise(),r=this.S[i],i>0&&this.F[i]>this.F[i-1]){var o=this.F[i];this.F[i]=this.F[i-1],this.F[i-1]=o,o=this.S[i],this.S[i]=this.S[i-1],this.S[i-1]=o;}}};},5260:(e,t,r)=>{const n=r(9260),i=r(576),o=r(7381);function s(e,t,r){for(var n=0,i=0,o=-1,s=new Array(1024);i>4,t.qshift=15&r,r=e.ReadByte(),t.qloc=r>>4,t.sloc=15&r,r=e.ReadByte(),t.ploc=r>>4,t.dloc=15&r,t.qmap=new Array(256),16&t.pflags)for(var n=0;n0&&128&t.pflags)s(e,t.qtab,256);else for(n=0;n<256;n++)t.qtab[n]=n;return t.ptab=new Array(1024),32&t.pflags&&s(e,t.ptab,1024),t.dtab=new Array(256),64&t.pflags&&s(e,t.dtab,256),t}function h(e,t,r,n,i,o){r.max_sel>0?i.s=n.sel.ModelDecode(e,t):i.s=0,i.x=r.stab[i.s];var s=r.params[i.x];if(s.fixed_len>=0){var a=n.len[0].ModelDecode(e,t);a|=n.len[1].ModelDecode(e,t)<<8,a|=n.len[2].ModelDecode(e,t)<<16,a|=n.len[3].ModelDecode(e,t)<<24,s.fixed_len>0&&(s.fixed_len=-a);}else a=-s.fixed_len;i.len=a,r.do_rev&&(o[i.rec]=n.rev.ModelDecode(e,t)),i.is_dup=0,2&s.pflags&&n.dup.ModelDecode(e,t)&&(i.is_dup=1),i.p=a,i.delta=0,i.qctx=0,i.prevq=0,i.rec++;}function l(e,t,r){for(var n=0,i=0,o=new Array(2*r),s=0;n1?r.nparam-1:0,o=new Array(256);if(2&r)i=e.ReadByte(),s(e,o,256);else {for(var a=0;a0&&(t.sel=new i(e.max_sel+1)),t}(n),d=new o(e);d.RangeStartDecode(e);for(var p=new Buffer.allocUnsafe(r),g={qctx:0,prevq:0,delta:0,p:0,s:0,x:0,len:0,is_dup:0,rec:0},m=0;m0&&c.dup.ModelDecode(e,d)){for(var y=0;y4),qshift:u,qloc:7,pbits:7,pshift:t[0]>128?1:0,ploc:0,dbits:u>4?0:1,dshift:3,dloc:15,sbits:0,sloc:15,do_stab:0,context:0,max_sym:f,nsym:a,do_qmap:c,do_dedup:0,fixed_len:1==t.length?1:0,do_sel:0,do_rev:0,do_pos:1,do_delta:u<=4?1:0,do_qtab:0,qbits:8+(u>4)-(0==s),sbits:1,sloc:15-(u<=4),do_stab:1,do_sel:1}]}(e,t,r,s),p=function(e,t,r,n,i,o,s){for(var a=[0,1,1,1,2,2,2,2,2,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7],f=0;f1?1:0)|(t[0].do_stab?2:0);if(e.WriteByte(h),1&h&&e.WriteByte(t.length),2&h){var u=1<0&&u--,e.WriteByte(u),l(e,s,256);}for(var c=0;c0){for(f=0;f<256;f++)n[c][f]=f;t[c].do_qtab&&l(e,n[c],256);}if(t[c].pbits>0){for(f=0;f<1024;f++)i[c][f]=Math.min((1<>t[c].pshift);l(e,i[c],1024);}if(t[c].dbits>0){for(f=0;f<256;f++)a[f]>(1<>t[c].dshift)];l(e,o[c],256);}}return e}(p,d,s,a,f,h,u);return function(e,t,r,n,s,a,f,h,l,u){var c=1<0&&c--;for(var d=t.length,p=0,g=0;g0&&v.ModelEncode(e,w,B);var E=u[B],S=r[Math.min(r.length-1,_++)];s[E].fixed_len?s[E].fixed_len>0&&(b[0].ModelEncode(e,w,255&S),b[1].ModelEncode(e,w,S>>8&255),b[2].ModelEncode(e,w,S>>16&255),b[3].ModelEncode(e,w,S>>24&255),s[E].fixed_len=-1):(b[0].ModelEncode(e,w,255&S),b[1].ModelEncode(e,w,S>>8&255),b[2].ModelEncode(e,w,S>>16&255),b[3].ModelEncode(e,w,S>>24&255)),s[E].do_dedup&&process.exit(1),g=S;var A=0,C=s[E].context,R=0,k=0;}var x=t[y++],I=a[E][x];m[C].ModelEncode(e,w,I),R=(R<0&&(C+=h[E][Math.min(g,1023)]<0&&(C+=l[E][Math.min(A,255)]<{var n=r(4459),i=r(594),o=r(445),s=r(5260),a=r(2881);e.exports={r4x8_uncompress:function(e,t){n.decode(e).copy(t,0,0);},r4x16_uncompress:function(e,t){i.decode(e).copy(t,0,0);},arith_uncompress:function(e,t){o.decode(e).copy(t,0,0);},fqzcomp_uncompress:function(e,t){var r=new Array;s.decode(e,r).copy(t,0,0);},tok3_uncompress:function(e,t){var r=a.decode(e,0,"\0");Buffer.from(r,"binary").copy(t,0,0);}};},9260:e=>{e.exports=class{constructor(e,t=0,r=0){0!=r?(this.buf=Buffer.allocUnsafe(r),this.length=r):(this.buf=e,this.length=e.length),this.pos=t;}EOF(){return this.pos>=this.length}ReadData(e){var t=this.buf.slice(this.pos,this.pos+e);return this.pos+=e,t}ReadByte(){const e=this.buf[this.pos];return this.pos++,e}ReadChar(){const e=this.buf[this.pos];return this.pos++,String.fromCharCode(e)}ReadUint16(){return this.ReadByte()|this.ReadByte()<<8}ReadUint32(){const e=this.buf.readInt32LE(this.pos);return this.pos+=4,e}ReadString(){var e="";do{var t=this.buf[this.pos++];t&&(e+=String.fromCharCode(t));}while(t);return e}ReadUint7(){var e=0;do{var t=this.ReadByte();e=e<<7|127&t;}while(128&t);return e}ReadITF8(){var e=this.buf[this.pos];return this.pos++,e>=240?(e=(15&e)<<28,e+=(this.buf[this.pos+0]<<20)+(this.buf[this.pos+1]<<12)+(this.buf[this.pos+2]<<4)+(this.buf[this.pos+3]>>4),this.pos+=4):e>=224?(e=(15&e)<<24,e+=(this.buf[this.pos+0]<<16)+(this.buf[this.pos+1]<<8)+(this.buf[this.pos+2]<<0),this.pos+=3):e>=192?(e=(31&e)<<16,e+=(this.buf[this.pos+0]<<8)+(this.buf[this.pos+1]<<0),this.pos+=2):e>=128&&(e=(63&e)<<8,e+=this.buf[this.pos],this.pos++),e}WriteByte(e){this.buf[this.pos++]=e;}WriteChar(e){this.buf[this.pos++]=e.charCodeAt(0);}WriteString(e){for(var t=0;t>8&255);}WriteUint32(e){this.buf.writeInt32LE(e,this.pos),this.pos+=4;}WriteUint7(e){var t=0,r=e;do{t+=7,r>>=7;}while(r>0);do{t-=7,this.WriteByte((e>>t&127)+((t>0)<<7));}while(t>0)}WriteITF8(e){e<0&&(e=1+e),e<=127?this.buf[this.pos++]=e:e<=16383?(this.buf[this.pos++]=128|Math.floor(e/256),this.buf[this.pos++]=255&e):e<131071?(this.buf[this.pos++]=192|Math.floor(e/65536),this.buf[this.pos++]=255&Math.floor(e/256),this.buf[this.pos++]=255&e):e<268435455?(this.buf[this.pos++]=224|Math.floor(e/16777216),this.buf[this.pos++]=255&Math.floor(e/65536),this.buf[this.pos++]=255&Math.floor(e/256),this.buf[this.pos++]=255&e):(this.buf[this.pos++]=240|Math.floor(e/268435456),this.buf[this.pos++]=255&Math.floor(e/1048576),this.buf[this.pos++]=255&Math.floor(e/4096),this.buf[this.pos++]=255&Math.floor(e/4),this.buf[this.pos++]=15&e);}WriteByteNeg(e){this.buf[--this.pos]=e;}};},4459:(e,t,r)=>{const n=r(9260);function i(e){return 4095&e}function o(e,t){for(var r=0;t>=e[r+1];)r++;return r}function s(e){for(var t=new Array(4096),r=0,n=0;n<4096;n++){for(;n>=e[r+1];)r++;t[n]=r;}return t}function a(e,t,r){return r*(e>>12)+(4095&e)-t}function f(e,t){for(;t<1<<23;)t=(t<<8)+e.ReadByte();return t}function h(e,t){t.WriteByteNeg(e>>24&255),t.WriteByteNeg(e>>16&255),t.WriteByteNeg(e>>8&255),t.WriteByteNeg(e>>0&255);}function l(e,t,r,n,i){return e=function(e,t,r,n){for(var i=(1<<23>>n<<8)*r;e>=i;)t.WriteByteNeg(255&e),e>>=8;return e}(e,t,n,i),(Math.floor(e/n)<0?(s--,i++):(i=e.ReadByte())==o+1&&(s=e.ReadByte()),o=i;}while(0!=i);for(r[0]=0,n=0;n<=255;n++)r[n+1]=r[n]+t[n];}function c(e){for(var t=0,r=0;r<256;r++)t+=e[r];const n=4096;var i=n/t;do{var o=0,s=0,a=0;for(t=0,r=0;r<256;r++)0!=e[r]&&(o2?e[s]-=t-n:t!=n&&(i*=.99,a=1);}while(a)}function d(e,t){for(var r=0,n=0;n<256;n++)if(t[n]){if(r>0)r--;else if(e.WriteByte(n),n>0&&t[n-1]>0){for(r=n+1;r<256&&t[r];r++);r-=n+1,e.WriteByte(r);}e.WriteITF8(t[n]);}e.WriteByte(0);}e.exports={decode:function(e){var t=new n(e),r=t.ReadByte(),h=(t.ReadUint32(),t.ReadUint32());return 0==r?function(e,t){var r=new Array(256),n=new Array(256);u(e,r,n);for(var o=s(n),h=new Array(4),l=0;l<4;l++)h[l]=e.ReadUint32();var c=new Buffer.allocUnsafe(t);for(l=0;l0?(a--,o++):(o=e.ReadByte())==s+1&&(a=e.ReadByte()),s=o;}while(0!=o)}(e,r,n);for(var h=new Array(256),l=0;l<256;l++)h[l]=s(n[l]);for(var c=new Array(4),d=new Array(4),p=0;p<4;p++)c[p]=e.ReadUint32(),d[p]=0;var g=new Buffer.allocUnsafe(t),m=Math.floor(t/4);for(l=0;l=0;s--)a[s%4]=l(a[s%4],u,o[e[s]],i[e[s]],12);for(s=3;s>=0;s--)h(a[s],u);var p=r.pos;return r.buf.writeInt32LE(p-9+(u.length-u.pos),1),r.buf.writeInt32LE(t,5),Buffer.concat([r.buf.slice(0,r.pos),u.buf.slice(u.pos,u.length)],r.pos+u.length-u.pos)}(e):function(e){const t=e.length;var r=new n("",0,198156);r.WriteByte(1),r.WriteUint32(0),r.WriteUint32(0);for(var i=new Array(256),o=new Array(256),s=new Array(256),a=0;a<256;a++)o[a]=new Array(256),s[a]=new Array(256);for(function(e,t,r){for(var n=0;n<256;n++){r[n]=0;for(var i=0;i<256;i++)t[n][i]=0;}var o=0;for(n=0;n>2)]]++,t[0][e[2*(e.length>>2)]]++,t[0][e[3*(e.length>>2)]]++,r[0]+=3;}(e,o,i),function(e,t){for(var r=0;r<256;r++)t[r]&&c(e[r]);}(o,i),function(e,t,r){for(var n=0,i=0;i<256;i++)if(r[i]){if(n>0)n--;else if(e.WriteByte(i),i>0&&r[i-1]>0){for(n=i+1;n<256&&r[n];n++);n-=i+1,e.WriteByte(n);}d(e,t[i]);}e.WriteByte(0);}(r,o,i),a=0;a<256;a++)if(i[a]){s[a][0]=0;for(var f=1;f<256;f++)s[a][f]=s[a][f-1]+o[a][f-1];}var u=new Array(4),p=new Array(4);for(f=0;f<4;f++)u[f]=1<<23,p[f]=0;var g=new n("",t,t),m=Math.floor(t/4),y=new Array(4),b=new Array(4);for(f=0;f<4;f++)y[f]=(f+1)*m-2,b[f]=e[y[f]+1];for(b[3]=e[t-1],a=t-2;a>4*m-2;a--)u[3]=l(u[3],g,s[e[a]][b[3]],o[e[a]][b[3]],12),b[3]=e[a];for(;y[0]>=0;)for(f=3;f>=0;f--){var v=e[y[f]];u[f]=l(u[f],g,s[v][b[f]],o[v][b[f]],12),b[f]=v,y[f]--;}for(f=3;f>=0;f--)u[f]=l(u[f],g,s[0][b[f]],o[0][b[f]],12);for(a=3;a>=0;a--)h(u[a],g);var w=r.pos;return r.buf.writeInt32LE(w-9+(g.length-g.pos),1),r.buf.writeInt32LE(t,5),Buffer.concat([r.buf.slice(0,r.pos),g.buf.slice(g.pos,g.length)],r.pos+g.length-g.pos)}(e)}};},594:(e,t,r)=>{const n=r(9260);function i(e,t){return e&(1<=e[r+1];)r++;return r}function s(e,t){for(var r=1<=e[i+1];)i++;n[o]=i;}return n}function a(e,t,r,n){return r*(e>>n)+(e&(1<>24&255),t.WriteByteNeg(e>>16&255),t.WriteByteNeg(e>>8&255),t.WriteByteNeg(e>>0&255);}function l(e,t,r,n,i){return e=function(e,t,r,n){for(var i=(1<<31-n)*r;e>=i;)t.WriteByteNeg(e>>8&255),t.WriteByteNeg(255&e),e>>=16;return e}(e,t,n,i),(Math.floor(e/n)<s),i[s]=new Array(o[s]);for(var a=0,f=0;fo),s[o]=c(e,i[o]);var a=new Buffer.allocUnsafe(t);for(o=0;o>4,h=e;if(1&c){var l=e.ReadUint7(),u=e.ReadUint7(),c=new n(e.ReadData(u));h=new n(g(c,l));}var d=new Array(256),m=new Array(256);!function(e,t,r,n){for(var i=0;i<256;i++){t[i]=new Array(256),r[i]=new Array(256);for(var o=0;o<256;o++)t[i][o]=0;}var s=p(e);for(i=0;i<256;i++)if(s[i]){var a=0;for(o=0;o<256;o++)s[o]&&(a>0?a--:(t[i][o]=e.ReadUint7(),0==t[i][o]&&(a=e.ReadByte())));for(y(t[i],n),r[i][0]=0,o=0;o<256;o++)r[i][o+1]=r[i][o]+t[i][o];}}(h,d,m,r);for(var b=new Array(256),v=0;v<256;v++)b[v]=s(m[v],r);for(var w=new Array(4),_=new Array(4),B=0;B<4;B++)w[B]=e.ReadUint32(),_[B]=0;var E=new Buffer.allocUnsafe(t),S=Math.floor(t/4);for(v=0;v>=1;}else if(r<=4)for(s=0;s>=2;else if(r<=16)for(s=0;s>=4;return i}(S,v,w,b)),S}function d(e,t){var r=new n("",0,10);r.WriteByte(t);var i=1&t,o=8&t,s=32&t,a=64&t,f=128&t,c=t>>8;if(16&t||r.WriteUint7(e.length),o)return Buffer.concat([r.buf.slice(0,r.pos),u(0,e,c)]);var d=new Buffer.alloc(0);f&&([d,e]=function(e){for(var t=new Array(256),r=0;r<256;r++)t[r]=0;for(r=0;r0&&(i[r]=o++);if(!(o>16)){if(o<=1)var s=new Buffer.allocUnsafe(0);else if(o<=2){s=new Buffer.allocUnsafe(Math.ceil(e.length/8));var a=-1;for(r=0;r0&&(t[r]=a++,f.WriteByte(r));return f.WriteUint7(s.length),[f.buf.slice(0,f.pos),s]}}(e));var p=new Buffer.alloc(0);if(a&&([p,e]=function(e){for(var t=new Array(256),r=0;r<256;r++)t[r]=0;var i=-1;for(r=0;r0&&o++;for(o||(o=1,t[0]=1),(h=new n("",0,o+1+e.length)).WriteByte(o),r=0;r<256;r++)t[r]>0&&h.WriteByte(r);var s=new Buffer.allocUnsafe(e.length),a=0;for(r=0;r0){i=e[r];for(var f=0;r+f+1>2)]]++,t[0][e[2*(e.length>>2)]]++,t[0][e[3*(e.length>>2)]]++,r[0]+=3;})))(e,o,i),function(e,t,r){for(var n=0;n<256;n++)if(t[n]){var i=Math.ceil(Math.log2(t[n]));i>12&&(i=12),m(e[n],i);}}(o,i);var u=new n("",0,198156);!function(e,t,r){b(e,r);for(var n=0;n<256;n++)if(r[n])for(var i=0,o=0;o<256;o++)if(r[o])if(i)i--;else if(e.WriteUint7(t[n][o]),!t[n][o]){for(var s=o+1;s<256;s++)if(r[s]){if(0!=t[n][s])break;i++;}e.WriteByte(i);}}(u,o,i);var c=v(u.buf.slice(0,u.pos));for(c.length>0,1.05*t+100>>0),_=Math.floor(t/4),B=new Array(4),E=new Array(4);for(d=0;d<4;d++)B[d]=(d+1)*_-2,E[d]=e[B[d]+1];for(E[3]=e[t-1],a=t-2;a>4*_-2;a--)p[3]=l(p[3],w,s[e[a]][E[3]],o[e[a]][E[3]],f),E[3]=e[a];for(;B[0]>=0;)for(d=3;d>=0;d--){var S=e[B[d]];p[d]=l(p[d],w,s[S][E[d]],o[S][E[d]],f),E[d]=S,B[d]--;}for(d=3;d>=0;d--)p[d]=l(p[d],w,s[0][E[d]],o[0][E[d]],f);for(a=3;a>=0;a--)h(p[a],w);return Buffer.concat([r.buf.slice(0,r.pos),w.buf.slice(w.pos,w.length)],r.pos+w.length-w.pos)}(e);return Buffer.concat([r.buf.slice(0,r.pos),d,p,g])}function p(e){for(var t=new Array(256),r=0;r<256;r++)t[r]=0;var n=0,i=e.ReadByte(),o=i;do{t[i]=1,n>0?(n--,i++):(i=e.ReadByte())==o+1&&(n=e.ReadByte()),o=i;}while(0!=i);return t}function g(e,t){var r=new Array(256),n=new Array(256);!function(e,t,r){for(var n=0;n<256;n++)t[n]=0;var i=p(e);for(n=0;n<256;n++)i[n]>0&&(t[n]=e.ReadUint7());for(y(t,12),r[0]=0,n=0;n<=255;n++)r[n+1]=r[n]+t[n];}(e,r,n);for(var o=s(n,12),h=new Array(4),l=0;l<4;l++)h[l]=e.ReadUint32();var u=new Buffer.allocUnsafe(t);for(l=0;l2?e[a]-=r-i:r!=i&&(o=i/r,f=1);}while(f)}function y(e,t){for(var r=0,n=0;n<256;n++)r+=e[n];if(0!=r&&r!=1<0)r--;else if(e.WriteByte(n),n>0&&t[n-1]>0){for(r=n+1;r<256&&t[r];r++);r-=n+1,e.WriteByte(r);}e.WriteByte(0);}function v(e){const t=e.length;var r=new n("",0,780),i=new Array(256);!function(e,t){for(var r=0;r<256;r++)t[r]=0;for(r=0;r12&&(o=12),m(i,o),function(e,t){b(e,t);for(var r=0;r<256;r++)t[r]&&e.WriteUint7(t[r]);}(r,i),m(i,12);var s=new Array(256);s[0]=0;for(var a=1;a<256;a++)s[a]=s[a-1]+i[a-1];var f=new Array(4);for(a=0;a<4;a++)f[a]=32768;var u=new n("",1.05*t+100>>0,1.05*t+100>>0);for(a=t-1;a>=0;a--)f[a%4]=l(f[a%4],u,s[e[a]],i[e[a]],12);for(a=3;a>=0;a--)h(f[a],u);return Buffer.concat([r.buf.slice(0,r.pos),u.buf.slice(u.pos,u.length)],r.pos+u.length-u.pos)}e.exports={decode:function(e){return c(new n(e),0)},encode:d};},2881:(e,t,r)=>{const n=r(9260),i=r(594);var o=new(r(445));function s(e,t){for(var r=e+"";r.length>0)+e[a][8].ReadByte();break;case 9:f=(r[o][a]>>0)+e[a][9].ReadByte(),h=r[o][a].length,r[n][a]=s(f,h);break;case 10:r[n][a]=r[o][a];break;default:r[n][a]="";}t[n]+=r[n][a++];}while(12!=i);return t[n]}function f(e,t,r,n,i,o){for(var s=0;s0&&5==t[s][0].type)&&t[s][r])switch(e[0].WriteByte(t[s][r].type),t[s][r].type){case 6:e[6].WriteUint32(t[s][r].val);break;case 5:e[5].WriteUint32(t[s][r].val);break;case 1:e[1].WriteString(t[s][r].val);break;case 2:e[2].WriteChar(t[s][r].val);break;case 7:e[7].WriteUint32(t[s][r].val);break;case 3:e[3].WriteUint32(t[s][r].val),e[4].WriteByte(t[s][r].val.length);break;case 8:case 9:e[t[s][r].type].WriteByte(t[s][r].val);}}function h(e,t,r,n){for(var i=0;i<=12;i++)if(!(e[i].pos<=0)){n.WriteByte(i+(0==i?128:0)),e[i]=e[i].buf.slice(0,e[i].pos);var o=l(e[i],r);n.WriteUint7(o.length),n.WriteData(o,o.length);}}function l(e,t){var r,n=1<<30,s=[0,1,64,65,128,129,201];for(var a in s){var f=s[a];if(!(1&f&&e.length<100||8&f&&e.length%4!=0)){try{var h=t?o.encode(e,f):i.encode(e,f);}catch(e){h=0;}h&&n>h.length&&(n=h.length,r=h);}}return r}function u(e,t,r,n,i){var o=0,s=i-1;e[i]=new Array(256),t[n]?e[i][0]={type:5,val:i-t[n]}:e[i][0]={type:6,val:0==i?0:1},t[n]=i;for(var a=n.match(/([a-zA-Z0-9]{1,9})|([^a-zA-Z0-9]+)/g),f=0;f=0&&e[s][h])if(e[s][h].str==a[f])l=10,u="";else if(7==e[s][h].type||8==e[s][h].type){var c=u-e[s][h].str;r[h]++,c>=0&&c<256&&r[h]>i/2&&(l=8,u=c);}else 3!=e[s][h].type&&9!=e[s][h].type||e[s][h].str.length!=u.length||(c=u-e[s][h].str,r[h]++,c>=0&&c<256&&r[h]>i/2&&(l=9,u=c));e[i][h]={str:a[f],val:u,type:l},o{a.callback(e);})),settled:!1,statusReporter:a,get aborted(){return this.aborter.signal.aborted}};f.aborter.addSignal(r),f.aborter.signal.addEventListener("abort",(()=>{f.settled||this.evict(e,f);})),f.promise.then((()=>{f.settled=!0;}),(()=>{f.settled=!0,this.evict(e,f);})).catch((e=>{throw console.error(e),e})),this.cache.set(e,f);}static checkSinglePromise(e,t){function r(){if(t&&t.aborted)throw Object.assign(new Error("aborted"),{code:"ERR_ABORTED"})}return e.then((e=>(r(),e)),(e=>{throw r(),e}))}has(e){return this.cache.has(e)}get(e,t,r,n){if(!r&&t instanceof i.AbortSignal)throw new TypeError("second get argument appears to be an AbortSignal, perhaps you meant to pass `null` for the fill data?");const o=this.cache.get(e);return o?o.aborted&&!o.settled?(this.evict(e,o),this.get(e,t,r,n)):o.settled?o.promise:(o.aborter.addSignal(r),o.statusReporter.addCallback(n),a.checkSinglePromise(o.promise,r)):(this.fill(e,t,r,n),a.checkSinglePromise(this.cache.get(e).promise,r))}delete(e){const t=this.cache.get(e);t&&(t.settled||t.aborter.abort(),this.cache.delete(e));}clear(){const e=this.cache.keys();let t=0;for(let r=e.next();!r.done;r=e.next())this.delete(r.value),t+=1;return t}}t.default=a;},9049:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:!0});const n=r(8904);class i{}t.default=class{constructor(){this.signals=new Set,this.abortController=new n.AbortController;}addSignal(e=new i){if(this.signal.aborted)throw new Error("cannot add a signal, already aborted!");this.signals.add(e),e.aborted?this.handleAborted(e):"function"==typeof e.addEventListener&&e.addEventListener("abort",(()=>{this.handleAborted(e);}));}handleAborted(e){this.signals.delete(e),0===this.signals.size&&this.abortController.abort();}get signal(){return this.abortController.signal}abort(){this.abortController.abort();}};},450:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.default=class{constructor(){this.callbacks=new Set;}addCallback(e=(()=>{})){this.callbacks.add(e),e(this.currentMessage);}callback(e){this.currentMessage=e,this.callbacks.forEach((t=>{t(e);}));}};},8904:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.AbortSignal=t.AbortController=void 0;const n=r(5988);var i=function(){if("undefined"!=typeof self)return self;if("undefined"!=typeof window)return window;if(void 0!==r.g)return r.g;throw new Error("unable to locate global object")};let o=void 0===i().AbortController?n.AbortController:i().AbortController;t.AbortController=o;let s=void 0===i().AbortController?n.AbortSignal:i().AbortSignal;t.AbortSignal=s;},4105:function(e,t,r){var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const i=n(r(1422));t.default=i.default;},5988:(e,t)=>{function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function n(e,t){for(var r=0;r{t.byteLength=function(e){var t=f(e),r=t[0],n=t[1];return 3*(r+n)/4-n},t.toByteArray=function(e){var t,r,o=f(e),s=o[0],a=o[1],h=new i(function(e,t,r){return 3*(t+r)/4-r}(0,s,a)),l=0,u=a>0?s-4:s;for(r=0;r>16&255,h[l++]=t>>8&255,h[l++]=255&t;return 2===a&&(t=n[e.charCodeAt(r)]<<2|n[e.charCodeAt(r+1)]>>4,h[l++]=255&t),1===a&&(t=n[e.charCodeAt(r)]<<10|n[e.charCodeAt(r+1)]<<4|n[e.charCodeAt(r+2)]>>2,h[l++]=t>>8&255,h[l++]=255&t),h},t.fromByteArray=function(e){for(var t,n=e.length,i=n%3,o=[],s=16383,a=0,f=n-i;af?f:a+s));return 1===i?(t=e[n-1],o.push(r[t>>2]+r[t<<4&63]+"==")):2===i&&(t=(e[n-2]<<8)+e[n-1],o.push(r[t>>10]+r[t>>4&63]+r[t<<2&63]+"=")),o.join("")};for(var r=[],n=[],i="undefined"!=typeof Uint8Array?Uint8Array:Array,o="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",s=0,a=o.length;s0)throw new Error("Invalid string. Length must be a multiple of 4");var r=e.indexOf("=");return -1===r&&(r=t),[r,r===t?0:4-r%4]}function h(e,t,n){for(var i,o,s=[],a=t;a>18&63]+r[o>>12&63]+r[o>>6&63]+r[63&o]);return s.join("")}n["-".charCodeAt(0)]=62,n["_".charCodeAt(0)]=63;},2779:(e,t,r)=>{var n=r(8764).Buffer,i=[0,1996959894,3993919788,2567524794,124634137,1886057615,3915621685,2657392035,249268274,2044508324,3772115230,2547177864,162941995,2125561021,3887607047,2428444049,498536548,1789927666,4089016648,2227061214,450548861,1843258603,4107580753,2211677639,325883990,1684777152,4251122042,2321926636,335633487,1661365465,4195302755,2366115317,997073096,1281953886,3579855332,2724688242,1006888145,1258607687,3524101629,2768942443,901097722,1119000684,3686517206,2898065728,853044451,1172266101,3705015759,2882616665,651767980,1373503546,3369554304,3218104598,565507253,1454621731,3485111705,3099436303,671266974,1594198024,3322730930,2970347812,795835527,1483230225,3244367275,3060149565,1994146192,31158534,2563907772,4023717930,1907459465,112637215,2680153253,3904427059,2013776290,251722036,2517215374,3775830040,2137656763,141376813,2439277719,3865271297,1802195444,476864866,2238001368,4066508878,1812370925,453092731,2181625025,4111451223,1706088902,314042704,2344532202,4240017532,1658658271,366619977,2362670323,4224994405,1303535960,984961486,2747007092,3569037538,1256170817,1037604311,2765210733,3554079995,1131014506,879679996,2909243462,3663771856,1141124467,855842277,2852801631,3708648649,1342533948,654459306,3188396048,3373015174,1466479909,544179635,3110523913,3462522015,1591671054,702138776,2966460450,3352799412,1504918807,783551873,3082640443,3233442989,3988292384,2596254646,62317068,1957810842,3939845945,2647816111,81470997,1943803523,3814918930,2489596804,225274430,2053790376,3826175755,2466906013,167816743,2097651377,4027552580,2265490386,503444072,1762050814,4150417245,2154129355,426522225,1852507879,4275313526,2312317920,282753626,1742555852,4189708143,2394877945,397917763,1622183637,3604390888,2714866558,953729732,1340076626,3518719985,2797360999,1068828381,1219638859,3624741850,2936675148,906185462,1090812512,3747672003,2825379669,829329135,1181335161,3412177804,3160834842,628085408,1382605366,3423369109,3138078467,570562233,1426400815,3317316542,2998733608,733239954,1555261956,3268935591,3050360625,752459403,1541320221,2607071920,3965973030,1969922972,40735498,2617837225,3943577151,1913087877,83908371,2512341634,3803740692,2075208622,213261112,2463272603,3855990285,2094854071,198958881,2262029012,4057260610,1759359992,534414190,2176718541,4139329115,1873836001,414664567,2282248934,4279200368,1711684554,285281116,2405801727,4167216745,1634467795,376229701,2685067896,3608007406,1308918612,956543938,2808555105,3495958263,1231636301,1047427035,2932959818,3654703836,1088359270,936918e3,2847714899,3736837829,1202900863,817233897,3183342108,3401237130,1404277552,615818150,3134207493,3453421203,1423857449,601450431,3009837614,3294710456,1567103746,711928724,3020668471,3272380065,1510334235,755167117];function o(e){if(n.isBuffer(e))return e;var t="function"==typeof n.alloc&&"function"==typeof n.from;if("number"==typeof e)return t?n.alloc(e):new n(e);if("string"==typeof e)return t?n.from(e):new n(e);throw new Error("input must be buffer, number, or string, received "+typeof e)}function s(e){var t=o(4);return t.writeInt32BE(e,0),t}function a(e,t){e=o(e),n.isBuffer(t)&&(t=t.readUInt32BE(0));for(var r=-1^~~t,s=0;s>>8;return -1^r}function f(){return s(a.apply(null,arguments))}"undefined"!=typeof Int32Array&&(i=new Int32Array(i)),f.signed=function(){return a.apply(null,arguments)},f.unsigned=function(){return a.apply(null,arguments)>>>0},e.exports=f;},8764:(e,t,r)=>{const n=r(9742),i=r(645),o="function"==typeof Symbol&&"function"==typeof Symbol.for?Symbol.for("nodejs.util.inspect.custom"):null;t.Buffer=f,t.SlowBuffer=function(e){return +e!=e&&(e=0),f.alloc(+e)},t.INSPECT_MAX_BYTES=50;const s=2147483647;function a(e){if(e>s)throw new RangeError('The value "'+e+'" is invalid for option "size"');const t=new Uint8Array(e);return Object.setPrototypeOf(t,f.prototype),t}function f(e,t,r){if("number"==typeof e){if("string"==typeof t)throw new TypeError('The "string" argument must be of type string. Received type number');return u(e)}return h(e,t,r)}function h(e,t,r){if("string"==typeof e)return function(e,t){if("string"==typeof t&&""!==t||(t="utf8"),!f.isEncoding(t))throw new TypeError("Unknown encoding: "+t);const r=0|g(e,t);let n=a(r);const i=n.write(e,t);return i!==r&&(n=n.slice(0,i)),n}(e,t);if(ArrayBuffer.isView(e))return function(e){if(Q(e,Uint8Array)){const t=new Uint8Array(e);return d(t.buffer,t.byteOffset,t.byteLength)}return c(e)}(e);if(null==e)throw new TypeError("The first argument must be one of type string, Buffer, ArrayBuffer, Array, or Array-like Object. Received type "+typeof e);if(Q(e,ArrayBuffer)||e&&Q(e.buffer,ArrayBuffer))return d(e,t,r);if("undefined"!=typeof SharedArrayBuffer&&(Q(e,SharedArrayBuffer)||e&&Q(e.buffer,SharedArrayBuffer)))return d(e,t,r);if("number"==typeof e)throw new TypeError('The "value" argument must not be of type number. Received type number');const n=e.valueOf&&e.valueOf();if(null!=n&&n!==e)return f.from(n,t,r);const i=function(e){if(f.isBuffer(e)){const t=0|p(e.length),r=a(t);return 0===r.length||e.copy(r,0,0,t),r}return void 0!==e.length?"number"!=typeof e.length||Y(e.length)?a(0):c(e):"Buffer"===e.type&&Array.isArray(e.data)?c(e.data):void 0}(e);if(i)return i;if("undefined"!=typeof Symbol&&null!=Symbol.toPrimitive&&"function"==typeof e[Symbol.toPrimitive])return f.from(e[Symbol.toPrimitive]("string"),t,r);throw new TypeError("The first argument must be one of type string, Buffer, ArrayBuffer, Array, or Array-like Object. Received type "+typeof e)}function l(e){if("number"!=typeof e)throw new TypeError('"size" argument must be of type number');if(e<0)throw new RangeError('The value "'+e+'" is invalid for option "size"')}function u(e){return l(e),a(e<0?0:0|p(e))}function c(e){const t=e.length<0?0:0|p(e.length),r=a(t);for(let n=0;n=s)throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+s.toString(16)+" bytes");return 0|e}function g(e,t){if(f.isBuffer(e))return e.length;if(ArrayBuffer.isView(e)||Q(e,ArrayBuffer))return e.byteLength;if("string"!=typeof e)throw new TypeError('The "string" argument must be one of type string, Buffer, or ArrayBuffer. Received type '+typeof e);const r=e.length,n=arguments.length>2&&!0===arguments[2];if(!n&&0===r)return 0;let i=!1;for(;;)switch(t){case"ascii":case"latin1":case"binary":return r;case"utf8":case"utf-8":return V(e).length;case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return 2*r;case"hex":return r>>>1;case"base64":return Z(e).length;default:if(i)return n?-1:V(e).length;t=(""+t).toLowerCase(),i=!0;}}function m(e,t,r){let n=!1;if((void 0===t||t<0)&&(t=0),t>this.length)return "";if((void 0===r||r>this.length)&&(r=this.length),r<=0)return "";if((r>>>=0)<=(t>>>=0))return "";for(e||(e="utf8");;)switch(e){case"hex":return I(this,t,r);case"utf8":case"utf-8":return C(this,t,r);case"ascii":return k(this,t,r);case"latin1":case"binary":return x(this,t,r);case"base64":return A(this,t,r);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return M(this,t,r);default:if(n)throw new TypeError("Unknown encoding: "+e);e=(e+"").toLowerCase(),n=!0;}}function y(e,t,r){const n=e[t];e[t]=e[r],e[r]=n;}function b(e,t,r,n,i){if(0===e.length)return -1;if("string"==typeof r?(n=r,r=0):r>2147483647?r=2147483647:r<-2147483648&&(r=-2147483648),Y(r=+r)&&(r=i?0:e.length-1),r<0&&(r=e.length+r),r>=e.length){if(i)return -1;r=e.length-1;}else if(r<0){if(!i)return -1;r=0;}if("string"==typeof t&&(t=f.from(t,n)),f.isBuffer(t))return 0===t.length?-1:v(e,t,r,n,i);if("number"==typeof t)return t&=255,"function"==typeof Uint8Array.prototype.indexOf?i?Uint8Array.prototype.indexOf.call(e,t,r):Uint8Array.prototype.lastIndexOf.call(e,t,r):v(e,[t],r,n,i);throw new TypeError("val must be string, number or Buffer")}function v(e,t,r,n,i){let o,s=1,a=e.length,f=t.length;if(void 0!==n&&("ucs2"===(n=String(n).toLowerCase())||"ucs-2"===n||"utf16le"===n||"utf-16le"===n)){if(e.length<2||t.length<2)return -1;s=2,a/=2,f/=2,r/=2;}function h(e,t){return 1===s?e[t]:e.readUInt16BE(t*s)}if(i){let n=-1;for(o=r;oa&&(r=a-f),o=r;o>=0;o--){let r=!0;for(let n=0;ni&&(n=i):n=i;const o=t.length;let s;for(n>o/2&&(n=o/2),s=0;s>8,i=r%256,o.push(i),o.push(n);return o}(t,e.length-r),e,r,n)}function A(e,t,r){return 0===t&&r===e.length?n.fromByteArray(e):n.fromByteArray(e.slice(t,r))}function C(e,t,r){r=Math.min(e.length,r);const n=[];let i=t;for(;i239?4:t>223?3:t>191?2:1;if(i+s<=r){let r,n,a,f;switch(s){case 1:t<128&&(o=t);break;case 2:r=e[i+1],128==(192&r)&&(f=(31&t)<<6|63&r,f>127&&(o=f));break;case 3:r=e[i+1],n=e[i+2],128==(192&r)&&128==(192&n)&&(f=(15&t)<<12|(63&r)<<6|63&n,f>2047&&(f<55296||f>57343)&&(o=f));break;case 4:r=e[i+1],n=e[i+2],a=e[i+3],128==(192&r)&&128==(192&n)&&128==(192&a)&&(f=(15&t)<<18|(63&r)<<12|(63&n)<<6|63&a,f>65535&&f<1114112&&(o=f));}}null===o?(o=65533,s=1):o>65535&&(o-=65536,n.push(o>>>10&1023|55296),o=56320|1023&o),n.push(o),i+=s;}return function(e){const t=e.length;if(t<=R)return String.fromCharCode.apply(String,e);let r="",n=0;for(;nn.length?(f.isBuffer(t)||(t=f.from(t)),t.copy(n,i)):Uint8Array.prototype.set.call(n,t,i);else {if(!f.isBuffer(t))throw new TypeError('"list" argument must be an Array of Buffers');t.copy(n,i);}i+=t.length;}return n},f.byteLength=g,f.prototype._isBuffer=!0,f.prototype.swap16=function(){const e=this.length;if(e%2!=0)throw new RangeError("Buffer size must be a multiple of 16-bits");for(let t=0;tr&&(e+=" ... "),""},o&&(f.prototype[o]=f.prototype.inspect),f.prototype.compare=function(e,t,r,n,i){if(Q(e,Uint8Array)&&(e=f.from(e,e.offset,e.byteLength)),!f.isBuffer(e))throw new TypeError('The "target" argument must be one of type Buffer or Uint8Array. Received type '+typeof e);if(void 0===t&&(t=0),void 0===r&&(r=e?e.length:0),void 0===n&&(n=0),void 0===i&&(i=this.length),t<0||r>e.length||n<0||i>this.length)throw new RangeError("out of range index");if(n>=i&&t>=r)return 0;if(n>=i)return -1;if(t>=r)return 1;if(this===e)return 0;let o=(i>>>=0)-(n>>>=0),s=(r>>>=0)-(t>>>=0);const a=Math.min(o,s),h=this.slice(n,i),l=e.slice(t,r);for(let e=0;e>>=0,isFinite(r)?(r>>>=0,void 0===n&&(n="utf8")):(n=r,r=void 0);}const i=this.length-t;if((void 0===r||r>i)&&(r=i),e.length>0&&(r<0||t<0)||t>this.length)throw new RangeError("Attempt to write outside buffer bounds");n||(n="utf8");let o=!1;for(;;)switch(n){case"hex":return w(this,e,t,r);case"utf8":case"utf-8":return _(this,e,t,r);case"ascii":case"latin1":case"binary":return B(this,e,t,r);case"base64":return E(this,e,t,r);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return S(this,e,t,r);default:if(o)throw new TypeError("Unknown encoding: "+n);n=(""+n).toLowerCase(),o=!0;}},f.prototype.toJSON=function(){return {type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}};const R=4096;function k(e,t,r){let n="";r=Math.min(e.length,r);for(let i=t;in)&&(r=n);let i="";for(let n=t;nr)throw new RangeError("Trying to access beyond buffer length")}function O(e,t,r,n,i,o){if(!f.isBuffer(e))throw new TypeError('"buffer" argument must be a Buffer instance');if(t>i||te.length)throw new RangeError("Index out of range")}function T(e,t,r,n,i){j(t,n,i,e,r,7);let o=Number(t&BigInt(4294967295));e[r++]=o,o>>=8,e[r++]=o,o>>=8,e[r++]=o,o>>=8,e[r++]=o;let s=Number(t>>BigInt(32)&BigInt(4294967295));return e[r++]=s,s>>=8,e[r++]=s,s>>=8,e[r++]=s,s>>=8,e[r++]=s,r}function U(e,t,r,n,i){j(t,n,i,e,r,7);let o=Number(t&BigInt(4294967295));e[r+7]=o,o>>=8,e[r+6]=o,o>>=8,e[r+5]=o,o>>=8,e[r+4]=o;let s=Number(t>>BigInt(32)&BigInt(4294967295));return e[r+3]=s,s>>=8,e[r+2]=s,s>>=8,e[r+1]=s,s>>=8,e[r]=s,r+8}function P(e,t,r,n,i,o){if(r+n>e.length)throw new RangeError("Index out of range");if(r<0)throw new RangeError("Index out of range")}function N(e,t,r,n,o){return t=+t,r>>>=0,o||P(e,0,r,4),i.write(e,t,r,n,23,4),r+4}function L(e,t,r,n,o){return t=+t,r>>>=0,o||P(e,0,r,8),i.write(e,t,r,n,52,8),r+8}f.prototype.slice=function(e,t){const r=this.length;(e=~~e)<0?(e+=r)<0&&(e=0):e>r&&(e=r),(t=void 0===t?r:~~t)<0?(t+=r)<0&&(t=0):t>r&&(t=r),t>>=0,t>>>=0,r||F(e,t,this.length);let n=this[e],i=1,o=0;for(;++o>>=0,t>>>=0,r||F(e,t,this.length);let n=this[e+--t],i=1;for(;t>0&&(i*=256);)n+=this[e+--t]*i;return n},f.prototype.readUint8=f.prototype.readUInt8=function(e,t){return e>>>=0,t||F(e,1,this.length),this[e]},f.prototype.readUint16LE=f.prototype.readUInt16LE=function(e,t){return e>>>=0,t||F(e,2,this.length),this[e]|this[e+1]<<8},f.prototype.readUint16BE=f.prototype.readUInt16BE=function(e,t){return e>>>=0,t||F(e,2,this.length),this[e]<<8|this[e+1]},f.prototype.readUint32LE=f.prototype.readUInt32LE=function(e,t){return e>>>=0,t||F(e,4,this.length),(this[e]|this[e+1]<<8|this[e+2]<<16)+16777216*this[e+3]},f.prototype.readUint32BE=f.prototype.readUInt32BE=function(e,t){return e>>>=0,t||F(e,4,this.length),16777216*this[e]+(this[e+1]<<16|this[e+2]<<8|this[e+3])},f.prototype.readBigUInt64LE=X((function(e){H(e>>>=0,"offset");const t=this[e],r=this[e+7];void 0!==t&&void 0!==r||W(e,this.length-8);const n=t+256*this[++e]+65536*this[++e]+this[++e]*2**24,i=this[++e]+256*this[++e]+65536*this[++e]+r*2**24;return BigInt(n)+(BigInt(i)<>>=0,"offset");const t=this[e],r=this[e+7];void 0!==t&&void 0!==r||W(e,this.length-8);const n=t*2**24+65536*this[++e]+256*this[++e]+this[++e],i=this[++e]*2**24+65536*this[++e]+256*this[++e]+r;return (BigInt(n)<>>=0,t>>>=0,r||F(e,t,this.length);let n=this[e],i=1,o=0;for(;++o=i&&(n-=Math.pow(2,8*t)),n},f.prototype.readIntBE=function(e,t,r){e>>>=0,t>>>=0,r||F(e,t,this.length);let n=t,i=1,o=this[e+--n];for(;n>0&&(i*=256);)o+=this[e+--n]*i;return i*=128,o>=i&&(o-=Math.pow(2,8*t)),o},f.prototype.readInt8=function(e,t){return e>>>=0,t||F(e,1,this.length),128&this[e]?-1*(255-this[e]+1):this[e]},f.prototype.readInt16LE=function(e,t){e>>>=0,t||F(e,2,this.length);const r=this[e]|this[e+1]<<8;return 32768&r?4294901760|r:r},f.prototype.readInt16BE=function(e,t){e>>>=0,t||F(e,2,this.length);const r=this[e+1]|this[e]<<8;return 32768&r?4294901760|r:r},f.prototype.readInt32LE=function(e,t){return e>>>=0,t||F(e,4,this.length),this[e]|this[e+1]<<8|this[e+2]<<16|this[e+3]<<24},f.prototype.readInt32BE=function(e,t){return e>>>=0,t||F(e,4,this.length),this[e]<<24|this[e+1]<<16|this[e+2]<<8|this[e+3]},f.prototype.readBigInt64LE=X((function(e){H(e>>>=0,"offset");const t=this[e],r=this[e+7];void 0!==t&&void 0!==r||W(e,this.length-8);const n=this[e+4]+256*this[e+5]+65536*this[e+6]+(r<<24);return (BigInt(n)<>>=0,"offset");const t=this[e],r=this[e+7];void 0!==t&&void 0!==r||W(e,this.length-8);const n=(t<<24)+65536*this[++e]+256*this[++e]+this[++e];return (BigInt(n)<>>=0,t||F(e,4,this.length),i.read(this,e,!0,23,4)},f.prototype.readFloatBE=function(e,t){return e>>>=0,t||F(e,4,this.length),i.read(this,e,!1,23,4)},f.prototype.readDoubleLE=function(e,t){return e>>>=0,t||F(e,8,this.length),i.read(this,e,!0,52,8)},f.prototype.readDoubleBE=function(e,t){return e>>>=0,t||F(e,8,this.length),i.read(this,e,!1,52,8)},f.prototype.writeUintLE=f.prototype.writeUIntLE=function(e,t,r,n){e=+e,t>>>=0,r>>>=0,n||O(this,e,t,r,Math.pow(2,8*r)-1,0);let i=1,o=0;for(this[t]=255&e;++o>>=0,r>>>=0,n||O(this,e,t,r,Math.pow(2,8*r)-1,0);let i=r-1,o=1;for(this[t+i]=255&e;--i>=0&&(o*=256);)this[t+i]=e/o&255;return t+r},f.prototype.writeUint8=f.prototype.writeUInt8=function(e,t,r){return e=+e,t>>>=0,r||O(this,e,t,1,255,0),this[t]=255&e,t+1},f.prototype.writeUint16LE=f.prototype.writeUInt16LE=function(e,t,r){return e=+e,t>>>=0,r||O(this,e,t,2,65535,0),this[t]=255&e,this[t+1]=e>>>8,t+2},f.prototype.writeUint16BE=f.prototype.writeUInt16BE=function(e,t,r){return e=+e,t>>>=0,r||O(this,e,t,2,65535,0),this[t]=e>>>8,this[t+1]=255&e,t+2},f.prototype.writeUint32LE=f.prototype.writeUInt32LE=function(e,t,r){return e=+e,t>>>=0,r||O(this,e,t,4,4294967295,0),this[t+3]=e>>>24,this[t+2]=e>>>16,this[t+1]=e>>>8,this[t]=255&e,t+4},f.prototype.writeUint32BE=f.prototype.writeUInt32BE=function(e,t,r){return e=+e,t>>>=0,r||O(this,e,t,4,4294967295,0),this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e,t+4},f.prototype.writeBigUInt64LE=X((function(e,t=0){return T(this,e,t,BigInt(0),BigInt("0xffffffffffffffff"))})),f.prototype.writeBigUInt64BE=X((function(e,t=0){return U(this,e,t,BigInt(0),BigInt("0xffffffffffffffff"))})),f.prototype.writeIntLE=function(e,t,r,n){if(e=+e,t>>>=0,!n){const n=Math.pow(2,8*r-1);O(this,e,t,r,n-1,-n);}let i=0,o=1,s=0;for(this[t]=255&e;++i>0)-s&255;return t+r},f.prototype.writeIntBE=function(e,t,r,n){if(e=+e,t>>>=0,!n){const n=Math.pow(2,8*r-1);O(this,e,t,r,n-1,-n);}let i=r-1,o=1,s=0;for(this[t+i]=255&e;--i>=0&&(o*=256);)e<0&&0===s&&0!==this[t+i+1]&&(s=1),this[t+i]=(e/o>>0)-s&255;return t+r},f.prototype.writeInt8=function(e,t,r){return e=+e,t>>>=0,r||O(this,e,t,1,127,-128),e<0&&(e=255+e+1),this[t]=255&e,t+1},f.prototype.writeInt16LE=function(e,t,r){return e=+e,t>>>=0,r||O(this,e,t,2,32767,-32768),this[t]=255&e,this[t+1]=e>>>8,t+2},f.prototype.writeInt16BE=function(e,t,r){return e=+e,t>>>=0,r||O(this,e,t,2,32767,-32768),this[t]=e>>>8,this[t+1]=255&e,t+2},f.prototype.writeInt32LE=function(e,t,r){return e=+e,t>>>=0,r||O(this,e,t,4,2147483647,-2147483648),this[t]=255&e,this[t+1]=e>>>8,this[t+2]=e>>>16,this[t+3]=e>>>24,t+4},f.prototype.writeInt32BE=function(e,t,r){return e=+e,t>>>=0,r||O(this,e,t,4,2147483647,-2147483648),e<0&&(e=4294967295+e+1),this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e,t+4},f.prototype.writeBigInt64LE=X((function(e,t=0){return T(this,e,t,-BigInt("0x8000000000000000"),BigInt("0x7fffffffffffffff"))})),f.prototype.writeBigInt64BE=X((function(e,t=0){return U(this,e,t,-BigInt("0x8000000000000000"),BigInt("0x7fffffffffffffff"))})),f.prototype.writeFloatLE=function(e,t,r){return N(this,e,t,!0,r)},f.prototype.writeFloatBE=function(e,t,r){return N(this,e,t,!1,r)},f.prototype.writeDoubleLE=function(e,t,r){return L(this,e,t,!0,r)},f.prototype.writeDoubleBE=function(e,t,r){return L(this,e,t,!1,r)},f.prototype.copy=function(e,t,r,n){if(!f.isBuffer(e))throw new TypeError("argument should be a Buffer");if(r||(r=0),n||0===n||(n=this.length),t>=e.length&&(t=e.length),t||(t=0),n>0&&n=this.length)throw new RangeError("Index out of range");if(n<0)throw new RangeError("sourceEnd out of bounds");n>this.length&&(n=this.length),e.length-t>>=0,r=void 0===r?this.length:r>>>0,e||(e=0),"number"==typeof e)for(i=t;i=n+4;r-=3)t=`_${e.slice(r-3,r)}${t}`;return `${e.slice(0,r)}${t}`}function j(e,t,r,n,i,o){if(e>r||e3?0===t||t===BigInt(0)?`>= 0${n} and < 2${n} ** ${8*(o+1)}${n}`:`>= -(2${n} ** ${8*(o+1)-1}${n}) and < 2 ** ${8*(o+1)-1}${n}`:`>= ${t}${n} and <= ${r}${n}`,new z.ERR_OUT_OF_RANGE("value",i,e)}!function(e,t,r){H(t,"offset"),void 0!==e[t]&&void 0!==e[t+r]||W(t,e.length-(r+1));}(n,i,o);}function H(e,t){if("number"!=typeof e)throw new z.ERR_INVALID_ARG_TYPE(t,"number",e)}function W(e,t,r){if(Math.floor(e)!==e)throw H(e,r),new z.ERR_OUT_OF_RANGE(r||"offset","an integer",e);if(t<0)throw new z.ERR_BUFFER_OUT_OF_BOUNDS;throw new z.ERR_OUT_OF_RANGE(r||"offset",`>= ${r?1:0} and <= ${t}`,e)}D("ERR_BUFFER_OUT_OF_BOUNDS",(function(e){return e?`${e} is outside of buffer bounds`:"Attempt to access memory outside buffer bounds"}),RangeError),D("ERR_INVALID_ARG_TYPE",(function(e,t){return `The "${e}" argument must be of type number. Received type ${typeof t}`}),TypeError),D("ERR_OUT_OF_RANGE",(function(e,t,r){let n=`The value of "${e}" is out of range.`,i=r;return Number.isInteger(r)&&Math.abs(r)>2**32?i=q(String(r)):"bigint"==typeof r&&(i=String(r),(r>BigInt(2)**BigInt(32)||r<-(BigInt(2)**BigInt(32)))&&(i=q(i)),i+="n"),n+=` It must be ${t}. Received ${i}`,n}),RangeError);const $=/[^+/0-9A-Za-z-_]/g;function V(e,t){let r;t=t||1/0;const n=e.length;let i=null;const o=[];for(let s=0;s55295&&r<57344){if(!i){if(r>56319){(t-=3)>-1&&o.push(239,191,189);continue}if(s+1===n){(t-=3)>-1&&o.push(239,191,189);continue}i=r;continue}if(r<56320){(t-=3)>-1&&o.push(239,191,189),i=r;continue}r=65536+(i-55296<<10|r-56320);}else i&&(t-=3)>-1&&o.push(239,191,189);if(i=null,r<128){if((t-=1)<0)break;o.push(r);}else if(r<2048){if((t-=2)<0)break;o.push(r>>6|192,63&r|128);}else if(r<65536){if((t-=3)<0)break;o.push(r>>12|224,r>>6&63|128,63&r|128);}else {if(!(r<1114112))throw new Error("Invalid code point");if((t-=4)<0)break;o.push(r>>18|240,r>>12&63|128,r>>6&63|128,63&r|128);}}return o}function Z(e){return n.toByteArray(function(e){if((e=(e=e.split("=")[0]).trim().replace($,"")).length<2)return "";for(;e.length%4!=0;)e+="=";return e}(e))}function G(e,t,r,n){let i;for(i=0;i=t.length||i>=e.length);++i)t[i+r]=e[i];return i}function Q(e,t){return e instanceof t||null!=e&&null!=e.constructor&&null!=e.constructor.name&&e.constructor.name===t.name}function Y(e){return e!=e}const K=function(){const e="0123456789abcdef",t=new Array(256);for(let r=0;r<16;++r){const n=16*r;for(let i=0;i<16;++i)t[n+i]=e[r]+e[i];}return t}();function X(e){return "undefined"==typeof BigInt?J:e}function J(){throw new Error("BigInt not supported")}},4693:e=>{var t={array:function(e){var t=0,r=0,n=[0,1,3,7,15,31,63,127,255];return function(i){for(var o=0;i>0;){var s=8-t;i>=s?(o<<=s,o|=n[s]&e[r++],t=0,i-=s):(o<<=i,o|=(e[r]&n[i]<<8-i-t)>>8-i-t,t+=i,i=0);}return o}},simple:function(e){var r,n,i=t.header(e),o=[],s=0;do{-1!=(n=t.decompress(e,i))&&(o.push(n),s+=n.byteLength);}while(-1!=n);r=new Uint8Array(s),s=0;for(var a=0;a9)throw "Not a BZIP archive";return t},decompress:function(e,t,r){for(var n=9e5,i="",o=0;o<6;o++)i+=e(8).toString(16);if("177245385090"==i)return -1;if("314159265359"!=i)throw "eek not valid bzip data";if(e(32),e(1))throw "unsupported obsolete version";var s=e(24);if(s>n)throw "Initial position larger than buffer size";var a=e(16),f=new Uint8Array(256),h=0;for(o=0;o<16;o++)if(a&1<<15-o){var l=e(16);for(g=0;g<16;g++)l&1<<15-g&&(f[h++]=16*o+g);}var u=e(3);if(u<2||u>6)throw "another error";var c=e(15);if(0==c)throw "meh";var d=[];for(o=0;o=u)throw "whoops another error";var m=d[g];d.splice(g,1),d.splice(0,0,m),p[o]=m;}var y=h+2,b=[];for(g=0;g20)throw "I gave up a while ago on writing error messages";if(!e(1))break;e(1)?a--:a++;}B[o]=a;}for(v=w=B[0],o=1;ow?w=B[o]:B[o]=c)throw "meow i'm a kitty, that's an error";S=(_=b[p[x++]]).base.subarray(1),A=_.limit.subarray(1);}for(g=e(o=_.minLen);;){if(o>_.maxLen)throw "rawr i'm a dinosaur";if(g<=A[o])break;o++,g=g<<1|e(1);}if((g-=S[o])<0||g>=258)throw "moo i'm a cow";var F=_.permute[g];if(0!=F&&1!=F){if(R){if(R=0,k+a>=n)throw "Boom.";for(I[m=f[d[0]]]+=a;a--;)M[k++]=m;}if(F>h)break;if(k>=n)throw "I can't think of anything. Error";m=d[o=F-1],d.splice(o,1),d.splice(0,0,m),I[m=f[m]]++,M[k++]=m;}else R||(R=1,a=0),a+=0==F?R:2*R,R<<=1;}if(s<0||s>=k)throw "I'm a monkey and I'm throwing something at someone, namely you";for(g=0,o=0;o<256;o++)l=g+I[o],I[o]=g,g=l;for(o=0;o>=8,U=-1);var P,N,L,z=new Uint8Array(n),D=0;for(r||(r=1/0);k;){for(k--,N=T,T=255&(O=M[O]),O>>=8,3==U++?(P=T,L=N,T=-1):(P=1,L=T);P--;)if(z[D++]=L,!--r)return z;T!=N&&(U=0);}return z.subarray(0,D)}};e.exports=t;},487:e=>{var t={utf8:{stringToBytes:function(e){return t.bin.stringToBytes(unescape(encodeURIComponent(e)))},bytesToString:function(e){return decodeURIComponent(escape(t.bin.bytesToString(e)))}},bin:{stringToBytes:function(e){for(var t=[],r=0;r{var t,r;t="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",r={rotl:function(e,t){return e<>>32-t},rotr:function(e,t){return e<<32-t|e>>>t},endian:function(e){if(e.constructor==Number)return 16711935&r.rotl(e,8)|4278255360&r.rotl(e,24);for(var t=0;t0;e--)t.push(Math.floor(256*Math.random()));return t},bytesToWords:function(e){for(var t=[],r=0,n=0;r>>5]|=e[r]<<24-n%32;return t},wordsToBytes:function(e){for(var t=[],r=0;r<32*e.length;r+=8)t.push(e[r>>>5]>>>24-r%32&255);return t},bytesToHex:function(e){for(var t=[],r=0;r>>4).toString(16)),t.push((15&e[r]).toString(16));return t.join("")},hexToBytes:function(e){for(var t=[],r=0;r>>6*(3-o)&63)):r.push("=");return r.join("")},base64ToBytes:function(e){e=e.replace(/[^A-Z0-9+\/]/gi,"");for(var r=[],n=0,i=0;n>>6-2*i);return r}},e.exports=r;},2949:(e,t,r)=>{r.r(t),r.d(t,{BlobFile:()=>h,LocalFile:()=>i(),RemoteFile:()=>a,fromUrl:()=>l,open:()=>u});var n=r(7067),i=r.n(n),o=r(8764);const s="undefined"!=typeof window?window:"undefined"!=typeof self?self:{fetch:void 0};class a{constructor(e,t={}){this.baseOverrides={},this.url=e;const r=t.fetch||s.fetch&&s.fetch.bind(s);if(!r)throw new TypeError("no fetch function supplied, and none found in global environment");t.overrides&&(this.baseOverrides=t.overrides),this.fetchImplementation=r;}async getBufferFromResponse(e){if("function"==typeof e.buffer)return e.buffer();if("function"==typeof e.arrayBuffer){const t=await e.arrayBuffer();return o.Buffer.from(t)}throw new TypeError("invalid HTTP response object, has no buffer method, and no arrayBuffer method")}async fetch(e,t){let r;try{r=await this.fetchImplementation(e,t);}catch(n){if(!`${n}`.includes("Failed to fetch"))throw n;console.warn(`generic-filehandle: refetching ${e} to attempt to work around chrome CORS header caching bug`),r=await this.fetchImplementation(e,{...t,cache:"reload"});}return r}async read(e,t=0,r,n=0,i={}){const{headers:o={},signal:s,overrides:a={}}=i;r<1/0?o.range=`bytes=${n}-${n+r}`:r===1/0&&0!==n&&(o.range=`bytes=${n}-`);const f={...this.baseOverrides,...a,headers:{...o,...a.headers,...this.baseOverrides.headers},method:"GET",redirect:"follow",mode:"cors",signal:s},h=await this.fetch(this.url,f);if(!h.ok)throw new Error(`HTTP ${h.status} ${h.statusText} ${this.url}`);if(200===h.status&&0===n||206===h.status){const n=await this.getBufferFromResponse(h),i=n.copy(e,t,0,Math.min(r,n.length)),o=h.headers.get("content-range"),s=/\/(\d+)$/.exec(o||"");return s&&s[1]&&(this._stat={size:parseInt(s[1],10)}),{bytesRead:i,buffer:e}}if(200===h.status)throw new Error("${this.url} fetch returned status 200, expected 206");throw new Error(`HTTP ${h.status} fetching ${this.url}`)}async readFile(e={}){let t,r;"string"==typeof e?(t=e,r={}):(t=e.encoding,r=e,delete r.encoding);const{headers:n={},signal:i,overrides:o={}}=r,s={headers:n,method:"GET",redirect:"follow",mode:"cors",signal:i,...this.baseOverrides,...o},a=await this.fetch(this.url,s);if(!a)throw new Error("generic-filehandle failed to fetch");if(200!==a.status)throw Object.assign(new Error(`HTTP ${a.status} fetching ${this.url}`),{status:a.status});if("utf8"===t)return a.text();if(t)throw new Error(`unsupported encoding: ${t}`);return this.getBufferFromResponse(a)}async stat(){if(!this._stat){const e=o.Buffer.allocUnsafe(10);if(await this.read(e,0,10,0),!this._stat)throw new Error(`unable to determine size of file at ${this.url}`)}return this._stat}async close(){}}function f(e){const t=new FileReader;return new Promise(((r,n)=>{t.onerror=()=>{t.abort(),n(new Error("problem reading blob"));},t.onabort=()=>{n(new Error("blob reading was aborted"));},t.onload=()=>{t.result&&"string"!=typeof t.result?r(t.result):n(new Error("unknown error reading blob"));},t.readAsArrayBuffer(e);}))}class h{constructor(e){this.blob=e,this.size=e.size;}async read(e,t=0,r,n=0){if(!r)return {bytesRead:0,buffer:e};const i=n,s=i+r,a=await f(this.blob.slice(i,s)),h=o.Buffer.from(a);return {bytesRead:h.copy(e,t),buffer:h}}async readFile(e){let t;if(t="string"==typeof e?e:e&&e.encoding,"utf8"===t)return function(e){const t=new FileReader;return new Promise(((r,n)=>{t.onerror=()=>{t.abort(),n(new Error("problem reading blob"));},t.onabort=()=>{n(new Error("blob reading was aborted"));},t.onload=()=>{t.result&&"string"==typeof t.result?r(t.result):n(new Error("unknown error reading blob"));},t.readAsText(e);}))}(this.blob);if(t)throw new Error(`unsupported encoding: ${t}`);const r=await f(this.blob);return o.Buffer.from(r)}async stat(){return {size:this.size}}async close(){}}function l(e,t={}){return new a(e,t)}function u(e,t,r,n={}){if(void 0!==r)return r;if(void 0!==e)return l(e,n);if(void 0!==t)return new(i())(t,n);throw new Error("no url, path, or filehandle provided, cannot open")}},645:(e,t)=>{t.read=function(e,t,r,n,i){var o,s,a=8*i-n-1,f=(1<>1,l=-7,u=r?i-1:0,c=r?-1:1,d=e[t+u];for(u+=c,o=d&(1<<-l)-1,d>>=-l,l+=a;l>0;o=256*o+e[t+u],u+=c,l-=8);for(s=o&(1<<-l)-1,o>>=-l,l+=n;l>0;s=256*s+e[t+u],u+=c,l-=8);if(0===o)o=1-h;else {if(o===f)return s?NaN:1/0*(d?-1:1);s+=Math.pow(2,n),o-=h;}return (d?-1:1)*s*Math.pow(2,o-n)},t.write=function(e,t,r,n,i,o){var s,a,f,h=8*o-i-1,l=(1<>1,c=23===i?Math.pow(2,-24)-Math.pow(2,-77):0,d=n?0:o-1,p=n?1:-1,g=t<0||0===t&&1/t<0?1:0;for(t=Math.abs(t),isNaN(t)||t===1/0?(a=isNaN(t)?1:0,s=l):(s=Math.floor(Math.log(t)/Math.LN2),t*(f=Math.pow(2,-s))<1&&(s--,f*=2),(t+=s+u>=1?c/f:c*Math.pow(2,1-u))*f>=2&&(s++,f/=2),s+u>=l?(a=0,s=l):s+u>=1?(a=(t*f-1)*Math.pow(2,i),s+=u):(a=t*Math.pow(2,u-1)*Math.pow(2,i),s=0));i>=8;e[r+d]=255&a,d+=p,a/=256,i-=8);for(s=s<0;e[r+d]=255&s,d+=p,s/=256,h-=8);e[r+d-p]|=128*g;};},8738:e=>{function t(e){return !!e.constructor&&"function"==typeof e.constructor.isBuffer&&e.constructor.isBuffer(e)}e.exports=function(e){return null!=e&&(t(e)||function(e){return "function"==typeof e.readFloatLE&&"function"==typeof e.slice&&t(e.slice(0,0))}(e)||!!e._isBuffer)};},3720:e=>{e.exports=r;var t=null;try{t=new WebAssembly.Instance(new WebAssembly.Module(new Uint8Array([0,97,115,109,1,0,0,0,1,13,2,96,0,1,127,96,4,127,127,127,127,1,127,3,7,6,0,1,1,1,1,1,6,6,1,127,1,65,0,11,7,50,6,3,109,117,108,0,1,5,100,105,118,95,115,0,2,5,100,105,118,95,117,0,3,5,114,101,109,95,115,0,4,5,114,101,109,95,117,0,5,8,103,101,116,95,104,105,103,104,0,0,10,191,1,6,4,0,35,0,11,36,1,1,126,32,0,173,32,1,173,66,32,134,132,32,2,173,32,3,173,66,32,134,132,126,34,4,66,32,135,167,36,0,32,4,167,11,36,1,1,126,32,0,173,32,1,173,66,32,134,132,32,2,173,32,3,173,66,32,134,132,127,34,4,66,32,135,167,36,0,32,4,167,11,36,1,1,126,32,0,173,32,1,173,66,32,134,132,32,2,173,32,3,173,66,32,134,132,128,34,4,66,32,135,167,36,0,32,4,167,11,36,1,1,126,32,0,173,32,1,173,66,32,134,132,32,2,173,32,3,173,66,32,134,132,129,34,4,66,32,135,167,36,0,32,4,167,11,36,1,1,126,32,0,173,32,1,173,66,32,134,132,32,2,173,32,3,173,66,32,134,132,130,34,4,66,32,135,167,36,0,32,4,167,11])),{}).exports;}catch(e){}function r(e,t,r){this.low=0|e,this.high=0|t,this.unsigned=!!r;}function n(e){return !0===(e&&e.__isLong__)}r.prototype.__isLong__,Object.defineProperty(r.prototype,"__isLong__",{value:!0}),r.isLong=n;var i={},o={};function s(e,t){var r,n,s;return t?(s=0<=(e>>>=0)&&e<256)&&(n=o[e])?n:(r=f(e,(0|e)<0?-1:0,!0),s&&(o[e]=r),r):(s=-128<=(e|=0)&&e<128)&&(n=i[e])?n:(r=f(e,e<0?-1:0,!1),s&&(i[e]=r),r)}function a(e,t){if(isNaN(e))return t?y:m;if(t){if(e<0)return y;if(e>=d)return B}else {if(e<=-p)return E;if(e+1>=p)return _}return e<0?a(-e,t).neg():f(e%c|0,e/c|0,t)}function f(e,t,n){return new r(e,t,n)}r.fromInt=s,r.fromNumber=a,r.fromBits=f;var h=Math.pow;function l(e,t,r){if(0===e.length)throw Error("empty string");if("NaN"===e||"Infinity"===e||"+Infinity"===e||"-Infinity"===e)return m;if("number"==typeof t?(r=t,t=!1):t=!!t,(r=r||10)<2||360)throw Error("interior hyphen");if(0===n)return l(e.substring(1),t,r).neg();for(var i=a(h(r,8)),o=m,s=0;s>>0:this.low},S.toNumber=function(){return this.unsigned?(this.high>>>0)*c+(this.low>>>0):this.high*c+(this.low>>>0)},S.toString=function(e){if((e=e||10)<2||36>>0).toString(e);if((o=f).isZero())return l+s;for(;l.length<6;)l="0"+l;s=""+l+s;}},S.getHighBits=function(){return this.high},S.getHighBitsUnsigned=function(){return this.high>>>0},S.getLowBits=function(){return this.low},S.getLowBitsUnsigned=function(){return this.low>>>0},S.getNumBitsAbs=function(){if(this.isNegative())return this.eq(E)?64:this.neg().getNumBitsAbs();for(var e=0!=this.high?this.high:this.low,t=31;t>0&&0==(e&1<=0},S.isOdd=function(){return 1==(1&this.low)},S.isEven=function(){return 0==(1&this.low)},S.equals=function(e){return n(e)||(e=u(e)),(this.unsigned===e.unsigned||this.high>>>31!=1||e.high>>>31!=1)&&this.high===e.high&&this.low===e.low},S.eq=S.equals,S.notEquals=function(e){return !this.eq(e)},S.neq=S.notEquals,S.ne=S.notEquals,S.lessThan=function(e){return this.comp(e)<0},S.lt=S.lessThan,S.lessThanOrEqual=function(e){return this.comp(e)<=0},S.lte=S.lessThanOrEqual,S.le=S.lessThanOrEqual,S.greaterThan=function(e){return this.comp(e)>0},S.gt=S.greaterThan,S.greaterThanOrEqual=function(e){return this.comp(e)>=0},S.gte=S.greaterThanOrEqual,S.ge=S.greaterThanOrEqual,S.compare=function(e){if(n(e)||(e=u(e)),this.eq(e))return 0;var t=this.isNegative(),r=e.isNegative();return t&&!r?-1:!t&&r?1:this.unsigned?e.high>>>0>this.high>>>0||e.high===this.high&&e.low>>>0>this.low>>>0?-1:1:this.sub(e).isNegative()?-1:1},S.comp=S.compare,S.negate=function(){return !this.unsigned&&this.eq(E)?E:this.not().add(b)},S.neg=S.negate,S.add=function(e){n(e)||(e=u(e));var t=this.high>>>16,r=65535&this.high,i=this.low>>>16,o=65535&this.low,s=e.high>>>16,a=65535&e.high,h=e.low>>>16,l=0,c=0,d=0,p=0;return d+=(p+=o+(65535&e.low))>>>16,c+=(d+=i+h)>>>16,l+=(c+=r+a)>>>16,l+=t+s,f((d&=65535)<<16|(p&=65535),(l&=65535)<<16|(c&=65535),this.unsigned)},S.subtract=function(e){return n(e)||(e=u(e)),this.add(e.neg())},S.sub=S.subtract,S.multiply=function(e){if(this.isZero())return m;if(n(e)||(e=u(e)),t)return f(t.mul(this.low,this.high,e.low,e.high),t.get_high(),this.unsigned);if(e.isZero())return m;if(this.eq(E))return e.isOdd()?E:m;if(e.eq(E))return this.isOdd()?E:m;if(this.isNegative())return e.isNegative()?this.neg().mul(e.neg()):this.neg().mul(e).neg();if(e.isNegative())return this.mul(e.neg()).neg();if(this.lt(g)&&e.lt(g))return a(this.toNumber()*e.toNumber(),this.unsigned);var r=this.high>>>16,i=65535&this.high,o=this.low>>>16,s=65535&this.low,h=e.high>>>16,l=65535&e.high,c=e.low>>>16,d=65535&e.low,p=0,y=0,b=0,v=0;return b+=(v+=s*d)>>>16,y+=(b+=o*d)>>>16,b&=65535,y+=(b+=s*c)>>>16,p+=(y+=i*d)>>>16,y&=65535,p+=(y+=o*c)>>>16,y&=65535,p+=(y+=s*l)>>>16,p+=r*d+i*c+o*l+s*h,f((b&=65535)<<16|(v&=65535),(p&=65535)<<16|(y&=65535),this.unsigned)},S.mul=S.multiply,S.divide=function(e){if(n(e)||(e=u(e)),e.isZero())throw Error("division by zero");var r,i,o;if(t)return this.unsigned||-2147483648!==this.high||-1!==e.low||-1!==e.high?f((this.unsigned?t.div_u:t.div_s)(this.low,this.high,e.low,e.high),t.get_high(),this.unsigned):this;if(this.isZero())return this.unsigned?y:m;if(this.unsigned){if(e.unsigned||(e=e.toUnsigned()),e.gt(this))return y;if(e.gt(this.shru(1)))return v;o=y;}else {if(this.eq(E))return e.eq(b)||e.eq(w)?E:e.eq(E)?b:(r=this.shr(1).div(e).shl(1)).eq(m)?e.isNegative()?b:w:(i=this.sub(e.mul(r)),o=r.add(i.div(e)));if(e.eq(E))return this.unsigned?y:m;if(this.isNegative())return e.isNegative()?this.neg().div(e.neg()):this.neg().div(e).neg();if(e.isNegative())return this.div(e.neg()).neg();o=m;}for(i=this;i.gte(e);){r=Math.max(1,Math.floor(i.toNumber()/e.toNumber()));for(var s=Math.ceil(Math.log(r)/Math.LN2),l=s<=48?1:h(2,s-48),c=a(r),d=c.mul(e);d.isNegative()||d.gt(i);)d=(c=a(r-=l,this.unsigned)).mul(e);c.isZero()&&(c=b),o=o.add(c),i=i.sub(d);}return o},S.div=S.divide,S.modulo=function(e){return n(e)||(e=u(e)),t?f((this.unsigned?t.rem_u:t.rem_s)(this.low,this.high,e.low,e.high),t.get_high(),this.unsigned):this.sub(this.div(e).mul(e))},S.mod=S.modulo,S.rem=S.modulo,S.not=function(){return f(~this.low,~this.high,this.unsigned)},S.and=function(e){return n(e)||(e=u(e)),f(this.low&e.low,this.high&e.high,this.unsigned)},S.or=function(e){return n(e)||(e=u(e)),f(this.low|e.low,this.high|e.high,this.unsigned)},S.xor=function(e){return n(e)||(e=u(e)),f(this.low^e.low,this.high^e.high,this.unsigned)},S.shiftLeft=function(e){return n(e)&&(e=e.toInt()),0==(e&=63)?this:e<32?f(this.low<>>32-e,this.unsigned):f(0,this.low<>>e|this.high<<32-e,this.high>>e,this.unsigned):f(this.high>>e-32,this.high>=0?0:-1,this.unsigned)},S.shr=S.shiftRight,S.shiftRightUnsigned=function(e){if(n(e)&&(e=e.toInt()),0==(e&=63))return this;var t=this.high;return e<32?f(this.low>>>e|t<<32-e,t>>>e,this.unsigned):f(32===e?t:t>>>e-32,0,this.unsigned)},S.shru=S.shiftRightUnsigned,S.shr_u=S.shiftRightUnsigned,S.toSigned=function(){return this.unsigned?f(this.low,this.high,!1):this},S.toUnsigned=function(){return this.unsigned?this:f(this.low,this.high,!0)},S.toBytes=function(e){return e?this.toBytesLE():this.toBytesBE()},S.toBytesLE=function(){var e=this.high,t=this.low;return [255&t,t>>>8&255,t>>>16&255,t>>>24,255&e,e>>>8&255,e>>>16&255,e>>>24]},S.toBytesBE=function(){var e=this.high,t=this.low;return [e>>>24,e>>>16&255,e>>>8&255,255&e,t>>>24,t>>>16&255,t>>>8&255,255&t]},r.fromBytes=function(e,t,n){return n?r.fromBytesLE(e,t):r.fromBytesBE(e,t)},r.fromBytesLE=function(e,t){return new r(e[0]|e[1]<<8|e[2]<<16|e[3]<<24,e[4]|e[5]<<8|e[6]<<16|e[7]<<24,t)},r.fromBytesBE=function(e,t){return new r(e[4]<<24|e[5]<<16|e[6]<<8|e[7],e[0]<<24|e[1]<<16|e[2]<<8|e[3],t)};},2568:(e,t,r)=>{var n,i,o,s,a;n=r(1012),i=r(487).utf8,o=r(8738),s=r(487).bin,(a=function(e,t){e.constructor==String?e=t&&"binary"===t.encoding?s.stringToBytes(e):i.stringToBytes(e):o(e)?e=Array.prototype.slice.call(e,0):Array.isArray(e)||e.constructor===Uint8Array||(e=e.toString());for(var r=n.bytesToWords(e),f=8*e.length,h=1732584193,l=-271733879,u=-1732584194,c=271733878,d=0;d>>24)|4278255360&(r[d]<<24|r[d]>>>8);r[f>>>5]|=128<>>9<<4)]=f;var p=a._ff,g=a._gg,m=a._hh,y=a._ii;for(d=0;d>>0,l=l+v>>>0,u=u+w>>>0,c=c+_>>>0;}return n.endian([h,l,u,c])})._ff=function(e,t,r,n,i,o,s){var a=e+(t&r|~t&n)+(i>>>0)+s;return (a<>>32-o)+t},a._gg=function(e,t,r,n,i,o,s){var a=e+(t&n|r&~n)+(i>>>0)+s;return (a<>>32-o)+t},a._hh=function(e,t,r,n,i,o,s){var a=e+(t^r^n)+(i>>>0)+s;return (a<>>32-o)+t},a._ii=function(e,t,r,n,i,o,s){var a=e+(r^(t|~n))+(i>>>0)+s;return (a<>>32-o)+t},a._blocksize=16,a._digestsize=16,e.exports=function(e,t){if(null==e)throw new Error("Illegal argument "+e);var r=n.wordsToBytes(a(e,t));return t&&t.asBytes?r:t&&t.asString?s.bytesToString(r):n.bytesToHex(r)};},9591:(e,t,r)=>{var n={};(0, r(4236).assign)(n,r(4555),r(8843),r(1619)),e.exports=n;},4555:(e,t,r)=>{var n=r(405),i=r(4236),o=r(9373),s=r(8898),a=r(2292),f=Object.prototype.toString;function h(e){if(!(this instanceof h))return new h(e);this.options=i.assign({level:-1,method:8,chunkSize:16384,windowBits:15,memLevel:8,strategy:0,to:""},e||{});var t=this.options;t.raw&&t.windowBits>0?t.windowBits=-t.windowBits:t.gzip&&t.windowBits>0&&t.windowBits<16&&(t.windowBits+=16),this.err=0,this.msg="",this.ended=!1,this.chunks=[],this.strm=new a,this.strm.avail_out=0;var r=n.deflateInit2(this.strm,t.level,t.method,t.windowBits,t.memLevel,t.strategy);if(0!==r)throw new Error(s[r]);if(t.header&&n.deflateSetHeader(this.strm,t.header),t.dictionary){var l;if(l="string"==typeof t.dictionary?o.string2buf(t.dictionary):"[object ArrayBuffer]"===f.call(t.dictionary)?new Uint8Array(t.dictionary):t.dictionary,0!==(r=n.deflateSetDictionary(this.strm,l)))throw new Error(s[r]);this._dict_set=!0;}}function l(e,t){var r=new h(t);if(r.push(e,!0),r.err)throw r.msg||s[r.err];return r.result}h.prototype.push=function(e,t){var r,s,a=this.strm,h=this.options.chunkSize;if(this.ended)return !1;s=t===~~t?t:!0===t?4:0,"string"==typeof e?a.input=o.string2buf(e):"[object ArrayBuffer]"===f.call(e)?a.input=new Uint8Array(e):a.input=e,a.next_in=0,a.avail_in=a.input.length;do{if(0===a.avail_out&&(a.output=new i.Buf8(h),a.next_out=0,a.avail_out=h),1!==(r=n.deflate(a,s))&&0!==r)return this.onEnd(r),this.ended=!0,!1;0!==a.avail_out&&(0!==a.avail_in||4!==s&&2!==s)||("string"===this.options.to?this.onData(o.buf2binstring(i.shrinkBuf(a.output,a.next_out))):this.onData(i.shrinkBuf(a.output,a.next_out)));}while((a.avail_in>0||0===a.avail_out)&&1!==r);return 4===s?(r=n.deflateEnd(this.strm),this.onEnd(r),this.ended=!0,0===r):2!==s||(this.onEnd(0),a.avail_out=0,!0)},h.prototype.onData=function(e){this.chunks.push(e);},h.prototype.onEnd=function(e){0===e&&("string"===this.options.to?this.result=this.chunks.join(""):this.result=i.flattenChunks(this.chunks)),this.chunks=[],this.err=e,this.msg=this.strm.msg;},t.Deflate=h,t.deflate=l,t.deflateRaw=function(e,t){return (t=t||{}).raw=!0,l(e,t)},t.gzip=function(e,t){return (t=t||{}).gzip=!0,l(e,t)};},8843:(e,t,r)=>{var n=r(7948),i=r(4236),o=r(9373),s=r(1619),a=r(8898),f=r(2292),h=r(2401),l=Object.prototype.toString;function u(e){if(!(this instanceof u))return new u(e);this.options=i.assign({chunkSize:16384,windowBits:0,to:""},e||{});var t=this.options;t.raw&&t.windowBits>=0&&t.windowBits<16&&(t.windowBits=-t.windowBits,0===t.windowBits&&(t.windowBits=-15)),!(t.windowBits>=0&&t.windowBits<16)||e&&e.windowBits||(t.windowBits+=32),t.windowBits>15&&t.windowBits<48&&0==(15&t.windowBits)&&(t.windowBits|=15),this.err=0,this.msg="",this.ended=!1,this.chunks=[],this.strm=new f,this.strm.avail_out=0;var r=n.inflateInit2(this.strm,t.windowBits);if(r!==s.Z_OK)throw new Error(a[r]);if(this.header=new h,n.inflateGetHeader(this.strm,this.header),t.dictionary&&("string"==typeof t.dictionary?t.dictionary=o.string2buf(t.dictionary):"[object ArrayBuffer]"===l.call(t.dictionary)&&(t.dictionary=new Uint8Array(t.dictionary)),t.raw&&(r=n.inflateSetDictionary(this.strm,t.dictionary))!==s.Z_OK))throw new Error(a[r])}function c(e,t){var r=new u(t);if(r.push(e,!0),r.err)throw r.msg||a[r.err];return r.result}u.prototype.push=function(e,t){var r,a,f,h,u,c=this.strm,d=this.options.chunkSize,p=this.options.dictionary,g=!1;if(this.ended)return !1;a=t===~~t?t:!0===t?s.Z_FINISH:s.Z_NO_FLUSH,"string"==typeof e?c.input=o.binstring2buf(e):"[object ArrayBuffer]"===l.call(e)?c.input=new Uint8Array(e):c.input=e,c.next_in=0,c.avail_in=c.input.length;do{if(0===c.avail_out&&(c.output=new i.Buf8(d),c.next_out=0,c.avail_out=d),(r=n.inflate(c,s.Z_NO_FLUSH))===s.Z_NEED_DICT&&p&&(r=n.inflateSetDictionary(this.strm,p)),r===s.Z_BUF_ERROR&&!0===g&&(r=s.Z_OK,g=!1),r!==s.Z_STREAM_END&&r!==s.Z_OK)return this.onEnd(r),this.ended=!0,!1;c.next_out&&(0!==c.avail_out&&r!==s.Z_STREAM_END&&(0!==c.avail_in||a!==s.Z_FINISH&&a!==s.Z_SYNC_FLUSH)||("string"===this.options.to?(f=o.utf8border(c.output,c.next_out),h=c.next_out-f,u=o.buf2string(c.output,f),c.next_out=h,c.avail_out=d-h,h&&i.arraySet(c.output,c.output,f,h,0),this.onData(u)):this.onData(i.shrinkBuf(c.output,c.next_out)))),0===c.avail_in&&0===c.avail_out&&(g=!0);}while((c.avail_in>0||0===c.avail_out)&&r!==s.Z_STREAM_END);return r===s.Z_STREAM_END&&(a=s.Z_FINISH),a===s.Z_FINISH?(r=n.inflateEnd(this.strm),this.onEnd(r),this.ended=!0,r===s.Z_OK):a!==s.Z_SYNC_FLUSH||(this.onEnd(s.Z_OK),c.avail_out=0,!0)},u.prototype.onData=function(e){this.chunks.push(e);},u.prototype.onEnd=function(e){e===s.Z_OK&&("string"===this.options.to?this.result=this.chunks.join(""):this.result=i.flattenChunks(this.chunks)),this.chunks=[],this.err=e,this.msg=this.strm.msg;},t.Inflate=u,t.inflate=c,t.inflateRaw=function(e,t){return (t=t||{}).raw=!0,c(e,t)},t.ungzip=c;},4236:(e,t)=>{var r="undefined"!=typeof Uint8Array&&"undefined"!=typeof Uint16Array&&"undefined"!=typeof Int32Array;function n(e,t){return Object.prototype.hasOwnProperty.call(e,t)}t.assign=function(e){for(var t=Array.prototype.slice.call(arguments,1);t.length;){var r=t.shift();if(r){if("object"!=typeof r)throw new TypeError(r+"must be non-object");for(var i in r)n(r,i)&&(e[i]=r[i]);}}return e},t.shrinkBuf=function(e,t){return e.length===t?e:e.subarray?e.subarray(0,t):(e.length=t,e)};var i={arraySet:function(e,t,r,n,i){if(t.subarray&&e.subarray)e.set(t.subarray(r,r+n),i);else for(var o=0;o{var n=r(4236),i=!0,o=!0;try{String.fromCharCode.apply(null,[0]);}catch(e){i=!1;}try{String.fromCharCode.apply(null,new Uint8Array(1));}catch(e){o=!1;}for(var s=new n.Buf8(256),a=0;a<256;a++)s[a]=a>=252?6:a>=248?5:a>=240?4:a>=224?3:a>=192?2:1;function f(e,t){if(t<65534&&(e.subarray&&o||!e.subarray&&i))return String.fromCharCode.apply(null,n.shrinkBuf(e,t));for(var r="",s=0;s>>6,t[s++]=128|63&r):r<65536?(t[s++]=224|r>>>12,t[s++]=128|r>>>6&63,t[s++]=128|63&r):(t[s++]=240|r>>>18,t[s++]=128|r>>>12&63,t[s++]=128|r>>>6&63,t[s++]=128|63&r);return t},t.buf2binstring=function(e){return f(e,e.length)},t.binstring2buf=function(e){for(var t=new n.Buf8(e.length),r=0,i=t.length;r4)h[n++]=65533,r+=o-1;else {for(i&=2===o?31:3===o?15:7;o>1&&r1?h[n++]=65533:i<65536?h[n++]=i:(i-=65536,h[n++]=55296|i>>10&1023,h[n++]=56320|1023&i);}return f(h,n)},t.utf8border=function(e,t){var r;for((t=t||e.length)>e.length&&(t=e.length),r=t-1;r>=0&&128==(192&e[r]);)r--;return r<0||0===r?t:r+s[e[r]]>t?r:t};},6069:e=>{e.exports=function(e,t,r,n){for(var i=65535&e|0,o=e>>>16&65535|0,s=0;0!==r;){r-=s=r>2e3?2e3:r;do{o=o+(i=i+t[n++]|0)|0;}while(--s);i%=65521,o%=65521;}return i|o<<16|0};},1619:e=>{e.exports={Z_NO_FLUSH:0,Z_PARTIAL_FLUSH:1,Z_SYNC_FLUSH:2,Z_FULL_FLUSH:3,Z_FINISH:4,Z_BLOCK:5,Z_TREES:6,Z_OK:0,Z_STREAM_END:1,Z_NEED_DICT:2,Z_ERRNO:-1,Z_STREAM_ERROR:-2,Z_DATA_ERROR:-3,Z_BUF_ERROR:-5,Z_NO_COMPRESSION:0,Z_BEST_SPEED:1,Z_BEST_COMPRESSION:9,Z_DEFAULT_COMPRESSION:-1,Z_FILTERED:1,Z_HUFFMAN_ONLY:2,Z_RLE:3,Z_FIXED:4,Z_DEFAULT_STRATEGY:0,Z_BINARY:0,Z_TEXT:1,Z_UNKNOWN:2,Z_DEFLATED:8};},2869:e=>{var t=function(){for(var e,t=[],r=0;r<256;r++){e=r;for(var n=0;n<8;n++)e=1&e?3988292384^e>>>1:e>>>1;t[r]=e;}return t}();e.exports=function(e,r,n,i){var o=t,s=i+n;e^=-1;for(var a=i;a>>8^o[255&(e^r[a])];return -1^e};},405:(e,t,r)=>{var n,i=r(4236),o=r(342),s=r(6069),a=r(2869),f=r(8898),h=-2,l=258,u=262,c=103,d=113,p=666;function g(e,t){return e.msg=f[t],t}function m(e){return (e<<1)-(e>4?9:0)}function y(e){for(var t=e.length;--t>=0;)e[t]=0;}function b(e){var t=e.state,r=t.pending;r>e.avail_out&&(r=e.avail_out),0!==r&&(i.arraySet(e.output,t.pending_buf,t.pending_out,r,e.next_out),e.next_out+=r,t.pending_out+=r,e.total_out+=r,e.avail_out-=r,t.pending-=r,0===t.pending&&(t.pending_out=0));}function v(e,t){o._tr_flush_block(e,e.block_start>=0?e.block_start:-1,e.strstart-e.block_start,t),e.block_start=e.strstart,b(e.strm);}function w(e,t){e.pending_buf[e.pending++]=t;}function _(e,t){e.pending_buf[e.pending++]=t>>>8&255,e.pending_buf[e.pending++]=255&t;}function B(e,t,r,n){var o=e.avail_in;return o>n&&(o=n),0===o?0:(e.avail_in-=o,i.arraySet(t,e.input,e.next_in,o,r),1===e.state.wrap?e.adler=s(e.adler,t,o,r):2===e.state.wrap&&(e.adler=a(e.adler,t,o,r)),e.next_in+=o,e.total_in+=o,o)}function E(e,t){var r,n,i=e.max_chain_length,o=e.strstart,s=e.prev_length,a=e.nice_match,f=e.strstart>e.w_size-u?e.strstart-(e.w_size-u):0,h=e.window,c=e.w_mask,d=e.prev,p=e.strstart+l,g=h[o+s-1],m=h[o+s];e.prev_length>=e.good_match&&(i>>=2),a>e.lookahead&&(a=e.lookahead);do{if(h[(r=t)+s]===m&&h[r+s-1]===g&&h[r]===h[o]&&h[++r]===h[o+1]){o+=2,r++;do{}while(h[++o]===h[++r]&&h[++o]===h[++r]&&h[++o]===h[++r]&&h[++o]===h[++r]&&h[++o]===h[++r]&&h[++o]===h[++r]&&h[++o]===h[++r]&&h[++o]===h[++r]&&os){if(e.match_start=t,s=n,n>=a)break;g=h[o+s-1],m=h[o+s];}}}while((t=d[t&c])>f&&0!=--i);return s<=e.lookahead?s:e.lookahead}function S(e){var t,r,n,o,s,a=e.w_size;do{if(o=e.window_size-e.lookahead-e.strstart,e.strstart>=a+(a-u)){i.arraySet(e.window,e.window,a,a,0),e.match_start-=a,e.strstart-=a,e.block_start-=a,t=r=e.hash_size;do{n=e.head[--t],e.head[t]=n>=a?n-a:0;}while(--r);t=r=a;do{n=e.prev[--t],e.prev[t]=n>=a?n-a:0;}while(--r);o+=a;}if(0===e.strm.avail_in)break;if(r=B(e.strm,e.window,e.strstart+e.lookahead,o),e.lookahead+=r,e.lookahead+e.insert>=3)for(s=e.strstart-e.insert,e.ins_h=e.window[s],e.ins_h=(e.ins_h<=3&&(e.ins_h=(e.ins_h<=3)if(n=o._tr_tally(e,e.strstart-e.match_start,e.match_length-3),e.lookahead-=e.match_length,e.match_length<=e.max_lazy_match&&e.lookahead>=3){e.match_length--;do{e.strstart++,e.ins_h=(e.ins_h<=3&&(e.ins_h=(e.ins_h<4096)&&(e.match_length=2)),e.prev_length>=3&&e.match_length<=e.prev_length){i=e.strstart+e.lookahead-3,n=o._tr_tally(e,e.strstart-1-e.prev_match,e.prev_length-3),e.lookahead-=e.prev_length-1,e.prev_length-=2;do{++e.strstart<=i&&(e.ins_h=(e.ins_h<15&&(a=2,n-=16),o<1||o>9||8!==r||n<8||n>15||t<0||t>9||s<0||s>4)return g(e,h);8===n&&(n=9);var f=new k;return e.state=f,f.strm=e,f.wrap=a,f.gzhead=null,f.w_bits=n,f.w_size=1<e.pending_buf_size-5&&(r=e.pending_buf_size-5);;){if(e.lookahead<=1){if(S(e),0===e.lookahead&&0===t)return 1;if(0===e.lookahead)break}e.strstart+=e.lookahead,e.lookahead=0;var n=e.block_start+r;if((0===e.strstart||e.strstart>=n)&&(e.lookahead=e.strstart-n,e.strstart=n,v(e,!1),0===e.strm.avail_out))return 1;if(e.strstart-e.block_start>=e.w_size-u&&(v(e,!1),0===e.strm.avail_out))return 1}return e.insert=0,4===t?(v(e,!0),0===e.strm.avail_out?3:4):(e.strstart>e.block_start&&(v(e,!1),e.strm.avail_out),1)})),new R(4,4,8,4,A),new R(4,5,16,8,A),new R(4,6,32,32,A),new R(4,4,16,16,C),new R(8,16,32,32,C),new R(8,16,128,128,C),new R(8,32,128,256,C),new R(32,128,258,1024,C),new R(32,258,258,4096,C)],t.deflateInit=function(e,t){return M(e,t,8,15,8,0)},t.deflateInit2=M,t.deflateReset=I,t.deflateResetKeep=x,t.deflateSetHeader=function(e,t){return e&&e.state?2!==e.state.wrap?h:(e.state.gzhead=t,0):h},t.deflate=function(e,t){var r,i,s,f;if(!e||!e.state||t>5||t<0)return e?g(e,h):h;if(i=e.state,!e.output||!e.input&&0!==e.avail_in||i.status===p&&4!==t)return g(e,0===e.avail_out?-5:h);if(i.strm=e,r=i.last_flush,i.last_flush=t,42===i.status)if(2===i.wrap)e.adler=0,w(i,31),w(i,139),w(i,8),i.gzhead?(w(i,(i.gzhead.text?1:0)+(i.gzhead.hcrc?2:0)+(i.gzhead.extra?4:0)+(i.gzhead.name?8:0)+(i.gzhead.comment?16:0)),w(i,255&i.gzhead.time),w(i,i.gzhead.time>>8&255),w(i,i.gzhead.time>>16&255),w(i,i.gzhead.time>>24&255),w(i,9===i.level?2:i.strategy>=2||i.level<2?4:0),w(i,255&i.gzhead.os),i.gzhead.extra&&i.gzhead.extra.length&&(w(i,255&i.gzhead.extra.length),w(i,i.gzhead.extra.length>>8&255)),i.gzhead.hcrc&&(e.adler=a(e.adler,i.pending_buf,i.pending,0)),i.gzindex=0,i.status=69):(w(i,0),w(i,0),w(i,0),w(i,0),w(i,0),w(i,9===i.level?2:i.strategy>=2||i.level<2?4:0),w(i,3),i.status=d);else {var u=8+(i.w_bits-8<<4)<<8;u|=(i.strategy>=2||i.level<2?0:i.level<6?1:6===i.level?2:3)<<6,0!==i.strstart&&(u|=32),u+=31-u%31,i.status=d,_(i,u),0!==i.strstart&&(_(i,e.adler>>>16),_(i,65535&e.adler)),e.adler=1;}if(69===i.status)if(i.gzhead.extra){for(s=i.pending;i.gzindex<(65535&i.gzhead.extra.length)&&(i.pending!==i.pending_buf_size||(i.gzhead.hcrc&&i.pending>s&&(e.adler=a(e.adler,i.pending_buf,i.pending-s,s)),b(e),s=i.pending,i.pending!==i.pending_buf_size));)w(i,255&i.gzhead.extra[i.gzindex]),i.gzindex++;i.gzhead.hcrc&&i.pending>s&&(e.adler=a(e.adler,i.pending_buf,i.pending-s,s)),i.gzindex===i.gzhead.extra.length&&(i.gzindex=0,i.status=73);}else i.status=73;if(73===i.status)if(i.gzhead.name){s=i.pending;do{if(i.pending===i.pending_buf_size&&(i.gzhead.hcrc&&i.pending>s&&(e.adler=a(e.adler,i.pending_buf,i.pending-s,s)),b(e),s=i.pending,i.pending===i.pending_buf_size)){f=1;break}f=i.gzindexs&&(e.adler=a(e.adler,i.pending_buf,i.pending-s,s)),0===f&&(i.gzindex=0,i.status=91);}else i.status=91;if(91===i.status)if(i.gzhead.comment){s=i.pending;do{if(i.pending===i.pending_buf_size&&(i.gzhead.hcrc&&i.pending>s&&(e.adler=a(e.adler,i.pending_buf,i.pending-s,s)),b(e),s=i.pending,i.pending===i.pending_buf_size)){f=1;break}f=i.gzindexs&&(e.adler=a(e.adler,i.pending_buf,i.pending-s,s)),0===f&&(i.status=c);}else i.status=c;if(i.status===c&&(i.gzhead.hcrc?(i.pending+2>i.pending_buf_size&&b(e),i.pending+2<=i.pending_buf_size&&(w(i,255&e.adler),w(i,e.adler>>8&255),e.adler=0,i.status=d)):i.status=d),0!==i.pending){if(b(e),0===e.avail_out)return i.last_flush=-1,0}else if(0===e.avail_in&&m(t)<=m(r)&&4!==t)return g(e,-5);if(i.status===p&&0!==e.avail_in)return g(e,-5);if(0!==e.avail_in||0!==i.lookahead||0!==t&&i.status!==p){var B=2===i.strategy?function(e,t){for(var r;;){if(0===e.lookahead&&(S(e),0===e.lookahead)){if(0===t)return 1;break}if(e.match_length=0,r=o._tr_tally(e,0,e.window[e.strstart]),e.lookahead--,e.strstart++,r&&(v(e,!1),0===e.strm.avail_out))return 1}return e.insert=0,4===t?(v(e,!0),0===e.strm.avail_out?3:4):e.last_lit&&(v(e,!1),0===e.strm.avail_out)?1:2}(i,t):3===i.strategy?function(e,t){for(var r,n,i,s,a=e.window;;){if(e.lookahead<=l){if(S(e),e.lookahead<=l&&0===t)return 1;if(0===e.lookahead)break}if(e.match_length=0,e.lookahead>=3&&e.strstart>0&&(n=a[i=e.strstart-1])===a[++i]&&n===a[++i]&&n===a[++i]){s=e.strstart+l;do{}while(n===a[++i]&&n===a[++i]&&n===a[++i]&&n===a[++i]&&n===a[++i]&&n===a[++i]&&n===a[++i]&&n===a[++i]&&ie.lookahead&&(e.match_length=e.lookahead);}if(e.match_length>=3?(r=o._tr_tally(e,1,e.match_length-3),e.lookahead-=e.match_length,e.strstart+=e.match_length,e.match_length=0):(r=o._tr_tally(e,0,e.window[e.strstart]),e.lookahead--,e.strstart++),r&&(v(e,!1),0===e.strm.avail_out))return 1}return e.insert=0,4===t?(v(e,!0),0===e.strm.avail_out?3:4):e.last_lit&&(v(e,!1),0===e.strm.avail_out)?1:2}(i,t):n[i.level].func(i,t);if(3!==B&&4!==B||(i.status=p),1===B||3===B)return 0===e.avail_out&&(i.last_flush=-1),0;if(2===B&&(1===t?o._tr_align(i):5!==t&&(o._tr_stored_block(i,0,0,!1),3===t&&(y(i.head),0===i.lookahead&&(i.strstart=0,i.block_start=0,i.insert=0))),b(e),0===e.avail_out))return i.last_flush=-1,0}return 4!==t?0:i.wrap<=0?1:(2===i.wrap?(w(i,255&e.adler),w(i,e.adler>>8&255),w(i,e.adler>>16&255),w(i,e.adler>>24&255),w(i,255&e.total_in),w(i,e.total_in>>8&255),w(i,e.total_in>>16&255),w(i,e.total_in>>24&255)):(_(i,e.adler>>>16),_(i,65535&e.adler)),b(e),i.wrap>0&&(i.wrap=-i.wrap),0!==i.pending?0:1)},t.deflateEnd=function(e){var t;return e&&e.state?42!==(t=e.state.status)&&69!==t&&73!==t&&91!==t&&t!==c&&t!==d&&t!==p?g(e,h):(e.state=null,t===d?g(e,-3):0):h},t.deflateSetDictionary=function(e,t){var r,n,o,a,f,l,u,c,d=t.length;if(!e||!e.state)return h;if(2===(a=(r=e.state).wrap)||1===a&&42!==r.status||r.lookahead)return h;for(1===a&&(e.adler=s(e.adler,t,d,0)),r.wrap=0,d>=r.w_size&&(0===a&&(y(r.head),r.strstart=0,r.block_start=0,r.insert=0),c=new i.Buf8(r.w_size),i.arraySet(c,t,d-r.w_size,r.w_size,0),t=c,d=r.w_size),f=e.avail_in,l=e.next_in,u=e.input,e.avail_in=d,e.next_in=0,e.input=t,S(r);r.lookahead>=3;){n=r.strstart,o=r.lookahead-2;do{r.ins_h=(r.ins_h<{e.exports=function(){this.text=0,this.time=0,this.xflags=0,this.os=0,this.extra=null,this.extra_len=0,this.name="",this.comment="",this.hcrc=0,this.done=!1;};},4264:e=>{e.exports=function(e,t){var r,n,i,o,s,a,f,h,l,u,c,d,p,g,m,y,b,v,w,_,B,E,S,A,C;r=e.state,n=e.next_in,A=e.input,i=n+(e.avail_in-5),o=e.next_out,C=e.output,s=o-(t-e.avail_out),a=o+(e.avail_out-257),f=r.dmax,h=r.wsize,l=r.whave,u=r.wnext,c=r.window,d=r.hold,p=r.bits,g=r.lencode,m=r.distcode,y=(1<>>=w=v>>>24,p-=w,0==(w=v>>>16&255))C[o++]=65535&v;else {if(!(16&w)){if(0==(64&w)){v=g[(65535&v)+(d&(1<>>=w,p-=w),p<15&&(d+=A[n++]<>>=w=v>>>24,p-=w,!(16&(w=v>>>16&255))){if(0==(64&w)){v=m[(65535&v)+(d&(1<f){e.msg="invalid distance too far back",r.mode=30;break e}if(d>>>=w,p-=w,B>(w=o-s)){if((w=B-w)>l&&r.sane){e.msg="invalid distance too far back",r.mode=30;break e}if(E=0,S=c,0===u){if(E+=h-w,w<_){_-=w;do{C[o++]=c[E++];}while(--w);E=o-B,S=C;}}else if(u2;)C[o++]=S[E++],C[o++]=S[E++],C[o++]=S[E++],_-=3;_&&(C[o++]=S[E++],_>1&&(C[o++]=S[E++]));}else {E=o-B;do{C[o++]=C[E++],C[o++]=C[E++],C[o++]=C[E++],_-=3;}while(_>2);_&&(C[o++]=C[E++],_>1&&(C[o++]=C[E++]));}break}}break}}while(n>3,d&=(1<<(p-=_<<3))-1,e.next_in=n,e.next_out=o,e.avail_in=n{var n=r(4236),i=r(6069),o=r(2869),s=r(4264),a=r(9241),f=-2,h=12,l=30;function u(e){return (e>>>24&255)+(e>>>8&65280)+((65280&e)<<8)+((255&e)<<24)}function c(){this.mode=0,this.last=!1,this.wrap=0,this.havedict=!1,this.flags=0,this.dmax=0,this.check=0,this.total=0,this.head=null,this.wbits=0,this.wsize=0,this.whave=0,this.wnext=0,this.window=null,this.hold=0,this.bits=0,this.length=0,this.offset=0,this.extra=0,this.lencode=null,this.distcode=null,this.lenbits=0,this.distbits=0,this.ncode=0,this.nlen=0,this.ndist=0,this.have=0,this.next=null,this.lens=new n.Buf16(320),this.work=new n.Buf16(288),this.lendyn=null,this.distdyn=null,this.sane=0,this.back=0,this.was=0;}function d(e){var t;return e&&e.state?(t=e.state,e.total_in=e.total_out=t.total=0,e.msg="",t.wrap&&(e.adler=1&t.wrap),t.mode=1,t.last=0,t.havedict=0,t.dmax=32768,t.head=null,t.hold=0,t.bits=0,t.lencode=t.lendyn=new n.Buf32(852),t.distcode=t.distdyn=new n.Buf32(592),t.sane=1,t.back=-1,0):f}function p(e){var t;return e&&e.state?((t=e.state).wsize=0,t.whave=0,t.wnext=0,d(e)):f}function g(e,t){var r,n;return e&&e.state?(n=e.state,t<0?(r=0,t=-t):(r=1+(t>>4),t<48&&(t&=15)),t&&(t<8||t>15)?f:(null!==n.window&&n.wbits!==t&&(n.window=null),n.wrap=r,n.wbits=t,p(e))):f}function m(e,t){var r,n;return e?(n=new c,e.state=n,n.window=null,0!==(r=g(e,t))&&(e.state=null),r):f}var y,b,v=!0;function w(e){if(v){var t;for(y=new n.Buf32(512),b=new n.Buf32(32),t=0;t<144;)e.lens[t++]=8;for(;t<256;)e.lens[t++]=9;for(;t<280;)e.lens[t++]=7;for(;t<288;)e.lens[t++]=8;for(a(1,e.lens,0,288,y,0,e.work,{bits:9}),t=0;t<32;)e.lens[t++]=5;a(2,e.lens,0,32,b,0,e.work,{bits:5}),v=!1;}e.lencode=y,e.lenbits=9,e.distcode=b,e.distbits=5;}function _(e,t,r,i){var o,s=e.state;return null===s.window&&(s.wsize=1<=s.wsize?(n.arraySet(s.window,t,r-s.wsize,s.wsize,0),s.wnext=0,s.whave=s.wsize):((o=s.wsize-s.wnext)>i&&(o=i),n.arraySet(s.window,t,r-i,o,s.wnext),(i-=o)?(n.arraySet(s.window,t,r-i,i,0),s.wnext=i,s.whave=s.wsize):(s.wnext+=o,s.wnext===s.wsize&&(s.wnext=0),s.whave>>8&255,r.check=o(r.check,L,2,0),b=0,v=0,r.mode=2;break}if(r.flags=0,r.head&&(r.head.done=!1),!(1&r.wrap)||(((255&b)<<8)+(b>>8))%31){e.msg="incorrect header check",r.mode=l;break}if(8!=(15&b)){e.msg="unknown compression method",r.mode=l;break}if(v-=4,O=8+(15&(b>>>=4)),0===r.wbits)r.wbits=O;else if(O>r.wbits){e.msg="invalid window size",r.mode=l;break}r.dmax=1<>8&1),512&r.flags&&(L[0]=255&b,L[1]=b>>>8&255,r.check=o(r.check,L,2,0)),b=0,v=0,r.mode=3;case 3:for(;v<32;){if(0===m)break e;m--,b+=c[p++]<>>8&255,L[2]=b>>>16&255,L[3]=b>>>24&255,r.check=o(r.check,L,4,0)),b=0,v=0,r.mode=4;case 4:for(;v<16;){if(0===m)break e;m--,b+=c[p++]<>8),512&r.flags&&(L[0]=255&b,L[1]=b>>>8&255,r.check=o(r.check,L,2,0)),b=0,v=0,r.mode=5;case 5:if(1024&r.flags){for(;v<16;){if(0===m)break e;m--,b+=c[p++]<>>8&255,r.check=o(r.check,L,2,0)),b=0,v=0;}else r.head&&(r.head.extra=null);r.mode=6;case 6:if(1024&r.flags&&((S=r.length)>m&&(S=m),S&&(r.head&&(O=r.head.extra_len-r.length,r.head.extra||(r.head.extra=new Array(r.head.extra_len)),n.arraySet(r.head.extra,c,p,S,O)),512&r.flags&&(r.check=o(r.check,c,S,p)),m-=S,p+=S,r.length-=S),r.length))break e;r.length=0,r.mode=7;case 7:if(2048&r.flags){if(0===m)break e;S=0;do{O=c[p+S++],r.head&&O&&r.length<65536&&(r.head.name+=String.fromCharCode(O));}while(O&&S>9&1,r.head.done=!0),e.adler=r.check=0,r.mode=h;break;case 10:for(;v<32;){if(0===m)break e;m--,b+=c[p++]<>>=7&v,v-=7&v,r.mode=27;break}for(;v<3;){if(0===m)break e;m--,b+=c[p++]<>>=1)){case 0:r.mode=14;break;case 1:if(w(r),r.mode=20,6===t){b>>>=2,v-=2;break e}break;case 2:r.mode=17;break;case 3:e.msg="invalid block type",r.mode=l;}b>>>=2,v-=2;break;case 14:for(b>>>=7&v,v-=7&v;v<32;){if(0===m)break e;m--,b+=c[p++]<>>16^65535)){e.msg="invalid stored block lengths",r.mode=l;break}if(r.length=65535&b,b=0,v=0,r.mode=15,6===t)break e;case 15:r.mode=16;case 16:if(S=r.length){if(S>m&&(S=m),S>y&&(S=y),0===S)break e;n.arraySet(d,c,p,S,g),m-=S,p+=S,y-=S,g+=S,r.length-=S;break}r.mode=h;break;case 17:for(;v<14;){if(0===m)break e;m--,b+=c[p++]<>>=5,v-=5,r.ndist=1+(31&b),b>>>=5,v-=5,r.ncode=4+(15&b),b>>>=4,v-=4,r.nlen>286||r.ndist>30){e.msg="too many length or distance symbols",r.mode=l;break}r.have=0,r.mode=18;case 18:for(;r.have>>=3,v-=3;}for(;r.have<19;)r.lens[z[r.have++]]=0;if(r.lencode=r.lendyn,r.lenbits=7,U={bits:r.lenbits},T=a(0,r.lens,0,19,r.lencode,0,r.work,U),r.lenbits=U.bits,T){e.msg="invalid code lengths set",r.mode=l;break}r.have=0,r.mode=19;case 19:for(;r.have>>16&255,x=65535&N,!((R=N>>>24)<=v);){if(0===m)break e;m--,b+=c[p++]<>>=R,v-=R,r.lens[r.have++]=x;else {if(16===x){for(P=R+2;v>>=R,v-=R,0===r.have){e.msg="invalid bit length repeat",r.mode=l;break}O=r.lens[r.have-1],S=3+(3&b),b>>>=2,v-=2;}else if(17===x){for(P=R+3;v>>=R)),b>>>=3,v-=3;}else {for(P=R+7;v>>=R)),b>>>=7,v-=7;}if(r.have+S>r.nlen+r.ndist){e.msg="invalid bit length repeat",r.mode=l;break}for(;S--;)r.lens[r.have++]=O;}}if(r.mode===l)break;if(0===r.lens[256]){e.msg="invalid code -- missing end-of-block",r.mode=l;break}if(r.lenbits=9,U={bits:r.lenbits},T=a(1,r.lens,0,r.nlen,r.lencode,0,r.work,U),r.lenbits=U.bits,T){e.msg="invalid literal/lengths set",r.mode=l;break}if(r.distbits=6,r.distcode=r.distdyn,U={bits:r.distbits},T=a(2,r.lens,r.nlen,r.ndist,r.distcode,0,r.work,U),r.distbits=U.bits,T){e.msg="invalid distances set",r.mode=l;break}if(r.mode=20,6===t)break e;case 20:r.mode=21;case 21:if(m>=6&&y>=258){e.next_out=g,e.avail_out=y,e.next_in=p,e.avail_in=m,r.hold=b,r.bits=v,s(e,E),g=e.next_out,d=e.output,y=e.avail_out,p=e.next_in,c=e.input,m=e.avail_in,b=r.hold,v=r.bits,r.mode===h&&(r.back=-1);break}for(r.back=0;k=(N=r.lencode[b&(1<>>16&255,x=65535&N,!((R=N>>>24)<=v);){if(0===m)break e;m--,b+=c[p++]<>I)])>>>16&255,x=65535&N,!(I+(R=N>>>24)<=v);){if(0===m)break e;m--,b+=c[p++]<>>=I,v-=I,r.back+=I;}if(b>>>=R,v-=R,r.back+=R,r.length=x,0===k){r.mode=26;break}if(32&k){r.back=-1,r.mode=h;break}if(64&k){e.msg="invalid literal/length code",r.mode=l;break}r.extra=15&k,r.mode=22;case 22:if(r.extra){for(P=r.extra;v>>=r.extra,v-=r.extra,r.back+=r.extra;}r.was=r.length,r.mode=23;case 23:for(;k=(N=r.distcode[b&(1<>>16&255,x=65535&N,!((R=N>>>24)<=v);){if(0===m)break e;m--,b+=c[p++]<>I)])>>>16&255,x=65535&N,!(I+(R=N>>>24)<=v);){if(0===m)break e;m--,b+=c[p++]<>>=I,v-=I,r.back+=I;}if(b>>>=R,v-=R,r.back+=R,64&k){e.msg="invalid distance code",r.mode=l;break}r.offset=x,r.extra=15&k,r.mode=24;case 24:if(r.extra){for(P=r.extra;v>>=r.extra,v-=r.extra,r.back+=r.extra;}if(r.offset>r.dmax){e.msg="invalid distance too far back",r.mode=l;break}r.mode=25;case 25:if(0===y)break e;if(S=E-y,r.offset>S){if((S=r.offset-S)>r.whave&&r.sane){e.msg="invalid distance too far back",r.mode=l;break}S>r.wnext?(S-=r.wnext,A=r.wsize-S):A=r.wnext-S,S>r.length&&(S=r.length),C=r.window;}else C=d,A=g-r.offset,S=r.length;S>y&&(S=y),y-=S,r.length-=S;do{d[g++]=C[A++];}while(--S);0===r.length&&(r.mode=21);break;case 26:if(0===y)break e;d[g++]=r.length,y--,r.mode=21;break;case 27:if(r.wrap){for(;v<32;){if(0===m)break e;m--,b|=c[p++]<{var n=r(4236),i=[3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258,0,0],o=[16,16,16,16,16,16,16,16,17,17,17,17,18,18,18,18,19,19,19,19,20,20,20,20,21,21,21,21,16,72,78],s=[1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,0,0],a=[16,16,16,16,17,17,18,18,19,19,20,20,21,21,22,22,23,23,24,24,25,25,26,26,27,27,28,28,29,29,64,64];e.exports=function(e,t,r,f,h,l,u,c){var d,p,g,m,y,b,v,w,_,B=c.bits,E=0,S=0,A=0,C=0,R=0,k=0,x=0,I=0,M=0,F=0,O=null,T=0,U=new n.Buf16(16),P=new n.Buf16(16),N=null,L=0;for(E=0;E<=15;E++)U[E]=0;for(S=0;S=1&&0===U[C];C--);if(R>C&&(R=C),0===C)return h[l++]=20971520,h[l++]=20971520,c.bits=1,0;for(A=1;A0&&(0===e||1!==C))return -1;for(P[1]=0,E=1;E<15;E++)P[E+1]=P[E]+U[E];for(S=0;S852||2===e&&M>592)return 1;for(;;){v=E-x,u[S]b?(w=N[L+u[S]],_=O[T+u[S]]):(w=96,_=0),d=1<>x)+(p-=d)]=v<<24|w<<16|_|0;}while(0!==p);for(d=1<>=1;if(0!==d?(F&=d-1,F+=d):F=0,S++,0==--U[E]){if(E===C)break;E=t[r+u[S]];}if(E>R&&(F&m)!==g){for(0===x&&(x=R),y+=A,I=1<<(k=E-x);k+x852||2===e&&M>592)return 1;h[g=F&m]=R<<24|k<<16|y-l|0;}}return 0!==F&&(h[y+F]=E-x<<24|64<<16|0),c.bits=R,0};},8898:e=>{e.exports={2:"need dictionary",1:"stream end",0:"","-1":"file error","-2":"stream error","-3":"data error","-4":"insufficient memory","-5":"buffer error","-6":"incompatible version"};},342:(e,t,r)=>{var n=r(4236);function i(e){for(var t=e.length;--t>=0;)e[t]=0;}var o=[0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0],s=[0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13],a=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7],f=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15],h=new Array(576);i(h);var l=new Array(60);i(l);var u=new Array(512);i(u);var c=new Array(256);i(c);var d=new Array(29);i(d);var p,g,m,y=new Array(30);function b(e,t,r,n,i){this.static_tree=e,this.extra_bits=t,this.extra_base=r,this.elems=n,this.max_length=i,this.has_stree=e&&e.length;}function v(e,t){this.dyn_tree=e,this.max_code=0,this.stat_desc=t;}function w(e){return e<256?u[e]:u[256+(e>>>7)]}function _(e,t){e.pending_buf[e.pending++]=255&t,e.pending_buf[e.pending++]=t>>>8&255;}function B(e,t,r){e.bi_valid>16-r?(e.bi_buf|=t<>16-e.bi_valid,e.bi_valid+=r-16):(e.bi_buf|=t<>>=1,r<<=1;}while(--t>0);return r>>>1}function A(e,t,r){var n,i,o=new Array(16),s=0;for(n=1;n<=15;n++)o[n]=s=s+r[n-1]<<1;for(i=0;i<=t;i++){var a=e[2*i+1];0!==a&&(e[2*i]=S(o[a]++,a));}}function C(e){var t;for(t=0;t<286;t++)e.dyn_ltree[2*t]=0;for(t=0;t<30;t++)e.dyn_dtree[2*t]=0;for(t=0;t<19;t++)e.bl_tree[2*t]=0;e.dyn_ltree[512]=1,e.opt_len=e.static_len=0,e.last_lit=e.matches=0;}function R(e){e.bi_valid>8?_(e,e.bi_buf):e.bi_valid>0&&(e.pending_buf[e.pending++]=e.bi_buf),e.bi_buf=0,e.bi_valid=0;}function k(e,t,r,n){var i=2*t,o=2*r;return e[i]>1;r>=1;r--)x(e,o,r);i=f;do{r=e.heap[1],e.heap[1]=e.heap[e.heap_len--],x(e,o,1),n=e.heap[1],e.heap[--e.heap_max]=r,e.heap[--e.heap_max]=n,o[2*i]=o[2*r]+o[2*n],e.depth[i]=(e.depth[r]>=e.depth[n]?e.depth[r]:e.depth[n])+1,o[2*r+1]=o[2*n+1]=i,e.heap[1]=i++,x(e,o,1);}while(e.heap_len>=2);e.heap[--e.heap_max]=e.heap[1],function(e,t){var r,n,i,o,s,a,f=t.dyn_tree,h=t.max_code,l=t.stat_desc.static_tree,u=t.stat_desc.has_stree,c=t.stat_desc.extra_bits,d=t.stat_desc.extra_base,p=t.stat_desc.max_length,g=0;for(o=0;o<=15;o++)e.bl_count[o]=0;for(f[2*e.heap[e.heap_max]+1]=0,r=e.heap_max+1;r<573;r++)(o=f[2*f[2*(n=e.heap[r])+1]+1]+1)>p&&(o=p,g++),f[2*n+1]=o,n>h||(e.bl_count[o]++,s=0,n>=d&&(s=c[n-d]),a=f[2*n],e.opt_len+=a*(o+s),u&&(e.static_len+=a*(l[2*n+1]+s)));if(0!==g){do{for(o=p-1;0===e.bl_count[o];)o--;e.bl_count[o]--,e.bl_count[o+1]+=2,e.bl_count[p]--,g-=2;}while(g>0);for(o=p;0!==o;o--)for(n=e.bl_count[o];0!==n;)(i=e.heap[--r])>h||(f[2*i+1]!==o&&(e.opt_len+=(o-f[2*i+1])*f[2*i],f[2*i+1]=o),n--);}}(e,t),A(o,h,e.bl_count);}function F(e,t,r){var n,i,o=-1,s=t[1],a=0,f=7,h=4;for(0===s&&(f=138,h=3),t[2*(r+1)+1]=65535,n=0;n<=r;n++)i=s,s=t[2*(n+1)+1],++a>=7;n<30;n++)for(y[n]=i<<7,e=0;e<1<0?(2===e.strm.data_type&&(e.strm.data_type=function(e){var t,r=4093624447;for(t=0;t<=31;t++,r>>>=1)if(1&r&&0!==e.dyn_ltree[2*t])return 0;if(0!==e.dyn_ltree[18]||0!==e.dyn_ltree[20]||0!==e.dyn_ltree[26])return 1;for(t=32;t<256;t++)if(0!==e.dyn_ltree[2*t])return 1;return 0}(e)),M(e,e.l_desc),M(e,e.d_desc),s=function(e){var t;for(F(e,e.dyn_ltree,e.l_desc.max_code),F(e,e.dyn_dtree,e.d_desc.max_code),M(e,e.bl_desc),t=18;t>=3&&0===e.bl_tree[2*f[t]+1];t--);return e.opt_len+=3*(t+1)+5+5+4,t}(e),i=e.opt_len+3+7>>>3,(o=e.static_len+3+7>>>3)<=i&&(i=o)):i=o=r+5,r+4<=i&&-1!==t?U(e,t,r,n):4===e.strategy||o===i?(B(e,2+(n?1:0),3),I(e,h,l)):(B(e,4+(n?1:0),3),function(e,t,r,n){var i;for(B(e,t-257,5),B(e,r-1,5),B(e,n-4,4),i=0;i>>8&255,e.pending_buf[e.d_buf+2*e.last_lit+1]=255&t,e.pending_buf[e.l_buf+e.last_lit]=255&r,e.last_lit++,0===t?e.dyn_ltree[2*r]++:(e.matches++,t--,e.dyn_ltree[2*(c[r]+256+1)]++,e.dyn_dtree[2*w(t)]++),e.last_lit===e.lit_bufsize-1},t._tr_align=function(e){B(e,2,3),E(e,256,h),function(e){16===e.bi_valid?(_(e,e.bi_buf),e.bi_buf=0,e.bi_valid=0):e.bi_valid>=8&&(e.pending_buf[e.pending++]=255&e.bi_buf,e.bi_buf>>=8,e.bi_valid-=8);}(e);};},2292:e=>{e.exports=function(){this.input=null,this.next_in=0,this.avail_in=0,this.total_in=0,this.output=null,this.next_out=0,this.avail_out=0,this.total_out=0,this.msg="",this.state=null,this.data_type=2,this.adler=0;};},2587:e=>{function t(e,t){return Object.prototype.hasOwnProperty.call(e,t)}e.exports=function(e,r,n,i){r=r||"&",n=n||"=";var o={};if("string"!=typeof e||0===e.length)return o;var s=/\+/g;e=e.split(r);var a=1e3;i&&"number"==typeof i.maxKeys&&(a=i.maxKeys);var f=e.length;a>0&&f>a&&(f=a);for(var h=0;h=0?(l=p.substr(0,g),u=p.substr(g+1)):(l=p,u=""),c=decodeURIComponent(l),d=decodeURIComponent(u),t(o,c)?Array.isArray(o[c])?o[c].push(d):o[c]=[o[c],d]:o[c]=d;}return o};},2361:e=>{var t=function(e){switch(typeof e){case"string":return e;case"boolean":return e?"true":"false";case"number":return isFinite(e)?e:"";default:return ""}};e.exports=function(e,r,n,i){return r=r||"&",n=n||"=",null===e&&(e=void 0),"object"==typeof e?Object.keys(e).map((function(i){var o=encodeURIComponent(t(i))+n;return Array.isArray(e[i])?e[i].map((function(e){return o+encodeURIComponent(t(e))})).join(r):o+encodeURIComponent(t(e[i]))})).join(r):i?encodeURIComponent(t(i))+n+encodeURIComponent(t(e)):""};},7673:(e,t,r)=>{t.decode=t.parse=r(2587),t.encode=t.stringify=r(2361);},1269:e=>{class t{constructor(e={}){if(!(e.maxSize&&e.maxSize>0))throw new TypeError("`maxSize` must be a number greater than 0");this.maxSize=e.maxSize,this.cache=new Map,this.oldCache=new Map,this._size=0;}_set(e,t){this.cache.set(e,t),this._size++,this._size>=this.maxSize&&(this._size=0,this.oldCache=this.cache,this.cache=new Map);}get(e){if(this.cache.has(e))return this.cache.get(e);if(this.oldCache.has(e)){const t=this.oldCache.get(e);return this.oldCache.delete(e),this._set(e,t),t}}set(e,t){return this.cache.has(e)?this.cache.set(e,t):this._set(e,t),this}has(e){return this.cache.has(e)||this.oldCache.has(e)}peek(e){return this.cache.has(e)?this.cache.get(e):this.oldCache.has(e)?this.oldCache.get(e):void 0}delete(e){const t=this.cache.delete(e);return t&&this._size--,this.oldCache.delete(e)||t}clear(){this.cache.clear(),this.oldCache.clear(),this._size=0;}*keys(){for(const[e]of this)yield e;}*values(){for(const[,e]of this)yield e;}*[Symbol.iterator](){for(const e of this.cache)yield e;for(const e of this.oldCache){const[t]=e;this.cache.has(t)||(yield e);}}get size(){let e=0;for(const t of this.oldCache.keys())this.cache.has(t)||e++;return this._size+e}}e.exports=t;},2511:function(e,t,r){var n;e=r.nmd(e),function(i){t&&t.nodeType,e&&e.nodeType;var o="object"==typeof r.g&&r.g;o.global!==o&&o.window!==o&&o.self;var s,a=2147483647,f=36,h=/^xn--/,l=/[^\x20-\x7E]/,u=/[\x2E\u3002\uFF0E\uFF61]/g,c={overflow:"Overflow: input needs wider integers to process","not-basic":"Illegal input >= 0x80 (not a basic code point)","invalid-input":"Invalid input"},d=Math.floor,p=String.fromCharCode;function g(e){throw RangeError(c[e])}function m(e,t){for(var r=e.length,n=[];r--;)n[r]=t(e[r]);return n}function y(e,t){var r=e.split("@"),n="";return r.length>1&&(n=r[0]+"@",e=r[1]),n+m((e=e.replace(u,".")).split("."),t).join(".")}function b(e){for(var t,r,n=[],i=0,o=e.length;i=55296&&t<=56319&&i65535&&(t+=p((e-=65536)>>>10&1023|55296),e=56320|1023&e),t+p(e)})).join("")}function w(e,t){return e+22+75*(e<26)-((0!=t)<<5)}function _(e,t,r){var n=0;for(e=r?d(e/700):e>>1,e+=d(e/t);e>455;n+=f)e=d(e/35);return d(n+36*e/(e+38))}function B(e){var t,r,n,i,o,s,h,l,u,c,p,m=[],y=e.length,b=0,w=128,B=72;for((r=e.lastIndexOf("-"))<0&&(r=0),n=0;n=128&&g("not-basic"),m.push(e.charCodeAt(n));for(i=r>0?r+1:0;i=y&&g("invalid-input"),((l=(p=e.charCodeAt(i++))-48<10?p-22:p-65<26?p-65:p-97<26?p-97:f)>=f||l>d((a-b)/s))&&g("overflow"),b+=l*s,!(l<(u=h<=B?1:h>=B+26?26:h-B));h+=f)s>d(a/(c=f-u))&&g("overflow"),s*=c;B=_(b-o,t=m.length+1,0==o),d(b/t)>a-w&&g("overflow"),w+=d(b/t),b%=t,m.splice(b++,0,w);}return v(m)}function E(e){var t,r,n,i,o,s,h,l,u,c,m,y,v,B,E,S=[];for(y=(e=b(e)).length,t=128,r=0,o=72,s=0;s=t&&md((a-r)/(v=n+1))&&g("overflow"),r+=(h-t)*v,t=h,s=0;sa&&g("overflow"),m==t){for(l=r,u=f;!(l<(c=u<=o?1:u>=o+26?26:u-o));u+=f)E=l-c,B=f-c,S.push(p(w(c+E%B,0))),l=d(E/B);S.push(p(w(l,0))),o=_(r,v,n==i),r=0,++n;}++r,++t;}return S.join("")}s={version:"1.3.2",ucs2:{decode:b,encode:v},decode:B,encode:E,toASCII:function(e){return y(e,(function(e){return l.test(e)?"xn--"+E(e):e}))},toUnicode:function(e){return y(e,(function(e){return h.test(e)?B(e.slice(4).toLowerCase()):e}))}},void 0===(n=function(){return s}.call(t,r,t,e))||(e.exports=n);}();},8575:(e,t,r)=>{var n=r(2511),i=r(2502);function o(){this.protocol=null,this.slashes=null,this.auth=null,this.host=null,this.port=null,this.hostname=null,this.hash=null,this.search=null,this.query=null,this.pathname=null,this.path=null,this.href=null;}t.parse=v,t.resolve=function(e,t){return v(e,!1,!0).resolve(t)},t.resolveObject=function(e,t){return e?v(e,!1,!0).resolveObject(t):t},t.format=function(e){return i.isString(e)&&(e=v(e)),e instanceof o?e.format():o.prototype.format.call(e)},t.Url=o;var s=/^([a-z0-9.+-]+:)/i,a=/:[0-9]*$/,f=/^(\/\/?(?!\/)[^\?\s]*)(\?[^\s]*)?$/,h=["{","}","|","\\","^","`"].concat(["<",">",'"',"`"," ","\r","\n","\t"]),l=["'"].concat(h),u=["%","/","?",";","#"].concat(l),c=["/","?","#"],d=/^[+a-z0-9A-Z_-]{0,63}$/,p=/^([+a-z0-9A-Z_-]{0,63})(.*)$/,g={javascript:!0,"javascript:":!0},m={javascript:!0,"javascript:":!0},y={http:!0,https:!0,ftp:!0,gopher:!0,file:!0,"http:":!0,"https:":!0,"ftp:":!0,"gopher:":!0,"file:":!0},b=r(7673);function v(e,t,r){if(e&&i.isObject(e)&&e instanceof o)return e;var n=new o;return n.parse(e,t,r),n}o.prototype.parse=function(e,t,r){if(!i.isString(e))throw new TypeError("Parameter 'url' must be a string, not "+typeof e);var o=e.indexOf("?"),a=-1!==o&&o127?O+="x":O+=F[T];if(!O.match(d)){var P=I.slice(0,R),N=I.slice(R+1),L=F.match(p);L&&(P.push(L[1]),N.unshift(L[2])),N.length&&(v="/"+N.join(".")+v),this.hostname=P.join(".");break}}}this.hostname.length>255?this.hostname="":this.hostname=this.hostname.toLowerCase(),x||(this.hostname=n.toASCII(this.hostname));var z=this.port?":"+this.port:"",D=this.hostname||"";this.host=D+z,this.href+=this.host,x&&(this.hostname=this.hostname.substr(1,this.hostname.length-2),"/"!==v[0]&&(v="/"+v));}if(!g[B])for(R=0,M=l.length;R0)&&r.host.split("@"))&&(r.auth=x.shift(),r.host=r.hostname=x.shift())),r.search=e.search,r.query=e.query,i.isNull(r.pathname)&&i.isNull(r.search)||(r.path=(r.pathname?r.pathname:"")+(r.search?r.search:"")),r.href=r.format(),r;if(!E.length)return r.pathname=null,r.search?r.path="/"+r.search:r.path=null,r.href=r.format(),r;for(var A=E.slice(-1)[0],C=(r.host||e.host||E.length>1)&&("."===A||".."===A)||""===A,R=0,k=E.length;k>=0;k--)"."===(A=E[k])?E.splice(k,1):".."===A?(E.splice(k,1),R++):R&&(E.splice(k,1),R--);if(!_&&!B)for(;R--;R)E.unshift("..");!_||""===E[0]||E[0]&&"/"===E[0].charAt(0)||E.unshift(""),C&&"/"!==E.join("/").substr(-1)&&E.push("");var x,I=""===E[0]||E[0]&&"/"===E[0].charAt(0);return S&&(r.hostname=r.host=I?"":E.length?E.shift():"",(x=!!(r.host&&r.host.indexOf("@")>0)&&r.host.split("@"))&&(r.auth=x.shift(),r.host=r.hostname=x.shift())),(_=_||r.host&&E.length)&&!I&&E.unshift(""),E.length?r.pathname=E.join("/"):(r.pathname=null,r.path=null),i.isNull(r.pathname)&&i.isNull(r.search)||(r.path=(r.pathname?r.pathname:"")+(r.search?r.search:"")),r.auth=e.auth||r.auth,r.slashes=r.slashes||e.slashes,r.href=r.format(),r},o.prototype.parseHost=function(){var e=this.host,t=a.exec(e);t&&(":"!==(t=t[0])&&(this.port=t.substr(1)),e=e.substr(0,e.length-t.length)),e&&(this.hostname=e);};},2502:e=>{e.exports={isString:function(e){return "string"==typeof e},isObject:function(e){return "object"==typeof e&&null!==e},isNull:function(e){return null===e},isNullOrUndefined:function(e){return null==e}};},7067:()=>{}},t={};function r(n){var i=t[n];if(void 0!==i)return i.exports;var o=t[n]={id:n,loaded:!1,exports:{}};return e[n].call(o.exports,o,o.exports,r),o.loaded=!0,o.exports}r.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return r.d(t,{a:t}),t},r.d=(e,t)=>{for(var n in t)r.o(t,n)&&!r.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]});},r.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),r.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),r.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0});},r.nmd=e=>(e.paths=[],e.children||(e.children=[]),e);var n=r(5590); - //window.gmodCRAM=n - return n; - }; - - const gmodCRAM = fn(); - - /* - * The MIT License (MIT) - * - * Copyright (c) 2018 The Regents of the University of California - * Author: Jim Robinson - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - const READ_STRAND_FLAG = 0x10; - const MATE_STRAND_FLAG = 0x20; - - const CRAM_MATE_STRAND_FLAG = 0x1; - - /** - * Class for reading a cram file. Wraps the gMOD Cram package. - * - * @param config - * @constructor - */ - class CramReader { - - constructor(config, genome, browser) { - - this.config = config; - this.browser = browser; - this.genome = genome; - - this.cramFile = new gmodCRAM.CramFile({ - filehandle: new FileHandler(config.url, config), - seqFetch: config.seqFetch || seqFetch.bind(this), - checkSequenceMD5: config.checkSequenceMD5 !== undefined ? config.checkSequenceMD5 : true - }); - - const indexFileHandle = new FileHandler(config.indexURL, config); - this.indexedCramFile = new gmodCRAM.IndexedCramFile({ - cram: this.cramFile, - index: new gmodCRAM.CraiIndex({ - filehandle: indexFileHandle - }), - fetchSizeLimit: 30000000 - }); - - BamUtils.setReaderDefaults(this, config); - - function seqFetch(seqID, start, end) { - - const sequence = this.genome.sequence; - const genome = this.genome; - - return this.getHeader() - .then(function (header) { - const chr = genome.getChromosomeName(header.chrNames[seqID]); - return sequence.getSequence(chr, start - 1, end) - }) - } - } - - - /** - * Parse the sequence dictionary from the SAM header and build chr name tables. This function - * is public so it can be unit tested. - * - * @returns {PromiseLike} - */ - - async getHeader() { - - if (!this.header) { - const genome = this.genome; - const samHeader = await this.cramFile.getSamHeader(); - const chrToIndex = {}; - const chrNames = []; - const chrAliasTable = {}; - const readGroups = []; - - for (let line of samHeader) { - if ('SQ' === line.tag) { - for (let d of line.data) { - if (d.tag === "SN") { - const seq = d.value; - chrToIndex[seq] = chrNames.length; - chrNames.push(seq); - if (genome) { - const alias = genome.getChromosomeName(seq); - chrAliasTable[alias] = seq; - } - break - } - } - } else if ('RG' === line.tag) { - readGroups.push(line.data); - } - } - - this.header = { - chrNames: chrNames, - chrToIndex: chrToIndex, - chrAliasTable: chrAliasTable, - readGroups: readGroups - }; - } - - return this.header - } - - async readAlignments(chr, bpStart, bpEnd) { - - this.browser; - const header = await this.getHeader(); - const queryChr = header.chrAliasTable.hasOwnProperty(chr) ? header.chrAliasTable[chr] : chr; - const chrIdx = header.chrToIndex[queryChr]; - const alignmentContainer = new AlignmentContainer(chr, bpStart, bpEnd, this.config); - - if (chrIdx === undefined) { - return alignmentContainer - - } else { - - try { - const records = await this.indexedCramFile.getRecordsForRange(chrIdx, bpStart, bpEnd); - - for (let record of records) { - - const refID = record.sequenceId; - const pos = record.alignmentStart; - const alignmentEnd = pos + record.lengthOnRef; - - if (refID < 0) { - continue // unmapped read - } else if (refID > chrIdx || pos > bpEnd) { - return // off right edge, we're done - } else if (refID < chrIdx) { - continue // Sequence to left of start, not sure this is possible - } - if (alignmentEnd < bpStart) { - continue - } // Record out-of-range "to the left", skip to next one - - const alignment = decodeCramRecord(record, header.chrNames); - - if (this.filter.pass(alignment)) { - alignmentContainer.push(alignment); - } - } - - alignmentContainer.finish(); - return alignmentContainer - } catch (error) { - let message = error.message; - if (message && message.indexOf("MD5") >= 0) { - message = "Sequence mismatch. Is this the correct genome for the loaded CRAM?"; - } - this.browser.alert.present(new Error(message)); - throw error - } - } - - function decodeCramRecord(record, chrNames) { - - const alignment = new BamAlignment(); - - alignment.chr = chrNames[record.sequenceId]; - alignment.start = record.alignmentStart - 1; - alignment.lengthOnRef = record.lengthOnRef; - alignment.flags = record.flags; - alignment.strand = !(record.flags & READ_STRAND_FLAG); - alignment.fragmentLength = record.templateLength || record.templateSize; - alignment.mq = record.mappingQuality; - alignment.end = record.alignmentStart + record.lengthOnRef; - alignment.readGroupId = record.readGroupId; - - if (record.mate && record.mate.sequenceId !== undefined) { - const strand = record.mate.flags !== undefined ? - !(record.mate.flags & CRAM_MATE_STRAND_FLAG) : - !(record.flags & MATE_STRAND_FLAG); - - alignment.mate = { - chr: chrNames[record.mate.sequenceId], - position: record.mate.alignmentStart, - strand: strand - }; - } - - alignment.seq = record.getReadBases(); - alignment.qual = record.qualityScores; - alignment.tagDict = record.tags; - alignment.readName = record.readName; - - // TODO -- cigar encoded in tag? - // BamUtils.bam_tag2cigar(ba, blockEnd, p, lseq, alignment, cigarArray); - - makeBlocks(record, alignment); - - if (alignment.mate && alignment.start > alignment.mate.position && alignment.fragmentLength > 0) { - alignment.fragmentLength = -alignment.fragmentLength; - } - - BamUtils.setPairOrientation(alignment); - - return alignment - - } - - function makeBlocks(cramRecord, alignment) { - - const blocks = []; - let insertions; - let gaps; - let basesUsed = 0; - let cigarString = ''; - - alignment.scStart = alignment.start; - alignment.scLengthOnRef = alignment.lengthOnRef; - - if (cramRecord.readFeatures) { - - for (let feature of cramRecord.readFeatures) { - - const code = feature.code; - const data = feature.data; - const readPos = feature.pos - 1; - const refPos = feature.refPos - 1; - - switch (code) { - case 'S' : - case 'I': - case 'i': - case 'N': - case 'D': - if (readPos > basesUsed) { - const len = readPos - basesUsed; - blocks.push(new AlignmentBlock({ - start: refPos - len, - seqOffset: basesUsed, - len: len, - type: 'M' - })); - basesUsed += len; - cigarString += len + 'M'; - } - - if ('S' === code) { - let scPos = refPos; - alignment.scLengthOnRef += data.length; - if (readPos === 0) { - alignment.scStart -= data.length; - scPos -= data.length; - } - const len = data.length; - blocks.push(new AlignmentBlock({ - start: scPos, - seqOffset: basesUsed, - len: len, - type: 'S' - })); - basesUsed += len; - cigarString += len + code; - } else if ('I' === code || 'i' === code) { - if (insertions === undefined) { - insertions = []; - } - const len = 'i' === code ? 1 : data.length; - insertions.push(new AlignmentBlock({ - start: refPos, - len: len, - seqOffset: basesUsed, - type: 'I' - })); - basesUsed += len; - cigarString += len + code; - } else if ('D' === code || 'N' === code) { - if (!gaps) { - gaps = []; - } - gaps.push({ - start: refPos, - len: data, - type: code - }); - cigarString += data + code; - } - break - - case 'H': - case 'P': - cigarString += data + code; - break - // Ignore - } - } - } - - // Last block - const len = cramRecord.readLength - basesUsed; - if (len > 0) { - blocks.push(new AlignmentBlock({ - start: cramRecord.alignmentStart + cramRecord.lengthOnRef - len - 1, - seqOffset: basesUsed, - len: len, - type: 'M' - })); - - cigarString += len + 'M'; - } - - alignment.blocks = blocks; - alignment.insertions = insertions; - alignment.gaps = gaps; - alignment.cigar = cigarString; - - } - - } - } - - class FileHandler { - - constructor(source, config) { - this.position = 0; - this.url = source; - this.config = config; - this.cache = new BufferCache({ - fetch: (start, length) => this._fetch(start, length), - }); - } - - async _fetch(position, length) { - - const loadRange = {start: position, size: length}; - this._stat = {size: undefined}; - const arrayBuffer = await igvxhr.loadArrayBuffer(this.url, buildOptions$1(this.config, {range: loadRange})); - return Buffer.from(arrayBuffer) - } - - async read(buffer, offset = 0, length = Infinity, position = 0) { - let readPosition = position; - if (readPosition === null) { - readPosition = this.position; - this.position += length; - } - return this.cache.get(buffer, offset, length, position) - } - - async readFile() { - const arrayBuffer = await igvxhr.loadArrayBuffer(this.url, buildOptions$1(this.config)); - return Buffer.from(arrayBuffer) - } - - async stat() { - if (!this._stat) { - const buf = Buffer.allocUnsafe(10); - await this.read(buf, 0, 10, 0); - if (!this._stat) - throw new Error(`unable to determine size of file at ${this.url}`) - } - return this._stat - } - } - - class BufferCache { - - constructor({fetch, size = 10000000, chunkSize = 32768}) { - - this.fetch = fetch; - this.chunkSize = chunkSize; - this.lruCache = new QuickLRU({maxSize: Math.floor(size / chunkSize)}); - } - - async get(outputBuffer, offset, length, position) { - if (outputBuffer.length < offset + length) - throw new Error('output buffer not big enough for request') - - // calculate the list of chunks involved in this fetch - const firstChunk = Math.floor(position / this.chunkSize); - const lastChunk = Math.floor((position + length) / this.chunkSize); - - // fetch them all as necessary - const fetches = new Array(lastChunk - firstChunk + 1); - for (let chunk = firstChunk; chunk <= lastChunk; chunk += 1) { - fetches[chunk - firstChunk] = this._getChunk(chunk).then(data => ({ - data, - chunkNumber: chunk, - })); - } - - // stitch together the response buffer using them - const chunks = await Promise.all(fetches); - const chunksOffset = position - chunks[0].chunkNumber * this.chunkSize; - chunks.forEach(({data, chunkNumber}) => { - const chunkPositionStart = chunkNumber * this.chunkSize; - let copyStart = 0; - let copyEnd = this.chunkSize; - let copyOffset = - offset + (chunkNumber - firstChunk) * this.chunkSize - chunksOffset; - - if (chunkNumber === firstChunk) { - copyOffset = offset; - copyStart = chunksOffset; - } - if (chunkNumber === lastChunk) { - copyEnd = position + length - chunkPositionStart; - } - - data.copy(outputBuffer, copyOffset, copyStart, copyEnd); - }); - } - - _getChunk(chunkNumber) { - const cachedPromise = this.lruCache.get(chunkNumber); - if (cachedPromise) return cachedPromise - - const freshPromise = this.fetch( - chunkNumber * this.chunkSize, - this.chunkSize, - ); - this.lruCache.set(chunkNumber, freshPromise); - return freshPromise - } - } - - class QuickLRU { - constructor(options = {}) { - if (!(options.maxSize && options.maxSize > 0)) { - throw new TypeError('`maxSize` must be a number greater than 0') - } - - this.maxSize = options.maxSize; - this.cache = new Map(); - this.oldCache = new Map(); - this._size = 0; - } - - _set(key, value) { - this.cache.set(key, value); - this._size++; - - if (this._size >= this.maxSize) { - this._size = 0; - this.oldCache = this.cache; - this.cache = new Map(); - } - } - - get(key) { - if (this.cache.has(key)) { - return this.cache.get(key) - } - - if (this.oldCache.has(key)) { - const value = this.oldCache.get(key); - this._set(key, value); - return value - } - } - - set(key, value) { - if (this.cache.has(key)) { - this.cache.set(key, value); - } else { - this._set(key, value); - } - - return this - } - - has(key) { - return this.cache.has(key) || this.oldCache.has(key) - } - - peek(key) { - if (this.cache.has(key)) { - return this.cache.get(key) - } - - if (this.oldCache.has(key)) { - return this.oldCache.get(key) - } - } - - delete(key) { - const deleted = this.cache.delete(key); - if (deleted) { - this._size--; - } - - return this.oldCache.delete(key) || deleted - } - - clear() { - this.cache.clear(); - this.oldCache.clear(); - this._size = 0; - } - - * keys() { - for (const [key] of this) { - yield key; - } - } - - * values() { - for (const [, value] of this) { - yield value; - } - } - - * [Symbol.iterator]() { - for (const item of this.cache) { - yield item; - } - - for (const item of this.oldCache) { - const [key] = item; - if (!this.cache.has(key)) { - yield item; - } - } - } - - get size() { - let oldCacheSize = 0; - for (const key of this.oldCache.keys()) { - if (!this.cache.has(key)) { - oldCacheSize++; - } - } - - return this._size + oldCacheSize - } - } - - /* - * The MIT License (MIT) - * - * Copyright (c) 2014 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - var CigarOperationTable = { - "ALIGNMENT_MATCH": "M", - "INSERT": "I", - "DELETE": "D", - "SKIP": "N", - "CLIP_SOFT": "S", - "CLIP_HARD": "H", - "PAD": "P", - "SEQUENCE_MATCH": "=", - "SEQUENCE_MISMATCH": "X" - }; - - const Ga4ghAlignmentReader = function (config, genome) { - - this.config = config; - this.genome = genome; - this.url = config.url; - this.filter = new BamFilter(config.filter); - this.readGroupSetIds = config.readGroupSetIds; - this.authKey = config.authKey; // Might be undefined or nill - - this.samplingWindowSize = config.samplingWindowSize === undefined ? 100 : config.samplingWindowSize; - this.samplingDepth = config.samplingDepth === undefined ? 1000 : config.samplingDepth; - if (config.viewAsPairs) { - this.pairsSupported = true; - } else { - this.pairsSupported = config.pairsSupported === undefined ? true : config.pairsSupported; - } - }; - - - Ga4ghAlignmentReader.prototype.readAlignments = function (chr, bpStart, bpEnd) { - - const genome = this.genome; - const self = this; - - return getChrAliasTable() - - .then(function (chrAliasTable) { - - var queryChr = chrAliasTable.hasOwnProperty(chr) ? chrAliasTable[chr] : chr, - readURL = self.url + "/reads/search"; - - return ga4ghSearch({ - url: readURL, - body: { - "readGroupSetIds": [self.readGroupSetIds], - "referenceName": queryChr, - "start": bpStart, - "end": bpEnd, - "pageSize": "10000" - }, - decode: decodeGa4ghReads, - results: new AlignmentContainer(chr, bpStart, bpEnd, self.config) - }) - }) - - - function getChrAliasTable() { - - if (self.chrAliasTable) { - - return Promise.resolve(self.chrAliasTable) - - } else { - - return self.readMetadata() - - .then(function (json) { - - self.chrAliasTable = {}; - - if (genome && json.readGroups && json.readGroups.length > 0) { - - var referenceSetId = json.readGroups[0].referenceSetId; - - if (referenceSetId) { - - // Query for reference names to build an alias table (map of genome ref names -> dataset ref names) - var readURL = self.url + "/references/search"; - - return ga4ghSearch({ - url: readURL, - body: { - "referenceSetId": referenceSetId - }, - decode: function (j) { - return j.references - } - }) - .then(function (references) { - - - references.forEach(function (ref) { - var refName = ref.name, - alias = genome.getChromosomeName(refName); - self.chrAliasTable[alias] = refName; - }); - - - return self.chrAliasTable - - }) - } else { - - // Try hardcoded constants -- workaround for non-compliant data at Google - populateChrAliasTable(self.chrAliasTable, self.config.datasetId); - - return self.chrAliasTable - } - } else { - // No browser object, can't build map. This can occur when run from unit tests - return self.chrAliasTable - } - }) - } - } - - /** - * Decode an array of ga4gh read records - * - - */ - function decodeGa4ghReads(j) { - - var i, - jsonRecords = j.alignments, - len = jsonRecords.length, - alignment, - jsonAlignment, - cigarDecoded, - alignments = [], - mate, - blocks; - - for (i = 0; i < len; i++) { - - let record = jsonRecords[i]; - - alignment = new BamAlignment(); - - alignment.readName = record.fragmentName; - alignment.properPlacement = record.properPlacement; - alignment.duplicateFragment = record.duplicateFragment; - alignment.numberReads = record.numberReads; - alignment.fragmentLength = record.fragmentLength; - alignment.readNumber = record.readNumber; - alignment.failedVendorQualityChecks = record.failedVendorQualityChecks; - alignment.secondaryAlignment = record.secondaryAlignment; - alignment.supplementaryAlignment = record.supplementaryAlignment; - alignment.seq = record.alignedSequence; - alignment.qual = record.alignedQuality; - alignment.matePos = record.nextMatePosition; - alignment.tagDict = record.info; - alignment.flags = encodeFlags(); - - - jsonAlignment = record.alignment; - if (jsonAlignment) { - alignment.mapped = true; - - alignment.chr = record.alignment.position.referenceName; - if (genome) alignment.chr = genome.getChromosomeName(alignment.chr); - - alignment.start = parseInt(record.alignment.position.position); - alignment.strand = !(record.alignment.position.reverseStrand); - alignment.mq = record.alignment.mappingQuality; - alignment.cigar = encodeCigar(record.alignment.cigar); - cigarDecoded = translateCigar(record.alignment.cigar); - - alignment.lengthOnRef = cigarDecoded.lengthOnRef; - - blocks = makeBlocks(alignment, cigarDecoded.array); - alignment.blocks = blocks.blocks; - alignment.insertions = blocks.insertions; - - } else { - alignment.mapped = false; - } - - mate = record.nextMatePosition; - if (mate) { - alignment.mate = { - chr: mate.referenceFrame, - position: parseInt(mate.position), - strand: !mate.reverseStrand - }; - } - - if (self.filter.pass(alignment)) { - alignments.push(alignment); - } - - - } - - return alignments - - - // Encode a cigar string -- used for popup text - function encodeCigar(cigarArray) { - - var cigarString = ""; - cigarArray.forEach(function (cigarUnit) { - var op = CigarOperationTable[cigarUnit.operation], - len = cigarUnit.operationLength; - cigarString = cigarString + (len + op); - }); - - return cigarString - } - - // TODO -- implement me - function encodeFlags(json) { - return 0 - } - - function translateCigar(cigar) { - - var cigarUnit, opLen, opLtr, - lengthOnRef = 0, - cigarArray = [], - i; - - for (i = 0; i < cigar.length; i++) { - - cigarUnit = cigar[i]; - - opLtr = CigarOperationTable[cigarUnit.operation]; - opLen = parseInt(cigarUnit.operationLength); // Google represents long as a String - - if (opLtr === 'M' || opLtr === 'EQ' || opLtr === 'X' || opLtr === 'D' || opLtr === 'N' || opLtr === '=') - lengthOnRef += opLen; - - cigarArray.push({len: opLen, ltr: opLtr}); - - } - - return {lengthOnRef: lengthOnRef, array: cigarArray} - } - - - /** - * Split the alignment record into blocks as specified in the cigarArray. Each aligned block contains - * its portion of the read sequence and base quality strings. A read sequence or base quality string - * of "*" indicates the value is not recorded. In all other cases the length of the block sequence (block.seq) - * and quality string (block.qual) must == the block length. - * - * NOTE: Insertions are not yet treated // TODO - * - * @param record - * @param cigarArray - * @returns array of blocks - */ - function makeBlocks(record, cigarArray) { - - - var blocks = [], - gaps, - insertions, - seqOffset = 0, - pos = record.start, - len = cigarArray.length, - gapType; - - for (var i = 0; i < len; i++) { - - var c = cigarArray[i]; - - switch (c.ltr) { - case 'H' : - break // ignore hard clips - case 'P' : - break // ignore pads - case 'S' : - seqOffset += c.len; - gapType = 'S'; - break // soft clip read bases - case 'N' : - case 'D' : - if (gaps === undefined) { - gaps = []; - } - gaps.push({ - start: pos, - len: c.len, - type: c.ltr - }); - pos += c.len; - break - case 'I' : - if (insertions === undefined) insertions = []; - insertions.push(new AlignmentBlock({ - start: pos, - len: c.len, - seqOffset: seqOffset - })); - seqOffset += c.len; - break - case 'M' : - case 'EQ' : - case '=' : - case 'X' : - blocks.push( - new AlignmentBlock({ - start: pos, - len: c.len, - seqOffset: seqOffset, - gapType: gapType - })); - seqOffset += c.len; - pos += c.len; - - break - - default : - console.log("Error processing cigar element: " + c.len + c.ltr); - } - } - - return {blocks: blocks, insertions: insertions, gaps: gaps} - } - } - }; - - - Ga4ghAlignmentReader.prototype.readMetadata = function () { - - return ga4ghGet({ - url: this.url, - entity: "readgroupsets", - entityId: this.readGroupSetIds - }) - }; - - /** - * Hardcoded hack to work around some non-compliant google datasets - * - * @param chrAliasTable - * @param datasetId - */ - function populateChrAliasTable(chrAliasTable, datasetId) { - var i; - if ("461916304629" === datasetId || "337315832689" === datasetId) { - for (i = 1; i < 23; i++) { - chrAliasTable["chr" + i] = i; - } - chrAliasTable["chrX"] = "X"; - chrAliasTable["chrY"] = "Y"; - chrAliasTable["chrM"] = "MT"; - } - } - - /* - * The MIT License (MIT) - * - * Copyright (c) 2014 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - class BamSource { - - constructor(config, browser) { - - const genome = browser.genome; - - this.config = config; - this.genome = genome; - - if (isDataURL(config.url)) { - this.config.indexed = false; - } - - if ("ga4gh" === config.sourceType) { - this.bamReader = new Ga4ghAlignmentReader(config, genome); - } else if ("pysam" === config.sourceType) { - this.bamReader = new BamWebserviceReader(config, genome); - } else if ("htsget" === config.sourceType) { - this.bamReader = new HtsgetBamReader(config, genome); - } else if ("shardedBam" === config.sourceType) { - this.bamReader = new ShardedBamReader(config, genome); - } else if ("cram" === config.format) { - this.bamReader = new CramReader(config, genome, browser); - } else { - if (!this.config.indexURL && config.indexed !== false) { - if (isString$2(this.config.url)) { - const inferIndexPath$1 = inferIndexPath(this.config.url, "bai"); - if (inferIndexPath$1) { - console.error(`Warning: no indexURL specified for ${this.config.url}. Guessing ${this.baiPath}`); - this.config.indexURL = inferIndexPath$1; - } else { - console.error(`Warning: no indexURL specified for ${this.config.url}.`); - this.config.indexed = false; - } - } else { - console.error(`Warning: no indexURL specified for ${this.config.name}.`); - this.config.indexed = false; - } - } - - if (this.config.indexed !== false) { // && this.config.indexURL) { - this.bamReader = new BamReader(config, genome); - } else { - this.bamReader = new BamReaderNonIndexed(config, genome); - } - } - - this.viewAsPairs = config.viewAsPairs; - this.showSoftClips = config.showSoftClips; - } - - setViewAsPairs(bool) { - this.viewAsPairs = bool; - } - - setShowSoftClips(bool) { - this.showSoftClips = bool; - } - - async getAlignments(chr, bpStart, bpEnd) { - - const genome = this.genome; - const showSoftClips = this.showSoftClips; - - const alignmentContainer = await this.bamReader.readAlignments(chr, bpStart, bpEnd); - let alignments = alignmentContainer.alignments; - if (!this.viewAsPairs) { - alignments = unpairAlignments([{alignments: alignments}]); - } - const hasAlignments = alignments.length > 0; - alignmentContainer.packedAlignmentRows = packAlignmentRows(alignments, alignmentContainer.start, alignmentContainer.end, showSoftClips); - - this.alignmentContainer = alignmentContainer; - - if (hasAlignments) { - const sequence = await genome.sequence.getSequence(chr, alignmentContainer.start, alignmentContainer.end); - if (sequence) { - alignmentContainer.coverageMap.refSeq = sequence; // TODO -- fix this - alignmentContainer.sequence = sequence; // TODO -- fix this - return alignmentContainer - } else { - console.error("No sequence for: " + chr + ":" + alignmentContainer.start + "-" + alignmentContainer.end); - } - } - return alignmentContainer - - } - } - - function paintAxis(ctx, pixelWidth, pixelHeight) { - - var x1, - x2, - y1, - y2, - a, - b, - reference, - shim, - font = { - 'font': 'normal 10px Arial', - 'textAlign': 'right', - 'strokeStyle': "black" - }; - - if (undefined === this.dataRange || undefined === this.dataRange.max || undefined === this.dataRange.min) { - return - } - - let flipAxis = (undefined === this.flipAxis) ? false : this.flipAxis; - - IGVGraphics.fillRect(ctx, 0, 0, pixelWidth, pixelHeight, {'fillStyle': "rgb(255, 255, 255)"}); - - reference = 0.95 * pixelWidth; - x1 = reference - 8; - x2 = reference; - - //shim = 0.5 * 0.125; - shim = .01; - y1 = y2 = shim * pixelHeight; - - a = {x: x2, y: y1}; - - // tick - IGVGraphics.strokeLine(ctx, x1, y1, x2, y2, font); - IGVGraphics.fillText(ctx, prettyPrint(flipAxis ? this.dataRange.min : this.dataRange.max), x1 + 4, y1 + 12, font); - - //shim = 0.25 * 0.125; - y1 = y2 = (1.0 - shim) * pixelHeight; - - b = {x: x2, y: y1}; - - // tick - IGVGraphics.strokeLine(ctx, x1, y1, x2, y2, font); - IGVGraphics.fillText(ctx, prettyPrint(flipAxis ? this.dataRange.max : this.dataRange.min), x1 + 4, y1 - 4, font); - - IGVGraphics.strokeLine(ctx, a.x, a.y, b.x, b.y, font); - - function prettyPrint(number) { - // if number >= 100, show whole number - // if >= 1 show 1 significant digits - // if < 1 show 2 significant digits - - if (number === 0) { - return "0" - } else if (Math.abs(number) >= 10) { - return number.toFixed() - } else if (Math.abs(number) >= 1) { - return number.toFixed(1) - } else { - return number.toFixed(2) - } - } - } - - class Locus { - - constructor({chr, start, end}) { - this.chr = chr; - this.start = start; - this.end = end; - } - - - contains(locus) { - return locus.chr === this.chr && locus.start >= this.start && locus.end <= this.end - } - - overlaps(locus) { - return locus.chr === this.chr && !(locus.end < this.start || locus.start > this.end) - } - - extend(l) { - if (l.chr !== this.chr) return - this.start = Math.min(l.start, this.start); - this.end = Math.max(l.end, this.end); - } - - getLocusString() { - if ('all' === this.chr) { - return 'all' - } else { - const ss = numberFormatter$1(Math.floor(this.start) + 1); - const ee = numberFormatter$1(Math.round(this.end)); - return `${this.chr}:${ss}-${ee}` - } - } - - static fromLocusString(str) { - if ('all' === str) { - return new Locus({chr: 'all'}) - } - const parts = str.split(':'); - const chr = parts[0]; - const se = parts[1].split("-"); - const start = Number.parseInt(se[0].replace(/,/g, "")) - 1; - const end = Number.parseInt(se[1].replace(/,/g, "")); - return new Locus({chr, start, end}) - } - } - - /*! - * vanilla-picker v2.12.1 - * https://vanilla-picker.js.org - * - * Copyright 2017-2021 Andreas Borgen (https://github.com/Sphinxxxx), Adam Brooks (https://github.com/dissimulate) - * Released under the ISC license. - */ - var classCallCheck = function (instance, Constructor) { - if (!(instance instanceof Constructor)) { - throw new TypeError("Cannot call a class as a function"); - } - }; - - var createClass = function () { - function defineProperties(target, props) { - for (var i = 0; i < props.length; i++) { - var descriptor = props[i]; - descriptor.enumerable = descriptor.enumerable || false; - descriptor.configurable = true; - if ("value" in descriptor) descriptor.writable = true; - Object.defineProperty(target, descriptor.key, descriptor); - } - } - - return function (Constructor, protoProps, staticProps) { - if (protoProps) defineProperties(Constructor.prototype, protoProps); - if (staticProps) defineProperties(Constructor, staticProps); - return Constructor; - }; - }(); - - var slicedToArray = function () { - function sliceIterator(arr, i) { - var _arr = []; - var _n = true; - var _d = false; - var _e = undefined; - - try { - for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { - _arr.push(_s.value); - - if (i && _arr.length === i) break; - } - } catch (err) { - _d = true; - _e = err; - } finally { - try { - if (!_n && _i["return"]) _i["return"](); - } finally { - if (_d) throw _e; - } - } - - return _arr; - } - - return function (arr, i) { - if (Array.isArray(arr)) { - return arr; - } else if (Symbol.iterator in Object(arr)) { - return sliceIterator(arr, i); - } else { - throw new TypeError("Invalid attempt to destructure non-iterable instance"); - } - }; - }(); - - String.prototype.startsWith = String.prototype.startsWith || function (needle) { - return this.indexOf(needle) === 0; - }; - String.prototype.padStart = String.prototype.padStart || function (len, pad) { - var str = this;while (str.length < len) { - str = pad + str; - }return str; - }; - - var colorNames = { cb: '0f8ff', tqw: 'aebd7', q: '-ffff', qmrn: '7fffd4', zr: '0ffff', bg: '5f5dc', bsq: 'e4c4', bck: '---', nch: 'ebcd', b: '--ff', bvt: '8a2be2', brwn: 'a52a2a', brw: 'deb887', ctb: '5f9ea0', hrt: '7fff-', chcT: 'd2691e', cr: '7f50', rnw: '6495ed', crns: '8dc', crms: 'dc143c', cn: '-ffff', Db: '--8b', Dcn: '-8b8b', Dgnr: 'b8860b', Dgr: 'a9a9a9', Dgrn: '-64-', Dkhk: 'bdb76b', Dmgn: '8b-8b', Dvgr: '556b2f', Drng: '8c-', Drch: '9932cc', Dr: '8b--', Dsmn: 'e9967a', Dsgr: '8fbc8f', DsTb: '483d8b', DsTg: '2f4f4f', Dtrq: '-ced1', Dvt: '94-d3', ppnk: '1493', pskb: '-bfff', mgr: '696969', grb: '1e90ff', rbrc: 'b22222', rwht: 'af0', stg: '228b22', chs: '-ff', gnsb: 'dcdcdc', st: '8f8ff', g: 'd7-', gnr: 'daa520', gr: '808080', grn: '-8-0', grnw: 'adff2f', hnw: '0fff0', htpn: '69b4', nnr: 'cd5c5c', ng: '4b-82', vr: '0', khk: '0e68c', vnr: 'e6e6fa', nrb: '0f5', wngr: '7cfc-', mnch: 'acd', Lb: 'add8e6', Lcr: '08080', Lcn: 'e0ffff', Lgnr: 'afad2', Lgr: 'd3d3d3', Lgrn: '90ee90', Lpnk: 'b6c1', Lsmn: 'a07a', Lsgr: '20b2aa', Lskb: '87cefa', LsTg: '778899', Lstb: 'b0c4de', Lw: 'e0', m: '-ff-', mgrn: '32cd32', nn: 'af0e6', mgnt: '-ff', mrn: '8--0', mqm: '66cdaa', mmb: '--cd', mmrc: 'ba55d3', mmpr: '9370db', msg: '3cb371', mmsT: '7b68ee', '': '-fa9a', mtr: '48d1cc', mmvt: 'c71585', mnLb: '191970', ntc: '5fffa', mstr: 'e4e1', mccs: 'e4b5', vjw: 'dead', nv: '--80', c: 'df5e6', v: '808-0', vrb: '6b8e23', rng: 'a5-', rngr: '45-', rch: 'da70d6', pgnr: 'eee8aa', pgrn: '98fb98', ptrq: 'afeeee', pvtr: 'db7093', ppwh: 'efd5', pchp: 'dab9', pr: 'cd853f', pnk: 'c0cb', pm: 'dda0dd', pwrb: 'b0e0e6', prp: '8-080', cc: '663399', r: '--', sbr: 'bc8f8f', rb: '4169e1', sbrw: '8b4513', smn: 'a8072', nbr: '4a460', sgrn: '2e8b57', ssh: '5ee', snn: 'a0522d', svr: 'c0c0c0', skb: '87ceeb', sTb: '6a5acd', sTgr: '708090', snw: 'afa', n: '-ff7f', stb: '4682b4', tn: 'd2b48c', t: '-8080', thst: 'd8bfd8', tmT: '6347', trqs: '40e0d0', vt: 'ee82ee', whT: '5deb3', wht: '', hts: '5f5f5', w: '-', wgrn: '9acd32' }; - - function printNum(num) { - var decs = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1; - - var str = decs > 0 ? num.toFixed(decs).replace(/0+$/, '').replace(/\.$/, '') : num.toString(); - return str || '0'; - } - - var Color = function () { - function Color(r, g, b, a) { - classCallCheck(this, Color); - - - var that = this; - function parseString(input) { - - if (input.startsWith('hsl')) { - var _input$match$map = input.match(/([\-\d\.e]+)/g).map(Number), - _input$match$map2 = slicedToArray(_input$match$map, 4), - h = _input$match$map2[0], - s = _input$match$map2[1], - l = _input$match$map2[2], - _a = _input$match$map2[3]; - - if (_a === undefined) { - _a = 1; - } - - h /= 360; - s /= 100; - l /= 100; - that.hsla = [h, s, l, _a]; - } else if (input.startsWith('rgb')) { - var _input$match$map3 = input.match(/([\-\d\.e]+)/g).map(Number), - _input$match$map4 = slicedToArray(_input$match$map3, 4), - _r = _input$match$map4[0], - _g = _input$match$map4[1], - _b = _input$match$map4[2], - _a2 = _input$match$map4[3]; - - if (_a2 === undefined) { - _a2 = 1; - } - - that.rgba = [_r, _g, _b, _a2]; - } else { - if (input.startsWith('#')) { - that.rgba = Color.hexToRgb(input); - } else { - that.rgba = Color.nameToRgb(input) || Color.hexToRgb(input); - } - } - } - - if (r === undefined) ; else if (Array.isArray(r)) { - this.rgba = r; - } else if (b === undefined) { - var color = r && '' + r; - if (color) { - parseString(color.toLowerCase()); - } - } else { - this.rgba = [r, g, b, a === undefined ? 1 : a]; - } - } - - createClass(Color, [{ - key: 'printRGB', - value: function printRGB(alpha) { - var rgb = alpha ? this.rgba : this.rgba.slice(0, 3), - vals = rgb.map(function (x, i) { - return printNum(x, i === 3 ? 3 : 0); - }); - - return alpha ? 'rgba(' + vals + ')' : 'rgb(' + vals + ')'; - } - }, { - key: 'printHSL', - value: function printHSL(alpha) { - var mults = [360, 100, 100, 1], - suff = ['', '%', '%', '']; - - var hsl = alpha ? this.hsla : this.hsla.slice(0, 3), - vals = hsl.map(function (x, i) { - return printNum(x * mults[i], i === 3 ? 3 : 1) + suff[i]; - }); - - return alpha ? 'hsla(' + vals + ')' : 'hsl(' + vals + ')'; - } - }, { - key: 'printHex', - value: function printHex(alpha) { - var hex = this.hex; - return alpha ? hex : hex.substring(0, 7); - } - }, { - key: 'rgba', - get: function get() { - if (this._rgba) { - return this._rgba; - } - if (!this._hsla) { - throw new Error('No color is set'); - } - - return this._rgba = Color.hslToRgb(this._hsla); - }, - set: function set(rgb) { - if (rgb.length === 3) { - rgb[3] = 1; - } - - this._rgba = rgb; - this._hsla = null; - } - }, { - key: 'rgbString', - get: function get() { - return this.printRGB(); - } - }, { - key: 'rgbaString', - get: function get() { - return this.printRGB(true); - } - }, { - key: 'hsla', - get: function get() { - if (this._hsla) { - return this._hsla; - } - if (!this._rgba) { - throw new Error('No color is set'); - } - - return this._hsla = Color.rgbToHsl(this._rgba); - }, - set: function set(hsl) { - if (hsl.length === 3) { - hsl[3] = 1; - } - - this._hsla = hsl; - this._rgba = null; - } - }, { - key: 'hslString', - get: function get() { - return this.printHSL(); - } - }, { - key: 'hslaString', - get: function get() { - return this.printHSL(true); - } - }, { - key: 'hex', - get: function get() { - var rgb = this.rgba, - hex = rgb.map(function (x, i) { - return i < 3 ? x.toString(16) : Math.round(x * 255).toString(16); - }); - - return '#' + hex.map(function (x) { - return x.padStart(2, '0'); - }).join(''); - }, - set: function set(hex) { - this.rgba = Color.hexToRgb(hex); - } - }], [{ - key: 'hexToRgb', - value: function hexToRgb(input) { - - var hex = (input.startsWith('#') ? input.slice(1) : input).replace(/^(\w{3})$/, '$1F').replace(/^(\w)(\w)(\w)(\w)$/, '$1$1$2$2$3$3$4$4').replace(/^(\w{6})$/, '$1FF'); - - if (!hex.match(/^([0-9a-fA-F]{8})$/)) { - throw new Error('Unknown hex color; ' + input); - } - - var rgba = hex.match(/^(\w\w)(\w\w)(\w\w)(\w\w)$/).slice(1).map(function (x) { - return parseInt(x, 16); - }); - - rgba[3] = rgba[3] / 255; - return rgba; - } - }, { - key: 'nameToRgb', - value: function nameToRgb(input) { - - var hash = input.toLowerCase().replace('at', 'T').replace(/[aeiouyldf]/g, '').replace('ght', 'L').replace('rk', 'D').slice(-5, 4), - hex = colorNames[hash]; - return hex === undefined ? hex : Color.hexToRgb(hex.replace(/\-/g, '00').padStart(6, 'f')); - } - }, { - key: 'rgbToHsl', - value: function rgbToHsl(_ref) { - var _ref2 = slicedToArray(_ref, 4), - r = _ref2[0], - g = _ref2[1], - b = _ref2[2], - a = _ref2[3]; - - r /= 255; - g /= 255; - b /= 255; - - var max = Math.max(r, g, b), - min = Math.min(r, g, b); - var h = void 0, - s = void 0, - l = (max + min) / 2; - - if (max === min) { - h = s = 0; - } else { - var d = max - min; - s = l > 0.5 ? d / (2 - max - min) : d / (max + min); - switch (max) { - case r: - h = (g - b) / d + (g < b ? 6 : 0);break; - case g: - h = (b - r) / d + 2;break; - case b: - h = (r - g) / d + 4;break; - } - - h /= 6; - } - - return [h, s, l, a]; - } - }, { - key: 'hslToRgb', - value: function hslToRgb(_ref3) { - var _ref4 = slicedToArray(_ref3, 4), - h = _ref4[0], - s = _ref4[1], - l = _ref4[2], - a = _ref4[3]; - - var r = void 0, - g = void 0, - b = void 0; - - if (s === 0) { - r = g = b = l; - } else { - var hue2rgb = function hue2rgb(p, q, t) { - if (t < 0) t += 1; - if (t > 1) t -= 1; - if (t < 1 / 6) return p + (q - p) * 6 * t; - if (t < 1 / 2) return q; - if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6; - return p; - }; - - var q = l < 0.5 ? l * (1 + s) : l + s - l * s, - p = 2 * l - q; - - r = hue2rgb(p, q, h + 1 / 3); - g = hue2rgb(p, q, h); - b = hue2rgb(p, q, h - 1 / 3); - } - - var rgba = [r * 255, g * 255, b * 255].map(Math.round); - rgba[3] = a; - - return rgba; - } - }]); - return Color; - }(); - - var EventBucket = function () { - function EventBucket() { - classCallCheck(this, EventBucket); - - this._events = []; - } - - createClass(EventBucket, [{ - key: 'add', - value: function add(target, type, handler) { - target.addEventListener(type, handler, false); - this._events.push({ - target: target, - type: type, - handler: handler - }); - } - }, { - key: 'remove', - value: function remove(target, type, handler) { - this._events = this._events.filter(function (e) { - var isMatch = true; - if (target && target !== e.target) { - isMatch = false; - } - if (type && type !== e.type) { - isMatch = false; - } - if (handler && handler !== e.handler) { - isMatch = false; - } - - if (isMatch) { - EventBucket._doRemove(e.target, e.type, e.handler); - } - return !isMatch; - }); - } - }, { - key: 'destroy', - value: function destroy() { - this._events.forEach(function (e) { - return EventBucket._doRemove(e.target, e.type, e.handler); - }); - this._events = []; - } - }], [{ - key: '_doRemove', - value: function _doRemove(target, type, handler) { - target.removeEventListener(type, handler, false); - } - }]); - return EventBucket; - }(); - - function parseHTML(htmlString) { - - var div = document.createElement('div'); - div.innerHTML = htmlString; - return div.firstElementChild; - } - - function dragTrack(eventBucket, area, callback) { - var dragging = false; - - function clamp(val, min, max) { - return Math.max(min, Math.min(val, max)); - } - - function onMove(e, info, starting) { - if (starting) { - dragging = true; - } - if (!dragging) { - return; - } - - e.preventDefault(); - - var bounds = area.getBoundingClientRect(), - w = bounds.width, - h = bounds.height, - x = info.clientX, - y = info.clientY; - - var relX = clamp(x - bounds.left, 0, w), - relY = clamp(y - bounds.top, 0, h); - - callback(relX / w, relY / h); - } - - function onMouse(e, starting) { - var button = e.buttons === undefined ? e.which : e.buttons; - if (button === 1) { - onMove(e, e, starting); - } else { - dragging = false; - } - } - - function onTouch(e, starting) { - if (e.touches.length === 1) { - onMove(e, e.touches[0], starting); - } else { - dragging = false; - } - } - - eventBucket.add(area, 'mousedown', function (e) { - onMouse(e, true); - }); - eventBucket.add(area, 'touchstart', function (e) { - onTouch(e, true); - }); - eventBucket.add(window, 'mousemove', onMouse); - eventBucket.add(area, 'touchmove', onTouch); - eventBucket.add(window, 'mouseup', function (e) { - dragging = false; - }); - eventBucket.add(area, 'touchend', function (e) { - dragging = false; - }); - eventBucket.add(area, 'touchcancel', function (e) { - dragging = false; - }); - } - - var BG_TRANSP = 'linear-gradient(45deg, lightgrey 25%, transparent 25%, transparent 75%, lightgrey 75%) 0 0 / 2em 2em,\n linear-gradient(45deg, lightgrey 25%, white 25%, white 75%, lightgrey 75%) 1em 1em / 2em 2em'; - var HUES = 360; - - var EVENT_KEY = 'keydown', - EVENT_CLICK_OUTSIDE = 'mousedown', - EVENT_TAB_MOVE = 'focusin'; - - function $(selector, context) { - return (context || document).querySelector(selector); - } - - function stopEvent(e) { - - e.preventDefault(); - e.stopPropagation(); - } - function onKey(bucket, target, keys, handler, stop) { - bucket.add(target, EVENT_KEY, function (e) { - if (keys.indexOf(e.key) >= 0) { - if (stop) { - stopEvent(e); - } - handler(e); - } - }); - } - - var Picker = function () { - function Picker(options) { - classCallCheck(this, Picker); - - - this.settings = { - - popup: 'right', - layout: 'default', - alpha: true, - editor: true, - editorFormat: 'hex', - cancelButton: false, - defaultColor: '#0cf' - }; - - this._events = new EventBucket(); - - this.onChange = null; - - this.onDone = null; - - this.onOpen = null; - - this.onClose = null; - - this.setOptions(options); - } - - createClass(Picker, [{ - key: 'setOptions', - value: function setOptions(options) { - var _this = this; - - if (!options) { - return; - } - var settings = this.settings; - - function transfer(source, target, skipKeys) { - for (var key in source) { - if (skipKeys && skipKeys.indexOf(key) >= 0) { - continue; - } - - target[key] = source[key]; - } - } - - if (options instanceof HTMLElement) { - settings.parent = options; - } else { - - if (settings.parent && options.parent && settings.parent !== options.parent) { - this._events.remove(settings.parent); - this._popupInited = false; - } - - transfer(options, settings); - - if (options.onChange) { - this.onChange = options.onChange; - } - if (options.onDone) { - this.onDone = options.onDone; - } - if (options.onOpen) { - this.onOpen = options.onOpen; - } - if (options.onClose) { - this.onClose = options.onClose; - } - - var col = options.color || options.colour; - if (col) { - this._setColor(col); - } - } - - var parent = settings.parent; - if (parent && settings.popup && !this._popupInited) { - - var openProxy = function openProxy(e) { - return _this.openHandler(e); - }; - - this._events.add(parent, 'click', openProxy); - - onKey(this._events, parent, [' ', 'Spacebar', 'Enter'], openProxy); - - this._popupInited = true; - } else if (options.parent && !settings.popup) { - this.show(); - } - } - }, { - key: 'openHandler', - value: function openHandler(e) { - if (this.show()) { - - e && e.preventDefault(); - - this.settings.parent.style.pointerEvents = 'none'; - - var toFocus = e && e.type === EVENT_KEY ? this._domEdit : this.domElement; - setTimeout(function () { - return toFocus.focus(); - }, 100); - - if (this.onOpen) { - this.onOpen(this.colour); - } - } - } - }, { - key: 'closeHandler', - value: function closeHandler(e) { - var event = e && e.type; - var doHide = false; - - if (!e) { - doHide = true; - } else if (event === EVENT_CLICK_OUTSIDE || event === EVENT_TAB_MOVE) { - - var knownTime = (this.__containedEvent || 0) + 100; - if (e.timeStamp > knownTime) { - doHide = true; - } - } else { - - stopEvent(e); - - doHide = true; - } - - if (doHide && this.hide()) { - this.settings.parent.style.pointerEvents = ''; - - if (event !== EVENT_CLICK_OUTSIDE) { - this.settings.parent.focus(); - } - - if (this.onClose) { - this.onClose(this.colour); - } - } - } - }, { - key: 'movePopup', - value: function movePopup(options, open) { - - this.closeHandler(); - - this.setOptions(options); - if (open) { - this.openHandler(); - } - } - }, { - key: 'setColor', - value: function setColor(color, silent) { - this._setColor(color, { silent: silent }); - } - }, { - key: '_setColor', - value: function _setColor(color, flags) { - if (typeof color === 'string') { - color = color.trim(); - } - if (!color) { - return; - } - - flags = flags || {}; - var c = void 0; - try { - - c = new Color(color); - } catch (ex) { - if (flags.failSilently) { - return; - } - throw ex; - } - - if (!this.settings.alpha) { - var hsla = c.hsla; - hsla[3] = 1; - c.hsla = hsla; - } - this.colour = this.color = c; - this._setHSLA(null, null, null, null, flags); - } - }, { - key: 'setColour', - value: function setColour(colour, silent) { - this.setColor(colour, silent); - } - }, { - key: 'show', - value: function show() { - var parent = this.settings.parent; - if (!parent) { - return false; - } - - if (this.domElement) { - var toggled = this._toggleDOM(true); - - this._setPosition(); - - return toggled; - } - - var html = this.settings.template || '
'; - var wrapper = parseHTML(html); - - this.domElement = wrapper; - this._domH = $('.picker_hue', wrapper); - this._domSL = $('.picker_sl', wrapper); - this._domA = $('.picker_alpha', wrapper); - this._domEdit = $('.picker_editor input', wrapper); - this._domSample = $('.picker_sample', wrapper); - this._domOkay = $('.picker_done button', wrapper); - this._domCancel = $('.picker_cancel button', wrapper); - - wrapper.classList.add('layout_' + this.settings.layout); - if (!this.settings.alpha) { - wrapper.classList.add('no_alpha'); - } - if (!this.settings.editor) { - wrapper.classList.add('no_editor'); - } - if (!this.settings.cancelButton) { - wrapper.classList.add('no_cancel'); - } - this._ifPopup(function () { - return wrapper.classList.add('popup'); - }); - - this._setPosition(); - - if (this.colour) { - this._updateUI(); - } else { - this._setColor(this.settings.defaultColor); - } - this._bindEvents(); - - return true; - } - }, { - key: 'hide', - value: function hide() { - return this._toggleDOM(false); - } - }, { - key: 'destroy', - value: function destroy() { - this._events.destroy(); - if (this.domElement) { - this.settings.parent.removeChild(this.domElement); - } - } - }, { - key: '_bindEvents', - value: function _bindEvents() { - var _this2 = this; - - var that = this, - dom = this.domElement, - events = this._events; - - function addEvent(target, type, handler) { - events.add(target, type, handler); - } - - addEvent(dom, 'click', function (e) { - return e.preventDefault(); - }); - - dragTrack(events, this._domH, function (x, y) { - return that._setHSLA(x); - }); - - dragTrack(events, this._domSL, function (x, y) { - return that._setHSLA(null, x, 1 - y); - }); - - if (this.settings.alpha) { - dragTrack(events, this._domA, function (x, y) { - return that._setHSLA(null, null, null, 1 - y); - }); - } - - var editInput = this._domEdit; - { - addEvent(editInput, 'input', function (e) { - that._setColor(this.value, { fromEditor: true, failSilently: true }); - }); - - addEvent(editInput, 'focus', function (e) { - var input = this; - - if (input.selectionStart === input.selectionEnd) { - input.select(); - } - }); - } - - this._ifPopup(function () { - - var popupCloseProxy = function popupCloseProxy(e) { - return _this2.closeHandler(e); - }; - - addEvent(window, EVENT_CLICK_OUTSIDE, popupCloseProxy); - addEvent(window, EVENT_TAB_MOVE, popupCloseProxy); - onKey(events, dom, ['Esc', 'Escape'], popupCloseProxy); - - var timeKeeper = function timeKeeper(e) { - _this2.__containedEvent = e.timeStamp; - }; - addEvent(dom, EVENT_CLICK_OUTSIDE, timeKeeper); - - addEvent(dom, EVENT_TAB_MOVE, timeKeeper); - - addEvent(_this2._domCancel, 'click', popupCloseProxy); - }); - - var onDoneProxy = function onDoneProxy(e) { - _this2._ifPopup(function () { - return _this2.closeHandler(e); - }); - if (_this2.onDone) { - _this2.onDone(_this2.colour); - } - }; - addEvent(this._domOkay, 'click', onDoneProxy); - onKey(events, dom, ['Enter'], onDoneProxy); - } - }, { - key: '_setPosition', - value: function _setPosition() { - var parent = this.settings.parent, - elm = this.domElement; - - if (parent !== elm.parentNode) { - parent.appendChild(elm); - } - - this._ifPopup(function (popup) { - - if (getComputedStyle(parent).position === 'static') { - parent.style.position = 'relative'; - } - - var cssClass = popup === true ? 'popup_right' : 'popup_' + popup; - - ['popup_top', 'popup_bottom', 'popup_left', 'popup_right'].forEach(function (c) { - - if (c === cssClass) { - elm.classList.add(c); - } else { - elm.classList.remove(c); - } - }); - - elm.classList.add(cssClass); - }); - } - }, { - key: '_setHSLA', - value: function _setHSLA(h, s, l, a, flags) { - flags = flags || {}; - - var col = this.colour, - hsla = col.hsla; - - [h, s, l, a].forEach(function (x, i) { - if (x || x === 0) { - hsla[i] = x; - } - }); - col.hsla = hsla; - - this._updateUI(flags); - - if (this.onChange && !flags.silent) { - this.onChange(col); - } - } - }, { - key: '_updateUI', - value: function _updateUI(flags) { - if (!this.domElement) { - return; - } - flags = flags || {}; - - var col = this.colour, - hsl = col.hsla, - cssHue = 'hsl(' + hsl[0] * HUES + ', 100%, 50%)', - cssHSL = col.hslString, - cssHSLA = col.hslaString; - - var uiH = this._domH, - uiSL = this._domSL, - uiA = this._domA, - thumbH = $('.picker_selector', uiH), - thumbSL = $('.picker_selector', uiSL), - thumbA = $('.picker_selector', uiA); - - function posX(parent, child, relX) { - child.style.left = relX * 100 + '%'; - } - function posY(parent, child, relY) { - child.style.top = relY * 100 + '%'; - } - - posX(uiH, thumbH, hsl[0]); - - this._domSL.style.backgroundColor = this._domH.style.color = cssHue; - - posX(uiSL, thumbSL, hsl[1]); - posY(uiSL, thumbSL, 1 - hsl[2]); - - uiSL.style.color = cssHSL; - - posY(uiA, thumbA, 1 - hsl[3]); - - var opaque = cssHSL, - transp = opaque.replace('hsl', 'hsla').replace(')', ', 0)'), - bg = 'linear-gradient(' + [opaque, transp] + ')'; - - this._domA.style.background = bg + ', ' + BG_TRANSP; - - if (!flags.fromEditor) { - var format = this.settings.editorFormat, - alpha = this.settings.alpha; - - var value = void 0; - switch (format) { - case 'rgb': - value = col.printRGB(alpha);break; - case 'hsl': - value = col.printHSL(alpha);break; - default: - value = col.printHex(alpha); - } - this._domEdit.value = value; - } - - this._domSample.style.color = cssHSLA; - } - }, { - key: '_ifPopup', - value: function _ifPopup(actionIf, actionElse) { - if (this.settings.parent && this.settings.popup) { - actionIf && actionIf(this.settings.popup); - } else { - actionElse && actionElse(); - } - } - }, { - key: '_toggleDOM', - value: function _toggleDOM(toVisible) { - var dom = this.domElement; - if (!dom) { - return false; - } - - var displayStyle = toVisible ? '' : 'none', - toggle = dom.style.display !== displayStyle; - - if (toggle) { - dom.style.display = displayStyle; - } - return toggle; - } - }]); - return Picker; - }(); - - { - var style = document.createElement('style'); - style.textContent = '.picker_wrapper.no_alpha .picker_alpha{display:none}.picker_wrapper.no_editor .picker_editor{position:absolute;z-index:-1;opacity:0}.picker_wrapper.no_cancel .picker_cancel{display:none}.layout_default.picker_wrapper{display:flex;flex-flow:row wrap;justify-content:space-between;align-items:stretch;font-size:10px;width:25em;padding:.5em}.layout_default.picker_wrapper input,.layout_default.picker_wrapper button{font-size:1rem}.layout_default.picker_wrapper>*{margin:.5em}.layout_default.picker_wrapper::before{content:"";display:block;width:100%;height:0;order:1}.layout_default .picker_slider,.layout_default .picker_selector{padding:1em}.layout_default .picker_hue{width:100%}.layout_default .picker_sl{flex:1 1 auto}.layout_default .picker_sl::before{content:"";display:block;padding-bottom:100%}.layout_default .picker_editor{order:1;width:6.5rem}.layout_default .picker_editor input{width:100%;height:100%}.layout_default .picker_sample{order:1;flex:1 1 auto}.layout_default .picker_done,.layout_default .picker_cancel{order:1}.picker_wrapper{box-sizing:border-box;background:#f2f2f2;box-shadow:0 0 0 1px silver;cursor:default;font-family:sans-serif;color:#444;pointer-events:auto}.picker_wrapper:focus{outline:none}.picker_wrapper button,.picker_wrapper input{box-sizing:border-box;border:none;box-shadow:0 0 0 1px silver;outline:none}.picker_wrapper button:focus,.picker_wrapper button:active,.picker_wrapper input:focus,.picker_wrapper input:active{box-shadow:0 0 2px 1px #1e90ff}.picker_wrapper button{padding:.4em .6em;cursor:pointer;background-color:#f5f5f5;background-image:linear-gradient(0deg, gainsboro, transparent)}.picker_wrapper button:active{background-image:linear-gradient(0deg, transparent, gainsboro)}.picker_wrapper button:hover{background-color:#fff}.picker_selector{position:absolute;z-index:1;display:block;-webkit-transform:translate(-50%, -50%);transform:translate(-50%, -50%);border:2px solid #fff;border-radius:100%;box-shadow:0 0 3px 1px #67b9ff;background:currentColor;cursor:pointer}.picker_slider .picker_selector{border-radius:2px}.picker_hue{position:relative;background-image:linear-gradient(90deg, red, yellow, lime, cyan, blue, magenta, red);box-shadow:0 0 0 1px silver}.picker_sl{position:relative;box-shadow:0 0 0 1px silver;background-image:linear-gradient(180deg, white, rgba(255, 255, 255, 0) 50%),linear-gradient(0deg, black, rgba(0, 0, 0, 0) 50%),linear-gradient(90deg, #808080, rgba(128, 128, 128, 0))}.picker_alpha,.picker_sample{position:relative;background:linear-gradient(45deg, lightgrey 25%, transparent 25%, transparent 75%, lightgrey 75%) 0 0/2em 2em,linear-gradient(45deg, lightgrey 25%, white 25%, white 75%, lightgrey 75%) 1em 1em/2em 2em;box-shadow:0 0 0 1px silver}.picker_alpha .picker_selector,.picker_sample .picker_selector{background:none}.picker_editor input{font-family:monospace;padding:.2em .4em}.picker_sample::before{content:"";position:absolute;display:block;width:100%;height:100%;background:currentColor}.picker_arrow{position:absolute;z-index:-1}.picker_wrapper.popup{position:absolute;z-index:2;margin:1.5em}.picker_wrapper.popup,.picker_wrapper.popup .picker_arrow::before,.picker_wrapper.popup .picker_arrow::after{background:#f2f2f2;box-shadow:0 0 10px 1px rgba(0,0,0,.4)}.picker_wrapper.popup .picker_arrow{width:3em;height:3em;margin:0}.picker_wrapper.popup .picker_arrow::before,.picker_wrapper.popup .picker_arrow::after{content:"";display:block;position:absolute;top:0;left:0;z-index:-99}.picker_wrapper.popup .picker_arrow::before{width:100%;height:100%;-webkit-transform:skew(45deg);transform:skew(45deg);-webkit-transform-origin:0 100%;transform-origin:0 100%}.picker_wrapper.popup .picker_arrow::after{width:150%;height:150%;box-shadow:none}.popup.popup_top{bottom:100%;left:0}.popup.popup_top .picker_arrow{bottom:0;left:0;-webkit-transform:rotate(-90deg);transform:rotate(-90deg)}.popup.popup_bottom{top:100%;left:0}.popup.popup_bottom .picker_arrow{top:0;left:0;-webkit-transform:rotate(90deg) scale(1, -1);transform:rotate(90deg) scale(1, -1)}.popup.popup_left{top:0;right:100%}.popup.popup_left .picker_arrow{top:0;right:0;-webkit-transform:scale(-1, 1);transform:scale(-1, 1)}.popup.popup_right{top:0;left:100%}.popup.popup_right .picker_arrow{top:0;left:0}'; - document.documentElement.firstElementChild.appendChild(style); - - Picker.StyleElement = style; - } - - function getChrColor$1(chr) { - if (chrColorMap$1[chr]) { - return chrColorMap$1[chr]; - } else if (chrColorMap$1["chr" + chr]) { - const color = chrColorMap$1["chr" + chr]; - chrColorMap$1[chr] = color; - return color; - } else { - const color = randomRGB(); - chrColorMap$1[chr] = color; - return color; - } - } - - function randomRGB (min, max) { - - var r = Math.round(Math.random() * 255).toString(10); - var g = Math.round(Math.random() * 255).toString(10); - var b = Math.round(Math.random() * 255).toString(10); - return "rgb(" + r + "," + g + "," + b + ")"; - } - - const chrColorMap$1 = { - "chrX": "rgb(204, 153, 0)", - "chrY": "rgb(153, 204, 0", - "chrUn": "rgb(50, 50, 50)", - "chr1": "rgb(80, 80, 255)", - "chrI": "rgb(139, 155, 187)", - "chr2": "rgb(206, 61, 50)", - "chrII": "rgb(206, 61, 50)", - "chr2a": "rgb(216, 71, 60)", - "chr2b": "rgb(226, 81, 70)", - "chr3": "rgb(116, 155, 88)", - "chrIII": "rgb(116, 155, 88)", - "chr4": "rgb(240, 230, 133)", - "chrIV": "rgb(240, 230, 133)", - "chr5": "rgb(70, 105, 131)", - "chr6": "rgb(186, 99, 56)", - "chr7": "rgb(93, 177, 221)", - "chr8": "rgb(128, 34, 104)", - "chr9": "rgb(107, 215, 107)", - "chr10": "rgb(213, 149, 167)", - "chr11": "rgb(146, 72, 34)", - "chr12": "rgb(131, 123, 141)", - "chr13": "rgb(199, 81, 39)", - "chr14": "rgb(213, 143, 92)", - "chr15": "rgb(122, 101, 165)", - "chr16": "rgb(228, 175, 105)", - "chr17": "rgb(59, 27, 83)", - "chr18": "rgb(205, 222, 183)", - "chr19": "rgb(97, 42, 121)", - "chr20": "rgb(174, 31, 99)", - "chr21": "rgb(231, 199, 111)", - "chr22": "rgb(90, 101, 94)", - "chr23": "rgb(204, 153, 0)", - "chr24": "rgb(153, 204, 0)", - "chr25": "rgb(51, 204, 0)", - "chr26": "rgb(0, 204, 51)", - "chr27": "rgb(0, 204, 153)", - "chr28": "rgb(0, 153, 204)", - "chr29": "rgb(10, 71, 255)", - "chr30": "rgb(71, 117, 255)", - "chr31": "rgb(255, 194, 10)", - "chr32": "rgb(255, 209, 71)", - "chr33": "rgb(153, 0, 51)", - "chr34": "rgb(153, 26, 0)", - "chr35": "rgb(153, 102, 0)", - "chr36": "rgb(128, 153, 0)", - "chr37": "rgb(51, 153, 0)", - "chr38": "rgb(0, 153, 26)", - "chr39": "rgb(0, 153, 102)", - "chr40": "rgb(0, 128, 153)", - "chr41": "rgb(0, 51, 153)", - "chr42": "rgb(26, 0, 153)", - "chr43": "rgb(102, 0, 153)", - "chr44": "rgb(153, 0, 128)", - "chr45": "rgb(214, 0, 71)", - "chr46": "rgb(255, 20, 99)", - "chr47": "rgb(0, 214, 143)", - "chr48": "rgb(20, 255, 177)", - }; - - class ChordSetManager { - - constructor(config) { - this.tracks = []; - this.chordSets = []; - } - - addChordSet(chordSet) { - - // If a chord set with this name exists replace it (same track, same region) - this.chordSets = this.chordSets.filter(g => g.name !== chordSet.name); - this.chordSets.push(chordSet); - - let track = this.tracks.find(t => chordSet.trackName === t.name); - if (track) { - track.chordSets = track.chordSets.filter(cs => cs.name !== chordSet.name); - track.chordSets.push(chordSet); - } - if (!track) { - track = new IGVTrack(chordSet); - this.tracks.push(track); - } - } - - clearChords() { - this.tracks = []; - this.chordSets = []; - } - - getTrack(name) { - return this.tracks.find(t => name === t.name) - } - - getChordSet(name) { - return this.chordSets.find(cs => name === cs.name) - } - - } - - class IGVTrack { - constructor(chordSet) { - this.name = chordSet.trackName; - this.color = chordSet.trackColor; - this.visible = true; - this.chordSets = [chordSet]; - this.id = guid$1(); - } - - get chords() { - if (this.chordSets.length === 1) { - return this.chordSets[0].chords - } - const chords = []; - for (let cs of this.chordSets) { - for (let c of cs.chords) { - chords.push(c); - } - } - return chords - } - } - - - function guid$1() { - return ("0000" + (Math.random() * Math.pow(36, 4) << 0).toString(36)).slice(-4) - } - - const EXP5 = Math.exp(5); - - class CircularView { - - static isInstalled() { - return window["JBrowseReactCircularGenomeView"] !== undefined && window["React"] !== undefined && window["ReactDOM"] !== undefined - } - - /** - * Create a new CircularView - * - * @param parent - * @param config - configuration options - * { - * assembly: {name: string, id: string, chromosomes: [{name: string, bpLength: integer, color: string}] - * onChordClick: function called upon chord click with chord feature as argument - * } - */ - constructor(parent, config) { - - config = config || {}; - this.config = config; - - if (CircularView.isInstalled()) { - - this.parent = parent; - this.groupByTrack = config.groupByTrack === true; - this.chordManager = new ChordSetManager(config); - - // wrapper for toolbar and circular-view container - const wrapper = document.createElement('div'); - wrapper.className = 'igv-circview-container'; - parent.appendChild(wrapper); - - // toolbar - this.createControls(wrapper); - this.resetControlPanel(); - - // circular view container - const element = document.createElement('div'); - element.className = 'igv-circview-circular-genome-view'; - wrapper.appendChild(element); - this.container = element; - - if (config.assembly) { - this.setAssembly(config.assembly); - } - - this.width = config.width || 500; - this.height = config.height || 500; - this.setSize(this.width, this.height); - - } else { - console.error("JBrowse circular view is not installed"); - } - } - - createControls(parent) { - - // toolbar - const toolbarDiv = document.createElement('div'); - toolbarDiv.className = 'igv-circview-toolbar'; - parent.appendChild(toolbarDiv); - this.toolbar = toolbarDiv; - - // control panel - const controlPanelDiv = document.createElement('div'); - controlPanelDiv.className = 'igv-circview-track-panel'; - parent.appendChild(controlPanelDiv); - this.controlPanel = controlPanelDiv; - this.controlPanel.style.display = 'none'; - - - // toolbar button container - Track Options - Clear All - const buttonContainer = document.createElement('div'); - buttonContainer.className = 'igv-circview-toolbar-button-container'; - this.toolbar.appendChild(buttonContainer); - - // Show Controls - this.showControlsButton = document.createElement('div'); - this.showControlsButton.className = 'igv-circview-button'; - buttonContainer.appendChild(this.showControlsButton); - this.showControlsButton.innerText = 'none' === this.controlPanel.style.display ? 'Show Controls' : 'Hide Controls'; - this.showControlsButton.addEventListener('click', (event) => { - const panelRows = this.controlPanel.querySelectorAll('div'); - if (panelRows.length > 0) { - if ('none' === this.controlPanel.style.display) { - this.controlPanel.style.display = 'flex'; - event.target.innerText = 'Hide Controls'; - } else { - this.controlPanel.style.display = 'none'; - event.target.innerText = 'Show Controls'; - } - } - }); - - // Clear All - let button = document.createElement('div'); - button.className = 'igv-circview-button'; - buttonContainer.appendChild(button); - button.innerText = 'Clear All'; - button.addEventListener('click', () => { - this.clearChords(); - }); - - // Close - if (false !== this.config.showCloseButton) { - button = document.createElement('div'); - button.className = 'igv-circview-button'; - buttonContainer.appendChild(button); - button.innerText = 'Close'; - button.addEventListener('click', () => { - this.visible = false; - }); - } - } - - resetControlPanel() { - this.controlPanel.innerHTML = ''; - this.controlPanel.appendChild(this.createGroupByCB()); - const chordSets = this.groupByTrack ? this.chordManager.tracks : this.chordManager.chordSets; - for(let cs of chordSets) { - this.addToControlPanel(cs); - } - } - - createGroupByCB() { - const groupByCB = document.createElement('input'); - groupByCB.type = 'checkbox'; - groupByCB.id = 'groupByCB'; - groupByCB.style.width = '1.4em'; - groupByCB.style.height = '1.4em'; - groupByCB.checked = this.groupByTrack; - - groupByCB.onclick = (evt) => { - this.groupByTrack = evt.target.checked; - this.resetControlPanel(); - this.render(); - }; - - const groupByLabel = document.createElement('label'); - groupByLabel.for = 'groupByCB'; - groupByLabel.innerText = 'Group by track'; - groupByLabel.style.color = 'black'; - groupByLabel.style.paddingLeft = '10px'; - const trackPanelRow = document.createElement('div'); - trackPanelRow.style.width = '100%'; - trackPanelRow.style.paddingTop = '5px'; - trackPanelRow.style.paddingBottom = '5px'; - trackPanelRow.style.background = 'rgb(216, 230, 234)'; - trackPanelRow.appendChild(groupByCB); - trackPanelRow.appendChild(groupByLabel); - return trackPanelRow - } - - addToControlPanel(chordSet) { - - // single track row - container for hide-button | color-picker-swatch | track-name - const row = document.createElement('div'); - this.controlPanel.appendChild(row); - - - // track hide|show - const hideShowButton = document.createElement('div'); - hideShowButton.className = 'igv-circview-button'; - row.appendChild(hideShowButton); - hideShowButton.innerText = true === chordSet.visible ? 'Hide' : 'Show'; - hideShowButton.addEventListener('click', event => { - if (true === chordSet.visible) { - this.hideChordSet(chordSet.name); - event.target.innerText = "Show"; - } else { - this.showChordSet(chordSet.name); - event.target.innerText = "Hide"; - } - }); - - // The alpha range slider. Create this here so we can reference it from the color picker - const alphaSlider = document.createElement('input'); - const valueToAlpha = (value) => Math.exp(value / 200) / EXP5; - const alphaToValue = (alpha) => 200 * Math.log(alpha * EXP5); - - // color - const colorPickerButton = document.createElement('div'); - colorPickerButton.className = 'igv-circview-button'; - colorPickerButton.innerHTML = '    '; // <- important for button to size properly - row.appendChild(colorPickerButton); - colorPickerButton.style.backgroundColor = setAlpha(chordSet.color, 1); - const pickerConfig = - { - parent: colorPickerButton, - popup: 'right', - editorFormat: 'rgb', - color: chordSet.color, - onChange: ({rgbaString}) => { - colorPickerButton.style.backgroundColor = setAlpha(rgbaString, 1); - this.setColor(chordSet.name, rgbaString); - alphaSlider.value = alphaToValue(getAlpha(chordSet.color)); - } - }; - const picker = new Picker(pickerConfig); - - // alpha transparency - alphaSlider.setAttribute('title', 'Adjust transparency of arcs'); - alphaSlider.type = 'range'; - //alphaSlider.className = 'igv-circview-alpha-slider' - alphaSlider.style.width = '100px'; - alphaSlider.style.marginRight = '10px'; - alphaSlider.setAttribute('class', 'range'); - alphaSlider.setAttribute('min', '0'); - alphaSlider.setAttribute('max', '1000'); - alphaSlider.value = alphaToValue(getAlpha(chordSet.color)); - alphaSlider.oninput = () => { - const v = valueToAlpha(alphaSlider.value); - this.setColor(chordSet.name, setAlpha(chordSet.color, v)); - picker.setColor(chordSet.color); - }; - row.appendChild(alphaSlider); - - // track name - const trackNameDive = document.createElement('div'); - trackNameDive.style.color = 'black'; - row.appendChild(trackNameDive); - trackNameDive.innerText = trackNameDive.title = chordSet.name; - - } - - /** - * Reset view with a new set of chromosomes. - * - * @param igvGenome {name: string, id: string, chromosomes: [{name: string, bpLength: integer, color: string} - */ - setAssembly(igvGenome) { - - const id = this.genomeId || guid$3(); - - if (this.genomeId === id) { - return - } - this.chordManager.clearChords(); - this.genomeId = id; - this.chrNames = new Set(igvGenome.chromosomes.map(chr => shortChrName$1(chr.name))); - - const regions = []; - const colors = []; - for (let chr of igvGenome.chromosomes) { - const shortName = shortChrName$1(chr.name); - colors.push(chr.color || getChrColor$1(shortName)); - regions.push( - { - refName: shortName, - uniqueId: shortName, - start: 0, - end: chr.bpLength - } - ); - } - - this.assembly = { - name: igvGenome.name, - sequence: { - trackId: id, - type: 'ReferenceSequenceTrack', - adapter: { - type: 'FromConfigSequenceAdapter', - features: regions, - }, - }, - refNameColors: colors - }; - - this.render(); - - } - - /** - * Append or replace current set of chords to the global set or a specific track. - * - * @param newChords array of chord feature objects. Example: - * [ - * { - * "uniqueId": "chr1:129763372-129763376_chr1:129806775-129806790", - * "color": "rgba(0, 0, 255, 0.1)", - * "refName": "1", - * "start": 129763372, - * "end": 129763376, - * "mate": { - * "refName": "2", - * "start": 129806775, - * "end": 129806790 - * } - * } - * ] - * @param options { - * name: string, // Track name - * color: string, // Track color - * append: boolean // Replace or append chords to current set. Default is append (true) - * } - */ - - addChords(newChords, options = {}) { - - const tmp = options.name || options.track || "*"; - const trackName = tmp.split(' ')[0].replaceAll("%20", " "); - const chordSetName = tmp.replaceAll("%20", " "); - - const chordSet = { - name: chordSetName, - trackName: trackName, - chords: newChords, - color: options.color || "black", - trackColor: options.trackColor || options.color || "black", - visible: true, - id: options.id || guid$3() - }; - - this.chordManager.addChordSet(chordSet); - - this.resetControlPanel(); - - this.render(); - } - - /** - * Set the nominal size of the view in pixels. Size is reduced some aribtrary amount to account for borders and margins - */ - setSize(width, height) { - - height = height || width; - - this.width = width; - this.height = height; - if (this.viewState) { - const view = this.viewState.session.view; - view.setWidth(width); - view.setHeight(height /* this is the height of the area inside the border in pixels */); - view.setBpPerPx(view.minBpPerPx); - } - } - - getSize() { - return Math.min(this.width, this.height) - } - - clearChords() { - //this.tracks = [] - this.chordManager.clearChords(); - this.resetControlPanel(); - this.render(); - } - - clearSelection() { - this.viewState.pluginManager.rootModel.session.clearSelection(); - } - - /** - * Deprecated, use "visible" property - */ - show() { - this.parent.style.display = 'block'; - } - - /** - * Deprecated, use "visible" property - */ - hide() { - this.parent.style.display = 'none'; - } - - get visible() { - return this.parent.style.display !== 'none' - } - - set visible(isVisible) { - this.parent.style.display = isVisible ? 'block' : 'none'; - } - - hideChordSet(trackName) { - let cs = this.getChordSet(trackName); - if (cs) { - cs.visible = false; - this.render(); - } else { - console.warn(`No track with name: ${name}`); - } - } - - showChordSet(name) { - let cs = this.getChordSet(name); - if (cs) { - cs.visible = true; - this.render(); - } else { - console.warn(`No track with name: ${name}`); - } - } - - // showTrack(trackID) { - // let idx = this.tracks.findIndex(t => trackID === t.id) - // if (idx >= 0) { - // const track = this.tracks[idx] - // track.visible = true - // this.tracks.splice(idx, 1) // Change z-order - // this.tracks.push(track) - // this.render() - // } else { - // console.warn(`No track with name: ${name}`) - // } - // } - - // TODO -- remove corresponding row from track panel - deleteTrack(trackID) { - let idx = this.tracks.findIndex(t => trackID === t.name); - if (idx >= 0) { - this.tracks.splice(idx, 1); - } - this.render(); - } - - getChordSet(name) { - return this.groupByTrack ? this.chordManager.getTrack(name) : this.chordManager.getChordSet(name) - } - - setColor(name, color) { - const t = this.getChordSet(name); - if (t) { - t.color = color; - const trackID = t.id; - for (let jbrowseTrack of this.viewState.config.tracks) { - if (trackID === jbrowseTrack.trackId) { - jbrowseTrack.displays[0].renderer.strokeColor.set(color); - break - } - } - } - } - - /** - * The main render function. Render here means build the React DOM. Trying to change react state dynamically - * has been buggy, so we completely rebuild the DOM ("render") on any state change. - */ - render() { - - const { - createViewState, - JBrowseCircularGenomeView, - } = JBrowseReactCircularGenomeView; - - // Remove all children from possible previous renders. React might do this for us when we render, but just in case. - ReactDOM.unmountComponentAtNode(this.container); - - const visibleChordSets = - (this.groupByTrack ? this.chordManager.tracks : this.chordManager.chordSets).filter(t => t.visible); - - const jbrowseTracks = []; - const colors = []; - - for (let chordSet of visibleChordSets) { - - jbrowseTracks.push({ - trackId: chordSet.id, - name: chordSet.name, - assemblyNames: ['forIGV'], - type: 'VariantTrack', - adapter: { - type: 'FromConfigAdapter', - features: chordSet.chords, - } - }); - colors.push(chordSet.color); - } - - this.viewState = createViewState({ - assembly: this.assembly, - tracks: jbrowseTracks, - }); - - // Set view colors - for (let i = 0; i < visibleChordSets.length; i++) { - this.viewState.config.tracks[i].displays[0].renderer.strokeColor.set(colors[i]); - //this.viewState.config.tracks[i].displays[0].renderer.strokeColor.set("jexl:get(feature, 'color') || 'black'"); - //this.viewState.config.tracks[i].displays[0].renderer.strokeColorSelected.set("jexl:get(feature, 'highlightColor') || 'red'"); - } - - this.element = React.createElement(JBrowseCircularGenomeView, {viewState: this.viewState}); - this.setSize(this.width, this.height); - - ReactDOM.render(this.element, this.container); - - const onChordClick = this.config.onChordClick || defaultOnChordClick; - for (let i = 0; i < visibleChordSets.length; i++) { - this.viewState.session.view.showTrack(this.viewState.config.tracks[i].trackId); - if (onChordClick) { - this.viewState.pluginManager.jexl.addFunction('onChordClick', onChordClick); - this.viewState.config.tracks[i].displays[0].onChordClick.set( - 'jexl:onChordClick(feature, track, pluginManager)' - ); - } - } - } - } - - function setAlpha(rgba, alpha) { - const [a, b, c, ignore] = rgba.split(','); // rgba(r g b alpha) - return `${a},${b},${c},${alpha})` - } - - function getAlpha(rgba) { - if (rgba.startsWith("rgba(")) { - return Number(rgba.split(',')[3].replace(')', '')) - } else { - return 1 - } - } - - function shortChrName$1(chrName) { - return chrName.startsWith("chr") ? chrName.substring(3) : chrName - } - - function defaultOnChordClick(feature, chordTrack, pluginManager) { - console.log(feature); - } - - function guid$3() { - return ("0000" + (Math.random() * Math.pow(36, 4) << 0).toString(36)).slice(-4) - } - - function embedCSS$1() { - - const css = '.igv-circview-container {\n width: fit-content;\n height: fit-content;\n box-sizing: content-box;\n color: dimgray;\n font-family: \"Open Sans\", sans-serif;\n font-size: 12px;\n background-color: white;\n border-color: dimgray;\n border-style: solid;\n border-width: thin;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: flex-start;\n}\n\n.igv-circview-toolbar {\n position: relative;\n width: 100%;\n height: 32px;\n background-color: lightgrey;\n border-bottom-style: solid;\n border-bottom-color: dimgray;\n border-bottom-width: thin;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-between;\n align-items: center;\n}\n\n.igv-circview-toolbar-button-container {\n height: 100%;\n width: fit-content;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n}\n.igv-circview-toolbar-button-container > div {\n margin: 4px;\n}\n\n.igv-circview-track-panel {\n z-index: 1024;\n position: absolute;\n top: 33px;\n left: 0;\n width: 100%;\n height: fit-content;\n border-bottom-style: solid;\n border-bottom-color: dimgray;\n border-bottom-width: thin;\n background-color: white;\n display: flex;\n flex-flow: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: flex-start;\n}\n.igv-circview-track-panel > div {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n}\n.igv-circview-track-panel > div > div {\n margin: 4px;\n}\n\n.igv-circview-swatch-button {\n cursor: pointer;\n padding: 5px;\n width: 8px;\n height: 8px;\n border: 1px solid #8d8b8b;\n border-radius: 16px;\n}\n\n.igv-circview-button {\n cursor: pointer;\n padding: 5px;\n color: #444;\n vertical-align: middle;\n text-align: center;\n font-family: \"Open Sans\", sans-serif;\n font-size: 12px;\n border: 1px solid #8d8b8b;\n border-radius: 4px;\n background: #efefef;\n box-shadow: 0 0 5px -1px rgba(0, 0, 0, 0.2);\n}\n\n.igv-circview-button:hover {\n background: #efefef;\n box-shadow: 0 0 5px -1px rgba(0, 0, 0, 0.6);\n}\n\n.igv-circview-button:active {\n color: #007bff;\n box-shadow: 0 0 5px -1px rgba(0, 0, 0, 0.6);\n}\n\n/*# sourceMappingURL=circular-view.css.map */\n'; - - const style = document.createElement('style'); - style.setAttribute('type', 'text/css'); - style.innerHTML = css; - document.head.insertBefore(style, document.head.childNodes[ document.head.childNodes.length - 1 ]); - } - - if(typeof document !== 'undefined') { - - if (!stylesheetExists("circular-view.css")) { - embedCSS$1(); - } - - function stylesheetExists(stylesheetName) { - for (let ss of document.styleSheets) { - ss = ss.href ? ss.href.replace(/^.*[\\\/]/, '') : ''; - if (ss === stylesheetName) { - return true; - } - } - return false; - } - } - - /** - * The minimum length for a VCF structural variant. VCF records < this length are ignored in the circular view - * @type {number} - */ - const MINIMUM_SV_LENGTH = 1000000; - - const shortChrName = (chrName) => { - return chrName.startsWith("chr") ? chrName.substring(3) : chrName - }; - - const makePairedAlignmentChords = (alignments) => { - - const chords = []; - for (let a of alignments) { - - if(a.paired) { - if(a.firstAlignment && a.secondAlignment) { - chords.push({ - uniqueId: a.readName, - refName: shortChrName(a.firstAlignment.chr), - start: a.firstAlignment.start, - end: a.firstAlignment.end, - mate: { - refName: shortChrName(a.secondAlignment.chr), - start: a.secondAlignment.start, - end: a.secondAlignment.end, - } - }); - } - } - else { - const mate = a.mate; - if (mate && mate.chr && mate.position) { - chords.push({ - uniqueId: a.readName, - refName: shortChrName(a.chr), - start: a.start, - end: a.end, - mate: { - refName: shortChrName(mate.chr), - start: mate.position - 1, - end: mate.position, - } - }); - } - } - } - return chords - }; - - const makeSupplementalAlignmentChords = (alignments) => { - - const makeChords = (a) => { - const sa = a.tags()['SA']; - const supAl = createSupplementaryAlignments(sa); - let n = 0; - for (let s of supAl) { - if (s.start !== a.start) { - chords.push({ - uniqueId: `${a.readName}_${n++}`, - refName: shortChrName(a.chr), - start: a.start, - end: a.end, - mate: { - refName: shortChrName(s.chr), - start: s.start, - end: s.start + s.lenOnRef - } - }); - } - } - }; - - const chords = []; - for (let a of alignments) { - if(a.paired) { - makeChords(a.firstAlignment); - if(a.secondAlignment) { - makeChords(a.secondAlignment); - } - } else { - makeChords(a); - } - } - return chords - }; - - const makeBedPEChords = (features) => { - - return features.map(v => { - - // If v is a whole-genome feature, get the true underlying variant. - const f = v._f || v; - - return { - uniqueId: `${f.chr1}:${f.start1}-${f.end1}_${f.chr2}:${f.start2}-${f.end2}`, - refName: shortChrName(f.chr1), - start: f.start1, - end: f.end1, - mate: { - refName: shortChrName(f.chr2), - start: f.start2, - end: f.end2, - } - } - }) - }; - - - const makeVCFChords = (features) => { - - const svFeatures = features.filter(v => { - const f = v._f || v; - const isLargeEnough = f.info && f.info.CHR2 && f.info.END && - (f.info.CHR2 !== f.chr || Math.abs(Number.parseInt(f.info.END) - f.pos) > MINIMUM_SV_LENGTH); - return isLargeEnough - }); - return svFeatures.map(v => { - - // If v is a whole-genome feature, get the true underlying variant. - const f = v._f || v; - - const pos2 = Number.parseInt(f.info.END); - const start2 = pos2 - 100; - const end2 = pos2 + 100; - - return { - uniqueId: `${f.chr}:${f.start}-${f.end}_${f.info.CHR2}:${f.info.END}`, - refName: shortChrName(f.chr), - start: f.start, - end: f.end, - mate: { - refName: shortChrName(f.info.CHR2), - start: start2, - end: end2 - } - } - }) - }; - - function makeCircViewChromosomes(genome) { - const regions = []; - const colors = []; - for (let chrName of genome.wgChromosomeNames) { - const chr = genome.getChromosome(chrName); - colors.push(getChrColor(chr.name)); - regions.push( - { - name: chr.name, - bpLength: chr.bpLength - } - ); - } - return regions - } - - function sendChords(chords, track, refFrame, alpha) { - - const baseColor = track.color || 'rgb(0,0,255)'; - - const chordSetColor = IGVColor.addAlpha("all" === refFrame.chr ? baseColor : getChrColor(refFrame.chr), alpha); - const trackColor = IGVColor.addAlpha(baseColor, alpha); - - // name the chord set to include locus and filtering information - const encodedName = track.name.replaceAll(' ', '%20'); - const chordSetName = "all" === refFrame.chr ? encodedName : - `${encodedName} ${refFrame.chr}:${refFrame.start}-${refFrame.end}`; - track.browser.circularView.addChords(chords, {track: chordSetName, color: chordSetColor, trackColor: trackColor}); - - // show circular view if hidden - if(!track.browser.circularViewVisible) track.browser.circularViewVisible = true; - - } - - - function createCircularView(el, browser) { - - const circularView = new CircularView(el, { - - onChordClick: (feature, chordTrack, pluginManager) => { - - const f1 = feature.data; - const f2 = f1.mate; - addFrameForFeature(f1); - addFrameForFeature(f2); - - function addFrameForFeature(feature) { - - feature.chr = browser.genome.getChromosomeName(feature.refName); - let frameFound = false; - for (let referenceFrame of browser.referenceFrameList) { - const l = Locus.fromLocusString(referenceFrame.getLocusString()); - if (l.contains(feature)) { - frameFound = true; - break - } else if (l.overlaps(feature)) { - referenceFrame.extend(feature); - frameFound = true; - break - } - } - if (!frameFound) { - const flanking = 2000; - const center = (feature.start + feature.end) / 2; - browser.addMultiLocusPanel(feature.chr, center - flanking, center + flanking); - - } - } - } - }); - - return circularView - } - - class PairedEndStats { - - constructor(alignments, {minTLENPercentile, maxTLENPercentile}) { - this.totalCount = 0; - this.frCount = 0; - this.rfCount = 0; - this.ffCount = 0; - this.sumF = 0; - this.sumF2 = 0; - this.lp = minTLENPercentile === undefined ? 0.1 : minTLENPercentile; - this.up = maxTLENPercentile === undefined ? 99.5 : maxTLENPercentile; - this.isizes = []; - this.compute(alignments); - } - - compute(alignments) { - - for (let alignment of alignments) { - if (alignment.isProperPair()) { - var tlen = Math.abs(alignment.fragmentLength); - this.sumF += tlen; - this.sumF2 += tlen * tlen; - this.isizes.push(tlen); - - var po = alignment.pairOrientation; - - if (typeof po === "string" && po.length === 4) { - var tmp = '' + po.charAt(0) + po.charAt(2); - switch (tmp) { - case 'FF': - case 'RR': - this.ffCount++; - break - case "FR": - this.frCount++; - break - case"RF": - this.rfCount++; - } - } - this.totalCount++; - } - } - - if (this.ffCount / this.totalCount > 0.9) this.orienation = "ff"; - else if (this.frCount / this.totalCount > 0.9) this.orienation = "fr"; - else if (this.rfCount / this.totalCount > 0.9) this.orienation = "rf"; - - this.minTLEN = this.lp === 0 ? 0 : percentile(this.isizes, this.lp); - this.maxTLEN = percentile(this.isizes, this.up); - - // var fMean = this.sumF / this.totalCount - // var stdDev = Math.sqrt((this.totalCount * this.sumF2 - this.sumF * this.sumF) / (this.totalCount * this.totalCount)) - // this.minTLEN = fMean - 3 * stdDev - // this.maxTLEN = fMean + 3 * stdDev - - } - } - - function percentile(array, p) { - - if (array.length === 0) return undefined - var k = Math.floor(array.length * (p / 100)); - array.sort(function (a, b) { - return a - b - }); - return array[k] - - } - - const GtexUtils = { - - getTissueInfo: function (datasetId, baseURL) { - datasetId = datasetId || 'gtex_v8'; - baseURL = baseURL || 'https://gtexportal.org/rest/v1'; - let url = baseURL + '/dataset/tissueInfo?datasetId=' + datasetId; - return igvxhr.loadJson(url, {}) - }, - - //https://gtexportal.org/rest/v1/association/singleTissueEqtlByLocation?chromosome=7&start=98358766&end=101523798&tissueName=Liver&datasetId=gtex_v7 - //https://gtexportal.org/rest/v1/association/singleTissueEqtlByLocation?chromosome=7&start=98358766&end=101523798&tissueSiteDetailId=Liver&datasetId=gtex_v8 - trackConfiguration: function (tissueSummary, baseURL) { - baseURL = baseURL || 'https://gtexportal.org/rest/v1'; - return { - type: "eqtl", - sourceType: "gtex-ws", - url: baseURL + '/association/singleTissueEqtlByLocation', - tissueSiteDetailId: tissueSummary.tissueSiteDetailId, - name: (tissueSummary.tissueSiteDetailId.split('_').join(' ')), - visibilityWindow: 250000 - } - } - }; - - /** - * @param feature - * @param bpStart genomic location of the left edge of the current canvas - * @param xScale scale in base-pairs per pixel - * @returns {{px: number, px1: number, pw: number, h: number, py: number}} - */ - function calculateFeatureCoordinates(feature, bpStart, xScale) { - let px = (feature.start - bpStart) / xScale; - let px1 = (feature.end - bpStart) / xScale; - //px = Math.round((feature.start - bpStart) / xScale), - //px1 = Math.round((feature.end - bpStart) / xScale), - let pw = px1 - px; - - if (pw < 3) { - pw = 3; - px -= 1.5; - } - - return { - px: px, - px1: px1, - pw: pw - } - } - - /** - * - * @param feature - * @param bpStart genomic location of the left edge of the current canvas - * @param xScale scale in base-pairs per pixel - * @param pixelHeight pixel height of the current canvas - * @param ctx the canvas 2d context - * @param options genomic state - */ - function renderFeature(feature, bpStart, xScale, pixelHeight, ctx, options) { - - try { - ctx.save(); - - // Set ctx color to a known valid color. If getColorForFeature returns an invalid color string it is ignored, and - // this default will be used. - ctx.fillStyle = this.color; - ctx.strokeStyle = this.color; - - const color = this.getColorForFeature(feature); - ctx.fillStyle = color; - ctx.strokeStyle = color; - - let h; - let py; - if (this.displayMode === "SQUISHED" && feature.row !== undefined) { - h = this.featureHeight / 2; - py = this.margin + this.squishedRowHeight * feature.row; - } else if (this.displayMode === "EXPANDED" && feature.row !== undefined) { - h = this.featureHeight; - py = this.margin + this.expandedRowHeight * feature.row; - } else { // collapsed - h = this.featureHeight; - py = this.margin; - } - - const pixelWidth = options.pixelWidth; // typical 3*viewportWidth - - const cy = py + h / 2; - const h2 = h / 2; - const py2 = cy - h2 / 2; - - const exonCount = feature.exons ? feature.exons.length : 0; - const coord = calculateFeatureCoordinates(feature, bpStart, xScale); - const step = this.arrowSpacing; - const direction = feature.strand === '+' ? 1 : feature.strand === '-' ? -1 : 0; - - if (exonCount === 0) { - // single-exon transcript - const xLeft = Math.max(0, coord.px); - const xRight = Math.min(pixelWidth, coord.px1); - const width = xRight - xLeft; - ctx.fillRect(xLeft, py, width, h); - - // Arrows - // Do not draw if strand is not +/- - if (direction !== 0) { - ctx.fillStyle = "white"; - ctx.strokeStyle = "white"; - for (let x = xLeft + step / 2; x < xRight; x += step) { - // draw arrowheads along central line indicating transcribed orientation - IGVGraphics.strokeLine(ctx, x - direction * 2, cy - 2, x, cy); - IGVGraphics.strokeLine(ctx, x - direction * 2, cy + 2, x, cy); - } - ctx.fillStyle = color; - ctx.strokeStyle = color; - } - } else { - // multi-exon transcript - IGVGraphics.strokeLine(ctx, coord.px + 1, cy, coord.px1 - 1, cy); // center line for introns - - - const xLeft = Math.max(0, coord.px) + step / 2; - const xRight = Math.min(pixelWidth, coord.px1); - for (let x = xLeft; x < xRight; x += step) { - // draw arrowheads along central line indicating transcribed orientation - IGVGraphics.strokeLine(ctx, x - direction * 2, cy - 2, x, cy); - IGVGraphics.strokeLine(ctx, x - direction * 2, cy + 2, x, cy); - } - for (let e = 0; e < exonCount; e++) { - // draw the exons - const exon = feature.exons[e]; - let ePx = Math.round((exon.start - bpStart) / xScale); - let ePx1 = Math.round((exon.end - bpStart) / xScale); - let ePw = Math.max(1, ePx1 - ePx); - let ePxU; - - if (ePx + ePw < 0) { - continue // Off the left edge - } - if (ePx > pixelWidth) { - break // Off the right edge - } - - if (exon.utr) { - ctx.fillRect(ePx, py2, ePw, h2); // Entire exon is UTR - } else { - if (exon.cdStart) { - ePxU = Math.round((exon.cdStart - bpStart) / xScale); - ctx.fillRect(ePx, py2, ePxU - ePx, h2); // start is UTR - ePw -= (ePxU - ePx); - ePx = ePxU; - - } - if (exon.cdEnd) { - ePxU = Math.round((exon.cdEnd - bpStart) / xScale); - ctx.fillRect(ePxU, py2, ePx1 - ePxU, h2); // start is UTR - ePw -= (ePx1 - ePxU); - ePx1 = ePxU; - } - - ePw = Math.max(ePw, 1); - ctx.fillRect(ePx, py, ePw, h); - - // Arrows - if (ePw > step + 5 && direction !== 0) { - ctx.fillStyle = "white"; - ctx.strokeStyle = "white"; - for (let x = ePx + step / 2; x < ePx1; x += step) { - // draw arrowheads along central line indicating transcribed orientation - IGVGraphics.strokeLine(ctx, x - direction * 2, cy - 2, x, cy); - IGVGraphics.strokeLine(ctx, x - direction * 2, cy + 2, x, cy); - } - ctx.fillStyle = color; - ctx.strokeStyle = color; - - } - } - } - } - - if (options.drawLabel && this.displayMode !== "SQUISHED") { - renderFeatureLabel.call(this, ctx, feature, coord.px, coord.px1, py, options.referenceFrame, options); - } - } finally { - ctx.restore(); - } - } - - /** - * @param ctx the canvas 2d context - * @param feature - * @param featureX feature start in pixel coordinates - * @param featureX1 feature end in pixel coordinates - * @param featureY feature y-coordinate - * @param windowX visible window start x-coordinate - * @param windowX1 visible window end x-coordinate - * @param referenceFrame genomic state - * @param options options - */ - function renderFeatureLabel(ctx, feature, featureX, featureX1, featureY, referenceFrame, options) { - - try { - ctx.save(); - - let name = feature.name; - if (name === undefined && feature.gene) name = feature.gene.name; - if (name === undefined) name = feature.id || feature.ID; - if (!name || name === '.') return - - let centerX = (featureX + featureX1) / 2; - - let transform; - if (this.displayMode === "COLLAPSED" && this.labelDisplayMode === "SLANT") { - transform = {rotate: {angle: 45}}; - } - const labelY = getFeatureLabelY(featureY, transform); - - let color = this.getColorForFeature(feature); - let geneColor; - let gtexSelection = false; - if (referenceFrame.selection && GtexUtils.gtexLoaded) { - // TODO -- for gtex, figure out a better way to do this - gtexSelection = true; - geneColor = referenceFrame.selection.colorForGene(name); - } - - const geneFontStyle = { - textAlign: "SLANT" === this.labelDisplayMode ? undefined : 'center', - fillStyle: geneColor || color, - strokeStyle: geneColor || color - }; - - const textBox = ctx.measureText(name); - const xleft = centerX - textBox.width / 2; - const xright = centerX + textBox.width / 2; - const lastLabelX = options.rowLastLabelX[feature.row] || -Number.MAX_SAFE_INTEGER; - if (options.labelAllFeatures || xleft > lastLabelX || gtexSelection) { - options.rowLastLabelX[feature.row] = xright; - - if ('y' === options.axis) { - ctx.save(); - IGVGraphics.labelTransformWithContext(ctx, centerX); - IGVGraphics.fillText(ctx, name, centerX, labelY, geneFontStyle, transform); - ctx.restore(); - } else { - IGVGraphics.fillText(ctx, name, centerX, labelY, geneFontStyle, transform); - } - } - - } finally { - ctx.restore(); - } - } - - function getFeatureLabelY(featureY, transform) { - return transform ? featureY + 20 : featureY + 25 - } - - // SNP constants - - const codingNonSynonSet = new Set(['nonsense', 'missense', 'stop-loss', 'frameshift', 'cds-indel']); - const codingSynonSet = new Set(['coding-synon']); - const spliceSiteSet = new Set(['splice-3', 'splice-5']); - const untranslatedSet = new Set(['untranslated-5', 'untranslated-3']); - - - /** - * Renderer for a UCSC snp track - * - * @param snp - * @param bpStart genomic location of the left edge of the current canvas - * @param xScale scale in base-pairs per pixel - * @param pixelHeight pixel height of the current canvas - * @param ctx the canvas 2d context - */ - function renderSnp(snp, bpStart, xScale, pixelHeight, ctx) { - - var coord = calculateFeatureCoordinates(snp, bpStart, xScale), - py = this.margin, - h, - colorArrLength = this.snpColors.length, - colorPriority; - - h = this.displayMode === "squished" ? this.squishedRowHeight : this.expandedRowHeight; - - switch (this.colorBy) { - case 'function': - colorPriority = colorByFunc(snp.func); - break - case 'class': - colorPriority = colorByClass(snp['class']); - } - - ctx.fillStyle = this.snpColors[colorPriority]; - ctx.fillRect(coord.px, py, coord.pw, h); - - // Coloring functions, convert a value to a priority - - function colorByFunc(theFunc) { - var priorities; - var funcArray = theFunc.split(','); - // possible func values - - - priorities = funcArray.map(function (func) { - if (codingNonSynonSet.has(func) || spliceSiteSet.has(func)) { - return colorArrLength - 1 - } else if (codingSynonSet.has(func)) { - return colorArrLength - 2 - } else if (untranslatedSet.has(func)) { - return colorArrLength - 3 - } else { // locusSet.has(func) || intronSet.has(func) - return 0 - } - }); - - return priorities.reduce(function (a, b) { - return Math.max(a, b) - }) - } - - function colorByClass(cls) { - if (cls === 'deletion') { - return colorArrLength - 1 - } else if (cls === 'mnp') { - return colorArrLength - 2 - } else if (cls === 'microsatellite' || cls === 'named') { - return colorArrLength - 3 - } else { // cls === 'single' || cls === 'in-del' || cls === 'insertion' - return 0 - } - } - } - - /** - * - * @param feature - * @param bpStart genomic location of the left edge of the current canvas - * @param xScale scale in base-pairs per pixel - * @param pixelHeight pixel height of the current canvas - * @param ctx the canvas 2d context - */ - function renderFusionJuncSpan(feature, bpStart, xScale, pixelHeight, ctx) { - - const rowHeight = (this.displayMode === "EXPANDED") ? this.expandedRowHeight : this.squishedRowHeight; - let py = this.margin; - if (this.displayMode !== "COLLAPSED" && feature.row !== undefined) { - py += feature.row * rowHeight; - } - - const cy = py + 0.5 * rowHeight; - const topY = cy - 0.5 * rowHeight; - const bottomY = cy + 0.5 * rowHeight; - - // draw the junction arc - const junctionLeftPx = Math.round((feature.junction_left - bpStart) / xScale); - const junctionRightPx = Math.round((feature.junction_right - bpStart) / xScale); - - ctx.beginPath(); - ctx.moveTo(junctionLeftPx, cy); - ctx.bezierCurveTo(junctionLeftPx, topY, junctionRightPx, topY, junctionRightPx, cy); - - ctx.lineWidth = 1 + Math.log(feature.num_junction_reads) / Math.log(2); - ctx.strokeStyle = 'blue'; - ctx.stroke(); - - // draw the spanning arcs - const spanningCoords = feature.spanning_frag_coords; - for (let i = 0; i < spanningCoords.length; i++) { - - const spanningInfo = spanningCoords[i]; - const spanLeftPx = Math.round((spanningInfo.left - bpStart) / xScale); - const spanRightPx = Math.round((spanningInfo.right - bpStart) / xScale); - - ctx.beginPath(); - ctx.moveTo(spanLeftPx, cy); - ctx.bezierCurveTo(spanLeftPx, bottomY, spanRightPx, bottomY, spanRightPx, cy); - - ctx.lineWidth = 1; - ctx.strokeStyle = 'purple'; - ctx.stroke(); - } - } - - const DEFAULT_COLOR$2 = 'rgb(0, 0, 150)'; - - - class FeatureTrack extends TrackBase { - - static defaults = { - type: "annotation", - maxRows: 1000, // protects against pathological feature packing cases (# of rows of overlapping feaures) - displayMode: "EXPANDED", // COLLAPSED | EXPANDED | SQUISHED - margin: 10, - featureHeight: 14, - autoHeight: false, - useScore: false - } - - - constructor(config, browser) { - super(config, browser); - } - - init(config) { - super.init(config); - - - // Obscure option, not common or supoorted, included for backward compatibility - this.labelDisplayMode = config.labelDisplayMode; - - if (config._featureSource) { - this.featureSource = config._featureSource; - delete config._featureSource; - } else { - this.featureSource = config.featureSource ? - config.featureSource : - FeatureSource(config, this.browser.genome); - } - - if ("FusionJuncSpan" === config.type) { - this.render = config.render || renderFusionJuncSpan; - this.squishedRowHeight = config.squishedRowHeight || 50; - this.expandedRowHeight = config.expandedRowHeight || 50; - this.height = config.height || this.margin + 2 * this.expandedRowHeight; - } else if ('snp' === config.type) { - this.render = config.render || renderSnp; - // colors ordered based on priority least to greatest - this.snpColors = ['rgb(0,0,0)', 'rgb(0,0,255)', 'rgb(0,255,0)', 'rgb(255,0,0)']; - this.colorBy = 'function'; - this.expandedRowHeight = config.expandedRowHeight || 10; - this.squishedRowHeight = config.squishedRowHeight || 5; - this.height = config.height || 30; - } else { - this.render = config.render || renderFeature; - this.arrowSpacing = 30; - // adjust label positions to make sure they're always visible - monitorTrackDrag(this); - this.squishedRowHeight = config.squishedRowHeight || 15; - this.expandedRowHeight = config.expandedRowHeight || 30; - this.height = config.height || this.margin + 2 * this.expandedRowHeight; - - // Set colorBy fields considering legacy options for backward compatibility - if (config.colorBy) { - if (config.colorBy.field) { - config.colorTable = config.colorBy.pallete || config.colorBy.palette; - config.colorBy = config.colorBy.field; - } - this.colorBy = config.colorBy; // Can be undefined => default - if (config.colorTable) { - this.colorTable = new ColorTable(config.colorTable); - } else { - this.colorTable = new PaletteColorTable("Set1"); - } - } - } - } - - async postInit() { - - if (typeof this.featureSource.getHeader === "function") { - this.header = await this.featureSource.getHeader(); - if (this.disposed) return // This track was removed during async load - } - - // Set properties from track line - if (this.header) { - this.setTrackProperties(this.header); - } - - if (this.visibilityWindow === undefined && typeof this.featureSource.defaultVisibilityWindow === 'function') { - this.visibilityWindow = await this.featureSource.defaultVisibilityWindow(); - } - - return this - - } - - get supportsWholeGenome() { - if (this.config.supportsWholeGenome !== undefined) { - return this.config.supportsWholeGenome - } else if (this.featureSource && typeof this.featureSource.supportsWholeGenome === 'function') { - return this.featureSource.supportsWholeGenome() - } else { - if (this.visibilityWindow === undefined && (this.config.indexed === false || !this.config.indexURL)) { - return true - } - } - } - - async getFeatures(chr, start, end, bpPerPixel) { - const visibilityWindow = this.visibilityWindow; - return this.featureSource.getFeatures({chr, start, end, bpPerPixel, visibilityWindow}) - }; - - - /** - * The required height in pixels required for the track content. This is not the visible track height, which - * can be smaller (with a scrollbar) or larger. - * - * @param features - * @returns {*} - */ - computePixelHeight(features) { - - if (this.displayMode === "COLLAPSED") { - return this.margin + this.expandedRowHeight - } else { - let maxRow = 0; - if (features && (typeof features.forEach === "function")) { - for (let feature of features) { - if (feature.row && feature.row > maxRow) { - maxRow = feature.row; - } - } - } - - const height = this.margin + (maxRow + 1) * ("SQUISHED" === this.displayMode ? this.squishedRowHeight : this.expandedRowHeight); - return height - - } - }; - - draw(options) { - - const featureList = options.features; - const ctx = options.context; - const bpPerPixel = options.bpPerPixel; - const bpStart = options.bpStart; - const pixelWidth = options.pixelWidth; - const pixelHeight = options.pixelHeight; - const bpEnd = bpStart + pixelWidth * bpPerPixel + 1; - - - if (!this.config.isMergedTrack) { - IGVGraphics.fillRect(ctx, 0, options.pixelTop, pixelWidth, pixelHeight, {'fillStyle': "rgb(255, 255, 255)"}); - } - - if (featureList) { - - const rowFeatureCount = []; - options.rowLastX = []; - options.rowLastLabelX = []; - for (let feature of featureList) { - if (feature.start > bpStart && feature.end < bpEnd) { - const row = this.displayMode === "COLLAPSED" ? 0 : feature.row || 0; - if (rowFeatureCount[row] === undefined) { - rowFeatureCount[row] = 1; - } else { - rowFeatureCount[row]++; - } - options.rowLastX[row] = -Number.MAX_SAFE_INTEGER; - options.rowLastLabelX[row] = -Number.MAX_SAFE_INTEGER; - } - } - const maxFeatureCount = Math.max(1, Math.max(...rowFeatureCount)); - const pixelsPerFeature = pixelWidth / maxFeatureCount; - - let lastPxEnd = []; - for (let feature of featureList) { - if (feature.end < bpStart) continue - if (feature.start > bpEnd) break - const row = this.displayMode === 'COLLAPSED' ? 0 : feature.row; - options.drawLabel = options.labelAllFeatures || pixelsPerFeature > 10; - const pxEnd = Math.ceil((feature.end - bpStart) / bpPerPixel); - const last = lastPxEnd[row]; - if (!last || pxEnd > last) { - this.render.call(this, feature, bpStart, bpPerPixel, pixelHeight, ctx, options); - - // Ensure a visible gap between features - const pxStart = Math.floor((feature.start - bpStart) / bpPerPixel); - if (last && pxStart - last <= 0) { - ctx.globalAlpha = 0.5; - IGVGraphics.strokeLine(ctx, pxStart, 0, pxStart, pixelHeight, {'strokeStyle': "rgb(255, 255, 255)"}); - ctx.globalAlpha = 1.0; - } - lastPxEnd[row] = pxEnd; - } - } - - } else { - console.log("No feature list"); - } - - }; - - clickedFeatures(clickState) { - - const y = clickState.y - this.margin; - const allFeatures = super.clickedFeatures(clickState); - - let row; - switch (this.displayMode) { - case 'SQUISHED': - row = Math.floor(y / this.squishedRowHeight); - break - case 'EXPANDED': - row = Math.floor(y / this.expandedRowHeight); - break - default: - row = undefined; - } - - return allFeatures.filter(function (feature) { - return (row === undefined || feature.row === undefined || row === feature.row) - }) - } - - /** - * Return "popup data" for feature @ genomic location. Data is an array of key-value pairs - */ - popupData(clickState, features) { - - if (features === undefined) features = this.clickedFeatures(clickState); - const genomicLocation = clickState.genomicLocation; - const data = []; - for (let feature of features) { - - // Whole genome hack, whole-genome psuedo features store the "real" feature in an _f field - const f = feature._f || feature; - - const featureData = (typeof f.popupData === "function") ? - f.popupData(genomicLocation) : - this.extractPopupData(f); - - if (featureData) { - - if (data.length > 0) { - data.push("

"); - } - - // If we have an infoURL, find the name property and create the link. We do this at this level - // to catch name properties in both custom popupData functions and the generic extractPopupData function - - const infoURL = this.infoURL || this.config.infoURL; - for (let fd of featureData) { - data.push(fd); - if (infoURL && - fd.name && - fd.name.toLowerCase() === "name" && - fd.value && - isString$2(fd.value) && - !fd.value.startsWith("<")) { - const href = infoURL.replace("$$", feature.name); - fd.value = `${fd.value}`; - } - } - - - //Array.prototype.push.apply(data, featureData); - - // If we have clicked over an exon number it. - // Disabled for GFF and GTF files if the visibility window is < the feature length since we don't know if we have all exons - const isGFF = "gff" === this.config.format || "gff3" === this.config.format || "gtf" === this.config.format; - if (f.exons) { - for (let i = 0; i < f.exons.length; i++) { - const exon = f.exons[i]; - if (genomicLocation >= exon.start && genomicLocation <= exon.end) { - const exonNumber = isGFF ? - exon.number : - f.strand === "-" ? f.exons.length - i : i + 1; - if (exonNumber) { - data.push('
'); - data.push({name: "Exon Number", value: exonNumber}); - } - break - } - } - } - } - } - - return data - - } - - menuItemList() { - - const menuItems = []; - - if (this.render === renderSnp) { - menuItems.push('
'); - for (let colorScheme of ["function", "class"]) { - menuItems.push({ - object: $$1(createCheckbox$2('Color by ' + colorScheme, colorScheme === this.colorBy)), - click: () => { - this.colorBy = colorScheme; - this.trackView.repaintViews(); - } - }); - } - } - - menuItems.push('
'); - for (let displayMode of ["COLLAPSED", "SQUISHED", "EXPANDED"]) { - const lut = - { - "COLLAPSED": "Collapse", - "SQUISHED": "Squish", - "EXPANDED": "Expand" - }; - - menuItems.push( - { - object: $$1(createCheckbox$2(lut[displayMode], displayMode === this.displayMode)), - click: () => { - this.displayMode = displayMode; - this.config.displayMode = displayMode; - this.trackView.checkContentHeight(); - this.trackView.repaintViews(); - } - }); - } - - return menuItems - - }; - - - contextMenuItemList(clickState) { - - const features = this.clickedFeatures(clickState); - - if (undefined === features || 0 === features.length) { - return undefined - } - - if (features.length > 1) { - features.sort((a, b) => (b.end - b.start) - (a.end - a.start)); - } - const f = features[0]; // The shortest clicked feature - - if ((f.end - f.start) <= 1000000) { - const list = [{ - label: 'View feature sequence', - click: async () => { - let seq = await this.browser.genome.getSequence(f.chr, f.start, f.end); - if (!seq) { - seq = "Unknown sequence"; - } else if (f.strand === '-') { - seq = reverseComplementSequence(seq); - } - this.browser.alert.present(seq); - - } - }]; - - if (isSecureContext() && navigator.clipboard !== undefined) { - list.push( - { - label: 'Copy feature sequence', - click: async () => { - let seq = await this.browser.genome.getSequence(f.chr, f.start, f.end); - if (!seq) { - seq = "Unknown sequence"; - } else if (f.strand === '-') { - seq = reverseComplementSequence(seq); - } - try { - await navigator.clipboard.writeText(seq); - } catch (e) { - console.error(e); - this.browser.alert.present(`error copying sequence to clipboard ${e}`); - } - } - } - ); - } - list.push('
'); - return list - } else { - return undefined - } - } - - description() { - - // if('snp' === this.type) { - if (renderSnp === this.render) { - let desc = "" + this.name + '
'; - desc += 'Color By Function:
'; - desc += 'Red: Coding-Non-Synonymous, Splice Site
'; - desc += 'Green: Coding-Synonymous
'; - desc += 'Blue: Untranslated
'; - desc += 'Black: Intron, Locus, Unknown

'; - desc += 'Color By Class:
'; - desc += 'Red: Deletion
'; - desc += 'Green: MNP
'; - desc += 'Blue: Microsatellite, Named
'; - desc += 'Black: Indel, Insertion, SNP'; - desc += ""; - return desc - } else { - return super.description() - } - - }; - - /** - * Return color for feature. - * @param feature - * @returns {string} - */ - - getColorForFeature(feature) { - - let color; - if (this.altColor && "-" === feature.strand) { - color = (typeof this.altColor === "function") ? this.altColor(feature) : this.altColor; - } else if (this.color) { - color = (typeof this.color === "function") ? this.color(feature) : this.color; // Explicit setting via menu, or possibly track line if !config.color - } else if (this.colorBy) { - const value = feature.getAttributeValue ? - feature.getAttributeValue(this.colorBy) : - feature[this.colorBy]; - color = this.colorTable.getColor(value); - } else if (feature.color) { - color = feature.color; // Explicit color for feature - } - - // If no explicit setting use the default - if (!color) { - color = DEFAULT_COLOR$2; // Track default - } - - if (feature.alpha && feature.alpha !== 1) { - color = IGVColor.addAlpha(color, feature.alpha); - } else if (this.useScore && feature.score && !Number.isNaN(feature.score)) { - // UCSC useScore option, for scores between 0-1000. See https://genome.ucsc.edu/goldenPath/help/customTrack.html#TRACK - const min = this.config.min ? this.config.min : this.viewLimitMin ? this.viewLimitMin : 0; - const max = this.config.max ? this.config.max : this.viewLimitMax ? this.viewLimitMax : 1000; - const alpha = getAlpha(min, max, feature.score); - feature.alpha = alpha; // Avoid computing again - color = IGVColor.addAlpha(color, alpha); - } - - - function getAlpha(min, max, score) { - const binWidth = (max - min) / 9; - const binNumber = Math.floor((score - min) / binWidth); - return Math.min(1.0, 0.2 + (binNumber * 0.8) / 9) - } - - return color - } - - - /** - * Called when the track is removed. Do any needed cleanup here - */ - dispose() { - this.trackView = undefined; - } - } - - /** - * Monitors track drag events, updates label position to ensure that they're always visible. - * @param track - */ - function monitorTrackDrag(track) { - - if (track.browser.on) { - track.browser.on('trackdragend', onDragEnd); - track.browser.on('trackremoved', unSubscribe); - } - - function onDragEnd() { - if (track.trackView && track.displayMode !== "SQUISHED") { - track.trackView.updateViews(); // TODO -- refine this to the viewport that was dragged after DOM refactor - } - } - - function unSubscribe(removedTrack) { - if (track.browser.un && track === removedTrack) { - track.browser.un('trackdragend', onDragEnd); - track.browser.un('trackremoved', unSubscribe); - } - } - - } - - class RegionTableBase { - constructor(config) { - - this.config = config; - - this.browser = config.browser; - - this.columnFormat = config.columnFormat; - - this.tableRowSelectionList = []; - - this.tableDOM = domUtils$1.div({ class: 'igv-roi-table' }); - // if(config.width) { - // let [ w ] = config.width.split('px') - // w = parseInt(w, 10) - // this.tableDOM.style.width = `${Math.min(w, 1600)}px` - // - // } - - config.parent.appendChild(this.tableDOM); - - this.headerDOM = config; - - this.tableColumnTitles = this.tableDOM; - - this.tableRowContainer = this.tableDOM; - - this.footerDOM = config.gotoButtonHandler; - - } - - set headerDOM({ browser, parent, headerTitle, dismissHandler }) { - - // header - const dom = domUtils$1.div(); - this.tableDOM.appendChild(dom); - - // header title - const div = domUtils$1.div(); - dom.appendChild(div); - div.innerHTML = headerTitle; - - // table dismiss button - const dismiss = domUtils$1.div(); - dom.appendChild(dismiss); - dismiss.appendChild(icons$1$1.createIcon('times')); - - this.boundDismissHandler = mouseClickHandler.bind(this); - - dismiss.addEventListener('click', this.boundDismissHandler); - - function mouseClickHandler (event) { - event.stopPropagation(); - dismissHandler(); - } - - const { y:y_root } = browser.root.getBoundingClientRect(); - const { y:y_parent } = parent.getBoundingClientRect(); - const constraint = -(y_parent - y_root); - makeDraggable$1(this.tableDOM, dom, { minX:0, minY:constraint }); - - this.tableDOM.style.display = 'none'; - - this._headerDOM = dom; - - } - - set tableColumnTitles(tableDOM) { - - const tblColumnTitles = domUtils$1.div({ class: 'igv-roi-table-column-titles' }); - tableDOM.appendChild(tblColumnTitles); - - for (const { label, width } of this.columnFormat) { - const col = domUtils$1.div(); - tblColumnTitles.appendChild(col); - col.style.width = width; - col.innerText = label; - } - - this._tableColumnTitlesDOM = tblColumnTitles; - - } - - get tableColumnTitles() { - return this._tableColumnTitlesDOM - } - - set tableRowContainer(container) { - - const tblRowContainer = domUtils$1.div({ class: 'igv-roi-table-row-container' }); - container.appendChild(tblRowContainer); - - this._tableRowContainerDOM = tblRowContainer; - - } - - get tableRowContainer() { - return this._tableRowContainerDOM - } - - set footerDOM(gotoButtonHandler) { - - const dom = domUtils$1.div(); - this.tableDOM.appendChild(dom); - - // Go To Button - const gotoButton = domUtils$1.div({class: 'igv-roi-table-button'}); - dom.appendChild(gotoButton); - - gotoButton.id = 'igv-roi-table-view-button'; - gotoButton.textContent = 'Go To'; - gotoButton.style.pointerEvents = 'none'; - - this._footerDOM = dom; - - this.gotoButton = gotoButton; - - this.boundGotoButtonHandler = gotoButtonHandler.bind(this); - - this.gotoButton.addEventListener('click', this.boundGotoButtonHandler); - - } - - tableRowDOMHelper(dom) { - - dom.addEventListener('mousedown', event => { - event.stopPropagation(); - - dom.classList.toggle('igv-roi-table-row-selected'); - dom.classList.contains('igv-roi-table-row-selected') ? dom.classList.remove('igv-roi-table-row-hover') : dom.classList.add('igv-roi-table-row-hover'); - - this.setTableRowSelectionState(dom.classList.contains('igv-roi-table-row-selected')); - }); - - dom.addEventListener('mouseover', e => { - dom.classList.contains('igv-roi-table-row-selected') ? dom.classList.remove('igv-roi-table-row-hover') : dom.classList.add('igv-roi-table-row-hover'); - }); - - dom.addEventListener('mouseout', e => { - dom.classList.remove('igv-roi-table-row-hover'); - }); - - } - - clearTable() { - const elements = this.tableRowContainer.querySelectorAll('.igv-roi-table-row'); - for (let el of elements) { - el.remove(); - } - } - - setTableRowSelectionState(isTableRowSelected) { - isTableRowSelected ? this.tableRowSelectionList.push(1) : this.tableRowSelectionList.pop(); - this.gotoButton.style.pointerEvents = this.tableRowSelectionList.length > 0 ? 'auto' : 'none'; - } - - present() { - this.tableDOM.style.left = `${ 0 }px`; - - const { y:y_root } = this.browser.root.getBoundingClientRect(); - const { y:y_parent } = this.config.parent.getBoundingClientRect(); - - this.tableDOM.style.top = `${ y_root - y_parent }px`; - this.tableDOM.style.display = 'flex'; - } - - dismiss() { - this.tableDOM.style.display = 'none'; - } - - dispose() { - - this.tableDOM.innerHTML = ''; - this.tableDOM.remove(); - - for (const key of Object.keys(this)) { - this[key] = undefined; - } - - document.removeEventListener('click', this.boundDismissHandler); - - } - - } - - class BlatTable extends RegionTableBase { - - constructor(config) { - - const cooked = Object.assign({ 'width':'1024px' }, config); - super(cooked); - - this.descriptionDOM = config; - - } - - set descriptionDOM(config) { - - if (config.description) { - - let dom; - - // BLAT result for query sequence - dom = domUtils$1.div({ class: 'igv-roi-table-description' }); - this.tableDOM.insertBefore(dom, this.tableColumnTitles); - dom.style.height = 'auto'; - dom.innerHTML = `BLAT result for query sequence:`; - - // CTAATCAtctacactggtttctactg ... - dom = domUtils$1.div({ class: 'igv-roi-table-description' }); - this.tableDOM.insertBefore(dom, this.tableColumnTitles); - dom.style.height = 'auto'; - dom.style.maxHeight = '128px'; - dom.innerHTML = config.description; - - // Select one or more rows ... - dom = domUtils$1.div({ class: 'igv-roi-table-goto-explainer' }); - this.tableDOM.insertBefore(dom, this.tableColumnTitles); - dom.innerHTML = `Select one or more rows and click Go To to view the regions`; - - } - - } - - tableRowDOM(record) { - - const dom = domUtils$1.div({ class: 'igv-roi-table-row' }); - - const pretty = record.map(item => isFinite(item) ? numberFormatter$1(item) : item); - - for (let i = 0; i < pretty.length; i++) { - - const el = domUtils$1.div(); - dom.appendChild(el); - - const format = this.columnFormat[ i ]; - el.style.width = format.width || 'fit-content'; - el.innerText = pretty[ i ]; - } - - this.tableRowDOMHelper(dom); - - return dom - } - - renderTable(records) { - - Array.from(this.tableRowContainer.querySelectorAll('.igv-roi-table-row')).forEach(el => el.remove()); - - if (records.length > 0) { - - for (let record of records) { - const row = this.tableRowDOM(record); - this.tableRowContainer.appendChild(row); - } - - } - - } - - static getColumnFormatConfiguration() { - - /* - return [ - { label: 'chr', width: '60px' }, - { label: 'start', width: '100px' }, - { label: 'end', width: '100px' }, - { label: 'strand', width: '50px' }, - { label: 'score', width: '50px' }, - { label: 'match', width: '50px' }, - { label: "mis-match", width: '70px' }, - { label: "rep. match", width: '70px' }, - { label: "N's", width: '32px' }, - { label: 'Q gap count', width: '90px' }, - { label: 'Q gap bases', width: '90px' }, - { label: 'T gap count', width: '90px' }, - { label: 'T gap bases', width: '90px' }, - ] - */ - - return [ - { label: 'chr', width: '7%' }, - { label: 'start', width: '12%' }, - { label: 'end', width: '12%' }, - { label: 'strand', width: '5%' }, - { label: 'score', width: '5%' }, - { label: 'match', width: '5%' }, - { label: "mis-match", width: '7%' }, - { label: "rep. match", width: '7%' }, - { label: "N's", width: '3%' }, - { label: 'Q gap count', width: '9%' }, - { label: 'Q gap bases', width: '9%' }, - { label: 'T gap count', width: '9%' }, - { label: 'T gap bases', width: '9%' }, - ] - } - - static gotoButtonHandler (event) { - - event.stopPropagation(); - - const selectedRows = this.tableDOM.querySelectorAll('.igv-roi-table-row-selected'); - - const loci = []; - for (const row of selectedRows) { - - const record = []; - row.querySelectorAll('div').forEach(el => record.push(el.innerText)); - - const [ chr, start, end ] = record; - loci.push(`${ chr }:${ start }-${ end }`); - } - - for (const el of this.tableDOM.querySelectorAll('.igv-roi-table-row')) { - el.classList.remove('igv-roi-table-row-selected'); - } - - this.setTableRowSelectionState(false); - - this.browser.search(loci.join(' ')); - - // console.log(`browser search( ${loci.join(' ')} )`) - - } - - } - - /* - http://genome.ucsc.edu/cgi-bin/hgBlat - ?userSeq=CTAATCAtctacactggtttctactgaaatgtctgttgtcatagacttaattgtgtcttcagatacagcagttctgttatttctgagttttacctggggcaagagaatctttagcaagtttaaaggcacctatatctggaatcacccctccctccagatgaatatcacagactctcccattaaaggtcttgccTTCCTTGATAGCATCATCACTCCA - &type=DNA - &db=hg38 - &output=json - */ - - //const blatServer = "https://genome.ucsc.edu/cgi-bin/hgBlat" - const defaultBlatServer = "https://igv.org/services/blatUCSC.php"; - //const blatServer = "http://localhost:8000/blatUCSC.php" - - - async function blat({url, userSeq, db}) { - - url = url || defaultBlatServer; - - const results = await postData(url, userSeq, db); - - results.fields; - - const features = results.blat.map(decodePSL); - - return features - } - - async function postData(url = "", userSeq, db) { - - const data = new URLSearchParams(); - data.append("userSeq", userSeq); - data.append("db", db); - - const response = await fetch(url, { method: "post", body: data }); - return response.json(); // parses JSON response into native JavaScript objects - } - - const maxSequenceSize = 25000; - - class BlatTrack extends FeatureTrack { - - constructor(config, browser) { - super(config, browser); - if (!this.name) { - this.name = 'Blat Results'; - } - this.sequence = config.sequence; - this.table = undefined; - } - - openTableView() { - - if (undefined === this.table) { - - const rows = this.config.features.map(f => [ - f.chr, - (f.start + 1), - f.end, - f.strand, - f.score, - f.matches, - f.misMatches, - f.repMatches, - f.nCount, - f.qNumInsert, - f.qBaseInsert, - f.tNumInsert, - f.tBaseInsert - ]); - - const config = - { - browser: this.browser, - parent: this.browser.parent, - headerTitle: this.config.title, - description: this.sequence, - dismissHandler: () => { - this.table.dismiss(); - this.table.dispose(); - this.table = undefined; - }, - columnFormat: BlatTable.getColumnFormatConfiguration(), - gotoButtonHandler: BlatTable.gotoButtonHandler - }; - - this.table = new BlatTable(config); - this.table.renderTable(rows); - } - - this.table.present(); - - } - - menuItemList() { - - const menuItems = super.menuItemList(); - - menuItems.push('
'); - menuItems.push({ - label: 'Open table view', - click: () => this.openTableView() - }); - return menuItems - } - - - /** - * Track has been permanently removed. Release resources and other cleanup - */ - dispose() { - super.dispose(); - // Release DOM element for table - if (this.table) { - this.table.popover.parentElement.removeChild(this.table.popover); - - } - - - } - } - - - async function createBlatTrack({sequence, browser, name, title}) { - - if (sequence.length > maxSequenceSize) { - browser.alert.present(`Sequence size exceeds maximum allowed length (${sequence.length} > ${maxSequenceSize})`); - return - } - - const db = browser.genome.id; // TODO -- blat specific property - - const url = browser.config["blatServerURL"]; - - try { - - const features = await blat({url, userSeq: sequence, db}); - const trackConfig = { - type: 'blat', - name: name || 'blat results', - title: title || 'blat results', - sequence: sequence, - altColor: 'rgb(176, 176, 236)', - color: 'rgb(236, 176, 176)', - features: features - }; - - const track = await browser.loadTrack(trackConfig); - track.openTableView(); - - } catch (e) { - browser.alert.present(`Error performing blat search: ${e}`); - } - - } - - /* - * The MIT License (MIT) - * - * Copyright (c) 2014 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - const alignmentStartGap = 5; - const downsampleRowHeight = 5; - const DEFAULT_ALIGNMENT_COLOR = "rgb(185, 185, 185)"; - const DEFAULT_COVERAGE_COLOR = "rgb(150, 150, 150)"; - const DEFAULT_CONNECTOR_COLOR = "rgb(200, 200, 200)"; - const MINIMUM_BLAT_LENGTH = 20; - - class BAMTrack extends TrackBase { - - static defaults = { - alleleFreqThreshold: 0.2, - visibilityWindow: 30000, - showCoverage: true, - showAlignments: true, - viewAsPairs: false, - pairsSupported: true, - showSoftClips: false, - showAllBases: false, - showInsertions: true, - showMismatches: true, - height: 300, - coverageTrackHeight: 50 - } - - constructor(config, browser) { - super(config, browser); - } - - init(config) { - - this.type = "alignment"; - this.featureSource = new BamSource(config, this.browser); - this.coverageTrack = new CoverageTrack(config, this); - this.alignmentTrack = new AlignmentTrack(config, this); - - super.init(config); - - this.alignmentTrack.setTop(this.coverageTrack, this.showCoverage); - - if(!this.showAlignments) { - this._height = this.coverageTrackHeight; - } - - // The sort object can be an array in the case of multi-locus view, however if multiple sort positions - // are present for a given reference frame the last one will take precedence - if (config.sort) { - if (Array.isArray(config.sort)) { - // Legacy support - this.assignSort(config.sort[0]); - } else { - this.assignSort(config.sort); - } - } - - } - - set height(h) { - this._height = h; - if (this.showAlignments) { - this.alignmentTrack.height = this.showCoverage ? h - this.coverageTrackHeight : h; - } - } - - get height() { - return this._height - } - - get minTemplateLength() { - const configMinTLEN = this.config.minTLEN !== undefined ? this.config.minTLEN : this.config.minFragmentLength; - return (configMinTLEN !== undefined) ? configMinTLEN : - this._pairedEndStats ? this._pairedEndStats.minTLEN : 0 - } - - get maxTemplateLength() { - const configMaxTLEN = this.config.maxTLEN !== undefined ? this.config.maxTLEN : this.config.maxFragmentLength; - return (configMaxTLEN !== undefined) ? configMaxTLEN : - this._pairedEndStats ? this._pairedEndStats.maxTLEN : 1000 - } - - sort(options) { - options = this.assignSort(options); - - for (let vp of this.trackView.viewports) { - if (vp.containsPosition(options.chr, options.position)) { - const alignmentContainer = vp.cachedFeatures; - if (alignmentContainer) { - alignmentContainer.sortRows(options); - vp.repaint(); - } - } - } - } - - /** - * Fix syntax problems for sort options. - * @param options - */ - assignSort(options) { - // convert old syntax - if (options.locus) { - const range = parseLocusString$1(options.locus); - options.chr = range.chr; - options.position = range.start; - } else { - options.position--; - } - options.direction = options.direction === "ASC" || options.direction === true; - - // chr aliasing - options.chr = this.browser.genome.getChromosomeName(options.chr); - this.sortObject = options; - - return this.sortObject - } - - async getFeatures(chr, bpStart, bpEnd, bpPerPixel, viewport) { - - const alignmentContainer = await this.featureSource.getAlignments(chr, bpStart, bpEnd); - - if (alignmentContainer.paired && !this._pairedEndStats && !this.config.maxFragmentLength) { - const pairedEndStats = new PairedEndStats(alignmentContainer.alignments, this.config); - if (pairedEndStats.totalCount > 99) { - this._pairedEndStats = pairedEndStats; - } - } - alignmentContainer.alignments = undefined; // Don't need to hold onto these anymore - - const sort = this.sortObject; - if (sort) { - if (sort.chr === chr && sort.position >= bpStart && sort.position <= bpEnd) { - alignmentContainer.sortRows(sort); - } - } - - return alignmentContainer - } - - - /** - * Compute the pixel height required to display all content. This is not the same as the viewport height - * (track.height) which might include a scrollbar. - * - * @param alignmentContainer - * @returns {number} - */ - computePixelHeight(alignmentContainer) { - return (this.showCoverage ? this.coverageTrackHeight : 0) + - (this.showAlignments ? this.alignmentTrack.computePixelHeight(alignmentContainer) : 0) - } - - draw(options) { - - IGVGraphics.fillRect(options.context, 0, options.pixelTop, options.pixelWidth, options.pixelHeight, {'fillStyle': "rgb(255, 255, 255)"}); - - if (true === this.showCoverage && this.coverageTrackHeight > 0) { - this.trackView.axisCanvas.style.display = 'block'; - this.coverageTrack.draw(options); - } else { - this.trackView.axisCanvas.style.display = 'none'; - } - - if (true === this.showAlignments) { - this.alignmentTrack.setTop(this.coverageTrack, this.showCoverage); - this.alignmentTrack.draw(options); - } - } - - paintAxis(ctx, pixelWidth, pixelHeight) { - - this.coverageTrack.paintAxis(ctx, pixelWidth, this.coverageTrackHeight); - - // if (this.browser.isMultiLocusMode()) { - // ctx.clearRect(0, 0, pixelWidth, pixelHeight); - // } else { - // this.coverageTrack.paintAxis(ctx, pixelWidth, this.coverageTrackHeight); - // } - } - - contextMenuItemList(config) { - return this.alignmentTrack.contextMenuItemList(config) - } - - popupData(clickState) { - if (true === this.showCoverage && clickState.y >= this.coverageTrack.top && clickState.y < this.coverageTrackHeight) { - return this.coverageTrack.popupData(clickState) - } else { - return this.alignmentTrack.popupData(clickState) - } - } - - /** - * Return the features (alignment, coverage, downsampled interval) clicked on. Needed for "onclick" event. - * @param clickState - * @param features - */ - clickedFeatures(clickState) { - - let clickedObject; - if (true === this.showCoverage && clickState.y >= this.coverageTrack.top && clickState.y < this.coverageTrackHeight) { - clickedObject = this.coverageTrack.getClickedObject(clickState); - } else { - clickedObject = this.alignmentTrack.getClickedObject(clickState); - } - return clickedObject ? [clickedObject] : undefined - } - - hoverText(clickState) { - if (true === this.showCoverage && clickState.y >= this.coverageTrack.top && clickState.y < this.coverageTrackHeight) { - const clickedObject = this.coverageTrack.getClickedObject(clickState); - if (clickedObject) { - return clickedObject.hoverText() - } - } - - } - - menuItemList() { - - - // Start with overage track items - let menuItems = []; - - menuItems = menuItems.concat(MenuUtils$1.numericDataMenuItems(this.trackView)); - - // Color by items - menuItems.push('
'); - const $e = $$1('
'); - $e.text('Color by:'); - menuItems.push({name: undefined, object: $e, click: undefined, init: undefined}); - - const colorByMenuItems = [{key: 'strand', label: 'read strand'}]; - if (this.alignmentTrack.hasPairs) { - colorByMenuItems.push({key: 'firstOfPairStrand', label: 'first-of-pair strand'}); - colorByMenuItems.push({key: 'pairOrientation', label: 'pair orientation'}); - colorByMenuItems.push({key: 'tlen', label: 'insert size (TLEN)'}); - colorByMenuItems.push({key: 'unexpectedPair', label: 'pair orientation & insert size (TLEN)'}); - } - const tagLabel = 'tag' + (this.alignmentTrack.colorByTag ? ' (' + this.alignmentTrack.colorByTag + ')' : ''); - colorByMenuItems.push({key: 'tag', label: tagLabel}); - for (let item of colorByMenuItems) { - const selected = (this.alignmentTrack.colorBy === item.key); - menuItems.push(this.colorByCB(item, selected)); - } - - // Show coverage / alignment options - const adjustTrackHeight = () => { - if (!this.autoHeight) { - const h = - (this.showCoverage ? this.coverageTrackHeight : 0) + - (this.showAlignments ? this.alignmentTrack.height : 0); - this.trackView.setTrackHeight(h); - } - }; - - menuItems.push('
'); - menuItems.push({ - object: $$1(createCheckbox$2("Show Coverage", this.showCoverage)), - click: () => { - this.showCoverage = !this.showCoverage; - adjustTrackHeight(); - this.trackView.checkContentHeight(); - this.trackView.repaintViews(); - } - }); - menuItems.push({ - object: $$1(createCheckbox$2("Show Alignments", this.showAlignments)), - click: () => { - this.showAlignments = !this.showAlignments; - adjustTrackHeight(); - this.trackView.checkContentHeight(); - this.trackView.repaintViews(); - } - }); - - // Show all bases - menuItems.push('
'); - menuItems.push({ - object: $$1(createCheckbox$2("Show all bases", this.showAllBases)), - click: () => { - this.showAllBases = !this.showAllBases; - this.config.showAllBases = this.showAllBases; - this.trackView.repaintViews(); - } - }); - - // Show mismatches - menuItems.push('
'); - menuItems.push({ - object: $$1(createCheckbox$2("Show mismatches", this.showMismatches)), - click: () => { - this.showMismatches = !this.showMismatches; - this.config.showMismatches = this.showMismatches; - this.trackView.repaintViews(); - } - }); - - // Insertions - menuItems.push({ - object: $$1(createCheckbox$2("Show insertions", this.showInsertions)), - click: () => { - this.showInsertions = !this.showInsertions; - this.config.showInsertions = this.showInsertions; - this.getCachedAlignmentContainers(); - this.trackView.repaintViews(); - } - }); - - // Soft clips - menuItems.push({ - object: $$1(createCheckbox$2("Show soft clips", this.showSoftClips)), - click: () => { - this.showSoftClips = !this.showSoftClips; - this.config.showSoftClips = this.showSoftClips; - this.featureSource.setShowSoftClips(this.showSoftClips); - const alignmentContainers = this.getCachedAlignmentContainers(); - for (let ac of alignmentContainers) { - ac.setShowSoftClips(this.showSoftClips); - } - this.trackView.repaintViews(); - } - }); - - // View as pairs - if (this.pairsSupported && this.alignmentTrack.hasPairs) { - menuItems.push('
'); - menuItems.push({ - object: $$1(createCheckbox$2("View as pairs", this.viewAsPairs)), - click: () => { - this.viewAsPairs = !this.viewAsPairs; - this.config.viewAsPairs = this.viewAsPairs; - this.featureSource.setViewAsPairs(this.viewAsPairs); - const alignmentContainers = this.getCachedAlignmentContainers(); - for (let ac of alignmentContainers) { - ac.setViewAsPairs(this.viewAsPairs); - } - this.trackView.repaintViews(); - } - }); - } - - // Add chords to JBrowse circular view, if present - if (this.browser.circularView && - (this.alignmentTrack.hasPairs || this.alignmentTrack.hasSupplemental)) { - menuItems.push('
'); - if (this.alignmentTrack.hasPairs) { - menuItems.push({ - label: 'Add discordant pairs to circular view', - click: () => { - for (let viewport of this.trackView.viewports) { - this.addPairedChordsForViewport(viewport); - } - } - }); - } - if (this.alignmentTrack.hasSupplemental) { - menuItems.push({ - label: 'Add split reads to circular view', - click: () => { - for (let viewport of this.trackView.viewports) { - this.addSplitChordsForViewport(viewport); - } - } - }); - } - } - - - // Display mode - menuItems.push('
'); - const $dml = $$1('
'); - $dml.text('Display mode:'); - menuItems.push({name: undefined, object: $dml, click: undefined, init: undefined}); - - menuItems.push({ - object: $$1(createCheckbox$2("expand", this.alignmentTrack.displayMode === "EXPANDED")), - click: () => { - this.alignmentTrack.displayMode = "EXPANDED"; - this.config.displayMode = "EXPANDED"; - this.trackView.checkContentHeight(); - this.trackView.repaintViews(); - } - }); - - menuItems.push({ - object: $$1(createCheckbox$2("squish", this.alignmentTrack.displayMode === "SQUISHED")), - click: () => { - this.alignmentTrack.displayMode = "SQUISHED"; - this.config.displayMode = "SQUISHED"; - this.trackView.checkContentHeight(); - this.trackView.repaintViews(); - } - }); - - return menuItems - } - - - /** - * Create a "color by" checkbox menu item, optionally initially checked - * @param menuItem - * @param showCheck - * @returns {{init: undefined, name: undefined, click: clickHandler, object: (jQuery|HTMLElement|jQuery.fn.init)}} - */ - colorByCB(menuItem, showCheck) { - const $e = $$1(createCheckbox$2(menuItem.label, showCheck)); - const clickHandler = (ev) => { - - if (menuItem.key !== 'tag') { - if (menuItem.key === this.alignmentTrack.colorBy) { - this.alignmentTrack.colorBy = 'none'; - this.config.colorBy = 'none'; - this.trackView.repaintViews(); - } else { - this.alignmentTrack.colorBy = menuItem.key; - this.config.colorBy = menuItem.key; - this.trackView.repaintViews(); - } - } else { - this.browser.inputDialog.present({ - label: 'Tag Name', - value: this.alignmentTrack.colorByTag ? this.alignmentTrack.colorByTag : '', - callback: (tag) => { - if (tag) { - this.alignmentTrack.colorBy = 'tag'; - this.alignmentTrack.colorByTag = tag; - if (!this.alignmentTrack.tagColors) { - this.alignmentTrack.tagColors = new PaletteColorTable("Set1"); - } - } else { - this.alignmentTrack.colorBy = 'none'; - this.alignmentTrack.colorByTag = ''; - } - this.trackView.repaintViews(); - } - }, ev); - - } - - }; - - return {name: undefined, object: $e, click: clickHandler, init: undefined} - } - - /** - * Return the current state of the track. Used to create sessions and bookmarks. - * - * @returns {*|{}} - */ - getState() { - - const config = super.getState(); - - if (this.sortObject) { - config.sort = { - chr: this.sortObject.chr, - position: this.sortObject.position + 1, - option: this.sortObject.option, - direction: this.sortObject.direction ? "ASC" : "DESC" - }; - } - - return config - } - - getCachedAlignmentContainers() { - return this.trackView.viewports.map(vp => vp.cachedFeatures) - } - - get dataRange() { - return this.coverageTrack.dataRange - } - - set dataRange(dataRange) { - this.coverageTrack.dataRange = dataRange; - } - - get logScale() { - return this.coverageTrack.logScale - } - - set logScale(logScale) { - this.coverageTrack.logScale = logScale; - } - - get autoscale() { - return this.coverageTrack.autoscale - } - - set autoscale(autoscale) { - this.coverageTrack.autoscale = autoscale; - } - - /** - * Add chords to the circular view for the given viewport, represented by its reference frame - * @param refFrame - */ - addPairedChordsForViewport(viewport) { - - const maxTemplateLength = this.maxTemplateLength; - const inView = []; - const refFrame = viewport.referenceFrame; - for (let a of viewport.cachedFeatures.allAlignments()) { - if (a.end >= refFrame.start - && a.start <= refFrame.end) { - if (a.paired) { - if (a.end - a.start > maxTemplateLength) { - inView.push(a); - } - } else { - if (a.mate - && a.mate.chr - && (a.mate.chr !== a.chr || Math.max(a.fragmentLength) > maxTemplateLength)) { - inView.push(a); - } - } - } - } - const chords = makePairedAlignmentChords(inView); - sendChords(chords, this, refFrame, 0.02); - } - - addSplitChordsForViewport(viewport) { - - const inView = []; - const refFrame = viewport.referenceFrame; - for (let a of viewport.cachedFeatures.allAlignments()) { - - const sa = a.hasTag('SA'); - if (a.end >= refFrame.start && a.start <= refFrame.end && sa) { - inView.push(a); - } - } - - const chords = makeSupplementalAlignmentChords(inView); - sendChords(chords, this, refFrame, 0.02); - } - } - - - class CoverageTrack { - - constructor(config, parent) { - this.parent = parent; - this.featureSource = parent.featureSource; - - this.paintAxis = paintAxis; - this.top = 0; - - this.autoscale = config.autoscale || config.max === undefined; - if (!this.autoscale) { - this.dataRange = { - min: config.min || 0, - max: config.max - }; - } - - } - - get height() { - return this.parent.coverageTrackHeight - } - - draw(options) { - - const pixelTop = options.pixelTop; - pixelTop + options.pixelHeight; - const nucleotideColors = this.parent.browser.nucleotideColors; - - if (pixelTop > this.height) { - return //scrolled out of view - } - - const ctx = options.context; - const alignmentContainer = options.features; - const coverageMap = alignmentContainer.coverageMap; - - let sequence; - if (coverageMap.refSeq) { - sequence = coverageMap.refSeq.toUpperCase(); - } - - const bpPerPixel = options.bpPerPixel; - const bpStart = options.bpStart; - const pixelWidth = options.pixelWidth; - const bpEnd = bpStart + pixelWidth * bpPerPixel + 1; - - // paint for all coverage buckets - // If alignment track color is != default, use it - let color; - if (this.parent.coverageColor) { - color = this.parent.coverageColor; - } else if (this.parent.color && typeof this.parent.color !== "function") { - color = IGVColor.darkenLighten(this.parent.color, -35); - } else { - color = DEFAULT_COVERAGE_COLOR; - } - IGVGraphics.setProperties(ctx, { - fillStyle: color, - strokeStyle: color - }); - - const w = Math.max(1, Math.ceil(1.0 / bpPerPixel)); - for (let i = 0, len = coverageMap.coverage.length; i < len; i++) { - - const bp = (coverageMap.bpStart + i); - if (bp < bpStart) continue - if (bp > bpEnd) break - - const item = coverageMap.coverage[i]; - if (!item) continue - - const h = Math.round((item.total / this.dataRange.max) * this.height); - const y = this.height - h; - const x = Math.floor((bp - bpStart) / bpPerPixel); - - - // IGVGraphics.setProperties(ctx, {fillStyle: "rgba(0, 200, 0, 0.25)", strokeStyle: "rgba(0, 200, 0, 0.25)" }); - IGVGraphics.fillRect(ctx, x, y, w, h); - } - - // coverage mismatch coloring -- don't try to do this in above loop, color bar will be overwritten when w<1 - if (sequence) { - for (let i = 0, len = coverageMap.coverage.length; i < len; i++) { - - const bp = (coverageMap.bpStart + i); - if (bp < bpStart) continue - if (bp > bpEnd) break - - const item = coverageMap.coverage[i]; - if (!item) continue - - const h = (item.total / this.dataRange.max) * this.height; - let y = this.height - h; - const x = Math.floor((bp - bpStart) / bpPerPixel); - - const refBase = sequence[i]; - if (item.isMismatch(refBase)) { - IGVGraphics.setProperties(ctx, {fillStyle: nucleotideColors[refBase]}); - IGVGraphics.fillRect(ctx, x, y, w, h); - - let accumulatedHeight = 0.0; - for (let nucleotide of ["A", "C", "T", "G"]) { - - const count = item["pos" + nucleotide] + item["neg" + nucleotide]; - - // non-logoritmic - const hh = (count / this.dataRange.max) * this.height; - y = (this.height - hh) - accumulatedHeight; - accumulatedHeight += hh; - IGVGraphics.setProperties(ctx, {fillStyle: nucleotideColors[nucleotide]}); - IGVGraphics.fillRect(ctx, x, y, w, hh); - } - } - } - } - } - - getClickedObject(clickState) { - - let features = clickState.viewport.cachedFeatures; - if (!features || features.length === 0) return - - const genomicLocation = Math.floor(clickState.genomicLocation); - const coverageMap = features.coverageMap; - const coverageMapIndex = Math.floor(genomicLocation - coverageMap.bpStart); - return coverageMap.coverage[coverageMapIndex] - } - - popupData(clickState) { - - const nameValues = []; - - const coverage = this.getClickedObject(clickState); - if (coverage) { - const genomicLocation = Math.floor(clickState.genomicLocation); - const referenceFrame = clickState.viewport.referenceFrame; - - nameValues.push(referenceFrame.chr + ":" + numberFormatter$1(1 + genomicLocation)); - - nameValues.push({name: 'Total Count', value: coverage.total}); - - // A - let tmp = coverage.posA + coverage.negA; - if (tmp > 0) tmp = tmp.toString() + " (" + Math.round((tmp / coverage.total) * 100.0) + "%, " + coverage.posA + "+, " + coverage.negA + "- )"; - nameValues.push({name: 'A', value: tmp}); - - // C - tmp = coverage.posC + coverage.negC; - if (tmp > 0) tmp = tmp.toString() + " (" + Math.round((tmp / coverage.total) * 100.0) + "%, " + coverage.posC + "+, " + coverage.negC + "- )"; - nameValues.push({name: 'C', value: tmp}); - - // G - tmp = coverage.posG + coverage.negG; - if (tmp > 0) tmp = tmp.toString() + " (" + Math.round((tmp / coverage.total) * 100.0) + "%, " + coverage.posG + "+, " + coverage.negG + "- )"; - nameValues.push({name: 'G', value: tmp}); - - // T - tmp = coverage.posT + coverage.negT; - if (tmp > 0) tmp = tmp.toString() + " (" + Math.round((tmp / coverage.total) * 100.0) + "%, " + coverage.posT + "+, " + coverage.negT + "- )"; - nameValues.push({name: 'T', value: tmp}); - - // N - tmp = coverage.posN + coverage.negN; - if (tmp > 0) tmp = tmp.toString() + " (" + Math.round((tmp / coverage.total) * 100.0) + "%, " + coverage.posN + "+, " + coverage.negN + "- )"; - nameValues.push({name: 'N', value: tmp}); - - nameValues.push('
'); - nameValues.push({name: 'DEL', value: coverage.del.toString()}); - nameValues.push({name: 'INS', value: coverage.ins.toString()}); - } - - return nameValues - - } - - } - - class AlignmentTrack { - - constructor(config, parent) { - - this.parent = parent; - this.browser = parent.browser; - this.featureSource = parent.featureSource; - this.top = 0 === config.coverageTrackHeight ? 0 : config.coverageTrackHeight + 5; - this.displayMode = config.displayMode || "EXPANDED"; - this.alignmentRowHeight = config.alignmentRowHeight || 14; - this.squishedRowHeight = config.squishedRowHeight || 3; - - this.negStrandColor = config.negStrandColor || "rgba(150, 150, 230, 0.75)"; - this.posStrandColor = config.posStrandColor || "rgba(230, 150, 150, 0.75)"; - this.insertionColor = config.insertionColor || "rgb(138, 94, 161)"; - this.insertionTextColor = config.insertionTextColor || "white"; - this.showInsertionText = config.showInsertionText === undefined ? false : !!config.showInsertionText; - this.deletionColor = config.deletionColor || "black"; - this.deletionTextColor = config.deletionTextColor || "black"; - this.showDeletionText = config.showDeletionText === undefined ? false : !!config.showDeletionText; - this.skippedColor = config.skippedColor || "rgb(150, 170, 170)"; - this.pairConnectorColor = config.pairConnectorColor; - - this.smallTLENColor = config.smallTLENColor || config.smallFragmentLengthColor || "rgb(0, 0, 150)"; - this.largeTLENColor = config.largeTLENColor || config.largeFragmentLengthColor || "rgb(200, 0, 0)"; - - this.pairOrientation = config.pairOrienation || 'fr'; - this.pairColors = {}; - this.pairColors["RL"] = config.rlColor || "rgb(0, 150, 0)"; - this.pairColors["RR"] = config.rrColor || "rgb(20, 50, 200)"; - this.pairColors["LL"] = config.llColor || "rgb(0, 150, 150)"; - - this.colorBy = config.colorBy || "unexpectedPair"; - this.colorByTag = config.colorByTag ? config.colorByTag.toUpperCase() : undefined; - this.bamColorTag = config.bamColorTag === undefined ? "YC" : config.bamColorTag; - - this.hideSmallIndels = config.hideSmallIndels; - this.indelSizeThreshold = config.indelSizeThreshold || 1; - - this.hasPairs = false; // Until proven otherwise - this.hasSupplemental = false; - } - - setTop(coverageTrack, showCoverage) { - this.top = (0 === coverageTrack.height || false === showCoverage) ? 0 : (5 + coverageTrack.height); - } - - /** - * Compute the pixel height required to display all content. - * - * @param alignmentContainer - * @returns {number|*} - */ - computePixelHeight(alignmentContainer) { - - if (alignmentContainer.packedAlignmentRows) { - const h = alignmentContainer.hasDownsampledIntervals() ? downsampleRowHeight + alignmentStartGap : 0; - const alignmentRowHeight = this.displayMode === "SQUISHED" ? - this.squishedRowHeight : - this.alignmentRowHeight; - return h + (alignmentRowHeight * alignmentContainer.packedAlignmentRows.length) + 5 - } else { - return 0 - } - } - - draw(options) { - - const alignmentContainer = options.features; - const ctx = options.context; - const bpPerPixel = options.bpPerPixel; - const bpStart = options.bpStart; - const pixelWidth = options.pixelWidth; - const bpEnd = bpStart + pixelWidth * bpPerPixel + 1; - const showSoftClips = this.parent.showSoftClips; - const showAllBases = this.parent.showAllBases; - const nucleotideColors = this.browser.nucleotideColors; - - //alignmentContainer.repack(bpPerPixel, showSoftClips); - const packedAlignmentRows = alignmentContainer.packedAlignmentRows; - - - ctx.save(); - - let referenceSequence = alignmentContainer.sequence; - if (referenceSequence) { - referenceSequence = referenceSequence.toUpperCase(); - } - let alignmentRowYInset = 0; - - let pixelTop = options.pixelTop; - if (this.top) { - ctx.translate(0, this.top); - } - const pixelBottom = pixelTop + options.pixelHeight; - - if (alignmentContainer.hasDownsampledIntervals()) { - alignmentRowYInset = downsampleRowHeight + alignmentStartGap; - - alignmentContainer.downsampledIntervals.forEach(function (interval) { - var xBlockStart = (interval.start - bpStart) / bpPerPixel, - xBlockEnd = (interval.end - bpStart) / bpPerPixel; - - if (xBlockEnd - xBlockStart > 5) { - xBlockStart += 1; - xBlockEnd -= 1; - } - IGVGraphics.fillRect(ctx, xBlockStart, 2, (xBlockEnd - xBlockStart), downsampleRowHeight - 2, {fillStyle: "black"}); - }); - - } else { - alignmentRowYInset = 0; - } - - // Transient variable -- rewritten on every draw, used for click object selection - this.alignmentsYOffset = alignmentRowYInset; - const alignmentRowHeight = this.displayMode === "SQUISHED" ? - this.squishedRowHeight : - this.alignmentRowHeight; - - if (packedAlignmentRows) { - - const nRows = packedAlignmentRows.length; - - for (let rowIndex = 0; rowIndex < nRows; rowIndex++) { - - const alignmentRow = packedAlignmentRows[rowIndex]; - const alignmentY = alignmentRowYInset + (alignmentRowHeight * rowIndex); - const alignmentHeight = alignmentRowHeight <= 4 ? alignmentRowHeight : alignmentRowHeight - 2; - - if (alignmentY > pixelBottom) { - break - } else if (alignmentY + alignmentHeight < pixelTop) { - continue - } - - for (let alignment of alignmentRow.alignments) { - - this.hasPairs = this.hasPairs || alignment.isPaired(); - if (this.browser.circularView) { - // This is an expensive check, only do it if needed - this.hasSupplemental = this.hasSupplemental || alignment.hasTag('SA'); - } - - if ((alignment.start + alignment.lengthOnRef) < bpStart) continue - if (alignment.start > bpEnd) break - if (true === alignment.hidden) { - continue - } - - if (alignment instanceof PairedAlignment) { - - drawPairConnector.call(this, alignment, alignmentY, alignmentHeight); - - drawSingleAlignment.call(this, alignment.firstAlignment, alignmentY, alignmentHeight); - - if (alignment.secondAlignment) { - drawSingleAlignment.call(this, alignment.secondAlignment, alignmentY, alignmentHeight); - } - - } else { - drawSingleAlignment.call(this, alignment, alignmentY, alignmentHeight); - } - - } - } - } - ctx.restore(); - - // alignment is a PairedAlignment - function drawPairConnector(alignment, yRect, alignmentHeight) { - - var connectorColor = this.getConnectorColor(alignment.firstAlignment), - xBlockStart = (alignment.connectingStart - bpStart) / bpPerPixel, - xBlockEnd = (alignment.connectingEnd - bpStart) / bpPerPixel, - yStrokedLine = yRect + alignmentHeight / 2; - - if ((alignment.connectingEnd) < bpStart || alignment.connectingStart > bpEnd) { - return - } - if (alignment.mq <= 0) { - connectorColor = IGVColor.addAlpha(connectorColor, 0.15); - } - IGVGraphics.setProperties(ctx, {fillStyle: connectorColor, strokeStyle: connectorColor}); - IGVGraphics.strokeLine(ctx, xBlockStart, yStrokedLine, xBlockEnd, yStrokedLine); - - } - - function drawSingleAlignment(alignment, yRect, alignmentHeight) { - - - if ((alignment.start + alignment.lengthOnRef) < bpStart || alignment.start > bpEnd) { - return - } - - const blocks = showSoftClips ? alignment.blocks : alignment.blocks.filter(b => 'S' !== b.type); - - let alignmentColor = this.getAlignmentColor(alignment); - const outlineColor = alignmentColor; - if (alignment.mq <= 0) { - alignmentColor = IGVColor.addAlpha(alignmentColor, 0.15); - } - IGVGraphics.setProperties(ctx, {fillStyle: alignmentColor, strokeStyle: outlineColor}); - - // Save bases to draw into an array for later drawing, so they can be overlaid on insertion blocks, - // which is relevant if we have insertions with size label - const basesToDraw = []; - - for (let b = 0; b < blocks.length; b++) { // Can't use forEach here -- we need ability to break - - const block = blocks[b]; - - // Somewhat complex test, neccessary to insure gaps are drawn. - // If this is not the last block, and the next block starts before the orign (off screen to left) then skip. - if ((b !== blocks.length - 1) && blocks[b + 1].start < bpStart) continue - - // drawBlock returns bases to draw, which are drawn on top of insertion blocks (if they're wider than - // the space between two bases) like in Java IGV - basesToDraw.push(...drawBlock.call(this, block, b)); - - if ((block.start + block.len) > bpEnd) { - // Do this after drawBlock to insure gaps are drawn - break - } - } - - if (alignment.gaps) { - const yStrokedLine = yRect + alignmentHeight / 2; - for (let gap of alignment.gaps) { - const sPixel = (gap.start - bpStart) / bpPerPixel; - const ePixel = ((gap.start + gap.len) - bpStart) / bpPerPixel; - const lineWidth = ePixel - sPixel; - const gapLenText = gap.len.toString(); - const gapTextWidth = gapLenText.length * 6; - const gapCenter = sPixel + (lineWidth / 2); - - const color = ("D" === gap.type) ? this.deletionColor : this.skippedColor; - - IGVGraphics.strokeLine(ctx, sPixel, yStrokedLine, ePixel, yStrokedLine, { - strokeStyle: color, - lineWidth: 2, - }); - - // Add gap width as text like Java IGV if it fits nicely and is a multi-base gap - if (this.showDeletionText && gap.len > 1 && lineWidth >= gapTextWidth + 8) { - const textStart = gapCenter - (gapTextWidth / 2); - IGVGraphics.fillRect(ctx, textStart - 1, yRect - 1, gapTextWidth + 2, 12, {fillStyle: "white"}); - IGVGraphics.fillText(ctx, gapLenText, textStart, yRect + 10, { - 'font': 'normal 10px monospace', - 'fillStyle': this.deletionTextColor, - }); - } - } - } - - if (alignment.insertions && this.parent.showInsertions) { - let lastXBlockStart = -1; - for (let insertionBlock of alignment.insertions) { - if (this.hideSmallIndels && insertionBlock.len <= this.indelSizeThreshold) { - continue - } - if (insertionBlock.start < bpStart) { - continue - } - if (insertionBlock.start > bpEnd) { - break - } - - const refOffset = insertionBlock.start - bpStart; - const insertLenText = insertionBlock.len.toString(); - - const textPixelWidth = 2 + (insertLenText.length * 6); - const basePixelWidth = (!this.showInsertionText || insertionBlock.len === 1) - ? 2 - : Math.round(insertionBlock.len / bpPerPixel); - const widthBlock = Math.max(Math.min(textPixelWidth, basePixelWidth), 2); - - const xBlockStart = (refOffset / bpPerPixel) - (widthBlock / 2); - if ((xBlockStart - lastXBlockStart) > 2) { - const props = {fillStyle: this.insertionColor}; - - // Draw decorations like Java IGV to make an 'I' shape - IGVGraphics.fillRect(ctx, xBlockStart - 2, yRect, widthBlock + 4, 2, props); - IGVGraphics.fillRect(ctx, xBlockStart, yRect + 2, widthBlock, alignmentHeight - 4, props); - IGVGraphics.fillRect(ctx, xBlockStart - 2, yRect + alignmentHeight - 2, widthBlock + 4, 2, props); - - // Show # of inserted bases as text if it's a multi-base insertion and the insertion block - // is wide enough to hold text (its size is capped at the text label size, but can be smaller - // if the browser is zoomed out and the insertion is small) - if (this.showInsertionText && insertionBlock.len > 1 && basePixelWidth > textPixelWidth) { - IGVGraphics.fillText(ctx, insertLenText, xBlockStart + 1, yRect + 10, { - 'font': 'normal 10px monospace', - 'fillStyle': this.insertionTextColor, - }); - } - lastXBlockStart = xBlockStart; - } - } - } - - basesToDraw.forEach(({bbox, baseColor, readChar}) => { - renderBlockOrReadChar(ctx, bpPerPixel, bbox, baseColor, readChar); - }); - - - function drawBlock(block, b) { - // Collect bases to draw for later rendering - const blockBasesToDraw = []; - - const offsetBP = block.start - alignmentContainer.start; - const blockStartPixel = (block.start - bpStart) / bpPerPixel; - const blockEndPixel = ((block.start + block.len) - bpStart) / bpPerPixel; - const blockWidthPixel = Math.max(1, blockEndPixel - blockStartPixel); - - //const arrowHeadWidthPixel = alignmentRowHeight / 2.0; - const nomPixelWidthOnRef = 100 / bpPerPixel; - const arrowHeadWidthPixel = Math.min(alignmentRowHeight / 2.0, nomPixelWidthOnRef / 6); - - const isSoftClip = 'S' === block.type; - - const strokeOutline = - alignment.mq <= 0 || - this.highlightedAlignmentReadNamed === alignment.readName || - isSoftClip; - - let blockOutlineColor = outlineColor; - if (this.highlightedAlignmentReadNamed === alignment.readName) blockOutlineColor = 'red'; - else if (isSoftClip) blockOutlineColor = 'rgb(50,50,50)'; - - const lastBlockPositiveStrand = (true === alignment.strand && b === blocks.length - 1); - const lastBlockReverseStrand = (false === alignment.strand && b === 0); - const lastBlock = lastBlockPositiveStrand | lastBlockReverseStrand; - - if (lastBlock) { - let xListPixel; - let yListPixel; - if (lastBlockPositiveStrand) { - xListPixel = [ - blockStartPixel, - blockEndPixel, - blockEndPixel + arrowHeadWidthPixel, - blockEndPixel, - blockStartPixel, - blockStartPixel]; - yListPixel = [ - yRect, - yRect, - yRect + (alignmentHeight / 2.0), - yRect + alignmentHeight, - yRect + alignmentHeight, - yRect]; - - } - - // Last block on - strand ? - else if (lastBlockReverseStrand) { - xListPixel = [ - blockEndPixel, - blockStartPixel, - blockStartPixel - arrowHeadWidthPixel, - blockStartPixel, - blockEndPixel, - blockEndPixel]; - yListPixel = [ - yRect, - yRect, - yRect + (alignmentHeight / 2.0), - yRect + alignmentHeight, - yRect + alignmentHeight, - yRect]; - - } - IGVGraphics.fillPolygon(ctx, xListPixel, yListPixel, {fillStyle: alignmentColor}); - - if (strokeOutline) { - IGVGraphics.strokePolygon(ctx, xListPixel, yListPixel, {strokeStyle: blockOutlineColor}); - } - } - - // Internal block - else { - IGVGraphics.fillRect(ctx, blockStartPixel, yRect, blockWidthPixel, alignmentHeight, {fillStyle: alignmentColor}); - - if (strokeOutline) { - ctx.save(); - ctx.strokeStyle = blockOutlineColor; - ctx.strokeRect(blockStartPixel, yRect, blockWidthPixel, alignmentHeight); - ctx.restore(); - } - } - - - // Read base coloring - - if (isSoftClip || - showAllBases || - this.parent.showMismatches && (referenceSequence && alignment.seq && alignment.seq !== "*")) { - - const seq = alignment.seq ? alignment.seq.toUpperCase() : undefined; - const qual = alignment.qual; - const seqOffset = block.seqOffset; - const widthPixel = Math.max(1, 1 / bpPerPixel); - - - for (let i = 0, len = block.len; i < len; i++) { - - const xPixel = ((block.start + i) - bpStart) / bpPerPixel; - - if (xPixel + widthPixel < 0) continue // Off left edge - if (xPixel > pixelWidth) break // Off right edge - - let readChar = seq ? seq.charAt(seqOffset + i) : ''; - const refChar = offsetBP + i >= 0 ? referenceSequence.charAt(offsetBP + i) : ''; - - if (readChar === "=") { - readChar = refChar; - } - if (readChar === "X" || refChar !== readChar || isSoftClip || showAllBases) { - - let baseColor; - if (!isSoftClip && qual !== undefined && qual.length > seqOffset + i) { - const readQual = qual[seqOffset + i]; - baseColor = shadedBaseColor(readQual, nucleotideColors[readChar]); - } else { - baseColor = nucleotideColors[readChar]; - } - if (baseColor) { - blockBasesToDraw.push({ - bbox: { - x: xPixel, - y: yRect, - width: widthPixel, - height: alignmentHeight - }, - baseColor, - readChar, - }); - } - } - } - } - - return blockBasesToDraw - } - - function renderBlockOrReadChar(context, bpp, bbox, color, char) { - var threshold, - center; - - threshold = 1.0 / 10.0; - if (bpp <= threshold && bbox.height >= 8) { - - // render letter - const fontHeight = Math.min(10, bbox.height); - context.font = '' + fontHeight + 'px sans-serif'; - center = bbox.x + (bbox.width / 2.0); - IGVGraphics.strokeText(context, char, center - (context.measureText(char).width / 2), fontHeight - 1 + bbox.y, {strokeStyle: color}); - } else { - - // render colored block - IGVGraphics.fillRect(context, bbox.x, bbox.y, bbox.width, bbox.height, {fillStyle: color}); - } - } - } - - }; - - popupData(clickState) { - const clickedObject = this.getClickedObject(clickState); - return clickedObject ? clickedObject.popupData(clickState.genomicLocation) : undefined - }; - - contextMenuItemList(clickState) { - - const viewport = clickState.viewport; - const list = []; - - const sortByOption = (option) => { - const cs = this.parent.sortObject; - const direction = (cs && cs.position === Math.floor(clickState.genomicLocation)) ? !cs.direction : true; - const newSortObject = { - chr: viewport.referenceFrame.chr, - position: Math.floor(clickState.genomicLocation), - option: option, - direction: direction - }; - this.parent.sortObject = newSortObject; - viewport.cachedFeatures.sortRows(newSortObject); - viewport.repaint(); - }; - list.push('Sort by...'); - list.push({label: '  base', click: () => sortByOption("BASE")}); - list.push({label: '  read strand', click: () => sortByOption("STRAND")}); - list.push({label: '  insert size', click: () => sortByOption("INSERT_SIZE")}); - list.push({label: '  gap size', click: () => sortByOption("GAP_SIZE")}); - list.push({label: '  chromosome of mate', click: () => sortByOption("MATE_CHR")}); - list.push({label: '  mapping quality', click: () => sortByOption("MQ")}); - list.push({label: '  read name', click: () => sortByOption("READ_NAME")}); - list.push({label: '  aligned read length', click: () => sortByOption("ALIGNED_READ_LENGTH")}); - list.push({ - label: '  tag', click: () => { - const cs = this.parent.sortObject; - const direction = (cs && cs.position === Math.floor(clickState.genomicLocation)) ? !cs.direction : true; - const config = - { - label: 'Tag Name', - value: this.sortByTag ? this.sortByTag : '', - callback: (tag) => { - if (tag) { - const newSortObject = { - chr: viewport.referenceFrame.chr, - position: Math.floor(clickState.genomicLocation), - option: "TAG", - tag: tag, - direction: direction - }; - this.sortByTag = tag; - this.parent.sortObject = newSortObject; - viewport.cachedFeatures.sortRows(newSortObject); - viewport.repaint(); - } - } - }; - this.browser.inputDialog.present(config, clickState.event); - } - }); - list.push('
'); - - const clickedObject = this.getClickedObject(clickState); - - if (clickedObject) { - - const showSoftClips = this.parent.showSoftClips; - const clickedAlignment = (typeof clickedObject.alignmentContaining === 'function') ? - clickedObject.alignmentContaining(clickState.genomicLocation, showSoftClips) : - clickedObject; - if (clickedAlignment) { - if (clickedAlignment.isPaired() && clickedAlignment.isMateMapped()) { - list.push({ - label: 'View mate in split screen', - click: () => { - if (clickedAlignment.mate) { - const referenceFrame = clickState.viewport.referenceFrame; - if (this.browser.genome.getChromosome(clickedAlignment.mate.chr)) { - this.highlightedAlignmentReadNamed = clickedAlignment.readName; - //this.browser.presentMultiLocusPanel(clickedAlignment, referenceFrame) - const bpWidth = referenceFrame.end - referenceFrame.start; - const frameStart = clickedAlignment.mate.position - bpWidth / 2; - const frameEnd = clickedAlignment.mate.position + bpWidth / 2; - this.browser.addMultiLocusPanel(clickedAlignment.mate.chr, frameStart, frameEnd, referenceFrame); - } else { - this.browser.alert.present(`Reference does not contain chromosome: ${clickedAlignment.mate.chr}`); - } - } - }, - init: undefined - }); - } - - list.push({ - label: 'View read sequence', - click: () => { - const seqstring = clickedAlignment.seq; //.map(b => String.fromCharCode(b)).join(""); - if (!seqstring || "*" === seqstring) { - this.browser.alert.present("Read sequence: *"); - } else { - this.browser.alert.present(seqstring); - } - } - }); - - if (isSecureContext()) { - list.push({ - label: 'Copy read sequence', - click: async () => { - const seq = clickedAlignment.seq; //.map(b => String.fromCharCode(b)).join(""); - try { - //console.log(`seq: ${seq}`) - await navigator.clipboard.writeText(seq); - } catch (e) { - console.error(e); - this.browser.alert.present(`error copying sequence to clipboard ${e}`); - } - - } - }); - } - - // TODO if genome supports blat - const seqstring = clickedAlignment.seq; - if (seqstring && "*" != seqstring) { - - if (seqstring.length < maxSequenceSize) { - list.push({ - label: 'BLAT read sequence', - click: () => { - const sequence = clickedAlignment.isNegativeStrand() ? reverseComplementSequence(seqstring) : seqstring; - const name = `${clickedAlignment.readName} - blat`; - const title = `${this.parent.name} - ${name}`; - createBlatTrack({sequence, browser: this.browser, name, title}); - } - }); - } - - const softClips = clickedAlignment.softClippedBlocks(); - if (softClips.left && softClips.left.len > MINIMUM_BLAT_LENGTH && softClips.left.len < maxSequenceSize) { - list.push({ - label: 'BLAT left soft-clipped sequence', - click: () => { - const clippedSequence = seqstring.substr(softClips.left.seqOffset, softClips.left.len); - const sequence = clickedAlignment.isNegativeStrand() ? reverseComplementSequence(clippedSequence) : clippedSequence; - const name = `${clickedAlignment.readName} - blat left clip`; - const title = `${this.parent.name} - ${name}`; - createBlatTrack({sequence, browser: this.browser, name, title}); - } - }); - } - if (softClips.right && softClips.right.len > MINIMUM_BLAT_LENGTH && softClips.right.len < maxSequenceSize) { - list.push({ - label: 'BLAT right soft-clipped sequence', - click: () => { - const clippedSequence = seqstring.substr(softClips.right.seqOffset, softClips.right.len); - const sequence = clickedAlignment.isNegativeStrand() ? reverseComplementSequence(clippedSequence) : clippedSequence; - const name = `${clickedAlignment.readName} - blat right clip`; - const title = `${this.parent.name} - ${name}`; - createBlatTrack({sequence, browser: this.browser, name, title}); - } - }); - } - } - - list.push('
'); - } - } - - // Experimental JBrowse feature - if (this.browser.circularView && (this.hasPairs || this.hasSupplemental)) { - if (this.hasPairs) { - list.push({ - label: 'Add discordant pairs to circular view', - click: () => { - this.parent.addPairedChordsForViewport(viewport); - } - }); - } - if (this.hasSupplemental) { - list.push({ - label: 'Add split reads to circular view', - click: () => { - this.parent.addSplitChordsForViewport(viewport); - } - }); - } - list.push('
'); - } - - return list - - } - - getClickedObject(clickState) { - - const viewport = clickState.viewport; - const y = clickState.y; - const genomicLocation = clickState.genomicLocation; - - const showSoftClips = this.parent.showSoftClips; - - let features = viewport.cachedFeatures; - if (!features || features.length === 0) return - - let packedAlignmentRows = features.packedAlignmentRows; - let downsampledIntervals = features.downsampledIntervals; - const alignmentRowHeight = this.displayMode === "SQUISHED" ? - this.squishedRowHeight : - this.alignmentRowHeight; - - let packedAlignmentsIndex = Math.floor((y - this.top - this.alignmentsYOffset) / alignmentRowHeight); - - if (packedAlignmentsIndex < 0) { - for (let i = 0; i < downsampledIntervals.length; i++) { - if (downsampledIntervals[i].start <= genomicLocation && (downsampledIntervals[i].end >= genomicLocation)) { - return downsampledIntervals[i] - } - } - } else if (packedAlignmentsIndex < packedAlignmentRows.length) { - const alignmentRow = packedAlignmentRows[packedAlignmentsIndex]; - const clicked = alignmentRow.alignments.filter(alignment => alignment.containsLocation(genomicLocation, showSoftClips)); - if (clicked.length > 0) return clicked[0] - } - - return undefined - - }; - - /** - * Return the color for connectors in paired alignment view. If explicitly set return that, otherwise return - * the alignment color, unless the color option can result in split colors (separte color for each mate). - * - * @param alignment - * @returns {string} - */ - getConnectorColor(alignment) { - - if (this.pairConnectorColor) { - return this.pairConnectorColor - } - - switch (this.colorBy) { - case "strand": - case "firstOfPairStrand": - case "pairOrientation": - case "tag": - if (this.parent.color) { - return (typeof this.parent.color === "function") ? this.parent.color(alignment) : this.parent.color - } else { - return DEFAULT_CONNECTOR_COLOR - } - default: - return this.getAlignmentColor(alignment) - - } - } - - getAlignmentColor(alignment) { - - let color = DEFAULT_ALIGNMENT_COLOR; // The default color if nothing else applies - if (this.parent.color) { - color = (typeof this.parent.color === "function") ? this.parent.color(alignment) : this.parent.color; - } else { - color = DEFAULT_ALIGNMENT_COLOR; - } - const option = this.colorBy; - switch (option) { - case "strand": - color = alignment.strand ? this.posStrandColor : this.negStrandColor; - break - - case "firstOfPairStrand": - - if (alignment instanceof PairedAlignment) { - color = alignment.firstOfPairStrand() ? this.posStrandColor : this.negStrandColor; - } else if (alignment.isPaired()) { - - if (alignment.isFirstOfPair()) { - color = alignment.strand ? this.posStrandColor : this.negStrandColor; - } else if (alignment.isSecondOfPair()) { - color = alignment.strand ? this.negStrandColor : this.posStrandColor; - } else { - console.error("ERROR. Paired alignments are either first or second."); - } - } - break - - case "unexpectedPair": - case "pairOrientation": - - if (this.pairOrientation && alignment.pairOrientation) { - const oTypes = orientationTypes[this.pairOrientation]; - if (oTypes) { - const pairColor = this.pairColors[oTypes[alignment.pairOrientation]]; - if (pairColor) { - color = pairColor; - break - } - } - } - if ("pairOrientation" === option) { - break - } - - case "tlen": - case "fragmentLength": - - if (alignment.mate && alignment.isMateMapped()) { - if (alignment.mate.chr !== alignment.chr) { - color = getChrColor(alignment.mate.chr); - } else if (this.parent.minTemplateLength && Math.abs(alignment.fragmentLength) < this.parent.minTemplateLength) { - color = this.smallTLENColor; - } else if (this.parent.maxTemplateLength && Math.abs(alignment.fragmentLength) > this.parent.maxTemplateLength) { - color = this.largeTLENColor; - } - } - break - - case "tag": - const tagValue = alignment.tags()[this.colorByTag]; - if (tagValue !== undefined) { - if (this.bamColorTag === this.colorByTag) { - // UCSC style color option - color = "rgb(" + tagValue + ")"; - } else { - - if (!this.tagColors) { - this.tagColors = new PaletteColorTable("Set1"); - } - color = this.tagColors.getColor(tagValue); - } - } - break - } - - return color - - } - } - - function shadedBaseColor(qual, baseColor) { - - const minQ = 5; //prefs.getAsInt(PreferenceManager.SAM_BASE_QUALITY_MIN), - const maxQ = 20; //prefs.getAsInt(PreferenceManager.SAM_BASE_QUALITY_MAX); - - let alpha; - if (qual < minQ) { - alpha = 0.1; - } else { - alpha = Math.max(0.1, Math.min(1.0, 0.1 + 0.9 * (qual - minQ) / (maxQ - minQ))); - } - // Round alpha to nearest 0.1 - alpha = Math.round(alpha * 10) / 10.0; - - if (alpha < 1) { - baseColor = IGVColor.addAlpha(baseColor, alpha); - } - return baseColor - } - - const orientationTypes = { - - "fr": { - "F1R2": "LR", - "F2R1": "LR", - "F1F2": "LL", - "F2F1": "LL", - "R1R2": "RR", - "R2R1": "RR", - "R1F2": "RL", - "R2F1": "RL" - }, - - "rf": { - "R1F2": "LR", - "R2F1": "LR", - "R1R2": "LL", - "R2R1": "LL", - "F1F2": "RR", - "F2F1": "RR", - "F1R2": "RL", - "F2R1": "RL" - }, - - "ff": { - "F2F1": "LR", - "R1R2": "LR", - "F2R1": "LL", - "R1F2": "LL", - "R2F1": "RR", - "F1R2": "RR", - "R2R1": "RL", - "F1F2": "RL" - } - }; - - function getChrColor(chr) { - if (chrColorMap[chr]) { - return chrColorMap[chr] - } else if (chrColorMap["chr" + chr]) { - const color = chrColorMap["chr" + chr]; - chrColorMap[chr] = color; - return color - } else { - const color = IGVColor.randomRGB(0, 255); - chrColorMap[chr] = color; - return color - } - } - - const chrColorMap = { - "chrX": "rgb(204, 153, 0)", - "chrY": "rgb(153, 204, 0)", - "chrUn": "rgb(50, 50, 50)", - "chr1": "rgb(80, 80, 255)", - "chrI": "rgb(139, 155, 187)", - "chr2": "rgb(206, 61, 50)", - "chrII": "rgb(206, 61, 50)", - "chr2a": "rgb(216, 71, 60)", - "chr2b": "rgb(226, 81, 70)", - "chr3": "rgb(116, 155, 88)", - "chrIII": "rgb(116, 155, 88)", - "chr4": "rgb(240, 230, 133)", - "chrIV": "rgb(240, 230, 133)", - "chr5": "rgb(70, 105, 131)", - "chr6": "rgb(186, 99, 56)", - "chr7": "rgb(93, 177, 221)", - "chr8": "rgb(128, 34, 104)", - "chr9": "rgb(107, 215, 107)", - "chr10": "rgb(213, 149, 167)", - "chr11": "rgb(146, 72, 34)", - "chr12": "rgb(131, 123, 141)", - "chr13": "rgb(199, 81, 39)", - "chr14": "rgb(213, 143, 92)", - "chr15": "rgb(122, 101, 165)", - "chr16": "rgb(228, 175, 105)", - "chr17": "rgb(59, 27, 83)", - "chr18": "rgb(205, 222, 183)", - "chr19": "rgb(97, 42, 121)", - "chr20": "rgb(174, 31, 99)", - "chr21": "rgb(231, 199, 111)", - "chr22": "rgb(90, 101, 94)", - "chr23": "rgb(204, 153, 0)", - "chr24": "rgb(153, 204, 0)", - "chr25": "rgb(51, 204, 0)", - "chr26": "rgb(0, 204, 51)", - "chr27": "rgb(0, 204, 153)", - "chr28": "rgb(0, 153, 204)", - "chr29": "rgb(10, 71, 255)", - "chr30": "rgb(71, 117, 255)", - "chr31": "rgb(255, 194, 10)", - "chr32": "rgb(255, 209, 71)", - "chr33": "rgb(153, 0, 51)", - "chr34": "rgb(153, 26, 0)", - "chr35": "rgb(153, 102, 0)", - "chr36": "rgb(128, 153, 0)", - "chr37": "rgb(51, 153, 0)", - "chr38": "rgb(0, 153, 26)", - "chr39": "rgb(0, 153, 102)", - "chr40": "rgb(0, 128, 153)", - "chr41": "rgb(0, 51, 153)", - "chr42": "rgb(26, 0, 153)", - "chr43": "rgb(102, 0, 153)", - "chr44": "rgb(153, 0, 128)", - "chr45": "rgb(214, 0, 71)", - "chr46": "rgb(255, 20, 99)", - "chr47": "rgb(0, 214, 143)", - "chr48": "rgb(20, 255, 177)", - }; - - let timer; - let currentViewport = undefined; - const toolTipTimeout = 1e4; - - class RulerViewport extends TrackViewport { - - constructor(trackView, $viewportColumn, referenceFrame, width) { - super(trackView, $viewportColumn, referenceFrame, width); - } - - get contentDiv() { - return this.$viewport.get(0) - } - - initializationHelper() { - - this.$multiLocusCloseButton = $$1('
', {class: 'igv-multi-locus-close-button'}); - this.$viewport.append(this.$multiLocusCloseButton); - this.$multiLocusCloseButton.get(0).appendChild(icons$1$1.createIcon("times-circle")); - - this.$multiLocusCloseButton.click(() => { - this.browser.removeMultiLocusPanel(this.referenceFrame); - }); - - this.$rulerLabel = $$1('
', {class: 'igv-multi-locus-ruler-label'}); - this.$viewport.append(this.$rulerLabel); - - let div; - div = document.createElement('div'); - this.$rulerLabel.append($$1(div)); - - this.$rulerLabel.get(0).addEventListener('click', async event => { - event.stopPropagation(); - await this.browser.gotoMultilocusPanel(this.referenceFrame); - }); - - this.$tooltip = $$1('
', {class: 'igv-ruler-tooltip'}); - this.$tooltip.height(this.$viewport.height()); - - this.$viewport.append(this.$tooltip); - - this.$tooltipContent = $$1('
'); - this.$tooltip.append(this.$tooltipContent); - - this.rulerSweeper = new RulerSweeper(this, this.$viewport.get(0).parentElement, this.browser, this.referenceFrame); - - this.attachMouseHandlers(GenomeUtils.isWholeGenomeView(this.referenceFrame.chr)); - - this.$tooltip.hide(); - - this.dismissLocusLabel(); - } - - presentLocusLabel(viewportWidth) { - - this.$multiLocusCloseButton.show(); - - this.$rulerLabel.show(); - this.$rulerLabel.get(0).style.backgroundColor = getChrColor(this.referenceFrame.chr); - - const textDiv = this.$rulerLabel.get(0).querySelector('div'); - - const { width } = this.$rulerLabel.get(0).getBoundingClientRect(); - - textDiv.innerHTML = `${ this.referenceFrame.getMultiLocusLabel(viewportWidth) }`; - const { width:textDivWidth } = textDiv.getBoundingClientRect(); - - if (textDivWidth/width > 0.5) { - textDiv.innerHTML = `${ this.referenceFrame.getMultiLocusLabelBPLengthOnly(viewportWidth) }`; - } - - //console.log(`${ Date.now() } textDiv ${ StringUtils.numberFormatter(Math.floor(textDivWidth)) }`) - - } - - // Use in conjuction with .igv-multi-locus-ruler-label-square-dot css class (_dom-misc.scss) - dismissLocusLabel() { - this.$rulerLabel.hide(); - this.$multiLocusCloseButton.hide(); - } - - attachMouseHandlers(isWholeGenomeView) { - - this.namespace = `.ruler_track_viewport_${this.browser.referenceFrameList.indexOf(this.referenceFrame)}`; - - this.$viewport.off(this.namespace); - - if (true === isWholeGenomeView) { - - const index = this.browser.referenceFrameList.indexOf(this.referenceFrame); - - const click = `click${this.namespace}`; - this.$viewport.on(click, (e) => { - - const {x: pixel} = domUtils$1.translateMouseCoordinates(e, this.$viewport.get(0)); - const bp = Math.round(this.referenceFrame.start + this.referenceFrame.toBP(pixel)); - - let searchString; - - const {chr} = this.browser.genome.getChromosomeCoordinate(bp); - - if (1 === this.browser.referenceFrameList.length) { - searchString = chr; - } else { - - let loci = this.browser.referenceFrameList.map(({locusSearchString}) => locusSearchString); - - loci[index] = chr; - - searchString = loci.join(' '); - } - - this.browser.search(searchString); - }); - - this.$viewport.get(0).style.cursor = 'pointer'; - } else { - this.$viewport.get(0).style.cursor = 'default'; - } - - } - - mouseMove(event) { - - if (true === this.browser.cursorGuideVisible) { - - if (undefined === currentViewport) { - currentViewport = this; - this.$tooltip.show(); - } else if (currentViewport.guid !== this.guid) { - if (currentViewport.$tooltip) { - currentViewport.$tooltip.hide(); - } - this.$tooltip.show(); - currentViewport = this; - } else { - this.$tooltip.show(); - } - - const isWholeGenome = (this.browser.isMultiLocusWholeGenomeView() || GenomeUtils.isWholeGenomeView(this.referenceFrame.chr)); - - if (isWholeGenome) { - this.$tooltip.hide(); - return - } - - const {x} = domUtils$1.translateMouseCoordinates(event, this.$viewport.get(0)); - const {start, bpPerPixel} = this.referenceFrame; - const bp = Math.round(0.5 + start + Math.max(0, x) * bpPerPixel); - - this.$tooltipContent.text(numberFormatter$1(bp)); - - const {width: ww} = this.$tooltipContent.get(0).getBoundingClientRect(); - const {width: w} = this.$viewport.get(0).getBoundingClientRect(); - - this.$tooltip.css({left: `${IGVMath.clamp(x, 0, w - ww)}px`}); - - // hide tooltip when movement stops - clearTimeout(timer); - timer = setTimeout(() => { - if (this.$tooltip) this.$tooltip.hide(); - }, toolTipTimeout); - - } - - } - - startSpinner() { - } - - stopSpinner() { - } - - dispose() { - this.rulerSweeper.dispose(); - super.dispose(); - } - - } - - /* - * The MIT License (MIT) - * - * Copyright (c) 2014 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - class IdeogramViewport extends TrackViewport { - - constructor(trackView, viewportColumn, referenceFrame, width) { - super(trackView, viewportColumn, referenceFrame, width); - } - - initializationHelper() { - - this.canvas = document.createElement('canvas'); - this.canvas.className = 'igv-ideogram-canvas'; - //this.$content.append($(this.canvas)) - this.$viewport.append($$1(this.canvas)); - this.ideogram_ctx = this.canvas.getContext('2d'); - - this.addMouseHandlers(); - } - - addMouseHandlers() { - this.addViewportClickHandler(this.$viewport.get(0)); - } - - addViewportClickHandler(viewport) { - - this.boundClickHandler = clickHandler.bind(this); - viewport.addEventListener('click', this.boundClickHandler); - - function clickHandler(event) { - - const {xNormalized, width} = domUtils$1.translateMouseCoordinates(event, this.ideogram_ctx.canvas); - const {bpLength} = this.browser.genome.getChromosome(this.referenceFrame.chr); - const locusLength = this.referenceFrame.bpPerPixel * width; - const chrCoveragePercentage = locusLength / bpLength; - - let xPercentage = xNormalized; - if (xPercentage - (chrCoveragePercentage / 2.0) < 0) { - xPercentage = chrCoveragePercentage / 2.0; - } - - if (xPercentage + (chrCoveragePercentage / 2.0) > 1.0) { - xPercentage = 1.0 - chrCoveragePercentage / 2.0; - } - - const ss = Math.round((xPercentage - (chrCoveragePercentage / 2.0)) * bpLength); - const ee = Math.round((xPercentage + (chrCoveragePercentage / 2.0)) * bpLength); - - this.referenceFrame.start = ss; - this.referenceFrame.end = ee; - this.referenceFrame.bpPerPixel = (ee - ss) / width; - - this.browser.updateViews(this.referenceFrame, this.browser.trackViews, true); - - } - - } - - setWidth(width) { - this.$viewport.width(width); - } - - drawSVGWithContext(context, width, height, id, x, y, yClipOffset) { - - context.saveWithTranslationAndClipRect(id, x, y, width, height, yClipOffset); - - this.trackView.track.draw({ - context, - referenceFrame: this.referenceFrame, - pixelWidth: width, - pixelHeight: height - }); - - context.restore(); - } - - repaint() { - this.draw({referenceFrame: this.referenceFrame}); - } - - draw({referenceFrame}) { - - IGVGraphics.configureHighDPICanvas(this.ideogram_ctx, this.$viewport.width(), this.$viewport.height()); - - this.trackView.track.draw({ - context: this.ideogram_ctx, - referenceFrame, - pixelWidth: this.$viewport.width(), - pixelHeight: this.$viewport.height() - }); - } - - startSpinner() { - } - - stopSpinner() { - } - - } - - /* - * The MIT License (MIT) - * - * Copyright (c) 2014 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - - function createViewport(trackView, column, referenceFrame, width) { - - if ('ruler' === trackView.track.type) { - return new RulerViewport(trackView, column, referenceFrame, width) - } else if ('ideogram' === trackView.track.id) { - return new IdeogramViewport(trackView, column, referenceFrame, width) - } else { - const viewportObject = new TrackViewport(trackView, column, referenceFrame, width); - - // if ('sequence' === trackView.track.type) { - // viewportObject.$viewport.get(0).style.marginTop = '0px' - // } - - return viewportObject - } - } - - const maxFontSize = 10; - - const fontConfigureTemplate = - { - // font: '2pt sans-serif', - textAlign: 'start', - textBaseline: 'bottom', - strokeStyle: 'black', - fillStyle: 'black' - }; - - class SampleNameViewport { - - constructor(trackView, column, unused, width) { - - this.guid = domUtils$1.guid(); - this.trackView = trackView; - - this.browser = trackView.browser; - - this.viewport = domUtils$1.div({class: 'igv-viewport'}); - - column.appendChild(this.viewport); - - if (trackView.track.height) { - this.viewport.style.height = `${trackView.track.height}px`; - } - - this.canvas = document.createElement('canvas'); - this.viewport.appendChild(this.canvas); - this.ctx = this.canvas.getContext("2d"); - - this.trackScrollDelta = 0; - - this.contentTop = 0; - - this.setWidth(width); - - if (false === this.browser.showSampleNames) { - this.hide(); - } - - this.addMouseHandlers(); - } - - checkCanvas() { - - const dpi = window.devicePixelRatio; - const requiredHeight = this.viewport.clientHeight; - const requiredWidth = this.browser.sampleNameViewportWidth; - - if (this.canvas.width !== requiredWidth * dpi || this.canvas.height !== requiredHeight * dpi) { - const canvas = this.canvas; - canvas.width = requiredWidth * dpi; - canvas.height = requiredHeight * dpi; - canvas.style.width = `${requiredWidth}px`; - canvas.style.height = `${requiredHeight}px`; - this.ctx = this.canvas.getContext("2d"); - this.ctx.scale(dpi, dpi); - } - - } - - setTop(contentTop) { - - if (typeof this.trackView.track.getSamples === 'function') { - this.contentTop = contentTop; - const samples = this.trackView.track.getSamples(); - this.repaint(samples); - } - - } - - setWidth(width) { - this.viewport.innerWidth = width; - this.checkCanvas(); - } - - show() { - this.viewport.style.display = 'block'; - } - - hide() { - this.viewport.style.display = 'none'; - } - - async repaint(samples) { - - this.checkCanvas(); - this.draw({context: this.ctx, samples}); - } - - draw({context, samples}) { - - if (!samples || samples.names.length === 0/* || samples.height < 1*/) { - return - } - - configureFont(context, fontConfigureTemplate, samples.height); - const sampleNameXShim = 4; - - context.clearRect(0, 0, context.canvas.width, context.canvas.height); - - context.fillStyle = appleCrayonRGB('lead'); - - const viewportHeight = this.viewport.getBoundingClientRect().height; - let y = (samples.yOffset || 0) + this.contentTop; // contentTop will always be a negative number (top relative to viewport) - - for (let name of samples.names) { - if (y > viewportHeight) { - break - } - if (y + samples.height > 0) { - const text = name; - const yFont = getYFont(context, text, y, samples.height); - context.fillText(text, sampleNameXShim, yFont); - - } - y += samples.height; - } - } - - renderSVGContext(context, {deltaX, deltaY}) { - - if (typeof this.trackView.track.getSamples === 'function') { - - const samples = this.trackView.track.getSamples(); - - const yScrollDelta = 0; // This is not relevant, scrolling is handled in "draw" - - const {width, height} = this.viewport.getBoundingClientRect(); - - const str = (this.trackView.track.name || this.trackView.track.id).replace(/\W/g, ''); - const id = `${str}_sample_names_guid_${domUtils$1.guid()}`; - - context.saveWithTranslationAndClipRect(id, deltaX, deltaY + yScrollDelta, width, height, -yScrollDelta); - - this.draw({context, samples}); - - context.restore(); - } - } - - addMouseHandlers() { - this.addViewportContextMenuHandler(this.viewport); - } - - removeMouseHandlers() { - this.removeViewportContextMenuHandler(this.viewport); - } - - addViewportContextMenuHandler(viewport) { - this.boundContextMenuHandler = contextMenuHandler.bind(this); - viewport.addEventListener('contextmenu', this.boundContextMenuHandler); - - function contextMenuHandler(event) { - - event.preventDefault(); - event.stopPropagation(); - - const config = - { - label: 'Name Panel Width', - value: this.browser.sampleNameViewportWidth, - callback: newWidth => { - this.browser.sampleNameViewportWidth = parseInt(newWidth); - for (let {sampleNameViewport} of this.browser.trackViews) { - sampleNameViewport.setWidth(this.browser.sampleNameViewportWidth); - } - this.browser.layoutChange(); - } - }; - - this.browser.inputDialog.present(config, event); - } - - } - - removeViewportContextMenuHandler(viewport) { - viewport.removeEventListener('contextmenu', this.boundContextMenuHandler); - } - - dispose() { - this.removeMouseHandlers(); - this.viewport.remove(); - } - } - - function getYFont(context, text, y, height) { - return y + height - getSampleNameYShim(context, text, height) - } - - function getSampleNameYShim(context, text, h) { - const {actualBoundingBoxAscent, actualBoundingBoxDescent} = context.measureText(text); - return (h - (actualBoundingBoxAscent + actualBoundingBoxDescent)) / 2 - } - - function configureFont(ctx, {textAlign, textBaseline, strokeStyle, fillStyle}, sampleHeight) { - const pixels = Math.min(sampleHeight, maxFontSize); - ctx.font = `${pixels}px sans-serif`; - ctx.textAlign = textAlign; - ctx.textBaseline = textBaseline; - ctx.fillStyle = fillStyle; - } - - const MenuPopup = function (parent) { - - this.popover = domUtils$1.div({class: 'igv-menu-popup'}); - parent.appendChild(this.popover); - - const header = domUtils$1.div({class: 'igv-menu-popup-header'}); - this.popover.appendChild(header); - - uiUtils$1.attachDialogCloseHandlerWithParent(header, () => this.hide()); - - this.popoverContent = domUtils$1.div(); - this.popover.appendChild(this.popoverContent); - - makeDraggable$1(this.popover, header); - - header.addEventListener('click', e => { - e.stopPropagation(); - e.preventDefault(); - // absorb click to prevent it leaking through to parent DOM element - }); - - this.hide(); - - }; - - MenuPopup.prototype.hide = function () { - this.popover.style.display = 'none'; - }; - - MenuPopup.prototype.presentMenuList = function (menuList) { - - hideAllMenuPopups(); - - if (menuList.length > 0) { - - this.popoverContent.innerHTML = ''; - - menuList = MenuUtils$1.trackMenuItemListHelper(menuList, this); - - for (let item of menuList) { - - if (item.init) { - item.init(); - } - - let $e = item.object; - if (0 === menuList.indexOf(item)) { - $e.removeClass('igv-track-menu-border-top'); - } - - if ($e.hasClass('igv-track-menu-border-top') || $e.hasClass('igv-menu-popup-check-container')) ; else if ($e.is('div')) { - $e.addClass('igv-menu-popup-shim'); - } - - this.popoverContent.appendChild($e.get(0)); - - } - - // NOTE: style.display most NOT be 'none' when calculating width. a display = 'none' will always - // yield a width of zero (0). - this.popover.style.display = 'flex'; - - const {width} = this.popover.getBoundingClientRect(); - - this.popover.style.left = `${-width}px`; - this.popover.style.top = `${0}px`; - - } - }; - - MenuPopup.prototype.presentTrackContextMenu = function (e, menuItems) { - - this.popoverContent.innerHTML = ''; - - const menuElements = createMenuElements(menuItems, this.popover); - for (let {el} of menuElements) { - this.popoverContent.appendChild(el); - } - - present(e, this.popover); - - }; - - MenuPopup.prototype.dispose = function () { - - this.popoverContent.innerHTML = ''; - this.popover.innerHTML = ''; - - Object.keys(this).forEach(function (key) { - this[key] = undefined; - }); - }; - - function createMenuElements(itemList, popover) { - - return itemList.map(item => { - - let el; - - if (typeof item === 'string' && '
' === item) { - el = document.createElement('hr'); - } else if (typeof item === 'string') { - el = domUtils$1.div({class: 'context-menu'}); - el.innerHTML = item; - } else if (typeof item === 'Node') { - el = item; - } else { - if (typeof item.init === 'function') { - item.init(); - } - - if ("checkbox" === item.type) { - el = createCheckbox$2("Show all bases", item.value); - } else if ("color" === item.type) { - - const colorPicker = new GenericColorPicker({parent: popover.parentElement, width: 364}); - colorPicker.configure(undefined, {color: color => item.click(color)}); - - el = domUtils$1.div({class: 'context-menu'}); - if (typeof item.label === 'string') { - el.innerHTML = item.label; - } - const clickHandler = e => { - colorPicker.show(); - domUtils$1.hide(popover); - e.preventDefault(); - e.stopPropagation(); - }; - el.addEventListener('click', clickHandler); - el.addEventListener('touchend', clickHandler); - el.addEventListener('mouseup', function (e) { - e.preventDefault(); - e.stopPropagation(); - }); - } else { - el = domUtils$1.div({class: 'context-menu'}); - if (typeof item.label === 'string') { - el.innerHTML = item.label; - } - } - - if (item.click && "color" !== item.type) { - el.addEventListener('click', handleClick); - el.addEventListener('touchend', handleClick); - el.addEventListener('mouseup', function (e) { - e.preventDefault(); - e.stopPropagation(); - }); - - // eslint-disable-next-line no-inner-declarations - function handleClick(e) { - item.click(); - domUtils$1.hide(popover); - e.preventDefault(); - e.stopPropagation(); - } - } - } - - return {el, init: item.init} - }) - - } - - function present(e, popover) { - - // NOTE: style.display most NOT be 'none' when calculating width. a display = 'none' will always - // yield a width of zero (0). - popover.style.display = 'flex'; - - const {x, y} = domUtils$1.translateMouseCoordinates(e, popover.parentNode); - const {width} = popover.getBoundingClientRect(); - const xmax = x + width; - - const {width: parentWidth} = popover.parentNode.getBoundingClientRect(); - - popover.style.left = `${xmax > parentWidth ? (x - (xmax - parentWidth)) : x}px`; - popover.style.top = `${y}px`; - - } - - const hideAllMenuPopups = () => { - - const menus = document.querySelectorAll('.igv-menu-popup'); - for (let i = 0; i < menus.length; i++) { - menus[i].style.display = 'none'; - } - - }; - - /* - * The MIT License (MIT) - * - * Copyright (c) 2014 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - const igv_axis_column_width = 50; - const scrollbarExclusionTypes = new Set(['ruler', 'ideogram']); - const colorPickerExclusionTypes = new Set(['ruler', 'sequence', 'ideogram']); - - class TrackView { - - constructor(browser, columnContainer, track) { - this.browser = browser; - this.track = track; - track.trackView = this; - this.addDOMToColumnContainer(browser, columnContainer, browser.referenceFrameList); - } - - /** - * Start a spinner for the track on any of its viewports. In practice this is called during initialization - * when there is only one. - */ - startSpinner() { - if (this.viewports && this.viewports.length > 0) { - this.viewports[0].startSpinner(); - } - } - - stopSpinner() { - if (this.viewports && this.viewports.length > 0) { - this.viewports[0].stopSpinner(); - } - } - - addDOMToColumnContainer(browser, columnContainer, referenceFrameList) { - - // Axis - this.axis = this.createAxis(browser, this.track); - - // Create a viewport for each reference frame - this.viewports = []; - const viewportWidth = browser.calculateViewportWidth(referenceFrameList.length); - const viewportColumns = columnContainer.querySelectorAll('.igv-column'); - for (let i = 0; i < viewportColumns.length; i++) { - const viewport = createViewport(this, viewportColumns[i], referenceFrameList[i], viewportWidth); - this.viewports.push(viewport); - } - - // SampleName Viewport - this.sampleNameViewport = new SampleNameViewport(this, browser.columnContainer.querySelector('.igv-sample-name-column'), undefined, browser.sampleNameViewportWidth); - - // Track Scrollbar - this.createTrackScrollbar(browser); - - // Track Drag - this.createTrackDragHandle(browser); - - // Track Gear - this.createTrackGearPopup(browser); - - } - - createAxis(browser, track) { - - const axis = domUtils$1.div(); - browser.columnContainer.querySelector('.igv-axis-column').appendChild(axis); - - axis.style.height = `${track.height}px`; - - if (typeof track.paintAxis === 'function') { - if (track.dataRange) { - axis.addEventListener('click', () => { - browser.dataRangeDialog.configure(this); - browser.dataRangeDialog.present($$1(browser.columnContainer)); - }); - } - - - const {width, height} = axis.getBoundingClientRect(); - this.axisCanvas = document.createElement('canvas'); - this.axisCanvas.style.width = `${width}px`; - this.axisCanvas.style.height = `${height}px`; - axis.appendChild(this.axisCanvas); - } - - return axis - - } - - resizeAxisCanvas(width, height) { - - this.axis.style.width = `${width}px`; - this.axis.style.height = `${height}px`; - - if (typeof this.track.paintAxis === 'function') { - // Size the canvas in CSS (logical) pixels. The buffer size will be set when painted. - this.axisCanvas.style.width = `${width}px`; - this.axisCanvas.style.height = `${height}px`; - - } - } - - removeDOMFromColumnContainer() { - - // Axis - if (this.boundAxisClickHander) { - this.removeAxisEventListener(this.axis); - } - this.axis.remove(); - - // Track Viewports - for (let viewport of this.viewports) { - viewport.$viewport.remove(); - } - - // SampleName Viewport - this.sampleNameViewport.dispose(); - - // empty trackScrollbar Column - this.removeTrackScrollMouseHandlers(); - this.outerScroll.remove(); - - // empty trackDrag Column - this.removeTrackDragMouseHandlers(); - this.dragHandle.remove(); - - // empty trackGear Column - this.removeTrackGearMouseHandlers(); - this.gearContainer.remove(); - - } - - renderSVGContext(context, {deltaX, deltaY}) { - - renderSVGAxis(context, this.track, this.axisCanvas, deltaX, deltaY); - - const {width: axisWidth} = this.axis.getBoundingClientRect(); - - const {y} = this.viewports[0].$viewport.get(0).getBoundingClientRect(); - - let delta = - { - deltaX: axisWidth + deltaX, - deltaY: y + deltaY - }; - - for (let viewport of this.viewports) { - viewport.renderSVGContext(context, delta); - const {width} = viewport.$viewport.get(0).getBoundingClientRect(); - delta.deltaX += width; - } - - if (true === this.browser.showSampleNames) { - this.sampleNameViewport.renderSVGContext(context, delta); - } - } - - dataRange() { - return this.track.dataRange ? this.track.dataRange : undefined - } - - setDataRange(min, max) { - if (min !== undefined) { - this.track.dataRange.min = min; - } - if (max !== undefined) { - this.track.dataRange.max = max; - } - this.track.autoscale = false; - this.repaintViews(); - } - - presentColorPicker(key) { - - if (false === colorPickerExclusionTypes.has(this.track.type)) { - - const trackColors = []; - const color = this.track.color || this.track.defaultColor; - if (isString$2(color)) { - trackColors.push(color); - } - if (this.track.altColor && isString$2(this.track.altColor)) { - trackColors.push(this.track.altColor); - } - const defaultColors = trackColors.map(c => c.startsWith("#") ? c : c.startsWith("rgb(") ? IGVColor.rgbToHex(c) : IGVColor.colorNameToHex(c)); - const colorHandlers = - { - color: color => { - this.track.color = color; - this.repaintViews(); - }, - altColor: color => { - this.track.altColor = color; - this.repaintViews(); - } - - }; - this.browser.genericColorPicker.configure(defaultColors, colorHandlers); - this.browser.genericColorPicker.setActiveColorHandler(key); - this.browser.genericColorPicker.show(); - } - - } - - setTrackHeight(newHeight, force) { - - if (!force) { - if (this.track.minHeight) { - newHeight = Math.max(this.track.minHeight, newHeight); - } - if (this.track.maxHeight) { - newHeight = Math.min(this.track.maxHeight, newHeight); - } - } - - this.track.height = newHeight; - - this.resizeAxisCanvas(this.axis.clientWidth, this.track.height); - - if (typeof this.track.paintAxis === 'function') { - this.paintAxis(); - } - - for (let {$viewport} of this.viewports) { - $viewport.height(newHeight); - } - - this.sampleNameViewport.viewport.style.height = `${newHeight}px`; - - // If the track does not manage its own content height set it equal to the viewport height here - if (typeof this.track.computePixelHeight !== "function") { - for (let vp of this.viewports) { - vp.setContentHeight(newHeight); - } - } - - this.repaintViews(); - - if (false === scrollbarExclusionTypes.has(this.track.type)) { - this.updateScrollbar(); - } - - this.dragHandle.style.height = `${newHeight}px`; - this.gearContainer.style.height = `${newHeight}px`; - - } - - updateScrollbar() { - - const viewportHeight = this.viewports[0].$viewport.height(); - this.outerScroll.style.height = `${viewportHeight}px`; - - const viewportContentHeight = this.maxViewportContentHeight(); - const innerScrollHeight = Math.round((viewportHeight / viewportContentHeight) * viewportHeight); - - if (viewportContentHeight > viewportHeight) { - this.innerScroll.style.display = 'block'; - this.innerScroll.style.height = `${innerScrollHeight}px`; - } else { - this.innerScroll.style.display = 'none'; - } - } - - moveScroller(delta) { - - const y = $$1(this.innerScroll).position().top + delta; - const top = Math.min(Math.max(0, y), this.outerScroll.clientHeight - this.innerScroll.clientHeight); - $$1(this.innerScroll).css('top', `${top}px`); - - const contentHeight = this.maxViewportContentHeight(); - const contentTop = -Math.round(top * (contentHeight / this.viewports[0].$viewport.height())); - - for (let viewport of this.viewports) { - viewport.setTop(contentTop); - } - - this.sampleNameViewport.trackScrollDelta = delta; - this.sampleNameViewport.setTop(contentTop); - - } - - isLoading() { - for (let viewport of this.viewports) { - if (viewport.isLoading()) return true - } - } - - /** - * Repaint all viewports without loading any new data. Use this for events that change visual aspect of data, - * e.g. color, sort order, etc, but do not change the genomic state. - */ - repaintViews() { - - for (let viewport of this.viewports) { - if (viewport.isVisible()) { - viewport.repaint(); - } - } - - if (typeof this.track.paintAxis === 'function') { - this.paintAxis(); - } - - // Repaint sample names last - this.repaintSamples(); - } - - repaintSamples() { - - if (typeof this.track.getSamples === 'function') { - const samples = this.track.getSamples(); - this.sampleNameViewport.repaint(samples); - } - } - - // track labels - setTrackLabelName(name) { - this.viewports.forEach(viewport => viewport.setTrackLabel(name)); - } - - /** - * Called in response to a window resize event, change in # of multilocus panels, or other event that changes - * the width of the track view. - * - * @param viewportWidth The width of each viewport in this track view. - */ - resize(viewportWidth) { - for (let viewport of this.viewports) { - viewport.setWidth(viewportWidth); - } - } - - /** - * Update viewports to reflect current genomic state, possibly loading additional data. - * - * @param force - if true, force a repaint even if no new data is loaded - * @returns {Promise} - */ - async updateViews() { - - if (!(this.browser && this.browser.referenceFrameList)) return - - const visibleViewports = this.viewports.filter(viewport => viewport.isVisible()); - - // Shift viewports left/right to current genomic state (pans canvas) - visibleViewports.forEach(viewport => viewport.shift()); - - // If dragging (panning) return - if (this.browser.dragObject) { - return - } - - // Filter zoomed out views. This has the side effect or turning off or no the zoomed out notice - const viewportsToRepaint = visibleViewports.filter(vp => vp.needsRepaint()).filter(viewport => viewport.checkZoomIn()); - - // Get viewports that require a data load - const viewportsToReload = viewportsToRepaint.filter(viewport => viewport.needsReload()); - - // Trigger viewport to load features needed to cover current genomic range - // NOTE: these must be loaded synchronously, do not user Promise.all, not all file readers are thread safe - for (let viewport of viewportsToReload) { - await viewport.loadFeatures(); - } - - if (this.disposed) return // Track was removed during load - - // Special case for variant tracks in multilocus view. The # of rows to allocate to the variant (site) - // section depends on data from all the views. We only need to adjust this however if any data was loaded - // (i.e. reloadableViewports.length > 0) - if (this.track && typeof this.track.variantRowCount === 'function' && viewportsToReload.length > 0) { - let maxRow = 0; - for (let viewport of this.viewports) { - if (viewport.featureCache && viewport.featureCache.features) { - maxRow = Math.max(maxRow, viewport.featureCache.features.reduce((a, f) => Math.max(a, f.row || 0), 0)); - } - } - const current = this.track.nVariantRows; - if (current !== maxRow + 1) { - this.track.variantRowCount(maxRow + 1); - for (let viewport of this.viewports) { - viewport.checkContentHeight(); - } - } - } - - if (this.track.autoscale) { - let allFeatures = []; - for (let visibleViewport of visibleViewports) { - const referenceFrame = visibleViewport.referenceFrame; - const start = referenceFrame.start; - const end = start + referenceFrame.toBP(visibleViewport.getWidth()); - if (visibleViewport.featureCache && visibleViewport.featureCache.features) { - // If the "features" object has a getMax function use it. Currently only alignmentContainer implements this, for coverage. - if (typeof visibleViewport.featureCache.features.getMax === 'function') { - const max = visibleViewport.featureCache.features.getMax(start, end); - allFeatures.push({value: max}); - } else { - const viewFeatures = FeatureUtils.findOverlapping(visibleViewport.featureCache.features, start, end); - for (let f of viewFeatures) { - allFeatures.push(f); - } - } - } - } - if (typeof this.track.doAutoscale === 'function') { - this.track.dataRange = this.track.doAutoscale(allFeatures); - } else { - this.track.dataRange = doAutoscale$1(allFeatures); - } - } - - const refreshView = (this.track.autoscale || this.track.autoscaleGroup || this.track.type === 'ruler'); - for (let vp of visibleViewports) { - if (viewportsToRepaint.includes(vp)) { - vp.repaint(); - } else if (refreshView) { - vp.refresh(); - } - } - - this.adjustTrackHeight(); - - // Repaint sample names last - this.repaintSamples(); - - this.updateRulerViewportLabels(); - } - - clearCachedFeatures() { - for (let viewport of this.viewports) { - viewport.clearCache(); - } - } - - updateRulerViewportLabels() { - - const viewportWidth = this.browser.calculateViewportWidth(this.viewports.length); - - for (let viewport of this.viewports) { - if ('ruler' === this.track.type) { - if (this.viewports.length > 1) { - viewport.presentLocusLabel(viewportWidth); - } else { - viewport.dismissLocusLabel(); - } - } - } - - } - - /** - * Return a promise to get all in-view features across all viewports. Used for group autoscaling. - */ - async getInViewFeatures() { - - if (!(this.browser && this.browser.referenceFrameList)) { - return [] - } - - let allFeatures = []; - const visibleViewports = this.viewports.filter(viewport => viewport.isVisible()); - for (let vp of visibleViewports) { - - const referenceFrame = vp.referenceFrame; - const {chr, start, bpPerPixel} = vp.referenceFrame; - const end = start + referenceFrame.toBP(vp.getWidth()); - const needsReload = !vp.featureCache || !vp.featureCache.containsRange(chr, start, end, bpPerPixel); - - if (needsReload) { - await vp.loadFeatures(); - } - if (vp.featureCache && vp.featureCache.features) { - - if (typeof vp.featureCache.features.getMax === 'function') { - const max = vp.featureCache.features.getMax(start, end); - allFeatures.push({value: max}); - } else { - const vpFeatures = typeof vp.featureCache.queryFeatures === 'function' ? - vp.featureCache.queryFeatures(chr, start, end) : - FeatureUtils.findOverlapping(vp.featureCache.features, start, end); - allFeatures = allFeatures.concat(vpFeatures); - } - } - } - return allFeatures - } - - checkContentHeight() { - - for (let viewport of this.viewports) { - viewport.checkContentHeight(); - } - this.adjustTrackHeight(); - - } - - adjustTrackHeight() { - - var contentHeight = this.maxViewportContentHeight(); - if (this.track.autoHeight) { - this.setTrackHeight(contentHeight, false); - } else if (this.track.paintAxis) { // Avoid duplication, paintAxis is already called in setTrackHeight - this.paintAxis(); - } - - if (false === scrollbarExclusionTypes.has(this.track.type)) { - - // Adjust scrollbar, if needed, to insure content is in view - const currentTop = this.viewports[0].getContentTop(); - const viewportHeight = this.viewports[0].$viewport.height(); - const minTop = Math.min(0, viewportHeight - contentHeight); - if(currentTop < minTop) { - for (let viewport of this.viewports) { - viewport.setTop(minTop); - } - } - this.updateScrollbar(); - } - } - - createTrackScrollbar(browser) { - - const outerScroll = domUtils$1.div(); - browser.columnContainer.querySelector('.igv-scrollbar-column').appendChild(outerScroll); - outerScroll.style.height = `${this.track.height}px`; - this.outerScroll = outerScroll; - - if (false === scrollbarExclusionTypes.has(this.track.type)) { - const innerScroll = domUtils$1.div(); - outerScroll.appendChild(innerScroll); - this.innerScroll = innerScroll; - - this.addTrackScrollMouseHandlers(browser); - } - - } - - createTrackDragHandle(browser) { - - const className = 'ideogram' === this.track.type || 'ruler' === this.track.type ? 'igv-track-drag-shim' : 'igv-track-drag-handle'; - this.dragHandle = domUtils$1.div({class: className}); - browser.columnContainer.querySelector('.igv-track-drag-column').appendChild(this.dragHandle); - this.dragHandle.style.height = `${this.track.height}px`; - - this.addTrackDragMouseHandlers(browser); - - } - - createTrackGearPopup(browser) { - - this.gearContainer = domUtils$1.div(); - browser.columnContainer.querySelector('.igv-gear-menu-column').appendChild(this.gearContainer); - this.gearContainer.style.height = `${this.track.height}px`; - - if (true === this.track.ignoreTrackMenu) ; else { - - this.gear = domUtils$1.div(); - this.gearContainer.appendChild(this.gear); - this.gear.appendChild(icons$1$1.createIcon('cog')); - - this.trackGearPopup = new MenuPopup(this.gear); - - this.addTrackGearMouseHandlers(); - } - - } - - addAxisEventListener(axis) { - - this.boundAxisClickHander = axisClickHandler.bind(this); - axis.addEventListener('click', this.boundAxisClickHander); - - function axisClickHandler(event) { - this.browser.dataRangeDialog.configure(this); - this.browser.dataRangeDialog.present($$1(this.browser.columnContainer)); - } - - } - - removeAxisEventListener(axis) { - axis.removeEventListener('click', this.boundAxisClickHander); - } - - addTrackScrollMouseHandlers(browser) { - - // Mouse Down - this.boundTrackScrollMouseDownHandler = trackScrollMouseDownHandler.bind(this); - this.innerScroll.addEventListener('mousedown', this.boundTrackScrollMouseDownHandler); - - function trackScrollMouseDownHandler(event) { - - event.stopPropagation(); - - const {y} = domUtils$1.pageCoordinates(event); - - $$1(this.innerScroll).data('yDown', y.toString()); - - this.boundColumnContainerMouseMoveHandler = columnContainerMouseMoveHandler.bind(this); - browser.columnContainer.addEventListener('mousemove', this.boundColumnContainerMouseMoveHandler); - - function columnContainerMouseMoveHandler(event) { - - event.stopPropagation(); - - const {y} = domUtils$1.pageCoordinates(event); - - this.moveScroller(y - parseInt($$1(this.innerScroll).data('yDown'))); - - $$1(this.innerScroll).data('yDown', y.toString()); - - } - } - - this.boundColumnContainerMouseUpHandler = columnContainerMouseUpHandler.bind(this); - browser.columnContainer.addEventListener('mouseup', this.boundColumnContainerMouseUpHandler); - - function columnContainerMouseUpHandler(event) { - browser.columnContainer.removeEventListener('mousemove', this.boundColumnContainerMouseMoveHandler); - } - - } - - removeTrackScrollMouseHandlers() { - if (false === scrollbarExclusionTypes.has(this.track.type)) { - this.innerScroll.removeEventListener('mousedown', this.boundTrackScrollMouseDownHandler); - this.browser.columnContainer.removeEventListener('mouseup', this.boundColumnContainerMouseUpHandler); - this.browser.columnContainer.removeEventListener('mousemove', this.boundColumnContainerMouseMoveHandler); - } - } - - addTrackDragMouseHandlers(browser) { - - if ('ideogram' === this.track.id || 'ruler' === this.track.id) ; else { - - let currentDragHandle = undefined; - - // Mouse Down - this.boundTrackDragMouseDownHandler = trackDragMouseDownHandler.bind(this); - this.dragHandle.addEventListener('mousedown', this.boundTrackDragMouseDownHandler); - - function trackDragMouseDownHandler(event) { - - event.preventDefault(); - - currentDragHandle = event.target; - currentDragHandle.classList.add('igv-track-drag-handle-hover'); - - browser.startTrackDrag(this); - - } - - // Mouse Up - this.boundDocumentTrackDragMouseUpHandler = documentTrackDragMouseUpHandler.bind(this); - document.addEventListener('mouseup', this.boundDocumentTrackDragMouseUpHandler); - - function documentTrackDragMouseUpHandler(event) { - - browser.endTrackDrag(); - - if (currentDragHandle && event.target !== currentDragHandle) { - currentDragHandle.classList.remove('igv-track-drag-handle-hover'); - } - - currentDragHandle = undefined; - } - - // Mouse Enter - this.boundTrackDragMouseEnterHandler = trackDragMouseEnterHandler.bind(this); - this.dragHandle.addEventListener('mouseenter', this.boundTrackDragMouseEnterHandler); - - function trackDragMouseEnterHandler(event) { - event.preventDefault(); - - if (undefined === currentDragHandle) { - event.target.classList.add('igv-track-drag-handle-hover'); - } - - browser.updateTrackDrag(this); - - } - - // Mouse Out - this.dragHandle.addEventListener('mouseout', e => { - e.preventDefault(); - - if (undefined === currentDragHandle) { - e.target.classList.remove('igv-track-drag-handle-hover'); - } - }); - - this.boundTrackDragMouseOutHandler = trackDragMouseOutHandler.bind(this); - this.dragHandle.addEventListener('mouseout', this.boundTrackDragMouseOutHandler); - - function trackDragMouseOutHandler(event) { - event.preventDefault(); - - if (undefined === currentDragHandle) { - event.target.classList.remove('igv-track-drag-handle-hover'); - } - } - - } - - } - - removeTrackDragMouseHandlers() { - - if ('ideogram' === this.track.id || 'ruler' === this.track.id) ; else { - this.dragHandle.removeEventListener('mousedown', this.boundTrackDragMouseDownHandler); - document.removeEventListener('mouseup', this.boundDocumentTrackDragMouseUpHandler); - this.dragHandle.removeEventListener('mouseup', this.boundTrackDragMouseEnterHandler); - this.dragHandle.removeEventListener('mouseout', this.boundTrackDragMouseOutHandler); - } - - } - - addTrackGearMouseHandlers() { - if (true === this.track.ignoreTrackMenu) ; else { - - this.boundTrackGearClickHandler = trackGearClickHandler.bind(this); - this.gear.addEventListener('click', this.boundTrackGearClickHandler); - - function trackGearClickHandler(event) { - event.preventDefault(); - event.stopPropagation(); - this.trackGearPopup.presentMenuList(MenuUtils$1.trackMenuItemList(this)); - } - - } - - } - - removeTrackGearMouseHandlers() { - if (true === this.track.ignoreTrackMenu) ; else { - this.gear.removeEventListener('click', this.boundTrackGearClickHandler); - } - - } - - /** - * Do any cleanup here - */ - dispose() { - - this.removeAxisEventListener(this.axis); - this.axis.remove(); - - for (let viewport of this.viewports) { - viewport.dispose(); - } - - this.sampleNameViewport.dispose(); - - this.removeTrackScrollMouseHandlers(); - this.outerScroll.remove(); - - this.removeTrackDragMouseHandlers(); - this.dragHandle.remove(); - - this.removeTrackGearMouseHandlers(); - this.gearContainer.remove(); - - if (typeof this.track.dispose === "function") { - this.track.dispose(); - } - - for (let key of Object.keys(this)) { - this[key] = undefined; - } - - if (this.alert) { - this.alert.container.remove(); // This is quite obviously a hack, need a "dispose" method on AlertDialog - } - - this.disposed = true; - } - - paintAxis() { - - if (typeof this.track.paintAxis === 'function') { - - // Set the canvas buffer size, this is the resolution it is drawn at. This is done here in case the browser - // has been drug between screens at different dpi resolutions since the last repaint - const {width, height} = this.axisCanvas.getBoundingClientRect(); - const dpi = window.devicePixelRatio || 1; - this.axisCanvas.height = dpi * height; - this.axisCanvas.width = dpi * width; - - // Get a scaled context to draw aon - const axisCanvasContext = this.axisCanvas.getContext('2d'); - axisCanvasContext.scale(dpi, dpi); - - this.track.paintAxis(axisCanvasContext, width, height); - } - } - - maxViewportContentHeight() { - return Math.max(this.viewports.map(viewport => viewport.getContentHeight())) - } - - } - - function renderSVGAxis(context, track, axisCanvas, deltaX, deltaY) { - - if (typeof track.paintAxis === 'function') { - - const {y, width, height} = axisCanvas.getBoundingClientRect(); - - const str = (track.name || track.id).replace(/\W/g, ''); - const id = `${str}_axis_guid_${domUtils$1.guid()}`; - - context.saveWithTranslationAndClipRect(id, deltaX, y + deltaY, width, height, 0); - - track.paintAxis(context, width, height); - - context.restore(); - } - - } - - /* - * The MIT License (MIT) - * - * Copyright (c) 2014 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - const DEFAULT_COLOR$1 = 'rgb(150, 150, 150)'; - - class WigTrack extends TrackBase { - - static defaults = { - height: 50, - flipAxis: false, - logScale: false, - windowFunction: 'mean', - graphType: 'bar', - autoscale: true, - normalize: undefined, - scaleFactor: undefined - } - - constructor(config, browser) { - super(config, browser); - } - - init(config) { - - super.init(config); - - this.type = "wig"; - this.featureType = 'numeric'; - this.paintAxis = paintAxis; - - const format = config.format ? config.format.toLowerCase() : config.format; - if (config.featureSource) { - this.featureSource = config.featureSource; - delete config.featureSource; - } else if ("bigwig" === format) { - this.featureSource = new BWSource(config, this.browser.genome); - } else if ("tdf" === format) { - this.featureSource = new TDFSource(config, this.browser.genome); - } else { - this.featureSource = FeatureSource(config, this.browser.genome); - } - - - // Override autoscale default - if(config.max === undefined || config.autoscale === true) { - this.autoscale = true; - } else { - this.dataRange = { - min: config.min || 0, - max: config.max - }; - } - } - - async postInit() { - const header = await this.getHeader(); - if (this.disposed) return // This track was removed during async load - if (header) this.setTrackProperties(header); - } - - async getFeatures(chr, start, end, bpPerPixel) { - const features = await this.featureSource.getFeatures({ - chr, - start, - end, - bpPerPixel, - visibilityWindow: this.visibilityWindow, - windowFunction: this.windowFunction - }); - if (this.normalize && this.featureSource.normalizationFactor) { - const scaleFactor = this.featureSource.normalizationFactor; - for (let f of features) { - f.value *= scaleFactor; - } - } - if (this.scaleFactor) { - const scaleFactor = this.scaleFactor; - for (let f of features) { - f.value *= scaleFactor; - } - } - return features - } - - menuItemList() { - let items = []; - - if (this.flipAxis !== undefined) { - items.push('
'); - items.push({ - label: "Flip y-axis", - click: () => { - this.flipAxis = !this.flipAxis; - this.trackView.repaintViews(); - } - }); - } - - items = items.concat(MenuUtils$1.numericDataMenuItems(this.trackView)); - - return items - } - - async getHeader() { - - if (typeof this.featureSource.getHeader === "function") { - this.header = await this.featureSource.getHeader(); - } - return this.header - } - - // TODO: refactor to igvUtils.js - getScaleFactor(min, max, height, logScale) { - const scale = logScale ? height / (Math.log10(max + 1) - (min <= 0 ? 0 : Math.log10(min + 1))) : height / (max - min); - return scale - } - - computeYPixelValue(yValue, yScaleFactor) { - return (this.flipAxis ? (yValue - this.dataRange.min) : (this.dataRange.max - yValue)) * yScaleFactor - } - - computeYPixelValueInLogScale(yValue, yScaleFactor) { - let maxValue = this.dataRange.max; - let minValue = this.dataRange.min; - if (maxValue <= 0) return 0 // TODO: - if (minValue <= -1) minValue = 0; - minValue = (minValue <= 0) ? 0 : Math.log10(minValue + 1); - maxValue = Math.log10(maxValue + 1); - yValue = Math.log10(yValue + 1); - return ((this.flipAxis ? (yValue - minValue) : (maxValue - yValue)) * yScaleFactor) - } - - draw(options) { - - const features = options.features; - const ctx = options.context; - const bpPerPixel = options.bpPerPixel; - const bpStart = options.bpStart; - const pixelWidth = options.pixelWidth; - options.pixelHeight; - const bpEnd = bpStart + pixelWidth * bpPerPixel + 1; - const posColor = this.color || DEFAULT_COLOR$1; - - let baselineColor; - if (typeof posColor === "string" && posColor.startsWith("rgb(")) { - baselineColor = IGVColor.addAlpha(posColor, 0.1); - } - const scaleFactor = this.getScaleFactor(this.dataRange.min, this.dataRange.max, options.pixelHeight, this.logScale); - const yScale = (yValue) => this.logScale - ? this.computeYPixelValueInLogScale(yValue, scaleFactor) - : this.computeYPixelValue(yValue, scaleFactor); - - if (features && features.length > 0) { - - if (this.dataRange.min === undefined) this.dataRange.min = 0; - - // Max can be less than min if config.min is set but max left to autoscale. If that's the case there is - // nothing to paint. - if (this.dataRange.max > this.dataRange.min) { - - let lastPixelEnd = -1; - let lastY; - const y0 = yScale(0); - for (let f of features) { - - if (f.end < bpStart) continue - if (f.start > bpEnd) break - - const x = Math.floor((f.start - bpStart) / bpPerPixel); - if (isNaN(x)) continue - - let y = yScale(f.value); - - const rectEnd = Math.ceil((f.end - bpStart) / bpPerPixel); - const width = Math.max(1, rectEnd - x); - - const color = this.getColorForFeature(f); - - if (this.graphType === "points") { - const pointSize = this.config.pointSize || 3; - const px = x + width / 2; - IGVGraphics.fillCircle(ctx, px, y, pointSize / 2, {"fillStyle": color, "strokeStyle": color}); - - } else if (this.graphType === "line") { - if (lastY != undefined) { - IGVGraphics.strokeLine(ctx, lastPixelEnd, lastY, x, y, { - "fillStyle": color, - "strokeStyle": color - }); - } - IGVGraphics.strokeLine(ctx, x, y, x + width, y, {"fillStyle": color, "strokeStyle": color}); - } else { - const height = y - y0; - IGVGraphics.fillRect(ctx, x, y0, width, height, {fillStyle: color}); - - } - lastPixelEnd = x + width; - lastY = y; - } - - // If the track includes negative values draw a baseline - if (this.dataRange.min < 0) { - const basepx = (this.dataRange.max / (this.dataRange.max - this.dataRange.min)) * options.pixelHeight; - IGVGraphics.strokeLine(ctx, 0, basepx, options.pixelWidth, basepx, {strokeStyle: baselineColor}); - } - } - } - - // Draw guidelines - if (this.config.hasOwnProperty('guideLines')) { - for (let line of this.config.guideLines) { - if (line.hasOwnProperty('color') && line.hasOwnProperty('y') && line.hasOwnProperty('dotted')) { - let y = yScale(line.y); - let props = { - 'strokeStyle': line['color'], - 'strokeWidth': 2 - }; - if (line['dotted']) IGVGraphics.dashedLine(options.context, 0, y, options.pixelWidth, y, 5, props); - else IGVGraphics.strokeLine(options.context, 0, y, options.pixelWidth, y, props); - } - } - } - } - - popupData(clickState, features) { - - if (features === undefined) features = this.clickedFeatures(clickState); - - if (features && features.length > 0) { - - const genomicLocation = clickState.genomicLocation; - const popupData = []; - - // Sort features based on distance from click - features.sort(function (a, b) { - const distA = Math.abs((a.start + a.end) / 2 - genomicLocation); - const distB = Math.abs((b.start + b.end) / 2 - genomicLocation); - return distA - distB - }); - - // Display closest 10 - const displayFeatures = features.length > 10 ? features.slice(0, 10) : features; - - // Resort in ascending order - displayFeatures.sort(function (a, b) { - return a.start - b.start - }); - - for (let selectedFeature of displayFeatures) { - if (selectedFeature) { - if (popupData.length > 0) { - popupData.push('
'); - } - let posString = (selectedFeature.end - selectedFeature.start) === 1 ? - numberFormatter$1(selectedFeature.start + 1) - : numberFormatter$1(selectedFeature.start + 1) + "-" + numberFormatter$1(selectedFeature.end); - popupData.push({name: "Position:", value: posString}); - popupData.push({ - name: "Value:     ", - value: numberFormatter$1(selectedFeature.value) - }); - } - } - if (displayFeatures.length < features.length) { - popupData.push("
..."); - } - - return popupData - - } else { - return [] - } - } - - get supportsWholeGenome() { - return !this.config.indexURL && this.config.supportsWholeGenome !== false - } - - /** - * Return color for feature. - * @param feature - * @returns {string} - */ - - getColorForFeature(f) { - let c = (f.value < 0 && this.altColor) ? this.altColor : this.color || DEFAULT_COLOR$1; - return (typeof c === "function") ? c(f.value) : c - } - - /** - * Called when the track is removed. Do any needed cleanup here - */ - dispose() { - this.trackView = undefined; - } - - } - - /** - * - * @param cs - object containing - * 1) array of threshold values defining bin boundaries in ascending order - * 2) array of colors for bins (length == thresholds.length + 1) - * @constructor - */ - function BinnedColorScale(cs) { - this.thresholds = cs.thresholds; - this.colors = cs.colors; - } - - BinnedColorScale.prototype.getColor = function (value) { - - for (let threshold of this.thresholds) { - if (value < threshold) { - return this.colors[this.thresholds.indexOf(threshold)] - } - } - - return this.colors[this.colors.length - 1] - - }; - - /** - * - * @param scale - object with the following properties - * low - * lowR - * lowG - * lowB - * high - * highR - * highG - * highB - * - * @constructor - */ - function GradientColorScale(scale) { - - this.scale = scale; - this.lowColor = "rgb(" + scale.lowR + "," + scale.lowG + "," + scale.lowB + ")"; - this.highColor = "rgb(" + scale.highR + "," + scale.highG + "," + scale.highB + ")"; - this.diff = scale.high - scale.low; - - } - - GradientColorScale.prototype.getColor = function (value) { - - var scale = this.scale, r, g, b, frac; - - if (value <= scale.low) return this.lowColor - else if (value >= scale.high) return this.highColor - - frac = (value - scale.low) / this.diff; - r = Math.floor(scale.lowR + frac * (scale.highR - scale.lowR)); - g = Math.floor(scale.lowG + frac * (scale.highG - scale.lowG)); - b = Math.floor(scale.lowB + frac * (scale.highB - scale.lowB)); - - return "rgb(" + r + "," + g + "," + b + ")" - }; - - class ConstantColorScale { - constructor(color) { - this.color = color; - } - - getColor() { - return this.color - } - } - - /* - * The MIT License (MIT) - * - * Copyright (c) 2014 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - class SegTrack extends TrackBase { - - constructor(config, browser) { - super(config, browser); - } - - init(config) { - super.init(config); - - this.type = config.type || "seg"; - if (this.type === 'maf') this.type = 'mut'; - this.isLog = config.isLog; - this.displayMode = config.displayMode || "EXPANDED"; // EXPANDED | SQUISHED - this.height = config.height || 300; - this.maxHeight = config.maxHeight || 500; - this.squishedRowHeight = config.sampleSquishHeight || config.squishedRowHeight || 2; - this.expandedRowHeight = config.sampleExpandHeight || config.expandedRowHeight || 13; - this.sampleHeight = this.squishedRowHeight; // Initial value, will get overwritten when rendered - - if (config.color) { - this.color = config.color; - } else { - // Color scales for "seg" (copy number) tracks. - this.posColorScale = config.posColorScale || - new GradientColorScale({ - low: 0.1, - lowR: 255, - lowG: 255, - lowB: 255, - high: 1.5, - highR: 255, - highG: 0, - highB: 0 - }); - this.negColorScale = config.negColorScale || - new GradientColorScale({ - low: -1.5, - lowR: 0, - lowG: 0, - lowB: 255, - high: -0.1, - highR: 255, - highG: 255, - highB: 255 - }); - - // Default color table for mutation (mut and maf) tracks - if (this.type === "mut") { - this.colorTable = new ColorTable(config.colorTable || MUT_COLORS); - } - } - - this.sampleKeys = []; - this.sampleNames = new Map(); - if (config.samples) { - // Explicit setting, keys == names - for (let s of config.samples) { - this.sampleKeys.push(s); - this.sampleNames.set(s, s); - } - this.explicitSamples = true; - } - - // this.featureSource = config.sourceType === "bigquery" ? - // new igv.BigQueryFeatureSource(this.config) : - - // Disable whole genome downsampling unless explicitly. - const configCopy = Object.assign({}, this.config); - configCopy.maxWGCount = configCopy.maxWGCount || Number.MAX_SAFE_INTEGER; - this.featureSource = FeatureSource(configCopy, this.browser.genome); - - this.initialSort = config.sort; - } - - async postInit() { - if (typeof this.featureSource.getHeader === "function") { - this.header = await this.featureSource.getHeader(); - if(this.disposed) return; // This track was removed during async load - } - // Set properties from track line - if (this.header) { - this.setTrackProperties(this.header); - } - } - - - menuItemList() { - - const menuItems = []; - const lut = - { - "SQUISHED": "Squish", - "EXPANDED": "Expand", - "FILL": "Fill" - }; - - menuItems.push('
'); - menuItems.push("DisplayMode:"); - - const displayOptions = this.type === 'seg' ? ["SQUISHED", "EXPANDED", "FILL"] : ["SQUISHED", "EXPANDED"]; - - for (let displayMode of displayOptions) { - - const checkBox = createCheckbox$2(lut[displayMode], displayMode === this.displayMode); - menuItems.push( - { - object: $$1(checkBox), - click: () => { - this.displayMode = displayMode; - this.config.displayMode = displayMode; - this.trackView.checkContentHeight(); - this.trackView.repaintViews(); - this.trackView.moveScroller(this.trackView.sampleNameViewport.trackScrollDelta); - } - }); - } - - return menuItems - - } - - hasSamples() { - return true // SEG, MUT, and MAF tracks have samples by definition - } - - getSamples() { - return { - names: this.sampleKeys.map(key => this.sampleNames.get(key)), - height: this.sampleHeight, - yOffset: 0 - } - } - - async getFeatures(chr, start, end) { - const features = await this.featureSource.getFeatures({chr, start, end}); - if (this.initialSort) { - const sort = this.initialSort; - this.sortSamples(sort.chr, sort.start, sort.end, sort.direction, features); - this.initialSort = undefined; // Sample order is sorted, - } - return features - } - - - draw({context, renderSVG, pixelTop, pixelWidth, pixelHeight, features, bpPerPixel, bpStart}) { - - IGVGraphics.fillRect(context, 0, pixelTop, pixelWidth, pixelHeight, {'fillStyle': "rgb(255, 255, 255)"}); - - if (features && features.length > 0) { - - this.checkForLog(features); - - // New segments could conceivably add new samples - this.updateSampleKeys(features); - - // Create a map for fast id -> row lookup - const samples = {}; - this.sampleKeys.forEach(function (id, index) { - samples[id] = index; - }); - - let border; - switch (this.displayMode) { - case "FILL": - this.sampleHeight = pixelHeight / this.sampleKeys.length; - border = 0; - break - - case "SQUISHED": - this.sampleHeight = this.squishedRowHeight; - border = 0; - break - default: // EXPANDED - this.sampleHeight = this.expandedRowHeight; - border = 1; - } - const rowHeight = this.sampleHeight; - - - // this.featureMap = new Map() - - for (let segment of features) { - segment.pixelRect = undefined; // !important, reset this in case segment is not drawn - } - - const pixelBottom = pixelTop + pixelHeight; - const bpEnd = bpStart + pixelWidth * bpPerPixel + 1; - const xScale = bpPerPixel; - - this.sampleYStart = undefined; - for (let f of features) { - - if (f.end < bpStart) continue - if (f.start > bpEnd) break - - const sampleKey = f.sampleKey || f.sample; - f.row = samples[sampleKey]; - const y = f.row * rowHeight + border; - - if (undefined === this.sampleYStart) { - this.sampleYStart = y; - } - - const bottom = y + rowHeight; - - if (bottom < pixelTop || y > pixelBottom) { - continue - } - - const segmentStart = Math.max(f.start, bpStart); - // const segmentStart = segment.start; - let x = Math.round((segmentStart - bpStart) / xScale); - - const segmentEnd = Math.min(f.end, bpEnd); - // const segmentEnd = segment.end; - const x1 = Math.round((segmentEnd - bpStart) / xScale); - let w = Math.max(1, x1 - x); - - let color; - if (this.color) { - if (typeof this.color === "function") { - color = this.color(f); - } else { - color = this.color; - } - } else if (this.colorTable) { - color = this.colorTable.getColor(f.value.toLowerCase()); - } - - let h; - if ("mut" === this.type) { - h = rowHeight - 2 * border; - if (w < 3) { - w = 3; - x -= 1; - } - } else { - // Assume seg track - let value = f.value; - if (!this.isLog) { - value = IGVMath.log2(value / 2); - } - if (value < -0.1) { - color = this.negColorScale.getColor(value); - } else if (value > 0.1) { - color = this.posColorScale.getColor(value); - } else { - color = "white"; - } - - let sh = rowHeight; - if (rowHeight < 0.25) { - const f = 0.1 + 2 * Math.abs(value); - sh = Math.min(1, f * rowHeight); - } - h = sh - 2 * border; - } - - - f.pixelRect = {x, y, w, h}; - - // Use for diagnostic rendering - // context.fillStyle = randomRGB(180, 240) - // context.fillStyle = randomGrey(200, 255) - context.fillStyle = color; - context.fillRect(x, y, w, h); - } - - } - - } - - - checkForLog(features) { - if (this.isLog === undefined) { - this.isLog = false; - for (let feature of features) { - if (feature.value < 0) { - this.isLog = true; - return - } - } - } - } - - /** - * Optional method to compute pixel height to accomodate the list of features. The implementation below - * has side effects (modifiying the samples hash). This is unfortunate, but harmless. - * - * Note displayMode "FILL" is handled by the viewport - * - * @param features - * @returns {number} - */ - computePixelHeight(features) { - if (!features) return 0 - const sampleHeight = ("SQUISHED" === this.displayMode) ? this.squishedRowHeight : this.expandedRowHeight; - this.updateSampleKeys(features); - return this.sampleKeys.length * sampleHeight - } - - /** - * Sort samples by the average value over the genomic range in the direction indicated (1 = ascending, -1 descending) - */ - async sortSamples(chr, start, end, direction, featureList) { - - if (!featureList) { - featureList = await this.featureSource.getFeatures({chr, start, end}); - } - if (!featureList) return - - this.updateSampleKeys(featureList); - - const scores = {}; - const d2 = (direction === "ASC" ? 1 : -1); - - const sortSeg = () => { - // Compute weighted average score for each sample - const bpLength = end - start + 1; - for (let segment of featureList) { - if (segment.end < start) continue - if (segment.start > end) break - const min = Math.max(start, segment.start); - const max = Math.min(end, segment.end); - const f = (max - min) / bpLength; - const sampleKey = segment.sampleKey || segment.sample; - const s = scores[sampleKey] || 0; - scores[sampleKey] = s + f * segment.value; - } - - // Now sort sample names by score - this.sampleKeys.sort(function (a, b) { - let s1 = scores[a]; - let s2 = scores[b]; - if (!s1) s1 = d2 * Number.MAX_VALUE; - if (!s2) s2 = d2 * Number.MAX_VALUE; - if (s1 === s2) return 0 - else if (s1 > s2) return d2 - else return d2 * -1 - }); - }; - - const sortMut = () => { - // Compute weighted average score for each sample - for (let segment of featureList) { - if (segment.end < start) continue - if (segment.start > end) break - const sampleKey = segment.sampleKey || segment.sample; - if (!scores.hasOwnProperty(sampleKey) || segment.value.localeCompare(scores[sampleKey]) > 0) { - scores[sampleKey] = segment.value; - } - } - // Now sort sample names by score - this.sampleKeys.sort(function (a, b) { - let sa = scores[a] || ""; - let sb = scores[b] || ""; - return d2 * (sa.localeCompare(sb)) - }); - }; - - if ("mut" === this.type) { - sortMut(); - } else { - sortSeg(); - } - - this.trackView.repaintViews(); - - } - - clickedFeatures(clickState) { - - const allFeatures = super.clickedFeatures(clickState); - const y = clickState.y; - return allFeatures.filter(function (feature) { - const rect = feature.pixelRect; - return rect && y >= rect.y && y <= (rect.y + rect.h) - }) - - } - - hoverText(clickState) { - const features = this.clickedFeatures(clickState); - if(features && features.length > 0) { - return `${features[0].sample}: ${features[0].value}` - } - } - - popupData(clickState, featureList) { - - if(featureList === undefined) featureList = this.clickedFeatures(clickState); - - const items = []; - - for (let feature of featureList) { - - // Double line divider between features - if (items.length > 0) { - items.push('
'); - items.push('
'); - } - - // hack for whole genome features, which save the original feature as "_f" - const f = feature._f || feature; - - const data = (typeof f.popupData === 'function') ? - f.popupData(this.type, this.browser.genome.id) : - this.extractPopupData(f); - Array.prototype.push.apply(items, data); - - } - - return items - } - - contextMenuItemList(clickState) { - - const referenceFrame = clickState.viewport.referenceFrame; - const genomicLocation = clickState.genomicLocation; - - // Define a region 5 "pixels" wide in genomic coordinates - const sortDirection = this.config.sort ? - (this.config.sort.direction === "ASC" ? "DESC" : "ASC") : // Toggle from previous sort - "DESC"; - const bpWidth = referenceFrame.toBP(2.5); - - const sortHandler = (sort) => { - const viewport = clickState.viewport; - const features = viewport.cachedFeatures; - this.sortSamples(sort.chr, sort.start, sort.end, sort.direction, features); - }; - - const sortLabel = this.type === 'seg' ? 'Sort by value' : 'Sort by type'; - - return [ - { - label: sortLabel, click: (e) => { - - - const sort = { - direction: sortDirection, - chr: clickState.viewport.referenceFrame.chr, - start: genomicLocation - bpWidth, - end: genomicLocation + bpWidth - - }; - - sortHandler(sort); - - this.config.sort = sort; - - } - }] - - } - - get supportsWholeGenome() { - return (this.config.indexed === false || !this.config.indexURL) && this.config.supportsWholeGenome !== false - } - - updateSampleKeys(featureList) { - - if (this.explicitSamples) return - - for (let feature of featureList) { - const sampleKey = feature.sampleKey || feature.sample; - if (!this.sampleNames.has(sampleKey)) { - this.sampleNames.set(sampleKey, feature.sample); - this.sampleKeys.push(sampleKey); - } - } - } - } - - // Mut and MAF file default color table - - const MUT_COLORS = { - - "indel": "rgb(0,200,0)", - "targeted region": "rgb(236,155,43)", - "truncating": "rgb( 150,0,0)", - "non-coding transcript": "rgb(0,0,150)", - - // Colors from https://www.nature.com/articles/nature11404 - "synonymous": "rgb(109,165,95)", - "silent": "rgb(109,135,80)", - "missense_mutation": "rgb(72,130,187)", - "missense": "rgb(72,130,187)", - "splice site": "rgb(143,83,155)", - "splice_region": "rgb(143,83,155)", - "nonsense": "rgb(216, 57,81)", - "nonsense_mutation": "rgb(216, 57,81)", - "frame_shift_del": "rgb(226,135,65)", - "frame_shift_ins": "rgb(226,135,65)", - "in_frame_del": "rgb(247,235,94)", - "in_frame_ins": "rgb(247,235,94)", - "*other*": "rgb(159,91,50)" - // - // 3'Flank - // 3'UTR - // 5'Flank - // 5'UTR - // Frame_Shift_Del - // Frame_Shift_Ins - // IGR - // In_Frame_Del - // In_Frame_Ins - // Intron - // Missense_Mutation - // Nonsense_Mutation - // Nonstop_Mutation - // RNA - // Silent - // Splice_Region - // Splice_Site - // Translation_Start_Site - // Variant_Classification - - }; - - /* - * The MIT License (MIT) - * - * Copyright (c) 2016-2017 The Regents of the University of California - * Author: Jim Robinson - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - - /** - * Represents 2 or more wig tracks overlaid on a common viewport. - */ - class MergedTrack extends TrackBase { - - constructor(config, browser) { - super(config, browser); - this.type = "merged"; - this.featureType = 'numeric'; - this.paintAxis = paintAxis; - this.graphType = config.graphType; - } - - init(config) { - if (!config.tracks) { - throw Error("Error: no tracks defined for merged track" + config) - } - - super.init(config); - } - - async postInit() { - - this.tracks = []; - const p = []; - for (let tconf of this.config.tracks) { - tconf.isMergedTrack = true; - const t = await this.browser.createTrack(tconf); - if (t) { - t.autoscale = false; // Scaling done from merged track - this.tracks.push(t); - } else { - console.warn("Could not create track " + tconf); - } - - if (typeof t.postInit === 'function') { - p.push(t.postInit()); - } - } - - this.flipAxis = this.config.flipAxis ? this.config.flipAxis : false; - this.logScale = this.config.logScale ? this.config.logScale : false; - this.autoscale = this.config.autoscale || this.config.max === undefined; - if (!this.autoscale) { - this.dataRange = { - min: this.config.min || 0, - max: this.config.max - }; - } - for (let t of this.tracks) { - t.autoscale = false; - t.dataRange = this.dataRange; - } - - this.height = this.config.height || 50; - - return Promise.all(p) - } - - get height() { - return this._height - } - - set height(h) { - this._height = h; - if (this.tracks) { - for (let t of this.tracks) { - t.height = h; - t.config.height = h; - } - } - } - - menuItemList() { - let items = []; - if (this.flipAxis !== undefined) { - items.push({ - label: "Flip y-axis", - click: () => { - this.flipAxis = !this.flipAxis; - this.trackView.repaintViews(); - } - }); - } - - items = items.concat(MenuUtils$1.numericDataMenuItems(this.trackView)); - - return items - } - - /** - * Returns a MergedFeatureCollection containing an array of features for the specified range, 1 for each track. - */ - async getFeatures(chr, bpStart, bpEnd, bpPerPixel) { - - const promises = this.tracks.map((t) => t.getFeatures(chr, bpStart, bpEnd, bpPerPixel)); - const featureArrays = await Promise.all(promises); - return new MergedFeatureCollection(featureArrays) - } - - draw(options) { - - const mergedFeatures = options.features; // A MergedFeatureCollection - - for (let i = 0, len = this.tracks.length; i < len; i++) { - const trackOptions = Object.assign({}, options); - trackOptions.features = mergedFeatures.featureArrays[i]; - this.tracks[i].dataRange = this.dataRange; - this.tracks[i].flipAxis = this.flipAxis; - this.tracks[i].logScale = this.logScale; - if (this.graphType) { - this.tracks[i].graphType = this.graphType; - } - this.tracks[i].draw(trackOptions); - } - } - - popupData(clickState) { - - if(clickState.viewport && clickState.viewport.cachedFeatures) { - - const featuresArray = clickState.viewport.cachedFeatures.featureArrays; - - if (featuresArray && featuresArray.length === this.tracks.length) { - // Array of feature arrays, 1 for each track - const popupData = []; - for (let i = 0; i < this.tracks.length; i++) { - if (i > 0) popupData.push('
'); - popupData.push(`
${this.tracks[i].name}
`); - const trackPopupData = this.tracks[i].popupData(clickState, featuresArray[i]); - popupData.push(...trackPopupData); - - } - return popupData - } - } - } - - clickedFeatures(clickState) { - - - // We use the cached features rather than method to avoid async load. If the - // feature is not already loaded this won't work, but the user wouldn't be mousing over it either. - const mergedFeaturesCollection = clickState.viewport.cachedFeatures; - - if(!mergedFeaturesCollection) { - return []; - } - - const genomicLocation = clickState.genomicLocation; - const clickedFeatures = []; - for(let features of mergedFeaturesCollection.featureArrays) { - // When zoomed out we need some tolerance around genomicLocation - const tolerance = (clickState.referenceFrame.bpPerPixel > 0.2) ? 3 * clickState.referenceFrame.bpPerPixel : 0.2; - const ss = genomicLocation - tolerance; - const ee = genomicLocation + tolerance; - const tmp = (FeatureUtils.findOverlapping(features, ss, ee)); - for(let f of tmp) { - clickedFeatures.push(f); - } - } - return clickedFeatures; - } - - - get supportsWholeGenome() { - return this.tracks.every(track => track.supportsWholeGenome) - } - } - - - class MergedFeatureCollection { - - constructor(featureArrays) { - this.featureArrays = featureArrays; - } - - getMax(start, end) { - let max = -Number.MAX_VALUE; - for (let a of this.featureArrays) { - for (let f of a) { - if (typeof f.value !== 'undefined' && !Number.isNaN(f.value)) { - if (f.end < start) { - continue - } - if (f.start > end) { - break - } - max = Math.max(max, f.value); - } - } - } - return max - } - - } - - /* - * The MIT License (MIT) - * - * Copyright (c) 2016-2018 The Regents of the University of California - * Author: Jim Robinson - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - function getArcType(config) { - if (!config.arcType) { - return "nested" - } - switch (config.arcType) { - case "chiapet": - return "inView" - case "chiapetoutbound": - return "partialInView" - default: - return config.arcType - } - } - - const DEFAULT_ARC_COLOR = "rgb(180,25,137)"; - - class InteractionTrack extends TrackBase { - - static defaults = { - height: 250, - theta: Math.PI / 4, - arcOrientation: true, - showBlocks: true, - blockHeight: 3, - thickness: 1, - alpha: 0.02, - logScale: true, - } - - constructor(config, browser) { - super(config, browser); - } - - init(config) { - - super.init(config); - - this.sinTheta = Math.sin(this.theta); - this.cosTheta = Math.cos(this.theta); - this.arcType = getArcType(config); // nested | proportional | inView | partialInView - this.alpha = config.alpha || 0.02; // was: 0.15 - this.painter = {flipAxis: !this.arcOrientation, dataRange: this.dataRange, paintAxis: paintAxis}; - - if (config.valueColumn) { - this.valueColumn = config.valueColumn; - this.hasValue = true; - } else if (config.useScore) { - this.hasValue = true; - this.valueColumn = "score"; - } - - if (config.max) { - this.dataRange = { - min: config.min || 0, - max: config.max - }; - this.autoscale = false; - } else { - this.autoscale = true; - } - - // Create the FeatureSource and override the default whole genome method - if (config.featureSource) { - this.featureSource = config.featureSource; - delete config._featureSource; - } else { - this.featureSource = FeatureSource(config, this.browser.genome); - this.featureSource.getWGFeatures = getWGFeatures; - } - } - - async postInit() { - - if (typeof this.featureSource.getHeader === "function") { - this.header = await this.featureSource.getHeader(); - if (this.disposed) return; // This track was removed during async load - } - - // Set properties from track line - if (this.header) { - this.setTrackProperties(this.header); - } - - if (this.visibilityWindow === undefined && typeof this.featureSource.defaultVisibilityWindow === 'function') { - this.visibilityWindow = await this.featureSource.defaultVisibilityWindow(); - this.featureSource.visibilityWindow = this.visibilityWindow; // <- this looks odd - } - - return this - } - - get supportsWholeGenome() { - return true - } - - async getFeatures(chr, start, end) { - const visibilityWindow = this.visibilityWindow; - const features = await this.featureSource.getFeatures({chr, start, end, visibilityWindow}); - - // Check for score or value - if (this.hasValue === undefined && features && features.length > 0) { - this.hasValue = features[0].score !== undefined; - } - - return features - } - - draw(options) { - - if (this.arcType === "proportional") { - this.drawProportional(options); - } else if (this.arcType === "inView" || this.arcType === "partialInView") { - this.drawProportional(options); - } else { - this.drawNested(options); - } - } - - drawNested(options) { - - const ctx = options.context; - const pixelWidth = options.pixelWidth; - const pixelHeight = options.pixelHeight; - const viewportWidth = options.viewportWidth; - const bpPerPixel = options.bpPerPixel; - const bpStart = options.bpStart; - const xScale = bpPerPixel; - - IGVGraphics.fillRect(ctx, 0, options.pixelTop, pixelWidth, pixelHeight, {'fillStyle': "rgb(255, 255, 255)"}); - - const featureList = options.features; - - if (featureList) { - - // Autoscale theta - autoscaleNested.call(this); - const y = this.arcOrientation ? options.pixelHeight : 0; - const direction = this.arcOrientation; - - ctx.font = "8px sans-serif"; - ctx.textAlign = "center"; - - for (let feature of featureList) { - - // Reset transient property drawState. An undefined value => feature has not been drawn. - feature.drawState = undefined; - - let color; - if (typeof this.color === 'function') { - color = this.color(feature); - } else { - color = this.color || feature.color || DEFAULT_ARC_COLOR; - if (color && this.config.useScore) { - color = getAlphaColor(color, scoreShade(feature.score)); - } - } - - ctx.lineWidth = feature.thickness || this.thickness || 1; - - if (feature.chr1 === feature.chr2 || feature.chr === 'all') { - - const {m1, m2} = getMidpoints(feature, this.browser.genome); - - let pixelStart = Math.round((m1 - bpStart) / xScale); - let pixelEnd = Math.round((m2 - bpStart) / xScale); - if (pixelEnd < 0 || pixelStart > pixelWidth) continue - - let w = (pixelEnd - pixelStart); - if (w < 3) { - w = 3; - pixelStart--; - } - - const a = w / 2; - const r = a / this.sinTheta; - const b = this.cosTheta * r; - const xc = pixelStart + a; - - let yc, startAngle, endAngle; - if (direction) { // UP - yc = this.height + b; - startAngle = Math.PI + Math.PI / 2 - this.theta; - endAngle = Math.PI + Math.PI / 2 + this.theta; - } else { // DOWN - yc = -b; - startAngle = Math.PI / 2 - this.theta; - endAngle = Math.PI / 2 + this.theta; - } - - if (this.showBlocks && feature.chr !== 'all') { - const s1 = (feature.start1 - bpStart) / xScale; - const e1 = (feature.end1 - bpStart) / xScale; - const s2 = (feature.start2 - bpStart) / xScale; - const e2 = (feature.end2 - bpStart) / xScale; - const hb = this.arcOrientation ? -this.blockHeight : this.blockHeight; - ctx.fillRect(s1, y, e1 - s1, hb); - ctx.fillRect(s2, y, e2 - s2, hb); - } - - // Alpha shade (de-emphasize) arcs that extend beyond viewport, unless alpha shading is used for score. - if (color && !this.config.useScore && w > viewportWidth) { - color = getAlphaColor(color, this.alpha); - } - ctx.strokeStyle = color; - ctx.fillStyle = color; - ctx.beginPath(); - ctx.arc(xc, yc, r, startAngle, endAngle, false); - ctx.stroke(); - feature.drawState = {xc, yc, r}; - } else { - - let pixelStart = Math.round((feature.start - bpStart) / xScale); - let pixelEnd = Math.round((feature.end - bpStart) / xScale); - if (pixelEnd < 0 || pixelStart > pixelWidth) continue - - let w = (pixelEnd - pixelStart); - if (w < 3) { - w = 3; - pixelStart--; - } - const otherChr = feature.chr === feature.chr1 ? feature.chr2 : feature.chr1; - ctx.strokeStyle = color; - // get a sense of trans "spread" - ctx.fillStyle = getAlphaColor(getChrColor(otherChr), 0.5); - // ctx.fillStyle = color - - if (direction) { - // UP - ctx.fillRect(pixelStart, this.height / 2, w, this.height / 2); - ctx.fillText(otherChr, pixelStart + w / 2, this.height / 2 - 5); - feature.drawState = {x: pixelStart, y: this.height / 2, w: w, h: this.height / 2}; - } else { - ctx.fillRect(pixelStart, 0, w, this.height / 2); - ctx.fillText(otherChr, pixelStart + w / 2, this.height / 2 + 13); - feature.drawState = {x: pixelStart, y: 0, w: w, h: this.height / 2}; - } - } - } - } - - function autoscaleNested() { - let max = 0; - for (let feature of featureList) { - let pixelStart = (feature.start - bpStart) / xScale; - let pixelEnd = (feature.end - bpStart) / xScale; - if (pixelStart >= 0 && pixelEnd <= pixelWidth) { - max = Math.max(max, pixelEnd - pixelStart); - } - } - let a = Math.min(viewportWidth, max) / 2; - if (max > 0) { - let coa = (pixelHeight - 10) / a; - this.theta = estimateTheta(coa); - this.sinTheta = Math.sin(this.theta); - this.cosTheta = Math.cos(this.theta); - } - } - } - - getScaleFactor(min, max, height, logScale) { - const scale = logScale ? height / (Math.log10(max + 1) - (min <= 0 ? 0 : Math.log10(min + 1))) : height / (max - min); - return scale - } - - drawProportional(options) { - - const ctx = options.context; - const pixelWidth = options.pixelWidth; - const pixelHeight = options.pixelHeight; - const bpPerPixel = options.bpPerPixel; - const bpStart = options.bpStart; - const xScale = bpPerPixel; - const refStart = options.referenceFrame.start; - const refEnd = options.referenceFrame.end; - - - IGVGraphics.fillRect(ctx, 0, options.pixelTop, pixelWidth, pixelHeight, {'fillStyle': "rgb(255, 255, 255)"}); - - const featureList = options.features; - - if (featureList && featureList.length > 0) { - - // we use the min as a filter but not moving the axis - const effectiveMin = 0; - const yScale = this.getScaleFactor(effectiveMin, this.dataRange.max, options.pixelHeight - 1, this.logScale); - const y = this.arcOrientation ? options.pixelHeight : 0; - - for (let feature of featureList) { - - // Reset transient property drawState. An undefined value => feature has not been drawn. - feature.drawState = undefined; - - const value = this.valueColumn ? feature[this.valueColumn] : feature.score; - if (value === undefined || Number.isNaN(value)) continue - - const radiusY = Math.round((this.logScale ? Math.log10(value + 1) : value) * yScale); - - if (feature.chr1 === feature.chr2 || feature.chr === 'all') { - - const {m1, m2} = getMidpoints(feature, this.browser.genome); - - let pixelStart = Math.round((m1 - bpStart) / xScale); - let pixelEnd = Math.round((m2 - bpStart) / xScale); - let w = (pixelEnd - pixelStart); - if (w < 3) { - w = 3; - pixelStart--; - } - - // Various filters - if (value < this.dataRange.min || value > this.dataRange.max) continue - if ("proportional" !== this.arcType) { - const showOutbound = (this.arcType === "partialInView"); - const within = (m1 >= refStart && m2 <= refEnd); - let outBound = false; - let inBound = false; - if (!within && showOutbound) { - outBound = (refStart <= m1 && m1 <= refEnd); - if (!outBound) inBound = (refStart <= m2 && m2 <= refEnd); - } - if (!(within || outBound || inBound)) continue - } - - - const radiusX = w / 2; - const xc = pixelStart + w / 2; - feature.drawState = {xc, yc: y, radiusX, radiusY}; - - // const arcKey = ((pixelStart << 16) | pixelEnd) - // let arc = arcCaches.get(arcKey) - // if (arc !== undefined) { - // if (arc.has(radiusY)) { - // continue - // } - // arc.add(radiusY) - // } else { - // let arcHeights = new Set() - // arcHeights.add(radiusY) - // arcCaches.set(arcKey, arcHeights) - // } - - const counterClockwise = this.arcOrientation ? true : false; - const color = feature.color || this.color; - ctx.strokeStyle = color; - ctx.lineWidth = feature.thickness || this.thickness || 1; - - if (true === ctx.isSVG) { - ctx.strokeEllipse(xc, y, radiusX, radiusY, 0, 0, Math.PI, counterClockwise); - } else { - ctx.beginPath(); - ctx.ellipse(xc, y, radiusX, radiusY, 0, 0, Math.PI, counterClockwise); - ctx.stroke(); - } - - if (this.alpha) { - ctx.fillStyle = getAlphaColor(color, this.alpha); - if (true === ctx.isSVG) { - ctx.fillEllipse(xc, y, radiusX, radiusY, 0, 0, Math.PI, counterClockwise); - } else { - ctx.fill(); - } - } - - if (this.showBlocks && feature.chr !== 'all') { - ctx.fillStyle = color; - const s1 = (feature.start1 - bpStart) / xScale; - const e1 = (feature.end1 - bpStart) / xScale; - const s2 = (feature.start2 - bpStart) / xScale; - const e2 = (feature.end2 - bpStart) / xScale; - const hb = this.arcOrientation ? -this.blockHeight : this.blockHeight; - ctx.fillRect(s1, y, e1 - s1, hb); - ctx.fillRect(s2, y, e2 - s2, hb); - } - - } else { - // Inter chromosome - let pixelStart = Math.round((feature.start - bpStart) / xScale); - let pixelEnd = Math.round((feature.end - bpStart) / xScale); - if (pixelEnd < 0 || pixelStart > pixelWidth || value < this.dataRange.min || value > this.dataRange.max) continue - - const h = Math.min(radiusY, this.height - 13); // Leave room for text - let w = (pixelEnd - pixelStart); - if (w < 3) { - w = 3; - pixelStart--; - } - const otherChr = feature.chr === feature.chr1 ? feature.chr2 : feature.chr1; - ctx.font = "8px sans-serif"; - ctx.textAlign = "center"; - // get a sense of trans "spread" - ctx.fillStyle = getAlphaColor(getChrColor(otherChr), 0.5); - if (this.arcOrientation) { - // UP - const y = this.height - h; - ctx.fillRect(pixelStart, y, w, h); - ctx.fillText(otherChr, pixelStart + w / 2, y - 5); - feature.drawState = {x: pixelStart, y, w, h}; - } else { - ctx.fillRect(pixelStart, 0, w, h); - ctx.fillText(otherChr, pixelStart + w / 2, h + 13); - feature.drawState = {x: pixelStart, y: 0, w, h}; - } - } - } - } - } - - clearAxis(ctx, pixelWidth, pixelHeight) { - IGVGraphics.fillRect(ctx, 0, 0, pixelWidth, pixelHeight, {'fillStyle': "rgb(255, 255, 255)"}); - } - - paintAxis(ctx, pixelWidth, pixelHeight) { - // dataRane is interpreted differently for interactino tracks -- all arcs are drawn from "zero", irrespective of dataRange.min - const axisRange = {min: 0, max: this.dataRange.max}; - if (this.arcType === "proportional") { - this.painter.flipAxis = !this.arcOrientation; - this.painter.dataRange = axisRange; - this.painter.paintAxis(ctx, pixelWidth, pixelHeight); - } else if (this.arcType === "inView" || this.arcType === "partialInView") { - this.painter.flipAxis = !this.arcOrientation; - this.painter.dataRange = axisRange; - this.painter.paintAxis(ctx, pixelWidth, pixelHeight); - } else { - this.clearAxis(ctx, pixelWidth, pixelHeight); - } - } - - menuItemList() { - - let items = []; - - if (this.hasValue) { - items.push("
"); - const lut = - { - "nested": "Nested", - "proportional": "Proportional - All", - "inView": "Proportional - Both Ends in View", - "partialInView": "Proportional - One End in View" - }; - items.push("Arc Type"); - for (let arcType of ["nested", "proportional", "inView", "partialInView"]) { - items.push( - { - object: $$1(createCheckbox$2(lut[arcType], arcType === this.arcType)), - click: () => { - this.arcType = arcType; - this.trackView.repaintViews(); - } - }); - } - } - items.push("
"); - - items.push({ - name: "Toggle arc direction", - click: () => { - this.arcOrientation = !this.arcOrientation; - this.trackView.repaintViews(); - } - }); - items.push({ - name: this.showBlocks ? "Hide Blocks" : "Show Blocks", - click: () => { - this.showBlocks = !this.showBlocks; - this.trackView.repaintViews(); - } - }); - - - if (this.arcType === "proportional" || this.arcType === "inView" || this.arcType === "partialInView") { - // MenuUtils.numericDataMenuItems(this.trackView).forEach(item => items.push(item)) - items = items.concat(MenuUtils$1.numericDataMenuItems(this.trackView)); - } - - if (this.browser.circularView) { - items.push('
'); - items.push({ - label: 'Add interactions to circular view', - click: () => { - for (let viewport of this.trackView.viewports) { - this.addChordsForViewport(viewport.referenceFrame); - } - } - }); - } - - return items - } - - contextMenuItemList(clickState) { - - // Experimental JBrowse feature - if (this.browser.circularView) { - const viewport = clickState.viewport; - const list = []; - - list.push({ - label: 'Add interactions to circular view', - click: () => { - const refFrame = viewport.referenceFrame; - // first pass: to get all the relevant features - this.addChordsForViewport(refFrame); - } - }); - - list.push('
'); - return list - } - } - - /** - * Add chords to the circular view for the given viewport, represented by its reference frame - * @param refFrame - */ - addChordsForViewport(refFrame) { - const cachedFeatures = "all" === refFrame.chr ? - this.featureSource.getAllFeatures() : - this.featureSource.featureCache.queryFeatures(refFrame.chr, refFrame.start, refFrame.end); - - // inView features are simply features that have been drawn, i.e. have a drawState - const inView = cachedFeatures.filter(f => f.drawState); - if (inView.length === 0) return; - - const chords = makeBedPEChords(inView); - sendChords(chords, this, refFrame, 0.5); - // - // - // // for filtered set, distinguishing the chromosomes is more critical than tracks - // const chordSetColor = IGVColor.addAlpha("all" === refFrame.chr ? this.color : getChrColor(refFrame.chr), 0.5) - // const trackColor = IGVColor.addAlpha(this.color, 0.5) - // - // // name the chord set to include locus and filtering information - // const encodedName = this.name.replaceAll(' ', '%20') - // const chordSetName = "all" === refFrame.chr ? - // encodedName : - // `${encodedName} (${refFrame.chr}:${refFrame.start}-${refFrame.end} ; range:${this.dataRange.min}-${this.dataRange.max})` - // this.browser.circularView.addChords(chords, {track: chordSetName, color: chordSetColor, trackColor: trackColor}) - } - - doAutoscale(features) { - - // if ("proportional" === this.arcType) { - let max = 0; - if (features) { - for (let f of features) { - const v = this.valueColumn ? f[this.valueColumn] : f.score; - if (!Number.isNaN(v)) { - max = Math.max(max, v); - } - } - } - return {min: 0, max: max} - // } - } - - popupData(clickState, features) { - - if (features === undefined) features = this.clickedFeatures(clickState); - - const data = []; - for (let feature of features) { - - const f = feature._ || feature; // For "whole genome" features, which keeps a pointer to the original - - data.push({name: "Region 1", value: positionString(f.chr1, f.start1, f.end1, f.strand1)}); - data.push({name: "Region 2", value: positionString(f.chr2, f.start2, f.end2, f.strand2)}); - if (f.name) { - data.push({name: "Name", value: f.name}); - } - if (f.value !== undefined) { - data.push({name: "Value", value: f.value}); - } - if (f.score !== undefined) { - data.push({name: "Score", value: f.score}); - } - - - if (f.extras && this.header && this.header.columnNames) { - const columnNames = this.header.columnNames; - const stdColumns = this.header.hiccups ? 6 : 10; - for (let i = stdColumns; i < columnNames.length; i++) { - if (this.header.colorColumn === i) continue; - if (columnNames[i] === 'info') { - extractInfoColumn(data, f.extras[i - stdColumns]); - } else { - data.push({name: columnNames[i], value: f.extras[i - stdColumns]}); - } - } - } - // For now just return the top hit - break - - //if (data.length > 0) { - // data.push("
"); - // } - } - return data - } - - clickedFeatures(clickState) { - - // We use the cached features rather than method to avoid async load. If the - // feature is not already loaded this won't work, but the user wouldn't be mousing over it either. - const featureList = clickState.viewport.cachedFeatures; - const candidates = []; - if (featureList) { - const proportional = (this.arcType === "proportional" || this.arcType === "inView" || this.arcType === "partialInView"); - - for (let feature of featureList) { - - if (!feature.drawState) continue - - if (feature.chr1 === feature.chr2 || feature.chr === 'all') { - if (proportional) { - //(x-xc)^2/radiusX^2 + (y-yc)^2/radiusY^2 <= 1 - const {xc, yc, radiusX, radiusY} = feature.drawState; - const dx = clickState.canvasX - xc; - const dy = clickState.canvasY - yc; - const score = (dx / radiusX) * (dx / radiusX) + (dy / radiusY) * (dy / radiusY); - if (score <= 1) { - candidates.push({score: 1 / score, feature}); - } - } else { - const {xc, yc, r} = feature.drawState; - const dx = clickState.canvasX - xc; - const dy = clickState.canvasY - yc; - const score = Math.abs(Math.sqrt(dx * dx + dy * dy) - r); - if (score < 5) { - candidates.push({score, feature}); - } - } - } else { - const {x, y, w, h} = feature.drawState; - const tolerance = 5; - if (clickState.canvasX >= x - tolerance && clickState.canvasX <= x + w + tolerance && - clickState.canvasY >= y && clickState.canvasY <= y + h) { - const score = -Math.abs(clickState.canvasX - (x + w / 2)); - candidates.push({score, feature}); - break - } - } - } - } - - if (candidates.length > 1) { - candidates.sort((a, b) => a.score - b.score); - } - return candidates.map((c) => c.feature) - } - } - - function getMidpoints(feature, genome) { - let m1 = (feature.start1 + feature.end1) / 2; - let m2 = (feature.start2 + feature.end2) / 2; - if (feature.chr === 'all') { - m1 = genome.getGenomeCoordinate(feature.chr1, m1); - m2 = genome.getGenomeCoordinate(feature.chr2, m2); - } - if (m1 > m2) { - const tmp = m1; - m1 = m2; - m2 = tmp; - } - return {m1, m2} - } - - function positionString(chr, start, end, strand) { - - return strand && strand !== '.' ? - `${chr}:${numberFormatter$1(start + 1)}-${numberFormatter$1(end)} (${strand})` : - `${chr}:${numberFormatter$1(start + 1)}-${numberFormatter$1(end)}` - } - - /** - * Estimate theta given the ratio of track height to 1/2 the feature width (coa). This relationship is approximately linear. - */ - function estimateTheta(x) { - let coa = [0.01570925532366355, 0.15838444032453644, 0.3249196962329063, 0.5095254494944288, 0.7265425280053609, 0.9999999999999999]; - let theta = [0.031415926535897934, 0.3141592653589793, 0.6283185307179586, 0.9424777960769379, 1.2566370614359172, 1.5707963267948966]; - let idx; - - for (idx = 0; idx < coa.length; idx++) { - if (coa[idx] > x) { - break - } - } - - let left = idx === 0 ? 0 : coa[idx - 1]; - let right = idx < coa.length ? coa[idx] : 1; - let r = (x - left) / (right - left); - - let thetaLeft = idx === 0 ? 0 : theta[idx - 1]; - let thetaRight = idx < theta.length ? theta[idx] : Math.PI / 2; - - return Math.min(Math.PI/2, (thetaLeft + r * (thetaRight - thetaLeft))) - - } - - const colorAlphaCache = new Map(); - - function getAlphaColor(color, alpha) { - const key = `${color}_${alpha}`; - let c = colorAlphaCache.get(key); - if (!c) { - c = IGVColor.addAlpha(color, alpha); - colorAlphaCache.set(key, c); - } - return c - } - - - /** - * Called in the context of FeatureSource (i.e. this == the feature source (a TextFeatureSource) for the track - * - * @param allFeatures - * @returns {[]} - */ - function getWGFeatures(allFeatures) { - - const makeWGFeature = (f) => { - const wg = Object.assign({}, f); - wg.chr = "all"; - wg.start = genome.getGenomeCoordinate(f.chr1, f.start1); - wg.end = genome.getGenomeCoordinate(f.chr2, f.end2); - return wg - }; - - const genome = this.genome; - - // First pass -- find the max score feature - let maxScoreFeature; - let totalFeatureCount = 0; - for (let c of genome.wgChromosomeNames) { - let chrFeatures = allFeatures[c]; - if (chrFeatures) { - for (let f of chrFeatures) { - if (!f.dup) { - totalFeatureCount++; - if (f.score && (!maxScoreFeature || f.score > maxScoreFeature.score)) { - maxScoreFeature = f; - } - } - } - } - } - - const maxCount = this.maxWGCount; - const nBins = maxScoreFeature && maxScoreFeature.score > 0 && totalFeatureCount > maxCount ? 5 : 1; // TODO make a function of total # of features & maxCount? - const featuresPerBin = Math.floor(maxCount / nBins); - const binSize = maxScoreFeature && maxScoreFeature.score > 0 ? Math.log(maxScoreFeature.score) / nBins : Number.MAX_SAFE_INTEGER; - - let binnedFeatures = []; - let counts = []; - for (let i = 0; i < nBins; i++) { - counts.push([0]); - binnedFeatures.push([]); - } - - for (let c of genome.wgChromosomeNames) { - let chrFeatures = allFeatures[c]; - if (chrFeatures) { - for (let f of chrFeatures) { - if (!f.dup) { - const bin = f.score ? Math.max(0, Math.min(nBins - 1, Math.floor(Math.log(f.score) / binSize))) : 0; - if (binnedFeatures[bin].length < featuresPerBin) { - binnedFeatures[bin].push(makeWGFeature(f)); - } else { - //Reservoir sampling - const samplingProb = featuresPerBin / (counts[bin] + 1); - if (Math.random() < samplingProb) { - const idx = Math.floor(Math.random() * (featuresPerBin - 1)); - binnedFeatures[bin][idx] = makeWGFeature(f); - } - } - counts[bin]++; - } - } - } - } - - let wgFeatures; - if (nBins === 1) { - wgFeatures = binnedFeatures[0]; - } else { - wgFeatures = []; - for (let bf of binnedFeatures) { - for (let f of bf) wgFeatures.push(f); - } - // Keep the feature with max score - if (maxScoreFeature) { - wgFeatures.push(makeWGFeature(maxScoreFeature)); - } - wgFeatures.sort(function (a, b) { - return a.start - b.start - }); - console.log(wgFeatures.length); - } - - - return wgFeatures - } - - /** - * Extract a gff style info column for popup text. This convention used by 10X for bedpe files - * ALLELIC_FRAC=0.0375670840787;BLACK1=.;BLACK2=.;... - * @param data - * @param str - */ - function extractInfoColumn(data, str) { - const kvs = str.split(';'); - for (let t of kvs) { - const kv = t.split('='); - if (kv.length === 2) { - data.push({name: kv[0], value: kv[1]}); - } - } - - } - - /* - * The MIT License (MIT) - * - * Copyright (c) 2016 University of California San Diego - * Author: Jim Robinson - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - const isString = isString$2; - - const DEFAULT_COLOR = "rgb(0,0,150)"; - const DEFAULT_VISIBILITY_WINDOW = 1000000; - const TOP_MARGIN = 10; - const STANDARD_FIELDS = new Map([["REF", "referenceBases"], ["ALT", "alternateBases"], ["QUAL", "quality"], ["FILTER", "filter"]]); - - - class VariantTrack extends TrackBase { - - static defaults = { - displayMode: "EXPANDED", - sortDirection: "ASC", - showGenotypes: true, - squishedVariantHeight: 2, - squishedCallHeight: 1, - expandedCallHeight: 10, - expandedVGap: 2, - squishedVGap: 1, - expandedGroupGap: 10, - squishedGroupGap: 5, - featureHeight: 14, - noGenotypeColor: "rgb(200,180,180)", - noCallColor: "rgb(225, 225, 225)", - nonRefColor: "rgb(200, 200, 215)", - mixedColor: "rgb(200, 220, 200)", - homrefColor: "rgb(200, 200, 200)", - homvarColor: "rgb(17,248,254)", - hetvarColor: "rgb(34,12,253)", - colorBy: undefined, - visibilityWindow: undefined, - labelDisplayMode: undefined, - type: "variant" - } - - constructor(config, browser) { - super(config, browser); - } - - init(config) { - - super.init(config); - - this.expandedVariantHeight = config.expandedVariantHeight || config.variantHeight || 10; - - this.featureSource = FeatureSource(config, this.browser.genome); - - this._initColorBy = config.colorBy; - if (config.colorTable) { - this.colorTables = new Map(); - this.colorTables.set(config.colorBy, new ColorTable(config.colorTable)); - } - this._color = config.color; - this._strokecolor = config.strokecolor; - this._context_hook = config.context_hook; - - - // The number of variant rows are computed dynamically, but start with "1" by default - this.variantRowCount(1); - - } - - async postInit() { - - this.header = await this.getHeader(); // cricital, don't remove' - if (this.disposed) return // This track was removed during async load - if (undefined === this.visibilityWindow && this.config.indexed !== false) { - const fn = isFile$1(this.config.url) ? this.config.url.name : this.config.url; - if (isString(fn) && fn.toLowerCase().includes("gnomad")) { - this.visibilityWindow = 1000; // these are known to be very dense - } else if (typeof this.featureSource.defaultVisibilityWindow === 'function') { - this.visibilityWindow = await this.featureSource.defaultVisibilityWindow(); - } else { - this.visibilityWindow = DEFAULT_VISIBILITY_WINDOW; - } - } - return this - - } - - get supportsWholeGenome() { - return this.config.indexed === false || this.config.supportsWholeGenome === true - } - - get color() { - return this._color || DEFAULT_COLOR - } - - set color(c) { - this._color = c; - this.colorBy = undefined; - } - - async getHeader() { - - if (!this.header) { - if (typeof this.featureSource.getHeader === "function") { - const header = await this.featureSource.getHeader(); - if (header) { - this.callSets = header.callSets || []; - } - this.header = header; - } - this.sampleNames = this.callSets ? this.callSets.map(cs => cs.name) : []; - } - - return this.header - } - - getCallsetsLength() { - return this.callSets ? this.callSets.length : 0 - } - - async getFeatures(chr, start, end, bpPerPixel) { - - if (this.header === undefined) { - this.header = await this.getHeader(); - } - return this.featureSource.getFeatures({chr, start, end, bpPerPixel, visibilityWindow: this.visibilityWindow}) - } - - hasSamples() { - return this.getCallsetsLength() > 0 - } - - getSamples() { - return { - yOffset: this.sampleYOffset, - names: this.sampleNames, - height: this.sampleHeight - } - } - - /** - * The required height in pixels required for the track content. This is not the visible track height, which - * can be smaller (with a scrollbar) or larger. - * - * @param features - * @returns {*} - */ - computePixelHeight(features) { - - if (!features || features.length == 0) return TOP_MARGIN - - const nVariantRows = (this.displayMode === "COLLAPSED") ? 1 : this.nVariantRows; - const vGap = (this.displayMode === "SQUISHED") ? this.squishedVGap : this.expandedVGap; - const variantHeight = (this.displayMode === "SQUISHED") ? this.squishedVariantHeight : this.expandedVariantHeight; - const callHeight = (this.displayMode === "SQUISHED") ? this.squishedCallHeight : this.expandedCallHeight; - const nCalls = this.showGenotypes === false ? 0 : this.getCallsetsLength() * nVariantRows; - const h = TOP_MARGIN + nVariantRows * (variantHeight + vGap); - return h + vGap + (nCalls + 1) * (callHeight + vGap) - - } - - variantRowCount(count) { - this.nVariantRows = count; - } - - draw({context, pixelWidth, pixelHeight, bpPerPixel, bpStart, pixelTop, features}) { - - IGVGraphics.fillRect(context, 0, pixelTop, pixelWidth, pixelHeight, {'fillStyle': "rgb(255, 255, 255)"}); - - const vGap = ("SQUISHED" === this.displayMode) ? this.squishedVGap : this.expandedVGap; - const rowCount = ("COLLAPSED" === this.displayMode) ? 1 : this.nVariantRows; - const variantHeight = ("SQUISHED" === this.displayMode) ? this.squishedVariantHeight : this.expandedVariantHeight; - this.variantBandHeight = TOP_MARGIN + rowCount * (variantHeight + vGap); - - let callSets = this.callSets; - if (!callSets && this._f) { - callSets = this._f.callSets; // "Complementary" variant for structural variants - } - const nCalls = this.getCallsetsLength(); - if (callSets && nCalls > 0 && this.showGenotypes !== false) { - IGVGraphics.strokeLine(context, 0, this.variantBandHeight, pixelWidth, this.variantBandHeight, {strokeStyle: 'rgb(224,224,224) '}); - } - - if (features) { - - const callHeight = ("SQUISHED" === this.displayMode) ? this.squishedCallHeight : this.expandedCallHeight; - const vGap = ("SQUISHED" === this.displayMode) ? this.squishedVGap : this.expandedVGap; - const bpEnd = bpStart + pixelWidth * bpPerPixel + 1; - - // Loop through variants. A variant == a row in a VCF file - for (let variant of features) { - - if (variant.end < bpStart) continue - if (variant.start > bpEnd) break - - const variantHeight = ("SQUISHED" === this.displayMode) ? this.squishedVariantHeight : this.expandedVariantHeight; - const y = TOP_MARGIN + ("COLLAPSED" === this.displayMode ? 0 : variant.row * (variantHeight + vGap)); - const h = variantHeight; - - // Compute pixel width. Minimum width is 3 pixels, if > 5 pixels create gap between variants - let x = Math.round((variant.start - bpStart) / bpPerPixel); - let x1 = Math.round((variant.end - bpStart) / bpPerPixel); - let w = Math.max(1, x1 - x); - if (w < 3) { - w = 3; - x -= 1; - } else if (w > 5) { - x += 1; - w -= 2; - } - context.fillStyle = this.getColorForFeature(variant); - context.fillRect(x, y, w, h); - - //only paint stroke if a color is defined - let strokecolor = this.getVariantStrokecolor(variant); - if (strokecolor) { - context.strokeStyle = strokecolor; - context.strokeRect(x, y, w, h); - } - - // call hook if _context_hook fn is defined - this.callContextHook(variant, context, x, y, w, h); - - variant.pixelRect = {x, y, w, h}; - - // Loop though the calls for this variant. There will potentially be a call for each sample. - if (nCalls > 0 && this.showGenotypes !== false) { - - const nVariantRows = "COLLAPSED" === this.displayMode ? 1 : this.nVariantRows; - this.sampleYOffset = this.variantBandHeight + vGap; - this.sampleHeight = nVariantRows * (callHeight + vGap); // For each sample, there is a call for each variant at this position - - let sampleNumber = 0; - if (callSets && variant.calls) { - for (let callSet of callSets) { - const call = variant.calls[callSet.id]; - if (call) { - const row = "COLLAPSED" === this.displayMode ? 0 : variant.row; - const py = this.sampleYOffset + sampleNumber * this.sampleHeight + row * (callHeight + vGap); - let allVar = true; // until proven otherwise - let allRef = true; - let noCall = false; - - if (call.genotype) { - for (let g of call.genotype) { - if ('.' === g) { - noCall = true; - break - } else { - if (g !== 0) allRef = false; - if (g === 0) allVar = false; - } - } - } - - if (!call.genotype) { - context.fillStyle = this.noGenotypeColor; - } else if (noCall) { - context.fillStyle = this.noCallColor; - } else if (allRef) { - context.fillStyle = this.homrefColor; - } else if (allVar) { - context.fillStyle = this.homvarColor; - } else { - context.fillStyle = this.hetvarColor; - } - - context.fillRect(x, py, w, callHeight); - - callSet.pixelRect = {x, y: py, w, h: callHeight}; - } - sampleNumber++; - } - } - } - } - - } else { - console.log("No feature list"); - } - }; - - - getColorForFeature(variant) { - - const v = variant._f || variant; - let variantColor; - - if (this.colorBy) { - const colorBy = this.colorBy; - let value; - if (v.info.hasOwnProperty(colorBy)) { - value = v.info[colorBy]; - } else if (STANDARD_FIELDS.has(colorBy)) { - const key = STANDARD_FIELDS.get(colorBy); - value = v[key]; - } - variantColor = this.getVariantColorTable(colorBy).getColor(value); - if (!variantColor) { - variantColor = "gray"; - } - - } else if (this._color) { - variantColor = (typeof this._color === "function") ? this._color(variant) : this._color; - } else if ("NONVARIANT" === v.type) { - variantColor = this.nonRefColor; - } else if ("MIXED" === v.type) { - variantColor = this.mixedColor; - } else { - variantColor = this.color; - } - return variantColor - } - - - getVariantStrokecolor(variant) { - - const v = variant._f || variant; - let variantStrokeColor; - - if (this._strokecolor) { - variantStrokeColor = (typeof this._strokecolor === "function") ? this._strokecolor(v) : this._strokecolor; - } else { - variantStrokeColor = undefined; - } - return variantStrokeColor - } - - callContextHook(variant, context, x, y, w, h) { - if (this._context_hook) { - if (typeof this._context_hook === "function") { - const v = variant._f || variant; - - context.save(); - this._context_hook(v, context, x, y, w, h); - context.restore(); - } - } - } - - clickedFeatures(clickState) { - - let featureList = super.clickedFeatures(clickState); - - const vGap = (this.displayMode === 'EXPANDED') ? this.expandedVGap : this.squishedVGap; - const callHeight = vGap + ("SQUISHED" === this.displayMode ? this.squishedCallHeight : this.expandedCallHeight); - // Find the variant row (i.e. row assigned during feature packing) - const yOffset = clickState.y; - if (yOffset <= this.variantBandHeight) { - // Variant - const variantHeight = ("SQUISHED" === this.displayMode) ? this.squishedVariantHeight : this.expandedVariantHeight; - const variantRow = Math.floor((yOffset - TOP_MARGIN) / (variantHeight + vGap)); - if ("COLLAPSED" !== this.displayMode) { - featureList = featureList.filter(f => f.row === variantRow); - } - } else if (this.callSets) { - const callSets = this.callSets; - const sampleY = yOffset - this.variantBandHeight; - const sampleRow = Math.floor(sampleY / this.sampleHeight); - if (sampleRow >= 0 && sampleRow < callSets.length) { - const variantRow = Math.floor((sampleY - sampleRow * this.sampleHeight) / callHeight); - const variants = "COLLAPSED" === this.displayMode ? featureList : featureList.filter(f => f.row === variantRow); - const cs = callSets[sampleRow]; - featureList = variants.map(v => { - const call = v.calls[cs.id]; - expandGenotype(call, v); - return call - }); - } - } - - return featureList - } - - - /** - * Return "popup data" for feature @ genomic location. Data is an array of key-value pairs - */ - popupData(clickState, featureList) { - - if (featureList === undefined) featureList = this.clickedFeatures(clickState); - const genomicLocation = clickState.genomicLocation; - const genomeID = this.browser.genome.id; - const sampleInformation = this.browser.sampleInformation; - - let popupData = []; - for (let v of featureList) { - - const f = v._f || v; // Get real variant from psuedo-variant, e.g. whole genome or SV mate - - if (popupData.length > 0) { - popupData.push({html: '
'}); - } - - if (typeof f.popupData === 'function') { - const v = f.popupData(genomicLocation, genomeID); - Array.prototype.push.apply(popupData, v); - } else { - // Assume this is a call (genotype) - const call = f; - - if (call.callSetName !== undefined) { - popupData.push({name: 'Name', value: call.callSetName}); - } - - if (call.genotypeName) { - popupData.push({name: 'Genotype', value: call.genotypeName}); - } - - if (call.phaseset !== undefined) { - popupData.push({name: 'Phase set', value: call.phaseset}); - } - if (call.genotypeLikelihood !== undefined) { - popupData.push({name: 'genotypeLikelihood', value: call.genotypeLikelihood.toString()}); - } - - if (sampleInformation) { - var attr = sampleInformation.getAttributes(call.callSetName); - if (attr) { - Object.keys(attr).forEach(function (attrName) { - var displayText = attrName.replace(/([A-Z])/g, " $1"); - displayText = displayText.charAt(0).toUpperCase() + displayText.slice(1); - popupData.push({name: displayText, value: attr[attrName]}); - }); - } - } - - var infoKeys = Object.keys(call.info); - if (infoKeys.length) { - popupData.push('
'); - } - infoKeys.forEach(function (key) { - popupData.push({name: key, value: decodeURIComponent(call.info[key])}); - }); - } - } - return popupData - - } - - - // VariantTrack.prototype.contextMenuItemList = function (clickState) { - // - // const self = this; - // const menuItems = []; - // - // const featureList = this.clickedFeatures(clickState); - // - // if (this.callSets && featureList && featureList.length > 0) { - // - // featureList.forEach(function (variant) { - // - // if ('str' === variant.type) { - // - // menuItems.push({ - // label: 'Sort by allele length', - // click: function () { - // sortCallSetsByAlleleLength(self.callSets, variant, self.sortDirection); - // self.sortDirection = (self.sortDirection === "ASC") ? "DESC" : "ASC"; - // self.trackView.repaintViews(); - // } - // }); - // - // } - // - // }); - // } - // - // - // function sortCallSetsByAlleleLength(callSets, variant, direction) { - // var d = (direction === "DESC") ? 1 : -1; - // Object.keys(callSets).forEach(function (property) { - // callSets[property].sort(function (a, b) { - // var aNan = isNaN(variant.calls[a.id].genotype[0]); - // var bNan = isNaN(variant.calls[b.id].genotype[0]); - // if (aNan && bNan) { - // return 0; - // } else if (aNan) { - // return 1; - // } else if (bNan) { - // return -1; - // } else { - // var a0 = getAlleleString(variant.calls[a.id], variant, 0); - // var a1 = getAlleleString(variant.calls[a.id], variant, 1); - // var b0 = getAlleleString(variant.calls[b.id], variant, 0); - // var b1 = getAlleleString(variant.calls[b.id], variant, 1); - // var result = Math.max(b0.length, b1.length) - Math.max(a0.length, a1.length); - // if (result === 0) { - // result = Math.min(b0.length, b1.length) - Math.min(a0.length, a1.length); - // } - // return d * result; - // } - // }); - // }); - // } - // - // - // return menuItems; - // - // }; - - menuItemList() { - - const menuItems = []; - - // color-by INFO attribute - if (this.header.INFO) { - //Code below will present checkboxes for all info fields of type "String". Wait until this is requested - //const stringInfoKeys = Object.keys(this.header.INFO).filter(key => "String" === this.header.INFO[key].Type); - - // For now stick to explicit info fields (well, exactly 1 for starters) - if (this.header.INFO) { - //const stringInfoKeys = Object.keys(this.header.INFO).filter(key => this.header.INFO[key].Type === "String") - const stringInfoKeys = this.header.INFO.SVTYPE ? ['SVTYPE'] : []; - if (this._initColorBy && this._initColorBy !== 'SVTYPE') { - stringInfoKeys.push(this._initColorBy); - } - if (stringInfoKeys.length > 0) { - menuItems.push('
'); - const $e = $$1('
'); - $e.text('Color by:'); - menuItems.push({name: undefined, object: $e, click: undefined, init: undefined}); - stringInfoKeys.sort(); - for (let item of stringInfoKeys) { - const selected = (this.colorBy === item); - const label = item ? item : 'None'; - menuItems.push(this.colorByCB({key: item, label: label}, selected)); - } - menuItems.push(this.colorByCB({key: undefined, label: 'None'}, this.colorBy === undefined)); - menuItems.push('
'); - } - } - } - - if (this.getCallsetsLength() > 0) { - menuItems.push({object: $$1('
')}); - menuItems.push({ - object: $$1(createCheckbox$2("Show Genotypes", this.showGenotypes)), - click: () => { - this.showGenotypes = !this.showGenotypes; - //adjustTrackHeight(); - this.trackView.checkContentHeight(); - this.trackView.repaintViews(); - } - }); - } - - menuItems.push({object: $$1('
')}); - for (let displayMode of ["COLLAPSED", "SQUISHED", "EXPANDED"]) { - var lut = - { - "COLLAPSED": "Collapse", - "SQUISHED": "Squish", - "EXPANDED": "Expand" - }; - - menuItems.push( - { - object: $$1(createCheckbox$2(lut[displayMode], displayMode === this.displayMode)), - click: () => { - this.displayMode = displayMode; - this.trackView.checkContentHeight(); - this.trackView.repaintViews(); - } - }); - } - - // Experimental JBrowse circular view integration - if (this.browser.circularView) { - - menuItems.push('
'); - menuItems.push({ - label: 'Add SVs to circular view', - click: () => { - for (let viewport of this.trackView.viewports) { - this.sendChordsForViewport(viewport); - } - } - }); - } - - return menuItems - } - - - contextMenuItemList(clickState) { - - // Experimental JBrowse circular view integration - if (this.browser.circularView) { - const viewport = clickState.viewport; - const list = []; - - list.push({ - label: 'Add SVs to Circular View', - click: () => { - this.sendChordsForViewport(viewport); - } - }); - - list.push('
'); - return list - } - } - - - sendChordsForViewport(viewport) { - const refFrame = viewport.referenceFrame; - let inView; - if ("all" === refFrame.chr) { - const all = this.featureSource.getAllFeatures(); - const arrays = Object.keys(all).map(k => all[k]); - inView = [].concat(...arrays); - } else { - inView = this.featureSource.featureCache.queryFeatures(refFrame.chr, refFrame.start, refFrame.end); - - } - - const chords = makeVCFChords(inView); - sendChords(chords, this, refFrame, 0.5); - } - - /** - * Create a "color by" checkbox menu item, optionally initially checked - * @param menuItem - * @param showCheck - * @returns {{init: undefined, name: undefined, click: clickHandler, object: (jQuery|HTMLElement|jQuery.fn.init)}} - */ - colorByCB(menuItem, showCheck) { - - const $e = $$1(createCheckbox$2(menuItem.label, showCheck)); - const clickHandler = () => { - - if (menuItem.key === this.colorBy) { - this.colorBy = undefined; - delete this.config.colorBy; - this.trackView.repaintViews(); - } else { - this.colorBy = menuItem.key; - this.config.colorBy = menuItem.key; - this.trackView.repaintViews(); - } - - }; - - return {name: undefined, object: $e, click: clickHandler, init: undefined} - } - - getState() { - - const config = super.getState(); - if (this._color && typeof this._color !== "function") { - config.color = this._color; - } - return config - - } - - getVariantColorTable(key) { - - if (!this.colorTables) { - this.colorTables = new Map(); - } - - if (!this.colorTables.has(key)) { - let tbl; - switch (key) { - case "SVTYPE" : - tbl = SV_COLOR_TABLE; - break - default: - tbl = new PaletteColorTable("Set1"); - } - this.colorTables.set(key, tbl); - } - return this.colorTables.get(key) - } - } - - - function expandGenotype(call, variant) { - - if (call.genotype) { - let gt = ''; - if (variant.alternateBases === ".") { - gt = "No Call"; - } else { - const altArray = variant.alternateBases.split(","); - for (let allele of call.genotype) { - if (gt.length > 0) { - gt += "|"; - } - if ('.' === allele) { - gt += '.'; - } else if (allele === 0) { - gt += variant.referenceBases; - } else { - let alt = altArray[allele - 1].replace("<", "<"); - gt += alt; - } - } - } - call.genotypeName = gt; - } - } - - - const SV_COLOR_TABLE = new ColorTable({ - 'DEL': '#ff2101', - 'INS': '#001888', - 'DUP': '#028401', - 'INV': '#008688', - 'CNV': '#8931ff', - 'BND': '#891100', - '*': '#002eff' - }); - - /* - * The MIT License (MIT) - * - * Copyright (c) 2014 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - class EqtlTrack extends TrackBase { - - constructor(config, browser) { - - super(config, browser); - } - - init(config) { - super.init(config); - - this.name = config.name; - this.pValueField = config.pValueField || "pValue"; - this.geneField = config.geneField || "geneSymbol"; - this.snpField = config.snpField || "snp"; - - const min = config.minLogP || config.min; - const max = config.maxLogP || config.max; - this.dataRange = { - min: min || 3.5, - max: max || 25 - }; - if (!max) { - this.autoscale = true; - } else { - this.autoscale = config.autoscale; - } - this.autoscalePercentile = (config.autoscalePercentile === undefined ? 98 : config.autoscalePercentile); - - - this.background = config.background; // No default - this.divider = config.divider || "rgb(225,225,225)"; - this.dotSize = config.dotSize || 2; - this.height = config.height || 100; - this.autoHeight = false; - this.disableButtons = config.disableButtons; - - // Limit visibility window to 2 mb, gtex server gets flaky beyond that - this.visibilityWindow = config.visibilityWindow === undefined ? - 2000000 : config.visibilityWindow >= 0 ? Math.min(2000000, config.visibilityWindow) : 2000000; - - this.featureSource = FeatureSource(config, this.browser.genome); - - GtexUtils.gtexLoaded = true; - } - - paintAxis(ctx, pixelWidth, pixelHeight) { - - const yScale = (this.dataRange.max - this.dataRange.min) / pixelHeight; - - const font = { - 'font': 'normal 10px Arial', - 'textAlign': 'right', - 'strokeStyle': "black" - }; - - IGVGraphics.fillRect(ctx, 0, 0, pixelWidth, pixelHeight, {'fillStyle': "rgb(255, 255, 255)"}); - - // Determine a tick spacing such that there is at least 10 pixels between ticks - - const n = Math.ceil((this.dataRange.max - this.dataRange.min) * 10 / pixelHeight); - - for (let p = 4; p <= this.dataRange.max; p += n) { - - // TODO: Dashes may not actually line up with correct scale. Ask Jim about this - - const ref = 0.85 * pixelWidth; - const x1 = ref - 5; - const x2 = ref; - const y = pixelHeight - (p - this.dataRange.min) / yScale; - - IGVGraphics.strokeLine(ctx, x1, y, x2, y, font); // Offset dashes up by 2 pixel - - if (y > 8) { - IGVGraphics.fillText(ctx, p, x1 - 1, y + 2, font); - } // Offset numbers down by 2 pixels; - } - - font['textAlign'] = 'center'; - - IGVGraphics.fillText(ctx, "-log10(pvalue)", pixelWidth / 4, pixelHeight / 2, font, {rotate: {angle: -90}}); - - }; - - async getFeatures(chr, start, end) { - - const pValueField = this.pValueField; - const visibilityWindow = this.visibilityWindow; - const features = await this.featureSource.getFeatures({chr, start, end, visibilityWindow}); - features.forEach(function (f) { - f.value = f[pValueField]; - }); - return features - } - - draw(options) { - - const ctx = options.context; - - const pixelWidth = options.pixelWidth; - const pixelHeight = options.pixelHeight; - - if (this.background) { - IGVGraphics.fillRect(ctx, 0, 0, pixelWidth, pixelHeight, {'fillStyle': this.background}); - } - IGVGraphics.strokeLine(ctx, 0, pixelHeight - 1, pixelWidth, pixelHeight - 1, {'strokeStyle': this.divider}); - - const drawEqtls = (drawSelected) => { - - const radius = drawSelected ? 2 * this.dotSize : this.dotSize; - const bpStart = options.bpStart; - const yScale = (this.dataRange.max - this.dataRange.min) / pixelHeight; - const selection = options.referenceFrame.selection; - - for (let eqtl of options.features) { - - const px = (eqtl.start - bpStart + 0.5) / options.bpPerPixel; - if (px < 0) continue - else if (px > pixelWidth) break - - const snp = eqtl.snp.toUpperCase(); - const geneName = eqtl[this.geneField].toUpperCase(); - - const isSelected = selection && - (selection.snp === snp || selection.gene === geneName); - - if (!drawSelected || isSelected) { - - // Add eqtl's gene to the selection if this is the selected snp. - // TODO -- this should not be done here in the rendering code. - if (selection && selection.snp === snp) { - selection.addGene(geneName); - } - - var mLogP = -Math.log(eqtl[this.pValueField]) / Math.LN10; - if (mLogP >= this.dataRange.min) { - let capped; - if (mLogP > this.dataRange.max) { - mLogP = this.dataRange.max; - capped = true; - } else { - capped = false; - - } - - const py = Math.max(0 + radius, pixelHeight - Math.round((mLogP - this.dataRange.min) / yScale)); - eqtl.px = px; - eqtl.py = py; - eqtl.radius = radius; - - let color; - if (drawSelected && selection) { - color = selection.colorForGene(geneName); - IGVGraphics.setProperties(ctx, {fillStyle: color, strokeStyle: "black"}); - } else { - color = capped ? "rgb(150, 150, 150)" : "rgb(180, 180, 180)"; - IGVGraphics.setProperties(ctx, {fillStyle: color, strokeStyle: color}); - } - - IGVGraphics.fillCircle(ctx, px, py, radius); - IGVGraphics.strokeCircle(ctx, px, py, radius); - } - } - } - }; - - // Draw in two passes, with "selected" eqtls drawn last - drawEqtls(false); - drawEqtls(true); - - } - - /** - * Return "popup data" for feature @ genomic location. Data is an array of key-value pairs - */ - popupData(clickState, features) { - - if(features === undefined) features = clickState.viewport.cachedFeatures; - if (!features || features.length === 0) return [] - - const tolerance = 3; - const tissue = this.name; - const popupData = []; - - for (let feature of features) { - // Hit test --use square vs circle for efficiency (no sqrt) - if (Math.abs(feature.px - clickState.canvasX) < (feature.radius + tolerance) && - Math.abs(feature.py - clickState.canvasY) < (feature.radius + tolerance)) { - - if (popupData.length > 0) { - popupData.push('
'); - } - popupData.push( - {name: "snp id", value: feature.snp}, - {name: "gene id", value: feature.geneId}, - {name: "gene name", value: feature.geneName}, - {name: "p value", value: feature.pValue}, - {name: "tissue", value: tissue}); - - } - } - - return popupData - } - - menuItemList() { - return MenuUtils$1.numericDataMenuItems(this.trackView) - } - - doAutoscale(featureList) { - - if (featureList.length > 0) { - - var values = featureList - .map(function (eqtl) { - return -Math.log(eqtl.value) / Math.LN10 - }); - - this.dataRange.max = IGVMath.percentile(values, this.autoscalePercentile); - } else { - // No features -- default - const max = this.config.maxLogP || this.config.max; - this.dataRange.max = max || 25; - } - - return this.dataRange - } - - } - - /** - * Colors used for coding omosomes - */ - - const GWASColors = { - "X": "rgb(204, 153, 0)", - "Y": "rgb(153, 204, 0)", - "Un": "darkGray)", - "1": "rgb(80, 80, 255)", - "2": "rgb(206, 61, 50)", - "2a": "rgb(210, 65, 55)", - "2b": "rgb(215, 70, 60)", - "3": "rgb(116, 155, 88)", - "4": "rgb(240, 230, 133)", - "5": "rgb(70, 105, 131)", - "6": "rgb(186, 99, 56)", - "7": "rgb(93, 177, 221)", - "8": "rgb(128, 34, 104)", - "9": "rgb(107, 215, 107)", - "10": "rgb(213, 149, 167)", - "11": "rgb(146, 72, 34)", - "12": "rgb(131, 123, 141)", - "13": "rgb(199, 81, 39)", - "14": "rgb(213, 143, 92)", - "15": "rgb(122, 101, 165)", - "16": "rgb(228, 175, 105)", - "17": "rgb(59, 27, 83)", - "18": "rgb(205, 222, 183)", - "19": "rgb(97, 42, 121)", - "20": "rgb(174, 31, 99)", - "21": "rgb(231, 199, 111)", - "22": "rgb(90, 101, 94)", - "23": "rgb(204, 153, 0)", - "24": "rgb(153, 204, 0)", - "25": "rgb(51, 204, 0)", - "26": "rgb(0, 204, 51)", - "27": "rgb(0, 204, 153)", - "28": "rgb(0, 153, 204)", - "29": "rgb(10, 71, 255)", - "30": "rgb(71, 117, 255)", - "31": "rgb(255, 194, 10)", - "32": "rgb(255, 209, 71)", - "33": "rgb(153, 0, 51)", - "34": "rgb(153, 26, 0)", - "35": "rgb(153, 102, 0)", - "36": "rgb(128, 153, 0)", - "37": "rgb(51, 153, 0)", - "38": "rgb(0, 153, 26)", - "39": "rgb(0, 153, 102)", - "40": "rgb(0, 128, 153)", - "41": "rgb(0, 51, 153)", - "42": "rgb(26, 0, 153)", - "43": "rgb(102, 0, 153)", - "44": "rgb(153, 0, 128)", - "45": "rgb(214, 0, 71)", - "46": "rgb(255, 20, 99)", - "47": "rgb(0, 214, 143)", - "48": "rgb(20, 255, 177)" - }; - - // aliasing - for (let key of Object.keys(GWASColors)) { - const altName = "chr" + key; - GWASColors[altName] = GWASColors[key]; - } - - // romanizing - for(let a = 1; a <= 48; a++) { - if(a === 10) continue // Don't overide "X" - const roman = romanize(a); - GWASColors[roman] = GWASColors[a.toString()]; - } - - - function romanize (num) { - if (!+num) return false; - var digits = String(+num).split(''); - var key = ['','C','CC','CCC','CD','D','DC','DCC','DCCC','CM', - '','X','XX','XXX','XL','L','LX','LXX','LXXX','XC', - '','I','II','III','IV','V','VI','VII','VIII','IX']; - var roman = '', i = 3; - while (i--) roman = (key[+digits.pop() + (i * 10)] || '') + roman; - return Array(+digits.join('') + 1).join('M') + roman; - } - - /* - * The MIT License (MIT) - * - * Copyright (c) 2014 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - const DEFAULT_POPOVER_WINDOW = 100000000; - - //const type = "gwas"; - - class GWASTrack extends TrackBase { - - constructor(config, browser) { - - super(config, browser); - } - - init(config) { - - super.init(config); - - this.useChrColors = config.useChrColors === undefined ? true : config.useChrColors; - this.trait = config.trait; - this.posteriorProbability = config.posteriorProbability; - this.valueProperty = "bed" === config.format ? "score" : "value"; - this.height = config.height || 100; // The preferred height - this.autoscale = config.autoscale; - this.autoscalePercentile = config.autoscalePercentile === undefined ? 98 : config.autoscalePercentile; - this.background = config.background; // No default - this.divider = config.divider || "rgb(225,225,225)"; - this.dotSize = config.dotSize || 3; - this.popoverWindow = (config.popoverWindow === undefined ? DEFAULT_POPOVER_WINDOW : config.popoverWindow); - - // Color settings - if (this.useChrColors) { - this.colorScale = new ColorTable(config.colorTable || GWASColors); - } else if (config.color) { - this.colorScale = new ConstantColorScale(config.color); - } else { - this.colorScale = - new BinnedColorScale(config.colorScale || - { - thresholds: [5e-8, 5e-4, 0.5], - colors: ["rgb(255,50,50)", "rgb(251,100,100)", "rgb(251,170,170)", "rgb(227,238,249)"], - }); - } - - this.featureSource = FeatureSource(config, this.browser.genome); - } - - async postInit() { - - if (typeof this.featureSource.getHeader === "function") { - this.header = await this.featureSource.getHeader(); - if (this.disposed) return // This track was removed during async load - } - - // Set properties from track line - if (this.header) { - this.setTrackProperties(this.header); // setTrackProperties defined in TrackBase - } - - // Set initial range if specfied, unless autoscale == true - if (!this.autoscale) { - if (this.posteriorProbability) { - this.dataRange = { - min: this.config.min === undefined ? 0 : this.config.min, - max: this.config.max === undefined ? 1 : this.config.max - }; - } else { - this.dataRange = { - min: this.config.min === undefined ? 0 : this.config.min, - max: this.config.max === undefined ? 25 : this.config.max - }; - } - } - - return this - - } - - - get supportsWholeGenome() { - return true - } - - async getFeatures(chr, start, end) { - const visibilityWindow = this.visibilityWindow; - return this.featureSource.getFeatures({chr, start, end, visibilityWindow}) - } - - draw(options) { - - const featureList = options.features; - const ctx = options.context; - const pixelWidth = options.pixelWidth; - const pixelHeight = options.pixelHeight; - if (this.background) { - IGVGraphics.fillRect(ctx, 0, 0, pixelWidth, pixelHeight, {'fillStyle': this.background}); - } - IGVGraphics.strokeLine(ctx, 0, pixelHeight - 1, pixelWidth, pixelHeight - 1, {'strokeStyle': this.divider}); - - if (featureList) { - - const bpPerPixel = options.bpPerPixel; - const bpStart = options.bpStart; - const bpEnd = bpStart + pixelWidth * bpPerPixel + 1; - for (let variant of featureList) { - const pos = variant.start; - if (pos < bpStart) continue - if (pos > bpEnd) break - - let val; - if (this.posteriorProbability) { - val = variant[this.valueProperty]; - } else { - const pvalue = variant[this.valueProperty]; - if (!pvalue) continue - val = -Math.log10(pvalue); - } - - const colorKey = this.useChrColors ? - variant._f ? variant._f.chr : variant.chr : - val; - - const color = this.colorScale.getColor(colorKey); - const yScale = (this.dataRange.max - this.dataRange.min) / pixelHeight; - const px = Math.round((pos - bpStart) / bpPerPixel); - const py = Math.max(this.dotSize, pixelHeight - Math.round((val - this.dataRange.min) / yScale)); - - if (color) { - IGVGraphics.setProperties(ctx, {fillStyle: color, strokeStyle: "black"}); - } - IGVGraphics.fillCircle(ctx, px, py, this.dotSize); - variant.px = px; - variant.py = py; - } - } - } - - paintAxis(ctx, pixelWidth, pixelHeight) { - - IGVGraphics.fillRect(ctx, 0, 0, pixelWidth, pixelHeight, {'fillStyle': "rgb(255, 255, 255)"}); - var font = { - 'font': 'normal 10px Arial', - 'textAlign': 'right', - 'strokeStyle': "black" - }; - - const yScale = (this.dataRange.max - this.dataRange.min) / pixelHeight; - if (this.posteriorProbability) { - const n = 0.1; - for (let p = this.dataRange.min; p < this.dataRange.max; p += n) { - const yp = pixelHeight - Math.round((p - this.dataRange.min) / yScale); - IGVGraphics.strokeLine(ctx, 45, yp - 2, 50, yp - 2, font); // Offset dashes up by 2 pixel - IGVGraphics.fillText(ctx, p.toFixed(1), 44, yp + 2, font); // Offset numbers down by 2 pixels; - } - } else { - const n = Math.ceil((this.dataRange.max - this.dataRange.min) * 10 / pixelHeight); - for (let p = this.dataRange.min; p < this.dataRange.max; p += n) { - const yp = pixelHeight - Math.round((p - this.dataRange.min) / yScale); - IGVGraphics.strokeLine(ctx, 45, yp, 50, yp, font); // Offset dashes up by 2 pixel - IGVGraphics.fillText(ctx, Math.floor(p), 44, yp + 4, font); // Offset numbers down by 2 pixels; - } - } - - font['textAlign'] = 'center'; - if (this.posteriorProbability) { - IGVGraphics.fillText(ctx, "PPA", pixelWidth / 2, pixelHeight / 2, font, {rotate: {angle: -90}}); - } else { - IGVGraphics.fillText(ctx, "-log10(pvalue)", pixelWidth / 2, pixelHeight / 2, font, {rotate: {angle: -90}}); - } - } - - popupData(clickState, features) { - - if (features === undefined) features = clickState.viewport.cachedFeatures; - - let data = []; - const track = clickState.viewport.trackView.track; - - if (features) { - let count = 0; - for (let f of features) { - const xDelta = Math.abs(clickState.canvasX - f.px); - const yDelta = Math.abs(clickState.canvasY - f.py); - const value = f[this.valueProperty]; - if (xDelta < this.dotSize && yDelta < this.dotSize) { - if (count > 0) { - data.push("
"); - } - if (count == 5) { - data.push("..."); - break - } - if (typeof f.popupData === 'function') { - data = data.concat(f.popupData()); - } else { - const chr = f.realChr || f.chr; - const pos = (f.realStart || f.start) + 1; - data.push({name: 'chromosome', value: chr}); - data.push({name: 'position', value: pos}); - data.push({name: 'name', value: f.name}); - if (track.posteriorProbability) { - data.push({name: 'posterior probability', value: value}); - } else { - data.push({name: 'pValue', value: value}); - } - } - count++; - } - } - } - - return data - } - - menuItemList() { - return MenuUtils$1.numericDataMenuItems(this.trackView) - } - - doAutoscale(featureList) { - - if (featureList.length > 0) { - // posterior probabilities are treated without modification, but we need to take a negative logarithm of P values - const valueProperty = this.valueProperty; - const posterior = this.posteriorProbability; - const features = - featureList.map(function (feature) { - const v = feature[valueProperty]; - return {value: posterior ? v : -Math.log(v) / Math.LN10} - }); - this.dataRange = doAutoscale$1(features); - - } else { - // No features -- pick something reasonable for PPAs and p-values - if (this.posteriorProbability) { - this.dataRange = {min: this.config.min || 0, max: this.config.max || 1}; - } else { - this.dataRange = {min: this.config.max || 25, max: this.config.min || 0}; - } - } - - return this.dataRange - } - - } - - const X_PIXEL_DIFF_THRESHOLD = 1; - - class GCNVTrack extends TrackBase { - - constructor(config, browser) { - super(config, browser); - } - - init(config) { - super.init(config); - - this.autoscale = config.autoscale || config.max === undefined; - this.dataRange = { - min: config.min || 0, - max: config.max - }; - - this.windowFunction = config.windowFunction || "mean"; - this.paintAxis = paintAxis; - this.graphType = config.graphType || "bar"; - - //hack to avoid creating feature source multiple times. If config.type is not set the file must be read - //to determine type, which results in creation of a feature source. - if (config._featureSource) { - this.featureSource = config._featureSource; - delete config._featureSource; - } else { - this.featureSource = FeatureSource(this.config, this.browser.genome); - } - - // Visibility window hardcoded to -1 (== whole chromosome). Draw method needs feature beyond current view, - // when/if this is resolved visibilityWindow can be used. - this.visibilityWindow = -1; - this.featureSource.visibilityWindow = this.visibilityWindow; - } - - async postInit() { - - if (typeof this.featureSource.getHeader === "function") { - this.header = await this.featureSource.getHeader(); - if(this.disposed) return; // This track was removed during async load - this.sampleNames = this.header.columnNames.slice(3); - - // Set generic properties from track line - this.setTrackProperties(this.header); // setTrackProperties defined in TrackBase - - // set option to highlight sample track line on click - if (this.header.hasOwnProperty("clickToHighlight")) { - let colour = this.header["clickToHighlight"]; - this.config.clickToHighlight = colour; - this.config.samplesClickedToHighlight = {}; - } - - // Special track line properties - if (this.header.hasOwnProperty("highlight")) { - this.config.highlightSamples = {}; - let v = this.header["highlight"]; - if (!Array.isArray(v)) v = [v]; - for (let h of v) { - const tokens = h.split(";"); - if (tokens.length === 2) { - this.config.highlightSamples[tokens[0]] = tokens[1]; - } - - } - } - } - } - - menuItemList() { - return MenuUtils$1.numericDataMenuItems(this.trackView) - } - - async getFeatures(chr, start, end) { - const chrFeatures = await this.featureSource.getFeatures({ - chr, - start: 0, - end: Number.MAX_SAFE_INTEGER, - visibilityWindow: this.visibilityWindow - }); - let prevIndex = undefined; - let nextIndex = undefined; - for (let i = 1; i < chrFeatures.length - 1; i++) { - if (prevIndex === undefined && chrFeatures[i].end > start) { - prevIndex = i - 1; - } - if (nextIndex === undefined && chrFeatures[i].start > end) { - nextIndex = i + 1; - break - } - } - if (prevIndex === undefined) prevIndex = 0; - if (nextIndex === undefined) nextIndex = chrFeatures.length; - return chrFeatures.slice(prevIndex, nextIndex) - } - - draw(options) { - - const {features, context, bpPerPixel, bpStart, pixelWidth, pixelHeight} = options; - - ///let baselineColor; - //if (typeof self.color === "string" && self.color.startsWith("rgb(")) { - // baselineColor = IGVColor.addAlpha(self.color, 0.1); - //} - - const yScale = (yValue) => { - return ((this.dataRange.max - yValue) / (this.dataRange.max - this.dataRange.min)) * pixelHeight - }; - - const getX = function (bpPosition) { - let x = Math.floor((bpPosition - bpStart) / bpPerPixel); - if (isNaN(x)) console.warn('isNaN(x). feature start ' + numberFormatter$1(bpPosition) + - ' bp start ' + numberFormatter$1(bpStart)); - return x - }; - - const drawGuideLines = (options) => { - if (this.config.hasOwnProperty('guideLines')) { - for (let line of this.config.guideLines) { - if (line.hasOwnProperty('color') && line.hasOwnProperty('y') && line.hasOwnProperty('dotted')) { - let y = yScale(line.y); - let props = { - 'strokeStyle': line['color'], - 'strokeWidth': 2 - }; - if (line['dotted']) IGVGraphics.dashedLine(options.context, 0, y, options.pixelWidth, y, 5, props); - else IGVGraphics.strokeLine(options.context, 0, y, options.pixelWidth, y, props); - } - } - } - }; - - if (features && features.length > 0) { - - if (this.dataRange.min === undefined) this.dataRange.min = 0; - - // Max can be less than min if config.min is set but max left to autoscale. If that's the case there is - // nothing to paint. - if (this.dataRange.max > this.dataRange.min) { - const highlightSamples = this.config.highlightSamples; - const onlyHandleClicksForHighlightedSamples = this.config.onlyHandleClicksForHighlightedSamples; - const clickToHighlight = this.config.clickToHighlight; - - let previousEnd = -1; - let previousValues = {}; - - let highlightConnectorLines = []; - let highlightFeatureLines = []; - - // clickDetectorCache allows fast retrieval of whether a mouse click hits a rendered line segment - // by storing lists of rendered line segments, keyed by their right x coordinate in canvas pixel space. - // this cache is regenerated on every draw. - this.clickDetectorCache = {}; - - for (let feature of features) { - const x1 = getX(feature.start); - const x2 = getX(feature.end); - const previousX = previousEnd >= 0 ? getX(previousEnd) : x1; - - if (isNaN(x1) || isNaN(x2)) continue - // if ((x1 - previousX < X_PIXEL_DIFF_THRESHOLD) && (x2 - x1 < X_PIXEL_DIFF_THRESHOLD)) continue; - - this.clickDetectorCache[x1] = []; - this.clickDetectorCache[x2] = []; - for (let i = 0; i < feature.values.length; i++) { - const sampleName = this.sampleNames[i]; - const value = feature.values[i]; - const y = yScale(value); - if (x1 - previousX >= X_PIXEL_DIFF_THRESHOLD) { - const previousValue = previousValues[sampleName]; - const previousY = yScale(previousValue); - const highlightColor = highlightSamples && highlightSamples[sampleName]; - - - if (highlightColor) { - highlightConnectorLines.push([previousX, previousY, x1, y, highlightColor]); - } else if (clickToHighlight && sampleName in this.config.samplesClickedToHighlight) { - highlightConnectorLines.push([previousX, previousY, x1, y, this.config.samplesClickedToHighlight[sampleName]]); - } else { - IGVGraphics.strokeLine(context, previousX, previousY, x1, y, {strokeStyle: '#D9D9D9'}); - } - if (!onlyHandleClicksForHighlightedSamples || sampleName in highlightSamples) { - this.clickDetectorCache[x1].push([previousX, previousY, x1, y, sampleName, highlightColor || 'gray']); - } - } - - if (x2 - x1 >= X_PIXEL_DIFF_THRESHOLD) { - const highlightColor = highlightSamples && highlightSamples[sampleName]; - if (highlightColor) { - highlightFeatureLines.push([x1, y, x2, y, highlightColor]); - } else if (clickToHighlight && sampleName in this.config.samplesClickedToHighlight) { - highlightFeatureLines.push([x1, y, x2, y, this.config.samplesClickedToHighlight[sampleName]]); - } else { - IGVGraphics.strokeLine(context, x1, y, x2, y, {strokeStyle: 'gray'}); - } - if (!onlyHandleClicksForHighlightedSamples || sampleName in highlightSamples) { - this.clickDetectorCache[x2].push([x1, y, x2, y, sampleName, highlightColor || 'gray']); - } - } - - previousValues[sampleName] = value; - - //IGVGraphics.fillCircle(ctx, px, y, pointSize / 2, {"fillStyle": color, "strokeStyle": color}); - //IGVGraphics.fillRect(ctx, x, y, width, height, {fillStyle: color}); - } - previousEnd = feature.end; - } - - for (let f of highlightConnectorLines) { - IGVGraphics.strokeLine(context, f[0], f[1], f[2], f[3], {strokeStyle: f[4], lineWidth: 1.3}); - } - for (let f of highlightFeatureLines) { - IGVGraphics.strokeLine(context, f[0], f[1], f[2], f[3], {strokeStyle: f[4], lineWidth: 2}); - } - - /* - // If the track includes negative values draw a baseline - if (this.dataRange.min < 0) { - const basepx = (self.dataRange.max / (this.dataRange.max - this.dataRange.min)) * options.pixelHeight; - IGVGraphics.strokeLine(context, 0, basepx, options.pixelWidth, basepx, {strokeStyle: baselineColor}); - } - */ - } - } - - drawGuideLines(options); - } - - doAutoscale(features) { - - let min, max; - if (features.length > 0) { - min = Number.MAX_VALUE; - max = -Number.MAX_VALUE; - - features.forEach(function (feature) { - min = Math.min(min, ...feature.values); - max = Math.max(max, ...feature.values); - }); - - min -= 0.01; - max += 0.01; - } else { - // No features -- default - min = 0; - max = 100; - } - - return {min: min, max: max} - } - - clickedFeatures(clickState) { - //console.warn('click', clickState.canvasX, clickState.canvasY, clickState) - - const BOUNDING_BOX_PADDING = 10; - const MIN_DISTANCE_TO_SEGMENT = 5; - - const clickX = clickState.canvasX; - const clickY = clickState.canvasY; - - let key = null; - for (key of Object.keys(this.clickDetectorCache)) { - key = parseInt(key); - if (key >= clickX) { - break - } - } - - - if (key) { - let closestDistanceSoFar = Number.MAX_VALUE; - let closestResult = []; - const segments = this.clickDetectorCache[key]; - for (let segment of segments) { - const x1 = segment[0]; - const x2 = segment[2]; - if (clickX < x1 || clickX > x2) return [] - - const y1 = segment[1]; - const y2 = segment[3]; - - if ((clickY < Math.min(y1, y2) - BOUNDING_BOX_PADDING) || (clickY > Math.max(y1, y2) + BOUNDING_BOX_PADDING)) continue - - const distance = distanceToLine(clickX, clickY, x1, y1, x2, y2); - if (distance < closestDistanceSoFar) { - closestResult = [{'name': segment[4], 'color': segment[5]}]; - closestDistanceSoFar = distance; - //console.warn('closest:', 'name', segment[4], 'color', segment[5], distance); - } - } - - if (closestDistanceSoFar < MIN_DISTANCE_TO_SEGMENT) { - // clickToHighlight set, add sample to dict of clicked lines - if (this.config.clickToHighlight) { - if (closestResult[0]['name'] in this.config.samplesClickedToHighlight) { - // clicked sample already highlighted => remove if clicked again - delete this.config.samplesClickedToHighlight[closestResult[0]['name']]; - } else if (this.config.clickToHighlight === 'any') { - var colourList = [ - 'red', 'darkblue', 'green', 'teal', 'olivedrab', - 'orange', 'maroon', 'purple', 'blue', 'gold', - ]; - var colour = colourList[Math.floor(Math.random() * (colourList.length + 1))]; - this.config.samplesClickedToHighlight[closestResult[0]['name']] = colour; - } else { - this.config.samplesClickedToHighlight[closestResult[0]['name']] = this.config.clickToHighlight; - } - this.trackView.repaintViews(); // prompt redraw to change colour of clicked sample - } - return closestResult - } - } - - return [] - } - - popupData(clickState, features) { - - if(features === undefined) features = this.clickedFeatures(clickState); - - const items = []; - features.forEach(function (f) { - for (let property of Object.keys(f)) { - if (isSimpleType(f[property])) { - items.push({name: property, value: f[property]}); - } - } - }); - - return items - } - - get supportsWholeGenome() { - return false - } - } - - - function distanceToLine(x, y, ax, ay, bx, by) { - /* - Finds distance between point (x, y) and line defined by points (ax, ay) (bx, by) - based on http://mathworld.wolfram.com/Point-LineDistance2-Dimensional.html - */ - - const bx_minus_ax = bx - ax; - const by_minus_ay = by - ay; - const v = Math.abs(bx_minus_ax * (ay - y) - (ax - x) * by_minus_ay); - const r = Math.sqrt(bx_minus_ax * bx_minus_ax + by_minus_ay * by_minus_ay); - - const distance = r > 0 ? v / r : 0; - //console.warn('Check if', x, y, 'is within', ax, ay, bx, by, '. Distance from line: ', distance); - - return distance - } - - /* - * The MIT License (MIT) - * - * Copyright (c) 2014 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - class RnaStructTrack extends TrackBase { - - constructor(config, browser) { - - super(config, browser); - - // Set defaults - if (!config.height) { - this.height = 300; - } - - this.arcOrientation = false; - - this.theta = Math.PI / 2; - - if ("bp" === config.format) { - this.featureSource = new RNAFeatureSource(config, browser.genome); - } else { - this.featureSource = new TextFeatureSource(config, browser.genome); - } - } - - async getFeatures(chr, start, end) { - const visibilityWindow = this.visibilityWindow; - return this.featureSource.getFeatures({chr, start, end, visibilityWindow}) - } - - draw(options) { - - const ctx = options.context; - - const theta = Math.PI / 2; - const pixelWidth = options.pixelWidth; - const pixelHeight = options.pixelHeight; - options.viewportWidth; - const bpPerPixel = options.bpPerPixel; - const bpStart = options.bpStart; - const xScale = bpPerPixel; - const orienation = this.arcOrientation; - - IGVGraphics.fillRect(ctx, 0, options.pixelTop, pixelWidth, pixelHeight, {'fillStyle': "rgb(255, 255, 255)"}); - - const featureList = options.features; - - if (featureList) { - - // Sort by score -- draw lowest scored features first - sortByScore(featureList, 1); - - for (let feature of featureList) { - - if (feature.startLeft) { - - let sl = Math.round((feature.startLeft - bpStart) / xScale); - let sr = Math.round((feature.startRight - bpStart) / xScale); - let el = Math.round((feature.endLeft - bpStart) / xScale); - let er = Math.round((feature.endRight - bpStart) / xScale); - - ctx.fillStyle = feature.color; - ctx.strokeStyle = feature.color; - ctx.beginPath(); - - // First arc - let x1 = (sl + er) / 2; - let r1 = (er - sl) / 2; - let y1 = this.height; - let sa = Math.PI + (Math.PI / 2 - theta); - let ea = 2 * Math.PI - (Math.PI / 2 - theta); - - if (orienation) { - y1 = 0; - ctx.arc(x1, y1, r1, ea, sa); - ctx.lineTo(er, y1); - } else { - ctx.arc(x1, y1, r1, sa, ea); - ctx.lineTo(el, y1); - } - - // Second arc - const x2 = (sr + el) / 2; - const r2 = (el - sr) / 2; - const y2 = y1; // Only for theta == pi/2 - - if (orienation) { - ctx.arc(x2, y2, r2, sa, ea, true); - ctx.lineTo(el, y2); - } else { - ctx.arc(x2, y2, r2, ea, sa, true); - ctx.lineTo(sl, y2); - } - - ctx.stroke(); - ctx.fill(); - - feature.drawState = {x1: x1, y1: y1, r1: r1, x2: x2, y2: y2, r2: r2, sa: sa, ea: ea}; - } else { - let s = Math.round((feature.start - bpStart) / xScale); - let e = Math.round((feature.end - bpStart) / xScale); - - ctx.strokeStyle = feature.color; - - ctx.beginPath(); - - // First arc - let x = (s + e) / 2; - let r = (e - s) / 2; - let y = this.height; - let sa = Math.PI + (Math.PI / 2 - theta); - let ea = 2 * Math.PI - (Math.PI / 2 - theta); - - if (orienation) { - y = 0; - ctx.arc(x, y, r, ea, sa); - } else { - ctx.arc(x, y, r, sa, ea); - } - - ctx.stroke(); - - feature.drawState = {x1: x, y1: y, r1: r, sa: sa, ea: ea}; - - } - - } - } - } - - clickedFeatures(clickState) { - - const features = super.clickedFeatures(clickState); - - const clicked = []; - - // Sort by score in descending order (opposite order than drawn) - sortByScore(features, -1); - - for (let f of features) { - const ds = f.drawState; - - // Distance from arc radius, or outer arc for type ".bp" - const dx1 = (clickState.canvasX - ds.x1); - const dy1 = (clickState.canvasY - ds.y1); - const d1 = Math.sqrt(dx1 * dx1 + dy1 * dy1); - const outerLim = ds.r1 + 3; - - - let d2; - let innerLim; - if (ds.x2 === undefined) { - d2 = d1; - innerLim = ds.r1 - 3; - - } else { - const dx2 = (clickState.canvasX - ds.x2); - const dy2 = (clickState.canvasY - ds.y2); - d2 = Math.sqrt(dx2 * dx2 + dy2 * dy2); - innerLim = ds.r2 - 3; - } - - - // Between outer and inner arcs, with some tolerance - if (d1 < outerLim && d2 > innerLim) { - clicked.push(f); - break - } - } - return clicked - } - - popupData(clickState, features) { - - if(features === undefined) features = this.clickedFeatures(clickState); - - if (features && features.length > 0) { - - return this.extractPopupData(features[0], this.getGenomeId()) - - } - } - - menuItemList() { - - var self = this; - - return [ - { - name: "Toggle arc direction", - click: function () { - self.arcOrientation = !self.arcOrientation; - self.trackView.repaintViews(); - } - } - ] - - }; - - - } - - function sortByScore(featureList, direction) { - - featureList.sort(function (a, b) { - const s1 = a.score === undefined ? -Number.MAX_VALUE : a.score; - const s2 = b.score === undefined ? -Number.MAX_VALUE : b.score; - const d = direction === undefined ? 1 : direction; - - return d * (s1 - s2) - }); - } - - - class RNAFeatureSource { - - constructor(config, genome) { - this.config = config; - this.genome = genome; - } - - async getFeatures({chr, start, end, bpPerPixel, visibilityWindow}) { - - - const genome = this.genome; - - if (!this.featureCache) { - - const options = buildOptions$1(this.config); - - const data = await igvxhr.loadString(this.config.url, options); - - this.featureCache = new FeatureCache$1(parseBP(data), genome); - - return this.featureCache.queryFeatures(chr, start, end) - - } else { - return this.featureCache.queryFeatures(chr, start, end) - } - - function parseBP(data) { - - if (!data) return null - - const dataWrapper = getDataWrapper(data); - - let header = true; - let line; - const colors = []; - const descriptors = []; - const features = []; - - while ((line = dataWrapper.nextLine()) !== undefined) { - - const tokens = line.split('\t'); - - if (header && line.startsWith("color:")) { - const color = "rgb(" + tokens[1] + "," + tokens[2] + "," + tokens[3] + ")"; - colors.push(color); - if (tokens.length > 4) { - descriptors.push(tokens[4]); - } - // TODO - use label - } else { - header = false; - - const chr = tokens[0]; - const startLeftNuc = Number.parseInt(tokens[1]) - 1; - const startRightNuc = Number.parseInt(tokens[2]) - 1; - const endLeftNuc = Number.parseInt(tokens[3]); - const endRightNuc = Number.parseInt(tokens[4]); - var colorIdx = Number.parseInt(tokens[5]); - const color = colors[colorIdx]; - - - let feature; - if (startLeftNuc <= endRightNuc) { - feature = { - chr: chr, - startLeft: Math.min(startLeftNuc, startRightNuc), - startRight: Math.max(startLeftNuc, startRightNuc), - endLeft: Math.min(endLeftNuc, endRightNuc), - endRight: Math.max(endLeftNuc, endRightNuc), - color: color, - score: colorIdx - }; - } else { - feature = { - chr: chr, - startLeft: Math.min(endLeftNuc, endRightNuc), - startRight: Math.max(endLeftNuc, endRightNuc), - endLeft: Math.min(startLeftNuc, startRightNuc), - endRight: Math.max(startLeftNuc, startRightNuc), - color: color, - score: colorIdx - }; - } - - feature.start = feature.startLeft; - feature.end = feature.endRight; - - if (descriptors.length > colorIdx) { - feature.description = descriptors[colorIdx]; - } - - features.push(feature); - } - } - - return features - } - } - } - - /* - * The MIT License (MIT) - * - * Copyright (c) 2014 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - /** - * Class represents an ideogram of a chromsome cytobands. It is used for the header of a track panel. - * - */ - class IdeogramTrack { - constructor(browser) { - this.browser = browser; - this.type = 'ideogram'; - this.height = 16; - this.order = Number.MIN_SAFE_INTEGER; - this.disableButtons = true; - this.ignoreTrackMenu = true; - } - - async getFeatures(chr, start, end) { - return [] - } - - computePixelHeight(ignore) { - return this.height - } - - draw({context, referenceFrame, pixelWidth, pixelHeight}) { - - const chr = referenceFrame.chr; - const chromosome = referenceFrame.genome.getChromosome(chr); - - if (undefined === chromosome || pixelWidth <= 0 || pixelHeight <= 0 || 'all' === chr.toLowerCase()) { - return - } - - const stainColors = []; - - drawIdeogram({ - ctx: context, - chr, - referenceFrame, - genome: referenceFrame.genome, - width: pixelWidth, - height: pixelHeight, - stainColors - }); - - const widthBP = Math.round(referenceFrame.bpPerPixel * pixelWidth); - const xBP = referenceFrame.start; - - // Total chromosome length can be > chromosome.bpLength for partial fastas. - let chrLength = chromosome.bpLength; - const cytobands = referenceFrame.genome.getCytobands(chr); - if (cytobands && cytobands.length > 0 && cytobands[cytobands.length - 1].end) { - chrLength = Math.max(chrLength, cytobands[cytobands.length - 1].end); - chromosome.bpLength = chrLength; // Correct bp length, bit of a hack - } - - if (widthBP < chrLength) { - - const percentWidth = widthBP / chrLength; - const percentX = xBP / chrLength; - - let x = Math.floor(percentX * pixelWidth); - let ww = Math.floor(percentWidth * pixelWidth); - - x = Math.max(0, x); - x = Math.min(pixelWidth - ww, x); - - // Push current context - context.save(); - - // Draw red box - context.strokeStyle = "red"; - context.lineWidth = (ww < 2) ? 1 : 2; - - const xx = x + (context.lineWidth) / 2; - ww = (ww < 2) ? 1 : ww - context.lineWidth; - - const yy = context.lineWidth / 2; - const hh = pixelHeight - context.lineWidth; - - context.strokeRect(xx, yy, ww, hh); - - // Pop current context - context.restore(); - } - - } - - dispose() { - this.trackView = undefined; - } - } - - function drawIdeogram({ctx, chr, referenceFrame, genome, width, height, stainColors}) { - - const shim = 1; - const shim2 = 0.5 * shim; - const ideogramTop = 0; - - if (undefined === genome) { - return - } - - IGVGraphics.fillRect(ctx, 0, 0, width, height, {fillStyle: IGVColor.greyScale(255)}); - - const cytobands = genome.getCytobands(chr); - if (cytobands) { - - const center = (ideogramTop + height / 2); - - const xC = []; - const yC = []; - - if (0 === cytobands.length) { - return - } - - // Get chrLength from the cytobands -- chromsome.bpLength might not work for igv-reports fasta files, which - // contain only a portion of the chromosome sequence - // *DOESNT WORK* const chrLength = referenceFrame.genome.getChromosome(chr).bpLength; - - const chrLength = cytobands[cytobands.length - 1].end; - const scale = width / chrLength; - - // round rect clipping path - ctx.beginPath(); - IGVGraphics.roundRect(ctx, shim2, shim2 + ideogramTop, width - 2 * shim2, height - 2 * shim2, (height - 2 * shim2) / 2, 0, 1); - ctx.clip(); - - for (let i = 0; i < cytobands.length; i++) { - - const cytoband = cytobands[i]; - const start = scale * cytoband.start; - const end = scale * cytoband.end; - - if (cytoband.type === 'c') { - - if (cytoband.name.charAt(0) === 'p') { - xC[0] = start; - yC[0] = height + ideogramTop; - xC[1] = start; - yC[1] = ideogramTop; - xC[2] = end; - yC[2] = center; - } else { - xC[0] = end; - yC[0] = height + ideogramTop; - xC[1] = end; - yC[1] = ideogramTop; - xC[2] = start; - yC[2] = center; - } - - ctx.fillStyle = "rgb(150, 0, 0)"; - ctx.strokeStyle = "rgb(150, 0, 0)"; - IGVGraphics.polygon(ctx, xC, yC, 1, 0); - } else { - - ctx.fillStyle = getCytobandColor(stainColors, cytoband); - IGVGraphics.fillRect(ctx, start, shim + ideogramTop, (end - start), height - 2 * shim); - } - } - } - - // round rect border - ctx.strokeStyle = IGVColor.greyScale(41); - IGVGraphics.roundRect(ctx, shim2, shim2 + ideogramTop, width - 2 * shim2, height - 2 * shim2, (height - 2 * shim2) / 2, 0, 1); - } - - function getCytobandColor(colors, data) { - - if (data.type === 'c') { // centermere: "acen" - return "rgb(150, 10, 10)" - } else { - var stain = data.stain; // + 4; - - var shade = 230; - if (data.type === 'p') { - shade = Math.floor(230 - stain / 100.0 * 230); - } - var c = colors[shade]; - if (!c) { - c = "rgb(" + shade + "," + shade + "," + shade + ")"; - colors[shade] = c; - } - return c - - } - } - - /* - * The MIT License (MIT) - * - * Copyright (c) 2014 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - let JUNCTION_MOTIF_PALETTE = new PaletteColorTable("Dark2"); - - // Lock in color-to-motif mapping so it's independent of data loading order. This list may not include all possible - // motif values as this varies depending on the RNA-seq pipeline. The current list is based on STAR v2.4 docs. - const someMotifValues = ['GT/AG', 'CT/AC', 'GC/AG', 'CT/GC', 'AT/AC', 'GT/AT', 'non-canonical']; - someMotifValues.forEach(motif => { - JUNCTION_MOTIF_PALETTE.getColor(motif); - }); - - // rendering context with values that only need to be computed once per render, rather than for each splice junction - const junctionRenderingContext = {}; - - class SpliceJunctionTrack extends TrackBase { - - constructor(config, browser) { - super(config, browser); - } - - - init(config) { - - super.init(config); - - this.type = config.type || 'junctions'; - - if (config._featureSource) { - this.featureSource = config._featureSource; - delete config._featureSource; - } else { - this.featureSource = config.featureSource ? - config.featureSource : - FeatureSource(config, this.browser.genome); - } - - this.margin = config.margin === undefined ? 10 : config.margin; - - if (!this.height) { - this.height = 100; - } - - //set defaults - if (config.colorByNumReadsThreshold === undefined) { - config.colorByNumReadsThreshold = 5; - } - } - - async postInit() { - - if (typeof this.featureSource.getHeader === "function") { - this.header = await this.featureSource.getHeader(); - if (this.disposed) return // This track was removed during async load - } - - // Set properties from track line - if (this.header) { - this.setTrackProperties(this.header); - } - - if (this.visibilityWindow === undefined && typeof this.featureSource.defaultVisibilityWindow === 'function') { - this.visibilityWindow = await this.featureSource.defaultVisibilityWindow(); - } - - return this - - } - - get supportsWholeGenome() { - return false - } - - async getFeatures(chr, start, end, bpPerPixel) { - const visibilityWindow = this.visibilityWindow; - return this.featureSource.getFeatures({chr, start, end, bpPerPixel, visibilityWindow}) - }; - - - /** - * The required height in pixels required for the track content. This is not the visible track height, which - * can be smaller (with a scrollbar) or larger. - * - * @param features - * @returns {*} - */ - computePixelHeight(features) { - return this.height - }; - - draw(options) { - - const featureList = options.features; - const ctx = options.context; - const bpPerPixel = options.bpPerPixel; - const bpStart = options.bpStart; - const pixelWidth = options.pixelWidth; - const pixelHeight = options.pixelHeight; - const bpEnd = bpStart + pixelWidth * bpPerPixel + 1; - - - if (!this.config.isMergedTrack) { - IGVGraphics.fillRect(ctx, 0, options.pixelTop, pixelWidth, pixelHeight, {'fillStyle': "rgb(255, 255, 255)"}); - } - - if (featureList) { - - - junctionRenderingContext.referenceFrame = options.viewport.referenceFrame; - junctionRenderingContext.referenceFrameStart = junctionRenderingContext.referenceFrame.start; - junctionRenderingContext.referenceFrameEnd = junctionRenderingContext.referenceFrameStart + - junctionRenderingContext.referenceFrame.toBP(options.viewport.getWidth()); - - // For a given viewport, records where features that are < 2px in width have been rendered already. - // This prevents wasteful rendering of multiple such features onto the same pixels. - junctionRenderingContext.featureZoomOutTracker = {}; - - for (let feature of featureList) { - if (feature.end < bpStart) continue - if (feature.start > bpEnd) break - this.renderJunction(feature, bpStart, bpPerPixel, pixelHeight, ctx); - } - - } else { - console.log("No feature list"); - } - - }; - - /** - * - * @param feature - * @param bpStart genomic location of the left edge of the current canvas - * @param xScale scale in base-pairs per pixel - * @param pixelHeight pixel height of the current canvas - * @param ctx the canvas 2d context - */ - renderJunction(feature, bpStart, xScale, pixelHeight, ctx) { - // cache whether this junction is rendered or filtered out. Use later to exclude non-rendered junctions from click detection. - feature.isVisible = false; - - const junctionLeftPx = Math.round((feature.start - bpStart) / xScale); - const junctionRightPx = Math.round((feature.end - bpStart) / xScale); - const junctionMiddlePx = (junctionLeftPx + junctionRightPx) / 2; - if (junctionRightPx - junctionLeftPx <= 3) { - if (junctionMiddlePx in junctionRenderingContext.featureZoomOutTracker) { - return - } - junctionRenderingContext.featureZoomOutTracker[junctionMiddlePx] = true; - } - - // TODO: cache filter and pixel calculations by doing them earlier when features are initially parsed? - if (this.config.hideAnnotatedJunctions && feature.attributes.annotated_junction === "true") { - return - } - if (this.config.hideUnannotatedJunctions && feature.attributes.annotated_junction === "false") { - return - } - if (this.config.hideMotifs && this.config.hideMotifs.includes(feature.attributes.motif)) { - return - } - if (this.config.hideStrand === feature.strand) { - return - } - - // check if splice junction is inside viewport - if (this.config.minJunctionEndsVisible) { - let numJunctionEndsVisible = 0; - if (feature.start >= junctionRenderingContext.referenceFrameStart && feature.start <= junctionRenderingContext.referenceFrameEnd) { - numJunctionEndsVisible += 1; - } - if (feature.end >= junctionRenderingContext.referenceFrameStart && feature.end <= junctionRenderingContext.referenceFrameEnd) { - numJunctionEndsVisible += 1; - } - if (numJunctionEndsVisible < this.config.minJunctionEndsVisible) { - return - } - } - - let uniquelyMappedReadCount; - let multiMappedReadCount; - let totalReadCount; - if (feature.attributes.uniquely_mapped) { - uniquelyMappedReadCount = parseInt(feature.attributes.uniquely_mapped); - if (uniquelyMappedReadCount < this.config.minUniquelyMappedReads) { - return - } - multiMappedReadCount = parseInt(feature.attributes.multi_mapped); - totalReadCount = uniquelyMappedReadCount + multiMappedReadCount; - if (totalReadCount < this.config.minTotalReads) { - return - } - if (totalReadCount > 0 && multiMappedReadCount / totalReadCount > this.config.maxFractionMultiMappedReads) { - return - } - if (feature.attributes.maximum_spliced_alignment_overhang && parseInt(feature.attributes.maximum_spliced_alignment_overhang) < this.config.minSplicedAlignmentOverhang) { - return - } - } - - let numSamplesWithThisJunction; - if (feature.attributes.num_samples_with_this_junction) { - numSamplesWithThisJunction = parseInt(feature.attributes.num_samples_with_this_junction); - if (this.config.minSamplesWithThisJunction && numSamplesWithThisJunction < this.config.minSamplesWithThisJunction) { - return - } - if (this.config.maxSamplesWithThisJunction && numSamplesWithThisJunction > this.config.maxSamplesWithThisJunction) { - return - } - if (feature.attributes.num_samples_total) { - feature.attributes.percent_samples_with_this_junction = 100 * numSamplesWithThisJunction / Number(feature.attributes.num_samples_total); - if (this.config.minPercentSamplesWithThisJunction) { - if (feature.attributes.percent_samples_with_this_junction < this.config.minPercentSamplesWithThisJunction || - feature.attributes.percent_samples_with_this_junction > this.config.maxPercentSamplesWithThisJunction) { - return - } - } - } - } - - const py = this.margin; - const rowHeight = this.height; - - const cy = py + 0.5 * rowHeight; - let topY = py; - const bottomY = py + rowHeight; - const bezierBottomY = bottomY - 10; - - // draw the junction arc - const bezierControlLeftPx = (junctionLeftPx + junctionMiddlePx) / 2; - const bezierControlRightPx = (junctionMiddlePx + junctionRightPx) / 2; - - let lineWidth = 1; - if (feature.attributes.line_width) { - lineWidth = Number(feature.attributes.line_width); - } else { - if (this.config.thicknessBasedOn === undefined || this.config.thicknessBasedOn === 'numUniqueReads') { - lineWidth = uniquelyMappedReadCount; - } else if (this.config.thicknessBasedOn === 'numReads') { - lineWidth = totalReadCount; - } else if (this.config.thicknessBasedOn === 'numSamplesWithThisJunction') { - if (numSamplesWithThisJunction !== undefined) { - lineWidth = numSamplesWithThisJunction; - } - } - lineWidth = 1 + Math.log(lineWidth + 1) / Math.log(12); - } - - let bounceHeight; - if (this.config.bounceHeightBasedOn === undefined || this.config.bounceHeightBasedOn === 'random') { - // randomly but deterministically stagger topY coordinates to reduce overlap - bounceHeight = (feature.start + feature.end) % 7; - } else if (this.config.bounceHeightBasedOn === 'distance') { - bounceHeight = 6 * (feature.end - feature.start) / (junctionRenderingContext.referenceFrameEnd - junctionRenderingContext.referenceFrameStart); - } else if (this.config.bounceHeightBasedOn === 'thickness') { - bounceHeight = 2 * lineWidth; - } - topY += rowHeight * Math.max(7 - bounceHeight, 0) / 10; - - let color; - if (feature.attributes.color) { - color = feature.attributes.color; // Explicit setting - } else if (this.config.colorBy === undefined || this.config.colorBy === 'numUniqueReads') { - color = uniquelyMappedReadCount > this.config.colorByNumReadsThreshold ? 'blue' : '#AAAAAA'; // color gradient? - } else if (this.config.colorBy === 'numReads') { - color = totalReadCount > this.config.colorByNumReadsThreshold ? 'blue' : '#AAAAAA'; - } else if (this.config.colorBy === 'isAnnotatedJunction') { - color = feature.attributes.annotated_junction === "true" ? '#b0b0ec' : 'orange'; - } else if (this.config.colorBy === 'strand') { - color = feature.strand === "+" ? '#b0b0ec' : '#ecb0b0'; - } else if (this.config.colorBy === 'motif') { - color = JUNCTION_MOTIF_PALETTE.getColor(feature.attributes.motif); - } else { - color = '#AAAAAA'; - } - - let label = ""; - if (feature.attributes.label) { - label = feature.attributes.label.replace(/_/g, " "); - } else if (this.config.labelWith === undefined || this.config.labelWith === 'uniqueReadCount') { - //default label - label = uniquelyMappedReadCount; - } else if (this.config.labelWith === 'totalReadCount') { - label = totalReadCount; - } else if (this.config.labelWith === 'numSamplesWithThisJunction') { - if (numSamplesWithThisJunction !== undefined) { - label = numSamplesWithThisJunction; - } - } else if (this.config.labelWith === 'percentSamplesWithThisJunction') { - if (feature.attributes.percent_samples_with_this_junction !== undefined) { - label = feature.attributes.percent_samples_with_this_junction.toFixed(0) + '%'; - } - } else if (this.config.labelWith === 'motif') { - if (feature.attributes.motif !== undefined) { - label += feature.attributes.motif; - } - } - - if (this.config.labelWithInParen === 'uniqueReadCount') { - label += ' (' + uniquelyMappedReadCount + ')'; - } else if (this.config.labelWithInParen === 'totalReadCount') { - label += ' (' + totalReadCount + ')'; - } else if (this.config.labelWithInParen === 'multiMappedReadCount') { - if (multiMappedReadCount > 0) { - label += ' (+' + multiMappedReadCount + ')'; - } - } else if (this.config.labelWithInParen === 'numSamplesWithThisJunction') { - if (numSamplesWithThisJunction !== undefined) { - label += ' (' + numSamplesWithThisJunction + ')'; - } - } else if (this.config.labelWithInParen === 'percentSamplesWithThisJunction') { - if (feature.attributes.percent_samples_with_this_junction !== undefined) { - label += ' (' + feature.attributes.percent_samples_with_this_junction.toFixed(0) + '%)'; - } - } else if (this.config.labelWithInParen === 'motif') { - if (feature.attributes.motif !== undefined) { - label += ` ${feature.attributes.motif}`; - } - } - - // data source: STAR splice junctions (eg. SJ.out.tab file converted to bed). - // .bed "name" field used to store unique + multi-mapped read counts, so: - // feature.score: unique spanning read counts - // feature.name: unique + multi-mapped spanning read counts - //example feature: { chr: "chr17", start: 39662344, end: 39662803, name: "59", row: 0, score: 38, strand: "+"} - feature.isVisible = true; - ctx.beginPath(); - ctx.moveTo(junctionLeftPx, bezierBottomY); - ctx.bezierCurveTo(bezierControlLeftPx, topY, bezierControlRightPx, topY, junctionRightPx, bezierBottomY); - - ctx.lineWidth = lineWidth; - ctx.strokeStyle = color; - ctx.stroke(); - - const drawArrowhead = (ctx, x, y, size) => { - //TODO draw better arrow heads: https://stackoverflow.com/questions/21052972/curved-thick-arrows-on-canvas - ctx.beginPath(); - ctx.moveTo(x, y); - ctx.lineTo(x - size / 2, y - size); - ctx.lineTo(x + size / 2, y - size); - ctx.lineTo(x, y); - ctx.closePath(); - ctx.fill(); - }; - - if (feature.attributes.left_shape || feature.attributes.right_shape) { - ctx.fillStyle = color; - const arrowSize = ctx.lineWidth > 2 ? 10 : 7; - if (feature.attributes.left_shape) { - drawArrowhead(ctx, junctionLeftPx, bezierBottomY, arrowSize); - } - if (feature.attributes.right_shape) { - drawArrowhead(ctx, junctionRightPx, bezierBottomY, arrowSize); - } - } - - ctx.fillText(label, junctionMiddlePx - ctx.measureText(label).width / 2, (7 * topY + cy) / 8); - } - - clickedFeatures(clickState) { - - const allFeatures = super.clickedFeatures(clickState); - - return allFeatures.filter(function (feature) { - return (feature.isVisible && feature.attributes) - }) - } - - /** - * Return "popup data" for feature @ genomic location. Data is an array of key-value pairs - */ - popupData(clickState, features) { - - if (features === undefined) features = this.clickedFeatures(clickState); - const genomicLocation = clickState.genomicLocation; - - const data = []; - for (let feature of features) { - - const featureData = (typeof feature.popupData === "function") ? - feature.popupData(genomicLocation) : - this.extractPopupData(feature._f || feature, this.getGenomeId()); - - if (featureData) { - if (data.length > 0) { - data.push("

"); - } - - Array.prototype.push.apply(data, featureData); - } - } - - return data - } - - /** - * Called when the track is removed. Do any needed cleanup here - */ - dispose() { - this.trackView = undefined; - } - } - - class RemoteFile$1 { - - constructor(args) { - this.config = args; - this.url = mapUrl$2(args.path || args.url); - } - - - async read(position, length) { - - //console.log(`${position} - ${position + length} (${length})`) - - const headers = this.config.headers || {}; - - if (position !== undefined && length) { - const rangeString = "bytes=" + position + "-" + (position + length - 1); - headers['Range'] = rangeString; - } - - let url = this.url.slice(); // slice => copy - if (this.config.oauthToken) { - const token = resolveToken(this.config.oauthToken); - headers['Authorization'] = `Bearer ${token}`; - } - - if (this.config.apiKey) { - url = addParameter$1(url, "key", this.config.apiKey); - } - - const response = await fetch(url, { - method: 'GET', - headers: headers, - redirect: 'follow', - mode: 'cors', - }); - - const status = response.status; - - if (status >= 400) { - const err = Error(response.statusText); - err.code = status; - throw err - } else { - return response.arrayBuffer() - } - - /** - * token can be a string, a function that returns a string, or a function that returns a Promise for a string - * @param token - * @returns {Promise<*>} - */ - async function resolveToken(token) { - if (typeof token === 'function') { - return await Promise.resolve(token()) // Normalize the result to a promise, since we don't know what the function returns - } else { - return token - } - } - - } - } - - - function mapUrl$2(url) { - - if (url.includes("//www.dropbox.com")) { - return url.replace("//www.dropbox.com", "//dl.dropboxusercontent.com") - } else if (url.startsWith("ftp://ftp.ncbi.nlm.nih.gov")) { - return url.replace("ftp://", "https://") - } else { - return url - } - } - - - function addParameter$1(url, name, value) { - const paramSeparator = url.includes("?") ? "&" : "?"; - return url + paramSeparator + name + "=" + value - } - - class BufferedFile$1 { - - constructor(args) { - this.file = args.file; - this.fetchSize = args.fetchSize || 16000; - this.maxSize = args.maxSize || 1000000; - this.buffers = []; - } - - async read(position, length) { - - - let overlappingBuffers = this.buffers.filter( b => b.overlaps(position, position + length)); - - // See if any buffers completely contain request, if so we're done - for(let buffer of overlappingBuffers) { - if(buffer.contains(position, position + length)) { - return buffer.slice(position, position + length) - } - } - - - if(overlappingBuffers.length === 0) { - - // No overlap with any existing buffer - let size = Math.max(length, this.fetchSize); - - // Find index of first buffer to the right, if any, to potentially limit size - this.buffers.sort((a, b) => a.start - b.start); - const idx = binarySearch(this.buffers, (b) => b.start > position, 0); - if(idx < this.buffers.length) { - size = Math.min(size, this.buffers[idx].start - position); - } - - const bufferStart = position; - const bufferData = await this.file.read(bufferStart, size); - const buffer = new Buffer$1(bufferStart, bufferData); - this.addBuffer(buffer); - - return buffer.slice(position, position + length) - } else { - - // console.log("Cache hit") - // Some overlap. Fill gaps - overlappingBuffers.sort((a, b) => a.start - b.start); - const allBuffers = []; - let currentEnd = position; - for (let ob of overlappingBuffers) { - if (currentEnd < ob.start) { - const bufferStart = currentEnd; - const bufferSize = ob.start - currentEnd; - const bufferData = await this.file.read(bufferStart, bufferSize); - const buffer = new Buffer$1(bufferStart, bufferData); - allBuffers.push(buffer); - } - allBuffers.push(ob); - currentEnd = ob.end; - } - - // Check end - const requestedEnd = position + length; - if (requestedEnd > currentEnd) { - const bufferStart = currentEnd; - const bufferSize = requestedEnd - bufferStart; - const bufferData = await this.file.read(bufferStart, bufferSize); - const buffer = new Buffer$1(bufferStart, bufferData); - allBuffers.push(buffer); - } - - const newStart = allBuffers[0].start; - const newArrayBuffer = concatArrayBuffers(allBuffers.map(b => b.buffer)); - const newBuffer = new Buffer$1(newStart, newArrayBuffer); - - // Replace the overlapping buffers with the new composite one - const tmp = new Set(overlappingBuffers); - this.buffers = this.buffers.filter(b => !tmp.has(b)); - this.addBuffer(newBuffer); - - return newBuffer.slice(position, position + length) - } - - } - - addBuffer(buffer) { - - const size = this.buffers.reduce((a,b) => a + b.size, 0) + buffer.size; - if(size > this.maxSize) { - // console.log(`max buffer size exceeded`) - const overage = size - this.maxSize; - this.buffers.sort((a,b) => a.creationTime - b.creationTime); - let sum = 0; - let i; - for(i=0; i overage) { - break - } - } - // console.log('removing buffers') - // for(let j=0; j this.buffer.byteLength) { - throw Error("buffer bounds error") - } - return this.buffer.slice(start - this.start, end - this.start) - } - - get end() { - return this.start + this.buffer.byteLength - } - - get size() { - return this.buffer.byteLength - } - - contains(start, end) { - return start >= this.start && end <= this.end - } - - overlaps(start, end) { - return (start > this.start && start < this.end) || (end > this.start && end < this.end) - } - - toString() { - return `Buffer ${this.creationTime} ${this.start} - ${this.end}` - } - - } - - /** - * concatenates 2 array buffers. - * Credit: https://gist.github.com/72lions/4528834 - * - * @private - * @param {ArrayBuffers} buffer1 The first buffer. - * @param {ArrayBuffers} buffer2 The second buffer. - * @return {ArrayBuffers} The new ArrayBuffer created out of the two. - */ - function concatArrayBuffers(buffers) { - const size = buffers.reduce((a,b) => a + b.byteLength, 0); - const tmp = new Uint8Array(size); - let offset = 0; - for(let b of buffers) { - tmp.set(new Uint8Array(b), offset); - offset += b.byteLength; - } - return tmp.buffer - } - - /** - * Return 0 <= i <= array.length such that !pred(array[i - 1]) && pred(array[i]). - * - * returns an index 0 ≤ i ≤ array.length such that the given predicate is false for array[i - 1] and true for array[i]* * - */ - function binarySearch(array, pred, min) { - let lo = min - 1, hi = array.length; - while (1 + lo < hi) { - const mi = lo + ((hi - lo) >> 1); - if (pred(array[mi])) { - hi = mi; - } else { - lo = mi; - } - } - return hi - } - - class BlobFile { - - constructor(blob) { - this.file = blob; - } - - async read(position, length) { - - if(length === 0) { - return new ArrayBuffer() - } - - const blob = (position != undefined && length) ? - this.file.slice(position, position + length) : - this.file; - - return blob.arrayBuffer() - } - } - - var __defProp = Object.defineProperty; - var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; - var __publicField = (obj, key, value) => { - __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value); - return value; - }; - - // esm/core.js - async function _unpack_struct_from_async(structure, async_buf, offset = 0) { - var output = /* @__PURE__ */ new Map(); - for (let [key, fmt] of structure.entries()) { - let value = await struct.unpack_from_async("<" + fmt, async_buf, offset); - offset += struct.calcsize(fmt); - if (value.length == 1) { - value = value[0]; - } - output.set(key, value); - } - return output; - } - function _unpack_struct_from(structure, buf, offset = 0) { - var output = /* @__PURE__ */ new Map(); - for (let [key, fmt] of structure.entries()) { - let value = struct.unpack_from("<" + fmt, buf, offset); - offset += struct.calcsize(fmt); - if (value.length == 1) { - value = value[0]; - } - output.set(key, value); - } - return output; - } - function assert(thing) { - if (!thing) { - thing(); - } - } - function _structure_size(structure) { - var fmt = "<" + Array.from(structure.values()).join(""); - return struct.calcsize(fmt); - } - function _padded_size(size, padding_multiple = 8) { - return Math.ceil(size / padding_multiple) * padding_multiple; - } - var dtype_to_format = { - "u": "Uint", - "i": "Int", - "f": "Float" - }; - function dtype_getter(dtype_str) { - var big_endian = struct._is_big_endian(dtype_str); - var getter, nbytes; - if (/S/.test(dtype_str)) { - getter = "getString"; - nbytes = ((dtype_str.match(/S(\d*)/) || [])[1] || 1) | 0; - } else { - let [_, fstr, bytestr] = dtype_str.match(/[<>=!@]?(i|u|f)(\d*)/); - nbytes = parseInt(bytestr || 4, 10); - let nbits = nbytes * 8; - getter = "get" + dtype_to_format[fstr] + nbits.toFixed(); - } - return [getter, big_endian, nbytes]; - } - var Struct = class { - constructor() { - this.big_endian = isBigEndian(); - this.getters = { - "s": "getUint8", - "b": "getInt8", - "B": "getUint8", - "h": "getInt16", - "H": "getUint16", - "i": "getInt32", - "I": "getUint32", - "l": "getInt32", - "L": "getUint32", - "q": "getInt64", - "Q": "getUint64", - "f": "getFloat32", - "d": "getFloat64" - }; - this.byte_lengths = { - "s": 1, - "b": 1, - "B": 1, - "h": 2, - "H": 2, - "i": 4, - "I": 4, - "l": 4, - "L": 4, - "q": 8, - "Q": 8, - "f": 4, - "d": 8 - }; - let all_formats = Object.keys(this.byte_lengths).join(""); - this.fmt_size_regex = "(\\d*)([" + all_formats + "])"; - } - calcsize(fmt) { - var size = 0; - var match; - var regex = new RegExp(this.fmt_size_regex, "g"); - while ((match = regex.exec(fmt)) !== null) { - let n = parseInt(match[1] || 1, 10); - let f = match[2]; - let subsize = this.byte_lengths[f]; - size += n * subsize; - } - return size; - } - _is_big_endian(fmt) { - var big_endian; - if (/^)/.test(fmt)) { - big_endian = true; - } else { - big_endian = this.big_endian; - } - return big_endian; - } - async unpack_from_async(fmt, async_buf, offset) { - offset = Number.parseInt(offset || 0); - const total_size = this.calcsize(fmt); - const local_buffer = await async_buf.slice(offset, offset + total_size); - let local_offset = 0; - var view = new DataView64(local_buffer); - var output = []; - var big_endian = this._is_big_endian(fmt); - var match; - var regex = new RegExp(this.fmt_size_regex, "g"); - while ((match = regex.exec(fmt)) !== null) { - let n = parseInt(match[1] || 1, 10); - let f = match[2]; - let getter = this.getters[f]; - let size = this.byte_lengths[f]; - if (f == "s") { - output.push(new TextDecoder().decode(local_buffer.slice(local_offset, local_offset + n))); - local_offset += n; - } else { - for (var i = 0; i < n; i++) { - output.push(view[getter](local_offset, !big_endian)); - local_offset += size; - } - } - } - return output; - } - unpack_from(fmt, buffer, offset) { - offset = Number.parseInt(offset || 0); - const total_size = this.calcsize(fmt); - const local_buffer = buffer.slice(offset, offset + total_size); - let local_offset = 0; - var view = new DataView64(local_buffer); - var output = []; - var big_endian = this._is_big_endian(fmt); - var match; - var regex = new RegExp(this.fmt_size_regex, "g"); - while ((match = regex.exec(fmt)) !== null) { - let n = parseInt(match[1] || 1, 10); - let f = match[2]; - let getter = this.getters[f]; - let size = this.byte_lengths[f]; - if (f == "s") { - output.push(new TextDecoder().decode(local_buffer.slice(local_offset, local_offset + n))); - local_offset += n; - } else { - for (var i = 0; i < n; i++) { - output.push(view[getter](local_offset, !big_endian)); - local_offset += size; - } - } - } - return output; - } - }; - var struct = new Struct(); - function isBigEndian() { - const array = new Uint8Array(4); - const view = new Uint32Array(array.buffer); - return !((view[0] = 1) & array[0]); - } - var DataView64 = class extends DataView { - getUint64(byteOffset, littleEndian) { - const left = BigInt(this.getUint32(byteOffset, littleEndian)); - const right = BigInt(this.getUint32(byteOffset + 4, littleEndian)); - let combined = littleEndian ? left + (right << 32n) : (left << 32n) + right; - return Number.parseInt(combined); - } - getInt64(byteOffset, littleEndian) { - var low, high; - if (littleEndian) { - low = this.getUint32(byteOffset, true); - high = this.getInt32(byteOffset + 4, true); - } else { - high = this.getInt32(byteOffset, false); - low = this.getUint32(byteOffset + 4, false); - } - let combined = BigInt(low) + (BigInt(high) << 32n); - return Number.parseInt(combined); - } - getString(byteOffset, littleEndian, length) { - const str_buffer = this.buffer.slice(byteOffset, byteOffset + length); - const decoder = new TextDecoder(); - return decoder.decode(str_buffer); - } - getVLENStruct(byteOffset, littleEndian, length) { - let item_size = this.getUint32(byteOffset, littleEndian); - let collection_address = this.getUint64(byteOffset + 4, littleEndian); - let object_index = this.getUint32(byteOffset + 12, littleEndian); - return [item_size, collection_address, object_index]; - } - }; - function bitSize(integer) { - return integer.toString(2).length; - } - function _unpack_integer(nbytes, buf, offset = 0, littleEndian = true) { - const local_buffer = buf.slice(offset, offset + nbytes); - let bytes = new Uint8Array(local_buffer); - if (!littleEndian) { - bytes.reverse(); - } - let integer = bytes.reduce((accumulator, currentValue, index) => accumulator + (currentValue << index * 8), 0); - return integer; - } - - // esm/datatype-msg.js - var DatatypeMessage = class { - constructor(buf, offset) { - this.buf = buf; - this.offset = offset; - this.dtype = this.determine_dtype(); - } - async determine_dtype() { - let datatype_msg = await _unpack_struct_from_async(DATATYPE_MSG, this.buf, this.offset); - this.offset += DATATYPE_MSG_SIZE; - let datatype_class = datatype_msg.get("class_and_version") & 15; - if (datatype_class == DATATYPE_FIXED_POINT) { - return this._determine_dtype_fixed_point(datatype_msg); - } else if (datatype_class == DATATYPE_FLOATING_POINT) { - return this._determine_dtype_floating_point(datatype_msg); - } else if (datatype_class == DATATYPE_TIME) { - throw "Time datatype class not supported."; - } else if (datatype_class == DATATYPE_STRING) { - return this._determine_dtype_string(datatype_msg); - } else if (datatype_class == DATATYPE_BITFIELD) { - throw "Bitfield datatype class not supported."; - } else if (datatype_class == DATATYPE_OPAQUE) { - return { - datatype_class: DATATYPE_OPAQUE, - size: datatype_msg.get("size") - }; - } else if (datatype_class == DATATYPE_COMPOUND) { - return this._determine_dtype_compound(datatype_msg); - } else if (datatype_class == DATATYPE_REFERENCE) { - return ["REFERENCE", datatype_msg.get("size")]; - } else if (datatype_class == DATATYPE_ENUMERATED) { - return this.determine_dtype(); - } else if (datatype_class == DATATYPE_ARRAY) { - throw "Array datatype class not supported."; - } else if (datatype_class == DATATYPE_VARIABLE_LENGTH) { - let vlen_type = this._determine_dtype_vlen(datatype_msg); - if (vlen_type[0] == "VLEN_SEQUENCE") { - let base_type = this.determine_dtype(); - vlen_type = ["VLEN_SEQUENCE", base_type]; - } - return vlen_type; - } else { - throw "Invalid datatype class " + datatype_class; - } - } - _determine_dtype_fixed_point(datatype_msg) { - let length_in_bytes = datatype_msg.get("size"); - if (![1, 2, 4, 8].includes(length_in_bytes)) { - throw "Unsupported datatype size"; - } - let signed = datatype_msg.get("class_bit_field_0") & 8; - var dtype_char; - if (signed > 0) { - dtype_char = "i"; - } else { - dtype_char = "u"; - } - let byte_order = datatype_msg.get("class_bit_field_0") & 1; - var byte_order_char; - if (byte_order == 0) { - byte_order_char = "<"; - } else { - byte_order_char = ">"; - } - this.offset += 4; - return byte_order_char + dtype_char + length_in_bytes.toFixed(); - } - _determine_dtype_floating_point(datatype_msg) { - let length_in_bytes = datatype_msg.get("size"); - if (![1, 2, 4, 8].includes(length_in_bytes)) { - throw "Unsupported datatype size"; - } - let dtype_char = "f"; - let byte_order = datatype_msg.get("class_bit_field_0") & 1; - var byte_order_char; - if (byte_order == 0) { - byte_order_char = "<"; - } else { - byte_order_char = ">"; - } - this.offset += 12; - return byte_order_char + dtype_char + length_in_bytes.toFixed(); - } - _determine_dtype_string(datatype_msg) { - return "S" + datatype_msg.get("size").toFixed(); - } - _determine_dtype_vlen(datatype_msg) { - let vlen_type = datatype_msg.get("class_bit_field_0") & 1; - if (vlen_type != 1) { - return ["VLEN_SEQUENCE", 0, 0]; - } - let padding_type = datatype_msg.get("class_bit_field_0") >> 4; - let character_set = datatype_msg.get("class_bit_field_1") & 1; - return ["VLEN_STRING", padding_type, character_set]; - } - _determine_dtype_compound(datatype_msg) { - throw "Compound type not yet implemented!"; - } - }; - var DATATYPE_MSG = /* @__PURE__ */ new Map([ - ["class_and_version", "B"], - ["class_bit_field_0", "B"], - ["class_bit_field_1", "B"], - ["class_bit_field_2", "B"], - ["size", "I"] - ]); - var DATATYPE_MSG_SIZE = _structure_size(DATATYPE_MSG); - var COMPOUND_PROP_DESC_V1 = /* @__PURE__ */ new Map([ - ["offset", "I"], - ["dimensionality", "B"], - ["reserved_0", "B"], - ["reserved_1", "B"], - ["reserved_2", "B"], - ["permutation", "I"], - ["reserved_3", "I"], - ["dim_size_1", "I"], - ["dim_size_2", "I"], - ["dim_size_3", "I"], - ["dim_size_4", "I"] - ]); - _structure_size(COMPOUND_PROP_DESC_V1); - var DATATYPE_FIXED_POINT = 0; - var DATATYPE_FLOATING_POINT = 1; - var DATATYPE_TIME = 2; - var DATATYPE_STRING = 3; - var DATATYPE_BITFIELD = 4; - var DATATYPE_OPAQUE = 5; - var DATATYPE_COMPOUND = 6; - var DATATYPE_REFERENCE = 7; - var DATATYPE_ENUMERATED = 8; - var DATATYPE_VARIABLE_LENGTH = 9; - var DATATYPE_ARRAY = 10; - function zero$1(buf) { - let len = buf.length; - while (--len >= 0) { - buf[len] = 0; - } - } - var MIN_MATCH$1 = 3; - var MAX_MATCH$1 = 258; - var LENGTH_CODES$1 = 29; - var LITERALS$1 = 256; - var L_CODES$1 = LITERALS$1 + 1 + LENGTH_CODES$1; - var D_CODES$1 = 30; - var DIST_CODE_LEN = 512; - var static_ltree = new Array((L_CODES$1 + 2) * 2); - zero$1(static_ltree); - var static_dtree = new Array(D_CODES$1 * 2); - zero$1(static_dtree); - var _dist_code = new Array(DIST_CODE_LEN); - zero$1(_dist_code); - var _length_code = new Array(MAX_MATCH$1 - MIN_MATCH$1 + 1); - zero$1(_length_code); - var base_length = new Array(LENGTH_CODES$1); - zero$1(base_length); - var base_dist = new Array(D_CODES$1); - zero$1(base_dist); - var adler32 = (adler, buf, len, pos) => { - let s1 = adler & 65535 | 0, s2 = adler >>> 16 & 65535 | 0, n = 0; - while (len !== 0) { - n = len > 2e3 ? 2e3 : len; - len -= n; - do { - s1 = s1 + buf[pos++] | 0; - s2 = s2 + s1 | 0; - } while (--n); - s1 %= 65521; - s2 %= 65521; - } - return s1 | s2 << 16 | 0; - }; - var adler32_1 = adler32; - var makeTable = () => { - let c, table = []; - for (var n = 0; n < 256; n++) { - c = n; - for (var k = 0; k < 8; k++) { - c = c & 1 ? 3988292384 ^ c >>> 1 : c >>> 1; - } - table[n] = c; - } - return table; - }; - var crcTable = new Uint32Array(makeTable()); - var crc32 = (crc, buf, len, pos) => { - const t = crcTable; - const end = pos + len; - crc ^= -1; - for (let i = pos; i < end; i++) { - crc = crc >>> 8 ^ t[(crc ^ buf[i]) & 255]; - } - return crc ^ -1; - }; - var crc32_1 = crc32; - var messages = { - 2: "need dictionary", - 1: "stream end", - 0: "", - "-1": "file error", - "-2": "stream error", - "-3": "data error", - "-4": "insufficient memory", - "-5": "buffer error", - "-6": "incompatible version" - }; - var constants$2 = { - Z_NO_FLUSH: 0, - Z_PARTIAL_FLUSH: 1, - Z_SYNC_FLUSH: 2, - Z_FULL_FLUSH: 3, - Z_FINISH: 4, - Z_BLOCK: 5, - Z_TREES: 6, - Z_OK: 0, - Z_STREAM_END: 1, - Z_NEED_DICT: 2, - Z_ERRNO: -1, - Z_STREAM_ERROR: -2, - Z_DATA_ERROR: -3, - Z_MEM_ERROR: -4, - Z_BUF_ERROR: -5, - Z_NO_COMPRESSION: 0, - Z_BEST_SPEED: 1, - Z_BEST_COMPRESSION: 9, - Z_DEFAULT_COMPRESSION: -1, - Z_FILTERED: 1, - Z_HUFFMAN_ONLY: 2, - Z_RLE: 3, - Z_FIXED: 4, - Z_DEFAULT_STRATEGY: 0, - Z_BINARY: 0, - Z_TEXT: 1, - Z_UNKNOWN: 2, - Z_DEFLATED: 8 - }; - var _has = (obj, key) => { - return Object.prototype.hasOwnProperty.call(obj, key); - }; - var assign = function(obj) { - const sources = Array.prototype.slice.call(arguments, 1); - while (sources.length) { - const source = sources.shift(); - if (!source) { - continue; - } - if (typeof source !== "object") { - throw new TypeError(source + "must be non-object"); - } - for (const p in source) { - if (_has(source, p)) { - obj[p] = source[p]; - } - } - } - return obj; - }; - var flattenChunks = (chunks) => { - let len = 0; - for (let i = 0, l = chunks.length; i < l; i++) { - len += chunks[i].length; - } - const result = new Uint8Array(len); - for (let i = 0, pos = 0, l = chunks.length; i < l; i++) { - let chunk = chunks[i]; - result.set(chunk, pos); - pos += chunk.length; - } - return result; - }; - var common = { - assign, - flattenChunks - }; - var STR_APPLY_UIA_OK = true; - try { - String.fromCharCode.apply(null, new Uint8Array(1)); - } catch (__) { - STR_APPLY_UIA_OK = false; - } - var _utf8len = new Uint8Array(256); - for (let q = 0; q < 256; q++) { - _utf8len[q] = q >= 252 ? 6 : q >= 248 ? 5 : q >= 240 ? 4 : q >= 224 ? 3 : q >= 192 ? 2 : 1; - } - _utf8len[254] = _utf8len[254] = 1; - var string2buf = (str) => { - if (typeof TextEncoder === "function" && TextEncoder.prototype.encode) { - return new TextEncoder().encode(str); - } - let buf, c, c2, m_pos, i, str_len = str.length, buf_len = 0; - for (m_pos = 0; m_pos < str_len; m_pos++) { - c = str.charCodeAt(m_pos); - if ((c & 64512) === 55296 && m_pos + 1 < str_len) { - c2 = str.charCodeAt(m_pos + 1); - if ((c2 & 64512) === 56320) { - c = 65536 + (c - 55296 << 10) + (c2 - 56320); - m_pos++; - } - } - buf_len += c < 128 ? 1 : c < 2048 ? 2 : c < 65536 ? 3 : 4; - } - buf = new Uint8Array(buf_len); - for (i = 0, m_pos = 0; i < buf_len; m_pos++) { - c = str.charCodeAt(m_pos); - if ((c & 64512) === 55296 && m_pos + 1 < str_len) { - c2 = str.charCodeAt(m_pos + 1); - if ((c2 & 64512) === 56320) { - c = 65536 + (c - 55296 << 10) + (c2 - 56320); - m_pos++; - } - } - if (c < 128) { - buf[i++] = c; - } else if (c < 2048) { - buf[i++] = 192 | c >>> 6; - buf[i++] = 128 | c & 63; - } else if (c < 65536) { - buf[i++] = 224 | c >>> 12; - buf[i++] = 128 | c >>> 6 & 63; - buf[i++] = 128 | c & 63; - } else { - buf[i++] = 240 | c >>> 18; - buf[i++] = 128 | c >>> 12 & 63; - buf[i++] = 128 | c >>> 6 & 63; - buf[i++] = 128 | c & 63; - } - } - return buf; - }; - var buf2binstring = (buf, len) => { - if (len < 65534) { - if (buf.subarray && STR_APPLY_UIA_OK) { - return String.fromCharCode.apply(null, buf.length === len ? buf : buf.subarray(0, len)); - } - } - let result = ""; - for (let i = 0; i < len; i++) { - result += String.fromCharCode(buf[i]); - } - return result; - }; - var buf2string = (buf, max) => { - const len = max || buf.length; - if (typeof TextDecoder === "function" && TextDecoder.prototype.decode) { - return new TextDecoder().decode(buf.subarray(0, max)); - } - let i, out; - const utf16buf = new Array(len * 2); - for (out = 0, i = 0; i < len; ) { - let c = buf[i++]; - if (c < 128) { - utf16buf[out++] = c; - continue; - } - let c_len = _utf8len[c]; - if (c_len > 4) { - utf16buf[out++] = 65533; - i += c_len - 1; - continue; - } - c &= c_len === 2 ? 31 : c_len === 3 ? 15 : 7; - while (c_len > 1 && i < len) { - c = c << 6 | buf[i++] & 63; - c_len--; - } - if (c_len > 1) { - utf16buf[out++] = 65533; - continue; - } - if (c < 65536) { - utf16buf[out++] = c; - } else { - c -= 65536; - utf16buf[out++] = 55296 | c >> 10 & 1023; - utf16buf[out++] = 56320 | c & 1023; - } - } - return buf2binstring(utf16buf, out); - }; - var utf8border = (buf, max) => { - max = max || buf.length; - if (max > buf.length) { - max = buf.length; - } - let pos = max - 1; - while (pos >= 0 && (buf[pos] & 192) === 128) { - pos--; - } - if (pos < 0) { - return max; - } - if (pos === 0) { - return max; - } - return pos + _utf8len[buf[pos]] > max ? pos : max; - }; - var strings = { - string2buf, - buf2string, - utf8border - }; - function ZStream() { - this.input = null; - this.next_in = 0; - this.avail_in = 0; - this.total_in = 0; - this.output = null; - this.next_out = 0; - this.avail_out = 0; - this.total_out = 0; - this.msg = ""; - this.state = null; - this.data_type = 2; - this.adler = 0; - } - var zstream = ZStream; - var BAD$1 = 30; - var TYPE$1 = 12; - var inffast = function inflate_fast(strm, start) { - let _in; - let last; - let _out; - let beg; - let end; - let dmax; - let wsize; - let whave; - let wnext; - let s_window; - let hold; - let bits; - let lcode; - let dcode; - let lmask; - let dmask; - let here; - let op; - let len; - let dist; - let from; - let from_source; - let input, output; - const state = strm.state; - _in = strm.next_in; - input = strm.input; - last = _in + (strm.avail_in - 5); - _out = strm.next_out; - output = strm.output; - beg = _out - (start - strm.avail_out); - end = _out + (strm.avail_out - 257); - dmax = state.dmax; - wsize = state.wsize; - whave = state.whave; - wnext = state.wnext; - s_window = state.window; - hold = state.hold; - bits = state.bits; - lcode = state.lencode; - dcode = state.distcode; - lmask = (1 << state.lenbits) - 1; - dmask = (1 << state.distbits) - 1; - top: - do { - if (bits < 15) { - hold += input[_in++] << bits; - bits += 8; - hold += input[_in++] << bits; - bits += 8; - } - here = lcode[hold & lmask]; - dolen: - for (; ; ) { - op = here >>> 24; - hold >>>= op; - bits -= op; - op = here >>> 16 & 255; - if (op === 0) { - output[_out++] = here & 65535; - } else if (op & 16) { - len = here & 65535; - op &= 15; - if (op) { - if (bits < op) { - hold += input[_in++] << bits; - bits += 8; - } - len += hold & (1 << op) - 1; - hold >>>= op; - bits -= op; - } - if (bits < 15) { - hold += input[_in++] << bits; - bits += 8; - hold += input[_in++] << bits; - bits += 8; - } - here = dcode[hold & dmask]; - dodist: - for (; ; ) { - op = here >>> 24; - hold >>>= op; - bits -= op; - op = here >>> 16 & 255; - if (op & 16) { - dist = here & 65535; - op &= 15; - if (bits < op) { - hold += input[_in++] << bits; - bits += 8; - if (bits < op) { - hold += input[_in++] << bits; - bits += 8; - } - } - dist += hold & (1 << op) - 1; - if (dist > dmax) { - strm.msg = "invalid distance too far back"; - state.mode = BAD$1; - break top; - } - hold >>>= op; - bits -= op; - op = _out - beg; - if (dist > op) { - op = dist - op; - if (op > whave) { - if (state.sane) { - strm.msg = "invalid distance too far back"; - state.mode = BAD$1; - break top; - } - } - from = 0; - from_source = s_window; - if (wnext === 0) { - from += wsize - op; - if (op < len) { - len -= op; - do { - output[_out++] = s_window[from++]; - } while (--op); - from = _out - dist; - from_source = output; - } - } else if (wnext < op) { - from += wsize + wnext - op; - op -= wnext; - if (op < len) { - len -= op; - do { - output[_out++] = s_window[from++]; - } while (--op); - from = 0; - if (wnext < len) { - op = wnext; - len -= op; - do { - output[_out++] = s_window[from++]; - } while (--op); - from = _out - dist; - from_source = output; - } - } - } else { - from += wnext - op; - if (op < len) { - len -= op; - do { - output[_out++] = s_window[from++]; - } while (--op); - from = _out - dist; - from_source = output; - } - } - while (len > 2) { - output[_out++] = from_source[from++]; - output[_out++] = from_source[from++]; - output[_out++] = from_source[from++]; - len -= 3; - } - if (len) { - output[_out++] = from_source[from++]; - if (len > 1) { - output[_out++] = from_source[from++]; - } - } - } else { - from = _out - dist; - do { - output[_out++] = output[from++]; - output[_out++] = output[from++]; - output[_out++] = output[from++]; - len -= 3; - } while (len > 2); - if (len) { - output[_out++] = output[from++]; - if (len > 1) { - output[_out++] = output[from++]; - } - } - } - } else if ((op & 64) === 0) { - here = dcode[(here & 65535) + (hold & (1 << op) - 1)]; - continue dodist; - } else { - strm.msg = "invalid distance code"; - state.mode = BAD$1; - break top; - } - break; - } - } else if ((op & 64) === 0) { - here = lcode[(here & 65535) + (hold & (1 << op) - 1)]; - continue dolen; - } else if (op & 32) { - state.mode = TYPE$1; - break top; - } else { - strm.msg = "invalid literal/length code"; - state.mode = BAD$1; - break top; - } - break; - } - } while (_in < last && _out < end); - len = bits >> 3; - _in -= len; - bits -= len << 3; - hold &= (1 << bits) - 1; - strm.next_in = _in; - strm.next_out = _out; - strm.avail_in = _in < last ? 5 + (last - _in) : 5 - (_in - last); - strm.avail_out = _out < end ? 257 + (end - _out) : 257 - (_out - end); - state.hold = hold; - state.bits = bits; - return; - }; - var MAXBITS = 15; - var ENOUGH_LENS$1 = 852; - var ENOUGH_DISTS$1 = 592; - var CODES$1 = 0; - var LENS$1 = 1; - var DISTS$1 = 2; - var lbase = new Uint16Array([ - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 11, - 13, - 15, - 17, - 19, - 23, - 27, - 31, - 35, - 43, - 51, - 59, - 67, - 83, - 99, - 115, - 131, - 163, - 195, - 227, - 258, - 0, - 0 - ]); - var lext = new Uint8Array([ - 16, - 16, - 16, - 16, - 16, - 16, - 16, - 16, - 17, - 17, - 17, - 17, - 18, - 18, - 18, - 18, - 19, - 19, - 19, - 19, - 20, - 20, - 20, - 20, - 21, - 21, - 21, - 21, - 16, - 72, - 78 - ]); - var dbase = new Uint16Array([ - 1, - 2, - 3, - 4, - 5, - 7, - 9, - 13, - 17, - 25, - 33, - 49, - 65, - 97, - 129, - 193, - 257, - 385, - 513, - 769, - 1025, - 1537, - 2049, - 3073, - 4097, - 6145, - 8193, - 12289, - 16385, - 24577, - 0, - 0 - ]); - var dext = new Uint8Array([ - 16, - 16, - 16, - 16, - 17, - 17, - 18, - 18, - 19, - 19, - 20, - 20, - 21, - 21, - 22, - 22, - 23, - 23, - 24, - 24, - 25, - 25, - 26, - 26, - 27, - 27, - 28, - 28, - 29, - 29, - 64, - 64 - ]); - var inflate_table = (type, lens, lens_index, codes, table, table_index, work, opts) => { - const bits = opts.bits; - let len = 0; - let sym = 0; - let min = 0, max = 0; - let root = 0; - let curr = 0; - let drop = 0; - let left = 0; - let used = 0; - let huff = 0; - let incr; - let fill; - let low; - let mask; - let next; - let base = null; - let base_index = 0; - let end; - const count = new Uint16Array(MAXBITS + 1); - const offs = new Uint16Array(MAXBITS + 1); - let extra = null; - let extra_index = 0; - let here_bits, here_op, here_val; - for (len = 0; len <= MAXBITS; len++) { - count[len] = 0; - } - for (sym = 0; sym < codes; sym++) { - count[lens[lens_index + sym]]++; - } - root = bits; - for (max = MAXBITS; max >= 1; max--) { - if (count[max] !== 0) { - break; - } - } - if (root > max) { - root = max; - } - if (max === 0) { - table[table_index++] = 1 << 24 | 64 << 16 | 0; - table[table_index++] = 1 << 24 | 64 << 16 | 0; - opts.bits = 1; - return 0; - } - for (min = 1; min < max; min++) { - if (count[min] !== 0) { - break; - } - } - if (root < min) { - root = min; - } - left = 1; - for (len = 1; len <= MAXBITS; len++) { - left <<= 1; - left -= count[len]; - if (left < 0) { - return -1; - } - } - if (left > 0 && (type === CODES$1 || max !== 1)) { - return -1; - } - offs[1] = 0; - for (len = 1; len < MAXBITS; len++) { - offs[len + 1] = offs[len] + count[len]; - } - for (sym = 0; sym < codes; sym++) { - if (lens[lens_index + sym] !== 0) { - work[offs[lens[lens_index + sym]]++] = sym; - } - } - if (type === CODES$1) { - base = extra = work; - end = 19; - } else if (type === LENS$1) { - base = lbase; - base_index -= 257; - extra = lext; - extra_index -= 257; - end = 256; - } else { - base = dbase; - extra = dext; - end = -1; - } - huff = 0; - sym = 0; - len = min; - next = table_index; - curr = root; - drop = 0; - low = -1; - used = 1 << root; - mask = used - 1; - if (type === LENS$1 && used > ENOUGH_LENS$1 || type === DISTS$1 && used > ENOUGH_DISTS$1) { - return 1; - } - for (; ; ) { - here_bits = len - drop; - if (work[sym] < end) { - here_op = 0; - here_val = work[sym]; - } else if (work[sym] > end) { - here_op = extra[extra_index + work[sym]]; - here_val = base[base_index + work[sym]]; - } else { - here_op = 32 + 64; - here_val = 0; - } - incr = 1 << len - drop; - fill = 1 << curr; - min = fill; - do { - fill -= incr; - table[next + (huff >> drop) + fill] = here_bits << 24 | here_op << 16 | here_val | 0; - } while (fill !== 0); - incr = 1 << len - 1; - while (huff & incr) { - incr >>= 1; - } - if (incr !== 0) { - huff &= incr - 1; - huff += incr; - } else { - huff = 0; - } - sym++; - if (--count[len] === 0) { - if (len === max) { - break; - } - len = lens[lens_index + work[sym]]; - } - if (len > root && (huff & mask) !== low) { - if (drop === 0) { - drop = root; - } - next += min; - curr = len - drop; - left = 1 << curr; - while (curr + drop < max) { - left -= count[curr + drop]; - if (left <= 0) { - break; - } - curr++; - left <<= 1; - } - used += 1 << curr; - if (type === LENS$1 && used > ENOUGH_LENS$1 || type === DISTS$1 && used > ENOUGH_DISTS$1) { - return 1; - } - low = huff & mask; - table[low] = root << 24 | curr << 16 | next - table_index | 0; - } - } - if (huff !== 0) { - table[next + huff] = len - drop << 24 | 64 << 16 | 0; - } - opts.bits = root; - return 0; - }; - var inftrees = inflate_table; - var CODES = 0; - var LENS = 1; - var DISTS = 2; - var { - Z_FINISH: Z_FINISH$1, - Z_BLOCK, - Z_TREES, - Z_OK: Z_OK$1, - Z_STREAM_END: Z_STREAM_END$1, - Z_NEED_DICT: Z_NEED_DICT$1, - Z_STREAM_ERROR: Z_STREAM_ERROR$1, - Z_DATA_ERROR: Z_DATA_ERROR$1, - Z_MEM_ERROR: Z_MEM_ERROR$1, - Z_BUF_ERROR, - Z_DEFLATED - } = constants$2; - var HEAD = 1; - var FLAGS = 2; - var TIME = 3; - var OS = 4; - var EXLEN = 5; - var EXTRA = 6; - var NAME = 7; - var COMMENT = 8; - var HCRC = 9; - var DICTID = 10; - var DICT = 11; - var TYPE = 12; - var TYPEDO = 13; - var STORED = 14; - var COPY_ = 15; - var COPY = 16; - var TABLE = 17; - var LENLENS = 18; - var CODELENS = 19; - var LEN_ = 20; - var LEN = 21; - var LENEXT = 22; - var DIST = 23; - var DISTEXT = 24; - var MATCH = 25; - var LIT = 26; - var CHECK = 27; - var LENGTH = 28; - var DONE = 29; - var BAD = 30; - var MEM = 31; - var SYNC = 32; - var ENOUGH_LENS = 852; - var ENOUGH_DISTS = 592; - var MAX_WBITS = 15; - var DEF_WBITS = MAX_WBITS; - var zswap32 = (q) => { - return (q >>> 24 & 255) + (q >>> 8 & 65280) + ((q & 65280) << 8) + ((q & 255) << 24); - }; - function InflateState() { - this.mode = 0; - this.last = false; - this.wrap = 0; - this.havedict = false; - this.flags = 0; - this.dmax = 0; - this.check = 0; - this.total = 0; - this.head = null; - this.wbits = 0; - this.wsize = 0; - this.whave = 0; - this.wnext = 0; - this.window = null; - this.hold = 0; - this.bits = 0; - this.length = 0; - this.offset = 0; - this.extra = 0; - this.lencode = null; - this.distcode = null; - this.lenbits = 0; - this.distbits = 0; - this.ncode = 0; - this.nlen = 0; - this.ndist = 0; - this.have = 0; - this.next = null; - this.lens = new Uint16Array(320); - this.work = new Uint16Array(288); - this.lendyn = null; - this.distdyn = null; - this.sane = 0; - this.back = 0; - this.was = 0; - } - var inflateResetKeep = (strm) => { - if (!strm || !strm.state) { - return Z_STREAM_ERROR$1; - } - const state = strm.state; - strm.total_in = strm.total_out = state.total = 0; - strm.msg = ""; - if (state.wrap) { - strm.adler = state.wrap & 1; - } - state.mode = HEAD; - state.last = 0; - state.havedict = 0; - state.dmax = 32768; - state.head = null; - state.hold = 0; - state.bits = 0; - state.lencode = state.lendyn = new Int32Array(ENOUGH_LENS); - state.distcode = state.distdyn = new Int32Array(ENOUGH_DISTS); - state.sane = 1; - state.back = -1; - return Z_OK$1; - }; - var inflateReset = (strm) => { - if (!strm || !strm.state) { - return Z_STREAM_ERROR$1; - } - const state = strm.state; - state.wsize = 0; - state.whave = 0; - state.wnext = 0; - return inflateResetKeep(strm); - }; - var inflateReset2 = (strm, windowBits) => { - let wrap; - if (!strm || !strm.state) { - return Z_STREAM_ERROR$1; - } - const state = strm.state; - if (windowBits < 0) { - wrap = 0; - windowBits = -windowBits; - } else { - wrap = (windowBits >> 4) + 1; - if (windowBits < 48) { - windowBits &= 15; - } - } - if (windowBits && (windowBits < 8 || windowBits > 15)) { - return Z_STREAM_ERROR$1; - } - if (state.window !== null && state.wbits !== windowBits) { - state.window = null; - } - state.wrap = wrap; - state.wbits = windowBits; - return inflateReset(strm); - }; - var inflateInit2 = (strm, windowBits) => { - if (!strm) { - return Z_STREAM_ERROR$1; - } - const state = new InflateState(); - strm.state = state; - state.window = null; - const ret = inflateReset2(strm, windowBits); - if (ret !== Z_OK$1) { - strm.state = null; - } - return ret; - }; - var inflateInit = (strm) => { - return inflateInit2(strm, DEF_WBITS); - }; - var virgin = true; - var lenfix; - var distfix; - var fixedtables = (state) => { - if (virgin) { - lenfix = new Int32Array(512); - distfix = new Int32Array(32); - let sym = 0; - while (sym < 144) { - state.lens[sym++] = 8; - } - while (sym < 256) { - state.lens[sym++] = 9; - } - while (sym < 280) { - state.lens[sym++] = 7; - } - while (sym < 288) { - state.lens[sym++] = 8; - } - inftrees(LENS, state.lens, 0, 288, lenfix, 0, state.work, { bits: 9 }); - sym = 0; - while (sym < 32) { - state.lens[sym++] = 5; - } - inftrees(DISTS, state.lens, 0, 32, distfix, 0, state.work, { bits: 5 }); - virgin = false; - } - state.lencode = lenfix; - state.lenbits = 9; - state.distcode = distfix; - state.distbits = 5; - }; - var updatewindow = (strm, src, end, copy) => { - let dist; - const state = strm.state; - if (state.window === null) { - state.wsize = 1 << state.wbits; - state.wnext = 0; - state.whave = 0; - state.window = new Uint8Array(state.wsize); - } - if (copy >= state.wsize) { - state.window.set(src.subarray(end - state.wsize, end), 0); - state.wnext = 0; - state.whave = state.wsize; - } else { - dist = state.wsize - state.wnext; - if (dist > copy) { - dist = copy; - } - state.window.set(src.subarray(end - copy, end - copy + dist), state.wnext); - copy -= dist; - if (copy) { - state.window.set(src.subarray(end - copy, end), 0); - state.wnext = copy; - state.whave = state.wsize; - } else { - state.wnext += dist; - if (state.wnext === state.wsize) { - state.wnext = 0; - } - if (state.whave < state.wsize) { - state.whave += dist; - } - } - } - return 0; - }; - var inflate$2 = (strm, flush) => { - let state; - let input, output; - let next; - let put; - let have, left; - let hold; - let bits; - let _in, _out; - let copy; - let from; - let from_source; - let here = 0; - let here_bits, here_op, here_val; - let last_bits, last_op, last_val; - let len; - let ret; - const hbuf = new Uint8Array(4); - let opts; - let n; - const order = new Uint8Array([16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15]); - if (!strm || !strm.state || !strm.output || !strm.input && strm.avail_in !== 0) { - return Z_STREAM_ERROR$1; - } - state = strm.state; - if (state.mode === TYPE) { - state.mode = TYPEDO; - } - put = strm.next_out; - output = strm.output; - left = strm.avail_out; - next = strm.next_in; - input = strm.input; - have = strm.avail_in; - hold = state.hold; - bits = state.bits; - _in = have; - _out = left; - ret = Z_OK$1; - inf_leave: - for (; ; ) { - switch (state.mode) { - case HEAD: - if (state.wrap === 0) { - state.mode = TYPEDO; - break; - } - while (bits < 16) { - if (have === 0) { - break inf_leave; - } - have--; - hold += input[next++] << bits; - bits += 8; - } - if (state.wrap & 2 && hold === 35615) { - state.check = 0; - hbuf[0] = hold & 255; - hbuf[1] = hold >>> 8 & 255; - state.check = crc32_1(state.check, hbuf, 2, 0); - hold = 0; - bits = 0; - state.mode = FLAGS; - break; - } - state.flags = 0; - if (state.head) { - state.head.done = false; - } - if (!(state.wrap & 1) || (((hold & 255) << 8) + (hold >> 8)) % 31) { - strm.msg = "incorrect header check"; - state.mode = BAD; - break; - } - if ((hold & 15) !== Z_DEFLATED) { - strm.msg = "unknown compression method"; - state.mode = BAD; - break; - } - hold >>>= 4; - bits -= 4; - len = (hold & 15) + 8; - if (state.wbits === 0) { - state.wbits = len; - } else if (len > state.wbits) { - strm.msg = "invalid window size"; - state.mode = BAD; - break; - } - state.dmax = 1 << state.wbits; - strm.adler = state.check = 1; - state.mode = hold & 512 ? DICTID : TYPE; - hold = 0; - bits = 0; - break; - case FLAGS: - while (bits < 16) { - if (have === 0) { - break inf_leave; - } - have--; - hold += input[next++] << bits; - bits += 8; - } - state.flags = hold; - if ((state.flags & 255) !== Z_DEFLATED) { - strm.msg = "unknown compression method"; - state.mode = BAD; - break; - } - if (state.flags & 57344) { - strm.msg = "unknown header flags set"; - state.mode = BAD; - break; - } - if (state.head) { - state.head.text = hold >> 8 & 1; - } - if (state.flags & 512) { - hbuf[0] = hold & 255; - hbuf[1] = hold >>> 8 & 255; - state.check = crc32_1(state.check, hbuf, 2, 0); - } - hold = 0; - bits = 0; - state.mode = TIME; - case TIME: - while (bits < 32) { - if (have === 0) { - break inf_leave; - } - have--; - hold += input[next++] << bits; - bits += 8; - } - if (state.head) { - state.head.time = hold; - } - if (state.flags & 512) { - hbuf[0] = hold & 255; - hbuf[1] = hold >>> 8 & 255; - hbuf[2] = hold >>> 16 & 255; - hbuf[3] = hold >>> 24 & 255; - state.check = crc32_1(state.check, hbuf, 4, 0); - } - hold = 0; - bits = 0; - state.mode = OS; - case OS: - while (bits < 16) { - if (have === 0) { - break inf_leave; - } - have--; - hold += input[next++] << bits; - bits += 8; - } - if (state.head) { - state.head.xflags = hold & 255; - state.head.os = hold >> 8; - } - if (state.flags & 512) { - hbuf[0] = hold & 255; - hbuf[1] = hold >>> 8 & 255; - state.check = crc32_1(state.check, hbuf, 2, 0); - } - hold = 0; - bits = 0; - state.mode = EXLEN; - case EXLEN: - if (state.flags & 1024) { - while (bits < 16) { - if (have === 0) { - break inf_leave; - } - have--; - hold += input[next++] << bits; - bits += 8; - } - state.length = hold; - if (state.head) { - state.head.extra_len = hold; - } - if (state.flags & 512) { - hbuf[0] = hold & 255; - hbuf[1] = hold >>> 8 & 255; - state.check = crc32_1(state.check, hbuf, 2, 0); - } - hold = 0; - bits = 0; - } else if (state.head) { - state.head.extra = null; - } - state.mode = EXTRA; - case EXTRA: - if (state.flags & 1024) { - copy = state.length; - if (copy > have) { - copy = have; - } - if (copy) { - if (state.head) { - len = state.head.extra_len - state.length; - if (!state.head.extra) { - state.head.extra = new Uint8Array(state.head.extra_len); - } - state.head.extra.set(input.subarray(next, next + copy), len); - } - if (state.flags & 512) { - state.check = crc32_1(state.check, input, copy, next); - } - have -= copy; - next += copy; - state.length -= copy; - } - if (state.length) { - break inf_leave; - } - } - state.length = 0; - state.mode = NAME; - case NAME: - if (state.flags & 2048) { - if (have === 0) { - break inf_leave; - } - copy = 0; - do { - len = input[next + copy++]; - if (state.head && len && state.length < 65536) { - state.head.name += String.fromCharCode(len); - } - } while (len && copy < have); - if (state.flags & 512) { - state.check = crc32_1(state.check, input, copy, next); - } - have -= copy; - next += copy; - if (len) { - break inf_leave; - } - } else if (state.head) { - state.head.name = null; - } - state.length = 0; - state.mode = COMMENT; - case COMMENT: - if (state.flags & 4096) { - if (have === 0) { - break inf_leave; - } - copy = 0; - do { - len = input[next + copy++]; - if (state.head && len && state.length < 65536) { - state.head.comment += String.fromCharCode(len); - } - } while (len && copy < have); - if (state.flags & 512) { - state.check = crc32_1(state.check, input, copy, next); - } - have -= copy; - next += copy; - if (len) { - break inf_leave; - } - } else if (state.head) { - state.head.comment = null; - } - state.mode = HCRC; - case HCRC: - if (state.flags & 512) { - while (bits < 16) { - if (have === 0) { - break inf_leave; - } - have--; - hold += input[next++] << bits; - bits += 8; - } - if (hold !== (state.check & 65535)) { - strm.msg = "header crc mismatch"; - state.mode = BAD; - break; - } - hold = 0; - bits = 0; - } - if (state.head) { - state.head.hcrc = state.flags >> 9 & 1; - state.head.done = true; - } - strm.adler = state.check = 0; - state.mode = TYPE; - break; - case DICTID: - while (bits < 32) { - if (have === 0) { - break inf_leave; - } - have--; - hold += input[next++] << bits; - bits += 8; - } - strm.adler = state.check = zswap32(hold); - hold = 0; - bits = 0; - state.mode = DICT; - case DICT: - if (state.havedict === 0) { - strm.next_out = put; - strm.avail_out = left; - strm.next_in = next; - strm.avail_in = have; - state.hold = hold; - state.bits = bits; - return Z_NEED_DICT$1; - } - strm.adler = state.check = 1; - state.mode = TYPE; - case TYPE: - if (flush === Z_BLOCK || flush === Z_TREES) { - break inf_leave; - } - case TYPEDO: - if (state.last) { - hold >>>= bits & 7; - bits -= bits & 7; - state.mode = CHECK; - break; - } - while (bits < 3) { - if (have === 0) { - break inf_leave; - } - have--; - hold += input[next++] << bits; - bits += 8; - } - state.last = hold & 1; - hold >>>= 1; - bits -= 1; - switch (hold & 3) { - case 0: - state.mode = STORED; - break; - case 1: - fixedtables(state); - state.mode = LEN_; - if (flush === Z_TREES) { - hold >>>= 2; - bits -= 2; - break inf_leave; - } - break; - case 2: - state.mode = TABLE; - break; - case 3: - strm.msg = "invalid block type"; - state.mode = BAD; - } - hold >>>= 2; - bits -= 2; - break; - case STORED: - hold >>>= bits & 7; - bits -= bits & 7; - while (bits < 32) { - if (have === 0) { - break inf_leave; - } - have--; - hold += input[next++] << bits; - bits += 8; - } - if ((hold & 65535) !== (hold >>> 16 ^ 65535)) { - strm.msg = "invalid stored block lengths"; - state.mode = BAD; - break; - } - state.length = hold & 65535; - hold = 0; - bits = 0; - state.mode = COPY_; - if (flush === Z_TREES) { - break inf_leave; - } - case COPY_: - state.mode = COPY; - case COPY: - copy = state.length; - if (copy) { - if (copy > have) { - copy = have; - } - if (copy > left) { - copy = left; - } - if (copy === 0) { - break inf_leave; - } - output.set(input.subarray(next, next + copy), put); - have -= copy; - next += copy; - left -= copy; - put += copy; - state.length -= copy; - break; - } - state.mode = TYPE; - break; - case TABLE: - while (bits < 14) { - if (have === 0) { - break inf_leave; - } - have--; - hold += input[next++] << bits; - bits += 8; - } - state.nlen = (hold & 31) + 257; - hold >>>= 5; - bits -= 5; - state.ndist = (hold & 31) + 1; - hold >>>= 5; - bits -= 5; - state.ncode = (hold & 15) + 4; - hold >>>= 4; - bits -= 4; - if (state.nlen > 286 || state.ndist > 30) { - strm.msg = "too many length or distance symbols"; - state.mode = BAD; - break; - } - state.have = 0; - state.mode = LENLENS; - case LENLENS: - while (state.have < state.ncode) { - while (bits < 3) { - if (have === 0) { - break inf_leave; - } - have--; - hold += input[next++] << bits; - bits += 8; - } - state.lens[order[state.have++]] = hold & 7; - hold >>>= 3; - bits -= 3; - } - while (state.have < 19) { - state.lens[order[state.have++]] = 0; - } - state.lencode = state.lendyn; - state.lenbits = 7; - opts = { bits: state.lenbits }; - ret = inftrees(CODES, state.lens, 0, 19, state.lencode, 0, state.work, opts); - state.lenbits = opts.bits; - if (ret) { - strm.msg = "invalid code lengths set"; - state.mode = BAD; - break; - } - state.have = 0; - state.mode = CODELENS; - case CODELENS: - while (state.have < state.nlen + state.ndist) { - for (; ; ) { - here = state.lencode[hold & (1 << state.lenbits) - 1]; - here_bits = here >>> 24; - here_op = here >>> 16 & 255; - here_val = here & 65535; - if (here_bits <= bits) { - break; - } - if (have === 0) { - break inf_leave; - } - have--; - hold += input[next++] << bits; - bits += 8; - } - if (here_val < 16) { - hold >>>= here_bits; - bits -= here_bits; - state.lens[state.have++] = here_val; - } else { - if (here_val === 16) { - n = here_bits + 2; - while (bits < n) { - if (have === 0) { - break inf_leave; - } - have--; - hold += input[next++] << bits; - bits += 8; - } - hold >>>= here_bits; - bits -= here_bits; - if (state.have === 0) { - strm.msg = "invalid bit length repeat"; - state.mode = BAD; - break; - } - len = state.lens[state.have - 1]; - copy = 3 + (hold & 3); - hold >>>= 2; - bits -= 2; - } else if (here_val === 17) { - n = here_bits + 3; - while (bits < n) { - if (have === 0) { - break inf_leave; - } - have--; - hold += input[next++] << bits; - bits += 8; - } - hold >>>= here_bits; - bits -= here_bits; - len = 0; - copy = 3 + (hold & 7); - hold >>>= 3; - bits -= 3; - } else { - n = here_bits + 7; - while (bits < n) { - if (have === 0) { - break inf_leave; - } - have--; - hold += input[next++] << bits; - bits += 8; - } - hold >>>= here_bits; - bits -= here_bits; - len = 0; - copy = 11 + (hold & 127); - hold >>>= 7; - bits -= 7; - } - if (state.have + copy > state.nlen + state.ndist) { - strm.msg = "invalid bit length repeat"; - state.mode = BAD; - break; - } - while (copy--) { - state.lens[state.have++] = len; - } - } - } - if (state.mode === BAD) { - break; - } - if (state.lens[256] === 0) { - strm.msg = "invalid code -- missing end-of-block"; - state.mode = BAD; - break; - } - state.lenbits = 9; - opts = { bits: state.lenbits }; - ret = inftrees(LENS, state.lens, 0, state.nlen, state.lencode, 0, state.work, opts); - state.lenbits = opts.bits; - if (ret) { - strm.msg = "invalid literal/lengths set"; - state.mode = BAD; - break; - } - state.distbits = 6; - state.distcode = state.distdyn; - opts = { bits: state.distbits }; - ret = inftrees(DISTS, state.lens, state.nlen, state.ndist, state.distcode, 0, state.work, opts); - state.distbits = opts.bits; - if (ret) { - strm.msg = "invalid distances set"; - state.mode = BAD; - break; - } - state.mode = LEN_; - if (flush === Z_TREES) { - break inf_leave; - } - case LEN_: - state.mode = LEN; - case LEN: - if (have >= 6 && left >= 258) { - strm.next_out = put; - strm.avail_out = left; - strm.next_in = next; - strm.avail_in = have; - state.hold = hold; - state.bits = bits; - inffast(strm, _out); - put = strm.next_out; - output = strm.output; - left = strm.avail_out; - next = strm.next_in; - input = strm.input; - have = strm.avail_in; - hold = state.hold; - bits = state.bits; - if (state.mode === TYPE) { - state.back = -1; - } - break; - } - state.back = 0; - for (; ; ) { - here = state.lencode[hold & (1 << state.lenbits) - 1]; - here_bits = here >>> 24; - here_op = here >>> 16 & 255; - here_val = here & 65535; - if (here_bits <= bits) { - break; - } - if (have === 0) { - break inf_leave; - } - have--; - hold += input[next++] << bits; - bits += 8; - } - if (here_op && (here_op & 240) === 0) { - last_bits = here_bits; - last_op = here_op; - last_val = here_val; - for (; ; ) { - here = state.lencode[last_val + ((hold & (1 << last_bits + last_op) - 1) >> last_bits)]; - here_bits = here >>> 24; - here_op = here >>> 16 & 255; - here_val = here & 65535; - if (last_bits + here_bits <= bits) { - break; - } - if (have === 0) { - break inf_leave; - } - have--; - hold += input[next++] << bits; - bits += 8; - } - hold >>>= last_bits; - bits -= last_bits; - state.back += last_bits; - } - hold >>>= here_bits; - bits -= here_bits; - state.back += here_bits; - state.length = here_val; - if (here_op === 0) { - state.mode = LIT; - break; - } - if (here_op & 32) { - state.back = -1; - state.mode = TYPE; - break; - } - if (here_op & 64) { - strm.msg = "invalid literal/length code"; - state.mode = BAD; - break; - } - state.extra = here_op & 15; - state.mode = LENEXT; - case LENEXT: - if (state.extra) { - n = state.extra; - while (bits < n) { - if (have === 0) { - break inf_leave; - } - have--; - hold += input[next++] << bits; - bits += 8; - } - state.length += hold & (1 << state.extra) - 1; - hold >>>= state.extra; - bits -= state.extra; - state.back += state.extra; - } - state.was = state.length; - state.mode = DIST; - case DIST: - for (; ; ) { - here = state.distcode[hold & (1 << state.distbits) - 1]; - here_bits = here >>> 24; - here_op = here >>> 16 & 255; - here_val = here & 65535; - if (here_bits <= bits) { - break; - } - if (have === 0) { - break inf_leave; - } - have--; - hold += input[next++] << bits; - bits += 8; - } - if ((here_op & 240) === 0) { - last_bits = here_bits; - last_op = here_op; - last_val = here_val; - for (; ; ) { - here = state.distcode[last_val + ((hold & (1 << last_bits + last_op) - 1) >> last_bits)]; - here_bits = here >>> 24; - here_op = here >>> 16 & 255; - here_val = here & 65535; - if (last_bits + here_bits <= bits) { - break; - } - if (have === 0) { - break inf_leave; - } - have--; - hold += input[next++] << bits; - bits += 8; - } - hold >>>= last_bits; - bits -= last_bits; - state.back += last_bits; - } - hold >>>= here_bits; - bits -= here_bits; - state.back += here_bits; - if (here_op & 64) { - strm.msg = "invalid distance code"; - state.mode = BAD; - break; - } - state.offset = here_val; - state.extra = here_op & 15; - state.mode = DISTEXT; - case DISTEXT: - if (state.extra) { - n = state.extra; - while (bits < n) { - if (have === 0) { - break inf_leave; - } - have--; - hold += input[next++] << bits; - bits += 8; - } - state.offset += hold & (1 << state.extra) - 1; - hold >>>= state.extra; - bits -= state.extra; - state.back += state.extra; - } - if (state.offset > state.dmax) { - strm.msg = "invalid distance too far back"; - state.mode = BAD; - break; - } - state.mode = MATCH; - case MATCH: - if (left === 0) { - break inf_leave; - } - copy = _out - left; - if (state.offset > copy) { - copy = state.offset - copy; - if (copy > state.whave) { - if (state.sane) { - strm.msg = "invalid distance too far back"; - state.mode = BAD; - break; - } - } - if (copy > state.wnext) { - copy -= state.wnext; - from = state.wsize - copy; - } else { - from = state.wnext - copy; - } - if (copy > state.length) { - copy = state.length; - } - from_source = state.window; - } else { - from_source = output; - from = put - state.offset; - copy = state.length; - } - if (copy > left) { - copy = left; - } - left -= copy; - state.length -= copy; - do { - output[put++] = from_source[from++]; - } while (--copy); - if (state.length === 0) { - state.mode = LEN; - } - break; - case LIT: - if (left === 0) { - break inf_leave; - } - output[put++] = state.length; - left--; - state.mode = LEN; - break; - case CHECK: - if (state.wrap) { - while (bits < 32) { - if (have === 0) { - break inf_leave; - } - have--; - hold |= input[next++] << bits; - bits += 8; - } - _out -= left; - strm.total_out += _out; - state.total += _out; - if (_out) { - strm.adler = state.check = state.flags ? crc32_1(state.check, output, _out, put - _out) : adler32_1(state.check, output, _out, put - _out); - } - _out = left; - if ((state.flags ? hold : zswap32(hold)) !== state.check) { - strm.msg = "incorrect data check"; - state.mode = BAD; - break; - } - hold = 0; - bits = 0; - } - state.mode = LENGTH; - case LENGTH: - if (state.wrap && state.flags) { - while (bits < 32) { - if (have === 0) { - break inf_leave; - } - have--; - hold += input[next++] << bits; - bits += 8; - } - if (hold !== (state.total & 4294967295)) { - strm.msg = "incorrect length check"; - state.mode = BAD; - break; - } - hold = 0; - bits = 0; - } - state.mode = DONE; - case DONE: - ret = Z_STREAM_END$1; - break inf_leave; - case BAD: - ret = Z_DATA_ERROR$1; - break inf_leave; - case MEM: - return Z_MEM_ERROR$1; - case SYNC: - default: - return Z_STREAM_ERROR$1; - } - } - strm.next_out = put; - strm.avail_out = left; - strm.next_in = next; - strm.avail_in = have; - state.hold = hold; - state.bits = bits; - if (state.wsize || _out !== strm.avail_out && state.mode < BAD && (state.mode < CHECK || flush !== Z_FINISH$1)) { - if (updatewindow(strm, strm.output, strm.next_out, _out - strm.avail_out)) - ; - } - _in -= strm.avail_in; - _out -= strm.avail_out; - strm.total_in += _in; - strm.total_out += _out; - state.total += _out; - if (state.wrap && _out) { - strm.adler = state.check = state.flags ? crc32_1(state.check, output, _out, strm.next_out - _out) : adler32_1(state.check, output, _out, strm.next_out - _out); - } - strm.data_type = state.bits + (state.last ? 64 : 0) + (state.mode === TYPE ? 128 : 0) + (state.mode === LEN_ || state.mode === COPY_ ? 256 : 0); - if ((_in === 0 && _out === 0 || flush === Z_FINISH$1) && ret === Z_OK$1) { - ret = Z_BUF_ERROR; - } - return ret; - }; - var inflateEnd = (strm) => { - if (!strm || !strm.state) { - return Z_STREAM_ERROR$1; - } - let state = strm.state; - if (state.window) { - state.window = null; - } - strm.state = null; - return Z_OK$1; - }; - var inflateGetHeader = (strm, head) => { - if (!strm || !strm.state) { - return Z_STREAM_ERROR$1; - } - const state = strm.state; - if ((state.wrap & 2) === 0) { - return Z_STREAM_ERROR$1; - } - state.head = head; - head.done = false; - return Z_OK$1; - }; - var inflateSetDictionary = (strm, dictionary) => { - const dictLength = dictionary.length; - let state; - let dictid; - let ret; - if (!strm || !strm.state) { - return Z_STREAM_ERROR$1; - } - state = strm.state; - if (state.wrap !== 0 && state.mode !== DICT) { - return Z_STREAM_ERROR$1; - } - if (state.mode === DICT) { - dictid = 1; - dictid = adler32_1(dictid, dictionary, dictLength, 0); - if (dictid !== state.check) { - return Z_DATA_ERROR$1; - } - } - ret = updatewindow(strm, dictionary, dictLength, dictLength); - if (ret) { - state.mode = MEM; - return Z_MEM_ERROR$1; - } - state.havedict = 1; - return Z_OK$1; - }; - var inflateReset_1 = inflateReset; - var inflateReset2_1 = inflateReset2; - var inflateResetKeep_1 = inflateResetKeep; - var inflateInit_1 = inflateInit; - var inflateInit2_1 = inflateInit2; - var inflate_2$1 = inflate$2; - var inflateEnd_1 = inflateEnd; - var inflateGetHeader_1 = inflateGetHeader; - var inflateSetDictionary_1 = inflateSetDictionary; - var inflateInfo = "pako inflate (from Nodeca project)"; - var inflate_1$2 = { - inflateReset: inflateReset_1, - inflateReset2: inflateReset2_1, - inflateResetKeep: inflateResetKeep_1, - inflateInit: inflateInit_1, - inflateInit2: inflateInit2_1, - inflate: inflate_2$1, - inflateEnd: inflateEnd_1, - inflateGetHeader: inflateGetHeader_1, - inflateSetDictionary: inflateSetDictionary_1, - inflateInfo - }; - function GZheader() { - this.text = 0; - this.time = 0; - this.xflags = 0; - this.os = 0; - this.extra = null; - this.extra_len = 0; - this.name = ""; - this.comment = ""; - this.hcrc = 0; - this.done = false; - } - var gzheader = GZheader; - var toString = Object.prototype.toString; - var { - Z_NO_FLUSH, - Z_FINISH, - Z_OK, - Z_STREAM_END, - Z_NEED_DICT, - Z_STREAM_ERROR, - Z_DATA_ERROR, - Z_MEM_ERROR - } = constants$2; - function Inflate$1(options) { - this.options = common.assign({ - chunkSize: 1024 * 64, - windowBits: 15, - to: "" - }, options || {}); - const opt = this.options; - if (opt.raw && opt.windowBits >= 0 && opt.windowBits < 16) { - opt.windowBits = -opt.windowBits; - if (opt.windowBits === 0) { - opt.windowBits = -15; - } - } - if (opt.windowBits >= 0 && opt.windowBits < 16 && !(options && options.windowBits)) { - opt.windowBits += 32; - } - if (opt.windowBits > 15 && opt.windowBits < 48) { - if ((opt.windowBits & 15) === 0) { - opt.windowBits |= 15; - } - } - this.err = 0; - this.msg = ""; - this.ended = false; - this.chunks = []; - this.strm = new zstream(); - this.strm.avail_out = 0; - let status = inflate_1$2.inflateInit2(this.strm, opt.windowBits); - if (status !== Z_OK) { - throw new Error(messages[status]); - } - this.header = new gzheader(); - inflate_1$2.inflateGetHeader(this.strm, this.header); - if (opt.dictionary) { - if (typeof opt.dictionary === "string") { - opt.dictionary = strings.string2buf(opt.dictionary); - } else if (toString.call(opt.dictionary) === "[object ArrayBuffer]") { - opt.dictionary = new Uint8Array(opt.dictionary); - } - if (opt.raw) { - status = inflate_1$2.inflateSetDictionary(this.strm, opt.dictionary); - if (status !== Z_OK) { - throw new Error(messages[status]); - } - } - } - } - Inflate$1.prototype.push = function(data, flush_mode) { - const strm = this.strm; - const chunkSize = this.options.chunkSize; - const dictionary = this.options.dictionary; - let status, _flush_mode, last_avail_out; - if (this.ended) - return false; - if (flush_mode === ~~flush_mode) - _flush_mode = flush_mode; - else - _flush_mode = flush_mode === true ? Z_FINISH : Z_NO_FLUSH; - if (toString.call(data) === "[object ArrayBuffer]") { - strm.input = new Uint8Array(data); - } else { - strm.input = data; - } - strm.next_in = 0; - strm.avail_in = strm.input.length; - for (; ; ) { - if (strm.avail_out === 0) { - strm.output = new Uint8Array(chunkSize); - strm.next_out = 0; - strm.avail_out = chunkSize; - } - status = inflate_1$2.inflate(strm, _flush_mode); - if (status === Z_NEED_DICT && dictionary) { - status = inflate_1$2.inflateSetDictionary(strm, dictionary); - if (status === Z_OK) { - status = inflate_1$2.inflate(strm, _flush_mode); - } else if (status === Z_DATA_ERROR) { - status = Z_NEED_DICT; - } - } - while (strm.avail_in > 0 && status === Z_STREAM_END && strm.state.wrap > 0 && data[strm.next_in] !== 0) { - inflate_1$2.inflateReset(strm); - status = inflate_1$2.inflate(strm, _flush_mode); - } - switch (status) { - case Z_STREAM_ERROR: - case Z_DATA_ERROR: - case Z_NEED_DICT: - case Z_MEM_ERROR: - this.onEnd(status); - this.ended = true; - return false; - } - last_avail_out = strm.avail_out; - if (strm.next_out) { - if (strm.avail_out === 0 || status === Z_STREAM_END) { - if (this.options.to === "string") { - let next_out_utf8 = strings.utf8border(strm.output, strm.next_out); - let tail = strm.next_out - next_out_utf8; - let utf8str = strings.buf2string(strm.output, next_out_utf8); - strm.next_out = tail; - strm.avail_out = chunkSize - tail; - if (tail) - strm.output.set(strm.output.subarray(next_out_utf8, next_out_utf8 + tail), 0); - this.onData(utf8str); - } else { - this.onData(strm.output.length === strm.next_out ? strm.output : strm.output.subarray(0, strm.next_out)); - } - } - } - if (status === Z_OK && last_avail_out === 0) - continue; - if (status === Z_STREAM_END) { - status = inflate_1$2.inflateEnd(this.strm); - this.onEnd(status); - this.ended = true; - return true; - } - if (strm.avail_in === 0) - break; - } - return true; - }; - Inflate$1.prototype.onData = function(chunk) { - this.chunks.push(chunk); - }; - Inflate$1.prototype.onEnd = function(status) { - if (status === Z_OK) { - if (this.options.to === "string") { - this.result = this.chunks.join(""); - } else { - this.result = common.flattenChunks(this.chunks); - } - } - this.chunks = []; - this.err = status; - this.msg = this.strm.msg; - }; - function inflate$1(input, options) { - const inflator = new Inflate$1(options); - inflator.push(input); - if (inflator.err) - throw inflator.msg || messages[inflator.err]; - return inflator.result; - } - function inflateRaw$1(input, options) { - options = options || {}; - options.raw = true; - return inflate$1(input, options); - } - var Inflate_1$1 = Inflate$1; - var inflate_2 = inflate$1; - var inflateRaw_1$1 = inflateRaw$1; - var ungzip$1 = inflate$1; - var constants = constants$2; - var inflate_1$1 = { - Inflate: Inflate_1$1, - inflate: inflate_2, - inflateRaw: inflateRaw_1$1, - ungzip: ungzip$1, - constants - }; - var { Inflate, inflate, inflateRaw, ungzip } = inflate_1$1; - var inflate_1 = inflate; - var ungzip_1 = ungzip; - - // esm/filters.js - var zlib_decompress = function(buf, itemsize) { - let input_array = new Uint8Array(buf); - return inflate_1(input_array).buffer; - }; - var unshuffle = function(buf, itemsize) { - let buffer_size = buf.byteLength; - let unshuffled_view = new Uint8Array(buffer_size); - let step = Math.floor(buffer_size / itemsize); - let shuffled_view = new DataView(buf); - for (var j = 0; j < itemsize; j++) { - for (var i = 0; i < step; i++) { - unshuffled_view[j + i * itemsize] = shuffled_view.getUint8(j * step + i); - } - } - return unshuffled_view.buffer; - }; - var fletch32 = function(buf, itemsize) { - _verify_fletcher32(buf); - return buf.slice(0, -4); - }; - function _verify_fletcher32(chunk_buffer) { - var odd_chunk_buffer = chunk_buffer.byteLength % 2 != 0; - var data_length = chunk_buffer.byteLength - 4; - var view = new DataView(chunk_buffer); - var sum1 = 0; - var sum2 = 0; - for (var offset = 0; offset < data_length - 1; offset += 2) { - let datum = view.getUint16(offset, true); - sum1 = (sum1 + datum) % 65535; - sum2 = (sum2 + sum1) % 65535; - } - if (odd_chunk_buffer) { - let datum = view.getUint8(data_length - 1); - sum1 = (sum1 + datum) % 65535; - sum2 = (sum2 + sum1) % 65535; - } - var [ref_sum1, ref_sum2] = struct.unpack_from(">HH", chunk_buffer, data_length); - ref_sum1 = ref_sum1 % 65535; - ref_sum2 = ref_sum2 % 65535; - if (sum1 != ref_sum1 || sum2 != ref_sum2) { - throw 'ValueError("fletcher32 checksum invalid")'; - } - return true; - } - var GZIP_DEFLATE_FILTER = 1; - var SHUFFLE_FILTER = 2; - var FLETCH32_FILTER = 3; - var Filters = /* @__PURE__ */ new Map([ - [GZIP_DEFLATE_FILTER, zlib_decompress], - [SHUFFLE_FILTER, unshuffle], - [FLETCH32_FILTER, fletch32] - ]); - - // esm/btree.js - var AbstractBTree = class { - constructor(fh, offset) { - this.fh = fh; - this.offset = offset; - this.depth = null; - } - async init() { - this.all_nodes = /* @__PURE__ */ new Map(); - await this._read_root_node(); - await this._read_children(); - } - async _read_children() { - let node_level = this.depth; - while (node_level > 0) { - for (var parent_node of this.all_nodes.get(node_level)) { - for (var child_addr of parent_node.get("addresses")) { - this._add_node(await this._read_node(child_addr, node_level - 1)); - } - } - node_level--; - } - } - async _read_root_node() { - let root_node = await this._read_node(this.offset, null); - this._add_node(root_node); - this.depth = root_node.get("node_level"); - } - _add_node(node) { - let node_level = node.get("node_level"); - if (this.all_nodes.has(node_level)) { - this.all_nodes.get(node_level).push(node); - } else { - this.all_nodes.set(node_level, [node]); - } - } - async _read_node(offset, node_level) { - let node = await this._read_node_header(offset, node_level); - node.set("keys", []); - node.set("addresses", []); - return node; - } - async _read_node_header(offset) { - throw "NotImplementedError: must define _read_node_header in implementation class"; - } - }; - var BTreeV1 = class extends AbstractBTree { - constructor() { - super(...arguments); - __publicField(this, "B_LINK_NODE", /* @__PURE__ */ new Map([ - ["signature", "4s"], - ["node_type", "B"], - ["node_level", "B"], - ["entries_used", "H"], - ["left_sibling", "Q"], - ["right_sibling", "Q"] - ])); - } - async _read_node_header(offset, node_level) { - let node = await _unpack_struct_from_async(this.B_LINK_NODE, this.fh, offset); - if (node_level != null) { - if (node.get("node_level") != node_level) { - throw "node level does not match"; - } - } - return node; - } - }; - var BTreeV1Groups = class extends BTreeV1 { - constructor(fh, offset) { - super(fh, offset); - __publicField(this, "NODE_TYPE", 0); - this.ready = this.init(); - } - async _read_node(offset, node_level) { - let node = await this._read_node_header(offset, node_level); - offset += _structure_size(this.B_LINK_NODE); - let keys = []; - let addresses = []; - let entries_used = node.get("entries_used"); - for (var i = 0; i < entries_used; i++) { - let key = (await struct.unpack_from_async("= 0; d--) { - if (cpos[d] >= chunk_shape[d]) { - cpos[d] = 0; - apos[d] = chunk_offset[d]; - if (d > 0) { - cpos[d - 1] += 1; - apos[d - 1] += 1; - } - } else { - break; - } - } - let inbounds = apos.slice(0, -1).every(function(p, d2) { - return p < data_shape[d2]; - }); - if (inbounds) { - let cb_offset = ci * item_size; - let datum = cview[item_getter](cb_offset, !item_big_endian, item_size); - let ai = apos.slice(0, -1).reduce(function(prev, curr, index) { - return curr * data_strides[index] + prev; - }, 0); - data[ai] = datum; - } - cpos[dims - 1] += 1; - apos[dims - 1] += 1; - } - } - } - return data; - } - _filter_chunk(chunk_buffer, filter_mask, filter_pipeline, itemsize) { - let num_filters = filter_pipeline.length; - let buf = chunk_buffer.slice(); - for (var filter_index = num_filters - 1; filter_index >= 0; filter_index--) { - if (filter_mask & 1 << filter_index) { - continue; - } - let pipeline_entry = filter_pipeline[filter_index]; - let filter_id = pipeline_entry.get("filter_id"); - let client_data = pipeline_entry.get("client_data"); - if (Filters.has(filter_id)) { - buf = Filters.get(filter_id)(buf, itemsize, client_data); - } else { - throw 'NotImplementedError("Filter with id:' + filter_id.toFixed() + ' not supported")'; - } - } - return buf; - } - }; - var BTreeV2 = class extends AbstractBTree { - constructor(fh, offset) { - super(fh, offset); - __publicField(this, "B_TREE_HEADER", /* @__PURE__ */ new Map([ - ["signature", "4s"], - ["version", "B"], - ["node_type", "B"], - ["node_size", "I"], - ["record_size", "H"], - ["depth", "H"], - ["split_percent", "B"], - ["merge_percent", "B"], - ["root_address", "Q"], - ["root_nrecords", "H"], - ["total_nrecords", "Q"] - ])); - __publicField(this, "B_LINK_NODE", /* @__PURE__ */ new Map([ - ["signature", "4s"], - ["version", "B"], - ["node_type", "B"] - ])); - this.ready = this.init(); - } - async _read_root_node() { - let h = await this._read_tree_header(this.offset); - this.address_formats = this._calculate_address_formats(h); - this.header = h; - this.depth = h.get("depth"); - let address = [h.get("root_address"), h.get("root_nrecords"), h.get("total_nrecords")]; - let root_node = await this._read_node(address, this.depth); - this._add_node(root_node); - } - async _read_tree_header(offset) { - let header = await _unpack_struct_from_async(this.B_TREE_HEADER, this.fh, this.offset); - return header; - } - _calculate_address_formats(header) { - let node_size = header.get("node_size"); - let record_size = header.get("record_size"); - let nrecords_max = 0; - let ntotalrecords_max = 0; - let address_formats = /* @__PURE__ */ new Map(); - let max_depth = header.get("depth"); - for (var node_level = 0; node_level <= max_depth; node_level++) { - let offset_fmt = ""; - let num1_fmt = ""; - let num2_fmt = ""; - let offset_size, num1_size, num2_size; - if (node_level == 0) { - offset_size = 0; - num1_size = 0; - num2_size = 0; - } else if (node_level == 1) { - offset_size = 8; - offset_fmt = " 0) { - ntotalrecords_max *= nrecords_max; - } else { - ntotalrecords_max = nrecords_max; - } - } - } - return address_formats; - } - _nrecords_max(node_size, record_size, addr_size) { - return Math.floor((node_size - 10 - addr_size) / (record_size + addr_size)); - } - _required_bytes(integer) { - return Math.ceil(bitSize(integer) / 8); - } - _int_format(bytelength) { - return [" 0) { - num2 = (await struct.unpack_from_async(num2_fmt, this.fh, offset))[0]; - offset += num2_size; - } - addresses.push([address_offset, num1, num2]); - } - } - node.set("keys", keys); - node.set("addresses", addresses); - return node; - } - async _read_node_header(offset, node_level) { - let node = await _unpack_struct_from_async(this.B_LINK_NODE, this.fh, offset); - node.set("node_level", node_level); - return node; - } - *iter_records() { - for (let nodelist of this.all_nodes.values()) { - for (let node of nodelist) { - for (let key of node.get("keys")) { - yield key; - } - } - } - } - _parse_record(record) { - throw "NotImplementedError"; - } - }; - var BTreeV2GroupNames = class extends BTreeV2 { - constructor() { - super(...arguments); - __publicField(this, "NODE_TYPE", 5); - } - async _parse_record(buf, offset, size) { - let namehash = (await struct.unpack_from_async(" 0) { - throw "Filter info size not supported on FractalHeap"; - } - if (header.get("btree_address_huge_objects") == UNDEFINED_ADDRESS) { - header.set("btree_address_huge_objects", null); - } else { - throw "Huge objects not implemented in FractalHeap"; - } - if (header.get("root_block_address") == UNDEFINED_ADDRESS) { - header.set("root_block_address", null); - } - let nbits = header.get("log2_maximum_heap_size"); - let block_offset_size = this._min_size_nbits(nbits); - let h = /* @__PURE__ */ new Map([ - ["signature", "4s"], - ["version", "B"], - ["heap_header_adddress", "Q"], - ["block_offset", `${block_offset_size}B`] - ]); - this.indirect_block_header = new Map(h); - this.indirect_block_header_size = _structure_size(h); - if ((header.get("flags") & 2) == 2) { - h.set("checksum", "I"); - } - this.direct_block_header = h; - this.direct_block_header_size = _structure_size(h); - let maximum_dblock_size = header.get("maximum_direct_block_size"); - this._managed_object_offset_size = this._min_size_nbits(nbits); - let value = Math.min(maximum_dblock_size, header.get("max_managed_object_size")); - this._managed_object_length_size = this._min_size_integer(value); - let start_block_size = header.get("starting_block_size"); - let table_width = header.get("table_width"); - if (!(start_block_size > 0)) { - throw "Starting block size == 0 not implemented"; - } - let log2_maximum_dblock_size = Number(Math.floor(Math.log2(maximum_dblock_size))); - assert(1n << BigInt(log2_maximum_dblock_size) == maximum_dblock_size); - let log2_start_block_size = Number(Math.floor(Math.log2(start_block_size))); - assert(1n << BigInt(log2_start_block_size) == start_block_size); - this._max_direct_nrows = log2_maximum_dblock_size - log2_start_block_size + 2; - let log2_table_width = Math.floor(Math.log2(table_width)); - assert(1 << log2_table_width == table_width); - this._indirect_nrows_sub = log2_table_width + log2_start_block_size - 1; - this.header = header; - this.nobjects = header.get("managed_object_count") + header.get("huge_object_count") + header.get("tiny_object_count"); - let managed = []; - let root_address = header.get("root_block_address"); - let nrows = 0; - if (root_address != null) { - nrows = header.get("indirect_current_rows_count"); - } - if (nrows > 0) { - for await (let data of this._iter_indirect_block(this.fh, root_address, nrows)) { - managed.push(data); - } - } else { - let data = await this._read_direct_block(this.fh, root_address, start_block_size); - managed.push(data); - } - let data_size = managed.reduce((p, c) => p + c.byteLength, 0); - let combined = new Uint8Array(data_size); - let moffset = 0; - managed.forEach((m) => { - combined.set(new Uint8Array(m), moffset); - moffset += m.byteLength; - }); - this.managed = combined.buffer; - } - async _read_direct_block(fh, offset, block_size) { - let data = await fh.slice(offset, offset + block_size); - let header = _unpack_struct_from(this.direct_block_header, data); - assert(header.get("signature") == "FHDB"); - return data; - } - get_data(heapid) { - let firstbyte = struct.unpack_from("> 4 & 3; - let version = firstbyte >> 6; - let data_offset = 1; - if (idtype == 0) { - assert(version == 0); - let nbytes = this._managed_object_offset_size; - let offset = _unpack_integer(nbytes, heapid, data_offset); - data_offset += nbytes; - nbytes = this._managed_object_length_size; - let size = _unpack_integer(nbytes, heapid, data_offset); - return this.managed.slice(offset, offset + size); - } else if (idtype == 1) { - throw "tiny objectID not supported in FractalHeap"; - } else if (idtype == 2) { - throw "huge objectID not supported in FractalHeap"; - } else { - throw "unknown objectID type in FractalHeap"; - } - } - _min_size_integer(integer) { - return this._min_size_nbits(bitSize(integer)); - } - _min_size_nbits(nbits) { - return Math.ceil(nbits / 8); - } - async *_iter_indirect_block(fh, offset, nrows) { - let header = await _unpack_struct_from_async(this.indirect_block_header, fh, offset); - offset += this.indirect_block_header_size; - assert(header.get("signature") == "FHIB"); - let block_offset_bytes = header.get("block_offset"); - let block_offset = block_offset_bytes.reduce((p, c, i) => p + (c << i * 8), 0); - header.set("block_offset", block_offset); - let [ndirect, nindirect] = this._indirect_info(nrows); - let direct_blocks = []; - for (let i = 0; i < ndirect; i++) { - let address = (await struct.unpack_from_async(" { - return this._chunks; - }); - } - get shape() { - let msg = this.find_msg_type(DATASPACE_MSG_TYPE)[0]; - let msg_offset = msg.get("offset_to_message"); - return determine_data_shape(this.fh, msg_offset); - } - async get_filter_pipeline() { - if (this._filter_pipeline != null) { - return this._filter_pipeline; - } - let filter_msgs = this.find_msg_type(DATA_STORAGE_FILTER_PIPELINE_MSG_TYPE); - if (!filter_msgs.length) { - this._filter_pipeline = null; - return this._filter_pipeline; - } - var offset = filter_msgs[0].get("offset_to_message"); - let [version, nfilters] = await struct.unpack_from_async(" 255) { - name_length = (await struct.unpack_from_async(" 0; - filter_info.set("optional", optional); - let num_client_values = (await struct.unpack_from_async(" 0) { - name = (await struct.unpack_from_async(`${name_length}s`, buf, offset))[0]; - offset += name_length; - } - filter_info.set("name", name); - let client_values = await struct.unpack_from_async(`<${num_client_values}i`, buf, offset); - offset += 4 * num_client_values; - filter_info.set("client_data_values", client_values); - filters.push(filter_info); - } - } else { - throw `version ${version} is not supported`; - } - this._filter_pipeline = filters; - return this._filter_pipeline; - } - find_msg_type(msg_type) { - return this.msgs.filter(function(m) { - return m.get("type") == msg_type; - }); - } - async get_attributes() { - let attrs = {}; - let attr_msgs = this.find_msg_type(ATTRIBUTE_MSG_TYPE); - for (let msg of attr_msgs) { - let offset = msg.get("offset_to_message"); - let [name, value] = await this.unpack_attribute(offset); - attrs[name] = value; - } - return attrs; - } - async get_fillvalue() { - let msg = this.find_msg_type(FILLVALUE_MSG_TYPE)[0]; - var offset = msg.get("offset_to_message"); - var is_defined; - let version = (await struct.unpack_from_async("= block_size) { - [block_offset, block_size] = object_header_blocks[++current_block]; - local_offset = 0; - } - let msg = await _unpack_struct_from_async(HEADER_MSG_INFO_V1, fh, block_offset + local_offset); - let offset_to_message = block_offset + local_offset + HEADER_MSG_INFO_V1_SIZE; - msg.set("offset_to_message", offset_to_message); - if (msg.get("type") == OBJECT_CONTINUATION_MSG_TYPE) { - var [fh_off, size] = await struct.unpack_from_async("= block_size - HEADER_MSG_INFO_V2_SIZE) { - let next_block = object_header_blocks[++current_block]; - if (next_block == null) { - break; - } - [block_offset, block_size] = next_block; - local_offset = 0; - } - let msg = await _unpack_struct_from_async(HEADER_MSG_INFO_V2, buf, block_offset + local_offset); - let offset_to_message = block_offset + local_offset + HEADER_MSG_INFO_V2_SIZE + creation_order_size; - msg.set("offset_to_message", offset_to_message); - if (msg.get("type") == OBJECT_CONTINUATION_MSG_TYPE) { - var [fh_off, size] = await struct.unpack_from_async(" 0; - let link_name_character_set_field_present = (flags & 2 ** 4) > 0; - let ordered = (flags & 2 ** 2) > 0; - let link_type; - if (link_type_field_present) { - link_type = (await struct.unpack_from_async(" 0) { - offset += 8; - } - let fmt = (flags & 2) > 0 ? LINK_INFO_MSG2 : LINK_INFO_MSG1; - let link_info = await _unpack_struct_from_async(fmt, data, offset); - let output = /* @__PURE__ */ new Map(); - for (let [k, v] of link_info.entries()) { - output.set(k, v == UNDEFINED_ADDRESS2 ? null : v); - } - return output; - } - get is_dataset() { - return this.find_msg_type(DATASPACE_MSG_TYPE).length > 0; - } - async get_data() { - let msg = this.find_msg_type(DATA_STORAGE_MSG_TYPE)[0]; - let msg_offset = msg.get("offset_to_message"); - var [version, dims, layout_class, property_offset] = await this._get_data_message_properties(msg_offset); - if (layout_class == 0) { - throw "Compact storage of DataObject not implemented"; - } else if (layout_class == 1) { - return this._get_contiguous_data(property_offset); - } else if (layout_class == 2) { - return this._get_chunked_data(msg_offset); - } - } - async _get_data_message_properties(msg_offset) { - let dims, layout_class, property_offset; - let [version, arg1, arg2] = await struct.unpack_from_async("= 1 && version <= 4); - return [version, dims, layout_class, property_offset]; - } - async _get_contiguous_data(property_offset) { - let [data_offset] = await struct.unpack_from_async("=!@\|]?(i|u|f|S)(\d*)/.test(dtype)) { - let [item_getter, item_is_big_endian, item_size] = dtype_getter(dtype); - let output = new Array(fullsize); - const local_buffer = await this.fh.slice(data_offset, data_offset + item_size * fullsize); - let view = new DataView64(local_buffer); - for (var i = 0; i < fullsize; i++) { - output[i] = view[item_getter](i * item_size, !item_is_big_endian, item_size); - } - return output; - } else if (dtype.datatype_class === 5) { - return this.fh.slice(data_offset, data_offset + dtype.size); - } else { - throw "not Implemented - no proper dtype defined"; - } - } else { - let dtype_class = dtype[0]; - if (dtype_class == "REFERENCE") { - let size = dtype[1]; - if (size != 8) { - throw "NotImplementedError('Unsupported Reference type')"; - } - let ref_addresses = await this.fh.slice(data_offset, data_offset + fullsize); - return ref_addresses; - } else if (dtype_class == "VLEN_STRING") { - let character_set = dtype[2]; - const encoding = character_set == 0 ? "ascii" : "utf-8"; - const decoder = new TextDecoder(encoding); - var value = []; - for (var i = 0; i < fullsize; i++) { - const [vlen, vlen_data] = await this._vlen_size_and_data(this.fh, data_offset); - value[i] = decoder.decode(vlen_data); - data_offset += 16; - } - return value; - } else { - throw "NotImplementedError('datatype not implemented')"; - } - } - } - async _get_chunked_data(offset) { - await this._get_chunk_params(); - if (this._chunk_address == UNDEFINED_ADDRESS2) { - return []; - } - var chunk_btree = new BTreeV1RawDataChunks(this.fh, this._chunk_address, this._chunk_dims); - await chunk_btree.ready; - const dtype = await this.dtype; - const shape = await this.shape; - const chunks = await this.chunks; - const filter_pipeline = await this.get_filter_pipeline(); - let data = await chunk_btree.construct_data_from_chunks(chunks, shape, dtype, filter_pipeline); - if (dtype instanceof Array && /^VLEN/.test(dtype[0])) { - let dtype_class = dtype[0]; - for (var i = 0; i < data.length; i++) { - let [item_size, gheap_address, object_index] = data[i]; - var gheap; - if (!(gheap_address in this._global_heaps)) { - gheap = new GlobalHeap(this.fh, gheap_address); - await gheap.ready; - this._global_heaps[gheap_address] = gheap; - } else { - gheap = this._global_heaps[gheap_address]; - } - let vlen_data = gheap.objects.get(object_index); - if (dtype_class == "VLEN_STRING") { - let character_set = dtype[2]; - const encoding = character_set == 0 ? "ascii" : "utf-8"; - const decoder = new TextDecoder(encoding); - data[i] = decoder.decode(vlen_data); - } - } - } - return data; - } - async _get_chunk_params() { - if (this._chunk_params_set) { - return; - } - this._chunk_params_set = true; - var msg = this.find_msg_type(DATA_STORAGE_MSG_TYPE)[0]; - var offset = msg.get("offset_to_message"); - var [version, dims, layout_class, property_offset] = await this._get_data_message_properties(offset); - if (layout_class != 2) { - return; - } - var data_offset; - if (version == 1 || version == 2) { - var address = (await struct.unpack_from_async("= 1 && version <= 3); - var fmt = "<" + (dims - 1).toFixed() + "I"; - var chunk_shape = await struct.unpack_from_async(fmt, this.fh, data_offset); - this._chunks = chunk_shape; - this._chunk_dims = dims; - this._chunk_address = address; - return; - } - }; - async function determine_data_shape(buf, offset) { - let version = (await struct.unpack_from_async(" this.get(k)); - } - length() { - return this.keys.length; - } - _dereference(ref) { - if (!ref) { - throw "cannot deference null reference"; - } - let obj = this.file._get_object_by_address(ref); - if (obj == null) { - throw "reference not found in file"; - } - return obj; - } - async get(y) { - if (typeof y == "number") { - return this._dereference(y); - } - var path = normpath(y); - if (path == "/") { - return this.file; - } - if (path == ".") { - return this; - } - if (/^\//.test(path)) { - return this.file.get(path.slice(1)); - } - if (posix_dirname(path) != "") { - var [next_obj, additional_obj] = path.split(/\/(.*)/); - } else { - var next_obj = path; - var additional_obj = "."; - } - if (!(next_obj in this._links)) { - throw next_obj + " not found in group"; - } - var obj_name = normpath(this.name + "/" + next_obj); - let link_target = this._links[next_obj]; - if (typeof link_target == "string") { - try { - return this.get(link_target); - } catch (error) { - return null; - } - } - var dataobjs = new DataObjects(this.file._fh, link_target); - await dataobjs.ready; - if (dataobjs.is_dataset) { - if (additional_obj != ".") { - throw obj_name + " is a dataset, not a group"; - } - return new Dataset$1(obj_name, dataobjs, this); - } else { - var new_group = new Group(obj_name, this); - await new_group.init(dataobjs); - return new_group.get(additional_obj); - } - } - visit(func) { - return this.visititems((name, obj) => func(name)); - } - visititems(func) { - var root_name_length = this.name.length; - if (!/\/$/.test(this.name)) { - root_name_length += 1; - } - var queue = this.values.slice(); - while (queue) { - let obj = queue.shift(); - if (queue.length == 1) - console.log(obj); - let name = obj.name.slice(root_name_length); - let ret = func(name, obj); - if (ret != null) { - return ret; - } - if (obj instanceof Group) { - queue = queue.concat(obj.values); - } - } - return null; - } - get attrs() { - if (this._attrs == null) { - this._attrs = this._dataobjects.get_attributes(); - } - return this._attrs; - } - }; - var File$1 = class extends Group { - constructor(fh, filename, options) { - super("/", null); - this.ready = this.init(fh, filename, options); - } - async init(fh, filename, options) { - var superblock = new SuperBlock(fh, 0); - await superblock.ready; - var offset = await superblock.get_offset_to_dataobjects(); - var dataobjects = new DataObjects(fh, offset); - await dataobjects.ready; - this.parent = this; - this.file = this; - this.name = "/"; - this._dataobjects = dataobjects; - this._attrs = null; - this._keys = null; - this._fh = fh; - this.filename = filename || ""; - this.mode = "r"; - this.userblock_size = 0; - if (options && options.index) { - this.index = options.index; - } else { - let index_offset; - if (options && options.indexOffset) { - index_offset = options.indexOffset; - } else { - const attrs = await this.attrs; - if (attrs.hasOwnProperty("_index_offset")) { - index_offset = attrs["_index_offset"]; - } else { - const indexName = this.indexName || "_index"; - const index_link = await dataobjects.find_link(indexName); - if (index_link) { - index_offset = index_link[1]; - } - } - } - if (index_offset) { - try { - const dataobject = new DataObjects(fh, index_offset); - await dataobject.ready; - const comp_index_data = await dataobject.get_data(); - const inflated = ungzip_1(comp_index_data); - const json = new TextDecoder().decode(inflated); - this.index = JSON.parse(json); - } catch (e) { - console.error(`Error loading index by offset ${e}`); - } - } - } - if (this.index && this.name in this.index) { - this._links = this.index[this.name]; - } else { - this._links = await dataobjects.get_links(); - } - } - _get_object_by_address(obj_addr) { - if (this._dataobjects.offset == obj_addr) { - return this; - } - return this.visititems((y) => { - y._dataobjects.offset == obj_addr ? y : null; - }); - } - }; - var Dataset$1 = class extends Array { - constructor(name, dataobjects, parent) { - super(); - this.parent = parent; - this.file = parent.file; - this.name = name; - this._dataobjects = dataobjects; - this._attrs = null; - this._astype = null; - } - get value() { - var data = this._dataobjects.get_data(); - if (this._astype == null) { - return this.getValue(data); - } - return data.astype(this._astype); - } - get shape() { - return this._dataobjects.shape; - } - get attrs() { - return this._dataobjects.get_attributes(); - } - get dtype() { - return this._dataobjects.dtype; - } - get fillvalue() { - return this._dataobjects.get_fillvalue(); - } - async to_array() { - const value = await this.value; - const shape = await this.shape; - return create_nested_array(value, shape); - } - async getValue(data) { - const dtype = await this.dtype; - if ((typeof dtype === "string" || dtype instanceof String) && dtype.startsWith("S")) { - return (await data).map((s) => { - let idx = s.indexOf("\0"); - return idx >= 0 ? s.substring(0, idx) : s; - }); - } else { - return data; - } - } - }; - function posix_dirname(p) { - let sep = "/"; - let i = p.lastIndexOf(sep) + 1; - let head = p.slice(0, i); - let all_sep = new RegExp("^" + sep + "+$"); - let end_sep = new RegExp(sep + "$"); - if (head && !all_sep.test(head)) { - head = head.replace(end_sep, ""); - } - return head; - } - function normpath(path) { - return path.replace(/\/(\/)+/g, "/"); - } - function create_nested_array(value, shape) { - const total_length = value.length; - const dims_product = shape.reduce((previous, current) => previous * current, 1); - if (total_length !== dims_product) { - console.warn(`shape product: ${dims_product} does not match length of flattened array: ${total_length}`); - } - let output = value; - const subdims = shape.slice(1).reverse(); - for (let dim of subdims) { - const new_output = []; - const { length } = output; - let cursor = 0; - while (cursor < length) { - new_output.push(output.slice(cursor, cursor += dim)); - } - output = new_output; - } - return output; - } - /*! pako 2.0.4 https://github.com/nodeca/pako @license (MIT AND Zlib) */ - - async function openH5File(options) { - - // Some clients (notably igv-webapp) pass a File reference in the url field. Fix this - if(options.url && isBlobLike(options.url)) { - options.file = options.url; - options.url = undefined; - } - - const isRemote = options.url !== undefined; - let fileReader = options.reader ? options.reader : getReaderFor(options); - - // Set default options appropriate for spacewalk - const fetchSize = options.fetchSize || 2000; - const maxSize = options.maxSize || 200000; - - if (isRemote) { - fileReader = new BufferedFile$1({file: fileReader, fetchSize, maxSize}); - } - const asyncBuffer = new AsyncBuffer(fileReader); - - // Optional external index -- this is not common - const index = await readExternalIndex(options); - const indexOffset = options.indexOffset; - - // Create HDF5 file - const filename = getFilenameFor(options); - const hdfFile = new File$1(asyncBuffer, filename, {index, indexOffset}); - await hdfFile.ready; - return hdfFile - } - - async function readExternalIndex(options) { - - let indexReader; - if(options.indexReader) { - indexReader = options.indexReader; - } - else if(options.index) { - return options.index - } else if (options.indexURL) { - indexReader = new RemoteFile$1({url: options.indexURL}); - } else if (options.indexPath) { - indexReader = new NodeLocalFile({path: options.indexPath}); - } else if (options.indexFile) { - indexReader = new BlobFile({file: options.indexFile}); - } - if (indexReader) { - const indexFileContents = await indexReader.read(); - const indexFileJson = new TextDecoder().decode(indexFileContents); - return JSON.parse(indexFileJson) - } else { - return undefined - } - } - - - function getReaderFor(options) { - if (options.url) { // An absolute or relative URL - return new RemoteFile$1(options) - } else if (options.path) { // A file path - return new NodeLocalFile(options) - } else if (options.file) { // A Browser file blob - return new BlobFile(options.file) - } else { - throw Error("One of 'url', 'path (node only)', or 'file (browser only)' must be specified") - } - } - - function getFilenameFor(options) { - if (options.url) { - return getFilename(options.url) - } else if (options.path) { - return getFilename(options.path) - } else if (options.file) { - return options.file.name - } - } - - /** - * Wraps an io.Reader in an interface jsfive-async expects* - */ - class AsyncBuffer { - constructor(fileReader) { - this.fileReader = fileReader; - } - - async slice(start, end) { - return this.fileReader.read(start, end - start) - } - } - - function getFilename(pathOrURL) { - const idx = pathOrURL.lastIndexOf("/"); - return idx > 0 ? pathOrURL.substring(idx + 1) : pathOrURL - } - - function isBlobLike(obj) { - return typeof obj.slice === 'function' && typeof obj.arrayBuffer === 'function' - } - - class HDF5Reader { - - constructor(h5_file, bin_size=100000){ - - this.h5_file = h5_file; - this.bin_size = bin_size; - this.h5_obj = undefined; - } - - async fetch(){ - - if(!this.h5_obj) { - this.h5_obj = await openH5File({ - url: this.h5_file, - fetchSize: 1000000, - maxSize: 200000000 - }); - } - return this.h5_obj - } - - async get_keys(){ - /* returns a list of keys of the pytor file*/ - let h5_obj = await this.fetch(); - - return h5_obj.keys - } - - async get_rd_signal(bin_size=this.bin_size){ - - let h5_obj = await this.fetch(); - let h5_obj_keys = h5_obj.keys; - - // console.log(h5_obj_keys) - let signal_bin = new ParseSignals(h5_obj_keys); - let rd_bins = signal_bin.get_rd_bins(); - let snp_bins = signal_bin.get_snp_bins(); - this.available_bins = [...new Set(rd_bins, snp_bins)]; - - // let bin_size = this.bin_size - if(! this.available_bins.includes(bin_size)){ - bin_size = this.available_bins.at(-1); - } - - const chr_ds = await h5_obj.get("rd_chromosomes"); - await chr_ds.dtype; - let rd_chromosomes = await chr_ds.value; - //console.log(`get_rd_signal rd_chromosomes ${Date.now() - t0}`) - //rd_chromosomes = fixString(rd_chromosomes) - let rd_flag = ""; - - // get rd stat - let rd_stat = await this.rd_stat(h5_obj, h5_obj_keys, bin_size); - - var wigFeatures = []; - var wigFeatures_gc = []; - var wigFeatures_rd_call_meanshift = []; - var wigFeatures_rd_call_combined = []; - var wigFeatures_baf1 = []; - var wigFeatures_baf2 = []; - - for (let chrom of rd_chromosomes) { - // for normal rd signal - var signal_rd = `his_rd_p_${chrom}_${bin_size}${rd_flag}`; - let chr_wig = await this.get_chr_signal(h5_obj, h5_obj_keys, chrom, bin_size, signal_rd, rd_stat); - wigFeatures = wigFeatures.concat(chr_wig); - - // rd gc corrected - var signal_rd_gc = `his_rd_p_${chrom}_${bin_size}_GC`; - let chr_wig_gc = await this.get_chr_signal(h5_obj, h5_obj_keys, chrom, bin_size, signal_rd_gc, rd_stat); - wigFeatures_gc = wigFeatures_gc.concat(chr_wig_gc); - - // rd call MeanShift - - let signal_rd_call = `his_rd_p_${chrom}_${bin_size}_partition_GC_merge`; - let chr_wig_rd_call_meanshift = await this.get_chr_signal(h5_obj, h5_obj_keys, chrom, bin_size, signal_rd_call, rd_stat); - wigFeatures_rd_call_meanshift = wigFeatures_rd_call_meanshift.concat(chr_wig_rd_call_meanshift); - - let chr_wig_rd_call = await this.rd_call_combined(h5_obj, h5_obj_keys, chrom, bin_size, rd_stat); - wigFeatures_rd_call_combined = wigFeatures_rd_call_combined.concat(chr_wig_rd_call); - - // baf likelihood - let signal_baf_1 = `snp_likelihood_${chrom}_${bin_size}_mask`; - let chr_wig_bafs = await this.get_baf_signals(h5_obj, h5_obj_keys, chrom, bin_size, signal_baf_1); - - // let signal_baf_1 = `snp_i1_${chrom}_${bin_size}_mask` - // let chr_wig_bafs = await this.get_baf_signals_v2(h5_obj, h5_obj_keys, chrom, bin_size, signal_baf_1) - - wigFeatures_baf1 = wigFeatures_baf1.concat(chr_wig_bafs[0]); - wigFeatures_baf2 = wigFeatures_baf2.concat(chr_wig_bafs[1]); - // this.rd_call_combined(h5_obj, h5_obj_keys, chrom, bin_size, rd_stat) - } - this.callers = []; - if (wigFeatures_rd_call_combined.length != 0){ - this.callers.push('ReadDepth'); - } - if (wigFeatures_rd_call_combined.length != 0){ - this.callers.push('2D'); - } - - var obj = {}; - var signal_obj = { - "RD_Raw": wigFeatures, - "RD_Raw_gc_coor" : wigFeatures_gc, - "ReadDepth": wigFeatures_rd_call_meanshift, - "2D": wigFeatures_rd_call_combined, - "BAF1": wigFeatures_baf1, - "BAF2": wigFeatures_baf2 - }; - obj[bin_size] = signal_obj; - return obj - } - - decode_segments(segments_arr){ - let max = 2 ** 32 - 1; - let segments = []; - let l = []; - for (let x of segments_arr){ - if(x == max){ - segments.push(l); - l = []; - } else { - l.push(x); - } - } - return segments - } - - async rd_call_combined(h5_obj, h5_obj_keys, chrom, bin_size, rd_stat){ - let chr_wig = []; - - let segments; - let mosaic_call_segments = `his_rd_p_${chrom}_${bin_size}_partition_GC_mosaic_segments_2d`; - if (h5_obj_keys.includes(mosaic_call_segments)){ - const chrom_dataset = await h5_obj.get(mosaic_call_segments); - let chrom_data = await chrom_dataset.value; - //console.log(`rd_call_combined ${mosaic_call_segments} ${Date.now() - t0}`) - segments = this.decode_segments(chrom_data); - - } - - let mosaic_calls = `his_rd_p_${chrom}_${bin_size}_partition_GC_mosaic_call_2d`; - if (h5_obj_keys.includes(mosaic_calls)){ - const segments_call_dataset = await h5_obj.get(mosaic_calls); - let segments_call = await segments_call_dataset.to_array(); //create_nested_array(value, shape) - segments.forEach((ind_segment, segment_idx) => { - ind_segment.forEach((bin_value, bin_idx) =>{ - chr_wig.push({chr:chrom, start: bin_value*bin_size, end: (bin_value+1) * bin_size, value: (segments_call[0][segment_idx]/rd_stat[4]) *2}); - }); - }); - } - - return chr_wig - - } - - async rd_stat(h5_obj, h5_obj_keys, bin_size){ - /* - returns a list for rd statistics information - paramter - --------- - h5_obj: cnvpytor read object - h5_obj_keys: a list of available signal names - bin_size: bin size - - */ - - let rd_stat_signal = `rd_stat_${bin_size}_auto`; - let rd_stat; - if (h5_obj_keys.includes(rd_stat_signal)){ - const rd_stat_dataset = await h5_obj.get(rd_stat_signal); - rd_stat = await rd_stat_dataset.value; - //console.log(`rd_stat_signal ${rd_stat_signal} ${Date.now() - t0}`) - } - return rd_stat - } - - - async get_chr_signal(h5_obj, h5_obj_keys, chrom, bin_size, signal_name, rd_stat){ - /* return a list of dictionary for a chromosome */ - let chr_wig = []; - - if (h5_obj_keys.includes(signal_name)){ - const chrom_dataset = await h5_obj.get(signal_name); - let chrom_data = await chrom_dataset.value; - //console.log(`chr_signal ${signal_name} ${Date.now() - t0}`) - chrom_data.forEach((bin_value, bin_idx) => { - chr_wig.push({chr:chrom, start: bin_idx*bin_size, end: (bin_idx+1) * bin_size, value: (bin_value/rd_stat[4]) *2}); - }); - } - return chr_wig - } - - async get_baf_signals(h5_obj, h5_obj_keys, chrom, bin_size, signal_name){ - /* return two list of dictionary*/ - let chr_wig_1 = []; - let chr_wig_2 = []; - if (h5_obj_keys.includes(signal_name)){ - let chrom_dataset = await h5_obj.get(signal_name); - let chrom_data = await chrom_dataset.to_array(); //create_nested_array(value, shape) - chrom_data.forEach((bin_value, bin_idx) => { - let max_value = Math.max(...bin_value); - const res = bin_value.indexOf(max_value); - let lh = Math.max(res / 200, 1 - res / 200); - chr_wig_1.push({chr:chrom, start: bin_idx*bin_size, end: (bin_idx+1) * bin_size, value: -2 * lh}); - if(lh != 0.5){ - chr_wig_2.push({chr:chrom, start: bin_idx*bin_size, end: (bin_idx+1) * bin_size, value: -2 *(1-lh)}); - } - }); - } - return [chr_wig_1, chr_wig_2] - } - - async get_baf_signals_v2(h5_obj, h5_obj_keys, chrom, bin_size, signal_name){ - - /* return two list of dictionary*/ - let chr_wig_1 = []; - let chr_wig_2 = []; - if (h5_obj_keys.includes(signal_name)){ - let chrom_dataset = await h5_obj.get(signal_name); - let chrom_data = await chrom_dataset.to_array(); //create_nested_array(value, shape) - chrom_data.forEach((lh, bin_idx) => { - if (!isNaN(lh)){ - chr_wig_1.push({chr:chrom, start: bin_idx*bin_size, end: (bin_idx+1) * bin_size, value: -2 * ( 0.5 - lh )}); - if(lh != 0.5){ - chr_wig_2.push({chr:chrom, start: bin_idx*bin_size, end: (bin_idx+1) * bin_size, value: -2 * ( 0.5 + lh )}); - } - } - }); - } - console.log(chrom, chr_wig_1, chr_wig_2); - return [chr_wig_1, chr_wig_2] - - } - } - - class ParseSignals{ - - constructor(signals){ - /* - Parse a signal names - - parameter - --------- - signals: List of keys in pytor files - */ - this.signals = signals; - } - - get_rd_bins(){ - /* return list of rd bins */ - let rd_keys = []; - this.signals.forEach( val => { - let match = val.match(/^his_rd_p_(.*)_(\d+)$/); - if(match){ - rd_keys.push({chr:match[1], bin_size:match[2]}); - }}); - const rd_bins = [...new Set(rd_keys.map(item => Number(item.bin_size)))]; - return rd_bins - } - - get_snp_bins(){ - /* return list of snp bins */ - let slected_signals = []; - this.signals.forEach( val => { - let match = val.match(/^snp_likelihood_(.*)_(\d+)_mask$/); - if(match){ - slected_signals.push({chr:match[1], bin_size:match[2]}); - }}); - const bins = [...new Set(slected_signals.map(item => Number(item.bin_size)))]; - return bins - } - } - - class GetFit { - constructor(allBins) { - this.allBins = allBins; - } - getValues() { - const bins = Object.values(this.allBins).reduce( - (binResult, bin) => { return binResult.concat(bin.filter(a => a.binScore > 0).map(a => a.binScore)) }, []); - return bins - } - getMean(data) { - return (data.reduce(function (a, b) { return a + b; }) / data.length); - } - fit_data() { - let rd_list = this.getValues(); - let distParmas = getDistParams(rd_list); - return distParmas - } - - histogram(data, bins) { - const step = bins[1] - bins[0]; - const hist_bins = []; - - data.forEach((value, index) => { - bins.forEach((bin_value, bin_index) => { - if (!hist_bins[bin_value]) { - hist_bins[bin_value] = { count: 0 }; - } - if (bin_value <= value && value < bin_value + step) { - hist_bins[bin_value].count++; - return false; - } - }); - }); - const dist_p = []; - hist_bins.forEach((bin, index) => { dist_p.push(bin.count); }); - return dist_p - } - - } - - function range_function(start, stop, step) { - const data_array = Array(Math.ceil((stop - start) / step)) - .fill(start) - .map((x, y) => x + y * step); - return data_array; - } - - function filterOutliers(someArray) { - - if (someArray.length < 4) - return someArray; - - let values, q1, q3, iqr, maxValue, minValue; - - values = someArray.slice().sort((a, b) => a - b); //copy array fast and sort - - if ((values.length / 4) % 1 === 0) { //find quartiles - q1 = 1 / 2 * (values[(values.length / 4)] + values[(values.length / 4) + 1]); - q3 = 1 / 2 * (values[(values.length * (3 / 4))] + values[(values.length * (3 / 4)) + 1]); - } else { - q1 = values[Math.floor(values.length / 4 + 1)]; - q3 = values[Math.ceil(values.length * (3 / 4) + 1)]; - } - - iqr = q3 - q1; - maxValue = q3 + iqr * 1.5; - minValue = q1 - iqr * 1.5; - - return values.filter((x) => (x >= minValue) && (x <= maxValue)); - } - - function getDistParams(bins) { - let filteredBins = filterOutliers(bins); - const n = filteredBins.length; - const mean = filteredBins.reduce((a, b) => a + b) / n; - const std = Math.sqrt(filteredBins.map(x => Math.pow(x - mean, 2)).reduce((a, b) => a + b) / n); - return [mean, std] - } - - function linspace(a, b, n) { - if (typeof n === "undefined") n = Math.max(Math.round(b - a) + 1, 1); - if (n < 2) { - return n === 1 ? [a] : []; - } - var ret = Array(n); - n--; - for (let i = n; i >= 0; i--) { - ret[i] = (i * b + (n - i) * a) / n; - } - return ret; - } - - var g_utils = { range_function, getDistParams, linspace, GetFit}; - - /** - * Evaluates the cumulative distribution function (CDF) for a Student's t distribution with degrees of freedom `v` at a value `t`. - * - * @params {number} t - value for the t test - * @params {PositiveNumber} v - degree of freedom - * @returns {Probability} evaluated CDF - */ - function TdistributionCDF(t, v){ - if (isNaN( t ) || isNaN( v ) || v <= 0.0) { - return NaN; - } - if ( t === 0.0 ) { - return 0.5; - } - return 1/2 + (1/2 * (incompbeta(1/2*v, 1/2, 1) - incompbeta(1/2*v, 1/2, v/(v+t*t)))) * Math.sign( t) - - } - - - /** - * incompbeta(a,b,x) evaluates incomplete beta function, here a, b > 0 and 0 <= x <= 1. This function requires contfractbeta(a,b,x, ITMAX = 200) - * code translated from https://malishoaib.wordpress.com/2014/04/15/the-beautiful-beta-functions-in-raw-python/ - * - * @params - * @params - * @params - * @returns - */ - function incompbeta(a, b, x){ - - if(x == 0){ - return 0; - } - else if (x == 1){ - return 1; - }else - { - let lbeta = lgamma(a+b) - lgamma(a) - lgamma(b) + a * Math.log(x) + b * Math.log(1-x); - if (x < (a+1) / (a+b+2)){ - return Math.exp(lbeta) * contfractbeta(a, b, x) / a; - } - else { - return 1 - Math.exp(lbeta) * contfractbeta(b, a, 1-x) / b; - } - } - } - - /** - * contfractbeta() evaluates the continued fraction form of the incomplete Beta function; incompbeta(). - * (Code translated from: Numerical Recipes in C.) - * - * @param {*} a - * @param {*} b - * @param {*} x - * @param {*} ITMAX - * @returns - */ - function contfractbeta(a,b,x, ITMAX = 1000){ - - let EPS = 3.0e-7; - let az = 1.0; - let am = 1.0; - let bm = 1.0; - let qab = a + b; - let qap = a + 1.0; - let qam = a-1.0; - let bz = 1.0 - qab*x/qap; - - //for i in range(ITMAX): - for(let i =0; i<= ITMAX; i++){ - let em = parseFloat(i+1); - let tem = em + em; - let d = em*(b-em)*x/((qam+tem)*(a+tem)); - let ap = az + d*am; - let bp = bz+d*bm; - d = -(a+em)*(qab+em)*x/((qap+tem)*(a+tem)); - let app = ap+d*az; - let bpp = bp+d*bz; - let aold = az; - am = ap/bpp; - bm = bp/bpp; - az = app/bpp; - bz = 1.0; - if (Math.abs(az-aold)<(EPS * Math.abs(az))){ - return az - } - } - } - - /** - * Evaluates factorial of a number - * - * @param {Number} xf - Integer number - * @returns factorial of the number - */ - function factorial(xf) { - if ((xf == 0) || (xf == 1)) return 1; - else { - let result = (xf * factorial(xf - 1)); - return result - } - } - - /** - * Evalues factorial for an integer or fraction using either either factorial or gamma function - * - * @param {Number} a - integar or fraction number - * @returns value of a gamma function - */ - function gamma(a){ - let gamma; - - var qc = [75122.6331530, 80916.6278952, 36308.2951477, 8687.24529705, 1168.92649479, 83.8676043424, 2.50662827511]; - - var sum1 = 0; - var prod1 = 1; - if (a == 0) { - gamma = 1e99; - }else { - if ((a % 1) == 0) {//if integer - gamma = factorial(a - 1); - } - else { //not integer - for (let j = 0; j < qc.length; j++) { - sum1 = sum1 + qc[j] * Math.pow(a, j); - prod1 = prod1 * (a + j); - } - gamma = (sum1 * Math.pow((a + 5.5), (a + 0.5))) * Math.exp(-(a + 5.5)) / prod1; - } - } - - return gamma - } - - /** - * - * @param {Number} xg - integar or fraction number - * @returns natural log of gamma function - */ - - function lgamma(xg){ - return Math.log(gamma(xg)) - } - - function t_test_1_sample$1(mean, m, s, n) { - if (s == 0) s = 1; - var t = ((mean - m) / s) * Math.sqrt(n); - var p = 1.0 - TdistributionCDF(Math.abs(t), (n - 1)); - return p - } - - function t_test_2_samples$1(m1, s1, n1, m2, s2, n2) { - if (s1 == 0) s1 = 1; - if (s2 == 0) s2 = 1; - var t = (m1 - m2) / Math.sqrt(s1 ** 2 / n1 + s2 ** 2 / n2); - var df = ((s1 ** 2 / n1 + s2 ** 2 / n2) ** 2 * (n1 - 1) * (n2 - 1)) / - ((s1 ** 4 * (n2 - 1)) / n1 ** 2 + (s2 ** 4 * (n1 - 1)) / n2 ** 2); - - var p = 1.0 - TdistributionCDF(Math.abs(t), parseInt(df + 0.5)); - - return p - } - - var t_dist = {TdistributionCDF, gamma, t_test_1_sample: t_test_1_sample$1, t_test_2_samples: t_test_2_samples$1}; - - class CombinedCaller{ - constructor(wigFeatures, binSize) { - this.wigFeatures = wigFeatures; - this.binSize = binSize; - // let fit_obj = this.get_fit() - // this.globalMean = fit_obj.globalMean - // this.globalStd = fit_obj.globalStd - } - get_fit(){ - var fit_info = new g_utils.GetFit(this.wigFeatures); - var [globalMean, globalStd] = fit_info.fit_data(); - - return {globalMean:globalMean, globalStd:globalStd} - - } - async call_2d(omin=null, mcount=null, event_type="both", max_distance=0.1, baf_threshold=0, max_copy_number=10, min_cell_fraction=0.0){ - - let fit_obj = this.get_fit(); - this.globalMean = fit_obj.globalMean; - this.globalStd = fit_obj.globalStd; - - let overlap_min = omin==null ? 0.05 * this.binSize / 3e9: omin ; - let min_count = mcount == null ? parseInt(this.binSize / 10000) : mcount ; - - let gstat_rd0 = []; - let gstat_rd_all = []; - let gstat_rd = []; - let gstat_error = []; - let gstat_lh = []; - let gstat_n = []; - - for (const [chr, wig] of Object.entries(this.wigFeatures)) { - let segments = []; - let levels = []; - let likelihoods = []; - - wig.forEach((bin, bin_idx) => { - if (bin.hets_count > 4 ){ - - if( bin.dp_count > min_count ){ - segments.push([bin_idx]); - levels.push(bin.binScore); - likelihoods.push(bin.likelihood_score); - delete bin.likelihood_score; - - } - } - }); - - let diff_level = []; - for(let i=1; i {return Math.sqrt(Math.sqrt(x) ** 2 + this.globalStd ** 2 + Math.pow(min_flank[x_idx]/2, 2));}); - - let overlaps = []; - - for(let i=0; i< segments.length-1; i++){ - - let lh_overlap = 0; - try{ - lh_overlap = likelihood_overlap(likelihoods[i], likelihoods[i+1]); - }catch{ - console.log("Overlap failed: ", i, likelihoods[i], segments[i+1], likelihoods[i+1]); - } - - let rd_overlap = normal_overlap_approx(levels[i], error[i], levels[i+1], error[i+1]); - overlaps.push(rd_overlap * lh_overlap); - - } - - while(overlaps.length >0) { - overlaps = overlaps.filter(num => typeof num === "number"); - - let max_overlap = arrayMax(overlaps); - if(isNaN(max_overlap)){ - console.log('NaN value', overlaps); - } - if(max_overlap < overlap_min){ - // console.log("maxoverlap ",max_overlap, "is smaller than overlap min") - break - } - let i = overlaps.indexOf(max_overlap); - - let merge_level = normal_merge(levels[i], error[i], levels[i + 1], error[i + 1]); - - let nlh; - let nlh_sum; - try{ - nlh = likelihoods[i].map((l_value, l_idx) => { return l_value * likelihoods[i+1][l_idx]}); - - nlh_sum = nlh.reduce((a, c_value) => {return a + c_value}); - - }catch{ - console.log(likelihoods); - console.log('max_overlap:', max_overlap, i, overlaps.length); - console.log('likelihood: ', i ,likelihoods[i], likelihoods[i+1]); - console.log('nlh: ', nlh_sum); - } - // nlh_sum = nlh.reduce((a, c_value) => {return a + c_value}); - - levels[i] = merge_level.nl; - error[i] = merge_level.ne; - - likelihoods[i] = nlh.map(function(item) { return item/nlh_sum } ); - - segments[i].push(...segments[i+1]); - - levels.splice(i + 1, 1); - error.splice(i + 1, 1); - segments.splice(i + 1, 1); - likelihoods.splice(i + 1, 1); - overlaps.splice(i, 1); - - if(i < overlaps.length){ - - let rd_overlap = normal_overlap_approx(levels[i], error[i], levels[i+1], error[i+1]); - let new_overlap = rd_overlap * likelihood_overlap(likelihoods[i], likelihoods[i + 1]); - - overlaps[i] = new_overlap; - } - if(i > 0){ - let new_overlap = normal_overlap_approx(levels[i - 1], error[i - 1], levels[i], error[i]) - * likelihood_overlap(likelihoods[i - 1], likelihoods[i]); - overlaps[i - 1] = new_overlap; - } - - } - let ons = -1; - while(true){ - overlaps = []; - for(let i=0; i< levels.length; i++){ - for(let j=i; j { return l_value * likelihoods[i+1][l_idx]}); - let nlh_sum = nlh.reduce((a, c_value) => {return a + c_value}); - likelihoods[i] = nlh.map(function(item) { return item/nlh_sum } ); - - - segments[i].push(...segments[i+1]); - segments[i] = segments[i].sort((a,b) => a-b); - - levels.splice(j, 1); - error.splice(j, 1); - segments.splice(j, 1); - likelihoods.splice(j, 1); - - if(j >= segments.length){ - i += 1; - j = i + 1; - } - - }else { - j += 1; - if(j >= segments.length){ - i += 1; - j = i + 1; - } - } - } - if(ons == segments.length){ - break - } - ons = segments.length; - } - // console.log('final segments', segments) - - segments.forEach((seg_value, seg_idx) => { - let baf_info = likelihood_baf_pval(likelihoods[seg_idx]); - if(seg_value.length > 1){ - - seg_value.forEach((bin, bin_idx) =>{ - gstat_rd_all.push(wig[bin]); - if(baf_info.mean <= baf_threshold){ - gstat_rd0.push(wig[bin]); - } - wig[bin].segment_score = levels[seg_idx]; - }); - gstat_rd.push(levels[seg_idx]); - gstat_error.push(error[seg_idx]); - gstat_lh.push(likelihoods[seg_idx]); - - } - - }); - - continue - } - - // Third stage for call - - // let data = gstat_rd0.lengthn == 0 ? gstat_rd_all: gstat_rd0 ; - - let points = parseInt(1000 * (1 - min_cell_fraction)); - if(points == 0){ - points = 1; - } - let x = g_utils.linspace(min_cell_fraction, 1, points); - let master_lh = {}; - let germline_lh = {}; - for(let cn=10; cn > -1; cn--){ - for(let h1=0; h1 < (cn/2+1); h1++){ - let h2 = cn - h1; - let mrd = x.map((v, idx) => {return 1-v +v*cn/2}); - let g_mrd = cn / 2; - let g_mbaf; - let mbaf; - if(cn > 0){ - g_mbaf = 0.5 - (h1 / (h1 + h2)); - mbaf = x.map((v, idx) => {return 0.5 - (1 - v + v * h1) / (2 - 2 * v + (h1 + h2) * v)}); - - }else { - g_mbaf = 0; - mbaf = x.map((v, idx) => {return 0*v}); - } - - for( let ei=0; ei < gstat_rd.length; ei++){ - - let g_lh = normal(g_mrd * this.globalMean, 1, gstat_rd[ei], gstat_error[ei]) * likelihood_of_baf(gstat_lh[ei], 0.5 + g_mbaf); - if(ei in germline_lh){ - germline_lh[ei].push([cn, h1, h2, g_lh, 1.0]); - }else { - germline_lh[ei] = [cn, h1, h2, g_lh, 1.0]; - } - let slh = 0; - let max_lh = 0; - let max_x = 0; - mrd.forEach((mi, idx) => { - if(!isNaN(mbaf[idx])){ - let tmpl = normal(mi * this.globalMean, 1, gstat_rd[ei], gstat_error[ei]) * likelihood_of_baf(gstat_lh[ei], 0.5 + mbaf[idx]); - slh += tmpl; - if(tmpl > max_lh){ - max_lh = tmpl; - max_x = x[idx]; - } - } - }); - if(ei in master_lh){ - master_lh[ei].push([cn, h1, h2, slh / x.length, max_x]); - }else { - master_lh[ei] = [cn, h1, h2, slh / x.length, max_x]; - } - } - - for( let ei=0; ei < gstat_rd.length; ei++){ - if(event_type == "germline"){ - master_lh[ei].sort((a, b) => a[3] - b[3]); - } - else { - master_lh[ei].sort((a, b) => a[3] - b[3]); - if(event_type == "both"){ - - germline_lh[ei].sort((a, b) => a[3] - b[3]); - if(germline_lh[ei][0][3] > master_lh[ei][0][3]){ - //let tmp_list = list(filter( lambda x: x[0] != germline_lh[ei][0][0] and x[1] != germline_lh[ei][0][1], master_lh[ei])) - let tmp_list = master_lh[ei].filter((x) => (x[0] != germline_lh[ei][0][0]) && (x[1] <= germline_lh[ei][0][1])); - // console.log('tmp_list', tmp_list) - // master_lh[ei] = [germline_lh[ei][0]] + tmp_list - master_lh[ei] = [germline_lh[ei][0]].push(...tmp_list); - } - } - } - } - for( let ei=0; ei < gstat_rd.length; ei++){ - if(master_lh[ei][0][0] > 2); - if(master_lh[ei][0][0] < 2); - gstat_rd[ei] / this.globalMean; - t_dist.t_test_1_sample(this.globalMean, gstat_rd[ei], gstat_error[ei], gstat_n[ei]); - // console.log(etype) - - } - - - // break - } - - } - - var rawbinScore = this.formatDataStructure(this.wigFeatures, 'binScore', this.globalMean); - var callScore = this.formatDataStructure(this.wigFeatures, 'segment_score', this.globalMean); - - return {binScore: rawbinScore, segment_score: callScore} - - } - - formatDataStructure(wigFeatures, feature_column, scaling_factor = 1) { - const results = []; - for (const [chr, wig] of Object.entries(wigFeatures)) { - - wig.forEach(sample => { - var new_sample = { ...sample }; - if (scaling_factor != 1) { - new_sample.value = sample[feature_column] / scaling_factor * 2; - } - results.push(new_sample); - }); - } - - return results - } - - formatDataStructure_BAF(feature_column, scaling_factor = 2) { - const baf1 = []; - const baf2 = []; - for (const [chr, wig] of Object.entries(this.wigFeatures)) { - - wig.forEach(sample => { - - var baf1_value = { ...sample }; - var baf2_value = { ...sample }; - - let value = sample[feature_column]; - if (value != 0.5){ - baf2_value.value = -2 * (1 - value); - baf2.push(baf2_value); - } - baf1_value.value = -2 * value; - baf1.push(baf1_value); - - }); - } - - - return [baf1, baf2] - } - } - - function arrayMax(arr) { - return arr.reduce(function (p, v) { - return ( p > v ? p : v ); - }); - } - - /** - * Normal distribution. - * - * @param {float} x - Variable. - * @param {float} a - area - * @param {float} x0 - Mean value - * @param {float} sigma - Sigma - * @returns {float} - Value of distribution in x. - */ - function normal(x, a, x0, sigma){ - - return a * Math.exp(-1* (x - x0) ** 2 / (2 * sigma ** 2)) / Math.sqrt(2 * Math.PI) / sigma - - } - - /** - * Calculates two normal distributions overlap area. - * - * @param {float} m1 - Mean value of the first distribution - * @param {float} s1 - Sigma of the first distribution - * @param {float} m2 - Mean value for second distribution - * @param {float} s2 - Sigma of the second distribution - * - * @returns {float} area - Area of overlap - */ - function normal_overlap_approx(m1, s1, m2, s2){ - - return Math.exp(-1* (m1-m2)**2/ (s1**2+s2**2)) - } - - - /** - * Returns overlap area of two likelihood functions. - * - * @param {*} lk1 - First likelihood function. - * @param {*} lk2 - Second likelihood function. - * - * @returns {float} - Overlap area. - */ - function likelihood_overlap(likelihood_1, likelihood_2){ - let sum; - try{ - sum = likelihood_1.reduce((accumulator, currentValue, currentIndex) => {return accumulator + Math.min(currentValue, likelihood_2[currentIndex])}); - }catch{ - console.log("Failed to find likelihood overlap: ", likelihood_1, likelihood_2); - return 0 - } - - return sum - } - - /** - * Calculates normal distribution that is product of two given normal distributions. - * - * @param {float} m1 - Mean value of the first distribution - * @param {float} s1 - Sigma of the first distribution - * @param {float} m2 - Mean value for second distribution - * @param {float} s2 - Sigma of the second distribution - * @returns {Object} An object representing the first distribution - * @property {float} nl - Mean value of the first distribution - * @property {float} ne - Sigma of the first distribution - */ - function normal_merge(m1, s1, m2, s2){ - - if((s1 == 0) && (s2 == 0)){ - return {nl: 0.5 * (m1 + m2), ne: 0} - } - else { - return {nl: (m1 * s2 * s2 + m2 * s1 * s1) / (s1 * s1 + s2 * s2), ne: Math.sqrt(s1 * s1 * s2 * s2 / (s1 * s1 + s2 * s2))} - } - } - - /** - * Calculates likelihood for given baf - * @param {*} likelihood - * @param {*} baf - * @returns {float} likelihood value - */ - function likelihood_of_baf(likelihood, baf){ - - let bin = parseInt(baf * (likelihood.length - 1)); - let fr = baf * (likelihood.length - 1) - bin; - if(bin < likelihood.length - 1){ - return likelihood[bin] * (1 - fr) + likelihood[bin + 1] * fr - } - else { - return likelihood[bin] - } - } - - /** - * - * Calculates baf level and p-value for given likelihood function. - * - * @param {*} likelihood - * @returns {Object} An object representing BAF - * @property {float} mean BAF level (difference from 1/2) - * @property {float} p p-value for event different than 1/2 - */ - function likelihood_baf_pval(likelihood) { - const res = likelihood.length; - const max_lh = Math.max(...likelihood); - let ix = likelihood.indexOf(max_lh); - if (ix > Math.floor(res / 2)) { - ix = res - 1 - ix; - } - const b = (res / 2 - ix) / (res + 1); - - const ix1 = Math.floor((res / 2 + ix) / 2); - const ix2 = res - 1 - ix1; - let p = likelihood.slice(ix1, ix2 + 1).reduce((acc, val) => acc + val, 0) / likelihood.reduce((acc, val) => acc + val, 0); - if (ix === Math.floor(res / 2)) { - p = 1.0; - } - return {mean:b, p:p}; - } - - var combined_caller = {CombinedCaller}; - - function erf(x) { - var m = 1.0, s = 1.0, sum = x * 1.0; - for (var i = 1; i < 50; i++) { - m *= i; - s *= -1; - sum += (s * Math.pow(x, 2.0 * i + 1.0)) / (m * (2.0 * i + 1.0)); - } - return (2 * sum) / Math.sqrt(3.14159265358979) - } - - function getEValue(mean, sigma, rd, start, end) { - var arr = new DataStat(rd.slice(start, end)); - if (arr.std == 0) { - if (sigma > 0) { arr.std = (sigma * arr.mean) / mean; } - else { arr.std = 1; } - } - var p_val = t_test_1_sample(mean, arr.mean, arr.std, end - start) / (end - start); - return p_val - } - - function gaussianEValue(mean, sigma, rd, start, end) { - var arr = new DataStat(rd.slice(start, end)); - - if (arr.mean < mean) { - var x = (arr.max - arr.mean) / (sigma * Math.sqrt(2)); - return Math.pow(0.5 * (1 + erf(x)), end - start) - } - var x = (arr.min - arr.mean) / (sigma * Math.sqrt(2)); - return Math.pow(0.5 * (1 - erf(x)), end - start) - } - - function adjustToEvalue(mean, sigma, rd, start, end, pval, max_steps = 1000) { - var val = getEValue(mean, sigma, rd, start, end); - var step = 0, done = false; - while ((val > pval) & !done & (step < max_steps)) { - done = true; - step += 1; - var [v1, v2, v3, v4] = [1e10, 1e10, 1e10, 1e10]; - if (start > 0) v1 = getEValue(mean, sigma, rd, start - 1, end); - if (end - start > 2) { - var v2 = getEValue(mean, sigma, rd, start + 1, end); - var v3 = getEValue(mean, sigma, rd, start, end - 1); - } - if (end < rd.length) { var v4 = getEValue(mean, sigma, rd, start, end + 1); } - if (Math.min[(v4)] < val) { - done = false; - if (v1 == Math.min[(v4)]) { - start -= 1; - val = v1; - } - elif(v2 == Math.min[(v4)]); { - start += 1; - val = v2; - } - elif(v3 == Math.min[(v4)]); { - end -= 1; - val = v3; - } - elif(v4 == Math.min[(v4)]); { - end += 1; - val = v4; - } - } - } - if (val <= pval) { return end } - return 0; - } - - class DataStat { - constructor(data_array) { - this.data = data_array; - this.mean = data_array.reduce((acc, n) => acc + n) / data_array.length; - this.std = Math.sqrt(data_array.reduce((acc, n) => (n - this.mean) ** 2) / data_array.length); - } - } - - function t_test_1_sample(mean, m, s, n) { - if (s == 0) s = 1; - var t = ((mean - m) / s) * Math.sqrt(n); - var p = 1.0 - t_dist.TdistributionCDF(Math.abs(t), (n - 1)); - return p - } - - function t_test_2_samples(m1, s1, n1, m2, s2, n2) { - if (s1 == 0) s1 = 1; - if (s2 == 0) s2 = 1; - var t = (m1 - m2) / Math.sqrt(s1 ** 2 / n1 + s2 ** 2 / n2); - var df = ((s1 ** 2 / n1 + s2 ** 2 / n2) ** 2 * (n1 - 1) * (n2 - 1)) / - ((s1 ** 4 * (n2 - 1)) / n1 ** 2 + (s2 ** 4 * (n1 - 1)) / n2 ** 2); - - var p = 1.0 - t_dist.TdistributionCDF(Math.abs(t), parseInt(df + 0.5)); - - return p - } - - class Partition { - - constructor(rd, mean, std) { - this.rd = rd; - this.mean = mean; - this.std = std; - this.bin_bands = [2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, 64, 80, 96, 112, 128]; - } - - get_rd_signal_bandwidth(data_array) { - var new_array = []; - - data_array.forEach((value, index) => { - var tmp_value = 0; - if (value > this.mean / 4) { - tmp_value = this.mean / (this.std ** 2 * value); - } else { - tmp_value = 4 / this.std ** 2; - } - new_array.push(tmp_value); - }); - return new_array - } - - meanShiftCaller(repeats = 3) { - var ChrLevels = {}; - - Object.entries(this.rd).forEach(([chr, chr_rd]) => { - var masked = new Array(chr_rd.length).fill(false); - - // set the level - var levels = new Array(chr_rd.length); - - for (let b = 0; b < chr_rd.length; b++) { - if (!masked[b]) { levels[b] = chr_rd[b]; } - } - - this.bin_bands.forEach((bin_band, bin_band_index) => { - // not masked levels at current bin - // get boolean values - var not_masked = masked.map((value, index) => { return !value; }); - - // not masked level at current bin - var nm_levels = []; - - Object.entries(chr_rd).forEach(([k, v]) => { nm_levels.push(v.binScore); }); - - // set the mask border - var mask_borders = [0]; - var count = 0; - - for (let i = 0; i < masked.length; i++) { - if (masked[i]) { - if (count > 0) { - mask_borders.push(mask_borders[mask_borders.length - 1] + count - 1); - count = 0; - } - } else { count += 1; } - } - - mask_borders.shift(); - - // repeating steps - for (let step = 0; step < repeats; step++) { - var isig = this.get_rd_signal_bandwidth(nm_levels); - var grad = new Array(nm_levels.length).fill(0); - - for (let i = 0; i < nm_levels.length; i++) { - for (let j = i - 3 * bin_band; j <= i + 3 * bin_band + 1; j++) { - if (j < 0 || j >= nm_levels.length) continue; - if (Math.abs(i - j) >= nm_levels.length) continue; - - var g_value = (j - i) * Math.exp((-0.5 * (j - i) ** 2) / bin_band ** 2) * - Math.exp(-0.5 * (nm_levels[i] - nm_levels[j]) ** 2 * isig[i]); - - grad[i] += g_value; - } - } - - // get the border - var border = new Array(); - for (var i = 0; i < grad.length - 1; i++) { - if ((grad[i] < 0) & (grad[i + 1] >= 0)) border.push(i); - } - - border.push(grad.length - 1); - border = border.concat(mask_borders).sort((a, b) => a - b); - border = Array.from(new Set(border)); - - var pb = 0; - for (var i = 0; i < border.length; i++) { - var range_array = nm_levels.slice(pb, border[i] + 1); - var range_mean = range_array.reduce((acc, n) => acc + n) / range_array.length; - - nm_levels.fill(range_mean, pb, border[i] + 1); - pb = border[i] + 1; - } - } - - for (var i = 0, j = 0; i < levels.length; i++) { - if (not_masked[i]) { - levels[i] = nm_levels[j]; - j++; - } - } - - //get the border - var border = new Array(); - for (var i = 0; i < levels.length - 1; i++) { - //if(i == levels.length -1) continue; - var diff = Math.abs(levels[i + 1] - levels[i]); - - if (diff > 0.01) border.push(i + 1); - } - - border.unshift(0); - border.push(levels.length); - - // reset the mask - masked = new Array(this.rd.length).fill(false); - - // check the borders - for (var i = 1; i < border.length; i++) { - var seg = [border[i - 1], border[i]]; - var seg_left = [border[i - 1], border[i - 1]]; - if (i > 1) { seg_left[0] = border[i - 2]; } else continue; - - var seg_right = [border[i], border[i]]; - if (i < border.length - 1) { seg_right[1] = border[i + 1]; } else continue; - - var n = seg[1] - seg[0]; - var n_left = seg_left[1] - seg_left[0]; - var n_right = seg_right[1] - seg_right[0]; - if (n <= 1) continue; - var seg_array = new DataStat(levels.slice(seg[0], seg[1])); - - if (n_right <= 15 || n_left <= 15 || n <= 15) { - var ns = 1.8 * Math.sqrt(levels[seg_left[0]] / this.mean) * this.std; - if (Math.abs(levels[seg_left[0]] - levels[seg[0]]) < ns) { continue } - - ns = 1.8 * Math.sqrt(levels[seg_right[0]] / this.mean) * this.std; - if (Math.abs(levels[seg_right[0]] - levels[seg[0]]) < ns) { continue } - } else { - var seg_left_array = levels.slice(seg_left[0], seg_left[1]); - var seg_left_1 = new DataStat(seg_left_array); - - var seg_right_array = levels.slice(seg_right[0], seg_right[1]); - var seg_right_1 = new DataStat(seg_right_array); - - var ttest_2sample_1 = t_test_2_samples(seg_array.mean, seg_array.std, seg_array.data.length, - seg_left_1.mean, seg_left_1.std, seg_left_1.data.length); - if (ttest_2sample_1 > (0.01 / genome_size) * bin_size * (n + n_left)) { continue } - - var ttest_2sample_2 = t_test_2_samples(seg_array.mean, seg_array.std, seg_array.data.length, - seg_right_1.mean, seg_right_1.std, seg_right_1.data.length); - if (ttest_2sample_2 > (0.01 / genome_size) * bin_size * (n + n_right)) { continue } - } - - var ttest_1sample_1 = t_test_1_sample(this.mean, seg_array.mean, seg_array.std, seg_array.data.length); - if (ttest_1sample_1 > 0.05) { continue } - let segments_rd = nm_levels.slice(seg[0], seg[1]); - var raw_seg_data = new DataStat(segments_rd); - - masked.fill(true, seg[0], seg[1]); - levels.fill(raw_seg_data.mean, seg[0], seg[1]); - } - }); - - ChrLevels[chr] = levels; - - }); - return ChrLevels - } - call_mean_shift(repeats = 3) { - const bin_size = 1000; - // const genome_size = bin_size * this.rd.length; - const genome_size = 2871000000; - var masked = new Array(this.rd.length).fill(false); - - // set the level - var levels = new Array(this.rd.length); - for (var b = 0; b < this.rd.length; b++) { - if (!masked[b]) { - levels[b] = this.rd[b]; - } - } - this.bin_bands.forEach((bin_band, bin_band_index) => { - // not masked levels at current bin - // get boolean values - var not_masked = masked.map((value, index) => { - return !value; - }); - - // not masked level at current bin - // var nm_levels = not_masked.map((value, index) => {if(value) return this.rd[index]}); - var nm_levels = []; - not_masked.forEach((value, index) => { - if (value) nm_levels.push(this.rd[index]); - }); - - // console.log(bin_band, nm_levels); - - // set the mask border - var mask_borders = [0]; - var count = 0; - - for (var i = 0; i < masked.length; i++) { - if (masked[i]) { - if (count > 0) { - mask_borders.push( - mask_borders[mask_borders.length - 1] + count - 1, - ); - count = 0; - } - } else { - count += 1; - } - } - - mask_borders.shift(); - // repeating steps - for (var step = 0; step < repeats; step++) { - var isig = this.get_rd_signal_bandwidth(nm_levels); - // console.log(isig); - var grad = new Array(nm_levels.length).fill(0); - - for (var i = 0; i < nm_levels.length; i++) { - for (var j = i - 3 * bin_band; j <= i + 3 * bin_band + 1; j++) { - if (j < 0 || j >= nm_levels.length) continue; - if (Math.abs(i - j) >= nm_levels.length) continue; - - var g_value = - (j - i) * - Math.exp((-0.5 * (j - i) ** 2) / bin_band ** 2) * - Math.exp(-0.5 * (nm_levels[i] - nm_levels[j]) ** 2 * isig[i]); - // console.log(g_value); - grad[i] += g_value; - } - } - // console.log(grad); - - // get the border - var border = new Array(); - for (var i = 0; i < grad.length - 1; i++) { - if ((grad[i] < 0) & (grad[i + 1] >= 0)) border.push(i); - } - - border.push(grad.length - 1); - border = border.concat(mask_borders).sort((a, b) => a - b); - border = Array.from(new Set(border)); - - var pb = 0; - for (var i = 0; i < border.length; i++) { - var range_array = nm_levels.slice(pb, border[i] + 1); - var range_mean = - range_array.reduce((acc, n) => acc + n) / range_array.length; - - nm_levels.fill(range_mean, pb, border[i] + 1); - pb = border[i] + 1; - } - } - - for (var i = 0, j = 0; i < levels.length; i++) { - if (not_masked[i]) { - levels[i] = nm_levels[j]; - j++; - } - } - - //get the border - var border = new Array(); - for (var i = 0; i < levels.length - 1; i++) { - //if(i == levels.length -1) continue; - var diff = Math.abs(levels[i + 1] - levels[i]); - - if (diff > 0.01) border.push(i + 1); - } - - border.unshift(0); - border.push(levels.length); - - // reset the mask - masked = new Array(this.rd.length).fill(false); - - // check the borders - for (var i = 1; i < border.length; i++) { - var seg = [border[i - 1], border[i]]; - var seg_left = [border[i - 1], border[i - 1]]; - if (i > 1) { - seg_left[0] = border[i - 2]; - } else continue; - - var seg_right = [border[i], border[i]]; - if (i < border.length - 1) { - seg_right[1] = border[i + 1]; - } else continue; - - var n = seg[1] - seg[0]; - var n_left = seg_left[1] - seg_left[0]; - var n_right = seg_right[1] - seg_right[0]; - if (n <= 1) continue; - var seg_array = new DataStat(levels.slice(seg[0], seg[1])); - - if (n_right <= 15 || n_left <= 15 || n <= 15) { - var ns = 1.8 * Math.sqrt(levels[seg_left[0]] / this.mean) * this.std; - if (Math.abs(levels[seg_left[0]] - levels[seg[0]]) < ns) { - continue; - } - - ns = 1.8 * Math.sqrt(levels[seg_right[0]] / this.mean) * this.std; - if (Math.abs(levels[seg_right[0]] - levels[seg[0]]) < ns) { - continue; - } - } else { - var seg_left_array = levels.slice(seg_left[0], seg_left[1]); - var seg_left_1 = new DataStat(seg_left_array); - - var seg_right_array = levels.slice(seg_right[0], seg_right[1]); - var seg_right_1 = new DataStat(seg_right_array); - - var ttest_2sample_1 = t_test_2_samples( - seg_array.mean, - seg_array.std, - seg_array.data.length, - seg_left_1.mean, - seg_left_1.std, - seg_left_1.data.length, - ); - if ( - ttest_2sample_1 > - (0.01 / genome_size) * bin_size * (n + n_left) - ) { - continue; - } - - var ttest_2sample_2 = t_test_2_samples( - seg_array.mean, - seg_array.std, - seg_array.data.length, - seg_right_1.mean, - seg_right_1.std, - seg_right_1.data.length, - ); - if ( - ttest_2sample_2 > - (0.01 / genome_size) * bin_size * (n + n_right) - ) { - continue; - } - } - - var ttest_1sample_1 = t_test_1_sample( - this.mean, - seg_array.mean, - seg_array.std, - seg_array.data.length, - ); - if (ttest_1sample_1 > 0.05) { - continue; - } - var raw_seg_data = new DataStat(this.rd.slice(seg[0], seg[1])); - - masked.fill(true, seg[0], seg[1]); - levels.fill(raw_seg_data.mean, seg[0], seg[1]); - } - }); - return levels; - } - - cnv_calling(bin_size = 100000) { - var delta = 0.25; - var delta = delta * this.mean; - - var min = this.mean - delta, max = this.mean + delta; - // console.log('min: ', min, ', Max: ', max) - - // console.log('delta', delta) - var normal_genome_size = 2971000000; - - var levels = this.meanShiftCaller(); - - - var merged_level = {}; - var cnv_levels = []; - // var t_value = cdf(Math.abs(10), (5)) - // console.log('Testing student t test:', t_value) - - Object.entries(levels).forEach(([chr, chr_levels]) => { - - var done = false; - while (!done) { - done = true; - - // - // get the borders - // - var borders = new Array(1).fill(0); - for (let i = 0; i < chr_levels.length - 1; i++) { - var diff = Math.abs(chr_levels[i + 1] - chr_levels[i]); - if (diff > 0.01) borders.push(i + 1); - } - borders.push(chr_levels.length); - - for (let ix = 0; ix < borders.length - 2; ix++) { - var v1 = Math.abs(chr_levels[borders[ix]] - chr_levels[borders[ix + 1]]); - // console.log(ix, v1); - if (v1 < delta) { - var v2 = v1 + 1, v3 = v1 + 1; - - if (ix > 0) { v2 = Math.abs(chr_levels[borders[ix]] - chr_levels[borders[ix - 1]]); } - if (ix < borders.length - 3) { v3 = Math.abs(levels[borders[ix + 1]] - chr_levels[borders[ix + 2]]); } - - if (v1 < v2 && v1 < v3) { - done = false; - - var tmp_array = new DataStat(chr_levels.slice(borders[ix], borders[ix + 2])); - chr_levels.fill(tmp_array.mean, borders[ix], borders[ix + 2]); - borders.splice(ix + 1, ix + 1); - } - } - } - } - // console.log('updated levels', chr_levels) - - // var chr_rd = this.rd[chr] - var chr_rd = []; - Object.entries(this.rd[chr]).forEach(([bin, binDict]) => { chr_rd.push(binDict.binScore); }); - // console.log('cnv_calling', chr_rd) - - // - // Calling Segments - // - - //var flags = [""] * levels.length; - var flags = new Array(chr_levels.length).fill(""); - - // console.log('default levels', chr, chr_levels) - var b = 0; - var pval = (0.05 * bin_size) / normal_genome_size; - while (b < chr_levels.length) { - var b0 = b, border_start = b; - while ((b < chr_levels.length) & (chr_levels[b] < min)) { - b += 1; - } - var border_end = b; - - if (border_end > border_start + 1) { - // console.log('border min', border_start, border_end) - var adj = adjustToEvalue(this.mean, this.std, chr_rd, border_start, border_end, pval); - // console.log(adj) - if (adj) { - var border_start, border_end = adj; - flags.fill("D", border_start, border_end); - } - } - border_start = b; - while ((b < chr_levels.length) & (chr_levels[b] > max)) { b += 1; } - border_end = b; - - if (border_end > border_start + 1) { - adj = adjustToEvalue(this.mean, this.std, chr_rd, border_start, border_end, pval); - // console.log(adj) - if (adj) { - (border_end = adj); - // flags[bs:be] = ["A"] * (be - bs) - flags.fill("A", border_start, border_end); - } - } - if (b == b0) b += 1; - } - - //console.log(chr, 'segments', segments) - // - // Calling additional deletions - // - b = 0; - while (b < chr_levels.length) { - while ((b < chr_levels.length) & (flags[b] != "")) b += 1; - border_start = b; - while ((b < chr_levels.length) & (chr_levels[b] < min)) b += 1; - border_end = b; - if (border_end > border_start + 1) { - if (gaussianEValue(this.mean, this.std, chr_rd, border_start, border_end) < 0.05 / normal_genome_size) { - flags.fill(["d"] * (border_end - border_start), border_start, border_end); - } - b -= 1; - } - b += 1; - } - - b = 0; - var cf; - if (b < chr_levels.length) cf = flags[b]; - - border_start = 0; - - //var merge = [...this.rd] - var merge = [...chr_rd]; - // console.log('initial merge', merge) - while (b < chr_levels.length) { - while (flags[b] == cf) { - b += 1; - if (b >= flags.length) break; - } - if (b > border_start) { - var merge_arr = new DataStat(merge.slice(border_start, b)); - merge.fill(merge_arr.mean, border_start, b); - } - if (b < chr_levels.length) cf = flags[b]; - border_start = b; - } - - merged_level[chr] = merge; - - - // - // calculate calls - // - b = 0; - while (b < chr_levels.length) { - cf = flags[b]; - if (cf == "") { - b += 1; - continue - } - border_start = b; - while (b < chr_levels.length & cf == flags[b]) { b += 1; } - var border_arr = new DataStat(merge.slice(border_start, b)); - let cnv = border_arr.mean / this.mean; - let event_type; - if (cf == "D") { - event_type = "deletion"; - } else { - event_type = "duplication"; - } - let cnv_dict = { - chr: chr, - start: bin_size * border_start + 1, - end: bin_size * b, - size: bin_size * (b - border_start + 1), - value: cnv * 2, - event_type: event_type - }; - cnv_levels.push(cnv_dict); - - } - }); - - return [merged_level, cnv_levels] - } - } - - - - var read_depth_caller = { Partition }; - - class CNVpytorVCF { - constructor(allVariants, binSize) { - this.allVariants = allVariants; - this.rowBinSize = 10000; - this.binSize = binSize; - this.binFactor = binSize / this.rowBinSize; - - } - - async computeDepthFeatures() { - - const chromosomes = Object.keys(this.allVariants); - const wigFeatures = []; - - for (let chr of chromosomes) { - const variants = this.allVariants[chr]; - if (variants.length === 0) continue - - const firstSnp = variants[0]; - - let sum = 0; - let count = 0; - let binStart = firstSnp.start = firstSnp.start % this.binSize; // Place start at integer multiple of binSize - let binEnd = binStart + this.binSize; - let featureBin = 0; - - for (let snp of variants) { - const position = snp.start + 1; // Convert from 0-base to 1-base coords - featureBin = Math.max(Math.floor((snp.start - 1) / this.binSize), 0); - if (position > binEnd) { - - if (count > 0) { - wigFeatures.push({ chr, start: binStart, end: binEnd, value: sum, bin: featureBin, count: count }); - } - - // Start new bin - sum = 0; - //count = 0 - binStart = snp.start - snp.start % this.binSize; - binEnd = binStart + this.binSize; - } - - const dpValue = snp.calls[9].info["DP"]; - // const dpValue = snp.getInfo("DP") - - if (dpValue) { - sum += Number.parseInt(dpValue); - count++; - } - } - - // final bin - if (count > 0) { - wigFeatures.push({ chr, start: binStart, end: binEnd, value: sum, bin: featureBin, count: count }); - } - } - - return wigFeatures - } - - // for for read depth calculation - async computeReadDepth() { - const chromosomes = Object.keys(this.allVariants); - var wigFeatures = {}; - - for (let chr of chromosomes) { - const variants = this.allVariants[chr]; - var featureBin; - if (variants.length === 0) continue - for (let snp of variants) { - featureBin = Math.max(Math.floor(snp.start / this.rowBinSize), 0); - if (!wigFeatures[chr]) { wigFeatures[chr] = []; } - if (!wigFeatures[chr][featureBin]) { - - wigFeatures[chr][featureBin] = { - chr, - start: featureBin * this.rowBinSize, - end: (featureBin + 1) * this.rowBinSize, - value: 0, - sum_score: 0, - count: 0, - }; - } - const dpValue = snp.calls[9].info["DP"]; - if (dpValue) { - // sum += Number.parseInt(dpValue) - wigFeatures[chr][featureBin].sum_score += Number.parseInt(dpValue); - wigFeatures[chr][featureBin].count++; - } - - } - // for last bin - //let last_bin = wigFeatures[chr][featureBin] - //last_bin.value = parseInt(last_bin.sum_score / last_bin.count) * 100 - } - - // adjust the bin values to actual bin size - var avgbin = {}; - for (let chr of chromosomes) { - if (!avgbin[chr]) { avgbin[chr] = []; } - for (let k = 0; k < wigFeatures[chr].length / this.binFactor; k++) { - const featureBin = k; - if (!avgbin[chr][k]) { - avgbin[chr][k] = { - chr, - binScore: 0, - start: featureBin * this.binSize, - end: (featureBin + 1) * this.binSize, - }; - } - - for (var j = k * 10; j < 10 * k + 10; j++) { - if (wigFeatures[chr][j]) { - var tmp_score = parseInt(wigFeatures[chr][j].sum_score / wigFeatures[chr][j].count) * 100; - avgbin[chr][k].binScore += tmp_score; - } - } - } - } - - var finalFeatureSet = this.readDepthMeanshift(avgbin); - return finalFeatureSet - - } - readDepthMeanshift(wigFeatures) { - - // Get global mean and standrad deviation - var fit_info = new g_utils.GetFit(wigFeatures); - var [globamMean, globalStd] = fit_info.fit_data(); - - // Apply partition method - var partition = new read_depth_caller.Partition(wigFeatures, globamMean, globalStd); - var partition_array = partition.meanShiftCaller(); - var caller_array = partition.cnv_calling(); - - // Assign the partition values to each bin - Object.entries(wigFeatures).forEach(([chr, chr_rd]) => { - chr_rd.forEach((bin, index) => { - bin.partition_level = parseInt(partition_array[chr][index]); - bin.partition_call = parseInt(caller_array[0][chr][index]); - }); - }); - - var rawbinScore = this.formatDataStructure(wigFeatures, 'binScore', globamMean); - var partition_levels = this.formatDataStructure(wigFeatures, 'partition_level', globamMean); - var partition_call = this.formatDataStructure(wigFeatures, 'partition_call', globamMean); - - return [rawbinScore, partition_levels, partition_call, caller_array[1]] - - } - formatDataStructure(wigFeatures, feature_column, scaling_factor = 1) { - const results = []; - for (const [chr, wig] of Object.entries(wigFeatures)) { - - wig.forEach(sample => { - var new_sample = { ...sample }; - if (scaling_factor != 1) { - new_sample.value = sample[feature_column] / scaling_factor * 2; - } - results.push(new_sample); - }); - } - - return results - } - - async computeBAF_v2() { - - const chromosomes = Object.keys(this.allVariants); - const wigFeatures = {}; - const baf1 = [], baf2 = []; - - for (let chr of chromosomes) { - const variants = this.allVariants[chr]; - if (variants.length === 0) continue - var featureBin; - for (let snp of variants) { - featureBin = Math.max(Math.floor(snp.start / this.binSize), 0); - - if (!wigFeatures[chr]) { - wigFeatures[chr] = []; - } - if (!wigFeatures[chr][featureBin]) { - if (featureBin > 0) { - // calculating the BAF likelihood for previous bin - let previous_featureBin = featureBin - 1; - if (wigFeatures[chr][previous_featureBin]) { - - const updated_bin = this.get_max_min_score(wigFeatures[chr][previous_featureBin]); - - if (updated_bin.value != 0.5) { - let baf_wig = Object.assign({}, updated_bin); - baf_wig.value = -2 * (1 - updated_bin.value); - baf2.push(baf_wig); - } - updated_bin.value = - 2 * updated_bin.value; - wigFeatures[chr][previous_featureBin] = updated_bin; - - baf1.push(wigFeatures[chr][previous_featureBin]); - - } - } - wigFeatures[chr][featureBin] = { - chr, - start: featureBin * this.binSize, - end: (featureBin + 1) * this.binSize, - value: 0, - count: 0, - likelihood_score: [], - min_score: 0, - }; - } - const calls = snp.calls[9]; - let genotype = calls.genotype; - let ad_score = calls.info["AD"].split(','); - let ad_a = ad_score[0], ad_b = ad_score[1]; - - if ((genotype[0] == 0 && genotype[1] == 1) || (genotype[0] == 1 && genotype[1] == 0)) { - //apply the beta function - if (wigFeatures[chr][featureBin].likelihood_score.length == 0) { - wigFeatures[chr][featureBin].likelihood_score = g_utils.linspace(0, 1, 100).map((value, index) => { - return beta(ad_a, ad_b, value); - }); - } else { - var sum = 0; - - wigFeatures[chr][featureBin].likelihood_score = g_utils.linspace(0, 1, 100).map((value, index) => { - var likelihood_value = wigFeatures[chr][featureBin].likelihood_score[index] * beta(ad_a, ad_b, value); - sum = sum + likelihood_value; - return likelihood_value; - }); - - wigFeatures[chr][featureBin].likelihood_score = g_utils.linspace(0, 1, 100).map((value, index) => { - return wigFeatures[chr][featureBin].likelihood_score[index] / sum; - }); - } - wigFeatures[chr][featureBin].count++; - } - } - - // last feature bin - const updated_bin = this.get_max_min_score(wigFeatures[chr][featureBin]); - - if (updated_bin.value != 0.5) { - let baf_wig = Object.assign({}, updated_bin); - baf_wig.value = -2 * (1 - updated_bin.value); - baf2.push(baf_wig); - } - updated_bin.value = -2 * updated_bin.value; - wigFeatures[chr][featureBin] = updated_bin; - baf1.push(wigFeatures[chr][featureBin]); - } - - return [baf1, baf2] - - } - - - format_BAF_likelihood(wigFeatures) { - const results = []; - - for (const [chr, wig] of Object.entries(wigFeatures)) { - wig.forEach(sample => { - var new_sample = { ...sample }; - if (sample.value != 0.5) { - new_sample.value = 1 - sample.value; - results.push(new_sample); - } - }); - } - return results - } - - get_max_min_score(sample) { - - if (sample.likelihood_score.length > 0) { - const max = Math.max(...sample.likelihood_score); - const res = sample.likelihood_score.indexOf(max); - sample.value = Math.max(res / 100, 1 - res / 100); - sample.min_score = Math.min(res / 100, 1 - res / 100); - - } else { - sample.score = 0; - } - - return sample - } - - async getAllbins() { - const bins = await this.computeDepthFeatures(); - - //console.log('getAllbins', bins["value"]) - - const fitter = new g_utils.GetFit(bins); - - fitter.fit_data(); - // dconsole.log('rd list', distParams) - - return bins - } - - async read_rd_baf(caller='ReadDepth'){ - - const chromosomes = Object.keys(this.allVariants); - var wigFeatures = {}; - - for (let chr of chromosomes) { - const variants = this.allVariants[chr]; - var featureBin; - if (variants.length === 0) continue - for (let snp of variants) { - featureBin = Math.max(Math.floor(snp.start / this.rowBinSize), 0); - if (!wigFeatures[chr]) { wigFeatures[chr] = []; } - if (!wigFeatures[chr][featureBin]) { - - wigFeatures[chr][featureBin] = { - chr, - start: featureBin * this.rowBinSize, - end: (featureBin + 1) * this.rowBinSize, - // value: 0, - dp_sum_score: 0, - dp_count: 0, - hets_count:0, - hets: [], - //likelihood_score: [], - }; - } - const calls = snp.calls[9]; - const dpValue = calls.info["DP"]; - if (dpValue) { - - wigFeatures[chr][featureBin].dp_sum_score += Number.parseInt(dpValue); - wigFeatures[chr][featureBin].dp_count++; - } - - let ad_score = calls.info["AD"].split(','); - let genotype = calls.genotype; - if ((genotype[0] == 0 && genotype[1] == 1) || (genotype[0] == 1 && genotype[1] == 0)) { - //apply the beta function - wigFeatures[chr][featureBin].hets_count++; - let ad_a = parseInt(ad_score[0]), ad_b = parseInt(ad_score[1]); - wigFeatures[chr][featureBin].hets.push({ref:ad_a, alt:ad_b}); - } - - } - - } - - var avgbin = this.adjust_bin_size(wigFeatures); - var finalFeatureSet; - if(caller == 'ReadDepth'){ - finalFeatureSet = this.readDepthMeanshift(avgbin); - var baf = this.formatDataStructure_BAF(avgbin, 'max_likelihood'); - }else if(caller=='2D'){ - - let caller_obj = new combined_caller.CombinedCaller(avgbin, this.binSize); - let processed_bins = await caller_obj.call_2d(); - - finalFeatureSet = [processed_bins.binScore, [], processed_bins.segment_score]; - - var baf = caller_obj.formatDataStructure_BAF('max_likelihood'); - } - - - return [finalFeatureSet, baf] - } - - formatDataStructure_BAF(wigFeatures, feature_column, scaling_factor = 2) { - const baf1 = []; - const baf2 = []; - for (const [chr, wig] of Object.entries(wigFeatures)) { - - wig.forEach(sample => { - delete sample.likelihood_score; - var baf1_value = { ...sample }; - var baf2_value = { ...sample }; - - let value = sample[feature_column]; - if (value != 0.5){ - baf2_value.value = -2 * (1 - value); - baf2.push(baf2_value); - } - baf1_value.value = -2 * value; - baf1.push(baf1_value); - - }); - } - - - return [baf1, baf2] - } - - adjust_bin_size(wigFeatures){ - const chromosomes = Object.keys(this.allVariants); - // adjust the bin values to actual bin size - var avgbin = {}; - for (let chr of chromosomes) { - if (!avgbin[chr]) { avgbin[chr] = []; } - for (let k = 0; k < wigFeatures[chr].length / this.binFactor; k++) { - const featureBin = k; - if (!avgbin[chr][k]) { - avgbin[chr][k] = { - chr, - start: featureBin * this.binSize, - end: (featureBin + 1) * this.binSize, - dp_count: 0, - hets_count: 0, - binScore: 0, - likelihood_score: [], - }; - } - - for (var j = k * 10; j < 10 * k + 10; j++) { - - if (wigFeatures[chr][j]) { - var tmp_score = parseInt(wigFeatures[chr][j].dp_sum_score / wigFeatures[chr][j].dp_count) * 100; - avgbin[chr][k].binScore += tmp_score; - avgbin[chr][k].dp_count += wigFeatures[chr][j].dp_count; - avgbin[chr][k].hets_count += wigFeatures[chr][j].hets_count; - - if (wigFeatures[chr][j].hets.length != 0){ - - - wigFeatures[chr][j].hets.forEach((hets, hets_idx) => { - if(avgbin[chr][k].likelihood_score.length == 0){ - avgbin[chr][k].likelihood_score = g_utils.linspace(0, 1, 100).map((value, index) => { - return beta(hets.ref, hets.alt, value); - }); - } - else { - var likelihood_sum = 0; - avgbin[chr][k].likelihood_score = g_utils.linspace(0, 1, 100).map((value, index) => { - var likelihood_value = avgbin[chr][k].likelihood_score[index] * beta(hets.ref, hets.alt, value); - likelihood_sum += likelihood_value; - return likelihood_value; - }); - - avgbin[chr][k].likelihood_score = g_utils.linspace(0, 1, 100).map((value, index) => { - return avgbin[chr][k].likelihood_score[index] / likelihood_sum; - }); - - } - }); - - // avgbin[chr][k].likelihood_score *= wigFeatures[chr][j].likelihood_score - } - } - } - - const updated_bin = this.get_max_min_score(avgbin[chr][k]); - avgbin[chr][k].max_likelihood = updated_bin.value; - } - } - return avgbin - } - - } - - function beta(a, b, p, phased = true) { - return p ** a * (1 - p) ** b + p ** b * (1 - p) ** a; - } - - /* - * The MIT License (MIT) - * - * Copyright (c) 2016-2017 The Regents of the University of California - * Author: Arijit Panda - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - - /** - * Represents 2 or more wig tracks overlaid on a common viewport. - */ - - const DEFAULT_TRACK_HEIGHT = 250; - - class CNVPytorTrack extends TrackBase { - - constructor(config, browser) { - super(config, browser); - this.featureType = 'numeric'; - this.paintAxis = paintAxis; - - if (!config.max) { - this.defaultScale = true; - this.autoscale = false; - } - - // Invoke height setter last to allocated to coverage and alignment tracks - this.height = (config.height !== undefined ? config.height : DEFAULT_TRACK_HEIGHT); - } - - async init(config) { - - this.type = "cnvpytor"; - this.graphType = config.graphType || "points"; - this.bin_size = config.bin_size || 100000; - this.signal_name = config.signal_name || "rd_snp"; - this.cnv_caller = config.cnv_caller || '2D'; - this.colors = config.colors || ['gray', 'black', 'green', 'blue']; - super.init(config); - - } - - get supportsWholeGenome() { - return true - } - - get_signals() { - let signals = []; - - if (this.signal_name == 'rd_snp') { - signals = ["RD_Raw", "RD_Raw_gc_coor", this.cnv_caller, "BAF1", "BAF2"]; - - } else if (this.signal_name == 'rd') { - signals = ["RD_Raw", "RD_Raw_gc_coor", this.cnv_caller]; - - } else if (this.signal_name == 'snp') { - signals = ["BAF1", "BAF2"]; - - } else if (this.signal_name == 'cnh') { - signals = [this.cnv_caller]; - } - return signals - } - - get_signal_colors() { - - let signal_colors = [ - { singal_name: 'RD_Raw', color: this.colors[0] }, - { singal_name: 'RD_Raw_gc_coor', color: this.colors[1] }, - { singal_name: 'ReadDepth', color: this.colors[2] }, - { singal_name: '2D', color: this.colors[2] }, - { singal_name: 'BAF1', color: this.colors[3] }, - { singal_name: 'BAF2', color: this.colors[3] }, - ]; - return signal_colors - } - - async postInit() { - - if (this.config.format == 'vcf') { - this.featureSource = FeatureSource(this.config, this.browser.genome); - this.header = await this.getHeader(); - - - var allVariants = this.featureSource.reader.features.reduce(function (r, a) { - r[a.chr] = r[a.chr] || []; - r[a.chr].push(a); - return r - }, Object.create(null)); - - const cnvpytor_obj = new CNVpytorVCF(allVariants, this.bin_size); - - let wigFeatures; - let bafFeatures; - this.wigFeatures_obj = {}; - this.wigFeatures_obj[this.bin_size] = {}; - - let dataWigs; - if(this.config.cnv_caller == '2D'){ - - dataWigs = await cnvpytor_obj.read_rd_baf('2D'); - - wigFeatures = dataWigs[0]; - bafFeatures = dataWigs[1]; - this.wigFeatures_obj[this.bin_size]['2D'] = wigFeatures[2]; - - this.available_callers = ['2D']; - }else { - dataWigs = await cnvpytor_obj.read_rd_baf(); - wigFeatures = dataWigs[0]; - bafFeatures = dataWigs[1]; - this.wigFeatures_obj[this.bin_size]['ReadDepth'] = wigFeatures[2]; - this.available_callers = ['ReadDepth']; - } - - this.wigFeatures_obj[this.bin_size]['RD_Raw'] = wigFeatures[0]; - this.wigFeatures_obj[this.bin_size]['RD_Raw_gc_coor'] = wigFeatures[1]; - this.wigFeatures_obj[this.bin_size]['BAF1'] = bafFeatures[0]; - this.wigFeatures_obj[this.bin_size]['BAF2'] = bafFeatures[1]; - - this.available_bins = [this.bin_size]; - - this.set_available_callers(); - - } else { - this.cnvpytor_obj = new HDF5Reader(this.config.url, this.bin_size); - this.wigFeatures_obj = await this.cnvpytor_obj.get_rd_signal(this.bin_size); - this.available_bins = this.cnvpytor_obj.available_bins; - this.available_callers = this.cnvpytor_obj.callers; - this.set_available_callers(); - } - - this.tracks = []; - const p = []; - - this.signals = this.get_signals(); - this.signal_colors = this.get_signal_colors(); - - for (let bin_size in this.wigFeatures_obj) { - - for (const [signal_name, wig] of Object.entries(this.wigFeatures_obj[bin_size])) { - - if (this.signals.includes(signal_name)) { - let tconf = {}; - tconf.type = "wig"; - tconf.isMergedTrack = true; - tconf.features = wig; - tconf.name = signal_name; - tconf.color = this.signal_colors.filter(x => x.singal_name === signal_name).map(x => x.color); - const t = await this.browser.createTrack(tconf); - if (t) { - t.autoscale = false; // Scaling done from merged track - this.tracks.push(t); - } else { - console.warn("Could not create track " + tconf); - } - - if (typeof t.postInit === 'function') { - p.push(t.postInit()); - } - } - } - - } - - - this.flipAxis = this.config.flipAxis ? this.config.flipAxis : false; - this.logScale = this.config.logScale ? this.config.logScale : false; - this.autoscale = this.config.autoscale; - if (!this.autoscale) { - this.dataRange = { - min: this.config.min || 0, - max: this.config.max - }; - } - for (let t of this.tracks) { - t.autoscale = false; - t.dataRange = this.dataRange; - } - - return Promise.all(p) - } - - set_available_callers() { - if (!this.available_callers.includes(this.cnv_caller)) { - if (this.available_callers.length > 0) { - this.cnv_caller = this.available_callers[0]; - } else { - this.cnv_caller = null; - } - } - } - - async getHeader() { - - if (!this.header) { - if (typeof this.featureSource.getHeader === "function") { - const header = await this.featureSource.getHeader(); - if (header) { - this.callSets = header.callSets || []; - } - this.header = header; - } - this.sampleNames = this.callSets ? this.callSets.map(cs => cs.name) : []; - } - - return this.header - } - - get height() { - return this._height - } - - set height(h) { - this._height = h; - if (this.tracks) { - for (let t of this.tracks) { - t.height = h; - t.config.height = h; - } - } - } - - menuItemList() { - let items = []; - - if (this.flipAxis !== undefined) { - items.push({ - label: "Flip y-axis", - click: () => { - this.flipAxis = !this.flipAxis; - this.trackView.repaintViews(); - } - }); - } - - items = items.concat(MenuUtils$1.numericDataMenuItems(this.trackView)); - - items.push('
'); - items.push("Bin Sizes"); - for (let rd_bin of this.available_bins) { - const checkBox = createCheckbox$2(rd_bin, rd_bin === this.bin_size); - items.push({ - object: $$1(checkBox), - click: async () => { - this.bin_size = rd_bin; - - await this.recreate_tracks(rd_bin); - this.clearCachedFeatures(); - this.trackView.updateViews(); - this.trackView.repaintViews(); - } - }); - } - items.push('
'); - items.push("Signal Type"); - - let signal_dct = {"rd_snp": "RD and BAF Likelihood", "rd": "RD Signal", "snp": "BAF Likelihood"}; - for (let signal_name in signal_dct) { - const checkBox = createCheckbox$2(signal_dct[signal_name], signal_name === this.signal_name); - items.push({ - object: $$1(checkBox), - click: async () => { - this.signal_name = signal_name; - await this.recreate_tracks(this.bin_size); - this.clearCachedFeatures(); - this.trackView.updateViews(); - this.trackView.repaintViews(); - - } - }); - } - - // cnv caller setting - items.push('
'); - items.push("CNV caller"); - for (let cnv_caller of this.available_callers) { - const checkBox = createCheckbox$2(cnv_caller, cnv_caller === this.cnv_caller); - items.push({ - object: $$1(checkBox), - click: async () => { - this.cnv_caller = cnv_caller; - await this.recreate_tracks(this.bin_size); - this.clearCachedFeatures(); - this.trackView.updateViews(); - this.trackView.repaintViews(); - } - }); - } - - return items - } - - async recreate_tracks(bin_size) { - this.tracks = []; - const p = []; - - if (!(bin_size in this.wigFeatures_obj)) { - this.wigFeatures_obj = {...this.wigFeatures_obj, ...await this.cnvpytor_obj.get_rd_signal(bin_size)}; - } - - this.signals = this.get_signals(); - this.signal_colors = this.get_signal_colors(); - - for (const [signal_name, wig] of Object.entries(this.wigFeatures_obj[bin_size])) { - if (this.signals.includes(signal_name)) { - let tconf = {}; - tconf.type = "wig"; - tconf.isMergedTrack = true; - tconf.features = wig; - tconf.name = signal_name; - tconf.color = this.signal_colors.filter(x => x.singal_name === signal_name).map(x => x.color); - const t = await this.browser.createTrack(tconf); - if (t) { - t.autoscale = false; // Scaling done from merged track - this.tracks.push(t); - } else { - console.warn("Could not create track " + tconf); - } - - if (typeof t.postInit === 'function') { - p.push(t.postInit()); - } - } - - } - - - this.flipAxis = this.config.flipAxis ? this.config.flipAxis : false; - this.logScale = this.config.logScale ? this.config.logScale : false; - this.autoscale = this.config.autoscale; - if (!this.autoscale) { - this.dataRange = { - min: this.config.min || 0, - max: this.config.max - }; - } - for (let t of this.tracks) { - t.autoscale = false; - t.dataRange = this.dataRange; - } - return Promise.all(p) - } - - async getFeatures(chr, bpStart, bpEnd, bpPerPixel) { - - if(this.tracks) { - const promises = this.tracks.map((t) => t.getFeatures(chr, bpStart, bpEnd, bpPerPixel)); - return Promise.all(promises) - } else { - return undefined // This can happen if a redraw is triggered before the track has initialized. - } - } - - // TODO: refactor to igvUtils.js - getScaleFactor(min, max, height, logScale) { - const scale = logScale ? height / (Math.log10(max + 1) - (min <= 0 ? 0 : Math.log10(min + 1))) : height / (max - min); - return scale - } - - computeYPixelValue(yValue, yScaleFactor) { - return (this.flipAxis ? (yValue - this.dataRange.min) : (this.dataRange.max - yValue)) * yScaleFactor - } - - computeYPixelValueInLogScale(yValue, yScaleFactor) { - let maxValue = this.dataRange.max; - let minValue = this.dataRange.min; - if (maxValue <= 0) return 0 // TODO: - if (minValue <= -1) minValue = 0; - minValue = (minValue <= 0) ? 0 : Math.log10(minValue + 1); - maxValue = Math.log10(maxValue + 1); - yValue = Math.log10(yValue + 1); - return ((this.flipAxis ? (yValue - minValue) : (maxValue - yValue)) * yScaleFactor) - } - - draw(options) { - - // const mergedFeatures = options.features // Array of feature arrays, 1 for each track - const mergedFeatures = options.features; - if(!mergedFeatures) return - - if (this.defaultScale) { - if (this.signal_name == 'rd_snp') { - this.dataRange = { - min: this.config.min || this.dataRange.min || -2, - max: this.config.max || this.dataRange.max || 6 - }; - } else if (this.signal_name == 'rd') { - this.dataRange = { - min: this.config.min || this.dataRange.min || 0, - max: this.config.max || this.dataRange.max || 6 - }; - } else if (this.signal_name == 'snp') { - this.dataRange = { - min: this.config.min || this.dataRange.min || -2, - max: this.config.max || this.dataRange.max || 0 - }; - } - } - - if (this.autoscale) { - this.dataRange = autoscale(options.referenceFrame.chr, mergedFeatures); - } - - if(this.tracks) { - for (let i = 0, len = this.tracks.length; i < len; i++) { - const trackOptions = Object.assign({}, options); - trackOptions.features = mergedFeatures[i]; - this.tracks[i].dataRange = this.dataRange; - this.tracks[i].flipAxis = this.flipAxis; - this.tracks[i].logScale = this.logScale; - if (this.graphType) { - this.tracks[i].graphType = this.graphType; - } - this.tracks[i].draw(trackOptions); - } - } - - // guides lines - const scaleFactor = this.getScaleFactor(this.dataRange.min, this.dataRange.max, options.pixelHeight, this.logScale); - const yScale = (yValue) => this.logScale - ? this.computeYPixelValueInLogScale(yValue, scaleFactor) - : this.computeYPixelValue(yValue, scaleFactor); - - // Draw guidelines - if (this.config.hasOwnProperty('guideLines')) { - for (let line of this.config.guideLines) { - if (line.hasOwnProperty('color') && line.hasOwnProperty('y') && line.hasOwnProperty('dotted')) { - let y = yScale(line.y); - let props = { - 'strokeStyle': line['color'], - 'strokeWidth': 1 - }; - if (line['dotted']) IGVGraphics.dashedLine(options.context, 0, y, options.pixelWidth, y, 5, props); - else IGVGraphics.strokeLine(options.context, 0, y, options.pixelWidth, y, props); - } - } - } - } - - popupData(clickState, features) { - - const featuresArray = features || clickState.viewport.cachedFeatures; - - if (featuresArray && featuresArray.length === this.tracks.length) { - // Array of feature arrays, 1 for each track - const popupData = []; - for (let i = 0; i < this.tracks.length; i++) { - if (i > 0) popupData.push('
'); - popupData.push(`
${this.tracks[i].name}
`); - const trackPopupData = this.tracks[i].popupData(clickState, featuresArray[i]); - popupData.push(...trackPopupData); - - } - return popupData - } - } - - } - - function autoscale(chr, featureArrays) { - - let min = 0; - let max = -Number.MAX_VALUE; - for (let features of featureArrays) { - for (let f of features) { - if (typeof f.value !== 'undefined' && !Number.isNaN(f.value)) { - min = Math.min(min, f.value); - max = Math.max(max, f.value); - } - } - } - return {min: min, max: max} - } - - //import CNVPytorTrack from "./CNVpytor/cnvpytorTrack.js" - - - const trackFunctions = - new Map([ - ['ideogram', (config, browser) => new IdeogramTrack(config, browser)], - ['sequence', (config, browser) => new SequenceTrack(config, browser)], - ['feature', (config, browser) => new FeatureTrack(config, browser)], - ['seg', (config, browser) => new SegTrack(config, browser)], - ['mut', (config, browser) => new SegTrack(config, browser)], - ['maf', (config, browser) => new SegTrack(config, browser)], - ['wig', (config, browser) => new WigTrack(config, browser)], - ['merged', (config, browser) => new MergedTrack(config, browser)], - ['alignment', (config, browser) => new BAMTrack(config, browser)], - ['interaction', (config, browser) => new InteractionTrack(config, browser)], - ['interact', (config, browser) => new InteractionTrack(config, browser)], - ['variant', (config, browser) => new VariantTrack(config, browser)], - ['eqtl', (config, browser) => new EqtlTrack(config, browser)], - ['gwas', (config, browser) => new GWASTrack(config, browser)], - ['arc', (config, browser) => new RnaStructTrack(config, browser)], - ['gcnv', (config, browser) => new GCNVTrack(config, browser)], - ['junction', (config, browser) => new SpliceJunctionTrack(config, browser)], - ['blat', (config, browser) => new BlatTrack(config, browser)], - ['cnvpytor', (config, browser) => new CNVPytorTrack(config, browser)] - ]); - - - /** - * Add a track constructor the the factory lookup table. - * - * @param type - * @param track - */ - const addTrackCreatorFunction = function (type, track) { - trackFunctions.set(type, track); - }; - - const getTrack = function (type, config, browser) { - - let trackKey; - switch (type) { - case "annotation": - case "genes": - case "fusionjuncspan": - case "snp": - trackKey = "feature"; - break - case 'seg': - case 'maf': - case 'mut': - trackKey = 'seg'; - break - case 'junctions': - case 'splicejunctions': - trackKey = 'junction'; - break - default: - trackKey = type; - } - - return trackFunctions.has(trackKey) ? - trackFunctions.get(trackKey)(config, browser) : - undefined - }; - - var TrackFactory = { - tracks: trackFunctions, - addTrack: addTrackCreatorFunction, - trackFunctions, - addTrackCreatorFunction, - getTrack - }; - - /* - * The MIT License (MIT) - * - * Copyright (c) 2016-2017 The Regents of the University of California - * Author: Jim Robinson - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - - /** - * Minimal support for the legacy IGV desktop session format. - */ - - class XMLSession { - - constructor(xmlString, knownGenomes) { - - const parser = new DOMParser(); - const xmlDoc = parser.parseFromString(xmlString, "text/xml"); - - this.processRootNode(xmlDoc, knownGenomes); - - const resourceElements = xmlDoc.getElementsByTagName("Resource"); - const trackElements = xmlDoc.getElementsByTagName("Track"); - const hasTrackElements = trackElements && trackElements.length > 0; - - const tracks = []; - this.tracks = tracks; - - const resourceMap = new Map(); - Array.from(resourceElements).forEach(function (r, idx) { - var config = { - url: r.getAttribute("path"), - indexURL: r.getAttribute("index"), - order: idx - }; - resourceMap.set(config.url, config); - if (!hasTrackElements) { - tracks.push(config); - } - }); - - // Check for optional Track section - if (hasTrackElements) { - - Array.from(trackElements).forEach(function (track) { - - const subtracks = track.getElementsByTagName("Track"); - - if (subtracks && subtracks.length > 0) { - - const mergedTrack = { - type: 'merged', - tracks: [] - }; - extractTrackAttributes(track, mergedTrack); - - tracks.push(mergedTrack); - - Array.from(subtracks).forEach(function (t) { - t.processed = true; - const id = t.getAttribute("id"); - const config = resourceMap.get(id); - if (config) { - mergedTrack.tracks.push(config); - extractTrackAttributes(t, config); - config.autoscale = false; - mergedTrack.height = config.height; - - // Add alpha for merged track colors. Alpha is not recorded by IGV desktop in XML session - //const color = t.getAttribute("color"); - //if (color) { - // config.color = "rgba(" + color + ",0.5)"; - //} - } - }); - } else if (!track.processed) { - - const id = track.getAttribute("id"); - const res = resourceMap.get(id); - if (res) { - tracks.push(res); - extractTrackAttributes(track, res); - } - - } - }); - } - } - - processRootNode(xmlDoc, knownGenomes) { - - const elements = xmlDoc.getElementsByTagName("Session"); - if (!elements || elements.length === 0) ; - const session = elements.item(0); - const genome = session.getAttribute("genome"); - const locus = session.getAttribute("locus"); - const ucscID = session.getAttribute("ucscID"); - - if (knownGenomes && knownGenomes.hasOwnProperty(genome)) { - this.genome = genome; - - } else { - this.reference = { - fastaURL: genome - }; - if (ucscID) { - this.reference.id = ucscID; - } - } - if (locus) { - this.locus = locus; - } - } - - } - - - function extractTrackAttributes(track, config) { - - - config.name = track.getAttribute("name"); - - const color = track.getAttribute("color"); - if (color) { - config.color = "rgb(" + color + ")"; - } - - const altColor = track.getAttribute("altColor"); - if (color) { - config.altColor = "rgb(" + altColor + ")"; - } - - const height = track.getAttribute("height"); - if (height) { - config.height = parseInt(height); - } - - const autoScale = track.getAttribute("autoScale"); - if (autoScale) { - config.autoscale = (autoScale === "true"); - } - - const autoscaleGroup = track.getAttribute("autoscaleGroup"); - if (autoscaleGroup) { - config.autoscaleGroup = autoscaleGroup; - } - - const windowFunction = track.getAttribute("windowFunction"); - if (windowFunction) { - config.windowFunction = windowFunction; - } - const visWindow = track.getAttribute("visibilityWindow") || track.getAttribute("featureVisibilityWindow"); - if (visWindow) { - config.visibilityWindow = visWindow; - } - - const indexed = track.getAttribute("indexed"); - if (indexed) { - config.indexed = (indexed === "true"); - } - - const normalize = track.getAttribute("normalize"); - if (normalize) { - config.normalize = normalize === "true"; - } - - const dataRangeCltn = track.getElementsByTagName("DataRange"); - if (dataRangeCltn.length > 0) { - const dataRange = dataRangeCltn.item(0); - config.min = Number(dataRange.getAttribute("minimum")); - config.max = Number(dataRange.getAttribute("maximum")); - config.logScale = dataRange.getAttribute("type") === "LOG"; - } - } - - /* - * The MIT License (MIT) - * - * Copyright (c) 2014-2015 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - const splitLines = splitLines$5; - - class SampleInformation { - constructor() { - this.attributes = {}; - this.plinkLoaded = false; - } - - async loadPlinkFile(url, config) { - - if (!config) config = {}; - - var options = buildOptions$1(config); // Add oauth token, if any - const data = await igvxhr.loadString(url, options); - var lines = splitLines(data); - - for (let line of lines) { - var line_arr = line.split(' '); - this.attributes[line_arr[1]] = { - familyId: line_arr[0], - fatherId: line_arr[2], - motherId: line_arr[3], - sex: line_arr[4], - phenotype: line_arr[5] - }; - } - this.plinkLoaded = true; - return this - } - - /** - * Return the attributes for the given sample as a map-like object (key-value pairs) - * @param sample - */ - getAttributes(sample) { - return this.attributes[sample] - }; - - getAttributeNames() { - - if (this.hasAttributes()) { - return Object.keys(this.attributes[Object.keys(this.attributes)[0]]) - } else return [] - }; - - hasAttributes() { - return Object.keys(this.attributes).length > 0 - } - } - - function loadPlinkFile(url, config) { - const si = new SampleInformation(); - return si.loadPlinkFile(url, config) - } - - /* - * The MIT License (MIT) - * - * Copyright (c) 2014 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - class GtexSelection { - - constructor(gene, snp) { - this.geneColors = {}; - this.gene = null; - this.snp = null; - this.genesCount = 0; - - if (gene) { - this.gene = gene.toUpperCase(); - this.geneColors[this.gene] = brewer[this.genesCount++]; - - } - if (snp) { - this.snp = snp.toUpperCase(); - } - } - - addGene(geneName) { - if (!this.geneColors[geneName.toUpperCase()]) { - this.geneColors[geneName.toUpperCase()] = brewer[this.genesCount++]; - } - } - - colorForGene(geneName) { - return this.geneColors[geneName.toUpperCase()] - } - } - - var brewer = []; - // Set +! - brewer.push("rgb(228,26,28)"); - brewer.push("rgb(55,126,184)"); - brewer.push("rgb(77,175,74)"); - brewer.push("rgb(166,86,40)"); - brewer.push("rgb(152,78,163)"); - brewer.push("rgb(255,127,0)"); - brewer.push("rgb(247,129,191)"); - brewer.push("rgb(153,153,153)"); - brewer.push("rgb(255,255,51)"); - - // #Set 2 - brewer.push("rgb(102, 194, 165"); - brewer.push("rgb(252, 141, 98"); - brewer.push("rgb(141, 160, 203"); - brewer.push("rgb(231, 138, 195"); - brewer.push("rgb(166, 216, 84"); - brewer.push("rgb(255, 217, 47"); - brewer.push("rgb(229, 196, 148"); - brewer.push("rgb(179, 179, 179"); - - //#Set 3 - brewer.push("rgb( 141, 211, 199"); - brewer.push("rgb(255, 255, 179"); - brewer.push("rgb(190, 186, 218"); - brewer.push("rgb(251, 128, 114"); - brewer.push("rgb(128, 177, 211"); - brewer.push("rgb(253, 180, 98"); - brewer.push("rgb(179, 222, 105"); - brewer.push("rgb(252, 205, 229"); - brewer.push("rgb(217, 217, 217"); - brewer.push("rgb(188, 128, 189"); - brewer.push("rgb(204, 235, 197"); - brewer.push("rgb(255, 237, 111"); - - /* - * The MIT License (MIT) - * - * Copyright (c) 2014 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - // Reference frame classes. Converts domain coordinates (usually genomic) to pixel coordinates - - class ReferenceFrame { - - constructor(genome, chr, start, end, bpPerPixel) { - this.genome = genome; - this.chr = chr; - - this.start = start; - - // TODO WARNING THIS IS NOT UPDATED !!! - this.end = end; - - this.bpPerPixel = bpPerPixel; - this.id = domUtils$1.guid(); - } - - /** - * Extend this frame to accomodate the given locus. Used th CircularView methods to merge 2 frames. - * @param locus - */ - extend(locus) { - const newStart = Math.min(locus.start, this.start); - const newEnd = Math.max(locus.end, this.end); - const ratio = (newEnd - newStart) / (this.end - this.start); - this.start = newStart; - this.end = newEnd; - this.bpPerPixel *= ratio; - } - - calculateEnd(pixels) { - return this.start + this.bpPerPixel * pixels - } - - calculateBPP(end, pixels) { - return (end - this.start) / pixels - } - - set(json) { - this.chr = json.chr; - this.start = json.start; - this.bpPerPixel = json.bpPerPixel; - } - - toPixels(bp) { - return bp / this.bpPerPixel - } - - toBP(pixels) { - return this.bpPerPixel * pixels - } - - /** - * Shift frame by stated pixels. Return true if view changed, false if not. - * - * @param pixels - * @param clamp -- if true "clamp" shift to prevent panning off edge of chromosome. This is disabled if "show soft clipping" is on - * @param viewportWidth - */ - shiftPixels(pixels, viewportWidth, clamp) { - - const currentStart = this.start; - const deltaBP = pixels * this.bpPerPixel; - - this.start += deltaBP; - - if(clamp) { - this.clampStart(viewportWidth); - } - - this.end = this.start + viewportWidth * this.bpPerPixel; - - return currentStart !== this.start - } - - clampStart(viewportWidth) { - // clamp left - const min = (this.genome.getChromosome(this.chr).bpStart || 0); - this.start = Math.max(min, this.start); - - // clamp right - if (viewportWidth) { - - const {bpLength} = this.genome.getChromosome(this.chr); - const maxStart = bpLength - (viewportWidth * this.bpPerPixel); - - if (this.start > maxStart) { - this.start = maxStart; - } - } - } - - async zoomWithScaleFactor(browser, scaleFactor, viewportWidth, centerBPOrUndefined) { - - const centerBP = undefined === centerBPOrUndefined ? (this.start + this.toBP(viewportWidth / 2.0)) : centerBPOrUndefined; - - // save initial start and bpp - const {start, bpPerPixel} = this.start; - - const {bpLength} = this.getChromosome(); - const bppThreshold = scaleFactor < 1.0 ? browser.minimumBases() / viewportWidth : bpLength / viewportWidth; - - // update bpp - if (scaleFactor < 1.0) { - this.bpPerPixel = Math.max(this.bpPerPixel * scaleFactor, bppThreshold); - } else { - this.bpPerPixel = Math.min(this.bpPerPixel * scaleFactor, bppThreshold); - } - - // update start and end - const widthBP = this.bpPerPixel * viewportWidth; - this.start = centerBP - 0.5 * widthBP; - this.clampStart(viewportWidth); - - this.end = this.start + widthBP; - - const viewChanged = start !== this.start || bpPerPixel !== this.bpPerPixel; - if (viewChanged) { - await browser.updateViews(true); - } - - } - - getChromosome() { - return this.genome.getChromosome(this.chr) - } - - getMultiLocusLabelBPLengthOnly(pixels) { - const margin = ' '; - const ss = Math.floor(this.start) + 1; - const ee = Math.round(this.start + this.bpPerPixel * pixels); - return `${margin}${this.chr}${margin}${prettyBasePairNumber(ee - ss)}${margin}` - } - - getMultiLocusLabelLocusOnly(pixels) { - const margin = ' '; - const {chr, start, end } = this.getPresentationLocusComponents(pixels); - return `${margin}${chr}:${start}-${end}${margin}` - } - - getMultiLocusLabel(pixels) { - const margin = ' '; - const {chr, start, end } = this.getPresentationLocusComponents(pixels); - const ss = Math.floor(this.start) + 1; - const ee = Math.round(this.start + this.bpPerPixel * pixels); - return `${margin}${chr}:${start}-${end}${margin}${margin}(${prettyBasePairNumber(ee - ss)})${margin}` - } - - getPresentationLocusComponents(pixels) { - - if ('all' === this.chr) { - return {chr: this.chr} - } else { - const ss = numberFormatter$1(Math.floor(this.start) + 1); - const ee = numberFormatter$1(Math.round(this.start + this.bpPerPixel * pixels)); - - return {chr: this.chr, start: ss, end: ee} - } - - } - - getLocusString() { - if ('all' === this.chr) { - return 'all' - } else { - const ss = numberFormatter$1(Math.floor(this.start) + 1); - const ee = numberFormatter$1(Math.round(this.end)); - return `${this.chr}:${ss}-${ee}` - } - } - - description(blurb) { - console.log(` ${blurb || ''} referenceFrame - ${this.chr} bpp ${this.bpPerPixel.toFixed(3)} start ${numberFormatter$1(Math.round(this.start))} end ${numberFormatter$1(Math.round(this.end))} `); - } - } - - function createReferenceFrameList(loci, genome, browserFlanking, minimumBases, viewportWidth, isSoftclipped) { - - return loci.map(locus => { - - // If a flanking region is defined, and the search object is a symbol ("gene") type, adjust start and end - if (browserFlanking && locus.gene) { - locus.start = Math.max(0, locus.start - browserFlanking); - locus.end += browserFlanking; - } - - // Validate the range. This potentionally modifies start & end of locus. - if(!isSoftclipped) { - const chromosome = genome.getChromosome(locus.chr); - validateGenomicExtent(chromosome.bpLength, locus, minimumBases); - } - - const referenceFrame = new ReferenceFrame(genome, - locus.chr, - locus.start, - locus.end, - (locus.end - locus.start) / viewportWidth); - - referenceFrame.locusSearchString = locus.locusSearchString; - - // GTEX hack - if (locus.gene || locus.snp) { - referenceFrame.selection = new GtexSelection(locus.gene, locus.snp); - } - - return referenceFrame - }) - } - - const DEFAULT_SEARCH_CONFIG = { - timeout: 5000, - type: "plain", // Legacy plain text support -- deprecated - url: 'https://igv.org/genomes/locus.php?genome=$GENOME$&name=$FEATURE$', - coords: 0, - chromosomeField: "chromosome", - startField: "start", - endField: "end", - geneField: "gene", - snpField: "snp" - }; - - /** - * Return an object representing the locus of the given string. Object is of the form - * { - * chr, - * start, - * end, - * locusSearchString, - * gene, - * snp - * } - * @param browser - * @param string - * @returns {Promise<*>} - */ - async function search(browser, string) { - - if (undefined === string || '' === string.trim()) { - return - } - - if (string && string.trim().toLowerCase() === "all" || string === "*") { - string = "all"; - } - - const loci = string.split(' '); - - let searchConfig = browser.searchConfig || DEFAULT_SEARCH_CONFIG; - let list = []; - - const searchLocus = async (locus) => { - let locusObject = parseLocusString(browser, locus); - - if (!locusObject) { - const feature = browser.genome.featureDB.get(locus.toUpperCase()); - if (feature) { - locusObject = { - chr: feature.chr, - start: feature.start, - end: feature.end, - gene: feature.name, - locusSearchString: string - }; - } - } - - if (!locusObject && (browser.config && false !== browser.config.search)) { - try { - locusObject = await searchWebService(browser, locus, searchConfig); - } catch (error) { - console.error(error); - throw Error("Search service currently unavailable.") - } - } - return locusObject - }; - - for (let locus of loci) { - const locusObject = await searchLocus(locus); - if (locusObject) { - locusObject.locusSearchString = locus; - list.push(locusObject); - } - } - - // If nothing is found, consider possibility that loci name itself has spaces - if (list.length === 0) { - const locusObject = await searchLocus(string); - if (locusObject) { - locusObject.locusSearchString = string; - list.push(locusObject); - } - } - - - return 0 === list.length ? undefined : list - } - - function parseLocusString(browser, locus) { - - // Check for tab delimited locus string - const tabTokens = locus.split('\t'); - if (tabTokens.length >= 3) { - // Possibly a tab-delimited locus - try { - const chr = browser.genome.getChromosomeName(tabTokens[0]); - const start = parseInt(tabTokens[1].replace(/,/g, ''), 10) - 1; - const end = parseInt(tabTokens[2].replace(/,/g, ''), 10); - if (!isNaN(start) && !isNaN(end)) { - return {chr, start, end} - } - } catch (e) { - // Not a tab delimited locus, apparently, but not really an error as that was a guess - } - - } - - const a = locus.split(':'); - const chr = a[0]; - if ('all' === chr && browser.genome.getChromosome(chr)) { - return {chr, start: 0, end: browser.genome.getChromosome(chr).bpLength} - - } else if (undefined === browser.genome.getChromosome(chr)) { - return undefined - - } else { - const queryChr = browser.genome.getChromosomeName(chr); - const extent = { - chr: queryChr, - start: 0, - end: browser.genome.getChromosome(chr).bpLength - }; - - if (a.length > 1) { - - let b = a[1].split('-'); - if (b.length > 2) { - // Allow for negative coordinates, which is possible if showing alignment soft clips - if (a[1].startsWith('-')) { - const i = a[1].indexOf('-', 1); - if (i > 0) { - const t1 = a[1].substring(0, i); - const t2 = a[1].substring(i + 1); - b = [t1, t2]; - } - } else { - return undefined - } - - } - - let numeric; - numeric = b[0].replace(/,/g, ''); - if (isNaN(numeric)) { - return undefined - } - - extent.start = parseInt(numeric, 10) - 1; - extent.end = extent.start + 1; - - if (1 === b.length) { - // Don't clamp coordinates if single coordinate is supplied. - extent.start -= 20; - extent.end += 20; - } - - if (2 === b.length) { - numeric = b[1].replace(/,/g, ''); - if (isNaN(numeric)) { - return undefined - } else { - extent.end = parseInt(numeric, 10); - } - - // Allow negative coordinates only if browser is softclipped, i.e. there is at least alignment track with softclipping on - if (extent.start < 0 && !browser.isSoftclipped()) { - const delta = -extent.start; - extent.start += delta; - extent.end += delta; - } - } - } - - return extent - } - } - - async function searchWebService(browser, locus, searchConfig) { - - let path = searchConfig.url.replace("$FEATURE$", locus.toUpperCase()); - if (path.indexOf("$GENOME$") > -1) { - path = path.replace("$GENOME$", (browser.genome.id ? browser.genome.id : "hg19")); - } - const options = searchConfig.timeout ? {timeout: searchConfig.timeout} : undefined; - const result = await igvxhr.loadString(path, options); - - const locusObject = processSearchResult(browser, result, searchConfig); - if (locusObject) { - locusObject.locusSearchString = locus; - } - return locusObject - } - - function processSearchResult(browser, result, searchConfig) { - - let results; - - if ('plain' === searchConfig.type) { - results = parseSearchResults$1(browser, result); - } else { - results = JSON.parse(result); - } - - if (searchConfig.resultsField) { - results = results[searchConfig.resultsField]; - } - - if (!results || 0 === results.length) { - return undefined - - } else { - - const chromosomeField = searchConfig.chromosomeField || "chromosome"; - const startField = searchConfig.startField || "start"; - const endField = searchConfig.endField || "end"; - const coords = searchConfig.coords || 1; - - - let result; - if (Array.isArray(results)) { - // Ignoring all but first result for now - // TODO -- present all and let user select if results.length > 1 - result = results[0]; - } else { - // When processing search results from Ensembl REST API - // Example: https://rest.ensembl.org/lookup/symbol/macaca_fascicularis/BRCA2?content-type=application/json - result = results; - } - - if (!(result.hasOwnProperty(chromosomeField) && (result.hasOwnProperty(startField)))) { - console.error("Search service results must include chromosome and start fields: " + result); - } - - const chrResult = result[chromosomeField]; - const chromosome = browser.genome.getChromosome(chrResult); - if (!chromosome) { - return undefined - } - const chr = chromosome.name; - - let start = result[startField] - coords; - let end = result[endField]; - if (undefined === end) { - end = start + 1; - } - - const locusObject = {chr, start, end}; - - // Some GTEX hacks - const type = result.type ? result.type : "gene"; - if (searchConfig.geneField && type === "gene") { - locusObject.gene = result[searchConfig.geneField]; - } - if (searchConfig.snpField && type === "snp") { - locusObject.snp = result[searchConfig.snpField]; - } - - return locusObject - } - } - - /** - * Parse the igv line-oriented (non json) search results. - * Example - * EGFR chr7:55,086,724-55,275,031 refseq - * - */ - function parseSearchResults$1(browser, data) { - - const linesTrimmed = []; - const results = []; - const lines = splitLines$5(data); - - lines.forEach(function (item) { - if ("" === item) ; else { - linesTrimmed.push(item); - } - }); - - linesTrimmed.forEach(function (line) { - - var tokens = line.split("\t"), - source, - locusTokens, - rangeTokens, - obj; - - if (tokens.length >= 3) { - - locusTokens = tokens[1].split(":"); - rangeTokens = locusTokens[1].split("-"); - source = tokens[2].trim(); - - obj = - { - gene: tokens[0], - chromosome: browser.genome.getChromosomeName(locusTokens[0].trim()), - start: parseInt(rangeTokens[0].replace(/,/g, '')), - end: parseInt(rangeTokens[1].replace(/,/g, '')), - type: ("gtex" === source ? "snp" : "gene") - }; - - results.push(obj); - - } - - }); - - return results - - } - - /* - * The MIT License (MIT) - * - * Copyright (c) 2014 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - class NavbarManager { - - constructor(browser) { - this.browser = browser; - } - - navbarDidResize(width) { - this.updateNavbar(this.createResponsiveClassSchedule(width)); - } - - updateNavbar(responsiveClassSchedule) { - - this.browser.$toggle_button_container.removeClass(); - this.browser.$toggle_button_container.addClass(responsiveClassSchedule.$toggle_button_container); - - $$1(this.browser.zoomWidget.zoomContainer).removeClass(); - $$1(this.browser.zoomWidget.zoomContainer).addClass(responsiveClassSchedule.zoomContainer); - } - - createResponsiveClassSchedule(navbarWidth) { - - let candidates = {}; - - const isWGV = this.browser.isMultiLocusWholeGenomeView() || - (this.browser.referenceFrameList && - GenomeUtils.isWholeGenomeView(this.browser.referenceFrameList[0].chr)); - - - if (isWGV) { - this.browser.windowSizePanel.hide(); - } else { - this.browser.windowSizePanel.show(); - } - - if (navbarWidth > 990) { - candidates.$toggle_button_container = 'igv-navbar-toggle-button-container'; - candidates.zoomContainer = 'igv-zoom-widget'; - } else if (navbarWidth > 860) { - candidates.$toggle_button_container = 'igv-navbar-toggle-button-container'; - candidates.zoomContainer = 'igv-zoom-widget-900'; - } else if (navbarWidth > 540) { - candidates.$toggle_button_container = 'igv-navbar-toggle-button-container-750'; - candidates.zoomContainer = 'igv-zoom-widget-900'; - } else { - candidates.$toggle_button_container = 'igv-navbar-toggle-button-container-750'; - candidates.zoomContainer = 'igv-zoom-widget-900'; - this.browser.windowSizePanel.hide(); - } - - if (isWGV) { - candidates['zoomContainer'] = 'igv-zoom-widget-hidden'; - } - - return candidates - } - } - - /* - * The MIT License (MIT) - * - * Copyright (c) 2016-2017 The Regents of the University of California - * Author: Jim Robinson - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - const ChromosomeSelectWidget = function (browser, parent) { - - this.container = domUtils$1.div({class: 'igv-chromosome-select-widget-container'}); - parent.appendChild(this.container); - - this.select = document.createElement('select'); - this.select.setAttribute('name', 'chromosome-select-widget'); - this.container.appendChild(this.select); - - this.select.addEventListener('change', () => { - this.select.blur(); - if (this.select.value !== '') { - browser.search(this.select.value); - } - }); - - this.showAllChromosomes = browser.config.showAllChromosomes !== false; // i.e. default to true - - }; - - ChromosomeSelectWidget.prototype.show = function () { - this.container.style.display = 'flex'; - }; - - ChromosomeSelectWidget.prototype.hide = function () { - this.container.style.display = 'none'; - }; - - ChromosomeSelectWidget.prototype.update = function (genome) { - - const list = this.showAllChromosomes ? genome.chromosomeNames.slice() : genome.wgChromosomeNames.slice(); - // console.log(`${ this.showAllChromosomes ? 'Do' : 'Do not'} show all chromosomes. List ${ list }`) - - if (genome.showWholeGenomeView()) { - list.unshift('all'); - list.unshift(''); - } - - this.select.innerHTML = ''; - - for (let name of list) { - const option = document.createElement('option'); - option.setAttribute('value', name); - option.innerText = name; - this.select.appendChild(option); - } - - }; - - /* - * The MIT License (MIT) - * - * Copyright (c) 2014 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - class WindowSizePanel { - constructor(parent, browser) { - - this.container = domUtils$1.div({class: 'igv-windowsize-panel-container'}); - parent.appendChild(this.container); - - browser.on('locuschange', (referenceFrameList) => { - this.updatePanel(referenceFrameList); - }); - - this.browser = browser; - - } - - show() { - this.container.style.display = 'block'; - } - - hide() { - this.container.style.display = 'none'; - } - - updatePanel(referenceFrameList) { - const width = this.browser.calculateViewportWidth(this.browser.referenceFrameList.length); - this.container.innerText = 1 === referenceFrameList.length ? prettyBasePairNumber(Math.round(width * referenceFrameList[0].bpPerPixel)) : ''; - } - } - - class CursorGuide { - - constructor(columnContainer, browser) { - this.browser = browser; - this.columnContainer = columnContainer; - - this.horizontalGuide = domUtils$1.div({class: 'igv-cursor-guide-horizontal'}); - columnContainer.appendChild(this.horizontalGuide); - - this.verticalGuide = domUtils$1.div({class: 'igv-cursor-guide-vertical'}); - columnContainer.appendChild(this.verticalGuide); - - this.addMouseHandler(browser); - - this.setVisibility(browser.config.showCursorGuide); - - } - - addMouseHandler(browser) { - - this.boundMouseMoveHandler = mouseMoveHandler.bind(this); - this.columnContainer.addEventListener('mousemove', this.boundMouseMoveHandler); - - function mouseMoveHandler(event) { - - const {x, y} = domUtils$1.translateMouseCoordinates(event, this.columnContainer); - this.horizontalGuide.style.top = `${y}px`; - - const target = document.elementFromPoint(event.clientX, event.clientY); - - const viewport = findAncestorOfClass(target, 'igv-viewport'); - - if (viewport && browser.getRulerTrackView()) { - - this.verticalGuide.style.left = `${x}px`; - - const columns = browser.root.querySelectorAll('.igv-column'); - let index = undefined; - const viewportParent = viewport.parentElement; - for (let i = 0; i < columns.length; i++) { - if (undefined === index && viewportParent === columns[i]) { - index = i; - } - } - - const rulerViewport = browser.getRulerTrackView().viewports[index]; - const result = rulerViewport.mouseMove(event); - - if (result) { - - const {start, bp, end} = result; - const interpolant = (bp - start) / (end - start); - - if (this.customMouseHandler) { - this.customMouseHandler({start, bp, end, interpolant}); - } - } - } - - } - } - - removeMouseHandler() { - this.columnContainer.removeEventListener('mousemove', this.boundMouseMoveHandler); - } - - setVisibility(showCursorGuide) { - if (true === showCursorGuide) { - this.show(); - } else { - this.hide(); - } - } - - show() { - this.verticalGuide.style.display = 'block'; - this.horizontalGuide.style.display = 'block'; - - } - - hide() { - - this.verticalGuide.style.display = 'none'; - this.horizontalGuide.style.display = 'none'; - - if (this.browser.getRulerTrackView()) { - for (let viewport of this.browser.getRulerTrackView().viewports) { - viewport.$tooltip.hide(); - } - } - - } - - } - - /** - * Walk up the tree until a parent is found with the given classname. If no ancestor is found return undefined. - * @param target - * @param classname - * @returns {*} - */ - function findAncestorOfClass(target, classname) { - - while (target.parentElement) { - if (target.parentElement.classList.contains(classname)) { - return target.parentElement - } else { - target = target.parentElement; - } - } - return undefined - - } - - /* - * The MIT License (MIT) - * - * Copyright (c) 2016 University of California San Diego - * Author: Jim Robinson - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - class CursorGuideButton { - - constructor(browser, parent) { - - this.browser = browser; - - this.button = domUtils$1.div({class: 'igv-navbar-button'}); - parent.appendChild(this.button); - - this.button.textContent = 'cursor guide'; - - this.button.addEventListener('click', () => { - browser.cursorGuideVisible = !browser.cursorGuideVisible; - browser.setCursorGuideVisibility(browser.cursorGuideVisible); - this.setButtonState(browser.cursorGuideVisible); - }); - - this.setButtonState(browser.cursorGuideVisible); - - if (browser.config.showCursorTrackingGuideButton) { - this.show(); - } else { - this.hide(); - } - - } - - setButtonState(cursorGuideVisible) { - if (true === cursorGuideVisible) { - this.button.classList.add('igv-navbar-button-clicked'); - } else { - this.button.classList.remove('igv-navbar-button-clicked'); - } - } - - show() { - this.button.style.display = 'block'; - this.setButtonState(this.browser.cursorGuideVisible); - } - - hide() { - this.button.style.display = 'none'; - } - } - - class CenterLineButton { - - constructor(browser, parent) { - - this.browser = browser; - - this.button = domUtils$1.div({class: 'igv-navbar-button'}); - parent.appendChild(this.button); - - this.button.textContent = 'center line'; - - this.button.addEventListener('click', () => { - browser.isCenterLineVisible = !browser.isCenterLineVisible; - browser.setCenterLineVisibility(browser.isCenterLineVisible); - this.setButtonState(browser.isCenterLineVisible); - }); - - this.setButtonState(browser.isCenterLineVisible); - - if (browser.config.showCenterGuideButton) { - this.show(); - } else { - this.hide(); - } - } - - setButtonState(isCenterLineVisible) { - if (true === isCenterLineVisible) { - this.button.classList.add('igv-navbar-button-clicked'); - } else { - this.button.classList.remove('igv-navbar-button-clicked'); - } - } - - show() { - this.isVisible = true; - this.button.style.display = 'block'; - this.setButtonState(this.browser.isCenterLineVisible); - } - - hide() { - this.isVisible = false; - this.button.style.display = 'none'; - } - } - - /* - * The MIT License (MIT) - * - * Copyright (c) 2016 University of California San Diego - * Author: Jim Robinson - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - class TrackLabelControl { - - constructor(parent, browser) { - - this.button = domUtils$1.div({class: 'igv-navbar-button'}); - parent.appendChild(this.button); - this.button.textContent = 'track labels'; - - this.button.addEventListener('click', () => { - browser.trackLabelsVisible = !browser.trackLabelsVisible; - this.setState(browser.trackLabelsVisible); - browser.setTrackLabelVisibility(browser.trackLabelsVisible); - }); - - this.browser = browser; - - this.setVisibility(browser.config.showTrackLabelButton); - - this.setState(browser.trackLabelsVisible); - } - - setVisibility(showTrackLabelButton) { - if (true === showTrackLabelButton) { - this.show(); - } else { - this.hide(); - } - } - - setState(trackLabelsVisible) { - if (true === trackLabelsVisible) { - this.button.classList.add('igv-navbar-button-clicked'); - } else { - this.button.classList.remove('igv-navbar-button-clicked'); - } - } - - show() { - this.button.style.display = 'block'; - this.setState(this.browser.trackLabelsVisible); - } - - hide() { - this.button.style.display = 'none'; - } - } - - /* - * The MIT License (MIT) - * - * Copyright (c) 2016 University of California San Diego - * Author: Jim Robinson - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - class SampleNameControl { - - constructor(parent, browser) { - - this.button = domUtils$1.div({class: 'igv-navbar-button'}); - parent.appendChild(this.button); - - this.button.innerText = 'Sample Names'; - - this.setState(browser.showSampleNames); - - this.setVisibility(browser.showSampleNameButton); - - this.button.addEventListener('click', () => { - - browser.showSampleNames = !browser.showSampleNames; - - this.setState(browser.showSampleNames); - - for (let {sampleNameViewport} of browser.trackViews) { - if (false === browser.showSampleNames) { - sampleNameViewport.hide(); - } else { - sampleNameViewport.show(); - } - } - - browser.layoutChange(); - - - }); - - } - - setVisibility(showSampleNameButton) { - - if (true === showSampleNameButton) { - this.show(); - } else { - this.hide(); - } - } - - setState(showSampleNames) { - if (true === showSampleNames) { - this.button.classList.add('igv-navbar-button-clicked'); - } else { - this.button.classList.remove('igv-navbar-button-clicked'); - } - } - - hide() { - this.button.style.display = 'none'; - } - - show() { - this.button.style.display = 'block'; - } - - } - - const sliderMin = 0; - let sliderMax = 23; - let sliderValueRaw = 0; - - const ZoomWidget = function (browser, parent) { - - this.browser = browser; - - this.zoomContainer = domUtils$1.div({class: 'igv-zoom-widget'}); - parent.appendChild(this.zoomContainer); - - // zoom out - this.zoomOutButton = domUtils$1.div(); - this.zoomContainer.appendChild(this.zoomOutButton); - this.zoomOutButton.appendChild(icons$1$1.createIcon('minus-circle')); - this.zoomOutButton.addEventListener('click', () => { - // browser.zoomWithScaleFactor(2.0) - browser.zoomOut(); - }); - - // Range slider - const el = domUtils$1.div(); - this.zoomContainer.appendChild(el); - this.slider = document.createElement('input'); - this.slider.type = 'range'; - - this.slider.min = `${sliderMin}`; - this.slider.max = `${sliderMax}`; - - el.appendChild(this.slider); - - this.slider.addEventListener('change', e => { - - e.preventDefault(); - e.stopPropagation(); - - const referenceFrame = browser.referenceFrameList[0]; - const {bpLength} = referenceFrame.genome.getChromosome(referenceFrame.chr); - const {end, start} = referenceFrame; - - const extent = end - start; - - // bpLength/(end - start) - const scaleFactor = Math.pow(2, e.target.valueAsNumber); - - // (end - start) = bpLength/scaleFactor - const zoomedExtent = bpLength / scaleFactor; - - // console.log(`zoom-widget - slider ${ e.target.value } scaleFactor ${ scaleFactor } extent-zoomed ${ StringUtils.numberFormatter(Math.round(zoomedExtent)) }`) - - browser.zoomWithScaleFactor(zoomedExtent / extent); - - }); - - // zoom in - this.zoomInButton = domUtils$1.div(); - this.zoomContainer.appendChild(this.zoomInButton); - this.zoomInButton.appendChild(icons$1$1.createIcon('plus-circle')); - this.zoomInButton.addEventListener('click', () => { - // browser.zoomWithScaleFactor(0.5) - browser.zoomIn(); - }); - - browser.on('locuschange', (referenceFrameList) => { - - if (this.browser.isMultiLocusMode()) { - this.disable(); - } else { - this.enable(); - this.update(referenceFrameList); - } - - }); - - }; - - ZoomWidget.prototype.update = function (referenceFrameList) { - - const referenceFrame = referenceFrameList[0]; - const {bpLength} = referenceFrame.genome.getChromosome(referenceFrame.chr); - const {start, end} = referenceFrame; - - sliderMax = Math.ceil(Math.log2(bpLength / this.browser.minimumBases())); - - this.slider.max = `${sliderMax}`; - - const scaleFactor = bpLength / (end - start); - sliderValueRaw = Math.log2(scaleFactor); - this.slider.value = `${Math.round(sliderValueRaw)}`; - - // referenceFrame.description('zoom.update') - - // console.log(`${ Date.now() } update - slider ${ this.slider.value } scaleFactor ${ Math.round(scaleFactor) } extent ${ StringUtils.numberFormatter(Math.round(extent)) }`) - - // console.log(`update - sliderMin ${ sliderMin } sliderValue ${ this.slider.value } sliderMax ${ sliderMax } scaleFactor ${ scaleFactor.toFixed(3) } derived-scaleFactor ${ derivedScalefactor.toFixed(3) }`) - - }; - - ZoomWidget.prototype.enable = function () { - - // this.zoomInButton.style.color = appleCrayonPalette[ 'steel' ]; - // this.zoomInButton.style.pointerEvents = 'auto'; - // - // this.zoomOutButton.style.color = appleCrayonPalette[ 'steel' ]; - // this.zoomOutButton.style.pointerEvents = 'auto'; - - this.slider.disabled = false; - }; - - ZoomWidget.prototype.disable = function () { - - // this.zoomInButton.style.color = appleCrayonPalette[ 'silver' ]; - // this.zoomInButton.style.pointerEvents = 'none'; - // - // this.zoomOutButton.style.color = appleCrayonPalette[ 'silver' ]; - // this.zoomOutButton.style.pointerEvents = 'none'; - - this.slider.disabled = true; - }; - - ZoomWidget.prototype.hide = function () { - this.zoomContainer.style.display = 'none'; - }; - - ZoomWidget.prototype.show = function () { - this.zoomContainer.style.display = 'block'; - }; - - ZoomWidget.prototype.hideSlider = function () { - this.slider.style.display = 'none'; - }; - - ZoomWidget.prototype.showSlider = function () { - this.slider.style.display = 'block'; - }; - - /* - * The MIT License (MIT) - * - * Copyright (c) 2016 University of California San Diego - * Author: Jim Robinson - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - const SVGSaveControl = function (parent, browser) { - const button = domUtils$1.div({class: 'igv-navbar-button'}); - parent.append(button); - - button.textContent = 'Save SVG'; - button.addEventListener('click', () => browser.saveSVGtoFile({})); - }; - - const viewportColumnManager = - { - createColumns: (columnContainer, count) => { - - for (let i = 0; i < count; i++) { - if (0 === i) { - createColumn(columnContainer, 'igv-column'); - } else { - columnContainer.appendChild(domUtils$1.div({class: 'igv-column-shim'})); - createColumn(columnContainer, 'igv-column'); - } - } - - }, - - removeColumnAtIndex: (i, column) => { - const shim = 0 === i ? column.nextElementSibling : column.previousElementSibling; - column.remove(); - shim.remove(); - }, - - insertAfter: referenceElement => { - - const shim = domUtils$1.div({class: 'igv-column-shim'}); - insertElementAfter(shim, referenceElement); - - const column = domUtils$1.div({class: 'igv-column'}); - insertElementAfter(column, shim); - - return column - }, - - insertBefore: (referenceElement, count) => { - - for (let i = 0; i < count; i++) { - - const column = domUtils$1.div({class: 'igv-column'}); - insertElementBefore(column, referenceElement); - - if (count > 1 && i > 0) { - const columnShim = domUtils$1.div({class: 'igv-column-shim'}); - insertElementBefore(columnShim, column); - } - - } - - }, - - indexOfColumn: (columnContainer, column) => { - - const allColumns = columnContainer.querySelectorAll('.igv-column'); - - for (let i = 0; i < allColumns.length; i++) { - const c = allColumns[ i ]; - if (c === column) { - return i - } - } - - return undefined - }, - }; - - /* - * The MIT License (MIT) - * - * Copyright (c) 2016 University of California San Diego - * Author: Jim Robinson - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - class ViewportCenterLine { - - constructor(browser, referenceFrame, column) { - - this.browser = browser; - this.referenceFrame = referenceFrame; - this.column = column; - - this.container = domUtils$1.div({class: 'igv-center-line'}); - column.appendChild(this.container); - - if (browser.isCenterLineVisible) { - this.show(); - } else { - this.hide(); - } - } - - repaint() { - - if (this.referenceFrame) { - - const ppb = 1.0 / this.referenceFrame.bpPerPixel; - if (ppb > 1) { - const width = Math.floor(this.referenceFrame.toPixels(1)); - this.container.style.width = `${width}px`; - this.container.classList.remove('igv-center-line-thin'); - this.container.classList.add('igv-center-line-wide'); - } else { - this.container.style.width = '1px'; - this.container.classList.remove('igv-center-line-wide'); - this.container.classList.add('igv-center-line-thin'); - } - } - } - - show() { - this.isVisible = true; - this.container.style.display = 'block'; - this.repaint(); - } - - hide() { - this.isVisible = false; - this.container.style.display = 'none'; - } - - resize() { - this.repaint(); - } - } - - /* - * The MIT License (MIT) - * - * Copyright (c) 2014 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - const numberFormatter = numberFormatter$1; - - class RulerTrack { - constructor(browser) { - - this.browser = browser; - this.height = 40; - this.name = ""; - this.id = "ruler"; - this.disableButtons = true; - this.ignoreTrackMenu = true; - this.order = Number.MIN_SAFE_INTEGER * 1e-2; - this.removable = false; - this.type = 'ruler'; - } - - async getFeatures(chr, start, end) { - return [] - }; - - computePixelHeight(ignore) { - return this.height - }; - - draw({context, referenceFrame, pixelWidth, pixelHeight, bpPerPixel, bpStart}) { - - if (GenomeUtils.isWholeGenomeView(referenceFrame.chr)) { - this.drawWholeGenome({context, pixelWidth, pixelHeight, bpPerPixel}); - } else { - this.doDraw({context, referenceFrame, pixelWidth, pixelHeight, bpStart}); - } - } - - drawWholeGenome({context, pixelWidth, pixelHeight, bpPerPixel}) { - - context.save(); - - IGVGraphics.fillRect(context, 0, 0, pixelWidth, pixelHeight, {'fillStyle': 'white'}); - - for (let name of this.browser.genome.wgChromosomeNames) { - - let xBP = this.browser.genome.getCumulativeOffset(name); - let wBP = this.browser.genome.getChromosome(name).bpLength; - - let x = Math.round(xBP / bpPerPixel); - let w = Math.round(wBP / bpPerPixel); - - this.renderChromosomeRect(context, x, 0, w, pixelHeight, name); - } - - context.restore(); - - } - - doDraw({context, referenceFrame, pixelWidth, pixelHeight, bpStart}) { - - context.clearRect(0, 0, pixelWidth, pixelHeight); - - const tickHeight = 6; - const shim = 2; - - const bpLength = Math.floor(referenceFrame.toBP(pixelWidth)); - const tick = findSpacing$1(bpLength, context.isSVG); - - let nTick = Math.floor(bpStart / tick.majorTick) - 1; - - const {tickDelta, labelLength} = calculateDeltas(context, referenceFrame, bpStart, nTick, tick); - - this.browser.referenceFrameList.indexOf(referenceFrame); - // console.log(`ruler(${ index }) label-length ${ labelLength > tickDelta ? 'clobbers' : 'less than' } tick-delta ${ StringUtils.numberFormatter(tickDelta)} `) - - let xTick; - let bp; - let accumulatedTickDelta = tickDelta; - const labelLengthShim = 0.25 * labelLength; - do { - - bp = Math.floor(nTick * tick.majorTick); - const rulerLabel = `${numberFormatter$1(Math.floor(bp / tick.unitMultiplier))} ${tick.majorUnit}`; - - xTick = Math.round(referenceFrame.toPixels((bp - 1) - bpStart + 0.5)); - const xLabel = Math.round(xTick - context.measureText(rulerLabel).width / 2); - - if (xLabel > 0 && (labelLengthShim + labelLength) <= accumulatedTickDelta) { - IGVGraphics.fillText(context, rulerLabel, xLabel, this.height - (tickHeight / 0.75)); - accumulatedTickDelta = 0; - } - - if (xTick > 0) { - IGVGraphics.strokeLine(context, xTick, this.height - tickHeight, xTick, this.height - shim); - } - - bp = Math.floor((1 + nTick) * tick.majorTick); - let pixel = Math.round(referenceFrame.toPixels((bp - 1) - bpStart + 0.5)); - let delta = (pixel - xTick) / 2; - let xx = xTick + delta; - if (xx > 0) { - IGVGraphics.strokeLine(context, xx, this.height - tickHeight, xx, this.height - shim); - } - - ++nTick; - accumulatedTickDelta += tickDelta; - - } while (xTick < pixelWidth) - - IGVGraphics.strokeLine(context, 0, this.height - shim, pixelWidth, this.height - shim); - - } - - renderChromosomeRect(ctx, x, y, w, h, name) { - - ctx.textAlign = 'center'; - ctx.textBaseline = 'middle'; - ctx.font = '12px sans-serif'; - - IGVGraphics.strokeLine(ctx, x + w, y, x + w, y + h, {strokeStyle: IGVColor.greyScale(191)}); - - const shortName = (name.startsWith("chr")) ? name.substring(3) : name; - - if (w > ctx.measureText(shortName).width) { - IGVGraphics.fillText(ctx, shortName, (x + (w / 2)), (y + (h / 2)), {fillStyle: IGVColor.greyScale(68)}); - } - } - - get supportsWholeGenome() { - return true - }; - - dispose() { - // do stuff - } - } - - function findSpacing$1(bpLength, isSVG) { - - if (bpLength < 10) { - return new Tick(1, 'bp', 1) - } - - const nZeroes = Math.floor(Math.log10(bpLength)); - - let majorUnit = 'bp'; - let unitMultiplier = 1; - - if (nZeroes > 9) { - majorUnit = 'gb'; - unitMultiplier = 1e9; - } else if (nZeroes > 6) { - majorUnit = 'mb'; - unitMultiplier = 1e6; - } else if (nZeroes > 3) { - majorUnit = 'kb'; - unitMultiplier = 1e3; - } - - const denom = Math.pow(10, nZeroes - 1); - const nMajorTicks = bpLength / denom; - - // const threshold = 25 - const threshold = 3 * 25; - - const belowThresholdTick = Math.pow(10, nZeroes - 1); - const aboveThresholdTick = Math.pow(10, nZeroes) / 2; - - // console.log(`zeros ${ nZeroes } tick-threshold ${ threshold } ticks ${ nMajorTicks } belowTick ${ StringUtils.numberFormatter(belowThresholdTick) } aboveTick ${ StringUtils.numberFormatter(aboveThresholdTick) }`) - - const majorTick = (nMajorTicks < threshold && isSVG !== true) ? belowThresholdTick : aboveThresholdTick; - - return new Tick(majorTick, majorUnit, unitMultiplier) - } - - function calculateDeltas(context, referenceFrame, bpStart, nTick, tick) { - - const tickDelta = getX(referenceFrame, getBP(1 + nTick, tick), bpStart) - getX(referenceFrame, getBP(nTick, tick), bpStart); - - const label = `${numberFormatter$1(Math.floor(getBP(nTick, tick) / tick.unitMultiplier))} ${tick.majorUnit}`; - const labelLength = Math.floor(context.measureText(label).width); - - return {tickDelta, labelLength} - - function getBP(nTick, tick) { - return Math.floor(nTick * tick.majorTick) - } - - function getX(referenceFrame, bp, bpStart) { - return Math.round(referenceFrame.toPixels((bp - 1) - bpStart + 0.5)) - } - } - - class Tick { - - constructor(majorTick, majorUnit, unitMultiplier) { - this.majorTick = majorTick; - this.minorTick = majorTick / 10.0; - this.majorUnit = majorUnit; - this.unitMultiplier = unitMultiplier; - } - - description(blurb) { - console.log((blurb || '') + ' tick ' + numberFormatter(this.majorTick) + ' label width ' + numberFormatter(this.labelWidthBP) + ' multiplier ' + this.unitMultiplier); - } - } - - /* - * The MIT License (MIT) - * - * Copyright (c) 2016 University of California San Diego - * Author: Jim Robinson - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - const CircularViewControl = function (parent, browser) { - - this.button = domUtils$1.div({class: 'igv-navbar-button'}); - parent.appendChild(this.button); - this.button.textContent = 'circular view'; - - this.button.addEventListener('click', () => { - browser.circularViewVisible = !browser.circularViewVisible; - //this.setState(browser.circularViewVisible) - }); - - this.browser = browser; - - this.setVisibility(browser.config.showCircularViewButton); - - this.setState(browser.circularViewVisible); - - }; - - CircularViewControl.prototype.setVisibility = function (showCircularViewButton) { - if (true === showCircularViewButton) { - this.show(); - } else { - this.hide(); - } - }; - - CircularViewControl.prototype.setState = function (circularViewVisible) { - if (true === circularViewVisible) { - this.button.classList.add('igv-navbar-button-clicked'); - } else { - this.button.classList.remove('igv-navbar-button-clicked'); - } - }; - - CircularViewControl.prototype.show = function () { - this.button.style.display = 'block'; - this.setState(this.browser.circularViewVisible); - }; - - CircularViewControl.prototype.hide = function () { - this.button.style.display = 'none'; - }; - - /** - * User supplied button for the navbar - */ - - const CustomButton = function (parent, browser, b) { - - const button = domUtils$1.div({class: 'igv-navbar-button'}); - parent.append(button); - button.textContent = b.label; - button.addEventListener('click', () => b.callback(browser)); - }; - - class ROIManager { - - constructor(browser, roiMenu, roiTable, top, roiSets) { - - this.browser = browser; - this.roiMenu = roiMenu; - this.roiTable = roiTable; - this.top = top; - this.roiSets = roiSets || []; - this.boundLocusChangeHandler = locusChangeHandler.bind(this); - browser.on('locuschange', this.boundLocusChangeHandler); - - } - - async initialize() { - - if (this.roiSets.length > 0) { - this.browser.showROITableButton = true; - this.browser.roiTableControl.setVisibility(this.browser.showROITableButton); - } - - const promises = this.roiSets.map(roiSet => this.renderROISet({ - browser: this.browser, - pixelTop: this.top, - roiSet - })); - - if (promises.length > 0) { - await Promise.all(promises); - } - - const records = await this.getTableRecords(); - this.roiTable.renderTable(records); - - } - - async loadROI(config, genome) { - - const configs = Array.isArray(config) ? config : [config]; - - for (let c of configs) { - this.roiSets.push(new ROISet(c, genome)); - } - - await this.initialize(); - - } - - clearROIs() { - - this.roiTable.clearTable(); - - const elements = this.browser.columnContainer.querySelectorAll('.igv-roi-region'); - for (let el of elements) { - el.remove(); - } - - for (let roiSet of this.roiSets) { - roiSet.dispose(); - } - - this.roiSets = []; - - } - - async getTableRecords() { - - const records = []; - - for (let roiSet of this.roiSets) { - const setName = roiSet.isUserDefined ? '' : (roiSet.name || ''); - const allFeatures = await roiSet.getAllFeatures(); - for (let chr of Object.keys(allFeatures)) { - for (let feature of allFeatures[chr]) { - records.push({setName, feature}); - } - } - } - - return records - } - - presentTable() { - this.roiTable.present(); - } - - async repaintTable() { - const records = await this.getTableRecords(); - this.roiTable.renderTable(records); - } - - dismissTable() { - this.roiTable.dismiss(); - } - - async updateUserDefinedROISet(feature) { - - let userDefinedROISet = await this.getUserDefinedROISet(); - - if (undefined === userDefinedROISet) { - userDefinedROISet = this.initializeUserDefinedROISet(); - } - - userDefinedROISet.addFeature(feature); - - if (false === this.browser.showROITableButton) { - this.setROITableButtonVisibility(true); - } - - await this.renderROISet({browser: this.browser, pixelTop: this.top, roiSet: userDefinedROISet}); - - const records = await this.getTableRecords(); - this.roiTable.renderTable(records); - } - - setROITableButtonVisibility(isVisible) { - this.browser.showROITableButton = isVisible; - this.browser.roiTableControl.setVisibility(this.browser.showROITableButton); - } - - async renderAllROISets() { - - for (let roiSet of this.roiSets) { - await this.renderROISet({browser: this.browser, pixelTop: this.top, roiSet}); - } - } - - async renderROISet({browser, pixelTop, roiSet}) { - - const columns = browser.columnContainer.querySelectorAll('.igv-column'); - - for (let i = 0; i < columns.length; i++) { - - let {chr, start: viewStart, end: viewEnd, bpPerPixel} = browser.referenceFrameList[i]; - - const elements = columns[i].querySelectorAll('.igv-roi-region'); - for (let el of elements) { - const regionKey = el.dataset.region; - const {chr: regionChr, start: regionStart, end: regionEnd} = parseRegionKey(regionKey); - if (regionChr !== chr || regionEnd < viewStart || regionStart > viewEnd) { - el.remove(); - } - } - - const features = await roiSet.getFeatures(chr, viewStart, viewEnd); - - if (features) { - - for (let feature of features) { - - const regionKey = createRegionKey(chr, feature.start, feature.end); - - const { - x: pixelX, - width: pixelWidth - } = screenCoordinates(Math.max(viewStart, feature.start), Math.min(viewEnd, feature.end), viewStart, bpPerPixel); - - - const el = columns[i].querySelector(createSelector(regionKey)); - - if (el) { - el.style.left = `${pixelX}px`; - el.style.width = `${pixelWidth}px`; - - } else { - const element = this.createRegionElement(browser.columnContainer, pixelTop, pixelX, pixelWidth, roiSet, regionKey, feature.name); - columns[i].appendChild(element); - } - } - } - } - } - - createRegionElement(columnContainer, pixelTop, pixelX, pixelWidth, roiSet, regionKey, name) { - - const regionElement = domUtils$1.div({class: 'igv-roi-region'}); - - regionElement.style.top = `${pixelTop}px`; - regionElement.style.left = `${pixelX}px`; - regionElement.style.width = `${pixelWidth}px`; - regionElement.style.backgroundColor = roiSet.color; - regionElement.dataset.region = regionKey; - - const header = domUtils$1.div(); - regionElement.appendChild(header); - - header.style.backgroundColor = roiSet.headerColor; - - if (true === roiSet.isUserDefined) { - header.addEventListener('click', event => { - event.preventDefault(); - event.stopPropagation(); - - const {x, y} = domUtils$1.translateMouseCoordinates(event, columnContainer); - this.roiMenu.present(x, y, this, columnContainer, regionElement); - }); - } else if (name) { - header.addEventListener('click', event => { - event.preventDefault(); - event.stopPropagation(); - if (this.popover) { - this.popover.dispose(); - } - this.popover = new Popover(columnContainer, roiSet.name); - this.popover.presentContentWithEvent(event, name); - }); - } else { - header.style.pointerEvents = 'none'; - } - - return regionElement - } - - renderSVGContext(context, {deltaX, deltaY}) { - - for (const regionElement of document.querySelectorAll('.igv-roi-region')) { - - // body - const { x, y, width, height } = regionElement.getBoundingClientRect(); - context.fillStyle = regionElement.style.backgroundColor; - context.fillRect(x+deltaX, y+deltaY, width, height); - - // header - const header = regionElement.querySelector('div'); - const { x:xx, y:yy, width:ww, height:hh } = header.getBoundingClientRect(); - context.fillStyle = header.style.backgroundColor; - context.fillRect(xx+deltaX, yy+deltaY, ww, hh); - } - } - - async getUserDefinedROISet() { - return this.roiSets.find(roiSet => true === roiSet.isUserDefined) - } - - initializeUserDefinedROISet() { - - const config = - { - isUserDefined: true, - features: [] - }; - const userDefinedROISet = new ROISet(config, this.browser.genome); - this.roiSets.push(userDefinedROISet); - - return userDefinedROISet - } - - async deleteUserDefinedRegionWithKey(regionKey, columnContainer) { - - columnContainer.querySelectorAll(createSelector(regionKey)).forEach(node => node.remove()); - - const feature = await this.findUserDefinedRegionWithKey(regionKey); - - const set = await this.getUserDefinedROISet(); - - if (set) { - set.removeFeature(feature); - } - - const records = await this.getTableRecords(); - - if (0 === records.length) { - this.browser.roiTableControl.buttonHandler(false); - this.setROITableButtonVisibility(false); - } - - } - - async findUserDefinedRegionWithKey(regionKey) { - - const {chr, start, end} = parseRegionKey(regionKey); - const set = await this.getUserDefinedROISet(); - - if (set) { - const features = await set.getFeatures(chr, start, end); - - for (let feature of features) { - if (feature.chr === chr && feature.start >= start && feature.end <= end) { - return feature - } - } - } - - return undefined - } - - toJSON() { - return this.roiSets.map(roiSet => roiSet.toJSON()) - } - - dispose() { - - this.browser.off('locuschange', this.boundLocusChangeHandler); - - const removable = this.browser.columnContainer.querySelectorAll('.igv-roi-region'); - - for (let el of removable) { - el.remove(); - } - - if (this.roiMenu) { - this.roiMenu.dispose(); - } - - if (this.roiTable) { - this.roiTable.dispose(); - } - - for (let roiSet of this.roiSets) { - roiSet.dispose(); - } - - for (let key of Object.keys(this)) { - this[key] = undefined; - } - - } - } - - function locusChangeHandler() { - this.renderAllROISets(); - } - - function createRegionKey(chr, start, end) { - return `${chr}-${start}-${end}` - } - - function createSelector(regionKey) { - return `[data-region="${regionKey}"]` - } - - function parseRegionKey(regionKey) { - let [chr, ss, ee] = regionKey.split('-'); - ss = parseInt(ss); - ee = parseInt(ee); - - return {chr, start: ss, end: ee, locus: `${chr}:${ss}-${ee}`, bedRecord: `${chr}\t${ss}\t${ee}`} - } - - class ROITable extends RegionTableBase { - constructor(config) { - - const cooked = Object.assign({ 'width':'512px' }, config); - super(cooked); - } - - tableRowDOM(record) { - - const dom = domUtils$1.div({ class: 'igv-roi-table-row' }); - - const { setName, feature } = record; - dom.dataset.region = createRegionKey(feature.chr, feature.start, feature.end); - - let strings = - [ - feature.chr, - numberFormatter$1(feature.start), - numberFormatter$1(feature.end), - feature.name || '', - setName - ]; - - if (4 === this.columnFormat.length) { - strings = strings.slice(0, 4); - } - - for (let i = 0; i < strings.length; i++) { - const el = domUtils$1.div(); - dom.appendChild(el); - el.style.width = this.columnFormat[ i ].width; - el.innerText = strings[ i ]; - } - - this.tableRowDOMHelper(dom); - - return dom - } - - renderTable(records) { - - Array.from(this.tableRowContainer.querySelectorAll('.igv-roi-table-row')).forEach(el => el.remove()); - - if (records.length > 0) { - - const sortedRecords = records.sort((a, b) => (a.feature.chr.localeCompare(b.feature.chr) || a.feature.start - b.feature.start || a.feature.end - b.feature.end)); - - for (let record of sortedRecords) { - const row = this.tableRowDOM(record); - this.tableRowContainer.appendChild(row); - } - - } - } - - dispose() { - - document.removeEventListener('click', this.boundGotoButtonHandler); - - this.browser.roiTableControl.buttonHandler(false); - super.dispose(); - } - - static getColumnFormatConfiguration(doIncludeROISetNames) { - - if (true === doIncludeROISetNames) { - - return [ - { label: 'Chr', width: '20%' }, - { label: 'Start', width: '15%' }, - { label: 'End', width: '15%' }, - { label: 'Description', width: '30%' }, - { label: 'ROI Set', width: '20%' } - ] - } else { - return [ - { label: 'Chr', width: '25%' }, - { label: 'Start', width: '20%' }, - { label: 'End', width: '20%' }, - { label: 'Description', width: '35%' } - ] - } - - } - - static gotoButtonHandler (event) { - - event.stopPropagation(); - - const selected = this.tableDOM.querySelectorAll('.igv-roi-table-row-selected'); - const loci = []; - for (let el of selected) { - const { locus } = parseRegionKey(el.dataset.region); - loci.push(locus); - } - - for (let el of this.tableDOM.querySelectorAll('.igv-roi-table-row')) { - el.classList.remove('igv-roi-table-row-selected'); - } - - this.setTableRowSelectionState(false); - - if (loci.length > 0) { - this.browser.search(loci.join(' ')); - } - - } - - } - - class ROIMenu { - constructor(browser, parent) { - - this.browser = browser; - - // container - this.container = domUtils$1.div({ class: 'igv-roi-menu-next-gen' }); - parent.appendChild(this.container); - - // header - const header = domUtils$1.div(); - this.container.appendChild(header); - - uiUtils$1.attachDialogCloseHandlerWithParent(header, () => this.container.style.display = 'none'); - - // body - this.body = domUtils$1.div(); - this.container.appendChild(this.body); - - this.container.style.display = 'none'; - - } - - async present(x, y, roiManager, columnContainer, regionElement) { - - removeAllChildNodes(this.body); - - const feature = await this.browser.roiManager.findUserDefinedRegionWithKey(regionElement.dataset.region); - - // Description Copy - const _description_copy_ = domUtils$1.div(); - this.body.appendChild(_description_copy_); - - const placeholder = 'Description'; - const str = (feature.name || placeholder); - - _description_copy_.innerText = str; - _description_copy_.setAttribute('title', str); - placeholder === str ? _description_copy_.classList.add('igv-roi-placeholder') : _description_copy_.classList.remove('igv-roi-placeholder'); - - - // Set Description - const description = domUtils$1.div(); - this.body.appendChild(description); - description.innerText = 'Set Description'; - - description.addEventListener('click', event => { - - event.stopPropagation(); - - this.container.style.display = 'none'; - - const callback = () => { - - const value = this.browser.inputDialog.value || ''; - feature.name = value.trim(); - - this.container.style.display = 'none'; - - this.browser.roiManager.repaintTable(); - }; - - const config = - { - label: 'Description', - value: (feature.name || ''), - callback - }; - - this.browser.inputDialog.present(config, event); - - }); - - - // Delete Region - const _delete_ = domUtils$1.div(); - this.body.appendChild(_delete_); - _delete_.innerText = 'Delete Region'; - - _delete_.addEventListener('click', event => { - event.stopPropagation(); - this.container.style.display = 'none'; - this.browser.roiManager.deleteUserDefinedRegionWithKey(regionElement.dataset.region, this.browser.columnContainer); - }); - - - - - - - - // columnContainer.addEventListener('click', event => { - // event.stopPropagation() - // this.container.style.display = 'none' - // }) - - this.container.style.left = `${ x }px`; - this.container.style.top = `${ y }px`; - this.container.style.display = 'flex'; - - } - - async __present(x, y, roiManager, columnContainer, regionElement) { - - removeAllChildNodes(this.container); - - const feature = await this.browser.roiManager.findUserDefinedRegionWithKey(regionElement.dataset.region); - - let row; - - // Go To - // row = DOMUtils.div({ class: 'igv-roi-menu-row' }) - // row.innerText = 'Go To' - // this.container.appendChild(row) - // - // row.addEventListener('click', event => { - // event.stopPropagation() - // this.container.style.display = 'none' - // - // const { locus } = parseRegionKey(regionElement.dataset.region) - // this.browser.search(locus) - // }) - - // Description: - row = domUtils$1.div({ class: 'igv-roi-menu-row-edit-description' }); - this.container.appendChild(row); - - row.addEventListener('click', e => { - e.stopPropagation(); - }); - - const str = 'description-input'; - - const label = document.createElement('label'); - row.appendChild(label); - - label.setAttribute('for', str); - label.innerText = 'Description:'; - - const input = document.createElement('input'); - row.appendChild(input); - - input.setAttribute('type', 'text'); - input.setAttribute('name', str); - // input.setAttribute('placeholder', feature.name || 'Edit Description') - input.setAttribute('placeholder', ''); - input.value = feature.name || ''; - - input.addEventListener('change', async e => { - - e.stopPropagation(); - - const feature = await this.browser.roiManager.findUserDefinedRegionWithKey(regionElement.dataset.region); - feature.name = input.value; - - input.blur(); - this.container.style.display = 'none'; - - await this.browser.roiManager.repaintTable(); - }); - - - // Delete - row = domUtils$1.div({ class: 'igv-roi-menu-row' }); - row.innerText = 'Delete region'; - this.container.appendChild(row); - - row.addEventListener('click', event => { - event.stopPropagation(); - this.container.style.display = 'none'; - this.browser.roiManager.deleteUserDefinedRegionWithKey(regionElement.dataset.region, this.browser.columnContainer); - }); - - this.container.style.left = `${ x }px`; - this.container.style.top = `${ y }px`; - this.container.style.display = 'flex'; - - columnContainer.addEventListener('click', event => { - event.stopPropagation(); - this.container.style.display = 'none'; - }); - - } - - dispose() { - this.container.innerHTML = ''; - } - - } - - function removeAllChildNodes(parent) { - while (parent.firstChild) { - parent.removeChild(parent.firstChild); - } - } - - class TrackROISet { - - constructor(config, genome) { - this.name = config.name; - this.featureSource = config.featureSource || FeatureSource(config, genome); - this.color = config.color || ROI_DEFAULT_COLOR; - } - - async getFeatures(chr, start, end) { - return this.featureSource.getFeatures({chr, start, end}) - } - - draw(drawConfiguration) { - - const { context, bpPerPixel, bpStart, pixelTop, pixelHeight, pixelWidth, features, } = drawConfiguration; - - if (!features) { - return - } - - const bpEnd = bpStart + (pixelWidth * bpPerPixel) + 1; - for (let { start:regionStartBP, end:regionEndBP } of features) { - - if (regionEndBP < bpStart) { - continue - } - - if (regionStartBP > bpEnd) { - break - } - - const { x, width } = screenCoordinates(regionStartBP, regionEndBP, bpStart, bpPerPixel); - IGVGraphics.fillRect(context, x, pixelTop, width, pixelHeight, { fillStyle: this.color }); - } - } - } - - /* - * The MIT License (MIT) - * - * Copyright (c) 2016 University of California San Diego - * Author: Jim Robinson - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - class ROITableControl { - - constructor(parent, browser) { - this.browser = browser; - this.button = domUtils$1.div({class: 'igv-navbar-button'}); - parent.appendChild(this.button); - this.button.textContent = 'ROI Table'; - - this.button.addEventListener('click', () => { - this.buttonHandler(!browser.roiTableVisible); - }); - - this.browser = browser; - - this.setVisibility(browser.showROITableButton); - - this.setState(browser.roiTableVisible); - } - - buttonHandler(status) { - this.browser.roiTableVisible = status; - this.setState(this.browser.roiTableVisible); - this.browser.setROITableVisibility(this.browser.roiTableVisible); - } - - setVisibility(doShowROITablelButton) { - if (true === doShowROITablelButton) { - this.show(); - } else { - this.hide(); - } - } - - setState(roiTableVisible) { - if (true === roiTableVisible) { - this.button.classList.add('igv-navbar-button-clicked'); - } else { - this.button.classList.remove('igv-navbar-button-clicked'); - } - } - - show() { - this.button.style.display = 'block'; - this.setState(this.browser.roiTableVisible); - } - - hide() { - this.button.style.display = 'none'; - } - } - - // css - $igv-scrollbar-outer-width: 14px; - const igv_scrollbar_outer_width = 14; - - // css - $igv-track-drag-column-width: 12px; - const igv_track_manipulation_handle_width = 12; - - // css - $igv-track-gear-menu-column-width: 28px; - const igv_track_gear_menu_column_width = 28; - - // $igv-column-shim-width: 1px; - // $igv-column-shim-margin: 2px; - const column_multi_locus_shim_width = 2 + 1 + 2; - - const defaultSampleNameViewportWidth = 200; - - class Browser { - - constructor(config, parentDiv) { - - this.config = config; - this.guid = domUtils$1.guid(); - this.namespace = '.browser_' + this.guid; - - this.parent = parentDiv; - - this.root = domUtils$1.div({class: 'igv-container'}); - parentDiv.appendChild(this.root); - - this.alert = new Alert$2(this.root); - - this.columnContainer = domUtils$1.div({class: 'igv-column-container'}); - this.root.appendChild(this.columnContainer); - - this.menuPopup = new MenuPopup(this.columnContainer); - - this.initialize(config); - - this.trackViews = []; - - this.constants = { - dragThreshold: 3, - scrollThreshold: 5, - defaultColor: "rgb(0,0,150)", - doubleClickDelay: config.doubleClickDelay || 500 - }; - - // Map of event name -> [ handlerFn, ... ] - this.eventHandlers = {}; - - this.addMouseHandlers(); - - this.setControls(config); - } - - initialize(config) { - - if (config.gtex) { - GtexUtils.gtexLoaded = true; - } - this.flanking = config.flanking; - this.crossDomainProxy = config.crossDomainProxy; - this.formats = config.formats; - this.trackDefaults = config.trackDefaults; - this.nucleotideColors = config.nucleotideColors || defaultNucleotideColors; - for (let key of Object.keys(this.nucleotideColors)) { - this.nucleotideColors[key.toLowerCase()] = this.nucleotideColors[key]; - } - - this.trackLabelsVisible = config.showTrackLabels; - - this.roiTableVisible = config.showROITable; - this.showROITableButton = config.showROITableButton; - - this.isCenterLineVisible = config.showCenterGuide; - - this.cursorGuideVisible = config.showCursorGuide; - - this.showSampleNames = config.showSampleNames; - this.showSampleNameButton = config.showSampleNameButton; - this.sampleNameViewportWidth = config.sampleNameViewportWidth || defaultSampleNameViewportWidth; - - if (config.search) { - this.searchConfig = { - type: "json", - url: config.search.url, - coords: config.search.coords === undefined ? 1 : config.search.coords, - chromosomeField: config.search.chromosomeField || "chromosome", - startField: config.search.startField || "start", - endField: config.search.endField || "end", - geneField: config.search.geneField || "gene", - snpField: config.search.snpField || "snp", - resultsField: config.search.resultsField - }; - } - } - - setControls(config) { - - const $navBar = this.createStandardControls(config); - $navBar.insertBefore($$1(this.columnContainer)); - this.$navigation = $navBar; - - if (false === config.showControls) { - $navBar.hide(); - } - - } - - createStandardControls(config) { - - this.navbarManager = new NavbarManager(this); - - const $navBar = $$1('
', {class: 'igv-navbar'}); - this.$navigation = $navBar; - - const $navbarLeftContainer = $$1('
', {class: 'igv-navbar-left-container'}); - $navBar.append($navbarLeftContainer); - - // IGV logo - const $logo = $$1('
', {class: 'igv-logo'}); - $navbarLeftContainer.append($logo); - - const logoSvg = logo(); - logoSvg.css("width", "34px"); - logoSvg.css("height", "32px"); - $logo.append(logoSvg); - - this.$current_genome = $$1('
', {class: 'igv-current-genome'}); - $navbarLeftContainer.append(this.$current_genome); - this.$current_genome.text(''); - - const $genomicLocation = $$1('
', {class: 'igv-navbar-genomic-location'}); - $navbarLeftContainer.append($genomicLocation); - - // chromosome select widget - this.chromosomeSelectWidget = new ChromosomeSelectWidget(this, $genomicLocation.get(0)); - if (undefined === config.showChromosomeWidget) { - config.showChromosomeWidget = true; // Default to true - } - if (true === config.showChromosomeWidget) { - this.chromosomeSelectWidget.show(); - } else { - this.chromosomeSelectWidget.hide(); - } - - const $locusSizeGroup = $$1('
', {class: 'igv-locus-size-group'}); - $genomicLocation.append($locusSizeGroup); - - const $searchContainer = $$1('
', {class: 'igv-search-container'}); - $locusSizeGroup.append($searchContainer); - - // browser.$searchInput = $(''); - this.$searchInput = $$1('', {class: 'igv-search-input', type: 'text', placeholder: 'Locus Search'}); - $searchContainer.append(this.$searchInput); - - this.$searchInput.change(() => this.doSearch(this.$searchInput.val())); - - const searchIconContainer = domUtils$1.div({class: 'igv-search-icon-container'}); - $searchContainer.append($$1(searchIconContainer)); - - searchIconContainer.appendChild(icons$1$1.createIcon("search")); - - searchIconContainer.addEventListener('click', () => this.doSearch(this.$searchInput.val())); - - this.windowSizePanel = new WindowSizePanel($locusSizeGroup.get(0), this); - - const $navbarRightContainer = $$1('
', {class: 'igv-navbar-right-container'}); - $navBar.append($navbarRightContainer); - - const $toggle_button_container = $$1('
'); - $navbarRightContainer.append($toggle_button_container); - this.$toggle_button_container = $toggle_button_container; - - this.cursorGuide = new CursorGuide(this.columnContainer, this); - - this.cursorGuideButton = new CursorGuideButton(this, $toggle_button_container.get(0)); - - this.centerLineButton = new CenterLineButton(this, $toggle_button_container.get(0)); - - this.setTrackLabelVisibility(config.showTrackLabels); - this.trackLabelControl = new TrackLabelControl($toggle_button_container.get(0), this); - - // ROI Control - this.roiTableControl = new ROITableControl($toggle_button_container.get(0), this); - - this.sampleNameControl = new SampleNameControl($toggle_button_container.get(0), this); - - if (true === config.showSVGButton) { - this.svgSaveControl = new SVGSaveControl($toggle_button_container.get(0), this); - } - - if (config.customButtons) { - for (let b of config.customButtons) { - new CustomButton($toggle_button_container.get(0), this, b); - } - } - - this.zoomWidget = new ZoomWidget(this, $navbarRightContainer.get(0)); - - if (false === config.showNavigation) { - this.$navigation.hide(); - } - - this.inputDialog = new InputDialog$1(this.root); - this.inputDialog.container.id = `igv-input-dialog-${domUtils$1.guid()}`; - - this.dataRangeDialog = new DataRangeDialog$1(this, $$1(this.root)); - this.dataRangeDialog.$container.get(0).id = `igv-data-range-dialog-${domUtils$1.guid()}`; - - this.genericColorPicker = new GenericColorPicker({parent: this.columnContainer, width: 432}); - this.genericColorPicker.container.id = `igv-track-color-picker-${domUtils$1.guid()}`; - - return $navBar - - } - - getSampleNameViewportWidth() { - return false === this.showSampleNames ? 0 : this.sampleNameViewportWidth - } - - isMultiLocusMode() { - return this.referenceFrameList && this.referenceFrameList.length > 1 - }; - - addTrackToFactory(name, track) { - TrackFactory.addTrack(name, track); - } - - isMultiLocusWholeGenomeView() { - - if (undefined === this.referenceFrameList || 1 === this.referenceFrameList.length) { - return false - } - - for (let referenceFrame of this.referenceFrameList) { - if ('all' === referenceFrame.chr.toLowerCase()) { - return true - } - } - - return false - }; - - /** - * PUBLIC API FUNCTION - * - * Return the current genomic region as a locus string, or array of locus strings if in multi-locus view - * @returns {string|*[]|*} - */ - currentLoci() { - const noCommaLocusString = (rf) => `${rf.chr}:${rf.start + 1}-${rf.end}`; - if (undefined === this.referenceFrameList || 0 === this.referenceFrameList.length) { - return "" - } else if (1 === this.referenceFrameList.length) { - return noCommaLocusString(this.referenceFrameList[0]) - } else { - return this.referenceFrameList.map(rf => noCommaLocusString(rf)) - } - } - - /** - * Render browse display as SVG - * @returns {string} - */ - toSVG() { - - const {y, width, height} = this.columnContainer.getBoundingClientRect(); - - const h_render = 8000; - - const config = - { - - width, - height: h_render, - - backdropColor: 'white', - - multiLocusGap: 0, - - viewbox: - { - x: 0, - y: 0, - width, - height: h_render - } - - }; - - const context = new ctx(config); - - // tracks -> SVG - const delta = {deltaX: 0, deltaY: -y}; - for (let trackView of this.trackViews) { - trackView.renderSVGContext(context, delta); - } - - this.roiManager.renderSVGContext(context, delta); - - // reset height to trim away unneeded svg canvas real estate. Yes, a bit of a hack. - context.setHeight(height); - - return context.getSerializedSvg(true) - - } - - renderSVG($container) { - const svg = this.toSVG(); - $container.empty(); - $container.append(svg); - - return svg - } - - saveSVGtoFile(config) { - - let svg = this.toSVG(); - - if (config.$container) { - config.$container.empty(); - config.$container.append(svg); - } - - const path = config.filename || 'igvjs.svg'; - const data = URL.createObjectURL(new Blob([svg], {type: "application/octet-stream"})); - download(path, data); - } - - /** - * Initialize a session from an object, json, or by loading from a file. - * - * TODO Really should be split into at least 2 functions, load from file and load from object/json - * - * @param options - * @returns {*} - */ - async loadSession(options) { - - // TODO: depricated - this.roiSets = []; - - let session; - if (options.url || options.file) { - session = await loadSessionFile(options); - } else { - session = options; - } - return this.loadSessionObject(session) - - - async function loadSessionFile(options) { - - const urlOrFile = options.url || options.file; - - if (options.url && (options.url.startsWith("blob:") || options.url.startsWith("data:"))) { - const json = Browser.uncompressSession(options.url); - return JSON.parse(json) - - } else { - let filename = options.filename; - if (!filename) { - filename = (options.url ? await getFilename$1(options.url) : options.file.name); - } - - if (filename.endsWith(".xml")) { - - const knownGenomes = GenomeUtils.KNOWN_GENOMES; - const string = await igvxhr.loadString(urlOrFile); - return new XMLSession(string, knownGenomes) - - } else if (filename.endsWith(".json")) { - return igvxhr.loadJson(urlOrFile) - } else { - return undefined - } - } - } - } - - - /** - * Note: public API function - * @param session - * @returns {Promise} - */ - async loadSessionObject(session) { - - // prepare to load a new session, discarding DOM and state - this.cleanHouseForSession(); - - this.showSampleNames = session.showSampleNames || false; - this.sampleNameControl.setState(this.showSampleNames === true); - - if (session.sampleNameViewportWidth) { - this.sampleNameViewportWidth = session.sampleNameViewportWidth; - } - - // axis column - createColumn(this.columnContainer, 'igv-axis-column'); - - // SampleName column - createColumn(this.columnContainer, 'igv-sample-name-column'); - - // Track scrollbar column - createColumn(this.columnContainer, 'igv-scrollbar-column'); - - // Track drag/reorder column - createColumn(this.columnContainer, 'igv-track-drag-column'); - - // Track gear column - createColumn(this.columnContainer, 'igv-gear-menu-column'); - - const genomeOrReference = session.reference || session.genome; - if(!genomeOrReference) { - console.warn("No genome or reference object specified"); - return; - } - const genomeConfig = await GenomeUtils.expandReference(this.alert, genomeOrReference); - - - await this.loadReference(genomeConfig, session.locus); - - this.centerLineList = this.createCenterLineList(this.columnContainer); - - // Create ideogram and ruler track. Really this belongs in browser initialization, but creation is - // deferred because ideogram and ruler are treated as "tracks", and tracks require a reference frame - let ideogramHeight = 0; - if (false !== session.showIdeogram) { - - const track = new IdeogramTrack(this); - track.id = 'ideogram'; - - const trackView = new TrackView(this, this.columnContainer, track); - const {$viewport} = trackView.viewports[0]; - ideogramHeight = getElementAbsoluteHeight($viewport.get(0)); - - this.trackViews.push(trackView); - } - - if (false !== session.showRuler) { - this.trackViews.push(new TrackView(this, this.columnContainer, new RulerTrack(this))); - } - - // Restore gtex selections. - if (session.gtexSelections) { - for (let referenceFrame of this.referenceFrameList) { - for (let s of Object.keys(session.gtexSelections)) { - const gene = session.gtexSelections[s].gene; - const snp = session.gtexSelections[s].snp; - referenceFrame.selection = new GtexSelection(gene, snp); - } - } - } - - if (this.roiManager) { - this.roiManager.dispose(); - } - - const roiMenu = new ROIMenu(this, this.columnContainer); - const roiTableConfig = - { - browser: this, - parent: this.columnContainer, - headerTitle: 'Regions of Interest', - dismissHandler: () => this.roiTableControl.buttonHandler(false), - gotoButtonHandler: ROITable.gotoButtonHandler - }; - if (session.roi) { - - const roiSetList = session.roi.map(c => new ROISet(c, this.genome)); - - const named = roiSetList.filter(({name}) => name !== undefined && name.length > 0); - - roiTableConfig.columnFormat = ROITable.getColumnFormatConfiguration(named.length > 0); - - const roiTable = new ROITable(roiTableConfig); - - this.roiManager = new ROIManager(this, roiMenu, roiTable, ideogramHeight, roiSetList); - } else { - - roiTableConfig.columnFormat = ROITable.getColumnFormatConfiguration(false); - - const roiTable = new ROITable(roiTableConfig); - - this.roiManager = new ROIManager(this, roiMenu, roiTable, ideogramHeight, undefined); - } - - await this.roiManager.initialize(); - - // Tracks. Start with genome tracks, if any, then append session tracks - const genomeTracks = genomeConfig.tracks || []; - const trackConfigurations = session.tracks ? genomeTracks.concat(session.tracks) : genomeTracks; - - // Ensure that we always have a sequence track with no explicit URL (=> the reference genome sequence track) - const pushSequenceTrack = trackConfigurations.filter(track => 'sequence' === track.type && !track.url && !track.fastaURL).length === 0; - if (pushSequenceTrack /*&& false !== this.config.showSequence*/) { - trackConfigurations.push({type: "sequence", order: defaultSequenceTrackOrder}); - } - - // Maintain track order unless explicitly set - let trackOrder = 1; - for (let t of trackConfigurations) { - if (undefined === t.order) { - t.order = trackOrder++; - } - } - - await this.loadTrackList(trackConfigurations); - - // The ruler and ideogram tracks are not explicitly loaded, but needs updated nonetheless. - for (let rtv of this.trackViews.filter((tv) => tv.track.type === 'ruler' || tv.track.type === 'ideogram')) { - rtv.updateViews(); - } - - this.updateUIWithReferenceFrameList(); - - } - - createCenterLineList(columnContainer) { - - const centerLines = columnContainer.querySelectorAll('.igv-center-line'); - for (let i = 0; i < centerLines.length; i++) { - centerLines[i].remove(); - } - - const centerLineList = []; - const viewportColumns = columnContainer.querySelectorAll('.igv-column'); - for (let i = 0; i < viewportColumns.length; i++) { - centerLineList.push(new ViewportCenterLine(this, this.referenceFrameList[i], viewportColumns[i])); - } - - return centerLineList - } - - /** - * Load a reference genome object. This includes the fasta, and optional cytoband, but no tracks. This method - * is used by loadGenome and loadSession. - * - * @param genomeConfig - * @param initialLocus - */ - async loadReference(genomeConfig, initialLocus) { - - const genome = await GenomeUtils.loadGenome(genomeConfig); - - const genomeChange = undefined === this.genome || (this.genome.id !== genome.id); - - this.genome = genome; - - this.updateNavbarDOMWithGenome(genome); - - if (genomeChange) { - this.removeAllTracks(); - } - - let locus = getInitialLocus(initialLocus, genome); - const locusFound = await this.search(locus, true); - if (!locusFound) { - console.log("Initial locus not found: " + locus); - locus = genome.getHomeChromosomeName(); - const locusFound = await this.search(locus, true); - if (!locusFound) { - throw new Error("Cannot set initial locus") - } - } - - if (genomeChange && this.circularView) { - this.circularView.setAssembly({ - name: this.genome.id, - id: this.genome.id, - chromosomes: makeCircViewChromosomes(this.genome) - }); - } - } - - cleanHouseForSession() { - - for (let trackView of this.trackViews) { - // empty axis column, viewport columns, sampleName column, scroll column, drag column, gear column - trackView.removeDOMFromColumnContainer(); - } - - // discard all columns - const elements = this.columnContainer.querySelectorAll('.igv-axis-column, .igv-column-shim, .igv-column, .igv-sample-name-column, .igv-scrollbar-column, .igv-track-drag-column, .igv-gear-menu-column'); - elements.forEach(column => column.remove()); - - this.trackViews = []; - - if (this.circularView) { - this.circularView.clearChords(); - } - - } - - updateNavbarDOMWithGenome(genome) { - - // If the genome is defined directly from a fasta file or data url the "id" will be the full url. Don't display - // this. - let genomeLabel = (genome.id && genome.id.length < 10 ? genome.id : ''); - this.$current_genome.text(genomeLabel); - this.$current_genome.attr('title', genome.id || ''); - this.chromosomeSelectWidget.update(genome); - } - - /** - * Load a genome, defined by a string ID or a json-like configuration object. This includes a fasta reference - * as well as optional cytoband and annotation tracks. - * - * @param idOrConfig - * @returns genome - */ - async loadGenome(idOrConfig) { - - const genomeConfig = await GenomeUtils.expandReference(this.alert, idOrConfig); - await this.loadReference(genomeConfig, undefined); - - const tracks = genomeConfig.tracks || []; - - // Insure that we always have a sequence track - const pushSequenceTrack = tracks.filter(track => track.type === 'sequence').length === 0; - if (pushSequenceTrack) { - tracks.push({type: "sequence", order: defaultSequenceTrackOrder}); - } - - await this.loadTrackList(tracks); - - await this.updateViews(); - - return this.genome - } - - /** - * Called after a session load, search, pan (horizontal drag), or resize - * - * @param referenceFrameList - */ - updateUIWithReferenceFrameList() { - - const referenceFrameList = this.referenceFrameList; - - this.updateLocusSearchWidget(); - - const isWGV = (this.isMultiLocusWholeGenomeView() || GenomeUtils.isWholeGenomeView(referenceFrameList[0].chr)); - - this.navbarManager.navbarDidResize(this.$navigation.width(), isWGV); - - toggleTrackLabels(this.trackViews, this.trackLabelsVisible); - - this.setCenterLineAndCenterLineButtonVisibility(!GenomeUtils.isWholeGenomeView(referenceFrameList[0].chr)); - - } - - setTrackLabelVisibility(isVisible) { - toggleTrackLabels(this.trackViews, isVisible); - } - - setROITableVisibility(isVisible) { - true === isVisible ? this.roiManager.presentTable() : this.roiManager.dismissTable(); - } - - // cursor guide - setCursorGuideVisibility(cursorGuideVisible) { - - if (cursorGuideVisible) { - this.cursorGuide.show(); - } else { - this.cursorGuide.hide(); - } - } - - setCustomCursorGuideMouseHandler(mouseHandler) { - this.cursorGuide.customMouseHandler = mouseHandler; - } - - // center line - setCenterLineVisibility(isCenterLineVisible) { - for (let centerLine of this.centerLineList) { - if (true === isCenterLineVisible) { - centerLine.show(); - centerLine.repaint(); - } else { - centerLine.hide(); - } - } - } - - setCenterLineAndCenterLineButtonVisibility(isCenterLineVisible) { - - for (let centerLine of this.centerLineList) { - const isShown = isCenterLineVisible && centerLine.isVisible; - isShown ? centerLine.show() : centerLine.container.style.display = 'none'; - } - - const isShown = isCenterLineVisible && this.centerLineButton.isVisible; - isShown ? this.centerLineButton.show() : this.centerLineButton.button.style.display = 'none'; - - } - - /** - * Public API function. Load a list of tracks. - * - * @param configList Array of track configurations - * @returns {Promise<*>} Promise for track objects - */ - async loadTrackList(configList) { - - const promises = []; - for (let config of configList) { - promises.push(this._loadTrack(config)); - } - - const loadedTracks = await Promise.all(promises); - const groupAutoscaleViews = this.trackViews.filter(function (trackView) { - return trackView.track.autoscaleGroup - }); - if (groupAutoscaleViews.length > 0) { - this.updateViews(); - } - return loadedTracks - } - - /** - * Public API function - * - * Load an individual track. If part of an autoscale group force a general update - * - * @param config A track configuration - * @returns {Promise<*>} Promise for track object - */ - async loadTrack(config) { - - const newTrack = this._loadTrack(config); - - if (config.autoscaleGroup) { - // Await newTrack load and update all views - await newTrack; - this.updateViews(); - } - - return newTrack - } - - /** - * Return a promise to load a track. Private function used by loadTrack() and loadTrackList() - * - * @param config - * @returns {*} - */ - - async _loadTrack(config) { - - // config might be json - if (isString$2(config)) { - config = JSON.parse(config); - } - - try { - - const newTrack = await this.createTrack(config); - - if (undefined === newTrack) { - return - } - - // Set order field of track here. Otherwise track order might get shuffled during asynchronous load - if (undefined === newTrack.order) { - newTrack.order = this.trackViews.length; - } - - const trackView = new TrackView(this, this.columnContainer, newTrack); - this.trackViews.push(trackView); - toggleTrackLabels(this.trackViews, this.trackLabelsVisible); - this.reorderTracks(); - this.fireEvent('trackorderchanged', [this.getTrackOrder()]); - - if (typeof newTrack.postInit === 'function') { - try { - trackView.startSpinner(); - await newTrack.postInit(); - } finally { - trackView.stopSpinner(); - } - } - - if (!newTrack.autoscaleGroup) { - // Group autoscale will get updated later (as a group) - if (config.sync) { - await trackView.updateViews(); - } else { - trackView.updateViews(); - } - } - - if (typeof newTrack.hasSamples === 'function' && newTrack.hasSamples()) { - if (this.config.showSampleNameButton !== false) { - this.sampleNameControl.show(); // If not explicitly set - } - } - - return newTrack - - } catch (error) { - const httpMessages = - { - "401": "Access unauthorized", - "403": "Access forbidden", - "404": "Not found" - }; - console.error(error); - let msg = error.message || error.error || error.toString(); - if (httpMessages.hasOwnProperty(msg)) { - msg = httpMessages[msg]; - } - msg += (": " + config.url); - this.alert.present(new Error(msg), undefined); - } - } - - /** - * Public API function - load a region of interest - * - * @param config A "track" configuration object, or array of objects, of type == "annotation" (bed, gff, etc) - * - * @returns {Promise} - */ - async loadROI(config) { - await this.roiManager.loadROI(config, this.genome); - } - - /** - * Public API function - clear all regions of interest (ROI), including preloaded and user-defined ROIs - */ - clearROIs() { - this.roiManager.clearROIs(); - } - - /** - * Public API function. Return a promise for the list of user-defined regions-of-interest - */ - async getUserDefinedROIs() { - - if (this.roiManager) { - - const set = await this.roiManager.getUserDefinedROISet(); - if (undefined === set) { - return [] - } - - const featureHash = await set.getAllFeatures(); - const featureList = []; - for (let value of Object.values(featureHash)) { - featureList.push(...value); - } - - return featureList - - } else { - return [] - } - } - - getRulerTrackView() { - const list = this.trackViews.filter(({track}) => 'ruler' === track.id); - return list.length > 0 ? list[0] : undefined - } - - /** - * Create a Track object. - * @param config - * @returns {Promise<*>} - */ - async createTrack(config) { - - // Resolve function and promise urls - let url = await resolveURL(config.url || config.fastaURL); - if (isString$2(url)) { - url = url.trim(); - } - - if (url) { - if (config.format) { - config.format = config.format.toLowerCase(); - } else if (config.fastaURL) { - config.format = "fasta"; // by definition - } else { - let filename = config.filename; - if (!filename) { - filename = await getFilename$1(url); - } - - const format = inferFileFormat(filename); - - if ("tsv" === format) { - config.format = await inferFileFormatFromHeader(config); - } else if (format) { - config.format = format; - } else { - if (config.sourceType === "htsget") { - // Check for htsget URL. This is a longshot - await HtsgetReader.inferFormat(config); - } - } - } - } - - - let type = config.type ? config.type.toLowerCase() : undefined; - - if (!type) { - type = inferTrackType(config); - if ("bedtype" === type) { - // Bed files must be read to determine track type - const featureSource = FeatureSource(config, this.genome); - config._featureSource = featureSource; // This is a temp variable, bit of a hack - const trackType = await featureSource.trackType(); - if (trackType) { - type = trackType; - } else { - type = "annotation"; - } - } - // Record in config to make type persistent in session - config.type = type; - } - - // Set defaults if specified - if (this.trackDefaults && type) { - const settings = this.trackDefaults[type]; - if (settings) { - for (let property in settings) { - if (settings.hasOwnProperty(property) && config[property] === undefined) { - config[property] = settings[property]; - } - } - } - } - - const track = TrackFactory.getTrack(type, config, this); - if (undefined === track) { - this.alert.present(new Error(`Error creating track. Could not determine track type for file: ${config.url || config}`), undefined); - } else { - - if (config.roi && config.roi.length > 0) { - track.roiSets = config.roi.map(r => new TrackROISet(r, this.genome)); - } - - return track - } - } - - - reorderTracks() { - - this.trackViews.sort(function (a, b) { - - const firstSortOrder = tv => { - return 'ideogram' === tv.track.id ? 1 : - 'ruler' === tv.track.id ? 2 : - 3 - }; - - const aOrder1 = firstSortOrder(a); - const bOrder1 = firstSortOrder(b); - if (aOrder1 === bOrder1) { - const aOrder2 = a.track.order || 0; - const bOrder2 = b.track.order || 0; - return aOrder2 - bOrder2 - } else { - return aOrder1 - bOrder1 - } - }); - - // discard current track order - for (let {axis, viewports, sampleNameViewport, outerScroll, dragHandle, gearContainer} of this.trackViews) { - - axis.remove(); - - for (let {$viewport} of viewports) { - $viewport.detach(); - } - - sampleNameViewport.viewport.remove(); - - outerScroll.remove(); - dragHandle.remove(); - gearContainer.remove(); - } - - // Reattach the divs to the dom in the correct order - const viewportColumns = this.columnContainer.querySelectorAll('.igv-column'); - - for (let {axis, viewports, sampleNameViewport, outerScroll, dragHandle, gearContainer} of this.trackViews) { - - this.columnContainer.querySelector('.igv-axis-column').appendChild(axis); - - for (let i = 0; i < viewportColumns.length; i++) { - const {$viewport} = viewports[i]; - viewportColumns[i].appendChild($viewport.get(0)); - } - - this.columnContainer.querySelector('.igv-sample-name-column').appendChild(sampleNameViewport.viewport); - - this.columnContainer.querySelector('.igv-scrollbar-column').appendChild(outerScroll); - - this.columnContainer.querySelector('.igv-track-drag-column').appendChild(dragHandle); - - this.columnContainer.querySelector('.igv-gear-menu-column').appendChild(gearContainer); - } - - } - - getTrackOrder() { - return this.trackViews.filter(tv => tv.track && tv.track.name).map(tv => tv.track.name) - } - - /** - * NOTE: Public API function - * - * Remove all tracks matching the given name. Usually this will be a single track, but there is no - * guarantee names are unique - * - * @param name - */ - removeTrackByName(name) { - const copy = this.trackViews.slice(); - for (let trackView of copy) { - if (name === trackView.track.name) { - this.removeTrack(trackView.track); - } - } - } - - /** - * NOTE: Public API function - * - * Remove the given track. If it has already been removed this is a no-op. - * - * @param track - */ - removeTrack(track) { - for (let trackView of this.trackViews) { - if (track === trackView.track) { - this._removeTrack(trackView.track); - break - } - } - } - - _removeTrack(track) { - if (track.disposed) return - this.trackViews.splice(this.trackViews.indexOf(track.trackView), 1); - this.fireEvent('trackremoved', [track]); - this.fireEvent('trackorderchanged', [this.getTrackOrder()]); - if (track.trackView) { - track.trackView.dispose(); - } - } - - /** - * API function - */ - removeAllTracks() { - - const remainingTrackViews = []; - - for (let trackView of this.trackViews) { - - if (trackView.track.id !== 'ruler' && trackView.track.id !== 'ideogram') { - this.fireEvent('trackremoved', [trackView.track]); - trackView.dispose(); - } else { - remainingTrackViews.push(trackView); - } - } - - this.trackViews = remainingTrackViews; - } - - /** - * - * @param property - * @param value - * @returns {Array} tracks with given property value. e.g. findTracks("type", "annotation") - */ - findTracks(property, value) { - - let f = typeof property === 'function' ? - trackView => property(trackView.track) : - trackView => value === trackView.track[property]; - - return this.trackViews.filter(f).map(tv => tv.track) - } - - /** - * Set the track height globally for all tracks. (Note: Its not clear why this is useful). - * @param newHeight - */ - setTrackHeight(newHeight) { - - this.trackHeight = newHeight; - - this.trackViews.forEach(function (trackView) { - trackView.setTrackHeight(newHeight); - }); - - } - - /** - * API function to signal that this browser visibility has changed, e.g. from hiding/showing in a tab interface. - * - * @returns {Promise} - */ - async visibilityChange() { - this.layoutChange(); - } - - async layoutChange() { - - const status = this.referenceFrameList.find(referenceFrame => referenceFrame.bpPerPixel < 0); - - if (status) { - const viewportWidth = this.calculateViewportWidth(this.referenceFrameList.length); - for (let referenceFrame of this.referenceFrameList) { - referenceFrame.bpPerPixel = (referenceFrame.end - referenceFrame.start) / viewportWidth; - } - } - - if (this.referenceFrameList) { - const isWGV = this.isMultiLocusWholeGenomeView() || GenomeUtils.isWholeGenomeView(this.referenceFrameList[0].chr); - this.navbarManager.navbarDidResize(this.$navigation.width(), isWGV); - } - - resize.call(this); - await this.updateViews(); - } - - async updateViews() { - - const trackViews = this.trackViews; - - this.updateLocusSearchWidget(); - - for (let centerGuide of this.centerLineList) { - centerGuide.repaint(); - } - - // Don't autoscale while dragging. - if (this.dragObject) { - for (let trackView of trackViews) { - await trackView.updateViews(); - } - } else { - // Group autoscale - const groupAutoscaleTracks = {}; - const otherTracks = []; - for (let trackView of trackViews) { - const group = trackView.track.autoscaleGroup; - if (group) { - var l = groupAutoscaleTracks[group]; - if (!l) { - l = []; - groupAutoscaleTracks[group] = l; - } - l.push(trackView); - } else { - otherTracks.push(trackView); - } - } - - if (Object.entries(groupAutoscaleTracks).length > 0) { - - const keys = Object.keys(groupAutoscaleTracks); - for (let group of keys) { - - const groupTrackViews = groupAutoscaleTracks[group]; - const promises = []; - - for (let trackView of groupTrackViews) { - promises.push(trackView.getInViewFeatures()); - } - - const featureArray = await Promise.all(promises); - - var allFeatures = [], dataRange; - - for (let features of featureArray) { - allFeatures = allFeatures.concat(features); - } - dataRange = doAutoscale$1(allFeatures); - - const p = []; - for (let trackView of groupTrackViews) { - trackView.track.dataRange = dataRange; - trackView.track.autoscale = false; - p.push(trackView.updateViews()); - } - await Promise.all(p); - } - - } - - await Promise.all(otherTracks.map(tv => tv.updateViews())); - // for (let trackView of otherTracks) { - // await trackView.updateViews(force); - // } - } - - } - - repaintViews() { - for (let trackView of this.trackViews) { - trackView.repaintViews(); - } - } - - updateLocusSearchWidget() { - - if(!this.referenceFrameList) return - const referenceFrameList = this.referenceFrameList; - - // Update end position of reference frames based on pixel widths. This is hacky, but its been done here - // for a long time, although indirectly. - const width = this.calculateViewportWidth(this.referenceFrameList.length); - for (let referenceFrame of referenceFrameList) { - referenceFrame.end = referenceFrame.start + referenceFrame.bpPerPixel * width; - } - - this.chromosomeSelectWidget.select.value = referenceFrameList.length === 1 ? this.referenceFrameList[0].chr : ''; - - const loc = this.referenceFrameList.map(rf => rf.getLocusString()).join(' '); - //const loc = this.referenceFrameList.length === 1 ? this.referenceFrameList[0].getLocusString() : ''; - this.$searchInput.val(loc); - - this.fireEvent('locuschange', [this.referenceFrameList]); - } - - calculateViewportWidth(columnCount) { - - let {width} = this.columnContainer.getBoundingClientRect(); - - const sampleNameViewportWidth = this.getSampleNameViewportWidth(); - - width -= igv_axis_column_width + sampleNameViewportWidth + igv_scrollbar_outer_width + igv_track_manipulation_handle_width + igv_track_gear_menu_column_width; - - width -= column_multi_locus_shim_width * (columnCount - 1); - - return Math.floor(width / columnCount) - } - - getCenterLineXOffset() { - let {width: columnContainerWidth} = this.columnContainer.getBoundingClientRect(); - columnContainerWidth -= igv_axis_column_width + this.getSampleNameViewportWidth() + igv_scrollbar_outer_width + igv_track_manipulation_handle_width + igv_track_gear_menu_column_width; - return Math.floor(columnContainerWidth / 2 + igv_axis_column_width) - } - - minimumBases() { - return this.config.minimumBases - } - - // Zoom in by a factor of 2, keeping the same center location - zoomIn() { - this.zoomWithScaleFactor(0.5); - }; - - // Zoom out by a factor of 2, keeping the same center location if possible - zoomOut() { - this.zoomWithScaleFactor(2.0); - }; - - async zoomWithScaleFactor(scaleFactor, centerBPOrUndefined, referenceFrameOrUndefined) { - - if(!this.referenceFrameList) return - - const viewportWidth = this.calculateViewportWidth(this.referenceFrameList.length); - - let referenceFrames = referenceFrameOrUndefined ? [referenceFrameOrUndefined] : this.referenceFrameList; - - for (let referenceFrame of referenceFrames) { - referenceFrame.zoomWithScaleFactor(this, scaleFactor, viewportWidth, centerBPOrUndefined); - } - } - - /** - * Add a new multi-locus panel for the specified region - * @param chr - * @param start - * @param end - * @param referenceFrameLeft - optional, if supplied new panel should be placed to the immediate right - */ - async addMultiLocusPanel(chr, start, end, referenceFrameLeft) { - - if(!this.referenceFrameList) return - - // account for reduced viewport width as a result of adding right mate pair panel - const viewportWidth = this.calculateViewportWidth(1 + this.referenceFrameList.length); - const scaleFactor = this.calculateViewportWidth(this.referenceFrameList.length) / this.calculateViewportWidth(1 + this.referenceFrameList.length); - for (let refFrame of this.referenceFrameList) { - refFrame.bpPerPixel *= scaleFactor; - } - - const bpp = (end - start) / viewportWidth; - const newReferenceFrame = new ReferenceFrame(this.genome, chr, start, end, bpp); - const indexLeft = referenceFrameLeft ? this.referenceFrameList.indexOf(referenceFrameLeft) : this.referenceFrameList.length - 1; - const indexRight = 1 + indexLeft; - - // TODO -- this is really ugly - const {$viewport} = this.trackViews[0].viewports[indexLeft]; - const viewportColumn = viewportColumnManager.insertAfter($viewport.get(0).parentElement); - - if (indexRight === this.referenceFrameList.length) { - this.referenceFrameList.push(newReferenceFrame); - for (let trackView of this.trackViews) { - const viewport = createViewport(trackView, viewportColumn, newReferenceFrame); - trackView.viewports.push(viewport); - } - } else { - this.referenceFrameList.splice(indexRight, 0, newReferenceFrame); - for (let trackView of this.trackViews) { - const viewport = createViewport(trackView, viewportColumn, newReferenceFrame); - trackView.viewports.splice(indexRight, 0, viewport); - } - } - - - this.centerLineList = this.createCenterLineList(this.columnContainer); - - resize.call(this); - await this.updateViews(true); - } - - async removeMultiLocusPanel(referenceFrame) { - - // find the $column corresponding to this referenceFrame and remove it - const index = this.referenceFrameList.indexOf(referenceFrame); - const {$viewport} = this.trackViews[0].viewports[index]; - viewportColumnManager.removeColumnAtIndex(index, $viewport.parent().get(0)); - - for (let {viewports} of this.trackViews) { - viewports[index].dispose(); - viewports.splice(index, 1); - } - - this.referenceFrameList.splice(index, 1); - - if (1 === this.referenceFrameList.length && this.getRulerTrackView()) { - for (let rulerViewport of this.getRulerTrackView().viewports) { - rulerViewport.dismissLocusLabel(); - } - } - - const scaleFactor = this.calculateViewportWidth(1 + this.referenceFrameList.length) / this.calculateViewportWidth(this.referenceFrameList.length); - - await this.rescaleForMultiLocus(scaleFactor); - - } - - /** - * Goto the locus represented by the selected referenceFrame, discarding all other panels - * - * @param referenceFrame - * @returns {Promise} - */ - async gotoMultilocusPanel(referenceFrame) { - - const referenceFrameIndex = this.referenceFrameList.indexOf(referenceFrame); - - // Remove columns for unselected panels - this.columnContainer.querySelectorAll('.igv-column').forEach((column, c) => { - if (c === referenceFrameIndex) ; else { - column.remove(); - } - }); - - // Remove all column shims - this.columnContainer.querySelectorAll('.igv-column-shim').forEach(shim => shim.remove()); - - // Discard viewports - for (let trackView of this.trackViews) { - const retain = trackView.viewports[referenceFrameIndex]; - trackView.viewports.filter((viewport, i) => i !== referenceFrameIndex).forEach(viewport => viewport.dispose()); - trackView.viewports = [retain]; - } - - const viewportWidth = this.calculateViewportWidth(1); - referenceFrame.bpPerPixel = (referenceFrame.end - referenceFrame.start) / viewportWidth; - this.referenceFrameList = [referenceFrame]; - - this.trackViews.forEach(({viewports}) => viewports.forEach(viewport => viewport.setWidth(viewportWidth))); - - this.centerLineList = this.createCenterLineList(this.columnContainer); - - this.updateUIWithReferenceFrameList(); - - await this.updateViews(true); - - } - - async rescaleForMultiLocus(scaleFactor) { - - const viewportWidth = this.calculateViewportWidth(this.referenceFrameList.length); - - for (let referenceFrame of this.referenceFrameList) { - referenceFrame.bpPerPixel *= scaleFactor; - } - - for (let {viewports} of this.trackViews) { - - for (let viewport of viewports) { - viewport.setWidth(viewportWidth); - } - } - - this.centerLineList = this.createCenterLineList(this.columnContainer); - - this.updateUIWithReferenceFrameList(); - - await this.updateViews(); - - } - - /** - * @deprecated This is a deprecated method with no known usages. To be removed in a future release. - */ - async goto(chr, start, end) { - await this.search(chr + ":" + start + "-" + end); - } - - /** - - * Search for the locus string -- this function is called from various igv.js GUI elements, and is not part of the - * API. Wraps ```search``` and presents an error dialog if false. - * - * @param string - * @param init - * @returns {Promise} - */ - async doSearch(string, init) { - const success = await this.search(string, init); - if (!success) { - this.alert.present(new Error(`Unrecognized locus: ${string} `)); - } - return success - } - - - /** - * Search for the locus string - * NOTE: This is part of the API - * @param string - * @param init true if called during browser initialization - * @returns {Promise} true if found, false if not - */ - async search(string, init) { - - const loci = await search(this, string); - - if (loci && loci.length > 0) { - - // create reference frame list based on search loci - this.referenceFrameList = createReferenceFrameList(loci, this.genome, this.flanking, this.minimumBases(), this.calculateViewportWidth(loci.length), this.isSoftclipped()); - - // discard viewport DOM elements - for (let trackView of this.trackViews) { - // empty axis column, viewport columns, sampleName column, scroll column, drag column, gear column - trackView.removeDOMFromColumnContainer(); - } - - // discard ONLY viewport columns - this.columnContainer.querySelectorAll('.igv-column-shim, .igv-column').forEach(el => el.remove()); - - // Insert viewport columns preceding the sample-name column - viewportColumnManager.insertBefore(this.columnContainer.querySelector('.igv-sample-name-column'), this.referenceFrameList.length); - - this.centerLineList = this.createCenterLineList(this.columnContainer); - - // Populate the columns - for (let trackView of this.trackViews) { - trackView.addDOMToColumnContainer(this, this.columnContainer, this.referenceFrameList); - } - - this.updateUIWithReferenceFrameList(); - - if (!init) { - await this.updateViews(); - } - return true - } else { - return false - } - } - - async loadSampleInformation(url) { - var name = url; - if (isFile$1(url)) { - name = url.name; - } - var ext = name.substr(name.lastIndexOf('.') + 1); - if (ext === 'fam') { - this.sampleInformation = await loadPlinkFile(url); - } - }; - - // EVENTS - - on(eventName, fn) { - if (!this.eventHandlers[eventName]) { - this.eventHandlers[eventName] = []; - } - this.eventHandlers[eventName].push(fn); - }; - - /** - * @deprecated use off() - * @param eventName - * @param fn - */ - un(eventName, fn) { - this.off(eventName, fn); - }; - - off(eventName, fn) { - - if (!eventName) { - this.eventHandlers = {}; // Remove all event handlers - } else if (!fn) { - this.eventHandlers[eventName] = []; // Remove all eventhandlers matching name - } else { - // Remove specific event handler - const handlers = this.eventHandlers[eventName]; - if (!handlers || handlers.length === 0) { - console.warn("No handlers to remove for event: " + eventName); - } else { - const callbackIndex = handlers.indexOf(fn); - if (callbackIndex !== -1) { - this.eventHandlers[eventName].splice(callbackIndex, 1); - } - } - } - } - - fireEvent(eventName, args, thisObj) { - - const handlers = this.eventHandlers[eventName]; - if (undefined === handlers || handlers.length === 0) { - return undefined - } - - const scope = thisObj || window; - const results = handlers.map(function (event) { - return event.apply(scope, args) - }); - - return results[0] - } - - dispose() { - this.removeMouseHandlers(); - for (let trackView of this.trackViews) { - trackView.dispose(); - } - } - - /** - * Return a json-like object (note not a json string) representing the current state. - * - */ - toJSON() { - - const json = { - "version": version$2() - }; - - if (this.showSampleNames !== undefined) { - json['showSampleNames'] = this.showSampleNames; - } - if (this.sampleNameViewportWidth !== defaultSampleNameViewportWidth) { - json['sampleNameViewportWidth'] = this.sampleNameViewportWidth; - } - - json["reference"] = this.genome.toJSON(); - if (json.reference.fastaURL instanceof File) { // Test specifically for File. Other types of File-like objects might be savable) { - throw new Error(`Error. Sessions cannot include local file references ${json.reference.fastaURL.name}.`) - } else if (json.reference.indexURL instanceof File) { // Test specifically for File. Other types of File-like objects might be savable) { - throw new Error(`Error. Sessions cannot include local file references ${json.reference.indexURL.name}.`) - } - - // Build locus array (multi-locus view). Use the first track to extract the loci, any track could be used. - const locus = []; - const gtexSelections = {}; - let hasGtexSelections = false; - let anyTrackView = this.trackViews[0]; - for (let {referenceFrame} of anyTrackView.viewports) { - const locusString = referenceFrame.getLocusString(); - locus.push(locusString); - if (referenceFrame.selection) { - const selection = { - gene: referenceFrame.selection.gene, - snp: referenceFrame.selection.snp - }; - gtexSelections[locusString] = selection; - hasGtexSelections = true; - } - } - json["locus"] = locus.length === 1 ? locus[0] : locus; - if (hasGtexSelections) { - json["gtexSelections"] = gtexSelections; - } - - json["roi"] = this.roiManager.toJSON(); - - const trackJson = []; - const errors = []; - for (let {track} of this.trackViews) { - try { - let config; - if (typeof track.getState === "function") { - config = track.getState(); - } else { - config = track.config; - } - - if (config) { - // null backpointer to browser - if (config.browser) { - delete config.browser; - } - config.order = track.order; //order++; - trackJson.push(config); - } - } catch (e) { - console.error(`Track: ${track.name}: ${e}`); - errors.push(`Track: ${track.name}: ${e}`); - } - } - - if (errors.length > 0) { - let n = 1; - let message = 'Errors encountered saving session:
'; - for (let e of errors) { - message += ` (${n++}) ${e.toString()}
`; - } - throw Error(message) - } - - - json["tracks"] = trackJson; - - return json // This is an object, not a json string - - } - - compressedSession() { - const json = JSON.stringify(this.toJSON()); - return compressString(json) - } - - sessionURL() { - const path = window.location.href.slice(); - const idx = path.indexOf("?"); - const surl = (idx > 0 ? path.substring(0, idx) : path) + "?sessionURL=blob:" + this.compressedSession(); - return surl - } - - /** - * Record a mouse click on a specific viewport. This might be the start of a drag operation. Dragging - * (panning) is handled here so that the mouse can move out of a specific viewport (e.g. stray into another - * track) without halting the drag. - * - * @param e - * @param viewport - */ - mouseDownOnViewport(e, viewport) { - - var coords; - coords = domUtils$1.pageCoordinates(e); - this.vpMouseDown = { - viewport, - lastMouseX: coords.x, - mouseDownX: coords.x, - lastMouseY: coords.y, - mouseDownY: coords.y, - referenceFrame: viewport.referenceFrame - }; - }; - - cancelTrackPan() { - - const dragObject = this.dragObject; - this.dragObject = undefined; - this.isScrolling = false; - this.vpMouseDown = undefined; - - if (dragObject && dragObject.viewport.referenceFrame.start !== dragObject.start) { - this.updateViews(); - this.fireEvent('trackdragend'); - } - } - - isTrackPanning() { - return this.dragObject - } - - isSoftclipped() { - const result = this.trackViews.find(tv => tv.track.showSoftClips === true); - return result !== undefined - } - - - /** - * Track drag here refers to vertical dragging to reorder tracks, not horizontal panning. - * - * @param trackView - */ - startTrackDrag(trackView) { - - this.dragTrack = trackView; - - } - - /** - * Track drag here refers to vertical dragging to reorder tracks, not horizontal panning. - * - * @param dragDestination - */ - updateTrackDrag(dragDestination) { - - if (dragDestination && this.dragTrack) { - - const dragged = this.dragTrack; - const indexDestination = this.trackViews.indexOf(dragDestination); - const indexDragged = this.trackViews.indexOf(dragged); - const trackViews = this.trackViews; - - trackViews[indexDestination] = dragged; - trackViews[indexDragged] = dragDestination; - - const newOrder = this.trackViews[indexDestination].track.order; - this.trackViews[indexDragged].track.order = newOrder; - - const nTracks = trackViews.length; - let lastOrder = newOrder; - - if (indexDestination < indexDragged) { - // Displace tracks below - - for (let i = indexDestination + 1; i < nTracks; i++) { - const track = trackViews[i].track; - if (track.order <= lastOrder) { - track.order = Math.min(Number.MAX_SAFE_INTEGER, lastOrder + 1); - lastOrder = track.order; - } else { - break - } - } - } else { - // Displace tracks above. First track (index 0) is "ruler" - for (let i = indexDestination - 1; i > 0; i--) { - const track = trackViews[i].track; - if (track.order >= lastOrder) { - track.order = Math.max(-Number.MAX_SAFE_INTEGER, lastOrder - 1); - lastOrder = track.order; - } else { - break - } - } - } - this.reorderTracks(); - } - } - - /** - * End vertical dragging of tracks (i.e. track re-order, not horizontal panning of data) - */ - endTrackDrag() { - if (this.dragTrack) { - // this.dragTrack.$trackDragScrim.hide(); - this.dragTrack = undefined; - this.fireEvent('trackorderchanged', [this.getTrackOrder()]); - } else { - this.dragTrack = undefined; - } - } - - /** - * Mouse handlers to support drag (pan) - */ - addMouseHandlers() { - this.addWindowResizeHandler(); - this.addRootMouseUpHandler(); - this.addRootMouseLeaveHandler(); - this.addColumnContainerEventHandlers(); - } - - removeMouseHandlers() { - this.removeWindowResizeHandler(); - this.removeRootMouseUpHandler(); - this.removeRootMouseLeaveHandler(); - this.removeColumnContainerEventHandlers(); - } - - addWindowResizeHandler() { - // Create a copy of the prototype "resize" function bound to this instance. Neccessary to support removing. - this.boundWindowResizeHandler = resize.bind(this); - window.addEventListener('resize', this.boundWindowResizeHandler); - } - - removeWindowResizeHandler() { - window.removeEventListener('resize', this.boundWindowResizeHandler); - } - - addRootMouseUpHandler() { - this.boundRootMouseUpHandler = mouseUpOrLeave.bind(this); - this.root.addEventListener('mouseup', this.boundRootMouseUpHandler); - } - - removeRootMouseUpHandler() { - this.root.removeEventListener('mouseup', this.boundRootMouseUpHandler); - } - - addRootMouseLeaveHandler() { - this.boundRootMouseLeaveHandler = mouseUpOrLeave.bind(this); - this.root.addEventListener('mouseleave', this.boundRootMouseLeaveHandler); - } - - removeRootMouseLeaveHandler() { - this.root.removeEventListener('mouseleave', this.boundRootMouseLeaveHandler); - } - - addColumnContainerEventHandlers() { - this.boundColumnContainerMouseMoveHandler = handleMouseMove.bind(this); - this.boundColumnContainerTouchMoveHandler = handleMouseMove.bind(this); - this.boundColumnContainerMouseLeaveHandler = mouseUpOrLeave.bind(this); - this.boundColumnContainerMouseUpHandler = mouseUpOrLeave.bind(this); - this.boundColumnContainerTouchEndHandler = mouseUpOrLeave.bind(this); - - this.columnContainer.addEventListener('mousemove', this.boundColumnContainerMouseMoveHandler); - this.columnContainer.addEventListener('touchmove', this.boundColumnContainerTouchMoveHandler); - - this.columnContainer.addEventListener('mouseleave', this.boundColumnContainerMouseLeaveHandler); - - this.columnContainer.addEventListener('mouseup', this.boundColumnContainerMouseUpHandler); - this.columnContainer.addEventListener('touchend', this.boundColumnContainerTouchEndHandler); - } - - removeColumnContainerEventHandlers() { - this.columnContainer.removeEventListener('mousemove', this.boundColumnContainerMouseMoveHandler); - this.columnContainer.removeEventListener('touchmove', this.boundColumnContainerTouchMoveHandler); - - this.columnContainer.removeEventListener('mouseleave', this.boundColumnContainerMouseLeaveHandler); - - this.columnContainer.removeEventListener('mouseup', this.boundColumnContainerMouseUpHandler); - this.columnContainer.removeEventListener('touchend', this.boundColumnContainerTouchEndHandler); - } - - static uncompressSession(url) { - - let bytes; - if (url.indexOf('/gzip;base64') > 0) { - //Proper dataURI - bytes = decodeDataURI$1(url); - let json = ''; - for (let b of bytes) { - json += String.fromCharCode(b); - } - return json - } else { - - let enc = url.substring(5); - return uncompressString(enc) - } - } - - createCircularView(container, show) { - show = show === true; // convert undefined to boolean - this.circularView = createCircularView(container, this); - this.circularViewControl = new CircularViewControl(this.$toggle_button_container.get(0), this); - this.circularView.setAssembly({ - name: this.genome.id, - id: this.genome.id, - chromosomes: makeCircViewChromosomes(this.genome) - }); - this.circularViewVisible = show; - return this.circularView - } - - get circularViewVisible() { - return this.circularView !== undefined && this.circularView.visible - } - - set circularViewVisible(isVisible) { - if (this.circularView) { - this.circularView.visible = isVisible; - this.circularViewControl.setState(isVisible); - } - } - } - - /** - * Function called win window is resized, or visibility changed (e.g. "show" from a tab). This is a function rather - * than class method because it needs to be copied and bound to specific instances of browser to support listener - * removal - * - * @returns {Promise} - */ - async function resize() { - - if(!this.referenceFrameList) return - - const viewportWidth = this.calculateViewportWidth(this.referenceFrameList.length); - - for (let referenceFrame of this.referenceFrameList) { - - const index = this.referenceFrameList.indexOf(referenceFrame); - - const {chr, genome} = referenceFrame; - - const {bpLength} = genome.getChromosome(referenceFrame.chr); - - const viewportWidthBP = referenceFrame.toBP(viewportWidth); - - // viewportWidthBP > bpLength occurs when locus is full chromosome and user widens browser - if (GenomeUtils.isWholeGenomeView(chr) || viewportWidthBP > bpLength) { - // console.log(`${ Date.now() } Recalc referenceFrame(${ index }) bpp. viewport ${ StringUtils.numberFormatter(viewportWidthBP) } > ${ StringUtils.numberFormatter(bpLength) }.`) - referenceFrame.bpPerPixel = bpLength / viewportWidth; - } else { - // console.log(`${ Date.now() } Recalc referenceFrame(${ index }) end.`) - referenceFrame.end = referenceFrame.start + referenceFrame.toBP(viewportWidth); - } - - for (let {viewports} of this.trackViews) { - viewports[index].setWidth(viewportWidth); - } - - } - - this.updateUIWithReferenceFrameList(); - - //TODO -- update view only if needed. Reducing size never needed. Increasing size maybe - - await this.updateViews(true); - } - - - function handleMouseMove(e) { - - e.preventDefault(); - - const {x, y} = domUtils$1.pageCoordinates(e); - - if (this.vpMouseDown) { - - const {viewport, referenceFrame} = this.vpMouseDown; - - // Determine direction, true == horizontal - const horizontal = Math.abs((x - this.vpMouseDown.mouseDownX)) > Math.abs((y - this.vpMouseDown.mouseDownY)); - - if (!this.dragObject && !this.isScrolling) { - if (horizontal) { - if (this.vpMouseDown.mouseDownX && Math.abs(x - this.vpMouseDown.mouseDownX) > this.constants.dragThreshold) { - this.dragObject = {viewport, start: referenceFrame.start}; - } - } else { - if (this.vpMouseDown.mouseDownY && - Math.abs(y - this.vpMouseDown.mouseDownY) > this.constants.scrollThreshold) { - // Scrolling => dragging track vertically - this.isScrolling = true; - const viewportHeight = viewport.$viewport.height(); - const contentHeight = viewport.trackView.maxViewportContentHeight(); - this.vpMouseDown.r = viewportHeight / contentHeight; - } - } - } - - if (this.dragObject) { - const clampDrag = !this.isSoftclipped(); - let deltaX = this.vpMouseDown.lastMouseX - x; - const viewChanged = referenceFrame.shiftPixels(deltaX, viewport.$viewport.width(), clampDrag); - if (viewChanged) { - this.updateViews(); - } - this.fireEvent('trackdrag'); - } - - - if (this.isScrolling) { - const delta = this.vpMouseDown.r * (this.vpMouseDown.lastMouseY - y); - viewport.trackView.moveScroller(delta); - } - - - this.vpMouseDown.lastMouseX = x; - this.vpMouseDown.lastMouseY = y; - } - } - - function mouseUpOrLeave(e) { - this.cancelTrackPan(); - this.endTrackDrag(); - } - - - function getInitialLocus(locus, genome) { - if (locus) { - return Array.isArray(locus) ? locus.join(' ') : locus - } else { - return genome.getHomeChromosomeName() - } - } - - function logo() { - - return $$1( - '' + - 'IGV' + - '' + - '' + - '' + - ';' + - '' + - ' ' - ) - } - - function toggleTrackLabels(trackViews, isVisible) { - - for (let {viewports} of trackViews) { - for (let viewport of viewports) { - if (viewport.$trackLabel) { - if (0 === viewports.indexOf(viewport) && true === isVisible) { - viewport.$trackLabel.show(); - } else { - viewport.$trackLabel.hide(); - } - } - } - } - } - - /* - * The MIT License (MIT) - * - * Copyright (c) 2014 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - let allBrowsers$1 = []; - - /** - * Create an igv.browser instance. This object defines the public API for interacting with the genome browser. - * - * @param parentDiv - DOM tree root - * @param config - configuration options. - * - */ - async function createBrowser$1(parentDiv, config) { - - if (undefined === config) config = {}; - - // Initialize pre-defined genomes. The genome list is shared among all browser instances - if (!GenomeUtils.KNOWN_GENOMES) { - await GenomeUtils.initializeGenomes(config); - } - - setDefaults$1(config); - - if (config.queryParametersSupported) { - extractQuery$1(config); - } - if (config.apiKey) { - igvxhr.setApiKey(config.apiKey); - } - if (config.oauthToken) { - igvxhr.setOauthToken(config.oauthToken); - } - if (config.clientId && (!isInitialized())) { - await init$1$1({ - clientId: config.clientId, - apiKey: config.apiKey, - scope: 'https://www.googleapis.com/auth/userinfo.profile' - }); - } - - // Create browser - const browser = new Browser(config, parentDiv); - allBrowsers$1.push(browser); - - // Load initial session - if (config.sessionURL) { - await browser.loadSession({ - url: config.sessionURL - }); - } else { - await browser.loadSessionObject(config); - } - - browser.navbarManager.navbarDidResize(browser.$navigation.width()); - - return browser - - } - - function removeBrowser(browser) { - browser.dispose(); - browser.root.remove(); - allBrowsers$1 = allBrowsers$1.filter(item => item !== browser); - } - - function removeAllBrowsers() { - for (let browser of allBrowsers$1) { - browser.dispose(); - browser.root.remove(); - } - allBrowsers$1 = []; - } - - /** - * This function provided so clients can inform igv of a visibility change, typically when an igv instance is - * made visible from a tab, accordion, or similar widget. - */ - async function visibilityChange() { - for (let browser of allBrowsers$1) { - await browser.visibilityChange(); - } - } - - function setDefaults$1(config) { - - if (undefined === config.minimumBases) { - config.minimumBases = 40; - } - - if (undefined === config.showIdeogram) { - config.showIdeogram = true; - } - - if (undefined === config.showCircularView) { - config.showCircularView = false; - } - - if (undefined === config.showCircularViewButton) { - config.showCircularViewButton = false; - } - - if (undefined === config.showTrackLabelButton) { - config.showTrackLabelButton = true; - } - - if (undefined === config.showTrackLabels) { - config.showTrackLabels = true; - } - - if (undefined === config.showROITableButton) { - config.showROITableButton = false; - } - - if (undefined === config.showROITable) { - config.showROITable = false; - } - - if (undefined === config.showCursorTrackingGuideButton) { - config.showCursorTrackingGuideButton = true; - } - - - if (undefined === config.showCursorGuide) { - config.showCursorGuide = config.showCursorTrackingGuide || false; // showCursorTrackingGuide is a synonym - } - - if (undefined === config.showCenterGuideButton) { - config.showCenterGuideButton = true; - } - - if (undefined === config.showCenterGuide) { - config.showCenterGuide = false; - } - - if (undefined === config.showSampleNames) { - config.showSampleNames = false; - } - - if (undefined === config.showSVGButton) { - config.showSVGButton = true; - } - - if (config.showControls === undefined) { - config.showControls = true; - } - - if (config.showNavigation === undefined) { - config.showNavigation = true; - } - - if (config.showRuler === undefined) { - config.showRuler = true; - } - - if (config.flanking === undefined) { - config.flanking = 1000; - } - - if (config.pairsSupported === undefined) { - config.pairsSupported = true; - } - - if (!config.tracks) { - config.tracks = []; - } - - } - - - function extractQuery$1(config) { - - var i1, i2, i, j, s, query, tokens, uri, key, value; - - uri = window.location.href; - - query = {}; - i1 = uri.indexOf("?"); - i2 = uri.lastIndexOf("#"); - - let files; - let indexURLs; - let names; - if (i1 >= 0) { - if (i2 < 0) i2 = uri.length; - for (i = i1 + 1; i < i2;) { - j = uri.indexOf("&", i); - if (j < 0) j = i2; - - s = uri.substring(i, j); - tokens = s.split("=", 2); - - if (tokens.length === 2) { - key = tokens[0]; - value = decodeURIComponent(tokens[1]); - - if ('file' === key) { - // IGV desktop style file parameter - files = value.split(','); - } else if ('index' === key) { - // IGV desktop style index parameter - indexURLs = value.split(','); - } else if ('name' === key) { - // IGV desktop style index parameter - names = value.split(','); - } else if ('genome' === key && ((value.startsWith("https://") || value.startsWith("http://")) && !value.endsWith(".json"))) { - // IGV desktop compatibility -- assuming url to fasta - config['reference'] = { - fastaURL: value, - indexURL: value + ".fai" - }; - } else { - config[key] = value; - } - i = j + 1; - } else { - i++; - } - } - } - - if (files) { - - if (!config.tracks) - config.tracks = []; - for (let i = 0; i < files.length; i++) { - - if (files[i].endsWith(".xml") || files[i].endsWith(".json")) { - config.sessionURL = files[i]; - break - } - - const trackConfig = {url: files[i]}; - if (indexURLs && indexURLs.length > i) { - trackConfig.indexURL = indexURLs[i]; - } - if (names && names.length > i) { - trackConfig.name = names[i]; - } - config.tracks.push(trackConfig); - } - } - - return query - } - - - async function createTrack(config, browser) { - return await Browser.prototype.createTrack.call(browser, config) - } - - function embedCSS$3() { - - var css = '.igv-navbar {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-between;\n align-items: center;\n box-sizing: border-box;\n width: 100%;\n color: #444;\n font-size: 12px;\n font-family: \"Open Sans\", sans-serif;\n font-weight: 400;\n line-height: 32px;\n padding-left: 8px;\n padding-right: 8px;\n margin-top: 2px;\n margin-bottom: 6px;\n height: 32px;\n border-style: solid;\n border-radius: 3px;\n border-width: thin;\n border-color: #bfbfbf;\n background-color: #f3f3f3;\n}\n.igv-navbar .igv-navbar-left-container {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-between;\n align-items: center;\n height: 32px;\n line-height: 32px;\n}\n.igv-navbar .igv-navbar-left-container .igv-logo {\n width: 34px;\n height: 32px;\n margin-right: 8px;\n}\n.igv-navbar .igv-navbar-left-container .igv-current-genome {\n height: 32px;\n margin-left: 4px;\n margin-right: 4px;\n user-select: none;\n line-height: 32px;\n vertical-align: middle;\n text-align: center;\n}\n.igv-navbar .igv-navbar-left-container .igv-navbar-genomic-location {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-between;\n align-items: center;\n height: 100%;\n}\n.igv-navbar .igv-navbar-left-container .igv-navbar-genomic-location .igv-chromosome-select-widget-container {\n display: flex;\n flex-flow: column;\n flex-wrap: nowrap;\n justify-content: space-around;\n align-items: center;\n height: 100%;\n width: 125px;\n margin-right: 4px;\n}\n.igv-navbar .igv-navbar-left-container .igv-navbar-genomic-location .igv-chromosome-select-widget-container select {\n display: block;\n cursor: pointer;\n width: 100px;\n height: 75%;\n outline: none;\n font-size: 12px;\n font-family: \"Open Sans\", sans-serif;\n font-weight: 400;\n}\n.igv-navbar .igv-navbar-left-container .igv-navbar-genomic-location .igv-locus-size-group {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-between;\n align-items: center;\n margin-left: 8px;\n height: 22px;\n}\n.igv-navbar .igv-navbar-left-container .igv-navbar-genomic-location .igv-locus-size-group .igv-search-container {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n width: 210px;\n height: 22px;\n line-height: 22px;\n}\n.igv-navbar .igv-navbar-left-container .igv-navbar-genomic-location .igv-locus-size-group .igv-search-container input.igv-search-input {\n cursor: text;\n width: 85%;\n height: 22px;\n line-height: 22px;\n font-size: 12px;\n font-family: \"Open Sans\", sans-serif;\n font-weight: 400;\n text-align: left;\n padding-left: 8px;\n margin-right: 8px;\n outline: none;\n border-style: solid;\n border-radius: 3px;\n border-width: thin;\n border-color: #bfbfbf;\n background-color: white;\n}\n.igv-navbar .igv-navbar-left-container .igv-navbar-genomic-location .igv-locus-size-group .igv-search-container .igv-search-icon-container {\n cursor: pointer;\n height: 16px;\n width: 16px;\n}\n.igv-navbar .igv-navbar-left-container .igv-navbar-genomic-location .igv-locus-size-group .igv-windowsize-panel-container {\n margin-left: 4px;\n user-select: none;\n}\n.igv-navbar .igv-navbar-right-container {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-between;\n align-items: center;\n height: 32px;\n line-height: 32px;\n}\n.igv-navbar .igv-navbar-right-container .igv-navbar-toggle-button-container {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-between;\n align-items: center;\n height: 100%;\n}\n.igv-navbar .igv-navbar-right-container .igv-navbar-toggle-button-container div {\n margin-left: 0;\n margin-right: 4px;\n}\n.igv-navbar .igv-navbar-right-container .igv-navbar-toggle-button-container div:last-child {\n margin-left: 0;\n margin-right: 0;\n}\n.igv-navbar .igv-navbar-right-container .igv-navbar-toggle-button-container-750 {\n display: none;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget {\n color: #737373;\n font-size: 18px;\n height: 32px;\n line-height: 32px;\n margin-left: 8px;\n user-select: none;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-end;\n align-items: center;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget div {\n cursor: pointer;\n margin-left: unset;\n margin-right: unset;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget div:first-child {\n height: 24px;\n width: 24px;\n margin-left: unset;\n margin-right: 8px;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget div:last-child {\n height: 24px;\n width: 24px;\n margin-left: 8px;\n margin-right: unset;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget div:nth-child(even) {\n display: block;\n height: fit-content;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget input {\n display: block;\n width: 125px;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget svg {\n display: block;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget-900 {\n color: #737373;\n font-size: 18px;\n height: 32px;\n line-height: 32px;\n margin-left: 8px;\n user-select: none;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-end;\n align-items: center;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget-900 div {\n cursor: pointer;\n margin-left: unset;\n margin-right: unset;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget-900 div:first-child {\n height: 24px;\n width: 24px;\n margin-left: unset;\n margin-right: 8px;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget-900 div:last-child {\n height: 24px;\n width: 24px;\n margin-left: 8px;\n margin-right: unset;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget-900 div:nth-child(even) {\n width: 0;\n height: 0;\n display: none;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget-900 input {\n width: 0;\n height: 0;\n display: none;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget-900 svg {\n display: block;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget-hidden {\n display: none;\n}\n\n.igv-navbar-button {\n display: block;\n box-sizing: unset;\n padding-left: 6px;\n padding-right: 6px;\n height: 18px;\n text-transform: capitalize;\n user-select: none;\n line-height: 18px;\n text-align: center;\n vertical-align: middle;\n font-family: \"Open Sans\", sans-serif;\n font-size: 11px;\n font-weight: 200;\n color: #737373;\n background-color: #f3f3f3;\n border-color: #737373;\n border-style: solid;\n border-width: thin;\n border-radius: 6px;\n}\n\n.igv-navbar-button-clicked {\n color: white;\n background-color: #737373;\n}\n\n.igv-navbar-button:hover {\n cursor: pointer;\n}\n\n.igv-zoom-in-notice-container {\n z-index: 1024;\n position: absolute;\n top: 8px;\n left: 50%;\n transform: translate(-50%, 0%);\n display: flex;\n flex-direction: row;\n flex-wrap: nowrap;\n justify-content: center;\n align-items: center;\n background-color: white;\n}\n.igv-zoom-in-notice-container > div {\n padding-left: 4px;\n padding-right: 4px;\n padding-top: 2px;\n padding-bottom: 2px;\n width: 100%;\n height: 100%;\n font-family: \"Open Sans\", sans-serif;\n font-size: 14px;\n font-weight: 400;\n color: #3f3f3f;\n}\n\n.igv-zoom-in-notice {\n position: absolute;\n top: 10px;\n left: 50%;\n}\n.igv-zoom-in-notice div {\n position: relative;\n left: -50%;\n font-family: \"Open Sans\", sans-serif;\n font-size: medium;\n font-weight: 400;\n color: #3f3f3f;\n background-color: rgba(255, 255, 255, 0.51);\n z-index: 64;\n}\n\n.igv-container-spinner {\n position: absolute;\n top: 90%;\n left: 50%;\n transform: translate(-50%, -50%);\n z-index: 1024;\n width: 24px;\n height: 24px;\n pointer-events: none;\n color: #737373;\n}\n\n.igv-multi-locus-close-button {\n position: absolute;\n top: 2px;\n right: 0;\n padding-left: 2px;\n padding-right: 2px;\n width: 12px;\n height: 12px;\n color: #666666;\n background-color: white;\n z-index: 1000;\n}\n.igv-multi-locus-close-button > svg {\n vertical-align: top;\n}\n\n.igv-multi-locus-close-button:hover {\n cursor: pointer;\n color: #434343;\n}\n\n.igv-multi-locus-ruler-label {\n z-index: 64;\n position: absolute;\n top: 2px;\n left: 0;\n width: 100%;\n height: 12px;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: center;\n align-items: center;\n}\n.igv-multi-locus-ruler-label > div {\n font-family: \"Open Sans\", sans-serif;\n font-size: 12px;\n color: rgb(16, 16, 16);\n background-color: white;\n}\n.igv-multi-locus-ruler-label > div {\n cursor: pointer;\n}\n\n.igv-multi-locus-ruler-label-square-dot {\n z-index: 64;\n position: absolute;\n left: 50%;\n top: 5%;\n transform: translate(-50%, 0%);\n background-color: white;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n}\n.igv-multi-locus-ruler-label-square-dot > div:first-child {\n width: 14px;\n height: 14px;\n}\n.igv-multi-locus-ruler-label-square-dot > div:last-child {\n margin-left: 16px;\n font-family: \"Open Sans\", sans-serif;\n font-size: 14px;\n font-weight: 400;\n color: rgb(16, 16, 16);\n}\n\n.igv-ruler-sweeper {\n display: none;\n pointer-events: none;\n position: absolute;\n top: 26px;\n bottom: 0;\n left: 0;\n width: 0;\n z-index: 99999;\n background-color: rgba(68, 134, 247, 0.25);\n}\n\n.igv-ruler-tooltip {\n pointer-events: none;\n z-index: 128;\n position: absolute;\n top: 0;\n left: 0;\n width: 1px;\n height: 32px;\n background-color: transparent;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n}\n.igv-ruler-tooltip > div {\n pointer-events: none;\n width: 128px;\n height: auto;\n padding: 1px;\n color: #373737;\n font-size: 10px;\n font-family: \"Open Sans\", sans-serif;\n font-weight: 400;\n background-color: white;\n border-style: solid;\n border-width: thin;\n border-color: #373737;\n}\n\n.igv-track-label {\n position: absolute;\n left: 8px;\n top: 8px;\n width: auto;\n height: auto;\n max-width: 50%;\n padding-left: 4px;\n padding-right: 4px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n font-family: \"Open Sans\", sans-serif;\n font-size: small;\n font-weight: 400;\n text-align: center;\n user-select: none;\n -moz-user-select: none;\n -webkit-user-select: none;\n border-color: #444;\n border-radius: 2px;\n border-style: solid;\n border-width: thin;\n background-color: white;\n z-index: 128;\n cursor: pointer;\n}\n\n.igv-track-label:hover,\n.igv-track-label:focus,\n.igv-track-label:active {\n background-color: #e8e8e8;\n}\n\n.igv-track-label-popup-shim {\n padding-left: 8px;\n padding-right: 8px;\n padding-top: 4px;\n}\n\n.igv-center-line {\n display: none;\n pointer-events: none;\n position: absolute;\n top: 0;\n bottom: 0;\n left: 50%;\n transform: translateX(-50%);\n z-index: 8;\n user-select: none;\n -moz-user-select: none;\n -webkit-user-select: none;\n border-left-style: dashed;\n border-left-width: thin;\n border-right-style: dashed;\n border-right-width: thin;\n}\n\n.igv-center-line-wide {\n background-color: rgba(0, 0, 0, 0);\n border-left-color: rgba(127, 127, 127, 0.51);\n border-right-color: rgba(127, 127, 127, 0.51);\n}\n\n.igv-center-line-thin {\n background-color: rgba(0, 0, 0, 0);\n border-left-color: rgba(127, 127, 127, 0.51);\n border-right-color: rgba(0, 0, 0, 0);\n}\n\n.igv-cursor-guide-horizontal {\n display: none;\n pointer-events: none;\n user-select: none;\n -moz-user-select: none;\n -webkit-user-select: none;\n position: absolute;\n left: 0;\n right: 0;\n top: 50%;\n height: 1px;\n z-index: 1;\n margin-left: 50px;\n margin-right: 54px;\n border-top-style: dotted;\n border-top-width: thin;\n border-top-color: rgba(127, 127, 127, 0.76);\n}\n\n.igv-cursor-guide-vertical {\n pointer-events: none;\n user-select: none;\n -moz-user-select: none;\n -webkit-user-select: none;\n position: absolute;\n top: 0;\n bottom: 0;\n left: 50%;\n width: 1px;\n z-index: 1;\n border-left-style: dotted;\n border-left-width: thin;\n border-left-color: rgba(127, 127, 127, 0.76);\n display: none;\n}\n\n.igv-user-feedback {\n position: fixed;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: 512px;\n height: 360px;\n z-index: 2048;\n background-color: white;\n border-color: #a2a2a2;\n border-style: solid;\n border-width: thin;\n font-family: \"Open Sans\", sans-serif;\n font-size: medium;\n font-weight: 400;\n color: #444;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n}\n.igv-user-feedback div:first-child {\n position: relative;\n height: 24px;\n width: 100%;\n background-color: white;\n border-bottom-color: #a2a2a2;\n border-bottom-style: solid;\n border-bottom-width: thin;\n}\n.igv-user-feedback div:first-child div {\n position: absolute;\n top: 2px;\n width: 16px;\n height: 16px;\n background-color: transparent;\n}\n.igv-user-feedback div:first-child div:first-child {\n left: 8px;\n}\n.igv-user-feedback div:first-child div:last-child {\n cursor: pointer;\n right: 8px;\n}\n.igv-user-feedback div:last-child {\n width: 100%;\n height: calc(100% - 24px);\n border-width: 0;\n}\n.igv-user-feedback div:last-child div {\n width: auto;\n height: auto;\n margin: 8px;\n}\n\n.igv-generic-dialog-container {\n position: absolute;\n top: 0;\n left: 0;\n width: 300px;\n height: 200px;\n border-color: #7F7F7F;\n border-radius: 4px;\n border-style: solid;\n border-width: thin;\n font-family: \"Open Sans\", sans-serif;\n font-size: medium;\n font-weight: 400;\n z-index: 2048;\n background-color: white;\n display: flex;\n flex-flow: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n}\n.igv-generic-dialog-container .igv-generic-dialog-header {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-end;\n align-items: center;\n width: 100%;\n height: 24px;\n cursor: move;\n border-top-left-radius: 4px;\n border-top-right-radius: 4px;\n border-bottom-color: #7F7F7F;\n border-bottom-style: solid;\n border-bottom-width: thin;\n background-color: #eee;\n}\n.igv-generic-dialog-container .igv-generic-dialog-header div {\n margin-right: 4px;\n margin-bottom: 2px;\n height: 12px;\n width: 12px;\n color: #7F7F7F;\n}\n.igv-generic-dialog-container .igv-generic-dialog-header div:hover {\n cursor: pointer;\n color: #444;\n}\n.igv-generic-dialog-container .igv-generic-dialog-one-liner {\n color: #373737;\n width: 95%;\n height: 24px;\n line-height: 24px;\n text-align: left;\n margin-top: 8px;\n padding-left: 8px;\n overflow-wrap: break-word;\n background-color: white;\n}\n.igv-generic-dialog-container .igv-generic-dialog-label-input {\n margin-top: 8px;\n width: 95%;\n height: 24px;\n color: #373737;\n line-height: 24px;\n padding-left: 8px;\n background-color: white;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n}\n.igv-generic-dialog-container .igv-generic-dialog-label-input div {\n width: 30%;\n height: 100%;\n font-size: 16px;\n text-align: right;\n padding-right: 8px;\n background-color: white;\n}\n.igv-generic-dialog-container .igv-generic-dialog-label-input input {\n display: block;\n height: 100%;\n width: 100%;\n padding-left: 4px;\n font-family: \"Open Sans\", sans-serif;\n font-weight: 400;\n color: #373737;\n text-align: left;\n outline: none;\n border-style: solid;\n border-width: thin;\n border-color: #7F7F7F;\n background-color: white;\n}\n.igv-generic-dialog-container .igv-generic-dialog-label-input input {\n width: 50%;\n font-size: 16px;\n}\n.igv-generic-dialog-container .igv-generic-dialog-input {\n margin-top: 8px;\n width: calc(100% - 16px);\n height: 24px;\n color: #373737;\n line-height: 24px;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-around;\n align-items: center;\n}\n.igv-generic-dialog-container .igv-generic-dialog-input input {\n display: block;\n height: 100%;\n width: 100%;\n padding-left: 4px;\n font-family: \"Open Sans\", sans-serif;\n font-weight: 400;\n color: #373737;\n text-align: left;\n outline: none;\n border-style: solid;\n border-width: thin;\n border-color: #7F7F7F;\n background-color: white;\n}\n.igv-generic-dialog-container .igv-generic-dialog-input input {\n font-size: 16px;\n}\n.igv-generic-dialog-container .igv-generic-dialog-ok-cancel {\n width: 100%;\n height: 28px;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-around;\n align-items: center;\n}\n.igv-generic-dialog-container .igv-generic-dialog-ok-cancel div {\n margin-top: 32px;\n color: white;\n font-family: \"Open Sans\", sans-serif;\n font-size: 14px;\n font-weight: 400;\n width: 75px;\n height: 28px;\n line-height: 28px;\n text-align: center;\n border-color: transparent;\n border-style: solid;\n border-width: thin;\n border-radius: 2px;\n}\n.igv-generic-dialog-container .igv-generic-dialog-ok-cancel div:first-child {\n margin-left: 32px;\n margin-right: 0;\n background-color: #5ea4e0;\n}\n.igv-generic-dialog-container .igv-generic-dialog-ok-cancel div:last-child {\n margin-left: 0;\n margin-right: 32px;\n background-color: #c4c4c4;\n}\n.igv-generic-dialog-container .igv-generic-dialog-ok-cancel div:first-child:hover {\n cursor: pointer;\n background-color: #3b5c7f;\n}\n.igv-generic-dialog-container .igv-generic-dialog-ok-cancel div:last-child:hover {\n cursor: pointer;\n background-color: #7f7f7f;\n}\n.igv-generic-dialog-container .igv-generic-dialog-ok {\n width: 100%;\n height: 36px;\n margin-top: 32px;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-around;\n align-items: center;\n}\n.igv-generic-dialog-container .igv-generic-dialog-ok div {\n width: 98px;\n height: 36px;\n line-height: 36px;\n text-align: center;\n color: white;\n font-family: \"Open Sans\", sans-serif;\n font-size: medium;\n font-weight: 400;\n border-color: white;\n border-style: solid;\n border-width: thin;\n border-radius: 4px;\n background-color: #2B81AF;\n}\n.igv-generic-dialog-container .igv-generic-dialog-ok div:hover {\n cursor: pointer;\n background-color: #25597f;\n}\n\n.igv-generic-container {\n position: absolute;\n top: 0;\n left: 0;\n z-index: 2048;\n background-color: white;\n cursor: pointer;\n display: flex;\n flex-direction: row;\n flex-wrap: wrap;\n justify-content: flex-start;\n align-items: center;\n}\n.igv-generic-container div:first-child {\n cursor: move;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-end;\n align-items: center;\n height: 24px;\n width: 100%;\n background-color: #dddddd;\n}\n.igv-generic-container div:first-child i {\n display: block;\n color: #5f5f5f;\n cursor: pointer;\n width: 14px;\n height: 14px;\n margin-right: 8px;\n margin-bottom: 4px;\n}\n\n.igv-menu-popup {\n position: absolute;\n top: 0;\n left: 0;\n width: max-content;\n z-index: 4096;\n cursor: pointer;\n font-family: \"Open Sans\", sans-serif;\n font-size: small;\n font-weight: 400;\n color: #4b4b4b;\n background: white;\n border-radius: 4px;\n border-color: #7F7F7F;\n border-style: solid;\n border-width: thin;\n display: flex;\n flex-flow: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: flex-end;\n text-align: left;\n}\n.igv-menu-popup > div:not(:first-child) {\n width: 100%;\n}\n.igv-menu-popup > div:not(:first-child) > div {\n background: white;\n}\n.igv-menu-popup > div:not(:first-child) > div.context-menu {\n padding-left: 4px;\n padding-right: 4px;\n}\n.igv-menu-popup > div:not(:first-child) > div:last-child {\n border-bottom-left-radius: 4px;\n border-bottom-right-radius: 4px;\n border-bottom-color: transparent;\n border-bottom-style: solid;\n border-bottom-width: thin;\n}\n.igv-menu-popup > div:not(:first-child) > div:hover {\n background: #efefef;\n}\n\n.igv-menu-popup-shim {\n padding-left: 8px;\n padding-right: 8px;\n padding-bottom: 1px;\n padding-top: 1px;\n}\n\n.igv-menu-popup-header {\n position: relative;\n width: 100%;\n height: 24px;\n cursor: move;\n border-top-color: transparent;\n border-top-left-radius: 4px;\n border-top-right-radius: 4px;\n border-bottom-color: #7F7F7F;\n border-bottom-style: solid;\n border-bottom-width: thin;\n background-color: #eee;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-end;\n align-items: center;\n}\n.igv-menu-popup-header div {\n margin-right: 4px;\n height: 12px;\n width: 12px;\n color: #7F7F7F;\n}\n.igv-menu-popup-header div:hover {\n cursor: pointer;\n color: #444;\n}\n\n.igv-menu-popup-check-container {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n width: 100%;\n height: 20px;\n margin-right: 4px;\n background-color: transparent;\n}\n.igv-menu-popup-check-container div {\n padding-top: 2px;\n padding-left: 8px;\n}\n.igv-menu-popup-check-container div:first-child {\n position: relative;\n width: 12px;\n height: 12px;\n}\n.igv-menu-popup-check-container div:first-child svg {\n position: absolute;\n width: 12px;\n height: 12px;\n}\n\n.igv-user-feedback {\n position: fixed;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: 512px;\n height: 360px;\n z-index: 2048;\n background-color: white;\n border-color: #a2a2a2;\n border-style: solid;\n border-width: thin;\n font-family: \"Open Sans\", sans-serif;\n font-size: medium;\n font-weight: 400;\n color: #444;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n}\n.igv-user-feedback div:first-child {\n position: relative;\n height: 24px;\n width: 100%;\n background-color: white;\n border-bottom-color: #a2a2a2;\n border-bottom-style: solid;\n border-bottom-width: thin;\n}\n.igv-user-feedback div:first-child div {\n position: absolute;\n top: 2px;\n width: 16px;\n height: 16px;\n background-color: transparent;\n}\n.igv-user-feedback div:first-child div:first-child {\n left: 8px;\n}\n.igv-user-feedback div:first-child div:last-child {\n cursor: pointer;\n right: 8px;\n}\n.igv-user-feedback div:last-child {\n width: 100%;\n height: calc(100% - 24px);\n border-width: 0;\n}\n.igv-user-feedback div:last-child div {\n width: auto;\n height: auto;\n margin: 8px;\n}\n\n.igv-loading-spinner-container {\n z-index: 1024;\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: 32px;\n height: 32px;\n display: flex;\n flex-direction: row;\n flex-wrap: nowrap;\n justify-content: center;\n align-items: center;\n}\n.igv-loading-spinner-container > div {\n box-sizing: border-box;\n width: 100%;\n height: 100%;\n border-radius: 50%;\n border: 4px solid rgba(128, 128, 128, 0.5);\n border-top-color: rgb(255, 255, 255);\n animation: spin 1s ease-in-out infinite;\n -webkit-animation: spin 1s ease-in-out infinite;\n}\n\n@keyframes spin {\n to {\n -webkit-transform: rotate(360deg);\n transform: rotate(360deg);\n }\n}\n@-webkit-keyframes spin {\n to {\n -webkit-transform: rotate(360deg);\n transform: rotate(360deg);\n }\n}\n.igv-roi-menu-next-gen {\n position: absolute;\n z-index: 512;\n font-family: \"Open Sans\", sans-serif;\n font-size: small;\n font-weight: 400;\n color: #4b4b4b;\n background-color: white;\n width: 192px;\n border-radius: 4px;\n border-color: #7F7F7F;\n border-style: solid;\n border-width: thin;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: stretch;\n}\n.igv-roi-menu-next-gen > div:first-child {\n height: 24px;\n border-top-color: transparent;\n border-top-left-radius: 4px;\n border-top-right-radius: 4px;\n border-bottom-color: #7F7F7F;\n border-bottom-style: solid;\n border-bottom-width: thin;\n background-color: #eee;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-end;\n align-items: center;\n}\n.igv-roi-menu-next-gen > div:first-child > div {\n margin-right: 4px;\n height: 12px;\n width: 12px;\n color: #7F7F7F;\n}\n.igv-roi-menu-next-gen > div:first-child > div:hover {\n cursor: pointer;\n color: #444;\n}\n.igv-roi-menu-next-gen > div:last-child {\n background-color: white;\n border-bottom-left-radius: 4px;\n border-bottom-right-radius: 4px;\n border-bottom-color: transparent;\n border-bottom-style: solid;\n border-bottom-width: 0;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: stretch;\n text-align: start;\n vertical-align: middle;\n}\n.igv-roi-menu-next-gen > div:last-child > div {\n height: 24px;\n padding-left: 4px;\n border-bottom-style: solid;\n border-bottom-width: thin;\n border-bottom-color: #7f7f7f;\n}\n.igv-roi-menu-next-gen > div:last-child > div:not(:first-child):hover {\n background-color: rgba(127, 127, 127, 0.1);\n}\n.igv-roi-menu-next-gen > div:last-child div:first-child {\n font-style: italic;\n text-align: center;\n padding-right: 4px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n.igv-roi-menu-next-gen > div:last-child > div:last-child {\n border-bottom-width: 0;\n border-bottom-color: transparent;\n}\n\n.igv-roi-placeholder {\n font-style: normal;\n color: rgba(75, 75, 75, 0.6);\n}\n\n.igv-roi-table {\n position: absolute;\n z-index: 1024;\n width: min-content;\n max-width: 1600px;\n border-color: #7f7f7f;\n border-radius: 4px;\n border-style: solid;\n border-width: thin;\n font-family: \"Open Sans\", sans-serif;\n font-size: 12px;\n font-weight: 400;\n background-color: white;\n display: flex;\n flex-flow: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: stretch;\n cursor: default;\n}\n.igv-roi-table > div {\n height: 24px;\n font-size: 14px;\n text-align: start;\n vertical-align: middle;\n line-height: 24px;\n}\n.igv-roi-table > div:first-child {\n border-color: transparent;\n border-top-left-radius: 4px;\n border-top-right-radius: 4px;\n border-top-width: 0;\n border-bottom-color: #7f7f7f;\n border-bottom-style: solid;\n border-bottom-width: thin;\n background-color: #eee;\n cursor: move;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-between;\n align-items: center;\n}\n.igv-roi-table > div:first-child > div:first-child {\n text-align: center;\n white-space: nowrap;\n text-overflow: ellipsis;\n overflow: hidden;\n margin-left: 4px;\n margin-right: 4px;\n width: calc(100% - 4px - 12px);\n}\n.igv-roi-table > div:first-child > div:last-child {\n margin-right: 4px;\n margin-bottom: 2px;\n height: 12px;\n width: 12px;\n color: #7f7f7f;\n}\n.igv-roi-table > div:first-child > div:last-child > svg {\n display: block;\n}\n.igv-roi-table > div:first-child > div:last-child:hover {\n cursor: pointer;\n color: #444;\n}\n.igv-roi-table > .igv-roi-table-description {\n padding: 4px;\n margin-left: 4px;\n word-break: break-all;\n overflow-y: auto;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n background-color: transparent;\n}\n.igv-roi-table > .igv-roi-table-goto-explainer {\n margin-top: 5px;\n margin-left: 4px;\n color: #7F7F7F;\n font-style: italic;\n height: 24px;\n border-top: solid lightgray;\n background-color: transparent;\n}\n.igv-roi-table > .igv-roi-table-column-titles {\n height: 24px;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: stretch;\n align-items: stretch;\n padding-right: 16px;\n background-color: white;\n border-top-color: #7f7f7f;\n border-top-style: solid;\n border-top-width: thin;\n border-bottom-color: #7f7f7f;\n border-bottom-style: solid;\n border-bottom-width: thin;\n}\n.igv-roi-table > .igv-roi-table-column-titles > div {\n font-size: 14px;\n vertical-align: middle;\n line-height: 24px;\n text-align: left;\n margin-left: 4px;\n height: 24px;\n overflow: hidden;\n text-overflow: ellipsis;\n border-right-color: #7f7f7f;\n border-right-style: solid;\n border-right-width: thin;\n}\n.igv-roi-table > .igv-roi-table-column-titles > div:last-child {\n border-right: unset;\n}\n.igv-roi-table > .igv-roi-table-row-container {\n overflow: auto;\n resize: both;\n max-width: 1600px;\n height: 360px;\n background-color: transparent;\n display: flex;\n flex-flow: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: stretch;\n}\n.igv-roi-table > .igv-roi-table-row-container > .igv-roi-table-row {\n height: 24px;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: stretch;\n align-items: stretch;\n}\n.igv-roi-table > .igv-roi-table-row-container > .igv-roi-table-row > div {\n font-size: 14px;\n vertical-align: middle;\n line-height: 24px;\n text-align: left;\n margin-left: 4px;\n height: 24px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n border-right-color: transparent;\n border-right-style: solid;\n border-right-width: thin;\n}\n.igv-roi-table > .igv-roi-table-row-container > .igv-roi-table-row > div:last-child {\n border-right: unset;\n}\n.igv-roi-table > .igv-roi-table-row-container > .igv-roi-table-row-hover {\n background-color: rgba(0, 0, 0, 0.04);\n}\n.igv-roi-table > div:last-child {\n height: 32px;\n line-height: 32px;\n border-top-color: #7f7f7f;\n border-top-style: solid;\n border-top-width: thin;\n border-bottom-color: transparent;\n border-bottom-left-radius: 4px;\n border-bottom-right-radius: 4px;\n border-bottom-width: 0;\n background-color: #eee;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-around;\n align-items: center;\n}\n\n.igv-roi-table-row-selected {\n background-color: rgba(0, 0, 0, 0.125);\n}\n\n.igv-roi-table-button {\n cursor: pointer;\n height: 20px;\n user-select: none;\n line-height: 20px;\n text-align: center;\n vertical-align: middle;\n font-family: \"Open Sans\", sans-serif;\n font-size: 13px;\n font-weight: 400;\n color: black;\n padding-left: 6px;\n padding-right: 6px;\n background-color: rgb(239, 239, 239);\n border-color: black;\n border-style: solid;\n border-width: thin;\n border-radius: 3px;\n}\n\n.igv-roi-table-button:hover {\n font-weight: 400;\n background-color: rgba(0, 0, 0, 0.13);\n}\n\n.igv-roi-region {\n z-index: 64;\n position: absolute;\n top: 0;\n bottom: 0;\n pointer-events: none;\n overflow: visible;\n margin-top: 44px;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: stretch;\n}\n.igv-roi-region > div {\n position: relative;\n width: 100%;\n height: 8px;\n pointer-events: auto;\n}\n\n.igv-roi-menu {\n position: absolute;\n z-index: 1024;\n width: 144px;\n border-color: #7f7f7f;\n border-radius: 4px;\n border-style: solid;\n border-width: thin;\n font-family: \"Open Sans\", sans-serif;\n background-color: white;\n display: flex;\n flex-flow: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: stretch;\n}\n.igv-roi-menu > div:not(:last-child) {\n border-bottom-color: rgba(128, 128, 128, 0.5);\n border-bottom-style: solid;\n border-bottom-width: thin;\n}\n.igv-roi-menu > div:first-child {\n border-top-left-radius: 4px;\n border-top-right-radius: 4px;\n border-top-color: transparent;\n border-top-style: solid;\n border-top-width: 0;\n}\n.igv-roi-menu > div:last-child {\n border-bottom-left-radius: 4px;\n border-bottom-right-radius: 4px;\n border-bottom-color: transparent;\n border-bottom-style: solid;\n border-bottom-width: 0;\n}\n\n.igv-roi-menu-row {\n height: 24px;\n padding-left: 8px;\n font-size: small;\n text-align: start;\n vertical-align: middle;\n line-height: 24px;\n background-color: white;\n}\n\n.igv-roi-menu-row-edit-description {\n width: -webkit-fill-available;\n font-size: small;\n text-align: start;\n vertical-align: middle;\n background-color: white;\n padding-left: 4px;\n padding-right: 4px;\n padding-bottom: 4px;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: stretch;\n align-items: stretch;\n}\n.igv-roi-menu-row-edit-description > label {\n margin-left: 2px;\n margin-bottom: 0;\n display: block;\n width: -webkit-fill-available;\n}\n.igv-roi-menu-row-edit-description > input {\n display: block;\n margin-left: 2px;\n margin-right: 2px;\n margin-bottom: 1px;\n width: -webkit-fill-available;\n}\n\n.igv-container {\n position: relative;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: flex-start;\n padding-top: 4px;\n user-select: none;\n -webkit-user-select: none;\n -ms-user-select: none;\n}\n\n.igv-viewport {\n position: relative;\n margin-top: 5px;\n line-height: 1;\n overflow-x: hidden;\n overflow-y: hidden;\n}\n\n.igv-viewport-content {\n position: relative;\n width: 100%;\n}\n.igv-viewport-content > canvas {\n position: relative;\n display: block;\n}\n\n.igv-column-container {\n position: relative;\n display: flex;\n flex-direction: row;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: stretch;\n width: 100%;\n}\n\n.igv-column-shim {\n width: 1px;\n margin-left: 2px;\n margin-right: 2px;\n background-color: #545453;\n}\n\n.igv-column {\n position: relative;\n position: relative;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: flex-start;\n box-sizing: border-box;\n height: 100%;\n}\n\n.igv-axis-column {\n position: relative;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: flex-start;\n box-sizing: border-box;\n height: 100%;\n width: 50px;\n}\n.igv-axis-column > div {\n margin-top: 5px;\n width: 100%;\n}\n\n.igv-sample-name-column {\n position: relative;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: flex-start;\n box-sizing: border-box;\n height: 100%;\n}\n\n.igv-scrollbar-column {\n position: relative;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: flex-start;\n box-sizing: border-box;\n height: 100%;\n width: 14px;\n}\n.igv-scrollbar-column > div {\n position: relative;\n margin-top: 5px;\n width: 14px;\n}\n.igv-scrollbar-column > div > div {\n cursor: pointer;\n position: absolute;\n top: 0;\n left: 2px;\n width: 8px;\n border-width: 1px;\n border-style: solid;\n border-color: #c4c4c4;\n border-top-left-radius: 4px;\n border-top-right-radius: 4px;\n border-bottom-left-radius: 4px;\n border-bottom-right-radius: 4px;\n}\n.igv-scrollbar-column > div > div:hover {\n background-color: #c4c4c4;\n}\n\n.igv-track-drag-column {\n position: relative;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: flex-start;\n box-sizing: border-box;\n height: 100%;\n width: 12px;\n background-color: white;\n}\n.igv-track-drag-column > .igv-track-drag-handle {\n z-index: 512;\n position: relative;\n cursor: pointer;\n margin-top: 5px;\n width: 100%;\n border-style: solid;\n border-width: 0;\n border-top-right-radius: 6px;\n border-bottom-right-radius: 6px;\n background-color: #c4c4c4;\n}\n.igv-track-drag-column .igv-track-drag-handle-hover {\n background-color: #787878;\n}\n.igv-track-drag-column > .igv-track-drag-shim {\n position: relative;\n margin-top: 5px;\n width: 100%;\n border-style: solid;\n border-width: 0;\n}\n\n.igv-gear-menu-column {\n position: relative;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: flex-start;\n box-sizing: border-box;\n height: 100%;\n width: 28px;\n}\n.igv-gear-menu-column > div {\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n margin-top: 5px;\n width: 100%;\n background: white;\n}\n.igv-gear-menu-column > div > div {\n position: relative;\n margin-top: 4px;\n width: 16px;\n height: 16px;\n color: #7F7F7F;\n}\n.igv-gear-menu-column > div > div:hover {\n cursor: pointer;\n color: #444;\n}\n\n/*# sourceMappingURL=dom.css.map */\n'; - - var style = document.createElement('style'); - style.setAttribute('type', 'text/css'); - style.innerHTML = css; - - document.head.append(style); - - } - - // Defines the top-level API for the igv module - - const setApiKey = igvxhr.setApiKey; - - embedCSS$3(); - - function setGoogleOauthToken(accessToken) { - return igvxhr.setOauthToken(accessToken) - } - - function setOauthToken(accessToken, host) { - return igvxhr.setOauthToken(accessToken, host) - } - - // Backward compatibility - const oauth = igvxhr.oauth; - - var index$1 = { - TrackUtils, - IGVGraphics, - MenuUtils: MenuUtils$1, - DataRangeDialog: DataRangeDialog$1, - createTrack, - createBrowser: createBrowser$1, - removeBrowser, - removeAllBrowsers, - visibilityChange, - setGoogleOauthToken, - setOauthToken, - oauth, - version: version$2, - setApiKey, - registerFileFormats - }; - - function div(options) { - return create("div", options); - } - - function create(tag, options) { - const elem = document.createElement(tag); - if (options) { - if (options.class) { - elem.classList.add(options.class); - } - if (options.id) { - elem.id = options.id; - } - if(options.style) { - applyStyle(elem, options.style); - } - } - return elem; - } - - function hide(elem) { - const cssStyle = getComputedStyle(elem); - if(cssStyle.display !== "none") { - elem._initialDisplay = cssStyle.display; - } - elem.style.display = "none"; - } - - function show(elem) { - const currentDisplay = getComputedStyle(elem).display; - if (currentDisplay === "none") { - const d = elem._initialDisplay || "block"; - elem.style.display = d; - } - } - - function hideAll(selector) { - document.querySelectorAll(selector).forEach(elem => { hide(elem); }); - } - - function empty(elem) { - while(elem.firstChild){ - elem.removeChild(elem.firstChild); - } - } - - function offset(elem) { - // Return zeros for disconnected and hidden (display: none) elements (gh-2310) - // Support: IE <=11 only - // Running getBoundingClientRect on a - // disconnected node in IE throws an error - if (!elem.getClientRects().length) { - return {top: 0, left: 0}; - } - - // Get document-relative position by adding viewport scroll to viewport-relative gBCR - const rect = elem.getBoundingClientRect(); - const win = elem.ownerDocument.defaultView; - return { - top: rect.top + win.pageYOffset, - left: rect.left + win.pageXOffset - }; - } - - function pageCoordinates(e) { - - if (e.type.startsWith("touch")) { - const touch = e.touches[0]; - return {x: touch.pageX, y: touch.pageY}; - } else { - return {x: e.pageX, y: e.pageY} - } - } - - const relativeDOMBBox = (parentElement, childElement) => { - const { x: x_p, y: y_p, width: width_p, height: height_p } = parentElement.getBoundingClientRect(); - const { x: x_c, y: y_c, width: width_c, height: height_c } = childElement.getBoundingClientRect(); - return { x: (x_c - x_p), y: (y_c - y_p), width: width_c, height:height_c }; - }; - - function applyStyle(elem, style) { - for (let key of Object.keys(style)) { - elem.style[key] = style[key]; - } - } - - function guid () { - return ("0000" + (Math.random() * Math.pow(36, 4) << 0).toString(36)).slice(-4); - } - - let getMouseXY = (domElement, { clientX, clientY }) => { - - // DOMRect object with eight properties: left, top, right, bottom, x, y, width, height - const { left, top, width, height } = domElement.getBoundingClientRect(); - - const x = clientX - left; - const y = clientY - top; - return { x, y, xNormalized: x/width, yNormalized: y/height, width, height }; - - }; - - /** - * Translate the mouse coordinates for the event to the coordinates for the given target element - * @param event - * @param domElement - * @returns {{x: number, y: number}} - */ - function translateMouseCoordinates(event, domElement) { - - const { clientX, clientY } = event; - return getMouseXY(domElement, { clientX, clientY }); - - } - - var domUtils = /*#__PURE__*/Object.freeze({ - __proto__: null, - applyStyle: applyStyle, - create: create, - div: div, - empty: empty, - guid: guid, - hide: hide, - hideAll: hideAll, - offset: offset, - pageCoordinates: pageCoordinates, - relativeDOMBBox: relativeDOMBBox, - show: show, - translateMouseCoordinates: translateMouseCoordinates - }); - - class Textbox { - - constructor({value, label, onchange}) { - - this.elem = div({class: 'igv-ui-generic-dialog-label-input'}); - - if(label) { - const div$1 = div(); - div$1.innerHTML = label; - this.elem.appendChild(div$1); - } - - this.textBox = create('input'); - if(value) { - this.textBox.value = value; - } - this.elem.appendChild(this.textBox); - - if(onchange) { - this.textBox.addEventListener('change', (e) => onchange(this.textBox.value)); - } - } - - get value() { - return this.textBox.value; - } - - set value(v) { - this.textBox.value = v; - } - } - - /** - * Generic container for UI components - */ - class Panel { - - constructor() { - - this.elem = create('div', { - class: 'igv-ui-panel-column' - }); - } - - add(component) { - - if(component instanceof Node) { - this.elem.append(component); - } - else if(typeof component === 'object') { - this.elem.append(component.elem); - } - else { - // Assuming a string, possibly html - const wrapper = div(); - wrapper.innerHTML = component; - this.elem.append(wrapper); - } - } - - - } - - function createIcon$1(name, color) { - return iconMarkup$1(name, color); - } - - function iconMarkup$1(name, color) { - color = color || "currentColor"; - let icon = icons$1[name]; - if (!icon) { - console.error(`No icon named: ${name}`); - icon = icons$1["question"]; - } - - const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg"); - svg.setAttributeNS(null,'viewBox', '0 0 ' + icon[0] + ' ' + icon[1]); - const path = document.createElementNS("http://www.w3.org/2000/svg", "path"); - path.setAttributeNS(null,'fill', color ); - path.setAttributeNS(null,'d', icon[4]); - svg.appendChild(path); - return svg; - } - - const icons$1 = { - "check": [512, 512, [], "f00c", "M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z"], - "cog": [512, 512, [], "f013", "M444.788 291.1l42.616 24.599c4.867 2.809 7.126 8.618 5.459 13.985-11.07 35.642-29.97 67.842-54.689 94.586a12.016 12.016 0 0 1-14.832 2.254l-42.584-24.595a191.577 191.577 0 0 1-60.759 35.13v49.182a12.01 12.01 0 0 1-9.377 11.718c-34.956 7.85-72.499 8.256-109.219.007-5.49-1.233-9.403-6.096-9.403-11.723v-49.184a191.555 191.555 0 0 1-60.759-35.13l-42.584 24.595a12.016 12.016 0 0 1-14.832-2.254c-24.718-26.744-43.619-58.944-54.689-94.586-1.667-5.366.592-11.175 5.459-13.985L67.212 291.1a193.48 193.48 0 0 1 0-70.199l-42.616-24.599c-4.867-2.809-7.126-8.618-5.459-13.985 11.07-35.642 29.97-67.842 54.689-94.586a12.016 12.016 0 0 1 14.832-2.254l42.584 24.595a191.577 191.577 0 0 1 60.759-35.13V25.759a12.01 12.01 0 0 1 9.377-11.718c34.956-7.85 72.499-8.256 109.219-.007 5.49 1.233 9.403 6.096 9.403 11.723v49.184a191.555 191.555 0 0 1 60.759 35.13l42.584-24.595a12.016 12.016 0 0 1 14.832 2.254c24.718 26.744 43.619 58.944 54.689 94.586 1.667 5.366-.592 11.175-5.459 13.985L444.788 220.9a193.485 193.485 0 0 1 0 70.2zM336 256c0-44.112-35.888-80-80-80s-80 35.888-80 80 35.888 80 80 80 80-35.888 80-80z"], - "exclamation": [192, 512, [], "f12a", "M176 432c0 44.112-35.888 80-80 80s-80-35.888-80-80 35.888-80 80-80 80 35.888 80 80zM25.26 25.199l13.6 272C39.499 309.972 50.041 320 62.83 320h66.34c12.789 0 23.331-10.028 23.97-22.801l13.6-272C167.425 11.49 156.496 0 142.77 0H49.23C35.504 0 24.575 11.49 25.26 25.199z"], - "exclamation-circle": [512, 512, [], "f06a", "M504 256c0 136.997-111.043 248-248 248S8 392.997 8 256C8 119.083 119.043 8 256 8s248 111.083 248 248zm-248 50c-25.405 0-46 20.595-46 46s20.595 46 46 46 46-20.595 46-46-20.595-46-46-46zm-43.673-165.346l7.418 136c.347 6.364 5.609 11.346 11.982 11.346h48.546c6.373 0 11.635-4.982 11.982-11.346l7.418-136c.375-6.874-5.098-12.654-11.982-12.654h-63.383c-6.884 0-12.356 5.78-11.981 12.654z"], - "exclamation-triangle": [576, 512, [], "f071", "M569.517 440.013C587.975 472.007 564.806 512 527.94 512H48.054c-36.937 0-59.999-40.055-41.577-71.987L246.423 23.985c18.467-32.009 64.72-31.951 83.154 0l239.94 416.028zM288 354c-25.405 0-46 20.595-46 46s20.595 46 46 46 46-20.595 46-46-20.595-46-46-46zm-43.673-165.346l7.418 136c.347 6.364 5.609 11.346 11.982 11.346h48.546c6.373 0 11.635-4.982 11.982-11.346l7.418-136c.375-6.874-5.098-12.654-11.982-12.654h-63.383c-6.884 0-12.356 5.78-11.981 12.654z"], - "minus": [448, 512, [], "f068", "M424 318.2c13.3 0 24-10.7 24-24v-76.4c0-13.3-10.7-24-24-24H24c-13.3 0-24 10.7-24 24v76.4c0 13.3 10.7 24 24 24h400z"], - "minus-circle": [512, 512, [], "f056", "M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zM124 296c-6.6 0-12-5.4-12-12v-56c0-6.6 5.4-12 12-12h264c6.6 0 12 5.4 12 12v56c0 6.6-5.4 12-12 12H124z"], - "minus-square": [448, 512, [], "f146", "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM92 296c-6.6 0-12-5.4-12-12v-56c0-6.6 5.4-12 12-12h264c6.6 0 12 5.4 12 12v56c0 6.6-5.4 12-12 12H92z"], - "plus": [448, 512, [], "f067", "M448 294.2v-76.4c0-13.3-10.7-24-24-24H286.2V56c0-13.3-10.7-24-24-24h-76.4c-13.3 0-24 10.7-24 24v137.8H24c-13.3 0-24 10.7-24 24v76.4c0 13.3 10.7 24 24 24h137.8V456c0 13.3 10.7 24 24 24h76.4c13.3 0 24-10.7 24-24V318.2H424c13.3 0 24-10.7 24-24z"], - "plus-circle": [512, 512, [], "f055", "M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm144 276c0 6.6-5.4 12-12 12h-92v92c0 6.6-5.4 12-12 12h-56c-6.6 0-12-5.4-12-12v-92h-92c-6.6 0-12-5.4-12-12v-56c0-6.6 5.4-12 12-12h92v-92c0-6.6 5.4-12 12-12h56c6.6 0 12 5.4 12 12v92h92c6.6 0 12 5.4 12 12v56z"], - "plus-square": [448, 512, [], "f0fe", "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-32 252c0 6.6-5.4 12-12 12h-92v92c0 6.6-5.4 12-12 12h-56c-6.6 0-12-5.4-12-12v-92H92c-6.6 0-12-5.4-12-12v-56c0-6.6 5.4-12 12-12h92v-92c0-6.6 5.4-12 12-12h56c6.6 0 12 5.4 12 12v92h92c6.6 0 12 5.4 12 12v56z"], - "question": [384, 512, [], "f128", "M202.021 0C122.202 0 70.503 32.703 29.914 91.026c-7.363 10.58-5.093 25.086 5.178 32.874l43.138 32.709c10.373 7.865 25.132 6.026 33.253-4.148 25.049-31.381 43.63-49.449 82.757-49.449 30.764 0 68.816 19.799 68.816 49.631 0 22.552-18.617 34.134-48.993 51.164-35.423 19.86-82.299 44.576-82.299 106.405V320c0 13.255 10.745 24 24 24h72.471c13.255 0 24-10.745 24-24v-5.773c0-42.86 125.268-44.645 125.268-160.627C377.504 66.256 286.902 0 202.021 0zM192 373.459c-38.196 0-69.271 31.075-69.271 69.271 0 38.195 31.075 69.27 69.271 69.27s69.271-31.075 69.271-69.271-31.075-69.27-69.271-69.27z"], - "save": [448, 512, [], "f0c7", "M433.941 129.941l-83.882-83.882A48 48 0 0 0 316.118 32H48C21.49 32 0 53.49 0 80v352c0 26.51 21.49 48 48 48h352c26.51 0 48-21.49 48-48V163.882a48 48 0 0 0-14.059-33.941zM224 416c-35.346 0-64-28.654-64-64 0-35.346 28.654-64 64-64s64 28.654 64 64c0 35.346-28.654 64-64 64zm96-304.52V212c0 6.627-5.373 12-12 12H76c-6.627 0-12-5.373-12-12V108c0-6.627 5.373-12 12-12h228.52c3.183 0 6.235 1.264 8.485 3.515l3.48 3.48A11.996 11.996 0 0 1 320 111.48z"], - "search": [512, 512, [], "f002", "M505 442.7L405.3 343c-4.5-4.5-10.6-7-17-7H372c27.6-35.3 44-79.7 44-128C416 93.1 322.9 0 208 0S0 93.1 0 208s93.1 208 208 208c48.3 0 92.7-16.4 128-44v16.3c0 6.4 2.5 12.5 7 17l99.7 99.7c9.4 9.4 24.6 9.4 33.9 0l28.3-28.3c9.4-9.4 9.4-24.6.1-34zM208 336c-70.7 0-128-57.2-128-128 0-70.7 57.2-128 128-128 70.7 0 128 57.2 128 128 0 70.7-57.2 128-128 128z"], - "share": [512, 512, [], "f064", "M503.691 189.836L327.687 37.851C312.281 24.546 288 35.347 288 56.015v80.053C127.371 137.907 0 170.1 0 322.326c0 61.441 39.581 122.309 83.333 154.132 13.653 9.931 33.111-2.533 28.077-18.631C66.066 312.814 132.917 274.316 288 272.085V360c0 20.7 24.3 31.453 39.687 18.164l176.004-152c11.071-9.562 11.086-26.753 0-36.328z"], - "spinner": [512, 512, [], "f110", "M304 48c0 26.51-21.49 48-48 48s-48-21.49-48-48 21.49-48 48-48 48 21.49 48 48zm-48 368c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48-21.49-48-48-48zm208-208c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48-21.49-48-48-48zM96 256c0-26.51-21.49-48-48-48S0 229.49 0 256s21.49 48 48 48 48-21.49 48-48zm12.922 99.078c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48c0-26.509-21.491-48-48-48zm294.156 0c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48c0-26.509-21.49-48-48-48zM108.922 60.922c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48-21.491-48-48-48z"], - "square": [448, 512, [], "f0c8", "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48z"], - "square-full": [512, 512, [], "f45c", "M512 512H0V0h512v512z"], - "times": [384, 512, [], "f00d", "M323.1 441l53.9-53.9c9.4-9.4 9.4-24.5 0-33.9L279.8 256l97.2-97.2c9.4-9.4 9.4-24.5 0-33.9L323.1 71c-9.4-9.4-24.5-9.4-33.9 0L192 168.2 94.8 71c-9.4-9.4-24.5-9.4-33.9 0L7 124.9c-9.4 9.4-9.4 24.5 0 33.9l97.2 97.2L7 353.2c-9.4 9.4-9.4 24.5 0 33.9L60.9 441c9.4 9.4 24.5 9.4 33.9 0l97.2-97.2 97.2 97.2c9.3 9.3 24.5 9.3 33.9 0z"], - "times-circle": [512, 512, [], "f057", "M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm121.6 313.1c4.7 4.7 4.7 12.3 0 17L338 377.6c-4.7 4.7-12.3 4.7-17 0L256 312l-65.1 65.6c-4.7 4.7-12.3 4.7-17 0L134.4 338c-4.7-4.7-4.7-12.3 0-17l65.6-65-65.6-65.1c-4.7-4.7-4.7-12.3 0-17l39.6-39.6c4.7-4.7 12.3-4.7 17 0l65 65.7 65.1-65.6c4.7-4.7 12.3-4.7 17 0l39.6 39.6c4.7 4.7 4.7 12.3 0 17L312 256l65.6 65.1z"], - "wrench": [512, 512, [], "f0ad", "M481.156 200c9.3 0 15.12 10.155 10.325 18.124C466.295 259.992 420.419 288 368 288c-79.222 0-143.501-63.974-143.997-143.079C223.505 65.469 288.548-.001 368.002 0c52.362.001 98.196 27.949 123.4 69.743C496.24 77.766 490.523 88 481.154 88H376l-40 56 40 56h105.156zm-171.649 93.003L109.255 493.255c-24.994 24.993-65.515 24.994-90.51 0-24.993-24.994-24.993-65.516 0-90.51L218.991 202.5c16.16 41.197 49.303 74.335 90.516 90.503zM104 432c0-13.255-10.745-24-24-24s-24 10.745-24 24 10.745 24 24 24 24-10.745 24-24z"], - }; - - function attachDialogCloseHandlerWithParent(parent, closeHandler) { - - var container = document.createElement("div"); - parent.appendChild(container); - container.appendChild(createIcon$1("times")); - container.addEventListener('click', function (e) { - e.preventDefault(); - e.stopPropagation(); - closeHandler(); - }); - } - - var uiUtils = /*#__PURE__*/Object.freeze({ - __proto__: null, - attachDialogCloseHandlerWithParent: attachDialogCloseHandlerWithParent - }); - - /** - * Make the target element movable by clicking and dragging on the handle. This is not a general purprose function, - * it makes several options specific to igv dialogs, the primary one being that the - * target is absolutely positioned in pixel coordinates - - */ - - let dragData; // Its assumed we are only dragging one element at a time. - - function makeDraggable(target, handle, constraint) { - - handle.addEventListener('mousedown', dragStart.bind(target)); - - function dragStart(event) { - - event.stopPropagation(); - event.preventDefault(); - - const dragFunction = drag.bind(this); - const dragEndFunction = dragEnd.bind(this); - const computedStyle = getComputedStyle(this); - - dragData = - { - constraint, - dragFunction, - dragEndFunction, - screenX: event.screenX, - screenY: event.screenY, - top: parseInt(computedStyle.top.replace("px", "")), - left: parseInt(computedStyle.left.replace("px", "")) - }; - - document.addEventListener('mousemove', dragFunction); - document.addEventListener('mouseup', dragEndFunction); - document.addEventListener('mouseleave', dragEndFunction); - document.addEventListener('mouseexit', dragEndFunction); - } - } - - function drag(event) { - - if (!dragData) { - console.error("No drag data!"); - return; - } - event.stopPropagation(); - event.preventDefault(); - const dx = event.screenX - dragData.screenX; - const dy = event.screenY - dragData.screenY; - - const left = dragData.left + dx; - const top = dragData.constraint ? Math.max(dragData.constraint.minY, dragData.top + dy) : dragData.top + dy; - - this.style.left = `${ left }px`; - this.style.top = `${ top }px`; - } - - function dragEnd(event) { - - if (!dragData) { - console.error("No drag data!"); - return; - } - event.stopPropagation(); - event.preventDefault(); - - const dragFunction = dragData.dragFunction; - const dragEndFunction = dragData.dragEndFunction; - document.removeEventListener('mousemove', dragFunction); - document.removeEventListener('mouseup', dragEndFunction); - document.removeEventListener('mouseleave', dragEndFunction); - document.removeEventListener('mouseexit', dragEndFunction); - dragData = undefined; - } - - class Dialog { - - constructor({label, content, okHandler, cancelHandler}) { - - const cancel = () => { - hide(this.elem); - if (typeof cancelHandler === 'function') { - cancelHandler(this); - } - }; - - // dialog container - this.elem = div({class: 'igv-ui-generic-dialog-container'}); - - // dialog header - const header = div({class: 'igv-ui-generic-dialog-header'}); - this.elem.appendChild(header); - - attachDialogCloseHandlerWithParent(header, cancel); - - // dialog label - if(label) { - const labelDiv = div({class: 'igv-ui-dialog-one-liner'}); - this.elem.appendChild(labelDiv); - labelDiv.innerHTML = label; - } - - // input container - content.elem.style.margin = '8px'; - this.elem.appendChild(content.elem); - - // ok | cancel - const buttons = div({class: 'igv-ui-generic-dialog-ok-cancel'}); - this.elem.appendChild(buttons); - - // ok - this.ok = div(); - buttons.appendChild(this.ok); - this.ok.textContent = 'OK'; - - // cancel - this.cancel = div(); - buttons.appendChild(this.cancel); - this.cancel.textContent = 'Cancel'; - - this.ok.addEventListener('click', (e) => { - hide(this.elem); - if (typeof okHandler === 'function') { - okHandler(this); - } - }); - - this.cancel.addEventListener('click', cancel); - - makeDraggable(this.elem, header); - - - // Consume all clicks in component - this.elem.addEventListener('click', (e) => { - e.preventDefault(); - e.stopPropagation(); - }); - - } - - present(options, e) { - - this.label.textContent = options.label; - this.input.value = options.value; - this.callback = options.callback; - - const page = pageCoordinates(e); - this.clampLocation(page.x, page.y); - - show(this.elem); - } - - clampLocation(pageX, pageY) { - - let popoverRect = this.elem.getBoundingClientRect(); - let parentRect = this.parent.getBoundingClientRect(); - const y = Math.min(Math.max(pageY, parentRect.y), parentRect.y + parentRect.height - popoverRect.height); - const x = Math.min(Math.max(pageX, parentRect.x), parentRect.x + parentRect.width - popoverRect.width); - this.elem.style.left = x + "px"; - this.elem.style.top = y + "px"; - } - } - - class DataRangeDialog { - - constructor(parent, okHandler) { - - const panel = new Panel(); - this.minbox = new Textbox({label: "Minimum", value: "0"}); - panel.add(this.minbox); - - this.maxbox = new Textbox({label: "Maximum", value: "0"}); - panel.add(this.maxbox); - - let callback; - if (okHandler) { - callback = (e) => { - okHandler(Number.parseFloat(this.minbox.value), Number.parseFloat(this.maxbox.value)); - }; - } else { - callback = (d) => { - console.log(`Minimum: ${this.minbox.value}`); - console.log(`Maximum: ${this.maxbox.value}`); - }; - } - - this.dialog = new Dialog({ - //label: 'Multi-select', - content: panel, - okHandler: callback - }); - - // Overide some css styles -- TODO redesign this. - this.dialog.elem.style.position = "absolute"; - - hide(this.dialog.elem); - parent.appendChild(this.dialog.elem); - } - - show({min, max}) { - if (min !== undefined) this.minbox.value = min.toString(); - if (max !== undefined) this.maxbox.value = max.toString(); - show(this.dialog.elem); - } - } - - const httpMessages = - { - "401": "Access unauthorized", - "403": "Access forbidden", - "404": "Not found" - }; - - - class AlertDialog { - /** - * Initialize a new alert dialog - * @param parent - * @param alertProps - Optional - properties such as scroll to error - */ - constructor(parent, alertProps) { - this.alertProps = Object.assign({ - /** When an alert is presented - focus occur */ - shouldFocus: true, - /** When focus occur - scroll into that element in the view */ - preventScroll: false - }, alertProps); - - // container - this.container = div({class: "igv-ui-alert-dialog-container"}); - parent.appendChild(this.container); - this.container.setAttribute('tabIndex', '-1'); - - // header - const header = div(); - this.container.appendChild(header); - - this.errorHeadline = div(); - header.appendChild(this.errorHeadline); - this.errorHeadline.textContent = ''; - - // body container - let bodyContainer = div({class: 'igv-ui-alert-dialog-body'}); - this.container.appendChild(bodyContainer); - - // body copy - this.body = div({class: 'igv-ui-alert-dialog-body-copy'}); - bodyContainer.appendChild(this.body); - - // ok container - let ok_container = div(); - this.container.appendChild(ok_container); - - // ok - this.ok = div(); - ok_container.appendChild(this.ok); - this.ok.textContent = 'OK'; - - const okHandler = () => { - - if (typeof this.callback === 'function') { - this.callback("OK"); - this.callback = undefined; - } - this.body.innerHTML = ''; - hide(this.container); - }; - - this.ok.addEventListener('click', event => { - - event.stopPropagation(); - - okHandler(); - }); - - this.container.addEventListener('keypress', event => { - - event.stopPropagation(); - - if ('Enter' === event.key) { - okHandler(); - } - }); - - makeDraggable(this.container, header); - - hide(this.container); - } - - present(alert, callback) { - - this.errorHeadline.textContent = alert.message ? 'ERROR' : ''; - let string = alert.message || alert; - - if (httpMessages.hasOwnProperty(string)) { - string = httpMessages[string]; - } - - this.body.innerHTML = string; - this.callback = callback; - show(this.container); - if (this.alertProps.shouldFocus) { - this.container.focus( - { preventScroll: this.alertProps.preventScroll } - ); - } - } - } - - // The global Alert dialog - - let alertDialog; - - const Alert$1 = { - - init(root, config={}) { - alertDialog = new AlertDialog(root, config); - }, - - presentAlert (alert, callback) { - if(!alertDialog) { - this.init(document.body); - } - alertDialog.present(alert, callback); - }, - }; - - class InputDialog { - - constructor(parent) { - - this.parent = parent; - - // dialog container - this.container = div({class: 'igv-ui-generic-dialog-container'}); - parent.appendChild(this.container); - - // const { x, y, width, height } = this.container.getBoundingClientRect(); - // console.log(`InputDialog - x ${ x } y ${ y } width ${ width } height ${ height }`) - - // dialog header - const header = div({class: 'igv-ui-generic-dialog-header'}); - this.container.appendChild(header); - - // dialog label - this.label = div({class: 'igv-ui-generic-dialog-one-liner'}); - this.container.appendChild(this.label); - this.label.text = 'Unlabeled'; - - // input container - this.input_container = div({class: 'igv-ui-generic-dialog-input'}); - this.container.appendChild(this.input_container); - // - this.input = document.createElement("input"); - this.input_container.appendChild(this.input); - - - // ok | cancel - const buttons = div({class: 'igv-ui-generic-dialog-ok-cancel'}); - this.container.appendChild(buttons); - - // ok - this.ok = div(); - buttons.appendChild(this.ok); - this.ok.textContent = 'OK'; - - // cancel - this.cancel = div(); - buttons.appendChild(this.cancel); - this.cancel.textContent = 'Cancel'; - - hide(this.container); - - this.input.addEventListener('keyup', e => { - if (13 === e.keyCode) { - if (typeof this.callback === 'function') { - this.callback(this.input.value); - this.callback = undefined; - } - this.input.value = undefined; - hide(this.container); - } - }); - - this.ok.addEventListener('click', () => { - if (typeof this.callback === 'function') { - this.callback(this.input.value); - this.callback = undefined; - } - this.input.value = undefined; - hide(this.container); - }); - - const cancel = () => { - this.input.value = ''; - hide(this.container); - }; - - this.cancel.addEventListener('click', cancel); - - attachDialogCloseHandlerWithParent(header, cancel); - makeDraggable(this.container, header); - - } - - present(options, e) { - - this.label.textContent = options.label; - this.input.value = options.value; - this.callback = options.callback || options.click; - - show(this.container); - this.clampLocation(e.clientX, e.clientY); - - } - - clampLocation(clientX, clientY) { - - const { width:w, height:h } = this.container.getBoundingClientRect(); - const wh = window.innerHeight; - const ww = window.innerWidth; - - const y = Math.min(wh - h, clientY); - const x = Math.min(ww - w, clientX); - this.container.style.left = `${ x }px`; - this.container.style.top = `${ y }px`; - - } - } - - const appleCrayonPalette = - { - licorice: "#000000", - lead: "#1e1e1e", - tungsten: "#3a3a3a", - iron: "#545453", - steel: "#6e6e6e", - tin: "#878687", - nickel: "#888787", - aluminum: "#a09fa0", - magnesium: "#b8b8b8", - silver: "#d0d0d0", - mercury: "#e8e8e8", - snow: "#ffffff", - // - cayenne: "#891100", - mocha: "#894800", - aspargus: "#888501", - fern: "#458401", - clover: "#028401", - moss: "#018448", - teal: "#008688", - ocean: "#004a88", - midnight: "#001888", - eggplant: "#491a88", - plum: "#891e88", - maroon: "#891648", - // - maraschino: "#ff2101", - tangerine: "#ff8802", - lemon: "#fffa03", - lime: "#83f902", - spring: "#05f802", - seam_foam: "#03f987", - turquoise: "#00fdff", - aqua: "#008cff", - blueberry: "#002eff", - grape: "#8931ff", - magenta: "#ff39ff", - strawberry: "#ff2987", - // - salmon: "#ff726e", - cantaloupe: "#ffce6e", - banana: "#fffb6d", - honeydew: "#cefa6e", - flora: "#68f96e", - spindrift: "#68fbd0", - ice: "#68fdff", - sky: "#6acfff", - orchid: "#6e76ff", - lavender: "#d278ff", - bubblegum: "#ff7aff", - carnation: "#ff7fd3" - }; - - class GenericContainer { - - constructor({parent, top, left, width, height, border, closeHandler}) { - - let container = div({class: 'igv-ui-generic-container'}); - parent.appendChild(container); - hide(container); - this.container = container; - - if(top !== undefined) { - this.container.style.top = `${ top }px`; - } - if(left !== undefined) { - this.container.style.left = `${ left }px`; - } - if (width !== undefined) { - this.container.style.width = `${ width }px`; - } - if (height !== undefined) { - this.container.style.height = `${ height }px`; - } - if(border) { - this.container.style.border = border; - } - // - // let bbox = parent.getBoundingClientRect(); - // this.origin = {x: bbox.x, y: bbox.y}; - // this.container.offset({left: this.origin.x, top: this.origin.y}); - - // header - const header = div(); - this.container.appendChild(header); - - // close button - attachDialogCloseHandlerWithParent(header, (e) => { - hide(this.container); - if(typeof closeHandler === "function") { - closeHandler(e); - } - }); - - makeDraggable(this.container, header); - } - - show() { - show(this.container); - } - - hide() { - hide(this.container); - } - - dispose() { - if(this.container.parent) { - this.container.parent.removeChild(this.container); - } - } - } - - class ColorPicker extends GenericContainer { - - constructor({parent, top, left, width, height, defaultColors, colorHandler}) { - - super({ parent, top, left, width, height, border: '1px solid gray'}); - - createColorSwatchSelector(this.container, colorHandler, defaultColors); - } - - } - - const createColorSwatchSelector = (container, colorHandler, defaultColors) => { - - const hexColorStrings = Object.values(appleCrayonPalette); - - for (let hexColorString of hexColorStrings) { - const swatch = div({ class: 'igv-ui-color-swatch' }); - container.appendChild(swatch); - decorateSwatch(swatch, hexColorString, colorHandler); - } - - if (defaultColors) { - for (let hexColorString of defaultColors) { - const swatch = div({ class: 'igv-ui-color-swatch' }); - container.appendChild(swatch); - decorateSwatch(swatch, hexColorString, colorHandler); - } - } - - }; - - const decorateSwatch = (swatch, hexColorString, colorHandler) => { - - swatch.style.backgroundColor = hexColorString; - - swatch.addEventListener('mouseenter', e => swatch.style.borderColor = hexColorString); - - swatch.addEventListener('mouseleave', e => swatch.style.borderColor = 'white'); - - swatch.addEventListener('click', event => { - event.stopPropagation(); - colorHandler(hexColorString); - }); - - swatch.addEventListener('touchend', event => { - event.stopPropagation(); - colorHandler(hexColorString); - }); - - }; - - function embedCSS() { - const style = document.createElement('style'); - style.setAttribute('type', 'text/css'); - style.setAttribute('title', 'igv-ui.css'); - style.innerHTML = `.igv-ui-popover { - cursor: default; - position: absolute; - z-index: 2048; - border-color: #7F7F7F; - border-radius: 4px; - border-style: solid; - border-width: 1px; - font-family: "Open Sans", sans-serif; - font-size: small; - background-color: white; -} -.igv-ui-popover > div:first-child { - display: flex; - flex-direction: row; - flex-wrap: nowrap; - justify-content: space-between; - align-items: center; - width: 100%; - height: 24px; - cursor: move; - border-top-left-radius: 4px; - border-top-right-radius: 4px; - border-bottom-color: #7F7F7F; - border-bottom-style: solid; - border-bottom-width: thin; - background-color: #eee; -} -.igv-ui-popover > div:first-child > div:first-child { - margin-left: 4px; -} -.igv-ui-popover > div:first-child > div:last-child { - margin-right: 4px; - height: 12px; - width: 12px; - color: #7F7F7F; -} -.igv-ui-popover > div:first-child > div:last-child:hover { - cursor: pointer; - color: #444; -} -.igv-ui-popover > div:last-child { - overflow-y: auto; - overflow-x: hidden; - max-height: 400px; - max-width: 800px; - background-color: white; -} -.igv-ui-popover > div:last-child > div { - -webkit-user-select: text; - -moz-user-select: text; - -ms-user-select: text; - user-select: text; - margin-left: 4px; - margin-right: 4px; - min-width: 220px; - overflow-x: hidden; - text-overflow: ellipsis; - white-space: nowrap; -} -.igv-ui-popover > div:last-child > div > span { - font-weight: bolder; -} -.igv-ui-popover > div:last-child hr { - width: 100%; -} - -.igv-ui-alert-dialog-container { - box-sizing: content-box; - position: absolute; - z-index: 2048; - top: 50%; - left: 50%; - width: 400px; - height: 200px; - border-color: #7F7F7F; - border-radius: 4px; - border-style: solid; - border-width: thin; - outline: none; - font-family: "Open Sans", sans-serif; - font-size: 15px; - font-weight: 400; - background-color: white; - display: flex; - flex-flow: column; - flex-wrap: nowrap; - justify-content: space-between; - align-items: center; -} -.igv-ui-alert-dialog-container > div:first-child { - display: flex; - flex-flow: row; - flex-wrap: nowrap; - justify-content: flex-start; - align-items: center; - width: 100%; - height: 24px; - cursor: move; - border-top-left-radius: 4px; - border-top-right-radius: 4px; - border-bottom-color: #7F7F7F; - border-bottom-style: solid; - border-bottom-width: thin; - background-color: #eee; -} -.igv-ui-alert-dialog-container > div:first-child div:first-child { - padding-left: 8px; -} -.igv-ui-alert-dialog-container .igv-ui-alert-dialog-body { - -webkit-user-select: text; - -moz-user-select: text; - -ms-user-select: text; - user-select: text; - color: #373737; - width: 100%; - height: calc(100% - 24px - 64px); - overflow-y: scroll; -} -.igv-ui-alert-dialog-container .igv-ui-alert-dialog-body .igv-ui-alert-dialog-body-copy { - margin: 16px; - width: auto; - height: auto; - overflow-wrap: break-word; - word-break: break-word; - background-color: white; - border: unset; -} -.igv-ui-alert-dialog-container > div:last-child { - width: 100%; - margin-bottom: 10px; - background-color: white; - display: flex; - flex-flow: row; - flex-wrap: nowrap; - justify-content: center; - align-items: center; -} -.igv-ui-alert-dialog-container > div:last-child div { - margin: unset; - width: 40px; - height: 30px; - line-height: 30px; - text-align: center; - color: white; - font-family: "Open Sans", sans-serif; - font-size: small; - font-weight: 400; - border-color: #2B81AF; - border-style: solid; - border-width: thin; - border-radius: 4px; - background-color: #2B81AF; -} -.igv-ui-alert-dialog-container > div:last-child div:hover { - cursor: pointer; - border-color: #25597f; - background-color: #25597f; -} - -.igv-ui-color-swatch { - position: relative; - box-sizing: content-box; - display: flex; - flex-flow: row; - flex-wrap: wrap; - justify-content: center; - align-items: center; - width: 32px; - height: 32px; - border-style: solid; - border-width: 2px; - border-color: white; - border-radius: 4px; -} - -.igv-ui-color-swatch:hover { - border-color: dimgray; -} - -.igv-ui-colorpicker-menu-close-button { - display: flex; - flex-flow: row; - flex-wrap: nowrap; - justify-content: flex-end; - align-items: center; - width: 100%; - height: 32px; - margin-top: 4px; - margin-bottom: 4px; - padding-right: 8px; -} -.igv-ui-colorpicker-menu-close-button i.fa { - display: block; - margin-left: 4px; - margin-right: 4px; - color: #5f5f5f; -} -.igv-ui-colorpicker-menu-close-button i.fa:hover, -.igv-ui-colorpicker-menu-close-button i.fa:focus, -.igv-ui-colorpicker-menu-close-button i.fa:active { - cursor: pointer; - color: #0f0f0f; -} - -.igv-ui-generic-dialog-container { - box-sizing: content-box; - position: fixed; - top: 0; - left: 0; - width: 300px; - height: 200px; - border-color: #7F7F7F; - border-radius: 4px; - border-style: solid; - border-width: thin; - font-family: "Open Sans", sans-serif; - font-size: medium; - font-weight: 400; - z-index: 2048; - background-color: white; - display: flex; - flex-flow: column; - flex-wrap: nowrap; - justify-content: flex-start; - align-items: center; -} -.igv-ui-generic-dialog-container .igv-ui-generic-dialog-header { - display: flex; - flex-flow: row; - flex-wrap: nowrap; - justify-content: flex-end; - align-items: center; - width: 100%; - height: 24px; - cursor: move; - border-top-left-radius: 4px; - border-top-right-radius: 4px; - border-bottom-color: #7F7F7F; - border-bottom-style: solid; - border-bottom-width: thin; - background-color: #eee; -} -.igv-ui-generic-dialog-container .igv-ui-generic-dialog-header div { - margin-right: 4px; - margin-bottom: 2px; - height: 12px; - width: 12px; - color: #7F7F7F; -} -.igv-ui-generic-dialog-container .igv-ui-generic-dialog-header div:hover { - cursor: pointer; - color: #444; -} -.igv-ui-generic-dialog-container .igv-ui-generic-dialog-one-liner { - color: #373737; - width: 95%; - height: 24px; - line-height: 24px; - text-align: left; - margin-top: 8px; - padding-left: 8px; - overflow-wrap: break-word; - background-color: white; -} -.igv-ui-generic-dialog-container .igv-ui-generic-dialog-label-input { - margin-top: 8px; - width: 95%; - height: 24px; - color: #373737; - line-height: 24px; - padding-left: 8px; - background-color: white; - display: flex; - flex-flow: row; - flex-wrap: nowrap; - justify-content: flex-start; - align-items: center; -} -.igv-ui-generic-dialog-container .igv-ui-generic-dialog-label-input div { - width: 30%; - height: 100%; - font-size: 16px; - text-align: right; - padding-right: 8px; - background-color: white; -} -.igv-ui-generic-dialog-container .igv-ui-generic-dialog-label-input input { - display: block; - height: 100%; - width: 100%; - padding-left: 4px; - font-family: "Open Sans", sans-serif; - font-weight: 400; - color: #373737; - text-align: left; - outline: none; - border-style: solid; - border-width: thin; - border-color: #7F7F7F; - background-color: white; -} -.igv-ui-generic-dialog-container .igv-ui-generic-dialog-label-input input { - width: 50%; - font-size: 16px; -} -.igv-ui-generic-dialog-container .igv-ui-generic-dialog-input { - margin-top: 8px; - width: calc(100% - 16px); - height: 24px; - color: #373737; - line-height: 24px; - display: flex; - flex-flow: row; - flex-wrap: nowrap; - justify-content: space-around; - align-items: center; -} -.igv-ui-generic-dialog-container .igv-ui-generic-dialog-input input { - display: block; - height: 100%; - width: 100%; - padding-left: 4px; - font-family: "Open Sans", sans-serif; - font-weight: 400; - color: #373737; - text-align: left; - outline: none; - border-style: solid; - border-width: thin; - border-color: #7F7F7F; - background-color: white; -} -.igv-ui-generic-dialog-container .igv-ui-generic-dialog-input input { - font-size: 16px; -} -.igv-ui-generic-dialog-container .igv-ui-generic-dialog-ok-cancel { - width: 100%; - height: 28px; - display: flex; - flex-flow: row; - flex-wrap: nowrap; - justify-content: space-around; - align-items: center; -} -.igv-ui-generic-dialog-container .igv-ui-generic-dialog-ok-cancel div { - margin-top: 32px; - color: white; - font-family: "Open Sans", sans-serif; - font-size: 14px; - font-weight: 400; - width: 75px; - height: 28px; - line-height: 28px; - text-align: center; - border-color: transparent; - border-style: solid; - border-width: thin; - border-radius: 2px; -} -.igv-ui-generic-dialog-container .igv-ui-generic-dialog-ok-cancel div:first-child { - margin-left: 32px; - margin-right: 0; - background-color: #5ea4e0; -} -.igv-ui-generic-dialog-container .igv-ui-generic-dialog-ok-cancel div:last-child { - margin-left: 0; - margin-right: 32px; - background-color: #c4c4c4; -} -.igv-ui-generic-dialog-container .igv-ui-generic-dialog-ok-cancel div:first-child:hover { - cursor: pointer; - background-color: #3b5c7f; -} -.igv-ui-generic-dialog-container .igv-ui-generic-dialog-ok-cancel div:last-child:hover { - cursor: pointer; - background-color: #7f7f7f; -} -.igv-ui-generic-dialog-container .igv-ui-generic-dialog-ok { - width: 100%; - height: 36px; - margin-top: 32px; - display: flex; - flex-flow: row; - flex-wrap: nowrap; - justify-content: space-around; - align-items: center; -} -.igv-ui-generic-dialog-container .igv-ui-generic-dialog-ok div { - width: 98px; - height: 36px; - line-height: 36px; - text-align: center; - color: white; - font-family: "Open Sans", sans-serif; - font-size: medium; - font-weight: 400; - border-color: white; - border-style: solid; - border-width: thin; - border-radius: 4px; - background-color: #2B81AF; -} -.igv-ui-generic-dialog-container .igv-ui-generic-dialog-ok div:hover { - cursor: pointer; - background-color: #25597f; -} - -.igv-ui-generic-container { - box-sizing: content-box; - position: absolute; - z-index: 2048; - background-color: white; - cursor: pointer; - display: flex; - flex-direction: row; - flex-wrap: wrap; - justify-content: flex-start; - align-items: center; -} -.igv-ui-generic-container > div:first-child { - cursor: move; - display: flex; - flex-flow: row; - flex-wrap: nowrap; - justify-content: flex-end; - align-items: center; - height: 24px; - width: 100%; - background-color: #dddddd; -} -.igv-ui-generic-container > div:first-child > div { - display: block; - color: #5f5f5f; - cursor: pointer; - width: 14px; - height: 14px; - margin-right: 8px; - margin-bottom: 4px; -} - -.igv-ui-dialog { - z-index: 2048; - position: fixed; - width: fit-content; - height: fit-content; - display: flex; - flex-flow: column; - flex-wrap: nowrap; - justify-content: flex-start; - background-color: white; - border-color: #7F7F7F; - border-radius: 4px; - border-style: solid; - border-width: thin; - font-family: "Open Sans", sans-serif; - font-size: medium; - font-weight: 400; -} -.igv-ui-dialog .igv-ui-dialog-header { - display: flex; - flex-flow: row; - flex-wrap: nowrap; - justify-content: flex-end; - align-items: center; - width: 100%; - height: 24px; - cursor: move; - border-top-left-radius: 4px; - border-top-right-radius: 4px; - border-bottom-color: #7F7F7F; - border-bottom-style: solid; - border-bottom-width: thin; - background-color: #eee; -} -.igv-ui-dialog .igv-ui-dialog-header div { - margin-right: 4px; - margin-bottom: 2px; - height: 12px; - width: 12px; - color: #7F7F7F; -} -.igv-ui-dialog .igv-ui-dialog-header div:hover { - cursor: pointer; - color: #444; -} -.igv-ui-dialog .igv-ui-dialog-one-liner { - width: 95%; - height: 24px; - line-height: 24px; - text-align: left; - margin: 8px; - overflow-wrap: break-word; - background-color: white; - font-weight: bold; -} -.igv-ui-dialog .igv-ui-dialog-ok-cancel { - width: 100%; - display: flex; - flex-flow: row; - flex-wrap: nowrap; - justify-content: space-around; - align-items: center; -} -.igv-ui-dialog .igv-ui-dialog-ok-cancel div { - margin: 16px; - margin-top: 32px; - color: white; - font-family: "Open Sans", sans-serif; - font-size: 14px; - font-weight: 400; - width: 75px; - height: 28px; - line-height: 28px; - text-align: center; - border-color: transparent; - border-style: solid; - border-width: thin; - border-radius: 2px; -} -.igv-ui-dialog .igv-ui-dialog-ok-cancel div:first-child { - background-color: #5ea4e0; -} -.igv-ui-dialog .igv-ui-dialog-ok-cancel div:last-child { - background-color: #c4c4c4; -} -.igv-ui-dialog .igv-ui-dialog-ok-cancel div:first-child:hover { - cursor: pointer; - background-color: #3b5c7f; -} -.igv-ui-dialog .igv-ui-dialog-ok-cancel div:last-child:hover { - cursor: pointer; - background-color: #7f7f7f; -} -.igv-ui-dialog .igv-ui-dialog-ok { - width: 100%; - height: 36px; - margin-top: 32px; - display: flex; - flex-flow: row; - flex-wrap: nowrap; - justify-content: space-around; - align-items: center; -} -.igv-ui-dialog .igv-ui-dialog-ok div { - width: 98px; - height: 36px; - line-height: 36px; - text-align: center; - color: white; - font-family: "Open Sans", sans-serif; - font-size: medium; - font-weight: 400; - border-color: white; - border-style: solid; - border-width: thin; - border-radius: 4px; - background-color: #2B81AF; -} -.igv-ui-dialog .igv-ui-dialog-ok div:hover { - cursor: pointer; - background-color: #25597f; -} - -.igv-ui-panel, .igv-ui-panel-row, .igv-ui-panel-column { - z-index: 2048; - background-color: white; - font-family: "Open Sans", sans-serif; - font-size: medium; - font-weight: 400; - display: flex; - justify-content: flex-start; - align-items: flex-start; -} - -.igv-ui-panel-column { - display: flex; - flex-direction: column; -} - -.igv-ui-panel-row { - display: flex; - flex-direction: row; -} - -.igv-ui-textbox { - background-color: white; - font-family: "Open Sans", sans-serif; - font-size: medium; - font-weight: 400; - display: flex; - justify-content: flex-start; - align-items: flex-start; -} - -.igv-ui-table { - background-color: white; -} - -.igv-ui-table thead { - position: sticky; - top: 0; -} - -.igv-ui-table th { - text-align: left; -} - -.igv-ui-table td { - padding-right: 20px; -} - -.igv-ui-table tr:hover { - background-color: lightblue; -} - -/*# sourceMappingURL=igv-ui.css.map */ -`; - document.head.append(style); - } - - if (typeof document !== 'undefined') { - - if (!stylesheetExists("igv-ui.css")) { - embedCSS(); - } - - function stylesheetExists(stylesheetName) { - for (let ss of document.styleSheets) { - ss = ss.href ? ss.href.replace(/^.*[\\\/]/, '') : ''; - if (ss === stylesheetName) { - return true - } - } - return false - } - } - - /* - * The MIT License (MIT) - * - * Copyright (c) 2016-2017 The Regents of the University of California - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and - * associated documentation files (the "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the - * following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING - * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - */ - - function isMobile() { - return (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)); - } - - function throttle(fn, threshhold, scope) { - var last, - deferTimer; - - threshhold || (threshhold = 200); - - return function () { - var context, - now, - args; - - context = scope || this; - now = +new Date; - args = arguments; - - if (last && now < last + threshhold) { - // hold on to it - clearTimeout(deferTimer); - deferTimer = setTimeout(function () { - last = now; - fn.apply(context, args); - }, threshhold); - } else { - last = now; - fn.apply(context, args); - } - } - } - - function getExtension(url) { - - if (undefined === url) { - return undefined - } - - let path = (isFile$2(url) || url.google_url) ? url.name : url; - let filename = path.toLowerCase(); - - //Strip parameters -- handle local files later - let index = filename.indexOf("?"); - if (index > 0) { - filename = filename.substr(0, index); - } - - //Strip aux extensions .gz, .tab, and .txt - if (filename.endsWith(".gz")) { - filename = filename.substr(0, filename.length - 3); - } else if (filename.endsWith(".txt") || filename.endsWith(".tab") || filename.endsWith(".bgz")) { - filename = filename.substr(0, filename.length - 4); - } - - index = filename.lastIndexOf("."); - - return index < 0 ? filename : filename.substr(1 + index) - } - - const Globals = {}; - - /* - * The MIT License (MIT) - * - * Copyright (c) 2016-2017 The Regents of the University of California - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and - * associated documentation files (the "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the - * following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING - * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - */ - - - /** - * @author Jim Robinson - */ - - - /** - * Barebones event bus. - */ - - class EventBus { - - constructor() { - - // Map eventType -> list of subscribers - this.subscribers = {}; - - this.stack = []; - } - - subscribe(eventType, object) { - - var subscriberList = this.subscribers[eventType]; - if (subscriberList == undefined) { - subscriberList = []; - this.subscribers[eventType] = subscriberList; - } - subscriberList.push(object); - - } - - post(event) { - - const eventType = event.type; - - if (this._hold) { - this.stack.push(event); - } else { - const subscriberList = this.subscribers[eventType]; - - if (subscriberList) { - for (let subscriber of subscriberList) { - - if ("function" === typeof subscriber.receiveEvent) { - subscriber.receiveEvent(event); - } else if ("function" === typeof subscriber) { - subscriber(event); - } - } - } - } - } - - hold() { - this._hold = true; - } - - release() { - this._hold = false; - for (let event of this.stack) { - this.post(event); - } - this.stack = []; - } - } - - // The global event bus - - EventBus.globalBus = new EventBus(); - - class Track2D { - - static DisplayModes = { - lower: 0b01, - upper: 0b10, - both: 0b01 | 0b10, - } - - constructor(config, features) { - - this.config = config; - this.name = config.name; - - if (config.color && validateColor(config.color)) { - this.color = this.color = config.color; // If specified, this will override colors of individual records. - } - - this.displayMode = config.displayMode; // Can be undefined => both - - this.isVisible = undefined === config.isVisible ? true : config.isVisible; - - this.repColor = features.length > 0 ? features[0].color : "black"; - - this.featureMap = {}; - this.featureCount = 0; - for (let f of features) { - this.featureCount++; - const key = getKey(f.chr1, f.chr2); - let list = this.featureMap[key]; - if (!list) { - list = []; - this.featureMap[key] = list; - } - list.push(f); - } - } - - static async loadTrack2D(config, genome) { - - const data = await igvxhr$1.loadString(config.url, buildOptions(config)); - const features = parseData(data, isBedPE(config), genome); - return new Track2D(config, features) - } - - getColor() { - return this.color || this.repColor - } - - getFeatures(chr1, chr2) { - const key = getKey(chr1, chr2); - return this.featureMap[key] - } - - toJSON() { - const json = - { - url: this.config.url - }; - if (this.name) { - json.name = this.name; - } - if (this.color) { - json.color = this.color; - } - if (this.displayMode) { - json.displayMode = this.displayMode; - } - if (!this.isVisible) { - json.isVisible = this.isVisible; - } - - return json - - } - - } - - - function isBedPE(config) { - - if (typeof config.url === "string") { - return config.url.toLowerCase().indexOf(".bedpe") > 0 - } else if (typeof config.name === "string") { - return config.name.toLowerCase().indexOf(".bedpe") > 0 - } else { - return true // Default - } - } - - function parseData(data, isBedPE, genome) { - - if (!data) return null - - const lines = splitLines$6(data); - const allFeatures = []; - const delimiter = "\t"; - const colorColumn = isBedPE ? 10 : 6; - - let errorCount = 0; - for (let line of lines) { - line = line.trim(); - if (line.startsWith("#") || line.startsWith("track") || line.startsWith("browser") || line.length === 0) { - continue - } - const tokens = line.split(delimiter); - if (tokens.length < 6 && errorCount <= 5) { - if (errorCount === 5) { - console.error("..."); - } else { - console.error("Could not parse line: " + line); - } - errorCount++; - continue - } - - const feature = { - chr1: genome ? genome.getChromosomeName(tokens[0]) : tokens[0], - x1: parseInt(tokens[1]), - x2: parseInt(tokens[2]), - chr2: genome ? genome.getChromosomeName(tokens[3]) : tokens[3], - y1: parseInt(tokens[4]), - y2: parseInt(tokens[5]) - }; - - if (tokens.length > colorColumn) { - feature.color = "rgb(" + tokens[colorColumn] + ")"; - } - - if (!Number.isNaN(feature.x1)) { - allFeatures.push(feature); - } - } - - return allFeatures - } - - function getKey(chr1, chr2) { - return chr1 > chr2 ? chr2 + "_" + chr1 : chr1 + "_" + chr2 - } - - function validateColor(str) { - var div = document.createElement("div"); - div.style.borderColor = str; - return div.style.borderColor !== "" - } - - function buildOptions(config, options) { - const defaultOptions = { - oauthToken: config.oauthToken, - headers: config.headers, - withCredentials: config.withCredentials, - filename: config.filename - }; - - return Object.assign(defaultOptions, options) - } - - /* - * The MIT License (MIT) - * - * Copyright (c) 2016-2017 The Regents of the University of California - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and - * associated documentation files (the "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the - * following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING - * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - */ - - class Ruler { - - constructor(browser, parentElement, axis) { - this.browser = browser; - this.axis = axis; - - this.axisElement = parentElement.querySelector(`div[id$='-axis']`); - - this.canvasElement = parentElement.querySelector("canvas"); - - this.ctx = this.canvasElement.getContext("2d"); - this.ctx.canvas.width = this.axisElement.offsetWidth; - this.ctx.canvas.height = this.axisElement.offsetHeight; - - this.wholeGenomeContainerElement = parentElement.querySelector("div[id$='-axis-whole-genome-container']"); - - this.setAxisTransform(axis); - - browser.eventBus.subscribe('MapLoad', this); - browser.eventBus.subscribe("UpdateContactMapMousePosition", this); - } - - wholeGenomeLayout(axisElement, wholeGenomeContainerElement, axisName, dataset) { - - const decorate = (div) => { - div.addEventListener('click', () => { - this.browser.parseGotoInput(div.textContent); - this.unhighlightWholeChromosome(); - this.otherRuler.unhighlightWholeChromosome(); - }); - - div.addEventListener('mouseenter', () => { - hoverHandler.call(this, div, true); - }); - - div.addEventListener('mouseleave', () => { - hoverHandler.call(this, div, false); - }); - }; - - const hoverHandler = (element, doHover) => { - const targetLabel = element.dataset.label; - - Array.from(this.otherRuler.wholeGenomeContainerElement.children).forEach(child => { - if (child.dataset.label === targetLabel) { - if (doHover) { - element.classList.add('hic-whole-genome-chromosome-highlight'); - child.classList.add('hic-whole-genome-chromosome-highlight'); - } else { - element.classList.remove('hic-whole-genome-chromosome-highlight'); - child.classList.remove('hic-whole-genome-chromosome-highlight'); - } - } - }); - }; - let list, dimen, extent, scraps, firstDivElement; - - // discard current tiles - wholeGenomeContainerElement.innerHTML = ''; - - list = dataset.chromosomes.filter(chromosome => chromosome.name.toLowerCase() !== 'all'); - - extent = list.reduce((sum, chromosome) => sum + chromosome.size, 0); - - dimen = axisName === 'x' ? axisElement.offsetWidth : axisElement.offsetHeight; - - scraps = 0; - this.bboxes = []; - firstDivElement = undefined; - - for (const chr of list) { - const percentage = chr.bpLength / extent; - - if (percentage * dimen < 1.0) { - scraps += percentage; - } else { - const divElement = document.createElement('div'); - divElement.className = `${this.axis}-axis-whole-genome-chromosome-container`; - divElement.dataset.label = chr.name; - wholeGenomeContainerElement.appendChild(divElement); - - if (!firstDivElement) { - firstDivElement = divElement; - } - - const size = Math.round(percentage * dimen); - if (axisName === 'x') { - divElement.style.width = `${size}px`; - } else { - divElement.style.height = `${size}px`; - } - - // Border - const borderElement = document.createElement('div'); - divElement.appendChild(borderElement); - - // Label - const labelElement = document.createElement('div'); - borderElement.appendChild(labelElement); - - labelElement.textContent = divElement.dataset.label; - labelElement.title = divElement.dataset.label; - - decorate(divElement); - } - } - - scraps = Math.floor(scraps * dimen); - if (scraps >= 1) { - - const divElement = document.createElement('div'); - wholeGenomeContainerElement.appendChild(divElement); - - divElement.className = `${this.axis}-axis-whole-genome-chromosome-container`; - divElement.dataset.label = '-'; - divElement.style.width = `${scraps}px`; - - decorate(divElement); - } - - for (const child of wholeGenomeContainerElement.children) { - this.bboxes.push(bbox(axisName, child, firstDivElement)); - } - - this.hideWholeGenome(); - - } - - hideWholeGenome() { - this.wholeGenomeContainerElement.style.display = 'none'; - this.canvasElement.style.display = 'block'; - } - - showWholeGenome() { - this.canvasElement.style.display = 'none'; - this.wholeGenomeContainerElement.style.display = 'flex'; - } - - setAxisTransform(axis) { - - this.canvasTransform = ('y' === axis) ? canvasTransformWithContext : identityTransformWithContext; - this.labelTransform = ('y' === axis) ? labelTransformWithContext : noopTransformWithContext; - - } - - unhighlightWholeChromosome() { - for (const child of this.wholeGenomeContainerElement.children) { - child.classList.remove('hic-whole-genome-chromosome-highlight'); - } - } - - receiveEvent(event) { - let offset, element; - - if (event.type === 'MapLoad') { - this.wholeGenomeLayout(this.axisElement, this.wholeGenomeContainerElement, this.axis, event.data); - this.update(); - } else if (event.type === 'UpdateContactMapMousePosition') { - if (this.bboxes) { - this.unhighlightWholeChromosome(); - offset = this.axis === 'x' ? event.data.x : event.data.y; - element = hitTest(this.bboxes, offset); - if (element) { - element.classList.add('hic-whole-genome-chromosome-highlight'); - } - } - } - } - - locusChange(event) { - - this.update(); - - } - - updateWidthWithCalculation(calc) { - this.axisElement.style.width = calc; - - const axisWidth = this.axisElement.offsetWidth; - this.canvasElement.width = axisWidth; - this.canvasElement.setAttribute('width', axisWidth); - - this.wholeGenomeLayout(this.axisElement, this.wholeGenomeContainerElement, this.axis, this.browser.dataset); - this.update(); - } - - updateHeight(height) { - this.canvasElement.height = height; - this.canvasElement.setAttribute('height', height); - - this.wholeGenomeLayout(this.axisElement, this.wholeGenomeContainerElement, this.axis, this.browser.dataset); - this.update(); - } - - update() { - const browser = this.browser; - const config = {}; - - if (browser.dataset.isWholeGenome(browser.state.chr1)) { - this.showWholeGenome(); - return; - } - - this.hideWholeGenome(); - - identityTransformWithContext(this.ctx); - index$1.IGVGraphics.fillRect( - this.ctx, - 0, - 0, - this.canvasElement.width, - this.canvasElement.height, - { fillStyle: IGVColor$1.rgbColor(255, 255, 255) } - ); - - this.canvasTransform(this.ctx); - - const width = this.axis === 'x' ? this.canvasElement.width : this.canvasElement.height; - const height = this.axis === 'x' ? this.canvasElement.height : this.canvasElement.width; - - index$1.IGVGraphics.fillRect( - this.ctx, - 0, - 0, - width, - height, - { fillStyle: IGVColor$1.rgbColor(255, 255, 255) } - ); - - config.bpPerPixel = browser.dataset.bpResolutions[browser.state.zoom] / browser.state.pixelSize; - const bin = this.axis === 'x' ? browser.state.x : browser.state.y; - config.bpStart = bin * browser.dataset.bpResolutions[browser.state.zoom]; - - config.rulerTickMarkReferencePixels = Math.max( - this.canvasElement.width, - this.canvasElement.height, - this.otherRulerCanvas.width, - this.otherRulerCanvas.height - ); - - config.rulerLengthPixels = width; - config.rulerHeightPixels = height; - - config.height = Math.min(this.canvasElement.width, this.canvasElement.height); - - this.draw(config); - } - - draw(options) { - const { - rulerLengthPixels, - rulerHeightPixels, - rulerTickMarkReferencePixels, - bpPerPixel, - bpStart, - chrName - } = options; - - const { chromosomes } = this.browser.dataset; - const { state } = this.browser; - const axisIsX = this.axis === 'x'; - const chr = axisIsX ? chromosomes[state.chr1] : chromosomes[state.chr2]; - const { name: chrNameSelected, size: chrSize } = chr; - - if (chrName !== "all") { - // Clear the ruler area - index$1.IGVGraphics.fillRect(this.ctx, 0, 0, rulerLengthPixels, rulerHeightPixels, { - fillStyle: IGVColor$1.rgbColor(255, 255, 255) - }); - - const fontStyle = { - textAlign: 'center', - font: '9px PT Sans', - fillStyle: "rgba(64, 64, 64, 1)", - strokeStyle: "rgba(64, 64, 64, 1)" - }; - - const tickSpec = findSpacing(Math.floor(rulerTickMarkReferencePixels * bpPerPixel)); - const majorTickSpacing = tickSpec.majorTick; - - let nTick = Math.floor(bpStart / majorTickSpacing) - 1; - let pixel = 0; - let pixelLast = 0; - - index$1.IGVGraphics.setProperties(this.ctx, fontStyle); - this.ctx.lineWidth = 1.0; - - const yShim = 1; - const tickHeight = 8; - - while (pixel < rulerLengthPixels) { - const l = Math.floor(nTick * majorTickSpacing); - pixel = Math.round(((l - 1) - bpStart + 0.5) / bpPerPixel); - - const rulerLabel = `${formatNumber(l / tickSpec.unitMultiplier, 0)} ${tickSpec.majorUnit}`; - const tickSpacingPixels = Math.abs(pixel - pixelLast); - const labelWidthPixels = this.ctx.measureText(rulerLabel).width; - - const modulo = labelWidthPixels > tickSpacingPixels - ? (tickSpacingPixels < 32 ? 4 : 2) - : 1; - - if (nTick % modulo === 0) { - if (Math.floor((pixel * bpPerPixel) + bpStart) < chrSize) { - this.ctx.save(); - this.labelTransform(this.ctx, pixel); - index$1.IGVGraphics.fillText(this.ctx, rulerLabel, pixel, options.height - (tickHeight / 0.75)); - this.ctx.restore(); - } - } - - if (Math.floor((pixel * bpPerPixel) + bpStart) < chrSize) { - index$1.IGVGraphics.strokeLine( - this.ctx, - pixel, options.height - tickHeight, - pixel, options.height - yShim - ); - } - - pixelLast = pixel; - nTick++; - } - - // Draw the baseline - index$1.IGVGraphics.strokeLine(this.ctx, 0, options.height - yShim, rulerLengthPixels, options.height - yShim); - } - } - } - - const formatNumber = (num, decimal = 0) => { - // Ensure decimal is between 0 and 3 - const precision = Math.min(Math.max(decimal, 0), 3); - - // Round the number to the desired decimal places - const roundedNum = Math.abs(num).toFixed(precision); - - // Split the integer and decimal parts - let [integerPart, decimalPart] = roundedNum.split("."); - - // Add commas to the integer part - integerPart = parseInt(integerPart, 10).toLocaleString(); - - // Pad the decimal part with zeros if necessary - if (precision > 0) { - decimalPart = decimalPart.padEnd(precision, "0"); - } - - // Combine integer and decimal parts - let formattedNum = precision > 0 ? `${integerPart}.${decimalPart}` : integerPart; - - // Wrap in parentheses if the original number was negative - if (num < 0) { - formattedNum = `(${formattedNum})`; - } - - // Optionally, prepend a dollar sign - // formattedNum = `$${formattedNum}`; - - return formattedNum; - }; - - function bbox(axis, childElement, firstChildElement) { - const offset = axis === 'x' - ? childElement.getBoundingClientRect().left - : childElement.getBoundingClientRect().top; - - const firstOffset = axis === 'x' - ? firstChildElement.getBoundingClientRect().left - : firstChildElement.getBoundingClientRect().top; - - const delta = offset - firstOffset; - const size = axis === 'x' - ? childElement.offsetWidth - : childElement.offsetHeight; - - return { element: childElement, a: delta, b: delta + size }; - } - - function hitTest(bboxes, value) { - - let hitElement = undefined; - - for (const bbox of bboxes) { - if (value >= bbox.a && value <= bbox.b) { - hitElement = bbox.element; - break; - } - } - - return hitElement; - } - - function TickSpacing(majorTick, majorUnit, unitMultiplier) { - this.majorTick = majorTick; - this.majorUnit = majorUnit; - this.unitMultiplier = unitMultiplier; - } - - function findSpacing(rulerLengthBP) { - - if (rulerLengthBP < 10) { - return new TickSpacing(1, "", 1); - } - - - // How many zeroes? - var nZeroes = Math.floor(log10(rulerLengthBP)); - var majorUnit = ""; - var unitMultiplier = 1; - if (nZeroes > 9) { - majorUnit = "gb"; - unitMultiplier = 1000000000; - } - if (nZeroes > 6) { - majorUnit = "mb"; - unitMultiplier = 1000000; - } else if (nZeroes > 3) { - majorUnit = "kb"; - unitMultiplier = 1000; - } - - var nMajorTicks = rulerLengthBP / Math.pow(10, nZeroes - 1); - if (nMajorTicks < 25) { - return new TickSpacing(Math.pow(10, nZeroes - 1), majorUnit, unitMultiplier); - } else { - return new TickSpacing(Math.pow(10, nZeroes) / 2, majorUnit, unitMultiplier); - } - - function log10(x) { - var dn = Math.log(10); - return Math.log(x) / dn; - } - } - - function canvasTransformWithContext(ctx) { - ctx.setTransform(0, 1, 1, 0, 0, 0); - } - - function labelTransformWithContext(context, exe) { - context.translate(exe, 0); - context.scale(-1, 1); - context.translate(-exe, 0); - } - - function identityTransformWithContext(context) { - // 3x2 matrix. column major. (sx 0 0 sy tx ty). - context.setTransform(1, 0, 0, 1, 0, 0); - } - - function noopTransformWithContext(ctx) { - - } - - /* - * The MIT License (MIT) - * - * Copyright (c) 2016-2017 The Regents of the University of California - * Author: Jim Robinson - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * - * This class uses icons from Font Awesome - * Font Awesome Free 5.0.8 by @fontawesome - https://fontawesome.com - * License - https://fontawesome.com/license (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) - */ - - const createCheckbox = (name, initialState) => { - // Create the container div - const container = document.createElement('div'); - container.className = 'jb-igv-menu-popup-check-container'; - - // Create the inner div - const div = document.createElement('div'); - container.appendChild(div); - - // Create the check icon using the existing iconMarkup function - const svg = iconMarkup('check', initialState === true ? '#444' : 'transparent'); - div.appendChild(svg); - - // Create the label div - const label = document.createElement('div'); - label.textContent = name; - // Optional: Add a class to the label if needed - // label.className = 'igv-some-label-class'; - - container.appendChild(label); - - return container; - }; - - function createIcon(name, color) { - return iconMarkup(name, color); - } - - const iconMarkup = (name, color = "currentColor") => { - const icon = icons[name] ?? icons["question"]; - - if (!icons[name]) { - console.error(`No icon named: ${name}`); - } - - const [width, height, , , pathData] = icon; - - // Create the SVG element with the correct namespace - const svgNS = "http://www.w3.org/2000/svg"; - const svg = document.createElementNS(svgNS, "svg"); - - // Set SVG attributes - svg.setAttribute("viewBox", `0 0 ${width} ${height}`); - svg.setAttribute("xmlns", svgNS); - svg.setAttribute("aria-label", `${name} icon`); - svg.setAttribute("role", "img"); - - // Create the path element - const path = document.createElementNS(svgNS, "path"); - path.setAttribute("fill", color); - path.setAttribute("d", pathData); - - // Append the path to the SVG - svg.appendChild(path); - - return svg; - }; - - const icons = { - "check": [512, 512, [], "f00c", "M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z"], - "cog": [512, 512, [], "f013", "M444.788 291.1l42.616 24.599c4.867 2.809 7.126 8.618 5.459 13.985-11.07 35.642-29.97 67.842-54.689 94.586a12.016 12.016 0 0 1-14.832 2.254l-42.584-24.595a191.577 191.577 0 0 1-60.759 35.13v49.182a12.01 12.01 0 0 1-9.377 11.718c-34.956 7.85-72.499 8.256-109.219.007-5.49-1.233-9.403-6.096-9.403-11.723v-49.184a191.555 191.555 0 0 1-60.759-35.13l-42.584 24.595a12.016 12.016 0 0 1-14.832-2.254c-24.718-26.744-43.619-58.944-54.689-94.586-1.667-5.366.592-11.175 5.459-13.985L67.212 291.1a193.48 193.48 0 0 1 0-70.199l-42.616-24.599c-4.867-2.809-7.126-8.618-5.459-13.985 11.07-35.642 29.97-67.842 54.689-94.586a12.016 12.016 0 0 1 14.832-2.254l42.584 24.595a191.577 191.577 0 0 1 60.759-35.13V25.759a12.01 12.01 0 0 1 9.377-11.718c34.956-7.85 72.499-8.256 109.219-.007 5.49 1.233 9.403 6.096 9.403 11.723v49.184a191.555 191.555 0 0 1 60.759 35.13l42.584-24.595a12.016 12.016 0 0 1 14.832 2.254c24.718 26.744 43.619 58.944 54.689 94.586 1.667 5.366-.592 11.175-5.459 13.985L444.788 220.9a193.485 193.485 0 0 1 0 70.2zM336 256c0-44.112-35.888-80-80-80s-80 35.888-80 80 35.888 80 80 80 80-35.888 80-80z"], - "exclamation": [192, 512, [], "f12a", "M176 432c0 44.112-35.888 80-80 80s-80-35.888-80-80 35.888-80 80-80 80 35.888 80 80zM25.26 25.199l13.6 272C39.499 309.972 50.041 320 62.83 320h66.34c12.789 0 23.331-10.028 23.97-22.801l13.6-272C167.425 11.49 156.496 0 142.77 0H49.23C35.504 0 24.575 11.49 25.26 25.199z"], - "exclamation-circle": [512, 512, [], "f06a", "M504 256c0 136.997-111.043 248-248 248S8 392.997 8 256C8 119.083 119.043 8 256 8s248 111.083 248 248zm-248 50c-25.405 0-46 20.595-46 46s20.595 46 46 46 46-20.595 46-46-20.595-46-46-46zm-43.673-165.346l7.418 136c.347 6.364 5.609 11.346 11.982 11.346h48.546c6.373 0 11.635-4.982 11.982-11.346l7.418-136c.375-6.874-5.098-12.654-11.982-12.654h-63.383c-6.884 0-12.356 5.78-11.981 12.654z"], - "exclamation-triangle": [576, 512, [], "f071", "M569.517 440.013C587.975 472.007 564.806 512 527.94 512H48.054c-36.937 0-59.999-40.055-41.577-71.987L246.423 23.985c18.467-32.009 64.72-31.951 83.154 0l239.94 416.028zM288 354c-25.405 0-46 20.595-46 46s20.595 46 46 46 46-20.595 46-46-20.595-46-46-46zm-43.673-165.346l7.418 136c.347 6.364 5.609 11.346 11.982 11.346h48.546c6.373 0 11.635-4.982 11.982-11.346l7.418-136c.375-6.874-5.098-12.654-11.982-12.654h-63.383c-6.884 0-12.356 5.78-11.981 12.654z"], - "minus": [448, 512, [], "f068", "M424 318.2c13.3 0 24-10.7 24-24v-76.4c0-13.3-10.7-24-24-24H24c-13.3 0-24 10.7-24 24v76.4c0 13.3 10.7 24 24 24h400z"], - "minus-circle": [512, 512, [], "f056", "M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zM124 296c-6.6 0-12-5.4-12-12v-56c0-6.6 5.4-12 12-12h264c6.6 0 12 5.4 12 12v56c0 6.6-5.4 12-12 12H124z"], - "minus-square": [448, 512, [], "f146", "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM92 296c-6.6 0-12-5.4-12-12v-56c0-6.6 5.4-12 12-12h264c6.6 0 12 5.4 12 12v56c0 6.6-5.4 12-12 12H92z"], - "plus": [448, 512, [], "f067", "M448 294.2v-76.4c0-13.3-10.7-24-24-24H286.2V56c0-13.3-10.7-24-24-24h-76.4c-13.3 0-24 10.7-24 24v137.8H24c-13.3 0-24 10.7-24 24v76.4c0 13.3 10.7 24 24 24h137.8V456c0 13.3 10.7 24 24 24h76.4c13.3 0 24-10.7 24-24V318.2H424c13.3 0 24-10.7 24-24z"], - "plus-circle": [512, 512, [], "f055", "M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm144 276c0 6.6-5.4 12-12 12h-92v92c0 6.6-5.4 12-12 12h-56c-6.6 0-12-5.4-12-12v-92h-92c-6.6 0-12-5.4-12-12v-56c0-6.6 5.4-12 12-12h92v-92c0-6.6 5.4-12 12-12h56c6.6 0 12 5.4 12 12v92h92c6.6 0 12 5.4 12 12v56z"], - "plus-square": [448, 512, [], "f0fe", "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-32 252c0 6.6-5.4 12-12 12h-92v92c0 6.6-5.4 12-12 12h-56c-6.6 0-12-5.4-12-12v-92H92c-6.6 0-12-5.4-12-12v-56c0-6.6 5.4-12 12-12h92v-92c0-6.6 5.4-12 12-12h56c6.6 0 12 5.4 12 12v92h92c6.6 0 12 5.4 12 12v56z"], - "question": [384, 512, [], "f128", "M202.021 0C122.202 0 70.503 32.703 29.914 91.026c-7.363 10.58-5.093 25.086 5.178 32.874l43.138 32.709c10.373 7.865 25.132 6.026 33.253-4.148 25.049-31.381 43.63-49.449 82.757-49.449 30.764 0 68.816 19.799 68.816 49.631 0 22.552-18.617 34.134-48.993 51.164-35.423 19.86-82.299 44.576-82.299 106.405V320c0 13.255 10.745 24 24 24h72.471c13.255 0 24-10.745 24-24v-5.773c0-42.86 125.268-44.645 125.268-160.627C377.504 66.256 286.902 0 202.021 0zM192 373.459c-38.196 0-69.271 31.075-69.271 69.271 0 38.195 31.075 69.27 69.271 69.27s69.271-31.075 69.271-69.271-31.075-69.27-69.271-69.27z"], - "save": [448, 512, [], "f0c7", "M433.941 129.941l-83.882-83.882A48 48 0 0 0 316.118 32H48C21.49 32 0 53.49 0 80v352c0 26.51 21.49 48 48 48h352c26.51 0 48-21.49 48-48V163.882a48 48 0 0 0-14.059-33.941zM224 416c-35.346 0-64-28.654-64-64 0-35.346 28.654-64 64-64s64 28.654 64 64c0 35.346-28.654 64-64 64zm96-304.52V212c0 6.627-5.373 12-12 12H76c-6.627 0-12-5.373-12-12V108c0-6.627 5.373-12 12-12h228.52c3.183 0 6.235 1.264 8.485 3.515l3.48 3.48A11.996 11.996 0 0 1 320 111.48z"], - "search": [512, 512, [], "f002", "M505 442.7L405.3 343c-4.5-4.5-10.6-7-17-7H372c27.6-35.3 44-79.7 44-128C416 93.1 322.9 0 208 0S0 93.1 0 208s93.1 208 208 208c48.3 0 92.7-16.4 128-44v16.3c0 6.4 2.5 12.5 7 17l99.7 99.7c9.4 9.4 24.6 9.4 33.9 0l28.3-28.3c9.4-9.4 9.4-24.6.1-34zM208 336c-70.7 0-128-57.2-128-128 0-70.7 57.2-128 128-128 70.7 0 128 57.2 128 128 0 70.7-57.2 128-128 128z"], - "share": [512, 512, [], "f064", "M503.691 189.836L327.687 37.851C312.281 24.546 288 35.347 288 56.015v80.053C127.371 137.907 0 170.1 0 322.326c0 61.441 39.581 122.309 83.333 154.132 13.653 9.931 33.111-2.533 28.077-18.631C66.066 312.814 132.917 274.316 288 272.085V360c0 20.7 24.3 31.453 39.687 18.164l176.004-152c11.071-9.562 11.086-26.753 0-36.328z"], - "spinner": [512, 512, [], "f110", "M304 48c0 26.51-21.49 48-48 48s-48-21.49-48-48 21.49-48 48-48 48 21.49 48 48zm-48 368c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48-21.49-48-48-48zm208-208c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48-21.49-48-48-48zM96 256c0-26.51-21.49-48-48-48S0 229.49 0 256s21.49 48 48 48 48-21.49 48-48zm12.922 99.078c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48c0-26.509-21.491-48-48-48zm294.156 0c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48c0-26.509-21.49-48-48-48zM108.922 60.922c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48-21.491-48-48-48z"], - "square": [448, 512, [], "f0c8", "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48z"], - "square-full": [512, 512, [], "f45c", "M512 512H0V0h512v512z"], - "times": [384, 512, [], "f00d", "M323.1 441l53.9-53.9c9.4-9.4 9.4-24.5 0-33.9L279.8 256l97.2-97.2c9.4-9.4 9.4-24.5 0-33.9L323.1 71c-9.4-9.4-24.5-9.4-33.9 0L192 168.2 94.8 71c-9.4-9.4-24.5-9.4-33.9 0L7 124.9c-9.4 9.4-9.4 24.5 0 33.9l97.2 97.2L7 353.2c-9.4 9.4-9.4 24.5 0 33.9L60.9 441c9.4 9.4 24.5 9.4 33.9 0l97.2-97.2 97.2 97.2c9.3 9.3 24.5 9.3 33.9 0z"], - "times-circle": [512, 512, [], "f057", "M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm121.6 313.1c4.7 4.7 4.7 12.3 0 17L338 377.6c-4.7 4.7-12.3 4.7-17 0L256 312l-65.1 65.6c-4.7 4.7-12.3 4.7-17 0L134.4 338c-4.7-4.7-4.7-12.3 0-17l65.6-65-65.6-65.1c-4.7-4.7-4.7-12.3 0-17l39.6-39.6c4.7-4.7 12.3-4.7 17 0l65 65.7 65.1-65.6c4.7-4.7 12.3-4.7 17 0l39.6 39.6c4.7 4.7 4.7 12.3 0 17L312 256l65.6 65.1z"], - "wrench": [512, 512, [], "f0ad", "M481.156 200c9.3 0 15.12 10.155 10.325 18.124C466.295 259.992 420.419 288 368 288c-79.222 0-143.501-63.974-143.997-143.079C223.505 65.469 288.548-.001 368.002 0c52.362.001 98.196 27.949 123.4 69.743C496.24 77.766 490.523 88 481.154 88H376l-40 56 40 56h105.156zm-171.649 93.003L109.255 493.255c-24.994 24.993-65.515 24.994-90.51 0-24.993-24.994-24.993-65.516 0-90.51L218.991 202.5c16.16 41.197 49.303 74.335 90.516 90.503zM104 432c0-13.255-10.745-24-24-24s-24 10.745-24 24 10.745 24 24 24 24-10.745 24-24z"], - }; - - /** - * Configure item list for track "gear" menu. - * @param trackRenderer - */ - const MenuUtils = { - - trackMenuItemList: trackPair => { - - const menuItems = []; - - menuItems.push(trackRenameMenuItem(trackPair)); - menuItems.push("
"); - - menuItems.push(colorPickerMenuItem({ trackPair, label: "Set color", option: "color" })); - menuItems.push(unsetColorMenuItem({ trackPair, label: "Unset color" })); - - if (trackPair.track.removable !== false) { - menuItems.push('
'); - menuItems.push(trackRemovalMenuItem(trackPair)); - } - - return menuItems - }, - - numericDataMenuItems: trackPair => { - const menuItems = []; - - // Data range - const element = document.createElement('div'); - element.textContent = 'Set data range'; - - const click = () => { - const { min, max } = trackPair.track.dataRange; - trackPair.dataRangeDialog.show({ min: min || 0, max }); - }; - - menuItems.push({ element, click }); - - if (trackPair.track.logScale !== undefined) { - menuItems.push({ - element: createCheckbox("Log scale", trackPair.track.logScale), - click: () => { - trackPair.track.logScale = !trackPair.track.logScale; - trackPair.repaintViews(); - } - }); - } - - menuItems.push({ - element: createCheckbox("Autoscale", trackPair.track.autoscale), - click: () => { - trackPair.track.autoscale = !trackPair.track.autoscale; - trackPair.repaintViews(); - } - }); - - return menuItems; - }, - - nucleotideColorChartMenuItems: trackPair => { - const menuItems = []; - menuItems.push(document.createElement('hr')); - - const element = document.createElement('div'); - element.className = 'jb-igv-menu-popup-chart'; - element.innerHTML = ` -
A
-
C
-
T
-
G
- `; - - const click = e => { - e.preventDefault(); - e.stopPropagation(); - }; - - menuItems.push({ element, click }); - - return menuItems; - } - - }; - - function trackRemovalMenuItem(trackPair) { - const element = document.createElement('div'); - element.textContent = 'Remove track'; - - const click = () => trackPair.browser.layoutController.removeTrackXYPair(trackPair); - - return { element, click }; - } - - function colorPickerMenuItem({ trackPair, label, option }) { - const element = document.createElement('div'); - element.textContent = label; - - const click = () => trackPair.colorPicker.show(); - - return { element, click }; - } - - function unsetColorMenuItem({ trackPair, label }) { - const element = document.createElement('div'); - element.textContent = label; - - const click = () => { - trackPair.track.color = undefined; - trackPair.repaintViews(); - }; - - return { element, click }; - } - - function trackRenameMenuItem(trackPair) { - const element = document.createElement('div'); - element.textContent = 'Set track name'; - - const click = e => { - const callback = value => { - let name; - if (value === '' || value === undefined) { - name = ''; - } else { - name = value.trim(); - } - trackPair.track.name = name; - }; - - const value = trackPair.track.name || ''; - trackPair.browser.inputDialog.present({ label: 'Track Name', value, callback }, e); - }; - - return { element, click }; - } - - /* - * The MIT License (MIT) - * - * Copyright (c) 2014 Broad Institute - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - class TrackGearPopup { - - constructor(parentElement) { - // Popover container - this.popoverElement = document.createElement('div'); - this.popoverElement.className = 'jb-igv-menu-popup'; - parentElement.appendChild(this.popoverElement); - - // Popover header - const popoverHeaderElement = document.createElement('div'); - popoverHeaderElement.className = 'jb-igv-menu-popup-header'; - this.popoverElement.appendChild(popoverHeaderElement); - - // Attach close handler - uiUtils.attachDialogCloseHandlerWithParent(popoverHeaderElement, () => { - this.popoverElement.style.display = 'none'; - }); - - // Popover content - this.popoverContentElement = document.createElement('div'); - this.popoverElement.appendChild(this.popoverContentElement); - - // Make draggable - makeDraggable(this.popoverElement, popoverHeaderElement); - - // Prevent click propagation - popoverHeaderElement.addEventListener('click', (e) => { - e.stopPropagation(); - e.preventDefault(); - }); - } - - presentMenuList(dx, dy, list) { - TrackGearPopup.hideAllMenuPopups(); - - if (list.length > 0) { - // Clear popover content - this.popoverContentElement.innerHTML = ''; - - const updatedList = trackMenuItemListHelper(list, this.popoverElement); - - for (const item of updatedList) { - if (item.init) { - item.init(); - } - - - // Remove the border-top class from the first item - if (updatedList.indexOf(item) === 0) { - item.element.classList.remove('igv-track-menu-border-top'); - } - - // Add 'jb-igv-menu-popup-shim' if applicable - if ( - !item.element.classList.contains('igv-track-menu-border-top') && - !item.element.classList.contains('jb-igv-menu-popup-check-container') && - item.element.tagName === 'DIV' - ) { - item.element.classList.add('jb-igv-menu-popup-shim'); - } - - // Append element to the popover content - this.popoverContentElement.appendChild(item.element); - } - - // Position and display the popover - this.popoverElement.style.left = `${dx}px`; - this.popoverElement.style.top = `${dy}px`; - this.popoverElement.style.display = 'block'; - } - } - - dispose() { - this.popoverElement.innerHTML = ''; - this.popoverContentElement.innerHTML = ''; - - for (let key of Object.keys(this)) { - this[key] = undefined; - } - } - - static hideAllMenuPopups() { - const popups = document.querySelectorAll('.jb-igv-menu-popup'); - for (let popup of popups) { - popup.style.display = 'none'; - } - } - - } - - function trackMenuItemListHelper(itemList, popoverElement) { - - let results = []; - - if (itemList.length > 0) { - - results = itemList.map((item, i) => { - let element; - - if (item.name) { - element = document.createElement('div'); - element.textContent = item.name; - } else if (item.element) { - element = item.element instanceof HTMLElement ? item.element.cloneNode(true) : item.element; - } else if (typeof item.label === 'string') { - element = document.createElement('div'); - element.innerHTML = item.label; - } else if (typeof item === 'string') { - if (item.startsWith("<")) { - const tempDiv = document.createElement('div'); - tempDiv.innerHTML = item; - element = tempDiv.firstElementChild; - } else { - element = document.createElement('div'); - element.textContent = item; - } - } - - // Add top border class to the first item - if (i === 0 && element) { - element.classList.add('igv-track-menu-border-top'); - } - - // Add click, touchend, and mouseup event listeners if item has a click handler - if (item.click && element) { - const eventHandler = e => { - e.preventDefault(); - e.stopPropagation(); - item.click(e); - popoverElement.style.display = 'none'; - }; - - element.addEventListener('click', eventHandler); - element.addEventListener('touchend', eventHandler); - element.addEventListener('mouseup', e => { - e.preventDefault(); - e.stopPropagation(); - }); - } - - return { element, init: item.init || undefined }; - }); - } - - return results; - } - - class Tile { - - constructor(chr, startBP, endBP, bpp, buffer, features) { - this.chr = chr; - this.startBP = startBP; - this.endBP = endBP; - this.bpp = bpp; - this.buffer = buffer; - this.features = features; - } - - containsRange(chr, startBP, endBP, bpp) { - return chr === this.chr && this.bpp === bpp && this.startBP <= startBP && this.endBP >= endBP; - } - } - - /** - * Created by dat on 4/5/17. - */ - - class TrackPair { - - constructor(browser, track) { - this.browser = browser; - this.track = track; - this.x = undefined; - this.y = undefined; - } - - init() { - this.colorPicker = new ColorPicker({ - parent: this.x.viewportElement, - width: 456, - height: undefined, - colorHandler: color => this.setColor(color) - }); - this.colorPicker.hide(); - - this.dataRangeDialog = new DataRangeDialog(this.x.viewportElement, (min, max) => this.setDataRange(min, max)); - - this.appendRightHandGutter(this.x.viewportElement); - - for (const el of this.x.trackReorderHandleElement.querySelectorAll('.fa')) { - el.addEventListener('click', e => { - e.preventDefault(); - e.stopPropagation(); - - const direction = e.target.classList.contains('fa-arrow-up') ? -1 : 1; - - let order = parseInt(this.x.viewportElement.style.order); - - if (order === 0 && direction === -1) { - return; - } else if (this.browser.trackPairs.length - 1 === order && direction === 1) { - return; - } - - const newOrder = direction === -1 ? order - 1 : order + 1; - - const targetTrackPair = this.browser.trackPairs.find( - trackPair => newOrder === parseInt(trackPair.x.viewportElement.style.order) - ); - - if (targetTrackPair) { - targetTrackPair.x.viewportElement.style.order = `${order}`; - targetTrackPair.y.viewportElement.style.order = `${order}`; - } - - this.x.viewportElement.style.order = `${newOrder}`; - this.y.viewportElement.style.order = `${newOrder}`; - - const a = this.browser.trackPairs; - [a[order], a[newOrder]] = [a[newOrder], a[order]]; - - setTrackReorderArrowColors(this.browser.trackPairs); - }); - } - - // igvjs compatibility - this.track.trackView = this; - this.track.trackView.trackDiv = this.x.viewportElement; - } - - presentColorPicker() { - const bbox = this.x.trackDiv.getBoundingClientRect(); - this.colorPicker.origin = { x: bbox.x, y: 0 }; - - // Set the position of the colorPicker container - this.colorPicker.containerElement.style.left = `${this.colorPicker.origin.x}px`; - this.colorPicker.containerElement.style.top = `${this.colorPicker.origin.y}px`; - - // Show the colorPicker container - this.colorPicker.containerElement.style.display = 'block'; - } - - setTrackLabelName(name) { - this.x.labelElement.textContent = name; - this.x.labelElement.title = name; - } - - setColor(color) { - this.y.tile = undefined; - this.x.tile = undefined; - this.track.color = color; - this.repaintViews(); - } - - dataRange() { - return this.track.dataRange ? this.track.dataRange : undefined; - } - - setDataRange(min, max) { - if (min !== undefined) { - this.track.dataRange.min = min; - this.track.config.min = min; - } - if (max !== undefined) { - this.track.dataRange.max = max; - this.track.config.max = max; - } - this.track.autoscale = false; - this.track.config.autoScale = false; - this.y.tile = undefined; - this.x.tile = undefined; - this.repaintViews(); - } - - appendRightHandGutter(parentElement) { - const div = document.createElement('div'); - div.className = 'hic-igv-right-hand-gutter'; - parentElement.appendChild(div); - this.createTrackGearPopup(div); - } - - createTrackGearPopup(parentElement) { - const container = document.createElement('div'); - container.className = 'igv-trackgear-container'; - parentElement.appendChild(container); - - container.appendChild(createIcon('cog')); - - this.trackGearPopup = new TrackGearPopup(parentElement); - this.trackGearPopup.popoverElement.style.display = 'none'; - - container.addEventListener('click', e => { - e.preventDefault(); - e.stopPropagation(); - - const { trackMenuItemList, numericDataMenuItems, nucleotideColorChartMenuItems } = MenuUtils; - - const list = [...trackMenuItemList(this)]; - - if (this.track.type === 'wig') { - list.push(...numericDataMenuItems(this)); - } - - if (this.track.type === 'sequence') { - list.push(...nucleotideColorChartMenuItems(this)); - } - - const width = this.trackGearPopup.popoverElement.getBoundingClientRect().width; - - this.trackGearPopup.presentMenuList(-width, 0, list); - }); - } - - async updateViews() { - - if (this.updating) { - this.pending = true; - } else { - try { - this.updating = true; - const genomicStateX = this.browser.genomicState(this.x.axis); - let imageTileX = await this.getTileX(genomicStateX); - if (imageTileX) { - this.x.drawTile(imageTileX, genomicStateX); - } - - const genomicStateY = this.browser.genomicState(this.y.axis); - let imageTileY = await this.getTileY(genomicStateY); - if (imageTileY) { - this.y.drawTile(imageTileY, genomicStateY); - } - } finally { - this.updating = false; - if (this.pending) { - this.pending = false; - this.updateViews(); - } - } - } - } - - /** - * Repaint current tiles with cached features (due to color, scale, or other visual attribute change) - * @returns {Promise} - */ - async repaintViews() { - - const genomicStateX = this.browser.genomicState(this.x.axis); - if (this.tileX) { - this.tileX = await this.createImageTile({ axis: 'x', ...genomicStateX }, this.tileX.features); - this.x.drawTile(this.tileX, genomicStateX); - } - - const genomicStateY = this.browser.genomicState(this.y.axis); - if (this.tileY) { - this.tileY = await this.createImageTile({ axis: 'y', ...genomicStateY }, this.tileY.features); - this.y.drawTile(this.tileY, genomicStateY); - } - } - - async getTileX(genomicState) { - - const { chromosome, bpp } = genomicState; - - if (!(this.tileX && this.tileX.containsRange(chromosome.name, genomicState.startBP, genomicState.endBP, bpp))) { - this.tileX = await this.createImageTile({ axis: 'x', ...genomicState }); - } - - return this.tileX - } - - async getTileY(genomicState) { - - const { chromosome, bpp } = genomicState; - - if (!(this.tileY && this.tileY.containsRange(chromosome.name, genomicState.startBP, genomicState.endBP, bpp))) { - this.tileY = await this.createImageTile({ axis: 'y', ...genomicState }); - } - - return this.tileY - } - - async createImageTile(genomicState, tileFeatures) { - if ( - this.track.visibilityWindow > 0 && - genomicState.bpp * Math.max(this.x.canvasElement.width, this.x.canvasElement.height) > this.track.visibilityWindow - ) ; else { - // Expand the requested range so we can pan a bit without reloading - const pixelWidth = 3 * this.x.canvasElement.width; - const lengthBP = Math.round(genomicState.bpp * pixelWidth); - const bpStart = Math.max(0, Math.round(genomicState.startBP - lengthBP / 3)); - const bpEnd = bpStart + lengthBP; - - const features = tileFeatures || await this.track.getFeatures( - genomicState.chromosome.name, - bpStart, - bpEnd, - genomicState.bpp - ); - - const canvas = document.createElement('canvas'); - canvas.width = pixelWidth; - canvas.height = this.x.canvasElement.height; - - const context = canvas.getContext('2d'); - - if (features) { - const drawConfiguration = { - axis: genomicState.axis, - features, - context, - pixelWidth, - bpStart, - bpEnd, - bpPerPixel: genomicState.bpp, - genomicState, - pixelHeight: Math.min(canvas.width, canvas.height), - viewportContainerX: (genomicState.startBP - bpStart) / genomicState.bpp, - viewportContainerWidth: pixelWidth, - viewportWidth: pixelWidth, - referenceFrame: {}, - }; - - if (this.track.autoscale || !this.track.dataRange) { - if (typeof this.track.doAutoscale === 'function') { - this.track.doAutoscale(features); - } else { - this.track.dataRange = doAutoscale(features); - } - } - - this.track.draw(drawConfiguration); - } else { - const wye = canvas.height - canvas.height / 4; - index$1.IGVGraphics.fillRect(context, 0, wye, canvas.width, 2, { fillStyle: 'rgba(0,0,0,0.1)' }); - } - - this.tile = new Tile(genomicState.chromosome.name, bpStart, bpEnd, genomicState.bpp, canvas, features); - return this.tile; - } - } - - dispose() { - this.x.dispose(); - this.y.dispose(); - } - } - - function doAutoscale (features = []) { - let min = Number.MAX_VALUE; - let max = -Number.MAX_VALUE; - - if (features.length > 0) { - for (const { value } of features) { - if (!Number.isNaN(value)) { - min = Math.min(min, value); - max = Math.max(max, value); - } - } - - // Ensure we have a zero baseline - if (max > 0) min = Math.min(0, min); - if (max < 0) max = 0; - } else { - // No features -- default - min = 0; - max = 100; - } - - return { min, max }; - } - - function setTrackReorderArrowColors(trackPairs) { - - for (const trackPair of trackPairs) { - const el = trackPair.x.viewportElement; - const order = parseInt(el.style.order); - - const arrowUp = el.querySelector('.fa-arrow-up'); - const arrowDown = el.querySelector('.fa-arrow-down'); - - if (order === 0) { - arrowUp.style.color = 'rgba(0, 0, 0, 0)'; - arrowDown.style.color = '#7F7F7F'; - } else if (order === trackPairs.length - 1) { - arrowUp.style.color = '#7F7F7F'; - arrowDown.style.color = 'rgba(0, 0, 0, 0)'; - } else { - arrowUp.style.color = '#7F7F7F'; - arrowDown.style.color = '#7F7F7F'; - } - } - - } - - class TrackRenderer { - - constructor(browser, track, axis) { - this.browser = browser; - this.track = track; - this.axis = axis; - this.id = `trackRender_${domUtils.guid()}`; - } - - init(containerElement, size, order) { - this.viewportElement = document.createElement('div'); - this.viewportElement.className = (this.axis === 'x') ? 'x-track-canvas-container' : 'y-track-canvas-container'; - containerElement.appendChild(this.viewportElement); - - if (this.axis === 'x') { - this.viewportElement.style.height = `${size}px`; - } else { - this.viewportElement.style.width = `${size}px`; - } - this.viewportElement.style.order = `${order}`; - - this.canvasElement = document.createElement('canvas'); - this.viewportElement.appendChild(this.canvasElement); - this.ctx = this.canvasElement.getContext("2d"); - - if (this.axis === 'x') { - this.trackReorderHandleElement = document.createElement('div'); - this.trackReorderHandleElement.className = 'x-track-reorder-handle'; - this.viewportElement.appendChild(this.trackReorderHandleElement); - - this.trackReorderHandleElement.innerHTML = ''; - - this.labelElement = document.createElement('div'); - this.labelElement.className = 'x-track-label'; - this.viewportElement.appendChild(this.labelElement); - - const labelText = this.track.name || ''; - this.labelElement.textContent = labelText; - this.labelElement.title = labelText; - - this.labelElement.style.display = this.browser.showTrackLabelAndGutter ? 'block' : 'none'; - - this.viewportElement.addEventListener('click', (e) => { - e.preventDefault(); - e.stopPropagation(); - this.browser.toggleTrackLabelAndGutterState(); - const displayState = this.browser.showTrackLabelAndGutter ? 'block' : 'none'; - document.querySelectorAll('.x-track-label, .hic-igv-right-hand-gutter').forEach(el => { - el.style.display = displayState; - }); - }); - } - - this.spinnerElement = document.createElement('div'); - this.spinnerElement.className = (this.axis === 'x') ? 'x-track-spinner' : 'y-track-spinner'; - this.viewportElement.appendChild(this.spinnerElement); - this.stopSpinner(); - } - - dispose() { - this.tile = undefined; - this.viewportElement.remove(); - } - - syncCanvas() { - this.canvasElement.width = this.viewportElement.offsetWidth; - this.canvasElement.height = this.viewportElement.offsetHeight; - } - - drawTile(tile, genomicState) { - if (tile) { - - let w; - let h; - if (this.axis === 'x') { - w = this.canvasElement.width; - h = this.canvasElement.height; - } else { - h = this.canvasElement.width; - w = this.canvasElement.height; - this.ctx.setTransform(0, 1, 1, 0, 0, 0); - } - - this.ctx.clearRect(0, 0, w, h); - - this.offsetPixel = Math.round((tile.startBP - genomicState.startBP) / genomicState.bpp); - this.ctx.drawImage(tile.buffer, this.offsetPixel, 0); - - } - } - - startSpinner() { - this.browser.startSpinner(); - } - - stopSpinner() { - this.browser.stopSpinner(); - } - - isLoading() { - return this.loading !== undefined; - } - } - - /* - * The MIT License (MIT) - * - * Copyright (c) 2016-2017 The Regents of the University of California - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and - * associated documentation files (the "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the - * following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING - * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - */ - - - function HICEvent (type, data, propogate) { - return { - type: type, - data: data || {}, - propogate: propogate !== undefined ? propogate : true // Default to true - } - } - - /** - * Test if object is a File or File-like object. - * - * Copied from igv-utils.FileUtils version 1.3.8 - * - * @param object - */ - function isFile(object) { - if(!object) { - return false; - } - return typeof object !== 'function' && - (object instanceof File || - (object.name !== undefined && typeof object.slice === 'function' && typeof object.arrayBuffer === 'function')) - } - - function createDOMFromHTMLString(string) { - const template = document.createElement('template'); - template.innerHTML = string.trim(); // Removes whitespace to avoid unintended text nodes - return template.content.firstElementChild; - } - - function getOffset(element) { - const { top, left } = element.getBoundingClientRect(); - return { top: top + window.scrollY, left: left + window.scrollX }; - } - - function parseRgbString(rgbString) { - - // Use a regular expression to extract the numbers from the string - const match = rgbString.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/); - - // Check if the match is successful - if (!match) { - throw new Error("Invalid RGB string format"); - } - - // Convert the matched strings into integers and return them as an array - return match.slice(1, 4).map(Number); - } - - function prettyPrint(number) { - - if (typeof number !== "number") { - console.error(`${ number } must be a number`); - return - } - - const integerPart = Math.trunc(number); - return integerPart.toLocaleString() - } - - function extractName(config) { - if (config.name === undefined) { - const urlOrFile = config.url; - if (isFile(urlOrFile)) { - return urlOrFile.name - } else { - const str = urlOrFile.split('?').shift(); - const idx = urlOrFile.lastIndexOf("/"); - return idx > 0 ? str.substring(idx + 1) : str - } - } else { - return config.name - } - } - - function presentError(prefix, error) { - const httpMessages = - { - 401: "Access unauthorized", - 403: "Access forbidden", - 404: "Not found" - }; - - const msg = httpMessages[error.message] || error.message; - Alert$1.presentAlert(`${prefix}: ${msg}`); - } - - /** - * Created by dat on 4/4/17. - */ - - class LayoutController { - - constructor(browser, rootElement) { - this.browser = browser; - createNavBar(browser, rootElement); - this.createAllContainers(browser, rootElement); - } - - createAllContainers(browser, root) { - const htmlXTrackContainer = createDOMFromHTMLString(` -
-
-
- -
-
`); - - root.appendChild(htmlXTrackContainer); - - this.xTrackContainer = root.querySelector(`div[id$='x-track-container']`); - this.trackShim = this.xTrackContainer.querySelector(`div[id$='track-shim']`); - this.xTracks = this.xTrackContainer.querySelector(`div[id$='x-tracks']`); - this.yTrackGuideElement = this.xTrackContainer.querySelector(`div[id$='y-track-guide']`); - - this.contentContainer = createDOMFromHTMLString(`
`); - root.appendChild(this.contentContainer); - - const htmlXAxisContainer = createDOMFromHTMLString(` -
-
- -
-
-
`); - - this.contentContainer.appendChild(htmlXAxisContainer); - const xAxisContainer = this.contentContainer.querySelector(`div[id$='x-axis-container']`); - - this.xAxisRuler = new Ruler(browser, xAxisContainer, 'x'); - - const htmlYTracksYAxisViewportYScrollbar = createDOMFromHTMLString(` -
-
- -
-
- -
-
-
`); - - this.contentContainer.appendChild(htmlYTracksYAxisViewportYScrollbar); - const yTracksYAxisViewportYScrollbar = this.contentContainer.querySelector(`div[id$='-y-tracks-y-axis-viewport-y-scrollbar']`); - - this.yTracks = yTracksYAxisViewportYScrollbar.querySelector(`div[id$='-y-tracks']`); - this.xTrackGuideElement = this.yTracks.querySelector(`div[id$='-x-track-guide']`); - - this.yAxisRuler = new Ruler(browser, yTracksYAxisViewportYScrollbar, 'y'); - - this.xAxisRuler.otherRulerCanvas = this.yAxisRuler.canvasElement; - this.xAxisRuler.otherRuler = this.yAxisRuler; - - this.yAxisRuler.otherRulerCanvas = this.xAxisRuler.canvasElement; - this.yAxisRuler.otherRuler = this.xAxisRuler; - - const htmlViewport = createDOMFromHTMLString(` -
- - - - - -
`); - - yTracksYAxisViewportYScrollbar.appendChild(htmlViewport); - - const htmlYAxisScrollbarContainer = createDOMFromHTMLString(` -
-
-
-
-
`); - - yTracksYAxisViewportYScrollbar.appendChild(htmlYAxisScrollbarContainer); - - const htmlXAxisScrollbarContainer = createDOMFromHTMLString(` -
-
-
-
-
-
-
`); - - this.contentContainer.appendChild(htmlXAxisScrollbarContainer); - } - - getContactMatrixViewport() { - const parent = this.contentContainer.querySelector("div[id$='-y-tracks-y-axis-viewport-y-scrollbar']"); - return parent ? parent.querySelector("div[id$='-viewport']") : null; - } - - getYAxisScrollbarContainer() { - const parent = this.contentContainer.querySelector("div[id$='-y-tracks-y-axis-viewport-y-scrollbar']"); - return parent ? parent.querySelector("div[id$='-y-axis-scrollbar-container']") : null; - } - - getXAxisScrollbarContainer() { - return this.contentContainer.querySelector("div[id$='-x-axis-scrollbar-container']"); - } - - updateLayoutWithTracks(tracks) { - - const { trackHeight } = getLayoutDimensions(); - - this.resizeLayoutWithTrackXYPairCount(tracks.length + this.browser.trackPairs.length); - - for (const track of tracks) { - - const trackPair = new TrackPair(this.browser, track); - this.browser.trackPairs.unshift(trackPair); - - trackPair.x = new TrackRenderer(this.browser, track, 'x'); - trackPair.x.init(this.xTracks, trackHeight, this.browser.trackPairs.indexOf(trackPair)); - - trackPair.y = new TrackRenderer(this.browser, track, 'y'); - trackPair.y.init(this.yTracks, trackHeight, this.browser.trackPairs.indexOf(trackPair)); - - trackPair.init(); - - EventBus.globalBus.post(HICEvent("TrackXYPairLoad", trackPair)); - } - - for (const trackPair of this.browser.trackPairs) { - const order = `${ this.browser.trackPairs.indexOf(trackPair) }`; - trackPair.x.viewportElement.style.order = order; - trackPair.y.viewportElement.style.order = order; - } - - setTrackReorderArrowColors(this.browser.trackPairs); - - } - - removeAllTrackXYPairs() { - - if (this.browser.trackPairs.length === 0 ) { - return; - } - - for(let trackPair of this.browser.trackPairs) { - // discard DOM element's - trackPair.dispose(); - } - this.browser.trackPairs = []; - this.browser.updateLayout(); - this.resizeLayoutWithTrackXYPairCount(0); - - } - - removeTrackXYPair(trackXYPair) { - - if (this.browser.trackPairs.length > 0) { - - // remove DOM element - trackXYPair.x.viewportElement.remove(); - trackXYPair.y.viewportElement.remove(); - - // remove from trackPairs list - const index = this.browser.trackPairs.indexOf(trackXYPair); - this.browser.trackPairs.splice(index, 1); - - this.resizeLayoutWithTrackXYPairCount(this.browser.trackPairs.length); - - this.browser.updateLayout(); - - EventBus.globalBus.post(HICEvent("TrackXYPairRemoval", trackXYPair)); - } - } - - resizeLayoutWithTrackXYPairCount(trackXYPairCount) { - const { trackHeight, trackMargin, axisHeight, scrollbarHeight } = getLayoutDimensions(); - const trackAggregateHeight = (trackXYPairCount === 0) ? 0 : trackXYPairCount * (trackHeight + trackMargin); - - let tokens = [getNavbarHeight(), trackAggregateHeight].map(number => `${number}px`); - const heightCalc = `calc(100% - (${tokens.join(' + ')}))`; - - tokens = [trackAggregateHeight, axisHeight, scrollbarHeight].map(number => `${number}px`); - const widthCalc = `calc(100% - (${tokens.join(' + ')}))`; - - // x-track container - this.xTrackContainer.style.height = `${trackAggregateHeight}px`; - - // track labels - this.trackShim.style.width = `${trackAggregateHeight}px`; - - // x-tracks - this.xTracks.style.width = widthCalc; - - // content container - this.contentContainer.style.height = heightCalc; - - // x-axis - repaint canvas - this.xAxisRuler.updateWidthWithCalculation(widthCalc); - - // y-tracks - this.yTracks.style.width = `${trackAggregateHeight}px`; - - // y-axis - repaint canvas - this.yAxisRuler.updateHeight(this.yAxisRuler.axisElement.offsetHeight); - - // viewport - this.browser.contactMatrixView.viewportElement.style.width = widthCalc; - - // x-scrollbar - this.browser.contactMatrixView.scrollbarWidget.xAxisScrollbarContainerElement.style.width = widthCalc; - } - - } - - function getNavbarContainer(browser) { - return browser.rootElement.querySelector('.hic-navbar-container'); - } - - function getNavbarHeight() { - const { navBarLabelHeight, navBarWidgetContainerHeight, navBarWidgetContainerMargin } = getLayoutDimensions(); - return 2 * (navBarLabelHeight + navBarWidgetContainerHeight + (2 * navBarWidgetContainerMargin)); - } - - function getCSSVariable(name) { - return parseInt(getComputedStyle(document.documentElement).getPropertyValue(name)); - } - - function setCSSVariable(name, value) { - document.documentElement.style.setProperty(name, `${value}px`); - } - - function getLayoutDimensions() { - return { - navBarLabelHeight: getCSSVariable('--nav-bar-label-height'), - navBarWidgetContainerHeight: getCSSVariable('--nav-bar-widget-container-height'), - navBarWidgetContainerMargin: getCSSVariable('--nav-bar-widget-container-margin'), - scrollbarHeight: getCSSVariable('--hic-scrollbar-height'), - axisHeight: getCSSVariable('--hic-axis-height'), - trackMargin: getCSSVariable('--track-margin'), - trackHeight: getCSSVariable('--track-height') - }; - } - - function setViewportSize(width, height) { - setCSSVariable('--hic-viewport-width', width); - setCSSVariable('--hic-viewport-height', height); - } - - function createNavBar(browser, root) { - - const hicNavbarContainer = document.createElement('div'); - hicNavbarContainer.className = 'hic-navbar-container'; - root.appendChild(hicNavbarContainer); - - hicNavbarContainer.addEventListener('click', e => { - e.stopPropagation(); - e.preventDefault(); - setCurrentBrowser(browser); - }); - - const htmlContactMapHicNavBarMapContainer = - `
-
-
- - -
-
`; - - hicNavbarContainer.appendChild(createDOMFromHTMLString(htmlContactMapHicNavBarMapContainer)); - - browser.contactMapLabel = hicNavbarContainer.querySelector(`div[id$='contact-map-hic-nav-bar-map-label']`); - browser.menuPresentDismiss = hicNavbarContainer.querySelector('.fa-bars'); - browser.menuPresentDismiss.addEventListener('click', e => browser.toggleMenu()); - - browser.browserPanelDeleteButton = hicNavbarContainer.querySelector('.fa-minus-circle'); - browser.browserPanelDeleteButton.addEventListener('click', e => deleteBrowser(browser)); - - // Delete button is only visible if there is more than one browser - browser.browserPanelDeleteButton.style.display = 'none'; - - const htmlControlMapHicNavBarMapContainer = - `
-
-
`; - - hicNavbarContainer.appendChild(createDOMFromHTMLString(htmlControlMapHicNavBarMapContainer)); - - browser.controlMapLabel = hicNavbarContainer.querySelector(`div[id$='control-map-hic-nav-bar-map-label']`); - - const htmlUpperHicNavBarWidgetContainer = `
`; - hicNavbarContainer.appendChild(createDOMFromHTMLString(htmlUpperHicNavBarWidgetContainer)); - - const htmlLowerHicNavBarWidgetContainer = `
`; - hicNavbarContainer.appendChild(createDOMFromHTMLString(htmlLowerHicNavBarWidgetContainer)); - } - - // from https://github.com/imaya/zlib.js - - var Zlib = { - Huffman: {}, - Util: {}, - CRC32: {} - }; - - - /** - * Compression Method - * @enum {number} - */ - Zlib.CompressionMethod = { - DEFLATE: 8, - RESERVED: 15 - }; - - - - - /** - * @param {Object=} opt_params options. - * @constructor - */ - Zlib.Zip = function(opt_params) { - opt_params = opt_params || {}; - /** @type {Array.<{ - * buffer: !(Array.|Uint8Array), - * option: Object, - * compressed: boolean, - * encrypted: boolean, - * size: number, - * crc32: number - * }>} */ - this.files = []; - /** @type {(Array.|Uint8Array)} */ - this.comment = opt_params['comment']; - /** @type {(Array.|Uint8Array)} */ - this.password; - }; - - - /** - * @enum {number} - */ - Zlib.Zip.CompressionMethod = { - STORE: 0, - DEFLATE: 8 - }; - - /** - * @enum {number} - */ - Zlib.Zip.OperatingSystem = { - MSDOS: 0, - UNIX: 3, - MACINTOSH: 7 - }; - - /** - * @enum {number} - */ - Zlib.Zip.Flags = { - ENCRYPT: 0x0001, - DESCRIPTOR: 0x0008, - UTF8: 0x0800 - }; - - /** - * @type {Array.} - * @const - */ - Zlib.Zip.FileHeaderSignature = [0x50, 0x4b, 0x01, 0x02]; - - /** - * @type {Array.} - * @const - */ - Zlib.Zip.LocalFileHeaderSignature = [0x50, 0x4b, 0x03, 0x04]; - - /** - * @type {Array.} - * @const - */ - Zlib.Zip.CentralDirectorySignature = [0x50, 0x4b, 0x05, 0x06]; - - /** - * @param {Array.|Uint8Array} input - * @param {Object=} opt_params options. - */ - Zlib.Zip.prototype.addFile = function(input, opt_params) { - opt_params = opt_params || {}; - /** @type {string} */ - opt_params['filename']; - /** @type {boolean} */ - var compressed; - /** @type {number} */ - var size = input.length; - /** @type {number} */ - var crc32 = 0; - - if (input instanceof Array) { - input = new Uint8Array(input); - } - - // default - if (typeof opt_params['compressionMethod'] !== 'number') { - opt_params['compressionMethod'] = Zlib.Zip.CompressionMethod.DEFLATE; - } - - // その場で圧縮する場合 - if (opt_params['compress']) { - switch (opt_params['compressionMethod']) { - case Zlib.Zip.CompressionMethod.STORE: - break; - case Zlib.Zip.CompressionMethod.DEFLATE: - crc32 = Zlib.CRC32.calc(input); - input = this.deflateWithOption(input, opt_params); - compressed = true; - break; - default: - throw new Error('unknown compression method:' + opt_params['compressionMethod']); - } - } - - this.files.push({ - buffer: input, - option: opt_params, - compressed: compressed, - encrypted: false, - size: size, - crc32: crc32 - }); - }; - - /** - * @param {(Array.|Uint8Array)} password - */ - Zlib.Zip.prototype.setPassword = function(password) { - this.password = password; - }; - - Zlib.Zip.prototype.compress = function() { - /** @type {Array.<{ - * buffer: !(Array.|Uint8Array), - * option: Object, - * compressed: boolean, - * encrypted: boolean, - * size: number, - * crc32: number - * }>} */ - var files = this.files; - /** @type {{ - * buffer: !(Array.|Uint8Array), - * option: Object, - * compressed: boolean, - * encrypted: boolean, - * size: number, - * crc32: number - * }} */ - var file; - /** @type {!(Array.|Uint8Array)} */ - var output; - /** @type {number} */ - var op1; - /** @type {number} */ - var op2; - /** @type {number} */ - var op3; - /** @type {number} */ - var localFileSize = 0; - /** @type {number} */ - var centralDirectorySize = 0; - /** @type {number} */ - var endOfCentralDirectorySize; - /** @type {number} */ - var offset; - /** @type {number} */ - var needVersion; - /** @type {number} */ - var flags; - /** @type {Zlib.Zip.CompressionMethod} */ - var compressionMethod; - /** @type {Date} */ - var date; - /** @type {number} */ - var crc32; - /** @type {number} */ - var size; - /** @type {number} */ - var plainSize; - /** @type {number} */ - var filenameLength; - /** @type {number} */ - var extraFieldLength; - /** @type {number} */ - var commentLength; - /** @type {(Array.|Uint8Array)} */ - var filename; - /** @type {(Array.|Uint8Array)} */ - var extraField; - /** @type {(Array.|Uint8Array)} */ - var comment; - /** @type {(Array.|Uint8Array)} */ - var buffer; - /** @type {*} */ - var tmp; - /** @type {Array.|Uint32Array|Object} */ - var key; - /** @type {number} */ - var i; - /** @type {number} */ - var il; - /** @type {number} */ - var j; - /** @type {number} */ - var jl; - - // ファイルの圧縮 - for (i = 0, il = files.length; i < il; ++i) { - file = files[i]; - filenameLength = - (file.option['filename']) ? file.option['filename'].length : 0; - extraFieldLength = - (file.option['extraField']) ? file.option['extraField'].length : 0; - commentLength = - (file.option['comment']) ? file.option['comment'].length : 0; - - // 圧縮されていなかったら圧縮 - if (!file.compressed) { - // 圧縮前に CRC32 の計算をしておく - file.crc32 = Zlib.CRC32.calc(file.buffer); - - switch (file.option['compressionMethod']) { - case Zlib.Zip.CompressionMethod.STORE: - break; - case Zlib.Zip.CompressionMethod.DEFLATE: - file.buffer = this.deflateWithOption(file.buffer, file.option); - file.compressed = true; - break; - default: - throw new Error('unknown compression method:' + file.option['compressionMethod']); - } - } - - // encryption - if (file.option['password'] !== void 0|| this.password !== void 0) { - // init encryption - key = this.createEncryptionKey(file.option['password'] || this.password); - - // add header - buffer = file.buffer; - { - tmp = new Uint8Array(buffer.length + 12); - tmp.set(buffer, 12); - buffer = tmp; - } - - for (j = 0; j < 12; ++j) { - buffer[j] = this.encode( - key, - i === 11 ? (file.crc32 & 0xff) : (Math.random() * 256 | 0) - ); - } - - // data encryption - for (jl = buffer.length; j < jl; ++j) { - buffer[j] = this.encode(key, buffer[j]); - } - file.buffer = buffer; - } - - // 必要バッファサイズの計算 - localFileSize += - // local file header - 30 + filenameLength + - // file data - file.buffer.length; - - centralDirectorySize += - // file header - 46 + filenameLength + commentLength; - } - - // end of central directory - endOfCentralDirectorySize = 22 + (this.comment ? this.comment.length : 0); - output = new (Uint8Array )( - localFileSize + centralDirectorySize + endOfCentralDirectorySize - ); - op1 = 0; - op2 = localFileSize; - op3 = op2 + centralDirectorySize; - - // ファイルの圧縮 - for (i = 0, il = files.length; i < il; ++i) { - file = files[i]; - filenameLength = - file.option['filename'] ? file.option['filename'].length : 0; - extraFieldLength = 0; // TODO - commentLength = - file.option['comment'] ? file.option['comment'].length : 0; - - //------------------------------------------------------------------------- - // local file header & file header - //------------------------------------------------------------------------- - - offset = op1; - - // signature - // local file header - output[op1++] = Zlib.Zip.LocalFileHeaderSignature[0]; - output[op1++] = Zlib.Zip.LocalFileHeaderSignature[1]; - output[op1++] = Zlib.Zip.LocalFileHeaderSignature[2]; - output[op1++] = Zlib.Zip.LocalFileHeaderSignature[3]; - // file header - output[op2++] = Zlib.Zip.FileHeaderSignature[0]; - output[op2++] = Zlib.Zip.FileHeaderSignature[1]; - output[op2++] = Zlib.Zip.FileHeaderSignature[2]; - output[op2++] = Zlib.Zip.FileHeaderSignature[3]; - - // compressor info - needVersion = 20; - output[op2++] = needVersion & 0xff; - output[op2++] = - /** @type {Zlib.Zip.OperatingSystem} */ - (file.option['os']) || - Zlib.Zip.OperatingSystem.MSDOS; - - // need version - output[op1++] = output[op2++] = needVersion & 0xff; - output[op1++] = output[op2++] = (needVersion >> 8) & 0xff; - - // general purpose bit flag - flags = 0; - if (file.option['password'] || this.password) { - flags |= Zlib.Zip.Flags.ENCRYPT; - } - output[op1++] = output[op2++] = flags & 0xff; - output[op1++] = output[op2++] = (flags >> 8) & 0xff; - - // compression method - compressionMethod = - /** @type {Zlib.Zip.CompressionMethod} */ - (file.option['compressionMethod']); - output[op1++] = output[op2++] = compressionMethod & 0xff; - output[op1++] = output[op2++] = (compressionMethod >> 8) & 0xff; - - // date - date = /** @type {(Date|undefined)} */(file.option['date']) || new Date(); - output[op1++] = output[op2++] = - ((date.getMinutes() & 0x7) << 5) | - (date.getSeconds() / 2 | 0); - output[op1++] = output[op2++] = - (date.getHours() << 3) | - (date.getMinutes() >> 3); - // - output[op1++] = output[op2++] = - ((date.getMonth() + 1 & 0x7) << 5) | - (date.getDate()); - output[op1++] = output[op2++] = - ((date.getFullYear() - 1980 & 0x7f) << 1) | - (date.getMonth() + 1 >> 3); - - // CRC-32 - crc32 = file.crc32; - output[op1++] = output[op2++] = crc32 & 0xff; - output[op1++] = output[op2++] = (crc32 >> 8) & 0xff; - output[op1++] = output[op2++] = (crc32 >> 16) & 0xff; - output[op1++] = output[op2++] = (crc32 >> 24) & 0xff; - - // compressed size - size = file.buffer.length; - output[op1++] = output[op2++] = size & 0xff; - output[op1++] = output[op2++] = (size >> 8) & 0xff; - output[op1++] = output[op2++] = (size >> 16) & 0xff; - output[op1++] = output[op2++] = (size >> 24) & 0xff; - - // uncompressed size - plainSize = file.size; - output[op1++] = output[op2++] = plainSize & 0xff; - output[op1++] = output[op2++] = (plainSize >> 8) & 0xff; - output[op1++] = output[op2++] = (plainSize >> 16) & 0xff; - output[op1++] = output[op2++] = (plainSize >> 24) & 0xff; - - // filename length - output[op1++] = output[op2++] = filenameLength & 0xff; - output[op1++] = output[op2++] = (filenameLength >> 8) & 0xff; - - // extra field length - output[op1++] = output[op2++] = extraFieldLength & 0xff; - output[op1++] = output[op2++] = (extraFieldLength >> 8) & 0xff; - - // file comment length - output[op2++] = commentLength & 0xff; - output[op2++] = (commentLength >> 8) & 0xff; - - // disk number start - output[op2++] = 0; - output[op2++] = 0; - - // internal file attributes - output[op2++] = 0; - output[op2++] = 0; - - // external file attributes - output[op2++] = 0; - output[op2++] = 0; - output[op2++] = 0; - output[op2++] = 0; - - // relative offset of local header - output[op2++] = offset & 0xff; - output[op2++] = (offset >> 8) & 0xff; - output[op2++] = (offset >> 16) & 0xff; - output[op2++] = (offset >> 24) & 0xff; - - // filename - filename = file.option['filename']; - if (filename) { - { - output.set(filename, op1); - output.set(filename, op2); - op1 += filenameLength; - op2 += filenameLength; - } - } - - // extra field - extraField = file.option['extraField']; - if (extraField) { - { - output.set(extraField, op1); - output.set(extraField, op2); - op1 += extraFieldLength; - op2 += extraFieldLength; - } - } - - // comment - comment = file.option['comment']; - if (comment) { - { - output.set(comment, op2); - op2 += commentLength; - } - } - - //------------------------------------------------------------------------- - // file data - //------------------------------------------------------------------------- - - { - output.set(file.buffer, op1); - op1 += file.buffer.length; - } - } - - //------------------------------------------------------------------------- - // end of central directory - //------------------------------------------------------------------------- - - // signature - output[op3++] = Zlib.Zip.CentralDirectorySignature[0]; - output[op3++] = Zlib.Zip.CentralDirectorySignature[1]; - output[op3++] = Zlib.Zip.CentralDirectorySignature[2]; - output[op3++] = Zlib.Zip.CentralDirectorySignature[3]; - - // number of this disk - output[op3++] = 0; - output[op3++] = 0; - - // number of the disk with the start of the central directory - output[op3++] = 0; - output[op3++] = 0; - - // total number of entries in the central directory on this disk - output[op3++] = il & 0xff; - output[op3++] = (il >> 8) & 0xff; - - // total number of entries in the central directory - output[op3++] = il & 0xff; - output[op3++] = (il >> 8) & 0xff; - - // size of the central directory - output[op3++] = centralDirectorySize & 0xff; - output[op3++] = (centralDirectorySize >> 8) & 0xff; - output[op3++] = (centralDirectorySize >> 16) & 0xff; - output[op3++] = (centralDirectorySize >> 24) & 0xff; - - // offset of start of central directory with respect to the starting disk number - output[op3++] = localFileSize & 0xff; - output[op3++] = (localFileSize >> 8) & 0xff; - output[op3++] = (localFileSize >> 16) & 0xff; - output[op3++] = (localFileSize >> 24) & 0xff; - - // .ZIP file comment length - commentLength = this.comment ? this.comment.length : 0; - output[op3++] = commentLength & 0xff; - output[op3++] = (commentLength >> 8) & 0xff; - - // .ZIP file comment - if (this.comment) { - { - output.set(this.comment, op3); - op3 += commentLength; - } - } - - return output; - }; - - /** - * @param {!(Array.|Uint8Array)} input - * @param {Object=} opt_params options. - * @return {!(Array.|Uint8Array)} - */ - Zlib.Zip.prototype.deflateWithOption = function(input, opt_params) { - /** @type {Zlib.RawDeflate} */ - var deflator = new Zlib.RawDeflate(input, opt_params['deflateOption']); - - return deflator.compress(); - }; - - /** - * @param {(Array.|Uint32Array)} key - * @return {number} - */ - Zlib.Zip.prototype.getByte = function(key) { - /** @type {number} */ - var tmp = ((key[2] & 0xffff) | 2); - - return ((tmp * (tmp ^ 1)) >> 8) & 0xff; - }; - - /** - * @param {(Array.|Uint32Array|Object)} key - * @param {number} n - * @return {number} - */ - Zlib.Zip.prototype.encode = function(key, n) { - /** @type {number} */ - var tmp = this.getByte(/** @type {(Array.|Uint32Array)} */(key)); - - this.updateKeys(/** @type {(Array.|Uint32Array)} */(key), n); - - return tmp ^ n; - }; - - /** - * @param {(Array.|Uint32Array)} key - * @param {number} n - */ - Zlib.Zip.prototype.updateKeys = function(key, n) { - key[0] = Zlib.CRC32.single(key[0], n); - key[1] = - (((((key[1] + (key[0] & 0xff)) * 20173 >>> 0) * 6681) >>> 0) + 1) >>> 0; - key[2] = Zlib.CRC32.single(key[2], key[1] >>> 24); - }; - - /** - * @param {(Array.|Uint8Array)} password - * @return {!(Array.|Uint32Array|Object)} - */ - Zlib.Zip.prototype.createEncryptionKey = function(password) { - /** @type {!(Array.|Uint32Array)} */ - var key = [305419896, 591751049, 878082192]; - /** @type {number} */ - var i; - /** @type {number} */ - var il; - - { - key = new Uint32Array(key); - } - - for (i = 0, il = password.length; i < il; ++i) { - this.updateKeys(key, password[i] & 0xff); - } - - return key; - }; - - - - /** - * build huffman table from length list. - * @param {!(Array.|Uint8Array)} lengths length list. - * @return {!Array} huffman table. - */ - Zlib.Huffman.buildHuffmanTable = function(lengths) { - /** @type {number} length list size. */ - var listSize = lengths.length; - /** @type {number} max code length for table size. */ - var maxCodeLength = 0; - /** @type {number} min code length for table size. */ - var minCodeLength = Number.POSITIVE_INFINITY; - /** @type {number} table size. */ - var size; - /** @type {!(Array|Uint8Array)} huffman code table. */ - var table; - /** @type {number} bit length. */ - var bitLength; - /** @type {number} huffman code. */ - var code; - /** - * サイズが 2^maxlength 個のテーブルを埋めるためのスキップ長. - * @type {number} skip length for table filling. - */ - var skip; - /** @type {number} reversed code. */ - var reversed; - /** @type {number} reverse temp. */ - var rtemp; - /** @type {number} loop counter. */ - var i; - /** @type {number} loop limit. */ - var il; - /** @type {number} loop counter. */ - var j; - /** @type {number} table value. */ - var value; - - // Math.max は遅いので最長の値は for-loop で取得する - for (i = 0, il = listSize; i < il; ++i) { - if (lengths[i] > maxCodeLength) { - maxCodeLength = lengths[i]; - } - if (lengths[i] < minCodeLength) { - minCodeLength = lengths[i]; - } - } - - size = 1 << maxCodeLength; - table = new (Uint32Array )(size); - - // ビット長の短い順からハフマン符号を割り当てる - for (bitLength = 1, code = 0, skip = 2; bitLength <= maxCodeLength;) { - for (i = 0; i < listSize; ++i) { - if (lengths[i] === bitLength) { - // ビットオーダーが逆になるためビット長分並びを反転する - for (reversed = 0, rtemp = code, j = 0; j < bitLength; ++j) { - reversed = (reversed << 1) | (rtemp & 1); - rtemp >>= 1; - } - - // 最大ビット長をもとにテーブルを作るため、 - // 最大ビット長以外では 0 / 1 どちらでも良い箇所ができる - // そのどちらでも良い場所は同じ値で埋めることで - // 本来のビット長以上のビット数取得しても問題が起こらないようにする - value = (bitLength << 16) | i; - for (j = reversed; j < size; j += skip) { - table[j] = value; - } - - ++code; - } - } - - // 次のビット長へ - ++bitLength; - code <<= 1; - skip <<= 1; - } - - return [table, maxCodeLength, minCodeLength]; - }; - - - - - //----------------------------------------------------------------------------- - - /** @define {number} buffer block size. */ - var ZLIB_RAW_INFLATE_BUFFER_SIZE = 0x8000; // [ 0x8000 >= ZLIB_BUFFER_BLOCK_SIZE ] - - //----------------------------------------------------------------------------- - - - var buildHuffmanTable = Zlib.Huffman.buildHuffmanTable; - - /** - * @constructor - * @param {!(Uint8Array|Array.)} input input buffer. - * @param {Object} opt_params option parameter. - * - * opt_params は以下のプロパティを指定する事ができます。 - * - index: input buffer の deflate コンテナの開始位置. - * - blockSize: バッファのブロックサイズ. - * - bufferType: Zlib.RawInflate.BufferType の値によってバッファの管理方法を指定する. - * - resize: 確保したバッファが実際の大きさより大きかった場合に切り詰める. - */ - Zlib.RawInflate = function(input, opt_params) { - /** @type {!(Array.|Uint8Array)} inflated buffer */ - this.buffer; - /** @type {!Array.<(Array.|Uint8Array)>} */ - this.blocks = []; - /** @type {number} block size. */ - this.bufferSize = ZLIB_RAW_INFLATE_BUFFER_SIZE; - /** @type {!number} total output buffer pointer. */ - this.totalpos = 0; - /** @type {!number} input buffer pointer. */ - this.ip = 0; - /** @type {!number} bit stream reader buffer. */ - this.bitsbuf = 0; - /** @type {!number} bit stream reader buffer size. */ - this.bitsbuflen = 0; - /** @type {!(Array.|Uint8Array)} input buffer. */ - this.input = new Uint8Array(input) ; - /** @type {!(Uint8Array|Array.)} output buffer. */ - this.output; - /** @type {!number} output buffer pointer. */ - this.op; - /** @type {boolean} is final block flag. */ - this.bfinal = false; - /** @type {Zlib.RawInflate.BufferType} buffer management. */ - this.bufferType = Zlib.RawInflate.BufferType.ADAPTIVE; - /** @type {boolean} resize flag for memory size optimization. */ - this.resize = false; - - // option parameters - if (opt_params || !(opt_params = {})) { - if (opt_params['index']) { - this.ip = opt_params['index']; - } - if (opt_params['bufferSize']) { - this.bufferSize = opt_params['bufferSize']; - } - if (opt_params['bufferType']) { - this.bufferType = opt_params['bufferType']; - } - if (opt_params['resize']) { - this.resize = opt_params['resize']; - } - } - - // initialize - switch (this.bufferType) { - case Zlib.RawInflate.BufferType.BLOCK: - this.op = Zlib.RawInflate.MaxBackwardLength; - this.output = - new (Uint8Array )( - Zlib.RawInflate.MaxBackwardLength + - this.bufferSize + - Zlib.RawInflate.MaxCopyLength - ); - break; - case Zlib.RawInflate.BufferType.ADAPTIVE: - this.op = 0; - this.output = new (Uint8Array )(this.bufferSize); - break; - default: - throw new Error('invalid inflate mode'); - } - }; - - /** - * @enum {number} - */ - Zlib.RawInflate.BufferType = { - BLOCK: 0, - ADAPTIVE: 1 - }; - - /** - * decompress. - * @return {!(Uint8Array|Array.)} inflated buffer. - */ - Zlib.RawInflate.prototype.decompress = function() { - while (!this.bfinal) { - this.parseBlock(); - } - - switch (this.bufferType) { - case Zlib.RawInflate.BufferType.BLOCK: - return this.concatBufferBlock(); - case Zlib.RawInflate.BufferType.ADAPTIVE: - return this.concatBufferDynamic(); - default: - throw new Error('invalid inflate mode'); - } - }; - - /** - * @const - * @type {number} max backward length for LZ77. - */ - Zlib.RawInflate.MaxBackwardLength = 32768; - - /** - * @const - * @type {number} max copy length for LZ77. - */ - Zlib.RawInflate.MaxCopyLength = 258; - - /** - * huffman order - * @const - * @type {!(Array.|Uint8Array)} - */ - Zlib.RawInflate.Order = (function(table) { - return new Uint16Array(table) ; - })([16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15]); - - /** - * huffman length code table. - * @const - * @type {!(Array.|Uint16Array)} - */ - Zlib.RawInflate.LengthCodeTable = (function(table) { - return new Uint16Array(table) ; - })([ - 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, - 0x000d, 0x000f, 0x0011, 0x0013, 0x0017, 0x001b, 0x001f, 0x0023, 0x002b, - 0x0033, 0x003b, 0x0043, 0x0053, 0x0063, 0x0073, 0x0083, 0x00a3, 0x00c3, - 0x00e3, 0x0102, 0x0102, 0x0102 - ]); - - /** - * huffman length extra-bits table. - * @const - * @type {!(Array.|Uint8Array)} - */ - Zlib.RawInflate.LengthExtraTable = (function(table) { - return new Uint8Array(table) ; - })([ - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, - 5, 5, 0, 0, 0 - ]); - - /** - * huffman dist code table. - * @const - * @type {!(Array.|Uint16Array)} - */ - Zlib.RawInflate.DistCodeTable = (function(table) { - return new Uint16Array(table) ; - })([ - 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0007, 0x0009, 0x000d, 0x0011, - 0x0019, 0x0021, 0x0031, 0x0041, 0x0061, 0x0081, 0x00c1, 0x0101, 0x0181, - 0x0201, 0x0301, 0x0401, 0x0601, 0x0801, 0x0c01, 0x1001, 0x1801, 0x2001, - 0x3001, 0x4001, 0x6001 - ]); - - /** - * huffman dist extra-bits table. - * @const - * @type {!(Array.|Uint8Array)} - */ - Zlib.RawInflate.DistExtraTable = (function(table) { - return new Uint8Array(table) ; - })([ - 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, - 11, 12, 12, 13, 13 - ]); - - /** - * fixed huffman length code table - * @const - * @type {!Array} - */ - Zlib.RawInflate.FixedLiteralLengthTable = (function(table) { - return table; - })((function() { - var lengths = new (Uint8Array )(288); - var i, il; - - for (i = 0, il = lengths.length; i < il; ++i) { - lengths[i] = - (i <= 143) ? 8 : - (i <= 255) ? 9 : - (i <= 279) ? 7 : - 8; - } - - return buildHuffmanTable(lengths); - })()); - - /** - * fixed huffman distance code table - * @const - * @type {!Array} - */ - Zlib.RawInflate.FixedDistanceTable = (function(table) { - return table; - })((function() { - var lengths = new (Uint8Array )(30); - var i, il; - - for (i = 0, il = lengths.length; i < il; ++i) { - lengths[i] = 5; - } - - return buildHuffmanTable(lengths); - })()); - - /** - * parse deflated block. - */ - Zlib.RawInflate.prototype.parseBlock = function() { - /** @type {number} header */ - var hdr = this.readBits(3); - - // BFINAL - if (hdr & 0x1) { - this.bfinal = true; - } - - // BTYPE - hdr >>>= 1; - switch (hdr) { - // uncompressed - case 0: - this.parseUncompressedBlock(); - break; - // fixed huffman - case 1: - this.parseFixedHuffmanBlock(); - break; - // dynamic huffman - case 2: - this.parseDynamicHuffmanBlock(); - break; - // reserved or other - default: - throw new Error('unknown BTYPE: ' + hdr); - } - }; - - /** - * read inflate bits - * @param {number} length bits length. - * @return {number} read bits. - */ - Zlib.RawInflate.prototype.readBits = function(length) { - var bitsbuf = this.bitsbuf; - var bitsbuflen = this.bitsbuflen; - var input = this.input; - var ip = this.ip; - - /** @type {number} */ - var inputLength = input.length; - /** @type {number} input and output byte. */ - var octet; - - // input byte - if (ip + ((length - bitsbuflen + 7) >> 3) >= inputLength) { - throw new Error('input buffer is broken'); - } - - // not enough buffer - while (bitsbuflen < length) { - bitsbuf |= input[ip++] << bitsbuflen; - bitsbuflen += 8; - } - - // output byte - octet = bitsbuf & /* MASK */ ((1 << length) - 1); - bitsbuf >>>= length; - bitsbuflen -= length; - - this.bitsbuf = bitsbuf; - this.bitsbuflen = bitsbuflen; - this.ip = ip; - - return octet; - }; - - /** - * read huffman code using table - * @param {!(Array.|Uint8Array|Uint16Array)} table huffman code table. - * @return {number} huffman code. - */ - Zlib.RawInflate.prototype.readCodeByTable = function(table) { - var bitsbuf = this.bitsbuf; - var bitsbuflen = this.bitsbuflen; - var input = this.input; - var ip = this.ip; - - /** @type {number} */ - var inputLength = input.length; - /** @type {!(Array.|Uint8Array)} huffman code table */ - var codeTable = table[0]; - /** @type {number} */ - var maxCodeLength = table[1]; - /** @type {number} code length & code (16bit, 16bit) */ - var codeWithLength; - /** @type {number} code bits length */ - var codeLength; - - // not enough buffer - while (bitsbuflen < maxCodeLength) { - if (ip >= inputLength) { - break; - } - bitsbuf |= input[ip++] << bitsbuflen; - bitsbuflen += 8; - } - - // read max length - codeWithLength = codeTable[bitsbuf & ((1 << maxCodeLength) - 1)]; - codeLength = codeWithLength >>> 16; - - if (codeLength > bitsbuflen) { - throw new Error('invalid code length: ' + codeLength); - } - - this.bitsbuf = bitsbuf >> codeLength; - this.bitsbuflen = bitsbuflen - codeLength; - this.ip = ip; - - return codeWithLength & 0xffff; - }; - - /** - * parse uncompressed block. - */ - Zlib.RawInflate.prototype.parseUncompressedBlock = function() { - var input = this.input; - var ip = this.ip; - var output = this.output; - var op = this.op; - - /** @type {number} */ - var inputLength = input.length; - /** @type {number} block length */ - var len; - /** @type {number} number for check block length */ - var nlen; - /** @type {number} output buffer length */ - var olength = output.length; - /** @type {number} copy counter */ - var preCopy; - - // skip buffered header bits - this.bitsbuf = 0; - this.bitsbuflen = 0; - - // len - if (ip + 1 >= inputLength) { - throw new Error('invalid uncompressed block header: LEN'); - } - len = input[ip++] | (input[ip++] << 8); - - // nlen - if (ip + 1 >= inputLength) { - throw new Error('invalid uncompressed block header: NLEN'); - } - nlen = input[ip++] | (input[ip++] << 8); - - // check len & nlen - if (len === ~nlen) { - throw new Error('invalid uncompressed block header: length verify'); - } - - // check size - if (ip + len > input.length) { throw new Error('input buffer is broken'); } - - // expand buffer - switch (this.bufferType) { - case Zlib.RawInflate.BufferType.BLOCK: - // pre copy - while (op + len > output.length) { - preCopy = olength - op; - len -= preCopy; - { - output.set(input.subarray(ip, ip + preCopy), op); - op += preCopy; - ip += preCopy; - } - this.op = op; - output = this.expandBufferBlock(); - op = this.op; - } - break; - case Zlib.RawInflate.BufferType.ADAPTIVE: - while (op + len > output.length) { - output = this.expandBufferAdaptive({fixRatio: 2}); - } - break; - default: - throw new Error('invalid inflate mode'); - } - - // copy - { - output.set(input.subarray(ip, ip + len), op); - op += len; - ip += len; - } - - this.ip = ip; - this.op = op; - this.output = output; - }; - - /** - * parse fixed huffman block. - */ - Zlib.RawInflate.prototype.parseFixedHuffmanBlock = function() { - switch (this.bufferType) { - case Zlib.RawInflate.BufferType.ADAPTIVE: - this.decodeHuffmanAdaptive( - Zlib.RawInflate.FixedLiteralLengthTable, - Zlib.RawInflate.FixedDistanceTable - ); - break; - case Zlib.RawInflate.BufferType.BLOCK: - this.decodeHuffmanBlock( - Zlib.RawInflate.FixedLiteralLengthTable, - Zlib.RawInflate.FixedDistanceTable - ); - break; - default: - throw new Error('invalid inflate mode'); - } - }; - - /** - * parse dynamic huffman block. - */ - Zlib.RawInflate.prototype.parseDynamicHuffmanBlock = function() { - /** @type {number} number of literal and length codes. */ - var hlit = this.readBits(5) + 257; - /** @type {number} number of distance codes. */ - var hdist = this.readBits(5) + 1; - /** @type {number} number of code lengths. */ - var hclen = this.readBits(4) + 4; - /** @type {!(Uint8Array|Array.)} code lengths. */ - var codeLengths = - new (Uint8Array )(Zlib.RawInflate.Order.length); - /** @type {!Array} code lengths table. */ - var codeLengthsTable; - /** @type {!(Uint8Array|Array.)} literal and length code table. */ - var litlenTable; - /** @type {!(Uint8Array|Array.)} distance code table. */ - var distTable; - /** @type {!(Uint8Array|Array.)} code length table. */ - var lengthTable; - /** @type {number} */ - var code; - /** @type {number} */ - var prev; - /** @type {number} */ - var repeat; - /** @type {number} loop counter. */ - var i; - /** @type {number} loop limit. */ - var il; - - // decode code lengths - for (i = 0; i < hclen; ++i) { - codeLengths[Zlib.RawInflate.Order[i]] = this.readBits(3); - } - - // decode length table - codeLengthsTable = buildHuffmanTable(codeLengths); - lengthTable = new (Uint8Array )(hlit + hdist); - for (i = 0, il = hlit + hdist; i < il;) { - code = this.readCodeByTable(codeLengthsTable); - switch (code) { - case 16: - repeat = 3 + this.readBits(2); - while (repeat--) { lengthTable[i++] = prev; } - break; - case 17: - repeat = 3 + this.readBits(3); - while (repeat--) { lengthTable[i++] = 0; } - prev = 0; - break; - case 18: - repeat = 11 + this.readBits(7); - while (repeat--) { lengthTable[i++] = 0; } - prev = 0; - break; - default: - lengthTable[i++] = code; - prev = code; - break; - } - } - - litlenTable = buildHuffmanTable(lengthTable.subarray(0, hlit)) - ; - distTable = buildHuffmanTable(lengthTable.subarray(hlit)) - ; - - switch (this.bufferType) { - case Zlib.RawInflate.BufferType.ADAPTIVE: - this.decodeHuffmanAdaptive(litlenTable, distTable); - break; - case Zlib.RawInflate.BufferType.BLOCK: - this.decodeHuffmanBlock(litlenTable, distTable); - break; - default: - throw new Error('invalid inflate mode'); - } - }; - - /** - * decode huffman code - * @param {!(Array.|Uint16Array)} litlen literal and length code table. - * @param {!(Array.|Uint8Array)} dist distination code table. - */ - Zlib.RawInflate.prototype.decodeHuffmanBlock = function(litlen, dist) { - var output = this.output; - var op = this.op; - - this.currentLitlenTable = litlen; - - /** @type {number} output position limit. */ - var olength = output.length - Zlib.RawInflate.MaxCopyLength; - /** @type {number} huffman code. */ - var code; - /** @type {number} table index. */ - var ti; - /** @type {number} huffman code distination. */ - var codeDist; - /** @type {number} huffman code length. */ - var codeLength; - - var lengthCodeTable = Zlib.RawInflate.LengthCodeTable; - var lengthExtraTable = Zlib.RawInflate.LengthExtraTable; - var distCodeTable = Zlib.RawInflate.DistCodeTable; - var distExtraTable = Zlib.RawInflate.DistExtraTable; - - while ((code = this.readCodeByTable(litlen)) !== 256) { - // literal - if (code < 256) { - if (op >= olength) { - this.op = op; - output = this.expandBufferBlock(); - op = this.op; - } - output[op++] = code; - - continue; - } - - // length code - ti = code - 257; - codeLength = lengthCodeTable[ti]; - if (lengthExtraTable[ti] > 0) { - codeLength += this.readBits(lengthExtraTable[ti]); - } - - // dist code - code = this.readCodeByTable(dist); - codeDist = distCodeTable[code]; - if (distExtraTable[code] > 0) { - codeDist += this.readBits(distExtraTable[code]); - } - - // lz77 decode - if (op >= olength) { - this.op = op; - output = this.expandBufferBlock(); - op = this.op; - } - while (codeLength--) { - output[op] = output[(op++) - codeDist]; - } - } - - while (this.bitsbuflen >= 8) { - this.bitsbuflen -= 8; - this.ip--; - } - this.op = op; - }; - - /** - * decode huffman code (adaptive) - * @param {!(Array.|Uint16Array)} litlen literal and length code table. - * @param {!(Array.|Uint8Array)} dist distination code table. - */ - Zlib.RawInflate.prototype.decodeHuffmanAdaptive = function(litlen, dist) { - var output = this.output; - var op = this.op; - - this.currentLitlenTable = litlen; - - /** @type {number} output position limit. */ - var olength = output.length; - /** @type {number} huffman code. */ - var code; - /** @type {number} table index. */ - var ti; - /** @type {number} huffman code distination. */ - var codeDist; - /** @type {number} huffman code length. */ - var codeLength; - - var lengthCodeTable = Zlib.RawInflate.LengthCodeTable; - var lengthExtraTable = Zlib.RawInflate.LengthExtraTable; - var distCodeTable = Zlib.RawInflate.DistCodeTable; - var distExtraTable = Zlib.RawInflate.DistExtraTable; - - while ((code = this.readCodeByTable(litlen)) !== 256) { - // literal - if (code < 256) { - if (op >= olength) { - output = this.expandBufferAdaptive(); - olength = output.length; - } - output[op++] = code; - - continue; - } - - // length code - ti = code - 257; - codeLength = lengthCodeTable[ti]; - if (lengthExtraTable[ti] > 0) { - codeLength += this.readBits(lengthExtraTable[ti]); - } - - // dist code - code = this.readCodeByTable(dist); - codeDist = distCodeTable[code]; - if (distExtraTable[code] > 0) { - codeDist += this.readBits(distExtraTable[code]); - } - - // lz77 decode - if (op + codeLength > olength) { - output = this.expandBufferAdaptive(); - olength = output.length; - } - while (codeLength--) { - output[op] = output[(op++) - codeDist]; - } - } - - while (this.bitsbuflen >= 8) { - this.bitsbuflen -= 8; - this.ip--; - } - this.op = op; - }; - - /** - * expand output buffer. - * @param {Object=} opt_param option parameters. - * @return {!(Array.|Uint8Array)} output buffer. - */ - Zlib.RawInflate.prototype.expandBufferBlock = function(opt_param) { - /** @type {!(Array.|Uint8Array)} store buffer. */ - var buffer = - new (Uint8Array )( - this.op - Zlib.RawInflate.MaxBackwardLength - ); - /** @type {number} backward base point */ - var backward = this.op - Zlib.RawInflate.MaxBackwardLength; - - var output = this.output; - - // copy to output buffer - { - buffer.set(output.subarray(Zlib.RawInflate.MaxBackwardLength, buffer.length)); - } - - this.blocks.push(buffer); - this.totalpos += buffer.length; - - // copy to backward buffer - { - output.set( - output.subarray(backward, backward + Zlib.RawInflate.MaxBackwardLength) - ); - } - - this.op = Zlib.RawInflate.MaxBackwardLength; - - return output; - }; - - /** - * expand output buffer. (adaptive) - * @param {Object=} opt_param option parameters. - * @return {!(Array.|Uint8Array)} output buffer pointer. - */ - Zlib.RawInflate.prototype.expandBufferAdaptive = function(opt_param) { - /** @type {!(Array.|Uint8Array)} store buffer. */ - var buffer; - /** @type {number} expantion ratio. */ - var ratio = (this.input.length / this.ip + 1) | 0; - /** @type {number} maximum number of huffman code. */ - var maxHuffCode; - /** @type {number} new output buffer size. */ - var newSize; - /** @type {number} max inflate size. */ - var maxInflateSize; - - var input = this.input; - var output = this.output; - - if (opt_param) { - if (typeof opt_param.fixRatio === 'number') { - ratio = opt_param.fixRatio; - } - if (typeof opt_param.addRatio === 'number') { - ratio += opt_param.addRatio; - } - } - - // calculate new buffer size - if (ratio < 2) { - maxHuffCode = - (input.length - this.ip) / this.currentLitlenTable[2]; - maxInflateSize = (maxHuffCode / 2 * 258) | 0; - newSize = maxInflateSize < output.length ? - output.length + maxInflateSize : - output.length << 1; - } else { - newSize = output.length * ratio; - } - - // buffer expantion - { - buffer = new Uint8Array(newSize); - buffer.set(output); - } - - this.output = buffer; - - return this.output; - }; - - /** - * concat output buffer. - * @return {!(Array.|Uint8Array)} output buffer. - */ - Zlib.RawInflate.prototype.concatBufferBlock = function() { - /** @type {number} buffer pointer. */ - var pos = 0; - /** @type {number} buffer pointer. */ - var limit = this.totalpos + (this.op - Zlib.RawInflate.MaxBackwardLength); - /** @type {!(Array.|Uint8Array)} output block array. */ - var output = this.output; - /** @type {!Array} blocks array. */ - var blocks = this.blocks; - /** @type {!(Array.|Uint8Array)} output block array. */ - var block; - /** @type {!(Array.|Uint8Array)} output buffer. */ - var buffer = new (Uint8Array )(limit); - /** @type {number} loop counter. */ - var i; - /** @type {number} loop limiter. */ - var il; - /** @type {number} loop counter. */ - var j; - /** @type {number} loop limiter. */ - var jl; - - // single buffer - if (blocks.length === 0) { - return this.output.subarray(Zlib.RawInflate.MaxBackwardLength, this.op) ; - } - - // copy to buffer - for (i = 0, il = blocks.length; i < il; ++i) { - block = blocks[i]; - for (j = 0, jl = block.length; j < jl; ++j) { - buffer[pos++] = block[j]; - } - } - - // current buffer - for (i = Zlib.RawInflate.MaxBackwardLength, il = this.op; i < il; ++i) { - buffer[pos++] = output[i]; - } - - this.blocks = []; - this.buffer = buffer; - - return this.buffer; - }; - - /** - * concat output buffer. (dynamic) - * @return {!(Array.|Uint8Array)} output buffer. - */ - Zlib.RawInflate.prototype.concatBufferDynamic = function() { - /** @type {Array.|Uint8Array} output buffer. */ - var buffer; - var op = this.op; - - { - if (this.resize) { - buffer = new Uint8Array(op); - buffer.set(this.output.subarray(0, op)); - } else { - buffer = this.output.subarray(0, op); - } - } - - this.buffer = buffer; - - return this.buffer; - }; - - - - - var buildHuffmanTable = Zlib.Huffman.buildHuffmanTable; - - /** - * @param {!(Uint8Array|Array.)} input input buffer. - * @param {number} ip input buffer pointer. - * @param {number=} opt_buffersize buffer block size. - * @constructor - */ - Zlib.RawInflateStream = function(input, ip, opt_buffersize) { - /** @type {!Array.<(Array|Uint8Array)>} */ - this.blocks = []; - /** @type {number} block size. */ - this.bufferSize = - opt_buffersize ? opt_buffersize : ZLIB_STREAM_RAW_INFLATE_BUFFER_SIZE; - /** @type {!number} total output buffer pointer. */ - this.totalpos = 0; - /** @type {!number} input buffer pointer. */ - this.ip = ip === void 0 ? 0 : ip; - /** @type {!number} bit stream reader buffer. */ - this.bitsbuf = 0; - /** @type {!number} bit stream reader buffer size. */ - this.bitsbuflen = 0; - /** @type {!(Array|Uint8Array)} input buffer. */ - this.input = new Uint8Array(input) ; - /** @type {!(Uint8Array|Array)} output buffer. */ - this.output = new (Uint8Array )(this.bufferSize); - /** @type {!number} output buffer pointer. */ - this.op = 0; - /** @type {boolean} is final block flag. */ - this.bfinal = false; - /** @type {number} uncompressed block length. */ - this.blockLength; - /** @type {boolean} resize flag for memory size optimization. */ - this.resize = false; - /** @type {Array} */ - this.litlenTable; - /** @type {Array} */ - this.distTable; - /** @type {number} */ - this.sp = 0; // stream pointer - /** @type {Zlib.RawInflateStream.Status} */ - this.status = Zlib.RawInflateStream.Status.INITIALIZED; - - // - // backup - // - /** @type {!number} */ - this.ip_; - /** @type {!number} */ - this.bitsbuflen_; - /** @type {!number} */ - this.bitsbuf_; - }; - - /** - * @enum {number} - */ - Zlib.RawInflateStream.BlockType = { - UNCOMPRESSED: 0, - FIXED: 1, - DYNAMIC: 2 - }; - - /** - * @enum {number} - */ - Zlib.RawInflateStream.Status = { - INITIALIZED: 0, - BLOCK_HEADER_START: 1, - BLOCK_HEADER_END: 2, - BLOCK_BODY_START: 3, - BLOCK_BODY_END: 4, - DECODE_BLOCK_START: 5, - DECODE_BLOCK_END: 6 - }; - - /** - * decompress. - * @return {!(Uint8Array|Array)} inflated buffer. - */ - Zlib.RawInflateStream.prototype.decompress = function(newInput, ip) { - /** @type {boolean} */ - var stop = false; - - if (newInput !== void 0) { - this.input = newInput; - } - - if (ip !== void 0) { - this.ip = ip; - } - - // decompress - while (!stop) { - switch (this.status) { - // block header - case Zlib.RawInflateStream.Status.INITIALIZED: - case Zlib.RawInflateStream.Status.BLOCK_HEADER_START: - if (this.readBlockHeader() < 0) { - stop = true; - } - break; - // block body - case Zlib.RawInflateStream.Status.BLOCK_HEADER_END: /* FALLTHROUGH */ - case Zlib.RawInflateStream.Status.BLOCK_BODY_START: - switch(this.currentBlockType) { - case Zlib.RawInflateStream.BlockType.UNCOMPRESSED: - if (this.readUncompressedBlockHeader() < 0) { - stop = true; - } - break; - case Zlib.RawInflateStream.BlockType.FIXED: - if (this.parseFixedHuffmanBlock() < 0) { - stop = true; - } - break; - case Zlib.RawInflateStream.BlockType.DYNAMIC: - if (this.parseDynamicHuffmanBlock() < 0) { - stop = true; - } - break; - } - break; - // decode data - case Zlib.RawInflateStream.Status.BLOCK_BODY_END: - case Zlib.RawInflateStream.Status.DECODE_BLOCK_START: - switch(this.currentBlockType) { - case Zlib.RawInflateStream.BlockType.UNCOMPRESSED: - if (this.parseUncompressedBlock() < 0) { - stop = true; - } - break; - case Zlib.RawInflateStream.BlockType.FIXED: /* FALLTHROUGH */ - case Zlib.RawInflateStream.BlockType.DYNAMIC: - if (this.decodeHuffman() < 0) { - stop = true; - } - break; - } - break; - case Zlib.RawInflateStream.Status.DECODE_BLOCK_END: - if (this.bfinal) { - stop = true; - } else { - this.status = Zlib.RawInflateStream.Status.INITIALIZED; - } - break; - } - } - - return this.concatBuffer(); - }; - - /** - * @const - * @type {number} max backward length for LZ77. - */ - Zlib.RawInflateStream.MaxBackwardLength = 32768; - - /** - * @const - * @type {number} max copy length for LZ77. - */ - Zlib.RawInflateStream.MaxCopyLength = 258; - - /** - * huffman order - * @const - * @type {!(Array.|Uint8Array)} - */ - Zlib.RawInflateStream.Order = (function(table) { - return new Uint16Array(table) ; - })([16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15]); - - /** - * huffman length code table. - * @const - * @type {!(Array.|Uint16Array)} - */ - Zlib.RawInflateStream.LengthCodeTable = (function(table) { - return new Uint16Array(table) ; - })([ - 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, - 0x000d, 0x000f, 0x0011, 0x0013, 0x0017, 0x001b, 0x001f, 0x0023, 0x002b, - 0x0033, 0x003b, 0x0043, 0x0053, 0x0063, 0x0073, 0x0083, 0x00a3, 0x00c3, - 0x00e3, 0x0102, 0x0102, 0x0102 - ]); - - /** - * huffman length extra-bits table. - * @const - * @type {!(Array.|Uint8Array)} - */ - Zlib.RawInflateStream.LengthExtraTable = (function(table) { - return new Uint8Array(table) ; - })([ - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, - 5, 5, 0, 0, 0 - ]); - - /** - * huffman dist code table. - * @const - * @type {!(Array.|Uint16Array)} - */ - Zlib.RawInflateStream.DistCodeTable = (function(table) { - return new Uint16Array(table) ; - })([ - 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0007, 0x0009, 0x000d, 0x0011, - 0x0019, 0x0021, 0x0031, 0x0041, 0x0061, 0x0081, 0x00c1, 0x0101, 0x0181, - 0x0201, 0x0301, 0x0401, 0x0601, 0x0801, 0x0c01, 0x1001, 0x1801, 0x2001, - 0x3001, 0x4001, 0x6001 - ]); - - /** - * huffman dist extra-bits table. - * @const - * @type {!(Array.|Uint8Array)} - */ - Zlib.RawInflateStream.DistExtraTable = (function(table) { - return new Uint8Array(table) ; - })([ - 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, - 11, 12, 12, 13, 13 - ]); - - /** - * fixed huffman length code table - * @const - * @type {!Array} - */ - Zlib.RawInflateStream.FixedLiteralLengthTable = (function(table) { - return table; - })((function() { - var lengths = new (Uint8Array )(288); - var i, il; - - for (i = 0, il = lengths.length; i < il; ++i) { - lengths[i] = - (i <= 143) ? 8 : - (i <= 255) ? 9 : - (i <= 279) ? 7 : - 8; - } - - return buildHuffmanTable(lengths); - })()); - - /** - * fixed huffman distance code table - * @const - * @type {!Array} - */ - Zlib.RawInflateStream.FixedDistanceTable = (function(table) { - return table; - })((function() { - var lengths = new (Uint8Array )(30); - var i, il; - - for (i = 0, il = lengths.length; i < il; ++i) { - lengths[i] = 5; - } - - return buildHuffmanTable(lengths); - })()); - - /** - * parse deflated block. - */ - Zlib.RawInflateStream.prototype.readBlockHeader = function() { - /** @type {number} header */ - var hdr; - - this.status = Zlib.RawInflateStream.Status.BLOCK_HEADER_START; - - this.save_(); - if ((hdr = this.readBits(3)) < 0) { - this.restore_(); - return -1; - } - - // BFINAL - if (hdr & 0x1) { - this.bfinal = true; - } - - // BTYPE - hdr >>>= 1; - switch (hdr) { - case 0: // uncompressed - this.currentBlockType = Zlib.RawInflateStream.BlockType.UNCOMPRESSED; - break; - case 1: // fixed huffman - this.currentBlockType = Zlib.RawInflateStream.BlockType.FIXED; - break; - case 2: // dynamic huffman - this.currentBlockType = Zlib.RawInflateStream.BlockType.DYNAMIC; - break; - default: // reserved or other - throw new Error('unknown BTYPE: ' + hdr); - } - - this.status = Zlib.RawInflateStream.Status.BLOCK_HEADER_END; - }; - - /** - * read inflate bits - * @param {number} length bits length. - * @return {number} read bits. - */ - Zlib.RawInflateStream.prototype.readBits = function(length) { - var bitsbuf = this.bitsbuf; - var bitsbuflen = this.bitsbuflen; - var input = this.input; - var ip = this.ip; - - /** @type {number} input and output byte. */ - var octet; - - // not enough buffer - while (bitsbuflen < length) { - // input byte - if (input.length <= ip) { - return -1; - } - octet = input[ip++]; - - // concat octet - bitsbuf |= octet << bitsbuflen; - bitsbuflen += 8; - } - - // output byte - octet = bitsbuf & /* MASK */ ((1 << length) - 1); - bitsbuf >>>= length; - bitsbuflen -= length; - - this.bitsbuf = bitsbuf; - this.bitsbuflen = bitsbuflen; - this.ip = ip; - - return octet; - }; - - /** - * read huffman code using table - * @param {Array} table huffman code table. - * @return {number} huffman code. - */ - Zlib.RawInflateStream.prototype.readCodeByTable = function(table) { - var bitsbuf = this.bitsbuf; - var bitsbuflen = this.bitsbuflen; - var input = this.input; - var ip = this.ip; - - /** @type {!(Array|Uint8Array)} huffman code table */ - var codeTable = table[0]; - /** @type {number} */ - var maxCodeLength = table[1]; - /** @type {number} input byte */ - var octet; - /** @type {number} code length & code (16bit, 16bit) */ - var codeWithLength; - /** @type {number} code bits length */ - var codeLength; - - // not enough buffer - while (bitsbuflen < maxCodeLength) { - if (input.length <= ip) { - return -1; - } - octet = input[ip++]; - bitsbuf |= octet << bitsbuflen; - bitsbuflen += 8; - } - - // read max length - codeWithLength = codeTable[bitsbuf & ((1 << maxCodeLength) - 1)]; - codeLength = codeWithLength >>> 16; - - if (codeLength > bitsbuflen) { - throw new Error('invalid code length: ' + codeLength); - } - - this.bitsbuf = bitsbuf >> codeLength; - this.bitsbuflen = bitsbuflen - codeLength; - this.ip = ip; - - return codeWithLength & 0xffff; - }; - - /** - * read uncompressed block header - */ - Zlib.RawInflateStream.prototype.readUncompressedBlockHeader = function() { - /** @type {number} block length */ - var len; - /** @type {number} number for check block length */ - var nlen; - - var input = this.input; - var ip = this.ip; - - this.status = Zlib.RawInflateStream.Status.BLOCK_BODY_START; - - if (ip + 4 >= input.length) { - return -1; - } - - len = input[ip++] | (input[ip++] << 8); - nlen = input[ip++] | (input[ip++] << 8); - - // check len & nlen - if (len === ~nlen) { - throw new Error('invalid uncompressed block header: length verify'); - } - - // skip buffered header bits - this.bitsbuf = 0; - this.bitsbuflen = 0; - - this.ip = ip; - this.blockLength = len; - this.status = Zlib.RawInflateStream.Status.BLOCK_BODY_END; - }; - - /** - * parse uncompressed block. - */ - Zlib.RawInflateStream.prototype.parseUncompressedBlock = function() { - var input = this.input; - var ip = this.ip; - var output = this.output; - var op = this.op; - var len = this.blockLength; - - this.status = Zlib.RawInflateStream.Status.DECODE_BLOCK_START; - - // copy - // XXX: とりあえず素直にコピー - while (len--) { - if (op === output.length) { - output = this.expandBuffer({fixRatio: 2}); - } - - // not enough input buffer - if (ip >= input.length) { - this.ip = ip; - this.op = op; - this.blockLength = len + 1; // コピーしてないので戻す - return -1; - } - - output[op++] = input[ip++]; - } - - if (len < 0) { - this.status = Zlib.RawInflateStream.Status.DECODE_BLOCK_END; - } - - this.ip = ip; - this.op = op; - - return 0; - }; - - /** - * parse fixed huffman block. - */ - Zlib.RawInflateStream.prototype.parseFixedHuffmanBlock = function() { - this.status = Zlib.RawInflateStream.Status.BLOCK_BODY_START; - - this.litlenTable = Zlib.RawInflateStream.FixedLiteralLengthTable; - this.distTable = Zlib.RawInflateStream.FixedDistanceTable; - - this.status = Zlib.RawInflateStream.Status.BLOCK_BODY_END; - - return 0; - }; - - /** - * オブジェクトのコンテキストを別のプロパティに退避する. - * @private - */ - Zlib.RawInflateStream.prototype.save_ = function() { - this.ip_ = this.ip; - this.bitsbuflen_ = this.bitsbuflen; - this.bitsbuf_ = this.bitsbuf; - }; - - /** - * 別のプロパティに退避したコンテキストを復元する. - * @private - */ - Zlib.RawInflateStream.prototype.restore_ = function() { - this.ip = this.ip_; - this.bitsbuflen = this.bitsbuflen_; - this.bitsbuf = this.bitsbuf_; - }; - - /** - * parse dynamic huffman block. - */ - Zlib.RawInflateStream.prototype.parseDynamicHuffmanBlock = function() { - /** @type {number} number of literal and length codes. */ - var hlit; - /** @type {number} number of distance codes. */ - var hdist; - /** @type {number} number of code lengths. */ - var hclen; - /** @type {!(Uint8Array|Array)} code lengths. */ - var codeLengths = - new (Uint8Array )(Zlib.RawInflateStream.Order.length); - /** @type {!Array} code lengths table. */ - var codeLengthsTable; - - this.status = Zlib.RawInflateStream.Status.BLOCK_BODY_START; - - this.save_(); - hlit = this.readBits(5) + 257; - hdist = this.readBits(5) + 1; - hclen = this.readBits(4) + 4; - if (hlit < 0 || hdist < 0 || hclen < 0) { - this.restore_(); - return -1; - } - - try { - parseDynamicHuffmanBlockImpl.call(this); - } catch(e) { - this.restore_(); - return -1; - } - - function parseDynamicHuffmanBlockImpl() { - /** @type {number} */ - var bits; - var code; - var prev = 0; - var repeat; - /** @type {!(Uint8Array|Array.)} code length table. */ - var lengthTable; - /** @type {number} loop counter. */ - var i; - /** @type {number} loop limit. */ - var il; - - // decode code lengths - for (i = 0; i < hclen; ++i) { - if ((bits = this.readBits(3)) < 0) { - throw new Error('not enough input'); - } - codeLengths[Zlib.RawInflateStream.Order[i]] = bits; - } - - // decode length table - codeLengthsTable = buildHuffmanTable(codeLengths); - lengthTable = new (Uint8Array )(hlit + hdist); - for (i = 0, il = hlit + hdist; i < il;) { - code = this.readCodeByTable(codeLengthsTable); - if (code < 0) { - throw new Error('not enough input'); - } - switch (code) { - case 16: - if ((bits = this.readBits(2)) < 0) { - throw new Error('not enough input'); - } - repeat = 3 + bits; - while (repeat--) { lengthTable[i++] = prev; } - break; - case 17: - if ((bits = this.readBits(3)) < 0) { - throw new Error('not enough input'); - } - repeat = 3 + bits; - while (repeat--) { lengthTable[i++] = 0; } - prev = 0; - break; - case 18: - if ((bits = this.readBits(7)) < 0) { - throw new Error('not enough input'); - } - repeat = 11 + bits; - while (repeat--) { lengthTable[i++] = 0; } - prev = 0; - break; - default: - lengthTable[i++] = code; - prev = code; - break; - } - } - - this.litlenTable = buildHuffmanTable(lengthTable.subarray(0, hlit)) - ; - this.distTable = buildHuffmanTable(lengthTable.subarray(hlit)) - ; - } - - this.status = Zlib.RawInflateStream.Status.BLOCK_BODY_END; - - return 0; - }; - - /** - * decode huffman code (dynamic) - * @return {(number|undefined)} -1 is error. - */ - Zlib.RawInflateStream.prototype.decodeHuffman = function() { - var output = this.output; - var op = this.op; - - /** @type {number} huffman code. */ - var code; - /** @type {number} table index. */ - var ti; - /** @type {number} huffman code distination. */ - var codeDist; - /** @type {number} huffman code length. */ - var codeLength; - - var litlen = this.litlenTable; - var dist = this.distTable; - - var olength = output.length; - var bits; - - this.status = Zlib.RawInflateStream.Status.DECODE_BLOCK_START; - - while (true) { - this.save_(); - - code = this.readCodeByTable(litlen); - if (code < 0) { - this.op = op; - this.restore_(); - return -1; - } - - if (code === 256) { - break; - } - - // literal - if (code < 256) { - if (op === olength) { - output = this.expandBuffer(); - olength = output.length; - } - output[op++] = code; - - continue; - } - - // length code - ti = code - 257; - codeLength = Zlib.RawInflateStream.LengthCodeTable[ti]; - if (Zlib.RawInflateStream.LengthExtraTable[ti] > 0) { - bits = this.readBits(Zlib.RawInflateStream.LengthExtraTable[ti]); - if (bits < 0) { - this.op = op; - this.restore_(); - return -1; - } - codeLength += bits; - } - - // dist code - code = this.readCodeByTable(dist); - if (code < 0) { - this.op = op; - this.restore_(); - return -1; - } - codeDist = Zlib.RawInflateStream.DistCodeTable[code]; - if (Zlib.RawInflateStream.DistExtraTable[code] > 0) { - bits = this.readBits(Zlib.RawInflateStream.DistExtraTable[code]); - if (bits < 0) { - this.op = op; - this.restore_(); - return -1; - } - codeDist += bits; - } - - // lz77 decode - if (op + codeLength >= olength) { - output = this.expandBuffer(); - olength = output.length; - } - - while (codeLength--) { - output[op] = output[(op++) - codeDist]; - } - - // break - if (this.ip === this.input.length) { - this.op = op; - return -1; - } - } - - while (this.bitsbuflen >= 8) { - this.bitsbuflen -= 8; - this.ip--; - } - - this.op = op; - this.status = Zlib.RawInflateStream.Status.DECODE_BLOCK_END; - }; - - /** - * expand output buffer. (dynamic) - * @param {Object=} opt_param option parameters. - * @return {!(Array|Uint8Array)} output buffer pointer. - */ - Zlib.RawInflateStream.prototype.expandBuffer = function(opt_param) { - /** @type {!(Array|Uint8Array)} store buffer. */ - var buffer; - /** @type {number} expantion ratio. */ - var ratio = (this.input.length / this.ip + 1) | 0; - /** @type {number} maximum number of huffman code. */ - var maxHuffCode; - /** @type {number} new output buffer size. */ - var newSize; - /** @type {number} max inflate size. */ - var maxInflateSize; - - var input = this.input; - var output = this.output; - - if (opt_param) { - if (typeof opt_param.fixRatio === 'number') { - ratio = opt_param.fixRatio; - } - if (typeof opt_param.addRatio === 'number') { - ratio += opt_param.addRatio; - } - } - - // calculate new buffer size - if (ratio < 2) { - maxHuffCode = - (input.length - this.ip) / this.litlenTable[2]; - maxInflateSize = (maxHuffCode / 2 * 258) | 0; - newSize = maxInflateSize < output.length ? - output.length + maxInflateSize : - output.length << 1; - } else { - newSize = output.length * ratio; - } - - // buffer expantion - { - buffer = new Uint8Array(newSize); - buffer.set(output); - } - - this.output = buffer; - - return this.output; - }; - - /** - * concat output buffer. (dynamic) - * @return {!(Array|Uint8Array)} output buffer. - */ - Zlib.RawInflateStream.prototype.concatBuffer = function() { - /** @type {!(Array|Uint8Array)} output buffer. */ - var buffer; - /** @type {number} */ - var op = this.op; - /** @type {Uint8Array} */ - var tmp; - - if (this.resize) { - { - buffer = new Uint8Array(this.output.subarray(this.sp, op)); - } - } else { - buffer = - this.output.subarray(this.sp, op) ; - } - - this.sp = op; - - // compaction - if (op > Zlib.RawInflateStream.MaxBackwardLength + this.bufferSize) { - this.op = this.sp = Zlib.RawInflateStream.MaxBackwardLength; - { - tmp = /** @type {Uint8Array} */(this.output); - this.output = new Uint8Array(this.bufferSize + Zlib.RawInflateStream.MaxBackwardLength); - this.output.set(tmp.subarray(op - Zlib.RawInflateStream.MaxBackwardLength, op)); - } - } - - return buffer; - }; - - - /** - * @constructor - * @param {!(Uint8Array|Array)} input deflated buffer. - * @param {Object=} opt_params option parameters. - * - * opt_params は以下のプロパティを指定する事ができます。 - * - index: input buffer の deflate コンテナの開始位置. - * - blockSize: バッファのブロックサイズ. - * - verify: 伸張が終わった後 adler-32 checksum の検証を行うか. - * - bufferType: Zlib.Inflate.BufferType の値によってバッファの管理方法を指定する. - * Zlib.Inflate.BufferType は Zlib.RawInflate.BufferType のエイリアス. - */ - Zlib.Inflate = function(input, opt_params) { - /** @type {number} */ - var cmf; - /** @type {number} */ - var flg; - - /** @type {!(Uint8Array|Array)} */ - this.input = input; - /** @type {number} */ - this.ip = 0; - /** @type {Zlib.RawInflate} */ - this.rawinflate; - /** @type {(boolean|undefined)} verify flag. */ - this.verify; - - // option parameters - if (opt_params || !(opt_params = {})) { - if (opt_params['index']) { - this.ip = opt_params['index']; - } - if (opt_params['verify']) { - this.verify = opt_params['verify']; - } - } - - // Compression Method and Flags - cmf = input[this.ip++]; - flg = input[this.ip++]; - - // compression method - switch (cmf & 0x0f) { - case Zlib.CompressionMethod.DEFLATE: - this.method = Zlib.CompressionMethod.DEFLATE; - break; - default: - throw new Error('unsupported compression method'); - } - - // fcheck - if (((cmf << 8) + flg) % 31 !== 0) { - throw new Error('invalid fcheck flag:' + ((cmf << 8) + flg) % 31); - } - - // fdict (not supported) - if (flg & 0x20) { - throw new Error('fdict flag is not supported'); - } - - // RawInflate - this.rawinflate = new Zlib.RawInflate(input, { - 'index': this.ip, - 'bufferSize': opt_params['bufferSize'], - 'bufferType': opt_params['bufferType'], - 'resize': opt_params['resize'] - }); - }; - - /** - * @enum {number} - */ - Zlib.Inflate.BufferType = Zlib.RawInflate.BufferType; - - /** - * decompress. - * @return {!(Uint8Array|Array)} inflated buffer. - */ - Zlib.Inflate.prototype.decompress = function() { - /** @type {!(Array|Uint8Array)} input buffer. */ - var input = this.input; - /** @type {!(Uint8Array|Array)} inflated buffer. */ - var buffer; - /** @type {number} adler-32 checksum */ - var adler32; - - buffer = this.rawinflate.decompress(); - this.ip = this.rawinflate.ip; - - // verify adler-32 - if (this.verify) { - adler32 = ( - input[this.ip++] << 24 | input[this.ip++] << 16 | - input[this.ip++] << 8 | input[this.ip++] - ) >>> 0; - - if (adler32 !== Zlib.Adler32(buffer)) { - throw new Error('invalid adler-32 checksum'); - } - } - - return buffer; - }; - - - /* vim:set expandtab ts=2 sw=2 tw=80: */ - - - /** - * @param {!(Uint8Array|Array)} input deflated buffer. - * @constructor - */ - Zlib.InflateStream = function(input) { - /** @type {!(Uint8Array|Array)} */ - this.input = input === void 0 ? new (Uint8Array )() : input; - /** @type {number} */ - this.ip = 0; - /** @type {Zlib.RawInflateStream} */ - this.rawinflate = new Zlib.RawInflateStream(this.input, this.ip); - /** @type {Zlib.CompressionMethod} */ - this.method; - /** @type {!(Array|Uint8Array)} */ - this.output = this.rawinflate.output; - }; - - /** - * decompress. - * @return {!(Uint8Array|Array)} inflated buffer. - */ - Zlib.InflateStream.prototype.decompress = function(input) { - /** @type {!(Uint8Array|Array)} inflated buffer. */ - var buffer; - - // 新しい入力を入力バッファに結合する - // XXX Array, Uint8Array のチェックを行うか確認する - if (input !== void 0) { - { - var tmp = new Uint8Array(this.input.length + input.length); - tmp.set(this.input, 0); - tmp.set(input, this.input.length); - this.input = tmp; - } - } - - if (this.method === void 0) { - if(this.readHeader() < 0) { - return new (Uint8Array )(); - } - } - - buffer = this.rawinflate.decompress(this.input, this.ip); - if (this.rawinflate.ip !== 0) { - this.input = this.input.subarray(this.rawinflate.ip) ; - this.ip = 0; - } - - // verify adler-32 - /* - if (this.verify) { - adler32 = - input[this.ip++] << 24 | input[this.ip++] << 16 | - input[this.ip++] << 8 | input[this.ip++]; - - if (adler32 !== Zlib.Adler32(buffer)) { - throw new Error('invalid adler-32 checksum'); - } - } - */ - - return buffer; - }; - - Zlib.InflateStream.prototype.readHeader = function() { - var ip = this.ip; - var input = this.input; - - // Compression Method and Flags - var cmf = input[ip++]; - var flg = input[ip++]; - - if (cmf === void 0 || flg === void 0) { - return -1; - } - - // compression method - switch (cmf & 0x0f) { - case Zlib.CompressionMethod.DEFLATE: - this.method = Zlib.CompressionMethod.DEFLATE; - break; - default: - throw new Error('unsupported compression method'); - } - - // fcheck - if (((cmf << 8) + flg) % 31 !== 0) { - throw new Error('invalid fcheck flag:' + ((cmf << 8) + flg) % 31); - } - - // fdict (not supported) - if (flg & 0x20) { - throw new Error('fdict flag is not supported'); - } - - this.ip = ip; - }; - - - /** - * @fileoverview GZIP (RFC1952) 展開コンテナ実装. - */ - - /** - * @constructor - * @param {!(Array|Uint8Array)} input input buffer. - * @param {Object=} opt_params option parameters. - */ - Zlib.Gunzip = function(input, opt_params) { - /** @type {!(Array.|Uint8Array)} input buffer. */ - this.input = input; - /** @type {number} input buffer pointer. */ - this.ip = 0; - /** @type {Array.} */ - this.member = []; - /** @type {boolean} */ - this.decompressed = false; - }; - - /** - * @return {Array.} - */ - Zlib.Gunzip.prototype.getMembers = function() { - if (!this.decompressed) { - this.decompress(); - } - - return this.member.slice(); - }; - - /** - * inflate gzip data. - * @return {!(Array.|Uint8Array)} inflated buffer. - */ - Zlib.Gunzip.prototype.decompress = function() { - /** @type {number} input length. */ - var il = this.input.length; - - while (this.ip < il) { - this.decodeMember(); - } - - this.decompressed = true; - - return this.concatMember(); - }; - - /** - * decode gzip member. - */ - Zlib.Gunzip.prototype.decodeMember = function() { - /** @type {Zlib.GunzipMember} */ - var member = new Zlib.GunzipMember(); - /** @type {number} */ - var isize; - /** @type {Zlib.RawInflate} RawInflate implementation. */ - var rawinflate; - /** @type {!(Array.|Uint8Array)} inflated data. */ - var inflated; - /** @type {number} inflate size */ - var inflen; - /** @type {number} character code */ - var c; - /** @type {number} character index in string. */ - var ci; - /** @type {Array.} character array. */ - var str; - /** @type {number} modification time. */ - var mtime; - /** @type {number} */ - var crc32; - - var input = this.input; - var ip = this.ip; - - member.id1 = input[ip++]; - member.id2 = input[ip++]; - - // check signature - if (member.id1 !== 0x1f || member.id2 !== 0x8b) { - throw new Error('invalid file signature:' + member.id1 + ',' + member.id2); - } - - // check compression method - member.cm = input[ip++]; - switch (member.cm) { - case 8: /* XXX: use Zlib const */ - break; - default: - throw new Error('unknown compression method: ' + member.cm); - } - - // flags - member.flg = input[ip++]; - - // modification time - mtime = (input[ip++]) | - (input[ip++] << 8) | - (input[ip++] << 16) | - (input[ip++] << 24); - member.mtime = new Date(mtime * 1000); - - // extra flags - member.xfl = input[ip++]; - - // operating system - member.os = input[ip++]; - - // extra - if ((member.flg & Zlib.Gzip.FlagsMask.FEXTRA) > 0) { - member.xlen = input[ip++] | (input[ip++] << 8); - ip = this.decodeSubField(ip, member.xlen); - } - - // fname - if ((member.flg & Zlib.Gzip.FlagsMask.FNAME) > 0) { - for(str = [], ci = 0; (c = input[ip++]) > 0;) { - str[ci++] = String.fromCharCode(c); - } - member.name = str.join(''); - } - - // fcomment - if ((member.flg & Zlib.Gzip.FlagsMask.FCOMMENT) > 0) { - for(str = [], ci = 0; (c = input[ip++]) > 0;) { - str[ci++] = String.fromCharCode(c); - } - member.comment = str.join(''); - } - - // fhcrc - if ((member.flg & Zlib.Gzip.FlagsMask.FHCRC) > 0) { - member.crc16 = Zlib.CRC32.calc(input, 0, ip) & 0xffff; - if (member.crc16 !== (input[ip++] | (input[ip++] << 8))) { - throw new Error('invalid header crc16'); - } - } - - // isize を事前に取得すると展開後のサイズが分かるため、 - // inflate処理のバッファサイズが事前に分かり、高速になる - isize = (input[input.length - 4]) | (input[input.length - 3] << 8) | - (input[input.length - 2] << 16) | (input[input.length - 1] << 24); - - // isize の妥当性チェック - // ハフマン符号では最小 2-bit のため、最大で 1/4 になる - // LZ77 符号では 長さと距離 2-Byte で最大 258-Byte を表現できるため、 - // 1/128 になるとする - // ここから入力バッファの残りが isize の 512 倍以上だったら - // サイズ指定のバッファ確保は行わない事とする - if (input.length - ip - /* CRC-32 */4 - /* ISIZE */4 < isize * 512) { - inflen = isize; - } - - // compressed block - rawinflate = new Zlib.RawInflate(input, {'index': ip, 'bufferSize': inflen}); - member.data = inflated = rawinflate.decompress(); - ip = rawinflate.ip; - - // crc32 - member.crc32 = crc32 = - ((input[ip++]) | (input[ip++] << 8) | - (input[ip++] << 16) | (input[ip++] << 24)) >>> 0; - if (Zlib.CRC32.calc(inflated) !== crc32) { - throw new Error('invalid CRC-32 checksum: 0x' + - Zlib.CRC32.calc(inflated).toString(16) + ' / 0x' + crc32.toString(16)); - } - - // input size - member.isize = isize = - ((input[ip++]) | (input[ip++] << 8) | - (input[ip++] << 16) | (input[ip++] << 24)) >>> 0; - if ((inflated.length & 0xffffffff) !== isize) { - throw new Error('invalid input size: ' + - (inflated.length & 0xffffffff) + ' / ' + isize); - } - - this.member.push(member); - this.ip = ip; - }; - - /** - * サブフィールドのデコード - * XXX: 現在は何もせずスキップする - */ - Zlib.Gunzip.prototype.decodeSubField = function(ip, length) { - return ip + length; - }; - - /** - * @return {!(Array.|Uint8Array)} - */ - Zlib.Gunzip.prototype.concatMember = function() { - /** @type {Array.} */ - var member = this.member; - /** @type {number} */ - var i; - /** @type {number} */ - var il; - /** @type {number} */ - var p = 0; - /** @type {number} */ - var size = 0; - /** @type {!(Array.|Uint8Array)} */ - var buffer; - - for (i = 0, il = member.length; i < il; ++i) { - size += member[i].data.length; - } - - { - buffer = new Uint8Array(size); - for (i = 0; i < il; ++i) { - buffer.set(member[i].data, p); - p += member[i].data.length; - } - } - - return buffer; - }; - - - - /** - * @constructor - */ - Zlib.GunzipMember = function() { - /** @type {number} signature first byte. */ - this.id1; - /** @type {number} signature second byte. */ - this.id2; - /** @type {number} compression method. */ - this.cm; - /** @type {number} flags. */ - this.flg; - /** @type {Date} modification time. */ - this.mtime; - /** @type {number} extra flags. */ - this.xfl; - /** @type {number} operating system number. */ - this.os; - /** @type {number} CRC-16 value for FHCRC flag. */ - this.crc16; - /** @type {number} extra length. */ - this.xlen; - /** @type {number} CRC-32 value for verification. */ - this.crc32; - /** @type {number} input size modulo 32 value. */ - this.isize; - /** @type {string} filename. */ - this.name; - /** @type {string} comment. */ - this.comment; - /** @type {!(Uint8Array|Array.)} */ - this.data; - }; - - Zlib.GunzipMember.prototype.getName = function() { - return this.name; - }; - - Zlib.GunzipMember.prototype.getData = function() { - return this.data; - }; - - Zlib.GunzipMember.prototype.getMtime = function() { - return this.mtime; - }; - - /** - * @fileoverview GZIP (RFC1952) 実装. - */ - - /** - * @constructor - * @param {!(Array|Uint8Array)} input input buffer. - * @param {Object=} opt_params option parameters. - */ - Zlib.Gzip = function(input, opt_params) { - /** @type {!(Array.|Uint8Array)} input buffer. */ - this.input = input; - /** @type {number} input buffer pointer. */ - this.ip = 0; - /** @type {!(Array.|Uint8Array)} output buffer. */ - this.output; - /** @type {number} output buffer. */ - this.op = 0; - /** @type {!Object} flags option flags. */ - this.flags = {}; - /** @type {!string} filename. */ - this.filename; - /** @type {!string} comment. */ - this.comment; - /** @type {!Object} deflate options. */ - this.deflateOptions; - - // option parameters - if (opt_params) { - if (opt_params['flags']) { - this.flags = opt_params['flags']; - } - if (typeof opt_params['filename'] === 'string') { - this.filename = opt_params['filename']; - } - if (typeof opt_params['comment'] === 'string') { - this.comment = opt_params['comment']; - } - if (opt_params['deflateOptions']) { - this.deflateOptions = opt_params['deflateOptions']; - } - } - - if (!this.deflateOptions) { - this.deflateOptions = {}; - } - }; - - /** - * @type {number} - * @const - */ - Zlib.Gzip.DefaultBufferSize = 0x8000; - - /** - * encode gzip members. - * @return {!(Array|Uint8Array)} gzip binary array. - */ - Zlib.Gzip.prototype.compress = function() { - /** @type {number} flags. */ - var flg; - /** @type {number} modification time. */ - var mtime; - /** @type {number} CRC-16 value for FHCRC flag. */ - var crc16; - /** @type {number} CRC-32 value for verification. */ - var crc32; - /** @type {!Zlib.RawDeflate} raw deflate object. */ - var rawdeflate; - /** @type {number} character code */ - var c; - /** @type {number} loop counter. */ - var i; - /** @type {number} loop limiter. */ - var il; - /** @type {!(Array|Uint8Array)} output buffer. */ - var output = - new (Uint8Array )(Zlib.Gzip.DefaultBufferSize); - /** @type {number} output buffer pointer. */ - var op = 0; - - var input = this.input; - var ip = this.ip; - var filename = this.filename; - var comment = this.comment; - - // check signature - output[op++] = 0x1f; - output[op++] = 0x8b; - - // check compression method - output[op++] = 8; /* XXX: use Zlib const */ - - // flags - flg = 0; - if (this.flags['fname']) flg |= Zlib.Gzip.FlagsMask.FNAME; - if (this.flags['fcomment']) flg |= Zlib.Gzip.FlagsMask.FCOMMENT; - if (this.flags['fhcrc']) flg |= Zlib.Gzip.FlagsMask.FHCRC; - // XXX: FTEXT - // XXX: FEXTRA - output[op++] = flg; - - // modification time - mtime = (Date.now ? Date.now() : +new Date()) / 1000 | 0; - output[op++] = mtime & 0xff; - output[op++] = mtime >>> 8 & 0xff; - output[op++] = mtime >>> 16 & 0xff; - output[op++] = mtime >>> 24 & 0xff; - - // extra flags - output[op++] = 0; - - // operating system - output[op++] = Zlib.Gzip.OperatingSystem.UNKNOWN; - - // extra - /* NOP */ - - // fname - if (this.flags['fname'] !== void 0) { - for (i = 0, il = filename.length; i < il; ++i) { - c = filename.charCodeAt(i); - if (c > 0xff) { output[op++] = (c >>> 8) & 0xff; } - output[op++] = c & 0xff; - } - output[op++] = 0; // null termination - } - - // fcomment - if (this.flags['comment']) { - for (i = 0, il = comment.length; i < il; ++i) { - c = comment.charCodeAt(i); - if (c > 0xff) { output[op++] = (c >>> 8) & 0xff; } - output[op++] = c & 0xff; - } - output[op++] = 0; // null termination - } - - // fhcrc - if (this.flags['fhcrc']) { - crc16 = Zlib.CRC32.calc(output, 0, op) & 0xffff; - output[op++] = (crc16 ) & 0xff; - output[op++] = (crc16 >>> 8) & 0xff; - } - - // add compress option - this.deflateOptions['outputBuffer'] = output; - this.deflateOptions['outputIndex'] = op; - - // compress - rawdeflate = new Zlib.RawDeflate(input, this.deflateOptions); - output = rawdeflate.compress(); - op = rawdeflate.op; - - // expand buffer - { - if (op + 8 > output.buffer.byteLength) { - this.output = new Uint8Array(op + 8); - this.output.set(new Uint8Array(output.buffer)); - output = this.output; - } else { - output = new Uint8Array(output.buffer); - } - } - - // crc32 - crc32 = Zlib.CRC32.calc(input); - output[op++] = (crc32 ) & 0xff; - output[op++] = (crc32 >>> 8) & 0xff; - output[op++] = (crc32 >>> 16) & 0xff; - output[op++] = (crc32 >>> 24) & 0xff; - - // input size - il = input.length; - output[op++] = (il ) & 0xff; - output[op++] = (il >>> 8) & 0xff; - output[op++] = (il >>> 16) & 0xff; - output[op++] = (il >>> 24) & 0xff; - - this.ip = ip; - - if (op < output.length) { - this.output = output = output.subarray(0, op); - } - - return output; - }; - - /** @enum {number} */ - Zlib.Gzip.OperatingSystem = { - FAT: 0, - AMIGA: 1, - VMS: 2, - UNIX: 3, - VM_CMS: 4, - ATARI_TOS: 5, - HPFS: 6, - MACINTOSH: 7, - Z_SYSTEM: 8, - CP_M: 9, - TOPS_20: 10, - NTFS: 11, - QDOS: 12, - ACORN_RISCOS: 13, - UNKNOWN: 255 - }; - - /** @enum {number} */ - Zlib.Gzip.FlagsMask = { - FTEXT: 0x01, - FHCRC: 0x02, - FEXTRA: 0x04, - FNAME: 0x08, - FCOMMENT: 0x10 - }; - - - /** - * @fileoverview Heap Sort 実装. ハフマン符号化で使用する. - */ - - /** - * カスタムハフマン符号で使用するヒープ実装 - * @param {number} length ヒープサイズ. - * @constructor - */ - Zlib.Heap = function(length) { - this.buffer = new (Uint16Array )(length * 2); - this.length = 0; - }; - - /** - * 親ノードの index 取得 - * @param {number} index 子ノードの index. - * @return {number} 親ノードの index. - * - */ - Zlib.Heap.prototype.getParent = function(index) { - return ((index - 2) / 4 | 0) * 2; - }; - - /** - * 子ノードの index 取得 - * @param {number} index 親ノードの index. - * @return {number} 子ノードの index. - */ - Zlib.Heap.prototype.getChild = function(index) { - return 2 * index + 2; - }; - - /** - * Heap に値を追加する - * @param {number} index キー index. - * @param {number} value 値. - * @return {number} 現在のヒープ長. - */ - Zlib.Heap.prototype.push = function(index, value) { - var current, parent, - heap = this.buffer, - swap; - - current = this.length; - heap[this.length++] = value; - heap[this.length++] = index; - - // ルートノードにたどり着くまで入れ替えを試みる - while (current > 0) { - parent = this.getParent(current); - - // 親ノードと比較して親の方が小さければ入れ替える - if (heap[current] > heap[parent]) { - swap = heap[current]; - heap[current] = heap[parent]; - heap[parent] = swap; - - swap = heap[current + 1]; - heap[current + 1] = heap[parent + 1]; - heap[parent + 1] = swap; - - current = parent; - // 入れ替えが必要なくなったらそこで抜ける - } else { - break; - } - } - - return this.length; - }; - - /** - * Heapから一番大きい値を返す - * @return {{index: number, value: number, length: number}} {index: キーindex, - * value: 値, length: ヒープ長} の Object. - */ - Zlib.Heap.prototype.pop = function() { - var index, value, - heap = this.buffer, swap, - current, parent; - - value = heap[0]; - index = heap[1]; - - // 後ろから値を取る - this.length -= 2; - heap[0] = heap[this.length]; - heap[1] = heap[this.length + 1]; - - parent = 0; - // ルートノードから下がっていく - while (true) { - current = this.getChild(parent); - - // 範囲チェック - if (current >= this.length) { - break; - } - - // 隣のノードと比較して、隣の方が値が大きければ隣を現在ノードとして選択 - if (current + 2 < this.length && heap[current + 2] > heap[current]) { - current += 2; - } - - // 親ノードと比較して親の方が小さい場合は入れ替える - if (heap[current] > heap[parent]) { - swap = heap[parent]; - heap[parent] = heap[current]; - heap[current] = swap; - - swap = heap[parent + 1]; - heap[parent + 1] = heap[current + 1]; - heap[current + 1] = swap; - } else { - break; - } - - parent = current; - } - - return {index: index, value: value, length: this.length}; - }; - - - /* vim:set expandtab ts=2 sw=2 tw=80: */ - - /** - * @fileoverview Deflate (RFC1951) 符号化アルゴリズム実装. - */ - - - /** - * Raw Deflate 実装 - * - * @constructor - * @param {!(Array.|Uint8Array)} input 符号化する対象のバッファ. - * @param {Object=} opt_params option parameters. - * - * typed array が使用可能なとき、outputBuffer が Array は自動的に Uint8Array に - * 変換されます. - * 別のオブジェクトになるため出力バッファを参照している変数などは - * 更新する必要があります. - */ - Zlib.RawDeflate = function(input, opt_params) { - /** @type {Zlib.RawDeflate.CompressionType} */ - this.compressionType = Zlib.RawDeflate.CompressionType.DYNAMIC; - /** @type {number} */ - this.lazy = 0; - /** @type {!(Array.|Uint32Array)} */ - this.freqsLitLen; - /** @type {!(Array.|Uint32Array)} */ - this.freqsDist; - /** @type {!(Array.|Uint8Array)} */ - this.input = - (input instanceof Array) ? new Uint8Array(input) : input; - /** @type {!(Array.|Uint8Array)} output output buffer. */ - this.output; - /** @type {number} pos output buffer position. */ - this.op = 0; - - // option parameters - if (opt_params) { - if (opt_params['lazy']) { - this.lazy = opt_params['lazy']; - } - if (typeof opt_params['compressionType'] === 'number') { - this.compressionType = opt_params['compressionType']; - } - if (opt_params['outputBuffer']) { - this.output = - (opt_params['outputBuffer'] instanceof Array) ? - new Uint8Array(opt_params['outputBuffer']) : opt_params['outputBuffer']; - } - if (typeof opt_params['outputIndex'] === 'number') { - this.op = opt_params['outputIndex']; - } - } - - if (!this.output) { - this.output = new (Uint8Array )(0x8000); - } - }; - - /** - * @enum {number} - */ - Zlib.RawDeflate.CompressionType = { - NONE: 0, - FIXED: 1, - DYNAMIC: 2, - RESERVED: 3 - }; - - - /** - * LZ77 の最小マッチ長 - * @const - * @type {number} - */ - Zlib.RawDeflate.Lz77MinLength = 3; - - /** - * LZ77 の最大マッチ長 - * @const - * @type {number} - */ - Zlib.RawDeflate.Lz77MaxLength = 258; - - /** - * LZ77 のウィンドウサイズ - * @const - * @type {number} - */ - Zlib.RawDeflate.WindowSize = 0x8000; - - /** - * 最長の符号長 - * @const - * @type {number} - */ - Zlib.RawDeflate.MaxCodeLength = 16; - - /** - * ハフマン符号の最大数値 - * @const - * @type {number} - */ - Zlib.RawDeflate.HUFMAX = 286; - - /** - * 固定ハフマン符号の符号化テーブル - * @const - * @type {Array.>} - */ - Zlib.RawDeflate.FixedHuffmanTable = (function() { - var table = [], i; - - for (i = 0; i < 288; i++) { - switch (true) { - case (i <= 143): table.push([i + 0x030, 8]); break; - case (i <= 255): table.push([i - 144 + 0x190, 9]); break; - case (i <= 279): table.push([i - 256 + 0x000, 7]); break; - case (i <= 287): table.push([i - 280 + 0x0C0, 8]); break; - default: - throw 'invalid literal: ' + i; - } - } - - return table; - })(); - - /** - * DEFLATE ブロックの作成 - * @return {!(Array.|Uint8Array)} 圧縮済み byte array. - */ - Zlib.RawDeflate.prototype.compress = function() { - /** @type {!(Array.|Uint8Array)} */ - var blockArray; - /** @type {number} */ - var position; - /** @type {number} */ - var length; - - var input = this.input; - - // compression - switch (this.compressionType) { - case Zlib.RawDeflate.CompressionType.NONE: - // each 65535-Byte (length header: 16-bit) - for (position = 0, length = input.length; position < length;) { - blockArray = input.subarray(position, position + 0xffff) ; - position += blockArray.length; - this.makeNocompressBlock(blockArray, (position === length)); - } - break; - case Zlib.RawDeflate.CompressionType.FIXED: - this.output = this.makeFixedHuffmanBlock(input, true); - this.op = this.output.length; - break; - case Zlib.RawDeflate.CompressionType.DYNAMIC: - this.output = this.makeDynamicHuffmanBlock(input, true); - this.op = this.output.length; - break; - default: - throw 'invalid compression type'; - } - - return this.output; - }; - - /** - * 非圧縮ブロックの作成 - * @param {!(Array.|Uint8Array)} blockArray ブロックデータ byte array. - * @param {!boolean} isFinalBlock 最後のブロックならばtrue. - * @return {!(Array.|Uint8Array)} 非圧縮ブロック byte array. - */ - Zlib.RawDeflate.prototype.makeNocompressBlock = - function(blockArray, isFinalBlock) { - /** @type {number} */ - var bfinal; - /** @type {Zlib.RawDeflate.CompressionType} */ - var btype; - /** @type {number} */ - var len; - /** @type {number} */ - var nlen; - - var output = this.output; - var op = this.op; - - // expand buffer - { - output = new Uint8Array(this.output.buffer); - while (output.length <= op + blockArray.length + 5) { - output = new Uint8Array(output.length << 1); - } - output.set(this.output); - } - - // header - bfinal = isFinalBlock ? 1 : 0; - btype = Zlib.RawDeflate.CompressionType.NONE; - output[op++] = (bfinal) | (btype << 1); - - // length - len = blockArray.length; - nlen = (~len + 0x10000) & 0xffff; - output[op++] = len & 0xff; - output[op++] = (len >>> 8) & 0xff; - output[op++] = nlen & 0xff; - output[op++] = (nlen >>> 8) & 0xff; - - // copy buffer - { - output.set(blockArray, op); - op += blockArray.length; - output = output.subarray(0, op); - } - - this.op = op; - this.output = output; - - return output; - }; - - /** - * 固定ハフマンブロックの作成 - * @param {!(Array.|Uint8Array)} blockArray ブロックデータ byte array. - * @param {!boolean} isFinalBlock 最後のブロックならばtrue. - * @return {!(Array.|Uint8Array)} 固定ハフマン符号化ブロック byte array. - */ - Zlib.RawDeflate.prototype.makeFixedHuffmanBlock = - function(blockArray, isFinalBlock) { - /** @type {Zlib.BitStream} */ - var stream = new Zlib.BitStream(new Uint8Array(this.output.buffer) , this.op); - /** @type {number} */ - var bfinal; - /** @type {Zlib.RawDeflate.CompressionType} */ - var btype; - /** @type {!(Array.|Uint16Array)} */ - var data; - - // header - bfinal = isFinalBlock ? 1 : 0; - btype = Zlib.RawDeflate.CompressionType.FIXED; - - stream.writeBits(bfinal, 1, true); - stream.writeBits(btype, 2, true); - - data = this.lz77(blockArray); - this.fixedHuffman(data, stream); - - return stream.finish(); - }; - - /** - * 動的ハフマンブロックの作成 - * @param {!(Array.|Uint8Array)} blockArray ブロックデータ byte array. - * @param {!boolean} isFinalBlock 最後のブロックならばtrue. - * @return {!(Array.|Uint8Array)} 動的ハフマン符号ブロック byte array. - */ - Zlib.RawDeflate.prototype.makeDynamicHuffmanBlock = - function(blockArray, isFinalBlock) { - /** @type {Zlib.BitStream} */ - var stream = new Zlib.BitStream(new Uint8Array(this.output.buffer) , this.op); - /** @type {number} */ - var bfinal; - /** @type {Zlib.RawDeflate.CompressionType} */ - var btype; - /** @type {!(Array.|Uint16Array)} */ - var data; - /** @type {number} */ - var hlit; - /** @type {number} */ - var hdist; - /** @type {number} */ - var hclen; - /** @const @type {Array.} */ - var hclenOrder = - [16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15]; - /** @type {!(Array.|Uint8Array)} */ - var litLenLengths; - /** @type {!(Array.|Uint16Array)} */ - var litLenCodes; - /** @type {!(Array.|Uint8Array)} */ - var distLengths; - /** @type {!(Array.|Uint16Array)} */ - var distCodes; - /** @type {{ - * codes: !(Array.|Uint32Array), - * freqs: !(Array.|Uint8Array) - * }} */ - var treeSymbols; - /** @type {!(Array.|Uint8Array)} */ - var treeLengths; - /** @type {Array} */ - var transLengths = new Array(19); - /** @type {!(Array.|Uint16Array)} */ - var treeCodes; - /** @type {number} */ - var code; - /** @type {number} */ - var bitlen; - /** @type {number} */ - var i; - /** @type {number} */ - var il; - - // header - bfinal = isFinalBlock ? 1 : 0; - btype = Zlib.RawDeflate.CompressionType.DYNAMIC; - - stream.writeBits(bfinal, 1, true); - stream.writeBits(btype, 2, true); - - data = this.lz77(blockArray); - - // リテラル・長さ, 距離のハフマン符号と符号長の算出 - litLenLengths = this.getLengths_(this.freqsLitLen, 15); - litLenCodes = this.getCodesFromLengths_(litLenLengths); - distLengths = this.getLengths_(this.freqsDist, 7); - distCodes = this.getCodesFromLengths_(distLengths); - - // HLIT, HDIST の決定 - for (hlit = 286; hlit > 257 && litLenLengths[hlit - 1] === 0; hlit--) {} - for (hdist = 30; hdist > 1 && distLengths[hdist - 1] === 0; hdist--) {} - - // HCLEN - treeSymbols = - this.getTreeSymbols_(hlit, litLenLengths, hdist, distLengths); - treeLengths = this.getLengths_(treeSymbols.freqs, 7); - for (i = 0; i < 19; i++) { - transLengths[i] = treeLengths[hclenOrder[i]]; - } - for (hclen = 19; hclen > 4 && transLengths[hclen - 1] === 0; hclen--) {} - - treeCodes = this.getCodesFromLengths_(treeLengths); - - // 出力 - stream.writeBits(hlit - 257, 5, true); - stream.writeBits(hdist - 1, 5, true); - stream.writeBits(hclen - 4, 4, true); - for (i = 0; i < hclen; i++) { - stream.writeBits(transLengths[i], 3, true); - } - - // ツリーの出力 - for (i = 0, il = treeSymbols.codes.length; i < il; i++) { - code = treeSymbols.codes[i]; - - stream.writeBits(treeCodes[code], treeLengths[code], true); - - // extra bits - if (code >= 16) { - i++; - switch (code) { - case 16: bitlen = 2; break; - case 17: bitlen = 3; break; - case 18: bitlen = 7; break; - default: - throw 'invalid code: ' + code; - } - - stream.writeBits(treeSymbols.codes[i], bitlen, true); - } - } - - this.dynamicHuffman( - data, - [litLenCodes, litLenLengths], - [distCodes, distLengths], - stream - ); - - return stream.finish(); - }; - - - /** - * 動的ハフマン符号化(カスタムハフマンテーブル) - * @param {!(Array.|Uint16Array)} dataArray LZ77 符号化済み byte array. - * @param {!Zlib.BitStream} stream 書き込み用ビットストリーム. - * @return {!Zlib.BitStream} ハフマン符号化済みビットストリームオブジェクト. - */ - Zlib.RawDeflate.prototype.dynamicHuffman = - function(dataArray, litLen, dist, stream) { - /** @type {number} */ - var index; - /** @type {number} */ - var length; - /** @type {number} */ - var literal; - /** @type {number} */ - var code; - /** @type {number} */ - var litLenCodes; - /** @type {number} */ - var litLenLengths; - /** @type {number} */ - var distCodes; - /** @type {number} */ - var distLengths; - - litLenCodes = litLen[0]; - litLenLengths = litLen[1]; - distCodes = dist[0]; - distLengths = dist[1]; - - // 符号を BitStream に書き込んでいく - for (index = 0, length = dataArray.length; index < length; ++index) { - literal = dataArray[index]; - - // literal or length - stream.writeBits(litLenCodes[literal], litLenLengths[literal], true); - - // 長さ・距離符号 - if (literal > 256) { - // length extra - stream.writeBits(dataArray[++index], dataArray[++index], true); - // distance - code = dataArray[++index]; - stream.writeBits(distCodes[code], distLengths[code], true); - // distance extra - stream.writeBits(dataArray[++index], dataArray[++index], true); - // 終端 - } else if (literal === 256) { - break; - } - } - - return stream; - }; - - /** - * 固定ハフマン符号化 - * @param {!(Array.|Uint16Array)} dataArray LZ77 符号化済み byte array. - * @param {!Zlib.BitStream} stream 書き込み用ビットストリーム. - * @return {!Zlib.BitStream} ハフマン符号化済みビットストリームオブジェクト. - */ - Zlib.RawDeflate.prototype.fixedHuffman = function(dataArray, stream) { - /** @type {number} */ - var index; - /** @type {number} */ - var length; - /** @type {number} */ - var literal; - - // 符号を BitStream に書き込んでいく - for (index = 0, length = dataArray.length; index < length; index++) { - literal = dataArray[index]; - - // 符号の書き込み - Zlib.BitStream.prototype.writeBits.apply( - stream, - Zlib.RawDeflate.FixedHuffmanTable[literal] - ); - - // 長さ・距離符号 - if (literal > 0x100) { - // length extra - stream.writeBits(dataArray[++index], dataArray[++index], true); - // distance - stream.writeBits(dataArray[++index], 5); - // distance extra - stream.writeBits(dataArray[++index], dataArray[++index], true); - // 終端 - } else if (literal === 0x100) { - break; - } - } - - return stream; - }; - - /** - * マッチ情報 - * @param {!number} length マッチした長さ. - * @param {!number} backwardDistance マッチ位置との距離. - * @constructor - */ - Zlib.RawDeflate.Lz77Match = function(length, backwardDistance) { - /** @type {number} match length. */ - this.length = length; - /** @type {number} backward distance. */ - this.backwardDistance = backwardDistance; - }; - - /** - * 長さ符号テーブル. - * [コード, 拡張ビット, 拡張ビット長] の配列となっている. - * @const - * @type {!(Array.|Uint32Array)} - */ - Zlib.RawDeflate.Lz77Match.LengthCodeTable = (function(table) { - return new Uint32Array(table) ; - })((function() { - /** @type {!Array} */ - var table = []; - /** @type {number} */ - var i; - /** @type {!Array.} */ - var c; - - for (i = 3; i <= 258; i++) { - c = code(i); - table[i] = (c[2] << 24) | (c[1] << 16) | c[0]; - } - - /** - * @param {number} length lz77 length. - * @return {!Array.} lz77 codes. - */ - function code(length) { - switch (true) { - case (length === 3): return [257, length - 3, 0]; case (length === 4): return [258, length - 4, 0]; case (length === 5): return [259, length - 5, 0]; case (length === 6): return [260, length - 6, 0]; case (length === 7): return [261, length - 7, 0]; case (length === 8): return [262, length - 8, 0]; case (length === 9): return [263, length - 9, 0]; case (length === 10): return [264, length - 10, 0]; case (length <= 12): return [265, length - 11, 1]; case (length <= 14): return [266, length - 13, 1]; case (length <= 16): return [267, length - 15, 1]; case (length <= 18): return [268, length - 17, 1]; case (length <= 22): return [269, length - 19, 2]; case (length <= 26): return [270, length - 23, 2]; case (length <= 30): return [271, length - 27, 2]; case (length <= 34): return [272, length - 31, 2]; case (length <= 42): return [273, length - 35, 3]; case (length <= 50): return [274, length - 43, 3]; case (length <= 58): return [275, length - 51, 3]; case (length <= 66): return [276, length - 59, 3]; case (length <= 82): return [277, length - 67, 4]; case (length <= 98): return [278, length - 83, 4]; case (length <= 114): return [279, length - 99, 4]; case (length <= 130): return [280, length - 115, 4]; case (length <= 162): return [281, length - 131, 5]; case (length <= 194): return [282, length - 163, 5]; case (length <= 226): return [283, length - 195, 5]; case (length <= 257): return [284, length - 227, 5]; case (length === 258): return [285, length - 258, 0]; default: throw 'invalid length: ' + length; - } - } - - return table; - })()); - - /** - * 距離符号テーブル - * @param {!number} dist 距離. - * @return {!Array.} コード、拡張ビット、拡張ビット長の配列. - * @private - */ - Zlib.RawDeflate.Lz77Match.prototype.getDistanceCode_ = function(dist) { - /** @type {!Array.} distance code table. */ - var r; - - switch (true) { - case (dist === 1): r = [0, dist - 1, 0]; break; - case (dist === 2): r = [1, dist - 2, 0]; break; - case (dist === 3): r = [2, dist - 3, 0]; break; - case (dist === 4): r = [3, dist - 4, 0]; break; - case (dist <= 6): r = [4, dist - 5, 1]; break; - case (dist <= 8): r = [5, dist - 7, 1]; break; - case (dist <= 12): r = [6, dist - 9, 2]; break; - case (dist <= 16): r = [7, dist - 13, 2]; break; - case (dist <= 24): r = [8, dist - 17, 3]; break; - case (dist <= 32): r = [9, dist - 25, 3]; break; - case (dist <= 48): r = [10, dist - 33, 4]; break; - case (dist <= 64): r = [11, dist - 49, 4]; break; - case (dist <= 96): r = [12, dist - 65, 5]; break; - case (dist <= 128): r = [13, dist - 97, 5]; break; - case (dist <= 192): r = [14, dist - 129, 6]; break; - case (dist <= 256): r = [15, dist - 193, 6]; break; - case (dist <= 384): r = [16, dist - 257, 7]; break; - case (dist <= 512): r = [17, dist - 385, 7]; break; - case (dist <= 768): r = [18, dist - 513, 8]; break; - case (dist <= 1024): r = [19, dist - 769, 8]; break; - case (dist <= 1536): r = [20, dist - 1025, 9]; break; - case (dist <= 2048): r = [21, dist - 1537, 9]; break; - case (dist <= 3072): r = [22, dist - 2049, 10]; break; - case (dist <= 4096): r = [23, dist - 3073, 10]; break; - case (dist <= 6144): r = [24, dist - 4097, 11]; break; - case (dist <= 8192): r = [25, dist - 6145, 11]; break; - case (dist <= 12288): r = [26, dist - 8193, 12]; break; - case (dist <= 16384): r = [27, dist - 12289, 12]; break; - case (dist <= 24576): r = [28, dist - 16385, 13]; break; - case (dist <= 32768): r = [29, dist - 24577, 13]; break; - default: throw 'invalid distance'; - } - - return r; - }; - - /** - * マッチ情報を LZ77 符号化配列で返す. - * なお、ここでは以下の内部仕様で符号化している - * [ CODE, EXTRA-BIT-LEN, EXTRA, CODE, EXTRA-BIT-LEN, EXTRA ] - * @return {!Array.} LZ77 符号化 byte array. - */ - Zlib.RawDeflate.Lz77Match.prototype.toLz77Array = function() { - /** @type {number} */ - var length = this.length; - /** @type {number} */ - var dist = this.backwardDistance; - /** @type {Array} */ - var codeArray = []; - /** @type {number} */ - var pos = 0; - /** @type {!Array.} */ - var code; - - // length - code = Zlib.RawDeflate.Lz77Match.LengthCodeTable[length]; - codeArray[pos++] = code & 0xffff; - codeArray[pos++] = (code >> 16) & 0xff; - codeArray[pos++] = code >> 24; - - // distance - code = this.getDistanceCode_(dist); - codeArray[pos++] = code[0]; - codeArray[pos++] = code[1]; - codeArray[pos++] = code[2]; - - return codeArray; - }; - - /** - * LZ77 実装 - * @param {!(Array.|Uint8Array)} dataArray LZ77 符号化するバイト配列. - * @return {!(Array.|Uint16Array)} LZ77 符号化した配列. - */ - Zlib.RawDeflate.prototype.lz77 = function(dataArray) { - /** @type {number} input position */ - var position; - /** @type {number} input length */ - var length; - /** @type {number} loop counter */ - var i; - /** @type {number} loop limiter */ - var il; - /** @type {number} chained-hash-table key */ - var matchKey; - /** @type {Object.>} chained-hash-table */ - var table = {}; - /** @const @type {number} */ - var windowSize = Zlib.RawDeflate.WindowSize; - /** @type {Array.} match list */ - var matchList; - /** @type {Zlib.RawDeflate.Lz77Match} longest match */ - var longestMatch; - /** @type {Zlib.RawDeflate.Lz77Match} previous longest match */ - var prevMatch; - /** @type {!(Array.|Uint16Array)} lz77 buffer */ - var lz77buf = new Uint16Array(dataArray.length * 2) ; - /** @type {number} lz77 output buffer pointer */ - var pos = 0; - /** @type {number} lz77 skip length */ - var skipLength = 0; - /** @type {!(Array.|Uint32Array)} */ - var freqsLitLen = new (Uint32Array )(286); - /** @type {!(Array.|Uint32Array)} */ - var freqsDist = new (Uint32Array )(30); - /** @type {number} */ - var lazy = this.lazy; - /** @type {*} temporary variable */ - var tmp; - freqsLitLen[256] = 1; // EOB の最低出現回数は 1 - - /** - * マッチデータの書き込み - * @param {Zlib.RawDeflate.Lz77Match} match LZ77 Match data. - * @param {!number} offset スキップ開始位置(相対指定). - * @private - */ - function writeMatch(match, offset) { - /** @type {Array.} */ - var lz77Array = match.toLz77Array(); - /** @type {number} */ - var i; - /** @type {number} */ - var il; - - for (i = 0, il = lz77Array.length; i < il; ++i) { - lz77buf[pos++] = lz77Array[i]; - } - freqsLitLen[lz77Array[0]]++; - freqsDist[lz77Array[3]]++; - skipLength = match.length + offset - 1; - prevMatch = null; - } - - // LZ77 符号化 - for (position = 0, length = dataArray.length; position < length; ++position) { - // ハッシュキーの作成 - for (matchKey = 0, i = 0, il = Zlib.RawDeflate.Lz77MinLength; i < il; ++i) { - if (position + i === length) { - break; - } - matchKey = (matchKey << 8) | dataArray[position + i]; - } - - // テーブルが未定義だったら作成する - if (table[matchKey] === void 0) { table[matchKey] = []; } - matchList = table[matchKey]; - - // skip - if (skipLength-- > 0) { - matchList.push(position); - continue; - } - - // マッチテーブルの更新 (最大戻り距離を超えているものを削除する) - while (matchList.length > 0 && position - matchList[0] > windowSize) { - matchList.shift(); - } - - // データ末尾でマッチしようがない場合はそのまま流しこむ - if (position + Zlib.RawDeflate.Lz77MinLength >= length) { - if (prevMatch) { - writeMatch(prevMatch, -1); - } - - for (i = 0, il = length - position; i < il; ++i) { - tmp = dataArray[position + i]; - lz77buf[pos++] = tmp; - ++freqsLitLen[tmp]; - } - break; - } - - // マッチ候補から最長のものを探す - if (matchList.length > 0) { - longestMatch = this.searchLongestMatch_(dataArray, position, matchList); - - if (prevMatch) { - // 現在のマッチの方が前回のマッチよりも長い - if (prevMatch.length < longestMatch.length) { - // write previous literal - tmp = dataArray[position - 1]; - lz77buf[pos++] = tmp; - ++freqsLitLen[tmp]; - - // write current match - writeMatch(longestMatch, 0); - } else { - // write previous match - writeMatch(prevMatch, -1); - } - } else if (longestMatch.length < lazy) { - prevMatch = longestMatch; - } else { - writeMatch(longestMatch, 0); - } - // 前回マッチしていて今回マッチがなかったら前回のを採用 - } else if (prevMatch) { - writeMatch(prevMatch, -1); - } else { - tmp = dataArray[position]; - lz77buf[pos++] = tmp; - ++freqsLitLen[tmp]; - } - - matchList.push(position); // マッチテーブルに現在の位置を保存 - } - - // 終端処理 - lz77buf[pos++] = 256; - freqsLitLen[256]++; - this.freqsLitLen = freqsLitLen; - this.freqsDist = freqsDist; - - return /** @type {!(Uint16Array|Array.)} */ ( - lz77buf.subarray(0, pos) - ); - }; - - /** - * マッチした候補の中から最長一致を探す - * @param {!Object} data plain data byte array. - * @param {!number} position plain data byte array position. - * @param {!Array.} matchList 候補となる位置の配列. - * @return {!Zlib.RawDeflate.Lz77Match} 最長かつ最短距離のマッチオブジェクト. - * @private - */ - Zlib.RawDeflate.prototype.searchLongestMatch_ = - function(data, position, matchList) { - var match, - currentMatch, - matchMax = 0, matchLength, - i, j, l, dl = data.length; - - // 候補を後ろから 1 つずつ絞り込んでゆく - permatch: - for (i = 0, l = matchList.length; i < l; i++) { - match = matchList[l - i - 1]; - matchLength = Zlib.RawDeflate.Lz77MinLength; - - // 前回までの最長一致を末尾から一致検索する - if (matchMax > Zlib.RawDeflate.Lz77MinLength) { - for (j = matchMax; j > Zlib.RawDeflate.Lz77MinLength; j--) { - if (data[match + j - 1] !== data[position + j - 1]) { - continue permatch; - } - } - matchLength = matchMax; - } - - // 最長一致探索 - while (matchLength < Zlib.RawDeflate.Lz77MaxLength && - position + matchLength < dl && - data[match + matchLength] === data[position + matchLength]) { - ++matchLength; - } - - // マッチ長が同じ場合は後方を優先 - if (matchLength > matchMax) { - currentMatch = match; - matchMax = matchLength; - } - - // 最長が確定したら後の処理は省略 - if (matchLength === Zlib.RawDeflate.Lz77MaxLength) { - break; - } - } - - return new Zlib.RawDeflate.Lz77Match(matchMax, position - currentMatch); - }; - - /** - * Tree-Transmit Symbols の算出 - * reference: PuTTY Deflate implementation - * @param {number} hlit HLIT. - * @param {!(Array.|Uint8Array)} litlenLengths リテラルと長さ符号の符号長配列. - * @param {number} hdist HDIST. - * @param {!(Array.|Uint8Array)} distLengths 距離符号の符号長配列. - * @return {{ - * codes: !(Array.|Uint32Array), - * freqs: !(Array.|Uint8Array) - * }} Tree-Transmit Symbols. - */ - Zlib.RawDeflate.prototype.getTreeSymbols_ = - function(hlit, litlenLengths, hdist, distLengths) { - var src = new (Uint32Array )(hlit + hdist), - i, j, runLength, l, - result = new (Uint32Array )(286 + 30), - nResult, - rpt, - freqs = new (Uint8Array )(19); - - j = 0; - for (i = 0; i < hlit; i++) { - src[j++] = litlenLengths[i]; - } - for (i = 0; i < hdist; i++) { - src[j++] = distLengths[i]; - } - - // 符号化 - nResult = 0; - for (i = 0, l = src.length; i < l; i += j) { - // Run Length Encoding - for (j = 1; i + j < l && src[i + j] === src[i]; ++j) {} - - runLength = j; - - if (src[i] === 0) { - // 0 の繰り返しが 3 回未満ならばそのまま - if (runLength < 3) { - while (runLength-- > 0) { - result[nResult++] = 0; - freqs[0]++; - } - } else { - while (runLength > 0) { - // 繰り返しは最大 138 までなので切り詰める - rpt = (runLength < 138 ? runLength : 138); - - if (rpt > runLength - 3 && rpt < runLength) { - rpt = runLength - 3; - } - - // 3-10 回 -> 17 - if (rpt <= 10) { - result[nResult++] = 17; - result[nResult++] = rpt - 3; - freqs[17]++; - // 11-138 回 -> 18 - } else { - result[nResult++] = 18; - result[nResult++] = rpt - 11; - freqs[18]++; - } - - runLength -= rpt; - } - } - } else { - result[nResult++] = src[i]; - freqs[src[i]]++; - runLength--; - - // 繰り返し回数が3回未満ならばランレングス符号は要らない - if (runLength < 3) { - while (runLength-- > 0) { - result[nResult++] = src[i]; - freqs[src[i]]++; - } - // 3 回以上ならばランレングス符号化 - } else { - while (runLength > 0) { - // runLengthを 3-6 で分割 - rpt = (runLength < 6 ? runLength : 6); - - if (rpt > runLength - 3 && rpt < runLength) { - rpt = runLength - 3; - } - - result[nResult++] = 16; - result[nResult++] = rpt - 3; - freqs[16]++; - - runLength -= rpt; - } - } - } - } - - return { - codes: - result.subarray(0, nResult) , - freqs: freqs - }; - }; - - /** - * ハフマン符号の長さを取得する - * @param {!(Array.|Uint8Array|Uint32Array)} freqs 出現カウント. - * @param {number} limit 符号長の制限. - * @return {!(Array.|Uint8Array)} 符号長配列. - * @private - */ - Zlib.RawDeflate.prototype.getLengths_ = function(freqs, limit) { - /** @type {number} */ - var nSymbols = freqs.length; - /** @type {Zlib.Heap} */ - var heap = new Zlib.Heap(2 * Zlib.RawDeflate.HUFMAX); - /** @type {!(Array.|Uint8Array)} */ - var length = new (Uint8Array )(nSymbols); - /** @type {Array} */ - var nodes; - /** @type {!(Array.|Uint32Array)} */ - var values; - /** @type {!(Array.|Uint8Array)} */ - var codeLength; - /** @type {number} */ - var i; - /** @type {number} */ - var il; - - // ヒープの構築 - for (i = 0; i < nSymbols; ++i) { - if (freqs[i] > 0) { - heap.push(i, freqs[i]); - } - } - nodes = new Array(heap.length / 2); - values = new (Uint32Array )(heap.length / 2); - - // 非 0 の要素が一つだけだった場合は、そのシンボルに符号長 1 を割り当てて終了 - if (nodes.length === 1) { - length[heap.pop().index] = 1; - return length; - } - - // Reverse Package Merge Algorithm による Canonical Huffman Code の符号長決定 - for (i = 0, il = heap.length / 2; i < il; ++i) { - nodes[i] = heap.pop(); - values[i] = nodes[i].value; - } - codeLength = this.reversePackageMerge_(values, values.length, limit); - - for (i = 0, il = nodes.length; i < il; ++i) { - length[nodes[i].index] = codeLength[i]; - } - - return length; - }; - - /** - * Reverse Package Merge Algorithm. - * @param {!(Array.|Uint32Array)} freqs sorted probability. - * @param {number} symbols number of symbols. - * @param {number} limit code length limit. - * @return {!(Array.|Uint8Array)} code lengths. - */ - Zlib.RawDeflate.prototype.reversePackageMerge_ = function(freqs, symbols, limit) { - /** @type {!(Array.|Uint16Array)} */ - var minimumCost = new (Uint16Array )(limit); - /** @type {!(Array.|Uint8Array)} */ - var flag = new (Uint8Array )(limit); - /** @type {!(Array.|Uint8Array)} */ - var codeLength = new (Uint8Array )(symbols); - /** @type {Array} */ - var value = new Array(limit); - /** @type {Array} */ - var type = new Array(limit); - /** @type {Array.} */ - var currentPosition = new Array(limit); - /** @type {number} */ - var excess = (1 << limit) - symbols; - /** @type {number} */ - var half = (1 << (limit - 1)); - /** @type {number} */ - var i; - /** @type {number} */ - var j; - /** @type {number} */ - var t; - /** @type {number} */ - var weight; - /** @type {number} */ - var next; - - /** - * @param {number} j - */ - function takePackage(j) { - /** @type {number} */ - var x = type[j][currentPosition[j]]; - - if (x === symbols) { - takePackage(j+1); - takePackage(j+1); - } else { - --codeLength[x]; - } - - ++currentPosition[j]; - } - - minimumCost[limit-1] = symbols; - - for (j = 0; j < limit; ++j) { - if (excess < half) { - flag[j] = 0; - } else { - flag[j] = 1; - excess -= half; - } - excess <<= 1; - minimumCost[limit-2-j] = (minimumCost[limit-1-j] / 2 | 0) + symbols; - } - minimumCost[0] = flag[0]; - - value[0] = new Array(minimumCost[0]); - type[0] = new Array(minimumCost[0]); - for (j = 1; j < limit; ++j) { - if (minimumCost[j] > 2 * minimumCost[j-1] + flag[j]) { - minimumCost[j] = 2 * minimumCost[j-1] + flag[j]; - } - value[j] = new Array(minimumCost[j]); - type[j] = new Array(minimumCost[j]); - } - - for (i = 0; i < symbols; ++i) { - codeLength[i] = limit; - } - - for (t = 0; t < minimumCost[limit-1]; ++t) { - value[limit-1][t] = freqs[t]; - type[limit-1][t] = t; - } - - for (i = 0; i < limit; ++i) { - currentPosition[i] = 0; - } - if (flag[limit-1] === 1) { - --codeLength[0]; - ++currentPosition[limit-1]; - } - - for (j = limit-2; j >= 0; --j) { - i = 0; - weight = 0; - next = currentPosition[j+1]; - - for (t = 0; t < minimumCost[j]; t++) { - weight = value[j+1][next] + value[j+1][next+1]; - - if (weight > freqs[i]) { - value[j][t] = weight; - type[j][t] = symbols; - next += 2; - } else { - value[j][t] = freqs[i]; - type[j][t] = i; - ++i; - } - } - - currentPosition[j] = 0; - if (flag[j] === 1) { - takePackage(j); - } - } - - return codeLength; - }; - - /** - * 符号長配列からハフマン符号を取得する - * reference: PuTTY Deflate implementation - * @param {!(Array.|Uint8Array)} lengths 符号長配列. - * @return {!(Array.|Uint16Array)} ハフマン符号配列. - * @private - */ - Zlib.RawDeflate.prototype.getCodesFromLengths_ = function(lengths) { - var codes = new (Uint16Array )(lengths.length), - count = [], - startCode = [], - code = 0, i, il, j, m; - - // Count the codes of each length. - for (i = 0, il = lengths.length; i < il; i++) { - count[lengths[i]] = (count[lengths[i]] | 0) + 1; - } - - // Determine the starting code for each length block. - for (i = 1, il = Zlib.RawDeflate.MaxCodeLength; i <= il; i++) { - startCode[i] = code; - code += count[i] | 0; - code <<= 1; - } - - // Determine the code for each symbol. Mirrored, of course. - for (i = 0, il = lengths.length; i < il; i++) { - code = startCode[lengths[i]]; - startCode[lengths[i]] += 1; - codes[i] = 0; - - for (j = 0, m = lengths[i]; j < m; j++) { - codes[i] = (codes[i] << 1) | (code & 1); - code >>>= 1; - } - } - - return codes; - }; - - - /** - * @param {!(Array.|Uint8Array)} input input buffer. - * @param {Object=} opt_params options. - * @constructor - */ - Zlib.Unzip = function(input, opt_params) { - opt_params = opt_params || {}; - /** @type {!(Array.|Uint8Array)} */ - this.input = - ((input instanceof Array)) ? - new Uint8Array(input) : input; - /** @type {number} */ - this.ip = 0; - /** @type {number} */ - this.eocdrOffset; - /** @type {number} */ - this.numberOfThisDisk; - /** @type {number} */ - this.startDisk; - /** @type {number} */ - this.totalEntriesThisDisk; - /** @type {number} */ - this.totalEntries; - /** @type {number} */ - this.centralDirectorySize; - /** @type {number} */ - this.centralDirectoryOffset; - /** @type {number} */ - this.commentLength; - /** @type {(Array.|Uint8Array)} */ - this.comment; - /** @type {Array.} */ - this.fileHeaderList; - /** @type {Object.} */ - this.filenameToIndex; - /** @type {boolean} */ - this.verify = opt_params['verify'] || false; - /** @type {(Array.|Uint8Array)} */ - this.password = opt_params['password']; - }; - - Zlib.Unzip.CompressionMethod = Zlib.Zip.CompressionMethod; - - /** - * @type {Array.} - * @const - */ - Zlib.Unzip.FileHeaderSignature = Zlib.Zip.FileHeaderSignature; - - /** - * @type {Array.} - * @const - */ - Zlib.Unzip.LocalFileHeaderSignature = Zlib.Zip.LocalFileHeaderSignature; - - /** - * @type {Array.} - * @const - */ - Zlib.Unzip.CentralDirectorySignature = Zlib.Zip.CentralDirectorySignature; - - /** - * @param {!(Array.|Uint8Array)} input input buffer. - * @param {number} ip input position. - * @constructor - */ - Zlib.Unzip.FileHeader = function(input, ip) { - /** @type {!(Array.|Uint8Array)} */ - this.input = input; - /** @type {number} */ - this.offset = ip; - /** @type {number} */ - this.length; - /** @type {number} */ - this.version; - /** @type {number} */ - this.os; - /** @type {number} */ - this.needVersion; - /** @type {number} */ - this.flags; - /** @type {number} */ - this.compression; - /** @type {number} */ - this.time; - /** @type {number} */ - this.date; - /** @type {number} */ - this.crc32; - /** @type {number} */ - this.compressedSize; - /** @type {number} */ - this.plainSize; - /** @type {number} */ - this.fileNameLength; - /** @type {number} */ - this.extraFieldLength; - /** @type {number} */ - this.fileCommentLength; - /** @type {number} */ - this.diskNumberStart; - /** @type {number} */ - this.internalFileAttributes; - /** @type {number} */ - this.externalFileAttributes; - /** @type {number} */ - this.relativeOffset; - /** @type {string} */ - this.filename; - /** @type {!(Array.|Uint8Array)} */ - this.extraField; - /** @type {!(Array.|Uint8Array)} */ - this.comment; - }; - - Zlib.Unzip.FileHeader.prototype.parse = function() { - /** @type {!(Array.|Uint8Array)} */ - var input = this.input; - /** @type {number} */ - var ip = this.offset; - - // central file header signature - if (input[ip++] !== Zlib.Unzip.FileHeaderSignature[0] || - input[ip++] !== Zlib.Unzip.FileHeaderSignature[1] || - input[ip++] !== Zlib.Unzip.FileHeaderSignature[2] || - input[ip++] !== Zlib.Unzip.FileHeaderSignature[3]) { - throw new Error('invalid file header signature'); - } - - // version made by - this.version = input[ip++]; - this.os = input[ip++]; - - // version needed to extract - this.needVersion = input[ip++] | (input[ip++] << 8); - - // general purpose bit flag - this.flags = input[ip++] | (input[ip++] << 8); - - // compression method - this.compression = input[ip++] | (input[ip++] << 8); - - // last mod file time - this.time = input[ip++] | (input[ip++] << 8); - - //last mod file date - this.date = input[ip++] | (input[ip++] << 8); - - // crc-32 - this.crc32 = ( - (input[ip++] ) | (input[ip++] << 8) | - (input[ip++] << 16) | (input[ip++] << 24) - ) >>> 0; - - // compressed size - this.compressedSize = ( - (input[ip++] ) | (input[ip++] << 8) | - (input[ip++] << 16) | (input[ip++] << 24) - ) >>> 0; - - // uncompressed size - this.plainSize = ( - (input[ip++] ) | (input[ip++] << 8) | - (input[ip++] << 16) | (input[ip++] << 24) - ) >>> 0; - - // file name length - this.fileNameLength = input[ip++] | (input[ip++] << 8); - - // extra field length - this.extraFieldLength = input[ip++] | (input[ip++] << 8); - - // file comment length - this.fileCommentLength = input[ip++] | (input[ip++] << 8); - - // disk number start - this.diskNumberStart = input[ip++] | (input[ip++] << 8); - - // internal file attributes - this.internalFileAttributes = input[ip++] | (input[ip++] << 8); - - // external file attributes - this.externalFileAttributes = - (input[ip++] ) | (input[ip++] << 8) | - (input[ip++] << 16) | (input[ip++] << 24); - - // relative offset of local header - this.relativeOffset = ( - (input[ip++] ) | (input[ip++] << 8) | - (input[ip++] << 16) | (input[ip++] << 24) - ) >>> 0; - - // file name - this.filename = String.fromCharCode.apply(null, input.subarray(ip, ip += this.fileNameLength) - ); - - // extra field - this.extraField = input.subarray(ip, ip += this.extraFieldLength) ; - - // file comment - this.comment = input.subarray(ip, ip + this.fileCommentLength) ; - - this.length = ip - this.offset; - }; - - /** - * @param {!(Array.|Uint8Array)} input input buffer. - * @param {number} ip input position. - * @constructor - */ - Zlib.Unzip.LocalFileHeader = function(input, ip) { - /** @type {!(Array.|Uint8Array)} */ - this.input = input; - /** @type {number} */ - this.offset = ip; - /** @type {number} */ - this.length; - /** @type {number} */ - this.needVersion; - /** @type {number} */ - this.flags; - /** @type {number} */ - this.compression; - /** @type {number} */ - this.time; - /** @type {number} */ - this.date; - /** @type {number} */ - this.crc32; - /** @type {number} */ - this.compressedSize; - /** @type {number} */ - this.plainSize; - /** @type {number} */ - this.fileNameLength; - /** @type {number} */ - this.extraFieldLength; - /** @type {string} */ - this.filename; - /** @type {!(Array.|Uint8Array)} */ - this.extraField; - }; - - Zlib.Unzip.LocalFileHeader.Flags = Zlib.Zip.Flags; - - Zlib.Unzip.LocalFileHeader.prototype.parse = function() { - /** @type {!(Array.|Uint8Array)} */ - var input = this.input; - /** @type {number} */ - var ip = this.offset; - - // local file header signature - if (input[ip++] !== Zlib.Unzip.LocalFileHeaderSignature[0] || - input[ip++] !== Zlib.Unzip.LocalFileHeaderSignature[1] || - input[ip++] !== Zlib.Unzip.LocalFileHeaderSignature[2] || - input[ip++] !== Zlib.Unzip.LocalFileHeaderSignature[3]) { - throw new Error('invalid local file header signature'); - } - - // version needed to extract - this.needVersion = input[ip++] | (input[ip++] << 8); - - // general purpose bit flag - this.flags = input[ip++] | (input[ip++] << 8); - - // compression method - this.compression = input[ip++] | (input[ip++] << 8); - - // last mod file time - this.time = input[ip++] | (input[ip++] << 8); - - //last mod file date - this.date = input[ip++] | (input[ip++] << 8); - - // crc-32 - this.crc32 = ( - (input[ip++] ) | (input[ip++] << 8) | - (input[ip++] << 16) | (input[ip++] << 24) - ) >>> 0; - - // compressed size - this.compressedSize = ( - (input[ip++] ) | (input[ip++] << 8) | - (input[ip++] << 16) | (input[ip++] << 24) - ) >>> 0; - - // uncompressed size - this.plainSize = ( - (input[ip++] ) | (input[ip++] << 8) | - (input[ip++] << 16) | (input[ip++] << 24) - ) >>> 0; - - // file name length - this.fileNameLength = input[ip++] | (input[ip++] << 8); - - // extra field length - this.extraFieldLength = input[ip++] | (input[ip++] << 8); - - // file name - this.filename = String.fromCharCode.apply(null, input.subarray(ip, ip += this.fileNameLength) - ); - - // extra field - this.extraField = input.subarray(ip, ip += this.extraFieldLength) ; - - this.length = ip - this.offset; - }; - - - Zlib.Unzip.prototype.searchEndOfCentralDirectoryRecord = function() { - /** @type {!(Array.|Uint8Array)} */ - var input = this.input; - /** @type {number} */ - var ip; - - for (ip = input.length - 12; ip > 0; --ip) { - if (input[ip ] === Zlib.Unzip.CentralDirectorySignature[0] && - input[ip+1] === Zlib.Unzip.CentralDirectorySignature[1] && - input[ip+2] === Zlib.Unzip.CentralDirectorySignature[2] && - input[ip+3] === Zlib.Unzip.CentralDirectorySignature[3]) { - this.eocdrOffset = ip; - return; - } - } - - throw new Error('End of Central Directory Record not found'); - }; - - Zlib.Unzip.prototype.parseEndOfCentralDirectoryRecord = function() { - /** @type {!(Array.|Uint8Array)} */ - var input = this.input; - /** @type {number} */ - var ip; - - if (!this.eocdrOffset) { - this.searchEndOfCentralDirectoryRecord(); - } - ip = this.eocdrOffset; - - // signature - if (input[ip++] !== Zlib.Unzip.CentralDirectorySignature[0] || - input[ip++] !== Zlib.Unzip.CentralDirectorySignature[1] || - input[ip++] !== Zlib.Unzip.CentralDirectorySignature[2] || - input[ip++] !== Zlib.Unzip.CentralDirectorySignature[3]) { - throw new Error('invalid signature'); - } - - // number of this disk - this.numberOfThisDisk = input[ip++] | (input[ip++] << 8); - - // number of the disk with the start of the central directory - this.startDisk = input[ip++] | (input[ip++] << 8); - - // total number of entries in the central directory on this disk - this.totalEntriesThisDisk = input[ip++] | (input[ip++] << 8); - - // total number of entries in the central directory - this.totalEntries = input[ip++] | (input[ip++] << 8); - - // size of the central directory - this.centralDirectorySize = ( - (input[ip++] ) | (input[ip++] << 8) | - (input[ip++] << 16) | (input[ip++] << 24) - ) >>> 0; - - // offset of start of central directory with respect to the starting disk number - this.centralDirectoryOffset = ( - (input[ip++] ) | (input[ip++] << 8) | - (input[ip++] << 16) | (input[ip++] << 24) - ) >>> 0; - - // .ZIP file comment length - this.commentLength = input[ip++] | (input[ip++] << 8); - - // .ZIP file comment - this.comment = input.subarray(ip, ip + this.commentLength) ; - }; - - Zlib.Unzip.prototype.parseFileHeader = function() { - /** @type {Array.} */ - var filelist = []; - /** @type {Object.} */ - var filetable = {}; - /** @type {number} */ - var ip; - /** @type {Zlib.Unzip.FileHeader} */ - var fileHeader; - /*: @type {number} */ - var i; - /*: @type {number} */ - var il; - - if (this.fileHeaderList) { - return; - } - - if (this.centralDirectoryOffset === void 0) { - this.parseEndOfCentralDirectoryRecord(); - } - ip = this.centralDirectoryOffset; - - for (i = 0, il = this.totalEntries; i < il; ++i) { - fileHeader = new Zlib.Unzip.FileHeader(this.input, ip); - fileHeader.parse(); - ip += fileHeader.length; - filelist[i] = fileHeader; - filetable[fileHeader.filename] = i; - } - - if (this.centralDirectorySize < ip - this.centralDirectoryOffset) { - throw new Error('invalid file header size'); - } - - this.fileHeaderList = filelist; - this.filenameToIndex = filetable; - }; - - /** - * @param {number} index file header index. - * @param {Object=} opt_params - * @return {!(Array.|Uint8Array)} file data. - */ - Zlib.Unzip.prototype.getFileData = function(index, opt_params) { - opt_params = opt_params || {}; - /** @type {!(Array.|Uint8Array)} */ - var input = this.input; - /** @type {Array.} */ - var fileHeaderList = this.fileHeaderList; - /** @type {Zlib.Unzip.LocalFileHeader} */ - var localFileHeader; - /** @type {number} */ - var offset; - /** @type {number} */ - var length; - /** @type {!(Array.|Uint8Array)} */ - var buffer; - /** @type {number} */ - var crc32; - /** @type {Array.|Uint32Array|Object} */ - var key; - /** @type {number} */ - var i; - /** @type {number} */ - var il; - - if (!fileHeaderList) { - this.parseFileHeader(); - } - - if (fileHeaderList[index] === void 0) { - throw new Error('wrong index'); - } - - offset = fileHeaderList[index].relativeOffset; - localFileHeader = new Zlib.Unzip.LocalFileHeader(this.input, offset); - localFileHeader.parse(); - offset += localFileHeader.length; - length = localFileHeader.compressedSize; - - // decryption - if ((localFileHeader.flags & Zlib.Unzip.LocalFileHeader.Flags.ENCRYPT) !== 0) { - if (!(opt_params['password'] || this.password)) { - throw new Error('please set password'); - } - key = this.createDecryptionKey(opt_params['password'] || this.password); - - // encryption header - for(i = offset, il = offset + 12; i < il; ++i) { - this.decode(key, input[i]); - } - offset += 12; - length -= 12; - - // decryption - for (i = offset, il = offset + length; i < il; ++i) { - input[i] = this.decode(key, input[i]); - } - } - - switch (localFileHeader.compression) { - case Zlib.Unzip.CompressionMethod.STORE: - buffer = this.input.subarray(offset, offset + length) ; - break; - case Zlib.Unzip.CompressionMethod.DEFLATE: - buffer = new Zlib.RawInflate(this.input, { - 'index': offset, - 'bufferSize': localFileHeader.plainSize - }).decompress(); - break; - default: - throw new Error('unknown compression type'); - } - - if (this.verify) { - crc32 = Zlib.CRC32.calc(buffer); - if (localFileHeader.crc32 !== crc32) { - throw new Error( - 'wrong crc: file=0x' + localFileHeader.crc32.toString(16) + - ', data=0x' + crc32.toString(16) - ); - } - } - - return buffer; - }; - - /** - * @return {Array.} - */ - Zlib.Unzip.prototype.getFilenames = function() { - /** @type {Array.} */ - var filenameList = []; - /** @type {number} */ - var i; - /** @type {number} */ - var il; - /** @type {Array.} */ - var fileHeaderList; - - if (!this.fileHeaderList) { - this.parseFileHeader(); - } - fileHeaderList = this.fileHeaderList; - - for (i = 0, il = fileHeaderList.length; i < il; ++i) { - filenameList[i] = fileHeaderList[i].filename; - } - - return filenameList; - }; - - /** - * @param {string} filename extract filename. - * @param {Object=} opt_params - * @return {!(Array.|Uint8Array)} decompressed data. - */ - Zlib.Unzip.prototype.decompress = function(filename, opt_params) { - /** @type {number} */ - var index; - - if (!this.filenameToIndex) { - this.parseFileHeader(); - } - index = this.filenameToIndex[filename]; - - if (index === void 0) { - throw new Error(filename + ' not found'); - } - - return this.getFileData(index, opt_params); - }; - - /** - * @param {(Array.|Uint8Array)} password - */ - Zlib.Unzip.prototype.setPassword = function(password) { - this.password = password; - }; - - /** - * @param {(Array.|Uint32Array|Object)} key - * @param {number} n - * @return {number} - */ - Zlib.Unzip.prototype.decode = function(key, n) { - n ^= this.getByte(/** @type {(Array.|Uint32Array)} */(key)); - this.updateKeys(/** @type {(Array.|Uint32Array)} */(key), n); - - return n; - }; - - // common method - Zlib.Unzip.prototype.updateKeys = Zlib.Zip.prototype.updateKeys; - Zlib.Unzip.prototype.createDecryptionKey = Zlib.Zip.prototype.createEncryptionKey; - Zlib.Unzip.prototype.getByte = Zlib.Zip.prototype.getByte; - - /** - * @fileoverview 雑多な関数群をまとめたモジュール実装. - */ - - - /** - * Byte String から Byte Array に変換. - * @param {!string} str byte string. - * @return {!Array.} byte array. - */ - Zlib.Util.stringToByteArray = function(str) { - /** @type {!Array.<(string|number)>} */ - var tmp = str.split(''); - /** @type {number} */ - var i; - /** @type {number} */ - var il; - - for (i = 0, il = tmp.length; i < il; i++) { - tmp[i] = (tmp[i].charCodeAt(0) & 0xff) >>> 0; - } - - return tmp; - }; - - - /** - * @fileoverview Adler32 checksum 実装. - */ - - - /** - * Adler32 ハッシュ値の作成 - * @param {!(Array|Uint8Array|string)} array 算出に使用する byte array. - * @return {number} Adler32 ハッシュ値. - */ - Zlib.Adler32 = function(array) { - if (typeof(array) === 'string') { - array = Zlib.Util.stringToByteArray(array); - } - return Zlib.Adler32.update(1, array); - }; - - /** - * Adler32 ハッシュ値の更新 - * @param {number} adler 現在のハッシュ値. - * @param {!(Array|Uint8Array)} array 更新に使用する byte array. - * @return {number} Adler32 ハッシュ値. - */ - Zlib.Adler32.update = function(adler, array) { - /** @type {number} */ - var s1 = adler & 0xffff; - /** @type {number} */ - var s2 = (adler >>> 16) & 0xffff; - /** @type {number} array length */ - var len = array.length; - /** @type {number} loop length (don't overflow) */ - var tlen; - /** @type {number} array index */ - var i = 0; - - while (len > 0) { - tlen = len > Zlib.Adler32.OptimizationParameter ? - Zlib.Adler32.OptimizationParameter : len; - len -= tlen; - do { - s1 += array[i++]; - s2 += s1; - } while (--tlen); - - s1 %= 65521; - s2 %= 65521; - } - - return ((s2 << 16) | s1) >>> 0; - }; - - /** - * Adler32 最適化パラメータ - * 現状では 1024 程度が最適. - * @see http://jsperf.com/adler-32-simple-vs-optimized/3 - * @define {number} - */ - Zlib.Adler32.OptimizationParameter = 1024; - - - - - /** - * ビットストリーム - * @constructor - * @param {!(Array|Uint8Array)=} buffer output buffer. - * @param {number=} bufferPosition start buffer pointer. - */ - Zlib.BitStream = function(buffer, bufferPosition) { - /** @type {number} buffer index. */ - this.index = typeof bufferPosition === 'number' ? bufferPosition : 0; - /** @type {number} bit index. */ - this.bitindex = 0; - /** @type {!(Array|Uint8Array)} bit-stream output buffer. */ - this.buffer = buffer instanceof (Uint8Array ) ? - buffer : - new (Uint8Array )(Zlib.BitStream.DefaultBlockSize); - - // 入力された index が足りなかったら拡張するが、倍にしてもダメなら不正とする - if (this.buffer.length * 2 <= this.index) { - throw new Error("invalid index"); - } else if (this.buffer.length <= this.index) { - this.expandBuffer(); - } - }; - - /** - * デフォルトブロックサイズ. - * @const - * @type {number} - */ - Zlib.BitStream.DefaultBlockSize = 0x8000; - - /** - * expand buffer. - * @return {!(Array|Uint8Array)} new buffer. - */ - Zlib.BitStream.prototype.expandBuffer = function() { - /** @type {!(Array|Uint8Array)} old buffer. */ - var oldbuf = this.buffer; - /** @type {number} loop limiter. */ - var il = oldbuf.length; - /** @type {!(Array|Uint8Array)} new buffer. */ - var buffer = - new (Uint8Array )(il << 1); - - // copy buffer - { - buffer.set(oldbuf); - } - - return (this.buffer = buffer); - }; - - - /** - * 数値をビットで指定した数だけ書き込む. - * @param {number} number 書き込む数値. - * @param {number} n 書き込むビット数. - * @param {boolean=} reverse 逆順に書き込むならば true. - */ - Zlib.BitStream.prototype.writeBits = function(number, n, reverse) { - var buffer = this.buffer; - var index = this.index; - var bitindex = this.bitindex; - - /** @type {number} current octet. */ - var current = buffer[index]; - /** @type {number} loop counter. */ - var i; - - /** - * 32-bit 整数のビット順を逆にする - * @param {number} n 32-bit integer. - * @return {number} reversed 32-bit integer. - * @private - */ - function rev32_(n) { - return (Zlib.BitStream.ReverseTable[n & 0xFF] << 24) | - (Zlib.BitStream.ReverseTable[n >>> 8 & 0xFF] << 16) | - (Zlib.BitStream.ReverseTable[n >>> 16 & 0xFF] << 8) | - Zlib.BitStream.ReverseTable[n >>> 24 & 0xFF]; - } - - if (reverse && n > 1) { - number = n > 8 ? - rev32_(number) >> (32 - n) : - Zlib.BitStream.ReverseTable[number] >> (8 - n); - } - - // Byte 境界を超えないとき - if (n + bitindex < 8) { - current = (current << n) | number; - bitindex += n; - // Byte 境界を超えるとき - } else { - for (i = 0; i < n; ++i) { - current = (current << 1) | ((number >> n - i - 1) & 1); - - // next byte - if (++bitindex === 8) { - bitindex = 0; - buffer[index++] = Zlib.BitStream.ReverseTable[current]; - current = 0; - - // expand - if (index === buffer.length) { - buffer = this.expandBuffer(); - } - } - } - } - buffer[index] = current; - - this.buffer = buffer; - this.bitindex = bitindex; - this.index = index; - }; - - - /** - * ストリームの終端処理を行う - * @return {!(Array|Uint8Array)} 終端処理後のバッファを byte array で返す. - */ - Zlib.BitStream.prototype.finish = function() { - var buffer = this.buffer; - var index = this.index; - - /** @type {!(Array|Uint8Array)} output buffer. */ - var output; - - // bitindex が 0 の時は余分に index が進んでいる状態 - if (this.bitindex > 0) { - buffer[index] <<= 8 - this.bitindex; - buffer[index] = Zlib.BitStream.ReverseTable[buffer[index]]; - index++; - } - - // array truncation - { - output = buffer.subarray(0, index); - } - - return output; - }; - - /** - * 0-255 のビット順を反転したテーブル - * @const - * @type {!(Uint8Array|Array.)} - */ - Zlib.BitStream.ReverseTable = (function(table) { - return table; - })((function() { - /** @type {!(Array|Uint8Array)} reverse table. */ - var table = new (Uint8Array )(256); - /** @type {number} loop counter. */ - var i; - - // generate - for (i = 0; i < 256; ++i) { - table[i] = (function(n) { - var r = n; - var s = 7; - - for (n >>>= 1; n; n >>>= 1) { - r <<= 1; - r |= n & 1; - --s; - } - - return (r << s & 0xff) >>> 0; - })(i); - } - - return table; - })()); - - /** - * CRC32 ハッシュ値を取得 - * @param {!(Array.|Uint8Array)} data data byte array. - * @param {number=} pos data position. - * @param {number=} length data length. - * @return {number} CRC32. - */ - Zlib.CRC32.calc = function(data, pos, length) { - return Zlib.CRC32.update(data, 0, pos, length); - }; - - /** - * CRC32ハッシュ値を更新 - * @param {!(Array.|Uint8Array)} data data byte array. - * @param {number} crc CRC32. - * @param {number=} pos data position. - * @param {number=} length data length. - * @return {number} CRC32. - */ - Zlib.CRC32.update = function(data, crc, pos, length) { - var table = Zlib.CRC32.Table; - var i = (typeof pos === 'number') ? pos : (pos = 0); - var il = (typeof length === 'number') ? length : data.length; - - crc ^= 0xffffffff; - - // loop unrolling for performance - for (i = il & 7; i--; ++pos) { - crc = (crc >>> 8) ^ table[(crc ^ data[pos]) & 0xff]; - } - for (i = il >> 3; i--; pos += 8) { - crc = (crc >>> 8) ^ table[(crc ^ data[pos ]) & 0xff]; - crc = (crc >>> 8) ^ table[(crc ^ data[pos + 1]) & 0xff]; - crc = (crc >>> 8) ^ table[(crc ^ data[pos + 2]) & 0xff]; - crc = (crc >>> 8) ^ table[(crc ^ data[pos + 3]) & 0xff]; - crc = (crc >>> 8) ^ table[(crc ^ data[pos + 4]) & 0xff]; - crc = (crc >>> 8) ^ table[(crc ^ data[pos + 5]) & 0xff]; - crc = (crc >>> 8) ^ table[(crc ^ data[pos + 6]) & 0xff]; - crc = (crc >>> 8) ^ table[(crc ^ data[pos + 7]) & 0xff]; - } - - return (crc ^ 0xffffffff) >>> 0; - }; - - /** - * @param {number} num - * @param {number} crc - * @returns {number} - */ - Zlib.CRC32.single = function(num, crc) { - return (Zlib.CRC32.Table[(num ^ crc) & 0xff] ^ (num >>> 8)) >>> 0; - }; - - /** - * @type {Array.} - * @const - * @private - */ - Zlib.CRC32.Table_ = [ - 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, - 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, - 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2, - 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, - 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, - 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, - 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c, - 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, - 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, - 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, - 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106, - 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, - 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, - 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, - 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, - 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, - 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, - 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, - 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, - 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, - 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, - 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, - 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84, - 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, - 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, - 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, - 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e, - 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, - 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, - 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, - 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, - 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, - 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, - 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, - 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, - 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, - 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, - 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, - 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, - 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, - 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, - 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, - 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d - ]; - - /** - * @type {!(Array.|Uint32Array)} CRC-32 Table. - * @const - */ - Zlib.CRC32.Table = new Uint32Array(Zlib.CRC32.Table_) ; - - /** - * @fileoverview Deflate (RFC1951) 実装. - * Deflateアルゴリズム本体は Zlib.RawDeflate で実装されている. - */ - - /** - * Zlib Deflate - * @constructor - * @param {!(Array|Uint8Array)} input 符号化する対象の byte array. - * @param {Object=} opt_params option parameters. - */ - Zlib.Deflate = function(input, opt_params) { - /** @type {!(Array|Uint8Array)} */ - this.input = input; - /** @type {!(Array|Uint8Array)} */ - this.output = - new (Uint8Array )(Zlib.Deflate.DefaultBufferSize); - /** @type {Zlib.Deflate.CompressionType} */ - this.compressionType = Zlib.Deflate.CompressionType.DYNAMIC; - /** @type {Zlib.RawDeflate} */ - this.rawDeflate; - /** @type {Object} */ - var rawDeflateOption = {}; - /** @type {string} */ - var prop; - - // option parameters - if (opt_params || !(opt_params = {})) { - if (typeof opt_params['compressionType'] === 'number') { - this.compressionType = opt_params['compressionType']; - } - } - - // copy options - for (prop in opt_params) { - rawDeflateOption[prop] = opt_params[prop]; - } - - // set raw-deflate output buffer - rawDeflateOption['outputBuffer'] = this.output; - - this.rawDeflate = new Zlib.RawDeflate(this.input, rawDeflateOption); - }; - - /** - * @const - * @type {number} デフォルトバッファサイズ. - */ - Zlib.Deflate.DefaultBufferSize = 0x8000; - - /** - * @enum {number} - */ - Zlib.Deflate.CompressionType = Zlib.RawDeflate.CompressionType; - - /** - * 直接圧縮に掛ける. - * @param {!(Array|Uint8Array)} input target buffer. - * @param {Object=} opt_params option parameters. - * @return {!(Array|Uint8Array)} compressed data byte array. - */ - Zlib.Deflate.compress = function(input, opt_params) { - return (new Zlib.Deflate(input, opt_params)).compress(); - }; - - /** - * Deflate Compression. - * @return {!(Array|Uint8Array)} compressed data byte array. - */ - Zlib.Deflate.prototype.compress = function() { - /** @type {Zlib.CompressionMethod} */ - var cm; - /** @type {number} */ - var cinfo; - /** @type {number} */ - var cmf; - /** @type {number} */ - var flg; - /** @type {number} */ - var fcheck; - /** @type {number} */ - var fdict; - /** @type {number} */ - var flevel; - /** @type {number} */ - var adler; - /** @type {!(Array|Uint8Array)} */ - var output; - /** @type {number} */ - var pos = 0; - - output = this.output; - - // Compression Method and Flags - cm = Zlib.CompressionMethod.DEFLATE; - switch (cm) { - case Zlib.CompressionMethod.DEFLATE: - cinfo = Math.LOG2E * Math.log(Zlib.RawDeflate.WindowSize) - 8; - break; - default: - throw new Error('invalid compression method'); - } - cmf = (cinfo << 4) | cm; - output[pos++] = cmf; - - // Flags - fdict = 0; - switch (cm) { - case Zlib.CompressionMethod.DEFLATE: - switch (this.compressionType) { - case Zlib.Deflate.CompressionType.NONE: flevel = 0; break; - case Zlib.Deflate.CompressionType.FIXED: flevel = 1; break; - case Zlib.Deflate.CompressionType.DYNAMIC: flevel = 2; break; - default: throw new Error('unsupported compression type'); - } - break; - default: - throw new Error('invalid compression method'); - } - flg = (flevel << 6) | (fdict << 5); - fcheck = 31 - (cmf * 256 + flg) % 31; - flg |= fcheck; - output[pos++] = flg; - - // Adler-32 checksum - adler = Zlib.Adler32(this.input); - - this.rawDeflate.op = pos; - output = this.rawDeflate.compress(); - pos = output.length; - - { - // subarray 分を元にもどす - output = new Uint8Array(output.buffer); - // expand buffer - if (output.length <= pos + 4) { - this.output = new Uint8Array(output.length + 4); - this.output.set(output); - output = this.output; - } - output = output.subarray(0, pos + 4); - } - - // adler32 - output[pos++] = (adler >> 24) & 0xff; - output[pos++] = (adler >> 16) & 0xff; - output[pos++] = (adler >> 8) & 0xff; - output[pos++] = (adler ) & 0xff; - - return output; - }; - - class BrowserLocalFile { - - constructor(blob) { - this.file = blob; - } - - async read(position, length) { - const file = this.file; - if (position !== undefined) { - return file.slice(position, position + length).arrayBuffer() - - } else { - return file.arrayBuffer() - - } - } - } - - typeof process !== 'undefined' && process.versions != null && process.versions.node != null; - - class RemoteFile { - - constructor(args) { - this.config = args; - this.url = mapUrl(args.path || args.url); - } - - - async read(position, length) { - - length = Math.ceil(length); - const headers = this.config.headers || {}; - const rangeString = "bytes=" + position + "-" + (position + length - 1); - headers['Range'] = rangeString; - - let url = this.url.slice(); // slice => copy - // headers['User-Agent'] = 'straw' - if (this.config.oauthToken) { - const token = resolveToken(this.config.oauthToken); - headers['Authorization'] = `Bearer ${token}`; - } - if (this.config.apiKey) { - url = addParameter(url, "key", this.config.apiKey); - } - - const response = await fetch(url, { - method: 'GET', - headers: headers, - redirect: 'follow', - mode: 'cors', - - }); - - const status = response.status; - - if (status >= 400) { - console.error(`${status} ${this.config.url}`); - const err = Error(response.statusText); - err.code = status; - throw err - } else { - return response.arrayBuffer() - } - - /** - * token can be a string, a function that returns a string, or a function that returns a Promise for a string - * @param token - * @returns {Promise<*>} - */ - async function resolveToken(token) { - if (typeof token === 'function') { - return await Promise.resolve(token()) // Normalize the result to a promise, since we don't know what the function returns - } else { - return token - } - } - - } - } - - - function mapUrl(url) { - - if (url.includes("//www.dropbox.com")) { - return url.replace("//www.dropbox.com", "//dl.dropboxusercontent.com") - } else if (url.startsWith("ftp://ftp.ncbi.nlm.nih.gov")) { - return url.replace("ftp://", "https://") - } else { - return url - } - } - - - function addParameter(url, name, value) { - const paramSeparator = url.includes("?") ? "&" : "?"; - return url + paramSeparator + name + "=" + value - } - - class ThrottledFile { - - constructor(file, rateLimiter) { - this.file = file; - this.rateLimiter = rateLimiter; - } - - - async read(position, length) { - - const file = this.file; - const rateLimiter = this.rateLimiter; - - return new Promise(function (fulfill, reject) { - rateLimiter.limiter(async function (f) { - try { - const result = await f.read(position, length); - fulfill(result); - } catch (e) { - reject(e); - } - })(file); - }) - } - } - - class RateLimiter { - - constructor(wait) { - this.wait = wait === undefined ? 100 : wait; - - this.isCalled = false; - this.calls = []; - } - - - limiter(fn) { - - const self = this; - - let caller = function () { - - if (self.calls.length && !self.isCalled) { - self.isCalled = true; - self.calls.shift().call(); - setTimeout(function () { - self.isCalled = false; - caller(); - }, self.wait); - } - }; - - return function () { - self.calls.push(fn.bind(this, ...arguments)); - caller(); - }; - } - - } - - class BufferedFile { - - constructor(args) { - this.file = args.file; - this.size = args.size || 64000; - this.position = 0; - this.bufferStart = 0; - this.bufferLength = 0; - this.buffer = undefined; - } - - - async read(position, length) { - - const start = position; - const end = position + length; - const bufferStart = this.bufferStart; - const bufferEnd = this.bufferStart + this.bufferLength; - - - if (length > this.size) { - // Request larger than max buffer size, pass through to underlying file - //console.log("0") - this.buffer = undefined; - this.bufferStart = 0; - this.bufferLength = 0; - return this.file.read(position, length) - } - - if (start >= bufferStart && end <= bufferEnd) { - // Request within buffer bounds - //console.log("1") - const sliceStart = start - bufferStart; - const sliceEnd = sliceStart + length; - return this.buffer.slice(sliceStart, sliceEnd) - } - - else if (start < bufferStart && end > bufferStart) { - // Overlap left, here for completness but this is an unexpected case in straw. We don't adjust the buffer. - //console.log("2") - const l1 = bufferStart - start; - const a1 = await this.file.read(position, l1); - const l2 = length - l1; - if (l2 > 0) { - //this.buffer = await this.file.read(bufferStart, this.size) - const a2 = this.buffer.slice(0, l2); - return concatBuffers(a1, a2) - } else { - return a1 - } - - } - - else if (start < bufferEnd && end > bufferEnd) { - // Overlap right - // console.log("3") - const l1 = bufferEnd - start; - const sliceStart = this.bufferLength - l1; - const a1 = this.buffer.slice(sliceStart, this.bufferLength); - - const l2 = length - l1; - if (l2 > 0) { - try { - this.buffer = await this.file.read(bufferEnd, this.size); - this.bufferStart = bufferEnd; - this.bufferLength = this.buffer.byteLength; - const a2 = this.buffer.slice(0, l2); - return concatBuffers(a1, a2) - } catch (e) { - // A "unsatisfiable range" error is expected here if we overlap past the end of file - if (e.code && e.code === 416) { - return a1 - } - else { - throw e - } - } - - } else { - return a1 - } - - } - - else { - // No overlap with buffer - // console.log("4") - this.buffer = await this.file.read(position, this.size); - this.bufferStart = position; - this.bufferLength = this.buffer.byteLength; - return this.buffer.slice(0, length) - } - - } - - } - - /** - * concatenates 2 array buffers. - * Credit: https://gist.github.com/72lions/4528834 - * - * @private - * @param {ArrayBuffers} buffer1 The first buffer. - * @param {ArrayBuffers} buffer2 The second buffer. - * @return {ArrayBuffers} The new ArrayBuffer created out of the two. - */ - var concatBuffers = function (buffer1, buffer2) { - var tmp = new Uint8Array(buffer1.byteLength + buffer2.byteLength); - tmp.set(new Uint8Array(buffer1), 0); - tmp.set(new Uint8Array(buffer2), buffer1.byteLength); - return tmp.buffer; - }; - - // TODO -- big endian - - const BinaryParser = function (dataView, littleEndian) { - - this.littleEndian = littleEndian !== undefined ? littleEndian : true; - this.position = 0; - this.view = dataView; - this.length = dataView.byteLength; - }; - - BinaryParser.prototype.available = function () { - return this.length - this.position; - }; - - BinaryParser.prototype.remLength = function () { - return this.length - this.position; - }; - - BinaryParser.prototype.hasNext = function () { - return this.position < this.length - 1; - }; - - BinaryParser.prototype.getByte = function () { - var retValue = this.view.getUint8(this.position, this.littleEndian); - this.position++; - return retValue; - }; - - BinaryParser.prototype.getShort = function () { - - var retValue = this.view.getInt16(this.position, this.littleEndian); - this.position += 2; - return retValue; - }; - - BinaryParser.prototype.getUShort = function () { - - // var byte1 = this.getByte(), - // byte2 = this.getByte(), - // retValue = ((byte2 << 24 >>> 16) + (byte1 << 24 >>> 24)); - // return retValue; - - // - var retValue = this.view.getUint16(this.position, this.littleEndian); - this.position += 2; - return retValue; - }; - - - BinaryParser.prototype.getInt = function () { - - var retValue = this.view.getInt32(this.position, this.littleEndian); - this.position += 4; - return retValue; - }; - - - BinaryParser.prototype.getUInt = function () { - var retValue = this.view.getUint32(this.position, this.littleEndian); - this.position += 4; - return retValue; - }; - - BinaryParser.prototype.getLong = function () { - - // DataView doesn't support long. So we'll try manually - - var b = []; - b[0] = this.view.getUint8(this.position); - b[1] = this.view.getUint8(this.position + 1); - b[2] = this.view.getUint8(this.position + 2); - b[3] = this.view.getUint8(this.position + 3); - b[4] = this.view.getUint8(this.position + 4); - b[5] = this.view.getUint8(this.position + 5); - b[6] = this.view.getUint8(this.position + 6); - b[7] = this.view.getUint8(this.position + 7); - - var value = 0; - if (this.littleEndian) { - for (var i = b.length - 1; i >= 0; i--) { - value = (value * 256) + b[i]; - } - } else { - for (var i = 0; i < b.length; i++) { - value = (value * 256) + b[i]; - } - } - - - this.position += 8; - return value; - }; - - BinaryParser.prototype.getString = function (len) { - - var s = ""; - var c; - while ((c = this.view.getUint8(this.position++)) != 0) { - s += String.fromCharCode(c); - if (len && s.length == len) break; - } - return s; - }; - - BinaryParser.prototype.getFixedLengthString = function (len) { - - var s = ""; - var i; - var c; - for (i = 0; i < len; i++) { - c = this.view.getUint8(this.position++); - if (c > 0) { - s += String.fromCharCode(c); - } - } - return s; - }; - - BinaryParser.prototype.getFixedLengthTrimmedString = function (len) { - - var s = ""; - var i; - var c; - for (i = 0; i < len; i++) { - c = this.view.getUint8(this.position++); - if (c > 32) { - s += String.fromCharCode(c); - } - } - return s; - }; - - BinaryParser.prototype.getFloat = function () { - - var retValue = this.view.getFloat32(this.position, this.littleEndian); - this.position += 4; - return retValue; - - - }; - - BinaryParser.prototype.getDouble = function () { - - var retValue = this.view.getFloat64(this.position, this.littleEndian); - this.position += 8; - return retValue; - }; - - BinaryParser.prototype.skip = function (n) { - - this.position += n; - return this.position; - }; - - - /** - * Return a bgzip (bam and tabix) virtual pointer - * TODO -- why isn't 8th byte used ? - * @returns {*} - */ - BinaryParser.prototype.getVPointer = function () { - - var position = this.position, - offset = (this.view.getUint8(position + 1) << 8) | (this.view.getUint8(position)), - byte6 = ((this.view.getUint8(position + 6) & 0xff) * 0x100000000), - byte5 = ((this.view.getUint8(position + 5) & 0xff) * 0x1000000), - byte4 = ((this.view.getUint8(position + 4) & 0xff) * 0x10000), - byte3 = ((this.view.getUint8(position + 3) & 0xff) * 0x100), - byte2 = ((this.view.getUint8(position + 2) & 0xff)), - block = byte6 + byte5 + byte4 + byte3 + byte2; - this.position += 8; - - // if (block == 0 && offset == 0) { - // return null; - // } else { - return new VPointer(block, offset); - // } - }; - - - function VPointer(block, offset) { - this.block = block; - this.offset = offset; - } - - VPointer.prototype.isLessThan = function (vp) { - return this.block < vp.block || - (this.block === vp.block && this.offset < vp.offset); - }; - - VPointer.prototype.isGreaterThan = function (vp) { - return this.block > vp.block || - (this.block === vp.block && this.offset > vp.offset); - }; - - VPointer.prototype.print = function () { - return "" + this.block + ":" + this.offset; - }; - - class MatrixZoomData { - - constructor(chr1, chr2) { - - this.chr1 = chr1; // chromosome index - this.chr2 = chr2; - } - - getKey () { - return this.chr1.name + "_" + this.chr2.name + "_" + this.zoom.unit + "_" + this.zoom.binSize; - } - - getBlockNumbers(region1, region2, version) { - - // Verify region chromosomes and swap if neccessary - if(region1.chr == this.chr2 && region2.chr === this.chr1) { - const tmp = region1; - region1 = region2; - region2 = tmp; - } - - const sameChr = this.chr1 === this.chr2; - const binsize = this.zoom.binSize; - const blockBinCount = this.blockBinCount; - const blockColumnCount = this.blockColumnCount; - return (version < 9 || !sameChr) ? getBlockNumbersV8() : getBlockNumbersV9(); - - function getBlockNumbersV8() - { - const x1 = region1.start / binsize; - const x2 = region1.end / binsize; - const y1 = region2.start / binsize; - const y2 = region2.end / binsize; - - const col1 = Math.floor(x1 / blockBinCount); - const col2 = Math.floor((x2 - 1) / blockBinCount); - const row1 = Math.floor(y1 / blockBinCount); - const row2 = Math.floor((y2 - 1) / blockBinCount); - - const blockNumbers = []; - for (let row = row1; row <= row2; row++) { - for (let column = col1; column <= col2; column++) { - let blockNumber; - if (sameChr && row < column) { - blockNumber = column * blockColumnCount + row; - } else { - blockNumber = row * blockColumnCount + column; - } - if (!blockNumbers.includes(blockNumber)) { // possible from transposition - blockNumbers.push(blockNumber); - } - } - } - return blockNumbers - } - - function getBlockNumbersV9() - { - - const binX1 = region1.start / binsize; - const binX2 = region1.end / binsize; - const binY1 = region2.start / binsize; - const binY2 = region2.end / binsize; - - // PAD = positionAlongDiagonal (~projected) - // Depth is axis perpendicular to diagonal; nearer means closer to diagonal - const translatedLowerPAD = Math.floor((binX1 + binY1) / 2 / blockBinCount); - const translatedHigherPAD = Math.floor((binX2 + binY2) / 2 / blockBinCount); - const translatedNearerDepth = Math.floor(Math.log2(1 + Math.abs(binX1 - binY2) / Math.sqrt(2) / blockBinCount)); - const translatedFurtherDepth = Math.floor(Math.log2(1 + Math.abs(binX2 - binY1) / Math.sqrt(2) / blockBinCount)); - - // because code above assume above diagonal; but we could be below diagonal - const containsDiagonal = (binX2 - binY1) * (binX1 - binY2) < 0; // i.e. sign of (x-y) opposite on 2 corners - const nearerDepth = containsDiagonal ? 0 : Math.min(translatedNearerDepth, translatedFurtherDepth); - const furtherDepth = Math.max(translatedNearerDepth, translatedFurtherDepth); - - const blockNumbers = []; - for (let depth = nearerDepth; depth <= furtherDepth; depth++) { - for (let pad = translatedLowerPAD; pad <= translatedHigherPAD; pad++) { - const block_number = depth * blockColumnCount + pad; - blockNumbers.push(block_number); - } - } - return blockNumbers - } - } - - static parseMatrixZoomData(chr1, chr2, dis) { - - const zd = new MatrixZoomData(chr1, chr2); - - const unit = dis.getString(); - const zoomIndex = dis.getInt(); - const sumCounts = dis.getFloat(); - const occupiedCellCount = dis.getFloat(); - const stdDev = dis.getFloat(); - const percent95 = dis.getFloat(); - const binSize = dis.getInt(); - zd. blockBinCount = dis.getInt(); - zd. blockColumnCount = dis.getInt(); - const nBlocks = dis.getInt(); - - zd. zoom = {index: zoomIndex, unit: unit, binSize: binSize}; - - zd.blockIndex = new StaticBlockIndex(nBlocks, dis); - - const nBins1 = (chr1.size / binSize); - const nBins2 = (chr2.size / binSize); - const avgCount = (sumCounts / nBins1) / nBins2; // <= trying to avoid overflows - - zd.averageCount = avgCount; - zd.sumCounts = sumCounts; - zd.stdDev = stdDev; - zd.occupiedCellCount = occupiedCellCount; - zd.percent95 = percent95; - - return zd; - } - } - - - class StaticBlockIndex { - - constructor(nBlocks, dis) { - this.blockIndex = {}; - while (nBlocks-- > 0) { - const blockNumber = dis.getInt(); - const filePosition = dis.getLong(); - const size = dis.getInt(); - this.blockIndex[blockNumber] = {filePosition, size}; - } - } - - getBlockIndexEntry(blockNumber) { - return this.blockIndex[blockNumber]; - } - } - - class Matrix { - - constructor(chr1, chr2, zoomDataList) { - this.chr1 = chr1; - this.chr2 = chr2; - this.bpZoomData = []; - this.fragZoomData = []; - for (let zd of zoomDataList) { - if (zd.zoom.unit === "BP") { - this.bpZoomData.push(zd); - } else { - this.fragZoomData.push(zd); - } - } - } - - /** - * Find the best zoom level for the given bin size - * @param binSize - * @param unit - * @returns {number} - */ - findZoomForResolution(binSize, unit) { - const zdArray = "FRAG" === unit ? this.fragZoomData : this.bpZoomData; - for (let i = 1; i < zdArray.length; i++) { - var zd = zdArray[i]; - if (zd.zoom.binSize < binSize) { - return i - 1 - } - } - return zdArray.length - 1 - } - - /** - * Fetch zoom data by bin size. If no matching level exists return undefined. - * - * @param unit - * @param binSize - * @param zoom - * @returns {undefined|*} - */ - getZoomData(binSize, unit) { - unit = unit || "BP"; - const zdArray = unit === "BP" ? this.bpZoomData : this.fragZoomData; - for (let i = 0; i < zdArray.length; i++) { - var zd = zdArray[i]; - if (binSize === zd.zoom.binSize) { - return zd - } - } - return undefined - } - - /** - * Return zoom data by resolution index. - * @param index - * @param unit - * @returns {*} - */ - getZoomDataByIndex(index, unit) { - const zdArray = "FRAG" === unit ? this.fragZoomData : this.bpZoomData; - return zdArray[index] - } - - static getKey(chrIdx1, chrIdx2) { - if (chrIdx1 > chrIdx2) { - const tmp = chrIdx1; - chrIdx1 = chrIdx2; - chrIdx2 = tmp; - } - return `${chrIdx1}_${chrIdx2}`; - } - - static parseMatrix(data, chromosomes) { - - const dis = new BinaryParser(new DataView(data)); - const c1 = dis.getInt(); // Should equal chrIdx1 - const c2 = dis.getInt(); // Should equal chrIdx2 - - // TODO validate this - const chr1 = chromosomes[c1]; - const chr2 = chromosomes[c2]; - - // # of resolution levels (bp and frags) - let nResolutions = dis.getInt(); - const zdList = []; - - while (nResolutions-- > 0) { - const zd = MatrixZoomData.parseMatrixZoomData(chr1, chr2, dis); - zdList.push(zd); - } - return new Matrix(c1, c2, zdList); - } - - } - - class ContactRecord { - - constructor(bin1, bin2, counts) { - this.bin1 = bin1; - this.bin2 = bin2; - this.counts = counts; - }; - - getKey() { - return "" + this.bin1 + "_" + this.bin2; - } - } - - class LRU { - constructor(max = 10) { - this.max = max; - this.map = new Map(); - } - - get(key) { - let item = this.map.get(key); - if (item) { - // refresh key - this.map.delete(key); - this.map.set(key, item); - } - return item; - } - - set(key, val) { - // refresh key - if (this.map.has(key)) this.map.delete(key); - // evict oldest - else if (this.map.size === this.max) { - this.map.delete(this.first()); - } - this.map.set(key, val); - } - - has(key) { - return this.map.has(key); - } - - clear() { - this.map.clear(); - } - - first() { - return this.map.keys().next().value; - } - } - - /* - * The MIT License (MIT) - * - * Copyright (c) 2016-2017 The Regents of the University of California - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and - * associated documentation files (the "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the - * following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING - * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - */ - const DOUBLE$1 = 8; - - class NormalizationVector { - - constructor(file, filePosition, nValues, dataType) { - this.file = file; - this.filePosition = filePosition; - this.nValues = nValues; - this.dataType = dataType; - this.cache = undefined; - } - - async getValues(start, end) { - - if(!this.cache || start < this.cache.start || end > this.cache.end) { - const adjustedStart = Math.max(0, start - 1000); - const adjustedEnd = Math.min(this.nValues, end + 1000); - const startPosition = this.filePosition + adjustedStart * this.dataType; - const n = adjustedEnd - adjustedStart; - const sizeInBytes = n * this.dataType; - const data = await this.file.read(startPosition, sizeInBytes); - if (!data) { - return undefined; - } - const parser = new BinaryParser(new DataView(data)); - - const values = []; - for (let i = 0; i < n; i++) { - values[i] = this.dataType === DOUBLE$1 ? parser.getDouble() : parser.getFloat(); - - } - this.cache = { - start: adjustedStart, - end: adjustedEnd, - values: values - }; - } - - const sliceStart = start - this.cache.start; - const sliceEnd = sliceStart + (end - start); - return this.cache.values.slice(sliceStart, sliceEnd); - } - - getKey() { - return NormalizationVector.getKey(this.type, this.chrIdx, this.unit, this.resolution); - } - - - static getNormalizationVectorKey(type, chrIdx, unit, resolution) { - return type + "_" + chrIdx + "_" + unit + "_" + resolution; - } - } - - // Contains "normalization vector index" (nvi values) for legacy (v8) hosted files from aidenlab, ENCODE, and 4DN. - // These values can speed up initialization by a few seconds. - var nvi$1 = { - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2Fcombined.hic": "54386046426,55860", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2Fprimary.hic": "33860030033,37504", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2Freplicate.hic": "30849652794,55832", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2Fmaternal.hic": "1380542661,17185", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2Fpaternal.hic": "1389001777,17185", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fimr90%2Fin-situ%2Fcombined.hic": "13433880319,35723", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC001.hic": "3409347253,35975", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC002.hic": "4529947083,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC003.hic": "6894962500,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC004.hic": "3395593338,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC005.hic": "5204128636,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC006.hic": "3278363811,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC007.hic": "3585547340,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC008.hic": "4134197273,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC009.hic": "2851728310,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC010.hic": "1754216102,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC011.hic": "1716829574,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC012.hic": "4367980375,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC013.hic": "2309654671,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC014.hic": "5324950266,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC015.hic": "3132333594,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC016.hic": "3159154704,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC017.hic": "3262554627,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC018.hic": "3014216364,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC019.hic": "5025753246,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC020.hic": "5861584507,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC021.hic": "3542263275,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC022.hic": "5061949378,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC023.hic": "4816423919,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC024.hic": "2683781104,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC025.hic": "6522701781,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC026.hic": "6748846520,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC027.hic": "5642693007,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC028.hic": "2098921691,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC029.hic": "3886454027,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fagar%2FHIC030.hic": "2288984204,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fagar%2FHIC031.hic": "2115342419,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fpellet%2FHIC032.hic": "2063314324,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fsupernatant%2FHIC033.hic": "1933908457,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fdilution%2FHIC034.hic": "13555514595,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fdilution%2FHIC035.hic": "6129650900,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fdilution%2FHIC036.hic": "4307445019,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fdilution%2FHIC037.hic": "9375139867,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fdilution%2Fcombined.hic": "11664249584,33929", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2Fcombined_DpnII.hic": "7003537290,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC038.hic": "2099825544,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC039.hic": "2096900138,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC040.hic": "2593642141,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC041.hic": "2263919098,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC042.hic": "2684774693,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2Fcombined_noXlink.hic": "5574807456,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC043.hic": "2986114347,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC044.hic": "1916378621,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC045.hic": "746463126,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC046.hic": "2338476164,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC047.hic": "1167496250,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC048.hic": "2231690794,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC049.hic": "2782308678,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fimr90%2Fin-situ%2FHIC050.hic": "3633531346,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fimr90%2Fin-situ%2FHIC051.hic": "4063486444,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fimr90%2Fin-situ%2FHIC052.hic": "929756278,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fimr90%2Fin-situ%2FHIC053.hic": "2489657204,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fimr90%2Fin-situ%2FHIC054.hic": "4036419444,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fimr90%2Fin-situ%2FHIC055.hic": "4284185549,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fimr90%2Fin-situ%2FHIC056.hic": "4410546240,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fimr90%2Fdilution%2FHIC057.hic": "1491998259,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fhmec%2Fin-situ%2Fcombined.hic": "7266425111,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fhmec%2Fin-situ%2FHIC058.hic": "6532635593,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fhmec%2Fin-situ%2FHIC059.hic": "400684530,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fhmec%2Fin-situ%2FHIC060.hic": "645352187,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fhmec%2Fin-situ%2FHIC061.hic": "736291871,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fhmec%2Fin-situ%2FHIC062.hic": "762731037,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fhmec%2Fin-situ%2FHIC063.hic": "682917431,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fhmec%2Fdilution%2FHIC064.hic": "4550171307,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fnhek%2Fin-situ%2Fcombined.hic": "11897184911,35789", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fnhek%2Fin-situ%2FHIC065.hic": "5425943567,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fnhek%2Fin-situ%2FHIC066.hic": "5942869818,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fnhek%2Fin-situ%2FHIC067.hic": "5191049261,35647", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fnhek%2Fdilution%2FHIC068.hic": "2713318801,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fk562%2Fin-situ%2Fcombined.hic": "12641555389,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fk562%2Fin-situ%2FHIC069.hic": "5630177461,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fk562%2Fin-situ%2FHIC070.hic": "5926611269,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fk562%2Fin-situ%2FHIC071.hic": "2486191351,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fk562%2Fin-situ%2FHIC072.hic": "2281343366,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fk562%2Fin-situ%2FHIC073.hic": "2173074239,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fk562%2Fin-situ%2FHIC074.hic": "2463700999,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fkbm7%2Fin-situ%2Fcombined.hic": "14661922519,35639", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fkbm7%2Fin-situ%2FHIC075.hic": "3685310515,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fkbm7%2Fin-situ%2FHIC076.hic": "5833658487,35891", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fkbm7%2Fin-situ%2FHIC077.hic": "2406346486,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fkbm7%2Fin-situ%2FHIC078.hic": "5241454987,35919", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fkbm7%2Fin-situ%2FHIC079.hic": "6297234263,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fhuvec%2Fin-situ%2Fcombined.hic": "9193858096,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fhuvec%2Fin-situ%2FHIC080.hic": "5171405536,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fhuvec%2Fin-situ%2FHIC081.hic": "3489767688,35891", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fhuvec%2Fin-situ%2FHIC082.hic": "4243339375,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fhuvec%2Fdilution%2FHIC083.hic": "1497495406,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fhela%2Fin-situ%2Fcombined.hic": "7923332224,35593", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fhela%2Fin-situ%2FHIC084.hic": "867699123,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fhela%2Fin-situ%2FHIC085.hic": "3669518514,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fhela%2Fin-situ%2FHIC086.hic": "5306474712,35595", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fhela%2Fin-situ%2FHIC087.hic": "1490963755,36397", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2Fcombined.hic": "8956382853,50248", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2FHIC088.hic": "1874185366,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2FHIC089.hic": "1301165236,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2FHIC090.hic": "1105246282,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2FHIC091.hic": "1338325770,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2FHIC092.hic": "1307918730,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2FHIC093.hic": "755136918,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2FHIC094.hic": "1606583694,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2FHIC095.hic": "2039711245,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2FHIC096.hic": "1909573053,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2FHIC097.hic": "1826710712,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2FHIC098.hic": "1998793575,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2FHIC099.hic": "1007740962,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2FHIC100.hic": "736464120,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2FHIC101.hic": "980505082,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2FHIC102.hic": "1116083646,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fdilution%2FHIC103.hic": "1096994310,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fdilution%2FHIC104.hic": "841063882,32102", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC105.hic": "107742864,36479", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC106.hic": "134295912,36479", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC107.hic": "110228014,36479", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC108.hic": "102761401,36479", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC109.hic": "100461491,36479", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC110.hic": "88828472,36479", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC111.hic": "81471064,36479", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC112.hic": "92297035,36479", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC113.hic": "65503916,36479", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC114.hic": "49181188,36479", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC115.hic": "46471102,36479", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC116.hic": "64284432,36479", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC117.hic": "60434076,36479", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC118.hic": "45248563,36479", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC119.hic": "60288782,36479", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC120.hic": "136888414,36479", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC121.hic": "125009003,33681", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC122.hic": "154011688,34127", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC123.hic": "177663372,35293", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC124.hic": "382186226,35245", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC125.hic": "158160717,35271", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC127.hic": "110261177,34659", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC128.hic": "246131875,35509", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC129.hic": "260160119,35667", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC130.hic": "117479562,34681", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC131.hic": "81508929,34673", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC132.hic": "105959102,34895", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC133.hic": "91504812,33451", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC134.hic": "52222546,33737", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC135.hic": "57763085,34159", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC136.hic": "50618489,33731", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC137.hic": "193163606,33363", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC138.hic": "229876152,33777", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC139.hic": "201783666,33571", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC140.hic": "281163862,34125", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC141.hic": "275969727,33935", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC142.hic": "275020431,34125", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC144.hic": "223834810,34177", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC145.hic": "296632653,33937", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC146.hic": "290945216,33961", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC147.hic": "234459964,34231", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC148.hic": "295457850,34039", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC149.hic": "113569632,35695", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC150.hic": "304381897,33963", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC151.hic": "289314545,33805", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC152.hic": "284320182,33803", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC153.hic": "401393947,34659", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC154.hic": "188065488,36479", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC155.hic": "299157119,33967", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC156.hic": "279289244,33787", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC157.hic": "254852119,33917", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC158.hic": "195969660,33477", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC159.hic": "185720388,36479", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC160.hic": "227709279,33599", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC161.hic": "157225076,33209", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC162.hic": "105703444,32033", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC163.hic": "122665658,32121", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC164.hic": "228048231,33761", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC165.hic": "114440819,32011", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC166.hic": "285147558,33891", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC167.hic": "363116754,33943", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC168.hic": "119592158,31937", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC169.hic": "236853872,33785", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC170.hic": "195187639,33395", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC171.hic": "208044058,33309", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC172.hic": "144645916,32877", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC173.hic": "119115941,32203", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC175.hic": "178030481,33525", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC176.hic": "117220136,32169", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC177.hic": "128586196,32659", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC178.hic": "191419141,33629", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC179.hic": "141556748,32959", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC180.hic": "199825102,33185", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC181.hic": "301022688,33783", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC182.hic": "185384453,33205", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC183.hic": "202189264,36367", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC184.hic": "37464475,36479", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC185.hic": "161938278,36099", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC186.hic": "133853166,36179", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC188.hic": "128068030,36237", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC189.hic": "148053886,36177", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC190.hic": "198946958,35803", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC191.hic": "226584564,36063", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC192.hic": "194412797,36341", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC193.hic": "176408194,36479", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC194.hic": "207215649,36055", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC195.hic": "175185530,36315", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC196.hic": "168969337,36479", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC197.hic": "121231252,36339", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC198.hic": "92713752,36479", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC199.hic": "105130500,36479", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC200.hic": "114526350,36479", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC201.hic": "122689717,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fhap1%2Fin-situ%2Fcombined.hic": "9614983328,36479", - "s3.amazonaws.com%2Fhicfiles%2Fexternal%2Fctbp_8_4_17%2Fall_intra_megabase_michrom.hic": "154205644,10960", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2Fdel-Xa-combined.hic": "8843305329,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FdelXa-chrX-diploid.hic": "11173520,1498", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FWT-combined.hic": "13365182403,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FWT-chrX-diploid.hic": "17343459,1498", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FHIC002.hic": "4279298739,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FHIC003.hic": "3027365532,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FHIC004.hic": "2896130835,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FHIC005.hic": "4717830071,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FHIC006.hic": "5066210154,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FHIC007.hic": "3069516128,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2Fdel-Xi-combined.hic": "14551096423,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FdelXi-chrX-diploid.hic": "17362477,1498", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FHIC008.hic": "2572386655,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FHIC009.hic": "2935931663,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FHIC010.hic": "2019085070,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FHIC011.hic": "6087610814,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FHIC012.hic": "2809618194,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FHIC013.hic": "2572386655,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fpatski%2FDarrowHuntley-2015%2Fcombined.hic": "6950423609,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fpatski%2FDarrowHuntley-2015%2Fpaternal.hic": "220592749,15691", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fpatski%2FDarrowHuntley-2015%2Fmaternal.hic": "323233095,15691", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fpatski%2FDarrowHuntley-2015%2FHIC014.hic": "3183235800,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fpatski%2FDarrowHuntley-2015%2FHIC015.hic": "1739539801,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fpatski%2FDarrowHuntley-2015%2FHIC016.hic": "1105912758,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fpatski%2FDarrowHuntley-2015%2FHIC017.hic": "1060773319,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fpatski%2FDarrowHuntley-2015%2FHIC018.hic": "1203679874,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fpatski%2FDarrowHuntley-2015%2FHIC019.hic": "3321955269,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Frhesus%2FDarrowHuntley-2015%2FHIC020.hic": "7108980626,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fcola%2FDarrowHuntley-2015%2FHIC021.hic": "3906448676,34955", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fassembly%2Faedes%2Fcombined.hic": "390780490,2245", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fassembly%2Fhs2-hic.hic": "1960284186,33561", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fassembly%2FCpipJ3.hic": "766279097,4381", - "s3.amazonaws.com%2Fhicfiles%2Fexternal%2Fphanstiel%2Fupdated_O%2FSnyder_O.hic": "8046980555,18679", - "s3.amazonaws.com%2Fhicfiles%2Fexternal%2Fphanstiel%2FA_inter.hic": "10986005145,18679", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Funtreated%2Funsynchronized%2Fcombined.hic": "30439217680,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftreated_6hr%2Funsynchronized%2Fcombined.hic": "33255540403,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2Fdeep%2F20min_withdraw_combined.hic": "11078436933,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2Fdeep%2F40min_withdraw_combined.hic": "11031830038,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2Fdeep%2F60min_withdraw_combined.hic": "10312725340,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2Fdeep%2F180min_withdraw_combined.hic": "10038610214,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Funtreated%2Funsynchronized%2FHIC001.hic": "8004335785,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Funtreated%2Funsynchronized%2FHIC002.hic": "8453215933,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Funtreated%2Funsynchronized%2FHIC003.hic": "9118406189,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Funtreated%2Funsynchronized%2FHIC004.hic": "5973342894,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Funtreated%2Funsynchronized%2FHIC005.hic": "6846576837,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Funtreated%2Funsynchronized%2FHIC006.hic": "6075148017,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Funtreated%2Funsynchronized%2FHIC007.hic": "8192366992,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftreated_6hr%2Funsynchronized%2FHIC008.hic": "6844159653,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftreated_6hr%2Funsynchronized%2FHIC009.hic": "7282063059,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftreated_6hr%2Funsynchronized%2FHIC010.hic": "10410578833,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftreated_6hr%2Funsynchronized%2FHIC011.hic": "8192366992,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftreated_6hr%2Funsynchronized%2FHIC012.hic": "7223422850,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftreated_6hr%2Funsynchronized%2FHIC013.hic": "7435986997,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftreated_6hr%2Funsynchronized%2FHIC014.hic": "9120113605,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Funtreated%2Fsynchronized%2Fcombined.hic": "4170577904,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Funtreated%2Fsynchronized%2FHIC015.hic": "1504084990,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Funtreated%2Fsynchronized%2FHIC016.hic": "1686244500,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Funtreated%2Fsynchronized%2FHIC017.hic": "1804802410,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Funtreated%2Fsynchronized%2FHIC018.hic": "1533942067,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftreated_6hr%2Fsynchronized%2Fcombined.hic": "4572390198,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftreated_6hr%2Fsynchronized%2FHIC019.hic": "1543609666,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftreated_6hr%2Fsynchronized%2FHIC020.hic": "1814133288,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftreated_6hr%2Fsynchronized%2FHIC021.hic": "1942698243,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftreated_6hr%2Fsynchronized%2FHIC022.hic": "1873587413,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2Funtreated%2FRao-2017-HIC049.hic": "405127557,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2Funtreated%2FRao-2017-HIC060.hic": "326681741,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2Funtreated%2FRao-2017-HIC061.hic": "300908673,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_20min%2FRao-2017-HIC050.hic": "481758242,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_20min%2FRao-2017-HIC051.hic": "417577401,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_40min%2FRao-2017-HIC052.hic": "419353227,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_40min%2FRao-2017-HIC053.hic": "411554953,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_60min%2FRao-2017-HIC054.hic": "386655891,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_60min%2FRao-2017-HIC055.hic": "402170701,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_240min%2FRao-2017-HIC057.hic": "735906308,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min%2FRao-2017-HIC058.hic": "443789827,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min%2FRao-2017-HIC059.hic": "491422615,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min%2FRao-2017-HIC062.hic": "320261375,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min%2FRao-2017-HIC063.hic": "306590499,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min_withdraw_20min%2FRao-2017-HIC032S.hic": "367051742,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min_withdraw_20min%2FRao-2017-HIC033S.hic": "344555339,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min_withdraw_40min%2FRao-2017-HIC036S.hic": "349392947,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min_withdraw_40min%2FRao-2017-HIC037S.hic": "317714554,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min_withdraw_60min%2FRao-2017-HIC040S.hic": "266786397,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min_withdraw_60min%2FRao-2017-HIC041S.hic": "279445530,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min_withdraw_180min%2FRao-2017-HIC044S.hic": "898418269,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min_withdraw_180min%2FRao-2017-HIC045S.hic": "961006347,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min_withdraw_360min%2FRao-2017-HIC064.hic": "833576408,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min_withdraw_360min%2FRao-2017-HIC065.hic": "840881418,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min_withdraw_1080min%2FRao-2017-HIC066.hic": "980958864,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min_withdraw_1080min%2FRao-2017-HIC067.hic": "882023129,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min_withdraw_1440min%2FRao-2017-HIC068.hic": "1110292630,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min_withdraw_1440min%2FRao-2017-HIC069.hic": "1001747023,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fexternal%2Frowley_nichols_mol_cell_2017%2FCP190_HiChIP.hic": "144107588,6976", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fexternal%2Frowley_nichols_mol_cell_2017%2FH3K27ac_HiChIP_combined.hic": "43171370,5233", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fexternal%2Frowley_nichols_mol_cell_2017%2FH3K27me3_HiChIP_combined.hic": "42906472,5233", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fexternal%2Frowley_nichols_mol_cell_2017%2FPol2_ChIAPET.hic": "41992430,6976", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fexternal%2Frowley_nichols_mol_cell_2017%2FPol2S2_HiChIP.hic": "145842743,6976", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fexternal%2Frowley_nichols_mol_cell_2017%2FArabidopsis_Wang2015_Liu2016.hic": "1134391078,4984", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fexternal%2Frowley_nichols_mol_cell_2017%2FElegans_Crane2015.hic": "387127568,8758", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fexternal%2Frowley_nichols_mol_cell_2017%2FNcrassa_Galazka2016.hic": "26555511,27725", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fexternal%2Frowley_nichols_mol_cell_2017%2FPfalciparum_trophozoite_Ay2014.hic": "15640893,13948", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fduan%2FE-Me-A.hic": "6897251,23348", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fduan%2FE-Me-B.hic": "4959088,23348", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fduan%2FE-Mp-A.hic": "5232286,23348", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fduan%2FE-Mp-B.hic": "5105292,23348", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fduan%2FH-Me-A.hic": "6900072,23348", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fduan%2FH-Me-B.hic": "8653258,23348", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fduan%2FH-Mp-A.hic": "7999058,23348", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fduan%2FH-Mp-B.hic": "8774657,23348", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fdekker%2F4dn%2Fh1hesc.hic": "23671753603,36479", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fdekker%2F4dn%2Fh1hesc_rep1.hic": "23671754721,36479", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fdekker%2F4dn%2Fh1hesc_rep2.hic": "22269909910,36479", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fdekker%2F4dn%2Fhffc6_rep1.hic": "19016661622,36479", - "hicfiles.s3.amazonaws.com%2Fexternal%2Flieberman_aiden_van_berkum%2FGM06990_NcoI.hic": "480725203,36479", - "hicfiles.s3.amazonaws.com%2Fexternal%2Flieberman_aiden_van_berkum%2F302NH.hic": "99948617,36479", - "hicfiles.s3.amazonaws.com%2Fexternal%2Flieberman_aiden_van_berkum%2FK562.hic": "470263605,36151", - "hicfiles.s3.amazonaws.com%2Fexternal%2Flieberman_aiden_van_berkum%2FGM06990_HindIII.hic": "293706559,36289", - "hicfiles.s3.amazonaws.com%2Fexternal%2Flieberman_aiden_van_berkum%2FGM06990_rep_HindIII.hic": "309673862,36087", - "hicfiles.s3.amazonaws.com%2Fexternal%2Frudan%2Fcanis-lupus-rep1.hic": "1531151371,56905", - "hicfiles.s3.amazonaws.com%2Fexternal%2Frudan%2Fcanis-lupus-rep2.hic": "2851437676,56905", - "hicfiles.s3.amazonaws.com%2Fexternal%2Frudan%2Fmouse-rep1.hic": "582052544,32102", - "hicfiles.s3.amazonaws.com%2Fexternal%2Frudan%2Fmacaque-rep1.hic": "698509182,32102", - "hicfiles.s3.amazonaws.com%2Fexternal%2Frudan%2Fmacaque-rep2.hic": "461410393,32102", - "hicfiles.s3.amazonaws.com%2Fexternal%2Frudan%2Frabbit-rep1.hic": "691045338,33561", - "hicfiles.s3.amazonaws.com%2Fexternal%2Frudan%2Frabbit-rep2.hic": "668888336,33561", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fsexton%2Fcombined.hic": "50650087,4486", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fkalhor%2Ftcc-hindiii.hic": "1071142023,16500", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fkalhor%2Ftcc-mboi.hic": "1508851093,16448", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fkalhor%2Fnon-tcc-hindiii.hic": "395179229,36093", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fkalhor%2Ftcc-combined.hic": "1050423847,36479", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fdixon%2Fmm9-hindiii%2Fsplit-read-run.hic": "9599984876,32102", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fdixon%2Fhesc-hindiii.hic": "1952555632,36479", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fdixon%2Fimr90-hindiii.hic": "9691260435,18679", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fdixon%2Fmm9-cortex.hic": "3712072953,32102", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fzhang%2Fatm-i-scei-chr18.hic": "2083350075,16438", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fzhang%2Fatm-i-scei-chr2.hic": "3362049644,16360", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fzhang%2Fatm-i-scei-chr7.hic": "1658399854,16438", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fzhang%2Fwt-i-scei-chr15.hic": "866691249,16438", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fzhang%2Fwt-i-scei-chr2.hic": "3304782795,16386", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fnagano%2Fcell-1.hic": "23673506,32102", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fnagano%2Fcell-2.hic": "26873280,30643", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fnagano%2Fcell-3.hic": "31066362,30643", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fnagano%2Fcell-4.hic": "16807724,30643", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fnagano%2Fcell-5.hic": "28665065,30643", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fnagano%2Fcell-6.hic": "13124158,30643", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fnagano%2Fcell-7.hic": "15118945,30643", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fnagano%2Fcell-8.hic": "68316814,32102", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fnagano%2Fcell-9.hic": "18965101,30643", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fnagano%2Fcell-10.hic": "17020666,30643", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fjin%2Fimr90%2Fcombined.hic": "6526601242,36427", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fjin%2Fimr90%2Frep1.hic": "1861562891,36401", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fjin%2Fimr90%2Frep2.hic": "3061013635,36479", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fjin%2Fimr90%2Frep3.hic": "1564588211,35969", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fjin%2Fimr90%2Frep4.hic": "1255543175,36153", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fjin%2Fimr90%2Frep5.hic": "974683253,36179", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fjin%2Fimr90%2Frep6.hic": "1040805629,36053", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fjin%2Fimr90-tnf-alpha%2Fcombined.hic": "8424080116,36401", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fjin%2Fimr90-tnf-alpha%2Frep1.hic": "2697976702,36295", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fjin%2Fimr90-tnf-alpha%2Frep3.hic": "1718610467,36159", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fjin%2Fimr90-tnf-alpha%2Frep4.hic": "2029519405,36101", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fjin%2Fimr90-tnf-alpha%2Frep5.hic": "985310855,36069", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fjin%2Fimr90-tnf-alpha%2Frep6.hic": "1418750480,35967", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fcheng%2Fmhh-call-4-cell-line.hic": "538380253,35351", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fcheng%2Fprimary-b-all.hic": "773764191,35793", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fcheng%2Fnormal-b-cell-line.hic": "336271459,35005", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fcheng%2Frl-cell-line.hic": "484807998,35351", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fhou%2Fkc167-biorep.hic": "135932435,8758", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fhou%2Fkc167-techrep1.hic": "160355961,8758", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fhou%2Fkc167-techrep2.hic": "188809887,8758", - "hicfiles.s3.amazonaws.com%2Fexternal%2Flin%2Fpre-prob-egs.hic": "2237792858,15483", - "hicfiles.s3.amazonaws.com%2Fexternal%2Flin%2Fprob-egs.hic": "5744720377,16438", - "hicfiles.s3.amazonaws.com%2Fexternal%2Flin%2Fprob-fa.hic": "2174866215,16438", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fli%2Fhct116-rnapii-pilot.hic": "396366166,35999", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fli%2Fhela-rnapii-pilot.hic": "882516759,35107", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fli%2Fk562-rnapii-pilot.hic": "1131576189,35969", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fli%2Fk562-rnapii-saturated.hic": "571583828,36291", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fli%2Fmcf7-rnapii-saturated.hic": "1282547841,36035", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fli%2Fnb4-rnapii-pilot.hic": "761614686,34861", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fjung%2Fmouse_sperm.hic": "1730231642,29184", - "hicfiles.s3.amazonaws.com%2Fexternal%2Ftang%2Fgm12878.hic": "1953518212,20505", - "hicfiles.s3.amazonaws.com%2Fexternal%2Frutledge%2FSRR1791299.hic": "5723484,11956", - "hicfiles.s3.amazonaws.com%2Fexternal%2Frutledge%2FSRR1791297.hic": "16534743,23348", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fzuin%2Fhek293t-rad21cv-hrv.hic": "5094525579,36289", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fzuin%2Fhek293t-rad21cv-hrv-rep1.hic": "2574358912,36373", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fzuin%2Fhek293t-rad21cv-hrv-rep2.hic": "3417099433,36243", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fzuin%2Fhek293t-rad21cv-tev.hic": "4785157552,36323", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fzuin%2Fhek293t-rad21cv-tev-rep1.hic": "2648268465,36321", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fzuin%2Fhek293t-rad21cv-tev-rep2.hic": "2994727980,36107", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fzuin%2Fhek293t-sirna-ctcf.hic": "5391791815,36063", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fzuin%2Fhek293t-sirna-ctcf-rep1.hic": "3325842095,36269", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fzuin%2Fhek293t-sirna-ctcf-rep2.hic": "3096215920,36167", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fzuin%2Fhek293t-sirna-ctrl.hic": "3830902383,36167", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fzuin%2Fhek293t-sirna-ctrl-rep1.hic": "1346712252,36079", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fzuin%2Fhek293t-sirna-ctrl_rep2.hic": "3098067367,36271", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fay%2Fp-falciparum-3d7-0h-hiseq.hic": "38174042,21889", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fay%2Fp-falciparum-3d7-18h-hiseq.hic": "26506099,21889", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fay%2Fp-falciparum-3d7-18h-hiseq-non-crosslinked_control.hic": "3545496,21889", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fay%2Fp-falciparum-3d7-36h-hiseq.hic": "70754194,21889", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fnaumova%2Fhelas3%2Fg1mid-r1.hic": "200863476,17185", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fnaumova%2Fhelas3%2Fm-r1.hic": "249021190,17185", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fnaumova%2Fhelas3%2Fm-r2.hic": "212341157,17185", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fnaumova%2Fhelas3ccl2p2%2Fg1-0-25fa.hic": "583572265,17185", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fnaumova%2Fhelas3ccl2p2%2Fg1-1fa.hic": "354502306,17185", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fnaumova%2Fhelas3ccl2p2%2Fm-0-25fa.hic": "149308791,17185", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fnaumova%2Fhelas3ccl2p2%2Fm-98percent.hic": "778175225,17185", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fnaumova%2Fhelas3ccl2p2%2Fm-1fa.hic": "158091047,17185", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fnaumova%2Fhff1%2Fcchic-hff1-ns-r1.hic": "801670039,17185", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fnaumova%2Fhff1%2Fcchic-hff1-m-r1.hic": "875922086,17185", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fnaumova%2Fk562%2Fm-r1.hic": "130959943,17185", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fnaumova%2Fk562%2Fm-r2.hic": "237861106,17185", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fsofueva%2FmAST-WT.hic": "496104039,30643", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fsofueva%2FmAST-WT-adv-cre.hic": "438608517,30643", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fsofueva%2FmAST-floxed-rep1.hic": "446205712,32102", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fsofueva%2FmAST-floxed-rep2.hic": "386354767,32102", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fsofueva%2FmAST-deleted-rep1.hic": "621998722,30643", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fsofueva%2FmAST-deleted-rep2.hic": "583840829,32102", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fsofueva%2FmNSC-floxed-rep1.hic": "801290988,30643", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fsofueva%2FmNSC-floxed-rep2.hic": "819406658,30643", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fsofueva%2FmNSC-deleted-rep1.hic": "792825269,32102", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fsofueva%2FmNSC-deleted-rep2.hic": "746189884,30643", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fsofueva%2FmNSC-WT.hic": "309353372,30643", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fsofueva%2FmNSC-WT-OHT.hic": "274229679,30643", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fseitan%2FTcell-Rad21KO-R1.hic": "1490362251,32102", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fseitan%2FTcell-Rad21KO-R3.hic": "2403664421,32102", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fseitan%2FTcell-Rad21WT-R1.hic": "1377124538,32102", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fseitan%2FTcell-Rad21WT-R3.hic": "2646201369,32102", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fmoissiard%2Fcrh6-mutant.hic": "105261071,10217", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fmoissiard%2FWT.hic": "127506388,10217", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fgrob%2FCol.hic": "153638500,10217", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fgrob%2Fcrwn1.hic": "211213220,10217", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fgrob%2Fcrwn4.hic": "134236837,10217", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fxie%2Fprimary.hic": "92936173,10217", - "hicfiles.s3.amazonaws.com%2Fexternal%2Ffeng%2F6wt-control6wt337.hic": "318737891,10217", - "hicfiles.s3.amazonaws.com%2Fexternal%2Ffeng%2F6wt-control6wt67.hic": "348123956,10217", - "hicfiles.s3.amazonaws.com%2Fexternal%2Ffeng%2F6wt337.hic": "251107279,10217", - "hicfiles.s3.amazonaws.com%2Fexternal%2Ffeng%2F6wt67.hic": "351840994,10217", - "hicfiles.s3.amazonaws.com%2Fexternal%2Ffeng%2FCol0.hic": "345969497,10217", - "hicfiles.s3.amazonaws.com%2Fexternal%2Ffeng%2Fclf28-swn7.hic": "299585025,10217", - "hicfiles.s3.amazonaws.com%2Fexternal%2Ffeng%2Fcmt3-11.hic": "253427706,10217", - "hicfiles.s3.amazonaws.com%2Fexternal%2Ffeng%2Fddm1-2.hic": "303626924,10217", - "hicfiles.s3.amazonaws.com%2Fexternal%2Ffeng%2Fmet1-3.hic": "347697973,10217", - "hicfiles.s3.amazonaws.com%2Fexternal%2Ffeng%2Fsuvh4-suvh5-suvh6.hic": "263122019,10217", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fma%2FDNase-HiC-WG-K562.hic": "892955840,18679", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fma%2FDNaseHiC-WG-H1.hic": "696922695,18679", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fma%2FtargetedDNaseHiC-lincRNA-K562-rep1.hic": "341917716,18679", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fma%2FtargeredDNaseHiC-lincRNA-K562-rep2.hic": "214841185,18679", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fma%2FtargetedDNaseHiC-lincRNA-H1-rep1.hic": "616326137,18679", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fma%2FtargetedDNaseHiC-lincRNA-H1-rep2.hic": "579654013,18679", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fma%2FtargetedDNaseHiC-pe-H1-rep1.hic": "519810544,18679", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fma%2FtargetedDNaseHiC-pe-K562-rep1.hic": "199553123,18679", - "hicfiles.s3.amazonaws.com%2Fexternal%2Frowley%2FKc167_DpnII.hic": "1319373594,6976", - "hicfiles.s3.amazonaws.com%2Fexternal%2Frowley%2FKc167_HinfI.hic": "1465493873,6976", - "hicfiles.s3.amazonaws.com%2Fexternal%2Frowley%2FKc167_DpnII_HinfI_combo.hic": "753062558,5814", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fbarutcu%2FMCF-10A.hic": "2784956115,36479", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fbarutcu%2FMCF-7.hic": "2700457411,36479", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fbatullin%2Fsperm.hic": "501052169,32102", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fminajigi%2FWT_hiC_rep1.hic": "1450697530,32102", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fminajigi%2FWT_hiC_rep2.hic": "1189371558,32102", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fminajigi%2Fcombined.hic": "2262007875,32102", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fminajigi%2Finactive.hic": "4444564,751", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fminajigi%2Factive.hic": "3993495,751", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fdeng%2Fpatski_rep1.hic": "1650838357,32102", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fdeng%2Fpatski_rep2.hic": "1258038606,32102", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fdeng%2Fpatski.hic": "499827296,16438", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fdeng%2Fpatski_active.hic": "79175714,15691", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fdeng%2Fpatski_inactive.hic": "98947881,15691", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fdeng%2Fbrain_dnase.hic": "4298088401,32102", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fdeng%2Fbrain_in_situ_dnase.hic": "609321852,32102", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fdeng%2Fbrain.hic": "1028196506,16438", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fdeng%2Fbrain_active.hic": "79175714,15691", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fdeng%2Fbrain_inactive.hic": "98947881,15691", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fle%2FBglII_rep1.hic": "1283306,1463", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fle%2FBglII_rep2.hic": "1263227,1463", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fle%2FNcoI_rep1.hic": "4380906,1463", - "hicfiles.s3.amazonaws.com%2Fexternal%2Feagen%2FGSE89112_Kc167combined.hic": "1829549643,25624", - "hicfiles.s3.amazonaws.com%2Fexternal%2Feagen%2FGSE89112_Kc167combined_randomized.hic": "1859742654,25624", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fmumbach%2FGSE80820_HiChIP_GM_cohesin.hic": "1231264781,17932", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fmumbach%2FGSE80820_HiChIP_mES_cohesin_all.hic": "1152008628,16438", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fmumbach%2FGSE80820_HiChIP_mES_Oct4.hic": "912828146,16438", - "s3.amazonaws.com%2Fhicfiles%2Fexternal%2Fwapl_hic%2FSCC4KO.hic": "1767906138,18679", - "s3.amazonaws.com%2Fhicfiles%2Fexternal%2Fwapl_hic%2FDKO.hic": "1487228787,18679", - "s3.amazonaws.com%2Fhicfiles%2Fexternal%2Fwapl_hic%2FWaplKO_1.14.hic": "1189751862,18679", - "s3.amazonaws.com%2Fhicfiles%2Fexternal%2Fwapl_hic%2FWaplKO_3.3.hic": "1155057696,18679", - "s3.amazonaws.com%2Fhicfiles%2Fexternal%2Fwapl_hic%2FWT.hic": "1522401568,18679", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fskfuwi4fnsjkdf9jekrw2%2Fmega_Liverpool%2Fmega.hic": "2612171975,4381", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fskfuwi4fnsjkdf9jekrw2%2FHIC2836_Liverpool1%2FLiverpool1.hic": "191729195,2245", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fskfuwi4fnsjkdf9jekrw2%2FHIC2861_Liverpool2%2FLiverpool2.hic": "1637096030,4381", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fskfuwi4fnsjkdf9jekrw2%2FHIC2862_Liverpool3%2FLiverpool3.hic": "1160045602,4381", - "s3.amazonaws.com%2Fhicfiles%2Fexternal%2Fgoodell%2FHSPC.hic": "11857786247,36479", - "s3.amazonaws.com%2Fhicfiles%2Fexternal%2Fgoodell%2FHSPC_CanyonDel.hic": "8139168836,36479", - "s3.amazonaws.com%2Fhicfiles%2Fexternal%2Fgoodell%2Ftcell.hic": "9871547081,36479", - "s3.amazonaws.com%2Fhicfiles%2Fexternal%2Fgoodell%2Fep.hic": "17479335373,36479", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fnagano%2FTh1_ensemble.hic": "1690592868,32102", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fbonev%2FES_mapq30.hic": "32930498831,32386", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fbonev%2FNPC_mapq30.hic": "55053730986,32386", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fbonev%2FCN_mapq30.hic": "53138031154,32386", - "hicfiles.s3.amazonaws.com%2Fhiseq%2FKieffer-Kwon_et_al_2017%2FMain_maps%2FKieffer-Kwon-2017-activated_B_cells_72_hours_WT.hic": "16492991184,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2FKieffer-Kwon_et_al_2017%2FMain_maps%2FKieffer-Kwon-2017-resting_B_cells_WT.hic": "23057795398,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2FKieffer-Kwon_et_al_2017%2FMain_maps%2FKieffer-Kwon-2017-activated_B_cells_24_hours_MYC_KO.hic": "21245554876,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2FKieffer-Kwon_et_al_2017%2FMain_maps%2FKieffer-Kwon-2017-resting_B_cells_TSA.hic": "13933346059,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2FKieffer-Kwon_et_al_2017%2FMain_maps%2FKieffer-Kwon-2017-activated_B_cells_24_hours_oligomycin.hic": "21902506832,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2FKieffer-Kwon_et_al_2017%2FMain_maps%2FKieffer-Kwon-2017-mES_WT.hic": "9451969795,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2FVian_et_al_2018%2FMain_maps%2FVian-2018-activated_B_cells_24_hours_WT.hic": "3600188564,16438", - "hicfiles.s3.amazonaws.com%2Fhiseq%2FVian_et_al_2018%2FMain_maps%2FVian-2018-activated_B_cells_30_hours_WT.hic": "1309503359,16438", - "hicfiles.s3.amazonaws.com%2Fhiseq%2FVian_et_al_2018%2FMain_maps%2FVian-2018-activated_B_cells_30_hours_HU_treated.hic": "1477252396,16438", - "hicfiles.s3.amazonaws.com%2Fhiseq%2FVian_et_al_2018%2FMain_maps%2FVian-2018-activated_B_cells_24_hours_flavopiridol.hic": "15711773490,32102", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fpgp%2FPGP1F_mega_090118%2FPGP1F_mega_090118_30.hic": "24786676166,36479", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fpgp%2FHIC7145%2FHIC7145_30.hic": "4554644616,36479", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fpgp%2FHIC7146%2FHIC7146_30.hic": "4174848944,36479", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fpgp%2FHIC7147%2FHIC7147_30.hic": "5062229182,36479", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fpgp%2FHIC7862%2FHIC7862_30.hic": "4520990620,36479", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fpgp%2FHIC7863%2FHIC7863_30.hic": "4330354773,36479", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fpgp%2FHIC7864%2FHIC7864_30.hic": "5880640268,36479", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fpgp%2FHIC7865%2FHIC7865_30.hic": "4431632469,36479", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fpgp%2FHIC7866%2FHIC7866_30.hic": "4686000222,36479", - "encode-public.s3.amazonaws.com%2F2018%2F10%2F19%2Fb122542b-306c-4631-bdc3-2e155e89af55%2FENCFF718AWL.hic": "39544267907,58932", - "encode-public.s3.amazonaws.com%2F2019%2F02%2F15%2F8e787cd8-e388-4bc2-a236-7a5e6f39e0c0%2FENCFF999YXX.hic": "9255069996,56883", - "encode-public.s3.amazonaws.com%2F2019%2F02%2F08%2Ffc1d9d5d-8fa0-4e29-9080-3da674d9490d%2FENCFF543USQ.hic": "5005263062,36479", - "s3.us-east-1.wasabisys.com%2Fhicfiles%2Finternal%2FLCL_mega_42B_500bp_30.hic": "106482584851,22829", - "www.encodeproject.org%2Ffiles%2FENCFF925QIF%2F%40%40download%2FENCFF925QIF.hic": "51712684396,54779", - "www.encodeproject.org%2Ffiles%2FENCFF259YUS%2F%40%40download%2FENCFF259YUS.hic": "24640030444,54779", - "www.encodeproject.org%2Ffiles%2FENCFF783KQI%2F%40%40download%2FENCFF783KQI.hic": "27209249856,54779", - "www.encodeproject.org%2Ffiles%2FENCFF318JAP%2F%40%40download%2FENCFF318JAP.hic": "28636979242,54779", - "www.encodeproject.org%2Ffiles%2FENCFF512PQA%2F%40%40download%2FENCFF512PQA.hic": "28124104361,54779", - "www.encodeproject.org%2Ffiles%2FENCFF591MHA%2F%40%40download%2FENCFF591MHA.hic": "37373387202,54779", - "www.encodeproject.org%2Ffiles%2FENCFF197OWW%2F%40%40download%2FENCFF197OWW.hic": "41826180893,54779", - "www.encodeproject.org%2Ffiles%2FENCFF317OIA%2F%40%40download%2FENCFF317OIA.hic": "34741636038,54779", - "www.encodeproject.org%2Ffiles%2FENCFF522YLZ%2F%40%40download%2FENCFF522YLZ.hic": "24064692329,54779", - "www.encodeproject.org%2Ffiles%2FENCFF420JTA%2F%40%40download%2FENCFF420JTA.hic": "21202405177,54779", - "www.encodeproject.org%2Ffiles%2FENCFF871ZDJ%2F%40%40download%2FENCFF871ZDJ.hic": "10124815680,18679", - "www.encodeproject.org%2Ffiles%2FENCFF349RZY%2F%40%40download%2FENCFF349RZY.hic": "4446702705,36479", - "www.encodeproject.org%2Ffiles%2FENCFF738YON%2F%40%40download%2FENCFF738YON.hic": "3338049584,35947", - "www.encodeproject.org%2Ffiles%2FENCFF406KJN%2F%40%40download%2FENCFF406KJN.hic": "4132875306,36479", - "www.encodeproject.org%2Ffiles%2FENCFF081NPN%2F%40%40download%2FENCFF081NPN.hic": "34495587443,54779", - "www.encodeproject.org%2Ffiles%2FENCFF946RZW%2F%40%40download%2FENCFF946RZW.hic": "34571955193,54779", - "www.encodeproject.org%2Ffiles%2FENCFF602CHT%2F%40%40download%2FENCFF602CHT.hic": "30674798032,54779", - "www.encodeproject.org%2Ffiles%2FENCFF150DKS%2F%40%40download%2FENCFF150DKS.hic": "12618769864,36479", - "www.encodeproject.org%2Ffiles%2FENCFF614IPZ%2F%40%40download%2FENCFF614IPZ.hic": "42450060331,54779", - "www.encodeproject.org%2Ffiles%2FENCFF571ZQR%2F%40%40download%2FENCFF571ZQR.hic": "15230068871,47429", - "www.encodeproject.org%2Ffiles%2FENCFF705MKK%2F%40%40download%2FENCFF705MKK.hic": "38686554702,54779", - "www.encodeproject.org%2Ffiles%2FENCFF658KTB%2F%40%40download%2FENCFF658KTB.hic": "13195884405,47429", - "www.encodeproject.org%2Ffiles%2FENCFF435JYN%2F%40%40download%2FENCFF435JYN.hic": "17192139674,54779", - "www.encodeproject.org%2Ffiles%2FENCFF016JKX%2F%40%40download%2FENCFF016JKX.hic": "37266736642,54779", - "www.encodeproject.org%2Ffiles%2FENCFF294GFP%2F%40%40download%2FENCFF294GFP.hic": "36389843399,54779", - "www.encodeproject.org%2Ffiles%2FENCFF700CYI%2F%40%40download%2FENCFF700CYI.hic": "60482012152,54779", - "www.encodeproject.org%2Ffiles%2FENCFF962EDB%2F%40%40download%2FENCFF962EDB.hic": "39394328182,54779", - "www.encodeproject.org%2Ffiles%2FENCFF467OGP%2F%40%40download%2FENCFF467OGP.hic": "35572788855,54779", - "www.encodeproject.org%2Ffiles%2FENCFF556RLR%2F%40%40download%2FENCFF556RLR.hic": "34826921187,54779", - "www.encodeproject.org%2Ffiles%2FENCFF309UNV%2F%40%40download%2FENCFF309UNV.hic": "48510618174,54779", - "www.encodeproject.org%2Ffiles%2FENCFF653HCO%2F%40%40download%2FENCFF653HCO.hic": "41079007620,54779", - "www.encodeproject.org%2Ffiles%2FENCFF120DSV%2F%40%40download%2FENCFF120DSV.hic": "12790195576,47429", - "www.encodeproject.org%2Ffiles%2FENCFF284OEA%2F%40%40download%2FENCFF284OEA.hic": "46007570339,54779", - "www.encodeproject.org%2Ffiles%2FENCFF035BLF%2F%40%40download%2FENCFF035BLF.hic": "63868871985,54779", - "www.encodeproject.org%2Ffiles%2FENCFF094KKX%2F%40%40download%2FENCFF094KKX.hic": "42151419971,54779", - "www.encodeproject.org%2Ffiles%2FENCFF965BPU%2F%40%40download%2FENCFF965BPU.hic": "42717376107,54779", - "www.encodeproject.org%2Ffiles%2FENCFF842DUO%2F%40%40download%2FENCFF842DUO.hic": "39553892515,54779", - "www.encodeproject.org%2Ffiles%2FENCFF417GBZ%2F%40%40download%2FENCFF417GBZ.hic": "45544785452,54779", - "www.encodeproject.org%2Ffiles%2FENCFF499BVX%2F%40%40download%2FENCFF499BVX.hic": "40900674170,54779", - "www.encodeproject.org%2Ffiles%2FENCFF136XCV%2F%40%40download%2FENCFF136XCV.hic": "47700392974,54779", - "www.encodeproject.org%2Ffiles%2FENCFF224HKR%2F%40%40download%2FENCFF224HKR.hic": "40426005932,54779", - "www.encodeproject.org%2Ffiles%2FENCFF711XSR%2F%40%40download%2FENCFF711XSR.hic": "41434581949,54779", - "www.encodeproject.org%2Ffiles%2FENCFF660JWA%2F%40%40download%2FENCFF660JWA.hic": "54201632697,54779", - "www.encodeproject.org%2Ffiles%2FENCFF081PMO%2F%40%40download%2FENCFF081PMO.hic": "53428285130,54779", - "www.encodeproject.org%2Ffiles%2FENCFF799QGA%2F%40%40download%2FENCFF799QGA.hic": "1228682189,36479", - "www.encodeproject.org%2Ffiles%2FENCFF473CAA%2F%40%40download%2FENCFF473CAA.hic": "1077514950,36479", - "www.encodeproject.org%2Ffiles%2FENCFF663FRL%2F%40%40download%2FENCFF663FRL.hic": "39843938245,54779", - "www.encodeproject.org%2Ffiles%2FENCFF341WOY%2F%40%40download%2FENCFF341WOY.hic": "34792598619,54779", - "www.encodeproject.org%2Ffiles%2FENCFF515ZBF%2F%40%40download%2FENCFF515ZBF.hic": "41779230923,54779", - "www.encodeproject.org%2Ffiles%2FENCFF545GBW%2F%40%40download%2FENCFF545GBW.hic": "38351980358,54779", - "www.encodeproject.org%2Ffiles%2FENCFF252ANV%2F%40%40download%2FENCFF252ANV.hic": "37668839771,54779", - "www.encodeproject.org%2Ffiles%2FENCFF912NDK%2F%40%40download%2FENCFF912NDK.hic": "21196851956,54779", - "www.encodeproject.org%2Ffiles%2FENCFF683PLM%2F%40%40download%2FENCFF683PLM.hic": "21849338763,54779", - "www.encodeproject.org%2Ffiles%2FENCFF355NFJ%2F%40%40download%2FENCFF355NFJ.hic": "47880627268,54779", - "www.encodeproject.org%2Ffiles%2FENCFF507WEW%2F%40%40download%2FENCFF507WEW.hic": "35777782924,54779", - "www.encodeproject.org%2Ffiles%2FENCFF241MSL%2F%40%40download%2FENCFF241MSL.hic": "22507408288,54779", - "www.encodeproject.org%2Ffiles%2FENCFF135MUT%2F%40%40download%2FENCFF135MUT.hic": "24168734040,54779", - "www.encodeproject.org%2Ffiles%2FENCFF459FRB%2F%40%40download%2FENCFF459FRB.hic": "37166770103,54779", - "www.encodeproject.org%2Ffiles%2FENCFF705YZH%2F%40%40download%2FENCFF705YZH.hic": "44679182442,54779", - "www.encodeproject.org%2Ffiles%2FENCFF395INO%2F%40%40download%2FENCFF395INO.hic": "56727346538,54779", - "www.encodeproject.org%2Ffiles%2FENCFF736ITL%2F%40%40download%2FENCFF736ITL.hic": "49036286185,54779", - "www.encodeproject.org%2Ffiles%2FENCFF546TZN%2F%40%40download%2FENCFF546TZN.hic": "33195126348,54779", - "www.encodeproject.org%2Ffiles%2FENCFF706SFK%2F%40%40download%2FENCFF706SFK.hic": "3271831702,36479", - "www.encodeproject.org%2Ffiles%2FENCFF922ERE%2F%40%40download%2FENCFF922ERE.hic": "12476647122,36479", - "www.encodeproject.org%2Ffiles%2FENCFF876OWE%2F%40%40download%2FENCFF876OWE.hic": "1538692704,47429", - "www.encodeproject.org%2Ffiles%2FENCFF227XJZ%2F%40%40download%2FENCFF227XJZ.hic": "1925617685,36479", - "www.encodeproject.org%2Ffiles%2FENCFF053BXY%2F%40%40download%2FENCFF053BXY.hic": "1032237652,36479", - "www.encodeproject.org%2Ffiles%2FENCFF014VMM%2F%40%40download%2FENCFF014VMM.hic": "1564021703,36479", - "www.encodeproject.org%2Ffiles%2FENCFF563XES%2F%40%40download%2FENCFF563XES.hic": "1489180508,36479", - "www.encodeproject.org%2Ffiles%2FENCFF482LGO%2F%40%40download%2FENCFF482LGO.hic": "1208778887,36479", - "www.encodeproject.org%2Ffiles%2FENCFF216QQM%2F%40%40download%2FENCFF216QQM.hic": "6293163571,47429", - "www.encodeproject.org%2Ffiles%2FENCFF256UOW%2F%40%40download%2FENCFF256UOW.hic": "6293163571,47429", - "www.encodeproject.org%2Ffiles%2FENCFF791UZC%2F%40%40download%2FENCFF791UZC.hic": "37029615181,54779", - "www.encodeproject.org%2Ffiles%2FENCFF911AHQ%2F%40%40download%2FENCFF911AHQ.hic": "34246649165,54779", - "www.encodeproject.org%2Ffiles%2FENCFF491AOR%2F%40%40download%2FENCFF491AOR.hic": "558663570,36479", - "www.encodeproject.org%2Ffiles%2FENCFF307PDL%2F%40%40download%2FENCFF307PDL.hic": "525321519,36479", - "www.encodeproject.org%2Ffiles%2FENCFF773ITV%2F%40%40download%2FENCFF773ITV.hic": "295464771,36479", - "www.encodeproject.org%2Ffiles%2FENCFF198SSL%2F%40%40download%2FENCFF198SSL.hic": "500142476,36479", - "www.encodeproject.org%2Ffiles%2FENCFF251UEF%2F%40%40download%2FENCFF251UEF.hic": "567443575,36479", - "www.encodeproject.org%2Ffiles%2FENCFF942LTN%2F%40%40download%2FENCFF942LTN.hic": "4430960222,36479", - "www.encodeproject.org%2Ffiles%2FENCFF543USQ%2F%40%40download%2FENCFF543USQ.hic": "5005263062,36479", - "www.encodeproject.org%2Ffiles%2FENCFF434XQU%2F%40%40download%2FENCFF434XQU.hic": "25506511674,54779", - "www.encodeproject.org%2Ffiles%2FENCFF318GOM%2F%40%40download%2FENCFF318GOM.hic": "44750824314,54779", - "www.encodeproject.org%2Ffiles%2FENCFF004TKY%2F%40%40download%2FENCFF004TKY.hic": "20705661833,54779", - "www.encodeproject.org%2Ffiles%2FENCFF493YNC%2F%40%40download%2FENCFF493YNC.hic": "53407154984,54779", - "www.encodeproject.org%2Ffiles%2FENCFF334XXU%2F%40%40download%2FENCFF334XXU.hic": "14341194962,47429", - "www.encodeproject.org%2Ffiles%2FENCFF569RJM%2F%40%40download%2FENCFF569RJM.hic": "1922066634,36479", - "www.encodeproject.org%2Ffiles%2FENCFF076LWH%2F%40%40download%2FENCFF076LWH.hic": "39406255845,54779", - "www.encodeproject.org%2Ffiles%2FENCFF977XWK%2F%40%40download%2FENCFF977XWK.hic": "20563512962,54779", - "www.encodeproject.org%2Ffiles%2FENCFF127TPS%2F%40%40download%2FENCFF127TPS.hic": "21032070512,54779", - "www.encodeproject.org%2Ffiles%2FENCFF480KLP%2F%40%40download%2FENCFF480KLP.hic": "33115569647,54779", - "www.encodeproject.org%2Ffiles%2FENCFF281ILS%2F%40%40download%2FENCFF281ILS.hic": "28236353584,54779", - "www.encodeproject.org%2Ffiles%2FENCFF129LMU%2F%40%40download%2FENCFF129LMU.hic": "35247096013,54779", - "www.encodeproject.org%2Ffiles%2FENCFF759YCW%2F%40%40download%2FENCFF759YCW.hic": "16058537743,32102", - "www.encodeproject.org%2Ffiles%2FENCFF045YOM%2F%40%40download%2FENCFF045YOM.hic": "19775445828,32102", - "www.encodeproject.org%2Ffiles%2FENCFF013TGD%2F%40%40download%2FENCFF013TGD.hic": "4208420532,36479", - "www.encodeproject.org%2Ffiles%2FENCFF929RPW%2F%40%40download%2FENCFF929RPW.hic": "1974260276,36479", - "www.encodeproject.org%2Ffiles%2FENCFF996XEO%2F%40%40download%2FENCFF996XEO.hic": "2072918865,36479", - "www.encodeproject.org%2Ffiles%2FENCFF097SKJ%2F%40%40download%2FENCFF097SKJ.hic": "1983524001,36479", - "www.encodeproject.org%2Ffiles%2FENCFF464KRA%2F%40%40download%2FENCFF464KRA.hic": "1957300131,36479", - "www.encodeproject.org%2Ffiles%2FENCFF406HHC%2F%40%40download%2FENCFF406HHC.hic": "3854527235,36479", - "www.encodeproject.org%2Ffiles%2FENCFF080DPJ%2F%40%40download%2FENCFF080DPJ.hic": "19953768024,47429", - "www.encodeproject.org%2Ffiles%2FENCFF621AIY%2F%40%40download%2FENCFF621AIY.hic": "26781700010,54779", - "www.encodeproject.org%2Ffiles%2FENCFF366ERB%2F%40%40download%2FENCFF366ERB.hic": "1049184239,36479", - "www.encodeproject.org%2Ffiles%2FENCFF997RGL%2F%40%40download%2FENCFF997RGL.hic": "2521167549,36479", - "www.encodeproject.org%2Ffiles%2FENCFF029MPB%2F%40%40download%2FENCFF029MPB.hic": "1854711185,36479", - "www.encodeproject.org%2Ffiles%2FENCFF043EEE%2F%40%40download%2FENCFF043EEE.hic": "2924133032,36479", - "www.encodeproject.org%2Ffiles%2FENCFF920CJR%2F%40%40download%2FENCFF920CJR.hic": "3011577886,36479", - "www.encodeproject.org%2Ffiles%2FENCFF928NJV%2F%40%40download%2FENCFF928NJV.hic": "2778936244,36479", - "www.encodeproject.org%2Ffiles%2FENCFF894GLR%2F%40%40download%2FENCFF894GLR.hic": "2831733099,36479", - "www.encodeproject.org%2Ffiles%2FENCFF303PCK%2F%40%40download%2FENCFF303PCK.hic": "688704435,36479", - "www.encodeproject.org%2Ffiles%2FENCFF999YXX%2F%40%40download%2FENCFF999YXX.hic": "9255069996,56883", - "www.encodeproject.org%2Ffiles%2FENCFF685BLG%2F%40%40download%2FENCFF685BLG.hic": "16797022992,47429", - "www.encodeproject.org%2Ffiles%2FENCFF188SSH%2F%40%40download%2FENCFF188SSH.hic": "16797023050,47429", - "www.encodeproject.org%2Ffiles%2FENCFF465ESX%2F%40%40download%2FENCFF465ESX.hic": "13489465953,32102", - "www.encodeproject.org%2Ffiles%2FENCFF493SFI%2F%40%40download%2FENCFF493SFI.hic": "30033046818,54779", - "www.encodeproject.org%2Ffiles%2FENCFF235LCO%2F%40%40download%2FENCFF235LCO.hic": "38572174589,54779", - "www.encodeproject.org%2Ffiles%2FENCFF625VNK%2F%40%40download%2FENCFF625VNK.hic": "45202258438,54779", - "www.encodeproject.org%2Ffiles%2FENCFF304HMS%2F%40%40download%2FENCFF304HMS.hic": "36994445315,54779", - "www.encodeproject.org%2Ffiles%2FENCFF605CEN%2F%40%40download%2FENCFF605CEN.hic": "40358346301,54779", - "www.encodeproject.org%2Ffiles%2FENCFF086ORS%2F%40%40download%2FENCFF086ORS.hic": "22650781304,54779", - "www.encodeproject.org%2Ffiles%2FENCFF237UKR%2F%40%40download%2FENCFF237UKR.hic": "41516707246,54779", - "www.encodeproject.org%2Ffiles%2FENCFF004YZQ%2F%40%40download%2FENCFF004YZQ.hic": "71900665326,54779", - "www.encodeproject.org%2Ffiles%2FENCFF104THR%2F%40%40download%2FENCFF104THR.hic": "15172410632,54779", - "www.encodeproject.org%2Ffiles%2FENCFF807IRK%2F%40%40download%2FENCFF807IRK.hic": "17346637451,54779", - "www.encodeproject.org%2Ffiles%2FENCFF193CQL%2F%40%40download%2FENCFF193CQL.hic": "55726903245,54779", - "www.encodeproject.org%2Ffiles%2FENCFF700DEX%2F%40%40download%2FENCFF700DEX.hic": "20231399798,54779", - "www.encodeproject.org%2Ffiles%2FENCFF234MDO%2F%40%40download%2FENCFF234MDO.hic": "24635312640,54779", - "www.encodeproject.org%2Ffiles%2FENCFF181ROW%2F%40%40download%2FENCFF181ROW.hic": "26883606497,54779", - "www.encodeproject.org%2Ffiles%2FENCFF896OFN%2F%40%40download%2FENCFF896OFN.hic": "36952196833,54779", - "www.encodeproject.org%2Ffiles%2FENCFF573OPJ%2F%40%40download%2FENCFF573OPJ.hic": "36685546919,54779", - "www.encodeproject.org%2Ffiles%2FENCFF028RXH%2F%40%40download%2FENCFF028RXH.hic": "31053919206,54779", - "www.encodeproject.org%2Ffiles%2FENCFF156GGD%2F%40%40download%2FENCFF156GGD.hic": "35284134289,54779", - "www.encodeproject.org%2Ffiles%2FENCFF496GEU%2F%40%40download%2FENCFF496GEU.hic": "44659660933,54779", - "www.encodeproject.org%2Ffiles%2FENCFF945TUH%2F%40%40download%2FENCFF945TUH.hic": "3898570191,35639", - "www.encodeproject.org%2Ffiles%2FENCFF698KFV%2F%40%40download%2FENCFF698KFV.hic": "4427896684,35751", - "www.encodeproject.org%2Ffiles%2FENCFF239BHZ%2F%40%40download%2FENCFF239BHZ.hic": "1718552021,36479", - "www.encodeproject.org%2Ffiles%2FENCFF277LAN%2F%40%40download%2FENCFF277LAN.hic": "4542391336,36479", - "www.encodeproject.org%2Ffiles%2FENCFF397CMD%2F%40%40download%2FENCFF397CMD.hic": "2832016430,36479", - "www.encodeproject.org%2Ffiles%2FENCFF778OYA%2F%40%40download%2FENCFF778OYA.hic": "14067187484,47429", - "www.encodeproject.org%2Ffiles%2FENCFF775VSU%2F%40%40download%2FENCFF775VSU.hic": "14067187484,47429", - "www.encodeproject.org%2Ffiles%2FENCFF812THZ%2F%40%40download%2FENCFF812THZ.hic": "9667720429,36479", - "www.encodeproject.org%2Ffiles%2FENCFF777KBU%2F%40%40download%2FENCFF777KBU.hic": "5058284320,36479", - "www.encodeproject.org%2Ffiles%2FENCFF688KOY%2F%40%40download%2FENCFF688KOY.hic": "4198695833,36479", - "www.encodeproject.org%2Ffiles%2FENCFF223UBX%2F%40%40download%2FENCFF223UBX.hic": "1206064037,36479", - "www.encodeproject.org%2Ffiles%2FENCFF273XBU%2F%40%40download%2FENCFF273XBU.hic": "44085607579,54779", - "www.encodeproject.org%2Ffiles%2FENCFF952JZV%2F%40%40download%2FENCFF952JZV.hic": "44728845246,54779", - "www.encodeproject.org%2Ffiles%2FENCFF643NDM%2F%40%40download%2FENCFF643NDM.hic": "35877886780,54779", - "www.encodeproject.org%2Ffiles%2FENCFF586MQY%2F%40%40download%2FENCFF586MQY.hic": "71158037547,54779", - "www.encodeproject.org%2Ffiles%2FENCFF251VFA%2F%40%40download%2FENCFF251VFA.hic": "40089479399,54779", - "www.encodeproject.org%2Ffiles%2FENCFF033WGK%2F%40%40download%2FENCFF033WGK.hic": "30802023728,54779", - "www.encodeproject.org%2Ffiles%2FENCFF649OHR%2F%40%40download%2FENCFF649OHR.hic": "28203184265,54779", - "www.encodeproject.org%2Ffiles%2FENCFF782WVZ%2F%40%40download%2FENCFF782WVZ.hic": "37248221674,54779", - "www.encodeproject.org%2Ffiles%2FENCFF579CAR%2F%40%40download%2FENCFF579CAR.hic": "39662025395,54779", - "www.encodeproject.org%2Ffiles%2FENCFF514XWQ%2F%40%40download%2FENCFF514XWQ.hic": "1319613701,36479", - "www.encodeproject.org%2Ffiles%2FENCFF666USK%2F%40%40download%2FENCFF666USK.hic": "15051670107,32102", - "www.encodeproject.org%2Ffiles%2FENCFF047SDP%2F%40%40download%2FENCFF047SDP.hic": "1357076705,16438", - "www.encodeproject.org%2Ffiles%2FENCFF584LEP%2F%40%40download%2FENCFF584LEP.hic": "9314176858,36479", - "www.encodeproject.org%2Ffiles%2FENCFF671SOE%2F%40%40download%2FENCFF671SOE.hic": "3273732256,16438", - "www.encodeproject.org%2Ffiles%2FENCFF702LAP%2F%40%40download%2FENCFF702LAP.hic": "1800427500,31682", - "www.encodeproject.org%2Ffiles%2FENCFF339PON%2F%40%40download%2FENCFF339PON.hic": "5394351199,31514", - "www.encodeproject.org%2Ffiles%2FENCFF741QPR%2F%40%40download%2FENCFF741QPR.hic": "4271510019,30139", - "www.encodeproject.org%2Ffiles%2FENCFF103ANX%2F%40%40download%2FENCFF103ANX.hic": "4439745804,30083", - "www.encodeproject.org%2Ffiles%2FENCFF395SBC%2F%40%40download%2FENCFF395SBC.hic": "1596732351,31850", - "www.encodeproject.org%2Ffiles%2FENCFF289WNN%2F%40%40download%2FENCFF289WNN.hic": "8632980535,32102", - "www.encodeproject.org%2Ffiles%2FENCFF381EAU%2F%40%40download%2FENCFF381EAU.hic": "1702476311,36479", - "www.encodeproject.org%2Ffiles%2FENCFF976FEY%2F%40%40download%2FENCFF976FEY.hic": "1448279040,36479", - "www.encodeproject.org%2Ffiles%2FENCFF485LVS%2F%40%40download%2FENCFF485LVS.hic": "1593610856,36479", - "www.encodeproject.org%2Ffiles%2FENCFF143VJV%2F%40%40download%2FENCFF143VJV.hic": "1422312076,36479", - "www.encodeproject.org%2Ffiles%2FENCFF588NHX%2F%40%40download%2FENCFF588NHX.hic": "3943637009,36479", - "www.encodeproject.org%2Ffiles%2FENCFF768UBD%2F%40%40download%2FENCFF768UBD.hic": "24786676166,36479", - "www.encodeproject.org%2Ffiles%2FENCFF965PEE%2F%40%40download%2FENCFF965PEE.hic": "29387092778,47429", - "www.encodeproject.org%2Ffiles%2FENCFF702IFC%2F%40%40download%2FENCFF702IFC.hic": "29387092778,47429", - "www.encodeproject.org%2Ffiles%2FENCFF288DNV%2F%40%40download%2FENCFF288DNV.hic": "10313429504,36479", - "www.encodeproject.org%2Ffiles%2FENCFF698HWZ%2F%40%40download%2FENCFF698HWZ.hic": "10962849269,47429", - "www.encodeproject.org%2Ffiles%2FENCFF355OWW%2F%40%40download%2FENCFF355OWW.hic": "3219571601,36479", - "www.encodeproject.org%2Ffiles%2FENCFF177TYX%2F%40%40download%2FENCFF177TYX.hic": "10325679706,36479", - "www.encodeproject.org%2Ffiles%2FENCFF542BHD%2F%40%40download%2FENCFF542BHD.hic": "11085397879,47429", - "www.encodeproject.org%2Ffiles%2FENCFF684IFW%2F%40%40download%2FENCFF684IFW.hic": "11085397879,47429", - "www.encodeproject.org%2Ffiles%2FENCFF592UHE%2F%40%40download%2FENCFF592UHE.hic": "21363948089,32102", - "www.encodeproject.org%2Ffiles%2FENCFF779XIS%2F%40%40download%2FENCFF779XIS.hic": "9517383271,36479", - "www.encodeproject.org%2Ffiles%2FENCFF518PSL%2F%40%40download%2FENCFF518PSL.hic": "7500581463,36479", - "www.encodeproject.org%2Ffiles%2FENCFF275GBB%2F%40%40download%2FENCFF275GBB.hic": "7889407162,36479", - "www.encodeproject.org%2Ffiles%2FENCFF634KXI%2F%40%40download%2FENCFF634KXI.hic": "6430702966,36479", - "www.encodeproject.org%2Ffiles%2FENCFF337QPM%2F%40%40download%2FENCFF337QPM.hic": "8529733887,36479", - "www.encodeproject.org%2Ffiles%2FENCFF162KMP%2F%40%40download%2FENCFF162KMP.hic": "5615896908,36479", - "www.encodeproject.org%2Ffiles%2FENCFF992VTE%2F%40%40download%2FENCFF992VTE.hic": "7328975027,36479", - "www.encodeproject.org%2Ffiles%2FENCFF464WXY%2F%40%40download%2FENCFF464WXY.hic": "5715339664,36479", - "www.encodeproject.org%2Ffiles%2FENCFF752EGH%2F%40%40download%2FENCFF752EGH.hic": "1733758743,36479", - "www.encodeproject.org%2Ffiles%2FENCFF474UJM%2F%40%40download%2FENCFF474UJM.hic": "222309548,18679", - "www.encodeproject.org%2Ffiles%2FENCFF531UPZ%2F%40%40download%2FENCFF531UPZ.hic": "1827756846,36479", - "www.encodeproject.org%2Ffiles%2FENCFF022VHA%2F%40%40download%2FENCFF022VHA.hic": "244983451,18679", - "www.encodeproject.org%2Ffiles%2FENCFF732NGR%2F%40%40download%2FENCFF732NGR.hic": "1679484567,36479", - "www.encodeproject.org%2Ffiles%2FENCFF513VSF%2F%40%40download%2FENCFF513VSF.hic": "28397932940,36479", - "www.encodeproject.org%2Ffiles%2FENCFF750AOC%2F%40%40download%2FENCFF750AOC.hic": "36471430712,47429", - "www.encodeproject.org%2Ffiles%2FENCFF219YOB%2F%40%40download%2FENCFF219YOB.hic": "2859767211,26979", - "www.encodeproject.org%2Ffiles%2FENCFF604YDD%2F%40%40download%2FENCFF604YDD.hic": "3549694085,26979", - "www.encodeproject.org%2Ffiles%2FENCFF746AMV%2F%40%40download%2FENCFF746AMV.hic": "2954867135,26979", - "www.encodeproject.org%2Ffiles%2FENCFF845ZEB%2F%40%40download%2FENCFF845ZEB.hic": "2763039282,26979", - "www.encodeproject.org%2Ffiles%2FENCFF570LWS%2F%40%40download%2FENCFF570LWS.hic": "2861588289,26979", - "www.encodeproject.org%2Ffiles%2FENCFF883YVR%2F%40%40download%2FENCFF883YVR.hic": "2433679887,26979", - "www.encodeproject.org%2Ffiles%2FENCFF056VLK%2F%40%40download%2FENCFF056VLK.hic": "2502986910,26979", - "www.encodeproject.org%2Ffiles%2FENCFF532DUQ%2F%40%40download%2FENCFF532DUQ.hic": "3172615899,26979", - "www.encodeproject.org%2Ffiles%2FENCFF723PYJ%2F%40%40download%2FENCFF723PYJ.hic": "10292839095,36479", - "www.encodeproject.org%2Ffiles%2FENCFF991SGJ%2F%40%40download%2FENCFF991SGJ.hic": "13072407683,32102", - "www.encodeproject.org%2Ffiles%2FENCFF885UZI%2F%40%40download%2FENCFF885UZI.hic": "1201881201,16438", - "www.encodeproject.org%2Ffiles%2FENCFF287KXA%2F%40%40download%2FENCFF287KXA.hic": "14705801988,32102", - "www.encodeproject.org%2Ffiles%2FENCFF335HYI%2F%40%40download%2FENCFF335HYI.hic": "20366756545,32102", - "www.encodeproject.org%2Ffiles%2FENCFF121YPY%2F%40%40download%2FENCFF121YPY.hic": "2760104016,26979", - "www.encodeproject.org%2Ffiles%2FENCFF675SJE%2F%40%40download%2FENCFF675SJE.hic": "3751779995,26979", - "www.encodeproject.org%2Ffiles%2FENCFF876LAW%2F%40%40download%2FENCFF876LAW.hic": "4032376256,26979", - "www.encodeproject.org%2Ffiles%2FENCFF740KVX%2F%40%40download%2FENCFF740KVX.hic": "3202490322,26979", - "www.encodeproject.org%2Ffiles%2FENCFF977OQV%2F%40%40download%2FENCFF977OQV.hic": "2919735477,26979", - "www.encodeproject.org%2Ffiles%2FENCFF525EFN%2F%40%40download%2FENCFF525EFN.hic": "2394748073,26979", - "www.encodeproject.org%2Ffiles%2FENCFF690QRC%2F%40%40download%2FENCFF690QRC.hic": "3183023394,26979", - "www.encodeproject.org%2Ffiles%2FENCFF452FWS%2F%40%40download%2FENCFF452FWS.hic": "2951805127,26979", - "www.encodeproject.org%2Ffiles%2FENCFF089KBG%2F%40%40download%2FENCFF089KBG.hic": "2531936700,26979", - "www.encodeproject.org%2Ffiles%2FENCFF939ARM%2F%40%40download%2FENCFF939ARM.hic": "3066385212,26979", - "www.encodeproject.org%2Ffiles%2FENCFF401ZAN%2F%40%40download%2FENCFF401ZAN.hic": "3008677144,26979", - "www.encodeproject.org%2Ffiles%2FENCFF378RZT%2F%40%40download%2FENCFF378RZT.hic": "2830232168,26979", - "www.encodeproject.org%2Ffiles%2FENCFF304AVD%2F%40%40download%2FENCFF304AVD.hic": "6164439305,50358", - "www.encodeproject.org%2Ffiles%2FENCFF453DBX%2F%40%40download%2FENCFF453DBX.hic": "6775246670,36479", - "www.encodeproject.org%2Ffiles%2FENCFF590VOM%2F%40%40download%2FENCFF590VOM.hic": "6443478922,36479", - "www.encodeproject.org%2Ffiles%2FENCFF246DOF%2F%40%40download%2FENCFF246DOF.hic": "6837914659,36479", - "www.encodeproject.org%2Ffiles%2FENCFF125FXX%2F%40%40download%2FENCFF125FXX.hic": "9736232550,36479", - "www.encodeproject.org%2Ffiles%2FENCFF241RAY%2F%40%40download%2FENCFF241RAY.hic": "7686758397,36479", - "www.encodeproject.org%2Ffiles%2FENCFF415XWQ%2F%40%40download%2FENCFF415XWQ.hic": "6973092068,36479", - "www.encodeproject.org%2Ffiles%2FENCFF374EBH%2F%40%40download%2FENCFF374EBH.hic": "8557459058,36479", - "www.encodeproject.org%2Ffiles%2FENCFF263YWR%2F%40%40download%2FENCFF263YWR.hic": "331586820,18679", - "www.encodeproject.org%2Ffiles%2FENCFF280CGS%2F%40%40download%2FENCFF280CGS.hic": "1743569614,36479", - "www.encodeproject.org%2Ffiles%2FENCFF553ZNS%2F%40%40download%2FENCFF553ZNS.hic": "1717253636,36479", - "www.encodeproject.org%2Ffiles%2FENCFF451VOI%2F%40%40download%2FENCFF451VOI.hic": "1626927468,36479", - "www.encodeproject.org%2Ffiles%2FENCFF420MQO%2F%40%40download%2FENCFF420MQO.hic": "31055961677,36479", - "www.encodeproject.org%2Ffiles%2FENCFF301BWY%2F%40%40download%2FENCFF301BWY.hic": "38902429246,47429", - "www.encodeproject.org%2Ffiles%2FENCFF606XNW%2F%40%40download%2FENCFF606XNW.hic": "1009699327,36479", - "www.encodeproject.org%2Ffiles%2FENCFF439ZOU%2F%40%40download%2FENCFF439ZOU.hic": "12381714313,36479", - "www.encodeproject.org%2Ffiles%2FENCFF499SYK%2F%40%40download%2FENCFF499SYK.hic": "13182654663,47429", - "www.encodeproject.org%2Ffiles%2FENCFF532LFI%2F%40%40download%2FENCFF532LFI.hic": "8286030286,36479", - "www.encodeproject.org%2Ffiles%2FENCFF020DPP%2F%40%40download%2FENCFF020DPP.hic": "23521952420,47429", - "www.encodeproject.org%2Ffiles%2FENCFF306VTV%2F%40%40download%2FENCFF306VTV.hic": "23521952480,47429", - "www.encodeproject.org%2Ffiles%2FENCFF399IHE%2F%40%40download%2FENCFF399IHE.hic": "10216571232,36479", - "www.encodeproject.org%2Ffiles%2FENCFF944AII%2F%40%40download%2FENCFF944AII.hic": "12567308552,47429", - "www.encodeproject.org%2Ffiles%2FENCFF230HVV%2F%40%40download%2FENCFF230HVV.hic": "8629849711,36479", - "www.encodeproject.org%2Ffiles%2FENCFF174LAF%2F%40%40download%2FENCFF174LAF.hic": "9446506633,47429", - "www.encodeproject.org%2Ffiles%2FENCFF898HRO%2F%40%40download%2FENCFF898HRO.hic": "9446506633,47429", - "www.encodeproject.org%2Ffiles%2FENCFF429MOR%2F%40%40download%2FENCFF429MOR.hic": "1455757398,36479", - "www.encodeproject.org%2Ffiles%2FENCFF061NXV%2F%40%40download%2FENCFF061NXV.hic": "1710915891,36479", - "www.encodeproject.org%2Ffiles%2FENCFF434PYS%2F%40%40download%2FENCFF434PYS.hic": "1832274903,36479", - "www.encodeproject.org%2Ffiles%2FENCFF704HHX%2F%40%40download%2FENCFF704HHX.hic": "1768142834,36479", - "www.encodeproject.org%2Ffiles%2FENCFF349DPM%2F%40%40download%2FENCFF349DPM.hic": "4316041260,36479", - "www.encodeproject.org%2Ffiles%2FENCFF718AWL%2F%40%40download%2FENCFF718AWL.hic": "39544267907,58932", - "www.encodeproject.org%2Ffiles%2FENCFF065LSP%2F%40%40download%2FENCFF065LSP.hic": "24929805283,55874", - "www.encodeproject.org%2Ffiles%2FENCFF632MFV%2F%40%40download%2FENCFF632MFV.hic": "22333105467,55798", - "www.encodeproject.org%2Ffiles%2FENCFF179HVU%2F%40%40download%2FENCFF179HVU.hic": "2659219603,36479", - "www.encodeproject.org%2Ffiles%2FENCFF791SPZ%2F%40%40download%2FENCFF791SPZ.hic": "2537491657,36479", - "www.encodeproject.org%2Ffiles%2FENCFF211ZWF%2F%40%40download%2FENCFF211ZWF.hic": "3512141227,36479", - "www.encodeproject.org%2Ffiles%2FENCFF614BNU%2F%40%40download%2FENCFF614BNU.hic": "5252155462,36479", - "www.encodeproject.org%2Ffiles%2FENCFF891DLM%2F%40%40download%2FENCFF891DLM.hic": "2549095612,36479", - "www.encodeproject.org%2Ffiles%2FENCFF056EXT%2F%40%40download%2FENCFF056EXT.hic": "2219014704,36479", - "www.encodeproject.org%2Ffiles%2FENCFF776DSS%2F%40%40download%2FENCFF776DSS.hic": "3920308353,36479", - "www.encodeproject.org%2Ffiles%2FENCFF814LQF%2F%40%40download%2FENCFF814LQF.hic": "1349480197,36479", - "www.encodeproject.org%2Ffiles%2FENCFF513ZNA%2F%40%40download%2FENCFF513ZNA.hic": "2638868195,36479", - "www.encodeproject.org%2Ffiles%2FENCFF692IOL%2F%40%40download%2FENCFF692IOL.hic": "3106768498,36479", - "www.encodeproject.org%2Ffiles%2FENCFF294WZY%2F%40%40download%2FENCFF294WZY.hic": "2211089761,36479", - "www.encodeproject.org%2Ffiles%2FENCFF339UWS%2F%40%40download%2FENCFF339UWS.hic": "2142759055,36479", - "www.encodeproject.org%2Ffiles%2FENCFF835FSK%2F%40%40download%2FENCFF835FSK.hic": "3919821739,36479", - "www.encodeproject.org%2Ffiles%2FENCFF328BMB%2F%40%40download%2FENCFF328BMB.hic": "2550686152,36479", - "www.encodeproject.org%2Ffiles%2FENCFF897RTY%2F%40%40download%2FENCFF897RTY.hic": "1323294397,36479", - "www.encodeproject.org%2Ffiles%2FENCFF306MWH%2F%40%40download%2FENCFF306MWH.hic": "1665386199,36479", - "www.encodeproject.org%2Ffiles%2FENCFF039YUJ%2F%40%40download%2FENCFF039YUJ.hic": "2335679939,36479", - "www.encodeproject.org%2Ffiles%2FENCFF468QIN%2F%40%40download%2FENCFF468QIN.hic": "3352516594,36479", - "www.encodeproject.org%2Ffiles%2FENCFF364WXU%2F%40%40download%2FENCFF364WXU.hic": "3959043175,36479", - "www.encodeproject.org%2Ffiles%2FENCFF373MSH%2F%40%40download%2FENCFF373MSH.hic": "4429550624,36479", - "www.encodeproject.org%2Ffiles%2FENCFF959EGQ%2F%40%40download%2FENCFF959EGQ.hic": "2475218228,36479", - "www.encodeproject.org%2Ffiles%2FENCFF624XMK%2F%40%40download%2FENCFF624XMK.hic": "3527855681,36479", - "www.encodeproject.org%2Ffiles%2FENCFF445OKS%2F%40%40download%2FENCFF445OKS.hic": "3369125589,36479", - "www.encodeproject.org%2Ffiles%2FENCFF239QDV%2F%40%40download%2FENCFF239QDV.hic": "1960069888,36479", - "www.encodeproject.org%2Ffiles%2FENCFF645AVM%2F%40%40download%2FENCFF645AVM.hic": "4969006589,36479", - "www.encodeproject.org%2Ffiles%2FENCFF494IPI%2F%40%40download%2FENCFF494IPI.hic": "1565483792,36479", - "www.encodeproject.org%2Ffiles%2FENCFF753IXE%2F%40%40download%2FENCFF753IXE.hic": "2892400648,36479", - "www.encodeproject.org%2Ffiles%2FENCFF731GXX%2F%40%40download%2FENCFF731GXX.hic": "5131381303,36479", - "www.encodeproject.org%2Ffiles%2FENCFF369CAQ%2F%40%40download%2FENCFF369CAQ.hic": "4236629448,36479", - "www.encodeproject.org%2Ffiles%2FENCFF053VBX%2F%40%40download%2FENCFF053VBX.hic": "54305946375,47429", - "www.encodeproject.org%2Ffiles%2FENCFF555ISR%2F%40%40download%2FENCFF555ISR.hic": "54305946434,47429", - "www.encodeproject.org%2Ffiles%2FENCFF964RSP%2F%40%40download%2FENCFF964RSP.hic": "12065485229,36479", - "www.encodeproject.org%2Ffiles%2FENCFF234MZQ%2F%40%40download%2FENCFF234MZQ.hic": "17507142760,47429", - "www.encodeproject.org%2Ffiles%2FENCFF994CEG%2F%40%40download%2FENCFF994CEG.hic": "17507142760,47429", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fb068e787-bbdd-49e2-9f6d-7a0e9f065d6e%2F4DNFIHSUIRFY.hic": "2701182442,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3768b89a-e124-40eb-8acd-94a4fdd35807%2F4DNFIXTAS6EE.hic": "3283740601,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F9c513602-5abb-4088-8415-c827c381ab0d%2F4DNFIC3JD6O2.hic": "4896075767,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fde954dad-1849-4c23-beb4-bf893b7d76c9%2F4DNFIGY85S4W.hic": "3364151996,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fe1befa6e-8067-4296-8db2-67d2a2458985%2F4DNFI2LTNXME.hic": "3699291418,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fbb3307fd-7162-477a-87c5-52f12d03befc%2F4DNFID162B9J.hic": "3576428773,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8597cdae-8319-42d9-9175-3f77aaee34e1%2F4DNFIQWS3632.hic": "4022561190,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F327f091d-6a63-47c4-9752-2dff303a13d9%2F4DNFI6GFHB6G.hic": "4239331168,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd70dc3b8-48a7-42c2-bd23-80bc44fc2266%2F4DNFIS5F6EBL.hic": "4404671861,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F77df7bf8-6a3d-407a-8968-4ca1e78d2269%2F4DNFIF2D3TL9.hic": "4793989394,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc8f7cc35-d2ef-4717-9009-c02154050fbf%2F4DNFI6EIFUZI.hic": "3370273763,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F98449d79-30d1-4e32-801d-07435819a42f%2F4DNFIRKGMZRQ.hic": "4669813207,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd4fe1844-2493-4722-8b98-34a93a4bb7d8%2F4DNFIQWD8ZYD.hic": "5379889057,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F1ee40499-1de4-47ff-b540-d9a65943c6b8%2F4DNFIX7H3CE2.hic": "4857679239,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fac016170-23a7-4111-8773-353d6c150f34%2F4DNFIO21YDCV.hic": "4695989644,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F1faea4e7-9a32-466e-a826-0bfdab6cd915%2F4DNFIUE5RAS6.hic": "4788044799,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fcbd396ed-11bb-404f-aed9-ef10abc258e6%2F4DNFIFI6NIKJ.hic": "2069414927,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Faf3f78db-ae92-4215-bcae-76d30c617e5d%2F4DNFIL5K3MA1.hic": "2585598247,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F66fc2893-224e-48b4-bdb0-25e022dedd03%2F4DNFIPV5KFMK.hic": "2060965679,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F2b39781d-aadc-434f-abe3-562d61308fdd%2F4DNFIW8TIFI5.hic": "1694424195,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fb6d28f7b-27d3-486f-b5ac-32567416560d%2F4DNFIA6NSSBJ.hic": "2219532611,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F08785616-722e-46bb-ade2-2fdd21324e11%2F4DNFIBKZK63V.hic": "2429136232,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F904b13d3-1203-42a4-812c-963e80c159b1%2F4DNFI3CFMRID.hic": "1233390166,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fb0ed4afe-5ecf-451d-bb1f-444697e3f558%2F4DNFIYIAUEPW.hic": "1753567534,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F4bb9a9b3-12a8-4d2f-8071-4722294c88ea%2F4DNFIC3HAU11.hic": "2271375254,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F5abf9c36-c1d1-44dc-8197-74d860d896c0%2F4DNFIM2BMJ33.hic": "1770471113,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fa68475db-7816-4cec-b2da-d4ce4a0c7a0e%2F4DNFIBY3UHJB.hic": "2095528423,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F07c40943-0d0b-4b3e-94a0-8583b0e00b47%2F4DNFIWZEN3FF.hic": "1558559508,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd8a39553-2718-4866-9b2a-45d8e9c5ac6f%2F4DNFIE5TEYK7.hic": "1323063102,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F294b61ef-5565-4f04-ade9-f921a6686cce%2F4DNFI7H4II2V.hic": "1436947982,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F87a70ad7-7d34-4302-9c03-eb824bd4e633%2F4DNFIAS8LV1C.hic": "1263105698,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F9db804c6-5a91-4cf5-8ae9-e054223afb77%2F4DNFIBXWIH8J.hic": "1587059951,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd1e55906-ec8f-444b-8ce1-2de22a431a76%2F4DNFIO2HBDAI.hic": "1666436393,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F7a4b9b37-8e38-470c-8190-fd4d513c0bbb%2F4DNFIXWCLD4M.hic": "1513511880,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F6c7615b2-5310-4bbf-a605-98761d3a3079%2F4DNFINASC4NQ.hic": "1420358914,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F20454014-49cd-4e2d-93da-f40ad52776d5%2F4DNFIZF1KI43.hic": "1377041630,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F5df04e86-ee2a-45f2-b878-bf1648e2cca5%2F4DNFIQBHR9XC.hic": "1179502734,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F9d1cc910-bb3f-4106-802a-73184c58d5ba%2F4DNFIQVMVRP6.hic": "1811976991,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fe431986b-0732-460f-92ff-0abd1694d2d0%2F4DNFIJ7OAIFQ.hic": "1685503856,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F56d0c575-4962-4ea3-92c3-55bd0e17c096%2F4DNFIE8E4ANZ.hic": "1598369564,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fdb1502fb-a989-4ef9-b800-7eaa7be172ae%2F4DNFIOUSETUP.hic": "1493294709,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Facc2f1c3-8c96-4d21-814a-3a8ba81e7741%2F4DNFIVJ3IIQL.hic": "1472376655,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F037fb4c3-8641-4953-a977-cc71f2137582%2F4DNFIHN2QSMX.hic": "1179632606,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F16d2c3c0-6d29-4815-b074-b142af90b615%2F4DNFIILDWK8M.hic": "2280059989,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F31789849-e4db-45d8-9730-66a048c02d8a%2F4DNFI6XD6JAQ.hic": "2253961696,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fff04947e-e6e8-4d62-8374-ef2ee4104809%2F4DNFIALNLR78.hic": "1914687914,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F53e6c1e7-9410-4158-84e6-57c2e683b095%2F4DNFIBT4EAKN.hic": "2296378356,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F0127900a-258f-4815-97d2-6fd2b043d853%2F4DNFIDJ2JZ7Q.hic": "2558945393,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F89f95693-3d28-44eb-9d45-14932f8e258c%2F4DNFI8JFOAJT.hic": "1726440253,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd803d818-b0d4-4796-8d61-a9f3943f3b10%2F4DNFIRZA6EV6.hic": "1805017504,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff9165fb1-0782-4757-a740-5b929e0252bb%2F4DNFIB7QTIMH.hic": "2541020707,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff8d916b2-b58e-4cdf-894c-ffcb3bf6ebd9%2F4DNFIJ5DQZVK.hic": "2445734043,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F14066a5b-e01a-43c2-a468-b18826174df3%2F4DNFISTWNV9C.hic": "2499319890,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd0692151-7f9a-4475-b059-f8802616dded%2F4DNFIBN9K4V9.hic": "1591570769,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F70a7ef36-a514-4e45-918f-47c4e9e30ef4%2F4DNFIR8OU6QJ.hic": "1689882108,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F180306cd-8593-413a-ae83-24f19209c5d2%2F4DNFIDSWKFF5.hic": "1596696630,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F6e7b9be7-f465-4434-8e9c-68d1e44a76af%2F4DNFIV239W4L.hic": "2345867406,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F55df948c-941d-4930-854c-6a07557a0c1d%2F4DNFIREVU1Z5.hic": "2254683002,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3f590cb7-df3a-498f-81c3-d5ed4179b8ad%2F4DNFIFHU75I5.hic": "2497670883,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8f064770-6008-4f74-bfca-268d4a22d745%2F4DNFIMROE6N4.hic": "9850583704,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fa93d0588-76b7-4ccf-933c-4325876b0a53%2F4DNFI5SUHCGZ.hic": "10364705187,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F2f5f0d6b-0b22-4936-93c9-0944d49c037b%2F4DNFII84FBKM.hic": "8836986129,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F12e90fc5-0b76-4e42-b346-58d267f9ad6e%2F4DNFI2J1ODWB.hic": "13410858286,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff2702a45-3e8b-4980-bcd5-6bb0e291614f%2F4DNFIJWBWE41.hic": "20515676755,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fa0859349-5f06-4ad3-b56f-b1166b34a9eb%2F4DNFIIMZB6Y9.hic": "15350325963,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F12685c57-d54a-46fa-9efb-acf34ed77574%2F4DNFICJECID5.hic": "1525002266,26979", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd101a58e-89aa-44fd-96c5-6bf1e2476272%2F4DNFIR6UW2QA.hic": "1264999913,26979", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3d8c73bf-1335-4af4-b124-e3622d48c5f6%2F4DNFIGOEKBUZ.hic": "1905947578,26979", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fcd2477cf-6ed0-4d7b-b4e9-88fb38b0df48%2F4DNFIMDNAEW4.hic": "996444147,26979", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F0f03953e-29da-4f2e-8c05-572d0edf4525%2F4DNFI5OSZ3JC.hic": "369361754,22829", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F29d95dbb-005a-4ae1-8b9c-0fec9ec0bbd0%2F4DNFI7KOUGFM.hic": "1227434049,26979", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fa441ab7b-afbe-437d-bf98-b6b916558642%2F4DNFIGKX4A32.hic": "883933242,26979", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F941b2f94-2fff-4d3c-aceb-fee4a5ae41a9%2F4DNFI1ORHOTA.hic": "1140970677,26979", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8720ede9-093f-4c00-912f-373283260a16%2F4DNFIWSVLZED.hic": "458091151,26979", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fe9e17155-2b62-4a68-afb2-31dfa674e169%2F4DNFI6H926RO.hic": "3552863515,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F22f22778-987a-4dc0-97bc-f26eae0156d9%2F4DNFIKTYSPOF.hic": "2939475400,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F40f40192-0acb-44cb-8778-8d21afe593fb%2F4DNFIZ4S52BV.hic": "3067438113,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd8767374-7018-4e11-9226-bf5612d39ebb%2F4DNFI3APMXHF.hic": "3258874744,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8c5140ec-a65a-4186-8c59-2927233eecaa%2F4DNFIQLIKDSD.hic": "2746398416,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8cdedda6-d7d8-4231-a85b-d56fcd962366%2F4DNFIKYXMF1E.hic": "14442148774,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Faa4d4497-7c6c-4dad-8040-be13ba07ea32%2F4DNFI9815EEJ.hic": "17960817603,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fe9b7b95f-190b-49fe-8047-ef4a8fc59746%2F4DNFIQ2687RT.hic": "15954277087,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F59863d3a-8d7c-49c7-9a41-7f2a58ad24d1%2F4DNFIYDBBSE3.hic": "16499534862,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3e80ca41-b3e0-4f4f-a05e-8f95fe96d938%2F4DNFIMOCN1YS.hic": "863725312,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F96f97a01-0020-4f09-93e8-fc8a9fd07218%2F4DNFI6558CM8.hic": "1597967345,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fce9e9334-ee0b-4549-a845-110470ba5986%2F4DNFIQZRKS7Y.hic": "907626411,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fdaac8209-1015-48da-9e31-2e252dfd8fe0%2F4DNFIX4DLXSE.hic": "1369766288,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F268b7d52-9655-474c-9467-8ba31bb2195c%2F4DNFII3JV8I1.hic": "856656441,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F9681f9b5-335a-4f56-afa1-15b58bbb41e8%2F4DNFI5IAH9H1.hic": "1495185175,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3e082eab-95aa-4677-88ed-9d7adcc1effb%2F4DNFIK5HY1GP.hic": "2135337789,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F31af1ead-4520-4669-957e-424b4b197c33%2F4DNFIFA89L5B.hic": "1975593640,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fcc2b78fd-52d4-4e0c-ac93-b84ee82daf7e%2F4DNFICXCFGEI.hic": "2628202920,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff54efece-280f-46ca-95e3-1f8a3cd18820%2F4DNFIK4CECUH.hic": "1901129375,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F1181c0c4-afb7-4b6a-9fdc-d868fb2253fc%2F4DNFI1EYIGOC.hic": "1947135384,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F1d3e2905-b9b9-4b91-bcb4-8d34746e78f6%2F4DNFI7TLEWUI.hic": "1185758726,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Faba3d42f-39cd-4a85-9d3f-835aefb5c803%2F4DNFIVCJKHMN.hic": "687240974,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F27f54fcb-54fe-41a4-b25a-2f8944c89044%2F4DNFIN8F14CS.hic": "1304082029,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fb75fedb5-88f4-4bc0-8e38-298df7847a7f%2F4DNFI5LCW273.hic": "12497258313,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F2f22b2a0-3712-496e-92d2-63775ec0e421%2F4DNFIVSCH2CH.hic": "12594733778,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F07e47261-5863-44f5-9198-76e263081bea%2F4DNFIZ268JGC.hic": "1499059135,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F682b1ae1-3ac3-40e4-a330-c49f63946952%2F4DNFIJ1P4HBI.hic": "1190211725,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F197e7c89-ea73-41de-8cb2-8c0b1e3bb945%2F4DNFITEGKBIW.hic": "2061501971,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F191f6928-c9a8-44b2-8516-ee4d6005f24b%2F4DNFIE1P6RVH.hic": "1711447310,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F94435086-3701-4b28-a6d0-4a59b24d7615%2F4DNFICJ6I4DO.hic": "1557899940,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Faa9ac173-d233-41c7-8985-ca91949664e4%2F4DNFIKUG8MEW.hic": "1339072088,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fba6d8ab6-ee18-4ba2-8da9-d631888dd50a%2F4DNFICFZGFAV.hic": "1261083478,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F87a3ab04-7094-4673-81e4-ac8c9add8eb5%2F4DNFIQXCZVVA.hic": "1084913802,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fbc1ff488-82af-4579-9424-959184edb139%2F4DNFIB6PJFJ3.hic": "1114571343,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F1f7026ee-987a-41e7-8a61-45510ee3f86b%2F4DNFIX97731O.hic": "1246860402,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F6186787c-2e72-4925-9729-02121e2e4597%2F4DNFIYQYZOTO.hic": "1212210849,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3b98a946-0109-4efa-a13e-cc7a36772125%2F4DNFIPXU7V25.hic": "1696288217,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fea17d041-c6ed-43a1-8047-535f3d19ad44%2F4DNFIL39PR76.hic": "1719284710,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F72774afe-f166-42ac-9849-4070b0dadf6d%2F4DNFIYLJ3R3B.hic": "1106419640,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F4a45e733-55f8-4a8e-be24-2ef34c976e25%2F4DNFIL51WBN6.hic": "1327651164,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F086c62b0-a26f-41ae-a5ff-88b8be2bd2aa%2F4DNFI6SFPUDA.hic": "1336964405,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F4d9b79c7-af62-4070-84a9-b953903f2732%2F4DNFI2KM22QR.hic": "953067310,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3c9889d1-f49e-4639-8e15-2d99d6cd22e7%2F4DNFIVF8Q45U.hic": "984193565,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fa080dd7b-b7bb-4eae-a275-572a8b45b2d0%2F4DNFI2RN3WFP.hic": "1046525527,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fb81860ca-c227-4b68-a298-1907fd32300a%2F4DNFI4TJTL7A.hic": "1160373401,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F74ab47dc-7b52-421c-845e-6feb33457adf%2F4DNFIYJ4TWB8.hic": "1268416204,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc6582128-a930-4bcc-941e-5c0733bdd4d5%2F4DNFIM6RGKPV.hic": "863347067,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F11a75514-4450-4295-9eda-18e3678a575a%2F4DNFIL2VWWL5.hic": "860731581,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F5eb52a8c-bf14-4225-bf34-14a0aa47c369%2F4DNFIX6ZXCA8.hic": "893462267,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F66aaa4c0-1f62-4040-8ecc-4e95da23cd18%2F4DNFIEVR81FS.hic": "879736207,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F821c6e7f-96f7-47de-b7d9-4970562b3c8e%2F4DNFIAUI6BBI.hic": "996313881,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F9252c362-31ab-413d-a47a-cc97bdbf243a%2F4DNFIAFEE9G2.hic": "1103265750,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc1a0bf52-2e65-4deb-871f-ede736babd41%2F4DNFIPZBEXCP.hic": "1081257762,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F729f5ce3-d7e0-466d-b781-d18049e63bfa%2F4DNFIWPKRZGU.hic": "973779283,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F80b769ee-a717-4825-9db0-dca86f913173%2F4DNFIMD9QNDX.hic": "1158688208,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F266290c0-2767-4158-85ab-7274368905b9%2F4DNFIATA1HD5.hic": "1073361089,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc46f18a8-eb24-4d35-b112-36db72bde2f5%2F4DNFIH9U4I7I.hic": "1111124316,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fec91a79e-7de7-49f7-9b3d-d28313aeddc8%2F4DNFIZ95S6TR.hic": "1242494051,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F9e9390b9-da20-43bb-a8f4-9830f354ddf9%2F4DNFI5ERM9J7.hic": "1271051397,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fee8ea82e-b9e4-41ad-bced-5f4fbdaa4fec%2F4DNFI15FPSQL.hic": "1216714120,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fbed7eb86-8990-42f2-b3ee-5992d6361f7c%2F4DNFIJ3DZPGM.hic": "1035089437,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fdaa8a324-3bf8-424c-8a86-b8ad325cc20d%2F4DNFINW9P6XF.hic": "1215712740,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F70631758-6bf8-47a0-92b6-132574886faa%2F4DNFITS16HW8.hic": "1105283847,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fe473304b-7bc8-49b8-bba1-ecb9f06914ee%2F4DNFIS3DIH4V.hic": "1036056660,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F10f9224a-111c-402a-ac25-e221ad0af9ef%2F4DNFIY3KDHP6.hic": "1071761024,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F17519b96-2bdd-4294-98f0-1535f1aef28e%2F4DNFIO8HVKOL.hic": "953793750,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ffb18f896-4730-4909-86a3-867fc8e76cd6%2F4DNFIMF6CFOM.hic": "708717889,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fcfee4d87-0873-40b0-b79f-35dcc8669c1c%2F4DNFIZZ77KD2.hic": "732668723,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fb8b5d909-8a1b-41bb-bcdd-d108a0bde762%2F4DNFIOLO226X.hic": "951271932,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F9ce81f6e-b9cf-4ec9-8bd3-517539e4b662%2F4DNFIJMS2ODT.hic": "932509067,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F506aa952-5d41-49ff-b658-916bcf88a395%2F4DNFI49F3LJ4.hic": "1208494817,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fe4dc392d-ca36-4bdf-a27d-173cae34f520%2F4DNFI65MQOIJ.hic": "854630155,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F149ef8d7-e0b4-4e4f-b7e5-7226e2603746%2F4DNFIM4KEPRD.hic": "882790622,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fa436f0a8-4f9a-4524-90ac-795c5b8491cf%2F4DNFIIXBIZFC.hic": "848244425,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fbc8a05dc-7449-4b01-8330-a55db37ca8e6%2F4DNFIWDOOBVE.hic": "1116239020,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Faef8b881-28fe-4694-9a95-1d31940e6726%2F4DNFIDT9EB5M.hic": "888289053,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff66f3162-a53d-46f2-8800-3752935d5400%2F4DNFIX2VUNV8.hic": "1226661451,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F36c782e6-2c48-4298-aa43-bd6624da003d%2F4DNFIEQHTV1R.hic": "804665819,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff15d571e-605d-4bcc-a359-0350b57a6815%2F4DNFIFW7GA64.hic": "901568712,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc2aa2e8b-ac7f-4acb-b4b5-ac5f845840fe%2F4DNFIXGXD67I.hic": "970995551,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F71b6fd7d-b249-4d65-a597-b80b95845399%2F4DNFIA7GB1NB.hic": "956785837,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F6cbb1418-34db-427f-9273-5174eac81529%2F4DNFIVOJGWNP.hic": "890415052,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc69c2ee7-b6c3-4a62-8d4f-913491c9dab8%2F4DNFIW22BNB5.hic": "1075499540,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fa268f28f-c6d9-4324-8989-75d2d317af1b%2F4DNFIIFBC8WN.hic": "1045459440,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F6c7361d4-60a6-440b-b5be-072cada98663%2F4DNFI9ZBEBJH.hic": "759395398,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fcceaad1a-e01e-4430-8bd6-24ffa6891802%2F4DNFID4SLU53.hic": "921288444,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F9eee5854-b33e-4d5a-9ba8-ceffd47e7488%2F4DNFIODI1NUJ.hic": "733159777,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F5e1089b0-42e8-441c-99bb-4be99bcec28b%2F4DNFIJL26LFN.hic": "723567970,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F298a429e-ea29-49d3-bfed-fa851e1e7c4c%2F4DNFI5KTF553.hic": "2213661745,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F965d29f0-e4a3-477c-8ae4-faf4a654e69a%2F4DNFIYSPGFGV.hic": "2274989349,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd88acbc1-37b9-4266-9f97-d8fed576d0f3%2F4DNFILOR6D2D.hic": "2595459358,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F7b6ddbce-0ed1-4272-b8ae-32793e4ea4e4%2F4DNFI1WMMPJQ.hic": "2262433890,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fedc0c8c4-97d8-4372-9a4f-5e0cdf09d7d0%2F4DNFI47P5978.hic": "2146314403,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F0edcc389-43a4-44d7-b946-fe3496f93d56%2F4DNFI7XGW6IH.hic": "2302805723,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F0a802926-e235-4c80-b521-83a1774dfb46%2F4DNFIK1EJG8I.hic": "2374943035,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3c36aedb-6a58-4aa2-9b11-bb440ec174f1%2F4DNFIDQ3THN9.hic": "2341188249,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F846123cd-8828-4e51-8b8a-27deaf293858%2F4DNFI3WPNFWT.hic": "775145629,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fbd06e3ad-0e37-48a3-8367-c7d5912cab03%2F4DNFI9DCUOQ1.hic": "870487824,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc2eaf9bf-9584-4cec-8685-bd74038a6c01%2F4DNFIU8AF5ZY.hic": "1276224366,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F219497b5-3f35-473b-9d4e-e1cf21c69561%2F4DNFIHW8NTQX.hic": "28864787856,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F4be13558-114a-4f2d-abca-7598e2ff4757%2F4DNFI4OUMWZ8.hic": "17061013588,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F49aed637-87a1-4d4d-ae68-e5da82aec05b%2F4DNFIEYQ5ZIR.hic": "13555272651,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fa2f48779-4eff-44a6-8a9d-96435aca1ddc%2F4DNFIDZT7PR8.hic": "13425047093,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fb6ec6b71-27b8-4891-b10a-ab06a5270468%2F4DNFIEJEFCAM.hic": "15394960208,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F68b9a7b5-8413-44fc-8c2d-59a67b1c4166%2F4DNFIJ8JKKWJ.hic": "17012681779,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F294d45a4-8b5e-456f-a9cb-1cbbbad3a7d2%2F4DNFINEQY95T.hic": "13966775978,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fbd7f3a48-b822-41e2-bd9c-f52b3aff7b6a%2F4DNFII6AN691.hic": "12367300362,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F7da44594-0dc8-4e74-8e10-a957aeaea51a%2F4DNFIDBIEXI7.hic": "2015474981,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F085a0453-3784-4eba-80b2-3556e53e2f52%2F4DNFIDKJFK2S.hic": "1983111659,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc370c78c-0a99-4c3f-a29b-2dfafc6a3e86%2F4DNFIPAF4PYT.hic": "3041434294,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F907ce45f-baa5-416d-92de-e86db4bacff1%2F4DNFIWIYYNQ5.hic": "7082321112,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff13afc6b-cf69-4c9d-881f-eed4dd3c28ee%2F4DNFIHMCILEN.hic": "1739157603,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F7575d891-0e3d-4a77-896a-3e1b3a8d330b%2F4DNFIJBJ6QVH.hic": "5213499748,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff0daa830-60d5-4c7c-a2e1-a4ee70b3fee7%2F4DNFIH2A7IKF.hic": "4099503507,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff4970a25-91d8-49a7-9a4a-fe0f12cb2b0f%2F4DNFIOL8KGQ2.hic": "2256042055,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F879f1850-d175-4a86-8a97-12658482e3d1%2F4DNFIWILLD6C.hic": "5476286356,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F787f538e-d619-4c8f-985b-78753fb7e57c%2F4DNFIZBXXJAF.hic": "5946467856,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fb8ee785f-1016-4989-9e64-78352621d32f%2F4DNFI8PZOJHN.hic": "8307204961,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3d8997fa-528c-4531-b25b-a412de6bd472%2F4DNFIGXAMSJY.hic": "6577588285,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F87aede55-7610-4283-af0e-c6840429a31e%2F4DNFIWNNO89O.hic": "2871061417,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F93b8e020-b337-4685-81dc-40cc8a12b5e9%2F4DNFIXU2KPNQ.hic": "3401717686,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ffb5cf1bd-59d6-46fe-857d-b86d9756029d%2F4DNFIHBGD6N6.hic": "840028421,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F2d1bc088-d838-49b8-85fc-fea78a7353c4%2F4DNFI7J8NI4A.hic": "675705256,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F21a27b63-fd67-401b-9aa2-2798e6588d21%2F4DNFISFM9VFK.hic": "800145922,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F656c0a9d-7058-4c4b-a3ce-701d929561c1%2F4DNFIJU5XBK7.hic": "966593603,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F2efacfbd-9c81-4e62-8df7-847d1ab774d5%2F4DNFIPKY8ED1.hic": "3401629450,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fa50b6a26-56b5-43f2-b525-fa219fd716f1%2F4DNFIQRTP7NM.hic": "5358852759,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff5dc7a59-b998-4490-8a76-afbf3b258a49%2F4DNFIBCIA62Q.hic": "5779049277,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F62b2b237-cb02-45f7-89d9-616cf9ffb678%2F4DNFIV56OFE3.hic": "5818844506,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8ac79b4f-cfbf-4b2a-9fc2-898ed6c3e5e1%2F4DNFILIM6FDL.hic": "19637469163,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F1cff8afa-5a13-4ad4-bcad-91fc3ced759c%2F4DNFIP71EWXC.hic": "17934647326,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F000789fe-9a22-4280-a71c-7ad228fd4cac%2F4DNFIM7ZVQOQ.hic": "700134697,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8d78457f-0c2b-4358-b08c-4d4ef4d9f59d%2F4DNFIS6EYHCX.hic": "628314484,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8ca3b4a0-2478-49c9-b4a2-a28430417a32%2F4DNFIKKCMS1Q.hic": "584050634,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff5041473-18ec-439d-92b1-8ad98c9b25c0%2F4DNFIBIV8OUN.hic": "522632731,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fcf474ec6-abd4-431e-a21c-252fcf5ee6b3%2F4DNFIAUMRM2S.hic": "313395531,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F2bb1c73e-fb0f-41c4-8620-a938cc8d24a0%2F4DNFI9ZUXG61.hic": "332217525,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F26dfa41e-7e4f-457a-a3ac-72daf8059f3c%2F4DNFIDBFENL7.hic": "359604894,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8ed2e68b-189e-4988-bb6d-94e63240a231%2F4DNFI7XAZNNQ.hic": "5312422266,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F6f2b1ce0-5205-4680-981e-d91b694dc3e4%2F4DNFISNGDB53.hic": "2008546759,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F73c8147f-bc7d-4d33-8a10-a9e7b413ecc6%2F4DNFI1CIGHYC.hic": "2221847625,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F526ae3e3-32cc-4670-970f-1faa9cfafd4d%2F4DNFIQD2DP2F.hic": "5295591503,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F6e803530-47f8-4c56-bb19-fbdcd578d2f0%2F4DNFINHT8P7C.hic": "3159499486,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ffe705f38-903f-47b7-9b38-f80ebd18a479%2F4DNFIGF8EM7M.hic": "3490552542,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Faa197328-d6da-4299-a0fd-409ac9892668%2F4DNFIUPG2ZBJ.hic": "5382003751,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ffe5d52c4-2be7-4812-bca0-cd4bb3025e6b%2F4DNFIH3OTR14.hic": "3224693110,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F21935f61-daa8-4df2-aa69-fcd27953b405%2F4DNFIUATRW3Z.hic": "3835865655,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F72147527-e3e8-4967-bc45-8251249d76c9%2F4DNFI6V7ZQAE.hic": "4382708138,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F589f0919-f54d-49ff-a482-e2f453ef7f34%2F4DNFICKMT1CY.hic": "4479068191,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F861946ca-bad8-4a87-96e1-b2eb20b9ef10%2F4DNFIF9BDCNI.hic": "3698151402,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff76346ac-97ec-4893-8984-2b75ce1cdc51%2F4DNFIG5O1OQS.hic": "5704288175,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fe8b43826-f049-4c3f-b83a-e75fa7aacc85%2F4DNFIHS2SVBQ.hic": "990025510,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F46316260-f555-4dd4-9e40-8ae06ca52822%2F4DNFIU95B69H.hic": "1275878544,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff62ef491-a3ae-4f66-ab33-c5673c9e0b65%2F4DNFIYRROFCR.hic": "1522530503,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F1cd617e1-fad4-4fdc-8b4e-cb277650123c%2F4DNFIF7JN3IU.hic": "1463443128,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fdb20fe2a-0078-4d4a-8a52-d76043d06f40%2F4DNFIB2RYULQ.hic": "1269529700,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3d386fcf-1d22-47de-a0d6-0c3a641ca174%2F4DNFIMVDK3SI.hic": "1185489599,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F00e470bd-c533-41b1-923a-4b471824da12%2F4DNFIRLOTXSC.hic": "978217499,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fb8774fb3-d0c5-43cc-a6c9-eb0ca39841fb%2F4DNFIZAPX6J8.hic": "1100356082,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fab3b826e-614c-448b-860f-a3ebef68a82f%2F4DNFIQD5VCSD.hic": "1322319877,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F66c78d2b-993a-4937-95ed-9e2d302ceb3e%2F4DNFIIF6VAGN.hic": "868885799,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F5d106fe1-2d80-466e-87aa-46b38ba142c5%2F4DNFI86IEZXH.hic": "751443267,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc99490b6-faf9-413f-9c38-3f53018089d6%2F4DNFIP881SR2.hic": "754427927,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F39c7e387-e710-4b1d-b757-357dec03f6ad%2F4DNFI42NNCW8.hic": "1166392978,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F4742a211-43b1-4325-af6f-82490aeb766b%2F4DNFIEV4PKP6.hic": "1102227476,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Feaa73842-1c86-4ad9-8a9e-c189c0b4c01d%2F4DNFIF1DUQHE.hic": "1206699207,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd25f24df-0298-4079-bb6f-1c8e1e32392b%2F4DNFIGW55EAY.hic": "1033358104,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc57a7ab5-2778-4fe2-9d64-9a4e95135f12%2F4DNFISZRU6I4.hic": "1539570262,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd89f494a-27ca-46b6-89be-7583f3f6d18c%2F4DNFIBKKDTAP.hic": "350372180,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F06725280-cb24-4f22-a267-18b434bfa79e%2F4DNFIJSRQW24.hic": "314361467,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8fe5c3c5-006f-425b-ac6d-ea475e29be78%2F4DNFI3REN89E.hic": "299665258,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc8b6ac5c-13b4-427e-9158-cec0b890b6d8%2F4DNFIF5XLHKM.hic": "235668364,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F01ff33fc-fc23-48aa-a6c6-b720d6fe0768%2F4DNFIB6Q538N.hic": "316494853,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F552978c8-abbc-424a-9187-3e34cf802a97%2F4DNFI3ST3F7Y.hic": "296298411,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F72e66520-5170-4f2e-844a-fbfd0e23b480%2F4DNFIQT4M6UI.hic": "307691265,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fb3eb3953-ffe8-4d5a-970c-a16f3b7b9ec3%2F4DNFIFNCC7M2.hic": "364160436,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F37d413fb-afab-41ff-99aa-1678830f7dde%2F4DNFITM9MDJL.hic": "252412426,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Faf5db92c-aaf1-4086-a0d2-79b28648f172%2F4DNFI3NTD7B3.hic": "227586640,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff6892f7b-1f8a-4d7d-9605-c67932cd5654%2F4DNFIBED48O1.hic": "328344868,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd64afb07-5ab1-4c4f-8438-2fee37afa86a%2F4DNFISATK9PF.hic": "379669025,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fad11bb63-8692-461c-b698-89c601451321%2F4DNFISRP84FE.hic": "298491537,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F63710ec5-35d2-47dd-bf9a-08d3daa83d67%2F4DNFI2LY7B73.hic": "303150299,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F76077d9e-ca75-4301-ab79-88aa49bda495%2F4DNFIXEB4UZO.hic": "711757090,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F34dd4c0e-3487-4fb4-b95f-c4bb66e0fa31%2F4DNFIQWWATGK.hic": "221304476,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F48a8cf86-3248-4a8e-8e85-472ec219d49c%2F4DNFI44JLUSL.hic": "284772724,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fee399fbf-2a9e-46e2-8364-457713bff508%2F4DNFIM7Q2FQQ.hic": "330729464,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F124d191a-c5c7-49b6-b84b-0d1bad8bef2b%2F4DNFIZK7W8GZ.hic": "293166018,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fe351f7cc-7a2c-4515-ae0b-3bb2f91c986a%2F4DNFIMIMLMD3.hic": "240094740,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ffd1ae249-57b1-41d6-81a6-16b21dcd8f12%2F4DNFI7QUSU5J.hic": "681762505,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F46c92c5c-9ad8-4d49-beba-f35c5cd99208%2F4DNFINXUOI5H.hic": "375594313,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd7350d40-4e9e-4131-9151-bb539d39b431%2F4DNFIIJR2296.hic": "331322302,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fbfacf37b-1665-45f3-a046-e29e1544e9b0%2F4DNFIJMZUTXR.hic": "361313244,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F234e18fb-9990-43bf-9a48-f72722cfa232%2F4DNFIZQPT9EL.hic": "540421873,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F4b35ab09-2e79-4876-b2bc-d3a8faa26257%2F4DNFIZIXSZ9J.hic": "545066813,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F2ae5118e-807a-46e0-8e92-143d4b282b3d%2F4DNFIDD9IF9T.hic": "237409149,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fb34d7f6f-73f7-4b6b-80c7-c8af0f991549%2F4DNFIVC8OQPG.hic": "355121712,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F9ab169fd-cbdd-4f60-8553-a4c6912ad89e%2F4DNFITUPI4HA.hic": "313085022,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F4e53712b-d0d9-40c5-afe1-ffa0fad71e59%2F4DNFI5IZNXIO.hic": "341863906,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F7a91477f-45eb-4a16-affb-fc131f9326b8%2F4DNFII16KXA7.hic": "248904495,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F153729de-0eca-43cc-9b61-61aa8d775b38%2F4DNFIAAH19VM.hic": "668047244,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F879fd78a-7165-43d9-a0de-ca158b53df30%2F4DNFIVKIY3KV.hic": "247571318,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F67f901a4-040b-4b04-9fff-94a1780423cd%2F4DNFIVVCWL6C.hic": "198355985,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd5b30c5a-654a-463c-9474-39bdc3ce4500%2F4DNFIJRF2273.hic": "343971277,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F7070280a-8f03-40d0-9fef-e9d9f4d3dae7%2F4DNFI6FCC9ZA.hic": "312013061,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F47049719-9407-4d76-9048-26231045f642%2F4DNFI1CPQ4O3.hic": "352923267,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F862c2b5f-44c2-4bd7-9264-b3ca032d3d8d%2F4DNFISXFEDE9.hic": "271745977,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Feffbe052-39ff-4217-9871-44199ed90818%2F4DNFIF9L6QEQ.hic": "668409334,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fa7791854-1b35-4258-90fb-603c55f24642%2F4DNFIPKASX1Q.hic": "312727920,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F79cccad6-a78e-4de9-9fe7-08f7e8df663d%2F4DNFIWXZ4JQZ.hic": "151808553,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F7e86e0cc-d6f1-4ce0-aba4-c36c6ebb3c4c%2F4DNFIEMQ1O8V.hic": "700533280,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F4a1b58d3-9ae6-43e4-91cf-49f1fcbbab33%2F4DNFIYWONU7A.hic": "729050356,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F67bff264-0b0c-4c5c-9d4d-ff5abef2bbe4%2F4DNFISNIE5FH.hic": "7987657997,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3a6a943f-2cc0-4433-a27d-c89f3fdd3309%2F4DNFIV8MLWJB.hic": "6646216171,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F9e235711-ba90-404d-b4ac-b15990ea8e33%2F4DNFIXSTDPHL.hic": "3146468238,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F0c89f4bc-e9fc-4ecf-b868-26108dbb7bb2%2F4DNFIQJNOH8U.hic": "2919703928,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F1856ff9e-de7a-4fa1-ae0b-3e04b837b5e1%2F4DNFI57XB4A8.hic": "13417594377,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F099bb5b9-6315-4650-8f78-d603f5a046b3%2F4DNFIQ7UKVZV.hic": "9016468637,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Faf3c7a30-0fc4-410d-8d41-247da3eb105d%2F4DNFIWJY8GHD.hic": "7921314766,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fda99f429-20ab-4d91-bbfe-f8bdea8ed7b1%2F4DNFIN8NKRNF.hic": "4247121358,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F0ca0f4e3-30ca-4332-b735-e32dce08e1a4%2F4DNFIZYGEHNZ.hic": "4910404663,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F243f48b0-6b59-4f37-ad39-a12e0986f530%2F4DNFIRPYGAV8.hic": "4220073636,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F49f1a890-d458-42a6-9c78-99c38b6c7a8f%2F4DNFI6MZTDM1.hic": "375035361,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F76bd4768-9343-44ba-a99d-5500e184e39d%2F4DNFIG3BCGPL.hic": "2422923206,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F9d1ed866-eaf6-4906-aa8c-9e39616dde38%2F4DNFIS9YPJ3L.hic": "1593271574,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F1e7a5636-bdb6-45fb-85d8-87a7e908de43%2F4DNFIOWGA9AX.hic": "1632314387,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F5ecc552a-0a6b-49a9-9aa5-9f3fd9b535fd%2F4DNFINKEDSBF.hic": "1458761024,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F6c03f1d2-bb25-4c94-b5f5-d5cdd01c14b6%2F4DNFIVIXVUK7.hic": "1504818271,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F1a4616ff-6d04-4a6a-9773-b80e81da2471%2F4DNFIANHFY16.hic": "1850724180,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd2231870-a78d-4c8b-9cfd-084f2468acb1%2F4DNFIJ67ZFBI.hic": "1473864703,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F859c2dd3-df8a-42b7-86ea-bf6524f75e80%2F4DNFIG3YQQ4V.hic": "1539822829,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8bad667e-6003-4828-9a20-07585fa9c811%2F4DNFIOLKEOME.hic": "3036353747,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F92ea551b-5779-4d31-a0f5-621e4bd0eb21%2F4DNFIVLN8WJE.hic": "2710426318,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F61ee79fa-0617-4083-b121-f92ef3a8905c%2F4DNFI2111XQA.hic": "2589549183,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F83ebb98d-e5db-403d-aa23-875293156c0e%2F4DNFI88HXX7D.hic": "2462367030,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F6d63671a-8f1d-4159-82c0-931b43464772%2F4DNFIUBM6QK8.hic": "2486020469,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fcccb9014-ce15-4032-81ac-222b3d621cb4%2F4DNFIVILEERC.hic": "2052537210,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F21a07867-4007-4ca5-b066-25d3168208dc%2F4DNFIF7Q43N4.hic": "2091773428,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff738de0f-358b-44bf-97dd-644c8d9b1b1c%2F4DNFID56VJGW.hic": "878913568,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fda97c1d4-bb92-4a77-92a7-f7960f88b9dc%2F4DNFIYUR29KO.hic": "983915575,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F54ea363a-99e7-4f55-861e-1644acab7939%2F4DNFIUDPGHO8.hic": "905253594,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fdcd66a07-55ee-48d9-a157-419cf4ee3eef%2F4DNFISWC2N8T.hic": "1233576358,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F40363837-7466-4a1d-b20d-a66d1670b700%2F4DNFICMPHDMI.hic": "516590777,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F0b3fa4e6-caeb-40b4-8942-e9c0b03dfe4f%2F4DNFIKMKN736.hic": "634310295,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fb6a34050-d52b-4880-91cf-d3fe4b0ce982%2F4DNFIN5NLS49.hic": "650451131,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8e63a47b-9fd4-4772-8b0c-10ee589ffb16%2F4DNFI4P8UBRL.hic": "705655033,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F7d92b666-30cc-4838-9d46-c1f11cee3d3c%2F4DNFISNC3LAI.hic": "176146197,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F17f7dc63-a1bc-4970-b389-87d9ee93b753%2F4DNFIVBWPFD7.hic": "749678512,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff8897333-4791-4a83-9444-a653e24aee13%2F4DNFITMQRXB7.hic": "254477361,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8712bf31-33d0-4562-ab0b-a1e9cf4fd30c%2F4DNFIUYD3HBY.hic": "995625724,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fbfaf6383-9cc6-4b5c-9b20-d3bf2e8c3495%2F4DNFIRRSC7P9.hic": "1149985362,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fb0b70598-5d17-4e0a-8831-6cbe697e69e2%2F4DNFIWKR8FP6.hic": "1151628407,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fccc094a8-23ce-4fd8-9c4a-41f07c045c8f%2F4DNFIQ74RSUY.hic": "931695969,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8eda16f3-af5e-4f1f-b46d-c74df44b76aa%2F4DNFI9IIO5PW.hic": "1077740364,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff283637b-cf2c-4412-ba00-0e3d7e279fad%2F4DNFI8WGJG19.hic": "812086456,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F7ad8438f-d3d9-42d8-88bf-42845a0dc2d0%2F4DNFIQ5CCESJ.hic": "652559720,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F70e3bdcc-caf4-4822-b9c5-85234873db7a%2F4DNFIWTZHB4H.hic": "760694196,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F56ed767d-cd8a-4d38-8047-ed1e8bc8cd19%2F4DNFIENYQCDP.hic": "1159428005,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fa912fff9-5f90-42b1-a3a6-cbb9eb2cf861%2F4DNFIFATZWPD.hic": "1033325746,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F21338ea5-fdee-4ad8-b61c-608fc6cec4bc%2F4DNFI7YRXKEO.hic": "388142539,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff0f88647-5631-437b-b48a-4603915e3714%2F4DNFIUY3J7EW.hic": "407344788,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F16926af8-ac3b-4f32-97d5-6c0dc6f1596a%2F4DNFIRKUYKP4.hic": "893352368,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F93e39aec-6cde-4c5b-bcdf-283faa3163a2%2F4DNFIAQDBJZP.hic": "489922022,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F0dc0b1ba-5509-4464-9814-dfe103ff09a0%2F4DNFIC1CLPK7.hic": "565748333,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fb50964c7-b025-49d9-b1ed-289bedb59678%2F4DNFI3A3VYWU.hic": "4597459343,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff4390cea-b330-4022-88c1-9ff8c0a786f7%2F4DNFI6JJQKFJ.hic": "3678393678,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F70c0f730-5da1-4863-9b7a-6cdd31066cff%2F4DNFIK61ILGM.hic": "3324300994,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F14b14ac4-ab59-4754-9c43-eacd9d0638e2%2F4DNFIYD8LO9Z.hic": "3227227120,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F7386f953-8da9-47b0-acb2-931cba810544%2F4DNFIOTPSS3L.hic": "253942497,7557", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff6b5d8bd-27dc-4415-a320-53405a16db85%2F4DNFI525PKU5.hic": "305089653,7557", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F1f922dbc-637b-4c43-b816-f604f0e79ad1%2F4DNFI8Y9SRP2.hic": "1438589609,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F6a36d686-716c-4ba8-a9c3-fa8311791d3c%2F4DNFIP25GZGA.hic": "1419100109,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F0e535542-2cf2-46e4-ba10-7a0b946a7fb2%2F4DNFITPO1WTY.hic": "3885296184,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F0c17d228-5052-4c83-880e-af05118e6929%2F4DNFIG4X5Z5F.hic": "2159245890,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc3977c00-525b-4556-9a27-061707f8cb76%2F4DNFIXLYR32S.hic": "587852728,21916", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3f856506-cbc5-4211-a29d-48a7530c622e%2F4DNFIWI3V5LI.hic": "2318237793,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F38f77979-5eb7-4b6f-9a60-c2451185db98%2F4DNFI2DGL7LH.hic": "2068150664,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fe0992a75-7727-405e-95ac-aa97141b51c1%2F4DNFI1VSO8JP.hic": "1807949651,21916", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fe925f1aa-2e7b-44e7-bfa8-2084a613ab13%2F4DNFIV5O2ZYO.hic": "2242134377,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F803a6d3c-3972-4939-8ff2-d195c5192090%2F4DNFIEWEWQ8D.hic": "2981341325,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F25104375-a588-46e6-a382-663cee6c332f%2F4DNFICSTCJQZ.hic": "14592996888,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F927aa8a5-24a5-43b7-807a-1e99ac321459%2F4DNFICEGAHRC.hic": "15431307603,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8c380474-12cd-41f4-b86f-2a29faf12eec%2F4DNFIY3XPKPO.hic": "2550999291,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F77da562e-d0ec-45a8-8764-14fa16d995a1%2F4DNFIK9PS9GM.hic": "3401011629,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F11b26222-d480-40a7-8d53-3ad8500396cb%2F4DNFIF4Y74JR.hic": "2127593378,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F93df02c6-1047-43f6-afae-d3598b61eeea%2F4DNFIBBKG9KD.hic": "5724446278,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F6cd4378a-8f51-4e65-99eb-15f5c80abf8d%2F4DNFIT4I5C6Z.hic": "5419655766,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F067881e5-563d-40de-a9e3-caccad887fbc%2F4DNFI2U38HCE.hic": "14749043471,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fcb3da9ad-7afe-4d0c-9c2d-261181e7a95c%2F4DNFIETP228R.hic": "9401474797,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F185b7bcc-7bb7-41b7-9ebe-92d4fe159431%2F4DNFIXKC48TK.hic": "11624295594,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F18459b84-dd43-4af6-a05f-bcb773096322%2F4DNFIFPGOWJ6.hic": "2843730862,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ffde1e48c-4a0d-4bb1-b84a-e0e45f9a0aa3%2F4DNFIIRMBE8Y.hic": "5820677927,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fbabed539-1f0f-4e87-8815-fde596e6024c%2F4DNFIVUGNDD7.hic": "5170782436,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F7d00531a-e616-469b-af52-5b028270e2ce%2F4DNFIFLJLIS5.hic": "18917549985,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F7a9dad53-b8af-4cb6-9ce3-5c38e4a855c7%2F4DNFIOX3BGNE.hic": "5482775936,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F82fd7b7e-5f47-48d5-bf0d-daaa48a4674d%2F4DNFISPUVQHA.hic": "2177864938,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F4c6680f3-9cf6-452f-9dc5-ecebf376775d%2F4DNFI8649RQJ.hic": "3288850368,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F2395f001-19d9-4000-9f00-dae3dea708d6%2F4DNFIE8T8JZ8.hic": "1383191843,21916", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F24464fa8-bf96-483c-8e9a-c2f626ad6e19%2F4DNFIBM714BP.hic": "1765204569,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F918fc048-fa27-41d2-a63a-d50c511fbb9a%2F4DNFI6CWNUFL.hic": "2431120602,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F7ff5a0d1-8e54-4cf0-9fe7-339f147c78da%2F4DNFIZ4F74QR.hic": "3211825957,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F355f0412-cb17-452a-b15c-aba16c5a742c%2F4DNFIOUVOX3R.hic": "5547401083,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3cac91c5-160a-4b91-a91e-edc309318dd5%2F4DNFIVTDXW6X.hic": "4797344498,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fe9ac9ec5-6221-4f39-951a-1c5054fc9f1c%2F4DNFICA8Y9TN.hic": "4277557869,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F46f62222-b50a-428b-938b-5444951600eb%2F4DNFIDWM3HN5.hic": "4374808431,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F50e4f2a1-9cb6-4192-8199-64d354bfdf96%2F4DNFIBK5TB3N.hic": "3757387253,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fe4cdd5a8-1a45-4c6a-906b-a9603260d4c8%2F4DNFI3JYF9VS.hic": "5260534916,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc8164e99-5778-427d-be26-f0e1b62400f0%2F4DNFIP1GNKUO.hic": "7589365689,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F0d72e78a-fc87-4716-8b8e-6dc5650ff2ef%2F4DNFIQYQWPF5.hic": "22022259901,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fac58fc15-48c2-4eec-a689-23b677b4b6e7%2F4DNFIW6H9U3S.hic": "6810897169,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F31811e40-e3ca-4456-8ba6-2ee66d6c7104%2F4DNFI7J8BQ4P.hic": "7188744676,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F62d81a52-d2cb-4bbd-8510-0fe120e786e0%2F4DNFIA3AKFSU.hic": "1763730692,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fae0b7513-d1a0-4f27-a9d3-348837f42cb6%2F4DNFID68JQY9.hic": "2422880133,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fae6a1a7e-1d2d-4fd2-a89f-1799abac8a9c%2F4DNFIL1FQDXE.hic": "1543814834,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F80d343c9-bd60-468a-803d-c3e351a958bc%2F4DNFITSIPCSK.hic": "2344682115,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff2d61195-a3a6-4d50-b928-546ca67546cb%2F4DNFIJ88LYHR.hic": "3362742962,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F31052aba-773a-4500-961b-e0a518245b0c%2F4DNFIJIPWD63.hic": "2529548812,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc93d0710-3fbf-40cc-b0eb-878e2aa659e4%2F4DNFIZUP2BBI.hic": "491996147,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8660baeb-5be1-4ba5-93e4-66499e9a4587%2F4DNFIEBC4AF3.hic": "2993048734,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff6d08fbc-b836-4776-82ad-8b1b277ae837%2F4DNFI5VO3E1W.hic": "1949322679,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3af004a2-a6fa-46dc-8be8-898b847a77be%2F4DNFIFDGVWLU.hic": "2456400803,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fbd613b4b-2422-492c-8d8f-8afba9c8a182%2F4DNFITVGFNYZ.hic": "1411204423,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc340694f-14f3-4638-b09b-98220c20039a%2F4DNFIOW9TTC1.hic": "2611370588,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3effa71b-6aa3-4265-87ba-f8d709d778d7%2F4DNFIOAA3ZEQ.hic": "3123195980,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fde75cf8b-9ce1-44fc-8b7b-ca0adea6bae9%2F4DNFIA5ID1S6.hic": "3496246968,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F714f775d-a5a4-4314-83f8-016b9d73200b%2F4DNFIZYU7V81.hic": "4245592042,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F5ca518af-6e1e-4777-b67b-0fe7f039ce58%2F4DNFIRV6PVUX.hic": "3981520466,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc29b57d5-c263-4372-b396-ab4f55682f5d%2F4DNFIMEANFBY.hic": "3999623376,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F4196d3ef-161a-4c18-a57e-005165c6b32a%2F4DNFIGLGQXLC.hic": "4105683321,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fe10828b5-9519-4ceb-81e7-7228bfd890de%2F4DNFILS2HLXC.hic": "3804942111,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Feaac88c7-9bdc-4b1e-aa9f-e675520dfffa%2F4DNFIQS8853L.hic": "5287726781,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Faab371b1-bc8d-4e83-998e-5bb977c443ca%2F4DNFIVBYCYGS.hic": "4657988157,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fdb116add-af8c-4a3b-b106-9f704ba0a175%2F4DNFIE4WWHMF.hic": "5116727268,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F033366e2-05a2-4381-9d48-90122892a9e0%2F4DNFIKDUUC3C.hic": "45638237,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F7284a446-442d-4a46-aae5-84987e75a7af%2F4DNFIJ5HIRA2.hic": "62201052,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F876649a3-6dd3-463a-8b17-5752a98a89c5%2F4DNFIXDFC7EM.hic": "69878143,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3cb4ce4d-d474-459f-8b8a-2159d8df8068%2F4DNFIO35EOVR.hic": "70153114,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F5c5612fa-18c2-47fb-8074-693b1054e254%2F4DNFI57QGL6U.hic": "54605055,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F70c1472d-cf3a-41d7-8682-cd03b7cc978d%2F4DNFI2AGEBE5.hic": "67930121,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F2bf4cce8-6e03-422b-a190-e51d4a07d501%2F4DNFI1E6NJQJ.hic": "4893181511,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F0eb3aa56-8a23-435d-a07b-8bb545e8d708%2F4DNFI2DNFM1A.hic": "60466977,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F1201682a-a223-482d-913d-3c3972b8eb65%2F4DNFIIRIHBR2.hic": "48961678,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F6aee7913-6356-43cf-affa-f2b60dd478f6%2F4DNFIKXNMT46.hic": "39095246,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F357139a3-c9a5-4343-b0a4-b41c45fd03fd%2F4DNFIRV7IRJP.hic": "70916718,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F76be3061-6259-42be-a917-19dcba41517b%2F4DNFIFX1XYKZ.hic": "229197441,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff60c348a-a62c-43c3-ac85-f6c28b5f823f%2F4DNFI64CJUZ5.hic": "112428610,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fbd0b0a14-9703-49af-bb36-2359f96d4d0e%2F4DNFIBPL2HL1.hic": "73972428,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F79ac278d-83f7-4c1f-91b2-05c8018c1426%2F4DNFIBRSIPE4.hic": "415430378,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F0c3b8141-8e67-4211-80dd-3bae88f9e537%2F4DNFIDLDVY14.hic": "112747303,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F2ae703d2-d85c-4ac4-9ce1-14d653927675%2F4DNFI4R1II4P.hic": "210565448,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F76e641af-90be-49f8-b126-12c20f856159%2F4DNFINMLRY95.hic": "1590865292,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3b416382-ae5d-469f-9e9a-85a3e2ce9793%2F4DNFI8KBXYNL.hic": "4626496956,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fa27589a6-86b2-43a2-8218-1f2232d551e6%2F4DNFI53R5IKA.hic": "1536016455,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fdd3999f5-b36e-4154-a6b9-446656959a3a%2F4DNFIAWVDQ8C.hic": "2210273411,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc377953b-0e61-426b-a905-abab2d5a3002%2F4DNFI9VXTBE2.hic": "3384365692,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F2dbe0377-1db2-4aae-af2b-d87dff728035%2F4DNFIT96Z365.hic": "7692311974,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fdcfcb009-f006-4ab8-a4c7-af72be58c12c%2F4DNFITUOMFUQ.hic": "6592120312,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F67f9073d-b2c5-474e-b3d5-7d72cde555cd%2F4DNFIHLQKDN8.hic": "2647703964,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F76968cc8-fb9f-485b-85b2-c9289067194b%2F4DNFIL9M97T2.hic": "6186798917,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F87d9330b-8d2c-4e9d-85bb-02e572de7a68%2F4DNFIDWGZLHX.hic": "4379708168,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ffc01b381-3665-4225-88ee-2e5e9ecb7324%2F4DNFIMEG1QIC.hic": "3587146533,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3144a03c-15c3-4bf9-95f8-ffad2640a1bf%2F4DNFIWSB66VX.hic": "1529739069,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd7d3aac0-ba66-494b-ba0c-147631084b98%2F4DNFIH7TH4MF.hic": "6896300679,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F4b13bd19-fbd1-4c68-8855-4f0158d1ce47%2F4DNFIHKWIZ9T.hic": "1954878455,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3d04e286-30d4-4add-a806-7a929d36419e%2F4DNFIZBBX795.hic": "1350142414,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Faa26f261-a88a-4cac-9118-ff8e90ab6f61%2F4DNFI9ZWZ5BS.hic": "3410552807,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F24e516ce-0b49-4476-b818-cc96471d8765%2F4DNFIPAI8XB5.hic": "4168518737,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fac3b06b5-46d4-4c1e-97e9-9a4f353473a7%2F4DNFI1OUWFSC.hic": "10766406904,21916", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F76c6aa27-895f-4e82-8ed8-7a85aca84490%2F4DNFIX4PJKXZ.hic": "1463157350,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fe6fbe03a-997b-4d72-a3cc-f1ed7bd88a92%2F4DNFIZGCA8AH.hic": "1597664180,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F61d99a87-4ec6-4116-be99-b483999641c4%2F4DNFI5CGQ46V.hic": "2870576870,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F271ea8cd-53b9-44c9-9fff-1bb5c444b54c%2F4DNFIOCW5AEM.hic": "2463600138,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fa98ca64a-861a-4a8c-92e9-586af457b1fb%2F4DNFI1UEG1HD.hic": "22480709268,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F5809b32e-0aea-4cf5-a174-cf162d591a35%2F4DNFI9YAVTI1.hic": "3141182061,25900" - }; - - const isNode = typeof process !== 'undefined' && process.versions != null && process.versions.node != null; - const Short_MIN_VALUE = -32768; - const DOUBLE = 8; - const FLOAT = 4; - const INT = 4; - const GoogleRateLimiter = new RateLimiter(100); - - - class HicFile { - - constructor(args) { - - if (args.alert) { - this.alert = args.alert; - } - - this.config = args; - - this.loadFragData = args.loadFragData; - this.fragmentSitesCache = {}; - this.normVectorCache = new LRU(10); - this.normalizationTypes = ['NONE']; - this.matrixCache = new LRU(10); - this.blockCache = new BlockCache(); - - // args may specify an io.File object, a local path (Node only), or a url - if (args.file) { - this.file = args.file; - } else if (args.blob) { - this.file = new BrowserLocalFile(args.blob); - } else if (args.url || (args.path && !isNode)) { - this.url = args.url || this.path; - this.remote = true; - - // Google drive must be rate limited. Perhaps all remote files should be rate limited? - const remoteFile = new RemoteFile(args); - if (isGoogleDrive(this.url)) { - this.file = new ThrottledFile(remoteFile, GoogleRateLimiter); - } else { - this.file = remoteFile; - } - } else if (args.path) { - // path argument, assumed local file - throw Error(`path property is deprecated, use NodeLocalFile`) - } else { - throw Error("Arguments must include file, blob, url, or path") - } - } - - async init() { - - if (this.initialized) { - return; - } else { - await this.readHeaderAndFooter(); - // Footer is read with header - //await this.readFooter() - this.initialized = true; - } - } - - async getVersion() { - if (this.version === undefined) { - const data = await this.file.read(0, 128); - if (!data) { - return undefined; - } - const binaryParser = new BinaryParser(new DataView(data)); - this.magic = binaryParser.getString(); - this.version = binaryParser.getInt(); - return this.version - } else { - return this.version - } - } - - async getMetaData() { - await this.init(); - return this.meta - } - - async readHeaderAndFooter() { - - // Read initial fields magic, version, and footer position - let data = await this.file.read(0, 16); - if (!data || data.byteLength === 0) { - throw Error("File content is empty") - } - let binaryParser = new BinaryParser(new DataView(data)); - this.magic = binaryParser.getString(); - this.version = binaryParser.getInt(); - if (this.version < 5) { - throw Error("Unsupported hic version: " + this.version) - } - this.footerPosition = binaryParser.getLong(); - - // Read footer and determine file position for body section (i.e. end of header) - - await this.readFooter(); - - const bodyPostion = Object.values(this.masterIndex).reduce((min, currentValue) => { - return Math.min(min, currentValue.start) - }, Number.MAX_VALUE); - - const remainingSize = bodyPostion - 16; - data = await this.file.read(16, remainingSize); - binaryParser = new BinaryParser(new DataView(data)); - - this.genomeId = binaryParser.getString(); - - if (this.version >= 9) { - this.normVectorIndexPosition = binaryParser.getLong(); - this.normVectorIndexSize = binaryParser.getLong(); - } - - this.attributes = {}; - let nAttributes = binaryParser.getInt(); - while (nAttributes-- > 0) { - this.attributes[binaryParser.getString()] = binaryParser.getString(); - } - - this.chromosomes = []; - this.chromosomeIndexMap = {}; - let nChrs = binaryParser.getInt(); - let i = 0; - while (nChrs-- > 0) { - const chr = { - index: i, - name: binaryParser.getString(), - size: this.version < 9 ? binaryParser.getInt() : binaryParser.getLong() - }; - if (chr.name.toLowerCase() === "all") { - this.wholeGenomeChromosome = chr; - this.wholeGenomeResolution = Math.round(chr.size * (1000 / 500)); // Hardcoded in juicer - } - this.chromosomes.push(chr); - this.chromosomeIndexMap[chr.name] = chr.index; - i++; - } - - this.bpResolutions = []; - let nBpResolutions = binaryParser.getInt(); - while (nBpResolutions-- > 0) { - this.bpResolutions.push(binaryParser.getInt()); - } - - if (this.loadFragData) { - this.fragResolutions = []; - let nFragResolutions = binaryParser.getInt(); - if (nFragResolutions > 0) { - while (nFragResolutions-- > 0) { - this.fragResolutions.push(binaryParser.getInt()); - } - - // this.sites = []; - // for(let i=0; i 0) { - const key = binaryParser.getString(); - const pos = binaryParser.getLong(); - const size = binaryParser.getInt(); - this.masterIndex[key] = {start: pos, size: size}; - } - - this.expectedValueVectors = {}; - - // Expected values - // const nExpValues = binaryParser.readInt(); - // while (nExpValues-- > 0) { - // type = "NONE"; - // unit = binaryParser.getString(); - // binSize = binaryParser.getInt(); - // nValues = binaryParser.getInt(); - // values = []; - // while (nValues-- > 0) { - // values.push(binaryParser.getDouble()); - // } - // - // nChrScaleFactors = binaryParser.getInt(); - // normFactors = {}; - // while (nChrScaleFactors-- > 0) { - // normFactors[binaryParser.getInt()] = binaryParser.getDouble(); - // } - // - // // key = unit + "_" + binSize + "_" + type; - // // NOT USED YET SO DON'T STORE - // // dataset.expectedValueVectors[key] = - // // new ExpectedValueFunction(type, unit, binSize, values, normFactors); - // } - - // normalized expected values start after expected value. Add 4 for - if (this.version > 5) { - const skip = this.version < 9 ? 4 : 8; - this.normExpectedValueVectorsPosition = this.footerPosition + skip + nBytes; - } - return this; - }; - - async printIndexStats() { - - let totalSize = 0; - let maxSize = 0; - let maxKey; - await await this.init(); - for (let key of Object.keys(this.masterIndex)) { - const entry = this.masterIndex[key]; - // console.log(`${key}\t${entry.start}\t${entry.size}`) - totalSize += entry.size; - if (entry.size > maxSize) { - maxSize = entry.size; - maxKey = key; - } - } - // console.log(`Total size = ${totalSize}`); - console.log(`${maxSize} ${maxKey} ${this.config.url}`); - } - - async getMatrix(chrIdx1, chrIdx2) { - const key = Matrix.getKey(chrIdx1, chrIdx2); - if (this.matrixCache.has(key)) { - return this.matrixCache.get(key); - } else { - const matrix = await this.readMatrix(chrIdx1, chrIdx2); - this.matrixCache.set(key, matrix); - return matrix; - } - } - - async readMatrix(chrIdx1, chrIdx2) { - - await this.init(); - - if (chrIdx1 > chrIdx2) { - const tmp = chrIdx1; - chrIdx1 = chrIdx2; - chrIdx2 = tmp; - } - - const key = Matrix.getKey(chrIdx1 , chrIdx2); - const idx = this.masterIndex[key]; - if (!idx) { - return undefined - } - const data = await this.file.read(idx.start, idx.size); - if (!data) { - return undefined - } - - return Matrix.parseMatrix(data, this.chromosomes); - - } - - async getContactRecords(normalization, region1, region2, units, binsize, allRecords = false) { - - await this.init(); - - const idx1 = this.chromosomeIndexMap[this.getFileChrName(region1.chr)]; - const idx2 = this.chromosomeIndexMap[this.getFileChrName(region2.chr)]; - - const transpose = (idx1 > idx2) || (idx1 === idx2 && region1.start >= region2.end); - if (transpose) { - const tmp = region1; - region1 = region2; - region2 = tmp; - } - - const blocks = await this.getBlocks(region1, region2, units, binsize); - if (!blocks || blocks.length === 0) { - return [] - } - - const contactRecords = []; - const x1 = region1.start / binsize; - const x2 = region1.end / binsize; - const y1 = region2.start / binsize; - const y2 = region2.end / binsize; - const nvX1 = Math.floor(x1); - const nvX2 = Math.ceil(x2); - const nvY1 = Math.floor(y1); - const nvY2 = Math.ceil(y2); - for (let block of blocks) { - if (block) { // An undefined block is most likely caused by a base pair range outside the chromosome - let normVector1; - let normVector2; - let isNorm = normalization && normalization !== "NONE"; - const chr1 = this.getFileChrName(region1.chr); - const chr2 = this.getFileChrName(region2.chr); - if (isNorm) { - - const nv1 = await this.getNormalizationVector(normalization, chr1, units, binsize); - const nv2 = (chr1 === chr2) ? nv1 : await this.getNormalizationVector(normalization, chr2, units, binsize); - - if (nv1 && nv2) { - normVector1 = await nv1.getValues(nvX1, nvX2); - normVector2 = await nv2.getValues(nvY1, nvY2); - } else { - isNorm = false; - // Raise message and switch pulldown - } - } - - for (let rec of block.records) { - if (allRecords || (rec.bin1 >= x1 && rec.bin1 < x2 && rec.bin2 >= y1 && rec.bin2 < y2)) { - if (isNorm) { - const x = rec.bin1; - const y = rec.bin2; - const nvnv = normVector1[x - nvX1] * normVector2[y - nvY1]; - if (nvnv !== 0 && !isNaN(nvnv)) { - const counts = rec.counts / nvnv; - contactRecords.push(new ContactRecord(x, y, counts)); - } - } else { - contactRecords.push(rec); - } - } - } - } - } - - return contactRecords; - } - - async getBlocks(region1, region2, unit, binSize) { - - const blockKey = (blockNumber, zd) => `${zd.getKey()}_${blockNumber}`; - - await this.init(); - const chr1 = this.getFileChrName(region1.chr); - const chr2 = this.getFileChrName(region2.chr); - const idx1 = this.chromosomeIndexMap[chr1]; - const idx2 = this.chromosomeIndexMap[chr2]; - - if (idx1 === undefined) { - console.log("No chromosome named: " + region1.chr); - return [] - } - if (idx2 === undefined) { - console.log("No chromosome named: " + region2.chr); - return [] - } - - const matrix = await this.getMatrix(idx1, idx2); - if (!matrix) { - console.log("No matrix for " + region1.chr + "-" + region2.chr); - return [] - } - - const zd = matrix.getZoomData(binSize, unit); - if (!zd) { - let msg = `No data avalailble for resolution: ${binSize} for map ${region1.chr}-${region2.chr}`; - throw new Error(msg) - } - - const blockNumbers = zd.getBlockNumbers(region1, region2, this.version); - - const blocks = []; - const blockNumbersToQuery = []; - for (let num of blockNumbers) { - const key = blockKey(num, zd); - if (this.blockCache.has(binSize, key)) { - blocks.push(this.blockCache.get(binSize, key)); - } else { - blockNumbersToQuery.push(num); - } - } - - const promises = blockNumbersToQuery.map(blockNumber => this.readBlock(blockNumber, zd)); - const newBlocks = await Promise.all(promises); - for (let block of newBlocks) { - if (block) { - this.blockCache.set(binSize, blockKey(block.blockNumber, zd), block); - } - } - return blocks.concat(newBlocks); - } - - async readBlock(blockNumber, zd) { - - const idx = await zd.blockIndex.getBlockIndexEntry(blockNumber); - - if (!idx) { - return undefined - } else { - let data = await this.file.read(idx.filePosition, idx.size); - if (!data) { - return undefined; - } - - const inflate = new Zlib.Inflate(new Uint8Array(data)); - const plain = inflate.decompress(); - //var plain = zlib.inflateSync(Buffer.from(data)) //.decompress(); - data = plain.buffer; - - const parser = new BinaryParser(new DataView(data)); - const nRecords = parser.getInt(); - const records = []; - - if (this.version < 7) { - for (let i = 0; i < nRecords; i++) { - const binX = parser.getInt(); - const binY = parser.getInt(); - const counts = parser.getFloat(); - records.push(new ContactRecord(binX, binY, counts)); - } - } else { - - const binXOffset = parser.getInt(); - const binYOffset = parser.getInt(); - - const useFloatContact = parser.getByte() === 1; - const useIntXPos = this.version < 9 ? false : parser.getByte() == 1; - const useIntYPos = this.version < 9 ? false : parser.getByte() == 1; - const type = parser.getByte(); - - if (type === 1) { - // List-of-rows representation - const rowCount = useIntYPos ? parser.getInt() : parser.getShort(); - for (let i = 0; i < rowCount; i++) { - const dy = useIntYPos ? parser.getInt() : parser.getShort(); - const binY = binYOffset + dy; - const colCount = useIntXPos ? parser.getInt() : parser.getShort(); - for (let j = 0; j < colCount; j++) { - const dx = useIntXPos ? parser.getInt() : parser.getShort(); - const binX = binXOffset + dx; - const counts = useFloatContact ? parser.getFloat() : parser.getShort(); - records.push(new ContactRecord(binX, binY, counts)); - } - } - } else if (type == 2) { - - const nPts = parser.getInt(); - const w = parser.getShort(); - - for (let i = 0; i < nPts; i++) { - //int idx = (p.y - binOffset2) * w + (p.x - binOffset1); - const row = Math.floor(i / w); - const col = i - row * w; - const bin1 = binXOffset + col; - const bin2 = binYOffset + row; - - if (useFloatContact) { - const counts = parser.getFloat(); - if (!isNaN(counts)) { - records.push(new ContactRecord(bin1, bin2, counts)); - } - } else { - const counts = parser.getShort(); - if (counts != Short_MIN_VALUE) { - records.push(new ContactRecord(bin1, bin2, counts)); - } - } - } - } else { - throw new Error("Unknown block type: " + type); - } - - } - - return new Block(blockNumber, zd, records, idx); - - - } - }; - - async hasNormalizationVector(type, chr, unit, binSize) { - await this.init(); - let chrIdx; - if (Number.isInteger(chr)) { - chrIdx = chr; - } else { - const canonicalName = this.getFileChrName(chr); - chrIdx = this.chromosomeIndexMap[canonicalName]; - } - const key = getNormalizationVectorKey(type, chrIdx, unit.toString(), binSize); - const normVectorIndex = await this.getNormVectorIndex(); - return normVectorIndex && normVectorIndex[key]; - } - - async isNormalizationValueAvailableAtResolution(normalization, chr, unit, resolution) { - - let chromosomeIndex; - if (Number.isInteger(chr)) { - chromosomeIndex = chr; - } else { - const canonicalName = this.getFileChrName(chr); - chromosomeIndex = this.chromosomeIndexMap[canonicalName]; - } - - const normVectorIndex = await this.getNormVectorIndex(); - - const key = getNormalizationVectorKey(normalization, chromosomeIndex, unit.toString(), resolution); - - const index = normVectorIndex[key]; - - return undefined !== index - - } - - async getNormalizationVector(type, chr, unit, binSize) { - - await this.init(); - - let chrIdx; - if (Number.isInteger(chr)) { - chrIdx = chr; - } else { - const canonicalName = this.getFileChrName(chr); - chrIdx = this.chromosomeIndexMap[canonicalName]; - } - - const key = getNormalizationVectorKey(type, chrIdx, unit.toString(), binSize); - - if (this.normVectorCache.has(key)) { - return this.normVectorCache.get(key); - } - - const normVectorIndex = await this.getNormVectorIndex(); - - if (!normVectorIndex) { - console.log("Normalization vectors not present in this file"); - return undefined - } - - const status = await this.isNormalizationValueAvailableAtResolution(type, chr, unit, binSize); - - if (false === status) { - - const str = `Normalization option ${ type } not available at resolution ${ binSize }. Will use NONE.`; - console.log(str); - - if (this.alert) { - this.alert(str); - } - return undefined - } - - const idx = normVectorIndex[key]; - - const data = await this.file.read(idx.filePosition, 8); - - if (!data) { - return undefined; - } - - const parser = new BinaryParser(new DataView(data)); - const nValues = this.version < 9 ? parser.getInt() : parser.getLong(); - const dataType = this.version < 9 ? DOUBLE : FLOAT; - const filePosition = this.version < 9 ? idx.filePosition + 4 : idx.filePosition + 8; - const nv = new NormalizationVector(this.file, filePosition, nValues, dataType); - this.normVectorCache.set(key, nv); - return nv; - - } - - async getNormVectorIndex() { - - if (this.version < 6) { - return undefined; - } - - if (!this.normVectorIndex) { - - // If nvi is not supplied, try reading from remote lambda service - if (!this.config.nvi && this.remote && this.url) { - const url = new URL(this.url); - const key = encodeURIComponent(url.hostname + url.pathname); - if(nvi$1.hasOwnProperty(key)) { - this.config.nvi = nvi$1[key]; - } - } - - if (this.config.nvi) { - const nviArray = decodeURIComponent(this.config.nvi).split(","); - const range = {start: parseInt(nviArray[0]), size: parseInt(nviArray[1])}; - return this.readNormVectorIndex(range) - } else { - try { - await this.readNormExpectedValuesAndNormVectorIndex(); - return this.normVectorIndex - } catch (e) { - if (e.code === "416" || e.code === 416) { - // This is expected if file does not contain norm vectors - this.normExpectedValueVectorsPosition = undefined; - } else { - console.error(e); - } - } - } - } - - return this.normVectorIndex - } - - async getNormalizationOptions() { - // Normalization options are computed as a side effect of loading the index. A bit - // ugly but alternatives are worse. - await this.getNormVectorIndex(); - return this.normalizationTypes; - } - - /** - * Return a promise to load the normalization vector index - * - * @param dataset - * @param range -- file range {position, size} - * @returns Promise for the normalization vector index - */ - async readNormVectorIndex(range) { - - await this.init(); - - this.normalizationVectorIndexRange = range; - - const data = await this.file.read(range.start, range.size); - - const binaryParser = new BinaryParser(new DataView(data)); - - this.normVectorIndex = {}; - - let nEntries = binaryParser.getInt(); - while (nEntries-- > 0) { - this.parseNormVectorEntry(binaryParser); - } - - return this.normVectorIndex; - - } - - /** - * This function is used when the position of the norm vector index is unknown. We must read through the expected - * values to find the index - * - * @param dataset - * @returns {Promise} - */ - async readNormExpectedValuesAndNormVectorIndex() { - - await this.init(); - - if (this.normExpectedValueVectorsPosition === undefined) { - return; - } - - const nviStart = await this.skipExpectedValues(this.normExpectedValueVectorsPosition); - let byteCount = INT; - - let data = await this.file.read(nviStart, INT); - if (data.byteLength === 0) { - // This is possible if there are no norm vectors. Its a legal v8 file, though uncommon - return; - } - const binaryParser = new BinaryParser(new DataView(data)); - const nEntries = binaryParser.getInt(); - const sizeEstimate = nEntries * 30; - const range = {start: nviStart + byteCount, size: sizeEstimate}; - - data = await this.file.read(range.start, range.size); - this.normalizedExpectedValueVectors = {}; - this.normVectorIndex = {}; - - // Recursively process entries - await processEntries.call(this, nEntries, data); - - this.config.nvi = nviStart.toString() + "," + byteCount; - - async function processEntries(nEntries, data) { - - const binaryParser = new BinaryParser(new DataView(data)); - - while (nEntries-- > 0) { - - if (binaryParser.available() < 100) { - - nEntries++; // Reset counter as entry is not processed - - byteCount += binaryParser.position; - const sizeEstimate = Math.max(1000, nEntries * 30); - const range = {start: nviStart + byteCount, size: sizeEstimate}; - const data = await this.file.read(range.start, range.size); - return processEntries.call(this, nEntries, data); - } - - this.parseNormVectorEntry(binaryParser); - - } - byteCount += binaryParser.position; - } - } - - /** - * This function is used when the position of the norm vector index is unknown. We must read through the - * normalized expected values to find the index - * - * @param dataset - * @returns {Promise} - */ - async skipExpectedValues(start) { - - const version = this.version; - const file = new BufferedFile({file: this.file, size: 256000}); - const range = {start: start, size: INT}; - const data = await file.read(range.start, range.size); - const binaryParser = new BinaryParser(new DataView(data)); - const nEntries = binaryParser.getInt(); // Total # of expected value chunks - if (nEntries === 0) { - return start + INT; - } else { - return parseNext(start + INT, nEntries); - } // Skip 4 bytes for int - - - async function parseNext(start, nEntries) { - - let range = {start: start, size: 500}; - let chunkSize = 0; - let p0 = start; - - let data = await file.read(range.start, range.size); - let binaryParser = new BinaryParser(new DataView(data)); - binaryParser.getString(); // type - binaryParser.getString(); // unit - binaryParser.getInt(); // binSize - const nValues = version < 9 ? binaryParser.getInt() : binaryParser.getLong(); - - chunkSize += binaryParser.position + nValues * (version < 9 ? DOUBLE : FLOAT); - - range = {start: start + chunkSize, size: INT}; - data = await file.read(range.start, range.size); - binaryParser = new BinaryParser(new DataView(data)); - const nChrScaleFactors = binaryParser.getInt(); - chunkSize += (INT + nChrScaleFactors * (INT + (version < 9 ? DOUBLE : FLOAT))); - - - nEntries--; - if (nEntries === 0) { - return p0 + chunkSize; - } else { - return parseNext(p0 + chunkSize, nEntries); - } - } - } - - getZoomIndexForBinSize(binSize, unit) { - - unit = unit || "BP"; - - let resolutionArray; - if (unit === "BP") { - resolutionArray = this.bpResolutions; - } else if (unit === "FRAG") { - resolutionArray = this.fragResolutions; - } else { - throw new Error("Invalid unit: " + unit); - } - - for (let i = 0; i < resolutionArray.length; i++) { - if (resolutionArray[i] === binSize) return i; - } - - return -1; - } - - parseNormVectorEntry(binaryParser) { - const type = binaryParser.getString(); //15 - const chrIdx = binaryParser.getInt(); //4 - const unit = binaryParser.getString(); //3 - const binSize = binaryParser.getInt(); //4 - const filePosition = binaryParser.getLong(); //8 - const sizeInBytes = this.version < 9 ? binaryParser.getInt() : binaryParser.getLong(); //4:8 - const key = type + "_" + chrIdx + "_" + unit + "_" + binSize; - // TODO -- why does this not work? NormalizationVector.getNormalizationVectorKey(type, chrIdx, unit, binSize); - - if (!this.normalizationTypes.includes(type)) { - this.normalizationTypes.push(type); - } - this.normVectorIndex[key] = {filePosition: filePosition, size: sizeInBytes}; - } - - getFileChrName(chrAlias) { - if (this.chrAliasTable.hasOwnProperty(chrAlias)) { - return this.chrAliasTable[chrAlias] - } else { - return chrAlias - } - } - - - // NOTE sties are not currently used - // async getSites(chrName) { - // let sites = this.fragmentSitesCache[chrName]; - // if (!sites) { - // if (this.fragmentSitesIndex) { - // const entry = self.fragmentSitesIndex[chrName]; - // if (entry && entry.nSites > 0) { - // sites = await this.readSites(entry.position, entry.nSites) - // this.fragmentSitesCache[chrName] = sites; - // } - // } - // } - // return sites; - // } - // - - } - - - function getNormalizationVectorKey(type, chrIdx, unit, resolution) { - return type + "_" + chrIdx + "_" + unit + "_" + resolution; - } - - function isGoogleDrive(url) { - return url.indexOf("drive.google.com") >= 0 || url.indexOf("www.googleapis.com/drive") > 0 - } - - class Block { - constructor(blockNumber, zoomData, records, idx) { - this.blockNumber = blockNumber; - this.zoomData = zoomData; - this.records = records; - this.idx = idx; - } - } - - - class BlockCache { - - constructor() { - this.resolution = undefined; - this.map = new LRU(6); - } - - set(resolution, key, value) { - if (this.resolution !== resolution) { - this.map.clear(); - } - this.resolution = resolution; - this.map.set(key, value); - } - - get(resolution, key) { - return this.resolution === resolution ? this.map.get(key) : undefined; - } - - has(resolution, key) { - return this.resolution === resolution && this.map.has(key); - } - } - - class Straw { - - constructor(config) { - this.config = config; - this.hicFile = new HicFile(config); - } - - async getMetaData() { - return await this.hicFile.getMetaData() - } - - //straw [:x1:x2] [:y1:y2] - async getContactRecords(normalization, region1, region2, units, binsize) { - return this.hicFile.getContactRecords(normalization, region1, region2, units, binsize); - } - - async getNormalizationOptions() { - return this.hicFile.getNormalizationOptions() - } - - async getNVI() { - await this.hicFile.getNormVectorIndex(); - return this.hicFile.config.nvi; - } - - async printIndexStats() { - await this.hicFile.printIndexStats(); - } - - getFileChrName(chrAlias) { - if (this.hicFile.chrAliasTable.hasOwnProperty(chrAlias)) { - return this.hicFile.chrAliasTable[chrAlias] - } else { - return chrAlias - } - } - } - - function isGoogleURL(url) { - return (url.includes("googleapis") && !url.includes("urlshortener")) || - isGoogleStorageURL(url) || - isGoogleDriveURL(url) - } - - function isGoogleStorageURL(url) { - return url.startsWith("gs://") || - url.startsWith("https://www.googleapis.com/storage") || - url.startsWith("https://storage.cloud.google.com") || - url.startsWith("https://storage.googleapis.com"); - } - - function isGoogleDriveURL(url) { - return url.indexOf("drive.google.com") >= 0 || url.indexOf("www.googleapis.com/drive") > 0 - } - - // %23 %24 %25 %26 %27 %28 %29 %2A %2B %2C %2F %3A %3B %3D %3F %40 %5B %5D - const encodings = new Map(); - encodings.set("!", "%21"); - encodings.set("#", "%23"); - encodings.set("$", "%24"); - encodings.set("%", "%25"); - encodings.set("&", "%26"); - encodings.set("'", "%27"); - encodings.set("(", "%28"); - encodings.set(")", "%29"); - encodings.set("*", "%2A"); - encodings.set("+", "%2B"); - encodings.set(",", "%2C"); - encodings.set("/", "%2F"); - encodings.set(":", "%3A"); - encodings.set(";", "%3B"); - encodings.set("=", "%3D"); - encodings.set("?", "%3F"); - encodings.set("@", "%40"); - encodings.set("[", "%5B"); - encodings.set("]", "%5D"); - encodings.set(" ", "%20"); - - function getDriveDownloadURL(link) { - // Return a google drive download url for the sharable link - //https://drive.google.com/open?id=0B-lleX9c2pZFbDJ4VVRxakJzVGM - //https://drive.google.com/file/d/1_FC4kCeO8E3V4dJ1yIW7A0sn1yURKIX-/view?usp=sharing - var id = getGoogleDriveFileID(link); - return id ? "https://www.googleapis.com/drive/v3/files/" + id + "?alt=media&supportsTeamDrives=true" : link; - } - - function getGoogleDriveFileID(link) { - - //https://drive.google.com/file/d/1_FC4kCeO8E3V4dJ1yIW7A0sn1yURKIX-/view?usp=sharing - //https://www.googleapis.com/drive/v3/files/1w-tvo6p1SH4p1OaQSVxpkV_EJgGIstWF?alt=media&supportsTeamDrives=true" - - if (link.includes("/open?id=")) { - const i1 = link.indexOf("/open?id=") + 9; - const i2 = link.indexOf("&"); - if (i1 > 0 && i2 > i1) { - return link.substring(i1, i2) - } else if (i1 > 0) { - return link.substring(i1); - } - - } else if (link.includes("/file/d/")) { - const i1 = link.indexOf("/file/d/") + 8; - const i2 = link.lastIndexOf("/"); - return link.substring(i1, i2); - - } else if (link.startsWith("https://www.googleapis.com/drive")) { - let i1 = link.indexOf("/files/"); - const i2 = link.indexOf("?"); - if (i1 > 0) { - i1 += 7; - return i2 > 0 ? - link.substring(i1, i2) : - link.substring(i1) - } - } - - throw Error("Unknown Google Drive url format: " + link); - - - } - - /* - * @author Jim Robinson Dec-2020 - */ - - class IGVRemoteFile { - - - constructor(args) { - this.config = args; - this.url = args.path || args.url; - } - - - async read(position, length) { - - const range = {start: position, size: length}; - - return igvxhr$1.loadArrayBuffer(this.url, {range}); - - } - } - - /* - * The MIT License (MIT) - * - * Copyright (c) 2016-2020 The Regents of the University of California - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and - * associated documentation files (the "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the - * following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING - * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - */ - - const knownGenomes = { - - "hg19": [249250621, 243199373, 198022430], - "hg38": [248956422, 242193529, 198295559], - "mm10": [195471971, 182113224, 160039680], - "mm9": [197195432, 181748087, 159599783], - "dm6": [23513712, 25286936, 28110227] - - }; - - class Dataset { - - constructor(config) { - this.straw = new Straw(config); - } - - async init() { - - this.hicFile = this.straw.hicFile; - await this.hicFile.init(); - this.normalizationTypes = ['NONE']; - - this.genomeId = this.hicFile.genomeId; - this.chromosomes = this.hicFile.chromosomes; - this.bpResolutions = this.hicFile.bpResolutions; - this.wholeGenomeChromosome = this.hicFile.wholeGenomeChromosome; - this.wholeGenomeResolution = this.hicFile.wholeGenomeResolution; - - // Attempt to determine genomeId if not recognized - // if (!Object.keys(knownGenomes).includes(this.genomeId)) { - const tmp = matchGenome(this.chromosomes); - if (tmp) this.genomeId = tmp; - // } - } - - async getContactRecords(normalization, region1, region2, units, binsize) { - return this.straw.getContactRecords(normalization, region1, region2, units, binsize) - } - - async hasNormalizationVector(type, chr, unit, binSize) { - return this.straw.hicFile.hasNormalizationVector(type, chr, unit, binSize); - } - - clearCaches() { - this.colorScaleCache = {}; - } - - async getMatrix(chr1, chr2) { - return this.hicFile.getMatrix(chr1, chr2) - } - - getZoomIndexForBinSize(binSize, unit) { - var i, - resolutionArray; - - unit = unit || "BP"; - - if (unit === "BP") { - resolutionArray = this.bpResolutions; - } else if (unit === "FRAG") { - resolutionArray = this.fragResolutions; - } else { - throw new Error("Invalid unit: " + unit); - } - - for (i = 0; i < resolutionArray.length; i++) { - if (resolutionArray[i] === binSize) return i; - } - - return -1; - } - - getBinSizeForZoomIndex(zoomIndex, unit) { - var resolutionArray; - - unit = unit || "BP"; - - if (unit === "BP") { - resolutionArray = this.bpResolutions; - } else if (unit === "FRAG") { - resolutionArray = this.fragResolutions; - } else { - throw new Error("Invalid unit: " + unit); - } - - return resolutionArray[zoomIndex]; - } - - getChrIndexFromName(chrName) { - var i; - for (i = 0; i < this.chromosomes.length; i++) { - if (chrName === this.chromosomes[i].name) return i; - } - return undefined; - } - - compareChromosomes(otherDataset) { - const chrs = this.chromosomes; - const otherChrs = otherDataset.chromosomes; - if (chrs.length !== otherChrs.length) { - return false; - } - for (let i = 0; i < chrs.length; i++) { - if (chrs[i].size !== otherChrs[i].size) { - return false; - } - } - return true; - } - - isWholeGenome(chrIndex) { - return (this.wholeGenomeChromosome != null && this.wholeGenomeChromosome.index === chrIndex); - } - - async getNormVectorIndex() { - return this.hicFile.getNormVectorIndex() - } - - async getNormalizationOptions() { - return this.hicFile.getNormalizationOptions() - } - - /** - * Compare 2 datasets for compatibility. Compatibility is defined as from the same assembly, even if - * different IDs are used (e.g. GRCh38 vs hg38). - * - * Trust the ID for well-known assemblies (hg19, etc). However, for others compare chromosome lengths - * as its been observed that uniqueness of ID is not guaranteed. - * - * @param d1 - * @param d2 - */ - isCompatible(d2) { - const id1 = this.genomeId; - const id2 = d2.genomeId; - return ((id1 === "hg38" || id1 === "GRCh38") && (id2 === "hg38" || id2 === "GRCh38")) || - ((id1 === "hg19" || id1 === "GRCh37") && (id2 === "hg19" || id2 === "GRCh37")) || - ((id1 === "mm10" || id1 === "GRCm38") && (id2 === "mm10" || id2 === "GRCm38")) || - this.compareChromosomes(d2) - } - - static async loadDataset(config) { - - // If this is a local file, use the "blob" field for straw - if (isFile(config.url)) { - config.blob = config.url; - delete config.url; - } else { - // If this is a google url, add api KEY - if (isGoogleURL(config.url)) { - if (isGoogleDriveURL(config.url)) { - config.url = getDriveDownloadURL(config.url); - } - const copy = Object.assign({}, config); - config.file = new IGVRemoteFile(copy); - } - } - - const dataset = new Dataset(config); - await dataset.init(); - dataset.url = config.url; - return dataset - } - } - - function matchGenome(chromosomes) { - - if (chromosomes.length < 4) return undefined; - - const keys = Object.keys(knownGenomes); - - // Find a candidate - let candidate; - for (let chr of chromosomes) { - for (let key of keys) { - if (knownGenomes[key].includes(chr.size)) { - candidate = key; - break; - } - } - } - - // Confirm candidate - if (candidate) { - const chrSizes = new Set(chromosomes.map((chr) => chr.size)); - for (let sz of knownGenomes[candidate]) { - if (!chrSizes.has(sz)) { - return undefined; - } - } - return candidate; - } else { - return undefined; - } - - - } - - /* - * The MIT License (MIT) - * - * Copyright (c) 2016-2017 The Regents of the University of California - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and - * associated documentation files (the "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the - * following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING - * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - */ - - - /** - * @author Jim Robinson - */ - - - /** - * - * @param id - * @param chromosomes -- an array of hic.Chromosome objects. - * @constructor - */ - class Genome { - constructor(id, chromosomes) { - - this.id = id; - this.chromosomes = chromosomes; - - this.wgChromosomeNames = []; - this.chromosomeLookupTable = {}; - - // Alias for size for igv compatibility - this.genomeLength = 0; - for (let c of this.chromosomes) { - c.bpLength = c.size; - if ('all' !== c.name.toLowerCase()) { - this.genomeLength += c.size; - this.wgChromosomeNames.push(c.name); - } - } - - /** - * Maps chr aliases to the offical name. Deals with - * 1 <-> chr1, chrM <-> MT, IV <-> chr4, etc. - * @param str - */ - var chrAliasTable = {}; - - // The standard mappings - for (let chromosome of chromosomes) { - - const name = chromosome.name; - if (name.startsWith("arm_")) { - //Special rule for aidenlab ad-hoc names for dMel - const officialName = name.substring(4); - chrAliasTable[officialName] = name; - chrAliasTable["chr" + officialName] = name; - } else { - const alias = name.startsWith("chr") ? name.substring(3) : "chr" + name; - chrAliasTable[alias] = name; - if (name === "chrM") chrAliasTable["MT"] = "chrM"; - if (name === "MT") chrAliasTable["chrmM"] = "MT"; - } - this.chromosomeLookupTable[name.toLowerCase()] = chromosome; - } - - this.chrAliasTable = chrAliasTable; - - this.featureDB = new Map(); // Hash of name -> feature, used for search function. - - } - - getChromosomeName(str) { - var chr = this.chrAliasTable[str]; - return chr ? chr : str; - }; - - getChromosome(str) { - var chrname = this.getChromosomeName(str).toLowerCase(); - return this.chromosomeLookupTable[chrname]; - }; - - /** - * Return the genome coordinate for the give chromosome and position. - */ - getGenomeCoordinate(chr, bp) { - return this.getCumulativeOffset(chr.name) + bp; - }; - - getChromosomeForCoordinate(bp) { - var i = 0, - offset = 0, - l; - - for (i = 1; i < this.chromosomes.length; i++) { - l = this.chromosomes[i].size; - if (offset + l > bp) return this.chromosomes[i]; - offset += l; - } - return this.chromosomes[this.chromosomes.length - 1]; - } - - - /** - * Return the offset in genome coordinates (kb) of the start of the given chromosome - */ - getCumulativeOffset(chr) { - - const queryChr = this.getChromosomeName(chr); - - if (this.cumulativeOffsets === undefined) { - computeCumulativeOffsets$1.call(this); - } - return this.cumulativeOffsets[queryChr]; - } - - // Required for igv.js - getGenomeLength() { - return this.genomeLength; - } - - // Required for igv.js - addFeaturesToDB(featureList, config) { - - const insertFeature = (name, feature) => { - const current = this.featureDB.get(name); - if (current) { - feature = (feature.end - feature.start) > (current.end - current.start) ? feature : current; - } - this.featureDB.set(name, feature); - }; - - for (let feature of featureList) { - if (feature.name) { - insertFeature(feature.name.toUpperCase(), feature); - } - if (feature.gene && feature.gene.name) { - insertFeature(feature.gene.name.toUpperCase(), feature); - } - } - } - } - function computeCumulativeOffsets$1() { - - const cumulativeOffsets = {}; - let offset = 0; - // Skip first chromosome (its chr all). - for (let chromosome of this.chromosomes) { - if(chromosome.name === 'all') continue; - cumulativeOffsets[chromosome.name] = Math.floor(offset); - offset += (chromosome.size); - } - this.cumulativeOffsets = cumulativeOffsets; - } - - /* - * The MIT License (MIT) - * - * Copyright (c) 2016-2017 The Regents of the University of California - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and - * associated documentation files (the "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the - * following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING - * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - */ - - class State { - - constructor(chr1, chr2, locus, zoom, x, y, pixelSize, normalization) { - if (chr1 <= chr2) { - this.chr1 = chr1; - this['x'] = x; - - this.chr2 = chr2; - this['y'] = y; - } else { - // Transpose - this.chr1 = chr2; - this['x'] = y; - - this.chr2 = chr1; - this['y'] = x; - } - - this.zoom = zoom; - - if (undefined === normalization) { - console.warn("Normalization is undefined. Will use NONE"); - normalization = 'NONE'; - } - this.normalization = normalization; - - if (Number.isNaN(pixelSize)) { - pixelSize = 1; - } - this.pixelSize = pixelSize; - - this.locus = locus; - } - - // Getters and setters for width and height - // get width() { - // return this._width; - // } - // - // set width(value) { - // this._width = value; - // } - // - // get height() { - // return this._height; - // } - // - // set height(value) { - // this._height = value; - // } - - clampXY(dataset, viewDimensions) { - const { width, height } = viewDimensions; - const { chromosomes, bpResolutions } = dataset; - - const binSize = bpResolutions[this.zoom]; - const maxX = Math.max(0, chromosomes[this.chr1].size / binSize - width / this.pixelSize); - const maxY = Math.max(0, chromosomes[this.chr2].size / binSize - height / this.pixelSize); - - this.x = Math.min(Math.max(0, this.x), maxX); - this.y = Math.min(Math.max(0, this.y), maxY); - } - - async panWithZoom(zoom, pixelSize, anchorPx, anchorPy, binSize, browser, dataset, viewDimensions, bpResolutions){ - - const minPixelSize = await browser.minPixelSize(this.chr1, this.chr2, zoom); - pixelSize = Math.max(pixelSize, minPixelSize); - - // Genomic anchor -- this position should remain at anchorPx, anchorPy after state change - bpResolutions[this.zoom]; - const gx = (this.x + anchorPx / this.pixelSize) * bpResolutions[this.zoom].binSize; - const gy = (this.y + anchorPy / this.pixelSize) * bpResolutions[this.zoom].binSize; - - this.x = gx / binSize - anchorPx / pixelSize; - this.y = gy / binSize - anchorPy / pixelSize; - - this.zoom = zoom; - this.pixelSize = pixelSize; - - this.clampXY(dataset, viewDimensions); - - } - - panShift(dx, dy, browser, dataset, viewDimensions) { - - this.x += (dx / this.pixelSize); - this.y += (dy / this.pixelSize); - this.clampXY(dataset, viewDimensions); - - this.configureLocus(browser, dataset, viewDimensions); - - } - - async setWithZoom(zoom, viewDimensions, browser, dataset){ - - const {width, height} = viewDimensions; - - // bin = bin + pixel * bin/pixel = bin - const xCenter = this.x + (width/2) / this.pixelSize; - const yCenter = this.y + (height/2) / this.pixelSize; - - const binSize = dataset.bpResolutions[this.zoom]; - const binSizeNew = dataset.bpResolutions[zoom]; - - const scaleFactor = binSize / binSizeNew; - - const xCenterNew = xCenter * scaleFactor; - const yCenterNew = yCenter * scaleFactor; - - const minPixelSize = await browser.minPixelSize(this.chr1, this.chr2, zoom); - - this.pixelSize = Math.max(DEFAULT_PIXEL_SIZE, minPixelSize); - - const resolutionChanged = (this.zoom !== zoom); - - this.zoom = zoom; - this.x = Math.max(0, xCenterNew - width / (2 * this.pixelSize)); - this.y = Math.max(0, yCenterNew - height / (2 * this.pixelSize)); - - this.clampXY(dataset, viewDimensions); - - this.configureLocus(browser, dataset, viewDimensions); - - return resolutionChanged - } - - configureLocus(browser, dataset, viewDimensions){ - - const bpPerBin = dataset.bpResolutions[this.zoom]; - - const startBP1 = Math.round(this.x * bpPerBin); - const startBP2 = Math.round(this.y * bpPerBin); - - const chr1 = dataset.chromosomes[this.chr1]; - const chr2 = dataset.chromosomes[this.chr2]; - const pixelsPerBin = this.pixelSize; - const endBP1 = Math.min(chr1.size, Math.round(((viewDimensions.width / pixelsPerBin) * bpPerBin)) + startBP1); - const endBP2 = Math.min(chr2.size, Math.round(((viewDimensions.height / pixelsPerBin) * bpPerBin)) + startBP2); - - const x = { chr:chr1.name, start:startBP1, end:endBP1 }; - const y = { chr:chr2.name, start:startBP2, end:endBP2 }; - - this.locus = { x, y }; - } - - updateWithLoci(chr1Name, bpX, bpXMax, chr2Name, bpY, bpYMax, browser, width, height){ - - const bpResolutions = browser.getResolutions(); - - // bp/pixel - let bpPerPixelTarget = Math.max((bpXMax - bpX) / width, (bpYMax - bpY) / height); - let resolutionChanged; - let zoomNew; - if (true === browser.resolutionLocked) { - resolutionChanged = false; - zoomNew = this.zoom; - } else { - zoomNew = browser.findMatchingZoomIndex(bpPerPixelTarget, bpResolutions); - resolutionChanged = (zoomNew !== this.zoom); - } - - const { binSize:binSizeNew } = bpResolutions[zoomNew]; - const pixelSize = Math.min(MAX_PIXEL_SIZE, Math.max(1, binSizeNew / bpPerPixelTarget)); - const newXBin = bpX / binSizeNew; - const newYBin = bpY / binSizeNew; - - const { index:chr1Index } = browser.genome.getChromosome( chr1Name ); - const { index:chr2Index } = browser.genome.getChromosome( chr2Name ); - - const chrChanged = this.chr1 !== chr1Index || this.chr2 !== chr2Index; - - this.chr1 = chr1Index; - this.chr2 = chr2Index; - this.zoom = zoomNew; - this.x = newXBin; - this.y = newYBin; - this.pixelSize = pixelSize; - this.locus = - { - x: { chr: chr1Name, start: bpX, end: bpXMax }, - y: { chr: chr2Name, start: bpY, end: bpYMax } - }; - - return { chrChanged, resolutionChanged } - } - - sync(targetState, browser, genome, dataset){ - - const chr1 = genome.getChromosome(targetState.chr1Name); - const chr2 = genome.getChromosome(targetState.chr2Name); - - const bpPerPixelTarget = targetState.binSize/targetState.pixelSize; - - const zoomNew = browser.findMatchingZoomIndex(bpPerPixelTarget, dataset.bpResolutions); - const binSizeNew = dataset.bpResolutions[ zoomNew ]; - const pixelSizeNew = Math.min(MAX_PIXEL_SIZE, Math.max(1, binSizeNew / bpPerPixelTarget)); - - const xBinNew = targetState.binX * (targetState.binSize/binSizeNew); - const yBinNew = targetState.binY * (targetState.binSize/binSizeNew); - - const zoomChanged = (browser.state.zoom !== zoomNew); - const chrChanged = (browser.state.chr1 !== chr1.index || browser.state.chr2 !== chr2.index); - - this.chr1 = chr1.index; - this.chr2 = chr2.index; - this.zoom = zoomNew; - this.x = xBinNew; - this.y = yBinNew; - this.pixelSize = pixelSizeNew; - - this.configureLocus(browser, dataset, browser.contactMatrixView.getViewDimensions()); - - return { zoomChanged, chrChanged } - - } - - stringify() { - if (this.normalization) { - return `${this.chr1},${this.chr2},${this.zoom},${this.x},${this.y},0,0,${this.pixelSize},${this.normalization}` - } else { - return `${this.chr1},${this.chr2},${this.zoom},${this.x},${this.y},0,0,${this.pixelSize}` - } - } - - clone() { - return Object.assign(new State(), this); - } - - equals(state) { - const s1 = JSON.stringify(this); - const s2 = JSON.stringify(state); - return s1 === s2; - } - - async sizeBP(dataset, zoomIndex, pixels){ - const matrix = await dataset.getMatrix(this.chr1, this.chr2); - const { zoom } = matrix.getZoomDataByIndex(zoomIndex, 'BP'); - - // bp = pixel * (bp/bin) * (bin/pixel) = pixel * bp/pixel = bp - return pixels * (zoom.binSize/this.pixelSize) - } - - static parse(string) { - const tokens = string.split(","); - - if (tokens.length <= 7) { - // Backwards compatibility - return new State( - parseInt(tokens[0]), // chr1 - parseInt(tokens[1]), // chr2 - undefined, // locus - parseFloat(tokens[2]), // zoom - parseFloat(tokens[3]), // x - parseFloat(tokens[4]), // y - parseFloat(tokens[5]), // pixelSize - tokens.length > 6 ? tokens[6] : "NONE" // normalization - ) - } else { - return new State( - parseInt(tokens[0]), // chr1 - parseInt(tokens[1]), // chr2 - undefined, // locus - parseFloat(tokens[2]), // zoom - parseFloat(tokens[3]), // x - parseFloat(tokens[4]), // y - parseFloat(tokens[7]), // pixelSize - tokens.length > 8 ? tokens[8] : "NONE" // normalization - ) - } - } - - // Method 1: Convert the State object to a JSON object - toJSON() { - const json = - { - chr1: this.chr1, - chr2: this.chr2, - zoom: this.zoom, - x: this.x, - y: this.y, - pixelSize: this.pixelSize, - normalization: this.normalization || 'NONE' - }; - - if (this.locus) { - json.locus = this.locus; - } - - return json - } - - // Method 2: Parse a JSON object and create an instance of the State class - static fromJSON(json) { - return new State( - json.chr1, - json.chr2, - json.locus, - json.zoom, - json.x, - json.y, - json.pixelSize, - json.normalization - ); - } - - static default(configOrUndefined) { - const state = new State(0, 0, undefined, 0, 0, 1, "NONE"); - return state - } - - } - - /* - * The MIT License (MIT) - * - * Copyright (c) 2016-2017 The Regents of the University of California - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and - * associated documentation files (the "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the - * following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING - * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - */ - - async function geneSearch(genomeId, featureName) { - const searchServiceURL = `https://portals.broadinstitute.org/webservices/igv/locus?genome=${genomeId}&name=${encodeURIComponent(featureName)}`; - - try { - const data = await igvxhr$1.loadString(searchServiceURL); - const results = parseSearchResults(data); - - return results.length ? results[0] : undefined; - } catch (error) { - console.error(`Error fetching gene data for "${featureName}":`, error); - return undefined; - } - } - - - function parseSearchResults(data) { - const parsed = splitLines$6(data) - .filter(line => line.trim() !== '').map(line => line.split('\t')) - .filter(tokens => tokens.length >= 3).map(tokens => tokens[1]); - - return parsed - } - - // Contains "normalization vector index" (nvi values) for legacy (v8) hosted files from aidenlab, ENCODE, and 4DN. - // These values can speed up initialization by a few seconds. - var nvi = { - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2Fcombined.hic": "54386046426,55860", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2Fprimary.hic": "33860030033,37504", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2Freplicate.hic": "30849652794,55832", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2Fmaternal.hic": "1380542661,17185", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2Fpaternal.hic": "1389001777,17185", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fimr90%2Fin-situ%2Fcombined.hic": "13433880319,35723", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC001.hic": "3409347253,35975", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC002.hic": "4529947083,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC003.hic": "6894962500,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC004.hic": "3395593338,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC005.hic": "5204128636,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC006.hic": "3278363811,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC007.hic": "3585547340,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC008.hic": "4134197273,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC009.hic": "2851728310,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC010.hic": "1754216102,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC011.hic": "1716829574,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC012.hic": "4367980375,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC013.hic": "2309654671,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC014.hic": "5324950266,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC015.hic": "3132333594,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC016.hic": "3159154704,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC017.hic": "3262554627,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC018.hic": "3014216364,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC019.hic": "5025753246,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC020.hic": "5861584507,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC021.hic": "3542263275,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC022.hic": "5061949378,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC023.hic": "4816423919,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC024.hic": "2683781104,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC025.hic": "6522701781,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC026.hic": "6748846520,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC027.hic": "5642693007,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC028.hic": "2098921691,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC029.hic": "3886454027,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fagar%2FHIC030.hic": "2288984204,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fagar%2FHIC031.hic": "2115342419,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fpellet%2FHIC032.hic": "2063314324,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fsupernatant%2FHIC033.hic": "1933908457,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fdilution%2FHIC034.hic": "13555514595,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fdilution%2FHIC035.hic": "6129650900,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fdilution%2FHIC036.hic": "4307445019,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fdilution%2FHIC037.hic": "9375139867,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fdilution%2Fcombined.hic": "11664249584,33929", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2Fcombined_DpnII.hic": "7003537290,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC038.hic": "2099825544,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC039.hic": "2096900138,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC040.hic": "2593642141,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC041.hic": "2263919098,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC042.hic": "2684774693,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2Fcombined_noXlink.hic": "5574807456,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC043.hic": "2986114347,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC044.hic": "1916378621,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC045.hic": "746463126,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC046.hic": "2338476164,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC047.hic": "1167496250,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC048.hic": "2231690794,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC049.hic": "2782308678,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fimr90%2Fin-situ%2FHIC050.hic": "3633531346,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fimr90%2Fin-situ%2FHIC051.hic": "4063486444,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fimr90%2Fin-situ%2FHIC052.hic": "929756278,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fimr90%2Fin-situ%2FHIC053.hic": "2489657204,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fimr90%2Fin-situ%2FHIC054.hic": "4036419444,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fimr90%2Fin-situ%2FHIC055.hic": "4284185549,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fimr90%2Fin-situ%2FHIC056.hic": "4410546240,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fimr90%2Fdilution%2FHIC057.hic": "1491998259,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fhmec%2Fin-situ%2Fcombined.hic": "7266425111,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fhmec%2Fin-situ%2FHIC058.hic": "6532635593,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fhmec%2Fin-situ%2FHIC059.hic": "400684530,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fhmec%2Fin-situ%2FHIC060.hic": "645352187,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fhmec%2Fin-situ%2FHIC061.hic": "736291871,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fhmec%2Fin-situ%2FHIC062.hic": "762731037,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fhmec%2Fin-situ%2FHIC063.hic": "682917431,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fhmec%2Fdilution%2FHIC064.hic": "4550171307,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fnhek%2Fin-situ%2Fcombined.hic": "11897184911,35789", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fnhek%2Fin-situ%2FHIC065.hic": "5425943567,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fnhek%2Fin-situ%2FHIC066.hic": "5942869818,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fnhek%2Fin-situ%2FHIC067.hic": "5191049261,35647", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fnhek%2Fdilution%2FHIC068.hic": "2713318801,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fk562%2Fin-situ%2Fcombined.hic": "12641555389,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fk562%2Fin-situ%2FHIC069.hic": "5630177461,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fk562%2Fin-situ%2FHIC070.hic": "5926611269,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fk562%2Fin-situ%2FHIC071.hic": "2486191351,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fk562%2Fin-situ%2FHIC072.hic": "2281343366,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fk562%2Fin-situ%2FHIC073.hic": "2173074239,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fk562%2Fin-situ%2FHIC074.hic": "2463700999,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fkbm7%2Fin-situ%2Fcombined.hic": "14661922519,35639", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fkbm7%2Fin-situ%2FHIC075.hic": "3685310515,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fkbm7%2Fin-situ%2FHIC076.hic": "5833658487,35891", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fkbm7%2Fin-situ%2FHIC077.hic": "2406346486,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fkbm7%2Fin-situ%2FHIC078.hic": "5241454987,35919", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fkbm7%2Fin-situ%2FHIC079.hic": "6297234263,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fhuvec%2Fin-situ%2Fcombined.hic": "9193858096,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fhuvec%2Fin-situ%2FHIC080.hic": "5171405536,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fhuvec%2Fin-situ%2FHIC081.hic": "3489767688,35891", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fhuvec%2Fin-situ%2FHIC082.hic": "4243339375,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fhuvec%2Fdilution%2FHIC083.hic": "1497495406,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fhela%2Fin-situ%2Fcombined.hic": "7923332224,35593", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fhela%2Fin-situ%2FHIC084.hic": "867699123,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fhela%2Fin-situ%2FHIC085.hic": "3669518514,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fhela%2Fin-situ%2FHIC086.hic": "5306474712,35595", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fhela%2Fin-situ%2FHIC087.hic": "1490963755,36397", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2Fcombined.hic": "8956382853,50248", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2FHIC088.hic": "1874185366,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2FHIC089.hic": "1301165236,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2FHIC090.hic": "1105246282,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2FHIC091.hic": "1338325770,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2FHIC092.hic": "1307918730,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2FHIC093.hic": "755136918,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2FHIC094.hic": "1606583694,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2FHIC095.hic": "2039711245,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2FHIC096.hic": "1909573053,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2FHIC097.hic": "1826710712,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2FHIC098.hic": "1998793575,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2FHIC099.hic": "1007740962,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2FHIC100.hic": "736464120,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2FHIC101.hic": "980505082,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2FHIC102.hic": "1116083646,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fdilution%2FHIC103.hic": "1096994310,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fdilution%2FHIC104.hic": "841063882,32102", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC105.hic": "107742864,36479", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC106.hic": "134295912,36479", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC107.hic": "110228014,36479", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC108.hic": "102761401,36479", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC109.hic": "100461491,36479", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC110.hic": "88828472,36479", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC111.hic": "81471064,36479", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC112.hic": "92297035,36479", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC113.hic": "65503916,36479", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC114.hic": "49181188,36479", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC115.hic": "46471102,36479", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC116.hic": "64284432,36479", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC117.hic": "60434076,36479", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC118.hic": "45248563,36479", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC119.hic": "60288782,36479", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC120.hic": "136888414,36479", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC121.hic": "125009003,33681", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC122.hic": "154011688,34127", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC123.hic": "177663372,35293", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC124.hic": "382186226,35245", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC125.hic": "158160717,35271", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC127.hic": "110261177,34659", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC128.hic": "246131875,35509", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC129.hic": "260160119,35667", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC130.hic": "117479562,34681", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC131.hic": "81508929,34673", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC132.hic": "105959102,34895", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC133.hic": "91504812,33451", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC134.hic": "52222546,33737", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC135.hic": "57763085,34159", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC136.hic": "50618489,33731", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC137.hic": "193163606,33363", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC138.hic": "229876152,33777", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC139.hic": "201783666,33571", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC140.hic": "281163862,34125", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC141.hic": "275969727,33935", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC142.hic": "275020431,34125", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC144.hic": "223834810,34177", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC145.hic": "296632653,33937", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC146.hic": "290945216,33961", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC147.hic": "234459964,34231", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC148.hic": "295457850,34039", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC149.hic": "113569632,35695", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC150.hic": "304381897,33963", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC151.hic": "289314545,33805", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC152.hic": "284320182,33803", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC153.hic": "401393947,34659", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC154.hic": "188065488,36479", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC155.hic": "299157119,33967", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC156.hic": "279289244,33787", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC157.hic": "254852119,33917", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC158.hic": "195969660,33477", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC159.hic": "185720388,36479", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC160.hic": "227709279,33599", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC161.hic": "157225076,33209", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC162.hic": "105703444,32033", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC163.hic": "122665658,32121", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC164.hic": "228048231,33761", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC165.hic": "114440819,32011", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC166.hic": "285147558,33891", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC167.hic": "363116754,33943", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC168.hic": "119592158,31937", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC169.hic": "236853872,33785", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC170.hic": "195187639,33395", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC171.hic": "208044058,33309", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC172.hic": "144645916,32877", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC173.hic": "119115941,32203", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC175.hic": "178030481,33525", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC176.hic": "117220136,32169", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC177.hic": "128586196,32659", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC178.hic": "191419141,33629", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC179.hic": "141556748,32959", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC180.hic": "199825102,33185", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC181.hic": "301022688,33783", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC182.hic": "185384453,33205", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC183.hic": "202189264,36367", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC184.hic": "37464475,36479", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC185.hic": "161938278,36099", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC186.hic": "133853166,36179", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC188.hic": "128068030,36237", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC189.hic": "148053886,36177", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC190.hic": "198946958,35803", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC191.hic": "226584564,36063", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC192.hic": "194412797,36341", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC193.hic": "176408194,36479", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC194.hic": "207215649,36055", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC195.hic": "175185530,36315", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC196.hic": "168969337,36479", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC197.hic": "121231252,36339", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC198.hic": "92713752,36479", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC199.hic": "105130500,36479", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC200.hic": "114526350,36479", - "hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC201.hic": "122689717,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fhap1%2Fin-situ%2Fcombined.hic": "9614983328,36479", - "s3.amazonaws.com%2Fhicfiles%2Fexternal%2Fctbp_8_4_17%2Fall_intra_megabase_michrom.hic": "154205644,10960", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2Fdel-Xa-combined.hic": "8843305329,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FdelXa-chrX-diploid.hic": "11173520,1498", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FWT-combined.hic": "13365182403,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FWT-chrX-diploid.hic": "17343459,1498", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FHIC002.hic": "4279298739,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FHIC003.hic": "3027365532,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FHIC004.hic": "2896130835,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FHIC005.hic": "4717830071,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FHIC006.hic": "5066210154,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FHIC007.hic": "3069516128,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2Fdel-Xi-combined.hic": "14551096423,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FdelXi-chrX-diploid.hic": "17362477,1498", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FHIC008.hic": "2572386655,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FHIC009.hic": "2935931663,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FHIC010.hic": "2019085070,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FHIC011.hic": "6087610814,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FHIC012.hic": "2809618194,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FHIC013.hic": "2572386655,36479", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fpatski%2FDarrowHuntley-2015%2Fcombined.hic": "6950423609,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fpatski%2FDarrowHuntley-2015%2Fpaternal.hic": "220592749,15691", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fpatski%2FDarrowHuntley-2015%2Fmaternal.hic": "323233095,15691", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fpatski%2FDarrowHuntley-2015%2FHIC014.hic": "3183235800,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fpatski%2FDarrowHuntley-2015%2FHIC015.hic": "1739539801,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fpatski%2FDarrowHuntley-2015%2FHIC016.hic": "1105912758,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fpatski%2FDarrowHuntley-2015%2FHIC017.hic": "1060773319,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fpatski%2FDarrowHuntley-2015%2FHIC018.hic": "1203679874,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fpatski%2FDarrowHuntley-2015%2FHIC019.hic": "3321955269,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Frhesus%2FDarrowHuntley-2015%2FHIC020.hic": "7108980626,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fcola%2FDarrowHuntley-2015%2FHIC021.hic": "3906448676,34955", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fassembly%2Faedes%2Fcombined.hic": "390780490,2245", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fassembly%2Fhs2-hic.hic": "1960284186,33561", - "hicfiles.s3.amazonaws.com%2Fhiseq%2Fassembly%2FCpipJ3.hic": "766279097,4381", - "s3.amazonaws.com%2Fhicfiles%2Fexternal%2Fphanstiel%2Fupdated_O%2FSnyder_O.hic": "8046980555,18679", - "s3.amazonaws.com%2Fhicfiles%2Fexternal%2Fphanstiel%2FA_inter.hic": "10986005145,18679", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Funtreated%2Funsynchronized%2Fcombined.hic": "30439217680,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftreated_6hr%2Funsynchronized%2Fcombined.hic": "33255540403,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2Fdeep%2F20min_withdraw_combined.hic": "11078436933,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2Fdeep%2F40min_withdraw_combined.hic": "11031830038,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2Fdeep%2F60min_withdraw_combined.hic": "10312725340,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2Fdeep%2F180min_withdraw_combined.hic": "10038610214,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Funtreated%2Funsynchronized%2FHIC001.hic": "8004335785,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Funtreated%2Funsynchronized%2FHIC002.hic": "8453215933,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Funtreated%2Funsynchronized%2FHIC003.hic": "9118406189,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Funtreated%2Funsynchronized%2FHIC004.hic": "5973342894,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Funtreated%2Funsynchronized%2FHIC005.hic": "6846576837,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Funtreated%2Funsynchronized%2FHIC006.hic": "6075148017,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Funtreated%2Funsynchronized%2FHIC007.hic": "8192366992,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftreated_6hr%2Funsynchronized%2FHIC008.hic": "6844159653,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftreated_6hr%2Funsynchronized%2FHIC009.hic": "7282063059,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftreated_6hr%2Funsynchronized%2FHIC010.hic": "10410578833,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftreated_6hr%2Funsynchronized%2FHIC011.hic": "8192366992,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftreated_6hr%2Funsynchronized%2FHIC012.hic": "7223422850,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftreated_6hr%2Funsynchronized%2FHIC013.hic": "7435986997,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftreated_6hr%2Funsynchronized%2FHIC014.hic": "9120113605,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Funtreated%2Fsynchronized%2Fcombined.hic": "4170577904,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Funtreated%2Fsynchronized%2FHIC015.hic": "1504084990,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Funtreated%2Fsynchronized%2FHIC016.hic": "1686244500,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Funtreated%2Fsynchronized%2FHIC017.hic": "1804802410,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Funtreated%2Fsynchronized%2FHIC018.hic": "1533942067,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftreated_6hr%2Fsynchronized%2Fcombined.hic": "4572390198,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftreated_6hr%2Fsynchronized%2FHIC019.hic": "1543609666,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftreated_6hr%2Fsynchronized%2FHIC020.hic": "1814133288,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftreated_6hr%2Fsynchronized%2FHIC021.hic": "1942698243,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftreated_6hr%2Fsynchronized%2FHIC022.hic": "1873587413,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2Funtreated%2FRao-2017-HIC049.hic": "405127557,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2Funtreated%2FRao-2017-HIC060.hic": "326681741,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2Funtreated%2FRao-2017-HIC061.hic": "300908673,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_20min%2FRao-2017-HIC050.hic": "481758242,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_20min%2FRao-2017-HIC051.hic": "417577401,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_40min%2FRao-2017-HIC052.hic": "419353227,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_40min%2FRao-2017-HIC053.hic": "411554953,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_60min%2FRao-2017-HIC054.hic": "386655891,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_60min%2FRao-2017-HIC055.hic": "402170701,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_240min%2FRao-2017-HIC057.hic": "735906308,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min%2FRao-2017-HIC058.hic": "443789827,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min%2FRao-2017-HIC059.hic": "491422615,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min%2FRao-2017-HIC062.hic": "320261375,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min%2FRao-2017-HIC063.hic": "306590499,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min_withdraw_20min%2FRao-2017-HIC032S.hic": "367051742,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min_withdraw_20min%2FRao-2017-HIC033S.hic": "344555339,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min_withdraw_40min%2FRao-2017-HIC036S.hic": "349392947,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min_withdraw_40min%2FRao-2017-HIC037S.hic": "317714554,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min_withdraw_60min%2FRao-2017-HIC040S.hic": "266786397,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min_withdraw_60min%2FRao-2017-HIC041S.hic": "279445530,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min_withdraw_180min%2FRao-2017-HIC044S.hic": "898418269,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min_withdraw_180min%2FRao-2017-HIC045S.hic": "961006347,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min_withdraw_360min%2FRao-2017-HIC064.hic": "833576408,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min_withdraw_360min%2FRao-2017-HIC065.hic": "840881418,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min_withdraw_1080min%2FRao-2017-HIC066.hic": "980958864,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min_withdraw_1080min%2FRao-2017-HIC067.hic": "882023129,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min_withdraw_1440min%2FRao-2017-HIC068.hic": "1110292630,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min_withdraw_1440min%2FRao-2017-HIC069.hic": "1001747023,36479", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fexternal%2Frowley_nichols_mol_cell_2017%2FCP190_HiChIP.hic": "144107588,6976", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fexternal%2Frowley_nichols_mol_cell_2017%2FH3K27ac_HiChIP_combined.hic": "43171370,5233", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fexternal%2Frowley_nichols_mol_cell_2017%2FH3K27me3_HiChIP_combined.hic": "42906472,5233", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fexternal%2Frowley_nichols_mol_cell_2017%2FPol2_ChIAPET.hic": "41992430,6976", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fexternal%2Frowley_nichols_mol_cell_2017%2FPol2S2_HiChIP.hic": "145842743,6976", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fexternal%2Frowley_nichols_mol_cell_2017%2FArabidopsis_Wang2015_Liu2016.hic": "1134391078,4984", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fexternal%2Frowley_nichols_mol_cell_2017%2FElegans_Crane2015.hic": "387127568,8758", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fexternal%2Frowley_nichols_mol_cell_2017%2FNcrassa_Galazka2016.hic": "26555511,27725", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fexternal%2Frowley_nichols_mol_cell_2017%2FPfalciparum_trophozoite_Ay2014.hic": "15640893,13948", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fduan%2FE-Me-A.hic": "6897251,23348", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fduan%2FE-Me-B.hic": "4959088,23348", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fduan%2FE-Mp-A.hic": "5232286,23348", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fduan%2FE-Mp-B.hic": "5105292,23348", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fduan%2FH-Me-A.hic": "6900072,23348", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fduan%2FH-Me-B.hic": "8653258,23348", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fduan%2FH-Mp-A.hic": "7999058,23348", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fduan%2FH-Mp-B.hic": "8774657,23348", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fdekker%2F4dn%2Fh1hesc.hic": "23671753603,36479", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fdekker%2F4dn%2Fh1hesc_rep1.hic": "23671754721,36479", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fdekker%2F4dn%2Fh1hesc_rep2.hic": "22269909910,36479", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fdekker%2F4dn%2Fhffc6_rep1.hic": "19016661622,36479", - "hicfiles.s3.amazonaws.com%2Fexternal%2Flieberman_aiden_van_berkum%2FGM06990_NcoI.hic": "480725203,36479", - "hicfiles.s3.amazonaws.com%2Fexternal%2Flieberman_aiden_van_berkum%2F302NH.hic": "99948617,36479", - "hicfiles.s3.amazonaws.com%2Fexternal%2Flieberman_aiden_van_berkum%2FK562.hic": "470263605,36151", - "hicfiles.s3.amazonaws.com%2Fexternal%2Flieberman_aiden_van_berkum%2FGM06990_HindIII.hic": "293706559,36289", - "hicfiles.s3.amazonaws.com%2Fexternal%2Flieberman_aiden_van_berkum%2FGM06990_rep_HindIII.hic": "309673862,36087", - "hicfiles.s3.amazonaws.com%2Fexternal%2Frudan%2Fcanis-lupus-rep1.hic": "1531151371,56905", - "hicfiles.s3.amazonaws.com%2Fexternal%2Frudan%2Fcanis-lupus-rep2.hic": "2851437676,56905", - "hicfiles.s3.amazonaws.com%2Fexternal%2Frudan%2Fmouse-rep1.hic": "582052544,32102", - "hicfiles.s3.amazonaws.com%2Fexternal%2Frudan%2Fmacaque-rep1.hic": "698509182,32102", - "hicfiles.s3.amazonaws.com%2Fexternal%2Frudan%2Fmacaque-rep2.hic": "461410393,32102", - "hicfiles.s3.amazonaws.com%2Fexternal%2Frudan%2Frabbit-rep1.hic": "691045338,33561", - "hicfiles.s3.amazonaws.com%2Fexternal%2Frudan%2Frabbit-rep2.hic": "668888336,33561", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fsexton%2Fcombined.hic": "50650087,4486", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fkalhor%2Ftcc-hindiii.hic": "1071142023,16500", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fkalhor%2Ftcc-mboi.hic": "1508851093,16448", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fkalhor%2Fnon-tcc-hindiii.hic": "395179229,36093", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fkalhor%2Ftcc-combined.hic": "1050423847,36479", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fdixon%2Fmm9-hindiii%2Fsplit-read-run.hic": "9599984876,32102", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fdixon%2Fhesc-hindiii.hic": "1952555632,36479", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fdixon%2Fimr90-hindiii.hic": "9691260435,18679", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fdixon%2Fmm9-cortex.hic": "3712072953,32102", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fzhang%2Fatm-i-scei-chr18.hic": "2083350075,16438", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fzhang%2Fatm-i-scei-chr2.hic": "3362049644,16360", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fzhang%2Fatm-i-scei-chr7.hic": "1658399854,16438", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fzhang%2Fwt-i-scei-chr15.hic": "866691249,16438", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fzhang%2Fwt-i-scei-chr2.hic": "3304782795,16386", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fnagano%2Fcell-1.hic": "23673506,32102", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fnagano%2Fcell-2.hic": "26873280,30643", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fnagano%2Fcell-3.hic": "31066362,30643", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fnagano%2Fcell-4.hic": "16807724,30643", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fnagano%2Fcell-5.hic": "28665065,30643", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fnagano%2Fcell-6.hic": "13124158,30643", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fnagano%2Fcell-7.hic": "15118945,30643", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fnagano%2Fcell-8.hic": "68316814,32102", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fnagano%2Fcell-9.hic": "18965101,30643", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fnagano%2Fcell-10.hic": "17020666,30643", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fjin%2Fimr90%2Fcombined.hic": "6526601242,36427", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fjin%2Fimr90%2Frep1.hic": "1861562891,36401", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fjin%2Fimr90%2Frep2.hic": "3061013635,36479", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fjin%2Fimr90%2Frep3.hic": "1564588211,35969", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fjin%2Fimr90%2Frep4.hic": "1255543175,36153", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fjin%2Fimr90%2Frep5.hic": "974683253,36179", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fjin%2Fimr90%2Frep6.hic": "1040805629,36053", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fjin%2Fimr90-tnf-alpha%2Fcombined.hic": "8424080116,36401", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fjin%2Fimr90-tnf-alpha%2Frep1.hic": "2697976702,36295", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fjin%2Fimr90-tnf-alpha%2Frep3.hic": "1718610467,36159", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fjin%2Fimr90-tnf-alpha%2Frep4.hic": "2029519405,36101", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fjin%2Fimr90-tnf-alpha%2Frep5.hic": "985310855,36069", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fjin%2Fimr90-tnf-alpha%2Frep6.hic": "1418750480,35967", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fcheng%2Fmhh-call-4-cell-line.hic": "538380253,35351", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fcheng%2Fprimary-b-all.hic": "773764191,35793", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fcheng%2Fnormal-b-cell-line.hic": "336271459,35005", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fcheng%2Frl-cell-line.hic": "484807998,35351", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fhou%2Fkc167-biorep.hic": "135932435,8758", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fhou%2Fkc167-techrep1.hic": "160355961,8758", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fhou%2Fkc167-techrep2.hic": "188809887,8758", - "hicfiles.s3.amazonaws.com%2Fexternal%2Flin%2Fpre-prob-egs.hic": "2237792858,15483", - "hicfiles.s3.amazonaws.com%2Fexternal%2Flin%2Fprob-egs.hic": "5744720377,16438", - "hicfiles.s3.amazonaws.com%2Fexternal%2Flin%2Fprob-fa.hic": "2174866215,16438", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fli%2Fhct116-rnapii-pilot.hic": "396366166,35999", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fli%2Fhela-rnapii-pilot.hic": "882516759,35107", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fli%2Fk562-rnapii-pilot.hic": "1131576189,35969", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fli%2Fk562-rnapii-saturated.hic": "571583828,36291", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fli%2Fmcf7-rnapii-saturated.hic": "1282547841,36035", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fli%2Fnb4-rnapii-pilot.hic": "761614686,34861", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fjung%2Fmouse_sperm.hic": "1730231642,29184", - "hicfiles.s3.amazonaws.com%2Fexternal%2Ftang%2Fgm12878.hic": "1953518212,20505", - "hicfiles.s3.amazonaws.com%2Fexternal%2Frutledge%2FSRR1791299.hic": "5723484,11956", - "hicfiles.s3.amazonaws.com%2Fexternal%2Frutledge%2FSRR1791297.hic": "16534743,23348", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fzuin%2Fhek293t-rad21cv-hrv.hic": "5094525579,36289", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fzuin%2Fhek293t-rad21cv-hrv-rep1.hic": "2574358912,36373", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fzuin%2Fhek293t-rad21cv-hrv-rep2.hic": "3417099433,36243", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fzuin%2Fhek293t-rad21cv-tev.hic": "4785157552,36323", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fzuin%2Fhek293t-rad21cv-tev-rep1.hic": "2648268465,36321", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fzuin%2Fhek293t-rad21cv-tev-rep2.hic": "2994727980,36107", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fzuin%2Fhek293t-sirna-ctcf.hic": "5391791815,36063", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fzuin%2Fhek293t-sirna-ctcf-rep1.hic": "3325842095,36269", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fzuin%2Fhek293t-sirna-ctcf-rep2.hic": "3096215920,36167", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fzuin%2Fhek293t-sirna-ctrl.hic": "3830902383,36167", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fzuin%2Fhek293t-sirna-ctrl-rep1.hic": "1346712252,36079", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fzuin%2Fhek293t-sirna-ctrl_rep2.hic": "3098067367,36271", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fay%2Fp-falciparum-3d7-0h-hiseq.hic": "38174042,21889", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fay%2Fp-falciparum-3d7-18h-hiseq.hic": "26506099,21889", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fay%2Fp-falciparum-3d7-18h-hiseq-non-crosslinked_control.hic": "3545496,21889", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fay%2Fp-falciparum-3d7-36h-hiseq.hic": "70754194,21889", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fnaumova%2Fhelas3%2Fg1mid-r1.hic": "200863476,17185", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fnaumova%2Fhelas3%2Fm-r1.hic": "249021190,17185", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fnaumova%2Fhelas3%2Fm-r2.hic": "212341157,17185", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fnaumova%2Fhelas3ccl2p2%2Fg1-0-25fa.hic": "583572265,17185", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fnaumova%2Fhelas3ccl2p2%2Fg1-1fa.hic": "354502306,17185", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fnaumova%2Fhelas3ccl2p2%2Fm-0-25fa.hic": "149308791,17185", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fnaumova%2Fhelas3ccl2p2%2Fm-98percent.hic": "778175225,17185", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fnaumova%2Fhelas3ccl2p2%2Fm-1fa.hic": "158091047,17185", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fnaumova%2Fhff1%2Fcchic-hff1-ns-r1.hic": "801670039,17185", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fnaumova%2Fhff1%2Fcchic-hff1-m-r1.hic": "875922086,17185", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fnaumova%2Fk562%2Fm-r1.hic": "130959943,17185", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fnaumova%2Fk562%2Fm-r2.hic": "237861106,17185", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fsofueva%2FmAST-WT.hic": "496104039,30643", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fsofueva%2FmAST-WT-adv-cre.hic": "438608517,30643", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fsofueva%2FmAST-floxed-rep1.hic": "446205712,32102", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fsofueva%2FmAST-floxed-rep2.hic": "386354767,32102", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fsofueva%2FmAST-deleted-rep1.hic": "621998722,30643", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fsofueva%2FmAST-deleted-rep2.hic": "583840829,32102", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fsofueva%2FmNSC-floxed-rep1.hic": "801290988,30643", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fsofueva%2FmNSC-floxed-rep2.hic": "819406658,30643", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fsofueva%2FmNSC-deleted-rep1.hic": "792825269,32102", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fsofueva%2FmNSC-deleted-rep2.hic": "746189884,30643", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fsofueva%2FmNSC-WT.hic": "309353372,30643", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fsofueva%2FmNSC-WT-OHT.hic": "274229679,30643", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fseitan%2FTcell-Rad21KO-R1.hic": "1490362251,32102", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fseitan%2FTcell-Rad21KO-R3.hic": "2403664421,32102", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fseitan%2FTcell-Rad21WT-R1.hic": "1377124538,32102", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fseitan%2FTcell-Rad21WT-R3.hic": "2646201369,32102", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fmoissiard%2Fcrh6-mutant.hic": "105261071,10217", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fmoissiard%2FWT.hic": "127506388,10217", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fgrob%2FCol.hic": "153638500,10217", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fgrob%2Fcrwn1.hic": "211213220,10217", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fgrob%2Fcrwn4.hic": "134236837,10217", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fxie%2Fprimary.hic": "92936173,10217", - "hicfiles.s3.amazonaws.com%2Fexternal%2Ffeng%2F6wt-control6wt337.hic": "318737891,10217", - "hicfiles.s3.amazonaws.com%2Fexternal%2Ffeng%2F6wt-control6wt67.hic": "348123956,10217", - "hicfiles.s3.amazonaws.com%2Fexternal%2Ffeng%2F6wt337.hic": "251107279,10217", - "hicfiles.s3.amazonaws.com%2Fexternal%2Ffeng%2F6wt67.hic": "351840994,10217", - "hicfiles.s3.amazonaws.com%2Fexternal%2Ffeng%2FCol0.hic": "345969497,10217", - "hicfiles.s3.amazonaws.com%2Fexternal%2Ffeng%2Fclf28-swn7.hic": "299585025,10217", - "hicfiles.s3.amazonaws.com%2Fexternal%2Ffeng%2Fcmt3-11.hic": "253427706,10217", - "hicfiles.s3.amazonaws.com%2Fexternal%2Ffeng%2Fddm1-2.hic": "303626924,10217", - "hicfiles.s3.amazonaws.com%2Fexternal%2Ffeng%2Fmet1-3.hic": "347697973,10217", - "hicfiles.s3.amazonaws.com%2Fexternal%2Ffeng%2Fsuvh4-suvh5-suvh6.hic": "263122019,10217", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fma%2FDNase-HiC-WG-K562.hic": "892955840,18679", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fma%2FDNaseHiC-WG-H1.hic": "696922695,18679", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fma%2FtargetedDNaseHiC-lincRNA-K562-rep1.hic": "341917716,18679", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fma%2FtargeredDNaseHiC-lincRNA-K562-rep2.hic": "214841185,18679", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fma%2FtargetedDNaseHiC-lincRNA-H1-rep1.hic": "616326137,18679", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fma%2FtargetedDNaseHiC-lincRNA-H1-rep2.hic": "579654013,18679", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fma%2FtargetedDNaseHiC-pe-H1-rep1.hic": "519810544,18679", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fma%2FtargetedDNaseHiC-pe-K562-rep1.hic": "199553123,18679", - "hicfiles.s3.amazonaws.com%2Fexternal%2Frowley%2FKc167_DpnII.hic": "1319373594,6976", - "hicfiles.s3.amazonaws.com%2Fexternal%2Frowley%2FKc167_HinfI.hic": "1465493873,6976", - "hicfiles.s3.amazonaws.com%2Fexternal%2Frowley%2FKc167_DpnII_HinfI_combo.hic": "753062558,5814", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fbarutcu%2FMCF-10A.hic": "2784956115,36479", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fbarutcu%2FMCF-7.hic": "2700457411,36479", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fbatullin%2Fsperm.hic": "501052169,32102", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fminajigi%2FWT_hiC_rep1.hic": "1450697530,32102", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fminajigi%2FWT_hiC_rep2.hic": "1189371558,32102", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fminajigi%2Fcombined.hic": "2262007875,32102", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fminajigi%2Finactive.hic": "4444564,751", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fminajigi%2Factive.hic": "3993495,751", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fdeng%2Fpatski_rep1.hic": "1650838357,32102", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fdeng%2Fpatski_rep2.hic": "1258038606,32102", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fdeng%2Fpatski.hic": "499827296,16438", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fdeng%2Fpatski_active.hic": "79175714,15691", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fdeng%2Fpatski_inactive.hic": "98947881,15691", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fdeng%2Fbrain_dnase.hic": "4298088401,32102", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fdeng%2Fbrain_in_situ_dnase.hic": "609321852,32102", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fdeng%2Fbrain.hic": "1028196506,16438", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fdeng%2Fbrain_active.hic": "79175714,15691", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fdeng%2Fbrain_inactive.hic": "98947881,15691", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fle%2FBglII_rep1.hic": "1283306,1463", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fle%2FBglII_rep2.hic": "1263227,1463", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fle%2FNcoI_rep1.hic": "4380906,1463", - "hicfiles.s3.amazonaws.com%2Fexternal%2Feagen%2FGSE89112_Kc167combined.hic": "1829549643,25624", - "hicfiles.s3.amazonaws.com%2Fexternal%2Feagen%2FGSE89112_Kc167combined_randomized.hic": "1859742654,25624", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fmumbach%2FGSE80820_HiChIP_GM_cohesin.hic": "1231264781,17932", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fmumbach%2FGSE80820_HiChIP_mES_cohesin_all.hic": "1152008628,16438", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fmumbach%2FGSE80820_HiChIP_mES_Oct4.hic": "912828146,16438", - "s3.amazonaws.com%2Fhicfiles%2Fexternal%2Fwapl_hic%2FSCC4KO.hic": "1767906138,18679", - "s3.amazonaws.com%2Fhicfiles%2Fexternal%2Fwapl_hic%2FDKO.hic": "1487228787,18679", - "s3.amazonaws.com%2Fhicfiles%2Fexternal%2Fwapl_hic%2FWaplKO_1.14.hic": "1189751862,18679", - "s3.amazonaws.com%2Fhicfiles%2Fexternal%2Fwapl_hic%2FWaplKO_3.3.hic": "1155057696,18679", - "s3.amazonaws.com%2Fhicfiles%2Fexternal%2Fwapl_hic%2FWT.hic": "1522401568,18679", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fskfuwi4fnsjkdf9jekrw2%2Fmega_Liverpool%2Fmega.hic": "2612171975,4381", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fskfuwi4fnsjkdf9jekrw2%2FHIC2836_Liverpool1%2FLiverpool1.hic": "191729195,2245", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fskfuwi4fnsjkdf9jekrw2%2FHIC2861_Liverpool2%2FLiverpool2.hic": "1637096030,4381", - "s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fskfuwi4fnsjkdf9jekrw2%2FHIC2862_Liverpool3%2FLiverpool3.hic": "1160045602,4381", - "s3.amazonaws.com%2Fhicfiles%2Fexternal%2Fgoodell%2FHSPC.hic": "11857786247,36479", - "s3.amazonaws.com%2Fhicfiles%2Fexternal%2Fgoodell%2FHSPC_CanyonDel.hic": "8139168836,36479", - "s3.amazonaws.com%2Fhicfiles%2Fexternal%2Fgoodell%2Ftcell.hic": "9871547081,36479", - "s3.amazonaws.com%2Fhicfiles%2Fexternal%2Fgoodell%2Fep.hic": "17479335373,36479", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fnagano%2FTh1_ensemble.hic": "1690592868,32102", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fbonev%2FES_mapq30.hic": "32930498831,32386", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fbonev%2FNPC_mapq30.hic": "55053730986,32386", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fbonev%2FCN_mapq30.hic": "53138031154,32386", - "hicfiles.s3.amazonaws.com%2Fhiseq%2FKieffer-Kwon_et_al_2017%2FMain_maps%2FKieffer-Kwon-2017-activated_B_cells_72_hours_WT.hic": "16492991184,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2FKieffer-Kwon_et_al_2017%2FMain_maps%2FKieffer-Kwon-2017-resting_B_cells_WT.hic": "23057795398,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2FKieffer-Kwon_et_al_2017%2FMain_maps%2FKieffer-Kwon-2017-activated_B_cells_24_hours_MYC_KO.hic": "21245554876,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2FKieffer-Kwon_et_al_2017%2FMain_maps%2FKieffer-Kwon-2017-resting_B_cells_TSA.hic": "13933346059,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2FKieffer-Kwon_et_al_2017%2FMain_maps%2FKieffer-Kwon-2017-activated_B_cells_24_hours_oligomycin.hic": "21902506832,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2FKieffer-Kwon_et_al_2017%2FMain_maps%2FKieffer-Kwon-2017-mES_WT.hic": "9451969795,32102", - "hicfiles.s3.amazonaws.com%2Fhiseq%2FVian_et_al_2018%2FMain_maps%2FVian-2018-activated_B_cells_24_hours_WT.hic": "3600188564,16438", - "hicfiles.s3.amazonaws.com%2Fhiseq%2FVian_et_al_2018%2FMain_maps%2FVian-2018-activated_B_cells_30_hours_WT.hic": "1309503359,16438", - "hicfiles.s3.amazonaws.com%2Fhiseq%2FVian_et_al_2018%2FMain_maps%2FVian-2018-activated_B_cells_30_hours_HU_treated.hic": "1477252396,16438", - "hicfiles.s3.amazonaws.com%2Fhiseq%2FVian_et_al_2018%2FMain_maps%2FVian-2018-activated_B_cells_24_hours_flavopiridol.hic": "15711773490,32102", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fpgp%2FPGP1F_mega_090118%2FPGP1F_mega_090118_30.hic": "24786676166,36479", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fpgp%2FHIC7145%2FHIC7145_30.hic": "4554644616,36479", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fpgp%2FHIC7146%2FHIC7146_30.hic": "4174848944,36479", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fpgp%2FHIC7147%2FHIC7147_30.hic": "5062229182,36479", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fpgp%2FHIC7862%2FHIC7862_30.hic": "4520990620,36479", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fpgp%2FHIC7863%2FHIC7863_30.hic": "4330354773,36479", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fpgp%2FHIC7864%2FHIC7864_30.hic": "5880640268,36479", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fpgp%2FHIC7865%2FHIC7865_30.hic": "4431632469,36479", - "hicfiles.s3.amazonaws.com%2Fexternal%2Fpgp%2FHIC7866%2FHIC7866_30.hic": "4686000222,36479", - "encode-public.s3.amazonaws.com%2F2018%2F10%2F19%2Fb122542b-306c-4631-bdc3-2e155e89af55%2FENCFF718AWL.hic": "39544267907,58932", - "encode-public.s3.amazonaws.com%2F2019%2F02%2F15%2F8e787cd8-e388-4bc2-a236-7a5e6f39e0c0%2FENCFF999YXX.hic": "9255069996,56883", - "encode-public.s3.amazonaws.com%2F2019%2F02%2F08%2Ffc1d9d5d-8fa0-4e29-9080-3da674d9490d%2FENCFF543USQ.hic": "5005263062,36479", - "s3.us-east-1.wasabisys.com%2Fhicfiles%2Finternal%2FLCL_mega_42B_500bp_30.hic": "106482584851,22829", - "www.encodeproject.org%2Ffiles%2FENCFF925QIF%2F%40%40download%2FENCFF925QIF.hic": "51712684396,54779", - "www.encodeproject.org%2Ffiles%2FENCFF259YUS%2F%40%40download%2FENCFF259YUS.hic": "24640030444,54779", - "www.encodeproject.org%2Ffiles%2FENCFF783KQI%2F%40%40download%2FENCFF783KQI.hic": "27209249856,54779", - "www.encodeproject.org%2Ffiles%2FENCFF318JAP%2F%40%40download%2FENCFF318JAP.hic": "28636979242,54779", - "www.encodeproject.org%2Ffiles%2FENCFF512PQA%2F%40%40download%2FENCFF512PQA.hic": "28124104361,54779", - "www.encodeproject.org%2Ffiles%2FENCFF591MHA%2F%40%40download%2FENCFF591MHA.hic": "37373387202,54779", - "www.encodeproject.org%2Ffiles%2FENCFF197OWW%2F%40%40download%2FENCFF197OWW.hic": "41826180893,54779", - "www.encodeproject.org%2Ffiles%2FENCFF317OIA%2F%40%40download%2FENCFF317OIA.hic": "34741636038,54779", - "www.encodeproject.org%2Ffiles%2FENCFF522YLZ%2F%40%40download%2FENCFF522YLZ.hic": "24064692329,54779", - "www.encodeproject.org%2Ffiles%2FENCFF420JTA%2F%40%40download%2FENCFF420JTA.hic": "21202405177,54779", - "www.encodeproject.org%2Ffiles%2FENCFF871ZDJ%2F%40%40download%2FENCFF871ZDJ.hic": "10124815680,18679", - "www.encodeproject.org%2Ffiles%2FENCFF349RZY%2F%40%40download%2FENCFF349RZY.hic": "4446702705,36479", - "www.encodeproject.org%2Ffiles%2FENCFF738YON%2F%40%40download%2FENCFF738YON.hic": "3338049584,35947", - "www.encodeproject.org%2Ffiles%2FENCFF406KJN%2F%40%40download%2FENCFF406KJN.hic": "4132875306,36479", - "www.encodeproject.org%2Ffiles%2FENCFF081NPN%2F%40%40download%2FENCFF081NPN.hic": "34495587443,54779", - "www.encodeproject.org%2Ffiles%2FENCFF946RZW%2F%40%40download%2FENCFF946RZW.hic": "34571955193,54779", - "www.encodeproject.org%2Ffiles%2FENCFF602CHT%2F%40%40download%2FENCFF602CHT.hic": "30674798032,54779", - "www.encodeproject.org%2Ffiles%2FENCFF150DKS%2F%40%40download%2FENCFF150DKS.hic": "12618769864,36479", - "www.encodeproject.org%2Ffiles%2FENCFF614IPZ%2F%40%40download%2FENCFF614IPZ.hic": "42450060331,54779", - "www.encodeproject.org%2Ffiles%2FENCFF571ZQR%2F%40%40download%2FENCFF571ZQR.hic": "15230068871,47429", - "www.encodeproject.org%2Ffiles%2FENCFF705MKK%2F%40%40download%2FENCFF705MKK.hic": "38686554702,54779", - "www.encodeproject.org%2Ffiles%2FENCFF658KTB%2F%40%40download%2FENCFF658KTB.hic": "13195884405,47429", - "www.encodeproject.org%2Ffiles%2FENCFF435JYN%2F%40%40download%2FENCFF435JYN.hic": "17192139674,54779", - "www.encodeproject.org%2Ffiles%2FENCFF016JKX%2F%40%40download%2FENCFF016JKX.hic": "37266736642,54779", - "www.encodeproject.org%2Ffiles%2FENCFF294GFP%2F%40%40download%2FENCFF294GFP.hic": "36389843399,54779", - "www.encodeproject.org%2Ffiles%2FENCFF700CYI%2F%40%40download%2FENCFF700CYI.hic": "60482012152,54779", - "www.encodeproject.org%2Ffiles%2FENCFF962EDB%2F%40%40download%2FENCFF962EDB.hic": "39394328182,54779", - "www.encodeproject.org%2Ffiles%2FENCFF467OGP%2F%40%40download%2FENCFF467OGP.hic": "35572788855,54779", - "www.encodeproject.org%2Ffiles%2FENCFF556RLR%2F%40%40download%2FENCFF556RLR.hic": "34826921187,54779", - "www.encodeproject.org%2Ffiles%2FENCFF309UNV%2F%40%40download%2FENCFF309UNV.hic": "48510618174,54779", - "www.encodeproject.org%2Ffiles%2FENCFF653HCO%2F%40%40download%2FENCFF653HCO.hic": "41079007620,54779", - "www.encodeproject.org%2Ffiles%2FENCFF120DSV%2F%40%40download%2FENCFF120DSV.hic": "12790195576,47429", - "www.encodeproject.org%2Ffiles%2FENCFF284OEA%2F%40%40download%2FENCFF284OEA.hic": "46007570339,54779", - "www.encodeproject.org%2Ffiles%2FENCFF035BLF%2F%40%40download%2FENCFF035BLF.hic": "63868871985,54779", - "www.encodeproject.org%2Ffiles%2FENCFF094KKX%2F%40%40download%2FENCFF094KKX.hic": "42151419971,54779", - "www.encodeproject.org%2Ffiles%2FENCFF965BPU%2F%40%40download%2FENCFF965BPU.hic": "42717376107,54779", - "www.encodeproject.org%2Ffiles%2FENCFF842DUO%2F%40%40download%2FENCFF842DUO.hic": "39553892515,54779", - "www.encodeproject.org%2Ffiles%2FENCFF417GBZ%2F%40%40download%2FENCFF417GBZ.hic": "45544785452,54779", - "www.encodeproject.org%2Ffiles%2FENCFF499BVX%2F%40%40download%2FENCFF499BVX.hic": "40900674170,54779", - "www.encodeproject.org%2Ffiles%2FENCFF136XCV%2F%40%40download%2FENCFF136XCV.hic": "47700392974,54779", - "www.encodeproject.org%2Ffiles%2FENCFF224HKR%2F%40%40download%2FENCFF224HKR.hic": "40426005932,54779", - "www.encodeproject.org%2Ffiles%2FENCFF711XSR%2F%40%40download%2FENCFF711XSR.hic": "41434581949,54779", - "www.encodeproject.org%2Ffiles%2FENCFF660JWA%2F%40%40download%2FENCFF660JWA.hic": "54201632697,54779", - "www.encodeproject.org%2Ffiles%2FENCFF081PMO%2F%40%40download%2FENCFF081PMO.hic": "53428285130,54779", - "www.encodeproject.org%2Ffiles%2FENCFF799QGA%2F%40%40download%2FENCFF799QGA.hic": "1228682189,36479", - "www.encodeproject.org%2Ffiles%2FENCFF473CAA%2F%40%40download%2FENCFF473CAA.hic": "1077514950,36479", - "www.encodeproject.org%2Ffiles%2FENCFF663FRL%2F%40%40download%2FENCFF663FRL.hic": "39843938245,54779", - "www.encodeproject.org%2Ffiles%2FENCFF341WOY%2F%40%40download%2FENCFF341WOY.hic": "34792598619,54779", - "www.encodeproject.org%2Ffiles%2FENCFF515ZBF%2F%40%40download%2FENCFF515ZBF.hic": "41779230923,54779", - "www.encodeproject.org%2Ffiles%2FENCFF545GBW%2F%40%40download%2FENCFF545GBW.hic": "38351980358,54779", - "www.encodeproject.org%2Ffiles%2FENCFF252ANV%2F%40%40download%2FENCFF252ANV.hic": "37668839771,54779", - "www.encodeproject.org%2Ffiles%2FENCFF912NDK%2F%40%40download%2FENCFF912NDK.hic": "21196851956,54779", - "www.encodeproject.org%2Ffiles%2FENCFF683PLM%2F%40%40download%2FENCFF683PLM.hic": "21849338763,54779", - "www.encodeproject.org%2Ffiles%2FENCFF355NFJ%2F%40%40download%2FENCFF355NFJ.hic": "47880627268,54779", - "www.encodeproject.org%2Ffiles%2FENCFF507WEW%2F%40%40download%2FENCFF507WEW.hic": "35777782924,54779", - "www.encodeproject.org%2Ffiles%2FENCFF241MSL%2F%40%40download%2FENCFF241MSL.hic": "22507408288,54779", - "www.encodeproject.org%2Ffiles%2FENCFF135MUT%2F%40%40download%2FENCFF135MUT.hic": "24168734040,54779", - "www.encodeproject.org%2Ffiles%2FENCFF459FRB%2F%40%40download%2FENCFF459FRB.hic": "37166770103,54779", - "www.encodeproject.org%2Ffiles%2FENCFF705YZH%2F%40%40download%2FENCFF705YZH.hic": "44679182442,54779", - "www.encodeproject.org%2Ffiles%2FENCFF395INO%2F%40%40download%2FENCFF395INO.hic": "56727346538,54779", - "www.encodeproject.org%2Ffiles%2FENCFF736ITL%2F%40%40download%2FENCFF736ITL.hic": "49036286185,54779", - "www.encodeproject.org%2Ffiles%2FENCFF546TZN%2F%40%40download%2FENCFF546TZN.hic": "33195126348,54779", - "www.encodeproject.org%2Ffiles%2FENCFF706SFK%2F%40%40download%2FENCFF706SFK.hic": "3271831702,36479", - "www.encodeproject.org%2Ffiles%2FENCFF922ERE%2F%40%40download%2FENCFF922ERE.hic": "12476647122,36479", - "www.encodeproject.org%2Ffiles%2FENCFF876OWE%2F%40%40download%2FENCFF876OWE.hic": "1538692704,47429", - "www.encodeproject.org%2Ffiles%2FENCFF227XJZ%2F%40%40download%2FENCFF227XJZ.hic": "1925617685,36479", - "www.encodeproject.org%2Ffiles%2FENCFF053BXY%2F%40%40download%2FENCFF053BXY.hic": "1032237652,36479", - "www.encodeproject.org%2Ffiles%2FENCFF014VMM%2F%40%40download%2FENCFF014VMM.hic": "1564021703,36479", - "www.encodeproject.org%2Ffiles%2FENCFF563XES%2F%40%40download%2FENCFF563XES.hic": "1489180508,36479", - "www.encodeproject.org%2Ffiles%2FENCFF482LGO%2F%40%40download%2FENCFF482LGO.hic": "1208778887,36479", - "www.encodeproject.org%2Ffiles%2FENCFF216QQM%2F%40%40download%2FENCFF216QQM.hic": "6293163571,47429", - "www.encodeproject.org%2Ffiles%2FENCFF256UOW%2F%40%40download%2FENCFF256UOW.hic": "6293163571,47429", - "www.encodeproject.org%2Ffiles%2FENCFF791UZC%2F%40%40download%2FENCFF791UZC.hic": "37029615181,54779", - "www.encodeproject.org%2Ffiles%2FENCFF911AHQ%2F%40%40download%2FENCFF911AHQ.hic": "34246649165,54779", - "www.encodeproject.org%2Ffiles%2FENCFF491AOR%2F%40%40download%2FENCFF491AOR.hic": "558663570,36479", - "www.encodeproject.org%2Ffiles%2FENCFF307PDL%2F%40%40download%2FENCFF307PDL.hic": "525321519,36479", - "www.encodeproject.org%2Ffiles%2FENCFF773ITV%2F%40%40download%2FENCFF773ITV.hic": "295464771,36479", - "www.encodeproject.org%2Ffiles%2FENCFF198SSL%2F%40%40download%2FENCFF198SSL.hic": "500142476,36479", - "www.encodeproject.org%2Ffiles%2FENCFF251UEF%2F%40%40download%2FENCFF251UEF.hic": "567443575,36479", - "www.encodeproject.org%2Ffiles%2FENCFF942LTN%2F%40%40download%2FENCFF942LTN.hic": "4430960222,36479", - "www.encodeproject.org%2Ffiles%2FENCFF543USQ%2F%40%40download%2FENCFF543USQ.hic": "5005263062,36479", - "www.encodeproject.org%2Ffiles%2FENCFF434XQU%2F%40%40download%2FENCFF434XQU.hic": "25506511674,54779", - "www.encodeproject.org%2Ffiles%2FENCFF318GOM%2F%40%40download%2FENCFF318GOM.hic": "44750824314,54779", - "www.encodeproject.org%2Ffiles%2FENCFF004TKY%2F%40%40download%2FENCFF004TKY.hic": "20705661833,54779", - "www.encodeproject.org%2Ffiles%2FENCFF493YNC%2F%40%40download%2FENCFF493YNC.hic": "53407154984,54779", - "www.encodeproject.org%2Ffiles%2FENCFF334XXU%2F%40%40download%2FENCFF334XXU.hic": "14341194962,47429", - "www.encodeproject.org%2Ffiles%2FENCFF569RJM%2F%40%40download%2FENCFF569RJM.hic": "1922066634,36479", - "www.encodeproject.org%2Ffiles%2FENCFF076LWH%2F%40%40download%2FENCFF076LWH.hic": "39406255845,54779", - "www.encodeproject.org%2Ffiles%2FENCFF977XWK%2F%40%40download%2FENCFF977XWK.hic": "20563512962,54779", - "www.encodeproject.org%2Ffiles%2FENCFF127TPS%2F%40%40download%2FENCFF127TPS.hic": "21032070512,54779", - "www.encodeproject.org%2Ffiles%2FENCFF480KLP%2F%40%40download%2FENCFF480KLP.hic": "33115569647,54779", - "www.encodeproject.org%2Ffiles%2FENCFF281ILS%2F%40%40download%2FENCFF281ILS.hic": "28236353584,54779", - "www.encodeproject.org%2Ffiles%2FENCFF129LMU%2F%40%40download%2FENCFF129LMU.hic": "35247096013,54779", - "www.encodeproject.org%2Ffiles%2FENCFF759YCW%2F%40%40download%2FENCFF759YCW.hic": "16058537743,32102", - "www.encodeproject.org%2Ffiles%2FENCFF045YOM%2F%40%40download%2FENCFF045YOM.hic": "19775445828,32102", - "www.encodeproject.org%2Ffiles%2FENCFF013TGD%2F%40%40download%2FENCFF013TGD.hic": "4208420532,36479", - "www.encodeproject.org%2Ffiles%2FENCFF929RPW%2F%40%40download%2FENCFF929RPW.hic": "1974260276,36479", - "www.encodeproject.org%2Ffiles%2FENCFF996XEO%2F%40%40download%2FENCFF996XEO.hic": "2072918865,36479", - "www.encodeproject.org%2Ffiles%2FENCFF097SKJ%2F%40%40download%2FENCFF097SKJ.hic": "1983524001,36479", - "www.encodeproject.org%2Ffiles%2FENCFF464KRA%2F%40%40download%2FENCFF464KRA.hic": "1957300131,36479", - "www.encodeproject.org%2Ffiles%2FENCFF406HHC%2F%40%40download%2FENCFF406HHC.hic": "3854527235,36479", - "www.encodeproject.org%2Ffiles%2FENCFF080DPJ%2F%40%40download%2FENCFF080DPJ.hic": "19953768024,47429", - "www.encodeproject.org%2Ffiles%2FENCFF621AIY%2F%40%40download%2FENCFF621AIY.hic": "26781700010,54779", - "www.encodeproject.org%2Ffiles%2FENCFF366ERB%2F%40%40download%2FENCFF366ERB.hic": "1049184239,36479", - "www.encodeproject.org%2Ffiles%2FENCFF997RGL%2F%40%40download%2FENCFF997RGL.hic": "2521167549,36479", - "www.encodeproject.org%2Ffiles%2FENCFF029MPB%2F%40%40download%2FENCFF029MPB.hic": "1854711185,36479", - "www.encodeproject.org%2Ffiles%2FENCFF043EEE%2F%40%40download%2FENCFF043EEE.hic": "2924133032,36479", - "www.encodeproject.org%2Ffiles%2FENCFF920CJR%2F%40%40download%2FENCFF920CJR.hic": "3011577886,36479", - "www.encodeproject.org%2Ffiles%2FENCFF928NJV%2F%40%40download%2FENCFF928NJV.hic": "2778936244,36479", - "www.encodeproject.org%2Ffiles%2FENCFF894GLR%2F%40%40download%2FENCFF894GLR.hic": "2831733099,36479", - "www.encodeproject.org%2Ffiles%2FENCFF303PCK%2F%40%40download%2FENCFF303PCK.hic": "688704435,36479", - "www.encodeproject.org%2Ffiles%2FENCFF999YXX%2F%40%40download%2FENCFF999YXX.hic": "9255069996,56883", - "www.encodeproject.org%2Ffiles%2FENCFF685BLG%2F%40%40download%2FENCFF685BLG.hic": "16797022992,47429", - "www.encodeproject.org%2Ffiles%2FENCFF188SSH%2F%40%40download%2FENCFF188SSH.hic": "16797023050,47429", - "www.encodeproject.org%2Ffiles%2FENCFF465ESX%2F%40%40download%2FENCFF465ESX.hic": "13489465953,32102", - "www.encodeproject.org%2Ffiles%2FENCFF493SFI%2F%40%40download%2FENCFF493SFI.hic": "30033046818,54779", - "www.encodeproject.org%2Ffiles%2FENCFF235LCO%2F%40%40download%2FENCFF235LCO.hic": "38572174589,54779", - "www.encodeproject.org%2Ffiles%2FENCFF625VNK%2F%40%40download%2FENCFF625VNK.hic": "45202258438,54779", - "www.encodeproject.org%2Ffiles%2FENCFF304HMS%2F%40%40download%2FENCFF304HMS.hic": "36994445315,54779", - "www.encodeproject.org%2Ffiles%2FENCFF605CEN%2F%40%40download%2FENCFF605CEN.hic": "40358346301,54779", - "www.encodeproject.org%2Ffiles%2FENCFF086ORS%2F%40%40download%2FENCFF086ORS.hic": "22650781304,54779", - "www.encodeproject.org%2Ffiles%2FENCFF237UKR%2F%40%40download%2FENCFF237UKR.hic": "41516707246,54779", - "www.encodeproject.org%2Ffiles%2FENCFF004YZQ%2F%40%40download%2FENCFF004YZQ.hic": "71900665326,54779", - "www.encodeproject.org%2Ffiles%2FENCFF104THR%2F%40%40download%2FENCFF104THR.hic": "15172410632,54779", - "www.encodeproject.org%2Ffiles%2FENCFF807IRK%2F%40%40download%2FENCFF807IRK.hic": "17346637451,54779", - "www.encodeproject.org%2Ffiles%2FENCFF193CQL%2F%40%40download%2FENCFF193CQL.hic": "55726903245,54779", - "www.encodeproject.org%2Ffiles%2FENCFF700DEX%2F%40%40download%2FENCFF700DEX.hic": "20231399798,54779", - "www.encodeproject.org%2Ffiles%2FENCFF234MDO%2F%40%40download%2FENCFF234MDO.hic": "24635312640,54779", - "www.encodeproject.org%2Ffiles%2FENCFF181ROW%2F%40%40download%2FENCFF181ROW.hic": "26883606497,54779", - "www.encodeproject.org%2Ffiles%2FENCFF896OFN%2F%40%40download%2FENCFF896OFN.hic": "36952196833,54779", - "www.encodeproject.org%2Ffiles%2FENCFF573OPJ%2F%40%40download%2FENCFF573OPJ.hic": "36685546919,54779", - "www.encodeproject.org%2Ffiles%2FENCFF028RXH%2F%40%40download%2FENCFF028RXH.hic": "31053919206,54779", - "www.encodeproject.org%2Ffiles%2FENCFF156GGD%2F%40%40download%2FENCFF156GGD.hic": "35284134289,54779", - "www.encodeproject.org%2Ffiles%2FENCFF496GEU%2F%40%40download%2FENCFF496GEU.hic": "44659660933,54779", - "www.encodeproject.org%2Ffiles%2FENCFF945TUH%2F%40%40download%2FENCFF945TUH.hic": "3898570191,35639", - "www.encodeproject.org%2Ffiles%2FENCFF698KFV%2F%40%40download%2FENCFF698KFV.hic": "4427896684,35751", - "www.encodeproject.org%2Ffiles%2FENCFF239BHZ%2F%40%40download%2FENCFF239BHZ.hic": "1718552021,36479", - "www.encodeproject.org%2Ffiles%2FENCFF277LAN%2F%40%40download%2FENCFF277LAN.hic": "4542391336,36479", - "www.encodeproject.org%2Ffiles%2FENCFF397CMD%2F%40%40download%2FENCFF397CMD.hic": "2832016430,36479", - "www.encodeproject.org%2Ffiles%2FENCFF778OYA%2F%40%40download%2FENCFF778OYA.hic": "14067187484,47429", - "www.encodeproject.org%2Ffiles%2FENCFF775VSU%2F%40%40download%2FENCFF775VSU.hic": "14067187484,47429", - "www.encodeproject.org%2Ffiles%2FENCFF812THZ%2F%40%40download%2FENCFF812THZ.hic": "9667720429,36479", - "www.encodeproject.org%2Ffiles%2FENCFF777KBU%2F%40%40download%2FENCFF777KBU.hic": "5058284320,36479", - "www.encodeproject.org%2Ffiles%2FENCFF688KOY%2F%40%40download%2FENCFF688KOY.hic": "4198695833,36479", - "www.encodeproject.org%2Ffiles%2FENCFF223UBX%2F%40%40download%2FENCFF223UBX.hic": "1206064037,36479", - "www.encodeproject.org%2Ffiles%2FENCFF273XBU%2F%40%40download%2FENCFF273XBU.hic": "44085607579,54779", - "www.encodeproject.org%2Ffiles%2FENCFF952JZV%2F%40%40download%2FENCFF952JZV.hic": "44728845246,54779", - "www.encodeproject.org%2Ffiles%2FENCFF643NDM%2F%40%40download%2FENCFF643NDM.hic": "35877886780,54779", - "www.encodeproject.org%2Ffiles%2FENCFF586MQY%2F%40%40download%2FENCFF586MQY.hic": "71158037547,54779", - "www.encodeproject.org%2Ffiles%2FENCFF251VFA%2F%40%40download%2FENCFF251VFA.hic": "40089479399,54779", - "www.encodeproject.org%2Ffiles%2FENCFF033WGK%2F%40%40download%2FENCFF033WGK.hic": "30802023728,54779", - "www.encodeproject.org%2Ffiles%2FENCFF649OHR%2F%40%40download%2FENCFF649OHR.hic": "28203184265,54779", - "www.encodeproject.org%2Ffiles%2FENCFF782WVZ%2F%40%40download%2FENCFF782WVZ.hic": "37248221674,54779", - "www.encodeproject.org%2Ffiles%2FENCFF579CAR%2F%40%40download%2FENCFF579CAR.hic": "39662025395,54779", - "www.encodeproject.org%2Ffiles%2FENCFF514XWQ%2F%40%40download%2FENCFF514XWQ.hic": "1319613701,36479", - "www.encodeproject.org%2Ffiles%2FENCFF666USK%2F%40%40download%2FENCFF666USK.hic": "15051670107,32102", - "www.encodeproject.org%2Ffiles%2FENCFF047SDP%2F%40%40download%2FENCFF047SDP.hic": "1357076705,16438", - "www.encodeproject.org%2Ffiles%2FENCFF584LEP%2F%40%40download%2FENCFF584LEP.hic": "9314176858,36479", - "www.encodeproject.org%2Ffiles%2FENCFF671SOE%2F%40%40download%2FENCFF671SOE.hic": "3273732256,16438", - "www.encodeproject.org%2Ffiles%2FENCFF702LAP%2F%40%40download%2FENCFF702LAP.hic": "1800427500,31682", - "www.encodeproject.org%2Ffiles%2FENCFF339PON%2F%40%40download%2FENCFF339PON.hic": "5394351199,31514", - "www.encodeproject.org%2Ffiles%2FENCFF741QPR%2F%40%40download%2FENCFF741QPR.hic": "4271510019,30139", - "www.encodeproject.org%2Ffiles%2FENCFF103ANX%2F%40%40download%2FENCFF103ANX.hic": "4439745804,30083", - "www.encodeproject.org%2Ffiles%2FENCFF395SBC%2F%40%40download%2FENCFF395SBC.hic": "1596732351,31850", - "www.encodeproject.org%2Ffiles%2FENCFF289WNN%2F%40%40download%2FENCFF289WNN.hic": "8632980535,32102", - "www.encodeproject.org%2Ffiles%2FENCFF381EAU%2F%40%40download%2FENCFF381EAU.hic": "1702476311,36479", - "www.encodeproject.org%2Ffiles%2FENCFF976FEY%2F%40%40download%2FENCFF976FEY.hic": "1448279040,36479", - "www.encodeproject.org%2Ffiles%2FENCFF485LVS%2F%40%40download%2FENCFF485LVS.hic": "1593610856,36479", - "www.encodeproject.org%2Ffiles%2FENCFF143VJV%2F%40%40download%2FENCFF143VJV.hic": "1422312076,36479", - "www.encodeproject.org%2Ffiles%2FENCFF588NHX%2F%40%40download%2FENCFF588NHX.hic": "3943637009,36479", - "www.encodeproject.org%2Ffiles%2FENCFF768UBD%2F%40%40download%2FENCFF768UBD.hic": "24786676166,36479", - "www.encodeproject.org%2Ffiles%2FENCFF965PEE%2F%40%40download%2FENCFF965PEE.hic": "29387092778,47429", - "www.encodeproject.org%2Ffiles%2FENCFF702IFC%2F%40%40download%2FENCFF702IFC.hic": "29387092778,47429", - "www.encodeproject.org%2Ffiles%2FENCFF288DNV%2F%40%40download%2FENCFF288DNV.hic": "10313429504,36479", - "www.encodeproject.org%2Ffiles%2FENCFF698HWZ%2F%40%40download%2FENCFF698HWZ.hic": "10962849269,47429", - "www.encodeproject.org%2Ffiles%2FENCFF355OWW%2F%40%40download%2FENCFF355OWW.hic": "3219571601,36479", - "www.encodeproject.org%2Ffiles%2FENCFF177TYX%2F%40%40download%2FENCFF177TYX.hic": "10325679706,36479", - "www.encodeproject.org%2Ffiles%2FENCFF542BHD%2F%40%40download%2FENCFF542BHD.hic": "11085397879,47429", - "www.encodeproject.org%2Ffiles%2FENCFF684IFW%2F%40%40download%2FENCFF684IFW.hic": "11085397879,47429", - "www.encodeproject.org%2Ffiles%2FENCFF592UHE%2F%40%40download%2FENCFF592UHE.hic": "21363948089,32102", - "www.encodeproject.org%2Ffiles%2FENCFF779XIS%2F%40%40download%2FENCFF779XIS.hic": "9517383271,36479", - "www.encodeproject.org%2Ffiles%2FENCFF518PSL%2F%40%40download%2FENCFF518PSL.hic": "7500581463,36479", - "www.encodeproject.org%2Ffiles%2FENCFF275GBB%2F%40%40download%2FENCFF275GBB.hic": "7889407162,36479", - "www.encodeproject.org%2Ffiles%2FENCFF634KXI%2F%40%40download%2FENCFF634KXI.hic": "6430702966,36479", - "www.encodeproject.org%2Ffiles%2FENCFF337QPM%2F%40%40download%2FENCFF337QPM.hic": "8529733887,36479", - "www.encodeproject.org%2Ffiles%2FENCFF162KMP%2F%40%40download%2FENCFF162KMP.hic": "5615896908,36479", - "www.encodeproject.org%2Ffiles%2FENCFF992VTE%2F%40%40download%2FENCFF992VTE.hic": "7328975027,36479", - "www.encodeproject.org%2Ffiles%2FENCFF464WXY%2F%40%40download%2FENCFF464WXY.hic": "5715339664,36479", - "www.encodeproject.org%2Ffiles%2FENCFF752EGH%2F%40%40download%2FENCFF752EGH.hic": "1733758743,36479", - "www.encodeproject.org%2Ffiles%2FENCFF474UJM%2F%40%40download%2FENCFF474UJM.hic": "222309548,18679", - "www.encodeproject.org%2Ffiles%2FENCFF531UPZ%2F%40%40download%2FENCFF531UPZ.hic": "1827756846,36479", - "www.encodeproject.org%2Ffiles%2FENCFF022VHA%2F%40%40download%2FENCFF022VHA.hic": "244983451,18679", - "www.encodeproject.org%2Ffiles%2FENCFF732NGR%2F%40%40download%2FENCFF732NGR.hic": "1679484567,36479", - "www.encodeproject.org%2Ffiles%2FENCFF513VSF%2F%40%40download%2FENCFF513VSF.hic": "28397932940,36479", - "www.encodeproject.org%2Ffiles%2FENCFF750AOC%2F%40%40download%2FENCFF750AOC.hic": "36471430712,47429", - "www.encodeproject.org%2Ffiles%2FENCFF219YOB%2F%40%40download%2FENCFF219YOB.hic": "2859767211,26979", - "www.encodeproject.org%2Ffiles%2FENCFF604YDD%2F%40%40download%2FENCFF604YDD.hic": "3549694085,26979", - "www.encodeproject.org%2Ffiles%2FENCFF746AMV%2F%40%40download%2FENCFF746AMV.hic": "2954867135,26979", - "www.encodeproject.org%2Ffiles%2FENCFF845ZEB%2F%40%40download%2FENCFF845ZEB.hic": "2763039282,26979", - "www.encodeproject.org%2Ffiles%2FENCFF570LWS%2F%40%40download%2FENCFF570LWS.hic": "2861588289,26979", - "www.encodeproject.org%2Ffiles%2FENCFF883YVR%2F%40%40download%2FENCFF883YVR.hic": "2433679887,26979", - "www.encodeproject.org%2Ffiles%2FENCFF056VLK%2F%40%40download%2FENCFF056VLK.hic": "2502986910,26979", - "www.encodeproject.org%2Ffiles%2FENCFF532DUQ%2F%40%40download%2FENCFF532DUQ.hic": "3172615899,26979", - "www.encodeproject.org%2Ffiles%2FENCFF723PYJ%2F%40%40download%2FENCFF723PYJ.hic": "10292839095,36479", - "www.encodeproject.org%2Ffiles%2FENCFF991SGJ%2F%40%40download%2FENCFF991SGJ.hic": "13072407683,32102", - "www.encodeproject.org%2Ffiles%2FENCFF885UZI%2F%40%40download%2FENCFF885UZI.hic": "1201881201,16438", - "www.encodeproject.org%2Ffiles%2FENCFF287KXA%2F%40%40download%2FENCFF287KXA.hic": "14705801988,32102", - "www.encodeproject.org%2Ffiles%2FENCFF335HYI%2F%40%40download%2FENCFF335HYI.hic": "20366756545,32102", - "www.encodeproject.org%2Ffiles%2FENCFF121YPY%2F%40%40download%2FENCFF121YPY.hic": "2760104016,26979", - "www.encodeproject.org%2Ffiles%2FENCFF675SJE%2F%40%40download%2FENCFF675SJE.hic": "3751779995,26979", - "www.encodeproject.org%2Ffiles%2FENCFF876LAW%2F%40%40download%2FENCFF876LAW.hic": "4032376256,26979", - "www.encodeproject.org%2Ffiles%2FENCFF740KVX%2F%40%40download%2FENCFF740KVX.hic": "3202490322,26979", - "www.encodeproject.org%2Ffiles%2FENCFF977OQV%2F%40%40download%2FENCFF977OQV.hic": "2919735477,26979", - "www.encodeproject.org%2Ffiles%2FENCFF525EFN%2F%40%40download%2FENCFF525EFN.hic": "2394748073,26979", - "www.encodeproject.org%2Ffiles%2FENCFF690QRC%2F%40%40download%2FENCFF690QRC.hic": "3183023394,26979", - "www.encodeproject.org%2Ffiles%2FENCFF452FWS%2F%40%40download%2FENCFF452FWS.hic": "2951805127,26979", - "www.encodeproject.org%2Ffiles%2FENCFF089KBG%2F%40%40download%2FENCFF089KBG.hic": "2531936700,26979", - "www.encodeproject.org%2Ffiles%2FENCFF939ARM%2F%40%40download%2FENCFF939ARM.hic": "3066385212,26979", - "www.encodeproject.org%2Ffiles%2FENCFF401ZAN%2F%40%40download%2FENCFF401ZAN.hic": "3008677144,26979", - "www.encodeproject.org%2Ffiles%2FENCFF378RZT%2F%40%40download%2FENCFF378RZT.hic": "2830232168,26979", - "www.encodeproject.org%2Ffiles%2FENCFF304AVD%2F%40%40download%2FENCFF304AVD.hic": "6164439305,50358", - "www.encodeproject.org%2Ffiles%2FENCFF453DBX%2F%40%40download%2FENCFF453DBX.hic": "6775246670,36479", - "www.encodeproject.org%2Ffiles%2FENCFF590VOM%2F%40%40download%2FENCFF590VOM.hic": "6443478922,36479", - "www.encodeproject.org%2Ffiles%2FENCFF246DOF%2F%40%40download%2FENCFF246DOF.hic": "6837914659,36479", - "www.encodeproject.org%2Ffiles%2FENCFF125FXX%2F%40%40download%2FENCFF125FXX.hic": "9736232550,36479", - "www.encodeproject.org%2Ffiles%2FENCFF241RAY%2F%40%40download%2FENCFF241RAY.hic": "7686758397,36479", - "www.encodeproject.org%2Ffiles%2FENCFF415XWQ%2F%40%40download%2FENCFF415XWQ.hic": "6973092068,36479", - "www.encodeproject.org%2Ffiles%2FENCFF374EBH%2F%40%40download%2FENCFF374EBH.hic": "8557459058,36479", - "www.encodeproject.org%2Ffiles%2FENCFF263YWR%2F%40%40download%2FENCFF263YWR.hic": "331586820,18679", - "www.encodeproject.org%2Ffiles%2FENCFF280CGS%2F%40%40download%2FENCFF280CGS.hic": "1743569614,36479", - "www.encodeproject.org%2Ffiles%2FENCFF553ZNS%2F%40%40download%2FENCFF553ZNS.hic": "1717253636,36479", - "www.encodeproject.org%2Ffiles%2FENCFF451VOI%2F%40%40download%2FENCFF451VOI.hic": "1626927468,36479", - "www.encodeproject.org%2Ffiles%2FENCFF420MQO%2F%40%40download%2FENCFF420MQO.hic": "31055961677,36479", - "www.encodeproject.org%2Ffiles%2FENCFF301BWY%2F%40%40download%2FENCFF301BWY.hic": "38902429246,47429", - "www.encodeproject.org%2Ffiles%2FENCFF606XNW%2F%40%40download%2FENCFF606XNW.hic": "1009699327,36479", - "www.encodeproject.org%2Ffiles%2FENCFF439ZOU%2F%40%40download%2FENCFF439ZOU.hic": "12381714313,36479", - "www.encodeproject.org%2Ffiles%2FENCFF499SYK%2F%40%40download%2FENCFF499SYK.hic": "13182654663,47429", - "www.encodeproject.org%2Ffiles%2FENCFF532LFI%2F%40%40download%2FENCFF532LFI.hic": "8286030286,36479", - "www.encodeproject.org%2Ffiles%2FENCFF020DPP%2F%40%40download%2FENCFF020DPP.hic": "23521952420,47429", - "www.encodeproject.org%2Ffiles%2FENCFF306VTV%2F%40%40download%2FENCFF306VTV.hic": "23521952480,47429", - "www.encodeproject.org%2Ffiles%2FENCFF399IHE%2F%40%40download%2FENCFF399IHE.hic": "10216571232,36479", - "www.encodeproject.org%2Ffiles%2FENCFF944AII%2F%40%40download%2FENCFF944AII.hic": "12567308552,47429", - "www.encodeproject.org%2Ffiles%2FENCFF230HVV%2F%40%40download%2FENCFF230HVV.hic": "8629849711,36479", - "www.encodeproject.org%2Ffiles%2FENCFF174LAF%2F%40%40download%2FENCFF174LAF.hic": "9446506633,47429", - "www.encodeproject.org%2Ffiles%2FENCFF898HRO%2F%40%40download%2FENCFF898HRO.hic": "9446506633,47429", - "www.encodeproject.org%2Ffiles%2FENCFF429MOR%2F%40%40download%2FENCFF429MOR.hic": "1455757398,36479", - "www.encodeproject.org%2Ffiles%2FENCFF061NXV%2F%40%40download%2FENCFF061NXV.hic": "1710915891,36479", - "www.encodeproject.org%2Ffiles%2FENCFF434PYS%2F%40%40download%2FENCFF434PYS.hic": "1832274903,36479", - "www.encodeproject.org%2Ffiles%2FENCFF704HHX%2F%40%40download%2FENCFF704HHX.hic": "1768142834,36479", - "www.encodeproject.org%2Ffiles%2FENCFF349DPM%2F%40%40download%2FENCFF349DPM.hic": "4316041260,36479", - "www.encodeproject.org%2Ffiles%2FENCFF718AWL%2F%40%40download%2FENCFF718AWL.hic": "39544267907,58932", - "www.encodeproject.org%2Ffiles%2FENCFF065LSP%2F%40%40download%2FENCFF065LSP.hic": "24929805283,55874", - "www.encodeproject.org%2Ffiles%2FENCFF632MFV%2F%40%40download%2FENCFF632MFV.hic": "22333105467,55798", - "www.encodeproject.org%2Ffiles%2FENCFF179HVU%2F%40%40download%2FENCFF179HVU.hic": "2659219603,36479", - "www.encodeproject.org%2Ffiles%2FENCFF791SPZ%2F%40%40download%2FENCFF791SPZ.hic": "2537491657,36479", - "www.encodeproject.org%2Ffiles%2FENCFF211ZWF%2F%40%40download%2FENCFF211ZWF.hic": "3512141227,36479", - "www.encodeproject.org%2Ffiles%2FENCFF614BNU%2F%40%40download%2FENCFF614BNU.hic": "5252155462,36479", - "www.encodeproject.org%2Ffiles%2FENCFF891DLM%2F%40%40download%2FENCFF891DLM.hic": "2549095612,36479", - "www.encodeproject.org%2Ffiles%2FENCFF056EXT%2F%40%40download%2FENCFF056EXT.hic": "2219014704,36479", - "www.encodeproject.org%2Ffiles%2FENCFF776DSS%2F%40%40download%2FENCFF776DSS.hic": "3920308353,36479", - "www.encodeproject.org%2Ffiles%2FENCFF814LQF%2F%40%40download%2FENCFF814LQF.hic": "1349480197,36479", - "www.encodeproject.org%2Ffiles%2FENCFF513ZNA%2F%40%40download%2FENCFF513ZNA.hic": "2638868195,36479", - "www.encodeproject.org%2Ffiles%2FENCFF692IOL%2F%40%40download%2FENCFF692IOL.hic": "3106768498,36479", - "www.encodeproject.org%2Ffiles%2FENCFF294WZY%2F%40%40download%2FENCFF294WZY.hic": "2211089761,36479", - "www.encodeproject.org%2Ffiles%2FENCFF339UWS%2F%40%40download%2FENCFF339UWS.hic": "2142759055,36479", - "www.encodeproject.org%2Ffiles%2FENCFF835FSK%2F%40%40download%2FENCFF835FSK.hic": "3919821739,36479", - "www.encodeproject.org%2Ffiles%2FENCFF328BMB%2F%40%40download%2FENCFF328BMB.hic": "2550686152,36479", - "www.encodeproject.org%2Ffiles%2FENCFF897RTY%2F%40%40download%2FENCFF897RTY.hic": "1323294397,36479", - "www.encodeproject.org%2Ffiles%2FENCFF306MWH%2F%40%40download%2FENCFF306MWH.hic": "1665386199,36479", - "www.encodeproject.org%2Ffiles%2FENCFF039YUJ%2F%40%40download%2FENCFF039YUJ.hic": "2335679939,36479", - "www.encodeproject.org%2Ffiles%2FENCFF468QIN%2F%40%40download%2FENCFF468QIN.hic": "3352516594,36479", - "www.encodeproject.org%2Ffiles%2FENCFF364WXU%2F%40%40download%2FENCFF364WXU.hic": "3959043175,36479", - "www.encodeproject.org%2Ffiles%2FENCFF373MSH%2F%40%40download%2FENCFF373MSH.hic": "4429550624,36479", - "www.encodeproject.org%2Ffiles%2FENCFF959EGQ%2F%40%40download%2FENCFF959EGQ.hic": "2475218228,36479", - "www.encodeproject.org%2Ffiles%2FENCFF624XMK%2F%40%40download%2FENCFF624XMK.hic": "3527855681,36479", - "www.encodeproject.org%2Ffiles%2FENCFF445OKS%2F%40%40download%2FENCFF445OKS.hic": "3369125589,36479", - "www.encodeproject.org%2Ffiles%2FENCFF239QDV%2F%40%40download%2FENCFF239QDV.hic": "1960069888,36479", - "www.encodeproject.org%2Ffiles%2FENCFF645AVM%2F%40%40download%2FENCFF645AVM.hic": "4969006589,36479", - "www.encodeproject.org%2Ffiles%2FENCFF494IPI%2F%40%40download%2FENCFF494IPI.hic": "1565483792,36479", - "www.encodeproject.org%2Ffiles%2FENCFF753IXE%2F%40%40download%2FENCFF753IXE.hic": "2892400648,36479", - "www.encodeproject.org%2Ffiles%2FENCFF731GXX%2F%40%40download%2FENCFF731GXX.hic": "5131381303,36479", - "www.encodeproject.org%2Ffiles%2FENCFF369CAQ%2F%40%40download%2FENCFF369CAQ.hic": "4236629448,36479", - "www.encodeproject.org%2Ffiles%2FENCFF053VBX%2F%40%40download%2FENCFF053VBX.hic": "54305946375,47429", - "www.encodeproject.org%2Ffiles%2FENCFF555ISR%2F%40%40download%2FENCFF555ISR.hic": "54305946434,47429", - "www.encodeproject.org%2Ffiles%2FENCFF964RSP%2F%40%40download%2FENCFF964RSP.hic": "12065485229,36479", - "www.encodeproject.org%2Ffiles%2FENCFF234MZQ%2F%40%40download%2FENCFF234MZQ.hic": "17507142760,47429", - "www.encodeproject.org%2Ffiles%2FENCFF994CEG%2F%40%40download%2FENCFF994CEG.hic": "17507142760,47429", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fb068e787-bbdd-49e2-9f6d-7a0e9f065d6e%2F4DNFIHSUIRFY.hic": "2701182442,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3768b89a-e124-40eb-8acd-94a4fdd35807%2F4DNFIXTAS6EE.hic": "3283740601,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F9c513602-5abb-4088-8415-c827c381ab0d%2F4DNFIC3JD6O2.hic": "4896075767,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fde954dad-1849-4c23-beb4-bf893b7d76c9%2F4DNFIGY85S4W.hic": "3364151996,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fe1befa6e-8067-4296-8db2-67d2a2458985%2F4DNFI2LTNXME.hic": "3699291418,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fbb3307fd-7162-477a-87c5-52f12d03befc%2F4DNFID162B9J.hic": "3576428773,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8597cdae-8319-42d9-9175-3f77aaee34e1%2F4DNFIQWS3632.hic": "4022561190,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F327f091d-6a63-47c4-9752-2dff303a13d9%2F4DNFI6GFHB6G.hic": "4239331168,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd70dc3b8-48a7-42c2-bd23-80bc44fc2266%2F4DNFIS5F6EBL.hic": "4404671861,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F77df7bf8-6a3d-407a-8968-4ca1e78d2269%2F4DNFIF2D3TL9.hic": "4793989394,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc8f7cc35-d2ef-4717-9009-c02154050fbf%2F4DNFI6EIFUZI.hic": "3370273763,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F98449d79-30d1-4e32-801d-07435819a42f%2F4DNFIRKGMZRQ.hic": "4669813207,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd4fe1844-2493-4722-8b98-34a93a4bb7d8%2F4DNFIQWD8ZYD.hic": "5379889057,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F1ee40499-1de4-47ff-b540-d9a65943c6b8%2F4DNFIX7H3CE2.hic": "4857679239,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fac016170-23a7-4111-8773-353d6c150f34%2F4DNFIO21YDCV.hic": "4695989644,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F1faea4e7-9a32-466e-a826-0bfdab6cd915%2F4DNFIUE5RAS6.hic": "4788044799,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fcbd396ed-11bb-404f-aed9-ef10abc258e6%2F4DNFIFI6NIKJ.hic": "2069414927,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Faf3f78db-ae92-4215-bcae-76d30c617e5d%2F4DNFIL5K3MA1.hic": "2585598247,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F66fc2893-224e-48b4-bdb0-25e022dedd03%2F4DNFIPV5KFMK.hic": "2060965679,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F2b39781d-aadc-434f-abe3-562d61308fdd%2F4DNFIW8TIFI5.hic": "1694424195,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fb6d28f7b-27d3-486f-b5ac-32567416560d%2F4DNFIA6NSSBJ.hic": "2219532611,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F08785616-722e-46bb-ade2-2fdd21324e11%2F4DNFIBKZK63V.hic": "2429136232,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F904b13d3-1203-42a4-812c-963e80c159b1%2F4DNFI3CFMRID.hic": "1233390166,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fb0ed4afe-5ecf-451d-bb1f-444697e3f558%2F4DNFIYIAUEPW.hic": "1753567534,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F4bb9a9b3-12a8-4d2f-8071-4722294c88ea%2F4DNFIC3HAU11.hic": "2271375254,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F5abf9c36-c1d1-44dc-8197-74d860d896c0%2F4DNFIM2BMJ33.hic": "1770471113,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fa68475db-7816-4cec-b2da-d4ce4a0c7a0e%2F4DNFIBY3UHJB.hic": "2095528423,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F07c40943-0d0b-4b3e-94a0-8583b0e00b47%2F4DNFIWZEN3FF.hic": "1558559508,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd8a39553-2718-4866-9b2a-45d8e9c5ac6f%2F4DNFIE5TEYK7.hic": "1323063102,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F294b61ef-5565-4f04-ade9-f921a6686cce%2F4DNFI7H4II2V.hic": "1436947982,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F87a70ad7-7d34-4302-9c03-eb824bd4e633%2F4DNFIAS8LV1C.hic": "1263105698,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F9db804c6-5a91-4cf5-8ae9-e054223afb77%2F4DNFIBXWIH8J.hic": "1587059951,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd1e55906-ec8f-444b-8ce1-2de22a431a76%2F4DNFIO2HBDAI.hic": "1666436393,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F7a4b9b37-8e38-470c-8190-fd4d513c0bbb%2F4DNFIXWCLD4M.hic": "1513511880,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F6c7615b2-5310-4bbf-a605-98761d3a3079%2F4DNFINASC4NQ.hic": "1420358914,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F20454014-49cd-4e2d-93da-f40ad52776d5%2F4DNFIZF1KI43.hic": "1377041630,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F5df04e86-ee2a-45f2-b878-bf1648e2cca5%2F4DNFIQBHR9XC.hic": "1179502734,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F9d1cc910-bb3f-4106-802a-73184c58d5ba%2F4DNFIQVMVRP6.hic": "1811976991,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fe431986b-0732-460f-92ff-0abd1694d2d0%2F4DNFIJ7OAIFQ.hic": "1685503856,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F56d0c575-4962-4ea3-92c3-55bd0e17c096%2F4DNFIE8E4ANZ.hic": "1598369564,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fdb1502fb-a989-4ef9-b800-7eaa7be172ae%2F4DNFIOUSETUP.hic": "1493294709,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Facc2f1c3-8c96-4d21-814a-3a8ba81e7741%2F4DNFIVJ3IIQL.hic": "1472376655,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F037fb4c3-8641-4953-a977-cc71f2137582%2F4DNFIHN2QSMX.hic": "1179632606,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F16d2c3c0-6d29-4815-b074-b142af90b615%2F4DNFIILDWK8M.hic": "2280059989,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F31789849-e4db-45d8-9730-66a048c02d8a%2F4DNFI6XD6JAQ.hic": "2253961696,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fff04947e-e6e8-4d62-8374-ef2ee4104809%2F4DNFIALNLR78.hic": "1914687914,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F53e6c1e7-9410-4158-84e6-57c2e683b095%2F4DNFIBT4EAKN.hic": "2296378356,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F0127900a-258f-4815-97d2-6fd2b043d853%2F4DNFIDJ2JZ7Q.hic": "2558945393,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F89f95693-3d28-44eb-9d45-14932f8e258c%2F4DNFI8JFOAJT.hic": "1726440253,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd803d818-b0d4-4796-8d61-a9f3943f3b10%2F4DNFIRZA6EV6.hic": "1805017504,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff9165fb1-0782-4757-a740-5b929e0252bb%2F4DNFIB7QTIMH.hic": "2541020707,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff8d916b2-b58e-4cdf-894c-ffcb3bf6ebd9%2F4DNFIJ5DQZVK.hic": "2445734043,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F14066a5b-e01a-43c2-a468-b18826174df3%2F4DNFISTWNV9C.hic": "2499319890,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd0692151-7f9a-4475-b059-f8802616dded%2F4DNFIBN9K4V9.hic": "1591570769,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F70a7ef36-a514-4e45-918f-47c4e9e30ef4%2F4DNFIR8OU6QJ.hic": "1689882108,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F180306cd-8593-413a-ae83-24f19209c5d2%2F4DNFIDSWKFF5.hic": "1596696630,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F6e7b9be7-f465-4434-8e9c-68d1e44a76af%2F4DNFIV239W4L.hic": "2345867406,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F55df948c-941d-4930-854c-6a07557a0c1d%2F4DNFIREVU1Z5.hic": "2254683002,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3f590cb7-df3a-498f-81c3-d5ed4179b8ad%2F4DNFIFHU75I5.hic": "2497670883,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8f064770-6008-4f74-bfca-268d4a22d745%2F4DNFIMROE6N4.hic": "9850583704,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fa93d0588-76b7-4ccf-933c-4325876b0a53%2F4DNFI5SUHCGZ.hic": "10364705187,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F2f5f0d6b-0b22-4936-93c9-0944d49c037b%2F4DNFII84FBKM.hic": "8836986129,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F12e90fc5-0b76-4e42-b346-58d267f9ad6e%2F4DNFI2J1ODWB.hic": "13410858286,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff2702a45-3e8b-4980-bcd5-6bb0e291614f%2F4DNFIJWBWE41.hic": "20515676755,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fa0859349-5f06-4ad3-b56f-b1166b34a9eb%2F4DNFIIMZB6Y9.hic": "15350325963,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F12685c57-d54a-46fa-9efb-acf34ed77574%2F4DNFICJECID5.hic": "1525002266,26979", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd101a58e-89aa-44fd-96c5-6bf1e2476272%2F4DNFIR6UW2QA.hic": "1264999913,26979", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3d8c73bf-1335-4af4-b124-e3622d48c5f6%2F4DNFIGOEKBUZ.hic": "1905947578,26979", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fcd2477cf-6ed0-4d7b-b4e9-88fb38b0df48%2F4DNFIMDNAEW4.hic": "996444147,26979", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F0f03953e-29da-4f2e-8c05-572d0edf4525%2F4DNFI5OSZ3JC.hic": "369361754,22829", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F29d95dbb-005a-4ae1-8b9c-0fec9ec0bbd0%2F4DNFI7KOUGFM.hic": "1227434049,26979", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fa441ab7b-afbe-437d-bf98-b6b916558642%2F4DNFIGKX4A32.hic": "883933242,26979", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F941b2f94-2fff-4d3c-aceb-fee4a5ae41a9%2F4DNFI1ORHOTA.hic": "1140970677,26979", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8720ede9-093f-4c00-912f-373283260a16%2F4DNFIWSVLZED.hic": "458091151,26979", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fe9e17155-2b62-4a68-afb2-31dfa674e169%2F4DNFI6H926RO.hic": "3552863515,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F22f22778-987a-4dc0-97bc-f26eae0156d9%2F4DNFIKTYSPOF.hic": "2939475400,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F40f40192-0acb-44cb-8778-8d21afe593fb%2F4DNFIZ4S52BV.hic": "3067438113,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd8767374-7018-4e11-9226-bf5612d39ebb%2F4DNFI3APMXHF.hic": "3258874744,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8c5140ec-a65a-4186-8c59-2927233eecaa%2F4DNFIQLIKDSD.hic": "2746398416,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8cdedda6-d7d8-4231-a85b-d56fcd962366%2F4DNFIKYXMF1E.hic": "14442148774,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Faa4d4497-7c6c-4dad-8040-be13ba07ea32%2F4DNFI9815EEJ.hic": "17960817603,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fe9b7b95f-190b-49fe-8047-ef4a8fc59746%2F4DNFIQ2687RT.hic": "15954277087,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F59863d3a-8d7c-49c7-9a41-7f2a58ad24d1%2F4DNFIYDBBSE3.hic": "16499534862,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3e80ca41-b3e0-4f4f-a05e-8f95fe96d938%2F4DNFIMOCN1YS.hic": "863725312,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F96f97a01-0020-4f09-93e8-fc8a9fd07218%2F4DNFI6558CM8.hic": "1597967345,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fce9e9334-ee0b-4549-a845-110470ba5986%2F4DNFIQZRKS7Y.hic": "907626411,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fdaac8209-1015-48da-9e31-2e252dfd8fe0%2F4DNFIX4DLXSE.hic": "1369766288,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F268b7d52-9655-474c-9467-8ba31bb2195c%2F4DNFII3JV8I1.hic": "856656441,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F9681f9b5-335a-4f56-afa1-15b58bbb41e8%2F4DNFI5IAH9H1.hic": "1495185175,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3e082eab-95aa-4677-88ed-9d7adcc1effb%2F4DNFIK5HY1GP.hic": "2135337789,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F31af1ead-4520-4669-957e-424b4b197c33%2F4DNFIFA89L5B.hic": "1975593640,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fcc2b78fd-52d4-4e0c-ac93-b84ee82daf7e%2F4DNFICXCFGEI.hic": "2628202920,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff54efece-280f-46ca-95e3-1f8a3cd18820%2F4DNFIK4CECUH.hic": "1901129375,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F1181c0c4-afb7-4b6a-9fdc-d868fb2253fc%2F4DNFI1EYIGOC.hic": "1947135384,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F1d3e2905-b9b9-4b91-bcb4-8d34746e78f6%2F4DNFI7TLEWUI.hic": "1185758726,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Faba3d42f-39cd-4a85-9d3f-835aefb5c803%2F4DNFIVCJKHMN.hic": "687240974,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F27f54fcb-54fe-41a4-b25a-2f8944c89044%2F4DNFIN8F14CS.hic": "1304082029,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fb75fedb5-88f4-4bc0-8e38-298df7847a7f%2F4DNFI5LCW273.hic": "12497258313,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F2f22b2a0-3712-496e-92d2-63775ec0e421%2F4DNFIVSCH2CH.hic": "12594733778,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F07e47261-5863-44f5-9198-76e263081bea%2F4DNFIZ268JGC.hic": "1499059135,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F682b1ae1-3ac3-40e4-a330-c49f63946952%2F4DNFIJ1P4HBI.hic": "1190211725,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F197e7c89-ea73-41de-8cb2-8c0b1e3bb945%2F4DNFITEGKBIW.hic": "2061501971,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F191f6928-c9a8-44b2-8516-ee4d6005f24b%2F4DNFIE1P6RVH.hic": "1711447310,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F94435086-3701-4b28-a6d0-4a59b24d7615%2F4DNFICJ6I4DO.hic": "1557899940,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Faa9ac173-d233-41c7-8985-ca91949664e4%2F4DNFIKUG8MEW.hic": "1339072088,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fba6d8ab6-ee18-4ba2-8da9-d631888dd50a%2F4DNFICFZGFAV.hic": "1261083478,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F87a3ab04-7094-4673-81e4-ac8c9add8eb5%2F4DNFIQXCZVVA.hic": "1084913802,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fbc1ff488-82af-4579-9424-959184edb139%2F4DNFIB6PJFJ3.hic": "1114571343,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F1f7026ee-987a-41e7-8a61-45510ee3f86b%2F4DNFIX97731O.hic": "1246860402,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F6186787c-2e72-4925-9729-02121e2e4597%2F4DNFIYQYZOTO.hic": "1212210849,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3b98a946-0109-4efa-a13e-cc7a36772125%2F4DNFIPXU7V25.hic": "1696288217,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fea17d041-c6ed-43a1-8047-535f3d19ad44%2F4DNFIL39PR76.hic": "1719284710,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F72774afe-f166-42ac-9849-4070b0dadf6d%2F4DNFIYLJ3R3B.hic": "1106419640,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F4a45e733-55f8-4a8e-be24-2ef34c976e25%2F4DNFIL51WBN6.hic": "1327651164,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F086c62b0-a26f-41ae-a5ff-88b8be2bd2aa%2F4DNFI6SFPUDA.hic": "1336964405,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F4d9b79c7-af62-4070-84a9-b953903f2732%2F4DNFI2KM22QR.hic": "953067310,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3c9889d1-f49e-4639-8e15-2d99d6cd22e7%2F4DNFIVF8Q45U.hic": "984193565,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fa080dd7b-b7bb-4eae-a275-572a8b45b2d0%2F4DNFI2RN3WFP.hic": "1046525527,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fb81860ca-c227-4b68-a298-1907fd32300a%2F4DNFI4TJTL7A.hic": "1160373401,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F74ab47dc-7b52-421c-845e-6feb33457adf%2F4DNFIYJ4TWB8.hic": "1268416204,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc6582128-a930-4bcc-941e-5c0733bdd4d5%2F4DNFIM6RGKPV.hic": "863347067,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F11a75514-4450-4295-9eda-18e3678a575a%2F4DNFIL2VWWL5.hic": "860731581,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F5eb52a8c-bf14-4225-bf34-14a0aa47c369%2F4DNFIX6ZXCA8.hic": "893462267,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F66aaa4c0-1f62-4040-8ecc-4e95da23cd18%2F4DNFIEVR81FS.hic": "879736207,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F821c6e7f-96f7-47de-b7d9-4970562b3c8e%2F4DNFIAUI6BBI.hic": "996313881,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F9252c362-31ab-413d-a47a-cc97bdbf243a%2F4DNFIAFEE9G2.hic": "1103265750,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc1a0bf52-2e65-4deb-871f-ede736babd41%2F4DNFIPZBEXCP.hic": "1081257762,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F729f5ce3-d7e0-466d-b781-d18049e63bfa%2F4DNFIWPKRZGU.hic": "973779283,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F80b769ee-a717-4825-9db0-dca86f913173%2F4DNFIMD9QNDX.hic": "1158688208,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F266290c0-2767-4158-85ab-7274368905b9%2F4DNFIATA1HD5.hic": "1073361089,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc46f18a8-eb24-4d35-b112-36db72bde2f5%2F4DNFIH9U4I7I.hic": "1111124316,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fec91a79e-7de7-49f7-9b3d-d28313aeddc8%2F4DNFIZ95S6TR.hic": "1242494051,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F9e9390b9-da20-43bb-a8f4-9830f354ddf9%2F4DNFI5ERM9J7.hic": "1271051397,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fee8ea82e-b9e4-41ad-bced-5f4fbdaa4fec%2F4DNFI15FPSQL.hic": "1216714120,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fbed7eb86-8990-42f2-b3ee-5992d6361f7c%2F4DNFIJ3DZPGM.hic": "1035089437,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fdaa8a324-3bf8-424c-8a86-b8ad325cc20d%2F4DNFINW9P6XF.hic": "1215712740,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F70631758-6bf8-47a0-92b6-132574886faa%2F4DNFITS16HW8.hic": "1105283847,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fe473304b-7bc8-49b8-bba1-ecb9f06914ee%2F4DNFIS3DIH4V.hic": "1036056660,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F10f9224a-111c-402a-ac25-e221ad0af9ef%2F4DNFIY3KDHP6.hic": "1071761024,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F17519b96-2bdd-4294-98f0-1535f1aef28e%2F4DNFIO8HVKOL.hic": "953793750,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ffb18f896-4730-4909-86a3-867fc8e76cd6%2F4DNFIMF6CFOM.hic": "708717889,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fcfee4d87-0873-40b0-b79f-35dcc8669c1c%2F4DNFIZZ77KD2.hic": "732668723,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fb8b5d909-8a1b-41bb-bcdd-d108a0bde762%2F4DNFIOLO226X.hic": "951271932,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F9ce81f6e-b9cf-4ec9-8bd3-517539e4b662%2F4DNFIJMS2ODT.hic": "932509067,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F506aa952-5d41-49ff-b658-916bcf88a395%2F4DNFI49F3LJ4.hic": "1208494817,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fe4dc392d-ca36-4bdf-a27d-173cae34f520%2F4DNFI65MQOIJ.hic": "854630155,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F149ef8d7-e0b4-4e4f-b7e5-7226e2603746%2F4DNFIM4KEPRD.hic": "882790622,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fa436f0a8-4f9a-4524-90ac-795c5b8491cf%2F4DNFIIXBIZFC.hic": "848244425,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fbc8a05dc-7449-4b01-8330-a55db37ca8e6%2F4DNFIWDOOBVE.hic": "1116239020,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Faef8b881-28fe-4694-9a95-1d31940e6726%2F4DNFIDT9EB5M.hic": "888289053,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff66f3162-a53d-46f2-8800-3752935d5400%2F4DNFIX2VUNV8.hic": "1226661451,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F36c782e6-2c48-4298-aa43-bd6624da003d%2F4DNFIEQHTV1R.hic": "804665819,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff15d571e-605d-4bcc-a359-0350b57a6815%2F4DNFIFW7GA64.hic": "901568712,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc2aa2e8b-ac7f-4acb-b4b5-ac5f845840fe%2F4DNFIXGXD67I.hic": "970995551,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F71b6fd7d-b249-4d65-a597-b80b95845399%2F4DNFIA7GB1NB.hic": "956785837,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F6cbb1418-34db-427f-9273-5174eac81529%2F4DNFIVOJGWNP.hic": "890415052,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc69c2ee7-b6c3-4a62-8d4f-913491c9dab8%2F4DNFIW22BNB5.hic": "1075499540,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fa268f28f-c6d9-4324-8989-75d2d317af1b%2F4DNFIIFBC8WN.hic": "1045459440,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F6c7361d4-60a6-440b-b5be-072cada98663%2F4DNFI9ZBEBJH.hic": "759395398,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fcceaad1a-e01e-4430-8bd6-24ffa6891802%2F4DNFID4SLU53.hic": "921288444,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F9eee5854-b33e-4d5a-9ba8-ceffd47e7488%2F4DNFIODI1NUJ.hic": "733159777,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F5e1089b0-42e8-441c-99bb-4be99bcec28b%2F4DNFIJL26LFN.hic": "723567970,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F298a429e-ea29-49d3-bfed-fa851e1e7c4c%2F4DNFI5KTF553.hic": "2213661745,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F965d29f0-e4a3-477c-8ae4-faf4a654e69a%2F4DNFIYSPGFGV.hic": "2274989349,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd88acbc1-37b9-4266-9f97-d8fed576d0f3%2F4DNFILOR6D2D.hic": "2595459358,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F7b6ddbce-0ed1-4272-b8ae-32793e4ea4e4%2F4DNFI1WMMPJQ.hic": "2262433890,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fedc0c8c4-97d8-4372-9a4f-5e0cdf09d7d0%2F4DNFI47P5978.hic": "2146314403,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F0edcc389-43a4-44d7-b946-fe3496f93d56%2F4DNFI7XGW6IH.hic": "2302805723,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F0a802926-e235-4c80-b521-83a1774dfb46%2F4DNFIK1EJG8I.hic": "2374943035,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3c36aedb-6a58-4aa2-9b11-bb440ec174f1%2F4DNFIDQ3THN9.hic": "2341188249,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F846123cd-8828-4e51-8b8a-27deaf293858%2F4DNFI3WPNFWT.hic": "775145629,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fbd06e3ad-0e37-48a3-8367-c7d5912cab03%2F4DNFI9DCUOQ1.hic": "870487824,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc2eaf9bf-9584-4cec-8685-bd74038a6c01%2F4DNFIU8AF5ZY.hic": "1276224366,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F219497b5-3f35-473b-9d4e-e1cf21c69561%2F4DNFIHW8NTQX.hic": "28864787856,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F4be13558-114a-4f2d-abca-7598e2ff4757%2F4DNFI4OUMWZ8.hic": "17061013588,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F49aed637-87a1-4d4d-ae68-e5da82aec05b%2F4DNFIEYQ5ZIR.hic": "13555272651,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fa2f48779-4eff-44a6-8a9d-96435aca1ddc%2F4DNFIDZT7PR8.hic": "13425047093,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fb6ec6b71-27b8-4891-b10a-ab06a5270468%2F4DNFIEJEFCAM.hic": "15394960208,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F68b9a7b5-8413-44fc-8c2d-59a67b1c4166%2F4DNFIJ8JKKWJ.hic": "17012681779,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F294d45a4-8b5e-456f-a9cb-1cbbbad3a7d2%2F4DNFINEQY95T.hic": "13966775978,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fbd7f3a48-b822-41e2-bd9c-f52b3aff7b6a%2F4DNFII6AN691.hic": "12367300362,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F7da44594-0dc8-4e74-8e10-a957aeaea51a%2F4DNFIDBIEXI7.hic": "2015474981,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F085a0453-3784-4eba-80b2-3556e53e2f52%2F4DNFIDKJFK2S.hic": "1983111659,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc370c78c-0a99-4c3f-a29b-2dfafc6a3e86%2F4DNFIPAF4PYT.hic": "3041434294,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F907ce45f-baa5-416d-92de-e86db4bacff1%2F4DNFIWIYYNQ5.hic": "7082321112,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff13afc6b-cf69-4c9d-881f-eed4dd3c28ee%2F4DNFIHMCILEN.hic": "1739157603,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F7575d891-0e3d-4a77-896a-3e1b3a8d330b%2F4DNFIJBJ6QVH.hic": "5213499748,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff0daa830-60d5-4c7c-a2e1-a4ee70b3fee7%2F4DNFIH2A7IKF.hic": "4099503507,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff4970a25-91d8-49a7-9a4a-fe0f12cb2b0f%2F4DNFIOL8KGQ2.hic": "2256042055,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F879f1850-d175-4a86-8a97-12658482e3d1%2F4DNFIWILLD6C.hic": "5476286356,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F787f538e-d619-4c8f-985b-78753fb7e57c%2F4DNFIZBXXJAF.hic": "5946467856,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fb8ee785f-1016-4989-9e64-78352621d32f%2F4DNFI8PZOJHN.hic": "8307204961,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3d8997fa-528c-4531-b25b-a412de6bd472%2F4DNFIGXAMSJY.hic": "6577588285,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F87aede55-7610-4283-af0e-c6840429a31e%2F4DNFIWNNO89O.hic": "2871061417,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F93b8e020-b337-4685-81dc-40cc8a12b5e9%2F4DNFIXU2KPNQ.hic": "3401717686,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ffb5cf1bd-59d6-46fe-857d-b86d9756029d%2F4DNFIHBGD6N6.hic": "840028421,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F2d1bc088-d838-49b8-85fc-fea78a7353c4%2F4DNFI7J8NI4A.hic": "675705256,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F21a27b63-fd67-401b-9aa2-2798e6588d21%2F4DNFISFM9VFK.hic": "800145922,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F656c0a9d-7058-4c4b-a3ce-701d929561c1%2F4DNFIJU5XBK7.hic": "966593603,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F2efacfbd-9c81-4e62-8df7-847d1ab774d5%2F4DNFIPKY8ED1.hic": "3401629450,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fa50b6a26-56b5-43f2-b525-fa219fd716f1%2F4DNFIQRTP7NM.hic": "5358852759,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff5dc7a59-b998-4490-8a76-afbf3b258a49%2F4DNFIBCIA62Q.hic": "5779049277,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F62b2b237-cb02-45f7-89d9-616cf9ffb678%2F4DNFIV56OFE3.hic": "5818844506,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8ac79b4f-cfbf-4b2a-9fc2-898ed6c3e5e1%2F4DNFILIM6FDL.hic": "19637469163,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F1cff8afa-5a13-4ad4-bcad-91fc3ced759c%2F4DNFIP71EWXC.hic": "17934647326,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F000789fe-9a22-4280-a71c-7ad228fd4cac%2F4DNFIM7ZVQOQ.hic": "700134697,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8d78457f-0c2b-4358-b08c-4d4ef4d9f59d%2F4DNFIS6EYHCX.hic": "628314484,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8ca3b4a0-2478-49c9-b4a2-a28430417a32%2F4DNFIKKCMS1Q.hic": "584050634,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff5041473-18ec-439d-92b1-8ad98c9b25c0%2F4DNFIBIV8OUN.hic": "522632731,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fcf474ec6-abd4-431e-a21c-252fcf5ee6b3%2F4DNFIAUMRM2S.hic": "313395531,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F2bb1c73e-fb0f-41c4-8620-a938cc8d24a0%2F4DNFI9ZUXG61.hic": "332217525,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F26dfa41e-7e4f-457a-a3ac-72daf8059f3c%2F4DNFIDBFENL7.hic": "359604894,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8ed2e68b-189e-4988-bb6d-94e63240a231%2F4DNFI7XAZNNQ.hic": "5312422266,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F6f2b1ce0-5205-4680-981e-d91b694dc3e4%2F4DNFISNGDB53.hic": "2008546759,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F73c8147f-bc7d-4d33-8a10-a9e7b413ecc6%2F4DNFI1CIGHYC.hic": "2221847625,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F526ae3e3-32cc-4670-970f-1faa9cfafd4d%2F4DNFIQD2DP2F.hic": "5295591503,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F6e803530-47f8-4c56-bb19-fbdcd578d2f0%2F4DNFINHT8P7C.hic": "3159499486,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ffe705f38-903f-47b7-9b38-f80ebd18a479%2F4DNFIGF8EM7M.hic": "3490552542,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Faa197328-d6da-4299-a0fd-409ac9892668%2F4DNFIUPG2ZBJ.hic": "5382003751,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ffe5d52c4-2be7-4812-bca0-cd4bb3025e6b%2F4DNFIH3OTR14.hic": "3224693110,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F21935f61-daa8-4df2-aa69-fcd27953b405%2F4DNFIUATRW3Z.hic": "3835865655,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F72147527-e3e8-4967-bc45-8251249d76c9%2F4DNFI6V7ZQAE.hic": "4382708138,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F589f0919-f54d-49ff-a482-e2f453ef7f34%2F4DNFICKMT1CY.hic": "4479068191,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F861946ca-bad8-4a87-96e1-b2eb20b9ef10%2F4DNFIF9BDCNI.hic": "3698151402,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff76346ac-97ec-4893-8984-2b75ce1cdc51%2F4DNFIG5O1OQS.hic": "5704288175,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fe8b43826-f049-4c3f-b83a-e75fa7aacc85%2F4DNFIHS2SVBQ.hic": "990025510,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F46316260-f555-4dd4-9e40-8ae06ca52822%2F4DNFIU95B69H.hic": "1275878544,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff62ef491-a3ae-4f66-ab33-c5673c9e0b65%2F4DNFIYRROFCR.hic": "1522530503,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F1cd617e1-fad4-4fdc-8b4e-cb277650123c%2F4DNFIF7JN3IU.hic": "1463443128,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fdb20fe2a-0078-4d4a-8a52-d76043d06f40%2F4DNFIB2RYULQ.hic": "1269529700,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3d386fcf-1d22-47de-a0d6-0c3a641ca174%2F4DNFIMVDK3SI.hic": "1185489599,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F00e470bd-c533-41b1-923a-4b471824da12%2F4DNFIRLOTXSC.hic": "978217499,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fb8774fb3-d0c5-43cc-a6c9-eb0ca39841fb%2F4DNFIZAPX6J8.hic": "1100356082,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fab3b826e-614c-448b-860f-a3ebef68a82f%2F4DNFIQD5VCSD.hic": "1322319877,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F66c78d2b-993a-4937-95ed-9e2d302ceb3e%2F4DNFIIF6VAGN.hic": "868885799,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F5d106fe1-2d80-466e-87aa-46b38ba142c5%2F4DNFI86IEZXH.hic": "751443267,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc99490b6-faf9-413f-9c38-3f53018089d6%2F4DNFIP881SR2.hic": "754427927,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F39c7e387-e710-4b1d-b757-357dec03f6ad%2F4DNFI42NNCW8.hic": "1166392978,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F4742a211-43b1-4325-af6f-82490aeb766b%2F4DNFIEV4PKP6.hic": "1102227476,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Feaa73842-1c86-4ad9-8a9e-c189c0b4c01d%2F4DNFIF1DUQHE.hic": "1206699207,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd25f24df-0298-4079-bb6f-1c8e1e32392b%2F4DNFIGW55EAY.hic": "1033358104,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc57a7ab5-2778-4fe2-9d64-9a4e95135f12%2F4DNFISZRU6I4.hic": "1539570262,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd89f494a-27ca-46b6-89be-7583f3f6d18c%2F4DNFIBKKDTAP.hic": "350372180,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F06725280-cb24-4f22-a267-18b434bfa79e%2F4DNFIJSRQW24.hic": "314361467,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8fe5c3c5-006f-425b-ac6d-ea475e29be78%2F4DNFI3REN89E.hic": "299665258,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc8b6ac5c-13b4-427e-9158-cec0b890b6d8%2F4DNFIF5XLHKM.hic": "235668364,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F01ff33fc-fc23-48aa-a6c6-b720d6fe0768%2F4DNFIB6Q538N.hic": "316494853,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F552978c8-abbc-424a-9187-3e34cf802a97%2F4DNFI3ST3F7Y.hic": "296298411,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F72e66520-5170-4f2e-844a-fbfd0e23b480%2F4DNFIQT4M6UI.hic": "307691265,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fb3eb3953-ffe8-4d5a-970c-a16f3b7b9ec3%2F4DNFIFNCC7M2.hic": "364160436,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F37d413fb-afab-41ff-99aa-1678830f7dde%2F4DNFITM9MDJL.hic": "252412426,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Faf5db92c-aaf1-4086-a0d2-79b28648f172%2F4DNFI3NTD7B3.hic": "227586640,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff6892f7b-1f8a-4d7d-9605-c67932cd5654%2F4DNFIBED48O1.hic": "328344868,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd64afb07-5ab1-4c4f-8438-2fee37afa86a%2F4DNFISATK9PF.hic": "379669025,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fad11bb63-8692-461c-b698-89c601451321%2F4DNFISRP84FE.hic": "298491537,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F63710ec5-35d2-47dd-bf9a-08d3daa83d67%2F4DNFI2LY7B73.hic": "303150299,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F76077d9e-ca75-4301-ab79-88aa49bda495%2F4DNFIXEB4UZO.hic": "711757090,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F34dd4c0e-3487-4fb4-b95f-c4bb66e0fa31%2F4DNFIQWWATGK.hic": "221304476,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F48a8cf86-3248-4a8e-8e85-472ec219d49c%2F4DNFI44JLUSL.hic": "284772724,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fee399fbf-2a9e-46e2-8364-457713bff508%2F4DNFIM7Q2FQQ.hic": "330729464,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F124d191a-c5c7-49b6-b84b-0d1bad8bef2b%2F4DNFIZK7W8GZ.hic": "293166018,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fe351f7cc-7a2c-4515-ae0b-3bb2f91c986a%2F4DNFIMIMLMD3.hic": "240094740,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ffd1ae249-57b1-41d6-81a6-16b21dcd8f12%2F4DNFI7QUSU5J.hic": "681762505,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F46c92c5c-9ad8-4d49-beba-f35c5cd99208%2F4DNFINXUOI5H.hic": "375594313,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd7350d40-4e9e-4131-9151-bb539d39b431%2F4DNFIIJR2296.hic": "331322302,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fbfacf37b-1665-45f3-a046-e29e1544e9b0%2F4DNFIJMZUTXR.hic": "361313244,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F234e18fb-9990-43bf-9a48-f72722cfa232%2F4DNFIZQPT9EL.hic": "540421873,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F4b35ab09-2e79-4876-b2bc-d3a8faa26257%2F4DNFIZIXSZ9J.hic": "545066813,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F2ae5118e-807a-46e0-8e92-143d4b282b3d%2F4DNFIDD9IF9T.hic": "237409149,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fb34d7f6f-73f7-4b6b-80c7-c8af0f991549%2F4DNFIVC8OQPG.hic": "355121712,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F9ab169fd-cbdd-4f60-8553-a4c6912ad89e%2F4DNFITUPI4HA.hic": "313085022,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F4e53712b-d0d9-40c5-afe1-ffa0fad71e59%2F4DNFI5IZNXIO.hic": "341863906,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F7a91477f-45eb-4a16-affb-fc131f9326b8%2F4DNFII16KXA7.hic": "248904495,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F153729de-0eca-43cc-9b61-61aa8d775b38%2F4DNFIAAH19VM.hic": "668047244,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F879fd78a-7165-43d9-a0de-ca158b53df30%2F4DNFIVKIY3KV.hic": "247571318,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F67f901a4-040b-4b04-9fff-94a1780423cd%2F4DNFIVVCWL6C.hic": "198355985,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd5b30c5a-654a-463c-9474-39bdc3ce4500%2F4DNFIJRF2273.hic": "343971277,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F7070280a-8f03-40d0-9fef-e9d9f4d3dae7%2F4DNFI6FCC9ZA.hic": "312013061,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F47049719-9407-4d76-9048-26231045f642%2F4DNFI1CPQ4O3.hic": "352923267,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F862c2b5f-44c2-4bd7-9264-b3ca032d3d8d%2F4DNFISXFEDE9.hic": "271745977,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Feffbe052-39ff-4217-9871-44199ed90818%2F4DNFIF9L6QEQ.hic": "668409334,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fa7791854-1b35-4258-90fb-603c55f24642%2F4DNFIPKASX1Q.hic": "312727920,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F79cccad6-a78e-4de9-9fe7-08f7e8df663d%2F4DNFIWXZ4JQZ.hic": "151808553,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F7e86e0cc-d6f1-4ce0-aba4-c36c6ebb3c4c%2F4DNFIEMQ1O8V.hic": "700533280,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F4a1b58d3-9ae6-43e4-91cf-49f1fcbbab33%2F4DNFIYWONU7A.hic": "729050356,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F67bff264-0b0c-4c5c-9d4d-ff5abef2bbe4%2F4DNFISNIE5FH.hic": "7987657997,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3a6a943f-2cc0-4433-a27d-c89f3fdd3309%2F4DNFIV8MLWJB.hic": "6646216171,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F9e235711-ba90-404d-b4ac-b15990ea8e33%2F4DNFIXSTDPHL.hic": "3146468238,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F0c89f4bc-e9fc-4ecf-b868-26108dbb7bb2%2F4DNFIQJNOH8U.hic": "2919703928,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F1856ff9e-de7a-4fa1-ae0b-3e04b837b5e1%2F4DNFI57XB4A8.hic": "13417594377,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F099bb5b9-6315-4650-8f78-d603f5a046b3%2F4DNFIQ7UKVZV.hic": "9016468637,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Faf3c7a30-0fc4-410d-8d41-247da3eb105d%2F4DNFIWJY8GHD.hic": "7921314766,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fda99f429-20ab-4d91-bbfe-f8bdea8ed7b1%2F4DNFIN8NKRNF.hic": "4247121358,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F0ca0f4e3-30ca-4332-b735-e32dce08e1a4%2F4DNFIZYGEHNZ.hic": "4910404663,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F243f48b0-6b59-4f37-ad39-a12e0986f530%2F4DNFIRPYGAV8.hic": "4220073636,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F49f1a890-d458-42a6-9c78-99c38b6c7a8f%2F4DNFI6MZTDM1.hic": "375035361,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F76bd4768-9343-44ba-a99d-5500e184e39d%2F4DNFIG3BCGPL.hic": "2422923206,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F9d1ed866-eaf6-4906-aa8c-9e39616dde38%2F4DNFIS9YPJ3L.hic": "1593271574,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F1e7a5636-bdb6-45fb-85d8-87a7e908de43%2F4DNFIOWGA9AX.hic": "1632314387,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F5ecc552a-0a6b-49a9-9aa5-9f3fd9b535fd%2F4DNFINKEDSBF.hic": "1458761024,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F6c03f1d2-bb25-4c94-b5f5-d5cdd01c14b6%2F4DNFIVIXVUK7.hic": "1504818271,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F1a4616ff-6d04-4a6a-9773-b80e81da2471%2F4DNFIANHFY16.hic": "1850724180,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd2231870-a78d-4c8b-9cfd-084f2468acb1%2F4DNFIJ67ZFBI.hic": "1473864703,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F859c2dd3-df8a-42b7-86ea-bf6524f75e80%2F4DNFIG3YQQ4V.hic": "1539822829,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8bad667e-6003-4828-9a20-07585fa9c811%2F4DNFIOLKEOME.hic": "3036353747,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F92ea551b-5779-4d31-a0f5-621e4bd0eb21%2F4DNFIVLN8WJE.hic": "2710426318,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F61ee79fa-0617-4083-b121-f92ef3a8905c%2F4DNFI2111XQA.hic": "2589549183,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F83ebb98d-e5db-403d-aa23-875293156c0e%2F4DNFI88HXX7D.hic": "2462367030,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F6d63671a-8f1d-4159-82c0-931b43464772%2F4DNFIUBM6QK8.hic": "2486020469,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fcccb9014-ce15-4032-81ac-222b3d621cb4%2F4DNFIVILEERC.hic": "2052537210,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F21a07867-4007-4ca5-b066-25d3168208dc%2F4DNFIF7Q43N4.hic": "2091773428,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff738de0f-358b-44bf-97dd-644c8d9b1b1c%2F4DNFID56VJGW.hic": "878913568,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fda97c1d4-bb92-4a77-92a7-f7960f88b9dc%2F4DNFIYUR29KO.hic": "983915575,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F54ea363a-99e7-4f55-861e-1644acab7939%2F4DNFIUDPGHO8.hic": "905253594,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fdcd66a07-55ee-48d9-a157-419cf4ee3eef%2F4DNFISWC2N8T.hic": "1233576358,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F40363837-7466-4a1d-b20d-a66d1670b700%2F4DNFICMPHDMI.hic": "516590777,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F0b3fa4e6-caeb-40b4-8942-e9c0b03dfe4f%2F4DNFIKMKN736.hic": "634310295,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fb6a34050-d52b-4880-91cf-d3fe4b0ce982%2F4DNFIN5NLS49.hic": "650451131,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8e63a47b-9fd4-4772-8b0c-10ee589ffb16%2F4DNFI4P8UBRL.hic": "705655033,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F7d92b666-30cc-4838-9d46-c1f11cee3d3c%2F4DNFISNC3LAI.hic": "176146197,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F17f7dc63-a1bc-4970-b389-87d9ee93b753%2F4DNFIVBWPFD7.hic": "749678512,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff8897333-4791-4a83-9444-a653e24aee13%2F4DNFITMQRXB7.hic": "254477361,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8712bf31-33d0-4562-ab0b-a1e9cf4fd30c%2F4DNFIUYD3HBY.hic": "995625724,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fbfaf6383-9cc6-4b5c-9b20-d3bf2e8c3495%2F4DNFIRRSC7P9.hic": "1149985362,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fb0b70598-5d17-4e0a-8831-6cbe697e69e2%2F4DNFIWKR8FP6.hic": "1151628407,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fccc094a8-23ce-4fd8-9c4a-41f07c045c8f%2F4DNFIQ74RSUY.hic": "931695969,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8eda16f3-af5e-4f1f-b46d-c74df44b76aa%2F4DNFI9IIO5PW.hic": "1077740364,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff283637b-cf2c-4412-ba00-0e3d7e279fad%2F4DNFI8WGJG19.hic": "812086456,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F7ad8438f-d3d9-42d8-88bf-42845a0dc2d0%2F4DNFIQ5CCESJ.hic": "652559720,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F70e3bdcc-caf4-4822-b9c5-85234873db7a%2F4DNFIWTZHB4H.hic": "760694196,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F56ed767d-cd8a-4d38-8047-ed1e8bc8cd19%2F4DNFIENYQCDP.hic": "1159428005,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fa912fff9-5f90-42b1-a3a6-cbb9eb2cf861%2F4DNFIFATZWPD.hic": "1033325746,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F21338ea5-fdee-4ad8-b61c-608fc6cec4bc%2F4DNFI7YRXKEO.hic": "388142539,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff0f88647-5631-437b-b48a-4603915e3714%2F4DNFIUY3J7EW.hic": "407344788,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F16926af8-ac3b-4f32-97d5-6c0dc6f1596a%2F4DNFIRKUYKP4.hic": "893352368,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F93e39aec-6cde-4c5b-bcdf-283faa3163a2%2F4DNFIAQDBJZP.hic": "489922022,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F0dc0b1ba-5509-4464-9814-dfe103ff09a0%2F4DNFIC1CLPK7.hic": "565748333,37769", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fb50964c7-b025-49d9-b1ed-289bedb59678%2F4DNFI3A3VYWU.hic": "4597459343,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff4390cea-b330-4022-88c1-9ff8c0a786f7%2F4DNFI6JJQKFJ.hic": "3678393678,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F70c0f730-5da1-4863-9b7a-6cdd31066cff%2F4DNFIK61ILGM.hic": "3324300994,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F14b14ac4-ab59-4754-9c43-eacd9d0638e2%2F4DNFIYD8LO9Z.hic": "3227227120,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F7386f953-8da9-47b0-acb2-931cba810544%2F4DNFIOTPSS3L.hic": "253942497,7557", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff6b5d8bd-27dc-4415-a320-53405a16db85%2F4DNFI525PKU5.hic": "305089653,7557", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F1f922dbc-637b-4c43-b816-f604f0e79ad1%2F4DNFI8Y9SRP2.hic": "1438589609,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F6a36d686-716c-4ba8-a9c3-fa8311791d3c%2F4DNFIP25GZGA.hic": "1419100109,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F0e535542-2cf2-46e4-ba10-7a0b946a7fb2%2F4DNFITPO1WTY.hic": "3885296184,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F0c17d228-5052-4c83-880e-af05118e6929%2F4DNFIG4X5Z5F.hic": "2159245890,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc3977c00-525b-4556-9a27-061707f8cb76%2F4DNFIXLYR32S.hic": "587852728,21916", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3f856506-cbc5-4211-a29d-48a7530c622e%2F4DNFIWI3V5LI.hic": "2318237793,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F38f77979-5eb7-4b6f-9a60-c2451185db98%2F4DNFI2DGL7LH.hic": "2068150664,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fe0992a75-7727-405e-95ac-aa97141b51c1%2F4DNFI1VSO8JP.hic": "1807949651,21916", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fe925f1aa-2e7b-44e7-bfa8-2084a613ab13%2F4DNFIV5O2ZYO.hic": "2242134377,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F803a6d3c-3972-4939-8ff2-d195c5192090%2F4DNFIEWEWQ8D.hic": "2981341325,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F25104375-a588-46e6-a382-663cee6c332f%2F4DNFICSTCJQZ.hic": "14592996888,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F927aa8a5-24a5-43b7-807a-1e99ac321459%2F4DNFICEGAHRC.hic": "15431307603,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8c380474-12cd-41f4-b86f-2a29faf12eec%2F4DNFIY3XPKPO.hic": "2550999291,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F77da562e-d0ec-45a8-8764-14fa16d995a1%2F4DNFIK9PS9GM.hic": "3401011629,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F11b26222-d480-40a7-8d53-3ad8500396cb%2F4DNFIF4Y74JR.hic": "2127593378,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F93df02c6-1047-43f6-afae-d3598b61eeea%2F4DNFIBBKG9KD.hic": "5724446278,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F6cd4378a-8f51-4e65-99eb-15f5c80abf8d%2F4DNFIT4I5C6Z.hic": "5419655766,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F067881e5-563d-40de-a9e3-caccad887fbc%2F4DNFI2U38HCE.hic": "14749043471,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fcb3da9ad-7afe-4d0c-9c2d-261181e7a95c%2F4DNFIETP228R.hic": "9401474797,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F185b7bcc-7bb7-41b7-9ebe-92d4fe159431%2F4DNFIXKC48TK.hic": "11624295594,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F18459b84-dd43-4af6-a05f-bcb773096322%2F4DNFIFPGOWJ6.hic": "2843730862,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ffde1e48c-4a0d-4bb1-b84a-e0e45f9a0aa3%2F4DNFIIRMBE8Y.hic": "5820677927,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fbabed539-1f0f-4e87-8815-fde596e6024c%2F4DNFIVUGNDD7.hic": "5170782436,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F7d00531a-e616-469b-af52-5b028270e2ce%2F4DNFIFLJLIS5.hic": "18917549985,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F7a9dad53-b8af-4cb6-9ce3-5c38e4a855c7%2F4DNFIOX3BGNE.hic": "5482775936,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F82fd7b7e-5f47-48d5-bf0d-daaa48a4674d%2F4DNFISPUVQHA.hic": "2177864938,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F4c6680f3-9cf6-452f-9dc5-ecebf376775d%2F4DNFI8649RQJ.hic": "3288850368,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F2395f001-19d9-4000-9f00-dae3dea708d6%2F4DNFIE8T8JZ8.hic": "1383191843,21916", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F24464fa8-bf96-483c-8e9a-c2f626ad6e19%2F4DNFIBM714BP.hic": "1765204569,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F918fc048-fa27-41d2-a63a-d50c511fbb9a%2F4DNFI6CWNUFL.hic": "2431120602,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F7ff5a0d1-8e54-4cf0-9fe7-339f147c78da%2F4DNFIZ4F74QR.hic": "3211825957,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F355f0412-cb17-452a-b15c-aba16c5a742c%2F4DNFIOUVOX3R.hic": "5547401083,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3cac91c5-160a-4b91-a91e-edc309318dd5%2F4DNFIVTDXW6X.hic": "4797344498,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fe9ac9ec5-6221-4f39-951a-1c5054fc9f1c%2F4DNFICA8Y9TN.hic": "4277557869,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F46f62222-b50a-428b-938b-5444951600eb%2F4DNFIDWM3HN5.hic": "4374808431,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F50e4f2a1-9cb6-4192-8199-64d354bfdf96%2F4DNFIBK5TB3N.hic": "3757387253,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fe4cdd5a8-1a45-4c6a-906b-a9603260d4c8%2F4DNFI3JYF9VS.hic": "5260534916,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc8164e99-5778-427d-be26-f0e1b62400f0%2F4DNFIP1GNKUO.hic": "7589365689,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F0d72e78a-fc87-4716-8b8e-6dc5650ff2ef%2F4DNFIQYQWPF5.hic": "22022259901,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fac58fc15-48c2-4eec-a689-23b677b4b6e7%2F4DNFIW6H9U3S.hic": "6810897169,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F31811e40-e3ca-4456-8ba6-2ee66d6c7104%2F4DNFI7J8BQ4P.hic": "7188744676,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F62d81a52-d2cb-4bbd-8510-0fe120e786e0%2F4DNFIA3AKFSU.hic": "1763730692,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fae0b7513-d1a0-4f27-a9d3-348837f42cb6%2F4DNFID68JQY9.hic": "2422880133,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fae6a1a7e-1d2d-4fd2-a89f-1799abac8a9c%2F4DNFIL1FQDXE.hic": "1543814834,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F80d343c9-bd60-468a-803d-c3e351a958bc%2F4DNFITSIPCSK.hic": "2344682115,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff2d61195-a3a6-4d50-b928-546ca67546cb%2F4DNFIJ88LYHR.hic": "3362742962,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F31052aba-773a-4500-961b-e0a518245b0c%2F4DNFIJIPWD63.hic": "2529548812,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc93d0710-3fbf-40cc-b0eb-878e2aa659e4%2F4DNFIZUP2BBI.hic": "491996147,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8660baeb-5be1-4ba5-93e4-66499e9a4587%2F4DNFIEBC4AF3.hic": "2993048734,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff6d08fbc-b836-4776-82ad-8b1b277ae837%2F4DNFI5VO3E1W.hic": "1949322679,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3af004a2-a6fa-46dc-8be8-898b847a77be%2F4DNFIFDGVWLU.hic": "2456400803,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fbd613b4b-2422-492c-8d8f-8afba9c8a182%2F4DNFITVGFNYZ.hic": "1411204423,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc340694f-14f3-4638-b09b-98220c20039a%2F4DNFIOW9TTC1.hic": "2611370588,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3effa71b-6aa3-4265-87ba-f8d709d778d7%2F4DNFIOAA3ZEQ.hic": "3123195980,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fde75cf8b-9ce1-44fc-8b7b-ca0adea6bae9%2F4DNFIA5ID1S6.hic": "3496246968,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F714f775d-a5a4-4314-83f8-016b9d73200b%2F4DNFIZYU7V81.hic": "4245592042,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F5ca518af-6e1e-4777-b67b-0fe7f039ce58%2F4DNFIRV6PVUX.hic": "3981520466,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc29b57d5-c263-4372-b396-ab4f55682f5d%2F4DNFIMEANFBY.hic": "3999623376,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F4196d3ef-161a-4c18-a57e-005165c6b32a%2F4DNFIGLGQXLC.hic": "4105683321,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fe10828b5-9519-4ceb-81e7-7228bfd890de%2F4DNFILS2HLXC.hic": "3804942111,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Feaac88c7-9bdc-4b1e-aa9f-e675520dfffa%2F4DNFIQS8853L.hic": "5287726781,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Faab371b1-bc8d-4e83-998e-5bb977c443ca%2F4DNFIVBYCYGS.hic": "4657988157,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fdb116add-af8c-4a3b-b106-9f704ba0a175%2F4DNFIE4WWHMF.hic": "5116727268,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F033366e2-05a2-4381-9d48-90122892a9e0%2F4DNFIKDUUC3C.hic": "45638237,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F7284a446-442d-4a46-aae5-84987e75a7af%2F4DNFIJ5HIRA2.hic": "62201052,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F876649a3-6dd3-463a-8b17-5752a98a89c5%2F4DNFIXDFC7EM.hic": "69878143,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3cb4ce4d-d474-459f-8b8a-2159d8df8068%2F4DNFIO35EOVR.hic": "70153114,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F5c5612fa-18c2-47fb-8074-693b1054e254%2F4DNFI57QGL6U.hic": "54605055,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F70c1472d-cf3a-41d7-8682-cd03b7cc978d%2F4DNFI2AGEBE5.hic": "67930121,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F2bf4cce8-6e03-422b-a190-e51d4a07d501%2F4DNFI1E6NJQJ.hic": "4893181511,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F0eb3aa56-8a23-435d-a07b-8bb545e8d708%2F4DNFI2DNFM1A.hic": "60466977,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F1201682a-a223-482d-913d-3c3972b8eb65%2F4DNFIIRIHBR2.hic": "48961678,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F6aee7913-6356-43cf-affa-f2b60dd478f6%2F4DNFIKXNMT46.hic": "39095246,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F357139a3-c9a5-4343-b0a4-b41c45fd03fd%2F4DNFIRV7IRJP.hic": "70916718,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F76be3061-6259-42be-a917-19dcba41517b%2F4DNFIFX1XYKZ.hic": "229197441,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff60c348a-a62c-43c3-ac85-f6c28b5f823f%2F4DNFI64CJUZ5.hic": "112428610,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fbd0b0a14-9703-49af-bb36-2359f96d4d0e%2F4DNFIBPL2HL1.hic": "73972428,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F79ac278d-83f7-4c1f-91b2-05c8018c1426%2F4DNFIBRSIPE4.hic": "415430378,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F0c3b8141-8e67-4211-80dd-3bae88f9e537%2F4DNFIDLDVY14.hic": "112747303,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F2ae703d2-d85c-4ac4-9ce1-14d653927675%2F4DNFI4R1II4P.hic": "210565448,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F76e641af-90be-49f8-b126-12c20f856159%2F4DNFINMLRY95.hic": "1590865292,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3b416382-ae5d-469f-9e9a-85a3e2ce9793%2F4DNFI8KBXYNL.hic": "4626496956,22663", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fa27589a6-86b2-43a2-8218-1f2232d551e6%2F4DNFI53R5IKA.hic": "1536016455,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fdd3999f5-b36e-4154-a6b9-446656959a3a%2F4DNFIAWVDQ8C.hic": "2210273411,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc377953b-0e61-426b-a905-abab2d5a3002%2F4DNFI9VXTBE2.hic": "3384365692,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F2dbe0377-1db2-4aae-af2b-d87dff728035%2F4DNFIT96Z365.hic": "7692311974,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fdcfcb009-f006-4ab8-a4c7-af72be58c12c%2F4DNFITUOMFUQ.hic": "6592120312,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F67f9073d-b2c5-474e-b3d5-7d72cde555cd%2F4DNFIHLQKDN8.hic": "2647703964,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F76968cc8-fb9f-485b-85b2-c9289067194b%2F4DNFIL9M97T2.hic": "6186798917,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F87d9330b-8d2c-4e9d-85bb-02e572de7a68%2F4DNFIDWGZLHX.hic": "4379708168,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ffc01b381-3665-4225-88ee-2e5e9ecb7324%2F4DNFIMEG1QIC.hic": "3587146533,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3144a03c-15c3-4bf9-95f8-ffad2640a1bf%2F4DNFIWSB66VX.hic": "1529739069,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd7d3aac0-ba66-494b-ba0c-147631084b98%2F4DNFIH7TH4MF.hic": "6896300679,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F4b13bd19-fbd1-4c68-8855-4f0158d1ce47%2F4DNFIHKWIZ9T.hic": "1954878455,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3d04e286-30d4-4add-a806-7a929d36419e%2F4DNFIZBBX795.hic": "1350142414,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Faa26f261-a88a-4cac-9118-ff8e90ab6f61%2F4DNFI9ZWZ5BS.hic": "3410552807,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F24e516ce-0b49-4476-b818-cc96471d8765%2F4DNFIPAI8XB5.hic": "4168518737,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fac3b06b5-46d4-4c1e-97e9-9a4f353473a7%2F4DNFI1OUWFSC.hic": "10766406904,21916", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F76c6aa27-895f-4e82-8ed8-7a85aca84490%2F4DNFIX4PJKXZ.hic": "1463157350,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fe6fbe03a-997b-4d72-a3cc-f1ed7bd88a92%2F4DNFIZGCA8AH.hic": "1597664180,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F61d99a87-4ec6-4116-be99-b483999641c4%2F4DNFI5CGQ46V.hic": "2870576870,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F271ea8cd-53b9-44c9-9fff-1bb5c444b54c%2F4DNFIOCW5AEM.hic": "2463600138,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fa98ca64a-861a-4a8c-92e9-586af457b1fb%2F4DNFI1UEG1HD.hic": "22480709268,25900", - "4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F5809b32e-0aea-4cf5-a174-cf162d591a35%2F4DNFI9YAVTI1.hic": "3141182061,25900" - }; - - /* - * The MIT License (MIT) - * - * Copyright (c) 2016-2017 The Regents of the University of California - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and - * associated documentation files (the "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the - * following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING - * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - */ - - class LocusGoto { - - constructor(browser, hicNavbarContainer) { - this.browser = browser; - - const parentElement = hicNavbarContainer.querySelector("div[id$='upper-hic-nav-bar-widget-container']"); - - this.containerElement = document.createElement('div'); - this.containerElement.className = 'hic-chromosome-goto-container'; - this.containerElement.title = 'Chromosome Goto'; - parentElement.appendChild(this.containerElement); - - this.resolutionSelectorElement = document.createElement('input'); - this.resolutionSelectorElement.type = 'text'; - this.resolutionSelectorElement.placeholder = 'chr-x-axis chr-y-axis'; - this.containerElement.appendChild(this.resolutionSelectorElement); - - this.resolutionSelectorElement.addEventListener('change', (e) => { - this.browser.parseGotoInput(this.resolutionSelectorElement.value); - this.resolutionSelectorElement.blur(); - }); - - this.browser.eventBus.subscribe("LocusChange", this); - } - - receiveEvent(event) { - if (event.type === "LocusChange") { - let loci; - const state = event.data.state || this.browser.state; - const isWholeGenome = this.browser.dataset.isWholeGenome(state.chr1); - if (isWholeGenome) { - loci = 'All'; - } else { - - const { chr:chrX, start:sX, end:eX } = state.locus.x; - const strX = `${chrX}:${prettyPrint(1 + sX)}-${prettyPrint(eX)}`; - - const { chr:chrY, start:sY, end:eY } = state.locus.y; - const strY = `${chrY}:${prettyPrint(1 + sY)}-${prettyPrint(eY)}`; - - loci = `${strX} ${strY}`; - - } - this.resolutionSelectorElement.value = loci; - } - } - } - - /* - * The MIT License (MIT) - * - * Copyright (c) 2016-2017 The Regents of the University of California - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and - * associated documentation files (the "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the - * following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING - * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - */ - - class ResolutionSelector { - - constructor(browser, hicNavbarContainer) { - this.browser = browser; - - const parentElement = hicNavbarContainer.querySelector("div[id$='upper-hic-nav-bar-widget-container']"); - - this.containerElement = document.createElement('div'); - this.containerElement.className = 'hic-resolution-selector-container'; - this.containerElement.title = 'Resolution'; - parentElement.appendChild(this.containerElement); - - // label container - this.labelContainerElement = document.createElement('div'); - this.labelContainerElement.id = 'hic-resolution-label-container'; - this.containerElement.appendChild(this.labelContainerElement); - - // Resolution (kb) - this.labelElement = document.createElement('div'); - this.labelElement.textContent = 'Resolution (kb)'; - this.labelElement.style.display = 'none'; - this.labelContainerElement.appendChild(this.labelElement); - - // lock/unlock - this.resolutionLockElement = document.createElement('i'); - this.resolutionLockElement.id = 'hic-resolution-lock'; - this.resolutionLockElement.className = 'fa fa-unlock'; - this.resolutionLockElement.setAttribute('aria-hidden', 'true'); - this.labelContainerElement.appendChild(this.resolutionLockElement); - this.labelContainerElement.addEventListener('click', () => { - this.browser.resolutionLocked = !this.browser.resolutionLocked; - this.setResolutionLock(this.browser.resolutionLocked); - }); - - this.resolutionSelectorElement = document.createElement('select'); - this.resolutionSelectorElement.name = 'resolution_selector'; - this.containerElement.appendChild(this.resolutionSelectorElement); - - this.resolutionSelectorElement.addEventListener('change', () => { - const zoomIndex = parseInt(this.resolutionSelectorElement.value); - this.browser.setZoom(zoomIndex); - }); - - this.browser.eventBus.subscribe("LocusChange", this); - this.browser.eventBus.subscribe("MapLoad", this); - this.browser.eventBus.subscribe("ControlMapLoad", this); - } - - setResolutionLock(resolutionLocked) { - this.resolutionLockElement.classList.remove(resolutionLocked ? 'fa-unlock' : 'fa-lock'); - this.resolutionLockElement.classList.add(resolutionLocked ? 'fa-lock' : 'fa-unlock'); - } - - receiveEvent(event) { - const browser = this.browser; - - if (event.type === "LocusChange") { - if (event.data.resolutionChanged) { - browser.resolutionLocked = false; - this.setResolutionLock(browser.resolutionLocked); - } - - if (event.data.chrChanged !== false) { - const isWholeGenome = browser.dataset.isWholeGenome(event.data.state.chr1); - this.labelElement.textContent = isWholeGenome ? 'Resolution (mb)' : 'Resolution (kb)'; - this.updateResolutions(browser.state.zoom); - } else { - const selectedIndex = browser.state.zoom; - Array.from(this.resolutionSelectorElement.options).forEach((option, index) => { - option.selected = index === selectedIndex; - }); - } - } else if (event.type === "MapLoad") { - browser.resolutionLocked = false; - this.setResolutionLock(false); - this.updateResolutions(browser.state.zoom); - } else if (event.type === "ControlMapLoad") { - this.updateResolutions(browser.state.zoom); - } - } - - async updateResolutions(zoomIndex) { - const browser = this.browser; - const resolutions = browser.isWholeGenome() ? - [{ index: 0, binSize: browser.dataset.wholeGenomeResolution }] : - browser.getResolutions(); - this.resolutionSelectorElement.innerHTML = ''; - - resolutions.forEach(resolution => { - const binSize = resolution.binSize; - const index = resolution.index; - let divisor, unit; - if (binSize >= 1e6) { - divisor = 1e6; - unit = 'mb'; - } else if (binSize >= 1e3) { - divisor = 1e3; - unit = 'kb'; - } else { - divisor = 1; - unit = 'bp'; - } - - const pretty = `${numberFormatter$2(Math.round(binSize / divisor))} ${unit}`; - const option = document.createElement('option'); - option.dataset.resolution = binSize; - option.value = index; - option.textContent = pretty; - if (zoomIndex === index) option.selected = true; - this.resolutionSelectorElement.appendChild(option); - }); - } - } - - /* - * The MIT License (MIT) - * - * Copyright (c) 2016-2017 The Regents of the University of California - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and - * associated documentation files (the "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the - * following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING - * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - */ - - const defaultColorScaleConfig = {threshold: 2000, r: 255, g: 0, b: 0}; - - class ColorScale { - - constructor(scale) { - this.threshold = scale.threshold; - this.r = scale.r; - this.g = scale.g; - this.b = scale.b; - this.cache = []; - this.nbins = 2000; - this.binsize = this.threshold / this.nbins; - } - - setThreshold(threshold) { - this.threshold = threshold; - this.cache = []; - this.binsize = this.threshold / this.nbins; - } - - getThreshold() { - return this.threshold; - } - - setColorComponents(components) { - this.r = components.r; - this.g = components.g; - this.b = components.b; - this.cache = []; - } - - getColorComponents() { - return { - r: this.r, - g: this.g, - b: this.b - } - } - - equals(cs) { - return JSON.stringify(this) === JSON.stringify(cs); - } - - getColor(value) { - const low = 0; - const bin = Math.floor(Math.min(this.threshold, value) / this.binsize); - if (undefined === this.cache[bin]) { - const alpha = Math.floor(255 * (IGVMath$1.clamp(value, low, this.threshold) - low) / (this.threshold - low)); - this.cache[bin] = { - red: this.r, - green: this.g, - blue: this.b, - alpha, - rgbaString: `rgba(${this.r},${this.g},${this.b}, ${alpha})` - }; - } - return this.cache[bin] - } - - stringify() { - return "" + this.threshold + ',' + this.r + ',' + this.g + ',' + this.b; - } - - static parse(string) { - - var pnstr, ratioCS; - - if (string.startsWith("R:")) { - pnstr = string.substring(2).split(":"); - ratioCS = new RatioColorScale(Number.parseFloat(pnstr[0])); - ratioCS.positiveScale = foo(pnstr[1]); - ratioCS.negativeScale = foo(pnstr[2]); - return ratioCS; - } else { - return foo(string); - } - - function foo(str) { - var cs, tokens; - - tokens = str.split(","); - - cs = { - threshold: tokens[0], - r: tokens[1], - g: tokens[2], - b: tokens[3] - }; - return new ColorScale(cs); - } - } - } - - /* - * The MIT License (MIT) - * - * Copyright (c) 2016-2017 The Regents of the University of California - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and - * associated documentation files (the "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the - * following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING - * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - */ - - const defaultRatioColorScaleConfig = {threshold: 5, positive: {r: 255, g: 0, b: 0}, negative: {r: 0, g: 0, b: 255}}; - - class RatioColorScale { - - constructor(threshold) { - - this.threshold = threshold; - - this.positiveScale = new ColorScale({ - threshold: Math.log(threshold), - r: 255, - g: 0, - b: 0 - }); - this.negativeScale = new ColorScale( - { - threshold: Math.log(threshold), - r: 0, - g: 0, - b: 255 - }); - } - - setThreshold(threshold) { - this.threshold = threshold; - this.positiveScale.setThreshold(Math.log(threshold)); - this.negativeScale.setThreshold(Math.log(threshold)); - } - - getThreshold() { - return this.threshold; - } - - setColorComponents(components, plusOrMinus) { - if ('-' === plusOrMinus) { - return this.negativeScale.setColorComponents(components); - } else { - return this.positiveScale.setColorComponents(components); - } - } - - getColorComponents(plusOrMinus) { - - if ('-' === plusOrMinus) { - return this.negativeScale.getColorComponents(); - } else { - return this.positiveScale.getColorComponents(); - } - } - - getColor(score) { - - var logScore = Math.log(score); - - if (logScore < 0) { - return this.negativeScale.getColor(-logScore); - } else { - return this.positiveScale.getColor(logScore); - } - } - - stringify() { - return "R:" + this.threshold + ":" + this.positiveScale.stringify() + ":" + this.negativeScale.stringify(); - } - } - - function getLocus(dataset, state, width, height, bpPerPixel){ - - // bp/bin = (bp/pixel) * (pixel/bin) = bp - const bpPerBin = bpPerPixel * state.pixelSize; - - // bp = bin * bp / bin = bp - const xStartBP = 1 + Math.round(state.x * bpPerBin); - const yStartBP = 1 + Math.round(state.y * bpPerBin); - - const chromosome1 = dataset.chromosomes[state.chr1]; - const chromosome2 = dataset.chromosomes[state.chr2]; - - // bp = (pixel * bin/pixel) * (bp/bin) - // bp = bin * bp/bin = bp - const widthBP = Math.round(bpPerPixel * width); - const heightBP = Math.round(bpPerPixel * height); - - // bp = bp - const xEndBP = Math.min(chromosome1.size, widthBP + xStartBP - 1); - const yEndBP = Math.min(chromosome2.size, heightBP + yStartBP - 1); - - return { xStartBP, yStartBP, xEndBP, yEndBP, chromosome1, chromosome2, pixelSize:state.pixelSize } - - } - - /* - * The MIT License (MIT) - * - * Copyright (c) 2016-2017 The Regents of the University of California - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and - * associated documentation files (the "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the - * following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING - * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - */ - - const DRAG_THRESHOLD = 2; - const DOUBLE_TAP_DIST_THRESHOLD = 20; - const DOUBLE_TAP_TIME_THRESHOLD = 300; - - const imageTileDimension = 685; - - const doLegacyTrack2DRendering = false; - - class ContactMatrixView { - - constructor(browser, viewportElement, sweepZoom, scrollbarWidget, colorScale, ratioColorScale, backgroundColor) { - this.browser = browser; - this.viewportElement = viewportElement; - this.sweepZoom = sweepZoom; - this.scrollbarWidget = scrollbarWidget; - - // Set initial color scales. These might be overridden/adjusted via parameters - this.colorScale = colorScale; - this.ratioColorScale = ratioColorScale; - // this.diffColorScale = new RatioColorScale(100, false); - - this.backgroundColor = backgroundColor; - this.backgroundRGBString = IGVColor$1.rgbColor(backgroundColor.r, backgroundColor.g, backgroundColor.b); - - this.canvasElement = viewportElement.querySelector('canvas'); - this.ctx = this.canvasElement.getContext('2d'); - - this.faSpinnerElement = viewportElement.querySelector('.fa-spinner'); - this.spinnerCount = 0; - - this.xGuideElement = viewportElement.querySelector("div[id$='-x-guide']"); - this.yGuideElement = viewportElement.querySelector("div[id$='-y-guide']"); - - this.displayMode = 'A'; - this.imageTileCache = {}; - this.imageTileCacheKeys = []; - this.imageTileCacheLimit = 8; // 8 is the minimum number required to support A/B cycling - this.colorScaleThresholdCache = {}; - - this.browser.eventBus.subscribe("NormalizationChange", this); - this.browser.eventBus.subscribe("TrackLoad2D", this); - this.browser.eventBus.subscribe("TrackState2D", this); - this.browser.eventBus.subscribe("MapLoad", this); - this.browser.eventBus.subscribe("ControlMapLoad", this); - this.browser.eventBus.subscribe("ColorChange", this); - - this.drawsInProgress = new Set(); - } - - setBackgroundColor(rgb) { - this.backgroundColor = rgb; - this.backgroundRGBString = IGVColor$1.rgbColor(rgb.r, rgb.g, rgb.b); - this.update(); - } - - stringifyBackgroundColor() { - return `${this.backgroundColor.r},${this.backgroundColor.g},${this.backgroundColor.b}` - } - - static parseBackgroundColor(rgbString) { - const [r, g, b] = rgbString.split(",").map(str => parseInt(str)); - return {r, g, b} - } - - setColorScale(colorScale) { - - switch (this.displayMode) { - case 'AOB': - case 'BOA': - this.ratioColorScale = colorScale; - break - case 'AMB': - this.diffColorScale = colorScale; - break - default: - this.colorScale = colorScale; - } - this.colorScaleThresholdCache[colorScaleKey(this.browser.state, this.displayMode)] = colorScale.threshold; - } - - async setColorScaleThreshold(threshold) { - this.getColorScale().setThreshold(threshold); - this.colorScaleThresholdCache[colorScaleKey(this.browser.state, this.displayMode)] = threshold; - this.imageTileCache = {}; - await this.update(); - } - - getColorScale() { - switch (this.displayMode) { - case 'AOB': - case 'BOA': - return this.ratioColorScale - case 'AMB': - return this.diffColorScale - default: - return this.colorScale - } - } - - async setDisplayMode(mode) { - this.displayMode = mode; - this.clearImageCaches(); - await this.update(); - } - - clearImageCaches() { - this.imageTileCache = {}; - this.imageTileCacheKeys = []; - } - - getViewDimensions() { - return { - width: this.viewportElement.offsetWidth, - height: this.viewportElement.offsetHeight - }; - } - - async receiveEvent(event) { - if (event.type === "MapLoad" || event.type === "ControlMapLoad") { - // Don't enable mouse actions until we have a dataset. - if (!this.mouseHandlersEnabled) { - this.addTouchHandlers(this.viewportElement); - this.addMouseHandlers(this.viewportElement); - this.mouseHandlersEnabled = true; - } - this.clearImageCaches(); - this.colorScaleThresholdCache = {}; - } else { - if (event.type !== "LocusChange") { - this.clearImageCaches(); - } - this.update(); - } - } - - async update() { - - if (this.disableUpdates) return // This flag is set during browser startup - - await this.repaint(); - - if (this.browser.dataset && false === doLegacyTrack2DRendering){ - await this.render2DTracks(this.browser.tracks2D, this.browser.dataset, this.browser.state); - } - - } - - async repaint() { - if (!this.browser.dataset) return; - - const viewportWidth = this.viewportElement.offsetWidth; - const viewportHeight = this.viewportElement.offsetHeight; - const canvasWidth = this.canvasElement.width; - const canvasHeight = this.canvasElement.height; - - if (canvasWidth !== viewportWidth || canvasHeight !== viewportHeight) { - this.canvasElement.width = viewportWidth; - this.canvasElement.height = viewportHeight; - this.canvasElement.setAttribute('width', viewportWidth); - this.canvasElement.setAttribute('height', viewportHeight); - } - - const { state, dataset, controlDataset } = this.browser; - let ds = dataset, dsControl = null, zdControl = null; - let zoom = state.zoom, controlZoom; - - switch (this.displayMode) { - case 'B': - zoom = getBZoomIndex(state.zoom); - ds = controlDataset; - break; - case 'AOB': - case 'AMB': - controlZoom = getBZoomIndex(state.zoom); - dsControl = controlDataset; - break; - case 'BOA': - zoom = getBZoomIndex(state.zoom); - controlZoom = state.zoom; - ds = controlDataset; - dsControl = dataset; - break; - } - - const matrix = await ds.getMatrix(state.chr1, state.chr2); - const zd = matrix.getZoomDataByIndex(zoom, "BP"); - - if (dsControl) { - const matrixControl = await dsControl.getMatrix(state.chr1, state.chr2); - zdControl = matrixControl.getZoomDataByIndex(controlZoom, "BP"); - } - - const pixelSizeInt = Math.max(1, Math.floor(state.pixelSize)); - const widthInBins = viewportWidth / pixelSizeInt; - const heightInBins = viewportHeight / pixelSizeInt; - const blockCol1 = Math.floor(state.x / imageTileDimension); - const blockCol2 = Math.floor((state.x + widthInBins) / imageTileDimension); - const blockRow1 = Math.floor(state.y / imageTileDimension); - const blockRow2 = Math.floor((state.y + heightInBins) / imageTileDimension); - - if (state.normalization !== "NONE") { - if (!ds.hasNormalizationVector(state.normalization, zd.chr1.name, zd.zoom.unit, zd.zoom.binSize)) { - Alert.presentAlert(`Normalization option ${state.normalization} unavailable at this resolution.`); - this.browser.eventBus.post(new HICEvent("NormalizationExternalChange", "NONE")); - state.normalization = "NONE"; - } - } - - await this.checkColorScale(ds, zd, blockRow1, blockRow2, blockCol1, blockCol2, state.normalization); - - this.ctx.clearRect(0, 0, viewportWidth, viewportHeight); - for (let r = blockRow1; r <= blockRow2; r++) { - for (let c = blockCol1; c <= blockCol2; c++) { - const tile = await this.getImageTile(ds, dsControl, zd, zdControl, r, c, state); - if (tile.image) this.paintTile(tile); - } - } - - this.genomicExtent = { - chr1: state.chr1, - chr2: state.chr2, - x: state.x * zd.zoom.binSize, - y: state.y * zd.zoom.binSize, - w: viewportWidth * zd.zoom.binSize / state.pixelSize, - h: viewportHeight * zd.zoom.binSize / state.pixelSize - }; - - function getBZoomIndex(zoom) { - const binSize = dataset.getBinSizeForZoomIndex(zoom); - if (!binSize) throw new Error(`Invalid zoom (resolution) index: ${zoom}`); - - const bZoom = controlDataset.getZoomIndexForBinSize(binSize); - if (bZoom < 0) throw new Error(`Invalid binSize for "B" map: ${binSize}`); - - return bZoom; - } - } - - /** - * This is where the image tile is actually drawn, if not in the cache - * - * @param ds - * @param dsControl - * @param zd - * @param zdControl - * @param row - * @param column - * @param state - * @returns {Promise<{image: HTMLCanvasElement, column: *, row: *, blockBinCount}|{image, inProgress: boolean, column: *, row: *, blockBinCount}|*>} - */ - async getImageTile(ds, dsControl, zd, zdControl, row, column, state) { - - const key = `${zd.chr1.name}_${zd.chr2.name}_${zd.zoom.binSize}_${zd.zoom.unit}_${row}_${column}_${state.normalization}_${this.displayMode}`; - - if (this.imageTileCache.hasOwnProperty(key)) { - return this.imageTileCache[key] - - } else { - if (this.drawsInProgress.has(key)) { - //console.log("In progress") - const imageSize = imageTileDimension; - const image = inProgressTile(imageSize); - return { - row: row, - column: column, - blockBinCount: imageTileDimension, - image: image, - inProgress: true - } // TODO return an image at a coarser resolution if avaliable - - } - this.drawsInProgress.add(key); - - try { - this.startSpinner(); - const sameChr = zd.chr1.index === zd.chr2.index; - const transpose = sameChr && row < column; - const averageCount = zd.averageCount; - const ctrlAverageCount = zdControl ? zdControl.averageCount : 1; - const averageAcrossMapAndControl = (averageCount + ctrlAverageCount) / 2; - - const imageSize = imageTileDimension; - const image = document.createElement('canvas'); - image.width = imageSize; - image.height = imageSize; - const ctx = image.getContext('2d'); - //ctx.clearRect(0, 0, image.width, image.height); - - // Get blocks - const widthInBP = imageTileDimension * zd.zoom.binSize; - const x0bp = column * widthInBP; - const region1 = {chr: zd.chr1.name, start: x0bp, end: x0bp + widthInBP}; - const y0bp = row * widthInBP; - const region2 = {chr: zd.chr2.name, start: y0bp, end: y0bp + widthInBP}; - const records = await ds.getContactRecords(state.normalization, region1, region2, zd.zoom.unit, zd.zoom.binSize); - let cRecords; - if (zdControl) { - cRecords = await dsControl.getContactRecords(state.normalization, region1, region2, zdControl.zoom.unit, zdControl.zoom.binSize); - } - - if (records.length > 0) { - - const controlRecords = {}; - if ('AOB' === this.displayMode || 'BOA' === this.displayMode || 'AMB' === this.displayMode) { - for (let record of cRecords) { - controlRecords[record.getKey()] = record; - } - } - - let id = ctx.getImageData(0, 0, image.width, image.height); - - - const x0 = transpose ? row * imageTileDimension : column * imageTileDimension; - const y0 = transpose ? column * imageTileDimension : row * imageTileDimension; - for (let i = 0; i < records.length; i++) { - - const rec = records[i]; - let x = Math.floor((rec.bin1 - x0)); - let y = Math.floor((rec.bin2 - y0)); - - if (transpose) { - const t = y; - y = x; - x = t; - } - - let rgba; - switch (this.displayMode) { - - case 'AOB': - case 'BOA': - let key = rec.getKey(); - let controlRec = controlRecords[key]; - if (!controlRec) { - continue // Skip - } - let score = (rec.counts / averageCount) / (controlRec.counts / ctrlAverageCount); - - rgba = this.ratioColorScale.getColor(score); - - break - - case 'AMB': - key = rec.getKey(); - controlRec = controlRecords[key]; - if (!controlRec) { - continue // Skip - } - score = averageAcrossMapAndControl * ((rec.counts / averageCount) - (controlRec.counts / ctrlAverageCount)); - - rgba = this.diffColorScale.getColor(score); - - break - - default: // Either 'A' or 'B' - rgba = this.colorScale.getColor(rec.counts); - } - - // TODO -- verify that this bitblting is faster than fillRect - setPixel(id, x, y, rgba.red, rgba.green, rgba.blue, rgba.alpha); - if (sameChr && row === column) { - setPixel(id, y, x, rgba.red, rgba.green, rgba.blue, rgba.alpha); - } - - } - - ctx.putImageData(id, 0, 0); - } - - - if (true === doLegacyTrack2DRendering) ; // if (true === doLegacyTrack2DRendering) - - // Uncomment to reveal tile boundaries for debugging. - // ctx.strokeStyle = "rgb(255,255,255)" - // ctx.strokeStyle = "pink" - // ctx.strokeRect(0, 0, image.width - 1, image.height - 1) - - const imageTile = { row, column, blockBinCount: imageTileDimension, image }; - - if (this.imageTileCacheLimit > 0) { - if (this.imageTileCacheKeys.length > this.imageTileCacheLimit) { - delete this.imageTileCache[this.imageTileCacheKeys[0]]; - this.imageTileCacheKeys.shift(); - } - this.imageTileCache[key] = imageTile; - - } - - return imageTile - - } finally { - this.drawsInProgress.delete(key); - this.stopSpinner(); - } - } - - - function setPixel(imageData, x, y, r, g, b, a) { - const index = (x + y * imageData.width) * 4; - imageData.data[index + 0] = r; - imageData.data[index + 1] = g; - imageData.data[index + 2] = b; - imageData.data[index + 3] = a; - } - - } - - /** - * Return a promise to adjust the color scale, if needed. This function might need to load the contact - * data to computer scale. - * - * @param zd - * @param row1 - * @param row2 - * @param col1 - * @param col2 - * @param normalization - * @returns {*} - */ - async checkColorScale(ds, zd, row1, row2, col1, col2, normalization) { - - const colorKey = colorScaleKey(this.browser.state, this.displayMode); // This doesn't feel right, state should be an argument - if ('AOB' === this.displayMode || 'BOA' === this.displayMode) { - return this.ratioColorScale // Don't adjust color scale for A/B. - } - - if (this.colorScaleThresholdCache[colorKey]) { - const changed = this.colorScale.threshold !== this.colorScaleThresholdCache[colorKey]; - this.colorScale.setThreshold(this.colorScaleThresholdCache[colorKey]); - if (changed) { - this.browser.eventBus.post(HICEvent("ColorScale", this.colorScale)); - } - return this.colorScale - } else { - try { - const widthInBP = imageTileDimension * zd.zoom.binSize; - const x0bp = col1 * widthInBP; - const xWidthInBP = (col2 - col1 + 1) * widthInBP; - const region1 = {chr: zd.chr1.name, start: x0bp, end: x0bp + xWidthInBP}; - const y0bp = row1 * widthInBP; - const yWidthInBp = (row2 - row1 + 1) * widthInBP; - const region2 = {chr: zd.chr2.name, start: y0bp, end: y0bp + yWidthInBp}; - const records = await ds.getContactRecords(normalization, region1, region2, zd.zoom.unit, zd.zoom.binSize, true); - - let s = computePercentile(records, 95); - if (!isNaN(s)) { // Can return NaN if all blocks are empty - if (0 === zd.chr1.index) s *= 4; // Heuristic for whole genome view - this.colorScale = new ColorScale(this.colorScale); - this.colorScale.setThreshold(s); - this.computeColorScale = false; - this.browser.eventBus.post(HICEvent("ColorScale", this.colorScale)); - this.colorScaleThresholdCache[colorKey] = s; - } - - return this.colorScale - } finally { - this.stopSpinner(); - } - - - } - - } - - async zoomIn() { - const state = this.browser.state; - const viewportWidth = this.viewportElement.offsetWidth; - const viewportHeight = this.viewportElement.offsetHeight; - const matrices = await getMatrices.call(this, state.chr1, state.chr2); - - const matrix = matrices[0]; - - if (matrix) { - const unit = "BP"; - const zd = await matrix.getZoomDataByIndex(state.zoom, unit); - const newGenomicExtent = { - x: state.x * zd.zoom.binSize, - y: state.y * zd.zoom.binSize, - w: viewportWidth * zd.zoom.binSize / state.pixelSize, - h: viewportHeight * zd.zoom.binSize / state.pixelSize - }; - - // Zoom out not supported - if (newGenomicExtent.w > this.genomicExtent.w) return; - - const sx = ((newGenomicExtent.x - this.genomicExtent.x) / this.genomicExtent.w) * viewportWidth; - const sy = ((newGenomicExtent.y - this.genomicExtent.y) / this.genomicExtent.w) * viewportHeight; - const sWidth = (newGenomicExtent.w / this.genomicExtent.w) * viewportWidth; - const sHeight = (newGenomicExtent.h / this.genomicExtent.h) * viewportHeight; - const img = this.canvasElement; - - const backCanvas = document.createElement('canvas'); - backCanvas.width = img.width; - backCanvas.height = img.height; - const backCtx = backCanvas.getContext('2d'); - backCtx.drawImage(img, sx, sy, sWidth, sHeight, 0, 0, viewportWidth, viewportHeight); - - this.ctx.clearRect(0, 0, viewportWidth, viewportHeight); - this.ctx.drawImage(backCanvas, 0, 0); - } - } - - paintTile({image, row, column, blockBinCount}) { - - const x0 = blockBinCount * column; - const y0 = blockBinCount * row; - - const {x, y, pixelSize} = this.browser.state; - //const pixelSizeInt = Math.max(1, Math.floor(pixelSize)) - const offsetX = (x0 - x) * pixelSize; - const offsetY = (y0 - y) * pixelSize; - - const scale = pixelSize; // / pixelSizeInt - const scaledWidth = image.width * scale; - const scaledHeight = image.height * scale; - - if (offsetX <= this.viewportElement.offsetWidth && offsetX + scaledWidth >= 0 && offsetY <= this.viewportElement.offsetHeight && offsetY + scaledHeight >= 0) { - this.ctx.fillStyle = this.backgroundRGBString; - this.ctx.fillRect(offsetX, offsetY, scaledWidth, scaledHeight); - if (scale === 1) { - this.ctx.drawImage(image, offsetX, offsetY); - } else { - this.ctx.drawImage(image, offsetX, offsetY, scaledWidth, scaledHeight); - } - // Debugging aid, uncomment to see tile boundaries - //this.ctx.strokeRect(offsetX, offsetY, scaledWidth, scaledHeight) - //this.ctx.strokeText(`${row} ${column}`, offsetX, offsetY); - } - } - - startSpinner() { - if (this.browser.isLoadingHICFile && this.browser.userInteractionShield) { - this.browser.userInteractionShield.style.display = 'block'; - } - this.faSpinnerElement.style.display = 'inline-block'; - this.spinnerCount++; - } - - stopSpinner() { - this.spinnerCount--; - if (this.spinnerCount === 0) { - this.faSpinnerElement.style.display = 'none'; - } - this.spinnerCount = Math.max(0, this.spinnerCount); // This should not be necessary - } - - addMouseHandlers(viewportElement) { - - let startX = 0; - let startY = 0; - let currentX = 0; - let currentY = 0; - - let isMouseDown = false; - let isSweepZooming = false; - let mouseDown; - let mouseLast; - let mouseOver; - - const panMouseUpOrMouseOut = () => { - if (this.isDragging) { - this.isDragging = false; - this.browser.eventBus.post(HICEvent("DragStopped")); - } - isMouseDown = false; - mouseDown = mouseLast = undefined; - }; - - this.isDragging = false; - - if (!this.browser.isMobile) { - - viewportElement.addEventListener('mousedown', (e) => { - e.preventDefault(); - e.stopPropagation(); - - if (this.browser.menuElement?.style.display === 'block') { - this.browser.hideMenu(); - } - - mouseLast = { x: e.offsetX, y: e.offsetY }; - mouseDown = { x: e.offsetX, y: e.offsetY }; - - if (e.altKey) { - isSweepZooming = true; - - const { top, left } = viewportElement.getBoundingClientRect(); - startX = e.clientX - left; - startY = e.clientY - top; - - this.sweepZoom.initialize(startX, startY); - } - - isMouseDown = true; - }); - - viewportElement.addEventListener('mousemove', (e) => { - - e.preventDefault(); - e.stopPropagation(); - - const coords = - { - x: e.offsetX, - y: e.offsetY - }; - - const { top, left } = getOffset(viewportElement); - - const xy = - { - x: e.pageX - left, - y: e.pageY - top - }; - - const { width, height } = viewportElement.getBoundingClientRect(); - xy.xNormalized = xy.x / width; - xy.yNormalized = xy.y / height; - - this.browser.eventBus.post(HICEvent("UpdateContactMapMousePosition", xy, false)); - - if (this.willShowCrosshairs) { - this.browser.updateCrosshairs(xy); - this.browser.showCrosshairs(); - } - - if (isMouseDown) { - if (isSweepZooming) { - - const { left, top } = viewportElement.getBoundingClientRect(); - currentX = e.clientX - left; - currentY = e.clientY - top; - const width = Math.abs(currentX - startX); - const height = Math.abs(currentY - startY); - - const config = - { - left: `${Math.min(startX, currentX)}px`, - top: `${Math.min(startY, currentY)}px`, - width: `${width}px`, - height: `${height}px`, - }; - - - this.sweepZoom.update(config); - - } else if (mouseDown.x && Math.abs(coords.x - mouseDown.x) > DRAG_THRESHOLD) { - this.isDragging = true; - const dx = mouseLast.x - coords.x; - const dy = mouseLast.y - coords.y; - this.browser.shiftPixels(dx, dy); - } - mouseLast = coords; - } - }); - - viewportElement.addEventListener('mouseup', panMouseUpOrMouseOut); - - viewportElement.addEventListener('dblclick', (e) => { - e.preventDefault(); - e.stopPropagation(); - const mouseX = e.offsetX; - const mouseY = e.offsetY; - this.browser.zoomAndCenter(1, mouseX, mouseY); - }); - - viewportElement.addEventListener('mouseover', () => mouseOver = true); - viewportElement.addEventListener('mouseout', () => mouseOver = undefined); - - - viewportElement.addEventListener('mouseleave', () => { - this.browser.layoutController.xAxisRuler.unhighlightWholeChromosome(); - this.browser.layoutController.yAxisRuler.unhighlightWholeChromosome(); - panMouseUpOrMouseOut(); - }); - - document.addEventListener('keydown', (e) => { - if (!this.willShowCrosshairs && mouseOver && e.shiftKey) { - this.willShowCrosshairs = true; - this.browser.eventBus.post(HICEvent('DidShowCrosshairs', 'DidShowCrosshairs', false)); - } - }); - - document.addEventListener('keyup', () => { - this.browser.hideCrosshairs(); - this.willShowCrosshairs = undefined; - this.browser.eventBus.post(HICEvent('DidHideCrosshairs', 'DidHideCrosshairs', false)); - }); - - document.addEventListener('mouseup', (e) => { - e.preventDefault(); - e.stopPropagation(); - - if (isSweepZooming) { - isSweepZooming = false; - - const sweepRect = - { - xPixel: Math.min(startX, currentX), - yPixel: Math.min(startY, currentY), - width: Math.abs(currentX - startX), - height: Math.abs(currentY - startY) - }; - - this.sweepZoom.commit(sweepRect); - } - }); - } - } - - /** - * Add touch handlers. Touches are mapped to one of the following application level events - * - double tap, equivalent to double click - * - move - * - pinch - * - * @param $viewport - */ - - addTouchHandlers(viewportElement) { - let lastTouch, pinch; - - const translateTouchCoordinates = (e, target) => { - const rect = target.getBoundingClientRect(); - return { - x: e.pageX - rect.left, - y: e.pageY - rect.top - }; - }; - - viewportElement.ontouchstart = (ev) => { - ev.preventDefault(); - ev.stopPropagation(); - - let touchCoords = translateTouchCoordinates(ev.targetTouches[0], viewportElement); - let offsetX = touchCoords.x; - let offsetY = touchCoords.y; - const count = ev.targetTouches.length; - const timeStamp = ev.timeStamp || Date.now(); - let resolved = false; - - if (count === 2) { - touchCoords = translateTouchCoordinates(ev.targetTouches[1], viewportElement); - offsetX = (offsetX + touchCoords.x) / 2; - offsetY = (offsetY + touchCoords.y) / 2; - } - - if (lastTouch && (timeStamp - lastTouch.timeStamp < DOUBLE_TAP_TIME_THRESHOLD) && count > 1 && lastTouch.count === 1) { - lastTouch = { x: offsetX, y: offsetY, timeStamp, count }; - return; - } - - if (lastTouch && (timeStamp - lastTouch.timeStamp < DOUBLE_TAP_TIME_THRESHOLD)) { - const dx = lastTouch.x - offsetX; - const dy = lastTouch.y - offsetY; - const dist = Math.hypot(dx, dy); - const direction = (lastTouch.count === 2 || count === 2) ? -1 : 1; - - if (dist < DOUBLE_TAP_DIST_THRESHOLD) { - this.browser.zoomAndCenter(direction, offsetX, offsetY); - lastTouch = undefined; - resolved = true; - } - } - - if (!resolved) { - lastTouch = { x: offsetX, y: offsetY, timeStamp, count }; - } - }; - - viewportElement.ontouchmove = throttle((ev) => { - ev.preventDefault(); - ev.stopPropagation(); - - if (ev.targetTouches.length === 2) { - const touchCoords1 = translateTouchCoordinates(ev.targetTouches[0], viewportElement); - const touchCoords2 = translateTouchCoordinates(ev.targetTouches[1], viewportElement); - - const t = { - x1: touchCoords1.x, - y1: touchCoords1.y, - x2: touchCoords2.x, - y2: touchCoords2.y - }; - - pinch ? (pinch.end = t) : (pinch = { start: t }); - } else { - const touchCoords = translateTouchCoordinates(ev.targetTouches[0], viewportElement); - const offsetX = touchCoords.x; - const offsetY = touchCoords.y; - - if (lastTouch) { - const dx = lastTouch.x - offsetX; - const dy = lastTouch.y - offsetY; - if (!isNaN(dx) && !isNaN(dy)) { - this.isDragging = true; - this.browser.shiftPixels(dx, dy); - } - } - - lastTouch = { - x: offsetX, - y: offsetY, - timeStamp: ev.timeStamp || Date.now(), - count: ev.targetTouches.length - }; - } - }, 50); - - viewportElement.ontouchend = (ev) => { - ev.preventDefault(); - ev.stopPropagation(); - - if (pinch && pinch.end) { - const { start, end } = pinch; - const dxStart = start.x2 - start.x1; - const dyStart = start.y2 - start.y1; - const dxEnd = end.x2 - end.x1; - const dyEnd = end.y2 - end.y1; - - const distStart = Math.hypot(dxStart, dyStart); - const distEnd = Math.hypot(dxEnd, dyEnd); - const scale = distEnd / distStart; - - const anchorX = (start.x1 + start.x2) / 2; - const anchorY = (start.y1 + start.y2) / 2; - - if (scale < 0.8 || scale > 1.2) { - lastTouch = undefined; - this.browser.pinchZoom(anchorX, anchorY, scale); - } - } else if (this.isDragging) { - this.isDragging = false; - this.browser.eventBus.post(HICEvent("DragStopped")); - } - - pinch = undefined; - }; - } - - async render2DTracks(track2DList, dataset, state) { - - const matrix = await dataset.getMatrix(state.chr1, state.chr2); - const zoomData = matrix.getZoomDataByIndex(state.zoom, 'BP'); - - const { width, height } = this.getViewDimensions(); - const bpPerPixel = zoomData.zoom.binSize/state.pixelSize; - const { xStartBP, yStartBP, xEndBP, yEndBP } = getLocus(dataset, state, width, height, bpPerPixel); - - zoomData.chr1.name; - zoomData.chr2.name; - - zoomData.chr1.index === zoomData.chr2.index; - - this.ctx.save(); - this.ctx.lineWidth = 2; - - const renderFeatures = (xS, xE, yS, yE) => { - - if (xE < xStartBP || xS > xEndBP || yE < yStartBP || yS > yEndBP) ; else { - const w = Math.max(1, (xE - xS)/bpPerPixel); - const h = Math.max(1, (yE - yS)/bpPerPixel); - const x = Math.floor((xS - xStartBP)/bpPerPixel); - const y = Math.floor((yS - yStartBP)/bpPerPixel); - this.ctx.strokeRect(x, y, w, h); - } - - }; - - const renderLowerFeatures = (track2D, features) => { - for (const { chr1, x1:xS, x2:xE, y1:yS, y2:yE, color } of features) { - - this.ctx.strokeStyle = track2D.color || color; - renderFeatures(xS, xE, yS, yE); - } - }; - - const renderUpperFeatures = (track2D, features) => { - for (const { chr1, x1:yS, x2:yE, y1:xS, y2:xE, color } of features) { - - this.ctx.strokeStyle = track2D.color || color; - renderFeatures(xS, xE, yS, yE); - } - }; - - for (const track2D of track2DList) { - - if (false === track2D.isVisible) { - continue - } - - const features = track2D.getFeatures(zoomData.chr1.name, zoomData.chr1.name); - - if (features) { - - if ('COLLAPSED' === track2D.displayMode || undefined === track2D.displayMode) { - renderLowerFeatures(track2D, features); - renderUpperFeatures(track2D, features); - } else if ('lower' === track2D.displayMode) { - renderLowerFeatures(track2D, features); - } else if ('upper' === track2D.displayMode) { - renderUpperFeatures(track2D, features); - } - - } - - - } - - this.ctx.restore(); - - } - } - - ContactMatrixView.defaultBackgroundColor = {r: 255, g: 255, b: 255}; - - function colorScaleKey(state, displayMode) { - return "" + state.chr1 + "_" + state.chr2 + "_" + state.zoom + "_" + state.normalization + "_" + displayMode - } - - /** - * Returns a promise for an image tile - * - * @param zd - * @param row - * @param column - * @param state - * @returns {*} - */ - - const inProgressCache = {}; - - function inProgressTile(imageSize) { - - let image = inProgressCache[imageSize]; - if (!image) { - image = document.createElement('canvas'); - image.width = imageSize; - image.height = imageSize; - const ctx = image.getContext('2d'); - ctx.font = '24px sans-serif'; - ctx.fillStyle = 'rgb(230, 230, 230)'; - ctx.fillRect(0, 0, image.width, image.height); - ctx.fillStyle = 'black'; - for (let i = 100; i < imageSize; i += 300) { - for (let j = 100; j < imageSize; j += 300) { - ctx.fillText('Loading...', i, j); - } - } - inProgressCache[imageSize] = image; - } - return image - } - - function getMatrices(chr1, chr2) { - - var promises = []; - if ('B' === this.displayMode && this.browser.controlDataset) { - promises.push(this.browser.controlDataset.getMatrix(chr1, chr2)); - } else { - promises.push(this.browser.dataset.getMatrix(chr1, chr2)); - if (this.displayMode && 'A' !== this.displayMode && this.browser.controlDataset) { - promises.push(this.browser.controlDataset.getMatrix(chr1, chr2)); - } - } - return Promise.all(promises) - } - - function computePercentile(records, p) { - const counts = records.map(r => r.counts); - counts.sort(function (a, b) { - return a - b - }); - const idx = Math.floor((p / 100) * records.length); - return counts[idx] - - // return HICMath.percentile(array, p); - } - - /* - * The MIT License (MIT) - * - * Copyright (c) 2016-2017 The Regents of the University of California - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and - * associated documentation files (the "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the - * following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING - * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - */ - - class ColorScaleWidget { - - constructor(browser, hicNavbarContainer) { - this.browser = browser; - - const container = hicNavbarContainer.querySelector("div[id$='lower-hic-nav-bar-widget-container']"); - - this.container = document.createElement('div'); - this.container.className = 'hic-colorscale-widget-container'; - container.appendChild(this.container); - - const { r: _r, g: _g, b: _b } = ContactMatrixView.defaultBackgroundColor; - this.mapBackgroundColorpickerButton = colorSwatch(IGVColor$1.rgbColor(_r, _g, _b)); - this.container.appendChild(this.mapBackgroundColorpickerButton); - this.backgroundColorpicker = createColorPicker(browser, this.mapBackgroundColorpickerButton); - - const { r: nr, g: ng, b: nb } = defaultRatioColorScaleConfig.negative; - this.minusButton = colorSwatch(IGVColor$1.rgbColor(nr, ng, nb)); - this.container.appendChild(this.minusButton); - this.minusColorPicker = createColorPicker(browser, this.minusButton, '-'); - this.minusButton.style.display = 'none'; - - const { r, g, b } = defaultRatioColorScaleConfig.positive; - this.plusButton = colorSwatch(IGVColor$1.rgbColor(r, g, b)); - this.container.appendChild(this.plusButton); - this.plusColorPicker = createColorPicker(browser, this.plusButton, '+'); - - this.minusButton.addEventListener('click', () => presentColorPicker(this.minusColorPicker, this.plusColorPicker, this.backgroundColorpicker)); - this.plusButton.addEventListener('click', () => presentColorPicker(this.plusColorPicker, this.minusColorPicker, this.backgroundColorpicker)); - this.mapBackgroundColorpickerButton.addEventListener('click', () => presentColorPicker(this.backgroundColorpicker, this.minusColorPicker, this.plusColorPicker)); - - this.highColorscaleInput = document.createElement('input'); - this.highColorscaleInput.type = 'text'; - this.highColorscaleInput.title = 'color scale input'; - this.container.appendChild(this.highColorscaleInput); - this.highColorscaleInput.addEventListener('change', (e) => { - const numeric = numberUnFormatter(e.target.value); - if (!isNaN(numeric)) { - browser.setColorScaleThreshold(numeric); - } - }); - - const minusIcon = createIconButton('fa-minus', 'negative threshold', () => this.highColorscaleInput.value = updateThreshold(browser, 0.5)); - this.container.appendChild(minusIcon); - - const plusIcon = createIconButton('fa-plus', 'positive threshold', () => this.highColorscaleInput.value = updateThreshold(browser, 2.0)); - this.container.appendChild(plusIcon); - - browser.eventBus.subscribe("ColorScale", (event) => { - if (event.data instanceof ColorScale) { - this.highColorscaleInput.value = event.data.threshold; - paintSwatch(this.plusButton, event.data); - } else if (event.data instanceof RatioColorScale) { - this.highColorscaleInput.value = event.data.threshold; - paintSwatch(this.minusButton, event.data.negativeScale); - paintSwatch(this.plusButton, event.data.positiveScale); - } - }); - - browser.eventBus.subscribe("DisplayMode", (event) => { - if (event.data === "AOB" || event.data === "BOA") { - this.minusButton.style.display = 'block'; - paintSwatch(this.minusButton, browser.contactMatrixView.ratioColorScale.negativeScale); - paintSwatch(this.plusButton, browser.contactMatrixView.ratioColorScale.positiveScale); - } else { - this.minusButton.style.display = 'none'; - paintSwatch(this.plusButton, browser.contactMatrixView.colorScale); - } - }); - - browser.eventBus.subscribe("MapLoad", () => { - paintSwatch(this.mapBackgroundColorpickerButton, browser.contactMatrixView.backgroundColor); - }); - } - } - - function paintSwatch(swatch, { r, g, b }) { - swatch.style.backgroundColor = IGVColor$1.rgbToHex(IGVColor$1.rgbColor(r, g, b)); - } - - function updateThreshold(browser, scaleFactor) { - const colorScale = browser.getColorScale(); - browser.setColorScaleThreshold(colorScale.getThreshold() * scaleFactor); - return numberFormatter$2(colorScale.getThreshold()); - } - - function createColorPicker(browser, parent, type) { - let defaultColors, colorHandler; - if (!type) { - const { r, g, b } = ContactMatrixView.defaultBackgroundColor; - defaultColors = [IGVColor$1.rgbToHex(IGVColor$1.rgbColor(r, g, b))]; - colorHandler = (hex) => { - parent.style.backgroundColor = hex; - const rgbString = IGVColor$1.hexToRgb(hex); - const [r, g, b] = parseRgbString(rgbString); - browser.contactMatrixView.setBackgroundColor({ r, g, b }); - }; - } else { - defaultColors = [defaultRatioColorScaleConfig.negative, defaultRatioColorScaleConfig.positive].map(({ r, g, b }) => IGVColor$1.rgbToHex(IGVColor$1.rgbColor(r, g, b))); - colorHandler = (hex) => { - parent.style.backgroundColor = hex; - const rgbString = IGVColor$1.hexToRgb(hex); - const [r, g, b] = parseRgbString(rgbString); - browser.getColorScale().setColorComponents({ r, g, b }, type); - browser.repaintMatrix(); - }; - } - return new ColorPicker({ parent, top: 64, left: 64, width: 432, defaultColors, colorHandler }); - } - - function presentColorPicker(presentable, hideableA, hideableB) { - hideableA.hide(); - hideableB.hide(); - presentable.show(); - } - - function colorSwatch(rgbString) { - const swatch = domUtils.div({ class: 'igv-ui-color-swatch' }); - swatch.style.backgroundColor = IGVColor$1.rgbToHex(rgbString); - return swatch; - } - - function createIconButton(iconClass, title, onClick) { - const icon = document.createElement('i'); - icon.className = `fa ${iconClass}`; - icon.title = title; - icon.addEventListener('click', onClick); - return icon; - } - - /* - * The MIT License (MIT) - * - * Copyright (c) 2016-2017 The Regents of the University of California - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and - * associated documentation files (the "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the - * following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING - * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - */ - - /** - * Created by dat on 3/21/17. - */ - - class ControlMapWidget { - - constructor(browser, hicNavbarContainer) { - this.browser = browser; - - const parent = hicNavbarContainer.querySelector("div[id$='lower-hic-nav-bar-widget-container']"); - - this.container = document.createElement('div'); - this.container.className = 'hic-control-map-selector-container'; - this.container.style.display = 'none'; - parent.appendChild(this.container); - - this.select = document.createElement('select'); - this.select.name = 'control_map_selector'; - this.container.appendChild(this.select); - - const toggleContainer = document.createElement('div'); - this.container.appendChild(toggleContainer); - - const cycleContainer = document.createElement('div'); - this.container.appendChild(cycleContainer); - - this.controlMapHash = new ControlMapHash(browser, this.select, toggleContainer, cycleContainer, toggleArrowsUp(), toggleArrowsDown()); - - browser.eventBus.subscribe("ControlMapLoad", () => { - this.controlMapHash.updateOptions(browser.getDisplayMode()); - this.container.style.display = 'block'; - }); - - browser.eventBus.subscribe("MapLoad", () => { - if (!browser.controlDataset) { - this.container.style.display = 'none'; - } - }); - - browser.eventBus.subscribe("DisplayMode", (event) => { - this.controlMapHash.updateOptions(event.data); - }); - } - - toggleDisplayMode() { - this.controlMapHash.toggleDisplayMode(); - } - - toggleDisplayModeCycle() { - this.controlMapHash.toggleDisplayModeCycle(); - } - - getDisplayModeCycle() { - return this.controlMapHash.cycleID; - } - } - - class ControlMapHash { - - constructor(browser, select, toggle, cycle, imgA, imgB) { - this.browser = browser; - this.select = select; - this.toggle = toggle; - this.cycle = cycle; - - this.imgA = imgA; - this.toggle.appendChild(this.imgA); - - this.imgB = imgB; - this.toggle.appendChild(this.imgB); - - this.hash = { - 'A': { title: 'A', value: 'A', other: 'B', hidden: this.imgB, shown: this.imgA }, - 'B': { title: 'B', value: 'B', other: 'A', hidden: this.imgA, shown: this.imgB }, - 'AOB': { title: 'A/B', value: 'AOB', other: 'BOA', hidden: this.imgB, shown: this.imgA }, - 'BOA': { title: 'B/A', value: 'BOA', other: 'AOB', hidden: this.imgA, shown: this.imgB } - }; - - this.select.addEventListener('change', (e) => { - this.disableDisplayModeCycle(); - this.setDisplayMode(e.target.value); - }); - - this.toggle.addEventListener('click', () => { - this.disableDisplayModeCycle(); - this.toggleDisplayMode(); - }); - - this.cycleOutline = cycleOutline(); - cycle.appendChild(this.cycleOutline); - - this.cycleSolid = cycleSolid(); - cycle.appendChild(this.cycleSolid); - this.cycleSolid.style.display = 'none'; - - cycle.addEventListener('click', () => { - this.toggleDisplayModeCycle(); - }); - - cycle.style.display = 'none'; - } - - disableDisplayModeCycle() { - if (this.cycleID) { - clearTimeout(this.cycleID); - this.cycleID = undefined; - this.cycleSolid.style.display = 'none'; - this.cycleOutline.style.display = 'block'; - } - } - - toggleDisplayModeCycle() { - if (this.cycleID) { - this.disableDisplayModeCycle(); - } else { - this.doToggle(); - this.cycleSolid.style.display = 'block'; - this.cycleOutline.style.display = 'none'; - } - } - - async doToggle() { - this.cycleID = setTimeout(async () => { - await this.toggleDisplayMode(); - this.doToggle(); - }, 2500); - } - - async toggleDisplayMode() { - const oldMode = this.browser.getDisplayMode(); - const newMode = this.hash[oldMode].other; - await this.browser.setDisplayMode(newMode); - this.hash[newMode].hidden.style.display = 'none'; - this.hash[newMode].shown.style.display = 'block'; - this.select.value = newMode; - } - - setDisplayMode(mode) { - this.hash[mode].hidden.style.display = 'none'; - this.hash[mode].shown.style.display = 'block'; - this.browser.setDisplayMode(mode); - } - - updateOptions(displayMode) { - this.imgA.style.display = 'none'; - this.imgB.style.display = 'none'; - this.select.innerHTML = ''; - - Object.keys(this.hash).forEach((key) => { - const item = this.hash[key]; - const option = document.createElement('option'); - option.value = item.value; - option.textContent = item.title; - if (displayMode === item.value) { - option.selected = true; - item.shown.style.display = 'block'; - } - this.select.appendChild(option); - }); - } - } - - function toggleArrowsUp() { - const svg = document.createElement('div'); - svg.innerHTML = '...'; // Simplified for brevity - return svg; - } - - function toggleArrowsDown() { - const svg = document.createElement('div'); - svg.innerHTML = '...'; // Simplified for brevity - return svg; - } - - function cycleOutline() { - const svg = document.createElement('div'); - svg.innerHTML = '...'; // Simplified for brevity - return svg; - } - - function cycleSolid() { - const svg = document.createElement('div'); - svg.innerHTML = '...'; // Simplified for brevity - return svg; - } - - /* - * The MIT License (MIT) - * - * Copyright (c) 2016-2017 The Regents of the University of California - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and - * associated documentation files (the "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the - * following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING - * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - */ - - /** - * Created by dat on 3/21/17. - */ - class NormalizationWidget { - - constructor(browser, hicNavBarContainer) { - this.browser = browser; - - const parent = hicNavBarContainer.querySelector("div[id$='lower-hic-nav-bar-widget-container']"); - - this.container = document.createElement('div'); - this.container.className = 'hic-normalization-selector-container'; - this.container.title = 'Normalization'; - parent.appendChild(this.container); - - let label = document.createElement('div'); - label.textContent = 'Norm'; - this.container.appendChild(label); - - this.normalizationSelector = document.createElement('select'); - this.normalizationSelector.name = 'normalization_selector'; - this.normalizationSelector.addEventListener('change', () => { - this.browser.setNormalization(this.normalizationSelector.value); - }); - this.container.appendChild(this.normalizationSelector); - - this.spinner = document.createElement('div'); - this.spinner.textContent = 'Loading ...'; - this.container.appendChild(this.spinner); - this.spinner.style.display = 'none'; - - this.browser.eventBus.subscribe("MapLoad", this); - this.browser.eventBus.subscribe("NormVectorIndexLoad", this); - this.browser.eventBus.subscribe("NormalizationFileLoad", this); - this.browser.eventBus.subscribe("NormalizationExternalChange", this); - } - - startNotReady() { - this.normalizationSelector.style.display = 'none'; - this.spinner.style.display = 'block'; - } - - stopNotReady() { - this.spinner.style.display = 'none'; - this.normalizationSelector.style.display = 'block'; - } - - receiveEvent(event) { - if ("NormVectorIndexLoad" === event.type) { - this.updateOptions(); - this.stopNotReady(); - } else if ("NormalizationFileLoad" === event.type) { - if (event.data === "start") { - this.startNotReady(); - } else { - this.stopNotReady(); - } - } else if ("NormalizationExternalChange" === event.type) { - Array.from(this.normalizationSelector.options).forEach(option => { - option.selected = option.value === event.data; - }); - } - } - - async updateOptions() { - const labels = { - NONE: 'None', - VC: 'Coverage', - VC_SQRT: 'Coverage - Sqrt', - KR: 'Balanced', - INTER_VC: 'Interchromosomal Coverage', - INTER_VC_SQRT: 'Interchromosomal Coverage - Sqrt', - INTER_KR: 'Interchromosomal Balanced', - GW_VC: 'Genome-wide Coverage', - GW_VC_SQRT: 'Genome-wide Coverage - Sqrt', - GW_KR: 'Genome-wide Balanced' - }; - - const norm = this.browser.state.normalization; - const normalizationTypes = await this.browser.getNormalizationOptions(); - if (normalizationTypes) { - this.normalizationSelector.innerHTML = ''; - normalizationTypes.forEach(normalization => { - const option = document.createElement('option'); - option.value = normalization; - option.textContent = labels[normalization] || normalization; - if (norm === normalization) { - option.selected = true; - } - this.normalizationSelector.appendChild(option); - }); - } - } - } - - /* - * The MIT License (MIT) - * - * Copyright (c) 2016-2017 The Regents of the University of California - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and - * associated documentation files (the "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the - * following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING - * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - */ - - class SweepZoom { - - constructor(browser, targetElement) { - this.browser = browser; - this.targetElement = targetElement; - - this.rulerSweeperElement = targetElement.querySelector("div[id$='-sweep-zoom-container']"); - this.rulerSweeperElement.style.display = 'none'; - - this.sweepRect = {}; - } - - initialize(startX, startY) { - this.rulerSweeperElement.style.left = `${startX}px`; - this.rulerSweeperElement.style.top = `${startY}px`; - this.rulerSweeperElement.style.width = '0px'; - this.rulerSweeperElement.style.height = '0px'; - this.rulerSweeperElement.style.display = 'block'; - } - - update({ left, top, width, height }) { - this.rulerSweeperElement.style.width = width; - this.rulerSweeperElement.style.height = height; - this.rulerSweeperElement.style.left = left; - this.rulerSweeperElement.style.top = top; - } - - commit({ xPixel, yPixel, width, height }) { - - this.rulerSweeperElement.style.display = 'none'; - - const { x, y, locus, zoom, pixelSize } = this.browser.state; - - // bp-per-bin - const bpResolution = this.browser.dataset.bpResolutions[zoom]; - - // bp = ((bin + pixel/pixel-per-bin) / bp-per-bin) - const xBP = (x + (xPixel / pixelSize)) * bpResolution; - const yBP = (y + (yPixel / pixelSize)) * bpResolution; - - const widthBP = ( width / pixelSize) * bpResolution; - const heightBP = (height / pixelSize) * bpResolution; - - this.browser.goto(locus.x.chr, Math.round(xBP), Math.round(xBP + widthBP), locus.y.chr, Math.round(yBP), Math.round(yBP + heightBP)); - - } - } - - /* - * The MIT License (MIT) - * - * Copyright (c) 2016-2017 The Regents of the University of California - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and - * associated documentation files (the "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the - * following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING - * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - */ - - class ScrollbarWidget { - - constructor(browser, xAxisScrollbarContainerElement, yAxisScrollbarContainerElement) { - this.browser = browser; - this.isDragging = false; - - // x-axis - this.xAxisScrollbarContainerElement = xAxisScrollbarContainerElement; - this.xAxisScrollbarElement = xAxisScrollbarContainerElement.querySelector("div[id$='-x-axis-scrollbar']"); - this.xLabelElement = this.xAxisScrollbarElement.querySelector('div'); - this.xLabelElement.textContent = ''; - - // y-axis - this.yAxisScrollbarContainerElement = yAxisScrollbarContainerElement; - this.yAxisScrollbarElement = yAxisScrollbarContainerElement.querySelector("div[id$='-y-axis-scrollbar']"); - this.yLabelElement = this.yAxisScrollbarElement.querySelector('.scrollbar-label-rotation-in-place'); - this.yLabelElement.textContent = ''; - - this.browser.eventBus.subscribe("LocusChange", this); - } - - receiveEvent(event) { - - if (!this.isDragging && event.type === "LocusChange") { - const { state } = event.data; - const { dataset } = this.browser; - - if (state.chr1 === 0) { - this.xAxisScrollbarElement.style.display = 'none'; - this.yAxisScrollbarElement.style.display = 'none'; - } else { - this.xAxisScrollbarElement.style.display = 'block'; - this.yAxisScrollbarElement.style.display = 'block'; - - this.xAxisScrollbarContainerElement.style.display = 'block'; - this.yAxisScrollbarContainerElement.style.display = 'block'; - - const { chr1, chr2, zoom, pixelSize, x, y } = state; - - const chromosomeLengthsBin = [chr1, chr2].map(chr => dataset.chromosomes[chr].size / dataset.bpResolutions[zoom]); - const chromosomeLengthsPixel = chromosomeLengthsBin.map(bin => bin * pixelSize); - const { width, height } = this.browser.contactMatrixView.getViewDimensions(); - const pixels = [width, height]; - - const bins = pixels.map(pixel => pixel / pixelSize); - - const percentages = bins.map((bin, i) => { - const binPercentage = Math.min(bin, chromosomeLengthsBin[i]) / chromosomeLengthsBin[i]; - const pixelPercentage = Math.min(chromosomeLengthsPixel[i], pixels[i]) / pixels[i]; - return Math.max(1, Math.round(100 * binPercentage * pixelPercentage)); - }); - - this.xAxisScrollbarElement.style.width = `${percentages[0]}%`; - this.yAxisScrollbarElement.style.height = `${percentages[1]}%`; - - const xPercentage = Math.round(100 * x / chromosomeLengthsBin[0]); - this.xAxisScrollbarElement.style.left = `${xPercentage}%`; - - const yPercentage = Math.round(100 * y / chromosomeLengthsBin[1]); - this.yAxisScrollbarElement.style.top = `${yPercentage}%`; - - this.xLabelElement.textContent = dataset.chromosomes[chr1].name; - this.yLabelElement.textContent = dataset.chromosomes[chr2].name; - } - } - } - - } - - /* - * The MIT License (MIT) - * - * Copyright (c) 2016-2017 The Regents of the University of California - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and - * associated documentation files (the "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the - * following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING - * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - */ - - /** - * Creates and manages the chromosome selector UI component - */ - class ChromosomeSelector { - constructor(browser, container) { - this.browser = browser; - this.container = container; - this.xAxisSelector = container.querySelector("select[name='x-axis-selector']"); - this.yAxisSelector = container.querySelector("select[name='y-axis-selector']"); - - this.initialize(); - } - - initialize() { - // Sync selectors when either changes - this.xAxisSelector.addEventListener('change', () => this.syncSelectors(this.xAxisSelector, this.yAxisSelector)); - this.yAxisSelector.addEventListener('change', () => this.syncSelectors(this.yAxisSelector, this.xAxisSelector)); - - // Handle chromosome swap button click - const nextDiv = this.yAxisSelector.nextElementSibling; - if (nextDiv) { - nextDiv.addEventListener('click', async () => { - const chrX = this.browser.dataset.chromosomes[parseInt(this.xAxisSelector.value, 10)]; - const chrY = this.browser.dataset.chromosomes[parseInt(this.yAxisSelector.value, 10)]; - - const xLocus = this.browser.parseLocusString(chrX.name); - const yLocus = this.browser.parseLocusString(chrY.name); - - await this.browser.setChromosomes(xLocus, yLocus); - }); - } - - // Subscribe to browser events - this.browser.eventBus.subscribe("MapLoad", (event) => { - this.respondToDataLoadWithDataset(event.data); - }); - - this.browser.eventBus.subscribe("LocusChange", (event) => { - this.respondToLocusChangeWithState(event.data.state); - }); - } - - syncSelectors(sourceSelector, targetSelector) { - const value = sourceSelector.value; - if (parseInt(value, 10) === 0 || parseInt(targetSelector.value, 10) === 0) { - targetSelector.value = value; - } - } - - respondToDataLoadWithDataset(dataset) { - const { chromosomes } = dataset; - const options = chromosomes.map(({ name }, index) => ``).join(''); - this.xAxisSelector.innerHTML = options; - this.yAxisSelector.innerHTML = options; - - this.xAxisSelector.value = this.browser.state.chr1; - this.yAxisSelector.value = this.browser.state.chr2; - } - - respondToLocusChangeWithState(state) { - if (!this.xAxisSelector.options.length || !this.yAxisSelector.options.length) return; - - this.xAxisSelector.value = state.chr1; - this.yAxisSelector.value = state.chr2; - } - } - - /* - * The MIT License (MIT) - * - * Copyright (c) 2016-2017 The Regents of the University of California - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and - * associated documentation files (the "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the - * following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING - * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - */ - - class AnnotationWidget { - constructor(browser, container, { title, alertMessage }, trackListRetrievalCallback) { - this.browser = browser; - this.trackListRetrievalCallback = trackListRetrievalCallback; - - this.annotationPresentationButton(container, alertMessage); - this.annotationPanel(browser.rootElement, title); - } - - updateBody(tracks) { - - this.annotationPanelElement.querySelectorAll('.hic-annotation-row-container').forEach(el => el.remove()); - - if (tracks[0] instanceof Track2D) { - for (let i = tracks.length - 1; i >= 0; i--) { - this.annotationPanelRow(this.annotationPanelElement, tracks[i]); - } - } else { - for (const trackRenderer of tracks) { - this.annotationPanelRow(this.annotationPanelElement, trackRenderer); - } - } - } - - annotationPresentationButton(parent, alertMessage) { - const button = parent.querySelector('button'); - - button.addEventListener('click', () => { - const list = this.trackListRetrievalCallback(); - - if (list.length > 0) { - this.updateBody(this.trackListRetrievalCallback()); - this.annotationPanelElement.style.display = - this.annotationPanelElement.style.display === 'none' ? 'flex' : 'none'; - } else { - Alert$1.presentAlert(alertMessage); - } - - this.browser.hideMenu(); - }); - } - - annotationPanel(parent, title) { - this.annotationPanelElement = document.createElement('div'); - this.annotationPanelElement.className = 'hic-annotation-panel-container'; - parent.appendChild(this.annotationPanelElement); - - const panelHeader = document.createElement('div'); - panelHeader.className = 'hic-annotation-panel-header'; - this.annotationPanelElement.appendChild(panelHeader); - - const titleDiv = document.createElement('div'); - titleDiv.textContent = title; - panelHeader.appendChild(titleDiv); - - const closeButtonDiv = document.createElement('div'); - closeButtonDiv.className = 'hic-menu-close-button'; - panelHeader.appendChild(closeButtonDiv); - - const closeIcon = document.createElement('i'); - closeIcon.className = 'fa fa-times'; - closeButtonDiv.appendChild(closeIcon); - - closeIcon.addEventListener('click', () => { - this.annotationPanelElement.style.display = - this.annotationPanelElement.style.display === 'none' ? 'flex' : 'none'; - }); - - makeDraggable(this.annotationPanelElement, panelHeader); - this.annotationPanelElement.style.display = 'none'; - } - - annotationPanelRow(container, track) { - const isTrack2D = track instanceof Track2D; - const trackList = this.trackListRetrievalCallback(); - - let trackRenderer; - if (false === isTrack2D) { - trackRenderer = track.x.track.trackView; - } - - const rowContainer = document.createElement('div'); - rowContainer.className = 'hic-annotation-row-container'; - container.appendChild(rowContainer); - - const row = document.createElement('div'); - row.className = 'hic-annotation-modal-row'; - rowContainer.appendChild(row); - - const trackName = document.createElement('div'); - trackName.textContent = isTrack2D ? track.config.name : track.x.track.config.name; - row.appendChild(trackName); - - if (isTrack2D) { - const visibilityIcon = document.createElement('i'); - visibilityIcon.className = track.isVisible ? 'fa fa-eye fa-lg' : 'fa fa-eye-slash fa-lg'; - row.appendChild(visibilityIcon); - - visibilityIcon.addEventListener('click', () => { - track.isVisible = !track.isVisible; - visibilityIcon.className = track.isVisible ? 'fa fa-eye fa-lg' : 'fa fa-eye-slash fa-lg'; - - this.browser.contactMatrixView.clearImageCaches(); - this.browser.contactMatrixView.update(); - }); - } - - if (isTrack2D) { - const displayModeIcon = document.createElement('div'); - displayModeIcon.className = 'matrix-diagonal-widget-container'; - - switch (track.displayMode) { - case 'lower': - displayModeIcon.classList.add('matrix-diagonal-widget-lower'); - break; - case 'upper': - displayModeIcon.classList.add('matrix-diagonal-widget-upper'); - break; - default: - displayModeIcon.classList.add('matrix-diagonal-widget-all'); - } - - displayModeIcon.addEventListener('click', () => { - this.displayModeHandler(displayModeIcon, track); - this.browser.contactMatrixView.clearImageCaches(); - this.browser.contactMatrixView.update(); - }); - - row.appendChild(displayModeIcon); - } - - const colorpickerContainer = createAnnotationPanelColorpickerContainer(rowContainer, {width: (29 * 24 + 2)}, () => { - const nextElement = row.nextElementSibling; - if (nextElement && nextElement.classList.contains('hic-color-swatch-container')) { - nextElement.style.display = nextElement.style.display === 'none' ? 'flex' : 'none'; - } - }); - - const colorpickerButton = this.annotationColorSwatch(isTrack2D ? track.getColor() : track.x.track.color); - row.appendChild(colorpickerButton); - - colorpickerButton.addEventListener('click', () => { - const nextElement = row.nextElementSibling; - if (nextElement && nextElement.classList.contains('hic-color-swatch-container')) { - nextElement.style.display = nextElement.style.display === 'none' ? 'flex' : 'none'; - } - }); - - colorpickerContainer.style.display = 'none'; - - const colorHandler = color => { - const swatch = row.querySelector('.fa-square'); - if (swatch) { - swatch.style.color = color; - } - - if (isTrack2D) { - track.color = color; - this.browser.eventBus.post(HICEvent('TrackState2D', track)); - } else { - trackRenderer.setColor(color); - } - }; - - createColorSwatchSelector(colorpickerContainer, colorHandler); - - // track up/down - const upDownContainer = document.createElement('div'); - upDownContainer.className = 'up-down-arrow-container'; - row.appendChild(upDownContainer); - - const upTrack = document.createElement('i'); - upTrack.className = 'fa fa-arrow-up'; - upTrack.setAttribute('aria-hidden', 'true'); - upDownContainer.appendChild(upTrack); - - const downTrack = document.createElement('i'); - downTrack.className = 'fa fa-arrow-down'; - downTrack.setAttribute('aria-hidden', 'true'); - upDownContainer.appendChild(downTrack); - - const hiddenColor = '#f7f7f7'; - if (trackList.length === 1) { - upTrack.style.color = hiddenColor; - downTrack.style.color = hiddenColor; - } else if (track === trackList[0]) { - const arrow = isTrack2D ? downTrack : upTrack; - arrow.style.color = hiddenColor; - } else if (track === trackList[trackList.length - 1]) { - const arrow = isTrack2D ? upTrack : downTrack; - arrow.style.color = hiddenColor; - } - - const index = trackList.indexOf(track); - - const moveUp = () => { - const temp = trackList[index + 1]; - trackList[index + 1] = trackList[index]; - trackList[index] = temp; - - if (isTrack2D) { - this.browser.eventBus.post(HICEvent('TrackState2D', trackList)); - this.updateBody(trackList); - } else { - this.browser.updateLayout(); - this.updateBody(trackList); - } - }; - - const moveDown = () => { - const temp = trackList[index - 1]; - trackList[index - 1] = trackList[index]; - trackList[index] = temp; - - if (isTrack2D) { - this.browser.eventBus.post(HICEvent('TrackState2D', trackList)); - this.updateBody(trackList); - } else { - this.browser.updateLayout(); - this.updateBody(trackList); - } - }; - - upTrack.addEventListener('click', isTrack2D ? moveUp : moveDown); - downTrack.addEventListener('click', isTrack2D ? moveDown : moveUp); - - - const deleteIcon = document.createElement('i'); - deleteIcon.className = 'fa fa-trash-o fa-lg'; - row.appendChild(deleteIcon); - - deleteIcon.addEventListener('click', () => { - const index = trackList.indexOf(track); - if (isTrack2D) { - trackList.splice(index, 1); - this.browser.contactMatrixView.clearImageCaches(); - this.browser.contactMatrixView.update(); - this.browser.eventBus.post(HICEvent('TrackLoad2D', trackList)); - } else { - this.browser.layoutController.removeTrackXYPair(track.x.track.trackRenderPair); - } - - this.updateBody(trackList); - }); - } - - displayModeHandler(icon, track2D) { - if (icon.classList.contains('matrix-diagonal-widget-all')) { - icon.classList.replace('matrix-diagonal-widget-all', 'matrix-diagonal-widget-lower'); - track2D.displayMode = 'lower'; - } else if (icon.classList.contains('matrix-diagonal-widget-lower')) { - icon.classList.replace('matrix-diagonal-widget-lower', 'matrix-diagonal-widget-upper'); - track2D.displayMode = 'upper'; - } else { - icon.classList.replace('matrix-diagonal-widget-upper', 'matrix-diagonal-widget-all'); - track2D.displayMode = undefined; - } - } - - annotationColorSwatch(color) { - const swatch = document.createElement('div'); - swatch.className = 'igv-color-swatch'; - - const icon = document.createElement('i'); - icon.className = 'fa fa-square fa-lg'; - icon.style.color = color; - swatch.appendChild(icon); - - return swatch; - } - } - - function createAnnotationPanelColorpickerContainer(parent, size, closeHandler) { - - const container = document.createElement('div'); - container.className = 'hic-color-swatch-container'; - parent.appendChild(container); - - // width - if (size && size.width) { - container.style.width = `${size.width}px`; - } - - // height - if (size && size.height) { - container.style.height = `${size.height}px`; - } - - // header - const header = document.createElement('div'); - container.appendChild(header); - - // close button - const closeButton = document.createElement('i'); - closeButton.className = 'fa fa-times'; - header.appendChild(closeButton); - - closeButton.addEventListener('click', () => { - closeHandler(); - }); - - return container; - } - - /* - * The MIT License (MIT) - * - * Copyright (c) 2016-2017 The Regents of the University of California - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and - * associated documentation files (the "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the - * following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING - * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - */ - - class BrowserUIManager { - constructor(browser) { - this.browser = browser; - this.components = new Map(); - this.initializeComponents(); - } - - initializeComponents() { - const navContainer = getNavbarContainer(this.browser); - - // Navbar components - this.components.set('locusGoto', new LocusGoto(this.browser, navContainer)); - - this.components.set('resolutionSelector', new ResolutionSelector(this.browser, navContainer)); - this.getComponent('resolutionSelector').setResolutionLock(this.browser.resolutionLocked); - - this.components.set('colorScale', new ColorScaleWidget(this.browser, navContainer)); - - this.components.set('controlMap', new ControlMapWidget(this.browser, navContainer)); - - this.components.set('normalization', new NormalizationWidget(this.browser, navContainer)); - - const chromosomeSelectorContainer = this.browser.menuElement.querySelector('.hic-chromosome-selector-widget-container'); - this.components.set('chromosomeSelector', new ChromosomeSelector(this.browser, chromosomeSelectorContainer)); - - const annotationContainer = this.browser.menuElement.querySelector('.hic-annotation-presentation-button-container'); - const annotation2DWidgetConfig = - { - title: '2D Annotations', - alertMessage: 'No 2D annotations currently loaded for this map' - }; - this.components.set('annotationWidget', new AnnotationWidget(this.browser, annotationContainer, annotation2DWidgetConfig, () => this.browser.tracks2D)); - - const sweepZoom = new SweepZoom(this.browser, this.browser.layoutController.getContactMatrixViewport()); - const scrollbarWidget = new ScrollbarWidget( - this.browser, - this.browser.layoutController.getXAxisScrollbarContainer(), - this.browser.layoutController.getYAxisScrollbarContainer() - ); - - const colorScale = new ColorScale(defaultColorScaleConfig); - const ratioColorScale = new RatioColorScale(defaultRatioColorScaleConfig.threshold); - ratioColorScale.setColorComponents(defaultRatioColorScaleConfig.negative, '-'); - ratioColorScale.setColorComponents(defaultRatioColorScaleConfig.positive, '+'); - - this.components.set('sweepZoom', sweepZoom); - this.components.set('scrollbar', scrollbarWidget); - this.components.set('colorScale', colorScale); - this.components.set('ratioColorScale', ratioColorScale); - - // Initialize ContactMatrixView with the components - const backgroundColor = this.browser.config.backgroundColor || ContactMatrixView.defaultBackgroundColor; - this.components.set('contactMatrix', new ContactMatrixView( - this.browser, - this.browser.layoutController.getContactMatrixViewport(), - sweepZoom, - scrollbarWidget, - colorScale, - ratioColorScale, - backgroundColor - )); - } - - getComponent(name) { - return this.components.get(name); - } - - } - - /* - * The MIT License (MIT) - * - * Copyright (c) 2016-2017 The Regents of the University of California - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and - * associated documentation files (the "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the - * following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING - * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - */ - - const DEFAULT_PIXEL_SIZE = 1; - const MAX_PIXEL_SIZE = 128; - const DEFAULT_ANNOTATION_COLOR$1 = "rgb(22, 129, 198)"; - - class HICBrowser { - - constructor(appContainer, config) { - this.config = config; - this.figureMode = config.figureMode || config.miniMode; // Mini mode for backward compatibility - this.resolutionLocked = false; - this.eventBus = new EventBus(); - - this.showTrackLabelAndGutter = true; - - this.id = `browser_${domUtils.guid()}`; - this.trackPairs = []; - this.tracks2D = []; - this.normVectorFiles = []; - - this.synchable = config.synchable !== false; - this.synchedBrowsers = new Set(); - - this.isMobile = isMobile(); - - this.rootElement = document.createElement('div'); - this.rootElement.className = 'hic-root unselect'; - appContainer.appendChild(this.rootElement); - - - if (config.width && config.height) { - setViewportSize(config.width, config.height); - } - - this.layoutController = new LayoutController(this, this.rootElement); - - this.inputDialog = new InputDialog(appContainer, this); - - this.menuElement = this.createMenu(this.rootElement); - this.menuElement.style.display = 'none'; - - // Initialize UI components through BrowserUIManager - this.ui = new BrowserUIManager(this); - - // Get the contact matrix view from UI manager - this.contactMatrixView = this.ui.getComponent('contactMatrix'); - - // prevent user interaction during lengthy data loads - this.userInteractionShield = document.createElement('div'); - this.userInteractionShield.className = 'hic-root-prevent-interaction'; - this.rootElement.appendChild(this.userInteractionShield); - this.userInteractionShield.style.display = 'none'; - - this.hideCrosshairs(); - } - - async init(config) { - this.pending = new Map(); - this.eventBus.hold(); - this.contactMatrixView.disableUpdates = true; - - try { - this.contactMatrixView.startSpinner(); - this.userInteractionShield.style.display = 'block'; - - await this.loadHicFile(config, true); - - if (config.controlUrl) { - await this.loadHicControlFile({ - url: config.controlUrl, - name: config.controlName, - nvi: config.controlNvi, - isControl: true - }, true); - } - - if (config.cycle) { - config.displayMode = "A"; - } - - if (config.displayMode) { - this.contactMatrixView.displayMode = config.displayMode; - this.eventBus.post({ type: "DisplayMode", data: config.displayMode }); - } - - if (config.colorScale) { - if (config.normalization) { - this.state.normalization = config.normalization; - } - this.contactMatrixView.setColorScale(config.colorScale); - this.eventBus.post({ type: "ColorScale", data: this.contactMatrixView.getColorScale() }); - } - - const promises = []; - - if (config.tracks) { - promises.push(this.loadTracks(config.tracks)); - } - - if (config.normVectorFiles) { - config.normVectorFiles.forEach(nv => { - promises.push(this.loadNormalizationFile(nv)); - }); - } - - await Promise.all(promises); - - if (config.normalization) { - const normalizations = await this.getNormalizationOptions(); - const validNormalizations = new Set(normalizations); - this.state.normalization = validNormalizations.has(config.normalization) ? config.normalization : 'NONE'; - } - - const tmp = this.contactMatrixView.colorScaleThresholdCache; - this.eventBus.release(); - this.contactMatrixView.colorScaleThresholdCache = tmp; - - if (config.cycle) { - this.ui.getComponent('controlMap').toggleDisplayModeCycle(); - } else { - await this.update(); - } - - } finally { - this.contactMatrixView.stopSpinner(); - this.userInteractionShield.style.display = 'none'; - this.contactMatrixView.disableUpdates = false; - this.contactMatrixView.update(); - } - } - - createMenu(rootElement) { - const html = ` - `; - - const template = document.createElement('template'); - template.innerHTML = html.trim(); - const menuElement = template.content.firstChild; - - rootElement.appendChild(menuElement); - - const closeButton = menuElement.querySelector(".fa-times"); - closeButton.addEventListener('click', () => this.toggleMenu()); - - return menuElement; - } - - toggleTrackLabelAndGutterState() { - this.showTrackLabelAndGutter = !this.showTrackLabelAndGutter; - } - - toggleMenu() { - if (this.menuElement.style.display === "flex") { - this.hideMenu(); - } else { - this.showMenu(); - } - } - - showMenu() { - this.menuElement.style.display = "flex"; - } - - hideMenu() { - this.menuElement.style.display = "none"; - } - - startSpinner() { - this.contactMatrixView.startSpinner(); - } - - stopSpinner() { - this.contactMatrixView.stopSpinner(); - } - - async setDisplayMode(mode) { - await this.contactMatrixView.setDisplayMode(mode); - this.eventBus.post(HICEvent("DisplayMode", mode)); - } - - getDisplayMode() { - return this.contactMatrixView ? this.contactMatrixView.displayMode : undefined - } - - async getNormalizationOptions() { - - if (!this.dataset) return [] - - const baseOptions = await this.dataset.getNormalizationOptions(); - if (this.controlDataset) { - let controlOptions = await this.controlDataset.getNormalizationOptions(); - controlOptions = new Set(controlOptions); - return baseOptions.filter(base => controlOptions.has(base)) - } else { - return baseOptions - } - } - - /** - * Return usable resolutions, that is the union of resolutions between dataset and controlDataset. - * @returns {{index: *, binSize: *}[]|Array} - */ - getResolutions() { - if (!this.dataset) return [] - - const baseResolutions = this.dataset.bpResolutions.map(function (resolution, index) { - return {index: index, binSize: resolution} - }); - if (this.controlDataset) { - let controlResolutions = new Set(this.controlDataset.bpResolutions); - return baseResolutions.filter(base => controlResolutions.has(base.binSize)) - } else { - return baseResolutions - } - } - - isWholeGenome() { - return this.dataset && this.state && this.dataset.isWholeGenome(this.state.chr1) - } - - getColorScale() { - - if (!this.contactMatrixView) return undefined - - switch (this.getDisplayMode()) { - case 'AOB': - case 'BOA': - return this.contactMatrixView.ratioColorScale - case 'AMB': - return this.contactMatrixView.diffColorScale - default: - return this.contactMatrixView.colorScale - } - } - - setColorScaleThreshold(threshold) { - this.contactMatrixView.setColorScaleThreshold(threshold); - } - - updateCrosshairs({ x, y, xNormalized, yNormalized }) { - - const xGuide = y < 0 ? { left: '0px' } : { top: `${y}px`, left: '0px' }; - this.contactMatrixView.xGuideElement.style.left = xGuide.left; - if (xGuide.top !== undefined) this.contactMatrixView.xGuideElement.style.top = xGuide.top; - - this.layoutController.xTrackGuideElement.style.left = xGuide.left; - if (xGuide.top !== undefined) this.layoutController.xTrackGuideElement.style.top = xGuide.top; - - const yGuide = x < 0 ? { top: '0px' } : { top: '0px', left: `${x}px` }; - this.contactMatrixView.yGuideElement.style.top = yGuide.top; - if (yGuide.left !== undefined) this.contactMatrixView.yGuideElement.style.left = yGuide.left; - - this.layoutController.yTrackGuideElement.style.top = yGuide.top; - if (yGuide.left !== undefined) this.layoutController.yTrackGuideElement.style.left = yGuide.left; - - if (this.customCrosshairsHandler) { - const { x: stateX, y: stateY, pixelSize } = this.state; - const resolution = this.resolution(); - - const xBP = (stateX + (x / pixelSize)) * resolution; - const yBP = (stateY + (y / pixelSize)) * resolution; - - const { startBP: startXBP, endBP: endXBP } = this.genomicState('x'); - const { startBP: startYBP, endBP: endYBP } = this.genomicState('y'); - - this.customCrosshairsHandler({ - xBP, - yBP, - startXBP, - startYBP, - endXBP, - endYBP, - interpolantX: xNormalized, - interpolantY: yNormalized - }); - } - } - - setCustomCrosshairsHandler(crosshairsHandler) { - this.customCrosshairsHandler = crosshairsHandler; - } - - hideCrosshairs() { - this.contactMatrixView.xGuideElement.style.display = 'none'; - this.layoutController.xTrackGuideElement.style.display = 'none'; - - this.contactMatrixView.yGuideElement.style.display = 'none'; - this.layoutController.yTrackGuideElement.style.display = 'none'; - } - - showCrosshairs() { - this.contactMatrixView.xGuideElement.style.display = 'block'; - this.layoutController.xTrackGuideElement.style.display = 'block'; - - this.contactMatrixView.yGuideElement.style.display = 'block'; - this.layoutController.yTrackGuideElement.style.display = 'block'; - } - - genomicState(axis) { - - let width = this.contactMatrixView.getViewDimensions().width; - let resolution = this.dataset.bpResolutions[this.state.zoom]; - const bpp = - (this.dataset.chromosomes[this.state.chr1].name.toLowerCase() === "all") ? - this.genome.getGenomeLength() / width : - resolution / this.state.pixelSize; - - const gs = - { - bpp - }; - - if (axis === "x") { - gs.chromosome = this.dataset.chromosomes[this.state.chr1]; - gs.startBP = this.state.x * resolution; - gs.endBP = gs.startBP + bpp * width; - } else { - gs.chromosome = this.dataset.chromosomes[this.state.chr2]; - gs.startBP = this.state.y * resolution; - gs.endBP = gs.startBP + bpp * this.contactMatrixView.getViewDimensions().height; - } - return gs - } - - /** - * Load a list of 1D genome tracks (wig, etc). - * - * NOTE: public API function - * - * @param configs - */ - async loadTracks(configs) { - const errorPrefix = configs.length === 1 ? `Error loading track ${configs[0].name}` : "Error loading tracks"; - - try { - this.contactMatrixView.startSpinner(); - - const tracks = []; - const promises2D = []; - - for (let config of configs) { - const fileName = isFile(config.url) - ? config.url.name - : config.filename || await getFilename$3(config.url); - - const extension = getExtension(fileName); - - if (['fasta', 'fa'].includes(extension)) { - config.type = config.format = 'sequence'; - } - - if (!config.format) { - config.format = index$1.TrackUtils.inferFileFormat(fileName); - } - - if (config.type === 'annotation') { - config.displayMode = 'COLLAPSED'; - if (config.color === DEFAULT_ANNOTATION_COLOR$1) { - delete config.color; - } - } - - if (config.max === undefined) { - config.autoscale = true; - } - - const { trackHeight } = getLayoutDimensions(); - config.height = trackHeight; - - if (config.format === undefined || ['bedpe', 'interact'].includes(config.format)) { - promises2D.push(Track2D.loadTrack2D(config, this.genome)); - } else { - const track = await index$1.createTrack(config, this); - - if (typeof track.postInit === 'function') { - await track.postInit(); - } - - tracks.push(track); - } - } - - if (tracks.length > 0) { - this.layoutController.updateLayoutWithTracks(tracks); - - const gearContainer = document.querySelector('.hic-igv-right-hand-gutter'); - if (this.showTrackLabelAndGutter) { - gearContainer.style.display = 'block'; - } else { - gearContainer.style.display = 'none'; - } - - await this.updateLayout(); - } - - if (promises2D.length > 0) { - const tracks2D = await Promise.all(promises2D); - if (tracks2D && tracks2D.length > 0) { - this.tracks2D = this.tracks2D.concat(tracks2D); - this.eventBus.post(HICEvent("TrackLoad2D", this.tracks2D)); - } - } - - } catch (error) { - presentError(errorPrefix, error); - console.error(error); - - } finally { - this.contactMatrixView.stopSpinner(); - } - } - - async loadNormalizationFile(url) { - - if (!this.dataset) return - this.eventBus.post(HICEvent("NormalizationFileLoad", "start")); - - const normVectors = await this.dataset.hicFile.readNormalizationVectorFile(url, this.dataset.chromosomes); - for (let type of normVectors['types']) { - if (!this.dataset.normalizationTypes) { - this.dataset.normalizationTypes = []; - } - if (!this.dataset.normalizationTypes.includes(type)) { - this.dataset.normalizationTypes.push(type); - } - this.eventBus.post(HICEvent("NormVectorIndexLoad", this.dataset)); - } - - return normVectors - } - - /** - * Render the XY pair of tracks. - * - * @param xy - */ - async renderTrackXY(xy) { - - try { - this.startSpinner(); - await xy.updateViews(); - } finally { - this.stopSpinner(); - } - } - - reset() { - this.layoutController.removeAllTrackXYPairs(); - this.contactMatrixView.clearImageCaches(); - this.tracks2D = []; - this.tracks = []; - this.contactMapLabel.textContent = ""; - this.contactMapLabel.title = ""; - this.controlMapLabel.textContent = ""; - this.controlMapLabel.title = ""; - this.dataset = undefined; - this.controlDataset = undefined; - this.unsyncSelf(); - } - - clearSession() { - // Clear current datasets. - this.dataset = undefined; - this.controlDataset = undefined; - this.setDisplayMode('A'); - this.unsyncSelf(); - } - - /** - * Remove reference to self from all synchedBrowsers lists. - */ - unsyncSelf() { - const allBrowsers = getAllBrowsers(); - for (let b of allBrowsers) { - b.unsync(this); - } - } - - /** - * Remove the reference browser from this collection of synched browsers - * @param browser - */ - unsync(browser) { - const list = [...this.synchedBrowsers]; - this.synchedBrowsers = new Set(list.filter(b => b !== browser)); - } - - /** - * Load a .hic file - * - * NOTE: public API function - * - * @return a promise for a dataset - * @param config - * @param noUpdates - */ - async loadHicFile(config, noUpdates) { - - if (!config.url) { - console.log("No .hic url specified"); - return undefined - } - - this.clearSession(); - - try { - - this.contactMatrixView.startSpinner(); - if (!noUpdates) { - this.userInteractionShield.style.display = 'block'; - } - - const name = extractName(config); - const prefix = this.controlDataset ? "A: " : ""; - this.contactMapLabel.textContent = prefix + name; - this.contactMapLabel.title = name; - config.name = name; - - const hicFileAlert = str => { - this.eventBus.post(HICEvent('NormalizationExternalChange', 'NONE')); - Alert$1.presentAlert(str); - }; - - this.dataset = await Dataset.loadDataset(Object.assign({alert: hicFileAlert}, config)); - this.dataset.name = name; - - const previousGenomeId = this.genome ? this.genome.id : undefined; - this.genome = new Genome(this.dataset.genomeId, this.dataset.chromosomes); - - if (this.genome.id !== previousGenomeId) { - EventBus.globalBus.post(HICEvent("GenomeChange", this.genome.id)); - } - - if (config.locus) { - this.state = State.default(config); - await this.parseGotoInput(config.locus); - } else if (config.state) { - - if (typeof config.state === 'string') { - await this.setState( State.parse(config.state) ); - } else if (typeof config.state === 'object') { - await this.setState( State.fromJSON(config.state) ); - } else { - alert('config.state is of unknown type'); - console.error('config.state is of unknown type'); - } - - - } else if (config.synchState && this.canBeSynched(config.synchState)) { - await this.syncState(config.synchState); - } else { - await this.setState(State.default(config)); - } - - this.eventBus.post(HICEvent("MapLoad", this.dataset)); - - // Initiate loading of the norm vector index, but don't block if the "nvi" parameter is not available. - // Let it load in the background - - // If nvi is not supplied, try lookup table of known values - if (!config.nvi && typeof config.url === "string") { - const url = new URL(config.url); - const key = encodeURIComponent(url.hostname + url.pathname); - if (nvi.hasOwnProperty(key)) { - config.nvi = nvi[key]; - } - } - - if (config.nvi) { - await this.dataset.getNormVectorIndex(config); - this.eventBus.post(HICEvent("NormVectorIndexLoad", this.dataset)); - } else { - - this.dataset.getNormVectorIndex(config) - .then(normVectorIndex => { - if (!config.isControl) { - this.eventBus.post(HICEvent("NormVectorIndexLoad", this.dataset)); - } - }); - } - - syncBrowsers(); - - // Find a browser to sync with, if any - const compatibleBrowsers = getAllBrowsers().filter(b => b !== this && b.dataset && b.dataset.isCompatible(this.dataset)); - if (compatibleBrowsers.length > 0) { - await this.syncState(compatibleBrowsers[0].getSyncState()); - } - - } catch (error) { - this.contactMapLabel.textContent = ""; - this.contactMapLabel.title = ""; - config.name = name; - throw error - } finally { - this.stopSpinner(); - if (!noUpdates) { - this.userInteractionShield.style.display = 'none'; - } - } - } - - /** - * Load a .hic file for a control map - * - * NOTE: public API function - * - * @return a promise for a dataset - * @param config - */ - async loadHicControlFile(config, noUpdates) { - - try { - this.userInteractionShield.style.display = 'block'; - this.contactMatrixView.startSpinner(); - this.controlUrl = config.url; - const name = extractName(config); - config.name = name; - - const hicFileAlert = str => { - this.eventBus.post(HICEvent('NormalizationExternalChange', 'NONE')); - Alert$1.presentAlert(str); - }; - - const controlDataset = await Dataset.loadDataset(Object.assign({alert: hicFileAlert}, config)); - - controlDataset.name = name; - - if (!this.dataset || this.dataset.isCompatible(controlDataset)) { - this.controlDataset = controlDataset; - if (this.dataset) { - this.contactMapLabel.textContent = "A: " + this.dataset.name; - } - this.controlMapLabel.textContent = "B: " + controlDataset.name; - this.controlMapLabel.title = controlDataset.name; - - //For the control dataset, block until the norm vector index is loaded - await controlDataset.getNormVectorIndex(config); - this.eventBus.post(HICEvent("ControlMapLoad", this.controlDataset)); - - if (!noUpdates) { - this.update(); - } - } else { - Alert$1.presentAlert('"B" map genome (' + controlDataset.genomeId + ') does not match "A" map genome (' + this.genome.id + ')'); - } - } finally { - this.userInteractionShield.style.display = 'none'; - this.stopSpinner(); - } - } - - async parseGotoInput(input) { - const loci = input.trim().split(' '); - - let xLocus = this.parseLocusString(loci[0]) || await this.lookupFeatureOrGene(loci[0]); - - if (!xLocus) { - console.error(`No feature found with name ${loci[ 0 ]}`); - alert(`No feature found with name ${loci[ 0 ]}`); - return; - } - - let yLocus = loci[1] ? this.parseLocusString(loci[1]) : { ...xLocus }; - if (!yLocus) { - yLocus = { ...xLocus }; - } - - if (xLocus.wholeChr && yLocus.wholeChr || 'All' === xLocus.chr && 'All' === yLocus.chr) { - await this.setChromosomes(xLocus, yLocus); - } else { - this.goto(xLocus.chr, xLocus.start, xLocus.end, yLocus.chr, yLocus.start, yLocus.end); - } - } - - parseLocusString(locus) { - const [chrName, range] = locus.trim().toLowerCase().split(':'); - const chromosome = this.genome.getChromosome(chrName); - - if (!chromosome) { - return undefined; - } - - const locusObject = - { - chr: chromosome.name, - wholeChr: (undefined === range && 'All' !== chromosome.name) - }; - - if (true === locusObject.wholeChr || 'All' === chromosome.name) { - // Chromosome name only or All: Set to whole range - locusObject.start = 0; - locusObject.end = chromosome.size; - } else { - - const [startStr, endStr] = range.split('-').map(part => part.replace(/,/g, '')); - - // Internally, loci are 0-based. - locusObject.start = isNaN(startStr) ? undefined : parseInt(startStr, 10) - 1; - locusObject.end = isNaN(endStr) ? undefined : parseInt(endStr, 10); - - } - - return locusObject; - } - - async lookupFeatureOrGene(name) { - - const trimmedName = name.trim(); - const upperName = trimmedName.toUpperCase(); - - if (this.genome.featureDB.has(upperName)) { - Globals.selectedGene = trimmedName; - this.state.selectedGene = Globals.selectedGene; - const {chr, start, end } = this.genome.featureDB.get(upperName); - - // Internally, loci are 0-based. parseLocusString() assumes and user-provided locus which is 1-based - return this.parseLocusString(`${chr}:${start + 1}-${end}`) - } - - const geneResult = await geneSearch(this.genome.id, trimmedName); - if (geneResult) { - Globals.selectedGene = trimmedName; - this.state.selectedGene = Globals.selectedGene; - return this.parseLocusString(geneResult) - } - - return undefined; // No match found - } - - goto(chr1, bpX, bpXMax, chr2, bpY, bpYMax) { - - const { width, height } = this.contactMatrixView.getViewDimensions(); - const { chrChanged, resolutionChanged } = this.state.updateWithLoci(chr1, bpX, bpXMax, chr2, bpY, bpYMax, this, width, height); - - this.contactMatrixView.clearImageCaches(); - - this.update(HICEvent("LocusChange", { state: this.state, resolutionChanged, chrChanged })); - - } - - /** - * Find the closest matching zoom index (index into the dataset resolutions array) for the target resolution. - * - * resolutionAraay can be either - * (1) an array of bin sizes - * (2) an array of objects with index and bin size - * @param targetResolution - * @param resolutionArray - * @returns {number} - */ - findMatchingZoomIndex(targetResolution, resolutionArray) { - const isObject = resolutionArray.length > 0 && resolutionArray[0].index !== undefined; - for (let z = resolutionArray.length - 1; z > 0; z--) { - const binSize = isObject ? resolutionArray[z].binSize : resolutionArray[z]; - const index = isObject ? resolutionArray[z].index : z; - if (binSize >= targetResolution) { - return index - } - } - return 0 - }; - - /** - * @param scaleFactor Values range from greater then 1 to decimal values less then one - * Value > 1 are magnification (zoom in) - * Decimal values (.9, .75, .25, etc.) are minification (zoom out) - * @param anchorPx -- anchor position in pixels (should not move after transformation) - * @param anchorPy - */ - async pinchZoom(anchorPx, anchorPy, scaleFactor) { - - if (this.state.chr1 === 0) { - await this.zoomAndCenter(1, anchorPx, anchorPy); - } else { - try { - this.startSpinner(); - - const bpResolutions = this.getResolutions(); - const currentResolution = bpResolutions[this.state.zoom]; - - let newBinSize; - let newZoom; - let newPixelSize; - let resolutionChanged; - - if (this.resolutionLocked || - (this.state.zoom === bpResolutions.length - 1 && scaleFactor > 1) || - (this.state.zoom === 0 && scaleFactor < 1)) { - // Can't change resolution level, must adjust pixel size - newBinSize = currentResolution.binSize; - newPixelSize = Math.min(MAX_PIXEL_SIZE, this.state.pixelSize * scaleFactor); - newZoom = this.state.zoom; - resolutionChanged = false; - } else { - const targetBinSize = (currentResolution.binSize / this.state.pixelSize) / scaleFactor; - newZoom = this.findMatchingZoomIndex(targetBinSize, bpResolutions); - newBinSize = bpResolutions[newZoom].binSize; - resolutionChanged = newZoom !== this.state.zoom; - newPixelSize = Math.min(MAX_PIXEL_SIZE, newBinSize / targetBinSize); - } - const z = await this.minZoom(this.state.chr1, this.state.chr2); - - - if (!this.resolutionLocked && scaleFactor < 1 && newZoom < z) { - // Zoom out to whole genome - const xLocus = this.parseLocusString('1'); - const yLocus = { xLocus }; - await this.setChromosomes(xLocus, yLocus); - } else { - - await this.state.panWithZoom(newZoom, newPixelSize, anchorPx, anchorPy, newBinSize, this, this.dataset, this.contactMatrixView.getViewDimensions(), bpResolutions); - - await this.contactMatrixView.zoomIn(anchorPx, anchorPy, 1/scaleFactor); - - await this.update(HICEvent("LocusChange", { state: this.state, resolutionChanged, chrChanged: false })); - } - } finally { - this.stopSpinner(); - } - } - - } - - // Zoom in response to a double-click - /** - * Zoom and center on bins at given screen coordinates. Supports double-click zoom, pinch zoom. - * @param direction - * @param centerPX screen coordinate to center on - * @param centerPY screen coordinate to center on - * @returns {Promise} - */ - async zoomAndCenter(direction, centerPX, centerPY) { - - if (undefined === this.dataset) { - console.warn('Dataset is undefined'); - return - } - - if (this.dataset.isWholeGenome(this.state.chr1) && direction > 0) { - // jump from whole genome to chromosome - const genomeCoordX = centerPX * this.dataset.wholeGenomeResolution / this.state.pixelSize; - const genomeCoordY = centerPY * this.dataset.wholeGenomeResolution / this.state.pixelSize; - const chrX = this.genome.getChromosomeForCoordinate(genomeCoordX); - const chrY = this.genome.getChromosomeForCoordinate(genomeCoordY); - const xLocus = { chr: chrX.name, start: 0, end: chrX.size, wholeChr: true }; - const yLocus = { chr: chrY.name, start: 0, end: chrY.size, wholeChr: true }; - await this.setChromosomes(xLocus, yLocus); - } else { - - const { width, height } = this.contactMatrixView.getViewDimensions(); - - const dx = centerPX === undefined ? 0 : centerPX - width / 2; - this.state.x += (dx / this.state.pixelSize); - - const dy = centerPY === undefined ? 0 : centerPY - height / 2; - this.state.y += (dy / this.state.pixelSize); - - const resolutions = this.getResolutions(); - const directionPositive = direction > 0 && this.state.zoom === resolutions[resolutions.length - 1].index; - const directionNegative = direction < 0 && this.state.zoom === resolutions[0].index; - if (this.resolutionLocked || directionPositive || directionNegative) { - - const minPS = await this.minPixelSize(this.state.chr1, this.state.chr2, this.state.zoom); - - const newPixelSize = Math.max(Math.min(MAX_PIXEL_SIZE, this.state.pixelSize * (direction > 0 ? 2 : 0.5)), minPS); - - const shiftRatio = (newPixelSize - this.state.pixelSize) / newPixelSize; - - this.state.pixelSize = newPixelSize; - - - this.state.x += shiftRatio * (width / this.state.pixelSize); - this.state.y += shiftRatio * (height / this.state.pixelSize); - - this.state.clampXY(this.dataset, this.contactMatrixView.getViewDimensions()); - - this.state.configureLocus(this, this.dataset, { width, height }); - - this.update(HICEvent("LocusChange", {state: this.state, resolutionChanged: false, chrChanged: false})); - - } else { - let i; - for (i = 0; i < resolutions.length; i++) { - if (this.state.zoom === resolutions[i].index) break - } - if (i) { - const newZoom = resolutions[i + direction].index; - this.setZoom(newZoom); - } - } - } - } - - /** - * Set the current zoom state and opctionally center over supplied coordinates. - * @param zoom - index to the datasets resolution array (dataset.bpResolutions) - * @returns {Promise} - */ - async setZoom(zoom) { - - const resolutionChanged = await this.state.setWithZoom(zoom, this.contactMatrixView.getViewDimensions(), this, this.dataset); - - await this.contactMatrixView.zoomIn(); - - this.update(HICEvent("LocusChange", { state: this.state, resolutionChanged, chrChanged: false })); - - } - - async setChromosomes(xLocus, yLocus) { - - const { index:chr1Index } = this.genome.getChromosome(xLocus.chr); - const { index:chr2Index } = this.genome.getChromosome(yLocus.chr); - - this.state.chr1 = Math.min(chr1Index, chr2Index); - this.state.x = 0; - - this.state.chr2 = Math.max(chr1Index, chr2Index); - this.state.y = 0; - - this.state.locus = - { - x: { chr: xLocus.chr, start: xLocus.start, end: xLocus.end }, - y: { chr: yLocus.chr, start: yLocus.start, end: yLocus.end } - }; - - if (xLocus.wholeChr && yLocus.wholeChr) { - this.state.zoom = await this.minZoom(this.state.chr1, this.state.chr2); - const minPS = await this.minPixelSize(this.state.chr1, this.state.chr2, this.state.zoom); - this.state.pixelSize = Math.min(100, Math.max(DEFAULT_PIXEL_SIZE, minPS)); - } else { - // Whole Genome - this.state.zoom = 0; - const minPS = await this.minPixelSize(this.state.chr1, this.state.chr2, this.state.zoom); - this.state.pixelSize = Math.max(this.state.pixelSize, minPS); - - } - - await this.update(HICEvent("LocusChange", {state: this.state, resolutionChanged: true, chrChanged: true})); - - } - - /** - * Called on loading tracks - * @returns {Promise} - */ - async updateLayout() { - - this.state.clampXY(this.dataset, this.contactMatrixView.getViewDimensions()); - - for (const trackXYPair of this.trackPairs) { - - trackXYPair.x.viewportElement.style.order = `${this.trackPairs.indexOf(trackXYPair)}`; - trackXYPair.y.viewportElement.style.order = `${this.trackPairs.indexOf(trackXYPair)}`; - - trackXYPair.x.syncCanvas(); - trackXYPair.y.syncCanvas(); - - } - - this.layoutController.xAxisRuler.update(); - this.layoutController.yAxisRuler.update(); - - setTrackReorderArrowColors(this.trackPairs); - - await this.update(); - - } - - /** - * Set the matrix state. Used to restore state from a bookmark - * @param state browser state - */ - async setState(state) { - - const chrChanged = !this.state || this.state.chr1 !== state.chr1 || this.state.chr2 !== state.chr2; - - this.state = state.clone(); - - // Possibly adjust pixel size - const minPS = await this.minPixelSize(this.state.chr1, this.state.chr2, this.state.zoom); - this.state.pixelSize = Math.max(state.pixelSize, minPS); - - // Derive locus if none is present in source state - if (undefined === state.locus) { - const viewDimensions = this.contactMatrixView.getViewDimensions(); - this.state.configureLocus(this, this.dataset, viewDimensions); - } - - const hicEvent = new HICEvent("LocusChange", { state: this.state, resolutionChanged: true, chrChanged }); - this.update(hicEvent); - this.eventBus.post(hicEvent); - } - - /** - * Return a modified state object used for synching. Other datasets might have different chromosome ordering - * and resolution arrays - */ - getSyncState() { - return { - chr1Name: this.dataset.chromosomes[this.state.chr1].name, - chr2Name: this.dataset.chromosomes[this.state.chr2].name, - binSize: this.dataset.bpResolutions[this.state.zoom], - binX: this.state.x, // TODO: translate to lower right corner - binY: this.state.y, - pixelSize: this.state.pixelSize - } - } - - /** - * Return true if this browser can be synced to the given state - * @param syncState - */ - canBeSynched(syncState) { - - if (false === this.synchable) return false // Explicitly not synchable - - return this.dataset && - (this.dataset.getChrIndexFromName(syncState.chr1Name) !== undefined) && - (this.dataset.getChrIndexFromName(syncState.chr2Name) !== undefined) - - } - - async syncState(targetState) { - - if (!targetState || false === this.synchable) return - - if (!this.dataset) return - - const { zoomChanged, chrChanged } = this.state.sync(targetState, this, this.genome, this.dataset); - - const payload = { state: this.state, resolutionChanged: zoomChanged, chrChanged }; - this.update(HICEvent("LocusChange", payload, false)); - - } - - setNormalization(normalization) { - - this.state.normalization = normalization; - this.eventBus.post(HICEvent("NormalizationChange", this.state.normalization)); - } - - shiftPixels(dx, dy) { - - if (undefined === this.dataset) { - console.warn('dataset is undefined'); - return - } - - this.state.panShift(dx, dy, this, this.dataset, this.contactMatrixView.getViewDimensions()); - - const locusChangeEvent = HICEvent("LocusChange", { - state: this.state, - resolutionChanged: false, - dragging: true, - chrChanged: false - }); - locusChangeEvent.dragging = true; - - this.update(locusChangeEvent); - this.eventBus.post(locusChangeEvent); - } - - /** - * Update the maps and tracks. This method can be called from the browser event thread repeatedly, for example - * while mouse dragging. If called while an update is in progress queue the event for processing later. It - * is only neccessary to queue the most recent recently received event, so a simple instance variable will suffice - * for the queue. - * - * @param event - */ - async update(event) { - - if (this.updating) { - const type = event ? event.type : "NONE"; - this.pending.set(type, event); - } else { - this.updating = true; - try { - - this.startSpinner(); - if (event !== undefined && "LocusChange" === event.type) { - this.layoutController.xAxisRuler.locusChange(event); - this.layoutController.yAxisRuler.locusChange(event); - } - - const promises = []; - - for (let xyTrackRenderPair of this.trackPairs) { - promises.push(this.renderTrackXY(xyTrackRenderPair)); - } - promises.push(this.contactMatrixView.update(event)); - await Promise.all(promises); - - if (event && event.propogate) { - let syncState1 = this.getSyncState(); - for (const browser of [...this.synchedBrowsers]) { - browser.syncState(syncState1); - } - } - - } finally { - this.updating = false; - if (this.pending.size > 0) { - const events = []; - for (let [k, v] of this.pending) { - events.push(v); - } - this.pending.clear(); - for (let e of events) { - this.update(e); - } - } - if (event) { - // possibly, unless update was called from an event post (infinite loop) - this.eventBus.post(event); - } - this.stopSpinner(); - } - } - } - - repaintMatrix() { - this.contactMatrixView.imageTileCache = {}; - this.contactMatrixView.initialImage = undefined; - this.contactMatrixView.update(); - } - - resolution() { - return this.dataset.bpResolutions[this.state.zoom] - }; - - toJSON() { - - if (!(this.dataset && this.dataset.url)) return "{}" // URL is required - - const jsonOBJ = {}; - - jsonOBJ.backgroundColor = this.contactMatrixView.stringifyBackgroundColor(); - jsonOBJ.url = this.dataset.url; - if (this.dataset.name) { - jsonOBJ.name = this.dataset.name; - } - - jsonOBJ.state = this.state.toJSON(); - - jsonOBJ.colorScale = this.contactMatrixView.getColorScale().stringify(); - if (Globals.selectedGene) { - jsonOBJ.selectedGene = Globals.selectedGene; - } - let nviString = this.dataset.hicFile.config.nvi; - if (nviString) { - jsonOBJ.nvi = nviString; - } - if (this.controlDataset) { - jsonOBJ.controlUrl = this.controlUrl; - if (this.controlDataset.name) { - jsonOBJ.controlName = this.controlDataset.name; - } - const displayMode = this.getDisplayMode(); - if (displayMode) { - jsonOBJ.displayMode = this.getDisplayMode(); - } - nviString = this.controlDataset.hicFile.config.nvi; - if (nviString) { - jsonOBJ.controlNvi = nviString; - } - const controlMapWidget = this.ui.getComponent('controlMap'); - if (controlMapWidget.getDisplayModeCycle() !== undefined) { - jsonOBJ.cycle = true; - } - } - - if (this.trackPairs.length > 0 || this.tracks2D.length > 0) { - let tracks = []; - jsonOBJ.tracks = tracks; - for (let trackRenderer of this.trackPairs) { - - const track = trackRenderer.x.track; - const config = track.config; - - if (typeof config.url === "string") { - - const t = {url: config.url}; - - if (config.type) { - t.type = config.type; - } - if (config.format) { - t.format = config.format; - } - if (track.name) { - t.name = track.name; - } - if (track.dataRange) { - t.min = track.dataRange.min; - t.max = track.dataRange.max; - } - if (track.color) { - t.color = track.color; - } - tracks.push(t); - } else if ('sequence' === config.type) { - tracks.push({type: 'sequence', format: 'sequence'}); - } - - } - for (const track2D of this.tracks2D) { - if (typeof track2D.config.url === "string") { - tracks.push(track2D.toJSON()); - } - } - } - - return jsonOBJ - } - - async minZoom(chr1, chr2) { - - const chromosome1 = this.dataset.chromosomes[chr1]; - const chromosome2 = this.dataset.chromosomes[chr2]; - - const { width, height } = this.contactMatrixView.getViewDimensions(); - const binSize = Math.max(chromosome1.size / width, chromosome2.size / height); - - const matrix = await this.dataset.getMatrix(chr1, chr2); - if (!matrix) { - throw new Error(`Data not avaiable for chromosomes ${chromosome1.name} - ${chromosome2.name}`) - } - return matrix.findZoomForResolution(binSize) - } - - async minPixelSize(chr1, chr2, zoomIndex) { - - // bp - const chr1Length = this.dataset.chromosomes[chr1].size; - const chr2Length = this.dataset.chromosomes[chr2].size; - - const matrix = await this.dataset.getMatrix(chr1, chr2); - const { zoom } = matrix.getZoomDataByIndex(zoomIndex, "BP"); - - // bin = bp * bin/bp = bin - const nBins1 = chr1Length / zoom.binSize; - const nBins2 = chr2Length / zoom.binSize; - - const { width, height } = this.contactMatrixView.getViewDimensions(); - - // pixel/bin - return Math.min(width / nBins1, height / nBins2) - - } - } - - /* - * @author Jim Robinson Dec-2020 - */ - - let allBrowsers = []; - let currentBrowser; - - async function createBrowser(hicContainer, config, callback) { - setDefaults(config); - - if (isString$3(config.colorScale)) config.colorScale = ColorScale.parse(config.colorScale); - if (isString$3(config.backgroundColor)) config.backgroundColor = ContactMatrixView.parseBackgroundColor(config.backgroundColor); - - const browser = new HICBrowser(hicContainer, config); - await browser.init(config); - - if (typeof callback === "function") callback(); - - allBrowsers.push(browser); - setCurrentBrowser(browser); - - if (allBrowsers.length > 1) { - allBrowsers.forEach(b => b.browserPanelDeleteButton.style.display = 'block'); - } - - return browser; - } - - async function createBrowserList(hicContainer, session) { - const configList = session.browsers || [session]; - allBrowsers = []; - const initPromises = []; - - for (const config of configList) { - - setDefaults(config); - - if (isString$3(config.colorScale)) { - config.colorScale = ColorScale.parse(config.colorScale); - } - if (isString$3(config.backgroundColor)) { - config.backgroundColor = ContactMatrixView.parseBackgroundColor(config.backgroundColor); - } - if (session.syncDatasets === false) { - config.synchable = false; - } - - const browser = new HICBrowser(hicContainer, config); - allBrowsers.push(browser); - initPromises.push(browser.init(config)); - } - await Promise.all(initPromises); - setCurrentBrowser(allBrowsers[0]); - - if (allBrowsers.length > 1) { - allBrowsers.forEach(b => b.browserPanelDeleteButton.style.display = 'block'); - } - } - - function deleteAllBrowsers() { - for (let b of allBrowsers) { - b.rootElement.remove(); - } - allBrowsers = []; - } - - function setCurrentBrowser(browser) { - if (browser === undefined) { - currentBrowser?.rootElement.classList.remove('hic-root-selected'); - currentBrowser = browser; - return; - } - - if (browser !== currentBrowser) { - currentBrowser?.rootElement.classList.remove('hic-root-selected'); - browser.rootElement.classList.add('hic-root-selected'); - currentBrowser = browser; - EventBus.globalBus.post(HICEvent("BrowserSelect", browser)); - } - } - - function deleteBrowser(browser) { - browser.unsyncSelf(); - browser.rootElement.remove(); - allBrowsers = allBrowsers.filter(b => b !== browser); - if (allBrowsers.length <= 1) { - allBrowsers.forEach(b => b.browserPanelDeleteButton.style.display = 'none'); - } - } - - function getCurrentBrowser() { - return currentBrowser; - } - - function syncBrowsers(browsers) { - const synchableBrowsers = (browsers || allBrowsers).filter(b => b.synchable !== false && b.dataset !== undefined); - - synchableBrowsers.forEach(b1 => { - synchableBrowsers.forEach(b2 => { - if (b1 !== b2 && b1.dataset.isCompatible(b2.dataset)) { - b1.synchedBrowsers.add(b2); - b2.synchedBrowsers.add(b1); - } - }); - }); - } - - function getAllBrowsers() { - return allBrowsers; - } - - function setDefaults(config) { - - if (config.figureMode === true) { - config.showLocusGoto = false; - config.showHicContactMapLabel = false; - config.showChromosomeSelector = false; - } else { - - - config.showLocusGoto = config.showLocusGoto ?? true; - config.showHicContactMapLabel = config.showHicContactMapLabel ?? true; - config.showChromosomeSelector = config.showChromosomeSelector ?? true; - } - } - - const version = "2.5.2"; - //, commit} - - function toJSON() { - const jsonOBJ = {}; - const browserJson = []; - const allBrowsers = getAllBrowsers(); - for (let browser of allBrowsers) { - browserJson.push(browser.toJSON()); - } - jsonOBJ.browsers = browserJson; - - if (Globals.selectedGene) { - jsonOBJ["selectedGene"] = Globals.selectedGene; - } - - const captionDiv = document.getElementById('hic-caption'); - if (captionDiv) { - var captionText = captionDiv.textContent; - if (captionText) { - captionText = captionText.trim(); - if (captionText) { - jsonOBJ.caption = captionText; - } - } - } - - return jsonOBJ; - } - - function compressedSession() { - const jsonString = JSON.stringify(toJSON()); - return `session=blob:${compressString$1(jsonString)}` - } - - - async function restoreSession(container, session) { - - deleteAllBrowsers(); - - if (session.hasOwnProperty("selectedGene")) { - Globals.selectedGene = session.selectedGene; - } - if (session.hasOwnProperty("caption")) { - const captionText = session.caption; - var captionDiv = document.getElementById("hic-caption"); - if (captionDiv) { - captionDiv.textContent = captionText; - } - } - - await createBrowserList(container, session); - - if (false !== session.syncDatasets) { - syncBrowsers(); - } - - } - - /* - * The MIT License (MIT) - * - * Copyright (c) 2016-2017 The Regents of the University of California - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and - * associated documentation files (the "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the - * following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING - * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - */ - - const DEFAULT_ANNOTATION_COLOR = "rgb(22, 129, 198)"; - - const urlShortcuts = { - "*s3e/": "https://hicfiles.s3.amazonaws.com/external/", - "*s3/": "https://hicfiles.s3.amazonaws.com/", - "*s3e_/": "http://hicfiles.s3.amazonaws.com/external/", - "*s3_/": "http://hicfiles.s3.amazonaws.com/", - "*enc/": "https://www.encodeproject.org/files/" - }; - - async function extractConfig(queryString) { - - let query = extractQuery(queryString); - let sessionConfig; - - if (query.hasOwnProperty("session")) { - if (query.session.startsWith("blob:") || query.session.startsWith("data:")) { - sessionConfig = JSON.parse(uncompressString$1(query.session.substr(5))); - } - } - - if (query.hasOwnProperty("juiceboxURL")) { - const jbURL = await expandURL(query["juiceboxURL"]); // Legacy bitly urls - query = extractQuery(jbURL); - } - - if (query.hasOwnProperty("juicebox") || query.hasOwnProperty("juiceboxData")) { - let q; - if (query.hasOwnProperty("juiceboxData")) { - q = uncompressString$1(query["juiceboxData"]); - } else { - q = query["juicebox"]; - if (q.startsWith("%7B")) { - q = decodeURIComponent(q); - } - } - - q = q.substr(1, q.length - 2); // Strip leading and trailing bracket - const parts = q.split("},{"); - const browsers = []; - for (let p of parts) { - const qObj = extractQuery(decodeURIComponent(p)); - browsers.push(decodeQuery(qObj)); - } - sessionConfig = {browsers}; - } - - // Try query parameter style - const uriDecode = true; - const queryConfig = decodeQuery(query, uriDecode); - if (queryConfig.url) { - sessionConfig = queryConfig; - } - - // Fix certain defaults - if (sessionConfig) { - if (sessionConfig.browsers) { - for (let b of sessionConfig.browsers) { - fixDefaults(b); - } - } else { - fixDefaults(sessionConfig); - } - } - - return sessionConfig; - - } - - function fixDefaults(browserConfig) { - if (browserConfig.tracks) { - for (let t of browserConfig.tracks) { - if (t.color === DEFAULT_ANNOTATION_COLOR) { - delete t.color; - } - if (t.min !== undefined && Number.isNaN(t.min)) { - delete t.min; - } - if (t.max !== undefined && Number.isNaN(t.max)) { - delete t.max; - } - t.displayMode = "COLLAPSED"; - } - } - } - - - /** - * Extend config properties with query parameters - * - * @param query - * @param config - */ - function decodeQuery(query, uriDecode) { - - const config = {}; - - let hicUrl = query["hicUrl"]; - const name = query["name"]; - let stateString = query["state"]; - let colorScale = query["colorScale"]; - let trackString = query["tracks"]; - const selectedGene = query["selectedGene"]; - const nvi = query["nvi"]; - - let controlUrl = query["controlUrl"]; - const controlName = query["controlName"]; - const displayMode = query["displayMode"]; - const controlNvi = query["controlNvi"]; - const cycle = query["cycle"]; - - if (hicUrl) { - hicUrl = paramDecode(hicUrl, uriDecode); - Object.keys(urlShortcuts).forEach(function (key) { - var value = urlShortcuts[key]; - if (hicUrl.startsWith(key)) hicUrl = hicUrl.replace(key, value); - }); - config.url = hicUrl; - - } - if (name) { - config.name = paramDecode(name, uriDecode); - } - if (controlUrl) { - controlUrl = paramDecode(controlUrl, uriDecode); - Object.keys(urlShortcuts).forEach(function (key) { - var value = urlShortcuts[key]; - if (controlUrl.startsWith(key)) controlUrl = controlUrl.replace(key, value); - }); - config.controlUrl = controlUrl; - } - if (controlName) { - config.controlName = paramDecode(controlName, uriDecode); - } - - if (stateString) { - stateString = paramDecode(stateString, uriDecode); - config.state = State.parse(stateString); - } - if (colorScale) { - colorScale = paramDecode(colorScale, uriDecode); - config.colorScale = ColorScale.parse(colorScale); - } - - if (displayMode) { - config.displayMode = paramDecode(displayMode, uriDecode); - } - - if (trackString) { - trackString = paramDecode(trackString, uriDecode); - config.tracks = destringifyTracksV0(trackString); - - // If an oAuth token is provided append it to track configs. - if (config.tracks && config.oauthToken) { - config.tracks.forEach(function (t) { - t.oauthToken = config.oauthToken; - }); - } - } - - if (selectedGene) { - Globals.selectedGene = selectedGene; - } - - config.cycle = cycle; - - if (nvi) { - config.nvi = paramDecode(nvi, uriDecode); - } - if (controlNvi) { - config.controlNvi = paramDecode(controlNvi, uriDecode); - } - - return config; - - function destringifyTracksV0(tracks) { - - const trackStringList = tracks.split("|||"); - const configList = []; - for (let trackString of trackStringList) { - - const tokens = trackString.split("|"); - const color = tokens.pop(); - let url = tokens.length > 1 ? tokens[0] : trackString; - if (url && url.trim().length > 0 && "undefined" !== url) { - const keys = Object.keys(urlShortcuts); - for (let key of keys) { - var value = urlShortcuts[key]; - if (url.startsWith(key)) { - url = url.replace(key, value); - break; - } - } - const trackConfig = {url: url}; - - if (tokens.length > 1) { - trackConfig.name = replaceAll(tokens[1], "$", "|"); - } - - if (tokens.length > 2) { - const dataRangeString = tokens[2]; - if (dataRangeString.startsWith("-")) { - const r = dataRangeString.substring(1).split("-"); - trackConfig.min = -parseFloat(r[0]); - trackConfig.max = parseFloat(r[1]); - } else { - const r = dataRangeString.split("-"); - trackConfig.min = parseFloat(r[0]); - trackConfig.max = parseFloat(r[1]); - } - } - - if (color) { - trackConfig.color = color; - } - - configList.push(trackConfig); - } - } - return configList; - } - - } - - - function paramDecode(str, uriDecode) { - - if (uriDecode) { - return decodeURIComponent(str); // Still more backward compatibility - } else { - var s = replaceAll(str, '%26', '&'); - s = replaceAll(s, '%20', ' '); - s = replaceAll(s, '+', ' '); - s = replaceAll(s, "%7C", "|"); - s = replaceAll(s, "%23", "#"); - s = replaceAll(s, "%3F", "?"); - s = replaceAll(s, "%3D", "="); - return s; - } - } - - - function replaceAll(str, target, replacement) { - return str.split(target).join(replacement); - } - - function extractQuery(uri) { - var i1, i2, i, j, s, query, tokens; - - query = {}; - i1 = uri.indexOf("?"); - i2 = uri.lastIndexOf("#"); - const i3 = uri.indexOf("="); - if (i1 > i3) i1 = -1; - - if (i2 < 0) i2 = uri.length; - for (i = i1 + 1; i < i2;) { - - j = uri.indexOf("&", i); - if (j < 0) j = i2; - - s = uri.substring(i, j); - tokens = s.split("=", 2); - if (tokens.length === 2) { - query[tokens[0]] = tokens[1]; - } - - i = j + 1; - - } - return query; - } - - /** - * Expand legacy bitly URLs - * @param url - * @returns {Promise<*>} - */ - async function expandURL(url) { - - const endpoint = `https://api-ssl.bitly.com/v4/expand`; - const id = url.startsWith("http://") ? url.substring(7) : url.substring(8); - const message = { - "bitlink_id": id - }; - - const response = await fetch(endpoint, { - method: 'POST', // or 'PUT' - headers: { - 'Content-Type': 'application/json', - 'Authorization': `Bearer ${btoa("ëtá¾´ãÎtsßéÆºÙçµóf¸í¿9snéÝz")}` - }, - body: JSON.stringify(message), - }); - - if (!response.ok) { - throw new Error(`Network error (${response.status}): ${response.statusText}`) - } - const json = await response.json(); - let longUrl = json.long_url; - - // Fix some Bitly "normalization" - longUrl = longUrl.replace("{", "%7B").replace("}", "%7D"); - return longUrl; - - } - - /* - * The MIT License (MIT) - * - * Copyright (c) 2016-2017 The Regents of the University of California - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and - * associated documentation files (the "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the - * following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING - * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - */ - - async function init$1(container, config) { - - Alert$1.init(container); - - if (false !== config.queryParametersSupported) { - const queryConfig = await extractConfig(window.location.href); - if(queryConfig) { - config= queryConfig; - } - } - - await restoreSession(container, config); - - const allBrowsers = getAllBrowsers(); - - return allBrowsers.length === 1 ? allBrowsers[0] : allBrowsers - } - - /* - * The MIT License (MIT) - * - * Copyright (c) 2016-2017 The Regents of the University of California - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and - * associated documentation files (the "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the - * following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING - * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - */ - - var index = { - version, - init: init$1, - toJSON, - restoreSession, - compressedSession, - createBrowser, - getCurrentBrowser, - setCurrentBrowser, - getAllBrowsers, - igvxhr: igvxhr$1, - EventBus - }; - - return index; - -})); diff --git a/dist/juicebox.min.js b/dist/juicebox.min.js deleted file mode 100644 index b7de48e7..00000000 --- a/dist/juicebox.min.js +++ /dev/null @@ -1,51 +0,0 @@ -!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).juicebox=t()}(this,(function(){"use strict";function e(e){return"string"==typeof e||e instanceof String}function t(e){var t=String(e).split(/[.,]/);return t[0].split("").reverse().reduce((function(e,t,i){return i%3==0?e+","+t:e+t})).split("").reverse().join("")+(t[1]?"."+t[1]:"")}const i=function(e){return e.split(/\n|\r\n|\r/g)};function n(t){if(void 0!==t.name)return t.name;if(e(t)){let e=t.lastIndexOf("/"),i=e<0?t:t.substr(e+1);return e=i.indexOf("?"),e>0&&(i=i.substr(0,e)),i}throw Error("Expected File or string, got "+typeof t)}function o(e){return!!e&&("function"!=typeof e&&(e instanceof File||e.hasOwnProperty("name")&&"function"==typeof e.slice&&"function"==typeof e.arrayBuffer))}"object"==typeof process&&"undefined"==typeof window&&(global.atob=function(e){return Buffer.from(e,"base64").toString("binary")});const r={strictMode:!1,key:["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"],q:{name:"queryKey",parser:/(?:^|&)([^&=]*)=?([^&]*)/g},parser:{strict:/^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/,loose:/^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/}}; -/*! pako 2.1.0 https://github.com/nodeca/pako @license (MIT AND Zlib) */function a(e){let t=e.length;for(;--t>=0;)e[t]=0}const s=256,c=286,l=30,h=15,d=new Uint8Array([0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0]),f=new Uint8Array([0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13]),u=new Uint8Array([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7]),p=new Uint8Array([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]),m=new Array(576);a(m);const g=new Array(60);a(g);const w=new Array(512);a(w);const F=new Array(256);a(F);const b=new Array(29);a(b);const v=new Array(l);function y(e,t,i,n,o){this.static_tree=e,this.extra_bits=t,this.extra_base=i,this.elems=n,this.max_length=o,this.has_stree=e&&e.length}let _,C,x;function k(e,t){this.dyn_tree=e,this.max_code=0,this.stat_desc=t}a(v);const E=e=>e<256?w[e]:w[256+(e>>>7)],N=(e,t)=>{e.pending_buf[e.pending++]=255&t,e.pending_buf[e.pending++]=t>>>8&255},S=(e,t,i)=>{e.bi_valid>16-i?(e.bi_buf|=t<>16-e.bi_valid,e.bi_valid+=i-16):(e.bi_buf|=t<{S(e,i[2*t],i[2*t+1])},z=(e,t)=>{let i=0;do{i|=1&e,e>>>=1,i<<=1}while(--t>0);return i>>>1},D=(e,t,i)=>{const n=new Array(16);let o,r,a=0;for(o=1;o<=h;o++)a=a+i[o-1]<<1,n[o]=a;for(r=0;r<=t;r++){let t=e[2*r+1];0!==t&&(e[2*r]=z(n[t]++,t))}},A=e=>{let t;for(t=0;t{e.bi_valid>8?N(e,e.bi_buf):e.bi_valid>0&&(e.pending_buf[e.pending++]=e.bi_buf),e.bi_buf=0,e.bi_valid=0},T=(e,t,i,n)=>{const o=2*t,r=2*i;return e[o]{const n=e.heap[i];let o=i<<1;for(;o<=e.heap_len&&(o{let n,o,r,a,c=0;if(0!==e.sym_next)do{n=255&e.pending_buf[e.sym_buf+c++],n+=(255&e.pending_buf[e.sym_buf+c++])<<8,o=e.pending_buf[e.sym_buf+c++],0===n?I(e,o,t):(r=F[o],I(e,r+s+1,t),a=d[r],0!==a&&(o-=b[r],S(e,o,a)),n--,r=E(n),I(e,r,i),a=f[r],0!==a&&(n-=v[r],S(e,n,a)))}while(c{const i=t.dyn_tree,n=t.stat_desc.static_tree,o=t.stat_desc.has_stree,r=t.stat_desc.elems;let a,s,c,l=-1;for(e.heap_len=0,e.heap_max=573,a=0;a>1;a>=1;a--)R(e,i,a);c=r;do{a=e.heap[1],e.heap[1]=e.heap[e.heap_len--],R(e,i,1),s=e.heap[1],e.heap[--e.heap_max]=a,e.heap[--e.heap_max]=s,i[2*c]=i[2*a]+i[2*s],e.depth[c]=(e.depth[a]>=e.depth[s]?e.depth[a]:e.depth[s])+1,i[2*a+1]=i[2*s+1]=c,e.heap[1]=c++,R(e,i,1)}while(e.heap_len>=2);e.heap[--e.heap_max]=e.heap[1],((e,t)=>{const i=t.dyn_tree,n=t.max_code,o=t.stat_desc.static_tree,r=t.stat_desc.has_stree,a=t.stat_desc.extra_bits,s=t.stat_desc.extra_base,c=t.stat_desc.max_length;let l,d,f,u,p,m,g=0;for(u=0;u<=h;u++)e.bl_count[u]=0;for(i[2*e.heap[e.heap_max]+1]=0,l=e.heap_max+1;l<573;l++)d=e.heap[l],u=i[2*i[2*d+1]+1]+1,u>c&&(u=c,g++),i[2*d+1]=u,d>n||(e.bl_count[u]++,p=0,d>=s&&(p=a[d-s]),m=i[2*d],e.opt_len+=m*(u+p),r&&(e.static_len+=m*(o[2*d+1]+p)));if(0!==g){do{for(u=c-1;0===e.bl_count[u];)u--;e.bl_count[u]--,e.bl_count[u+1]+=2,e.bl_count[c]--,g-=2}while(g>0);for(u=c;0!==u;u--)for(d=e.bl_count[u];0!==d;)f=e.heap[--l],f>n||(i[2*f+1]!==u&&(e.opt_len+=(u-i[2*f+1])*i[2*f],i[2*f+1]=u),d--)}})(e,t),D(i,l,e.bl_count)},H=(e,t,i)=>{let n,o,r=-1,a=t[1],s=0,c=7,l=4;for(0===a&&(c=138,l=3),t[2*(i+1)+1]=65535,n=0;n<=i;n++)o=a,a=t[2*(n+1)+1],++s{let n,o,r=-1,a=t[1],s=0,c=7,l=4;for(0===a&&(c=138,l=3),n=0;n<=i;n++)if(o=a,a=t[2*(n+1)+1],!(++s{S(e,0+(n?1:0),3),M(e),N(e,i),N(e,~i),i&&e.pending_buf.set(e.window.subarray(t,t+i),e.pending),e.pending+=i};var V=(e,t,i,n)=>{let o,r,a=0;e.level>0?(2===e.strm.data_type&&(e.strm.data_type=(e=>{let t,i=4093624447;for(t=0;t<=31;t++,i>>>=1)if(1&i&&0!==e.dyn_ltree[2*t])return 0;if(0!==e.dyn_ltree[18]||0!==e.dyn_ltree[20]||0!==e.dyn_ltree[26])return 1;for(t=32;t{let t;for(H(e,e.dyn_ltree,e.l_desc.max_code),H(e,e.dyn_dtree,e.d_desc.max_code),B(e,e.bl_desc),t=18;t>=3&&0===e.bl_tree[2*p[t]+1];t--);return e.opt_len+=3*(t+1)+5+5+4,t})(e),o=e.opt_len+3+7>>>3,r=e.static_len+3+7>>>3,r<=o&&(o=r)):o=r=i+5,i+4<=o&&-1!==t?q(e,t,i,n):4===e.strategy||r===o?(S(e,2+(n?1:0),3),L(e,m,g)):(S(e,4+(n?1:0),3),((e,t,i,n)=>{let o;for(S(e,t-257,5),S(e,i-1,5),S(e,n-4,4),o=0;o{P||((()=>{let e,t,i,n,o;const r=new Array(16);for(i=0,n=0;n<28;n++)for(b[n]=i,e=0;e<1<>=7;n(e.pending_buf[e.sym_buf+e.sym_next++]=t,e.pending_buf[e.sym_buf+e.sym_next++]=t>>8,e.pending_buf[e.sym_buf+e.sym_next++]=i,0===t?e.dyn_ltree[2*i]++:(e.matches++,t--,e.dyn_ltree[2*(F[i]+s+1)]++,e.dyn_dtree[2*E(t)]++),e.sym_next===e.sym_end),_tr_align:e=>{S(e,2,3),I(e,256,m),(e=>{16===e.bi_valid?(N(e,e.bi_buf),e.bi_buf=0,e.bi_valid=0):e.bi_valid>=8&&(e.pending_buf[e.pending++]=255&e.bi_buf,e.bi_buf>>=8,e.bi_valid-=8)})(e)}};var j=(e,t,i,n)=>{let o=65535&e,r=e>>>16&65535,a=0;for(;0!==i;){a=i>2e3?2e3:i,i-=a;do{o=o+t[n++]|0,r=r+o|0}while(--a);o%=65521,r%=65521}return o|r<<16};const W=new Uint32Array((()=>{let e,t=[];for(var i=0;i<256;i++){e=i;for(var n=0;n<8;n++)e=1&e?3988292384^e>>>1:e>>>1;t[i]=e}return t})());var G=(e,t,i,n)=>{const o=W,r=n+i;e^=-1;for(let i=n;i>>8^o[255&(e^t[i])];return~e},$={2:"need dictionary",1:"stream end",0:"","-1":"file error","-2":"stream error","-3":"data error","-4":"insufficient memory","-5":"buffer error","-6":"incompatible version"},Z={Z_NO_FLUSH:0,Z_PARTIAL_FLUSH:1,Z_SYNC_FLUSH:2,Z_FULL_FLUSH:3,Z_FINISH:4,Z_BLOCK:5,Z_TREES:6,Z_OK:0,Z_STREAM_END:1,Z_NEED_DICT:2,Z_ERRNO:-1,Z_STREAM_ERROR:-2,Z_DATA_ERROR:-3,Z_MEM_ERROR:-4,Z_BUF_ERROR:-5,Z_NO_COMPRESSION:0,Z_BEST_SPEED:1,Z_BEST_COMPRESSION:9,Z_DEFAULT_COMPRESSION:-1,Z_FILTERED:1,Z_HUFFMAN_ONLY:2,Z_RLE:3,Z_FIXED:4,Z_DEFAULT_STRATEGY:0,Z_BINARY:0,Z_TEXT:1,Z_UNKNOWN:2,Z_DEFLATED:8};const{_tr_init:K,_tr_stored_block:X,_tr_flush_block:Y,_tr_tally:Q,_tr_align:J}=U,{Z_NO_FLUSH:ee,Z_PARTIAL_FLUSH:te,Z_FULL_FLUSH:ie,Z_FINISH:ne,Z_BLOCK:oe,Z_OK:re,Z_STREAM_END:ae,Z_STREAM_ERROR:se,Z_DATA_ERROR:ce,Z_BUF_ERROR:le,Z_DEFAULT_COMPRESSION:he,Z_FILTERED:de,Z_HUFFMAN_ONLY:fe,Z_RLE:ue,Z_FIXED:pe,Z_DEFAULT_STRATEGY:me,Z_UNKNOWN:ge,Z_DEFLATED:we}=Z,Fe=258,be=262,ve=42,ye=113,_e=666,Ce=(e,t)=>(e.msg=$[t],t),xe=e=>2*e-(e>4?9:0),ke=e=>{let t=e.length;for(;--t>=0;)e[t]=0},Ee=e=>{let t,i,n,o=e.w_size;t=e.hash_size,n=t;do{i=e.head[--n],e.head[n]=i>=o?i-o:0}while(--t);t=o,n=t;do{i=e.prev[--n],e.prev[n]=i>=o?i-o:0}while(--t)};let Ne=(e,t,i)=>(t<{const t=e.state;let i=t.pending;i>e.avail_out&&(i=e.avail_out),0!==i&&(e.output.set(t.pending_buf.subarray(t.pending_out,t.pending_out+i),e.next_out),e.next_out+=i,t.pending_out+=i,e.total_out+=i,e.avail_out-=i,t.pending-=i,0===t.pending&&(t.pending_out=0))},Ie=(e,t)=>{Y(e,e.block_start>=0?e.block_start:-1,e.strstart-e.block_start,t),e.block_start=e.strstart,Se(e.strm)},ze=(e,t)=>{e.pending_buf[e.pending++]=t},De=(e,t)=>{e.pending_buf[e.pending++]=t>>>8&255,e.pending_buf[e.pending++]=255&t},Ae=(e,t,i,n)=>{let o=e.avail_in;return o>n&&(o=n),0===o?0:(e.avail_in-=o,t.set(e.input.subarray(e.next_in,e.next_in+o),i),1===e.state.wrap?e.adler=j(e.adler,t,o,i):2===e.state.wrap&&(e.adler=G(e.adler,t,o,i)),e.next_in+=o,e.total_in+=o,o)},Me=(e,t)=>{let i,n,o=e.max_chain_length,r=e.strstart,a=e.prev_length,s=e.nice_match;const c=e.strstart>e.w_size-be?e.strstart-(e.w_size-be):0,l=e.window,h=e.w_mask,d=e.prev,f=e.strstart+Fe;let u=l[r+a-1],p=l[r+a];e.prev_length>=e.good_match&&(o>>=2),s>e.lookahead&&(s=e.lookahead);do{if(i=t,l[i+a]===p&&l[i+a-1]===u&&l[i]===l[r]&&l[++i]===l[r+1]){r+=2,i++;do{}while(l[++r]===l[++i]&&l[++r]===l[++i]&&l[++r]===l[++i]&&l[++r]===l[++i]&&l[++r]===l[++i]&&l[++r]===l[++i]&&l[++r]===l[++i]&&l[++r]===l[++i]&&ra){if(e.match_start=t,a=n,n>=s)break;u=l[r+a-1],p=l[r+a]}}}while((t=d[t&h])>c&&0!=--o);return a<=e.lookahead?a:e.lookahead},Te=e=>{const t=e.w_size;let i,n,o;do{if(n=e.window_size-e.lookahead-e.strstart,e.strstart>=t+(t-be)&&(e.window.set(e.window.subarray(t,t+t-n),0),e.match_start-=t,e.strstart-=t,e.block_start-=t,e.insert>e.strstart&&(e.insert=e.strstart),Ee(e),n+=t),0===e.strm.avail_in)break;if(i=Ae(e.strm,e.window,e.strstart+e.lookahead,n),e.lookahead+=i,e.lookahead+e.insert>=3)for(o=e.strstart-e.insert,e.ins_h=e.window[o],e.ins_h=Ne(e,e.ins_h,e.window[o+1]);e.insert&&(e.ins_h=Ne(e,e.ins_h,e.window[o+3-1]),e.prev[o&e.w_mask]=e.head[e.ins_h],e.head[e.ins_h]=o,o++,e.insert--,!(e.lookahead+e.insert<3)););}while(e.lookahead{let i,n,o,r=e.pending_buf_size-5>e.w_size?e.w_size:e.pending_buf_size-5,a=0,s=e.strm.avail_in;do{if(i=65535,o=e.bi_valid+42>>3,e.strm.avail_outn+e.strm.avail_in&&(i=n+e.strm.avail_in),i>o&&(i=o),i>8,e.pending_buf[e.pending-2]=~i,e.pending_buf[e.pending-1]=~i>>8,Se(e.strm),n&&(n>i&&(n=i),e.strm.output.set(e.window.subarray(e.block_start,e.block_start+n),e.strm.next_out),e.strm.next_out+=n,e.strm.avail_out-=n,e.strm.total_out+=n,e.block_start+=n,i-=n),i&&(Ae(e.strm,e.strm.output,e.strm.next_out,i),e.strm.next_out+=i,e.strm.avail_out-=i,e.strm.total_out+=i)}while(0===a);return s-=e.strm.avail_in,s&&(s>=e.w_size?(e.matches=2,e.window.set(e.strm.input.subarray(e.strm.next_in-e.w_size,e.strm.next_in),0),e.strstart=e.w_size,e.insert=e.strstart):(e.window_size-e.strstart<=s&&(e.strstart-=e.w_size,e.window.set(e.window.subarray(e.w_size,e.w_size+e.strstart),0),e.matches<2&&e.matches++,e.insert>e.strstart&&(e.insert=e.strstart)),e.window.set(e.strm.input.subarray(e.strm.next_in-s,e.strm.next_in),e.strstart),e.strstart+=s,e.insert+=s>e.w_size-e.insert?e.w_size-e.insert:s),e.block_start=e.strstart),e.high_watero&&e.block_start>=e.w_size&&(e.block_start-=e.w_size,e.strstart-=e.w_size,e.window.set(e.window.subarray(e.w_size,e.w_size+e.strstart),0),e.matches<2&&e.matches++,o+=e.w_size,e.insert>e.strstart&&(e.insert=e.strstart)),o>e.strm.avail_in&&(o=e.strm.avail_in),o&&(Ae(e.strm,e.window,e.strstart,o),e.strstart+=o,e.insert+=o>e.w_size-e.insert?e.w_size-e.insert:o),e.high_water>3,o=e.pending_buf_size-o>65535?65535:e.pending_buf_size-o,r=o>e.w_size?e.w_size:o,n=e.strstart-e.block_start,(n>=r||(n||t===ne)&&t!==ee&&0===e.strm.avail_in&&n<=o)&&(i=n>o?o:n,a=t===ne&&0===e.strm.avail_in&&i===n?1:0,X(e,e.block_start,i,a),e.block_start+=i,Se(e.strm)),a?3:1)},Le=(e,t)=>{let i,n;for(;;){if(e.lookahead=3&&(e.ins_h=Ne(e,e.ins_h,e.window[e.strstart+3-1]),i=e.prev[e.strstart&e.w_mask]=e.head[e.ins_h],e.head[e.ins_h]=e.strstart),0!==i&&e.strstart-i<=e.w_size-be&&(e.match_length=Me(e,i)),e.match_length>=3)if(n=Q(e,e.strstart-e.match_start,e.match_length-3),e.lookahead-=e.match_length,e.match_length<=e.max_lazy_match&&e.lookahead>=3){e.match_length--;do{e.strstart++,e.ins_h=Ne(e,e.ins_h,e.window[e.strstart+3-1]),i=e.prev[e.strstart&e.w_mask]=e.head[e.ins_h],e.head[e.ins_h]=e.strstart}while(0!=--e.match_length);e.strstart++}else e.strstart+=e.match_length,e.match_length=0,e.ins_h=e.window[e.strstart],e.ins_h=Ne(e,e.ins_h,e.window[e.strstart+1]);else n=Q(e,0,e.window[e.strstart]),e.lookahead--,e.strstart++;if(n&&(Ie(e,!1),0===e.strm.avail_out))return 1}return e.insert=e.strstart<2?e.strstart:2,t===ne?(Ie(e,!0),0===e.strm.avail_out?3:4):e.sym_next&&(Ie(e,!1),0===e.strm.avail_out)?1:2},Be=(e,t)=>{let i,n,o;for(;;){if(e.lookahead=3&&(e.ins_h=Ne(e,e.ins_h,e.window[e.strstart+3-1]),i=e.prev[e.strstart&e.w_mask]=e.head[e.ins_h],e.head[e.ins_h]=e.strstart),e.prev_length=e.match_length,e.prev_match=e.match_start,e.match_length=2,0!==i&&e.prev_length4096)&&(e.match_length=2)),e.prev_length>=3&&e.match_length<=e.prev_length){o=e.strstart+e.lookahead-3,n=Q(e,e.strstart-1-e.prev_match,e.prev_length-3),e.lookahead-=e.prev_length-1,e.prev_length-=2;do{++e.strstart<=o&&(e.ins_h=Ne(e,e.ins_h,e.window[e.strstart+3-1]),i=e.prev[e.strstart&e.w_mask]=e.head[e.ins_h],e.head[e.ins_h]=e.strstart)}while(0!=--e.prev_length);if(e.match_available=0,e.match_length=2,e.strstart++,n&&(Ie(e,!1),0===e.strm.avail_out))return 1}else if(e.match_available){if(n=Q(e,0,e.window[e.strstart-1]),n&&Ie(e,!1),e.strstart++,e.lookahead--,0===e.strm.avail_out)return 1}else e.match_available=1,e.strstart++,e.lookahead--}return e.match_available&&(n=Q(e,0,e.window[e.strstart-1]),e.match_available=0),e.insert=e.strstart<2?e.strstart:2,t===ne?(Ie(e,!0),0===e.strm.avail_out?3:4):e.sym_next&&(Ie(e,!1),0===e.strm.avail_out)?1:2};function He(e,t,i,n,o){this.good_length=e,this.max_lazy=t,this.nice_length=i,this.max_chain=n,this.func=o}const Oe=[new He(0,0,0,0,Re),new He(4,4,8,4,Le),new He(4,5,16,8,Le),new He(4,6,32,32,Le),new He(4,4,16,16,Be),new He(8,16,32,32,Be),new He(8,16,128,128,Be),new He(8,32,128,256,Be),new He(32,128,258,1024,Be),new He(32,258,258,4096,Be)];function Pe(){this.strm=null,this.status=0,this.pending_buf=null,this.pending_buf_size=0,this.pending_out=0,this.pending=0,this.wrap=0,this.gzhead=null,this.gzindex=0,this.method=we,this.last_flush=-1,this.w_size=0,this.w_bits=0,this.w_mask=0,this.window=null,this.window_size=0,this.prev=null,this.head=null,this.ins_h=0,this.hash_size=0,this.hash_bits=0,this.hash_mask=0,this.hash_shift=0,this.block_start=0,this.match_length=0,this.prev_match=0,this.match_available=0,this.strstart=0,this.match_start=0,this.lookahead=0,this.prev_length=0,this.max_chain_length=0,this.max_lazy_match=0,this.level=0,this.strategy=0,this.good_match=0,this.nice_match=0,this.dyn_ltree=new Uint16Array(1146),this.dyn_dtree=new Uint16Array(122),this.bl_tree=new Uint16Array(78),ke(this.dyn_ltree),ke(this.dyn_dtree),ke(this.bl_tree),this.l_desc=null,this.d_desc=null,this.bl_desc=null,this.bl_count=new Uint16Array(16),this.heap=new Uint16Array(573),ke(this.heap),this.heap_len=0,this.heap_max=0,this.depth=new Uint16Array(573),ke(this.depth),this.sym_buf=0,this.lit_bufsize=0,this.sym_next=0,this.sym_end=0,this.opt_len=0,this.static_len=0,this.matches=0,this.insert=0,this.bi_buf=0,this.bi_valid=0}const qe=e=>{if(!e)return 1;const t=e.state;return!t||t.strm!==e||t.status!==ve&&57!==t.status&&69!==t.status&&73!==t.status&&91!==t.status&&103!==t.status&&t.status!==ye&&t.status!==_e?1:0},Ve=e=>{if(qe(e))return Ce(e,se);e.total_in=e.total_out=0,e.data_type=ge;const t=e.state;return t.pending=0,t.pending_out=0,t.wrap<0&&(t.wrap=-t.wrap),t.status=2===t.wrap?57:t.wrap?ve:ye,e.adler=2===t.wrap?0:1,t.last_flush=-2,K(t),re},Ue=e=>{const t=Ve(e);var i;return t===re&&((i=e.state).window_size=2*i.w_size,ke(i.head),i.max_lazy_match=Oe[i.level].max_lazy,i.good_match=Oe[i.level].good_length,i.nice_match=Oe[i.level].nice_length,i.max_chain_length=Oe[i.level].max_chain,i.strstart=0,i.block_start=0,i.lookahead=0,i.insert=0,i.match_length=i.prev_length=2,i.match_available=0,i.ins_h=0),t},je=(e,t,i,n,o,r)=>{if(!e)return se;let a=1;if(t===he&&(t=6),n<0?(a=0,n=-n):n>15&&(a=2,n-=16),o<1||o>9||i!==we||n<8||n>15||t<0||t>9||r<0||r>pe||8===n&&1!==a)return Ce(e,se);8===n&&(n=9);const s=new Pe;return e.state=s,s.strm=e,s.status=ve,s.wrap=a,s.gzhead=null,s.w_bits=n,s.w_size=1<{let i=t.length;if(qe(e))return se;const n=e.state,o=n.wrap;if(2===o||1===o&&n.status!==ve||n.lookahead)return se;if(1===o&&(e.adler=j(e.adler,t,i,0)),n.wrap=0,i>=n.w_size){0===o&&(ke(n.head),n.strstart=0,n.block_start=0,n.insert=0);let e=new Uint8Array(n.w_size);e.set(t.subarray(i-n.w_size,i),0),t=e,i=n.w_size}const r=e.avail_in,a=e.next_in,s=e.input;for(e.avail_in=i,e.next_in=0,e.input=t,Te(n);n.lookahead>=3;){let e=n.strstart,t=n.lookahead-2;do{n.ins_h=Ne(n,n.ins_h,n.window[e+3-1]),n.prev[e&n.w_mask]=n.head[n.ins_h],n.head[n.ins_h]=e,e++}while(--t);n.strstart=e,n.lookahead=2,Te(n)}return n.strstart+=n.lookahead,n.block_start=n.strstart,n.insert=n.lookahead,n.lookahead=0,n.match_length=n.prev_length=2,n.match_available=0,e.next_in=a,e.input=s,e.avail_in=r,n.wrap=o,re},Ge={deflateInit:(e,t)=>je(e,t,we,15,8,me),deflateInit2:je,deflateReset:Ue,deflateResetKeep:Ve,deflateSetHeader:(e,t)=>qe(e)||2!==e.state.wrap?se:(e.state.gzhead=t,re),deflate:(e,t)=>{if(qe(e)||t>oe||t<0)return e?Ce(e,se):se;const i=e.state;if(!e.output||0!==e.avail_in&&!e.input||i.status===_e&&t!==ne)return Ce(e,0===e.avail_out?le:se);const n=i.last_flush;if(i.last_flush=t,0!==i.pending){if(Se(e),0===e.avail_out)return i.last_flush=-1,re}else if(0===e.avail_in&&xe(t)<=xe(n)&&t!==ne)return Ce(e,le);if(i.status===_e&&0!==e.avail_in)return Ce(e,le);if(i.status===ve&&0===i.wrap&&(i.status=ye),i.status===ve){let t=we+(i.w_bits-8<<4)<<8,n=-1;if(n=i.strategy>=fe||i.level<2?0:i.level<6?1:6===i.level?2:3,t|=n<<6,0!==i.strstart&&(t|=32),t+=31-t%31,De(i,t),0!==i.strstart&&(De(i,e.adler>>>16),De(i,65535&e.adler)),e.adler=1,i.status=ye,Se(e),0!==i.pending)return i.last_flush=-1,re}if(57===i.status)if(e.adler=0,ze(i,31),ze(i,139),ze(i,8),i.gzhead)ze(i,(i.gzhead.text?1:0)+(i.gzhead.hcrc?2:0)+(i.gzhead.extra?4:0)+(i.gzhead.name?8:0)+(i.gzhead.comment?16:0)),ze(i,255&i.gzhead.time),ze(i,i.gzhead.time>>8&255),ze(i,i.gzhead.time>>16&255),ze(i,i.gzhead.time>>24&255),ze(i,9===i.level?2:i.strategy>=fe||i.level<2?4:0),ze(i,255&i.gzhead.os),i.gzhead.extra&&i.gzhead.extra.length&&(ze(i,255&i.gzhead.extra.length),ze(i,i.gzhead.extra.length>>8&255)),i.gzhead.hcrc&&(e.adler=G(e.adler,i.pending_buf,i.pending,0)),i.gzindex=0,i.status=69;else if(ze(i,0),ze(i,0),ze(i,0),ze(i,0),ze(i,0),ze(i,9===i.level?2:i.strategy>=fe||i.level<2?4:0),ze(i,3),i.status=ye,Se(e),0!==i.pending)return i.last_flush=-1,re;if(69===i.status){if(i.gzhead.extra){let t=i.pending,n=(65535&i.gzhead.extra.length)-i.gzindex;for(;i.pending+n>i.pending_buf_size;){let o=i.pending_buf_size-i.pending;if(i.pending_buf.set(i.gzhead.extra.subarray(i.gzindex,i.gzindex+o),i.pending),i.pending=i.pending_buf_size,i.gzhead.hcrc&&i.pending>t&&(e.adler=G(e.adler,i.pending_buf,i.pending-t,t)),i.gzindex+=o,Se(e),0!==i.pending)return i.last_flush=-1,re;t=0,n-=o}let o=new Uint8Array(i.gzhead.extra);i.pending_buf.set(o.subarray(i.gzindex,i.gzindex+n),i.pending),i.pending+=n,i.gzhead.hcrc&&i.pending>t&&(e.adler=G(e.adler,i.pending_buf,i.pending-t,t)),i.gzindex=0}i.status=73}if(73===i.status){if(i.gzhead.name){let t,n=i.pending;do{if(i.pending===i.pending_buf_size){if(i.gzhead.hcrc&&i.pending>n&&(e.adler=G(e.adler,i.pending_buf,i.pending-n,n)),Se(e),0!==i.pending)return i.last_flush=-1,re;n=0}t=i.gzindexn&&(e.adler=G(e.adler,i.pending_buf,i.pending-n,n)),i.gzindex=0}i.status=91}if(91===i.status){if(i.gzhead.comment){let t,n=i.pending;do{if(i.pending===i.pending_buf_size){if(i.gzhead.hcrc&&i.pending>n&&(e.adler=G(e.adler,i.pending_buf,i.pending-n,n)),Se(e),0!==i.pending)return i.last_flush=-1,re;n=0}t=i.gzindexn&&(e.adler=G(e.adler,i.pending_buf,i.pending-n,n))}i.status=103}if(103===i.status){if(i.gzhead.hcrc){if(i.pending+2>i.pending_buf_size&&(Se(e),0!==i.pending))return i.last_flush=-1,re;ze(i,255&e.adler),ze(i,e.adler>>8&255),e.adler=0}if(i.status=ye,Se(e),0!==i.pending)return i.last_flush=-1,re}if(0!==e.avail_in||0!==i.lookahead||t!==ee&&i.status!==_e){let n=0===i.level?Re(i,t):i.strategy===fe?((e,t)=>{let i;for(;;){if(0===e.lookahead&&(Te(e),0===e.lookahead)){if(t===ee)return 1;break}if(e.match_length=0,i=Q(e,0,e.window[e.strstart]),e.lookahead--,e.strstart++,i&&(Ie(e,!1),0===e.strm.avail_out))return 1}return e.insert=0,t===ne?(Ie(e,!0),0===e.strm.avail_out?3:4):e.sym_next&&(Ie(e,!1),0===e.strm.avail_out)?1:2})(i,t):i.strategy===ue?((e,t)=>{let i,n,o,r;const a=e.window;for(;;){if(e.lookahead<=Fe){if(Te(e),e.lookahead<=Fe&&t===ee)return 1;if(0===e.lookahead)break}if(e.match_length=0,e.lookahead>=3&&e.strstart>0&&(o=e.strstart-1,n=a[o],n===a[++o]&&n===a[++o]&&n===a[++o])){r=e.strstart+Fe;do{}while(n===a[++o]&&n===a[++o]&&n===a[++o]&&n===a[++o]&&n===a[++o]&&n===a[++o]&&n===a[++o]&&n===a[++o]&&oe.lookahead&&(e.match_length=e.lookahead)}if(e.match_length>=3?(i=Q(e,1,e.match_length-3),e.lookahead-=e.match_length,e.strstart+=e.match_length,e.match_length=0):(i=Q(e,0,e.window[e.strstart]),e.lookahead--,e.strstart++),i&&(Ie(e,!1),0===e.strm.avail_out))return 1}return e.insert=0,t===ne?(Ie(e,!0),0===e.strm.avail_out?3:4):e.sym_next&&(Ie(e,!1),0===e.strm.avail_out)?1:2})(i,t):Oe[i.level].func(i,t);if(3!==n&&4!==n||(i.status=_e),1===n||3===n)return 0===e.avail_out&&(i.last_flush=-1),re;if(2===n&&(t===te?J(i):t!==oe&&(X(i,0,0,!1),t===ie&&(ke(i.head),0===i.lookahead&&(i.strstart=0,i.block_start=0,i.insert=0))),Se(e),0===e.avail_out))return i.last_flush=-1,re}return t!==ne?re:i.wrap<=0?ae:(2===i.wrap?(ze(i,255&e.adler),ze(i,e.adler>>8&255),ze(i,e.adler>>16&255),ze(i,e.adler>>24&255),ze(i,255&e.total_in),ze(i,e.total_in>>8&255),ze(i,e.total_in>>16&255),ze(i,e.total_in>>24&255)):(De(i,e.adler>>>16),De(i,65535&e.adler)),Se(e),i.wrap>0&&(i.wrap=-i.wrap),0!==i.pending?re:ae)},deflateEnd:e=>{if(qe(e))return se;const t=e.state.status;return e.state=null,t===ye?Ce(e,ce):re},deflateSetDictionary:We,deflateInfo:"pako deflate (from Nodeca project)"};const $e=(e,t)=>Object.prototype.hasOwnProperty.call(e,t);var Ze=function(e){const t=Array.prototype.slice.call(arguments,1);for(;t.length;){const i=t.shift();if(i){if("object"!=typeof i)throw new TypeError(i+"must be non-object");for(const t in i)$e(i,t)&&(e[t]=i[t])}}return e},Ke=e=>{let t=0;for(let i=0,n=e.length;i=252?6:zk>=248?5:zk>=240?4:zk>=224?3:zk>=192?2:1;Ye[254]=Ye[254]=1;var Qe=e=>{if("function"==typeof TextEncoder&&TextEncoder.prototype.encode)return(new TextEncoder).encode(e);let t,i,n,o,r,a=e.length,s=0;for(o=0;o>>6,t[r++]=128|63&i):i<65536?(t[r++]=224|i>>>12,t[r++]=128|i>>>6&63,t[r++]=128|63&i):(t[r++]=240|i>>>18,t[r++]=128|i>>>12&63,t[r++]=128|i>>>6&63,t[r++]=128|63&i);return t},Je=(e,t)=>{const i=t||e.length;if("function"==typeof TextDecoder&&TextDecoder.prototype.decode)return(new TextDecoder).decode(e.subarray(0,t));let n,o;const r=new Array(2*i);for(o=0,n=0;n4)r[o++]=65533,n+=a-1;else{for(t&=2===a?31:3===a?15:7;a>1&&n1?r[o++]=65533:t<65536?r[o++]=t:(t-=65536,r[o++]=55296|t>>10&1023,r[o++]=56320|1023&t)}}return((e,t)=>{if(t<65534&&e.subarray&&Xe)return String.fromCharCode.apply(null,e.length===t?e:e.subarray(0,t));let i="";for(let n=0;n{(t=t||e.length)>e.length&&(t=e.length);let i=t-1;for(;i>=0&&128==(192&e[i]);)i--;return i<0||0===i?t:i+Ye[e[i]]>t?i:t};var tt=function(){this.input=null,this.next_in=0,this.avail_in=0,this.total_in=0,this.output=null,this.next_out=0,this.avail_out=0,this.total_out=0,this.msg="",this.state=null,this.data_type=2,this.adler=0};const it=Object.prototype.toString,{Z_NO_FLUSH:nt,Z_SYNC_FLUSH:ot,Z_FULL_FLUSH:rt,Z_FINISH:at,Z_OK:st,Z_STREAM_END:ct,Z_DEFAULT_COMPRESSION:lt,Z_DEFAULT_STRATEGY:ht,Z_DEFLATED:dt}=Z;function ft(e){this.options=Ze({level:lt,method:dt,chunkSize:16384,windowBits:15,memLevel:8,strategy:ht},e||{});let t=this.options;t.raw&&t.windowBits>0?t.windowBits=-t.windowBits:t.gzip&&t.windowBits>0&&t.windowBits<16&&(t.windowBits+=16),this.err=0,this.msg="",this.ended=!1,this.chunks=[],this.strm=new tt,this.strm.avail_out=0;let i=Ge.deflateInit2(this.strm,t.level,t.method,t.windowBits,t.memLevel,t.strategy);if(i!==st)throw new Error($[i]);if(t.header&&Ge.deflateSetHeader(this.strm,t.header),t.dictionary){let e;if(e="string"==typeof t.dictionary?Qe(t.dictionary):"[object ArrayBuffer]"===it.call(t.dictionary)?new Uint8Array(t.dictionary):t.dictionary,i=Ge.deflateSetDictionary(this.strm,e),i!==st)throw new Error($[i]);this._dict_set=!0}}function ut(e,t){const i=new ft(t);if(i.push(e,!0),i.err)throw i.msg||$[i.err];return i.result}ft.prototype.push=function(e,t){const i=this.strm,n=this.options.chunkSize;let o,r;if(this.ended)return!1;for(r=t===~~t?t:!0===t?at:nt,"string"==typeof e?i.input=Qe(e):"[object ArrayBuffer]"===it.call(e)?i.input=new Uint8Array(e):i.input=e,i.next_in=0,i.avail_in=i.input.length;;)if(0===i.avail_out&&(i.output=new Uint8Array(n),i.next_out=0,i.avail_out=n),(r===ot||r===rt)&&i.avail_out<=6)this.onData(i.output.subarray(0,i.next_out)),i.avail_out=0;else{if(o=Ge.deflate(i,r),o===ct)return i.next_out>0&&this.onData(i.output.subarray(0,i.next_out)),o=Ge.deflateEnd(this.strm),this.onEnd(o),this.ended=!0,o===st;if(0!==i.avail_out){if(r>0&&i.next_out>0)this.onData(i.output.subarray(0,i.next_out)),i.avail_out=0;else if(0===i.avail_in)break}else this.onData(i.output)}return!0},ft.prototype.onData=function(e){this.chunks.push(e)},ft.prototype.onEnd=function(e){e===st&&(this.result=Ke(this.chunks)),this.chunks=[],this.err=e,this.msg=this.strm.msg};var pt=function(e,t){return(t=t||{}).raw=!0,ut(e,t)},mt=function(e,t){return(t=t||{}).gzip=!0,ut(e,t)},gt={Deflate:ft,deflate:ut,deflateRaw:pt,gzip:mt,constants:Z};const wt=16209;var Ft=function(e,t){let i,n,o,r,a,s,c,l,h,d,f,u,p,m,g,w,F,b,v,y,_,C,x,k;const E=e.state;i=e.next_in,x=e.input,n=i+(e.avail_in-5),o=e.next_out,k=e.output,r=o-(t-e.avail_out),a=o+(e.avail_out-257),s=E.dmax,c=E.wsize,l=E.whave,h=E.wnext,d=E.window,f=E.hold,u=E.bits,p=E.lencode,m=E.distcode,g=(1<>>24,f>>>=b,u-=b,b=F>>>16&255,0===b)k[o++]=65535&F;else{if(!(16&b)){if(64&b){if(32&b){E.mode=16191;break e}e.msg="invalid literal/length code",E.mode=wt;break e}F=p[(65535&F)+(f&(1<>>=b,u-=b),u<15&&(f+=x[i++]<>>24,f>>>=b,u-=b,b=F>>>16&255,16&b){if(y=65535&F,b&=15,us){e.msg="invalid distance too far back",E.mode=wt;break e}if(f>>>=b,u-=b,b=o-r,y>b){if(b=y-b,b>l&&E.sane){e.msg="invalid distance too far back",E.mode=wt;break e}if(_=0,C=d,0===h){if(_+=c-b,b2;)k[o++]=C[_++],k[o++]=C[_++],k[o++]=C[_++],v-=3;v&&(k[o++]=C[_++],v>1&&(k[o++]=C[_++]))}else{_=o-y;do{k[o++]=k[_++],k[o++]=k[_++],k[o++]=k[_++],v-=3}while(v>2);v&&(k[o++]=k[_++],v>1&&(k[o++]=k[_++]))}break}if(64&b){e.msg="invalid distance code",E.mode=wt;break e}F=m[(65535&F)+(f&(1<>3,i-=v,u-=v<<3,f&=(1<{const c=s.bits;let l,h,d,f,u,p,m=0,g=0,w=0,F=0,b=0,v=0,y=0,_=0,C=0,x=0,k=null;const E=new Uint16Array(16),N=new Uint16Array(16);let S,I,z,D=null;for(m=0;m<=bt;m++)E[m]=0;for(g=0;g=1&&0===E[F];F--);if(b>F&&(b=F),0===F)return o[r++]=20971520,o[r++]=20971520,s.bits=1,0;for(w=1;w0&&(0===e||1!==F))return-1;for(N[1]=0,m=1;m852||2===e&&C>592)return 1;for(;;){S=m-y,a[g]+1=p?(I=D[a[g]-p],z=k[a[g]-p]):(I=96,z=0),l=1<>y)+h]=S<<24|I<<16|z}while(0!==h);for(l=1<>=1;if(0!==l?(x&=l-1,x+=l):x=0,g++,0==--E[m]){if(m===F)break;m=t[i+a[g]]}if(m>b&&(x&f)!==d){for(0===y&&(y=b),u+=w,v=m-y,_=1<852||2===e&&C>592)return 1;d=x&f,o[d]=b<<24|v<<16|u-r}}return 0!==x&&(o[u+x]=m-y<<24|64<<16),s.bits=b,0};const{Z_FINISH:kt,Z_BLOCK:Et,Z_TREES:Nt,Z_OK:St,Z_STREAM_END:It,Z_NEED_DICT:zt,Z_STREAM_ERROR:Dt,Z_DATA_ERROR:At,Z_MEM_ERROR:Mt,Z_BUF_ERROR:Tt,Z_DEFLATED:Rt}=Z,Lt=16180,Bt=16190,Ht=16191,Ot=16192,Pt=16194,qt=16199,Vt=16200,Ut=16206,jt=16209,Wt=e=>(e>>>24&255)+(e>>>8&65280)+((65280&e)<<8)+((255&e)<<24);function Gt(){this.strm=null,this.mode=0,this.last=!1,this.wrap=0,this.havedict=!1,this.flags=0,this.dmax=0,this.check=0,this.total=0,this.head=null,this.wbits=0,this.wsize=0,this.whave=0,this.wnext=0,this.window=null,this.hold=0,this.bits=0,this.length=0,this.offset=0,this.extra=0,this.lencode=null,this.distcode=null,this.lenbits=0,this.distbits=0,this.ncode=0,this.nlen=0,this.ndist=0,this.have=0,this.next=null,this.lens=new Uint16Array(320),this.work=new Uint16Array(288),this.lendyn=null,this.distdyn=null,this.sane=0,this.back=0,this.was=0}const $t=e=>{if(!e)return 1;const t=e.state;return!t||t.strm!==e||t.mode16211?1:0},Zt=e=>{if($t(e))return Dt;const t=e.state;return e.total_in=e.total_out=t.total=0,e.msg="",t.wrap&&(e.adler=1&t.wrap),t.mode=Lt,t.last=0,t.havedict=0,t.flags=-1,t.dmax=32768,t.head=null,t.hold=0,t.bits=0,t.lencode=t.lendyn=new Int32Array(852),t.distcode=t.distdyn=new Int32Array(592),t.sane=1,t.back=-1,St},Kt=e=>{if($t(e))return Dt;const t=e.state;return t.wsize=0,t.whave=0,t.wnext=0,Zt(e)},Xt=(e,t)=>{let i;if($t(e))return Dt;const n=e.state;return t<0?(i=0,t=-t):(i=5+(t>>4),t<48&&(t&=15)),t&&(t<8||t>15)?Dt:(null!==n.window&&n.wbits!==t&&(n.window=null),n.wrap=i,n.wbits=t,Kt(e))},Yt=(e,t)=>{if(!e)return Dt;const i=new Gt;e.state=i,i.strm=e,i.window=null,i.mode=Lt;const n=Xt(e,t);return n!==St&&(e.state=null),n};let Qt,Jt,ei=!0;const ti=e=>{if(ei){Qt=new Int32Array(512),Jt=new Int32Array(32);let t=0;for(;t<144;)e.lens[t++]=8;for(;t<256;)e.lens[t++]=9;for(;t<280;)e.lens[t++]=7;for(;t<288;)e.lens[t++]=8;for(xt(1,e.lens,0,288,Qt,0,e.work,{bits:9}),t=0;t<32;)e.lens[t++]=5;xt(2,e.lens,0,32,Jt,0,e.work,{bits:5}),ei=!1}e.lencode=Qt,e.lenbits=9,e.distcode=Jt,e.distbits=5},ii=(e,t,i,n)=>{let o;const r=e.state;return null===r.window&&(r.wsize=1<=r.wsize?(r.window.set(t.subarray(i-r.wsize,i),0),r.wnext=0,r.whave=r.wsize):(o=r.wsize-r.wnext,o>n&&(o=n),r.window.set(t.subarray(i-n,i-n+o),r.wnext),(n-=o)?(r.window.set(t.subarray(i-n,i),0),r.wnext=n,r.whave=r.wsize):(r.wnext+=o,r.wnext===r.wsize&&(r.wnext=0),r.whave{let i,n,o,r,a,s,c,l,h,d,f,u,p,m,g,w,F,b,v,y,_,C,x=0;const k=new Uint8Array(4);let E,N;const S=new Uint8Array([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]);if($t(e)||!e.output||!e.input&&0!==e.avail_in)return Dt;i=e.state,i.mode===Ht&&(i.mode=Ot),a=e.next_out,o=e.output,c=e.avail_out,r=e.next_in,n=e.input,s=e.avail_in,l=i.hold,h=i.bits,d=s,f=c,C=St;e:for(;;)switch(i.mode){case Lt:if(0===i.wrap){i.mode=Ot;break}for(;h<16;){if(0===s)break e;s--,l+=n[r++]<>>8&255,i.check=G(i.check,k,2,0),l=0,h=0,i.mode=16181;break}if(i.head&&(i.head.done=!1),!(1&i.wrap)||(((255&l)<<8)+(l>>8))%31){e.msg="incorrect header check",i.mode=jt;break}if((15&l)!==Rt){e.msg="unknown compression method",i.mode=jt;break}if(l>>>=4,h-=4,_=8+(15&l),0===i.wbits&&(i.wbits=_),_>15||_>i.wbits){e.msg="invalid window size",i.mode=jt;break}i.dmax=1<>8&1),512&i.flags&&4&i.wrap&&(k[0]=255&l,k[1]=l>>>8&255,i.check=G(i.check,k,2,0)),l=0,h=0,i.mode=16182;case 16182:for(;h<32;){if(0===s)break e;s--,l+=n[r++]<>>8&255,k[2]=l>>>16&255,k[3]=l>>>24&255,i.check=G(i.check,k,4,0)),l=0,h=0,i.mode=16183;case 16183:for(;h<16;){if(0===s)break e;s--,l+=n[r++]<>8),512&i.flags&&4&i.wrap&&(k[0]=255&l,k[1]=l>>>8&255,i.check=G(i.check,k,2,0)),l=0,h=0,i.mode=16184;case 16184:if(1024&i.flags){for(;h<16;){if(0===s)break e;s--,l+=n[r++]<>>8&255,i.check=G(i.check,k,2,0)),l=0,h=0}else i.head&&(i.head.extra=null);i.mode=16185;case 16185:if(1024&i.flags&&(u=i.length,u>s&&(u=s),u&&(i.head&&(_=i.head.extra_len-i.length,i.head.extra||(i.head.extra=new Uint8Array(i.head.extra_len)),i.head.extra.set(n.subarray(r,r+u),_)),512&i.flags&&4&i.wrap&&(i.check=G(i.check,n,u,r)),s-=u,r+=u,i.length-=u),i.length))break e;i.length=0,i.mode=16186;case 16186:if(2048&i.flags){if(0===s)break e;u=0;do{_=n[r+u++],i.head&&_&&i.length<65536&&(i.head.name+=String.fromCharCode(_))}while(_&&u>9&1,i.head.done=!0),e.adler=i.check=0,i.mode=Ht;break;case 16189:for(;h<32;){if(0===s)break e;s--,l+=n[r++]<>>=7&h,h-=7&h,i.mode=Ut;break}for(;h<3;){if(0===s)break e;s--,l+=n[r++]<>>=1,h-=1,3&l){case 0:i.mode=16193;break;case 1:if(ti(i),i.mode=qt,t===Nt){l>>>=2,h-=2;break e}break;case 2:i.mode=16196;break;case 3:e.msg="invalid block type",i.mode=jt}l>>>=2,h-=2;break;case 16193:for(l>>>=7&h,h-=7&h;h<32;){if(0===s)break e;s--,l+=n[r++]<>>16^65535)){e.msg="invalid stored block lengths",i.mode=jt;break}if(i.length=65535&l,l=0,h=0,i.mode=Pt,t===Nt)break e;case Pt:i.mode=16195;case 16195:if(u=i.length,u){if(u>s&&(u=s),u>c&&(u=c),0===u)break e;o.set(n.subarray(r,r+u),a),s-=u,r+=u,c-=u,a+=u,i.length-=u;break}i.mode=Ht;break;case 16196:for(;h<14;){if(0===s)break e;s--,l+=n[r++]<>>=5,h-=5,i.ndist=1+(31&l),l>>>=5,h-=5,i.ncode=4+(15&l),l>>>=4,h-=4,i.nlen>286||i.ndist>30){e.msg="too many length or distance symbols",i.mode=jt;break}i.have=0,i.mode=16197;case 16197:for(;i.have>>=3,h-=3}for(;i.have<19;)i.lens[S[i.have++]]=0;if(i.lencode=i.lendyn,i.lenbits=7,E={bits:i.lenbits},C=xt(0,i.lens,0,19,i.lencode,0,i.work,E),i.lenbits=E.bits,C){e.msg="invalid code lengths set",i.mode=jt;break}i.have=0,i.mode=16198;case 16198:for(;i.have>>24,w=x>>>16&255,F=65535&x,!(g<=h);){if(0===s)break e;s--,l+=n[r++]<>>=g,h-=g,i.lens[i.have++]=F;else{if(16===F){for(N=g+2;h>>=g,h-=g,0===i.have){e.msg="invalid bit length repeat",i.mode=jt;break}_=i.lens[i.have-1],u=3+(3&l),l>>>=2,h-=2}else if(17===F){for(N=g+3;h>>=g,h-=g,_=0,u=3+(7&l),l>>>=3,h-=3}else{for(N=g+7;h>>=g,h-=g,_=0,u=11+(127&l),l>>>=7,h-=7}if(i.have+u>i.nlen+i.ndist){e.msg="invalid bit length repeat",i.mode=jt;break}for(;u--;)i.lens[i.have++]=_}}if(i.mode===jt)break;if(0===i.lens[256]){e.msg="invalid code -- missing end-of-block",i.mode=jt;break}if(i.lenbits=9,E={bits:i.lenbits},C=xt(1,i.lens,0,i.nlen,i.lencode,0,i.work,E),i.lenbits=E.bits,C){e.msg="invalid literal/lengths set",i.mode=jt;break}if(i.distbits=6,i.distcode=i.distdyn,E={bits:i.distbits},C=xt(2,i.lens,i.nlen,i.ndist,i.distcode,0,i.work,E),i.distbits=E.bits,C){e.msg="invalid distances set",i.mode=jt;break}if(i.mode=qt,t===Nt)break e;case qt:i.mode=Vt;case Vt:if(s>=6&&c>=258){e.next_out=a,e.avail_out=c,e.next_in=r,e.avail_in=s,i.hold=l,i.bits=h,Ft(e,f),a=e.next_out,o=e.output,c=e.avail_out,r=e.next_in,n=e.input,s=e.avail_in,l=i.hold,h=i.bits,i.mode===Ht&&(i.back=-1);break}for(i.back=0;x=i.lencode[l&(1<>>24,w=x>>>16&255,F=65535&x,!(g<=h);){if(0===s)break e;s--,l+=n[r++]<>b)],g=x>>>24,w=x>>>16&255,F=65535&x,!(b+g<=h);){if(0===s)break e;s--,l+=n[r++]<>>=b,h-=b,i.back+=b}if(l>>>=g,h-=g,i.back+=g,i.length=F,0===w){i.mode=16205;break}if(32&w){i.back=-1,i.mode=Ht;break}if(64&w){e.msg="invalid literal/length code",i.mode=jt;break}i.extra=15&w,i.mode=16201;case 16201:if(i.extra){for(N=i.extra;h>>=i.extra,h-=i.extra,i.back+=i.extra}i.was=i.length,i.mode=16202;case 16202:for(;x=i.distcode[l&(1<>>24,w=x>>>16&255,F=65535&x,!(g<=h);){if(0===s)break e;s--,l+=n[r++]<>b)],g=x>>>24,w=x>>>16&255,F=65535&x,!(b+g<=h);){if(0===s)break e;s--,l+=n[r++]<>>=b,h-=b,i.back+=b}if(l>>>=g,h-=g,i.back+=g,64&w){e.msg="invalid distance code",i.mode=jt;break}i.offset=F,i.extra=15&w,i.mode=16203;case 16203:if(i.extra){for(N=i.extra;h>>=i.extra,h-=i.extra,i.back+=i.extra}if(i.offset>i.dmax){e.msg="invalid distance too far back",i.mode=jt;break}i.mode=16204;case 16204:if(0===c)break e;if(u=f-c,i.offset>u){if(u=i.offset-u,u>i.whave&&i.sane){e.msg="invalid distance too far back",i.mode=jt;break}u>i.wnext?(u-=i.wnext,p=i.wsize-u):p=i.wnext-u,u>i.length&&(u=i.length),m=i.window}else m=o,p=a-i.offset,u=i.length;u>c&&(u=c),c-=u,i.length-=u;do{o[a++]=m[p++]}while(--u);0===i.length&&(i.mode=Vt);break;case 16205:if(0===c)break e;o[a++]=i.length,c--,i.mode=Vt;break;case Ut:if(i.wrap){for(;h<32;){if(0===s)break e;s--,l|=n[r++]<Yt(e,15),inflateInit2:Yt,inflate:ni,inflateEnd:e=>{if($t(e))return Dt;let t=e.state;return t.window&&(t.window=null),e.state=null,St},inflateGetHeader:(e,t)=>{if($t(e))return Dt;const i=e.state;return 2&i.wrap?(i.head=t,t.done=!1,St):Dt},inflateSetDictionary:(e,t)=>{const i=t.length;let n,o,r;return $t(e)?Dt:(n=e.state,0!==n.wrap&&n.mode!==Bt?Dt:n.mode===Bt&&(o=1,o=j(o,t,i,0),o!==n.check)?At:(r=ii(e,t,i,i),r?(n.mode=16210,Mt):(n.havedict=1,St)))},inflateInfo:"pako inflate (from Nodeca project)"};var ri=function(){this.text=0,this.time=0,this.xflags=0,this.os=0,this.extra=null,this.extra_len=0,this.name="",this.comment="",this.hcrc=0,this.done=!1};const ai=Object.prototype.toString,{Z_NO_FLUSH:si,Z_FINISH:ci,Z_OK:li,Z_STREAM_END:hi,Z_NEED_DICT:di,Z_STREAM_ERROR:fi,Z_DATA_ERROR:ui,Z_MEM_ERROR:pi}=Z;function mi(e){this.options=Ze({chunkSize:65536,windowBits:15,to:""},e||{});const t=this.options;t.raw&&t.windowBits>=0&&t.windowBits<16&&(t.windowBits=-t.windowBits,0===t.windowBits&&(t.windowBits=-15)),!(t.windowBits>=0&&t.windowBits<16)||e&&e.windowBits||(t.windowBits+=32),t.windowBits>15&&t.windowBits<48&&(15&t.windowBits||(t.windowBits|=15)),this.err=0,this.msg="",this.ended=!1,this.chunks=[],this.strm=new tt,this.strm.avail_out=0;let i=oi.inflateInit2(this.strm,t.windowBits);if(i!==li)throw new Error($[i]);if(this.header=new ri,oi.inflateGetHeader(this.strm,this.header),t.dictionary&&("string"==typeof t.dictionary?t.dictionary=Qe(t.dictionary):"[object ArrayBuffer]"===ai.call(t.dictionary)&&(t.dictionary=new Uint8Array(t.dictionary)),t.raw&&(i=oi.inflateSetDictionary(this.strm,t.dictionary),i!==li)))throw new Error($[i])}function gi(e,t){const i=new mi(t);if(i.push(e),i.err)throw i.msg||$[i.err];return i.result}mi.prototype.push=function(e,t){const i=this.strm,n=this.options.chunkSize,o=this.options.dictionary;let r,a,s;if(this.ended)return!1;for(a=t===~~t?t:!0===t?ci:si,"[object ArrayBuffer]"===ai.call(e)?i.input=new Uint8Array(e):i.input=e,i.next_in=0,i.avail_in=i.input.length;;){for(0===i.avail_out&&(i.output=new Uint8Array(n),i.next_out=0,i.avail_out=n),r=oi.inflate(i,a),r===di&&o&&(r=oi.inflateSetDictionary(i,o),r===li?r=oi.inflate(i,a):r===ui&&(r=di));i.avail_in>0&&r===hi&&i.state.wrap>0&&0!==e[i.next_in];)oi.inflateReset(i),r=oi.inflate(i,a);switch(r){case fi:case ui:case di:case pi:return this.onEnd(r),this.ended=!0,!1}if(s=i.avail_out,i.next_out&&(0===i.avail_out||r===hi))if("string"===this.options.to){let e=et(i.output,i.next_out),t=i.next_out-e,o=Je(i.output,e);i.next_out=t,i.avail_out=n-t,t&&i.output.set(i.output.subarray(e,e+t),0),this.onData(o)}else this.onData(i.output.length===i.next_out?i.output:i.output.subarray(0,i.next_out));if(r!==li||0!==s){if(r===hi)return r=oi.inflateEnd(this.strm),this.onEnd(r),this.ended=!0,!0;if(0===i.avail_in)break}}return!0},mi.prototype.onData=function(e){this.chunks.push(e)},mi.prototype.onEnd=function(e){e===li&&("string"===this.options.to?this.result=this.chunks.join(""):this.result=Ke(this.chunks)),this.chunks=[],this.err=e,this.msg=this.strm.msg};var wi=function(e,t){return(t=t||{}).raw=!0,gi(e,t)},Fi={Inflate:mi,inflate:gi,inflateRaw:wi,ungzip:gi,constants:Z};const{Deflate:bi,deflate:vi,deflateRaw:yi,gzip:_i}=gt,{Inflate:Ci,inflate:xi,inflateRaw:ki,ungzip:Ei}=Fi;var Ni=yi,Si=ki,Ii=Ei;function zi(e){const t=ArrayBuffer.isView(e)?e:new Uint8Array(e);return 0!==(4&t[3])&&66===t[12]&&67===t[13]?function(e,t){const i=[];let n=0,o=0;t=t||e.byteLength-18;for(;n100?Mi(new Uint8Array(e.buffer,e.byteOffset+t,o),i,n):function(e,t,i,n,o){for(let r=0;r0&&(this.content[0]=t,this.sinkDown(0)),e},remove:function(e){for(var t=this.content.length,i=0;i0;){var n=Math.floor((e+1)/2)-1,o=this.content[n];if(i>=o)break;this.content[n]=t,this.content[e]=o,e=n}},sinkDown:function(e){for(var t=this.content.length,i=this.content[e],n=i;;){var o=2*(e+1),r=o-1,a=null;if(r{let e=[];for(let t=1;t>=.5;t-=.1)for(let i=0;i<1;i+=1/28){const n="rgb("+Hi.hsvToRgb(i,1,t).join(",")+")";e.push(n)}return e.pop(),e.push(Hi.rgbColor(16,16,16)),e},rgbToHex:function(e){return(e=e.match(/^rgba?[\s+]?\([\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?/i))&&4===e.length?"#"+("0"+parseInt(e[1],10).toString(16)).slice(-2)+("0"+parseInt(e[2],10).toString(16)).slice(-2)+("0"+parseInt(e[3],10).toString(16)).slice(-2):""},hexToRgb:function(e){var t=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(e);if(null!==t)return"rgb("+parseInt(t[1],16)+","+parseInt(t[2],16)+","+parseInt(t[3],16)+")"},hsvToRgb:function(e,t,i){var n,o,r,a=Math.floor(6*e),s=6*e-a,c=i*(1-t),l=i*(1-s*t),h=i*(1-(1-s)*t);switch(a%6){case 0:n=i,o=h,r=c;break;case 1:n=l,o=i,r=c;break;case 2:n=c,o=i,r=h;break;case 3:n=c,o=l,r=i;break;case 4:n=h,o=c,r=i;break;case 5:n=i,o=c,r=l}return[Math.floor(255*n),Math.floor(255*o),Math.floor(255*r)]},hslToRgb:function(e,t,i){var n,o,r;if(0===t)n=o=r=i;else{var a=i<.5?i*(1+t):i+t-i*t,s=2*i-a;n=Hi.hue2rgb(s,a,e+1/3),o=Hi.hue2rgb(s,a,e),r=Hi.hue2rgb(s,a,e-1/3)}return[255*n,255*o,255*r]},hue2rgb:(e,t,i)=>(i<0&&(i+=1),i>1&&(i-=1),i<1/6?e+6*(t-e)*i:i<.5?t:i<2/3?e+(t-e)*(2/3-i)*6:e),rgbaColor:function(e,t,i,n){return"rgba("+(e=Ri(e,0,255))+","+(t=Ri(t,0,255))+","+(i=Ri(i,0,255))+","+(n=Ri(n,0,1))+")"},rgbColor:function(e,t,i){return"rgb("+(e=Ri(e,0,255))+","+(t=Ri(t,0,255))+","+(i=Ri(i,0,255))+")"},greyScale:function(e){var t=Ri(e,0,255);return"rgb("+t+","+t+","+t+")"},randomGrey:function(e,t){e=Ri(e,0,255),t=Ri(t,0,255);var i=Math.round(Bi(e,t)).toString(10);return"rgb("+i+","+i+","+i+")"},randomRGB:function(e,t){return e=Ri(e,0,255),t=Ri(t,0,255),"rgb("+Math.round(Bi(e,t)).toString(10)+","+Math.round(Bi(e,t)).toString(10)+","+Math.round(Bi(e,t)).toString(10)+")"},randomRGBConstantAlpha:function(e,t,i){return e=Ri(e,0,255),t=Ri(t,0,255),"rgba("+Math.round(Bi(e,t)).toString(10)+","+Math.round(Bi(e,t)).toString(10)+","+Math.round(Bi(e,t)).toString(10)+","+i+")"},addAlpha:function(e,t){if("0"===e||"."===e)e="rgb(0,0,0)";else{const t=this.colorNameToHex(e);t&&(e=t)}var i=/(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(e);if(e.startsWith("rgba")){const i=e.lastIndexOf(",");return e.substring(0,i+1)+t.toString()+")"}return i&&(e=Hi.hexToRgb(e)),e.startsWith("rgb")?e.replace("rgb","rgba").replace(")",", "+t+")"):(console.log(e+" is not an rgb style string"),e)},rgbComponents:function(e){if("0"===e||"."===e)return[0,0,0];if(/(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(e))e=Hi.hexToRgb(e);else if(!e.startsWith("rgb")){const t=this.colorNameToHex(e);e=this.hexToRgb(t)}if(e.startsWith("rgb("))return e.substring(4,e.length-1).split(",").map((e=>Number.parseInt(e.trim())));if(e.startsWith("rgba("))return e.substring(5,e.length-1).split(",").map(((e,t)=>(e=e.trim(),3===t?Number.parseFloat(e):Number.parseInt(e))));throw Error("Unrecognized color string: color")},getCompositeColor:function(e,t,i){return"rgb("+Math.floor(i*t[0]+(1-i)*e[0])+","+Math.floor(i*t[1]+(1-i)*e[1])+","+Math.floor(i*t[2]+(1-i)*e[2])+")"},createColorString:function(e){return(e=function(e){return void 0===e||((e.startsWith("'")||e.startsWith('"'))&&(e=e.substring(1)),(e.endsWith("'")||e.endsWith('"'))&&(e=e.substring(0,e.length-1))),e}(e)).includes(",")?e.startsWith("rgb")?e:"rgb("+e+")":e},darkenLighten:function(e,t){let i,n=this.colorNameToHex(e);i=n?Hi.hexToRgb(n):e.startsWith("rgb(")?e:Hi.hexToRgb(e);const o=i.replace(")","").substring(4).split(","),r=Math.max(0,Math.min(255,Number.parseInt(o[0].trim())+t)),a=Math.max(0,Math.min(255,Number.parseInt(o[1].trim())+t)),s=Math.max(0,Math.min(255,Number.parseInt(o[2].trim())+t));return"rgb("+r.toString()+","+a.toString()+","+s.toString()+")"},colorNameToHex:function(e){return{aliceblue:"#f0f8ff",antiquewhite:"#faebd7",aqua:"#00ffff",aquamarine:"#7fffd4",azure:"#f0ffff",beige:"#f5f5dc",bisque:"#ffe4c4",black:"#000000",blanchedalmond:"#ffebcd",blue:"#0000ff",blueviolet:"#8a2be2",brown:"#a52a2a",burlywood:"#deb887",cadetblue:"#5f9ea0",chartreuse:"#7fff00",chocolate:"#d2691e",coral:"#ff7f50",cornflowerblue:"#6495ed",cornsilk:"#fff8dc",crimson:"#dc143c",cyan:"#00ffff",darkblue:"#00008b",darkcyan:"#008b8b",darkgoldenrod:"#b8860b",darkgray:"#a9a9a9",darkgreen:"#006400",darkkhaki:"#bdb76b",darkmagenta:"#8b008b",darkolivegreen:"#556b2f",darkorange:"#ff8c00",darkorchid:"#9932cc",darkred:"#8b0000",darksalmon:"#e9967a",darkseagreen:"#8fbc8f",darkslateblue:"#483d8b",darkslategray:"#2f4f4f",darkturquoise:"#00ced1",darkviolet:"#9400d3",deeppink:"#ff1493",deepskyblue:"#00bfff",dimgray:"#696969",dodgerblue:"#1e90ff",firebrick:"#b22222",floralwhite:"#fffaf0",forestgreen:"#228b22",fuchsia:"#ff00ff",gainsboro:"#dcdcdc",ghostwhite:"#f8f8ff",gold:"#ffd700",goldenrod:"#daa520",gray:"#808080",green:"#008000",greenyellow:"#adff2f",honeydew:"#f0fff0",hotpink:"#ff69b4","indianred ":"#cd5c5c","indigo ":"#4b0082",ivory:"#fffff0",khaki:"#f0e68c",lavender:"#e6e6fa",lavenderblush:"#fff0f5",lawngreen:"#7cfc00",lemonchiffon:"#fffacd",lightblue:"#add8e6",lightcoral:"#f08080",lightcyan:"#e0ffff",lightgoldenrodyellow:"#fafad2",lightgrey:"#d3d3d3",lightgreen:"#90ee90",lightpink:"#ffb6c1",lightsalmon:"#ffa07a",lightseagreen:"#20b2aa",lightskyblue:"#87cefa",lightslategray:"#778899",lightsteelblue:"#b0c4de",lightyellow:"#ffffe0",lime:"#00ff00",limegreen:"#32cd32",linen:"#faf0e6",magenta:"#ff00ff",maroon:"#800000",mediumaquamarine:"#66cdaa",mediumblue:"#0000cd",mediumorchid:"#ba55d3",mediumpurple:"#9370d8",mediumseagreen:"#3cb371",mediumslateblue:"#7b68ee",mediumspringgreen:"#00fa9a",mediumturquoise:"#48d1cc",mediumvioletred:"#c71585",midnightblue:"#191970",mintcream:"#f5fffa",mistyrose:"#ffe4e1",moccasin:"#ffe4b5",navajowhite:"#ffdead",navy:"#000080",oldlace:"#fdf5e6",olive:"#808000",olivedrab:"#6b8e23",orange:"#ffa500",orangered:"#ff4500",orchid:"#da70d6",palegoldenrod:"#eee8aa",palegreen:"#98fb98",paleturquoise:"#afeeee",palevioletred:"#d87093",papayawhip:"#ffefd5",peachpuff:"#ffdab9",peru:"#cd853f",pink:"#ffc0cb",plum:"#dda0dd",powderblue:"#b0e0e6",purple:"#800080",red:"#ff0000",rosybrown:"#bc8f8f",royalblue:"#4169e1",saddlebrown:"#8b4513",salmon:"#fa8072",sandybrown:"#f4a460",seagreen:"#2e8b57",seashell:"#fff5ee",sienna:"#a0522d",silver:"#c0c0c0",skyblue:"#87ceeb",slateblue:"#6a5acd",slategray:"#708090",snow:"#fffafa",springgreen:"#00ff7f",steelblue:"#4682b4",tan:"#d2b48c",teal:"#008080",thistle:"#d8bfd8",tomato:"#ff6347",turquoise:"#40e0d0",violet:"#ee82ee",wheat:"#f5deb3",white:"#ffffff",whitesmoke:"#f5f5f5",yellow:"#ffff00",yellowgreen:"#9acd32",darkgrey:"#a9a9a9",darkslategrey:"#2f4f4f",dimgrey:"#696969",grey:"#808080",lightgray:"#d3d3d3",lightslategrey:"#778899",slategrey:"#708090"}[e]}},Oi="googleapis";class Pi{constructor(){this.oauthTokens={}}setToken(e,t){t=t||Oi,this.oauthTokens[t]=e}getToken(e){let t;e=e||Oi;for(let i of Object.keys(this.oauthTokens)){if(qi(i).test(e)){t=this.oauthTokens[i];break}}return t}removeToken(e){e=e||Oi;for(let t of Object.keys(this.oauthTokens)){qi(t).test(e)&&(this.oauthTokens[t]=void 0)}}}function qi(e){return new RegExp("^"+e.split(/\*+/).map(Vi).join(".*")+"$")}function Vi(e){return e.replace(/[|\\{}()[\]^$+*?.]/g,"\\$&")}function Ui(e){return e.includes("googleapis")&&!e.includes("urlshortener")||ji(e)||Wi(e)}function ji(e){return e.startsWith("gs://")||e.startsWith("https://www.googleapis.com/storage")||e.startsWith("https://storage.cloud.google.com")||e.startsWith("https://storage.googleapis.com")}function Wi(e){return e.indexOf("drive.google.com")>=0||e.indexOf("www.googleapis.com/drive")>0}function Gi(e){let{bucket:t,object:i}=function(e){let t,i;if(e.startsWith("gs://")){const n=e.indexOf("/",5);if(n>=0){t=e.substring(5,n);const o=e.indexOf("?");i=o<0?e.substring(n+1):e.substring(n+1,o)}}else if(e.startsWith("https://storage.googleapis.com")||e.startsWith("https://storage.cloud.google.com")){const n=e.indexOf("/v1/b/",8);if(n>0){const o=e.indexOf("/o/",n);if(o>0){const r=e.indexOf("?",o);t=e.substring(n+6,o),i=r>0?e.substring(o+3,r):e.substring(o+3)}}else{const n=e.indexOf("/",8),o=e.indexOf("/",n+1),r=e.indexOf("?",o);o>0&&(t=e.substring(n+1,o),i=r<0?e.substring(o+1):e.substring(o+1,r))}}else if(e.startsWith("https://www.googleapis.com/storage/v1/b")){const n=e.indexOf("/v1/b/",8),o=e.indexOf("/o/",n);if(o>0){const r=e.indexOf("?",o);t=e.substring(n+6,o),i=r>0?e.substring(o+3,r):e.substring(o+3)}}if(t&&i)return{bucket:t,object:i};throw Error(`Unrecognized Google Storage URI: ${e}`)}(e);i=function(e){let t="";return e.split("").forEach((function(e){$i.has(e)?t+=$i.get(e):t+=e})),t}(i);const n=e.indexOf("?");return`https://storage.googleapis.com/storage/v1/b/${t}/o/${i}${n>0?e.substring(n)+"&alt=media":"?alt=media"}`}const $i=new Map;function Zi(){return window.google&&window.google.igv}function Ki(e){var t=function(e){if(e.includes("/open?id=")){const t=e.indexOf("/open?id=")+9,i=e.indexOf("&");if(t>0&&i>t)return e.substring(t,i);if(t>0)return e.substring(t)}else{if(e.includes("/file/d/")){const t=e.indexOf("/file/d/")+8,i=e.lastIndexOf("/");return e.substring(t,i)}if(e.startsWith("https://www.googleapis.com/drive")){let t=e.indexOf("/files/");const i=e.indexOf("?");if(t>0)return t+=7,i>0?e.substring(t,i):e.substring(t)}}throw Error("Unknown Google Drive url format: "+e)}(e);return t?"https://www.googleapis.com/drive/v3/files/"+t+"?alt=media&supportsTeamDrives=true":e}$i.set("!","%21"),$i.set("#","%23"),$i.set("$","%24"),$i.set("%","%25"),$i.set("&","%26"),$i.set("'","%27"),$i.set("(","%28"),$i.set(")","%29"),$i.set("*","%2A"),$i.set("+","%2B"),$i.set(",","%2C"),$i.set("/","%2F"),$i.set(":","%3A"),$i.set(";","%3B"),$i.set("=","%3D"),$i.set("?","%3F"),$i.set("@","%40"),$i.set("[","%5B"),$i.set("]","%5D"),$i.set(" ","%20");class Xi{constructor(e){this.requestsPerSecond=e.requestsPerSecond||10,this.lastStartTime=0,this.queued=[]}add(e,t){var i=this;return new Promise((function(t,n){i.queued.push({resolve:t,reject:n,asyncFunction:e}),i.dequeue()}))}addAll(e,t){var i=e.map(function(e){return this.add(e,t)}.bind(this));return Promise.all(i)}dequeue(){if(this.queued.length>0){var e=new Date,t=1e3/this.requestsPerSecond+1,i=e-this.lastStartTime;i>=t?this._execute():setTimeout(function(){this.dequeue()}.bind(this),t-i)}}async _execute(){this.lastStartTime=new Date;var e=this.queued.shift();const t=e.asyncFunction;try{const i=await t();e.resolve(i)}catch(t){e.reject(t)}}}function Yi(e){return e.indexOf("X-Goog-Signature")>-1}function Qi(){if(Zi()){return Zi()&&google.igv.tokenResponse&&Date.now()0)for(var a=0;a=0){o=atob(o);const e=new Uint8Array(o.length);for(let t=0;t0?Ii(e):e,i}return decodeURIComponent(o)}(e).buffer;if(t.range){const e=t.range.size?t.range.start+t.range.size:i.byteLength;return i.slice(t.range.start,e)}return i}return e.startsWith("https://drive.google.com")&&(e=Ki(e)),Wi(e)||e.startsWith("https://www.dropbox.com")?this.googleThrottle.add((async()=>this._loadURL(e,t))):this._loadURL(e,t)}throw Error(`url must be either a 'File', 'string', 'function', or 'Promise'. Actual type: ${i}`)}async getContentLength(e,t){if(!this.contentLengthMap.has(e)){(t=t||{}).method="HEAD",t.GET_CONTENT_LENGTH=!0;const i=await this._loadURL(e,t),n=i?Number.parseInt(i):-1;this.contentLengthMap.set(e,n)}return this.contentLengthMap.get(e)}async _loadURL(e,t){const i=this;e=function(e){return e.startsWith("https://www.dropbox.com")?e.replace("//www.dropbox.com","//dl.dropboxusercontent.com"):e.startsWith("https://drive.google.com")?Ki(e):e.includes("//www.broadinstitute.org/igvdata")?e.replace("//www.broadinstitute.org/igvdata","//data.broadinstitute.org/igvdata"):e.includes("//igvdata.broadinstitute.org")?e.replace("//igvdata.broadinstitute.org","//s3.amazonaws.com/igv.broadinstitute.org"):e.includes("//igv.genepattern.org")?e.replace("//igv.genepattern.org","//igv-genepattern-org.s3.amazonaws.com"):e.startsWith("ftp://ftp.ncbi.nlm.nih.gov/geo")?e.replace("ftp://","https://"):e}(e);let n=(t=t||{}).oauthToken||this.getOauthToken(e);n&&(n=await("function"==typeof n?n():n));let o=-1;return!t.range||function(e){return e.indexOf("X-Amz-Signature")>-1}(e)||Yi(e)||(o=await this.getContentLength(e)),new Promise((function(r,a){Ui(e)&&!Yi(e)&&(ji(e)&&(e=Gi(e)),e=function(e){let t=en.apiKey;t||"undefined"==typeof gapi||(t=gapi.apiKey);if(void 0!==t&&!e.includes("key=")){const i=e.includes("?")?"&":"?";e=e+i+"key="+t}return e}(e),Wi(e)&&function(e){if(e.includes("supportsTeamDrive"))return e;{const t=e.includes("?")?"&":"?";e=e+t+"supportsTeamDrive=true"}}(e),n||(n=Qi()));const s=t.headers||{};n&&function(e,t){t&&(e["Cache-Control"]="no-cache",e.Authorization="Bearer "+t)}(s,n);const c=t.range,l=new XMLHttpRequest,h=t.sendData||t.body,d=t.method||(h?"POST":"GET"),f=t.responseType,u=t.contentType,p=t.mimeType;if(l.open(d,e),t.timeout&&(l.timeout=t.timeout),c){let e="";c.size&&(e=c.start+c.size-1,o>0&&(e=Math.min(e,o-1))),l.setRequestHeader("Range","bytes="+c.start+"-"+e)}if(u&&l.setRequestHeader("Content-Type",u),p&&l.overrideMimeType(p),f&&(l.responseType=f),s)for(let e of Object.keys(s)){const t=s[e];l.setRequestHeader(e,t)}!0===t.withCredentials&&(l.withCredentials=!0),l.onload=async function(n){t.GET_CONTENT_LENGTH&&r(l.getResponseHeader("content-length")),0===l.status||l.status>=200&&l.status<=300?c&&206!==l.status&&0!==c.start?(l.response.length>1e5&&!i.RANGE_WARNING_GIVEN&&alert(`Warning: Range header ignored for URL: ${e}. This can have severe performance impacts.`),r(l.response.slice(c.start,c.start+c.size))):r(l.response):"undefined"==typeof gapi||404!==l.status&&401!==l.status&&403!==l.status||!Ui(e)||t.retries?403===l.status?m("Access forbidden: "+e):416===l.status?m("Unsatisfiable range"):m(l.status):g()},l.onerror=function(i){Ui(e)&&!t.retries?g():m("Error accessing resource: "+e+" Status: "+l.status)},l.ontimeout=function(e){m("Timed out")},l.onabort=function(e){console.log("Aborted"),a(e)};try{l.send(h)}catch(i){Ui(e)&&!t.retries?g():m(i)}function m(e){if(!a)throw e;a(e)}async function g(){try{const n=await async function(e){if(Zi()){const t=function(e){return Wi(e)?"https://www.googleapis.com/auth/drive.readonly":ji(e)?"https://www.googleapis.com/auth/devstorage.read_only":"https://www.googleapis.com/auth/userinfo.profile"}(e),i=await async function(e){if(!Zi())throw Error("Google oAuth has not been initialized");if(google.igv.tokenResponse&&Date.now(){try{t.callback=e=>{void 0!==e.error&&n(e),google.igv.tokenResponse=e,google.igv.tokenExpiresAt=Date.now()+1e3*e.expires_in,i(e.access_token)},t.requestAccessToken({scope:e})}catch(e){console.log(e)}}))}}(t);return i}throw Error("Authorization is required, but Google oAuth has not been initalized. Contact your site administrator for assistance.")}(e);t.retries=1,t.oauthToken=n;const o=await i.load(e,t);r(o)}catch(e){if(e.error){const t=e.error.startsWith("popup_blocked")?"Google login popup blocked by browser.":e.error;alert(t)}else m(e)}}}))}async _loadFileSlice(e,t){let i=t&&t.range?e.slice(t.range.start,t.range.start+t.range.size):e;const n=await i.arrayBuffer();return"arraybuffer"===t.responseType?n:Ji(n)}async _loadStringFromFile(e,t){const i=t.range?e.slice(t.range.start,t.range.start+t.range.size):e;return Ji(await i.arrayBuffer())}async _loadStringFromUrl(e,t){(t=t||{}).responseType="arraybuffer";return Ji(await this.load(e,t))}setOauthToken(e,t){this.oauth.setToken(e,t)}getOauthToken(e){const t=Ui(e)?void 0:function(e){for(var t=r,i=t.parser.loose.exec(e),n={},o=14;o--;)n[t.key[o]]=i[o]||"";return n[t.q.name]={},n[t.key[12]].replace(t.q.parser,(function(e,i,o){i&&(n[t.q.name][i]=o)})),n}(e).host;let i=this.oauth.getToken(t);if(i)return i;if(void 0===t){const e=Qi();if(e&&e.expires_at>Date.now())return e.access_token}}};var tn={color:1};tn.parent=tn,tn.left=tn,tn.right=tn; -/*! - * jQuery JavaScript Library v3.3.1 -ajax,-ajax/jsonp,-ajax/load,-ajax/parseXML,-ajax/script,-ajax/var/location,-ajax/var/nonce,-ajax/var/rquery,-ajax/xhr,-manipulation/_evalUrl,-event/ajax,-effects,-effects/Tween,-effects/animatedSelector - * https://jquery.com/ - * - * Includes Sizzle.js - * https://sizzlejs.com/ - * - * Copyright JS Foundation and other contributors - * Released under the MIT license - * https://jquery.org/license - * - * Date: 2018-01-20T17:24Z - */ -var nn=[],on=window.document,rn=Object.getPrototypeOf,an=nn.slice,sn=nn.concat,cn=nn.push,ln=nn.indexOf,hn={},dn=hn.toString,fn=hn.hasOwnProperty,un=fn.toString,pn=un.call(Object),mn={},gn=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType},wn=function(e){return null!=e&&e===e.window},Fn={type:!0,src:!0,noModule:!0};function bn(e,t,i){var n,o=(t=t||on).createElement("script");if(o.text=e,i)for(n in Fn)i[n]&&(o[n]=i[n]);t.head.appendChild(o).parentNode.removeChild(o)}function vn(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?hn[dn.call(e)]||"object":typeof e}var yn="3.3.1 -ajax,-ajax/jsonp,-ajax/load,-ajax/parseXML,-ajax/script,-ajax/var/location,-ajax/var/nonce,-ajax/var/rquery,-ajax/xhr,-manipulation/_evalUrl,-event/ajax,-effects,-effects/Tween,-effects/animatedSelector",_n=function(e,t){return new _n.fn.init(e,t)},Cn=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;function xn(e){var t=!!e&&"length"in e&&e.length,i=vn(e);return!gn(e)&&!wn(e)&&("array"===i||0===t||"number"==typeof t&&t>0&&t-1 in e)}_n.fn=_n.prototype={jquery:yn,constructor:_n,length:0,toArray:function(){return an.call(this)},get:function(e){return null==e?an.call(this):e<0?this[e+this.length]:this[e]},pushStack:function(e){var t=_n.merge(this.constructor(),e);return t.prevObject=this,t},each:function(e){return _n.each(this,e)},map:function(e){return this.pushStack(_n.map(this,(function(t,i){return e.call(t,i,t)})))},slice:function(){return this.pushStack(an.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(e){var t=this.length,i=+e+(e<0?t:0);return this.pushStack(i>=0&&i+~]|"+L+")"+L+"*"),j=new RegExp("="+L+"*([^\\]'\"]*?)"+L+"*\\]","g"),W=new RegExp(O),G=new RegExp("^"+B+"$"),$={ID:new RegExp("^#("+B+")"),CLASS:new RegExp("^\\.("+B+")"),TAG:new RegExp("^("+B+"|[*])"),ATTR:new RegExp("^"+H),PSEUDO:new RegExp("^"+O),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+L+"*(even|odd|(([+-]|)(\\d*)n|)"+L+"*(?:([+-]|)"+L+"*(\\d+)|))"+L+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+L+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+L+"*((?:-\\d)?\\d*)"+L+"*\\)|)(?=[^-]|$)","i")},Z=/^(?:input|select|textarea|button)$/i,K=/^h\d$/i,X=/^[^{]+\{\s*\[native \w/,Y=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,Q=/[+~]/,J=new RegExp("\\\\([\\da-f]{1,6}"+L+"?|("+L+")|.)","ig"),ee=function(e,t,i){var n="0x"+t-65536;return n!=n||i?t:n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320)},te=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"�":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},ne=function(){f()},oe=we((function(e){return!0===e.disabled&&("form"in e||"label"in e)}),{dir:"parentNode",next:"legend"});try{A.apply(I=M.call(y.childNodes),y.childNodes),I[y.childNodes.length].nodeType}catch(e){A={apply:I.length?function(e,t){D.apply(e,M.call(t))}:function(e,t){for(var i=e.length,n=0;e[i++]=t[n++];);e.length=i-1}}}function re(e,t,n,o){var r,s,l,h,d,p,w,F=t&&t.ownerDocument,_=t?t.nodeType:9;if(n=n||[],"string"!=typeof e||!e||1!==_&&9!==_&&11!==_)return n;if(!o&&((t?t.ownerDocument||t:y)!==u&&f(t),t=t||u,m)){if(11!==_&&(d=Y.exec(e)))if(r=d[1]){if(9===_){if(!(l=t.getElementById(r)))return n;if(l.id===r)return n.push(l),n}else if(F&&(l=F.getElementById(r))&&b(t,l)&&l.id===r)return n.push(l),n}else{if(d[2])return A.apply(n,t.getElementsByTagName(e)),n;if((r=d[3])&&i.getElementsByClassName&&t.getElementsByClassName)return A.apply(n,t.getElementsByClassName(r)),n}if(i.qsa&&!E[e+" "]&&(!g||!g.test(e))){if(1!==_)F=t,w=e;else if("object"!==t.nodeName.toLowerCase()){for((h=t.getAttribute("id"))?h=h.replace(te,ie):t.setAttribute("id",h=v),s=(p=a(e)).length;s--;)p[s]="#"+h+" "+ge(p[s]);w=p.join(","),F=Q.test(e)&&pe(t.parentNode)||t}if(w)try{return A.apply(n,F.querySelectorAll(w)),n}catch(e){}finally{h===v&&t.removeAttribute("id")}}}return c(e.replace(q,"$1"),t,n,o)}function ae(){var e=[];return function t(i,o){return e.push(i+" ")>n.cacheLength&&delete t[e.shift()],t[i+" "]=o}}function se(e){return e[v]=!0,e}function ce(e){var t=u.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function le(e,t){var i=t&&e,n=i&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(n)return n;if(i)for(;i=i.nextSibling;)if(i===t)return-1;return e?1:-1}function he(e){return function(t){return"input"===t.nodeName.toLowerCase()&&t.type===e}}function de(e){return function(t){var i=t.nodeName.toLowerCase();return("input"===i||"button"===i)&&t.type===e}}function fe(e){return function(t){return"form"in t?t.parentNode&&!1===t.disabled?"label"in t?"label"in t.parentNode?t.parentNode.disabled===e:t.disabled===e:t.isDisabled===e||t.isDisabled!==!e&&oe(t)===e:t.disabled===e:"label"in t&&t.disabled===e}}function ue(e){return se((function(t){return t=+t,se((function(i,n){for(var o,r=e([],i.length,t),a=r.length;a--;)i[o=r[a]]&&(i[o]=!(n[o]=i[o]))}))}))}function pe(e){return e&&void 0!==e.getElementsByTagName&&e}for(t in i=re.support={},r=re.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return!!t&&"HTML"!==t.nodeName},f=re.setDocument=function(e){var t,o,a=e?e.ownerDocument||e:y;return a!==u&&9===a.nodeType&&a.documentElement?(p=(u=a).documentElement,m=!r(u),y!==u&&(o=u.defaultView)&&o.top!==o&&(o.addEventListener?o.addEventListener("unload",ne,!1):o.attachEvent&&o.attachEvent("onunload",ne)),i.attributes=ce((function(e){return e.className="i",!e.getAttribute("className")})),i.getElementsByTagName=ce((function(e){return e.appendChild(u.createComment("")),!e.getElementsByTagName("*").length})),i.getElementsByClassName=X.test(u.getElementsByClassName),i.getById=ce((function(e){return p.appendChild(e).id=v,!u.getElementsByName||!u.getElementsByName(v).length})),i.getById?(n.filter.ID=function(e){var t=e.replace(J,ee);return function(e){return e.getAttribute("id")===t}},n.find.ID=function(e,t){if(void 0!==t.getElementById&&m){var i=t.getElementById(e);return i?[i]:[]}}):(n.filter.ID=function(e){var t=e.replace(J,ee);return function(e){var i=void 0!==e.getAttributeNode&&e.getAttributeNode("id");return i&&i.value===t}},n.find.ID=function(e,t){if(void 0!==t.getElementById&&m){var i,n,o,r=t.getElementById(e);if(r){if((i=r.getAttributeNode("id"))&&i.value===e)return[r];for(o=t.getElementsByName(e),n=0;r=o[n++];)if((i=r.getAttributeNode("id"))&&i.value===e)return[r]}return[]}}),n.find.TAG=i.getElementsByTagName?function(e,t){return void 0!==t.getElementsByTagName?t.getElementsByTagName(e):i.qsa?t.querySelectorAll(e):void 0}:function(e,t){var i,n=[],o=0,r=t.getElementsByTagName(e);if("*"===e){for(;i=r[o++];)1===i.nodeType&&n.push(i);return n}return r},n.find.CLASS=i.getElementsByClassName&&function(e,t){if(void 0!==t.getElementsByClassName&&m)return t.getElementsByClassName(e)},w=[],g=[],(i.qsa=X.test(u.querySelectorAll))&&(ce((function(e){p.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&g.push("[*^$]="+L+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||g.push("\\["+L+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+v+"-]").length||g.push("~="),e.querySelectorAll(":checked").length||g.push(":checked"),e.querySelectorAll("a#"+v+"+*").length||g.push(".#.+[+~]")})),ce((function(e){e.innerHTML="";var t=u.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&g.push("name"+L+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&g.push(":enabled",":disabled"),p.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&g.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),g.push(",.*:")}))),(i.matchesSelector=X.test(F=p.matches||p.webkitMatchesSelector||p.mozMatchesSelector||p.oMatchesSelector||p.msMatchesSelector))&&ce((function(e){i.disconnectedMatch=F.call(e,"*"),F.call(e,"[s!='']:x"),w.push("!=",O)})),g=g.length&&new RegExp(g.join("|")),w=w.length&&new RegExp(w.join("|")),t=X.test(p.compareDocumentPosition),b=t||X.test(p.contains)?function(e,t){var i=9===e.nodeType?e.documentElement:e,n=t&&t.parentNode;return e===n||!(!n||1!==n.nodeType||!(i.contains?i.contains(n):e.compareDocumentPosition&&16&e.compareDocumentPosition(n)))}:function(e,t){if(t)for(;t=t.parentNode;)if(t===e)return!0;return!1},N=t?function(e,t){if(e===t)return d=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)===(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!i.sortDetached&&t.compareDocumentPosition(e)===n?e===u||e.ownerDocument===y&&b(y,e)?-1:t===u||t.ownerDocument===y&&b(y,t)?1:h?T(h,e)-T(h,t):0:4&n?-1:1)}:function(e,t){if(e===t)return d=!0,0;var i,n=0,o=e.parentNode,r=t.parentNode,a=[e],s=[t];if(!o||!r)return e===u?-1:t===u?1:o?-1:r?1:h?T(h,e)-T(h,t):0;if(o===r)return le(e,t);for(i=e;i=i.parentNode;)a.unshift(i);for(i=t;i=i.parentNode;)s.unshift(i);for(;a[n]===s[n];)n++;return n?le(a[n],s[n]):a[n]===y?-1:s[n]===y?1:0},u):u},re.matches=function(e,t){return re(e,null,null,t)},re.matchesSelector=function(e,t){if((e.ownerDocument||e)!==u&&f(e),t=t.replace(j,"='$1']"),i.matchesSelector&&m&&!E[t+" "]&&(!w||!w.test(t))&&(!g||!g.test(t)))try{var n=F.call(e,t);if(n||i.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){}return re(t,u,null,[e]).length>0},re.contains=function(e,t){return(e.ownerDocument||e)!==u&&f(e),b(e,t)},re.attr=function(e,t){(e.ownerDocument||e)!==u&&f(e);var o=n.attrHandle[t.toLowerCase()],r=o&&S.call(n.attrHandle,t.toLowerCase())?o(e,t,!m):void 0;return void 0!==r?r:i.attributes||!m?e.getAttribute(t):(r=e.getAttributeNode(t))&&r.specified?r.value:null},re.escape=function(e){return(e+"").replace(te,ie)},re.error=function(e){throw new Error("Syntax error, unrecognized expression: "+e)},re.uniqueSort=function(e){var t,n=[],o=0,r=0;if(d=!i.detectDuplicates,h=!i.sortStable&&e.slice(0),e.sort(N),d){for(;t=e[r++];)t===e[r]&&(o=n.push(r));for(;o--;)e.splice(n[o],1)}return h=null,e},o=re.getText=function(e){var t,i="",n=0,r=e.nodeType;if(r){if(1===r||9===r||11===r){if("string"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)i+=o(e)}else if(3===r||4===r)return e.nodeValue}else for(;t=e[n++];)i+=o(t);return i},n=re.selectors={cacheLength:50,createPseudo:se,match:$,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(J,ee),e[3]=(e[3]||e[4]||e[5]||"").replace(J,ee),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||re.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&re.error(e[0]),e},PSEUDO:function(e){var t,i=!e[6]&&e[2];return $.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":i&&W.test(i)&&(t=a(i,!0))&&(t=i.indexOf(")",i.length-t)-i.length)&&(e[0]=e[0].slice(0,t),e[2]=i.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(J,ee).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=x[e+" "];return t||(t=new RegExp("(^|"+L+")"+e+"("+L+"|$)"))&&x(e,(function(e){return t.test("string"==typeof e.className&&e.className||void 0!==e.getAttribute&&e.getAttribute("class")||"")}))},ATTR:function(e,t,i){return function(n){var o=re.attr(n,e);return null==o?"!="===t:!t||(o+="","="===t?o===i:"!="===t?o!==i:"^="===t?i&&0===o.indexOf(i):"*="===t?i&&o.indexOf(i)>-1:"$="===t?i&&o.slice(-i.length)===i:"~="===t?(" "+o.replace(P," ")+" ").indexOf(i)>-1:"|="===t&&(o===i||o.slice(0,i.length+1)===i+"-"))}},CHILD:function(e,t,i,n,o){var r="nth"!==e.slice(0,3),a="last"!==e.slice(-4),s="of-type"===t;return 1===n&&0===o?function(e){return!!e.parentNode}:function(t,i,c){var l,h,d,f,u,p,m=r!==a?"nextSibling":"previousSibling",g=t.parentNode,w=s&&t.nodeName.toLowerCase(),F=!c&&!s,b=!1;if(g){if(r){for(;m;){for(f=t;f=f[m];)if(s?f.nodeName.toLowerCase()===w:1===f.nodeType)return!1;p=m="only"===e&&!p&&"nextSibling"}return!0}if(p=[a?g.firstChild:g.lastChild],a&&F){for(b=(u=(l=(h=(d=(f=g)[v]||(f[v]={}))[f.uniqueID]||(d[f.uniqueID]={}))[e]||[])[0]===_&&l[1])&&l[2],f=u&&g.childNodes[u];f=++u&&f&&f[m]||(b=u=0)||p.pop();)if(1===f.nodeType&&++b&&f===t){h[e]=[_,u,b];break}}else if(F&&(b=u=(l=(h=(d=(f=t)[v]||(f[v]={}))[f.uniqueID]||(d[f.uniqueID]={}))[e]||[])[0]===_&&l[1]),!1===b)for(;(f=++u&&f&&f[m]||(b=u=0)||p.pop())&&((s?f.nodeName.toLowerCase()!==w:1!==f.nodeType)||!++b||(F&&((h=(d=f[v]||(f[v]={}))[f.uniqueID]||(d[f.uniqueID]={}))[e]=[_,b]),f!==t)););return(b-=o)===n||b%n==0&&b/n>=0}}},PSEUDO:function(e,t){var i,o=n.pseudos[e]||n.setFilters[e.toLowerCase()]||re.error("unsupported pseudo: "+e);return o[v]?o(t):o.length>1?(i=[e,e,"",t],n.setFilters.hasOwnProperty(e.toLowerCase())?se((function(e,i){for(var n,r=o(e,t),a=r.length;a--;)e[n=T(e,r[a])]=!(i[n]=r[a])})):function(e){return o(e,0,i)}):o}},pseudos:{not:se((function(e){var t=[],i=[],n=s(e.replace(q,"$1"));return n[v]?se((function(e,t,i,o){for(var r,a=n(e,null,o,[]),s=e.length;s--;)(r=a[s])&&(e[s]=!(t[s]=r))})):function(e,o,r){return t[0]=e,n(t,null,r,i),t[0]=null,!i.pop()}})),has:se((function(e){return function(t){return re(e,t).length>0}})),contains:se((function(e){return e=e.replace(J,ee),function(t){return(t.textContent||t.innerText||o(t)).indexOf(e)>-1}})),lang:se((function(e){return G.test(e||"")||re.error("unsupported lang: "+e),e=e.replace(J,ee).toLowerCase(),function(t){var i;do{if(i=m?t.lang:t.getAttribute("xml:lang")||t.getAttribute("lang"))return(i=i.toLowerCase())===e||0===i.indexOf(e+"-")}while((t=t.parentNode)&&1===t.nodeType);return!1}})),target:function(t){var i=e.location&&e.location.hash;return i&&i.slice(1)===t.id},root:function(e){return e===p},focus:function(e){return e===u.activeElement&&(!u.hasFocus||u.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:fe(!1),disabled:fe(!0),checked:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&!!e.checked||"option"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,!0===e.selected},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeType<6)return!1;return!0},parent:function(e){return!n.pseudos.empty(e)},header:function(e){return K.test(e.nodeName)},input:function(e){return Z.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&"button"===e.type||"button"===t},text:function(e){var t;return"input"===e.nodeName.toLowerCase()&&"text"===e.type&&(null==(t=e.getAttribute("type"))||"text"===t.toLowerCase())},first:ue((function(){return[0]})),last:ue((function(e,t){return[t-1]})),eq:ue((function(e,t,i){return[i<0?i+t:i]})),even:ue((function(e,t){for(var i=0;i=0;)e.push(n);return e})),gt:ue((function(e,t,i){for(var n=i<0?i+t:i;++n1?function(t,i,n){for(var o=e.length;o--;)if(!e[o](t,i,n))return!1;return!0}:e[0]}function be(e,t,i,n,o){for(var r,a=[],s=0,c=e.length,l=null!=t;s-1&&(r[l]=!(a[l]=d))}}else w=be(w===a?w.splice(p,w.length):w),o?o(null,a,w,c):A.apply(a,w)}))}function ye(e){for(var t,i,o,r=e.length,a=n.relative[e[0].type],s=a||n.relative[" "],c=a?1:0,h=we((function(e){return e===t}),s,!0),d=we((function(e){return T(t,e)>-1}),s,!0),f=[function(e,i,n){var o=!a&&(n||i!==l)||((t=i).nodeType?h(e,i,n):d(e,i,n));return t=null,o}];c1&&Fe(f),c>1&&ge(e.slice(0,c-1).concat({value:" "===e[c-2].type?"*":""})).replace(q,"$1"),i,c0,o=e.length>0,r=function(r,a,s,c,h){var d,p,g,w=0,F="0",b=r&&[],v=[],y=l,C=r||o&&n.find.TAG("*",h),x=_+=null==y?1:Math.random()||.1,k=C.length;for(h&&(l=a===u||a||h);F!==k&&null!=(d=C[F]);F++){if(o&&d){for(p=0,a||d.ownerDocument===u||(f(d),s=!m);g=e[p++];)if(g(d,a||u,s)){c.push(d);break}h&&(_=x)}i&&((d=!g&&d)&&w--,r&&b.push(d))}if(w+=F,i&&F!==w){for(p=0;g=t[p++];)g(b,v,a,s);if(r){if(w>0)for(;F--;)b[F]||v[F]||(v[F]=z.call(c));v=be(v)}A.apply(c,v),h&&!r&&v.length>0&&w+t.length>1&&re.uniqueSort(c)}return h&&(_=x,l=y),b};return i?se(r):r}(r,o)),s.selector=e}return s},c=re.select=function(e,t,i,o){var r,c,l,h,d,f="function"==typeof e&&e,u=!o&&a(e=f.selector||e);if(i=i||[],1===u.length){if((c=u[0]=u[0].slice(0)).length>2&&"ID"===(l=c[0]).type&&9===t.nodeType&&m&&n.relative[c[1].type]){if(!(t=(n.find.ID(l.matches[0].replace(J,ee),t)||[])[0]))return i;f&&(t=t.parentNode),e=e.slice(c.shift().value.length)}for(r=$.needsContext.test(e)?0:c.length;r--&&(l=c[r],!n.relative[h=l.type]);)if((d=n.find[h])&&(o=d(l.matches[0].replace(J,ee),Q.test(c[0].type)&&pe(t.parentNode)||t))){if(c.splice(r,1),!(e=o.length&&ge(c)))return A.apply(i,o),i;break}}return(f||s(e,u))(o,t,!m,i,!t||Q.test(e)&&pe(t.parentNode)||t),i},i.sortStable=v.split("").sort(N).join("")===v,i.detectDuplicates=!!d,f(),re}(window);_n.find=kn,_n.expr=kn.selectors,_n.expr[":"]=_n.expr.pseudos,_n.uniqueSort=_n.unique=kn.uniqueSort,_n.text=kn.getText,_n.isXMLDoc=kn.isXML,_n.contains=kn.contains,_n.escapeSelector=kn.escape;var En=function(e,t,i){for(var n=[],o=void 0!==i;(e=e[t])&&9!==e.nodeType;)if(1===e.nodeType){if(o&&_n(e).is(i))break;n.push(e)}return n},Nn=function(e,t){for(var i=[];e;e=e.nextSibling)1===e.nodeType&&e!==t&&i.push(e);return i},Sn=_n.expr.match.needsContext;function In(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()}var zn=/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function Dn(e,t,i){return gn(t)?_n.grep(e,(function(e,n){return!!t.call(e,n,e)!==i})):t.nodeType?_n.grep(e,(function(e){return e===t!==i})):"string"!=typeof t?_n.grep(e,(function(e){return ln.call(t,e)>-1!==i})):_n.filter(t,e,i)}_n.filter=function(e,t,i){var n=t[0];return i&&(e=":not("+e+")"),1===t.length&&1===n.nodeType?_n.find.matchesSelector(n,e)?[n]:[]:_n.find.matches(e,_n.grep(t,(function(e){return 1===e.nodeType})))},_n.fn.extend({find:function(e){var t,i,n=this.length,o=this;if("string"!=typeof e)return this.pushStack(_n(e).filter((function(){for(t=0;t1?_n.uniqueSort(i):i},filter:function(e){return this.pushStack(Dn(this,e||[],!1))},not:function(e){return this.pushStack(Dn(this,e||[],!0))},is:function(e){return!!Dn(this,"string"==typeof e&&Sn.test(e)?_n(e):e||[],!1).length}});var An,Mn=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/;(_n.fn.init=function(e,t,i){var n,o;if(!e)return this;if(i=i||An,"string"==typeof e){if(!(n="<"===e[0]&&">"===e[e.length-1]&&e.length>=3?[null,e,null]:Mn.exec(e))||!n[1]&&t)return!t||t.jquery?(t||i).find(e):this.constructor(t).find(e);if(n[1]){if(t=t instanceof _n?t[0]:t,_n.merge(this,_n.parseHTML(n[1],t&&t.nodeType?t.ownerDocument||t:on,!0)),zn.test(n[1])&&_n.isPlainObject(t))for(n in t)gn(this[n])?this[n](t[n]):this.attr(n,t[n]);return this}return(o=on.getElementById(n[2]))&&(this[0]=o,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):gn(e)?void 0!==i.ready?i.ready(e):e(_n):_n.makeArray(e,this)}).prototype=_n.fn,An=_n(on);var Tn=/^(?:parents|prev(?:Until|All))/,Rn={children:!0,contents:!0,next:!0,prev:!0};function Ln(e,t){for(;(e=e[t])&&1!==e.nodeType;);return e}_n.fn.extend({has:function(e){var t=_n(e,this),i=t.length;return this.filter((function(){for(var e=0;e-1:1===i.nodeType&&_n.find.matchesSelector(i,e))){r.push(i);break}return this.pushStack(r.length>1?_n.uniqueSort(r):r)},index:function(e){return e?"string"==typeof e?ln.call(_n(e),this[0]):ln.call(this,e.jquery?e[0]:e):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){return this.pushStack(_n.uniqueSort(_n.merge(this.get(),_n(e,t))))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}}),_n.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return En(e,"parentNode")},parentsUntil:function(e,t,i){return En(e,"parentNode",i)},next:function(e){return Ln(e,"nextSibling")},prev:function(e){return Ln(e,"previousSibling")},nextAll:function(e){return En(e,"nextSibling")},prevAll:function(e){return En(e,"previousSibling")},nextUntil:function(e,t,i){return En(e,"nextSibling",i)},prevUntil:function(e,t,i){return En(e,"previousSibling",i)},siblings:function(e){return Nn((e.parentNode||{}).firstChild,e)},children:function(e){return Nn(e.firstChild)},contents:function(e){return In(e,"iframe")?e.contentDocument:(In(e,"template")&&(e=e.content||e),_n.merge([],e.childNodes))}},(function(e,t){_n.fn[e]=function(i,n){var o=_n.map(this,t,i);return"Until"!==e.slice(-5)&&(n=i),n&&"string"==typeof n&&(o=_n.filter(n,o)),this.length>1&&(Rn[e]||_n.uniqueSort(o),Tn.test(e)&&o.reverse()),this.pushStack(o)}}));var Bn=/[^\x20\t\r\n\f]+/g;function Hn(e){return e}function On(e){throw e}function Pn(e,t,i,n){var o;try{e&&gn(o=e.promise)?o.call(e).done(t).fail(i):e&&gn(o=e.then)?o.call(e,t,i):t.apply(void 0,[e].slice(n))}catch(e){i.apply(void 0,[e])}}_n.Callbacks=function(e){e="string"==typeof e?function(e){var t={};return _n.each(e.match(Bn)||[],(function(e,i){t[i]=!0})),t}(e):_n.extend({},e);var t,i,n,o,r=[],a=[],s=-1,c=function(){for(o=o||e.once,n=t=!0;a.length;s=-1)for(i=a.shift();++s-1;)r.splice(i,1),i<=s&&s--})),this},has:function(e){return e?_n.inArray(e,r)>-1:r.length>0},empty:function(){return r&&(r=[]),this},disable:function(){return o=a=[],r=i="",this},disabled:function(){return!r},lock:function(){return o=a=[],i||t||(r=i=""),this},locked:function(){return!!o},fireWith:function(e,i){return o||(i=[e,(i=i||[]).slice?i.slice():i],a.push(i),t||c()),this},fire:function(){return l.fireWith(this,arguments),this},fired:function(){return!!n}};return l},_n.extend({Deferred:function(e){var t=[["notify","progress",_n.Callbacks("memory"),_n.Callbacks("memory"),2],["resolve","done",_n.Callbacks("once memory"),_n.Callbacks("once memory"),0,"resolved"],["reject","fail",_n.Callbacks("once memory"),_n.Callbacks("once memory"),1,"rejected"]],i="pending",n={state:function(){return i},always:function(){return o.done(arguments).fail(arguments),this},catch:function(e){return n.then(null,e)},pipe:function(){var e=arguments;return _n.Deferred((function(i){_n.each(t,(function(t,n){var r=gn(e[n[4]])&&e[n[4]];o[n[1]]((function(){var e=r&&r.apply(this,arguments);e&&gn(e.promise)?e.promise().progress(i.notify).done(i.resolve).fail(i.reject):i[n[0]+"With"](this,r?[e]:arguments)}))})),e=null})).promise()},then:function(e,i,n){var o=0;function r(e,t,i,n){return function(){var a=this,s=arguments,c=function(){var c,l;if(!(e=o&&(i!==On&&(a=void 0,s=[n]),t.rejectWith(a,s))}};e?l():(_n.Deferred.getStackHook&&(l.stackTrace=_n.Deferred.getStackHook()),window.setTimeout(l))}}return _n.Deferred((function(o){t[0][3].add(r(0,o,gn(n)?n:Hn,o.notifyWith)),t[1][3].add(r(0,o,gn(e)?e:Hn)),t[2][3].add(r(0,o,gn(i)?i:On))})).promise()},promise:function(e){return null!=e?_n.extend(e,n):n}},o={};return _n.each(t,(function(e,r){var a=r[2],s=r[5];n[r[1]]=a.add,s&&a.add((function(){i=s}),t[3-e][2].disable,t[3-e][3].disable,t[0][2].lock,t[0][3].lock),a.add(r[3].fire),o[r[0]]=function(){return o[r[0]+"With"](this===o?void 0:this,arguments),this},o[r[0]+"With"]=a.fireWith})),n.promise(o),e&&e.call(o,o),o},when:function(e){var t=arguments.length,i=t,n=Array(i),o=an.call(arguments),r=_n.Deferred(),a=function(e){return function(i){n[e]=this,o[e]=arguments.length>1?an.call(arguments):i,--t||r.resolveWith(n,o)}};if(t<=1&&(Pn(e,r.done(a(i)).resolve,r.reject,!t),"pending"===r.state()||gn(o[i]&&o[i].then)))return r.then();for(;i--;)Pn(o[i],a(i),r.reject);return r.promise()}});var qn=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;_n.Deferred.exceptionHook=function(e,t){window.console&&window.console.warn&&e&&qn.test(e.name)&&window.console.warn("jQuery.Deferred exception: "+e.message,e.stack,t)},_n.readyException=function(e){window.setTimeout((function(){throw e}))};var Vn=_n.Deferred();function Un(){on.removeEventListener("DOMContentLoaded",Un),window.removeEventListener("load",Un),_n.ready()}_n.fn.ready=function(e){return Vn.then(e).catch((function(e){_n.readyException(e)})),this},_n.extend({isReady:!1,readyWait:1,ready:function(e){(!0===e?--_n.readyWait:_n.isReady)||(_n.isReady=!0,!0!==e&&--_n.readyWait>0||Vn.resolveWith(on,[_n]))}}),_n.ready.then=Vn.then,"complete"===on.readyState||"loading"!==on.readyState&&!on.documentElement.doScroll?window.setTimeout(_n.ready):(on.addEventListener("DOMContentLoaded",Un),window.addEventListener("load",Un));var jn=function(e,t,i,n,o,r,a){var s=0,c=e.length,l=null==i;if("object"===vn(i))for(s in o=!0,i)jn(e,t,s,i[s],!0,r,a);else if(void 0!==n&&(o=!0,gn(n)||(a=!0),l&&(a?(t.call(e,n),t=null):(l=t,t=function(e,t,i){return l.call(_n(e),i)})),t))for(;s1,null,!0)},removeData:function(e){return this.each((function(){Qn.remove(this,e)}))}}),_n.extend({queue:function(e,t,i){var n;if(e)return t=(t||"fx")+"queue",n=Yn.get(e,t),i&&(!n||Array.isArray(i)?n=Yn.access(e,t,_n.makeArray(i)):n.push(i)),n||[]},dequeue:function(e,t){t=t||"fx";var i=_n.queue(e,t),n=i.length,o=i.shift(),r=_n._queueHooks(e,t);"inprogress"===o&&(o=i.shift(),n--),o&&("fx"===t&&i.unshift("inprogress"),delete r.stop,o.call(e,(function(){_n.dequeue(e,t)}),r)),!n&&r&&r.empty.fire()},_queueHooks:function(e,t){var i=t+"queueHooks";return Yn.get(e,i)||Yn.access(e,i,{empty:_n.Callbacks("once memory").add((function(){Yn.remove(e,[t+"queue",i])}))})}}),_n.fn.extend({queue:function(e,t){var i=2;return"string"!=typeof e&&(t=e,e="fx",i--),arguments.length\x20\t\r\n\f]+)/i,uo=/^$|^module$|\/(?:java|ecma)script/i,po={option:[1,""],thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function mo(e,t){var i;return i=void 0!==e.getElementsByTagName?e.getElementsByTagName(t||"*"):void 0!==e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&In(e,t)?_n.merge([e],i):i}function go(e,t){for(var i=0,n=e.length;i-1)o&&o.push(r);else if(l=_n.contains(r.ownerDocument,r),a=mo(d.appendChild(r),"script"),l&&go(a),i)for(h=0;r=a[h++];)uo.test(r.type||"")&&i.push(r);return d}!function(){var e=on.createDocumentFragment().appendChild(on.createElement("div")),t=on.createElement("input");t.setAttribute("type","radio"),t.setAttribute("checked","checked"),t.setAttribute("name","t"),e.appendChild(t),mn.checkClone=e.cloneNode(!0).cloneNode(!0).lastChild.checked,e.innerHTML="",mn.noCloneChecked=!!e.cloneNode(!0).lastChild.defaultValue}();var bo=on.documentElement,vo=/^key/,yo=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,_o=/^([^.]*)(?:\.(.+)|)/;function Co(){return!0}function xo(){return!1}function ko(){try{return on.activeElement}catch(e){}}function Eo(e,t,i,n,o,r){var a,s;if("object"==typeof t){for(s in"string"!=typeof i&&(n=n||i,i=void 0),t)Eo(e,s,i,n,t[s],r);return e}if(null==n&&null==o?(o=i,n=i=void 0):null==o&&("string"==typeof i?(o=n,n=void 0):(o=n,n=i,i=void 0)),!1===o)o=xo;else if(!o)return e;return 1===r&&(a=o,o=function(e){return _n().off(e),a.apply(this,arguments)},o.guid=a.guid||(a.guid=_n.guid++)),e.each((function(){_n.event.add(this,t,o,n,i)}))}_n.event={global:{},add:function(e,t,i,n,o){var r,a,s,c,l,h,d,f,u,p,m,g=Yn.get(e);if(g)for(i.handler&&(i=(r=i).handler,o=r.selector),o&&_n.find.matchesSelector(bo,o),i.guid||(i.guid=_n.guid++),(c=g.events)||(c=g.events={}),(a=g.handle)||(a=g.handle=function(t){return void 0!==_n&&_n.event.triggered!==t.type?_n.event.dispatch.apply(e,arguments):void 0}),l=(t=(t||"").match(Bn)||[""]).length;l--;)u=m=(s=_o.exec(t[l])||[])[1],p=(s[2]||"").split(".").sort(),u&&(d=_n.event.special[u]||{},u=(o?d.delegateType:d.bindType)||u,d=_n.event.special[u]||{},h=_n.extend({type:u,origType:m,data:n,handler:i,guid:i.guid,selector:o,needsContext:o&&_n.expr.match.needsContext.test(o),namespace:p.join(".")},r),(f=c[u])||((f=c[u]=[]).delegateCount=0,d.setup&&!1!==d.setup.call(e,n,p,a)||e.addEventListener&&e.addEventListener(u,a)),d.add&&(d.add.call(e,h),h.handler.guid||(h.handler.guid=i.guid)),o?f.splice(f.delegateCount++,0,h):f.push(h),_n.event.global[u]=!0)},remove:function(e,t,i,n,o){var r,a,s,c,l,h,d,f,u,p,m,g=Yn.hasData(e)&&Yn.get(e);if(g&&(c=g.events)){for(l=(t=(t||"").match(Bn)||[""]).length;l--;)if(u=m=(s=_o.exec(t[l])||[])[1],p=(s[2]||"").split(".").sort(),u){for(d=_n.event.special[u]||{},f=c[u=(n?d.delegateType:d.bindType)||u]||[],s=s[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),a=r=f.length;r--;)h=f[r],!o&&m!==h.origType||i&&i.guid!==h.guid||s&&!s.test(h.namespace)||n&&n!==h.selector&&("**"!==n||!h.selector)||(f.splice(r,1),h.selector&&f.delegateCount--,d.remove&&d.remove.call(e,h));a&&!f.length&&(d.teardown&&!1!==d.teardown.call(e,p,g.handle)||_n.removeEvent(e,u,g.handle),delete c[u])}else for(u in c)_n.event.remove(e,u+t[l],i,n,!0);_n.isEmptyObject(c)&&Yn.remove(e,"handle events")}},dispatch:function(e){var t,i,n,o,r,a,s=_n.event.fix(e),c=new Array(arguments.length),l=(Yn.get(this,"events")||{})[s.type]||[],h=_n.event.special[s.type]||{};for(c[0]=s,t=1;t=1))for(;l!==this;l=l.parentNode||this)if(1===l.nodeType&&("click"!==e.type||!0!==l.disabled)){for(r=[],a={},i=0;i-1:_n.find(o,this,null,[l]).length),a[o]&&r.push(n);r.length&&s.push({elem:l,handlers:r})}return l=this,c\x20\t\r\n\f]*)[^>]*)\/>/gi,So=/\s*$/g;function Do(e,t){return In(e,"table")&&In(11!==t.nodeType?t:t.firstChild,"tr")&&_n(e).children("tbody")[0]||e}function Ao(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function Mo(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function To(e,t){var i,n,o,r,a,s,c,l;if(1===t.nodeType){if(Yn.hasData(e)&&(r=Yn.access(e),a=Yn.set(t,r),l=r.events))for(o in delete a.handle,a.events={},l)for(i=0,n=l[o].length;i1&&"string"==typeof u&&!mn.checkClone&&Io.test(u))return e.each((function(o){var r=e.eq(o);p&&(t[0]=u.call(this,o,r.html())),Lo(r,t,i,n)}));if(d&&(r=(o=Fo(t,e[0].ownerDocument,!1,e,n)).firstChild,1===o.childNodes.length&&(o=r),r||n)){for(s=(a=_n.map(mo(o,"script"),Ao)).length;h")},clone:function(e,t,i){var n,o,r,a,s=e.cloneNode(!0),c=_n.contains(e.ownerDocument,e);if(!(mn.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||_n.isXMLDoc(e)))for(a=mo(s),n=0,o=(r=mo(e)).length;n0&&go(a,!c&&mo(e,"script")),s},cleanData:function(e){for(var t,i,n,o=_n.event.special,r=0;void 0!==(i=e[r]);r++)if(Kn(i)){if(t=i[Yn.expando]){if(t.events)for(n in t.events)o[n]?_n.event.remove(i,n):_n.removeEvent(i,n,t.handle);i[Yn.expando]=void 0}i[Qn.expando]&&(i[Qn.expando]=void 0)}}}),_n.fn.extend({detach:function(e){return Bo(this,e,!0)},remove:function(e){return Bo(this,e)},text:function(e){return jn(this,(function(e){return void 0===e?_n.text(this):this.empty().each((function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=e)}))}),null,e,arguments.length)},append:function(){return Lo(this,arguments,(function(e){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||Do(this,e).appendChild(e)}))},prepend:function(){return Lo(this,arguments,(function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=Do(this,e);t.insertBefore(e,t.firstChild)}}))},before:function(){return Lo(this,arguments,(function(e){this.parentNode&&this.parentNode.insertBefore(e,this)}))},after:function(){return Lo(this,arguments,(function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)}))},empty:function(){for(var e,t=0;null!=(e=this[t]);t++)1===e.nodeType&&(_n.cleanData(mo(e,!1)),e.textContent="");return this},clone:function(e,t){return e=null!=e&&e,t=null==t?e:t,this.map((function(){return _n.clone(this,e,t)}))},html:function(e){return jn(this,(function(e){var t=this[0]||{},i=0,n=this.length;if(void 0===e&&1===t.nodeType)return t.innerHTML;if("string"==typeof e&&!So.test(e)&&!po[(fo.exec(e)||["",""])[1].toLowerCase()]){e=_n.htmlPrefilter(e);try{for(;i=0&&(c+=Math.max(0,Math.ceil(e["offset"+t[0].toUpperCase()+t.slice(1)]-r-c-s-.5))),c}function er(e,t,i){var n=Oo(e),o=qo(e,t,n),r="border-box"===_n.css(e,"boxSizing",!1,n),a=r;if(Ho.test(o)){if(!i)return o;o="auto"}return a=a&&(mn.boxSizingReliable()||o===e.style[t]),("auto"===o||!parseFloat(o)&&"inline"===_n.css(e,"display",!1,n))&&(o=e["offset"+t[0].toUpperCase()+t.slice(1)],a=!0),(o=parseFloat(o)||0)+Jo(e,t,i||(r?"border":"content"),a,n,o)+"px"}_n.extend({cssHooks:{opacity:{get:function(e,t){if(t){var i=qo(e,"opacity");return""===i?"1":i}}}},cssNumber:{animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{},style:function(e,t,i,n){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var o,r,a,s=Zn(t),c=Go.test(t),l=e.style;if(c||(t=Yo(s)),a=_n.cssHooks[t]||_n.cssHooks[s],void 0===i)return a&&"get"in a&&void 0!==(o=a.get(e,!1,n))?o:l[t];"string"===(r=typeof i)&&(o=no.exec(i))&&o[1]&&(i=function(e,t,i,n){var o,r,a=20,s=n?function(){return n.cur()}:function(){return _n.css(e,t,"")},c=s(),l=i&&i[3]||(_n.cssNumber[t]?"":"px"),h=(_n.cssNumber[t]||"px"!==l&&+c)&&no.exec(_n.css(e,t));if(h&&h[3]!==l){for(c/=2,l=l||h[3],h=+c||1;a--;)_n.style(e,t,h+l),(1-r)*(1-(r=s()/c||.5))<=0&&(a=0),h/=r;h*=2,_n.style(e,t,h+l),i=i||[]}return i&&(h=+h||+c||0,o=i[1]?h+(i[1]+1)*i[2]:+i[2],n&&(n.unit=l,n.start=h,n.end=o)),o}(e,t,o),r="number"),null!=i&&i==i&&("number"===r&&(i+=o&&o[3]||(_n.cssNumber[s]?"":"px")),mn.clearCloneStyle||""!==i||0!==t.indexOf("background")||(l[t]="inherit"),a&&"set"in a&&void 0===(i=a.set(e,i,n))||(c?l.setProperty(t,i):l[t]=i))}},css:function(e,t,i,n){var o,r,a,s=Zn(t);return Go.test(t)||(t=Yo(s)),(a=_n.cssHooks[t]||_n.cssHooks[s])&&"get"in a&&(o=a.get(e,!0,i)),void 0===o&&(o=qo(e,t,n)),"normal"===o&&t in Zo&&(o=Zo[t]),""===i||i?(r=parseFloat(o),!0===i||isFinite(r)?r||0:o):o}}),_n.each(["height","width"],(function(e,t){_n.cssHooks[t]={get:function(e,i,n){if(i)return!Wo.test(_n.css(e,"display"))||e.getClientRects().length&&e.getBoundingClientRect().width?er(e,t,n):ao(e,$o,(function(){return er(e,t,n)}))},set:function(e,i,n){var o,r=Oo(e),a="border-box"===_n.css(e,"boxSizing",!1,r),s=n&&Jo(e,t,n,a,r);return a&&mn.scrollboxSize()===r.position&&(s-=Math.ceil(e["offset"+t[0].toUpperCase()+t.slice(1)]-parseFloat(r[t])-Jo(e,t,"border",!1,r)-.5)),s&&(o=no.exec(i))&&"px"!==(o[3]||"px")&&(e.style[t]=i,i=_n.css(e,t)),Qo(0,i,s)}}})),_n.cssHooks.marginLeft=Vo(mn.reliableMarginLeft,(function(e,t){if(t)return(parseFloat(qo(e,"marginLeft"))||e.getBoundingClientRect().left-ao(e,{marginLeft:0},(function(){return e.getBoundingClientRect().left})))+"px"})),_n.each({margin:"",padding:"",border:"Width"},(function(e,t){_n.cssHooks[e+t]={expand:function(i){for(var n=0,o={},r="string"==typeof i?i.split(" "):[i];n<4;n++)o[e+oo[n]+t]=r[n]||r[n-2]||r[0];return o}},"margin"!==e&&(_n.cssHooks[e+t].set=Qo)})),_n.fn.extend({css:function(e,t){return jn(this,(function(e,t,i){var n,o,r={},a=0;if(Array.isArray(t)){for(n=Oo(e),o=t.length;a1)}}),_n.fn.delay=function(e,t){return e=_n.fx&&_n.fx.speeds[e]||e,t=t||"fx",this.queue(t,(function(t,i){var n=window.setTimeout(t,e);i.stop=function(){window.clearTimeout(n)}}))},Uo=on.createElement("input"),jo=on.createElement("select").appendChild(on.createElement("option")),Uo.type="checkbox",mn.checkOn=""!==Uo.value,mn.optSelected=jo.selected,(Uo=on.createElement("input")).value="t",Uo.type="radio",mn.radioValue="t"===Uo.value;var tr,ir=_n.expr.attrHandle;_n.fn.extend({attr:function(e,t){return jn(this,_n.attr,e,t,arguments.length>1)},removeAttr:function(e){return this.each((function(){_n.removeAttr(this,e)}))}}),_n.extend({attr:function(e,t,i){var n,o,r=e.nodeType;if(3!==r&&8!==r&&2!==r)return void 0===e.getAttribute?_n.prop(e,t,i):(1===r&&_n.isXMLDoc(e)||(o=_n.attrHooks[t.toLowerCase()]||(_n.expr.match.bool.test(t)?tr:void 0)),void 0!==i?null===i?void _n.removeAttr(e,t):o&&"set"in o&&void 0!==(n=o.set(e,i,t))?n:(e.setAttribute(t,i+""),i):o&&"get"in o&&null!==(n=o.get(e,t))?n:null==(n=_n.find.attr(e,t))?void 0:n)},attrHooks:{type:{set:function(e,t){if(!mn.radioValue&&"radio"===t&&In(e,"input")){var i=e.value;return e.setAttribute("type",t),i&&(e.value=i),t}}}},removeAttr:function(e,t){var i,n=0,o=t&&t.match(Bn);if(o&&1===e.nodeType)for(;i=o[n++];)e.removeAttribute(i)}}),tr={set:function(e,t,i){return!1===t?_n.removeAttr(e,i):e.setAttribute(i,i),i}},_n.each(_n.expr.match.bool.source.match(/\w+/g),(function(e,t){var i=ir[t]||_n.find.attr;ir[t]=function(e,t,n){var o,r,a=t.toLowerCase();return n||(r=ir[a],ir[a]=o,o=null!=i(e,t,n)?a:null,ir[a]=r),o}}));var nr=/^(?:input|select|textarea|button)$/i,or=/^(?:a|area)$/i;function rr(e){return(e.match(Bn)||[]).join(" ")}function ar(e){return e.getAttribute&&e.getAttribute("class")||""}function sr(e){return Array.isArray(e)?e:"string"==typeof e&&e.match(Bn)||[]}_n.fn.extend({prop:function(e,t){return jn(this,_n.prop,e,t,arguments.length>1)},removeProp:function(e){return this.each((function(){delete this[_n.propFix[e]||e]}))}}),_n.extend({prop:function(e,t,i){var n,o,r=e.nodeType;if(3!==r&&8!==r&&2!==r)return 1===r&&_n.isXMLDoc(e)||(t=_n.propFix[t]||t,o=_n.propHooks[t]),void 0!==i?o&&"set"in o&&void 0!==(n=o.set(e,i,t))?n:e[t]=i:o&&"get"in o&&null!==(n=o.get(e,t))?n:e[t]},propHooks:{tabIndex:{get:function(e){var t=_n.find.attr(e,"tabindex");return t?parseInt(t,10):nr.test(e.nodeName)||or.test(e.nodeName)&&e.href?0:-1}}},propFix:{for:"htmlFor",class:"className"}}),mn.optSelected||(_n.propHooks.selected={get:function(e){var t=e.parentNode;return t&&t.parentNode&&t.parentNode.selectedIndex,null},set:function(e){var t=e.parentNode;t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex)}}),_n.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],(function(){_n.propFix[this.toLowerCase()]=this})),_n.fn.extend({addClass:function(e){var t,i,n,o,r,a,s,c=0;if(gn(e))return this.each((function(t){_n(this).addClass(e.call(this,t,ar(this)))}));if((t=sr(e)).length)for(;i=this[c++];)if(o=ar(i),n=1===i.nodeType&&" "+rr(o)+" "){for(a=0;r=t[a++];)n.indexOf(" "+r+" ")<0&&(n+=r+" ");o!==(s=rr(n))&&i.setAttribute("class",s)}return this},removeClass:function(e){var t,i,n,o,r,a,s,c=0;if(gn(e))return this.each((function(t){_n(this).removeClass(e.call(this,t,ar(this)))}));if(!arguments.length)return this.attr("class","");if((t=sr(e)).length)for(;i=this[c++];)if(o=ar(i),n=1===i.nodeType&&" "+rr(o)+" "){for(a=0;r=t[a++];)for(;n.indexOf(" "+r+" ")>-1;)n=n.replace(" "+r+" "," ");o!==(s=rr(n))&&i.setAttribute("class",s)}return this},toggleClass:function(e,t){var i=typeof e,n="string"===i||Array.isArray(e);return"boolean"==typeof t&&n?t?this.addClass(e):this.removeClass(e):gn(e)?this.each((function(i){_n(this).toggleClass(e.call(this,i,ar(this),t),t)})):this.each((function(){var t,o,r,a;if(n)for(o=0,r=_n(this),a=sr(e);t=a[o++];)r.hasClass(t)?r.removeClass(t):r.addClass(t);else void 0!==e&&"boolean"!==i||((t=ar(this))&&Yn.set(this,"__className__",t),this.setAttribute&&this.setAttribute("class",t||!1===e?"":Yn.get(this,"__className__")||""))}))},hasClass:function(e){var t,i,n=0;for(t=" "+e+" ";i=this[n++];)if(1===i.nodeType&&(" "+rr(ar(i))+" ").indexOf(t)>-1)return!0;return!1}});var cr=/\r/g;_n.fn.extend({val:function(e){var t,i,n,o=this[0];return arguments.length?(n=gn(e),this.each((function(i){var o;1===this.nodeType&&(null==(o=n?e.call(this,i,_n(this).val()):e)?o="":"number"==typeof o?o+="":Array.isArray(o)&&(o=_n.map(o,(function(e){return null==e?"":e+""}))),(t=_n.valHooks[this.type]||_n.valHooks[this.nodeName.toLowerCase()])&&"set"in t&&void 0!==t.set(this,o,"value")||(this.value=o))}))):o?(t=_n.valHooks[o.type]||_n.valHooks[o.nodeName.toLowerCase()])&&"get"in t&&void 0!==(i=t.get(o,"value"))?i:"string"==typeof(i=o.value)?i.replace(cr,""):null==i?"":i:void 0}}),_n.extend({valHooks:{option:{get:function(e){var t=_n.find.attr(e,"value");return null!=t?t:rr(_n.text(e))}},select:{get:function(e){var t,i,n,o=e.options,r=e.selectedIndex,a="select-one"===e.type,s=a?null:[],c=a?r+1:o.length;for(n=r<0?c:a?r:0;n-1)&&(i=!0);return i||(e.selectedIndex=-1),r}}}}),_n.each(["radio","checkbox"],(function(){_n.valHooks[this]={set:function(e,t){if(Array.isArray(t))return e.checked=_n.inArray(_n(e).val(),t)>-1}},mn.checkOn||(_n.valHooks[this].get=function(e){return null===e.getAttribute("value")?"on":e.value})})),mn.focusin="onfocusin"in window;var lr=/^(?:focusinfocus|focusoutblur)$/,hr=function(e){e.stopPropagation()};_n.extend(_n.event,{trigger:function(e,t,i,n){var o,r,a,s,c,l,h,d,f=[i||on],u=fn.call(e,"type")?e.type:e,p=fn.call(e,"namespace")?e.namespace.split("."):[];if(r=d=a=i=i||on,3!==i.nodeType&&8!==i.nodeType&&!lr.test(u+_n.event.triggered)&&(u.indexOf(".")>-1&&(p=u.split("."),u=p.shift(),p.sort()),c=u.indexOf(":")<0&&"on"+u,(e=e[_n.expando]?e:new _n.Event(u,"object"==typeof e&&e)).isTrigger=n?2:3,e.namespace=p.join("."),e.rnamespace=e.namespace?new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,e.result=void 0,e.target||(e.target=i),t=null==t?[e]:_n.makeArray(t,[e]),h=_n.event.special[u]||{},n||!h.trigger||!1!==h.trigger.apply(i,t))){if(!n&&!h.noBubble&&!wn(i)){for(s=h.delegateType||u,lr.test(s+u)||(r=r.parentNode);r;r=r.parentNode)f.push(r),a=r;a===(i.ownerDocument||on)&&f.push(a.defaultView||a.parentWindow||window)}for(o=0;(r=f[o++])&&!e.isPropagationStopped();)d=r,e.type=o>1?s:h.bindType||u,(l=(Yn.get(r,"events")||{})[e.type]&&Yn.get(r,"handle"))&&l.apply(r,t),(l=c&&r[c])&&l.apply&&Kn(r)&&(e.result=l.apply(r,t),!1===e.result&&e.preventDefault());return e.type=u,n||e.isDefaultPrevented()||h._default&&!1!==h._default.apply(f.pop(),t)||!Kn(i)||c&&gn(i[u])&&!wn(i)&&((a=i[c])&&(i[c]=null),_n.event.triggered=u,e.isPropagationStopped()&&d.addEventListener(u,hr),i[u](),e.isPropagationStopped()&&d.removeEventListener(u,hr),_n.event.triggered=void 0,a&&(i[c]=a)),e.result}},simulate:function(e,t,i){var n=_n.extend(new _n.Event,i,{type:e,isSimulated:!0});_n.event.trigger(n,null,t)}}),_n.fn.extend({trigger:function(e,t){return this.each((function(){_n.event.trigger(e,t,this)}))},triggerHandler:function(e,t){var i=this[0];if(i)return _n.event.trigger(e,t,i,!0)}}),mn.focusin||_n.each({focus:"focusin",blur:"focusout"},(function(e,t){var i=function(e){_n.event.simulate(t,e.target,_n.event.fix(e))};_n.event.special[t]={setup:function(){var n=this.ownerDocument||this,o=Yn.access(n,t);o||n.addEventListener(e,i,!0),Yn.access(n,t,(o||0)+1)},teardown:function(){var n=this.ownerDocument||this,o=Yn.access(n,t)-1;o?Yn.access(n,t,o):(n.removeEventListener(e,i,!0),Yn.remove(n,t))}}}));var dr,fr=/\[\]$/,ur=/\r?\n/g,pr=/^(?:submit|button|image|reset|file)$/i,mr=/^(?:input|select|textarea|keygen)/i;function gr(e,t,i,n){var o;if(Array.isArray(t))_n.each(t,(function(t,o){i||fr.test(e)?n(e,o):gr(e+"["+("object"==typeof o&&null!=o?t:"")+"]",o,i,n)}));else if(i||"object"!==vn(t))n(e,t);else for(o in t)gr(e+"["+o+"]",t[o],i,n)}_n.param=function(e,t){var i,n=[],o=function(e,t){var i=gn(t)?t():t;n[n.length]=encodeURIComponent(e)+"="+encodeURIComponent(null==i?"":i)};if(Array.isArray(e)||e.jquery&&!_n.isPlainObject(e))_n.each(e,(function(){o(this.name,this.value)}));else for(i in e)gr(i,e[i],t,o);return n.join("&")},_n.fn.extend({serialize:function(){return _n.param(this.serializeArray())},serializeArray:function(){return this.map((function(){var e=_n.prop(this,"elements");return e?_n.makeArray(e):this})).filter((function(){var e=this.type;return this.name&&!_n(this).is(":disabled")&&mr.test(this.nodeName)&&!pr.test(e)&&(this.checked||!ho.test(e))})).map((function(e,t){var i=_n(this).val();return null==i?null:Array.isArray(i)?_n.map(i,(function(e){return{name:t.name,value:e.replace(ur,"\r\n")}})):{name:t.name,value:i.replace(ur,"\r\n")}})).get()}}),_n.fn.extend({wrapAll:function(e){var t;return this[0]&&(gn(e)&&(e=e.call(this[0])),t=_n(e,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&t.insertBefore(this[0]),t.map((function(){for(var e=this;e.firstElementChild;)e=e.firstElementChild;return e})).append(this)),this},wrapInner:function(e){return gn(e)?this.each((function(t){_n(this).wrapInner(e.call(this,t))})):this.each((function(){var t=_n(this),i=t.contents();i.length?i.wrapAll(e):t.append(e)}))},wrap:function(e){var t=gn(e);return this.each((function(i){_n(this).wrapAll(t?e.call(this,i):e)}))},unwrap:function(e){return this.parent(e).not("body").each((function(){_n(this).replaceWith(this.childNodes)})),this}}),_n.expr.pseudos.hidden=function(e){return!_n.expr.pseudos.visible(e)},_n.expr.pseudos.visible=function(e){return!!(e.offsetWidth||e.offsetHeight||e.getClientRects().length)},mn.createHTMLDocument=((dr=on.implementation.createHTMLDocument("").body).innerHTML="
",2===dr.childNodes.length),_n.parseHTML=function(e,t,i){return"string"!=typeof e?[]:("boolean"==typeof t&&(i=t,t=!1),t||(mn.createHTMLDocument?((n=(t=on.implementation.createHTMLDocument("")).createElement("base")).href=on.location.href,t.head.appendChild(n)):t=on),r=!i&&[],(o=zn.exec(e))?[t.createElement(o[1])]:(o=Fo([e],t,r),r&&r.length&&_n(r).remove(),_n.merge([],o.childNodes)));var n,o,r},_n.offset={setOffset:function(e,t,i){var n,o,r,a,s,c,l=_n.css(e,"position"),h=_n(e),d={};"static"===l&&(e.style.position="relative"),s=h.offset(),r=_n.css(e,"top"),c=_n.css(e,"left"),("absolute"===l||"fixed"===l)&&(r+c).indexOf("auto")>-1?(a=(n=h.position()).top,o=n.left):(a=parseFloat(r)||0,o=parseFloat(c)||0),gn(t)&&(t=t.call(e,i,_n.extend({},s))),null!=t.top&&(d.top=t.top-s.top+a),null!=t.left&&(d.left=t.left-s.left+o),"using"in t?t.using.call(e,d):h.css(d)}},_n.fn.extend({offset:function(e){if(arguments.length)return void 0===e?this:this.each((function(t){_n.offset.setOffset(this,e,t)}));var t,i,n=this[0];return n?n.getClientRects().length?(t=n.getBoundingClientRect(),i=n.ownerDocument.defaultView,{top:t.top+i.pageYOffset,left:t.left+i.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,i,n=this[0],o={top:0,left:0};if("fixed"===_n.css(n,"position"))t=n.getBoundingClientRect();else{for(t=this.offset(),i=n.ownerDocument,e=n.offsetParent||i.documentElement;e&&(e===i.body||e===i.documentElement)&&"static"===_n.css(e,"position");)e=e.parentNode;e&&e!==n&&1===e.nodeType&&((o=_n(e).offset()).top+=_n.css(e,"borderTopWidth",!0),o.left+=_n.css(e,"borderLeftWidth",!0))}return{top:t.top-o.top-_n.css(n,"marginTop",!0),left:t.left-o.left-_n.css(n,"marginLeft",!0)}}},offsetParent:function(){return this.map((function(){for(var e=this.offsetParent;e&&"static"===_n.css(e,"position");)e=e.offsetParent;return e||bo}))}}),_n.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},(function(e,t){var i="pageYOffset"===t;_n.fn[e]=function(n){return jn(this,(function(e,n,o){var r;if(wn(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===o)return r?r[t]:e[n];r?r.scrollTo(i?r.pageXOffset:o,i?o:r.pageYOffset):e[n]=o}),e,n,arguments.length)}})),_n.each(["top","left"],(function(e,t){_n.cssHooks[t]=Vo(mn.pixelPosition,(function(e,i){if(i)return i=qo(e,t),Ho.test(i)?_n(e).position()[t]+"px":i}))})),_n.each({Height:"height",Width:"width"},(function(e,t){_n.each({padding:"inner"+e,content:t,"":"outer"+e},(function(i,n){_n.fn[n]=function(o,r){var a=arguments.length&&(i||"boolean"!=typeof o),s=i||(!0===o||!0===r?"margin":"border");return jn(this,(function(t,i,o){var r;return wn(t)?0===n.indexOf("outer")?t["inner"+e]:t.document.documentElement["client"+e]:9===t.nodeType?(r=t.documentElement,Math.max(t.body["scroll"+e],r["scroll"+e],t.body["offset"+e],r["offset"+e],r["client"+e])):void 0===o?_n.css(t,i,s):_n.style(t,i,o,s)}),t,a?o:void 0,a)}}))})),_n.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),(function(e,t){_n.fn[t]=function(e,i){return arguments.length>0?this.on(t,null,e,i):this.trigger(t)}})),_n.fn.extend({hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),_n.fn.extend({bind:function(e,t,i){return this.on(e,null,t,i)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,i,n){return this.on(t,e,i,n)},undelegate:function(e,t,i){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",i)}}),_n.proxy=function(e,t){var i,n,o;if("string"==typeof t&&(i=e[t],t=e,e=i),gn(e))return n=an.call(arguments,2),o=function(){return e.apply(t||this,n.concat(an.call(arguments)))},o.guid=e.guid=e.guid||_n.guid++,o},_n.holdReady=function(e){e?_n.readyWait++:_n.ready(!0)},_n.isArray=Array.isArray,_n.parseJSON=JSON.parse,_n.nodeName=In,_n.isFunction=gn,_n.isWindow=wn,_n.camelCase=Zn,_n.type=vn,_n.now=Date.now,_n.isNumeric=function(e){var t=_n.type(e);return("number"===t||"string"===t)&&!isNaN(e-parseFloat(e))};const wr=_n;function Fr(e){return br("div",e)}function br(e,t){const i=document.createElement(e);return t&&(t.class&&i.classList.add(t.class),t.id&&(i.id=t.id),t.style&&_r(i,t.style)),i}function vr(e){const t=getComputedStyle(e);"none"!==t.display&&(e._initialDisplay=t.display),e.style.display="none"}function yr(e){if("none"===getComputedStyle(e).display){const t=e._initialDisplay||"block";e.style.display=t}}function _r(e,t){for(let i of Object.keys(t))e.style[i]=t[i]}function Cr(e,t){const{clientX:i,clientY:n}=e;return((e,{clientX:t,clientY:i})=>{const{left:n,top:o,width:r,height:a}=e.getBoundingClientRect(),s=t-n,c=i-o;return{x:s,y:c,xNormalized:s/r,yNormalized:c/a,width:r,height:a}})(t,{clientX:i,clientY:n})}var xr=Object.freeze({__proto__:null,applyStyle:_r,create:br,div:Fr,empty:function(e){for(;e.firstChild;)e.removeChild(e.firstChild)},guid:function(){return("0000"+(Math.random()*Math.pow(36,4)|0).toString(36)).slice(-4)},hide:vr,hideAll:function(e){document.querySelectorAll(e).forEach((e=>{vr(e)}))},offset:function(e){if(!e.getClientRects().length)return{top:0,left:0};const t=e.getBoundingClientRect(),i=e.ownerDocument.defaultView;return{top:t.top+i.pageYOffset,left:t.left+i.pageXOffset}},pageCoordinates:function(e){if(e.type.startsWith("touch")){const t=e.touches[0];return{x:t.pageX,y:t.pageY}}return{x:e.pageX,y:e.pageY}},relativeDOMBBox:(e,t)=>{const{x:i,y:n,width:o,height:r}=e.getBoundingClientRect(),{x:a,y:s,width:c,height:l}=t.getBoundingClientRect();return{x:a-i,y:s-n,width:c,height:l}},show:yr,translateMouseCoordinates:Cr}); -/*! @license DOMPurify 3.0.5 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/3.0.5/LICENSE */const{entries:kr,setPrototypeOf:Er,isFrozen:Nr,getPrototypeOf:Sr,getOwnPropertyDescriptor:Ir}=Object;let{freeze:zr,seal:Dr,create:Ar}=Object,{apply:Mr,construct:Tr}="undefined"!=typeof Reflect&&Reflect;Mr||(Mr=function(e,t,i){return e.apply(t,i)}),zr||(zr=function(e){return e}),Dr||(Dr=function(e){return e}),Tr||(Tr=function(e,t){return new e(...t)});const Rr=$r(Array.prototype.forEach),Lr=$r(Array.prototype.pop),Br=$r(Array.prototype.push),Hr=$r(String.prototype.toLowerCase),Or=$r(String.prototype.toString),Pr=$r(String.prototype.match),qr=$r(String.prototype.replace),Vr=$r(String.prototype.indexOf),Ur=$r(String.prototype.trim),jr=$r(RegExp.prototype.test),Wr=(Gr=TypeError,function(){for(var e=arguments.length,t=new Array(e),i=0;i1?i-1:0),o=1;o/gm),ha=Dr(/\${[\w\W]*}/gm),da=Dr(/^data-[\-\w.\u00B7-\uFFFF]/),fa=Dr(/^aria-[\-\w]+$/),ua=Dr(/^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i),pa=Dr(/^(?:\w+script|data):/i),ma=Dr(/[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g),ga=Dr(/^html$/i);var wa=Object.freeze({__proto__:null,MUSTACHE_EXPR:ca,ERB_EXPR:la,TMPLIT_EXPR:ha,DATA_ATTR:da,ARIA_ATTR:fa,IS_ALLOWED_URI:ua,IS_SCRIPT_OR_DATA:pa,ATTR_WHITESPACE:ma,DOCTYPE_NAME:ga});const Fa=()=>"undefined"==typeof window?null:window;var ba=function e(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:Fa();const i=t=>e(t);if(i.version="3.0.5",i.removed=[],!t||!t.document||9!==t.document.nodeType)return i.isSupported=!1,i;const n=t.document,o=n.currentScript;let{document:r}=t;const{DocumentFragment:a,HTMLTemplateElement:s,Node:c,Element:l,NodeFilter:h,NamedNodeMap:d=t.NamedNodeMap||t.MozNamedAttrMap,HTMLFormElement:f,DOMParser:u,trustedTypes:p}=t,m=l.prototype,g=Xr(m,"cloneNode"),w=Xr(m,"nextSibling"),F=Xr(m,"childNodes"),b=Xr(m,"parentNode");if("function"==typeof s){const e=r.createElement("template");e.content&&e.content.ownerDocument&&(r=e.content.ownerDocument)}let v,y="";const{implementation:_,createNodeIterator:C,createDocumentFragment:x,getElementsByTagName:k}=r,{importNode:E}=n;let N={};i.isSupported="function"==typeof kr&&"function"==typeof b&&_&&void 0!==_.createHTMLDocument;const{MUSTACHE_EXPR:S,ERB_EXPR:I,TMPLIT_EXPR:z,DATA_ATTR:D,ARIA_ATTR:A,IS_SCRIPT_OR_DATA:M,ATTR_WHITESPACE:T}=wa;let{IS_ALLOWED_URI:R}=wa,L=null;const B=Zr({},[...Yr,...Qr,...Jr,...ta,...na]);let H=null;const O=Zr({},[...oa,...ra,...aa,...sa]);let P=Object.seal(Object.create(null,{tagNameCheck:{writable:!0,configurable:!1,enumerable:!0,value:null},attributeNameCheck:{writable:!0,configurable:!1,enumerable:!0,value:null},allowCustomizedBuiltInElements:{writable:!0,configurable:!1,enumerable:!0,value:!1}})),q=null,V=null,U=!0,j=!0,W=!1,G=!0,$=!1,Z=!1,K=!1,X=!1,Y=!1,Q=!1,J=!1,ee=!0,te=!1,ie=!0,ne=!1,oe={},re=null;const ae=Zr({},["annotation-xml","audio","colgroup","desc","foreignobject","head","iframe","math","mi","mn","mo","ms","mtext","noembed","noframes","noscript","plaintext","script","style","svg","template","thead","title","video","xmp"]);let se=null;const ce=Zr({},["audio","video","img","source","image","track"]);let le=null;const he=Zr({},["alt","class","for","id","label","name","pattern","placeholder","role","summary","title","value","style","xmlns"]),de="http://www.w3.org/1998/Math/MathML",fe="http://www.w3.org/2000/svg",ue="http://www.w3.org/1999/xhtml";let pe=ue,me=!1,ge=null;const we=Zr({},[de,fe,ue],Or);let Fe;const be=["application/xhtml+xml","text/html"];let ve,ye=null;const _e=r.createElement("form"),Ce=function(e){return e instanceof RegExp||e instanceof Function},xe=function(e){if(!ye||ye!==e){if(e&&"object"==typeof e||(e={}),e=Kr(e),Fe=Fe=-1===be.indexOf(e.PARSER_MEDIA_TYPE)?"text/html":e.PARSER_MEDIA_TYPE,ve="application/xhtml+xml"===Fe?Or:Hr,L="ALLOWED_TAGS"in e?Zr({},e.ALLOWED_TAGS,ve):B,H="ALLOWED_ATTR"in e?Zr({},e.ALLOWED_ATTR,ve):O,ge="ALLOWED_NAMESPACES"in e?Zr({},e.ALLOWED_NAMESPACES,Or):we,le="ADD_URI_SAFE_ATTR"in e?Zr(Kr(he),e.ADD_URI_SAFE_ATTR,ve):he,se="ADD_DATA_URI_TAGS"in e?Zr(Kr(ce),e.ADD_DATA_URI_TAGS,ve):ce,re="FORBID_CONTENTS"in e?Zr({},e.FORBID_CONTENTS,ve):ae,q="FORBID_TAGS"in e?Zr({},e.FORBID_TAGS,ve):{},V="FORBID_ATTR"in e?Zr({},e.FORBID_ATTR,ve):{},oe="USE_PROFILES"in e&&e.USE_PROFILES,U=!1!==e.ALLOW_ARIA_ATTR,j=!1!==e.ALLOW_DATA_ATTR,W=e.ALLOW_UNKNOWN_PROTOCOLS||!1,G=!1!==e.ALLOW_SELF_CLOSE_IN_ATTR,$=e.SAFE_FOR_TEMPLATES||!1,Z=e.WHOLE_DOCUMENT||!1,Y=e.RETURN_DOM||!1,Q=e.RETURN_DOM_FRAGMENT||!1,J=e.RETURN_TRUSTED_TYPE||!1,X=e.FORCE_BODY||!1,ee=!1!==e.SANITIZE_DOM,te=e.SANITIZE_NAMED_PROPS||!1,ie=!1!==e.KEEP_CONTENT,ne=e.IN_PLACE||!1,R=e.ALLOWED_URI_REGEXP||ua,pe=e.NAMESPACE||ue,P=e.CUSTOM_ELEMENT_HANDLING||{},e.CUSTOM_ELEMENT_HANDLING&&Ce(e.CUSTOM_ELEMENT_HANDLING.tagNameCheck)&&(P.tagNameCheck=e.CUSTOM_ELEMENT_HANDLING.tagNameCheck),e.CUSTOM_ELEMENT_HANDLING&&Ce(e.CUSTOM_ELEMENT_HANDLING.attributeNameCheck)&&(P.attributeNameCheck=e.CUSTOM_ELEMENT_HANDLING.attributeNameCheck),e.CUSTOM_ELEMENT_HANDLING&&"boolean"==typeof e.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements&&(P.allowCustomizedBuiltInElements=e.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements),$&&(j=!1),Q&&(Y=!0),oe&&(L=Zr({},[...na]),H=[],!0===oe.html&&(Zr(L,Yr),Zr(H,oa)),!0===oe.svg&&(Zr(L,Qr),Zr(H,ra),Zr(H,sa)),!0===oe.svgFilters&&(Zr(L,Jr),Zr(H,ra),Zr(H,sa)),!0===oe.mathMl&&(Zr(L,ta),Zr(H,aa),Zr(H,sa))),e.ADD_TAGS&&(L===B&&(L=Kr(L)),Zr(L,e.ADD_TAGS,ve)),e.ADD_ATTR&&(H===O&&(H=Kr(H)),Zr(H,e.ADD_ATTR,ve)),e.ADD_URI_SAFE_ATTR&&Zr(le,e.ADD_URI_SAFE_ATTR,ve),e.FORBID_CONTENTS&&(re===ae&&(re=Kr(re)),Zr(re,e.FORBID_CONTENTS,ve)),ie&&(L["#text"]=!0),Z&&Zr(L,["html","head","body"]),L.table&&(Zr(L,["tbody"]),delete q.tbody),e.TRUSTED_TYPES_POLICY){if("function"!=typeof e.TRUSTED_TYPES_POLICY.createHTML)throw Wr('TRUSTED_TYPES_POLICY configuration option must provide a "createHTML" hook.');if("function"!=typeof e.TRUSTED_TYPES_POLICY.createScriptURL)throw Wr('TRUSTED_TYPES_POLICY configuration option must provide a "createScriptURL" hook.');v=e.TRUSTED_TYPES_POLICY,y=v.createHTML("")}else void 0===v&&(v=function(e,t){if("object"!=typeof e||"function"!=typeof e.createPolicy)return null;let i=null;const n="data-tt-policy-suffix";t&&t.hasAttribute(n)&&(i=t.getAttribute(n));const o="dompurify"+(i?"#"+i:"");try{return e.createPolicy(o,{createHTML:e=>e,createScriptURL:e=>e})}catch(e){return console.warn("TrustedTypes policy "+o+" could not be created."),null}}(p,o)),null!==v&&"string"==typeof y&&(y=v.createHTML(""));zr&&zr(e),ye=e}},ke=Zr({},["mi","mo","mn","ms","mtext"]),Ee=Zr({},["foreignobject","desc","title","annotation-xml"]),Ne=Zr({},["title","style","font","a","script"]),Se=Zr({},Qr);Zr(Se,Jr),Zr(Se,ea);const Ie=Zr({},ta);Zr(Ie,ia);const ze=function(e){Br(i.removed,{element:e});try{e.parentNode.removeChild(e)}catch(t){e.remove()}},De=function(e,t){try{Br(i.removed,{attribute:t.getAttributeNode(e),from:t})}catch(e){Br(i.removed,{attribute:null,from:t})}if(t.removeAttribute(e),"is"===e&&!H[e])if(Y||Q)try{ze(t)}catch(e){}else try{t.setAttribute(e,"")}catch(e){}},Ae=function(e){let t,i;if(X)e=""+e;else{const t=Pr(e,/^[\r\n\t ]+/);i=t&&t[0]}"application/xhtml+xml"===Fe&&pe===ue&&(e=''+e+"");const n=v?v.createHTML(e):e;if(pe===ue)try{t=(new u).parseFromString(n,Fe)}catch(e){}if(!t||!t.documentElement){t=_.createDocument(pe,"template",null);try{t.documentElement.innerHTML=me?y:n}catch(e){}}const o=t.body||t.documentElement;return e&&i&&o.insertBefore(r.createTextNode(i),o.childNodes[0]||null),pe===ue?k.call(t,Z?"html":"body")[0]:Z?t.documentElement:o},Me=function(e){return C.call(e.ownerDocument||e,e,h.SHOW_ELEMENT|h.SHOW_COMMENT|h.SHOW_TEXT,null,!1)},Te=function(e){return"object"==typeof c?e instanceof c:e&&"object"==typeof e&&"number"==typeof e.nodeType&&"string"==typeof e.nodeName},Re=function(e,t,n){N[e]&&Rr(N[e],(e=>{e.call(i,t,n,ye)}))},Le=function(e){let t;if(Re("beforeSanitizeElements",e,null),(n=e)instanceof f&&("string"!=typeof n.nodeName||"string"!=typeof n.textContent||"function"!=typeof n.removeChild||!(n.attributes instanceof d)||"function"!=typeof n.removeAttribute||"function"!=typeof n.setAttribute||"string"!=typeof n.namespaceURI||"function"!=typeof n.insertBefore||"function"!=typeof n.hasChildNodes))return ze(e),!0;var n;const o=ve(e.nodeName);if(Re("uponSanitizeElement",e,{tagName:o,allowedTags:L}),e.hasChildNodes()&&!Te(e.firstElementChild)&&(!Te(e.content)||!Te(e.content.firstElementChild))&&jr(/<[/\w]/g,e.innerHTML)&&jr(/<[/\w]/g,e.textContent))return ze(e),!0;if(!L[o]||q[o]){if(!q[o]&&He(o)){if(P.tagNameCheck instanceof RegExp&&jr(P.tagNameCheck,o))return!1;if(P.tagNameCheck instanceof Function&&P.tagNameCheck(o))return!1}if(ie&&!re[o]){const t=b(e)||e.parentNode,i=F(e)||e.childNodes;if(i&&t){for(let n=i.length-1;n>=0;--n)t.insertBefore(g(i[n],!0),w(e))}}return ze(e),!0}return e instanceof l&&!function(e){let t=b(e);t&&t.tagName||(t={namespaceURI:pe,tagName:"template"});const i=Hr(e.tagName),n=Hr(t.tagName);return!!ge[e.namespaceURI]&&(e.namespaceURI===fe?t.namespaceURI===ue?"svg"===i:t.namespaceURI===de?"svg"===i&&("annotation-xml"===n||ke[n]):Boolean(Se[i]):e.namespaceURI===de?t.namespaceURI===ue?"math"===i:t.namespaceURI===fe?"math"===i&&Ee[n]:Boolean(Ie[i]):e.namespaceURI===ue?!(t.namespaceURI===fe&&!Ee[n])&&!(t.namespaceURI===de&&!ke[n])&&!Ie[i]&&(Ne[i]||!Se[i]):!("application/xhtml+xml"!==Fe||!ge[e.namespaceURI]))}(e)?(ze(e),!0):"noscript"!==o&&"noembed"!==o&&"noframes"!==o||!jr(/<\/no(script|embed|frames)/i,e.innerHTML)?($&&3===e.nodeType&&(t=e.textContent,t=qr(t,S," "),t=qr(t,I," "),t=qr(t,z," "),e.textContent!==t&&(Br(i.removed,{element:e.cloneNode()}),e.textContent=t)),Re("afterSanitizeElements",e,null),!1):(ze(e),!0)},Be=function(e,t,i){if(ee&&("id"===t||"name"===t)&&(i in r||i in _e))return!1;if(j&&!V[t]&&jr(D,t));else if(U&&jr(A,t));else if(!H[t]||V[t]){if(!(He(e)&&(P.tagNameCheck instanceof RegExp&&jr(P.tagNameCheck,e)||P.tagNameCheck instanceof Function&&P.tagNameCheck(e))&&(P.attributeNameCheck instanceof RegExp&&jr(P.attributeNameCheck,t)||P.attributeNameCheck instanceof Function&&P.attributeNameCheck(t))||"is"===t&&P.allowCustomizedBuiltInElements&&(P.tagNameCheck instanceof RegExp&&jr(P.tagNameCheck,i)||P.tagNameCheck instanceof Function&&P.tagNameCheck(i))))return!1}else if(le[t]);else if(jr(R,qr(i,T,"")));else if("src"!==t&&"xlink:href"!==t&&"href"!==t||"script"===e||0!==Vr(i,"data:")||!se[e]){if(W&&!jr(M,qr(i,T,"")));else if(i)return!1}else;return!0},He=function(e){return e.indexOf("-")>0},Oe=function(e){let t,n,o,r;Re("beforeSanitizeAttributes",e,null);const{attributes:a}=e;if(!a)return;const s={attrName:"",attrValue:"",keepAttr:!0,allowedAttributes:H};for(r=a.length;r--;){t=a[r];const{name:c,namespaceURI:l}=t;if(n="value"===c?t.value:Ur(t.value),o=ve(c),s.attrName=o,s.attrValue=n,s.keepAttr=!0,s.forceKeepAttr=void 0,Re("uponSanitizeAttribute",e,s),n=s.attrValue,s.forceKeepAttr)continue;if(De(c,e),!s.keepAttr)continue;if(!G&&jr(/\/>/i,n)){De(c,e);continue}$&&(n=qr(n,S," "),n=qr(n,I," "),n=qr(n,z," "));const h=ve(e.nodeName);if(Be(h,o,n)){if(!te||"id"!==o&&"name"!==o||(De(c,e),n="user-content-"+n),v&&"object"==typeof p&&"function"==typeof p.getAttributeType)if(l);else switch(p.getAttributeType(h,o)){case"TrustedHTML":n=v.createHTML(n);break;case"TrustedScriptURL":n=v.createScriptURL(n)}try{l?e.setAttributeNS(l,c,n):e.setAttribute(c,n),Lr(i.removed)}catch(e){}}}Re("afterSanitizeAttributes",e,null)},Pe=function e(t){let i;const n=Me(t);for(Re("beforeSanitizeShadowDOM",t,null);i=n.nextNode();)Re("uponSanitizeShadowNode",i,null),Le(i)||(i.content instanceof a&&e(i.content),Oe(i));Re("afterSanitizeShadowDOM",t,null)};return i.sanitize=function(e){let t,o,r,s,l=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};if(me=!e,me&&(e="\x3c!--\x3e"),"string"!=typeof e&&!Te(e)){if("function"!=typeof e.toString)throw Wr("toString is not a function");if("string"!=typeof(e=e.toString()))throw Wr("dirty is not a string, aborting")}if(!i.isSupported)return e;if(K||xe(l),i.removed=[],"string"==typeof e&&(ne=!1),ne){if(e.nodeName){const t=ve(e.nodeName);if(!L[t]||q[t])throw Wr("root node is forbidden and cannot be sanitized in-place")}}else if(e instanceof c)t=Ae("\x3c!----\x3e"),o=t.ownerDocument.importNode(e,!0),1===o.nodeType&&"BODY"===o.nodeName||"HTML"===o.nodeName?t=o:t.appendChild(o);else{if(!Y&&!$&&!Z&&-1===e.indexOf("<"))return v&&J?v.createHTML(e):e;if(t=Ae(e),!t)return Y?null:J?y:""}t&&X&&ze(t.firstChild);const h=Me(ne?e:t);for(;r=h.nextNode();)Le(r)||(r.content instanceof a&&Pe(r.content),Oe(r));if(ne)return e;if(Y){if(Q)for(s=x.call(t.ownerDocument);t.firstChild;)s.appendChild(t.firstChild);else s=t;return(H.shadowroot||H.shadowrootmode)&&(s=E.call(n,s,!0)),s}let d=Z?t.outerHTML:t.innerHTML;return Z&&L["!doctype"]&&t.ownerDocument&&t.ownerDocument.doctype&&t.ownerDocument.doctype.name&&jr(ga,t.ownerDocument.doctype.name)&&(d="\n"+d),$&&(d=qr(d,S," "),d=qr(d,I," "),d=qr(d,z," ")),v&&J?v.createHTML(d):d},i.setConfig=function(e){xe(e),K=!0},i.clearConfig=function(){ye=null,K=!1},i.isValidAttribute=function(e,t,i){ye||xe({});const n=ve(e),o=ve(t);return Be(n,o,i)},i.addHook=function(e,t){"function"==typeof t&&(N[e]=N[e]||[],Br(N[e],t))},i.removeHook=function(e){if(N[e])return Lr(N[e])},i.removeHooks=function(e){N[e]&&(N[e]=[])},i.removeAllHooks=function(){N={}},i}();function va(e,t){const i=Fr({class:"igv-ui-trackgear-popover-check-container"}),n=_a("check",!0===t?"#444":"transparent");n.style.borderColor="gray",n.style.borderWidth="1px",n.style.borderStyle="solid",i.appendChild(n);let o=Fr();return o.textContent=e,i.appendChild(o),i}function ya(e,t){return _a(e,t)}function _a(e,t){t=t||"currentColor";let i=Ca[e];i||(console.error(`No icon named: ${e}`),i=Ca.question);const n=document.createElementNS("http://www.w3.org/2000/svg","svg");n.setAttributeNS(null,"viewBox","0 0 "+i[0]+" "+i[1]);const o=document.createElementNS("http://www.w3.org/2000/svg","path");return o.setAttributeNS(null,"fill",t),o.setAttributeNS(null,"d",i[4]),n.appendChild(o),n}const Ca={check:[512,512,[],"f00c","M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z"],cog:[512,512,[],"f013","M444.788 291.1l42.616 24.599c4.867 2.809 7.126 8.618 5.459 13.985-11.07 35.642-29.97 67.842-54.689 94.586a12.016 12.016 0 0 1-14.832 2.254l-42.584-24.595a191.577 191.577 0 0 1-60.759 35.13v49.182a12.01 12.01 0 0 1-9.377 11.718c-34.956 7.85-72.499 8.256-109.219.007-5.49-1.233-9.403-6.096-9.403-11.723v-49.184a191.555 191.555 0 0 1-60.759-35.13l-42.584 24.595a12.016 12.016 0 0 1-14.832-2.254c-24.718-26.744-43.619-58.944-54.689-94.586-1.667-5.366.592-11.175 5.459-13.985L67.212 291.1a193.48 193.48 0 0 1 0-70.199l-42.616-24.599c-4.867-2.809-7.126-8.618-5.459-13.985 11.07-35.642 29.97-67.842 54.689-94.586a12.016 12.016 0 0 1 14.832-2.254l42.584 24.595a191.577 191.577 0 0 1 60.759-35.13V25.759a12.01 12.01 0 0 1 9.377-11.718c34.956-7.85 72.499-8.256 109.219-.007 5.49 1.233 9.403 6.096 9.403 11.723v49.184a191.555 191.555 0 0 1 60.759 35.13l42.584-24.595a12.016 12.016 0 0 1 14.832 2.254c24.718 26.744 43.619 58.944 54.689 94.586 1.667 5.366-.592 11.175-5.459 13.985L444.788 220.9a193.485 193.485 0 0 1 0 70.2zM336 256c0-44.112-35.888-80-80-80s-80 35.888-80 80 35.888 80 80 80 80-35.888 80-80z"],exclamation:[192,512,[],"f12a","M176 432c0 44.112-35.888 80-80 80s-80-35.888-80-80 35.888-80 80-80 80 35.888 80 80zM25.26 25.199l13.6 272C39.499 309.972 50.041 320 62.83 320h66.34c12.789 0 23.331-10.028 23.97-22.801l13.6-272C167.425 11.49 156.496 0 142.77 0H49.23C35.504 0 24.575 11.49 25.26 25.199z"],"exclamation-circle":[512,512,[],"f06a","M504 256c0 136.997-111.043 248-248 248S8 392.997 8 256C8 119.083 119.043 8 256 8s248 111.083 248 248zm-248 50c-25.405 0-46 20.595-46 46s20.595 46 46 46 46-20.595 46-46-20.595-46-46-46zm-43.673-165.346l7.418 136c.347 6.364 5.609 11.346 11.982 11.346h48.546c6.373 0 11.635-4.982 11.982-11.346l7.418-136c.375-6.874-5.098-12.654-11.982-12.654h-63.383c-6.884 0-12.356 5.78-11.981 12.654z"],"exclamation-triangle":[576,512,[],"f071","M569.517 440.013C587.975 472.007 564.806 512 527.94 512H48.054c-36.937 0-59.999-40.055-41.577-71.987L246.423 23.985c18.467-32.009 64.72-31.951 83.154 0l239.94 416.028zM288 354c-25.405 0-46 20.595-46 46s20.595 46 46 46 46-20.595 46-46-20.595-46-46-46zm-43.673-165.346l7.418 136c.347 6.364 5.609 11.346 11.982 11.346h48.546c6.373 0 11.635-4.982 11.982-11.346l7.418-136c.375-6.874-5.098-12.654-11.982-12.654h-63.383c-6.884 0-12.356 5.78-11.981 12.654z"],minus:[448,512,[],"f068","M424 318.2c13.3 0 24-10.7 24-24v-76.4c0-13.3-10.7-24-24-24H24c-13.3 0-24 10.7-24 24v76.4c0 13.3 10.7 24 24 24h400z"],"minus-circle":[512,512,[],"f056","M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zM124 296c-6.6 0-12-5.4-12-12v-56c0-6.6 5.4-12 12-12h264c6.6 0 12 5.4 12 12v56c0 6.6-5.4 12-12 12H124z"],"minus-square":[448,512,[],"f146","M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM92 296c-6.6 0-12-5.4-12-12v-56c0-6.6 5.4-12 12-12h264c6.6 0 12 5.4 12 12v56c0 6.6-5.4 12-12 12H92z"],plus:[448,512,[],"f067","M448 294.2v-76.4c0-13.3-10.7-24-24-24H286.2V56c0-13.3-10.7-24-24-24h-76.4c-13.3 0-24 10.7-24 24v137.8H24c-13.3 0-24 10.7-24 24v76.4c0 13.3 10.7 24 24 24h137.8V456c0 13.3 10.7 24 24 24h76.4c13.3 0 24-10.7 24-24V318.2H424c13.3 0 24-10.7 24-24z"],"plus-circle":[512,512,[],"f055","M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm144 276c0 6.6-5.4 12-12 12h-92v92c0 6.6-5.4 12-12 12h-56c-6.6 0-12-5.4-12-12v-92h-92c-6.6 0-12-5.4-12-12v-56c0-6.6 5.4-12 12-12h92v-92c0-6.6 5.4-12 12-12h56c6.6 0 12 5.4 12 12v92h92c6.6 0 12 5.4 12 12v56z"],"plus-square":[448,512,[],"f0fe","M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-32 252c0 6.6-5.4 12-12 12h-92v92c0 6.6-5.4 12-12 12h-56c-6.6 0-12-5.4-12-12v-92H92c-6.6 0-12-5.4-12-12v-56c0-6.6 5.4-12 12-12h92v-92c0-6.6 5.4-12 12-12h56c6.6 0 12 5.4 12 12v92h92c6.6 0 12 5.4 12 12v56z"],question:[384,512,[],"f128","M202.021 0C122.202 0 70.503 32.703 29.914 91.026c-7.363 10.58-5.093 25.086 5.178 32.874l43.138 32.709c10.373 7.865 25.132 6.026 33.253-4.148 25.049-31.381 43.63-49.449 82.757-49.449 30.764 0 68.816 19.799 68.816 49.631 0 22.552-18.617 34.134-48.993 51.164-35.423 19.86-82.299 44.576-82.299 106.405V320c0 13.255 10.745 24 24 24h72.471c13.255 0 24-10.745 24-24v-5.773c0-42.86 125.268-44.645 125.268-160.627C377.504 66.256 286.902 0 202.021 0zM192 373.459c-38.196 0-69.271 31.075-69.271 69.271 0 38.195 31.075 69.27 69.271 69.27s69.271-31.075 69.271-69.271-31.075-69.27-69.271-69.27z"],save:[448,512,[],"f0c7","M433.941 129.941l-83.882-83.882A48 48 0 0 0 316.118 32H48C21.49 32 0 53.49 0 80v352c0 26.51 21.49 48 48 48h352c26.51 0 48-21.49 48-48V163.882a48 48 0 0 0-14.059-33.941zM224 416c-35.346 0-64-28.654-64-64 0-35.346 28.654-64 64-64s64 28.654 64 64c0 35.346-28.654 64-64 64zm96-304.52V212c0 6.627-5.373 12-12 12H76c-6.627 0-12-5.373-12-12V108c0-6.627 5.373-12 12-12h228.52c3.183 0 6.235 1.264 8.485 3.515l3.48 3.48A11.996 11.996 0 0 1 320 111.48z"],search:[512,512,[],"f002","M505 442.7L405.3 343c-4.5-4.5-10.6-7-17-7H372c27.6-35.3 44-79.7 44-128C416 93.1 322.9 0 208 0S0 93.1 0 208s93.1 208 208 208c48.3 0 92.7-16.4 128-44v16.3c0 6.4 2.5 12.5 7 17l99.7 99.7c9.4 9.4 24.6 9.4 33.9 0l28.3-28.3c9.4-9.4 9.4-24.6.1-34zM208 336c-70.7 0-128-57.2-128-128 0-70.7 57.2-128 128-128 70.7 0 128 57.2 128 128 0 70.7-57.2 128-128 128z"],share:[512,512,[],"f064","M503.691 189.836L327.687 37.851C312.281 24.546 288 35.347 288 56.015v80.053C127.371 137.907 0 170.1 0 322.326c0 61.441 39.581 122.309 83.333 154.132 13.653 9.931 33.111-2.533 28.077-18.631C66.066 312.814 132.917 274.316 288 272.085V360c0 20.7 24.3 31.453 39.687 18.164l176.004-152c11.071-9.562 11.086-26.753 0-36.328z"],spinner:[512,512,[],"f110","M304 48c0 26.51-21.49 48-48 48s-48-21.49-48-48 21.49-48 48-48 48 21.49 48 48zm-48 368c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48-21.49-48-48-48zm208-208c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48-21.49-48-48-48zM96 256c0-26.51-21.49-48-48-48S0 229.49 0 256s21.49 48 48 48 48-21.49 48-48zm12.922 99.078c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48c0-26.509-21.491-48-48-48zm294.156 0c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48c0-26.509-21.49-48-48-48zM108.922 60.922c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48-21.491-48-48-48z"],square:[448,512,[],"f0c8","M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48z"],"square-full":[512,512,[],"f45c","M512 512H0V0h512v512z"],times:[384,512,[],"f00d","M323.1 441l53.9-53.9c9.4-9.4 9.4-24.5 0-33.9L279.8 256l97.2-97.2c9.4-9.4 9.4-24.5 0-33.9L323.1 71c-9.4-9.4-24.5-9.4-33.9 0L192 168.2 94.8 71c-9.4-9.4-24.5-9.4-33.9 0L7 124.9c-9.4 9.4-9.4 24.5 0 33.9l97.2 97.2L7 353.2c-9.4 9.4-9.4 24.5 0 33.9L60.9 441c9.4 9.4 24.5 9.4 33.9 0l97.2-97.2 97.2 97.2c9.3 9.3 24.5 9.3 33.9 0z"],"times-circle":[512,512,[],"f057","M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm121.6 313.1c4.7 4.7 4.7 12.3 0 17L338 377.6c-4.7 4.7-12.3 4.7-17 0L256 312l-65.1 65.6c-4.7 4.7-12.3 4.7-17 0L134.4 338c-4.7-4.7-4.7-12.3 0-17l65.6-65-65.6-65.1c-4.7-4.7-4.7-12.3 0-17l39.6-39.6c4.7-4.7 12.3-4.7 17 0l65 65.7 65.1-65.6c4.7-4.7 12.3-4.7 17 0l39.6 39.6c4.7 4.7 4.7 12.3 0 17L312 256l65.6 65.1z"],wrench:[512,512,[],"f0ad","M481.156 200c9.3 0 15.12 10.155 10.325 18.124C466.295 259.992 420.419 288 368 288c-79.222 0-143.501-63.974-143.997-143.079C223.505 65.469 288.548-.001 368.002 0c52.362.001 98.196 27.949 123.4 69.743C496.24 77.766 490.523 88 481.154 88H376l-40 56 40 56h105.156zm-171.649 93.003L109.255 493.255c-24.994 24.993-65.515 24.994-90.51 0-24.993-24.994-24.993-65.516 0-90.51L218.991 202.5c16.16 41.197 49.303 74.335 90.516 90.503zM104 432c0-13.255-10.745-24-24-24s-24 10.745-24 24 10.745 24 24 24 24-10.745 24-24z"]};var xa=Object.freeze({__proto__:null,createCheckbox:va,createIcon:ya});function ka(e,t){var i=document.createElement("div");e.appendChild(i),i.appendChild(ya("times")),i.addEventListener("click",(function(e){e.preventDefault(),e.stopPropagation(),t()}))}var Ea=Object.freeze({__proto__:null,attachDialogCloseHandlerWithParent:ka});let Na;function Sa(e,t,i){t.addEventListener("mousedown",function(e){e.stopPropagation(),e.preventDefault();const t=Ia.bind(this),n=za.bind(this),o=getComputedStyle(this);Na={constraint:i,dragFunction:t,dragEndFunction:n,screenX:e.screenX,screenY:e.screenY,top:parseInt(o.top.replace("px","")),left:parseInt(o.left.replace("px",""))},document.addEventListener("mousemove",t),document.addEventListener("mouseup",n),document.addEventListener("mouseleave",n),document.addEventListener("mouseexit",n)}.bind(e))}function Ia(e){if(!Na)return void console.error("No drag data!");e.stopPropagation(),e.preventDefault();const t=e.screenX-Na.screenX,i=e.screenY-Na.screenY,n=Na.left+t,o=Na.constraint?Math.max(Na.constraint.minY,Na.top+i):Na.top+i;this.style.left=`${n}px`,this.style.top=`${o}px`}function za(e){if(!Na)return void console.error("No drag data!");e.stopPropagation(),e.preventDefault();const t=Na.dragFunction,i=Na.dragEndFunction;document.removeEventListener("mousemove",t),document.removeEventListener("mouseup",i),document.removeEventListener("mouseleave",i),document.removeEventListener("mouseexit",i),Na=void 0}const Da={401:"Access unauthorized",403:"Access forbidden",404:"Not found"};class Aa{constructor(e,t){this.alertProps=Object.assign({shouldFocus:!0,preventScroll:!1},t),this.container=Fr({class:"igv-ui-alert-dialog-container"}),e.appendChild(this.container),this.container.setAttribute("tabIndex","-1");const i=Fr();this.container.appendChild(i),this.errorHeadline=Fr(),i.appendChild(this.errorHeadline),this.errorHeadline.textContent="";let n=Fr({class:"igv-ui-alert-dialog-body"});this.container.appendChild(n),this.body=Fr({class:"igv-ui-alert-dialog-body-copy"}),n.appendChild(this.body);let o=Fr();this.container.appendChild(o),this.ok=Fr(),o.appendChild(this.ok),this.ok.textContent="OK";const r=()=>{"function"==typeof this.callback&&(this.callback("OK"),this.callback=void 0),this.body.innerHTML="",vr(this.container)};this.ok.addEventListener("click",(e=>{e.stopPropagation(),r()})),this.container.addEventListener("keypress",(e=>{e.stopPropagation(),"Enter"===e.key&&r()})),Sa(this.container,i),vr(this.container)}present(e,t){this.errorHeadline.textContent=e.message?"ERROR":"";let i=e.message||e;Da.hasOwnProperty(i)&&(i=Da[i]);const n=ba.sanitize(i);this.body.innerHTML=n,this.callback=t,yr(this.container),this.alertProps.shouldFocus&&this.container.focus({preventScroll:this.alertProps.preventScroll})}}class Ma{constructor(e){this.parent=e,this.container=Fr({class:"igv-ui-generic-dialog-container"}),e.appendChild(this.container);const t=Fr({class:"igv-ui-generic-dialog-header"});this.container.appendChild(t),this.label=Fr({class:"igv-ui-generic-dialog-one-liner"}),this.container.appendChild(this.label),this.label.text="Unlabeled",this.input_container=Fr({class:"igv-ui-generic-dialog-input"}),this.container.appendChild(this.input_container),this.input=document.createElement("input"),this.input_container.appendChild(this.input);const i=Fr({class:"igv-ui-generic-dialog-ok-cancel"});this.container.appendChild(i),this.ok=Fr(),i.appendChild(this.ok),this.ok.textContent="OK",this.cancel=Fr(),i.appendChild(this.cancel),this.cancel.textContent="Cancel",vr(this.container),this.input.addEventListener("keyup",(e=>{13===e.keyCode&&("function"==typeof this.callback&&(this.callback(this.input.value),this.callback=void 0),this.input.value=void 0,vr(this.container))})),this.ok.addEventListener("click",(()=>{"function"==typeof this.callback&&(this.callback(this.input.value),this.callback=void 0),this.input.value=void 0,vr(this.container)}));const n=()=>{this.input.value="",vr(this.container)};this.cancel.addEventListener("click",n),ka(t,n),Sa(this.container,t)}get value(){return ba.sanitize(this.input.value)}present(e,t){this.label.textContent=e.label,this.input.value=e.value,this.callback=e.callback||e.click,yr(this.container),this.clampLocation(t.clientX,t.clientY)}clampLocation(e,t){const{width:i,height:n}=this.container.getBoundingClientRect(),o=window.innerHeight,r=window.innerWidth,a=Math.min(o-n,t),s=Math.min(r-i,e);this.container.style.left=`${s}px`,this.container.style.top=`${a}px`}}const Ta={licorice:"#000000",lead:"#1e1e1e",tungsten:"#3a3a3a",iron:"#545453",steel:"#6e6e6e",tin:"#878687",nickel:"#888787",aluminum:"#a09fa0",magnesium:"#b8b8b8",silver:"#d0d0d0",mercury:"#e8e8e8",snow:"#ffffff",cayenne:"#891100",mocha:"#894800",aspargus:"#888501",fern:"#458401",clover:"#028401",moss:"#018448",teal:"#008688",ocean:"#004a88",midnight:"#001888",eggplant:"#491a88",plum:"#891e88",maroon:"#891648",maraschino:"#ff2101",tangerine:"#ff8802",lemon:"#fffa03",lime:"#83f902",spring:"#05f802",seam_foam:"#03f987",turquoise:"#00fdff",aqua:"#008cff",blueberry:"#002eff",grape:"#8931ff",magenta:"#ff39ff",strawberry:"#ff2987",salmon:"#ff726e",cantaloupe:"#ffce6e",banana:"#fffb6d",honeydew:"#cefa6e",flora:"#68f96e",spindrift:"#68fbd0",ice:"#68fdff",sky:"#6acfff",orchid:"#6e76ff",lavender:"#d278ff",bubblegum:"#ff7aff",carnation:"#ff7fd3"};class Ra{constructor({parent:e,top:t,left:i,width:n,height:o,border:r,closeHandler:a}){let s=Fr({class:"igv-ui-generic-container"});e.appendChild(s),vr(s),this.container=s,void 0!==t&&(this.container.style.top=`${t}px`),void 0!==i&&(this.container.style.left=`${i}px`),void 0!==n&&(this.container.style.width=`${n}px`),void 0!==o&&(this.container.style.height=`${o}px`),r&&(this.container.style.border=r);const c=Fr();this.container.appendChild(c),ka(c,(e=>{vr(this.container),"function"==typeof a&&a(e)})),Sa(this.container,c)}show(){yr(this.container)}hide(){vr(this.container)}dispose(){this.container.parent&&this.container.parent.removeChild(this.container)}}class La extends Ra{constructor({parent:e,top:t,left:i,width:n,height:o,defaultColors:r,colorHandler:a}){super({parent:e,top:t,left:i,width:n,height:o,border:"1px solid gray"}),Ba(this.container,a,r)}}const Ba=(e,t,i)=>{const n=Object.values(Ta);for(let i of n){const n=Fr({class:"igv-ui-color-swatch"});e.appendChild(n),Ha(n,i,t)}if(i)for(let n of i){const i=Fr({class:"igv-ui-color-swatch"});e.appendChild(i),Ha(i,n,t)}},Ha=(e,t,i)=>{e.style.backgroundColor=t,e.addEventListener("mouseenter",(i=>e.style.borderColor=t)),e.addEventListener("mouseleave",(t=>e.style.borderColor="white")),e.addEventListener("click",(e=>{e.stopPropagation(),i(t)})),e.addEventListener("touchend",(e=>{e.stopPropagation(),i(t)}))};class Oa{constructor(e,t){this.parent=e,this.popover=Fr({class:"igv-ui-popover"}),e.appendChild(this.popover);const i=Fr();this.popover.appendChild(i);const n=Fr();i.appendChild(n),t&&(n.textContent=t),ka(i,(()=>this.hide())),Sa(this.popover,i),this.popoverContent=Fr(),this.popover.appendChild(this.popoverContent),this.popover.style.display="none"}presentContentWithEvent(e,t){this.popover.style.display="block",this.popoverContent.innerHTML=t,Pa(e,this.popover,this.popoverContent)}presentMenu(e,t){if(0===t.length)return;this.popover.style.display="block";const i=function(e,t){const i=e.map((function(e,i){let n;if("string"==typeof e)n=Fr(),n.innerHTML=e;else if("Node"==typeof e)n=e;else{if("function"==typeof e.init&&e.init(),"checkbox"===e.type)n=va("Show all bases",e.value);else if("color"===e.type){const o=new La({parent:t.parentElement,width:364,colorHandler:t=>e.click(t)});n=Fr(),"string"==typeof e.label&&(n.innerHTML=e.label);const r=e=>{o.show(),vr(t),e.preventDefault(),e.stopPropagation()};n.addEventListener("click",r),n.addEventListener("touchend",r),n.addEventListener("mouseup",(function(e){e.preventDefault(),e.stopPropagation()}))}else n=Fr(),"string"==typeof e.label&&(n.innerHTML=e.label);if(e.click&&"color"!==e.type){function a(i){e.click(),vr(t),i.preventDefault(),i.stopPropagation()}n.addEventListener("click",a),n.addEventListener("touchend",a),n.addEventListener("mouseup",(function(e){e.preventDefault(),e.stopPropagation()}))}}return{object:n,init:e.init}}));return i}(t,this.popover);for(let e of i)this.popoverContent.appendChild(e.object);Pa(e,this.popover,this.popoverContent)}hide(){this.popover.style.display="none",this.dispose()}dispose(){this.popover&&this.popover.parentNode.removeChild(this.popover);const e=Object.keys(this);for(let t of e)this[t]=void 0}}function Pa(e,t,i){const{x:n,y:o,width:r}=Cr(e,t.parentNode);t.style.top=`${o}px`;const{width:a}=t.getBoundingClientRect(),s=n+a,c=s-r;t.style.left=`${s>r?n-c:n}px`,i.style.maxWidth=`${Math.min(a,r)}px`}class qa extends Ra{constructor({parent:e,width:t}){super({parent:e,width:t,border:"1px solid gray"})}configure(e,t){this.colorHandlers=t,this.setActiveColorHandler("color"),this.createSwatches(e)}setActiveColorHandler(e){this.activeColorHandler=this.colorHandlers[e]}createSwatches(e){this.container.querySelectorAll(".igv-ui-color-swatch").forEach((e=>e.remove()));const t=Object.values(Ta);for(let e of t){const t=Fr({class:"igv-ui-color-swatch"});this.container.appendChild(t),this.decorateSwatch(t,e)}if(e)for(let t of e){const e=Fr({class:"igv-ui-color-swatch"});this.container.appendChild(e),this.decorateSwatch(e,t)}}decorateSwatch(e,t){e.style.backgroundColor=t,e.addEventListener("mouseenter",(()=>e.style.borderColor=t)),e.addEventListener("mouseleave",(()=>e.style.borderColor="white")),e.addEventListener("click",(e=>{e.stopPropagation(),this.activeColorHandler(t)})),e.addEventListener("touchend",(e=>{e.stopPropagation(),this.activeColorHandler(t)}))}}if("undefined"!=typeof document){function Dk(e){for(let t of document.styleSheets)if(t=t.href?t.href.replace(/^.*[\\\/]/,""):"",t===e)return!0;return!1}Dk("igv-ui.css")||function(){const e=document.createElement("style");e.setAttribute("type","text/css"),e.setAttribute("title","igv-ui.css"),e.innerHTML='.igv-ui-popover {\n cursor: default;\n position: absolute;\n z-index: 2048;\n border-color: #7F7F7F;\n border-radius: 4px;\n border-style: solid;\n border-width: 1px;\n font-family: "Open Sans", sans-serif;\n font-size: small;\n background-color: white;\n}\n.igv-ui-popover > div:first-child {\n display: flex;\n flex-direction: row;\n flex-wrap: nowrap;\n justify-content: space-between;\n align-items: center;\n width: 100%;\n height: 24px;\n cursor: move;\n border-top-left-radius: 4px;\n border-top-right-radius: 4px;\n border-bottom-color: #7F7F7F;\n border-bottom-style: solid;\n border-bottom-width: thin;\n background-color: #eee;\n}\n.igv-ui-popover > div:first-child > div:first-child {\n margin-left: 4px;\n}\n.igv-ui-popover > div:first-child > div:last-child {\n margin-right: 4px;\n height: 12px;\n width: 12px;\n color: #7F7F7F;\n}\n.igv-ui-popover > div:first-child > div:last-child:hover {\n cursor: pointer;\n color: #444;\n}\n.igv-ui-popover > div:last-child {\n overflow-y: auto;\n overflow-x: hidden;\n max-height: 400px;\n max-width: 800px;\n background-color: white;\n}\n.igv-ui-popover > div:last-child > div {\n user-select: all;\n margin-left: 4px;\n margin-right: 4px;\n min-width: 220px;\n overflow-x: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.igv-ui-popover > div:last-child > div > span {\n font-weight: bolder;\n}\n.igv-ui-popover > div:last-child hr {\n width: 100%;\n}\n\n.igv-ui-alert-dialog-container {\n box-sizing: content-box;\n position: absolute;\n z-index: 2048;\n top: 50%;\n left: 50%;\n width: 400px;\n height: 200px;\n border-color: #7F7F7F;\n border-radius: 4px;\n border-style: solid;\n border-width: thin;\n outline: none;\n font-family: "Open Sans", sans-serif;\n font-size: 15px;\n font-weight: 400;\n background-color: white;\n display: flex;\n flex-flow: column;\n flex-wrap: nowrap;\n justify-content: space-between;\n align-items: center;\n}\n.igv-ui-alert-dialog-container > div:first-child {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n width: 100%;\n height: 24px;\n cursor: move;\n border-top-left-radius: 4px;\n border-top-right-radius: 4px;\n border-bottom-color: #7F7F7F;\n border-bottom-style: solid;\n border-bottom-width: thin;\n background-color: #eee;\n}\n.igv-ui-alert-dialog-container > div:first-child div:first-child {\n padding-left: 8px;\n}\n.igv-ui-alert-dialog-container .igv-ui-alert-dialog-body {\n -webkit-user-select: text;\n -moz-user-select: text;\n -ms-user-select: text;\n user-select: text;\n color: #373737;\n width: 100%;\n height: calc(100% - 24px - 64px);\n overflow-y: scroll;\n}\n.igv-ui-alert-dialog-container .igv-ui-alert-dialog-body .igv-ui-alert-dialog-body-copy {\n margin: 16px;\n width: auto;\n height: auto;\n overflow-wrap: break-word;\n word-break: break-word;\n background-color: white;\n border: unset;\n}\n.igv-ui-alert-dialog-container > div:last-child {\n width: 100%;\n margin-bottom: 10px;\n background-color: white;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: center;\n align-items: center;\n}\n.igv-ui-alert-dialog-container > div:last-child div {\n margin: unset;\n width: 40px;\n height: 30px;\n line-height: 30px;\n text-align: center;\n color: white;\n font-family: "Open Sans", sans-serif;\n font-size: small;\n font-weight: 400;\n border-color: #2B81AF;\n border-style: solid;\n border-width: thin;\n border-radius: 4px;\n background-color: #2B81AF;\n}\n.igv-ui-alert-dialog-container > div:last-child div:hover {\n cursor: pointer;\n border-color: #25597f;\n background-color: #25597f;\n}\n\n.igv-ui-color-swatch {\n position: relative;\n box-sizing: content-box;\n display: flex;\n flex-flow: row;\n flex-wrap: wrap;\n justify-content: center;\n align-items: center;\n width: 32px;\n height: 32px;\n border-style: solid;\n border-width: 2px;\n border-color: white;\n border-radius: 4px;\n}\n\n.igv-ui-color-swatch:hover {\n border-color: dimgray;\n}\n\n.igv-ui-colorpicker-menu-close-button {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-end;\n align-items: center;\n width: 100%;\n height: 32px;\n margin-top: 4px;\n margin-bottom: 4px;\n padding-right: 8px;\n}\n.igv-ui-colorpicker-menu-close-button i.fa {\n display: block;\n margin-left: 4px;\n margin-right: 4px;\n color: #5f5f5f;\n}\n.igv-ui-colorpicker-menu-close-button i.fa:hover,\n.igv-ui-colorpicker-menu-close-button i.fa:focus,\n.igv-ui-colorpicker-menu-close-button i.fa:active {\n cursor: pointer;\n color: #0f0f0f;\n}\n\n.igv-ui-generic-dialog-container {\n box-sizing: content-box;\n position: fixed;\n top: 0;\n left: 0;\n width: 300px;\n height: 200px;\n border-color: #7F7F7F;\n border-radius: 4px;\n border-style: solid;\n border-width: thin;\n font-family: "Open Sans", sans-serif;\n font-size: medium;\n font-weight: 400;\n z-index: 2048;\n background-color: white;\n display: flex;\n flex-flow: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n}\n.igv-ui-generic-dialog-container .igv-ui-generic-dialog-header {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-end;\n align-items: center;\n width: 100%;\n height: 24px;\n cursor: move;\n border-top-left-radius: 4px;\n border-top-right-radius: 4px;\n border-bottom-color: #7F7F7F;\n border-bottom-style: solid;\n border-bottom-width: thin;\n background-color: #eee;\n}\n.igv-ui-generic-dialog-container .igv-ui-generic-dialog-header div {\n margin-right: 4px;\n margin-bottom: 2px;\n height: 12px;\n width: 12px;\n color: #7F7F7F;\n}\n.igv-ui-generic-dialog-container .igv-ui-generic-dialog-header div:hover {\n cursor: pointer;\n color: #444;\n}\n.igv-ui-generic-dialog-container .igv-ui-generic-dialog-one-liner {\n color: #373737;\n width: 95%;\n height: 24px;\n line-height: 24px;\n text-align: left;\n margin-top: 8px;\n padding-left: 8px;\n overflow-wrap: break-word;\n background-color: white;\n}\n.igv-ui-generic-dialog-container .igv-ui-generic-dialog-label-input {\n margin-top: 8px;\n width: 95%;\n height: 24px;\n color: #373737;\n line-height: 24px;\n padding-left: 8px;\n background-color: white;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n}\n.igv-ui-generic-dialog-container .igv-ui-generic-dialog-label-input div {\n width: 30%;\n height: 100%;\n font-size: 16px;\n text-align: right;\n padding-right: 8px;\n background-color: white;\n}\n.igv-ui-generic-dialog-container .igv-ui-generic-dialog-label-input input {\n display: block;\n height: 100%;\n width: 100%;\n padding-left: 4px;\n font-family: "Open Sans", sans-serif;\n font-weight: 400;\n color: #373737;\n text-align: left;\n outline: none;\n border-style: solid;\n border-width: thin;\n border-color: #7F7F7F;\n background-color: white;\n}\n.igv-ui-generic-dialog-container .igv-ui-generic-dialog-label-input input {\n width: 50%;\n font-size: 16px;\n}\n.igv-ui-generic-dialog-container .igv-ui-generic-dialog-input {\n margin-top: 8px;\n width: calc(100% - 16px);\n height: 24px;\n color: #373737;\n line-height: 24px;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-around;\n align-items: center;\n}\n.igv-ui-generic-dialog-container .igv-ui-generic-dialog-input input {\n display: block;\n height: 100%;\n width: 100%;\n padding-left: 4px;\n font-family: "Open Sans", sans-serif;\n font-weight: 400;\n color: #373737;\n text-align: left;\n outline: none;\n border-style: solid;\n border-width: thin;\n border-color: #7F7F7F;\n background-color: white;\n}\n.igv-ui-generic-dialog-container .igv-ui-generic-dialog-input input {\n font-size: 16px;\n}\n.igv-ui-generic-dialog-container .igv-ui-generic-dialog-ok-cancel {\n width: 100%;\n height: 28px;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-around;\n align-items: center;\n}\n.igv-ui-generic-dialog-container .igv-ui-generic-dialog-ok-cancel div {\n margin-top: 32px;\n color: white;\n font-family: "Open Sans", sans-serif;\n font-size: 14px;\n font-weight: 400;\n width: 75px;\n height: 28px;\n line-height: 28px;\n text-align: center;\n border-color: transparent;\n border-style: solid;\n border-width: thin;\n border-radius: 2px;\n}\n.igv-ui-generic-dialog-container .igv-ui-generic-dialog-ok-cancel div:first-child {\n margin-left: 32px;\n margin-right: 0;\n background-color: #5ea4e0;\n}\n.igv-ui-generic-dialog-container .igv-ui-generic-dialog-ok-cancel div:last-child {\n margin-left: 0;\n margin-right: 32px;\n background-color: #c4c4c4;\n}\n.igv-ui-generic-dialog-container .igv-ui-generic-dialog-ok-cancel div:first-child:hover {\n cursor: pointer;\n background-color: #3b5c7f;\n}\n.igv-ui-generic-dialog-container .igv-ui-generic-dialog-ok-cancel div:last-child:hover {\n cursor: pointer;\n background-color: #7f7f7f;\n}\n.igv-ui-generic-dialog-container .igv-ui-generic-dialog-ok {\n width: 100%;\n height: 36px;\n margin-top: 32px;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-around;\n align-items: center;\n}\n.igv-ui-generic-dialog-container .igv-ui-generic-dialog-ok div {\n width: 98px;\n height: 36px;\n line-height: 36px;\n text-align: center;\n color: white;\n font-family: "Open Sans", sans-serif;\n font-size: medium;\n font-weight: 400;\n border-color: white;\n border-style: solid;\n border-width: thin;\n border-radius: 4px;\n background-color: #2B81AF;\n}\n.igv-ui-generic-dialog-container .igv-ui-generic-dialog-ok div:hover {\n cursor: pointer;\n background-color: #25597f;\n}\n\n.igv-ui-generic-container {\n box-sizing: content-box;\n position: absolute;\n z-index: 2048;\n background-color: white;\n cursor: pointer;\n display: flex;\n flex-direction: row;\n flex-wrap: wrap;\n justify-content: flex-start;\n align-items: center;\n}\n.igv-ui-generic-container > div:first-child {\n cursor: move;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-end;\n align-items: center;\n height: 24px;\n width: 100%;\n background-color: #dddddd;\n}\n.igv-ui-generic-container > div:first-child > div {\n display: block;\n color: #5f5f5f;\n cursor: pointer;\n width: 14px;\n height: 14px;\n margin-right: 8px;\n margin-bottom: 4px;\n}\n\n.igv-ui-dialog {\n z-index: 2048;\n position: fixed;\n width: fit-content;\n height: fit-content;\n display: flex;\n flex-flow: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n background-color: white;\n border-color: #7F7F7F;\n border-radius: 4px;\n border-style: solid;\n border-width: thin;\n font-family: "Open Sans", sans-serif;\n font-size: medium;\n font-weight: 400;\n}\n.igv-ui-dialog .igv-ui-dialog-header {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-end;\n align-items: center;\n width: 100%;\n height: 24px;\n cursor: move;\n border-top-left-radius: 4px;\n border-top-right-radius: 4px;\n border-bottom-color: #7F7F7F;\n border-bottom-style: solid;\n border-bottom-width: thin;\n background-color: #eee;\n}\n.igv-ui-dialog .igv-ui-dialog-header div {\n margin-right: 4px;\n margin-bottom: 2px;\n height: 12px;\n width: 12px;\n color: #7F7F7F;\n}\n.igv-ui-dialog .igv-ui-dialog-header div:hover {\n cursor: pointer;\n color: #444;\n}\n.igv-ui-dialog .igv-ui-dialog-one-liner {\n width: 95%;\n height: 24px;\n line-height: 24px;\n text-align: left;\n margin: 8px;\n overflow-wrap: break-word;\n background-color: white;\n font-weight: bold;\n}\n.igv-ui-dialog .igv-ui-dialog-ok-cancel {\n width: 100%;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-around;\n align-items: center;\n}\n.igv-ui-dialog .igv-ui-dialog-ok-cancel div {\n margin: 16px;\n margin-top: 32px;\n color: white;\n font-family: "Open Sans", sans-serif;\n font-size: 14px;\n font-weight: 400;\n width: 75px;\n height: 28px;\n line-height: 28px;\n text-align: center;\n border-color: transparent;\n border-style: solid;\n border-width: thin;\n border-radius: 2px;\n}\n.igv-ui-dialog .igv-ui-dialog-ok-cancel div:first-child {\n background-color: #5ea4e0;\n}\n.igv-ui-dialog .igv-ui-dialog-ok-cancel div:last-child {\n background-color: #c4c4c4;\n}\n.igv-ui-dialog .igv-ui-dialog-ok-cancel div:first-child:hover {\n cursor: pointer;\n background-color: #3b5c7f;\n}\n.igv-ui-dialog .igv-ui-dialog-ok-cancel div:last-child:hover {\n cursor: pointer;\n background-color: #7f7f7f;\n}\n.igv-ui-dialog .igv-ui-dialog-ok {\n width: 100%;\n height: 36px;\n margin-top: 32px;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-around;\n align-items: center;\n}\n.igv-ui-dialog .igv-ui-dialog-ok div {\n width: 98px;\n height: 36px;\n line-height: 36px;\n text-align: center;\n color: white;\n font-family: "Open Sans", sans-serif;\n font-size: medium;\n font-weight: 400;\n border-color: white;\n border-style: solid;\n border-width: thin;\n border-radius: 4px;\n background-color: #2B81AF;\n}\n.igv-ui-dialog .igv-ui-dialog-ok div:hover {\n cursor: pointer;\n background-color: #25597f;\n}\n\n.igv-ui-panel, .igv-ui-panel-row, .igv-ui-panel-column {\n z-index: 2048;\n background-color: white;\n font-family: "Open Sans", sans-serif;\n font-size: medium;\n font-weight: 400;\n display: flex;\n justify-content: flex-start;\n align-items: flex-start;\n}\n\n.igv-ui-panel-column {\n display: flex;\n flex-direction: column;\n}\n\n.igv-ui-panel-row {\n display: flex;\n flex-direction: row;\n}\n\n.igv-ui-textbox {\n background-color: white;\n font-family: "Open Sans", sans-serif;\n font-size: medium;\n font-weight: 400;\n display: flex;\n justify-content: flex-start;\n align-items: flex-start;\n}\n\n.igv-ui-table {\n background-color: white;\n}\n\n.igv-ui-table thead {\n position: sticky;\n top: 0;\n}\n\n.igv-ui-table th {\n text-align: left;\n}\n\n.igv-ui-table td {\n padding-right: 20px;\n}\n\n.igv-ui-table tr:hover {\n background-color: lightblue;\n}\n\n/*# sourceMappingURL=igv-ui.css.map */\n',document.head.append(e)}()}function Va(e,t){const i=xr.div({class:"igv-menu-popup-check-container"}),n=xr.div();i.appendChild(n);const o=xa.createIcon("check",!0===t?"#444":"transparent");n.appendChild(o);const r=xr.div();return r.innerText=e,i.appendChild(r),i}const Ua={trackMenuItemList:function(e){const t=new Set(["alignment","annotation","variant","eqtl","snp"]),i=e.track.config&&void 0!==e.track.config.visibilityWindow;let n=[];return"sequence"!==e.track.config.type&&(n.push(function(e){const t=t=>{const i=function(){let t=e.browser.inputDialog.value;t=""===t||void 0===t?"untitled":t.trim(),e.track.name=t},n={label:"Track Name",value:Wa(e.track)||"unnamed",callback:i};e.browser.inputDialog.present(n,t)},i=wr("
");return i.text("Set track name"),{object:i,click:t}}(e)),n.push(function(e){const t=t=>{const i=()=>{const t=Number(e.browser.inputDialog.value,10);void 0!==t&&(void 0!==e.track.minHeight&&e.track.minHeight>t&&(e.track.minHeight=t),void 0!==e.track.maxHeight&&e.track.maxHeight");return i.text("Set track height"),{object:i,click:t}}(e))),this.showColorPicker(e.track)&&(n.push("
"),n.push(ja({trackView:e,label:"Set track color",option:"color"})),n.push(function({trackView:e,label:t}){const i=wr("
");return i.text(t),{object:i,click:()=>{e.track.color=void 0,e.repaintViews()}}}({trackView:e,label:"Unset track color"})),"wig"!==e.track.config.type&&"annotation"!==e.track.config.type||(n.push(ja({trackView:e,label:"Set alt color",option:"altColor"})),n.push(function({trackView:e,label:t}){const i=wr("
");return i.text(t),{object:i,click:()=>{e.track.altColor=void 0,e.repaintViews()}}}({trackView:e,label:"Unset alt color"})))),e.track.menuItemList&&(n=n.concat(e.track.menuItemList())),(i||t.has(e.track.type))&&(n.push("
"),n.push(function(e){const t=t=>{const i=()=>{let t=e.browser.inputDialog.value;t=""===t||void 0===t?-1:t.trim(),e.track.visibilityWindow=Number.parseInt(t),e.track.config.visibilityWindow=Number.parseInt(t),e.updateViews()},n={label:"Visibility Window",value:e.track.visibilityWindow,callback:i};e.browser.inputDialog.present(n,t)},i=wr("
");return i.text("Set visibility window"),{object:i,click:t}}(e))),!1!==e.track.removable&&(n.push("
"),n.push(function(e){const t=wr("
");return t.text("Remove track"),{object:t,click:()=>e.browser.removeTrack(e.track)}}(e))),n},numericDataMenuItems:function(e){const t=[];t.push("
");const i=wr("
");i.text("Set data range");return t.push({object:i,click:()=>{e.browser.dataRangeDialog.configure(e),e.browser.dataRangeDialog.present(wr(e.browser.columnContainer))}}),void 0!==e.track.logScale&&t.push({object:wr(Va("Log scale",e.track.logScale)),click:()=>{e.track.logScale=!e.track.logScale,e.repaintViews()}}),t.push({object:wr(Va("Autoscale",e.track.autoscale)),click:()=>{e.track.autoscale=!e.track.autoscale,e.updateViews()}}),t},trackMenuItemListHelper:function(e,t){var i=[];return e.length>0&&(i=e.map((function(e,i){var n;if(e.name?(n=wr("
")).text(e.name):e.object?n=e.object:"string"==typeof e.label?(n=wr("
")).html(e.label):"string"==typeof e&&(n=e.startsWith("<")?wr(e):wr("
"+e+"
")),0===i&&n.addClass("igv-track-menu-border-top"),e.click){function o(i){e.click(i),t.hide(),i.preventDefault(),i.stopPropagation()}n.on("click",o),n.on("touchend",(function(e){o(e)})),n.on("mouseup",(function(e){e.preventDefault(),e.stopPropagation()}))}return{object:n,init:e.init||void 0}}))),i},showColorPicker:e=>void 0===e.type||"bedtype"===e.type||"alignment"===e.type||"annotation"===e.type||"variant"===e.type||"wig"===e.type||"interact"===e.type,createMenuItem(e,t){const i=wr("
");return i.text(e),{object:i,click:t}}};function ja({trackView:e,label:t,option:i}){const n=wr("
");return n.text(t),{object:n,click:()=>e.presentColorPicker(i)}}function Wa(e){return e.trackView.viewports[0].$trackLabel.text()}class Ga{constructor(e,t,i){this.browser=e,this.$container=wr("
",{class:"igv-generic-dialog-container"}),t.append(this.$container),this.$container.offset({left:0,top:0});const n=wr("
",{class:"igv-generic-dialog-header"});this.$container.append(n),Ea.attachDialogCloseHandlerWithParent(n[0],(()=>{this.$minimum_input.val(void 0),this.$maximum_input.val(void 0),this.$container.offset({left:0,top:0}),this.$container.hide()})),this.$minimum=wr("
",{class:"igv-generic-dialog-label-input"}),this.$container.append(this.$minimum);const o=wr("
");o.text("Minimum"),this.$minimum.append(o),this.$minimum_input=wr(""),this.$minimum.append(this.$minimum_input),this.$maximum=wr("
",{class:"igv-generic-dialog-label-input"}),this.$container.append(this.$maximum);const r=wr("
");r.text("Maximum"),this.$maximum.append(r),this.$maximum_input=wr(""),this.$maximum.append(this.$maximum_input);const a=wr("
",{class:"igv-generic-dialog-ok-cancel"});this.$container.append(a),this.$ok=wr("
"),a.append(this.$ok),this.$ok.text("OK"),this.$cancel=wr("
"),a.append(this.$cancel),this.$cancel.text("Cancel"),this.$cancel.on("click",(()=>{this.$minimum_input.val(void 0),this.$maximum_input.val(void 0),this.$container.offset({left:0,top:0}),this.$container.hide()})),Sa(this.$container.get(0),n.get(0)),this.$container.hide()}configure(e){const t=e.dataRange();let i,n;t?(i=t.min,n=t.max):(i=0,n=100),this.$minimum_input.val(i),this.$maximum_input.val(n),this.$minimum_input.unbind(),this.$minimum_input.on("keyup",(t=>{13===t.keyCode&&this.processResults(e)})),this.$maximum_input.unbind(),this.$maximum_input.on("keyup",(t=>{13===t.keyCode&&this.processResults(e)})),this.$ok.unbind(),this.$ok.on("click",(t=>{this.processResults(e)}))}processResults(e){const t=Number(this.$minimum_input.val()),i=Number(this.$maximum_input.val());isNaN(t)||isNaN(i)?this.browser.alert.present(new Error("Must input numeric values"),void 0):e.setDataRange(t,i),this.$minimum_input.val(void 0),this.$maximum_input.val(void 0),this.$container.offset({left:0,top:0}),this.$container.hide()}present(e){const t=e.offset().top,i=wr("body").scrollTop();this.$container.offset({left:e.width()-this.$container.width(),top:t+i}),this.$container.show()}}function $a(e){return"string"==typeof e||e instanceof String}function Za(e){var t=String(e).split(/[.,]/);return t[0].split("").reverse().reduce((function(e,t,i){return i%3==0?e+","+t:e+t})).split("").reverse().join("")+(t[1]?"."+t[1]:"")}const Ka=function(e){return e.split(/\n|\r\n|\r/g)};function Xa(e,t){var i,n,o=[],r=e.length,a=0,s=!1;if(r>0)for(o[a]=e.charAt(0),i=1;i0?e.charAt(0).toUpperCase()+e.slice(1):e}function Qa(e){if(void 0!==e.name)return e.name;if($a(e)){let t=e.lastIndexOf("/"),i=t<0?e:e.substr(t+1);return t=i.indexOf("?"),t>0&&(i=i.substr(0,t)),i}throw Error("Expected File or string, got "+typeof e)}function Ja(e){return!!e&&("function"!=typeof e&&(e instanceof File||e.hasOwnProperty("name")&&"function"==typeof e.slice&&"function"==typeof e.arrayBuffer))}function es(e,t){const i=document.createElement("a");i.setAttribute("href",t),i.setAttribute("download",e),i.style.display="none",document.body.appendChild(i),i.click(),document.body.removeChild(i)}function ts(e){for(var t=is,i=t.parser.loose.exec(e),n={},o=14;o--;)n[t.key[o]]=i[o]||"";return n[t.q.name]={},n[t.key[12]].replace(t.q.parser,(function(e,i,o){i&&(n[t.q.name][i]=o)})),n}"object"==typeof process&&"undefined"==typeof window&&(global.atob=function(e){return Buffer.from(e,"base64").toString("binary")});const is={strictMode:!1,key:["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"],q:{name:"queryKey",parser:/(?:^|&)([^&=]*)=?([^&]*)/g},parser:{strict:/^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/,loose:/^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/}};function ns(e){let t=e.length;for(;--t>=0;)e[t]=0}const os=256,rs=286,as=30,ss=15,cs=new Uint8Array([0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0]),ls=new Uint8Array([0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13]),hs=new Uint8Array([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7]),ds=new Uint8Array([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]),fs=new Array(576);ns(fs);const us=new Array(60);ns(us);const ps=new Array(512);ns(ps);const ms=new Array(256);ns(ms);const gs=new Array(29);ns(gs);const ws=new Array(as);function Fs(e,t,i,n,o){this.static_tree=e,this.extra_bits=t,this.extra_base=i,this.elems=n,this.max_length=o,this.has_stree=e&&e.length}let bs,vs,ys;function _s(e,t){this.dyn_tree=e,this.max_code=0,this.stat_desc=t}ns(ws);const Cs=e=>e<256?ps[e]:ps[256+(e>>>7)],xs=(e,t)=>{e.pending_buf[e.pending++]=255&t,e.pending_buf[e.pending++]=t>>>8&255},ks=(e,t,i)=>{e.bi_valid>16-i?(e.bi_buf|=t<>16-e.bi_valid,e.bi_valid+=i-16):(e.bi_buf|=t<{ks(e,i[2*t],i[2*t+1])},Ns=(e,t)=>{let i=0;do{i|=1&e,e>>>=1,i<<=1}while(--t>0);return i>>>1},Ss=(e,t,i)=>{const n=new Array(16);let o,r,a=0;for(o=1;o<=ss;o++)a=a+i[o-1]<<1,n[o]=a;for(r=0;r<=t;r++){let t=e[2*r+1];0!==t&&(e[2*r]=Ns(n[t]++,t))}},Is=e=>{let t;for(t=0;t{e.bi_valid>8?xs(e,e.bi_buf):e.bi_valid>0&&(e.pending_buf[e.pending++]=e.bi_buf),e.bi_buf=0,e.bi_valid=0},Ds=(e,t,i,n)=>{const o=2*t,r=2*i;return e[o]{const n=e.heap[i];let o=i<<1;for(;o<=e.heap_len&&(o{let n,o,r,a,s=0;if(0!==e.sym_next)do{n=255&e.pending_buf[e.sym_buf+s++],n+=(255&e.pending_buf[e.sym_buf+s++])<<8,o=e.pending_buf[e.sym_buf+s++],0===n?Es(e,o,t):(r=ms[o],Es(e,r+os+1,t),a=cs[r],0!==a&&(o-=gs[r],ks(e,o,a)),n--,r=Cs(n),Es(e,r,i),a=ls[r],0!==a&&(n-=ws[r],ks(e,n,a)))}while(s{const i=t.dyn_tree,n=t.stat_desc.static_tree,o=t.stat_desc.has_stree,r=t.stat_desc.elems;let a,s,c,l=-1;for(e.heap_len=0,e.heap_max=573,a=0;a>1;a>=1;a--)As(e,i,a);c=r;do{a=e.heap[1],e.heap[1]=e.heap[e.heap_len--],As(e,i,1),s=e.heap[1],e.heap[--e.heap_max]=a,e.heap[--e.heap_max]=s,i[2*c]=i[2*a]+i[2*s],e.depth[c]=(e.depth[a]>=e.depth[s]?e.depth[a]:e.depth[s])+1,i[2*a+1]=i[2*s+1]=c,e.heap[1]=c++,As(e,i,1)}while(e.heap_len>=2);e.heap[--e.heap_max]=e.heap[1],((e,t)=>{const i=t.dyn_tree,n=t.max_code,o=t.stat_desc.static_tree,r=t.stat_desc.has_stree,a=t.stat_desc.extra_bits,s=t.stat_desc.extra_base,c=t.stat_desc.max_length;let l,h,d,f,u,p,m=0;for(f=0;f<=ss;f++)e.bl_count[f]=0;for(i[2*e.heap[e.heap_max]+1]=0,l=e.heap_max+1;l<573;l++)h=e.heap[l],f=i[2*i[2*h+1]+1]+1,f>c&&(f=c,m++),i[2*h+1]=f,h>n||(e.bl_count[f]++,u=0,h>=s&&(u=a[h-s]),p=i[2*h],e.opt_len+=p*(f+u),r&&(e.static_len+=p*(o[2*h+1]+u)));if(0!==m){do{for(f=c-1;0===e.bl_count[f];)f--;e.bl_count[f]--,e.bl_count[f+1]+=2,e.bl_count[c]--,m-=2}while(m>0);for(f=c;0!==f;f--)for(h=e.bl_count[f];0!==h;)d=e.heap[--l],d>n||(i[2*d+1]!==f&&(e.opt_len+=(f-i[2*d+1])*i[2*d],i[2*d+1]=f),h--)}})(e,t),Ss(i,l,e.bl_count)},Rs=(e,t,i)=>{let n,o,r=-1,a=t[1],s=0,c=7,l=4;for(0===a&&(c=138,l=3),t[2*(i+1)+1]=65535,n=0;n<=i;n++)o=a,a=t[2*(n+1)+1],++s{let n,o,r=-1,a=t[1],s=0,c=7,l=4;for(0===a&&(c=138,l=3),n=0;n<=i;n++)if(o=a,a=t[2*(n+1)+1],!(++s{ks(e,0+(n?1:0),3),zs(e),xs(e,i),xs(e,~i),i&&e.pending_buf.set(e.window.subarray(t,t+i),e.pending),e.pending+=i};var Os=(e,t,i,n)=>{let o,r,a=0;e.level>0?(2===e.strm.data_type&&(e.strm.data_type=(e=>{let t,i=4093624447;for(t=0;t<=31;t++,i>>>=1)if(1&i&&0!==e.dyn_ltree[2*t])return 0;if(0!==e.dyn_ltree[18]||0!==e.dyn_ltree[20]||0!==e.dyn_ltree[26])return 1;for(t=32;t{let t;for(Rs(e,e.dyn_ltree,e.l_desc.max_code),Rs(e,e.dyn_dtree,e.d_desc.max_code),Ts(e,e.bl_desc),t=18;t>=3&&0===e.bl_tree[2*ds[t]+1];t--);return e.opt_len+=3*(t+1)+5+5+4,t})(e),o=e.opt_len+3+7>>>3,r=e.static_len+3+7>>>3,r<=o&&(o=r)):o=r=i+5,i+4<=o&&-1!==t?Hs(e,t,i,n):4===e.strategy||r===o?(ks(e,2+(n?1:0),3),Ms(e,fs,us)):(ks(e,4+(n?1:0),3),((e,t,i,n)=>{let o;for(ks(e,t-257,5),ks(e,i-1,5),ks(e,n-4,4),o=0;o{Bs||((()=>{let e,t,i,n,o;const r=new Array(16);for(i=0,n=0;n<28;n++)for(gs[n]=i,e=0;e<1<>=7;n(e.pending_buf[e.sym_buf+e.sym_next++]=t,e.pending_buf[e.sym_buf+e.sym_next++]=t>>8,e.pending_buf[e.sym_buf+e.sym_next++]=i,0===t?e.dyn_ltree[2*i]++:(e.matches++,t--,e.dyn_ltree[2*(ms[i]+os+1)]++,e.dyn_dtree[2*Cs(t)]++),e.sym_next===e.sym_end),_tr_align:e=>{ks(e,2,3),Es(e,256,fs),(e=>{16===e.bi_valid?(xs(e,e.bi_buf),e.bi_buf=0,e.bi_valid=0):e.bi_valid>=8&&(e.pending_buf[e.pending++]=255&e.bi_buf,e.bi_buf>>=8,e.bi_valid-=8)})(e)}};var qs=(e,t,i,n)=>{let o=65535&e,r=e>>>16&65535,a=0;for(;0!==i;){a=i>2e3?2e3:i,i-=a;do{o=o+t[n++]|0,r=r+o|0}while(--a);o%=65521,r%=65521}return o|r<<16};const Vs=new Uint32Array((()=>{let e,t=[];for(var i=0;i<256;i++){e=i;for(var n=0;n<8;n++)e=1&e?3988292384^e>>>1:e>>>1;t[i]=e}return t})());var Us=(e,t,i,n)=>{const o=Vs,r=n+i;e^=-1;for(let i=n;i>>8^o[255&(e^t[i])];return~e},js={2:"need dictionary",1:"stream end",0:"","-1":"file error","-2":"stream error","-3":"data error","-4":"insufficient memory","-5":"buffer error","-6":"incompatible version"},Ws={Z_NO_FLUSH:0,Z_PARTIAL_FLUSH:1,Z_SYNC_FLUSH:2,Z_FULL_FLUSH:3,Z_FINISH:4,Z_BLOCK:5,Z_TREES:6,Z_OK:0,Z_STREAM_END:1,Z_NEED_DICT:2,Z_ERRNO:-1,Z_STREAM_ERROR:-2,Z_DATA_ERROR:-3,Z_MEM_ERROR:-4,Z_BUF_ERROR:-5,Z_NO_COMPRESSION:0,Z_BEST_SPEED:1,Z_BEST_COMPRESSION:9,Z_DEFAULT_COMPRESSION:-1,Z_FILTERED:1,Z_HUFFMAN_ONLY:2,Z_RLE:3,Z_FIXED:4,Z_DEFAULT_STRATEGY:0,Z_BINARY:0,Z_TEXT:1,Z_UNKNOWN:2,Z_DEFLATED:8};const{_tr_init:Gs,_tr_stored_block:$s,_tr_flush_block:Zs,_tr_tally:Ks,_tr_align:Xs}=Ps,{Z_NO_FLUSH:Ys,Z_PARTIAL_FLUSH:Qs,Z_FULL_FLUSH:Js,Z_FINISH:ec,Z_BLOCK:tc,Z_OK:ic,Z_STREAM_END:nc,Z_STREAM_ERROR:oc,Z_DATA_ERROR:rc,Z_BUF_ERROR:ac,Z_DEFAULT_COMPRESSION:sc,Z_FILTERED:cc,Z_HUFFMAN_ONLY:lc,Z_RLE:hc,Z_FIXED:dc,Z_DEFAULT_STRATEGY:fc,Z_UNKNOWN:uc,Z_DEFLATED:pc}=Ws,mc=258,gc=262,wc=42,Fc=113,bc=666,vc=(e,t)=>(e.msg=js[t],t),yc=e=>2*e-(e>4?9:0),_c=e=>{let t=e.length;for(;--t>=0;)e[t]=0},Cc=e=>{let t,i,n,o=e.w_size;t=e.hash_size,n=t;do{i=e.head[--n],e.head[n]=i>=o?i-o:0}while(--t);t=o,n=t;do{i=e.prev[--n],e.prev[n]=i>=o?i-o:0}while(--t)};let xc=(e,t,i)=>(t<{const t=e.state;let i=t.pending;i>e.avail_out&&(i=e.avail_out),0!==i&&(e.output.set(t.pending_buf.subarray(t.pending_out,t.pending_out+i),e.next_out),e.next_out+=i,t.pending_out+=i,e.total_out+=i,e.avail_out-=i,t.pending-=i,0===t.pending&&(t.pending_out=0))},Ec=(e,t)=>{Zs(e,e.block_start>=0?e.block_start:-1,e.strstart-e.block_start,t),e.block_start=e.strstart,kc(e.strm)},Nc=(e,t)=>{e.pending_buf[e.pending++]=t},Sc=(e,t)=>{e.pending_buf[e.pending++]=t>>>8&255,e.pending_buf[e.pending++]=255&t},Ic=(e,t,i,n)=>{let o=e.avail_in;return o>n&&(o=n),0===o?0:(e.avail_in-=o,t.set(e.input.subarray(e.next_in,e.next_in+o),i),1===e.state.wrap?e.adler=qs(e.adler,t,o,i):2===e.state.wrap&&(e.adler=Us(e.adler,t,o,i)),e.next_in+=o,e.total_in+=o,o)},zc=(e,t)=>{let i,n,o=e.max_chain_length,r=e.strstart,a=e.prev_length,s=e.nice_match;const c=e.strstart>e.w_size-gc?e.strstart-(e.w_size-gc):0,l=e.window,h=e.w_mask,d=e.prev,f=e.strstart+mc;let u=l[r+a-1],p=l[r+a];e.prev_length>=e.good_match&&(o>>=2),s>e.lookahead&&(s=e.lookahead);do{if(i=t,l[i+a]===p&&l[i+a-1]===u&&l[i]===l[r]&&l[++i]===l[r+1]){r+=2,i++;do{}while(l[++r]===l[++i]&&l[++r]===l[++i]&&l[++r]===l[++i]&&l[++r]===l[++i]&&l[++r]===l[++i]&&l[++r]===l[++i]&&l[++r]===l[++i]&&l[++r]===l[++i]&&ra){if(e.match_start=t,a=n,n>=s)break;u=l[r+a-1],p=l[r+a]}}}while((t=d[t&h])>c&&0!=--o);return a<=e.lookahead?a:e.lookahead},Dc=e=>{const t=e.w_size;let i,n,o;do{if(n=e.window_size-e.lookahead-e.strstart,e.strstart>=t+(t-gc)&&(e.window.set(e.window.subarray(t,t+t-n),0),e.match_start-=t,e.strstart-=t,e.block_start-=t,e.insert>e.strstart&&(e.insert=e.strstart),Cc(e),n+=t),0===e.strm.avail_in)break;if(i=Ic(e.strm,e.window,e.strstart+e.lookahead,n),e.lookahead+=i,e.lookahead+e.insert>=3)for(o=e.strstart-e.insert,e.ins_h=e.window[o],e.ins_h=xc(e,e.ins_h,e.window[o+1]);e.insert&&(e.ins_h=xc(e,e.ins_h,e.window[o+3-1]),e.prev[o&e.w_mask]=e.head[e.ins_h],e.head[e.ins_h]=o,o++,e.insert--,!(e.lookahead+e.insert<3)););}while(e.lookahead{let i,n,o,r=e.pending_buf_size-5>e.w_size?e.w_size:e.pending_buf_size-5,a=0,s=e.strm.avail_in;do{if(i=65535,o=e.bi_valid+42>>3,e.strm.avail_outn+e.strm.avail_in&&(i=n+e.strm.avail_in),i>o&&(i=o),i>8,e.pending_buf[e.pending-2]=~i,e.pending_buf[e.pending-1]=~i>>8,kc(e.strm),n&&(n>i&&(n=i),e.strm.output.set(e.window.subarray(e.block_start,e.block_start+n),e.strm.next_out),e.strm.next_out+=n,e.strm.avail_out-=n,e.strm.total_out+=n,e.block_start+=n,i-=n),i&&(Ic(e.strm,e.strm.output,e.strm.next_out,i),e.strm.next_out+=i,e.strm.avail_out-=i,e.strm.total_out+=i)}while(0===a);return s-=e.strm.avail_in,s&&(s>=e.w_size?(e.matches=2,e.window.set(e.strm.input.subarray(e.strm.next_in-e.w_size,e.strm.next_in),0),e.strstart=e.w_size,e.insert=e.strstart):(e.window_size-e.strstart<=s&&(e.strstart-=e.w_size,e.window.set(e.window.subarray(e.w_size,e.w_size+e.strstart),0),e.matches<2&&e.matches++,e.insert>e.strstart&&(e.insert=e.strstart)),e.window.set(e.strm.input.subarray(e.strm.next_in-s,e.strm.next_in),e.strstart),e.strstart+=s,e.insert+=s>e.w_size-e.insert?e.w_size-e.insert:s),e.block_start=e.strstart),e.high_watero&&e.block_start>=e.w_size&&(e.block_start-=e.w_size,e.strstart-=e.w_size,e.window.set(e.window.subarray(e.w_size,e.w_size+e.strstart),0),e.matches<2&&e.matches++,o+=e.w_size,e.insert>e.strstart&&(e.insert=e.strstart)),o>e.strm.avail_in&&(o=e.strm.avail_in),o&&(Ic(e.strm,e.window,e.strstart,o),e.strstart+=o,e.insert+=o>e.w_size-e.insert?e.w_size-e.insert:o),e.high_water>3,o=e.pending_buf_size-o>65535?65535:e.pending_buf_size-o,r=o>e.w_size?e.w_size:o,n=e.strstart-e.block_start,(n>=r||(n||t===ec)&&t!==Ys&&0===e.strm.avail_in&&n<=o)&&(i=n>o?o:n,a=t===ec&&0===e.strm.avail_in&&i===n?1:0,$s(e,e.block_start,i,a),e.block_start+=i,kc(e.strm)),a?3:1)},Mc=(e,t)=>{let i,n;for(;;){if(e.lookahead=3&&(e.ins_h=xc(e,e.ins_h,e.window[e.strstart+3-1]),i=e.prev[e.strstart&e.w_mask]=e.head[e.ins_h],e.head[e.ins_h]=e.strstart),0!==i&&e.strstart-i<=e.w_size-gc&&(e.match_length=zc(e,i)),e.match_length>=3)if(n=Ks(e,e.strstart-e.match_start,e.match_length-3),e.lookahead-=e.match_length,e.match_length<=e.max_lazy_match&&e.lookahead>=3){e.match_length--;do{e.strstart++,e.ins_h=xc(e,e.ins_h,e.window[e.strstart+3-1]),i=e.prev[e.strstart&e.w_mask]=e.head[e.ins_h],e.head[e.ins_h]=e.strstart}while(0!=--e.match_length);e.strstart++}else e.strstart+=e.match_length,e.match_length=0,e.ins_h=e.window[e.strstart],e.ins_h=xc(e,e.ins_h,e.window[e.strstart+1]);else n=Ks(e,0,e.window[e.strstart]),e.lookahead--,e.strstart++;if(n&&(Ec(e,!1),0===e.strm.avail_out))return 1}return e.insert=e.strstart<2?e.strstart:2,t===ec?(Ec(e,!0),0===e.strm.avail_out?3:4):e.sym_next&&(Ec(e,!1),0===e.strm.avail_out)?1:2},Tc=(e,t)=>{let i,n,o;for(;;){if(e.lookahead=3&&(e.ins_h=xc(e,e.ins_h,e.window[e.strstart+3-1]),i=e.prev[e.strstart&e.w_mask]=e.head[e.ins_h],e.head[e.ins_h]=e.strstart),e.prev_length=e.match_length,e.prev_match=e.match_start,e.match_length=2,0!==i&&e.prev_length4096)&&(e.match_length=2)),e.prev_length>=3&&e.match_length<=e.prev_length){o=e.strstart+e.lookahead-3,n=Ks(e,e.strstart-1-e.prev_match,e.prev_length-3),e.lookahead-=e.prev_length-1,e.prev_length-=2;do{++e.strstart<=o&&(e.ins_h=xc(e,e.ins_h,e.window[e.strstart+3-1]),i=e.prev[e.strstart&e.w_mask]=e.head[e.ins_h],e.head[e.ins_h]=e.strstart)}while(0!=--e.prev_length);if(e.match_available=0,e.match_length=2,e.strstart++,n&&(Ec(e,!1),0===e.strm.avail_out))return 1}else if(e.match_available){if(n=Ks(e,0,e.window[e.strstart-1]),n&&Ec(e,!1),e.strstart++,e.lookahead--,0===e.strm.avail_out)return 1}else e.match_available=1,e.strstart++,e.lookahead--}return e.match_available&&(n=Ks(e,0,e.window[e.strstart-1]),e.match_available=0),e.insert=e.strstart<2?e.strstart:2,t===ec?(Ec(e,!0),0===e.strm.avail_out?3:4):e.sym_next&&(Ec(e,!1),0===e.strm.avail_out)?1:2};function Rc(e,t,i,n,o){this.good_length=e,this.max_lazy=t,this.nice_length=i,this.max_chain=n,this.func=o}const Lc=[new Rc(0,0,0,0,Ac),new Rc(4,4,8,4,Mc),new Rc(4,5,16,8,Mc),new Rc(4,6,32,32,Mc),new Rc(4,4,16,16,Tc),new Rc(8,16,32,32,Tc),new Rc(8,16,128,128,Tc),new Rc(8,32,128,256,Tc),new Rc(32,128,258,1024,Tc),new Rc(32,258,258,4096,Tc)];function Bc(){this.strm=null,this.status=0,this.pending_buf=null,this.pending_buf_size=0,this.pending_out=0,this.pending=0,this.wrap=0,this.gzhead=null,this.gzindex=0,this.method=pc,this.last_flush=-1,this.w_size=0,this.w_bits=0,this.w_mask=0,this.window=null,this.window_size=0,this.prev=null,this.head=null,this.ins_h=0,this.hash_size=0,this.hash_bits=0,this.hash_mask=0,this.hash_shift=0,this.block_start=0,this.match_length=0,this.prev_match=0,this.match_available=0,this.strstart=0,this.match_start=0,this.lookahead=0,this.prev_length=0,this.max_chain_length=0,this.max_lazy_match=0,this.level=0,this.strategy=0,this.good_match=0,this.nice_match=0,this.dyn_ltree=new Uint16Array(1146),this.dyn_dtree=new Uint16Array(122),this.bl_tree=new Uint16Array(78),_c(this.dyn_ltree),_c(this.dyn_dtree),_c(this.bl_tree),this.l_desc=null,this.d_desc=null,this.bl_desc=null,this.bl_count=new Uint16Array(16),this.heap=new Uint16Array(573),_c(this.heap),this.heap_len=0,this.heap_max=0,this.depth=new Uint16Array(573),_c(this.depth),this.sym_buf=0,this.lit_bufsize=0,this.sym_next=0,this.sym_end=0,this.opt_len=0,this.static_len=0,this.matches=0,this.insert=0,this.bi_buf=0,this.bi_valid=0}const Hc=e=>{if(!e)return 1;const t=e.state;return!t||t.strm!==e||t.status!==wc&&57!==t.status&&69!==t.status&&73!==t.status&&91!==t.status&&103!==t.status&&t.status!==Fc&&t.status!==bc?1:0},Oc=e=>{if(Hc(e))return vc(e,oc);e.total_in=e.total_out=0,e.data_type=uc;const t=e.state;return t.pending=0,t.pending_out=0,t.wrap<0&&(t.wrap=-t.wrap),t.status=2===t.wrap?57:t.wrap?wc:Fc,e.adler=2===t.wrap?0:1,t.last_flush=-2,Gs(t),ic},Pc=e=>{const t=Oc(e);var i;return t===ic&&((i=e.state).window_size=2*i.w_size,_c(i.head),i.max_lazy_match=Lc[i.level].max_lazy,i.good_match=Lc[i.level].good_length,i.nice_match=Lc[i.level].nice_length,i.max_chain_length=Lc[i.level].max_chain,i.strstart=0,i.block_start=0,i.lookahead=0,i.insert=0,i.match_length=i.prev_length=2,i.match_available=0,i.ins_h=0),t},qc=(e,t,i,n,o,r)=>{if(!e)return oc;let a=1;if(t===sc&&(t=6),n<0?(a=0,n=-n):n>15&&(a=2,n-=16),o<1||o>9||i!==pc||n<8||n>15||t<0||t>9||r<0||r>dc||8===n&&1!==a)return vc(e,oc);8===n&&(n=9);const s=new Bc;return e.state=s,s.strm=e,s.status=wc,s.wrap=a,s.gzhead=null,s.w_bits=n,s.w_size=1<{let i=t.length;if(Hc(e))return oc;const n=e.state,o=n.wrap;if(2===o||1===o&&n.status!==wc||n.lookahead)return oc;if(1===o&&(e.adler=qs(e.adler,t,i,0)),n.wrap=0,i>=n.w_size){0===o&&(_c(n.head),n.strstart=0,n.block_start=0,n.insert=0);let e=new Uint8Array(n.w_size);e.set(t.subarray(i-n.w_size,i),0),t=e,i=n.w_size}const r=e.avail_in,a=e.next_in,s=e.input;for(e.avail_in=i,e.next_in=0,e.input=t,Dc(n);n.lookahead>=3;){let e=n.strstart,t=n.lookahead-2;do{n.ins_h=xc(n,n.ins_h,n.window[e+3-1]),n.prev[e&n.w_mask]=n.head[n.ins_h],n.head[n.ins_h]=e,e++}while(--t);n.strstart=e,n.lookahead=2,Dc(n)}return n.strstart+=n.lookahead,n.block_start=n.strstart,n.insert=n.lookahead,n.lookahead=0,n.match_length=n.prev_length=2,n.match_available=0,e.next_in=a,e.input=s,e.avail_in=r,n.wrap=o,ic},Uc={deflateInit:(e,t)=>qc(e,t,pc,15,8,fc),deflateInit2:qc,deflateReset:Pc,deflateResetKeep:Oc,deflateSetHeader:(e,t)=>Hc(e)||2!==e.state.wrap?oc:(e.state.gzhead=t,ic),deflate:(e,t)=>{if(Hc(e)||t>tc||t<0)return e?vc(e,oc):oc;const i=e.state;if(!e.output||0!==e.avail_in&&!e.input||i.status===bc&&t!==ec)return vc(e,0===e.avail_out?ac:oc);const n=i.last_flush;if(i.last_flush=t,0!==i.pending){if(kc(e),0===e.avail_out)return i.last_flush=-1,ic}else if(0===e.avail_in&&yc(t)<=yc(n)&&t!==ec)return vc(e,ac);if(i.status===bc&&0!==e.avail_in)return vc(e,ac);if(i.status===wc&&0===i.wrap&&(i.status=Fc),i.status===wc){let t=pc+(i.w_bits-8<<4)<<8,n=-1;if(n=i.strategy>=lc||i.level<2?0:i.level<6?1:6===i.level?2:3,t|=n<<6,0!==i.strstart&&(t|=32),t+=31-t%31,Sc(i,t),0!==i.strstart&&(Sc(i,e.adler>>>16),Sc(i,65535&e.adler)),e.adler=1,i.status=Fc,kc(e),0!==i.pending)return i.last_flush=-1,ic}if(57===i.status)if(e.adler=0,Nc(i,31),Nc(i,139),Nc(i,8),i.gzhead)Nc(i,(i.gzhead.text?1:0)+(i.gzhead.hcrc?2:0)+(i.gzhead.extra?4:0)+(i.gzhead.name?8:0)+(i.gzhead.comment?16:0)),Nc(i,255&i.gzhead.time),Nc(i,i.gzhead.time>>8&255),Nc(i,i.gzhead.time>>16&255),Nc(i,i.gzhead.time>>24&255),Nc(i,9===i.level?2:i.strategy>=lc||i.level<2?4:0),Nc(i,255&i.gzhead.os),i.gzhead.extra&&i.gzhead.extra.length&&(Nc(i,255&i.gzhead.extra.length),Nc(i,i.gzhead.extra.length>>8&255)),i.gzhead.hcrc&&(e.adler=Us(e.adler,i.pending_buf,i.pending,0)),i.gzindex=0,i.status=69;else if(Nc(i,0),Nc(i,0),Nc(i,0),Nc(i,0),Nc(i,0),Nc(i,9===i.level?2:i.strategy>=lc||i.level<2?4:0),Nc(i,3),i.status=Fc,kc(e),0!==i.pending)return i.last_flush=-1,ic;if(69===i.status){if(i.gzhead.extra){let t=i.pending,n=(65535&i.gzhead.extra.length)-i.gzindex;for(;i.pending+n>i.pending_buf_size;){let o=i.pending_buf_size-i.pending;if(i.pending_buf.set(i.gzhead.extra.subarray(i.gzindex,i.gzindex+o),i.pending),i.pending=i.pending_buf_size,i.gzhead.hcrc&&i.pending>t&&(e.adler=Us(e.adler,i.pending_buf,i.pending-t,t)),i.gzindex+=o,kc(e),0!==i.pending)return i.last_flush=-1,ic;t=0,n-=o}let o=new Uint8Array(i.gzhead.extra);i.pending_buf.set(o.subarray(i.gzindex,i.gzindex+n),i.pending),i.pending+=n,i.gzhead.hcrc&&i.pending>t&&(e.adler=Us(e.adler,i.pending_buf,i.pending-t,t)),i.gzindex=0}i.status=73}if(73===i.status){if(i.gzhead.name){let t,n=i.pending;do{if(i.pending===i.pending_buf_size){if(i.gzhead.hcrc&&i.pending>n&&(e.adler=Us(e.adler,i.pending_buf,i.pending-n,n)),kc(e),0!==i.pending)return i.last_flush=-1,ic;n=0}t=i.gzindexn&&(e.adler=Us(e.adler,i.pending_buf,i.pending-n,n)),i.gzindex=0}i.status=91}if(91===i.status){if(i.gzhead.comment){let t,n=i.pending;do{if(i.pending===i.pending_buf_size){if(i.gzhead.hcrc&&i.pending>n&&(e.adler=Us(e.adler,i.pending_buf,i.pending-n,n)),kc(e),0!==i.pending)return i.last_flush=-1,ic;n=0}t=i.gzindexn&&(e.adler=Us(e.adler,i.pending_buf,i.pending-n,n))}i.status=103}if(103===i.status){if(i.gzhead.hcrc){if(i.pending+2>i.pending_buf_size&&(kc(e),0!==i.pending))return i.last_flush=-1,ic;Nc(i,255&e.adler),Nc(i,e.adler>>8&255),e.adler=0}if(i.status=Fc,kc(e),0!==i.pending)return i.last_flush=-1,ic}if(0!==e.avail_in||0!==i.lookahead||t!==Ys&&i.status!==bc){let n=0===i.level?Ac(i,t):i.strategy===lc?((e,t)=>{let i;for(;;){if(0===e.lookahead&&(Dc(e),0===e.lookahead)){if(t===Ys)return 1;break}if(e.match_length=0,i=Ks(e,0,e.window[e.strstart]),e.lookahead--,e.strstart++,i&&(Ec(e,!1),0===e.strm.avail_out))return 1}return e.insert=0,t===ec?(Ec(e,!0),0===e.strm.avail_out?3:4):e.sym_next&&(Ec(e,!1),0===e.strm.avail_out)?1:2})(i,t):i.strategy===hc?((e,t)=>{let i,n,o,r;const a=e.window;for(;;){if(e.lookahead<=mc){if(Dc(e),e.lookahead<=mc&&t===Ys)return 1;if(0===e.lookahead)break}if(e.match_length=0,e.lookahead>=3&&e.strstart>0&&(o=e.strstart-1,n=a[o],n===a[++o]&&n===a[++o]&&n===a[++o])){r=e.strstart+mc;do{}while(n===a[++o]&&n===a[++o]&&n===a[++o]&&n===a[++o]&&n===a[++o]&&n===a[++o]&&n===a[++o]&&n===a[++o]&&oe.lookahead&&(e.match_length=e.lookahead)}if(e.match_length>=3?(i=Ks(e,1,e.match_length-3),e.lookahead-=e.match_length,e.strstart+=e.match_length,e.match_length=0):(i=Ks(e,0,e.window[e.strstart]),e.lookahead--,e.strstart++),i&&(Ec(e,!1),0===e.strm.avail_out))return 1}return e.insert=0,t===ec?(Ec(e,!0),0===e.strm.avail_out?3:4):e.sym_next&&(Ec(e,!1),0===e.strm.avail_out)?1:2})(i,t):Lc[i.level].func(i,t);if(3!==n&&4!==n||(i.status=bc),1===n||3===n)return 0===e.avail_out&&(i.last_flush=-1),ic;if(2===n&&(t===Qs?Xs(i):t!==tc&&($s(i,0,0,!1),t===Js&&(_c(i.head),0===i.lookahead&&(i.strstart=0,i.block_start=0,i.insert=0))),kc(e),0===e.avail_out))return i.last_flush=-1,ic}return t!==ec?ic:i.wrap<=0?nc:(2===i.wrap?(Nc(i,255&e.adler),Nc(i,e.adler>>8&255),Nc(i,e.adler>>16&255),Nc(i,e.adler>>24&255),Nc(i,255&e.total_in),Nc(i,e.total_in>>8&255),Nc(i,e.total_in>>16&255),Nc(i,e.total_in>>24&255)):(Sc(i,e.adler>>>16),Sc(i,65535&e.adler)),kc(e),i.wrap>0&&(i.wrap=-i.wrap),0!==i.pending?ic:nc)},deflateEnd:e=>{if(Hc(e))return oc;const t=e.state.status;return e.state=null,t===Fc?vc(e,rc):ic},deflateSetDictionary:Vc,deflateInfo:"pako deflate (from Nodeca project)"};const jc=(e,t)=>Object.prototype.hasOwnProperty.call(e,t);var Wc=function(e){const t=Array.prototype.slice.call(arguments,1);for(;t.length;){const i=t.shift();if(i){if("object"!=typeof i)throw new TypeError(i+"must be non-object");for(const t in i)jc(i,t)&&(e[t]=i[t])}}return e},Gc=e=>{let t=0;for(let i=0,n=e.length;i=252?6:Mk>=248?5:Mk>=240?4:Mk>=224?3:Mk>=192?2:1;Zc[254]=Zc[254]=1;var Kc=e=>{if("function"==typeof TextEncoder&&TextEncoder.prototype.encode)return(new TextEncoder).encode(e);let t,i,n,o,r,a=e.length,s=0;for(o=0;o>>6,t[r++]=128|63&i):i<65536?(t[r++]=224|i>>>12,t[r++]=128|i>>>6&63,t[r++]=128|63&i):(t[r++]=240|i>>>18,t[r++]=128|i>>>12&63,t[r++]=128|i>>>6&63,t[r++]=128|63&i);return t},Xc=(e,t)=>{const i=t||e.length;if("function"==typeof TextDecoder&&TextDecoder.prototype.decode)return(new TextDecoder).decode(e.subarray(0,t));let n,o;const r=new Array(2*i);for(o=0,n=0;n4)r[o++]=65533,n+=a-1;else{for(t&=2===a?31:3===a?15:7;a>1&&n1?r[o++]=65533:t<65536?r[o++]=t:(t-=65536,r[o++]=55296|t>>10&1023,r[o++]=56320|1023&t)}}return((e,t)=>{if(t<65534&&e.subarray&&$c)return String.fromCharCode.apply(null,e.length===t?e:e.subarray(0,t));let i="";for(let n=0;n{(t=t||e.length)>e.length&&(t=e.length);let i=t-1;for(;i>=0&&128==(192&e[i]);)i--;return i<0||0===i?t:i+Zc[e[i]]>t?i:t};var Qc=function(){this.input=null,this.next_in=0,this.avail_in=0,this.total_in=0,this.output=null,this.next_out=0,this.avail_out=0,this.total_out=0,this.msg="",this.state=null,this.data_type=2,this.adler=0};const Jc=Object.prototype.toString,{Z_NO_FLUSH:el,Z_SYNC_FLUSH:tl,Z_FULL_FLUSH:il,Z_FINISH:nl,Z_OK:ol,Z_STREAM_END:rl,Z_DEFAULT_COMPRESSION:al,Z_DEFAULT_STRATEGY:sl,Z_DEFLATED:cl}=Ws;function ll(e){this.options=Wc({level:al,method:cl,chunkSize:16384,windowBits:15,memLevel:8,strategy:sl},e||{});let t=this.options;t.raw&&t.windowBits>0?t.windowBits=-t.windowBits:t.gzip&&t.windowBits>0&&t.windowBits<16&&(t.windowBits+=16),this.err=0,this.msg="",this.ended=!1,this.chunks=[],this.strm=new Qc,this.strm.avail_out=0;let i=Uc.deflateInit2(this.strm,t.level,t.method,t.windowBits,t.memLevel,t.strategy);if(i!==ol)throw new Error(js[i]);if(t.header&&Uc.deflateSetHeader(this.strm,t.header),t.dictionary){let e;if(e="string"==typeof t.dictionary?Kc(t.dictionary):"[object ArrayBuffer]"===Jc.call(t.dictionary)?new Uint8Array(t.dictionary):t.dictionary,i=Uc.deflateSetDictionary(this.strm,e),i!==ol)throw new Error(js[i]);this._dict_set=!0}}function hl(e,t){const i=new ll(t);if(i.push(e,!0),i.err)throw i.msg||js[i.err];return i.result}ll.prototype.push=function(e,t){const i=this.strm,n=this.options.chunkSize;let o,r;if(this.ended)return!1;for(r=t===~~t?t:!0===t?nl:el,"string"==typeof e?i.input=Kc(e):"[object ArrayBuffer]"===Jc.call(e)?i.input=new Uint8Array(e):i.input=e,i.next_in=0,i.avail_in=i.input.length;;)if(0===i.avail_out&&(i.output=new Uint8Array(n),i.next_out=0,i.avail_out=n),(r===tl||r===il)&&i.avail_out<=6)this.onData(i.output.subarray(0,i.next_out)),i.avail_out=0;else{if(o=Uc.deflate(i,r),o===rl)return i.next_out>0&&this.onData(i.output.subarray(0,i.next_out)),o=Uc.deflateEnd(this.strm),this.onEnd(o),this.ended=!0,o===ol;if(0!==i.avail_out){if(r>0&&i.next_out>0)this.onData(i.output.subarray(0,i.next_out)),i.avail_out=0;else if(0===i.avail_in)break}else this.onData(i.output)}return!0},ll.prototype.onData=function(e){this.chunks.push(e)},ll.prototype.onEnd=function(e){e===ol&&(this.result=Gc(this.chunks)),this.chunks=[],this.err=e,this.msg=this.strm.msg};var dl=function(e,t){return(t=t||{}).raw=!0,hl(e,t)},fl=function(e,t){return(t=t||{}).gzip=!0,hl(e,t)},ul={Deflate:ll,deflate:hl,deflateRaw:dl,gzip:fl,constants:Ws};const pl=16209;var ml=function(e,t){let i,n,o,r,a,s,c,l,h,d,f,u,p,m,g,w,F,b,v,y,_,C,x,k;const E=e.state;i=e.next_in,x=e.input,n=i+(e.avail_in-5),o=e.next_out,k=e.output,r=o-(t-e.avail_out),a=o+(e.avail_out-257),s=E.dmax,c=E.wsize,l=E.whave,h=E.wnext,d=E.window,f=E.hold,u=E.bits,p=E.lencode,m=E.distcode,g=(1<>>24,f>>>=b,u-=b,b=F>>>16&255,0===b)k[o++]=65535&F;else{if(!(16&b)){if(64&b){if(32&b){E.mode=16191;break e}e.msg="invalid literal/length code",E.mode=pl;break e}F=p[(65535&F)+(f&(1<>>=b,u-=b),u<15&&(f+=x[i++]<>>24,f>>>=b,u-=b,b=F>>>16&255,16&b){if(y=65535&F,b&=15,us){e.msg="invalid distance too far back",E.mode=pl;break e}if(f>>>=b,u-=b,b=o-r,y>b){if(b=y-b,b>l&&E.sane){e.msg="invalid distance too far back",E.mode=pl;break e}if(_=0,C=d,0===h){if(_+=c-b,b2;)k[o++]=C[_++],k[o++]=C[_++],k[o++]=C[_++],v-=3;v&&(k[o++]=C[_++],v>1&&(k[o++]=C[_++]))}else{_=o-y;do{k[o++]=k[_++],k[o++]=k[_++],k[o++]=k[_++],v-=3}while(v>2);v&&(k[o++]=k[_++],v>1&&(k[o++]=k[_++]))}break}if(64&b){e.msg="invalid distance code",E.mode=pl;break e}F=m[(65535&F)+(f&(1<>3,i-=v,u-=v<<3,f&=(1<{const c=s.bits;let l,h,d,f,u,p,m=0,g=0,w=0,F=0,b=0,v=0,y=0,_=0,C=0,x=0,k=null;const E=new Uint16Array(16),N=new Uint16Array(16);let S,I,z,D=null;for(m=0;m<=gl;m++)E[m]=0;for(g=0;g=1&&0===E[F];F--);if(b>F&&(b=F),0===F)return o[r++]=20971520,o[r++]=20971520,s.bits=1,0;for(w=1;w0&&(0===e||1!==F))return-1;for(N[1]=0,m=1;m852||2===e&&C>592)return 1;for(;;){S=m-y,a[g]+1=p?(I=D[a[g]-p],z=k[a[g]-p]):(I=96,z=0),l=1<>y)+h]=S<<24|I<<16|z}while(0!==h);for(l=1<>=1;if(0!==l?(x&=l-1,x+=l):x=0,g++,0==--E[m]){if(m===F)break;m=t[i+a[g]]}if(m>b&&(x&f)!==d){for(0===y&&(y=b),u+=w,v=m-y,_=1<852||2===e&&C>592)return 1;d=x&f,o[d]=b<<24|v<<16|u-r}}return 0!==x&&(o[u+x]=m-y<<24|64<<16),s.bits=b,0};const{Z_FINISH:_l,Z_BLOCK:Cl,Z_TREES:xl,Z_OK:kl,Z_STREAM_END:El,Z_NEED_DICT:Nl,Z_STREAM_ERROR:Sl,Z_DATA_ERROR:Il,Z_MEM_ERROR:zl,Z_BUF_ERROR:Dl,Z_DEFLATED:Al}=Ws,Ml=16180,Tl=16190,Rl=16191,Ll=16192,Bl=16194,Hl=16199,Ol=16200,Pl=16206,ql=16209,Vl=e=>(e>>>24&255)+(e>>>8&65280)+((65280&e)<<8)+((255&e)<<24);function Ul(){this.strm=null,this.mode=0,this.last=!1,this.wrap=0,this.havedict=!1,this.flags=0,this.dmax=0,this.check=0,this.total=0,this.head=null,this.wbits=0,this.wsize=0,this.whave=0,this.wnext=0,this.window=null,this.hold=0,this.bits=0,this.length=0,this.offset=0,this.extra=0,this.lencode=null,this.distcode=null,this.lenbits=0,this.distbits=0,this.ncode=0,this.nlen=0,this.ndist=0,this.have=0,this.next=null,this.lens=new Uint16Array(320),this.work=new Uint16Array(288),this.lendyn=null,this.distdyn=null,this.sane=0,this.back=0,this.was=0}const jl=e=>{if(!e)return 1;const t=e.state;return!t||t.strm!==e||t.mode16211?1:0},Wl=e=>{if(jl(e))return Sl;const t=e.state;return e.total_in=e.total_out=t.total=0,e.msg="",t.wrap&&(e.adler=1&t.wrap),t.mode=Ml,t.last=0,t.havedict=0,t.flags=-1,t.dmax=32768,t.head=null,t.hold=0,t.bits=0,t.lencode=t.lendyn=new Int32Array(852),t.distcode=t.distdyn=new Int32Array(592),t.sane=1,t.back=-1,kl},Gl=e=>{if(jl(e))return Sl;const t=e.state;return t.wsize=0,t.whave=0,t.wnext=0,Wl(e)},$l=(e,t)=>{let i;if(jl(e))return Sl;const n=e.state;return t<0?(i=0,t=-t):(i=5+(t>>4),t<48&&(t&=15)),t&&(t<8||t>15)?Sl:(null!==n.window&&n.wbits!==t&&(n.window=null),n.wrap=i,n.wbits=t,Gl(e))},Zl=(e,t)=>{if(!e)return Sl;const i=new Ul;e.state=i,i.strm=e,i.window=null,i.mode=Ml;const n=$l(e,t);return n!==kl&&(e.state=null),n};let Kl,Xl,Yl=!0;const Ql=e=>{if(Yl){Kl=new Int32Array(512),Xl=new Int32Array(32);let t=0;for(;t<144;)e.lens[t++]=8;for(;t<256;)e.lens[t++]=9;for(;t<280;)e.lens[t++]=7;for(;t<288;)e.lens[t++]=8;for(yl(1,e.lens,0,288,Kl,0,e.work,{bits:9}),t=0;t<32;)e.lens[t++]=5;yl(2,e.lens,0,32,Xl,0,e.work,{bits:5}),Yl=!1}e.lencode=Kl,e.lenbits=9,e.distcode=Xl,e.distbits=5},Jl=(e,t,i,n)=>{let o;const r=e.state;return null===r.window&&(r.wsize=1<=r.wsize?(r.window.set(t.subarray(i-r.wsize,i),0),r.wnext=0,r.whave=r.wsize):(o=r.wsize-r.wnext,o>n&&(o=n),r.window.set(t.subarray(i-n,i-n+o),r.wnext),(n-=o)?(r.window.set(t.subarray(i-n,i),0),r.wnext=n,r.whave=r.wsize):(r.wnext+=o,r.wnext===r.wsize&&(r.wnext=0),r.whave{let i,n,o,r,a,s,c,l,h,d,f,u,p,m,g,w,F,b,v,y,_,C,x=0;const k=new Uint8Array(4);let E,N;const S=new Uint8Array([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]);if(jl(e)||!e.output||!e.input&&0!==e.avail_in)return Sl;i=e.state,i.mode===Rl&&(i.mode=Ll),a=e.next_out,o=e.output,c=e.avail_out,r=e.next_in,n=e.input,s=e.avail_in,l=i.hold,h=i.bits,d=s,f=c,C=kl;e:for(;;)switch(i.mode){case Ml:if(0===i.wrap){i.mode=Ll;break}for(;h<16;){if(0===s)break e;s--,l+=n[r++]<>>8&255,i.check=Us(i.check,k,2,0),l=0,h=0,i.mode=16181;break}if(i.head&&(i.head.done=!1),!(1&i.wrap)||(((255&l)<<8)+(l>>8))%31){e.msg="incorrect header check",i.mode=ql;break}if((15&l)!==Al){e.msg="unknown compression method",i.mode=ql;break}if(l>>>=4,h-=4,_=8+(15&l),0===i.wbits&&(i.wbits=_),_>15||_>i.wbits){e.msg="invalid window size",i.mode=ql;break}i.dmax=1<>8&1),512&i.flags&&4&i.wrap&&(k[0]=255&l,k[1]=l>>>8&255,i.check=Us(i.check,k,2,0)),l=0,h=0,i.mode=16182;case 16182:for(;h<32;){if(0===s)break e;s--,l+=n[r++]<>>8&255,k[2]=l>>>16&255,k[3]=l>>>24&255,i.check=Us(i.check,k,4,0)),l=0,h=0,i.mode=16183;case 16183:for(;h<16;){if(0===s)break e;s--,l+=n[r++]<>8),512&i.flags&&4&i.wrap&&(k[0]=255&l,k[1]=l>>>8&255,i.check=Us(i.check,k,2,0)),l=0,h=0,i.mode=16184;case 16184:if(1024&i.flags){for(;h<16;){if(0===s)break e;s--,l+=n[r++]<>>8&255,i.check=Us(i.check,k,2,0)),l=0,h=0}else i.head&&(i.head.extra=null);i.mode=16185;case 16185:if(1024&i.flags&&(u=i.length,u>s&&(u=s),u&&(i.head&&(_=i.head.extra_len-i.length,i.head.extra||(i.head.extra=new Uint8Array(i.head.extra_len)),i.head.extra.set(n.subarray(r,r+u),_)),512&i.flags&&4&i.wrap&&(i.check=Us(i.check,n,u,r)),s-=u,r+=u,i.length-=u),i.length))break e;i.length=0,i.mode=16186;case 16186:if(2048&i.flags){if(0===s)break e;u=0;do{_=n[r+u++],i.head&&_&&i.length<65536&&(i.head.name+=String.fromCharCode(_))}while(_&&u>9&1,i.head.done=!0),e.adler=i.check=0,i.mode=Rl;break;case 16189:for(;h<32;){if(0===s)break e;s--,l+=n[r++]<>>=7&h,h-=7&h,i.mode=Pl;break}for(;h<3;){if(0===s)break e;s--,l+=n[r++]<>>=1,h-=1,3&l){case 0:i.mode=16193;break;case 1:if(Ql(i),i.mode=Hl,t===xl){l>>>=2,h-=2;break e}break;case 2:i.mode=16196;break;case 3:e.msg="invalid block type",i.mode=ql}l>>>=2,h-=2;break;case 16193:for(l>>>=7&h,h-=7&h;h<32;){if(0===s)break e;s--,l+=n[r++]<>>16^65535)){e.msg="invalid stored block lengths",i.mode=ql;break}if(i.length=65535&l,l=0,h=0,i.mode=Bl,t===xl)break e;case Bl:i.mode=16195;case 16195:if(u=i.length,u){if(u>s&&(u=s),u>c&&(u=c),0===u)break e;o.set(n.subarray(r,r+u),a),s-=u,r+=u,c-=u,a+=u,i.length-=u;break}i.mode=Rl;break;case 16196:for(;h<14;){if(0===s)break e;s--,l+=n[r++]<>>=5,h-=5,i.ndist=1+(31&l),l>>>=5,h-=5,i.ncode=4+(15&l),l>>>=4,h-=4,i.nlen>286||i.ndist>30){e.msg="too many length or distance symbols",i.mode=ql;break}i.have=0,i.mode=16197;case 16197:for(;i.have>>=3,h-=3}for(;i.have<19;)i.lens[S[i.have++]]=0;if(i.lencode=i.lendyn,i.lenbits=7,E={bits:i.lenbits},C=yl(0,i.lens,0,19,i.lencode,0,i.work,E),i.lenbits=E.bits,C){e.msg="invalid code lengths set",i.mode=ql;break}i.have=0,i.mode=16198;case 16198:for(;i.have>>24,w=x>>>16&255,F=65535&x,!(g<=h);){if(0===s)break e;s--,l+=n[r++]<>>=g,h-=g,i.lens[i.have++]=F;else{if(16===F){for(N=g+2;h>>=g,h-=g,0===i.have){e.msg="invalid bit length repeat",i.mode=ql;break}_=i.lens[i.have-1],u=3+(3&l),l>>>=2,h-=2}else if(17===F){for(N=g+3;h>>=g,h-=g,_=0,u=3+(7&l),l>>>=3,h-=3}else{for(N=g+7;h>>=g,h-=g,_=0,u=11+(127&l),l>>>=7,h-=7}if(i.have+u>i.nlen+i.ndist){e.msg="invalid bit length repeat",i.mode=ql;break}for(;u--;)i.lens[i.have++]=_}}if(i.mode===ql)break;if(0===i.lens[256]){e.msg="invalid code -- missing end-of-block",i.mode=ql;break}if(i.lenbits=9,E={bits:i.lenbits},C=yl(1,i.lens,0,i.nlen,i.lencode,0,i.work,E),i.lenbits=E.bits,C){e.msg="invalid literal/lengths set",i.mode=ql;break}if(i.distbits=6,i.distcode=i.distdyn,E={bits:i.distbits},C=yl(2,i.lens,i.nlen,i.ndist,i.distcode,0,i.work,E),i.distbits=E.bits,C){e.msg="invalid distances set",i.mode=ql;break}if(i.mode=Hl,t===xl)break e;case Hl:i.mode=Ol;case Ol:if(s>=6&&c>=258){e.next_out=a,e.avail_out=c,e.next_in=r,e.avail_in=s,i.hold=l,i.bits=h,ml(e,f),a=e.next_out,o=e.output,c=e.avail_out,r=e.next_in,n=e.input,s=e.avail_in,l=i.hold,h=i.bits,i.mode===Rl&&(i.back=-1);break}for(i.back=0;x=i.lencode[l&(1<>>24,w=x>>>16&255,F=65535&x,!(g<=h);){if(0===s)break e;s--,l+=n[r++]<>b)],g=x>>>24,w=x>>>16&255,F=65535&x,!(b+g<=h);){if(0===s)break e;s--,l+=n[r++]<>>=b,h-=b,i.back+=b}if(l>>>=g,h-=g,i.back+=g,i.length=F,0===w){i.mode=16205;break}if(32&w){i.back=-1,i.mode=Rl;break}if(64&w){e.msg="invalid literal/length code",i.mode=ql;break}i.extra=15&w,i.mode=16201;case 16201:if(i.extra){for(N=i.extra;h>>=i.extra,h-=i.extra,i.back+=i.extra}i.was=i.length,i.mode=16202;case 16202:for(;x=i.distcode[l&(1<>>24,w=x>>>16&255,F=65535&x,!(g<=h);){if(0===s)break e;s--,l+=n[r++]<>b)],g=x>>>24,w=x>>>16&255,F=65535&x,!(b+g<=h);){if(0===s)break e;s--,l+=n[r++]<>>=b,h-=b,i.back+=b}if(l>>>=g,h-=g,i.back+=g,64&w){e.msg="invalid distance code",i.mode=ql;break}i.offset=F,i.extra=15&w,i.mode=16203;case 16203:if(i.extra){for(N=i.extra;h>>=i.extra,h-=i.extra,i.back+=i.extra}if(i.offset>i.dmax){e.msg="invalid distance too far back",i.mode=ql;break}i.mode=16204;case 16204:if(0===c)break e;if(u=f-c,i.offset>u){if(u=i.offset-u,u>i.whave&&i.sane){e.msg="invalid distance too far back",i.mode=ql;break}u>i.wnext?(u-=i.wnext,p=i.wsize-u):p=i.wnext-u,u>i.length&&(u=i.length),m=i.window}else m=o,p=a-i.offset,u=i.length;u>c&&(u=c),c-=u,i.length-=u;do{o[a++]=m[p++]}while(--u);0===i.length&&(i.mode=Ol);break;case 16205:if(0===c)break e;o[a++]=i.length,c--,i.mode=Ol;break;case Pl:if(i.wrap){for(;h<32;){if(0===s)break e;s--,l|=n[r++]<Zl(e,15),inflateInit2:Zl,inflate:eh,inflateEnd:e=>{if(jl(e))return Sl;let t=e.state;return t.window&&(t.window=null),e.state=null,kl},inflateGetHeader:(e,t)=>{if(jl(e))return Sl;const i=e.state;return 2&i.wrap?(i.head=t,t.done=!1,kl):Sl},inflateSetDictionary:(e,t)=>{const i=t.length;let n,o,r;return jl(e)?Sl:(n=e.state,0!==n.wrap&&n.mode!==Tl?Sl:n.mode===Tl&&(o=1,o=qs(o,t,i,0),o!==n.check)?Il:(r=Jl(e,t,i,i),r?(n.mode=16210,zl):(n.havedict=1,kl)))},inflateInfo:"pako inflate (from Nodeca project)"};var ih=function(){this.text=0,this.time=0,this.xflags=0,this.os=0,this.extra=null,this.extra_len=0,this.name="",this.comment="",this.hcrc=0,this.done=!1};const nh=Object.prototype.toString,{Z_NO_FLUSH:oh,Z_FINISH:rh,Z_OK:ah,Z_STREAM_END:sh,Z_NEED_DICT:ch,Z_STREAM_ERROR:lh,Z_DATA_ERROR:hh,Z_MEM_ERROR:dh}=Ws;function fh(e){this.options=Wc({chunkSize:65536,windowBits:15,to:""},e||{});const t=this.options;t.raw&&t.windowBits>=0&&t.windowBits<16&&(t.windowBits=-t.windowBits,0===t.windowBits&&(t.windowBits=-15)),!(t.windowBits>=0&&t.windowBits<16)||e&&e.windowBits||(t.windowBits+=32),t.windowBits>15&&t.windowBits<48&&(15&t.windowBits||(t.windowBits|=15)),this.err=0,this.msg="",this.ended=!1,this.chunks=[],this.strm=new Qc,this.strm.avail_out=0;let i=th.inflateInit2(this.strm,t.windowBits);if(i!==ah)throw new Error(js[i]);if(this.header=new ih,th.inflateGetHeader(this.strm,this.header),t.dictionary&&("string"==typeof t.dictionary?t.dictionary=Kc(t.dictionary):"[object ArrayBuffer]"===nh.call(t.dictionary)&&(t.dictionary=new Uint8Array(t.dictionary)),t.raw&&(i=th.inflateSetDictionary(this.strm,t.dictionary),i!==ah)))throw new Error(js[i])}function uh(e,t){const i=new fh(t);if(i.push(e),i.err)throw i.msg||js[i.err];return i.result}fh.prototype.push=function(e,t){const i=this.strm,n=this.options.chunkSize,o=this.options.dictionary;let r,a,s;if(this.ended)return!1;for(a=t===~~t?t:!0===t?rh:oh,"[object ArrayBuffer]"===nh.call(e)?i.input=new Uint8Array(e):i.input=e,i.next_in=0,i.avail_in=i.input.length;;){for(0===i.avail_out&&(i.output=new Uint8Array(n),i.next_out=0,i.avail_out=n),r=th.inflate(i,a),r===ch&&o&&(r=th.inflateSetDictionary(i,o),r===ah?r=th.inflate(i,a):r===hh&&(r=ch));i.avail_in>0&&r===sh&&i.state.wrap>0&&0!==e[i.next_in];)th.inflateReset(i),r=th.inflate(i,a);switch(r){case lh:case hh:case ch:case dh:return this.onEnd(r),this.ended=!0,!1}if(s=i.avail_out,i.next_out&&(0===i.avail_out||r===sh))if("string"===this.options.to){let e=Yc(i.output,i.next_out),t=i.next_out-e,o=Xc(i.output,e);i.next_out=t,i.avail_out=n-t,t&&i.output.set(i.output.subarray(e,e+t),0),this.onData(o)}else this.onData(i.output.length===i.next_out?i.output:i.output.subarray(0,i.next_out));if(r!==ah||0!==s){if(r===sh)return r=th.inflateEnd(this.strm),this.onEnd(r),this.ended=!0,!0;if(0===i.avail_in)break}}return!0},fh.prototype.onData=function(e){this.chunks.push(e)},fh.prototype.onEnd=function(e){e===ah&&("string"===this.options.to?this.result=this.chunks.join(""):this.result=Gc(this.chunks)),this.chunks=[],this.err=e,this.msg=this.strm.msg};var ph=function(e,t){return(t=t||{}).raw=!0,uh(e,t)},mh={Inflate:fh,inflate:uh,inflateRaw:ph,ungzip:uh,constants:Ws};const{Deflate:gh,deflate:wh,deflateRaw:Fh,gzip:bh}=ul,{Inflate:vh,inflate:yh,inflateRaw:_h,ungzip:Ch}=mh;var xh=Fh,kh=yh,Eh=_h,Nh=Ch;function Sh(e){const t=ArrayBuffer.isView(e)?e:new Uint8Array(e);return 31===t[0]&&139===t[1]}function Ih(e){const t=ArrayBuffer.isView(e)?e:new Uint8Array(e);return 0!==(4&t[3])&&66===t[12]&&67===t[13]?zh(t.buffer):Nh(t)}function zh(e,t){const i=[];let n=0,o=0;for(t=t||e.byteLength-18;n100?Th(new Uint8Array(e.buffer,e.byteOffset+t,o),i,n):function(e,t,i,n,o){for(let r=0;r=0){o=atob(o);const e=new Uint8Array(o.length);for(let t=0;t0?Nh(e):e,i}return decodeURIComponent(o)}const Lh=function(e,t){if(0!==e.length){var i=Math.floor(e.length*((100-t)/100));return 0===i?(e.sort((function(e,t){return t-e})),e[i]):function(e,t){var i,n=new Oh;for(i=0;in.content[0])&&(n.content.length===t&&n.pop(),n.push(o))}return n.content[0]}(e,i)}},Bh=function(e,t,i){return Math.min(Math.max(e,t),i)},Hh=function(e){return Math.log(e)/Math.LN2};function Oh(){this.content=[]}function Ph(e,t){return Math.random()*(t-e)+e}Oh.prototype={push:function(e){this.content.push(e),this.bubbleUp(this.content.length-1)},pop:function(){var e=this.content[0],t=this.content.pop();return this.content.length>0&&(this.content[0]=t,this.sinkDown(0)),e},remove:function(e){for(var t=this.content.length,i=0;i0;){var n=Math.floor((e+1)/2)-1,o=this.content[n];if(i>=o)break;this.content[n]=t,this.content[e]=o,e=n}},sinkDown:function(e){for(var t=this.content.length,i=this.content[e],n=i;;){var o=2*(e+1),r=o-1,a=null;if(r{let e=[];for(let t=1;t>=.5;t-=.1)for(let i=0;i<1;i+=1/28){const n="rgb("+qh.hsvToRgb(i,1,t).join(",")+")";e.push(n)}return e.pop(),e.push(qh.rgbColor(16,16,16)),e},rgbToHex:function(e){return(e=e.match(/^rgba?[\s+]?\([\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?/i))&&4===e.length?"#"+("0"+parseInt(e[1],10).toString(16)).slice(-2)+("0"+parseInt(e[2],10).toString(16)).slice(-2)+("0"+parseInt(e[3],10).toString(16)).slice(-2):""},hexToRgb:function(e){var t=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(e);if(null!==t)return"rgb("+parseInt(t[1],16)+","+parseInt(t[2],16)+","+parseInt(t[3],16)+")"},hsvToRgb:function(e,t,i){var n,o,r,a=Math.floor(6*e),s=6*e-a,c=i*(1-t),l=i*(1-s*t),h=i*(1-(1-s)*t);switch(a%6){case 0:n=i,o=h,r=c;break;case 1:n=l,o=i,r=c;break;case 2:n=c,o=i,r=h;break;case 3:n=c,o=l,r=i;break;case 4:n=h,o=c,r=i;break;case 5:n=i,o=c,r=l}return[Math.floor(255*n),Math.floor(255*o),Math.floor(255*r)]},hslToRgb:function(e,t,i){var n,o,r;if(0===t)n=o=r=i;else{var a=i<.5?i*(1+t):i+t-i*t,s=2*i-a;n=qh.hue2rgb(s,a,e+1/3),o=qh.hue2rgb(s,a,e),r=qh.hue2rgb(s,a,e-1/3)}return[255*n,255*o,255*r]},hue2rgb:(e,t,i)=>(i<0&&(i+=1),i>1&&(i-=1),i<1/6?e+6*(t-e)*i:i<.5?t:i<2/3?e+(t-e)*(2/3-i)*6:e),rgbaColor:function(e,t,i,n){return"rgba("+(e=Bh(e,0,255))+","+(t=Bh(t,0,255))+","+(i=Bh(i,0,255))+","+(n=Bh(n,0,1))+")"},rgbColor:function(e,t,i){return"rgb("+(e=Bh(e,0,255))+","+(t=Bh(t,0,255))+","+(i=Bh(i,0,255))+")"},greyScale:function(e){var t=Bh(e,0,255);return"rgb("+t+","+t+","+t+")"},randomGrey:function(e,t){e=Bh(e,0,255),t=Bh(t,0,255);var i=Math.round(Ph(e,t)).toString(10);return"rgb("+i+","+i+","+i+")"},randomRGB:function(e,t){return e=Bh(e,0,255),t=Bh(t,0,255),"rgb("+Math.round(Ph(e,t)).toString(10)+","+Math.round(Ph(e,t)).toString(10)+","+Math.round(Ph(e,t)).toString(10)+")"},randomRGBConstantAlpha:function(e,t,i){return e=Bh(e,0,255),t=Bh(t,0,255),"rgba("+Math.round(Ph(e,t)).toString(10)+","+Math.round(Ph(e,t)).toString(10)+","+Math.round(Ph(e,t)).toString(10)+","+i+")"},addAlpha:function(e,t){if("0"===e||"."===e)e="rgb(0,0,0)";else{const t=this.colorNameToHex(e);t&&(e=t)}var i=/(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(e);if(e.startsWith("rgba")){const i=e.lastIndexOf(",");return e.substring(0,i+1)+t.toString()+")"}return i&&(e=qh.hexToRgb(e)),e.startsWith("rgb")?e.replace("rgb","rgba").replace(")",", "+t+")"):(console.log(e+" is not an rgb style string"),e)},rgbComponents:function(e){if("0"===e||"."===e)return[0,0,0];if(/(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(e))e=qh.hexToRgb(e);else if(!e.startsWith("rgb")){const t=this.colorNameToHex(e);e=this.hexToRgb(t)}if(e.startsWith("rgb("))return e.substring(4,e.length-1).split(",").map((e=>Number.parseInt(e.trim())));if(e.startsWith("rgba("))return e.substring(5,e.length-1).split(",").map(((e,t)=>(e=e.trim(),3===t?Number.parseFloat(e):Number.parseInt(e))));throw Error("Unrecognized color string: color")},getCompositeColor:function(e,t,i){return"rgb("+Math.floor(i*t[0]+(1-i)*e[0])+","+Math.floor(i*t[1]+(1-i)*e[1])+","+Math.floor(i*t[2]+(1-i)*e[2])+")"},createColorString:function(e){const t=this.createColorStringSafe(e);return t||e},createColorStringSafe:function(e){if((e=function(e){return void 0===e||((e.startsWith("'")||e.startsWith('"'))&&(e=e.substring(1)),(e.endsWith("'")||e.endsWith('"'))&&(e=e.substring(0,e.length-1))),e}(e)).startsWith("rgb(")&&e.endsWith(")"))return e;if(e.startsWith("#")&&e.length<8)return e;const t=this.colorNameToHex(e);if(t)return t;const i=e.split(",");return 3===i.length&&Vh(i[0])&&Vh(i[1])&&Vh(i[2])?`rgb(${e})`:void 0},darkenLighten:function(e,t){let i,n=this.colorNameToHex(e);i=n?qh.hexToRgb(n):e.startsWith("rgb(")?e:qh.hexToRgb(e);const o=i.replace(")","").substring(4).split(","),r=Math.max(0,Math.min(255,Number.parseInt(o[0].trim())+t)),a=Math.max(0,Math.min(255,Number.parseInt(o[1].trim())+t)),s=Math.max(0,Math.min(255,Number.parseInt(o[2].trim())+t));return"rgb("+r.toString()+","+a.toString()+","+s.toString()+")"},colorNameToHex:function(e){return{aliceblue:"#f0f8ff",antiquewhite:"#faebd7",aqua:"#00ffff",aquamarine:"#7fffd4",azure:"#f0ffff",beige:"#f5f5dc",bisque:"#ffe4c4",black:"#000000",blanchedalmond:"#ffebcd",blue:"#0000ff",blueviolet:"#8a2be2",brown:"#a52a2a",burlywood:"#deb887",cadetblue:"#5f9ea0",chartreuse:"#7fff00",chocolate:"#d2691e",coral:"#ff7f50",cornflowerblue:"#6495ed",cornsilk:"#fff8dc",crimson:"#dc143c",cyan:"#00ffff",darkblue:"#00008b",darkcyan:"#008b8b",darkgoldenrod:"#b8860b",darkgray:"#a9a9a9",darkgreen:"#006400",darkkhaki:"#bdb76b",darkmagenta:"#8b008b",darkolivegreen:"#556b2f",darkorange:"#ff8c00",darkorchid:"#9932cc",darkred:"#8b0000",darksalmon:"#e9967a",darkseagreen:"#8fbc8f",darkslateblue:"#483d8b",darkslategray:"#2f4f4f",darkturquoise:"#00ced1",darkviolet:"#9400d3",deeppink:"#ff1493",deepskyblue:"#00bfff",dimgray:"#696969",dodgerblue:"#1e90ff",firebrick:"#b22222",floralwhite:"#fffaf0",forestgreen:"#228b22",fuchsia:"#ff00ff",gainsboro:"#dcdcdc",ghostwhite:"#f8f8ff",gold:"#ffd700",goldenrod:"#daa520",gray:"#808080",green:"#008000",greenyellow:"#adff2f",honeydew:"#f0fff0",hotpink:"#ff69b4","indianred ":"#cd5c5c","indigo ":"#4b0082",ivory:"#fffff0",khaki:"#f0e68c",lavender:"#e6e6fa",lavenderblush:"#fff0f5",lawngreen:"#7cfc00",lemonchiffon:"#fffacd",lightblue:"#add8e6",lightcoral:"#f08080",lightcyan:"#e0ffff",lightgoldenrodyellow:"#fafad2",lightgrey:"#d3d3d3",lightgreen:"#90ee90",lightpink:"#ffb6c1",lightsalmon:"#ffa07a",lightseagreen:"#20b2aa",lightskyblue:"#87cefa",lightslategray:"#778899",lightsteelblue:"#b0c4de",lightyellow:"#ffffe0",lime:"#00ff00",limegreen:"#32cd32",linen:"#faf0e6",magenta:"#ff00ff",maroon:"#800000",mediumaquamarine:"#66cdaa",mediumblue:"#0000cd",mediumorchid:"#ba55d3",mediumpurple:"#9370d8",mediumseagreen:"#3cb371",mediumslateblue:"#7b68ee",mediumspringgreen:"#00fa9a",mediumturquoise:"#48d1cc",mediumvioletred:"#c71585",midnightblue:"#191970",mintcream:"#f5fffa",mistyrose:"#ffe4e1",moccasin:"#ffe4b5",navajowhite:"#ffdead",navy:"#000080",oldlace:"#fdf5e6",olive:"#808000",olivedrab:"#6b8e23",orange:"#ffa500",orangered:"#ff4500",orchid:"#da70d6",palegoldenrod:"#eee8aa",palegreen:"#98fb98",paleturquoise:"#afeeee",palevioletred:"#d87093",papayawhip:"#ffefd5",peachpuff:"#ffdab9",peru:"#cd853f",pink:"#ffc0cb",plum:"#dda0dd",powderblue:"#b0e0e6",purple:"#800080",red:"#ff0000",rosybrown:"#bc8f8f",royalblue:"#4169e1",saddlebrown:"#8b4513",salmon:"#fa8072",sandybrown:"#f4a460",seagreen:"#2e8b57",seashell:"#fff5ee",sienna:"#a0522d",silver:"#c0c0c0",skyblue:"#87ceeb",slateblue:"#6a5acd",slategray:"#708090",snow:"#fffafa",springgreen:"#00ff7f",steelblue:"#4682b4",tan:"#d2b48c",teal:"#008080",thistle:"#d8bfd8",tomato:"#ff6347",turquoise:"#40e0d0",violet:"#ee82ee",wheat:"#f5deb3",white:"#ffffff",whitesmoke:"#f5f5f5",yellow:"#ffff00",yellowgreen:"#9acd32",darkgrey:"#a9a9a9",darkslategrey:"#2f4f4f",dimgrey:"#696969",grey:"#808080",lightgray:"#d3d3d3",lightslategrey:"#778899",slategrey:"#708090"}[e]}};function Vh(e){const t=Number.parseInt(e);return!Number.isNaN(t)&&t>=0&&t<=255}const Uh="googleapis";class jh{constructor(){this.oauthTokens={}}setToken(e,t){t=t||Uh,this.oauthTokens[t]=e}getToken(e){let t;e=e||Uh;for(let i of Object.keys(this.oauthTokens)){if(Wh(i).test(e)){t=this.oauthTokens[i];break}}return t}removeToken(e){e=e||Uh;for(let t of Object.keys(this.oauthTokens)){Wh(t).test(e)&&(this.oauthTokens[t]=void 0)}}}function Wh(e){return new RegExp("^"+e.split(/\*+/).map(Gh).join(".*")+"$")}function Gh(e){return e.replace(/[|\\{}()[\]^$+*?.]/g,"\\$&")}function $h(e){return e.includes("googleapis")&&!e.includes("urlshortener")||Zh(e)||Kh(e)}function Zh(e){return e.startsWith("gs://")||e.startsWith("https://www.googleapis.com/storage")||e.startsWith("https://storage.cloud.google.com")||e.startsWith("https://storage.googleapis.com")}function Kh(e){return e.indexOf("drive.google.com")>=0||e.indexOf("www.googleapis.com/drive")>0}function Xh(e){let{bucket:t,object:i}=function(e){let t,i;if(e.startsWith("gs://")){const n=e.indexOf("/",5);if(n>=0){t=e.substring(5,n);const o=e.indexOf("?");i=o<0?e.substring(n+1):e.substring(n+1,o)}}else if(e.startsWith("https://storage.googleapis.com")||e.startsWith("https://storage.cloud.google.com")){const n=e.indexOf("/v1/b/",8);if(n>0){const o=e.indexOf("/o/",n);if(o>0){const r=e.indexOf("?",o);t=e.substring(n+6,o),i=r>0?e.substring(o+3,r):e.substring(o+3)}}else{const n=e.indexOf("/",8),o=e.indexOf("/",n+1),r=e.indexOf("?",o);o>0&&(t=e.substring(n+1,o),i=r<0?e.substring(o+1):e.substring(o+1,r))}}else if(e.startsWith("https://www.googleapis.com/storage/v1/b")){const n=e.indexOf("/v1/b/",8),o=e.indexOf("/o/",n);if(o>0){const r=e.indexOf("?",o);t=e.substring(n+6,o),i=r>0?e.substring(o+3,r):e.substring(o+3)}}if(t&&i)return{bucket:t,object:i};throw Error(`Unrecognized Google Storage URI: ${e}`)}(e);i=function(e){let t="";return e.split("").forEach((function(e){Yh.has(e)?t+=Yh.get(e):t+=e})),t}(i);const n=e.indexOf("?");return`https://storage.googleapis.com/storage/v1/b/${t}/o/${i}${n>0?e.substring(n)+"&alt=media":"?alt=media"}`}const Yh=new Map;function Qh(){return window.google&&window.google.igv}async function Jh(e){if(!Qh())throw Error("Google oAuth has not been initialized");if(google.igv.tokenResponse&&Date.now(){try{t.callback=e=>{void 0!==e.error&&n(e),google.igv.tokenResponse=e,google.igv.tokenExpiresAt=Date.now()+1e3*e.expires_in,i(e.access_token)},t.requestAccessToken({scope:e})}catch(e){console.log(e)}}))}}function ed(){return google.igv.apiKey}function td(e){var t=id(e);return t?"https://www.googleapis.com/drive/v3/files/"+t+"?alt=media&supportsTeamDrives=true":e}function id(e){if(e.includes("/open?id=")){const t=e.indexOf("/open?id=")+9,i=e.indexOf("&");if(t>0&&i>t)return e.substring(t,i);if(t>0)return e.substring(t)}else{if(e.includes("/file/d/")){const t=e.indexOf("/file/d/")+8,i=e.lastIndexOf("/");return e.substring(t,i)}if(e.startsWith("https://www.googleapis.com/drive")){let t=e.indexOf("/files/");const i=e.indexOf("?");if(t>0)return t+=7,i>0?e.substring(t,i):e.substring(t)}}throw Error("Unknown Google Drive url format: "+e)}Yh.set("!","%21"),Yh.set("#","%23"),Yh.set("$","%24"),Yh.set("%","%25"),Yh.set("&","%26"),Yh.set("'","%27"),Yh.set("(","%28"),Yh.set(")","%29"),Yh.set("*","%2A"),Yh.set("+","%2B"),Yh.set(",","%2C"),Yh.set("/","%2F"),Yh.set(":","%3A"),Yh.set(";","%3B"),Yh.set("=","%3D"),Yh.set("?","%3F"),Yh.set("@","%40"),Yh.set("[","%5B"),Yh.set("]","%5D"),Yh.set(" ","%20");class nd{constructor(e){this.requestsPerSecond=e.requestsPerSecond||10,this.lastStartTime=0,this.queued=[]}add(e,t){var i=this;return new Promise((function(t,n){i.queued.push({resolve:t,reject:n,asyncFunction:e}),i.dequeue()}))}addAll(e,t){var i=e.map(function(e){return this.add(e,t)}.bind(this));return Promise.all(i)}dequeue(){if(this.queued.length>0){var e=new Date,t=1e3/this.requestsPerSecond+1,i=e-this.lastStartTime;i>=t?this._execute():setTimeout(function(){this.dequeue()}.bind(this),t-i)}}async _execute(){this.lastStartTime=new Date;var e=this.queued.shift();const t=e.asyncFunction;try{const i=await t();e.resolve(i)}catch(t){e.reject(t)}}}function od(){if(Qh()){return Qh()&&google.igv.tokenResponse&&Date.now()0)for(var a=0;athis._loadURL(e,t))):this._loadURL(e,t)}throw Error(`url must be either a 'File', 'string', 'function', or 'Promise'. Actual type: ${i}`)}async _loadURL(e,t){const i=this,n=e;e=function(e){return e.startsWith("https://www.dropbox.com")?e.replace("//www.dropbox.com","//dl.dropboxusercontent.com"):e.startsWith("https://drive.google.com")?td(e):e.includes("//www.broadinstitute.org/igvdata")?e.replace("//www.broadinstitute.org/igvdata","//data.broadinstitute.org/igvdata"):e.includes("//igvdata.broadinstitute.org")?e.replace("//igvdata.broadinstitute.org","//s3.amazonaws.com/igv.broadinstitute.org"):e.includes("//igv.genepattern.org")?e.replace("//igv.genepattern.org","//igv-genepattern-org.s3.amazonaws.com"):e.startsWith("ftp://ftp.ncbi.nlm.nih.gov/geo")?e.replace("ftp://","https://"):e}(e);let o=(t=t||{}).oauthToken||this.getOauthToken(e);return o&&(o=await("function"==typeof o?o():o)),new Promise((function(r,a){$h(e)&&!function(e){return e.indexOf("X-Goog-Signature")>-1}(e)&&(Zh(e)&&(e=Xh(e)),e=function(e){let t=ad.apiKey;t||"undefined"==typeof gapi||(t=gapi.apiKey);if(void 0!==t&&!e.includes("key=")){const i=e.includes("?")?"&":"?";e=e+i+"key="+t}return e}(e),Kh(e)&&function(e){if(e.includes("supportsTeamDrive"))return e;{const t=e.includes("?")?"&":"?";e=e+t+"supportsTeamDrive=true"}}(e),o||(o=od()));const s=t.headers||{};o&&function(e,t){t&&(e["Cache-Control"]="no-cache",e.Authorization="Bearer "+t)}(s,o);const c=t.range,l=new XMLHttpRequest,h=t.sendData||t.body,d=t.method||(h?"POST":"GET"),f=t.responseType,u=t.contentType,p=t.mimeType;if(l.open(d,e),t.timeout&&(l.timeout=t.timeout),c){let e="";c.size&&(e=c.start+c.size-1),l.setRequestHeader("Range","bytes="+c.start+"-"+e)}if(u&&l.setRequestHeader("Content-Type",u),p&&l.overrideMimeType(p),f&&(l.responseType=f),s)for(let e of Object.keys(s)){const t=s[e];l.setRequestHeader(e,t)}!0===t.withCredentials&&(l.withCredentials=!0),l.onload=async function(n){if(0===l.status||l.status>=200&&l.status<=300)if("HEAD"===t.method){const e=t.requestedHeaders||["content-length"],i={};for(let t of e)i[t]=l.getResponseHeader(t);r(i)}else c&&206!==l.status&&0!==c.start?(l.response.length>1e5&&!i.RANGE_WARNING_GIVEN&&alert(`Warning: Range header ignored for URL: ${e}. This can have severe performance impacts.`),r(l.response.slice(c.start,c.start+c.size))):r(l.response);else 416===l.status?m(Error("416 Unsatisfiable Range")):!Qh()||404!==l.status&&401!==l.status&&403!==l.status||!$h(e)||t.retries?403===l.status?m("Access forbidden: "+e):m(l.status):g()},l.onerror=function(i){$h(e)&&!t.retries?g():m("Error accessing resource: "+e+" Status: "+l.status)},l.ontimeout=function(e){m("Timed out")},l.onabort=function(e){console.log("Aborted"),a(e)};try{l.send(h)}catch(i){$h(e)&&!t.retries?g():m(i)}function m(e){if(!a)throw e;a(e)}async function g(){try{const e=await async function(e){if(Qh()){const t=function(e){return Kh(e)?"https://www.googleapis.com/auth/drive.file":Zh(e)?"https://www.googleapis.com/auth/devstorage.read_only":"https://www.googleapis.com/auth/userinfo.profile"}(e);return await Jh(t)}throw Error("Authorization is required, but Google oAuth has not been initalized. Contact your site administrator for assistance.")}(n);t.retries=1,t.oauthToken=e;const o=await i.load(n,t);r(o)}catch(e){if(e.error){const t=e.error.startsWith("popup_blocked")?"Google login popup blocked by browser.":e.error;alert(t)}else m(e)}}}))}async _loadFileSlice(e,t){let i=t&&t.range?e.slice(t.range.start,t.range.start+t.range.size):e;const n=await i.arrayBuffer();return"arraybuffer"===t.responseType?n:rd(n)}async _loadStringFromFile(e,t){const i=t.range?e.slice(t.range.start,t.range.start+t.range.size):e;return rd(await i.arrayBuffer())}async _loadStringFromUrl(e,t){(t=t||{}).responseType="arraybuffer";return rd(await this.load(e,t))}setOauthToken(e,t){this.oauth.setToken(e,t)}getOauthToken(e){const t=$h(e)?void 0:ts(e).host;let i=this.oauth.getToken(t);if(i)return i;if(void 0===t){const e=od();if(e&&e.expires_at>Date.now())return e.access_token}}async getContentLength(e,t){(t=t||{}).method="HEAD",t.requestedHeaders=["content-length"];const i=(await this._loadURL(e,t))["content-length"];return i?Number.parseInt(i):0}};var sd={color:1};sd.parent=sd,sd.left=sd,sd.right=sd;class cd{constructor(){this.root=sd}insert(e,t,i){var n=new pd(new ud(e,t,i));for(this.treeInsert(n),n.color=2;n!==this.root&&2===n.parent.color;)if(n.parent===n.parent.parent.left){let e=n.parent.parent.right;2===e.color?(n.parent.color=1,e.color=1,n.parent.parent.color=2,n=n.parent.parent):(n===n.parent.right&&(n=n.parent,hd.call(this,n)),n.parent.color=1,n.parent.parent.color=2,dd.call(this,n.parent.parent))}else{let e=n.parent.parent.left;2===e.color?(n.parent.color=1,e.color=1,n.parent.parent.color=2,n=n.parent.parent):(n===n.parent.left&&(n=n.parent,dd.call(this,n)),n.parent.color=1,n.parent.parent.color=2,hd.call(this,n.parent.parent))}this.root.color=1}findOverlapping(e,t){var i=new ud(e,t,0);if(this.root===sd)return[];var n=ld.call(this,i,this.root,[]);return n.length>1&&n.sort((function(e,t){return e.low-t.low})),n}logIntervals(){!function e(t,i){for(var n="",o=0;o=e.low&&ld.call(this,e,t.left,i),t.right!==sd&&t.right.min<=e.high&&ld.call(this,e,t.right,i),i}function hd(e){var t=e.right;e.right=t.left,t.left!==sd&&(t.left.parent=e),t.parent=e.parent,e.parent===sd?this.root=t:e.parent.left===e?e.parent.left=t:e.parent.right=t,t.left=e,e.parent=t,fd.call(this,e)}function dd(e){var t=e.left;e.left=t.right,t.right!==sd&&(t.right.parent=e),t.parent=e.parent,e.parent===sd?this.root=t:e.parent.right===e?e.parent.right=t:e.parent.left=t,t.right=e,e.parent=t,fd.call(this,e)}function fd(e){for(;e!==sd;){var t=e.left.max>e.right.max?e.left.max:e.right.max,i=e.interval.high;e.max=t>i?t:i;var n=e.left.mine.low?1:this.highe.high?1:0}overlaps(e){return this.low<=e.high&&e.low<=this.high}}function pd(e){this.parent=sd,this.left=sd,this.right=sd,this.interval=e,this.color=2}class md{constructor(e,t,i){e=e||[],this.treeMap=this.buildTreeMap(e,t),this.range=i,this.count=e.length}containsRange(e){return void 0===this.range||this.range.contains(e.chr,e.start,e.end)}queryFeatures(e,t,i){const n=this.treeMap[e];if(!n)return[];const o=n.findOverlapping(t,i);if(0===o.length)return[];{const n=[],r=this.allFeatures[e];if(r){for(let e of o){const o=e.value;for(let e=o.start;ei)break;o.end>=t&&n.push(o)}}n.sort((function(e,t){return e.start-t.start}))}return n}}getAllFeatures(){return this.allFeatures}buildTreeMap(e,t){const i={},n=[];if(this.allFeatures={},e){for(let i of e){let e=i.chr;t&&(e=t.getChromosomeName(e));let o=this.allFeatures[e];o||(n.push(e),o=[],this.allFeatures[e]=o),o.push(i)}for(let e of n){const t=this.allFeatures[e];t.sort((function(e,t){return e.start===t.start?0:e.start>t.start?1:-1})),i[e]=gd(t)}}return i}}function gd(e){const t=new cd,i=e.length,n=Math.max(10,Math.round(i/10));for(let o=0;ot.start?1:-1}));for(let o=0;oi)break;r.end>t&&e.push(r)}})),e.sort((function(e,t){return e.start-t.start})),e)}return[]};const bd={cantaloupe:{r:255,g:206,b:110},honeydew:{r:206,g:250,b:110},spindrift:{r:104,g:251,b:208},sky:{r:106,g:207,b:255},lavender:{r:210,g:120,b:255},carnation:{r:255,g:127,b:211},licorice:{r:0,g:0,b:0},snow:{r:255,g:255,b:255},salmon:{r:255,g:114,b:110},banana:{r:255,g:251,b:109},flora:{r:104,g:249,b:110},ice:{r:104,g:253,b:255},orchid:{r:110,g:118,b:255},bubblegum:{r:255,g:122,b:255},lead:{r:30,g:30,b:30},mercury:{r:232,g:232,b:232},tangerine:{r:255,g:136,b:2},lime:{r:131,g:249,b:2},sea_foam:{r:3,g:249,b:135},aqua:{r:0,g:140,b:255},grape:{r:137,g:49,b:255},strawberry:{r:255,g:41,b:135},tungsten:{r:58,g:58,b:58},silver:{r:208,g:208,b:208},maraschino:{r:255,g:33,b:1},lemon:{r:255,g:250,b:3},spring:{r:5,g:248,b:2},turquoise:{r:0,g:253,b:255},blueberry:{r:0,g:46,b:255},magenta:{r:255,g:57,b:255},iron:{r:84,g:84,b:83},magnesium:{r:184,g:184,b:184},mocha:{r:137,g:72,b:0},fern:{r:69,g:132,b:1},moss:{r:1,g:132,b:72},ocean:{r:0,g:74,b:136},eggplant:{r:73,g:26,b:136},maroon:{r:137,g:22,b:72},steel:{r:110,g:110,b:110},aluminum:{r:160,g:159,b:160},cayenne:{r:137,g:17,b:0},aspargus:{r:136,g:133,b:1},clover:{r:2,g:132,b:1},teal:{r:0,g:134,b:136},midnight:{r:0,g:24,b:136},plum:{r:137,g:30,b:136},tin:{r:135,g:134,b:135},nickel:{r:136,g:135,b:135}};const vd={Set1:["rgb(228,26,28)","rgb(55,126,184)","rgb(77,175,74)","rgb(166,86,40)","rgb(152,78,163)","rgb(255,127,0)","rgb(247,129,191)","rgb(153,153,153)","rgb(255,255,51)"],Dark2:["rgb(27,158,119)","rgb(217,95,2)","rgb(117,112,179)","rgb(231,41,138)","rgb(102,166,30)","rgb(230,171,2)","rgb(166,118,29)","rgb(102,102,102)"],Set2:["rgb(102, 194,165)","rgb(252,141,98)","rgb(141,160,203)","rgb(231,138,195)","rgb(166,216,84)","rgb(255,217,47)","rgb(229,196,148)","rgb(179,179,179)"],Set3:["rgb(141,211,199)","rgb(255,255,179)","rgb(190,186,218)","rgb(251,128,114)","rgb(128,177,211)","rgb(253,180,98)","rgb(179,222,105)","rgb(252,205,229)","rgb(217,217,217)","rgb(188,128,189)","rgb(204,235,197)","rgb(255,237,111)"],Pastel1:["rgb(251,180,174)","rgb(179,205,227)","rgb(204,235,197)","rgb(222,203,228)","rgb(254,217,166)","rgb(255,255,204)","rgb(229,216,189)","rgb(253,218,236)"],Pastel2:["rgb(173,226,207)","rgb(253,205,172)","rgb(203,213,232)","rgb(244,202,228)","rgb(230,245,201)","rgb(255,242,174)","rgb(243,225,206)"],Accent:["rgb(127,201,127)","rgb(190,174,212)","rgb(253,192,134)","rgb(255,255,153)","rgb(56,108,176)","rgb(240,2,127)","rgb(191,91,23)"]};class yd{constructor(e){this.colors=vd[e],Array.isArray(this.colors)||(this.colors=[]),this.colorTable={},this.nextIdx=0,this.colorGenerator=new Cd}getColor(e){return this.colorTable.hasOwnProperty(e)||(this.nextIdxthis.hexwidth?e:new Array(this.hexwidth-e.length+1).join("0")+e},Cd.prototype.get=function(e,t){this.hue+=this.goldenRatio,this.hue%=1,"number"!=typeof e&&(e=.5),"number"!=typeof t&&(t=.95);var i=this.hsvToRgb(this.hue,e,t);return"#"+this.padHex(i[0].toString(16))+this.padHex(i[1].toString(16))+this.padHex(i[2].toString(16))},new Cd;const kd={configureHighDPICanvas:function(e,t,i){const n=window.devicePixelRatio;e.canvas.style.width=`${t}px`,e.canvas.width=Math.floor(n*t),e.canvas.style.height=`${i}px`,e.canvas.height=Math.floor(n*i),e.scale(n,n)},setProperties:function(e,t){for(var i in t)if(t.hasOwnProperty(i)){var n=t[i];e[i]=n}},strokeLine:function(e,t,i,n,o,r){t=Math.floor(t)+.5,i=Math.floor(i)+.5,n=Math.floor(n)+.5,o=Math.floor(o)+.5,r&&(e.save(),kd.setProperties(e,r)),e.beginPath(),e.moveTo(t,i),e.lineTo(n,o),e.stroke(),r&&e.restore()},fillRect:function(e,t,i,n,o,r){t=Math.round(t),i=Math.round(i),r&&(e.save(),kd.setProperties(e,r)),e.fillRect(t,i,n,o),r&&e.restore()},fillPolygon:function(e,t,i,n){n&&(e.save(),kd.setProperties(e,n)),Ed(e,t,i),e.fill(),n&&e.restore()},strokePolygon:function(e,t,i,n){n&&(e.save(),kd.setProperties(e,n)),Ed(e,t,i),e.stroke(),n&&e.restore()},fillText:function(e,t,i,n,o,r){if((o||r)&&e.save(),o&&kd.setProperties(e,o),r){for(var a in e.translate(i,n),r){var s=r[a];"translate"===a&&e.translate(s.x,s.y),"rotate"===a&&e.rotate(s.angle*Math.PI/180)}e.fillText(t,0,0)}else e.fillText(t,i,n);(o||r)&&e.restore()},strokeText:function(e,t,i,n,o,r){if((o||r)&&e.save(),o&&kd.setProperties(e,o),r){for(var a in e.translate(i,n),r){var s=r[a];"translate"===a&&e.translate(s.x,s.y),"rotate"===a&&e.rotate(s.angle*Math.PI/180)}e.strokeText(t,0,0)}else e.strokeText(t,i,n);(o||r)&&e.restore()},strokeCircle:function(e,t,i,n,o){o&&(e.save(),kd.setProperties(e,o)),e.beginPath(),e.arc(t,i,n,0,2*Math.PI),e.stroke(),o&&e.restore()},fillCircle:function(e,t,i,n,o){o&&(e.save(),kd.setProperties(e,o)),e.beginPath(),e.arc(t,i,n,0,2*Math.PI),e.fill(),o&&e.restore()},drawArrowhead:function(e,t,i,n,o){e.save(),n||(n=5),o&&(e.lineWidth=o),e.beginPath(),e.moveTo(t,i-n/2),e.lineTo(t,i+n/2),e.lineTo(t+n,i),e.lineTo(t,i-n/2),e.closePath(),e.fill(),e.restore()},dashedLine:function(e,t,i,n,o,r,a={}){void 0===r&&(r=2),e.setLineDash([r,r]),kd.strokeLine(e,t,i,n,o,a),e.setLineDash([])},roundRect:function(e,t,i,n,o,r,a,s){void 0===s&&(s=!0),void 0===r&&(r=5),e.beginPath(),e.moveTo(t+r,i),e.lineTo(t+n-r,i),e.quadraticCurveTo(t+n,i,t+n,i+r),e.lineTo(t+n,i+o-r),e.quadraticCurveTo(t+n,i+o,t+n-r,i+o),e.lineTo(t+r,i+o),e.quadraticCurveTo(t,i+o,t,i+o-r),e.lineTo(t,i+r),e.quadraticCurveTo(t,i,t+r,i),e.closePath(),s&&e.stroke(),a&&e.fill()},polygon:function(e,t,i,n,o){void 0===o&&(o=!0),e.beginPath();var r=t.length;e.moveTo(t[0],i[0]);for(var a=1;a{for(let t=0;t{e.translate(t,0),e.scale(-1,1),e.translate(-t,0)}};function Ed(e,t,i){var n,o=t.length;for(n=0;n0){t=Number.MAX_VALUE,i=-Number.MAX_VALUE;for(let n of e)Number.isNaN(n.value)||(t=Math.min(t,n.value),i=Math.max(i,n.value));i>0&&(t=Math.min(0,t)),i<0&&(i=0)}else t=0,i=100;return{min:t,max:i}},Ad=function(e,t,i){let n=t.start,o=t.end;if(void 0===o)n-=i/2,o=n+i,o>e?(o=e,n=o-i):n<0&&(n=0,o=i);else if(o-ne?(o=e,n=o-i):(n=t-i/2,o=n+i)}t.start=Math.ceil(n),t.end=Math.floor(o)};async function Md(e){if($a(e)&&e.startsWith("https://drive.google.com")){if(void 0===ed())throw Error("Google drive is referenced, but API key is not defined. An API key is required for Google Drive access");const t=await async function(e){let t="https://www.googleapis.com/drive/v3/files/"+id(e)+"?supportsTeamDrives=true";const i=ed();i&&(t+="&key="+i);const n=await fetch(t);let o=await n.json();if(o.error&&404===o.error.code){let e="https://www.googleapis.com/auth/drive.readonly";const i=await Jh(e);if(!i)throw Error(o.error);{const e=await fetch(t,{headers:{Authorization:`Bearer ${i}`}});if(o=await e.json(),o.error)throw Error(o.error)}}return o}(e);return t.originalFileName||t.name}return Qa(e)}function Td(e){var t,i;return e>1e7?(t=" mb",i=e/1e6,Math.floor(i).toString()+t):e>1e4?(t=" kb",i=e/1e3,Za(Math.floor(i))+t):Za(e)+" bp"}function Rd(e){return $a(e)&&e.startsWith("data:")}function Ld(e,t){const i=xr.div({class:t});e.appendChild(i)}function Bd(e,t){t.parentNode.insertBefore(e,t)}function Hd(e,t){t.parentNode.insertBefore(e,t.nextSibling)}function Od(){return"https:"===window.location.protocol||"localhost"===window.location.hostname}function Pd(e,t){if(e.length<6)return void console.log("Skipping line: "+e.join(" "));var i={chr1:e[0],start1:Number.parseInt(e[1]),end1:Number.parseInt(e[2]),chr2:e[3],start2:Number.parseInt(e[4]),end2:Number.parseInt(e[5])};if(isNaN(i.start1)||isNaN(i.end1)||isNaN(i.start2)||isNaN(i.end2))return;t&&void 0===t.hiccups&&(t.hiccups=!!t.columnNames&&Vd(t.columnNames));const n=t&&t.hiccups,o=n?6:10;if(n||(e.length>6&&"."!==e[6]&&(i.name=e[6]),e.length>7&&"."!==e[7]&&(i.score=Number(e[7])),e.length>8&&"."!==e[8]&&(i.strand1=e[8]),e.length>9&&"."!==e[9]&&(i.strand2=e[9])),t){const n=t.colorColumn;n&&no&&t.columnNames&&t.columnNames.length===e.length&&(i.extras=e.slice(o))}return i.chr1===i.chr2&&(i.chr=i.chr1,i.start=Math.min(i.start1,i.start2),i.end=Math.max(i.end1,i.end2)),i}function qd(e,t){if(!(e.length<8))return{chr:e[0],start:Number.parseInt(e[1]),end:Number.parseInt(e[2]),color:qh.createColorString(e[6]),value:Number(e[7])}}function Vd(e){return e&&(e.includes("fdrDonut")||e.includes("fdr_donut"))}const Ud=new Set(["narrowpeak","broadpeak","regionpeak","peaks","bedgraph","wig","gff3","gff","gtf","fusionjuncspan","refflat","seg","aed","bed","vcf","bb","bigbed","biginteract","biggenepred","bignarrowpeak","bw","bigwig","bam","tdf","refgene","genepred","genepredext","bedpe","bp","snp","rmsk","cram","gwas","maf","mut","tsv","hiccups","fasta","fa","fna","pytor"]);function jd(e){return Sd&&Sd[e]?function(e){const t=e.fields,i=["chr","start","end"];for(let n=0;n0&&(e=e.substr(0,t)),e.endsWith(".gz")&&(e=e.substr(0,e.length-3)),(e.endsWith(".txt")||e.endsWith(".tab")||e.endsWith(".bgz"))&&(e=e.substr(0,e.length-4)),i=(t=e.lastIndexOf("."))<0?e:e.substr(t+1)){case"bw":return"bigwig";case"bb":return"bigbed";case"fasta":case"fa":case"fna":return"fasta";default:return Ud.has(i)?i:void 0}}function Gd(e,t){if($a(e)){if(e.includes("?")){const i=e.indexOf("?");return e.substring(0,i)+"."+t+e.substring(i)}return e+"."+t}}function $d(e){if(function(e){e.featureType&&(e.type=e.type||e.featureType,e.featureType=void 0);"junctions"===e.type?e.type="junction":"bed"===e.type?(e.type="annotation",e.format=e.format||"bed"):"annotations"===e.type?e.type="annotation":"alignments"===e.type?e.type="alignment":"bam"===e.type?(e.type="alignment",e.format="bam"):"vcf"===e.type?(e.type="variant",e.format="vcf"):"t2d"===e.type?e.type="gwas":"FusionJuncSpan"!==e.type||e.format?"aed"===e.type&&(e.type="annotation",e.format=e.format||"aed"):e.format="fusionjuncspan"}(e),e.type)return e.type;if(e.format){switch(e.format.toLowerCase()){case"bw":case"bigwig":case"wig":case"bedgraph":case"tdf":return"wig";case"vcf":return"variant";case"seg":return"seg";case"mut":case"maf":return"mut";case"bam":case"cram":return"alignment";case"hiccups":case"bedpe":case"bedpe-loop":case"biginteract":return"interact";case"bp":return"arc";case"gwas":return"gwas";case"bed":case"bigbed":case"bb":case"biggenepred":case"bignarrowpeak":return"bedtype";case"fasta":return"sequence";case"pytor":return"cnvpytor";default:return"annotation"}}}async function Zd(e){if(e.url){const t=await ad.loadString(e.url,zd(e,{range:{start:0,size:1e3}}));if(t){if(Vd(t.split("\n")[0].split("\t")))return"hiccups"}}}function Kd(e,t){Sd[e]={fields:t}}var Xd=Object.freeze({__proto__:null,knownFileExtensions:Ud,getFormat:jd,inferFileFormat:Wd,inferFileFormatFromHeader:Zd,inferTrackType:$d,inferIndexPath:Gd,registerFileFormats:Kd});const Yd=[["A","T"],["G","C"],["Y","R"],["W","S"],["K","M"],["D","H"],["B","V"]],Qd=new Map;for(let Tk of Yd){const Rk=Tk[0],Lk=Tk[1];Qd.set(Rk,Lk),Qd.set(Lk,Rk),Qd.set(Rk.toLowerCase(),Lk.toLowerCase()),Qd.set(Lk.toLowerCase(),Rk.toLowerCase())}function Jd(e){let t="",i=e.length;for(;i-- >0;){const n=e[i];t+=Qd.has(n)?Qd.get(n):n}return t}class ef{constructor(e,t,i){this.name=e,this.order=t,this.bpLength=i}}const tf=Ka,nf=new Set(["fastaURL","indexURL","cytobandURL","indexed"]);class of{constructor(e){this.fastaURL=e.fastaURL,this.withCredentials=e.withCredentials,this.chromosomeNames=[],this.chromosomes={},this.sequences=new Map;const t={};for(let i in e)e.hasOwnProperty(i)&&!nf.has(i)&&(t[i]=e[i]);this.config=t}async init(){return this.loadAll()}async getSequence(e,t,i){if(!this.sequences.has(e))return;let n=this.sequences.get(e).find((e=>e.contains(t,i)));if(!n&&(n=this.sequences.get(e).find((e=>e.overlaps(t,i))),!n))return;t-=n.offset,i-=n.offset;let o="";if(t<0)for(let e=t;e")){s&&s.seq&&c.call(this,s,a++);const e=o.substr(1).split(/\s+/),t=e[0].split(":");if(s.chr=t[0],s.seq="",s.offset=0,t.length>1&&t[1].indexOf("-")>0){const i=t[1].split("-");2===i.length&&/^[0-9]+$/.test(i[0])&&/^[0-9]+$/.test(i[1]);const n=Number.parseInt(i[0]);if(Number.parseInt(i[1])>n&&(s.offset=n-1),e.length>1&&e[1].startsWith("@len="))try{s.length=parseInt(e[1].trim().substring(5))}catch(e){s.length=void 0,console.error(`Error parsing sequence length for ${o}`)}else s.length=void 0}}else s.seq+=o;s&&s.seq&&c.call(this,s,a)}function c(e,i){const n=e.length||e.offset+e.seq.length;if(t.has(e.chr)){const t=this.chromosomes[e.chr];t.bpLength=Math.max(t.bpLength,n)}else this.chromosomeNames.push(e.chr),this.sequences.set(e.chr,[]),this.chromosomes[e.chr]=new ef(e.chr,i,n),t.add(e.chr);this.sequences.get(e.chr).push(new rf(e.offset,e.seq))}}}class rf{constructor(e,t){this.offset=e,this.sequence=t}contains(e,t){return this.offset<=e&&this.end>=t}overlaps(e,t){return this.offsete}get end(){return this.offset+this.sequence.length}}const af=function(e,t,i,n){this.chr=e,this.start=t,this.end=i,this.features=n};af.prototype.contains=function(e,t,i){return this.chr===e&&this.start<=t&&this.end>=i},af.prototype.containsRange=function(e){return this.chr===e.chr&&this.start<=e.start&&this.end>=e.end};const sf=Ka,cf=new Set(["fastaURL","indexURL","compressedIndexURL","cytobandURL","indexed"]);class lf{constructor(e){this.file=e.fastaURL,this.indexFile=e.indexURL||e.indexFile||this.file+".fai",this.compressedIndexFile=e.compressedIndexURL||!1,this.withCredentials=e.withCredentials,this.chromosomeNames=[],this.chromosomes={},this.sequences={},this.offsets={};const t={};for(let i in e)e.hasOwnProperty(i)&&!cf.has(i)&&(t[i]=e[i]);this.config=t}async init(){return this.getIndex()}async getSequence(e,t,i){if(!(this.interval&&this.interval.contains(e,t,i))){let n=t,o=i;if(i-t<5e4){const e=i-t,r=Math.round(t+e/2);n=Math.max(0,r-25e3),o=r+25e3}const r=await this.readSequence(e,n,o);this.interval=new af(e,n,o,r)}const n=t-this.interval.start,o=i-t;return this.interval.features?this.interval.features.substr(n,o):null}async getIndex(){if(this.index)return this.index;{const e=await ad.load(this.indexFile,zd(this.config)),t=sf(e),i=t.length;let n=0,o=0;for(this.index={};nthis.compressedIndex[n][1])return[n];let o=0,r=n,a=Math.floor(this.compressedIndex.length/2),s=this.compressedIndex.length+1,c=!1;for(let t=0;te){c=!0;break}t=t)break}const l=i[i.length-1];return l===this.compressedIndex.length-1&&this.compressedIndex[l][1]0&&(w=Math.min(r-o,s-f),F+=g.substr(b,w),b+=w+l);b{this.reversed=!this.reversed,this.trackView.repaintViews()}},{name:this.frameTranslate?"Close Translation":"Three-frame Translate",click:()=>{if(this.frameTranslate=!this.frameTranslate,this.frameTranslate){for(let e of this.trackView.viewports)e.setContentHeight(bf);this.trackView.setTrackHeight(bf)}else{for(let e of this.trackView.viewports)e.setContentHeight(25);this.trackView.setTrackHeight(25)}this.trackView.repaintViews()}}]}contextMenuItemList(e){const t=e.viewport;if(t.referenceFrame.bpPerPixel<=1){const e=t.getWidth()*t.referenceFrame.bpPerPixel,i=t.referenceFrame.chr,n=Math.floor(t.referenceFrame.start),o=Math.ceil(n+e),r=[{label:this.reversed?"View visible sequence (reversed)...":"View visible sequence...",click:async()=>{let e=await this.browser.genome.sequence.getSequence(i,n,o);e?this.reversed&&(e=Jd(e)):e="Unknown sequence",this.browser.alert.present(e)}}];return Od()&&r.push({label:"Copy visible sequence",click:async()=>{let e=await this.browser.genome.sequence.getSequence(i,n,o);e?this.reversed&&(e=Jd(e)):e="Unknown sequence";try{await navigator.clipboard.writeText(e)}catch(e){console.error(e),this.browser.alert.present(`error copying sequence to clipboard ${e}`)}}}),r.push("
"),r}}translateSequence(e){const t=[[],[],[]];for(let i of[0,1,2]){let n=i;for(;e.length-n>=3;){let o=e.slice(n,n+3);this.reversed&&(o=o.split("").reverse().join(""));const r=mf[o.toUpperCase()]||"";t[i].push({codons:o,aminoA:r}),n+=3}}return t}async getSequenceSource(){return this.config.fastaURL?(this.fasta||(this.fasta=new yf(this.config,this.browser.genome),await this.fasta.init()),this.fasta):this.browser.genome.sequence}async getFeatures(e,t,i,n){if(t=Math.floor(t),i=Math.floor(i),n&&n>10)return null;{const n=await this.getSequenceSource();return{bpStart:t,sequence:await n.getSequence(e,t,i)}}}draw(e){const t=e.context;if(e.features){let i=e.features.sequence;if(!i)return;this.reversed&&(i=i.split("").map((function(e){return gf[e]})).join(""));const n=e.features.bpStart,o=1+e.bpStart+e.pixelWidth*e.bpPerPixel;for(let r=Math.floor(e.bpStart);r<=o;r++){const o=Math.floor(r-n);if(o>=0&&o.1)kd.fillRect(t,n,5,a,10,{fillStyle:c});else{const i=n+.5*(a-t.measureText(s).width);"y"===e.axis?(t.save(),kd.labelTransformWithContext(t,i),kd.strokeText(t,s,i,15,{strokeStyle:c}),t.restore()):kd.strokeText(t,s,i,15,{strokeStyle:c})}}}if(this.frameTranslate){let o=25;const r=this.translateSequence(i);for(let i=0;ie.pixelWidth)break;let u=c.aminoA;c.aminoA.indexOf("STOP")>-1?(s="rgb(255, 0, 0)",u="STOP"):"M"===c.aminoA&&(s="rgb(0, 153, 0)",u="START"),kd.fillRect(t,h,o,d-h,25,{fillStyle:s}),e.bpPerPixel<=.1&&kd.strokeText(t,u,f-t.measureText(u).width/2,o+15)}o+=30}}}}get supportsWholeGenome(){return!1}computePixelHeight(e){return this.height=this.frameTranslate?bf:25,this.height}fillColor(e){return this.color?this.color:"dna"===this.sequenceType?uf[e]||"gray":"rgb(0, 0, 150)"}getState(){const e={type:"sequence"};return this.order!==pf&&(e.order=this.order),this.reversed&&(e.revealed=!0),e}}class yf{constructor(e,t){this.config=e,this.genome=t}async init(){this.fasta=await ff(this.config),this.chrNameMap=new Map;for(let e of this.fasta.chromosomeNames)this.chrNameMap.set(this.genome.getChromosomeName(e),e)}async getSequence(e,t,i){const n=this.chrNameMap.has(e)?this.chrNameMap.get(e):e;return this.fasta.getSequence(n,t,i)}}class _f{constructor(e,t,i,n){this.guid=xr.guid(),this.trackView=e,this.referenceFrame=i,this.browser=e.browser,this.$viewport=wr('
'),t.appendChild(this.$viewport.get(0)),e.track.height&&(this.$viewport.get(0).style.height=`${e.track.height}px`),e.track instanceof vf&&(this.alert=new Aa(this.$viewport.get(0))),this.contentTop=0,this.contentHeight=this.$viewport.height(),this.$viewport.width(n),this.initializationHelper()}initializationHelper(){}showMessage(e){this.messageDiv||(this.messageDiv=document.createElement("div"),this.messageDiv.className="igv-viewport-message",this.$viewport.append(wr(this.messageDiv))),this.messageDiv.textContent=e,this.messageDiv.style.display="inline-block"}hideMessage(e){this.messageDiv&&(this.messageDiv.style.display="none")}setTrackLabel(e){}startSpinner(){}stopSpinner(){}checkZoomIn(){return!0}shift(){}setTop(e){this.contentTop=e,this.$viewport.height()}async loadFeatures(){}clearCache(){}async repaint(){}draw(e,t,i){console.log("Viewport - draw(drawConfiguration, features, roiFeatures)")}checkContentHeight(e){let t=this.trackView.track;if(e=e||this.cachedFeatures,"FILL"===t.displayMode)this.setContentHeight(this.$viewport.height());else if("function"==typeof t.computePixelHeight&&e&&e.length>0){let i=t.computePixelHeight(e);i!==this.contentHeight&&this.setContentHeight(i)}}getContentHeight(){return this.contentHeight}setContentHeight(e){this.contentHeight=e}isLoading(){return!1}saveSVG(){}isVisible(){return this.$viewport.width()}setWidth(e){this.$viewport.width(e)}getWidth(){return this.$viewport.width()}getContentTop(){return this.contentTop}containsPosition(e,t){console.log("Viewport - containsPosition(chr, position)")}addMouseHandlers(){}removeMouseHandlers(){}dispose(){this.popover&&this.popover.dispose(),this.$viewport.get(0).remove();for(let e of Object.keys(this))this[e]=void 0}} -/*!! - * Canvas 2 Svg v1.0.19 - * A low level canvas to SVG converter. Uses a mock canvas context to build an SVG document. - * - * Licensed under the MIT license: - * http://www.opensource.org/licenses/mit-license.php - * - * Author: - * Kerry Liu - * - * Copyright (c) 2014 Gliffy Inc. - */function Cf(e,t){var i,n=Object.keys(t);for(i=0;i0){"path"===this.__currentElement.nodeName&&(this.__currentElementsToStyle||(this.__currentElementsToStyle={element:t,children:[]}),this.__currentElementsToStyle.children.push(this.__currentElement),this.__applyCurrentDefaultPath());var i=this.__createElement("g");t.appendChild(i),this.__currentElement=i}var n=this.__currentElement.getAttribute("transform");n?n+=" ":n="",n+=e,this.__currentElement.setAttribute("transform",n)}addTrackGroupWithTranslationAndClipRect(e,t,i,n,o,r){const a=e+"_clip_rect";let s=this.__createElement("clipPath",{id:a});this.__defs.appendChild(s),s.appendChild(this.__createElement("rect",{x:"0",y:r.toString(),width:n.toString(),height:o.toString()}));let c=this.__createElement("g");this.__rootGroup.appendChild(c),c.setAttribute("transform",Cf("translate({x},{y})",{x:t,y:i})),c.setAttribute("id",e+"_group"),c.setAttribute("clip-path",Cf("url(#{id})",{id:a})),this.__currentElement=c}scale(e,t){void 0===t&&(t=e),this.__addTransform(Cf("scale({x},{y})",{x:e,y:t}))}rotate(e){var t=180*e/Math.PI;this.__addTransform(Cf("rotate({angle},{cx},{cy})",{angle:t,cx:0,cy:0}))}translate(e,t){this.__addTransform(Cf("translate({x},{y})",{x:e,y:t}))}transform(e,t,i,n,o,r){this.__addTransform(Cf("matrix({a},{b},{c},{d},{e},{f})",{a:e,b:t,c:i,d:n,e:o,f:r}))}beginPath(){var e;this.__currentDefaultPath="",this.__currentPosition={},e=this.__createElement("path",{},!0),this.__closestGroupOrSvg().appendChild(e),this.__currentElement=e}__applyCurrentDefaultPath(){var e=this.__currentElement;"path"===e.nodeName?e.setAttribute("d",this.__currentDefaultPath):console.error("Attempted to apply path command to node",e.nodeName)}__addPathCommand(e){this.__currentDefaultPath+=" ",this.__currentDefaultPath+=e}moveTo(e,t){"path"!==this.__currentElement.nodeName&&this.beginPath(),this.__currentPosition={x:e,y:t},this.__addPathCommand(Cf("M {x} {y}",{x:e,y:t}))}closePath(){this.__currentDefaultPath&&this.__addPathCommand("Z")}lineTo(e,t){this.__currentPosition={x:e,y:t},this.__currentDefaultPath&&this.__currentDefaultPath.indexOf("M")>-1?this.__addPathCommand(Cf("L {x} {y}",{x:e,y:t})):this.__addPathCommand(Cf("M {x} {y}",{x:e,y:t}))}bezierCurveTo(e,t,i,n,o,r){this.__currentPosition={x:o,y:r},this.__addPathCommand(Cf("C {cp1x} {cp1y} {cp2x} {cp2y} {x} {y}",{cp1x:e,cp1y:t,cp2x:i,cp2y:n,x:o,y:r}))}quadraticCurveTo(e,t,i,n){this.__currentPosition={x:i,y:n},this.__addPathCommand(Cf("Q {cpx} {cpy} {x} {y}",{cpx:e,cpy:t,x:i,y:n}))}arcTo(e,t,i,n,o){var r=this.__currentPosition&&this.__currentPosition.x,a=this.__currentPosition&&this.__currentPosition.y;if(void 0!==r&&void 0!==a){if(o<0)throw new Error("IndexSizeError: The radius provided ("+o+") is negative.");if(r===e&&a===t||e===i&&t===n||0===o)this.lineTo(e,t);else{var s=Ef([r-e,a-t]),c=Ef([i-e,n-t]);if(s[0]*c[1]!=s[1]*c[0]){var l=s[0]*c[0]+s[1]*c[1],h=Math.acos(Math.abs(l)),d=Ef([s[0]+c[0],s[1]+c[1]]),f=o/Math.sin(h/2),u=e+f*d[0],p=t+f*d[1],m=[-s[1],s[0]],g=[c[1],-c[0]],w=function(e){var t=e[0];return e[1]>=0?Math.acos(t):-Math.acos(t)},F=w(m),b=w(g);this.lineTo(u+m[0]*o,p+m[1]*o),this.arc(u,p,o,F,b)}else this.lineTo(e,t)}}}stroke(){"path"===this.__currentElement.nodeName&&this.__currentElement.setAttribute("paint-order","fill stroke markers"),this.__applyCurrentDefaultPath(),this.__applyStyleToCurrentElement("stroke")}fill(){"path"===this.__currentElement.nodeName&&this.__currentElement.setAttribute("paint-order","stroke fill markers"),this.__applyCurrentDefaultPath(),this.__applyStyleToCurrentElement("fill")}rect(e,t,i,n){"path"!==this.__currentElement.nodeName&&this.beginPath(),this.moveTo(e,t),this.lineTo(e+i,t),this.lineTo(e+i,t+n),this.lineTo(e,t+n),this.lineTo(e,t),this.closePath()}fillRect(e,t,i,n){n<0&&(t+=n,n=-n),i<0&&(e+=i,i=-i);var o,r,a,s={x:e,y:t,width:i,height:n};(!this.viewbox||(o=this.viewbox,r=s,o.xr.x&&o.yr.y))&&(a=this.__createElement("rect",s,!0),this.__closestGroupOrSvg().appendChild(a),this.__currentElement=a,this.__applyStyleToCurrentElement("fill"))}strokeRect(e,t,i,n){var o;o=this.__createElement("rect",{x:e,y:t,width:i,height:n},!0),this.__closestGroupOrSvg().appendChild(o),this.__currentElement=o,this.__applyStyleToCurrentElement("stroke")}strokeEllipse(e,t,i,n,o,r,a,s){this.__ellipse(e,t,i,n,o,r,a,s,"stroke")}fillEllipse(e,t,i,n,o,r,a,s){this.__ellipse(e,t,i,n,o,r,a,s,"fill")}__ellipse(e,t,i,n,o,r,a,s,c){const l={cx:e,cy:t,rx:i,ry:n},h=this.__createElement("ellipse",l,!0);this.__closestGroupOrSvg().appendChild(h),this.__currentElement=h,this.__applyStyleToCurrentElement(c)}__clearCanvas(){for(var e=this.__closestGroupOrSvg().getAttribute("transform"),t=this.__root.childNodes[1],i=t.childNodes,n=i.length-1;n>=0;n--)i[n]&&t.removeChild(i[n]);this.__currentElement=t,this.__groupStack=[],e&&this.__addTransform(e)}clearRect(e,t,i,n){if(0!==e||0!==t||i!==this.width||n!==this.height){var o,r=this.__closestGroupOrSvg();o=this.__createElement("rect",{x:e,y:t,width:i,height:n,fill:"#FFFFFF"},!0),r.appendChild(o)}else this.__clearCanvas()}createLinearGradient(e,t,i,n){var o=this.__createElement("linearGradient",{id:xf(this.__ids),x1:e+"px",x2:i+"px",y1:t+"px",y2:n+"px",gradientUnits:"userSpaceOnUse"},!1);return this.__defs.appendChild(o),new If(o,this)}createRadialGradient(e,t,i,n,o,r){var a=this.__createElement("radialGradient",{id:xf(this.__ids),cx:n+"px",cy:o+"px",r:r+"px",fx:e+"px",fy:t+"px",gradientUnits:"userSpaceOnUse"},!1);return this.__defs.appendChild(a),new If(a,this)}__parseFont(){var e=/^\s*(?=(?:(?:[-a-z]+\s*){0,2}(italic|oblique))?)(?=(?:(?:[-a-z]+\s*){0,2}(small-caps))?)(?=(?:(?:[-a-z]+\s*){0,2}(bold(?:er)?|lighter|[1-9]00))?)(?:(?:normal|\1|\2|\3)\s*){0,3}((?:xx?-)?(?:small|large)|medium|smaller|larger|[.\d]+(?:\%|in|[cem]m|ex|p[ctx]))(?:\s*\/\s*(normal|[.\d]+(?:\%|in|[cem]m|ex|p[ctx])))?\s*([-,\'\"\sa-z0-9]+?)\s*$/i.exec(this.font),t={style:e[1]||"normal",size:e[4]||"10px",family:e[6]||"sans-serif",weight:e[3]||"normal",decoration:e[2]||"normal",href:null};return"underline"===this.__fontUnderline&&(t.decoration="underline"),this.__fontHref&&(t.href=this.__fontHref),t}__wrapTextLink(e,t){if(e.href){var i=this.__createElement("a");return i.setAttributeNS("http://www.w3.org/1999/xlink","xlink:href",e.href),i.appendChild(t),i}return t}__applyText(e,t,i,n){var o,r,a=this.__parseFont(),s=this.__closestGroupOrSvg(),c=this.__createElement("text",{"font-family":a.family,"font-size":a.size,"font-style":a.style,"font-weight":a.weight,"text-decoration":a.decoration,x:t,y:i,"text-anchor":(o=this.textAlign,r={left:"start",right:"end",center:"middle",start:"start",end:"end"},r[o]||r.start),"dominant-baseline":kf(this.textBaseline)},!0);c.appendChild(this.__document.createTextNode(e)),this.__currentElement=c,this.__applyStyleToCurrentElement(n),s.appendChild(this.__wrapTextLink(a,c))}fillText(e,t,i){this.__applyText(e,t,i,"fill")}strokeText(e,t,i){this.__applyText(e,t,i,"stroke")}measureText(e){return this.__ctx.font=this.font,this.__ctx.measureText(e)}arc(e,t,i,n,o,r){if(n!==o){(n%=2*Math.PI)===(o%=2*Math.PI)&&(o=(o+2*Math.PI-.001*(r?-1:1))%(2*Math.PI));var a=e+i*Math.cos(o),s=t+i*Math.sin(o),c=e+i*Math.cos(n),l=t+i*Math.sin(n),h=r?0:1,d=0,f=o-n;f<0&&(f+=2*Math.PI),d=r?f>Math.PI?0:1:f>Math.PI?1:0,this.lineTo(c,l),this.__addPathCommand(Cf("A {rx} {ry} {xAxisRotation} {largeArcFlag} {sweepFlag} {endX} {endY}",{rx:i,ry:i,xAxisRotation:0,largeArcFlag:d,sweepFlag:h,endX:a,endY:s})),this.__currentPosition={x:a,y:s}}}clip(){var e=this.__closestGroupOrSvg(),t=this.__createElement("clipPath"),i=xf(this.__ids),n=this.__createElement("g");this.__applyCurrentDefaultPath(),e.removeChild(this.__currentElement),t.setAttribute("id",i),t.appendChild(this.__currentElement),this.__defs.appendChild(t),e.setAttribute("clip-path",Cf("url(#{id})",{id:i})),e.appendChild(n),this.__currentElement=n}drawImage(){var e,t,i,n,o,r,a,s,c,l,h,d,f,u=Array.prototype.slice.call(arguments),p=u[0],m=0,g=0;if(3===u.length)e=u[1],t=u[2],i=o=p.width,n=r=p.height;else if(5===u.length)e=u[1],t=u[2],i=u[3],n=u[4],o=p.width,r=p.height;else{if(9!==u.length)throw new Error("Invalid number of arguments passed to drawImage: "+arguments.length);m=u[1],g=u[2],o=u[3],r=u[4],e=u[5],t=u[6],i=u[7],n=u[8]}a=this.__closestGroupOrSvg(),this.__currentElement;var w="translate("+e+", "+t+")";if(p instanceof Df){if((s=p.getSvg().cloneNode(!0)).childNodes&&s.childNodes.length>1){for(c=s.childNodes[0];c.childNodes.length;)f=c.childNodes[0].getAttribute("id"),this.__ids[f]=f,this.__defs.appendChild(c.childNodes[0]);if(l=s.childNodes[1]){var F,b=l.getAttribute("transform");F=b?b+" "+w:w,l.setAttribute("transform",F),a.appendChild(l)}}}else"CANVAS"!==p.nodeName&&"IMG"!==p.nodeName||((h=this.__createElement("image")).setAttribute("width",i),h.setAttribute("height",n),h.setAttribute("preserveAspectRatio","none"),(m||g||o!==p.width||r!==p.height)&&((d=this.__document.createElement("canvas")).width=i,d.height=n,d.getContext("2d").drawImage(p,m,g,o,r,0,0,i,n),p=d),h.setAttribute("transform",w),h.setAttributeNS("http://www.w3.org/1999/xlink","xlink:href","CANVAS"===p.nodeName?p.toDataURL():p.getAttribute("src")),a.appendChild(h))}createPattern(e,t){let i,n=this.__document.__createElement("pattern"),o=xf(this.__ids);return n.setAttribute("id",o),n.setAttribute("width",e.width),n.setAttribute("height",e.height),"CANVAS"===e.nodeName||"IMG"===e.nodeName?(i=this.__createElement("image"),i.setAttribute("width",e.width),i.setAttribute("height",e.height),i.setAttributeNS("http://www.w3.org/1999/xlink","xlink:href","CANVAS"===e.nodeName?e.toDataURL():e.getAttribute("src")),n.appendChild(i),this.__defs.appendChild(n)):e instanceof Df&&(n.appendChild(e.__root.childNodes[1]),this.__defs.appendChild(n)),new zf(n,this)}setLineDash(e){e&&e.length>0?this.lineDash=e.join(","):this.lineDash=null}drawFocusRing(){}createImageData(){}getImageData(){}putImageData(){}globalCompositeOperation(){}setTransform(){}}const Af=function(e,t,i,n){this.start=e,this.end=t,this.name=i,this.stain=0,"acen"===n?this.type="c":(this.type=n.charAt(1),"p"===this.type&&(this.stain=parseInt(n.substring(4))))};function Mf(){return"2.15.13"}const Tf=Ka,Rf={loadGenome:async function(e){const t=e.cytobandURL,i=e.aliasURL,n=await ff(e);let o;i&&(o=await function(e,t){return ad.loadString(e,zd(t)).then((function(e){var t=Tf(e),i=[];return t.forEach((function(e){!e.startsWith("#")&&e.length>0&&i.push(e.split("\t"))})),i}))}(i,n.config));const r=new Lf(e,n,o);return t&&(r.cytobands=await async function(e,t,i){let n;if(Rd(e)){const t=Rh(e);n="";const i=t.length;for(let e=0;e1?function(e,t){let i;if(t.chromosomeOrder)Array.isArray(t.chromosomeOrder)?e.wgChromosomeNames=t.chromosomeOrder:e.wgChromosomeNames=t.chromosomeOrder.split(",").map((e=>e.trim())),i=e.wgChromosomeNames.map((t=>e.chromosomes[t])).filter((e=>void 0!==e));else{const t=Object.keys(e.chromosomes).map((t=>e.chromosomes[t].bpLength)).reduce(((e,t)=>Math.max(e,t)))/50;i=Object.values(e.chromosomes).filter((e=>e.bpLength>t));const n=i.filter((e=>o(e.name.replace("chr","")))),r=i.filter((e=>!o(e.name.replace("chr",""))));n.sort(((e,t)=>Number.parseInt(e.name.replace("chr",""))-Number.parseInt(t.name.replace("chr",""))));const a=n.map((e=>e.name));for(let e of r)a.push(e.name);e.wgChromosomeNames=a}const n=i.reduce(((e,t)=>e+t.bpLength),0);function o(e){return/^\d+$/.test(e)}e.chromosomes.all={name:"all",bpLength:n}}(this,e):this.wgChromosomeNames=t.chromosomeNames;var n={},o=this;n.all="all",this.chromosomeNames.forEach((function(e){var t=e.startsWith("chr")?e.substring(3):"chr"+e;n[t.toLowerCase()]=e,"chrM"===e&&(n.mt="chrM"),"MT"===e&&(n.chrm="MT"),n[e.toLowerCase()]=e})),i&&i.forEach((function(e){var t,i;for(i=0;ie.bpLength)&&(e=i)}return e}}getChromosomes(){return this.chromosomes}getGenomeCoordinate(e,t){var i=this.getCumulativeOffset(e);if(void 0!==i)return i+t}getChromosomeCoordinate(e){let t;void 0===this.cumulativeOffsets&&(this.cumulativeOffsets=computeCumulativeOffsets.call(this));let i=0;for(let n of this.wgChromosomeNames){const o=this.cumulativeOffsets[n];if(o>e){return{chr:t,position:e-i}}t=n,i=o}return{chr:this.wgChromosomeNames[this.wgChromosomeNames.length-1],position:0}}getCumulativeOffset(e){void 0===this.cumulativeOffsets&&(this.cumulativeOffsets=function(){let e=this,t={},i=0;for(let n of e.wgChromosomeNames){t[n]=Math.floor(i);i+=e.getChromosome(n).bpLength}return t}.call(this));const t=this.getChromosomeName(e);return this.cumulativeOffsets[t]}getGenomeLength(){let e=this;if(!this.bpLength){let t=0;e.wgChromosomeNames.forEach((function(i){let n=e.chromosomes[i];t+=n.bpLength})),this.bpLength=t}return this.bpLength}async getSequence(e,t,i){return e=this.getChromosomeName(e),this.sequence.getSequence(e,t,i)}addFeaturesToDB(e,t){const i=(e,t)=>{const i=this.featureDB.get(e);i&&(t=t.end-t.start>i.end-i.start?t:i),this.featureDB.set(e,t)};for(let n of e)if(n.name&&i(n.name.toUpperCase(),n),n.gene&&n.gene.name&&i(n.gene.name.toUpperCase(),n),t.searchableFields)for(let e of t.searchableFields){const t=n.getAttributeValue(e);t&&(t.indexOf(" ")>0?i(t.replaceAll(" ","+").toUpperCase(),n):i(t.toUpperCase(),n))}}}let Bf,Hf=0,Of=0;class Pf extends _f{constructor(e,t,i,n){super(e,t,i,n)}initializationHelper(){this.$spinner=wr("
",{class:"igv-loading-spinner-container"}),this.$viewport.append(this.$spinner),this.$spinner.append(wr("
"));const e=this.trackView.track;"sequence"!==e.type&&(this.$zoomInNotice=this.createZoomInNotice(this.$viewport)),e.name&&"sequence"!==e.id&&(this.$trackLabel=wr('
'),this.$viewport.append(this.$trackLabel),this.setTrackLabel(e.name),!1===this.browser.trackLabelsVisible&&this.$trackLabel.hide()),this.stopSpinner(),this.addMouseHandlers()}setContentHeight(e){super.setContentHeight(e),this.featureCache&&(this.featureCache.redraw=!0)}setTrackLabel(e){this.$trackLabel.empty(),this.$trackLabel.html(e);const t=this.$trackLabel.text();this.$trackLabel.attr("title",t)}startSpinner(){this.$spinner.show()}stopSpinner(){this.$spinner&&this.$spinner.hide()}checkZoomIn(){if(this.trackView.track&&"sequence"===this.trackView.track.type&&this.referenceFrame.bpPerPixel>10)return wr(this.canvas).remove(),this.canvas=void 0,!1;if(!this.viewIsReady())return!1;if((()=>{if("all"!==this.referenceFrame.chr.toLowerCase()||this.trackView.track.supportsWholeGenome){const e=this.trackView.track.visibilityWindow;return void 0!==e&&e>0&&this.referenceFrame.bpPerPixel*this.$viewport.width()>e}return!0})()){if(this.canvas&&(wr(this.canvas).remove(),this.canvas=void 0),this.trackView.track.autoHeight){const e=this.trackView.minHeight||0;this.setContentHeight(e)}return this.$zoomInNotice&&this.$zoomInNotice.show(),!1}return this.$zoomInNotice&&this.$zoomInNotice.hide(),!0}shift(){const e=this.referenceFrame;if(this.canvas&&this.canvas._data&&this.canvas._data.referenceFrame.chr===this.referenceFrame.chr&&this.canvas._data.bpPerPixel===e.bpPerPixel){const t=Math.round((this.canvas._data.bpStart-e.start)/e.bpPerPixel);this.canvas.style.left=t+"px"}}setTop(e){if(super.setTop(e),this.canvas){const t=this.$viewport.height(),i=e+this.canvas._data.pixelTop,n=i+this.canvas._data.pixelHeight;(i>0||n0)for(let n of i.roiSets){const i=await n.getFeatures(t,o,r,e.bpPerPixel);a.push({track:n,features:i})}const s=i&&("wig"===i.type||"merged"===i.type);return this.featureCache=new qf(t,o,r,e.bpPerPixel,n,a,s),this.loading=!1,this.hideMessage(),this.stopSpinner(),this.featureCache}}catch(e){this.trackView&&!0!==this.trackView.disposed&&(this.showMessage("Error loading track data"),this.browser.alert.present(e),console.error(e))}finally{this.loading=!1,this.stopSpinner()}}}repaintDimensions(){const e=Rf.isWholeGenomeView(this.referenceFrame.chr),t=e?this.$viewport.width():3*this.$viewport.width(),i=this.referenceFrame.bpPerPixel;return{bpStart:this.referenceFrame.start-(e?0:t/3*i),bpEnd:this.referenceFrame.end+(e?0:t/3*i),pixelWidth:t}}repaint(){if(void 0===this.featureCache)return;const{features:e,roiFeatures:t}=this.featureCache,{bpStart:i,bpEnd:n,pixelWidth:o}=this.repaintDimensions(),r=this.$viewport.height(),a=this.getContentHeight(),s=t?Math.max(a,r):a,c=Math.min(s,3*r);if(0===o||0===c)return void(this.canvas&&wr(this.canvas).remove());const l=Math.max(0,-this.contentTop-Math.floor(c/3)),h=this.referenceFrame.bpPerPixel,d=Math.round((i-this.referenceFrame.start)/h),f=(this.contentTop||0)+l,u=document.createElement("canvas");u.style.position="relative",u.style.display="block",u.style.width=o+"px",u.style.height=c+"px",u.style.left=d+"px",u.style.top=f+"px";const p="FILL"===this.trackView.track.displayMode||!1!==this.trackView.track.supportHiDPI?window.devicePixelRatio:1;u.width=p*o,u.height=p*c;const m=u.getContext("2d");m.scale(p,p),m.translate(0,-l);const g={context:m,pixelXOffset:d,pixelWidth:o,pixelHeight:c,pixelTop:l,bpStart:i,bpEnd:n,bpPerPixel:h,referenceFrame:this.referenceFrame,selection:this.selection,viewport:this,viewportWidth:this.$viewport.width()};this.draw(g,e,t),this.canvas&&wr(this.canvas).remove(),u._data=g,this.canvas=u,this.$viewport.append(wr(u))}refresh(){if(!this.canvas||!this.featureCache)return;const e=this.canvas._data;e.context.clearRect(0,0,this.canvas.width,this.canvas.height);const{features:t,roiFeatures:i}=this.featureCache;this.draw(e,t,i)}draw(e,t,i){if(t&&(e.features=t,this.trackView.track.draw(e)),i&&i.length>0)for(let t of i)e.features=t.features,t.track.draw(e)}containsPosition(e,t){return this.referenceFrame.chr===e&&t>=this.referenceFrame.start&&t<=this.referenceFrame.calculateEnd(this.getWidth())}isLoading(){return this.loading}savePNG(){if(!this.canvas)return;const e=this.canvas._data,t=e?e.pixelTop:0,i=window.devicePixelRatio,n=this.$viewport.width()*i,o=this.$viewport.height()*i,r=-wr(this.canvas).position().left*i,a=(-this.contentTop-t)*i,s=this.canvas.getContext("2d").getImageData(r,a,n,o),c=document.createElement("canvas"),l=c.getContext("2d");c.width=s.width,c.height=s.height,l.putImageData(s,0,0);es((this.$trackLabel.text()?this.$trackLabel.text():"image")+".png",c.toDataURL("image/png"))}saveSVG(){let{width:e,height:t}=this.browser.columnContainer.getBoundingClientRect();const i=new Df({width:e,height:8e3,backdropColor:"white",multiLocusGap:0,viewbox:{x:0,y:0,width:e,height:8e3}}),n={deltaX:32,deltaY:32};this.renderViewportToSVG(i,n),i.setHeight(t);const o=(this.trackView.track.name||this.trackView.track.id).replace(/\W/g,""),r=this.browser.referenceFrameList.indexOf(this.referenceFrame),a=i.getSerializedSvg(!0),s=URL.createObjectURL(new Blob([a],{type:"application/octet-stream"}));es(`${`${o}_referenceFrame_${r}_guid_${xr.guid()}`}.svg`,s)}renderViewportToSVG(e,{deltaX:t,deltaY:i}){if(this.$zoomInNotice&&this.$zoomInNotice.is(":visible"))return;const{width:n,height:o}=this.$viewport.get(0).getBoundingClientRect(),r=`${(this.trackView.track.name||this.trackView.track.id).replace(/\W/g,"")}_referenceFrame_${this.browser.referenceFrameList.indexOf(this.referenceFrame)}_guid_${xr.guid()}`;this.drawSVGWithContext(e,n,o,r,t,i+this.contentTop,-this.contentTop)}renderSVGContext(e,{deltaX:t,deltaY:i}){if(this.renderViewportToSVG(e,{deltaX:t,deltaY:i}),(!this.$zoomInNotice||!this.$zoomInNotice.is(":visible"))&&this.$trackLabel&&!0===this.browser.trackLabelsVisible){const{x:n,y:o,width:r,height:a}=xr.relativeDOMBBox(this.$viewport.get(0),this.$trackLabel.get(0));this.renderTrackLabelSVG(e,t+n,i+o,r,a)}}renderTrackLabelSVG(e,t,i,n,o){const r=`${(this.trackView.track.name||this.trackView.track.id).replace(/\W/g,"")}_track_label_guid_${xr.guid()}`;e.saveWithTranslationAndClipRect(r,t,i,n,o,0),e.fillStyle="white",e.fillRect(0,0,n,o),e.font="12px Arial",e.fillStyle="rgb(68, 68, 68)";const{width:a}=e.measureText(this.$trackLabel.text()),s=.25*(n-a),c=.7*(o-12);e.fillText(this.$trackLabel.text(),s,o-c),e.strokeStyle="rgb(68, 68, 68)",e.strokeRect(0,0,n,o),e.restore()}drawSVGWithContext(e,t,i,n,o,r,a){e.saveWithTranslationAndClipRect(n,o,r,t,i,a);let{start:s,bpPerPixel:c}=this.referenceFrame;const l={context:e,viewport:this,referenceFrame:this.referenceFrame,top:a,pixelTop:a,pixelWidth:t,pixelHeight:i,bpStart:s,bpEnd:s+t*c,bpPerPixel:c,viewportWidth:t,selection:this.selection},h=this.featureCache?this.featureCache.features:void 0,d=this.featureCache?this.featureCache.roiFeatures:void 0;this.draw(l,h,d),e.restore()}get cachedFeatures(){return this.featureCache?this.featureCache.features:[]}clearCache(){this.featureCache=void 0,this.canvas&&(this.canvas._data=void 0)}async getFeatures(e,t,i,n,o){if(this.featureCache&&this.featureCache.containsRange(t,i,n,o))return this.featureCache.features;if("function"==typeof e.getFeatures){const r=await e.getFeatures(t,i,n,o,this);return this.checkContentHeight(r),r}}needsRepaint(){if(!this.canvas)return!0;const e=this.canvas._data;return!e||this.referenceFrame.starte.bpEnd||this.referenceFrame.chr!==e.referenceFrame.chr||this.referenceFrame.bpPerPixel!=e.bpPerPixel}needsReload(){if(!this.featureCache)return!0;const{chr:e,bpPerPixel:t}=this.referenceFrame,{bpStart:i,bpEnd:n}=this.repaintDimensions();return!this.featureCache.containsRange(e,i,n,t)}createZoomInNotice(e){const t=wr("
",{class:"igv-zoom-in-notice-container"});e.append(t);const i=wr("
");return t.append(i),i.text("Zoom in to see features"),t.hide(),t}viewIsReady(){return this.browser&&this.browser.referenceFrameList&&this.referenceFrame}addMouseHandlers(){const e=this.$viewport.get(0);this.addViewportContextMenuHandler(e);const t=e=>{this.enableClick=!0,this.browser.mouseDownOnViewport(e,this),xr.pageCoordinates(e)};e.addEventListener("mousedown",t),e.addEventListener("touchstart",t);const i=e=>{this.browser.dragObject||this.browser.isScrolling?(this.browser.cancelTrackPan(),this.enableClick=!1):(this.browser.cancelTrackPan(),this.browser.endTrackDrag())};e.addEventListener("mouseup",i),e.addEventListener("touchend",i),"function"==typeof this.trackView.track.hoverText&&e.addEventListener("mousemove",(e=>{if(0===e.buttons&&Date.now()-Of>100){Of=Date.now();const t=this.createClickState(e);if(t){const e=this.trackView.track.hoverText(t);e?this.$viewport[0].setAttribute("title",e):this.$viewport[0].removeAttribute("title")}}})),this.addViewportClickHandler(this.$viewport.get(0)),this.trackView.track.name&&"sequence"!==this.trackView.track.config.type&&this.addTrackLabelClickHandler(this.$trackLabel.get(0))}addViewportContextMenuHandler(e){e.addEventListener("contextmenu",(e=>{if(this.browser.dragObject)return!1;const t=this.createClickState(e);if(void 0===t)return!1;e.preventDefault();let i=[];if("function"==typeof this.trackView.track.contextMenuItemList){const e=this.trackView.track.contextMenuItemList(t);e&&(i=e)}i.length>0&&i.push({label:wr("
")}),i.push({label:"Save Image (PNG)",click:()=>this.savePNG()}),i.push({label:"Save Image (SVG)",click:()=>this.saveSVG()}),this.browser.menuPopup.presentTrackContextMenu(e,i)}))}addViewportClickHandler(e){e.addEventListener("click",(e=>{if(this.enableClick&&this.canvas){if(3===e.which||e.ctrlKey)return;if(wr(".igv-popover").hide(),this.browser.dragObject||this.browser.isScrolling)return;e.preventDefault();const t=xr.translateMouseCoordinates(e,this.$viewport.get(0)).x,i=xr.translateMouseCoordinates(e,this.canvas).x,n=this.referenceFrame,o=Math.floor(n.start+n.toBP(i)),r=Date.now();if(r-Hfe));e[this.browser.referenceFrameList.indexOf(this.referenceFrame)]=t,i=e.join(" ")}this.browser.search(i)}else this.browser.zoomWithScaleFactor(.5,e,this.referenceFrame)}else e.shiftKey&&"function"==typeof this.trackView.track.shiftClick?this.trackView.track.shiftClick(o,e):"function"==typeof this.trackView.track.popupData&&(Bf=setTimeout((()=>{const t=this.getPopupContent(e);t&&(this.popover&&this.popover.dispose(),this.popover=new Oa(this.browser.columnContainer),this.popover.presentContentWithEvent(e,t)),window.clearTimeout(Bf),Bf=void 0}),this.browser.constants.doubleClickDelay));Hf=r}}))}addTrackLabelClickHandler(e){e.addEventListener("click",(e=>{e.stopPropagation();const{track:t}=this.trackView;let i;"function"==typeof t.description?i=t.description():t.description&&(i=`
${t.description}
`),i&&(this.popover&&this.popover.dispose(),this.popover=new Oa(this.browser.columnContainer,t.name||""),this.popover.presentContentWithEvent(e,i))}))}createClickState(e){if(!this.canvas)return;const t=this.referenceFrame,i=xr.translateMouseCoordinates(e,this.$viewport.get(0)),n=xr.translateMouseCoordinates(e,this.canvas),o=t.start+t.toBP(i.x);return{event:e,viewport:this,referenceFrame:t,genomicLocation:o,y:i.y-this.contentTop,canvasX:n.x,canvasY:n.y}}getPopupContent(e){const t=this.createClickState(e);if(void 0===t)return;let i=this.trackView.track;const n=i.popupData(t),o=this.browser.fireEvent("trackclick",[i,n]);let r;return void 0===o||!0===o?n&&n.length>0&&(r=n.map((e=>{if(e.name){const t=`${e.name}   ${e.value}`;return`
${t}
`}return"
"===e?e:e.html?e.html:`
${e}
`})).join("")):"string"==typeof o&&(r=o),r}}class qf{constructor(e,t,i,n,o,r,a){this.chr=e,this.bpStart=t,this.bpEnd=i,this.bpPerPixel=n,this.features=o,this.roiFeatures=r,this.multiresolution=a}containsRange(e,t,i,n){const o=this.multiresolution?this.bpPerPixel/n:1;return t>=this.bpStart&&i<=this.bpEnd&&e===this.chr&&o>.5&&o<2}overlapsRange(e,t,i){return this.chr===e&&i>=this.bpStart&&t<=this.bpEnd}}function Vf(e,t){if(!(e.length<6))return{chr:e[0],start:e[1],end:e[2],chr1:e[8],start1:Number.parseInt(e[9]),end1:Number.parseInt(e[10]),chr2:e[13],start2:Number.parseInt(e[14]),end2:Number.parseInt(e[15]),name:e[3],score:Number(e[4]),value:Number(e[5]),color:"."===e[7]?void 0:"0"===e[7]?"rgb(0,0,0)":e[7]};console.log("Skipping line: "+e.join(" "))}const Uf=new Set(["transcript","primary_transcript","processed_transcript","mRNA","mrna","lnc_RNA","miRNA","ncRNA","rRNA","scRNA","snRNA","snoRNA","tRNA"]),jf=new Set(["CDS","cds"]),Wf=new Set(["start_codon","stop_codon"]),Gf=new Set(["5UTR","3UTR","UTR","five_prime_UTR","three_prime_UTR","3'-UTR","5'-UTR"]),$f=new Set(["exon","coding-exon"]),Zf=new Set;for(let Hk of[jf,Wf,Gf,$f])for(let Ok of Hk)Zf.add(Ok);function Kf(e){return e.includes("intron")}function Xf(e){return jf.has(e)||Wf.has(e)}function Yf(e){return Gf.has(e)}function Qf(e){return Uf.has(e)||e.endsWith("RNA")||e.endsWith("transcript")}function Jf(e){return Zf.has(e)||e.endsWith("RNA")||Kf(e)}const eu=new Set(["id","parent","name"]);class tu{constructor(e){Object.assign(this,e)}popupData(e){const t=this.geneObject?this.geneObject.popupData():[];if(this.geneObject&&t.push("
"),this.name&&t.push({name:"Name",value:this.name}),t.push({name:"Type",value:this.type}),t.push({name:"Source",value:this.source}),void 0!==this.score&&t.push({name:"Score",value:this.score}),this.attributeString){const e=au(this.attributeString,this.delim);for(let[i,n]of e)void 0!==n&&n.length>0&&!eu.has(i.toLowerCase())&&t.push({name:i+":",value:n})}return t.push({name:"Location",value:`${this.chr}:${Za(this.start+1)}-${Za(this.end)}`}),t}getAttributeValue(e){if(this.hasOwnProperty(e))return this[e];if(this._attributeCache||(this._attributeCache=new Map),this._attributeCache.has(e))return this._attributeCache.get(e);{const t=au(this.attributeString,this.delim);let i;for(let[n,o]of t)if(n===e){i=o;break}return this._attributeCache.set(e,i),i}}}class iu extends tu{constructor(e){super(e),this.exons=[],this.parts=[]}addExon(e){this.exons.push(e),this.start=Math.min(this.start,e.start),this.end=Math.max(this.end,e.end)}addPart(e){this.parts.push(e)}assembleParts(){if(0===this.parts.length)return;this.parts.sort((function(e,t){return e.start-t.start}));let e=this.parts[0].start,t=this.parts[0].end;for(let i=1;i=t&&i.start<=e)return i}addCDS(e){let t;const i=this.exons;for(let n of i)if(n.start<=e.start&&n.end>=e.end){t=n;break}t?(t.cdStart=t.cdStart?Math.min(e.start,t.cdStart):e.start,t.cdEnd=t.cdEnd?Math.max(e.end,t.cdEnd):e.end):console.error("No exon found spanning "+e.start+"-"+e.end),this.cdStart=this.cdStart?Math.min(e.start,this.cdStart):e.start,this.cdEnd=this.cdEnd?Math.max(e.end,this.cdEnd):e.end}addUTR(e){let t;const i=this.exons;for(let n=0;n=e.end){t=i[n];break}t?e.start===t.start&&e.end===t.end?t.utr=!0:(e.endt.start&&(t.cdEnd=e.start)):console.error("No exon found spanning "+cds.start+"-"+cds.end)}finish(){this.assembleParts();var e=this.cdStart,t=this.cdEnd;this.exons.sort((function(e,t){return e.start-t.start})),e&&this.exons.forEach((function(i){(i.endt)&&(i.utr=!0)}))}popupData(e){const t=super.popupData(e);for(let i of this.exons)if(!i.pseudo&&e>=i.start&&e");const n=i.popupData(e);for(let e of n)t.push(e)}for(let i of this.parts)if(e>=i.start&&e");const n=i.popupData(e);for(let e of n)t.push(e)}return t}}function nu(e,t){const i=t.format;if(e.length<9)return;const n="gff3"===i?"=":" ";return new tu({source:lu(e[1]),type:e[2],chr:e[0],start:parseInt(e[3])-1,end:parseInt(e[4]),score:"."===e[5]?void 0:Number(e[5]),strand:e[6],phase:"."===e[7]?0:parseInt(e[7]),attributeString:e[8],delim:n})}function ou(e,t){const i=nu(e,t);if(!i)return;const n=au(i.attributeString,i.delim);for(let[e,t]of n){const n=e.toLowerCase();"color"===n||"colour"===n?i.color=qh.createColorString(t):"ID"===e?i.id=t:"Parent"===e&&(i.parent=t)}return i}function ru(e,t){const i=nu(e,t);if(!i)return;const n=au(i.attributeString,i.delim);let o,r;switch(i.type){case"gene":o="gene_id";break;case"transcript":o="transcript_id",r="gene_id";break;default:r="transcript_id"}for(let[e,t]of n){const n=e.toLowerCase();"color"===n||"colour"===n?i.color=qh.createColorString(t):e===o?i.id=t:e===r&&(i.parent=t)}return i}function au(e,t,i=!1){var n=[];for(let o of e.split(";")){o=o.trim();const e=o.indexOf(t);if(e>0&&e2?parseInt(e[2]):n+1;if(isNaN(n)||isNaN(o))return new hu("Unparsable bed record.");const r=new Cu({chr:i,start:n,end:o,score:1e3});try{if(e.length>3){if(e[3].indexOf(";")>0&&e[3].indexOf("=")>0){const i=au(e[3],"=",!0);r.attributes={};for(let e of i)r.attributes[e[0]]=e[1],null!=t.nameField&&e[0]===t.nameField&&(r.name=e[1])}r.name||(r.name="."===e[3]?"":e[3])}if(e.length>4&&(r.score="."===e[4]?0:Number(e[4]),isNaN(r.score)))return r;if(e.length>5&&(r.strand=e[5],"."!==r.strand&&"+"!==r.strand&&"-"!==r.strand))return r;if(e.length>6&&(r.cdStart=parseInt(e[6]),isNaN(r.cdStart)))return r;if(e.length>7&&(r.cdEnd=parseInt(e[7]),isNaN(r.cdEnd)))return r;if(e.length>8&&"."!==e[8]&&"0"!==e[8]&&(r.color=qh.createColorString(e[8])),e.length>11){const t=parseInt(e[9]);if(t>1e3)return r;const i=e[10].replace(/,$/,"").split(","),o=e[11].replace(/,$/,"").split(",");if(i.length!==o.length||t!==i.length)return r;const a=[];for(let e=0;e0&&(Fu(a,r.cdStart,r.cdEnd),r.exons=a)}if(t){let i=t.thicknessColumn,n=t.colorColumn;n&&ni?n.utr=!0:(t>=o&&t<=e&&(n.cdStart=t),i>=o&&i<=e&&(n.cdEnd=i))}}function bu(e,t){var i,n,o,r,a,s,c;if(!(e.length<9))return i=e[0],n=parseInt(e[1]),o=parseInt(e[2]),a=e[3],s=Number(e[4]),r=e[5].trim(),c=Number(e[6]),0===s&&(s=c),{chr:i,start:n,end:o,name:a,score:s,strand:r,signal:c,pValue:Number(e[7]),qValue:Number(e[8])}}function vu(e,t){if(e.length<=3)return;const i={chr:e[0],start:parseInt(e[1]),end:parseInt(e[2]),value:Number(e[3])};if(t){let n=t.colorColumn;n&&n0)for(var f=c.split(","),u=0;ud&&(d=g),l.spanning_frag_coords.push({left:m,right:g})}return l.start=h,l.end=d,l}}function Eu(e,t){if(e.length<7)return null;const i={chr:e[0],start:parseInt(e[1])-1,end:parseInt(e[2]),"Strongest SNP-risk allele":e[3],"Disease/Phenotype":e[4],"P-value":e[5],"Odds ratio or beta":e[6]};return e.length>6&&(i.PUBMEDID=`${e[7]}`),i}function Nu(e,t){const i=t.customFormat;if(e.length1&&(t=e)}else{this.setDecoder(n.format);const e=i.split(this.delimiter||"\t");try{const i=Object.assign({columnNames:t},n);if(this.decode(e,i))break;e.length>1&&(t=e)}catch(i){e.length>1&&(t=e)}}}if(t){n.columnNames=t;for(let e=0;e0&&console.error(`Error parsing line '${r}': ${c.message}`)):c&&t.push(c)}return i===Pd&&function(e){if(0==e.length)return;const t=e[0];if(void 0===t.score&&void 0!==t.name){for(let t of e)if(!("number"==typeof(i=t.name)?i-i==0:"string"==typeof i&&""!==i.trim()&&(Number.isFinite?Number.isFinite(+i):isFinite(+i)))&&"."!==t.name)return;for(let t of e)t.score=Number(t.name),delete t.name}var i;const n=e.filter((e=>e.chr1!==e.chr2));for(let t of n){const i=Object.assign({},t);i.dup=!0,e.push(i),t.chr=t.chr1,t.start=t.start1,t.end=t.end1,i.chr=i.chr2,i.start=i.start2,i.end=i.end2}}(t),t}setDecoder(e){switch(e){case"narrowpeak":case"broadpeak":case"regionpeak":case"peaks":this.decode=bu,this.delimiter=this.config.delimiter||/\s+/;break;case"bedgraph":this.decode=vu,this.delimiter=/\s+/;break;case"wig":this.decode=yu,this.delimiter=this.config.delimiter||/\s+/;break;case"gff3":case"gff":this.decode=ou,this.delimiter="\t";break;case"gtf":this.decode=ru,this.delimiter="\t";break;case"fusionjuncspan":this.decode=ku,this.delimiter=this.config.delimiter||/\s+/;break;case"gtexgwas":this.skipRows=1,this.decode=Eu,this.delimiter="\t";break;case"refflat":this.decode=mu,this.delimiter=this.config.delimiter||/\s+/;break;case"genepred":this.decode=uu,this.delimiter=this.config.delimiter||/\s+/;break;case"genepredext":this.decode=pu,this.delimiter=this.config.delimiter||/\s+/;break;case"ensgene":this.decode=uu,this.header.shift=1,this.delimiter=this.config.delimiter||/\s+/;break;case"refgene":this.decode=pu,this.delimiter=this.config.delimiter||/\s+/,this.header.shift=1;break;case"bed":this.decode=du,this.delimiter=this.config.delimiter||/\s+/;break;case"bedpe":case"hiccups":this.decode=Pd,this.delimiter=this.config.delimiter||"\t";break;case"bedpe-domain":this.decode=qd,this.headerLine=!0,this.delimiter=this.config.delimiter||"\t";break;case"bedpe-loop":this.decode=Pd,this.delimiter=this.config.delimiter||"\t",this.header={colorColumn:7};break;case"interact":this.decode=Vf,this.delimiter=this.config.delimiter||/\s+/;break;case"snp":this.decode=_u,this.delimiter="\t";break;case"rmsk":this.decode=fu,this.delimiter="\t";break;case"gcnv":this.decode=Su,this.delimiter="\t";break;default:const t=jd(e);void 0!==t?(this.decode=Nu,this.header.customFormat=t,this.delimiter=t.delimiter||"\t"):(this.decode=du,this.delimiter=this.config.delimiter||/\s+/)}}}function zu(e){const t={},i=e.split(/(?:")([^"]+)(?:")|([^\s"]+)(?=\s+|$)/g);let n;const o=[];for(let e of i)e&&0!==e.trim().length&&(e.endsWith("=")?n=e:n?(o.push(n+e),n=void 0):o.push(e));for(let e of o){if(!e)return;var r=e.split("=",2);if(2===r.length){const e=r[0].trim(),i=r[1].trim();if(t.hasOwnProperty(e)){let n=t[e];Array.isArray(n)?n.push(i):t[e]=[n,i]}else t[e]=i}}return"interact"==t.type?t.format="interact":"gcnv"===t.type&&(t.format="gcnv"),t}function Du(e){let t={},i=e.split(/\s+/);if(2===i.length){i[1].split(";").forEach((function(e){let i=e.split("=");"color"===i[0]?t.colorColumn=Number.parseInt(i[1])-1:"thickness"===i[0]&&(t.thicknessColumn=Number.parseInt(i[1])-1)}))}return t}function Au(e){const t=e.split(/\s+/);return{format:"fixedStep",chrom:t[1].split("=")[1],start:parseInt(t[2].split("=")[1],10)-1,step:parseInt(t[3].split("=")[1],10),span:t.length>4?parseInt(t[4].split("=")[1],10):1,index:0}}function Mu(e){const t=e.split(/\s+/);return{format:"variableStep",chrom:t[1].split("=")[1],span:t.length>2?parseInt(t[2].split("=")[1],10):1}}class Tu{static defaults={height:50,autoHeight:!1,visibilityWindow:void 0,color:void 0,altColor:void 0,supportHiDPI:!0};constructor(e,t){this.browser=t,this.init(e)}init(e){this.config=e,e.displayMode&&(e.displayMode=e.displayMode.toUpperCase());const t=Object.assign({},Tu.defaults);if(this.constructor.defaults)for(let e of Object.keys(this.constructor.defaults))t[e]=this.constructor.defaults[e];for(let n of Object.keys(t))this[n]=e.hasOwnProperty(n)?e[n]:t[n],"color"!==n&&"altColor"!==n||(this[n]=$a(i=this[n])&&i.indexOf(",")>0&&!i.startsWith("rgb(")&&!i.startsWith("rgba(")?`rgb(${i})`:i);var i;e.name||e.label?this.name=e.name||e.label:Ja(e.url)?this.name=e.url.name:$a(e.url)&&!e.url.startsWith("data:")&&(this.name=Qa(e.url)),this.url=e.url,this.config.type&&(this.type=this.config.type),this.id=void 0===this.config.id?this.name:this.config.id,this.order=e.order,this.autoscaleGroup=e.autoscaleGroup,this.removable=void 0===e.removable||e.removable,this.minHeight=e.minHeight||Math.min(25,this.height),this.maxHeight=e.maxHeight||Math.max(1e3,this.height),e.onclick&&(this.onclick=e.onclick,e.onclick=void 0),e.description&&("function"==typeof e.description?this.description=e.description:this.description=()=>e.description),e.hoverTextFields?this.hoverText=Ru.bind(this):"function"==typeof this.config.hoverText&&(this.hoverText=this.config.hoverText)}get name(){return this._name}set name(e){this._name=e,this.trackView&&this.trackView.setTrackLabelName(e)}updateConfig(e){this.init(e)}clearCachedFeatures(){this.trackView&&this.trackView.clearCachedFeatures()}updateViews(){this.trackView&&this.trackView.updateViews()}getState(){const e={};for(let i of Object.keys(this.config))i.startsWith("_")||(void 0===(t=this.config[i])||"function"==typeof t||t instanceof File||t instanceof Promise)||(e[i]=this.config[i]);var t;for(let t of Object.keys(e)){if(t.startsWith("_"))continue;const i=this[t];i&&(Id(i)||"boolean"==typeof i||"metadata"===t)&&(e[t]=i)}const i=Tu.defaults;if(this.constructor.defaults)for(let e of Object.keys(this.constructor.defaults))i[e]=this.constructor.defaults[e];for(let t of Object.keys(i))void 0!==this[t]&&i[t]!==this[t]&&(e[t]=this[t]);return!this.autoscale&&this.dataRange&&(e.min=this.dataRange.min,e.max=this.dataRange.max),e}get supportsWholeGenome(){return!0===this.config.supportsWholeGenome}hasSamples(){return!1}getGenomeId(){return this.browser.genome?this.browser.genome.id:void 0}setTrackProperties(e){if(this.disposed)return;const t={};let i;for(let n of Object.keys(e))switch(n.toLowerCase()){case"usescore":t.useScore=1===e[n]||"1"===e[n]||"on"===e[n]||!0===e[n];break;case"visibility":switch(e[n]){case"2":case"3":case"pack":case"full":t.displayMode="EXPANDED";break;case"4":case"squish":t.displayMode="SQUISHED";break;case"1":case"dense":t.displayMode="COLLAPSED"}break;case"color":case"altcolor":t[n]=e[n].startsWith("rgb(")?e[n]:"rgb("+e[n]+")";break;case"featurevisiblitywindow":case"visibilitywindow":t.visibilityWindow=Number.parseInt(e[n]);break;case"maxheightpixels":i=e[n].split(":"),3===i.length&&(t.minHeight=Number.parseInt(i[2]),t.height=Number.parseInt(i[1]),t.maxHeight=Number.parseInt(i[0]));break;case"viewlimits":if(!this.config.autoscale){i=e[n].split(":");let o,r=0;1==i.length?o=Number(i[0]):2==i.length&&(r=Number(i[0]),o=Number(i[1])),t.autoscale=!1,t.dataRange={min:r,max:o},this.viewLimitMin=r,this.viewLimitMax=o}case"name":t[n]=e[n];break;case"url":t.infoURL=e[n];break;case"type":const o=e[n];Lu.has(o)?t[n]=Lu.get(o):t[n]=o;break;case"graphtype":t.graphType=e[n];break;default:t[n]=e[n]}for(let e of Object.keys(t))if(!this.config.hasOwnProperty(e)||"name"===e&&this.config._derivedName){let i=t[e];if("true"===i&&(i=!0),"false"===i&&(i=!1),this[e]=i,"height"===e&&this.trackView)try{const e=Number.parseInt(i);this.trackView.setTrackHeight(e)}catch(e){console.error(e)}}}clickedFeatures(e){const t=e.viewport.cachedFeatures;if(!t||!Array.isArray(t)||0===t.length)return[];const i=e.genomicLocation,n=e.referenceFrame.bpPerPixel>.2?3*e.referenceFrame.bpPerPixel:.2;return Fd(t,i-n,i+n)}extractPopupData(e,t){const i=new Set(["row","color","chr","start","end","cdStart","cdEnd","strand","alpha"]),n=[];let o,r;for(let t in e)if(e.hasOwnProperty(t)&&!i.has(t)&&Id(e[t])){let i=e[t];n.push({name:Ya(t),value:i}),"alleles"===t?o=e[t]:"alleleFreqs"===t&&(r=e[t])}if(o&&r){o.endsWith(",")&&(o=o.substr(0,o.length-1)),r.endsWith(",")&&(r=r.substr(0,r.length-1));let i=o.split(","),a=r.split(",");if(a.length>1){let o=[];for(let e=0;e=0;i--){let a=o[i].a;if(1===a.length){t||(t=this.getGenomeId());const i=Tu.getCravatLink(e.chr,e.start+1,r,a,t);console.log(i),i&&(n.push("
"),n.push({html:i}),n.push("
"))}}}}if(e.attributes)for(let t of Object.keys(e.attributes))n.push({name:t,value:e.attributes[t]});let a=`${e.chr}:${Za(e.start+1)}-${Za(e.end)}`;return e.strand&&(a+=` (${e.strand})`),n.push({name:"Location",value:a}),n}description(){const e=(e,t)=>`
${e}: ${t}
`;let t='
';if(this.url?Ja(this.url)?t+=e("Filename",this.url.name):t+=e("URL",this.url):t=this.name,this.config){if(this.config.metadata)for(let i of Object.keys(this.config.metadata)){t+=e(i,this.config.metadata[i])}for(let i of Object.keys(this.config)){if(i.startsWith("_"))continue;let n=i.substr(0,1);if(n!==n.toLowerCase()){const n=this.config[i];n&&Id(n)&&(t+=e(i,n))}}}return t+="
",t}getColorForFeature(e){return"function"==typeof this.color?this.color(feature):this.color}dispose(){this.disposed=!0;for(let e of Object.keys(this))this[e]=void 0}static getCravatLink(e,t,i,n,o){if("hg38"===o||"GRCh38"===o){return`Cravat ${i}->${n}`}}}function Ru(e){if(!this.hoverTextFields)return;const t=this.clickedFeatures(e);if(t&&t.length>0){let e="";for(let i=0;i0&&(e+="\n"),e="";for(let t of this.hoverTextFields)e.length>0&&(e+="\n"),n.hasOwnProperty(t)?e+=n[t]:"function"==typeof n.getAttribute&&(e+=n.getAttribute(t))}return e}}const Lu=new Map([["wiggle_0","wig"],["bed","bed"],["bigBed","bigBed"],["bigWig","bigWig"]]);class Bu{constructor(e){switch(this.type=e||"seg",this.type){case"mut":this.sampleColumn=3,this.chrColumn=0,this.startColumn=1,this.endColumn=2,this.dataColumn=4;break;case"maf":this.sampleColumn=15,this.chrColumn=4,this.startColumn=5,this.endColumn=6,this.dataColumn=8;break;default:this.sampleColumn=0,this.chrColumn=1,this.startColumn=2,this.endColumn=3}}async parseHeader(e){let t;for(;void 0!==(t=await e.nextLine());)if(!t.startsWith("#")){const e=t.split("\t");this.header={headings:e};break}return this.header}async parseFeatures(e){const t=[];let i;this.header||(this.header=await this.parseHeader(e)),"seg"===this.type&&(this.dataColumn=this.header.headings.length-1),this.header.headings.length>5&&(i=this.extractExtraColumns(this.header.headings));const n=this.header.headings[this.dataColumn];let o;for(;void 0!==(o=await e.nextLine());){const e=o.split("\t"),r="seg"===this.type?Number(e[this.dataColumn]):e[this.dataColumn];if(e.length>this.dataColumn){const o=new Hu({sample:e[this.sampleColumn],chr:e[this.chrColumn],start:parseInt(e[this.startColumn])-1,end:parseInt(e[this.endColumn]),value:r,valueColumnName:n});if(i){const t=this.extractExtraColumns(e);o.setAttributes({names:i,values:t})}t.push(o)}}return t}extractExtraColumns(e){const t=[];for(let i=0;i=0)return this.attributeValues[t]}}popupData(e,t){const i=new Set(["chr","start","end","sample","value","row","color","sampleKey","uniqueSampleKey","sampleId","chromosome","uniquePatientKey"]),n=this.chr+":"+Za(this.start+1)+"-"+Za(this.end),o=[{name:"Sample",value:this.sample},{name:"Location",value:n},{name:this.valueColumnName?Ya(this.valueColumnName):"Value",value:this.value}];if("mut"===e&&"hg38"===t){const e=this.extractCravatLink(t);e&&(o.push("
"),o.push({html:e}),o.push("
"))}if(this.attributeNames&&this.attributeNames.length>0)for(let e=0;e0)for(let n=0;n"===t||"<*>"===t||"."===t)return"NONVARIANT";{const e=t.split(",").map((function(e){return 1===i&&1===e.length?"SNP":""===e?"NONVARIANT":"OTHER"}));let n=e[0];for(let t of e)if(t!==n)return"MIXED";return n}}(e,t)),"NONVARIANT"===this.type&&(this.heterozygosity=0),this.info.END)this.start=this.pos-1,this.info.CHR2&&this.info.CHR2!==this.chr?this.end=this.start+1:this.end=Number.parseInt(this.info.END);else if("NONVARIANT"===this.type)this.start=this.pos-1,this.end=this.start+e.length;else{const i=t.split(",").filter((e=>e.length>0));this.alleles=[],this.start=void 0,this.end=void 0;for(let t of i)if(this.alleles.push(t),"SV"!==this.type&&Vu(t)){let i=t.length,n=e.length;const o=Math.min(i,n);let r=0;for(;r0&&n>0;){const o=r+i-1,a=r+n-1;if(t.charCodeAt(o)!==e.charCodeAt(a))break;i--,n--}for(;i>0&&n>0;){const o=r,a=r;if(t.charCodeAt(o)!==e.charCodeAt(a))break;r++,i--,n--}const a=this.pos+r-1,s=a+n;this.start=void 0===this.start?a:Math.min(this.start,a),this.end=void 0===this.end?s:Math.max(this.end,s)}void 0===this.start&&(this.start=this.pos-1,this.end=this.pos)}}popupData(e,t){const i=`${Za(this.pos)}`,n=this.start===this.end?`${Za(this.start)} | ${Za(this.start+1)}`:`${Za(this.start+1)}-${Za(this.end)}`,o=[{name:"Chr",value:this.chr},{name:"Pos",value:i},{name:"Loc",value:n},{name:"ID",value:this.names?this.names:""},{name:"Ref",value:this.referenceBases},{name:"Alt",value:this.alternateBases.replace("<","<")},{name:"Qual",value:this.quality},{name:"Filter",value:this.filter}];if("SNP"===this.type){let e=this.referenceBases;if(1===e.length){let i=this.alternateBases.split(",");for(let n of i)if(1===n.length){let i=Tu.getCravatLink(this.chr,this.pos,e,n,t);i&&(o.push("
"),o.push({html:i}))}}}if(this.hasOwnProperty("heterozygosity")&&o.push({name:"Heterozygosity",value:this.heterozygosity}),this.info){o.push({html:'
'});for(let e of Object.keys(this.info))o.push({name:e,value:Uu(decodeURIComponent(this.info[e]))})}return o}getInfo(e){return this.info?this.info[e]:void 0}isRefBlock(){return"NONVARIANT"===this.type}}const qu=new Set(["A","C","T","G"].map((e=>e.charCodeAt(0))));function Vu(e){for(let t=0;t");if(!(t>2&&a>0)){console.log("Malformed VCF header line: "+n);continue}const s=n.substring(2,t-1);i[s]||(i[s]={});const c=Xa(n.substring(t+1,a-1),",");for(let t of c){var o=t.split("=");o.length>1&&("ID"===o[0]?e=o[1]:r[o[0]]=o[1])}e&&(i[s][e]=r)}else if(n.startsWith("##contig")&&t){const e=n.indexOf("",e));const r=n.substring(e+4,o),a=t.getChromosomeName(r);i.chrAliasTable.set(a,r)}}else if(n.startsWith("#CHROM")){const e=n.split("\t");if(e.length>8){i.callSets=[];for(let t=9;t9){const t=Wu(e[8].split(":"));n.calls={};for(let o=9;o0?n=e:n?(o.push(n+e),n=void 0):o.push(e));for(let e of o){if(!e)return;var r=e.split("=",2);if(2===r.length){const e=r[0].trim(),i=r[1].trim();t[e]=i}}return t}function tp(e){let t={},i=e.split(/\s+/);if(2===i.length){i[1].split(";").forEach((function(e){let i=e.split("=");"color"===i[0]?t.colorColumn=Number.parseInt(i[1])-1:"thickness"===i[0]&&(t.thicknessColumn=Number.parseInt(i[1])-1)}))}return t}function ip(e,t){var i,n,o=e.columns;this.aed=e,this.allColumns=t,this.chr=null,this.start=null,this.end=null,this.score=1e3,this.strand=".",this.cdStart=null,this.cdEnd=null,this.name=null,this.color=null;for(let e=0;e0)for(let e=0;e=0;i--)t=256*t+e[i];else for(let i=0;i0&&(n+=String.fromCharCode(i));return n}getFixedLengthTrimmedString(e){var t,i,n="";for(t=0;t32&&(n+=String.fromCharCode(i));return n}getFloat(){var e=this.view.getFloat32(this.position,this.littleEndian);return this.position+=4,e}getDouble(){var e=this.view.getFloat64(this.position,this.littleEndian);return this.position+=8,e}skip(e){return this.position+=e,this.position}getVPointer(){var e=this.position,t=this.view.getUint8(e+1)<<8|this.view.getUint8(e),i=4294967296*(255&this.view.getUint8(e+6))+16777216*(255&this.view.getUint8(e+5))+65536*(255&this.view.getUint8(e+4))+256*(255&this.view.getUint8(e+3))+(255&this.view.getUint8(e+2));return this.position+=8,new rp(i,t)}}class rp{constructor(e,t){this.block=e,this.offset=t}isLessThan(e){return this.blocke.block||this.block===e.block&&this.offset>e.offset}isEqualTo(e){return this.block===e.block&&this.offset===e.offset}print(){return this.block+":"+this.offset}}function ap(e,t){if(0===e.length)return e;if(e.sort((function(e,t){const i=e.minv.block-t.minv.block;return 0!==i?i:e.minv.offset-t.minv.offset})),e.length<=1)return e;t&&(e=e.filter((e=>e.maxv.isGreaterThan(t))));const i=[];let n;for(let t of e)n&&sp(n,t)?t.maxv.isGreaterThan(n.maxv)&&(n.maxv=t.maxv):(i.push(t),n=t);return i}function sp(e,t){t.minv.block,e.maxv.block;return e.maxv.block-e.minv.block<5e6}class cp{constructor(e){this.tabix=!0}parse(e,t){const i=new op(new DataView(e)),n=i.getInt();if(21582659!==n)throw 38359875===n?Error("CSI version 2 is not supported. Please enter an issue at https://github.com/igvteam/igv.js"):Error("Not a CSI index");this.indices=[],this.blockMin=Number.MAX_SAFE_INTEGER,this.lastBlockPosition=[],this.sequenceIndexMap={},this.minShift=i.getInt(),this.depth=i.getInt();const o=[];let r=0;if(i.getInt()>=28){i.getInt(),i.getInt(),i.getInt(),i.getInt(),i.getInt(),i.getInt();const e=i.getInt(),n=i.position+e;let r=0;for(;i.positiona)i.getInt(),i.getVPointer(),i.getVPointer(),i.getLong(),i.getLong();else{t[e]=[];const n=i.getInt();for(let o=0;or&&(r=o.block),t[e].push([n,o]))}}}o>0&&(this.indices[e]={binIndex:t,loffset:n})}this.lastBlockPosition=r}get chromosomeNames(){return Object.keys(this.sequenceIndexMap)}chunksForRange(e,t,i){const n=this.indices[e];if(n){const e=this.reg2bins(t,i);if(0==e.length)return[];const o=[];for(let t of e)for(let e=t[0];e<=t[1];e++)if(n.binIndex[e]){const t=n.binIndex[e];for(let i of t){const t=i[0],n=i[1];o.push({minv:t,maxv:n,bin:e})}}return ap(o,n.loffset[e[0]])}return[]}reg2bins(e,t){(e-=1)<1&&(e=1),t>2**34&&(t=2**34),t-=1;let i=0,n=0,o=this.minShift+3*this.depth;const r=[];for(;i<=this.depth;o-=3,n+=1<<3*i,i+=1){const i=n+(e>>o),a=n+(t>>o);r.push([i,a])}return r}bin_limit(){return((1<<3*(this.depth+1))-1)/7}}class lp{constructor(){}async parse(e,t,i){const n=[];let o=Number.MAX_SAFE_INTEGER,r=0;const a=new op(new DataView(e)),s=a.getInt(),c={};if(!(21578050===s||t&&21578324===s))throw new Error(indexURL+" is not a "+(t?"tabix":"bai")+" file");{const e=a.getInt();if(t){a.getInt(),a.getInt(),a.getInt(),a.getInt(),a.getInt(),a.getInt(),a.getInt();for(let t=0;tr&&(r=n.block),e[t].push([i,n]))}}}const c=a.getInt();for(let e=0;e0&&(n[t]={binIndex:e,linearIndex:i})}this.firstBlockPosition=o,this.lastBlockPosition=r,this.indices=n,this.sequenceIndexMap=c,this.tabix=t}}get chromosomeNames(){return Object.keys(this.sequenceIndexMap)}chunksForRange(e,t,i){const n=this.indices[e];if(n){const e=function(e,t){const i=[];t>=1<<29&&(t=1<<29);return--t,i.push([0,0]),i.push([1+(e>>26),1+(t>>26)]),i.push([9+(e>>23),9+(t>>23)]),i.push([73+(e>>20),73+(t>>20)]),i.push([585+(e>>17),585+(t>>17)]),i.push([4681+(e>>14),4681+(t>>14)]),i}(t,i),o=[];for(let t of e)for(let e=t[0];e<=t[1];e++)if(n.binIndex[e]){const t=n.binIndex[e];for(let e of t){const t=e[0],i=e[1];o.push({minv:t,maxv:i})}}const r=n.linearIndex.length;let a;const s=Math.min(t>>14,r-1),c=Math.min(i>>14,r-1);for(let e=s;e<=c;e++){const t=n.linearIndex[e];if(t){a=t;break}}return ap(o,a)}return[]}}class hp{constructor(){}async parse(e,t){let i=0;this.chrIndex={},this.lastBlockPosition=[];const n=new op(new DataView(e));!function(e){e.getInt(),e.getInt();const t=e.getInt();if(e.getString(),e.getLong(),e.getLong(),e.getString(),e.getInt(),t>=3){let t=e.getInt();for(;t-- >0;)e.getString(),e.getString()}}(n);let o=n.getInt();for(;o-- >0;){let e=n.getString();t&&(e=t.getChromosomeName(e));const o=n.getInt(),r=n.getInt(),a=n.getInt();n.getInt(),n.getInt();let s=n.getLong();const c=[];for(let e=0;ei&&(i=e)}this.chrIndex[e]={chr:e,blocks:c,longestFeature:a,binWidth:o}}this.lastBlockPosition=i}get chromosomeNames(){return Object.keys(this.chrIndex)}chunksForRange(e,t,i){const n=this.chrIndex[e];if(n){const e=n.blocks,o=n.longestFeature,r=n.binWidth,a=Math.max(t-o,0),s=Math.floor(a/r);if(s>=e.length)return[];{const t=Math.min(Math.floor((i-1)/r),e.length-1),n=e[s].min,o=e[t].max;if(0===o-n)return[];return[{minv:{block:n,offset:0},maxv:{block:o,offset:0}}]}}}}async function dp(e,t,i){let n=await ad.loadArrayBuffer(e,zd(t)),o=new DataView(n);if(31===o.getUint8(0)&&139===o.getUint8(1)){n=zh(n).buffer,o=new DataView(n)}switch(o.getInt32(0,!0)){case 21578050:return async function(e,t){const i=new lp;return await i.parse(e,!1,t),i}(n,i);case 21578324:return async function(e,t){const i=new lp;return await i.parse(e,!0,t),i}(n,i);case 21582659:return async function(e,t){const i=new cp;return i.parse(e,t),i}(n,i);case 1480870228:return async function(e,t){const i=new hp;return i.parse(e,t),i}(n,i);case 38359875:throw Error("CSI version 2 is not supported.");default:throw Error(`Unrecognized index type: ${e}`)}}function fp(e){return"string"==typeof e||e instanceof String?new up(e):new pp(e)}class up{constructor(e){this.data=e,this.ptr=0}nextLine(){var e=this.ptr,t=this.data.indexOf("\n",e),i=this.data;if(t>0)return this.ptr=t+1,t>e&&"\r"===i.charAt(t-1)?i.substring(e,t-1):i.substring(e,t);var n=i.length;return this.ptr=n,e>=n?void 0:i.substring(e)}}class pp{constructor(e){this.data=e,this.length=this.data.length,this.ptr=0}nextLine(){var e,t;if(t="",!(this.ptr>=this.length)){for(var i=this.ptr;i{const t=ArrayBuffer.isView(e)?e:new Uint8Array(e);return 1+(t[17]<<8|t[16])};class wp{constructor(e){this.config=e,this.cacheBlocks=0!=e.cacheBlocks,this.cache=void 0}async getData(e,t){const i=e.block,n=t.block,o=0===t.offset,r=await this.getInflatedBlocks(i,n,o);if(1===r.length)return r[0];let a=0;for(const e of r)a+=e.byteLength;const s=new Uint8Array(a);let c=0;for(const e of r)s.set(e,c),c+=e.byteLength;return s}async getInflatedBlocks(e,t,i){if(this.cacheBlocks){const n=this.cache;if(n&&n.startBlock<=e&&(n.endBlock>=t||i&&n.nextEndBlock===t)){const i=e-n.startBlock,o=t-n.startBlock;return bp(n.buffer,i,o)}{let o;if(!n||n.startBlock>t||n.endBlock=n.endBlock)a=n.buffer;else{const i=Math.max(0,e-n.startBlock);let o;if(t>=n.endBlock)o=n.buffer.byteLength;else{const e=Fp(n.buffer);for(let i=0;in.endBlock){const e=await this.loadBLockData(n.endBlock,t,{skipStart:!0,skipEnd:i});r.push(e)}o=function(e){if(1===e.length)return e[0];let t=0;for(const i of e)t+=i.byteLength;const i=new Uint8Array(t);let n=0;for(const t of e)i.set(new Uint8Array(t),n),n+=t.byteLength;return i.buffer}(r)}let r=t;if(i){const e=Fp(o);t=e[e.length-1]}return this.cache={startBlock:e,endBlock:t,nextEndBlock:r,buffer:o},bp(o)}}return bp(await this.loadBLockData(e,t,{skipEnd:i}))}async loadBLockData(e,t,i){const n=this.config,o=i&&i.skipStart;let r=0;if(!(i&&i.skipEnd)){const e=zd(n,{range:{start:t,size:26}}),i=await ad.loadArrayBuffer(n.url,e);r=gp(i)}if(o){const t=zd(n,{range:{start:e,size:26}}),i=await ad.loadArrayBuffer(n.url,t);e+=gp(i)}const a=zd(n,{range:{start:e,size:t+r-e}});return ad.loadArrayBuffer(n.url,a)}}function Fp(e){const t=e.byteLength;let i=0;const n=[0];for(;ie.blocks)).map((e=>e.max)).reduce(((e,t)=>Math.min(e,t)),Number.MAX_SAFE_INTEGER),n=zd(this.config,{bgz:e.tabix,range:{start:0,size:i}});t=fp(await ad.loadString(this.config.url,n))}return this.header=await this.parser.parseHeader(t),this.header}{const e=zd(this.config),t=await ad.loadString(this.config.url,e);let i=fp(t);return this.header=await this.parser.parseHeader(i),i=fp(t),this.features=await this.parser.parseFeatures(i),this.header}}getParser(e){switch(e.format){case"vcf":return new ju(e);case"seg":return new Bu("seg");case"mut":return new Bu("mut");case"maf":return new Bu("maf");case"gwas":return new $u(e);case"aed":return new Yu(e);default:return new Iu(e)}}async loadFeaturesNoIndex(){if(this.features){const e=this.features;return delete this.features,e}{const e=zd(this.config),t=await ad.loadString(this.config.url,e);if(!this.header){const e=fp(t);this.header=await this.parser.parseHeader(e)}const i=fp(t);return await this.parser.parseFeatures(i)}}async loadFeaturesWithIndex(e,t,i){this.dataURI||this.header||await this.readHeader();const n=this.config,o=this.parser,r=this.index.tabix,a=r?this.index.sequenceIndexMap[e]:e;if(void 0===a)return[];const s=this.genome,c=this.index.chunksForRange(a,t,i);if(c&&0!==c.length){const a=[];for(let l of c){let c;if(r)c=await this._blockLoader.getData(l.minv,l.maxv);else{const e=zd(n,{range:{start:l.minv.block,size:l.maxv.block-l.minv.block+1}});c=await ad.loadString(n.url,e)}const h=fp(l.minv.offset?c.slice(l.minv.offset):c);let d=await o.parseFeatures(h);d=d.filter((e=>void 0===e._f));let f=!1;for(let n=0;ni){a.push(o);break}o.end>=t&&o.start<=i&&(f||(f=!0,n>0&&a.push(d[n-1])),a.push(o))}}return a.sort((function(e,t){return e.start-t.start})),a}return[]}async getIndex(){return this.index?this.index:this.config.indexURL?(this.index=await this.loadIndex(),this.index):void 0}async loadIndex(){return dp(this.config.indexURL,this.config,this.genome)}async loadFeaturesFromDataURI(){if(this.features){const e=this.features;return delete this.features,e}{const e=Rh(this.dataURI);let t=fp(e);return this.header=await this.parser.parseHeader(t),this.header instanceof String&&this.header.startsWith("##gff-version 3")&&(this.format="gff3"),t=fp(e),this.features=await this.parser.parseFeatures(t),this.features}}}const yp=$a;class _p{constructor(e){this.config=e}async readFeatures(e,t,i){let n;n="function"==typeof this.config.url?this.config.url({chr:e,start:t,end:i}):this.config.url.replace("$CHR",e).replace("$START",t).replace("$END",i);let o,r=Object.assign({},this.config);void 0!==this.config.body&&("function"==typeof this.config.body?r.body=this.config.body({chr:e,start:t,end:i}):r.body=this.config.body.replace("$CHR",e).replace("$START",t).replace("$END",i));const a=await ad.load(n,r);if(a&&(o="function"==typeof this.config.parser?this.config.parser(a):yp(a)?JSON.parse(a):a),this.config.mappings){let e=Object.keys(this.config.mappings);for(let t of o)for(let i of e)t[i]=t[this.config.mappings[i]]}return o}}const Cp=function(e,t){this.config=e,this.genome=t,this.expandQueryInterval=!1};Cp.prototype.readFeatures=function(e,t,i){const n=Math.max(0,Math.floor(t));let o=Math.ceil(i);if(this.genome){const t=this.genome.getChromosome(e);t&&o>t.bpLength&&(o=t.bpLength)}const r=this.config.url+"?db="+this.config.db+"&table="+this.config.tableName+"&chr="+e+"&start="+n+"&end="+o;return ad.loadJson(r,this.config).then((function(e){return e?(e.forEach((function(e){e.hasOwnProperty("exonStarts")&&e.hasOwnProperty("exonEnds")&&e.hasOwnProperty("exonCount")&&e.hasOwnProperty("cdsStart")&&e.hasOwnProperty("cdsEnd")&&function(e){var t,i,n,o,r,a;t=e.exonCount,i=e.exonStarts.split(","),n=e.exonEnds.split(","),o=[];for(var s=0;sa||e.cdsEnd=r&&e.cdsStart<=a&&(c.cdStart=e.cdsStart),e.cdsEnd>=r&&e.cdsEnd<=a&&(c.cdEnd=e.cdsEnd),o.push(c)}e.exons=o}(e)})),e):null}))};const xp=["Name","gene_name","gene","gene_id","alias","locus","name"];class kp{constructor(e){this.format=e.format,this.nameField=e.nameField,this.filterTypes=void 0===e.filterTypes?new Set(["chromosome"]):new Set(e.filterTypes)}combineFeatures(e,t){let i;const n=this.filterTypes;if(e=e.filter((e=>void 0===n||!n.has(e.type))),"gff3"===this.format){const t=this.combineFeaturesById(e);i=this.combineFeaturesByType(t)}else i=this.combineFeaturesByType(e);return i.sort((function(e,t){return e.start-t.start})),this.numberExons(i,t),this.nameFeatures(i),i}combineFeaturesById(e){const t=new Map,i=[];for(let n of e)if(Jf(n.type)||Qf(n.type)||!n.id)i.push(n);else{let e=t.get(n.chr);e||(e=new Map,t.set(n.chr,e));let i=e.get(n.id);i?i.push(n):e.set(n.id,[n])}for(let e of t.values())for(let t of e.values())if(t.length>1){const e=t[0];e.exons=[];for(let i of t)e.start=Math.min(e.start,i.start),e.end=Math.max(e.end,i.end),e.exons.push({start:i.start,end:i.end});i.push(e)}else i.push(t[0]);return i}combineFeaturesByType(e){const t=e.filter((e=>"gene"===e.type||e.type.endsWith("_gene"))),i=Object.create(null);for(let e of t)i[e.id]=e;const n=Object.create(null),o=[],r=new Set,a=this.filterTypes;e=e.filter((e=>void 0===a||!a.has(e.type)));for(let t of e)if("biological_region"===t.type&&console.log(),Qf(t.type)){const e=t.id;if(void 0!==e){const a=new iu(t);n[e]=a,o.push(a),r.add(t);const s=i[t.parent];s&&(a.geneObject=s,r.add(s))}}for(let t of e)if(Jf(t.type)){const e=l(t);if(e)for(let i of e){let a=n[i];if(!a&&"gtf"===this.format){const e=Object.assign({},t);e.type="transcript",a=new iu(e),n[i]=a,o.push(a)}if(void 0!==a){if(s=t.type,$f.has(s))if(e.length>1){const e=new tu(t);a.addExon(e)}else a.addExon(t);else a.addPart(t);r.add(t)}}}var s;o.forEach((function(e){"function"==typeof e.finish&&e.finish()}));const c=e.filter((e=>!r.has(e)));for(let e of c)o.push(e);return o;function l(e){return e.parent&&""!==e.parent.trim()?e.parent.trim().split(","):null}}numberExons(e,t){for(let i of e)if(i.exons&&(!t||i.end<=t.end&&i.start>t.start))for(let e=0;e0){const e=1===this.variant_types.length?"Type":"Types";let i;for(let e of this.variant_types)i?i+=", "+e.display_name:i=e.display_name;t.push({name:e,value:i})}return t.push({name:"Actionability",value:this.actionabilityScore}),t.push({name:"Location",value:this.locationString}),t;function i(e,t){return""+e+""}}}class Tp{constructor(e,t){if(this.config=e,this.genome=t,this.format=e.format?e.format.toUpperCase():"BAM","BAM"!==this.format&&"VCF"!==this.format)throw Error(`htsget format ${e.format} is not supported`)}async readHeaderData(){const e=`${Rp(this.config)}?class=header&format=${this.format}`,t=await ad.loadJson(e,zd(this.config));return await this.loadUrls(t.htsget.urls)}async readData(e,t,i){const n=`${Rp(this.config)}?format=${this.format}&referenceName=${e}&start=${Math.floor(t)}&end=${Math.ceil(i)}`,o=await ad.loadJson(n,zd(this.config));return this.loadUrls(o.htsget.urls)}async loadUrls(e){const t=[];for(let i of e)if(i.url.startsWith("data:"))t.push(Promise.resolve(Lp(i.url)));else{const e=zd(this.config||{});i.headers&&(e.headers=Object.assign(e.headers||{},i.headers)),t.push(ad.loadArrayBuffer(i.url,e))}return function(e){let t=0;for(let i of e)t+=i.byteLength;let i=0;const n=new Uint8Array(t);for(let t of e){const e=new Uint8Array(t);n.set(e,i),i+=e.length}return n}(await Promise.all(t))}static async inferFormat(e){try{const t=Rp(e),i=`${t}${t.includes("?")?"&":"?"}class=header`,n=await ad.loadJson(i,zd(e));if(n.htsget){const t=n.htsget.format;if("BAM"!==t&&"VCF"!==t)throw Error(`htsget format ${t} is not supported`);e.format=t.toLowerCase(),e.sourceType="htsget",e.name||(e.name=await Md(e.url))}}catch(e){}}}function Rp(e){if(e.url&&e.endpoint&&e.id)return e.url+e.endpoint+e.id;if(e.endpoint&&e.id)return e.endpoint+e.id;if(e.url)return e.url.startsWith("htsget://")?e.url.replace("htsget://","https://"):e.url;throw Error("Must specify either 'url', or 'endpoint' and 'id")}function Lp(e){const t=e.split(","),i=t[0].split(":")[1];let n=t[1];n=i.indexOf("base64")>=0?atob(n):decodeURI(n);const o=new Uint8Array(n.length);for(var r=0;r=i[e]){n.row=e,i[e]=n.end;break}n.row=e,i[e]=n.end}}function Op(e,t,i){const n=i||1e4,o=e=>{const i=Object.assign({},e);return i.chr="all",i.start=t.getGenomeCoordinate(e.chr,e.start),i.end=t.getGenomeCoordinate(e.chr,e.end),i._f=e,i.exons&&delete i.exons,i},r=new Set(t.wgChromosomeNames),a=[];let s=0;for(let i of t.wgChromosomeNames){if(Array.isArray(e)){const i={};for(let n of e){const e=t.getChromosomeName(n.chr);i.hasOwnProperty(e)||(i[e]=[]),i[e].push(n)}e=i}const c=e[i];if(c)for(let e of c){let i=t.getChromosomeName(e.chr);if(r.has(i))if(a.lengthi-t&&!1!==this.config.expandQuery){const e=Math.min(4.1*(i-t),n);r=Math.max(0,(t+i)/2-e),a=t+e}let s=await o.readFeatures(e,r,a);void 0===this.queryable&&(this.queryable=o.indexed);const c=this.queryable?new af(e,r,a):void 0;if(s){if(!1===this.config.assembleGFF||"gtf"!==this.config.format&&"gff3"!==this.config.format&&"gff"!==this.config.format||(s=new kp(this.config).combineFeatures(s,c)),"wig"!==this.config.format&&"junctions"!==this.config.type){Pp(s,this.config.maxRows||Number.MAX_SAFE_INTEGER)}this.featureCache=new md(s,this.genome,c),this.searchable&&this.genome.addFeaturesToDB(s,this.config)}else this.featureCache=new md([],c)}}class Vp{constructor(e,t,i){this.path=e.url,this.bufferSize=i||512e3,this.range={start:-1,size:-1},this.config=e}async dataViewForRange(e,t,i=0){try{if(!(this.data&&this.range.start<=e.start&&this.range.start+this.range.size>=e.start+e.size)){let t;t=e.size?Math.max(this.bufferSize,e.size):this.bufferSize,this.contentLength&&(t=Math.min(t,this.contentLength-e.start));const i={start:e.start,size:t},n=await ad.loadArrayBuffer(this.path,zd(this.config,{range:i}));this.data=n,this.range=i}const i=this.data.byteLength,n=e.start-this.range.start;return t?new Uint8Array(this.data,n,i-n):new DataView(this.data,n,i-n)}catch(n){if(0===i&&n.message&&n.message.startsWith("416")){try{return this.contentLength=await ad.getContentLength(this.path,zd(this.config)),this.dataViewForRange(e,t,++i)}catch(e){console.error(e)}throw n}}}}let Up=512e3;class jp{constructor(e,t){this.path=e.url,this.format=e.format||"bigwig",this.genome=t,this.rpTreeCache={},this.config=e,this.loader=Rd(this.path)?new tm(this.path):ad}async readWGFeatures(e,t){await this.loadHeader();const i=this.chromTree.idToChrom.length-1,n=this.chromTree.idToChrom[0],o=this.chromTree.idToChrom[i];return this.readFeatures(n,0,o,Number.MAX_VALUE,e,t)}async readFeatures(e,t,i,n,o,r){await this.loadHeader();const a=this.chromTree.chromToID[e],s=this.chromTree.chromToID[i];if(void 0===a||void 0===s)return[];let c,l;if("bigwig"===this.type){const e=await this.getZoomHeaders();let t=o?function(e,t){let i;for(let n=0;n0?kh(o):o,l.call(this,new DataView(d.buffer),a,t,s,n,h,this.chromTree.idToChrom,r)}return h.sort((function(e,t){return e.start-t.start})),h}return[]}async getZoomHeaders(){return this.zoomLevelHeaders||await this.loadHeader(),this.zoomLevelHeaders}async loadHeader(){if(this.header)return this.header;{let e,t=await this.loader.loadArrayBuffer(this.path,zd(this.config,{range:{start:0,size:64}}));this.littleEndian=!0;let i=new op(new DataView(t)),n=i.getUInt();if(2291137574===n)this.type="bigwig";else if(2273964779===n)this.type="bigbed";else{this.littleEndian=!1,i.littleEndian=!1,i.position=0;let e=i.getUInt();654085990===e?this.type="bigwig":3958540679===e&&(this.type="bigbed")}e={bwVersion:i.getUShort(),nZoomLevels:i.getUShort(),chromTreeOffset:i.getLong(),fullDataOffset:i.getLong(),fullIndexOffset:i.getLong(),fieldCount:i.getUShort(),definedFieldCount:i.getUShort(),autoSqlOffset:i.getLong(),totalSummaryOffset:i.getLong(),uncompressBuffSize:i.getInt(),extensionOffset:i.getLong()};const o=64;let r={start:o,size:e.fullDataOffset-o+5};t=await this.loader.loadArrayBuffer(this.path,zd(this.config,{range:r}));const a=e.nZoomLevels;i=new op(new DataView(t)),this.zoomLevelHeaders=[],this.firstZoomDataOffset=Number.MAX_SAFE_INTEGER;for(let e=1;e<=a;e++){const t=a-e,n=new Wp(t,i);this.firstZoomDataOffset=Math.min(n.dataOffset,this.firstZoomDataOffset),this.zoomLevelHeaders[t]=n}if(e.autoSqlOffset>0){i.position=e.autoSqlOffset-o;const t=i.getString();t&&(this.autoSql=function(e){let t;const i=[];let n=!1;const o=e.trim().split(/\s*[\r\n]+\s*/g);for(let e of o)if(e.startsWith("table"))t=e.split(/\s+/)[1].trim();else if(e.startsWith("("))n=!0;else if(e.startsWith(")"));else if(n&&e.length>0){const t=e.indexOf(";"),n=e.substr(0,t).split(/\s+/),o=e.substr(t+1).replace(/"/g,"").trim();i.push({type:n[0],name:n[1],description:o})}return{table:t,fields:i}}(t))}if(e.totalSummaryOffset>0&&(i.position=e.totalSummaryOffset-o,this.totalSummary=new Xp(i)),!(e.chromTreeOffset>0))throw"BigWig chromosome tree offset <= 0";return i.position=e.chromTreeOffset-o,this.chromTree=new Zp(i,o,this.genome),i.position=e.fullDataOffset-o,e.dataCount=i.getInt(),this.setDefaultVisibilityWindow(e),this.header=e,this.header}}async loadRPTree(e){let t=this.rpTreeCache[e];return t||(t=new Gp(e,this.config,this.littleEndian,this.loader),await t.load(),this.rpTreeCache[e]=t,t)}async getType(){return await this.loadHeader(),this.type}async getTrackType(){return await this.loadHeader(),"bigwig"===this.type?"wig":this.autoSql&&"chromatinInteract"===this.autoSql.table?"interact":"annotation"}setDefaultVisibilityWindow(e){if("bigwig"===this.type)this.visibilityWindow=-1;else{let t=this.genome?this.genome.getGenomeLength():3088286401;this.visibilityWindow=e.dataCount<1e3?-1:t/e.dataCount*1e3}}}class Wp{constructor(e,t){this.index=e,this.reductionLevel=t.getInt(),this.reserved=t.getInt(),this.dataOffset=t.getLong(),this.indexOffset=t.getLong()}}class Gp{constructor(e,t,i,n){this.config=t,this.loader=n,this.fileOffset=e,this.path=t.url,this.littleEndian=i}async load(){const e=this.fileOffset+48,t=Rd(this.path)?this.loader:new Vp(this.config,Up);return this.rootNode=await this.readNode(e,t),this}async readNode(e,t){let i=await t.dataViewForRange({start:e,size:4},!1),n=new op(i,this.littleEndian);const o=1===n.getByte();n.getByte();const r=n.getUShort();let a={start:e+=4,size:r*(o?32:24)};i=await t.dataViewForRange(a,!1);const s=new Array(r);if(n=new op(i),o){for(let e=0;e=0&&(n.position=o);let a=n.getByte();n.getByte();let s,c,d,f,u,p,m=n.getUShort();if(1===a)for(s=0;se.startChrom||n===e.startChrom&&o>=e.startBase)&&(t0){this.mean=this.sumData/e,this.stddev=Math.sqrt(this.sumSquares/(e-1));let t=this.minVal<0?this.mean-2*this.stddev:0,i=this.maxVal>0?this.mean+2*this.stddev:0;this.defaultRange={min:t,max:i}}}function Qp(e,t,i,n,o,r,a){const s=new op(e),c=s.getInt(),l=s.getInt();let h=l,d=s.getInt();const f=s.getInt(),u=s.getInt(),p=s.getByte();s.getByte();let m=s.getUShort();if(c>=t&&c<=n){let e=0;for(;m-- >0;){let m;switch(p){case 1:h=s.getInt(),d=s.getInt(),m=s.getFloat();break;case 2:h=s.getInt(),m=s.getFloat(),d=h+u;break;case 3:m=s.getFloat(),h=l+e*f,d=h+u,e++}if(!(cn||c===n&&h>=o)break;if(Number.isFinite(m)){const e=a[c];r.push({chr:e,start:h,end:d,value:m})}}}}}function Jp(){const e=function(e,t,i,n){if("biginteract"===n||i&&"chromatinInteract"===i.table||"interact"===i.table)return function(e,t){return e.chr1=t[5],e.start1=Number.parseInt(t[6]),e.end1=Number.parseInt(t[7]),e.chr2=t[10],e.start2=Number.parseInt(t[11]),e.end2=Number.parseInt(t[12]),e.name=t[0],e.score=Number(t[1]),e.value=Number(t[2]),e.color="."===t[4]?void 0:"0"===t[4]?"rgb(0,0,0)":t[4],e};{const n=e-3;return function(o,r){if(n>0&&(o.name=r[0]),n>1&&(o.score=Number(r[1])),n>2&&(o.strand=r[2]),n>3&&(o.cdStart=parseInt(r[3])),n>4&&(o.cdEnd=parseInt(r[4])),n>5&&"."!==r[5]&&"0"!==r[5]&&"-1"!==r[5]){const e=qh.createColorString(r[5]);o.color=e.startsWith("rgb")?e:void 0}if(n>8){const e=parseInt(r[6]),t=r[7].split(","),i=r[8].split(","),n=[];for(let r=0;ri?n.utr=!0:(t>=o&&t<=e&&(n.cdStart=t),i>=o&&i<=e&&(n.cdEnd=i))}}(n,o.cdStart,o.cdEnd),o.exons=n}if(i)for(let n=e;n=13;){const t=c.getInt(),l=s[t],h=c.getInt(),d=c.getInt(),f=c.getString();if(!(to||t===o&&h>=r)break;if(d>0){const t={chr:l,start:h,end:d};a.push(t);const i=f.split("\t");e(t,i)}}}}}function em(e,t,i,n,o,r,a,s){const c=new op(e);for(;c.remLength()>=32;){const e=c.getInt(),l=a[e],h=c.getInt(),d=c.getInt(),f=c.getInt(),u=c.getFloat(),p=c.getFloat(),m=c.getFloat();let g;switch(c.getFloat(),s){case"min":g=u;break;case"max":g=p;break;default:g=0===f?0:m/f}if(!(en||e===n&&h>=o)break;Number.isFinite(g)&&r.push({chr:l,start:h,end:d,value:g})}}}class tm{constructor(e){this.data=Rh(e).buffer}loadArrayBuffer(e,t){const i=t.range;return i?this.data.slice(i.start,i.start+i.size):this.data}async dataViewForRange(e,t){const i=Math.min(this.data.byteLength-e.start,e.size);return t?new Uint8Array(this.data,e.start,i):new DataView(this.data,e.start,i)}}class im{constructor(e,t){this.reader=new jp(e,t),this.genome=t,this.format=e.format||"bigwig",this.wgValues={},this.queryable=!0}async getFeatures({chr:e,start:t,end:i,bpPerPixel:n,windowFunction:o}){const r="bigwig"===this.reader.type,a="all"===e.toLowerCase()?r?await this.getWGValues(o):[]:await this.reader.readFeatures(e,t,e,i,n,o);return r||Hp(a),a}async getHeader(){return this.reader.loadHeader()}getDefaultRange(){return void 0!==this.reader.totalSummary?this.reader.totalSummary.defaultRange:void 0}async defaultVisibilityWindow(){return this.reader.defaultVisibilityWindow}async getWGValues(e){const t=this.genome;if(this.wgValues[e])return this.wgValues[e];{const i=t.getGenomeLength()/1e3,n=await this.reader.readWGFeatures(i,e);let o=[];for(let e of n){const i=e.chr,n=t.getCumulativeOffset(i),r=Object.assign({},e);r.chr="all",r.start=n+e.start,r.end=n+e.end,o.push(r)}return this.wgValues[e]=o,o}}supportsWholeGenome(){return"bigwig"===this.reader.type}async trackType(){return this.reader.getTrackType()}}class nm{constructor(e,t){this.config=e,this.genome=t,this.path=e.url,this.groupCache={},this.datasetCache={}}async readHeader(){if(void 0!==this.magic)return this;let e=await ad.loadArrayBuffer(this.path,zd(this.config,{range:{start:0,size:64e3}})),t=new op(new DataView(e));if(this.magic=t.getInt(),this.version=t.getInt(),this.indexPos=t.getLong(),this.indexSize=t.getInt(),t.getInt(),this.version>=2){let e=t.getInt();for(this.windowFunctions=[];e-- >0;)this.windowFunctions.push(t.getString())}this.trackType=t.getString(),this.trackLine=t.getString();let i=t.getInt();for(this.trackNames=[];i-- >0;)this.trackNames.push(t.getString());this.genomeID=t.getString(),this.flags=t.getInt(),this.compressed=!!(1&this.flags),e=await ad.loadArrayBuffer(this.path,zd(this.config,{range:{start:this.indexPos,size:this.indexSize}})),t=new op(new DataView(e)),this.datasetIndex={};let n=t.getInt();for(;n-- >0;){const e=t.getString(),i=t.getLong(),n=t.getInt();this.datasetIndex[e]={position:i,size:n}}for(this.groupIndex={},n=t.getInt();n-- >0;){const e=t.getString(),i=t.getLong(),n=t.getInt();this.groupIndex[e]={position:i,size:n}}return this}async readDataset(e,t,i){const n=e+"_"+t+"_"+i;if(this.datasetCache[n])return this.datasetCache[n];{await this.readHeader();const o=this.version<2?"":"/"+t,r="all"===e.toLowerCase()||void 0===i?"0":i.toString();let a;a="raw"===t?"/"+e+"/raw":"/"+e+"/z"+r+o;const s=this.datasetIndex[a];if(void 0===s)return;const c=await ad.loadArrayBuffer(this.path,zd(this.config,{range:{start:s.position,size:s.size}}));if(!c)return;const l=new op(new DataView(c));let h=l.getInt();const d={};for(;h-- >0;)d[l.getString()]=l.getString();const f=l.getString(),u=l.getFloat();let p=l.getInt();const m=[];for(;p-- >0;)m.push({position:l.getLong(),size:l.getInt()});const g={name:a,attributes:d,dataType:f,tileWidth:u,tiles:m};return this.datasetCache[n]=g,g}}async readRootGroup(){const e=this.genome,t=this.groupCache["/"];if(t)return t;{const t=await this.readGroup("/"),i=t.chromosomes,n=t.maxZoom;n&&(this.maxZoom=Number(n));const o=t.totalCount;o&&(t.totalCount=Number(o));const r={};return i&&i.split(",").forEach((function(t){const i=e.getChromosomeName(t);r[i]=t})),this.chrAliasTable=r,this.groupCache["/"]=t,t}}async readGroup(e){const t=this.groupCache[e];if(t)return t;{await this.readHeader();const t=this.groupIndex[e];if(void 0===t)return;const i=await ad.loadArrayBuffer(this.path,zd(this.config,{range:{start:t.position,size:t.size}}));if(!i)return;const n=new op(new DataView(i)),o={name:e};let r=n.getInt();for(;r-- >0;){const e=n.getString(),t=n.getString();o[e]=t}return this.groupCache[e]=o,o}}async readTiles(e,t){if(e.sort((function(e,t){return e.position-t.position})),0===(e=e.filter((function(e){return e.size>0}))).length)return Promise.resolve([]);const i=e[0],n=e[e.length-1],o=i.position,r=n.position+n.size-o,a=await ad.loadArrayBuffer(this.path,zd(this.config,{range:{start:o,size:r}})),s=[];for(let i of e){const e=i.position-o,n=i.size;if(n>0){let i;if(this.compressed){i=kh(a.slice(e,e+n)).buffer}else i=a.slice(e,e+n);const o=new op(new DataView(i)),r=o.getString();let c;switch(r){case"fixedStep":c=om(o,t);break;case"variableStep":c=rm(o,t);break;case"bed":case"bedWithName":c=am(o,t,r);break;default:throw"Unknown tile type: "+r}s.push(c)}}return s}async readTile(e,t){let i=await ad.loadArrayBuffer(this.path,zd(this.config,{range:{start:e.position,size:e.size}}));if(this.compressed){i=kh(i).buffer}const n=new op(new DataView(i)),o=n.getString();switch(o){case"fixedStep":return om(n,t);case"variableStep":return rm(n,t);case"bed":case"bedWithName":return am(n,t,o);default:throw"Unknown tile type: "+o}}}function om(e,t){const i=e.getInt(),n=e.getInt(),o=e.getFloat(),r=[];let a=t;for(;a-- >0;){let t=i;const n=[];for(;t-- >0;)n.push(e.getFloat());r.push(n)}return{type:"fixedStep",start:n,span:o,data:r,nTracks:t,nPositions:i}}function rm(e,t){const i=e.getInt(),n=e.getFloat(),o=e.getInt(),r=[];let a=o;for(;a-- >0;)r.push(e.getInt());e.getInt();const s=[];let c=t;for(;c-- >0;){a=o;const t=[];for(;a-- >0;)t.push(e.getFloat());s.push(t)}return{type:"variableStep",tileStart:i,span:n,start:r,data:s,nTracks:t,nPositions:o}}function am(e,t,i){const n=e.getInt();let o=n;const r=[];for(;o-- >0;)r.push(e.getInt());o=n;const a=[];for(;o-- >0;)a.push(e.getInt());e.getInt();const s=[];let c=t;for(;c-- >0;){let t=n;const i=[];for(;t-- >0;)i.push(e.getFloat());s.push(i)}if("bedWithName"===i){o=n;const t=[];for(;o-- >0;)t.push(e.getString())}return{type:i,start:r,end:a,data:s,nTracks:t,nPositions:n}}class sm{constructor(e,t){this.genome=t,this.windowFunction=e.windowFunction||"mean",this.reader=new nm(e,t),this.queryable=!0}async getFeatures({chr:e,start:t,end:i,bpPerPixel:n}){if("all"===e.toLowerCase()){const e=[],t=this.genome;if(this.genome.wgChromosomeNames)for(let i of t.wgChromosomeNames){const o=t.getChromosome(i).bpLength;n=o/1e3;const r=await this._getFeatures(i,0,o,n);if(r)for(let i of r){const n=Object.assign({},i);n.chr="all",n.start=t.getGenomeCoordinate(i.chr,i.start),n.end=t.getGenomeCoordinate(i.chr,i.end),n._f=i,e.push(n)}}return e}return this._getFeatures(e,t,i,n)}async _getFeatures(e,t,i,n){const o=new af(e,t,i),r=this.genome;if(!this.rootGroup&&(this.rootGroup=await this.reader.readRootGroup(),!this.normalizationFactor)){const e=this.rootGroup.totalCount;e&&(this.normalizationFactor=1e6/e)}o.bpPerPixel=n;const a=function(e,t,i){var n=i.getChromosome(e).bpLength;return Math.ceil(Math.log(Math.max(0,n/(700*t)))/dm)}(e,n,r);let s=this.reader.chrAliasTable[e],c=this.reader.maxZoom;void 0===s&&(s=e),void 0===c&&(c=-1);const l=a>c?"raw":this.windowFunction,h=await this.reader.readDataset(s,l,a);if(null==h)return[];const d=h.tileWidth,f=Math.floor(t/d),u=Math.floor(i/d),p=await this.reader.readTiles(h.tiles.slice(f,u+1),1),m=[];for(let o of p)switch(o.type){case"bed":cm(o,e,t,i,n,m);break;case"variableStep":lm(o,e,t,i,n,m);break;case"fixedStep":hm(o,e,t,i,n,m);break;default:throw"Unknown tile type: "+o.type}return m.sort((function(e,t){return e.start-t.start})),m}get supportsWholeGenome(){return!0}}function cm(e,t,i,n,o,r){const a=e.nPositions,s=e.start,c=e.end,l=e.data[0];for(let e=0;en)break;r.push({chr:t,start:o,end:a,value:l[e]})}}}function lm(e,t,i,n,o,r){const a=e.nPositions,s=e.start,c=e.span,l=e.data[0];for(let e=0;en)break;r.push({chr:t,start:o,end:a,value:l[e]})}}}function hm(e,t,i,n,o,r){const a=e.nPositions;let s=e.start;const c=e.span,l=e.data[0];for(let e=0;en)break;o>=i&&(Number.isNaN(l[e])||r.push({chr:t,start:s,end:o,value:l[e]})),s=o}}var dm=Math.log(2);class fm{constructor(e,t){this.config=e,this.genome=t,this.queryable=!1,this.searchable=!1!==e.searchable,this.updateFeatures(e.features)}updateFeatures(e){Pp(e=function(e,t){if(t)for(let i of e)i.chr=t.getChromosomeName(i.chr);return e}(e,this.genome)),this.config.mappings&&function(e,t){let i=Object.keys(t);e.forEach((function(e){i.forEach((function(i){e[i]=e[t[i]]}))}))}(e,this.config.mappings),this.featureCache=new md(e,this.genome),(this.searchable||this.config.searchableFields)&&this.genome.addFeaturesToDB(e,this.config)}async getFeatures({chr:e,start:t,end:i,bpPerPixel:n,visibilityWindow:o}){const r=this.genome,a=r?r.getChromosomeName(e):e;return"all"===a.toLowerCase()?Op(this.featureCache.getAllFeatures(),this.genome,this.maxWGCount):this.featureCache.queryFeatures(a,t,i)}getAllFeatures(){return this.featureCache.getAllFeatures()}supportsWholeGenome(){return!0}}const um=new Set(["bigwig","bw","bigbed","bb","biginteract","biggenepred","bignarrowpeak"]);function pm(e,t){const i=e.format?e.format.toLowerCase():void 0;return e.features?new fm(e,t):um.has(i)?new im(e,t):"tdf"===i?new sm(e,t):new qp(e,t)}const mm=function(e,t){const{r:i,g:n,b:o}=bd[e];return`rgba(${i},${n},${o},${t})`}("nickel",2/16),gm=mm;class wm{constructor(e,t){if(this.url=e.url,e.name?this.name=e.name:e.url&&Ja(e.url)?this.name=e.url.name:e.url&&$a(e.url)&&!e.url.startsWith("data:")&&(this.name=Qa(e.url)),this.isUserDefined=e.isUserDefined,e.features)this.featureSource=new bm(e.features,t);else{if(e.format)e.format=e.format.toLowerCase();else{const t=Qa(e.url);e.format=Wd(t)}this.featureSource=e.featureSource||pm(e,t)}!0===this.isUserDefined?(this.color=e.color||gm,this.headerColor="rgba(155,185,129)"):(this.color=e.color||mm,this.headerColor="rgb(190,190,190)")}async getFeatures(e,t,i){return this.featureSource.getFeatures({chr:e,start:t,end:i})}async getAllFeatures(){return"function"==typeof this.featureSource.getAllFeatures?await this.featureSource.getAllFeatures():{}}addFeature(e){this.isUserDefined?this.featureSource.addFeature(e):console.error("Attempt to add ROI to non user-defined set")}removeFeature(e){this.isUserDefined?this.featureSource.removeFeature(e):console.error("Attempt to remove ROI from non user-defined set")}toJSON(){if(this.url)return{name:this.name,color:this.color,url:this.url,isUserDefined:this.isUserDefined};{const e=this.featureSource.getAllFeatures(),t=[];for(let i of Object.keys(e))for(let n of e[i])t.push(n);return{name:this.name,color:this.color,features:t,isUserDefined:this.isUserDefined}}}dispose(){for(let e of Object.keys(this))this[e]=void 0}}function Fm(e,t,i,n){let o=Math.round((e-i)/n);let r=Math.round((t-i)/n)-o;return r<3&&(r=3,o-=1),{x:o,width:r}}class bm{constructor(e,t){this.featureMap={},this.genome=t;for(let i of e){const e=t?t.getChromosomeName(i.chr):i.chr;let n=this.featureMap[e];n||(n=[],this.featureMap[e]=n),n.push(i)}for(let e of Object.keys(this.featureMap))this.featureMap[e].sort(((e,t)=>e.start-t.start))}getFeatures({chr:e,start:t,end:i}){if("all"===e.toLowerCase())return Op(this.featureMap,this.genome);{const n=this.featureMap[e];return n?n.filter((e=>e.end>t&&e.starte.start-t.start))}removeFeature({chr:e,start:t,end:i}){if(this.featureMap[e]){const n=`${e}-${t}-${i}`;this.featureMap[e]=this.featureMap[e].filter((e=>n!==`${e.chr}-${e.start}-${e.end}`))}}}class vm{constructor(e,t,i,n){this.rulerViewport=e,this.rulerSweeper=xr.div({class:"igv-ruler-sweeper"}),t.appendChild(this.rulerSweeper),this.browser=i,this.referenceFrame=n,this.isMouseHandlers=void 0,this.addBrowserObserver()}addBrowserObserver(){this.boundObserverHandler=(()=>{this.referenceFrame&&(Rf.isWholeGenomeView(this.referenceFrame.chr)?this.removeMouseHandlers():this.addMouseHandlers())}).bind(this),this.browser.on("locuschange",this.boundObserverHandler)}removeBrowserObserver(){this.browser.off("locuschange",this.boundObserverHandler)}addMouseHandlers(){if(!0===this.isMouseHandlers)return;let e,t,i,n,o,r;this.boundContentMouseDownHandler=function(r){e=!0,t=!0;const{x:a}=xr.translateMouseCoordinates(r,this.rulerViewport.contentDiv);n=i=a,o=1,this.rulerSweeper.style.display="block",this.rulerSweeper.style.backgroundColor=!0===r.shiftKey?gm:"rgba(68, 134, 247, 0.25)",this.rulerSweeper.style.left=`${n}px`,this.rulerSweeper.style.width=`${o}px`}.bind(this),this.rulerViewport.contentDiv.addEventListener("mousedown",this.boundContentMouseDownHandler),this.boundDocumentMouseMoveHandler=function(a){let s;if(e&&t){const{x:e}=xr.translateMouseCoordinates(a,this.rulerViewport.contentDiv);s=Math.max(Math.min(e,this.rulerViewport.contentDiv.clientWidth),0),r=s-i,o=Math.abs(r),this.rulerSweeper.style.width=`${o}px`,r<0&&(n=i+r,this.rulerSweeper.style.left=`${n}px`)}}.bind(this),document.addEventListener("mousemove",this.boundDocumentMouseMoveHandler),this.boundDocumentMouseUpHandler=function(i){let r;if(!0===e&&!0===t&&(e=t=void 0,this.rulerSweeper.style.display="none",o>1)){r={start:Math.floor(this.referenceFrame.calculateEnd(n)),end:Math.floor(this.referenceFrame.calculateEnd(n+o))};!0===i.shiftKey?this.browser.roiManager.updateUserDefinedROISet(Object.assign({chr:this.referenceFrame.chr},r)):(Ad(this.browser.genome.getChromosome(this.referenceFrame.chr).bpLength,r,this.browser.minimumBases()),function(e,t,i){e.start=Math.round(t.start),e.end=Math.round(t.end),e.bpPerPixel=(e.end-e.start)/i}(this.referenceFrame,r,this.rulerViewport.contentDiv.clientWidth),this.browser.updateViews(this.referenceFrame))}}.bind(this),document.addEventListener("mouseup",this.boundDocumentMouseUpHandler),this.isMouseHandlers=!0}removeMouseHandlers(){this.rulerViewport.contentDiv.removeEventListener("mousedown",this.boundContentMouseDownHandler),document.removeEventListener("mousemove",this.boundDocumentMouseMoveHandler),document.removeEventListener("mouseup",this.boundDocumentMouseUpHandler),this.isMouseHandlers=!1}dispose(){this.removeBrowserObserver(),this.removeMouseHandlers(),this.rulerSweeper.remove()}}class ym{constructor(e){this.paired=!0,this.firstAlignment=e,this.chr=e.chr,this.readName=e.readName,e.startt.start?this.connectingEnd=e.start:this.connectingStart=e.start+e.lengthOnRef,this.start=Math.min(t.start,e.start),this.end=Math.max(t.start+t.lengthOnRef,e.start+e.lengthOnRef),this.lengthOnRef=this.end-this.start,this.scStart=Math.min(t.scStart,e.scStart);const i=Math.max(t.scStart+t.scLengthOnRef,e.scStart+e.scLengthOnRef);this.scLengthOnRef=i-this.scStart}containsLocation(e,t){const i=t?this.scStart:this.start,n=t?this.scLengthOnRef:this.lengthOnRef;return e>=i&&e<=i+n}alignmentContaining(e,t){return this.firstAlignment.containsLocation(e,t)?this.firstAlignment:this.secondAlignment&&this.secondAlignment.containsLocation(e,t)?this.secondAlignment:void 0}popupData(e){let t=this.firstAlignment.popupData(e);return this.secondAlignment&&(t.push("-------------------------------"),t=t.concat(this.secondAlignment.popupData(e))),t}isPaired(){return!0}isMateMapped(){return!0}isProperPair(){return this.firstAlignment.isProperPair()}get fragmentLength(){return Math.abs(this.firstAlignment.fragmentLength)}firstOfPairStrand(){return this.firstAlignment.isFirstOfPair()?this.firstAlignment.strand:this.secondAlignment&&this.secondAlignment.isFirstOfPair()?this.secondAlignment.strand:this.firstAlignment.mate.strand}hasTag(e){return this.firstAlignment.hasTag(e)||this.secondAlignment&&this.secondAlignment.hasTag(e)}}class _m{constructor(){this.alignments=[],this.score=void 0}findAlignment(e){const t=(e,t)=>t>=e.start&&t=o.start&&e0?h-=e:0===h&&(h=1)}return h}(o,n,e);case"STRAND":return o.strand?1:-1;case"START":return o.start;case"TAG":return o.tags()[i];case"READ_NAME":return o.readName;case"INSERT_SIZE":return-Math.abs(o.fragmentLength);case"GAP_SIZE":return-o.gapSizeAt(e);case"MATE_CHR":return o.mate;case"MQ":return void 0===o.mq?Number.MAX_VALUE:-o.mq;case"ALIGNED_READ_LENGTH":return-o.lengthOnRef;default:return Number.MAX_VALUE}}}function Cm(e){return e.isPaired()&&e.mate&&e.isMateMapped()&&e.chr===e.mate.chr&&(e.isFirstOfPair()||e.isSecondOfPair())&&!(e.isSecondary()||e.isSupplementary())}function xm(e){const t=[];for(let i of e)for(let e of i.alignments)e instanceof ym?(e.firstAlignment&&t.push(e.firstAlignment),e.secondAlignment&&t.push(e.secondAlignment)):t.push(e);return t}function km(e,t,i,n){if(e){if(0===e.length)return[];{e.sort((function(e,t){return n?e.scStart-t.scStart:e.start-t.start}));const t=[];let i,o=0,r=0;const a=new Set,s=()=>{i=new _m,t.push(i),o=0,r=0,a.clear()};for(s();e.length>0;)if(r>=0&&r(n?e.scStart:e.start)>o),r)}else e=e.filter((e=>!a.has(e))),s();return t}}}function Em(e,t,i){let n=i-1,o=e.length;for(;1+n>1);t(e[i])?o=i:n=i}return o}class Nm{constructor(e,t,i,{samplingWindowSize:n,samplingDepth:o,pairsSupported:r,alleleFreqThreshold:a}){this.chr=e,this.start=Math.floor(t),this.end=Math.ceil(i),this.length=i-t,this.alleleFreqThreshold=void 0===a?.2:a,this.coverageMap=new Im(e,t,i,this.alleleFreqThreshold),this.alignments=[],this.downsampledIntervals=[],this.samplingWindowSize=void 0===n?100:n,this.samplingDepth=void 0===o?1e3:o,this.pairsSupported=void 0===r||r,this.paired=!1,this.pairsCache={},this.downsampledReads=new Set,this.currentBucket=new Sm(this.start,this.start+this.samplingWindowSize,this),this.filter=function(e){return e.isMapped()&&!e.isFailsVendorQualityCheck()}}push(e){!1!==this.filter(e)&&(this.coverageMap.incCounts(e),this.pairsSupported&&this.downsampledReads.has(e.readName)||(e.start>=this.currentBucket.end&&(this.finishBucket(),this.currentBucket=new Sm(e.start,e.start+this.samplingWindowSize,this)),this.currentBucket.addAlignment(e)))}forEach(e){this.alignments.forEach(e)}finish(){void 0!==this.currentBucket&&this.finishBucket(),this.alignments.sort((function(e,t){return e.start-t.start})),this.pairsCache=void 0,this.downsampledReads=void 0}contains(e,t,i){return this.chr===e&&this.start<=t&&this.end>=i}hasDownsampledIntervals(){return this.downsampledIntervals&&this.downsampledIntervals.length>0}finishBucket(){this.alignments=this.alignments.concat(this.currentBucket.alignments),this.currentBucket.downsampledCount>0&&this.downsampledIntervals.push(new Dm(this.currentBucket.start,this.currentBucket.end,this.currentBucket.downsampledCount)),this.paired=this.paired||this.currentBucket.paired}setViewAsPairs(e){let t;t=e?function(e){const t={},i=[];for(let n of e)for(let e of n.alignments)if(Cm(e)){let n=t[e.readName];n?(n.setSecondAlignment(e),t[e.readName]=void 0):(n=new ym(e),t[e.readName]=n,i.push(n))}else i.push(e);return i}(this.packedAlignmentRows):xm(this.packedAlignmentRows),this.packedAlignmentRows=km(t,this.start,this.end)}setShowSoftClips(e){const t=this.allAlignments();this.packedAlignmentRows=km(t,this.start,this.end,e)}repack(e,t){const i=this.allAlignments();this.packedAlignmentRows=km(i,this.start,this.end,t)}allAlignments(){const e=[];for(let t of this.packedAlignmentRows)for(let i of t.alignments)e.push(i);return e}getMax(e,t){return this.coverageMap.getMax(e,t)}sortRows(e){const t=[],i=[];for(let n of this.packedAlignmentRows){void 0!==n.findAlignment(e.position)?t.push(n):i.push(n)}t.sort(((t,i)=>{const n=e.direction,o=t.getSortValue(e,this),r=i.getSortValue(e,this);if(void 0===r&&void 0!==r)return 1;if(void 0!==o&&void 0===r)return-1;const a=o>r?1:ot)break;const r=this.coverage[o];n>=e&&r&&(i=Math.max(i,r.total))}return i}incCounts(e){var t=this;if(void 0===e.blocks?i(e):e.blocks.forEach((function(e){i(e)})),e.gaps)for(let i of e.gaps)if("D"===i.type){const e=i.start-t.bpStart;for(let n=e;n=t}}class Dm{constructor(e,t,i){this.start=e,this.end=t,this.counts=i}popupData(e){return[{name:"start",value:this.start+1},{name:"end",value:this.end},{name:"# downsampled:",value:this.counts}]}}class Am{constructor(e){const t=e.split(",");this.chr=t[0],this.start=parseInt(t[1]),this.strand=t[2].charAt(0),this.mapQ=parseInt(t[4]),this.numMismatches=parseInt(t[5]),this.lenOnRef=Km.computeLengthOnReference(t[3])}printString(){return this.chr+":"+Za(this.start)+"-"+Za(this.start+this.lenOnRef)+" ("+this.strand+") = "+Za(this.lenOnRef)+"bp @MAPQ: "+this.mapQ+" NM: "+this.numMismatches}}function Mm(e){return e.split(";").filter((e=>e.length>0)).map((e=>new Am(e)))}const Tm={c:1,C:1,s:2,S:2,i:4,I:4,f:4};class Rm{constructor(){this.hidden=!1}isMapped(){return!(4&this.flags)}isPaired(){return!!(1&this.flags)}isProperPair(){return!!(2&this.flags)}isFirstOfPair(){return!!(64&this.flags)}isSecondOfPair(){return!!(128&this.flags)}isSecondary(){return!!(256&this.flags)}isSupplementary(){return!!(2048&this.flags)}isFailsVendorQualityCheck(){return!!(512&this.flags)}isDuplicate(){return!!(1024&this.flags)}isMateMapped(){return!(8&this.flags)}isNegativeStrand(){return!!(16&this.flags)}isMateNegativeStrand(){return!!(32&this.flags)}hasTag(e){return(this.tagDict||Bm(this.tagBA)).hasOwnProperty(e)}tags(){return this.tagDict||(this.tagBA?(this.tagDict=Bm(this.tagBA),this.tagBA=void 0):this.tagDict={}),this.tagDict}containsLocation(e,t){const i=t?this.scStart:this.start,n=t?this.scLengthOnRef:this.lengthOnRef;return e>=i&&e<=i+n}popupData(e){const t=[];if(e=Math.floor(e),this.insertions){const n=this.seq;for(let o of this.insertions){var i=o.start;if(e===i||e===i-1)return t.push({name:"Insertion",value:n.substr(o.seqOffset,o.len)}),t.push({name:"Location",value:i}),t}}t.push({name:"Read Name",value:this.readName}),t.push("
"),t.push({name:"Alignment Start",value:Za(1+this.start),borderTop:!0}),t.push({name:"Read Strand",value:!0===this.strand?"(+)":"(-)",borderTop:!0});let n=this.cigar;if(n&&n.length>50){const e=25;n=`${n.substring(0,e-2)} ... ${n.substring(n.length-e+2)}`}t.push({name:"Cigar",value:n}),t.push({name:"Mapping Quality",value:this.mq}),t.push({name:"Secondary",value:a(this.isSecondary())}),t.push({name:"Supplementary",value:a(this.isSupplementary())}),t.push({name:"Duplicate",value:a(this.isDuplicate())}),t.push({name:"Failed QC",value:a(this.isFailsVendorQualityCheck())}),this.isPaired()&&(t.push("
"),t.push({name:"First in Pair",value:!this.isSecondOfPair(),borderTop:!0}),t.push({name:"Mate is Mapped",value:a(this.isMateMapped())}),this.pairOrientation&&t.push({name:"Pair Orientation",value:this.pairOrientation}),this.isMateMapped()&&(t.push({name:"Mate Chromosome",value:this.mate.chr}),t.push({name:"Mate Start",value:this.mate.position+1}),t.push({name:"Mate Strand",value:!0===this.mate.strand?"(+)":"(-)"}),t.push({name:"Insert Size",value:this.fragmentLength})));const o=this.tags();if(o.hasOwnProperty("SA")){t.push("
"),t.push({name:"Supplementary Alignments",value:""});const e=Mm(o.SA);if(e){t.push("
    ");for(let i of e)t.push(`
  • ${i.printString()}
  • `);t.push("
")}}const r=new Set(["SA","MD"]);t.push("
");for(let e in o)r.has(e)||t.push({name:e,value:o[e]});return t.push({name:"Hidden Tags",value:"SA, MD"}),t.push("
"),t.push({name:"Genomic Location: ",value:Za(1+e)}),t.push({name:"Read Base:",value:this.readBaseAt(e)}),t.push({name:"Base Quality:",value:this.readBaseQualityAt(e)}),t;function a(e){return e?"Yes":"No"}}readBaseAt(e){const t=Lm(this.blocks,e);if(t){if("*"===this.seq)return"*";{const i=t.seqIndexAt(e);return this.seq[i]}}}readBaseQualityAt(e){const t=Lm(this.blocks,e);if(t){if("*"===this.qual)return 30;{const i=t.seqIndexAt(e);return i>=0&&this.qual&&i=t.start&&e=n.start&&t>1)+n;s+4=t)return!1;if("B"!==String.fromCharCode(e[s+2])||"I"!==String.fromCharCode(e[s+3]))return!1;var l=Ym(e,s+4),h=s+8;if(h+4*l>t)return!1;var d="",f=0;r.length=0,s=h;for(var u=0;u>4,g=Gm[15&p];"M"!==g&&"EQ"!==g&&"X"!==g&&"D"!==g&&"N"!==g&&"="!==g||(f+=m),d=d+m+g,r.push({len:m,ltr:g})}return o.cigar=d,o.lengthOnRef=f,!0},decodeBamRecords:function(e,t,i,n,o,r,a,s){for(;te.length)return;if(p<0){t=f;continue}if(void 0!==o&&(p>o||m>a))return!0;if(void 0!==o&&p>8,F=255&g,b=Ym(e,t+16),v=(4294901760&b)>>16,y=65535&b,_=Ym(e,t+20),C=Ym(e,t+24),x=Ym(e,t+28),k=Ym(e,t+32);let E=[];for(let i=0;i>4,h=Gm[15&c];"M"!==h&&"EQ"!==h&&"X"!==h&&"D"!==h&&"N"!==h&&"="!==h||(N+=l),S=S+l+h,I+=4,D={len:l,ltr:h},z.push(D)}if(u.chr=n[p],u.start=m,u.flags=v,u.strand=!(16&v),u.readName=E,u.cigar=S,u.lengthOnRef=N,u.fragmentLength=k,u.mq=w,Km.bam_tag2cigar(e,f,I,_,u,z),u.end=u.start+u.lengthOnRef,u.end>1;for(let t=0;t>4]),A.push(Wm[15&d])}A=A.slice(0,_).join(""),I+=M;const T=[];for(let t=0;t<_;++t)T.push(e[I+t]);I+=_,C>=0&&(u.mate={chr:n[C],position:x,strand:!(32&v)}),u.seq=A,u.qual=T,u.tagBA=new Uint8Array(e.buffer.slice(I,f)),this.setPairOrientation(u),(void 0===s||s.pass(u))&&(Xm(u,z),i.push(u)),t=f}},decodeSamRecords:function(e,t,i,n,o,r){var a,s,c,l,h,d,f,u,p,m;for(l=(a=Ka(e)).length,s=0;so)break;if(u=0,(m=Qm(p.cigar)).forEach((function(e){var t=e.len,i=e.ltr;"M"!==i&&"EQ"!==i&&"X"!==i&&"D"!==i&&"N"!==i&&"="!==i||(u+=t)})),p.lengthOnRef=u,!(p.start+uZm&&(console.log("Warning: attempt to set sampling depth > maximum value of "+Zm),e.samplingDepth=Zm),t.viewAsPairs?e.pairsSupported=!0:e.pairsSupported=void 0===t.pairsSupported||t.pairsSupported},setPairOrientation:function(e){if(e.isMapped()&&e.mate&&e.isMateMapped()&&e.mate.chr===e.chr){var t=e.strand?"F":"R",i=e.mate,n=i.strand?"F":"R",o=" ",r=" ";e.isFirstOfPair()?(o="1",r="2"):e.isSecondOfPair()&&(o="2",r="1");var a=[],s=e.fragmentLength,c=e.end-e.start;if(0===s)s=(e.start0?(a[0]=t,a[1]=o,a[2]=n,a[3]=r):(a[2]=t,a[3]=o,a[0]=n,a[1]=r),e.pairOrientation=a.join("")}},computeLengthOnReference:function(e){let t=0,i="";for(let n=0;n47&&o<58)i+=e.charAt(n);else{switch(o){case 78:case 68:case 77:case 61:case 88:t+=parseInt(i.toString())}i=""}}return t}};function Xm(e,t){const i=[];let n,o,r=0,a=e.start;e.scStart=e.start,e.scLengthOnRef=e.lengthOnRef;for(let s of t){let t;switch(s.ltr){case"H":case"P":break;case"S":t=a,e.scLengthOnRef+=s.len,0===i.length&&(e.scStart-=s.len,t-=s.len),i.push(new Um({start:t,seqOffset:r,len:s.len,type:"S"})),r+=s.len;break;case"N":case"D":void 0===o&&(o=[]),o.push({start:a,len:s.len,type:s.ltr}),a+=s.len;break;case"I":void 0===n&&(n=[]),n.push(new Um({start:a,len:s.len,seqOffset:r,type:"I"})),r+=s.len;break;case"M":case"EQ":case"=":case"X":i.push(new Um({start:a,seqOffset:r,len:s.len,type:"M"})),r+=s.len,a+=s.len;break;default:console.log("Error processing cigar element: "+s.len+s.ltr)}}e.blocks=i,e.insertions=n,e.gaps=o}function Ym(e,t){return e[t+3]<<24|e[t+2]<<16|e[t+1]<<8|e[t]}function Qm(e){var t,i,n,o,r,a,s,c,l;for(t=[],i=[],r=null,o=e.length,n=0;n=48&&l<=57?i.push(a):(s=a,c=Number.parseInt(i.join("")),i=[],null!==r&&r.ltr===s?r.len+=c:(r={len:c,ltr:s},t.push(r)));return t}function Jm(e){var t={};return e.forEach((function(e){var i=e.split(":");t[i[0]]=i[2]})),t}class eg{constructor(e,t){this.config=e,this.genome=t,this.bamPath=e.url,this.isDataUri=Rd(e.url),Km.setReaderDefaults(this,e)}async readAlignments(e,t,i){if(this.alignmentCache){const n=this.header,o=n.chrAliasTable.hasOwnProperty(e)?n.chrAliasTable[e]:e,r=this.alignmentCache.queryFeatures(o,t,i),a=new Nm(e,t,i,this.config);for(let e of r)a.push(e);return a.finish(),a}if(this.isDataUri){const n=zh(function(e){const t=e.split(","),i=t[0].split(":")[1];let n=t[1];n=i.indexOf("base64")>=0?atob(n):decodeURI(n);const o=new Uint8Array(n.length);for(var r=0;r{var e={368:function(e,t,i){var n=this&&this.__awaiter||function(e,t,i,n){return new(i||(i=Promise))((function(o,r){function a(e){try{c(n.next(e))}catch(e){r(e)}}function s(e){try{c(n.throw(e))}catch(e){r(e)}}function c(e){var t;e.done?o(e.value):(t=e.value,t instanceof i?t:new i((function(e){e(t)}))).then(a,s)}c((n=n.apply(e,t||[])).next())}))},o=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const r=o(i(4105)),a=o(i(1269)),s=i(597),c=i(3427),l=i(8577);function h(e,t){if(t.some((e=>void 0===e)))throw new l.CramMalformedError("invalid .crai index file");const[i,n,o,r,a,s]=t;e[i]||(e[i]=[]),e[i].push({start:n,span:o,containerStart:r,sliceStart:a,sliceBytes:s})}t.default=class{constructor(e){this.filehandle=(0,c.open)(e.url,e.path,e.filehandle),this._parseCache=new r.default({cache:new a.default({maxSize:1}),fill:(e,t)=>this.parseIndex()})}parseIndex(){const e={};return this.filehandle.readFile().then((e=>31===e[0]&&139===e[1]?(0,s.unzip)(e):e)).then((t=>{if(t.length>4&&21578050===t.readUInt32LE(0))throw new l.CramMalformedError("invalid .crai index file. note: file appears to be a .bai index. this is technically legal but please open a github issue if you need support");let i=[],n="";for(let o=0;o=48&&r<=57||!n&&45===r)n+=String.fromCharCode(r);else if(9===r)i.push(Number.parseInt(n,10)),n="";else if(10===r)i.push(Number.parseInt(n,10)),n="",h(e,i),i=[];else if(13!==r&&32!==r)throw new l.CramMalformedError("invalid .crai index file")}return n&&i.push(Number.parseInt(n,10)),6===i.length&&h(e,i),Object.entries(e).forEach((([t,i])=>{e[t]=i.sort(((e,t)=>e.start-t.start||e.span-t.span))})),e}))}getIndex(e={}){return this._parseCache.get("index",null,e.signal)}hasDataForReferenceSequence(e){return n(this,void 0,void 0,(function*(){return!!(yield this.getIndex())[e]}))}getEntriesForRange(e,t,i){return n(this,void 0,void 0,(function*(){const n=(yield this.getIndex())[e];if(!n)return[];const o=e=>{const n=e.start,o=e.start+e.span;return n>i?-1:o<=t?1:0},r=[];for(let e=0;e{Object.defineProperty(t,"__esModule",{value:!0}),t.default=class{constructor(e,t){this.parameters=e,this.dataType=t}}},4863:function(e,t,i){var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const o=i(8577),r=n(i(1050)),a=i(1074);class s extends r.default{constructor(e,t){if(super(e,t),"int"!==this.dataType)throw new o.CramUnimplementedError(`${this.dataType} decoding not yet implemented by BETA codec`)}decode(e,t,i,n){return(0,a.getBits)(t.content,n.coreBlock,this.parameters.length)-this.parameters.offset}}t.default=s},1738:function(e,t,i){var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const o=i(9488),r=n(i(1050));class a extends r.default{constructor(e,t,i){if(super(e,t),this.instantiateCodec=i,"byteArray"!==t)throw new TypeError(`byteArrayLength does not support data type ${t}`)}decode(e,t,i,n){const o=this._getLengthCodec().decode(e,t,i,n),r=this._getDataCodec(),a=new Uint8Array(o);for(let s=0;s(0,o.tinyMemoize)(a,e)))},1405:function(e,t,i){var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const o=i(8577),r=n(i(1050)),a=i(1074);class s extends r.default{constructor(e,t){if(super(e,t),"byteArray"!==t)throw new TypeError(`byteArrayStop codec does not support data type ${t}`)}decode(e,t,i,n){const{blockContentId:r}=this.parameters,a=i[r];if(!a)throw new o.CramMalformedError(`no block found with content ID ${r}`);const s=n.externalBlocks.getCursor(r);return this._decodeByteArray(a,s)}_decodeByteArray(e,t){const i=e.content,{stopByte:n}=this.parameters,o=t.bytePosition;let r=t.bytePosition;for(;i[r]!==n&&r=e.content.length)throw new s.CramBufferOverrunError("attempted to read beyond end of block. this file seems truncated.");return e.content[t.bytePosition++]}}t.default=c},4229:function(e,t,i){var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const o=i(8577),r=n(i(1050)),a=i(1074);class s extends r.default{constructor(e,t){if(super(e,t),"int"!==this.dataType)throw new o.CramUnimplementedError(`${this.dataType} decoding not yet implemented by GAMMA codec`)}decode(e,t,i,n){let o=1;for(;0===(0,a.getBits)(t.content,n.coreBlock,1);)o+=1;return((0,a.getBits)(t.content,n.coreBlock,o-1)|1<{Object.defineProperty(t,"__esModule",{value:!0}),t.getBits=t.CramBufferOverrunError=void 0;class i extends Error{}t.CramBufferOverrunError=i,t.getBits=function(e,t,n){let o=0;if(t.bytePosition+(7-t.bitPosition+n)/8>e.length)throw new i("read error during decoding. the file seems to be truncated.");for(let i=n;i;i--)o<<=1,o|=e[t.bytePosition]>>t.bitPosition&1,t.bitPosition-=1,t.bitPosition<0&&(t.bytePosition+=1),t.bitPosition&=7;return o}},2082:function(e,t,i){var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const o=i(8577),r=n(i(1050)),a=i(1074);class s extends r.default{constructor(e,t){if(super(e,t),this.codes={},this.codeBook={},this.sortedByValue=[],this.sortedCodes=[],this.sortedValuesByBitCode=[],this.sortedBitCodes=[],this.sortedBitLengthsByBitCode=[],this.bitCodeToValue=[],!["byte","int"].includes(this.dataType))throw new TypeError(`${this.dataType} decoding not yet implemented by HUFFMAN_INT codec`);this.buildCodeBook(),this.buildCodes(),this.buildCaches(),0===this.sortedCodes[0].bitLength&&(this._decode=this._decodeZeroLengthCode)}buildCodeBook(){let e=new Array(this.parameters.numCodes);for(let t=0;te.bitLength-t.bitLength||e.symbol-t.symbol)),this.codeBook={},e.forEach((e=>{this.codeBook[e.bitLength]||(this.codeBook[e.bitLength]=[]),this.codeBook[e.bitLength].push(e.symbol)}))}buildCodes(){this.codes={};let e=0,t=-1;Object.entries(this.codeBook).forEach((([i,n])=>{const r=parseInt(i,10);n.forEach((i=>{const n={bitLength:r,value:i,bitCode:0};t+=1;const a=r-e;if(t<<=a,n.bitCode=t,e+=a,function(e){let t=e-(e>>1)&1431655765;return t=(858993459&t)+(t>>2&858993459),16843009*(t+(t>>4)&252645135)>>24}(t)>r)throw new o.CramMalformedError("Symbol out of range");this.codes[i]=n}))}))}buildCaches(){this.sortedCodes=Object.values(this.codes).sort(((e,t)=>e.bitLength-t.bitLength||e.bitCode-t.bitCode)),this.sortedByValue=Object.values(this.codes).sort(((e,t)=>e.value-t.value)),this.sortedValuesByBitCode=this.sortedCodes.map((e=>e.value)),this.sortedBitCodes=this.sortedCodes.map((e=>e.bitCode)),this.sortedBitLengthsByBitCode=this.sortedCodes.map((e=>e.bitLength));const e=Math.max(...this.sortedBitCodes);this.bitCodeToValue=new Array(e+1).fill(-1);for(let e=0;e-1&&this.sortedBitLengthsByBitCode[i]===t)return this.sortedValuesByBitCode[i];for(let i=e;this.sortedCodes[i+1].bitLength===t&&i{Object.defineProperty(t,"__esModule",{value:!0}),t.default={CRAM_FLAG_PRESERVE_QUAL_SCORES:1,CRAM_FLAG_DETACHED:2,CRAM_FLAG_MATE_DOWNSTREAM:4,CRAM_FLAG_NO_SEQ:8,CRAM_FLAG_MASK:15,CRAM_M_REVERSE:1,CRAM_M_UNMAP:2,BAM_FPAIRED:1,BAM_FPROPER_PAIR:2,BAM_FUNMAP:4,BAM_FMUNMAP:8,BAM_FREVERSE:16,BAM_FMREVERSE:32,BAM_FREAD1:64,BAM_FREAD2:128,BAM_FSECONDARY:256,BAM_FQCFAIL:512,BAM_FDUP:1024,BAM_FSUPPLEMENTARY:2048,BAM_CMATCH:0,BAM_CINS:1,BAM_CDEL:2,BAM_CREF_SKIP:3,BAM_CSOFT_CLIP:4,BAM_CHARD_CLIP:5,BAM_CPAD:6,BAM_CEQUAL:7,BAM_CDIFF:8,BAM_CBACK:9,BAM_CIGAR_STR:"MIDNSHP:XB",BAM_CIGAR_SHIFT:4,BAM_CIGAR_MASK:15,BAM_CIGAR_TYPE:246183}},8543:(e,t,i)=>{Object.defineProperty(t,"__esModule",{value:!0});const n=i(8772),o=i(8577),r={BF:"int",CF:"int",RI:"int",RL:"int",AP:"int",RG:"int",MF:"int",NS:"int",NP:"int",TS:"int",NF:"int",TC:"byte",TN:"int",FN:"int",FC:"byte",FP:"int",BS:"byte",IN:"byteArray",SC:"byteArray",DL:"int",BA:"byte",BB:"byteArray",RS:"int",PD:"int",HC:"int",MQ:"int",RN:"byteArray",QS:"byte",QQ:"byteArray",TL:"int"};t.default=class{constructor(e){this.dataSeriesCodecCache={},this.tagCodecCache={},this.tagEncoding={},this.readNamesIncluded=e.preservation.RN,this.APdelta=e.preservation.AP,this.referenceRequired=!!e.preservation.RR,this.tagIdsDictionary=e.preservation.TD,this.substitutionMatrix=function(e){const t=new Array(5);for(let e=0;e<5;e+=1)t[e]=new Array(4);return t[0][e[0]>>6&3]="C",t[0][e[0]>>4&3]="G",t[0][e[0]>>2&3]="T",t[0][3&e[0]]="N",t[1][e[1]>>6&3]="A",t[1][e[1]>>4&3]="G",t[1][e[1]>>2&3]="T",t[1][3&e[1]]="N",t[2][e[2]>>6&3]="A",t[2][e[2]>>4&3]="C",t[2][e[2]>>2&3]="T",t[2][3&e[2]]="N",t[3][e[3]>>6&3]="A",t[3][e[3]>>4&3]="C",t[3][e[3]>>2&3]="G",t[3][3&e[3]]="N",t[4][e[4]>>6&3]="A",t[4][e[4]>>4&3]="C",t[4][e[4]>>2&3]="G",t[4][3&e[4]]="T",t}(e.preservation.SM),this.dataSeriesEncoding=e.dataSeriesEncoding,this.tagEncoding=e.tagEncoding,this.preservation=e.preservation,this._size=e._size,this._endPosition=e._endPosition}getCodecForTag(e){if(!this.tagCodecCache[e]){const t=this.tagEncoding[e];t&&(this.tagCodecCache[e]=(0,n.instantiateCodec)(t,"byteArray"))}return this.tagCodecCache[e]}getTagNames(e){return this.tagIdsDictionary[e]}getCodecForDataSeries(e){let t=this.dataSeriesCodecCache[e];if(void 0===t){const i=this.dataSeriesEncoding[e];if(i){const a=r[e];if(!a)throw new o.CramMalformedError(`data series name ${e} not defined in file compression header`);t=(0,n.instantiateCodec)(i,a),this.dataSeriesCodecCache[e]=t}}return t}toJSON(){const e={};return Object.keys(this).forEach((t=>{/Cache$/.test(t)||(e[t]=this[t])})),e}}},6284:function(e,t,i){var n=this&&this.__awaiter||function(e,t,i,n){return new(i||(i=Promise))((function(o,r){function a(e){try{c(n.next(e))}catch(e){r(e)}}function s(e){try{c(n.throw(e))}catch(e){r(e)}}function c(e){var t;e.done?o(e.value):(t=e.value,t instanceof i?t:new i((function(e){e(t)}))).then(a,s)}c((n=n.apply(e,t||[])).next())}))},o=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const r=i(8577),a=i(9488),s=o(i(6601)),c=o(i(8543));class l{constructor(e,t){this.file=e,this.filePosition=t}getHeader(){return this._readContainerHeader(this.filePosition)}getCompressionHeaderBlock(){return n(this,void 0,void 0,(function*(){if(!(yield this.getHeader()).numRecords)return null;const e=yield this.file.getSectionParsers(),t=yield this.getFirstBlock();if(void 0===t)return;if("COMPRESSION_HEADER"!==t.contentType)throw new r.CramMalformedError(`invalid content type ${t.contentType} in what is supposed to be the compression header block`);const i=(0,a.parseItem)(t.content,e.cramCompressionHeader.parser,0,t.contentPosition);return Object.assign(Object.assign({},t),{parsedContent:i})}))}getFirstBlock(){return n(this,void 0,void 0,(function*(){const e=yield this.getHeader();return this.file.readBlock(e._endPosition)}))}getCompressionScheme(){return n(this,void 0,void 0,(function*(){const e=yield this.getCompressionHeaderBlock();if(e)return new c.default(e.parsedContent)}))}getSlice(e,t){return new s.default(this,e,t)}_readContainerHeader(e){return n(this,void 0,void 0,(function*(){const t=yield this.file.getSectionParsers(),{cramContainerHeader1:i,cramContainerHeader2:n}=t,{size:o}=yield this.file.stat();if(e>=o)return;const r=Buffer.allocUnsafe(i.maxLength);yield this.file.read(r,0,i.maxLength,e);const s=(0,a.parseItem)(r,i.parser),c=(0,a.itf8Size)(s.numLandmarks);if(e+s.length>=o)return void console.warn(`${this.file}: container header at ${e} indicates that the container has length ${s.length}, which extends beyond the length of the file. Skipping this container.`);const l=Buffer.allocUnsafe(n.maxLength(s.numLandmarks));yield this.file.read(l,0,n.maxLength(s.numLandmarks),e+s._size-c);const h=(0,a.parseItem)(l,n.parser);return this.file.validateChecksums&&void 0!==h.crc32&&(yield this.file.checkCrc32(e,s._size+h._size-c-4,h.crc32,`container header beginning at position ${e}`)),Object.assign(s,h,{_size:s._size+h._size-c,_endPosition:s._size+h._size-c+e})}))}}t.default=l,"getHeader getCompressionHeaderBlock getCompressionScheme".split(" ").forEach((e=>(0,a.tinyMemoize)(l,e)))},5457:function(e,t,i){var n=this&&this.__awaiter||function(e,t,i,n){return new(i||(i=Promise))((function(o,r){function a(e){try{c(n.next(e))}catch(e){r(e)}}function s(e){try{c(n.throw(e))}catch(e){r(e)}}function c(e){var t;e.done?o(e.value):(t=e.value,t instanceof i?t:new i((function(e){e(t)}))).then(a,s)}c((n=n.apply(e,t||[])).next())}))},o=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const r=i(597),a=o(i(2779)),s=o(i(1269)),c=i(8577),l=o(i(9675)),h=i(6141),d=o(i(3498)),f=o(i(6284)),u=i(3427),p=i(9488),m=i(7578);class g{constructor(e){var t;if(this.file=(0,u.open)(e.url,e.path,e.filehandle),this.validateChecksums=!0,this.fetchReferenceSequenceCallback=e.seqFetch,this.options={checkSequenceMD5:e.checkSequenceMD5,cacheSize:null!==(t=e.cacheSize)&&void 0!==t?t:2e4},this.featureCache=new s.default({maxSize:this.options.cacheSize}),function(){const e=new Uint32Array([287454020]),t=new Uint8Array(e.buffer);return 68===t[0]?0:17===t[0]?1:2}()>0)throw new Error("Detected big-endian machine, may be unable to run")}read(e,t,i,n){return this.file.read(e,t,i,n)}stat(){return this.file.stat()}getDefinition(){return n(this,void 0,void 0,(function*(){const e=Buffer.allocUnsafe(h.cramFileDefinition.maxLength);yield this.file.read(e,0,h.cramFileDefinition.maxLength,0);const t=h.cramFileDefinition.parser.parse(e).result;if(2!==t.majorVersion&&3!==t.majorVersion)throw new c.CramUnimplementedError(`CRAM version ${t.majorVersion} not supported`);return t}))}getSamHeader(){return n(this,void 0,void 0,(function*(){const e=yield this.getContainerById(0);if(!e)throw new c.CramMalformedError("file contains no containers");const t=yield e.getFirstBlock();if(void 0===t)return(0,m.parseHeaderText)("");const i=t.content,n=i.readInt32LE(0),o=i.toString("utf8",4,4+n);return this.header=o,(0,m.parseHeaderText)(o)}))}getHeaderText(){return n(this,void 0,void 0,(function*(){return yield this.getSamHeader(),this.header}))}getSectionParsers(){return n(this,void 0,void 0,(function*(){const{majorVersion:e}=yield this.getDefinition();return(0,h.getSectionParsers)(e)}))}getContainerById(e){return n(this,void 0,void 0,(function*(){const t=yield this.getSectionParsers();let i=t.cramFileDefinition.maxLength;const{size:n}=yield this.file.stat(),{cramContainerHeader1:o}=t;let r;for(let t=0;t<=e;t+=1){if(i+o.maxLength+8>=n)return;r=this.getContainerAtPosition(i);const a=yield r.getHeader();if(!a)throw new c.CramMalformedError(`container ${e} not found in file`);if(0===t){i=a._endPosition;for(let e=0;e=n)return;const o=Buffer.allocUnsafe(i.maxLength);return yield this.file.read(o,0,i.maxLength,e),(0,p.parseItem)(o,i.parser,0,e)}))}_parseSection(e,t,i=e.maxLength,o){return n(this,void 0,void 0,(function*(){let n;if(o)n=o;else{const{size:e}=yield this.file.stat();if(t+i>=e)return;n=Buffer.allocUnsafe(i),yield this.file.read(n,0,i,t)}const r=(0,p.parseItem)(n,e.parser,0,t);if(r._size!==i)throw new c.CramMalformedError(`section read error: requested size ${i} does not equal parsed size ${r._size}`);return r}))}_uncompress(e,t,i){if("gzip"===e)(0,r.unzip)(t).copy(i);else if("bzip2"===e){const e=bzip2.array(t);let n,o=bzip2.header(e),r=0;do{n=bzip2.decompress(e,o),-1!=n&&(Buffer.from(n).copy(i,r),r+=n.length,o-=n.length)}while(-1!=n)}else if("rans"===e)(0,l.default)(t,i);else if("rans4x16"===e)d.default.r4x16_uncompress(t,i);else if("arith"===e)d.default.arith_uncompress(t,i);else if("fqzcomp"===e)d.default.fqzcomp_uncompress(t,i);else{if("tok3"!==e)throw new c.CramUnimplementedError(`${e} decompression not yet implemented`);d.default.tok3_uncompress(t,i)}}readBlock(e){return n(this,void 0,void 0,(function*(){const{majorVersion:t}=yield this.getDefinition(),i=yield this.getSectionParsers(),n=yield this.readBlockHeader(e);if(void 0===n)return;const o=n._endPosition,r=Buffer.allocUnsafe(n.uncompressedSize),a=Object.assign(Object.assign({},n),{_endPosition:o,contentPosition:o,content:r});if("raw"!==n.compressionMethod){const e=Buffer.allocUnsafe(n.compressedSize);yield this.read(e,0,n.compressedSize,o),this._uncompress(n.compressionMethod,e,r)}else yield this.read(r,0,n.uncompressedSize,o);if(t>=3){const t=yield this._parseSection(i.cramBlockCrc32,o+n.compressedSize);if(void 0===t)return;a.crc32=t.crc32,this.validateChecksums&&(yield this.checkCrc32(e,n._size+n.compressedSize,t.crc32,"block data")),a._endPosition=t._endPosition,a._size=a.compressedSize+i.cramBlockCrc32.maxLength}else a._endPosition=o+a.compressedSize,a._size=a.compressedSize;return a}))}}t.default=g,"getDefinition getSectionParsers getSamHeader".split(" ").forEach((e=>(0,p.tinyMemoize)(g,e)))},8222:function(e,t,i){var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0}),t.CramRecord=void 0;const o=n(i(5457));var r=i(8631);Object.defineProperty(t,"CramRecord",{enumerable:!0,get:function(){return n(r).default}}),t.default=o.default},8631:function(e,t,i){var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0}),t.MateFlagsDecoder=t.CramFlagsDecoder=t.BamFlagsDecoder=t.MateFlags=t.CramFlags=t.BamFlags=void 0;const o=n(i(2615)),r={a:0,A:0,c:1,C:1,g:2,G:2,t:3,T:3,n:4,N:4};function a(e){const t={};for(const[i,n]of e)t["is"+n]=e=>!!(e&i),t["set"+n]=e=>e|i;return t}t.BamFlags=[[1,"Paired"],[2,"ProperlyPaired"],[4,"SegmentUnmapped"],[8,"MateUnmapped"],[16,"ReverseComplemented"],[32,"MateReverseComplemented"],[64,"Read1"],[128,"Read2"],[256,"Secondary"],[512,"FailedQc"],[1024,"Duplicate"],[2048,"Supplementary"]],t.CramFlags=[[1,"PreservingQualityScores"],[2,"Detached"],[4,"WithMateDownstream"],[8,"DecodeSequenceAsStar"]],t.MateFlags=[[1,"OnNegativeStrand"],[2,"Unmapped"]],t.BamFlagsDecoder=a(t.BamFlags),t.CramFlagsDecoder=a(t.CramFlags),t.MateFlagsDecoder=a(t.MateFlags),t.default=class{constructor({flags:e,cramFlags:t,readLength:i,mappingQuality:n,lengthOnRef:o,qualityScores:r,mateRecordNumber:a,readBases:s,readFeatures:c,mateToUse:l,readGroupId:h,readName:d,sequenceId:f,uniqueId:u,templateSize:p,alignmentStart:m,tags:g}){this.flags=e,this.cramFlags=t,this.readLength=i,this.mappingQuality=n,this.lengthOnRef=o,this.qualityScores=r,s&&(this.readBases=s),this.readGroupId=h,this.readName=d,this.sequenceId=f,this.uniqueId=u,this.templateSize=p,this.alignmentStart=m,this.tags=g,c&&(this.readFeatures=c),l&&(this.mate={flags:l.mateFlags,readName:l.mateReadName,sequenceId:l.mateSequenceId,alignmentStart:l.mateAlignmentStart}),a&&(this.mateRecordNumber=a)}isPaired(){return!!(this.flags&o.default.BAM_FPAIRED)}isProperlyPaired(){return!!(this.flags&o.default.BAM_FPROPER_PAIR)}isSegmentUnmapped(){return!!(this.flags&o.default.BAM_FUNMAP)}isMateUnmapped(){return!!(this.flags&o.default.BAM_FMUNMAP)}isReverseComplemented(){return!!(this.flags&o.default.BAM_FREVERSE)}isMateReverseComplemented(){return!!(this.flags&o.default.BAM_FMREVERSE)}isRead1(){return!!(this.flags&o.default.BAM_FREAD1)}isRead2(){return!!(this.flags&o.default.BAM_FREAD2)}isSecondary(){return!!(this.flags&o.default.BAM_FSECONDARY)}isFailedQc(){return!!(this.flags&o.default.BAM_FQCFAIL)}isDuplicate(){return!!(this.flags&o.default.BAM_FDUP)}isSupplementary(){return!!(this.flags&o.default.BAM_FSUPPLEMENTARY)}isDetached(){return!!(this.cramFlags&o.default.CRAM_FLAG_DETACHED)}hasMateDownStream(){return!!(this.cramFlags&o.default.CRAM_FLAG_MATE_DOWNSTREAM)}isPreservingQualityScores(){return!!(this.cramFlags&o.default.CRAM_FLAG_PRESERVE_QUAL_SCORES)}isUnknownBases(){return!!(this.cramFlags&o.default.CRAM_FLAG_NO_SEQ)}getReadBases(){if(!this.readBases&&this._refRegion){const e=function(e,t){if(!e.lengthOnRef&&!e.readLength)return null;if(e.isUnknownBases())return null;const i=e.alignmentStart-t.start;if(!e.readFeatures)return t.seq.substr(i,e.lengthOnRef).toUpperCase();let n="",o=i,r=0;for(;n.lengththis.mate.alignmentStart&&r>0&&(r=-r),r>0?(o[0]=e,o[1]=i,o[2]=t,o[3]=n):(o[2]=e,o[3]=i,o[0]=t,o[1]=n),o.join("")}return null}addReferenceSequence(e,t){this.readFeatures&&this.readFeatures.forEach((i=>{"X"===i.code&&function(e,t,i,n){if(!t)return;const o=n.refPos-t.start,a=t.seq.charAt(o);a&&(n.ref=a);let s=r[a];void 0===s&&(s=4);const c=i.substitutionMatrix[s][n.data];c&&(n.sub=c)}(0,e,t,i)})),!this.readBases&&e.start<=this.alignmentStart&&e.end>=this.alignmentStart+(this.lengthOnRef||this.readLength)-1&&(this._refRegion=e)}toJSON(){const e={};return Object.keys(this).forEach((t=>{"_"!==t.charAt(0)&&(e[t]=this[t])})),e.readBases=this.getReadBases(),e}}},6141:(e,t,i)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.getSectionParsers=t.cramFileDefinition=t.isMappedSliceHeader=void 0;const n=i(9996),o=(new n.Parser).itf8(),r={parser:(new n.Parser).string("magic",{length:4}).uint8("majorVersion").uint8("minorVersion").string("fileId",{length:20,stripNull:!0}),maxLength:26};t.cramFileDefinition=r;const a={parser:(new n.Parser).uint8("compressionMethod",{formatter:e=>{const t=["raw","gzip","bzip2","lzma","rans","rans4x16","arith","fqzcomp","tok3"][e];if(!t)throw new Error(`compression method number ${e} not implemented`);return t}}).uint8("contentType",{formatter:e=>{const t=["FILE_HEADER","COMPRESSION_HEADER","MAPPED_SLICE_HEADER","UNMAPPED_SLICE_HEADER","EXTERNAL_DATA","CORE_DATA"][e];if(!t)throw new Error(`invalid block content type id ${e}`);return t}}).itf8("contentId").itf8("compressedSize").itf8("uncompressedSize"),maxLength:17},s={parser:(new n.Parser).uint32("crc32"),maxLength:4},c=(new n.Parser).itf8("size").buffer("ents",{length:"size",formatter:e=>{function t(t,i){const n=e.toString("utf8",t,i),o=[];for(let e=0;eo&&n.push(t(o,i)),n}}),l=(new n.Parser).uint8(null,{formatter:e=>!!e}),h=(new n.Parser).itf8("mapSize").itf8("mapCount").array("ents",{length:"mapCount",type:(new n.Parser).string("key",{length:2,stripNull:!1}).choice("value",{tag:"key",choices:{MI:l,UI:l,PI:l,RN:l,AP:l,RR:l,SM:(new n.Parser).array(null,{type:"uint8",length:5}),TD:(new n.Parser).nest(null,{type:c,formatter:e=>e.ents})}})});function d(e){const t={};for(let i=0;i=3?(i=i.ltf8("recordCounter"),t+=9):2===e&&(i=i.itf8("recordCounter"),t+=5),i=i.itf8("numBlocks").itf8("numContentIds").array("contentIds",{type:o,length:"numContentIds"}),t+=10,e>=2&&(i=i.array("md5",{type:"uint8",length:16}),t+=16),{parser:i,maxLength:e=>t+5*e}},cramMappedSliceHeader(e){let t=(new n.Parser).itf8("refSeqId").itf8("refSeqStart").itf8("refSeqSpan").itf8("numRecords"),i=20;return e>=3?(t=t.ltf8("recordCounter"),i+=9):2===e&&(t=t.itf8("recordCounter"),i+=5),t=t.itf8("numBlocks").itf8("numContentIds").array("contentIds",{type:o,length:"numContentIds"}).itf8("refBaseBlockId"),i+=15,e>=2&&(t=t.array("md5",{type:"uint8",length:16}),i+=16),{parser:t,maxLength:e=>i+5*e}},cramEncoding:e=>({parser:(new n.Parser).namely("cramEncoding").itf8("codecId").itf8("parametersBytes").choice("parameters",{tag:"codecId",choices:{0:new n.Parser,1:(new n.Parser).itf8("blockContentId"),2:(new n.Parser).itf8("offset").itf8("M"),3:n.Parser.start().itf8("numCodes").array("symbols",{length:"numCodes",type:o}).itf8("numLengths").array("bitLengths",{length:"numLengths",type:o}),4:n.Parser.start().nest("lengthsEncoding",{type:"cramEncoding"}).nest("valuesEncoding",{type:"cramEncoding"}),5:(new n.Parser).uint8("stopByte").itf8("blockContentId"),6:(new n.Parser).itf8("offset").itf8("length"),7:(new n.Parser).itf8("offset").itf8("K"),8:(new n.Parser).itf8("offset").itf8("log2m"),9:(new n.Parser).itf8("offset")}})}),cramDataSeriesEncodingMap(e){return(new n.Parser).itf8("mapSize").itf8("mapCount").array("ents",{length:"mapCount",type:(new n.Parser).string("key",{length:2,stripNull:!1}).nest("value",{type:this.cramEncoding(e).parser})})},cramTagEncodingMap(e){return(new n.Parser).itf8("mapSize").itf8("mapCount").array("ents",{length:"mapCount",type:(new n.Parser).itf8("key",{formatter:e=>String.fromCharCode(e>>16&255)+String.fromCharCode(e>>8&255)+String.fromCharCode(255&e)}).nest("value",{type:this.cramEncoding(e).parser})})},cramCompressionHeader(e){let t=new n.Parser;return t=t.nest("preservation",{type:h,formatter:d}).nest("dataSeriesEncoding",{type:this.cramDataSeriesEncodingMap(e),formatter:d}).nest("tagEncoding",{type:this.cramTagEncodingMap(e),formatter:d}),{parser:t}},cramContainerHeader1(e){let t=(new n.Parser).int32("length").itf8("refSeqId").itf8("refSeqStart").itf8("alignmentSpan").itf8("numRecords"),i=24;return e>=3?(t=t.ltf8("recordCounter"),i+=9):2===e&&(t=t.itf8("recordCounter"),i+=5),e>1&&(t=t.ltf8("numBases"),i+=9),t=t.itf8("numBlocks").itf8("numLandmarks"),i+=10,{parser:t,maxLength:i}},cramContainerHeader2(e){let t=(new n.Parser).itf8("numLandmarks").array("landmarks",{type:(new n.Parser).itf8(),length:"numLandmarks"}),i=0;return e>=3&&(t=t.uint32("crc32"),i=4),{parser:t,maxLength:e=>5+5*e+i}}};t.getSectionParsers=function(e){const t=Object.assign({},f);return Object.keys(u).forEach((i=>{t[i]=u[i](e)})),t}},3757:function(e,t,i){var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const o=n(i(3720)),r=i(8577),a=i(8631),s=i(6141);function c(e){let t="";for(let i=0;i1&&-2===n.parsedContent.refSeqId?t("RI"):n.parsedContent.refSeqId;const w=t("RL");let F=t("AP");i.APdelta&&(F+=d.lastAlignmentStart),d.lastAlignmentStart=F;const b=t("RG");let v,y,_,C;if(i.readNamesIncluded&&(v=c(t("RN"))),a.CramFlagsDecoder.isDetached(m)){const e=t("MF");let n;i.readNamesIncluded||(n=c(t("RN")),v=n);const o=t("NS"),r=t("NP");(e||o>-1)&&(y={mateFlags:e,mateSequenceId:o,mateAlignmentStart:r,mateReadName:n}),_=t("TS"),a.MateFlagsDecoder.isUnmapped(e)&&(p=a.BamFlagsDecoder.setMateUnmapped(p)),a.MateFlagsDecoder.isOnNegativeStrand(e)&&(p=a.BamFlagsDecoder.setMateReverseComplemented(p))}else a.CramFlagsDecoder.isWithMateDownstream(m)&&(C=t("NF")+u+1);const x=t("TL");if(x<0)throw new r.CramMalformedError("invalid TL index");const k={},E=i.getTagNames(x),N=E.length;for(let t=0;t1?"SC":"IN"],X:["number","BS"],D:["number","DL"],I:["string","IN"],i:["character","BA"],b:["string","BB"],q:["numArray","QQ"],Q:["number","QS"],H:["number","HC"],P:["number","PD"],N:["number","RS"]}[t];if(!h)throw new r.CramMalformedError(`invalid read feature code "${t}"`);let d=l(h);const f={B:["number","QS"]}[t];f&&(d=[d,l(f)]),a+=n;const u=a;s+=n;const p=s;"D"===t||"N"===t?s+=d:"I"===t||"S"===t?s-=d.length:"i"===t&&(s-=1),c[e]={code:t,pos:u,refPos:p,data:d}}return c}(F,e,t,0,f)),I=w,S)for(const{code:e,data:t}of S)"D"===e||"N"===e?I+=t:"I"===e||"S"===e?I-=t.length:"i"===e&&(I-=1);if(Number.isNaN(I)&&(console.warn(`${v||`${g}:${F}`} record has invalid read features`),I=w),z=t("MQ"),a.CramFlagsDecoder.isPreservingQualityScores(m)){D=new Array(w);for(let e=0;e=0){const o=e[i.mateRecordNumber];if(!o)throw new r.CramMalformedError("intra-slice mate record not found, this file seems malformed");n.push(...t(o))}return n}(i),o=n.map((e=>e.alignmentStart)),a=n.map((e=>e.alignmentStart+e.readLength-1)),s=Math.max(...a)-Math.min(...o)+1;s>=0&&n.forEach((e=>{if(void 0!==e.templateLength)throw new r.CramMalformedError("mate pair group has some members that have template lengths already, this file seems malformed");e.templateLength=s}))}(e,0,i):function(e,t){const i=Math.min(e.alignmentStart,t.alignmentStart),n=Math.max(e.alignmentStart+e.readLength-1,t.alignmentStart+t.readLength-1)-i+1;e.templateLength=n,t.templateLength=n}(i,n)),delete i.mateRecordNumber}class u{constructor(e,t,i){this.container=e,this.containerPosition=t,this.file=e.file}getHeader(){return n(this,void 0,void 0,(function*(){const e=yield this.file.getSectionParsers(),t=yield this.container.getHeader(),i=yield this.file.readBlock(t._endPosition+this.containerPosition);if(void 0===i)throw new Error;if("MAPPED_SLICE_HEADER"===i.contentType){const n=(0,a.parseItem)(i.content,e.cramMappedSliceHeader.parser,0,t._endPosition);return Object.assign(Object.assign({},i),{parsedContent:n})}if("UNMAPPED_SLICE_HEADER"===i.contentType){const n=(0,a.parseItem)(i.content,e.cramUnmappedSliceHeader.parser,0,t._endPosition);return Object.assign(Object.assign({},i),{parsedContent:n})}throw new r.CramMalformedError(`error reading slice header block, invalid content type ${i.contentType}`)}))}getBlocks(){return n(this,void 0,void 0,(function*(){const e=yield this.getHeader();let t=e._endPosition;const i=new Array(e.parsedContent.numBlocks);for(let e=0;e{"EXTERNAL_DATA"===e.contentType&&(t[e.contentId]=e)})),t}))}getBlockByContentId(e){return n(this,void 0,void 0,(function*(){return(yield this._getBlocksContentIdIndex())[e]}))}getReferenceRegion(){return n(this,void 0,void 0,(function*(){const e=(yield this.getHeader()).parsedContent;if(!(0,h.isMappedSliceHeader)(e))throw new Error;if(e.refSeqId<0)return;const t=yield this.container.getCompressionScheme();if(void 0===t)throw new Error;if(e.refBaseBlockId>=0){const t=yield this.getBlockByContentId(e.refBaseBlockId);if(!t)throw new r.CramMalformedError("embedded reference specified, but reference block does not exist");return{seq:t.data.toString("utf8"),start:e.refSeqStart,end:e.refSeqStart+e.refSeqSpan-1,span:e.refSeqSpan}}if(t.referenceRequired||this.file.fetchReferenceSequenceCallback){if(!this.file.fetchReferenceSequenceCallback)throw new Error("reference sequence not embedded, and seqFetch callback not provided, cannot fetch reference sequence");const t=yield this.file.fetchReferenceSequenceCallback(e.refSeqId,e.refSeqStart,e.refSeqStart+e.refSeqSpan-1);if(t.length!==e.refSeqSpan)throw new r.CramArgumentError("seqFetch callback returned a reference sequence of the wrong length");return{seq:t,start:e.refSeqStart,end:e.refSeqStart+e.refSeqSpan-1,span:e.refSeqSpan}}}))}getAllRecords(){return this.getRecords((()=>!0))}_fetchRecords(){return n(this,void 0,void 0,(function*(){const{majorVersion:e}=yield this.file.getDefinition(),t=yield this.container.getCompressionScheme();if(void 0===t)throw new Error;const i=yield this.getHeader();if(void 0===i)throw new Error;const n=yield this._getBlocksContentIdIndex();if(e>1&&this.file.options.checkSequenceMD5&&(0,h.isMappedSliceHeader)(i.parsedContent)&&i.parsedContent.refSeqId>=0&&"0000000000000000"!==i.parsedContent.md5.join("")){const e=yield this.getReferenceRegion();if(e){const{seq:t,start:n,end:o}=e,s=(0,a.sequenceMD5)(t),c=i.parsedContent.md5.map((e=>(e<16?"0":"")+e.toString(16))).join("");if(s!==c)throw new r.CramMalformedError(`MD5 checksum reference mismatch for ref ${i.parsedContent.refSeqId} pos ${n}..${o}. recorded MD5: ${c}, calculated MD5: ${s}`)}}const o=yield this.getCoreDataBlock(),s={lastAlignmentStart:(0,h.isMappedSliceHeader)(i.parsedContent)?i.parsedContent.refSeqStart:0,coreBlock:{bitPosition:7,bytePosition:0},externalBlocks:{map:new Map,getCursor(e){let t=this.map.get(e);return void 0===t&&(t={bitPosition:7,bytePosition:0},this.map.set(e,t)),t}}},u=e=>{const i=t.getCodecForDataSeries(e);if(!i)throw new r.CramMalformedError(`no codec defined for ${e} data series`);return i.decode(this,o,n,s)};let p=new Array(i.parsedContent.numRecords);for(let r=0;r!!e));break}throw e}for(let e=0;e=0&&f(p,e,p[e],p[t])}return p}))}getRecords(e){return n(this,void 0,void 0,(function*(){const t=this.container.filePosition+this.containerPosition;let i=this.file.featureCache.get(t.toString());i||(i=this._fetchRecords(),this.file.featureCache.set(t.toString(),i));const o=(yield i).filter(e);if(o.length&&this.file.fetchReferenceSequenceCallback){const e=yield this.getHeader();if((0,h.isMappedSliceHeader)(e.parsedContent)&&(e.parsedContent.refSeqId>=0||-2===e.parsedContent.refSeqId)){const t=e.parsedContent.refSeqId>=0?e.parsedContent.refSeqId:void 0,i=yield this.container.getCompressionScheme();if(void 0===i)throw new Error;const r={};for(let e=0;en.end&&(n.end=a),o[e].alignmentStartn(this,void 0,void 0,(function*(){-1!==e.id&&e.start<=e.end&&(e.seq=yield this.file.fetchReferenceSequenceCallback(e.id,e.start,e.end))})))));for(let e=0;e(0,a.tinyMemoize)(u,e)))},9488:function(e,t,i){var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0}),t.sequenceMD5=t.tinyMemoize=t.parseItem=t.parseItf8=t.itf8Size=void 0;const o=n(i(2568)),r=i(1074);t.itf8Size=function(e){return-128&e?-16384&e?-2097152&e?-268435456&e?5:4:3:2:1},t.parseItf8=function(e,t){let i=t;const n=e[i];let o;if(n<128?(o=n,i+=1):n<192?(o=16383&(n<<8|e[i+1]),i+=2):n<224?(o=2097151&(n<<16|e[i+1]<<8|e[i+2]),i+=3):n<240?(o=268435455&(n<<24|e[i+1]<<16|e[i+2]<<8|e[i+3]),i+=4):(o=(15&n)<<28|e[i+1]<<20|e[i+2]<<12|e[i+3]<<4|15&e[i+4],i+=5),i>e.length)throw new r.CramBufferOverrunError("Attempted to read beyond end of buffer; this file seems truncated.");return[o,i-t]},t.parseItem=function(e,t,i=0,n=0){const{offset:o,result:r}=t.parse(e);return Object.assign(Object.assign({},r),{_endPosition:o+n,_size:o-i})},t.tinyMemoize=function(e,t){const i=e.prototype[t],n=`_memo_${t}`;e.prototype[t]=function(){if(!(n in this)){const e=i.call(this);this[n]=e,Promise.resolve(e).catch((()=>{delete this[n]}))}return this[n]}},t.sequenceMD5=function(e){return(0,o.default)(e.toUpperCase().replace(/[^\x21-\x7e]/g,""))}},8577:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.CramArgumentError=t.CramSizeLimitError=t.CramMalformedError=t.CramUnimplementedError=t.CramError=void 0;class i extends Error{}t.CramError=i;class n extends Error{}t.CramUnimplementedError=n,t.CramMalformedError=class extends i{},t.CramSizeLimitError=class extends i{},t.CramArgumentError=class extends i{}},5590:function(e,t,i){var n=this&&this.__createBinding||(Object.create?function(e,t,i,n){void 0===n&&(n=i);var o=Object.getOwnPropertyDescriptor(t,i);o&&!("get"in o?!t.__esModule:o.writable||o.configurable)||(o={enumerable:!0,get:function(){return t[i]}}),Object.defineProperty(e,n,o)}:function(e,t,i,n){void 0===n&&(n=i),e[n]=t[i]}),o=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),r=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var i in e)"default"!==i&&Object.prototype.hasOwnProperty.call(e,i)&&n(t,e,i);return o(t,e),t},a=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0}),t.CramRecord=t.CraiIndex=t.IndexedCramFile=t.CramFile=void 0;const s=r(i(8222));t.CramFile=s.default,Object.defineProperty(t,"CramRecord",{enumerable:!0,get:function(){return s.CramRecord}});const c=a(i(946));t.IndexedCramFile=c.default;const l=a(i(368));t.CraiIndex=l.default},946:function(e,t,i){var n=this&&this.__awaiter||function(e,t,i,n){return new(i||(i=Promise))((function(o,r){function a(e){try{c(n.next(e))}catch(e){r(e)}}function s(e){try{c(n.throw(e))}catch(e){r(e)}}function c(e){var t;e.done?o(e.value):(t=e.value,t instanceof i?t:new i((function(e){e(t)}))).then(a,s)}c((n=n.apply(e,t||[])).next())}))},o=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const r=i(8577),a=o(i(8222));t.default=class{constructor(e){if(e.cram?this.cram=e.cram:this.cram=new a.default({url:e.cramUrl,path:e.cramPath,filehandle:e.cramFilehandle,seqFetch:e.seqFetch,checkSequenceMD5:e.checkSequenceMD5,cacheSize:e.cacheSize}),!(this.cram instanceof a.default))throw new Error("invalid arguments: no cramfile");if(this.index=e.index,!this.index.getEntriesForRange)throw new Error("invalid arguments: not an index");this.fetchSizeLimit=e.fetchSizeLimit||3e6}getRecordsForRange(e,t,i,o={}){return n(this,void 0,void 0,(function*(){if(o.viewAsPairs=o.viewAsPairs||!1,o.pairAcrossChr=o.pairAcrossChr||!1,o.maxInsertSize=o.maxInsertSize||2e5,"string"==typeof e)throw new r.CramUnimplementedError("string sequence names not yet supported");const n=e,a=yield this.index.getEntriesForRange(n,t,i),s=a.map((e=>e.sliceBytes)).reduce(((e,t)=>e+t),0);if(s>this.fetchSizeLimit)throw new r.CramSizeLimitError(`data size of ${s.toLocaleString()} bytes exceeded fetch size limit of ${this.fetchSizeLimit.toLocaleString()} bytes`);const c=n=>n.sequenceId===e&&n.alignmentStart<=i&&void 0!==n.lengthOnRef&&n.alignmentStart+n.lengthOnRef-1>=t,l=yield Promise.all(a.map((e=>this.getRecordsInSlice(e,c))));let h=Array.prototype.concat(...l);if(o.viewAsPairs){const e={},t={};for(let i=0;i{1===t&&(i[e]=!0)}));const r=[];for(let e=0;ee.toString().localeCompare(t.toString()))).filter(((e,t,i)=>!t||e.toString()!==i[t-1].toString()));const c=[],l=s.map((e=>e.sliceBytes)).reduce(((e,t)=>e+t),0);if(l>this.fetchSizeLimit)throw new Error(`mate data size of ${l.toLocaleString()} bytes exceeded fetch size limit of ${this.fetchSizeLimit.toLocaleString()} bytes`);s.forEach((e=>{let n=this.cram.featureCache.get(e.toString());n||(n=this.getRecordsInSlice(e,(()=>!0)),this.cram.featureCache.set(e.toString(),n));const o=n.then((e=>{const n=[];for(let o=0;oe.concat(t)));h=h.concat(e)}}return h}))}getRecordsInSlice({containerStart:e,sliceStart:t,sliceBytes:i},n){return this.cram.getContainerAtPosition(e).getSlice(t,i).getRecords(n)}hasDataForReferenceSequence(e){return this.index.hasDataForReferenceSequence(e)}}},3427:function(e,t,i){var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0}),t.open=t.fromUrl=t.RemoteFile=t.LocalFile=void 0;const o=n(i(8575)),r=i(4319),a=i(2949);function s(e){const{protocol:t,pathname:i}=o.default.parse(e);return"file:"===t?new a.LocalFile(unescape((0,r.ensureNotNullish)(i))):new a.RemoteFile(e)}Object.defineProperty(t,"LocalFile",{enumerable:!0,get:function(){return a.LocalFile}}),Object.defineProperty(t,"RemoteFile",{enumerable:!0,get:function(){return a.RemoteFile}}),t.fromUrl=s,t.open=function(e,t,i){if(i)return i;if(e)return s(e);if(t)return new a.LocalFile(t);throw new Error("no url, path, or filehandle provided, cannot open")}},5702:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.RANS_BYTE_L=t.TOTFREQ=t.TF_SHIFT=void 0,t.TF_SHIFT=12,t.TOTFREQ=4096,t.RANS_BYTE_L=1<<23},6484:function(e,t,i){var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const o=i(8577),r=i(5702),a=n(i(7634));t.default=function(e,t,i,n){let s=e.getInt(),c=e.getInt(),l=e.getInt(),h=e.getInt();const d=n.remaining(),f=-4&d;for(let o=0;o>2;let f=0,u=d,p=2*d,m=3*d,g=0,w=0,F=0,b=0;for(;f{Object.defineProperty(t,"__esModule",{value:!0});const n=i(8577),o=i(5702);class r{constructor(){this.F=void 0,this.C=void 0}}function a(e,t,i,n){return i*(e>>n)+(e&(1<>r)+(e&(1<=128&&(t.fc[c].F&=-129,t.fc[c].F=(127&t.fc[c].F)<<8|255&e.get()),t.fc[c].C=o,a.default.symbolInit(i[c],t.fc[c].C,t.fc[c].F),t.R||(t.R=new Array(r.TOTFREQ)),t.R.fill(c,o,o+t.fc[c].F),o+=t.fc[c].F,0===n&&c+1===(255&e.getByteAt(e.position()))?(c=255&e.get(),n=255&e.get()):0!==n?(n-=1,c+=1):c=255&e.get()}while(0!==c);s(o=128&&(t[o].fc[h].F&=-129,t[o].fc[h].F=(127&t[o].fc[h].F)<<8|255&e.get()),t[o].fc[h].C=l,0===t[o].fc[h].F&&(t[o].fc[h].F=r.TOTFREQ),null==i[o][h]&&(i[o][h]=new a.default.RansDecSymbol),a.default.symbolInit(i[o][h],t[o].fc[h].C,t[o].fc[h].F),null==t[o].R&&(t[o].R=new Array(r.TOTFREQ)),t[o].R.fill(h,l,l+t[o].fc[h].F),l+=t[o].fc[h].F,s(l<=r.TOTFREQ),0===c&&h+1===(255&e.getByteAt(e.position()))?(h=255&e.get(),c=255&e.get()):0!==c?(c-=1,h+=1):h=255&e.get()}while(0!==h);0===n&&o+1===(255&e.getByteAt(e.position()))?(o=255&e.get(),n=255&e.get()):0!==n?(n-=1,o+=1):o=255&e.get()}while(0!==o)}},9675:function(e,t,i){var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const o=i(8577),r=n(i(7634)),a=i(696),s=n(i(6484)),c=n(i(7121));class l{constructor(e,t=0){this._buffer=e,this._position=t,this.length=e.length}get(){const e=this._buffer[this._position];return this._position+=1,e}getByte(){return this.get()}getByteAt(e){return this._buffer[e]}position(){return this._position}put(e){return this._buffer[this._position]=e,this._position+=1,e}putAt(e,t){return this._buffer[e]=t,t}setPosition(e){return this._position=e,e}getInt(){const e=this._buffer.readInt32LE(this._position);return this._position+=4,e}remaining(){return this._buffer.length-this._position}}t.default=function(e,t,i=0){if(0===e.length)return t.fill(0),t;const n=new l(e,i),h=n.get();if(0!==h&&1!==h)throw new o.CramMalformedError(`Invalid rANS order ${h}`);if(n.getInt()!==n.remaining()-4)throw new o.CramMalformedError("Incorrect input length.");const d=n.getInt(),f=new l(t||Buffer.allocUnsafe(d));if(f.length{Object.defineProperty(t,"__esModule",{value:!0}),t.parseHeaderText=void 0,t.parseHeaderText=function(e){const t=e.split(/\r?\n/),i=[];return t.forEach((e=>{const[t,...n]=e.split(/\t/),o=n.map((e=>{const[t,i]=e.split(":",2);return{tag:t,value:i}}));t&&i.push({tag:t.substr(1),data:o})})),i}},4319:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.ensureNotNullish=void 0,t.ensureNotNullish=function(e){if(null==e)throw new Error("Value must not be nullish.");return e}},597:(e,t,i)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.unzip=void 0;const n=i(9591);t.unzip=function(e){return Buffer.from((0,n.inflate)(e))}},9996:(e,t,i)=>{function n(e){return n="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},n(e)}var o=i(8764).Buffer,r=i(22),a=i(2961)._,s=i(3720);"undefined"!=typeof window&&(window.Buffer=o),"undefined"!=typeof self&&(self.Buffer=o);var c={UInt8:1,UInt16LE:2,UInt16BE:2,UInt32LE:4,UInt32BE:4,Int8:1,Int16LE:2,Int16BE:2,Int32LE:4,Int32BE:4,FloatLE:4,FloatBE:4,DoubleLE:8,DoubleBE:8,UInt64:8,Int64:8},l={},h="___parser_",d=[];!function(){var e;for(e=1;e<=32;e++)d.push(e)}();var f={};Object.keys(c).concat(Object.keys({String:null,Buffer:null,Array:null,Skip:null,Choice:null,Nest:null,Bit:null,Itf8:null,Ltf8:null})).forEach((function(e){f[e.toLowerCase()]=e}));var u=function(){this.varName="",this.type="",this.options={},this.next=null,this.head=null,this.compiled=null,this.endian="le",this.constructorFn=null,this.alias=null};u.start=function(){return new u},Object.keys(c).forEach((function(e){u.prototype[e.toLowerCase()]=function(t,i){return this.setNextParser(e.toLowerCase(),t,i)};var t=e.replace(/BE|LE/,"").toLowerCase();t in u.prototype||(u.prototype[t]=function(e,i){return this[t+this.endian](e,i)})})),d.forEach((function(e){u.prototype["bit".concat(e.toString())]=function(t,i){return i||(i={}),i.length=e,this.setNextParser("bit",t,i)}})),u.prototype.namely=function(e){return l[e]=this,this.alias=e,this},u.prototype.skip=function(e,t){if(t&&t.assert)throw new Error("assert option on skip is not allowed.");return this.setNextParser("skip","",{length:e})},u.prototype.string=function(e,t){if(!t.zeroTerminated&&!t.length&&!t.greedy)throw new Error("Neither length, zeroTerminated, nor greedy is defined for string.");if((t.zeroTerminated||t.length)&&t.greedy)throw new Error("greedy is mutually exclusive with length and zeroTerminated for string.");if(t.stripNull&&!t.length&&!t.greedy)throw new Error("Length or greedy must be defined if stripNull is defined.");return t.encoding=t.encoding||"utf8",this.setNextParser("string",e,t)},u.prototype.buffer=function(e,t){if(!t.length&&!t.readUntil)throw new Error("Length nor readUntil is defined in buffer parser");return this.setNextParser("buffer",e,t)},u.prototype.array=function(e,t){if(!t.readUntil&&!t.length&&!t.lengthInBytes)throw new Error("Length option of array is not defined.");if(!t.type)throw new Error("Type option of array is not defined.");if("string"==typeof t.type&&!l[t.type]&&Object.keys(c).indexOf(f[t.type])<0)throw new Error('Specified primitive type "'.concat(t.type,'" is not supported.'));return this.setNextParser("array",e,t)},u.prototype.choice=function(e,t){if(1===arguments.length&&"object"===n(e)&&(t=e,e=null),!t.tag)throw new Error("Tag option of array is not defined.");if(!t.choices)throw new Error("Choices option of array is not defined.");return Object.keys(t.choices).forEach((function(i){if(!t.choices[i])throw new Error("Choice Case ".concat(i," of ").concat(e," is not valid."));if("string"==typeof t.choices[i]&&!l[t.choices[i]]&&Object.keys(c).indexOf(f[t.choices[i]])<0)throw new Error('Specified primitive type "'.concat(t.choices[i],'" is not supported.'))}),this),this.setNextParser("choice",e,t)},u.prototype.nest=function(e,t){if(1===arguments.length&&"object"===n(e)&&(t=e,e=null),!t.type)throw new Error("Type option of nest is not defined.");if(!(t.type instanceof u||l[t.type]))throw new Error("Type option of nest must be a Parser object.");if(!(t.type instanceof u||e))throw new Error("options.type must be a object if variable name is omitted.");return this.setNextParser("nest",e,t)},u.prototype.endianess=function(e){switch(e.toLowerCase()){case"little":this.endian="le";break;case"big":this.endian="be";break;default:throw new Error("Invalid endianess: ".concat(e))}return this},u.prototype.create=function(e){if(!(e instanceof Function))throw new Error("Constructor must be a Function object.");return this.constructorFn=e,this},u.prototype.getCode=function(){var e=new a;return e.pushCode("if (!Buffer.isBuffer(buffer)) {"),e.generateError('"argument buffer is not a Buffer object"'),e.pushCode("}"),this.alias?this.addAliasedCode(e):this.addRawCode(e),this.alias?e.pushCode("return {0}(0)",h+this.alias):e.pushCode("return { offset: offset, result: vars };"),e.code},u.prototype.addRawCode=function(e){e.pushCode("var offset = 0;"),this.constructorFn?e.pushCode("var vars = new constructorFn();"):e.pushCode("var vars = {};"),this.generate(e),this.resolveReferences(e),e.pushCode("return { offset: offset, result: vars };")},u.prototype.addAliasedCode=function(e){return e.pushCode("function {0}(offset) {",h+this.alias),this.constructorFn?e.pushCode("var vars = new constructorFn();"):e.pushCode("var vars = {};"),this.generate(e),e.markResolved(this.alias),this.resolveReferences(e),e.pushCode("return { offset: offset, result: vars };"),e.pushCode("}"),e},u.prototype.resolveReferences=function(e){var t=e.getUnresolvedReferences();e.markRequested(t),t.forEach((function(t){l[t].addAliasedCode(e)}))},u.prototype.compile=function(){var e="(function(buffer, constructorFn, Long) { ".concat(this.getCode()," })");this.compiled=r.runInThisContext(e)},u.prototype.sizeOf=function(){var e=NaN;if(Object.keys(c).indexOf(this.type)>=0)e=c[this.type];else if("String"===this.type&&"number"==typeof this.options.length)e=this.options.length;else if("Buffer"===this.type&&"number"==typeof this.options.length)e=this.options.length;else if("Array"===this.type&&"number"==typeof this.options.length){var t=NaN;"string"==typeof this.options.type?t=c[f[this.options.type]]:this.options.type instanceof u&&(t=this.options.type.sizeOf()),e=this.options.length*t}else"Skip"===this.type?e=this.options.length:"Nest"===this.type?e=this.options.type.sizeOf():this.type||(e=0);return this.next&&(e+=this.next.sizeOf()),e},u.prototype.parse=function(e){return this.compiled||this.compile(),this.compiled(e,this.constructorFn,s)},u.prototype.setNextParser=function(e,t,i){var n=new u;return n.type=f[e],n.varName=t,n.options=i||n.options,n.endian=this.endian,this.head?this.head.next=n:this.next=n,this.head=n,this},u.prototype.generate=function(e){this.type&&(this["generate".concat(this.type)](e),this.generateAssert(e));var t=e.generateVariable(this.varName);return this.options.formatter&&this.generateFormatter(e,t,this.options.formatter),this.generateNext(e)},u.prototype.generateAssert=function(e){if(this.options.assert){var t=e.generateVariable(this.varName);switch(n(this.options.assert)){case"function":e.pushCode("if (!({0}).call(vars, {1})) {",this.options.assert,t);break;case"number":e.pushCode("if ({0} !== {1}) {",this.options.assert,t);break;case"string":e.pushCode('if ("{0}" !== {1}) {',this.options.assert,t);break;default:throw new Error("Assert option supports only strings, numbers and assert functions.")}e.generateError('"Assert error: {0} is " + {0}',t),e.pushCode("}")}},u.prototype.generateNext=function(e){return this.next&&(e=this.next.generate(e)),e},Object.keys(c).forEach((function(e){u.prototype["generate".concat(e)]=function(t){"UInt64"===e?t.pushCode("{0} = Long.fromBytes(buffer.slice(offset,offset+8), true, this.endian === 'le').toNumber();",t.generateVariable(this.varName),e):"Int64"===e?t.pushCode("{0} = Long.fromBytes(buffer.slice(offset,offset+8), false, this.endian === 'le').toNumber();",t.generateVariable(this.varName),e):t.pushCode("{0} = buffer.read{1}(offset);",t.generateVariable(this.varName),e),t.pushCode("offset += {0};",c[e])}})),u.prototype.generateBit=function(e){var t=JSON.parse(JSON.stringify(this));if(t.varName=e.generateVariable(t.varName),e.bitFields.push(t),!this.next||this.next&&["Bit","Nest"].indexOf(this.next.type)<0){var i=0;e.bitFields.forEach((function(e){i+=e.options.length}));var n=e.generateTmpVariable();if(i<=8)e.pushCode("var {0} = buffer.readUInt8(offset);",n),i=8;else if(i<=16)e.pushCode("var {0} = buffer.readUInt16BE(offset);",n),i=16;else if(i<=24){var o=e.generateTmpVariable(),r=e.generateTmpVariable();e.pushCode("var {0} = buffer.readUInt16BE(offset);",o),e.pushCode("var {0} = buffer.readUInt8(offset + 2);",r),e.pushCode("var {2} = ({0} << 8) | {1};",o,r,n),i=24}else{if(!(i<=32))throw new Error("Currently, bit field sequence longer than 4-bytes is not supported.");e.pushCode("var {0} = buffer.readUInt32BE(offset);",n),i=32}e.pushCode("offset += {0};",i/8);var a=0,s="be"===this.endian;e.bitFields.forEach((function(t){e.pushCode("{0} = {1} >> {2} & {3};",t.varName,n,s?i-a-t.options.length:a,(1< offset++);"),e.pushCode("{0} = buffer.toString('{1}', {2}, offset);",t,this.options.encoding,i)),this.options.stripNull&&e.pushCode("{0} = {0}.replace(/\\x00+$/g, '')",t)},u.prototype.generateBuffer=function(e){"eof"===this.options.readUntil?e.pushCode("{0} = buffer.slice(offset);",e.generateVariable(this.varName)):(e.pushCode("{0} = buffer.slice(offset, offset + {1});",e.generateVariable(this.varName),e.generateOption(this.options.length)),e.pushCode("offset += {0};",e.generateOption(this.options.length))),this.options.clone&&e.pushCode("{0} = Buffer.from({0});",e.generateVariable(this.varName))},u.prototype.generateArray=function(e){var t=e.generateOption(this.options.length),i=e.generateOption(this.options.lengthInBytes),n=this.options.type,o=e.generateTmpVariable(),r=e.generateVariable(this.varName),a=e.generateTmpVariable(),s=this.options.key,d="string"==typeof s;if(d?e.pushCode("{0} = {};",r):e.pushCode("{0} = [];",r),"function"==typeof this.options.readUntil?e.pushCode("do {"):"eof"===this.options.readUntil?e.pushCode("for (var {0} = 0; offset < buffer.length; {0}++) {",o):void 0!==i?e.pushCode("for (var {0} = offset; offset - {0} < {1}; ) {",o,i):e.pushCode("for (var {0} = 0; {0} < {1}; {0}++) {",o,t),"string"==typeof n)if(l[n]){var p=e.generateTmpVariable();e.pushCode("var {0} = {1}(offset);",p,h+n),e.pushCode("var {0} = {1}.result; offset = {1}.offset;",a,p),n!==this.alias&&e.addReference(n)}else e.pushCode("var {0} = buffer.read{1}(offset);",a,f[n]),e.pushCode("offset += {0};",c[f[n]]);else n instanceof u&&(e.pushCode("var {0} = {};",a),e.pushScope(a),n.generate(e),e.popScope());d?e.pushCode("{0}[{2}.{1}] = {2};",r,s,a):e.pushCode("{0}.push({1});",r,a),e.pushCode("}"),"function"==typeof this.options.readUntil&&e.pushCode(" while (!({0}).call(this, {1}, buffer.slice(offset)));",this.options.readUntil,a)},u.prototype.generateChoiceCase=function(e,t,i){if("string"==typeof i)if(l[i]){var n=e.generateTmpVariable();e.pushCode("var {0} = {1}(offset);",n,h+i),e.pushCode("{0} = {1}.result; offset = {1}.offset;",e.generateVariable(this.varName),n),i!==this.alias&&e.addReference(i)}else e.pushCode("{0} = buffer.read{1}(offset);",e.generateVariable(this.varName),f[i]),e.pushCode("offset += {0};",c[f[i]]);else i instanceof u&&(e.pushPath(t),i.generate(e),e.popPath(t))},u.prototype.generateChoice=function(e){var t=e.generateOption(this.options.tag);this.varName&&e.pushCode("{0} = {};",e.generateVariable(this.varName)),e.pushCode("switch({0}) {",t),Object.keys(this.options.choices).forEach((function(t){var i=this.options.choices[t];Number.isNaN(parseInt(t,10))?e.pushCode("case '{0}':",t):e.pushCode("case {0}:",t),this.generateChoiceCase(e,this.varName,i),e.pushCode("break;")}),this),e.pushCode("default:"),this.options.defaultChoice?this.generateChoiceCase(e,this.varName,this.options.defaultChoice):e.generateError('"Met undefined tag value " + {0} + " at choice"',t),e.pushCode("}")},u.prototype.generateNest=function(e){var t=e.generateVariable(this.varName);if(this.options.type instanceof u)this.varName&&e.pushCode("{0} = {};",t),e.pushPath(this.varName),this.options.type.generate(e),e.popPath(this.varName);else if(l[this.options.type]){var i=e.generateTmpVariable();e.pushCode("var {0} = {1}(offset);",i,h+this.options.type),e.pushCode("{0} = {1}.result; offset = {1}.offset;",t,i),this.options.type!==this.alias&&e.addReference(this.options.type)}},u.prototype.generateFormatter=function(e,t,i){"function"==typeof i&&e.pushCode("{0} = ({1}).call(this, {0});",t,i)},u.prototype.isInteger=function(){return!!this.type.match(/U?Int[8|16|32][BE|LE]?|Bit\d+/)},u.prototype.itf8=function(e,t){return this.setNextParser("itf8",e,t)},u.prototype.itf8=function(e,t){return this.setNextParser("itf8",e,t)},u.prototype.generateItf8=function(e){var t=e.generateVariable(this.varName),i=e.generateTmpVariable();e.pushCode("\n var ".concat(i," = buffer[offset];\n if (").concat(i," < 0x80) {\n ").concat(t," = ").concat(i,";\n offset += 1;\n } else if (").concat(i," < 0xc0) {\n ").concat(t," = ((").concat(i,"<<8) | buffer[offset+1]) & 0x3fff;\n offset += 2;\n } else if (").concat(i," < 0xe0) {\n ").concat(t," = ((").concat(i,"<<16) | (buffer[offset+1]<< 8) | buffer[offset+2]) & 0x1fffff;\n offset += 3;\n } else if (").concat(i," < 0xf0) {\n ").concat(t," = ((").concat(i,"<<24) | (buffer[offset+1]<<16) | (buffer[offset+2]<<8) | buffer[offset+3]) & 0x0fffffff;\n offset += 4\n } else {\n ").concat(t," = ((").concat(i," & 0x0f)<<28) | (buffer[offset+1]<<20) | (buffer[offset+2]<<12) | (buffer[offset+3]<<4) | (buffer[offset+4] & 0x0f);\n // x=((0xff & 0x0f)<<28) | (0xff<<20) | (0xff<<12) | (0xff<<4) | (0x0f & 0x0f);\n // TODO *val_p = uv < 0x80000000UL ? uv : -((int32_t) (0xffffffffUL - uv)) - 1;\n offset += 5\n }\n "))},u.prototype.ltf8=function(e,t){return this.setNextParser("ltf8",e,t)},u.prototype.generateLtf8=function(e){var t=e.generateVariable(this.varName),i=e.generateTmpVariable();e.pushCode("\n var ".concat(i," = buffer[offset];\n if (").concat(i," < 0x80) {\n ").concat(t," = ").concat(i,";\n offset += 1;\n } else if (").concat(i," < 0xc0) {\n ").concat(t," = ((buffer[offset]<<8) | buffer[offset+1]) & 0x3fff;\n offset += 2;\n } else if (").concat(i," < 0xe0) {\n ").concat(t," = ((buffer[offset]<<16) | (buffer[offset+1]<<8) | buffer[offset+2]) & 0x1fffff;\n ").concat(t," = (((").concat(i," & 63) << 16) | buffer.readUInt16LE(offset + 1));\n offset += 3;\n } else if (").concat(i," < 0xf0) {\n ").concat(t," = ((buffer[offset]<<24) | (buffer[offset+1]<<16) | (buffer[offset+2]<<8) | buffer[offset+3]) & 0x0fffffff;\n offset += 4;\n } else if (").concat(i," < 0xf8) {\n ").concat(t," = (((buffer[offset] & 15) * Math.pow(2,32))) +\n (buffer[offset+1]<<24) | (buffer[offset+2]<<16 | buffer[offset+3]<<8 | buffer[offset+4])\n // TODO *val_p = uv < 0x80000000UL ? uv : -((int32_t) (0xffffffffUL - uv)) - 1;\n offset += 5;\n } else if (").concat(i," < 0xfc) {\n ").concat(t," = ((((buffer[offset] & 7) << 8) | buffer[offset+1] )) * Math.pow(2,32) +\n (buffer[offset+2]<<24) | (buffer[offset+3]<<16 | buffer[offset+4]<<8 | buffer[offset+5])\n offset += 6;\n } else if (").concat(i," < 0xfe) {\n ").concat(t," = ((((buffer[offset] & 3) << 16) | buffer[offset+1]<<8 | buffer[offset+2])) * Math.pow(2,32) +\n (buffer[offset+3]<<24) | (buffer[offset+4]<<16 | buffer[offset+5]<<8 | buffer[offset+6])\n offset += 7;\n } else if (").concat(i," < 0xff) {\n ").concat(t," = Long.fromBytesBE(buffer.slice(offset+1,offset+8));\n if (").concat(t,".greaterThan(Number.MAX_SAFE_INTEGER) || ").concat(t,".lessThan(Number.MIN_SAFE_INTEGER))\n throw new Error('integer overflow')\n ").concat(t," = ").concat(t,".toNumber()\n offset += 8;\n } else {\n ").concat(t," = Long.fromBytesBE(buffer.slice(offset+1,offset+9));\n if (").concat(t,".greaterThan(Number.MAX_SAFE_INTEGER) || ").concat(t,".lessThan(Number.MIN_SAFE_INTEGER))\n throw new Error('integer overflow')\n ").concat(t," = ").concat(t,".toNumber()\n offset += 9;\n }\n "))},t.Parser=u},2961:(e,t)=>{function i(e){return i="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},i(e)}var n=function(){this.code="",this.scopes=[["vars"]],this.isAsync=!1,this.bitFields=[],this.tmpVariableCount=0,this.references={}};n.prototype.generateVariable=function(e){var t=[];for(Array.prototype.push.apply(t,this.scopes[this.scopes.length-1]);/^\$parent\./.test(e);)t.pop(),e=e.replace(/^\$parent\./,"");return e&&t.push(e),t.join(".")},n.prototype.generateOption=function(e){switch(i(e)){case"number":return e.toString();case"string":return this.generateVariable(e);case"function":return"(".concat(e,").call(").concat(this.generateVariable(),", vars)");default:return}},n.prototype.generateError=function(){var e=Array.prototype.slice.call(arguments),t=n.interpolate.apply(this,e);this.isAsync?this.pushCode("return process.nextTick(function() { callback(new Error(".concat(t,"), vars); });")):this.pushCode("throw new Error(".concat(t,");"))},n.prototype.generateTmpVariable=function(){return"$tmp".concat(this.tmpVariableCount++)},n.prototype.pushCode=function(){var e=Array.prototype.slice.call(arguments);this.code+="".concat(n.interpolate.apply(this,e),"\n")},n.prototype.pushPath=function(e){e&&this.scopes[this.scopes.length-1].push(e)},n.prototype.popPath=function(e){e&&this.scopes[this.scopes.length-1].pop()},n.prototype.pushScope=function(e){this.scopes.push([e])},n.prototype.popScope=function(){this.scopes.pop()},n.prototype.addReference=function(e){this.references[e]||(this.references[e]={resolved:!1,requested:!1})},n.prototype.markResolved=function(e){this.references[e].resolved=!0},n.prototype.markRequested=function(e){e.forEach(function(e){this.references[e].requested=!0}.bind(this))},n.prototype.getUnresolvedReferences=function(){var e=this.references;return Object.keys(this.references).filter((function(t){return!e[t].resolved&&!e[t].requested}))},n.interpolate=function(e){var t=e.match(/{\d+}/g),i=Array.prototype.slice.call(arguments,1);return t&&t.forEach((function(t){var n=parseInt(t.substr(1,t.length-2),10);e=e.replace(t,i[n].toString())})),e},t._=n},22:e=>{e.exports.runInThisContext=function(e){return new Function("code","return eval(code);").call(globalThis,e)}},445:(e,t,i)=>{const n=i(7381),o=i(9260),r=i(576),a=i(4693),s=128;e.exports=class{decode(e){return this.stream=new o(e),this.decodeStream(this.stream)}decodeStream(e,t=0){var i=this.stream.ReadByte();16&i||(t=this.stream.ReadUint7());var n,o=t,r=1&i;if(8&i)return this.decodeStripe(this.stream,t);if(i&s&&([n,o]=this.decodePackMeta(this.stream)),32&i)var a=this.decodeCat(this.stream,o);else a=4&i?this.decodeExt(this.stream,o):64&i?r?this.decodeRLE1(this.stream,o):this.decodeRLE0(this.stream,o):r?this.decode1(this.stream,o):this.decode0(this.stream,o);return i&s&&(a=this.decodePack(a,n,t)),a}encode(e,t){if(this.stream=new o("",0,1.1*e.length+100),this.stream.WriteByte(t),16&t||this.stream.WriteUint7(e.length),8&t)return Buffer.concat([this.stream.buf.slice(0,this.stream.pos),this.encodeStripe(this.stream,e,t>>8)]);var i,n=1&t,r=e.length;return t&s&&([i,e,r]=this.encodePack(e)),t&s&&this.stream.WriteStream(i),64&t?n?this.encodeRLE1(e,r,this.stream):this.encodeRLE0(e,r,this.stream):n?this.encode1(e,r,this.stream):this.encode0(e,r,this.stream)}decode0(e,t){var i=new Buffer.allocUnsafe(t),o=e.ReadByte();0==o&&(o=256);var a=new r(o),s=new n(e);s.RangeStartDecode(e);for(var c=0;c=3?3:h;for(c[d].ModelEncode(i,l,f),h-=f,d=256;3==f;)f=h>=3?3:h,c[d].ModelEncode(i,l,f),d=257,h-=f}return l.RangeFinishEncode(i),i.buf.slice(0,i.pos)}decodeRLE1(e,t){var i=new Buffer.allocUnsafe(t),o=e.ReadByte();0==o&&(o=256);for(var a=new Array(o),s=0;s=3?3:d;for(c[f].ModelEncode(i,l,u),d-=u,f=256;3==u;)u=d>=3?3:d,c[f].ModelEncode(i,l,u),f=257,d-=u}return l.RangeFinishEncode(i),i.buf.slice(0,i.pos)}decodePackMeta(e){this.nsym=e.ReadByte();for(var t=new Array(this.nsym),i=0;i>=1}}else if(this.nsym<=4)for(o=0,r=0;o>=2;else{if(!(this.nsym<=16))return e;for(o=0,r=0;o>=4}return n}packMeta(e){for(var t=new o("",0,1024),i=new Array(256),n=0;na),n[a]=new Array(r[a]);for(var s=0,c=0;cr),a[r]=this.decodeStream(e,o[r]);var s=new Buffer.allocUnsafe(t);for(r=0;r{e.exports=class{constructor(e){this.low=0,this.range=4294967295,this.code=0,this.FFnum=0,this.carry=0,this.cache=0}RangeStartDecode(e){for(var t=0;t<5;t++)this.code=(this.code<<8)+e.ReadByte();this.code&=4294967295,this.code>>>=0}RangeGetFrequency(e){return this.range=Math.floor(this.range/e),Math.floor(this.code/this.range)}RangeDecode(e,t,i,n){for(this.code-=t*this.range,this.range*=i;this.range<1<<24;)this.range*=256,this.code=256*this.code+e.ReadByte()}RangeShiftLow(e){if(this.low<4278190080|this.carry){for(e.WriteByte(this.cache+this.carry);this.FFnum;)e.WriteByte(this.carry-1),this.FFnum--;this.cache=this.low>>>24,this.carry=0}else this.FFnum++;this.low<<=8,this.low>>>=0}RangeEncode(e,t,i,n){var o=this.low;for(this.range=Math.floor(this.range/n),this.low+=t*this.range,this.low>>>=0,this.range*=i,this.low{e.exports=class{constructor(e=256){this.total_freq=e,this.max_sym=e-1,this.S=new Array,this.F=new Array;for(var t=0;t<=this.max_sym;t++)this.S[t]=t,this.F[t]=1}ModelDecode(e,t){for(var i=t.RangeGetFrequency(this.total_freq),n=0,o=0;n+this.F[o]<=i;)n+=this.F[o++];t.RangeDecode(e,n,this.F[o],this.total_freq),this.F[o]+=16,this.total_freq+=16,this.total_freq>65519&&this.ModelRenormalise();var r=this.S[o];if(o>0&&this.F[o]>this.F[o-1]){var a=this.F[o];this.F[o]=this.F[o-1],this.F[o-1]=a,a=this.S[o],this.S[o]=this.S[o-1],this.S[o-1]=a}return r}ModelRenormalise(){this.total_freq=0;for(var e=0;e<=this.max_sym;e++)this.F[e]-=Math.floor(this.F[e]/2),this.total_freq+=this.F[e]}ModelEncode(e,t,i){for(var n=0,o=0;this.S[o]!=i;o++)n+=this.F[o];if(t.RangeEncode(e,n,this.F[o],this.total_freq),this.F[o]+=16,this.total_freq+=16,this.total_freq>65519&&this.ModelRenormalise(),i=this.S[o],o>0&&this.F[o]>this.F[o-1]){var r=this.F[o];this.F[o]=this.F[o-1],this.F[o-1]=r,r=this.S[o],this.S[o]=this.S[o-1],this.S[o-1]=r}}}},5260:(e,t,i)=>{const n=i(9260),o=i(576),r=i(7381);function a(e,t,i){for(var n=0,o=0,r=-1,a=new Array(1024);o>4,t.qshift=15&i,i=e.ReadByte(),t.qloc=i>>4,t.sloc=15&i,i=e.ReadByte(),t.ploc=i>>4,t.dloc=15&i,t.qmap=new Array(256),16&t.pflags)for(var n=0;n0&&128&t.pflags)a(e,t.qtab,256);else for(n=0;n<256;n++)t.qtab[n]=n;return t.ptab=new Array(1024),32&t.pflags&&a(e,t.ptab,1024),t.dtab=new Array(256),64&t.pflags&&a(e,t.dtab,256),t}function l(e,t,i,n,o,r){i.max_sel>0?o.s=n.sel.ModelDecode(e,t):o.s=0,o.x=i.stab[o.s];var a=i.params[o.x];if(a.fixed_len>=0){var s=n.len[0].ModelDecode(e,t);s|=n.len[1].ModelDecode(e,t)<<8,s|=n.len[2].ModelDecode(e,t)<<16,s|=n.len[3].ModelDecode(e,t)<<24,a.fixed_len>0&&(a.fixed_len=-s)}else s=-a.fixed_len;o.len=s,i.do_rev&&(r[o.rec]=n.rev.ModelDecode(e,t)),o.is_dup=0,2&a.pflags&&n.dup.ModelDecode(e,t)&&(o.is_dup=1),o.p=s,o.delta=0,o.qctx=0,o.prevq=0,o.rec++}function h(e,t,i){for(var n=0,o=0,r=new Array(2*i),a=0;n1?i.nparam-1:0,r=new Array(256);if(2&i)o=e.ReadByte(),a(e,r,256);else{for(var s=0;s0&&(t.sel=new o(e.max_sel+1)),t}(n),u=new r(e);u.RangeStartDecode(e);for(var p=new Buffer.allocUnsafe(i),m={qctx:0,prevq:0,delta:0,p:0,s:0,x:0,len:0,is_dup:0,rec:0},g=0;g0&&f.dup.ModelDecode(e,u)){for(var w=0;w4),qshift:d,qloc:7,pbits:7,pshift:t[0]>128?1:0,ploc:0,dbits:d>4?0:1,dshift:3,dloc:15,sbits:0,sloc:15,do_stab:0,context:0,max_sym:c,nsym:s,do_qmap:f,do_dedup:0,fixed_len:1==t.length?1:0,do_sel:0,do_rev:0,do_pos:1,do_delta:d<=4?1:0,do_qtab:0,qbits:8+(d>4)-(0==a),sbits:1,sloc:15-(d<=4),do_stab:1,do_sel:1}]}(e,t,i,a),p=function(e,t,i,n,o,r,a){for(var s=[0,1,1,1,2,2,2,2,2,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7],c=0;c1?1:0)|(t[0].do_stab?2:0);if(e.WriteByte(l),1&l&&e.WriteByte(t.length),2&l){var d=1<0&&d--,e.WriteByte(d),h(e,a,256)}for(var f=0;f0){for(c=0;c<256;c++)n[f][c]=c;t[f].do_qtab&&h(e,n[f],256)}if(t[f].pbits>0){for(c=0;c<1024;c++)o[f][c]=Math.min((1<>t[f].pshift);h(e,o[f],1024)}if(t[f].dbits>0){for(c=0;c<256;c++)s[c]>(1<>t[f].dshift)];h(e,r[f],256)}}return e}(p,u,a,s,c,l,d);return function(e,t,i,n,a,s,c,l,h,d){var f=1<0&&f--;for(var u=t.length,p=0,m=0;m0&&b.ModelEncode(e,v,_);var C=d[_],x=i[Math.min(i.length-1,y++)];a[C].fixed_len?a[C].fixed_len>0&&(F[0].ModelEncode(e,v,255&x),F[1].ModelEncode(e,v,x>>8&255),F[2].ModelEncode(e,v,x>>16&255),F[3].ModelEncode(e,v,x>>24&255),a[C].fixed_len=-1):(F[0].ModelEncode(e,v,255&x),F[1].ModelEncode(e,v,x>>8&255),F[2].ModelEncode(e,v,x>>16&255),F[3].ModelEncode(e,v,x>>24&255)),a[C].do_dedup&&process.exit(1),m=x;var k=0,E=a[C].context,N=0,S=0}var I=t[w++],z=s[C][I];g[E].ModelEncode(e,v,z),N=(N<0&&(E+=l[C][Math.min(m,1023)]<0&&(E+=h[C][Math.min(k,255)]<{var n=i(4459),o=i(594),r=i(445),a=i(5260),s=i(2881);e.exports={r4x8_uncompress:function(e,t){n.decode(e).copy(t,0,0)},r4x16_uncompress:function(e,t){o.decode(e).copy(t,0,0)},arith_uncompress:function(e,t){r.decode(e).copy(t,0,0)},fqzcomp_uncompress:function(e,t){var i=new Array;a.decode(e,i).copy(t,0,0)},tok3_uncompress:function(e,t){var i=s.decode(e,0,"\0");Buffer.from(i,"binary").copy(t,0,0)}}},9260:e=>{e.exports=class{constructor(e,t=0,i=0){0!=i?(this.buf=Buffer.allocUnsafe(i),this.length=i):(this.buf=e,this.length=e.length),this.pos=t}EOF(){return this.pos>=this.length}ReadData(e){var t=this.buf.slice(this.pos,this.pos+e);return this.pos+=e,t}ReadByte(){const e=this.buf[this.pos];return this.pos++,e}ReadChar(){const e=this.buf[this.pos];return this.pos++,String.fromCharCode(e)}ReadUint16(){return this.ReadByte()|this.ReadByte()<<8}ReadUint32(){const e=this.buf.readInt32LE(this.pos);return this.pos+=4,e}ReadString(){var e="";do{var t=this.buf[this.pos++];t&&(e+=String.fromCharCode(t))}while(t);return e}ReadUint7(){var e=0;do{var t=this.ReadByte();e=e<<7|127&t}while(128&t);return e}ReadITF8(){var e=this.buf[this.pos];return this.pos++,e>=240?(e=(15&e)<<28,e+=(this.buf[this.pos+0]<<20)+(this.buf[this.pos+1]<<12)+(this.buf[this.pos+2]<<4)+(this.buf[this.pos+3]>>4),this.pos+=4):e>=224?(e=(15&e)<<24,e+=(this.buf[this.pos+0]<<16)+(this.buf[this.pos+1]<<8)+(this.buf[this.pos+2]|0),this.pos+=3):e>=192?(e=(31&e)<<16,e+=(this.buf[this.pos+0]<<8)+(this.buf[this.pos+1]|0),this.pos+=2):e>=128&&(e=(63&e)<<8,e+=this.buf[this.pos],this.pos++),e}WriteByte(e){this.buf[this.pos++]=e}WriteChar(e){this.buf[this.pos++]=e.charCodeAt(0)}WriteString(e){for(var t=0;t>8&255)}WriteUint32(e){this.buf.writeInt32LE(e,this.pos),this.pos+=4}WriteUint7(e){var t=0,i=e;do{t+=7,i>>=7}while(i>0);do{t-=7,this.WriteByte((e>>t&127)+((t>0)<<7))}while(t>0)}WriteITF8(e){e<0&&(e=1+e),e<=127?this.buf[this.pos++]=e:e<=16383?(this.buf[this.pos++]=128|Math.floor(e/256),this.buf[this.pos++]=255&e):e<131071?(this.buf[this.pos++]=192|Math.floor(e/65536),this.buf[this.pos++]=255&Math.floor(e/256),this.buf[this.pos++]=255&e):e<268435455?(this.buf[this.pos++]=224|Math.floor(e/16777216),this.buf[this.pos++]=255&Math.floor(e/65536),this.buf[this.pos++]=255&Math.floor(e/256),this.buf[this.pos++]=255&e):(this.buf[this.pos++]=240|Math.floor(e/268435456),this.buf[this.pos++]=255&Math.floor(e/1048576),this.buf[this.pos++]=255&Math.floor(e/4096),this.buf[this.pos++]=255&Math.floor(e/4),this.buf[this.pos++]=15&e)}WriteByteNeg(e){this.buf[--this.pos]=e}}},4459:(e,t,i)=>{const n=i(9260);function o(e){return 4095&e}function r(e,t){for(var i=0;t>=e[i+1];)i++;return i}function a(e){for(var t=new Array(4096),i=0,n=0;n<4096;n++){for(;n>=e[i+1];)i++;t[n]=i}return t}function s(e,t,i){return i*(e>>12)+(4095&e)-t}function c(e,t){for(;t<1<<23;)t=(t<<8)+e.ReadByte();return t}function l(e,t){t.WriteByteNeg(e>>24&255),t.WriteByteNeg(e>>16&255),t.WriteByteNeg(e>>8&255),t.WriteByteNeg(255&e)}function h(e,t,i,n,o){return e=function(e,t,i,n){for(var o=(1<<23>>n<<8)*i;e>=o;)t.WriteByteNeg(255&e),e>>=8;return e}(e,t,n,o),(Math.floor(e/n)<0?(a--,o++):(o=e.ReadByte())==r+1&&(a=e.ReadByte()),r=o}while(0!=o);for(i[0]=0,n=0;n<=255;n++)i[n+1]=i[n]+t[n]}function f(e){for(var t=0,i=0;i<256;i++)t+=e[i];const n=4096;var o=n/t;do{var r=0,a=0,s=0;for(t=0,i=0;i<256;i++)0!=e[i]&&(r2?e[a]-=t-n:t!=n&&(o*=.99,s=1)}while(s)}function u(e,t){for(var i=0,n=0;n<256;n++)if(t[n]){if(i>0)i--;else if(e.WriteByte(n),n>0&&t[n-1]>0){for(i=n+1;i<256&&t[i];i++);i-=n+1,e.WriteByte(i)}e.WriteITF8(t[n])}e.WriteByte(0)}e.exports={decode:function(e){var t=new n(e),i=t.ReadByte(),l=(t.ReadUint32(),t.ReadUint32());return 0==i?function(e,t){var i=new Array(256),n=new Array(256);d(e,i,n);for(var r=a(n),l=new Array(4),h=0;h<4;h++)l[h]=e.ReadUint32();var f=new Buffer.allocUnsafe(t);for(h=0;h0?(s--,r++):(r=e.ReadByte())==a+1&&(s=e.ReadByte()),a=r}while(0!=r)}(e,i,n);for(var l=new Array(256),h=0;h<256;h++)l[h]=a(n[h]);for(var f=new Array(4),u=new Array(4),p=0;p<4;p++)f[p]=e.ReadUint32(),u[p]=0;var m=new Buffer.allocUnsafe(t),g=Math.floor(t/4);for(h=0;h=0;a--)s[a%4]=h(s[a%4],d,r[e[a]],o[e[a]],12);for(a=3;a>=0;a--)l(s[a],d);var p=i.pos;return i.buf.writeInt32LE(p-9+(d.length-d.pos),1),i.buf.writeInt32LE(t,5),Buffer.concat([i.buf.slice(0,i.pos),d.buf.slice(d.pos,d.length)],i.pos+d.length-d.pos)}(e):function(e){const t=e.length;var i=new n("",0,198156);i.WriteByte(1),i.WriteUint32(0),i.WriteUint32(0);for(var o=new Array(256),r=new Array(256),a=new Array(256),s=0;s<256;s++)r[s]=new Array(256),a[s]=new Array(256);for(function(e,t,i){for(var n=0;n<256;n++){i[n]=0;for(var o=0;o<256;o++)t[n][o]=0}var r=0;for(n=0;n>2)]]++,t[0][e[2*(e.length>>2)]]++,t[0][e[3*(e.length>>2)]]++,i[0]+=3}(e,r,o),function(e,t){for(var i=0;i<256;i++)t[i]&&f(e[i])}(r,o),function(e,t,i){for(var n=0,o=0;o<256;o++)if(i[o]){if(n>0)n--;else if(e.WriteByte(o),o>0&&i[o-1]>0){for(n=o+1;n<256&&i[n];n++);n-=o+1,e.WriteByte(n)}u(e,t[o])}e.WriteByte(0)}(i,r,o),s=0;s<256;s++)if(o[s]){a[s][0]=0;for(var c=1;c<256;c++)a[s][c]=a[s][c-1]+r[s][c-1]}var d=new Array(4),p=new Array(4);for(c=0;c<4;c++)d[c]=1<<23,p[c]=0;var m=new n("",t,t),g=Math.floor(t/4),w=new Array(4),F=new Array(4);for(c=0;c<4;c++)w[c]=(c+1)*g-2,F[c]=e[w[c]+1];for(F[3]=e[t-1],s=t-2;s>4*g-2;s--)d[3]=h(d[3],m,a[e[s]][F[3]],r[e[s]][F[3]],12),F[3]=e[s];for(;w[0]>=0;)for(c=3;c>=0;c--){var b=e[w[c]];d[c]=h(d[c],m,a[b][F[c]],r[b][F[c]],12),F[c]=b,w[c]--}for(c=3;c>=0;c--)d[c]=h(d[c],m,a[0][F[c]],r[0][F[c]],12);for(s=3;s>=0;s--)l(d[s],m);var v=i.pos;return i.buf.writeInt32LE(v-9+(m.length-m.pos),1),i.buf.writeInt32LE(t,5),Buffer.concat([i.buf.slice(0,i.pos),m.buf.slice(m.pos,m.length)],i.pos+m.length-m.pos)}(e)}}},594:(e,t,i)=>{const n=i(9260);function o(e,t){return e&(1<=e[i+1];)i++;return i}function a(e,t){for(var i=1<=e[o+1];)o++;n[r]=o}return n}function s(e,t,i,n){return i*(e>>n)+(e&(1<>24&255),t.WriteByteNeg(e>>16&255),t.WriteByteNeg(e>>8&255),t.WriteByteNeg(255&e)}function h(e,t,i,n,o){return e=function(e,t,i,n){for(var o=(1<<31-n)*i;e>=o;)t.WriteByteNeg(e>>8&255),t.WriteByteNeg(255&e),e>>=16;return e}(e,t,n,o),(Math.floor(e/n)<a),o[a]=new Array(r[a]);for(var s=0,c=0;cr),a[r]=f(e,o[r]);var s=new Buffer.allocUnsafe(t);for(r=0;r>4,l=e;if(1&f){var h=e.ReadUint7(),d=e.ReadUint7(),f=new n(e.ReadData(d));l=new n(m(f,h))}var u=new Array(256),g=new Array(256);!function(e,t,i,n){for(var o=0;o<256;o++){t[o]=new Array(256),i[o]=new Array(256);for(var r=0;r<256;r++)t[o][r]=0}var a=p(e);for(o=0;o<256;o++)if(a[o]){var s=0;for(r=0;r<256;r++)a[r]&&(s>0?s--:(t[o][r]=e.ReadUint7(),0==t[o][r]&&(s=e.ReadByte())));for(w(t[o],n),i[o][0]=0,r=0;r<256;r++)i[o][r+1]=i[o][r]+t[o][r]}}(l,u,g,i);for(var F=new Array(256),b=0;b<256;b++)F[b]=a(g[b],i);for(var v=new Array(4),y=new Array(4),_=0;_<4;_++)v[_]=e.ReadUint32(),y[_]=0;var C=new Buffer.allocUnsafe(t),x=Math.floor(t/4);for(b=0;b>=1}else if(i<=4)for(a=0;a>=2;else if(i<=16)for(a=0;a>=4;return o}(x,b,v,F)),x}function u(e,t){var i=new n("",0,10);i.WriteByte(t);var o=1&t,r=8&t,a=32&t,s=64&t,c=128&t,f=t>>8;if(16&t||i.WriteUint7(e.length),r)return Buffer.concat([i.buf.slice(0,i.pos),d(0,e,f)]);var u=new Buffer.alloc(0);c&&([u,e]=function(e){for(var t=new Array(256),i=0;i<256;i++)t[i]=0;for(i=0;i0&&(o[i]=r++);if(!(r>16)){if(r<=1)var a=new Buffer.allocUnsafe(0);else if(r<=2){a=new Buffer.allocUnsafe(Math.ceil(e.length/8));var s=-1;for(i=0;i0&&(t[i]=s++,c.WriteByte(i));return c.WriteUint7(a.length),[c.buf.slice(0,c.pos),a]}}(e));var p=new Buffer.alloc(0);if(s&&([p,e]=function(e){for(var t=new Array(256),i=0;i<256;i++)t[i]=0;var o=-1;for(i=0;i0&&r++;for(r||(r=1,t[0]=1),(l=new n("",0,r+1+e.length)).WriteByte(r),i=0;i<256;i++)t[i]>0&&l.WriteByte(i);var a=new Buffer.allocUnsafe(e.length),s=0;for(i=0;i0){o=e[i];for(var c=0;i+c+1>2)]]++,t[0][e[2*(e.length>>2)]]++,t[0][e[3*(e.length>>2)]]++,i[0]+=3})(e,r,o),function(e,t){for(var i=0;i<256;i++)if(t[i]){var n=Math.ceil(Math.log2(t[i]));n>12&&(n=12),g(e[i],n)}}(r,o);var c=new n("",0,198156);!function(e,t,i){F(e,i);for(var n=0;n<256;n++)if(i[n])for(var o=0,r=0;r<256;r++)if(i[r])if(o)o--;else if(e.WriteUint7(t[n][r]),!t[n][r]){for(var a=r+1;a<256;a++)if(i[a]){if(0!=t[n][a])break;o++}e.WriteByte(o)}}(c,r,o);var d=b(c.buf.slice(0,c.pos));for(d.length4*v-2;s--)u[3]=h(u[3],m,a[e[s]][_[3]],r[e[s]][_[3]],12),_[3]=e[s];for(;y[0]>=0;)for(f=3;f>=0;f--){var C=e[y[f]];u[f]=h(u[f],m,a[C][_[f]],r[C][_[f]],12),_[f]=C,y[f]--}for(f=3;f>=0;f--)u[f]=h(u[f],m,a[0][_[f]],r[0][_[f]],12);for(s=3;s>=0;s--)l(u[s],m);return Buffer.concat([i.buf.slice(0,i.pos),m.buf.slice(m.pos,m.length)],i.pos+m.length-m.pos)}(e);return Buffer.concat([i.buf.slice(0,i.pos),u,p,m])}function p(e){for(var t=new Array(256),i=0;i<256;i++)t[i]=0;var n=0,o=e.ReadByte(),r=o;do{t[o]=1,n>0?(n--,o++):(o=e.ReadByte())==r+1&&(n=e.ReadByte()),r=o}while(0!=o);return t}function m(e,t){var i=new Array(256),n=new Array(256);!function(e,t,i){for(var n=0;n<256;n++)t[n]=0;var o=p(e);for(n=0;n<256;n++)o[n]>0&&(t[n]=e.ReadUint7());for(w(t,12),i[0]=0,n=0;n<=255;n++)i[n+1]=i[n]+t[n]}(e,i,n);for(var r=a(n,12),l=new Array(4),h=0;h<4;h++)l[h]=e.ReadUint32();var d=new Buffer.allocUnsafe(t);for(h=0;h2?e[s]-=i-o:i!=o&&(r=o/i,c=1)}while(c)}function w(e,t){for(var i=0,n=0;n<256;n++)i+=e[n];if(0!=i&&i!=1<0)i--;else if(e.WriteByte(n),n>0&&t[n-1]>0){for(i=n+1;i<256&&t[i];i++);i-=n+1,e.WriteByte(i)}e.WriteByte(0)}function b(e){const t=e.length;var i=new n("",0,780),o=new Array(256);!function(e,t){for(var i=0;i<256;i++)t[i]=0;for(i=0;i12&&(r=12),g(o,r),function(e,t){F(e,t);for(var i=0;i<256;i++)t[i]&&e.WriteUint7(t[i])}(i,o),g(o,12);var a=new Array(256);a[0]=0;for(var s=1;s<256;s++)a[s]=a[s-1]+o[s-1];var c=new Array(4);for(s=0;s<4;s++)c[s]=32768;var d=new n("",1.05*t+100|0,1.05*t+100|0);for(s=t-1;s>=0;s--)c[s%4]=h(c[s%4],d,a[e[s]],o[e[s]],12);for(s=3;s>=0;s--)l(c[s],d);return Buffer.concat([i.buf.slice(0,i.pos),d.buf.slice(d.pos,d.length)],i.pos+d.length-d.pos)}e.exports={decode:function(e){return f(new n(e),0)},encode:u}},2881:(e,t,i)=>{const n=i(9260),o=i(594);var r=new(i(445));function a(e,t){for(var i=e+"";i.length0&&5==t[a][0].type)&&t[a][i])switch(e[0].WriteByte(t[a][i].type),t[a][i].type){case 6:e[6].WriteUint32(t[a][i].val);break;case 5:e[5].WriteUint32(t[a][i].val);break;case 1:e[1].WriteString(t[a][i].val);break;case 2:e[2].WriteChar(t[a][i].val);break;case 7:e[7].WriteUint32(t[a][i].val);break;case 3:e[3].WriteUint32(t[a][i].val),e[4].WriteByte(t[a][i].val.length);break;case 8:case 9:e[t[a][i].type].WriteByte(t[a][i].val)}}function l(e,t,i,n){for(var o=0;o<=12;o++)if(!(e[o].pos<=0)){n.WriteByte(o+(0==o?128:0)),e[o]=e[o].buf.slice(0,e[o].pos);var r=h(e[o],i);n.WriteUint7(r.length),n.WriteData(r,r.length)}}function h(e,t){var i,n=1<<30,a=[0,1,64,65,128,129,201];for(var s in a){var c=a[s];if(!(1&c&&e.length<100||8&c&&e.length%4!=0)){try{var l=t?r.encode(e,c):o.encode(e,c)}catch(e){l=0}l&&n>l.length&&(n=l.length,i=l)}}return i}function d(e,t,i,n,o){var r=0,a=o-1;e[o]=new Array(256),t[n]?e[o][0]={type:5,val:o-t[n]}:e[o][0]={type:6,val:0==o?0:1},t[n]=o;for(var s=n.match(/([a-zA-Z0-9]{1,9})|([^a-zA-Z0-9]+)/g),c=0;c=0&&e[a][l])if(e[a][l].str==s[c])h=10,d="";else if(7==e[a][l].type||8==e[a][l].type){var f=d-e[a][l].str;i[l]++,f>=0&&f<256&&i[l]>o/2&&(h=8,d=f)}else 3!=e[a][l].type&&9!=e[a][l].type||e[a][l].str.length!=d.length||(f=d-e[a][l].str,i[l]++,f>=0&&f<256&&i[l]>o/2&&(h=9,d=f));e[o][l]={str:s[c],val:d,type:h},r{s.callback(e)})),settled:!1,statusReporter:s,get aborted(){return this.aborter.signal.aborted}};c.aborter.addSignal(i),c.aborter.signal.addEventListener("abort",(()=>{c.settled||this.evict(e,c)})),c.promise.then((()=>{c.settled=!0}),(()=>{c.settled=!0,this.evict(e,c)})).catch((e=>{throw console.error(e),e})),this.cache.set(e,c)}static checkSinglePromise(e,t){function i(){if(t&&t.aborted)throw Object.assign(new Error("aborted"),{code:"ERR_ABORTED"})}return e.then((e=>(i(),e)),(e=>{throw i(),e}))}has(e){return this.cache.has(e)}get(e,t,i,n){if(!i&&t instanceof o.AbortSignal)throw new TypeError("second get argument appears to be an AbortSignal, perhaps you meant to pass `null` for the fill data?");const r=this.cache.get(e);return r?r.aborted&&!r.settled?(this.evict(e,r),this.get(e,t,i,n)):r.settled?r.promise:(r.aborter.addSignal(i),r.statusReporter.addCallback(n),s.checkSinglePromise(r.promise,i)):(this.fill(e,t,i,n),s.checkSinglePromise(this.cache.get(e).promise,i))}delete(e){const t=this.cache.get(e);t&&(t.settled||t.aborter.abort(),this.cache.delete(e))}clear(){const e=this.cache.keys();let t=0;for(let i=e.next();!i.done;i=e.next())this.delete(i.value),t+=1;return t}}t.default=s},9049:(e,t,i)=>{Object.defineProperty(t,"__esModule",{value:!0});const n=i(8904);class o{}t.default=class{constructor(){this.signals=new Set,this.abortController=new n.AbortController}addSignal(e=new o){if(this.signal.aborted)throw new Error("cannot add a signal, already aborted!");this.signals.add(e),e.aborted?this.handleAborted(e):"function"==typeof e.addEventListener&&e.addEventListener("abort",(()=>{this.handleAborted(e)}))}handleAborted(e){this.signals.delete(e),0===this.signals.size&&this.abortController.abort()}get signal(){return this.abortController.signal}abort(){this.abortController.abort()}}},450:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.default=class{constructor(){this.callbacks=new Set}addCallback(e=()=>{}){this.callbacks.add(e),e(this.currentMessage)}callback(e){this.currentMessage=e,this.callbacks.forEach((t=>{t(e)}))}}},8904:(e,t,i)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.AbortSignal=t.AbortController=void 0;const n=i(5988);var o=function(){if("undefined"!=typeof self)return self;if("undefined"!=typeof window)return window;if(void 0!==i.g)return i.g;throw new Error("unable to locate global object")};let r=void 0===o().AbortController?n.AbortController:o().AbortController;t.AbortController=r;let a=void 0===o().AbortController?n.AbortSignal:o().AbortSignal;t.AbortSignal=a},4105:function(e,t,i){var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const o=n(i(1422));t.default=o.default},5988:(e,t)=>{function i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function n(e,t){for(var i=0;i{t.byteLength=function(e){var t=s(e),i=t[0],n=t[1];return 3*(i+n)/4-n},t.toByteArray=function(e){var t,i,r=s(e),a=r[0],c=r[1],l=new o(function(e,t,i){return 3*(t+i)/4-i}(0,a,c)),h=0,d=c>0?a-4:a;for(i=0;i>16&255,l[h++]=t>>8&255,l[h++]=255&t;return 2===c&&(t=n[e.charCodeAt(i)]<<2|n[e.charCodeAt(i+1)]>>4,l[h++]=255&t),1===c&&(t=n[e.charCodeAt(i)]<<10|n[e.charCodeAt(i+1)]<<4|n[e.charCodeAt(i+2)]>>2,l[h++]=t>>8&255,l[h++]=255&t),l},t.fromByteArray=function(e){for(var t,n=e.length,o=n%3,r=[],a=16383,s=0,l=n-o;sl?l:s+a));return 1===o?(t=e[n-1],r.push(i[t>>2]+i[t<<4&63]+"==")):2===o&&(t=(e[n-2]<<8)+e[n-1],r.push(i[t>>10]+i[t>>4&63]+i[t<<2&63]+"=")),r.join("")};for(var i=[],n=[],o="undefined"!=typeof Uint8Array?Uint8Array:Array,r="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",a=0;a<64;++a)i[a]=r[a],n[r.charCodeAt(a)]=a;function s(e){var t=e.length;if(t%4>0)throw new Error("Invalid string. Length must be a multiple of 4");var i=e.indexOf("=");return-1===i&&(i=t),[i,i===t?0:4-i%4]}function c(e,t,n){for(var o,r,a=[],s=t;s>18&63]+i[r>>12&63]+i[r>>6&63]+i[63&r]);return a.join("")}n["-".charCodeAt(0)]=62,n["_".charCodeAt(0)]=63},2779:(e,t,i)=>{var n=i(8764).Buffer,o=[0,1996959894,3993919788,2567524794,124634137,1886057615,3915621685,2657392035,249268274,2044508324,3772115230,2547177864,162941995,2125561021,3887607047,2428444049,498536548,1789927666,4089016648,2227061214,450548861,1843258603,4107580753,2211677639,325883990,1684777152,4251122042,2321926636,335633487,1661365465,4195302755,2366115317,997073096,1281953886,3579855332,2724688242,1006888145,1258607687,3524101629,2768942443,901097722,1119000684,3686517206,2898065728,853044451,1172266101,3705015759,2882616665,651767980,1373503546,3369554304,3218104598,565507253,1454621731,3485111705,3099436303,671266974,1594198024,3322730930,2970347812,795835527,1483230225,3244367275,3060149565,1994146192,31158534,2563907772,4023717930,1907459465,112637215,2680153253,3904427059,2013776290,251722036,2517215374,3775830040,2137656763,141376813,2439277719,3865271297,1802195444,476864866,2238001368,4066508878,1812370925,453092731,2181625025,4111451223,1706088902,314042704,2344532202,4240017532,1658658271,366619977,2362670323,4224994405,1303535960,984961486,2747007092,3569037538,1256170817,1037604311,2765210733,3554079995,1131014506,879679996,2909243462,3663771856,1141124467,855842277,2852801631,3708648649,1342533948,654459306,3188396048,3373015174,1466479909,544179635,3110523913,3462522015,1591671054,702138776,2966460450,3352799412,1504918807,783551873,3082640443,3233442989,3988292384,2596254646,62317068,1957810842,3939845945,2647816111,81470997,1943803523,3814918930,2489596804,225274430,2053790376,3826175755,2466906013,167816743,2097651377,4027552580,2265490386,503444072,1762050814,4150417245,2154129355,426522225,1852507879,4275313526,2312317920,282753626,1742555852,4189708143,2394877945,397917763,1622183637,3604390888,2714866558,953729732,1340076626,3518719985,2797360999,1068828381,1219638859,3624741850,2936675148,906185462,1090812512,3747672003,2825379669,829329135,1181335161,3412177804,3160834842,628085408,1382605366,3423369109,3138078467,570562233,1426400815,3317316542,2998733608,733239954,1555261956,3268935591,3050360625,752459403,1541320221,2607071920,3965973030,1969922972,40735498,2617837225,3943577151,1913087877,83908371,2512341634,3803740692,2075208622,213261112,2463272603,3855990285,2094854071,198958881,2262029012,4057260610,1759359992,534414190,2176718541,4139329115,1873836001,414664567,2282248934,4279200368,1711684554,285281116,2405801727,4167216745,1634467795,376229701,2685067896,3608007406,1308918612,956543938,2808555105,3495958263,1231636301,1047427035,2932959818,3654703836,1088359270,936918e3,2847714899,3736837829,1202900863,817233897,3183342108,3401237130,1404277552,615818150,3134207493,3453421203,1423857449,601450431,3009837614,3294710456,1567103746,711928724,3020668471,3272380065,1510334235,755167117];function r(e){if(n.isBuffer(e))return e;var t="function"==typeof n.alloc&&"function"==typeof n.from;if("number"==typeof e)return t?n.alloc(e):new n(e);if("string"==typeof e)return t?n.from(e):new n(e);throw new Error("input must be buffer, number, or string, received "+typeof e)}function a(e,t){e=r(e),n.isBuffer(t)&&(t=t.readUInt32BE(0));for(var i=~t,a=0;a>>8;return~i}function s(){return function(e){var t=r(4);return t.writeInt32BE(e,0),t}(a.apply(null,arguments))}"undefined"!=typeof Int32Array&&(o=new Int32Array(o)),s.signed=function(){return a.apply(null,arguments)},s.unsigned=function(){return a.apply(null,arguments)>>>0},e.exports=s},8764:(e,t,i)=>{const n=i(9742),o=i(645),r="function"==typeof Symbol&&"function"==typeof Symbol.for?Symbol.for("nodejs.util.inspect.custom"):null;t.Buffer=c,t.SlowBuffer=function(e){return+e!=e&&(e=0),c.alloc(+e)},t.INSPECT_MAX_BYTES=50;const a=2147483647;function s(e){if(e>a)throw new RangeError('The value "'+e+'" is invalid for option "size"');const t=new Uint8Array(e);return Object.setPrototypeOf(t,c.prototype),t}function c(e,t,i){if("number"==typeof e){if("string"==typeof t)throw new TypeError('The "string" argument must be of type string. Received type number');return d(e)}return l(e,t,i)}function l(e,t,i){if("string"==typeof e)return function(e,t){if("string"==typeof t&&""!==t||(t="utf8"),!c.isEncoding(t))throw new TypeError("Unknown encoding: "+t);const i=0|m(e,t);let n=s(i);const o=n.write(e,t);return o!==i&&(n=n.slice(0,o)),n}(e,t);if(ArrayBuffer.isView(e))return function(e){if(K(e,Uint8Array)){const t=new Uint8Array(e);return u(t.buffer,t.byteOffset,t.byteLength)}return f(e)}(e);if(null==e)throw new TypeError("The first argument must be one of type string, Buffer, ArrayBuffer, Array, or Array-like Object. Received type "+typeof e);if(K(e,ArrayBuffer)||e&&K(e.buffer,ArrayBuffer))return u(e,t,i);if("undefined"!=typeof SharedArrayBuffer&&(K(e,SharedArrayBuffer)||e&&K(e.buffer,SharedArrayBuffer)))return u(e,t,i);if("number"==typeof e)throw new TypeError('The "value" argument must not be of type number. Received type number');const n=e.valueOf&&e.valueOf();if(null!=n&&n!==e)return c.from(n,t,i);const o=function(e){if(c.isBuffer(e)){const t=0|p(e.length),i=s(t);return 0===i.length||e.copy(i,0,0,t),i}return void 0!==e.length?"number"!=typeof e.length||X(e.length)?s(0):f(e):"Buffer"===e.type&&Array.isArray(e.data)?f(e.data):void 0}(e);if(o)return o;if("undefined"!=typeof Symbol&&null!=Symbol.toPrimitive&&"function"==typeof e[Symbol.toPrimitive])return c.from(e[Symbol.toPrimitive]("string"),t,i);throw new TypeError("The first argument must be one of type string, Buffer, ArrayBuffer, Array, or Array-like Object. Received type "+typeof e)}function h(e){if("number"!=typeof e)throw new TypeError('"size" argument must be of type number');if(e<0)throw new RangeError('The value "'+e+'" is invalid for option "size"')}function d(e){return h(e),s(e<0?0:0|p(e))}function f(e){const t=e.length<0?0:0|p(e.length),i=s(t);for(let n=0;n=a)throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+a.toString(16)+" bytes");return 0|e}function m(e,t){if(c.isBuffer(e))return e.length;if(ArrayBuffer.isView(e)||K(e,ArrayBuffer))return e.byteLength;if("string"!=typeof e)throw new TypeError('The "string" argument must be one of type string, Buffer, or ArrayBuffer. Received type '+typeof e);const i=e.length,n=arguments.length>2&&!0===arguments[2];if(!n&&0===i)return 0;let o=!1;for(;;)switch(t){case"ascii":case"latin1":case"binary":return i;case"utf8":case"utf-8":return G(e).length;case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return 2*i;case"hex":return i>>>1;case"base64":return $(e).length;default:if(o)return n?-1:G(e).length;t=(""+t).toLowerCase(),o=!0}}function g(e,t,i){let n=!1;if((void 0===t||t<0)&&(t=0),t>this.length)return"";if((void 0===i||i>this.length)&&(i=this.length),i<=0)return"";if((i>>>=0)<=(t>>>=0))return"";for(e||(e="utf8");;)switch(e){case"hex":return z(this,t,i);case"utf8":case"utf-8":return E(this,t,i);case"ascii":return S(this,t,i);case"latin1":case"binary":return I(this,t,i);case"base64":return k(this,t,i);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return D(this,t,i);default:if(n)throw new TypeError("Unknown encoding: "+e);e=(e+"").toLowerCase(),n=!0}}function w(e,t,i){const n=e[t];e[t]=e[i],e[i]=n}function F(e,t,i,n,o){if(0===e.length)return-1;if("string"==typeof i?(n=i,i=0):i>2147483647?i=2147483647:i<-2147483648&&(i=-2147483648),X(i=+i)&&(i=o?0:e.length-1),i<0&&(i=e.length+i),i>=e.length){if(o)return-1;i=e.length-1}else if(i<0){if(!o)return-1;i=0}if("string"==typeof t&&(t=c.from(t,n)),c.isBuffer(t))return 0===t.length?-1:b(e,t,i,n,o);if("number"==typeof t)return t&=255,"function"==typeof Uint8Array.prototype.indexOf?o?Uint8Array.prototype.indexOf.call(e,t,i):Uint8Array.prototype.lastIndexOf.call(e,t,i):b(e,[t],i,n,o);throw new TypeError("val must be string, number or Buffer")}function b(e,t,i,n,o){let r,a=1,s=e.length,c=t.length;if(void 0!==n&&("ucs2"===(n=String(n).toLowerCase())||"ucs-2"===n||"utf16le"===n||"utf-16le"===n)){if(e.length<2||t.length<2)return-1;a=2,s/=2,c/=2,i/=2}function l(e,t){return 1===a?e[t]:e.readUInt16BE(t*a)}if(o){let n=-1;for(r=i;rs&&(i=s-c),r=i;r>=0;r--){let i=!0;for(let n=0;no&&(n=o):n=o;const r=t.length;let a;for(n>r/2&&(n=r/2),a=0;a>8,o=i%256,r.push(o),r.push(n);return r}(t,e.length-i),e,i,n)}function k(e,t,i){return 0===t&&i===e.length?n.fromByteArray(e):n.fromByteArray(e.slice(t,i))}function E(e,t,i){i=Math.min(e.length,i);const n=[];let o=t;for(;o239?4:t>223?3:t>191?2:1;if(o+a<=i){let i,n,s,c;switch(a){case 1:t<128&&(r=t);break;case 2:i=e[o+1],128==(192&i)&&(c=(31&t)<<6|63&i,c>127&&(r=c));break;case 3:i=e[o+1],n=e[o+2],128==(192&i)&&128==(192&n)&&(c=(15&t)<<12|(63&i)<<6|63&n,c>2047&&(c<55296||c>57343)&&(r=c));break;case 4:i=e[o+1],n=e[o+2],s=e[o+3],128==(192&i)&&128==(192&n)&&128==(192&s)&&(c=(15&t)<<18|(63&i)<<12|(63&n)<<6|63&s,c>65535&&c<1114112&&(r=c))}}null===r?(r=65533,a=1):r>65535&&(r-=65536,n.push(r>>>10&1023|55296),r=56320|1023&r),n.push(r),o+=a}return function(e){const t=e.length;if(t<=N)return String.fromCharCode.apply(String,e);let i="",n=0;for(;nn.length?(c.isBuffer(t)||(t=c.from(t)),t.copy(n,o)):Uint8Array.prototype.set.call(n,t,o);else{if(!c.isBuffer(t))throw new TypeError('"list" argument must be an Array of Buffers');t.copy(n,o)}o+=t.length}return n},c.byteLength=m,c.prototype._isBuffer=!0,c.prototype.swap16=function(){const e=this.length;if(e%2!=0)throw new RangeError("Buffer size must be a multiple of 16-bits");for(let t=0;ti&&(e+=" ... "),""},r&&(c.prototype[r]=c.prototype.inspect),c.prototype.compare=function(e,t,i,n,o){if(K(e,Uint8Array)&&(e=c.from(e,e.offset,e.byteLength)),!c.isBuffer(e))throw new TypeError('The "target" argument must be one of type Buffer or Uint8Array. Received type '+typeof e);if(void 0===t&&(t=0),void 0===i&&(i=e?e.length:0),void 0===n&&(n=0),void 0===o&&(o=this.length),t<0||i>e.length||n<0||o>this.length)throw new RangeError("out of range index");if(n>=o&&t>=i)return 0;if(n>=o)return-1;if(t>=i)return 1;if(this===e)return 0;let r=(o>>>=0)-(n>>>=0),a=(i>>>=0)-(t>>>=0);const s=Math.min(r,a),l=this.slice(n,o),h=e.slice(t,i);for(let e=0;e>>=0,isFinite(i)?(i>>>=0,void 0===n&&(n="utf8")):(n=i,i=void 0)}const o=this.length-t;if((void 0===i||i>o)&&(i=o),e.length>0&&(i<0||t<0)||t>this.length)throw new RangeError("Attempt to write outside buffer bounds");n||(n="utf8");let r=!1;for(;;)switch(n){case"hex":return v(this,e,t,i);case"utf8":case"utf-8":return y(this,e,t,i);case"ascii":case"latin1":case"binary":return _(this,e,t,i);case"base64":return C(this,e,t,i);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return x(this,e,t,i);default:if(r)throw new TypeError("Unknown encoding: "+n);n=(""+n).toLowerCase(),r=!0}},c.prototype.toJSON=function(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}};const N=4096;function S(e,t,i){let n="";i=Math.min(e.length,i);for(let o=t;on)&&(i=n);let o="";for(let n=t;ni)throw new RangeError("Trying to access beyond buffer length")}function M(e,t,i,n,o,r){if(!c.isBuffer(e))throw new TypeError('"buffer" argument must be a Buffer instance');if(t>o||te.length)throw new RangeError("Index out of range")}function T(e,t,i,n,o){V(t,n,o,e,i,7);let r=Number(t&BigInt(4294967295));e[i++]=r,r>>=8,e[i++]=r,r>>=8,e[i++]=r,r>>=8,e[i++]=r;let a=Number(t>>BigInt(32)&BigInt(4294967295));return e[i++]=a,a>>=8,e[i++]=a,a>>=8,e[i++]=a,a>>=8,e[i++]=a,i}function R(e,t,i,n,o){V(t,n,o,e,i,7);let r=Number(t&BigInt(4294967295));e[i+7]=r,r>>=8,e[i+6]=r,r>>=8,e[i+5]=r,r>>=8,e[i+4]=r;let a=Number(t>>BigInt(32)&BigInt(4294967295));return e[i+3]=a,a>>=8,e[i+2]=a,a>>=8,e[i+1]=a,a>>=8,e[i]=a,i+8}function L(e,t,i,n,o,r){if(i+n>e.length)throw new RangeError("Index out of range");if(i<0)throw new RangeError("Index out of range")}function B(e,t,i,n,r){return t=+t,i>>>=0,r||L(e,0,i,4),o.write(e,t,i,n,23,4),i+4}function H(e,t,i,n,r){return t=+t,i>>>=0,r||L(e,0,i,8),o.write(e,t,i,n,52,8),i+8}c.prototype.slice=function(e,t){const i=this.length;(e=~~e)<0?(e+=i)<0&&(e=0):e>i&&(e=i),(t=void 0===t?i:~~t)<0?(t+=i)<0&&(t=0):t>i&&(t=i),t>>=0,t>>>=0,i||A(e,t,this.length);let n=this[e],o=1,r=0;for(;++r>>=0,t>>>=0,i||A(e,t,this.length);let n=this[e+--t],o=1;for(;t>0&&(o*=256);)n+=this[e+--t]*o;return n},c.prototype.readUint8=c.prototype.readUInt8=function(e,t){return e>>>=0,t||A(e,1,this.length),this[e]},c.prototype.readUint16LE=c.prototype.readUInt16LE=function(e,t){return e>>>=0,t||A(e,2,this.length),this[e]|this[e+1]<<8},c.prototype.readUint16BE=c.prototype.readUInt16BE=function(e,t){return e>>>=0,t||A(e,2,this.length),this[e]<<8|this[e+1]},c.prototype.readUint32LE=c.prototype.readUInt32LE=function(e,t){return e>>>=0,t||A(e,4,this.length),(this[e]|this[e+1]<<8|this[e+2]<<16)+16777216*this[e+3]},c.prototype.readUint32BE=c.prototype.readUInt32BE=function(e,t){return e>>>=0,t||A(e,4,this.length),16777216*this[e]+(this[e+1]<<16|this[e+2]<<8|this[e+3])},c.prototype.readBigUInt64LE=Q((function(e){U(e>>>=0,"offset");const t=this[e],i=this[e+7];void 0!==t&&void 0!==i||j(e,this.length-8);const n=t+256*this[++e]+65536*this[++e]+this[++e]*2**24,o=this[++e]+256*this[++e]+65536*this[++e]+i*2**24;return BigInt(n)+(BigInt(o)<>>=0,"offset");const t=this[e],i=this[e+7];void 0!==t&&void 0!==i||j(e,this.length-8);const n=t*2**24+65536*this[++e]+256*this[++e]+this[++e],o=this[++e]*2**24+65536*this[++e]+256*this[++e]+i;return(BigInt(n)<>>=0,t>>>=0,i||A(e,t,this.length);let n=this[e],o=1,r=0;for(;++r=o&&(n-=Math.pow(2,8*t)),n},c.prototype.readIntBE=function(e,t,i){e>>>=0,t>>>=0,i||A(e,t,this.length);let n=t,o=1,r=this[e+--n];for(;n>0&&(o*=256);)r+=this[e+--n]*o;return o*=128,r>=o&&(r-=Math.pow(2,8*t)),r},c.prototype.readInt8=function(e,t){return e>>>=0,t||A(e,1,this.length),128&this[e]?-1*(255-this[e]+1):this[e]},c.prototype.readInt16LE=function(e,t){e>>>=0,t||A(e,2,this.length);const i=this[e]|this[e+1]<<8;return 32768&i?4294901760|i:i},c.prototype.readInt16BE=function(e,t){e>>>=0,t||A(e,2,this.length);const i=this[e+1]|this[e]<<8;return 32768&i?4294901760|i:i},c.prototype.readInt32LE=function(e,t){return e>>>=0,t||A(e,4,this.length),this[e]|this[e+1]<<8|this[e+2]<<16|this[e+3]<<24},c.prototype.readInt32BE=function(e,t){return e>>>=0,t||A(e,4,this.length),this[e]<<24|this[e+1]<<16|this[e+2]<<8|this[e+3]},c.prototype.readBigInt64LE=Q((function(e){U(e>>>=0,"offset");const t=this[e],i=this[e+7];void 0!==t&&void 0!==i||j(e,this.length-8);const n=this[e+4]+256*this[e+5]+65536*this[e+6]+(i<<24);return(BigInt(n)<>>=0,"offset");const t=this[e],i=this[e+7];void 0!==t&&void 0!==i||j(e,this.length-8);const n=(t<<24)+65536*this[++e]+256*this[++e]+this[++e];return(BigInt(n)<>>=0,t||A(e,4,this.length),o.read(this,e,!0,23,4)},c.prototype.readFloatBE=function(e,t){return e>>>=0,t||A(e,4,this.length),o.read(this,e,!1,23,4)},c.prototype.readDoubleLE=function(e,t){return e>>>=0,t||A(e,8,this.length),o.read(this,e,!0,52,8)},c.prototype.readDoubleBE=function(e,t){return e>>>=0,t||A(e,8,this.length),o.read(this,e,!1,52,8)},c.prototype.writeUintLE=c.prototype.writeUIntLE=function(e,t,i,n){e=+e,t>>>=0,i>>>=0,n||M(this,e,t,i,Math.pow(2,8*i)-1,0);let o=1,r=0;for(this[t]=255&e;++r>>=0,i>>>=0,n||M(this,e,t,i,Math.pow(2,8*i)-1,0);let o=i-1,r=1;for(this[t+o]=255&e;--o>=0&&(r*=256);)this[t+o]=e/r&255;return t+i},c.prototype.writeUint8=c.prototype.writeUInt8=function(e,t,i){return e=+e,t>>>=0,i||M(this,e,t,1,255,0),this[t]=255&e,t+1},c.prototype.writeUint16LE=c.prototype.writeUInt16LE=function(e,t,i){return e=+e,t>>>=0,i||M(this,e,t,2,65535,0),this[t]=255&e,this[t+1]=e>>>8,t+2},c.prototype.writeUint16BE=c.prototype.writeUInt16BE=function(e,t,i){return e=+e,t>>>=0,i||M(this,e,t,2,65535,0),this[t]=e>>>8,this[t+1]=255&e,t+2},c.prototype.writeUint32LE=c.prototype.writeUInt32LE=function(e,t,i){return e=+e,t>>>=0,i||M(this,e,t,4,4294967295,0),this[t+3]=e>>>24,this[t+2]=e>>>16,this[t+1]=e>>>8,this[t]=255&e,t+4},c.prototype.writeUint32BE=c.prototype.writeUInt32BE=function(e,t,i){return e=+e,t>>>=0,i||M(this,e,t,4,4294967295,0),this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e,t+4},c.prototype.writeBigUInt64LE=Q((function(e,t=0){return T(this,e,t,BigInt(0),BigInt("0xffffffffffffffff"))})),c.prototype.writeBigUInt64BE=Q((function(e,t=0){return R(this,e,t,BigInt(0),BigInt("0xffffffffffffffff"))})),c.prototype.writeIntLE=function(e,t,i,n){if(e=+e,t>>>=0,!n){const n=Math.pow(2,8*i-1);M(this,e,t,i,n-1,-n)}let o=0,r=1,a=0;for(this[t]=255&e;++o>>=0,!n){const n=Math.pow(2,8*i-1);M(this,e,t,i,n-1,-n)}let o=i-1,r=1,a=0;for(this[t+o]=255&e;--o>=0&&(r*=256);)e<0&&0===a&&0!==this[t+o+1]&&(a=1),this[t+o]=(e/r|0)-a&255;return t+i},c.prototype.writeInt8=function(e,t,i){return e=+e,t>>>=0,i||M(this,e,t,1,127,-128),e<0&&(e=255+e+1),this[t]=255&e,t+1},c.prototype.writeInt16LE=function(e,t,i){return e=+e,t>>>=0,i||M(this,e,t,2,32767,-32768),this[t]=255&e,this[t+1]=e>>>8,t+2},c.prototype.writeInt16BE=function(e,t,i){return e=+e,t>>>=0,i||M(this,e,t,2,32767,-32768),this[t]=e>>>8,this[t+1]=255&e,t+2},c.prototype.writeInt32LE=function(e,t,i){return e=+e,t>>>=0,i||M(this,e,t,4,2147483647,-2147483648),this[t]=255&e,this[t+1]=e>>>8,this[t+2]=e>>>16,this[t+3]=e>>>24,t+4},c.prototype.writeInt32BE=function(e,t,i){return e=+e,t>>>=0,i||M(this,e,t,4,2147483647,-2147483648),e<0&&(e=4294967295+e+1),this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e,t+4},c.prototype.writeBigInt64LE=Q((function(e,t=0){return T(this,e,t,-BigInt("0x8000000000000000"),BigInt("0x7fffffffffffffff"))})),c.prototype.writeBigInt64BE=Q((function(e,t=0){return R(this,e,t,-BigInt("0x8000000000000000"),BigInt("0x7fffffffffffffff"))})),c.prototype.writeFloatLE=function(e,t,i){return B(this,e,t,!0,i)},c.prototype.writeFloatBE=function(e,t,i){return B(this,e,t,!1,i)},c.prototype.writeDoubleLE=function(e,t,i){return H(this,e,t,!0,i)},c.prototype.writeDoubleBE=function(e,t,i){return H(this,e,t,!1,i)},c.prototype.copy=function(e,t,i,n){if(!c.isBuffer(e))throw new TypeError("argument should be a Buffer");if(i||(i=0),n||0===n||(n=this.length),t>=e.length&&(t=e.length),t||(t=0),n>0&&n=this.length)throw new RangeError("Index out of range");if(n<0)throw new RangeError("sourceEnd out of bounds");n>this.length&&(n=this.length),e.length-t>>=0,i=void 0===i?this.length:i>>>0,e||(e=0),"number"==typeof e)for(o=t;o=n+4;i-=3)t=`_${e.slice(i-3,i)}${t}`;return`${e.slice(0,i)}${t}`}function V(e,t,i,n,o,r){if(e>i||e3?0===t||t===BigInt(0)?`>= 0${n} and < 2${n} ** ${8*(r+1)}${n}`:`>= -(2${n} ** ${8*(r+1)-1}${n}) and < 2 ** ${8*(r+1)-1}${n}`:`>= ${t}${n} and <= ${i}${n}`,new O.ERR_OUT_OF_RANGE("value",o,e)}!function(e,t,i){U(t,"offset"),void 0!==e[t]&&void 0!==e[t+i]||j(t,e.length-(i+1))}(n,o,r)}function U(e,t){if("number"!=typeof e)throw new O.ERR_INVALID_ARG_TYPE(t,"number",e)}function j(e,t,i){if(Math.floor(e)!==e)throw U(e,i),new O.ERR_OUT_OF_RANGE(i||"offset","an integer",e);if(t<0)throw new O.ERR_BUFFER_OUT_OF_BOUNDS;throw new O.ERR_OUT_OF_RANGE(i||"offset",`>= ${i?1:0} and <= ${t}`,e)}P("ERR_BUFFER_OUT_OF_BOUNDS",(function(e){return e?`${e} is outside of buffer bounds`:"Attempt to access memory outside buffer bounds"}),RangeError),P("ERR_INVALID_ARG_TYPE",(function(e,t){return`The "${e}" argument must be of type number. Received type ${typeof t}`}),TypeError),P("ERR_OUT_OF_RANGE",(function(e,t,i){let n=`The value of "${e}" is out of range.`,o=i;return Number.isInteger(i)&&Math.abs(i)>2**32?o=q(String(i)):"bigint"==typeof i&&(o=String(i),(i>BigInt(2)**BigInt(32)||i<-(BigInt(2)**BigInt(32)))&&(o=q(o)),o+="n"),n+=` It must be ${t}. Received ${o}`,n}),RangeError);const W=/[^+/0-9A-Za-z-_]/g;function G(e,t){let i;t=t||1/0;const n=e.length;let o=null;const r=[];for(let a=0;a55295&&i<57344){if(!o){if(i>56319){(t-=3)>-1&&r.push(239,191,189);continue}if(a+1===n){(t-=3)>-1&&r.push(239,191,189);continue}o=i;continue}if(i<56320){(t-=3)>-1&&r.push(239,191,189),o=i;continue}i=65536+(o-55296<<10|i-56320)}else o&&(t-=3)>-1&&r.push(239,191,189);if(o=null,i<128){if((t-=1)<0)break;r.push(i)}else if(i<2048){if((t-=2)<0)break;r.push(i>>6|192,63&i|128)}else if(i<65536){if((t-=3)<0)break;r.push(i>>12|224,i>>6&63|128,63&i|128)}else{if(!(i<1114112))throw new Error("Invalid code point");if((t-=4)<0)break;r.push(i>>18|240,i>>12&63|128,i>>6&63|128,63&i|128)}}return r}function $(e){return n.toByteArray(function(e){if((e=(e=e.split("=")[0]).trim().replace(W,"")).length<2)return"";for(;e.length%4!=0;)e+="=";return e}(e))}function Z(e,t,i,n){let o;for(o=0;o=t.length||o>=e.length);++o)t[o+i]=e[o];return o}function K(e,t){return e instanceof t||null!=e&&null!=e.constructor&&null!=e.constructor.name&&e.constructor.name===t.name}function X(e){return e!=e}const Y=function(){const e="0123456789abcdef",t=new Array(256);for(let i=0;i<16;++i){const n=16*i;for(let o=0;o<16;++o)t[n+o]=e[i]+e[o]}return t}();function Q(e){return"undefined"==typeof BigInt?J:e}function J(){throw new Error("BigInt not supported")}},4693:e=>{var t={array:function(e){var t=0,i=0,n=[0,1,3,7,15,31,63,127,255];return function(o){for(var r=0;o>0;){var a=8-t;o>=a?(r<<=a,r|=n[a]&e[i++],t=0,o-=a):(r<<=o,r|=(e[i]&n[o]<<8-o-t)>>8-o-t,t+=o,o=0)}return r}},simple:function(e){var i,n,o=t.header(e),r=[],a=0;do{-1!=(n=t.decompress(e,o))&&(r.push(n),a+=n.byteLength)}while(-1!=n);i=new Uint8Array(a),a=0;for(var s=0;s9)throw"Not a BZIP archive";return t},decompress:function(e,t,i){for(var n=9e5,o="",r=0;r<6;r++)o+=e(8).toString(16);if("177245385090"==o)return-1;if("314159265359"!=o)throw"eek not valid bzip data";if(e(32),e(1))throw"unsupported obsolete version";var a=e(24);if(a>n)throw"Initial position larger than buffer size";var s=e(16),c=new Uint8Array(256),l=0;for(r=0;r<16;r++)if(s&1<<15-r){var h=e(16);for(m=0;m<16;m++)h&1<<15-m&&(c[l++]=16*r+m)}var d=e(3);if(d<2||d>6)throw"another error";var f=e(15);if(0==f)throw"meh";var u=[];for(r=0;r=d)throw"whoops another error";var g=u[m];u.splice(m,1),u.splice(0,0,g),p[r]=g}var w=l+2,F=[];for(m=0;m20)throw"I gave up a while ago on writing error messages";if(!e(1))break;e(1)?s--:s++}_[r]=s}for(b=v=_[0],r=1;rv?v=_[r]:_[r]=f)throw"meow i'm a kitty, that's an error";x=(y=F[p[I++]]).base.subarray(1),k=y.limit.subarray(1)}for(m=e(r=y.minLen);;){if(r>y.maxLen)throw"rawr i'm a dinosaur";if(m<=k[r])break;r++,m=m<<1|e(1)}if((m-=x[r])<0||m>=258)throw"moo i'm a cow";var A=y.permute[m];if(0!=A&&1!=A){if(N){if(N=0,S+s>=n)throw"Boom.";for(z[g=c[u[0]]]+=s;s--;)D[S++]=g}if(A>l)break;if(S>=n)throw"I can't think of anything. Error";g=u[r=A-1],u.splice(r,1),u.splice(0,0,g),z[g=c[g]]++,D[S++]=g}else N||(N=1,s=0),s+=0==A?N:2*N,N<<=1}if(a<0||a>=S)throw"I'm a monkey and I'm throwing something at someone, namely you";for(m=0,r=0;r<256;r++)h=m+z[r],z[r]=m,m=h;for(r=0;r>=8,R=-1);var L,B,H,O=new Uint8Array(n),P=0;for(i||(i=1/0);S;){for(S--,B=T,T=255&(M=D[M]),M>>=8,3==R++?(L=T,H=B,T=-1):(L=1,H=T);L--;)if(O[P++]=H,! --i)return O;T!=B&&(R=0)}return O.subarray(0,P)}};e.exports=t},487:e=>{var t={utf8:{stringToBytes:function(e){return t.bin.stringToBytes(unescape(encodeURIComponent(e)))},bytesToString:function(e){return decodeURIComponent(escape(t.bin.bytesToString(e)))}},bin:{stringToBytes:function(e){for(var t=[],i=0;i{var t,i;t="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",i={rotl:function(e,t){return e<>>32-t},rotr:function(e,t){return e<<32-t|e>>>t},endian:function(e){if(e.constructor==Number)return 16711935&i.rotl(e,8)|4278255360&i.rotl(e,24);for(var t=0;t0;e--)t.push(Math.floor(256*Math.random()));return t},bytesToWords:function(e){for(var t=[],i=0,n=0;i>>5]|=e[i]<<24-n%32;return t},wordsToBytes:function(e){for(var t=[],i=0;i<32*e.length;i+=8)t.push(e[i>>>5]>>>24-i%32&255);return t},bytesToHex:function(e){for(var t=[],i=0;i>>4).toString(16)),t.push((15&e[i]).toString(16));return t.join("")},hexToBytes:function(e){for(var t=[],i=0;i>>6*(3-r)&63)):i.push("=");return i.join("")},base64ToBytes:function(e){e=e.replace(/[^A-Z0-9+\/]/gi,"");for(var i=[],n=0,o=0;n>>6-2*o);return i}},e.exports=i},2949:(e,t,i)=>{i.r(t),i.d(t,{BlobFile:()=>l,LocalFile:()=>o(),RemoteFile:()=>s,fromUrl:()=>h,open:()=>d});var n=i(7067),o=i.n(n),r=i(8764);const a="undefined"!=typeof window?window:"undefined"!=typeof self?self:{fetch:void 0};class s{constructor(e,t={}){this.baseOverrides={},this.url=e;const i=t.fetch||a.fetch&&a.fetch.bind(a);if(!i)throw new TypeError("no fetch function supplied, and none found in global environment");t.overrides&&(this.baseOverrides=t.overrides),this.fetchImplementation=i}async getBufferFromResponse(e){if("function"==typeof e.buffer)return e.buffer();if("function"==typeof e.arrayBuffer){const t=await e.arrayBuffer();return r.Buffer.from(t)}throw new TypeError("invalid HTTP response object, has no buffer method, and no arrayBuffer method")}async fetch(e,t){let i;try{i=await this.fetchImplementation(e,t)}catch(n){if(!`${n}`.includes("Failed to fetch"))throw n;console.warn(`generic-filehandle: refetching ${e} to attempt to work around chrome CORS header caching bug`),i=await this.fetchImplementation(e,{...t,cache:"reload"})}return i}async read(e,t=0,i,n=0,o={}){const{headers:r={},signal:a,overrides:s={}}=o;i<1/0?r.range=`bytes=${n}-${n+i}`:i===1/0&&0!==n&&(r.range=`bytes=${n}-`);const c={...this.baseOverrides,...s,headers:{...r,...s.headers,...this.baseOverrides.headers},method:"GET",redirect:"follow",mode:"cors",signal:a},l=await this.fetch(this.url,c);if(!l.ok)throw new Error(`HTTP ${l.status} ${l.statusText} ${this.url}`);if(200===l.status&&0===n||206===l.status){const n=await this.getBufferFromResponse(l),o=n.copy(e,t,0,Math.min(i,n.length)),r=l.headers.get("content-range"),a=/\/(\d+)$/.exec(r||"");return a&&a[1]&&(this._stat={size:parseInt(a[1],10)}),{bytesRead:o,buffer:e}}if(200===l.status)throw new Error("${this.url} fetch returned status 200, expected 206");throw new Error(`HTTP ${l.status} fetching ${this.url}`)}async readFile(e={}){let t,i;"string"==typeof e?(t=e,i={}):(t=e.encoding,i=e,delete i.encoding);const{headers:n={},signal:o,overrides:r={}}=i,a={headers:n,method:"GET",redirect:"follow",mode:"cors",signal:o,...this.baseOverrides,...r},s=await this.fetch(this.url,a);if(!s)throw new Error("generic-filehandle failed to fetch");if(200!==s.status)throw Object.assign(new Error(`HTTP ${s.status} fetching ${this.url}`),{status:s.status});if("utf8"===t)return s.text();if(t)throw new Error(`unsupported encoding: ${t}`);return this.getBufferFromResponse(s)}async stat(){if(!this._stat){const e=r.Buffer.allocUnsafe(10);if(await this.read(e,0,10,0),!this._stat)throw new Error(`unable to determine size of file at ${this.url}`)}return this._stat}async close(){}}function c(e){const t=new FileReader;return new Promise(((i,n)=>{t.onerror=()=>{t.abort(),n(new Error("problem reading blob"))},t.onabort=()=>{n(new Error("blob reading was aborted"))},t.onload=()=>{t.result&&"string"!=typeof t.result?i(t.result):n(new Error("unknown error reading blob"))},t.readAsArrayBuffer(e)}))}class l{constructor(e){this.blob=e,this.size=e.size}async read(e,t=0,i,n=0){if(!i)return{bytesRead:0,buffer:e};const o=n,a=o+i,s=await c(this.blob.slice(o,a)),l=r.Buffer.from(s);return{bytesRead:l.copy(e,t),buffer:l}}async readFile(e){let t;if(t="string"==typeof e?e:e&&e.encoding,"utf8"===t)return function(e){const t=new FileReader;return new Promise(((i,n)=>{t.onerror=()=>{t.abort(),n(new Error("problem reading blob"))},t.onabort=()=>{n(new Error("blob reading was aborted"))},t.onload=()=>{t.result&&"string"==typeof t.result?i(t.result):n(new Error("unknown error reading blob"))},t.readAsText(e)}))}(this.blob);if(t)throw new Error(`unsupported encoding: ${t}`);const i=await c(this.blob);return r.Buffer.from(i)}async stat(){return{size:this.size}}async close(){}}function h(e,t={}){return new s(e,t)}function d(e,t,i,n={}){if(void 0!==i)return i;if(void 0!==e)return h(e,n);if(void 0!==t)return new(o())(t,n);throw new Error("no url, path, or filehandle provided, cannot open")}},645:(e,t)=>{t.read=function(e,t,i,n,o){var r,a,s=8*o-n-1,c=(1<>1,h=-7,d=i?o-1:0,f=i?-1:1,u=e[t+d];for(d+=f,r=u&(1<<-h)-1,u>>=-h,h+=s;h>0;r=256*r+e[t+d],d+=f,h-=8);for(a=r&(1<<-h)-1,r>>=-h,h+=n;h>0;a=256*a+e[t+d],d+=f,h-=8);if(0===r)r=1-l;else{if(r===c)return a?NaN:1/0*(u?-1:1);a+=Math.pow(2,n),r-=l}return(u?-1:1)*a*Math.pow(2,r-n)},t.write=function(e,t,i,n,o,r){var a,s,c,l=8*r-o-1,h=(1<>1,f=23===o?Math.pow(2,-24)-Math.pow(2,-77):0,u=n?0:r-1,p=n?1:-1,m=t<0||0===t&&1/t<0?1:0;for(t=Math.abs(t),isNaN(t)||t===1/0?(s=isNaN(t)?1:0,a=h):(a=Math.floor(Math.log(t)/Math.LN2),t*(c=Math.pow(2,-a))<1&&(a--,c*=2),(t+=a+d>=1?f/c:f*Math.pow(2,1-d))*c>=2&&(a++,c/=2),a+d>=h?(s=0,a=h):a+d>=1?(s=(t*c-1)*Math.pow(2,o),a+=d):(s=t*Math.pow(2,d-1)*Math.pow(2,o),a=0));o>=8;e[i+u]=255&s,u+=p,s/=256,o-=8);for(a=a<0;e[i+u]=255&a,u+=p,a/=256,l-=8);e[i+u-p]|=128*m}},8738:e=>{function t(e){return!!e.constructor&&"function"==typeof e.constructor.isBuffer&&e.constructor.isBuffer(e)}e.exports=function(e){return null!=e&&(t(e)||function(e){return"function"==typeof e.readFloatLE&&"function"==typeof e.slice&&t(e.slice(0,0))}(e)||!!e._isBuffer)}},3720:e=>{e.exports=i;var t=null;try{t=new WebAssembly.Instance(new WebAssembly.Module(new Uint8Array([0,97,115,109,1,0,0,0,1,13,2,96,0,1,127,96,4,127,127,127,127,1,127,3,7,6,0,1,1,1,1,1,6,6,1,127,1,65,0,11,7,50,6,3,109,117,108,0,1,5,100,105,118,95,115,0,2,5,100,105,118,95,117,0,3,5,114,101,109,95,115,0,4,5,114,101,109,95,117,0,5,8,103,101,116,95,104,105,103,104,0,0,10,191,1,6,4,0,35,0,11,36,1,1,126,32,0,173,32,1,173,66,32,134,132,32,2,173,32,3,173,66,32,134,132,126,34,4,66,32,135,167,36,0,32,4,167,11,36,1,1,126,32,0,173,32,1,173,66,32,134,132,32,2,173,32,3,173,66,32,134,132,127,34,4,66,32,135,167,36,0,32,4,167,11,36,1,1,126,32,0,173,32,1,173,66,32,134,132,32,2,173,32,3,173,66,32,134,132,128,34,4,66,32,135,167,36,0,32,4,167,11,36,1,1,126,32,0,173,32,1,173,66,32,134,132,32,2,173,32,3,173,66,32,134,132,129,34,4,66,32,135,167,36,0,32,4,167,11,36,1,1,126,32,0,173,32,1,173,66,32,134,132,32,2,173,32,3,173,66,32,134,132,130,34,4,66,32,135,167,36,0,32,4,167,11])),{}).exports}catch(e){}function i(e,t,i){this.low=0|e,this.high=0|t,this.unsigned=!!i}function n(e){return!0===(e&&e.__isLong__)}i.prototype.__isLong__,Object.defineProperty(i.prototype,"__isLong__",{value:!0}),i.isLong=n;var o={},r={};function a(e,t){var i,n,a;return t?(a=0<=(e>>>=0)&&e<256)&&(n=r[e])?n:(i=c(e,(0|e)<0?-1:0,!0),a&&(r[e]=i),i):(a=-128<=(e|=0)&&e<128)&&(n=o[e])?n:(i=c(e,e<0?-1:0,!1),a&&(o[e]=i),i)}function s(e,t){if(isNaN(e))return t?w:g;if(t){if(e<0)return w;if(e>=u)return _}else{if(e<=-p)return C;if(e+1>=p)return y}return e<0?s(-e,t).neg():c(e%f|0,e/f|0,t)}function c(e,t,n){return new i(e,t,n)}i.fromInt=a,i.fromNumber=s,i.fromBits=c;var l=Math.pow;function h(e,t,i){if(0===e.length)throw Error("empty string");if("NaN"===e||"Infinity"===e||"+Infinity"===e||"-Infinity"===e)return g;if("number"==typeof t?(i=t,t=!1):t=!!t,(i=i||10)<2||360)throw Error("interior hyphen");if(0===n)return h(e.substring(1),t,i).neg();for(var o=s(l(i,8)),r=g,a=0;a>>0:this.low},x.toNumber=function(){return this.unsigned?(this.high>>>0)*f+(this.low>>>0):this.high*f+(this.low>>>0)},x.toString=function(e){if((e=e||10)<2||36>>0).toString(e);if((r=c).isZero())return h+a;for(;h.length<6;)h="0"+h;a=""+h+a}},x.getHighBits=function(){return this.high},x.getHighBitsUnsigned=function(){return this.high>>>0},x.getLowBits=function(){return this.low},x.getLowBitsUnsigned=function(){return this.low>>>0},x.getNumBitsAbs=function(){if(this.isNegative())return this.eq(C)?64:this.neg().getNumBitsAbs();for(var e=0!=this.high?this.high:this.low,t=31;t>0&&!(e&1<=0},x.isOdd=function(){return!(1&~this.low)},x.isEven=function(){return!(1&this.low)},x.equals=function(e){return n(e)||(e=d(e)),(this.unsigned===e.unsigned||this.high>>>31!=1||e.high>>>31!=1)&&this.high===e.high&&this.low===e.low},x.eq=x.equals,x.notEquals=function(e){return!this.eq(e)},x.neq=x.notEquals,x.ne=x.notEquals,x.lessThan=function(e){return this.comp(e)<0},x.lt=x.lessThan,x.lessThanOrEqual=function(e){return this.comp(e)<=0},x.lte=x.lessThanOrEqual,x.le=x.lessThanOrEqual,x.greaterThan=function(e){return this.comp(e)>0},x.gt=x.greaterThan,x.greaterThanOrEqual=function(e){return this.comp(e)>=0},x.gte=x.greaterThanOrEqual,x.ge=x.greaterThanOrEqual,x.compare=function(e){if(n(e)||(e=d(e)),this.eq(e))return 0;var t=this.isNegative(),i=e.isNegative();return t&&!i?-1:!t&&i?1:this.unsigned?e.high>>>0>this.high>>>0||e.high===this.high&&e.low>>>0>this.low>>>0?-1:1:this.sub(e).isNegative()?-1:1},x.comp=x.compare,x.negate=function(){return!this.unsigned&&this.eq(C)?C:this.not().add(F)},x.neg=x.negate,x.add=function(e){n(e)||(e=d(e));var t=this.high>>>16,i=65535&this.high,o=this.low>>>16,r=65535&this.low,a=e.high>>>16,s=65535&e.high,l=e.low>>>16,h=0,f=0,u=0,p=0;return u+=(p+=r+(65535&e.low))>>>16,f+=(u+=o+l)>>>16,h+=(f+=i+s)>>>16,h+=t+a,c((u&=65535)<<16|(p&=65535),(h&=65535)<<16|(f&=65535),this.unsigned)},x.subtract=function(e){return n(e)||(e=d(e)),this.add(e.neg())},x.sub=x.subtract,x.multiply=function(e){if(this.isZero())return g;if(n(e)||(e=d(e)),t)return c(t.mul(this.low,this.high,e.low,e.high),t.get_high(),this.unsigned);if(e.isZero())return g;if(this.eq(C))return e.isOdd()?C:g;if(e.eq(C))return this.isOdd()?C:g;if(this.isNegative())return e.isNegative()?this.neg().mul(e.neg()):this.neg().mul(e).neg();if(e.isNegative())return this.mul(e.neg()).neg();if(this.lt(m)&&e.lt(m))return s(this.toNumber()*e.toNumber(),this.unsigned);var i=this.high>>>16,o=65535&this.high,r=this.low>>>16,a=65535&this.low,l=e.high>>>16,h=65535&e.high,f=e.low>>>16,u=65535&e.low,p=0,w=0,F=0,b=0;return F+=(b+=a*u)>>>16,w+=(F+=r*u)>>>16,F&=65535,w+=(F+=a*f)>>>16,p+=(w+=o*u)>>>16,w&=65535,p+=(w+=r*f)>>>16,w&=65535,p+=(w+=a*h)>>>16,p+=i*u+o*f+r*h+a*l,c((F&=65535)<<16|(b&=65535),(p&=65535)<<16|(w&=65535),this.unsigned)},x.mul=x.multiply,x.divide=function(e){if(n(e)||(e=d(e)),e.isZero())throw Error("division by zero");var i,o,r;if(t)return this.unsigned||-2147483648!==this.high||-1!==e.low||-1!==e.high?c((this.unsigned?t.div_u:t.div_s)(this.low,this.high,e.low,e.high),t.get_high(),this.unsigned):this;if(this.isZero())return this.unsigned?w:g;if(this.unsigned){if(e.unsigned||(e=e.toUnsigned()),e.gt(this))return w;if(e.gt(this.shru(1)))return b;r=w}else{if(this.eq(C))return e.eq(F)||e.eq(v)?C:e.eq(C)?F:(i=this.shr(1).div(e).shl(1)).eq(g)?e.isNegative()?F:v:(o=this.sub(e.mul(i)),r=i.add(o.div(e)));if(e.eq(C))return this.unsigned?w:g;if(this.isNegative())return e.isNegative()?this.neg().div(e.neg()):this.neg().div(e).neg();if(e.isNegative())return this.div(e.neg()).neg();r=g}for(o=this;o.gte(e);){i=Math.max(1,Math.floor(o.toNumber()/e.toNumber()));for(var a=Math.ceil(Math.log(i)/Math.LN2),h=a<=48?1:l(2,a-48),f=s(i),u=f.mul(e);u.isNegative()||u.gt(o);)u=(f=s(i-=h,this.unsigned)).mul(e);f.isZero()&&(f=F),r=r.add(f),o=o.sub(u)}return r},x.div=x.divide,x.modulo=function(e){return n(e)||(e=d(e)),t?c((this.unsigned?t.rem_u:t.rem_s)(this.low,this.high,e.low,e.high),t.get_high(),this.unsigned):this.sub(this.div(e).mul(e))},x.mod=x.modulo,x.rem=x.modulo,x.not=function(){return c(~this.low,~this.high,this.unsigned)},x.and=function(e){return n(e)||(e=d(e)),c(this.low&e.low,this.high&e.high,this.unsigned)},x.or=function(e){return n(e)||(e=d(e)),c(this.low|e.low,this.high|e.high,this.unsigned)},x.xor=function(e){return n(e)||(e=d(e)),c(this.low^e.low,this.high^e.high,this.unsigned)},x.shiftLeft=function(e){return n(e)&&(e=e.toInt()),0==(e&=63)?this:e<32?c(this.low<>>32-e,this.unsigned):c(0,this.low<>>e|this.high<<32-e,this.high>>e,this.unsigned):c(this.high>>e-32,this.high>=0?0:-1,this.unsigned)},x.shr=x.shiftRight,x.shiftRightUnsigned=function(e){if(n(e)&&(e=e.toInt()),0==(e&=63))return this;var t=this.high;return e<32?c(this.low>>>e|t<<32-e,t>>>e,this.unsigned):c(32===e?t:t>>>e-32,0,this.unsigned)},x.shru=x.shiftRightUnsigned,x.shr_u=x.shiftRightUnsigned,x.toSigned=function(){return this.unsigned?c(this.low,this.high,!1):this},x.toUnsigned=function(){return this.unsigned?this:c(this.low,this.high,!0)},x.toBytes=function(e){return e?this.toBytesLE():this.toBytesBE()},x.toBytesLE=function(){var e=this.high,t=this.low;return[255&t,t>>>8&255,t>>>16&255,t>>>24,255&e,e>>>8&255,e>>>16&255,e>>>24]},x.toBytesBE=function(){var e=this.high,t=this.low;return[e>>>24,e>>>16&255,e>>>8&255,255&e,t>>>24,t>>>16&255,t>>>8&255,255&t]},i.fromBytes=function(e,t,n){return n?i.fromBytesLE(e,t):i.fromBytesBE(e,t)},i.fromBytesLE=function(e,t){return new i(e[0]|e[1]<<8|e[2]<<16|e[3]<<24,e[4]|e[5]<<8|e[6]<<16|e[7]<<24,t)},i.fromBytesBE=function(e,t){return new i(e[4]<<24|e[5]<<16|e[6]<<8|e[7],e[0]<<24|e[1]<<16|e[2]<<8|e[3],t)}},2568:(e,t,i)=>{var n,o,r,a,s;n=i(1012),o=i(487).utf8,r=i(8738),a=i(487).bin,(s=function(e,t){e.constructor==String?e=t&&"binary"===t.encoding?a.stringToBytes(e):o.stringToBytes(e):r(e)?e=Array.prototype.slice.call(e,0):Array.isArray(e)||e.constructor===Uint8Array||(e=e.toString());for(var i=n.bytesToWords(e),c=8*e.length,l=1732584193,h=-271733879,d=-1732584194,f=271733878,u=0;u>>24)|4278255360&(i[u]<<24|i[u]>>>8);i[c>>>5]|=128<>>9<<4)]=c;var p=s._ff,m=s._gg,g=s._hh,w=s._ii;for(u=0;u>>0,h=h+b>>>0,d=d+v>>>0,f=f+y>>>0}return n.endian([l,h,d,f])})._ff=function(e,t,i,n,o,r,a){var s=e+(t&i|~t&n)+(o>>>0)+a;return(s<>>32-r)+t},s._gg=function(e,t,i,n,o,r,a){var s=e+(t&n|i&~n)+(o>>>0)+a;return(s<>>32-r)+t},s._hh=function(e,t,i,n,o,r,a){var s=e+(t^i^n)+(o>>>0)+a;return(s<>>32-r)+t},s._ii=function(e,t,i,n,o,r,a){var s=e+(i^(t|~n))+(o>>>0)+a;return(s<>>32-r)+t},s._blocksize=16,s._digestsize=16,e.exports=function(e,t){if(null==e)throw new Error("Illegal argument "+e);var i=n.wordsToBytes(s(e,t));return t&&t.asBytes?i:t&&t.asString?a.bytesToString(i):n.bytesToHex(i)}},9591:(e,t,i)=>{var n={};(0,i(4236).assign)(n,i(4555),i(8843),i(1619)),e.exports=n},4555:(e,t,i)=>{var n=i(405),o=i(4236),r=i(9373),a=i(8898),s=i(2292),c=Object.prototype.toString;function l(e){if(!(this instanceof l))return new l(e);this.options=o.assign({level:-1,method:8,chunkSize:16384,windowBits:15,memLevel:8,strategy:0,to:""},e||{});var t=this.options;t.raw&&t.windowBits>0?t.windowBits=-t.windowBits:t.gzip&&t.windowBits>0&&t.windowBits<16&&(t.windowBits+=16),this.err=0,this.msg="",this.ended=!1,this.chunks=[],this.strm=new s,this.strm.avail_out=0;var i=n.deflateInit2(this.strm,t.level,t.method,t.windowBits,t.memLevel,t.strategy);if(0!==i)throw new Error(a[i]);if(t.header&&n.deflateSetHeader(this.strm,t.header),t.dictionary){var h;if(h="string"==typeof t.dictionary?r.string2buf(t.dictionary):"[object ArrayBuffer]"===c.call(t.dictionary)?new Uint8Array(t.dictionary):t.dictionary,0!==(i=n.deflateSetDictionary(this.strm,h)))throw new Error(a[i]);this._dict_set=!0}}function h(e,t){var i=new l(t);if(i.push(e,!0),i.err)throw i.msg||a[i.err];return i.result}l.prototype.push=function(e,t){var i,a,s=this.strm,l=this.options.chunkSize;if(this.ended)return!1;a=t===~~t?t:!0===t?4:0,"string"==typeof e?s.input=r.string2buf(e):"[object ArrayBuffer]"===c.call(e)?s.input=new Uint8Array(e):s.input=e,s.next_in=0,s.avail_in=s.input.length;do{if(0===s.avail_out&&(s.output=new o.Buf8(l),s.next_out=0,s.avail_out=l),1!==(i=n.deflate(s,a))&&0!==i)return this.onEnd(i),this.ended=!0,!1;0!==s.avail_out&&(0!==s.avail_in||4!==a&&2!==a)||("string"===this.options.to?this.onData(r.buf2binstring(o.shrinkBuf(s.output,s.next_out))):this.onData(o.shrinkBuf(s.output,s.next_out)))}while((s.avail_in>0||0===s.avail_out)&&1!==i);return 4===a?(i=n.deflateEnd(this.strm),this.onEnd(i),this.ended=!0,0===i):2!==a||(this.onEnd(0),s.avail_out=0,!0)},l.prototype.onData=function(e){this.chunks.push(e)},l.prototype.onEnd=function(e){0===e&&("string"===this.options.to?this.result=this.chunks.join(""):this.result=o.flattenChunks(this.chunks)),this.chunks=[],this.err=e,this.msg=this.strm.msg},t.Deflate=l,t.deflate=h,t.deflateRaw=function(e,t){return(t=t||{}).raw=!0,h(e,t)},t.gzip=function(e,t){return(t=t||{}).gzip=!0,h(e,t)}},8843:(e,t,i)=>{var n=i(7948),o=i(4236),r=i(9373),a=i(1619),s=i(8898),c=i(2292),l=i(2401),h=Object.prototype.toString;function d(e){if(!(this instanceof d))return new d(e);this.options=o.assign({chunkSize:16384,windowBits:0,to:""},e||{});var t=this.options;t.raw&&t.windowBits>=0&&t.windowBits<16&&(t.windowBits=-t.windowBits,0===t.windowBits&&(t.windowBits=-15)),!(t.windowBits>=0&&t.windowBits<16)||e&&e.windowBits||(t.windowBits+=32),t.windowBits>15&&t.windowBits<48&&!(15&t.windowBits)&&(t.windowBits|=15),this.err=0,this.msg="",this.ended=!1,this.chunks=[],this.strm=new c,this.strm.avail_out=0;var i=n.inflateInit2(this.strm,t.windowBits);if(i!==a.Z_OK)throw new Error(s[i]);if(this.header=new l,n.inflateGetHeader(this.strm,this.header),t.dictionary&&("string"==typeof t.dictionary?t.dictionary=r.string2buf(t.dictionary):"[object ArrayBuffer]"===h.call(t.dictionary)&&(t.dictionary=new Uint8Array(t.dictionary)),t.raw&&(i=n.inflateSetDictionary(this.strm,t.dictionary))!==a.Z_OK))throw new Error(s[i])}function f(e,t){var i=new d(t);if(i.push(e,!0),i.err)throw i.msg||s[i.err];return i.result}d.prototype.push=function(e,t){var i,s,c,l,d,f=this.strm,u=this.options.chunkSize,p=this.options.dictionary,m=!1;if(this.ended)return!1;s=t===~~t?t:!0===t?a.Z_FINISH:a.Z_NO_FLUSH,"string"==typeof e?f.input=r.binstring2buf(e):"[object ArrayBuffer]"===h.call(e)?f.input=new Uint8Array(e):f.input=e,f.next_in=0,f.avail_in=f.input.length;do{if(0===f.avail_out&&(f.output=new o.Buf8(u),f.next_out=0,f.avail_out=u),(i=n.inflate(f,a.Z_NO_FLUSH))===a.Z_NEED_DICT&&p&&(i=n.inflateSetDictionary(this.strm,p)),i===a.Z_BUF_ERROR&&!0===m&&(i=a.Z_OK,m=!1),i!==a.Z_STREAM_END&&i!==a.Z_OK)return this.onEnd(i),this.ended=!0,!1;f.next_out&&(0!==f.avail_out&&i!==a.Z_STREAM_END&&(0!==f.avail_in||s!==a.Z_FINISH&&s!==a.Z_SYNC_FLUSH)||("string"===this.options.to?(c=r.utf8border(f.output,f.next_out),l=f.next_out-c,d=r.buf2string(f.output,c),f.next_out=l,f.avail_out=u-l,l&&o.arraySet(f.output,f.output,c,l,0),this.onData(d)):this.onData(o.shrinkBuf(f.output,f.next_out)))),0===f.avail_in&&0===f.avail_out&&(m=!0)}while((f.avail_in>0||0===f.avail_out)&&i!==a.Z_STREAM_END);return i===a.Z_STREAM_END&&(s=a.Z_FINISH),s===a.Z_FINISH?(i=n.inflateEnd(this.strm),this.onEnd(i),this.ended=!0,i===a.Z_OK):s!==a.Z_SYNC_FLUSH||(this.onEnd(a.Z_OK),f.avail_out=0,!0)},d.prototype.onData=function(e){this.chunks.push(e)},d.prototype.onEnd=function(e){e===a.Z_OK&&("string"===this.options.to?this.result=this.chunks.join(""):this.result=o.flattenChunks(this.chunks)),this.chunks=[],this.err=e,this.msg=this.strm.msg},t.Inflate=d,t.inflate=f,t.inflateRaw=function(e,t){return(t=t||{}).raw=!0,f(e,t)},t.ungzip=f},4236:(e,t)=>{var i="undefined"!=typeof Uint8Array&&"undefined"!=typeof Uint16Array&&"undefined"!=typeof Int32Array;function n(e,t){return Object.prototype.hasOwnProperty.call(e,t)}t.assign=function(e){for(var t=Array.prototype.slice.call(arguments,1);t.length;){var i=t.shift();if(i){if("object"!=typeof i)throw new TypeError(i+"must be non-object");for(var o in i)n(i,o)&&(e[o]=i[o])}}return e},t.shrinkBuf=function(e,t){return e.length===t?e:e.subarray?e.subarray(0,t):(e.length=t,e)};var o={arraySet:function(e,t,i,n,o){if(t.subarray&&e.subarray)e.set(t.subarray(i,i+n),o);else for(var r=0;r{var n=i(4236),o=!0,r=!0;try{String.fromCharCode.apply(null,[0])}catch(e){o=!1}try{String.fromCharCode.apply(null,new Uint8Array(1))}catch(e){r=!1}for(var a=new n.Buf8(256),s=0;s<256;s++)a[s]=s>=252?6:s>=248?5:s>=240?4:s>=224?3:s>=192?2:1;function c(e,t){if(t<65534&&(e.subarray&&r||!e.subarray&&o))return String.fromCharCode.apply(null,n.shrinkBuf(e,t));for(var i="",a=0;a>>6,t[a++]=128|63&i):i<65536?(t[a++]=224|i>>>12,t[a++]=128|i>>>6&63,t[a++]=128|63&i):(t[a++]=240|i>>>18,t[a++]=128|i>>>12&63,t[a++]=128|i>>>6&63,t[a++]=128|63&i);return t},t.buf2binstring=function(e){return c(e,e.length)},t.binstring2buf=function(e){for(var t=new n.Buf8(e.length),i=0,o=t.length;i4)l[n++]=65533,i+=r-1;else{for(o&=2===r?31:3===r?15:7;r>1&&i1?l[n++]=65533:o<65536?l[n++]=o:(o-=65536,l[n++]=55296|o>>10&1023,l[n++]=56320|1023&o)}return c(l,n)},t.utf8border=function(e,t){var i;for((t=t||e.length)>e.length&&(t=e.length),i=t-1;i>=0&&128==(192&e[i]);)i--;return i<0||0===i?t:i+a[e[i]]>t?i:t}},6069:e=>{e.exports=function(e,t,i,n){for(var o=65535&e,r=e>>>16&65535,a=0;0!==i;){i-=a=i>2e3?2e3:i;do{r=r+(o=o+t[n++]|0)|0}while(--a);o%=65521,r%=65521}return o|r<<16}},1619:e=>{e.exports={Z_NO_FLUSH:0,Z_PARTIAL_FLUSH:1,Z_SYNC_FLUSH:2,Z_FULL_FLUSH:3,Z_FINISH:4,Z_BLOCK:5,Z_TREES:6,Z_OK:0,Z_STREAM_END:1,Z_NEED_DICT:2,Z_ERRNO:-1,Z_STREAM_ERROR:-2,Z_DATA_ERROR:-3,Z_BUF_ERROR:-5,Z_NO_COMPRESSION:0,Z_BEST_SPEED:1,Z_BEST_COMPRESSION:9,Z_DEFAULT_COMPRESSION:-1,Z_FILTERED:1,Z_HUFFMAN_ONLY:2,Z_RLE:3,Z_FIXED:4,Z_DEFAULT_STRATEGY:0,Z_BINARY:0,Z_TEXT:1,Z_UNKNOWN:2,Z_DEFLATED:8}},2869:e=>{var t=function(){for(var e,t=[],i=0;i<256;i++){e=i;for(var n=0;n<8;n++)e=1&e?3988292384^e>>>1:e>>>1;t[i]=e}return t}();e.exports=function(e,i,n,o){var r=t,a=o+n;e^=-1;for(var s=o;s>>8^r[255&(e^i[s])];return~e}},405:(e,t,i)=>{var n,o=i(4236),r=i(342),a=i(6069),s=i(2869),c=i(8898),l=-2,h=258,d=262,f=103,u=113,p=666;function m(e,t){return e.msg=c[t],t}function g(e){return(e<<1)-(e>4?9:0)}function w(e){for(var t=e.length;--t>=0;)e[t]=0}function F(e){var t=e.state,i=t.pending;i>e.avail_out&&(i=e.avail_out),0!==i&&(o.arraySet(e.output,t.pending_buf,t.pending_out,i,e.next_out),e.next_out+=i,t.pending_out+=i,e.total_out+=i,e.avail_out-=i,t.pending-=i,0===t.pending&&(t.pending_out=0))}function b(e,t){r._tr_flush_block(e,e.block_start>=0?e.block_start:-1,e.strstart-e.block_start,t),e.block_start=e.strstart,F(e.strm)}function v(e,t){e.pending_buf[e.pending++]=t}function y(e,t){e.pending_buf[e.pending++]=t>>>8&255,e.pending_buf[e.pending++]=255&t}function _(e,t,i,n){var r=e.avail_in;return r>n&&(r=n),0===r?0:(e.avail_in-=r,o.arraySet(t,e.input,e.next_in,r,i),1===e.state.wrap?e.adler=a(e.adler,t,r,i):2===e.state.wrap&&(e.adler=s(e.adler,t,r,i)),e.next_in+=r,e.total_in+=r,r)}function C(e,t){var i,n,o=e.max_chain_length,r=e.strstart,a=e.prev_length,s=e.nice_match,c=e.strstart>e.w_size-d?e.strstart-(e.w_size-d):0,l=e.window,f=e.w_mask,u=e.prev,p=e.strstart+h,m=l[r+a-1],g=l[r+a];e.prev_length>=e.good_match&&(o>>=2),s>e.lookahead&&(s=e.lookahead);do{if(l[(i=t)+a]===g&&l[i+a-1]===m&&l[i]===l[r]&&l[++i]===l[r+1]){r+=2,i++;do{}while(l[++r]===l[++i]&&l[++r]===l[++i]&&l[++r]===l[++i]&&l[++r]===l[++i]&&l[++r]===l[++i]&&l[++r]===l[++i]&&l[++r]===l[++i]&&l[++r]===l[++i]&&ra){if(e.match_start=t,a=n,n>=s)break;m=l[r+a-1],g=l[r+a]}}}while((t=u[t&f])>c&&0!=--o);return a<=e.lookahead?a:e.lookahead}function x(e){var t,i,n,r,a,s=e.w_size;do{if(r=e.window_size-e.lookahead-e.strstart,e.strstart>=s+(s-d)){o.arraySet(e.window,e.window,s,s,0),e.match_start-=s,e.strstart-=s,e.block_start-=s,t=i=e.hash_size;do{n=e.head[--t],e.head[t]=n>=s?n-s:0}while(--i);t=i=s;do{n=e.prev[--t],e.prev[t]=n>=s?n-s:0}while(--i);r+=s}if(0===e.strm.avail_in)break;if(i=_(e.strm,e.window,e.strstart+e.lookahead,r),e.lookahead+=i,e.lookahead+e.insert>=3)for(a=e.strstart-e.insert,e.ins_h=e.window[a],e.ins_h=(e.ins_h<=3&&(e.ins_h=(e.ins_h<=3)if(n=r._tr_tally(e,e.strstart-e.match_start,e.match_length-3),e.lookahead-=e.match_length,e.match_length<=e.max_lazy_match&&e.lookahead>=3){e.match_length--;do{e.strstart++,e.ins_h=(e.ins_h<=3&&(e.ins_h=(e.ins_h<4096)&&(e.match_length=2)),e.prev_length>=3&&e.match_length<=e.prev_length){o=e.strstart+e.lookahead-3,n=r._tr_tally(e,e.strstart-1-e.prev_match,e.prev_length-3),e.lookahead-=e.prev_length-1,e.prev_length-=2;do{++e.strstart<=o&&(e.ins_h=(e.ins_h<15&&(s=2,n-=16),r<1||r>9||8!==i||n<8||n>15||t<0||t>9||a<0||a>4)return m(e,l);8===n&&(n=9);var c=new S;return e.state=c,c.strm=e,c.wrap=s,c.gzhead=null,c.w_bits=n,c.w_size=1<e.pending_buf_size-5&&(i=e.pending_buf_size-5);;){if(e.lookahead<=1){if(x(e),0===e.lookahead&&0===t)return 1;if(0===e.lookahead)break}e.strstart+=e.lookahead,e.lookahead=0;var n=e.block_start+i;if((0===e.strstart||e.strstart>=n)&&(e.lookahead=e.strstart-n,e.strstart=n,b(e,!1),0===e.strm.avail_out))return 1;if(e.strstart-e.block_start>=e.w_size-d&&(b(e,!1),0===e.strm.avail_out))return 1}return e.insert=0,4===t?(b(e,!0),0===e.strm.avail_out?3:4):(e.strstart>e.block_start&&(b(e,!1),e.strm.avail_out),1)})),new N(4,4,8,4,k),new N(4,5,16,8,k),new N(4,6,32,32,k),new N(4,4,16,16,E),new N(8,16,32,32,E),new N(8,16,128,128,E),new N(8,32,128,256,E),new N(32,128,258,1024,E),new N(32,258,258,4096,E)],t.deflateInit=function(e,t){return D(e,t,8,15,8,0)},t.deflateInit2=D,t.deflateReset=z,t.deflateResetKeep=I,t.deflateSetHeader=function(e,t){return e&&e.state?2!==e.state.wrap?l:(e.state.gzhead=t,0):l},t.deflate=function(e,t){var i,o,a,c;if(!e||!e.state||t>5||t<0)return e?m(e,l):l;if(o=e.state,!e.output||!e.input&&0!==e.avail_in||o.status===p&&4!==t)return m(e,0===e.avail_out?-5:l);if(o.strm=e,i=o.last_flush,o.last_flush=t,42===o.status)if(2===o.wrap)e.adler=0,v(o,31),v(o,139),v(o,8),o.gzhead?(v(o,(o.gzhead.text?1:0)+(o.gzhead.hcrc?2:0)+(o.gzhead.extra?4:0)+(o.gzhead.name?8:0)+(o.gzhead.comment?16:0)),v(o,255&o.gzhead.time),v(o,o.gzhead.time>>8&255),v(o,o.gzhead.time>>16&255),v(o,o.gzhead.time>>24&255),v(o,9===o.level?2:o.strategy>=2||o.level<2?4:0),v(o,255&o.gzhead.os),o.gzhead.extra&&o.gzhead.extra.length&&(v(o,255&o.gzhead.extra.length),v(o,o.gzhead.extra.length>>8&255)),o.gzhead.hcrc&&(e.adler=s(e.adler,o.pending_buf,o.pending,0)),o.gzindex=0,o.status=69):(v(o,0),v(o,0),v(o,0),v(o,0),v(o,0),v(o,9===o.level?2:o.strategy>=2||o.level<2?4:0),v(o,3),o.status=u);else{var d=8+(o.w_bits-8<<4)<<8;d|=(o.strategy>=2||o.level<2?0:o.level<6?1:6===o.level?2:3)<<6,0!==o.strstart&&(d|=32),d+=31-d%31,o.status=u,y(o,d),0!==o.strstart&&(y(o,e.adler>>>16),y(o,65535&e.adler)),e.adler=1}if(69===o.status)if(o.gzhead.extra){for(a=o.pending;o.gzindex<(65535&o.gzhead.extra.length)&&(o.pending!==o.pending_buf_size||(o.gzhead.hcrc&&o.pending>a&&(e.adler=s(e.adler,o.pending_buf,o.pending-a,a)),F(e),a=o.pending,o.pending!==o.pending_buf_size));)v(o,255&o.gzhead.extra[o.gzindex]),o.gzindex++;o.gzhead.hcrc&&o.pending>a&&(e.adler=s(e.adler,o.pending_buf,o.pending-a,a)),o.gzindex===o.gzhead.extra.length&&(o.gzindex=0,o.status=73)}else o.status=73;if(73===o.status)if(o.gzhead.name){a=o.pending;do{if(o.pending===o.pending_buf_size&&(o.gzhead.hcrc&&o.pending>a&&(e.adler=s(e.adler,o.pending_buf,o.pending-a,a)),F(e),a=o.pending,o.pending===o.pending_buf_size)){c=1;break}c=o.gzindexa&&(e.adler=s(e.adler,o.pending_buf,o.pending-a,a)),0===c&&(o.gzindex=0,o.status=91)}else o.status=91;if(91===o.status)if(o.gzhead.comment){a=o.pending;do{if(o.pending===o.pending_buf_size&&(o.gzhead.hcrc&&o.pending>a&&(e.adler=s(e.adler,o.pending_buf,o.pending-a,a)),F(e),a=o.pending,o.pending===o.pending_buf_size)){c=1;break}c=o.gzindexa&&(e.adler=s(e.adler,o.pending_buf,o.pending-a,a)),0===c&&(o.status=f)}else o.status=f;if(o.status===f&&(o.gzhead.hcrc?(o.pending+2>o.pending_buf_size&&F(e),o.pending+2<=o.pending_buf_size&&(v(o,255&e.adler),v(o,e.adler>>8&255),e.adler=0,o.status=u)):o.status=u),0!==o.pending){if(F(e),0===e.avail_out)return o.last_flush=-1,0}else if(0===e.avail_in&&g(t)<=g(i)&&4!==t)return m(e,-5);if(o.status===p&&0!==e.avail_in)return m(e,-5);if(0!==e.avail_in||0!==o.lookahead||0!==t&&o.status!==p){var _=2===o.strategy?function(e,t){for(var i;;){if(0===e.lookahead&&(x(e),0===e.lookahead)){if(0===t)return 1;break}if(e.match_length=0,i=r._tr_tally(e,0,e.window[e.strstart]),e.lookahead--,e.strstart++,i&&(b(e,!1),0===e.strm.avail_out))return 1}return e.insert=0,4===t?(b(e,!0),0===e.strm.avail_out?3:4):e.last_lit&&(b(e,!1),0===e.strm.avail_out)?1:2}(o,t):3===o.strategy?function(e,t){for(var i,n,o,a,s=e.window;;){if(e.lookahead<=h){if(x(e),e.lookahead<=h&&0===t)return 1;if(0===e.lookahead)break}if(e.match_length=0,e.lookahead>=3&&e.strstart>0&&(n=s[o=e.strstart-1])===s[++o]&&n===s[++o]&&n===s[++o]){a=e.strstart+h;do{}while(n===s[++o]&&n===s[++o]&&n===s[++o]&&n===s[++o]&&n===s[++o]&&n===s[++o]&&n===s[++o]&&n===s[++o]&&oe.lookahead&&(e.match_length=e.lookahead)}if(e.match_length>=3?(i=r._tr_tally(e,1,e.match_length-3),e.lookahead-=e.match_length,e.strstart+=e.match_length,e.match_length=0):(i=r._tr_tally(e,0,e.window[e.strstart]),e.lookahead--,e.strstart++),i&&(b(e,!1),0===e.strm.avail_out))return 1}return e.insert=0,4===t?(b(e,!0),0===e.strm.avail_out?3:4):e.last_lit&&(b(e,!1),0===e.strm.avail_out)?1:2}(o,t):n[o.level].func(o,t);if(3!==_&&4!==_||(o.status=p),1===_||3===_)return 0===e.avail_out&&(o.last_flush=-1),0;if(2===_&&(1===t?r._tr_align(o):5!==t&&(r._tr_stored_block(o,0,0,!1),3===t&&(w(o.head),0===o.lookahead&&(o.strstart=0,o.block_start=0,o.insert=0))),F(e),0===e.avail_out))return o.last_flush=-1,0}return 4!==t?0:o.wrap<=0?1:(2===o.wrap?(v(o,255&e.adler),v(o,e.adler>>8&255),v(o,e.adler>>16&255),v(o,e.adler>>24&255),v(o,255&e.total_in),v(o,e.total_in>>8&255),v(o,e.total_in>>16&255),v(o,e.total_in>>24&255)):(y(o,e.adler>>>16),y(o,65535&e.adler)),F(e),o.wrap>0&&(o.wrap=-o.wrap),0!==o.pending?0:1)},t.deflateEnd=function(e){var t;return e&&e.state?42!==(t=e.state.status)&&69!==t&&73!==t&&91!==t&&t!==f&&t!==u&&t!==p?m(e,l):(e.state=null,t===u?m(e,-3):0):l},t.deflateSetDictionary=function(e,t){var i,n,r,s,c,h,d,f,u=t.length;if(!e||!e.state)return l;if(2===(s=(i=e.state).wrap)||1===s&&42!==i.status||i.lookahead)return l;for(1===s&&(e.adler=a(e.adler,t,u,0)),i.wrap=0,u>=i.w_size&&(0===s&&(w(i.head),i.strstart=0,i.block_start=0,i.insert=0),f=new o.Buf8(i.w_size),o.arraySet(f,t,u-i.w_size,i.w_size,0),t=f,u=i.w_size),c=e.avail_in,h=e.next_in,d=e.input,e.avail_in=u,e.next_in=0,e.input=t,x(i);i.lookahead>=3;){n=i.strstart,r=i.lookahead-2;do{i.ins_h=(i.ins_h<{e.exports=function(){this.text=0,this.time=0,this.xflags=0,this.os=0,this.extra=null,this.extra_len=0,this.name="",this.comment="",this.hcrc=0,this.done=!1}},4264:e=>{e.exports=function(e,t){var i,n,o,r,a,s,c,l,h,d,f,u,p,m,g,w,F,b,v,y,_,C,x,k,E;i=e.state,n=e.next_in,k=e.input,o=n+(e.avail_in-5),r=e.next_out,E=e.output,a=r-(t-e.avail_out),s=r+(e.avail_out-257),c=i.dmax,l=i.wsize,h=i.whave,d=i.wnext,f=i.window,u=i.hold,p=i.bits,m=i.lencode,g=i.distcode,w=(1<>>=v=b>>>24,p-=v,0==(v=b>>>16&255))E[r++]=65535&b;else{if(!(16&v)){if(!(64&v)){b=m[(65535&b)+(u&(1<>>=v,p-=v),p<15&&(u+=k[n++]<>>=v=b>>>24,p-=v,!(16&(v=b>>>16&255))){if(!(64&v)){b=g[(65535&b)+(u&(1<c){e.msg="invalid distance too far back",i.mode=30;break e}if(u>>>=v,p-=v,_>(v=r-a)){if((v=_-v)>h&&i.sane){e.msg="invalid distance too far back",i.mode=30;break e}if(C=0,x=f,0===d){if(C+=l-v,v2;)E[r++]=x[C++],E[r++]=x[C++],E[r++]=x[C++],y-=3;y&&(E[r++]=x[C++],y>1&&(E[r++]=x[C++]))}else{C=r-_;do{E[r++]=E[C++],E[r++]=E[C++],E[r++]=E[C++],y-=3}while(y>2);y&&(E[r++]=E[C++],y>1&&(E[r++]=E[C++]))}break}}break}}while(n>3,u&=(1<<(p-=y<<3))-1,e.next_in=n,e.next_out=r,e.avail_in=n{var n=i(4236),o=i(6069),r=i(2869),a=i(4264),s=i(9241),c=-2,l=12,h=30;function d(e){return(e>>>24&255)+(e>>>8&65280)+((65280&e)<<8)+((255&e)<<24)}function f(){this.mode=0,this.last=!1,this.wrap=0,this.havedict=!1,this.flags=0,this.dmax=0,this.check=0,this.total=0,this.head=null,this.wbits=0,this.wsize=0,this.whave=0,this.wnext=0,this.window=null,this.hold=0,this.bits=0,this.length=0,this.offset=0,this.extra=0,this.lencode=null,this.distcode=null,this.lenbits=0,this.distbits=0,this.ncode=0,this.nlen=0,this.ndist=0,this.have=0,this.next=null,this.lens=new n.Buf16(320),this.work=new n.Buf16(288),this.lendyn=null,this.distdyn=null,this.sane=0,this.back=0,this.was=0}function u(e){var t;return e&&e.state?(t=e.state,e.total_in=e.total_out=t.total=0,e.msg="",t.wrap&&(e.adler=1&t.wrap),t.mode=1,t.last=0,t.havedict=0,t.dmax=32768,t.head=null,t.hold=0,t.bits=0,t.lencode=t.lendyn=new n.Buf32(852),t.distcode=t.distdyn=new n.Buf32(592),t.sane=1,t.back=-1,0):c}function p(e){var t;return e&&e.state?((t=e.state).wsize=0,t.whave=0,t.wnext=0,u(e)):c}function m(e,t){var i,n;return e&&e.state?(n=e.state,t<0?(i=0,t=-t):(i=1+(t>>4),t<48&&(t&=15)),t&&(t<8||t>15)?c:(null!==n.window&&n.wbits!==t&&(n.window=null),n.wrap=i,n.wbits=t,p(e))):c}function g(e,t){var i,n;return e?(n=new f,e.state=n,n.window=null,0!==(i=m(e,t))&&(e.state=null),i):c}var w,F,b=!0;function v(e){if(b){var t;for(w=new n.Buf32(512),F=new n.Buf32(32),t=0;t<144;)e.lens[t++]=8;for(;t<256;)e.lens[t++]=9;for(;t<280;)e.lens[t++]=7;for(;t<288;)e.lens[t++]=8;for(s(1,e.lens,0,288,w,0,e.work,{bits:9}),t=0;t<32;)e.lens[t++]=5;s(2,e.lens,0,32,F,0,e.work,{bits:5}),b=!1}e.lencode=w,e.lenbits=9,e.distcode=F,e.distbits=5}function y(e,t,i,o){var r,a=e.state;return null===a.window&&(a.wsize=1<=a.wsize?(n.arraySet(a.window,t,i-a.wsize,a.wsize,0),a.wnext=0,a.whave=a.wsize):((r=a.wsize-a.wnext)>o&&(r=o),n.arraySet(a.window,t,i-o,r,a.wnext),(o-=r)?(n.arraySet(a.window,t,i-o,o,0),a.wnext=o,a.whave=a.wsize):(a.wnext+=r,a.wnext===a.wsize&&(a.wnext=0),a.whave>>8&255,i.check=r(i.check,H,2,0),F=0,b=0,i.mode=2;break}if(i.flags=0,i.head&&(i.head.done=!1),!(1&i.wrap)||(((255&F)<<8)+(F>>8))%31){e.msg="incorrect header check",i.mode=h;break}if(8!=(15&F)){e.msg="unknown compression method",i.mode=h;break}if(b-=4,M=8+(15&(F>>>=4)),0===i.wbits)i.wbits=M;else if(M>i.wbits){e.msg="invalid window size",i.mode=h;break}i.dmax=1<>8&1),512&i.flags&&(H[0]=255&F,H[1]=F>>>8&255,i.check=r(i.check,H,2,0)),F=0,b=0,i.mode=3;case 3:for(;b<32;){if(0===g)break e;g--,F+=f[p++]<>>8&255,H[2]=F>>>16&255,H[3]=F>>>24&255,i.check=r(i.check,H,4,0)),F=0,b=0,i.mode=4;case 4:for(;b<16;){if(0===g)break e;g--,F+=f[p++]<>8),512&i.flags&&(H[0]=255&F,H[1]=F>>>8&255,i.check=r(i.check,H,2,0)),F=0,b=0,i.mode=5;case 5:if(1024&i.flags){for(;b<16;){if(0===g)break e;g--,F+=f[p++]<>>8&255,i.check=r(i.check,H,2,0)),F=0,b=0}else i.head&&(i.head.extra=null);i.mode=6;case 6:if(1024&i.flags&&((x=i.length)>g&&(x=g),x&&(i.head&&(M=i.head.extra_len-i.length,i.head.extra||(i.head.extra=new Array(i.head.extra_len)),n.arraySet(i.head.extra,f,p,x,M)),512&i.flags&&(i.check=r(i.check,f,x,p)),g-=x,p+=x,i.length-=x),i.length))break e;i.length=0,i.mode=7;case 7:if(2048&i.flags){if(0===g)break e;x=0;do{M=f[p+x++],i.head&&M&&i.length<65536&&(i.head.name+=String.fromCharCode(M))}while(M&&x>9&1,i.head.done=!0),e.adler=i.check=0,i.mode=l;break;case 10:for(;b<32;){if(0===g)break e;g--,F+=f[p++]<>>=7&b,b-=7&b,i.mode=27;break}for(;b<3;){if(0===g)break e;g--,F+=f[p++]<>>=1)){case 0:i.mode=14;break;case 1:if(v(i),i.mode=20,6===t){F>>>=2,b-=2;break e}break;case 2:i.mode=17;break;case 3:e.msg="invalid block type",i.mode=h}F>>>=2,b-=2;break;case 14:for(F>>>=7&b,b-=7&b;b<32;){if(0===g)break e;g--,F+=f[p++]<>>16^65535)){e.msg="invalid stored block lengths",i.mode=h;break}if(i.length=65535&F,F=0,b=0,i.mode=15,6===t)break e;case 15:i.mode=16;case 16:if(x=i.length){if(x>g&&(x=g),x>w&&(x=w),0===x)break e;n.arraySet(u,f,p,x,m),g-=x,p+=x,w-=x,m+=x,i.length-=x;break}i.mode=l;break;case 17:for(;b<14;){if(0===g)break e;g--,F+=f[p++]<>>=5,b-=5,i.ndist=1+(31&F),F>>>=5,b-=5,i.ncode=4+(15&F),F>>>=4,b-=4,i.nlen>286||i.ndist>30){e.msg="too many length or distance symbols",i.mode=h;break}i.have=0,i.mode=18;case 18:for(;i.have>>=3,b-=3}for(;i.have<19;)i.lens[O[i.have++]]=0;if(i.lencode=i.lendyn,i.lenbits=7,R={bits:i.lenbits},T=s(0,i.lens,0,19,i.lencode,0,i.work,R),i.lenbits=R.bits,T){e.msg="invalid code lengths set",i.mode=h;break}i.have=0,i.mode=19;case 19:for(;i.have>>16&255,I=65535&B,!((N=B>>>24)<=b);){if(0===g)break e;g--,F+=f[p++]<>>=N,b-=N,i.lens[i.have++]=I;else{if(16===I){for(L=N+2;b>>=N,b-=N,0===i.have){e.msg="invalid bit length repeat",i.mode=h;break}M=i.lens[i.have-1],x=3+(3&F),F>>>=2,b-=2}else if(17===I){for(L=N+3;b>>=N)),F>>>=3,b-=3}else{for(L=N+7;b>>=N)),F>>>=7,b-=7}if(i.have+x>i.nlen+i.ndist){e.msg="invalid bit length repeat",i.mode=h;break}for(;x--;)i.lens[i.have++]=M}}if(i.mode===h)break;if(0===i.lens[256]){e.msg="invalid code -- missing end-of-block",i.mode=h;break}if(i.lenbits=9,R={bits:i.lenbits},T=s(1,i.lens,0,i.nlen,i.lencode,0,i.work,R),i.lenbits=R.bits,T){e.msg="invalid literal/lengths set",i.mode=h;break}if(i.distbits=6,i.distcode=i.distdyn,R={bits:i.distbits},T=s(2,i.lens,i.nlen,i.ndist,i.distcode,0,i.work,R),i.distbits=R.bits,T){e.msg="invalid distances set",i.mode=h;break}if(i.mode=20,6===t)break e;case 20:i.mode=21;case 21:if(g>=6&&w>=258){e.next_out=m,e.avail_out=w,e.next_in=p,e.avail_in=g,i.hold=F,i.bits=b,a(e,C),m=e.next_out,u=e.output,w=e.avail_out,p=e.next_in,f=e.input,g=e.avail_in,F=i.hold,b=i.bits,i.mode===l&&(i.back=-1);break}for(i.back=0;S=(B=i.lencode[F&(1<>>16&255,I=65535&B,!((N=B>>>24)<=b);){if(0===g)break e;g--,F+=f[p++]<>z)])>>>16&255,I=65535&B,!(z+(N=B>>>24)<=b);){if(0===g)break e;g--,F+=f[p++]<>>=z,b-=z,i.back+=z}if(F>>>=N,b-=N,i.back+=N,i.length=I,0===S){i.mode=26;break}if(32&S){i.back=-1,i.mode=l;break}if(64&S){e.msg="invalid literal/length code",i.mode=h;break}i.extra=15&S,i.mode=22;case 22:if(i.extra){for(L=i.extra;b>>=i.extra,b-=i.extra,i.back+=i.extra}i.was=i.length,i.mode=23;case 23:for(;S=(B=i.distcode[F&(1<>>16&255,I=65535&B,!((N=B>>>24)<=b);){if(0===g)break e;g--,F+=f[p++]<>z)])>>>16&255,I=65535&B,!(z+(N=B>>>24)<=b);){if(0===g)break e;g--,F+=f[p++]<>>=z,b-=z,i.back+=z}if(F>>>=N,b-=N,i.back+=N,64&S){e.msg="invalid distance code",i.mode=h;break}i.offset=I,i.extra=15&S,i.mode=24;case 24:if(i.extra){for(L=i.extra;b>>=i.extra,b-=i.extra,i.back+=i.extra}if(i.offset>i.dmax){e.msg="invalid distance too far back",i.mode=h;break}i.mode=25;case 25:if(0===w)break e;if(x=C-w,i.offset>x){if((x=i.offset-x)>i.whave&&i.sane){e.msg="invalid distance too far back",i.mode=h;break}x>i.wnext?(x-=i.wnext,k=i.wsize-x):k=i.wnext-x,x>i.length&&(x=i.length),E=i.window}else E=u,k=m-i.offset,x=i.length;x>w&&(x=w),w-=x,i.length-=x;do{u[m++]=E[k++]}while(--x);0===i.length&&(i.mode=21);break;case 26:if(0===w)break e;u[m++]=i.length,w--,i.mode=21;break;case 27:if(i.wrap){for(;b<32;){if(0===g)break e;g--,F|=f[p++]<{var n=i(4236),o=[3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258,0,0],r=[16,16,16,16,16,16,16,16,17,17,17,17,18,18,18,18,19,19,19,19,20,20,20,20,21,21,21,21,16,72,78],a=[1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,0,0],s=[16,16,16,16,17,17,18,18,19,19,20,20,21,21,22,22,23,23,24,24,25,25,26,26,27,27,28,28,29,29,64,64];e.exports=function(e,t,i,c,l,h,d,f){var u,p,m,g,w,F,b,v,y,_=f.bits,C=0,x=0,k=0,E=0,N=0,S=0,I=0,z=0,D=0,A=0,M=null,T=0,R=new n.Buf16(16),L=new n.Buf16(16),B=null,H=0;for(C=0;C<=15;C++)R[C]=0;for(x=0;x=1&&0===R[E];E--);if(N>E&&(N=E),0===E)return l[h++]=20971520,l[h++]=20971520,f.bits=1,0;for(k=1;k0&&(0===e||1!==E))return-1;for(L[1]=0,C=1;C<15;C++)L[C+1]=L[C]+R[C];for(x=0;x852||2===e&&D>592)return 1;for(;;){b=C-I,d[x]F?(v=B[H+d[x]],y=M[T+d[x]]):(v=96,y=0),u=1<>I)+(p-=u)]=b<<24|v<<16|y}while(0!==p);for(u=1<>=1;if(0!==u?(A&=u-1,A+=u):A=0,x++,0==--R[C]){if(C===E)break;C=t[i+d[x]]}if(C>N&&(A&g)!==m){for(0===I&&(I=N),w+=k,z=1<<(S=C-I);S+I852||2===e&&D>592)return 1;l[m=A&g]=N<<24|S<<16|w-h}}return 0!==A&&(l[w+A]=C-I<<24|64<<16),f.bits=N,0}},8898:e=>{e.exports={2:"need dictionary",1:"stream end",0:"","-1":"file error","-2":"stream error","-3":"data error","-4":"insufficient memory","-5":"buffer error","-6":"incompatible version"}},342:(e,t,i)=>{var n=i(4236);function o(e){for(var t=e.length;--t>=0;)e[t]=0}var r=[0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0],a=[0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13],s=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7],c=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15],l=new Array(576);o(l);var h=new Array(60);o(h);var d=new Array(512);o(d);var f=new Array(256);o(f);var u=new Array(29);o(u);var p,m,g,w=new Array(30);function F(e,t,i,n,o){this.static_tree=e,this.extra_bits=t,this.extra_base=i,this.elems=n,this.max_length=o,this.has_stree=e&&e.length}function b(e,t){this.dyn_tree=e,this.max_code=0,this.stat_desc=t}function v(e){return e<256?d[e]:d[256+(e>>>7)]}function y(e,t){e.pending_buf[e.pending++]=255&t,e.pending_buf[e.pending++]=t>>>8&255}function _(e,t,i){e.bi_valid>16-i?(e.bi_buf|=t<>16-e.bi_valid,e.bi_valid+=i-16):(e.bi_buf|=t<>>=1,i<<=1}while(--t>0);return i>>>1}function k(e,t,i){var n,o,r=new Array(16),a=0;for(n=1;n<=15;n++)r[n]=a=a+i[n-1]<<1;for(o=0;o<=t;o++){var s=e[2*o+1];0!==s&&(e[2*o]=x(r[s]++,s))}}function E(e){var t;for(t=0;t<286;t++)e.dyn_ltree[2*t]=0;for(t=0;t<30;t++)e.dyn_dtree[2*t]=0;for(t=0;t<19;t++)e.bl_tree[2*t]=0;e.dyn_ltree[512]=1,e.opt_len=e.static_len=0,e.last_lit=e.matches=0}function N(e){e.bi_valid>8?y(e,e.bi_buf):e.bi_valid>0&&(e.pending_buf[e.pending++]=e.bi_buf),e.bi_buf=0,e.bi_valid=0}function S(e,t,i,n){var o=2*t,r=2*i;return e[o]>1;i>=1;i--)I(e,r,i);o=c;do{i=e.heap[1],e.heap[1]=e.heap[e.heap_len--],I(e,r,1),n=e.heap[1],e.heap[--e.heap_max]=i,e.heap[--e.heap_max]=n,r[2*o]=r[2*i]+r[2*n],e.depth[o]=(e.depth[i]>=e.depth[n]?e.depth[i]:e.depth[n])+1,r[2*i+1]=r[2*n+1]=o,e.heap[1]=o++,I(e,r,1)}while(e.heap_len>=2);e.heap[--e.heap_max]=e.heap[1],function(e,t){var i,n,o,r,a,s,c=t.dyn_tree,l=t.max_code,h=t.stat_desc.static_tree,d=t.stat_desc.has_stree,f=t.stat_desc.extra_bits,u=t.stat_desc.extra_base,p=t.stat_desc.max_length,m=0;for(r=0;r<=15;r++)e.bl_count[r]=0;for(c[2*e.heap[e.heap_max]+1]=0,i=e.heap_max+1;i<573;i++)(r=c[2*c[2*(n=e.heap[i])+1]+1]+1)>p&&(r=p,m++),c[2*n+1]=r,n>l||(e.bl_count[r]++,a=0,n>=u&&(a=f[n-u]),s=c[2*n],e.opt_len+=s*(r+a),d&&(e.static_len+=s*(h[2*n+1]+a)));if(0!==m){do{for(r=p-1;0===e.bl_count[r];)r--;e.bl_count[r]--,e.bl_count[r+1]+=2,e.bl_count[p]--,m-=2}while(m>0);for(r=p;0!==r;r--)for(n=e.bl_count[r];0!==n;)(o=e.heap[--i])>l||(c[2*o+1]!==r&&(e.opt_len+=(r-c[2*o+1])*c[2*o],c[2*o+1]=r),n--)}}(e,t),k(r,l,e.bl_count)}function A(e,t,i){var n,o,r=-1,a=t[1],s=0,c=7,l=4;for(0===a&&(c=138,l=3),t[2*(i+1)+1]=65535,n=0;n<=i;n++)o=a,a=t[2*(n+1)+1],++s>=7;n<30;n++)for(w[n]=o<<7,e=0;e<1<0?(2===e.strm.data_type&&(e.strm.data_type=function(e){var t,i=4093624447;for(t=0;t<=31;t++,i>>>=1)if(1&i&&0!==e.dyn_ltree[2*t])return 0;if(0!==e.dyn_ltree[18]||0!==e.dyn_ltree[20]||0!==e.dyn_ltree[26])return 1;for(t=32;t<256;t++)if(0!==e.dyn_ltree[2*t])return 1;return 0}(e)),D(e,e.l_desc),D(e,e.d_desc),a=function(e){var t;for(A(e,e.dyn_ltree,e.l_desc.max_code),A(e,e.dyn_dtree,e.d_desc.max_code),D(e,e.bl_desc),t=18;t>=3&&0===e.bl_tree[2*c[t]+1];t--);return e.opt_len+=3*(t+1)+5+5+4,t}(e),o=e.opt_len+3+7>>>3,(r=e.static_len+3+7>>>3)<=o&&(o=r)):o=r=i+5,i+4<=o&&-1!==t?R(e,t,i,n):4===e.strategy||r===o?(_(e,2+(n?1:0),3),z(e,l,h)):(_(e,4+(n?1:0),3),function(e,t,i,n){var o;for(_(e,t-257,5),_(e,i-1,5),_(e,n-4,4),o=0;o>>8&255,e.pending_buf[e.d_buf+2*e.last_lit+1]=255&t,e.pending_buf[e.l_buf+e.last_lit]=255&i,e.last_lit++,0===t?e.dyn_ltree[2*i]++:(e.matches++,t--,e.dyn_ltree[2*(f[i]+256+1)]++,e.dyn_dtree[2*v(t)]++),e.last_lit===e.lit_bufsize-1},t._tr_align=function(e){_(e,2,3),C(e,256,l),function(e){16===e.bi_valid?(y(e,e.bi_buf),e.bi_buf=0,e.bi_valid=0):e.bi_valid>=8&&(e.pending_buf[e.pending++]=255&e.bi_buf,e.bi_buf>>=8,e.bi_valid-=8)}(e)}},2292:e=>{e.exports=function(){this.input=null,this.next_in=0,this.avail_in=0,this.total_in=0,this.output=null,this.next_out=0,this.avail_out=0,this.total_out=0,this.msg="",this.state=null,this.data_type=2,this.adler=0}},2587:e=>{function t(e,t){return Object.prototype.hasOwnProperty.call(e,t)}e.exports=function(e,i,n,o){i=i||"&",n=n||"=";var r={};if("string"!=typeof e||0===e.length)return r;var a=/\+/g;e=e.split(i);var s=1e3;o&&"number"==typeof o.maxKeys&&(s=o.maxKeys);var c=e.length;s>0&&c>s&&(c=s);for(var l=0;l=0?(h=p.substr(0,m),d=p.substr(m+1)):(h=p,d=""),f=decodeURIComponent(h),u=decodeURIComponent(d),t(r,f)?Array.isArray(r[f])?r[f].push(u):r[f]=[r[f],u]:r[f]=u}return r}},2361:e=>{var t=function(e){switch(typeof e){case"string":return e;case"boolean":return e?"true":"false";case"number":return isFinite(e)?e:"";default:return""}};e.exports=function(e,i,n,o){return i=i||"&",n=n||"=",null===e&&(e=void 0),"object"==typeof e?Object.keys(e).map((function(o){var r=encodeURIComponent(t(o))+n;return Array.isArray(e[o])?e[o].map((function(e){return r+encodeURIComponent(t(e))})).join(i):r+encodeURIComponent(t(e[o]))})).join(i):o?encodeURIComponent(t(o))+n+encodeURIComponent(t(e)):""}},7673:(e,t,i)=>{t.decode=t.parse=i(2587),t.encode=t.stringify=i(2361)},1269:e=>{class t{constructor(e={}){if(!(e.maxSize&&e.maxSize>0))throw new TypeError("`maxSize` must be a number greater than 0");this.maxSize=e.maxSize,this.cache=new Map,this.oldCache=new Map,this._size=0}_set(e,t){this.cache.set(e,t),this._size++,this._size>=this.maxSize&&(this._size=0,this.oldCache=this.cache,this.cache=new Map)}get(e){if(this.cache.has(e))return this.cache.get(e);if(this.oldCache.has(e)){const t=this.oldCache.get(e);return this.oldCache.delete(e),this._set(e,t),t}}set(e,t){return this.cache.has(e)?this.cache.set(e,t):this._set(e,t),this}has(e){return this.cache.has(e)||this.oldCache.has(e)}peek(e){return this.cache.has(e)?this.cache.get(e):this.oldCache.has(e)?this.oldCache.get(e):void 0}delete(e){const t=this.cache.delete(e);return t&&this._size--,this.oldCache.delete(e)||t}clear(){this.cache.clear(),this.oldCache.clear(),this._size=0}*keys(){for(const[e]of this)yield e}*values(){for(const[,e]of this)yield e}*[Symbol.iterator](){for(const e of this.cache)yield e;for(const e of this.oldCache){const[t]=e;this.cache.has(t)||(yield e)}}get size(){let e=0;for(const t of this.oldCache.keys())this.cache.has(t)||e++;return this._size+e}}e.exports=t},2511:function(e,t,i){var n;e=i.nmd(e),function(){t&&t.nodeType,e&&e.nodeType;var o="object"==typeof i.g&&i.g;o.global!==o&&o.window!==o&&o.self;var r,a=2147483647,s=36,c=/^xn--/,l=/[^\x20-\x7E]/,h=/[\x2E\u3002\uFF0E\uFF61]/g,d={overflow:"Overflow: input needs wider integers to process","not-basic":"Illegal input >= 0x80 (not a basic code point)","invalid-input":"Invalid input"},f=Math.floor,u=String.fromCharCode;function p(e){throw RangeError(d[e])}function m(e,t){for(var i=e.length,n=[];i--;)n[i]=t(e[i]);return n}function g(e,t){var i=e.split("@"),n="";return i.length>1&&(n=i[0]+"@",e=i[1]),n+m((e=e.replace(h,".")).split("."),t).join(".")}function w(e){for(var t,i,n=[],o=0,r=e.length;o=55296&&t<=56319&&o65535&&(t+=u((e-=65536)>>>10&1023|55296),e=56320|1023&e),t+u(e)})).join("")}function b(e,t){return e+22+75*(e<26)-((0!=t)<<5)}function v(e,t,i){var n=0;for(e=i?f(e/700):e>>1,e+=f(e/t);e>455;n+=s)e=f(e/35);return f(n+36*e/(e+38))}function y(e){var t,i,n,o,r,c,l,h,d,u,m,g=[],w=e.length,b=0,y=128,_=72;for((i=e.lastIndexOf("-"))<0&&(i=0),n=0;n=128&&p("not-basic"),g.push(e.charCodeAt(n));for(o=i>0?i+1:0;o=w&&p("invalid-input"),((h=(m=e.charCodeAt(o++))-48<10?m-22:m-65<26?m-65:m-97<26?m-97:s)>=s||h>f((a-b)/c))&&p("overflow"),b+=h*c,!(h<(d=l<=_?1:l>=_+26?26:l-_));l+=s)c>f(a/(u=s-d))&&p("overflow"),c*=u;_=v(b-r,t=g.length+1,0==r),f(b/t)>a-y&&p("overflow"),y+=f(b/t),b%=t,g.splice(b++,0,y)}return F(g)}function _(e){var t,i,n,o,r,c,l,h,d,m,g,F,y,_,C,x=[];for(F=(e=w(e)).length,t=128,i=0,r=72,c=0;c=t&&gf((a-i)/(y=n+1))&&p("overflow"),i+=(l-t)*y,t=l,c=0;ca&&p("overflow"),g==t){for(h=i,d=s;!(h<(m=d<=r?1:d>=r+26?26:d-r));d+=s)C=h-m,_=s-m,x.push(u(b(m+C%_,0))),h=f(C/_);x.push(u(b(h,0))),r=v(i,y,n==o),i=0,++n}++i,++t}return x.join("")}r={version:"1.3.2",ucs2:{decode:w,encode:F},decode:y,encode:_,toASCII:function(e){return g(e,(function(e){return l.test(e)?"xn--"+_(e):e}))},toUnicode:function(e){return g(e,(function(e){return c.test(e)?y(e.slice(4).toLowerCase()):e}))}},void 0===(n=function(){return r}.call(t,i,t,e))||(e.exports=n)}()},8575:(e,t,i)=>{var n=i(2511),o=i(2502);function r(){this.protocol=null,this.slashes=null,this.auth=null,this.host=null,this.port=null,this.hostname=null,this.hash=null,this.search=null,this.query=null,this.pathname=null,this.path=null,this.href=null}t.parse=b,t.resolve=function(e,t){return b(e,!1,!0).resolve(t)},t.resolveObject=function(e,t){return e?b(e,!1,!0).resolveObject(t):t},t.format=function(e){return o.isString(e)&&(e=b(e)),e instanceof r?e.format():r.prototype.format.call(e)},t.Url=r;var a=/^([a-z0-9.+-]+:)/i,s=/:[0-9]*$/,c=/^(\/\/?(?!\/)[^\?\s]*)(\?[^\s]*)?$/,l=["{","}","|","\\","^","`"].concat(["<",">",'"',"`"," ","\r","\n","\t"]),h=["'"].concat(l),d=["%","/","?",";","#"].concat(h),f=["/","?","#"],u=/^[+a-z0-9A-Z_-]{0,63}$/,p=/^([+a-z0-9A-Z_-]{0,63})(.*)$/,m={javascript:!0,"javascript:":!0},g={javascript:!0,"javascript:":!0},w={http:!0,https:!0,ftp:!0,gopher:!0,file:!0,"http:":!0,"https:":!0,"ftp:":!0,"gopher:":!0,"file:":!0},F=i(7673);function b(e,t,i){if(e&&o.isObject(e)&&e instanceof r)return e;var n=new r;return n.parse(e,t,i),n}r.prototype.parse=function(e,t,i){if(!o.isString(e))throw new TypeError("Parameter 'url' must be a string, not "+typeof e);var r=e.indexOf("?"),s=-1!==r&&r127?M+="x":M+=A[T];if(!M.match(u)){var L=z.slice(0,N),B=z.slice(N+1),H=A.match(p);H&&(L.push(H[1]),B.unshift(H[2])),B.length&&(b="/"+B.join(".")+b),this.hostname=L.join(".");break}}}this.hostname.length>255?this.hostname="":this.hostname=this.hostname.toLowerCase(),I||(this.hostname=n.toASCII(this.hostname));var O=this.port?":"+this.port:"",P=this.hostname||"";this.host=P+O,this.href+=this.host,I&&(this.hostname=this.hostname.substr(1,this.hostname.length-2),"/"!==b[0]&&(b="/"+b))}if(!m[_])for(N=0,D=h.length;N0)&&i.host.split("@"))&&(i.auth=I.shift(),i.host=i.hostname=I.shift())),i.search=e.search,i.query=e.query,o.isNull(i.pathname)&&o.isNull(i.search)||(i.path=(i.pathname?i.pathname:"")+(i.search?i.search:"")),i.href=i.format(),i;if(!C.length)return i.pathname=null,i.search?i.path="/"+i.search:i.path=null,i.href=i.format(),i;for(var k=C.slice(-1)[0],E=(i.host||e.host||C.length>1)&&("."===k||".."===k)||""===k,N=0,S=C.length;S>=0;S--)"."===(k=C[S])?C.splice(S,1):".."===k?(C.splice(S,1),N++):N&&(C.splice(S,1),N--);if(!y&&!_)for(;N--;N)C.unshift("..");!y||""===C[0]||C[0]&&"/"===C[0].charAt(0)||C.unshift(""),E&&"/"!==C.join("/").substr(-1)&&C.push("");var I,z=""===C[0]||C[0]&&"/"===C[0].charAt(0);return x&&(i.hostname=i.host=z?"":C.length?C.shift():"",(I=!!(i.host&&i.host.indexOf("@")>0)&&i.host.split("@"))&&(i.auth=I.shift(),i.host=i.hostname=I.shift())),(y=y||i.host&&C.length)&&!z&&C.unshift(""),C.length?i.pathname=C.join("/"):(i.pathname=null,i.path=null),o.isNull(i.pathname)&&o.isNull(i.search)||(i.path=(i.pathname?i.pathname:"")+(i.search?i.search:"")),i.auth=e.auth||i.auth,i.slashes=i.slashes||e.slashes,i.href=i.format(),i},r.prototype.parseHost=function(){var e=this.host,t=s.exec(e);t&&(":"!==(t=t[0])&&(this.port=t.substr(1)),e=e.substr(0,e.length-t.length)),e&&(this.hostname=e)}},2502:e=>{e.exports={isString:function(e){return"string"==typeof e},isObject:function(e){return"object"==typeof e&&null!==e},isNull:function(e){return null===e},isNullOrUndefined:function(e){return null==e}}},7067:()=>{}},t={};function i(n){var o=t[n];if(void 0!==o)return o.exports;var r=t[n]={id:n,loaded:!1,exports:{}};return e[n].call(r.exports,r,r.exports,i),r.loaded=!0,r.exports}return i.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return i.d(t,{a:t}),t},i.d=(e,t)=>{for(var n in t)i.o(t,n)&&!i.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},i.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),i.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),i.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},i.nmd=e=>(e.paths=[],e.children||(e.children=[]),e),i(5590)})();class sg{constructor(e,t,i){this.config=e,this.browser=i,this.genome=t,this.cramFile=new ag.CramFile({filehandle:new cg(e.url,e),seqFetch:e.seqFetch||function(e,t,i){const n=this.genome.sequence,o=this.genome;return this.getHeader().then((function(r){const a=o.getChromosomeName(r.chrNames[e]);return n.getSequence(a,t-1,i)}))}.bind(this),checkSequenceMD5:void 0===e.checkSequenceMD5||e.checkSequenceMD5});const n=new cg(e.indexURL,e);this.indexedCramFile=new ag.IndexedCramFile({cram:this.cramFile,index:new ag.CraiIndex({filehandle:n}),fetchSizeLimit:3e7}),Km.setReaderDefaults(this,e)}async getHeader(){if(!this.header){const e=this.genome,t=await this.cramFile.getSamHeader(),i={},n=[],o={},r=[];for(let a of t)if("SQ"===a.tag){for(let t of a.data)if("SN"===t.tag){const r=t.value;if(i[r]=n.length,n.push(r),e){o[e.getChromosomeName(r)]=r}break}}else"RG"===a.tag&&r.push(a.data);this.header={chrNames:n,chrToIndex:i,chrAliasTable:o,readGroups:r}}return this.header}async readAlignments(e,t,i){this.browser;const n=await this.getHeader(),o=n.chrAliasTable.hasOwnProperty(e)?n.chrAliasTable[e]:e,r=n.chrToIndex[o],a=new Nm(e,t,i,this.config);if(void 0===r)return a;try{const e=await this.indexedCramFile.getRecordsForRange(r,t,i);for(let o of e){const e=o.sequenceId,c=o.alignmentStart,l=c+o.lengthOnRef;if(e<0)continue;if(e>r||c>i)return;if(e=0&&(t="Sequence mismatch. Is this the correct genome for the loaded CRAM?"),this.browser.alert.present(new Error(t)),e}function s(e,t){const i=new Rm;if(i.chr=t[e.sequenceId],i.start=e.alignmentStart-1,i.lengthOnRef=e.lengthOnRef,i.flags=e.flags,i.strand=!(16&e.flags),i.fragmentLength=e.templateLength||e.templateSize,i.mq=e.mappingQuality,i.end=e.alignmentStart+e.lengthOnRef,i.readGroupId=e.readGroupId,e.mate&&void 0!==e.mate.sequenceId){const n=void 0!==e.mate.flags?!(1&e.mate.flags):!(32&e.flags);i.mate={chr:t[e.mate.sequenceId],position:e.mate.alignmentStart,strand:n}}return i.seq=e.getReadBases(),i.qual=e.qualityScores,i.tagDict=e.tags,i.readName=e.readName,function(e,t){const i=[];let n,o,r=0,a="";if(t.scStart=t.start,t.scLengthOnRef=t.lengthOnRef,e.readFeatures)for(let s of e.readFeatures){const e=s.code,c=s.data,l=s.pos-1,h=s.refPos-1;switch(e){case"S":case"I":case"i":case"N":case"D":if(l>r){const e=l-r;i.push(new Um({start:h-e,seqOffset:r,len:e,type:"M"})),r+=e,a+=e+"M"}if("S"===e){let n=h;t.scLengthOnRef+=c.length,0===l&&(t.scStart-=c.length,n-=c.length);const o=c.length;i.push(new Um({start:n,seqOffset:r,len:o,type:"S"})),r+=o,a+=o+e}else if("I"===e||"i"===e){void 0===n&&(n=[]);const t="i"===e?1:c.length;n.push(new Um({start:h,len:t,seqOffset:r,type:"I"})),r+=t,a+=t+e}else"D"!==e&&"N"!==e||(o||(o=[]),o.push({start:h,len:c,type:e}),a+=c+e);break;case"H":case"P":a+=c+e}}const s=e.readLength-r;s>0&&(i.push(new Um({start:e.alignmentStart+e.lengthOnRef-s-1,seqOffset:r,len:s,type:"M"})),a+=s+"M");t.blocks=i,t.insertions=n,t.gaps=o,t.cigar=a}(e,i),i.mate&&i.start>i.mate.position&&i.fragmentLength>0&&(i.fragmentLength=-i.fragmentLength),Km.setPairOrientation(i),i}}}class cg{constructor(e,t){this.position=0,this.url=e,this.config=t,this.cache=new lg({fetch:(e,t)=>this._fetch(e,t)})}async _fetch(e,t){const i={start:e,size:t};this._stat={size:void 0};const n=await ad.loadArrayBuffer(this.url,zd(this.config,{range:i}));return Buffer.from(n)}async read(e,t=0,i=1/0,n=0){let o=n;return null===n&&(o=this.position,this.position+=i),this.cache.get(e,t,i,n)}async readFile(){const e=await ad.loadArrayBuffer(this.url,zd(this.config));return Buffer.from(e)}async stat(){if(!this._stat){const e=Buffer.allocUnsafe(10);if(await this.read(e,0,10,0),!this._stat)throw new Error(`unable to determine size of file at ${this.url}`)}return this._stat}}class lg{constructor({fetch:e,size:t=1e7,chunkSize:i=32768}){this.fetch=e,this.chunkSize=i,this.lruCache=new hg({maxSize:Math.floor(t/i)})}async get(e,t,i,n){if(e.length({data:t,chunkNumber:e})));const s=await Promise.all(a),c=n-s[0].chunkNumber*this.chunkSize;s.forEach((({data:a,chunkNumber:s})=>{const l=s*this.chunkSize;let h=0,d=this.chunkSize,f=t+(s-o)*this.chunkSize-c;s===o&&(f=t,h=c),s===r&&(d=n+i-l),a.copy(e,f,h,d)}))}_getChunk(e){const t=this.lruCache.get(e);if(t)return t;const i=this.fetch(e*this.chunkSize,this.chunkSize);return this.lruCache.set(e,i),i}}class hg{constructor(e={}){if(!(e.maxSize&&e.maxSize>0))throw new TypeError("`maxSize` must be a number greater than 0");this.maxSize=e.maxSize,this.cache=new Map,this.oldCache=new Map,this._size=0}_set(e,t){this.cache.set(e,t),this._size++,this._size>=this.maxSize&&(this._size=0,this.oldCache=this.cache,this.cache=new Map)}get(e){if(this.cache.has(e))return this.cache.get(e);if(this.oldCache.has(e)){const t=this.oldCache.get(e);return this._set(e,t),t}}set(e,t){return this.cache.has(e)?this.cache.set(e,t):this._set(e,t),this}has(e){return this.cache.has(e)||this.oldCache.has(e)}peek(e){return this.cache.has(e)?this.cache.get(e):this.oldCache.has(e)?this.oldCache.get(e):void 0}delete(e){const t=this.cache.delete(e);return t&&this._size--,this.oldCache.delete(e)||t}clear(){this.cache.clear(),this.oldCache.clear(),this._size=0}*keys(){for(const[e]of this)yield e}*values(){for(const[,e]of this)yield e}*[Symbol.iterator](){for(const e of this.cache)yield e;for(const e of this.oldCache){const[t]=e;this.cache.has(t)||(yield e)}}get size(){let e=0;for(const t of this.oldCache.keys())this.cache.has(t)||e++;return this._size+e}}var dg={ALIGNMENT_MATCH:"M",INSERT:"I",DELETE:"D",SKIP:"N",CLIP_SOFT:"S",CLIP_HARD:"H",PAD:"P",SEQUENCE_MATCH:"=",SEQUENCE_MISMATCH:"X"};const fg=function(e,t){this.config=e,this.genome=t,this.url=e.url,this.filter=new jm(e.filter),this.readGroupSetIds=e.readGroupSetIds,this.authKey=e.authKey,this.samplingWindowSize=void 0===e.samplingWindowSize?100:e.samplingWindowSize,this.samplingDepth=void 0===e.samplingDepth?1e3:e.samplingDepth,e.viewAsPairs?this.pairsSupported=!0:this.pairsSupported=void 0===e.pairsSupported||e.pairsSupported};fg.prototype.readAlignments=function(e,t,i){const n=this.genome,o=this;return(o.chrAliasTable?Promise.resolve(o.chrAliasTable):o.readMetadata().then((function(e){if(o.chrAliasTable={},n&&e.readGroups&&e.readGroups.length>0){var t=e.readGroups[0].referenceSetId;return t?zp({url:o.url+"/references/search",body:{referenceSetId:t},decode:function(e){return e.references}}).then((function(e){return e.forEach((function(e){var t=e.name,i=n.getChromosomeName(t);o.chrAliasTable[i]=t})),o.chrAliasTable})):(function(e,t){var i;if("461916304629"===t||"337315832689"===t){for(i=1;i<23;i++)e["chr"+i]=i;e.chrX="X",e.chrY="Y",e.chrM="MT"}}(o.chrAliasTable,o.config.datasetId),o.chrAliasTable)}return o.chrAliasTable}))).then((function(n){var a=n.hasOwnProperty(e)?n[e]:e;return zp({url:o.url+"/reads/search",body:{readGroupSetIds:[o.readGroupSetIds],referenceName:a,start:t,end:i,pageSize:"10000"},decode:r,results:new Nm(e,t,i,o.config)})}));function r(e){var t,i,r,a,s,c=e.alignments,l=c.length,h=[];for(t=0;t0;if(r.packedAlignmentRows=km(a,r.start,r.end,o),this.alignmentContainer=r,s){const t=await n.sequence.getSequence(e,r.start,r.end);if(t)return r.coverageMap.refSeq=t,r.sequence=t,r;console.error("No sequence for: "+e+":"+r.start+"-"+r.end)}return r}}function pg(e,t,i){var n,o,r,a,s,c,l,h={font:"normal 10px Arial",textAlign:"right",strokeStyle:"black"};if(void 0===this.dataRange||void 0===this.dataRange.max||void 0===this.dataRange.min)return;let d=void 0!==this.flipAxis&&this.flipAxis;function f(e){return 0===e?"0":Math.abs(e)>=10?e.toFixed():Math.abs(e)>=1?e.toFixed(1):e.toFixed(2)}kd.fillRect(e,0,0,t,i,{fillStyle:"rgb(255, 255, 255)"}),n=(l=.95*t)-8,s={x:o=l,y:r=a=.01*i},kd.strokeLine(e,n,r,o,a,h),kd.fillText(e,f(d?this.dataRange.min:this.dataRange.max),n+4,r+12,h),c={x:o,y:r=a=.99*i},kd.strokeLine(e,n,r,o,a,h),kd.fillText(e,f(d?this.dataRange.max:this.dataRange.min),n+4,r-4,h),kd.strokeLine(e,s.x,s.y,c.x,c.y,h)}class mg{constructor({chr:e,start:t,end:i}){this.chr=e,this.start=t,this.end=i}contains(e){return e.chr===this.chr&&e.start>=this.start&&e.end<=this.end}overlaps(e){return e.chr===this.chr&&!(e.endthis.end)}extend(e){e.chr===this.chr&&(this.start=Math.min(e.start,this.start),this.end=Math.max(e.end,this.end))}getLocusString(){if("all"===this.chr)return"all";{const e=Za(Math.floor(this.start)+1),t=Za(Math.round(this.end));return`${this.chr}:${e}-${t}`}}static fromLocusString(e){if("all"===e)return new mg({chr:"all"});const t=e.split(":"),i=t[0],n=t[1].split("-"),o=Number.parseInt(n[0].replace(/,/g,""))-1,r=Number.parseInt(n[1].replace(/,/g,""));return new mg({chr:i,start:o,end:r})}} -/*! - * vanilla-picker v2.12.1 - * https://vanilla-picker.js.org - * - * Copyright 2017-2021 Andreas Borgen (https://github.com/Sphinxxxx), Adam Brooks (https://github.com/dissimulate) - * Released under the ISC license. - */var gg=function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")},wg=function(){function e(e,t){for(var i=0;i1&&void 0!==arguments[1]?arguments[1]:1;return(t>0?e.toFixed(t).replace(/0+$/,"").replace(/\.$/,""):e.toString())||"0"}var yg=function(){function e(t,i,n,o){gg(this,e);var r=this;if(void 0===t);else if(Array.isArray(t))this.rgba=t;else if(void 0===n){var a=t&&""+t;a&&function(t){if(t.startsWith("hsl")){var i=t.match(/([\-\d\.e]+)/g).map(Number),n=Fg(i,4),o=n[0],a=n[1],s=n[2],c=n[3];void 0===c&&(c=1),o/=360,a/=100,s/=100,r.hsla=[o,a,s,c]}else if(t.startsWith("rgb")){var l=t.match(/([\-\d\.e]+)/g).map(Number),h=Fg(l,4),d=h[0],f=h[1],u=h[2],p=h[3];void 0===p&&(p=1),r.rgba=[d,f,u,p]}else t.startsWith("#")?r.rgba=e.hexToRgb(t):r.rgba=e.nameToRgb(t)||e.hexToRgb(t)}(a.toLowerCase())}else this.rgba=[t,i,n,void 0===o?1:o]}return wg(e,[{key:"printRGB",value:function(e){var t=(e?this.rgba:this.rgba.slice(0,3)).map((function(e,t){return vg(e,3===t?3:0)}));return e?"rgba("+t+")":"rgb("+t+")"}},{key:"printHSL",value:function(e){var t=[360,100,100,1],i=["","%","%",""],n=(e?this.hsla:this.hsla.slice(0,3)).map((function(e,n){return vg(e*t[n],3===n?3:1)+i[n]}));return e?"hsla("+n+")":"hsl("+n+")"}},{key:"printHex",value:function(e){var t=this.hex;return e?t:t.substring(0,7)}},{key:"rgba",get:function(){if(this._rgba)return this._rgba;if(!this._hsla)throw new Error("No color is set");return this._rgba=e.hslToRgb(this._hsla)},set:function(e){3===e.length&&(e[3]=1),this._rgba=e,this._hsla=null}},{key:"rgbString",get:function(){return this.printRGB()}},{key:"rgbaString",get:function(){return this.printRGB(!0)}},{key:"hsla",get:function(){if(this._hsla)return this._hsla;if(!this._rgba)throw new Error("No color is set");return this._hsla=e.rgbToHsl(this._rgba)},set:function(e){3===e.length&&(e[3]=1),this._hsla=e,this._rgba=null}},{key:"hslString",get:function(){return this.printHSL()}},{key:"hslaString",get:function(){return this.printHSL(!0)}},{key:"hex",get:function(){return"#"+this.rgba.map((function(e,t){return t<3?e.toString(16):Math.round(255*e).toString(16)})).map((function(e){return e.padStart(2,"0")})).join("")},set:function(t){this.rgba=e.hexToRgb(t)}}],[{key:"hexToRgb",value:function(e){var t=(e.startsWith("#")?e.slice(1):e).replace(/^(\w{3})$/,"$1F").replace(/^(\w)(\w)(\w)(\w)$/,"$1$1$2$2$3$3$4$4").replace(/^(\w{6})$/,"$1FF");if(!t.match(/^([0-9a-fA-F]{8})$/))throw new Error("Unknown hex color; "+e);var i=t.match(/^(\w\w)(\w\w)(\w\w)(\w\w)$/).slice(1).map((function(e){return parseInt(e,16)}));return i[3]=i[3]/255,i}},{key:"nameToRgb",value:function(t){var i=t.toLowerCase().replace("at","T").replace(/[aeiouyldf]/g,"").replace("ght","L").replace("rk","D").slice(-5,4),n=bg[i];return void 0===n?n:e.hexToRgb(n.replace(/\-/g,"00").padStart(6,"f"))}},{key:"rgbToHsl",value:function(e){var t=Fg(e,4),i=t[0],n=t[1],o=t[2],r=t[3];i/=255,n/=255,o/=255;var a=Math.max(i,n,o),s=Math.min(i,n,o),c=void 0,l=void 0,h=(a+s)/2;if(a===s)c=l=0;else{var d=a-s;switch(l=h>.5?d/(2-a-s):d/(a+s),a){case i:c=(n-o)/d+(n1&&(i-=1),i<1/6?e+6*(t-e)*i:i<.5?t:i<2/3?e+(t-e)*(2/3-i)*6:e},h=o<.5?o*(1+n):o+n-o*n,d=2*o-h;a=l(d,h,i+1/3),s=l(d,h,i),c=l(d,h,i-1/3)}var f=[255*a,255*s,255*c].map(Math.round);return f[3]=r,f}}]),e}(),_g=function(){function e(){gg(this,e),this._events=[]}return wg(e,[{key:"add",value:function(e,t,i){e.addEventListener(t,i,!1),this._events.push({target:e,type:t,handler:i})}},{key:"remove",value:function(t,i,n){this._events=this._events.filter((function(o){var r=!0;return t&&t!==o.target&&(r=!1),i&&i!==o.type&&(r=!1),n&&n!==o.handler&&(r=!1),r&&e._doRemove(o.target,o.type,o.handler),!r}))}},{key:"destroy",value:function(){this._events.forEach((function(t){return e._doRemove(t.target,t.type,t.handler)})),this._events=[]}}],[{key:"_doRemove",value:function(e,t,i){e.removeEventListener(t,i,!1)}}]),e}();function Cg(e,t,i){var n=!1;function o(e,t,i){return Math.max(t,Math.min(e,i))}function r(e,r,a){if(a&&(n=!0),n){e.preventDefault();var s=t.getBoundingClientRect(),c=s.width,l=s.height,h=r.clientX,d=r.clientY,f=o(h-s.left,0,c),u=o(d-s.top,0,l);i(f/c,u/l)}}function a(e,t){1===(void 0===e.buttons?e.which:e.buttons)?r(e,e,t):n=!1}function s(e,t){1===e.touches.length?r(e,e.touches[0],t):n=!1}e.add(t,"mousedown",(function(e){a(e,!0)})),e.add(t,"touchstart",(function(e){s(e,!0)})),e.add(window,"mousemove",a),e.add(t,"touchmove",s),e.add(window,"mouseup",(function(e){n=!1})),e.add(t,"touchend",(function(e){n=!1})),e.add(t,"touchcancel",(function(e){n=!1}))}var xg="keydown",kg="mousedown",Eg="focusin";function Ng(e,t){return(t||document).querySelector(e)}function Sg(e){e.preventDefault(),e.stopPropagation()}function Ig(e,t,i,n,o){e.add(t,xg,(function(e){i.indexOf(e.key)>=0&&(o&&Sg(e),n(e))}))}var zg=function(){function e(t){gg(this,e),this.settings={popup:"right",layout:"default",alpha:!0,editor:!0,editorFormat:"hex",cancelButton:!1,defaultColor:"#0cf"},this._events=new _g,this.onChange=null,this.onDone=null,this.onOpen=null,this.onClose=null,this.setOptions(t)}return wg(e,[{key:"setOptions",value:function(e){var t=this;if(e){var i=this.settings;if(e instanceof HTMLElement)i.parent=e;else{i.parent&&e.parent&&i.parent!==e.parent&&(this._events.remove(i.parent),this._popupInited=!1),function(e,t,i){for(var n in e)i&&i.indexOf(n)>=0||(t[n]=e[n])}(e,i),e.onChange&&(this.onChange=e.onChange),e.onDone&&(this.onDone=e.onDone),e.onOpen&&(this.onOpen=e.onOpen),e.onClose&&(this.onClose=e.onClose);var n=e.color||e.colour;n&&this._setColor(n)}var o=i.parent;if(o&&i.popup&&!this._popupInited){var r=function(e){return t.openHandler(e)};this._events.add(o,"click",r),Ig(this._events,o,[" ","Spacebar","Enter"],r),this._popupInited=!0}else e.parent&&!i.popup&&this.show()}}},{key:"openHandler",value:function(e){if(this.show()){e&&e.preventDefault(),this.settings.parent.style.pointerEvents="none";var t=e&&e.type===xg?this._domEdit:this.domElement;setTimeout((function(){return t.focus()}),100),this.onOpen&&this.onOpen(this.colour)}}},{key:"closeHandler",value:function(e){var t=e&&e.type,i=!1;if(e)if(t===kg||t===Eg){var n=(this.__containedEvent||0)+100;e.timeStamp>n&&(i=!0)}else Sg(e),i=!0;else i=!0;i&&this.hide()&&(this.settings.parent.style.pointerEvents="",t!==kg&&this.settings.parent.focus(),this.onClose&&this.onClose(this.colour))}},{key:"movePopup",value:function(e,t){this.closeHandler(),this.setOptions(e),t&&this.openHandler()}},{key:"setColor",value:function(e,t){this._setColor(e,{silent:t})}},{key:"_setColor",value:function(e,t){if("string"==typeof e&&(e=e.trim()),e){t=t||{};var i=void 0;try{i=new yg(e)}catch(e){if(t.failSilently)return;throw e}if(!this.settings.alpha){var n=i.hsla;n[3]=1,i.hsla=n}this.colour=this.color=i,this._setHSLA(null,null,null,null,t)}}},{key:"setColour",value:function(e,t){this.setColor(e,t)}},{key:"show",value:function(){if(!this.settings.parent)return!1;if(this.domElement){var e=this._toggleDOM(!0);return this._setPosition(),e}var t=function(e){var t=document.createElement("div");return t.innerHTML=e,t.firstElementChild}(this.settings.template||'
');return this.domElement=t,this._domH=Ng(".picker_hue",t),this._domSL=Ng(".picker_sl",t),this._domA=Ng(".picker_alpha",t),this._domEdit=Ng(".picker_editor input",t),this._domSample=Ng(".picker_sample",t),this._domOkay=Ng(".picker_done button",t),this._domCancel=Ng(".picker_cancel button",t),t.classList.add("layout_"+this.settings.layout),this.settings.alpha||t.classList.add("no_alpha"),this.settings.editor||t.classList.add("no_editor"),this.settings.cancelButton||t.classList.add("no_cancel"),this._ifPopup((function(){return t.classList.add("popup")})),this._setPosition(),this.colour?this._updateUI():this._setColor(this.settings.defaultColor),this._bindEvents(),!0}},{key:"hide",value:function(){return this._toggleDOM(!1)}},{key:"destroy",value:function(){this._events.destroy(),this.domElement&&this.settings.parent.removeChild(this.domElement)}},{key:"_bindEvents",value:function(){var e=this,t=this,i=this.domElement,n=this._events;function o(e,t,i){n.add(e,t,i)}o(i,"click",(function(e){return e.preventDefault()})),Cg(n,this._domH,(function(e,i){return t._setHSLA(e)})),Cg(n,this._domSL,(function(e,i){return t._setHSLA(null,e,1-i)})),this.settings.alpha&&Cg(n,this._domA,(function(e,i){return t._setHSLA(null,null,null,1-i)}));var r=this._domEdit;o(r,"input",(function(e){t._setColor(this.value,{fromEditor:!0,failSilently:!0})})),o(r,"focus",(function(e){var t=this;t.selectionStart===t.selectionEnd&&t.select()})),this._ifPopup((function(){var t=function(t){return e.closeHandler(t)};o(window,kg,t),o(window,Eg,t),Ig(n,i,["Esc","Escape"],t);var r=function(t){e.__containedEvent=t.timeStamp};o(i,kg,r),o(i,Eg,r),o(e._domCancel,"click",t)}));var a=function(t){e._ifPopup((function(){return e.closeHandler(t)})),e.onDone&&e.onDone(e.colour)};o(this._domOkay,"click",a),Ig(n,i,["Enter"],a)}},{key:"_setPosition",value:function(){var e=this.settings.parent,t=this.domElement;e!==t.parentNode&&e.appendChild(t),this._ifPopup((function(i){"static"===getComputedStyle(e).position&&(e.style.position="relative");var n=!0===i?"popup_right":"popup_"+i;["popup_top","popup_bottom","popup_left","popup_right"].forEach((function(e){e===n?t.classList.add(e):t.classList.remove(e)})),t.classList.add(n)}))}},{key:"_setHSLA",value:function(e,t,i,n,o){o=o||{};var r=this.colour,a=r.hsla;[e,t,i,n].forEach((function(e,t){(e||0===e)&&(a[t]=e)})),r.hsla=a,this._updateUI(o),this.onChange&&!o.silent&&this.onChange(r)}},{key:"_updateUI",value:function(e){if(this.domElement){e=e||{};var t=this.colour,i=t.hsla,n="hsl("+360*i[0]+", 100%, 50%)",o=t.hslString,r=t.hslaString,a=this._domH,s=this._domSL,c=this._domA,l=Ng(".picker_selector",a),h=Ng(".picker_selector",s),d=Ng(".picker_selector",c);F(0,l,i[0]),this._domSL.style.backgroundColor=this._domH.style.color=n,F(0,h,i[1]),b(0,h,1-i[2]),s.style.color=o,b(0,d,1-i[3]);var f=o,u=f.replace("hsl","hsla").replace(")",", 0)"),p="linear-gradient("+[f,u]+")";if(this._domA.style.background=p+", linear-gradient(45deg, lightgrey 25%, transparent 25%, transparent 75%, lightgrey 75%) 0 0 / 2em 2em,\n linear-gradient(45deg, lightgrey 25%, white 25%, white 75%, lightgrey 75%) 1em 1em / 2em 2em",!e.fromEditor){var m=this.settings.editorFormat,g=this.settings.alpha,w=void 0;switch(m){case"rgb":w=t.printRGB(g);break;case"hsl":w=t.printHSL(g);break;default:w=t.printHex(g)}this._domEdit.value=w}this._domSample.style.color=r}function F(e,t,i){t.style.left=100*i+"%"}function b(e,t,i){t.style.top=100*i+"%"}}},{key:"_ifPopup",value:function(e,t){this.settings.parent&&this.settings.popup?e&&e(this.settings.popup):t&&t()}},{key:"_toggleDOM",value:function(e){var t=this.domElement;if(!t)return!1;var i=e?"":"none",n=t.style.display!==i;return n&&(t.style.display=i),n}}]),e}(),Dg=document.createElement("style");function Ag(e){if(Mg[e])return Mg[e];if(Mg["chr"+e]){const t=Mg["chr"+e];return Mg[e]=t,t}{const o=(t=Math.round(255*Math.random()).toString(10),i=Math.round(255*Math.random()).toString(10),n=Math.round(255*Math.random()).toString(10),"rgb("+t+","+i+","+n+")");return Mg[e]=o,o}var t,i,n}Dg.textContent='.picker_wrapper.no_alpha .picker_alpha{display:none}.picker_wrapper.no_editor .picker_editor{position:absolute;z-index:-1;opacity:0}.picker_wrapper.no_cancel .picker_cancel{display:none}.layout_default.picker_wrapper{display:flex;flex-flow:row wrap;justify-content:space-between;align-items:stretch;font-size:10px;width:25em;padding:.5em}.layout_default.picker_wrapper input,.layout_default.picker_wrapper button{font-size:1rem}.layout_default.picker_wrapper>*{margin:.5em}.layout_default.picker_wrapper::before{content:"";display:block;width:100%;height:0;order:1}.layout_default .picker_slider,.layout_default .picker_selector{padding:1em}.layout_default .picker_hue{width:100%}.layout_default .picker_sl{flex:1 1 auto}.layout_default .picker_sl::before{content:"";display:block;padding-bottom:100%}.layout_default .picker_editor{order:1;width:6.5rem}.layout_default .picker_editor input{width:100%;height:100%}.layout_default .picker_sample{order:1;flex:1 1 auto}.layout_default .picker_done,.layout_default .picker_cancel{order:1}.picker_wrapper{box-sizing:border-box;background:#f2f2f2;box-shadow:0 0 0 1px silver;cursor:default;font-family:sans-serif;color:#444;pointer-events:auto}.picker_wrapper:focus{outline:none}.picker_wrapper button,.picker_wrapper input{box-sizing:border-box;border:none;box-shadow:0 0 0 1px silver;outline:none}.picker_wrapper button:focus,.picker_wrapper button:active,.picker_wrapper input:focus,.picker_wrapper input:active{box-shadow:0 0 2px 1px #1e90ff}.picker_wrapper button{padding:.4em .6em;cursor:pointer;background-color:#f5f5f5;background-image:linear-gradient(0deg, gainsboro, transparent)}.picker_wrapper button:active{background-image:linear-gradient(0deg, transparent, gainsboro)}.picker_wrapper button:hover{background-color:#fff}.picker_selector{position:absolute;z-index:1;display:block;-webkit-transform:translate(-50%, -50%);transform:translate(-50%, -50%);border:2px solid #fff;border-radius:100%;box-shadow:0 0 3px 1px #67b9ff;background:currentColor;cursor:pointer}.picker_slider .picker_selector{border-radius:2px}.picker_hue{position:relative;background-image:linear-gradient(90deg, red, yellow, lime, cyan, blue, magenta, red);box-shadow:0 0 0 1px silver}.picker_sl{position:relative;box-shadow:0 0 0 1px silver;background-image:linear-gradient(180deg, white, rgba(255, 255, 255, 0) 50%),linear-gradient(0deg, black, rgba(0, 0, 0, 0) 50%),linear-gradient(90deg, #808080, rgba(128, 128, 128, 0))}.picker_alpha,.picker_sample{position:relative;background:linear-gradient(45deg, lightgrey 25%, transparent 25%, transparent 75%, lightgrey 75%) 0 0/2em 2em,linear-gradient(45deg, lightgrey 25%, white 25%, white 75%, lightgrey 75%) 1em 1em/2em 2em;box-shadow:0 0 0 1px silver}.picker_alpha .picker_selector,.picker_sample .picker_selector{background:none}.picker_editor input{font-family:monospace;padding:.2em .4em}.picker_sample::before{content:"";position:absolute;display:block;width:100%;height:100%;background:currentColor}.picker_arrow{position:absolute;z-index:-1}.picker_wrapper.popup{position:absolute;z-index:2;margin:1.5em}.picker_wrapper.popup,.picker_wrapper.popup .picker_arrow::before,.picker_wrapper.popup .picker_arrow::after{background:#f2f2f2;box-shadow:0 0 10px 1px rgba(0,0,0,.4)}.picker_wrapper.popup .picker_arrow{width:3em;height:3em;margin:0}.picker_wrapper.popup .picker_arrow::before,.picker_wrapper.popup .picker_arrow::after{content:"";display:block;position:absolute;top:0;left:0;z-index:-99}.picker_wrapper.popup .picker_arrow::before{width:100%;height:100%;-webkit-transform:skew(45deg);transform:skew(45deg);-webkit-transform-origin:0 100%;transform-origin:0 100%}.picker_wrapper.popup .picker_arrow::after{width:150%;height:150%;box-shadow:none}.popup.popup_top{bottom:100%;left:0}.popup.popup_top .picker_arrow{bottom:0;left:0;-webkit-transform:rotate(-90deg);transform:rotate(-90deg)}.popup.popup_bottom{top:100%;left:0}.popup.popup_bottom .picker_arrow{top:0;left:0;-webkit-transform:rotate(90deg) scale(1, -1);transform:rotate(90deg) scale(1, -1)}.popup.popup_left{top:0;right:100%}.popup.popup_left .picker_arrow{top:0;right:0;-webkit-transform:scale(-1, 1);transform:scale(-1, 1)}.popup.popup_right{top:0;left:100%}.popup.popup_right .picker_arrow{top:0;left:0}',document.documentElement.firstElementChild.appendChild(Dg),zg.StyleElement=Dg;const Mg={chrX:"rgb(204, 153, 0)",chrY:"rgb(153, 204, 0",chrUn:"rgb(50, 50, 50)",chr1:"rgb(80, 80, 255)",chrI:"rgb(139, 155, 187)",chr2:"rgb(206, 61, 50)",chrII:"rgb(206, 61, 50)",chr2a:"rgb(216, 71, 60)",chr2b:"rgb(226, 81, 70)",chr3:"rgb(116, 155, 88)",chrIII:"rgb(116, 155, 88)",chr4:"rgb(240, 230, 133)",chrIV:"rgb(240, 230, 133)",chr5:"rgb(70, 105, 131)",chr6:"rgb(186, 99, 56)",chr7:"rgb(93, 177, 221)",chr8:"rgb(128, 34, 104)",chr9:"rgb(107, 215, 107)",chr10:"rgb(213, 149, 167)",chr11:"rgb(146, 72, 34)",chr12:"rgb(131, 123, 141)",chr13:"rgb(199, 81, 39)",chr14:"rgb(213, 143, 92)",chr15:"rgb(122, 101, 165)",chr16:"rgb(228, 175, 105)",chr17:"rgb(59, 27, 83)",chr18:"rgb(205, 222, 183)",chr19:"rgb(97, 42, 121)",chr20:"rgb(174, 31, 99)",chr21:"rgb(231, 199, 111)",chr22:"rgb(90, 101, 94)",chr23:"rgb(204, 153, 0)",chr24:"rgb(153, 204, 0)",chr25:"rgb(51, 204, 0)",chr26:"rgb(0, 204, 51)",chr27:"rgb(0, 204, 153)",chr28:"rgb(0, 153, 204)",chr29:"rgb(10, 71, 255)",chr30:"rgb(71, 117, 255)",chr31:"rgb(255, 194, 10)",chr32:"rgb(255, 209, 71)",chr33:"rgb(153, 0, 51)",chr34:"rgb(153, 26, 0)",chr35:"rgb(153, 102, 0)",chr36:"rgb(128, 153, 0)",chr37:"rgb(51, 153, 0)",chr38:"rgb(0, 153, 26)",chr39:"rgb(0, 153, 102)",chr40:"rgb(0, 128, 153)",chr41:"rgb(0, 51, 153)",chr42:"rgb(26, 0, 153)",chr43:"rgb(102, 0, 153)",chr44:"rgb(153, 0, 128)",chr45:"rgb(214, 0, 71)",chr46:"rgb(255, 20, 99)",chr47:"rgb(0, 214, 143)",chr48:"rgb(20, 255, 177)"};class Tg{constructor(e){this.tracks=[],this.chordSets=[]}addChordSet(e){this.chordSets=this.chordSets.filter((t=>t.name!==e.name)),this.chordSets.push(e);let t=this.tracks.find((t=>e.trackName===t.name));t&&(t.chordSets=t.chordSets.filter((t=>t.name!==e.name)),t.chordSets.push(e)),t||(t=new Rg(e),this.tracks.push(t))}clearChords(){this.tracks=[],this.chordSets=[]}getTrack(e){return this.tracks.find((t=>e===t.name))}getChordSet(e){return this.chordSets.find((t=>e===t.name))}}class Rg{constructor(e){this.name=e.trackName,this.color=e.trackColor,this.visible=!0,this.chordSets=[e],this.id=("0000"+(Math.random()*Math.pow(36,4)|0).toString(36)).slice(-4)}get chords(){if(1===this.chordSets.length)return this.chordSets[0].chords;const e=[];for(let t of this.chordSets)for(let i of t.chords)e.push(i);return e}}const Lg=Math.exp(5);class Bg{static isInstalled(){return void 0!==window.JBrowseReactCircularGenomeView&&void 0!==window.React&&void 0!==window.ReactDOM}constructor(e,t){if(t=t||{},this.config=t,Bg.isInstalled()){this.parent=e,this.groupByTrack=!0===t.groupByTrack,this.chordManager=new Tg(t);const i=document.createElement("div");i.className="igv-circview-container",e.appendChild(i),this.createControls(i),this.resetControlPanel();const n=document.createElement("div");n.className="igv-circview-circular-genome-view",i.appendChild(n),this.container=n,t.assembly&&this.setAssembly(t.assembly),this.width=t.width||500,this.height=t.height||500,this.setSize(this.width,this.height)}else console.error("JBrowse circular view is not installed")}createControls(e){const t=document.createElement("div");t.className="igv-circview-toolbar",e.appendChild(t),this.toolbar=t;const i=document.createElement("div");i.className="igv-circview-track-panel",e.appendChild(i),this.controlPanel=i,this.controlPanel.style.display="none";const n=document.createElement("div");n.className="igv-circview-toolbar-button-container",this.toolbar.appendChild(n),this.showControlsButton=document.createElement("div"),this.showControlsButton.className="igv-circview-button",n.appendChild(this.showControlsButton),this.showControlsButton.innerText="none"===this.controlPanel.style.display?"Show Controls":"Hide Controls",this.showControlsButton.addEventListener("click",(e=>{this.controlPanel.querySelectorAll("div").length>0&&("none"===this.controlPanel.style.display?(this.controlPanel.style.display="flex",e.target.innerText="Hide Controls"):(this.controlPanel.style.display="none",e.target.innerText="Show Controls"))}));let o=document.createElement("div");o.className="igv-circview-button",n.appendChild(o),o.innerText="Clear All",o.addEventListener("click",(()=>{this.clearChords()})),!1!==this.config.showCloseButton&&(o=document.createElement("div"),o.className="igv-circview-button",n.appendChild(o),o.innerText="Close",o.addEventListener("click",(()=>{this.visible=!1})))}resetControlPanel(){this.controlPanel.innerHTML="",this.controlPanel.appendChild(this.createGroupByCB());const e=this.groupByTrack?this.chordManager.tracks:this.chordManager.chordSets;for(let t of e)this.addToControlPanel(t)}createGroupByCB(){const e=document.createElement("input");e.type="checkbox",e.id="groupByCB",e.style.width="1.4em",e.style.height="1.4em",e.checked=this.groupByTrack,e.onclick=e=>{this.groupByTrack=e.target.checked,this.resetControlPanel(),this.render()};const t=document.createElement("label");t.for="groupByCB",t.innerText="Group by track",t.style.color="black",t.style.paddingLeft="10px";const i=document.createElement("div");return i.style.width="100%",i.style.paddingTop="5px",i.style.paddingBottom="5px",i.style.background="rgb(216, 230, 234)",i.appendChild(e),i.appendChild(t),i}addToControlPanel(e){const t=document.createElement("div");this.controlPanel.appendChild(t);const i=document.createElement("div");i.className="igv-circview-button",t.appendChild(i),i.innerText=!0===e.visible?"Hide":"Show",i.addEventListener("click",(t=>{!0===e.visible?(this.hideChordSet(e.name),t.target.innerText="Show"):(this.showChordSet(e.name),t.target.innerText="Hide")}));const n=document.createElement("input"),o=e=>200*Math.log(e*Lg),r=document.createElement("div");r.className="igv-circview-button",r.innerHTML="    ",t.appendChild(r),r.style.backgroundColor=Hg(e.color,1);const a={parent:r,popup:"right",editorFormat:"rgb",color:e.color,onChange:({rgbaString:t})=>{r.style.backgroundColor=Hg(t,1),this.setColor(e.name,t),n.value=o(Og(e.color))}},s=new zg(a);n.setAttribute("title","Adjust transparency of arcs"),n.type="range",n.style.width="100px",n.style.marginRight="10px",n.setAttribute("class","range"),n.setAttribute("min","0"),n.setAttribute("max","1000"),n.value=o(Og(e.color)),n.oninput=()=>{const t=(i=n.value,Math.exp(i/200)/Lg);var i;this.setColor(e.name,Hg(e.color,t)),s.setColor(e.color)},t.appendChild(n);const c=document.createElement("div");c.style.color="black",t.appendChild(c),c.innerText=c.title=e.name}setAssembly(e){const t=this.genomeId||Vg();if(this.genomeId===t)return;this.chordManager.clearChords(),this.genomeId=t,this.chrNames=new Set(e.chromosomes.map((e=>Pg(e.name))));const i=[],n=[];for(let t of e.chromosomes){const e=Pg(t.name);n.push(t.color||Ag(e)),i.push({refName:e,uniqueId:e,start:0,end:t.bpLength})}this.assembly={name:e.name,sequence:{trackId:t,type:"ReferenceSequenceTrack",adapter:{type:"FromConfigSequenceAdapter",features:i}},refNameColors:n},this.render()}addChords(e,t={}){const i=t.name||t.track||"*",n=i.split(" ")[0].replaceAll("%20"," "),o={name:i.replaceAll("%20"," "),trackName:n,chords:e,color:t.color||"black",trackColor:t.trackColor||t.color||"black",visible:!0,id:t.id||Vg()};this.chordManager.addChordSet(o),this.resetControlPanel(),this.render()}setSize(e,t){if(t=t||e,this.width=e,this.height=t,this.viewState){const i=this.viewState.session.view;i.setWidth(e),i.setHeight(t),i.setBpPerPx(i.minBpPerPx)}}getSize(){return Math.min(this.width,this.height)}clearChords(){this.chordManager.clearChords(),this.resetControlPanel(),this.render()}clearSelection(){this.viewState.pluginManager.rootModel.session.clearSelection()}show(){this.parent.style.display="block"}hide(){this.parent.style.display="none"}get visible(){return"none"!==this.parent.style.display}set visible(e){this.parent.style.display=e?"block":"none"}hideChordSet(e){let t=this.getChordSet(e);t?(t.visible=!1,this.render()):console.warn(`No track with name: ${name}`)}showChordSet(e){let t=this.getChordSet(e);t?(t.visible=!0,this.render()):console.warn(`No track with name: ${e}`)}deleteTrack(e){let t=this.tracks.findIndex((t=>e===t.name));t>=0&&this.tracks.splice(t,1),this.render()}getChordSet(e){return this.groupByTrack?this.chordManager.getTrack(e):this.chordManager.getChordSet(e)}setColor(e,t){const i=this.getChordSet(e);if(i){i.color=t;const e=i.id;for(let i of this.viewState.config.tracks)if(e===i.trackId){i.displays[0].renderer.strokeColor.set(t);break}}}render(){const{createViewState:e,JBrowseCircularGenomeView:t}=JBrowseReactCircularGenomeView;ReactDOM.unmountComponentAtNode(this.container);const i=(this.groupByTrack?this.chordManager.tracks:this.chordManager.chordSets).filter((e=>e.visible)),n=[],o=[];for(let e of i)n.push({trackId:e.id,name:e.name,assemblyNames:["forIGV"],type:"VariantTrack",adapter:{type:"FromConfigAdapter",features:e.chords}}),o.push(e.color);this.viewState=e({assembly:this.assembly,tracks:n});for(let e=0;e div {\n margin: 4px;\n}\n\n.igv-circview-track-panel {\n z-index: 1024;\n position: absolute;\n top: 33px;\n left: 0;\n width: 100%;\n height: fit-content;\n border-bottom-style: solid;\n border-bottom-color: dimgray;\n border-bottom-width: thin;\n background-color: white;\n display: flex;\n flex-flow: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: flex-start;\n}\n.igv-circview-track-panel > div {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n}\n.igv-circview-track-panel > div > div {\n margin: 4px;\n}\n\n.igv-circview-swatch-button {\n cursor: pointer;\n padding: 5px;\n width: 8px;\n height: 8px;\n border: 1px solid #8d8b8b;\n border-radius: 16px;\n}\n\n.igv-circview-button {\n cursor: pointer;\n padding: 5px;\n color: #444;\n vertical-align: middle;\n text-align: center;\n font-family: "Open Sans", sans-serif;\n font-size: 12px;\n border: 1px solid #8d8b8b;\n border-radius: 4px;\n background: #efefef;\n box-shadow: 0 0 5px -1px rgba(0, 0, 0, 0.2);\n}\n\n.igv-circview-button:hover {\n background: #efefef;\n box-shadow: 0 0 5px -1px rgba(0, 0, 0, 0.6);\n}\n\n.igv-circview-button:active {\n color: #007bff;\n box-shadow: 0 0 5px -1px rgba(0, 0, 0, 0.6);\n}\n\n/*# sourceMappingURL=circular-view.css.map */\n',document.head.insertBefore(e,document.head.childNodes[document.head.childNodes.length-1])}()}const Ug=e=>e.startsWith("chr")?e.substring(3):e;function jg(e){const t=[],i=[];for(let n of e.wgChromosomeNames){const o=e.getChromosome(n);i.push(ww(o.name)),t.push({name:o.name,bpLength:o.bpLength})}return t}function Wg(e,t,i,n){const o=t.color||"rgb(0,0,255)",r=qh.addAlpha("all"===i.chr?o:ww(i.chr),n),a=qh.addAlpha(o,n),s=t.name.replaceAll(" ","%20"),c="all"===i.chr?s:`${s} ${i.chr}:${i.start}-${i.end}`;t.browser.circularView.addChords(e,{track:c,color:r,trackColor:a}),t.browser.circularViewVisible||(t.browser.circularViewVisible=!0)}class Gg{constructor(e,{minTLENPercentile:t,maxTLENPercentile:i}){this.totalCount=0,this.frCount=0,this.rfCount=0,this.ffCount=0,this.sumF=0,this.sumF2=0,this.lp=void 0===t?.1:t,this.up=void 0===i?99.5:i,this.isizes=[],this.compute(e)}compute(e){for(let n of e)if(n.isProperPair()){var t=Math.abs(n.fragmentLength);this.sumF+=t,this.sumF2+=t*t,this.isizes.push(t);var i=n.pairOrientation;if("string"==typeof i&&4===i.length)switch(""+i.charAt(0)+i.charAt(2)){case"FF":case"RR":this.ffCount++;break;case"FR":this.frCount++;break;case"RF":this.rfCount++}this.totalCount++}this.ffCount/this.totalCount>.9?this.orienation="ff":this.frCount/this.totalCount>.9?this.orienation="fr":this.rfCount/this.totalCount>.9&&(this.orienation="rf"),this.minTLEN=0===this.lp?0:$g(this.isizes,this.lp),this.maxTLEN=$g(this.isizes,this.up)}}function $g(e,t){if(0!==e.length){var i=Math.floor(e.length*(t/100));return e.sort((function(e,t){return e-t})),e[i]}}const Zg={getTissueInfo:function(e,t){let i=(t=t||"https://gtexportal.org/rest/v1")+"/dataset/tissueInfo?datasetId="+(e=e||"gtex_v8");return ad.loadJson(i,{})},trackConfiguration:function(e,t){return{type:"eqtl",sourceType:"gtex-ws",url:(t=t||"https://gtexportal.org/rest/v1")+"/association/singleTissueEqtlByLocation",tissueSiteDetailId:e.tissueSiteDetailId,name:e.tissueSiteDetailId.split("_").join(" "),visibilityWindow:25e4}}};function Kg(e,t,i){let n=(e.start-t)/i,o=(e.end-t)/i,r=o-n;return r<3&&(r=3,n-=1.5),{px:n,px1:o,pw:r}}function Xg(e,t,i,n,o,r){try{o.save(),o.fillStyle=this.color,o.strokeStyle=this.color;const n=this.getColorForFeature(e);let a,s;o.fillStyle=n,o.strokeStyle=n,"SQUISHED"===this.displayMode&&void 0!==e.row?(a=this.featureHeight/2,s=this.margin+this.squishedRowHeight*e.row):"EXPANDED"===this.displayMode&&void 0!==e.row?(a=this.featureHeight,s=this.margin+this.expandedRowHeight*e.row):(a=this.featureHeight,s=this.margin);const c=r.pixelWidth,l=s+a/2,h=a/2,d=l-h/2,f=e.exons?e.exons.length:0,u=Kg(e,t,i),p=this.arrowSpacing,m="+"===e.strand?1:"-"===e.strand?-1:0;if(0===f){const e=Math.max(0,u.px),t=Math.min(c,u.px1),i=t-e;if(o.fillRect(e,s,i,a),0!==m){o.fillStyle="white",o.strokeStyle="white";for(let i=e+p/2;ic)break;if(f.utr)o.fillRect(g,d,F,h);else if(f.cdStart&&(u=Math.round((f.cdStart-t)/i),o.fillRect(g,d,u-g,h),F-=u-g,g=u),f.cdEnd&&(u=Math.round((f.cdEnd-t)/i),o.fillRect(u,d,w-u,h),F-=w-u,w=u),F=Math.max(F,1),o.fillRect(g,s,F,a),F>p+5&&0!==m){o.fillStyle="white",o.strokeStyle="white";for(let e=g+p/2;eF||u)&&(a.rowLastLabelX[t.row]=w,"y"===a.axis?(e.save(),kd.labelTransformWithContext(e,l),kd.fillText(e,s,l,h,p,c),e.restore()):kd.fillText(e,s,l,h,p,c))}finally{e.restore()}}const Qg=new Set(["nonsense","missense","stop-loss","frameshift","cds-indel"]),Jg=new Set(["coding-synon"]),ew=new Set(["splice-3","splice-5"]),tw=new Set(["untranslated-5","untranslated-3"]);function iw(e,t,i,n,o){var r,a,s,c,l,h,d=Kg(e,t,i),f=this.margin,u=this.snpColors.length;switch(r="squished"===this.displayMode?this.squishedRowHeight:this.expandedRowHeight,this.colorBy){case"function":c=e.func,h=c.split(","),l=h.map((function(e){return Qg.has(e)||ew.has(e)?u-1:Jg.has(e)?u-2:tw.has(e)?u-3:0})),a=l.reduce((function(e,t){return Math.max(e,t)}));break;case"class":a="deletion"===(s=e.class)?u-1:"mnp"===s?u-2:"microsatellite"===s||"named"===s?u-3:0}o.fillStyle=this.snpColors[a],o.fillRect(d.px,f,d.pw,r)}function nw(e,t,i,n,o){const r="EXPANDED"===this.displayMode?this.expandedRowHeight:this.squishedRowHeight;let a=this.margin;"COLLAPSED"!==this.displayMode&&void 0!==e.row&&(a+=e.row*r);const s=a+.5*r,c=s-.5*r,l=s+.5*r,h=Math.round((e.junction_left-t)/i),d=Math.round((e.junction_right-t)/i);o.beginPath(),o.moveTo(h,s),o.bezierCurveTo(h,c,d,c,d,s),o.lineWidth=1+Math.log(e.num_junction_reads)/Math.log(2),o.strokeStyle="blue",o.stroke();const f=e.spanning_frag_coords;for(let e=0;et&&(t=i.row);return this.margin+(t+1)*("SQUISHED"===this.displayMode?this.squishedRowHeight:this.expandedRowHeight)}}draw(e){const t=e.features,i=e.context,n=e.bpPerPixel,o=e.bpStart,r=e.pixelWidth,a=e.pixelHeight,s=o+r*n+1;if(this.config.isMergedTrack||kd.fillRect(i,0,e.pixelTop,r,a,{fillStyle:"rgb(255, 255, 255)"}),t){const c=[];e.rowLastX=[],e.rowLastLabelX=[];for(let i of t)if(i.start>o&&i.ends)break;const t="COLLAPSED"===this.displayMode?0:r.row;e.drawLabel=e.labelAllFeatures||l>10;const c=Math.ceil((r.end-o)/n),d=h[t];if(!d||c>d){this.render.call(this,r,o,n,a,i,e);const s=Math.floor((r.start-o)/n);d&&s-d<=0&&(i.globalAlpha=.5,kd.strokeLine(i,s,0,s,a,{strokeStyle:"rgb(255, 255, 255)"}),i.globalAlpha=1),h[t]=c}}}else console.log("No feature list")}clickedFeatures(e){const t=e.y-this.margin,i=super.clickedFeatures(e);let n;switch(this.displayMode){case"SQUISHED":n=Math.floor(t/this.squishedRowHeight);break;case"EXPANDED":n=Math.floor(t/this.expandedRowHeight);break;default:n=void 0}return i.filter((function(e){return void 0===n||void 0===e.row||n===e.row}))}popupData(e,t){void 0===t&&(t=this.clickedFeatures(e));const i=e.genomicLocation,n=[];for(let e of t){const t=e._f||e,o="function"==typeof t.popupData?t.popupData(i):this.extractPopupData(t);if(o){n.length>0&&n.push("

");const r=this.infoURL||this.config.infoURL;for(let t of o)if(n.push(t),r&&t.name&&"name"===t.name.toLowerCase()&&t.value&&$a(t.value)&&!t.value.startsWith("<")){const i=r.replace("$$",e.name);t.value=`${t.value}`}const a="gff"===this.config.format||"gff3"===this.config.format||"gtf"===this.config.format;if(t.exons)for(let e=0;e=o.start&&i<=o.end){const i=a?o.number:"-"===t.strand?t.exons.length-e:e+1;i&&(n.push("
"),n.push({name:"Exon Number",value:i}));break}}}}return n}menuItemList(){const e=[];if(this.render===iw){e.push("
");for(let t of["function","class"])e.push({object:wr(Va("Color by "+t,t===this.colorBy)),click:()=>{this.colorBy=t,this.trackView.repaintViews()}})}e.push("
");for(let t of["COLLAPSED","SQUISHED","EXPANDED"]){const i={COLLAPSED:"Collapse",SQUISHED:"Squish",EXPANDED:"Expand"};e.push({object:wr(Va(i[t],t===this.displayMode)),click:()=>{this.displayMode=t,this.config.displayMode=t,this.trackView.checkContentHeight(),this.trackView.repaintViews()}})}return e}contextMenuItemList(e){const t=this.clickedFeatures(e);if(void 0===t||0===t.length)return;t.length>1&&t.sort(((e,t)=>t.end-t.start-(e.end-e.start)));const i=t[0];if(i.end-i.start<=1e6){const e=[{label:"View feature sequence",click:async()=>{let e=await this.browser.genome.getSequence(i.chr,i.start,i.end);e?"-"===i.strand&&(e=Jd(e)):e="Unknown sequence",this.browser.alert.present(e)}}];return Od()&&void 0!==navigator.clipboard&&e.push({label:"Copy feature sequence",click:async()=>{let e=await this.browser.genome.getSequence(i.chr,i.start,i.end);e?"-"===i.strand&&(e=Jd(e)):e="Unknown sequence";try{await navigator.clipboard.writeText(e)}catch(e){console.error(e),this.browser.alert.present(`error copying sequence to clipboard ${e}`)}}}),e.push("
"),e}}description(){if(iw===this.render){let e=""+this.name+"
";return e+="Color By Function:
",e+='Red: Coding-Non-Synonymous, Splice Site
',e+='Green: Coding-Synonymous
',e+='Blue: Untranslated
',e+='Black: Intron, Locus, Unknown

',e+="Color By Class:
",e+='Red: Deletion
',e+='Green: MNP
',e+='Blue: Microsatellite, Named
',e+='Black: Indel, Insertion, SNP',e+="",e}return super.description()}getColorForFeature(e){let t;if(this.altColor&&"-"===e.strand)t="function"==typeof this.altColor?this.altColor(e):this.altColor;else if(this.color)t="function"==typeof this.color?this.color(e):this.color;else if(this.colorBy){const i=e.getAttributeValue?e.getAttributeValue(this.colorBy):e[this.colorBy];t=this.colorTable.getColor(i)}else e.color&&(t=e.color);if(t||(t="rgb(0, 0, 150)"),e.alpha&&1!==e.alpha)t=qh.addAlpha(t,e.alpha);else if(this.useScore&&e.score&&!Number.isNaN(e.score)){const i=function(e,t,i){const n=(t-e)/9,o=Math.floor((i-e)/n);return Math.min(1,.2+.8*o/9)}(this.config.min?this.config.min:this.viewLimitMin?this.viewLimitMin:0,this.config.max?this.config.max:this.viewLimitMax?this.viewLimitMax:1e3,e.score);e.alpha=i,t=qh.addAlpha(t,i)}return t}dispose(){this.trackView=void 0}}class rw{constructor(e){this.config=e,this.browser=e.browser,this.columnFormat=e.columnFormat,this.tableRowSelectionList=[],this.tableDOM=xr.div({class:"igv-roi-table"}),e.parent.appendChild(this.tableDOM),this.headerDOM=e,this.tableColumnTitles=this.tableDOM,this.tableRowContainer=this.tableDOM,this.footerDOM=e.gotoButtonHandler}set headerDOM({browser:e,parent:t,headerTitle:i,dismissHandler:n}){const o=xr.div();this.tableDOM.appendChild(o);const r=xr.div();o.appendChild(r),r.innerHTML=i;const a=xr.div();o.appendChild(a),a.appendChild(xa.createIcon("times")),this.boundDismissHandler=function(e){e.stopPropagation(),n()}.bind(this),a.addEventListener("click",this.boundDismissHandler);const{y:s}=e.root.getBoundingClientRect(),{y:c}=t.getBoundingClientRect(),l=-(c-s);Sa(this.tableDOM,o,{minX:0,minY:l}),this.tableDOM.style.display="none",this._headerDOM=o}set tableColumnTitles(e){const t=xr.div({class:"igv-roi-table-column-titles"});e.appendChild(t);for(const{label:e,width:i}of this.columnFormat){const n=xr.div();t.appendChild(n),n.style.width=i,n.innerText=e}this._tableColumnTitlesDOM=t}get tableColumnTitles(){return this._tableColumnTitlesDOM}set tableRowContainer(e){const t=xr.div({class:"igv-roi-table-row-container"});e.appendChild(t),this._tableRowContainerDOM=t}get tableRowContainer(){return this._tableRowContainerDOM}set footerDOM(e){const t=xr.div();this.tableDOM.appendChild(t);const i=xr.div({class:"igv-roi-table-button"});t.appendChild(i),i.id="igv-roi-table-view-button",i.textContent="Go To",i.style.pointerEvents="none",this._footerDOM=t,this.gotoButton=i,this.boundGotoButtonHandler=e.bind(this),this.gotoButton.addEventListener("click",this.boundGotoButtonHandler)}tableRowDOMHelper(e){e.addEventListener("mousedown",(t=>{t.stopPropagation(),e.classList.toggle("igv-roi-table-row-selected"),e.classList.contains("igv-roi-table-row-selected")?e.classList.remove("igv-roi-table-row-hover"):e.classList.add("igv-roi-table-row-hover"),this.setTableRowSelectionState(e.classList.contains("igv-roi-table-row-selected"))})),e.addEventListener("mouseover",(t=>{e.classList.contains("igv-roi-table-row-selected")?e.classList.remove("igv-roi-table-row-hover"):e.classList.add("igv-roi-table-row-hover")})),e.addEventListener("mouseout",(t=>{e.classList.remove("igv-roi-table-row-hover")}))}clearTable(){const e=this.tableRowContainer.querySelectorAll(".igv-roi-table-row");for(let t of e)t.remove()}setTableRowSelectionState(e){e?this.tableRowSelectionList.push(1):this.tableRowSelectionList.pop(),this.gotoButton.style.pointerEvents=this.tableRowSelectionList.length>0?"auto":"none"}present(){this.tableDOM.style.left="0px";const{y:e}=this.browser.root.getBoundingClientRect(),{y:t}=this.config.parent.getBoundingClientRect();this.tableDOM.style.top=e-t+"px",this.tableDOM.style.display="flex"}dismiss(){this.tableDOM.style.display="none"}dispose(){this.tableDOM.innerHTML="",this.tableDOM.remove();for(const e of Object.keys(this))this[e]=void 0;document.removeEventListener("click",this.boundDismissHandler)}}class aw extends rw{constructor(e){super(Object.assign({width:"1024px"},e)),this.descriptionDOM=e}set descriptionDOM(e){if(e.description){let t;t=xr.div({class:"igv-roi-table-description"}),this.tableDOM.insertBefore(t,this.tableColumnTitles),t.style.height="auto",t.innerHTML="BLAT result for query sequence:",t=xr.div({class:"igv-roi-table-description"}),this.tableDOM.insertBefore(t,this.tableColumnTitles),t.style.height="auto",t.style.maxHeight="128px",t.innerHTML=e.description,t=xr.div({class:"igv-roi-table-goto-explainer"}),this.tableDOM.insertBefore(t,this.tableColumnTitles),t.innerHTML="Select one or more rows and click Go To to view the regions"}}tableRowDOM(e){const t=xr.div({class:"igv-roi-table-row"}),i=e.map((e=>isFinite(e)?Za(e):e));for(let e=0;ee.remove())),e.length>0)for(let t of e){const e=this.tableRowDOM(t);this.tableRowContainer.appendChild(e)}}static getColumnFormatConfiguration(){return[{label:"chr",width:"7%"},{label:"start",width:"12%"},{label:"end",width:"12%"},{label:"strand",width:"5%"},{label:"score",width:"5%"},{label:"match",width:"5%"},{label:"mis-match",width:"7%"},{label:"rep. match",width:"7%"},{label:"N's",width:"3%"},{label:"Q gap count",width:"9%"},{label:"Q gap bases",width:"9%"},{label:"T gap count",width:"9%"},{label:"T gap bases",width:"9%"}]}static gotoButtonHandler(e){e.stopPropagation();const t=this.tableDOM.querySelectorAll(".igv-roi-table-row-selected"),i=[];for(const e of t){const t=[];e.querySelectorAll("div").forEach((e=>t.push(e.innerText)));const[n,o,r]=t;i.push(`${n}:${o}-${r}`)}for(const e of this.tableDOM.querySelectorAll(".igv-roi-table-row"))e.classList.remove("igv-roi-table-row-selected");this.setTableRowSelectionState(!1),this.browser.search(i.join(" "))}}async function sw({url:e,userSeq:t,db:i}){e=e||"https://igv.org/services/blatUCSC.php";const n=await async function(e="",t,i){const n=new URLSearchParams;n.append("userSeq",t),n.append("db",i);const o=await fetch(e,{method:"post",body:n});return o.json()}(e,t,i);n.fields;return n.blat.map(gu)}const cw=25e3;class lw extends ow{constructor(e,t){super(e,t),this.name||(this.name="Blat Results"),this.sequence=e.sequence,this.table=void 0}openTableView(){if(void 0===this.table){const e=this.config.features.map((e=>[e.chr,e.start+1,e.end,e.strand,e.score,e.matches,e.misMatches,e.repMatches,e.nCount,e.qNumInsert,e.qBaseInsert,e.tNumInsert,e.tBaseInsert])),t={browser:this.browser,parent:this.browser.parent,headerTitle:this.config.title,description:this.sequence,dismissHandler:()=>{this.table.dismiss(),this.table.dispose(),this.table=void 0},columnFormat:aw.getColumnFormatConfiguration(),gotoButtonHandler:aw.gotoButtonHandler};this.table=new aw(t),this.table.renderTable(e)}this.table.present()}menuItemList(){const e=super.menuItemList();return e.push("
"),e.push({label:"Open table view",click:()=>this.openTableView()}),e}dispose(){super.dispose(),this.table&&this.table.popover.parentElement.removeChild(this.table.popover)}}async function hw({sequence:e,browser:t,name:i,title:n}){if(e.length>cw)return void t.alert.present(`Sequence size exceeds maximum allowed length (${e.length} > 25000)`);const o=t.genome.id,r=t.config.blatServerURL;try{const a={type:"blat",name:i||"blat results",title:n||"blat results",sequence:e,altColor:"rgb(176, 176, 236)",color:"rgb(236, 176, 176)",features:await sw({url:r,userSeq:e,db:o})};(await t.loadTrack(a)).openTableView()}catch(e){t.alert.present(`Error performing blat search: ${e}`)}}const dw="rgb(185, 185, 185)";class fw extends Tu{static defaults={alleleFreqThreshold:.2,visibilityWindow:3e4,showCoverage:!0,showAlignments:!0,viewAsPairs:!1,pairsSupported:!0,showSoftClips:!1,showAllBases:!1,showInsertions:!0,showMismatches:!0,height:300,coverageTrackHeight:50};constructor(e,t){super(e,t)}init(e){this.type="alignment",this.featureSource=new ug(e,this.browser),this.coverageTrack=new uw(e,this),this.alignmentTrack=new pw(e,this),super.init(e),this.alignmentTrack.setTop(this.coverageTrack,this.showCoverage),this.showAlignments||(this._height=this.coverageTrackHeight),e.sort&&(Array.isArray(e.sort)?this.assignSort(e.sort[0]):this.assignSort(e.sort))}set height(e){this._height=e,this.showAlignments&&(this.alignmentTrack.height=this.showCoverage?e-this.coverageTrackHeight:e)}get height(){return this._height}get minTemplateLength(){const e=void 0!==this.config.minTLEN?this.config.minTLEN:this.config.minFragmentLength;return void 0!==e?e:this._pairedEndStats?this._pairedEndStats.minTLEN:0}get maxTemplateLength(){const e=void 0!==this.config.maxTLEN?this.config.maxTLEN:this.config.maxFragmentLength;return void 0!==e?e:this._pairedEndStats?this._pairedEndStats.maxTLEN:1e3}sort(e){e=this.assignSort(e);for(let t of this.trackView.viewports)if(t.containsPosition(e.chr,e.position)){const i=t.cachedFeatures;i&&(i.sortRows(e),t.repaint())}}assignSort(e){if(e.locus){const t=function(e){const t=e.split(":"),i=t[1].split("-"),n={chr:t[0],start:Number.parseInt(i[0].replace(/,/g,""))-1};return i.length>1?n.end=Number.parseInt(i[1].replace(/,/g,"")):n.end=n.start+1,n}(e.locus);e.chr=t.chr,e.position=t.start}else e.position--;return e.direction="ASC"===e.direction||!0===e.direction,e.chr=this.browser.genome.getChromosomeName(e.chr),this.sortObject=e,this.sortObject}async getFeatures(e,t,i,n,o){const r=await this.featureSource.getAlignments(e,t,i);if(r.paired&&!this._pairedEndStats&&!this.config.maxFragmentLength){const e=new Gg(r.alignments,this.config);e.totalCount>99&&(this._pairedEndStats=e)}r.alignments=void 0;const a=this.sortObject;return a&&a.chr===e&&a.position>=t&&a.position<=i&&r.sortRows(a),r}computePixelHeight(e){return(this.showCoverage?this.coverageTrackHeight:0)+(this.showAlignments?this.alignmentTrack.computePixelHeight(e):0)}draw(e){kd.fillRect(e.context,0,e.pixelTop,e.pixelWidth,e.pixelHeight,{fillStyle:"rgb(255, 255, 255)"}),!0===this.showCoverage&&this.coverageTrackHeight>0?(this.trackView.axisCanvas.style.display="block",this.coverageTrack.draw(e)):this.trackView.axisCanvas.style.display="none",!0===this.showAlignments&&(this.alignmentTrack.setTop(this.coverageTrack,this.showCoverage),this.alignmentTrack.draw(e))}paintAxis(e,t,i){this.coverageTrack.paintAxis(e,t,this.coverageTrackHeight)}contextMenuItemList(e){return this.alignmentTrack.contextMenuItemList(e)}popupData(e){return!0===this.showCoverage&&e.y>=this.coverageTrack.top&&e.y=this.coverageTrack.top&&e.y=this.coverageTrack.top&&e.y");const t=wr('
');t.text("Color by:"),e.push({name:void 0,object:t,click:void 0,init:void 0});const i=[{key:"strand",label:"read strand"}];this.alignmentTrack.hasPairs&&(i.push({key:"firstOfPairStrand",label:"first-of-pair strand"}),i.push({key:"pairOrientation",label:"pair orientation"}),i.push({key:"tlen",label:"insert size (TLEN)"}),i.push({key:"unexpectedPair",label:"pair orientation & insert size (TLEN)"}));const n="tag"+(this.alignmentTrack.colorByTag?" ("+this.alignmentTrack.colorByTag+")":"");i.push({key:"tag",label:n});for(let t of i){const i=this.alignmentTrack.colorBy===t.key;e.push(this.colorByCB(t,i))}const o=()=>{if(!this.autoHeight){const e=(this.showCoverage?this.coverageTrackHeight:0)+(this.showAlignments?this.alignmentTrack.height:0);this.trackView.setTrackHeight(e)}};e.push("
"),e.push({object:wr(Va("Show Coverage",this.showCoverage)),click:()=>{this.showCoverage=!this.showCoverage,o(),this.trackView.checkContentHeight(),this.trackView.repaintViews()}}),e.push({object:wr(Va("Show Alignments",this.showAlignments)),click:()=>{this.showAlignments=!this.showAlignments,o(),this.trackView.checkContentHeight(),this.trackView.repaintViews()}}),e.push("
"),e.push({object:wr(Va("Show all bases",this.showAllBases)),click:()=>{this.showAllBases=!this.showAllBases,this.config.showAllBases=this.showAllBases,this.trackView.repaintViews()}}),e.push("
"),e.push({object:wr(Va("Show mismatches",this.showMismatches)),click:()=>{this.showMismatches=!this.showMismatches,this.config.showMismatches=this.showMismatches,this.trackView.repaintViews()}}),e.push({object:wr(Va("Show insertions",this.showInsertions)),click:()=>{this.showInsertions=!this.showInsertions,this.config.showInsertions=this.showInsertions,this.getCachedAlignmentContainers(),this.trackView.repaintViews()}}),e.push({object:wr(Va("Show soft clips",this.showSoftClips)),click:()=>{this.showSoftClips=!this.showSoftClips,this.config.showSoftClips=this.showSoftClips,this.featureSource.setShowSoftClips(this.showSoftClips);const e=this.getCachedAlignmentContainers();for(let t of e)t.setShowSoftClips(this.showSoftClips);this.trackView.repaintViews()}}),this.pairsSupported&&this.alignmentTrack.hasPairs&&(e.push("
"),e.push({object:wr(Va("View as pairs",this.viewAsPairs)),click:()=>{this.viewAsPairs=!this.viewAsPairs,this.config.viewAsPairs=this.viewAsPairs,this.featureSource.setViewAsPairs(this.viewAsPairs);const e=this.getCachedAlignmentContainers();for(let t of e)t.setViewAsPairs(this.viewAsPairs);this.trackView.repaintViews()}})),this.browser.circularView&&(this.alignmentTrack.hasPairs||this.alignmentTrack.hasSupplemental)&&(e.push("
"),this.alignmentTrack.hasPairs&&e.push({label:"Add discordant pairs to circular view",click:()=>{for(let e of this.trackView.viewports)this.addPairedChordsForViewport(e)}}),this.alignmentTrack.hasSupplemental&&e.push({label:"Add split reads to circular view",click:()=>{for(let e of this.trackView.viewports)this.addSplitChordsForViewport(e)}})),e.push("
");const r=wr('
');return r.text("Display mode:"),e.push({name:void 0,object:r,click:void 0,init:void 0}),e.push({object:wr(Va("expand","EXPANDED"===this.alignmentTrack.displayMode)),click:()=>{this.alignmentTrack.displayMode="EXPANDED",this.config.displayMode="EXPANDED",this.trackView.checkContentHeight(),this.trackView.repaintViews()}}),e.push({object:wr(Va("squish","SQUISHED"===this.alignmentTrack.displayMode)),click:()=>{this.alignmentTrack.displayMode="SQUISHED",this.config.displayMode="SQUISHED",this.trackView.checkContentHeight(),this.trackView.repaintViews()}}),e}colorByCB(e,t){return{name:void 0,object:wr(Va(e.label,t)),click:t=>{"tag"!==e.key?e.key===this.alignmentTrack.colorBy?(this.alignmentTrack.colorBy="none",this.config.colorBy="none",this.trackView.repaintViews()):(this.alignmentTrack.colorBy=e.key,this.config.colorBy=e.key,this.trackView.repaintViews()):this.browser.inputDialog.present({label:"Tag Name",value:this.alignmentTrack.colorByTag?this.alignmentTrack.colorByTag:"",callback:e=>{e?(this.alignmentTrack.colorBy="tag",this.alignmentTrack.colorByTag=e,this.alignmentTrack.tagColors||(this.alignmentTrack.tagColors=new yd("Set1"))):(this.alignmentTrack.colorBy="none",this.alignmentTrack.colorByTag=""),this.trackView.repaintViews()}},t)},init:void 0}}getState(){const e=super.getState();return this.sortObject&&(e.sort={chr:this.sortObject.chr,position:this.sortObject.position+1,option:this.sortObject.option,direction:this.sortObject.direction?"ASC":"DESC"}),e}getCachedAlignmentContainers(){return this.trackView.viewports.map((e=>e.cachedFeatures))}get dataRange(){return this.coverageTrack.dataRange}set dataRange(e){this.coverageTrack.dataRange=e}get logScale(){return this.coverageTrack.logScale}set logScale(e){this.coverageTrack.logScale=e}get autoscale(){return this.coverageTrack.autoscale}set autoscale(e){this.coverageTrack.autoscale=e}addPairedChordsForViewport(e){const t=this.maxTemplateLength,i=[],n=e.referenceFrame;for(let o of e.cachedFeatures.allAlignments())o.end>=n.start&&o.start<=n.end&&(o.paired?o.end-o.start>t&&i.push(o):o.mate&&o.mate.chr&&(o.mate.chr!==o.chr||Math.max(o.fragmentLength)>t)&&i.push(o));Wg((e=>{const t=[];for(let i of e)if(i.paired)i.firstAlignment&&i.secondAlignment&&t.push({uniqueId:i.readName,refName:Ug(i.firstAlignment.chr),start:i.firstAlignment.start,end:i.firstAlignment.end,mate:{refName:Ug(i.secondAlignment.chr),start:i.secondAlignment.start,end:i.secondAlignment.end}});else{const e=i.mate;e&&e.chr&&e.position&&t.push({uniqueId:i.readName,refName:Ug(i.chr),start:i.start,end:i.end,mate:{refName:Ug(e.chr),start:e.position-1,end:e.position}})}return t})(i),this,n,.02)}addSplitChordsForViewport(e){const t=[],i=e.referenceFrame;for(let n of e.cachedFeatures.allAlignments()){const e=n.hasTag("SA");n.end>=i.start&&n.start<=i.end&&e&&t.push(n)}Wg((e=>{const t=e=>{const t=Mm(e.tags().SA);let n=0;for(let o of t)o.start!==e.start&&i.push({uniqueId:`${e.readName}_${n++}`,refName:Ug(e.chr),start:e.start,end:e.end,mate:{refName:Ug(o.chr),start:o.start,end:o.start+o.lenOnRef}})},i=[];for(let i of e)i.paired?(t(i.firstAlignment),i.secondAlignment&&t(i.secondAlignment)):t(i);return i})(t),this,i,.02)}}class uw{constructor(e,t){this.parent=t,this.featureSource=t.featureSource,this.paintAxis=pg,this.top=0,this.autoscale=e.autoscale||void 0===e.max,this.autoscale||(this.dataRange={min:e.min||0,max:e.max})}get height(){return this.parent.coverageTrackHeight}draw(e){const t=e.pixelTop;e.pixelHeight;const i=this.parent.browser.nucleotideColors;if(t>this.height)return;const n=e.context,o=e.features.coverageMap;let r;o.refSeq&&(r=o.refSeq.toUpperCase());const a=e.bpPerPixel,s=e.bpStart,c=s+e.pixelWidth*a+1;let l;l=this.parent.coverageColor?this.parent.coverageColor:this.parent.color&&"function"!=typeof this.parent.color?qh.darkenLighten(this.parent.color,-35):"rgb(150, 150, 150)",kd.setProperties(n,{fillStyle:l,strokeStyle:l});const h=Math.max(1,Math.ceil(1/a));for(let e=0,t=o.coverage.length;ec)break;const i=o.coverage[e];if(!i)continue;const r=Math.round(i.total/this.dataRange.max*this.height),l=this.height-r,d=Math.floor((t-s)/a);kd.fillRect(n,d,l,h,r)}if(r)for(let e=0,t=o.coverage.length;ec)break;const l=o.coverage[e];if(!l)continue;const d=l.total/this.dataRange.max*this.height;let f=this.height-d;const u=Math.floor((t-s)/a),p=r[e];if(l.isMismatch(p)){kd.setProperties(n,{fillStyle:i[p]}),kd.fillRect(n,u,f,h,d);let e=0;for(let t of["A","C","T","G"]){const o=(l["pos"+t]+l["neg"+t])/this.dataRange.max*this.height;f=this.height-o-e,e+=o,kd.setProperties(n,{fillStyle:i[t]}),kd.fillRect(n,u,f,h,o)}}}}getClickedObject(e){let t=e.viewport.cachedFeatures;if(!t||0===t.length)return;const i=Math.floor(e.genomicLocation),n=t.coverageMap,o=Math.floor(i-n.bpStart);return n.coverage[o]}popupData(e){const t=[],i=this.getClickedObject(e);if(i){const n=Math.floor(e.genomicLocation),o=e.viewport.referenceFrame;t.push(o.chr+":"+Za(1+n)),t.push({name:"Total Count",value:i.total});let r=i.posA+i.negA;r>0&&(r=r.toString()+" ("+Math.round(r/i.total*100)+"%, "+i.posA+"+, "+i.negA+"- )"),t.push({name:"A",value:r}),r=i.posC+i.negC,r>0&&(r=r.toString()+" ("+Math.round(r/i.total*100)+"%, "+i.posC+"+, "+i.negC+"- )"),t.push({name:"C",value:r}),r=i.posG+i.negG,r>0&&(r=r.toString()+" ("+Math.round(r/i.total*100)+"%, "+i.posG+"+, "+i.negG+"- )"),t.push({name:"G",value:r}),r=i.posT+i.negT,r>0&&(r=r.toString()+" ("+Math.round(r/i.total*100)+"%, "+i.posT+"+, "+i.negT+"- )"),t.push({name:"T",value:r}),r=i.posN+i.negN,r>0&&(r=r.toString()+" ("+Math.round(r/i.total*100)+"%, "+i.posN+"+, "+i.negN+"- )"),t.push({name:"N",value:r}),t.push("
"),t.push({name:"DEL",value:i.del.toString()}),t.push({name:"INS",value:i.ins.toString()})}return t}}class pw{constructor(e,t){this.parent=t,this.browser=t.browser,this.featureSource=t.featureSource,this.top=0===e.coverageTrackHeight?0:e.coverageTrackHeight+5,this.displayMode=e.displayMode||"EXPANDED",this.alignmentRowHeight=e.alignmentRowHeight||14,this.squishedRowHeight=e.squishedRowHeight||3,this.negStrandColor=e.negStrandColor||"rgba(150, 150, 230, 0.75)",this.posStrandColor=e.posStrandColor||"rgba(230, 150, 150, 0.75)",this.insertionColor=e.insertionColor||"rgb(138, 94, 161)",this.insertionTextColor=e.insertionTextColor||"white",this.showInsertionText=void 0!==e.showInsertionText&&!!e.showInsertionText,this.deletionColor=e.deletionColor||"black",this.deletionTextColor=e.deletionTextColor||"black",this.showDeletionText=void 0!==e.showDeletionText&&!!e.showDeletionText,this.skippedColor=e.skippedColor||"rgb(150, 170, 170)",this.pairConnectorColor=e.pairConnectorColor,this.smallTLENColor=e.smallTLENColor||e.smallFragmentLengthColor||"rgb(0, 0, 150)",this.largeTLENColor=e.largeTLENColor||e.largeFragmentLengthColor||"rgb(200, 0, 0)",this.pairOrientation=e.pairOrienation||"fr",this.pairColors={},this.pairColors.RL=e.rlColor||"rgb(0, 150, 0)",this.pairColors.RR=e.rrColor||"rgb(20, 50, 200)",this.pairColors.LL=e.llColor||"rgb(0, 150, 150)",this.colorBy=e.colorBy||"unexpectedPair",this.colorByTag=e.colorByTag?e.colorByTag.toUpperCase():void 0,this.bamColorTag=void 0===e.bamColorTag?"YC":e.bamColorTag,this.hideSmallIndels=e.hideSmallIndels,this.indelSizeThreshold=e.indelSizeThreshold||1,this.hasPairs=!1,this.hasSupplemental=!1}setTop(e,t){this.top=0===e.height||!1===t?0:5+e.height}computePixelHeight(e){if(e.packedAlignmentRows){return(e.hasDownsampledIntervals()?10:0)+("SQUISHED"===this.displayMode?this.squishedRowHeight:this.alignmentRowHeight)*e.packedAlignmentRows.length+5}return 0}draw(e){const t=e.features,i=e.context,n=e.bpPerPixel,o=e.bpStart,r=e.pixelWidth,a=o+r*n+1,s=this.parent.showSoftClips,c=this.parent.showAllBases,l=this.browser.nucleotideColors,h=t.packedAlignmentRows;i.save();let d=t.sequence;d&&(d=d.toUpperCase());let f=0,u=e.pixelTop;this.top&&i.translate(0,this.top);const p=u+e.pixelHeight;t.hasDownsampledIntervals()?(f=10,t.downsampledIntervals.forEach((function(e){var t=(e.start-o)/n,r=(e.end-o)/n;r-t>5&&(t+=1,r-=1),kd.fillRect(i,t,2,r-t,3,{fillStyle:"black"})}))):f=0,this.alignmentsYOffset=f;const m="SQUISHED"===this.displayMode?this.squishedRowHeight:this.alignmentRowHeight;if(h){const e=h.length;for(let t=0;tp)break;if(!(i+na)break;!0!==t.hidden&&(t instanceof ym?(g.call(this,t,i,n),w.call(this,t.firstAlignment,i,n),t.secondAlignment&&w.call(this,t.secondAlignment,i,n)):w.call(this,t,i,n))}}}function g(e,t,r){var s=this.getConnectorColor(e.firstAlignment),c=(e.connectingStart-o)/n,l=(e.connectingEnd-o)/n,h=t+r/2;e.connectingEnda||(e.mq<=0&&(s=qh.addAlpha(s,.15)),kd.setProperties(i,{fillStyle:s,strokeStyle:s}),kd.strokeLine(i,c,h,l,h))}function w(e,h,f){if(e.start+e.lengthOnRefa)return;const u=s?e.blocks:e.blocks.filter((e=>"S"!==e.type));let p=this.getAlignmentColor(e);const g=p;e.mq<=0&&(p=qh.addAlpha(p,.15)),kd.setProperties(i,{fillStyle:p,strokeStyle:g});const w=[];for(let e=0;ea))break}if(e.gaps){const t=h+f/2;for(let r of e.gaps){const e=(r.start-o)/n,a=(r.start+r.len-o)/n,s=a-e,c=r.len.toString(),l=6*c.length,d=e+s/2,f="D"===r.type?this.deletionColor:this.skippedColor;if(kd.strokeLine(i,e,t,a,t,{strokeStyle:f,lineWidth:2}),this.showDeletionText&&r.len>1&&s>=l+8){const e=d-l/2;kd.fillRect(i,e-1,h-1,l+2,12,{fillStyle:"white"}),kd.fillText(i,c,e,h+10,{font:"normal 10px monospace",fillStyle:this.deletionTextColor})}}}if(e.insertions&&this.parent.showInsertions){let t=-1;for(let r of e.insertions){if(this.hideSmallIndels&&r.len<=this.indelSizeThreshold)continue;if(r.starta)break;const e=r.start-o,s=r.len.toString(),c=2+6*s.length,l=this.showInsertionText&&1!==r.len?Math.round(r.len/n):2,d=Math.max(Math.min(c,l),2),u=e/n-d/2;if(u-t>2){const e={fillStyle:this.insertionColor};kd.fillRect(i,u-2,h,d+4,2,e),kd.fillRect(i,u,h+2,d,f-4,e),kd.fillRect(i,u-2,h+f-2,d+4,2,e),this.showInsertionText&&r.len>1&&l>c&&kd.fillText(i,s,u+1,h+10,{font:"normal 10px monospace",fillStyle:this.insertionTextColor}),t=u}}}function F(a,s){const w=[],F=a.start-t.start,b=(a.start-o)/n,v=(a.start+a.len-o)/n,y=Math.max(1,v-b),_=100/n,C=Math.min(m/2,_/6),x="S"===a.type,k=e.mq<=0||this.highlightedAlignmentReadNamed===e.readName||x;let E=g;this.highlightedAlignmentReadNamed===e.readName?E="red":x&&(E="rgb(50,50,50)");const N=!0===e.strand&&s===u.length-1,S=!1===e.strand&&0===s;if(N|S){let e,t;N?(e=[b,v,v+C,v,b,b],t=[h,h,h+f/2,h+f,h+f,h]):S&&(e=[v,b,b-C,b,v,v],t=[h,h,h+f/2,h+f,h+f,h]),kd.fillPolygon(i,e,t,{fillStyle:p}),k&&kd.strokePolygon(i,e,t,{strokeStyle:E})}else kd.fillRect(i,b,h,y,f,{fillStyle:p}),k&&(i.save(),i.strokeStyle=E,i.strokeRect(b,h,y,f),i.restore());if(x||c||this.parent.showMismatches&&d&&e.seq&&"*"!==e.seq){const t=e.seq?e.seq.toUpperCase():void 0,i=e.qual,s=a.seqOffset,u=Math.max(1,1/n);for(let e=0,p=a.len;er)break;let m=t?t.charAt(s+e):"";const g=F+e>=0?d.charAt(F+e):"";if("="===m&&(m=g),"X"===m||g!==m||x||c){let t;if(!x&&void 0!==i&&i.length>s+e){t=mw(i[s+e],l[m])}else t=l[m];t&&w.push({bbox:{x:p,y:h,width:u,height:f},baseColor:t,readChar:m})}}}return w}w.forEach((({bbox:e,baseColor:t,readChar:o})=>{!function(e,t,i,n,o){var r;if(t<=.1&&i.height>=8){const t=Math.min(10,i.height);e.font=t+"px sans-serif",r=i.x+i.width/2,kd.strokeText(e,o,r-e.measureText(o).width/2,t-1+i.y,{strokeStyle:n})}else kd.fillRect(e,i.x,i.y,i.width,i.height,{fillStyle:n})}(i,n,e,t,o)}))}i.restore()}popupData(e){const t=this.getClickedObject(e);return t?t.popupData(e.genomicLocation):void 0}contextMenuItemList(e){const t=e.viewport,i=[],n=i=>{const n=this.parent.sortObject,o=!n||n.position!==Math.floor(e.genomicLocation)||!n.direction,r={chr:t.referenceFrame.chr,position:Math.floor(e.genomicLocation),option:i,direction:o};this.parent.sortObject=r,t.cachedFeatures.sortRows(r),t.repaint()};i.push("Sort by..."),i.push({label:"  base",click:()=>n("BASE")}),i.push({label:"  read strand",click:()=>n("STRAND")}),i.push({label:"  insert size",click:()=>n("INSERT_SIZE")}),i.push({label:"  gap size",click:()=>n("GAP_SIZE")}),i.push({label:"  chromosome of mate",click:()=>n("MATE_CHR")}),i.push({label:"  mapping quality",click:()=>n("MQ")}),i.push({label:"  read name",click:()=>n("READ_NAME")}),i.push({label:"  aligned read length",click:()=>n("ALIGNED_READ_LENGTH")}),i.push({label:"  tag",click:()=>{const i=this.parent.sortObject,n=!i||i.position!==Math.floor(e.genomicLocation)||!i.direction,o={label:"Tag Name",value:this.sortByTag?this.sortByTag:"",callback:i=>{if(i){const o={chr:t.referenceFrame.chr,position:Math.floor(e.genomicLocation),option:"TAG",tag:i,direction:n};this.sortByTag=i,this.parent.sortObject=o,t.cachedFeatures.sortRows(o),t.repaint()}}};this.browser.inputDialog.present(o,e.event)}}),i.push("
");const o=this.getClickedObject(e);if(o){const t=this.parent.showSoftClips,n="function"==typeof o.alignmentContaining?o.alignmentContaining(e.genomicLocation,t):o;if(n){n.isPaired()&&n.isMateMapped()&&i.push({label:"View mate in split screen",click:()=>{if(n.mate){const t=e.viewport.referenceFrame;if(this.browser.genome.getChromosome(n.mate.chr)){this.highlightedAlignmentReadNamed=n.readName;const e=t.end-t.start,i=n.mate.position-e/2,o=n.mate.position+e/2;this.browser.addMultiLocusPanel(n.mate.chr,i,o,t)}else this.browser.alert.present(`Reference does not contain chromosome: ${n.mate.chr}`)}},init:void 0}),i.push({label:"View read sequence",click:()=>{const e=n.seq;e&&"*"!==e?this.browser.alert.present(e):this.browser.alert.present("Read sequence: *")}}),Od()&&i.push({label:"Copy read sequence",click:async()=>{const e=n.seq;try{await navigator.clipboard.writeText(e)}catch(e){console.error(e),this.browser.alert.present(`error copying sequence to clipboard ${e}`)}}});const t=n.seq;if(t&&"*"!=t){t.length{const e=n.isNegativeStrand()?Jd(t):t,i=`${n.readName} - blat`,o=`${this.parent.name} - ${i}`;hw({sequence:e,browser:this.browser,name:i,title:o})}});const e=n.softClippedBlocks();e.left&&e.left.len>20&&e.left.len{const i=t.substr(e.left.seqOffset,e.left.len),o=n.isNegativeStrand()?Jd(i):i,r=`${n.readName} - blat left clip`,a=`${this.parent.name} - ${r}`;hw({sequence:o,browser:this.browser,name:r,title:a})}}),e.right&&e.right.len>20&&e.right.len{const i=t.substr(e.right.seqOffset,e.right.len),o=n.isNegativeStrand()?Jd(i):i,r=`${n.readName} - blat right clip`,a=`${this.parent.name} - ${r}`;hw({sequence:o,browser:this.browser,name:r,title:a})}})}i.push("
")}}return this.browser.circularView&&(this.hasPairs||this.hasSupplemental)&&(this.hasPairs&&i.push({label:"Add discordant pairs to circular view",click:()=>{this.parent.addPairedChordsForViewport(t)}}),this.hasSupplemental&&i.push({label:"Add split reads to circular view",click:()=>{this.parent.addSplitChordsForViewport(t)}}),i.push("
")),i}getClickedObject(e){const t=e.viewport,i=e.y,n=e.genomicLocation,o=this.parent.showSoftClips;let r=t.cachedFeatures;if(!r||0===r.length)return;let a=r.packedAlignmentRows,s=r.downsampledIntervals;const c="SQUISHED"===this.displayMode?this.squishedRowHeight:this.alignmentRowHeight;let l=Math.floor((i-this.top-this.alignmentsYOffset)/c);if(l<0){for(let e=0;e=n)return s[e]}else if(le.containsLocation(n,o)));if(e.length>0)return e[0]}}getConnectorColor(e){if(this.pairConnectorColor)return this.pairConnectorColor;switch(this.colorBy){case"strand":case"firstOfPairStrand":case"pairOrientation":case"tag":return this.parent.color?"function"==typeof this.parent.color?this.parent.color(e):this.parent.color:"rgb(200, 200, 200)";default:return this.getAlignmentColor(e)}}getAlignmentColor(e){let t=dw;t=this.parent.color?"function"==typeof this.parent.color?this.parent.color(e):this.parent.color:dw;const i=this.colorBy;switch(i){case"strand":t=e.strand?this.posStrandColor:this.negStrandColor;break;case"firstOfPairStrand":e instanceof ym?t=e.firstOfPairStrand()?this.posStrandColor:this.negStrandColor:e.isPaired()&&(e.isFirstOfPair()?t=e.strand?this.posStrandColor:this.negStrandColor:e.isSecondOfPair()?t=e.strand?this.negStrandColor:this.posStrandColor:console.error("ERROR. Paired alignments are either first or second."));break;case"unexpectedPair":case"pairOrientation":if(this.pairOrientation&&e.pairOrientation){const i=gw[this.pairOrientation];if(i){const n=this.pairColors[i[e.pairOrientation]];if(n){t=n;break}}}if("pairOrientation"===i)break;case"tlen":case"fragmentLength":e.mate&&e.isMateMapped()&&(e.mate.chr!==e.chr?t=ww(e.mate.chr):this.parent.minTemplateLength&&Math.abs(e.fragmentLength)this.parent.maxTemplateLength&&(t=this.largeTLENColor));break;case"tag":const n=e.tags()[this.colorByTag];void 0!==n&&(this.bamColorTag===this.colorByTag?t="rgb("+n+")":(this.tagColors||(this.tagColors=new yd("Set1")),t=this.tagColors.getColor(n)))}return t}}function mw(e,t){let i;return i=e<5?.1:Math.max(.1,Math.min(1,.1+.9*(e-5)/15)),i=Math.round(10*i)/10,i<1&&(t=qh.addAlpha(t,i)),t}const gw={fr:{F1R2:"LR",F2R1:"LR",F1F2:"LL",F2F1:"LL",R1R2:"RR",R2R1:"RR",R1F2:"RL",R2F1:"RL"},rf:{R1F2:"LR",R2F1:"LR",R1R2:"LL",R2R1:"LL",F1F2:"RR",F2F1:"RR",F1R2:"RL",F2R1:"RL"},ff:{F2F1:"LR",R1R2:"LR",F2R1:"LL",R1F2:"LL",R2F1:"RR",F1R2:"RR",R2R1:"RL",F1F2:"RL"}};function ww(e){if(Fw[e])return Fw[e];if(Fw["chr"+e]){const t=Fw["chr"+e];return Fw[e]=t,t}{const t=qh.randomRGB(0,255);return Fw[e]=t,t}}const Fw={chrX:"rgb(204, 153, 0)",chrY:"rgb(153, 204, 0)",chrUn:"rgb(50, 50, 50)",chr1:"rgb(80, 80, 255)",chrI:"rgb(139, 155, 187)",chr2:"rgb(206, 61, 50)",chrII:"rgb(206, 61, 50)",chr2a:"rgb(216, 71, 60)",chr2b:"rgb(226, 81, 70)",chr3:"rgb(116, 155, 88)",chrIII:"rgb(116, 155, 88)",chr4:"rgb(240, 230, 133)",chrIV:"rgb(240, 230, 133)",chr5:"rgb(70, 105, 131)",chr6:"rgb(186, 99, 56)",chr7:"rgb(93, 177, 221)",chr8:"rgb(128, 34, 104)",chr9:"rgb(107, 215, 107)",chr10:"rgb(213, 149, 167)",chr11:"rgb(146, 72, 34)",chr12:"rgb(131, 123, 141)",chr13:"rgb(199, 81, 39)",chr14:"rgb(213, 143, 92)",chr15:"rgb(122, 101, 165)",chr16:"rgb(228, 175, 105)",chr17:"rgb(59, 27, 83)",chr18:"rgb(205, 222, 183)",chr19:"rgb(97, 42, 121)",chr20:"rgb(174, 31, 99)",chr21:"rgb(231, 199, 111)",chr22:"rgb(90, 101, 94)",chr23:"rgb(204, 153, 0)",chr24:"rgb(153, 204, 0)",chr25:"rgb(51, 204, 0)",chr26:"rgb(0, 204, 51)",chr27:"rgb(0, 204, 153)",chr28:"rgb(0, 153, 204)",chr29:"rgb(10, 71, 255)",chr30:"rgb(71, 117, 255)",chr31:"rgb(255, 194, 10)",chr32:"rgb(255, 209, 71)",chr33:"rgb(153, 0, 51)",chr34:"rgb(153, 26, 0)",chr35:"rgb(153, 102, 0)",chr36:"rgb(128, 153, 0)",chr37:"rgb(51, 153, 0)",chr38:"rgb(0, 153, 26)",chr39:"rgb(0, 153, 102)",chr40:"rgb(0, 128, 153)",chr41:"rgb(0, 51, 153)",chr42:"rgb(26, 0, 153)",chr43:"rgb(102, 0, 153)",chr44:"rgb(153, 0, 128)",chr45:"rgb(214, 0, 71)",chr46:"rgb(255, 20, 99)",chr47:"rgb(0, 214, 143)",chr48:"rgb(20, 255, 177)"};let bw,vw;class yw extends Pf{constructor(e,t,i,n){super(e,t,i,n)}get contentDiv(){return this.$viewport.get(0)}initializationHelper(){let e;this.$multiLocusCloseButton=wr("
",{class:"igv-multi-locus-close-button"}),this.$viewport.append(this.$multiLocusCloseButton),this.$multiLocusCloseButton.get(0).appendChild(xa.createIcon("times-circle")),this.$multiLocusCloseButton.click((()=>{this.browser.removeMultiLocusPanel(this.referenceFrame)})),this.$rulerLabel=wr("
",{class:"igv-multi-locus-ruler-label"}),this.$viewport.append(this.$rulerLabel),e=document.createElement("div"),this.$rulerLabel.append(wr(e)),this.$rulerLabel.get(0).addEventListener("click",(async e=>{e.stopPropagation(),await this.browser.gotoMultilocusPanel(this.referenceFrame)})),this.$tooltip=wr("
",{class:"igv-ruler-tooltip"}),this.$tooltip.height(this.$viewport.height()),this.$viewport.append(this.$tooltip),this.$tooltipContent=wr("
"),this.$tooltip.append(this.$tooltipContent),this.rulerSweeper=new vm(this,this.$viewport.get(0).parentElement,this.browser,this.referenceFrame),this.attachMouseHandlers(Rf.isWholeGenomeView(this.referenceFrame.chr)),this.$tooltip.hide(),this.dismissLocusLabel()}presentLocusLabel(e){this.$multiLocusCloseButton.show(),this.$rulerLabel.show(),this.$rulerLabel.get(0).style.backgroundColor=ww(this.referenceFrame.chr);const t=this.$rulerLabel.get(0).querySelector("div"),{width:i}=this.$rulerLabel.get(0).getBoundingClientRect();t.innerHTML=`${this.referenceFrame.getMultiLocusLabel(e)}`;const{width:n}=t.getBoundingClientRect();n/i>.5&&(t.innerHTML=`${this.referenceFrame.getMultiLocusLabelBPLengthOnly(e)}`)}dismissLocusLabel(){this.$rulerLabel.hide(),this.$multiLocusCloseButton.hide()}attachMouseHandlers(e){if(this.namespace=`.ruler_track_viewport_${this.browser.referenceFrameList.indexOf(this.referenceFrame)}`,this.$viewport.off(this.namespace),!0===e){const e=this.browser.referenceFrameList.indexOf(this.referenceFrame),t=`click${this.namespace}`;this.$viewport.on(t,(t=>{const{x:i}=xr.translateMouseCoordinates(t,this.$viewport.get(0)),n=Math.round(this.referenceFrame.start+this.referenceFrame.toBP(i));let o;const{chr:r}=this.browser.genome.getChromosomeCoordinate(n);if(1===this.browser.referenceFrameList.length)o=r;else{let t=this.browser.referenceFrameList.map((({locusSearchString:e})=>e));t[e]=r,o=t.join(" ")}this.browser.search(o)})),this.$viewport.get(0).style.cursor="pointer"}else this.$viewport.get(0).style.cursor="default"}mouseMove(e){if(!0===this.browser.cursorGuideVisible){void 0===vw?(vw=this,this.$tooltip.show()):vw.guid!==this.guid?(vw.$tooltip&&vw.$tooltip.hide(),this.$tooltip.show(),vw=this):this.$tooltip.show();if(this.browser.isMultiLocusWholeGenomeView()||Rf.isWholeGenomeView(this.referenceFrame.chr))return void this.$tooltip.hide();const{x:t}=xr.translateMouseCoordinates(e,this.$viewport.get(0)),{start:i,bpPerPixel:n}=this.referenceFrame,o=Math.round(.5+i+Math.max(0,t)*n);this.$tooltipContent.text(Za(o));const{width:r}=this.$tooltipContent.get(0).getBoundingClientRect(),{width:a}=this.$viewport.get(0).getBoundingClientRect();this.$tooltip.css({left:`${Bh(t,0,a-r)}px`}),clearTimeout(bw),bw=setTimeout((()=>{this.$tooltip&&this.$tooltip.hide()}),1e4)}}startSpinner(){}stopSpinner(){}dispose(){this.rulerSweeper.dispose(),super.dispose()}}class _w extends Pf{constructor(e,t,i,n){super(e,t,i,n)}initializationHelper(){this.canvas=document.createElement("canvas"),this.canvas.className="igv-ideogram-canvas",this.$viewport.append(wr(this.canvas)),this.ideogram_ctx=this.canvas.getContext("2d"),this.addMouseHandlers()}addMouseHandlers(){this.addViewportClickHandler(this.$viewport.get(0))}addViewportClickHandler(e){this.boundClickHandler=function(e){const{xNormalized:t,width:i}=xr.translateMouseCoordinates(e,this.ideogram_ctx.canvas),{bpLength:n}=this.browser.genome.getChromosome(this.referenceFrame.chr),o=this.referenceFrame.bpPerPixel*i/n;let r=t;r-o/2<0&&(r=o/2);r+o/2>1&&(r=1-o/2);const a=Math.round((r-o/2)*n),s=Math.round((r+o/2)*n);this.referenceFrame.start=a,this.referenceFrame.end=s,this.referenceFrame.bpPerPixel=(s-a)/i,this.browser.updateViews(this.referenceFrame,this.browser.trackViews,!0)}.bind(this),e.addEventListener("click",this.boundClickHandler)}setWidth(e){this.$viewport.width(e)}drawSVGWithContext(e,t,i,n,o,r,a){e.saveWithTranslationAndClipRect(n,o,r,t,i,a),this.trackView.track.draw({context:e,referenceFrame:this.referenceFrame,pixelWidth:t,pixelHeight:i}),e.restore()}repaint(){this.draw({referenceFrame:this.referenceFrame})}draw({referenceFrame:e}){kd.configureHighDPICanvas(this.ideogram_ctx,this.$viewport.width(),this.$viewport.height()),this.trackView.track.draw({context:this.ideogram_ctx,referenceFrame:e,pixelWidth:this.$viewport.width(),pixelHeight:this.$viewport.height()})}startSpinner(){}stopSpinner(){}}function Cw(e,t,i,n){if("ruler"===e.track.type)return new yw(e,t,i,n);if("ideogram"===e.track.id)return new _w(e,t,i,n);return new Pf(e,t,i,n)}const xw={textAlign:"start",textBaseline:"bottom",strokeStyle:"black",fillStyle:"black"};class kw{constructor(e,t,i,n){this.guid=xr.guid(),this.trackView=e,this.browser=e.browser,this.viewport=xr.div({class:"igv-viewport"}),t.appendChild(this.viewport),e.track.height&&(this.viewport.style.height=`${e.track.height}px`),this.canvas=document.createElement("canvas"),this.viewport.appendChild(this.canvas),this.ctx=this.canvas.getContext("2d"),this.trackScrollDelta=0,this.contentTop=0,this.setWidth(n),!1===this.browser.showSampleNames&&this.hide(),this.addMouseHandlers()}checkCanvas(){const e=window.devicePixelRatio,t=this.viewport.clientHeight,i=this.browser.sampleNameViewportWidth;if(this.canvas.width!==i*e||this.canvas.height!==t*e){const n=this.canvas;n.width=i*e,n.height=t*e,n.style.width=`${i}px`,n.style.height=`${t}px`,this.ctx=this.canvas.getContext("2d"),this.ctx.scale(e,e)}}setTop(e){if("function"==typeof this.trackView.track.getSamples){this.contentTop=e;const t=this.trackView.track.getSamples();this.repaint(t)}}setWidth(e){this.viewport.innerWidth=e,this.checkCanvas()}show(){this.viewport.style.display="block"}hide(){this.viewport.style.display="none"}async repaint(e){this.checkCanvas(),this.draw({context:this.ctx,samples:e})}draw({context:e,samples:t}){if(!t||0===t.names.length)return;!function(e,{textAlign:t,textBaseline:i,strokeStyle:n,fillStyle:o},r){const a=Math.min(r,10);e.font=`${a}px sans-serif`,e.textAlign=t,e.textBaseline=i,e.fillStyle=o}(e,xw,t.height);e.clearRect(0,0,e.canvas.width,e.canvas.height),e.fillStyle=function(e){const{r:t,g:i,b:n}=bd[e];return`rgb(${t},${i},${n})`}("lead");const i=this.viewport.getBoundingClientRect().height;let n=(t.yOffset||0)+this.contentTop;for(let o of t.names){if(n>i)break;if(n+t.height>0){const i=o,r=Ew(e,i,n,t.height);e.fillText(i,4,r)}n+=t.height}}renderSVGContext(e,{deltaX:t,deltaY:i}){if("function"==typeof this.trackView.track.getSamples){const n=this.trackView.track.getSamples(),o=0,{width:r,height:a}=this.viewport.getBoundingClientRect(),s=`${(this.trackView.track.name||this.trackView.track.id).replace(/\W/g,"")}_sample_names_guid_${xr.guid()}`;e.saveWithTranslationAndClipRect(s,t,i+o,r,a,-o),this.draw({context:e,samples:n}),e.restore()}}addMouseHandlers(){this.addViewportContextMenuHandler(this.viewport)}removeMouseHandlers(){this.removeViewportContextMenuHandler(this.viewport)}addViewportContextMenuHandler(e){this.boundContextMenuHandler=function(e){e.preventDefault(),e.stopPropagation();const t={label:"Name Panel Width",value:this.browser.sampleNameViewportWidth,callback:e=>{this.browser.sampleNameViewportWidth=parseInt(e);for(let{sampleNameViewport:e}of this.browser.trackViews)e.setWidth(this.browser.sampleNameViewportWidth);this.browser.layoutChange()}};this.browser.inputDialog.present(t,e)}.bind(this),e.addEventListener("contextmenu",this.boundContextMenuHandler)}removeViewportContextMenuHandler(e){e.removeEventListener("contextmenu",this.boundContextMenuHandler)}dispose(){this.removeMouseHandlers(),this.viewport.remove()}}function Ew(e,t,i,n){return i+n-function(e,t,i){const{actualBoundingBoxAscent:n,actualBoundingBoxDescent:o}=e.measureText(t);return(i-(n+o))/2}(e,t,n)}const Nw=function(e){this.popover=xr.div({class:"igv-menu-popup"}),e.appendChild(this.popover);const t=xr.div({class:"igv-menu-popup-header"});this.popover.appendChild(t),Ea.attachDialogCloseHandlerWithParent(t,(()=>this.hide())),this.popoverContent=xr.div(),this.popover.appendChild(this.popoverContent),Sa(this.popover,t),t.addEventListener("click",(e=>{e.stopPropagation(),e.preventDefault()})),this.hide()};Nw.prototype.hide=function(){this.popover.style.display="none"},Nw.prototype.presentMenuList=function(e){if(Sw(),e.length>0){this.popoverContent.innerHTML="",e=Ua.trackMenuItemListHelper(e,this);for(let t of e){t.init&&t.init();let i=t.object;0===e.indexOf(t)&&i.removeClass("igv-track-menu-border-top"),i.hasClass("igv-track-menu-border-top")||i.hasClass("igv-menu-popup-check-container")||i.is("div")&&i.addClass("igv-menu-popup-shim"),this.popoverContent.appendChild(i.get(0))}this.popover.style.display="flex";const{width:t}=this.popover.getBoundingClientRect();this.popover.style.left=-t+"px",this.popover.style.top="0px"}},Nw.prototype.presentTrackContextMenu=function(e,t){this.popoverContent.innerHTML="";const i=(n=t,o=this.popover,n.map((e=>{let t;if("string"==typeof e&&"
"===e)t=document.createElement("hr");else if("string"==typeof e)t=xr.div({class:"context-menu"}),t.innerHTML=e;else if("Node"==typeof e)t=e;else{if("function"==typeof e.init&&e.init(),"checkbox"===e.type)t=Va("Show all bases",e.value);else if("color"===e.type){const i=new qa({parent:o.parentElement,width:364});i.configure(void 0,{color:t=>e.click(t)}),t=xr.div({class:"context-menu"}),"string"==typeof e.label&&(t.innerHTML=e.label);const n=e=>{i.show(),xr.hide(o),e.preventDefault(),e.stopPropagation()};t.addEventListener("click",n),t.addEventListener("touchend",n),t.addEventListener("mouseup",(function(e){e.preventDefault(),e.stopPropagation()}))}else t=xr.div({class:"context-menu"}),"string"==typeof e.label&&(t.innerHTML=e.label);if(e.click&&"color"!==e.type){function r(t){e.click(),xr.hide(o),t.preventDefault(),t.stopPropagation()}t.addEventListener("click",r),t.addEventListener("touchend",r),t.addEventListener("mouseup",(function(e){e.preventDefault(),e.stopPropagation()}))}}return{el:t,init:e.init}})));var n,o;for(let{el:e}of i)this.popoverContent.appendChild(e);!function(e,t){t.style.display="flex";const{x:i,y:n}=xr.translateMouseCoordinates(e,t.parentNode),{width:o}=t.getBoundingClientRect(),r=i+o,{width:a}=t.parentNode.getBoundingClientRect();t.style.left=`${r>a?i-(r-a):i}px`,t.style.top=`${n}px`}(e,this.popover)},Nw.prototype.dispose=function(){this.popoverContent.innerHTML="",this.popover.innerHTML="",Object.keys(this).forEach((function(e){this[e]=void 0}))};const Sw=()=>{const e=document.querySelectorAll(".igv-menu-popup");for(let t=0;t0&&this.viewports[0].startSpinner()}stopSpinner(){this.viewports&&this.viewports.length>0&&this.viewports[0].stopSpinner()}addDOMToColumnContainer(e,t,i){this.axis=this.createAxis(e,this.track),this.viewports=[];const n=e.calculateViewportWidth(i.length),o=t.querySelectorAll(".igv-column");for(let e=0;e{e.dataRangeDialog.configure(this),e.dataRangeDialog.present(wr(e.columnContainer))}));const{width:n,height:o}=i.getBoundingClientRect();this.axisCanvas=document.createElement("canvas"),this.axisCanvas.style.width=`${n}px`,this.axisCanvas.style.height=`${o}px`,i.appendChild(this.axisCanvas)}return i}resizeAxisCanvas(e,t){this.axis.style.width=`${e}px`,this.axis.style.height=`${t}px`,"function"==typeof this.track.paintAxis&&(this.axisCanvas.style.width=`${e}px`,this.axisCanvas.style.height=`${t}px`)}removeDOMFromColumnContainer(){this.boundAxisClickHander&&this.removeAxisEventListener(this.axis),this.axis.remove();for(let e of this.viewports)e.$viewport.remove();this.sampleNameViewport.dispose(),this.removeTrackScrollMouseHandlers(),this.outerScroll.remove(),this.removeTrackDragMouseHandlers(),this.dragHandle.remove(),this.removeTrackGearMouseHandlers(),this.gearContainer.remove()}renderSVGContext(e,{deltaX:t,deltaY:i}){!function(e,t,i,n,o){if("function"==typeof t.paintAxis){const{y:r,width:a,height:s}=i.getBoundingClientRect(),c=`${(t.name||t.id).replace(/\W/g,"")}_axis_guid_${xr.guid()}`;e.saveWithTranslationAndClipRect(c,n,r+o,a,s,0),t.paintAxis(e,a,s),e.restore()}}(e,this.track,this.axisCanvas,t,i);const{width:n}=this.axis.getBoundingClientRect(),{y:o}=this.viewports[0].$viewport.get(0).getBoundingClientRect();let r={deltaX:n+t,deltaY:o+i};for(let t of this.viewports){t.renderSVGContext(e,r);const{width:i}=t.$viewport.get(0).getBoundingClientRect();r.deltaX+=i}!0===this.browser.showSampleNames&&this.sampleNameViewport.renderSVGContext(e,r)}dataRange(){return this.track.dataRange?this.track.dataRange:void 0}setDataRange(e,t){void 0!==e&&(this.track.dataRange.min=e),void 0!==t&&(this.track.dataRange.max=t),this.track.autoscale=!1,this.repaintViews()}presentColorPicker(e){if(!1===zw.has(this.track.type)){const t=[],i=this.track.color||this.track.defaultColor;$a(i)&&t.push(i),this.track.altColor&&$a(this.track.altColor)&&t.push(this.track.altColor);const n=t.map((e=>e.startsWith("#")?e:e.startsWith("rgb(")?qh.rgbToHex(e):qh.colorNameToHex(e))),o={color:e=>{this.track.color=e,this.repaintViews()},altColor:e=>{this.track.altColor=e,this.repaintViews()}};this.browser.genericColorPicker.configure(n,o),this.browser.genericColorPicker.setActiveColorHandler(e),this.browser.genericColorPicker.show()}}setTrackHeight(e,t){t||(this.track.minHeight&&(e=Math.max(this.track.minHeight,e)),this.track.maxHeight&&(e=Math.min(this.track.maxHeight,e))),this.track.height=e,this.resizeAxisCanvas(this.axis.clientWidth,this.track.height),"function"==typeof this.track.paintAxis&&this.paintAxis();for(let{$viewport:t}of this.viewports)t.height(e);if(this.sampleNameViewport.viewport.style.height=`${e}px`,"function"!=typeof this.track.computePixelHeight)for(let t of this.viewports)t.setContentHeight(e);this.repaintViews(),!1===Iw.has(this.track.type)&&this.updateScrollbar(),this.dragHandle.style.height=`${e}px`,this.gearContainer.style.height=`${e}px`}updateScrollbar(){const e=this.viewports[0].$viewport.height();this.outerScroll.style.height=`${e}px`;const t=this.maxViewportContentHeight(),i=Math.round(e/t*e);t>e?(this.innerScroll.style.display="block",this.innerScroll.style.height=`${i}px`):this.innerScroll.style.display="none"}moveScroller(e){const t=wr(this.innerScroll).position().top+e,i=Math.min(Math.max(0,t),this.outerScroll.clientHeight-this.innerScroll.clientHeight);wr(this.innerScroll).css("top",`${i}px`);const n=this.maxViewportContentHeight(),o=-Math.round(i*(n/this.viewports[0].$viewport.height()));for(let e of this.viewports)e.setTop(o);this.sampleNameViewport.trackScrollDelta=e,this.sampleNameViewport.setTop(o)}isLoading(){for(let e of this.viewports)if(e.isLoading())return!0}repaintViews(){for(let e of this.viewports)e.isVisible()&&e.repaint();"function"==typeof this.track.paintAxis&&this.paintAxis(),this.repaintSamples()}repaintSamples(){if("function"==typeof this.track.getSamples){const e=this.track.getSamples();this.sampleNameViewport.repaint(e)}}setTrackLabelName(e){this.viewports.forEach((t=>t.setTrackLabel(e)))}resize(e){for(let t of this.viewports)t.setWidth(e)}async updateViews(){if(!this.browser||!this.browser.referenceFrameList)return;const e=this.viewports.filter((e=>e.isVisible()));if(e.forEach((e=>e.shift())),this.browser.dragObject)return;const t=e.filter((e=>e.needsRepaint())).filter((e=>e.checkZoomIn())),i=t.filter((e=>e.needsReload()));for(let e of i)await e.loadFeatures();if(this.disposed)return;if(this.track&&"function"==typeof this.track.variantRowCount&&i.length>0){let e=0;for(let t of this.viewports)t.featureCache&&t.featureCache.features&&(e=Math.max(e,t.featureCache.features.reduce(((e,t)=>Math.max(e,t.row||0)),0)));if(this.track.nVariantRows!==e+1){this.track.variantRowCount(e+1);for(let e of this.viewports)e.checkContentHeight()}}if(this.track.autoscale){let t=[];for(let i of e){const e=i.referenceFrame,n=e.start,o=n+e.toBP(i.getWidth());if(i.featureCache&&i.featureCache.features)if("function"==typeof i.featureCache.features.getMax){const e=i.featureCache.features.getMax(n,o);t.push({value:e})}else{const e=Fd(i.featureCache.features,n,o);for(let i of e)t.push(i)}}"function"==typeof this.track.doAutoscale?this.track.dataRange=this.track.doAutoscale(t):this.track.dataRange=Dd(t)}const n=this.track.autoscale||this.track.autoscaleGroup||"ruler"===this.track.type;for(let i of e)t.includes(i)?i.repaint():n&&i.refresh();this.adjustTrackHeight(),this.repaintSamples(),this.updateRulerViewportLabels()}clearCachedFeatures(){for(let e of this.viewports)e.clearCache()}updateRulerViewportLabels(){const e=this.browser.calculateViewportWidth(this.viewports.length);for(let t of this.viewports)"ruler"===this.track.type&&(this.viewports.length>1?t.presentLocusLabel(e):t.dismissLocusLabel())}async getInViewFeatures(){if(!this.browser||!this.browser.referenceFrameList)return[];let e=[];const t=this.viewports.filter((e=>e.isVisible()));for(let i of t){const t=i.referenceFrame,{chr:n,start:o,bpPerPixel:r}=i.referenceFrame,a=o+t.toBP(i.getWidth());if((!i.featureCache||!i.featureCache.containsRange(n,o,a,r))&&await i.loadFeatures(),i.featureCache&&i.featureCache.features)if("function"==typeof i.featureCache.features.getMax){const t=i.featureCache.features.getMax(o,a);e.push({value:t})}else{const t="function"==typeof i.featureCache.queryFeatures?i.featureCache.queryFeatures(n,o,a):Fd(i.featureCache.features,o,a);e=e.concat(t)}}return e}checkContentHeight(){for(let e of this.viewports)e.checkContentHeight();this.adjustTrackHeight()}adjustTrackHeight(){var e=this.maxViewportContentHeight();if(this.track.autoHeight?this.setTrackHeight(e,!1):this.track.paintAxis&&this.paintAxis(),!1===Iw.has(this.track.type)){const t=this.viewports[0].getContentTop(),i=this.viewports[0].$viewport.height(),n=Math.min(0,i-e);if(t{e.preventDefault(),void 0===t&&e.target.classList.remove("igv-track-drag-handle-hover")})),this.boundTrackDragMouseOutHandler=r.bind(this),this.dragHandle.addEventListener("mouseout",this.boundTrackDragMouseOutHandler)}}removeTrackDragMouseHandlers(){"ideogram"===this.track.id||"ruler"===this.track.id||(this.dragHandle.removeEventListener("mousedown",this.boundTrackDragMouseDownHandler),document.removeEventListener("mouseup",this.boundDocumentTrackDragMouseUpHandler),this.dragHandle.removeEventListener("mouseup",this.boundTrackDragMouseEnterHandler),this.dragHandle.removeEventListener("mouseout",this.boundTrackDragMouseOutHandler))}addTrackGearMouseHandlers(){if(!0===this.track.ignoreTrackMenu);else{function e(e){e.preventDefault(),e.stopPropagation(),this.trackGearPopup.presentMenuList(Ua.trackMenuItemList(this))}this.boundTrackGearClickHandler=e.bind(this),this.gear.addEventListener("click",this.boundTrackGearClickHandler)}}removeTrackGearMouseHandlers(){!0===this.track.ignoreTrackMenu||this.gear.removeEventListener("click",this.boundTrackGearClickHandler)}dispose(){this.removeAxisEventListener(this.axis),this.axis.remove();for(let e of this.viewports)e.dispose();this.sampleNameViewport.dispose(),this.removeTrackScrollMouseHandlers(),this.outerScroll.remove(),this.removeTrackDragMouseHandlers(),this.dragHandle.remove(),this.removeTrackGearMouseHandlers(),this.gearContainer.remove(),"function"==typeof this.track.dispose&&this.track.dispose();for(let e of Object.keys(this))this[e]=void 0;this.alert&&this.alert.container.remove(),this.disposed=!0}paintAxis(){if("function"==typeof this.track.paintAxis){const{width:e,height:t}=this.axisCanvas.getBoundingClientRect(),i=window.devicePixelRatio||1;this.axisCanvas.height=i*t,this.axisCanvas.width=i*e;const n=this.axisCanvas.getContext("2d");n.scale(i,i),this.track.paintAxis(n,e,t)}}maxViewportContentHeight(){return Math.max(this.viewports.map((e=>e.getContentHeight())))}}const Aw="rgb(150, 150, 150)";class Mw extends Tu{static defaults={height:50,flipAxis:!1,logScale:!1,windowFunction:"mean",graphType:"bar",autoscale:!0,normalize:void 0,scaleFactor:void 0};constructor(e,t){super(e,t)}init(e){super.init(e),this.type="wig",this.featureType="numeric",this.paintAxis=pg;const t=e.format?e.format.toLowerCase():e.format;e.featureSource?(this.featureSource=e.featureSource,delete e.featureSource):this.featureSource="bigwig"===t?new im(e,this.browser.genome):"tdf"===t?new sm(e,this.browser.genome):pm(e,this.browser.genome),void 0===e.max||!0===e.autoscale?this.autoscale=!0:this.dataRange={min:e.min||0,max:e.max}}async postInit(){const e=await this.getHeader();this.disposed||e&&this.setTrackProperties(e)}async getFeatures(e,t,i,n){const o=await this.featureSource.getFeatures({chr:e,start:t,end:i,bpPerPixel:n,visibilityWindow:this.visibilityWindow,windowFunction:this.windowFunction});if(this.normalize&&this.featureSource.normalizationFactor){const e=this.featureSource.normalizationFactor;for(let t of o)t.value*=e}if(this.scaleFactor){const e=this.scaleFactor;for(let t of o)t.value*=e}return o}menuItemList(){let e=[];return void 0!==this.flipAxis&&(e.push("
"),e.push({label:"Flip y-axis",click:()=>{this.flipAxis=!this.flipAxis,this.trackView.repaintViews()}})),e=e.concat(Ua.numericDataMenuItems(this.trackView)),e}async getHeader(){return"function"==typeof this.featureSource.getHeader&&(this.header=await this.featureSource.getHeader()),this.header}getScaleFactor(e,t,i,n){return n?i/(Math.log10(t+1)-(e<=0?0:Math.log10(e+1))):i/(t-e)}computeYPixelValue(e,t){return(this.flipAxis?e-this.dataRange.min:this.dataRange.max-e)*t}computeYPixelValueInLogScale(e,t){let i=this.dataRange.max,n=this.dataRange.min;return i<=0?0:(n<=-1&&(n=0),n=n<=0?0:Math.log10(n+1),i=Math.log10(i+1),e=Math.log10(e+1),(this.flipAxis?e-n:i-e)*t)}draw(e){const t=e.features,i=e.context,n=e.bpPerPixel,o=e.bpStart,r=e.pixelWidth;e.pixelHeight;const a=o+r*n+1,s=this.color||Aw;let c;"string"==typeof s&&s.startsWith("rgb(")&&(c=qh.addAlpha(s,.1));const l=this.getScaleFactor(this.dataRange.min,this.dataRange.max,e.pixelHeight,this.logScale),h=e=>this.logScale?this.computeYPixelValueInLogScale(e,l):this.computeYPixelValue(e,l);if(t&&t.length>0&&(void 0===this.dataRange.min&&(this.dataRange.min=0),this.dataRange.max>this.dataRange.min)){let r,s=-1;const l=h(0);for(let e of t){if(e.enda)break;const t=Math.floor((e.start-o)/n);if(isNaN(t))continue;let c=h(e.value);const d=Math.ceil((e.end-o)/n),f=Math.max(1,d-t),u=this.getColorForFeature(e);if("points"===this.graphType){const e=this.config.pointSize||3,n=t+f/2;kd.fillCircle(i,n,c,e/2,{fillStyle:u,strokeStyle:u})}else if("line"===this.graphType)null!=r&&kd.strokeLine(i,s,r,t,c,{fillStyle:u,strokeStyle:u}),kd.strokeLine(i,t,c,t+f,c,{fillStyle:u,strokeStyle:u});else{const e=c-l;kd.fillRect(i,t,l,f,e,{fillStyle:u})}s=t+f,r=c}if(this.dataRange.min<0){const t=this.dataRange.max/(this.dataRange.max-this.dataRange.min)*e.pixelHeight;kd.strokeLine(i,0,t,e.pixelWidth,t,{strokeStyle:c})}}if(this.config.hasOwnProperty("guideLines"))for(let t of this.config.guideLines)if(t.hasOwnProperty("color")&&t.hasOwnProperty("y")&&t.hasOwnProperty("dotted")){let i=h(t.y),n={strokeStyle:t.color,strokeWidth:2};t.dotted?kd.dashedLine(e.context,0,i,e.pixelWidth,i,5,n):kd.strokeLine(e.context,0,i,e.pixelWidth,i,n)}}popupData(e,t){if(void 0===t&&(t=this.clickedFeatures(e)),t&&t.length>0){const i=e.genomicLocation,n=[];t.sort((function(e,t){return Math.abs((e.start+e.end)/2-i)-Math.abs((t.start+t.end)/2-i)}));const o=t.length>10?t.slice(0,10):t;o.sort((function(e,t){return e.start-t.start}));for(let e of o)if(e){n.length>0&&n.push("
");let t=e.end-e.start==1?Za(e.start+1):Za(e.start+1)+"-"+Za(e.end);n.push({name:"Position:",value:t}),n.push({name:"Value:     ",value:Za(e.value)})}return o.length..."),n}return[]}get supportsWholeGenome(){return!this.config.indexURL&&!1!==this.config.supportsWholeGenome}getColorForFeature(e){let t=e.value<0&&this.altColor?this.altColor:this.color||Aw;return"function"==typeof t?t(e.value):t}dispose(){this.trackView=void 0}}function Tw(e){this.thresholds=e.thresholds,this.colors=e.colors}function Rw(e){this.scale=e,this.lowColor="rgb("+e.lowR+","+e.lowG+","+e.lowB+")",this.highColor="rgb("+e.highR+","+e.highG+","+e.highB+")",this.diff=e.high-e.low}Tw.prototype.getColor=function(e){for(let t of this.thresholds)if(e=i.high?this.highColor:(t=(e-i.low)/this.diff,"rgb("+Math.floor(i.lowR+t*(i.highR-i.lowR))+","+Math.floor(i.lowG+t*(i.highG-i.lowG))+","+Math.floor(i.lowB+t*(i.highB-i.lowB))+")")};class Lw{constructor(e){this.color=e}getColor(){return this.color}}class Bw extends Tu{constructor(e,t){super(e,t)}init(e){if(super.init(e),this.type=e.type||"seg","maf"===this.type&&(this.type="mut"),this.isLog=e.isLog,this.displayMode=e.displayMode||"EXPANDED",this.height=e.height||300,this.maxHeight=e.maxHeight||500,this.squishedRowHeight=e.sampleSquishHeight||e.squishedRowHeight||2,this.expandedRowHeight=e.sampleExpandHeight||e.expandedRowHeight||13,this.sampleHeight=this.squishedRowHeight,e.color?this.color=e.color:(this.posColorScale=e.posColorScale||new Rw({low:.1,lowR:255,lowG:255,lowB:255,high:1.5,highR:255,highG:0,highB:0}),this.negColorScale=e.negColorScale||new Rw({low:-1.5,lowR:0,lowG:0,lowB:255,high:-.1,highR:255,highG:255,highB:255}),"mut"===this.type&&(this.colorTable=new _d(e.colorTable||Hw))),this.sampleKeys=[],this.sampleNames=new Map,e.samples){for(let t of e.samples)this.sampleKeys.push(t),this.sampleNames.set(t,t);this.explicitSamples=!0}const t=Object.assign({},this.config);t.maxWGCount=t.maxWGCount||Number.MAX_SAFE_INTEGER,this.featureSource=pm(t,this.browser.genome),this.initialSort=e.sort}async postInit(){"function"==typeof this.featureSource.getHeader&&(this.header=await this.featureSource.getHeader(),this.disposed)||this.header&&this.setTrackProperties(this.header)}menuItemList(){const e=[],t={SQUISHED:"Squish",EXPANDED:"Expand",FILL:"Fill"};e.push("
"),e.push("DisplayMode:");const i="seg"===this.type?["SQUISHED","EXPANDED","FILL"]:["SQUISHED","EXPANDED"];for(let n of i){const i=Va(t[n],n===this.displayMode);e.push({object:wr(i),click:()=>{this.displayMode=n,this.config.displayMode=n,this.trackView.checkContentHeight(),this.trackView.repaintViews(),this.trackView.moveScroller(this.trackView.sampleNameViewport.trackScrollDelta)}})}return e}hasSamples(){return!0}getSamples(){return{names:this.sampleKeys.map((e=>this.sampleNames.get(e))),height:this.sampleHeight,yOffset:0}}async getFeatures(e,t,i){const n=await this.featureSource.getFeatures({chr:e,start:t,end:i});if(this.initialSort){const e=this.initialSort;this.sortSamples(e.chr,e.start,e.end,e.direction,n),this.initialSort=void 0}return n}draw({context:e,renderSVG:t,pixelTop:i,pixelWidth:n,pixelHeight:o,features:r,bpPerPixel:a,bpStart:s}){if(kd.fillRect(e,0,i,n,o,{fillStyle:"rgb(255, 255, 255)"}),r&&r.length>0){this.checkForLog(r),this.updateSampleKeys(r);const t={};let c;switch(this.sampleKeys.forEach((function(e,i){t[e]=i})),this.displayMode){case"FILL":this.sampleHeight=o/this.sampleKeys.length,c=0;break;case"SQUISHED":this.sampleHeight=this.squishedRowHeight,c=0;break;default:this.sampleHeight=this.expandedRowHeight,c=1}const l=this.sampleHeight;for(let e of r)e.pixelRect=void 0;const h=i+o,d=s+n*a+1,f=a;this.sampleYStart=void 0;for(let n of r){if(n.endd)break;const o=n.sampleKey||n.sample;n.row=t[o];const r=n.row*l+c;void 0===this.sampleYStart&&(this.sampleYStart=r);if(r+lh)continue;const a=Math.max(n.start,s);let u=Math.round((a-s)/f);const p=Math.min(n.end,d),m=Math.round((p-s)/f);let g,w,F=Math.max(1,m-u);if(this.color?g="function"==typeof this.color?this.color(n):this.color:this.colorTable&&(g=this.colorTable.getColor(n.value.toLowerCase())),"mut"===this.type)w=l-2*c,F<3&&(F=3,u-=1);else{let e=n.value;this.isLog||(e=Hh(e/2)),g=e<-.1?this.negColorScale.getColor(e):e>.1?this.posColorScale.getColor(e):"white";let t=l;if(l<.25){const i=.1+2*Math.abs(e);t=Math.min(1,i*l)}w=t-2*c}n.pixelRect={x:u,y:r,w:F,h:w},e.fillStyle=g,e.fillRect(u,r,F,w)}}}checkForLog(e){if(void 0===this.isLog){this.isLog=!1;for(let t of e)if(t.value<0)return void(this.isLog=!0)}}computePixelHeight(e){if(!e)return 0;const t="SQUISHED"===this.displayMode?this.squishedRowHeight:this.expandedRowHeight;return this.updateSampleKeys(e),this.sampleKeys.length*t}async sortSamples(e,t,i,n,o){if(o||(o=await this.featureSource.getFeatures({chr:e,start:t,end:i})),!o)return;this.updateSampleKeys(o);const r={},a="ASC"===n?1:-1,s=()=>{const e=i-t+1;for(let n of o){if(n.endi)break;const o=Math.max(t,n.start),a=(Math.min(i,n.end)-o)/e,s=n.sampleKey||n.sample,c=r[s]||0;r[s]=c+a*n.value}this.sampleKeys.sort((function(e,t){let i=r[e],n=r[t];return i||(i=a*Number.MAX_VALUE),n||(n=a*Number.MAX_VALUE),i===n?0:i>n?a:-1*a}))},c=()=>{for(let e of o){if(e.endi)break;const n=e.sampleKey||e.sample;(!r.hasOwnProperty(n)||e.value.localeCompare(r[n])>0)&&(r[n]=e.value)}this.sampleKeys.sort((function(e,t){let i=r[e]||"",n=r[t]||"";return a*i.localeCompare(n)}))};"mut"===this.type?c():s(),this.trackView.repaintViews()}clickedFeatures(e){const t=super.clickedFeatures(e),i=e.y;return t.filter((function(e){const t=e.pixelRect;return t&&i>=t.y&&i<=t.y+t.h}))}hoverText(e){const t=this.clickedFeatures(e);if(t&&t.length>0)return`${t[0].sample}: ${t[0].value}`}popupData(e,t){void 0===t&&(t=this.clickedFeatures(e));const i=[];for(let e of t){i.length>0&&(i.push("
"),i.push("
"));const t=e._f||e,n="function"==typeof t.popupData?t.popupData(this.type,this.browser.genome.id):this.extractPopupData(t);Array.prototype.push.apply(i,n)}return i}contextMenuItemList(e){const t=e.viewport.referenceFrame,i=e.genomicLocation,n=this.config.sort?"ASC"===this.config.sort.direction?"DESC":"ASC":"DESC",o=t.toBP(2.5),r=t=>{const i=e.viewport.cachedFeatures;this.sortSamples(t.chr,t.start,t.end,t.direction,i)};return[{label:"seg"===this.type?"Sort by value":"Sort by type",click:t=>{const a={direction:n,chr:e.viewport.referenceFrame.chr,start:i-o,end:i+o};r(a),this.config.sort=a}}]}get supportsWholeGenome(){return(!1===this.config.indexed||!this.config.indexURL)&&!1!==this.config.supportsWholeGenome}updateSampleKeys(e){if(!this.explicitSamples)for(let t of e){const e=t.sampleKey||t.sample;this.sampleNames.has(e)||(this.sampleNames.set(e,t.sample),this.sampleKeys.push(e))}}}const Hw={indel:"rgb(0,200,0)","targeted region":"rgb(236,155,43)",truncating:"rgb(\t150,0,0)","non-coding transcript":"rgb(0,0,150)",synonymous:"rgb(109,165,95)",silent:"rgb(109,135,80)",missense_mutation:"rgb(72,130,187)",missense:"rgb(72,130,187)","splice site":"rgb(143,83,155)",splice_region:"rgb(143,83,155)",nonsense:"rgb(216, 57,81)",nonsense_mutation:"rgb(216, 57,81)",frame_shift_del:"rgb(226,135,65)",frame_shift_ins:"rgb(226,135,65)",in_frame_del:"rgb(247,235,94)",in_frame_ins:"rgb(247,235,94)","*other*":"rgb(159,91,50)"};class Ow extends Tu{constructor(e,t){super(e,t),this.type="merged",this.featureType="numeric",this.paintAxis=pg,this.graphType=e.graphType}init(e){if(!e.tracks)throw Error("Error: no tracks defined for merged track"+e);super.init(e)}async postInit(){this.tracks=[];const e=[];for(let t of this.config.tracks){t.isMergedTrack=!0;const i=await this.browser.createTrack(t);i?(i.autoscale=!1,this.tracks.push(i)):console.warn("Could not create track "+t),"function"==typeof i.postInit&&e.push(i.postInit())}this.flipAxis=!!this.config.flipAxis&&this.config.flipAxis,this.logScale=!!this.config.logScale&&this.config.logScale,this.autoscale=this.config.autoscale||void 0===this.config.max,this.autoscale||(this.dataRange={min:this.config.min||0,max:this.config.max});for(let e of this.tracks)e.autoscale=!1,e.dataRange=this.dataRange;return this.height=this.config.height||50,Promise.all(e)}get height(){return this._height}set height(e){if(this._height=e,this.tracks)for(let t of this.tracks)t.height=e,t.config.height=e}menuItemList(){let e=[];return void 0!==this.flipAxis&&e.push({label:"Flip y-axis",click:()=>{this.flipAxis=!this.flipAxis,this.trackView.repaintViews()}}),e=e.concat(Ua.numericDataMenuItems(this.trackView)),e}async getFeatures(e,t,i,n){const o=this.tracks.map((o=>o.getFeatures(e,t,i,n))),r=await Promise.all(o);return new Pw(r)}draw(e){const t=e.features;for(let i=0,n=this.tracks.length;i0&&i.push("
"),i.push(`
${this.tracks[n].name}
`);const o=this.tracks[n].popupData(e,t[n]);i.push(...o)}return i}}}clickedFeatures(e){const t=e.viewport.cachedFeatures;if(!t)return[];const i=e.genomicLocation,n=[];for(let o of t.featureArrays){const t=e.referenceFrame.bpPerPixel>.2?3*e.referenceFrame.bpPerPixel:.2,r=Fd(o,i-t,i+t);for(let e of r)n.push(e)}return n}get supportsWholeGenome(){return this.tracks.every((e=>e.supportsWholeGenome))}}class Pw{constructor(e){this.featureArrays=e}getMax(e,t){let i=-Number.MAX_VALUE;for(let n of this.featureArrays)for(let o of n)if(void 0!==o.value&&!Number.isNaN(o.value)){if(o.endt)break;i=Math.max(i,o.value)}return i}}class qw extends Tu{static defaults={height:250,theta:Math.PI/4,arcOrientation:!0,showBlocks:!0,blockHeight:3,thickness:1,alpha:.02,logScale:!0};constructor(e,t){super(e,t)}init(e){super.init(e),this.sinTheta=Math.sin(this.theta),this.cosTheta=Math.cos(this.theta),this.arcType=function(e){if(!e.arcType)return"nested";switch(e.arcType){case"chiapet":return"inView";case"chiapetoutbound":return"partialInView";default:return e.arcType}}(e),this.alpha=e.alpha||.02,this.painter={flipAxis:!this.arcOrientation,dataRange:this.dataRange,paintAxis:pg},e.valueColumn?(this.valueColumn=e.valueColumn,this.hasValue=!0):e.useScore&&(this.hasValue=!0,this.valueColumn="score"),e.max?(this.dataRange={min:e.min||0,max:e.max},this.autoscale=!1):this.autoscale=!0,e.featureSource?(this.featureSource=e.featureSource,delete e._featureSource):(this.featureSource=pm(e,this.browser.genome),this.featureSource.getWGFeatures=Gw)}async postInit(){if("function"!=typeof this.featureSource.getHeader||(this.header=await this.featureSource.getHeader(),!this.disposed))return this.header&&this.setTrackProperties(this.header),void 0===this.visibilityWindow&&"function"==typeof this.featureSource.defaultVisibilityWindow&&(this.visibilityWindow=await this.featureSource.defaultVisibilityWindow(),this.featureSource.visibilityWindow=this.visibilityWindow),this}get supportsWholeGenome(){return!0}async getFeatures(e,t,i){const n=this.visibilityWindow,o=await this.featureSource.getFeatures({chr:e,start:t,end:i,visibilityWindow:n});return void 0===this.hasValue&&o&&o.length>0&&(this.hasValue=void 0!==o[0].score),o}draw(e){"proportional"===this.arcType||"inView"===this.arcType||"partialInView"===this.arcType?this.drawProportional(e):this.drawNested(e)}drawNested(e){const t=e.context,i=e.pixelWidth,n=e.pixelHeight,o=e.viewportWidth,r=e.bpPerPixel,a=e.bpStart,s=r;kd.fillRect(t,0,e.pixelTop,i,n,{fillStyle:"rgb(255, 255, 255)"});const c=e.features;if(c){(function(){let e=0;for(let t of c){let n=(t.start-a)/s,o=(t.end-a)/s;n>=0&&o<=i&&(e=Math.max(e,o-n))}let t=Math.min(o,e)/2;if(e>0){let e=(n-10)/t;this.theta=function(e){let t,i=[.01570925532366355,.15838444032453644,.3249196962329063,.5095254494944288,.7265425280053609,.9999999999999999],n=[.031415926535897934,.3141592653589793,.6283185307179586,.9424777960769379,1.2566370614359172,1.5707963267948966];for(t=0;te);t++);let o=0===t?0:i[t-1],r=ti)continue;let u=f-d;u<3&&(u=3,d--);const p=u/2,m=p/this.sinTheta,g=this.cosTheta*m,w=d+p;let F,b,v;if(h?(F=this.height+g,b=Math.PI+Math.PI/2-this.theta,v=Math.PI+Math.PI/2+this.theta):(F=-g,b=Math.PI/2-this.theta,v=Math.PI/2+this.theta),this.showBlocks&&"all"!==e.chr){const i=(e.start1-a)/s,n=(e.end1-a)/s,o=(e.start2-a)/s,c=(e.end2-a)/s,l=this.arcOrientation?-this.blockHeight:this.blockHeight;t.fillRect(i,r,n-i,l),t.fillRect(o,r,c-o,l)}n&&!this.config.useScore&&u>o&&(n=Ww(n,this.alpha)),t.strokeStyle=n,t.fillStyle=n,t.beginPath(),t.arc(w,F,m,b,v,!1),t.stroke(),e.drawState={xc:w,yc:F,r:m}}else{let o=Math.round((e.start-a)/s),r=Math.round((e.end-a)/s);if(r<0||o>i)continue;let c=r-o;c<3&&(c=3,o--);const l=e.chr===e.chr1?e.chr2:e.chr1;t.strokeStyle=n,t.fillStyle=Ww(ww(l),.5),h?(t.fillRect(o,this.height/2,c,this.height/2),t.fillText(l,o+c/2,this.height/2-5),e.drawState={x:o,y:this.height/2,w:c,h:this.height/2}):(t.fillRect(o,0,c,this.height/2),t.fillText(l,o+c/2,this.height/2+13),e.drawState={x:o,y:0,w:c,h:this.height/2})}}}var l}getScaleFactor(e,t,i,n){return n?i/(Math.log10(t+1)-(e<=0?0:Math.log10(e+1))):i/(t-e)}drawProportional(e){const t=e.context,i=e.pixelWidth,n=e.pixelHeight,o=e.bpPerPixel,r=e.bpStart,a=o,s=e.referenceFrame.start,c=e.referenceFrame.end;kd.fillRect(t,0,e.pixelTop,i,n,{fillStyle:"rgb(255, 255, 255)"});const l=e.features;if(l&&l.length>0){const n=0,o=this.getScaleFactor(n,this.dataRange.max,e.pixelHeight-1,this.logScale),h=this.arcOrientation?e.pixelHeight:0;for(let e of l){e.drawState=void 0;const n=this.valueColumn?e[this.valueColumn]:e.score;if(void 0===n||Number.isNaN(n))continue;const l=Math.round((this.logScale?Math.log10(n+1):n)*o);if(e.chr1===e.chr2||"all"===e.chr){const{m1:i,m2:o}=Vw(e,this.browser.genome);let d=Math.round((i-r)/a),f=Math.round((o-r)/a)-d;if(f<3&&(f=3,d--),nthis.dataRange.max)continue;if("proportional"!==this.arcType){const e="partialInView"===this.arcType,t=i>=s&&o<=c;let n=!1,r=!1;if(!t&&e&&(n=s<=i&&i<=c,n||(r=s<=o&&o<=c)),!(t||n||r))continue}const u=f/2,p=d+f/2;e.drawState={xc:p,yc:h,radiusX:u,radiusY:l};const m=!!this.arcOrientation,g=e.color||this.color;if(t.strokeStyle=g,t.lineWidth=e.thickness||this.thickness||1,!0===t.isSVG?t.strokeEllipse(p,h,u,l,0,0,Math.PI,m):(t.beginPath(),t.ellipse(p,h,u,l,0,0,Math.PI,m),t.stroke()),this.alpha&&(t.fillStyle=Ww(g,this.alpha),!0===t.isSVG?t.fillEllipse(p,h,u,l,0,0,Math.PI,m):t.fill()),this.showBlocks&&"all"!==e.chr){t.fillStyle=g;const i=(e.start1-r)/a,n=(e.end1-r)/a,o=(e.start2-r)/a,s=(e.end2-r)/a,c=this.arcOrientation?-this.blockHeight:this.blockHeight;t.fillRect(i,h,n-i,c),t.fillRect(o,h,s-o,c)}}else{let o=Math.round((e.start-r)/a),s=Math.round((e.end-r)/a);if(s<0||o>i||nthis.dataRange.max)continue;const c=Math.min(l,this.height-13);let h=s-o;h<3&&(h=3,o--);const d=e.chr===e.chr1?e.chr2:e.chr1;if(t.font="8px sans-serif",t.textAlign="center",t.fillStyle=Ww(ww(d),.5),this.arcOrientation){const i=this.height-c;t.fillRect(o,i,h,c),t.fillText(d,o+h/2,i-5),e.drawState={x:o,y:i,w:h,h:c}}else t.fillRect(o,0,h,c),t.fillText(d,o+h/2,c+13),e.drawState={x:o,y:0,w:h,h:c}}}}}clearAxis(e,t,i){kd.fillRect(e,0,0,t,i,{fillStyle:"rgb(255, 255, 255)"})}paintAxis(e,t,i){const n={min:0,max:this.dataRange.max};"proportional"===this.arcType||"inView"===this.arcType||"partialInView"===this.arcType?(this.painter.flipAxis=!this.arcOrientation,this.painter.dataRange=n,this.painter.paintAxis(e,t,i)):this.clearAxis(e,t,i)}menuItemList(){let e=[];if(this.hasValue){e.push("
");const t={nested:"Nested",proportional:"Proportional - All",inView:"Proportional - Both Ends in View",partialInView:"Proportional - One End in View"};e.push("Arc Type");for(let i of["nested","proportional","inView","partialInView"])e.push({object:wr(Va(t[i],i===this.arcType)),click:()=>{this.arcType=i,this.trackView.repaintViews()}})}return e.push("
"),e.push({name:"Toggle arc direction",click:()=>{this.arcOrientation=!this.arcOrientation,this.trackView.repaintViews()}}),e.push({name:this.showBlocks?"Hide Blocks":"Show Blocks",click:()=>{this.showBlocks=!this.showBlocks,this.trackView.repaintViews()}}),"proportional"!==this.arcType&&"inView"!==this.arcType&&"partialInView"!==this.arcType||(e=e.concat(Ua.numericDataMenuItems(this.trackView))),this.browser.circularView&&(e.push("
"),e.push({label:"Add interactions to circular view",click:()=>{for(let e of this.trackView.viewports)this.addChordsForViewport(e.referenceFrame)}})),e}contextMenuItemList(e){if(this.browser.circularView){const t=e.viewport,i=[];return i.push({label:"Add interactions to circular view",click:()=>{const e=t.referenceFrame;this.addChordsForViewport(e)}}),i.push("
"),i}}addChordsForViewport(e){const t=("all"===e.chr?this.featureSource.getAllFeatures():this.featureSource.featureCache.queryFeatures(e.chr,e.start,e.end)).filter((e=>e.drawState));if(0===t.length)return;Wg(t.map((e=>{const t=e._f||e;return{uniqueId:`${t.chr1}:${t.start1}-${t.end1}_${t.chr2}:${t.start2}-${t.end2}`,refName:Ug(t.chr1),start:t.start1,end:t.end1,mate:{refName:Ug(t.chr2),start:t.start2,end:t.end2}}})),this,e,.5)}doAutoscale(e){let t=0;if(e)for(let i of e){const e=this.valueColumn?i[this.valueColumn]:i.score;Number.isNaN(e)||(t=Math.max(t,e))}return{min:0,max:t}}popupData(e,t){void 0===t&&(t=this.clickedFeatures(e));const i=[];for(let e of t){const t=e._||e;if(i.push({name:"Region 1",value:Uw(t.chr1,t.start1,t.end1,t.strand1)}),i.push({name:"Region 2",value:Uw(t.chr2,t.start2,t.end2,t.strand2)}),t.name&&i.push({name:"Name",value:t.name}),void 0!==t.value&&i.push({name:"Value",value:t.value}),void 0!==t.score&&i.push({name:"Score",value:t.score}),t.extras&&this.header&&this.header.columnNames){const e=this.header.columnNames,n=this.header.hiccups?6:10;for(let o=n;o=t-s&&e.canvasX<=t+r+s&&e.canvasY>=n&&e.canvasY<=n+a){const n=-Math.abs(e.canvasX-(t+r/2));i.push({score:n,feature:o});break}}}return i.length>1&&i.sort(((e,t)=>e.score-t.score)),i.map((e=>e.feature))}}function Vw(e,t){let i=(e.start1+e.end1)/2,n=(e.start2+e.end2)/2;if("all"===e.chr&&(i=t.getGenomeCoordinate(e.chr1,i),n=t.getGenomeCoordinate(e.chr2,n)),i>n){const e=i;i=n,n=e}return{m1:i,m2:n}}function Uw(e,t,i,n){return n&&"."!==n?`${e}:${Za(t+1)}-${Za(i)} (${n})`:`${e}:${Za(t+1)}-${Za(i)}`}const jw=new Map;function Ww(e,t){const i=`${e}_${t}`;let n=jw.get(i);return n||(n=qh.addAlpha(e,t),jw.set(i,n)),n}function Gw(e){const t=e=>{const t=Object.assign({},e);return t.chr="all",t.start=i.getGenomeCoordinate(e.chr1,e.start1),t.end=i.getGenomeCoordinate(e.chr2,e.end2),t},i=this.genome;let n,o=0;for(let t of i.wgChromosomeNames){let i=e[t];if(i)for(let e of i)e.dup||(o++,e.score&&(!n||e.score>n.score)&&(n=e))}const r=this.maxWGCount,a=n&&n.score>0&&o>r?5:1,s=Math.floor(r/a),c=n&&n.score>0?Math.log(n.score)/a:Number.MAX_SAFE_INTEGER;let l,h=[],d=[];for(let e=0;ee.name)):[]}return this.header}getCallsetsLength(){return this.callSets?this.callSets.length:0}async getFeatures(e,t,i,n){return void 0===this.header&&(this.header=await this.getHeader()),this.featureSource.getFeatures({chr:e,start:t,end:i,bpPerPixel:n,visibilityWindow:this.visibilityWindow})}hasSamples(){return this.getCallsetsLength()>0}getSamples(){return{yOffset:this.sampleYOffset,names:this.sampleNames,height:this.sampleHeight}}computePixelHeight(e){if(!e||0==e.length)return 10;const t="COLLAPSED"===this.displayMode?1:this.nVariantRows,i="SQUISHED"===this.displayMode?this.squishedVGap:this.expandedVGap,n="SQUISHED"===this.displayMode?this.squishedVariantHeight:this.expandedVariantHeight,o="SQUISHED"===this.displayMode?this.squishedCallHeight:this.expandedCallHeight;return 10+t*(n+i)+i+((!1===this.showGenotypes?0:this.getCallsetsLength()*t)+1)*(o+i)}variantRowCount(e){this.nVariantRows=e}draw({context:e,pixelWidth:t,pixelHeight:i,bpPerPixel:n,bpStart:o,pixelTop:r,features:a}){kd.fillRect(e,0,r,t,i,{fillStyle:"rgb(255, 255, 255)"});const s="SQUISHED"===this.displayMode?this.squishedVGap:this.expandedVGap,c="COLLAPSED"===this.displayMode?1:this.nVariantRows,l="SQUISHED"===this.displayMode?this.squishedVariantHeight:this.expandedVariantHeight;this.variantBandHeight=10+c*(l+s);let h=this.callSets;!h&&this._f&&(h=this._f.callSets);const d=this.getCallsetsLength();if(h&&d>0&&!1!==this.showGenotypes&&kd.strokeLine(e,0,this.variantBandHeight,t,this.variantBandHeight,{strokeStyle:"rgb(224,224,224) "}),a){const i="SQUISHED"===this.displayMode?this.squishedCallHeight:this.expandedCallHeight,r="SQUISHED"===this.displayMode?this.squishedVGap:this.expandedVGap,s=o+t*n+1;for(let t of a){if(t.ends)break;const a="SQUISHED"===this.displayMode?this.squishedVariantHeight:this.expandedVariantHeight,c=10+("COLLAPSED"===this.displayMode?0:t.row*(a+r)),l=a;let f=Math.round((t.start-o)/n),u=Math.round((t.end-o)/n),p=Math.max(1,u-f);p<3?(p=3,f-=1):p>5&&(f+=1,p-=2),e.fillStyle=this.getColorForFeature(t),e.fillRect(f,c,p,l);let m=this.getVariantStrokecolor(t);if(m&&(e.strokeStyle=m,e.strokeRect(f,c,p,l)),this.callContextHook(t,e,f,c,p,l),t.pixelRect={x:f,y:c,w:p,h:l},d>0&&!1!==this.showGenotypes){const n="COLLAPSED"===this.displayMode?1:this.nVariantRows;this.sampleYOffset=this.variantBandHeight+r,this.sampleHeight=n*(i+r);let o=0;if(h&&t.calls)for(let n of h){const a=t.calls[n.id];if(a){const s="COLLAPSED"===this.displayMode?0:t.row,c=this.sampleYOffset+o*this.sampleHeight+s*(i+r);let l=!0,h=!0,d=!1;if(a.genotype)for(let e of a.genotype){if("."===e){d=!0;break}0!==e&&(h=!1),0===e&&(l=!1)}a.genotype?e.fillStyle=d?this.noCallColor:h?this.homrefColor:l?this.homvarColor:this.hetvarColor:e.fillStyle=this.noGenotypeColor,e.fillRect(f,c,p,i),n.pixelRect={x:f,y:c,w:p,h:i}}o++}}}}else console.log("No feature list")}getColorForFeature(e){const t=e._f||e;let i;if(this.colorBy){const e=this.colorBy;let n;if(t.info.hasOwnProperty(e))n=t.info[e];else if(Kw.has(e)){n=t[Kw.get(e)]}i=this.getVariantColorTable(e).getColor(n),i||(i="gray")}else i=this._color?"function"==typeof this._color?this._color(e):this._color:"NONVARIANT"===t.type?this.nonRefColor:"MIXED"===t.type?this.mixedColor:this.color;return i}getVariantStrokecolor(e){const t=e._f||e;let i;return i=this._strokecolor?"function"==typeof this._strokecolor?this._strokecolor(t):this._strokecolor:void 0,i}callContextHook(e,t,i,n,o,r){if(this._context_hook&&"function"==typeof this._context_hook){const a=e._f||e;t.save(),this._context_hook(a,t,i,n,o,r),t.restore()}}clickedFeatures(e){let t=super.clickedFeatures(e);const i="EXPANDED"===this.displayMode?this.expandedVGap:this.squishedVGap,n=i+("SQUISHED"===this.displayMode?this.squishedCallHeight:this.expandedCallHeight),o=e.y;if(o<=this.variantBandHeight){const e="SQUISHED"===this.displayMode?this.squishedVariantHeight:this.expandedVariantHeight,n=Math.floor((o-10)/(e+i));"COLLAPSED"!==this.displayMode&&(t=t.filter((e=>e.row===n)))}else if(this.callSets){const e=this.callSets,i=o-this.variantBandHeight,r=Math.floor(i/this.sampleHeight);if(r>=0&&re.row===o)),s=e[r];t=a.map((e=>{const t=e.calls[s.id];return function(e,t){if(e.genotype){let i="";if("."===t.alternateBases)i="No Call";else{const n=t.alternateBases.split(",");for(let o of e.genotype)if(i.length>0&&(i+="|"),"."===o)i+=".";else if(0===o)i+=t.referenceBases;else{i+=n[o-1].replace("<","<")}}e.genotypeName=i}}(t,e),t}))}}return t}popupData(e,t){void 0===t&&(t=this.clickedFeatures(e));const i=e.genomicLocation,n=this.browser.genome.id,o=this.browser.sampleInformation;let r=[];for(let e of t){const t=e._f||e;if(r.length>0&&r.push({html:'
'}),"function"==typeof t.popupData){const e=t.popupData(i,n);Array.prototype.push.apply(r,e)}else{const e=t;if(void 0!==e.callSetName&&r.push({name:"Name",value:e.callSetName}),e.genotypeName&&r.push({name:"Genotype",value:e.genotypeName}),void 0!==e.phaseset&&r.push({name:"Phase set",value:e.phaseset}),void 0!==e.genotypeLikelihood&&r.push({name:"genotypeLikelihood",value:e.genotypeLikelihood.toString()}),o){var a=o.getAttributes(e.callSetName);a&&Object.keys(a).forEach((function(e){var t=e.replace(/([A-Z])/g," $1");t=t.charAt(0).toUpperCase()+t.slice(1),r.push({name:t,value:a[e]})}))}var s=Object.keys(e.info);s.length&&r.push("
"),s.forEach((function(t){r.push({name:t,value:decodeURIComponent(e.info[t])})}))}}return r}menuItemList(){const e=[];if(this.header.INFO&&this.header.INFO){const t=this.header.INFO.SVTYPE?["SVTYPE"]:[];if(this._initColorBy&&"SVTYPE"!==this._initColorBy&&t.push(this._initColorBy),t.length>0){e.push("
");const i=wr('
');i.text("Color by:"),e.push({name:void 0,object:i,click:void 0,init:void 0}),t.sort();for(let i of t){const t=this.colorBy===i,n=i||"None";e.push(this.colorByCB({key:i,label:n},t))}e.push(this.colorByCB({key:void 0,label:"None"},void 0===this.colorBy)),e.push("
")}}this.getCallsetsLength()>0&&(e.push({object:wr('
')}),e.push({object:wr(Va("Show Genotypes",this.showGenotypes)),click:()=>{this.showGenotypes=!this.showGenotypes,this.trackView.checkContentHeight(),this.trackView.repaintViews()}})),e.push({object:wr('
')});for(let t of["COLLAPSED","SQUISHED","EXPANDED"]){e.push({object:wr(Va({COLLAPSED:"Collapse",SQUISHED:"Squish",EXPANDED:"Expand"}[t],t===this.displayMode)),click:()=>{this.displayMode=t,this.trackView.checkContentHeight(),this.trackView.repaintViews()}})}return this.browser.circularView&&(e.push("
"),e.push({label:"Add SVs to circular view",click:()=>{for(let e of this.trackView.viewports)this.sendChordsForViewport(e)}})),e}contextMenuItemList(e){if(this.browser.circularView){const t=e.viewport,i=[];return i.push({label:"Add SVs to Circular View",click:()=>{this.sendChordsForViewport(t)}}),i.push("
"),i}}sendChordsForViewport(e){const t=e.referenceFrame;let i;if("all"===t.chr){const e=this.featureSource.getAllFeatures(),t=Object.keys(e).map((t=>e[t]));i=[].concat(...t)}else i=this.featureSource.featureCache.queryFeatures(t.chr,t.start,t.end);Wg(i.filter((e=>{const t=e._f||e;return t.info&&t.info.CHR2&&t.info.END&&(t.info.CHR2!==t.chr||Math.abs(Number.parseInt(t.info.END)-t.pos)>1e6)})).map((e=>{const t=e._f||e,i=Number.parseInt(t.info.END),n=i-100,o=i+100;return{uniqueId:`${t.chr}:${t.start}-${t.end}_${t.info.CHR2}:${t.info.END}`,refName:Ug(t.chr),start:t.start,end:t.end,mate:{refName:Ug(t.info.CHR2),start:n,end:o}}})),this,t,.5)}colorByCB(e,t){return{name:void 0,object:wr(Va(e.label,t)),click:()=>{e.key===this.colorBy?(this.colorBy=void 0,delete this.config.colorBy,this.trackView.repaintViews()):(this.colorBy=e.key,this.config.colorBy=e.key,this.trackView.repaintViews())},init:void 0}}getState(){const e=super.getState();return this._color&&"function"!=typeof this._color&&(e.color=this._color),e}getVariantColorTable(e){if(this.colorTables||(this.colorTables=new Map),!this.colorTables.has(e)){let t;if("SVTYPE"===e)t=Yw;else t=new yd("Set1");this.colorTables.set(e,t)}return this.colorTables.get(e)}}const Yw=new _d({DEL:"#ff2101",INS:"#001888",DUP:"#028401",INV:"#008688",CNV:"#8931ff",BND:"#891100","*":"#002eff"});class Qw extends Tu{constructor(e,t){super(e,t)}init(e){super.init(e),this.name=e.name,this.pValueField=e.pValueField||"pValue",this.geneField=e.geneField||"geneSymbol",this.snpField=e.snpField||"snp";const t=e.minLogP||e.min,i=e.maxLogP||e.max;this.dataRange={min:t||3.5,max:i||25},this.autoscale=!i||e.autoscale,this.autoscalePercentile=void 0===e.autoscalePercentile?98:e.autoscalePercentile,this.background=e.background,this.divider=e.divider||"rgb(225,225,225)",this.dotSize=e.dotSize||2,this.height=e.height||100,this.autoHeight=!1,this.disableButtons=e.disableButtons,this.visibilityWindow=void 0===e.visibilityWindow?2e6:e.visibilityWindow>=0?Math.min(2e6,e.visibilityWindow):2e6,this.featureSource=pm(e,this.browser.genome),Zg.gtexLoaded=!0}paintAxis(e,t,i){const n=(this.dataRange.max-this.dataRange.min)/i,o={font:"normal 10px Arial",textAlign:"right",strokeStyle:"black"};kd.fillRect(e,0,0,t,i,{fillStyle:"rgb(255, 255, 255)"});const r=Math.ceil(10*(this.dataRange.max-this.dataRange.min)/i);for(let a=4;a<=this.dataRange.max;a+=r){const r=.85*t,s=r-5,c=r,l=i-(a-this.dataRange.min)/n;kd.strokeLine(e,s,l,c,l,o),l>8&&kd.fillText(e,a,s-1,l+2,o)}o.textAlign="center",kd.fillText(e,"-log10(pvalue)",t/4,i/2,o,{rotate:{angle:-90}})}async getFeatures(e,t,i){const n=this.pValueField,o=this.visibilityWindow,r=await this.featureSource.getFeatures({chr:e,start:t,end:i,visibilityWindow:o});return r.forEach((function(e){e.value=e[n]})),r}draw(e){const t=e.context,i=e.pixelWidth,n=e.pixelHeight;this.background&&kd.fillRect(t,0,0,i,n,{fillStyle:this.background}),kd.strokeLine(t,0,n-1,i,n-1,{strokeStyle:this.divider});const o=o=>{const r=o?2*this.dotSize:this.dotSize,a=e.bpStart,s=(this.dataRange.max-this.dataRange.min)/n,c=e.referenceFrame.selection;for(let h of e.features){const d=(h.start-a+.5)/e.bpPerPixel;if(d<0)continue;if(d>i)break;const f=h.snp.toUpperCase(),u=h[this.geneField].toUpperCase(),p=c&&(c.snp===f||c.gene===u);if(!o||p){c&&c.snp===f&&c.addGene(u);var l=-Math.log(h[this.pValueField])/Math.LN10;if(l>=this.dataRange.min){let e;l>this.dataRange.max?(l=this.dataRange.max,e=!0):e=!1;const i=Math.max(0+r,n-Math.round((l-this.dataRange.min)/s));let a;h.px=d,h.py=i,h.radius=r,o&&c?(a=c.colorForGene(u),kd.setProperties(t,{fillStyle:a,strokeStyle:"black"})):(a=e?"rgb(150, 150, 150)":"rgb(180, 180, 180)",kd.setProperties(t,{fillStyle:a,strokeStyle:a})),kd.fillCircle(t,d,i,r),kd.strokeCircle(t,d,i,r)}}}};o(!1),o(!0)}popupData(e,t){if(void 0===t&&(t=e.viewport.cachedFeatures),!t||0===t.length)return[];const i=this.name,n=[];for(let o of t)Math.abs(o.px-e.canvasX)0&&n.push("
"),n.push({name:"snp id",value:o.snp},{name:"gene id",value:o.geneId},{name:"gene name",value:o.geneName},{name:"p value",value:o.pValue},{name:"tissue",value:i}));return n}menuItemList(){return Ua.numericDataMenuItems(this.trackView)}doAutoscale(e){if(e.length>0){var t=e.map((function(e){return-Math.log(e.value)/Math.LN10}));this.dataRange.max=Lh(t,this.autoscalePercentile)}else{const e=this.config.maxLogP||this.config.max;this.dataRange.max=e||25}return this.dataRange}}const Jw={X:"rgb(204, 153, 0)",Y:"rgb(153, 204, 0)",Un:"darkGray)",1:"rgb(80, 80, 255)",2:"rgb(206, 61, 50)","2a":"rgb(210, 65, 55)","2b":"rgb(215, 70, 60)",3:"rgb(116, 155, 88)",4:"rgb(240, 230, 133)",5:"rgb(70, 105, 131)",6:"rgb(186, 99, 56)",7:"rgb(93, 177, 221)",8:"rgb(128, 34, 104)",9:"rgb(107, 215, 107)",10:"rgb(213, 149, 167)",11:"rgb(146, 72, 34)",12:"rgb(131, 123, 141)",13:"rgb(199, 81, 39)",14:"rgb(213, 143, 92)",15:"rgb(122, 101, 165)",16:"rgb(228, 175, 105)",17:"rgb(59, 27, 83)",18:"rgb(205, 222, 183)",19:"rgb(97, 42, 121)",20:"rgb(174, 31, 99)",21:"rgb(231, 199, 111)",22:"rgb(90, 101, 94)",23:"rgb(204, 153, 0)",24:"rgb(153, 204, 0)",25:"rgb(51, 204, 0)",26:"rgb(0, 204, 51)",27:"rgb(0, 204, 153)",28:"rgb(0, 153, 204)",29:"rgb(10, 71, 255)",30:"rgb(71, 117, 255)",31:"rgb(255, 194, 10)",32:"rgb(255, 209, 71)",33:"rgb(153, 0, 51)",34:"rgb(153, 26, 0)",35:"rgb(153, 102, 0)",36:"rgb(128, 153, 0)",37:"rgb(51, 153, 0)",38:"rgb(0, 153, 26)",39:"rgb(0, 153, 102)",40:"rgb(0, 128, 153)",41:"rgb(0, 51, 153)",42:"rgb(26, 0, 153)",43:"rgb(102, 0, 153)",44:"rgb(153, 0, 128)",45:"rgb(214, 0, 71)",46:"rgb(255, 20, 99)",47:"rgb(0, 214, 143)",48:"rgb(20, 255, 177)"};for(let qk of Object.keys(Jw)){Jw["chr"+qk]=Jw[qk]}for(let Vk=1;Vk<=48;Vk++){if(10===Vk)continue;const Uk=eF(Vk);Jw[Uk]=Jw[Vk.toString()]}function eF(e){if(!+e)return!1;for(var t=String(+e).split(""),i=["","C","CC","CCC","CD","D","DC","DCC","DCCC","CM","","X","XX","XXX","XL","L","LX","LXX","LXXX","XC","","I","II","III","IV","V","VI","VII","VIII","IX"],n="",o=3;o--;)n=(i[+t.pop()+10*o]||"")+n;return Array(+t.join("")+1).join("M")+n}class tF extends Tu{constructor(e,t){super(e,t)}init(e){super.init(e),this.useChrColors=void 0===e.useChrColors||e.useChrColors,this.trait=e.trait,this.posteriorProbability=e.posteriorProbability,this.valueProperty="bed"===e.format?"score":"value",this.height=e.height||100,this.autoscale=e.autoscale,this.autoscalePercentile=void 0===e.autoscalePercentile?98:e.autoscalePercentile,this.background=e.background,this.divider=e.divider||"rgb(225,225,225)",this.dotSize=e.dotSize||3,this.popoverWindow=void 0===e.popoverWindow?1e8:e.popoverWindow,this.useChrColors?this.colorScale=new _d(e.colorTable||Jw):e.color?this.colorScale=new Lw(e.color):this.colorScale=new Tw(e.colorScale||{thresholds:[5e-8,5e-4,.5],colors:["rgb(255,50,50)","rgb(251,100,100)","rgb(251,170,170)","rgb(227,238,249)"]}),this.featureSource=pm(e,this.browser.genome)}async postInit(){if("function"!=typeof this.featureSource.getHeader||(this.header=await this.featureSource.getHeader(),!this.disposed))return this.header&&this.setTrackProperties(this.header),this.autoscale||(this.posteriorProbability?this.dataRange={min:void 0===this.config.min?0:this.config.min,max:void 0===this.config.max?1:this.config.max}:this.dataRange={min:void 0===this.config.min?0:this.config.min,max:void 0===this.config.max?25:this.config.max}),this}get supportsWholeGenome(){return!0}async getFeatures(e,t,i){const n=this.visibilityWindow;return this.featureSource.getFeatures({chr:e,start:t,end:i,visibilityWindow:n})}draw(e){const t=e.features,i=e.context,n=e.pixelWidth,o=e.pixelHeight;if(this.background&&kd.fillRect(i,0,0,n,o,{fillStyle:this.background}),kd.strokeLine(i,0,o-1,n,o-1,{strokeStyle:this.divider}),t){const r=e.bpPerPixel,a=e.bpStart,s=a+n*r+1;for(let e of t){const t=e.start;if(ts)break;let n;if(this.posteriorProbability)n=e[this.valueProperty];else{const t=e[this.valueProperty];if(!t)continue;n=-Math.log10(t)}const c=this.useChrColors?e._f?e._f.chr:e.chr:n,l=this.colorScale.getColor(c),h=(this.dataRange.max-this.dataRange.min)/o,d=Math.round((t-a)/r),f=Math.max(this.dotSize,o-Math.round((n-this.dataRange.min)/h));l&&kd.setProperties(i,{fillStyle:l,strokeStyle:"black"}),kd.fillCircle(i,d,f,this.dotSize),e.px=d,e.py=f}}}paintAxis(e,t,i){kd.fillRect(e,0,0,t,i,{fillStyle:"rgb(255, 255, 255)"});var n={font:"normal 10px Arial",textAlign:"right",strokeStyle:"black"};const o=(this.dataRange.max-this.dataRange.min)/i;if(this.posteriorProbability){const t=.1;for(let r=this.dataRange.min;r0&&i.push("
"),5==o){i.push("...");break}if("function"==typeof r.popupData)i=i.concat(r.popupData());else{const e=r.realChr||r.chr,t=(r.realStart||r.start)+1;i.push({name:"chromosome",value:e}),i.push({name:"position",value:t}),i.push({name:"name",value:r.name}),n.posteriorProbability?i.push({name:"posterior probability",value:s}):i.push({name:"pValue",value:s})}o++}}}return i}menuItemList(){return Ua.numericDataMenuItems(this.trackView)}doAutoscale(e){if(e.length>0){const t=this.valueProperty,i=this.posteriorProbability,n=e.map((function(e){const n=e[t];return{value:i?n:-Math.log(n)/Math.LN10}}));this.dataRange=Dd(n)}else this.posteriorProbability?this.dataRange={min:this.config.min||0,max:this.config.max||1}:this.dataRange={min:this.config.max||25,max:this.config.min||0};return this.dataRange}}class iF extends Tu{constructor(e,t){super(e,t)}init(e){super.init(e),this.autoscale=e.autoscale||void 0===e.max,this.dataRange={min:e.min||0,max:e.max},this.windowFunction=e.windowFunction||"mean",this.paintAxis=pg,this.graphType=e.graphType||"bar",e._featureSource?(this.featureSource=e._featureSource,delete e._featureSource):this.featureSource=pm(this.config,this.browser.genome),this.visibilityWindow=-1,this.featureSource.visibilityWindow=this.visibilityWindow}async postInit(){if("function"==typeof this.featureSource.getHeader){if(this.header=await this.featureSource.getHeader(),this.disposed)return;if(this.sampleNames=this.header.columnNames.slice(3),this.setTrackProperties(this.header),this.header.hasOwnProperty("clickToHighlight")){let e=this.header.clickToHighlight;this.config.clickToHighlight=e,this.config.samplesClickedToHighlight={}}if(this.header.hasOwnProperty("highlight")){this.config.highlightSamples={};let e=this.header.highlight;Array.isArray(e)||(e=[e]);for(let t of e){const e=t.split(";");2===e.length&&(this.config.highlightSamples[e[0]]=e[1])}}}}menuItemList(){return Ua.numericDataMenuItems(this.trackView)}async getFeatures(e,t,i){const n=await this.featureSource.getFeatures({chr:e,start:0,end:Number.MAX_SAFE_INTEGER,visibilityWindow:this.visibilityWindow});let o,r;for(let e=1;et&&(o=e-1),void 0===r&&n[e].start>i){r=e+1;break}return void 0===o&&(o=0),void 0===r&&(r=n.length),n.slice(o,r)}draw(e){const{features:t,context:i,bpPerPixel:n,bpStart:o,pixelWidth:r,pixelHeight:a}=e,s=e=>(this.dataRange.max-e)/(this.dataRange.max-this.dataRange.min)*a,c=function(e){let t=Math.floor((e-o)/n);return isNaN(t)&&console.warn("isNaN(x). feature start "+Za(e)+" bp start "+Za(o)),t};if(t&&t.length>0&&(void 0===this.dataRange.min&&(this.dataRange.min=0),this.dataRange.max>this.dataRange.min)){const e=this.config.highlightSamples,n=this.config.onlyHandleClicksForHighlightedSamples,o=this.config.clickToHighlight;let r=-1,a={},l=[],h=[];this.clickDetectorCache={};for(let d of t){const t=c(d.start),f=c(d.end),u=r>=0?c(r):t;if(!isNaN(t)&&!isNaN(f)){this.clickDetectorCache[t]=[],this.clickDetectorCache[f]=[];for(let r=0;r=1){const r=a[c],h=s(r),d=e&&e[c];d?l.push([u,h,t,m,d]):o&&c in this.config.samplesClickedToHighlight?l.push([u,h,t,m,this.config.samplesClickedToHighlight[c]]):kd.strokeLine(i,u,h,t,m,{strokeStyle:"#D9D9D9"}),n&&!(c in e)||this.clickDetectorCache[t].push([u,h,t,m,c,d||"gray"])}if(f-t>=1){const r=e&&e[c];r?h.push([t,m,f,m,r]):o&&c in this.config.samplesClickedToHighlight?h.push([t,m,f,m,this.config.samplesClickedToHighlight[c]]):kd.strokeLine(i,t,m,f,m,{strokeStyle:"gray"}),n&&!(c in e)||this.clickDetectorCache[f].push([t,m,f,m,c,r||"gray"])}a[c]=p}r=d.end}}for(let e of l)kd.strokeLine(i,e[0],e[1],e[2],e[3],{strokeStyle:e[4],lineWidth:1.3});for(let e of h)kd.strokeLine(i,e[0],e[1],e[2],e[3],{strokeStyle:e[4],lineWidth:2})}(e=>{if(this.config.hasOwnProperty("guideLines"))for(let t of this.config.guideLines)if(t.hasOwnProperty("color")&&t.hasOwnProperty("y")&&t.hasOwnProperty("dotted")){let i=s(t.y),n={strokeStyle:t.color,strokeWidth:2};t.dotted?kd.dashedLine(e.context,0,i,e.pixelWidth,i,5,n):kd.strokeLine(e.context,0,i,e.pixelWidth,i,n)}})(e)}doAutoscale(e){let t,i;return e.length>0?(t=Number.MAX_VALUE,i=-Number.MAX_VALUE,e.forEach((function(e){t=Math.min(t,...e.values),i=Math.max(i,...e.values)})),t-=.01,i+=.01):(t=0,i=100),{min:t,max:i}}clickedFeatures(e){const t=e.canvasX,i=e.canvasY;let n=null;for(n of Object.keys(this.clickDetectorCache))if(n=parseInt(n),n>=t)break;if(n){let e=Number.MAX_VALUE,a=[];const s=this.clickDetectorCache[n];for(let n of s){const o=n[0],r=n[2];if(tr)return[];const s=n[1],c=n[3];if(iMath.max(s,c)+10)continue;const l=nF(t,i,o,s,r,c);l0?c/l:0}class oF extends Tu{constructor(e,t){super(e,t),e.height||(this.height=300),this.arcOrientation=!1,this.theta=Math.PI/2,"bp"===e.format?this.featureSource=new aF(e,t.genome):this.featureSource=new qp(e,t.genome)}async getFeatures(e,t,i){const n=this.visibilityWindow;return this.featureSource.getFeatures({chr:e,start:t,end:i,visibilityWindow:n})}draw(e){const t=e.context,i=Math.PI/2,n=e.pixelWidth,o=e.pixelHeight;e.viewportWidth;const r=e.bpPerPixel,a=e.bpStart,s=r,c=this.arcOrientation;kd.fillRect(t,0,e.pixelTop,n,o,{fillStyle:"rgb(255, 255, 255)"});const l=e.features;if(l){rF(l,1);for(let e of l)if(e.startLeft){let n=Math.round((e.startLeft-a)/s),o=Math.round((e.startRight-a)/s),r=Math.round((e.endLeft-a)/s),l=Math.round((e.endRight-a)/s);t.fillStyle=e.color,t.strokeStyle=e.color,t.beginPath();let h=(n+l)/2,d=(l-n)/2,f=this.height,u=Math.PI+(Math.PI/2-i),p=2*Math.PI-(Math.PI/2-i);c?(f=0,t.arc(h,f,d,p,u),t.lineTo(l,f)):(t.arc(h,f,d,u,p),t.lineTo(r,f));const m=(o+r)/2,g=(r-o)/2,w=f;c?(t.arc(m,w,g,u,p,!0),t.lineTo(r,w)):(t.arc(m,w,g,p,u,!0),t.lineTo(n,w)),t.stroke(),t.fill(),e.drawState={x1:h,y1:f,r1:d,x2:m,y2:w,r2:g,sa:u,ea:p}}else{let n=Math.round((e.start-a)/s),o=Math.round((e.end-a)/s);t.strokeStyle=e.color,t.beginPath();let r=(n+o)/2,l=(o-n)/2,h=this.height,d=Math.PI+(Math.PI/2-i),f=2*Math.PI-(Math.PI/2-i);c?(h=0,t.arc(r,h,l,f,d)):t.arc(r,h,l,d,f),t.stroke(),e.drawState={x1:r,y1:h,r1:l,sa:d,ea:f}}}}clickedFeatures(e){const t=super.clickedFeatures(e),i=[];rF(t,-1);for(let n of t){const t=n.drawState,o=e.canvasX-t.x1,r=e.canvasY-t.y1,a=Math.sqrt(o*o+r*r),s=t.r1+3;let c,l;if(void 0===t.x2)c=a,l=t.r1-3;else{const i=e.canvasX-t.x2,n=e.canvasY-t.y2;c=Math.sqrt(i*i+n*n),l=t.r2-3}if(al){i.push(n);break}}return i}popupData(e,t){if(void 0===t&&(t=this.clickedFeatures(e)),t&&t.length>0)return this.extractPopupData(t[0],this.getGenomeId())}menuItemList(){var e=this;return[{name:"Toggle arc direction",click:function(){e.arcOrientation=!e.arcOrientation,e.trackView.repaintViews()}}]}}function rF(e,t){e.sort((function(e,i){const n=void 0===e.score?-Number.MAX_VALUE:e.score,o=void 0===i.score?-Number.MAX_VALUE:i.score;return(void 0===t?1:t)*(n-o)}))}class aF{constructor(e,t){this.config=e,this.genome=t}async getFeatures({chr:e,start:t,end:i,bpPerPixel:n,visibilityWindow:o}){const r=this.genome;if(this.featureCache)return this.featureCache.queryFeatures(e,t,i);{const n=zd(this.config),o=await ad.loadString(this.config.url,n);return this.featureCache=new md(function(e){if(!e)return null;const t=fp(e);let i,n=!0;const o=[],r=[],a=[];for(;void 0!==(i=t.nextLine());){const e=i.split("\t");if(n&&i.startsWith("color:")){const t="rgb("+e[1]+","+e[2]+","+e[3]+")";o.push(t),e.length>4&&r.push(e[4])}else{n=!1;const t=e[0],i=Number.parseInt(e[1])-1,c=Number.parseInt(e[2])-1,l=Number.parseInt(e[3]),h=Number.parseInt(e[4]);var s=Number.parseInt(e[5]);const d=o[s];let f;f=i<=h?{chr:t,startLeft:Math.min(i,c),startRight:Math.max(i,c),endLeft:Math.min(l,h),endRight:Math.max(l,h),color:d,score:s}:{chr:t,startLeft:Math.min(l,h),startRight:Math.max(l,h),endLeft:Math.min(i,c),endRight:Math.max(i,c),color:d,score:s},f.start=f.startLeft,f.end=f.endRight,r.length>s&&(f.description=r[s]),a.push(f)}}return a}(o),r),this.featureCache.queryFeatures(e,t,i)}}}class sF{constructor(e){this.browser=e,this.type="ideogram",this.height=16,this.order=Number.MIN_SAFE_INTEGER,this.disableButtons=!0,this.ignoreTrackMenu=!0}async getFeatures(e,t,i){return[]}computePixelHeight(e){return this.height}draw({context:e,referenceFrame:t,pixelWidth:i,pixelHeight:n}){const o=t.chr,r=t.genome.getChromosome(o);if(void 0===r||i<=0||n<=0||"all"===o.toLowerCase())return;!function({ctx:e,chr:t,referenceFrame:i,genome:n,width:o,height:r,stainColors:a}){const s=1,c=.5*s,l=0;if(void 0===n)return;kd.fillRect(e,0,0,o,r,{fillStyle:qh.greyScale(255)});const h=n.getCytobands(t);if(h){const t=l+r/2,i=[],n=[];if(0===h.length)return;const d=o/h[h.length-1].end;e.beginPath(),kd.roundRect(e,c,c+l,o-2*c,r-2*c,(r-2*c)/2,0,1),e.clip();for(let o=0;o0&&l[l.length-1].end&&(c=Math.max(c,l[l.length-1].end),r.bpLength=c),a{lF.getColor(e)}));const hF={};class dF extends Tu{constructor(e,t){super(e,t)}init(e){super.init(e),this.type=e.type||"junctions",e._featureSource?(this.featureSource=e._featureSource,delete e._featureSource):this.featureSource=e.featureSource?e.featureSource:pm(e,this.browser.genome),this.margin=void 0===e.margin?10:e.margin,this.height||(this.height=100),void 0===e.colorByNumReadsThreshold&&(e.colorByNumReadsThreshold=5)}async postInit(){if("function"!=typeof this.featureSource.getHeader||(this.header=await this.featureSource.getHeader(),!this.disposed))return this.header&&this.setTrackProperties(this.header),void 0===this.visibilityWindow&&"function"==typeof this.featureSource.defaultVisibilityWindow&&(this.visibilityWindow=await this.featureSource.defaultVisibilityWindow()),this}get supportsWholeGenome(){return!1}async getFeatures(e,t,i,n){const o=this.visibilityWindow;return this.featureSource.getFeatures({chr:e,start:t,end:i,bpPerPixel:n,visibilityWindow:o})}computePixelHeight(e){return this.height}draw(e){const t=e.features,i=e.context,n=e.bpPerPixel,o=e.bpStart,r=e.pixelWidth,a=e.pixelHeight,s=o+r*n+1;if(this.config.isMergedTrack||kd.fillRect(i,0,e.pixelTop,r,a,{fillStyle:"rgb(255, 255, 255)"}),t){hF.referenceFrame=e.viewport.referenceFrame,hF.referenceFrameStart=hF.referenceFrame.start,hF.referenceFrameEnd=hF.referenceFrameStart+hF.referenceFrame.toBP(e.viewport.getWidth()),hF.featureZoomOutTracker={};for(let e of t)if(!(e.ends)break;this.renderJunction(e,o,n,a,i)}}else console.log("No feature list")}renderJunction(e,t,i,n,o){e.isVisible=!1;const r=Math.round((e.start-t)/i),a=Math.round((e.end-t)/i),s=(r+a)/2;if(a-r<=3){if(s in hF.featureZoomOutTracker)return;hF.featureZoomOutTracker[s]=!0}if(this.config.hideAnnotatedJunctions&&"true"===e.attributes.annotated_junction)return;if(this.config.hideUnannotatedJunctions&&"false"===e.attributes.annotated_junction)return;if(this.config.hideMotifs&&this.config.hideMotifs.includes(e.attributes.motif))return;if(this.config.hideStrand===e.strand)return;if(this.config.minJunctionEndsVisible){let t=0;if(e.start>=hF.referenceFrameStart&&e.start<=hF.referenceFrameEnd&&(t+=1),e.end>=hF.referenceFrameStart&&e.end<=hF.referenceFrameEnd&&(t+=1),t0&&l/h>this.config.maxFractionMultiMappedReads)return;if(e.attributes.maximum_spliced_alignment_overhang&&parseInt(e.attributes.maximum_spliced_alignment_overhang)this.config.maxSamplesWithThisJunction)return;if(e.attributes.num_samples_total&&(e.attributes.percent_samples_with_this_junction=100*d/Number(e.attributes.num_samples_total),this.config.minPercentSamplesWithThisJunction&&(e.attributes.percent_samples_with_this_junctionthis.config.maxPercentSamplesWithThisJunction)))return}const f=this.margin,u=this.height,p=f+.5*u;let m=f;const g=f+u-10,w=(r+s)/2,F=(s+a)/2;let b,v,y=1;e.attributes.line_width?y=Number(e.attributes.line_width):(void 0===this.config.thicknessBasedOn||"numUniqueReads"===this.config.thicknessBasedOn?y=c:"numReads"===this.config.thicknessBasedOn?y=h:"numSamplesWithThisJunction"===this.config.thicknessBasedOn&&void 0!==d&&(y=d),y=1+Math.log(y+1)/Math.log(12)),void 0===this.config.bounceHeightBasedOn||"random"===this.config.bounceHeightBasedOn?b=(e.start+e.end)%7:"distance"===this.config.bounceHeightBasedOn?b=6*(e.end-e.start)/(hF.referenceFrameEnd-hF.referenceFrameStart):"thickness"===this.config.bounceHeightBasedOn&&(b=2*y),m+=u*Math.max(7-b,0)/10,v=e.attributes.color?e.attributes.color:void 0===this.config.colorBy||"numUniqueReads"===this.config.colorBy?c>this.config.colorByNumReadsThreshold?"blue":"#AAAAAA":"numReads"===this.config.colorBy?h>this.config.colorByNumReadsThreshold?"blue":"#AAAAAA":"isAnnotatedJunction"===this.config.colorBy?"true"===e.attributes.annotated_junction?"#b0b0ec":"orange":"strand"===this.config.colorBy?"+"===e.strand?"#b0b0ec":"#ecb0b0":"motif"===this.config.colorBy?lF.getColor(e.attributes.motif):"#AAAAAA";let _="";e.attributes.label?_=e.attributes.label.replace(/_/g," "):void 0===this.config.labelWith||"uniqueReadCount"===this.config.labelWith?_=c:"totalReadCount"===this.config.labelWith?_=h:"numSamplesWithThisJunction"===this.config.labelWith?void 0!==d&&(_=d):"percentSamplesWithThisJunction"===this.config.labelWith?void 0!==e.attributes.percent_samples_with_this_junction&&(_=e.attributes.percent_samples_with_this_junction.toFixed(0)+"%"):"motif"===this.config.labelWith&&void 0!==e.attributes.motif&&(_+=e.attributes.motif),"uniqueReadCount"===this.config.labelWithInParen?_+=" ("+c+")":"totalReadCount"===this.config.labelWithInParen?_+=" ("+h+")":"multiMappedReadCount"===this.config.labelWithInParen?l>0&&(_+=" (+"+l+")"):"numSamplesWithThisJunction"===this.config.labelWithInParen?void 0!==d&&(_+=" ("+d+")"):"percentSamplesWithThisJunction"===this.config.labelWithInParen?void 0!==e.attributes.percent_samples_with_this_junction&&(_+=" ("+e.attributes.percent_samples_with_this_junction.toFixed(0)+"%)"):"motif"===this.config.labelWithInParen&&void 0!==e.attributes.motif&&(_+=` ${e.attributes.motif}`),e.isVisible=!0,o.beginPath(),o.moveTo(r,g),o.bezierCurveTo(w,m,F,m,a,g),o.lineWidth=y,o.strokeStyle=v,o.stroke();const C=(e,t,i,n)=>{e.beginPath(),e.moveTo(t,i),e.lineTo(t-n/2,i-n),e.lineTo(t+n/2,i-n),e.lineTo(t,i),e.closePath(),e.fill()};if(e.attributes.left_shape||e.attributes.right_shape){o.fillStyle=v;const t=o.lineWidth>2?10:7;e.attributes.left_shape&&C(o,r,g,t),e.attributes.right_shape&&C(o,a,g,t)}o.fillText(_,s-o.measureText(_).width/2,(7*m+p)/8)}clickedFeatures(e){return super.clickedFeatures(e).filter((function(e){return e.isVisible&&e.attributes}))}popupData(e,t){void 0===t&&(t=this.clickedFeatures(e));const i=e.genomicLocation,n=[];for(let e of t){const t="function"==typeof e.popupData?e.popupData(i):this.extractPopupData(e._f||e,this.getGenomeId());t&&(n.length>0&&n.push("

"),Array.prototype.push.apply(n,t))}return n}dispose(){this.trackView=void 0}}class fF{constructor(e){var t;this.config=e,this.url=(t=e.path||e.url).includes("//www.dropbox.com")?t.replace("//www.dropbox.com","//dl.dropboxusercontent.com"):t.startsWith("ftp://ftp.ncbi.nlm.nih.gov")?t.replace("ftp://","https://"):t}async read(e,t){const i=this.config.headers||{};if(void 0!==e&&t){const n="bytes="+e+"-"+(e+t-1);i.Range=n}let n=this.url.slice();if(this.config.oauthToken){const e=async function(e){return"function"==typeof e?await Promise.resolve(e()):e}(this.config.oauthToken);i.Authorization=`Bearer ${e}`}this.config.apiKey&&(n=function(e,t,i){const n=e.includes("?")?"&":"?";return e+n+t+"="+i}(n,"key",this.config.apiKey));const o=await fetch(n,{method:"GET",headers:i,redirect:"follow",mode:"cors"}),r=o.status;if(r>=400){const e=Error(o.statusText);throw e.code=r,e}return o.arrayBuffer()}}class uF{constructor(e){this.file=e.file,this.fetchSize=e.fetchSize||16e3,this.maxSize=e.maxSize||1e6,this.buffers=[]}async read(e,t){let i=this.buffers.filter((i=>i.overlaps(e,e+t)));for(let n of i)if(n.contains(e,e+t))return n.slice(e,e+t);if(0===i.length){let i=Math.max(t,this.fetchSize);this.buffers.sort(((e,t)=>e.start-t.start));const n=function(e,t,i){let n=i-1,o=e.length;for(;1+n>1);t(e[i])?o=i:n=i}return o}(this.buffers,(t=>t.start>e),0);ne.start-t.start));const n=[];let o=e;for(let e of i){if(oo){const e=o,t=r-e,i=await this.file.read(e,t),a=new pF(e,i);n.push(a)}const a=n[0].start,s=function(e){const t=e.reduce(((e,t)=>e+t.byteLength),0),i=new Uint8Array(t);let n=0;for(let t of e)i.set(new Uint8Array(t),n),n+=t.byteLength;return i.buffer}(n.map((e=>e.buffer))),c=new pF(a,s),l=new Set(i);return this.buffers=this.buffers.filter((e=>!l.has(e))),this.addBuffer(c),c.slice(e,e+t)}}addBuffer(e){const t=this.buffers.reduce(((e,t)=>e+t.size),0)+e.size;if(t>this.maxSize){const e=t-this.maxSize;this.buffers.sort(((e,t)=>e.creationTime-t.creationTime));let i,n=0;for(i=0;ie));i++);this.buffers=ithis.buffer.byteLength)throw Error("buffer bounds error");return this.buffer.slice(e-this.start,t-this.start)}get end(){return this.start+this.buffer.byteLength}get size(){return this.buffer.byteLength}contains(e,t){return e>=this.start&&t<=this.end}overlaps(e,t){return e>this.start&&ethis.start&&t(((e,t,i)=>{t in e?gF(e,t,{enumerable:!0,configurable:!0,writable:!0,value:i}):e[t]=i})(e,"symbol"!=typeof t?t+"":t,i),i);async function FF(e,t,i=0){var n=new Map;for(let[o,r]of e.entries()){let e=await kF.unpack_from_async("<"+r,t,i);i+=kF.calcsize(r),1==e.length&&(e=e[0]),n.set(o,e)}return n}function bF(e,t,i=0){var n=new Map;for(let[o,r]of e.entries()){let e=kF.unpack_from("<"+r,t,i);i+=kF.calcsize(r),1==e.length&&(e=e[0]),n.set(o,e)}return n}function vF(e){e||e()}function yF(e){var t="<"+Array.from(e.values()).join("");return kF.calcsize(t)}function _F(e,t=8){return Math.ceil(e/t)*t}var CF={u:"Uint",i:"Int",f:"Float"};function xF(e){var t,i,n=kF._is_big_endian(e);if(/S/.test(e))t="getString",i=0|((e.match(/S(\d*)/)||[])[1]||1);else{let[n,o,r]=e.match(/[<>=!@]?(i|u|f)(\d*)/);i=parseInt(r||4,10),t="get"+CF[o]+(8*i).toFixed()}return[t,n,i]}var kF=new class{constructor(){this.big_endian=function(){const e=new Uint8Array(4);return!((new Uint32Array(e.buffer)[0]=1)&e[0])}(),this.getters={s:"getUint8",b:"getInt8",B:"getUint8",h:"getInt16",H:"getUint16",i:"getInt32",I:"getUint32",l:"getInt32",L:"getUint32",q:"getInt64",Q:"getUint64",f:"getFloat32",d:"getFloat64"},this.byte_lengths={s:1,b:1,B:1,h:2,H:2,i:4,I:4,l:4,L:4,q:8,Q:8,f:4,d:8};let e=Object.keys(this.byte_lengths).join("");this.fmt_size_regex="(\\d*)(["+e+"])"}calcsize(e){for(var t,i=0,n=new RegExp(this.fmt_size_regex,"g");null!==(t=n.exec(e));){let e=parseInt(t[1]||1,10),n=t[2];i+=e*this.byte_lengths[n]}return i}_is_big_endian(e){return!/^)/.test(e)||this.big_endian)}async unpack_from_async(e,t,i){i=Number.parseInt(i||0);const n=this.calcsize(e),o=await t.slice(i,i+n);let r=0;for(var a,s=new EF(o),c=[],l=this._is_big_endian(e),h=new RegExp(this.fmt_size_regex,"g");null!==(a=h.exec(e));){let e=parseInt(a[1]||1,10),t=a[2],i=this.getters[t],n=this.byte_lengths[t];if("s"==t)c.push((new TextDecoder).decode(o.slice(r,r+e))),r+=e;else for(var d=0;de+(t<<8*i)),0);return a}var IF=class{constructor(e,t){this.buf=e,this.offset=t,this.dtype=this.determine_dtype()}async determine_dtype(){let e=await FF(zF,this.buf,this.offset);this.offset+=DF;let t=15&e.get("class_and_version");if(t==AF)return this._determine_dtype_fixed_point(e);if(t==MF)return this._determine_dtype_floating_point(e);if(t==TF)throw"Time datatype class not supported.";if(t==RF)return this._determine_dtype_string(e);if(t==LF)throw"Bitfield datatype class not supported.";if(t==BF)return{datatype_class:BF,size:e.get("size")};if(t==HF)return this._determine_dtype_compound(e);if(t==OF)return["REFERENCE",e.get("size")];if(t==PF)return this.determine_dtype();if(t==VF)throw"Array datatype class not supported.";if(t==qF){let t=this._determine_dtype_vlen(e);if("VLEN_SEQUENCE"==t[0]){t=["VLEN_SEQUENCE",this.determine_dtype()]}return t}throw"Invalid datatype class "+t}_determine_dtype_fixed_point(e){let t=e.get("size");if(![1,2,4,8].includes(t))throw"Unsupported datatype size";var i;var n;return i=(8&e.get("class_bit_field_0"))>0?"i":"u",n=0==(1&e.get("class_bit_field_0"))?"<":">",this.offset+=4,n+i+t.toFixed()}_determine_dtype_floating_point(e){let t=e.get("size");if(![1,2,4,8].includes(t))throw"Unsupported datatype size";var i;return i=0==(1&e.get("class_bit_field_0"))?"<":">",this.offset+=12,i+"f"+t.toFixed()}_determine_dtype_string(e){return"S"+e.get("size").toFixed()}_determine_dtype_vlen(e){return 1!=(1&e.get("class_bit_field_0"))?["VLEN_SEQUENCE",0,0]:["VLEN_STRING",e.get("class_bit_field_0")>>4,1&e.get("class_bit_field_1")]}_determine_dtype_compound(e){throw"Compound type not yet implemented!"}},zF=new Map([["class_and_version","B"],["class_bit_field_0","B"],["class_bit_field_1","B"],["class_bit_field_2","B"],["size","I"]]),DF=yF(zF);yF(new Map([["offset","I"],["dimensionality","B"],["reserved_0","B"],["reserved_1","B"],["reserved_2","B"],["permutation","I"],["reserved_3","I"],["dim_size_1","I"],["dim_size_2","I"],["dim_size_3","I"],["dim_size_4","I"]]));var AF=0,MF=1,TF=2,RF=3,LF=4,BF=5,HF=6,OF=7,PF=8,qF=9,VF=10;function UF(e){let t=e.length;for(;--t>=0;)e[t]=0}UF(new Array(576)),UF(new Array(60)),UF(new Array(512)),UF(new Array(256)),UF(new Array(29)),UF(new Array(30));var jF=(e,t,i,n)=>{let o=65535&e,r=e>>>16&65535,a=0;for(;0!==i;){a=i>2e3?2e3:i,i-=a;do{o=o+t[n++]|0,r=r+o|0}while(--a);o%=65521,r%=65521}return o|r<<16},WF=new Uint32Array((()=>{let e,t=[];for(var i=0;i<256;i++){e=i;for(var n=0;n<8;n++)e=1&e?3988292384^e>>>1:e>>>1;t[i]=e}return t})()),GF=(e,t,i,n)=>{const o=WF,r=n+i;e^=-1;for(let i=n;i>>8^o[255&(e^t[i])];return~e},$F={2:"need dictionary",1:"stream end",0:"","-1":"file error","-2":"stream error","-3":"data error","-4":"insufficient memory","-5":"buffer error","-6":"incompatible version"},ZF={Z_NO_FLUSH:0,Z_PARTIAL_FLUSH:1,Z_SYNC_FLUSH:2,Z_FULL_FLUSH:3,Z_FINISH:4,Z_BLOCK:5,Z_TREES:6,Z_OK:0,Z_STREAM_END:1,Z_NEED_DICT:2,Z_ERRNO:-1,Z_STREAM_ERROR:-2,Z_DATA_ERROR:-3,Z_MEM_ERROR:-4,Z_BUF_ERROR:-5,Z_NO_COMPRESSION:0,Z_BEST_SPEED:1,Z_BEST_COMPRESSION:9,Z_DEFAULT_COMPRESSION:-1,Z_FILTERED:1,Z_HUFFMAN_ONLY:2,Z_RLE:3,Z_FIXED:4,Z_DEFAULT_STRATEGY:0,Z_BINARY:0,Z_TEXT:1,Z_UNKNOWN:2,Z_DEFLATED:8},KF=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),XF=function(e){const t=Array.prototype.slice.call(arguments,1);for(;t.length;){const i=t.shift();if(i){if("object"!=typeof i)throw new TypeError(i+"must be non-object");for(const t in i)KF(i,t)&&(e[t]=i[t])}}return e},YF=e=>{let t=0;for(let i=0,n=e.length;i=252?6:Wk>=248?5:Wk>=240?4:Wk>=224?3:Wk>=192?2:1;JF[254]=JF[254]=1;var eb=e=>{if("function"==typeof TextEncoder&&TextEncoder.prototype.encode)return(new TextEncoder).encode(e);let t,i,n,o,r,a=e.length,s=0;for(o=0;o>>6,t[r++]=128|63&i):i<65536?(t[r++]=224|i>>>12,t[r++]=128|i>>>6&63,t[r++]=128|63&i):(t[r++]=240|i>>>18,t[r++]=128|i>>>12&63,t[r++]=128|i>>>6&63,t[r++]=128|63&i);return t},tb=(e,t)=>{const i=t||e.length;if("function"==typeof TextDecoder&&TextDecoder.prototype.decode)return(new TextDecoder).decode(e.subarray(0,t));let n,o;const r=new Array(2*i);for(o=0,n=0;n4)r[o++]=65533,n+=a-1;else{for(t&=2===a?31:3===a?15:7;a>1&&n1?r[o++]=65533:t<65536?r[o++]=t:(t-=65536,r[o++]=55296|t>>10&1023,r[o++]=56320|1023&t)}}return((e,t)=>{if(t<65534&&e.subarray&&QF)return String.fromCharCode.apply(null,e.length===t?e:e.subarray(0,t));let i="";for(let n=0;n{(t=t||e.length)>e.length&&(t=e.length);let i=t-1;for(;i>=0&&128==(192&e[i]);)i--;return i<0||0===i?t:i+JF[e[i]]>t?i:t};var nb=function(){this.input=null,this.next_in=0,this.avail_in=0,this.total_in=0,this.output=null,this.next_out=0,this.avail_out=0,this.total_out=0,this.msg="",this.state=null,this.data_type=2,this.adler=0},ob=function(e,t){let i,n,o,r,a,s,c,l,h,d,f,u,p,m,g,w,F,b,v,y,_,C,x,k;const E=e.state;i=e.next_in,x=e.input,n=i+(e.avail_in-5),o=e.next_out,k=e.output,r=o-(t-e.avail_out),a=o+(e.avail_out-257),s=E.dmax,c=E.wsize,l=E.whave,h=E.wnext,d=E.window,f=E.hold,u=E.bits,p=E.lencode,m=E.distcode,g=(1<>>24,f>>>=b,u-=b,b=F>>>16&255,0===b)k[o++]=65535&F;else{if(!(16&b)){if(64&b){if(32&b){E.mode=12;break e}e.msg="invalid literal/length code",E.mode=30;break e}F=p[(65535&F)+(f&(1<>>=b,u-=b),u<15&&(f+=x[i++]<>>24,f>>>=b,u-=b,b=F>>>16&255,16&b){if(y=65535&F,b&=15,us){e.msg="invalid distance too far back",E.mode=30;break e}if(f>>>=b,u-=b,b=o-r,y>b){if(b=y-b,b>l&&E.sane){e.msg="invalid distance too far back",E.mode=30;break e}if(_=0,C=d,0===h){if(_+=c-b,b2;)k[o++]=C[_++],k[o++]=C[_++],k[o++]=C[_++],v-=3;v&&(k[o++]=C[_++],v>1&&(k[o++]=C[_++]))}else{_=o-y;do{k[o++]=k[_++],k[o++]=k[_++],k[o++]=k[_++],v-=3}while(v>2);v&&(k[o++]=k[_++],v>1&&(k[o++]=k[_++]))}break}if(64&b){e.msg="invalid distance code",E.mode=30;break e}F=m[(65535&F)+(f&(1<>3,i-=v,u-=v<<3,f&=(1<{const c=s.bits;let l,h,d,f,u,p,m=0,g=0,w=0,F=0,b=0,v=0,y=0,_=0,C=0,x=0,k=null,E=0;const N=new Uint16Array(16),S=new Uint16Array(16);let I,z,D,A=null,M=0;for(m=0;m<=rb;m++)N[m]=0;for(g=0;g=1&&0===N[F];F--);if(b>F&&(b=F),0===F)return o[r++]=20971520,o[r++]=20971520,s.bits=1,0;for(w=1;w0&&(0===e||1!==F))return-1;for(S[1]=0,m=1;m852||2===e&&C>592)return 1;for(;;){I=m-y,a[g]p?(z=A[M+a[g]],D=k[E+a[g]]):(z=96,D=0),l=1<>y)+h]=I<<24|z<<16|D}while(0!==h);for(l=1<>=1;if(0!==l?(x&=l-1,x+=l):x=0,g++,0==--N[m]){if(m===F)break;m=t[i+a[g]]}if(m>b&&(x&f)!==d){for(0===y&&(y=b),u+=w,v=m-y,_=1<852||2===e&&C>592)return 1;d=x&f,o[d]=b<<24|v<<16|u-r}}return 0!==x&&(o[u+x]=m-y<<24|64<<16),s.bits=b,0},{Z_FINISH:db,Z_BLOCK:fb,Z_TREES:ub,Z_OK:pb,Z_STREAM_END:mb,Z_NEED_DICT:gb,Z_STREAM_ERROR:wb,Z_DATA_ERROR:Fb,Z_MEM_ERROR:bb,Z_BUF_ERROR:vb,Z_DEFLATED:yb}=ZF,_b=12,Cb=30,xb=e=>(e>>>24&255)+(e>>>8&65280)+((65280&e)<<8)+((255&e)<<24);function kb(){this.mode=0,this.last=!1,this.wrap=0,this.havedict=!1,this.flags=0,this.dmax=0,this.check=0,this.total=0,this.head=null,this.wbits=0,this.wsize=0,this.whave=0,this.wnext=0,this.window=null,this.hold=0,this.bits=0,this.length=0,this.offset=0,this.extra=0,this.lencode=null,this.distcode=null,this.lenbits=0,this.distbits=0,this.ncode=0,this.nlen=0,this.ndist=0,this.have=0,this.next=null,this.lens=new Uint16Array(320),this.work=new Uint16Array(288),this.lendyn=null,this.distdyn=null,this.sane=0,this.back=0,this.was=0}var Eb,Nb,Sb=e=>{if(!e||!e.state)return wb;const t=e.state;return e.total_in=e.total_out=t.total=0,e.msg="",t.wrap&&(e.adler=1&t.wrap),t.mode=1,t.last=0,t.havedict=0,t.dmax=32768,t.head=null,t.hold=0,t.bits=0,t.lencode=t.lendyn=new Int32Array(852),t.distcode=t.distdyn=new Int32Array(592),t.sane=1,t.back=-1,pb},Ib=e=>{if(!e||!e.state)return wb;const t=e.state;return t.wsize=0,t.whave=0,t.wnext=0,Sb(e)},zb=(e,t)=>{let i;if(!e||!e.state)return wb;const n=e.state;return t<0?(i=0,t=-t):(i=1+(t>>4),t<48&&(t&=15)),t&&(t<8||t>15)?wb:(null!==n.window&&n.wbits!==t&&(n.window=null),n.wrap=i,n.wbits=t,Ib(e))},Db=(e,t)=>{if(!e)return wb;const i=new kb;e.state=i,i.window=null;const n=zb(e,t);return n!==pb&&(e.state=null),n},Ab=!0,Mb=e=>{if(Ab){Eb=new Int32Array(512),Nb=new Int32Array(32);let t=0;for(;t<144;)e.lens[t++]=8;for(;t<256;)e.lens[t++]=9;for(;t<280;)e.lens[t++]=7;for(;t<288;)e.lens[t++]=8;for(hb(1,e.lens,0,288,Eb,0,e.work,{bits:9}),t=0;t<32;)e.lens[t++]=5;hb(2,e.lens,0,32,Nb,0,e.work,{bits:5}),Ab=!1}e.lencode=Eb,e.lenbits=9,e.distcode=Nb,e.distbits=5},Tb=(e,t,i,n)=>{let o;const r=e.state;return null===r.window&&(r.wsize=1<=r.wsize?(r.window.set(t.subarray(i-r.wsize,i),0),r.wnext=0,r.whave=r.wsize):(o=r.wsize-r.wnext,o>n&&(o=n),r.window.set(t.subarray(i-n,i-n+o),r.wnext),(n-=o)?(r.window.set(t.subarray(i-n,i),0),r.wnext=n,r.whave=r.wsize):(r.wnext+=o,r.wnext===r.wsize&&(r.wnext=0),r.whave{let i,n,o,r,a,s,c,l,h,d,f,u,p,m,g,w,F,b,v,y,_,C,x=0;const k=new Uint8Array(4);let E,N;const S=new Uint8Array([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]);if(!e||!e.state||!e.output||!e.input&&0!==e.avail_in)return wb;i=e.state,i.mode===_b&&(i.mode=13),a=e.next_out,o=e.output,c=e.avail_out,r=e.next_in,n=e.input,s=e.avail_in,l=i.hold,h=i.bits,d=s,f=c,C=pb;e:for(;;)switch(i.mode){case 1:if(0===i.wrap){i.mode=13;break}for(;h<16;){if(0===s)break e;s--,l+=n[r++]<>>8&255,i.check=GF(i.check,k,2,0),l=0,h=0,i.mode=2;break}if(i.flags=0,i.head&&(i.head.done=!1),!(1&i.wrap)||(((255&l)<<8)+(l>>8))%31){e.msg="incorrect header check",i.mode=Cb;break}if((15&l)!==yb){e.msg="unknown compression method",i.mode=Cb;break}if(l>>>=4,h-=4,_=8+(15&l),0===i.wbits)i.wbits=_;else if(_>i.wbits){e.msg="invalid window size",i.mode=Cb;break}i.dmax=1<>8&1),512&i.flags&&(k[0]=255&l,k[1]=l>>>8&255,i.check=GF(i.check,k,2,0)),l=0,h=0,i.mode=3;case 3:for(;h<32;){if(0===s)break e;s--,l+=n[r++]<>>8&255,k[2]=l>>>16&255,k[3]=l>>>24&255,i.check=GF(i.check,k,4,0)),l=0,h=0,i.mode=4;case 4:for(;h<16;){if(0===s)break e;s--,l+=n[r++]<>8),512&i.flags&&(k[0]=255&l,k[1]=l>>>8&255,i.check=GF(i.check,k,2,0)),l=0,h=0,i.mode=5;case 5:if(1024&i.flags){for(;h<16;){if(0===s)break e;s--,l+=n[r++]<>>8&255,i.check=GF(i.check,k,2,0)),l=0,h=0}else i.head&&(i.head.extra=null);i.mode=6;case 6:if(1024&i.flags&&(u=i.length,u>s&&(u=s),u&&(i.head&&(_=i.head.extra_len-i.length,i.head.extra||(i.head.extra=new Uint8Array(i.head.extra_len)),i.head.extra.set(n.subarray(r,r+u),_)),512&i.flags&&(i.check=GF(i.check,n,u,r)),s-=u,r+=u,i.length-=u),i.length))break e;i.length=0,i.mode=7;case 7:if(2048&i.flags){if(0===s)break e;u=0;do{_=n[r+u++],i.head&&_&&i.length<65536&&(i.head.name+=String.fromCharCode(_))}while(_&&u>9&1,i.head.done=!0),e.adler=i.check=0,i.mode=_b;break;case 10:for(;h<32;){if(0===s)break e;s--,l+=n[r++]<>>=7&h,h-=7&h,i.mode=27;break}for(;h<3;){if(0===s)break e;s--,l+=n[r++]<>>=1,h-=1,3&l){case 0:i.mode=14;break;case 1:if(Mb(i),i.mode=20,t===ub){l>>>=2,h-=2;break e}break;case 2:i.mode=17;break;case 3:e.msg="invalid block type",i.mode=Cb}l>>>=2,h-=2;break;case 14:for(l>>>=7&h,h-=7&h;h<32;){if(0===s)break e;s--,l+=n[r++]<>>16^65535)){e.msg="invalid stored block lengths",i.mode=Cb;break}if(i.length=65535&l,l=0,h=0,i.mode=15,t===ub)break e;case 15:i.mode=16;case 16:if(u=i.length,u){if(u>s&&(u=s),u>c&&(u=c),0===u)break e;o.set(n.subarray(r,r+u),a),s-=u,r+=u,c-=u,a+=u,i.length-=u;break}i.mode=_b;break;case 17:for(;h<14;){if(0===s)break e;s--,l+=n[r++]<>>=5,h-=5,i.ndist=1+(31&l),l>>>=5,h-=5,i.ncode=4+(15&l),l>>>=4,h-=4,i.nlen>286||i.ndist>30){e.msg="too many length or distance symbols",i.mode=Cb;break}i.have=0,i.mode=18;case 18:for(;i.have>>=3,h-=3}for(;i.have<19;)i.lens[S[i.have++]]=0;if(i.lencode=i.lendyn,i.lenbits=7,E={bits:i.lenbits},C=hb(0,i.lens,0,19,i.lencode,0,i.work,E),i.lenbits=E.bits,C){e.msg="invalid code lengths set",i.mode=Cb;break}i.have=0,i.mode=19;case 19:for(;i.have>>24,w=x>>>16&255,F=65535&x,!(g<=h);){if(0===s)break e;s--,l+=n[r++]<>>=g,h-=g,i.lens[i.have++]=F;else{if(16===F){for(N=g+2;h>>=g,h-=g,0===i.have){e.msg="invalid bit length repeat",i.mode=Cb;break}_=i.lens[i.have-1],u=3+(3&l),l>>>=2,h-=2}else if(17===F){for(N=g+3;h>>=g,h-=g,_=0,u=3+(7&l),l>>>=3,h-=3}else{for(N=g+7;h>>=g,h-=g,_=0,u=11+(127&l),l>>>=7,h-=7}if(i.have+u>i.nlen+i.ndist){e.msg="invalid bit length repeat",i.mode=Cb;break}for(;u--;)i.lens[i.have++]=_}}if(i.mode===Cb)break;if(0===i.lens[256]){e.msg="invalid code -- missing end-of-block",i.mode=Cb;break}if(i.lenbits=9,E={bits:i.lenbits},C=hb(1,i.lens,0,i.nlen,i.lencode,0,i.work,E),i.lenbits=E.bits,C){e.msg="invalid literal/lengths set",i.mode=Cb;break}if(i.distbits=6,i.distcode=i.distdyn,E={bits:i.distbits},C=hb(2,i.lens,i.nlen,i.ndist,i.distcode,0,i.work,E),i.distbits=E.bits,C){e.msg="invalid distances set",i.mode=Cb;break}if(i.mode=20,t===ub)break e;case 20:i.mode=21;case 21:if(s>=6&&c>=258){e.next_out=a,e.avail_out=c,e.next_in=r,e.avail_in=s,i.hold=l,i.bits=h,ob(e,f),a=e.next_out,o=e.output,c=e.avail_out,r=e.next_in,n=e.input,s=e.avail_in,l=i.hold,h=i.bits,i.mode===_b&&(i.back=-1);break}for(i.back=0;x=i.lencode[l&(1<>>24,w=x>>>16&255,F=65535&x,!(g<=h);){if(0===s)break e;s--,l+=n[r++]<>b)],g=x>>>24,w=x>>>16&255,F=65535&x,!(b+g<=h);){if(0===s)break e;s--,l+=n[r++]<>>=b,h-=b,i.back+=b}if(l>>>=g,h-=g,i.back+=g,i.length=F,0===w){i.mode=26;break}if(32&w){i.back=-1,i.mode=_b;break}if(64&w){e.msg="invalid literal/length code",i.mode=Cb;break}i.extra=15&w,i.mode=22;case 22:if(i.extra){for(N=i.extra;h>>=i.extra,h-=i.extra,i.back+=i.extra}i.was=i.length,i.mode=23;case 23:for(;x=i.distcode[l&(1<>>24,w=x>>>16&255,F=65535&x,!(g<=h);){if(0===s)break e;s--,l+=n[r++]<>b)],g=x>>>24,w=x>>>16&255,F=65535&x,!(b+g<=h);){if(0===s)break e;s--,l+=n[r++]<>>=b,h-=b,i.back+=b}if(l>>>=g,h-=g,i.back+=g,64&w){e.msg="invalid distance code",i.mode=Cb;break}i.offset=F,i.extra=15&w,i.mode=24;case 24:if(i.extra){for(N=i.extra;h>>=i.extra,h-=i.extra,i.back+=i.extra}if(i.offset>i.dmax){e.msg="invalid distance too far back",i.mode=Cb;break}i.mode=25;case 25:if(0===c)break e;if(u=f-c,i.offset>u){if(u=i.offset-u,u>i.whave&&i.sane){e.msg="invalid distance too far back",i.mode=Cb;break}u>i.wnext?(u-=i.wnext,p=i.wsize-u):p=i.wnext-u,u>i.length&&(u=i.length),m=i.window}else m=o,p=a-i.offset,u=i.length;u>c&&(u=c),c-=u,i.length-=u;do{o[a++]=m[p++]}while(--u);0===i.length&&(i.mode=21);break;case 26:if(0===c)break e;o[a++]=i.length,c--,i.mode=21;break;case 27:if(i.wrap){for(;h<32;){if(0===s)break e;s--,l|=n[r++]<Db(e,15),inflateInit2:Db,inflate:Rb,inflateEnd:e=>{if(!e||!e.state)return wb;let t=e.state;return t.window&&(t.window=null),e.state=null,pb},inflateGetHeader:(e,t)=>{if(!e||!e.state)return wb;const i=e.state;return 2&i.wrap?(i.head=t,t.done=!1,pb):wb},inflateSetDictionary:(e,t)=>{const i=t.length;let n,o,r;return e&&e.state?(n=e.state,0!==n.wrap&&11!==n.mode?wb:11===n.mode&&(o=1,o=jF(o,t,i,0),o!==n.check)?Fb:(r=Tb(e,t,i,i),r?(n.mode=31,bb):(n.havedict=1,pb))):wb},inflateInfo:"pako inflate (from Nodeca project)"};var Bb=function(){this.text=0,this.time=0,this.xflags=0,this.os=0,this.extra=null,this.extra_len=0,this.name="",this.comment="",this.hcrc=0,this.done=!1},Hb=Object.prototype.toString,{Z_NO_FLUSH:Ob,Z_FINISH:Pb,Z_OK:qb,Z_STREAM_END:Vb,Z_NEED_DICT:Ub,Z_STREAM_ERROR:jb,Z_DATA_ERROR:Wb,Z_MEM_ERROR:Gb}=ZF;function $b(e){this.options=XF({chunkSize:65536,windowBits:15,to:""},e||{});const t=this.options;t.raw&&t.windowBits>=0&&t.windowBits<16&&(t.windowBits=-t.windowBits,0===t.windowBits&&(t.windowBits=-15)),!(t.windowBits>=0&&t.windowBits<16)||e&&e.windowBits||(t.windowBits+=32),t.windowBits>15&&t.windowBits<48&&(15&t.windowBits||(t.windowBits|=15)),this.err=0,this.msg="",this.ended=!1,this.chunks=[],this.strm=new nb,this.strm.avail_out=0;let i=Lb.inflateInit2(this.strm,t.windowBits);if(i!==qb)throw new Error($F[i]);if(this.header=new Bb,Lb.inflateGetHeader(this.strm,this.header),t.dictionary&&("string"==typeof t.dictionary?t.dictionary=eb(t.dictionary):"[object ArrayBuffer]"===Hb.call(t.dictionary)&&(t.dictionary=new Uint8Array(t.dictionary)),t.raw&&(i=Lb.inflateSetDictionary(this.strm,t.dictionary),i!==qb)))throw new Error($F[i])}function Zb(e,t){const i=new $b(t);if(i.push(e),i.err)throw i.msg||$F[i.err];return i.result}$b.prototype.push=function(e,t){const i=this.strm,n=this.options.chunkSize,o=this.options.dictionary;let r,a,s;if(this.ended)return!1;for(a=t===~~t?t:!0===t?Pb:Ob,"[object ArrayBuffer]"===Hb.call(e)?i.input=new Uint8Array(e):i.input=e,i.next_in=0,i.avail_in=i.input.length;;){for(0===i.avail_out&&(i.output=new Uint8Array(n),i.next_out=0,i.avail_out=n),r=Lb.inflate(i,a),r===Ub&&o&&(r=Lb.inflateSetDictionary(i,o),r===qb?r=Lb.inflate(i,a):r===Wb&&(r=Ub));i.avail_in>0&&r===Vb&&i.state.wrap>0&&0!==e[i.next_in];)Lb.inflateReset(i),r=Lb.inflate(i,a);switch(r){case jb:case Wb:case Ub:case Gb:return this.onEnd(r),this.ended=!0,!1}if(s=i.avail_out,i.next_out&&(0===i.avail_out||r===Vb))if("string"===this.options.to){let e=ib(i.output,i.next_out),t=i.next_out-e,o=tb(i.output,e);i.next_out=t,i.avail_out=n-t,t&&i.output.set(i.output.subarray(e,e+t),0),this.onData(o)}else this.onData(i.output.length===i.next_out?i.output:i.output.subarray(0,i.next_out));if(r!==qb||0!==s){if(r===Vb)return r=Lb.inflateEnd(this.strm),this.onEnd(r),this.ended=!0,!0;if(0===i.avail_in)break}}return!0},$b.prototype.onData=function(e){this.chunks.push(e)},$b.prototype.onEnd=function(e){e===qb&&("string"===this.options.to?this.result=this.chunks.join(""):this.result=YF(this.chunks)),this.chunks=[],this.err=e,this.msg=this.strm.msg};var Kb=function(e,t){return(t=t||{}).raw=!0,Zb(e,t)},Xb={Inflate:$b,inflate:Zb,inflateRaw:Kb,ungzip:Zb,constants:ZF},{Inflate:Yb,inflate:Qb,inflateRaw:Jb,ungzip:ev}=Xb,tv=Qb,iv=ev;var nv=new Map([[1,function(e,t){let i=new Uint8Array(e);return tv(i).buffer}],[2,function(e,t){let i=e.byteLength,n=new Uint8Array(i),o=Math.floor(i/t),r=new DataView(e);for(var a=0;aHH",e,i);if(c%=65535,o!=(s%=65535)||r!=c)throw'ValueError("fletcher32 checksum invalid")'}(e),e.slice(0,-4)}]]),ov=class{constructor(e,t){this.fh=e,this.offset=t,this.depth=null}async init(){this.all_nodes=new Map,await this._read_root_node(),await this._read_children()}async _read_children(){let e=this.depth;for(;e>0;){for(var t of this.all_nodes.get(e))for(var i of t.get("addresses"))this._add_node(await this._read_node(i,e-1));e--}}async _read_root_node(){let e=await this._read_node(this.offset,null);this._add_node(e),this.depth=e.get("node_level")}_add_node(e){let t=e.get("node_level");this.all_nodes.has(t)?this.all_nodes.get(t).push(e):this.all_nodes.set(t,[e])}async _read_node(e,t){let i=await this._read_node_header(e,t);return i.set("keys",[]),i.set("addresses",[]),i}async _read_node_header(e){throw"NotImplementedError: must define _read_node_header in implementation class"}},rv=class extends ov{constructor(){super(...arguments),wF(this,"B_LINK_NODE",new Map([["signature","4s"],["node_type","B"],["node_level","B"],["entries_used","H"],["left_sibling","Q"],["right_sibling","Q"]]))}async _read_node_header(e,t){let i=await FF(this.B_LINK_NODE,this.fh,e);if(null!=t&&i.get("node_level")!=t)throw"node level does not match";return i}},av=class extends rv{constructor(e,t){super(e,t),wF(this,"NODE_TYPE",0),this.ready=this.init()}async _read_node(e,t){let i=await this._read_node_header(e,t);e+=yF(this.B_LINK_NODE);let n=[],o=[],r=i.get("entries_used");for(var a=0;a=0&&b[_]>=e[_];_--)b[_]=0,F[_]=w[_],_>0&&(b[_-1]+=1,F[_-1]+=1);if(F.slice(0,-1).every((function(e,i){return e=0;a--){if(t&1<0?o*=n:o=n}}return r}_nrecords_max(e,t,i){return Math.floor((e-10-i)/(t+i))}_required_bytes(e){return Math.ceil(NF(e)/8)}_int_format(e){return["0&&(h=(await kF.unpack_from_async(s,this.fh,i))[0],i+=o),c.push([n,l,h])}}return r.set("keys",s),r.set("addresses",c),r}async _read_node_header(e,t){let i=await FF(this.B_LINK_NODE,this.fh,e);return i.set("node_level",t),i}*iter_records(){for(let e of this.all_nodes.values())for(let t of e)for(let e of t.get("keys"))yield e}_parse_record(e){throw"NotImplementedError"}},lv=class extends cv{constructor(){super(...arguments),wF(this,"NODE_TYPE",5)}async _parse_record(e,t,i){let n=(await kF.unpack_from_async("0)throw"Filter info size not supported on FractalHeap";if(t.get("btree_address_huge_objects")!=wv)throw"Huge objects not implemented in FractalHeap";t.set("btree_address_huge_objects",null),t.get("root_block_address")==wv&&t.set("root_block_address",null);let i=t.get("log2_maximum_heap_size"),n=this._min_size_nbits(i),o=new Map([["signature","4s"],["version","B"],["heap_header_adddress","Q"],["block_offset",`${n}B`]]);this.indirect_block_header=new Map(o),this.indirect_block_header_size=yF(o),2&~t.get("flags")||o.set("checksum","I"),this.direct_block_header=o,this.direct_block_header_size=yF(o);let r=t.get("maximum_direct_block_size");this._managed_object_offset_size=this._min_size_nbits(i);let a=Math.min(r,t.get("max_managed_object_size"));this._managed_object_length_size=this._min_size_integer(a);let s=t.get("starting_block_size"),c=t.get("table_width");if(!(s>0))throw"Starting block size == 0 not implemented";let l=Number(Math.floor(Math.log2(r)));vF(1n<0)for await(let e of this._iter_indirect_block(this.fh,u,p))f.push(e);else{let e=await this._read_direct_block(this.fh,u,s);f.push(e)}let m=f.reduce(((e,t)=>e+t.byteLength),0),g=new Uint8Array(m),w=0;f.forEach((e=>{g.set(new Uint8Array(e),w),w+=e.byteLength})),this.managed=g.buffer}async _read_direct_block(e,t,i){let n=await e.slice(t,t+i);return vF("FHDB"==bF(this.direct_block_header,n).get("signature")),n}get_data(e){let t=kF.unpack_from(">4&3,n=1;if(0==i){vF(0==t>>6);let i=this._managed_object_offset_size,o=SF(i,e,n);n+=i,i=this._managed_object_length_size;let r=SF(i,e,n);return this.managed.slice(o,o+r)}throw 1==i?"tiny objectID not supported in FractalHeap":2==i?"huge objectID not supported in FractalHeap":"unknown objectID type in FractalHeap"}_min_size_integer(e){return this._min_size_nbits(NF(e))}_min_size_nbits(e){return Math.ceil(e/8)}async*_iter_indirect_block(e,t,i){let n=await FF(this.indirect_block_header,e,t);t+=this.indirect_block_header_size,vF("FHIB"==n.get("signature"));let o=n.get("block_offset").reduce(((e,t,i)=>e+(t<<8*i)),0);n.set("block_offset",o);let[r,a]=this._indirect_info(i),s=[];for(let i=0;ithis._chunks))}get shape(){let e=this.find_msg_type(oy)[0].get("offset_to_message");return async function(e,t){let i=(await kF.unpack_from_async("255&&(r=(await kF.unpack_from_async("0;e.set("optional",s);let c,l=(await kF.unpack_from_async("0&&(c=(await kF.unpack_from_async(`${r}s`,i,t))[0],t+=r),e.set("name",c);let h=await kF.unpack_from_async(`<${l}i`,i,t);t+=4*l,e.set("client_data_values",h),o.push(e)}}return this._filter_pipeline=o,this._filter_pipeline}find_msg_type(e){return this.msgs.filter((function(t){return t.get("type")==e}))}async get_attributes(){let e={},t=this.find_msg_type(dy);for(let i of t){let t=i.get("offset_to_message"),[n,o]=await this.unpack_attribute(t);e[n]=o}return e}async get_fillvalue(){var e,t=this.find_msg_type(sy)[0].get("offset_to_message");let i=(await kF.unpack_from_async("=o&&([r,o]=s[++c],l=0);let t=await FF(Wv,e,r+l),i=r+l+Gv;if(t.set("offset_to_message",i),t.get("type")==fy){var[f,u]=await kF.unpack_from_async("=a-Zv){let e=c[++l];if(null==e)break;[o,a]=e,h=0}let t=await FF($v,e,o+h),i=o+h+Zv+n;if(t.set("offset_to_message",i),t.get("type")==fy){var[d,f]=await kF.unpack_from_async("0,c=(4&n)>0;(8&n)>0?(o=(await kF.unpack_from_async("0&&(t+=8);let o=(2&n)>0?Yv:Xv,r=await FF(o,e,t),a=new Map;for(let[e,t]of r.entries())a.set(e,t==Mv?null:t);return a}get is_dataset(){return this.find_msg_type(oy).length>0}async get_data(){let e=this.find_msg_type(ly)[0].get("offset_to_message");var[t,i,n,o]=await this._get_data_message_properties(e);if(0==n)throw"Compact storage of DataObject not implemented";return 1==n?this._get_contiguous_data(o):2==n?this._get_chunked_data(e):void 0}async _get_data_message_properties(e){let t,i,n,[o,r,a]=await kF.unpack_from_async("=1&&o<=4),[o,t,i,n]}async _get_contiguous_data(e){let[t]=await kF.unpack_from_async("=!@\|]?(i|u|f|S)(\d*)/.test(n)){let[e,i,r]=xF(n),s=new Array(o);const c=await this.fh.slice(t,t+r*o);let l=new EF(c);for(var a=0;a=1&&t<=3);var s="<"+(i-1).toFixed()+"I",c=await kF.unpack_from_async(s,this.fh,r);this._chunks=c,this._chunk_dims=i,this._chunk_address=a}}}};var Mv=kF.unpack_from("this.get(e)))}length(){return this.keys.length}_dereference(e){if(!e)throw"cannot deference null reference";let t=this.file._get_object_by_address(e);if(null==t)throw"reference not found in file";return t}async get(e){if("number"==typeof e)return this._dereference(e);var t=wy(e);if("/"==t)return this.file;if("."==t)return this;if(/^\//.test(t))return this.file.get(t.slice(1));if(""!=function(e){let t="/",i=e.lastIndexOf(t)+1,n=e.slice(0,i),o=new RegExp("^"+t+"+$"),r=new RegExp(t+"$");n&&!o.test(n)&&(n=n.replace(r,""));return n}(t))var[i,n]=t.split(/\/(.*)/);else var i=t,n=".";if(!(i in this._links))throw i+" not found in group";var o=wy(this.name+"/"+i);let r=this._links[i];if("string"==typeof r)try{return this.get(r)}catch(e){return null}var a=new Av(this.file._fh,r);if(await a.ready,a.is_dataset){if("."!=n)throw o+" is a dataset, not a group";return new gy(o,a,this)}var s=new py(o,this);return await s.init(a),s.get(n)}visit(e){return this.visititems(((t,i)=>e(t)))}visititems(e){var t=this.name.length;/\/$/.test(this.name)||(t+=1);for(var i=this.values.slice();i;){let n=i.shift();1==i.length&&console.log(n);let o=e(n.name.slice(t),n);if(null!=o)return o;n instanceof py&&(i=i.concat(n.values))}return null}get attrs(){return null==this._attrs&&(this._attrs=this._dataobjects.get_attributes()),this._attrs}},my=class extends py{constructor(e,t,i){super("/",null),this.ready=this.init(e,t,i)}async init(e,t,i){var n=new dv(e,0);await n.ready;var o=await n.get_offset_to_dataobjects(),r=new Av(e,o);if(await r.ready,this.parent=this,this.file=this,this.name="/",this._dataobjects=r,this._attrs=null,this._keys=null,this._fh=e,this.filename=t||"",this.mode="r",this.userblock_size=0,i&&i.index)this.index=i.index;else{let t;if(i&&i.indexOffset)t=i.indexOffset;else{const e=await this.attrs;if(e.hasOwnProperty("_index_offset"))t=e._index_offset;else{const e=this.indexName||"_index",i=await r.find_link(e);i&&(t=i[1])}}if(t)try{const i=new Av(e,t);await i.ready;const n=await i.get_data(),o=iv(n),r=(new TextDecoder).decode(o);this.index=JSON.parse(r)}catch(e){console.error(`Error loading index by offset ${e}`)}}this.index&&this.name in this.index?this._links=this.index[this.name]:this._links=await r.get_links()}_get_object_by_address(e){return this._dataobjects.offset==e?this:this.visititems((e=>{e._dataobjects.offset}))}},gy=class extends Array{constructor(e,t,i){super(),this.parent=i,this.file=i.file,this.name=e,this._dataobjects=t,this._attrs=null,this._astype=null}get value(){var e=this._dataobjects.get_data();return null==this._astype?this.getValue(e):e.astype(this._astype)}get shape(){return this._dataobjects.shape}get attrs(){return this._dataobjects.get_attributes()}get dtype(){return this._dataobjects.dtype}get fillvalue(){return this._dataobjects.get_fillvalue()}async to_array(){return function(e,t){const i=e.length,n=t.reduce(((e,t)=>e*t),1);i!==n&&console.warn(`shape product: ${n} does not match length of flattened array: ${i}`);let o=e;const r=t.slice(1).reverse();for(let e of r){const t=[],{length:i}=o;let n=0;for(;n{let t=e.indexOf("\0");return t>=0?e.substring(0,t):e})):e}};function wy(e){return e.replace(/\/(\/)+/g,"/")}async function Fy(e){var t;e.url&&("function"==typeof(t=e.url).slice&&"function"==typeof t.arrayBuffer)&&(e.file=e.url,e.url=void 0);const i=void 0!==e.url;let n=e.reader?e.reader:function(e){if(e.url)return new fF(e);if(e.path)return new NodeLocalFile(e);if(e.file)return new mF(e.file);throw Error("One of 'url', 'path (node only)', or 'file (browser only)' must be specified")}(e);const o=e.fetchSize||2e3,r=e.maxSize||2e5;i&&(n=new uF({file:n,fetchSize:o,maxSize:r}));const a=new by(n),s=await async function(e){let t;if(e.indexReader)t=e.indexReader;else{if(e.index)return e.index;e.indexURL?t=new fF({url:e.indexURL}):e.indexPath?t=new NodeLocalFile({path:e.indexPath}):e.indexFile&&(t=new mF({file:e.indexFile}))}if(t){const e=await t.read(),i=(new TextDecoder).decode(e);return JSON.parse(i)}return}(e),c=e.indexOffset,l=function(e){if(e.url)return vy(e.url);if(e.path)return vy(e.path);if(e.file)return e.file.name}(e),h=new my(a,l,{index:s,indexOffset:c});return await h.ready,h}class by{constructor(e){this.fileReader=e}async slice(e,t){return this.fileReader.read(e,t-e)}}function vy(e){const t=e.lastIndexOf("/");return t>0?e.substring(t+1):e}class yy{constructor(e,t=1e5){this.h5_file=e,this.bin_size=t,this.h5_obj=void 0}async fetch(){return this.h5_obj||(this.h5_obj=await Fy({url:this.h5_file,fetchSize:1e6,maxSize:2e8})),this.h5_obj}async get_keys(){return(await this.fetch()).keys}async get_rd_signal(e=this.bin_size){let t=await this.fetch(),i=t.keys,n=new _y(i),o=n.get_rd_bins(),r=n.get_snp_bins();this.available_bins=[...new Set(o,r)],this.available_bins.includes(e)||(e=this.available_bins.at(-1));const a=await t.get("rd_chromosomes");await a.dtype;let s=await a.value,c=await this.rd_stat(t,i,e);var l=[],h=[],d=[],f=[],u=[],p=[];for(let n of s){var m=`his_rd_p_${n}_${e}`;let o=await this.get_chr_signal(t,i,n,e,m,c);l=l.concat(o);var g=`his_rd_p_${n}_${e}_GC`;let r=await this.get_chr_signal(t,i,n,e,g,c);h=h.concat(r);let a=`his_rd_p_${n}_${e}_partition_GC_merge`,s=await this.get_chr_signal(t,i,n,e,a,c);d=d.concat(s);let w=await this.rd_call_combined(t,i,n,e,c);f=f.concat(w);let F=`snp_likelihood_${n}_${e}_mask`,b=await this.get_baf_signals(t,i,n,e,F);u=u.concat(b[0]),p=p.concat(b[1])}this.callers=[],0!=f.length&&this.callers.push("ReadDepth"),0!=f.length&&this.callers.push("2D");var w={},F={RD_Raw:l,RD_Raw_gc_coor:h,ReadDepth:d,"2D":f,BAF1:u,BAF2:p};return w[e]=F,w}decode_segments(e){let t=[],i=[];for(let n of e)4294967295==n?(t.push(i),i=[]):i.push(n);return t}async rd_call_combined(e,t,i,n,o){let r,a=[],s=`his_rd_p_${i}_${n}_partition_GC_mosaic_segments_2d`;if(t.includes(s)){const t=await e.get(s);let i=await t.value;r=this.decode_segments(i)}let c=`his_rd_p_${i}_${n}_partition_GC_mosaic_call_2d`;if(t.includes(c)){const t=await e.get(c);let s=await t.to_array();r.forEach(((e,t)=>{e.forEach(((e,r)=>{a.push({chr:i,start:e*n,end:(e+1)*n,value:s[0][t]/o[4]*2})}))}))}return a}async rd_stat(e,t,i){let n,o=`rd_stat_${i}_auto`;if(t.includes(o)){const t=await e.get(o);n=await t.value}return n}async get_chr_signal(e,t,i,n,o,r){let a=[];if(t.includes(o)){const t=await e.get(o);(await t.value).forEach(((e,t)=>{a.push({chr:i,start:t*n,end:(t+1)*n,value:e/r[4]*2})}))}return a}async get_baf_signals(e,t,i,n,o){let r=[],a=[];if(t.includes(o)){let t=await e.get(o);(await t.to_array()).forEach(((e,t)=>{let o=Math.max(...e);const s=e.indexOf(o);let c=Math.max(s/200,1-s/200);r.push({chr:i,start:t*n,end:(t+1)*n,value:-2*c}),.5!=c&&a.push({chr:i,start:t*n,end:(t+1)*n,value:-2*(1-c)})}))}return[r,a]}async get_baf_signals_v2(e,t,i,n,o){let r=[],a=[];if(t.includes(o)){let t=await e.get(o);(await t.to_array()).forEach(((e,t)=>{isNaN(e)||(r.push({chr:i,start:t*n,end:(t+1)*n,value:-2*(.5-e)}),.5!=e&&a.push({chr:i,start:t*n,end:(t+1)*n,value:-2*(.5+e)}))}))}return console.log(i,r,a),[r,a]}}class _y{constructor(e){this.signals=e}get_rd_bins(){let e=[];this.signals.forEach((t=>{let i=t.match(/^his_rd_p_(.*)_(\d+)$/);i&&e.push({chr:i[1],bin_size:i[2]})}));return[...new Set(e.map((e=>Number(e.bin_size))))]}get_snp_bins(){let e=[];this.signals.forEach((t=>{let i=t.match(/^snp_likelihood_(.*)_(\d+)_mask$/);i&&e.push({chr:i[1],bin_size:i[2]})}));return[...new Set(e.map((e=>Number(e.bin_size))))]}}function Cy(e){let t=function(e){if(e.length<4)return e;let t,i,n,o,r,a;return t=e.slice().sort(((e,t)=>e-t)),t.length/4%1==0?(i=.5*(t[t.length/4]+t[t.length/4+1]),n=.5*(t[t.length*(3/4)]+t[t.length*(3/4)+1])):(i=t[Math.floor(t.length/4+1)],n=t[Math.ceil(t.length*(3/4)+1)]),o=n-i,r=n+1.5*o,a=i-1.5*o,t.filter((e=>e>=a&&e<=r))}(e);const i=t.length,n=t.reduce(((e,t)=>e+t))/i,o=Math.sqrt(t.map((e=>Math.pow(e-n,2))).reduce(((e,t)=>e+t))/i);return[n,o]}var xy={range_function:function(e,t,i){return Array(Math.ceil((t-e)/i)).fill(e).map(((e,t)=>e+t*i))},getDistParams:Cy,linspace:function(e,t,i){if(void 0===i&&(i=Math.max(Math.round(t-e)+1,1)),i<2)return 1===i?[e]:[];var n=Array(i);for(let o=--i;o>=0;o--)n[o]=(o*t+(i-o)*e)/i;return n},GetFit:class{constructor(e){this.allBins=e}getValues(){return Object.values(this.allBins).reduce(((e,t)=>e.concat(t.filter((e=>e.binScore>0)).map((e=>e.binScore)))),[])}getMean(e){return e.reduce((function(e,t){return e+t}))/e.length}fit_data(){return Cy(this.getValues())}histogram(e,t){const i=t[1]-t[0],n=[];e.forEach(((e,o)=>{t.forEach(((t,o)=>{if(n[t]||(n[t]={count:0}),t<=e&&e{o.push(e.count)})),o}}};function ky(e,t){return isNaN(e)||isNaN(t)||t<=0?NaN:0===e?.5:.5+.5*(Ey(.5*t,.5,1)-Ey(.5*t,.5,t/(t+e*e)))*Math.sign(e)}function Ey(e,t,i){if(0==i)return 0;if(1==i)return 1;{let n=zy(e+t)-zy(e)-zy(t)+e*Math.log(i)+t*Math.log(1-i);return i<(e+1)/(e+t+2)?Math.exp(n)*Ny(e,t,i)/e:1-Math.exp(n)*Ny(t,e,1-i)/t}}function Ny(e,t,i,n=1e3){let o=1,r=1,a=1,s=e+t,c=e+1,l=e-1,h=1-s*i/c;for(let d=0;d<=n;d++){let n=parseFloat(d+1),f=n+n,u=n*(t-n)*i/((l+f)*(e+f)),p=o+u*r,m=h+u*a;u=-(e+n)*(s+n)*i/((c+f)*(e+f));let g=m+u*h,w=o;if(r=p/g,a=m/g,o=(p+u*o)/g,h=1,Math.abs(o-w)<3e-7*Math.abs(o))return o}}function Sy(e){if(0==e||1==e)return 1;return e*Sy(e-1)}function Iy(e){let t;var i=[75122.633153,80916.6278952,36308.2951477,8687.24529705,1168.92649479,83.8676043424,2.50662827511],n=0,o=1;if(0==e)t=1e99;else if(e%1==0)t=Sy(e-1);else{for(let t=0;tt?e:t}))}function My(e,t,i,n){return t*Math.exp(-1*(e-i)**2/(2*n**2))/Math.sqrt(2*Math.PI)/n}function Ty(e,t,i,n){return Math.exp(-1*(e-i)**2/(t**2+n**2))}function Ry(e,t){let i;try{i=e.reduce(((e,i,n)=>e+Math.min(i,t[n])))}catch{return console.log("Failed to find likelihood overlap: ",e,t),0}return i}function Ly(e,t,i,n){return 0==t&&0==n?{nl:.5*(e+i),ne:0}:{nl:(e*n*n+i*t*t)/(t*t+n*n),ne:Math.sqrt(t*t*n*n/(t*t+n*n))}}function By(e,t){let i=parseInt(t*(e.length-1)),n=t*(e.length-1)-i;return iMath.floor(t/2)&&(n=t-1-n);const o=(t/2-n)/(t+1),r=Math.floor((t/2+n)/2),a=t-1-r;let s=e.slice(r,a+1).reduce(((e,t)=>e+t),0)/e.reduce(((e,t)=>e+t),0);return n===Math.floor(t/2)&&(s=1),{mean:o,p:s}}var Oy=class{constructor(e,t){this.wigFeatures=e,this.binSize=t}get_fit(){var e=new xy.GetFit(this.wigFeatures),[t,i]=e.fit_data();return{globalMean:t,globalStd:i}}async call_2d(e=null,t=null,i="both",n=.1,o=0,r=10,a=0){let s=this.get_fit();this.globalMean=s.globalMean,this.globalStd=s.globalStd;let c=null==e?.05*this.binSize/3e9:e,l=null==t?parseInt(this.binSize/1e4):t,h=[],d=[],f=[],u=[],p=[],m=[];for(const[e,t]of Object.entries(this.wigFeatures)){let e=[],i=[],r=[];t.forEach(((t,n)=>{t.hets_count>4&&t.dp_count>l&&(e.push([n]),i.push(t.binScore),r.push(t.likelihood_score),delete t.likelihood_score)}));let a=[];for(let e=1;eMath.sqrt(Math.sqrt(e)**2+this.globalStd**2+Math.pow(s[t]/2,2)))),g=[];for(let t=0;t0;){g=g.filter((e=>"number"==typeof e));let t=Ay(g);if(isNaN(t)&&console.log("NaN value",g),te*r[a+1][t])),o=n.reduce(((e,t)=>e+t))}catch{console.log(r),console.log("max_overlap:",t,a,g.length),console.log("likelihood: ",a,r[a],r[a+1]),console.log("nlh: ",o)}if(i[a]=s.nl,m[a]=s.ne,r[a]=n.map((function(e){return e/o})),e[a].push(...e[a+1]),i.splice(a+1,1),m.splice(a+1,1),e.splice(a+1,1),r.splice(a+1,1),g.splice(a,1),a0){let e=Ty(i[a-1],m[a-1],i[a],m[a])*Ry(r[a-1],r[a]);g[a-1]=e}}let w=-1;for(;;){g=[];for(let t=0;te*r[o+1][t])),s=n.reduce(((e,t)=>e+t));r[o]=n.map((function(e){return e/s})),e[o].push(...e[o+1]),e[o]=e[o].sort(((e,t)=>e-t)),i.splice(a,1),m.splice(a,1),e.splice(a,1),r.splice(a,1),a>=e.length&&(o+=1,a=o+1)}else a+=1,a>=e.length&&(o+=1,a=o+1)}if(w==e.length)break;w=e.length}e.forEach(((e,n)=>{let a=Hy(r[n]);e.length>1&&(e.forEach(((e,r)=>{d.push(t[e]),a.mean<=o&&h.push(t[e]),t[e].segment_score=i[n]})),f.push(i[n]),u.push(m[n]),p.push(r[n]))}))}let g=parseInt(1e3*(1-a));0==g&&(g=1);let w=xy.linspace(a,1,g),F={},b={};for(let e=10;e>-1;e--)for(let t=0;t1-t+t*e/2)),s=e/2;e>0?(n=.5-t/(t+r),o=w.map(((e,i)=>.5-(1-e+e*t)/(2-2*e+(t+r)*e)))):(n=0,o=w.map(((e,t)=>0*e)));for(let i=0;i{if(!isNaN(o[t])){let n=My(e*this.globalMean,1,f[i],u[i])*By(p[i],.5+o[t]);l+=n,n>h&&(h=n,d=w[t])}})),i in F?F[i].push([e,t,r,l/w.length,d]):F[i]=[e,t,r,l/w.length,d]}for(let e=0;ee[3]-t[3]));else if(F[e].sort(((e,t)=>e[3]-t[3])),"both"==i&&(b[e].sort(((e,t)=>e[3]-t[3])),b[e][0][3]>F[e][0][3])){let t=F[e].filter((t=>t[0]!=b[e][0][0]&&t[1]<=b[e][0][1]));F[e]=[b[e][0]].push(...t)}for(let e=0;e{var o={...e};1!=i&&(o.value=e[t]/i*2),n.push(o)}));return n}formatDataStructure_BAF(e,t=2){const i=[],n=[];for(const[t,o]of Object.entries(this.wigFeatures))o.forEach((t=>{var o={...t},r={...t};let a=t[e];.5!=a&&(r.value=-2*(1-a),n.push(r)),o.value=-2*a,i.push(o)}));return[i,n]}};function Py(e){for(var t=1,i=1,n=1*e,o=1;o<50;o++)t*=o,n+=(i*=-1)*Math.pow(e,2*o+1)/(t*(2*o+1));return 2*n/Math.sqrt(3.14159265358979)}function qy(e,t,i,n,o){var r=new jy(i.slice(n,o));return 0==r.std&&(r.std=t>0?t*r.mean/e:1),Wy(e,r.mean,r.std,o-n)/(o-n)}function Vy(e,t,i,n,o){var r=new jy(i.slice(n,o));if(r.meanr&!l&c0&&(h=qy(e,t,i,n-1,o)),o-n>2)var d=qy(e,t,i,n+1,o),f=qy(e,t,i,n,o-1);if(oe+t))/e.length,this.std=Math.sqrt(e.reduce(((e,t)=>(t-this.mean)**2))/e.length)}}function Wy(e,t,i,n){0==i&&(i=1);var o=(e-t)/i*Math.sqrt(n);return 1-Dy.TdistributionCDF(Math.abs(o),n-1)}function Gy(e,t,i,n,o,r){0==t&&(t=1),0==o&&(o=1);var a=(e-n)/Math.sqrt(t**2/i+o**2/r),s=(t**2/i+o**2/r)**2*(i-1)*(r-1)/(t**4*(r-1)/i**2+o**4*(i-1)/r**2);return 1-Dy.TdistributionCDF(Math.abs(a),parseInt(s+.5))}var $y=class{constructor(e,t,i){this.rd=e,this.mean=t,this.std=i,this.bin_bands=[2,3,4,5,6,7,8,10,12,14,16,20,24,28,32,40,48,56,64,80,96,112,128]}get_rd_signal_bandwidth(e){var t=[];return e.forEach(((e,i)=>{var n=0;n=e>this.mean/4?this.mean/(this.std**2*e):4/this.std**2,t.push(n)})),t}meanShiftCaller(e=3){var t={};return Object.entries(this.rd).forEach((([i,n])=>{var o=new Array(n.length).fill(!1),r=new Array(n.length);for(let e=0;e{var a=o.map(((e,t)=>!e)),s=[];Object.entries(n).forEach((([e,t])=>{s.push(t.binScore)}));var c=[0],l=0;for(let e=0;e0&&(c.push(c[c.length-1]+l-1),l=0):l+=1;c.shift();for(let i=0;i=s.length||Math.abs(e-i)>=s.length)){var f=(i-e)*Math.exp(-.5*(i-e)**2/t**2)*Math.exp(-.5*(s[e]-s[i])**2*h[e]);d[e]+=f}for(var u=new Array,p=0;p=0&&u.push(p);u.push(d.length-1),u=u.concat(c).sort(((e,t)=>e-t)),u=Array.from(new Set(u));var m=0;for(p=0;pe+t))/g.length;s.fill(w,m,u[p]+1),m=u[p]+1}}p=0;for(var F=0;p.01&&u.push(p+1)}u.unshift(0),u.push(r.length),o=new Array(this.rd.length).fill(!1);for(p=1;p1))continue;v[0]=u[p-2];var y=[u[p],u[p]];if(!(p.01/genome_size*bin_size*(_+C))continue;if(Gy(k.mean,k.std,k.data.length,z.mean,z.std,z.data.length)>.01/genome_size*bin_size*(_+x))continue}if(Wy(this.mean,k.mean,k.std,k.data.length)>.05)continue;let e=s.slice(b[0],b[1]);var D=new jy(e);o.fill(!0,b[0],b[1]),r.fill(D.mean,b[0],b[1])}})),t[i]=r})),t}call_mean_shift(e=3){for(var t=new Array(this.rd.length).fill(!1),i=new Array(this.rd.length),n=0;n{var r=t.map(((e,t)=>!e)),a=[];r.forEach(((e,t)=>{e&&a.push(this.rd[t])}));for(var s=[0],c=0,l=0;l0&&(s.push(s[s.length-1]+c-1),c=0):c+=1;s.shift();for(var h=0;h=a.length||Math.abs(l-u)>=a.length)){var p=(u-l)*Math.exp(-.5*(u-l)**2/n**2)*Math.exp(-.5*(a[l]-a[u])**2*d[l]);f[l]+=p}var m=new Array;for(l=0;l=0&&m.push(l);m.push(f.length-1),m=m.concat(s).sort(((e,t)=>e-t)),m=Array.from(new Set(m));var g=0;for(l=0;le+t))/w.length;a.fill(F,g,m[l]+1),g=m[l]+1}}for(l=0,u=0;l.01&&m.push(l+1)}m.unshift(0),m.push(i.length),t=new Array(this.rd.length).fill(!1);for(l=1;l1){v[0]=m[l-2];var y=[m[l],m[l]];if(l3.483106931382794e-9*(_+C))continue;if(Gy(k.mean,k.std,k.data.length,z.mean,z.std,z.data.length)>3.483106931382794e-9*(_+x))continue}if(!(Wy(this.mean,k.mean,k.std,k.data.length)>.05)){var D=new jy(this.rd.slice(b[0],b[1]));t.fill(!0,b[0],b[1]),i.fill(D.mean,b[0],b[1])}}}}}})),i}cnv_calling(e=1e5){var t=(t=.25)*this.mean,i=this.mean-t,n=this.mean+t,o=2971e6,r=this.meanShiftCaller(),a={},s=[];return Object.entries(r).forEach((([c,l])=>{for(var h=!1;!h;){h=!0;var d=new Array(1).fill(0);for(let e=0;e.01&&d.push(e+1)}d.push(l.length);for(let e=0;e0&&(u=Math.abs(l[d[e]]-l[d[e-1]])),e{g.push(t.binScore)}));for(var w,F=new Array(l.length).fill(""),b=0,v=.05*e/o;b_+1){var C=Uy(this.mean,this.std,g,_,x,v);if(C){var x=C;F.fill("D",_,x)}}for(_=b;bn;)b+=1;(x=b)>_+1&&(C=Uy(this.mean,this.std,g,_,x,v))&&(x=C,F.fill("A",_,x)),b==y&&(b+=1)}for(b=0;b_+1&&(Vy(this.mean,this.std,g,_,x)<1682935038707506e-26&&F.fill(["d"]*(x-_),_,x),b-=1),b+=1}(b=0)=F.length););if(b>_){var E=new jy(k.slice(_,b));k.fill(E.mean,_,b)}bs&&(r>0&&t.push({chr:i,start:a,end:s,value:o,bin:c,count:r}),o=0,a=n.start-n.start%this.binSize,s=a+this.binSize);const l=n.calls[9].info.DP;l&&(o+=Number.parseInt(l),r++)}r>0&&t.push({chr:i,start:a,end:s,value:o,bin:c,count:r})}return t}async computeReadDepth(){const e=Object.keys(this.allVariants);var t={};for(let n of e){const e=this.allVariants[n];var i;if(0!==e.length)for(let o of e){i=Math.max(Math.floor(o.start/this.rowBinSize),0),t[n]||(t[n]=[]),t[n][i]||(t[n][i]={chr:n,start:i*this.rowBinSize,end:(i+1)*this.rowBinSize,value:0,sum_score:0,count:0});const e=o.calls[9].info.DP;e&&(t[n][i].sum_score+=Number.parseInt(e),t[n][i].count++)}}var n={};for(let i of e){n[i]||(n[i]=[]);for(let e=0;e{t.forEach(((t,i)=>{t.partition_level=parseInt(r[e][i]),t.partition_call=parseInt(a[0][e][i])}))})),[this.formatDataStructure(e,"binScore",i),this.formatDataStructure(e,"partition_level",i),this.formatDataStructure(e,"partition_call",i),a[1]]}formatDataStructure(e,t,i=1){const n=[];for(const[o,r]of Object.entries(e))r.forEach((e=>{var o={...e};1!=i&&(o.value=e[t]/i*2),n.push(o)}));return n}async computeBAF_v2(){const e=Object.keys(this.allVariants),t={},i=[],n=[];for(let a of e){const e=this.allVariants[a];if(0===e.length)continue;var o;for(let s of e){if(o=Math.max(Math.floor(s.start/this.binSize),0),t[a]||(t[a]=[]),!t[a][o]){if(o>0){let e=o-1;if(t[a][e]){const o=this.get_max_min_score(t[a][e]);if(.5!=o.value){let e=Object.assign({},o);e.value=-2*(1-o.value),n.push(e)}o.value=-2*o.value,t[a][e]=o,i.push(t[a][e])}}t[a][o]={chr:a,start:o*this.binSize,end:(o+1)*this.binSize,value:0,count:0,likelihood_score:[],min_score:0}}const e=s.calls[9];let c=e.genotype,l=e.info.AD.split(","),h=l[0],d=l[1];if(0==c[0]&&1==c[1]||1==c[0]&&0==c[1]){if(0==t[a][o].likelihood_score.length)t[a][o].likelihood_score=xy.linspace(0,1,100).map(((e,t)=>Ky(h,d,e)));else{var r=0;t[a][o].likelihood_score=xy.linspace(0,1,100).map(((e,i)=>{var n=t[a][o].likelihood_score[i]*Ky(h,d,e);return r+=n,n})),t[a][o].likelihood_score=xy.linspace(0,1,100).map(((e,i)=>t[a][o].likelihood_score[i]/r))}t[a][o].count++}}const s=this.get_max_min_score(t[a][o]);if(.5!=s.value){let e=Object.assign({},s);e.value=-2*(1-s.value),n.push(e)}s.value=-2*s.value,t[a][o]=s,i.push(t[a][o])}return[i,n]}format_BAF_likelihood(e){const t=[];for(const[i,n]of Object.entries(e))n.forEach((e=>{var i={...e};.5!=e.value&&(i.value=1-e.value,t.push(i))}));return t}get_max_min_score(e){if(e.likelihood_score.length>0){const t=Math.max(...e.likelihood_score),i=e.likelihood_score.indexOf(t);e.value=Math.max(i/100,1-i/100),e.min_score=Math.min(i/100,1-i/100)}else e.score=0;return e}async getAllbins(){const e=await this.computeDepthFeatures();return new xy.GetFit(e).fit_data(),e}async read_rd_baf(e="ReadDepth"){const t=Object.keys(this.allVariants);var i={};for(let e of t){const t=this.allVariants[e];var n;if(0!==t.length)for(let o of t){n=Math.max(Math.floor(o.start/this.rowBinSize),0),i[e]||(i[e]=[]),i[e][n]||(i[e][n]={chr:e,start:n*this.rowBinSize,end:(n+1)*this.rowBinSize,dp_sum_score:0,dp_count:0,hets_count:0,hets:[]});const t=o.calls[9],r=t.info.DP;r&&(i[e][n].dp_sum_score+=Number.parseInt(r),i[e][n].dp_count++);let a=t.info.AD.split(","),s=t.genotype;if(0==s[0]&&1==s[1]||1==s[0]&&0==s[1]){i[e][n].hets_count++;let t=parseInt(a[0]),o=parseInt(a[1]);i[e][n].hets.push({ref:t,alt:o})}}}var o,r=this.adjust_bin_size(i);if("ReadDepth"==e){o=this.readDepthMeanshift(r);var a=this.formatDataStructure_BAF(r,"max_likelihood")}else if("2D"==e){let e=new Oy(r,this.binSize),t=await e.call_2d();o=[t.binScore,[],t.segment_score];a=e.formatDataStructure_BAF("max_likelihood")}return[o,a]}formatDataStructure_BAF(e,t,i=2){const n=[],o=[];for(const[i,r]of Object.entries(e))r.forEach((e=>{delete e.likelihood_score;var i={...e},r={...e};let a=e[t];.5!=a&&(r.value=-2*(1-a),o.push(r)),i.value=-2*a,n.push(i)}));return[n,o]}adjust_bin_size(e){const t=Object.keys(this.allVariants);var i={};for(let r of t){i[r]||(i[r]=[]);for(let t=0;t{if(0==i[r][t].likelihood_score.length)i[r][t].likelihood_score=xy.linspace(0,1,100).map(((t,i)=>Ky(e.ref,e.alt,t)));else{var o=0;i[r][t].likelihood_score=xy.linspace(0,1,100).map(((n,a)=>{var s=i[r][t].likelihood_score[a]*Ky(e.ref,e.alt,n);return o+=s,s})),i[r][t].likelihood_score=xy.linspace(0,1,100).map(((e,n)=>i[r][t].likelihood_score[n]/o))}}))}const s=this.get_max_min_score(i[r][t]);i[r][t].max_likelihood=s.value}}return i}}function Ky(e,t,i,n=!0){return i**e*(1-i)**t+i**t*(1-i)**e}class Xy extends Tu{constructor(e,t){super(e,t),this.featureType="numeric",this.paintAxis=pg,e.max||(this.defaultScale=!0,this.autoscale=!1),this.height=void 0!==e.height?e.height:250}async init(e){this.type="cnvpytor",this.graphType=e.graphType||"points",this.bin_size=e.bin_size||1e5,this.signal_name=e.signal_name||"rd_snp",this.cnv_caller=e.cnv_caller||"2D",this.colors=e.colors||["gray","black","green","blue"],super.init(e)}get supportsWholeGenome(){return!0}get_signals(){let e=[];return"rd_snp"==this.signal_name?e=["RD_Raw","RD_Raw_gc_coor",this.cnv_caller,"BAF1","BAF2"]:"rd"==this.signal_name?e=["RD_Raw","RD_Raw_gc_coor",this.cnv_caller]:"snp"==this.signal_name?e=["BAF1","BAF2"]:"cnh"==this.signal_name&&(e=[this.cnv_caller]),e}get_signal_colors(){return[{singal_name:"RD_Raw",color:this.colors[0]},{singal_name:"RD_Raw_gc_coor",color:this.colors[1]},{singal_name:"ReadDepth",color:this.colors[2]},{singal_name:"2D",color:this.colors[2]},{singal_name:"BAF1",color:this.colors[3]},{singal_name:"BAF2",color:this.colors[3]}]}async postInit(){if("vcf"==this.config.format){this.featureSource=pm(this.config,this.browser.genome),this.header=await this.getHeader();var e=this.featureSource.reader.features.reduce((function(e,t){return e[t.chr]=e[t.chr]||[],e[t.chr].push(t),e}),Object.create(null));const t=new Zy(e,this.bin_size);let i,n,o;this.wigFeatures_obj={},this.wigFeatures_obj[this.bin_size]={},"2D"==this.config.cnv_caller?(o=await t.read_rd_baf("2D"),i=o[0],n=o[1],this.wigFeatures_obj[this.bin_size]["2D"]=i[2],this.available_callers=["2D"]):(o=await t.read_rd_baf(),i=o[0],n=o[1],this.wigFeatures_obj[this.bin_size].ReadDepth=i[2],this.available_callers=["ReadDepth"]),this.wigFeatures_obj[this.bin_size].RD_Raw=i[0],this.wigFeatures_obj[this.bin_size].RD_Raw_gc_coor=i[1],this.wigFeatures_obj[this.bin_size].BAF1=n[0],this.wigFeatures_obj[this.bin_size].BAF2=n[1],this.available_bins=[this.bin_size],this.set_available_callers()}else this.cnvpytor_obj=new yy(this.config.url,this.bin_size),this.wigFeatures_obj=await this.cnvpytor_obj.get_rd_signal(this.bin_size),this.available_bins=this.cnvpytor_obj.available_bins,this.available_callers=this.cnvpytor_obj.callers,this.set_available_callers();this.tracks=[];const t=[];this.signals=this.get_signals(),this.signal_colors=this.get_signal_colors();for(let e in this.wigFeatures_obj)for(const[i,n]of Object.entries(this.wigFeatures_obj[e]))if(this.signals.includes(i)){let e={type:"wig",isMergedTrack:!0};e.features=n,e.name=i,e.color=this.signal_colors.filter((e=>e.singal_name===i)).map((e=>e.color));const o=await this.browser.createTrack(e);o?(o.autoscale=!1,this.tracks.push(o)):console.warn("Could not create track "+e),"function"==typeof o.postInit&&t.push(o.postInit())}this.flipAxis=!!this.config.flipAxis&&this.config.flipAxis,this.logScale=!!this.config.logScale&&this.config.logScale,this.autoscale=this.config.autoscale,this.autoscale||(this.dataRange={min:this.config.min||0,max:this.config.max});for(let e of this.tracks)e.autoscale=!1,e.dataRange=this.dataRange;return Promise.all(t)}set_available_callers(){this.available_callers.includes(this.cnv_caller)||(this.available_callers.length>0?this.cnv_caller=this.available_callers[0]:this.cnv_caller=null)}async getHeader(){if(!this.header){if("function"==typeof this.featureSource.getHeader){const e=await this.featureSource.getHeader();e&&(this.callSets=e.callSets||[]),this.header=e}this.sampleNames=this.callSets?this.callSets.map((e=>e.name)):[]}return this.header}get height(){return this._height}set height(e){if(this._height=e,this.tracks)for(let t of this.tracks)t.height=e,t.config.height=e}menuItemList(){let e=[];void 0!==this.flipAxis&&e.push({label:"Flip y-axis",click:()=>{this.flipAxis=!this.flipAxis,this.trackView.repaintViews()}}),e=e.concat(Ua.numericDataMenuItems(this.trackView)),e.push("
"),e.push("Bin Sizes");for(let t of this.available_bins){const i=Va(t,t===this.bin_size);e.push({object:wr(i),click:async()=>{this.bin_size=t,await this.recreate_tracks(t),this.clearCachedFeatures(),this.trackView.updateViews(),this.trackView.repaintViews()}})}e.push("
"),e.push("Signal Type");let t={rd_snp:"RD and BAF Likelihood",rd:"RD Signal",snp:"BAF Likelihood"};for(let i in t){const n=Va(t[i],i===this.signal_name);e.push({object:wr(n),click:async()=>{this.signal_name=i,await this.recreate_tracks(this.bin_size),this.clearCachedFeatures(),this.trackView.updateViews(),this.trackView.repaintViews()}})}e.push("
"),e.push("CNV caller");for(let t of this.available_callers){const i=Va(t,t===this.cnv_caller);e.push({object:wr(i),click:async()=>{this.cnv_caller=t,await this.recreate_tracks(this.bin_size),this.clearCachedFeatures(),this.trackView.updateViews(),this.trackView.repaintViews()}})}return e}async recreate_tracks(e){this.tracks=[];const t=[];e in this.wigFeatures_obj||(this.wigFeatures_obj={...this.wigFeatures_obj,...await this.cnvpytor_obj.get_rd_signal(e)}),this.signals=this.get_signals(),this.signal_colors=this.get_signal_colors();for(const[i,n]of Object.entries(this.wigFeatures_obj[e]))if(this.signals.includes(i)){let e={type:"wig",isMergedTrack:!0};e.features=n,e.name=i,e.color=this.signal_colors.filter((e=>e.singal_name===i)).map((e=>e.color));const o=await this.browser.createTrack(e);o?(o.autoscale=!1,this.tracks.push(o)):console.warn("Could not create track "+e),"function"==typeof o.postInit&&t.push(o.postInit())}this.flipAxis=!!this.config.flipAxis&&this.config.flipAxis,this.logScale=!!this.config.logScale&&this.config.logScale,this.autoscale=this.config.autoscale,this.autoscale||(this.dataRange={min:this.config.min||0,max:this.config.max});for(let e of this.tracks)e.autoscale=!1,e.dataRange=this.dataRange;return Promise.all(t)}async getFeatures(e,t,i,n){if(this.tracks){const o=this.tracks.map((o=>o.getFeatures(e,t,i,n)));return Promise.all(o)}}getScaleFactor(e,t,i,n){return n?i/(Math.log10(t+1)-(e<=0?0:Math.log10(e+1))):i/(t-e)}computeYPixelValue(e,t){return(this.flipAxis?e-this.dataRange.min:this.dataRange.max-e)*t}computeYPixelValueInLogScale(e,t){let i=this.dataRange.max,n=this.dataRange.min;return i<=0?0:(n<=-1&&(n=0),n=n<=0?0:Math.log10(n+1),i=Math.log10(i+1),e=Math.log10(e+1),(this.flipAxis?e-n:i-e)*t)}draw(e){const t=e.features;if(!t)return;if(this.defaultScale&&("rd_snp"==this.signal_name?this.dataRange={min:this.config.min||this.dataRange.min||-2,max:this.config.max||this.dataRange.max||6}:"rd"==this.signal_name?this.dataRange={min:this.config.min||this.dataRange.min||0,max:this.config.max||this.dataRange.max||6}:"snp"==this.signal_name&&(this.dataRange={min:this.config.min||this.dataRange.min||-2,max:this.config.max||this.dataRange.max||0})),this.autoscale&&(this.dataRange=function(e,t){let i=0,n=-Number.MAX_VALUE;for(let e of t)for(let t of e)void 0===t.value||Number.isNaN(t.value)||(i=Math.min(i,t.value),n=Math.max(n,t.value));return{min:i,max:n}}(e.referenceFrame.chr,t)),this.tracks)for(let i=0,n=this.tracks.length;ithis.logScale?this.computeYPixelValueInLogScale(e,i):this.computeYPixelValue(e,i);if(this.config.hasOwnProperty("guideLines"))for(let t of this.config.guideLines)if(t.hasOwnProperty("color")&&t.hasOwnProperty("y")&&t.hasOwnProperty("dotted")){let i=n(t.y),o={strokeStyle:t.color,strokeWidth:1};t.dotted?kd.dashedLine(e.context,0,i,e.pixelWidth,i,5,o):kd.strokeLine(e.context,0,i,e.pixelWidth,i,o)}}popupData(e,t){const i=t||e.viewport.cachedFeatures;if(i&&i.length===this.tracks.length){const t=[];for(let n=0;n0&&t.push("
"),t.push(`
${this.tracks[n].name}
`);const o=this.tracks[n].popupData(e,i[n]);t.push(...o)}return t}}}const Yy=new Map([["ideogram",(e,t)=>new sF(e,t)],["sequence",(e,t)=>new vf(e,t)],["feature",(e,t)=>new ow(e,t)],["seg",(e,t)=>new Bw(e,t)],["mut",(e,t)=>new Bw(e,t)],["maf",(e,t)=>new Bw(e,t)],["wig",(e,t)=>new Mw(e,t)],["merged",(e,t)=>new Ow(e,t)],["alignment",(e,t)=>new fw(e,t)],["interaction",(e,t)=>new qw(e,t)],["interact",(e,t)=>new qw(e,t)],["variant",(e,t)=>new Xw(e,t)],["eqtl",(e,t)=>new Qw(e,t)],["gwas",(e,t)=>new tF(e,t)],["arc",(e,t)=>new oF(e,t)],["gcnv",(e,t)=>new iF(e,t)],["junction",(e,t)=>new dF(e,t)],["blat",(e,t)=>new lw(e,t)],["cnvpytor",(e,t)=>new Xy(e,t)]]),Qy=function(e,t){Yy.set(e,t)};var Jy=Qy,e_=function(e,t,i){let n;switch(e){case"annotation":case"genes":case"fusionjuncspan":case"snp":n="feature";break;case"seg":case"maf":case"mut":n="seg";break;case"junctions":case"splicejunctions":n="junction";break;default:n=e}return Yy.has(n)?Yy.get(n)(t,i):void 0};class t_{constructor(e,t){const i=(new DOMParser).parseFromString(e,"text/xml");this.processRootNode(i,t);const n=i.getElementsByTagName("Resource"),o=i.getElementsByTagName("Track"),r=o&&o.length>0,a=[];this.tracks=a;const s=new Map;Array.from(n).forEach((function(e,t){var i={url:e.getAttribute("path"),indexURL:e.getAttribute("index"),order:t};s.set(i.url,i),r||a.push(i)})),r&&Array.from(o).forEach((function(e){const t=e.getElementsByTagName("Track");if(t&&t.length>0){const i={type:"merged",tracks:[]};i_(e,i),a.push(i),Array.from(t).forEach((function(e){e.processed=!0;const t=e.getAttribute("id"),n=s.get(t);n&&(i.tracks.push(n),i_(e,n),n.autoscale=!1,i.height=n.height)}))}else if(!e.processed){const t=e.getAttribute("id"),i=s.get(t);i&&(a.push(i),i_(e,i))}}))}processRootNode(e,t){const i=e.getElementsByTagName("Session");!i||i.length;const n=i.item(0),o=n.getAttribute("genome"),r=n.getAttribute("locus"),a=n.getAttribute("ucscID");t&&t.hasOwnProperty(o)?this.genome=o:(this.reference={fastaURL:o},a&&(this.reference.id=a)),r&&(this.locus=r)}}function i_(e,t){t.name=e.getAttribute("name");const i=e.getAttribute("color");i&&(t.color="rgb("+i+")");const n=e.getAttribute("altColor");i&&(t.altColor="rgb("+n+")");const o=e.getAttribute("height");o&&(t.height=parseInt(o));const r=e.getAttribute("autoScale");r&&(t.autoscale="true"===r);const a=e.getAttribute("autoscaleGroup");a&&(t.autoscaleGroup=a);const s=e.getAttribute("windowFunction");s&&(t.windowFunction=s);const c=e.getAttribute("visibilityWindow")||e.getAttribute("featureVisibilityWindow");c&&(t.visibilityWindow=c);const l=e.getAttribute("indexed");l&&(t.indexed="true"===l);const h=e.getAttribute("normalize");h&&(t.normalize="true"===h);const d=e.getElementsByTagName("DataRange");if(d.length>0){const e=d.item(0);t.min=Number(e.getAttribute("minimum")),t.max=Number(e.getAttribute("maximum")),t.logScale="LOG"===e.getAttribute("type")}}const n_=Ka;class o_{constructor(){this.attributes={},this.plinkLoaded=!1}async loadPlinkFile(e,t){t||(t={});var i=zd(t);const n=await ad.loadString(e,i);var o=n_(n);for(let e of o){var r=e.split(" ");this.attributes[r[1]]={familyId:r[0],fatherId:r[2],motherId:r[3],sex:r[4],phenotype:r[5]}}return this.plinkLoaded=!0,this}getAttributes(e){return this.attributes[e]}getAttributeNames(){return this.hasAttributes()?Object.keys(this.attributes[Object.keys(this.attributes)[0]]):[]}hasAttributes(){return Object.keys(this.attributes).length>0}}class r_{constructor(e,t){this.geneColors={},this.gene=null,this.snp=null,this.genesCount=0,e&&(this.gene=e.toUpperCase(),this.geneColors[this.gene]=a_[this.genesCount++]),t&&(this.snp=t.toUpperCase())}addGene(e){this.geneColors[e.toUpperCase()]||(this.geneColors[e.toUpperCase()]=a_[this.genesCount++])}colorForGene(e){return this.geneColors[e.toUpperCase()]}}var a_=[];a_.push("rgb(228,26,28)"),a_.push("rgb(55,126,184)"),a_.push("rgb(77,175,74)"),a_.push("rgb(166,86,40)"),a_.push("rgb(152,78,163)"),a_.push("rgb(255,127,0)"),a_.push("rgb(247,129,191)"),a_.push("rgb(153,153,153)"),a_.push("rgb(255,255,51)"),a_.push("rgb(102, 194, 165"),a_.push("rgb(252, 141, 98"),a_.push("rgb(141, 160, 203"),a_.push("rgb(231, 138, 195"),a_.push("rgb(166, 216, 84"),a_.push("rgb(255, 217, 47"),a_.push("rgb(229, 196, 148"),a_.push("rgb(179, 179, 179"),a_.push("rgb( 141, 211, 199"),a_.push("rgb(255, 255, 179"),a_.push("rgb(190, 186, 218"),a_.push("rgb(251, 128, 114"),a_.push("rgb(128, 177, 211"),a_.push("rgb(253, 180, 98"),a_.push("rgb(179, 222, 105"),a_.push("rgb(252, 205, 229"),a_.push("rgb(217, 217, 217"),a_.push("rgb(188, 128, 189"),a_.push("rgb(204, 235, 197"),a_.push("rgb(255, 237, 111");class s_{constructor(e,t,i,n,o){this.genome=e,this.chr=t,this.start=i,this.end=n,this.bpPerPixel=o,this.id=xr.guid()}extend(e){const t=Math.min(e.start,this.start),i=Math.max(e.end,this.end),n=(i-t)/(this.end-this.start);this.start=t,this.end=i,this.bpPerPixel*=n}calculateEnd(e){return this.start+this.bpPerPixel*e}calculateBPP(e,t){return(e-this.start)/t}set(e){this.chr=e.chr,this.start=e.start,this.bpPerPixel=e.bpPerPixel}toPixels(e){return e/this.bpPerPixel}toBP(e){return this.bpPerPixel*e}shiftPixels(e,t,i){const n=this.start,o=e*this.bpPerPixel;return this.start+=o,i&&this.clampStart(t),this.end=this.start+t*this.bpPerPixel,n!==this.start}clampStart(e){const t=this.genome.getChromosome(this.chr).bpStart||0;if(this.start=Math.max(t,this.start),e){const{bpLength:t}=this.genome.getChromosome(this.chr),i=t-e*this.bpPerPixel;this.start>i&&(this.start=i)}}async zoomWithScaleFactor(e,t,i,n){const o=void 0===n?this.start+this.toBP(i/2):n,{start:r,bpPerPixel:a}=this.start,{bpLength:s}=this.getChromosome(),c=t<1?e.minimumBases()/i:s/i;this.bpPerPixel=t<1?Math.max(this.bpPerPixel*t,c):Math.min(this.bpPerPixel*t,c);const l=this.bpPerPixel*i;this.start=o-.5*l,this.clampStart(i),this.end=this.start+l;(r!==this.start||a!==this.bpPerPixel)&&await e.updateViews(!0)}getChromosome(){return this.genome.getChromosome(this.chr)}getMultiLocusLabelBPLengthOnly(e){const t=" ",i=Math.floor(this.start)+1,n=Math.round(this.start+this.bpPerPixel*e);return`${t}${this.chr}${t}${Td(n-i)}${t}`}getMultiLocusLabelLocusOnly(e){const t=" ",{chr:i,start:n,end:o}=this.getPresentationLocusComponents(e);return`${t}${i}:${n}-${o}${t}`}getMultiLocusLabel(e){const t=" ",{chr:i,start:n,end:o}=this.getPresentationLocusComponents(e),r=Math.floor(this.start)+1;return`${t}${i}:${n}-${o}${t}${t}(${Td(Math.round(this.start+this.bpPerPixel*e)-r)})${t}`}getPresentationLocusComponents(e){if("all"===this.chr)return{chr:this.chr};{const t=Za(Math.floor(this.start)+1),i=Za(Math.round(this.start+this.bpPerPixel*e));return{chr:this.chr,start:t,end:i}}}getLocusString(){if("all"===this.chr)return"all";{const e=Za(Math.floor(this.start)+1),t=Za(Math.round(this.end));return`${this.chr}:${e}-${t}`}}description(e){console.log(` ${e||""} referenceFrame - ${this.chr} bpp ${this.bpPerPixel.toFixed(3)} start ${Za(Math.round(this.start))} end ${Za(Math.round(this.end))} `)}}const c_={timeout:5e3,type:"plain",url:"https://igv.org/genomes/locus.php?genome=$GENOME$&name=$FEATURE$",coords:0,chromosomeField:"chromosome",startField:"start",endField:"end",geneField:"gene",snpField:"snp"};async function l_(e,t){if(void 0===t||""===t.trim())return;(t&&"all"===t.trim().toLowerCase()||"*"===t)&&(t="all");const i=t.split(" ");let n=e.searchConfig||c_,o=[];const r=async i=>{let o=function(e,t){const i=t.split("\t");if(i.length>=3)try{const t=e.genome.getChromosomeName(i[0]),n=parseInt(i[1].replace(/,/g,""),10)-1,o=parseInt(i[2].replace(/,/g,""),10);if(!isNaN(n)&&!isNaN(o))return{chr:t,start:n,end:o}}catch(e){}const n=t.split(":"),o=n[0];if("all"===o&&e.genome.getChromosome(o))return{chr:o,start:0,end:e.genome.getChromosome(o).bpLength};if(void 0===e.genome.getChromosome(o))return;{const t={chr:e.genome.getChromosomeName(o),start:0,end:e.genome.getChromosome(o).bpLength};if(n.length>1){let i,o=n[1].split("-");if(o.length>2){if(!n[1].startsWith("-"))return;{const e=n[1].indexOf("-",1);if(e>0){o=[n[1].substring(0,e),n[1].substring(e+1)]}}}if(i=o[0].replace(/,/g,""),isNaN(i))return;if(t.start=parseInt(i,10)-1,t.end=t.start+1,1===o.length&&(t.start-=20,t.end+=20),2===o.length){if(i=o[1].replace(/,/g,""),isNaN(i))return;if(t.end=parseInt(i,10),t.start<0&&!e.isSoftclipped()){const e=-t.start;t.start+=e,t.end+=e}}}return t}}(e,i);if(!o){const n=e.genome.featureDB.get(i.toUpperCase());n&&(o={chr:n.chr,start:n.start,end:n.end,gene:n.name,locusSearchString:t})}if(!o&&e.config&&!1!==e.config.search)try{o=await async function(e,t,i){let n=i.url.replace("$FEATURE$",t.toUpperCase());n.indexOf("$GENOME$")>-1&&(n=n.replace("$GENOME$",e.genome.id?e.genome.id:"hg19"));const o=i.timeout?{timeout:i.timeout}:void 0,r=await ad.loadString(n,o),a=function(e,t,i){let n;n="plain"===i.type?function(e,t){const i=[],n=[];return Ka(t).forEach((function(e){""===e||i.push(e)})),i.forEach((function(t){var i,o,r,a,s=t.split("\t");s.length>=3&&(r=(o=s[1].split(":"))[1].split("-"),i=s[2].trim(),a={gene:s[0],chromosome:e.genome.getChromosomeName(o[0].trim()),start:parseInt(r[0].replace(/,/g,"")),end:parseInt(r[1].replace(/,/g,"")),type:"gtex"===i?"snp":"gene"},n.push(a))})),n}(e,t):JSON.parse(t);i.resultsField&&(n=n[i.resultsField]);if(n&&0!==n.length){const t=i.chromosomeField||"chromosome",o=i.startField||"start",r=i.endField||"end",a=i.coords||1;let s;s=Array.isArray(n)?n[0]:n,s.hasOwnProperty(t)&&s.hasOwnProperty(o)||console.error("Search service results must include chromosome and start fields: "+s);const c=s[t],l=e.genome.getChromosome(c);if(!l)return;const h=l.name;let d=s[o]-a,f=s[r];void 0===f&&(f=d+1);const u={chr:h,start:d,end:f},p=s.type?s.type:"gene";return i.geneField&&"gene"===p&&(u.gene=s[i.geneField]),i.snpField&&"snp"===p&&(u.snp=s[i.snpField]),u}return}(e,r,i);a&&(a.locusSearchString=t);return a}(e,i,n)}catch(e){throw console.error(e),Error("Search service currently unavailable.")}return o};for(let e of i){const t=await r(e);t&&(t.locusSearchString=e,o.push(t))}if(0===o.length){const e=await r(t);e&&(e.locusSearchString=t,o.push(e))}return 0===o.length?void 0:o}class h_{constructor(e){this.browser=e}navbarDidResize(e){this.updateNavbar(this.createResponsiveClassSchedule(e))}updateNavbar(e){this.browser.$toggle_button_container.removeClass(),this.browser.$toggle_button_container.addClass(e.$toggle_button_container),wr(this.browser.zoomWidget.zoomContainer).removeClass(),wr(this.browser.zoomWidget.zoomContainer).addClass(e.zoomContainer)}createResponsiveClassSchedule(e){let t={};const i=this.browser.isMultiLocusWholeGenomeView()||this.browser.referenceFrameList&&Rf.isWholeGenomeView(this.browser.referenceFrameList[0].chr);return i?this.browser.windowSizePanel.hide():this.browser.windowSizePanel.show(),e>990?(t.$toggle_button_container="igv-navbar-toggle-button-container",t.zoomContainer="igv-zoom-widget"):e>860?(t.$toggle_button_container="igv-navbar-toggle-button-container",t.zoomContainer="igv-zoom-widget-900"):e>540?(t.$toggle_button_container="igv-navbar-toggle-button-container-750",t.zoomContainer="igv-zoom-widget-900"):(t.$toggle_button_container="igv-navbar-toggle-button-container-750",t.zoomContainer="igv-zoom-widget-900",this.browser.windowSizePanel.hide()),i&&(t.zoomContainer="igv-zoom-widget-hidden"),t}}const d_=function(e,t){this.container=xr.div({class:"igv-chromosome-select-widget-container"}),t.appendChild(this.container),this.select=document.createElement("select"),this.select.setAttribute("name","chromosome-select-widget"),this.container.appendChild(this.select),this.select.addEventListener("change",(()=>{this.select.blur(),""!==this.select.value&&e.search(this.select.value)})),this.showAllChromosomes=!1!==e.config.showAllChromosomes};d_.prototype.show=function(){this.container.style.display="flex"},d_.prototype.hide=function(){this.container.style.display="none"},d_.prototype.update=function(e){const t=this.showAllChromosomes?e.chromosomeNames.slice():e.wgChromosomeNames.slice();e.showWholeGenomeView()&&(t.unshift("all"),t.unshift("")),this.select.innerHTML="";for(let e of t){const t=document.createElement("option");t.setAttribute("value",e),t.innerText=e,this.select.appendChild(t)}};class f_{constructor(e,t){this.container=xr.div({class:"igv-windowsize-panel-container"}),e.appendChild(this.container),t.on("locuschange",(e=>{this.updatePanel(e)})),this.browser=t}show(){this.container.style.display="block"}hide(){this.container.style.display="none"}updatePanel(e){const t=this.browser.calculateViewportWidth(this.browser.referenceFrameList.length);this.container.innerText=1===e.length?Td(Math.round(t*e[0].bpPerPixel)):""}}class u_{constructor(e,t){this.browser=t,this.columnContainer=e,this.horizontalGuide=xr.div({class:"igv-cursor-guide-horizontal"}),e.appendChild(this.horizontalGuide),this.verticalGuide=xr.div({class:"igv-cursor-guide-vertical"}),e.appendChild(this.verticalGuide),this.addMouseHandler(t),this.setVisibility(t.config.showCursorGuide)}addMouseHandler(e){this.boundMouseMoveHandler=function(t){const{x:i,y:n}=xr.translateMouseCoordinates(t,this.columnContainer);this.horizontalGuide.style.top=`${n}px`;const o=function(e,t){for(;e.parentElement;){if(e.parentElement.classList.contains(t))return e.parentElement;e=e.parentElement}return}(document.elementFromPoint(t.clientX,t.clientY),"igv-viewport");if(o&&e.getRulerTrackView()){this.verticalGuide.style.left=`${i}px`;const n=e.root.querySelectorAll(".igv-column");let r;const a=o.parentElement;for(let e=0;e{e.cursorGuideVisible=!e.cursorGuideVisible,e.setCursorGuideVisibility(e.cursorGuideVisible),this.setButtonState(e.cursorGuideVisible)})),this.setButtonState(e.cursorGuideVisible),e.config.showCursorTrackingGuideButton?this.show():this.hide()}setButtonState(e){!0===e?this.button.classList.add("igv-navbar-button-clicked"):this.button.classList.remove("igv-navbar-button-clicked")}show(){this.button.style.display="block",this.setButtonState(this.browser.cursorGuideVisible)}hide(){this.button.style.display="none"}}class m_{constructor(e,t){this.browser=e,this.button=xr.div({class:"igv-navbar-button"}),t.appendChild(this.button),this.button.textContent="center line",this.button.addEventListener("click",(()=>{e.isCenterLineVisible=!e.isCenterLineVisible,e.setCenterLineVisibility(e.isCenterLineVisible),this.setButtonState(e.isCenterLineVisible)})),this.setButtonState(e.isCenterLineVisible),e.config.showCenterGuideButton?this.show():this.hide()}setButtonState(e){!0===e?this.button.classList.add("igv-navbar-button-clicked"):this.button.classList.remove("igv-navbar-button-clicked")}show(){this.isVisible=!0,this.button.style.display="block",this.setButtonState(this.browser.isCenterLineVisible)}hide(){this.isVisible=!1,this.button.style.display="none"}}class g_{constructor(e,t){this.button=xr.div({class:"igv-navbar-button"}),e.appendChild(this.button),this.button.textContent="track labels",this.button.addEventListener("click",(()=>{t.trackLabelsVisible=!t.trackLabelsVisible,this.setState(t.trackLabelsVisible),t.setTrackLabelVisibility(t.trackLabelsVisible)})),this.browser=t,this.setVisibility(t.config.showTrackLabelButton),this.setState(t.trackLabelsVisible)}setVisibility(e){!0===e?this.show():this.hide()}setState(e){!0===e?this.button.classList.add("igv-navbar-button-clicked"):this.button.classList.remove("igv-navbar-button-clicked")}show(){this.button.style.display="block",this.setState(this.browser.trackLabelsVisible)}hide(){this.button.style.display="none"}}class w_{constructor(e,t){this.button=xr.div({class:"igv-navbar-button"}),e.appendChild(this.button),this.button.innerText="Sample Names",this.setState(t.showSampleNames),this.setVisibility(t.showSampleNameButton),this.button.addEventListener("click",(()=>{t.showSampleNames=!t.showSampleNames,this.setState(t.showSampleNames);for(let{sampleNameViewport:e}of t.trackViews)!1===t.showSampleNames?e.hide():e.show();t.layoutChange()}))}setVisibility(e){!0===e?this.show():this.hide()}setState(e){!0===e?this.button.classList.add("igv-navbar-button-clicked"):this.button.classList.remove("igv-navbar-button-clicked")}hide(){this.button.style.display="none"}show(){this.button.style.display="block"}}let F_=23,b_=0;const v_=function(e,t){this.browser=e,this.zoomContainer=xr.div({class:"igv-zoom-widget"}),t.appendChild(this.zoomContainer),this.zoomOutButton=xr.div(),this.zoomContainer.appendChild(this.zoomOutButton),this.zoomOutButton.appendChild(xa.createIcon("minus-circle")),this.zoomOutButton.addEventListener("click",(()=>{e.zoomOut()}));const i=xr.div();this.zoomContainer.appendChild(i),this.slider=document.createElement("input"),this.slider.type="range",this.slider.min="0",this.slider.max=`${F_}`,i.appendChild(this.slider),this.slider.addEventListener("change",(t=>{t.preventDefault(),t.stopPropagation();const i=e.referenceFrameList[0],{bpLength:n}=i.genome.getChromosome(i.chr),{end:o,start:r}=i,a=o-r,s=n/Math.pow(2,t.target.valueAsNumber);e.zoomWithScaleFactor(s/a)})),this.zoomInButton=xr.div(),this.zoomContainer.appendChild(this.zoomInButton),this.zoomInButton.appendChild(xa.createIcon("plus-circle")),this.zoomInButton.addEventListener("click",(()=>{e.zoomIn()})),e.on("locuschange",(e=>{this.browser.isMultiLocusMode()?this.disable():(this.enable(),this.update(e))}))};v_.prototype.update=function(e){const t=e[0],{bpLength:i}=t.genome.getChromosome(t.chr),{start:n,end:o}=t;F_=Math.ceil(Math.log2(i/this.browser.minimumBases())),this.slider.max=`${F_}`;const r=i/(o-n);b_=Math.log2(r),this.slider.value=`${Math.round(b_)}`},v_.prototype.enable=function(){this.slider.disabled=!1},v_.prototype.disable=function(){this.slider.disabled=!0},v_.prototype.hide=function(){this.zoomContainer.style.display="none"},v_.prototype.show=function(){this.zoomContainer.style.display="block"},v_.prototype.hideSlider=function(){this.slider.style.display="none"},v_.prototype.showSlider=function(){this.slider.style.display="block"};const y_=function(e,t){const i=xr.div({class:"igv-navbar-button"});e.append(i),i.textContent="Save SVG",i.addEventListener("click",(()=>t.saveSVGtoFile({})))},__=(e,t)=>{const i=0===e?t.nextElementSibling:t.previousElementSibling;t.remove(),i.remove()},C_=e=>{const t=xr.div({class:"igv-column-shim"});Hd(t,e);const i=xr.div({class:"igv-column"});return Hd(i,t),i},x_=(e,t)=>{for(let i=0;i1&&i>0){Bd(xr.div({class:"igv-column-shim"}),n)}}};class k_{constructor(e,t,i){this.browser=e,this.referenceFrame=t,this.column=i,this.container=xr.div({class:"igv-center-line"}),i.appendChild(this.container),e.isCenterLineVisible?this.show():this.hide()}repaint(){if(this.referenceFrame){if(1/this.referenceFrame.bpPerPixel>1){const e=Math.floor(this.referenceFrame.toPixels(1));this.container.style.width=`${e}px`,this.container.classList.remove("igv-center-line-thin"),this.container.classList.add("igv-center-line-wide")}else this.container.style.width="1px",this.container.classList.remove("igv-center-line-wide"),this.container.classList.add("igv-center-line-thin")}}show(){this.isVisible=!0,this.container.style.display="block",this.repaint()}hide(){this.isVisible=!1,this.container.style.display="none"}resize(){this.repaint()}}const E_=Za;class N_{constructor(e){this.browser=e,this.height=40,this.name="",this.id="ruler",this.disableButtons=!0,this.ignoreTrackMenu=!0,this.order=.01*Number.MIN_SAFE_INTEGER,this.removable=!1,this.type="ruler"}async getFeatures(e,t,i){return[]}computePixelHeight(e){return this.height}draw({context:e,referenceFrame:t,pixelWidth:i,pixelHeight:n,bpPerPixel:o,bpStart:r}){Rf.isWholeGenomeView(t.chr)?this.drawWholeGenome({context:e,pixelWidth:i,pixelHeight:n,bpPerPixel:o}):this.doDraw({context:e,referenceFrame:t,pixelWidth:i,pixelHeight:n,bpStart:r})}drawWholeGenome({context:e,pixelWidth:t,pixelHeight:i,bpPerPixel:n}){e.save(),kd.fillRect(e,0,0,t,i,{fillStyle:"white"});for(let t of this.browser.genome.wgChromosomeNames){let o=this.browser.genome.getCumulativeOffset(t),r=this.browser.genome.getChromosome(t).bpLength,a=Math.round(o/n),s=Math.round(r/n);this.renderChromosomeRect(e,a,0,s,i,t)}e.restore()}doDraw({context:e,referenceFrame:t,pixelWidth:i,pixelHeight:n,bpStart:o}){e.clearRect(0,0,i,n);const r=function(e,t){if(e<10)return new S_(1,"bp",1);const i=Math.floor(Math.log10(e));let n="bp",o=1;i>9?(n="gb",o=1e9):i>6?(n="mb",o=1e6):i>3&&(n="kb",o=1e3);const r=Math.pow(10,i-1),a=e/r,s=75,c=Math.pow(10,i-1),l=Math.pow(10,i)/2;return new S_(a0&&f+c<=d&&(kd.fillText(e,i,n,this.height-8),d=0),l>0&&kd.strokeLine(e,l,this.height-6,l,this.height-2),h=Math.floor((1+a)*r.majorTick);let u=l+(Math.round(t.toPixels(h-1-o+.5))-l)/2;u>0&&kd.strokeLine(e,u,this.height-6,u,this.height-2),++a,d+=s}while(le.measureText(a).width&&kd.fillText(e,a,t+n/2,i+o/2,{fillStyle:qh.greyScale(68)})}get supportsWholeGenome(){return!0}dispose(){}}class S_{constructor(e,t,i){this.majorTick=e,this.minorTick=e/10,this.majorUnit=t,this.unitMultiplier=i}description(e){console.log((e||"")+" tick "+E_(this.majorTick)+" label width "+E_(this.labelWidthBP)+" multiplier "+this.unitMultiplier)}}const I_=function(e,t){this.button=xr.div({class:"igv-navbar-button"}),e.appendChild(this.button),this.button.textContent="circular view",this.button.addEventListener("click",(()=>{t.circularViewVisible=!t.circularViewVisible})),this.browser=t,this.setVisibility(t.config.showCircularViewButton),this.setState(t.circularViewVisible)};I_.prototype.setVisibility=function(e){!0===e?this.show():this.hide()},I_.prototype.setState=function(e){!0===e?this.button.classList.add("igv-navbar-button-clicked"):this.button.classList.remove("igv-navbar-button-clicked")},I_.prototype.show=function(){this.button.style.display="block",this.setState(this.browser.circularViewVisible)},I_.prototype.hide=function(){this.button.style.display="none"};const z_=function(e,t,i){const n=xr.div({class:"igv-navbar-button"});e.append(n),n.textContent=i.label,n.addEventListener("click",(()=>i.callback(t)))};class D_{constructor(e,t,i,n,o){this.browser=e,this.roiMenu=t,this.roiTable=i,this.top=n,this.roiSets=o||[],this.boundLocusChangeHandler=A_.bind(this),e.on("locuschange",this.boundLocusChangeHandler)}async initialize(){this.roiSets.length>0&&(this.browser.showROITableButton=!0,this.browser.roiTableControl.setVisibility(this.browser.showROITableButton));const e=this.roiSets.map((e=>this.renderROISet({browser:this.browser,pixelTop:this.top,roiSet:e})));e.length>0&&await Promise.all(e);const t=await this.getTableRecords();this.roiTable.renderTable(t)}async loadROI(e,t){const i=Array.isArray(e)?e:[e];for(let e of i)this.roiSets.push(new wm(e,t));await this.initialize()}clearROIs(){this.roiTable.clearTable();const e=this.browser.columnContainer.querySelectorAll(".igv-roi-region");for(let t of e)t.remove();for(let e of this.roiSets)e.dispose();this.roiSets=[]}async getTableRecords(){const e=[];for(let t of this.roiSets){const i=t.isUserDefined?"":t.name||"",n=await t.getAllFeatures();for(let t of Object.keys(n))for(let o of n[t])e.push({setName:i,feature:o})}return e}presentTable(){this.roiTable.present()}async repaintTable(){const e=await this.getTableRecords();this.roiTable.renderTable(e)}dismissTable(){this.roiTable.dismiss()}async updateUserDefinedROISet(e){let t=await this.getUserDefinedROISet();void 0===t&&(t=this.initializeUserDefinedROISet()),t.addFeature(e),!1===this.browser.showROITableButton&&this.setROITableButtonVisibility(!0),await this.renderROISet({browser:this.browser,pixelTop:this.top,roiSet:t});const i=await this.getTableRecords();this.roiTable.renderTable(i)}setROITableButtonVisibility(e){this.browser.showROITableButton=e,this.browser.roiTableControl.setVisibility(this.browser.showROITableButton)}async renderAllROISets(){for(let e of this.roiSets)await this.renderROISet({browser:this.browser,pixelTop:this.top,roiSet:e})}async renderROISet({browser:e,pixelTop:t,roiSet:i}){const n=e.columnContainer.querySelectorAll(".igv-column");for(let o=0;os)&&e.remove()}const h=await i.getFeatures(r,a,s);if(h)for(let l of h){const h=M_(r,l.start,l.end),{x:d,width:f}=Fm(Math.max(a,l.start),Math.min(s,l.end),a,c),u=n[o].querySelector(T_(h));if(u)u.style.left=`${d}px`,u.style.width=`${f}px`;else{const r=this.createRegionElement(e.columnContainer,t,d,f,i,h,l.name);n[o].appendChild(r)}}}}createRegionElement(e,t,i,n,o,r,a){const s=xr.div({class:"igv-roi-region"});s.style.top=`${t}px`,s.style.left=`${i}px`,s.style.width=`${n}px`,s.style.backgroundColor=o.color,s.dataset.region=r;const c=xr.div();return s.appendChild(c),c.style.backgroundColor=o.headerColor,!0===o.isUserDefined?c.addEventListener("click",(t=>{t.preventDefault(),t.stopPropagation();const{x:i,y:n}=xr.translateMouseCoordinates(t,e);this.roiMenu.present(i,n,this,e,s)})):a?c.addEventListener("click",(t=>{t.preventDefault(),t.stopPropagation(),this.popover&&this.popover.dispose(),this.popover=new Oa(e,o.name),this.popover.presentContentWithEvent(t,a)})):c.style.pointerEvents="none",s}renderSVGContext(e,{deltaX:t,deltaY:i}){for(const n of document.querySelectorAll(".igv-roi-region")){const{x:o,y:r,width:a,height:s}=n.getBoundingClientRect();e.fillStyle=n.style.backgroundColor,e.fillRect(o+t,r+i,a,s);const c=n.querySelector("div"),{x:l,y:h,width:d,height:f}=c.getBoundingClientRect();e.fillStyle=c.style.backgroundColor,e.fillRect(l+t,h+i,d,f)}}async getUserDefinedROISet(){return this.roiSets.find((e=>!0===e.isUserDefined))}initializeUserDefinedROISet(){const e=new wm({isUserDefined:!0,features:[]},this.browser.genome);return this.roiSets.push(e),e}async deleteUserDefinedRegionWithKey(e,t){t.querySelectorAll(T_(e)).forEach((e=>e.remove()));const i=await this.findUserDefinedRegionWithKey(e),n=await this.getUserDefinedROISet();n&&n.removeFeature(i);0===(await this.getTableRecords()).length&&(this.browser.roiTableControl.buttonHandler(!1),this.setROITableButtonVisibility(!1))}async findUserDefinedRegionWithKey(e){const{chr:t,start:i,end:n}=R_(e),o=await this.getUserDefinedROISet();if(o){const e=await o.getFeatures(t,i,n);for(let o of e)if(o.chr===t&&o.start>=i&&o.end<=n)return o}}toJSON(){return this.roiSets.map((e=>e.toJSON()))}dispose(){this.browser.off("locuschange",this.boundLocusChangeHandler);const e=this.browser.columnContainer.querySelectorAll(".igv-roi-region");for(let t of e)t.remove();this.roiMenu&&this.roiMenu.dispose(),this.roiTable&&this.roiTable.dispose();for(let e of this.roiSets)e.dispose();for(let e of Object.keys(this))this[e]=void 0}}function A_(){this.renderAllROISets()}function M_(e,t,i){return`${e}-${t}-${i}`}function T_(e){return`[data-region="${e}"]`}function R_(e){let[t,i,n]=e.split("-");return i=parseInt(i),n=parseInt(n),{chr:t,start:i,end:n,locus:`${t}:${i}-${n}`,bedRecord:`${t}\t${i}\t${n}`}}class L_ extends rw{constructor(e){super(Object.assign({width:"512px"},e))}tableRowDOM(e){const t=xr.div({class:"igv-roi-table-row"}),{setName:i,feature:n}=e;t.dataset.region=M_(n.chr,n.start,n.end);let o=[n.chr,Za(n.start),Za(n.end),n.name||"",i];4===this.columnFormat.length&&(o=o.slice(0,4));for(let e=0;ee.remove())),e.length>0){const t=e.sort(((e,t)=>e.feature.chr.localeCompare(t.feature.chr)||e.feature.start-t.feature.start||e.feature.end-t.feature.end));for(let e of t){const t=this.tableRowDOM(e);this.tableRowContainer.appendChild(t)}}}dispose(){document.removeEventListener("click",this.boundGotoButtonHandler),this.browser.roiTableControl.buttonHandler(!1),super.dispose()}static getColumnFormatConfiguration(e){return!0===e?[{label:"Chr",width:"20%"},{label:"Start",width:"15%"},{label:"End",width:"15%"},{label:"Description",width:"30%"},{label:"ROI Set",width:"20%"}]:[{label:"Chr",width:"25%"},{label:"Start",width:"20%"},{label:"End",width:"20%"},{label:"Description",width:"35%"}]}static gotoButtonHandler(e){e.stopPropagation();const t=this.tableDOM.querySelectorAll(".igv-roi-table-row-selected"),i=[];for(let e of t){const{locus:t}=R_(e.dataset.region);i.push(t)}for(let e of this.tableDOM.querySelectorAll(".igv-roi-table-row"))e.classList.remove("igv-roi-table-row-selected");this.setTableRowSelectionState(!1),i.length>0&&this.browser.search(i.join(" "))}}class B_{constructor(e,t){this.browser=e,this.container=xr.div({class:"igv-roi-menu-next-gen"}),t.appendChild(this.container);const i=xr.div();this.container.appendChild(i),Ea.attachDialogCloseHandlerWithParent(i,(()=>this.container.style.display="none")),this.body=xr.div(),this.container.appendChild(this.body),this.container.style.display="none"}async present(e,t,i,n,o){H_(this.body);const r=await this.browser.roiManager.findUserDefinedRegionWithKey(o.dataset.region),a=xr.div();this.body.appendChild(a);const s="Description",c=r.name||s;a.innerText=c,a.setAttribute("title",c),s===c?a.classList.add("igv-roi-placeholder"):a.classList.remove("igv-roi-placeholder");const l=xr.div();this.body.appendChild(l),l.innerText="Set Description",l.addEventListener("click",(e=>{e.stopPropagation(),this.container.style.display="none";const t={label:"Description",value:r.name||"",callback:()=>{const e=this.browser.inputDialog.value||"";r.name=e.trim(),this.container.style.display="none",this.browser.roiManager.repaintTable()}};this.browser.inputDialog.present(t,e)}));const h=xr.div();this.body.appendChild(h),h.innerText="Delete Region",h.addEventListener("click",(e=>{e.stopPropagation(),this.container.style.display="none",this.browser.roiManager.deleteUserDefinedRegionWithKey(o.dataset.region,this.browser.columnContainer)})),this.container.style.left=`${e}px`,this.container.style.top=`${t}px`,this.container.style.display="flex"}async __present(e,t,i,n,o){H_(this.container);const r=await this.browser.roiManager.findUserDefinedRegionWithKey(o.dataset.region);let a;a=xr.div({class:"igv-roi-menu-row-edit-description"}),this.container.appendChild(a),a.addEventListener("click",(e=>{e.stopPropagation()}));const s="description-input",c=document.createElement("label");a.appendChild(c),c.setAttribute("for",s),c.innerText="Description:";const l=document.createElement("input");a.appendChild(l),l.setAttribute("type","text"),l.setAttribute("name",s),l.setAttribute("placeholder",""),l.value=r.name||"",l.addEventListener("change",(async e=>{e.stopPropagation();(await this.browser.roiManager.findUserDefinedRegionWithKey(o.dataset.region)).name=l.value,l.blur(),this.container.style.display="none",await this.browser.roiManager.repaintTable()})),a=xr.div({class:"igv-roi-menu-row"}),a.innerText="Delete region",this.container.appendChild(a),a.addEventListener("click",(e=>{e.stopPropagation(),this.container.style.display="none",this.browser.roiManager.deleteUserDefinedRegionWithKey(o.dataset.region,this.browser.columnContainer)})),this.container.style.left=`${e}px`,this.container.style.top=`${t}px`,this.container.style.display="flex",n.addEventListener("click",(e=>{e.stopPropagation(),this.container.style.display="none"}))}dispose(){this.container.innerHTML=""}}function H_(e){for(;e.firstChild;)e.removeChild(e.firstChild)}class O_{constructor(e,t){this.name=e.name,this.featureSource=e.featureSource||pm(e,t),this.color=e.color||mm}async getFeatures(e,t,i){return this.featureSource.getFeatures({chr:e,start:t,end:i})}draw(e){const{context:t,bpPerPixel:i,bpStart:n,pixelTop:o,pixelHeight:r,pixelWidth:a,features:s}=e;if(!s)return;const c=n+a*i+1;for(let{start:e,end:a}of s){if(ac)break;const{x:s,width:l}=Fm(e,a,n,i);kd.fillRect(t,s,o,l,r,{fillStyle:this.color})}}}class P_{constructor(e,t){this.browser=t,this.button=xr.div({class:"igv-navbar-button"}),e.appendChild(this.button),this.button.textContent="ROI Table",this.button.addEventListener("click",(()=>{this.buttonHandler(!t.roiTableVisible)})),this.browser=t,this.setVisibility(t.showROITableButton),this.setState(t.roiTableVisible)}buttonHandler(e){this.browser.roiTableVisible=e,this.setState(this.browser.roiTableVisible),this.browser.setROITableVisibility(this.browser.roiTableVisible)}setVisibility(e){!0===e?this.show():this.hide()}setState(e){!0===e?this.button.classList.add("igv-navbar-button-clicked"):this.button.classList.remove("igv-navbar-button-clicked")}show(){this.button.style.display="block",this.setState(this.browser.roiTableVisible)}hide(){this.button.style.display="none"}}class q_{constructor(e,t){this.config=e,this.guid=xr.guid(),this.namespace=".browser_"+this.guid,this.parent=t,this.root=xr.div({class:"igv-container"}),t.appendChild(this.root),this.alert=new Nd(this.root),this.columnContainer=xr.div({class:"igv-column-container"}),this.root.appendChild(this.columnContainer),this.menuPopup=new Nw(this.columnContainer),this.initialize(e),this.trackViews=[],this.constants={dragThreshold:3,scrollThreshold:5,defaultColor:"rgb(0,0,150)",doubleClickDelay:e.doubleClickDelay||500},this.eventHandlers={},this.addMouseHandlers(),this.setControls(e)}initialize(e){e.gtex&&(Zg.gtexLoaded=!0),this.flanking=e.flanking,this.crossDomainProxy=e.crossDomainProxy,this.formats=e.formats,this.trackDefaults=e.trackDefaults,this.nucleotideColors=e.nucleotideColors||uf;for(let e of Object.keys(this.nucleotideColors))this.nucleotideColors[e.toLowerCase()]=this.nucleotideColors[e];this.trackLabelsVisible=e.showTrackLabels,this.roiTableVisible=e.showROITable,this.showROITableButton=e.showROITableButton,this.isCenterLineVisible=e.showCenterGuide,this.cursorGuideVisible=e.showCursorGuide,this.showSampleNames=e.showSampleNames,this.showSampleNameButton=e.showSampleNameButton,this.sampleNameViewportWidth=e.sampleNameViewportWidth||200,e.search&&(this.searchConfig={type:"json",url:e.search.url,coords:void 0===e.search.coords?1:e.search.coords,chromosomeField:e.search.chromosomeField||"chromosome",startField:e.search.startField||"start",endField:e.search.endField||"end",geneField:e.search.geneField||"gene",snpField:e.search.snpField||"snp",resultsField:e.search.resultsField})}setControls(e){const t=this.createStandardControls(e);t.insertBefore(wr(this.columnContainer)),this.$navigation=t,!1===e.showControls&&t.hide()}createStandardControls(e){this.navbarManager=new h_(this);const t=wr("
",{class:"igv-navbar"});this.$navigation=t;const i=wr("
",{class:"igv-navbar-left-container"});t.append(i);const n=wr("
",{class:"igv-logo"});i.append(n);const o=wr('IGV; ');o.css("width","34px"),o.css("height","32px"),n.append(o),this.$current_genome=wr("
",{class:"igv-current-genome"}),i.append(this.$current_genome),this.$current_genome.text("");const r=wr("
",{class:"igv-navbar-genomic-location"});i.append(r),this.chromosomeSelectWidget=new d_(this,r.get(0)),void 0===e.showChromosomeWidget&&(e.showChromosomeWidget=!0),!0===e.showChromosomeWidget?this.chromosomeSelectWidget.show():this.chromosomeSelectWidget.hide();const a=wr("
",{class:"igv-locus-size-group"});r.append(a);const s=wr("
",{class:"igv-search-container"});a.append(s),this.$searchInput=wr("",{class:"igv-search-input",type:"text",placeholder:"Locus Search"}),s.append(this.$searchInput),this.$searchInput.change((()=>this.doSearch(this.$searchInput.val())));const c=xr.div({class:"igv-search-icon-container"});s.append(wr(c)),c.appendChild(xa.createIcon("search")),c.addEventListener("click",(()=>this.doSearch(this.$searchInput.val()))),this.windowSizePanel=new f_(a.get(0),this);const l=wr("
",{class:"igv-navbar-right-container"});t.append(l);const h=wr('
');if(l.append(h),this.$toggle_button_container=h,this.cursorGuide=new u_(this.columnContainer,this),this.cursorGuideButton=new p_(this,h.get(0)),this.centerLineButton=new m_(this,h.get(0)),this.setTrackLabelVisibility(e.showTrackLabels),this.trackLabelControl=new g_(h.get(0),this),this.roiTableControl=new P_(h.get(0),this),this.sampleNameControl=new w_(h.get(0),this),!0===e.showSVGButton&&(this.svgSaveControl=new y_(h.get(0),this)),e.customButtons)for(let t of e.customButtons)new z_(h.get(0),this,t);return this.zoomWidget=new v_(this,l.get(0)),!1===e.showNavigation&&this.$navigation.hide(),this.inputDialog=new Ma(this.root),this.inputDialog.container.id=`igv-input-dialog-${xr.guid()}`,this.dataRangeDialog=new Ga(this,wr(this.root)),this.dataRangeDialog.$container.get(0).id=`igv-data-range-dialog-${xr.guid()}`,this.genericColorPicker=new qa({parent:this.columnContainer,width:432}),this.genericColorPicker.container.id=`igv-track-color-picker-${xr.guid()}`,t}getSampleNameViewportWidth(){return!1===this.showSampleNames?0:this.sampleNameViewportWidth}isMultiLocusMode(){return this.referenceFrameList&&this.referenceFrameList.length>1}addTrackToFactory(e,t){Jy(e,t)}isMultiLocusWholeGenomeView(){if(void 0===this.referenceFrameList||1===this.referenceFrameList.length)return!1;for(let e of this.referenceFrameList)if("all"===e.chr.toLowerCase())return!0;return!1}currentLoci(){const e=e=>`${e.chr}:${e.start+1}-${e.end}`;return void 0===this.referenceFrameList||0===this.referenceFrameList.length?"":1===this.referenceFrameList.length?e(this.referenceFrameList[0]):this.referenceFrameList.map((t=>e(t)))}toSVG(){const{y:e,width:t,height:i}=this.columnContainer.getBoundingClientRect(),n=new Df({width:t,height:8e3,backdropColor:"white",multiLocusGap:0,viewbox:{x:0,y:0,width:t,height:8e3}}),o={deltaX:0,deltaY:-e};for(let e of this.trackViews)e.renderSVGContext(n,o);return this.roiManager.renderSVGContext(n,o),n.setHeight(i),n.getSerializedSvg(!0)}renderSVG(e){const t=this.toSVG();return e.empty(),e.append(t),t}saveSVGtoFile(e){let t=this.toSVG();e.$container&&(e.$container.empty(),e.$container.append(t));es(e.filename||"igvjs.svg",URL.createObjectURL(new Blob([t],{type:"application/octet-stream"})))}async loadSession(e){let t;return this.roiSets=[],t=e.url||e.file?await async function(e){const t=e.url||e.file;if(e.url&&(e.url.startsWith("blob:")||e.url.startsWith("data:"))){const t=q_.uncompressSession(e.url);return JSON.parse(t)}{let i=e.filename;if(i||(i=e.url?await Md(e.url):e.file.name),i.endsWith(".xml")){const e=Rf.KNOWN_GENOMES,i=await ad.loadString(t);return new t_(i,e)}return i.endsWith(".json")?ad.loadJson(t):void 0}}(e):e,this.loadSessionObject(t)}async loadSessionObject(e){this.cleanHouseForSession(),this.showSampleNames=e.showSampleNames||!1,this.sampleNameControl.setState(!0===this.showSampleNames),e.sampleNameViewportWidth&&(this.sampleNameViewportWidth=e.sampleNameViewportWidth),Ld(this.columnContainer,"igv-axis-column"),Ld(this.columnContainer,"igv-sample-name-column"),Ld(this.columnContainer,"igv-scrollbar-column"),Ld(this.columnContainer,"igv-track-drag-column"),Ld(this.columnContainer,"igv-gear-menu-column");const t=e.reference||e.genome;if(!t)return void console.warn("No genome or reference object specified");const i=await Rf.expandReference(this.alert,t);await this.loadReference(i,e.locus),this.centerLineList=this.createCenterLineList(this.columnContainer);let n=0;if(!1!==e.showIdeogram){const e=new sF(this);e.id="ideogram";const t=new Dw(this,this.columnContainer,e),{$viewport:i}=t.viewports[0];n=function(e){e="string"==typeof e?document.querySelector(e):e;const t=window.getComputedStyle(e),i=parseFloat(t.marginTop)+parseFloat(t.marginBottom),n=e.offsetHeight;return Math.ceil(i+n)}(i.get(0)),this.trackViews.push(t)}if(!1!==e.showRuler&&this.trackViews.push(new Dw(this,this.columnContainer,new N_(this))),e.gtexSelections)for(let t of this.referenceFrameList)for(let i of Object.keys(e.gtexSelections)){const n=e.gtexSelections[i].gene,o=e.gtexSelections[i].snp;t.selection=new r_(n,o)}this.roiManager&&this.roiManager.dispose();const o=new B_(this,this.columnContainer),r={browser:this,parent:this.columnContainer,headerTitle:"Regions of Interest",dismissHandler:()=>this.roiTableControl.buttonHandler(!1),gotoButtonHandler:L_.gotoButtonHandler};if(e.roi){const t=e.roi.map((e=>new wm(e,this.genome))),i=t.filter((({name:e})=>void 0!==e&&e.length>0));r.columnFormat=L_.getColumnFormatConfiguration(i.length>0);const a=new L_(r);this.roiManager=new D_(this,o,a,n,t)}else{r.columnFormat=L_.getColumnFormatConfiguration(!1);const e=new L_(r);this.roiManager=new D_(this,o,e,n,void 0)}await this.roiManager.initialize();const a=i.tracks||[],s=e.tracks?a.concat(e.tracks):a;0===s.filter((e=>"sequence"===e.type&&!e.url&&!e.fastaURL)).length&&s.push({type:"sequence",order:pf});let c=1;for(let e of s)void 0===e.order&&(e.order=c++);await this.loadTrackList(s);for(let e of this.trackViews.filter((e=>"ruler"===e.track.type||"ideogram"===e.track.type)))e.updateViews();this.updateUIWithReferenceFrameList()}createCenterLineList(e){const t=e.querySelectorAll(".igv-center-line");for(let e=0;ee.remove())),this.trackViews=[],this.circularView&&this.circularView.clearChords()}updateNavbarDOMWithGenome(e){let t=e.id&&e.id.length<10?e.id:"";this.$current_genome.text(t),this.$current_genome.attr("title",e.id||""),this.chromosomeSelectWidget.update(e)}async loadGenome(e){const t=await Rf.expandReference(this.alert,e);await this.loadReference(t,void 0);const i=t.tracks||[];return 0===i.filter((e=>"sequence"===e.type)).length&&i.push({type:"sequence",order:pf}),await this.loadTrackList(i),await this.updateViews(),this.genome}updateUIWithReferenceFrameList(){const e=this.referenceFrameList;this.updateLocusSearchWidget();const t=this.isMultiLocusWholeGenomeView()||Rf.isWholeGenomeView(e[0].chr);this.navbarManager.navbarDidResize(this.$navigation.width(),t),W_(this.trackViews,this.trackLabelsVisible),this.setCenterLineAndCenterLineButtonVisibility(!Rf.isWholeGenomeView(e[0].chr))}setTrackLabelVisibility(e){W_(this.trackViews,e)}setROITableVisibility(e){!0===e?this.roiManager.presentTable():this.roiManager.dismissTable()}setCursorGuideVisibility(e){e?this.cursorGuide.show():this.cursorGuide.hide()}setCustomCursorGuideMouseHandler(e){this.cursorGuide.customMouseHandler=e}setCenterLineVisibility(e){for(let t of this.centerLineList)!0===e?(t.show(),t.repaint()):t.hide()}setCenterLineAndCenterLineButtonVisibility(e){for(let t of this.centerLineList){e&&t.isVisible?t.show():t.container.style.display="none"}e&&this.centerLineButton.isVisible?this.centerLineButton.show():this.centerLineButton.button.style.display="none"}async loadTrackList(e){const t=[];for(let i of e)t.push(this._loadTrack(i));const i=await Promise.all(t);return this.trackViews.filter((function(e){return e.track.autoscaleGroup})).length>0&&this.updateViews(),i}async loadTrack(e){const t=this._loadTrack(e);return e.autoscaleGroup&&(await t,this.updateViews()),t}async _loadTrack(e){$a(e)&&(e=JSON.parse(e));try{const t=await this.createTrack(e);if(void 0===t)return;void 0===t.order&&(t.order=this.trackViews.length);const i=new Dw(this,this.columnContainer,t);if(this.trackViews.push(i),W_(this.trackViews,this.trackLabelsVisible),this.reorderTracks(),this.fireEvent("trackorderchanged",[this.getTrackOrder()]),"function"==typeof t.postInit)try{i.startSpinner(),await t.postInit()}finally{i.stopSpinner()}return t.autoscaleGroup||(e.sync?await i.updateViews():i.updateViews()),"function"==typeof t.hasSamples&&t.hasSamples()&&!1!==this.config.showSampleNameButton&&this.sampleNameControl.show(),t}catch(t){const i={401:"Access unauthorized",403:"Access forbidden",404:"Not found"};console.error(t);let n=t.message||t.error||t.toString();i.hasOwnProperty(n)&&(n=i[n]),n+=": "+e.url,this.alert.present(new Error(n),void 0)}}async loadROI(e){await this.roiManager.loadROI(e,this.genome)}clearROIs(){this.roiManager.clearROIs()}async getUserDefinedROIs(){if(this.roiManager){const e=await this.roiManager.getUserDefinedROISet();if(void 0===e)return[];const t=await e.getAllFeatures(),i=[];for(let e of Object.values(t))i.push(...e);return i}return[]}getRulerTrackView(){const e=this.trackViews.filter((({track:e})=>"ruler"===e.id));return e.length>0?e[0]:void 0}async createTrack(e){let t=await async function(e){return"function"==typeof e?e():e} -/*! pako 2.1.0 https://github.com/nodeca/pako @license (MIT AND Zlib) */(e.url||e.fastaURL);if($a(t)&&(t=t.trim()),t)if(e.format)e.format=e.format.toLowerCase();else if(e.fastaURL)e.format="fasta";else{let i=e.filename;i||(i=await Md(t));const n=Wd(i);"tsv"===n?e.format=await Zd(e):n?e.format=n:"htsget"===e.sourceType&&await Tp.inferFormat(e)}let i=e.type?e.type.toLowerCase():void 0;if(!i){if(i=$d(e),"bedtype"===i){const t=pm(e,this.genome);e._featureSource=t;const n=await t.trackType();i=n||"annotation"}e.type=i}if(this.trackDefaults&&i){const t=this.trackDefaults[i];if(t)for(let i in t)t.hasOwnProperty(i)&&void 0===e[i]&&(e[i]=t[i])}const n=e_(i,e,this);if(void 0!==n)return e.roi&&e.roi.length>0&&(n.roiSets=e.roi.map((e=>new O_(e,this.genome)))),n;this.alert.present(new Error(`Error creating track. Could not determine track type for file: ${e.url||e}`),void 0)}reorderTracks(){this.trackViews.sort((function(e,t){const i=e=>"ideogram"===e.track.id?1:"ruler"===e.track.id?2:3,n=i(e),o=i(t);if(n===o){return(e.track.order||0)-(t.track.order||0)}return n-o}));for(let{axis:e,viewports:t,sampleNameViewport:i,outerScroll:n,dragHandle:o,gearContainer:r}of this.trackViews){e.remove();for(let{$viewport:e}of t)e.detach();i.viewport.remove(),n.remove(),o.remove(),r.remove()}const e=this.columnContainer.querySelectorAll(".igv-column");for(let{axis:t,viewports:i,sampleNameViewport:n,outerScroll:o,dragHandle:r,gearContainer:a}of this.trackViews){this.columnContainer.querySelector(".igv-axis-column").appendChild(t);for(let t=0;te.track&&e.track.name)).map((e=>e.track.name))}removeTrackByName(e){const t=this.trackViews.slice();for(let i of t)e===i.track.name&&this.removeTrack(i.track)}removeTrack(e){for(let t of this.trackViews)if(e===t.track){this._removeTrack(t.track);break}}_removeTrack(e){e.disposed||(this.trackViews.splice(this.trackViews.indexOf(e.trackView),1),this.fireEvent("trackremoved",[e]),this.fireEvent("trackorderchanged",[this.getTrackOrder()]),e.trackView&&e.trackView.dispose())}removeAllTracks(){const e=[];for(let t of this.trackViews)"ruler"!==t.track.id&&"ideogram"!==t.track.id?(this.fireEvent("trackremoved",[t.track]),t.dispose()):e.push(t);this.trackViews=e}findTracks(e,t){let i="function"==typeof e?t=>e(t.track):i=>t===i.track[e];return this.trackViews.filter(i).map((e=>e.track))}setTrackHeight(e){this.trackHeight=e,this.trackViews.forEach((function(t){t.setTrackHeight(e)}))}async visibilityChange(){this.layoutChange()}async layoutChange(){if(this.referenceFrameList.find((e=>e.bpPerPixel<0))){const e=this.calculateViewportWidth(this.referenceFrameList.length);for(let t of this.referenceFrameList)t.bpPerPixel=(t.end-t.start)/e}if(this.referenceFrameList){const e=this.isMultiLocusWholeGenomeView()||Rf.isWholeGenomeView(this.referenceFrameList[0].chr);this.navbarManager.navbarDidResize(this.$navigation.width(),e)}V_.call(this),await this.updateViews()}async updateViews(){const e=this.trackViews;this.updateLocusSearchWidget();for(let e of this.centerLineList)e.repaint();if(this.dragObject)for(let t of e)await t.updateViews();else{const o={},r=[];for(let i of e){const e=i.track.autoscaleGroup;if(e){var t=o[e];t||(t=[],o[e]=t),t.push(i)}else r.push(i)}if(Object.entries(o).length>0){const e=Object.keys(o);for(let t of e){const e=o[t],r=[];for(let t of e)r.push(t.getInViewFeatures());const a=await Promise.all(r);var i,n=[];for(let e of a)n=n.concat(e);i=Dd(n);const s=[];for(let t of e)t.track.dataRange=i,t.track.autoscale=!1,s.push(t.updateViews());await Promise.all(s)}}await Promise.all(r.map((e=>e.updateViews())))}}repaintViews(){for(let e of this.trackViews)e.repaintViews()}updateLocusSearchWidget(){if(!this.referenceFrameList)return;const e=this.referenceFrameList,t=this.calculateViewportWidth(this.referenceFrameList.length);for(let i of e)i.end=i.start+i.bpPerPixel*t;this.chromosomeSelectWidget.select.value=1===e.length?this.referenceFrameList[0].chr:"";const i=this.referenceFrameList.map((e=>e.getLocusString())).join(" ");this.$searchInput.val(i),this.fireEvent("locuschange",[this.referenceFrameList])}calculateViewportWidth(e){let{width:t}=this.columnContainer.getBoundingClientRect();return t-=50+this.getSampleNameViewportWidth()+14+12+28,t-=5*(e-1),Math.floor(t/e)}getCenterLineXOffset(){let{width:e}=this.columnContainer.getBoundingClientRect();return e-=50+this.getSampleNameViewportWidth()+14+12+28,Math.floor(e/2+50)}minimumBases(){return this.config.minimumBases}zoomIn(){this.zoomWithScaleFactor(.5)}zoomOut(){this.zoomWithScaleFactor(2)}async zoomWithScaleFactor(e,t,i){if(!this.referenceFrameList)return;const n=this.calculateViewportWidth(this.referenceFrameList.length);let o=i?[i]:this.referenceFrameList;for(let i of o)i.zoomWithScaleFactor(this,e,n,t)}async addMultiLocusPanel(e,t,i,n){if(!this.referenceFrameList)return;const o=this.calculateViewportWidth(1+this.referenceFrameList.length),r=this.calculateViewportWidth(this.referenceFrameList.length)/this.calculateViewportWidth(1+this.referenceFrameList.length);for(let e of this.referenceFrameList)e.bpPerPixel*=r;const a=(i-t)/o,s=new s_(this.genome,e,t,i,a),c=n?this.referenceFrameList.indexOf(n):this.referenceFrameList.length-1,l=1+c,{$viewport:h}=this.trackViews[0].viewports[c],d=C_(h.get(0).parentElement);if(l===this.referenceFrameList.length){this.referenceFrameList.push(s);for(let e of this.trackViews){const t=Cw(e,d,s);e.viewports.push(t)}}else{this.referenceFrameList.splice(l,0,s);for(let e of this.trackViews){const t=Cw(e,d,s);e.viewports.splice(l,0,t)}}this.centerLineList=this.createCenterLineList(this.columnContainer),V_.call(this),await this.updateViews(!0)}async removeMultiLocusPanel(e){const t=this.referenceFrameList.indexOf(e),{$viewport:i}=this.trackViews[0].viewports[t];__(t,i.parent().get(0));for(let{viewports:e}of this.trackViews)e[t].dispose(),e.splice(t,1);if(this.referenceFrameList.splice(t,1),1===this.referenceFrameList.length&&this.getRulerTrackView())for(let e of this.getRulerTrackView().viewports)e.dismissLocusLabel();const n=this.calculateViewportWidth(1+this.referenceFrameList.length)/this.calculateViewportWidth(this.referenceFrameList.length);await this.rescaleForMultiLocus(n)}async gotoMultilocusPanel(e){const t=this.referenceFrameList.indexOf(e);this.columnContainer.querySelectorAll(".igv-column").forEach(((e,i)=>{i===t||e.remove()})),this.columnContainer.querySelectorAll(".igv-column-shim").forEach((e=>e.remove()));for(let e of this.trackViews){const i=e.viewports[t];e.viewports.filter(((e,i)=>i!==t)).forEach((e=>e.dispose())),e.viewports=[i]}const i=this.calculateViewportWidth(1);e.bpPerPixel=(e.end-e.start)/i,this.referenceFrameList=[e],this.trackViews.forEach((({viewports:e})=>e.forEach((e=>e.setWidth(i))))),this.centerLineList=this.createCenterLineList(this.columnContainer),this.updateUIWithReferenceFrameList(),await this.updateViews(!0)}async rescaleForMultiLocus(e){const t=this.calculateViewportWidth(this.referenceFrameList.length);for(let t of this.referenceFrameList)t.bpPerPixel*=e;for(let{viewports:e}of this.trackViews)for(let i of e)i.setWidth(t);this.centerLineList=this.createCenterLineList(this.columnContainer),this.updateUIWithReferenceFrameList(),await this.updateViews()}async goto(e,t,i){await this.search(e+":"+t+"-"+i)}async doSearch(e,t){const i=await this.search(e,t);return i||this.alert.present(new Error(`Unrecognized locus: ${e} `)),i}async search(e,t){const i=await l_(this,e);if(i&&i.length>0){this.referenceFrameList=function(e,t,i,n,o,r){return e.map((e=>{if(i&&e.gene&&(e.start=Math.max(0,e.start-i),e.end+=i),!r){const i=t.getChromosome(e.chr);Ad(i.bpLength,e,n)}const a=new s_(t,e.chr,e.start,e.end,(e.end-e.start)/o);return a.locusSearchString=e.locusSearchString,(e.gene||e.snp)&&(a.selection=new r_(e.gene,e.snp)),a}))}(i,this.genome,this.flanking,this.minimumBases(),this.calculateViewportWidth(i.length),this.isSoftclipped());for(let e of this.trackViews)e.removeDOMFromColumnContainer();this.columnContainer.querySelectorAll(".igv-column-shim, .igv-column").forEach((e=>e.remove())),x_(this.columnContainer.querySelector(".igv-sample-name-column"),this.referenceFrameList.length),this.centerLineList=this.createCenterLineList(this.columnContainer);for(let e of this.trackViews)e.addDOMToColumnContainer(this,this.columnContainer,this.referenceFrameList);return this.updateUIWithReferenceFrameList(),t||await this.updateViews(),!0}return!1}async loadSampleInformation(e){var t=e;Ja(e)&&(t=e.name),"fam"===t.substr(t.lastIndexOf(".")+1)&&(this.sampleInformation=await function(e,t){return(new o_).loadPlinkFile(e,t)}(e))}on(e,t){this.eventHandlers[e]||(this.eventHandlers[e]=[]),this.eventHandlers[e].push(t)}un(e,t){this.off(e,t)}off(e,t){if(e)if(t){const i=this.eventHandlers[e];if(i&&0!==i.length){const n=i.indexOf(t);-1!==n&&this.eventHandlers[e].splice(n,1)}else console.warn("No handlers to remove for event: "+e)}else this.eventHandlers[e]=[];else this.eventHandlers={}}fireEvent(e,t,i){const n=this.eventHandlers[e];if(void 0===n||0===n.length)return;const o=i||window;return n.map((function(e){return e.apply(o,t)}))[0]}dispose(){this.removeMouseHandlers();for(let e of this.trackViews)e.dispose()}toJSON(){const e={version:"2.15.13"};if(void 0!==this.showSampleNames&&(e.showSampleNames=this.showSampleNames),200!==this.sampleNameViewportWidth&&(e.sampleNameViewportWidth=this.sampleNameViewportWidth),e.reference=this.genome.toJSON(),e.reference.fastaURL instanceof File)throw new Error(`Error. Sessions cannot include local file references ${e.reference.fastaURL.name}.`);if(e.reference.indexURL instanceof File)throw new Error(`Error. Sessions cannot include local file references ${e.reference.indexURL.name}.`);const t=[],i={};let n=!1,o=this.trackViews[0];for(let{referenceFrame:e}of o.viewports){const o=e.getLocusString();if(t.push(o),e.selection){const t={gene:e.selection.gene,snp:e.selection.snp};i[o]=t,n=!0}}e.locus=1===t.length?t[0]:t,n&&(e.gtexSelections=i),e.roi=this.roiManager.toJSON();const r=[],a=[];for(let{track:e}of this.trackViews)try{let t;t="function"==typeof e.getState?e.getState():e.config,t&&(t.browser&&delete t.browser,t.order=e.order,r.push(t))}catch(t){console.error(`Track: ${e.name}: ${t}`),a.push(`Track: ${e.name}: ${t}`)}if(a.length>0){let e=1,t="Errors encountered saving session:
";for(let i of a)t+=` (${e++}) ${i.toString()}
`;throw Error(t)}return e.tracks=r,e}compressedSession(){return function(e){const t=new Uint8Array(e.length);for(var i=0;i0?e.substring(0,t):e)+"?sessionURL=blob:"+this.compressedSession()}mouseDownOnViewport(e,t){var i;i=xr.pageCoordinates(e),this.vpMouseDown={viewport:t,lastMouseX:i.x,mouseDownX:i.x,lastMouseY:i.y,mouseDownY:i.y,referenceFrame:t.referenceFrame}}cancelTrackPan(){const e=this.dragObject;this.dragObject=void 0,this.isScrolling=!1,this.vpMouseDown=void 0,e&&e.viewport.referenceFrame.start!==e.start&&(this.updateViews(),this.fireEvent("trackdragend"))}isTrackPanning(){return this.dragObject}isSoftclipped(){return void 0!==this.trackViews.find((e=>!0===e.track.showSoftClips))}startTrackDrag(e){this.dragTrack=e}updateTrackDrag(e){if(e&&this.dragTrack){const t=this.dragTrack,i=this.trackViews.indexOf(e),n=this.trackViews.indexOf(t),o=this.trackViews;o[i]=t,o[n]=e;const r=this.trackViews[i].track.order;this.trackViews[n].track.order=r;const a=o.length;let s=r;if(i0;e--){const t=o[e].track;if(!(t.order>=s))break;t.order=Math.max(-Number.MAX_SAFE_INTEGER,s-1),s=t.order}this.reorderTracks()}}endTrackDrag(){this.dragTrack?(this.dragTrack=void 0,this.fireEvent("trackorderchanged",[this.getTrackOrder()])):this.dragTrack=void 0}addMouseHandlers(){this.addWindowResizeHandler(),this.addRootMouseUpHandler(),this.addRootMouseLeaveHandler(),this.addColumnContainerEventHandlers()}removeMouseHandlers(){this.removeWindowResizeHandler(),this.removeRootMouseUpHandler(),this.removeRootMouseLeaveHandler(),this.removeColumnContainerEventHandlers()}addWindowResizeHandler(){this.boundWindowResizeHandler=V_.bind(this),window.addEventListener("resize",this.boundWindowResizeHandler)}removeWindowResizeHandler(){window.removeEventListener("resize",this.boundWindowResizeHandler)}addRootMouseUpHandler(){this.boundRootMouseUpHandler=j_.bind(this),this.root.addEventListener("mouseup",this.boundRootMouseUpHandler)}removeRootMouseUpHandler(){this.root.removeEventListener("mouseup",this.boundRootMouseUpHandler)}addRootMouseLeaveHandler(){this.boundRootMouseLeaveHandler=j_.bind(this),this.root.addEventListener("mouseleave",this.boundRootMouseLeaveHandler)}removeRootMouseLeaveHandler(){this.root.removeEventListener("mouseleave",this.boundRootMouseLeaveHandler)}addColumnContainerEventHandlers(){this.boundColumnContainerMouseMoveHandler=U_.bind(this),this.boundColumnContainerTouchMoveHandler=U_.bind(this),this.boundColumnContainerMouseLeaveHandler=j_.bind(this),this.boundColumnContainerMouseUpHandler=j_.bind(this),this.boundColumnContainerTouchEndHandler=j_.bind(this),this.columnContainer.addEventListener("mousemove",this.boundColumnContainerMouseMoveHandler),this.columnContainer.addEventListener("touchmove",this.boundColumnContainerTouchMoveHandler),this.columnContainer.addEventListener("mouseleave",this.boundColumnContainerMouseLeaveHandler),this.columnContainer.addEventListener("mouseup",this.boundColumnContainerMouseUpHandler),this.columnContainer.addEventListener("touchend",this.boundColumnContainerTouchEndHandler)}removeColumnContainerEventHandlers(){this.columnContainer.removeEventListener("mousemove",this.boundColumnContainerMouseMoveHandler),this.columnContainer.removeEventListener("touchmove",this.boundColumnContainerTouchMoveHandler),this.columnContainer.removeEventListener("mouseleave",this.boundColumnContainerMouseLeaveHandler),this.columnContainer.removeEventListener("mouseup",this.boundColumnContainerMouseUpHandler),this.columnContainer.removeEventListener("touchend",this.boundColumnContainerTouchEndHandler)}static uncompressSession(e){let t;if(e.indexOf("/gzip;base64")>0){t=Rh(e);let i="";for(let e of t)i+=String.fromCharCode(e);return i}return function(e){e=e.replace(/\./g,"+").replace(/_/g,"/").replace(/-/g,"=");const t=atob(e),i=[];for(let e=0;e{const o=e.data,r=o.mate;function a(e){e.chr=i.genome.getChromosomeName(e.refName);let t=!1;for(let n of i.referenceFrameList){const i=mg.fromLocusString(n.getLocusString());if(i.contains(e)){t=!0;break}if(i.overlaps(e)){n.extend(e),t=!0;break}}if(!t){const t=2e3,n=(e.start+e.end)/2;i.addMultiLocusPanel(e.chr,n-t,n+t)}}a(o),a(r)}})),this.circularViewControl=new I_(this.$toggle_button_container.get(0),this),this.circularView.setAssembly({name:this.genome.id,id:this.genome.id,chromosomes:jg(this.genome)}),this.circularViewVisible=t,this.circularView}get circularViewVisible(){return void 0!==this.circularView&&this.circularView.visible}set circularViewVisible(e){this.circularView&&(this.circularView.visible=e,this.circularViewControl.setState(e))}}async function V_(){if(!this.referenceFrameList)return;const e=this.calculateViewportWidth(this.referenceFrameList.length);for(let t of this.referenceFrameList){const i=this.referenceFrameList.indexOf(t),{chr:n,genome:o}=t,{bpLength:r}=o.getChromosome(t.chr),a=t.toBP(e);Rf.isWholeGenomeView(n)||a>r?t.bpPerPixel=r/e:t.end=t.start+t.toBP(e);for(let{viewports:t}of this.trackViews)t[i].setWidth(e)}this.updateUIWithReferenceFrameList(),await this.updateViews(!0)}function U_(e){e.preventDefault();const{x:t,y:i}=xr.pageCoordinates(e);if(this.vpMouseDown){const{viewport:e,referenceFrame:n}=this.vpMouseDown,o=Math.abs(t-this.vpMouseDown.mouseDownX)>Math.abs(i-this.vpMouseDown.mouseDownY);if(!this.dragObject&&!this.isScrolling)if(o)this.vpMouseDown.mouseDownX&&Math.abs(t-this.vpMouseDown.mouseDownX)>this.constants.dragThreshold&&(this.dragObject={viewport:e,start:n.start});else if(this.vpMouseDown.mouseDownY&&Math.abs(i-this.vpMouseDown.mouseDownY)>this.constants.scrollThreshold){this.isScrolling=!0;const t=e.$viewport.height(),i=e.trackView.maxViewportContentHeight();this.vpMouseDown.r=t/i}if(this.dragObject){const i=!this.isSoftclipped();let o=this.vpMouseDown.lastMouseX-t;n.shiftPixels(o,e.$viewport.width(),i)&&this.updateViews(),this.fireEvent("trackdrag")}if(this.isScrolling){const t=this.vpMouseDown.r*(this.vpMouseDown.lastMouseY-i);e.trackView.moveScroller(t)}this.vpMouseDown.lastMouseX=t,this.vpMouseDown.lastMouseY=i}}function j_(e){this.cancelTrackPan(),this.endTrackDrag()}function W_(e,t){for(let{viewports:i}of e)for(let e of i)e.$trackLabel&&(0===i.indexOf(e)&&!0===t?e.$trackLabel.show():e.$trackLabel.hide())}let G_=[];const $_=ad.setApiKey;!function(){var e=document.createElement("style");e.setAttribute("type","text/css"),e.innerHTML='.igv-navbar {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-between;\n align-items: center;\n box-sizing: border-box;\n width: 100%;\n color: #444;\n font-size: 12px;\n font-family: "Open Sans", sans-serif;\n font-weight: 400;\n line-height: 32px;\n padding-left: 8px;\n padding-right: 8px;\n margin-top: 2px;\n margin-bottom: 6px;\n height: 32px;\n border-style: solid;\n border-radius: 3px;\n border-width: thin;\n border-color: #bfbfbf;\n background-color: #f3f3f3;\n}\n.igv-navbar .igv-navbar-left-container {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-between;\n align-items: center;\n height: 32px;\n line-height: 32px;\n}\n.igv-navbar .igv-navbar-left-container .igv-logo {\n width: 34px;\n height: 32px;\n margin-right: 8px;\n}\n.igv-navbar .igv-navbar-left-container .igv-current-genome {\n height: 32px;\n margin-left: 4px;\n margin-right: 4px;\n user-select: none;\n line-height: 32px;\n vertical-align: middle;\n text-align: center;\n}\n.igv-navbar .igv-navbar-left-container .igv-navbar-genomic-location {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-between;\n align-items: center;\n height: 100%;\n}\n.igv-navbar .igv-navbar-left-container .igv-navbar-genomic-location .igv-chromosome-select-widget-container {\n display: flex;\n flex-flow: column;\n flex-wrap: nowrap;\n justify-content: space-around;\n align-items: center;\n height: 100%;\n width: 125px;\n margin-right: 4px;\n}\n.igv-navbar .igv-navbar-left-container .igv-navbar-genomic-location .igv-chromosome-select-widget-container select {\n display: block;\n cursor: pointer;\n width: 100px;\n height: 75%;\n outline: none;\n font-size: 12px;\n font-family: "Open Sans", sans-serif;\n font-weight: 400;\n}\n.igv-navbar .igv-navbar-left-container .igv-navbar-genomic-location .igv-locus-size-group {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-between;\n align-items: center;\n margin-left: 8px;\n height: 22px;\n}\n.igv-navbar .igv-navbar-left-container .igv-navbar-genomic-location .igv-locus-size-group .igv-search-container {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n width: 210px;\n height: 22px;\n line-height: 22px;\n}\n.igv-navbar .igv-navbar-left-container .igv-navbar-genomic-location .igv-locus-size-group .igv-search-container input.igv-search-input {\n cursor: text;\n width: 85%;\n height: 22px;\n line-height: 22px;\n font-size: 12px;\n font-family: "Open Sans", sans-serif;\n font-weight: 400;\n text-align: left;\n padding-left: 8px;\n margin-right: 8px;\n outline: none;\n border-style: solid;\n border-radius: 3px;\n border-width: thin;\n border-color: #bfbfbf;\n background-color: white;\n}\n.igv-navbar .igv-navbar-left-container .igv-navbar-genomic-location .igv-locus-size-group .igv-search-container .igv-search-icon-container {\n cursor: pointer;\n height: 16px;\n width: 16px;\n}\n.igv-navbar .igv-navbar-left-container .igv-navbar-genomic-location .igv-locus-size-group .igv-windowsize-panel-container {\n margin-left: 4px;\n user-select: none;\n}\n.igv-navbar .igv-navbar-right-container {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-between;\n align-items: center;\n height: 32px;\n line-height: 32px;\n}\n.igv-navbar .igv-navbar-right-container .igv-navbar-toggle-button-container {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-between;\n align-items: center;\n height: 100%;\n}\n.igv-navbar .igv-navbar-right-container .igv-navbar-toggle-button-container div {\n margin-left: 0;\n margin-right: 4px;\n}\n.igv-navbar .igv-navbar-right-container .igv-navbar-toggle-button-container div:last-child {\n margin-left: 0;\n margin-right: 0;\n}\n.igv-navbar .igv-navbar-right-container .igv-navbar-toggle-button-container-750 {\n display: none;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget {\n color: #737373;\n font-size: 18px;\n height: 32px;\n line-height: 32px;\n margin-left: 8px;\n user-select: none;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-end;\n align-items: center;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget div {\n cursor: pointer;\n margin-left: unset;\n margin-right: unset;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget div:first-child {\n height: 24px;\n width: 24px;\n margin-left: unset;\n margin-right: 8px;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget div:last-child {\n height: 24px;\n width: 24px;\n margin-left: 8px;\n margin-right: unset;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget div:nth-child(even) {\n display: block;\n height: fit-content;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget input {\n display: block;\n width: 125px;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget svg {\n display: block;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget-900 {\n color: #737373;\n font-size: 18px;\n height: 32px;\n line-height: 32px;\n margin-left: 8px;\n user-select: none;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-end;\n align-items: center;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget-900 div {\n cursor: pointer;\n margin-left: unset;\n margin-right: unset;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget-900 div:first-child {\n height: 24px;\n width: 24px;\n margin-left: unset;\n margin-right: 8px;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget-900 div:last-child {\n height: 24px;\n width: 24px;\n margin-left: 8px;\n margin-right: unset;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget-900 div:nth-child(even) {\n width: 0;\n height: 0;\n display: none;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget-900 input {\n width: 0;\n height: 0;\n display: none;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget-900 svg {\n display: block;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget-hidden {\n display: none;\n}\n\n.igv-navbar-button {\n display: block;\n box-sizing: unset;\n padding-left: 6px;\n padding-right: 6px;\n height: 18px;\n text-transform: capitalize;\n user-select: none;\n line-height: 18px;\n text-align: center;\n vertical-align: middle;\n font-family: "Open Sans", sans-serif;\n font-size: 11px;\n font-weight: 200;\n color: #737373;\n background-color: #f3f3f3;\n border-color: #737373;\n border-style: solid;\n border-width: thin;\n border-radius: 6px;\n}\n\n.igv-navbar-button-clicked {\n color: white;\n background-color: #737373;\n}\n\n.igv-navbar-button:hover {\n cursor: pointer;\n}\n\n.igv-zoom-in-notice-container {\n z-index: 1024;\n position: absolute;\n top: 8px;\n left: 50%;\n transform: translate(-50%, 0%);\n display: flex;\n flex-direction: row;\n flex-wrap: nowrap;\n justify-content: center;\n align-items: center;\n background-color: white;\n}\n.igv-zoom-in-notice-container > div {\n padding-left: 4px;\n padding-right: 4px;\n padding-top: 2px;\n padding-bottom: 2px;\n width: 100%;\n height: 100%;\n font-family: "Open Sans", sans-serif;\n font-size: 14px;\n font-weight: 400;\n color: #3f3f3f;\n}\n\n.igv-zoom-in-notice {\n position: absolute;\n top: 10px;\n left: 50%;\n}\n.igv-zoom-in-notice div {\n position: relative;\n left: -50%;\n font-family: "Open Sans", sans-serif;\n font-size: medium;\n font-weight: 400;\n color: #3f3f3f;\n background-color: rgba(255, 255, 255, 0.51);\n z-index: 64;\n}\n\n.igv-container-spinner {\n position: absolute;\n top: 90%;\n left: 50%;\n transform: translate(-50%, -50%);\n z-index: 1024;\n width: 24px;\n height: 24px;\n pointer-events: none;\n color: #737373;\n}\n\n.igv-multi-locus-close-button {\n position: absolute;\n top: 2px;\n right: 0;\n padding-left: 2px;\n padding-right: 2px;\n width: 12px;\n height: 12px;\n color: #666666;\n background-color: white;\n z-index: 1000;\n}\n.igv-multi-locus-close-button > svg {\n vertical-align: top;\n}\n\n.igv-multi-locus-close-button:hover {\n cursor: pointer;\n color: #434343;\n}\n\n.igv-multi-locus-ruler-label {\n z-index: 64;\n position: absolute;\n top: 2px;\n left: 0;\n width: 100%;\n height: 12px;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: center;\n align-items: center;\n}\n.igv-multi-locus-ruler-label > div {\n font-family: "Open Sans", sans-serif;\n font-size: 12px;\n color: rgb(16, 16, 16);\n background-color: white;\n}\n.igv-multi-locus-ruler-label > div {\n cursor: pointer;\n}\n\n.igv-multi-locus-ruler-label-square-dot {\n z-index: 64;\n position: absolute;\n left: 50%;\n top: 5%;\n transform: translate(-50%, 0%);\n background-color: white;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n}\n.igv-multi-locus-ruler-label-square-dot > div:first-child {\n width: 14px;\n height: 14px;\n}\n.igv-multi-locus-ruler-label-square-dot > div:last-child {\n margin-left: 16px;\n font-family: "Open Sans", sans-serif;\n font-size: 14px;\n font-weight: 400;\n color: rgb(16, 16, 16);\n}\n\n.igv-ruler-sweeper {\n display: none;\n pointer-events: none;\n position: absolute;\n top: 26px;\n bottom: 0;\n left: 0;\n width: 0;\n z-index: 99999;\n background-color: rgba(68, 134, 247, 0.25);\n}\n\n.igv-ruler-tooltip {\n pointer-events: none;\n z-index: 128;\n position: absolute;\n top: 0;\n left: 0;\n width: 1px;\n height: 32px;\n background-color: transparent;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n}\n.igv-ruler-tooltip > div {\n pointer-events: none;\n width: 128px;\n height: auto;\n padding: 1px;\n color: #373737;\n font-size: 10px;\n font-family: "Open Sans", sans-serif;\n font-weight: 400;\n background-color: white;\n border-style: solid;\n border-width: thin;\n border-color: #373737;\n}\n\n.igv-track-label {\n position: absolute;\n left: 8px;\n top: 8px;\n width: auto;\n height: auto;\n max-width: 50%;\n padding-left: 4px;\n padding-right: 4px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n font-family: "Open Sans", sans-serif;\n font-size: small;\n font-weight: 400;\n text-align: center;\n user-select: none;\n -moz-user-select: none;\n -webkit-user-select: none;\n border-color: #444;\n border-radius: 2px;\n border-style: solid;\n border-width: thin;\n background-color: white;\n z-index: 128;\n cursor: pointer;\n}\n\n.igv-track-label:hover,\n.igv-track-label:focus,\n.igv-track-label:active {\n background-color: #e8e8e8;\n}\n\n.igv-track-label-popup-shim {\n padding-left: 8px;\n padding-right: 8px;\n padding-top: 4px;\n}\n\n.igv-center-line {\n display: none;\n pointer-events: none;\n position: absolute;\n top: 0;\n bottom: 0;\n left: 50%;\n transform: translateX(-50%);\n z-index: 8;\n user-select: none;\n -moz-user-select: none;\n -webkit-user-select: none;\n border-left-style: dashed;\n border-left-width: thin;\n border-right-style: dashed;\n border-right-width: thin;\n}\n\n.igv-center-line-wide {\n background-color: rgba(0, 0, 0, 0);\n border-left-color: rgba(127, 127, 127, 0.51);\n border-right-color: rgba(127, 127, 127, 0.51);\n}\n\n.igv-center-line-thin {\n background-color: rgba(0, 0, 0, 0);\n border-left-color: rgba(127, 127, 127, 0.51);\n border-right-color: rgba(0, 0, 0, 0);\n}\n\n.igv-cursor-guide-horizontal {\n display: none;\n pointer-events: none;\n user-select: none;\n -moz-user-select: none;\n -webkit-user-select: none;\n position: absolute;\n left: 0;\n right: 0;\n top: 50%;\n height: 1px;\n z-index: 1;\n margin-left: 50px;\n margin-right: 54px;\n border-top-style: dotted;\n border-top-width: thin;\n border-top-color: rgba(127, 127, 127, 0.76);\n}\n\n.igv-cursor-guide-vertical {\n pointer-events: none;\n user-select: none;\n -moz-user-select: none;\n -webkit-user-select: none;\n position: absolute;\n top: 0;\n bottom: 0;\n left: 50%;\n width: 1px;\n z-index: 1;\n border-left-style: dotted;\n border-left-width: thin;\n border-left-color: rgba(127, 127, 127, 0.76);\n display: none;\n}\n\n.igv-user-feedback {\n position: fixed;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: 512px;\n height: 360px;\n z-index: 2048;\n background-color: white;\n border-color: #a2a2a2;\n border-style: solid;\n border-width: thin;\n font-family: "Open Sans", sans-serif;\n font-size: medium;\n font-weight: 400;\n color: #444;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n}\n.igv-user-feedback div:first-child {\n position: relative;\n height: 24px;\n width: 100%;\n background-color: white;\n border-bottom-color: #a2a2a2;\n border-bottom-style: solid;\n border-bottom-width: thin;\n}\n.igv-user-feedback div:first-child div {\n position: absolute;\n top: 2px;\n width: 16px;\n height: 16px;\n background-color: transparent;\n}\n.igv-user-feedback div:first-child div:first-child {\n left: 8px;\n}\n.igv-user-feedback div:first-child div:last-child {\n cursor: pointer;\n right: 8px;\n}\n.igv-user-feedback div:last-child {\n width: 100%;\n height: calc(100% - 24px);\n border-width: 0;\n}\n.igv-user-feedback div:last-child div {\n width: auto;\n height: auto;\n margin: 8px;\n}\n\n.igv-generic-dialog-container {\n position: absolute;\n top: 0;\n left: 0;\n width: 300px;\n height: 200px;\n border-color: #7F7F7F;\n border-radius: 4px;\n border-style: solid;\n border-width: thin;\n font-family: "Open Sans", sans-serif;\n font-size: medium;\n font-weight: 400;\n z-index: 2048;\n background-color: white;\n display: flex;\n flex-flow: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n}\n.igv-generic-dialog-container .igv-generic-dialog-header {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-end;\n align-items: center;\n width: 100%;\n height: 24px;\n cursor: move;\n border-top-left-radius: 4px;\n border-top-right-radius: 4px;\n border-bottom-color: #7F7F7F;\n border-bottom-style: solid;\n border-bottom-width: thin;\n background-color: #eee;\n}\n.igv-generic-dialog-container .igv-generic-dialog-header div {\n margin-right: 4px;\n margin-bottom: 2px;\n height: 12px;\n width: 12px;\n color: #7F7F7F;\n}\n.igv-generic-dialog-container .igv-generic-dialog-header div:hover {\n cursor: pointer;\n color: #444;\n}\n.igv-generic-dialog-container .igv-generic-dialog-one-liner {\n color: #373737;\n width: 95%;\n height: 24px;\n line-height: 24px;\n text-align: left;\n margin-top: 8px;\n padding-left: 8px;\n overflow-wrap: break-word;\n background-color: white;\n}\n.igv-generic-dialog-container .igv-generic-dialog-label-input {\n margin-top: 8px;\n width: 95%;\n height: 24px;\n color: #373737;\n line-height: 24px;\n padding-left: 8px;\n background-color: white;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n}\n.igv-generic-dialog-container .igv-generic-dialog-label-input div {\n width: 30%;\n height: 100%;\n font-size: 16px;\n text-align: right;\n padding-right: 8px;\n background-color: white;\n}\n.igv-generic-dialog-container .igv-generic-dialog-label-input input {\n display: block;\n height: 100%;\n width: 100%;\n padding-left: 4px;\n font-family: "Open Sans", sans-serif;\n font-weight: 400;\n color: #373737;\n text-align: left;\n outline: none;\n border-style: solid;\n border-width: thin;\n border-color: #7F7F7F;\n background-color: white;\n}\n.igv-generic-dialog-container .igv-generic-dialog-label-input input {\n width: 50%;\n font-size: 16px;\n}\n.igv-generic-dialog-container .igv-generic-dialog-input {\n margin-top: 8px;\n width: calc(100% - 16px);\n height: 24px;\n color: #373737;\n line-height: 24px;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-around;\n align-items: center;\n}\n.igv-generic-dialog-container .igv-generic-dialog-input input {\n display: block;\n height: 100%;\n width: 100%;\n padding-left: 4px;\n font-family: "Open Sans", sans-serif;\n font-weight: 400;\n color: #373737;\n text-align: left;\n outline: none;\n border-style: solid;\n border-width: thin;\n border-color: #7F7F7F;\n background-color: white;\n}\n.igv-generic-dialog-container .igv-generic-dialog-input input {\n font-size: 16px;\n}\n.igv-generic-dialog-container .igv-generic-dialog-ok-cancel {\n width: 100%;\n height: 28px;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-around;\n align-items: center;\n}\n.igv-generic-dialog-container .igv-generic-dialog-ok-cancel div {\n margin-top: 32px;\n color: white;\n font-family: "Open Sans", sans-serif;\n font-size: 14px;\n font-weight: 400;\n width: 75px;\n height: 28px;\n line-height: 28px;\n text-align: center;\n border-color: transparent;\n border-style: solid;\n border-width: thin;\n border-radius: 2px;\n}\n.igv-generic-dialog-container .igv-generic-dialog-ok-cancel div:first-child {\n margin-left: 32px;\n margin-right: 0;\n background-color: #5ea4e0;\n}\n.igv-generic-dialog-container .igv-generic-dialog-ok-cancel div:last-child {\n margin-left: 0;\n margin-right: 32px;\n background-color: #c4c4c4;\n}\n.igv-generic-dialog-container .igv-generic-dialog-ok-cancel div:first-child:hover {\n cursor: pointer;\n background-color: #3b5c7f;\n}\n.igv-generic-dialog-container .igv-generic-dialog-ok-cancel div:last-child:hover {\n cursor: pointer;\n background-color: #7f7f7f;\n}\n.igv-generic-dialog-container .igv-generic-dialog-ok {\n width: 100%;\n height: 36px;\n margin-top: 32px;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-around;\n align-items: center;\n}\n.igv-generic-dialog-container .igv-generic-dialog-ok div {\n width: 98px;\n height: 36px;\n line-height: 36px;\n text-align: center;\n color: white;\n font-family: "Open Sans", sans-serif;\n font-size: medium;\n font-weight: 400;\n border-color: white;\n border-style: solid;\n border-width: thin;\n border-radius: 4px;\n background-color: #2B81AF;\n}\n.igv-generic-dialog-container .igv-generic-dialog-ok div:hover {\n cursor: pointer;\n background-color: #25597f;\n}\n\n.igv-generic-container {\n position: absolute;\n top: 0;\n left: 0;\n z-index: 2048;\n background-color: white;\n cursor: pointer;\n display: flex;\n flex-direction: row;\n flex-wrap: wrap;\n justify-content: flex-start;\n align-items: center;\n}\n.igv-generic-container div:first-child {\n cursor: move;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-end;\n align-items: center;\n height: 24px;\n width: 100%;\n background-color: #dddddd;\n}\n.igv-generic-container div:first-child i {\n display: block;\n color: #5f5f5f;\n cursor: pointer;\n width: 14px;\n height: 14px;\n margin-right: 8px;\n margin-bottom: 4px;\n}\n\n.igv-menu-popup {\n position: absolute;\n top: 0;\n left: 0;\n width: max-content;\n z-index: 4096;\n cursor: pointer;\n font-family: "Open Sans", sans-serif;\n font-size: small;\n font-weight: 400;\n color: #4b4b4b;\n background: white;\n border-radius: 4px;\n border-color: #7F7F7F;\n border-style: solid;\n border-width: thin;\n display: flex;\n flex-flow: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: flex-end;\n text-align: left;\n}\n.igv-menu-popup > div:not(:first-child) {\n width: 100%;\n}\n.igv-menu-popup > div:not(:first-child) > div {\n background: white;\n}\n.igv-menu-popup > div:not(:first-child) > div.context-menu {\n padding-left: 4px;\n padding-right: 4px;\n}\n.igv-menu-popup > div:not(:first-child) > div:last-child {\n border-bottom-left-radius: 4px;\n border-bottom-right-radius: 4px;\n border-bottom-color: transparent;\n border-bottom-style: solid;\n border-bottom-width: thin;\n}\n.igv-menu-popup > div:not(:first-child) > div:hover {\n background: #efefef;\n}\n\n.igv-menu-popup-shim {\n padding-left: 8px;\n padding-right: 8px;\n padding-bottom: 1px;\n padding-top: 1px;\n}\n\n.igv-menu-popup-header {\n position: relative;\n width: 100%;\n height: 24px;\n cursor: move;\n border-top-color: transparent;\n border-top-left-radius: 4px;\n border-top-right-radius: 4px;\n border-bottom-color: #7F7F7F;\n border-bottom-style: solid;\n border-bottom-width: thin;\n background-color: #eee;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-end;\n align-items: center;\n}\n.igv-menu-popup-header div {\n margin-right: 4px;\n height: 12px;\n width: 12px;\n color: #7F7F7F;\n}\n.igv-menu-popup-header div:hover {\n cursor: pointer;\n color: #444;\n}\n\n.igv-menu-popup-check-container {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n width: 100%;\n height: 20px;\n margin-right: 4px;\n background-color: transparent;\n}\n.igv-menu-popup-check-container div {\n padding-top: 2px;\n padding-left: 8px;\n}\n.igv-menu-popup-check-container div:first-child {\n position: relative;\n width: 12px;\n height: 12px;\n}\n.igv-menu-popup-check-container div:first-child svg {\n position: absolute;\n width: 12px;\n height: 12px;\n}\n\n.igv-user-feedback {\n position: fixed;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: 512px;\n height: 360px;\n z-index: 2048;\n background-color: white;\n border-color: #a2a2a2;\n border-style: solid;\n border-width: thin;\n font-family: "Open Sans", sans-serif;\n font-size: medium;\n font-weight: 400;\n color: #444;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n}\n.igv-user-feedback div:first-child {\n position: relative;\n height: 24px;\n width: 100%;\n background-color: white;\n border-bottom-color: #a2a2a2;\n border-bottom-style: solid;\n border-bottom-width: thin;\n}\n.igv-user-feedback div:first-child div {\n position: absolute;\n top: 2px;\n width: 16px;\n height: 16px;\n background-color: transparent;\n}\n.igv-user-feedback div:first-child div:first-child {\n left: 8px;\n}\n.igv-user-feedback div:first-child div:last-child {\n cursor: pointer;\n right: 8px;\n}\n.igv-user-feedback div:last-child {\n width: 100%;\n height: calc(100% - 24px);\n border-width: 0;\n}\n.igv-user-feedback div:last-child div {\n width: auto;\n height: auto;\n margin: 8px;\n}\n\n.igv-loading-spinner-container {\n z-index: 1024;\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: 32px;\n height: 32px;\n display: flex;\n flex-direction: row;\n flex-wrap: nowrap;\n justify-content: center;\n align-items: center;\n}\n.igv-loading-spinner-container > div {\n box-sizing: border-box;\n width: 100%;\n height: 100%;\n border-radius: 50%;\n border: 4px solid rgba(128, 128, 128, 0.5);\n border-top-color: rgb(255, 255, 255);\n animation: spin 1s ease-in-out infinite;\n -webkit-animation: spin 1s ease-in-out infinite;\n}\n\n@keyframes spin {\n to {\n -webkit-transform: rotate(360deg);\n transform: rotate(360deg);\n }\n}\n@-webkit-keyframes spin {\n to {\n -webkit-transform: rotate(360deg);\n transform: rotate(360deg);\n }\n}\n.igv-roi-menu-next-gen {\n position: absolute;\n z-index: 512;\n font-family: "Open Sans", sans-serif;\n font-size: small;\n font-weight: 400;\n color: #4b4b4b;\n background-color: white;\n width: 192px;\n border-radius: 4px;\n border-color: #7F7F7F;\n border-style: solid;\n border-width: thin;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: stretch;\n}\n.igv-roi-menu-next-gen > div:first-child {\n height: 24px;\n border-top-color: transparent;\n border-top-left-radius: 4px;\n border-top-right-radius: 4px;\n border-bottom-color: #7F7F7F;\n border-bottom-style: solid;\n border-bottom-width: thin;\n background-color: #eee;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-end;\n align-items: center;\n}\n.igv-roi-menu-next-gen > div:first-child > div {\n margin-right: 4px;\n height: 12px;\n width: 12px;\n color: #7F7F7F;\n}\n.igv-roi-menu-next-gen > div:first-child > div:hover {\n cursor: pointer;\n color: #444;\n}\n.igv-roi-menu-next-gen > div:last-child {\n background-color: white;\n border-bottom-left-radius: 4px;\n border-bottom-right-radius: 4px;\n border-bottom-color: transparent;\n border-bottom-style: solid;\n border-bottom-width: 0;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: stretch;\n text-align: start;\n vertical-align: middle;\n}\n.igv-roi-menu-next-gen > div:last-child > div {\n height: 24px;\n padding-left: 4px;\n border-bottom-style: solid;\n border-bottom-width: thin;\n border-bottom-color: #7f7f7f;\n}\n.igv-roi-menu-next-gen > div:last-child > div:not(:first-child):hover {\n background-color: rgba(127, 127, 127, 0.1);\n}\n.igv-roi-menu-next-gen > div:last-child div:first-child {\n font-style: italic;\n text-align: center;\n padding-right: 4px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n.igv-roi-menu-next-gen > div:last-child > div:last-child {\n border-bottom-width: 0;\n border-bottom-color: transparent;\n}\n\n.igv-roi-placeholder {\n font-style: normal;\n color: rgba(75, 75, 75, 0.6);\n}\n\n.igv-roi-table {\n position: absolute;\n z-index: 1024;\n width: min-content;\n max-width: 1600px;\n border-color: #7f7f7f;\n border-radius: 4px;\n border-style: solid;\n border-width: thin;\n font-family: "Open Sans", sans-serif;\n font-size: 12px;\n font-weight: 400;\n background-color: white;\n display: flex;\n flex-flow: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: stretch;\n cursor: default;\n}\n.igv-roi-table > div {\n height: 24px;\n font-size: 14px;\n text-align: start;\n vertical-align: middle;\n line-height: 24px;\n}\n.igv-roi-table > div:first-child {\n border-color: transparent;\n border-top-left-radius: 4px;\n border-top-right-radius: 4px;\n border-top-width: 0;\n border-bottom-color: #7f7f7f;\n border-bottom-style: solid;\n border-bottom-width: thin;\n background-color: #eee;\n cursor: move;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-between;\n align-items: center;\n}\n.igv-roi-table > div:first-child > div:first-child {\n text-align: center;\n white-space: nowrap;\n text-overflow: ellipsis;\n overflow: hidden;\n margin-left: 4px;\n margin-right: 4px;\n width: calc(100% - 4px - 12px);\n}\n.igv-roi-table > div:first-child > div:last-child {\n margin-right: 4px;\n margin-bottom: 2px;\n height: 12px;\n width: 12px;\n color: #7f7f7f;\n}\n.igv-roi-table > div:first-child > div:last-child > svg {\n display: block;\n}\n.igv-roi-table > div:first-child > div:last-child:hover {\n cursor: pointer;\n color: #444;\n}\n.igv-roi-table > .igv-roi-table-description {\n padding: 4px;\n margin-left: 4px;\n word-break: break-all;\n overflow-y: auto;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n background-color: transparent;\n}\n.igv-roi-table > .igv-roi-table-goto-explainer {\n margin-top: 5px;\n margin-left: 4px;\n color: #7F7F7F;\n font-style: italic;\n height: 24px;\n border-top: solid lightgray;\n background-color: transparent;\n}\n.igv-roi-table > .igv-roi-table-column-titles {\n height: 24px;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: stretch;\n align-items: stretch;\n padding-right: 16px;\n background-color: white;\n border-top-color: #7f7f7f;\n border-top-style: solid;\n border-top-width: thin;\n border-bottom-color: #7f7f7f;\n border-bottom-style: solid;\n border-bottom-width: thin;\n}\n.igv-roi-table > .igv-roi-table-column-titles > div {\n font-size: 14px;\n vertical-align: middle;\n line-height: 24px;\n text-align: left;\n margin-left: 4px;\n height: 24px;\n overflow: hidden;\n text-overflow: ellipsis;\n border-right-color: #7f7f7f;\n border-right-style: solid;\n border-right-width: thin;\n}\n.igv-roi-table > .igv-roi-table-column-titles > div:last-child {\n border-right: unset;\n}\n.igv-roi-table > .igv-roi-table-row-container {\n overflow: auto;\n resize: both;\n max-width: 1600px;\n height: 360px;\n background-color: transparent;\n display: flex;\n flex-flow: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: stretch;\n}\n.igv-roi-table > .igv-roi-table-row-container > .igv-roi-table-row {\n height: 24px;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: stretch;\n align-items: stretch;\n}\n.igv-roi-table > .igv-roi-table-row-container > .igv-roi-table-row > div {\n font-size: 14px;\n vertical-align: middle;\n line-height: 24px;\n text-align: left;\n margin-left: 4px;\n height: 24px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n border-right-color: transparent;\n border-right-style: solid;\n border-right-width: thin;\n}\n.igv-roi-table > .igv-roi-table-row-container > .igv-roi-table-row > div:last-child {\n border-right: unset;\n}\n.igv-roi-table > .igv-roi-table-row-container > .igv-roi-table-row-hover {\n background-color: rgba(0, 0, 0, 0.04);\n}\n.igv-roi-table > div:last-child {\n height: 32px;\n line-height: 32px;\n border-top-color: #7f7f7f;\n border-top-style: solid;\n border-top-width: thin;\n border-bottom-color: transparent;\n border-bottom-left-radius: 4px;\n border-bottom-right-radius: 4px;\n border-bottom-width: 0;\n background-color: #eee;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-around;\n align-items: center;\n}\n\n.igv-roi-table-row-selected {\n background-color: rgba(0, 0, 0, 0.125);\n}\n\n.igv-roi-table-button {\n cursor: pointer;\n height: 20px;\n user-select: none;\n line-height: 20px;\n text-align: center;\n vertical-align: middle;\n font-family: "Open Sans", sans-serif;\n font-size: 13px;\n font-weight: 400;\n color: black;\n padding-left: 6px;\n padding-right: 6px;\n background-color: rgb(239, 239, 239);\n border-color: black;\n border-style: solid;\n border-width: thin;\n border-radius: 3px;\n}\n\n.igv-roi-table-button:hover {\n font-weight: 400;\n background-color: rgba(0, 0, 0, 0.13);\n}\n\n.igv-roi-region {\n z-index: 64;\n position: absolute;\n top: 0;\n bottom: 0;\n pointer-events: none;\n overflow: visible;\n margin-top: 44px;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: stretch;\n}\n.igv-roi-region > div {\n position: relative;\n width: 100%;\n height: 8px;\n pointer-events: auto;\n}\n\n.igv-roi-menu {\n position: absolute;\n z-index: 1024;\n width: 144px;\n border-color: #7f7f7f;\n border-radius: 4px;\n border-style: solid;\n border-width: thin;\n font-family: "Open Sans", sans-serif;\n background-color: white;\n display: flex;\n flex-flow: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: stretch;\n}\n.igv-roi-menu > div:not(:last-child) {\n border-bottom-color: rgba(128, 128, 128, 0.5);\n border-bottom-style: solid;\n border-bottom-width: thin;\n}\n.igv-roi-menu > div:first-child {\n border-top-left-radius: 4px;\n border-top-right-radius: 4px;\n border-top-color: transparent;\n border-top-style: solid;\n border-top-width: 0;\n}\n.igv-roi-menu > div:last-child {\n border-bottom-left-radius: 4px;\n border-bottom-right-radius: 4px;\n border-bottom-color: transparent;\n border-bottom-style: solid;\n border-bottom-width: 0;\n}\n\n.igv-roi-menu-row {\n height: 24px;\n padding-left: 8px;\n font-size: small;\n text-align: start;\n vertical-align: middle;\n line-height: 24px;\n background-color: white;\n}\n\n.igv-roi-menu-row-edit-description {\n width: -webkit-fill-available;\n font-size: small;\n text-align: start;\n vertical-align: middle;\n background-color: white;\n padding-left: 4px;\n padding-right: 4px;\n padding-bottom: 4px;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: stretch;\n align-items: stretch;\n}\n.igv-roi-menu-row-edit-description > label {\n margin-left: 2px;\n margin-bottom: 0;\n display: block;\n width: -webkit-fill-available;\n}\n.igv-roi-menu-row-edit-description > input {\n display: block;\n margin-left: 2px;\n margin-right: 2px;\n margin-bottom: 1px;\n width: -webkit-fill-available;\n}\n\n.igv-container {\n position: relative;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: flex-start;\n padding-top: 4px;\n user-select: none;\n -webkit-user-select: none;\n -ms-user-select: none;\n}\n\n.igv-viewport {\n position: relative;\n margin-top: 5px;\n line-height: 1;\n overflow-x: hidden;\n overflow-y: hidden;\n}\n\n.igv-viewport-content {\n position: relative;\n width: 100%;\n}\n.igv-viewport-content > canvas {\n position: relative;\n display: block;\n}\n\n.igv-column-container {\n position: relative;\n display: flex;\n flex-direction: row;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: stretch;\n width: 100%;\n}\n\n.igv-column-shim {\n width: 1px;\n margin-left: 2px;\n margin-right: 2px;\n background-color: #545453;\n}\n\n.igv-column {\n position: relative;\n position: relative;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: flex-start;\n box-sizing: border-box;\n height: 100%;\n}\n\n.igv-axis-column {\n position: relative;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: flex-start;\n box-sizing: border-box;\n height: 100%;\n width: 50px;\n}\n.igv-axis-column > div {\n margin-top: 5px;\n width: 100%;\n}\n\n.igv-sample-name-column {\n position: relative;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: flex-start;\n box-sizing: border-box;\n height: 100%;\n}\n\n.igv-scrollbar-column {\n position: relative;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: flex-start;\n box-sizing: border-box;\n height: 100%;\n width: 14px;\n}\n.igv-scrollbar-column > div {\n position: relative;\n margin-top: 5px;\n width: 14px;\n}\n.igv-scrollbar-column > div > div {\n cursor: pointer;\n position: absolute;\n top: 0;\n left: 2px;\n width: 8px;\n border-width: 1px;\n border-style: solid;\n border-color: #c4c4c4;\n border-top-left-radius: 4px;\n border-top-right-radius: 4px;\n border-bottom-left-radius: 4px;\n border-bottom-right-radius: 4px;\n}\n.igv-scrollbar-column > div > div:hover {\n background-color: #c4c4c4;\n}\n\n.igv-track-drag-column {\n position: relative;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: flex-start;\n box-sizing: border-box;\n height: 100%;\n width: 12px;\n background-color: white;\n}\n.igv-track-drag-column > .igv-track-drag-handle {\n z-index: 512;\n position: relative;\n cursor: pointer;\n margin-top: 5px;\n width: 100%;\n border-style: solid;\n border-width: 0;\n border-top-right-radius: 6px;\n border-bottom-right-radius: 6px;\n background-color: #c4c4c4;\n}\n.igv-track-drag-column .igv-track-drag-handle-hover {\n background-color: #787878;\n}\n.igv-track-drag-column > .igv-track-drag-shim {\n position: relative;\n margin-top: 5px;\n width: 100%;\n border-style: solid;\n border-width: 0;\n}\n\n.igv-gear-menu-column {\n position: relative;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: flex-start;\n box-sizing: border-box;\n height: 100%;\n width: 28px;\n}\n.igv-gear-menu-column > div {\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n margin-top: 5px;\n width: 100%;\n background: white;\n}\n.igv-gear-menu-column > div > div {\n position: relative;\n margin-top: 4px;\n width: 16px;\n height: 16px;\n color: #7F7F7F;\n}\n.igv-gear-menu-column > div > div:hover {\n cursor: pointer;\n color: #444;\n}\n\n/*# sourceMappingURL=dom.css.map */\n',document.head.append(e)}();const Z_=ad.oauth;var K_={TrackUtils:Xd,IGVGraphics:kd,MenuUtils:Ua,DataRangeDialog:Ga,createTrack:async function(e,t){return await q_.prototype.createTrack.call(t,e)},createBrowser:async function(e,t){void 0===t&&(t={}),Rf.KNOWN_GENOMES||await Rf.initializeGenomes(t),function(e){void 0===e.minimumBases&&(e.minimumBases=40);void 0===e.showIdeogram&&(e.showIdeogram=!0);void 0===e.showCircularView&&(e.showCircularView=!1);void 0===e.showCircularViewButton&&(e.showCircularViewButton=!1);void 0===e.showTrackLabelButton&&(e.showTrackLabelButton=!0);void 0===e.showTrackLabels&&(e.showTrackLabels=!0);void 0===e.showROITableButton&&(e.showROITableButton=!1);void 0===e.showROITable&&(e.showROITable=!1);void 0===e.showCursorTrackingGuideButton&&(e.showCursorTrackingGuideButton=!0);void 0===e.showCursorGuide&&(e.showCursorGuide=e.showCursorTrackingGuide||!1);void 0===e.showCenterGuideButton&&(e.showCenterGuideButton=!0);void 0===e.showCenterGuide&&(e.showCenterGuide=!1);void 0===e.showSampleNames&&(e.showSampleNames=!1);void 0===e.showSVGButton&&(e.showSVGButton=!0);void 0===e.showControls&&(e.showControls=!0);void 0===e.showNavigation&&(e.showNavigation=!0);void 0===e.showRuler&&(e.showRuler=!0);void 0===e.flanking&&(e.flanking=1e3);void 0===e.pairsSupported&&(e.pairsSupported=!0);e.tracks||(e.tracks=[])}(t),t.queryParametersSupported&&function(e){var t,i,n,o,r,a,s,c,l;let h,d,f;if(s=window.location.href,r={},t=s.indexOf("?"),i=s.lastIndexOf("#"),t>=0)for(i<0&&(i=s.length),n=t+1;nt&&(i.indexURL=d[t]),f&&f.length>t&&(i.name=f[t]),e.tracks.push(i)}}}(t),t.apiKey&&ad.setApiKey(t.apiKey),t.oauthToken&&ad.setOauthToken(t.oauthToken),t.clientId&&!Qh()&&await async function(e){if(!google.accounts.oauth2.initTokenClient)throw new Error("Google accounts token client not loaded (https://accounts.google.com/gsi/client)");if(Qh())throw new Error("Google client is already initialized");const t={client_id:e.client_id||e.clientId,scope:e.scope||"https://www.googleapis.com/auth/userinfo.profile",state:e.state||"igv",error:e=>{throw new Error(e.type)},hint:e.hint,hosted_domain:e.hosted_domain},i=google.accounts.oauth2.initTokenClient(t);google.igv={tokenClient:i,apiKey:e.apiKey}}({clientId:t.clientId,apiKey:t.apiKey,scope:"https://www.googleapis.com/auth/userinfo.profile"});const i=new q_(t,e);return G_.push(i),t.sessionURL?await i.loadSession({url:t.sessionURL}):await i.loadSessionObject(t),i.navbarManager.navbarDidResize(i.$navigation.width()),i},removeBrowser:function(e){e.dispose(),e.root.remove(),G_=G_.filter((t=>t!==e))},removeAllBrowsers:function(){for(let e of G_)e.dispose(),e.root.remove();G_=[]},visibilityChange:async function(){for(let e of G_)await e.visibilityChange()},setGoogleOauthToken:function(e){return ad.setOauthToken(e)},setOauthToken:function(e,t){return ad.setOauthToken(e,t)},oauth:Z_,version:Mf,setApiKey:$_,registerFileFormats:Kd};function X_(e){return Y_("div",e)}function Y_(e,t){const i=document.createElement(e);return t&&(t.class&&i.classList.add(t.class),t.id&&(i.id=t.id),t.style&&tC(i,t.style)),i}function Q_(e){const t=getComputedStyle(e);"none"!==t.display&&(e._initialDisplay=t.display),e.style.display="none"}function J_(e){if("none"===getComputedStyle(e).display){const t=e._initialDisplay||"block";e.style.display=t}}function eC(e){if(e.type.startsWith("touch")){const t=e.touches[0];return{x:t.pageX,y:t.pageY}}return{x:e.pageX,y:e.pageY}}function tC(e,t){for(let i of Object.keys(t))e.style[i]=t[i]}var iC=Object.freeze({__proto__:null,applyStyle:tC,create:Y_,div:X_,empty:function(e){for(;e.firstChild;)e.removeChild(e.firstChild)},guid:function(){return("0000"+(Math.random()*Math.pow(36,4)|0).toString(36)).slice(-4)},hide:Q_,hideAll:function(e){document.querySelectorAll(e).forEach((e=>{Q_(e)}))},offset:function(e){if(!e.getClientRects().length)return{top:0,left:0};const t=e.getBoundingClientRect(),i=e.ownerDocument.defaultView;return{top:t.top+i.pageYOffset,left:t.left+i.pageXOffset}},pageCoordinates:eC,relativeDOMBBox:(e,t)=>{const{x:i,y:n,width:o,height:r}=e.getBoundingClientRect(),{x:a,y:s,width:c,height:l}=t.getBoundingClientRect();return{x:a-i,y:s-n,width:c,height:l}},show:J_,translateMouseCoordinates:function(e,t){const{clientX:i,clientY:n}=e;return((e,{clientX:t,clientY:i})=>{const{left:n,top:o,width:r,height:a}=e.getBoundingClientRect(),s=t-n,c=i-o;return{x:s,y:c,xNormalized:s/r,yNormalized:c/a,width:r,height:a}})(t,{clientX:i,clientY:n})}});class nC{constructor({value:e,label:t,onchange:i}){if(this.elem=X_({class:"igv-ui-generic-dialog-label-input"}),t){const e=X_();e.innerHTML=t,this.elem.appendChild(e)}this.textBox=Y_("input"),e&&(this.textBox.value=e),this.elem.appendChild(this.textBox),i&&this.textBox.addEventListener("change",(e=>i(this.textBox.value)))}get value(){return this.textBox.value}set value(e){this.textBox.value=e}}class oC{constructor(){this.elem=Y_("div",{class:"igv-ui-panel-column"})}add(e){if(e instanceof Node)this.elem.append(e);else if("object"==typeof e)this.elem.append(e.elem);else{const t=X_();t.innerHTML=e,this.elem.append(t)}}}function rC(e,t){return function(e,t){t=t||"currentColor";let i=aC[e];i||(console.error(`No icon named: ${e}`),i=aC.question);const n=document.createElementNS("http://www.w3.org/2000/svg","svg");n.setAttributeNS(null,"viewBox","0 0 "+i[0]+" "+i[1]);const o=document.createElementNS("http://www.w3.org/2000/svg","path");return o.setAttributeNS(null,"fill",t),o.setAttributeNS(null,"d",i[4]),n.appendChild(o),n}(e,t)}const aC={check:[512,512,[],"f00c","M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z"],cog:[512,512,[],"f013","M444.788 291.1l42.616 24.599c4.867 2.809 7.126 8.618 5.459 13.985-11.07 35.642-29.97 67.842-54.689 94.586a12.016 12.016 0 0 1-14.832 2.254l-42.584-24.595a191.577 191.577 0 0 1-60.759 35.13v49.182a12.01 12.01 0 0 1-9.377 11.718c-34.956 7.85-72.499 8.256-109.219.007-5.49-1.233-9.403-6.096-9.403-11.723v-49.184a191.555 191.555 0 0 1-60.759-35.13l-42.584 24.595a12.016 12.016 0 0 1-14.832-2.254c-24.718-26.744-43.619-58.944-54.689-94.586-1.667-5.366.592-11.175 5.459-13.985L67.212 291.1a193.48 193.48 0 0 1 0-70.199l-42.616-24.599c-4.867-2.809-7.126-8.618-5.459-13.985 11.07-35.642 29.97-67.842 54.689-94.586a12.016 12.016 0 0 1 14.832-2.254l42.584 24.595a191.577 191.577 0 0 1 60.759-35.13V25.759a12.01 12.01 0 0 1 9.377-11.718c34.956-7.85 72.499-8.256 109.219-.007 5.49 1.233 9.403 6.096 9.403 11.723v49.184a191.555 191.555 0 0 1 60.759 35.13l42.584-24.595a12.016 12.016 0 0 1 14.832 2.254c24.718 26.744 43.619 58.944 54.689 94.586 1.667 5.366-.592 11.175-5.459 13.985L444.788 220.9a193.485 193.485 0 0 1 0 70.2zM336 256c0-44.112-35.888-80-80-80s-80 35.888-80 80 35.888 80 80 80 80-35.888 80-80z"],exclamation:[192,512,[],"f12a","M176 432c0 44.112-35.888 80-80 80s-80-35.888-80-80 35.888-80 80-80 80 35.888 80 80zM25.26 25.199l13.6 272C39.499 309.972 50.041 320 62.83 320h66.34c12.789 0 23.331-10.028 23.97-22.801l13.6-272C167.425 11.49 156.496 0 142.77 0H49.23C35.504 0 24.575 11.49 25.26 25.199z"],"exclamation-circle":[512,512,[],"f06a","M504 256c0 136.997-111.043 248-248 248S8 392.997 8 256C8 119.083 119.043 8 256 8s248 111.083 248 248zm-248 50c-25.405 0-46 20.595-46 46s20.595 46 46 46 46-20.595 46-46-20.595-46-46-46zm-43.673-165.346l7.418 136c.347 6.364 5.609 11.346 11.982 11.346h48.546c6.373 0 11.635-4.982 11.982-11.346l7.418-136c.375-6.874-5.098-12.654-11.982-12.654h-63.383c-6.884 0-12.356 5.78-11.981 12.654z"],"exclamation-triangle":[576,512,[],"f071","M569.517 440.013C587.975 472.007 564.806 512 527.94 512H48.054c-36.937 0-59.999-40.055-41.577-71.987L246.423 23.985c18.467-32.009 64.72-31.951 83.154 0l239.94 416.028zM288 354c-25.405 0-46 20.595-46 46s20.595 46 46 46 46-20.595 46-46-20.595-46-46-46zm-43.673-165.346l7.418 136c.347 6.364 5.609 11.346 11.982 11.346h48.546c6.373 0 11.635-4.982 11.982-11.346l7.418-136c.375-6.874-5.098-12.654-11.982-12.654h-63.383c-6.884 0-12.356 5.78-11.981 12.654z"],minus:[448,512,[],"f068","M424 318.2c13.3 0 24-10.7 24-24v-76.4c0-13.3-10.7-24-24-24H24c-13.3 0-24 10.7-24 24v76.4c0 13.3 10.7 24 24 24h400z"],"minus-circle":[512,512,[],"f056","M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zM124 296c-6.6 0-12-5.4-12-12v-56c0-6.6 5.4-12 12-12h264c6.6 0 12 5.4 12 12v56c0 6.6-5.4 12-12 12H124z"],"minus-square":[448,512,[],"f146","M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM92 296c-6.6 0-12-5.4-12-12v-56c0-6.6 5.4-12 12-12h264c6.6 0 12 5.4 12 12v56c0 6.6-5.4 12-12 12H92z"],plus:[448,512,[],"f067","M448 294.2v-76.4c0-13.3-10.7-24-24-24H286.2V56c0-13.3-10.7-24-24-24h-76.4c-13.3 0-24 10.7-24 24v137.8H24c-13.3 0-24 10.7-24 24v76.4c0 13.3 10.7 24 24 24h137.8V456c0 13.3 10.7 24 24 24h76.4c13.3 0 24-10.7 24-24V318.2H424c13.3 0 24-10.7 24-24z"],"plus-circle":[512,512,[],"f055","M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm144 276c0 6.6-5.4 12-12 12h-92v92c0 6.6-5.4 12-12 12h-56c-6.6 0-12-5.4-12-12v-92h-92c-6.6 0-12-5.4-12-12v-56c0-6.6 5.4-12 12-12h92v-92c0-6.6 5.4-12 12-12h56c6.6 0 12 5.4 12 12v92h92c6.6 0 12 5.4 12 12v56z"],"plus-square":[448,512,[],"f0fe","M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-32 252c0 6.6-5.4 12-12 12h-92v92c0 6.6-5.4 12-12 12h-56c-6.6 0-12-5.4-12-12v-92H92c-6.6 0-12-5.4-12-12v-56c0-6.6 5.4-12 12-12h92v-92c0-6.6 5.4-12 12-12h56c6.6 0 12 5.4 12 12v92h92c6.6 0 12 5.4 12 12v56z"],question:[384,512,[],"f128","M202.021 0C122.202 0 70.503 32.703 29.914 91.026c-7.363 10.58-5.093 25.086 5.178 32.874l43.138 32.709c10.373 7.865 25.132 6.026 33.253-4.148 25.049-31.381 43.63-49.449 82.757-49.449 30.764 0 68.816 19.799 68.816 49.631 0 22.552-18.617 34.134-48.993 51.164-35.423 19.86-82.299 44.576-82.299 106.405V320c0 13.255 10.745 24 24 24h72.471c13.255 0 24-10.745 24-24v-5.773c0-42.86 125.268-44.645 125.268-160.627C377.504 66.256 286.902 0 202.021 0zM192 373.459c-38.196 0-69.271 31.075-69.271 69.271 0 38.195 31.075 69.27 69.271 69.27s69.271-31.075 69.271-69.271-31.075-69.27-69.271-69.27z"],save:[448,512,[],"f0c7","M433.941 129.941l-83.882-83.882A48 48 0 0 0 316.118 32H48C21.49 32 0 53.49 0 80v352c0 26.51 21.49 48 48 48h352c26.51 0 48-21.49 48-48V163.882a48 48 0 0 0-14.059-33.941zM224 416c-35.346 0-64-28.654-64-64 0-35.346 28.654-64 64-64s64 28.654 64 64c0 35.346-28.654 64-64 64zm96-304.52V212c0 6.627-5.373 12-12 12H76c-6.627 0-12-5.373-12-12V108c0-6.627 5.373-12 12-12h228.52c3.183 0 6.235 1.264 8.485 3.515l3.48 3.48A11.996 11.996 0 0 1 320 111.48z"],search:[512,512,[],"f002","M505 442.7L405.3 343c-4.5-4.5-10.6-7-17-7H372c27.6-35.3 44-79.7 44-128C416 93.1 322.9 0 208 0S0 93.1 0 208s93.1 208 208 208c48.3 0 92.7-16.4 128-44v16.3c0 6.4 2.5 12.5 7 17l99.7 99.7c9.4 9.4 24.6 9.4 33.9 0l28.3-28.3c9.4-9.4 9.4-24.6.1-34zM208 336c-70.7 0-128-57.2-128-128 0-70.7 57.2-128 128-128 70.7 0 128 57.2 128 128 0 70.7-57.2 128-128 128z"],share:[512,512,[],"f064","M503.691 189.836L327.687 37.851C312.281 24.546 288 35.347 288 56.015v80.053C127.371 137.907 0 170.1 0 322.326c0 61.441 39.581 122.309 83.333 154.132 13.653 9.931 33.111-2.533 28.077-18.631C66.066 312.814 132.917 274.316 288 272.085V360c0 20.7 24.3 31.453 39.687 18.164l176.004-152c11.071-9.562 11.086-26.753 0-36.328z"],spinner:[512,512,[],"f110","M304 48c0 26.51-21.49 48-48 48s-48-21.49-48-48 21.49-48 48-48 48 21.49 48 48zm-48 368c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48-21.49-48-48-48zm208-208c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48-21.49-48-48-48zM96 256c0-26.51-21.49-48-48-48S0 229.49 0 256s21.49 48 48 48 48-21.49 48-48zm12.922 99.078c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48c0-26.509-21.491-48-48-48zm294.156 0c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48c0-26.509-21.49-48-48-48zM108.922 60.922c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48-21.491-48-48-48z"],square:[448,512,[],"f0c8","M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48z"],"square-full":[512,512,[],"f45c","M512 512H0V0h512v512z"],times:[384,512,[],"f00d","M323.1 441l53.9-53.9c9.4-9.4 9.4-24.5 0-33.9L279.8 256l97.2-97.2c9.4-9.4 9.4-24.5 0-33.9L323.1 71c-9.4-9.4-24.5-9.4-33.9 0L192 168.2 94.8 71c-9.4-9.4-24.5-9.4-33.9 0L7 124.9c-9.4 9.4-9.4 24.5 0 33.9l97.2 97.2L7 353.2c-9.4 9.4-9.4 24.5 0 33.9L60.9 441c9.4 9.4 24.5 9.4 33.9 0l97.2-97.2 97.2 97.2c9.3 9.3 24.5 9.3 33.9 0z"],"times-circle":[512,512,[],"f057","M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm121.6 313.1c4.7 4.7 4.7 12.3 0 17L338 377.6c-4.7 4.7-12.3 4.7-17 0L256 312l-65.1 65.6c-4.7 4.7-12.3 4.7-17 0L134.4 338c-4.7-4.7-4.7-12.3 0-17l65.6-65-65.6-65.1c-4.7-4.7-4.7-12.3 0-17l39.6-39.6c4.7-4.7 12.3-4.7 17 0l65 65.7 65.1-65.6c4.7-4.7 12.3-4.7 17 0l39.6 39.6c4.7 4.7 4.7 12.3 0 17L312 256l65.6 65.1z"],wrench:[512,512,[],"f0ad","M481.156 200c9.3 0 15.12 10.155 10.325 18.124C466.295 259.992 420.419 288 368 288c-79.222 0-143.501-63.974-143.997-143.079C223.505 65.469 288.548-.001 368.002 0c52.362.001 98.196 27.949 123.4 69.743C496.24 77.766 490.523 88 481.154 88H376l-40 56 40 56h105.156zm-171.649 93.003L109.255 493.255c-24.994 24.993-65.515 24.994-90.51 0-24.993-24.994-24.993-65.516 0-90.51L218.991 202.5c16.16 41.197 49.303 74.335 90.516 90.503zM104 432c0-13.255-10.745-24-24-24s-24 10.745-24 24 10.745 24 24 24 24-10.745 24-24z"]};function sC(e,t){var i=document.createElement("div");e.appendChild(i),i.appendChild(rC("times")),i.addEventListener("click",(function(e){e.preventDefault(),e.stopPropagation(),t()}))}var cC=Object.freeze({__proto__:null,attachDialogCloseHandlerWithParent:sC});let lC;function hC(e,t,i){t.addEventListener("mousedown",function(e){e.stopPropagation(),e.preventDefault();const t=dC.bind(this),n=fC.bind(this),o=getComputedStyle(this);lC={constraint:i,dragFunction:t,dragEndFunction:n,screenX:e.screenX,screenY:e.screenY,top:parseInt(o.top.replace("px","")),left:parseInt(o.left.replace("px",""))},document.addEventListener("mousemove",t),document.addEventListener("mouseup",n),document.addEventListener("mouseleave",n),document.addEventListener("mouseexit",n)}.bind(e))}function dC(e){if(!lC)return void console.error("No drag data!");e.stopPropagation(),e.preventDefault();const t=e.screenX-lC.screenX,i=e.screenY-lC.screenY,n=lC.left+t,o=lC.constraint?Math.max(lC.constraint.minY,lC.top+i):lC.top+i;this.style.left=`${n}px`,this.style.top=`${o}px`}function fC(e){if(!lC)return void console.error("No drag data!");e.stopPropagation(),e.preventDefault();const t=lC.dragFunction,i=lC.dragEndFunction;document.removeEventListener("mousemove",t),document.removeEventListener("mouseup",i),document.removeEventListener("mouseleave",i),document.removeEventListener("mouseexit",i),lC=void 0}class uC{constructor({label:e,content:t,okHandler:i,cancelHandler:n}){const o=()=>{Q_(this.elem),"function"==typeof n&&n(this)};this.elem=X_({class:"igv-ui-generic-dialog-container"});const r=X_({class:"igv-ui-generic-dialog-header"});if(this.elem.appendChild(r),sC(r,o),e){const t=X_({class:"igv-ui-dialog-one-liner"});this.elem.appendChild(t),t.innerHTML=e}t.elem.style.margin="8px",this.elem.appendChild(t.elem);const a=X_({class:"igv-ui-generic-dialog-ok-cancel"});this.elem.appendChild(a),this.ok=X_(),a.appendChild(this.ok),this.ok.textContent="OK",this.cancel=X_(),a.appendChild(this.cancel),this.cancel.textContent="Cancel",this.ok.addEventListener("click",(e=>{Q_(this.elem),"function"==typeof i&&i(this)})),this.cancel.addEventListener("click",o),hC(this.elem,r),this.elem.addEventListener("click",(e=>{e.preventDefault(),e.stopPropagation()}))}present(e,t){this.label.textContent=e.label,this.input.value=e.value,this.callback=e.callback;const i=eC(t);this.clampLocation(i.x,i.y),J_(this.elem)}clampLocation(e,t){let i=this.elem.getBoundingClientRect(),n=this.parent.getBoundingClientRect();const o=Math.min(Math.max(t,n.y),n.y+n.height-i.height),r=Math.min(Math.max(e,n.x),n.x+n.width-i.width);this.elem.style.left=r+"px",this.elem.style.top=o+"px"}}class pC{constructor(e,t){const i=new oC;let n;this.minbox=new nC({label:"Minimum",value:"0"}),i.add(this.minbox),this.maxbox=new nC({label:"Maximum",value:"0"}),i.add(this.maxbox),n=t?e=>{t(Number.parseFloat(this.minbox.value),Number.parseFloat(this.maxbox.value))}:e=>{console.log(`Minimum: ${this.minbox.value}`),console.log(`Maximum: ${this.maxbox.value}`)},this.dialog=new uC({content:i,okHandler:n}),this.dialog.elem.style.position="absolute",Q_(this.dialog.elem),e.appendChild(this.dialog.elem)}show({min:e,max:t}){void 0!==e&&(this.minbox.value=e.toString()),void 0!==t&&(this.maxbox.value=t.toString()),J_(this.dialog.elem)}}const mC={401:"Access unauthorized",403:"Access forbidden",404:"Not found"};class gC{constructor(e,t){this.alertProps=Object.assign({shouldFocus:!0,preventScroll:!1},t),this.container=X_({class:"igv-ui-alert-dialog-container"}),e.appendChild(this.container),this.container.setAttribute("tabIndex","-1");const i=X_();this.container.appendChild(i),this.errorHeadline=X_(),i.appendChild(this.errorHeadline),this.errorHeadline.textContent="";let n=X_({class:"igv-ui-alert-dialog-body"});this.container.appendChild(n),this.body=X_({class:"igv-ui-alert-dialog-body-copy"}),n.appendChild(this.body);let o=X_();this.container.appendChild(o),this.ok=X_(),o.appendChild(this.ok),this.ok.textContent="OK";const r=()=>{"function"==typeof this.callback&&(this.callback("OK"),this.callback=void 0),this.body.innerHTML="",Q_(this.container)};this.ok.addEventListener("click",(e=>{e.stopPropagation(),r()})),this.container.addEventListener("keypress",(e=>{e.stopPropagation(),"Enter"===e.key&&r()})),hC(this.container,i),Q_(this.container)}present(e,t){this.errorHeadline.textContent=e.message?"ERROR":"";let i=e.message||e;mC.hasOwnProperty(i)&&(i=mC[i]),this.body.innerHTML=i,this.callback=t,J_(this.container),this.alertProps.shouldFocus&&this.container.focus({preventScroll:this.alertProps.preventScroll})}}let wC;const FC={init(e,t={}){wC=new gC(e,t)},presentAlert(e,t){wC||this.init(document.body),wC.present(e,t)}};class bC{constructor(e){this.parent=e,this.container=X_({class:"igv-ui-generic-dialog-container"}),e.appendChild(this.container);const t=X_({class:"igv-ui-generic-dialog-header"});this.container.appendChild(t),this.label=X_({class:"igv-ui-generic-dialog-one-liner"}),this.container.appendChild(this.label),this.label.text="Unlabeled",this.input_container=X_({class:"igv-ui-generic-dialog-input"}),this.container.appendChild(this.input_container),this.input=document.createElement("input"),this.input_container.appendChild(this.input);const i=X_({class:"igv-ui-generic-dialog-ok-cancel"});this.container.appendChild(i),this.ok=X_(),i.appendChild(this.ok),this.ok.textContent="OK",this.cancel=X_(),i.appendChild(this.cancel),this.cancel.textContent="Cancel",Q_(this.container),this.input.addEventListener("keyup",(e=>{13===e.keyCode&&("function"==typeof this.callback&&(this.callback(this.input.value),this.callback=void 0),this.input.value=void 0,Q_(this.container))})),this.ok.addEventListener("click",(()=>{"function"==typeof this.callback&&(this.callback(this.input.value),this.callback=void 0),this.input.value=void 0,Q_(this.container)}));const n=()=>{this.input.value="",Q_(this.container)};this.cancel.addEventListener("click",n),sC(t,n),hC(this.container,t)}present(e,t){this.label.textContent=e.label,this.input.value=e.value,this.callback=e.callback||e.click,J_(this.container),this.clampLocation(t.clientX,t.clientY)}clampLocation(e,t){const{width:i,height:n}=this.container.getBoundingClientRect(),o=window.innerHeight,r=window.innerWidth,a=Math.min(o-n,t),s=Math.min(r-i,e);this.container.style.left=`${s}px`,this.container.style.top=`${a}px`}}const vC={licorice:"#000000",lead:"#1e1e1e",tungsten:"#3a3a3a",iron:"#545453",steel:"#6e6e6e",tin:"#878687",nickel:"#888787",aluminum:"#a09fa0",magnesium:"#b8b8b8",silver:"#d0d0d0",mercury:"#e8e8e8",snow:"#ffffff",cayenne:"#891100",mocha:"#894800",aspargus:"#888501",fern:"#458401",clover:"#028401",moss:"#018448",teal:"#008688",ocean:"#004a88",midnight:"#001888",eggplant:"#491a88",plum:"#891e88",maroon:"#891648",maraschino:"#ff2101",tangerine:"#ff8802",lemon:"#fffa03",lime:"#83f902",spring:"#05f802",seam_foam:"#03f987",turquoise:"#00fdff",aqua:"#008cff",blueberry:"#002eff",grape:"#8931ff",magenta:"#ff39ff",strawberry:"#ff2987",salmon:"#ff726e",cantaloupe:"#ffce6e",banana:"#fffb6d",honeydew:"#cefa6e",flora:"#68f96e",spindrift:"#68fbd0",ice:"#68fdff",sky:"#6acfff",orchid:"#6e76ff",lavender:"#d278ff",bubblegum:"#ff7aff",carnation:"#ff7fd3"};class yC{constructor({parent:e,top:t,left:i,width:n,height:o,border:r,closeHandler:a}){let s=X_({class:"igv-ui-generic-container"});e.appendChild(s),Q_(s),this.container=s,void 0!==t&&(this.container.style.top=`${t}px`),void 0!==i&&(this.container.style.left=`${i}px`),void 0!==n&&(this.container.style.width=`${n}px`),void 0!==o&&(this.container.style.height=`${o}px`),r&&(this.container.style.border=r);const c=X_();this.container.appendChild(c),sC(c,(e=>{Q_(this.container),"function"==typeof a&&a(e)})),hC(this.container,c)}show(){J_(this.container)}hide(){Q_(this.container)}dispose(){this.container.parent&&this.container.parent.removeChild(this.container)}}class _C extends yC{constructor({parent:e,top:t,left:i,width:n,height:o,defaultColors:r,colorHandler:a}){super({parent:e,top:t,left:i,width:n,height:o,border:"1px solid gray"}),CC(this.container,a,r)}}const CC=(e,t,i)=>{const n=Object.values(vC);for(let i of n){const n=X_({class:"igv-ui-color-swatch"});e.appendChild(n),xC(n,i,t)}if(i)for(let n of i){const i=X_({class:"igv-ui-color-swatch"});e.appendChild(i),xC(i,n,t)}},xC=(e,t,i)=>{e.style.backgroundColor=t,e.addEventListener("mouseenter",(i=>e.style.borderColor=t)),e.addEventListener("mouseleave",(t=>e.style.borderColor="white")),e.addEventListener("click",(e=>{e.stopPropagation(),i(t)})),e.addEventListener("touchend",(e=>{e.stopPropagation(),i(t)}))};if("undefined"!=typeof document){function Gk(e){for(let t of document.styleSheets)if(t=t.href?t.href.replace(/^.*[\\\/]/,""):"",t===e)return!0;return!1}Gk("igv-ui.css")||function(){const e=document.createElement("style");e.setAttribute("type","text/css"),e.setAttribute("title","igv-ui.css"),e.innerHTML='.igv-ui-popover {\n cursor: default;\n position: absolute;\n z-index: 2048;\n border-color: #7F7F7F;\n border-radius: 4px;\n border-style: solid;\n border-width: 1px;\n font-family: "Open Sans", sans-serif;\n font-size: small;\n background-color: white;\n}\n.igv-ui-popover > div:first-child {\n display: flex;\n flex-direction: row;\n flex-wrap: nowrap;\n justify-content: space-between;\n align-items: center;\n width: 100%;\n height: 24px;\n cursor: move;\n border-top-left-radius: 4px;\n border-top-right-radius: 4px;\n border-bottom-color: #7F7F7F;\n border-bottom-style: solid;\n border-bottom-width: thin;\n background-color: #eee;\n}\n.igv-ui-popover > div:first-child > div:first-child {\n margin-left: 4px;\n}\n.igv-ui-popover > div:first-child > div:last-child {\n margin-right: 4px;\n height: 12px;\n width: 12px;\n color: #7F7F7F;\n}\n.igv-ui-popover > div:first-child > div:last-child:hover {\n cursor: pointer;\n color: #444;\n}\n.igv-ui-popover > div:last-child {\n overflow-y: auto;\n overflow-x: hidden;\n max-height: 400px;\n max-width: 800px;\n background-color: white;\n}\n.igv-ui-popover > div:last-child > div {\n -webkit-user-select: text;\n -moz-user-select: text;\n -ms-user-select: text;\n user-select: text;\n margin-left: 4px;\n margin-right: 4px;\n min-width: 220px;\n overflow-x: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.igv-ui-popover > div:last-child > div > span {\n font-weight: bolder;\n}\n.igv-ui-popover > div:last-child hr {\n width: 100%;\n}\n\n.igv-ui-alert-dialog-container {\n box-sizing: content-box;\n position: absolute;\n z-index: 2048;\n top: 50%;\n left: 50%;\n width: 400px;\n height: 200px;\n border-color: #7F7F7F;\n border-radius: 4px;\n border-style: solid;\n border-width: thin;\n outline: none;\n font-family: "Open Sans", sans-serif;\n font-size: 15px;\n font-weight: 400;\n background-color: white;\n display: flex;\n flex-flow: column;\n flex-wrap: nowrap;\n justify-content: space-between;\n align-items: center;\n}\n.igv-ui-alert-dialog-container > div:first-child {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n width: 100%;\n height: 24px;\n cursor: move;\n border-top-left-radius: 4px;\n border-top-right-radius: 4px;\n border-bottom-color: #7F7F7F;\n border-bottom-style: solid;\n border-bottom-width: thin;\n background-color: #eee;\n}\n.igv-ui-alert-dialog-container > div:first-child div:first-child {\n padding-left: 8px;\n}\n.igv-ui-alert-dialog-container .igv-ui-alert-dialog-body {\n -webkit-user-select: text;\n -moz-user-select: text;\n -ms-user-select: text;\n user-select: text;\n color: #373737;\n width: 100%;\n height: calc(100% - 24px - 64px);\n overflow-y: scroll;\n}\n.igv-ui-alert-dialog-container .igv-ui-alert-dialog-body .igv-ui-alert-dialog-body-copy {\n margin: 16px;\n width: auto;\n height: auto;\n overflow-wrap: break-word;\n word-break: break-word;\n background-color: white;\n border: unset;\n}\n.igv-ui-alert-dialog-container > div:last-child {\n width: 100%;\n margin-bottom: 10px;\n background-color: white;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: center;\n align-items: center;\n}\n.igv-ui-alert-dialog-container > div:last-child div {\n margin: unset;\n width: 40px;\n height: 30px;\n line-height: 30px;\n text-align: center;\n color: white;\n font-family: "Open Sans", sans-serif;\n font-size: small;\n font-weight: 400;\n border-color: #2B81AF;\n border-style: solid;\n border-width: thin;\n border-radius: 4px;\n background-color: #2B81AF;\n}\n.igv-ui-alert-dialog-container > div:last-child div:hover {\n cursor: pointer;\n border-color: #25597f;\n background-color: #25597f;\n}\n\n.igv-ui-color-swatch {\n position: relative;\n box-sizing: content-box;\n display: flex;\n flex-flow: row;\n flex-wrap: wrap;\n justify-content: center;\n align-items: center;\n width: 32px;\n height: 32px;\n border-style: solid;\n border-width: 2px;\n border-color: white;\n border-radius: 4px;\n}\n\n.igv-ui-color-swatch:hover {\n border-color: dimgray;\n}\n\n.igv-ui-colorpicker-menu-close-button {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-end;\n align-items: center;\n width: 100%;\n height: 32px;\n margin-top: 4px;\n margin-bottom: 4px;\n padding-right: 8px;\n}\n.igv-ui-colorpicker-menu-close-button i.fa {\n display: block;\n margin-left: 4px;\n margin-right: 4px;\n color: #5f5f5f;\n}\n.igv-ui-colorpicker-menu-close-button i.fa:hover,\n.igv-ui-colorpicker-menu-close-button i.fa:focus,\n.igv-ui-colorpicker-menu-close-button i.fa:active {\n cursor: pointer;\n color: #0f0f0f;\n}\n\n.igv-ui-generic-dialog-container {\n box-sizing: content-box;\n position: fixed;\n top: 0;\n left: 0;\n width: 300px;\n height: 200px;\n border-color: #7F7F7F;\n border-radius: 4px;\n border-style: solid;\n border-width: thin;\n font-family: "Open Sans", sans-serif;\n font-size: medium;\n font-weight: 400;\n z-index: 2048;\n background-color: white;\n display: flex;\n flex-flow: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n}\n.igv-ui-generic-dialog-container .igv-ui-generic-dialog-header {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-end;\n align-items: center;\n width: 100%;\n height: 24px;\n cursor: move;\n border-top-left-radius: 4px;\n border-top-right-radius: 4px;\n border-bottom-color: #7F7F7F;\n border-bottom-style: solid;\n border-bottom-width: thin;\n background-color: #eee;\n}\n.igv-ui-generic-dialog-container .igv-ui-generic-dialog-header div {\n margin-right: 4px;\n margin-bottom: 2px;\n height: 12px;\n width: 12px;\n color: #7F7F7F;\n}\n.igv-ui-generic-dialog-container .igv-ui-generic-dialog-header div:hover {\n cursor: pointer;\n color: #444;\n}\n.igv-ui-generic-dialog-container .igv-ui-generic-dialog-one-liner {\n color: #373737;\n width: 95%;\n height: 24px;\n line-height: 24px;\n text-align: left;\n margin-top: 8px;\n padding-left: 8px;\n overflow-wrap: break-word;\n background-color: white;\n}\n.igv-ui-generic-dialog-container .igv-ui-generic-dialog-label-input {\n margin-top: 8px;\n width: 95%;\n height: 24px;\n color: #373737;\n line-height: 24px;\n padding-left: 8px;\n background-color: white;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n}\n.igv-ui-generic-dialog-container .igv-ui-generic-dialog-label-input div {\n width: 30%;\n height: 100%;\n font-size: 16px;\n text-align: right;\n padding-right: 8px;\n background-color: white;\n}\n.igv-ui-generic-dialog-container .igv-ui-generic-dialog-label-input input {\n display: block;\n height: 100%;\n width: 100%;\n padding-left: 4px;\n font-family: "Open Sans", sans-serif;\n font-weight: 400;\n color: #373737;\n text-align: left;\n outline: none;\n border-style: solid;\n border-width: thin;\n border-color: #7F7F7F;\n background-color: white;\n}\n.igv-ui-generic-dialog-container .igv-ui-generic-dialog-label-input input {\n width: 50%;\n font-size: 16px;\n}\n.igv-ui-generic-dialog-container .igv-ui-generic-dialog-input {\n margin-top: 8px;\n width: calc(100% - 16px);\n height: 24px;\n color: #373737;\n line-height: 24px;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-around;\n align-items: center;\n}\n.igv-ui-generic-dialog-container .igv-ui-generic-dialog-input input {\n display: block;\n height: 100%;\n width: 100%;\n padding-left: 4px;\n font-family: "Open Sans", sans-serif;\n font-weight: 400;\n color: #373737;\n text-align: left;\n outline: none;\n border-style: solid;\n border-width: thin;\n border-color: #7F7F7F;\n background-color: white;\n}\n.igv-ui-generic-dialog-container .igv-ui-generic-dialog-input input {\n font-size: 16px;\n}\n.igv-ui-generic-dialog-container .igv-ui-generic-dialog-ok-cancel {\n width: 100%;\n height: 28px;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-around;\n align-items: center;\n}\n.igv-ui-generic-dialog-container .igv-ui-generic-dialog-ok-cancel div {\n margin-top: 32px;\n color: white;\n font-family: "Open Sans", sans-serif;\n font-size: 14px;\n font-weight: 400;\n width: 75px;\n height: 28px;\n line-height: 28px;\n text-align: center;\n border-color: transparent;\n border-style: solid;\n border-width: thin;\n border-radius: 2px;\n}\n.igv-ui-generic-dialog-container .igv-ui-generic-dialog-ok-cancel div:first-child {\n margin-left: 32px;\n margin-right: 0;\n background-color: #5ea4e0;\n}\n.igv-ui-generic-dialog-container .igv-ui-generic-dialog-ok-cancel div:last-child {\n margin-left: 0;\n margin-right: 32px;\n background-color: #c4c4c4;\n}\n.igv-ui-generic-dialog-container .igv-ui-generic-dialog-ok-cancel div:first-child:hover {\n cursor: pointer;\n background-color: #3b5c7f;\n}\n.igv-ui-generic-dialog-container .igv-ui-generic-dialog-ok-cancel div:last-child:hover {\n cursor: pointer;\n background-color: #7f7f7f;\n}\n.igv-ui-generic-dialog-container .igv-ui-generic-dialog-ok {\n width: 100%;\n height: 36px;\n margin-top: 32px;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-around;\n align-items: center;\n}\n.igv-ui-generic-dialog-container .igv-ui-generic-dialog-ok div {\n width: 98px;\n height: 36px;\n line-height: 36px;\n text-align: center;\n color: white;\n font-family: "Open Sans", sans-serif;\n font-size: medium;\n font-weight: 400;\n border-color: white;\n border-style: solid;\n border-width: thin;\n border-radius: 4px;\n background-color: #2B81AF;\n}\n.igv-ui-generic-dialog-container .igv-ui-generic-dialog-ok div:hover {\n cursor: pointer;\n background-color: #25597f;\n}\n\n.igv-ui-generic-container {\n box-sizing: content-box;\n position: absolute;\n z-index: 2048;\n background-color: white;\n cursor: pointer;\n display: flex;\n flex-direction: row;\n flex-wrap: wrap;\n justify-content: flex-start;\n align-items: center;\n}\n.igv-ui-generic-container > div:first-child {\n cursor: move;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-end;\n align-items: center;\n height: 24px;\n width: 100%;\n background-color: #dddddd;\n}\n.igv-ui-generic-container > div:first-child > div {\n display: block;\n color: #5f5f5f;\n cursor: pointer;\n width: 14px;\n height: 14px;\n margin-right: 8px;\n margin-bottom: 4px;\n}\n\n.igv-ui-dialog {\n z-index: 2048;\n position: fixed;\n width: fit-content;\n height: fit-content;\n display: flex;\n flex-flow: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n background-color: white;\n border-color: #7F7F7F;\n border-radius: 4px;\n border-style: solid;\n border-width: thin;\n font-family: "Open Sans", sans-serif;\n font-size: medium;\n font-weight: 400;\n}\n.igv-ui-dialog .igv-ui-dialog-header {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-end;\n align-items: center;\n width: 100%;\n height: 24px;\n cursor: move;\n border-top-left-radius: 4px;\n border-top-right-radius: 4px;\n border-bottom-color: #7F7F7F;\n border-bottom-style: solid;\n border-bottom-width: thin;\n background-color: #eee;\n}\n.igv-ui-dialog .igv-ui-dialog-header div {\n margin-right: 4px;\n margin-bottom: 2px;\n height: 12px;\n width: 12px;\n color: #7F7F7F;\n}\n.igv-ui-dialog .igv-ui-dialog-header div:hover {\n cursor: pointer;\n color: #444;\n}\n.igv-ui-dialog .igv-ui-dialog-one-liner {\n width: 95%;\n height: 24px;\n line-height: 24px;\n text-align: left;\n margin: 8px;\n overflow-wrap: break-word;\n background-color: white;\n font-weight: bold;\n}\n.igv-ui-dialog .igv-ui-dialog-ok-cancel {\n width: 100%;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-around;\n align-items: center;\n}\n.igv-ui-dialog .igv-ui-dialog-ok-cancel div {\n margin: 16px;\n margin-top: 32px;\n color: white;\n font-family: "Open Sans", sans-serif;\n font-size: 14px;\n font-weight: 400;\n width: 75px;\n height: 28px;\n line-height: 28px;\n text-align: center;\n border-color: transparent;\n border-style: solid;\n border-width: thin;\n border-radius: 2px;\n}\n.igv-ui-dialog .igv-ui-dialog-ok-cancel div:first-child {\n background-color: #5ea4e0;\n}\n.igv-ui-dialog .igv-ui-dialog-ok-cancel div:last-child {\n background-color: #c4c4c4;\n}\n.igv-ui-dialog .igv-ui-dialog-ok-cancel div:first-child:hover {\n cursor: pointer;\n background-color: #3b5c7f;\n}\n.igv-ui-dialog .igv-ui-dialog-ok-cancel div:last-child:hover {\n cursor: pointer;\n background-color: #7f7f7f;\n}\n.igv-ui-dialog .igv-ui-dialog-ok {\n width: 100%;\n height: 36px;\n margin-top: 32px;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-around;\n align-items: center;\n}\n.igv-ui-dialog .igv-ui-dialog-ok div {\n width: 98px;\n height: 36px;\n line-height: 36px;\n text-align: center;\n color: white;\n font-family: "Open Sans", sans-serif;\n font-size: medium;\n font-weight: 400;\n border-color: white;\n border-style: solid;\n border-width: thin;\n border-radius: 4px;\n background-color: #2B81AF;\n}\n.igv-ui-dialog .igv-ui-dialog-ok div:hover {\n cursor: pointer;\n background-color: #25597f;\n}\n\n.igv-ui-panel, .igv-ui-panel-row, .igv-ui-panel-column {\n z-index: 2048;\n background-color: white;\n font-family: "Open Sans", sans-serif;\n font-size: medium;\n font-weight: 400;\n display: flex;\n justify-content: flex-start;\n align-items: flex-start;\n}\n\n.igv-ui-panel-column {\n display: flex;\n flex-direction: column;\n}\n\n.igv-ui-panel-row {\n display: flex;\n flex-direction: row;\n}\n\n.igv-ui-textbox {\n background-color: white;\n font-family: "Open Sans", sans-serif;\n font-size: medium;\n font-weight: 400;\n display: flex;\n justify-content: flex-start;\n align-items: flex-start;\n}\n\n.igv-ui-table {\n background-color: white;\n}\n\n.igv-ui-table thead {\n position: sticky;\n top: 0;\n}\n\n.igv-ui-table th {\n text-align: left;\n}\n\n.igv-ui-table td {\n padding-right: 20px;\n}\n\n.igv-ui-table tr:hover {\n background-color: lightblue;\n}\n\n/*# sourceMappingURL=igv-ui.css.map */\n',document.head.append(e)}()}function kC(e){if(void 0===e)return;let t=(o(e)||e.google_url?e.name:e).toLowerCase(),i=t.indexOf("?");return i>0&&(t=t.substr(0,i)),t.endsWith(".gz")?t=t.substr(0,t.length-3):(t.endsWith(".txt")||t.endsWith(".tab")||t.endsWith(".bgz"))&&(t=t.substr(0,t.length-4)),i=t.lastIndexOf("."),i<0?t:t.substr(1+i)}const EC={};class NC{constructor(){this.subscribers={},this.stack=[]}subscribe(e,t){var i=this.subscribers[e];null==i&&(i=[],this.subscribers[e]=i),i.push(t)}post(e){const t=e.type;if(this._hold)this.stack.push(e);else{const i=this.subscribers[t];if(i)for(let t of i)"function"==typeof t.receiveEvent?t.receiveEvent(e):"function"==typeof t&&t(e)}}hold(){this._hold=!0}release(){this._hold=!1;for(let e of this.stack)this.post(e);this.stack=[]}}NC.globalBus=new NC;class SC{static DisplayModes={lower:1,upper:2,both:3};constructor(e,t){this.config=e,this.name=e.name,e.color&&function(e){var t=document.createElement("div");return t.style.borderColor=e,""!==t.style.borderColor}(e.color)&&(this.color=this.color=e.color),this.displayMode=e.displayMode,this.isVisible=void 0===e.isVisible||e.isVisible,this.repColor=t.length>0?t[0].color:"black",this.featureMap={},this.featureCount=0;for(let e of t){this.featureCount++;const t=IC(e.chr1,e.chr2);let i=this.featureMap[t];i||(i=[],this.featureMap[t]=i),i.push(e)}}static async loadTrack2D(e,t){const n=await en.loadString(e.url,function(e,t){const i={oauthToken:e.oauthToken,headers:e.headers,withCredentials:e.withCredentials,filename:e.filename};return Object.assign(i,t)}(e)),o=function(e,t,n){if(!e)return null;const o=i(e),r=[],a="\t",s=t?10:6;let c=0;for(let e of o){if(e=e.trim(),e.startsWith("#")||e.startsWith("track")||e.startsWith("browser")||0===e.length)continue;const t=e.split(a);if(t.length<6&&c<=5){5===c?console.error("..."):console.error("Could not parse line: "+e),c++;continue}const i={chr1:n?n.getChromosomeName(t[0]):t[0],x1:parseInt(t[1]),x2:parseInt(t[2]),chr2:n?n.getChromosomeName(t[3]):t[3],y1:parseInt(t[4]),y2:parseInt(t[5])};t.length>s&&(i.color="rgb("+t[s]+")"),Number.isNaN(i.x1)||r.push(i)}return r}(n,function(e){return"string"==typeof e.url?e.url.toLowerCase().indexOf(".bedpe")>0:"string"!=typeof e.name||e.name.toLowerCase().indexOf(".bedpe")>0}(e),t);return new SC(e,o)}getColor(){return this.color||this.repColor}getFeatures(e,t){const i=IC(e,t);return this.featureMap[i]}toJSON(){const e={url:this.config.url};return this.name&&(e.name=this.name),this.color&&(e.color=this.color),this.displayMode&&(e.displayMode=this.displayMode),this.isVisible||(e.isVisible=this.isVisible),e}}function IC(e,t){return e>t?t+"_"+e:e+"_"+t}class zC{constructor(e,t,i){this.browser=e,this.axis=i,this.axisElement=t.querySelector("div[id$='-axis']"),this.canvasElement=t.querySelector("canvas"),this.ctx=this.canvasElement.getContext("2d"),this.ctx.canvas.width=this.axisElement.offsetWidth,this.ctx.canvas.height=this.axisElement.offsetHeight,this.wholeGenomeContainerElement=t.querySelector("div[id$='-axis-whole-genome-container']"),this.setAxisTransform(i),e.eventBus.subscribe("MapLoad",this),e.eventBus.subscribe("UpdateContactMapMousePosition",this)}wholeGenomeLayout(e,t,i,n){const o=e=>{e.addEventListener("click",(()=>{this.browser.parseGotoInput(e.textContent),this.unhighlightWholeChromosome(),this.otherRuler.unhighlightWholeChromosome()})),e.addEventListener("mouseenter",(()=>{r.call(this,e,!0)})),e.addEventListener("mouseleave",(()=>{r.call(this,e,!1)}))},r=(e,t)=>{const i=e.dataset.label;Array.from(this.otherRuler.wholeGenomeContainerElement.children).forEach((n=>{n.dataset.label===i&&(t?(e.classList.add("hic-whole-genome-chromosome-highlight"),n.classList.add("hic-whole-genome-chromosome-highlight")):(e.classList.remove("hic-whole-genome-chromosome-highlight"),n.classList.remove("hic-whole-genome-chromosome-highlight")))}))};let a,s,c,l,h;t.innerHTML="",a=n.chromosomes.filter((e=>"all"!==e.name.toLowerCase())),c=a.reduce(((e,t)=>e+t.size),0),s="x"===i?e.offsetWidth:e.offsetHeight,l=0,this.bboxes=[],h=void 0;for(const e of a){const n=e.bpLength/c;if(n*s<1)l+=n;else{const r=document.createElement("div");r.className=`${this.axis}-axis-whole-genome-chromosome-container`,r.dataset.label=e.name,t.appendChild(r),h||(h=r);const a=Math.round(n*s);"x"===i?r.style.width=`${a}px`:r.style.height=`${a}px`;const c=document.createElement("div");r.appendChild(c);const l=document.createElement("div");c.appendChild(l),l.textContent=r.dataset.label,l.title=r.dataset.label,o(r)}}if(l=Math.floor(l*s),l>=1){const e=document.createElement("div");t.appendChild(e),e.className=`${this.axis}-axis-whole-genome-chromosome-container`,e.dataset.label="-",e.style.width=`${l}px`,o(e)}for(const e of t.children)this.bboxes.push(AC(i,e,h));this.hideWholeGenome()}hideWholeGenome(){this.wholeGenomeContainerElement.style.display="none",this.canvasElement.style.display="block"}showWholeGenome(){this.canvasElement.style.display="none",this.wholeGenomeContainerElement.style.display="flex"}setAxisTransform(e){this.canvasTransform="y"===e?TC:LC,this.labelTransform="y"===e?RC:BC}unhighlightWholeChromosome(){for(const e of this.wholeGenomeContainerElement.children)e.classList.remove("hic-whole-genome-chromosome-highlight")}receiveEvent(e){let t,i;"MapLoad"===e.type?(this.wholeGenomeLayout(this.axisElement,this.wholeGenomeContainerElement,this.axis,e.data),this.update()):"UpdateContactMapMousePosition"===e.type&&this.bboxes&&(this.unhighlightWholeChromosome(),t="x"===this.axis?e.data.x:e.data.y,i=function(e,t){let i;for(const n of e)if(t>=n.a&&t<=n.b){i=n.element;break}return i}(this.bboxes,t),i&&i.classList.add("hic-whole-genome-chromosome-highlight"))}locusChange(e){this.update()}updateWidthWithCalculation(e){this.axisElement.style.width=e;const t=this.axisElement.offsetWidth;this.canvasElement.width=t,this.canvasElement.setAttribute("width",t),this.wholeGenomeLayout(this.axisElement,this.wholeGenomeContainerElement,this.axis,this.browser.dataset),this.update()}updateHeight(e){this.canvasElement.height=e,this.canvasElement.setAttribute("height",e),this.wholeGenomeLayout(this.axisElement,this.wholeGenomeContainerElement,this.axis,this.browser.dataset),this.update()}update(){const e=this.browser,t={};if(e.dataset.isWholeGenome(e.state.chr1))return void this.showWholeGenome();this.hideWholeGenome(),LC(this.ctx),K_.IGVGraphics.fillRect(this.ctx,0,0,this.canvasElement.width,this.canvasElement.height,{fillStyle:Hi.rgbColor(255,255,255)}),this.canvasTransform(this.ctx);const i="x"===this.axis?this.canvasElement.width:this.canvasElement.height,n="x"===this.axis?this.canvasElement.height:this.canvasElement.width;K_.IGVGraphics.fillRect(this.ctx,0,0,i,n,{fillStyle:Hi.rgbColor(255,255,255)}),t.bpPerPixel=e.dataset.bpResolutions[e.state.zoom]/e.state.pixelSize;const o="x"===this.axis?e.state.x:e.state.y;t.bpStart=o*e.dataset.bpResolutions[e.state.zoom],t.rulerTickMarkReferencePixels=Math.max(this.canvasElement.width,this.canvasElement.height,this.otherRulerCanvas.width,this.otherRulerCanvas.height),t.rulerLengthPixels=i,t.rulerHeightPixels=n,t.height=Math.min(this.canvasElement.width,this.canvasElement.height),this.draw(t)}draw(e){const{rulerLengthPixels:t,rulerHeightPixels:i,rulerTickMarkReferencePixels:n,bpPerPixel:o,bpStart:r,chrName:a}=e,{chromosomes:s}=this.browser.dataset,{state:c}=this.browser,l="x"===this.axis?s[c.chr1]:s[c.chr2],{name:h,size:d}=l;if("all"!==a){K_.IGVGraphics.fillRect(this.ctx,0,0,t,i,{fillStyle:Hi.rgbColor(255,255,255)});const a={textAlign:"center",font:"9px PT Sans",fillStyle:"rgba(64, 64, 64, 1)",strokeStyle:"rgba(64, 64, 64, 1)"},s=function(e){if(e<10)return new MC(1,"",1);var t=Math.floor(o(e)),i="",n=1;t>9&&(i="gb",n=1e9);t>6?(i="mb",n=1e6):t>3&&(i="kb",n=1e3);return e/Math.pow(10,t-1)<25?new MC(Math.pow(10,t-1),i,n):new MC(Math.pow(10,t)/2,i,n);function o(e){var t=Math.log(10);return Math.log(e)/t}}(Math.floor(n*o)),c=s.majorTick;let l=Math.floor(r/c)-1,h=0,f=0;K_.IGVGraphics.setProperties(this.ctx,a),this.ctx.lineWidth=1;const u=1,p=8;for(;hn?n<32?4:2:1)==0&&Math.floor(h*o+r){const i=Math.min(Math.max(t,0),3),n=Math.abs(e).toFixed(i);let[o,r]=n.split(".");o=parseInt(o,10).toLocaleString(),i>0&&(r=r.padEnd(i,"0"));let a=i>0?`${o}.${r}`:o;return e<0&&(a=`(${a})`),a};function AC(e,t,i){const n=("x"===e?t.getBoundingClientRect().left:t.getBoundingClientRect().top)-("x"===e?i.getBoundingClientRect().left:i.getBoundingClientRect().top);return{element:t,a:n,b:n+("x"===e?t.offsetWidth:t.offsetHeight)}}function MC(e,t,i){this.majorTick=e,this.majorUnit=t,this.unitMultiplier=i}function TC(e){e.setTransform(0,1,1,0,0,0)}function RC(e,t){e.translate(t,0),e.scale(-1,1),e.translate(-t,0)}function LC(e){e.setTransform(1,0,0,1,0,0)}function BC(e){}const HC=(e,t)=>{const i=document.createElement("div");i.className="jb-igv-menu-popup-check-container";const n=document.createElement("div");i.appendChild(n);const o=OC("check",!0===t?"#444":"transparent");n.appendChild(o);const r=document.createElement("div");return r.textContent=e,i.appendChild(r),i};const OC=(e,t="currentColor")=>{const i=PC[e]??PC.question;PC[e]||console.error(`No icon named: ${e}`);const[n,o,,,r]=i,a="http://www.w3.org/2000/svg",s=document.createElementNS(a,"svg");s.setAttribute("viewBox",`0 0 ${n} ${o}`),s.setAttribute("xmlns",a),s.setAttribute("aria-label",`${e} icon`),s.setAttribute("role","img");const c=document.createElementNS(a,"path");return c.setAttribute("fill",t),c.setAttribute("d",r),s.appendChild(c),s},PC={check:[512,512,[],"f00c","M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z"],cog:[512,512,[],"f013","M444.788 291.1l42.616 24.599c4.867 2.809 7.126 8.618 5.459 13.985-11.07 35.642-29.97 67.842-54.689 94.586a12.016 12.016 0 0 1-14.832 2.254l-42.584-24.595a191.577 191.577 0 0 1-60.759 35.13v49.182a12.01 12.01 0 0 1-9.377 11.718c-34.956 7.85-72.499 8.256-109.219.007-5.49-1.233-9.403-6.096-9.403-11.723v-49.184a191.555 191.555 0 0 1-60.759-35.13l-42.584 24.595a12.016 12.016 0 0 1-14.832-2.254c-24.718-26.744-43.619-58.944-54.689-94.586-1.667-5.366.592-11.175 5.459-13.985L67.212 291.1a193.48 193.48 0 0 1 0-70.199l-42.616-24.599c-4.867-2.809-7.126-8.618-5.459-13.985 11.07-35.642 29.97-67.842 54.689-94.586a12.016 12.016 0 0 1 14.832-2.254l42.584 24.595a191.577 191.577 0 0 1 60.759-35.13V25.759a12.01 12.01 0 0 1 9.377-11.718c34.956-7.85 72.499-8.256 109.219-.007 5.49 1.233 9.403 6.096 9.403 11.723v49.184a191.555 191.555 0 0 1 60.759 35.13l42.584-24.595a12.016 12.016 0 0 1 14.832 2.254c24.718 26.744 43.619 58.944 54.689 94.586 1.667 5.366-.592 11.175-5.459 13.985L444.788 220.9a193.485 193.485 0 0 1 0 70.2zM336 256c0-44.112-35.888-80-80-80s-80 35.888-80 80 35.888 80 80 80 80-35.888 80-80z"],exclamation:[192,512,[],"f12a","M176 432c0 44.112-35.888 80-80 80s-80-35.888-80-80 35.888-80 80-80 80 35.888 80 80zM25.26 25.199l13.6 272C39.499 309.972 50.041 320 62.83 320h66.34c12.789 0 23.331-10.028 23.97-22.801l13.6-272C167.425 11.49 156.496 0 142.77 0H49.23C35.504 0 24.575 11.49 25.26 25.199z"],"exclamation-circle":[512,512,[],"f06a","M504 256c0 136.997-111.043 248-248 248S8 392.997 8 256C8 119.083 119.043 8 256 8s248 111.083 248 248zm-248 50c-25.405 0-46 20.595-46 46s20.595 46 46 46 46-20.595 46-46-20.595-46-46-46zm-43.673-165.346l7.418 136c.347 6.364 5.609 11.346 11.982 11.346h48.546c6.373 0 11.635-4.982 11.982-11.346l7.418-136c.375-6.874-5.098-12.654-11.982-12.654h-63.383c-6.884 0-12.356 5.78-11.981 12.654z"],"exclamation-triangle":[576,512,[],"f071","M569.517 440.013C587.975 472.007 564.806 512 527.94 512H48.054c-36.937 0-59.999-40.055-41.577-71.987L246.423 23.985c18.467-32.009 64.72-31.951 83.154 0l239.94 416.028zM288 354c-25.405 0-46 20.595-46 46s20.595 46 46 46 46-20.595 46-46-20.595-46-46-46zm-43.673-165.346l7.418 136c.347 6.364 5.609 11.346 11.982 11.346h48.546c6.373 0 11.635-4.982 11.982-11.346l7.418-136c.375-6.874-5.098-12.654-11.982-12.654h-63.383c-6.884 0-12.356 5.78-11.981 12.654z"],minus:[448,512,[],"f068","M424 318.2c13.3 0 24-10.7 24-24v-76.4c0-13.3-10.7-24-24-24H24c-13.3 0-24 10.7-24 24v76.4c0 13.3 10.7 24 24 24h400z"],"minus-circle":[512,512,[],"f056","M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zM124 296c-6.6 0-12-5.4-12-12v-56c0-6.6 5.4-12 12-12h264c6.6 0 12 5.4 12 12v56c0 6.6-5.4 12-12 12H124z"],"minus-square":[448,512,[],"f146","M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM92 296c-6.6 0-12-5.4-12-12v-56c0-6.6 5.4-12 12-12h264c6.6 0 12 5.4 12 12v56c0 6.6-5.4 12-12 12H92z"],plus:[448,512,[],"f067","M448 294.2v-76.4c0-13.3-10.7-24-24-24H286.2V56c0-13.3-10.7-24-24-24h-76.4c-13.3 0-24 10.7-24 24v137.8H24c-13.3 0-24 10.7-24 24v76.4c0 13.3 10.7 24 24 24h137.8V456c0 13.3 10.7 24 24 24h76.4c13.3 0 24-10.7 24-24V318.2H424c13.3 0 24-10.7 24-24z"],"plus-circle":[512,512,[],"f055","M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm144 276c0 6.6-5.4 12-12 12h-92v92c0 6.6-5.4 12-12 12h-56c-6.6 0-12-5.4-12-12v-92h-92c-6.6 0-12-5.4-12-12v-56c0-6.6 5.4-12 12-12h92v-92c0-6.6 5.4-12 12-12h56c6.6 0 12 5.4 12 12v92h92c6.6 0 12 5.4 12 12v56z"],"plus-square":[448,512,[],"f0fe","M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-32 252c0 6.6-5.4 12-12 12h-92v92c0 6.6-5.4 12-12 12h-56c-6.6 0-12-5.4-12-12v-92H92c-6.6 0-12-5.4-12-12v-56c0-6.6 5.4-12 12-12h92v-92c0-6.6 5.4-12 12-12h56c6.6 0 12 5.4 12 12v92h92c6.6 0 12 5.4 12 12v56z"],question:[384,512,[],"f128","M202.021 0C122.202 0 70.503 32.703 29.914 91.026c-7.363 10.58-5.093 25.086 5.178 32.874l43.138 32.709c10.373 7.865 25.132 6.026 33.253-4.148 25.049-31.381 43.63-49.449 82.757-49.449 30.764 0 68.816 19.799 68.816 49.631 0 22.552-18.617 34.134-48.993 51.164-35.423 19.86-82.299 44.576-82.299 106.405V320c0 13.255 10.745 24 24 24h72.471c13.255 0 24-10.745 24-24v-5.773c0-42.86 125.268-44.645 125.268-160.627C377.504 66.256 286.902 0 202.021 0zM192 373.459c-38.196 0-69.271 31.075-69.271 69.271 0 38.195 31.075 69.27 69.271 69.27s69.271-31.075 69.271-69.271-31.075-69.27-69.271-69.27z"],save:[448,512,[],"f0c7","M433.941 129.941l-83.882-83.882A48 48 0 0 0 316.118 32H48C21.49 32 0 53.49 0 80v352c0 26.51 21.49 48 48 48h352c26.51 0 48-21.49 48-48V163.882a48 48 0 0 0-14.059-33.941zM224 416c-35.346 0-64-28.654-64-64 0-35.346 28.654-64 64-64s64 28.654 64 64c0 35.346-28.654 64-64 64zm96-304.52V212c0 6.627-5.373 12-12 12H76c-6.627 0-12-5.373-12-12V108c0-6.627 5.373-12 12-12h228.52c3.183 0 6.235 1.264 8.485 3.515l3.48 3.48A11.996 11.996 0 0 1 320 111.48z"],search:[512,512,[],"f002","M505 442.7L405.3 343c-4.5-4.5-10.6-7-17-7H372c27.6-35.3 44-79.7 44-128C416 93.1 322.9 0 208 0S0 93.1 0 208s93.1 208 208 208c48.3 0 92.7-16.4 128-44v16.3c0 6.4 2.5 12.5 7 17l99.7 99.7c9.4 9.4 24.6 9.4 33.9 0l28.3-28.3c9.4-9.4 9.4-24.6.1-34zM208 336c-70.7 0-128-57.2-128-128 0-70.7 57.2-128 128-128 70.7 0 128 57.2 128 128 0 70.7-57.2 128-128 128z"],share:[512,512,[],"f064","M503.691 189.836L327.687 37.851C312.281 24.546 288 35.347 288 56.015v80.053C127.371 137.907 0 170.1 0 322.326c0 61.441 39.581 122.309 83.333 154.132 13.653 9.931 33.111-2.533 28.077-18.631C66.066 312.814 132.917 274.316 288 272.085V360c0 20.7 24.3 31.453 39.687 18.164l176.004-152c11.071-9.562 11.086-26.753 0-36.328z"],spinner:[512,512,[],"f110","M304 48c0 26.51-21.49 48-48 48s-48-21.49-48-48 21.49-48 48-48 48 21.49 48 48zm-48 368c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48-21.49-48-48-48zm208-208c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48-21.49-48-48-48zM96 256c0-26.51-21.49-48-48-48S0 229.49 0 256s21.49 48 48 48 48-21.49 48-48zm12.922 99.078c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48c0-26.509-21.491-48-48-48zm294.156 0c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48c0-26.509-21.49-48-48-48zM108.922 60.922c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48-21.491-48-48-48z"],square:[448,512,[],"f0c8","M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48z"],"square-full":[512,512,[],"f45c","M512 512H0V0h512v512z"],times:[384,512,[],"f00d","M323.1 441l53.9-53.9c9.4-9.4 9.4-24.5 0-33.9L279.8 256l97.2-97.2c9.4-9.4 9.4-24.5 0-33.9L323.1 71c-9.4-9.4-24.5-9.4-33.9 0L192 168.2 94.8 71c-9.4-9.4-24.5-9.4-33.9 0L7 124.9c-9.4 9.4-9.4 24.5 0 33.9l97.2 97.2L7 353.2c-9.4 9.4-9.4 24.5 0 33.9L60.9 441c9.4 9.4 24.5 9.4 33.9 0l97.2-97.2 97.2 97.2c9.3 9.3 24.5 9.3 33.9 0z"],"times-circle":[512,512,[],"f057","M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm121.6 313.1c4.7 4.7 4.7 12.3 0 17L338 377.6c-4.7 4.7-12.3 4.7-17 0L256 312l-65.1 65.6c-4.7 4.7-12.3 4.7-17 0L134.4 338c-4.7-4.7-4.7-12.3 0-17l65.6-65-65.6-65.1c-4.7-4.7-4.7-12.3 0-17l39.6-39.6c4.7-4.7 12.3-4.7 17 0l65 65.7 65.1-65.6c4.7-4.7 12.3-4.7 17 0l39.6 39.6c4.7 4.7 4.7 12.3 0 17L312 256l65.6 65.1z"],wrench:[512,512,[],"f0ad","M481.156 200c9.3 0 15.12 10.155 10.325 18.124C466.295 259.992 420.419 288 368 288c-79.222 0-143.501-63.974-143.997-143.079C223.505 65.469 288.548-.001 368.002 0c52.362.001 98.196 27.949 123.4 69.743C496.24 77.766 490.523 88 481.154 88H376l-40 56 40 56h105.156zm-171.649 93.003L109.255 493.255c-24.994 24.993-65.515 24.994-90.51 0-24.993-24.994-24.993-65.516 0-90.51L218.991 202.5c16.16 41.197 49.303 74.335 90.516 90.503zM104 432c0-13.255-10.745-24-24-24s-24 10.745-24 24 10.745 24 24 24 24-10.745 24-24z"]},qC={trackMenuItemList:e=>{const t=[];return t.push(function(e){const t=document.createElement("div");t.textContent="Set track name";const i=t=>{const i=t=>{let i;i=""===t||void 0===t?"":t.trim(),e.track.name=i},n=e.track.name||"";e.browser.inputDialog.present({label:"Track Name",value:n,callback:i},t)};return{element:t,click:i}}(e)),t.push("
"),t.push(function({trackPair:e,label:t,option:i}){const n=document.createElement("div");n.textContent=t;const o=()=>e.colorPicker.show();return{element:n,click:o}}({trackPair:e,label:"Set color",option:"color"})),t.push(function({trackPair:e,label:t}){const i=document.createElement("div");i.textContent=t;const n=()=>{e.track.color=void 0,e.repaintViews()};return{element:i,click:n}}({trackPair:e,label:"Unset color"})),!1!==e.track.removable&&(t.push("
"),t.push(function(e){const t=document.createElement("div");t.textContent="Remove track";const i=()=>e.browser.layoutController.removeTrackXYPair(e);return{element:t,click:i}}(e))),t},numericDataMenuItems:e=>{const t=[],i=document.createElement("div");i.textContent="Set data range";return t.push({element:i,click:()=>{const{min:t,max:i}=e.track.dataRange;e.dataRangeDialog.show({min:t||0,max:i})}}),void 0!==e.track.logScale&&t.push({element:HC("Log scale",e.track.logScale),click:()=>{e.track.logScale=!e.track.logScale,e.repaintViews()}}),t.push({element:HC("Autoscale",e.track.autoscale),click:()=>{e.track.autoscale=!e.track.autoscale,e.repaintViews()}}),t},nucleotideColorChartMenuItems:e=>{const t=[];t.push(document.createElement("hr"));const i=document.createElement("div");i.className="jb-igv-menu-popup-chart",i.innerHTML="\n
A
\n
C
\n
T
\n
G
\n ";return t.push({element:i,click:e=>{e.preventDefault(),e.stopPropagation()}}),t}};class VC{constructor(e){this.popoverElement=document.createElement("div"),this.popoverElement.className="jb-igv-menu-popup",e.appendChild(this.popoverElement);const t=document.createElement("div");t.className="jb-igv-menu-popup-header",this.popoverElement.appendChild(t),cC.attachDialogCloseHandlerWithParent(t,(()=>{this.popoverElement.style.display="none"})),this.popoverContentElement=document.createElement("div"),this.popoverElement.appendChild(this.popoverContentElement),hC(this.popoverElement,t),t.addEventListener("click",(e=>{e.stopPropagation(),e.preventDefault()}))}presentMenuList(e,t,i){if(VC.hideAllMenuPopups(),i.length>0){this.popoverContentElement.innerHTML="";const n=function(e,t){let i=[];e.length>0&&(i=e.map(((e,i)=>{let n;if(e.name)n=document.createElement("div"),n.textContent=e.name;else if(e.element)n=e.element instanceof HTMLElement?e.element.cloneNode(!0):e.element;else if("string"==typeof e.label)n=document.createElement("div"),n.innerHTML=e.label;else if("string"==typeof e)if(e.startsWith("<")){const t=document.createElement("div");t.innerHTML=e,n=t.firstElementChild}else n=document.createElement("div"),n.textContent=e;if(0===i&&n&&n.classList.add("igv-track-menu-border-top"),e.click&&n){const i=i=>{i.preventDefault(),i.stopPropagation(),e.click(i),t.style.display="none"};n.addEventListener("click",i),n.addEventListener("touchend",i),n.addEventListener("mouseup",(e=>{e.preventDefault(),e.stopPropagation()}))}return{element:n,init:e.init||void 0}})));return i}(i,this.popoverElement);for(const e of n)e.init&&e.init(),0===n.indexOf(e)&&e.element.classList.remove("igv-track-menu-border-top"),e.element.classList.contains("igv-track-menu-border-top")||e.element.classList.contains("jb-igv-menu-popup-check-container")||"DIV"!==e.element.tagName||e.element.classList.add("jb-igv-menu-popup-shim"),this.popoverContentElement.appendChild(e.element);this.popoverElement.style.left=`${e}px`,this.popoverElement.style.top=`${t}px`,this.popoverElement.style.display="block"}}dispose(){this.popoverElement.innerHTML="",this.popoverContentElement.innerHTML="";for(let e of Object.keys(this))this[e]=void 0}static hideAllMenuPopups(){const e=document.querySelectorAll(".jb-igv-menu-popup");for(let t of e)t.style.display="none"}}class UC{constructor(e,t,i,n,o,r){this.chr=e,this.startBP=t,this.endBP=i,this.bpp=n,this.buffer=o,this.features=r}containsRange(e,t,i,n){return e===this.chr&&this.bpp===n&&this.startBP<=t&&this.endBP>=i}}class jC{constructor(e,t){this.browser=e,this.track=t,this.x=void 0,this.y=void 0}init(){this.colorPicker=new _C({parent:this.x.viewportElement,width:456,height:void 0,colorHandler:e=>this.setColor(e)}),this.colorPicker.hide(),this.dataRangeDialog=new pC(this.x.viewportElement,((e,t)=>this.setDataRange(e,t))),this.appendRightHandGutter(this.x.viewportElement);for(const e of this.x.trackReorderHandleElement.querySelectorAll(".fa"))e.addEventListener("click",(e=>{e.preventDefault(),e.stopPropagation();const t=e.target.classList.contains("fa-arrow-up")?-1:1;let i=parseInt(this.x.viewportElement.style.order);if(0===i&&-1===t)return;if(this.browser.trackPairs.length-1===i&&1===t)return;const n=-1===t?i-1:i+1,o=this.browser.trackPairs.find((e=>n===parseInt(e.x.viewportElement.style.order)));o&&(o.x.viewportElement.style.order=`${i}`,o.y.viewportElement.style.order=`${i}`),this.x.viewportElement.style.order=`${n}`,this.y.viewportElement.style.order=`${n}`;const r=this.browser.trackPairs;[r[i],r[n]]=[r[n],r[i]],WC(this.browser.trackPairs)}));this.track.trackView=this,this.track.trackView.trackDiv=this.x.viewportElement}presentColorPicker(){const e=this.x.trackDiv.getBoundingClientRect();this.colorPicker.origin={x:e.x,y:0},this.colorPicker.containerElement.style.left=`${this.colorPicker.origin.x}px`,this.colorPicker.containerElement.style.top=`${this.colorPicker.origin.y}px`,this.colorPicker.containerElement.style.display="block"}setTrackLabelName(e){this.x.labelElement.textContent=e,this.x.labelElement.title=e}setColor(e){this.y.tile=void 0,this.x.tile=void 0,this.track.color=e,this.repaintViews()}dataRange(){return this.track.dataRange?this.track.dataRange:void 0}setDataRange(e,t){void 0!==e&&(this.track.dataRange.min=e,this.track.config.min=e),void 0!==t&&(this.track.dataRange.max=t,this.track.config.max=t),this.track.autoscale=!1,this.track.config.autoScale=!1,this.y.tile=void 0,this.x.tile=void 0,this.repaintViews()}appendRightHandGutter(e){const t=document.createElement("div");t.className="hic-igv-right-hand-gutter",e.appendChild(t),this.createTrackGearPopup(t)}createTrackGearPopup(e){const t=document.createElement("div");t.className="igv-trackgear-container",e.appendChild(t),t.appendChild(function(e,t){return OC(e,t)}("cog")),this.trackGearPopup=new VC(e),this.trackGearPopup.popoverElement.style.display="none",t.addEventListener("click",(e=>{e.preventDefault(),e.stopPropagation();const{trackMenuItemList:t,numericDataMenuItems:i,nucleotideColorChartMenuItems:n}=qC,o=[...t(this)];"wig"===this.track.type&&o.push(...i(this)),"sequence"===this.track.type&&o.push(...n(this));const r=this.trackGearPopup.popoverElement.getBoundingClientRect().width;this.trackGearPopup.presentMenuList(-r,0,o)}))}async updateViews(){if(this.updating)this.pending=!0;else try{this.updating=!0;const e=this.browser.genomicState(this.x.axis);let t=await this.getTileX(e);t&&this.x.drawTile(t,e);const i=this.browser.genomicState(this.y.axis);let n=await this.getTileY(i);n&&this.y.drawTile(n,i)}finally{this.updating=!1,this.pending&&(this.pending=!1,this.updateViews())}}async repaintViews(){const e=this.browser.genomicState(this.x.axis);this.tileX&&(this.tileX=await this.createImageTile({axis:"x",...e},this.tileX.features),this.x.drawTile(this.tileX,e));const t=this.browser.genomicState(this.y.axis);this.tileY&&(this.tileY=await this.createImageTile({axis:"y",...t},this.tileY.features),this.y.drawTile(this.tileY,t))}async getTileX(e){const{chromosome:t,bpp:i}=e;return this.tileX&&this.tileX.containsRange(t.name,e.startBP,e.endBP,i)||(this.tileX=await this.createImageTile({axis:"x",...e})),this.tileX}async getTileY(e){const{chromosome:t,bpp:i}=e;return this.tileY&&this.tileY.containsRange(t.name,e.startBP,e.endBP,i)||(this.tileY=await this.createImageTile({axis:"y",...e})),this.tileY}async createImageTile(e,t){if(!(this.track.visibilityWindow>0&&e.bpp*Math.max(this.x.canvasElement.width,this.x.canvasElement.height)>this.track.visibilityWindow)){const i=3*this.x.canvasElement.width,n=Math.round(e.bpp*i),o=Math.max(0,Math.round(e.startBP-n/3)),r=o+n,a=t||await this.track.getFeatures(e.chromosome.name,o,r,e.bpp),s=document.createElement("canvas");s.width=i,s.height=this.x.canvasElement.height;const c=s.getContext("2d");if(a){const t={axis:e.axis,features:a,context:c,pixelWidth:i,bpStart:o,bpEnd:r,bpPerPixel:e.bpp,genomicState:e,pixelHeight:Math.min(s.width,s.height),viewportContainerX:(e.startBP-o)/e.bpp,viewportContainerWidth:i,viewportWidth:i,referenceFrame:{}};!this.track.autoscale&&this.track.dataRange||("function"==typeof this.track.doAutoscale?this.track.doAutoscale(a):this.track.dataRange=function(e=[]){let t=Number.MAX_VALUE,i=-Number.MAX_VALUE;if(e.length>0){for(const{value:n}of e)Number.isNaN(n)||(t=Math.min(t,n),i=Math.max(i,n));i>0&&(t=Math.min(0,t)),i<0&&(i=0)}else t=0,i=100;return{min:t,max:i}}(a)),this.track.draw(t)}else{const e=s.height-s.height/4;K_.IGVGraphics.fillRect(c,0,e,s.width,2,{fillStyle:"rgba(0,0,0,0.1)"})}return this.tile=new UC(e.chromosome.name,o,r,e.bpp,s,a),this.tile}}dispose(){this.x.dispose(),this.y.dispose()}}function WC(e){for(const t of e){const i=t.x.viewportElement,n=parseInt(i.style.order),o=i.querySelector(".fa-arrow-up"),r=i.querySelector(".fa-arrow-down");0===n?(o.style.color="rgba(0, 0, 0, 0)",r.style.color="#7F7F7F"):n===e.length-1?(o.style.color="#7F7F7F",r.style.color="rgba(0, 0, 0, 0)"):(o.style.color="#7F7F7F",r.style.color="#7F7F7F")}}class GC{constructor(e,t,i){this.browser=e,this.track=t,this.axis=i,this.id=`trackRender_${iC.guid()}`}init(e,t,i){if(this.viewportElement=document.createElement("div"),this.viewportElement.className="x"===this.axis?"x-track-canvas-container":"y-track-canvas-container",e.appendChild(this.viewportElement),"x"===this.axis?this.viewportElement.style.height=`${t}px`:this.viewportElement.style.width=`${t}px`,this.viewportElement.style.order=`${i}`,this.canvasElement=document.createElement("canvas"),this.viewportElement.appendChild(this.canvasElement),this.ctx=this.canvasElement.getContext("2d"),"x"===this.axis){this.trackReorderHandleElement=document.createElement("div"),this.trackReorderHandleElement.className="x-track-reorder-handle",this.viewportElement.appendChild(this.trackReorderHandleElement),this.trackReorderHandleElement.innerHTML='',this.labelElement=document.createElement("div"),this.labelElement.className="x-track-label",this.viewportElement.appendChild(this.labelElement);const e=this.track.name||"";this.labelElement.textContent=e,this.labelElement.title=e,this.labelElement.style.display=this.browser.showTrackLabelAndGutter?"block":"none",this.viewportElement.addEventListener("click",(e=>{e.preventDefault(),e.stopPropagation(),this.browser.toggleTrackLabelAndGutterState();const t=this.browser.showTrackLabelAndGutter?"block":"none";document.querySelectorAll(".x-track-label, .hic-igv-right-hand-gutter").forEach((e=>{e.style.display=t}))}))}this.spinnerElement=document.createElement("div"),this.spinnerElement.className="x"===this.axis?"x-track-spinner":"y-track-spinner",this.viewportElement.appendChild(this.spinnerElement),this.stopSpinner()}dispose(){this.tile=void 0,this.viewportElement.remove()}syncCanvas(){this.canvasElement.width=this.viewportElement.offsetWidth,this.canvasElement.height=this.viewportElement.offsetHeight}drawTile(e,t){if(e){let i,n;"x"===this.axis?(i=this.canvasElement.width,n=this.canvasElement.height):(n=this.canvasElement.width,i=this.canvasElement.height,this.ctx.setTransform(0,1,1,0,0,0)),this.ctx.clearRect(0,0,i,n),this.offsetPixel=Math.round((e.startBP-t.startBP)/t.bpp),this.ctx.drawImage(e.buffer,this.offsetPixel,0)}}startSpinner(){this.browser.startSpinner()}stopSpinner(){this.browser.stopSpinner()}isLoading(){return void 0!==this.loading}}function $C(e,t,i){return{type:e,data:t||{},propogate:void 0===i||i}}function ZC(e){return!!e&&("function"!=typeof e&&(e instanceof File||void 0!==e.name&&"function"==typeof e.slice&&"function"==typeof e.arrayBuffer))}function KC(e){const t=document.createElement("template");return t.innerHTML=e.trim(),t.content.firstElementChild}function XC(e){const t=e.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/);if(!t)throw new Error("Invalid RGB string format");return t.slice(1,4).map(Number)}function YC(e){if("number"!=typeof e)return void console.error(`${e} must be a number`);return Math.trunc(e).toLocaleString()}function QC(e){if(void 0===e.name){const t=e.url;if(ZC(t))return t.name;{const e=t.split("?").shift(),i=t.lastIndexOf("/");return i>0?e.substring(i+1):e}}return e.name}class JC{constructor(e,t){this.browser=e,function(e,t){const i=document.createElement("div");i.className="hic-navbar-container",t.appendChild(i),i.addEventListener("click",(t=>{t.stopPropagation(),t.preventDefault(),gk(e)}));const n=`
\n
\n
\n \n \n
\n
`;i.appendChild(KC(n)),e.contactMapLabel=i.querySelector("div[id$='contact-map-hic-nav-bar-map-label']"),e.menuPresentDismiss=i.querySelector(".fa-bars"),e.menuPresentDismiss.addEventListener("click",(t=>e.toggleMenu())),e.browserPanelDeleteButton=i.querySelector(".fa-minus-circle"),e.browserPanelDeleteButton.addEventListener("click",(t=>function(e){e.unsyncSelf(),e.rootElement.remove(),mk=mk.filter((t=>t!==e)),mk.length<=1&&mk.forEach((e=>e.browserPanelDeleteButton.style.display="none"))}(e))),e.browserPanelDeleteButton.style.display="none";const o=`
\n
\n
`;i.appendChild(KC(o)),e.controlMapLabel=i.querySelector("div[id$='control-map-hic-nav-bar-map-label']");const r=`
`;i.appendChild(KC(r));const a=`
`;i.appendChild(KC(a))}(e,t),this.createAllContainers(e,t)}createAllContainers(e,t){const i=KC(`\n
\n
\n
\n \n
\n
`);t.appendChild(i),this.xTrackContainer=t.querySelector("div[id$='x-track-container']"),this.trackShim=this.xTrackContainer.querySelector("div[id$='track-shim']"),this.xTracks=this.xTrackContainer.querySelector("div[id$='x-tracks']"),this.yTrackGuideElement=this.xTrackContainer.querySelector("div[id$='y-track-guide']"),this.contentContainer=KC(`
`),t.appendChild(this.contentContainer);const n=KC(`\n
\n
\n \n
\n
\n
`);this.contentContainer.appendChild(n);const o=this.contentContainer.querySelector("div[id$='x-axis-container']");this.xAxisRuler=new zC(e,o,"x");const r=KC(`\n
\n
\n \n
\n
\n \n
\n
\n
`);this.contentContainer.appendChild(r);const a=this.contentContainer.querySelector("div[id$='-y-tracks-y-axis-viewport-y-scrollbar']");this.yTracks=a.querySelector("div[id$='-y-tracks']"),this.xTrackGuideElement=this.yTracks.querySelector("div[id$='-x-track-guide']"),this.yAxisRuler=new zC(e,a,"y"),this.xAxisRuler.otherRulerCanvas=this.yAxisRuler.canvasElement,this.xAxisRuler.otherRuler=this.yAxisRuler,this.yAxisRuler.otherRulerCanvas=this.xAxisRuler.canvasElement,this.yAxisRuler.otherRuler=this.xAxisRuler;const s=KC(`\n
\n \n \n \n \n \n
`);a.appendChild(s);const c=KC(`\n
\n
\n
\n
\n
`);a.appendChild(c);const l=KC(`\n
\n
\n
\n
\n
\n
\n
`);this.contentContainer.appendChild(l)}getContactMatrixViewport(){const e=this.contentContainer.querySelector("div[id$='-y-tracks-y-axis-viewport-y-scrollbar']");return e?e.querySelector("div[id$='-viewport']"):null}getYAxisScrollbarContainer(){const e=this.contentContainer.querySelector("div[id$='-y-tracks-y-axis-viewport-y-scrollbar']");return e?e.querySelector("div[id$='-y-axis-scrollbar-container']"):null}getXAxisScrollbarContainer(){return this.contentContainer.querySelector("div[id$='-x-axis-scrollbar-container']")}updateLayoutWithTracks(e){const{trackHeight:t}=nx();this.resizeLayoutWithTrackXYPairCount(e.length+this.browser.trackPairs.length);for(const i of e){const e=new jC(this.browser,i);this.browser.trackPairs.unshift(e),e.x=new GC(this.browser,i,"x"),e.x.init(this.xTracks,t,this.browser.trackPairs.indexOf(e)),e.y=new GC(this.browser,i,"y"),e.y.init(this.yTracks,t,this.browser.trackPairs.indexOf(e)),e.init(),NC.globalBus.post($C("TrackXYPairLoad",e))}for(const e of this.browser.trackPairs){const t=`${this.browser.trackPairs.indexOf(e)}`;e.x.viewportElement.style.order=t,e.y.viewportElement.style.order=t}WC(this.browser.trackPairs)}removeAllTrackXYPairs(){if(0!==this.browser.trackPairs.length){for(let e of this.browser.trackPairs)e.dispose();this.browser.trackPairs=[],this.browser.updateLayout(),this.resizeLayoutWithTrackXYPairCount(0)}}removeTrackXYPair(e){if(this.browser.trackPairs.length>0){e.x.viewportElement.remove(),e.y.viewportElement.remove();const t=this.browser.trackPairs.indexOf(e);this.browser.trackPairs.splice(t,1),this.resizeLayoutWithTrackXYPairCount(this.browser.trackPairs.length),this.browser.updateLayout(),NC.globalBus.post($C("TrackXYPairRemoval",e))}}resizeLayoutWithTrackXYPairCount(e){const{trackHeight:t,trackMargin:i,axisHeight:n,scrollbarHeight:o}=nx(),r=0===e?0:e*(t+i);let a=[ex(),r].map((e=>`${e}px`));const s=`calc(100% - (${a.join(" + ")}))`;a=[r,n,o].map((e=>`${e}px`));const c=`calc(100% - (${a.join(" + ")}))`;this.xTrackContainer.style.height=`${r}px`,this.trackShim.style.width=`${r}px`,this.xTracks.style.width=c,this.contentContainer.style.height=s,this.xAxisRuler.updateWidthWithCalculation(c),this.yTracks.style.width=`${r}px`,this.yAxisRuler.updateHeight(this.yAxisRuler.axisElement.offsetHeight),this.browser.contactMatrixView.viewportElement.style.width=c,this.browser.contactMatrixView.scrollbarWidget.xAxisScrollbarContainerElement.style.width=c}}function ex(){const{navBarLabelHeight:e,navBarWidgetContainerHeight:t,navBarWidgetContainerMargin:i}=nx();return 2*(e+t+2*i)}function tx(e){return parseInt(getComputedStyle(document.documentElement).getPropertyValue(e))}function ix(e,t){document.documentElement.style.setProperty(e,`${t}px`)}function nx(){return{navBarLabelHeight:tx("--nav-bar-label-height"),navBarWidgetContainerHeight:tx("--nav-bar-widget-container-height"),navBarWidgetContainerMargin:tx("--nav-bar-widget-container-margin"),scrollbarHeight:tx("--hic-scrollbar-height"),axisHeight:tx("--hic-axis-height"),trackMargin:tx("--track-margin"),trackHeight:tx("--track-height")}}var ox={Huffman:{},Util:{},CRC32:{},CompressionMethod:{DEFLATE:8,RESERVED:15},Zip:function(e){e=e||{},this.files=[],this.comment=e.comment,this.password}};ox.Zip.CompressionMethod={STORE:0,DEFLATE:8},ox.Zip.OperatingSystem={MSDOS:0,UNIX:3,MACINTOSH:7},ox.Zip.Flags={ENCRYPT:1,DESCRIPTOR:8,UTF8:2048},ox.Zip.FileHeaderSignature=[80,75,1,2],ox.Zip.LocalFileHeaderSignature=[80,75,3,4],ox.Zip.CentralDirectorySignature=[80,75,5,6],ox.Zip.prototype.addFile=function(e,t){var i;(t=t||{}).filename;var n=e.length,o=0;if(e instanceof Array&&(e=new Uint8Array(e)),"number"!=typeof t.compressionMethod&&(t.compressionMethod=ox.Zip.CompressionMethod.DEFLATE),t.compress)switch(t.compressionMethod){case ox.Zip.CompressionMethod.STORE:break;case ox.Zip.CompressionMethod.DEFLATE:o=ox.CRC32.calc(e),e=this.deflateWithOption(e,t),i=!0;break;default:throw new Error("unknown compression method:"+t.compressionMethod)}this.files.push({buffer:e,option:t,compressed:i,encrypted:!1,size:n,crc32:o})},ox.Zip.prototype.setPassword=function(e){this.password=e},ox.Zip.prototype.compress=function(){var e,t,i,n,o,r,a,s,c,l,h,d,f,u,p,m,g,w,F,b,v,y,_,C,x,k,E=this.files,N=0,S=0;for(_=0,C=E.length;_>8&255,c=e.option.compressionMethod,t[i++]=t[n++]=255&c,t[i++]=t[n++]=c>>8&255,l=e.option.date||new Date,t[i++]=t[n++]=(7&l.getMinutes())<<5|l.getSeconds()/2,t[i++]=t[n++]=l.getHours()<<3|l.getMinutes()>>3,t[i++]=t[n++]=(l.getMonth()+1&7)<<5|l.getDate(),t[i++]=t[n++]=(l.getFullYear()-1980&127)<<1|l.getMonth()+1>>3,h=e.crc32,t[i++]=t[n++]=255&h,t[i++]=t[n++]=h>>8&255,t[i++]=t[n++]=h>>16&255,t[i++]=t[n++]=h>>24&255,d=e.buffer.length,t[i++]=t[n++]=255&d,t[i++]=t[n++]=d>>8&255,t[i++]=t[n++]=d>>16&255,t[i++]=t[n++]=d>>24&255,f=e.size,t[i++]=t[n++]=255&f,t[i++]=t[n++]=f>>8&255,t[i++]=t[n++]=f>>16&255,t[i++]=t[n++]=f>>24&255,t[i++]=t[n++]=255&u,t[i++]=t[n++]=u>>8&255,t[i++]=t[n++]=255&p,t[i++]=t[n++]=p>>8&255,t[n++]=255&m,t[n++]=m>>8&255,t[n++]=0,t[n++]=0,t[n++]=0,t[n++]=0,t[n++]=0,t[n++]=0,t[n++]=0,t[n++]=0,t[n++]=255&a,t[n++]=a>>8&255,t[n++]=a>>16&255,t[n++]=a>>24&255,(g=e.option.filename)&&(t.set(g,i),t.set(g,n),i+=u,n+=u),(w=e.option.extraField)&&(t.set(w,i),t.set(w,n),i+=p,n+=p),(F=e.option.comment)&&(t.set(F,n),n+=m),t.set(e.buffer,i),i+=e.buffer.length;return t[o++]=ox.Zip.CentralDirectorySignature[0],t[o++]=ox.Zip.CentralDirectorySignature[1],t[o++]=ox.Zip.CentralDirectorySignature[2],t[o++]=ox.Zip.CentralDirectorySignature[3],t[o++]=0,t[o++]=0,t[o++]=0,t[o++]=0,t[o++]=255&C,t[o++]=C>>8&255,t[o++]=255&C,t[o++]=C>>8&255,t[o++]=255&S,t[o++]=S>>8&255,t[o++]=S>>16&255,t[o++]=S>>24&255,t[o++]=255&N,t[o++]=N>>8&255,t[o++]=N>>16&255,t[o++]=N>>24&255,m=this.comment?this.comment.length:0,t[o++]=255&m,t[o++]=m>>8&255,this.comment&&(t.set(this.comment,o),o+=m),t},ox.Zip.prototype.deflateWithOption=function(e,t){return new ox.RawDeflate(e,t.deflateOption).compress()},ox.Zip.prototype.getByte=function(e){var t=65535&e[2]|2;return t*(1^t)>>8&255},ox.Zip.prototype.encode=function(e,t){var i=this.getByte(e);return this.updateKeys(e,t),i^t},ox.Zip.prototype.updateKeys=function(e,t){e[0]=ox.CRC32.single(e[0],t),e[1]=1+(6681*(20173*(e[1]+(255&e[0]))>>>0)>>>0)>>>0,e[2]=ox.CRC32.single(e[2],e[1]>>>24)},ox.Zip.prototype.createEncryptionKey=function(e){var t,i,n=[305419896,591751049,878082192];for(n=new Uint32Array(n),t=0,i=e.length;tu&&(u=e[c]),e[c]>=1;for(d=n<<16|c,h=a;h>>=1){case 0:this.parseUncompressedBlock();break;case 1:this.parseFixedHuffmanBlock();break;case 2:this.parseDynamicHuffmanBlock();break;default:throw new Error("unknown BTYPE: "+e)}},ox.RawInflate.prototype.readBits=function(e){var t,i=this.bitsbuf,n=this.bitsbuflen,o=this.input,r=this.ip;if(r+(e-n+7>>3)>=o.length)throw new Error("input buffer is broken");for(;n>>=e,n-=e,this.bitsbuf=i,this.bitsbuflen=n,this.ip=r,t},ox.RawInflate.prototype.readCodeByTable=function(e){for(var t,i,n=this.bitsbuf,o=this.bitsbuflen,r=this.input,a=this.ip,s=r.length,c=e[0],l=e[1];o=s);)n|=r[a++]<>>16)>o)throw new Error("invalid code length: "+i);return this.bitsbuf=n>>i,this.bitsbuflen=o-i,this.ip=a,65535&t},ox.RawInflate.prototype.parseUncompressedBlock=function(){var e,t,i=this.input,n=this.ip,o=this.output,r=this.op,a=i.length,s=o.length;if(this.bitsbuf=0,this.bitsbuflen=0,n+1>=a)throw new Error("invalid uncompressed block header: LEN");if(e=i[n++]|i[n++]<<8,n+1>=a)throw new Error("invalid uncompressed block header: NLEN");if(e===~(i[n++]|i[n++]<<8))throw new Error("invalid uncompressed block header: length verify");if(n+e>i.length)throw new Error("input buffer is broken");switch(this.bufferType){case ox.RawInflate.BufferType.BLOCK:for(;r+e>o.length;)e-=t=s-r,o.set(i.subarray(n,n+t),r),r+=t,n+=t,this.op=r,o=this.expandBufferBlock(),r=this.op;break;case ox.RawInflate.BufferType.ADAPTIVE:for(;r+e>o.length;)o=this.expandBufferAdaptive({fixRatio:2});break;default:throw new Error("invalid inflate mode")}o.set(i.subarray(n,n+e),r),r+=e,n+=e,this.ip=n,this.op=r,this.output=o},ox.RawInflate.prototype.parseFixedHuffmanBlock=function(){switch(this.bufferType){case ox.RawInflate.BufferType.ADAPTIVE:this.decodeHuffmanAdaptive(ox.RawInflate.FixedLiteralLengthTable,ox.RawInflate.FixedDistanceTable);break;case ox.RawInflate.BufferType.BLOCK:this.decodeHuffmanBlock(ox.RawInflate.FixedLiteralLengthTable,ox.RawInflate.FixedDistanceTable);break;default:throw new Error("invalid inflate mode")}},ox.RawInflate.prototype.parseDynamicHuffmanBlock=function(){var e,t,i,n,o,r,a,s,c,l=this.readBits(5)+257,h=this.readBits(5)+1,d=this.readBits(4)+4,f=new Uint8Array(ox.RawInflate.Order.length);for(s=0;s=c&&(this.op=n,i=this.expandBufferBlock(),n=this.op),i[n++]=o;else for(s=l[r=o-257],h[r]>0&&(s+=this.readBits(h[r])),a=d[o=this.readCodeByTable(t)],f[o]>0&&(a+=this.readBits(f[o])),n>=c&&(this.op=n,i=this.expandBufferBlock(),n=this.op);s--;)i[n]=i[n++-a];for(;this.bitsbuflen>=8;)this.bitsbuflen-=8,this.ip--;this.op=n},ox.RawInflate.prototype.decodeHuffmanAdaptive=function(e,t){var i=this.output,n=this.op;this.currentLitlenTable=e;for(var o,r,a,s,c=i.length,l=ox.RawInflate.LengthCodeTable,h=ox.RawInflate.LengthExtraTable,d=ox.RawInflate.DistCodeTable,f=ox.RawInflate.DistExtraTable;256!==(o=this.readCodeByTable(e));)if(o<256)n>=c&&(c=(i=this.expandBufferAdaptive()).length),i[n++]=o;else for(s=l[r=o-257],h[r]>0&&(s+=this.readBits(h[r])),a=d[o=this.readCodeByTable(t)],f[o]>0&&(a+=this.readBits(f[o])),n+s>c&&(c=(i=this.expandBufferAdaptive()).length);s--;)i[n]=i[n++-a];for(;this.bitsbuflen>=8;)this.bitsbuflen-=8,this.ip--;this.op=n},ox.RawInflate.prototype.expandBufferBlock=function(e){var t=new Uint8Array(this.op-ox.RawInflate.MaxBackwardLength),i=this.op-ox.RawInflate.MaxBackwardLength,n=this.output;return t.set(n.subarray(ox.RawInflate.MaxBackwardLength,t.length)),this.blocks.push(t),this.totalpos+=t.length,n.set(n.subarray(i,i+ox.RawInflate.MaxBackwardLength)),this.op=ox.RawInflate.MaxBackwardLength,n},ox.RawInflate.prototype.expandBufferAdaptive=function(e){var t,i,n,o=this.input.length/this.ip+1|0,r=this.input,a=this.output;return e&&("number"==typeof e.fixRatio&&(o=e.fixRatio),"number"==typeof e.addRatio&&(o+=e.addRatio)),i=o<2?(n=(r.length-this.ip)/this.currentLitlenTable[2]/2*258|0)>>=1){case 0:this.currentBlockType=ox.RawInflateStream.BlockType.UNCOMPRESSED;break;case 1:this.currentBlockType=ox.RawInflateStream.BlockType.FIXED;break;case 2:this.currentBlockType=ox.RawInflateStream.BlockType.DYNAMIC;break;default:throw new Error("unknown BTYPE: "+e)}this.status=ox.RawInflateStream.Status.BLOCK_HEADER_END},ox.RawInflateStream.prototype.readBits=function(e){for(var t,i=this.bitsbuf,n=this.bitsbuflen,o=this.input,r=this.ip;n>>=e,n-=e,this.bitsbuf=i,this.bitsbuflen=n,this.ip=r,t},ox.RawInflateStream.prototype.readCodeByTable=function(e){for(var t,i,n=this.bitsbuf,o=this.bitsbuflen,r=this.input,a=this.ip,s=e[0],c=e[1];o>>16)>o)throw new Error("invalid code length: "+i);return this.bitsbuf=n>>i,this.bitsbuflen=o-i,this.ip=a,65535&t},ox.RawInflateStream.prototype.readUncompressedBlockHeader=function(){var e,t=this.input,i=this.ip;if(this.status=ox.RawInflateStream.Status.BLOCK_BODY_START,i+4>=t.length)return-1;if((e=t[i++]|t[i++]<<8)===~(t[i++]|t[i++]<<8))throw new Error("invalid uncompressed block header: length verify");this.bitsbuf=0,this.bitsbuflen=0,this.ip=i,this.blockLength=e,this.status=ox.RawInflateStream.Status.BLOCK_BODY_END},ox.RawInflateStream.prototype.parseUncompressedBlock=function(){var e=this.input,t=this.ip,i=this.output,n=this.op,o=this.blockLength;for(this.status=ox.RawInflateStream.Status.DECODE_BLOCK_START;o--;){if(n===i.length&&(i=this.expandBuffer({fixRatio:2})),t>=e.length)return this.ip=t,this.op=n,this.blockLength=o+1,-1;i[n++]=e[t++]}return o<0&&(this.status=ox.RawInflateStream.Status.DECODE_BLOCK_END),this.ip=t,this.op=n,0},ox.RawInflateStream.prototype.parseFixedHuffmanBlock=function(){return this.status=ox.RawInflateStream.Status.BLOCK_BODY_START,this.litlenTable=ox.RawInflateStream.FixedLiteralLengthTable,this.distTable=ox.RawInflateStream.FixedDistanceTable,this.status=ox.RawInflateStream.Status.BLOCK_BODY_END,0},ox.RawInflateStream.prototype.save_=function(){this.ip_=this.ip,this.bitsbuflen_=this.bitsbuflen,this.bitsbuf_=this.bitsbuf},ox.RawInflateStream.prototype.restore_=function(){this.ip=this.ip_,this.bitsbuflen=this.bitsbuflen_,this.bitsbuf=this.bitsbuf_},ox.RawInflateStream.prototype.parseDynamicHuffmanBlock=function(){var e,t,i,n,o=new Uint8Array(ox.RawInflateStream.Order.length);if(this.status=ox.RawInflateStream.Status.BLOCK_BODY_START,this.save_(),e=this.readBits(5)+257,t=this.readBits(5)+1,i=this.readBits(4)+4,e<0||t<0||i<0)return this.restore_(),-1;try{(function(){var r,a,s,c,l,h,d=0;for(l=0;l0){if((o=this.readBits(ox.RawInflateStream.LengthExtraTable[t]))<0)return this.op=a,this.restore_(),-1;n+=o}if((e=this.readCodeByTable(c))<0)return this.op=a,this.restore_(),-1;if(i=ox.RawInflateStream.DistCodeTable[e],ox.RawInflateStream.DistExtraTable[e]>0){if((o=this.readBits(ox.RawInflateStream.DistExtraTable[e]))<0)return this.op=a,this.restore_(),-1;i+=o}for(a+n>=l&&(l=(r=this.expandBuffer()).length);n--;)r[a]=r[a++-i];if(this.ip===this.input.length)return this.op=a,-1}}for(;this.bitsbuflen>=8;)this.bitsbuflen-=8,this.ip--;this.op=a,this.status=ox.RawInflateStream.Status.DECODE_BLOCK_END},ox.RawInflateStream.prototype.expandBuffer=function(e){var t,i,n,o=this.input.length/this.ip+1|0,r=this.input,a=this.output;return e&&("number"==typeof e.fixRatio&&(o=e.fixRatio),"number"==typeof e.addRatio&&(o+=e.addRatio)),i=o<2?(n=(r.length-this.ip)/this.litlenTable[2]/2*258|0)ox.RawInflateStream.MaxBackwardLength+this.bufferSize&&(this.op=this.sp=ox.RawInflateStream.MaxBackwardLength,t=this.output,this.output=new Uint8Array(this.bufferSize+ox.RawInflateStream.MaxBackwardLength),this.output.set(t.subarray(i-ox.RawInflateStream.MaxBackwardLength,i))),e},ox.Inflate=function(e,t){var i,n;if(this.input=e,this.ip=0,this.rawinflate,this.verify,!t&&(t={})||(t.index&&(this.ip=t.index),t.verify&&(this.verify=t.verify)),i=e[this.ip++],n=e[this.ip++],(15&i)!==ox.CompressionMethod.DEFLATE)throw new Error("unsupported compression method");if(this.method=ox.CompressionMethod.DEFLATE,((i<<8)+n)%31!=0)throw new Error("invalid fcheck flag:"+((i<<8)+n)%31);if(32&n)throw new Error("fdict flag is not supported");this.rawinflate=new ox.RawInflate(e,{index:this.ip,bufferSize:t.bufferSize,bufferType:t.bufferType,resize:t.resize})},ox.Inflate.BufferType=ox.RawInflate.BufferType,ox.Inflate.prototype.decompress=function(){var e,t=this.input;if(e=this.rawinflate.decompress(),this.ip=this.rawinflate.ip,this.verify&&(t[this.ip++]<<24|t[this.ip++]<<16|t[this.ip++]<<8|t[this.ip++])>>>0!==ox.Adler32(e))throw new Error("invalid adler-32 checksum");return e},ox.InflateStream=function(e){this.input=void 0===e?new Uint8Array:e,this.ip=0,this.rawinflate=new ox.RawInflateStream(this.input,this.ip),this.method,this.output=this.rawinflate.output},ox.InflateStream.prototype.decompress=function(e){var t;if(void 0!==e){var i=new Uint8Array(this.input.length+e.length);i.set(this.input,0),i.set(e,this.input.length),this.input=i}return void 0===this.method&&this.readHeader()<0?new Uint8Array:(t=this.rawinflate.decompress(this.input,this.ip),0!==this.rawinflate.ip&&(this.input=this.input.subarray(this.rawinflate.ip),this.ip=0),t)},ox.InflateStream.prototype.readHeader=function(){var e=this.ip,t=this.input,i=t[e++],n=t[e++];if(void 0===i||void 0===n)return-1;if((15&i)!==ox.CompressionMethod.DEFLATE)throw new Error("unsupported compression method");if(this.method=ox.CompressionMethod.DEFLATE,((i<<8)+n)%31!=0)throw new Error("invalid fcheck flag:"+((i<<8)+n)%31);if(32&n)throw new Error("fdict flag is not supported");this.ip=e},ox.Gunzip=function(e,t){this.input=e,this.ip=0,this.member=[],this.decompressed=!1},ox.Gunzip.prototype.getMembers=function(){return this.decompressed||this.decompress(),this.member.slice()},ox.Gunzip.prototype.decompress=function(){for(var e=this.input.length;this.ip0&&(l.xlen=h[d++]|h[d++]<<8,d=this.decodeSubField(d,l.xlen)),(l.flg&ox.Gzip.FlagsMask.FNAME)>0){for(a=[],r=0;(o=h[d++])>0;)a[r++]=String.fromCharCode(o);l.name=a.join("")}if((l.flg&ox.Gzip.FlagsMask.FCOMMENT)>0){for(a=[],r=0;(o=h[d++])>0;)a[r++]=String.fromCharCode(o);l.comment=a.join("")}if((l.flg&ox.Gzip.FlagsMask.FHCRC)>0&&(l.crc16=65535&ox.CRC32.calc(h,0,d),l.crc16!==(h[d++]|h[d++]<<8)))throw new Error("invalid header crc16");if(e=h[h.length-4]|h[h.length-3]<<8|h[h.length-2]<<16|h[h.length-1]<<24,h.length-d-4-4<512*e&&(n=e),t=new ox.RawInflate(h,{index:d,bufferSize:n}),l.data=i=t.decompress(),d=t.ip,l.crc32=c=(h[d++]|h[d++]<<8|h[d++]<<16|h[d++]<<24)>>>0,ox.CRC32.calc(i)!==c)throw new Error("invalid CRC-32 checksum: 0x"+ox.CRC32.calc(i).toString(16)+" / 0x"+c.toString(16));if(l.isize=e=(h[d++]|h[d++]<<8|h[d++]<<16|h[d++]<<24)>>>0,(4294967295&i.length)!==e)throw new Error("invalid input size: "+(4294967295&i.length)+" / "+e);this.member.push(l),this.ip=d},ox.Gunzip.prototype.decodeSubField=function(e,t){return e+t},ox.Gunzip.prototype.concatMember=function(){var e,t,i,n=this.member,o=0,r=0;for(e=0,t=n.length;e>>8&255,c[l++]=t>>>16&255,c[l++]=t>>>24&255,c[l++]=0,c[l++]=ox.Gzip.OperatingSystem.UNKNOWN,void 0!==this.flags.fname){for(a=0,s=f.length;a255&&(c[l++]=r>>>8&255),c[l++]=255&r;c[l++]=0}if(this.flags.comment){for(a=0,s=u.length;a255&&(c[l++]=r>>>8&255),c[l++]=255&r;c[l++]=0}return this.flags.fhcrc&&(i=65535&ox.CRC32.calc(c,0,l),c[l++]=255&i,c[l++]=i>>>8&255),this.deflateOptions.outputBuffer=c,this.deflateOptions.outputIndex=l,c=(o=new ox.RawDeflate(h,this.deflateOptions)).compress(),(l=o.op)+8>c.buffer.byteLength?(this.output=new Uint8Array(l+8),this.output.set(new Uint8Array(c.buffer)),c=this.output):c=new Uint8Array(c.buffer),n=ox.CRC32.calc(h),c[l++]=255&n,c[l++]=n>>>8&255,c[l++]=n>>>16&255,c[l++]=n>>>24&255,s=h.length,c[l++]=255&s,c[l++]=s>>>8&255,c[l++]=s>>>16&255,c[l++]=s>>>24&255,this.ip=d,l0&&(n=this.getParent(i),r[i]>r[n]);)o=r[i],r[i]=r[n],r[n]=o,o=r[i+1],r[i+1]=r[n+1],r[n+1]=o,i=n;return this.length},ox.Heap.prototype.pop=function(){var e,t,i,n,o,r=this.buffer;for(t=r[0],e=r[1],this.length-=2,r[0]=r[this.length],r[1]=r[this.length+1],o=0;!((n=this.getChild(o))>=this.length)&&(n+2r[n]&&(n+=2),r[n]>r[o]);)i=r[o],r[o]=r[n],r[n]=i,i=r[o+1],r[o+1]=r[n+1],r[n+1]=i,o=n;return{index:e,value:t,length:this.length}},ox.RawDeflate=function(e,t){this.compressionType=ox.RawDeflate.CompressionType.DYNAMIC,this.lazy=0,this.freqsLitLen,this.freqsDist,this.input=e instanceof Array?new Uint8Array(e):e,this.output,this.op=0,t&&(t.lazy&&(this.lazy=t.lazy),"number"==typeof t.compressionType&&(this.compressionType=t.compressionType),t.outputBuffer&&(this.output=t.outputBuffer instanceof Array?new Uint8Array(t.outputBuffer):t.outputBuffer),"number"==typeof t.outputIndex&&(this.op=t.outputIndex)),this.output||(this.output=new Uint8Array(32768))},ox.RawDeflate.CompressionType={NONE:0,FIXED:1,DYNAMIC:2,RESERVED:3},ox.RawDeflate.Lz77MinLength=3,ox.RawDeflate.Lz77MaxLength=258,ox.RawDeflate.WindowSize=32768,ox.RawDeflate.MaxCodeLength=16,ox.RawDeflate.HUFMAX=286,ox.RawDeflate.FixedHuffmanTable=function(){var e,t=[];for(e=0;e<288;e++)switch(!0){case e<=143:t.push([e+48,8]);break;case e<=255:t.push([e-144+400,9]);break;case e<=279:t.push([e-256+0,7]);break;case e<=287:t.push([e-280+192,8]);break;default:throw"invalid literal: "+e}return t}(),ox.RawDeflate.prototype.compress=function(){var e,t,i,n=this.input;switch(this.compressionType){case ox.RawDeflate.CompressionType.NONE:for(t=0,i=n.length;t>>8&255,a[s++]=255&r,a[s++]=r>>>8&255,a.set(e,s),s+=e.length,a=a.subarray(0,s),this.op=s,this.output=a,a},ox.RawDeflate.prototype.makeFixedHuffmanBlock=function(e,t){var i,n,o,r=new ox.BitStream(new Uint8Array(this.output.buffer),this.op);return i=t?1:0,n=ox.RawDeflate.CompressionType.FIXED,r.writeBits(i,1,!0),r.writeBits(n,2,!0),o=this.lz77(e),this.fixedHuffman(o,r),r.finish()},ox.RawDeflate.prototype.makeDynamicHuffmanBlock=function(e,t){var i,n,o,r,a,s,c,l,h,d,f,u,p,m,g,w,F,b=new ox.BitStream(new Uint8Array(this.output.buffer),this.op),v=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15],y=new Array(19);for(i=t?1:0,n=ox.RawDeflate.CompressionType.DYNAMIC,b.writeBits(i,1,!0),b.writeBits(n,2,!0),o=this.lz77(e),c=this.getLengths_(this.freqsLitLen,15),l=this.getCodesFromLengths_(c),h=this.getLengths_(this.freqsDist,7),d=this.getCodesFromLengths_(h),r=286;r>257&&0===c[r-1];r--);for(a=30;a>1&&0===h[a-1];a--);for(f=this.getTreeSymbols_(r,c,a,h),u=this.getLengths_(f.freqs,7),w=0;w<19;w++)y[w]=u[v[w]];for(s=19;s>4&&0===y[s-1];s--);for(p=this.getCodesFromLengths_(u),b.writeBits(r-257,5,!0),b.writeBits(a-1,5,!0),b.writeBits(s-4,4,!0),w=0;w=16){switch(w++,m){case 16:g=2;break;case 17:g=3;break;case 18:g=7;break;default:throw"invalid code: "+m}b.writeBits(f.codes[w],g,!0)}return this.dynamicHuffman(o,[l,c],[d,h],b),b.finish()},ox.RawDeflate.prototype.dynamicHuffman=function(e,t,i,n){var o,r,a,s,c,l,h,d;for(c=t[0],l=t[1],h=i[0],d=i[1],o=0,r=e.length;o256)n.writeBits(e[++o],e[++o],!0),s=e[++o],n.writeBits(h[s],d[s],!0),n.writeBits(e[++o],e[++o],!0);else if(256===a)break;return n},ox.RawDeflate.prototype.fixedHuffman=function(e,t){var i,n,o;for(i=0,n=e.length;i256)t.writeBits(e[++i],e[++i],!0),t.writeBits(e[++i],5),t.writeBits(e[++i],e[++i],!0);else if(256===o)break;return t},ox.RawDeflate.Lz77Match=function(e,t){this.length=e,this.backwardDistance=t},ox.RawDeflate.Lz77Match.LengthCodeTable=(ax=function(){var e,t,i=[];for(e=3;e<=258;e++)t=n(e),i[e]=t[2]<<24|t[1]<<16|t[0];function n(e){switch(!0){case 3===e:return[257,e-3,0];case 4===e:return[258,e-4,0];case 5===e:return[259,e-5,0];case 6===e:return[260,e-6,0];case 7===e:return[261,e-7,0];case 8===e:return[262,e-8,0];case 9===e:return[263,e-9,0];case 10===e:return[264,e-10,0];case e<=12:return[265,e-11,1];case e<=14:return[266,e-13,1];case e<=16:return[267,e-15,1];case e<=18:return[268,e-17,1];case e<=22:return[269,e-19,2];case e<=26:return[270,e-23,2];case e<=30:return[271,e-27,2];case e<=34:return[272,e-31,2];case e<=42:return[273,e-35,3];case e<=50:return[274,e-43,3];case e<=58:return[275,e-51,3];case e<=66:return[276,e-59,3];case e<=82:return[277,e-67,4];case e<=98:return[278,e-83,4];case e<=114:return[279,e-99,4];case e<=130:return[280,e-115,4];case e<=162:return[281,e-131,5];case e<=194:return[282,e-163,5];case e<=226:return[283,e-195,5];case e<=257:return[284,e-227,5];case 258===e:return[285,e-258,0];default:throw"invalid length: "+e}}return i}(),new Uint32Array(ax)),ox.RawDeflate.Lz77Match.prototype.getDistanceCode_=function(e){var t;switch(!0){case 1===e:t=[0,e-1,0];break;case 2===e:t=[1,e-2,0];break;case 3===e:t=[2,e-3,0];break;case 4===e:t=[3,e-4,0];break;case e<=6:t=[4,e-5,1];break;case e<=8:t=[5,e-7,1];break;case e<=12:t=[6,e-9,2];break;case e<=16:t=[7,e-13,2];break;case e<=24:t=[8,e-17,3];break;case e<=32:t=[9,e-25,3];break;case e<=48:t=[10,e-33,4];break;case e<=64:t=[11,e-49,4];break;case e<=96:t=[12,e-65,5];break;case e<=128:t=[13,e-97,5];break;case e<=192:t=[14,e-129,6];break;case e<=256:t=[15,e-193,6];break;case e<=384:t=[16,e-257,7];break;case e<=512:t=[17,e-385,7];break;case e<=768:t=[18,e-513,8];break;case e<=1024:t=[19,e-769,8];break;case e<=1536:t=[20,e-1025,9];break;case e<=2048:t=[21,e-1537,9];break;case e<=3072:t=[22,e-2049,10];break;case e<=4096:t=[23,e-3073,10];break;case e<=6144:t=[24,e-4097,11];break;case e<=8192:t=[25,e-6145,11];break;case e<=12288:t=[26,e-8193,12];break;case e<=16384:t=[27,e-12289,12];break;case e<=24576:t=[28,e-16385,13];break;case e<=32768:t=[29,e-24577,13];break;default:throw"invalid distance"}return t},ox.RawDeflate.Lz77Match.prototype.toLz77Array=function(){var e,t=this.length,i=this.backwardDistance,n=[],o=0;return e=ox.RawDeflate.Lz77Match.LengthCodeTable[t],n[o++]=65535&e,n[o++]=e>>16&255,n[o++]=e>>24,e=this.getDistanceCode_(i),n[o++]=e[0],n[o++]=e[1],n[o++]=e[2],n},ox.RawDeflate.prototype.lz77=function(e){var t,i,n,o,r,a,s,c,l,h={},d=ox.RawDeflate.WindowSize,f=new Uint16Array(2*e.length),u=0,p=0,m=new Uint32Array(286),g=new Uint32Array(30),w=this.lazy;function F(e,t){var i,n,o=e.toLz77Array();for(i=0,n=o.length;i0)a.push(t);else{for(;a.length>0&&t-a[0]>d;)a.shift();if(t+ox.RawDeflate.Lz77MinLength>=i){for(c&&F(c,-1),n=0,o=i-t;n0?(s=this.searchLongestMatch_(e,t,a),c?c.lengthox.RawDeflate.Lz77MinLength){for(s=l;s>ox.RawDeflate.Lz77MinLength;s--)if(e[n+s-1]!==e[t+s-1])continue e;r=l}for(;rl&&(o=n,l=r),r===ox.RawDeflate.Lz77MaxLength)break}return new ox.RawDeflate.Lz77Match(l,t-o)},ox.RawDeflate.prototype.getTreeSymbols_=function(e,t,i,n){var o,r,a,s,c,l,h=new Uint32Array(e+i),d=new Uint32Array(316),f=new Uint8Array(19);for(r=0,o=0;o0;)d[c++]=0,f[0]++;else for(;a>0;)(l=a<138?a:138)>a-3&&l0;)d[c++]=h[o],f[h[o]]++;else for(;a>0;)(l=a<6?a:6)>a-3&&l0&&c.push(r,e[r]);if(i=new Array(c.length/2),n=new Uint32Array(c.length/2),1===i.length)return l[c.pop().index]=1,l;for(r=0,a=c.length/2;r2*c[o-1]+l[o]&&(c[o]=2*c[o-1]+l[o]),d[o]=new Array(c[o]),f[o]=new Array(c[o]);for(n=0;n=0;--o){for(n=0,a=0,s=u[o+1],r=0;re[n]?(d[o][r]=a,f[o][r]=t,s+=2):(d[o][r]=e[n],f[o][r]=n,++n);u[o]=0,1===l[o]&&g(o)}return h},ox.RawDeflate.prototype.getCodesFromLengths_=function(e){var t,i,n,o,r=new Uint16Array(e.length),a=[],s=[],c=0;for(t=0,i=e.length;t>>=1;return r},ox.Unzip=function(e,t){t=t||{},this.input=e instanceof Array?new Uint8Array(e):e,this.ip=0,this.eocdrOffset,this.numberOfThisDisk,this.startDisk,this.totalEntriesThisDisk,this.totalEntries,this.centralDirectorySize,this.centralDirectoryOffset,this.commentLength,this.comment,this.fileHeaderList,this.filenameToIndex,this.verify=t.verify||!1,this.password=t.password},ox.Unzip.CompressionMethod=ox.Zip.CompressionMethod,ox.Unzip.FileHeaderSignature=ox.Zip.FileHeaderSignature,ox.Unzip.LocalFileHeaderSignature=ox.Zip.LocalFileHeaderSignature,ox.Unzip.CentralDirectorySignature=ox.Zip.CentralDirectorySignature,ox.Unzip.FileHeader=function(e,t){this.input=e,this.offset=t,this.length,this.version,this.os,this.needVersion,this.flags,this.compression,this.time,this.date,this.crc32,this.compressedSize,this.plainSize,this.fileNameLength,this.extraFieldLength,this.fileCommentLength,this.diskNumberStart,this.internalFileAttributes,this.externalFileAttributes,this.relativeOffset,this.filename,this.extraField,this.comment},ox.Unzip.FileHeader.prototype.parse=function(){var e=this.input,t=this.offset;if(e[t++]!==ox.Unzip.FileHeaderSignature[0]||e[t++]!==ox.Unzip.FileHeaderSignature[1]||e[t++]!==ox.Unzip.FileHeaderSignature[2]||e[t++]!==ox.Unzip.FileHeaderSignature[3])throw new Error("invalid file header signature");this.version=e[t++],this.os=e[t++],this.needVersion=e[t++]|e[t++]<<8,this.flags=e[t++]|e[t++]<<8,this.compression=e[t++]|e[t++]<<8,this.time=e[t++]|e[t++]<<8,this.date=e[t++]|e[t++]<<8,this.crc32=(e[t++]|e[t++]<<8|e[t++]<<16|e[t++]<<24)>>>0,this.compressedSize=(e[t++]|e[t++]<<8|e[t++]<<16|e[t++]<<24)>>>0,this.plainSize=(e[t++]|e[t++]<<8|e[t++]<<16|e[t++]<<24)>>>0,this.fileNameLength=e[t++]|e[t++]<<8,this.extraFieldLength=e[t++]|e[t++]<<8,this.fileCommentLength=e[t++]|e[t++]<<8,this.diskNumberStart=e[t++]|e[t++]<<8,this.internalFileAttributes=e[t++]|e[t++]<<8,this.externalFileAttributes=e[t++]|e[t++]<<8|e[t++]<<16|e[t++]<<24,this.relativeOffset=(e[t++]|e[t++]<<8|e[t++]<<16|e[t++]<<24)>>>0,this.filename=String.fromCharCode.apply(null,e.subarray(t,t+=this.fileNameLength)),this.extraField=e.subarray(t,t+=this.extraFieldLength),this.comment=e.subarray(t,t+this.fileCommentLength),this.length=t-this.offset},ox.Unzip.LocalFileHeader=function(e,t){this.input=e,this.offset=t,this.length,this.needVersion,this.flags,this.compression,this.time,this.date,this.crc32,this.compressedSize,this.plainSize,this.fileNameLength,this.extraFieldLength,this.filename,this.extraField},ox.Unzip.LocalFileHeader.Flags=ox.Zip.Flags,ox.Unzip.LocalFileHeader.prototype.parse=function(){var e=this.input,t=this.offset;if(e[t++]!==ox.Unzip.LocalFileHeaderSignature[0]||e[t++]!==ox.Unzip.LocalFileHeaderSignature[1]||e[t++]!==ox.Unzip.LocalFileHeaderSignature[2]||e[t++]!==ox.Unzip.LocalFileHeaderSignature[3])throw new Error("invalid local file header signature");this.needVersion=e[t++]|e[t++]<<8,this.flags=e[t++]|e[t++]<<8,this.compression=e[t++]|e[t++]<<8,this.time=e[t++]|e[t++]<<8,this.date=e[t++]|e[t++]<<8,this.crc32=(e[t++]|e[t++]<<8|e[t++]<<16|e[t++]<<24)>>>0,this.compressedSize=(e[t++]|e[t++]<<8|e[t++]<<16|e[t++]<<24)>>>0,this.plainSize=(e[t++]|e[t++]<<8|e[t++]<<16|e[t++]<<24)>>>0,this.fileNameLength=e[t++]|e[t++]<<8,this.extraFieldLength=e[t++]|e[t++]<<8,this.filename=String.fromCharCode.apply(null,e.subarray(t,t+=this.fileNameLength)),this.extraField=e.subarray(t,t+=this.extraFieldLength),this.length=t-this.offset},ox.Unzip.prototype.searchEndOfCentralDirectoryRecord=function(){var e,t=this.input;for(e=t.length-12;e>0;--e)if(t[e]===ox.Unzip.CentralDirectorySignature[0]&&t[e+1]===ox.Unzip.CentralDirectorySignature[1]&&t[e+2]===ox.Unzip.CentralDirectorySignature[2]&&t[e+3]===ox.Unzip.CentralDirectorySignature[3])return void(this.eocdrOffset=e);throw new Error("End of Central Directory Record not found")},ox.Unzip.prototype.parseEndOfCentralDirectoryRecord=function(){var e,t=this.input;if(this.eocdrOffset||this.searchEndOfCentralDirectoryRecord(),e=this.eocdrOffset,t[e++]!==ox.Unzip.CentralDirectorySignature[0]||t[e++]!==ox.Unzip.CentralDirectorySignature[1]||t[e++]!==ox.Unzip.CentralDirectorySignature[2]||t[e++]!==ox.Unzip.CentralDirectorySignature[3])throw new Error("invalid signature");this.numberOfThisDisk=t[e++]|t[e++]<<8,this.startDisk=t[e++]|t[e++]<<8,this.totalEntriesThisDisk=t[e++]|t[e++]<<8,this.totalEntries=t[e++]|t[e++]<<8,this.centralDirectorySize=(t[e++]|t[e++]<<8|t[e++]<<16|t[e++]<<24)>>>0,this.centralDirectoryOffset=(t[e++]|t[e++]<<8|t[e++]<<16|t[e++]<<24)>>>0,this.commentLength=t[e++]|t[e++]<<8,this.comment=t.subarray(e,e+this.commentLength)},ox.Unzip.prototype.parseFileHeader=function(){var e,t,i,n,o=[],r={};if(!this.fileHeaderList){for(void 0===this.centralDirectoryOffset&&this.parseEndOfCentralDirectoryRecord(),e=this.centralDirectoryOffset,i=0,n=this.totalEntries;i>>0;return n},ox.Adler32=function(e){return"string"==typeof e&&(e=ox.Util.stringToByteArray(e)),ox.Adler32.update(1,e)},ox.Adler32.update=function(e,t){for(var i,n=65535&e,o=e>>>16&65535,r=t.length,a=0;r>0;){r-=i=r>ox.Adler32.OptimizationParameter?ox.Adler32.OptimizationParameter:r;do{o+=n+=t[a++]}while(--i);n%=65521,o%=65521}return(o<<16|n)>>>0},ox.Adler32.OptimizationParameter=1024,ox.BitStream=function(e,t){if(this.index="number"==typeof t?t:0,this.bitindex=0,this.buffer=e instanceof Uint8Array?e:new Uint8Array(ox.BitStream.DefaultBlockSize),2*this.buffer.length<=this.index)throw new Error("invalid index");this.buffer.length<=this.index&&this.expandBuffer()},ox.BitStream.DefaultBlockSize=32768,ox.BitStream.prototype.expandBuffer=function(){var e=this.buffer,t=e.length,i=new Uint8Array(t<<1);return i.set(e),this.buffer=i},ox.BitStream.prototype.writeBits=function(e,t,i){var n,o=this.buffer,r=this.index,a=this.bitindex,s=o[r];if(i&&t>1&&(e=t>8?function(e){return ox.BitStream.ReverseTable[255&e]<<24|ox.BitStream.ReverseTable[e>>>8&255]<<16|ox.BitStream.ReverseTable[e>>>16&255]<<8|ox.BitStream.ReverseTable[e>>>24&255]}(e)>>32-t:ox.BitStream.ReverseTable[e]>>8-t),t+a<8)s=s<>t-n-1&1,8==++a&&(a=0,o[r++]=ox.BitStream.ReverseTable[s],s=0,r===o.length&&(o=this.expandBuffer()));o[r]=s,this.buffer=o,this.bitindex=a,this.index=r},ox.BitStream.prototype.finish=function(){var e=this.buffer,t=this.index;return this.bitindex>0&&(e[t]<<=8-this.bitindex,e[t]=ox.BitStream.ReverseTable[e[t]],t++),e.subarray(0,t)},ox.BitStream.ReverseTable=function(){var e,t=new Uint8Array(256);for(e=0;e<256;++e)t[e]=function(e){var t=e,i=7;for(e>>>=1;e;e>>>=1)t<<=1,t|=1&e,--i;return(t<>>0}(e);return t}(),ox.CRC32.calc=function(e,t,i){return ox.CRC32.update(e,0,t,i)},ox.CRC32.update=function(e,t,i,n){var o=ox.CRC32.Table,r="number"==typeof i?i:i=0,a="number"==typeof n?n:e.length;for(t^=4294967295,r=7&a;r--;++i)t=t>>>8^o[255&(t^e[i])];for(r=a>>3;r--;i+=8)t=(t=(t=(t=(t=(t=(t=(t=t>>>8^o[255&(t^e[i])])>>>8^o[255&(t^e[i+1])])>>>8^o[255&(t^e[i+2])])>>>8^o[255&(t^e[i+3])])>>>8^o[255&(t^e[i+4])])>>>8^o[255&(t^e[i+5])])>>>8^o[255&(t^e[i+6])])>>>8^o[255&(t^e[i+7])];return(4294967295^t)>>>0},ox.CRC32.single=function(e,t){return(ox.CRC32.Table[255&(e^t)]^e>>>8)>>>0},ox.CRC32.Table_=[0,1996959894,3993919788,2567524794,124634137,1886057615,3915621685,2657392035,249268274,2044508324,3772115230,2547177864,162941995,2125561021,3887607047,2428444049,498536548,1789927666,4089016648,2227061214,450548861,1843258603,4107580753,2211677639,325883990,1684777152,4251122042,2321926636,335633487,1661365465,4195302755,2366115317,997073096,1281953886,3579855332,2724688242,1006888145,1258607687,3524101629,2768942443,901097722,1119000684,3686517206,2898065728,853044451,1172266101,3705015759,2882616665,651767980,1373503546,3369554304,3218104598,565507253,1454621731,3485111705,3099436303,671266974,1594198024,3322730930,2970347812,795835527,1483230225,3244367275,3060149565,1994146192,31158534,2563907772,4023717930,1907459465,112637215,2680153253,3904427059,2013776290,251722036,2517215374,3775830040,2137656763,141376813,2439277719,3865271297,1802195444,476864866,2238001368,4066508878,1812370925,453092731,2181625025,4111451223,1706088902,314042704,2344532202,4240017532,1658658271,366619977,2362670323,4224994405,1303535960,984961486,2747007092,3569037538,1256170817,1037604311,2765210733,3554079995,1131014506,879679996,2909243462,3663771856,1141124467,855842277,2852801631,3708648649,1342533948,654459306,3188396048,3373015174,1466479909,544179635,3110523913,3462522015,1591671054,702138776,2966460450,3352799412,1504918807,783551873,3082640443,3233442989,3988292384,2596254646,62317068,1957810842,3939845945,2647816111,81470997,1943803523,3814918930,2489596804,225274430,2053790376,3826175755,2466906013,167816743,2097651377,4027552580,2265490386,503444072,1762050814,4150417245,2154129355,426522225,1852507879,4275313526,2312317920,282753626,1742555852,4189708143,2394877945,397917763,1622183637,3604390888,2714866558,953729732,1340076626,3518719985,2797360999,1068828381,1219638859,3624741850,2936675148,906185462,1090812512,3747672003,2825379669,829329135,1181335161,3412177804,3160834842,628085408,1382605366,3423369109,3138078467,570562233,1426400815,3317316542,2998733608,733239954,1555261956,3268935591,3050360625,752459403,1541320221,2607071920,3965973030,1969922972,40735498,2617837225,3943577151,1913087877,83908371,2512341634,3803740692,2075208622,213261112,2463272603,3855990285,2094854071,198958881,2262029012,4057260610,1759359992,534414190,2176718541,4139329115,1873836001,414664567,2282248934,4279200368,1711684554,285281116,2405801727,4167216745,1634467795,376229701,2685067896,3608007406,1308918612,956543938,2808555105,3495958263,1231636301,1047427035,2932959818,3654703836,1088359270,936918e3,2847714899,3736837829,1202900863,817233897,3183342108,3401237130,1404277552,615818150,3134207493,3453421203,1423857449,601450431,3009837614,3294710456,1567103746,711928724,3020668471,3272380065,1510334235,755167117],ox.CRC32.Table=new Uint32Array(ox.CRC32.Table_),ox.Deflate=function(e,t){this.input=e,this.output=new Uint8Array(ox.Deflate.DefaultBufferSize),this.compressionType=ox.Deflate.CompressionType.DYNAMIC,this.rawDeflate;var i,n={};for(i in!t&&(t={})||"number"==typeof t.compressionType&&(this.compressionType=t.compressionType),t)n[i]=t[i];n.outputBuffer=this.output,this.rawDeflate=new ox.RawDeflate(this.input,n)},ox.Deflate.DefaultBufferSize=32768,ox.Deflate.CompressionType=ox.RawDeflate.CompressionType,ox.Deflate.compress=function(e,t){return new ox.Deflate(e,t).compress()},ox.Deflate.prototype.compress=function(){var e,t,i,n,o,r,a=0;if(r=this.output,(e=ox.CompressionMethod.DEFLATE)!==ox.CompressionMethod.DEFLATE)throw new Error("invalid compression method");if(t=Math.LOG2E*Math.log(ox.RawDeflate.WindowSize)-8<<4|e,r[a++]=t,e!==ox.CompressionMethod.DEFLATE)throw new Error("invalid compression method");switch(this.compressionType){case ox.Deflate.CompressionType.NONE:n=0;break;case ox.Deflate.CompressionType.FIXED:n=1;break;case ox.Deflate.CompressionType.DYNAMIC:n=2;break;default:throw new Error("unsupported compression type")}return i=n<<6,i|=31-(256*t+i)%31,r[a++]=i,o=ox.Adler32(this.input),this.rawDeflate.op=a,a=(r=this.rawDeflate.compress()).length,(r=new Uint8Array(r.buffer)).length<=a+4&&(this.output=new Uint8Array(r.length+4),this.output.set(r),r=this.output),(r=r.subarray(0,a+4))[a++]=o>>24&255,r[a++]=o>>16&255,r[a++]=o>>8&255,r[a++]=255&o,r};class sx{constructor(e){this.file=e}async read(e,t){const i=this.file;return void 0!==e?i.slice(e,e+t).arrayBuffer():i.arrayBuffer()}}"undefined"!=typeof process&&null!=process.versions&&process.versions.node;class cx{constructor(e){var t;this.config=e,this.url=(t=e.path||e.url).includes("//www.dropbox.com")?t.replace("//www.dropbox.com","//dl.dropboxusercontent.com"):t.startsWith("ftp://ftp.ncbi.nlm.nih.gov")?t.replace("ftp://","https://"):t}async read(e,t){t=Math.ceil(t);const i=this.config.headers||{},n="bytes="+e+"-"+(e+t-1);i.Range=n;let o=this.url.slice();if(this.config.oauthToken){const e=async function(e){return"function"==typeof e?await Promise.resolve(e()):e}(this.config.oauthToken);i.Authorization=`Bearer ${e}`}this.config.apiKey&&(o=function(e,t,i){const n=e.includes("?")?"&":"?";return e+n+t+"="+i}(o,"key",this.config.apiKey));const r=await fetch(o,{method:"GET",headers:i,redirect:"follow",mode:"cors"}),a=r.status;if(a>=400){console.error(`${a} ${this.config.url}`);const e=Error(r.statusText);throw e.code=a,e}return r.arrayBuffer()}}class lx{constructor(e,t){this.file=e,this.rateLimiter=t}async read(e,t){const i=this.file,n=this.rateLimiter;return new Promise((function(o,r){n.limiter((async function(i){try{const n=await i.read(e,t);o(n)}catch(e){r(e)}}))(i)}))}}class hx{constructor(e){this.file=e.file,this.size=e.size||64e3,this.position=0,this.bufferStart=0,this.bufferLength=0,this.buffer=void 0}async read(e,t){const i=e,n=e+t,o=this.bufferStart,r=this.bufferStart+this.bufferLength;if(t>this.size)return this.buffer=void 0,this.bufferStart=0,this.bufferLength=0,this.file.read(e,t);if(i>=o&&n<=r){const e=i-o,n=e+t;return this.buffer.slice(e,n)}if(io){const n=o-i,r=await this.file.read(e,n),a=t-n;if(a>0){const e=this.buffer.slice(0,a);return dx(r,e)}return r}if(!(ir))return this.buffer=await this.file.read(e,this.size),this.bufferStart=e,this.bufferLength=this.buffer.byteLength,this.buffer.slice(0,t);{const e=r-i,n=this.bufferLength-e,o=this.buffer.slice(n,this.bufferLength),a=t-e;if(!(a>0))return o;try{this.buffer=await this.file.read(r,this.size),this.bufferStart=r,this.bufferLength=this.buffer.byteLength;const e=this.buffer.slice(0,a);return dx(o,e)}catch(e){if(e.code&&416===e.code)return o;throw e}}}}var dx=function(e,t){var i=new Uint8Array(e.byteLength+t.byteLength);return i.set(new Uint8Array(e),0),i.set(new Uint8Array(t),e.byteLength),i.buffer};const fx=function(e,t){this.littleEndian=void 0===t||t,this.position=0,this.view=e,this.length=e.byteLength};function ux(e,t){this.block=e,this.offset=t}fx.prototype.available=function(){return this.length-this.position},fx.prototype.remLength=function(){return this.length-this.position},fx.prototype.hasNext=function(){return this.position=0;i--)t=256*t+e[i];else for(i=0;i0&&(n+=String.fromCharCode(i));return n},fx.prototype.getFixedLengthTrimmedString=function(e){var t,i,n="";for(t=0;t32&&(n+=String.fromCharCode(i));return n},fx.prototype.getFloat=function(){var e=this.view.getFloat32(this.position,this.littleEndian);return this.position+=4,e},fx.prototype.getDouble=function(){var e=this.view.getFloat64(this.position,this.littleEndian);return this.position+=8,e},fx.prototype.skip=function(e){return this.position+=e,this.position},fx.prototype.getVPointer=function(){var e=this.position,t=this.view.getUint8(e+1)<<8|this.view.getUint8(e),i=4294967296*(255&this.view.getUint8(e+6))+16777216*(255&this.view.getUint8(e+5))+65536*(255&this.view.getUint8(e+4))+256*(255&this.view.getUint8(e+3))+(255&this.view.getUint8(e+2));return this.position+=8,new ux(i,t)},ux.prototype.isLessThan=function(e){return this.blocke.block||this.block===e.block&&this.offset>e.offset},ux.prototype.print=function(){return this.block+":"+this.offset};class px{constructor(e,t){this.chr1=e,this.chr2=t}getKey(){return this.chr1.name+"_"+this.chr2.name+"_"+this.zoom.unit+"_"+this.zoom.binSize}getBlockNumbers(e,t,i){if(e.chr==this.chr2&&t.chr===this.chr1){const i=e;e=t,t=i}const n=this.chr1===this.chr2,o=this.zoom.binSize,r=this.blockBinCount,a=this.blockColumnCount;return i<9||!n?function(){const i=e.start/o,s=e.end/o,c=t.start/o,l=t.end/o,h=Math.floor(i/r),d=Math.floor((s-1)/r),f=Math.floor(c/r),u=Math.floor((l-1)/r),p=[];for(let e=f;e<=u;e++)for(let t=h;t<=d;t++){let i;i=n&&e0;){const e=t.getInt(),i=t.getLong(),n=t.getInt();this.blockIndex[e]={filePosition:i,size:n}}}getBlockIndexEntry(e){return this.blockIndex[e]}}class gx{constructor(e,t,i){this.chr1=e,this.chr2=t,this.bpZoomData=[],this.fragZoomData=[];for(let e of i)"BP"===e.zoom.unit?this.bpZoomData.push(e):this.fragZoomData.push(e)}findZoomForResolution(e,t){const i="FRAG"===t?this.fragZoomData:this.bpZoomData;for(let t=1;tt){const i=e;e=t,t=i}return`${e}_${t}`}static parseMatrix(e,t){const i=new fx(new DataView(e)),n=i.getInt(),o=i.getInt(),r=t[n],a=t[o];let s=i.getInt();const c=[];for(;s-- >0;){const e=px.parseMatrixZoomData(r,a,i);c.push(e)}return new gx(n,o,c)}}class wx{constructor(e,t,i){this.bin1=e,this.bin2=t,this.counts=i}getKey(){return this.bin1+"_"+this.bin2}}class Fx{constructor(e=10){this.max=e,this.map=new Map}get(e){let t=this.map.get(e);return t&&(this.map.delete(e),this.map.set(e,t)),t}set(e,t){this.map.has(e)?this.map.delete(e):this.map.size===this.max&&this.map.delete(this.first()),this.map.set(e,t)}has(e){return this.map.has(e)}clear(){this.map.clear()}first(){return this.map.keys().next().value}}class bx{constructor(e,t,i,n){this.file=e,this.filePosition=t,this.nValues=i,this.dataType=n,this.cache=void 0}async getValues(e,t){if(!this.cache||ethis.cache.end){const i=Math.max(0,e-1e3),n=Math.min(this.nValues,t+1e3),o=this.filePosition+i*this.dataType,r=n-i,a=r*this.dataType,s=await this.file.read(o,a);if(!s)return;const c=new fx(new DataView(s)),l=[];for(let e=0;e=0||t.indexOf("www.googleapis.com/drive")>0?this.file=new lx(i,_x):this.file=i}}var t}async init(){this.initialized||(await this.readHeaderAndFooter(),this.initialized=!0)}async getVersion(){if(void 0===this.version){const e=await this.file.read(0,128);if(!e)return;const t=new fx(new DataView(e));return this.magic=t.getString(),this.version=t.getInt(),this.version}return this.version}async getMetaData(){return await this.init(),this.meta}async readHeaderAndFooter(){let e=await this.file.read(0,16);if(!e||0===e.byteLength)throw Error("File content is empty");let t=new fx(new DataView(e));if(this.magic=t.getString(),this.version=t.getInt(),this.version<5)throw Error("Unsupported hic version: "+this.version);this.footerPosition=t.getLong(),await this.readFooter();const i=Object.values(this.masterIndex).reduce(((e,t)=>Math.min(e,t.start)),Number.MAX_VALUE)-16;e=await this.file.read(16,i),t=new fx(new DataView(e)),this.genomeId=t.getString(),this.version>=9&&(this.normVectorIndexPosition=t.getLong(),this.normVectorIndexSize=t.getLong()),this.attributes={};let n=t.getInt();for(;n-- >0;)this.attributes[t.getString()]=t.getString();this.chromosomes=[],this.chromosomeIndexMap={};let o=t.getInt(),r=0;for(;o-- >0;){const e={index:r,name:t.getString(),size:this.version<9?t.getInt():t.getLong()};"all"===e.name.toLowerCase()&&(this.wholeGenomeChromosome=e,this.wholeGenomeResolution=Math.round(2*e.size)),this.chromosomes.push(e),this.chromosomeIndexMap[e.name]=e.index,r++}this.bpResolutions=[];let a=t.getInt();for(;a-- >0;)this.bpResolutions.push(t.getInt());if(this.loadFragData){this.fragResolutions=[];let e=t.getInt();if(e>0)for(;e-- >0;)this.fragResolutions.push(t.getInt())}this.chrAliasTable={};for(let e of Object.keys(this.chromosomeIndexMap))e.startsWith("chr")?this.chrAliasTable[e.substr(3)]=e:"MT"===e?this.chrAliasTable.chrM=e:this.chrAliasTable["chr"+e]=e;this.meta={version:this.version,genome:this.genomeId,chromosomes:this.chromosomes,resolutions:this.bpResolutions}}async readFooter(){const e=this.version<9?8:12;let t=await this.file.read(this.footerPosition,e);if(!t)return null;let i=new fx(new DataView(t));const n=this.version<9?i.getInt():i.getLong();let o=i.getInt();const r=196*o;for(t=await this.file.read(this.footerPosition+e,Math.min(r,n)),i=new fx(new DataView(t)),this.masterIndex={};o-- >0;){const e=i.getString(),t=i.getLong(),n=i.getInt();this.masterIndex[e]={start:t,size:n}}if(this.expectedValueVectors={},this.version>5){const e=this.version<9?4:8;this.normExpectedValueVectorsPosition=this.footerPosition+e+n}return this}async printIndexStats(){let e,t=0,i=0;await await this.init();for(let n of Object.keys(this.masterIndex)){const o=this.masterIndex[n];t+=o.size,o.size>i&&(i=o.size,e=n)}console.log(`${i} ${e} ${this.config.url}`)}async getMatrix(e,t){const i=gx.getKey(e,t);if(this.matrixCache.has(i))return this.matrixCache.get(i);{const n=await this.readMatrix(e,t);return this.matrixCache.set(i,n),n}}async readMatrix(e,t){if(await this.init(),e>t){const i=e;e=t,t=i}const i=gx.getKey(e,t),n=this.masterIndex[i];if(!n)return;const o=await this.file.read(n.start,n.size);return o?gx.parseMatrix(o,this.chromosomes):void 0}async getContactRecords(e,t,i,n,o,r=!1){await this.init();const a=this.chromosomeIndexMap[this.getFileChrName(t.chr)],s=this.chromosomeIndexMap[this.getFileChrName(i.chr)];if(a>s||a===s&&t.start>=i.end){const e=t;t=i,i=e}const c=await this.getBlocks(t,i,n,o);if(!c||0===c.length)return[];const l=[],h=t.start/o,d=t.end/o,f=i.start/o,u=i.end/o,p=Math.floor(h),m=Math.ceil(d),g=Math.floor(f),w=Math.ceil(u);for(let a of c)if(a){let s,c,F=e&&"NONE"!==e;const b=this.getFileChrName(t.chr),v=this.getFileChrName(i.chr);if(F){const t=await this.getNormalizationVector(e,b,n,o),i=b===v?t:await this.getNormalizationVector(e,v,n,o);t&&i?(s=await t.getValues(p,m),c=await i.getValues(g,w)):F=!1}for(let e of a.records)if(r||e.bin1>=h&&e.bin1=f&&e.bin2`${t.getKey()}_${e}`;await this.init();const r=this.getFileChrName(e.chr),a=this.getFileChrName(t.chr),s=this.chromosomeIndexMap[r],c=this.chromosomeIndexMap[a];if(void 0===s)return console.log("No chromosome named: "+e.chr),[];if(void 0===c)return console.log("No chromosome named: "+t.chr),[];const l=await this.getMatrix(s,c);if(!l)return console.log("No matrix for "+e.chr+"-"+t.chr),[];const h=l.getZoomData(n,i);if(!h){let i=`No data avalailble for resolution: ${n} for map ${e.chr}-${t.chr}`;throw new Error(i)}const d=h.getBlockNumbers(e,t,this.version),f=[],u=[];for(let e of d){const t=o(e,h);this.blockCache.has(n,t)?f.push(this.blockCache.get(n,t)):u.push(e)}const p=u.map((e=>this.readBlock(e,h))),m=await Promise.all(p);for(let e of m)e&&this.blockCache.set(n,o(e.blockNumber,h),e);return f.concat(m)}async readBlock(e,t){const i=await t.blockIndex.getBlockIndexEntry(e);if(i){let n=await this.file.read(i.filePosition,i.size);if(!n)return;n=new ox.Inflate(new Uint8Array(n)).decompress().buffer;const o=new fx(new DataView(n)),r=o.getInt(),a=[];if(this.version<7)for(let e=0;e0;)this.parseNormVectorEntry(i);return this.normVectorIndex}async readNormExpectedValuesAndNormVectorIndex(){if(await this.init(),void 0===this.normExpectedValueVectorsPosition)return;const e=await this.skipExpectedValues(this.normExpectedValueVectorsPosition);let t=4,i=await this.file.read(e,4);if(0===i.byteLength)return;const n=new fx(new DataView(i)).getInt(),o={start:e+t,size:30*n};i=await this.file.read(o.start,o.size),this.normalizedExpectedValueVectors={},this.normVectorIndex={},await async function i(n,o){const r=new fx(new DataView(o));for(;n-- >0;){if(r.available()<100){n++,t+=r.position;const o=Math.max(1e3,30*n),a={start:e+t,size:o},s=await this.file.read(a.start,a.size);return i.call(this,n,s)}this.parseNormVectorEntry(r)}t+=r.position}.call(this,n,i),this.config.nvi=e.toString()+","+t}async skipExpectedValues(e){const t=this.version,i=new hx({file:this.file,size:256e3}),n={start:e,size:4},o=await i.read(n.start,n.size),r=new fx(new DataView(o)).getInt();return 0===r?e+4:async function e(n,o){let r={start:n,size:500},a=0,s=n,c=await i.read(r.start,r.size),l=new fx(new DataView(c));l.getString(),l.getString(),l.getInt();const h=t<9?l.getInt():l.getLong();a+=l.position+h*(t<9?8:4),r={start:n+a,size:4},c=await i.read(r.start,r.size),l=new fx(new DataView(c));const d=l.getInt();return a+=4+d*(4+(t<9?8:4)),o--,0===o?s+a:e(s+a,o)}(e+4,r)}getZoomIndexForBinSize(e,t){let i;if("BP"===(t=t||"BP"))i=this.bpResolutions;else{if("FRAG"!==t)throw new Error("Invalid unit: "+t);i=this.fragResolutions}for(let t=0;t=0||e.indexOf("www.googleapis.com/drive")>0}const Ix=new Map;function zx(e){var t=function(e){if(e.includes("/open?id=")){const t=e.indexOf("/open?id=")+9,i=e.indexOf("&");if(t>0&&i>t)return e.substring(t,i);if(t>0)return e.substring(t)}else{if(e.includes("/file/d/")){const t=e.indexOf("/file/d/")+8,i=e.lastIndexOf("/");return e.substring(t,i)}if(e.startsWith("https://www.googleapis.com/drive")){let t=e.indexOf("/files/");const i=e.indexOf("?");if(t>0)return t+=7,i>0?e.substring(t,i):e.substring(t)}}throw Error("Unknown Google Drive url format: "+e)}(e);return t?"https://www.googleapis.com/drive/v3/files/"+t+"?alt=media&supportsTeamDrives=true":e}Ix.set("!","%21"),Ix.set("#","%23"),Ix.set("$","%24"),Ix.set("%","%25"),Ix.set("&","%26"),Ix.set("'","%27"),Ix.set("(","%28"),Ix.set(")","%29"),Ix.set("*","%2A"),Ix.set("+","%2B"),Ix.set(",","%2C"),Ix.set("/","%2F"),Ix.set(":","%3A"),Ix.set(";","%3B"),Ix.set("=","%3D"),Ix.set("?","%3F"),Ix.set("@","%40"),Ix.set("[","%5B"),Ix.set("]","%5D"),Ix.set(" ","%20");class Dx{constructor(e){this.config=e,this.url=e.path||e.url}async read(e,t){const i={start:e,size:t};return en.loadArrayBuffer(this.url,{range:i})}}const Ax={hg19:[249250621,243199373,198022430],hg38:[248956422,242193529,198295559],mm10:[195471971,182113224,160039680],mm9:[197195432,181748087,159599783],dm6:[23513712,25286936,28110227]};class Mx{constructor(e){this.straw=new Nx(e)}async init(){this.hicFile=this.straw.hicFile,await this.hicFile.init(),this.normalizationTypes=["NONE"],this.genomeId=this.hicFile.genomeId,this.chromosomes=this.hicFile.chromosomes,this.bpResolutions=this.hicFile.bpResolutions,this.wholeGenomeChromosome=this.hicFile.wholeGenomeChromosome,this.wholeGenomeResolution=this.hicFile.wholeGenomeResolution;const e=function(e){if(e.length<4)return;const t=Object.keys(Ax);let i;for(let n of e)for(let e of t)if(Ax[e].includes(n.size)){i=e;break}if(i){const t=new Set(e.map((e=>e.size)));for(let e of Ax[i])if(!t.has(e))return;return i}return}(this.chromosomes);e&&(this.genomeId=e)}async getContactRecords(e,t,i,n,o){return this.straw.getContactRecords(e,t,i,n,o)}async hasNormalizationVector(e,t,i,n){return this.straw.hicFile.hasNormalizationVector(e,t,i,n)}clearCaches(){this.colorScaleCache={}}async getMatrix(e,t){return this.hicFile.getMatrix(e,t)}getZoomIndexForBinSize(e,t){var i,n;if("BP"===(t=t||"BP"))n=this.bpResolutions;else{if("FRAG"!==t)throw new Error("Invalid unit: "+t);n=this.fragResolutions}for(i=0;ie)return this.chromosomes[i];n+=t}return this.chromosomes[this.chromosomes.length-1]}getCumulativeOffset(e){const t=this.getChromosomeName(e);return void 0===this.cumulativeOffsets&&Rx.call(this),this.cumulativeOffsets[t]}getGenomeLength(){return this.genomeLength}addFeaturesToDB(e,t){const i=(e,t)=>{const i=this.featureDB.get(e);i&&(t=t.end-t.start>i.end-i.start?t:i),this.featureDB.set(e,t)};for(let t of e)t.name&&i(t.name.toUpperCase(),t),t.gene&&t.gene.name&&i(t.gene.name.toUpperCase(),t)}}function Rx(){const e={};let t=0;for(let i of this.chromosomes)"all"!==i.name&&(e[i.name]=Math.floor(t),t+=i.size);this.cumulativeOffsets=e}class Lx{constructor(e,t,i,n,o,r,a,s){e<=t?(this.chr1=e,this.x=o,this.chr2=t,this.y=r):(this.chr1=t,this.x=r,this.chr2=e,this.y=o),this.zoom=n,void 0===s&&(console.warn("Normalization is undefined. Will use NONE"),s="NONE"),this.normalization=s,Number.isNaN(a)&&(a=1),this.pixelSize=a,this.locus=i}clampXY(e,t){const{width:i,height:n}=t,{chromosomes:o,bpResolutions:r}=e,a=r[this.zoom],s=Math.max(0,o[this.chr1].size/a-i/this.pixelSize),c=Math.max(0,o[this.chr2].size/a-n/this.pixelSize);this.x=Math.min(Math.max(0,this.x),s),this.y=Math.min(Math.max(0,this.y),c)}async panWithZoom(e,t,i,n,o,r,a,s,c){const l=await r.minPixelSize(this.chr1,this.chr2,e);t=Math.max(t,l),c[this.zoom];const h=(this.x+i/this.pixelSize)*c[this.zoom].binSize,d=(this.y+n/this.pixelSize)*c[this.zoom].binSize;this.x=h/o-i/t,this.y=d/o-n/t,this.zoom=e,this.pixelSize=t,this.clampXY(a,s)}panShift(e,t,i,n,o){this.x+=e/this.pixelSize,this.y+=t/this.pixelSize,this.clampXY(n,o),this.configureLocus(i,n,o)}async setWithZoom(e,t,i,n){const{width:o,height:r}=t,a=this.x+o/2/this.pixelSize,s=this.y+r/2/this.pixelSize,c=n.bpResolutions[this.zoom]/n.bpResolutions[e],l=a*c,h=s*c,d=await i.minPixelSize(this.chr1,this.chr2,e);this.pixelSize=Math.max(dk,d);const f=this.zoom!==e;return this.zoom=e,this.x=Math.max(0,l-o/(2*this.pixelSize)),this.y=Math.max(0,h-r/(2*this.pixelSize)),this.clampXY(n,t),this.configureLocus(i,n,t),f}configureLocus(e,t,i){const n=t.bpResolutions[this.zoom],o=Math.round(this.x*n),r=Math.round(this.y*n),a=t.chromosomes[this.chr1],s=t.chromosomes[this.chr2],c=this.pixelSize,l=Math.min(a.size,Math.round(i.width/c*n)+o),h=Math.min(s.size,Math.round(i.height/c*n)+r),d={chr:a.name,start:o,end:l},f={chr:s.name,start:r,end:h};this.locus={x:d,y:f}}updateWithLoci(e,t,i,n,o,r,a,s,c){const l=a.getResolutions();let h,d,f=Math.max((i-t)/s,(r-o)/c);!0===a.resolutionLocked?(h=!1,d=this.zoom):(d=a.findMatchingZoomIndex(f,l),h=d!==this.zoom);const{binSize:u}=l[d],p=Math.min(fk,Math.max(1,u/f)),m=t/u,g=o/u,{index:w}=a.genome.getChromosome(e),{index:F}=a.genome.getChromosome(n),b=this.chr1!==w||this.chr2!==F;return this.chr1=w,this.chr2=F,this.zoom=d,this.x=m,this.y=g,this.pixelSize=p,this.locus={x:{chr:e,start:t,end:i},y:{chr:n,start:o,end:r}},{chrChanged:b,resolutionChanged:h}}sync(e,t,i,n){const o=i.getChromosome(e.chr1Name),r=i.getChromosome(e.chr2Name),a=e.binSize/e.pixelSize,s=t.findMatchingZoomIndex(a,n.bpResolutions),c=n.bpResolutions[s],l=Math.min(fk,Math.max(1,c/a)),h=e.binX*(e.binSize/c),d=e.binY*(e.binSize/c),f=t.state.zoom!==s,u=t.state.chr1!==o.index||t.state.chr2!==r.index;return this.chr1=o.index,this.chr2=r.index,this.zoom=s,this.x=h,this.y=d,this.pixelSize=l,this.configureLocus(t,n,t.contactMatrixView.getViewDimensions()),{zoomChanged:f,chrChanged:u}}stringify(){return this.normalization?`${this.chr1},${this.chr2},${this.zoom},${this.x},${this.y},0,0,${this.pixelSize},${this.normalization}`:`${this.chr1},${this.chr2},${this.zoom},${this.x},${this.y},0,0,${this.pixelSize}`}clone(){return Object.assign(new Lx,this)}equals(e){return JSON.stringify(this)===JSON.stringify(e)}async sizeBP(e,t,i){const n=await e.getMatrix(this.chr1,this.chr2),{zoom:o}=n.getZoomDataByIndex(t,"BP");return i*(o.binSize/this.pixelSize)}static parse(e){const t=e.split(",");return t.length<=7?new Lx(parseInt(t[0]),parseInt(t[1]),void 0,parseFloat(t[2]),parseFloat(t[3]),parseFloat(t[4]),parseFloat(t[5]),t.length>6?t[6]:"NONE"):new Lx(parseInt(t[0]),parseInt(t[1]),void 0,parseFloat(t[2]),parseFloat(t[3]),parseFloat(t[4]),parseFloat(t[7]),t.length>8?t[8]:"NONE")}toJSON(){const e={chr1:this.chr1,chr2:this.chr2,zoom:this.zoom,x:this.x,y:this.y,pixelSize:this.pixelSize,normalization:this.normalization||"NONE"};return this.locus&&(e.locus=this.locus),e}static fromJSON(e){return new Lx(e.chr1,e.chr2,e.locus,e.zoom,e.x,e.y,e.pixelSize,e.normalization)}static default(e){return new Lx(0,0,void 0,0,0,1,"NONE")}}async function Bx(e,t){const n=`https://portals.broadinstitute.org/webservices/igv/locus?genome=${e}&name=${encodeURIComponent(t)}`;try{const e=function(e){const t=i(e).filter((e=>""!==e.trim())).map((e=>e.split("\t"))).filter((e=>e.length>=3)).map((e=>e[1]));return t}(await en.loadString(n));return e.length?e[0]:void 0}catch(e){return void console.error(`Error fetching gene data for "${t}":`,e)}}var Hx={"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2Fcombined.hic":"54386046426,55860","hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2Fprimary.hic":"33860030033,37504","hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2Freplicate.hic":"30849652794,55832","hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2Fmaternal.hic":"1380542661,17185","hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2Fpaternal.hic":"1389001777,17185","hicfiles.s3.amazonaws.com%2Fhiseq%2Fimr90%2Fin-situ%2Fcombined.hic":"13433880319,35723","hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC001.hic":"3409347253,35975","hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC002.hic":"4529947083,36479","hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC003.hic":"6894962500,36479","hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC004.hic":"3395593338,36479","hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC005.hic":"5204128636,36479","hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC006.hic":"3278363811,36479","hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC007.hic":"3585547340,36479","hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC008.hic":"4134197273,36479","hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC009.hic":"2851728310,36479","hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC010.hic":"1754216102,36479","hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC011.hic":"1716829574,36479","hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC012.hic":"4367980375,36479","hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC013.hic":"2309654671,36479","hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC014.hic":"5324950266,36479","hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC015.hic":"3132333594,36479","hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC016.hic":"3159154704,36479","hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC017.hic":"3262554627,36479","hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC018.hic":"3014216364,36479","hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC019.hic":"5025753246,36479","hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC020.hic":"5861584507,36479","hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC021.hic":"3542263275,36479","hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC022.hic":"5061949378,36479","hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC023.hic":"4816423919,36479","hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC024.hic":"2683781104,36479","hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC025.hic":"6522701781,36479","hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC026.hic":"6748846520,36479","hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC027.hic":"5642693007,36479","hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC028.hic":"2098921691,36479","hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC029.hic":"3886454027,36479","hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fagar%2FHIC030.hic":"2288984204,36479","hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fagar%2FHIC031.hic":"2115342419,36479","hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fpellet%2FHIC032.hic":"2063314324,36479","hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fsupernatant%2FHIC033.hic":"1933908457,36479","hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fdilution%2FHIC034.hic":"13555514595,36479","hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fdilution%2FHIC035.hic":"6129650900,36479","hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fdilution%2FHIC036.hic":"4307445019,36479","hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fdilution%2FHIC037.hic":"9375139867,36479","hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fdilution%2Fcombined.hic":"11664249584,33929","hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2Fcombined_DpnII.hic":"7003537290,36479","hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC038.hic":"2099825544,36479","hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC039.hic":"2096900138,36479","hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC040.hic":"2593642141,36479","hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC041.hic":"2263919098,36479","hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC042.hic":"2684774693,36479","hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2Fcombined_noXlink.hic":"5574807456,36479","hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC043.hic":"2986114347,36479","hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC044.hic":"1916378621,36479","hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC045.hic":"746463126,36479","hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC046.hic":"2338476164,36479","hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC047.hic":"1167496250,36479","hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC048.hic":"2231690794,36479","hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC049.hic":"2782308678,36479","hicfiles.s3.amazonaws.com%2Fhiseq%2Fimr90%2Fin-situ%2FHIC050.hic":"3633531346,36479","hicfiles.s3.amazonaws.com%2Fhiseq%2Fimr90%2Fin-situ%2FHIC051.hic":"4063486444,36479","hicfiles.s3.amazonaws.com%2Fhiseq%2Fimr90%2Fin-situ%2FHIC052.hic":"929756278,36479","hicfiles.s3.amazonaws.com%2Fhiseq%2Fimr90%2Fin-situ%2FHIC053.hic":"2489657204,36479","hicfiles.s3.amazonaws.com%2Fhiseq%2Fimr90%2Fin-situ%2FHIC054.hic":"4036419444,36479","hicfiles.s3.amazonaws.com%2Fhiseq%2Fimr90%2Fin-situ%2FHIC055.hic":"4284185549,36479","hicfiles.s3.amazonaws.com%2Fhiseq%2Fimr90%2Fin-situ%2FHIC056.hic":"4410546240,36479","hicfiles.s3.amazonaws.com%2Fhiseq%2Fimr90%2Fdilution%2FHIC057.hic":"1491998259,36479","hicfiles.s3.amazonaws.com%2Fhiseq%2Fhmec%2Fin-situ%2Fcombined.hic":"7266425111,36479","hicfiles.s3.amazonaws.com%2Fhiseq%2Fhmec%2Fin-situ%2FHIC058.hic":"6532635593,36479","hicfiles.s3.amazonaws.com%2Fhiseq%2Fhmec%2Fin-situ%2FHIC059.hic":"400684530,36479","hicfiles.s3.amazonaws.com%2Fhiseq%2Fhmec%2Fin-situ%2FHIC060.hic":"645352187,36479","hicfiles.s3.amazonaws.com%2Fhiseq%2Fhmec%2Fin-situ%2FHIC061.hic":"736291871,36479","hicfiles.s3.amazonaws.com%2Fhiseq%2Fhmec%2Fin-situ%2FHIC062.hic":"762731037,36479","hicfiles.s3.amazonaws.com%2Fhiseq%2Fhmec%2Fin-situ%2FHIC063.hic":"682917431,36479","hicfiles.s3.amazonaws.com%2Fhiseq%2Fhmec%2Fdilution%2FHIC064.hic":"4550171307,36479","hicfiles.s3.amazonaws.com%2Fhiseq%2Fnhek%2Fin-situ%2Fcombined.hic":"11897184911,35789","hicfiles.s3.amazonaws.com%2Fhiseq%2Fnhek%2Fin-situ%2FHIC065.hic":"5425943567,36479","hicfiles.s3.amazonaws.com%2Fhiseq%2Fnhek%2Fin-situ%2FHIC066.hic":"5942869818,36479","hicfiles.s3.amazonaws.com%2Fhiseq%2Fnhek%2Fin-situ%2FHIC067.hic":"5191049261,35647","hicfiles.s3.amazonaws.com%2Fhiseq%2Fnhek%2Fdilution%2FHIC068.hic":"2713318801,36479","hicfiles.s3.amazonaws.com%2Fhiseq%2Fk562%2Fin-situ%2Fcombined.hic":"12641555389,36479","hicfiles.s3.amazonaws.com%2Fhiseq%2Fk562%2Fin-situ%2FHIC069.hic":"5630177461,36479","hicfiles.s3.amazonaws.com%2Fhiseq%2Fk562%2Fin-situ%2FHIC070.hic":"5926611269,36479","hicfiles.s3.amazonaws.com%2Fhiseq%2Fk562%2Fin-situ%2FHIC071.hic":"2486191351,36479","hicfiles.s3.amazonaws.com%2Fhiseq%2Fk562%2Fin-situ%2FHIC072.hic":"2281343366,36479","hicfiles.s3.amazonaws.com%2Fhiseq%2Fk562%2Fin-situ%2FHIC073.hic":"2173074239,36479","hicfiles.s3.amazonaws.com%2Fhiseq%2Fk562%2Fin-situ%2FHIC074.hic":"2463700999,36479","hicfiles.s3.amazonaws.com%2Fhiseq%2Fkbm7%2Fin-situ%2Fcombined.hic":"14661922519,35639","hicfiles.s3.amazonaws.com%2Fhiseq%2Fkbm7%2Fin-situ%2FHIC075.hic":"3685310515,36479","hicfiles.s3.amazonaws.com%2Fhiseq%2Fkbm7%2Fin-situ%2FHIC076.hic":"5833658487,35891","hicfiles.s3.amazonaws.com%2Fhiseq%2Fkbm7%2Fin-situ%2FHIC077.hic":"2406346486,36479","hicfiles.s3.amazonaws.com%2Fhiseq%2Fkbm7%2Fin-situ%2FHIC078.hic":"5241454987,35919","hicfiles.s3.amazonaws.com%2Fhiseq%2Fkbm7%2Fin-situ%2FHIC079.hic":"6297234263,36479","hicfiles.s3.amazonaws.com%2Fhiseq%2Fhuvec%2Fin-situ%2Fcombined.hic":"9193858096,36479","hicfiles.s3.amazonaws.com%2Fhiseq%2Fhuvec%2Fin-situ%2FHIC080.hic":"5171405536,36479","hicfiles.s3.amazonaws.com%2Fhiseq%2Fhuvec%2Fin-situ%2FHIC081.hic":"3489767688,35891","hicfiles.s3.amazonaws.com%2Fhiseq%2Fhuvec%2Fin-situ%2FHIC082.hic":"4243339375,36479","hicfiles.s3.amazonaws.com%2Fhiseq%2Fhuvec%2Fdilution%2FHIC083.hic":"1497495406,36479","hicfiles.s3.amazonaws.com%2Fhiseq%2Fhela%2Fin-situ%2Fcombined.hic":"7923332224,35593","hicfiles.s3.amazonaws.com%2Fhiseq%2Fhela%2Fin-situ%2FHIC084.hic":"867699123,36479","hicfiles.s3.amazonaws.com%2Fhiseq%2Fhela%2Fin-situ%2FHIC085.hic":"3669518514,36479","hicfiles.s3.amazonaws.com%2Fhiseq%2Fhela%2Fin-situ%2FHIC086.hic":"5306474712,35595","hicfiles.s3.amazonaws.com%2Fhiseq%2Fhela%2Fin-situ%2FHIC087.hic":"1490963755,36397","hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2Fcombined.hic":"8956382853,50248","hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2FHIC088.hic":"1874185366,32102","hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2FHIC089.hic":"1301165236,32102","hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2FHIC090.hic":"1105246282,32102","hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2FHIC091.hic":"1338325770,32102","hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2FHIC092.hic":"1307918730,32102","hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2FHIC093.hic":"755136918,32102","hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2FHIC094.hic":"1606583694,32102","hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2FHIC095.hic":"2039711245,32102","hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2FHIC096.hic":"1909573053,32102","hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2FHIC097.hic":"1826710712,32102","hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2FHIC098.hic":"1998793575,32102","hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2FHIC099.hic":"1007740962,32102","hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2FHIC100.hic":"736464120,32102","hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2FHIC101.hic":"980505082,32102","hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2FHIC102.hic":"1116083646,32102","hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fdilution%2FHIC103.hic":"1096994310,32102","hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fdilution%2FHIC104.hic":"841063882,32102","hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC105.hic":"107742864,36479","hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC106.hic":"134295912,36479","hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC107.hic":"110228014,36479","hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC108.hic":"102761401,36479","hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC109.hic":"100461491,36479","hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC110.hic":"88828472,36479","hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC111.hic":"81471064,36479","hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC112.hic":"92297035,36479","hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC113.hic":"65503916,36479","hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC114.hic":"49181188,36479","hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC115.hic":"46471102,36479","hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC116.hic":"64284432,36479","hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC117.hic":"60434076,36479","hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC118.hic":"45248563,36479","hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC119.hic":"60288782,36479","hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC120.hic":"136888414,36479","hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC121.hic":"125009003,33681","hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC122.hic":"154011688,34127","hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC123.hic":"177663372,35293","hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC124.hic":"382186226,35245","hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC125.hic":"158160717,35271","hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC127.hic":"110261177,34659","hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC128.hic":"246131875,35509","hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC129.hic":"260160119,35667","hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC130.hic":"117479562,34681","hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC131.hic":"81508929,34673","hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC132.hic":"105959102,34895","hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC133.hic":"91504812,33451","hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC134.hic":"52222546,33737","hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC135.hic":"57763085,34159","hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC136.hic":"50618489,33731","hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC137.hic":"193163606,33363","hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC138.hic":"229876152,33777","hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC139.hic":"201783666,33571","hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC140.hic":"281163862,34125","hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC141.hic":"275969727,33935","hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC142.hic":"275020431,34125","hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC144.hic":"223834810,34177","hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC145.hic":"296632653,33937","hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC146.hic":"290945216,33961","hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC147.hic":"234459964,34231","hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC148.hic":"295457850,34039","hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC149.hic":"113569632,35695","hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC150.hic":"304381897,33963","hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC151.hic":"289314545,33805","hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC152.hic":"284320182,33803","hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC153.hic":"401393947,34659","hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC154.hic":"188065488,36479","hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC155.hic":"299157119,33967","hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC156.hic":"279289244,33787","hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC157.hic":"254852119,33917","hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC158.hic":"195969660,33477","hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC159.hic":"185720388,36479","hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC160.hic":"227709279,33599","hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC161.hic":"157225076,33209","hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC162.hic":"105703444,32033","hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC163.hic":"122665658,32121","hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC164.hic":"228048231,33761","hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC165.hic":"114440819,32011","hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC166.hic":"285147558,33891","hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC167.hic":"363116754,33943","hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC168.hic":"119592158,31937","hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC169.hic":"236853872,33785","hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC170.hic":"195187639,33395","hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC171.hic":"208044058,33309","hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC172.hic":"144645916,32877","hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC173.hic":"119115941,32203","hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC175.hic":"178030481,33525","hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC176.hic":"117220136,32169","hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC177.hic":"128586196,32659","hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC178.hic":"191419141,33629","hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC179.hic":"141556748,32959","hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC180.hic":"199825102,33185","hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC181.hic":"301022688,33783","hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC182.hic":"185384453,33205","hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC183.hic":"202189264,36367","hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC184.hic":"37464475,36479","hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC185.hic":"161938278,36099","hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC186.hic":"133853166,36179","hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC188.hic":"128068030,36237","hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC189.hic":"148053886,36177","hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC190.hic":"198946958,35803","hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC191.hic":"226584564,36063","hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC192.hic":"194412797,36341","hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC193.hic":"176408194,36479","hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC194.hic":"207215649,36055","hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC195.hic":"175185530,36315","hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC196.hic":"168969337,36479","hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC197.hic":"121231252,36339","hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC198.hic":"92713752,36479","hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC199.hic":"105130500,36479","hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC200.hic":"114526350,36479","hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC201.hic":"122689717,36479","hicfiles.s3.amazonaws.com%2Fhiseq%2Fhap1%2Fin-situ%2Fcombined.hic":"9614983328,36479","s3.amazonaws.com%2Fhicfiles%2Fexternal%2Fctbp_8_4_17%2Fall_intra_megabase_michrom.hic":"154205644,10960","hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2Fdel-Xa-combined.hic":"8843305329,36479","hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FdelXa-chrX-diploid.hic":"11173520,1498","hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FWT-combined.hic":"13365182403,36479","hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FWT-chrX-diploid.hic":"17343459,1498","hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FHIC002.hic":"4279298739,36479","hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FHIC003.hic":"3027365532,36479","hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FHIC004.hic":"2896130835,36479","hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FHIC005.hic":"4717830071,36479","hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FHIC006.hic":"5066210154,36479","hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FHIC007.hic":"3069516128,36479","hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2Fdel-Xi-combined.hic":"14551096423,36479","hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FdelXi-chrX-diploid.hic":"17362477,1498","hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FHIC008.hic":"2572386655,36479","hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FHIC009.hic":"2935931663,36479","hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FHIC010.hic":"2019085070,36479","hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FHIC011.hic":"6087610814,36479","hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FHIC012.hic":"2809618194,36479","hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FHIC013.hic":"2572386655,36479","hicfiles.s3.amazonaws.com%2Fhiseq%2Fpatski%2FDarrowHuntley-2015%2Fcombined.hic":"6950423609,32102","hicfiles.s3.amazonaws.com%2Fhiseq%2Fpatski%2FDarrowHuntley-2015%2Fpaternal.hic":"220592749,15691","hicfiles.s3.amazonaws.com%2Fhiseq%2Fpatski%2FDarrowHuntley-2015%2Fmaternal.hic":"323233095,15691","hicfiles.s3.amazonaws.com%2Fhiseq%2Fpatski%2FDarrowHuntley-2015%2FHIC014.hic":"3183235800,32102","hicfiles.s3.amazonaws.com%2Fhiseq%2Fpatski%2FDarrowHuntley-2015%2FHIC015.hic":"1739539801,32102","hicfiles.s3.amazonaws.com%2Fhiseq%2Fpatski%2FDarrowHuntley-2015%2FHIC016.hic":"1105912758,32102","hicfiles.s3.amazonaws.com%2Fhiseq%2Fpatski%2FDarrowHuntley-2015%2FHIC017.hic":"1060773319,32102","hicfiles.s3.amazonaws.com%2Fhiseq%2Fpatski%2FDarrowHuntley-2015%2FHIC018.hic":"1203679874,32102","hicfiles.s3.amazonaws.com%2Fhiseq%2Fpatski%2FDarrowHuntley-2015%2FHIC019.hic":"3321955269,32102","hicfiles.s3.amazonaws.com%2Fhiseq%2Frhesus%2FDarrowHuntley-2015%2FHIC020.hic":"7108980626,32102","hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fcola%2FDarrowHuntley-2015%2FHIC021.hic":"3906448676,34955","hicfiles.s3.amazonaws.com%2Fhiseq%2Fassembly%2Faedes%2Fcombined.hic":"390780490,2245","hicfiles.s3.amazonaws.com%2Fhiseq%2Fassembly%2Fhs2-hic.hic":"1960284186,33561","hicfiles.s3.amazonaws.com%2Fhiseq%2Fassembly%2FCpipJ3.hic":"766279097,4381","s3.amazonaws.com%2Fhicfiles%2Fexternal%2Fphanstiel%2Fupdated_O%2FSnyder_O.hic":"8046980555,18679","s3.amazonaws.com%2Fhicfiles%2Fexternal%2Fphanstiel%2FA_inter.hic":"10986005145,18679","s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Funtreated%2Funsynchronized%2Fcombined.hic":"30439217680,36479","s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftreated_6hr%2Funsynchronized%2Fcombined.hic":"33255540403,36479","s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2Fdeep%2F20min_withdraw_combined.hic":"11078436933,36479","s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2Fdeep%2F40min_withdraw_combined.hic":"11031830038,36479","s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2Fdeep%2F60min_withdraw_combined.hic":"10312725340,36479","s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2Fdeep%2F180min_withdraw_combined.hic":"10038610214,36479","s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Funtreated%2Funsynchronized%2FHIC001.hic":"8004335785,36479","s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Funtreated%2Funsynchronized%2FHIC002.hic":"8453215933,36479","s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Funtreated%2Funsynchronized%2FHIC003.hic":"9118406189,36479","s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Funtreated%2Funsynchronized%2FHIC004.hic":"5973342894,36479","s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Funtreated%2Funsynchronized%2FHIC005.hic":"6846576837,36479","s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Funtreated%2Funsynchronized%2FHIC006.hic":"6075148017,36479","s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Funtreated%2Funsynchronized%2FHIC007.hic":"8192366992,36479","s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftreated_6hr%2Funsynchronized%2FHIC008.hic":"6844159653,36479","s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftreated_6hr%2Funsynchronized%2FHIC009.hic":"7282063059,36479","s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftreated_6hr%2Funsynchronized%2FHIC010.hic":"10410578833,36479","s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftreated_6hr%2Funsynchronized%2FHIC011.hic":"8192366992,36479","s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftreated_6hr%2Funsynchronized%2FHIC012.hic":"7223422850,36479","s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftreated_6hr%2Funsynchronized%2FHIC013.hic":"7435986997,36479","s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftreated_6hr%2Funsynchronized%2FHIC014.hic":"9120113605,36479","s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Funtreated%2Fsynchronized%2Fcombined.hic":"4170577904,36479","s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Funtreated%2Fsynchronized%2FHIC015.hic":"1504084990,36479","s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Funtreated%2Fsynchronized%2FHIC016.hic":"1686244500,36479","s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Funtreated%2Fsynchronized%2FHIC017.hic":"1804802410,36479","s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Funtreated%2Fsynchronized%2FHIC018.hic":"1533942067,36479","s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftreated_6hr%2Fsynchronized%2Fcombined.hic":"4572390198,36479","s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftreated_6hr%2Fsynchronized%2FHIC019.hic":"1543609666,36479","s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftreated_6hr%2Fsynchronized%2FHIC020.hic":"1814133288,36479","s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftreated_6hr%2Fsynchronized%2FHIC021.hic":"1942698243,36479","s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftreated_6hr%2Fsynchronized%2FHIC022.hic":"1873587413,36479","s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2Funtreated%2FRao-2017-HIC049.hic":"405127557,36479","s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2Funtreated%2FRao-2017-HIC060.hic":"326681741,36479","s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2Funtreated%2FRao-2017-HIC061.hic":"300908673,36479","s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_20min%2FRao-2017-HIC050.hic":"481758242,36479","s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_20min%2FRao-2017-HIC051.hic":"417577401,36479","s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_40min%2FRao-2017-HIC052.hic":"419353227,36479","s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_40min%2FRao-2017-HIC053.hic":"411554953,36479","s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_60min%2FRao-2017-HIC054.hic":"386655891,36479","s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_60min%2FRao-2017-HIC055.hic":"402170701,36479","s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_240min%2FRao-2017-HIC057.hic":"735906308,36479","s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min%2FRao-2017-HIC058.hic":"443789827,36479","s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min%2FRao-2017-HIC059.hic":"491422615,36479","s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min%2FRao-2017-HIC062.hic":"320261375,36479","s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min%2FRao-2017-HIC063.hic":"306590499,36479","s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min_withdraw_20min%2FRao-2017-HIC032S.hic":"367051742,36479","s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min_withdraw_20min%2FRao-2017-HIC033S.hic":"344555339,36479","s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min_withdraw_40min%2FRao-2017-HIC036S.hic":"349392947,36479","s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min_withdraw_40min%2FRao-2017-HIC037S.hic":"317714554,36479","s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min_withdraw_60min%2FRao-2017-HIC040S.hic":"266786397,36479","s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min_withdraw_60min%2FRao-2017-HIC041S.hic":"279445530,36479","s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min_withdraw_180min%2FRao-2017-HIC044S.hic":"898418269,36479","s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min_withdraw_180min%2FRao-2017-HIC045S.hic":"961006347,36479","s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min_withdraw_360min%2FRao-2017-HIC064.hic":"833576408,36479","s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min_withdraw_360min%2FRao-2017-HIC065.hic":"840881418,36479","s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min_withdraw_1080min%2FRao-2017-HIC066.hic":"980958864,36479","s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min_withdraw_1080min%2FRao-2017-HIC067.hic":"882023129,36479","s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min_withdraw_1440min%2FRao-2017-HIC068.hic":"1110292630,36479","s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min_withdraw_1440min%2FRao-2017-HIC069.hic":"1001747023,36479","s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fexternal%2Frowley_nichols_mol_cell_2017%2FCP190_HiChIP.hic":"144107588,6976","s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fexternal%2Frowley_nichols_mol_cell_2017%2FH3K27ac_HiChIP_combined.hic":"43171370,5233","s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fexternal%2Frowley_nichols_mol_cell_2017%2FH3K27me3_HiChIP_combined.hic":"42906472,5233","s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fexternal%2Frowley_nichols_mol_cell_2017%2FPol2_ChIAPET.hic":"41992430,6976","s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fexternal%2Frowley_nichols_mol_cell_2017%2FPol2S2_HiChIP.hic":"145842743,6976","s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fexternal%2Frowley_nichols_mol_cell_2017%2FArabidopsis_Wang2015_Liu2016.hic":"1134391078,4984","s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fexternal%2Frowley_nichols_mol_cell_2017%2FElegans_Crane2015.hic":"387127568,8758","s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fexternal%2Frowley_nichols_mol_cell_2017%2FNcrassa_Galazka2016.hic":"26555511,27725","s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fexternal%2Frowley_nichols_mol_cell_2017%2FPfalciparum_trophozoite_Ay2014.hic":"15640893,13948","hicfiles.s3.amazonaws.com%2Fexternal%2Fduan%2FE-Me-A.hic":"6897251,23348","hicfiles.s3.amazonaws.com%2Fexternal%2Fduan%2FE-Me-B.hic":"4959088,23348","hicfiles.s3.amazonaws.com%2Fexternal%2Fduan%2FE-Mp-A.hic":"5232286,23348","hicfiles.s3.amazonaws.com%2Fexternal%2Fduan%2FE-Mp-B.hic":"5105292,23348","hicfiles.s3.amazonaws.com%2Fexternal%2Fduan%2FH-Me-A.hic":"6900072,23348","hicfiles.s3.amazonaws.com%2Fexternal%2Fduan%2FH-Me-B.hic":"8653258,23348","hicfiles.s3.amazonaws.com%2Fexternal%2Fduan%2FH-Mp-A.hic":"7999058,23348","hicfiles.s3.amazonaws.com%2Fexternal%2Fduan%2FH-Mp-B.hic":"8774657,23348","hicfiles.s3.amazonaws.com%2Fexternal%2Fdekker%2F4dn%2Fh1hesc.hic":"23671753603,36479","hicfiles.s3.amazonaws.com%2Fexternal%2Fdekker%2F4dn%2Fh1hesc_rep1.hic":"23671754721,36479","hicfiles.s3.amazonaws.com%2Fexternal%2Fdekker%2F4dn%2Fh1hesc_rep2.hic":"22269909910,36479","hicfiles.s3.amazonaws.com%2Fexternal%2Fdekker%2F4dn%2Fhffc6_rep1.hic":"19016661622,36479","hicfiles.s3.amazonaws.com%2Fexternal%2Flieberman_aiden_van_berkum%2FGM06990_NcoI.hic":"480725203,36479","hicfiles.s3.amazonaws.com%2Fexternal%2Flieberman_aiden_van_berkum%2F302NH.hic":"99948617,36479","hicfiles.s3.amazonaws.com%2Fexternal%2Flieberman_aiden_van_berkum%2FK562.hic":"470263605,36151","hicfiles.s3.amazonaws.com%2Fexternal%2Flieberman_aiden_van_berkum%2FGM06990_HindIII.hic":"293706559,36289","hicfiles.s3.amazonaws.com%2Fexternal%2Flieberman_aiden_van_berkum%2FGM06990_rep_HindIII.hic":"309673862,36087","hicfiles.s3.amazonaws.com%2Fexternal%2Frudan%2Fcanis-lupus-rep1.hic":"1531151371,56905","hicfiles.s3.amazonaws.com%2Fexternal%2Frudan%2Fcanis-lupus-rep2.hic":"2851437676,56905","hicfiles.s3.amazonaws.com%2Fexternal%2Frudan%2Fmouse-rep1.hic":"582052544,32102","hicfiles.s3.amazonaws.com%2Fexternal%2Frudan%2Fmacaque-rep1.hic":"698509182,32102","hicfiles.s3.amazonaws.com%2Fexternal%2Frudan%2Fmacaque-rep2.hic":"461410393,32102","hicfiles.s3.amazonaws.com%2Fexternal%2Frudan%2Frabbit-rep1.hic":"691045338,33561","hicfiles.s3.amazonaws.com%2Fexternal%2Frudan%2Frabbit-rep2.hic":"668888336,33561","hicfiles.s3.amazonaws.com%2Fexternal%2Fsexton%2Fcombined.hic":"50650087,4486","hicfiles.s3.amazonaws.com%2Fexternal%2Fkalhor%2Ftcc-hindiii.hic":"1071142023,16500","hicfiles.s3.amazonaws.com%2Fexternal%2Fkalhor%2Ftcc-mboi.hic":"1508851093,16448","hicfiles.s3.amazonaws.com%2Fexternal%2Fkalhor%2Fnon-tcc-hindiii.hic":"395179229,36093","hicfiles.s3.amazonaws.com%2Fexternal%2Fkalhor%2Ftcc-combined.hic":"1050423847,36479","hicfiles.s3.amazonaws.com%2Fexternal%2Fdixon%2Fmm9-hindiii%2Fsplit-read-run.hic":"9599984876,32102","hicfiles.s3.amazonaws.com%2Fexternal%2Fdixon%2Fhesc-hindiii.hic":"1952555632,36479","hicfiles.s3.amazonaws.com%2Fexternal%2Fdixon%2Fimr90-hindiii.hic":"9691260435,18679","hicfiles.s3.amazonaws.com%2Fexternal%2Fdixon%2Fmm9-cortex.hic":"3712072953,32102","hicfiles.s3.amazonaws.com%2Fexternal%2Fzhang%2Fatm-i-scei-chr18.hic":"2083350075,16438","hicfiles.s3.amazonaws.com%2Fexternal%2Fzhang%2Fatm-i-scei-chr2.hic":"3362049644,16360","hicfiles.s3.amazonaws.com%2Fexternal%2Fzhang%2Fatm-i-scei-chr7.hic":"1658399854,16438","hicfiles.s3.amazonaws.com%2Fexternal%2Fzhang%2Fwt-i-scei-chr15.hic":"866691249,16438","hicfiles.s3.amazonaws.com%2Fexternal%2Fzhang%2Fwt-i-scei-chr2.hic":"3304782795,16386","hicfiles.s3.amazonaws.com%2Fexternal%2Fnagano%2Fcell-1.hic":"23673506,32102","hicfiles.s3.amazonaws.com%2Fexternal%2Fnagano%2Fcell-2.hic":"26873280,30643","hicfiles.s3.amazonaws.com%2Fexternal%2Fnagano%2Fcell-3.hic":"31066362,30643","hicfiles.s3.amazonaws.com%2Fexternal%2Fnagano%2Fcell-4.hic":"16807724,30643","hicfiles.s3.amazonaws.com%2Fexternal%2Fnagano%2Fcell-5.hic":"28665065,30643","hicfiles.s3.amazonaws.com%2Fexternal%2Fnagano%2Fcell-6.hic":"13124158,30643","hicfiles.s3.amazonaws.com%2Fexternal%2Fnagano%2Fcell-7.hic":"15118945,30643","hicfiles.s3.amazonaws.com%2Fexternal%2Fnagano%2Fcell-8.hic":"68316814,32102","hicfiles.s3.amazonaws.com%2Fexternal%2Fnagano%2Fcell-9.hic":"18965101,30643","hicfiles.s3.amazonaws.com%2Fexternal%2Fnagano%2Fcell-10.hic":"17020666,30643","hicfiles.s3.amazonaws.com%2Fexternal%2Fjin%2Fimr90%2Fcombined.hic":"6526601242,36427","hicfiles.s3.amazonaws.com%2Fexternal%2Fjin%2Fimr90%2Frep1.hic":"1861562891,36401","hicfiles.s3.amazonaws.com%2Fexternal%2Fjin%2Fimr90%2Frep2.hic":"3061013635,36479","hicfiles.s3.amazonaws.com%2Fexternal%2Fjin%2Fimr90%2Frep3.hic":"1564588211,35969","hicfiles.s3.amazonaws.com%2Fexternal%2Fjin%2Fimr90%2Frep4.hic":"1255543175,36153","hicfiles.s3.amazonaws.com%2Fexternal%2Fjin%2Fimr90%2Frep5.hic":"974683253,36179","hicfiles.s3.amazonaws.com%2Fexternal%2Fjin%2Fimr90%2Frep6.hic":"1040805629,36053","hicfiles.s3.amazonaws.com%2Fexternal%2Fjin%2Fimr90-tnf-alpha%2Fcombined.hic":"8424080116,36401","hicfiles.s3.amazonaws.com%2Fexternal%2Fjin%2Fimr90-tnf-alpha%2Frep1.hic":"2697976702,36295","hicfiles.s3.amazonaws.com%2Fexternal%2Fjin%2Fimr90-tnf-alpha%2Frep3.hic":"1718610467,36159","hicfiles.s3.amazonaws.com%2Fexternal%2Fjin%2Fimr90-tnf-alpha%2Frep4.hic":"2029519405,36101","hicfiles.s3.amazonaws.com%2Fexternal%2Fjin%2Fimr90-tnf-alpha%2Frep5.hic":"985310855,36069","hicfiles.s3.amazonaws.com%2Fexternal%2Fjin%2Fimr90-tnf-alpha%2Frep6.hic":"1418750480,35967","hicfiles.s3.amazonaws.com%2Fexternal%2Fcheng%2Fmhh-call-4-cell-line.hic":"538380253,35351","hicfiles.s3.amazonaws.com%2Fexternal%2Fcheng%2Fprimary-b-all.hic":"773764191,35793","hicfiles.s3.amazonaws.com%2Fexternal%2Fcheng%2Fnormal-b-cell-line.hic":"336271459,35005","hicfiles.s3.amazonaws.com%2Fexternal%2Fcheng%2Frl-cell-line.hic":"484807998,35351","hicfiles.s3.amazonaws.com%2Fexternal%2Fhou%2Fkc167-biorep.hic":"135932435,8758","hicfiles.s3.amazonaws.com%2Fexternal%2Fhou%2Fkc167-techrep1.hic":"160355961,8758","hicfiles.s3.amazonaws.com%2Fexternal%2Fhou%2Fkc167-techrep2.hic":"188809887,8758","hicfiles.s3.amazonaws.com%2Fexternal%2Flin%2Fpre-prob-egs.hic":"2237792858,15483","hicfiles.s3.amazonaws.com%2Fexternal%2Flin%2Fprob-egs.hic":"5744720377,16438","hicfiles.s3.amazonaws.com%2Fexternal%2Flin%2Fprob-fa.hic":"2174866215,16438","hicfiles.s3.amazonaws.com%2Fexternal%2Fli%2Fhct116-rnapii-pilot.hic":"396366166,35999","hicfiles.s3.amazonaws.com%2Fexternal%2Fli%2Fhela-rnapii-pilot.hic":"882516759,35107","hicfiles.s3.amazonaws.com%2Fexternal%2Fli%2Fk562-rnapii-pilot.hic":"1131576189,35969","hicfiles.s3.amazonaws.com%2Fexternal%2Fli%2Fk562-rnapii-saturated.hic":"571583828,36291","hicfiles.s3.amazonaws.com%2Fexternal%2Fli%2Fmcf7-rnapii-saturated.hic":"1282547841,36035","hicfiles.s3.amazonaws.com%2Fexternal%2Fli%2Fnb4-rnapii-pilot.hic":"761614686,34861","hicfiles.s3.amazonaws.com%2Fexternal%2Fjung%2Fmouse_sperm.hic":"1730231642,29184","hicfiles.s3.amazonaws.com%2Fexternal%2Ftang%2Fgm12878.hic":"1953518212,20505","hicfiles.s3.amazonaws.com%2Fexternal%2Frutledge%2FSRR1791299.hic":"5723484,11956","hicfiles.s3.amazonaws.com%2Fexternal%2Frutledge%2FSRR1791297.hic":"16534743,23348","hicfiles.s3.amazonaws.com%2Fexternal%2Fzuin%2Fhek293t-rad21cv-hrv.hic":"5094525579,36289","hicfiles.s3.amazonaws.com%2Fexternal%2Fzuin%2Fhek293t-rad21cv-hrv-rep1.hic":"2574358912,36373","hicfiles.s3.amazonaws.com%2Fexternal%2Fzuin%2Fhek293t-rad21cv-hrv-rep2.hic":"3417099433,36243","hicfiles.s3.amazonaws.com%2Fexternal%2Fzuin%2Fhek293t-rad21cv-tev.hic":"4785157552,36323","hicfiles.s3.amazonaws.com%2Fexternal%2Fzuin%2Fhek293t-rad21cv-tev-rep1.hic":"2648268465,36321","hicfiles.s3.amazonaws.com%2Fexternal%2Fzuin%2Fhek293t-rad21cv-tev-rep2.hic":"2994727980,36107","hicfiles.s3.amazonaws.com%2Fexternal%2Fzuin%2Fhek293t-sirna-ctcf.hic":"5391791815,36063","hicfiles.s3.amazonaws.com%2Fexternal%2Fzuin%2Fhek293t-sirna-ctcf-rep1.hic":"3325842095,36269","hicfiles.s3.amazonaws.com%2Fexternal%2Fzuin%2Fhek293t-sirna-ctcf-rep2.hic":"3096215920,36167","hicfiles.s3.amazonaws.com%2Fexternal%2Fzuin%2Fhek293t-sirna-ctrl.hic":"3830902383,36167","hicfiles.s3.amazonaws.com%2Fexternal%2Fzuin%2Fhek293t-sirna-ctrl-rep1.hic":"1346712252,36079","hicfiles.s3.amazonaws.com%2Fexternal%2Fzuin%2Fhek293t-sirna-ctrl_rep2.hic":"3098067367,36271","hicfiles.s3.amazonaws.com%2Fexternal%2Fay%2Fp-falciparum-3d7-0h-hiseq.hic":"38174042,21889","hicfiles.s3.amazonaws.com%2Fexternal%2Fay%2Fp-falciparum-3d7-18h-hiseq.hic":"26506099,21889","hicfiles.s3.amazonaws.com%2Fexternal%2Fay%2Fp-falciparum-3d7-18h-hiseq-non-crosslinked_control.hic":"3545496,21889","hicfiles.s3.amazonaws.com%2Fexternal%2Fay%2Fp-falciparum-3d7-36h-hiseq.hic":"70754194,21889","hicfiles.s3.amazonaws.com%2Fexternal%2Fnaumova%2Fhelas3%2Fg1mid-r1.hic":"200863476,17185","hicfiles.s3.amazonaws.com%2Fexternal%2Fnaumova%2Fhelas3%2Fm-r1.hic":"249021190,17185","hicfiles.s3.amazonaws.com%2Fexternal%2Fnaumova%2Fhelas3%2Fm-r2.hic":"212341157,17185","hicfiles.s3.amazonaws.com%2Fexternal%2Fnaumova%2Fhelas3ccl2p2%2Fg1-0-25fa.hic":"583572265,17185","hicfiles.s3.amazonaws.com%2Fexternal%2Fnaumova%2Fhelas3ccl2p2%2Fg1-1fa.hic":"354502306,17185","hicfiles.s3.amazonaws.com%2Fexternal%2Fnaumova%2Fhelas3ccl2p2%2Fm-0-25fa.hic":"149308791,17185","hicfiles.s3.amazonaws.com%2Fexternal%2Fnaumova%2Fhelas3ccl2p2%2Fm-98percent.hic":"778175225,17185","hicfiles.s3.amazonaws.com%2Fexternal%2Fnaumova%2Fhelas3ccl2p2%2Fm-1fa.hic":"158091047,17185","hicfiles.s3.amazonaws.com%2Fexternal%2Fnaumova%2Fhff1%2Fcchic-hff1-ns-r1.hic":"801670039,17185","hicfiles.s3.amazonaws.com%2Fexternal%2Fnaumova%2Fhff1%2Fcchic-hff1-m-r1.hic":"875922086,17185","hicfiles.s3.amazonaws.com%2Fexternal%2Fnaumova%2Fk562%2Fm-r1.hic":"130959943,17185","hicfiles.s3.amazonaws.com%2Fexternal%2Fnaumova%2Fk562%2Fm-r2.hic":"237861106,17185","hicfiles.s3.amazonaws.com%2Fexternal%2Fsofueva%2FmAST-WT.hic":"496104039,30643","hicfiles.s3.amazonaws.com%2Fexternal%2Fsofueva%2FmAST-WT-adv-cre.hic":"438608517,30643","hicfiles.s3.amazonaws.com%2Fexternal%2Fsofueva%2FmAST-floxed-rep1.hic":"446205712,32102","hicfiles.s3.amazonaws.com%2Fexternal%2Fsofueva%2FmAST-floxed-rep2.hic":"386354767,32102","hicfiles.s3.amazonaws.com%2Fexternal%2Fsofueva%2FmAST-deleted-rep1.hic":"621998722,30643","hicfiles.s3.amazonaws.com%2Fexternal%2Fsofueva%2FmAST-deleted-rep2.hic":"583840829,32102","hicfiles.s3.amazonaws.com%2Fexternal%2Fsofueva%2FmNSC-floxed-rep1.hic":"801290988,30643","hicfiles.s3.amazonaws.com%2Fexternal%2Fsofueva%2FmNSC-floxed-rep2.hic":"819406658,30643","hicfiles.s3.amazonaws.com%2Fexternal%2Fsofueva%2FmNSC-deleted-rep1.hic":"792825269,32102","hicfiles.s3.amazonaws.com%2Fexternal%2Fsofueva%2FmNSC-deleted-rep2.hic":"746189884,30643","hicfiles.s3.amazonaws.com%2Fexternal%2Fsofueva%2FmNSC-WT.hic":"309353372,30643","hicfiles.s3.amazonaws.com%2Fexternal%2Fsofueva%2FmNSC-WT-OHT.hic":"274229679,30643","hicfiles.s3.amazonaws.com%2Fexternal%2Fseitan%2FTcell-Rad21KO-R1.hic":"1490362251,32102","hicfiles.s3.amazonaws.com%2Fexternal%2Fseitan%2FTcell-Rad21KO-R3.hic":"2403664421,32102","hicfiles.s3.amazonaws.com%2Fexternal%2Fseitan%2FTcell-Rad21WT-R1.hic":"1377124538,32102","hicfiles.s3.amazonaws.com%2Fexternal%2Fseitan%2FTcell-Rad21WT-R3.hic":"2646201369,32102","hicfiles.s3.amazonaws.com%2Fexternal%2Fmoissiard%2Fcrh6-mutant.hic":"105261071,10217","hicfiles.s3.amazonaws.com%2Fexternal%2Fmoissiard%2FWT.hic":"127506388,10217","hicfiles.s3.amazonaws.com%2Fexternal%2Fgrob%2FCol.hic":"153638500,10217","hicfiles.s3.amazonaws.com%2Fexternal%2Fgrob%2Fcrwn1.hic":"211213220,10217","hicfiles.s3.amazonaws.com%2Fexternal%2Fgrob%2Fcrwn4.hic":"134236837,10217","hicfiles.s3.amazonaws.com%2Fexternal%2Fxie%2Fprimary.hic":"92936173,10217","hicfiles.s3.amazonaws.com%2Fexternal%2Ffeng%2F6wt-control6wt337.hic":"318737891,10217","hicfiles.s3.amazonaws.com%2Fexternal%2Ffeng%2F6wt-control6wt67.hic":"348123956,10217","hicfiles.s3.amazonaws.com%2Fexternal%2Ffeng%2F6wt337.hic":"251107279,10217","hicfiles.s3.amazonaws.com%2Fexternal%2Ffeng%2F6wt67.hic":"351840994,10217","hicfiles.s3.amazonaws.com%2Fexternal%2Ffeng%2FCol0.hic":"345969497,10217","hicfiles.s3.amazonaws.com%2Fexternal%2Ffeng%2Fclf28-swn7.hic":"299585025,10217","hicfiles.s3.amazonaws.com%2Fexternal%2Ffeng%2Fcmt3-11.hic":"253427706,10217","hicfiles.s3.amazonaws.com%2Fexternal%2Ffeng%2Fddm1-2.hic":"303626924,10217","hicfiles.s3.amazonaws.com%2Fexternal%2Ffeng%2Fmet1-3.hic":"347697973,10217","hicfiles.s3.amazonaws.com%2Fexternal%2Ffeng%2Fsuvh4-suvh5-suvh6.hic":"263122019,10217","hicfiles.s3.amazonaws.com%2Fexternal%2Fma%2FDNase-HiC-WG-K562.hic":"892955840,18679","hicfiles.s3.amazonaws.com%2Fexternal%2Fma%2FDNaseHiC-WG-H1.hic":"696922695,18679","hicfiles.s3.amazonaws.com%2Fexternal%2Fma%2FtargetedDNaseHiC-lincRNA-K562-rep1.hic":"341917716,18679","hicfiles.s3.amazonaws.com%2Fexternal%2Fma%2FtargeredDNaseHiC-lincRNA-K562-rep2.hic":"214841185,18679","hicfiles.s3.amazonaws.com%2Fexternal%2Fma%2FtargetedDNaseHiC-lincRNA-H1-rep1.hic":"616326137,18679","hicfiles.s3.amazonaws.com%2Fexternal%2Fma%2FtargetedDNaseHiC-lincRNA-H1-rep2.hic":"579654013,18679","hicfiles.s3.amazonaws.com%2Fexternal%2Fma%2FtargetedDNaseHiC-pe-H1-rep1.hic":"519810544,18679","hicfiles.s3.amazonaws.com%2Fexternal%2Fma%2FtargetedDNaseHiC-pe-K562-rep1.hic":"199553123,18679","hicfiles.s3.amazonaws.com%2Fexternal%2Frowley%2FKc167_DpnII.hic":"1319373594,6976","hicfiles.s3.amazonaws.com%2Fexternal%2Frowley%2FKc167_HinfI.hic":"1465493873,6976","hicfiles.s3.amazonaws.com%2Fexternal%2Frowley%2FKc167_DpnII_HinfI_combo.hic":"753062558,5814","hicfiles.s3.amazonaws.com%2Fexternal%2Fbarutcu%2FMCF-10A.hic":"2784956115,36479","hicfiles.s3.amazonaws.com%2Fexternal%2Fbarutcu%2FMCF-7.hic":"2700457411,36479","hicfiles.s3.amazonaws.com%2Fexternal%2Fbatullin%2Fsperm.hic":"501052169,32102","hicfiles.s3.amazonaws.com%2Fexternal%2Fminajigi%2FWT_hiC_rep1.hic":"1450697530,32102","hicfiles.s3.amazonaws.com%2Fexternal%2Fminajigi%2FWT_hiC_rep2.hic":"1189371558,32102","hicfiles.s3.amazonaws.com%2Fexternal%2Fminajigi%2Fcombined.hic":"2262007875,32102","hicfiles.s3.amazonaws.com%2Fexternal%2Fminajigi%2Finactive.hic":"4444564,751","hicfiles.s3.amazonaws.com%2Fexternal%2Fminajigi%2Factive.hic":"3993495,751","hicfiles.s3.amazonaws.com%2Fexternal%2Fdeng%2Fpatski_rep1.hic":"1650838357,32102","hicfiles.s3.amazonaws.com%2Fexternal%2Fdeng%2Fpatski_rep2.hic":"1258038606,32102","hicfiles.s3.amazonaws.com%2Fexternal%2Fdeng%2Fpatski.hic":"499827296,16438","hicfiles.s3.amazonaws.com%2Fexternal%2Fdeng%2Fpatski_active.hic":"79175714,15691","hicfiles.s3.amazonaws.com%2Fexternal%2Fdeng%2Fpatski_inactive.hic":"98947881,15691","hicfiles.s3.amazonaws.com%2Fexternal%2Fdeng%2Fbrain_dnase.hic":"4298088401,32102","hicfiles.s3.amazonaws.com%2Fexternal%2Fdeng%2Fbrain_in_situ_dnase.hic":"609321852,32102","hicfiles.s3.amazonaws.com%2Fexternal%2Fdeng%2Fbrain.hic":"1028196506,16438","hicfiles.s3.amazonaws.com%2Fexternal%2Fdeng%2Fbrain_active.hic":"79175714,15691","hicfiles.s3.amazonaws.com%2Fexternal%2Fdeng%2Fbrain_inactive.hic":"98947881,15691","hicfiles.s3.amazonaws.com%2Fexternal%2Fle%2FBglII_rep1.hic":"1283306,1463","hicfiles.s3.amazonaws.com%2Fexternal%2Fle%2FBglII_rep2.hic":"1263227,1463","hicfiles.s3.amazonaws.com%2Fexternal%2Fle%2FNcoI_rep1.hic":"4380906,1463","hicfiles.s3.amazonaws.com%2Fexternal%2Feagen%2FGSE89112_Kc167combined.hic":"1829549643,25624","hicfiles.s3.amazonaws.com%2Fexternal%2Feagen%2FGSE89112_Kc167combined_randomized.hic":"1859742654,25624","hicfiles.s3.amazonaws.com%2Fexternal%2Fmumbach%2FGSE80820_HiChIP_GM_cohesin.hic":"1231264781,17932","hicfiles.s3.amazonaws.com%2Fexternal%2Fmumbach%2FGSE80820_HiChIP_mES_cohesin_all.hic":"1152008628,16438","hicfiles.s3.amazonaws.com%2Fexternal%2Fmumbach%2FGSE80820_HiChIP_mES_Oct4.hic":"912828146,16438","s3.amazonaws.com%2Fhicfiles%2Fexternal%2Fwapl_hic%2FSCC4KO.hic":"1767906138,18679","s3.amazonaws.com%2Fhicfiles%2Fexternal%2Fwapl_hic%2FDKO.hic":"1487228787,18679","s3.amazonaws.com%2Fhicfiles%2Fexternal%2Fwapl_hic%2FWaplKO_1.14.hic":"1189751862,18679","s3.amazonaws.com%2Fhicfiles%2Fexternal%2Fwapl_hic%2FWaplKO_3.3.hic":"1155057696,18679","s3.amazonaws.com%2Fhicfiles%2Fexternal%2Fwapl_hic%2FWT.hic":"1522401568,18679","s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fskfuwi4fnsjkdf9jekrw2%2Fmega_Liverpool%2Fmega.hic":"2612171975,4381","s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fskfuwi4fnsjkdf9jekrw2%2FHIC2836_Liverpool1%2FLiverpool1.hic":"191729195,2245","s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fskfuwi4fnsjkdf9jekrw2%2FHIC2861_Liverpool2%2FLiverpool2.hic":"1637096030,4381","s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fskfuwi4fnsjkdf9jekrw2%2FHIC2862_Liverpool3%2FLiverpool3.hic":"1160045602,4381","s3.amazonaws.com%2Fhicfiles%2Fexternal%2Fgoodell%2FHSPC.hic":"11857786247,36479","s3.amazonaws.com%2Fhicfiles%2Fexternal%2Fgoodell%2FHSPC_CanyonDel.hic":"8139168836,36479","s3.amazonaws.com%2Fhicfiles%2Fexternal%2Fgoodell%2Ftcell.hic":"9871547081,36479","s3.amazonaws.com%2Fhicfiles%2Fexternal%2Fgoodell%2Fep.hic":"17479335373,36479","hicfiles.s3.amazonaws.com%2Fexternal%2Fnagano%2FTh1_ensemble.hic":"1690592868,32102","hicfiles.s3.amazonaws.com%2Fexternal%2Fbonev%2FES_mapq30.hic":"32930498831,32386","hicfiles.s3.amazonaws.com%2Fexternal%2Fbonev%2FNPC_mapq30.hic":"55053730986,32386","hicfiles.s3.amazonaws.com%2Fexternal%2Fbonev%2FCN_mapq30.hic":"53138031154,32386","hicfiles.s3.amazonaws.com%2Fhiseq%2FKieffer-Kwon_et_al_2017%2FMain_maps%2FKieffer-Kwon-2017-activated_B_cells_72_hours_WT.hic":"16492991184,32102","hicfiles.s3.amazonaws.com%2Fhiseq%2FKieffer-Kwon_et_al_2017%2FMain_maps%2FKieffer-Kwon-2017-resting_B_cells_WT.hic":"23057795398,32102","hicfiles.s3.amazonaws.com%2Fhiseq%2FKieffer-Kwon_et_al_2017%2FMain_maps%2FKieffer-Kwon-2017-activated_B_cells_24_hours_MYC_KO.hic":"21245554876,32102","hicfiles.s3.amazonaws.com%2Fhiseq%2FKieffer-Kwon_et_al_2017%2FMain_maps%2FKieffer-Kwon-2017-resting_B_cells_TSA.hic":"13933346059,32102","hicfiles.s3.amazonaws.com%2Fhiseq%2FKieffer-Kwon_et_al_2017%2FMain_maps%2FKieffer-Kwon-2017-activated_B_cells_24_hours_oligomycin.hic":"21902506832,32102","hicfiles.s3.amazonaws.com%2Fhiseq%2FKieffer-Kwon_et_al_2017%2FMain_maps%2FKieffer-Kwon-2017-mES_WT.hic":"9451969795,32102","hicfiles.s3.amazonaws.com%2Fhiseq%2FVian_et_al_2018%2FMain_maps%2FVian-2018-activated_B_cells_24_hours_WT.hic":"3600188564,16438","hicfiles.s3.amazonaws.com%2Fhiseq%2FVian_et_al_2018%2FMain_maps%2FVian-2018-activated_B_cells_30_hours_WT.hic":"1309503359,16438","hicfiles.s3.amazonaws.com%2Fhiseq%2FVian_et_al_2018%2FMain_maps%2FVian-2018-activated_B_cells_30_hours_HU_treated.hic":"1477252396,16438","hicfiles.s3.amazonaws.com%2Fhiseq%2FVian_et_al_2018%2FMain_maps%2FVian-2018-activated_B_cells_24_hours_flavopiridol.hic":"15711773490,32102","hicfiles.s3.amazonaws.com%2Fexternal%2Fpgp%2FPGP1F_mega_090118%2FPGP1F_mega_090118_30.hic":"24786676166,36479","hicfiles.s3.amazonaws.com%2Fexternal%2Fpgp%2FHIC7145%2FHIC7145_30.hic":"4554644616,36479","hicfiles.s3.amazonaws.com%2Fexternal%2Fpgp%2FHIC7146%2FHIC7146_30.hic":"4174848944,36479","hicfiles.s3.amazonaws.com%2Fexternal%2Fpgp%2FHIC7147%2FHIC7147_30.hic":"5062229182,36479","hicfiles.s3.amazonaws.com%2Fexternal%2Fpgp%2FHIC7862%2FHIC7862_30.hic":"4520990620,36479","hicfiles.s3.amazonaws.com%2Fexternal%2Fpgp%2FHIC7863%2FHIC7863_30.hic":"4330354773,36479","hicfiles.s3.amazonaws.com%2Fexternal%2Fpgp%2FHIC7864%2FHIC7864_30.hic":"5880640268,36479","hicfiles.s3.amazonaws.com%2Fexternal%2Fpgp%2FHIC7865%2FHIC7865_30.hic":"4431632469,36479","hicfiles.s3.amazonaws.com%2Fexternal%2Fpgp%2FHIC7866%2FHIC7866_30.hic":"4686000222,36479","encode-public.s3.amazonaws.com%2F2018%2F10%2F19%2Fb122542b-306c-4631-bdc3-2e155e89af55%2FENCFF718AWL.hic":"39544267907,58932","encode-public.s3.amazonaws.com%2F2019%2F02%2F15%2F8e787cd8-e388-4bc2-a236-7a5e6f39e0c0%2FENCFF999YXX.hic":"9255069996,56883","encode-public.s3.amazonaws.com%2F2019%2F02%2F08%2Ffc1d9d5d-8fa0-4e29-9080-3da674d9490d%2FENCFF543USQ.hic":"5005263062,36479","s3.us-east-1.wasabisys.com%2Fhicfiles%2Finternal%2FLCL_mega_42B_500bp_30.hic":"106482584851,22829","www.encodeproject.org%2Ffiles%2FENCFF925QIF%2F%40%40download%2FENCFF925QIF.hic":"51712684396,54779","www.encodeproject.org%2Ffiles%2FENCFF259YUS%2F%40%40download%2FENCFF259YUS.hic":"24640030444,54779","www.encodeproject.org%2Ffiles%2FENCFF783KQI%2F%40%40download%2FENCFF783KQI.hic":"27209249856,54779","www.encodeproject.org%2Ffiles%2FENCFF318JAP%2F%40%40download%2FENCFF318JAP.hic":"28636979242,54779","www.encodeproject.org%2Ffiles%2FENCFF512PQA%2F%40%40download%2FENCFF512PQA.hic":"28124104361,54779","www.encodeproject.org%2Ffiles%2FENCFF591MHA%2F%40%40download%2FENCFF591MHA.hic":"37373387202,54779","www.encodeproject.org%2Ffiles%2FENCFF197OWW%2F%40%40download%2FENCFF197OWW.hic":"41826180893,54779","www.encodeproject.org%2Ffiles%2FENCFF317OIA%2F%40%40download%2FENCFF317OIA.hic":"34741636038,54779","www.encodeproject.org%2Ffiles%2FENCFF522YLZ%2F%40%40download%2FENCFF522YLZ.hic":"24064692329,54779","www.encodeproject.org%2Ffiles%2FENCFF420JTA%2F%40%40download%2FENCFF420JTA.hic":"21202405177,54779","www.encodeproject.org%2Ffiles%2FENCFF871ZDJ%2F%40%40download%2FENCFF871ZDJ.hic":"10124815680,18679","www.encodeproject.org%2Ffiles%2FENCFF349RZY%2F%40%40download%2FENCFF349RZY.hic":"4446702705,36479","www.encodeproject.org%2Ffiles%2FENCFF738YON%2F%40%40download%2FENCFF738YON.hic":"3338049584,35947","www.encodeproject.org%2Ffiles%2FENCFF406KJN%2F%40%40download%2FENCFF406KJN.hic":"4132875306,36479","www.encodeproject.org%2Ffiles%2FENCFF081NPN%2F%40%40download%2FENCFF081NPN.hic":"34495587443,54779","www.encodeproject.org%2Ffiles%2FENCFF946RZW%2F%40%40download%2FENCFF946RZW.hic":"34571955193,54779","www.encodeproject.org%2Ffiles%2FENCFF602CHT%2F%40%40download%2FENCFF602CHT.hic":"30674798032,54779","www.encodeproject.org%2Ffiles%2FENCFF150DKS%2F%40%40download%2FENCFF150DKS.hic":"12618769864,36479","www.encodeproject.org%2Ffiles%2FENCFF614IPZ%2F%40%40download%2FENCFF614IPZ.hic":"42450060331,54779","www.encodeproject.org%2Ffiles%2FENCFF571ZQR%2F%40%40download%2FENCFF571ZQR.hic":"15230068871,47429","www.encodeproject.org%2Ffiles%2FENCFF705MKK%2F%40%40download%2FENCFF705MKK.hic":"38686554702,54779","www.encodeproject.org%2Ffiles%2FENCFF658KTB%2F%40%40download%2FENCFF658KTB.hic":"13195884405,47429","www.encodeproject.org%2Ffiles%2FENCFF435JYN%2F%40%40download%2FENCFF435JYN.hic":"17192139674,54779","www.encodeproject.org%2Ffiles%2FENCFF016JKX%2F%40%40download%2FENCFF016JKX.hic":"37266736642,54779","www.encodeproject.org%2Ffiles%2FENCFF294GFP%2F%40%40download%2FENCFF294GFP.hic":"36389843399,54779","www.encodeproject.org%2Ffiles%2FENCFF700CYI%2F%40%40download%2FENCFF700CYI.hic":"60482012152,54779","www.encodeproject.org%2Ffiles%2FENCFF962EDB%2F%40%40download%2FENCFF962EDB.hic":"39394328182,54779","www.encodeproject.org%2Ffiles%2FENCFF467OGP%2F%40%40download%2FENCFF467OGP.hic":"35572788855,54779","www.encodeproject.org%2Ffiles%2FENCFF556RLR%2F%40%40download%2FENCFF556RLR.hic":"34826921187,54779","www.encodeproject.org%2Ffiles%2FENCFF309UNV%2F%40%40download%2FENCFF309UNV.hic":"48510618174,54779","www.encodeproject.org%2Ffiles%2FENCFF653HCO%2F%40%40download%2FENCFF653HCO.hic":"41079007620,54779","www.encodeproject.org%2Ffiles%2FENCFF120DSV%2F%40%40download%2FENCFF120DSV.hic":"12790195576,47429","www.encodeproject.org%2Ffiles%2FENCFF284OEA%2F%40%40download%2FENCFF284OEA.hic":"46007570339,54779","www.encodeproject.org%2Ffiles%2FENCFF035BLF%2F%40%40download%2FENCFF035BLF.hic":"63868871985,54779","www.encodeproject.org%2Ffiles%2FENCFF094KKX%2F%40%40download%2FENCFF094KKX.hic":"42151419971,54779","www.encodeproject.org%2Ffiles%2FENCFF965BPU%2F%40%40download%2FENCFF965BPU.hic":"42717376107,54779","www.encodeproject.org%2Ffiles%2FENCFF842DUO%2F%40%40download%2FENCFF842DUO.hic":"39553892515,54779","www.encodeproject.org%2Ffiles%2FENCFF417GBZ%2F%40%40download%2FENCFF417GBZ.hic":"45544785452,54779","www.encodeproject.org%2Ffiles%2FENCFF499BVX%2F%40%40download%2FENCFF499BVX.hic":"40900674170,54779","www.encodeproject.org%2Ffiles%2FENCFF136XCV%2F%40%40download%2FENCFF136XCV.hic":"47700392974,54779","www.encodeproject.org%2Ffiles%2FENCFF224HKR%2F%40%40download%2FENCFF224HKR.hic":"40426005932,54779","www.encodeproject.org%2Ffiles%2FENCFF711XSR%2F%40%40download%2FENCFF711XSR.hic":"41434581949,54779","www.encodeproject.org%2Ffiles%2FENCFF660JWA%2F%40%40download%2FENCFF660JWA.hic":"54201632697,54779","www.encodeproject.org%2Ffiles%2FENCFF081PMO%2F%40%40download%2FENCFF081PMO.hic":"53428285130,54779","www.encodeproject.org%2Ffiles%2FENCFF799QGA%2F%40%40download%2FENCFF799QGA.hic":"1228682189,36479","www.encodeproject.org%2Ffiles%2FENCFF473CAA%2F%40%40download%2FENCFF473CAA.hic":"1077514950,36479","www.encodeproject.org%2Ffiles%2FENCFF663FRL%2F%40%40download%2FENCFF663FRL.hic":"39843938245,54779","www.encodeproject.org%2Ffiles%2FENCFF341WOY%2F%40%40download%2FENCFF341WOY.hic":"34792598619,54779","www.encodeproject.org%2Ffiles%2FENCFF515ZBF%2F%40%40download%2FENCFF515ZBF.hic":"41779230923,54779","www.encodeproject.org%2Ffiles%2FENCFF545GBW%2F%40%40download%2FENCFF545GBW.hic":"38351980358,54779","www.encodeproject.org%2Ffiles%2FENCFF252ANV%2F%40%40download%2FENCFF252ANV.hic":"37668839771,54779","www.encodeproject.org%2Ffiles%2FENCFF912NDK%2F%40%40download%2FENCFF912NDK.hic":"21196851956,54779","www.encodeproject.org%2Ffiles%2FENCFF683PLM%2F%40%40download%2FENCFF683PLM.hic":"21849338763,54779","www.encodeproject.org%2Ffiles%2FENCFF355NFJ%2F%40%40download%2FENCFF355NFJ.hic":"47880627268,54779","www.encodeproject.org%2Ffiles%2FENCFF507WEW%2F%40%40download%2FENCFF507WEW.hic":"35777782924,54779","www.encodeproject.org%2Ffiles%2FENCFF241MSL%2F%40%40download%2FENCFF241MSL.hic":"22507408288,54779","www.encodeproject.org%2Ffiles%2FENCFF135MUT%2F%40%40download%2FENCFF135MUT.hic":"24168734040,54779","www.encodeproject.org%2Ffiles%2FENCFF459FRB%2F%40%40download%2FENCFF459FRB.hic":"37166770103,54779","www.encodeproject.org%2Ffiles%2FENCFF705YZH%2F%40%40download%2FENCFF705YZH.hic":"44679182442,54779","www.encodeproject.org%2Ffiles%2FENCFF395INO%2F%40%40download%2FENCFF395INO.hic":"56727346538,54779","www.encodeproject.org%2Ffiles%2FENCFF736ITL%2F%40%40download%2FENCFF736ITL.hic":"49036286185,54779","www.encodeproject.org%2Ffiles%2FENCFF546TZN%2F%40%40download%2FENCFF546TZN.hic":"33195126348,54779","www.encodeproject.org%2Ffiles%2FENCFF706SFK%2F%40%40download%2FENCFF706SFK.hic":"3271831702,36479","www.encodeproject.org%2Ffiles%2FENCFF922ERE%2F%40%40download%2FENCFF922ERE.hic":"12476647122,36479","www.encodeproject.org%2Ffiles%2FENCFF876OWE%2F%40%40download%2FENCFF876OWE.hic":"1538692704,47429","www.encodeproject.org%2Ffiles%2FENCFF227XJZ%2F%40%40download%2FENCFF227XJZ.hic":"1925617685,36479","www.encodeproject.org%2Ffiles%2FENCFF053BXY%2F%40%40download%2FENCFF053BXY.hic":"1032237652,36479","www.encodeproject.org%2Ffiles%2FENCFF014VMM%2F%40%40download%2FENCFF014VMM.hic":"1564021703,36479","www.encodeproject.org%2Ffiles%2FENCFF563XES%2F%40%40download%2FENCFF563XES.hic":"1489180508,36479","www.encodeproject.org%2Ffiles%2FENCFF482LGO%2F%40%40download%2FENCFF482LGO.hic":"1208778887,36479","www.encodeproject.org%2Ffiles%2FENCFF216QQM%2F%40%40download%2FENCFF216QQM.hic":"6293163571,47429","www.encodeproject.org%2Ffiles%2FENCFF256UOW%2F%40%40download%2FENCFF256UOW.hic":"6293163571,47429","www.encodeproject.org%2Ffiles%2FENCFF791UZC%2F%40%40download%2FENCFF791UZC.hic":"37029615181,54779","www.encodeproject.org%2Ffiles%2FENCFF911AHQ%2F%40%40download%2FENCFF911AHQ.hic":"34246649165,54779","www.encodeproject.org%2Ffiles%2FENCFF491AOR%2F%40%40download%2FENCFF491AOR.hic":"558663570,36479","www.encodeproject.org%2Ffiles%2FENCFF307PDL%2F%40%40download%2FENCFF307PDL.hic":"525321519,36479","www.encodeproject.org%2Ffiles%2FENCFF773ITV%2F%40%40download%2FENCFF773ITV.hic":"295464771,36479","www.encodeproject.org%2Ffiles%2FENCFF198SSL%2F%40%40download%2FENCFF198SSL.hic":"500142476,36479","www.encodeproject.org%2Ffiles%2FENCFF251UEF%2F%40%40download%2FENCFF251UEF.hic":"567443575,36479","www.encodeproject.org%2Ffiles%2FENCFF942LTN%2F%40%40download%2FENCFF942LTN.hic":"4430960222,36479","www.encodeproject.org%2Ffiles%2FENCFF543USQ%2F%40%40download%2FENCFF543USQ.hic":"5005263062,36479","www.encodeproject.org%2Ffiles%2FENCFF434XQU%2F%40%40download%2FENCFF434XQU.hic":"25506511674,54779","www.encodeproject.org%2Ffiles%2FENCFF318GOM%2F%40%40download%2FENCFF318GOM.hic":"44750824314,54779","www.encodeproject.org%2Ffiles%2FENCFF004TKY%2F%40%40download%2FENCFF004TKY.hic":"20705661833,54779","www.encodeproject.org%2Ffiles%2FENCFF493YNC%2F%40%40download%2FENCFF493YNC.hic":"53407154984,54779","www.encodeproject.org%2Ffiles%2FENCFF334XXU%2F%40%40download%2FENCFF334XXU.hic":"14341194962,47429","www.encodeproject.org%2Ffiles%2FENCFF569RJM%2F%40%40download%2FENCFF569RJM.hic":"1922066634,36479","www.encodeproject.org%2Ffiles%2FENCFF076LWH%2F%40%40download%2FENCFF076LWH.hic":"39406255845,54779","www.encodeproject.org%2Ffiles%2FENCFF977XWK%2F%40%40download%2FENCFF977XWK.hic":"20563512962,54779","www.encodeproject.org%2Ffiles%2FENCFF127TPS%2F%40%40download%2FENCFF127TPS.hic":"21032070512,54779","www.encodeproject.org%2Ffiles%2FENCFF480KLP%2F%40%40download%2FENCFF480KLP.hic":"33115569647,54779","www.encodeproject.org%2Ffiles%2FENCFF281ILS%2F%40%40download%2FENCFF281ILS.hic":"28236353584,54779","www.encodeproject.org%2Ffiles%2FENCFF129LMU%2F%40%40download%2FENCFF129LMU.hic":"35247096013,54779","www.encodeproject.org%2Ffiles%2FENCFF759YCW%2F%40%40download%2FENCFF759YCW.hic":"16058537743,32102","www.encodeproject.org%2Ffiles%2FENCFF045YOM%2F%40%40download%2FENCFF045YOM.hic":"19775445828,32102","www.encodeproject.org%2Ffiles%2FENCFF013TGD%2F%40%40download%2FENCFF013TGD.hic":"4208420532,36479","www.encodeproject.org%2Ffiles%2FENCFF929RPW%2F%40%40download%2FENCFF929RPW.hic":"1974260276,36479","www.encodeproject.org%2Ffiles%2FENCFF996XEO%2F%40%40download%2FENCFF996XEO.hic":"2072918865,36479","www.encodeproject.org%2Ffiles%2FENCFF097SKJ%2F%40%40download%2FENCFF097SKJ.hic":"1983524001,36479","www.encodeproject.org%2Ffiles%2FENCFF464KRA%2F%40%40download%2FENCFF464KRA.hic":"1957300131,36479","www.encodeproject.org%2Ffiles%2FENCFF406HHC%2F%40%40download%2FENCFF406HHC.hic":"3854527235,36479","www.encodeproject.org%2Ffiles%2FENCFF080DPJ%2F%40%40download%2FENCFF080DPJ.hic":"19953768024,47429","www.encodeproject.org%2Ffiles%2FENCFF621AIY%2F%40%40download%2FENCFF621AIY.hic":"26781700010,54779","www.encodeproject.org%2Ffiles%2FENCFF366ERB%2F%40%40download%2FENCFF366ERB.hic":"1049184239,36479","www.encodeproject.org%2Ffiles%2FENCFF997RGL%2F%40%40download%2FENCFF997RGL.hic":"2521167549,36479","www.encodeproject.org%2Ffiles%2FENCFF029MPB%2F%40%40download%2FENCFF029MPB.hic":"1854711185,36479","www.encodeproject.org%2Ffiles%2FENCFF043EEE%2F%40%40download%2FENCFF043EEE.hic":"2924133032,36479","www.encodeproject.org%2Ffiles%2FENCFF920CJR%2F%40%40download%2FENCFF920CJR.hic":"3011577886,36479","www.encodeproject.org%2Ffiles%2FENCFF928NJV%2F%40%40download%2FENCFF928NJV.hic":"2778936244,36479","www.encodeproject.org%2Ffiles%2FENCFF894GLR%2F%40%40download%2FENCFF894GLR.hic":"2831733099,36479","www.encodeproject.org%2Ffiles%2FENCFF303PCK%2F%40%40download%2FENCFF303PCK.hic":"688704435,36479","www.encodeproject.org%2Ffiles%2FENCFF999YXX%2F%40%40download%2FENCFF999YXX.hic":"9255069996,56883","www.encodeproject.org%2Ffiles%2FENCFF685BLG%2F%40%40download%2FENCFF685BLG.hic":"16797022992,47429","www.encodeproject.org%2Ffiles%2FENCFF188SSH%2F%40%40download%2FENCFF188SSH.hic":"16797023050,47429","www.encodeproject.org%2Ffiles%2FENCFF465ESX%2F%40%40download%2FENCFF465ESX.hic":"13489465953,32102","www.encodeproject.org%2Ffiles%2FENCFF493SFI%2F%40%40download%2FENCFF493SFI.hic":"30033046818,54779","www.encodeproject.org%2Ffiles%2FENCFF235LCO%2F%40%40download%2FENCFF235LCO.hic":"38572174589,54779","www.encodeproject.org%2Ffiles%2FENCFF625VNK%2F%40%40download%2FENCFF625VNK.hic":"45202258438,54779","www.encodeproject.org%2Ffiles%2FENCFF304HMS%2F%40%40download%2FENCFF304HMS.hic":"36994445315,54779","www.encodeproject.org%2Ffiles%2FENCFF605CEN%2F%40%40download%2FENCFF605CEN.hic":"40358346301,54779","www.encodeproject.org%2Ffiles%2FENCFF086ORS%2F%40%40download%2FENCFF086ORS.hic":"22650781304,54779","www.encodeproject.org%2Ffiles%2FENCFF237UKR%2F%40%40download%2FENCFF237UKR.hic":"41516707246,54779","www.encodeproject.org%2Ffiles%2FENCFF004YZQ%2F%40%40download%2FENCFF004YZQ.hic":"71900665326,54779","www.encodeproject.org%2Ffiles%2FENCFF104THR%2F%40%40download%2FENCFF104THR.hic":"15172410632,54779","www.encodeproject.org%2Ffiles%2FENCFF807IRK%2F%40%40download%2FENCFF807IRK.hic":"17346637451,54779","www.encodeproject.org%2Ffiles%2FENCFF193CQL%2F%40%40download%2FENCFF193CQL.hic":"55726903245,54779","www.encodeproject.org%2Ffiles%2FENCFF700DEX%2F%40%40download%2FENCFF700DEX.hic":"20231399798,54779","www.encodeproject.org%2Ffiles%2FENCFF234MDO%2F%40%40download%2FENCFF234MDO.hic":"24635312640,54779","www.encodeproject.org%2Ffiles%2FENCFF181ROW%2F%40%40download%2FENCFF181ROW.hic":"26883606497,54779","www.encodeproject.org%2Ffiles%2FENCFF896OFN%2F%40%40download%2FENCFF896OFN.hic":"36952196833,54779","www.encodeproject.org%2Ffiles%2FENCFF573OPJ%2F%40%40download%2FENCFF573OPJ.hic":"36685546919,54779","www.encodeproject.org%2Ffiles%2FENCFF028RXH%2F%40%40download%2FENCFF028RXH.hic":"31053919206,54779","www.encodeproject.org%2Ffiles%2FENCFF156GGD%2F%40%40download%2FENCFF156GGD.hic":"35284134289,54779","www.encodeproject.org%2Ffiles%2FENCFF496GEU%2F%40%40download%2FENCFF496GEU.hic":"44659660933,54779","www.encodeproject.org%2Ffiles%2FENCFF945TUH%2F%40%40download%2FENCFF945TUH.hic":"3898570191,35639","www.encodeproject.org%2Ffiles%2FENCFF698KFV%2F%40%40download%2FENCFF698KFV.hic":"4427896684,35751","www.encodeproject.org%2Ffiles%2FENCFF239BHZ%2F%40%40download%2FENCFF239BHZ.hic":"1718552021,36479","www.encodeproject.org%2Ffiles%2FENCFF277LAN%2F%40%40download%2FENCFF277LAN.hic":"4542391336,36479","www.encodeproject.org%2Ffiles%2FENCFF397CMD%2F%40%40download%2FENCFF397CMD.hic":"2832016430,36479","www.encodeproject.org%2Ffiles%2FENCFF778OYA%2F%40%40download%2FENCFF778OYA.hic":"14067187484,47429","www.encodeproject.org%2Ffiles%2FENCFF775VSU%2F%40%40download%2FENCFF775VSU.hic":"14067187484,47429","www.encodeproject.org%2Ffiles%2FENCFF812THZ%2F%40%40download%2FENCFF812THZ.hic":"9667720429,36479","www.encodeproject.org%2Ffiles%2FENCFF777KBU%2F%40%40download%2FENCFF777KBU.hic":"5058284320,36479","www.encodeproject.org%2Ffiles%2FENCFF688KOY%2F%40%40download%2FENCFF688KOY.hic":"4198695833,36479","www.encodeproject.org%2Ffiles%2FENCFF223UBX%2F%40%40download%2FENCFF223UBX.hic":"1206064037,36479","www.encodeproject.org%2Ffiles%2FENCFF273XBU%2F%40%40download%2FENCFF273XBU.hic":"44085607579,54779","www.encodeproject.org%2Ffiles%2FENCFF952JZV%2F%40%40download%2FENCFF952JZV.hic":"44728845246,54779","www.encodeproject.org%2Ffiles%2FENCFF643NDM%2F%40%40download%2FENCFF643NDM.hic":"35877886780,54779","www.encodeproject.org%2Ffiles%2FENCFF586MQY%2F%40%40download%2FENCFF586MQY.hic":"71158037547,54779","www.encodeproject.org%2Ffiles%2FENCFF251VFA%2F%40%40download%2FENCFF251VFA.hic":"40089479399,54779","www.encodeproject.org%2Ffiles%2FENCFF033WGK%2F%40%40download%2FENCFF033WGK.hic":"30802023728,54779","www.encodeproject.org%2Ffiles%2FENCFF649OHR%2F%40%40download%2FENCFF649OHR.hic":"28203184265,54779","www.encodeproject.org%2Ffiles%2FENCFF782WVZ%2F%40%40download%2FENCFF782WVZ.hic":"37248221674,54779","www.encodeproject.org%2Ffiles%2FENCFF579CAR%2F%40%40download%2FENCFF579CAR.hic":"39662025395,54779","www.encodeproject.org%2Ffiles%2FENCFF514XWQ%2F%40%40download%2FENCFF514XWQ.hic":"1319613701,36479","www.encodeproject.org%2Ffiles%2FENCFF666USK%2F%40%40download%2FENCFF666USK.hic":"15051670107,32102","www.encodeproject.org%2Ffiles%2FENCFF047SDP%2F%40%40download%2FENCFF047SDP.hic":"1357076705,16438","www.encodeproject.org%2Ffiles%2FENCFF584LEP%2F%40%40download%2FENCFF584LEP.hic":"9314176858,36479","www.encodeproject.org%2Ffiles%2FENCFF671SOE%2F%40%40download%2FENCFF671SOE.hic":"3273732256,16438","www.encodeproject.org%2Ffiles%2FENCFF702LAP%2F%40%40download%2FENCFF702LAP.hic":"1800427500,31682","www.encodeproject.org%2Ffiles%2FENCFF339PON%2F%40%40download%2FENCFF339PON.hic":"5394351199,31514","www.encodeproject.org%2Ffiles%2FENCFF741QPR%2F%40%40download%2FENCFF741QPR.hic":"4271510019,30139","www.encodeproject.org%2Ffiles%2FENCFF103ANX%2F%40%40download%2FENCFF103ANX.hic":"4439745804,30083","www.encodeproject.org%2Ffiles%2FENCFF395SBC%2F%40%40download%2FENCFF395SBC.hic":"1596732351,31850","www.encodeproject.org%2Ffiles%2FENCFF289WNN%2F%40%40download%2FENCFF289WNN.hic":"8632980535,32102","www.encodeproject.org%2Ffiles%2FENCFF381EAU%2F%40%40download%2FENCFF381EAU.hic":"1702476311,36479","www.encodeproject.org%2Ffiles%2FENCFF976FEY%2F%40%40download%2FENCFF976FEY.hic":"1448279040,36479","www.encodeproject.org%2Ffiles%2FENCFF485LVS%2F%40%40download%2FENCFF485LVS.hic":"1593610856,36479","www.encodeproject.org%2Ffiles%2FENCFF143VJV%2F%40%40download%2FENCFF143VJV.hic":"1422312076,36479","www.encodeproject.org%2Ffiles%2FENCFF588NHX%2F%40%40download%2FENCFF588NHX.hic":"3943637009,36479","www.encodeproject.org%2Ffiles%2FENCFF768UBD%2F%40%40download%2FENCFF768UBD.hic":"24786676166,36479","www.encodeproject.org%2Ffiles%2FENCFF965PEE%2F%40%40download%2FENCFF965PEE.hic":"29387092778,47429","www.encodeproject.org%2Ffiles%2FENCFF702IFC%2F%40%40download%2FENCFF702IFC.hic":"29387092778,47429","www.encodeproject.org%2Ffiles%2FENCFF288DNV%2F%40%40download%2FENCFF288DNV.hic":"10313429504,36479","www.encodeproject.org%2Ffiles%2FENCFF698HWZ%2F%40%40download%2FENCFF698HWZ.hic":"10962849269,47429","www.encodeproject.org%2Ffiles%2FENCFF355OWW%2F%40%40download%2FENCFF355OWW.hic":"3219571601,36479","www.encodeproject.org%2Ffiles%2FENCFF177TYX%2F%40%40download%2FENCFF177TYX.hic":"10325679706,36479","www.encodeproject.org%2Ffiles%2FENCFF542BHD%2F%40%40download%2FENCFF542BHD.hic":"11085397879,47429","www.encodeproject.org%2Ffiles%2FENCFF684IFW%2F%40%40download%2FENCFF684IFW.hic":"11085397879,47429","www.encodeproject.org%2Ffiles%2FENCFF592UHE%2F%40%40download%2FENCFF592UHE.hic":"21363948089,32102","www.encodeproject.org%2Ffiles%2FENCFF779XIS%2F%40%40download%2FENCFF779XIS.hic":"9517383271,36479","www.encodeproject.org%2Ffiles%2FENCFF518PSL%2F%40%40download%2FENCFF518PSL.hic":"7500581463,36479","www.encodeproject.org%2Ffiles%2FENCFF275GBB%2F%40%40download%2FENCFF275GBB.hic":"7889407162,36479","www.encodeproject.org%2Ffiles%2FENCFF634KXI%2F%40%40download%2FENCFF634KXI.hic":"6430702966,36479","www.encodeproject.org%2Ffiles%2FENCFF337QPM%2F%40%40download%2FENCFF337QPM.hic":"8529733887,36479","www.encodeproject.org%2Ffiles%2FENCFF162KMP%2F%40%40download%2FENCFF162KMP.hic":"5615896908,36479","www.encodeproject.org%2Ffiles%2FENCFF992VTE%2F%40%40download%2FENCFF992VTE.hic":"7328975027,36479","www.encodeproject.org%2Ffiles%2FENCFF464WXY%2F%40%40download%2FENCFF464WXY.hic":"5715339664,36479","www.encodeproject.org%2Ffiles%2FENCFF752EGH%2F%40%40download%2FENCFF752EGH.hic":"1733758743,36479","www.encodeproject.org%2Ffiles%2FENCFF474UJM%2F%40%40download%2FENCFF474UJM.hic":"222309548,18679","www.encodeproject.org%2Ffiles%2FENCFF531UPZ%2F%40%40download%2FENCFF531UPZ.hic":"1827756846,36479","www.encodeproject.org%2Ffiles%2FENCFF022VHA%2F%40%40download%2FENCFF022VHA.hic":"244983451,18679","www.encodeproject.org%2Ffiles%2FENCFF732NGR%2F%40%40download%2FENCFF732NGR.hic":"1679484567,36479","www.encodeproject.org%2Ffiles%2FENCFF513VSF%2F%40%40download%2FENCFF513VSF.hic":"28397932940,36479","www.encodeproject.org%2Ffiles%2FENCFF750AOC%2F%40%40download%2FENCFF750AOC.hic":"36471430712,47429","www.encodeproject.org%2Ffiles%2FENCFF219YOB%2F%40%40download%2FENCFF219YOB.hic":"2859767211,26979","www.encodeproject.org%2Ffiles%2FENCFF604YDD%2F%40%40download%2FENCFF604YDD.hic":"3549694085,26979","www.encodeproject.org%2Ffiles%2FENCFF746AMV%2F%40%40download%2FENCFF746AMV.hic":"2954867135,26979","www.encodeproject.org%2Ffiles%2FENCFF845ZEB%2F%40%40download%2FENCFF845ZEB.hic":"2763039282,26979","www.encodeproject.org%2Ffiles%2FENCFF570LWS%2F%40%40download%2FENCFF570LWS.hic":"2861588289,26979","www.encodeproject.org%2Ffiles%2FENCFF883YVR%2F%40%40download%2FENCFF883YVR.hic":"2433679887,26979","www.encodeproject.org%2Ffiles%2FENCFF056VLK%2F%40%40download%2FENCFF056VLK.hic":"2502986910,26979","www.encodeproject.org%2Ffiles%2FENCFF532DUQ%2F%40%40download%2FENCFF532DUQ.hic":"3172615899,26979","www.encodeproject.org%2Ffiles%2FENCFF723PYJ%2F%40%40download%2FENCFF723PYJ.hic":"10292839095,36479","www.encodeproject.org%2Ffiles%2FENCFF991SGJ%2F%40%40download%2FENCFF991SGJ.hic":"13072407683,32102","www.encodeproject.org%2Ffiles%2FENCFF885UZI%2F%40%40download%2FENCFF885UZI.hic":"1201881201,16438","www.encodeproject.org%2Ffiles%2FENCFF287KXA%2F%40%40download%2FENCFF287KXA.hic":"14705801988,32102","www.encodeproject.org%2Ffiles%2FENCFF335HYI%2F%40%40download%2FENCFF335HYI.hic":"20366756545,32102","www.encodeproject.org%2Ffiles%2FENCFF121YPY%2F%40%40download%2FENCFF121YPY.hic":"2760104016,26979","www.encodeproject.org%2Ffiles%2FENCFF675SJE%2F%40%40download%2FENCFF675SJE.hic":"3751779995,26979","www.encodeproject.org%2Ffiles%2FENCFF876LAW%2F%40%40download%2FENCFF876LAW.hic":"4032376256,26979","www.encodeproject.org%2Ffiles%2FENCFF740KVX%2F%40%40download%2FENCFF740KVX.hic":"3202490322,26979","www.encodeproject.org%2Ffiles%2FENCFF977OQV%2F%40%40download%2FENCFF977OQV.hic":"2919735477,26979","www.encodeproject.org%2Ffiles%2FENCFF525EFN%2F%40%40download%2FENCFF525EFN.hic":"2394748073,26979","www.encodeproject.org%2Ffiles%2FENCFF690QRC%2F%40%40download%2FENCFF690QRC.hic":"3183023394,26979","www.encodeproject.org%2Ffiles%2FENCFF452FWS%2F%40%40download%2FENCFF452FWS.hic":"2951805127,26979","www.encodeproject.org%2Ffiles%2FENCFF089KBG%2F%40%40download%2FENCFF089KBG.hic":"2531936700,26979","www.encodeproject.org%2Ffiles%2FENCFF939ARM%2F%40%40download%2FENCFF939ARM.hic":"3066385212,26979","www.encodeproject.org%2Ffiles%2FENCFF401ZAN%2F%40%40download%2FENCFF401ZAN.hic":"3008677144,26979","www.encodeproject.org%2Ffiles%2FENCFF378RZT%2F%40%40download%2FENCFF378RZT.hic":"2830232168,26979","www.encodeproject.org%2Ffiles%2FENCFF304AVD%2F%40%40download%2FENCFF304AVD.hic":"6164439305,50358","www.encodeproject.org%2Ffiles%2FENCFF453DBX%2F%40%40download%2FENCFF453DBX.hic":"6775246670,36479","www.encodeproject.org%2Ffiles%2FENCFF590VOM%2F%40%40download%2FENCFF590VOM.hic":"6443478922,36479","www.encodeproject.org%2Ffiles%2FENCFF246DOF%2F%40%40download%2FENCFF246DOF.hic":"6837914659,36479","www.encodeproject.org%2Ffiles%2FENCFF125FXX%2F%40%40download%2FENCFF125FXX.hic":"9736232550,36479","www.encodeproject.org%2Ffiles%2FENCFF241RAY%2F%40%40download%2FENCFF241RAY.hic":"7686758397,36479","www.encodeproject.org%2Ffiles%2FENCFF415XWQ%2F%40%40download%2FENCFF415XWQ.hic":"6973092068,36479","www.encodeproject.org%2Ffiles%2FENCFF374EBH%2F%40%40download%2FENCFF374EBH.hic":"8557459058,36479","www.encodeproject.org%2Ffiles%2FENCFF263YWR%2F%40%40download%2FENCFF263YWR.hic":"331586820,18679","www.encodeproject.org%2Ffiles%2FENCFF280CGS%2F%40%40download%2FENCFF280CGS.hic":"1743569614,36479","www.encodeproject.org%2Ffiles%2FENCFF553ZNS%2F%40%40download%2FENCFF553ZNS.hic":"1717253636,36479","www.encodeproject.org%2Ffiles%2FENCFF451VOI%2F%40%40download%2FENCFF451VOI.hic":"1626927468,36479","www.encodeproject.org%2Ffiles%2FENCFF420MQO%2F%40%40download%2FENCFF420MQO.hic":"31055961677,36479","www.encodeproject.org%2Ffiles%2FENCFF301BWY%2F%40%40download%2FENCFF301BWY.hic":"38902429246,47429","www.encodeproject.org%2Ffiles%2FENCFF606XNW%2F%40%40download%2FENCFF606XNW.hic":"1009699327,36479","www.encodeproject.org%2Ffiles%2FENCFF439ZOU%2F%40%40download%2FENCFF439ZOU.hic":"12381714313,36479","www.encodeproject.org%2Ffiles%2FENCFF499SYK%2F%40%40download%2FENCFF499SYK.hic":"13182654663,47429","www.encodeproject.org%2Ffiles%2FENCFF532LFI%2F%40%40download%2FENCFF532LFI.hic":"8286030286,36479","www.encodeproject.org%2Ffiles%2FENCFF020DPP%2F%40%40download%2FENCFF020DPP.hic":"23521952420,47429","www.encodeproject.org%2Ffiles%2FENCFF306VTV%2F%40%40download%2FENCFF306VTV.hic":"23521952480,47429","www.encodeproject.org%2Ffiles%2FENCFF399IHE%2F%40%40download%2FENCFF399IHE.hic":"10216571232,36479","www.encodeproject.org%2Ffiles%2FENCFF944AII%2F%40%40download%2FENCFF944AII.hic":"12567308552,47429","www.encodeproject.org%2Ffiles%2FENCFF230HVV%2F%40%40download%2FENCFF230HVV.hic":"8629849711,36479","www.encodeproject.org%2Ffiles%2FENCFF174LAF%2F%40%40download%2FENCFF174LAF.hic":"9446506633,47429","www.encodeproject.org%2Ffiles%2FENCFF898HRO%2F%40%40download%2FENCFF898HRO.hic":"9446506633,47429","www.encodeproject.org%2Ffiles%2FENCFF429MOR%2F%40%40download%2FENCFF429MOR.hic":"1455757398,36479","www.encodeproject.org%2Ffiles%2FENCFF061NXV%2F%40%40download%2FENCFF061NXV.hic":"1710915891,36479","www.encodeproject.org%2Ffiles%2FENCFF434PYS%2F%40%40download%2FENCFF434PYS.hic":"1832274903,36479","www.encodeproject.org%2Ffiles%2FENCFF704HHX%2F%40%40download%2FENCFF704HHX.hic":"1768142834,36479","www.encodeproject.org%2Ffiles%2FENCFF349DPM%2F%40%40download%2FENCFF349DPM.hic":"4316041260,36479","www.encodeproject.org%2Ffiles%2FENCFF718AWL%2F%40%40download%2FENCFF718AWL.hic":"39544267907,58932","www.encodeproject.org%2Ffiles%2FENCFF065LSP%2F%40%40download%2FENCFF065LSP.hic":"24929805283,55874","www.encodeproject.org%2Ffiles%2FENCFF632MFV%2F%40%40download%2FENCFF632MFV.hic":"22333105467,55798","www.encodeproject.org%2Ffiles%2FENCFF179HVU%2F%40%40download%2FENCFF179HVU.hic":"2659219603,36479","www.encodeproject.org%2Ffiles%2FENCFF791SPZ%2F%40%40download%2FENCFF791SPZ.hic":"2537491657,36479","www.encodeproject.org%2Ffiles%2FENCFF211ZWF%2F%40%40download%2FENCFF211ZWF.hic":"3512141227,36479","www.encodeproject.org%2Ffiles%2FENCFF614BNU%2F%40%40download%2FENCFF614BNU.hic":"5252155462,36479","www.encodeproject.org%2Ffiles%2FENCFF891DLM%2F%40%40download%2FENCFF891DLM.hic":"2549095612,36479","www.encodeproject.org%2Ffiles%2FENCFF056EXT%2F%40%40download%2FENCFF056EXT.hic":"2219014704,36479","www.encodeproject.org%2Ffiles%2FENCFF776DSS%2F%40%40download%2FENCFF776DSS.hic":"3920308353,36479","www.encodeproject.org%2Ffiles%2FENCFF814LQF%2F%40%40download%2FENCFF814LQF.hic":"1349480197,36479","www.encodeproject.org%2Ffiles%2FENCFF513ZNA%2F%40%40download%2FENCFF513ZNA.hic":"2638868195,36479","www.encodeproject.org%2Ffiles%2FENCFF692IOL%2F%40%40download%2FENCFF692IOL.hic":"3106768498,36479","www.encodeproject.org%2Ffiles%2FENCFF294WZY%2F%40%40download%2FENCFF294WZY.hic":"2211089761,36479","www.encodeproject.org%2Ffiles%2FENCFF339UWS%2F%40%40download%2FENCFF339UWS.hic":"2142759055,36479","www.encodeproject.org%2Ffiles%2FENCFF835FSK%2F%40%40download%2FENCFF835FSK.hic":"3919821739,36479","www.encodeproject.org%2Ffiles%2FENCFF328BMB%2F%40%40download%2FENCFF328BMB.hic":"2550686152,36479","www.encodeproject.org%2Ffiles%2FENCFF897RTY%2F%40%40download%2FENCFF897RTY.hic":"1323294397,36479","www.encodeproject.org%2Ffiles%2FENCFF306MWH%2F%40%40download%2FENCFF306MWH.hic":"1665386199,36479","www.encodeproject.org%2Ffiles%2FENCFF039YUJ%2F%40%40download%2FENCFF039YUJ.hic":"2335679939,36479","www.encodeproject.org%2Ffiles%2FENCFF468QIN%2F%40%40download%2FENCFF468QIN.hic":"3352516594,36479","www.encodeproject.org%2Ffiles%2FENCFF364WXU%2F%40%40download%2FENCFF364WXU.hic":"3959043175,36479","www.encodeproject.org%2Ffiles%2FENCFF373MSH%2F%40%40download%2FENCFF373MSH.hic":"4429550624,36479","www.encodeproject.org%2Ffiles%2FENCFF959EGQ%2F%40%40download%2FENCFF959EGQ.hic":"2475218228,36479","www.encodeproject.org%2Ffiles%2FENCFF624XMK%2F%40%40download%2FENCFF624XMK.hic":"3527855681,36479","www.encodeproject.org%2Ffiles%2FENCFF445OKS%2F%40%40download%2FENCFF445OKS.hic":"3369125589,36479","www.encodeproject.org%2Ffiles%2FENCFF239QDV%2F%40%40download%2FENCFF239QDV.hic":"1960069888,36479","www.encodeproject.org%2Ffiles%2FENCFF645AVM%2F%40%40download%2FENCFF645AVM.hic":"4969006589,36479","www.encodeproject.org%2Ffiles%2FENCFF494IPI%2F%40%40download%2FENCFF494IPI.hic":"1565483792,36479","www.encodeproject.org%2Ffiles%2FENCFF753IXE%2F%40%40download%2FENCFF753IXE.hic":"2892400648,36479","www.encodeproject.org%2Ffiles%2FENCFF731GXX%2F%40%40download%2FENCFF731GXX.hic":"5131381303,36479","www.encodeproject.org%2Ffiles%2FENCFF369CAQ%2F%40%40download%2FENCFF369CAQ.hic":"4236629448,36479","www.encodeproject.org%2Ffiles%2FENCFF053VBX%2F%40%40download%2FENCFF053VBX.hic":"54305946375,47429","www.encodeproject.org%2Ffiles%2FENCFF555ISR%2F%40%40download%2FENCFF555ISR.hic":"54305946434,47429","www.encodeproject.org%2Ffiles%2FENCFF964RSP%2F%40%40download%2FENCFF964RSP.hic":"12065485229,36479","www.encodeproject.org%2Ffiles%2FENCFF234MZQ%2F%40%40download%2FENCFF234MZQ.hic":"17507142760,47429","www.encodeproject.org%2Ffiles%2FENCFF994CEG%2F%40%40download%2FENCFF994CEG.hic":"17507142760,47429","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fb068e787-bbdd-49e2-9f6d-7a0e9f065d6e%2F4DNFIHSUIRFY.hic":"2701182442,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3768b89a-e124-40eb-8acd-94a4fdd35807%2F4DNFIXTAS6EE.hic":"3283740601,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F9c513602-5abb-4088-8415-c827c381ab0d%2F4DNFIC3JD6O2.hic":"4896075767,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fde954dad-1849-4c23-beb4-bf893b7d76c9%2F4DNFIGY85S4W.hic":"3364151996,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fe1befa6e-8067-4296-8db2-67d2a2458985%2F4DNFI2LTNXME.hic":"3699291418,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fbb3307fd-7162-477a-87c5-52f12d03befc%2F4DNFID162B9J.hic":"3576428773,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8597cdae-8319-42d9-9175-3f77aaee34e1%2F4DNFIQWS3632.hic":"4022561190,22663","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F327f091d-6a63-47c4-9752-2dff303a13d9%2F4DNFI6GFHB6G.hic":"4239331168,22663","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd70dc3b8-48a7-42c2-bd23-80bc44fc2266%2F4DNFIS5F6EBL.hic":"4404671861,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F77df7bf8-6a3d-407a-8968-4ca1e78d2269%2F4DNFIF2D3TL9.hic":"4793989394,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc8f7cc35-d2ef-4717-9009-c02154050fbf%2F4DNFI6EIFUZI.hic":"3370273763,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F98449d79-30d1-4e32-801d-07435819a42f%2F4DNFIRKGMZRQ.hic":"4669813207,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd4fe1844-2493-4722-8b98-34a93a4bb7d8%2F4DNFIQWD8ZYD.hic":"5379889057,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F1ee40499-1de4-47ff-b540-d9a65943c6b8%2F4DNFIX7H3CE2.hic":"4857679239,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fac016170-23a7-4111-8773-353d6c150f34%2F4DNFIO21YDCV.hic":"4695989644,22663","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F1faea4e7-9a32-466e-a826-0bfdab6cd915%2F4DNFIUE5RAS6.hic":"4788044799,22663","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fcbd396ed-11bb-404f-aed9-ef10abc258e6%2F4DNFIFI6NIKJ.hic":"2069414927,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Faf3f78db-ae92-4215-bcae-76d30c617e5d%2F4DNFIL5K3MA1.hic":"2585598247,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F66fc2893-224e-48b4-bdb0-25e022dedd03%2F4DNFIPV5KFMK.hic":"2060965679,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F2b39781d-aadc-434f-abe3-562d61308fdd%2F4DNFIW8TIFI5.hic":"1694424195,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fb6d28f7b-27d3-486f-b5ac-32567416560d%2F4DNFIA6NSSBJ.hic":"2219532611,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F08785616-722e-46bb-ade2-2fdd21324e11%2F4DNFIBKZK63V.hic":"2429136232,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F904b13d3-1203-42a4-812c-963e80c159b1%2F4DNFI3CFMRID.hic":"1233390166,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fb0ed4afe-5ecf-451d-bb1f-444697e3f558%2F4DNFIYIAUEPW.hic":"1753567534,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F4bb9a9b3-12a8-4d2f-8071-4722294c88ea%2F4DNFIC3HAU11.hic":"2271375254,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F5abf9c36-c1d1-44dc-8197-74d860d896c0%2F4DNFIM2BMJ33.hic":"1770471113,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fa68475db-7816-4cec-b2da-d4ce4a0c7a0e%2F4DNFIBY3UHJB.hic":"2095528423,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F07c40943-0d0b-4b3e-94a0-8583b0e00b47%2F4DNFIWZEN3FF.hic":"1558559508,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd8a39553-2718-4866-9b2a-45d8e9c5ac6f%2F4DNFIE5TEYK7.hic":"1323063102,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F294b61ef-5565-4f04-ade9-f921a6686cce%2F4DNFI7H4II2V.hic":"1436947982,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F87a70ad7-7d34-4302-9c03-eb824bd4e633%2F4DNFIAS8LV1C.hic":"1263105698,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F9db804c6-5a91-4cf5-8ae9-e054223afb77%2F4DNFIBXWIH8J.hic":"1587059951,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd1e55906-ec8f-444b-8ce1-2de22a431a76%2F4DNFIO2HBDAI.hic":"1666436393,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F7a4b9b37-8e38-470c-8190-fd4d513c0bbb%2F4DNFIXWCLD4M.hic":"1513511880,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F6c7615b2-5310-4bbf-a605-98761d3a3079%2F4DNFINASC4NQ.hic":"1420358914,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F20454014-49cd-4e2d-93da-f40ad52776d5%2F4DNFIZF1KI43.hic":"1377041630,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F5df04e86-ee2a-45f2-b878-bf1648e2cca5%2F4DNFIQBHR9XC.hic":"1179502734,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F9d1cc910-bb3f-4106-802a-73184c58d5ba%2F4DNFIQVMVRP6.hic":"1811976991,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fe431986b-0732-460f-92ff-0abd1694d2d0%2F4DNFIJ7OAIFQ.hic":"1685503856,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F56d0c575-4962-4ea3-92c3-55bd0e17c096%2F4DNFIE8E4ANZ.hic":"1598369564,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fdb1502fb-a989-4ef9-b800-7eaa7be172ae%2F4DNFIOUSETUP.hic":"1493294709,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Facc2f1c3-8c96-4d21-814a-3a8ba81e7741%2F4DNFIVJ3IIQL.hic":"1472376655,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F037fb4c3-8641-4953-a977-cc71f2137582%2F4DNFIHN2QSMX.hic":"1179632606,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F16d2c3c0-6d29-4815-b074-b142af90b615%2F4DNFIILDWK8M.hic":"2280059989,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F31789849-e4db-45d8-9730-66a048c02d8a%2F4DNFI6XD6JAQ.hic":"2253961696,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fff04947e-e6e8-4d62-8374-ef2ee4104809%2F4DNFIALNLR78.hic":"1914687914,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F53e6c1e7-9410-4158-84e6-57c2e683b095%2F4DNFIBT4EAKN.hic":"2296378356,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F0127900a-258f-4815-97d2-6fd2b043d853%2F4DNFIDJ2JZ7Q.hic":"2558945393,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F89f95693-3d28-44eb-9d45-14932f8e258c%2F4DNFI8JFOAJT.hic":"1726440253,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd803d818-b0d4-4796-8d61-a9f3943f3b10%2F4DNFIRZA6EV6.hic":"1805017504,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff9165fb1-0782-4757-a740-5b929e0252bb%2F4DNFIB7QTIMH.hic":"2541020707,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff8d916b2-b58e-4cdf-894c-ffcb3bf6ebd9%2F4DNFIJ5DQZVK.hic":"2445734043,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F14066a5b-e01a-43c2-a468-b18826174df3%2F4DNFISTWNV9C.hic":"2499319890,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd0692151-7f9a-4475-b059-f8802616dded%2F4DNFIBN9K4V9.hic":"1591570769,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F70a7ef36-a514-4e45-918f-47c4e9e30ef4%2F4DNFIR8OU6QJ.hic":"1689882108,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F180306cd-8593-413a-ae83-24f19209c5d2%2F4DNFIDSWKFF5.hic":"1596696630,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F6e7b9be7-f465-4434-8e9c-68d1e44a76af%2F4DNFIV239W4L.hic":"2345867406,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F55df948c-941d-4930-854c-6a07557a0c1d%2F4DNFIREVU1Z5.hic":"2254683002,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3f590cb7-df3a-498f-81c3-d5ed4179b8ad%2F4DNFIFHU75I5.hic":"2497670883,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8f064770-6008-4f74-bfca-268d4a22d745%2F4DNFIMROE6N4.hic":"9850583704,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fa93d0588-76b7-4ccf-933c-4325876b0a53%2F4DNFI5SUHCGZ.hic":"10364705187,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F2f5f0d6b-0b22-4936-93c9-0944d49c037b%2F4DNFII84FBKM.hic":"8836986129,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F12e90fc5-0b76-4e42-b346-58d267f9ad6e%2F4DNFI2J1ODWB.hic":"13410858286,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff2702a45-3e8b-4980-bcd5-6bb0e291614f%2F4DNFIJWBWE41.hic":"20515676755,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fa0859349-5f06-4ad3-b56f-b1166b34a9eb%2F4DNFIIMZB6Y9.hic":"15350325963,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F12685c57-d54a-46fa-9efb-acf34ed77574%2F4DNFICJECID5.hic":"1525002266,26979","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd101a58e-89aa-44fd-96c5-6bf1e2476272%2F4DNFIR6UW2QA.hic":"1264999913,26979","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3d8c73bf-1335-4af4-b124-e3622d48c5f6%2F4DNFIGOEKBUZ.hic":"1905947578,26979","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fcd2477cf-6ed0-4d7b-b4e9-88fb38b0df48%2F4DNFIMDNAEW4.hic":"996444147,26979","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F0f03953e-29da-4f2e-8c05-572d0edf4525%2F4DNFI5OSZ3JC.hic":"369361754,22829","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F29d95dbb-005a-4ae1-8b9c-0fec9ec0bbd0%2F4DNFI7KOUGFM.hic":"1227434049,26979","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fa441ab7b-afbe-437d-bf98-b6b916558642%2F4DNFIGKX4A32.hic":"883933242,26979","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F941b2f94-2fff-4d3c-aceb-fee4a5ae41a9%2F4DNFI1ORHOTA.hic":"1140970677,26979","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8720ede9-093f-4c00-912f-373283260a16%2F4DNFIWSVLZED.hic":"458091151,26979","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fe9e17155-2b62-4a68-afb2-31dfa674e169%2F4DNFI6H926RO.hic":"3552863515,22663","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F22f22778-987a-4dc0-97bc-f26eae0156d9%2F4DNFIKTYSPOF.hic":"2939475400,22663","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F40f40192-0acb-44cb-8778-8d21afe593fb%2F4DNFIZ4S52BV.hic":"3067438113,22663","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd8767374-7018-4e11-9226-bf5612d39ebb%2F4DNFI3APMXHF.hic":"3258874744,22663","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8c5140ec-a65a-4186-8c59-2927233eecaa%2F4DNFIQLIKDSD.hic":"2746398416,22663","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8cdedda6-d7d8-4231-a85b-d56fcd962366%2F4DNFIKYXMF1E.hic":"14442148774,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Faa4d4497-7c6c-4dad-8040-be13ba07ea32%2F4DNFI9815EEJ.hic":"17960817603,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fe9b7b95f-190b-49fe-8047-ef4a8fc59746%2F4DNFIQ2687RT.hic":"15954277087,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F59863d3a-8d7c-49c7-9a41-7f2a58ad24d1%2F4DNFIYDBBSE3.hic":"16499534862,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3e80ca41-b3e0-4f4f-a05e-8f95fe96d938%2F4DNFIMOCN1YS.hic":"863725312,22663","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F96f97a01-0020-4f09-93e8-fc8a9fd07218%2F4DNFI6558CM8.hic":"1597967345,22663","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fce9e9334-ee0b-4549-a845-110470ba5986%2F4DNFIQZRKS7Y.hic":"907626411,22663","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fdaac8209-1015-48da-9e31-2e252dfd8fe0%2F4DNFIX4DLXSE.hic":"1369766288,22663","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F268b7d52-9655-474c-9467-8ba31bb2195c%2F4DNFII3JV8I1.hic":"856656441,22663","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F9681f9b5-335a-4f56-afa1-15b58bbb41e8%2F4DNFI5IAH9H1.hic":"1495185175,22663","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3e082eab-95aa-4677-88ed-9d7adcc1effb%2F4DNFIK5HY1GP.hic":"2135337789,22663","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F31af1ead-4520-4669-957e-424b4b197c33%2F4DNFIFA89L5B.hic":"1975593640,22663","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fcc2b78fd-52d4-4e0c-ac93-b84ee82daf7e%2F4DNFICXCFGEI.hic":"2628202920,22663","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff54efece-280f-46ca-95e3-1f8a3cd18820%2F4DNFIK4CECUH.hic":"1901129375,22663","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F1181c0c4-afb7-4b6a-9fdc-d868fb2253fc%2F4DNFI1EYIGOC.hic":"1947135384,22663","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F1d3e2905-b9b9-4b91-bcb4-8d34746e78f6%2F4DNFI7TLEWUI.hic":"1185758726,22663","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Faba3d42f-39cd-4a85-9d3f-835aefb5c803%2F4DNFIVCJKHMN.hic":"687240974,22663","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F27f54fcb-54fe-41a4-b25a-2f8944c89044%2F4DNFIN8F14CS.hic":"1304082029,22663","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fb75fedb5-88f4-4bc0-8e38-298df7847a7f%2F4DNFI5LCW273.hic":"12497258313,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F2f22b2a0-3712-496e-92d2-63775ec0e421%2F4DNFIVSCH2CH.hic":"12594733778,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F07e47261-5863-44f5-9198-76e263081bea%2F4DNFIZ268JGC.hic":"1499059135,22663","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F682b1ae1-3ac3-40e4-a330-c49f63946952%2F4DNFIJ1P4HBI.hic":"1190211725,22663","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F197e7c89-ea73-41de-8cb2-8c0b1e3bb945%2F4DNFITEGKBIW.hic":"2061501971,22663","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F191f6928-c9a8-44b2-8516-ee4d6005f24b%2F4DNFIE1P6RVH.hic":"1711447310,22663","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F94435086-3701-4b28-a6d0-4a59b24d7615%2F4DNFICJ6I4DO.hic":"1557899940,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Faa9ac173-d233-41c7-8985-ca91949664e4%2F4DNFIKUG8MEW.hic":"1339072088,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fba6d8ab6-ee18-4ba2-8da9-d631888dd50a%2F4DNFICFZGFAV.hic":"1261083478,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F87a3ab04-7094-4673-81e4-ac8c9add8eb5%2F4DNFIQXCZVVA.hic":"1084913802,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fbc1ff488-82af-4579-9424-959184edb139%2F4DNFIB6PJFJ3.hic":"1114571343,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F1f7026ee-987a-41e7-8a61-45510ee3f86b%2F4DNFIX97731O.hic":"1246860402,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F6186787c-2e72-4925-9729-02121e2e4597%2F4DNFIYQYZOTO.hic":"1212210849,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3b98a946-0109-4efa-a13e-cc7a36772125%2F4DNFIPXU7V25.hic":"1696288217,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fea17d041-c6ed-43a1-8047-535f3d19ad44%2F4DNFIL39PR76.hic":"1719284710,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F72774afe-f166-42ac-9849-4070b0dadf6d%2F4DNFIYLJ3R3B.hic":"1106419640,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F4a45e733-55f8-4a8e-be24-2ef34c976e25%2F4DNFIL51WBN6.hic":"1327651164,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F086c62b0-a26f-41ae-a5ff-88b8be2bd2aa%2F4DNFI6SFPUDA.hic":"1336964405,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F4d9b79c7-af62-4070-84a9-b953903f2732%2F4DNFI2KM22QR.hic":"953067310,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3c9889d1-f49e-4639-8e15-2d99d6cd22e7%2F4DNFIVF8Q45U.hic":"984193565,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fa080dd7b-b7bb-4eae-a275-572a8b45b2d0%2F4DNFI2RN3WFP.hic":"1046525527,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fb81860ca-c227-4b68-a298-1907fd32300a%2F4DNFI4TJTL7A.hic":"1160373401,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F74ab47dc-7b52-421c-845e-6feb33457adf%2F4DNFIYJ4TWB8.hic":"1268416204,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc6582128-a930-4bcc-941e-5c0733bdd4d5%2F4DNFIM6RGKPV.hic":"863347067,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F11a75514-4450-4295-9eda-18e3678a575a%2F4DNFIL2VWWL5.hic":"860731581,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F5eb52a8c-bf14-4225-bf34-14a0aa47c369%2F4DNFIX6ZXCA8.hic":"893462267,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F66aaa4c0-1f62-4040-8ecc-4e95da23cd18%2F4DNFIEVR81FS.hic":"879736207,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F821c6e7f-96f7-47de-b7d9-4970562b3c8e%2F4DNFIAUI6BBI.hic":"996313881,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F9252c362-31ab-413d-a47a-cc97bdbf243a%2F4DNFIAFEE9G2.hic":"1103265750,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc1a0bf52-2e65-4deb-871f-ede736babd41%2F4DNFIPZBEXCP.hic":"1081257762,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F729f5ce3-d7e0-466d-b781-d18049e63bfa%2F4DNFIWPKRZGU.hic":"973779283,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F80b769ee-a717-4825-9db0-dca86f913173%2F4DNFIMD9QNDX.hic":"1158688208,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F266290c0-2767-4158-85ab-7274368905b9%2F4DNFIATA1HD5.hic":"1073361089,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc46f18a8-eb24-4d35-b112-36db72bde2f5%2F4DNFIH9U4I7I.hic":"1111124316,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fec91a79e-7de7-49f7-9b3d-d28313aeddc8%2F4DNFIZ95S6TR.hic":"1242494051,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F9e9390b9-da20-43bb-a8f4-9830f354ddf9%2F4DNFI5ERM9J7.hic":"1271051397,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fee8ea82e-b9e4-41ad-bced-5f4fbdaa4fec%2F4DNFI15FPSQL.hic":"1216714120,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fbed7eb86-8990-42f2-b3ee-5992d6361f7c%2F4DNFIJ3DZPGM.hic":"1035089437,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fdaa8a324-3bf8-424c-8a86-b8ad325cc20d%2F4DNFINW9P6XF.hic":"1215712740,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F70631758-6bf8-47a0-92b6-132574886faa%2F4DNFITS16HW8.hic":"1105283847,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fe473304b-7bc8-49b8-bba1-ecb9f06914ee%2F4DNFIS3DIH4V.hic":"1036056660,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F10f9224a-111c-402a-ac25-e221ad0af9ef%2F4DNFIY3KDHP6.hic":"1071761024,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F17519b96-2bdd-4294-98f0-1535f1aef28e%2F4DNFIO8HVKOL.hic":"953793750,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ffb18f896-4730-4909-86a3-867fc8e76cd6%2F4DNFIMF6CFOM.hic":"708717889,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fcfee4d87-0873-40b0-b79f-35dcc8669c1c%2F4DNFIZZ77KD2.hic":"732668723,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fb8b5d909-8a1b-41bb-bcdd-d108a0bde762%2F4DNFIOLO226X.hic":"951271932,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F9ce81f6e-b9cf-4ec9-8bd3-517539e4b662%2F4DNFIJMS2ODT.hic":"932509067,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F506aa952-5d41-49ff-b658-916bcf88a395%2F4DNFI49F3LJ4.hic":"1208494817,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fe4dc392d-ca36-4bdf-a27d-173cae34f520%2F4DNFI65MQOIJ.hic":"854630155,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F149ef8d7-e0b4-4e4f-b7e5-7226e2603746%2F4DNFIM4KEPRD.hic":"882790622,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fa436f0a8-4f9a-4524-90ac-795c5b8491cf%2F4DNFIIXBIZFC.hic":"848244425,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fbc8a05dc-7449-4b01-8330-a55db37ca8e6%2F4DNFIWDOOBVE.hic":"1116239020,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Faef8b881-28fe-4694-9a95-1d31940e6726%2F4DNFIDT9EB5M.hic":"888289053,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff66f3162-a53d-46f2-8800-3752935d5400%2F4DNFIX2VUNV8.hic":"1226661451,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F36c782e6-2c48-4298-aa43-bd6624da003d%2F4DNFIEQHTV1R.hic":"804665819,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff15d571e-605d-4bcc-a359-0350b57a6815%2F4DNFIFW7GA64.hic":"901568712,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc2aa2e8b-ac7f-4acb-b4b5-ac5f845840fe%2F4DNFIXGXD67I.hic":"970995551,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F71b6fd7d-b249-4d65-a597-b80b95845399%2F4DNFIA7GB1NB.hic":"956785837,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F6cbb1418-34db-427f-9273-5174eac81529%2F4DNFIVOJGWNP.hic":"890415052,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc69c2ee7-b6c3-4a62-8d4f-913491c9dab8%2F4DNFIW22BNB5.hic":"1075499540,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fa268f28f-c6d9-4324-8989-75d2d317af1b%2F4DNFIIFBC8WN.hic":"1045459440,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F6c7361d4-60a6-440b-b5be-072cada98663%2F4DNFI9ZBEBJH.hic":"759395398,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fcceaad1a-e01e-4430-8bd6-24ffa6891802%2F4DNFID4SLU53.hic":"921288444,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F9eee5854-b33e-4d5a-9ba8-ceffd47e7488%2F4DNFIODI1NUJ.hic":"733159777,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F5e1089b0-42e8-441c-99bb-4be99bcec28b%2F4DNFIJL26LFN.hic":"723567970,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F298a429e-ea29-49d3-bfed-fa851e1e7c4c%2F4DNFI5KTF553.hic":"2213661745,22663","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F965d29f0-e4a3-477c-8ae4-faf4a654e69a%2F4DNFIYSPGFGV.hic":"2274989349,22663","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd88acbc1-37b9-4266-9f97-d8fed576d0f3%2F4DNFILOR6D2D.hic":"2595459358,22663","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F7b6ddbce-0ed1-4272-b8ae-32793e4ea4e4%2F4DNFI1WMMPJQ.hic":"2262433890,22663","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fedc0c8c4-97d8-4372-9a4f-5e0cdf09d7d0%2F4DNFI47P5978.hic":"2146314403,22663","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F0edcc389-43a4-44d7-b946-fe3496f93d56%2F4DNFI7XGW6IH.hic":"2302805723,22663","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F0a802926-e235-4c80-b521-83a1774dfb46%2F4DNFIK1EJG8I.hic":"2374943035,22663","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3c36aedb-6a58-4aa2-9b11-bb440ec174f1%2F4DNFIDQ3THN9.hic":"2341188249,22663","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F846123cd-8828-4e51-8b8a-27deaf293858%2F4DNFI3WPNFWT.hic":"775145629,22663","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fbd06e3ad-0e37-48a3-8367-c7d5912cab03%2F4DNFI9DCUOQ1.hic":"870487824,22663","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc2eaf9bf-9584-4cec-8685-bd74038a6c01%2F4DNFIU8AF5ZY.hic":"1276224366,22663","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F219497b5-3f35-473b-9d4e-e1cf21c69561%2F4DNFIHW8NTQX.hic":"28864787856,22663","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F4be13558-114a-4f2d-abca-7598e2ff4757%2F4DNFI4OUMWZ8.hic":"17061013588,22663","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F49aed637-87a1-4d4d-ae68-e5da82aec05b%2F4DNFIEYQ5ZIR.hic":"13555272651,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fa2f48779-4eff-44a6-8a9d-96435aca1ddc%2F4DNFIDZT7PR8.hic":"13425047093,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fb6ec6b71-27b8-4891-b10a-ab06a5270468%2F4DNFIEJEFCAM.hic":"15394960208,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F68b9a7b5-8413-44fc-8c2d-59a67b1c4166%2F4DNFIJ8JKKWJ.hic":"17012681779,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F294d45a4-8b5e-456f-a9cb-1cbbbad3a7d2%2F4DNFINEQY95T.hic":"13966775978,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fbd7f3a48-b822-41e2-bd9c-f52b3aff7b6a%2F4DNFII6AN691.hic":"12367300362,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F7da44594-0dc8-4e74-8e10-a957aeaea51a%2F4DNFIDBIEXI7.hic":"2015474981,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F085a0453-3784-4eba-80b2-3556e53e2f52%2F4DNFIDKJFK2S.hic":"1983111659,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc370c78c-0a99-4c3f-a29b-2dfafc6a3e86%2F4DNFIPAF4PYT.hic":"3041434294,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F907ce45f-baa5-416d-92de-e86db4bacff1%2F4DNFIWIYYNQ5.hic":"7082321112,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff13afc6b-cf69-4c9d-881f-eed4dd3c28ee%2F4DNFIHMCILEN.hic":"1739157603,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F7575d891-0e3d-4a77-896a-3e1b3a8d330b%2F4DNFIJBJ6QVH.hic":"5213499748,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff0daa830-60d5-4c7c-a2e1-a4ee70b3fee7%2F4DNFIH2A7IKF.hic":"4099503507,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff4970a25-91d8-49a7-9a4a-fe0f12cb2b0f%2F4DNFIOL8KGQ2.hic":"2256042055,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F879f1850-d175-4a86-8a97-12658482e3d1%2F4DNFIWILLD6C.hic":"5476286356,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F787f538e-d619-4c8f-985b-78753fb7e57c%2F4DNFIZBXXJAF.hic":"5946467856,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fb8ee785f-1016-4989-9e64-78352621d32f%2F4DNFI8PZOJHN.hic":"8307204961,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3d8997fa-528c-4531-b25b-a412de6bd472%2F4DNFIGXAMSJY.hic":"6577588285,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F87aede55-7610-4283-af0e-c6840429a31e%2F4DNFIWNNO89O.hic":"2871061417,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F93b8e020-b337-4685-81dc-40cc8a12b5e9%2F4DNFIXU2KPNQ.hic":"3401717686,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ffb5cf1bd-59d6-46fe-857d-b86d9756029d%2F4DNFIHBGD6N6.hic":"840028421,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F2d1bc088-d838-49b8-85fc-fea78a7353c4%2F4DNFI7J8NI4A.hic":"675705256,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F21a27b63-fd67-401b-9aa2-2798e6588d21%2F4DNFISFM9VFK.hic":"800145922,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F656c0a9d-7058-4c4b-a3ce-701d929561c1%2F4DNFIJU5XBK7.hic":"966593603,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F2efacfbd-9c81-4e62-8df7-847d1ab774d5%2F4DNFIPKY8ED1.hic":"3401629450,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fa50b6a26-56b5-43f2-b525-fa219fd716f1%2F4DNFIQRTP7NM.hic":"5358852759,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff5dc7a59-b998-4490-8a76-afbf3b258a49%2F4DNFIBCIA62Q.hic":"5779049277,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F62b2b237-cb02-45f7-89d9-616cf9ffb678%2F4DNFIV56OFE3.hic":"5818844506,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8ac79b4f-cfbf-4b2a-9fc2-898ed6c3e5e1%2F4DNFILIM6FDL.hic":"19637469163,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F1cff8afa-5a13-4ad4-bcad-91fc3ced759c%2F4DNFIP71EWXC.hic":"17934647326,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F000789fe-9a22-4280-a71c-7ad228fd4cac%2F4DNFIM7ZVQOQ.hic":"700134697,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8d78457f-0c2b-4358-b08c-4d4ef4d9f59d%2F4DNFIS6EYHCX.hic":"628314484,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8ca3b4a0-2478-49c9-b4a2-a28430417a32%2F4DNFIKKCMS1Q.hic":"584050634,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff5041473-18ec-439d-92b1-8ad98c9b25c0%2F4DNFIBIV8OUN.hic":"522632731,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fcf474ec6-abd4-431e-a21c-252fcf5ee6b3%2F4DNFIAUMRM2S.hic":"313395531,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F2bb1c73e-fb0f-41c4-8620-a938cc8d24a0%2F4DNFI9ZUXG61.hic":"332217525,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F26dfa41e-7e4f-457a-a3ac-72daf8059f3c%2F4DNFIDBFENL7.hic":"359604894,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8ed2e68b-189e-4988-bb6d-94e63240a231%2F4DNFI7XAZNNQ.hic":"5312422266,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F6f2b1ce0-5205-4680-981e-d91b694dc3e4%2F4DNFISNGDB53.hic":"2008546759,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F73c8147f-bc7d-4d33-8a10-a9e7b413ecc6%2F4DNFI1CIGHYC.hic":"2221847625,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F526ae3e3-32cc-4670-970f-1faa9cfafd4d%2F4DNFIQD2DP2F.hic":"5295591503,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F6e803530-47f8-4c56-bb19-fbdcd578d2f0%2F4DNFINHT8P7C.hic":"3159499486,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ffe705f38-903f-47b7-9b38-f80ebd18a479%2F4DNFIGF8EM7M.hic":"3490552542,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Faa197328-d6da-4299-a0fd-409ac9892668%2F4DNFIUPG2ZBJ.hic":"5382003751,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ffe5d52c4-2be7-4812-bca0-cd4bb3025e6b%2F4DNFIH3OTR14.hic":"3224693110,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F21935f61-daa8-4df2-aa69-fcd27953b405%2F4DNFIUATRW3Z.hic":"3835865655,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F72147527-e3e8-4967-bc45-8251249d76c9%2F4DNFI6V7ZQAE.hic":"4382708138,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F589f0919-f54d-49ff-a482-e2f453ef7f34%2F4DNFICKMT1CY.hic":"4479068191,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F861946ca-bad8-4a87-96e1-b2eb20b9ef10%2F4DNFIF9BDCNI.hic":"3698151402,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff76346ac-97ec-4893-8984-2b75ce1cdc51%2F4DNFIG5O1OQS.hic":"5704288175,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fe8b43826-f049-4c3f-b83a-e75fa7aacc85%2F4DNFIHS2SVBQ.hic":"990025510,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F46316260-f555-4dd4-9e40-8ae06ca52822%2F4DNFIU95B69H.hic":"1275878544,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff62ef491-a3ae-4f66-ab33-c5673c9e0b65%2F4DNFIYRROFCR.hic":"1522530503,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F1cd617e1-fad4-4fdc-8b4e-cb277650123c%2F4DNFIF7JN3IU.hic":"1463443128,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fdb20fe2a-0078-4d4a-8a52-d76043d06f40%2F4DNFIB2RYULQ.hic":"1269529700,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3d386fcf-1d22-47de-a0d6-0c3a641ca174%2F4DNFIMVDK3SI.hic":"1185489599,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F00e470bd-c533-41b1-923a-4b471824da12%2F4DNFIRLOTXSC.hic":"978217499,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fb8774fb3-d0c5-43cc-a6c9-eb0ca39841fb%2F4DNFIZAPX6J8.hic":"1100356082,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fab3b826e-614c-448b-860f-a3ebef68a82f%2F4DNFIQD5VCSD.hic":"1322319877,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F66c78d2b-993a-4937-95ed-9e2d302ceb3e%2F4DNFIIF6VAGN.hic":"868885799,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F5d106fe1-2d80-466e-87aa-46b38ba142c5%2F4DNFI86IEZXH.hic":"751443267,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc99490b6-faf9-413f-9c38-3f53018089d6%2F4DNFIP881SR2.hic":"754427927,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F39c7e387-e710-4b1d-b757-357dec03f6ad%2F4DNFI42NNCW8.hic":"1166392978,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F4742a211-43b1-4325-af6f-82490aeb766b%2F4DNFIEV4PKP6.hic":"1102227476,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Feaa73842-1c86-4ad9-8a9e-c189c0b4c01d%2F4DNFIF1DUQHE.hic":"1206699207,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd25f24df-0298-4079-bb6f-1c8e1e32392b%2F4DNFIGW55EAY.hic":"1033358104,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc57a7ab5-2778-4fe2-9d64-9a4e95135f12%2F4DNFISZRU6I4.hic":"1539570262,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd89f494a-27ca-46b6-89be-7583f3f6d18c%2F4DNFIBKKDTAP.hic":"350372180,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F06725280-cb24-4f22-a267-18b434bfa79e%2F4DNFIJSRQW24.hic":"314361467,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8fe5c3c5-006f-425b-ac6d-ea475e29be78%2F4DNFI3REN89E.hic":"299665258,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc8b6ac5c-13b4-427e-9158-cec0b890b6d8%2F4DNFIF5XLHKM.hic":"235668364,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F01ff33fc-fc23-48aa-a6c6-b720d6fe0768%2F4DNFIB6Q538N.hic":"316494853,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F552978c8-abbc-424a-9187-3e34cf802a97%2F4DNFI3ST3F7Y.hic":"296298411,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F72e66520-5170-4f2e-844a-fbfd0e23b480%2F4DNFIQT4M6UI.hic":"307691265,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fb3eb3953-ffe8-4d5a-970c-a16f3b7b9ec3%2F4DNFIFNCC7M2.hic":"364160436,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F37d413fb-afab-41ff-99aa-1678830f7dde%2F4DNFITM9MDJL.hic":"252412426,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Faf5db92c-aaf1-4086-a0d2-79b28648f172%2F4DNFI3NTD7B3.hic":"227586640,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff6892f7b-1f8a-4d7d-9605-c67932cd5654%2F4DNFIBED48O1.hic":"328344868,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd64afb07-5ab1-4c4f-8438-2fee37afa86a%2F4DNFISATK9PF.hic":"379669025,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fad11bb63-8692-461c-b698-89c601451321%2F4DNFISRP84FE.hic":"298491537,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F63710ec5-35d2-47dd-bf9a-08d3daa83d67%2F4DNFI2LY7B73.hic":"303150299,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F76077d9e-ca75-4301-ab79-88aa49bda495%2F4DNFIXEB4UZO.hic":"711757090,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F34dd4c0e-3487-4fb4-b95f-c4bb66e0fa31%2F4DNFIQWWATGK.hic":"221304476,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F48a8cf86-3248-4a8e-8e85-472ec219d49c%2F4DNFI44JLUSL.hic":"284772724,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fee399fbf-2a9e-46e2-8364-457713bff508%2F4DNFIM7Q2FQQ.hic":"330729464,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F124d191a-c5c7-49b6-b84b-0d1bad8bef2b%2F4DNFIZK7W8GZ.hic":"293166018,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fe351f7cc-7a2c-4515-ae0b-3bb2f91c986a%2F4DNFIMIMLMD3.hic":"240094740,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ffd1ae249-57b1-41d6-81a6-16b21dcd8f12%2F4DNFI7QUSU5J.hic":"681762505,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F46c92c5c-9ad8-4d49-beba-f35c5cd99208%2F4DNFINXUOI5H.hic":"375594313,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd7350d40-4e9e-4131-9151-bb539d39b431%2F4DNFIIJR2296.hic":"331322302,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fbfacf37b-1665-45f3-a046-e29e1544e9b0%2F4DNFIJMZUTXR.hic":"361313244,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F234e18fb-9990-43bf-9a48-f72722cfa232%2F4DNFIZQPT9EL.hic":"540421873,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F4b35ab09-2e79-4876-b2bc-d3a8faa26257%2F4DNFIZIXSZ9J.hic":"545066813,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F2ae5118e-807a-46e0-8e92-143d4b282b3d%2F4DNFIDD9IF9T.hic":"237409149,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fb34d7f6f-73f7-4b6b-80c7-c8af0f991549%2F4DNFIVC8OQPG.hic":"355121712,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F9ab169fd-cbdd-4f60-8553-a4c6912ad89e%2F4DNFITUPI4HA.hic":"313085022,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F4e53712b-d0d9-40c5-afe1-ffa0fad71e59%2F4DNFI5IZNXIO.hic":"341863906,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F7a91477f-45eb-4a16-affb-fc131f9326b8%2F4DNFII16KXA7.hic":"248904495,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F153729de-0eca-43cc-9b61-61aa8d775b38%2F4DNFIAAH19VM.hic":"668047244,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F879fd78a-7165-43d9-a0de-ca158b53df30%2F4DNFIVKIY3KV.hic":"247571318,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F67f901a4-040b-4b04-9fff-94a1780423cd%2F4DNFIVVCWL6C.hic":"198355985,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd5b30c5a-654a-463c-9474-39bdc3ce4500%2F4DNFIJRF2273.hic":"343971277,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F7070280a-8f03-40d0-9fef-e9d9f4d3dae7%2F4DNFI6FCC9ZA.hic":"312013061,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F47049719-9407-4d76-9048-26231045f642%2F4DNFI1CPQ4O3.hic":"352923267,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F862c2b5f-44c2-4bd7-9264-b3ca032d3d8d%2F4DNFISXFEDE9.hic":"271745977,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Feffbe052-39ff-4217-9871-44199ed90818%2F4DNFIF9L6QEQ.hic":"668409334,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fa7791854-1b35-4258-90fb-603c55f24642%2F4DNFIPKASX1Q.hic":"312727920,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F79cccad6-a78e-4de9-9fe7-08f7e8df663d%2F4DNFIWXZ4JQZ.hic":"151808553,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F7e86e0cc-d6f1-4ce0-aba4-c36c6ebb3c4c%2F4DNFIEMQ1O8V.hic":"700533280,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F4a1b58d3-9ae6-43e4-91cf-49f1fcbbab33%2F4DNFIYWONU7A.hic":"729050356,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F67bff264-0b0c-4c5c-9d4d-ff5abef2bbe4%2F4DNFISNIE5FH.hic":"7987657997,22663","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3a6a943f-2cc0-4433-a27d-c89f3fdd3309%2F4DNFIV8MLWJB.hic":"6646216171,22663","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F9e235711-ba90-404d-b4ac-b15990ea8e33%2F4DNFIXSTDPHL.hic":"3146468238,22663","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F0c89f4bc-e9fc-4ecf-b868-26108dbb7bb2%2F4DNFIQJNOH8U.hic":"2919703928,22663","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F1856ff9e-de7a-4fa1-ae0b-3e04b837b5e1%2F4DNFI57XB4A8.hic":"13417594377,22663","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F099bb5b9-6315-4650-8f78-d603f5a046b3%2F4DNFIQ7UKVZV.hic":"9016468637,22663","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Faf3c7a30-0fc4-410d-8d41-247da3eb105d%2F4DNFIWJY8GHD.hic":"7921314766,22663","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fda99f429-20ab-4d91-bbfe-f8bdea8ed7b1%2F4DNFIN8NKRNF.hic":"4247121358,22663","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F0ca0f4e3-30ca-4332-b735-e32dce08e1a4%2F4DNFIZYGEHNZ.hic":"4910404663,22663","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F243f48b0-6b59-4f37-ad39-a12e0986f530%2F4DNFIRPYGAV8.hic":"4220073636,22663","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F49f1a890-d458-42a6-9c78-99c38b6c7a8f%2F4DNFI6MZTDM1.hic":"375035361,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F76bd4768-9343-44ba-a99d-5500e184e39d%2F4DNFIG3BCGPL.hic":"2422923206,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F9d1ed866-eaf6-4906-aa8c-9e39616dde38%2F4DNFIS9YPJ3L.hic":"1593271574,37769","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F1e7a5636-bdb6-45fb-85d8-87a7e908de43%2F4DNFIOWGA9AX.hic":"1632314387,37769","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F5ecc552a-0a6b-49a9-9aa5-9f3fd9b535fd%2F4DNFINKEDSBF.hic":"1458761024,37769","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F6c03f1d2-bb25-4c94-b5f5-d5cdd01c14b6%2F4DNFIVIXVUK7.hic":"1504818271,37769","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F1a4616ff-6d04-4a6a-9773-b80e81da2471%2F4DNFIANHFY16.hic":"1850724180,37769","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd2231870-a78d-4c8b-9cfd-084f2468acb1%2F4DNFIJ67ZFBI.hic":"1473864703,37769","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F859c2dd3-df8a-42b7-86ea-bf6524f75e80%2F4DNFIG3YQQ4V.hic":"1539822829,37769","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8bad667e-6003-4828-9a20-07585fa9c811%2F4DNFIOLKEOME.hic":"3036353747,37769","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F92ea551b-5779-4d31-a0f5-621e4bd0eb21%2F4DNFIVLN8WJE.hic":"2710426318,37769","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F61ee79fa-0617-4083-b121-f92ef3a8905c%2F4DNFI2111XQA.hic":"2589549183,37769","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F83ebb98d-e5db-403d-aa23-875293156c0e%2F4DNFI88HXX7D.hic":"2462367030,37769","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F6d63671a-8f1d-4159-82c0-931b43464772%2F4DNFIUBM6QK8.hic":"2486020469,37769","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fcccb9014-ce15-4032-81ac-222b3d621cb4%2F4DNFIVILEERC.hic":"2052537210,37769","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F21a07867-4007-4ca5-b066-25d3168208dc%2F4DNFIF7Q43N4.hic":"2091773428,37769","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff738de0f-358b-44bf-97dd-644c8d9b1b1c%2F4DNFID56VJGW.hic":"878913568,37769","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fda97c1d4-bb92-4a77-92a7-f7960f88b9dc%2F4DNFIYUR29KO.hic":"983915575,37769","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F54ea363a-99e7-4f55-861e-1644acab7939%2F4DNFIUDPGHO8.hic":"905253594,37769","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fdcd66a07-55ee-48d9-a157-419cf4ee3eef%2F4DNFISWC2N8T.hic":"1233576358,37769","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F40363837-7466-4a1d-b20d-a66d1670b700%2F4DNFICMPHDMI.hic":"516590777,37769","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F0b3fa4e6-caeb-40b4-8942-e9c0b03dfe4f%2F4DNFIKMKN736.hic":"634310295,37769","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fb6a34050-d52b-4880-91cf-d3fe4b0ce982%2F4DNFIN5NLS49.hic":"650451131,37769","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8e63a47b-9fd4-4772-8b0c-10ee589ffb16%2F4DNFI4P8UBRL.hic":"705655033,37769","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F7d92b666-30cc-4838-9d46-c1f11cee3d3c%2F4DNFISNC3LAI.hic":"176146197,37769","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F17f7dc63-a1bc-4970-b389-87d9ee93b753%2F4DNFIVBWPFD7.hic":"749678512,37769","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff8897333-4791-4a83-9444-a653e24aee13%2F4DNFITMQRXB7.hic":"254477361,37769","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8712bf31-33d0-4562-ab0b-a1e9cf4fd30c%2F4DNFIUYD3HBY.hic":"995625724,37769","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fbfaf6383-9cc6-4b5c-9b20-d3bf2e8c3495%2F4DNFIRRSC7P9.hic":"1149985362,37769","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fb0b70598-5d17-4e0a-8831-6cbe697e69e2%2F4DNFIWKR8FP6.hic":"1151628407,37769","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fccc094a8-23ce-4fd8-9c4a-41f07c045c8f%2F4DNFIQ74RSUY.hic":"931695969,37769","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8eda16f3-af5e-4f1f-b46d-c74df44b76aa%2F4DNFI9IIO5PW.hic":"1077740364,37769","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff283637b-cf2c-4412-ba00-0e3d7e279fad%2F4DNFI8WGJG19.hic":"812086456,37769","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F7ad8438f-d3d9-42d8-88bf-42845a0dc2d0%2F4DNFIQ5CCESJ.hic":"652559720,37769","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F70e3bdcc-caf4-4822-b9c5-85234873db7a%2F4DNFIWTZHB4H.hic":"760694196,37769","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F56ed767d-cd8a-4d38-8047-ed1e8bc8cd19%2F4DNFIENYQCDP.hic":"1159428005,37769","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fa912fff9-5f90-42b1-a3a6-cbb9eb2cf861%2F4DNFIFATZWPD.hic":"1033325746,37769","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F21338ea5-fdee-4ad8-b61c-608fc6cec4bc%2F4DNFI7YRXKEO.hic":"388142539,37769","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff0f88647-5631-437b-b48a-4603915e3714%2F4DNFIUY3J7EW.hic":"407344788,37769","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F16926af8-ac3b-4f32-97d5-6c0dc6f1596a%2F4DNFIRKUYKP4.hic":"893352368,37769","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F93e39aec-6cde-4c5b-bcdf-283faa3163a2%2F4DNFIAQDBJZP.hic":"489922022,37769","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F0dc0b1ba-5509-4464-9814-dfe103ff09a0%2F4DNFIC1CLPK7.hic":"565748333,37769","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fb50964c7-b025-49d9-b1ed-289bedb59678%2F4DNFI3A3VYWU.hic":"4597459343,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff4390cea-b330-4022-88c1-9ff8c0a786f7%2F4DNFI6JJQKFJ.hic":"3678393678,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F70c0f730-5da1-4863-9b7a-6cdd31066cff%2F4DNFIK61ILGM.hic":"3324300994,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F14b14ac4-ab59-4754-9c43-eacd9d0638e2%2F4DNFIYD8LO9Z.hic":"3227227120,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F7386f953-8da9-47b0-acb2-931cba810544%2F4DNFIOTPSS3L.hic":"253942497,7557","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff6b5d8bd-27dc-4415-a320-53405a16db85%2F4DNFI525PKU5.hic":"305089653,7557","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F1f922dbc-637b-4c43-b816-f604f0e79ad1%2F4DNFI8Y9SRP2.hic":"1438589609,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F6a36d686-716c-4ba8-a9c3-fa8311791d3c%2F4DNFIP25GZGA.hic":"1419100109,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F0e535542-2cf2-46e4-ba10-7a0b946a7fb2%2F4DNFITPO1WTY.hic":"3885296184,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F0c17d228-5052-4c83-880e-af05118e6929%2F4DNFIG4X5Z5F.hic":"2159245890,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc3977c00-525b-4556-9a27-061707f8cb76%2F4DNFIXLYR32S.hic":"587852728,21916","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3f856506-cbc5-4211-a29d-48a7530c622e%2F4DNFIWI3V5LI.hic":"2318237793,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F38f77979-5eb7-4b6f-9a60-c2451185db98%2F4DNFI2DGL7LH.hic":"2068150664,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fe0992a75-7727-405e-95ac-aa97141b51c1%2F4DNFI1VSO8JP.hic":"1807949651,21916","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fe925f1aa-2e7b-44e7-bfa8-2084a613ab13%2F4DNFIV5O2ZYO.hic":"2242134377,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F803a6d3c-3972-4939-8ff2-d195c5192090%2F4DNFIEWEWQ8D.hic":"2981341325,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F25104375-a588-46e6-a382-663cee6c332f%2F4DNFICSTCJQZ.hic":"14592996888,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F927aa8a5-24a5-43b7-807a-1e99ac321459%2F4DNFICEGAHRC.hic":"15431307603,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8c380474-12cd-41f4-b86f-2a29faf12eec%2F4DNFIY3XPKPO.hic":"2550999291,22663","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F77da562e-d0ec-45a8-8764-14fa16d995a1%2F4DNFIK9PS9GM.hic":"3401011629,22663","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F11b26222-d480-40a7-8d53-3ad8500396cb%2F4DNFIF4Y74JR.hic":"2127593378,22663","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F93df02c6-1047-43f6-afae-d3598b61eeea%2F4DNFIBBKG9KD.hic":"5724446278,22663","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F6cd4378a-8f51-4e65-99eb-15f5c80abf8d%2F4DNFIT4I5C6Z.hic":"5419655766,22663","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F067881e5-563d-40de-a9e3-caccad887fbc%2F4DNFI2U38HCE.hic":"14749043471,22663","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fcb3da9ad-7afe-4d0c-9c2d-261181e7a95c%2F4DNFIETP228R.hic":"9401474797,22663","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F185b7bcc-7bb7-41b7-9ebe-92d4fe159431%2F4DNFIXKC48TK.hic":"11624295594,22663","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F18459b84-dd43-4af6-a05f-bcb773096322%2F4DNFIFPGOWJ6.hic":"2843730862,22663","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ffde1e48c-4a0d-4bb1-b84a-e0e45f9a0aa3%2F4DNFIIRMBE8Y.hic":"5820677927,22663","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fbabed539-1f0f-4e87-8815-fde596e6024c%2F4DNFIVUGNDD7.hic":"5170782436,22663","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F7d00531a-e616-469b-af52-5b028270e2ce%2F4DNFIFLJLIS5.hic":"18917549985,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F7a9dad53-b8af-4cb6-9ce3-5c38e4a855c7%2F4DNFIOX3BGNE.hic":"5482775936,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F82fd7b7e-5f47-48d5-bf0d-daaa48a4674d%2F4DNFISPUVQHA.hic":"2177864938,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F4c6680f3-9cf6-452f-9dc5-ecebf376775d%2F4DNFI8649RQJ.hic":"3288850368,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F2395f001-19d9-4000-9f00-dae3dea708d6%2F4DNFIE8T8JZ8.hic":"1383191843,21916","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F24464fa8-bf96-483c-8e9a-c2f626ad6e19%2F4DNFIBM714BP.hic":"1765204569,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F918fc048-fa27-41d2-a63a-d50c511fbb9a%2F4DNFI6CWNUFL.hic":"2431120602,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F7ff5a0d1-8e54-4cf0-9fe7-339f147c78da%2F4DNFIZ4F74QR.hic":"3211825957,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F355f0412-cb17-452a-b15c-aba16c5a742c%2F4DNFIOUVOX3R.hic":"5547401083,22663","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3cac91c5-160a-4b91-a91e-edc309318dd5%2F4DNFIVTDXW6X.hic":"4797344498,22663","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fe9ac9ec5-6221-4f39-951a-1c5054fc9f1c%2F4DNFICA8Y9TN.hic":"4277557869,22663","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F46f62222-b50a-428b-938b-5444951600eb%2F4DNFIDWM3HN5.hic":"4374808431,22663","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F50e4f2a1-9cb6-4192-8199-64d354bfdf96%2F4DNFIBK5TB3N.hic":"3757387253,22663","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fe4cdd5a8-1a45-4c6a-906b-a9603260d4c8%2F4DNFI3JYF9VS.hic":"5260534916,22663","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc8164e99-5778-427d-be26-f0e1b62400f0%2F4DNFIP1GNKUO.hic":"7589365689,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F0d72e78a-fc87-4716-8b8e-6dc5650ff2ef%2F4DNFIQYQWPF5.hic":"22022259901,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fac58fc15-48c2-4eec-a689-23b677b4b6e7%2F4DNFIW6H9U3S.hic":"6810897169,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F31811e40-e3ca-4456-8ba6-2ee66d6c7104%2F4DNFI7J8BQ4P.hic":"7188744676,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F62d81a52-d2cb-4bbd-8510-0fe120e786e0%2F4DNFIA3AKFSU.hic":"1763730692,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fae0b7513-d1a0-4f27-a9d3-348837f42cb6%2F4DNFID68JQY9.hic":"2422880133,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fae6a1a7e-1d2d-4fd2-a89f-1799abac8a9c%2F4DNFIL1FQDXE.hic":"1543814834,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F80d343c9-bd60-468a-803d-c3e351a958bc%2F4DNFITSIPCSK.hic":"2344682115,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff2d61195-a3a6-4d50-b928-546ca67546cb%2F4DNFIJ88LYHR.hic":"3362742962,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F31052aba-773a-4500-961b-e0a518245b0c%2F4DNFIJIPWD63.hic":"2529548812,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc93d0710-3fbf-40cc-b0eb-878e2aa659e4%2F4DNFIZUP2BBI.hic":"491996147,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8660baeb-5be1-4ba5-93e4-66499e9a4587%2F4DNFIEBC4AF3.hic":"2993048734,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff6d08fbc-b836-4776-82ad-8b1b277ae837%2F4DNFI5VO3E1W.hic":"1949322679,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3af004a2-a6fa-46dc-8be8-898b847a77be%2F4DNFIFDGVWLU.hic":"2456400803,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fbd613b4b-2422-492c-8d8f-8afba9c8a182%2F4DNFITVGFNYZ.hic":"1411204423,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc340694f-14f3-4638-b09b-98220c20039a%2F4DNFIOW9TTC1.hic":"2611370588,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3effa71b-6aa3-4265-87ba-f8d709d778d7%2F4DNFIOAA3ZEQ.hic":"3123195980,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fde75cf8b-9ce1-44fc-8b7b-ca0adea6bae9%2F4DNFIA5ID1S6.hic":"3496246968,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F714f775d-a5a4-4314-83f8-016b9d73200b%2F4DNFIZYU7V81.hic":"4245592042,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F5ca518af-6e1e-4777-b67b-0fe7f039ce58%2F4DNFIRV6PVUX.hic":"3981520466,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc29b57d5-c263-4372-b396-ab4f55682f5d%2F4DNFIMEANFBY.hic":"3999623376,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F4196d3ef-161a-4c18-a57e-005165c6b32a%2F4DNFIGLGQXLC.hic":"4105683321,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fe10828b5-9519-4ceb-81e7-7228bfd890de%2F4DNFILS2HLXC.hic":"3804942111,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Feaac88c7-9bdc-4b1e-aa9f-e675520dfffa%2F4DNFIQS8853L.hic":"5287726781,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Faab371b1-bc8d-4e83-998e-5bb977c443ca%2F4DNFIVBYCYGS.hic":"4657988157,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fdb116add-af8c-4a3b-b106-9f704ba0a175%2F4DNFIE4WWHMF.hic":"5116727268,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F033366e2-05a2-4381-9d48-90122892a9e0%2F4DNFIKDUUC3C.hic":"45638237,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F7284a446-442d-4a46-aae5-84987e75a7af%2F4DNFIJ5HIRA2.hic":"62201052,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F876649a3-6dd3-463a-8b17-5752a98a89c5%2F4DNFIXDFC7EM.hic":"69878143,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3cb4ce4d-d474-459f-8b8a-2159d8df8068%2F4DNFIO35EOVR.hic":"70153114,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F5c5612fa-18c2-47fb-8074-693b1054e254%2F4DNFI57QGL6U.hic":"54605055,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F70c1472d-cf3a-41d7-8682-cd03b7cc978d%2F4DNFI2AGEBE5.hic":"67930121,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F2bf4cce8-6e03-422b-a190-e51d4a07d501%2F4DNFI1E6NJQJ.hic":"4893181511,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F0eb3aa56-8a23-435d-a07b-8bb545e8d708%2F4DNFI2DNFM1A.hic":"60466977,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F1201682a-a223-482d-913d-3c3972b8eb65%2F4DNFIIRIHBR2.hic":"48961678,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F6aee7913-6356-43cf-affa-f2b60dd478f6%2F4DNFIKXNMT46.hic":"39095246,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F357139a3-c9a5-4343-b0a4-b41c45fd03fd%2F4DNFIRV7IRJP.hic":"70916718,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F76be3061-6259-42be-a917-19dcba41517b%2F4DNFIFX1XYKZ.hic":"229197441,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff60c348a-a62c-43c3-ac85-f6c28b5f823f%2F4DNFI64CJUZ5.hic":"112428610,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fbd0b0a14-9703-49af-bb36-2359f96d4d0e%2F4DNFIBPL2HL1.hic":"73972428,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F79ac278d-83f7-4c1f-91b2-05c8018c1426%2F4DNFIBRSIPE4.hic":"415430378,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F0c3b8141-8e67-4211-80dd-3bae88f9e537%2F4DNFIDLDVY14.hic":"112747303,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F2ae703d2-d85c-4ac4-9ce1-14d653927675%2F4DNFI4R1II4P.hic":"210565448,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F76e641af-90be-49f8-b126-12c20f856159%2F4DNFINMLRY95.hic":"1590865292,22663","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3b416382-ae5d-469f-9e9a-85a3e2ce9793%2F4DNFI8KBXYNL.hic":"4626496956,22663","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fa27589a6-86b2-43a2-8218-1f2232d551e6%2F4DNFI53R5IKA.hic":"1536016455,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fdd3999f5-b36e-4154-a6b9-446656959a3a%2F4DNFIAWVDQ8C.hic":"2210273411,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc377953b-0e61-426b-a905-abab2d5a3002%2F4DNFI9VXTBE2.hic":"3384365692,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F2dbe0377-1db2-4aae-af2b-d87dff728035%2F4DNFIT96Z365.hic":"7692311974,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fdcfcb009-f006-4ab8-a4c7-af72be58c12c%2F4DNFITUOMFUQ.hic":"6592120312,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F67f9073d-b2c5-474e-b3d5-7d72cde555cd%2F4DNFIHLQKDN8.hic":"2647703964,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F76968cc8-fb9f-485b-85b2-c9289067194b%2F4DNFIL9M97T2.hic":"6186798917,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F87d9330b-8d2c-4e9d-85bb-02e572de7a68%2F4DNFIDWGZLHX.hic":"4379708168,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ffc01b381-3665-4225-88ee-2e5e9ecb7324%2F4DNFIMEG1QIC.hic":"3587146533,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3144a03c-15c3-4bf9-95f8-ffad2640a1bf%2F4DNFIWSB66VX.hic":"1529739069,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd7d3aac0-ba66-494b-ba0c-147631084b98%2F4DNFIH7TH4MF.hic":"6896300679,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F4b13bd19-fbd1-4c68-8855-4f0158d1ce47%2F4DNFIHKWIZ9T.hic":"1954878455,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3d04e286-30d4-4add-a806-7a929d36419e%2F4DNFIZBBX795.hic":"1350142414,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Faa26f261-a88a-4cac-9118-ff8e90ab6f61%2F4DNFI9ZWZ5BS.hic":"3410552807,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F24e516ce-0b49-4476-b818-cc96471d8765%2F4DNFIPAI8XB5.hic":"4168518737,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fac3b06b5-46d4-4c1e-97e9-9a4f353473a7%2F4DNFI1OUWFSC.hic":"10766406904,21916","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F76c6aa27-895f-4e82-8ed8-7a85aca84490%2F4DNFIX4PJKXZ.hic":"1463157350,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fe6fbe03a-997b-4d72-a3cc-f1ed7bd88a92%2F4DNFIZGCA8AH.hic":"1597664180,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F61d99a87-4ec6-4116-be99-b483999641c4%2F4DNFI5CGQ46V.hic":"2870576870,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F271ea8cd-53b9-44c9-9fff-1bb5c444b54c%2F4DNFIOCW5AEM.hic":"2463600138,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fa98ca64a-861a-4a8c-92e9-586af457b1fb%2F4DNFI1UEG1HD.hic":"22480709268,25900","4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F5809b32e-0aea-4cf5-a174-cf162d591a35%2F4DNFI9YAVTI1.hic":"3141182061,25900"};class Ox{constructor(e,t){this.browser=e;const i=t.querySelector("div[id$='upper-hic-nav-bar-widget-container']");this.containerElement=document.createElement("div"),this.containerElement.className="hic-chromosome-goto-container",this.containerElement.title="Chromosome Goto",i.appendChild(this.containerElement),this.resolutionSelectorElement=document.createElement("input"),this.resolutionSelectorElement.type="text",this.resolutionSelectorElement.placeholder="chr-x-axis chr-y-axis",this.containerElement.appendChild(this.resolutionSelectorElement),this.resolutionSelectorElement.addEventListener("change",(e=>{this.browser.parseGotoInput(this.resolutionSelectorElement.value),this.resolutionSelectorElement.blur()})),this.browser.eventBus.subscribe("LocusChange",this)}receiveEvent(e){if("LocusChange"===e.type){let t;const i=e.data.state||this.browser.state;if(this.browser.dataset.isWholeGenome(i.chr1))t="All";else{const{chr:e,start:n,end:o}=i.locus.x,r=`${e}:${YC(1+n)}-${YC(o)}`,{chr:a,start:s,end:c}=i.locus.y;t=`${r} ${`${a}:${YC(1+s)}-${YC(c)}`}`}this.resolutionSelectorElement.value=t}}}class Px{constructor(e,t){this.browser=e;const i=t.querySelector("div[id$='upper-hic-nav-bar-widget-container']");this.containerElement=document.createElement("div"),this.containerElement.className="hic-resolution-selector-container",this.containerElement.title="Resolution",i.appendChild(this.containerElement),this.labelContainerElement=document.createElement("div"),this.labelContainerElement.id="hic-resolution-label-container",this.containerElement.appendChild(this.labelContainerElement),this.labelElement=document.createElement("div"),this.labelElement.textContent="Resolution (kb)",this.labelElement.style.display="none",this.labelContainerElement.appendChild(this.labelElement),this.resolutionLockElement=document.createElement("i"),this.resolutionLockElement.id="hic-resolution-lock",this.resolutionLockElement.className="fa fa-unlock",this.resolutionLockElement.setAttribute("aria-hidden","true"),this.labelContainerElement.appendChild(this.resolutionLockElement),this.labelContainerElement.addEventListener("click",(()=>{this.browser.resolutionLocked=!this.browser.resolutionLocked,this.setResolutionLock(this.browser.resolutionLocked)})),this.resolutionSelectorElement=document.createElement("select"),this.resolutionSelectorElement.name="resolution_selector",this.containerElement.appendChild(this.resolutionSelectorElement),this.resolutionSelectorElement.addEventListener("change",(()=>{const e=parseInt(this.resolutionSelectorElement.value);this.browser.setZoom(e)})),this.browser.eventBus.subscribe("LocusChange",this),this.browser.eventBus.subscribe("MapLoad",this),this.browser.eventBus.subscribe("ControlMapLoad",this)}setResolutionLock(e){this.resolutionLockElement.classList.remove(e?"fa-unlock":"fa-lock"),this.resolutionLockElement.classList.add(e?"fa-lock":"fa-unlock")}receiveEvent(e){const t=this.browser;if("LocusChange"===e.type)if(e.data.resolutionChanged&&(t.resolutionLocked=!1,this.setResolutionLock(t.resolutionLocked)),!1!==e.data.chrChanged){const i=t.dataset.isWholeGenome(e.data.state.chr1);this.labelElement.textContent=i?"Resolution (mb)":"Resolution (kb)",this.updateResolutions(t.state.zoom)}else{const e=t.state.zoom;Array.from(this.resolutionSelectorElement.options).forEach(((t,i)=>{t.selected=i===e}))}else"MapLoad"===e.type?(t.resolutionLocked=!1,this.setResolutionLock(!1),this.updateResolutions(t.state.zoom)):"ControlMapLoad"===e.type&&this.updateResolutions(t.state.zoom)}async updateResolutions(e){const i=this.browser,n=i.isWholeGenome()?[{index:0,binSize:i.dataset.wholeGenomeResolution}]:i.getResolutions();this.resolutionSelectorElement.innerHTML="",n.forEach((i=>{const n=i.binSize,o=i.index;let r,a;n>=1e6?(r=1e6,a="mb"):n>=1e3?(r=1e3,a="kb"):(r=1,a="bp");const s=`${t(Math.round(n/r))} ${a}`,c=document.createElement("option");c.dataset.resolution=n,c.value=o,c.textContent=s,e===o&&(c.selected=!0),this.resolutionSelectorElement.appendChild(c)}))}}const qx={threshold:2e3,r:255,g:0,b:0};class Vx{constructor(e){this.threshold=e.threshold,this.r=e.r,this.g=e.g,this.b=e.b,this.cache=[],this.nbins=2e3,this.binsize=this.threshold/this.nbins}setThreshold(e){this.threshold=e,this.cache=[],this.binsize=this.threshold/this.nbins}getThreshold(){return this.threshold}setColorComponents(e){this.r=e.r,this.g=e.g,this.b=e.b,this.cache=[]}getColorComponents(){return{r:this.r,g:this.g,b:this.b}}equals(e){return JSON.stringify(this)===JSON.stringify(e)}getColor(e){const t=Math.floor(Math.min(this.threshold,e)/this.binsize);if(void 0===this.cache[t]){const i=Math.floor(255*(Ri(e,0,this.threshold)-0)/(this.threshold-0));this.cache[t]={red:this.r,green:this.g,blue:this.b,alpha:i,rgbaString:`rgba(${this.r},${this.g},${this.b}, ${i})`}}return this.cache[t]}stringify(){return this.threshold+","+this.r+","+this.g+","+this.b}static parse(e){var t,i;return e.startsWith("R:")?(t=e.substring(2).split(":"),(i=new jx(Number.parseFloat(t[0]))).positiveScale=n(t[1]),i.negativeScale=n(t[2]),i):n(e);function n(e){var t,i;return t={threshold:(i=e.split(","))[0],r:i[1],g:i[2],b:i[3]},new Vx(t)}}}const Ux={threshold:5,positive:{r:255,g:0,b:0},negative:{r:0,g:0,b:255}};class jx{constructor(e){this.threshold=e,this.positiveScale=new Vx({threshold:Math.log(e),r:255,g:0,b:0}),this.negativeScale=new Vx({threshold:Math.log(e),r:0,g:0,b:255})}setThreshold(e){this.threshold=e,this.positiveScale.setThreshold(Math.log(e)),this.negativeScale.setThreshold(Math.log(e))}getThreshold(){return this.threshold}setColorComponents(e,t){return"-"===t?this.negativeScale.setColorComponents(e):this.positiveScale.setColorComponents(e)}getColorComponents(e){return"-"===e?this.negativeScale.getColorComponents():this.positiveScale.getColorComponents()}getColor(e){var t=Math.log(e);return t<0?this.negativeScale.getColor(-t):this.positiveScale.getColor(t)}stringify(){return"R:"+this.threshold+":"+this.positiveScale.stringify()+":"+this.negativeScale.stringify()}}const Wx=685;class Gx{constructor(e,t,i,n,o,r,a){this.browser=e,this.viewportElement=t,this.sweepZoom=i,this.scrollbarWidget=n,this.colorScale=o,this.ratioColorScale=r,this.backgroundColor=a,this.backgroundRGBString=Hi.rgbColor(a.r,a.g,a.b),this.canvasElement=t.querySelector("canvas"),this.ctx=this.canvasElement.getContext("2d"),this.faSpinnerElement=t.querySelector(".fa-spinner"),this.spinnerCount=0,this.xGuideElement=t.querySelector("div[id$='-x-guide']"),this.yGuideElement=t.querySelector("div[id$='-y-guide']"),this.displayMode="A",this.imageTileCache={},this.imageTileCacheKeys=[],this.imageTileCacheLimit=8,this.colorScaleThresholdCache={},this.browser.eventBus.subscribe("NormalizationChange",this),this.browser.eventBus.subscribe("TrackLoad2D",this),this.browser.eventBus.subscribe("TrackState2D",this),this.browser.eventBus.subscribe("MapLoad",this),this.browser.eventBus.subscribe("ControlMapLoad",this),this.browser.eventBus.subscribe("ColorChange",this),this.drawsInProgress=new Set}setBackgroundColor(e){this.backgroundColor=e,this.backgroundRGBString=Hi.rgbColor(e.r,e.g,e.b),this.update()}stringifyBackgroundColor(){return`${this.backgroundColor.r},${this.backgroundColor.g},${this.backgroundColor.b}`}static parseBackgroundColor(e){const[t,i,n]=e.split(",").map((e=>parseInt(e)));return{r:t,g:i,b:n}}setColorScale(e){switch(this.displayMode){case"AOB":case"BOA":this.ratioColorScale=e;break;case"AMB":this.diffColorScale=e;break;default:this.colorScale=e}this.colorScaleThresholdCache[$x(this.browser.state,this.displayMode)]=e.threshold}async setColorScaleThreshold(e){this.getColorScale().setThreshold(e),this.colorScaleThresholdCache[$x(this.browser.state,this.displayMode)]=e,this.imageTileCache={},await this.update()}getColorScale(){switch(this.displayMode){case"AOB":case"BOA":return this.ratioColorScale;case"AMB":return this.diffColorScale;default:return this.colorScale}}async setDisplayMode(e){this.displayMode=e,this.clearImageCaches(),await this.update()}clearImageCaches(){this.imageTileCache={},this.imageTileCacheKeys=[]}getViewDimensions(){return{width:this.viewportElement.offsetWidth,height:this.viewportElement.offsetHeight}}async receiveEvent(e){"MapLoad"===e.type||"ControlMapLoad"===e.type?(this.mouseHandlersEnabled||(this.addTouchHandlers(this.viewportElement),this.addMouseHandlers(this.viewportElement),this.mouseHandlersEnabled=!0),this.clearImageCaches(),this.colorScaleThresholdCache={}):("LocusChange"!==e.type&&this.clearImageCaches(),this.update())}async update(){this.disableUpdates||(await this.repaint(),this.browser.dataset&&await this.render2DTracks(this.browser.tracks2D,this.browser.dataset,this.browser.state))}async repaint(){if(!this.browser.dataset)return;const e=this.viewportElement.offsetWidth,t=this.viewportElement.offsetHeight,i=this.canvasElement.width,n=this.canvasElement.height;i===e&&n===t||(this.canvasElement.width=e,this.canvasElement.height=t,this.canvasElement.setAttribute("width",e),this.canvasElement.setAttribute("height",t));const{state:o,dataset:r,controlDataset:a}=this.browser;let s,c=r,l=null,h=null,d=o.zoom;switch(this.displayMode){case"B":d=v(o.zoom),c=a;break;case"AOB":case"AMB":s=v(o.zoom),l=a;break;case"BOA":d=v(o.zoom),s=o.zoom,c=a,l=r}const f=(await c.getMatrix(o.chr1,o.chr2)).getZoomDataByIndex(d,"BP");if(l){h=(await l.getMatrix(o.chr1,o.chr2)).getZoomDataByIndex(s,"BP")}const u=Math.max(1,Math.floor(o.pixelSize)),p=e/u,m=t/u,g=Math.floor(o.x/Wx),w=Math.floor((o.x+p)/Wx),F=Math.floor(o.y/Wx),b=Math.floor((o.y+m)/Wx);"NONE"!==o.normalization&&(c.hasNormalizationVector(o.normalization,f.chr1.name,f.zoom.unit,f.zoom.binSize)||(Alert.presentAlert(`Normalization option ${o.normalization} unavailable at this resolution.`),this.browser.eventBus.post(new $C("NormalizationExternalChange","NONE")),o.normalization="NONE")),await this.checkColorScale(c,f,F,b,g,w,o.normalization),this.ctx.clearRect(0,0,e,t);for(let e=F;e<=b;e++)for(let t=g;t<=w;t++){const i=await this.getImageTile(c,l,f,h,e,t,o);i.image&&this.paintTile(i)}function v(e){const t=r.getBinSizeForZoomIndex(e);if(!t)throw new Error(`Invalid zoom (resolution) index: ${e}`);const i=a.getZoomIndexForBinSize(t);if(i<0)throw new Error(`Invalid binSize for "B" map: ${t}`);return i}this.genomicExtent={chr1:o.chr1,chr2:o.chr2,x:o.x*f.zoom.binSize,y:o.y*f.zoom.binSize,w:e*f.zoom.binSize/o.pixelSize,h:t*f.zoom.binSize/o.pixelSize}}async getImageTile(e,t,i,n,o,r,a){const s=`${i.chr1.name}_${i.chr2.name}_${i.zoom.binSize}_${i.zoom.unit}_${o}_${r}_${a.normalization}_${this.displayMode}`;if(this.imageTileCache.hasOwnProperty(s))return this.imageTileCache[s];if(this.drawsInProgress.has(s)){const e=function(e){let t=Zx[e];if(!t){t=document.createElement("canvas"),t.width=e,t.height=e;const i=t.getContext("2d");i.font="24px sans-serif",i.fillStyle="rgb(230, 230, 230)",i.fillRect(0,0,t.width,t.height),i.fillStyle="black";for(let t=100;t0){const e={};if("AOB"===this.displayMode||"BOA"===this.displayMode||"AMB"===this.displayMode)for(let t of C)e[t.getKey()]=t;let t=g.getImageData(0,0,m.width,m.height);const i=h?o*Wx:r*Wx,n=h?r*Wx:o*Wx;for(let a=0;a<_.length;a++){const s=_[a];let p,m=Math.floor(s.bin1-i),g=Math.floor(s.bin2-n);if(h){const e=g;g=m,m=e}switch(this.displayMode){case"AOB":case"BOA":let t=s.getKey(),i=e[t];if(!i)continue;let n=s.counts/d/(i.counts/f);p=this.ratioColorScale.getColor(n);break;case"AMB":if(t=s.getKey(),i=e[t],!i)continue;n=u*(s.counts/d-i.counts/f),p=this.diffColorScale.getColor(n);break;default:p=this.colorScale.getColor(s.counts)}c(t,m,g,p.red,p.green,p.blue,p.alpha),l&&o===r&&c(t,g,m,p.red,p.green,p.blue,p.alpha)}g.putImageData(t,0,0)}0;const x={row:o,column:r,blockBinCount:Wx,image:m};return this.imageTileCacheLimit>0&&(this.imageTileCacheKeys.length>this.imageTileCacheLimit&&(delete this.imageTileCache[this.imageTileCacheKeys[0]],this.imageTileCacheKeys.shift()),this.imageTileCache[s]=x),x}finally{this.drawsInProgress.delete(s),this.stopSpinner()}function c(e,t,i,n,o,r,a){const s=4*(t+i*e.width);e.data[s+0]=n,e.data[s+1]=o,e.data[s+2]=r,e.data[s+3]=a}}async checkColorScale(e,t,i,n,o,r,a){const s=$x(this.browser.state,this.displayMode);if("AOB"===this.displayMode||"BOA"===this.displayMode)return this.ratioColorScale;if(this.colorScaleThresholdCache[s]){const e=this.colorScale.threshold!==this.colorScaleThresholdCache[s];return this.colorScale.setThreshold(this.colorScaleThresholdCache[s]),e&&this.browser.eventBus.post($C("ColorScale",this.colorScale)),this.colorScale}try{const c=Wx*t.zoom.binSize,l=o*c,h=(r-o+1)*c,d={chr:t.chr1.name,start:l,end:l+h},f=i*c,u=(n-i+1)*c,p={chr:t.chr2.name,start:f,end:f+u};let m=function(e,t){const i=e.map((e=>e.counts));i.sort((function(e,t){return e-t}));const n=Math.floor(t/100*e.length);return i[n]}(await e.getContactRecords(a,d,p,t.zoom.unit,t.zoom.binSize,!0),95);return isNaN(m)||(0===t.chr1.index&&(m*=4),this.colorScale=new Vx(this.colorScale),this.colorScale.setThreshold(m),this.computeColorScale=!1,this.browser.eventBus.post($C("ColorScale",this.colorScale)),this.colorScaleThresholdCache[s]=m),this.colorScale}finally{this.stopSpinner()}}async zoomIn(){const e=this.browser.state,t=this.viewportElement.offsetWidth,i=this.viewportElement.offsetHeight,n=(await Kx.call(this,e.chr1,e.chr2))[0];if(n){const o="BP",r=await n.getZoomDataByIndex(e.zoom,o),a={x:e.x*r.zoom.binSize,y:e.y*r.zoom.binSize,w:t*r.zoom.binSize/e.pixelSize,h:i*r.zoom.binSize/e.pixelSize};if(a.w>this.genomicExtent.w)return;const s=(a.x-this.genomicExtent.x)/this.genomicExtent.w*t,c=(a.y-this.genomicExtent.y)/this.genomicExtent.w*i,l=a.w/this.genomicExtent.w*t,h=a.h/this.genomicExtent.h*i,d=this.canvasElement,f=document.createElement("canvas");f.width=d.width,f.height=d.height;f.getContext("2d").drawImage(d,s,c,l,h,0,0,t,i),this.ctx.clearRect(0,0,t,i),this.ctx.drawImage(f,0,0)}}paintTile({image:e,row:t,column:i,blockBinCount:n}){const o=n*i,r=n*t,{x:a,y:s,pixelSize:c}=this.browser.state,l=(o-a)*c,h=(r-s)*c,d=c,f=e.width*d,u=e.height*d;l<=this.viewportElement.offsetWidth&&l+f>=0&&h<=this.viewportElement.offsetHeight&&h+u>=0&&(this.ctx.fillStyle=this.backgroundRGBString,this.ctx.fillRect(l,h,f,u),1===d?this.ctx.drawImage(e,l,h):this.ctx.drawImage(e,l,h,f,u))}startSpinner(){this.browser.isLoadingHICFile&&this.browser.userInteractionShield&&(this.browser.userInteractionShield.style.display="block"),this.faSpinnerElement.style.display="inline-block",this.spinnerCount++}stopSpinner(){this.spinnerCount--,0===this.spinnerCount&&(this.faSpinnerElement.style.display="none"),this.spinnerCount=Math.max(0,this.spinnerCount)}addMouseHandlers(e){let t,i,n,o=0,r=0,a=0,s=0,c=!1,l=!1;const h=()=>{this.isDragging&&(this.isDragging=!1,this.browser.eventBus.post($C("DragStopped"))),c=!1,t=i=void 0};this.isDragging=!1,this.browser.isMobile||(e.addEventListener("mousedown",(n=>{if(n.preventDefault(),n.stopPropagation(),"block"===this.browser.menuElement?.style.display&&this.browser.hideMenu(),i={x:n.offsetX,y:n.offsetY},t={x:n.offsetX,y:n.offsetY},n.altKey){l=!0;const{top:t,left:i}=e.getBoundingClientRect();o=n.clientX-i,r=n.clientY-t,this.sweepZoom.initialize(o,r)}c=!0})),e.addEventListener("mousemove",(n=>{n.preventDefault(),n.stopPropagation();const h={x:n.offsetX,y:n.offsetY},{top:d,left:f}=function(e){const{top:t,left:i}=e.getBoundingClientRect();return{top:t+window.scrollY,left:i+window.scrollX}}(e),u={x:n.pageX-f,y:n.pageY-d},{width:p,height:m}=e.getBoundingClientRect();if(u.xNormalized=u.x/p,u.yNormalized=u.y/m,this.browser.eventBus.post($C("UpdateContactMapMousePosition",u,!1)),this.willShowCrosshairs&&(this.browser.updateCrosshairs(u),this.browser.showCrosshairs()),c){if(l){const{left:t,top:i}=e.getBoundingClientRect();a=n.clientX-t,s=n.clientY-i;const c=Math.abs(a-o),l=Math.abs(s-r),h={left:`${Math.min(o,a)}px`,top:`${Math.min(r,s)}px`,width:`${c}px`,height:`${l}px`};this.sweepZoom.update(h)}else if(t.x&&Math.abs(h.x-t.x)>2){this.isDragging=!0;const e=i.x-h.x,t=i.y-h.y;this.browser.shiftPixels(e,t)}i=h}})),e.addEventListener("mouseup",h),e.addEventListener("dblclick",(e=>{e.preventDefault(),e.stopPropagation();const t=e.offsetX,i=e.offsetY;this.browser.zoomAndCenter(1,t,i)})),e.addEventListener("mouseover",(()=>n=!0)),e.addEventListener("mouseout",(()=>n=void 0)),e.addEventListener("mouseleave",(()=>{this.browser.layoutController.xAxisRuler.unhighlightWholeChromosome(),this.browser.layoutController.yAxisRuler.unhighlightWholeChromosome(),h()})),document.addEventListener("keydown",(e=>{!this.willShowCrosshairs&&n&&e.shiftKey&&(this.willShowCrosshairs=!0,this.browser.eventBus.post($C("DidShowCrosshairs","DidShowCrosshairs",!1)))})),document.addEventListener("keyup",(()=>{this.browser.hideCrosshairs(),this.willShowCrosshairs=void 0,this.browser.eventBus.post($C("DidHideCrosshairs","DidHideCrosshairs",!1))})),document.addEventListener("mouseup",(e=>{if(e.preventDefault(),e.stopPropagation(),l){l=!1;const e={xPixel:Math.min(o,a),yPixel:Math.min(r,s),width:Math.abs(a-o),height:Math.abs(s-r)};this.sweepZoom.commit(e)}})))}addTouchHandlers(e){let t,i;const n=(e,t)=>{const i=t.getBoundingClientRect();return{x:e.pageX-i.left,y:e.pageY-i.top}};e.ontouchstart=i=>{i.preventDefault(),i.stopPropagation();let o=n(i.targetTouches[0],e),r=o.x,a=o.y;const s=i.targetTouches.length,c=i.timeStamp||Date.now();let l=!1;if(2===s&&(o=n(i.targetTouches[1],e),r=(r+o.x)/2,a=(a+o.y)/2),t&&c-t.timeStamp<300&&s>1&&1===t.count)t={x:r,y:a,timeStamp:c,count:s};else{if(t&&c-t.timeStamp<300){const e=t.x-r,i=t.y-a,n=Math.hypot(e,i),o=2===t.count||2===s?-1:1;n<20&&(this.browser.zoomAndCenter(o,r,a),t=void 0,l=!0)}l||(t={x:r,y:a,timeStamp:c,count:s})}},e.ontouchmove=function(e,t,i){var n,o;return t||(t=200),function(){var r,a,s;r=i||this,a=+new Date,s=arguments,n&&a{if(o.preventDefault(),o.stopPropagation(),2===o.targetTouches.length){const t=n(o.targetTouches[0],e),r=n(o.targetTouches[1],e),a={x1:t.x,y1:t.y,x2:r.x,y2:r.y};i?i.end=a:i={start:a}}else{const i=n(o.targetTouches[0],e),r=i.x,a=i.y;if(t){const e=t.x-r,i=t.y-a;isNaN(e)||isNaN(i)||(this.isDragging=!0,this.browser.shiftPixels(e,i))}t={x:r,y:a,timeStamp:o.timeStamp||Date.now(),count:o.targetTouches.length}}}),50),e.ontouchend=e=>{if(e.preventDefault(),e.stopPropagation(),i&&i.end){const{start:e,end:n}=i,o=e.x2-e.x1,r=e.y2-e.y1,a=n.x2-n.x1,s=n.y2-n.y1,c=Math.hypot(o,r),l=Math.hypot(a,s)/c,h=(e.x1+e.x2)/2,d=(e.y1+e.y2)/2;(l<.8||l>1.2)&&(t=void 0,this.browser.pinchZoom(h,d,l))}else this.isDragging&&(this.isDragging=!1,this.browser.eventBus.post($C("DragStopped")));i=void 0}}async render2DTracks(e,t,i){const n=(await t.getMatrix(i.chr1,i.chr2)).getZoomDataByIndex(i.zoom,"BP"),{width:o,height:r}=this.getViewDimensions(),a=n.zoom.binSize/i.pixelSize,{xStartBP:s,yStartBP:c,xEndBP:l,yEndBP:h}=function(e,t,i,n,o){const r=o*t.pixelSize,a=1+Math.round(t.x*r),s=1+Math.round(t.y*r),c=e.chromosomes[t.chr1],l=e.chromosomes[t.chr2],h=Math.round(o*i),d=Math.round(o*n);return{xStartBP:a,yStartBP:s,xEndBP:Math.min(c.size,h+a-1),yEndBP:Math.min(l.size,d+s-1),chromosome1:c,chromosome2:l,pixelSize:t.pixelSize}}(t,i,o,r,a);n.chr1.name,n.chr2.name,n.chr1.index,n.chr2.index,this.ctx.save(),this.ctx.lineWidth=2;const d=(e,t,i,n)=>{if(tl||nh);else{const o=Math.max(1,(t-e)/a),r=Math.max(1,(n-i)/a),l=Math.floor((e-s)/a),h=Math.floor((i-c)/a);this.ctx.strokeRect(l,h,o,r)}},f=(e,t)=>{for(const{chr1:i,x1:n,x2:o,y1:r,y2:a,color:s}of t)this.ctx.strokeStyle=e.color||s,d(n,o,r,a)},u=(e,t)=>{for(const{chr1:i,x1:n,x2:o,y1:r,y2:a,color:s}of t)this.ctx.strokeStyle=e.color||s,d(r,a,n,o)};for(const t of e){if(!1===t.isVisible)continue;const e=t.getFeatures(n.chr1.name,n.chr1.name);e&&("COLLAPSED"===t.displayMode||void 0===t.displayMode?(f(t,e),u(t,e)):"lower"===t.displayMode?f(t,e):"upper"===t.displayMode&&u(t,e))}this.ctx.restore()}}function $x(e,t){return e.chr1+"_"+e.chr2+"_"+e.zoom+"_"+e.normalization+"_"+t}Gx.defaultBackgroundColor={r:255,g:255,b:255};const Zx={};function Kx(e,t){var i=[];return"B"===this.displayMode&&this.browser.controlDataset?i.push(this.browser.controlDataset.getMatrix(e,t)):(i.push(this.browser.dataset.getMatrix(e,t)),this.displayMode&&"A"!==this.displayMode&&this.browser.controlDataset&&i.push(this.browser.controlDataset.getMatrix(e,t))),Promise.all(i)}class Xx{constructor(e,t){this.browser=e;const i=t.querySelector("div[id$='lower-hic-nav-bar-widget-container']");this.container=document.createElement("div"),this.container.className="hic-colorscale-widget-container",i.appendChild(this.container);const{r:n,g:o,b:r}=Gx.defaultBackgroundColor;this.mapBackgroundColorpickerButton=tk(Hi.rgbColor(n,o,r)),this.container.appendChild(this.mapBackgroundColorpickerButton),this.backgroundColorpicker=Jx(e,this.mapBackgroundColorpickerButton);const{r:a,g:s,b:c}=Ux.negative;this.minusButton=tk(Hi.rgbColor(a,s,c)),this.container.appendChild(this.minusButton),this.minusColorPicker=Jx(e,this.minusButton,"-"),this.minusButton.style.display="none";const{r:l,g:h,b:d}=Ux.positive;this.plusButton=tk(Hi.rgbColor(l,h,d)),this.container.appendChild(this.plusButton),this.plusColorPicker=Jx(e,this.plusButton,"+"),this.minusButton.addEventListener("click",(()=>ek(this.minusColorPicker,this.plusColorPicker,this.backgroundColorpicker))),this.plusButton.addEventListener("click",(()=>ek(this.plusColorPicker,this.minusColorPicker,this.backgroundColorpicker))),this.mapBackgroundColorpickerButton.addEventListener("click",(()=>ek(this.backgroundColorpicker,this.minusColorPicker,this.plusColorPicker))),this.highColorscaleInput=document.createElement("input"),this.highColorscaleInput.type="text",this.highColorscaleInput.title="color scale input",this.container.appendChild(this.highColorscaleInput),this.highColorscaleInput.addEventListener("change",(t=>{const i=t.target.value.split(",").join().replace(",","","g");isNaN(i)||e.setColorScaleThreshold(i)}));const f=ik("fa-minus","negative threshold",(()=>this.highColorscaleInput.value=Qx(e,.5)));this.container.appendChild(f);const u=ik("fa-plus","positive threshold",(()=>this.highColorscaleInput.value=Qx(e,2)));this.container.appendChild(u),e.eventBus.subscribe("ColorScale",(e=>{e.data instanceof Vx?(this.highColorscaleInput.value=e.data.threshold,Yx(this.plusButton,e.data)):e.data instanceof jx&&(this.highColorscaleInput.value=e.data.threshold,Yx(this.minusButton,e.data.negativeScale),Yx(this.plusButton,e.data.positiveScale))})),e.eventBus.subscribe("DisplayMode",(t=>{"AOB"===t.data||"BOA"===t.data?(this.minusButton.style.display="block",Yx(this.minusButton,e.contactMatrixView.ratioColorScale.negativeScale),Yx(this.plusButton,e.contactMatrixView.ratioColorScale.positiveScale)):(this.minusButton.style.display="none",Yx(this.plusButton,e.contactMatrixView.colorScale))})),e.eventBus.subscribe("MapLoad",(()=>{Yx(this.mapBackgroundColorpickerButton,e.contactMatrixView.backgroundColor)}))}}function Yx(e,{r:t,g:i,b:n}){e.style.backgroundColor=Hi.rgbToHex(Hi.rgbColor(t,i,n))}function Qx(e,i){const n=e.getColorScale();return e.setColorScaleThreshold(n.getThreshold()*i),t(n.getThreshold())}function Jx(e,t,i){let n,o;if(i)n=[Ux.negative,Ux.positive].map((({r:e,g:t,b:i})=>Hi.rgbToHex(Hi.rgbColor(e,t,i)))),o=n=>{t.style.backgroundColor=n;const o=Hi.hexToRgb(n),[r,a,s]=XC(o);e.getColorScale().setColorComponents({r:r,g:a,b:s},i),e.repaintMatrix()};else{const{r:i,g:r,b:a}=Gx.defaultBackgroundColor;n=[Hi.rgbToHex(Hi.rgbColor(i,r,a))],o=i=>{t.style.backgroundColor=i;const n=Hi.hexToRgb(i),[o,r,a]=XC(n);e.contactMatrixView.setBackgroundColor({r:o,g:r,b:a})}}return new _C({parent:t,top:64,left:64,width:432,defaultColors:n,colorHandler:o})}function ek(e,t,i){t.hide(),i.hide(),e.show()}function tk(e){const t=iC.div({class:"igv-ui-color-swatch"});return t.style.backgroundColor=Hi.rgbToHex(e),t}function ik(e,t,i){const n=document.createElement("i");return n.className=`fa ${e}`,n.title=t,n.addEventListener("click",i),n}class nk{constructor(e,t){this.browser=e;const i=t.querySelector("div[id$='lower-hic-nav-bar-widget-container']");this.container=document.createElement("div"),this.container.className="hic-control-map-selector-container",this.container.style.display="none",i.appendChild(this.container),this.select=document.createElement("select"),this.select.name="control_map_selector",this.container.appendChild(this.select);const n=document.createElement("div");this.container.appendChild(n);const o=document.createElement("div");this.container.appendChild(o),this.controlMapHash=new ok(e,this.select,n,o,function(){const e=document.createElement("div");return e.innerHTML="...",e}(),function(){const e=document.createElement("div");return e.innerHTML="...",e}()),e.eventBus.subscribe("ControlMapLoad",(()=>{this.controlMapHash.updateOptions(e.getDisplayMode()),this.container.style.display="block"})),e.eventBus.subscribe("MapLoad",(()=>{e.controlDataset||(this.container.style.display="none")})),e.eventBus.subscribe("DisplayMode",(e=>{this.controlMapHash.updateOptions(e.data)}))}toggleDisplayMode(){this.controlMapHash.toggleDisplayMode()}toggleDisplayModeCycle(){this.controlMapHash.toggleDisplayModeCycle()}getDisplayModeCycle(){return this.controlMapHash.cycleID}}class ok{constructor(e,t,i,n,o,r){this.browser=e,this.select=t,this.toggle=i,this.cycle=n,this.imgA=o,this.toggle.appendChild(this.imgA),this.imgB=r,this.toggle.appendChild(this.imgB),this.hash={A:{title:"A",value:"A",other:"B",hidden:this.imgB,shown:this.imgA},B:{title:"B",value:"B",other:"A",hidden:this.imgA,shown:this.imgB},AOB:{title:"A/B",value:"AOB",other:"BOA",hidden:this.imgB,shown:this.imgA},BOA:{title:"B/A",value:"BOA",other:"AOB",hidden:this.imgA,shown:this.imgB}},this.select.addEventListener("change",(e=>{this.disableDisplayModeCycle(),this.setDisplayMode(e.target.value)})),this.toggle.addEventListener("click",(()=>{this.disableDisplayModeCycle(),this.toggleDisplayMode()})),this.cycleOutline=function(){const e=document.createElement("div");return e.innerHTML="...",e}(),n.appendChild(this.cycleOutline),this.cycleSolid=function(){const e=document.createElement("div");return e.innerHTML="...",e}(),n.appendChild(this.cycleSolid),this.cycleSolid.style.display="none",n.addEventListener("click",(()=>{this.toggleDisplayModeCycle()})),n.style.display="none"}disableDisplayModeCycle(){this.cycleID&&(clearTimeout(this.cycleID),this.cycleID=void 0,this.cycleSolid.style.display="none",this.cycleOutline.style.display="block")}toggleDisplayModeCycle(){this.cycleID?this.disableDisplayModeCycle():(this.doToggle(),this.cycleSolid.style.display="block",this.cycleOutline.style.display="none")}async doToggle(){this.cycleID=setTimeout((async()=>{await this.toggleDisplayMode(),this.doToggle()}),2500)}async toggleDisplayMode(){const e=this.browser.getDisplayMode(),t=this.hash[e].other;await this.browser.setDisplayMode(t),this.hash[t].hidden.style.display="none",this.hash[t].shown.style.display="block",this.select.value=t}setDisplayMode(e){this.hash[e].hidden.style.display="none",this.hash[e].shown.style.display="block",this.browser.setDisplayMode(e)}updateOptions(e){this.imgA.style.display="none",this.imgB.style.display="none",this.select.innerHTML="",Object.keys(this.hash).forEach((t=>{const i=this.hash[t],n=document.createElement("option");n.value=i.value,n.textContent=i.title,e===i.value&&(n.selected=!0,i.shown.style.display="block"),this.select.appendChild(n)}))}}class rk{constructor(e,t){this.browser=e;const i=t.querySelector("div[id$='lower-hic-nav-bar-widget-container']");this.container=document.createElement("div"),this.container.className="hic-normalization-selector-container",this.container.title="Normalization",i.appendChild(this.container);let n=document.createElement("div");n.textContent="Norm",this.container.appendChild(n),this.normalizationSelector=document.createElement("select"),this.normalizationSelector.name="normalization_selector",this.normalizationSelector.addEventListener("change",(()=>{this.browser.setNormalization(this.normalizationSelector.value)})),this.container.appendChild(this.normalizationSelector),this.spinner=document.createElement("div"),this.spinner.textContent="Loading ...",this.container.appendChild(this.spinner),this.spinner.style.display="none",this.browser.eventBus.subscribe("MapLoad",this),this.browser.eventBus.subscribe("NormVectorIndexLoad",this),this.browser.eventBus.subscribe("NormalizationFileLoad",this),this.browser.eventBus.subscribe("NormalizationExternalChange",this)}startNotReady(){this.normalizationSelector.style.display="none",this.spinner.style.display="block"}stopNotReady(){this.spinner.style.display="none",this.normalizationSelector.style.display="block"}receiveEvent(e){"NormVectorIndexLoad"===e.type?(this.updateOptions(),this.stopNotReady()):"NormalizationFileLoad"===e.type?"start"===e.data?this.startNotReady():this.stopNotReady():"NormalizationExternalChange"===e.type&&Array.from(this.normalizationSelector.options).forEach((t=>{t.selected=t.value===e.data}))}async updateOptions(){const e={NONE:"None",VC:"Coverage",VC_SQRT:"Coverage - Sqrt",KR:"Balanced",INTER_VC:"Interchromosomal Coverage",INTER_VC_SQRT:"Interchromosomal Coverage - Sqrt",INTER_KR:"Interchromosomal Balanced",GW_VC:"Genome-wide Coverage",GW_VC_SQRT:"Genome-wide Coverage - Sqrt",GW_KR:"Genome-wide Balanced"},t=this.browser.state.normalization,i=await this.browser.getNormalizationOptions();i&&(this.normalizationSelector.innerHTML="",i.forEach((i=>{const n=document.createElement("option");n.value=i,n.textContent=e[i]||i,t===i&&(n.selected=!0),this.normalizationSelector.appendChild(n)})))}}class ak{constructor(e,t){this.browser=e,this.targetElement=t,this.rulerSweeperElement=t.querySelector("div[id$='-sweep-zoom-container']"),this.rulerSweeperElement.style.display="none",this.sweepRect={}}initialize(e,t){this.rulerSweeperElement.style.left=`${e}px`,this.rulerSweeperElement.style.top=`${t}px`,this.rulerSweeperElement.style.width="0px",this.rulerSweeperElement.style.height="0px",this.rulerSweeperElement.style.display="block"}update({left:e,top:t,width:i,height:n}){this.rulerSweeperElement.style.width=i,this.rulerSweeperElement.style.height=n,this.rulerSweeperElement.style.left=e,this.rulerSweeperElement.style.top=t}commit({xPixel:e,yPixel:t,width:i,height:n}){this.rulerSweeperElement.style.display="none";const{x:o,y:r,locus:a,zoom:s,pixelSize:c}=this.browser.state,l=this.browser.dataset.bpResolutions[s],h=(o+e/c)*l,d=(r+t/c)*l,f=i/c*l,u=n/c*l;this.browser.goto(a.x.chr,Math.round(h),Math.round(h+f),a.y.chr,Math.round(d),Math.round(d+u))}}class sk{constructor(e,t,i){this.browser=e,this.isDragging=!1,this.xAxisScrollbarContainerElement=t,this.xAxisScrollbarElement=t.querySelector("div[id$='-x-axis-scrollbar']"),this.xLabelElement=this.xAxisScrollbarElement.querySelector("div"),this.xLabelElement.textContent="",this.yAxisScrollbarContainerElement=i,this.yAxisScrollbarElement=i.querySelector("div[id$='-y-axis-scrollbar']"),this.yLabelElement=this.yAxisScrollbarElement.querySelector(".scrollbar-label-rotation-in-place"),this.yLabelElement.textContent="",this.browser.eventBus.subscribe("LocusChange",this)}receiveEvent(e){if(!this.isDragging&&"LocusChange"===e.type){const{state:t}=e.data,{dataset:i}=this.browser;if(0===t.chr1)this.xAxisScrollbarElement.style.display="none",this.yAxisScrollbarElement.style.display="none";else{this.xAxisScrollbarElement.style.display="block",this.yAxisScrollbarElement.style.display="block",this.xAxisScrollbarContainerElement.style.display="block",this.yAxisScrollbarContainerElement.style.display="block";const{chr1:e,chr2:n,zoom:o,pixelSize:r,x:a,y:s}=t,c=[e,n].map((e=>i.chromosomes[e].size/i.bpResolutions[o])),l=c.map((e=>e*r)),{width:h,height:d}=this.browser.contactMatrixView.getViewDimensions(),f=[h,d],u=f.map((e=>e/r)).map(((e,t)=>{const i=Math.min(e,c[t])/c[t],n=Math.min(l[t],f[t])/f[t];return Math.max(1,Math.round(100*i*n))}));this.xAxisScrollbarElement.style.width=`${u[0]}%`,this.yAxisScrollbarElement.style.height=`${u[1]}%`;const p=Math.round(100*a/c[0]);this.xAxisScrollbarElement.style.left=`${p}%`;const m=Math.round(100*s/c[1]);this.yAxisScrollbarElement.style.top=`${m}%`,this.xLabelElement.textContent=i.chromosomes[e].name,this.yLabelElement.textContent=i.chromosomes[n].name}}}}class ck{constructor(e,t){this.browser=e,this.container=t,this.xAxisSelector=t.querySelector("select[name='x-axis-selector']"),this.yAxisSelector=t.querySelector("select[name='y-axis-selector']"),this.initialize()}initialize(){this.xAxisSelector.addEventListener("change",(()=>this.syncSelectors(this.xAxisSelector,this.yAxisSelector))),this.yAxisSelector.addEventListener("change",(()=>this.syncSelectors(this.yAxisSelector,this.xAxisSelector)));const e=this.yAxisSelector.nextElementSibling;e&&e.addEventListener("click",(async()=>{const e=this.browser.dataset.chromosomes[parseInt(this.xAxisSelector.value,10)],t=this.browser.dataset.chromosomes[parseInt(this.yAxisSelector.value,10)],i=this.browser.parseLocusString(e.name),n=this.browser.parseLocusString(t.name);await this.browser.setChromosomes(i,n)})),this.browser.eventBus.subscribe("MapLoad",(e=>{this.respondToDataLoadWithDataset(e.data)})),this.browser.eventBus.subscribe("LocusChange",(e=>{this.respondToLocusChangeWithState(e.data.state)}))}syncSelectors(e,t){const i=e.value;0!==parseInt(i,10)&&0!==parseInt(t.value,10)||(t.value=i)}respondToDataLoadWithDataset(e){const{chromosomes:t}=e,i=t.map((({name:e},t)=>``)).join("");this.xAxisSelector.innerHTML=i,this.yAxisSelector.innerHTML=i,this.xAxisSelector.value=this.browser.state.chr1,this.yAxisSelector.value=this.browser.state.chr2}respondToLocusChangeWithState(e){this.xAxisSelector.options.length&&this.yAxisSelector.options.length&&(this.xAxisSelector.value=e.chr1,this.yAxisSelector.value=e.chr2)}}class lk{constructor(e,t,{title:i,alertMessage:n},o){this.browser=e,this.trackListRetrievalCallback=o,this.annotationPresentationButton(t,n),this.annotationPanel(e.rootElement,i)}updateBody(e){if(this.annotationPanelElement.querySelectorAll(".hic-annotation-row-container").forEach((e=>e.remove())),e[0]instanceof SC)for(let t=e.length-1;t>=0;t--)this.annotationPanelRow(this.annotationPanelElement,e[t]);else for(const t of e)this.annotationPanelRow(this.annotationPanelElement,t)}annotationPresentationButton(e,t){e.querySelector("button").addEventListener("click",(()=>{this.trackListRetrievalCallback().length>0?(this.updateBody(this.trackListRetrievalCallback()),this.annotationPanelElement.style.display="none"===this.annotationPanelElement.style.display?"flex":"none"):FC.presentAlert(t),this.browser.hideMenu()}))}annotationPanel(e,t){this.annotationPanelElement=document.createElement("div"),this.annotationPanelElement.className="hic-annotation-panel-container",e.appendChild(this.annotationPanelElement);const i=document.createElement("div");i.className="hic-annotation-panel-header",this.annotationPanelElement.appendChild(i);const n=document.createElement("div");n.textContent=t,i.appendChild(n);const o=document.createElement("div");o.className="hic-menu-close-button",i.appendChild(o);const r=document.createElement("i");r.className="fa fa-times",o.appendChild(r),r.addEventListener("click",(()=>{this.annotationPanelElement.style.display="none"===this.annotationPanelElement.style.display?"flex":"none"})),hC(this.annotationPanelElement,i),this.annotationPanelElement.style.display="none"}annotationPanelRow(e,t){const i=t instanceof SC,n=this.trackListRetrievalCallback();let o;!1===i&&(o=t.x.track.trackView);const r=document.createElement("div");r.className="hic-annotation-row-container",e.appendChild(r);const a=document.createElement("div");a.className="hic-annotation-modal-row",r.appendChild(a);const s=document.createElement("div");if(s.textContent=i?t.config.name:t.x.track.config.name,a.appendChild(s),i){const e=document.createElement("i");e.className=t.isVisible?"fa fa-eye fa-lg":"fa fa-eye-slash fa-lg",a.appendChild(e),e.addEventListener("click",(()=>{t.isVisible=!t.isVisible,e.className=t.isVisible?"fa fa-eye fa-lg":"fa fa-eye-slash fa-lg",this.browser.contactMatrixView.clearImageCaches(),this.browser.contactMatrixView.update()}))}if(i){const e=document.createElement("div");switch(e.className="matrix-diagonal-widget-container",t.displayMode){case"lower":e.classList.add("matrix-diagonal-widget-lower");break;case"upper":e.classList.add("matrix-diagonal-widget-upper");break;default:e.classList.add("matrix-diagonal-widget-all")}e.addEventListener("click",(()=>{this.displayModeHandler(e,t),this.browser.contactMatrixView.clearImageCaches(),this.browser.contactMatrixView.update()})),a.appendChild(e)}const c=function(e,t,i){const n=document.createElement("div");n.className="hic-color-swatch-container",e.appendChild(n),t&&t.width&&(n.style.width=`${t.width}px`);t&&t.height&&(n.style.height=`${t.height}px`);const o=document.createElement("div");n.appendChild(o);const r=document.createElement("i");return r.className="fa fa-times",o.appendChild(r),r.addEventListener("click",(()=>{i()})),n}(r,{width:698},(()=>{const e=a.nextElementSibling;e&&e.classList.contains("hic-color-swatch-container")&&(e.style.display="none"===e.style.display?"flex":"none")})),l=this.annotationColorSwatch(i?t.getColor():t.x.track.color);a.appendChild(l),l.addEventListener("click",(()=>{const e=a.nextElementSibling;e&&e.classList.contains("hic-color-swatch-container")&&(e.style.display="none"===e.style.display?"flex":"none")})),c.style.display="none";CC(c,(e=>{const n=a.querySelector(".fa-square");n&&(n.style.color=e),i?(t.color=e,this.browser.eventBus.post($C("TrackState2D",t))):o.setColor(e)}));const h=document.createElement("div");h.className="up-down-arrow-container",a.appendChild(h);const d=document.createElement("i");d.className="fa fa-arrow-up",d.setAttribute("aria-hidden","true"),h.appendChild(d);const f=document.createElement("i");f.className="fa fa-arrow-down",f.setAttribute("aria-hidden","true"),h.appendChild(f);const u="#f7f7f7";if(1===n.length)d.style.color=u,f.style.color=u;else if(t===n[0]){(i?f:d).style.color=u}else if(t===n[n.length-1]){(i?d:f).style.color=u}const p=n.indexOf(t),m=()=>{const e=n[p+1];n[p+1]=n[p],n[p]=e,i?(this.browser.eventBus.post($C("TrackState2D",n)),this.updateBody(n)):(this.browser.updateLayout(),this.updateBody(n))},g=()=>{const e=n[p-1];n[p-1]=n[p],n[p]=e,i?(this.browser.eventBus.post($C("TrackState2D",n)),this.updateBody(n)):(this.browser.updateLayout(),this.updateBody(n))};d.addEventListener("click",i?m:g),f.addEventListener("click",i?g:m);const w=document.createElement("i");w.className="fa fa-trash-o fa-lg",a.appendChild(w),w.addEventListener("click",(()=>{const e=n.indexOf(t);i?(n.splice(e,1),this.browser.contactMatrixView.clearImageCaches(),this.browser.contactMatrixView.update(),this.browser.eventBus.post($C("TrackLoad2D",n))):this.browser.layoutController.removeTrackXYPair(t.x.track.trackRenderPair),this.updateBody(n)}))}displayModeHandler(e,t){e.classList.contains("matrix-diagonal-widget-all")?(e.classList.replace("matrix-diagonal-widget-all","matrix-diagonal-widget-lower"),t.displayMode="lower"):e.classList.contains("matrix-diagonal-widget-lower")?(e.classList.replace("matrix-diagonal-widget-lower","matrix-diagonal-widget-upper"),t.displayMode="upper"):(e.classList.replace("matrix-diagonal-widget-upper","matrix-diagonal-widget-all"),t.displayMode=void 0)}annotationColorSwatch(e){const t=document.createElement("div");t.className="igv-color-swatch";const i=document.createElement("i");return i.className="fa fa-square fa-lg",i.style.color=e,t.appendChild(i),t}}class hk{constructor(e){this.browser=e,this.components=new Map,this.initializeComponents()}initializeComponents(){const e=this.browser.rootElement.querySelector(".hic-navbar-container");this.components.set("locusGoto",new Ox(this.browser,e)),this.components.set("resolutionSelector",new Px(this.browser,e)),this.getComponent("resolutionSelector").setResolutionLock(this.browser.resolutionLocked),this.components.set("colorScale",new Xx(this.browser,e)),this.components.set("controlMap",new nk(this.browser,e)),this.components.set("normalization",new rk(this.browser,e));const t=this.browser.menuElement.querySelector(".hic-chromosome-selector-widget-container");this.components.set("chromosomeSelector",new ck(this.browser,t));const i=this.browser.menuElement.querySelector(".hic-annotation-presentation-button-container");this.components.set("annotationWidget",new lk(this.browser,i,{title:"2D Annotations",alertMessage:"No 2D annotations currently loaded for this map"},(()=>this.browser.tracks2D)));const n=new ak(this.browser,this.browser.layoutController.getContactMatrixViewport()),o=new sk(this.browser,this.browser.layoutController.getXAxisScrollbarContainer(),this.browser.layoutController.getYAxisScrollbarContainer()),r=new Vx(qx),a=new jx(Ux.threshold);a.setColorComponents(Ux.negative,"-"),a.setColorComponents(Ux.positive,"+"),this.components.set("sweepZoom",n),this.components.set("scrollbar",o),this.components.set("colorScale",r),this.components.set("ratioColorScale",a);const s=this.browser.config.backgroundColor||Gx.defaultBackgroundColor;this.components.set("contactMatrix",new Gx(this.browser,this.browser.layoutController.getContactMatrixViewport(),n,o,r,a,s))}getComponent(e){return this.components.get(e)}}const dk=1,fk=128;class uk{constructor(e,t){var i,n;this.config=t,this.figureMode=t.figureMode||t.miniMode,this.resolutionLocked=!1,this.eventBus=new NC,this.showTrackLabelAndGutter=!0,this.id=`browser_${iC.guid()}`,this.trackPairs=[],this.tracks2D=[],this.normVectorFiles=[],this.synchable=!1!==t.synchable,this.synchedBrowsers=new Set,this.isMobile=/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent),this.rootElement=document.createElement("div"),this.rootElement.className="hic-root unselect",e.appendChild(this.rootElement),t.width&&t.height&&(i=t.width,n=t.height,ix("--hic-viewport-width",i),ix("--hic-viewport-height",n)),this.layoutController=new JC(this,this.rootElement),this.inputDialog=new bC(e,this),this.menuElement=this.createMenu(this.rootElement),this.menuElement.style.display="none",this.ui=new hk(this),this.contactMatrixView=this.ui.getComponent("contactMatrix"),this.userInteractionShield=document.createElement("div"),this.userInteractionShield.className="hic-root-prevent-interaction",this.rootElement.appendChild(this.userInteractionShield),this.userInteractionShield.style.display="none",this.hideCrosshairs()}async init(e){this.pending=new Map,this.eventBus.hold(),this.contactMatrixView.disableUpdates=!0;try{this.contactMatrixView.startSpinner(),this.userInteractionShield.style.display="block",await this.loadHicFile(e,!0),e.controlUrl&&await this.loadHicControlFile({url:e.controlUrl,name:e.controlName,nvi:e.controlNvi,isControl:!0},!0),e.cycle&&(e.displayMode="A"),e.displayMode&&(this.contactMatrixView.displayMode=e.displayMode,this.eventBus.post({type:"DisplayMode",data:e.displayMode})),e.colorScale&&(e.normalization&&(this.state.normalization=e.normalization),this.contactMatrixView.setColorScale(e.colorScale),this.eventBus.post({type:"ColorScale",data:this.contactMatrixView.getColorScale()}));const t=[];if(e.tracks&&t.push(this.loadTracks(e.tracks)),e.normVectorFiles&&e.normVectorFiles.forEach((e=>{t.push(this.loadNormalizationFile(e))})),await Promise.all(t),e.normalization){const t=await this.getNormalizationOptions(),i=new Set(t);this.state.normalization=i.has(e.normalization)?e.normalization:"NONE"}const i=this.contactMatrixView.colorScaleThresholdCache;this.eventBus.release(),this.contactMatrixView.colorScaleThresholdCache=i,e.cycle?this.ui.getComponent("controlMap").toggleDisplayModeCycle():await this.update()}finally{this.contactMatrixView.stopSpinner(),this.userInteractionShield.style.display="none",this.contactMatrixView.disableUpdates=!1,this.contactMatrixView.update()}}createMenu(e){const t='\n ',i=document.createElement("template");i.innerHTML=t.trim();const n=i.content.firstChild;e.appendChild(n);return n.querySelector(".fa-times").addEventListener("click",(()=>this.toggleMenu())),n}toggleTrackLabelAndGutterState(){this.showTrackLabelAndGutter=!this.showTrackLabelAndGutter}toggleMenu(){"flex"===this.menuElement.style.display?this.hideMenu():this.showMenu()}showMenu(){this.menuElement.style.display="flex"}hideMenu(){this.menuElement.style.display="none"}startSpinner(){this.contactMatrixView.startSpinner()}stopSpinner(){this.contactMatrixView.stopSpinner()}async setDisplayMode(e){await this.contactMatrixView.setDisplayMode(e),this.eventBus.post($C("DisplayMode",e))}getDisplayMode(){return this.contactMatrixView?this.contactMatrixView.displayMode:void 0}async getNormalizationOptions(){if(!this.dataset)return[];const e=await this.dataset.getNormalizationOptions();if(this.controlDataset){let t=await this.controlDataset.getNormalizationOptions();return t=new Set(t),e.filter((e=>t.has(e)))}return e}getResolutions(){if(!this.dataset)return[];const e=this.dataset.bpResolutions.map((function(e,t){return{index:t,binSize:e}}));if(this.controlDataset){let t=new Set(this.controlDataset.bpResolutions);return e.filter((e=>t.has(e.binSize)))}return e}isWholeGenome(){return this.dataset&&this.state&&this.dataset.isWholeGenome(this.state.chr1)}getColorScale(){if(this.contactMatrixView)switch(this.getDisplayMode()){case"AOB":case"BOA":return this.contactMatrixView.ratioColorScale;case"AMB":return this.contactMatrixView.diffColorScale;default:return this.contactMatrixView.colorScale}}setColorScaleThreshold(e){this.contactMatrixView.setColorScaleThreshold(e)}updateCrosshairs({x:e,y:t,xNormalized:i,yNormalized:n}){const o=t<0?{left:"0px"}:{top:`${t}px`,left:"0px"};this.contactMatrixView.xGuideElement.style.left=o.left,void 0!==o.top&&(this.contactMatrixView.xGuideElement.style.top=o.top),this.layoutController.xTrackGuideElement.style.left=o.left,void 0!==o.top&&(this.layoutController.xTrackGuideElement.style.top=o.top);const r=e<0?{top:"0px"}:{top:"0px",left:`${e}px`};if(this.contactMatrixView.yGuideElement.style.top=r.top,void 0!==r.left&&(this.contactMatrixView.yGuideElement.style.left=r.left),this.layoutController.yTrackGuideElement.style.top=r.top,void 0!==r.left&&(this.layoutController.yTrackGuideElement.style.left=r.left),this.customCrosshairsHandler){const{x:o,y:r,pixelSize:a}=this.state,s=this.resolution(),c=(o+e/a)*s,l=(r+t/a)*s,{startBP:h,endBP:d}=this.genomicState("x"),{startBP:f,endBP:u}=this.genomicState("y");this.customCrosshairsHandler({xBP:c,yBP:l,startXBP:h,startYBP:f,endXBP:d,endYBP:u,interpolantX:i,interpolantY:n})}}setCustomCrosshairsHandler(e){this.customCrosshairsHandler=e}hideCrosshairs(){this.contactMatrixView.xGuideElement.style.display="none",this.layoutController.xTrackGuideElement.style.display="none",this.contactMatrixView.yGuideElement.style.display="none",this.layoutController.yTrackGuideElement.style.display="none"}showCrosshairs(){this.contactMatrixView.xGuideElement.style.display="block",this.layoutController.xTrackGuideElement.style.display="block",this.contactMatrixView.yGuideElement.style.display="block",this.layoutController.yTrackGuideElement.style.display="block"}genomicState(e){let t=this.contactMatrixView.getViewDimensions().width,i=this.dataset.bpResolutions[this.state.zoom];const n="all"===this.dataset.chromosomes[this.state.chr1].name.toLowerCase()?this.genome.getGenomeLength()/t:i/this.state.pixelSize,o={bpp:n};return"x"===e?(o.chromosome=this.dataset.chromosomes[this.state.chr1],o.startBP=this.state.x*i,o.endBP=o.startBP+n*t):(o.chromosome=this.dataset.chromosomes[this.state.chr2],o.startBP=this.state.y*i,o.endBP=o.startBP+n*this.contactMatrixView.getViewDimensions().height),o}async loadTracks(e){const t=1===e.length?`Error loading track ${e[0].name}`:"Error loading tracks";try{this.contactMatrixView.startSpinner();const t=[],i=[];for(let o of e){const e=ZC(o.url)?o.url.name:o.filename||await n(o.url),r=kC(e);["fasta","fa"].includes(r)&&(o.type=o.format="sequence"),o.format||(o.format=K_.TrackUtils.inferFileFormat(e)),"annotation"===o.type&&(o.displayMode="COLLAPSED","rgb(22, 129, 198)"===o.color&&delete o.color),void 0===o.max&&(o.autoscale=!0);const{trackHeight:a}=nx();if(o.height=a,void 0===o.format||["bedpe","interact"].includes(o.format))i.push(SC.loadTrack2D(o,this.genome));else{const e=await K_.createTrack(o,this);"function"==typeof e.postInit&&await e.postInit(),t.push(e)}}if(t.length>0){this.layoutController.updateLayoutWithTracks(t);const e=document.querySelector(".hic-igv-right-hand-gutter");this.showTrackLabelAndGutter?e.style.display="block":e.style.display="none",await this.updateLayout()}if(i.length>0){const e=await Promise.all(i);e&&e.length>0&&(this.tracks2D=this.tracks2D.concat(e),this.eventBus.post($C("TrackLoad2D",this.tracks2D)))}}catch(e){!function(e,t){const i={401:"Access unauthorized",403:"Access forbidden",404:"Not found"}[t.message]||t.message;FC.presentAlert(`${e}: ${i}`)}(t,e),console.error(e)}finally{this.contactMatrixView.stopSpinner()}}async loadNormalizationFile(e){if(!this.dataset)return;this.eventBus.post($C("NormalizationFileLoad","start"));const t=await this.dataset.hicFile.readNormalizationVectorFile(e,this.dataset.chromosomes);for(let e of t.types)this.dataset.normalizationTypes||(this.dataset.normalizationTypes=[]),this.dataset.normalizationTypes.includes(e)||this.dataset.normalizationTypes.push(e),this.eventBus.post($C("NormVectorIndexLoad",this.dataset));return t}async renderTrackXY(e){try{this.startSpinner(),await e.updateViews()}finally{this.stopSpinner()}}reset(){this.layoutController.removeAllTrackXYPairs(),this.contactMatrixView.clearImageCaches(),this.tracks2D=[],this.tracks=[],this.contactMapLabel.textContent="",this.contactMapLabel.title="",this.controlMapLabel.textContent="",this.controlMapLabel.title="",this.dataset=void 0,this.controlDataset=void 0,this.unsyncSelf()}clearSession(){this.dataset=void 0,this.controlDataset=void 0,this.setDisplayMode("A"),this.unsyncSelf()}unsyncSelf(){const e=Fk();for(let t of e)t.unsync(this)}unsync(e){const t=[...this.synchedBrowsers];this.synchedBrowsers=new Set(t.filter((t=>t!==e)))}async loadHicFile(e,t){if(e.url){this.clearSession();try{this.contactMatrixView.startSpinner(),t||(this.userInteractionShield.style.display="block");const i=QC(e),n=this.controlDataset?"A: ":"";this.contactMapLabel.textContent=n+i,this.contactMapLabel.title=i,e.name=i;const o=e=>{this.eventBus.post($C("NormalizationExternalChange","NONE")),FC.presentAlert(e)};this.dataset=await Mx.loadDataset(Object.assign({alert:o},e)),this.dataset.name=i;const r=this.genome?this.genome.id:void 0;if(this.genome=new Tx(this.dataset.genomeId,this.dataset.chromosomes),this.genome.id!==r&&NC.globalBus.post($C("GenomeChange",this.genome.id)),e.locus?(this.state=Lx.default(e),await this.parseGotoInput(e.locus)):e.state?"string"==typeof e.state?await this.setState(Lx.parse(e.state)):"object"==typeof e.state?await this.setState(Lx.fromJSON(e.state)):(alert("config.state is of unknown type"),console.error("config.state is of unknown type")):e.synchState&&this.canBeSynched(e.synchState)?await this.syncState(e.synchState):await this.setState(Lx.default(e)),this.eventBus.post($C("MapLoad",this.dataset)),!e.nvi&&"string"==typeof e.url){const t=new URL(e.url),i=encodeURIComponent(t.hostname+t.pathname);Hx.hasOwnProperty(i)&&(e.nvi=Hx[i])}e.nvi?(await this.dataset.getNormVectorIndex(e),this.eventBus.post($C("NormVectorIndexLoad",this.dataset))):this.dataset.getNormVectorIndex(e).then((t=>{e.isControl||this.eventBus.post($C("NormVectorIndexLoad",this.dataset))})),wk();const a=Fk().filter((e=>e!==this&&e.dataset&&e.dataset.isCompatible(this.dataset)));a.length>0&&await this.syncState(a[0].getSyncState())}catch(t){throw this.contactMapLabel.textContent="",this.contactMapLabel.title="",e.name=name,t}finally{this.stopSpinner(),t||(this.userInteractionShield.style.display="none")}}else console.log("No .hic url specified")}async loadHicControlFile(e,t){try{this.userInteractionShield.style.display="block",this.contactMatrixView.startSpinner(),this.controlUrl=e.url;const i=QC(e);e.name=i;const n=e=>{this.eventBus.post($C("NormalizationExternalChange","NONE")),FC.presentAlert(e)},o=await Mx.loadDataset(Object.assign({alert:n},e));o.name=i,!this.dataset||this.dataset.isCompatible(o)?(this.controlDataset=o,this.dataset&&(this.contactMapLabel.textContent="A: "+this.dataset.name),this.controlMapLabel.textContent="B: "+o.name,this.controlMapLabel.title=o.name,await o.getNormVectorIndex(e),this.eventBus.post($C("ControlMapLoad",this.controlDataset)),t||this.update()):FC.presentAlert('"B" map genome ('+o.genomeId+') does not match "A" map genome ('+this.genome.id+")")}finally{this.userInteractionShield.style.display="none",this.stopSpinner()}}async parseGotoInput(e){const t=e.trim().split(" ");let i=this.parseLocusString(t[0])||await this.lookupFeatureOrGene(t[0]);if(!i)return console.error(`No feature found with name ${t[0]}`),void alert(`No feature found with name ${t[0]}`);let n=t[1]?this.parseLocusString(t[1]):{...i};n||(n={...i}),i.wholeChr&&n.wholeChr||"All"===i.chr&&"All"===n.chr?await this.setChromosomes(i,n):this.goto(i.chr,i.start,i.end,n.chr,n.start,n.end)}parseLocusString(e){const[t,i]=e.trim().toLowerCase().split(":"),n=this.genome.getChromosome(t);if(!n)return;const o={chr:n.name,wholeChr:void 0===i&&"All"!==n.name};if(!0===o.wholeChr||"All"===n.name)o.start=0,o.end=n.size;else{const[e,t]=i.split("-").map((e=>e.replace(/,/g,"")));o.start=isNaN(e)?void 0:parseInt(e,10)-1,o.end=isNaN(t)?void 0:parseInt(t,10)}return o}async lookupFeatureOrGene(e){const t=e.trim(),i=t.toUpperCase();if(this.genome.featureDB.has(i)){EC.selectedGene=t,this.state.selectedGene=EC.selectedGene;const{chr:e,start:n,end:o}=this.genome.featureDB.get(i);return this.parseLocusString(`${e}:${n+1}-${o}`)}const n=await Bx(this.genome.id,t);if(n)return EC.selectedGene=t,this.state.selectedGene=EC.selectedGene,this.parseLocusString(n)}goto(e,t,i,n,o,r){const{width:a,height:s}=this.contactMatrixView.getViewDimensions(),{chrChanged:c,resolutionChanged:l}=this.state.updateWithLoci(e,t,i,n,o,r,this,a,s);this.contactMatrixView.clearImageCaches(),this.update($C("LocusChange",{state:this.state,resolutionChanged:l,chrChanged:c}))}findMatchingZoomIndex(e,t){const i=t.length>0&&void 0!==t[0].index;for(let n=t.length-1;n>0;n--){const o=i?t[n].binSize:t[n],r=i?t[n].index:n;if(o>=e)return r}return 0}async pinchZoom(e,t,i){if(0===this.state.chr1)await this.zoomAndCenter(1,e,t);else try{this.startSpinner();const n=this.getResolutions(),o=n[this.state.zoom];let r,a,s,c;if(this.resolutionLocked||this.state.zoom===n.length-1&&i>1||0===this.state.zoom&&i<1)r=o.binSize,s=Math.min(fk,this.state.pixelSize*i),a=this.state.zoom,c=!1;else{const e=o.binSize/this.state.pixelSize/i;a=this.findMatchingZoomIndex(e,n),r=n[a].binSize,c=a!==this.state.zoom,s=Math.min(fk,r/e)}const l=await this.minZoom(this.state.chr1,this.state.chr2);if(!this.resolutionLocked&&i<1&&a0){const e=t*this.dataset.wholeGenomeResolution/this.state.pixelSize,n=i*this.dataset.wholeGenomeResolution/this.state.pixelSize,o=this.genome.getChromosomeForCoordinate(e),r=this.genome.getChromosomeForCoordinate(n),a={chr:o.name,start:0,end:o.size,wholeChr:!0},s={chr:r.name,start:0,end:r.size,wholeChr:!0};await this.setChromosomes(a,s)}else{const{width:n,height:o}=this.contactMatrixView.getViewDimensions(),r=void 0===t?0:t-n/2;this.state.x+=r/this.state.pixelSize;const a=void 0===i?0:i-o/2;this.state.y+=a/this.state.pixelSize;const s=this.getResolutions(),c=e>0&&this.state.zoom===s[s.length-1].index,l=e<0&&this.state.zoom===s[0].index;if(this.resolutionLocked||c||l){const t=await this.minPixelSize(this.state.chr1,this.state.chr2,this.state.zoom),i=Math.max(Math.min(fk,this.state.pixelSize*(e>0?2:.5)),t),r=(i-this.state.pixelSize)/i;this.state.pixelSize=i,this.state.x+=r*(n/this.state.pixelSize),this.state.y+=r*(o/this.state.pixelSize),this.state.clampXY(this.dataset,this.contactMatrixView.getViewDimensions()),this.state.configureLocus(this,this.dataset,{width:n,height:o}),this.update($C("LocusChange",{state:this.state,resolutionChanged:!1,chrChanged:!1}))}else{let t;for(t=0;t0){const e=[];for(let[t,i]of this.pending)e.push(i);this.pending.clear();for(let t of e)this.update(t)}e&&this.eventBus.post(e),this.stopSpinner()}}}repaintMatrix(){this.contactMatrixView.imageTileCache={},this.contactMatrixView.initialImage=void 0,this.contactMatrixView.update()}resolution(){return this.dataset.bpResolutions[this.state.zoom]}toJSON(){if(!this.dataset||!this.dataset.url)return"{}";const e={};e.backgroundColor=this.contactMatrixView.stringifyBackgroundColor(),e.url=this.dataset.url,this.dataset.name&&(e.name=this.dataset.name),e.state=this.state.toJSON(),e.colorScale=this.contactMatrixView.getColorScale().stringify(),EC.selectedGene&&(e.selectedGene=EC.selectedGene);let t=this.dataset.hicFile.config.nvi;if(t&&(e.nvi=t),this.controlDataset){e.controlUrl=this.controlUrl,this.controlDataset.name&&(e.controlName=this.controlDataset.name);this.getDisplayMode()&&(e.displayMode=this.getDisplayMode()),t=this.controlDataset.hicFile.config.nvi,t&&(e.controlNvi=t);void 0!==this.ui.getComponent("controlMap").getDisplayModeCycle()&&(e.cycle=!0)}if(this.trackPairs.length>0||this.tracks2D.length>0){let t=[];e.tracks=t;for(let e of this.trackPairs){const i=e.x.track,n=i.config;if("string"==typeof n.url){const e={url:n.url};n.type&&(e.type=n.type),n.format&&(e.format=n.format),i.name&&(e.name=i.name),i.dataRange&&(e.min=i.dataRange.min,e.max=i.dataRange.max),i.color&&(e.color=i.color),t.push(e)}else"sequence"===n.type&&t.push({type:"sequence",format:"sequence"})}for(const e of this.tracks2D)"string"==typeof e.config.url&&t.push(e.toJSON())}return e}async minZoom(e,t){const i=this.dataset.chromosomes[e],n=this.dataset.chromosomes[t],{width:o,height:r}=this.contactMatrixView.getViewDimensions(),a=Math.max(i.size/o,n.size/r),s=await this.dataset.getMatrix(e,t);if(!s)throw new Error(`Data not avaiable for chromosomes ${i.name} - ${n.name}`);return s.findZoomForResolution(a)}async minPixelSize(e,t,i){const n=this.dataset.chromosomes[e].size,o=this.dataset.chromosomes[t].size,r=await this.dataset.getMatrix(e,t),{zoom:a}=r.getZoomDataByIndex(i,"BP"),s=n/a.binSize,c=o/a.binSize,{width:l,height:h}=this.contactMatrixView.getViewDimensions();return Math.min(l/s,h/c)}}let pk,mk=[];function gk(e){if(void 0===e)return pk?.rootElement.classList.remove("hic-root-selected"),void(pk=e);e!==pk&&(pk?.rootElement.classList.remove("hic-root-selected"),e.rootElement.classList.add("hic-root-selected"),pk=e,NC.globalBus.post($C("BrowserSelect",e)))}function wk(e){const t=(e||mk).filter((e=>!1!==e.synchable&&void 0!==e.dataset));t.forEach((e=>{t.forEach((t=>{e!==t&&e.dataset.isCompatible(t.dataset)&&(e.synchedBrowsers.add(t),t.synchedBrowsers.add(e))}))}))}function Fk(){return mk}function bk(e){!0===e.figureMode?(e.showLocusGoto=!1,e.showHicContactMapLabel=!1,e.showChromosomeSelector=!1):(e.showLocusGoto=e.showLocusGoto??!0,e.showHicContactMapLabel=e.showHicContactMapLabel??!0,e.showChromosomeSelector=e.showChromosomeSelector??!0)}function vk(){const e={},t=[],i=Fk();for(let e of i)t.push(e.toJSON());e.browsers=t,EC.selectedGene&&(e.selectedGene=EC.selectedGene);const n=document.getElementById("hic-caption");if(n){var o=n.textContent;o&&(o=o.trim())&&(e.caption=o)}return e}async function yk(t,i){if(function(){for(let e of mk)e.rootElement.remove();mk=[]}(),i.hasOwnProperty("selectedGene")&&(EC.selectedGene=i.selectedGene),i.hasOwnProperty("caption")){const e=i.caption;var n=document.getElementById("hic-caption");n&&(n.textContent=e)}await async function(t,i){const n=i.browsers||[i];mk=[];const o=[];for(const r of n){bk(r),e(r.colorScale)&&(r.colorScale=Vx.parse(r.colorScale)),e(r.backgroundColor)&&(r.backgroundColor=Gx.parseBackgroundColor(r.backgroundColor)),!1===i.syncDatasets&&(r.synchable=!1);const n=new uk(t,r);mk.push(n),o.push(n.init(r))}await Promise.all(o),gk(mk[0]),mk.length>1&&mk.forEach((e=>e.browserPanelDeleteButton.style.display="block"))}(t,i),!1!==i.syncDatasets&&wk()}const _k={"*s3e/":"https://hicfiles.s3.amazonaws.com/external/","*s3/":"https://hicfiles.s3.amazonaws.com/","*s3e_/":"http://hicfiles.s3.amazonaws.com/external/","*s3_/":"http://hicfiles.s3.amazonaws.com/","*enc/":"https://www.encodeproject.org/files/"};async function Ck(e){let t,i=Sk(e);if(i.hasOwnProperty("session")&&(i.session.startsWith("blob:")||i.session.startsWith("data:"))&&(t=JSON.parse(Ti(i.session.substr(5)))),i.hasOwnProperty("juiceboxURL")){i=Sk(await async function(e){const t="https://api-ssl.bitly.com/v4/expand",i={bitlink_id:e.startsWith("http://")?e.substring(7):e.substring(8)},n=await fetch(t,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${btoa("ëtá¾´ãÎtsßéÆºÙçµóf¸í¿9snéÝz")}`},body:JSON.stringify(i)});if(!n.ok)throw new Error(`Network error (${n.status}): ${n.statusText}`);let o=(await n.json()).long_url;return o=o.replace("{","%7B").replace("}","%7D"),o}(i.juiceboxURL))}if(i.hasOwnProperty("juicebox")||i.hasOwnProperty("juiceboxData")){let e;i.hasOwnProperty("juiceboxData")?e=Ti(i.juiceboxData):(e=i.juicebox,e.startsWith("%7B")&&(e=decodeURIComponent(e))),e=e.substr(1,e.length-2);const n=e.split("},{"),o=[];for(let e of n){const t=Sk(decodeURIComponent(e));o.push(kk(t))}t={browsers:o}}const n=kk(i,!0);if(n.url&&(t=n),t)if(t.browsers)for(let e of t.browsers)xk(e);else xk(t);return t}function xk(e){if(e.tracks)for(let t of e.tracks)"rgb(22, 129, 198)"===t.color&&delete t.color,void 0!==t.min&&Number.isNaN(t.min)&&delete t.min,void 0!==t.max&&Number.isNaN(t.max)&&delete t.max,t.displayMode="COLLAPSED"}function kk(e,t){const i={};let n=e.hicUrl;const o=e.name;let r=e.state,a=e.colorScale,s=e.tracks;const c=e.selectedGene,l=e.nvi;let h=e.controlUrl;const d=e.controlName,f=e.displayMode,u=e.controlNvi,p=e.cycle;return n&&(n=Ek(n,t),Object.keys(_k).forEach((function(e){var t=_k[e];n.startsWith(e)&&(n=n.replace(e,t))})),i.url=n),o&&(i.name=Ek(o,t)),h&&(h=Ek(h,t),Object.keys(_k).forEach((function(e){var t=_k[e];h.startsWith(e)&&(h=h.replace(e,t))})),i.controlUrl=h),d&&(i.controlName=Ek(d,t)),r&&(r=Ek(r,t),i.state=Lx.parse(r)),a&&(a=Ek(a,t),i.colorScale=Vx.parse(a)),f&&(i.displayMode=Ek(f,t)),s&&(s=Ek(s,t),i.tracks=function(e){const t=e.split("|||"),i=[];for(let e of t){const t=e.split("|"),o=t.pop();let r=t.length>1?t[0]:e;if(r&&r.trim().length>0&&"undefined"!==r){const e=Object.keys(_k);for(let t of e){var n=_k[t];if(r.startsWith(t)){r=r.replace(t,n);break}}const a={url:r};if(t.length>1&&(a.name=Nk(t[1],"$","|")),t.length>2){const e=t[2];if(e.startsWith("-")){const t=e.substring(1).split("-");a.min=-parseFloat(t[0]),a.max=parseFloat(t[1])}else{const t=e.split("-");a.min=parseFloat(t[0]),a.max=parseFloat(t[1])}}o&&(a.color=o),i.push(a)}}return i}(s),i.tracks&&i.oauthToken&&i.tracks.forEach((function(e){e.oauthToken=i.oauthToken}))),c&&(EC.selectedGene=c),i.cycle=p,l&&(i.nvi=Ek(l,t)),u&&(i.controlNvi=Ek(u,t)),i}function Ek(e,t){if(t)return decodeURIComponent(e);var i=Nk(e,"%26","&");return i=Nk(i,"%20"," "),i=Nk(i,"+"," "),i=Nk(i,"%7C","|"),i=Nk(i,"%23","#"),i=Nk(i,"%3F","?"),i=Nk(i,"%3D","=")}function Nk(e,t,i){return e.split(t).join(i)}function Sk(e){var t,i,n,o,r,a;r={},t=e.indexOf("?"),i=e.lastIndexOf("#");for(t>e.indexOf("=")&&(t=-1),i<0&&(i=e.length),n=t+1;n1&&mk.forEach((e=>e.browserPanelDeleteButton.style.display="block")),o},getCurrentBrowser:function(){return pk},setCurrentBrowser:gk,getAllBrowsers:Fk,igvxhr:en,EventBus:NC}})); -//# sourceMappingURL=juicebox.min.js.map diff --git a/dist/juicebox.min.js.map b/dist/juicebox.min.js.map deleted file mode 100644 index 32b32c43..00000000 --- a/dist/juicebox.min.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"juicebox.min.js","sources":["../node_modules/igv-utils/src/stringUtils.js","../node_modules/igv-utils/src/fileUtils.js","../node_modules/igv-utils/src/uriUtils.js","../node_modules/igv-utils/src/pako.esm.js","../node_modules/igv-utils/src/bgzf.js","../node_modules/igv-utils/src/igv-math.js","../node_modules/igv-utils/src/igv-color.js","../node_modules/igv-utils/src/oauth.js","../node_modules/igv-utils/src/google-utils/googleUtils.js","../node_modules/igv-utils/src/google-utils/googleAuth.js","../node_modules/igv-utils/src/google-utils/googleDrive.js","../node_modules/igv-utils/src/throttle.js","../node_modules/igv-utils/src/igvxhr.js","../node_modules/igv-utils/src/intervalTree.js","../node_modules/igv/dist/igv.esm.js","../node_modules/igv-ui/dist/igv-ui.js","../js/hicUtils.js","../js/globals.js","../js/eventBus.js","../js/track2D.js","../js/ruler.js","../js/igv-icons.js","../js/trackMenuUtils.js","../js/trackGearPopup.js","../js/tile.js","../js/trackPair.js","../js/trackRenderer.js","../js/hicEvent.js","../js/fileUtils.js","../js/utils.js","../js/layoutController.js","../js/createBrowser.js","../node_modules/hic-straw/src/vendor/zlib_and_gzip.js","../node_modules/hic-straw/src/io/browserLocalFile.js","../node_modules/hic-straw/src/io/remoteFile.js","../node_modules/hic-straw/src/io/throttledFile.js","../node_modules/hic-straw/src/io/bufferedFile.js","../node_modules/hic-straw/src/binary.js","../node_modules/hic-straw/src/matrixZoomData.js","../node_modules/hic-straw/src/matrix.js","../node_modules/hic-straw/src/contactRecord.js","../node_modules/hic-straw/src/lru.js","../node_modules/hic-straw/src/normalizationVector.js","../node_modules/hic-straw/src/nvi.js","../node_modules/hic-straw/src/hicFile.js","../node_modules/hic-straw/src/io/rateLimiter.js","../node_modules/hic-straw/src/straw.js","../node_modules/google-utils/src/googleUtils.js","../node_modules/google-utils/src/googleDrive.js","../js/igvRemoteFile.js","../js/hicDataset.js","../js/genome.js","../js/hicState.js","../js/geneSearch.js","../js/nvi.js","../js/hicLocusGoto.js","../js/hicResolutionSelector.js","../js/colorScale.js","../js/ratioColorScale.js","../js/contactMatrixView.js","../js/genomicUtils.js","../js/hicColorScaleWidget.js","../js/controlMapWidget.js","../js/normalizationWidget.js","../js/sweepZoom.js","../js/scrollbarWidget.js","../js/chromosomeSelector.js","../js/annotationWidget.js","../js/browserUIManager.js","../js/hicBrowser.js","../js/session.js","../js/urlUtils.js","../js/index.js","../js/version.js","../js/init.js"],"sourcesContent":["\n/**\n * Covers string literals and String objects\n * @param x\n * @returns {boolean}\n */\nfunction isString(x) {\n return typeof x === \"string\" || x instanceof String\n}\n\n\n// StackOverflow: http://stackoverflow.com/a/10810674/116169\nfunction numberFormatter(rawNumber) {\n\n var dec = String(rawNumber).split(/[.,]/),\n sep = ',',\n decsep = '.';\n\n return dec[0].split('').reverse().reduce(function (prev, now, i) {\n return i % 3 === 0 ? prev + sep + now : prev + now;\n }).split('').reverse().join('') + (dec[1] ? decsep + dec[1] : '');\n}\n\nconst numberUnFormatter = formatedNumber => formatedNumber.split(\",\").join().replace(\",\", \"\", \"g\");\n\nconst splitLines = function (string) {\n return string.split(/\\n|\\r\\n|\\r/g);\n}\n\n\nfunction splitStringRespectingQuotes(string, delim) {\n\n var tokens = [],\n len = string.length,\n i,\n n = 0,\n quote = false,\n c;\n\n if (len > 0) {\n\n tokens[n] = string.charAt(0);\n for (i = 1; i < len; i++) {\n c = string.charAt(i);\n if (c === '\"') {\n quote = !quote;\n } else if (!quote && c === delim) {\n n++;\n tokens[n] = \"\";\n } else {\n tokens[n] += c;\n }\n }\n }\n return tokens;\n}\n\nfunction stripQuotes(str) {\n if(str === undefined) {\n return str;\n }\n if(str.startsWith(\"'\") || str.startsWith('\"')) {\n str = str.substring(1);\n }\n if (str.endsWith(\"'\") || str.endsWith('\"')) {\n str = str.substring(0, str.length - 1);\n }\n return str;\n}\n\nfunction hashCode(s) {\n return s.split(\"\").reduce(function (a, b) {\n a = ((a << 5) - a) + b.charCodeAt(0);\n return a & a\n }, 0);\n}\n\nfunction capitalize(str) {\n return str.length > 0 ? str.charAt(0).toUpperCase() + str.slice(1) : str;\n}\n\n\n/**\n * Parse a locus string and return a range object. Locus string is of the form chr:start-end. End is optional\n *\n */\nfunction parseLocusString(string) {\n\n const t1 = string.split(\":\");\n const t2 = t1[1].split(\"-\");\n\n const range = {\n chr: t1[0],\n start: Number.parseInt(t2[0].replace(/,/g, '')) - 1\n };\n\n if (t2.length > 1) {\n range.end = Number.parseInt(t2[1].replace(/,/g, ''));\n } else {\n range.end = range.start + 1;\n }\n\n return range;\n}\n\nexport {\n isString, numberFormatter, numberUnFormatter, splitLines, splitStringRespectingQuotes, stripQuotes,\n hashCode, capitalize, parseLocusString\n};","import {isString} from \"./stringUtils.js\"\n\nfunction getExtension(url) {\n\n if (undefined === url) {\n return undefined\n }\n\n let path = (isFilePath(url) || url.google_url) ? url.name : url\n let filename = path.toLowerCase()\n\n //Strip parameters -- handle local files later\n let index = filename.indexOf(\"?\")\n if (index > 0) {\n filename = filename.substr(0, index)\n }\n\n //Strip aux extensions .gz, .tab, and .txt\n if (filename.endsWith(\".gz\")) {\n filename = filename.substr(0, filename.length - 3)\n } else if (filename.endsWith(\".txt\") || filename.endsWith(\".tab\") || filename.endsWith(\".bgz\")) {\n filename = filename.substr(0, filename.length - 4)\n }\n\n index = filename.lastIndexOf(\".\")\n\n return index < 0 ? filename : filename.substr(1 + index)\n}\n\n/**\n * Return the filename from the path. Example\n * https://foo.com/bar.bed?param=2 => bar.bed\n * @param urlOrFile\n */\n\nfunction getFilename(urlOrFile) {\n\n if (urlOrFile.name !== undefined) {\n return urlOrFile.name\n } else if (isString(urlOrFile)) {\n\n let index = urlOrFile.lastIndexOf(\"/\")\n let filename = index < 0 ? urlOrFile : urlOrFile.substr(index + 1)\n\n //Strip parameters -- handle local files later\n index = filename.indexOf(\"?\")\n if (index > 0) {\n filename = filename.substr(0, index)\n }\n return filename\n } else {\n throw Error(`Expected File or string, got ${typeof urlOrFile}`)\n }\n}\n\n\n/**\n * Test if object is a File or File-like object.\n *\n * @param object\n */\nfunction isFile(object) {\n if(!object) {\n return false;\n }\n return typeof object !== 'function' &&\n (object instanceof File ||\n (object.hasOwnProperty(\"name\") && typeof object.slice === 'function' && typeof object.arrayBuffer === 'function'))\n}\n\nconst isFilePath = isFile // deprecated\n\nfunction download(filename, data) {\n\n const element = document.createElement('a')\n element.setAttribute('href', data)\n element.setAttribute('download', filename)\n element.style.display = 'none'\n document.body.appendChild(element)\n element.click()\n document.body.removeChild(element)\n}\n\nexport {getExtension, getFilename, isFilePath, isFile, download}\n","if (typeof process === 'object' && typeof window === 'undefined') {\n global.atob = function (str) {\n return Buffer.from(str, 'base64').toString('binary');\n }\n}\n\n\nfunction parseUri(str) {\n\n var o = options,\n m = o.parser[o.strictMode ? \"strict\" : \"loose\"].exec(str),\n uri = {},\n i = 14;\n\n while (i--) uri[o.key[i]] = m[i] || \"\";\n\n uri[o.q.name] = {};\n uri[o.key[12]].replace(o.q.parser, function ($0, $1, $2) {\n if ($1) uri[o.q.name][$1] = $2;\n });\n\n return uri;\n}\n\nconst options = {\n strictMode: false,\n key: [\"source\", \"protocol\", \"authority\", \"userInfo\", \"user\", \"password\", \"host\", \"port\", \"relative\", \"path\", \"directory\", \"file\", \"query\", \"anchor\"],\n q: {\n name: \"queryKey\",\n parser: /(?:^|&)([^&=]*)=?([^&]*)/g\n },\n parser: {\n strict: /^(?:([^:\\/?#]+):)?(?:\\/\\/((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\\/?#]*)(?::(\\d*))?))?((((?:[^?#\\/]*\\/)*)([^?#]*))(?:\\?([^#]*))?(?:#(.*))?)/,\n loose: /^(?:(?![^:@]+:[^:@\\/]*@)([^:\\/?#.]+):)?(?:\\/\\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\\/?#]*)(?::(\\d*))?)(((\\/(?:[^?#](?![^?#\\/]*\\.[^?#\\/.]+(?:[?#]|$)))*\\/?)?([^?#\\/]*))(?:\\?([^#]*))?(?:#(.*))?)/\n }\n};\n\nfunction addExtension(url, extension) {\n\n const idx = url.indexOf(\"?\");\n if (idx < 0) {\n return url + extension;\n } else {\n return url.substring(0, idx) + extension + url.substring(idx);\n }\n}\n\n/**\n * Resolve a url, which might be a string, function (that returns a string or Promse), or Promise (that resolves to a string)\n *\n * @param url\n * @returns {Promise<*>}\n */\nasync function resolveURL(url) {\n return (typeof url === 'function') ? url() : url;\n}\n\nexport {parseUri, addExtension, resolveURL};\n\n","\n/*! pako 2.1.0 https://github.com/nodeca/pako @license (MIT AND Zlib) */\n// (C) 1995-2013 Jean-loup Gailly and Mark Adler\n// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin\n//\n// This software is provided 'as-is', without any express or implied\n// warranty. In no event will the authors be held liable for any damages\n// arising from the use of this software.\n//\n// Permission is granted to anyone to use this software for any purpose,\n// including commercial applications, and to alter it and redistribute it\n// freely, subject to the following restrictions:\n//\n// 1. The origin of this software must not be misrepresented; you must not\n// claim that you wrote the original software. If you use this software\n// in a product, an acknowledgment in the product documentation would be\n// appreciated but is not required.\n// 2. Altered source versions must be plainly marked as such, and must not be\n// misrepresented as being the original software.\n// 3. This notice may not be removed or altered from any source distribution.\n\n/* eslint-disable space-unary-ops */\n\n/* Public constants ==========================================================*/\n/* ===========================================================================*/\n\n\n//const Z_FILTERED = 1;\n//const Z_HUFFMAN_ONLY = 2;\n//const Z_RLE = 3;\nconst Z_FIXED$1 = 4;\n//const Z_DEFAULT_STRATEGY = 0;\n\n/* Possible values of the data_type field (though see inflate()) */\nconst Z_BINARY = 0;\nconst Z_TEXT = 1;\n//const Z_ASCII = 1; // = Z_TEXT\nconst Z_UNKNOWN$1 = 2;\n\n/*============================================================================*/\n\n\nfunction zero$1(buf) { let len = buf.length; while (--len >= 0) { buf[len] = 0; } }\n\n// From zutil.h\n\nconst STORED_BLOCK = 0;\nconst STATIC_TREES = 1;\nconst DYN_TREES = 2;\n/* The three kinds of block type */\n\nconst MIN_MATCH$1 = 3;\nconst MAX_MATCH$1 = 258;\n/* The minimum and maximum match lengths */\n\n// From deflate.h\n/* ===========================================================================\n * Internal compression state.\n */\n\nconst LENGTH_CODES$1 = 29;\n/* number of length codes, not counting the special END_BLOCK code */\n\nconst LITERALS$1 = 256;\n/* number of literal bytes 0..255 */\n\nconst L_CODES$1 = LITERALS$1 + 1 + LENGTH_CODES$1;\n/* number of Literal or Length codes, including the END_BLOCK code */\n\nconst D_CODES$1 = 30;\n/* number of distance codes */\n\nconst BL_CODES$1 = 19;\n/* number of codes used to transfer the bit lengths */\n\nconst HEAP_SIZE$1 = 2 * L_CODES$1 + 1;\n/* maximum heap size */\n\nconst MAX_BITS$1 = 15;\n/* All codes must not exceed MAX_BITS bits */\n\nconst Buf_size = 16;\n/* size of bit buffer in bi_buf */\n\n\n/* ===========================================================================\n * Constants\n */\n\nconst MAX_BL_BITS = 7;\n/* Bit length codes must not exceed MAX_BL_BITS bits */\n\nconst END_BLOCK = 256;\n/* end of block literal code */\n\nconst REP_3_6 = 16;\n/* repeat previous bit length 3-6 times (2 bits of repeat count) */\n\nconst REPZ_3_10 = 17;\n/* repeat a zero length 3-10 times (3 bits of repeat count) */\n\nconst REPZ_11_138 = 18;\n/* repeat a zero length 11-138 times (7 bits of repeat count) */\n\n/* eslint-disable comma-spacing,array-bracket-spacing */\nconst extra_lbits = /* extra bits for each length code */\n new Uint8Array([0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0]);\n\nconst extra_dbits = /* extra bits for each distance code */\n new Uint8Array([0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13]);\n\nconst extra_blbits = /* extra bits for each bit length code */\n new Uint8Array([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7]);\n\nconst bl_order =\n new Uint8Array([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]);\n/* eslint-enable comma-spacing,array-bracket-spacing */\n\n/* The lengths of the bit length codes are sent in order of decreasing\n * probability, to avoid transmitting the lengths for unused bit length codes.\n */\n\n/* ===========================================================================\n * Local data. These are initialized only once.\n */\n\n// We pre-fill arrays with 0 to avoid uninitialized gaps\n\nconst DIST_CODE_LEN = 512; /* see definition of array dist_code below */\n\n// !!!! Use flat array instead of structure, Freq = i*2, Len = i*2+1\nconst static_ltree = new Array((L_CODES$1 + 2) * 2);\nzero$1(static_ltree);\n/* The static literal tree. Since the bit lengths are imposed, there is no\n * need for the L_CODES extra codes used during heap construction. However\n * The codes 286 and 287 are needed to build a canonical tree (see _tr_init\n * below).\n */\n\nconst static_dtree = new Array(D_CODES$1 * 2);\nzero$1(static_dtree);\n/* The static distance tree. (Actually a trivial tree since all codes use\n * 5 bits.)\n */\n\nconst _dist_code = new Array(DIST_CODE_LEN);\nzero$1(_dist_code);\n/* Distance codes. The first 256 values correspond to the distances\n * 3 .. 258, the last 256 values correspond to the top 8 bits of\n * the 15 bit distances.\n */\n\nconst _length_code = new Array(MAX_MATCH$1 - MIN_MATCH$1 + 1);\nzero$1(_length_code);\n/* length code for each normalized match length (0 == MIN_MATCH) */\n\nconst base_length = new Array(LENGTH_CODES$1);\nzero$1(base_length);\n/* First normalized length for each code (0 = MIN_MATCH) */\n\nconst base_dist = new Array(D_CODES$1);\nzero$1(base_dist);\n/* First normalized distance for each code (0 = distance of 1) */\n\n\nfunction StaticTreeDesc(static_tree, extra_bits, extra_base, elems, max_length) {\n\n this.static_tree = static_tree; /* static tree or NULL */\n this.extra_bits = extra_bits; /* extra bits for each code or NULL */\n this.extra_base = extra_base; /* base index for extra_bits */\n this.elems = elems; /* max number of elements in the tree */\n this.max_length = max_length; /* max bit length for the codes */\n\n // show if `static_tree` has data or dummy - needed for monomorphic objects\n this.has_stree = static_tree && static_tree.length;\n}\n\n\nlet static_l_desc;\nlet static_d_desc;\nlet static_bl_desc;\n\n\nfunction TreeDesc(dyn_tree, stat_desc) {\n this.dyn_tree = dyn_tree; /* the dynamic tree */\n this.max_code = 0; /* largest code with non zero frequency */\n this.stat_desc = stat_desc; /* the corresponding static tree */\n}\n\n\n\nconst d_code = (dist) => {\n\n return dist < 256 ? _dist_code[dist] : _dist_code[256 + (dist >>> 7)];\n};\n\n\n/* ===========================================================================\n * Output a short LSB first on the stream.\n * IN assertion: there is enough room in pendingBuf.\n */\nconst put_short = (s, w) => {\n// put_byte(s, (uch)((w) & 0xff));\n// put_byte(s, (uch)((ush)(w) >> 8));\n s.pending_buf[s.pending++] = (w) & 0xff;\n s.pending_buf[s.pending++] = (w >>> 8) & 0xff;\n};\n\n\n/* ===========================================================================\n * Send a value on a given number of bits.\n * IN assertion: length <= 16 and value fits in length bits.\n */\nconst send_bits = (s, value, length) => {\n\n if (s.bi_valid > (Buf_size - length)) {\n s.bi_buf |= (value << s.bi_valid) & 0xffff;\n put_short(s, s.bi_buf);\n s.bi_buf = value >> (Buf_size - s.bi_valid);\n s.bi_valid += length - Buf_size;\n } else {\n s.bi_buf |= (value << s.bi_valid) & 0xffff;\n s.bi_valid += length;\n }\n};\n\n\nconst send_code = (s, c, tree) => {\n\n send_bits(s, tree[c * 2]/*.Code*/, tree[c * 2 + 1]/*.Len*/);\n};\n\n\n/* ===========================================================================\n * Reverse the first len bits of a code, using straightforward code (a faster\n * method would use a table)\n * IN assertion: 1 <= len <= 15\n */\nconst bi_reverse = (code, len) => {\n\n let res = 0;\n do {\n res |= code & 1;\n code >>>= 1;\n res <<= 1;\n } while (--len > 0);\n return res >>> 1;\n};\n\n\n/* ===========================================================================\n * Flush the bit buffer, keeping at most 7 bits in it.\n */\nconst bi_flush = (s) => {\n\n if (s.bi_valid === 16) {\n put_short(s, s.bi_buf);\n s.bi_buf = 0;\n s.bi_valid = 0;\n\n } else if (s.bi_valid >= 8) {\n s.pending_buf[s.pending++] = s.bi_buf & 0xff;\n s.bi_buf >>= 8;\n s.bi_valid -= 8;\n }\n};\n\n\n/* ===========================================================================\n * Compute the optimal bit lengths for a tree and update the total bit length\n * for the current block.\n * IN assertion: the fields freq and dad are set, heap[heap_max] and\n * above are the tree nodes sorted by increasing frequency.\n * OUT assertions: the field len is set to the optimal bit length, the\n * array bl_count contains the frequencies for each bit length.\n * The length opt_len is updated; static_len is also updated if stree is\n * not null.\n */\nconst gen_bitlen = (s, desc) => {\n// deflate_state *s;\n// tree_desc *desc; /* the tree descriptor */\n\n const tree = desc.dyn_tree;\n const max_code = desc.max_code;\n const stree = desc.stat_desc.static_tree;\n const has_stree = desc.stat_desc.has_stree;\n const extra = desc.stat_desc.extra_bits;\n const base = desc.stat_desc.extra_base;\n const max_length = desc.stat_desc.max_length;\n let h; /* heap index */\n let n, m; /* iterate over the tree elements */\n let bits; /* bit length */\n let xbits; /* extra bits */\n let f; /* frequency */\n let overflow = 0; /* number of elements with bit length too large */\n\n for (bits = 0; bits <= MAX_BITS$1; bits++) {\n s.bl_count[bits] = 0;\n }\n\n /* In a first pass, compute the optimal bit lengths (which may\n * overflow in the case of the bit length tree).\n */\n tree[s.heap[s.heap_max] * 2 + 1]/*.Len*/ = 0; /* root of the heap */\n\n for (h = s.heap_max + 1; h < HEAP_SIZE$1; h++) {\n n = s.heap[h];\n bits = tree[tree[n * 2 + 1]/*.Dad*/ * 2 + 1]/*.Len*/ + 1;\n if (bits > max_length) {\n bits = max_length;\n overflow++;\n }\n tree[n * 2 + 1]/*.Len*/ = bits;\n /* We overwrite tree[n].Dad which is no longer needed */\n\n if (n > max_code) { continue; } /* not a leaf node */\n\n s.bl_count[bits]++;\n xbits = 0;\n if (n >= base) {\n xbits = extra[n - base];\n }\n f = tree[n * 2]/*.Freq*/;\n s.opt_len += f * (bits + xbits);\n if (has_stree) {\n s.static_len += f * (stree[n * 2 + 1]/*.Len*/ + xbits);\n }\n }\n if (overflow === 0) { return; }\n\n // Tracev((stderr,\"\\nbit length overflow\\n\"));\n /* This happens for example on obj2 and pic of the Calgary corpus */\n\n /* Find the first bit length which could increase: */\n do {\n bits = max_length - 1;\n while (s.bl_count[bits] === 0) { bits--; }\n s.bl_count[bits]--; /* move one leaf down the tree */\n s.bl_count[bits + 1] += 2; /* move one overflow item as its brother */\n s.bl_count[max_length]--;\n /* The brother of the overflow item also moves one step up,\n * but this does not affect bl_count[max_length]\n */\n overflow -= 2;\n } while (overflow > 0);\n\n /* Now recompute all bit lengths, scanning in increasing frequency.\n * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all\n * lengths instead of fixing only the wrong ones. This idea is taken\n * from 'ar' written by Haruhiko Okumura.)\n */\n for (bits = max_length; bits !== 0; bits--) {\n n = s.bl_count[bits];\n while (n !== 0) {\n m = s.heap[--h];\n if (m > max_code) { continue; }\n if (tree[m * 2 + 1]/*.Len*/ !== bits) {\n // Tracev((stderr,\"code %d bits %d->%d\\n\", m, tree[m].Len, bits));\n s.opt_len += (bits - tree[m * 2 + 1]/*.Len*/) * tree[m * 2]/*.Freq*/;\n tree[m * 2 + 1]/*.Len*/ = bits;\n }\n n--;\n }\n }\n};\n\n\n/* ===========================================================================\n * Generate the codes for a given tree and bit counts (which need not be\n * optimal).\n * IN assertion: the array bl_count contains the bit length statistics for\n * the given tree and the field len is set for all tree elements.\n * OUT assertion: the field code is set for all tree elements of non\n * zero code length.\n */\nconst gen_codes = (tree, max_code, bl_count) => {\n// ct_data *tree; /* the tree to decorate */\n// int max_code; /* largest code with non zero frequency */\n// ushf *bl_count; /* number of codes at each bit length */\n\n const next_code = new Array(MAX_BITS$1 + 1); /* next code value for each bit length */\n let code = 0; /* running code value */\n let bits; /* bit index */\n let n; /* code index */\n\n /* The distribution counts are first used to generate the code values\n * without bit reversal.\n */\n for (bits = 1; bits <= MAX_BITS$1; bits++) {\n code = (code + bl_count[bits - 1]) << 1;\n next_code[bits] = code;\n }\n /* Check that the bit counts in bl_count are consistent. The last code\n * must be all ones.\n */\n //Assert (code + bl_count[MAX_BITS]-1 == (1< {\n\n let n; /* iterates over tree elements */\n let bits; /* bit counter */\n let length; /* length value */\n let code; /* code value */\n let dist; /* distance index */\n const bl_count = new Array(MAX_BITS$1 + 1);\n /* number of codes at each bit length for an optimal tree */\n\n // do check in _tr_init()\n //if (static_init_done) return;\n\n /* For some embedded targets, global variables are not initialized: */\n/*#ifdef NO_INIT_GLOBAL_POINTERS\n static_l_desc.static_tree = static_ltree;\n static_l_desc.extra_bits = extra_lbits;\n static_d_desc.static_tree = static_dtree;\n static_d_desc.extra_bits = extra_dbits;\n static_bl_desc.extra_bits = extra_blbits;\n#endif*/\n\n /* Initialize the mapping length (0..255) -> length code (0..28) */\n length = 0;\n for (code = 0; code < LENGTH_CODES$1 - 1; code++) {\n base_length[code] = length;\n for (n = 0; n < (1 << extra_lbits[code]); n++) {\n _length_code[length++] = code;\n }\n }\n //Assert (length == 256, \"tr_static_init: length != 256\");\n /* Note that the length 255 (match length 258) can be represented\n * in two different ways: code 284 + 5 bits or code 285, so we\n * overwrite length_code[255] to use the best encoding:\n */\n _length_code[length - 1] = code;\n\n /* Initialize the mapping dist (0..32K) -> dist code (0..29) */\n dist = 0;\n for (code = 0; code < 16; code++) {\n base_dist[code] = dist;\n for (n = 0; n < (1 << extra_dbits[code]); n++) {\n _dist_code[dist++] = code;\n }\n }\n //Assert (dist == 256, \"tr_static_init: dist != 256\");\n dist >>= 7; /* from now on, all distances are divided by 128 */\n for (; code < D_CODES$1; code++) {\n base_dist[code] = dist << 7;\n for (n = 0; n < (1 << (extra_dbits[code] - 7)); n++) {\n _dist_code[256 + dist++] = code;\n }\n }\n //Assert (dist == 256, \"tr_static_init: 256+dist != 512\");\n\n /* Construct the codes of the static literal tree */\n for (bits = 0; bits <= MAX_BITS$1; bits++) {\n bl_count[bits] = 0;\n }\n\n n = 0;\n while (n <= 143) {\n static_ltree[n * 2 + 1]/*.Len*/ = 8;\n n++;\n bl_count[8]++;\n }\n while (n <= 255) {\n static_ltree[n * 2 + 1]/*.Len*/ = 9;\n n++;\n bl_count[9]++;\n }\n while (n <= 279) {\n static_ltree[n * 2 + 1]/*.Len*/ = 7;\n n++;\n bl_count[7]++;\n }\n while (n <= 287) {\n static_ltree[n * 2 + 1]/*.Len*/ = 8;\n n++;\n bl_count[8]++;\n }\n /* Codes 286 and 287 do not exist, but we must include them in the\n * tree construction to get a canonical Huffman tree (longest code\n * all ones)\n */\n gen_codes(static_ltree, L_CODES$1 + 1, bl_count);\n\n /* The static distance tree is trivial: */\n for (n = 0; n < D_CODES$1; n++) {\n static_dtree[n * 2 + 1]/*.Len*/ = 5;\n static_dtree[n * 2]/*.Code*/ = bi_reverse(n, 5);\n }\n\n // Now data ready and we can init static trees\n static_l_desc = new StaticTreeDesc(static_ltree, extra_lbits, LITERALS$1 + 1, L_CODES$1, MAX_BITS$1);\n static_d_desc = new StaticTreeDesc(static_dtree, extra_dbits, 0, D_CODES$1, MAX_BITS$1);\n static_bl_desc = new StaticTreeDesc(new Array(0), extra_blbits, 0, BL_CODES$1, MAX_BL_BITS);\n\n //static_init_done = true;\n};\n\n\n/* ===========================================================================\n * Initialize a new block.\n */\nconst init_block = (s) => {\n\n let n; /* iterates over tree elements */\n\n /* Initialize the trees. */\n for (n = 0; n < L_CODES$1; n++) { s.dyn_ltree[n * 2]/*.Freq*/ = 0; }\n for (n = 0; n < D_CODES$1; n++) { s.dyn_dtree[n * 2]/*.Freq*/ = 0; }\n for (n = 0; n < BL_CODES$1; n++) { s.bl_tree[n * 2]/*.Freq*/ = 0; }\n\n s.dyn_ltree[END_BLOCK * 2]/*.Freq*/ = 1;\n s.opt_len = s.static_len = 0;\n s.sym_next = s.matches = 0;\n};\n\n\n/* ===========================================================================\n * Flush the bit buffer and align the output on a byte boundary\n */\nconst bi_windup = (s) =>\n{\n if (s.bi_valid > 8) {\n put_short(s, s.bi_buf);\n } else if (s.bi_valid > 0) {\n //put_byte(s, (Byte)s->bi_buf);\n s.pending_buf[s.pending++] = s.bi_buf;\n }\n s.bi_buf = 0;\n s.bi_valid = 0;\n};\n\n/* ===========================================================================\n * Compares to subtrees, using the tree depth as tie breaker when\n * the subtrees have equal frequency. This minimizes the worst case length.\n */\nconst smaller = (tree, n, m, depth) => {\n\n const _n2 = n * 2;\n const _m2 = m * 2;\n return (tree[_n2]/*.Freq*/ < tree[_m2]/*.Freq*/ ||\n (tree[_n2]/*.Freq*/ === tree[_m2]/*.Freq*/ && depth[n] <= depth[m]));\n};\n\n/* ===========================================================================\n * Restore the heap property by moving down the tree starting at node k,\n * exchanging a node with the smallest of its two sons if necessary, stopping\n * when the heap property is re-established (each father smaller than its\n * two sons).\n */\nconst pqdownheap = (s, tree, k) => {\n// deflate_state *s;\n// ct_data *tree; /* the tree to restore */\n// int k; /* node to move down */\n\n const v = s.heap[k];\n let j = k << 1; /* left son of k */\n while (j <= s.heap_len) {\n /* Set j to the smallest of the two sons: */\n if (j < s.heap_len &&\n smaller(tree, s.heap[j + 1], s.heap[j], s.depth)) {\n j++;\n }\n /* Exit if v is smaller than both sons */\n if (smaller(tree, v, s.heap[j], s.depth)) { break; }\n\n /* Exchange v with the smallest son */\n s.heap[k] = s.heap[j];\n k = j;\n\n /* And continue down the tree, setting j to the left son of k */\n j <<= 1;\n }\n s.heap[k] = v;\n};\n\n\n// inlined manually\n// const SMALLEST = 1;\n\n/* ===========================================================================\n * Send the block data compressed using the given Huffman trees\n */\nconst compress_block = (s, ltree, dtree) => {\n// deflate_state *s;\n// const ct_data *ltree; /* literal tree */\n// const ct_data *dtree; /* distance tree */\n\n let dist; /* distance of matched string */\n let lc; /* match length or unmatched char (if dist == 0) */\n let sx = 0; /* running index in sym_buf */\n let code; /* the code to send */\n let extra; /* number of extra bits to send */\n\n if (s.sym_next !== 0) {\n do {\n dist = s.pending_buf[s.sym_buf + sx++] & 0xff;\n dist += (s.pending_buf[s.sym_buf + sx++] & 0xff) << 8;\n lc = s.pending_buf[s.sym_buf + sx++];\n if (dist === 0) {\n send_code(s, lc, ltree); /* send a literal byte */\n //Tracecv(isgraph(lc), (stderr,\" '%c' \", lc));\n } else {\n /* Here, lc is the match length - MIN_MATCH */\n code = _length_code[lc];\n send_code(s, code + LITERALS$1 + 1, ltree); /* send the length code */\n extra = extra_lbits[code];\n if (extra !== 0) {\n lc -= base_length[code];\n send_bits(s, lc, extra); /* send the extra length bits */\n }\n dist--; /* dist is now the match distance - 1 */\n code = d_code(dist);\n //Assert (code < D_CODES, \"bad d_code\");\n\n send_code(s, code, dtree); /* send the distance code */\n extra = extra_dbits[code];\n if (extra !== 0) {\n dist -= base_dist[code];\n send_bits(s, dist, extra); /* send the extra distance bits */\n }\n } /* literal or match pair ? */\n\n /* Check that the overlay between pending_buf and sym_buf is ok: */\n //Assert(s->pending < s->lit_bufsize + sx, \"pendingBuf overflow\");\n\n } while (sx < s.sym_next);\n }\n\n send_code(s, END_BLOCK, ltree);\n};\n\n\n/* ===========================================================================\n * Construct one Huffman tree and assigns the code bit strings and lengths.\n * Update the total bit length for the current block.\n * IN assertion: the field freq is set for all tree elements.\n * OUT assertions: the fields len and code are set to the optimal bit length\n * and corresponding code. The length opt_len is updated; static_len is\n * also updated if stree is not null. The field max_code is set.\n */\nconst build_tree = (s, desc) => {\n// deflate_state *s;\n// tree_desc *desc; /* the tree descriptor */\n\n const tree = desc.dyn_tree;\n const stree = desc.stat_desc.static_tree;\n const has_stree = desc.stat_desc.has_stree;\n const elems = desc.stat_desc.elems;\n let n, m; /* iterate over heap elements */\n let max_code = -1; /* largest code with non zero frequency */\n let node; /* new node being created */\n\n /* Construct the initial heap, with least frequent element in\n * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1].\n * heap[0] is not used.\n */\n s.heap_len = 0;\n s.heap_max = HEAP_SIZE$1;\n\n for (n = 0; n < elems; n++) {\n if (tree[n * 2]/*.Freq*/ !== 0) {\n s.heap[++s.heap_len] = max_code = n;\n s.depth[n] = 0;\n\n } else {\n tree[n * 2 + 1]/*.Len*/ = 0;\n }\n }\n\n /* The pkzip format requires that at least one distance code exists,\n * and that at least one bit should be sent even if there is only one\n * possible code. So to avoid special checks later on we force at least\n * two codes of non zero frequency.\n */\n while (s.heap_len < 2) {\n node = s.heap[++s.heap_len] = (max_code < 2 ? ++max_code : 0);\n tree[node * 2]/*.Freq*/ = 1;\n s.depth[node] = 0;\n s.opt_len--;\n\n if (has_stree) {\n s.static_len -= stree[node * 2 + 1]/*.Len*/;\n }\n /* node is 0 or 1 so it does not have extra bits */\n }\n desc.max_code = max_code;\n\n /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree,\n * establish sub-heaps of increasing lengths:\n */\n for (n = (s.heap_len >> 1/*int /2*/); n >= 1; n--) { pqdownheap(s, tree, n); }\n\n /* Construct the Huffman tree by repeatedly combining the least two\n * frequent nodes.\n */\n node = elems; /* next internal node of the tree */\n do {\n //pqremove(s, tree, n); /* n = node of least frequency */\n /*** pqremove ***/\n n = s.heap[1/*SMALLEST*/];\n s.heap[1/*SMALLEST*/] = s.heap[s.heap_len--];\n pqdownheap(s, tree, 1/*SMALLEST*/);\n /***/\n\n m = s.heap[1/*SMALLEST*/]; /* m = node of next least frequency */\n\n s.heap[--s.heap_max] = n; /* keep the nodes sorted by frequency */\n s.heap[--s.heap_max] = m;\n\n /* Create a new node father of n and m */\n tree[node * 2]/*.Freq*/ = tree[n * 2]/*.Freq*/ + tree[m * 2]/*.Freq*/;\n s.depth[node] = (s.depth[n] >= s.depth[m] ? s.depth[n] : s.depth[m]) + 1;\n tree[n * 2 + 1]/*.Dad*/ = tree[m * 2 + 1]/*.Dad*/ = node;\n\n /* and insert the new node in the heap */\n s.heap[1/*SMALLEST*/] = node++;\n pqdownheap(s, tree, 1/*SMALLEST*/);\n\n } while (s.heap_len >= 2);\n\n s.heap[--s.heap_max] = s.heap[1/*SMALLEST*/];\n\n /* At this point, the fields freq and dad are set. We can now\n * generate the bit lengths.\n */\n gen_bitlen(s, desc);\n\n /* The field len is now set, we can generate the bit codes */\n gen_codes(tree, max_code, s.bl_count);\n};\n\n\n/* ===========================================================================\n * Scan a literal or distance tree to determine the frequencies of the codes\n * in the bit length tree.\n */\nconst scan_tree = (s, tree, max_code) => {\n// deflate_state *s;\n// ct_data *tree; /* the tree to be scanned */\n// int max_code; /* and its largest code of non zero frequency */\n\n let n; /* iterates over all tree elements */\n let prevlen = -1; /* last emitted length */\n let curlen; /* length of current code */\n\n let nextlen = tree[0 * 2 + 1]/*.Len*/; /* length of next code */\n\n let count = 0; /* repeat count of the current code */\n let max_count = 7; /* max repeat count */\n let min_count = 4; /* min repeat count */\n\n if (nextlen === 0) {\n max_count = 138;\n min_count = 3;\n }\n tree[(max_code + 1) * 2 + 1]/*.Len*/ = 0xffff; /* guard */\n\n for (n = 0; n <= max_code; n++) {\n curlen = nextlen;\n nextlen = tree[(n + 1) * 2 + 1]/*.Len*/;\n\n if (++count < max_count && curlen === nextlen) {\n continue;\n\n } else if (count < min_count) {\n s.bl_tree[curlen * 2]/*.Freq*/ += count;\n\n } else if (curlen !== 0) {\n\n if (curlen !== prevlen) { s.bl_tree[curlen * 2]/*.Freq*/++; }\n s.bl_tree[REP_3_6 * 2]/*.Freq*/++;\n\n } else if (count <= 10) {\n s.bl_tree[REPZ_3_10 * 2]/*.Freq*/++;\n\n } else {\n s.bl_tree[REPZ_11_138 * 2]/*.Freq*/++;\n }\n\n count = 0;\n prevlen = curlen;\n\n if (nextlen === 0) {\n max_count = 138;\n min_count = 3;\n\n } else if (curlen === nextlen) {\n max_count = 6;\n min_count = 3;\n\n } else {\n max_count = 7;\n min_count = 4;\n }\n }\n};\n\n\n/* ===========================================================================\n * Send a literal or distance tree in compressed form, using the codes in\n * bl_tree.\n */\nconst send_tree = (s, tree, max_code) => {\n// deflate_state *s;\n// ct_data *tree; /* the tree to be scanned */\n// int max_code; /* and its largest code of non zero frequency */\n\n let n; /* iterates over all tree elements */\n let prevlen = -1; /* last emitted length */\n let curlen; /* length of current code */\n\n let nextlen = tree[0 * 2 + 1]/*.Len*/; /* length of next code */\n\n let count = 0; /* repeat count of the current code */\n let max_count = 7; /* max repeat count */\n let min_count = 4; /* min repeat count */\n\n /* tree[max_code+1].Len = -1; */ /* guard already set */\n if (nextlen === 0) {\n max_count = 138;\n min_count = 3;\n }\n\n for (n = 0; n <= max_code; n++) {\n curlen = nextlen;\n nextlen = tree[(n + 1) * 2 + 1]/*.Len*/;\n\n if (++count < max_count && curlen === nextlen) {\n continue;\n\n } else if (count < min_count) {\n do { send_code(s, curlen, s.bl_tree); } while (--count !== 0);\n\n } else if (curlen !== 0) {\n if (curlen !== prevlen) {\n send_code(s, curlen, s.bl_tree);\n count--;\n }\n //Assert(count >= 3 && count <= 6, \" 3_6?\");\n send_code(s, REP_3_6, s.bl_tree);\n send_bits(s, count - 3, 2);\n\n } else if (count <= 10) {\n send_code(s, REPZ_3_10, s.bl_tree);\n send_bits(s, count - 3, 3);\n\n } else {\n send_code(s, REPZ_11_138, s.bl_tree);\n send_bits(s, count - 11, 7);\n }\n\n count = 0;\n prevlen = curlen;\n if (nextlen === 0) {\n max_count = 138;\n min_count = 3;\n\n } else if (curlen === nextlen) {\n max_count = 6;\n min_count = 3;\n\n } else {\n max_count = 7;\n min_count = 4;\n }\n }\n};\n\n\n/* ===========================================================================\n * Construct the Huffman tree for the bit lengths and return the index in\n * bl_order of the last bit length code to send.\n */\nconst build_bl_tree = (s) => {\n\n let max_blindex; /* index of last bit length code of non zero freq */\n\n /* Determine the bit length frequencies for literal and distance trees */\n scan_tree(s, s.dyn_ltree, s.l_desc.max_code);\n scan_tree(s, s.dyn_dtree, s.d_desc.max_code);\n\n /* Build the bit length tree: */\n build_tree(s, s.bl_desc);\n /* opt_len now includes the length of the tree representations, except\n * the lengths of the bit lengths codes and the 5+5+4 bits for the counts.\n */\n\n /* Determine the number of bit length codes to send. The pkzip format\n * requires that at least 4 bit length codes be sent. (appnote.txt says\n * 3 but the actual value used is 4.)\n */\n for (max_blindex = BL_CODES$1 - 1; max_blindex >= 3; max_blindex--) {\n if (s.bl_tree[bl_order[max_blindex] * 2 + 1]/*.Len*/ !== 0) {\n break;\n }\n }\n /* Update opt_len to include the bit length tree and counts */\n s.opt_len += 3 * (max_blindex + 1) + 5 + 5 + 4;\n //Tracev((stderr, \"\\ndyn trees: dyn %ld, stat %ld\",\n // s->opt_len, s->static_len));\n\n return max_blindex;\n};\n\n\n/* ===========================================================================\n * Send the header for a block using dynamic Huffman trees: the counts, the\n * lengths of the bit length codes, the literal tree and the distance tree.\n * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4.\n */\nconst send_all_trees = (s, lcodes, dcodes, blcodes) => {\n// deflate_state *s;\n// int lcodes, dcodes, blcodes; /* number of codes for each tree */\n\n let rank; /* index in bl_order */\n\n //Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, \"not enough codes\");\n //Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES,\n // \"too many codes\");\n //Tracev((stderr, \"\\nbl counts: \"));\n send_bits(s, lcodes - 257, 5); /* not +255 as stated in appnote.txt */\n send_bits(s, dcodes - 1, 5);\n send_bits(s, blcodes - 4, 4); /* not -3 as stated in appnote.txt */\n for (rank = 0; rank < blcodes; rank++) {\n //Tracev((stderr, \"\\nbl code %2d \", bl_order[rank]));\n send_bits(s, s.bl_tree[bl_order[rank] * 2 + 1]/*.Len*/, 3);\n }\n //Tracev((stderr, \"\\nbl tree: sent %ld\", s->bits_sent));\n\n send_tree(s, s.dyn_ltree, lcodes - 1); /* literal tree */\n //Tracev((stderr, \"\\nlit tree: sent %ld\", s->bits_sent));\n\n send_tree(s, s.dyn_dtree, dcodes - 1); /* distance tree */\n //Tracev((stderr, \"\\ndist tree: sent %ld\", s->bits_sent));\n};\n\n\n/* ===========================================================================\n * Check if the data type is TEXT or BINARY, using the following algorithm:\n * - TEXT if the two conditions below are satisfied:\n * a) There are no non-portable control characters belonging to the\n * \"block list\" (0..6, 14..25, 28..31).\n * b) There is at least one printable character belonging to the\n * \"allow list\" (9 {TAB}, 10 {LF}, 13 {CR}, 32..255).\n * - BINARY otherwise.\n * - The following partially-portable control characters form a\n * \"gray list\" that is ignored in this detection algorithm:\n * (7 {BEL}, 8 {BS}, 11 {VT}, 12 {FF}, 26 {SUB}, 27 {ESC}).\n * IN assertion: the fields Freq of dyn_ltree are set.\n */\nconst detect_data_type = (s) => {\n /* block_mask is the bit mask of block-listed bytes\n * set bits 0..6, 14..25, and 28..31\n * 0xf3ffc07f = binary 11110011111111111100000001111111\n */\n let block_mask = 0xf3ffc07f;\n let n;\n\n /* Check for non-textual (\"block-listed\") bytes. */\n for (n = 0; n <= 31; n++, block_mask >>>= 1) {\n if ((block_mask & 1) && (s.dyn_ltree[n * 2]/*.Freq*/ !== 0)) {\n return Z_BINARY;\n }\n }\n\n /* Check for textual (\"allow-listed\") bytes. */\n if (s.dyn_ltree[9 * 2]/*.Freq*/ !== 0 || s.dyn_ltree[10 * 2]/*.Freq*/ !== 0 ||\n s.dyn_ltree[13 * 2]/*.Freq*/ !== 0) {\n return Z_TEXT;\n }\n for (n = 32; n < LITERALS$1; n++) {\n if (s.dyn_ltree[n * 2]/*.Freq*/ !== 0) {\n return Z_TEXT;\n }\n }\n\n /* There are no \"block-listed\" or \"allow-listed\" bytes:\n * this stream either is empty or has tolerated (\"gray-listed\") bytes only.\n */\n return Z_BINARY;\n};\n\n\nlet static_init_done = false;\n\n/* ===========================================================================\n * Initialize the tree data structures for a new zlib stream.\n */\nconst _tr_init$1 = (s) =>\n{\n\n if (!static_init_done) {\n tr_static_init();\n static_init_done = true;\n }\n\n s.l_desc = new TreeDesc(s.dyn_ltree, static_l_desc);\n s.d_desc = new TreeDesc(s.dyn_dtree, static_d_desc);\n s.bl_desc = new TreeDesc(s.bl_tree, static_bl_desc);\n\n s.bi_buf = 0;\n s.bi_valid = 0;\n\n /* Initialize the first block of the first file: */\n init_block(s);\n};\n\n\n/* ===========================================================================\n * Send a stored block\n */\nconst _tr_stored_block$1 = (s, buf, stored_len, last) => {\n//DeflateState *s;\n//charf *buf; /* input block */\n//ulg stored_len; /* length of input block */\n//int last; /* one if this is the last block for a file */\n\n send_bits(s, (STORED_BLOCK << 1) + (last ? 1 : 0), 3); /* send block type */\n bi_windup(s); /* align on byte boundary */\n put_short(s, stored_len);\n put_short(s, ~stored_len);\n if (stored_len) {\n s.pending_buf.set(s.window.subarray(buf, buf + stored_len), s.pending);\n }\n s.pending += stored_len;\n};\n\n\n/* ===========================================================================\n * Send one empty static block to give enough lookahead for inflate.\n * This takes 10 bits, of which 7 may remain in the bit buffer.\n */\nconst _tr_align$1 = (s) => {\n send_bits(s, STATIC_TREES << 1, 3);\n send_code(s, END_BLOCK, static_ltree);\n bi_flush(s);\n};\n\n\n/* ===========================================================================\n * Determine the best encoding for the current block: dynamic trees, static\n * trees or store, and write out the encoded block.\n */\nconst _tr_flush_block$1 = (s, buf, stored_len, last) => {\n//DeflateState *s;\n//charf *buf; /* input block, or NULL if too old */\n//ulg stored_len; /* length of input block */\n//int last; /* one if this is the last block for a file */\n\n let opt_lenb, static_lenb; /* opt_len and static_len in bytes */\n let max_blindex = 0; /* index of last bit length code of non zero freq */\n\n /* Build the Huffman trees unless a stored block is forced */\n if (s.level > 0) {\n\n /* Check if the file is binary or text */\n if (s.strm.data_type === Z_UNKNOWN$1) {\n s.strm.data_type = detect_data_type(s);\n }\n\n /* Construct the literal and distance trees */\n build_tree(s, s.l_desc);\n // Tracev((stderr, \"\\nlit data: dyn %ld, stat %ld\", s->opt_len,\n // s->static_len));\n\n build_tree(s, s.d_desc);\n // Tracev((stderr, \"\\ndist data: dyn %ld, stat %ld\", s->opt_len,\n // s->static_len));\n /* At this point, opt_len and static_len are the total bit lengths of\n * the compressed block data, excluding the tree representations.\n */\n\n /* Build the bit length tree for the above two trees, and get the index\n * in bl_order of the last bit length code to send.\n */\n max_blindex = build_bl_tree(s);\n\n /* Determine the best encoding. Compute the block lengths in bytes. */\n opt_lenb = (s.opt_len + 3 + 7) >>> 3;\n static_lenb = (s.static_len + 3 + 7) >>> 3;\n\n // Tracev((stderr, \"\\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u \",\n // opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len,\n // s->sym_next / 3));\n\n if (static_lenb <= opt_lenb) { opt_lenb = static_lenb; }\n\n } else {\n // Assert(buf != (char*)0, \"lost buf\");\n opt_lenb = static_lenb = stored_len + 5; /* force a stored block */\n }\n\n if ((stored_len + 4 <= opt_lenb) && (buf !== -1)) {\n /* 4: two words for the lengths */\n\n /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE.\n * Otherwise we can't have processed more than WSIZE input bytes since\n * the last block flush, because compression would have been\n * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to\n * transform a block into a stored block.\n */\n _tr_stored_block$1(s, buf, stored_len, last);\n\n } else if (s.strategy === Z_FIXED$1 || static_lenb === opt_lenb) {\n\n send_bits(s, (STATIC_TREES << 1) + (last ? 1 : 0), 3);\n compress_block(s, static_ltree, static_dtree);\n\n } else {\n send_bits(s, (DYN_TREES << 1) + (last ? 1 : 0), 3);\n send_all_trees(s, s.l_desc.max_code + 1, s.d_desc.max_code + 1, max_blindex + 1);\n compress_block(s, s.dyn_ltree, s.dyn_dtree);\n }\n // Assert (s->compressed_len == s->bits_sent, \"bad compressed size\");\n /* The above check is made mod 2^32, for files larger than 512 MB\n * and uLong implemented on 32 bits.\n */\n init_block(s);\n\n if (last) {\n bi_windup(s);\n }\n // Tracev((stderr,\"\\ncomprlen %lu(%lu) \", s->compressed_len>>3,\n // s->compressed_len-7*last));\n};\n\n/* ===========================================================================\n * Save the match info and tally the frequency counts. Return true if\n * the current block must be flushed.\n */\nconst _tr_tally$1 = (s, dist, lc) => {\n// deflate_state *s;\n// unsigned dist; /* distance of matched string */\n// unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */\n\n s.pending_buf[s.sym_buf + s.sym_next++] = dist;\n s.pending_buf[s.sym_buf + s.sym_next++] = dist >> 8;\n s.pending_buf[s.sym_buf + s.sym_next++] = lc;\n if (dist === 0) {\n /* lc is the unmatched char */\n s.dyn_ltree[lc * 2]/*.Freq*/++;\n } else {\n s.matches++;\n /* Here, lc is the match length - MIN_MATCH */\n dist--; /* dist = match distance - 1 */\n //Assert((ush)dist < (ush)MAX_DIST(s) &&\n // (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) &&\n // (ush)d_code(dist) < (ush)D_CODES, \"_tr_tally: bad match\");\n\n s.dyn_ltree[(_length_code[lc] + LITERALS$1 + 1) * 2]/*.Freq*/++;\n s.dyn_dtree[d_code(dist) * 2]/*.Freq*/++;\n }\n\n return (s.sym_next === s.sym_end);\n};\n\nvar _tr_init_1 = _tr_init$1;\nvar _tr_stored_block_1 = _tr_stored_block$1;\nvar _tr_flush_block_1 = _tr_flush_block$1;\nvar _tr_tally_1 = _tr_tally$1;\nvar _tr_align_1 = _tr_align$1;\n\nvar trees = {\n\t_tr_init: _tr_init_1,\n\t_tr_stored_block: _tr_stored_block_1,\n\t_tr_flush_block: _tr_flush_block_1,\n\t_tr_tally: _tr_tally_1,\n\t_tr_align: _tr_align_1\n};\n\n// Note: adler32 takes 12% for level 0 and 2% for level 6.\n// It isn't worth it to make additional optimizations as in original.\n// Small size is preferable.\n\n// (C) 1995-2013 Jean-loup Gailly and Mark Adler\n// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin\n//\n// This software is provided 'as-is', without any express or implied\n// warranty. In no event will the authors be held liable for any damages\n// arising from the use of this software.\n//\n// Permission is granted to anyone to use this software for any purpose,\n// including commercial applications, and to alter it and redistribute it\n// freely, subject to the following restrictions:\n//\n// 1. The origin of this software must not be misrepresented; you must not\n// claim that you wrote the original software. If you use this software\n// in a product, an acknowledgment in the product documentation would be\n// appreciated but is not required.\n// 2. Altered source versions must be plainly marked as such, and must not be\n// misrepresented as being the original software.\n// 3. This notice may not be removed or altered from any source distribution.\n\nconst adler32 = (adler, buf, len, pos) => {\n let s1 = (adler & 0xffff) |0,\n s2 = ((adler >>> 16) & 0xffff) |0,\n n = 0;\n\n while (len !== 0) {\n // Set limit ~ twice less than 5552, to keep\n // s2 in 31-bits, because we force signed ints.\n // in other case %= will fail.\n n = len > 2000 ? 2000 : len;\n len -= n;\n\n do {\n s1 = (s1 + buf[pos++]) |0;\n s2 = (s2 + s1) |0;\n } while (--n);\n\n s1 %= 65521;\n s2 %= 65521;\n }\n\n return (s1 | (s2 << 16)) |0;\n};\n\n\nvar adler32_1 = adler32;\n\n// Note: we can't get significant speed boost here.\n// So write code to minimize size - no pregenerated tables\n// and array tools dependencies.\n\n// (C) 1995-2013 Jean-loup Gailly and Mark Adler\n// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin\n//\n// This software is provided 'as-is', without any express or implied\n// warranty. In no event will the authors be held liable for any damages\n// arising from the use of this software.\n//\n// Permission is granted to anyone to use this software for any purpose,\n// including commercial applications, and to alter it and redistribute it\n// freely, subject to the following restrictions:\n//\n// 1. The origin of this software must not be misrepresented; you must not\n// claim that you wrote the original software. If you use this software\n// in a product, an acknowledgment in the product documentation would be\n// appreciated but is not required.\n// 2. Altered source versions must be plainly marked as such, and must not be\n// misrepresented as being the original software.\n// 3. This notice may not be removed or altered from any source distribution.\n\n// Use ordinary array, since untyped makes no boost here\nconst makeTable = () => {\n let c, table = [];\n\n for (var n = 0; n < 256; n++) {\n c = n;\n for (var k = 0; k < 8; k++) {\n c = ((c & 1) ? (0xEDB88320 ^ (c >>> 1)) : (c >>> 1));\n }\n table[n] = c;\n }\n\n return table;\n};\n\n// Create table on load. Just 255 signed longs. Not a problem.\nconst crcTable = new Uint32Array(makeTable());\n\n\nconst crc32 = (crc, buf, len, pos) => {\n const t = crcTable;\n const end = pos + len;\n\n crc ^= -1;\n\n for (let i = pos; i < end; i++) {\n crc = (crc >>> 8) ^ t[(crc ^ buf[i]) & 0xFF];\n }\n\n return (crc ^ (-1)); // >>> 0;\n};\n\n\nvar crc32_1 = crc32;\n\n// (C) 1995-2013 Jean-loup Gailly and Mark Adler\n// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin\n//\n// This software is provided 'as-is', without any express or implied\n// warranty. In no event will the authors be held liable for any damages\n// arising from the use of this software.\n//\n// Permission is granted to anyone to use this software for any purpose,\n// including commercial applications, and to alter it and redistribute it\n// freely, subject to the following restrictions:\n//\n// 1. The origin of this software must not be misrepresented; you must not\n// claim that you wrote the original software. If you use this software\n// in a product, an acknowledgment in the product documentation would be\n// appreciated but is not required.\n// 2. Altered source versions must be plainly marked as such, and must not be\n// misrepresented as being the original software.\n// 3. This notice may not be removed or altered from any source distribution.\n\nvar messages = {\n 2: 'need dictionary', /* Z_NEED_DICT 2 */\n 1: 'stream end', /* Z_STREAM_END 1 */\n 0: '', /* Z_OK 0 */\n '-1': 'file error', /* Z_ERRNO (-1) */\n '-2': 'stream error', /* Z_STREAM_ERROR (-2) */\n '-3': 'data error', /* Z_DATA_ERROR (-3) */\n '-4': 'insufficient memory', /* Z_MEM_ERROR (-4) */\n '-5': 'buffer error', /* Z_BUF_ERROR (-5) */\n '-6': 'incompatible version' /* Z_VERSION_ERROR (-6) */\n};\n\n// (C) 1995-2013 Jean-loup Gailly and Mark Adler\n// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin\n//\n// This software is provided 'as-is', without any express or implied\n// warranty. In no event will the authors be held liable for any damages\n// arising from the use of this software.\n//\n// Permission is granted to anyone to use this software for any purpose,\n// including commercial applications, and to alter it and redistribute it\n// freely, subject to the following restrictions:\n//\n// 1. The origin of this software must not be misrepresented; you must not\n// claim that you wrote the original software. If you use this software\n// in a product, an acknowledgment in the product documentation would be\n// appreciated but is not required.\n// 2. Altered source versions must be plainly marked as such, and must not be\n// misrepresented as being the original software.\n// 3. This notice may not be removed or altered from any source distribution.\n\nvar constants$2 = {\n\n /* Allowed flush values; see deflate() and inflate() below for details */\n Z_NO_FLUSH: 0,\n Z_PARTIAL_FLUSH: 1,\n Z_SYNC_FLUSH: 2,\n Z_FULL_FLUSH: 3,\n Z_FINISH: 4,\n Z_BLOCK: 5,\n Z_TREES: 6,\n\n /* Return codes for the compression/decompression functions. Negative values\n * are errors, positive values are used for special but normal events.\n */\n Z_OK: 0,\n Z_STREAM_END: 1,\n Z_NEED_DICT: 2,\n Z_ERRNO: -1,\n Z_STREAM_ERROR: -2,\n Z_DATA_ERROR: -3,\n Z_MEM_ERROR: -4,\n Z_BUF_ERROR: -5,\n //Z_VERSION_ERROR: -6,\n\n /* compression levels */\n Z_NO_COMPRESSION: 0,\n Z_BEST_SPEED: 1,\n Z_BEST_COMPRESSION: 9,\n Z_DEFAULT_COMPRESSION: -1,\n\n\n Z_FILTERED: 1,\n Z_HUFFMAN_ONLY: 2,\n Z_RLE: 3,\n Z_FIXED: 4,\n Z_DEFAULT_STRATEGY: 0,\n\n /* Possible values of the data_type field (though see inflate()) */\n Z_BINARY: 0,\n Z_TEXT: 1,\n //Z_ASCII: 1, // = Z_TEXT (deprecated)\n Z_UNKNOWN: 2,\n\n /* The deflate compression method */\n Z_DEFLATED: 8\n //Z_NULL: null // Use -1 or null inline, depending on var type\n};\n\n// (C) 1995-2013 Jean-loup Gailly and Mark Adler\n// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin\n//\n// This software is provided 'as-is', without any express or implied\n// warranty. In no event will the authors be held liable for any damages\n// arising from the use of this software.\n//\n// Permission is granted to anyone to use this software for any purpose,\n// including commercial applications, and to alter it and redistribute it\n// freely, subject to the following restrictions:\n//\n// 1. The origin of this software must not be misrepresented; you must not\n// claim that you wrote the original software. If you use this software\n// in a product, an acknowledgment in the product documentation would be\n// appreciated but is not required.\n// 2. Altered source versions must be plainly marked as such, and must not be\n// misrepresented as being the original software.\n// 3. This notice may not be removed or altered from any source distribution.\n\nconst { _tr_init, _tr_stored_block, _tr_flush_block, _tr_tally, _tr_align } = trees;\n\n\n\n\n/* Public constants ==========================================================*/\n/* ===========================================================================*/\n\nconst {\n Z_NO_FLUSH: Z_NO_FLUSH$2, Z_PARTIAL_FLUSH, Z_FULL_FLUSH: Z_FULL_FLUSH$1, Z_FINISH: Z_FINISH$3, Z_BLOCK: Z_BLOCK$1,\n Z_OK: Z_OK$3, Z_STREAM_END: Z_STREAM_END$3, Z_STREAM_ERROR: Z_STREAM_ERROR$2, Z_DATA_ERROR: Z_DATA_ERROR$2, Z_BUF_ERROR: Z_BUF_ERROR$1,\n Z_DEFAULT_COMPRESSION: Z_DEFAULT_COMPRESSION$1,\n Z_FILTERED, Z_HUFFMAN_ONLY, Z_RLE, Z_FIXED, Z_DEFAULT_STRATEGY: Z_DEFAULT_STRATEGY$1,\n Z_UNKNOWN,\n Z_DEFLATED: Z_DEFLATED$2\n} = constants$2;\n\n/*============================================================================*/\n\n\nconst MAX_MEM_LEVEL = 9;\n/* Maximum value for memLevel in deflateInit2 */\nconst MAX_WBITS$1 = 15;\n/* 32K LZ77 window */\nconst DEF_MEM_LEVEL = 8;\n\n\nconst LENGTH_CODES = 29;\n/* number of length codes, not counting the special END_BLOCK code */\nconst LITERALS = 256;\n/* number of literal bytes 0..255 */\nconst L_CODES = LITERALS + 1 + LENGTH_CODES;\n/* number of Literal or Length codes, including the END_BLOCK code */\nconst D_CODES = 30;\n/* number of distance codes */\nconst BL_CODES = 19;\n/* number of codes used to transfer the bit lengths */\nconst HEAP_SIZE = 2 * L_CODES + 1;\n/* maximum heap size */\nconst MAX_BITS = 15;\n/* All codes must not exceed MAX_BITS bits */\n\nconst MIN_MATCH = 3;\nconst MAX_MATCH = 258;\nconst MIN_LOOKAHEAD = (MAX_MATCH + MIN_MATCH + 1);\n\nconst PRESET_DICT = 0x20;\n\nconst INIT_STATE = 42; /* zlib header -> BUSY_STATE */\n//#ifdef GZIP\nconst GZIP_STATE = 57; /* gzip header -> BUSY_STATE | EXTRA_STATE */\n//#endif\nconst EXTRA_STATE = 69; /* gzip extra block -> NAME_STATE */\nconst NAME_STATE = 73; /* gzip file name -> COMMENT_STATE */\nconst COMMENT_STATE = 91; /* gzip comment -> HCRC_STATE */\nconst HCRC_STATE = 103; /* gzip header CRC -> BUSY_STATE */\nconst BUSY_STATE = 113; /* deflate -> FINISH_STATE */\nconst FINISH_STATE = 666; /* stream complete */\n\nconst BS_NEED_MORE = 1; /* block not completed, need more input or more output */\nconst BS_BLOCK_DONE = 2; /* block flush performed */\nconst BS_FINISH_STARTED = 3; /* finish started, need only more output at next deflate */\nconst BS_FINISH_DONE = 4; /* finish done, accept no more input or output */\n\nconst OS_CODE = 0x03; // Unix :) . Don't detect, use this default.\n\nconst err = (strm, errorCode) => {\n strm.msg = messages[errorCode];\n return errorCode;\n};\n\nconst rank = (f) => {\n return ((f) * 2) - ((f) > 4 ? 9 : 0);\n};\n\nconst zero = (buf) => {\n let len = buf.length; while (--len >= 0) { buf[len] = 0; }\n};\n\n/* ===========================================================================\n * Slide the hash table when sliding the window down (could be avoided with 32\n * bit values at the expense of memory usage). We slide even when level == 0 to\n * keep the hash table consistent if we switch back to level > 0 later.\n */\nconst slide_hash = (s) => {\n let n, m;\n let p;\n let wsize = s.w_size;\n\n n = s.hash_size;\n p = n;\n do {\n m = s.head[--p];\n s.head[p] = (m >= wsize ? m - wsize : 0);\n } while (--n);\n n = wsize;\n//#ifndef FASTEST\n p = n;\n do {\n m = s.prev[--p];\n s.prev[p] = (m >= wsize ? m - wsize : 0);\n /* If n is not on any hash chain, prev[n] is garbage but\n * its value will never be used.\n */\n } while (--n);\n//#endif\n};\n\n/* eslint-disable new-cap */\nlet HASH_ZLIB = (s, prev, data) => ((prev << s.hash_shift) ^ data) & s.hash_mask;\n// This hash causes less collisions, https://github.com/nodeca/pako/issues/135\n// But breaks binary compatibility\n//let HASH_FAST = (s, prev, data) => ((prev << 8) + (prev >> 8) + (data << 4)) & s.hash_mask;\nlet HASH = HASH_ZLIB;\n\n\n/* =========================================================================\n * Flush as much pending output as possible. All deflate() output, except for\n * some deflate_stored() output, goes through this function so some\n * applications may wish to modify it to avoid allocating a large\n * strm->next_out buffer and copying into it. (See also read_buf()).\n */\nconst flush_pending = (strm) => {\n const s = strm.state;\n\n //_tr_flush_bits(s);\n let len = s.pending;\n if (len > strm.avail_out) {\n len = strm.avail_out;\n }\n if (len === 0) { return; }\n\n strm.output.set(s.pending_buf.subarray(s.pending_out, s.pending_out + len), strm.next_out);\n strm.next_out += len;\n s.pending_out += len;\n strm.total_out += len;\n strm.avail_out -= len;\n s.pending -= len;\n if (s.pending === 0) {\n s.pending_out = 0;\n }\n};\n\n\nconst flush_block_only = (s, last) => {\n _tr_flush_block(s, (s.block_start >= 0 ? s.block_start : -1), s.strstart - s.block_start, last);\n s.block_start = s.strstart;\n flush_pending(s.strm);\n};\n\n\nconst put_byte = (s, b) => {\n s.pending_buf[s.pending++] = b;\n};\n\n\n/* =========================================================================\n * Put a short in the pending buffer. The 16-bit value is put in MSB order.\n * IN assertion: the stream state is correct and there is enough room in\n * pending_buf.\n */\nconst putShortMSB = (s, b) => {\n\n // put_byte(s, (Byte)(b >> 8));\n// put_byte(s, (Byte)(b & 0xff));\n s.pending_buf[s.pending++] = (b >>> 8) & 0xff;\n s.pending_buf[s.pending++] = b & 0xff;\n};\n\n\n/* ===========================================================================\n * Read a new buffer from the current input stream, update the adler32\n * and total number of bytes read. All deflate() input goes through\n * this function so some applications may wish to modify it to avoid\n * allocating a large strm->input buffer and copying from it.\n * (See also flush_pending()).\n */\nconst read_buf = (strm, buf, start, size) => {\n\n let len = strm.avail_in;\n\n if (len > size) { len = size; }\n if (len === 0) { return 0; }\n\n strm.avail_in -= len;\n\n // zmemcpy(buf, strm->next_in, len);\n buf.set(strm.input.subarray(strm.next_in, strm.next_in + len), start);\n if (strm.state.wrap === 1) {\n strm.adler = adler32_1(strm.adler, buf, len, start);\n }\n\n else if (strm.state.wrap === 2) {\n strm.adler = crc32_1(strm.adler, buf, len, start);\n }\n\n strm.next_in += len;\n strm.total_in += len;\n\n return len;\n};\n\n\n/* ===========================================================================\n * Set match_start to the longest match starting at the given string and\n * return its length. Matches shorter or equal to prev_length are discarded,\n * in which case the result is equal to prev_length and match_start is\n * garbage.\n * IN assertions: cur_match is the head of the hash chain for the current\n * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1\n * OUT assertion: the match length is not greater than s->lookahead.\n */\nconst longest_match = (s, cur_match) => {\n\n let chain_length = s.max_chain_length; /* max hash chain length */\n let scan = s.strstart; /* current string */\n let match; /* matched string */\n let len; /* length of current match */\n let best_len = s.prev_length; /* best match length so far */\n let nice_match = s.nice_match; /* stop if match long enough */\n const limit = (s.strstart > (s.w_size - MIN_LOOKAHEAD)) ?\n s.strstart - (s.w_size - MIN_LOOKAHEAD) : 0/*NIL*/;\n\n const _win = s.window; // shortcut\n\n const wmask = s.w_mask;\n const prev = s.prev;\n\n /* Stop when cur_match becomes <= limit. To simplify the code,\n * we prevent matches with the string of window index 0.\n */\n\n const strend = s.strstart + MAX_MATCH;\n let scan_end1 = _win[scan + best_len - 1];\n let scan_end = _win[scan + best_len];\n\n /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.\n * It is easy to get rid of this optimization if necessary.\n */\n // Assert(s->hash_bits >= 8 && MAX_MATCH == 258, \"Code too clever\");\n\n /* Do not waste too much time if we already have a good match: */\n if (s.prev_length >= s.good_match) {\n chain_length >>= 2;\n }\n /* Do not look for matches beyond the end of the input. This is necessary\n * to make deflate deterministic.\n */\n if (nice_match > s.lookahead) { nice_match = s.lookahead; }\n\n // Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, \"need lookahead\");\n\n do {\n // Assert(cur_match < s->strstart, \"no future\");\n match = cur_match;\n\n /* Skip to next match if the match length cannot increase\n * or if the match length is less than 2. Note that the checks below\n * for insufficient lookahead only occur occasionally for performance\n * reasons. Therefore uninitialized memory will be accessed, and\n * conditional jumps will be made that depend on those values.\n * However the length of the match is limited to the lookahead, so\n * the output of deflate is not affected by the uninitialized values.\n */\n\n if (_win[match + best_len] !== scan_end ||\n _win[match + best_len - 1] !== scan_end1 ||\n _win[match] !== _win[scan] ||\n _win[++match] !== _win[scan + 1]) {\n continue;\n }\n\n /* The check at best_len-1 can be removed because it will be made\n * again later. (This heuristic is not always a win.)\n * It is not necessary to compare scan[2] and match[2] since they\n * are always equal when the other bytes match, given that\n * the hash keys are equal and that HASH_BITS >= 8.\n */\n scan += 2;\n match++;\n // Assert(*scan == *match, \"match[2]?\");\n\n /* We check for insufficient lookahead only every 8th comparison;\n * the 256th check will be made at strstart+258.\n */\n do {\n /*jshint noempty:false*/\n } while (_win[++scan] === _win[++match] && _win[++scan] === _win[++match] &&\n _win[++scan] === _win[++match] && _win[++scan] === _win[++match] &&\n _win[++scan] === _win[++match] && _win[++scan] === _win[++match] &&\n _win[++scan] === _win[++match] && _win[++scan] === _win[++match] &&\n scan < strend);\n\n // Assert(scan <= s->window+(unsigned)(s->window_size-1), \"wild scan\");\n\n len = MAX_MATCH - (strend - scan);\n scan = strend - MAX_MATCH;\n\n if (len > best_len) {\n s.match_start = cur_match;\n best_len = len;\n if (len >= nice_match) {\n break;\n }\n scan_end1 = _win[scan + best_len - 1];\n scan_end = _win[scan + best_len];\n }\n } while ((cur_match = prev[cur_match & wmask]) > limit && --chain_length !== 0);\n\n if (best_len <= s.lookahead) {\n return best_len;\n }\n return s.lookahead;\n};\n\n\n/* ===========================================================================\n * Fill the window when the lookahead becomes insufficient.\n * Updates strstart and lookahead.\n *\n * IN assertion: lookahead < MIN_LOOKAHEAD\n * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD\n * At least one byte has been read, or avail_in == 0; reads are\n * performed for at least two bytes (required for the zip translate_eol\n * option -- not supported here).\n */\nconst fill_window = (s) => {\n\n const _w_size = s.w_size;\n let n, more, str;\n\n //Assert(s->lookahead < MIN_LOOKAHEAD, \"already enough lookahead\");\n\n do {\n more = s.window_size - s.lookahead - s.strstart;\n\n // JS ints have 32 bit, block below not needed\n /* Deal with !@#$% 64K limit: */\n //if (sizeof(int) <= 2) {\n // if (more == 0 && s->strstart == 0 && s->lookahead == 0) {\n // more = wsize;\n //\n // } else if (more == (unsigned)(-1)) {\n // /* Very unlikely, but possible on 16 bit machine if\n // * strstart == 0 && lookahead == 1 (input done a byte at time)\n // */\n // more--;\n // }\n //}\n\n\n /* If the window is almost full and there is insufficient lookahead,\n * move the upper half to the lower one to make room in the upper half.\n */\n if (s.strstart >= _w_size + (_w_size - MIN_LOOKAHEAD)) {\n\n s.window.set(s.window.subarray(_w_size, _w_size + _w_size - more), 0);\n s.match_start -= _w_size;\n s.strstart -= _w_size;\n /* we now have strstart >= MAX_DIST */\n s.block_start -= _w_size;\n if (s.insert > s.strstart) {\n s.insert = s.strstart;\n }\n slide_hash(s);\n more += _w_size;\n }\n if (s.strm.avail_in === 0) {\n break;\n }\n\n /* If there was no sliding:\n * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 &&\n * more == window_size - lookahead - strstart\n * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1)\n * => more >= window_size - 2*WSIZE + 2\n * In the BIG_MEM or MMAP case (not yet supported),\n * window_size == input_size + MIN_LOOKAHEAD &&\n * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD.\n * Otherwise, window_size == 2*WSIZE so more >= 2.\n * If there was sliding, more >= WSIZE. So in all cases, more >= 2.\n */\n //Assert(more >= 2, \"more < 2\");\n n = read_buf(s.strm, s.window, s.strstart + s.lookahead, more);\n s.lookahead += n;\n\n /* Initialize the hash value now that we have some input: */\n if (s.lookahead + s.insert >= MIN_MATCH) {\n str = s.strstart - s.insert;\n s.ins_h = s.window[str];\n\n /* UPDATE_HASH(s, s->ins_h, s->window[str + 1]); */\n s.ins_h = HASH(s, s.ins_h, s.window[str + 1]);\n//#if MIN_MATCH != 3\n// Call update_hash() MIN_MATCH-3 more times\n//#endif\n while (s.insert) {\n /* UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); */\n s.ins_h = HASH(s, s.ins_h, s.window[str + MIN_MATCH - 1]);\n\n s.prev[str & s.w_mask] = s.head[s.ins_h];\n s.head[s.ins_h] = str;\n str++;\n s.insert--;\n if (s.lookahead + s.insert < MIN_MATCH) {\n break;\n }\n }\n }\n /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage,\n * but this is not important since only literal bytes will be emitted.\n */\n\n } while (s.lookahead < MIN_LOOKAHEAD && s.strm.avail_in !== 0);\n\n /* If the WIN_INIT bytes after the end of the current data have never been\n * written, then zero those bytes in order to avoid memory check reports of\n * the use of uninitialized (or uninitialised as Julian writes) bytes by\n * the longest match routines. Update the high water mark for the next\n * time through here. WIN_INIT is set to MAX_MATCH since the longest match\n * routines allow scanning to strstart + MAX_MATCH, ignoring lookahead.\n */\n// if (s.high_water < s.window_size) {\n// const curr = s.strstart + s.lookahead;\n// let init = 0;\n//\n// if (s.high_water < curr) {\n// /* Previous high water mark below current data -- zero WIN_INIT\n// * bytes or up to end of window, whichever is less.\n// */\n// init = s.window_size - curr;\n// if (init > WIN_INIT)\n// init = WIN_INIT;\n// zmemzero(s->window + curr, (unsigned)init);\n// s->high_water = curr + init;\n// }\n// else if (s->high_water < (ulg)curr + WIN_INIT) {\n// /* High water mark at or above current data, but below current data\n// * plus WIN_INIT -- zero out to current data plus WIN_INIT, or up\n// * to end of window, whichever is less.\n// */\n// init = (ulg)curr + WIN_INIT - s->high_water;\n// if (init > s->window_size - s->high_water)\n// init = s->window_size - s->high_water;\n// zmemzero(s->window + s->high_water, (unsigned)init);\n// s->high_water += init;\n// }\n// }\n//\n// Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD,\n// \"not enough room for search\");\n};\n\n/* ===========================================================================\n * Copy without compression as much as possible from the input stream, return\n * the current block state.\n *\n * In case deflateParams() is used to later switch to a non-zero compression\n * level, s->matches (otherwise unused when storing) keeps track of the number\n * of hash table slides to perform. If s->matches is 1, then one hash table\n * slide will be done when switching. If s->matches is 2, the maximum value\n * allowed here, then the hash table will be cleared, since two or more slides\n * is the same as a clear.\n *\n * deflate_stored() is written to minimize the number of times an input byte is\n * copied. It is most efficient with large input and output buffers, which\n * maximizes the opportunites to have a single copy from next_in to next_out.\n */\nconst deflate_stored = (s, flush) => {\n\n /* Smallest worthy block size when not flushing or finishing. By default\n * this is 32K. This can be as small as 507 bytes for memLevel == 1. For\n * large input and output buffers, the stored block size will be larger.\n */\n let min_block = s.pending_buf_size - 5 > s.w_size ? s.w_size : s.pending_buf_size - 5;\n\n /* Copy as many min_block or larger stored blocks directly to next_out as\n * possible. If flushing, copy the remaining available input to next_out as\n * stored blocks, if there is enough space.\n */\n let len, left, have, last = 0;\n let used = s.strm.avail_in;\n do {\n /* Set len to the maximum size block that we can copy directly with the\n * available input data and output space. Set left to how much of that\n * would be copied from what's left in the window.\n */\n len = 65535/* MAX_STORED */; /* maximum deflate stored block length */\n have = (s.bi_valid + 42) >> 3; /* number of header bytes */\n if (s.strm.avail_out < have) { /* need room for header */\n break;\n }\n /* maximum stored block length that will fit in avail_out: */\n have = s.strm.avail_out - have;\n left = s.strstart - s.block_start; /* bytes left in window */\n if (len > left + s.strm.avail_in) {\n len = left + s.strm.avail_in; /* limit len to the input */\n }\n if (len > have) {\n len = have; /* limit len to the output */\n }\n\n /* If the stored block would be less than min_block in length, or if\n * unable to copy all of the available input when flushing, then try\n * copying to the window and the pending buffer instead. Also don't\n * write an empty block when flushing -- deflate() does that.\n */\n if (len < min_block && ((len === 0 && flush !== Z_FINISH$3) ||\n flush === Z_NO_FLUSH$2 ||\n len !== left + s.strm.avail_in)) {\n break;\n }\n\n /* Make a dummy stored block in pending to get the header bytes,\n * including any pending bits. This also updates the debugging counts.\n */\n last = flush === Z_FINISH$3 && len === left + s.strm.avail_in ? 1 : 0;\n _tr_stored_block(s, 0, 0, last);\n\n /* Replace the lengths in the dummy stored block with len. */\n s.pending_buf[s.pending - 4] = len;\n s.pending_buf[s.pending - 3] = len >> 8;\n s.pending_buf[s.pending - 2] = ~len;\n s.pending_buf[s.pending - 1] = ~len >> 8;\n\n /* Write the stored block header bytes. */\n flush_pending(s.strm);\n\n//#ifdef ZLIB_DEBUG\n// /* Update debugging counts for the data about to be copied. */\n// s->compressed_len += len << 3;\n// s->bits_sent += len << 3;\n//#endif\n\n /* Copy uncompressed bytes from the window to next_out. */\n if (left) {\n if (left > len) {\n left = len;\n }\n //zmemcpy(s->strm->next_out, s->window + s->block_start, left);\n s.strm.output.set(s.window.subarray(s.block_start, s.block_start + left), s.strm.next_out);\n s.strm.next_out += left;\n s.strm.avail_out -= left;\n s.strm.total_out += left;\n s.block_start += left;\n len -= left;\n }\n\n /* Copy uncompressed bytes directly from next_in to next_out, updating\n * the check value.\n */\n if (len) {\n read_buf(s.strm, s.strm.output, s.strm.next_out, len);\n s.strm.next_out += len;\n s.strm.avail_out -= len;\n s.strm.total_out += len;\n }\n } while (last === 0);\n\n /* Update the sliding window with the last s->w_size bytes of the copied\n * data, or append all of the copied data to the existing window if less\n * than s->w_size bytes were copied. Also update the number of bytes to\n * insert in the hash tables, in the event that deflateParams() switches to\n * a non-zero compression level.\n */\n used -= s.strm.avail_in; /* number of input bytes directly copied */\n if (used) {\n /* If any input was used, then no unused input remains in the window,\n * therefore s->block_start == s->strstart.\n */\n if (used >= s.w_size) { /* supplant the previous history */\n s.matches = 2; /* clear hash */\n //zmemcpy(s->window, s->strm->next_in - s->w_size, s->w_size);\n s.window.set(s.strm.input.subarray(s.strm.next_in - s.w_size, s.strm.next_in), 0);\n s.strstart = s.w_size;\n s.insert = s.strstart;\n }\n else {\n if (s.window_size - s.strstart <= used) {\n /* Slide the window down. */\n s.strstart -= s.w_size;\n //zmemcpy(s->window, s->window + s->w_size, s->strstart);\n s.window.set(s.window.subarray(s.w_size, s.w_size + s.strstart), 0);\n if (s.matches < 2) {\n s.matches++; /* add a pending slide_hash() */\n }\n if (s.insert > s.strstart) {\n s.insert = s.strstart;\n }\n }\n //zmemcpy(s->window + s->strstart, s->strm->next_in - used, used);\n s.window.set(s.strm.input.subarray(s.strm.next_in - used, s.strm.next_in), s.strstart);\n s.strstart += used;\n s.insert += used > s.w_size - s.insert ? s.w_size - s.insert : used;\n }\n s.block_start = s.strstart;\n }\n if (s.high_water < s.strstart) {\n s.high_water = s.strstart;\n }\n\n /* If the last block was written to next_out, then done. */\n if (last) {\n return BS_FINISH_DONE;\n }\n\n /* If flushing and all input has been consumed, then done. */\n if (flush !== Z_NO_FLUSH$2 && flush !== Z_FINISH$3 &&\n s.strm.avail_in === 0 && s.strstart === s.block_start) {\n return BS_BLOCK_DONE;\n }\n\n /* Fill the window with any remaining input. */\n have = s.window_size - s.strstart;\n if (s.strm.avail_in > have && s.block_start >= s.w_size) {\n /* Slide the window down. */\n s.block_start -= s.w_size;\n s.strstart -= s.w_size;\n //zmemcpy(s->window, s->window + s->w_size, s->strstart);\n s.window.set(s.window.subarray(s.w_size, s.w_size + s.strstart), 0);\n if (s.matches < 2) {\n s.matches++; /* add a pending slide_hash() */\n }\n have += s.w_size; /* more space now */\n if (s.insert > s.strstart) {\n s.insert = s.strstart;\n }\n }\n if (have > s.strm.avail_in) {\n have = s.strm.avail_in;\n }\n if (have) {\n read_buf(s.strm, s.window, s.strstart, have);\n s.strstart += have;\n s.insert += have > s.w_size - s.insert ? s.w_size - s.insert : have;\n }\n if (s.high_water < s.strstart) {\n s.high_water = s.strstart;\n }\n\n /* There was not enough avail_out to write a complete worthy or flushed\n * stored block to next_out. Write a stored block to pending instead, if we\n * have enough input for a worthy block, or if flushing and there is enough\n * room for the remaining input as a stored block in the pending buffer.\n */\n have = (s.bi_valid + 42) >> 3; /* number of header bytes */\n /* maximum stored block length that will fit in pending: */\n have = s.pending_buf_size - have > 65535/* MAX_STORED */ ? 65535/* MAX_STORED */ : s.pending_buf_size - have;\n min_block = have > s.w_size ? s.w_size : have;\n left = s.strstart - s.block_start;\n if (left >= min_block ||\n ((left || flush === Z_FINISH$3) && flush !== Z_NO_FLUSH$2 &&\n s.strm.avail_in === 0 && left <= have)) {\n len = left > have ? have : left;\n last = flush === Z_FINISH$3 && s.strm.avail_in === 0 &&\n len === left ? 1 : 0;\n _tr_stored_block(s, s.block_start, len, last);\n s.block_start += len;\n flush_pending(s.strm);\n }\n\n /* We've done all we can with the available input and output. */\n return last ? BS_FINISH_STARTED : BS_NEED_MORE;\n};\n\n\n/* ===========================================================================\n * Compress as much as possible from the input stream, return the current\n * block state.\n * This function does not perform lazy evaluation of matches and inserts\n * new strings in the dictionary only for unmatched strings or for short\n * matches. It is used only for the fast compression options.\n */\nconst deflate_fast = (s, flush) => {\n\n let hash_head; /* head of the hash chain */\n let bflush; /* set if current block must be flushed */\n\n for (;;) {\n /* Make sure that we always have enough lookahead, except\n * at the end of the input file. We need MAX_MATCH bytes\n * for the next match, plus MIN_MATCH bytes to insert the\n * string following the next match.\n */\n if (s.lookahead < MIN_LOOKAHEAD) {\n fill_window(s);\n if (s.lookahead < MIN_LOOKAHEAD && flush === Z_NO_FLUSH$2) {\n return BS_NEED_MORE;\n }\n if (s.lookahead === 0) {\n break; /* flush the current block */\n }\n }\n\n /* Insert the string window[strstart .. strstart+2] in the\n * dictionary, and set hash_head to the head of the hash chain:\n */\n hash_head = 0/*NIL*/;\n if (s.lookahead >= MIN_MATCH) {\n /*** INSERT_STRING(s, s.strstart, hash_head); ***/\n s.ins_h = HASH(s, s.ins_h, s.window[s.strstart + MIN_MATCH - 1]);\n hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h];\n s.head[s.ins_h] = s.strstart;\n /***/\n }\n\n /* Find the longest match, discarding those <= prev_length.\n * At this point we have always match_length < MIN_MATCH\n */\n if (hash_head !== 0/*NIL*/ && ((s.strstart - hash_head) <= (s.w_size - MIN_LOOKAHEAD))) {\n /* To simplify the code, we prevent matches with the string\n * of window index 0 (in particular we have to avoid a match\n * of the string with itself at the start of the input file).\n */\n s.match_length = longest_match(s, hash_head);\n /* longest_match() sets match_start */\n }\n if (s.match_length >= MIN_MATCH) {\n // check_match(s, s.strstart, s.match_start, s.match_length); // for debug only\n\n /*** _tr_tally_dist(s, s.strstart - s.match_start,\n s.match_length - MIN_MATCH, bflush); ***/\n bflush = _tr_tally(s, s.strstart - s.match_start, s.match_length - MIN_MATCH);\n\n s.lookahead -= s.match_length;\n\n /* Insert new strings in the hash table only if the match length\n * is not too large. This saves time but degrades compression.\n */\n if (s.match_length <= s.max_lazy_match/*max_insert_length*/ && s.lookahead >= MIN_MATCH) {\n s.match_length--; /* string at strstart already in table */\n do {\n s.strstart++;\n /*** INSERT_STRING(s, s.strstart, hash_head); ***/\n s.ins_h = HASH(s, s.ins_h, s.window[s.strstart + MIN_MATCH - 1]);\n hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h];\n s.head[s.ins_h] = s.strstart;\n /***/\n /* strstart never exceeds WSIZE-MAX_MATCH, so there are\n * always MIN_MATCH bytes ahead.\n */\n } while (--s.match_length !== 0);\n s.strstart++;\n } else\n {\n s.strstart += s.match_length;\n s.match_length = 0;\n s.ins_h = s.window[s.strstart];\n /* UPDATE_HASH(s, s.ins_h, s.window[s.strstart+1]); */\n s.ins_h = HASH(s, s.ins_h, s.window[s.strstart + 1]);\n\n//#if MIN_MATCH != 3\n// Call UPDATE_HASH() MIN_MATCH-3 more times\n//#endif\n /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not\n * matter since it will be recomputed at next deflate call.\n */\n }\n } else {\n /* No match, output a literal byte */\n //Tracevv((stderr,\"%c\", s.window[s.strstart]));\n /*** _tr_tally_lit(s, s.window[s.strstart], bflush); ***/\n bflush = _tr_tally(s, 0, s.window[s.strstart]);\n\n s.lookahead--;\n s.strstart++;\n }\n if (bflush) {\n /*** FLUSH_BLOCK(s, 0); ***/\n flush_block_only(s, false);\n if (s.strm.avail_out === 0) {\n return BS_NEED_MORE;\n }\n /***/\n }\n }\n s.insert = ((s.strstart < (MIN_MATCH - 1)) ? s.strstart : MIN_MATCH - 1);\n if (flush === Z_FINISH$3) {\n /*** FLUSH_BLOCK(s, 1); ***/\n flush_block_only(s, true);\n if (s.strm.avail_out === 0) {\n return BS_FINISH_STARTED;\n }\n /***/\n return BS_FINISH_DONE;\n }\n if (s.sym_next) {\n /*** FLUSH_BLOCK(s, 0); ***/\n flush_block_only(s, false);\n if (s.strm.avail_out === 0) {\n return BS_NEED_MORE;\n }\n /***/\n }\n return BS_BLOCK_DONE;\n};\n\n/* ===========================================================================\n * Same as above, but achieves better compression. We use a lazy\n * evaluation for matches: a match is finally adopted only if there is\n * no better match at the next window position.\n */\nconst deflate_slow = (s, flush) => {\n\n let hash_head; /* head of hash chain */\n let bflush; /* set if current block must be flushed */\n\n let max_insert;\n\n /* Process the input block. */\n for (;;) {\n /* Make sure that we always have enough lookahead, except\n * at the end of the input file. We need MAX_MATCH bytes\n * for the next match, plus MIN_MATCH bytes to insert the\n * string following the next match.\n */\n if (s.lookahead < MIN_LOOKAHEAD) {\n fill_window(s);\n if (s.lookahead < MIN_LOOKAHEAD && flush === Z_NO_FLUSH$2) {\n return BS_NEED_MORE;\n }\n if (s.lookahead === 0) { break; } /* flush the current block */\n }\n\n /* Insert the string window[strstart .. strstart+2] in the\n * dictionary, and set hash_head to the head of the hash chain:\n */\n hash_head = 0/*NIL*/;\n if (s.lookahead >= MIN_MATCH) {\n /*** INSERT_STRING(s, s.strstart, hash_head); ***/\n s.ins_h = HASH(s, s.ins_h, s.window[s.strstart + MIN_MATCH - 1]);\n hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h];\n s.head[s.ins_h] = s.strstart;\n /***/\n }\n\n /* Find the longest match, discarding those <= prev_length.\n */\n s.prev_length = s.match_length;\n s.prev_match = s.match_start;\n s.match_length = MIN_MATCH - 1;\n\n if (hash_head !== 0/*NIL*/ && s.prev_length < s.max_lazy_match &&\n s.strstart - hash_head <= (s.w_size - MIN_LOOKAHEAD)/*MAX_DIST(s)*/) {\n /* To simplify the code, we prevent matches with the string\n * of window index 0 (in particular we have to avoid a match\n * of the string with itself at the start of the input file).\n */\n s.match_length = longest_match(s, hash_head);\n /* longest_match() sets match_start */\n\n if (s.match_length <= 5 &&\n (s.strategy === Z_FILTERED || (s.match_length === MIN_MATCH && s.strstart - s.match_start > 4096/*TOO_FAR*/))) {\n\n /* If prev_match is also MIN_MATCH, match_start is garbage\n * but we will ignore the current match anyway.\n */\n s.match_length = MIN_MATCH - 1;\n }\n }\n /* If there was a match at the previous step and the current\n * match is not better, output the previous match:\n */\n if (s.prev_length >= MIN_MATCH && s.match_length <= s.prev_length) {\n max_insert = s.strstart + s.lookahead - MIN_MATCH;\n /* Do not insert strings in hash table beyond this. */\n\n //check_match(s, s.strstart-1, s.prev_match, s.prev_length);\n\n /***_tr_tally_dist(s, s.strstart - 1 - s.prev_match,\n s.prev_length - MIN_MATCH, bflush);***/\n bflush = _tr_tally(s, s.strstart - 1 - s.prev_match, s.prev_length - MIN_MATCH);\n /* Insert in hash table all strings up to the end of the match.\n * strstart-1 and strstart are already inserted. If there is not\n * enough lookahead, the last two strings are not inserted in\n * the hash table.\n */\n s.lookahead -= s.prev_length - 1;\n s.prev_length -= 2;\n do {\n if (++s.strstart <= max_insert) {\n /*** INSERT_STRING(s, s.strstart, hash_head); ***/\n s.ins_h = HASH(s, s.ins_h, s.window[s.strstart + MIN_MATCH - 1]);\n hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h];\n s.head[s.ins_h] = s.strstart;\n /***/\n }\n } while (--s.prev_length !== 0);\n s.match_available = 0;\n s.match_length = MIN_MATCH - 1;\n s.strstart++;\n\n if (bflush) {\n /*** FLUSH_BLOCK(s, 0); ***/\n flush_block_only(s, false);\n if (s.strm.avail_out === 0) {\n return BS_NEED_MORE;\n }\n /***/\n }\n\n } else if (s.match_available) {\n /* If there was no match at the previous position, output a\n * single literal. If there was a match but the current match\n * is longer, truncate the previous match to a single literal.\n */\n //Tracevv((stderr,\"%c\", s->window[s->strstart-1]));\n /*** _tr_tally_lit(s, s.window[s.strstart-1], bflush); ***/\n bflush = _tr_tally(s, 0, s.window[s.strstart - 1]);\n\n if (bflush) {\n /*** FLUSH_BLOCK_ONLY(s, 0) ***/\n flush_block_only(s, false);\n /***/\n }\n s.strstart++;\n s.lookahead--;\n if (s.strm.avail_out === 0) {\n return BS_NEED_MORE;\n }\n } else {\n /* There is no previous match to compare with, wait for\n * the next step to decide.\n */\n s.match_available = 1;\n s.strstart++;\n s.lookahead--;\n }\n }\n //Assert (flush != Z_NO_FLUSH, \"no flush?\");\n if (s.match_available) {\n //Tracevv((stderr,\"%c\", s->window[s->strstart-1]));\n /*** _tr_tally_lit(s, s.window[s.strstart-1], bflush); ***/\n bflush = _tr_tally(s, 0, s.window[s.strstart - 1]);\n\n s.match_available = 0;\n }\n s.insert = s.strstart < MIN_MATCH - 1 ? s.strstart : MIN_MATCH - 1;\n if (flush === Z_FINISH$3) {\n /*** FLUSH_BLOCK(s, 1); ***/\n flush_block_only(s, true);\n if (s.strm.avail_out === 0) {\n return BS_FINISH_STARTED;\n }\n /***/\n return BS_FINISH_DONE;\n }\n if (s.sym_next) {\n /*** FLUSH_BLOCK(s, 0); ***/\n flush_block_only(s, false);\n if (s.strm.avail_out === 0) {\n return BS_NEED_MORE;\n }\n /***/\n }\n\n return BS_BLOCK_DONE;\n};\n\n\n/* ===========================================================================\n * For Z_RLE, simply look for runs of bytes, generate matches only of distance\n * one. Do not maintain a hash table. (It will be regenerated if this run of\n * deflate switches away from Z_RLE.)\n */\nconst deflate_rle = (s, flush) => {\n\n let bflush; /* set if current block must be flushed */\n let prev; /* byte at distance one to match */\n let scan, strend; /* scan goes up to strend for length of run */\n\n const _win = s.window;\n\n for (;;) {\n /* Make sure that we always have enough lookahead, except\n * at the end of the input file. We need MAX_MATCH bytes\n * for the longest run, plus one for the unrolled loop.\n */\n if (s.lookahead <= MAX_MATCH) {\n fill_window(s);\n if (s.lookahead <= MAX_MATCH && flush === Z_NO_FLUSH$2) {\n return BS_NEED_MORE;\n }\n if (s.lookahead === 0) { break; } /* flush the current block */\n }\n\n /* See how many times the previous byte repeats */\n s.match_length = 0;\n if (s.lookahead >= MIN_MATCH && s.strstart > 0) {\n scan = s.strstart - 1;\n prev = _win[scan];\n if (prev === _win[++scan] && prev === _win[++scan] && prev === _win[++scan]) {\n strend = s.strstart + MAX_MATCH;\n do {\n /*jshint noempty:false*/\n } while (prev === _win[++scan] && prev === _win[++scan] &&\n prev === _win[++scan] && prev === _win[++scan] &&\n prev === _win[++scan] && prev === _win[++scan] &&\n prev === _win[++scan] && prev === _win[++scan] &&\n scan < strend);\n s.match_length = MAX_MATCH - (strend - scan);\n if (s.match_length > s.lookahead) {\n s.match_length = s.lookahead;\n }\n }\n //Assert(scan <= s->window+(uInt)(s->window_size-1), \"wild scan\");\n }\n\n /* Emit match if have run of MIN_MATCH or longer, else emit literal */\n if (s.match_length >= MIN_MATCH) {\n //check_match(s, s.strstart, s.strstart - 1, s.match_length);\n\n /*** _tr_tally_dist(s, 1, s.match_length - MIN_MATCH, bflush); ***/\n bflush = _tr_tally(s, 1, s.match_length - MIN_MATCH);\n\n s.lookahead -= s.match_length;\n s.strstart += s.match_length;\n s.match_length = 0;\n } else {\n /* No match, output a literal byte */\n //Tracevv((stderr,\"%c\", s->window[s->strstart]));\n /*** _tr_tally_lit(s, s.window[s.strstart], bflush); ***/\n bflush = _tr_tally(s, 0, s.window[s.strstart]);\n\n s.lookahead--;\n s.strstart++;\n }\n if (bflush) {\n /*** FLUSH_BLOCK(s, 0); ***/\n flush_block_only(s, false);\n if (s.strm.avail_out === 0) {\n return BS_NEED_MORE;\n }\n /***/\n }\n }\n s.insert = 0;\n if (flush === Z_FINISH$3) {\n /*** FLUSH_BLOCK(s, 1); ***/\n flush_block_only(s, true);\n if (s.strm.avail_out === 0) {\n return BS_FINISH_STARTED;\n }\n /***/\n return BS_FINISH_DONE;\n }\n if (s.sym_next) {\n /*** FLUSH_BLOCK(s, 0); ***/\n flush_block_only(s, false);\n if (s.strm.avail_out === 0) {\n return BS_NEED_MORE;\n }\n /***/\n }\n return BS_BLOCK_DONE;\n};\n\n/* ===========================================================================\n * For Z_HUFFMAN_ONLY, do not look for matches. Do not maintain a hash table.\n * (It will be regenerated if this run of deflate switches away from Huffman.)\n */\nconst deflate_huff = (s, flush) => {\n\n let bflush; /* set if current block must be flushed */\n\n for (;;) {\n /* Make sure that we have a literal to write. */\n if (s.lookahead === 0) {\n fill_window(s);\n if (s.lookahead === 0) {\n if (flush === Z_NO_FLUSH$2) {\n return BS_NEED_MORE;\n }\n break; /* flush the current block */\n }\n }\n\n /* Output a literal byte */\n s.match_length = 0;\n //Tracevv((stderr,\"%c\", s->window[s->strstart]));\n /*** _tr_tally_lit(s, s.window[s.strstart], bflush); ***/\n bflush = _tr_tally(s, 0, s.window[s.strstart]);\n s.lookahead--;\n s.strstart++;\n if (bflush) {\n /*** FLUSH_BLOCK(s, 0); ***/\n flush_block_only(s, false);\n if (s.strm.avail_out === 0) {\n return BS_NEED_MORE;\n }\n /***/\n }\n }\n s.insert = 0;\n if (flush === Z_FINISH$3) {\n /*** FLUSH_BLOCK(s, 1); ***/\n flush_block_only(s, true);\n if (s.strm.avail_out === 0) {\n return BS_FINISH_STARTED;\n }\n /***/\n return BS_FINISH_DONE;\n }\n if (s.sym_next) {\n /*** FLUSH_BLOCK(s, 0); ***/\n flush_block_only(s, false);\n if (s.strm.avail_out === 0) {\n return BS_NEED_MORE;\n }\n /***/\n }\n return BS_BLOCK_DONE;\n};\n\n/* Values for max_lazy_match, good_match and max_chain_length, depending on\n * the desired pack level (0..9). The values given below have been tuned to\n * exclude worst case performance for pathological files. Better values may be\n * found for specific files.\n */\nfunction Config(good_length, max_lazy, nice_length, max_chain, func) {\n\n this.good_length = good_length;\n this.max_lazy = max_lazy;\n this.nice_length = nice_length;\n this.max_chain = max_chain;\n this.func = func;\n}\n\nconst configuration_table = [\n /* good lazy nice chain */\n new Config(0, 0, 0, 0, deflate_stored), /* 0 store only */\n new Config(4, 4, 8, 4, deflate_fast), /* 1 max speed, no lazy matches */\n new Config(4, 5, 16, 8, deflate_fast), /* 2 */\n new Config(4, 6, 32, 32, deflate_fast), /* 3 */\n\n new Config(4, 4, 16, 16, deflate_slow), /* 4 lazy matches */\n new Config(8, 16, 32, 32, deflate_slow), /* 5 */\n new Config(8, 16, 128, 128, deflate_slow), /* 6 */\n new Config(8, 32, 128, 256, deflate_slow), /* 7 */\n new Config(32, 128, 258, 1024, deflate_slow), /* 8 */\n new Config(32, 258, 258, 4096, deflate_slow) /* 9 max compression */\n];\n\n\n/* ===========================================================================\n * Initialize the \"longest match\" routines for a new zlib stream\n */\nconst lm_init = (s) => {\n\n s.window_size = 2 * s.w_size;\n\n /*** CLEAR_HASH(s); ***/\n zero(s.head); // Fill with NIL (= 0);\n\n /* Set the default configuration parameters:\n */\n s.max_lazy_match = configuration_table[s.level].max_lazy;\n s.good_match = configuration_table[s.level].good_length;\n s.nice_match = configuration_table[s.level].nice_length;\n s.max_chain_length = configuration_table[s.level].max_chain;\n\n s.strstart = 0;\n s.block_start = 0;\n s.lookahead = 0;\n s.insert = 0;\n s.match_length = s.prev_length = MIN_MATCH - 1;\n s.match_available = 0;\n s.ins_h = 0;\n};\n\n\nfunction DeflateState() {\n this.strm = null; /* pointer back to this zlib stream */\n this.status = 0; /* as the name implies */\n this.pending_buf = null; /* output still pending */\n this.pending_buf_size = 0; /* size of pending_buf */\n this.pending_out = 0; /* next pending byte to output to the stream */\n this.pending = 0; /* nb of bytes in the pending buffer */\n this.wrap = 0; /* bit 0 true for zlib, bit 1 true for gzip */\n this.gzhead = null; /* gzip header information to write */\n this.gzindex = 0; /* where in extra, name, or comment */\n this.method = Z_DEFLATED$2; /* can only be DEFLATED */\n this.last_flush = -1; /* value of flush param for previous deflate call */\n\n this.w_size = 0; /* LZ77 window size (32K by default) */\n this.w_bits = 0; /* log2(w_size) (8..16) */\n this.w_mask = 0; /* w_size - 1 */\n\n this.window = null;\n /* Sliding window. Input bytes are read into the second half of the window,\n * and move to the first half later to keep a dictionary of at least wSize\n * bytes. With this organization, matches are limited to a distance of\n * wSize-MAX_MATCH bytes, but this ensures that IO is always\n * performed with a length multiple of the block size.\n */\n\n this.window_size = 0;\n /* Actual size of window: 2*wSize, except when the user input buffer\n * is directly used as sliding window.\n */\n\n this.prev = null;\n /* Link to older string with same hash index. To limit the size of this\n * array to 64K, this link is maintained only for the last 32K strings.\n * An index in this array is thus a window index modulo 32K.\n */\n\n this.head = null; /* Heads of the hash chains or NIL. */\n\n this.ins_h = 0; /* hash index of string to be inserted */\n this.hash_size = 0; /* number of elements in hash table */\n this.hash_bits = 0; /* log2(hash_size) */\n this.hash_mask = 0; /* hash_size-1 */\n\n this.hash_shift = 0;\n /* Number of bits by which ins_h must be shifted at each input\n * step. It must be such that after MIN_MATCH steps, the oldest\n * byte no longer takes part in the hash key, that is:\n * hash_shift * MIN_MATCH >= hash_bits\n */\n\n this.block_start = 0;\n /* Window position at the beginning of the current output block. Gets\n * negative when the window is moved backwards.\n */\n\n this.match_length = 0; /* length of best match */\n this.prev_match = 0; /* previous match */\n this.match_available = 0; /* set if previous match exists */\n this.strstart = 0; /* start of string to insert */\n this.match_start = 0; /* start of matching string */\n this.lookahead = 0; /* number of valid bytes ahead in window */\n\n this.prev_length = 0;\n /* Length of the best match at previous step. Matches not greater than this\n * are discarded. This is used in the lazy match evaluation.\n */\n\n this.max_chain_length = 0;\n /* To speed up deflation, hash chains are never searched beyond this\n * length. A higher limit improves compression ratio but degrades the\n * speed.\n */\n\n this.max_lazy_match = 0;\n /* Attempt to find a better match only when the current match is strictly\n * smaller than this value. This mechanism is used only for compression\n * levels >= 4.\n */\n // That's alias to max_lazy_match, don't use directly\n //this.max_insert_length = 0;\n /* Insert new strings in the hash table only if the match length is not\n * greater than this length. This saves time but degrades compression.\n * max_insert_length is used only for compression levels <= 3.\n */\n\n this.level = 0; /* compression level (1..9) */\n this.strategy = 0; /* favor or force Huffman coding*/\n\n this.good_match = 0;\n /* Use a faster search when the previous match is longer than this */\n\n this.nice_match = 0; /* Stop searching when current match exceeds this */\n\n /* used by trees.c: */\n\n /* Didn't use ct_data typedef below to suppress compiler warning */\n\n // struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */\n // struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */\n // struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */\n\n // Use flat array of DOUBLE size, with interleaved fata,\n // because JS does not support effective\n this.dyn_ltree = new Uint16Array(HEAP_SIZE * 2);\n this.dyn_dtree = new Uint16Array((2 * D_CODES + 1) * 2);\n this.bl_tree = new Uint16Array((2 * BL_CODES + 1) * 2);\n zero(this.dyn_ltree);\n zero(this.dyn_dtree);\n zero(this.bl_tree);\n\n this.l_desc = null; /* desc. for literal tree */\n this.d_desc = null; /* desc. for distance tree */\n this.bl_desc = null; /* desc. for bit length tree */\n\n //ush bl_count[MAX_BITS+1];\n this.bl_count = new Uint16Array(MAX_BITS + 1);\n /* number of codes at each bit length for an optimal tree */\n\n //int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */\n this.heap = new Uint16Array(2 * L_CODES + 1); /* heap used to build the Huffman trees */\n zero(this.heap);\n\n this.heap_len = 0; /* number of elements in the heap */\n this.heap_max = 0; /* element of largest frequency */\n /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used.\n * The same heap array is used to build all trees.\n */\n\n this.depth = new Uint16Array(2 * L_CODES + 1); //uch depth[2*L_CODES+1];\n zero(this.depth);\n /* Depth of each subtree used as tie breaker for trees of equal frequency\n */\n\n this.sym_buf = 0; /* buffer for distances and literals/lengths */\n\n this.lit_bufsize = 0;\n /* Size of match buffer for literals/lengths. There are 4 reasons for\n * limiting lit_bufsize to 64K:\n * - frequencies can be kept in 16 bit counters\n * - if compression is not successful for the first block, all input\n * data is still in the window so we can still emit a stored block even\n * when input comes from standard input. (This can also be done for\n * all blocks if lit_bufsize is not greater than 32K.)\n * - if compression is not successful for a file smaller than 64K, we can\n * even emit a stored file instead of a stored block (saving 5 bytes).\n * This is applicable only for zip (not gzip or zlib).\n * - creating new Huffman trees less frequently may not provide fast\n * adaptation to changes in the input data statistics. (Take for\n * example a binary file with poorly compressible code followed by\n * a highly compressible string table.) Smaller buffer sizes give\n * fast adaptation but have of course the overhead of transmitting\n * trees more frequently.\n * - I can't count above 4\n */\n\n this.sym_next = 0; /* running index in sym_buf */\n this.sym_end = 0; /* symbol table full when sym_next reaches this */\n\n this.opt_len = 0; /* bit length of current block with optimal trees */\n this.static_len = 0; /* bit length of current block with static trees */\n this.matches = 0; /* number of string matches in current block */\n this.insert = 0; /* bytes at end of window left to insert */\n\n\n this.bi_buf = 0;\n /* Output buffer. bits are inserted starting at the bottom (least\n * significant bits).\n */\n this.bi_valid = 0;\n /* Number of valid bits in bi_buf. All bits above the last valid bit\n * are always zero.\n */\n\n // Used for window memory init. We safely ignore it for JS. That makes\n // sense only for pointers and memory check tools.\n //this.high_water = 0;\n /* High water mark offset in window for initialized bytes -- bytes above\n * this are set to zero in order to avoid memory check warnings when\n * longest match routines access bytes past the input. This is then\n * updated to the new high water mark.\n */\n}\n\n\n/* =========================================================================\n * Check for a valid deflate stream state. Return 0 if ok, 1 if not.\n */\nconst deflateStateCheck = (strm) => {\n\n if (!strm) {\n return 1;\n }\n const s = strm.state;\n if (!s || s.strm !== strm || (s.status !== INIT_STATE &&\n//#ifdef GZIP\n s.status !== GZIP_STATE &&\n//#endif\n s.status !== EXTRA_STATE &&\n s.status !== NAME_STATE &&\n s.status !== COMMENT_STATE &&\n s.status !== HCRC_STATE &&\n s.status !== BUSY_STATE &&\n s.status !== FINISH_STATE)) {\n return 1;\n }\n return 0;\n};\n\n\nconst deflateResetKeep = (strm) => {\n\n if (deflateStateCheck(strm)) {\n return err(strm, Z_STREAM_ERROR$2);\n }\n\n strm.total_in = strm.total_out = 0;\n strm.data_type = Z_UNKNOWN;\n\n const s = strm.state;\n s.pending = 0;\n s.pending_out = 0;\n\n if (s.wrap < 0) {\n s.wrap = -s.wrap;\n /* was made negative by deflate(..., Z_FINISH); */\n }\n s.status =\n//#ifdef GZIP\n s.wrap === 2 ? GZIP_STATE :\n//#endif\n s.wrap ? INIT_STATE : BUSY_STATE;\n strm.adler = (s.wrap === 2) ?\n 0 // crc32(0, Z_NULL, 0)\n :\n 1; // adler32(0, Z_NULL, 0)\n s.last_flush = -2;\n _tr_init(s);\n return Z_OK$3;\n};\n\n\nconst deflateReset = (strm) => {\n\n const ret = deflateResetKeep(strm);\n if (ret === Z_OK$3) {\n lm_init(strm.state);\n }\n return ret;\n};\n\n\nconst deflateSetHeader = (strm, head) => {\n\n if (deflateStateCheck(strm) || strm.state.wrap !== 2) {\n return Z_STREAM_ERROR$2;\n }\n strm.state.gzhead = head;\n return Z_OK$3;\n};\n\n\nconst deflateInit2 = (strm, level, method, windowBits, memLevel, strategy) => {\n\n if (!strm) { // === Z_NULL\n return Z_STREAM_ERROR$2;\n }\n let wrap = 1;\n\n if (level === Z_DEFAULT_COMPRESSION$1) {\n level = 6;\n }\n\n if (windowBits < 0) { /* suppress zlib wrapper */\n wrap = 0;\n windowBits = -windowBits;\n }\n\n else if (windowBits > 15) {\n wrap = 2; /* write gzip wrapper instead */\n windowBits -= 16;\n }\n\n\n if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method !== Z_DEFLATED$2 ||\n windowBits < 8 || windowBits > 15 || level < 0 || level > 9 ||\n strategy < 0 || strategy > Z_FIXED || (windowBits === 8 && wrap !== 1)) {\n return err(strm, Z_STREAM_ERROR$2);\n }\n\n\n if (windowBits === 8) {\n windowBits = 9;\n }\n /* until 256-byte window bug fixed */\n\n const s = new DeflateState();\n\n strm.state = s;\n s.strm = strm;\n s.status = INIT_STATE; /* to pass state test in deflateReset() */\n\n s.wrap = wrap;\n s.gzhead = null;\n s.w_bits = windowBits;\n s.w_size = 1 << s.w_bits;\n s.w_mask = s.w_size - 1;\n\n s.hash_bits = memLevel + 7;\n s.hash_size = 1 << s.hash_bits;\n s.hash_mask = s.hash_size - 1;\n s.hash_shift = ~~((s.hash_bits + MIN_MATCH - 1) / MIN_MATCH);\n\n s.window = new Uint8Array(s.w_size * 2);\n s.head = new Uint16Array(s.hash_size);\n s.prev = new Uint16Array(s.w_size);\n\n // Don't need mem init magic for JS.\n //s.high_water = 0; /* nothing written to s->window yet */\n\n s.lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */\n\n /* We overlay pending_buf and sym_buf. This works since the average size\n * for length/distance pairs over any compressed block is assured to be 31\n * bits or less.\n *\n * Analysis: The longest fixed codes are a length code of 8 bits plus 5\n * extra bits, for lengths 131 to 257. The longest fixed distance codes are\n * 5 bits plus 13 extra bits, for distances 16385 to 32768. The longest\n * possible fixed-codes length/distance pair is then 31 bits total.\n *\n * sym_buf starts one-fourth of the way into pending_buf. So there are\n * three bytes in sym_buf for every four bytes in pending_buf. Each symbol\n * in sym_buf is three bytes -- two for the distance and one for the\n * literal/length. As each symbol is consumed, the pointer to the next\n * sym_buf value to read moves forward three bytes. From that symbol, up to\n * 31 bits are written to pending_buf. The closest the written pending_buf\n * bits gets to the next sym_buf symbol to read is just before the last\n * code is written. At that time, 31*(n-2) bits have been written, just\n * after 24*(n-2) bits have been consumed from sym_buf. sym_buf starts at\n * 8*n bits into pending_buf. (Note that the symbol buffer fills when n-1\n * symbols are written.) The closest the writing gets to what is unread is\n * then n+14 bits. Here n is lit_bufsize, which is 16384 by default, and\n * can range from 128 to 32768.\n *\n * Therefore, at a minimum, there are 142 bits of space between what is\n * written and what is read in the overlain buffers, so the symbols cannot\n * be overwritten by the compressed data. That space is actually 139 bits,\n * due to the three-bit fixed-code block header.\n *\n * That covers the case where either Z_FIXED is specified, forcing fixed\n * codes, or when the use of fixed codes is chosen, because that choice\n * results in a smaller compressed block than dynamic codes. That latter\n * condition then assures that the above analysis also covers all dynamic\n * blocks. A dynamic-code block will only be chosen to be emitted if it has\n * fewer bits than a fixed-code block would for the same set of symbols.\n * Therefore its average symbol length is assured to be less than 31. So\n * the compressed data for a dynamic block also cannot overwrite the\n * symbols from which it is being constructed.\n */\n\n s.pending_buf_size = s.lit_bufsize * 4;\n s.pending_buf = new Uint8Array(s.pending_buf_size);\n\n // It is offset from `s.pending_buf` (size is `s.lit_bufsize * 2`)\n //s->sym_buf = s->pending_buf + s->lit_bufsize;\n s.sym_buf = s.lit_bufsize;\n\n //s->sym_end = (s->lit_bufsize - 1) * 3;\n s.sym_end = (s.lit_bufsize - 1) * 3;\n /* We avoid equality with lit_bufsize*3 because of wraparound at 64K\n * on 16 bit machines and because stored blocks are restricted to\n * 64K-1 bytes.\n */\n\n s.level = level;\n s.strategy = strategy;\n s.method = method;\n\n return deflateReset(strm);\n};\n\nconst deflateInit = (strm, level) => {\n\n return deflateInit2(strm, level, Z_DEFLATED$2, MAX_WBITS$1, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY$1);\n};\n\n\n/* ========================================================================= */\nconst deflate$2 = (strm, flush) => {\n\n if (deflateStateCheck(strm) || flush > Z_BLOCK$1 || flush < 0) {\n return strm ? err(strm, Z_STREAM_ERROR$2) : Z_STREAM_ERROR$2;\n }\n\n const s = strm.state;\n\n if (!strm.output ||\n (strm.avail_in !== 0 && !strm.input) ||\n (s.status === FINISH_STATE && flush !== Z_FINISH$3)) {\n return err(strm, (strm.avail_out === 0) ? Z_BUF_ERROR$1 : Z_STREAM_ERROR$2);\n }\n\n const old_flush = s.last_flush;\n s.last_flush = flush;\n\n /* Flush as much pending output as possible */\n if (s.pending !== 0) {\n flush_pending(strm);\n if (strm.avail_out === 0) {\n /* Since avail_out is 0, deflate will be called again with\n * more output space, but possibly with both pending and\n * avail_in equal to zero. There won't be anything to do,\n * but this is not an error situation so make sure we\n * return OK instead of BUF_ERROR at next call of deflate:\n */\n s.last_flush = -1;\n return Z_OK$3;\n }\n\n /* Make sure there is something to do and avoid duplicate consecutive\n * flushes. For repeated and useless calls with Z_FINISH, we keep\n * returning Z_STREAM_END instead of Z_BUF_ERROR.\n */\n } else if (strm.avail_in === 0 && rank(flush) <= rank(old_flush) &&\n flush !== Z_FINISH$3) {\n return err(strm, Z_BUF_ERROR$1);\n }\n\n /* User must not provide more input after the first FINISH: */\n if (s.status === FINISH_STATE && strm.avail_in !== 0) {\n return err(strm, Z_BUF_ERROR$1);\n }\n\n /* Write the header */\n if (s.status === INIT_STATE && s.wrap === 0) {\n s.status = BUSY_STATE;\n }\n if (s.status === INIT_STATE) {\n /* zlib header */\n let header = (Z_DEFLATED$2 + ((s.w_bits - 8) << 4)) << 8;\n let level_flags = -1;\n\n if (s.strategy >= Z_HUFFMAN_ONLY || s.level < 2) {\n level_flags = 0;\n } else if (s.level < 6) {\n level_flags = 1;\n } else if (s.level === 6) {\n level_flags = 2;\n } else {\n level_flags = 3;\n }\n header |= (level_flags << 6);\n if (s.strstart !== 0) { header |= PRESET_DICT; }\n header += 31 - (header % 31);\n\n putShortMSB(s, header);\n\n /* Save the adler32 of the preset dictionary: */\n if (s.strstart !== 0) {\n putShortMSB(s, strm.adler >>> 16);\n putShortMSB(s, strm.adler & 0xffff);\n }\n strm.adler = 1; // adler32(0L, Z_NULL, 0);\n s.status = BUSY_STATE;\n\n /* Compression must start with an empty pending buffer */\n flush_pending(strm);\n if (s.pending !== 0) {\n s.last_flush = -1;\n return Z_OK$3;\n }\n }\n//#ifdef GZIP\n if (s.status === GZIP_STATE) {\n /* gzip header */\n strm.adler = 0; //crc32(0L, Z_NULL, 0);\n put_byte(s, 31);\n put_byte(s, 139);\n put_byte(s, 8);\n if (!s.gzhead) { // s->gzhead == Z_NULL\n put_byte(s, 0);\n put_byte(s, 0);\n put_byte(s, 0);\n put_byte(s, 0);\n put_byte(s, 0);\n put_byte(s, s.level === 9 ? 2 :\n (s.strategy >= Z_HUFFMAN_ONLY || s.level < 2 ?\n 4 : 0));\n put_byte(s, OS_CODE);\n s.status = BUSY_STATE;\n\n /* Compression must start with an empty pending buffer */\n flush_pending(strm);\n if (s.pending !== 0) {\n s.last_flush = -1;\n return Z_OK$3;\n }\n }\n else {\n put_byte(s, (s.gzhead.text ? 1 : 0) +\n (s.gzhead.hcrc ? 2 : 0) +\n (!s.gzhead.extra ? 0 : 4) +\n (!s.gzhead.name ? 0 : 8) +\n (!s.gzhead.comment ? 0 : 16)\n );\n put_byte(s, s.gzhead.time & 0xff);\n put_byte(s, (s.gzhead.time >> 8) & 0xff);\n put_byte(s, (s.gzhead.time >> 16) & 0xff);\n put_byte(s, (s.gzhead.time >> 24) & 0xff);\n put_byte(s, s.level === 9 ? 2 :\n (s.strategy >= Z_HUFFMAN_ONLY || s.level < 2 ?\n 4 : 0));\n put_byte(s, s.gzhead.os & 0xff);\n if (s.gzhead.extra && s.gzhead.extra.length) {\n put_byte(s, s.gzhead.extra.length & 0xff);\n put_byte(s, (s.gzhead.extra.length >> 8) & 0xff);\n }\n if (s.gzhead.hcrc) {\n strm.adler = crc32_1(strm.adler, s.pending_buf, s.pending, 0);\n }\n s.gzindex = 0;\n s.status = EXTRA_STATE;\n }\n }\n if (s.status === EXTRA_STATE) {\n if (s.gzhead.extra/* != Z_NULL*/) {\n let beg = s.pending; /* start of bytes to update crc */\n let left = (s.gzhead.extra.length & 0xffff) - s.gzindex;\n while (s.pending + left > s.pending_buf_size) {\n let copy = s.pending_buf_size - s.pending;\n // zmemcpy(s.pending_buf + s.pending,\n // s.gzhead.extra + s.gzindex, copy);\n s.pending_buf.set(s.gzhead.extra.subarray(s.gzindex, s.gzindex + copy), s.pending);\n s.pending = s.pending_buf_size;\n //--- HCRC_UPDATE(beg) ---//\n if (s.gzhead.hcrc && s.pending > beg) {\n strm.adler = crc32_1(strm.adler, s.pending_buf, s.pending - beg, beg);\n }\n //---//\n s.gzindex += copy;\n flush_pending(strm);\n if (s.pending !== 0) {\n s.last_flush = -1;\n return Z_OK$3;\n }\n beg = 0;\n left -= copy;\n }\n // JS specific: s.gzhead.extra may be TypedArray or Array for backward compatibility\n // TypedArray.slice and TypedArray.from don't exist in IE10-IE11\n let gzhead_extra = new Uint8Array(s.gzhead.extra);\n // zmemcpy(s->pending_buf + s->pending,\n // s->gzhead->extra + s->gzindex, left);\n s.pending_buf.set(gzhead_extra.subarray(s.gzindex, s.gzindex + left), s.pending);\n s.pending += left;\n //--- HCRC_UPDATE(beg) ---//\n if (s.gzhead.hcrc && s.pending > beg) {\n strm.adler = crc32_1(strm.adler, s.pending_buf, s.pending - beg, beg);\n }\n //---//\n s.gzindex = 0;\n }\n s.status = NAME_STATE;\n }\n if (s.status === NAME_STATE) {\n if (s.gzhead.name/* != Z_NULL*/) {\n let beg = s.pending; /* start of bytes to update crc */\n let val;\n do {\n if (s.pending === s.pending_buf_size) {\n //--- HCRC_UPDATE(beg) ---//\n if (s.gzhead.hcrc && s.pending > beg) {\n strm.adler = crc32_1(strm.adler, s.pending_buf, s.pending - beg, beg);\n }\n //---//\n flush_pending(strm);\n if (s.pending !== 0) {\n s.last_flush = -1;\n return Z_OK$3;\n }\n beg = 0;\n }\n // JS specific: little magic to add zero terminator to end of string\n if (s.gzindex < s.gzhead.name.length) {\n val = s.gzhead.name.charCodeAt(s.gzindex++) & 0xff;\n } else {\n val = 0;\n }\n put_byte(s, val);\n } while (val !== 0);\n //--- HCRC_UPDATE(beg) ---//\n if (s.gzhead.hcrc && s.pending > beg) {\n strm.adler = crc32_1(strm.adler, s.pending_buf, s.pending - beg, beg);\n }\n //---//\n s.gzindex = 0;\n }\n s.status = COMMENT_STATE;\n }\n if (s.status === COMMENT_STATE) {\n if (s.gzhead.comment/* != Z_NULL*/) {\n let beg = s.pending; /* start of bytes to update crc */\n let val;\n do {\n if (s.pending === s.pending_buf_size) {\n //--- HCRC_UPDATE(beg) ---//\n if (s.gzhead.hcrc && s.pending > beg) {\n strm.adler = crc32_1(strm.adler, s.pending_buf, s.pending - beg, beg);\n }\n //---//\n flush_pending(strm);\n if (s.pending !== 0) {\n s.last_flush = -1;\n return Z_OK$3;\n }\n beg = 0;\n }\n // JS specific: little magic to add zero terminator to end of string\n if (s.gzindex < s.gzhead.comment.length) {\n val = s.gzhead.comment.charCodeAt(s.gzindex++) & 0xff;\n } else {\n val = 0;\n }\n put_byte(s, val);\n } while (val !== 0);\n //--- HCRC_UPDATE(beg) ---//\n if (s.gzhead.hcrc && s.pending > beg) {\n strm.adler = crc32_1(strm.adler, s.pending_buf, s.pending - beg, beg);\n }\n //---//\n }\n s.status = HCRC_STATE;\n }\n if (s.status === HCRC_STATE) {\n if (s.gzhead.hcrc) {\n if (s.pending + 2 > s.pending_buf_size) {\n flush_pending(strm);\n if (s.pending !== 0) {\n s.last_flush = -1;\n return Z_OK$3;\n }\n }\n put_byte(s, strm.adler & 0xff);\n put_byte(s, (strm.adler >> 8) & 0xff);\n strm.adler = 0; //crc32(0L, Z_NULL, 0);\n }\n s.status = BUSY_STATE;\n\n /* Compression must start with an empty pending buffer */\n flush_pending(strm);\n if (s.pending !== 0) {\n s.last_flush = -1;\n return Z_OK$3;\n }\n }\n//#endif\n\n /* Start a new block or continue the current one.\n */\n if (strm.avail_in !== 0 || s.lookahead !== 0 ||\n (flush !== Z_NO_FLUSH$2 && s.status !== FINISH_STATE)) {\n let bstate = s.level === 0 ? deflate_stored(s, flush) :\n s.strategy === Z_HUFFMAN_ONLY ? deflate_huff(s, flush) :\n s.strategy === Z_RLE ? deflate_rle(s, flush) :\n configuration_table[s.level].func(s, flush);\n\n if (bstate === BS_FINISH_STARTED || bstate === BS_FINISH_DONE) {\n s.status = FINISH_STATE;\n }\n if (bstate === BS_NEED_MORE || bstate === BS_FINISH_STARTED) {\n if (strm.avail_out === 0) {\n s.last_flush = -1;\n /* avoid BUF_ERROR next call, see above */\n }\n return Z_OK$3;\n /* If flush != Z_NO_FLUSH && avail_out == 0, the next call\n * of deflate should use the same flush parameter to make sure\n * that the flush is complete. So we don't have to output an\n * empty block here, this will be done at next call. This also\n * ensures that for a very small output buffer, we emit at most\n * one empty block.\n */\n }\n if (bstate === BS_BLOCK_DONE) {\n if (flush === Z_PARTIAL_FLUSH) {\n _tr_align(s);\n }\n else if (flush !== Z_BLOCK$1) { /* FULL_FLUSH or SYNC_FLUSH */\n\n _tr_stored_block(s, 0, 0, false);\n /* For a full flush, this empty block will be recognized\n * as a special marker by inflate_sync().\n */\n if (flush === Z_FULL_FLUSH$1) {\n /*** CLEAR_HASH(s); ***/ /* forget history */\n zero(s.head); // Fill with NIL (= 0);\n\n if (s.lookahead === 0) {\n s.strstart = 0;\n s.block_start = 0;\n s.insert = 0;\n }\n }\n }\n flush_pending(strm);\n if (strm.avail_out === 0) {\n s.last_flush = -1; /* avoid BUF_ERROR at next call, see above */\n return Z_OK$3;\n }\n }\n }\n\n if (flush !== Z_FINISH$3) { return Z_OK$3; }\n if (s.wrap <= 0) { return Z_STREAM_END$3; }\n\n /* Write the trailer */\n if (s.wrap === 2) {\n put_byte(s, strm.adler & 0xff);\n put_byte(s, (strm.adler >> 8) & 0xff);\n put_byte(s, (strm.adler >> 16) & 0xff);\n put_byte(s, (strm.adler >> 24) & 0xff);\n put_byte(s, strm.total_in & 0xff);\n put_byte(s, (strm.total_in >> 8) & 0xff);\n put_byte(s, (strm.total_in >> 16) & 0xff);\n put_byte(s, (strm.total_in >> 24) & 0xff);\n }\n else\n {\n putShortMSB(s, strm.adler >>> 16);\n putShortMSB(s, strm.adler & 0xffff);\n }\n\n flush_pending(strm);\n /* If avail_out is zero, the application will call deflate again\n * to flush the rest.\n */\n if (s.wrap > 0) { s.wrap = -s.wrap; }\n /* write the trailer only once! */\n return s.pending !== 0 ? Z_OK$3 : Z_STREAM_END$3;\n};\n\n\nconst deflateEnd = (strm) => {\n\n if (deflateStateCheck(strm)) {\n return Z_STREAM_ERROR$2;\n }\n\n const status = strm.state.status;\n\n strm.state = null;\n\n return status === BUSY_STATE ? err(strm, Z_DATA_ERROR$2) : Z_OK$3;\n};\n\n\n/* =========================================================================\n * Initializes the compression dictionary from the given byte\n * sequence without producing any compressed output.\n */\nconst deflateSetDictionary = (strm, dictionary) => {\n\n let dictLength = dictionary.length;\n\n if (deflateStateCheck(strm)) {\n return Z_STREAM_ERROR$2;\n }\n\n const s = strm.state;\n const wrap = s.wrap;\n\n if (wrap === 2 || (wrap === 1 && s.status !== INIT_STATE) || s.lookahead) {\n return Z_STREAM_ERROR$2;\n }\n\n /* when using zlib wrappers, compute Adler-32 for provided dictionary */\n if (wrap === 1) {\n /* adler32(strm->adler, dictionary, dictLength); */\n strm.adler = adler32_1(strm.adler, dictionary, dictLength, 0);\n }\n\n s.wrap = 0; /* avoid computing Adler-32 in read_buf */\n\n /* if dictionary would fill window, just replace the history */\n if (dictLength >= s.w_size) {\n if (wrap === 0) { /* already empty otherwise */\n /*** CLEAR_HASH(s); ***/\n zero(s.head); // Fill with NIL (= 0);\n s.strstart = 0;\n s.block_start = 0;\n s.insert = 0;\n }\n /* use the tail */\n // dictionary = dictionary.slice(dictLength - s.w_size);\n let tmpDict = new Uint8Array(s.w_size);\n tmpDict.set(dictionary.subarray(dictLength - s.w_size, dictLength), 0);\n dictionary = tmpDict;\n dictLength = s.w_size;\n }\n /* insert dictionary into window and hash */\n const avail = strm.avail_in;\n const next = strm.next_in;\n const input = strm.input;\n strm.avail_in = dictLength;\n strm.next_in = 0;\n strm.input = dictionary;\n fill_window(s);\n while (s.lookahead >= MIN_MATCH) {\n let str = s.strstart;\n let n = s.lookahead - (MIN_MATCH - 1);\n do {\n /* UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); */\n s.ins_h = HASH(s, s.ins_h, s.window[str + MIN_MATCH - 1]);\n\n s.prev[str & s.w_mask] = s.head[s.ins_h];\n\n s.head[s.ins_h] = str;\n str++;\n } while (--n);\n s.strstart = str;\n s.lookahead = MIN_MATCH - 1;\n fill_window(s);\n }\n s.strstart += s.lookahead;\n s.block_start = s.strstart;\n s.insert = s.lookahead;\n s.lookahead = 0;\n s.match_length = s.prev_length = MIN_MATCH - 1;\n s.match_available = 0;\n strm.next_in = next;\n strm.input = input;\n strm.avail_in = avail;\n s.wrap = wrap;\n return Z_OK$3;\n};\n\n\nvar deflateInit_1 = deflateInit;\nvar deflateInit2_1 = deflateInit2;\nvar deflateReset_1 = deflateReset;\nvar deflateResetKeep_1 = deflateResetKeep;\nvar deflateSetHeader_1 = deflateSetHeader;\nvar deflate_2$1 = deflate$2;\nvar deflateEnd_1 = deflateEnd;\nvar deflateSetDictionary_1 = deflateSetDictionary;\nvar deflateInfo = 'pako deflate (from Nodeca project)';\n\n/* Not implemented\nmodule.exports.deflateBound = deflateBound;\nmodule.exports.deflateCopy = deflateCopy;\nmodule.exports.deflateGetDictionary = deflateGetDictionary;\nmodule.exports.deflateParams = deflateParams;\nmodule.exports.deflatePending = deflatePending;\nmodule.exports.deflatePrime = deflatePrime;\nmodule.exports.deflateTune = deflateTune;\n*/\n\nvar deflate_1$2 = {\n\tdeflateInit: deflateInit_1,\n\tdeflateInit2: deflateInit2_1,\n\tdeflateReset: deflateReset_1,\n\tdeflateResetKeep: deflateResetKeep_1,\n\tdeflateSetHeader: deflateSetHeader_1,\n\tdeflate: deflate_2$1,\n\tdeflateEnd: deflateEnd_1,\n\tdeflateSetDictionary: deflateSetDictionary_1,\n\tdeflateInfo: deflateInfo\n};\n\nconst _has = (obj, key) => {\n return Object.prototype.hasOwnProperty.call(obj, key);\n};\n\nvar assign = function (obj /*from1, from2, from3, ...*/) {\n const sources = Array.prototype.slice.call(arguments, 1);\n while (sources.length) {\n const source = sources.shift();\n if (!source) { continue; }\n\n if (typeof source !== 'object') {\n throw new TypeError(source + 'must be non-object');\n }\n\n for (const p in source) {\n if (_has(source, p)) {\n obj[p] = source[p];\n }\n }\n }\n\n return obj;\n};\n\n\n// Join array of chunks to single array.\nvar flattenChunks = (chunks) => {\n // calculate data length\n let len = 0;\n\n for (let i = 0, l = chunks.length; i < l; i++) {\n len += chunks[i].length;\n }\n\n // join chunks\n const result = new Uint8Array(len);\n\n for (let i = 0, pos = 0, l = chunks.length; i < l; i++) {\n let chunk = chunks[i];\n result.set(chunk, pos);\n pos += chunk.length;\n }\n\n return result;\n};\n\nvar common = {\n\tassign: assign,\n\tflattenChunks: flattenChunks\n};\n\n// String encode/decode helpers\n\n\n// Quick check if we can use fast array to bin string conversion\n//\n// - apply(Array) can fail on Android 2.2\n// - apply(Uint8Array) can fail on iOS 5.1 Safari\n//\nlet STR_APPLY_UIA_OK = true;\n\ntry { String.fromCharCode.apply(null, new Uint8Array(1)); } catch (__) { STR_APPLY_UIA_OK = false; }\n\n\n// Table with utf8 lengths (calculated by first byte of sequence)\n// Note, that 5 & 6-byte values and some 4-byte values can not be represented in JS,\n// because max possible codepoint is 0x10ffff\nconst _utf8len = new Uint8Array(256);\nfor (let q = 0; q < 256; q++) {\n _utf8len[q] = (q >= 252 ? 6 : q >= 248 ? 5 : q >= 240 ? 4 : q >= 224 ? 3 : q >= 192 ? 2 : 1);\n}\n_utf8len[254] = _utf8len[254] = 1; // Invalid sequence start\n\n\n// convert string to array (typed, when possible)\nvar string2buf = (str) => {\n if (typeof TextEncoder === 'function' && TextEncoder.prototype.encode) {\n return new TextEncoder().encode(str);\n }\n\n let buf, c, c2, m_pos, i, str_len = str.length, buf_len = 0;\n\n // count binary size\n for (m_pos = 0; m_pos < str_len; m_pos++) {\n c = str.charCodeAt(m_pos);\n if ((c & 0xfc00) === 0xd800 && (m_pos + 1 < str_len)) {\n c2 = str.charCodeAt(m_pos + 1);\n if ((c2 & 0xfc00) === 0xdc00) {\n c = 0x10000 + ((c - 0xd800) << 10) + (c2 - 0xdc00);\n m_pos++;\n }\n }\n buf_len += c < 0x80 ? 1 : c < 0x800 ? 2 : c < 0x10000 ? 3 : 4;\n }\n\n // allocate buffer\n buf = new Uint8Array(buf_len);\n\n // convert\n for (i = 0, m_pos = 0; i < buf_len; m_pos++) {\n c = str.charCodeAt(m_pos);\n if ((c & 0xfc00) === 0xd800 && (m_pos + 1 < str_len)) {\n c2 = str.charCodeAt(m_pos + 1);\n if ((c2 & 0xfc00) === 0xdc00) {\n c = 0x10000 + ((c - 0xd800) << 10) + (c2 - 0xdc00);\n m_pos++;\n }\n }\n if (c < 0x80) {\n /* one byte */\n buf[i++] = c;\n } else if (c < 0x800) {\n /* two bytes */\n buf[i++] = 0xC0 | (c >>> 6);\n buf[i++] = 0x80 | (c & 0x3f);\n } else if (c < 0x10000) {\n /* three bytes */\n buf[i++] = 0xE0 | (c >>> 12);\n buf[i++] = 0x80 | (c >>> 6 & 0x3f);\n buf[i++] = 0x80 | (c & 0x3f);\n } else {\n /* four bytes */\n buf[i++] = 0xf0 | (c >>> 18);\n buf[i++] = 0x80 | (c >>> 12 & 0x3f);\n buf[i++] = 0x80 | (c >>> 6 & 0x3f);\n buf[i++] = 0x80 | (c & 0x3f);\n }\n }\n\n return buf;\n};\n\n// Helper\nconst buf2binstring = (buf, len) => {\n // On Chrome, the arguments in a function call that are allowed is `65534`.\n // If the length of the buffer is smaller than that, we can use this optimization,\n // otherwise we will take a slower path.\n if (len < 65534) {\n if (buf.subarray && STR_APPLY_UIA_OK) {\n return String.fromCharCode.apply(null, buf.length === len ? buf : buf.subarray(0, len));\n }\n }\n\n let result = '';\n for (let i = 0; i < len; i++) {\n result += String.fromCharCode(buf[i]);\n }\n return result;\n};\n\n\n// convert array to string\nvar buf2string = (buf, max) => {\n const len = max || buf.length;\n\n if (typeof TextDecoder === 'function' && TextDecoder.prototype.decode) {\n return new TextDecoder().decode(buf.subarray(0, max));\n }\n\n let i, out;\n\n // Reserve max possible length (2 words per char)\n // NB: by unknown reasons, Array is significantly faster for\n // String.fromCharCode.apply than Uint16Array.\n const utf16buf = new Array(len * 2);\n\n for (out = 0, i = 0; i < len;) {\n let c = buf[i++];\n // quick process ascii\n if (c < 0x80) { utf16buf[out++] = c; continue; }\n\n let c_len = _utf8len[c];\n // skip 5 & 6 byte codes\n if (c_len > 4) { utf16buf[out++] = 0xfffd; i += c_len - 1; continue; }\n\n // apply mask on first byte\n c &= c_len === 2 ? 0x1f : c_len === 3 ? 0x0f : 0x07;\n // join the rest\n while (c_len > 1 && i < len) {\n c = (c << 6) | (buf[i++] & 0x3f);\n c_len--;\n }\n\n // terminated by end of string?\n if (c_len > 1) { utf16buf[out++] = 0xfffd; continue; }\n\n if (c < 0x10000) {\n utf16buf[out++] = c;\n } else {\n c -= 0x10000;\n utf16buf[out++] = 0xd800 | ((c >> 10) & 0x3ff);\n utf16buf[out++] = 0xdc00 | (c & 0x3ff);\n }\n }\n\n return buf2binstring(utf16buf, out);\n};\n\n\n// Calculate max possible position in utf8 buffer,\n// that will not break sequence. If that's not possible\n// - (very small limits) return max size as is.\n//\n// buf[] - utf8 bytes array\n// max - length limit (mandatory);\nvar utf8border = (buf, max) => {\n\n max = max || buf.length;\n if (max > buf.length) { max = buf.length; }\n\n // go back from last position, until start of sequence found\n let pos = max - 1;\n while (pos >= 0 && (buf[pos] & 0xC0) === 0x80) { pos--; }\n\n // Very small and broken sequence,\n // return max, because we should return something anyway.\n if (pos < 0) { return max; }\n\n // If we came to start of buffer - that means buffer is too small,\n // return max too.\n if (pos === 0) { return max; }\n\n return (pos + _utf8len[buf[pos]] > max) ? pos : max;\n};\n\nvar strings = {\n\tstring2buf: string2buf,\n\tbuf2string: buf2string,\n\tutf8border: utf8border\n};\n\n// (C) 1995-2013 Jean-loup Gailly and Mark Adler\n// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin\n//\n// This software is provided 'as-is', without any express or implied\n// warranty. In no event will the authors be held liable for any damages\n// arising from the use of this software.\n//\n// Permission is granted to anyone to use this software for any purpose,\n// including commercial applications, and to alter it and redistribute it\n// freely, subject to the following restrictions:\n//\n// 1. The origin of this software must not be misrepresented; you must not\n// claim that you wrote the original software. If you use this software\n// in a product, an acknowledgment in the product documentation would be\n// appreciated but is not required.\n// 2. Altered source versions must be plainly marked as such, and must not be\n// misrepresented as being the original software.\n// 3. This notice may not be removed or altered from any source distribution.\n\nfunction ZStream() {\n /* next input byte */\n this.input = null; // JS specific, because we have no pointers\n this.next_in = 0;\n /* number of bytes available at input */\n this.avail_in = 0;\n /* total number of input bytes read so far */\n this.total_in = 0;\n /* next output byte should be put there */\n this.output = null; // JS specific, because we have no pointers\n this.next_out = 0;\n /* remaining free space at output */\n this.avail_out = 0;\n /* total number of bytes output so far */\n this.total_out = 0;\n /* last error message, NULL if no error */\n this.msg = ''/*Z_NULL*/;\n /* not visible by applications */\n this.state = null;\n /* best guess about the data type: binary or text */\n this.data_type = 2/*Z_UNKNOWN*/;\n /* adler32 value of the uncompressed data */\n this.adler = 0;\n}\n\nvar zstream = ZStream;\n\nconst toString$1 = Object.prototype.toString;\n\n/* Public constants ==========================================================*/\n/* ===========================================================================*/\n\nconst {\n Z_NO_FLUSH: Z_NO_FLUSH$1, Z_SYNC_FLUSH, Z_FULL_FLUSH, Z_FINISH: Z_FINISH$2,\n Z_OK: Z_OK$2, Z_STREAM_END: Z_STREAM_END$2,\n Z_DEFAULT_COMPRESSION,\n Z_DEFAULT_STRATEGY,\n Z_DEFLATED: Z_DEFLATED$1\n} = constants$2;\n\n/* ===========================================================================*/\n\n\n/**\n * class Deflate\n *\n * Generic JS-style wrapper for zlib calls. If you don't need\n * streaming behaviour - use more simple functions: [[deflate]],\n * [[deflateRaw]] and [[gzip]].\n **/\n\n/* internal\n * Deflate.chunks -> Array\n *\n * Chunks of output data, if [[Deflate#onData]] not overridden.\n **/\n\n/**\n * Deflate.result -> Uint8Array\n *\n * Compressed result, generated by default [[Deflate#onData]]\n * and [[Deflate#onEnd]] handlers. Filled after you push last chunk\n * (call [[Deflate#push]] with `Z_FINISH` / `true` param).\n **/\n\n/**\n * Deflate.err -> Number\n *\n * Error code after deflate finished. 0 (Z_OK) on success.\n * You will not need it in real life, because deflate errors\n * are possible only on wrong options or bad `onData` / `onEnd`\n * custom handlers.\n **/\n\n/**\n * Deflate.msg -> String\n *\n * Error message, if [[Deflate.err]] != 0\n **/\n\n\n/**\n * new Deflate(options)\n * - options (Object): zlib deflate options.\n *\n * Creates new deflator instance with specified params. Throws exception\n * on bad params. Supported options:\n *\n * - `level`\n * - `windowBits`\n * - `memLevel`\n * - `strategy`\n * - `dictionary`\n *\n * [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced)\n * for more information on these.\n *\n * Additional options, for internal needs:\n *\n * - `chunkSize` - size of generated data chunks (16K by default)\n * - `raw` (Boolean) - do raw deflate\n * - `gzip` (Boolean) - create gzip wrapper\n * - `header` (Object) - custom header for gzip\n * - `text` (Boolean) - true if compressed data believed to be text\n * - `time` (Number) - modification time, unix timestamp\n * - `os` (Number) - operation system code\n * - `extra` (Array) - array of bytes with extra data (max 65536)\n * - `name` (String) - file name (binary string)\n * - `comment` (String) - comment (binary string)\n * - `hcrc` (Boolean) - true if header crc should be added\n *\n * ##### Example:\n *\n * ```javascript\n * const pako = require('pako')\n * , chunk1 = new Uint8Array([1,2,3,4,5,6,7,8,9])\n * , chunk2 = new Uint8Array([10,11,12,13,14,15,16,17,18,19]);\n *\n * const deflate = new pako.Deflate({ level: 3});\n *\n * deflate.push(chunk1, false);\n * deflate.push(chunk2, true); // true -> last chunk\n *\n * if (deflate.err) { throw new Error(deflate.err); }\n *\n * console.log(deflate.result);\n * ```\n **/\nfunction Deflate$1(options) {\n this.options = common.assign({\n level: Z_DEFAULT_COMPRESSION,\n method: Z_DEFLATED$1,\n chunkSize: 16384,\n windowBits: 15,\n memLevel: 8,\n strategy: Z_DEFAULT_STRATEGY\n }, options || {});\n\n let opt = this.options;\n\n if (opt.raw && (opt.windowBits > 0)) {\n opt.windowBits = -opt.windowBits;\n }\n\n else if (opt.gzip && (opt.windowBits > 0) && (opt.windowBits < 16)) {\n opt.windowBits += 16;\n }\n\n this.err = 0; // error code, if happens (0 = Z_OK)\n this.msg = ''; // error message\n this.ended = false; // used to avoid multiple onEnd() calls\n this.chunks = []; // chunks of compressed data\n\n this.strm = new zstream();\n this.strm.avail_out = 0;\n\n let status = deflate_1$2.deflateInit2(\n this.strm,\n opt.level,\n opt.method,\n opt.windowBits,\n opt.memLevel,\n opt.strategy\n );\n\n if (status !== Z_OK$2) {\n throw new Error(messages[status]);\n }\n\n if (opt.header) {\n deflate_1$2.deflateSetHeader(this.strm, opt.header);\n }\n\n if (opt.dictionary) {\n let dict;\n // Convert data if needed\n if (typeof opt.dictionary === 'string') {\n // If we need to compress text, change encoding to utf8.\n dict = strings.string2buf(opt.dictionary);\n } else if (toString$1.call(opt.dictionary) === '[object ArrayBuffer]') {\n dict = new Uint8Array(opt.dictionary);\n } else {\n dict = opt.dictionary;\n }\n\n status = deflate_1$2.deflateSetDictionary(this.strm, dict);\n\n if (status !== Z_OK$2) {\n throw new Error(messages[status]);\n }\n\n this._dict_set = true;\n }\n}\n\n/**\n * Deflate#push(data[, flush_mode]) -> Boolean\n * - data (Uint8Array|ArrayBuffer|String): input data. Strings will be\n * converted to utf8 byte sequence.\n * - flush_mode (Number|Boolean): 0..6 for corresponding Z_NO_FLUSH..Z_TREE modes.\n * See constants. Skipped or `false` means Z_NO_FLUSH, `true` means Z_FINISH.\n *\n * Sends input data to deflate pipe, generating [[Deflate#onData]] calls with\n * new compressed chunks. Returns `true` on success. The last data block must\n * have `flush_mode` Z_FINISH (or `true`). That will flush internal pending\n * buffers and call [[Deflate#onEnd]].\n *\n * On fail call [[Deflate#onEnd]] with error code and return false.\n *\n * ##### Example\n *\n * ```javascript\n * push(chunk, false); // push one of data chunks\n * ...\n * push(chunk, true); // push last chunk\n * ```\n **/\nDeflate$1.prototype.push = function (data, flush_mode) {\n const strm = this.strm;\n const chunkSize = this.options.chunkSize;\n let status, _flush_mode;\n\n if (this.ended) { return false; }\n\n if (flush_mode === ~~flush_mode) _flush_mode = flush_mode;\n else _flush_mode = flush_mode === true ? Z_FINISH$2 : Z_NO_FLUSH$1;\n\n // Convert data if needed\n if (typeof data === 'string') {\n // If we need to compress text, change encoding to utf8.\n strm.input = strings.string2buf(data);\n } else if (toString$1.call(data) === '[object ArrayBuffer]') {\n strm.input = new Uint8Array(data);\n } else {\n strm.input = data;\n }\n\n strm.next_in = 0;\n strm.avail_in = strm.input.length;\n\n for (;;) {\n if (strm.avail_out === 0) {\n strm.output = new Uint8Array(chunkSize);\n strm.next_out = 0;\n strm.avail_out = chunkSize;\n }\n\n // Make sure avail_out > 6 to avoid repeating markers\n if ((_flush_mode === Z_SYNC_FLUSH || _flush_mode === Z_FULL_FLUSH) && strm.avail_out <= 6) {\n this.onData(strm.output.subarray(0, strm.next_out));\n strm.avail_out = 0;\n continue;\n }\n\n status = deflate_1$2.deflate(strm, _flush_mode);\n\n // Ended => flush and finish\n if (status === Z_STREAM_END$2) {\n if (strm.next_out > 0) {\n this.onData(strm.output.subarray(0, strm.next_out));\n }\n status = deflate_1$2.deflateEnd(this.strm);\n this.onEnd(status);\n this.ended = true;\n return status === Z_OK$2;\n }\n\n // Flush if out buffer full\n if (strm.avail_out === 0) {\n this.onData(strm.output);\n continue;\n }\n\n // Flush if requested and has data\n if (_flush_mode > 0 && strm.next_out > 0) {\n this.onData(strm.output.subarray(0, strm.next_out));\n strm.avail_out = 0;\n continue;\n }\n\n if (strm.avail_in === 0) break;\n }\n\n return true;\n};\n\n\n/**\n * Deflate#onData(chunk) -> Void\n * - chunk (Uint8Array): output data.\n *\n * By default, stores data blocks in `chunks[]` property and glue\n * those in `onEnd`. Override this handler, if you need another behaviour.\n **/\nDeflate$1.prototype.onData = function (chunk) {\n this.chunks.push(chunk);\n};\n\n\n/**\n * Deflate#onEnd(status) -> Void\n * - status (Number): deflate status. 0 (Z_OK) on success,\n * other if not.\n *\n * Called once after you tell deflate that the input stream is\n * complete (Z_FINISH). By default - join collected chunks,\n * free memory and fill `results` / `err` properties.\n **/\nDeflate$1.prototype.onEnd = function (status) {\n // On success - join\n if (status === Z_OK$2) {\n this.result = common.flattenChunks(this.chunks);\n }\n this.chunks = [];\n this.err = status;\n this.msg = this.strm.msg;\n};\n\n\n/**\n * deflate(data[, options]) -> Uint8Array\n * - data (Uint8Array|ArrayBuffer|String): input data to compress.\n * - options (Object): zlib deflate options.\n *\n * Compress `data` with deflate algorithm and `options`.\n *\n * Supported options are:\n *\n * - level\n * - windowBits\n * - memLevel\n * - strategy\n * - dictionary\n *\n * [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced)\n * for more information on these.\n *\n * Sugar (options):\n *\n * - `raw` (Boolean) - say that we work with raw stream, if you don't wish to specify\n * negative windowBits implicitly.\n *\n * ##### Example:\n *\n * ```javascript\n * const pako = require('pako')\n * const data = new Uint8Array([1,2,3,4,5,6,7,8,9]);\n *\n * console.log(pako.deflate(data));\n * ```\n **/\nfunction deflate$1(input, options) {\n const deflator = new Deflate$1(options);\n\n deflator.push(input, true);\n\n // That will never happens, if you don't cheat with options :)\n if (deflator.err) { throw deflator.msg || messages[deflator.err]; }\n\n return deflator.result;\n}\n\n\n/**\n * deflateRaw(data[, options]) -> Uint8Array\n * - data (Uint8Array|ArrayBuffer|String): input data to compress.\n * - options (Object): zlib deflate options.\n *\n * The same as [[deflate]], but creates raw data, without wrapper\n * (header and adler32 crc).\n **/\nfunction deflateRaw$1(input, options) {\n options = options || {};\n options.raw = true;\n return deflate$1(input, options);\n}\n\n\n/**\n * gzip(data[, options]) -> Uint8Array\n * - data (Uint8Array|ArrayBuffer|String): input data to compress.\n * - options (Object): zlib deflate options.\n *\n * The same as [[deflate]], but create gzip wrapper instead of\n * deflate one.\n **/\nfunction gzip$1(input, options) {\n options = options || {};\n options.gzip = true;\n return deflate$1(input, options);\n}\n\n\nvar Deflate_1$1 = Deflate$1;\nvar deflate_2 = deflate$1;\nvar deflateRaw_1$1 = deflateRaw$1;\nvar gzip_1$1 = gzip$1;\nvar constants$1 = constants$2;\n\nvar deflate_1$1 = {\n\tDeflate: Deflate_1$1,\n\tdeflate: deflate_2,\n\tdeflateRaw: deflateRaw_1$1,\n\tgzip: gzip_1$1,\n\tconstants: constants$1\n};\n\n// (C) 1995-2013 Jean-loup Gailly and Mark Adler\n// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin\n//\n// This software is provided 'as-is', without any express or implied\n// warranty. In no event will the authors be held liable for any damages\n// arising from the use of this software.\n//\n// Permission is granted to anyone to use this software for any purpose,\n// including commercial applications, and to alter it and redistribute it\n// freely, subject to the following restrictions:\n//\n// 1. The origin of this software must not be misrepresented; you must not\n// claim that you wrote the original software. If you use this software\n// in a product, an acknowledgment in the product documentation would be\n// appreciated but is not required.\n// 2. Altered source versions must be plainly marked as such, and must not be\n// misrepresented as being the original software.\n// 3. This notice may not be removed or altered from any source distribution.\n\n// See state defs from inflate.js\nconst BAD$1 = 16209; /* got a data error -- remain here until reset */\nconst TYPE$1 = 16191; /* i: waiting for type bits, including last-flag bit */\n\n/*\n Decode literal, length, and distance codes and write out the resulting\n literal and match bytes until either not enough input or output is\n available, an end-of-block is encountered, or a data error is encountered.\n When large enough input and output buffers are supplied to inflate(), for\n example, a 16K input buffer and a 64K output buffer, more than 95% of the\n inflate execution time is spent in this routine.\n\n Entry assumptions:\n\n state.mode === LEN\n strm.avail_in >= 6\n strm.avail_out >= 258\n start >= strm.avail_out\n state.bits < 8\n\n On return, state.mode is one of:\n\n LEN -- ran out of enough output space or enough available input\n TYPE -- reached end of block code, inflate() to interpret next block\n BAD -- error in block data\n\n Notes:\n\n - The maximum input bits used by a length/distance pair is 15 bits for the\n length code, 5 bits for the length extra, 15 bits for the distance code,\n and 13 bits for the distance extra. This totals 48 bits, or six bytes.\n Therefore if strm.avail_in >= 6, then there is enough input to avoid\n checking for available input while decoding.\n\n - The maximum bytes that a single length/distance pair can output is 258\n bytes, which is the maximum length that can be coded. inflate_fast()\n requires strm.avail_out >= 258 for each loop to avoid checking for\n output space.\n */\nvar inffast = function inflate_fast(strm, start) {\n let _in; /* local strm.input */\n let last; /* have enough input while in < last */\n let _out; /* local strm.output */\n let beg; /* inflate()'s initial strm.output */\n let end; /* while out < end, enough space available */\n//#ifdef INFLATE_STRICT\n let dmax; /* maximum distance from zlib header */\n//#endif\n let wsize; /* window size or zero if not using window */\n let whave; /* valid bytes in the window */\n let wnext; /* window write index */\n // Use `s_window` instead `window`, avoid conflict with instrumentation tools\n let s_window; /* allocated sliding window, if wsize != 0 */\n let hold; /* local strm.hold */\n let bits; /* local strm.bits */\n let lcode; /* local strm.lencode */\n let dcode; /* local strm.distcode */\n let lmask; /* mask for first level of length codes */\n let dmask; /* mask for first level of distance codes */\n let here; /* retrieved table entry */\n let op; /* code bits, operation, extra bits, or */\n /* window position, window bytes to copy */\n let len; /* match length, unused bytes */\n let dist; /* match distance */\n let from; /* where to copy match from */\n let from_source;\n\n\n let input, output; // JS specific, because we have no pointers\n\n /* copy state to local variables */\n const state = strm.state;\n //here = state.here;\n _in = strm.next_in;\n input = strm.input;\n last = _in + (strm.avail_in - 5);\n _out = strm.next_out;\n output = strm.output;\n beg = _out - (start - strm.avail_out);\n end = _out + (strm.avail_out - 257);\n//#ifdef INFLATE_STRICT\n dmax = state.dmax;\n//#endif\n wsize = state.wsize;\n whave = state.whave;\n wnext = state.wnext;\n s_window = state.window;\n hold = state.hold;\n bits = state.bits;\n lcode = state.lencode;\n dcode = state.distcode;\n lmask = (1 << state.lenbits) - 1;\n dmask = (1 << state.distbits) - 1;\n\n\n /* decode literals and length/distances until end-of-block or not enough\n input data or output space */\n\n top:\n do {\n if (bits < 15) {\n hold += input[_in++] << bits;\n bits += 8;\n hold += input[_in++] << bits;\n bits += 8;\n }\n\n here = lcode[hold & lmask];\n\n dolen:\n for (;;) { // Goto emulation\n op = here >>> 24/*here.bits*/;\n hold >>>= op;\n bits -= op;\n op = (here >>> 16) & 0xff/*here.op*/;\n if (op === 0) { /* literal */\n //Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?\n // \"inflate: literal '%c'\\n\" :\n // \"inflate: literal 0x%02x\\n\", here.val));\n output[_out++] = here & 0xffff/*here.val*/;\n }\n else if (op & 16) { /* length base */\n len = here & 0xffff/*here.val*/;\n op &= 15; /* number of extra bits */\n if (op) {\n if (bits < op) {\n hold += input[_in++] << bits;\n bits += 8;\n }\n len += hold & ((1 << op) - 1);\n hold >>>= op;\n bits -= op;\n }\n //Tracevv((stderr, \"inflate: length %u\\n\", len));\n if (bits < 15) {\n hold += input[_in++] << bits;\n bits += 8;\n hold += input[_in++] << bits;\n bits += 8;\n }\n here = dcode[hold & dmask];\n\n dodist:\n for (;;) { // goto emulation\n op = here >>> 24/*here.bits*/;\n hold >>>= op;\n bits -= op;\n op = (here >>> 16) & 0xff/*here.op*/;\n\n if (op & 16) { /* distance base */\n dist = here & 0xffff/*here.val*/;\n op &= 15; /* number of extra bits */\n if (bits < op) {\n hold += input[_in++] << bits;\n bits += 8;\n if (bits < op) {\n hold += input[_in++] << bits;\n bits += 8;\n }\n }\n dist += hold & ((1 << op) - 1);\n//#ifdef INFLATE_STRICT\n if (dist > dmax) {\n strm.msg = 'invalid distance too far back';\n state.mode = BAD$1;\n break top;\n }\n//#endif\n hold >>>= op;\n bits -= op;\n //Tracevv((stderr, \"inflate: distance %u\\n\", dist));\n op = _out - beg; /* max distance in output */\n if (dist > op) { /* see if copy from window */\n op = dist - op; /* distance back in window */\n if (op > whave) {\n if (state.sane) {\n strm.msg = 'invalid distance too far back';\n state.mode = BAD$1;\n break top;\n }\n\n// (!) This block is disabled in zlib defaults,\n// don't enable it for binary compatibility\n//#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR\n// if (len <= op - whave) {\n// do {\n// output[_out++] = 0;\n// } while (--len);\n// continue top;\n// }\n// len -= op - whave;\n// do {\n// output[_out++] = 0;\n// } while (--op > whave);\n// if (op === 0) {\n// from = _out - dist;\n// do {\n// output[_out++] = output[from++];\n// } while (--len);\n// continue top;\n// }\n//#endif\n }\n from = 0; // window index\n from_source = s_window;\n if (wnext === 0) { /* very common case */\n from += wsize - op;\n if (op < len) { /* some from window */\n len -= op;\n do {\n output[_out++] = s_window[from++];\n } while (--op);\n from = _out - dist; /* rest from output */\n from_source = output;\n }\n }\n else if (wnext < op) { /* wrap around window */\n from += wsize + wnext - op;\n op -= wnext;\n if (op < len) { /* some from end of window */\n len -= op;\n do {\n output[_out++] = s_window[from++];\n } while (--op);\n from = 0;\n if (wnext < len) { /* some from start of window */\n op = wnext;\n len -= op;\n do {\n output[_out++] = s_window[from++];\n } while (--op);\n from = _out - dist; /* rest from output */\n from_source = output;\n }\n }\n }\n else { /* contiguous in window */\n from += wnext - op;\n if (op < len) { /* some from window */\n len -= op;\n do {\n output[_out++] = s_window[from++];\n } while (--op);\n from = _out - dist; /* rest from output */\n from_source = output;\n }\n }\n while (len > 2) {\n output[_out++] = from_source[from++];\n output[_out++] = from_source[from++];\n output[_out++] = from_source[from++];\n len -= 3;\n }\n if (len) {\n output[_out++] = from_source[from++];\n if (len > 1) {\n output[_out++] = from_source[from++];\n }\n }\n }\n else {\n from = _out - dist; /* copy direct from output */\n do { /* minimum length is three */\n output[_out++] = output[from++];\n output[_out++] = output[from++];\n output[_out++] = output[from++];\n len -= 3;\n } while (len > 2);\n if (len) {\n output[_out++] = output[from++];\n if (len > 1) {\n output[_out++] = output[from++];\n }\n }\n }\n }\n else if ((op & 64) === 0) { /* 2nd level distance code */\n here = dcode[(here & 0xffff)/*here.val*/ + (hold & ((1 << op) - 1))];\n continue dodist;\n }\n else {\n strm.msg = 'invalid distance code';\n state.mode = BAD$1;\n break top;\n }\n\n break; // need to emulate goto via \"continue\"\n }\n }\n else if ((op & 64) === 0) { /* 2nd level length code */\n here = lcode[(here & 0xffff)/*here.val*/ + (hold & ((1 << op) - 1))];\n continue dolen;\n }\n else if (op & 32) { /* end-of-block */\n //Tracevv((stderr, \"inflate: end of block\\n\"));\n state.mode = TYPE$1;\n break top;\n }\n else {\n strm.msg = 'invalid literal/length code';\n state.mode = BAD$1;\n break top;\n }\n\n break; // need to emulate goto via \"continue\"\n }\n } while (_in < last && _out < end);\n\n /* return unused bytes (on entry, bits < 8, so in won't go too far back) */\n len = bits >> 3;\n _in -= len;\n bits -= len << 3;\n hold &= (1 << bits) - 1;\n\n /* update state and return */\n strm.next_in = _in;\n strm.next_out = _out;\n strm.avail_in = (_in < last ? 5 + (last - _in) : 5 - (_in - last));\n strm.avail_out = (_out < end ? 257 + (end - _out) : 257 - (_out - end));\n state.hold = hold;\n state.bits = bits;\n return;\n};\n\n// (C) 1995-2013 Jean-loup Gailly and Mark Adler\n// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin\n//\n// This software is provided 'as-is', without any express or implied\n// warranty. In no event will the authors be held liable for any damages\n// arising from the use of this software.\n//\n// Permission is granted to anyone to use this software for any purpose,\n// including commercial applications, and to alter it and redistribute it\n// freely, subject to the following restrictions:\n//\n// 1. The origin of this software must not be misrepresented; you must not\n// claim that you wrote the original software. If you use this software\n// in a product, an acknowledgment in the product documentation would be\n// appreciated but is not required.\n// 2. Altered source versions must be plainly marked as such, and must not be\n// misrepresented as being the original software.\n// 3. This notice may not be removed or altered from any source distribution.\n\nconst MAXBITS = 15;\nconst ENOUGH_LENS$1 = 852;\nconst ENOUGH_DISTS$1 = 592;\n//const ENOUGH = (ENOUGH_LENS+ENOUGH_DISTS);\n\nconst CODES$1 = 0;\nconst LENS$1 = 1;\nconst DISTS$1 = 2;\n\nconst lbase = new Uint16Array([ /* Length codes 257..285 base */\n 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,\n 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0\n]);\n\nconst lext = new Uint8Array([ /* Length codes 257..285 extra */\n 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18,\n 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 72, 78\n]);\n\nconst dbase = new Uint16Array([ /* Distance codes 0..29 base */\n 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,\n 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,\n 8193, 12289, 16385, 24577, 0, 0\n]);\n\nconst dext = new Uint8Array([ /* Distance codes 0..29 extra */\n 16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22,\n 23, 23, 24, 24, 25, 25, 26, 26, 27, 27,\n 28, 28, 29, 29, 64, 64\n]);\n\nconst inflate_table = (type, lens, lens_index, codes, table, table_index, work, opts) =>\n{\n const bits = opts.bits;\n //here = opts.here; /* table entry for duplication */\n\n let len = 0; /* a code's length in bits */\n let sym = 0; /* index of code symbols */\n let min = 0, max = 0; /* minimum and maximum code lengths */\n let root = 0; /* number of index bits for root table */\n let curr = 0; /* number of index bits for current table */\n let drop = 0; /* code bits to drop for sub-table */\n let left = 0; /* number of prefix codes available */\n let used = 0; /* code entries in table used */\n let huff = 0; /* Huffman code */\n let incr; /* for incrementing code, index */\n let fill; /* index for replicating entries */\n let low; /* low bits for current root entry */\n let mask; /* mask for low root bits */\n let next; /* next available space in table */\n let base = null; /* base value table to use */\n// let shoextra; /* extra bits table to use */\n let match; /* use base and extra for symbol >= match */\n const count = new Uint16Array(MAXBITS + 1); //[MAXBITS+1]; /* number of codes of each length */\n const offs = new Uint16Array(MAXBITS + 1); //[MAXBITS+1]; /* offsets in table for each length */\n let extra = null;\n\n let here_bits, here_op, here_val;\n\n /*\n Process a set of code lengths to create a canonical Huffman code. The\n code lengths are lens[0..codes-1]. Each length corresponds to the\n symbols 0..codes-1. The Huffman code is generated by first sorting the\n symbols by length from short to long, and retaining the symbol order\n for codes with equal lengths. Then the code starts with all zero bits\n for the first code of the shortest length, and the codes are integer\n increments for the same length, and zeros are appended as the length\n increases. For the deflate format, these bits are stored backwards\n from their more natural integer increment ordering, and so when the\n decoding tables are built in the large loop below, the integer codes\n are incremented backwards.\n\n This routine assumes, but does not check, that all of the entries in\n lens[] are in the range 0..MAXBITS. The caller must assure this.\n 1..MAXBITS is interpreted as that code length. zero means that that\n symbol does not occur in this code.\n\n The codes are sorted by computing a count of codes for each length,\n creating from that a table of starting indices for each length in the\n sorted table, and then entering the symbols in order in the sorted\n table. The sorted table is work[], with that space being provided by\n the caller.\n\n The length counts are used for other purposes as well, i.e. finding\n the minimum and maximum length codes, determining if there are any\n codes at all, checking for a valid set of lengths, and looking ahead\n at length counts to determine sub-table sizes when building the\n decoding tables.\n */\n\n /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */\n for (len = 0; len <= MAXBITS; len++) {\n count[len] = 0;\n }\n for (sym = 0; sym < codes; sym++) {\n count[lens[lens_index + sym]]++;\n }\n\n /* bound code lengths, force root to be within code lengths */\n root = bits;\n for (max = MAXBITS; max >= 1; max--) {\n if (count[max] !== 0) { break; }\n }\n if (root > max) {\n root = max;\n }\n if (max === 0) { /* no symbols to code at all */\n //table.op[opts.table_index] = 64; //here.op = (var char)64; /* invalid code marker */\n //table.bits[opts.table_index] = 1; //here.bits = (var char)1;\n //table.val[opts.table_index++] = 0; //here.val = (var short)0;\n table[table_index++] = (1 << 24) | (64 << 16) | 0;\n\n\n //table.op[opts.table_index] = 64;\n //table.bits[opts.table_index] = 1;\n //table.val[opts.table_index++] = 0;\n table[table_index++] = (1 << 24) | (64 << 16) | 0;\n\n opts.bits = 1;\n return 0; /* no symbols, but wait for decoding to report error */\n }\n for (min = 1; min < max; min++) {\n if (count[min] !== 0) { break; }\n }\n if (root < min) {\n root = min;\n }\n\n /* check for an over-subscribed or incomplete set of lengths */\n left = 1;\n for (len = 1; len <= MAXBITS; len++) {\n left <<= 1;\n left -= count[len];\n if (left < 0) {\n return -1;\n } /* over-subscribed */\n }\n if (left > 0 && (type === CODES$1 || max !== 1)) {\n return -1; /* incomplete set */\n }\n\n /* generate offsets into symbol table for each length for sorting */\n offs[1] = 0;\n for (len = 1; len < MAXBITS; len++) {\n offs[len + 1] = offs[len] + count[len];\n }\n\n /* sort symbols by length, by symbol order within each length */\n for (sym = 0; sym < codes; sym++) {\n if (lens[lens_index + sym] !== 0) {\n work[offs[lens[lens_index + sym]]++] = sym;\n }\n }\n\n /*\n Create and fill in decoding tables. In this loop, the table being\n filled is at next and has curr index bits. The code being used is huff\n with length len. That code is converted to an index by dropping drop\n bits off of the bottom. For codes where len is less than drop + curr,\n those top drop + curr - len bits are incremented through all values to\n fill the table with replicated entries.\n\n root is the number of index bits for the root table. When len exceeds\n root, sub-tables are created pointed to by the root entry with an index\n of the low root bits of huff. This is saved in low to check for when a\n new sub-table should be started. drop is zero when the root table is\n being filled, and drop is root when sub-tables are being filled.\n\n When a new sub-table is needed, it is necessary to look ahead in the\n code lengths to determine what size sub-table is needed. The length\n counts are used for this, and so count[] is decremented as codes are\n entered in the tables.\n\n used keeps track of how many table entries have been allocated from the\n provided *table space. It is checked for LENS and DIST tables against\n the constants ENOUGH_LENS and ENOUGH_DISTS to guard against changes in\n the initial root table size constants. See the comments in inftrees.h\n for more information.\n\n sym increments through all symbols, and the loop terminates when\n all codes of length max, i.e. all codes, have been processed. This\n routine permits incomplete codes, so another loop after this one fills\n in the rest of the decoding tables with invalid code markers.\n */\n\n /* set up for code type */\n // poor man optimization - use if-else instead of switch,\n // to avoid deopts in old v8\n if (type === CODES$1) {\n base = extra = work; /* dummy value--not used */\n match = 20;\n\n } else if (type === LENS$1) {\n base = lbase;\n extra = lext;\n match = 257;\n\n } else { /* DISTS */\n base = dbase;\n extra = dext;\n match = 0;\n }\n\n /* initialize opts for loop */\n huff = 0; /* starting code */\n sym = 0; /* starting code symbol */\n len = min; /* starting code length */\n next = table_index; /* current table to fill in */\n curr = root; /* current table index bits */\n drop = 0; /* current bits to drop from code for index */\n low = -1; /* trigger new sub-table when len > root */\n used = 1 << root; /* use root table entries */\n mask = used - 1; /* mask for comparing low */\n\n /* check available table space */\n if ((type === LENS$1 && used > ENOUGH_LENS$1) ||\n (type === DISTS$1 && used > ENOUGH_DISTS$1)) {\n return 1;\n }\n\n /* process all codes and make table entries */\n for (;;) {\n /* create table entry */\n here_bits = len - drop;\n if (work[sym] + 1 < match) {\n here_op = 0;\n here_val = work[sym];\n }\n else if (work[sym] >= match) {\n here_op = extra[work[sym] - match];\n here_val = base[work[sym] - match];\n }\n else {\n here_op = 32 + 64; /* end of block */\n here_val = 0;\n }\n\n /* replicate for those indices with low len bits equal to huff */\n incr = 1 << (len - drop);\n fill = 1 << curr;\n min = fill; /* save offset to next table */\n do {\n fill -= incr;\n table[next + (huff >> drop) + fill] = (here_bits << 24) | (here_op << 16) | here_val |0;\n } while (fill !== 0);\n\n /* backwards increment the len-bit code huff */\n incr = 1 << (len - 1);\n while (huff & incr) {\n incr >>= 1;\n }\n if (incr !== 0) {\n huff &= incr - 1;\n huff += incr;\n } else {\n huff = 0;\n }\n\n /* go to next symbol, update count, len */\n sym++;\n if (--count[len] === 0) {\n if (len === max) { break; }\n len = lens[lens_index + work[sym]];\n }\n\n /* create new sub-table if needed */\n if (len > root && (huff & mask) !== low) {\n /* if first time, transition to sub-tables */\n if (drop === 0) {\n drop = root;\n }\n\n /* increment past last table */\n next += min; /* here min is 1 << curr */\n\n /* determine length of next table */\n curr = len - drop;\n left = 1 << curr;\n while (curr + drop < max) {\n left -= count[curr + drop];\n if (left <= 0) { break; }\n curr++;\n left <<= 1;\n }\n\n /* check for enough space */\n used += 1 << curr;\n if ((type === LENS$1 && used > ENOUGH_LENS$1) ||\n (type === DISTS$1 && used > ENOUGH_DISTS$1)) {\n return 1;\n }\n\n /* point entry in root table to sub-table */\n low = huff & mask;\n /*table.op[low] = curr;\n table.bits[low] = root;\n table.val[low] = next - opts.table_index;*/\n table[low] = (root << 24) | (curr << 16) | (next - table_index) |0;\n }\n }\n\n /* fill in remaining table entry if code is incomplete (guaranteed to have\n at most one remaining entry, since if the code is incomplete, the\n maximum code length that was allowed to get this far is one bit) */\n if (huff !== 0) {\n //table.op[next + huff] = 64; /* invalid code marker */\n //table.bits[next + huff] = len - drop;\n //table.val[next + huff] = 0;\n table[next + huff] = ((len - drop) << 24) | (64 << 16) |0;\n }\n\n /* set return parameters */\n //opts.table_index += used;\n opts.bits = root;\n return 0;\n};\n\n\nvar inftrees = inflate_table;\n\n// (C) 1995-2013 Jean-loup Gailly and Mark Adler\n// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin\n//\n// This software is provided 'as-is', without any express or implied\n// warranty. In no event will the authors be held liable for any damages\n// arising from the use of this software.\n//\n// Permission is granted to anyone to use this software for any purpose,\n// including commercial applications, and to alter it and redistribute it\n// freely, subject to the following restrictions:\n//\n// 1. The origin of this software must not be misrepresented; you must not\n// claim that you wrote the original software. If you use this software\n// in a product, an acknowledgment in the product documentation would be\n// appreciated but is not required.\n// 2. Altered source versions must be plainly marked as such, and must not be\n// misrepresented as being the original software.\n// 3. This notice may not be removed or altered from any source distribution.\n\n\n\n\n\n\nconst CODES = 0;\nconst LENS = 1;\nconst DISTS = 2;\n\n/* Public constants ==========================================================*/\n/* ===========================================================================*/\n\nconst {\n Z_FINISH: Z_FINISH$1, Z_BLOCK, Z_TREES,\n Z_OK: Z_OK$1, Z_STREAM_END: Z_STREAM_END$1, Z_NEED_DICT: Z_NEED_DICT$1, Z_STREAM_ERROR: Z_STREAM_ERROR$1, Z_DATA_ERROR: Z_DATA_ERROR$1, Z_MEM_ERROR: Z_MEM_ERROR$1, Z_BUF_ERROR,\n Z_DEFLATED\n} = constants$2;\n\n\n/* STATES ====================================================================*/\n/* ===========================================================================*/\n\n\nconst HEAD = 16180; /* i: waiting for magic header */\nconst FLAGS = 16181; /* i: waiting for method and flags (gzip) */\nconst TIME = 16182; /* i: waiting for modification time (gzip) */\nconst OS = 16183; /* i: waiting for extra flags and operating system (gzip) */\nconst EXLEN = 16184; /* i: waiting for extra length (gzip) */\nconst EXTRA = 16185; /* i: waiting for extra bytes (gzip) */\nconst NAME = 16186; /* i: waiting for end of file name (gzip) */\nconst COMMENT = 16187; /* i: waiting for end of comment (gzip) */\nconst HCRC = 16188; /* i: waiting for header crc (gzip) */\nconst DICTID = 16189; /* i: waiting for dictionary check value */\nconst DICT = 16190; /* waiting for inflateSetDictionary() call */\nconst TYPE = 16191; /* i: waiting for type bits, including last-flag bit */\nconst TYPEDO = 16192; /* i: same, but skip check to exit inflate on new block */\nconst STORED = 16193; /* i: waiting for stored size (length and complement) */\nconst COPY_ = 16194; /* i/o: same as COPY below, but only first time in */\nconst COPY = 16195; /* i/o: waiting for input or output to copy stored block */\nconst TABLE = 16196; /* i: waiting for dynamic block table lengths */\nconst LENLENS = 16197; /* i: waiting for code length code lengths */\nconst CODELENS = 16198; /* i: waiting for length/lit and distance code lengths */\nconst LEN_ = 16199; /* i: same as LEN below, but only first time in */\nconst LEN = 16200; /* i: waiting for length/lit/eob code */\nconst LENEXT = 16201; /* i: waiting for length extra bits */\nconst DIST = 16202; /* i: waiting for distance code */\nconst DISTEXT = 16203; /* i: waiting for distance extra bits */\nconst MATCH = 16204; /* o: waiting for output space to copy string */\nconst LIT = 16205; /* o: waiting for output space to write literal */\nconst CHECK = 16206; /* i: waiting for 32-bit check value */\nconst LENGTH = 16207; /* i: waiting for 32-bit length (gzip) */\nconst DONE = 16208; /* finished check, done -- remain here until reset */\nconst BAD = 16209; /* got a data error -- remain here until reset */\nconst MEM = 16210; /* got an inflate() memory error -- remain here until reset */\nconst SYNC = 16211; /* looking for synchronization bytes to restart inflate() */\n\n/* ===========================================================================*/\n\n\n\nconst ENOUGH_LENS = 852;\nconst ENOUGH_DISTS = 592;\n//const ENOUGH = (ENOUGH_LENS+ENOUGH_DISTS);\n\nconst MAX_WBITS = 15;\n/* 32K LZ77 window */\nconst DEF_WBITS = MAX_WBITS;\n\n\nconst zswap32 = (q) => {\n\n return (((q >>> 24) & 0xff) +\n ((q >>> 8) & 0xff00) +\n ((q & 0xff00) << 8) +\n ((q & 0xff) << 24));\n};\n\n\nfunction InflateState() {\n this.strm = null; /* pointer back to this zlib stream */\n this.mode = 0; /* current inflate mode */\n this.last = false; /* true if processing last block */\n this.wrap = 0; /* bit 0 true for zlib, bit 1 true for gzip,\n bit 2 true to validate check value */\n this.havedict = false; /* true if dictionary provided */\n this.flags = 0; /* gzip header method and flags (0 if zlib), or\n -1 if raw or no header yet */\n this.dmax = 0; /* zlib header max distance (INFLATE_STRICT) */\n this.check = 0; /* protected copy of check value */\n this.total = 0; /* protected copy of output count */\n // TODO: may be {}\n this.head = null; /* where to save gzip header information */\n\n /* sliding window */\n this.wbits = 0; /* log base 2 of requested window size */\n this.wsize = 0; /* window size or zero if not using window */\n this.whave = 0; /* valid bytes in the window */\n this.wnext = 0; /* window write index */\n this.window = null; /* allocated sliding window, if needed */\n\n /* bit accumulator */\n this.hold = 0; /* input bit accumulator */\n this.bits = 0; /* number of bits in \"in\" */\n\n /* for string and stored block copying */\n this.length = 0; /* literal or length of data to copy */\n this.offset = 0; /* distance back to copy string from */\n\n /* for table and code decoding */\n this.extra = 0; /* extra bits needed */\n\n /* fixed and dynamic code tables */\n this.lencode = null; /* starting table for length/literal codes */\n this.distcode = null; /* starting table for distance codes */\n this.lenbits = 0; /* index bits for lencode */\n this.distbits = 0; /* index bits for distcode */\n\n /* dynamic table building */\n this.ncode = 0; /* number of code length code lengths */\n this.nlen = 0; /* number of length code lengths */\n this.ndist = 0; /* number of distance code lengths */\n this.have = 0; /* number of code lengths in lens[] */\n this.next = null; /* next available space in codes[] */\n\n this.lens = new Uint16Array(320); /* temporary storage for code lengths */\n this.work = new Uint16Array(288); /* work area for code table building */\n\n /*\n because we don't have pointers in js, we use lencode and distcode directly\n as buffers so we don't need codes\n */\n //this.codes = new Int32Array(ENOUGH); /* space for code tables */\n this.lendyn = null; /* dynamic table for length/literal codes (JS specific) */\n this.distdyn = null; /* dynamic table for distance codes (JS specific) */\n this.sane = 0; /* if false, allow invalid distance too far */\n this.back = 0; /* bits back of last unprocessed length/lit */\n this.was = 0; /* initial length of match */\n}\n\n\nconst inflateStateCheck = (strm) => {\n\n if (!strm) {\n return 1;\n }\n const state = strm.state;\n if (!state || state.strm !== strm ||\n state.mode < HEAD || state.mode > SYNC) {\n return 1;\n }\n return 0;\n};\n\n\nconst inflateResetKeep = (strm) => {\n\n if (inflateStateCheck(strm)) { return Z_STREAM_ERROR$1; }\n const state = strm.state;\n strm.total_in = strm.total_out = state.total = 0;\n strm.msg = ''; /*Z_NULL*/\n if (state.wrap) { /* to support ill-conceived Java test suite */\n strm.adler = state.wrap & 1;\n }\n state.mode = HEAD;\n state.last = 0;\n state.havedict = 0;\n state.flags = -1;\n state.dmax = 32768;\n state.head = null/*Z_NULL*/;\n state.hold = 0;\n state.bits = 0;\n //state.lencode = state.distcode = state.next = state.codes;\n state.lencode = state.lendyn = new Int32Array(ENOUGH_LENS);\n state.distcode = state.distdyn = new Int32Array(ENOUGH_DISTS);\n\n state.sane = 1;\n state.back = -1;\n //Tracev((stderr, \"inflate: reset\\n\"));\n return Z_OK$1;\n};\n\n\nconst inflateReset = (strm) => {\n\n if (inflateStateCheck(strm)) { return Z_STREAM_ERROR$1; }\n const state = strm.state;\n state.wsize = 0;\n state.whave = 0;\n state.wnext = 0;\n return inflateResetKeep(strm);\n\n};\n\n\nconst inflateReset2 = (strm, windowBits) => {\n let wrap;\n\n /* get the state */\n if (inflateStateCheck(strm)) { return Z_STREAM_ERROR$1; }\n const state = strm.state;\n\n /* extract wrap request from windowBits parameter */\n if (windowBits < 0) {\n wrap = 0;\n windowBits = -windowBits;\n }\n else {\n wrap = (windowBits >> 4) + 5;\n if (windowBits < 48) {\n windowBits &= 15;\n }\n }\n\n /* set number of window bits, free window if different */\n if (windowBits && (windowBits < 8 || windowBits > 15)) {\n return Z_STREAM_ERROR$1;\n }\n if (state.window !== null && state.wbits !== windowBits) {\n state.window = null;\n }\n\n /* update state and reset the rest of it */\n state.wrap = wrap;\n state.wbits = windowBits;\n return inflateReset(strm);\n};\n\n\nconst inflateInit2 = (strm, windowBits) => {\n\n if (!strm) { return Z_STREAM_ERROR$1; }\n //strm.msg = Z_NULL; /* in case we return an error */\n\n const state = new InflateState();\n\n //if (state === Z_NULL) return Z_MEM_ERROR;\n //Tracev((stderr, \"inflate: allocated\\n\"));\n strm.state = state;\n state.strm = strm;\n state.window = null/*Z_NULL*/;\n state.mode = HEAD; /* to pass state test in inflateReset2() */\n const ret = inflateReset2(strm, windowBits);\n if (ret !== Z_OK$1) {\n strm.state = null/*Z_NULL*/;\n }\n return ret;\n};\n\n\nconst inflateInit = (strm) => {\n\n return inflateInit2(strm, DEF_WBITS);\n};\n\n\n/*\n Return state with length and distance decoding tables and index sizes set to\n fixed code decoding. Normally this returns fixed tables from inffixed.h.\n If BUILDFIXED is defined, then instead this routine builds the tables the\n first time it's called, and returns those tables the first time and\n thereafter. This reduces the size of the code by about 2K bytes, in\n exchange for a little execution time. However, BUILDFIXED should not be\n used for threaded applications, since the rewriting of the tables and virgin\n may not be thread-safe.\n */\nlet virgin = true;\n\nlet lenfix, distfix; // We have no pointers in JS, so keep tables separate\n\n\nconst fixedtables = (state) => {\n\n /* build fixed huffman tables if first call (may not be thread safe) */\n if (virgin) {\n lenfix = new Int32Array(512);\n distfix = new Int32Array(32);\n\n /* literal/length table */\n let sym = 0;\n while (sym < 144) { state.lens[sym++] = 8; }\n while (sym < 256) { state.lens[sym++] = 9; }\n while (sym < 280) { state.lens[sym++] = 7; }\n while (sym < 288) { state.lens[sym++] = 8; }\n\n inftrees(LENS, state.lens, 0, 288, lenfix, 0, state.work, { bits: 9 });\n\n /* distance table */\n sym = 0;\n while (sym < 32) { state.lens[sym++] = 5; }\n\n inftrees(DISTS, state.lens, 0, 32, distfix, 0, state.work, { bits: 5 });\n\n /* do this just once */\n virgin = false;\n }\n\n state.lencode = lenfix;\n state.lenbits = 9;\n state.distcode = distfix;\n state.distbits = 5;\n};\n\n\n/*\n Update the window with the last wsize (normally 32K) bytes written before\n returning. If window does not exist yet, create it. This is only called\n when a window is already in use, or when output has been written during this\n inflate call, but the end of the deflate stream has not been reached yet.\n It is also called to create a window for dictionary data when a dictionary\n is loaded.\n\n Providing output buffers larger than 32K to inflate() should provide a speed\n advantage, since only the last 32K of output is copied to the sliding window\n upon return from inflate(), and since all distances after the first 32K of\n output will fall in the output data, making match copies simpler and faster.\n The advantage may be dependent on the size of the processor's data caches.\n */\nconst updatewindow = (strm, src, end, copy) => {\n\n let dist;\n const state = strm.state;\n\n /* if it hasn't been done already, allocate space for the window */\n if (state.window === null) {\n state.wsize = 1 << state.wbits;\n state.wnext = 0;\n state.whave = 0;\n\n state.window = new Uint8Array(state.wsize);\n }\n\n /* copy state->wsize or less output bytes into the circular window */\n if (copy >= state.wsize) {\n state.window.set(src.subarray(end - state.wsize, end), 0);\n state.wnext = 0;\n state.whave = state.wsize;\n }\n else {\n dist = state.wsize - state.wnext;\n if (dist > copy) {\n dist = copy;\n }\n //zmemcpy(state->window + state->wnext, end - copy, dist);\n state.window.set(src.subarray(end - copy, end - copy + dist), state.wnext);\n copy -= dist;\n if (copy) {\n //zmemcpy(state->window, end - copy, copy);\n state.window.set(src.subarray(end - copy, end), 0);\n state.wnext = copy;\n state.whave = state.wsize;\n }\n else {\n state.wnext += dist;\n if (state.wnext === state.wsize) { state.wnext = 0; }\n if (state.whave < state.wsize) { state.whave += dist; }\n }\n }\n return 0;\n};\n\n\nconst inflate$2 = (strm, flush) => {\n\n let state;\n let input, output; // input/output buffers\n let next; /* next input INDEX */\n let put; /* next output INDEX */\n let have, left; /* available input and output */\n let hold; /* bit buffer */\n let bits; /* bits in bit buffer */\n let _in, _out; /* save starting available input and output */\n let copy; /* number of stored or match bytes to copy */\n let from; /* where to copy match bytes from */\n let from_source;\n let here = 0; /* current decoding table entry */\n let here_bits, here_op, here_val; // paked \"here\" denormalized (JS specific)\n //let last; /* parent table entry */\n let last_bits, last_op, last_val; // paked \"last\" denormalized (JS specific)\n let len; /* length to copy for repeats, bits to drop */\n let ret; /* return code */\n const hbuf = new Uint8Array(4); /* buffer for gzip header crc calculation */\n let opts;\n\n let n; // temporary variable for NEED_BITS\n\n const order = /* permutation of code lengths */\n new Uint8Array([ 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 ]);\n\n\n if (inflateStateCheck(strm) || !strm.output ||\n (!strm.input && strm.avail_in !== 0)) {\n return Z_STREAM_ERROR$1;\n }\n\n state = strm.state;\n if (state.mode === TYPE) { state.mode = TYPEDO; } /* skip check */\n\n\n //--- LOAD() ---\n put = strm.next_out;\n output = strm.output;\n left = strm.avail_out;\n next = strm.next_in;\n input = strm.input;\n have = strm.avail_in;\n hold = state.hold;\n bits = state.bits;\n //---\n\n _in = have;\n _out = left;\n ret = Z_OK$1;\n\n inf_leave: // goto emulation\n for (;;) {\n switch (state.mode) {\n case HEAD:\n if (state.wrap === 0) {\n state.mode = TYPEDO;\n break;\n }\n //=== NEEDBITS(16);\n while (bits < 16) {\n if (have === 0) { break inf_leave; }\n have--;\n hold += input[next++] << bits;\n bits += 8;\n }\n //===//\n if ((state.wrap & 2) && hold === 0x8b1f) { /* gzip header */\n if (state.wbits === 0) {\n state.wbits = 15;\n }\n state.check = 0/*crc32(0L, Z_NULL, 0)*/;\n //=== CRC2(state.check, hold);\n hbuf[0] = hold & 0xff;\n hbuf[1] = (hold >>> 8) & 0xff;\n state.check = crc32_1(state.check, hbuf, 2, 0);\n //===//\n\n //=== INITBITS();\n hold = 0;\n bits = 0;\n //===//\n state.mode = FLAGS;\n break;\n }\n if (state.head) {\n state.head.done = false;\n }\n if (!(state.wrap & 1) || /* check if zlib header allowed */\n (((hold & 0xff)/*BITS(8)*/ << 8) + (hold >> 8)) % 31) {\n strm.msg = 'incorrect header check';\n state.mode = BAD;\n break;\n }\n if ((hold & 0x0f)/*BITS(4)*/ !== Z_DEFLATED) {\n strm.msg = 'unknown compression method';\n state.mode = BAD;\n break;\n }\n //--- DROPBITS(4) ---//\n hold >>>= 4;\n bits -= 4;\n //---//\n len = (hold & 0x0f)/*BITS(4)*/ + 8;\n if (state.wbits === 0) {\n state.wbits = len;\n }\n if (len > 15 || len > state.wbits) {\n strm.msg = 'invalid window size';\n state.mode = BAD;\n break;\n }\n\n // !!! pako patch. Force use `options.windowBits` if passed.\n // Required to always use max window size by default.\n state.dmax = 1 << state.wbits;\n //state.dmax = 1 << len;\n\n state.flags = 0; /* indicate zlib header */\n //Tracev((stderr, \"inflate: zlib header ok\\n\"));\n strm.adler = state.check = 1/*adler32(0L, Z_NULL, 0)*/;\n state.mode = hold & 0x200 ? DICTID : TYPE;\n //=== INITBITS();\n hold = 0;\n bits = 0;\n //===//\n break;\n case FLAGS:\n //=== NEEDBITS(16); */\n while (bits < 16) {\n if (have === 0) { break inf_leave; }\n have--;\n hold += input[next++] << bits;\n bits += 8;\n }\n //===//\n state.flags = hold;\n if ((state.flags & 0xff) !== Z_DEFLATED) {\n strm.msg = 'unknown compression method';\n state.mode = BAD;\n break;\n }\n if (state.flags & 0xe000) {\n strm.msg = 'unknown header flags set';\n state.mode = BAD;\n break;\n }\n if (state.head) {\n state.head.text = ((hold >> 8) & 1);\n }\n if ((state.flags & 0x0200) && (state.wrap & 4)) {\n //=== CRC2(state.check, hold);\n hbuf[0] = hold & 0xff;\n hbuf[1] = (hold >>> 8) & 0xff;\n state.check = crc32_1(state.check, hbuf, 2, 0);\n //===//\n }\n //=== INITBITS();\n hold = 0;\n bits = 0;\n //===//\n state.mode = TIME;\n /* falls through */\n case TIME:\n //=== NEEDBITS(32); */\n while (bits < 32) {\n if (have === 0) { break inf_leave; }\n have--;\n hold += input[next++] << bits;\n bits += 8;\n }\n //===//\n if (state.head) {\n state.head.time = hold;\n }\n if ((state.flags & 0x0200) && (state.wrap & 4)) {\n //=== CRC4(state.check, hold)\n hbuf[0] = hold & 0xff;\n hbuf[1] = (hold >>> 8) & 0xff;\n hbuf[2] = (hold >>> 16) & 0xff;\n hbuf[3] = (hold >>> 24) & 0xff;\n state.check = crc32_1(state.check, hbuf, 4, 0);\n //===\n }\n //=== INITBITS();\n hold = 0;\n bits = 0;\n //===//\n state.mode = OS;\n /* falls through */\n case OS:\n //=== NEEDBITS(16); */\n while (bits < 16) {\n if (have === 0) { break inf_leave; }\n have--;\n hold += input[next++] << bits;\n bits += 8;\n }\n //===//\n if (state.head) {\n state.head.xflags = (hold & 0xff);\n state.head.os = (hold >> 8);\n }\n if ((state.flags & 0x0200) && (state.wrap & 4)) {\n //=== CRC2(state.check, hold);\n hbuf[0] = hold & 0xff;\n hbuf[1] = (hold >>> 8) & 0xff;\n state.check = crc32_1(state.check, hbuf, 2, 0);\n //===//\n }\n //=== INITBITS();\n hold = 0;\n bits = 0;\n //===//\n state.mode = EXLEN;\n /* falls through */\n case EXLEN:\n if (state.flags & 0x0400) {\n //=== NEEDBITS(16); */\n while (bits < 16) {\n if (have === 0) { break inf_leave; }\n have--;\n hold += input[next++] << bits;\n bits += 8;\n }\n //===//\n state.length = hold;\n if (state.head) {\n state.head.extra_len = hold;\n }\n if ((state.flags & 0x0200) && (state.wrap & 4)) {\n //=== CRC2(state.check, hold);\n hbuf[0] = hold & 0xff;\n hbuf[1] = (hold >>> 8) & 0xff;\n state.check = crc32_1(state.check, hbuf, 2, 0);\n //===//\n }\n //=== INITBITS();\n hold = 0;\n bits = 0;\n //===//\n }\n else if (state.head) {\n state.head.extra = null/*Z_NULL*/;\n }\n state.mode = EXTRA;\n /* falls through */\n case EXTRA:\n if (state.flags & 0x0400) {\n copy = state.length;\n if (copy > have) { copy = have; }\n if (copy) {\n if (state.head) {\n len = state.head.extra_len - state.length;\n if (!state.head.extra) {\n // Use untyped array for more convenient processing later\n state.head.extra = new Uint8Array(state.head.extra_len);\n }\n state.head.extra.set(\n input.subarray(\n next,\n // extra field is limited to 65536 bytes\n // - no need for additional size check\n next + copy\n ),\n /*len + copy > state.head.extra_max - len ? state.head.extra_max : copy,*/\n len\n );\n //zmemcpy(state.head.extra + len, next,\n // len + copy > state.head.extra_max ?\n // state.head.extra_max - len : copy);\n }\n if ((state.flags & 0x0200) && (state.wrap & 4)) {\n state.check = crc32_1(state.check, input, copy, next);\n }\n have -= copy;\n next += copy;\n state.length -= copy;\n }\n if (state.length) { break inf_leave; }\n }\n state.length = 0;\n state.mode = NAME;\n /* falls through */\n case NAME:\n if (state.flags & 0x0800) {\n if (have === 0) { break inf_leave; }\n copy = 0;\n do {\n // TODO: 2 or 1 bytes?\n len = input[next + copy++];\n /* use constant limit because in js we should not preallocate memory */\n if (state.head && len &&\n (state.length < 65536 /*state.head.name_max*/)) {\n state.head.name += String.fromCharCode(len);\n }\n } while (len && copy < have);\n\n if ((state.flags & 0x0200) && (state.wrap & 4)) {\n state.check = crc32_1(state.check, input, copy, next);\n }\n have -= copy;\n next += copy;\n if (len) { break inf_leave; }\n }\n else if (state.head) {\n state.head.name = null;\n }\n state.length = 0;\n state.mode = COMMENT;\n /* falls through */\n case COMMENT:\n if (state.flags & 0x1000) {\n if (have === 0) { break inf_leave; }\n copy = 0;\n do {\n len = input[next + copy++];\n /* use constant limit because in js we should not preallocate memory */\n if (state.head && len &&\n (state.length < 65536 /*state.head.comm_max*/)) {\n state.head.comment += String.fromCharCode(len);\n }\n } while (len && copy < have);\n if ((state.flags & 0x0200) && (state.wrap & 4)) {\n state.check = crc32_1(state.check, input, copy, next);\n }\n have -= copy;\n next += copy;\n if (len) { break inf_leave; }\n }\n else if (state.head) {\n state.head.comment = null;\n }\n state.mode = HCRC;\n /* falls through */\n case HCRC:\n if (state.flags & 0x0200) {\n //=== NEEDBITS(16); */\n while (bits < 16) {\n if (have === 0) { break inf_leave; }\n have--;\n hold += input[next++] << bits;\n bits += 8;\n }\n //===//\n if ((state.wrap & 4) && hold !== (state.check & 0xffff)) {\n strm.msg = 'header crc mismatch';\n state.mode = BAD;\n break;\n }\n //=== INITBITS();\n hold = 0;\n bits = 0;\n //===//\n }\n if (state.head) {\n state.head.hcrc = ((state.flags >> 9) & 1);\n state.head.done = true;\n }\n strm.adler = state.check = 0;\n state.mode = TYPE;\n break;\n case DICTID:\n //=== NEEDBITS(32); */\n while (bits < 32) {\n if (have === 0) { break inf_leave; }\n have--;\n hold += input[next++] << bits;\n bits += 8;\n }\n //===//\n strm.adler = state.check = zswap32(hold);\n //=== INITBITS();\n hold = 0;\n bits = 0;\n //===//\n state.mode = DICT;\n /* falls through */\n case DICT:\n if (state.havedict === 0) {\n //--- RESTORE() ---\n strm.next_out = put;\n strm.avail_out = left;\n strm.next_in = next;\n strm.avail_in = have;\n state.hold = hold;\n state.bits = bits;\n //---\n return Z_NEED_DICT$1;\n }\n strm.adler = state.check = 1/*adler32(0L, Z_NULL, 0)*/;\n state.mode = TYPE;\n /* falls through */\n case TYPE:\n if (flush === Z_BLOCK || flush === Z_TREES) { break inf_leave; }\n /* falls through */\n case TYPEDO:\n if (state.last) {\n //--- BYTEBITS() ---//\n hold >>>= bits & 7;\n bits -= bits & 7;\n //---//\n state.mode = CHECK;\n break;\n }\n //=== NEEDBITS(3); */\n while (bits < 3) {\n if (have === 0) { break inf_leave; }\n have--;\n hold += input[next++] << bits;\n bits += 8;\n }\n //===//\n state.last = (hold & 0x01)/*BITS(1)*/;\n //--- DROPBITS(1) ---//\n hold >>>= 1;\n bits -= 1;\n //---//\n\n switch ((hold & 0x03)/*BITS(2)*/) {\n case 0: /* stored block */\n //Tracev((stderr, \"inflate: stored block%s\\n\",\n // state.last ? \" (last)\" : \"\"));\n state.mode = STORED;\n break;\n case 1: /* fixed block */\n fixedtables(state);\n //Tracev((stderr, \"inflate: fixed codes block%s\\n\",\n // state.last ? \" (last)\" : \"\"));\n state.mode = LEN_; /* decode codes */\n if (flush === Z_TREES) {\n //--- DROPBITS(2) ---//\n hold >>>= 2;\n bits -= 2;\n //---//\n break inf_leave;\n }\n break;\n case 2: /* dynamic block */\n //Tracev((stderr, \"inflate: dynamic codes block%s\\n\",\n // state.last ? \" (last)\" : \"\"));\n state.mode = TABLE;\n break;\n case 3:\n strm.msg = 'invalid block type';\n state.mode = BAD;\n }\n //--- DROPBITS(2) ---//\n hold >>>= 2;\n bits -= 2;\n //---//\n break;\n case STORED:\n //--- BYTEBITS() ---// /* go to byte boundary */\n hold >>>= bits & 7;\n bits -= bits & 7;\n //---//\n //=== NEEDBITS(32); */\n while (bits < 32) {\n if (have === 0) { break inf_leave; }\n have--;\n hold += input[next++] << bits;\n bits += 8;\n }\n //===//\n if ((hold & 0xffff) !== ((hold >>> 16) ^ 0xffff)) {\n strm.msg = 'invalid stored block lengths';\n state.mode = BAD;\n break;\n }\n state.length = hold & 0xffff;\n //Tracev((stderr, \"inflate: stored length %u\\n\",\n // state.length));\n //=== INITBITS();\n hold = 0;\n bits = 0;\n //===//\n state.mode = COPY_;\n if (flush === Z_TREES) { break inf_leave; }\n /* falls through */\n case COPY_:\n state.mode = COPY;\n /* falls through */\n case COPY:\n copy = state.length;\n if (copy) {\n if (copy > have) { copy = have; }\n if (copy > left) { copy = left; }\n if (copy === 0) { break inf_leave; }\n //--- zmemcpy(put, next, copy); ---\n output.set(input.subarray(next, next + copy), put);\n //---//\n have -= copy;\n next += copy;\n left -= copy;\n put += copy;\n state.length -= copy;\n break;\n }\n //Tracev((stderr, \"inflate: stored end\\n\"));\n state.mode = TYPE;\n break;\n case TABLE:\n //=== NEEDBITS(14); */\n while (bits < 14) {\n if (have === 0) { break inf_leave; }\n have--;\n hold += input[next++] << bits;\n bits += 8;\n }\n //===//\n state.nlen = (hold & 0x1f)/*BITS(5)*/ + 257;\n //--- DROPBITS(5) ---//\n hold >>>= 5;\n bits -= 5;\n //---//\n state.ndist = (hold & 0x1f)/*BITS(5)*/ + 1;\n //--- DROPBITS(5) ---//\n hold >>>= 5;\n bits -= 5;\n //---//\n state.ncode = (hold & 0x0f)/*BITS(4)*/ + 4;\n //--- DROPBITS(4) ---//\n hold >>>= 4;\n bits -= 4;\n //---//\n//#ifndef PKZIP_BUG_WORKAROUND\n if (state.nlen > 286 || state.ndist > 30) {\n strm.msg = 'too many length or distance symbols';\n state.mode = BAD;\n break;\n }\n//#endif\n //Tracev((stderr, \"inflate: table sizes ok\\n\"));\n state.have = 0;\n state.mode = LENLENS;\n /* falls through */\n case LENLENS:\n while (state.have < state.ncode) {\n //=== NEEDBITS(3);\n while (bits < 3) {\n if (have === 0) { break inf_leave; }\n have--;\n hold += input[next++] << bits;\n bits += 8;\n }\n //===//\n state.lens[order[state.have++]] = (hold & 0x07);//BITS(3);\n //--- DROPBITS(3) ---//\n hold >>>= 3;\n bits -= 3;\n //---//\n }\n while (state.have < 19) {\n state.lens[order[state.have++]] = 0;\n }\n // We have separate tables & no pointers. 2 commented lines below not needed.\n //state.next = state.codes;\n //state.lencode = state.next;\n // Switch to use dynamic table\n state.lencode = state.lendyn;\n state.lenbits = 7;\n\n opts = { bits: state.lenbits };\n ret = inftrees(CODES, state.lens, 0, 19, state.lencode, 0, state.work, opts);\n state.lenbits = opts.bits;\n\n if (ret) {\n strm.msg = 'invalid code lengths set';\n state.mode = BAD;\n break;\n }\n //Tracev((stderr, \"inflate: code lengths ok\\n\"));\n state.have = 0;\n state.mode = CODELENS;\n /* falls through */\n case CODELENS:\n while (state.have < state.nlen + state.ndist) {\n for (;;) {\n here = state.lencode[hold & ((1 << state.lenbits) - 1)];/*BITS(state.lenbits)*/\n here_bits = here >>> 24;\n here_op = (here >>> 16) & 0xff;\n here_val = here & 0xffff;\n\n if ((here_bits) <= bits) { break; }\n //--- PULLBYTE() ---//\n if (have === 0) { break inf_leave; }\n have--;\n hold += input[next++] << bits;\n bits += 8;\n //---//\n }\n if (here_val < 16) {\n //--- DROPBITS(here.bits) ---//\n hold >>>= here_bits;\n bits -= here_bits;\n //---//\n state.lens[state.have++] = here_val;\n }\n else {\n if (here_val === 16) {\n //=== NEEDBITS(here.bits + 2);\n n = here_bits + 2;\n while (bits < n) {\n if (have === 0) { break inf_leave; }\n have--;\n hold += input[next++] << bits;\n bits += 8;\n }\n //===//\n //--- DROPBITS(here.bits) ---//\n hold >>>= here_bits;\n bits -= here_bits;\n //---//\n if (state.have === 0) {\n strm.msg = 'invalid bit length repeat';\n state.mode = BAD;\n break;\n }\n len = state.lens[state.have - 1];\n copy = 3 + (hold & 0x03);//BITS(2);\n //--- DROPBITS(2) ---//\n hold >>>= 2;\n bits -= 2;\n //---//\n }\n else if (here_val === 17) {\n //=== NEEDBITS(here.bits + 3);\n n = here_bits + 3;\n while (bits < n) {\n if (have === 0) { break inf_leave; }\n have--;\n hold += input[next++] << bits;\n bits += 8;\n }\n //===//\n //--- DROPBITS(here.bits) ---//\n hold >>>= here_bits;\n bits -= here_bits;\n //---//\n len = 0;\n copy = 3 + (hold & 0x07);//BITS(3);\n //--- DROPBITS(3) ---//\n hold >>>= 3;\n bits -= 3;\n //---//\n }\n else {\n //=== NEEDBITS(here.bits + 7);\n n = here_bits + 7;\n while (bits < n) {\n if (have === 0) { break inf_leave; }\n have--;\n hold += input[next++] << bits;\n bits += 8;\n }\n //===//\n //--- DROPBITS(here.bits) ---//\n hold >>>= here_bits;\n bits -= here_bits;\n //---//\n len = 0;\n copy = 11 + (hold & 0x7f);//BITS(7);\n //--- DROPBITS(7) ---//\n hold >>>= 7;\n bits -= 7;\n //---//\n }\n if (state.have + copy > state.nlen + state.ndist) {\n strm.msg = 'invalid bit length repeat';\n state.mode = BAD;\n break;\n }\n while (copy--) {\n state.lens[state.have++] = len;\n }\n }\n }\n\n /* handle error breaks in while */\n if (state.mode === BAD) { break; }\n\n /* check for end-of-block code (better have one) */\n if (state.lens[256] === 0) {\n strm.msg = 'invalid code -- missing end-of-block';\n state.mode = BAD;\n break;\n }\n\n /* build code tables -- note: do not change the lenbits or distbits\n values here (9 and 6) without reading the comments in inftrees.h\n concerning the ENOUGH constants, which depend on those values */\n state.lenbits = 9;\n\n opts = { bits: state.lenbits };\n ret = inftrees(LENS, state.lens, 0, state.nlen, state.lencode, 0, state.work, opts);\n // We have separate tables & no pointers. 2 commented lines below not needed.\n // state.next_index = opts.table_index;\n state.lenbits = opts.bits;\n // state.lencode = state.next;\n\n if (ret) {\n strm.msg = 'invalid literal/lengths set';\n state.mode = BAD;\n break;\n }\n\n state.distbits = 6;\n //state.distcode.copy(state.codes);\n // Switch to use dynamic table\n state.distcode = state.distdyn;\n opts = { bits: state.distbits };\n ret = inftrees(DISTS, state.lens, state.nlen, state.ndist, state.distcode, 0, state.work, opts);\n // We have separate tables & no pointers. 2 commented lines below not needed.\n // state.next_index = opts.table_index;\n state.distbits = opts.bits;\n // state.distcode = state.next;\n\n if (ret) {\n strm.msg = 'invalid distances set';\n state.mode = BAD;\n break;\n }\n //Tracev((stderr, 'inflate: codes ok\\n'));\n state.mode = LEN_;\n if (flush === Z_TREES) { break inf_leave; }\n /* falls through */\n case LEN_:\n state.mode = LEN;\n /* falls through */\n case LEN:\n if (have >= 6 && left >= 258) {\n //--- RESTORE() ---\n strm.next_out = put;\n strm.avail_out = left;\n strm.next_in = next;\n strm.avail_in = have;\n state.hold = hold;\n state.bits = bits;\n //---\n inffast(strm, _out);\n //--- LOAD() ---\n put = strm.next_out;\n output = strm.output;\n left = strm.avail_out;\n next = strm.next_in;\n input = strm.input;\n have = strm.avail_in;\n hold = state.hold;\n bits = state.bits;\n //---\n\n if (state.mode === TYPE) {\n state.back = -1;\n }\n break;\n }\n state.back = 0;\n for (;;) {\n here = state.lencode[hold & ((1 << state.lenbits) - 1)]; /*BITS(state.lenbits)*/\n here_bits = here >>> 24;\n here_op = (here >>> 16) & 0xff;\n here_val = here & 0xffff;\n\n if (here_bits <= bits) { break; }\n //--- PULLBYTE() ---//\n if (have === 0) { break inf_leave; }\n have--;\n hold += input[next++] << bits;\n bits += 8;\n //---//\n }\n if (here_op && (here_op & 0xf0) === 0) {\n last_bits = here_bits;\n last_op = here_op;\n last_val = here_val;\n for (;;) {\n here = state.lencode[last_val +\n ((hold & ((1 << (last_bits + last_op)) - 1))/*BITS(last.bits + last.op)*/ >> last_bits)];\n here_bits = here >>> 24;\n here_op = (here >>> 16) & 0xff;\n here_val = here & 0xffff;\n\n if ((last_bits + here_bits) <= bits) { break; }\n //--- PULLBYTE() ---//\n if (have === 0) { break inf_leave; }\n have--;\n hold += input[next++] << bits;\n bits += 8;\n //---//\n }\n //--- DROPBITS(last.bits) ---//\n hold >>>= last_bits;\n bits -= last_bits;\n //---//\n state.back += last_bits;\n }\n //--- DROPBITS(here.bits) ---//\n hold >>>= here_bits;\n bits -= here_bits;\n //---//\n state.back += here_bits;\n state.length = here_val;\n if (here_op === 0) {\n //Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?\n // \"inflate: literal '%c'\\n\" :\n // \"inflate: literal 0x%02x\\n\", here.val));\n state.mode = LIT;\n break;\n }\n if (here_op & 32) {\n //Tracevv((stderr, \"inflate: end of block\\n\"));\n state.back = -1;\n state.mode = TYPE;\n break;\n }\n if (here_op & 64) {\n strm.msg = 'invalid literal/length code';\n state.mode = BAD;\n break;\n }\n state.extra = here_op & 15;\n state.mode = LENEXT;\n /* falls through */\n case LENEXT:\n if (state.extra) {\n //=== NEEDBITS(state.extra);\n n = state.extra;\n while (bits < n) {\n if (have === 0) { break inf_leave; }\n have--;\n hold += input[next++] << bits;\n bits += 8;\n }\n //===//\n state.length += hold & ((1 << state.extra) - 1)/*BITS(state.extra)*/;\n //--- DROPBITS(state.extra) ---//\n hold >>>= state.extra;\n bits -= state.extra;\n //---//\n state.back += state.extra;\n }\n //Tracevv((stderr, \"inflate: length %u\\n\", state.length));\n state.was = state.length;\n state.mode = DIST;\n /* falls through */\n case DIST:\n for (;;) {\n here = state.distcode[hold & ((1 << state.distbits) - 1)];/*BITS(state.distbits)*/\n here_bits = here >>> 24;\n here_op = (here >>> 16) & 0xff;\n here_val = here & 0xffff;\n\n if ((here_bits) <= bits) { break; }\n //--- PULLBYTE() ---//\n if (have === 0) { break inf_leave; }\n have--;\n hold += input[next++] << bits;\n bits += 8;\n //---//\n }\n if ((here_op & 0xf0) === 0) {\n last_bits = here_bits;\n last_op = here_op;\n last_val = here_val;\n for (;;) {\n here = state.distcode[last_val +\n ((hold & ((1 << (last_bits + last_op)) - 1))/*BITS(last.bits + last.op)*/ >> last_bits)];\n here_bits = here >>> 24;\n here_op = (here >>> 16) & 0xff;\n here_val = here & 0xffff;\n\n if ((last_bits + here_bits) <= bits) { break; }\n //--- PULLBYTE() ---//\n if (have === 0) { break inf_leave; }\n have--;\n hold += input[next++] << bits;\n bits += 8;\n //---//\n }\n //--- DROPBITS(last.bits) ---//\n hold >>>= last_bits;\n bits -= last_bits;\n //---//\n state.back += last_bits;\n }\n //--- DROPBITS(here.bits) ---//\n hold >>>= here_bits;\n bits -= here_bits;\n //---//\n state.back += here_bits;\n if (here_op & 64) {\n strm.msg = 'invalid distance code';\n state.mode = BAD;\n break;\n }\n state.offset = here_val;\n state.extra = (here_op) & 15;\n state.mode = DISTEXT;\n /* falls through */\n case DISTEXT:\n if (state.extra) {\n //=== NEEDBITS(state.extra);\n n = state.extra;\n while (bits < n) {\n if (have === 0) { break inf_leave; }\n have--;\n hold += input[next++] << bits;\n bits += 8;\n }\n //===//\n state.offset += hold & ((1 << state.extra) - 1)/*BITS(state.extra)*/;\n //--- DROPBITS(state.extra) ---//\n hold >>>= state.extra;\n bits -= state.extra;\n //---//\n state.back += state.extra;\n }\n//#ifdef INFLATE_STRICT\n if (state.offset > state.dmax) {\n strm.msg = 'invalid distance too far back';\n state.mode = BAD;\n break;\n }\n//#endif\n //Tracevv((stderr, \"inflate: distance %u\\n\", state.offset));\n state.mode = MATCH;\n /* falls through */\n case MATCH:\n if (left === 0) { break inf_leave; }\n copy = _out - left;\n if (state.offset > copy) { /* copy from window */\n copy = state.offset - copy;\n if (copy > state.whave) {\n if (state.sane) {\n strm.msg = 'invalid distance too far back';\n state.mode = BAD;\n break;\n }\n// (!) This block is disabled in zlib defaults,\n// don't enable it for binary compatibility\n//#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR\n// Trace((stderr, \"inflate.c too far\\n\"));\n// copy -= state.whave;\n// if (copy > state.length) { copy = state.length; }\n// if (copy > left) { copy = left; }\n// left -= copy;\n// state.length -= copy;\n// do {\n// output[put++] = 0;\n// } while (--copy);\n// if (state.length === 0) { state.mode = LEN; }\n// break;\n//#endif\n }\n if (copy > state.wnext) {\n copy -= state.wnext;\n from = state.wsize - copy;\n }\n else {\n from = state.wnext - copy;\n }\n if (copy > state.length) { copy = state.length; }\n from_source = state.window;\n }\n else { /* copy from output */\n from_source = output;\n from = put - state.offset;\n copy = state.length;\n }\n if (copy > left) { copy = left; }\n left -= copy;\n state.length -= copy;\n do {\n output[put++] = from_source[from++];\n } while (--copy);\n if (state.length === 0) { state.mode = LEN; }\n break;\n case LIT:\n if (left === 0) { break inf_leave; }\n output[put++] = state.length;\n left--;\n state.mode = LEN;\n break;\n case CHECK:\n if (state.wrap) {\n //=== NEEDBITS(32);\n while (bits < 32) {\n if (have === 0) { break inf_leave; }\n have--;\n // Use '|' instead of '+' to make sure that result is signed\n hold |= input[next++] << bits;\n bits += 8;\n }\n //===//\n _out -= left;\n strm.total_out += _out;\n state.total += _out;\n if ((state.wrap & 4) && _out) {\n strm.adler = state.check =\n /*UPDATE_CHECK(state.check, put - _out, _out);*/\n (state.flags ? crc32_1(state.check, output, _out, put - _out) : adler32_1(state.check, output, _out, put - _out));\n\n }\n _out = left;\n // NB: crc32 stored as signed 32-bit int, zswap32 returns signed too\n if ((state.wrap & 4) && (state.flags ? hold : zswap32(hold)) !== state.check) {\n strm.msg = 'incorrect data check';\n state.mode = BAD;\n break;\n }\n //=== INITBITS();\n hold = 0;\n bits = 0;\n //===//\n //Tracev((stderr, \"inflate: check matches trailer\\n\"));\n }\n state.mode = LENGTH;\n /* falls through */\n case LENGTH:\n if (state.wrap && state.flags) {\n //=== NEEDBITS(32);\n while (bits < 32) {\n if (have === 0) { break inf_leave; }\n have--;\n hold += input[next++] << bits;\n bits += 8;\n }\n //===//\n if ((state.wrap & 4) && hold !== (state.total & 0xffffffff)) {\n strm.msg = 'incorrect length check';\n state.mode = BAD;\n break;\n }\n //=== INITBITS();\n hold = 0;\n bits = 0;\n //===//\n //Tracev((stderr, \"inflate: length matches trailer\\n\"));\n }\n state.mode = DONE;\n /* falls through */\n case DONE:\n ret = Z_STREAM_END$1;\n break inf_leave;\n case BAD:\n ret = Z_DATA_ERROR$1;\n break inf_leave;\n case MEM:\n return Z_MEM_ERROR$1;\n case SYNC:\n /* falls through */\n default:\n return Z_STREAM_ERROR$1;\n }\n }\n\n // inf_leave <- here is real place for \"goto inf_leave\", emulated via \"break inf_leave\"\n\n /*\n Return from inflate(), updating the total counts and the check value.\n If there was no progress during the inflate() call, return a buffer\n error. Call updatewindow() to create and/or update the window state.\n Note: a memory error from inflate() is non-recoverable.\n */\n\n //--- RESTORE() ---\n strm.next_out = put;\n strm.avail_out = left;\n strm.next_in = next;\n strm.avail_in = have;\n state.hold = hold;\n state.bits = bits;\n //---\n\n if (state.wsize || (_out !== strm.avail_out && state.mode < BAD &&\n (state.mode < CHECK || flush !== Z_FINISH$1))) {\n if (updatewindow(strm, strm.output, strm.next_out, _out - strm.avail_out)) ;\n }\n _in -= strm.avail_in;\n _out -= strm.avail_out;\n strm.total_in += _in;\n strm.total_out += _out;\n state.total += _out;\n if ((state.wrap & 4) && _out) {\n strm.adler = state.check = /*UPDATE_CHECK(state.check, strm.next_out - _out, _out);*/\n (state.flags ? crc32_1(state.check, output, _out, strm.next_out - _out) : adler32_1(state.check, output, _out, strm.next_out - _out));\n }\n strm.data_type = state.bits + (state.last ? 64 : 0) +\n (state.mode === TYPE ? 128 : 0) +\n (state.mode === LEN_ || state.mode === COPY_ ? 256 : 0);\n if (((_in === 0 && _out === 0) || flush === Z_FINISH$1) && ret === Z_OK$1) {\n ret = Z_BUF_ERROR;\n }\n return ret;\n};\n\n\nconst inflateEnd = (strm) => {\n\n if (inflateStateCheck(strm)) {\n return Z_STREAM_ERROR$1;\n }\n\n let state = strm.state;\n if (state.window) {\n state.window = null;\n }\n strm.state = null;\n return Z_OK$1;\n};\n\n\nconst inflateGetHeader = (strm, head) => {\n\n /* check state */\n if (inflateStateCheck(strm)) { return Z_STREAM_ERROR$1; }\n const state = strm.state;\n if ((state.wrap & 2) === 0) { return Z_STREAM_ERROR$1; }\n\n /* save header structure */\n state.head = head;\n head.done = false;\n return Z_OK$1;\n};\n\n\nconst inflateSetDictionary = (strm, dictionary) => {\n const dictLength = dictionary.length;\n\n let state;\n let dictid;\n let ret;\n\n /* check state */\n if (inflateStateCheck(strm)) { return Z_STREAM_ERROR$1; }\n state = strm.state;\n\n if (state.wrap !== 0 && state.mode !== DICT) {\n return Z_STREAM_ERROR$1;\n }\n\n /* check for correct dictionary identifier */\n if (state.mode === DICT) {\n dictid = 1; /* adler32(0, null, 0)*/\n /* dictid = adler32(dictid, dictionary, dictLength); */\n dictid = adler32_1(dictid, dictionary, dictLength, 0);\n if (dictid !== state.check) {\n return Z_DATA_ERROR$1;\n }\n }\n /* copy dictionary to window using updatewindow(), which will amend the\n existing dictionary if appropriate */\n ret = updatewindow(strm, dictionary, dictLength, dictLength);\n if (ret) {\n state.mode = MEM;\n return Z_MEM_ERROR$1;\n }\n state.havedict = 1;\n // Tracev((stderr, \"inflate: dictionary set\\n\"));\n return Z_OK$1;\n};\n\n\nvar inflateReset_1 = inflateReset;\nvar inflateReset2_1 = inflateReset2;\nvar inflateResetKeep_1 = inflateResetKeep;\nvar inflateInit_1 = inflateInit;\nvar inflateInit2_1 = inflateInit2;\nvar inflate_2$1 = inflate$2;\nvar inflateEnd_1 = inflateEnd;\nvar inflateGetHeader_1 = inflateGetHeader;\nvar inflateSetDictionary_1 = inflateSetDictionary;\nvar inflateInfo = 'pako inflate (from Nodeca project)';\n\n/* Not implemented\nmodule.exports.inflateCodesUsed = inflateCodesUsed;\nmodule.exports.inflateCopy = inflateCopy;\nmodule.exports.inflateGetDictionary = inflateGetDictionary;\nmodule.exports.inflateMark = inflateMark;\nmodule.exports.inflatePrime = inflatePrime;\nmodule.exports.inflateSync = inflateSync;\nmodule.exports.inflateSyncPoint = inflateSyncPoint;\nmodule.exports.inflateUndermine = inflateUndermine;\nmodule.exports.inflateValidate = inflateValidate;\n*/\n\nvar inflate_1$2 = {\n\tinflateReset: inflateReset_1,\n\tinflateReset2: inflateReset2_1,\n\tinflateResetKeep: inflateResetKeep_1,\n\tinflateInit: inflateInit_1,\n\tinflateInit2: inflateInit2_1,\n\tinflate: inflate_2$1,\n\tinflateEnd: inflateEnd_1,\n\tinflateGetHeader: inflateGetHeader_1,\n\tinflateSetDictionary: inflateSetDictionary_1,\n\tinflateInfo: inflateInfo\n};\n\n// (C) 1995-2013 Jean-loup Gailly and Mark Adler\n// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin\n//\n// This software is provided 'as-is', without any express or implied\n// warranty. In no event will the authors be held liable for any damages\n// arising from the use of this software.\n//\n// Permission is granted to anyone to use this software for any purpose,\n// including commercial applications, and to alter it and redistribute it\n// freely, subject to the following restrictions:\n//\n// 1. The origin of this software must not be misrepresented; you must not\n// claim that you wrote the original software. If you use this software\n// in a product, an acknowledgment in the product documentation would be\n// appreciated but is not required.\n// 2. Altered source versions must be plainly marked as such, and must not be\n// misrepresented as being the original software.\n// 3. This notice may not be removed or altered from any source distribution.\n\nfunction GZheader() {\n /* true if compressed data believed to be text */\n this.text = 0;\n /* modification time */\n this.time = 0;\n /* extra flags (not used when writing a gzip file) */\n this.xflags = 0;\n /* operating system */\n this.os = 0;\n /* pointer to extra field or Z_NULL if none */\n this.extra = null;\n /* extra field length (valid if extra != Z_NULL) */\n this.extra_len = 0; // Actually, we don't need it in JS,\n // but leave for few code modifications\n\n //\n // Setup limits is not necessary because in js we should not preallocate memory\n // for inflate use constant limit in 65536 bytes\n //\n\n /* space at extra (only when reading header) */\n // this.extra_max = 0;\n /* pointer to zero-terminated file name or Z_NULL */\n this.name = '';\n /* space at name (only when reading header) */\n // this.name_max = 0;\n /* pointer to zero-terminated comment or Z_NULL */\n this.comment = '';\n /* space at comment (only when reading header) */\n // this.comm_max = 0;\n /* true if there was or will be a header crc */\n this.hcrc = 0;\n /* true when done reading gzip header (not used when writing a gzip file) */\n this.done = false;\n}\n\nvar gzheader = GZheader;\n\nconst toString = Object.prototype.toString;\n\n/* Public constants ==========================================================*/\n/* ===========================================================================*/\n\nconst {\n Z_NO_FLUSH, Z_FINISH,\n Z_OK, Z_STREAM_END, Z_NEED_DICT, Z_STREAM_ERROR, Z_DATA_ERROR, Z_MEM_ERROR\n} = constants$2;\n\n/* ===========================================================================*/\n\n\n/**\n * class Inflate\n *\n * Generic JS-style wrapper for zlib calls. If you don't need\n * streaming behaviour - use more simple functions: [[inflate]]\n * and [[inflateRaw]].\n **/\n\n/* internal\n * inflate.chunks -> Array\n *\n * Chunks of output data, if [[Inflate#onData]] not overridden.\n **/\n\n/**\n * Inflate.result -> Uint8Array|String\n *\n * Uncompressed result, generated by default [[Inflate#onData]]\n * and [[Inflate#onEnd]] handlers. Filled after you push last chunk\n * (call [[Inflate#push]] with `Z_FINISH` / `true` param).\n **/\n\n/**\n * Inflate.err -> Number\n *\n * Error code after inflate finished. 0 (Z_OK) on success.\n * Should be checked if broken data possible.\n **/\n\n/**\n * Inflate.msg -> String\n *\n * Error message, if [[Inflate.err]] != 0\n **/\n\n\n/**\n * new Inflate(options)\n * - options (Object): zlib inflate options.\n *\n * Creates new inflator instance with specified params. Throws exception\n * on bad params. Supported options:\n *\n * - `windowBits`\n * - `dictionary`\n *\n * [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced)\n * for more information on these.\n *\n * Additional options, for internal needs:\n *\n * - `chunkSize` - size of generated data chunks (16K by default)\n * - `raw` (Boolean) - do raw inflate\n * - `to` (String) - if equal to 'string', then result will be converted\n * from utf8 to utf16 (javascript) string. When string output requested,\n * chunk length can differ from `chunkSize`, depending on content.\n *\n * By default, when no options set, autodetect deflate/gzip data format via\n * wrapper header.\n *\n * ##### Example:\n *\n * ```javascript\n * const pako = require('pako')\n * const chunk1 = new Uint8Array([1,2,3,4,5,6,7,8,9])\n * const chunk2 = new Uint8Array([10,11,12,13,14,15,16,17,18,19]);\n *\n * const inflate = new pako.Inflate({ level: 3});\n *\n * inflate.push(chunk1, false);\n * inflate.push(chunk2, true); // true -> last chunk\n *\n * if (inflate.err) { throw new Error(inflate.err); }\n *\n * console.log(inflate.result);\n * ```\n **/\nfunction Inflate$1(options) {\n this.options = common.assign({\n chunkSize: 1024 * 64,\n windowBits: 15,\n to: ''\n }, options || {});\n\n const opt = this.options;\n\n // Force window size for `raw` data, if not set directly,\n // because we have no header for autodetect.\n if (opt.raw && (opt.windowBits >= 0) && (opt.windowBits < 16)) {\n opt.windowBits = -opt.windowBits;\n if (opt.windowBits === 0) { opt.windowBits = -15; }\n }\n\n // If `windowBits` not defined (and mode not raw) - set autodetect flag for gzip/deflate\n if ((opt.windowBits >= 0) && (opt.windowBits < 16) &&\n !(options && options.windowBits)) {\n opt.windowBits += 32;\n }\n\n // Gzip header has no info about windows size, we can do autodetect only\n // for deflate. So, if window size not set, force it to max when gzip possible\n if ((opt.windowBits > 15) && (opt.windowBits < 48)) {\n // bit 3 (16) -> gzipped data\n // bit 4 (32) -> autodetect gzip/deflate\n if ((opt.windowBits & 15) === 0) {\n opt.windowBits |= 15;\n }\n }\n\n this.err = 0; // error code, if happens (0 = Z_OK)\n this.msg = ''; // error message\n this.ended = false; // used to avoid multiple onEnd() calls\n this.chunks = []; // chunks of compressed data\n\n this.strm = new zstream();\n this.strm.avail_out = 0;\n\n let status = inflate_1$2.inflateInit2(\n this.strm,\n opt.windowBits\n );\n\n if (status !== Z_OK) {\n throw new Error(messages[status]);\n }\n\n this.header = new gzheader();\n\n inflate_1$2.inflateGetHeader(this.strm, this.header);\n\n // Setup dictionary\n if (opt.dictionary) {\n // Convert data if needed\n if (typeof opt.dictionary === 'string') {\n opt.dictionary = strings.string2buf(opt.dictionary);\n } else if (toString.call(opt.dictionary) === '[object ArrayBuffer]') {\n opt.dictionary = new Uint8Array(opt.dictionary);\n }\n if (opt.raw) { //In raw mode we need to set the dictionary early\n status = inflate_1$2.inflateSetDictionary(this.strm, opt.dictionary);\n if (status !== Z_OK) {\n throw new Error(messages[status]);\n }\n }\n }\n}\n\n/**\n * Inflate#push(data[, flush_mode]) -> Boolean\n * - data (Uint8Array|ArrayBuffer): input data\n * - flush_mode (Number|Boolean): 0..6 for corresponding Z_NO_FLUSH..Z_TREE\n * flush modes. See constants. Skipped or `false` means Z_NO_FLUSH,\n * `true` means Z_FINISH.\n *\n * Sends input data to inflate pipe, generating [[Inflate#onData]] calls with\n * new output chunks. Returns `true` on success. If end of stream detected,\n * [[Inflate#onEnd]] will be called.\n *\n * `flush_mode` is not needed for normal operation, because end of stream\n * detected automatically. You may try to use it for advanced things, but\n * this functionality was not tested.\n *\n * On fail call [[Inflate#onEnd]] with error code and return false.\n *\n * ##### Example\n *\n * ```javascript\n * push(chunk, false); // push one of data chunks\n * ...\n * push(chunk, true); // push last chunk\n * ```\n **/\nInflate$1.prototype.push = function (data, flush_mode) {\n const strm = this.strm;\n const chunkSize = this.options.chunkSize;\n const dictionary = this.options.dictionary;\n let status, _flush_mode, last_avail_out;\n\n if (this.ended) return false;\n\n if (flush_mode === ~~flush_mode) _flush_mode = flush_mode;\n else _flush_mode = flush_mode === true ? Z_FINISH : Z_NO_FLUSH;\n\n // Convert data if needed\n if (toString.call(data) === '[object ArrayBuffer]') {\n strm.input = new Uint8Array(data);\n } else {\n strm.input = data;\n }\n\n strm.next_in = 0;\n strm.avail_in = strm.input.length;\n\n for (;;) {\n if (strm.avail_out === 0) {\n strm.output = new Uint8Array(chunkSize);\n strm.next_out = 0;\n strm.avail_out = chunkSize;\n }\n\n status = inflate_1$2.inflate(strm, _flush_mode);\n\n if (status === Z_NEED_DICT && dictionary) {\n status = inflate_1$2.inflateSetDictionary(strm, dictionary);\n\n if (status === Z_OK) {\n status = inflate_1$2.inflate(strm, _flush_mode);\n } else if (status === Z_DATA_ERROR) {\n // Replace code with more verbose\n status = Z_NEED_DICT;\n }\n }\n\n // Skip snyc markers if more data follows and not raw mode\n while (strm.avail_in > 0 &&\n status === Z_STREAM_END &&\n strm.state.wrap > 0 &&\n data[strm.next_in] !== 0)\n {\n inflate_1$2.inflateReset(strm);\n status = inflate_1$2.inflate(strm, _flush_mode);\n }\n\n switch (status) {\n case Z_STREAM_ERROR:\n case Z_DATA_ERROR:\n case Z_NEED_DICT:\n case Z_MEM_ERROR:\n this.onEnd(status);\n this.ended = true;\n return false;\n }\n\n // Remember real `avail_out` value, because we may patch out buffer content\n // to align utf8 strings boundaries.\n last_avail_out = strm.avail_out;\n\n if (strm.next_out) {\n if (strm.avail_out === 0 || status === Z_STREAM_END) {\n\n if (this.options.to === 'string') {\n\n let next_out_utf8 = strings.utf8border(strm.output, strm.next_out);\n\n let tail = strm.next_out - next_out_utf8;\n let utf8str = strings.buf2string(strm.output, next_out_utf8);\n\n // move tail & realign counters\n strm.next_out = tail;\n strm.avail_out = chunkSize - tail;\n if (tail) strm.output.set(strm.output.subarray(next_out_utf8, next_out_utf8 + tail), 0);\n\n this.onData(utf8str);\n\n } else {\n this.onData(strm.output.length === strm.next_out ? strm.output : strm.output.subarray(0, strm.next_out));\n }\n }\n }\n\n // Must repeat iteration if out buffer is full\n if (status === Z_OK && last_avail_out === 0) continue;\n\n // Finalize if end of stream reached.\n if (status === Z_STREAM_END) {\n status = inflate_1$2.inflateEnd(this.strm);\n this.onEnd(status);\n this.ended = true;\n return true;\n }\n\n if (strm.avail_in === 0) break;\n }\n\n return true;\n};\n\n\n/**\n * Inflate#onData(chunk) -> Void\n * - chunk (Uint8Array|String): output data. When string output requested,\n * each chunk will be string.\n *\n * By default, stores data blocks in `chunks[]` property and glue\n * those in `onEnd`. Override this handler, if you need another behaviour.\n **/\nInflate$1.prototype.onData = function (chunk) {\n this.chunks.push(chunk);\n};\n\n\n/**\n * Inflate#onEnd(status) -> Void\n * - status (Number): inflate status. 0 (Z_OK) on success,\n * other if not.\n *\n * Called either after you tell inflate that the input stream is\n * complete (Z_FINISH). By default - join collected chunks,\n * free memory and fill `results` / `err` properties.\n **/\nInflate$1.prototype.onEnd = function (status) {\n // On success - join\n if (status === Z_OK) {\n if (this.options.to === 'string') {\n this.result = this.chunks.join('');\n } else {\n this.result = common.flattenChunks(this.chunks);\n }\n }\n this.chunks = [];\n this.err = status;\n this.msg = this.strm.msg;\n};\n\n\n/**\n * inflate(data[, options]) -> Uint8Array|String\n * - data (Uint8Array|ArrayBuffer): input data to decompress.\n * - options (Object): zlib inflate options.\n *\n * Decompress `data` with inflate/ungzip and `options`. Autodetect\n * format via wrapper header by default. That's why we don't provide\n * separate `ungzip` method.\n *\n * Supported options are:\n *\n * - windowBits\n *\n * [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced)\n * for more information.\n *\n * Sugar (options):\n *\n * - `raw` (Boolean) - say that we work with raw stream, if you don't wish to specify\n * negative windowBits implicitly.\n * - `to` (String) - if equal to 'string', then result will be converted\n * from utf8 to utf16 (javascript) string. When string output requested,\n * chunk length can differ from `chunkSize`, depending on content.\n *\n *\n * ##### Example:\n *\n * ```javascript\n * const pako = require('pako');\n * const input = pako.deflate(new Uint8Array([1,2,3,4,5,6,7,8,9]));\n * let output;\n *\n * try {\n * output = pako.inflate(input);\n * } catch (err) {\n * console.log(err);\n * }\n * ```\n **/\nfunction inflate$1(input, options) {\n const inflator = new Inflate$1(options);\n\n inflator.push(input);\n\n // That will never happens, if you don't cheat with options :)\n if (inflator.err) throw inflator.msg || messages[inflator.err];\n\n return inflator.result;\n}\n\n\n/**\n * inflateRaw(data[, options]) -> Uint8Array|String\n * - data (Uint8Array|ArrayBuffer): input data to decompress.\n * - options (Object): zlib inflate options.\n *\n * The same as [[inflate]], but creates raw data, without wrapper\n * (header and adler32 crc).\n **/\nfunction inflateRaw$1(input, options) {\n options = options || {};\n options.raw = true;\n return inflate$1(input, options);\n}\n\n\n/**\n * ungzip(data[, options]) -> Uint8Array|String\n * - data (Uint8Array|ArrayBuffer): input data to decompress.\n * - options (Object): zlib inflate options.\n *\n * Just shortcut to [[inflate]], because it autodetects format\n * by header.content. Done for convenience.\n **/\n\n\nvar Inflate_1$1 = Inflate$1;\nvar inflate_2 = inflate$1;\nvar inflateRaw_1$1 = inflateRaw$1;\nvar ungzip$1 = inflate$1;\nvar constants = constants$2;\n\nvar inflate_1$1 = {\n\tInflate: Inflate_1$1,\n\tinflate: inflate_2,\n\tinflateRaw: inflateRaw_1$1,\n\tungzip: ungzip$1,\n\tconstants: constants\n};\n\nconst { Deflate, deflate, deflateRaw, gzip } = deflate_1$1;\n\nconst { Inflate, inflate, inflateRaw, ungzip } = inflate_1$1;\n\n\n\nvar Deflate_1 = Deflate;\nvar deflate_1 = deflate;\nvar deflateRaw_1 = deflateRaw;\nvar gzip_1 = gzip;\nvar Inflate_1 = Inflate;\nvar inflate_1 = inflate;\nvar inflateRaw_1 = inflateRaw;\nvar ungzip_1 = ungzip;\nvar constants_1 = constants$2;\n\n\nexport { Deflate_1 as Deflate, Inflate_1 as Inflate, constants_1 as constants, deflate_1 as deflate, deflateRaw_1 as deflateRaw, gzip_1 as gzip, inflate_1 as inflate, inflateRaw_1 as inflateRaw, ungzip_1 as ungzip };\n","\nimport {ungzip, gzip, deflateRaw, inflateRaw, inflate} from \"./pako.esm.js\"\n\n\nconst FEXTRA = 4; // gzip spec F.EXTRA flag\n\nfunction isgzipped(data) {\n const b = ArrayBuffer.isView(data) ? data : new Uint8Array(data);\n return b[0] ===31 && b[1] === 139;\n}\n\n/**\n * Pako does not properly ungzip block compressed files if > 1 block is present. Test for bgzip and use wrapper.\n */\nfunction ungzip_blocks(data) {\n const ba = ArrayBuffer.isView(data) ? data : new Uint8Array(data);\n const b = ba[3] & FEXTRA;\n if (b !== 0 && ba[12] === 66 && ba[13] === 67) {\n return unbgzf(ba.buffer);\n } else {\n return ungzip(ba);\n }\n}\n\n// Uncompress data, assumed to be series of bgzipped blocks\nfunction unbgzf(data, lim) {\n\n const oBlockList = [];\n let ptr = 0;\n let totalSize = 0;\n\n lim = lim || data.byteLength - 18;\n\n while (ptr < lim) {\n try {\n const ba = ArrayBuffer.isView(data) ? data : new Uint8Array(data, ptr, 18);\n const xlen = (ba[11] << 8) | (ba[10]);\n const flg = ba[3];\n const fextra = flg & FEXTRA;\n const si1 = ba[12];\n const si2 = ba[13];\n const slen = (ba[15] << 8) | (ba[14]);\n const bsize = ((ba[17] << 8) | (ba[16])) + 1;\n const start = 12 + xlen + ptr; // Start of CDATA\n const bytesLeft = data.byteLength - start;\n const cDataSize = bsize - xlen - 19;\n if (bytesLeft < cDataSize || cDataSize <= 0) break;\n\n const a = new Uint8Array(data, start, cDataSize);\n const unc = inflateRaw(a);\n\n // const inflate = new Zlib.RawInflate(a);\n // const unc = inflate.decompress();\n\n ptr += (cDataSize - 1) + 26; //inflate.ip + 26\n totalSize += unc.byteLength;\n oBlockList.push(unc);\n } catch (e) {\n console.error(e)\n break;\n }\n }\n\n // Concatenate decompressed blocks\n if (oBlockList.length === 1) {\n return oBlockList[0];\n } else {\n const out = new Uint8Array(totalSize);\n let cursor = 0;\n for (let i = 0; i < oBlockList.length; ++i) {\n var b = new Uint8Array(oBlockList[i]);\n arrayCopy(b, 0, out, cursor, b.length);\n cursor += b.length;\n }\n return out;\n }\n}\n\nfunction bgzBlockSize(data) {\n const ba = ArrayBuffer.isView(data) ? data : new Uint8Array(data);\n const bsize = (ba[17] << 8 | ba[16]) + 1;\n return bsize;\n}\n\n// From Thomas Down's zlib implementation\n\nconst testArray = new Uint8Array(1);\nconst hasSubarray = (typeof testArray.subarray === 'function');\n\nfunction arrayCopy(src, srcOffset, dest, destOffset, count) {\n if (count === 0) {\n return;\n }\n if (!src) {\n throw \"Undef src\";\n } else if (!dest) {\n throw \"Undef dest\";\n }\n if (srcOffset === 0 && count === src.length) {\n arrayCopy_fast(src, dest, destOffset);\n } else if (hasSubarray) {\n arrayCopy_fast(src.subarray(srcOffset, srcOffset + count), dest, destOffset);\n } else if (src.BYTES_PER_ELEMENT === 1 && count > 100) {\n arrayCopy_fast(new Uint8Array(src.buffer, src.byteOffset + srcOffset, count), dest, destOffset);\n } else {\n arrayCopy_slow(src, srcOffset, dest, destOffset, count);\n }\n}\n\nfunction arrayCopy_slow(src, srcOffset, dest, destOffset, count) {\n for (let i = 0; i < count; ++i) {\n dest[destOffset + i] = src[srcOffset + i];\n }\n}\n\nfunction arrayCopy_fast(src, dest, destOffset) {\n dest.set(src, destOffset);\n}\n\n\n/**\n * Compress string and encode in a url safe form\n * @param s\n */\nfunction compressString(str) {\n\n const bytes = new Uint8Array(str.length);\n for (var i = 0; i < str.length; i++) {\n bytes[i] = str.charCodeAt(i);\n }\n const compressedBytes = new deflateRaw(bytes); // UInt8Arry\n const compressedString = String.fromCharCode.apply(null, compressedBytes); // Convert to string\n let enc = btoa(compressedString);\n return enc.replace(/\\+/g, '.').replace(/\\//g, '_').replace(/=/g, '-'); // URL safe\n}\n\n/**\n * Uncompress the url-safe encoded compressed string, presumably created by compressString above\n *\n * @param enc\n * @returns {string}\n */\nfunction uncompressString(enc) {\n\n enc = enc.replace(/\\./g, '+').replace(/_/g, '/').replace(/-/g, '=')\n\n const compressedString = atob(enc);\n const compressedBytes = [];\n for (let i = 0; i < compressedString.length; i++) {\n compressedBytes.push(compressedString.charCodeAt(i));\n }\n //const bytes = new Zlib.RawInflate(compressedBytes).decompress();\n const bytes = inflateRaw(compressedBytes);\n\n let str = ''\n for (let b of bytes) {\n str += String.fromCharCode(b)\n }\n return str;\n}\n\n\n/**\n * @param dataURI\n * @returns {Array|Uint8Array}\n */\nfunction decodeDataURI(dataURI, gzip) {\n\n const split = dataURI.split(',');\n const info = split[0].split(':')[1];\n let dataString = split[1];\n\n if (info.indexOf('base64') >= 0) {\n dataString = atob(dataString);\n\n const bytes = new Uint8Array(dataString.length);\n for (let i = 0; i < dataString.length; i++) {\n bytes[i] = dataString.charCodeAt(i);\n }\n\n let plain\n if (gzip || info.indexOf('gzip') > 0) {\n plain = ungzip(bytes)\n } else {\n plain = bytes\n }\n return plain\n } else {\n return decodeURIComponent(dataString); // URL encoded string -- not currently used or tested\n }\n}\n\nexport {\n unbgzf,\n bgzBlockSize,\n gzip,\n ungzip_blocks as ungzip,\n isgzipped,\n compressString,\n uncompressString,\n decodeDataURI,\n inflate,\n inflateRaw\n}","/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2016-2017 The Regents of the University of California\n * Author: Jim Robinson\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\nconst IGVMath = {\n\n lerp: (v0, v1, t) => {\n return (1 - t) * v0 + t * v1;\n },\n\n mean: function (array) {\n\n var t = 0, n = 0,\n i;\n for (i = 0; i < array.length; i++) {\n if (!isNaN(array[i])) {\n t += array[i];\n n++;\n }\n }\n return n > 0 ? t / n : 0;\n },\n\n meanAndStdev: function (array) {\n\n var v, t = 0, t2 = 0, n = 0, i;\n\n for (i = 0; i < array.length; i++) {\n\n v = array[i];\n\n if (!isNaN(v)) {\n t += v;\n t2 += v * v;\n n++;\n }\n }\n return n > 0 ? {mean: t / n, stdev: Math.sqrt(t2 - t * t / n)} : {mean: 0, stdev: 0};\n },\n\n median: function (numbers) {\n // median of [3, 5, 4, 4, 1, 1, 2, 3] = 3\n var median = 0, numsLen = numbers.length;\n numbers.sort();\n\n if (\n numsLen % 2 === 0 // is even\n ) {\n // average of two middle numbers\n median = (numbers[numsLen / 2 - 1] + numbers[numsLen / 2]) / 2;\n } else { // is odd\n // middle number only\n median = numbers[(numsLen - 1) / 2];\n }\n\n return median;\n },\n\n // Fast percentile function for \"p\" near edges. This needs profiled for p in middle (e.g. median)\n percentile: function (array, p) {\n\n if (array.length === 0) return undefined;\n\n var k = Math.floor(array.length * ((100 - p) / 100));\n if (k === 0) {\n array.sort(function (a, b) {\n return b - a\n });\n return array[k];\n } else {\n return selectElement(array, k);\n }\n\n },\n\n\n clamp: function (value, min, max) {\n return Math.min(Math.max(value, min), max);\n },\n\n log2: function (x) {\n return Math.log(x) / Math.LN2;\n }\n\n};\n\nfunction selectElement(array, k) {\n\n // Credit Steve Hanov http://stevehanov.ca/blog/index.php?id=122\n var heap = new BinaryHeap(),\n i;\n\n for (i = 0; i < array.length; i++) {\n\n var item = array[i];\n\n // If we have not yet found k items, or the current item is larger than\n // the smallest item on the heap, add current item\n if (heap.content.length < k || item > heap.content[0]) {\n // If the heap is full, remove the smallest element on the heap.\n if (heap.content.length === k) {\n var r = heap.pop();\n }\n heap.push(item)\n }\n }\n\n return heap.content[0];\n}\n\n\nfunction BinaryHeap() {\n this.content = [];\n}\n\nBinaryHeap.prototype = {\n push: function (element) {\n // Add the new element to the end of the array.\n this.content.push(element);\n // Allow it to bubble up.\n this.bubbleUp(this.content.length - 1);\n },\n\n pop: function () {\n // Store the first element so we can return it later.\n var result = this.content[0];\n // Get the element at the end of the array.\n var end = this.content.pop();\n // If there are any elements left, put the end element at the\n // start, and let it sink down.\n if (this.content.length > 0) {\n this.content[0] = end;\n this.sinkDown(0);\n }\n return result;\n },\n\n remove: function (node) {\n var length = this.content.length;\n // To remove a value, we must search through the array to find\n // it.\n for (var i = 0; i < length; i++) {\n if (this.content[i] !== node) continue;\n // When it is found, the process seen in 'pop' is repeated\n // to fill up the hole.\n var end = this.content.pop();\n // If the element we popped was the one we needed to remove,\n // we're done.\n if (i === length - 1) break;\n // Otherwise, we replace the removed element with the popped\n // one, and allow it to float up or sink down as appropriate.\n this.content[i] = end;\n this.bubbleUp(i);\n this.sinkDown(i);\n break;\n }\n },\n\n size: function () {\n return this.content.length;\n },\n\n bubbleUp: function (n) {\n // Fetch the element that has to be moved.\n var element = this.content[n], score = element;\n // When at 0, an element can not go up any further.\n while (n > 0) {\n // Compute the parent element's index, and fetch it.\n var parentN = Math.floor((n + 1) / 2) - 1,\n parent = this.content[parentN];\n // If the parent has a lesser score, things are in order and we\n // are done.\n if (score >= parent)\n break;\n\n // Otherwise, swap the parent with the current element and\n // continue.\n this.content[parentN] = element;\n this.content[n] = parent;\n n = parentN;\n }\n },\n\n sinkDown: function (n) {\n // Look up the target element and its score.\n var length = this.content.length,\n element = this.content[n],\n elemScore = element;\n\n while (true) {\n // Compute the indices of the child elements.\n var child2N = (n + 1) * 2, child1N = child2N - 1;\n // This is used to store the new position of the element,\n // if any.\n var swap = null;\n // If the first child exists (is inside the array)...\n if (child1N < length) {\n // Look it up and compute its score.\n var child1 = this.content[child1N],\n child1Score = child1;\n // If the score is less than our element's, we need to swap.\n if (child1Score < elemScore)\n swap = child1N;\n }\n // Do the same checks for the other child.\n if (child2N < length) {\n var child2 = this.content[child2N],\n child2Score = child2;\n if (child2Score < (swap == null ? elemScore : child1Score))\n swap = child2N;\n }\n\n // No need to swap further, we are done.\n if (swap == null) break;\n\n // Otherwise, swap and continue.\n this.content[n] = this.content[swap];\n this.content[swap] = element;\n n = swap;\n }\n }\n};\n\nexport default IGVMath;\n","/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2014 Broad Institute\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\nimport IGVMath from \"./igv-math.js\";\nimport {stripQuotes} from \"./stringUtils.js\";\n\nfunction _random(min, max) {\n return Math.random() * (max - min) + min;\n}\n\nconst IGVColor = {\n\n rgbListFromHSV: () => {\n\n let s = 1;\n let accumulation = [];\n for (let v = 1; v >= 0.5; v -= .1) {\n for (let h = 0; h < 1; h += 1 / 28) {\n const r = \"rgb(\" + IGVColor.hsvToRgb(h, s, v).join(\",\") + \")\";\n accumulation.push(r);\n }\n }\n\n // add black\n accumulation.pop();\n accumulation.push(IGVColor.rgbColor(16, 16, 16));\n\n return accumulation;\n },\n\n rgbToHex: function (rgb) {\n rgb = rgb.match(/^rgba?[\\s+]?\\([\\s+]?(\\d+)[\\s+]?,[\\s+]?(\\d+)[\\s+]?,[\\s+]?(\\d+)[\\s+]?/i);\n return (rgb && rgb.length === 4) ? \"#\" +\n (\"0\" + parseInt(rgb[1], 10).toString(16)).slice(-2) +\n (\"0\" + parseInt(rgb[2], 10).toString(16)).slice(-2) +\n (\"0\" + parseInt(rgb[3], 10).toString(16)).slice(-2) : '';\n },\n\n hexToRgb: function (hex) {\n\n var cooked = /^#?([a-f\\d]{2})([a-f\\d]{2})([a-f\\d]{2})$/i.exec(hex);\n\n if (null === cooked) {\n return undefined;\n }\n\n return \"rgb(\" + parseInt(cooked[1], 16) + \",\" + parseInt(cooked[2], 16) + \",\" + parseInt(cooked[3], 16) + \")\";\n },\n\n /**\n * Converts an HSV color value to RGB. Conversion formula\n * adapted from http://en.wikipedia.org/wiki/HSV_color_space.\n * Assumes h, s, and v are contained in the set [0, 1] and\n * returns r, g, and b in the set [0, 255].\n *\n * Credit: https://gist.githubusercontent.com/mjackson/5311256\n *\n * @param h The hue\n * @param s The saturation\n * @param v The value\n * @return Array The RGB representation\n */\n hsvToRgb: function (h, s, v) {\n var r, g, b;\n\n var i = Math.floor(h * 6);\n var f = h * 6 - i;\n var p = v * (1 - s);\n var q = v * (1 - f * s);\n var t = v * (1 - (1 - f) * s);\n\n switch (i % 6) {\n case 0:\n r = v, g = t, b = p;\n break;\n case 1:\n r = q, g = v, b = p;\n break;\n case 2:\n r = p, g = v, b = t;\n break;\n case 3:\n r = p, g = q, b = v;\n break;\n case 4:\n r = t, g = p, b = v;\n break;\n case 5:\n r = v, g = p, b = q;\n break;\n }\n\n return [Math.floor(r * 255), Math.floor(g * 255), Math.floor(b * 255)];\n },\n\n /**\n * Converts an HSL color value to RGB. Conversion formula\n * adapted from http://en.wikipedia.org/wiki/HSL_color_space.\n * Assumes h, s, and l are contained in the set [0, 1] and\n * returns r, g, and b in the set [0, 255].\n *\n * Credit: https://gist.githubusercontent.com/mjackson/5311256\n *\n * @param h The hue\n * @param s The saturation\n * @param l The lightness\n * @return Array The RGB representation\n */\n hslToRgb: function (h, s, l) {\n var r, g, b;\n\n if (s === 0) {\n r = g = b = l; // achromatic\n } else {\n\n\n var q = l < 0.5 ? l * (1 + s) : l + s - l * s;\n var p = 2 * l - q;\n\n r = IGVColor.hue2rgb(p, q, h + 1 / 3);\n g = IGVColor.hue2rgb(p, q, h);\n b = IGVColor.hue2rgb(p, q, h - 1 / 3);\n }\n\n return [r * 255, g * 255, b * 255];\n },\n\n hue2rgb: (p, q, t) => {\n if (t < 0) t += 1;\n if (t > 1) t -= 1;\n if (t < 1 / 6) return p + (q - p) * 6 * t;\n if (t < 1 / 2) return q;\n if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;\n return p;\n },\n\n rgbaColor: function (r, g, b, a) {\n\n r = IGVMath.clamp(r, 0, 255);\n g = IGVMath.clamp(g, 0, 255);\n b = IGVMath.clamp(b, 0, 255);\n a = IGVMath.clamp(a, 0.0, 1.0);\n\n return \"rgba(\" + r + \",\" + g + \",\" + b + \",\" + a + \")\";\n },\n\n rgbColor: function (r, g, b) {\n\n r = IGVMath.clamp(r, 0, 255);\n g = IGVMath.clamp(g, 0, 255);\n b = IGVMath.clamp(b, 0, 255);\n\n return \"rgb(\" + r + \",\" + g + \",\" + b + \")\";\n },\n\n greyScale: function (value) {\n\n var grey = IGVMath.clamp(value, 0, 255);\n\n return \"rgb(\" + grey + \",\" + grey + \",\" + grey + \")\";\n },\n\n randomGrey: function (min, max) {\n\n min = IGVMath.clamp(min, 0, 255);\n max = IGVMath.clamp(max, 0, 255);\n\n var g = Math.round(_random(min, max)).toString(10);\n\n return \"rgb(\" + g + \",\" + g + \",\" + g + \")\";\n },\n\n randomRGB: function (min, max) {\n\n min = IGVMath.clamp(min, 0, 255);\n max = IGVMath.clamp(max, 0, 255);\n\n var r = Math.round(_random(min, max)).toString(10);\n var g = Math.round(_random(min, max)).toString(10);\n var b = Math.round(_random(min, max)).toString(10);\n\n return \"rgb(\" + r + \",\" + g + \",\" + b + \")\";\n },\n\n randomRGBConstantAlpha: function (min, max, alpha) {\n\n min = IGVMath.clamp(min, 0, 255);\n max = IGVMath.clamp(max, 0, 255);\n\n var r = Math.round(_random(min, max)).toString(10);\n var g = Math.round(_random(min, max)).toString(10);\n var b = Math.round(_random(min, max)).toString(10);\n\n return \"rgba(\" + r + \",\" + g + \",\" + b + \",\" + alpha + \")\";\n },\n\n addAlpha: function (color, alpha) {\n\n if(color === \"0\" || color === \".\") {\n color = \"rgb(0,0,0)\"\n } else {\n const c = this.colorNameToHex(color);\n if (c) {\n color = c;\n }\n }\n\n var isHex = /(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(color);\n\n if (color.startsWith(\"rgba\")) {\n const idx = color.lastIndexOf(\",\");\n return color.substring(0, idx+1) + alpha.toString() + \")\";\n }\n\n if (isHex) {\n color = IGVColor.hexToRgb(color);\n }\n\n if (color.startsWith(\"rgb\")) {\n return color.replace(\"rgb\", \"rgba\").replace(\")\", \", \" + alpha + \")\");\n } else {\n console.log(color + \" is not an rgb style string\");\n return color;\n }\n },\n\n rgbComponents: function (color) {\n\n if(color === \"0\" || color === \".\") {\n return [0,0,0];\n }\n const isHex = /(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(color);\n if (isHex) {\n color = IGVColor.hexToRgb(color);\n } else {\n if(!color.startsWith(\"rgb\")) {\n const hex = this.colorNameToHex(color);\n color = this.hexToRgb(hex);\n }\n }\n\n if (color.startsWith(\"rgb(\")) {\n return color.substring(4, color.length-1).split(\",\").map(s => Number.parseInt(s.trim()));\n } else if (color.startsWith(\"rgba(\")) {\n return color.substring(5, color.length-1).split(\",\").map((s, i) => {\n s = s.trim();\n return i === 3 ? Number.parseFloat(s) : Number.parseInt(s)\n });\n }\n else {\n throw Error(\"Unrecognized color string: color\");\n }\n },\n\n /**\n *\n * @param dest RGB components as an array\n * @param src RGB components as an array\n * @param alpha alpha transparancy in the range 0-1\n * @returns {}\n */\n getCompositeColor: function (dest, src, alpha) {\n\n var r = Math.floor(alpha * src[0] + (1 - alpha) * dest[0]),\n g = Math.floor(alpha * src[1] + (1 - alpha) * dest[1]),\n b = Math.floor(alpha * src[2] + (1 - alpha) * dest[2]);\n\n return \"rgb(\" + r + \",\" + g + \",\" + b + \")\";\n\n },\n\n\n createColorString: function (str) {\n // Excel will quote color strings, strip all quotes\n str = stripQuotes(str);\n\n if (str.includes(\",\")) {\n return str.startsWith(\"rgb\") ? str : \"rgb(\" + str + \")\";\n } else {\n return str;\n }\n },\n\n darkenLighten: function (color, amt) {\n\n let src;\n let hexColor = this.colorNameToHex(color);\n if(hexColor) {\n src = IGVColor.hexToRgb(hexColor);\n } else {\n src = color.startsWith('rgb(') ? color : IGVColor.hexToRgb(color);\n }\n\n const components = src.replace(\")\", \"\").substring(4).split(\",\");\n\n const r = Math.max(0, Math.min(255, Number.parseInt(components[0].trim()) + amt));\n const g = Math.max(0, Math.min(255, Number.parseInt(components[1].trim()) + amt));\n const b = Math.max(0, Math.min(255, Number.parseInt(components[2].trim()) + amt));\n\n return 'rgb(' + r.toString() + ',' + g.toString() + ',' + b.toString() + ')';\n\n },\n\n /**\n * Convert html/css color name to hex value. Adapted from https://gist.github.com/mxfh/4719348\n * @param colorName\n * @returns {*}\n */\n colorNameToHex: function (colorName) { // color list from http://stackoverflow.com/q/1573053/731179 with added gray/gray\n const definedColorNames = {\n \"aliceblue\": \"#f0f8ff\",\n \"antiquewhite\": \"#faebd7\",\n \"aqua\": \"#00ffff\",\n \"aquamarine\": \"#7fffd4\",\n \"azure\": \"#f0ffff\",\n \"beige\": \"#f5f5dc\",\n \"bisque\": \"#ffe4c4\",\n \"black\": \"#000000\",\n \"blanchedalmond\": \"#ffebcd\",\n \"blue\": \"#0000ff\",\n \"blueviolet\": \"#8a2be2\",\n \"brown\": \"#a52a2a\",\n \"burlywood\": \"#deb887\",\n \"cadetblue\": \"#5f9ea0\",\n \"chartreuse\": \"#7fff00\",\n \"chocolate\": \"#d2691e\",\n \"coral\": \"#ff7f50\",\n \"cornflowerblue\": \"#6495ed\",\n \"cornsilk\": \"#fff8dc\",\n \"crimson\": \"#dc143c\",\n \"cyan\": \"#00ffff\",\n \"darkblue\": \"#00008b\",\n \"darkcyan\": \"#008b8b\",\n \"darkgoldenrod\": \"#b8860b\",\n \"darkgray\": \"#a9a9a9\",\n \"darkgreen\": \"#006400\",\n \"darkkhaki\": \"#bdb76b\",\n \"darkmagenta\": \"#8b008b\",\n \"darkolivegreen\": \"#556b2f\",\n \"darkorange\": \"#ff8c00\",\n \"darkorchid\": \"#9932cc\",\n \"darkred\": \"#8b0000\",\n \"darksalmon\": \"#e9967a\",\n \"darkseagreen\": \"#8fbc8f\",\n \"darkslateblue\": \"#483d8b\",\n \"darkslategray\": \"#2f4f4f\",\n \"darkturquoise\": \"#00ced1\",\n \"darkviolet\": \"#9400d3\",\n \"deeppink\": \"#ff1493\",\n \"deepskyblue\": \"#00bfff\",\n \"dimgray\": \"#696969\",\n \"dodgerblue\": \"#1e90ff\",\n \"firebrick\": \"#b22222\",\n \"floralwhite\": \"#fffaf0\",\n \"forestgreen\": \"#228b22\",\n \"fuchsia\": \"#ff00ff\",\n \"gainsboro\": \"#dcdcdc\",\n \"ghostwhite\": \"#f8f8ff\",\n \"gold\": \"#ffd700\",\n \"goldenrod\": \"#daa520\",\n \"gray\": \"#808080\",\n \"green\": \"#008000\",\n \"greenyellow\": \"#adff2f\",\n \"honeydew\": \"#f0fff0\",\n \"hotpink\": \"#ff69b4\",\n \"indianred \": \"#cd5c5c\",\n \"indigo \": \"#4b0082\",\n \"ivory\": \"#fffff0\",\n \"khaki\": \"#f0e68c\",\n \"lavender\": \"#e6e6fa\",\n \"lavenderblush\": \"#fff0f5\",\n \"lawngreen\": \"#7cfc00\",\n \"lemonchiffon\": \"#fffacd\",\n \"lightblue\": \"#add8e6\",\n \"lightcoral\": \"#f08080\",\n \"lightcyan\": \"#e0ffff\",\n \"lightgoldenrodyellow\": \"#fafad2\",\n \"lightgrey\": \"#d3d3d3\",\n \"lightgreen\": \"#90ee90\",\n \"lightpink\": \"#ffb6c1\",\n \"lightsalmon\": \"#ffa07a\",\n \"lightseagreen\": \"#20b2aa\",\n \"lightskyblue\": \"#87cefa\",\n \"lightslategray\": \"#778899\",\n \"lightsteelblue\": \"#b0c4de\",\n \"lightyellow\": \"#ffffe0\",\n \"lime\": \"#00ff00\",\n \"limegreen\": \"#32cd32\",\n \"linen\": \"#faf0e6\",\n \"magenta\": \"#ff00ff\",\n \"maroon\": \"#800000\",\n \"mediumaquamarine\": \"#66cdaa\",\n \"mediumblue\": \"#0000cd\",\n \"mediumorchid\": \"#ba55d3\",\n \"mediumpurple\": \"#9370d8\",\n \"mediumseagreen\": \"#3cb371\",\n \"mediumslateblue\": \"#7b68ee\",\n \"mediumspringgreen\": \"#00fa9a\",\n \"mediumturquoise\": \"#48d1cc\",\n \"mediumvioletred\": \"#c71585\",\n \"midnightblue\": \"#191970\",\n \"mintcream\": \"#f5fffa\",\n \"mistyrose\": \"#ffe4e1\",\n \"moccasin\": \"#ffe4b5\",\n \"navajowhite\": \"#ffdead\",\n \"navy\": \"#000080\",\n \"oldlace\": \"#fdf5e6\",\n \"olive\": \"#808000\",\n \"olivedrab\": \"#6b8e23\",\n \"orange\": \"#ffa500\",\n \"orangered\": \"#ff4500\",\n \"orchid\": \"#da70d6\",\n \"palegoldenrod\": \"#eee8aa\",\n \"palegreen\": \"#98fb98\",\n \"paleturquoise\": \"#afeeee\",\n \"palevioletred\": \"#d87093\",\n \"papayawhip\": \"#ffefd5\",\n \"peachpuff\": \"#ffdab9\",\n \"peru\": \"#cd853f\",\n \"pink\": \"#ffc0cb\",\n \"plum\": \"#dda0dd\",\n \"powderblue\": \"#b0e0e6\",\n \"purple\": \"#800080\",\n \"red\": \"#ff0000\",\n \"rosybrown\": \"#bc8f8f\",\n \"royalblue\": \"#4169e1\",\n \"saddlebrown\": \"#8b4513\",\n \"salmon\": \"#fa8072\",\n \"sandybrown\": \"#f4a460\",\n \"seagreen\": \"#2e8b57\",\n \"seashell\": \"#fff5ee\",\n \"sienna\": \"#a0522d\",\n \"silver\": \"#c0c0c0\",\n \"skyblue\": \"#87ceeb\",\n \"slateblue\": \"#6a5acd\",\n \"slategray\": \"#708090\",\n \"snow\": \"#fffafa\",\n \"springgreen\": \"#00ff7f\",\n \"steelblue\": \"#4682b4\",\n \"tan\": \"#d2b48c\",\n \"teal\": \"#008080\",\n \"thistle\": \"#d8bfd8\",\n \"tomato\": \"#ff6347\",\n \"turquoise\": \"#40e0d0\",\n \"violet\": \"#ee82ee\",\n \"wheat\": \"#f5deb3\",\n \"white\": \"#ffffff\",\n \"whitesmoke\": \"#f5f5f5\",\n \"yellow\": \"#ffff00\",\n \"yellowgreen\": \"#9acd32\",\n \"darkgrey\": \"#a9a9a9\",\n \"darkslategrey\": \"#2f4f4f\",\n \"dimgrey\": \"#696969\",\n \"grey\": \"#808080\",\n \"lightgray\": \"#d3d3d3\",\n \"lightslategrey\": \"#778899\",\n \"slategrey\": \"#708090\"\n };\n return definedColorNames[colorName];\n }\n}\n\n\nexport default IGVColor;\n","// Support for oauth token based authorization\n// This class supports explicit setting of an oauth token either globally or for specific hosts.\n//\n// The variable oauth.google.access_token, which becomes igv.oauth.google.access_token on ES5 conversion is\n// supported for backward compatibility\n\nconst DEFAULT_HOST = \"googleapis\"\n\nclass Oauth {\n\n constructor() {\n this.oauthTokens = {}\n }\n\n\n setToken(token, host) {\n host = host || DEFAULT_HOST\n this.oauthTokens[host] = token\n }\n\n getToken(host) {\n host = host || DEFAULT_HOST\n let token\n for (let key of Object.keys(this.oauthTokens)) {\n const regex = wildcardToRegExp(key)\n if (regex.test(host)) {\n token = this.oauthTokens[key]\n break\n }\n }\n return token\n }\n\n removeToken(host) {\n host = host || DEFAULT_HOST\n for (let key of Object.keys(this.oauthTokens)) {\n const regex = wildcardToRegExp(key)\n if (regex.test(host)) {\n this.oauthTokens[key] = undefined\n }\n }\n }\n\n // Special object for google -- legacy support\n // google: {\n // setToken: function (token) {\n // oauth.setToken(token);\n // }\n // }\n}\n\n\n/**\n * Creates a RegExp from the given string, converting asterisks to .* expressions,\n * and escaping all other characters.\n *\n * credit https://gist.github.com/donmccurdy/6d073ce2c6f3951312dfa45da14a420f\n */\nfunction wildcardToRegExp(s) {\n return new RegExp('^' + s.split(/\\*+/).map(regExpEscape).join('.*') + '$')\n}\n\n/**\n * RegExp-escapes all characters in the given string.\n *\n * credit https://gist.github.com/donmccurdy/6d073ce2c6f3951312dfa45da14a420f\n */\nfunction regExpEscape(s) {\n return s.replace(/[|\\\\{}()[\\]^$+*?.]/g, '\\\\$&')\n}\n\nexport default Oauth\n","function isGoogleURL(url) {\n return (url.includes(\"googleapis\") && !url.includes(\"urlshortener\")) ||\n isGoogleStorageURL(url) ||\n isGoogleDriveURL(url)\n}\n\nfunction isGoogleStorageURL(url) {\n return url.startsWith(\"gs://\") ||\n url.startsWith(\"https://www.googleapis.com/storage\") ||\n url.startsWith(\"https://storage.cloud.google.com\") ||\n url.startsWith(\"https://storage.googleapis.com\");\n}\n\nfunction isGoogleDriveURL(url) {\n return url.indexOf(\"drive.google.com\") >= 0 || url.indexOf(\"www.googleapis.com/drive\") > 0\n}\n\n/**\n * Translate gs:// urls to https\n * See https://cloud.google.com/storage/docs/json_api/v1\n * @param gsUrl\n * @returns {string|*}\n */\nfunction translateGoogleCloudURL(gsUrl) {\n\n let {bucket, object} = parseBucketName(gsUrl);\n object = encode(object);\n\n const qIdx = gsUrl.indexOf('?');\n const paramString = (qIdx > 0) ? gsUrl.substring(qIdx) + \"&alt=media\" : \"?alt=media\";\n\n return `https://storage.googleapis.com/storage/v1/b/${bucket}/o/${object}${paramString}`\n}\n\n/**\n * Parse a google bucket and object name from a google storage URL. Known forms include\n *\n * gs://BUCKET_NAME/OBJECT_NAME\n * https://storage.googleapis.com/BUCKET_NAME/OBJECT_NAME\n * https://storage.googleapis.com/storage/v1/b/BUCKET_NAME/o/OBJECT_NAME\n * https://www.googleapis.com/storage/v1/b/BUCKET_NAME/o/OBJECT_NAME\"\n * https://storage.googleapis.com/download/storage/v1/b/BUCKET_NAME/o/OBJECT_NAME\n *\n * @param url\n */\nfunction parseBucketName(url) {\n\n let bucket;\n let object;\n\n if (url.startsWith(\"gs://\")) {\n const i = url.indexOf('/', 5);\n if (i >= 0) {\n bucket = url.substring(5, i);\n const qIdx = url.indexOf('?');\n object = (qIdx < 0) ? url.substring(i + 1) : url.substring(i + 1, qIdx);\n }\n\n } else if (url.startsWith(\"https://storage.googleapis.com\") || url.startsWith(\"https://storage.cloud.google.com\")) {\n const bucketIdx = url.indexOf(\"/v1/b/\", 8)\n if (bucketIdx > 0) {\n const objIdx = url.indexOf(\"/o/\", bucketIdx);\n if (objIdx > 0) {\n const queryIdx = url.indexOf(\"?\", objIdx);\n bucket = url.substring(bucketIdx + 6, objIdx);\n object = queryIdx > 0 ? url.substring(objIdx + 3, queryIdx) : url.substring(objIdx + 3);\n }\n\n } else {\n const idx1 = url.indexOf(\"/\", 8);\n const idx2 = url.indexOf(\"/\", idx1+1);\n const idx3 = url.indexOf(\"?\", idx2);\n if (idx2 > 0) {\n bucket = url.substring(idx1+1, idx2);\n object = idx3 < 0 ? url.substring(idx2+1) : url.substring(idx2+1, idx3);\n }\n }\n\n } else if (url.startsWith(\"https://www.googleapis.com/storage/v1/b\")) {\n const bucketIdx = url.indexOf(\"/v1/b/\", 8);\n const objIdx = url.indexOf(\"/o/\", bucketIdx);\n if (objIdx > 0) {\n const queryIdx = url.indexOf(\"?\", objIdx);\n bucket = url.substring(bucketIdx + 6, objIdx);\n object = queryIdx > 0 ? url.substring(objIdx + 3, queryIdx) : url.substring(objIdx + 3);\n }\n }\n\n if (bucket && object) {\n return {\n bucket, object\n }\n } else {\n throw Error(`Unrecognized Google Storage URI: ${url}`)\n }\n\n}\n\n/**\n * Percent a GCS object name. See https://cloud.google.com/storage/docs/request-endpoints\n * Specific characters to encode:\n * !, #, $, &, ', (, ), *, +, ,, /, :, ;, =, ?, @, [, ], and space characters.\n * @param obj\n */\n\nfunction encode(objectName) {\n\n let result = '';\n objectName.split('').forEach(function(letter) {\n if(encodings.has(letter)) {\n result += encodings.get(letter);\n } else {\n result += letter;\n }\n })\n return result;\n}\n\n//\t%23\t%24\t%25\t%26\t%27\t%28\t%29\t%2A\t%2B\t%2C\t%2F\t%3A\t%3B\t%3D\t%3F\t%40\t%5B\t%5D\nconst encodings = new Map();\nencodings.set(\"!\", \"%21\");\nencodings.set(\"#\", \"%23\");\nencodings.set(\"$\", \"%24\");\nencodings.set(\"%\", \"%25\");\nencodings.set(\"&\", \"%26\");\nencodings.set(\"'\", \"%27\");\nencodings.set(\"(\", \"%28\");\nencodings.set(\")\", \"%29\");\nencodings.set(\"*\", \"%2A\");\nencodings.set(\"+\", \"%2B\");\nencodings.set(\",\", \"%2C\");\nencodings.set(\"/\", \"%2F\");\nencodings.set(\":\", \"%3A\");\nencodings.set(\";\", \"%3B\");\nencodings.set(\"=\", \"%3D\");\nencodings.set(\"?\", \"%3F\");\nencodings.set(\"@\", \"%40\");\nencodings.set(\"[\", \"%5B\");\nencodings.set(\"]\", \"%5D\");\nencodings.set(\" \", \"%20\");\n\n// For testing\n//for(let [key, value] of encodings) {\n// const v2 = encodeURIComponent(key);\n// console.log(value + \" \" + v2);\n//}\n\nexport {\n isGoogleURL, isGoogleDriveURL, isGoogleStorageURL, translateGoogleCloudURL, parseBucketName\n}\n\n\n\n","// Convenience functions for the gapi oAuth library.\n// This wrapper is stateless -- this is important as multiple copies of this module might be present\n// in an application. All state is attached to the global google object.\n\nimport {isGoogleDriveURL, isGoogleStorageURL} from \"./googleUtils.js\"\n\nasync function init(config) {\n\n if (!(google.accounts.oauth2.initTokenClient)) {\n throw new Error(\"Google accounts token client not loaded (https://accounts.google.com/gsi/client)\")\n }\n\n if (isInitialized()) {\n throw new Error(\"Google client is already initialized\")\n }\n\n // Note: callback is added when accessToken is requested\n const codeClientConfig = {\n client_id: config.client_id,\n scope: config.scope || 'https://www.googleapis.com/auth/userinfo.profile',\n state: config.state || 'igv',\n error: (err) => {\n throw new Error(err.type)\n },\n hint: config.hint, // Optional\n hosted_domain: config.hosted_domain // Optional\n }\n\n const tokenClient = google.accounts.oauth2.initTokenClient(codeClientConfig)\n\n // Attach an object to keep igv state\n google.igv = {\n tokenClient: tokenClient,\n apiKey: config.apiKey\n }\n}\n\nfunction isInitialized() {\n return window.google && window.google.igv\n}\n\n/**\n * Return the current access token if the user is signed in, or undefined otherwise. This function does not\n * attempt a signIn or request any specfic scopes.\n *\n * @returns access_token || undefined\n */\nfunction getCurrentAccessToken() {\n return (isInitialized() && google.igv.tokenResponse && Date.now() < google.igv.tokenExpiresAt) ?\n google.igv.tokenResponse.access_token :\n undefined\n}\n\n/**\n * Return the of the currently logged in user, if any, as represented by the current access token. This does not force a login.*\n * @returns {Promise}\n */\nasync function getCurrentUserProfile() {\n const access_token = getCurrentAccessToken()\n if (access_token) {\n const endPoint = \"https://www.googleapis.com/oauth2/v1/userinfo?alt=json\"\n const response = await fetch(endPoint, {\n headers: {\n 'Authorization': `Bearer ${access_token}`\n }\n })\n return response.json()\n } else {\n return undefined\n }\n}\n\n\n/**\n * Return a promise for an access token for the given scope. If the user hasn't authorized the scope request it\n *\n * @param scope\n * @returns {Promise}\n */\nasync function getAccessToken(scope) {\n\n if (!isInitialized()) {\n throw Error(\"Google oAuth has not been initialized\")\n }\n\n if (google.igv.tokenResponse &&\n Date.now() < google.igv.tokenExpiresAt &&\n google.accounts.oauth2.hasGrantedAllScopes(google.igv.tokenResponse, scope)) {\n return google.igv.tokenResponse.access_token\n } else {\n const tokenClient = google.igv.tokenClient\n return new Promise((resolve, reject) => {\n try {\n // Settle this promise in the response callback for requestAccessToken()\n tokenClient.callback = (tokenResponse) => {\n if (tokenResponse.error !== undefined) {\n reject(tokenResponse)\n }\n google.igv.tokenResponse = tokenResponse\n google.igv.tokenExpiresAt = Date.now() + tokenResponse.expires_in * 1000\n resolve(tokenResponse.access_token)\n }\n tokenClient.requestAccessToken({scope})\n } catch (err) {\n console.log(err)\n }\n })\n }\n}\n\nasync function signIn(scope) {\n\n if (!isInitialized()) {\n throw Error(\"Google oAuth has not been initialized\")\n }\n\n scope = scope || 'https://www.googleapis.com/auth/userinfo.profile'\n await getAccessToken(scope)\n\n if (typeof google.igv.signInListener === 'function') {\n google.igv.signInListener(undefined !== google.igv.tokenResponse)\n\n }\n\n return google.igv.tokenResponse\n\n}\n\nasync function signOut() {\n\n if (!isInitialized()) {\n throw Error(\"Google oAuth has not been initialized\")\n }\n\n if (google.igv && google.igv.tokenResponse) {\n google.igv.tokenResponse = undefined\n }\n\n if (typeof google.igv.signInListener === 'function') {\n google.igv.signInListener(false)\n }\n}\n\nfunction signInListen(fn) {\n google.igv.signInListener = fn\n}\n\n// gapi.auth2.getAuthInstance().isSignedIn.listen(status => {\n// const user = gapi.auth2.getAuthInstance().currentUser.get()\n// queryGoogleAuthenticationStatus(user, status)\n// })\n\nfunction getScopeForURL(url) {\n if (isGoogleDriveURL(url)) {\n return \"https://www.googleapis.com/auth/drive.readonly\"\n } else if (isGoogleStorageURL(url)) {\n return \"https://www.googleapis.com/auth/devstorage.read_only\"\n } else {\n return 'https://www.googleapis.com/auth/userinfo.profile'\n }\n}\n\nfunction getApiKey() {\n return google.igv.apiKey\n}\n\n\nexport {\n init,\n getAccessToken,\n getCurrentAccessToken,\n getScopeForURL,\n getApiKey,\n isInitialized,\n signIn,\n signOut,\n getCurrentUserProfile,\n signInListen\n}\n\n","import {getAccessToken, getApiKey} from \"./googleAuth.js\"\n\n\n/**\n * Return information about a specific google drive URL\n *\n * @param googleDriveURL\n * @returns {Promise}\n */\nasync function getDriveFileInfo(googleDriveURL) {\n\n const id = getGoogleDriveFileID(googleDriveURL);\n let endPoint = \"https://www.googleapis.com/drive/v3/files/\" + id + \"?supportsTeamDrives=true\";\n const apiKey = getApiKey();\n if (apiKey) {\n endPoint += \"&key=\" + apiKey;\n }\n const response = await fetch(endPoint);\n let json = await response.json();\n if (json.error && json.error.code === 404) {\n let scope = \"https://www.googleapis.com/auth/drive.readonly\"\n const access_token = await getAccessToken(scope);\n if (access_token) {\n const response = await fetch(endPoint, {\n headers: {\n 'Authorization': `Bearer ${access_token}`\n }\n })\n json = await response.json();\n if (json.error) {\n throw Error(json.error);\n }\n } else {\n throw Error(json.error);\n }\n }\n return json;\n}\n\n/**\n * Return general Google Drive information for the currently logged in user*\n * *\n * @returns {Promise}\n */\nasync function getDriveInfo() {\n const access_token = await getAccessToken('https://www.googleapis.com/auth/drive.readonly')\n const endPoint = \"https://www.googleapis.com/drive/v3/about?fields=*\"\n const response = await fetch(endPoint, {\n headers: {\n 'Authorization': `Bearer ${access_token}`\n }\n })\n return response.json()\n}\n\n\nfunction getDriveDownloadURL(link) {\n // Return a google drive download url for the sharable link\n //https://drive.google.com/open?id=0B-lleX9c2pZFbDJ4VVRxakJzVGM\n //https://drive.google.com/file/d/1_FC4kCeO8E3V4dJ1yIW7A0sn1yURKIX-/view?usp=sharing\n var id = getGoogleDriveFileID(link);\n return id ? \"https://www.googleapis.com/drive/v3/files/\" + id + \"?alt=media&supportsTeamDrives=true\" : link;\n}\n\nfunction getGoogleDriveFileID(link) {\n\n //https://drive.google.com/file/d/1_FC4kCeO8E3V4dJ1yIW7A0sn1yURKIX-/view?usp=sharing\n //https://www.googleapis.com/drive/v3/files/1w-tvo6p1SH4p1OaQSVxpkV_EJgGIstWF?alt=media&supportsTeamDrives=true\"\n\n if (link.includes(\"/open?id=\")) {\n const i1 = link.indexOf(\"/open?id=\") + 9;\n const i2 = link.indexOf(\"&\");\n if (i1 > 0 && i2 > i1) {\n return link.substring(i1, i2)\n } else if (i1 > 0) {\n return link.substring(i1);\n }\n\n } else if (link.includes(\"/file/d/\")) {\n const i1 = link.indexOf(\"/file/d/\") + 8;\n const i2 = link.lastIndexOf(\"/\");\n return link.substring(i1, i2);\n\n } else if (link.startsWith(\"https://www.googleapis.com/drive\")) {\n let i1 = link.indexOf(\"/files/\")\n const i2 = link.indexOf(\"?\")\n if (i1 > 0) {\n i1 += 7;\n return i2 > 0 ?\n link.substring(i1, i2) :\n link.substring(i1)\n }\n }\n\n throw Error(\"Unknown Google Drive url format: \" + link);\n\n\n}\n\n\n\nexport {getDriveFileInfo, getDriveInfo, getDriveDownloadURL, getGoogleDriveFileID}","// The MIT License (MIT)\n// Adapted from https://github.com/JMPerez/promise-throttle\n//\n// Copyright (c) 2015 José M. Pérez\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n//\n\n\n'use strict';\n\n/**\n * @constructor\n * @param {Object} options A set op options to pass to the throttle function\n * @param {number} requestsPerSecond The amount of requests per second\n * the library will limit to\n */\nclass Throttle {\n constructor(options) {\n this.requestsPerSecond = options.requestsPerSecond || 10;\n this.lastStartTime = 0;\n this.queued = [];\n }\n\n /**\n * Adds a promise\n * @param {Function} async function to be executed\n * @param {Object} options A set of options.\n * @return {Promise} A promise\n */\n add(asyncFunction, options) {\n\n var self = this;\n return new Promise(function (resolve, reject) {\n self.queued.push({\n resolve: resolve,\n reject: reject,\n asyncFunction: asyncFunction,\n });\n self.dequeue();\n });\n }\n\n /**\n * Adds all the promises passed as parameters\n * @param {Function} promises An array of functions that return a promise\n * @param {Object} options A set of options.\n * @param {number} options.signal An AbortSignal object that can be used to abort the returned promise\n * @param {number} options.weight A \"weight\" of each operation resolving by array of promises\n * @return {Promise} A promise that succeeds when all the promises passed as options do\n */\n addAll(promises, options) {\n var addedPromises = promises.map(function (promise) {\n return this.add(promise, options);\n }.bind(this));\n\n return Promise.all(addedPromises);\n };\n\n /**\n * Dequeues a promise\n * @return {void}\n */\n dequeue() {\n if (this.queued.length > 0) {\n var now = new Date(),\n inc = (1000 / this.requestsPerSecond) + 1,\n elapsed = now - this.lastStartTime;\n\n if (elapsed >= inc) {\n this._execute();\n } else {\n // we have reached the limit, schedule a dequeue operation\n setTimeout(function () {\n this.dequeue();\n }.bind(this), inc - elapsed);\n }\n }\n }\n\n /**\n * Executes the promise\n * @private\n * @return {void}\n */\n async _execute() {\n this.lastStartTime = new Date();\n var candidate = this.queued.shift();\n const f = candidate.asyncFunction;\n try {\n const r = await f();\n candidate.resolve(r);\n } catch (e) {\n candidate.reject(e);\n }\n\n }\n\n\n}\n\nexport default Throttle;\n","/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2014 Broad Institute\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\nimport Oauth from \"./oauth.js\"\nimport {isFile} from './fileUtils.js'\nimport {parseUri} from './uriUtils.js'\nimport {ungzip, isgzipped, decodeDataURI} from './bgzf.js'\nimport * as GoogleUtils from './google-utils/googleUtils.js'\nimport * as GoogleAuth from './google-utils/googleAuth.js'\nimport * as GoogleDrive from './google-utils/googleDrive.js'\nimport Throttle from \"./throttle.js\"\n\nclass IGVXhr {\n\n constructor() {\n this.apiKey = undefined\n this.googleThrottle = new Throttle({\n requestsPerSecond: 8\n })\n this.RANGE_WARNING_GIVEN = false\n this.oauth = new Oauth()\n this.contentLengthMap = new Map()\n }\n\n setApiKey(key) {\n this.apiKey = key\n }\n\n async loadArrayBuffer(url, options) {\n options = options || {}\n if (!options.responseType) {\n options.responseType = \"arraybuffer\"\n }\n if (isFile(url)) {\n return this._loadFileSlice(url, options)\n } else {\n return this.load(url, options)\n }\n }\n\n async loadJson(url, options) {\n options = options || {}\n const method = options.method || (options.sendData ? \"POST\" : \"GET\")\n if (method === \"POST\") {\n options.contentType = \"application/json\"\n }\n const result = await this.loadString(url, options)\n if (result) {\n return JSON.parse(result)\n } else {\n return result\n }\n }\n\n async loadString(path, options) {\n options = options || {}\n if (path instanceof File) {\n return this._loadStringFromFile(path, options)\n } else {\n return this._loadStringFromUrl(path, options)\n }\n }\n\n async load(url, options) {\n\n options = options || {}\n const urlType = typeof url\n\n // Resolve functions, promises, and functions that return promises\n url = await (typeof url === 'function' ? url() : url)\n\n if (isFile(url)) {\n return this._loadFileSlice(url, options)\n } else if (typeof url.startsWith === 'function') { // Test for string\n if (url.startsWith(\"data:\")) {\n const buffer = decodeDataURI(url).buffer\n if (options.range) {\n const rangeEnd = options.range.size ? options.range.start + options.range.size : buffer.byteLength\n return buffer.slice(options.range.start, rangeEnd)\n } else {\n return buffer\n }\n } else {\n if (url.startsWith(\"https://drive.google.com\")) {\n url = GoogleDrive.getDriveDownloadURL(url)\n }\n if (GoogleUtils.isGoogleDriveURL(url) || url.startsWith(\"https://www.dropbox.com\")) {\n return this.googleThrottle.add(async () => {\n return this._loadURL(url, options)\n })\n } else {\n return this._loadURL(url, options)\n }\n }\n } else {\n throw Error(`url must be either a 'File', 'string', 'function', or 'Promise'. Actual type: ${urlType}`)\n }\n }\n\n async getContentLength(url, options) {\n if (!this.contentLengthMap.has(url)) {\n options = options || {}\n options.method = 'HEAD'\n options.GET_CONTENT_LENGTH = true\n const contentLengthString = await this._loadURL(url, options)\n const contentLength = contentLengthString ? Number.parseInt(contentLengthString) : -1\n this.contentLengthMap.set(url, contentLength)\n }\n return this.contentLengthMap.get(url)\n }\n\n async _loadURL(url, options) {\n\n const self = this\n\n //console.log(`${Date.now()} ${url}`)\n url = mapUrl(url)\n\n options = options || {}\n\n let oauthToken = options.oauthToken || this.getOauthToken(url)\n if (oauthToken) {\n oauthToken = await (typeof oauthToken === 'function' ? oauthToken() : oauthToken)\n }\n\n let contentLength = -1\n if (options.range && !isAmazonV4Signed(url) && !isGoogleStorageSigned(url)) {\n contentLength = await this.getContentLength(url)\n }\n\n return new Promise(function (resolve, reject) {\n\n // Various Google tansformations\n if (GoogleUtils.isGoogleURL(url) && !isGoogleStorageSigned(url)) {\n if (GoogleUtils.isGoogleStorageURL(url)) {\n url = GoogleUtils.translateGoogleCloudURL(url)\n }\n url = addApiKey(url)\n\n if (GoogleUtils.isGoogleDriveURL(url)) {\n addTeamDrive(url)\n }\n\n // If we have an access token try it, but don't force a signIn or request for scopes yet\n if (!oauthToken) {\n oauthToken = getCurrentGoogleAccessToken()\n }\n }\n\n const headers = options.headers || {}\n if (oauthToken) {\n addOauthHeaders(headers, oauthToken)\n }\n const range = options.range\n\n\n const xhr = new XMLHttpRequest()\n const sendData = options.sendData || options.body\n const method = options.method || (sendData ? \"POST\" : \"GET\")\n const responseType = options.responseType\n const contentType = options.contentType\n const mimeType = options.mimeType\n\n xhr.open(method, url)\n\n if (options.timeout) {\n xhr.timeout = options.timeout\n }\n\n if (range) {\n let rangeEnd = \"\"\n if (range.size) {\n rangeEnd = range.start + range.size - 1\n if (contentLength > 0) {\n rangeEnd = Math.min(rangeEnd, contentLength - 1)\n }\n }\n xhr.setRequestHeader(\"Range\", \"bytes=\" + range.start + \"-\" + rangeEnd)\n // xhr.setRequestHeader(\"Cache-Control\", \"no-cache\"); <= This can cause CORS issues, disabled for now\n }\n if (contentType) {\n xhr.setRequestHeader(\"Content-Type\", contentType)\n }\n if (mimeType) {\n xhr.overrideMimeType(mimeType)\n }\n if (responseType) {\n xhr.responseType = responseType\n }\n if (headers) {\n for (let key of Object.keys(headers)) {\n const value = headers[key]\n xhr.setRequestHeader(key, value)\n }\n }\n\n // NOTE: using withCredentials with servers that return \"*\" for access-allowed-origin will fail\n if (options.withCredentials === true) {\n xhr.withCredentials = true\n }\n\n xhr.onload = async function (event) {\n\n if (options.GET_CONTENT_LENGTH) {\n resolve(xhr.getResponseHeader('content-length'))\n }\n\n // when the url points to a local file, the status is 0 but that is not an error\n if (xhr.status === 0 || (xhr.status >= 200 && xhr.status <= 300)) {\n if (range && xhr.status !== 206 && range.start !== 0) {\n // For small files a range starting at 0 can return the whole file => 200\n // Provide just the slice we asked for, throw out the rest quietly\n // If file is large warn user\n if (xhr.response.length > 100000 && !self.RANGE_WARNING_GIVEN) {\n alert(`Warning: Range header ignored for URL: ${url}. This can have severe performance impacts.`)\n }\n resolve(xhr.response.slice(range.start, range.start + range.size))\n\n } else {\n resolve(xhr.response)\n }\n } else if ((typeof gapi !== \"undefined\") &&\n ((xhr.status === 404 || xhr.status === 401 || xhr.status === 403) &&\n GoogleUtils.isGoogleURL(url)) &&\n !options.retries) {\n tryGoogleAuth()\n\n } else {\n if (xhr.status === 403) {\n handleError(\"Access forbidden: \" + url)\n } else if (xhr.status === 416) {\n // Tried to read off the end of the file. This shouldn't happen, but if it does return an\n handleError(\"Unsatisfiable range\")\n } else {\n handleError(xhr.status)\n }\n }\n }\n\n\n xhr.onerror = function (event) {\n if (GoogleUtils.isGoogleURL(url) && !options.retries) {\n tryGoogleAuth()\n } else {\n handleError(\"Error accessing resource: \" + url + \" Status: \" + xhr.status)\n }\n }\n\n xhr.ontimeout = function (event) {\n handleError(\"Timed out\")\n }\n\n xhr.onabort = function (event) {\n console.log(\"Aborted\")\n reject(event)\n }\n\n try {\n xhr.send(sendData)\n } catch (e) {\n if (GoogleUtils.isGoogleURL(url) && !options.retries) {\n tryGoogleAuth()\n } else {\n handleError(e)\n }\n }\n\n\n function handleError(error) {\n if (reject) {\n reject(error)\n } else {\n throw error\n }\n }\n\n async function tryGoogleAuth() {\n try {\n const accessToken = await fetchGoogleAccessToken(url)\n options.retries = 1\n options.oauthToken = accessToken\n const response = await self.load(url, options)\n resolve(response)\n } catch (e) {\n if (e.error) {\n const msg = e.error.startsWith(\"popup_blocked\") ?\n \"Google login popup blocked by browser.\" :\n e.error\n alert(msg)\n } else {\n handleError(e)\n }\n }\n }\n })\n\n }\n\n async _loadFileSlice(localfile, options) {\n\n let blob = (options && options.range) ?\n localfile.slice(options.range.start, options.range.start + options.range.size) :\n localfile\n\n const arrayBuffer = await blob.arrayBuffer()\n\n if (\"arraybuffer\" === options.responseType) {\n return arrayBuffer\n } else {\n return arrayBufferToString(arrayBuffer)\n }\n }\n\n async _loadStringFromFile(localfile, options) {\n\n const blob = options.range ? localfile.slice(options.range.start, options.range.start + options.range.size) : localfile\n const arrayBuffer = await blob.arrayBuffer()\n return arrayBufferToString(arrayBuffer)\n }\n\n async _loadStringFromUrl(url, options) {\n\n options = options || {}\n options.responseType = \"arraybuffer\"\n const data = await this.load(url, options)\n return arrayBufferToString(data)\n }\n\n /**\n * Explicity set an oAuth token for use with given host. If host is undefined token is used for google api access*\n * @param token\n * @param host\n */\n setOauthToken(token, host) {\n this.oauth.setToken(token, host)\n }\n\n /**\n * Return an oauth token for the URL if we have one. This method does not force sign-in, and the token may\n * or may not be valid. Sign-in is triggered on request failure.\n * *\n * @param url\n * @returns {*}\n */\n getOauthToken(url) {\n\n // Google is the default provider, don't try to parse host for google URLs\n const host = GoogleUtils.isGoogleURL(url) ?\n undefined :\n parseUri(url).host\n\n // First check the explicit settings (i.e. token set through the API)\n let token = this.oauth.getToken(host)\n if (token) {\n return token\n } else if (host === undefined) {\n // Now try Google oauth tokens previously obtained. This will return undefined if google oauth is not\n // configured.\n const googleToken = getCurrentGoogleAccessToken()\n if (googleToken && googleToken.expires_at > Date.now()) {\n return googleToken.access_token\n }\n }\n }\n}\n\nfunction isGoogleStorageSigned(url) {\n return url.indexOf(\"X-Goog-Signature\") > -1\n}\n\n\n/**\n * Return a Google oAuth token, triggering a sign in if required. This method should not be called until we know\n * a token is required, that is until we've tried the url and received a 401, 403, or 404.\n *\n * @param url\n * @returns the oauth token\n */\nasync function fetchGoogleAccessToken(url) {\n if (GoogleAuth.isInitialized()) {\n const scope = GoogleAuth.getScopeForURL(url)\n const access_token = await GoogleAuth.getAccessToken(scope)\n return access_token\n } else {\n throw Error(\n `Authorization is required, but Google oAuth has not been initalized. Contact your site administrator for assistance.`)\n }\n}\n\n/**\n * Return the current google access token, if one exists. Do not triger signOn or request additional scopes.\n * @returns {undefined|access_token}\n */\nfunction getCurrentGoogleAccessToken() {\n if (GoogleAuth.isInitialized()) {\n const access_token = GoogleAuth.getCurrentAccessToken()\n return access_token\n } else {\n return undefined\n }\n}\n\nfunction addOauthHeaders(headers, acToken) {\n if (acToken) {\n headers[\"Cache-Control\"] = \"no-cache\"\n headers[\"Authorization\"] = \"Bearer \" + acToken\n }\n return headers\n}\n\n\nfunction addApiKey(url) {\n let apiKey = igvxhr.apiKey\n if (!apiKey && typeof gapi !== \"undefined\") {\n apiKey = gapi.apiKey\n }\n if (apiKey !== undefined && !url.includes(\"key=\")) {\n const paramSeparator = url.includes(\"?\") ? \"&\" : \"?\"\n url = url + paramSeparator + \"key=\" + apiKey\n }\n return url\n}\n\nfunction addTeamDrive(url) {\n if (url.includes(\"supportsTeamDrive\")) {\n return url\n } else {\n const paramSeparator = url.includes(\"?\") ? \"&\" : \"?\"\n url = url + paramSeparator + \"supportsTeamDrive=true\"\n }\n}\n\n/**\n * Perform some well-known url mappings.\n * @param url\n */\nfunction mapUrl(url) {\n\n if (url.startsWith(\"https://www.dropbox.com\")) {\n return url.replace(\"//www.dropbox.com\", \"//dl.dropboxusercontent.com\")\n } else if (url.startsWith(\"https://drive.google.com\")) {\n return GoogleDrive.getDriveDownloadURL(url)\n } else if (url.includes(\"//www.broadinstitute.org/igvdata\")) {\n return url.replace(\"//www.broadinstitute.org/igvdata\", \"//data.broadinstitute.org/igvdata\")\n } else if (url.includes(\"//igvdata.broadinstitute.org\")) {\n return url.replace(\"//igvdata.broadinstitute.org\", \"//s3.amazonaws.com/igv.broadinstitute.org\")\n } else if (url.includes(\"//igv.genepattern.org\")) {\n return url.replace(\"//igv.genepattern.org\", \"//igv-genepattern-org.s3.amazonaws.com\")\n } else if (url.startsWith(\"ftp://ftp.ncbi.nlm.nih.gov/geo\")) {\n return url.replace(\"ftp://\", \"https://\")\n } else {\n return url\n }\n}\n\n\nfunction arrayBufferToString(arraybuffer) {\n\n let plain\n if (isgzipped(arraybuffer)) {\n plain = ungzip(arraybuffer)\n } else {\n plain = new Uint8Array(arraybuffer)\n }\n\n if ('TextDecoder' in getGlobalObject()) {\n return new TextDecoder().decode(plain)\n } else {\n return decodeUTF8(plain)\n }\n}\n\n/**\n * Use when TextDecoder is not available (primarily IE).\n *\n * From: https://gist.github.com/Yaffle/5458286\n *\n * @param octets\n * @returns {string}\n */\nfunction decodeUTF8(octets) {\n var string = \"\"\n var i = 0\n while (i < octets.length) {\n var octet = octets[i]\n var bytesNeeded = 0\n var codePoint = 0\n if (octet <= 0x7F) {\n bytesNeeded = 0\n codePoint = octet & 0xFF\n } else if (octet <= 0xDF) {\n bytesNeeded = 1\n codePoint = octet & 0x1F\n } else if (octet <= 0xEF) {\n bytesNeeded = 2\n codePoint = octet & 0x0F\n } else if (octet <= 0xF4) {\n bytesNeeded = 3\n codePoint = octet & 0x07\n }\n if (octets.length - i - bytesNeeded > 0) {\n var k = 0\n while (k < bytesNeeded) {\n octet = octets[i + k + 1]\n codePoint = (codePoint << 6) | (octet & 0x3F)\n k += 1\n }\n } else {\n codePoint = 0xFFFD\n bytesNeeded = octets.length - i\n }\n string += String.fromCodePoint(codePoint)\n i += bytesNeeded + 1\n }\n return string\n}\n\n\nfunction getGlobalObject() {\n if (typeof self !== 'undefined') {\n return self\n }\n if (typeof global !== 'undefined') {\n return global\n } else {\n return window\n }\n}\n\nfunction isAmazonV4Signed(url) {\n return url.indexOf(\"X-Amz-Signature\") > -1\n}\n\n\nconst igvxhr = new IGVXhr()\n\nexport default igvxhr\nexport {arrayBufferToString, mapUrl}\n","/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2014 Broad Institute\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\n/** An implementation of an interval tree, following the explanation.\n * from CLR.\n *\n * Public interface:\n * Constructor IntervalTree\n * Insertion insert\n * Search findOverlapping\n */\n\nvar BLACK = 1;\nvar RED = 2;\n\nvar NIL = {}\nNIL.color = BLACK;\nNIL.parent = NIL;\nNIL.left = NIL;\nNIL.right = NIL;\n\n\nclass IntervalTree {\n\n constructor() {\n this.root = NIL;\n }\n\n insert(start, end, value) {\n\n var interval = new Interval(start, end, value);\n var x = new Node(interval);\n this.treeInsert(x);\n x.color = RED;\n while (x !== this.root && x.parent.color === RED) {\n if (x.parent === x.parent.parent.left) {\n let y = x.parent.parent.right;\n if (y.color === RED) {\n x.parent.color = BLACK;\n y.color = BLACK;\n x.parent.parent.color = RED;\n x = x.parent.parent;\n } else {\n if (x === x.parent.right) {\n x = x.parent;\n leftRotate.call(this, x);\n }\n x.parent.color = BLACK;\n x.parent.parent.color = RED;\n rightRotate.call(this, x.parent.parent);\n }\n } else {\n let y = x.parent.parent.left;\n if (y.color === RED) {\n x.parent.color = BLACK;\n y.color = BLACK;\n x.parent.parent.color = RED;\n x = x.parent.parent;\n } else {\n if (x === x.parent.left) {\n x = x.parent;\n rightRotate.call(this, x);\n }\n x.parent.color = BLACK;\n x.parent.parent.color = RED;\n leftRotate.call(this, x.parent.parent);\n }\n }\n }\n this.root.color = BLACK;\n }\n\n /**\n *\n * @param start - query interval\n * @param end - query interval\n * @returns Array of all intervals overlapping the query region\n */\n findOverlapping(start, end) {\n\n\n var searchInterval = new Interval(start, end, 0);\n\n if (this.root === NIL) return [];\n\n var intervals = searchAll.call(this, searchInterval, this.root, []);\n\n if (intervals.length > 1) {\n intervals.sort(function (i1, i2) {\n return i1.low - i2.low;\n });\n }\n\n return intervals;\n }\n\n /**\n * Dump info on intervals to console. For debugging.\n */\n logIntervals() {\n\n logNode(this.root, 0);\n\n function logNode(node, indent) {\n\n var space = \"\";\n for (var i = 0; i < indent; i++) space += \" \";\n console.log(space + node.interval.low + \" \" + node.interval.high); // + \" \" + (node.interval.value ? node.interval.value : \" null\"));\n\n indent += 5;\n\n if (node.left !== NIL) logNode(node.left, indent);\n if (node.right !== NIL) logNode(node.right, indent);\n }\n\n }\n\n mapIntervals(func) {\n\n applyInterval(this.root);\n\n function applyInterval(node) {\n\n func(node.interval);\n\n if (node.left !== NIL) applyInterval(node.left);\n if (node.right !== NIL) applyInterval(node.right);\n }\n }\n\n\n /**\n * Note: Does not maintain RB constraints, this is done post insert\n *\n * @param x a Node\n */\n treeInsert(x) {\n var node = this.root;\n var y = NIL;\n while (node !== NIL) {\n y = node;\n if (x.interval.low <= node.interval.low) {\n node = node.left;\n } else {\n node = node.right;\n }\n }\n x.parent = y;\n\n if (y === NIL) {\n this.root = x;\n x.left = x.right = NIL;\n } else {\n if (x.interval.low <= y.interval.low) {\n y.left = x;\n } else {\n y.right = x;\n }\n }\n\n applyUpdate.call(this, x);\n }\n}\n\nfunction searchAll(interval, node, results) {\n\n if (node.interval.overlaps(interval)) {\n results.push(node.interval);\n }\n\n if (node.left !== NIL && node.left.max >= interval.low) {\n searchAll.call(this, interval, node.left, results);\n }\n\n if (node.right !== NIL && node.right.min <= interval.high) {\n searchAll.call(this, interval, node.right, results);\n }\n\n return results;\n}\n\nfunction leftRotate(x) {\n var y = x.right;\n x.right = y.left;\n if (y.left !== NIL) {\n y.left.parent = x;\n }\n y.parent = x.parent;\n if (x.parent === NIL) {\n this.root = y;\n } else {\n if (x.parent.left === x) {\n x.parent.left = y;\n } else {\n x.parent.right = y;\n }\n }\n y.left = x;\n x.parent = y;\n\n applyUpdate.call(this, x);\n // no need to apply update on y, since it'll y is an ancestor\n // of x, and will be touched by applyUpdate().\n}\n\n\nfunction rightRotate(x) {\n var y = x.left;\n x.left = y.right;\n if (y.right !== NIL) {\n y.right.parent = x;\n }\n y.parent = x.parent;\n if (x.parent === NIL) {\n this.root = y;\n } else {\n if (x.parent.right === x) {\n x.parent.right = y;\n } else {\n x.parent.left = y;\n }\n }\n y.right = x;\n x.parent = y;\n\n\n applyUpdate.call(this, x);\n // no need to apply update on y, since it'll y is an ancestor\n // of x, and will be touched by applyUpdate().\n}\n\n\n// Applies the statistic update on the node and its ancestors.\nfunction applyUpdate(node) {\n while (node !== NIL) {\n var nodeMax = node.left.max > node.right.max ? node.left.max : node.right.max;\n var intervalHigh = node.interval.high;\n node.max = nodeMax > intervalHigh ? nodeMax : intervalHigh;\n\n var nodeMin = node.left.min < node.right.min ? node.left.min : node.right.min;\n var intervalLow = node.interval.low;\n node.min = nodeMin < intervalLow ? nodeMin : intervalLow;\n\n node = node.parent;\n }\n}\n\n\nclass Interval {\n constructor(low, high, value) {\n this.low = low;\n this.high = high;\n this.value = value;\n }\n\n equals(other) {\n if (!other) {\n return false;\n }\n if (this === other) {\n return true;\n }\n return (this.low === other.low &&\n this.high === other.high);\n\n }\n\n compareTo(other) {\n if (this.low < other.low)\n return -1;\n if (this.low > other.low)\n return 1;\n\n if (this.high < other.high)\n return -1;\n if (this.high > other.high)\n return 1;\n\n return 0;\n }\n\n /**\n * Returns true if this interval overlaps the other.\n */\n overlaps(other) {\n return (this.low <= other.high && other.low <= this.high);\n }\n}\n\nfunction Node(interval) {\n this.parent = NIL;\n this.left = NIL;\n this.right = NIL;\n this.interval = interval;\n this.color = RED;\n}\n\n\n//\n//\n// function minimum(node) {\n// while (node.left != NIL) {\n// node = node.left;\n// }\n// return node;\n// }\n//\n//\n// function maximum(node) {\n//\n// while (node.right != NIL) {\n// node = node.right;\n// }\n// return node;\n// }\n//\n//\n// function successor(x) {\n//\n// if (x.right != NIL) {\n// return minimum(x.right);\n// }\n// var y = x.parent;\n// while (y != NIL && x == y.right) {\n// x = y;\n// y = y.parent;\n// }\n// return y;\n// }\n//\n//\n// function predecessor(x) {\n// if (x.left != NIL) {\n// return maximum(x.left);\n// }\n// var y = x.parent;\n// while (y != NIL && x == y.left) {\n// x = y;\n// y = y.parent;\n// }\n// return y;\n// }\n//\n//\n//\n// allRedNodesFollowConstraints = function (node) {\n// if (node == NIL)\n// return true;\n//\n// if (node.color == BLACK) {\n// return (this.allRedNodesFollowConstraints(node.left) &&\n// this.allRedNodesFollowConstraints(node.right));\n// }\n//\n// // At this point, we know we're on a RED node.\n// return (node.left.color == BLACK &&\n// node.right.color == BLACK &&\n// this.allRedNodesFollowConstraints(node.left) &&\n// this.allRedNodesFollowConstraints(node.right));\n// }\n//\n//\n// // Check that both ends are equally balanced in terms of black height.\n// isBalancedBlackHeight = function (node) {\n// if (node == NIL)\n// return true;\n// return (blackHeight(node.left) == blackHeight(node.right) &&\n// this.isBalancedBlackHeight(node.left) &&\n// this.isBalancedBlackHeight(node.right));\n// }\n//\n//\n// // The black height of a node should be left/right equal.\n// blackHeight = function (node) {\n// if (node == NIL)\n// return 0;\n// var leftBlackHeight = blackHeight(node.left);\n// if (node.color == BLACK) {\n// return leftBlackHeight + 1;\n// } else {\n// return leftBlackHeight;\n// }\n// }\n\n\n/**\n * Test code: make sure that the tree has all the properties\n * defined by Red Black trees and interval trees\n *

\n * o. Root is black.\n *

\n * o. NIL is black.\n *

\n * o. Red nodes have black children.\n *

\n * o. Every path from root to leaves contains the same number of\n * black nodes.\n *

\n * o. getMax(node) is the maximum of any interval rooted at that node..\n *

\n * This code is expensive, and only meant to be used for\n * assertions and testing.\n */\n//\n// isValid = function () {\n// if (this.root.color != BLACK) {\n// logger.warn(\"root color is wrong\");\n// return false;\n// }\n// if (NIL.color != BLACK) {\n// logger.warn(\"NIL color is wrong\");\n// return false;\n// }\n// if (allRedNodesFollowConstraints(this.root) == false) {\n// logger.warn(\"red node doesn't follow constraints\");\n// return false;\n// }\n// if (isBalancedBlackHeight(this.root) == false) {\n// logger.warn(\"black height unbalanced\");\n// return false;\n// }\n//\n// return hasCorrectMaxFields(this.root) &&\n// hasCorrectMinFields(this.root);\n// }\n//\n//\n// hasCorrectMaxFields = function (node) {\n// if (node == NIL)\n// return true;\n// return (getRealMax(node) == (node.max) &&\n// this.hasCorrectMaxFields(node.left) &&\n// this.hasCorrectMaxFields(node.right));\n// }\n//\n//\n// hasCorrectMinFields = function (node) {\n// if (node == NIL)\n// return true;\n// return (getRealMin(node) == (node.min) &&\n// this.hasCorrectMinFields(node.left) &&\n// this.hasCorrectMinFields(node.right));\n// }\n\nexport default IntervalTree;\n","/*!\n * jQuery JavaScript Library v3.3.1 -ajax,-ajax/jsonp,-ajax/load,-ajax/parseXML,-ajax/script,-ajax/var/location,-ajax/var/nonce,-ajax/var/rquery,-ajax/xhr,-manipulation/_evalUrl,-event/ajax,-effects,-effects/Tween,-effects/animatedSelector\n * https://jquery.com/\n *\n * Includes Sizzle.js\n * https://sizzlejs.com/\n *\n * Copyright JS Foundation and other contributors\n * Released under the MIT license\n * https://jquery.org/license\n *\n * Date: 2018-01-20T17:24Z\n */\n\nvar arr = [];\n\nvar document$1 = window.document;\n\nvar getProto = Object.getPrototypeOf;\n\nvar slice = arr.slice;\n\nvar concat = arr.concat;\n\nvar push = arr.push;\n\nvar indexOf = arr.indexOf;\n\nvar class2type = {};\n\nvar toString$3 = class2type.toString;\n\nvar hasOwn = class2type.hasOwnProperty;\n\nvar fnToString = hasOwn.toString;\n\nvar ObjectFunctionString = fnToString.call(Object);\n\nvar support = {};\n\nvar isFunction = function isFunction(obj) {\n\n // Support: Chrome <=57, Firefox <=52\n // In some browsers, typeof returns \"function\" for HTML elements\n // (i.e., `typeof document.createElement( \"object\" ) === \"function\"`).\n // We don't want to classify *any* DOM node as a function.\n return typeof obj === \"function\" && typeof obj.nodeType !== \"number\";\n};\n\n\nvar isWindow = function isWindow(obj) {\n return obj != null && obj === obj.window;\n};\n\n\nvar preservedScriptAttributes = {\n type: true,\n src: true,\n noModule: true\n};\n\nfunction DOMEval(code, doc, node) {\n doc = doc || document$1;\n\n var i,\n script = doc.createElement(\"script\");\n\n script.text = code;\n if (node) {\n for (i in preservedScriptAttributes) {\n if (node[i]) {\n script[i] = node[i];\n }\n }\n }\n doc.head.appendChild(script).parentNode.removeChild(script);\n}\n\n\nfunction toType(obj) {\n if (obj == null) {\n return obj + \"\";\n }\n\n // Support: Android <=2.3 only (functionish RegExp)\n return typeof obj === \"object\" || typeof obj === \"function\" ?\n class2type[toString$3.call(obj)] || \"object\" :\n typeof obj;\n}\n\n// global Symbol\n// Defining this global in .eslintrc.json would create a danger of using the global\n// unguarded in another place, it seems safer to define global only for this module\n\n\nvar\n version$1 = \"3.3.1 -ajax,-ajax/jsonp,-ajax/load,-ajax/parseXML,-ajax/script,-ajax/var/location,-ajax/var/nonce,-ajax/var/rquery,-ajax/xhr,-manipulation/_evalUrl,-event/ajax,-effects,-effects/Tween,-effects/animatedSelector\",\n\n // Define a local copy of jQuery\n jQuery = function (selector, context) {\n\n // The jQuery object is actually just the init constructor 'enhanced'\n // Need init if jQuery is called (just allow error to be thrown if not included)\n return new jQuery.fn.init(selector, context);\n },\n\n // Support: Android <=4.0 only\n // Make sure we trim BOM and NBSP\n rtrim = /^[\\s\\uFEFF\\xA0]+|[\\s\\uFEFF\\xA0]+$/g;\n\njQuery.fn = jQuery.prototype = {\n\n // The current version of jQuery being used\n jquery: version$1,\n\n constructor: jQuery,\n\n // The default length of a jQuery object is 0\n length: 0,\n\n toArray: function () {\n return slice.call(this);\n },\n\n // Get the Nth element in the matched element set OR\n // Get the whole matched element set as a clean array\n get: function (num) {\n\n // Return all the elements in a clean array\n if (num == null) {\n return slice.call(this);\n }\n\n // Return just the one element from the set\n return num < 0 ? this[num + this.length] : this[num];\n },\n\n // Take an array of elements and push it onto the stack\n // (returning the new matched element set)\n pushStack: function (elems) {\n\n // Build a new jQuery matched element set\n var ret = jQuery.merge(this.constructor(), elems);\n\n // Add the old object onto the stack (as a reference)\n ret.prevObject = this;\n\n // Return the newly-formed element set\n return ret;\n },\n\n // Execute a callback for every element in the matched set.\n each: function (callback) {\n return jQuery.each(this, callback);\n },\n\n map: function (callback) {\n return this.pushStack(jQuery.map(this, function (elem, i) {\n return callback.call(elem, i, elem);\n }));\n },\n\n slice: function () {\n return this.pushStack(slice.apply(this, arguments));\n },\n\n first: function () {\n return this.eq(0);\n },\n\n last: function () {\n return this.eq(-1);\n },\n\n eq: function (i) {\n var len = this.length,\n j = +i + (i < 0 ? len : 0);\n return this.pushStack(j >= 0 && j < len ? [this[j]] : []);\n },\n\n end: function () {\n return this.prevObject || this.constructor();\n },\n\n // For internal use only.\n // Behaves like an Array's method, not like a jQuery method.\n push: push,\n sort: arr.sort,\n splice: arr.splice\n};\n\njQuery.extend = jQuery.fn.extend = function () {\n var options, name, src, copy, copyIsArray, clone,\n target = arguments[0] || {},\n i = 1,\n length = arguments.length,\n deep = false;\n\n // Handle a deep copy situation\n if (typeof target === \"boolean\") {\n deep = target;\n\n // Skip the boolean and the target\n target = arguments[i] || {};\n i++;\n }\n\n // Handle case when target is a string or something (possible in deep copy)\n if (typeof target !== \"object\" && !isFunction(target)) {\n target = {};\n }\n\n // Extend jQuery itself if only one argument is passed\n if (i === length) {\n target = this;\n i--;\n }\n\n for (; i < length; i++) {\n\n // Only deal with non-null/undefined values\n if ((options = arguments[i]) != null) {\n\n // Extend the base object\n for (name in options) {\n src = target[name];\n copy = options[name];\n\n // Prevent never-ending loop\n if (target === copy) {\n continue;\n }\n\n // Recurse if we're merging plain objects or arrays\n if (deep && copy && (jQuery.isPlainObject(copy) ||\n (copyIsArray = Array.isArray(copy)))) {\n\n if (copyIsArray) {\n copyIsArray = false;\n clone = src && Array.isArray(src) ? src : [];\n\n } else {\n clone = src && jQuery.isPlainObject(src) ? src : {};\n }\n\n // Never move original objects, clone them\n target[name] = jQuery.extend(deep, clone, copy);\n\n // Don't bring in undefined values\n } else if (copy !== undefined) {\n target[name] = copy;\n }\n }\n }\n }\n\n // Return the modified object\n return target;\n};\n\njQuery.extend({\n\n // Unique for each copy of jQuery on the page\n expando: \"jQuery\" + (version$1 + Math.random()).replace(/\\D/g, \"\"),\n\n // Assume jQuery is ready without the ready module\n isReady: true,\n\n error: function (msg) {\n throw new Error(msg);\n },\n\n noop: function () {\n },\n\n isPlainObject: function (obj) {\n var proto, Ctor;\n\n // Detect obvious negatives\n // Use toString instead of jQuery.type to catch host objects\n if (!obj || toString$3.call(obj) !== \"[object Object]\") {\n return false;\n }\n\n proto = getProto(obj);\n\n // Objects with no prototype (e.g., `Object.create( null )`) are plain\n if (!proto) {\n return true;\n }\n\n // Objects with prototype are plain iff they were constructed by a global Object function\n Ctor = hasOwn.call(proto, \"constructor\") && proto.constructor;\n return typeof Ctor === \"function\" && fnToString.call(Ctor) === ObjectFunctionString;\n },\n\n isEmptyObject: function (obj) {\n\n /* eslint-disable no-unused-vars */\n // See https://github.com/eslint/eslint/issues/6125\n var name;\n\n for (name in obj) {\n return false;\n }\n return true;\n },\n\n // Evaluates a script in a global context\n globalEval: function (code) {\n DOMEval(code);\n },\n\n each: function (obj, callback) {\n var length, i = 0;\n\n if (isArrayLike(obj)) {\n length = obj.length;\n for (; i < length; i++) {\n if (callback.call(obj[i], i, obj[i]) === false) {\n break;\n }\n }\n } else {\n for (i in obj) {\n if (callback.call(obj[i], i, obj[i]) === false) {\n break;\n }\n }\n }\n\n return obj;\n },\n\n // Support: Android <=4.0 only\n trim: function (text) {\n return text == null ?\n \"\" :\n (text + \"\").replace(rtrim, \"\");\n },\n\n // results is for internal usage only\n makeArray: function (arr, results) {\n var ret = results || [];\n\n if (arr != null) {\n if (isArrayLike(Object(arr))) {\n jQuery.merge(ret,\n typeof arr === \"string\" ?\n [arr] : arr\n );\n } else {\n push.call(ret, arr);\n }\n }\n\n return ret;\n },\n\n inArray: function (elem, arr, i) {\n return arr == null ? -1 : indexOf.call(arr, elem, i);\n },\n\n // Support: Android <=4.0 only, PhantomJS 1 only\n // push.apply(_, arraylike) throws on ancient WebKit\n merge: function (first, second) {\n var len = +second.length,\n j = 0,\n i = first.length;\n\n for (; j < len; j++) {\n first[i++] = second[j];\n }\n\n first.length = i;\n\n return first;\n },\n\n grep: function (elems, callback, invert) {\n var callbackInverse,\n matches = [],\n i = 0,\n length = elems.length,\n callbackExpect = !invert;\n\n // Go through the array, only saving the items\n // that pass the validator function\n for (; i < length; i++) {\n callbackInverse = !callback(elems[i], i);\n if (callbackInverse !== callbackExpect) {\n matches.push(elems[i]);\n }\n }\n\n return matches;\n },\n\n // arg is for internal usage only\n map: function (elems, callback, arg) {\n var length, value,\n i = 0,\n ret = [];\n\n // Go through the array, translating each of the items to their new values\n if (isArrayLike(elems)) {\n length = elems.length;\n for (; i < length; i++) {\n value = callback(elems[i], i, arg);\n\n if (value != null) {\n ret.push(value);\n }\n }\n\n // Go through every key on the object,\n } else {\n for (i in elems) {\n value = callback(elems[i], i, arg);\n\n if (value != null) {\n ret.push(value);\n }\n }\n }\n\n // Flatten any nested arrays\n return concat.apply([], ret);\n },\n\n // A global GUID counter for objects\n guid: 1,\n\n // jQuery.support is not used in Core but other projects attach their\n // properties to it so it needs to exist.\n support: support\n});\n\nif (typeof Symbol === \"function\") {\n jQuery.fn[Symbol.iterator] = arr[Symbol.iterator];\n}\n\n// Populate the class2type map\njQuery.each(\"Boolean Number String Function Array Date RegExp Object Error Symbol\".split(\" \"),\n function (i, name) {\n class2type[\"[object \" + name + \"]\"] = name.toLowerCase();\n });\n\nfunction isArrayLike(obj) {\n\n // Support: real iOS 8.2 only (not reproducible in simulator)\n // `in` check used to prevent JIT error (gh-2145)\n // hasOwn isn't used here due to false negatives\n // regarding Nodelist length in IE\n var length = !!obj && \"length\" in obj && obj.length,\n type = toType(obj);\n\n if (isFunction(obj) || isWindow(obj)) {\n return false;\n }\n\n return type === \"array\" || length === 0 ||\n typeof length === \"number\" && length > 0 && (length - 1) in obj;\n}\n\nvar Sizzle =\n /*!\n * Sizzle CSS Selector Engine v2.3.3\n * https://sizzlejs.com/\n *\n * Copyright jQuery Foundation and other contributors\n * Released under the MIT license\n * http://jquery.org/license\n *\n * Date: 2016-08-08\n */\n (function (window) {\n\n var i,\n support,\n Expr,\n getText,\n isXML,\n tokenize,\n compile,\n select,\n outermostContext,\n sortInput,\n hasDuplicate,\n\n // Local document vars\n setDocument,\n document,\n docElem,\n documentIsHTML,\n rbuggyQSA,\n rbuggyMatches,\n matches,\n contains,\n\n // Instance-specific data\n expando = \"sizzle\" + 1 * new Date(),\n preferredDoc = window.document,\n dirruns = 0,\n done = 0,\n classCache = createCache(),\n tokenCache = createCache(),\n compilerCache = createCache(),\n sortOrder = function (a, b) {\n if (a === b) {\n hasDuplicate = true;\n }\n return 0;\n },\n\n // Instance methods\n hasOwn = ({}).hasOwnProperty,\n arr = [],\n pop = arr.pop,\n push_native = arr.push,\n push = arr.push,\n slice = arr.slice,\n // Use a stripped-down indexOf as it's faster than native\n // https://jsperf.com/thor-indexof-vs-for/5\n indexOf = function (list, elem) {\n var i = 0,\n len = list.length;\n for (; i < len; i++) {\n if (list[i] === elem) {\n return i;\n }\n }\n return -1;\n },\n\n booleans = \"checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped\",\n\n // Regular expressions\n\n // http://www.w3.org/TR/css3-selectors/#whitespace\n whitespace = \"[\\\\x20\\\\t\\\\r\\\\n\\\\f]\",\n\n // http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier\n identifier = \"(?:\\\\\\\\.|[\\\\w-]|[^\\0-\\\\xa0])+\",\n\n // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors\n attributes = \"\\\\[\" + whitespace + \"*(\" + identifier + \")(?:\" + whitespace +\n // Operator (capture 2)\n \"*([*^$|!~]?=)\" + whitespace +\n // \"Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]\"\n \"*(?:'((?:\\\\\\\\.|[^\\\\\\\\'])*)'|\\\"((?:\\\\\\\\.|[^\\\\\\\\\\\"])*)\\\"|(\" + identifier + \"))|)\" + whitespace +\n \"*\\\\]\",\n\n pseudos = \":(\" + identifier + \")(?:\\\\((\" +\n // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:\n // 1. quoted (capture 3; capture 4 or capture 5)\n \"('((?:\\\\\\\\.|[^\\\\\\\\'])*)'|\\\"((?:\\\\\\\\.|[^\\\\\\\\\\\"])*)\\\")|\" +\n // 2. simple (capture 6)\n \"((?:\\\\\\\\.|[^\\\\\\\\()[\\\\]]|\" + attributes + \")*)|\" +\n // 3. anything else (capture 2)\n \".*\" +\n \")\\\\)|)\",\n\n // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter\n rwhitespace = new RegExp(whitespace + \"+\", \"g\"),\n rtrim = new RegExp(\"^\" + whitespace + \"+|((?:^|[^\\\\\\\\])(?:\\\\\\\\.)*)\" + whitespace + \"+$\", \"g\"),\n\n rcomma = new RegExp(\"^\" + whitespace + \"*,\" + whitespace + \"*\"),\n rcombinators = new RegExp(\"^\" + whitespace + \"*([>+~]|\" + whitespace + \")\" + whitespace + \"*\"),\n\n rattributeQuotes = new RegExp(\"=\" + whitespace + \"*([^\\\\]'\\\"]*?)\" + whitespace + \"*\\\\]\", \"g\"),\n\n rpseudo = new RegExp(pseudos),\n ridentifier = new RegExp(\"^\" + identifier + \"$\"),\n\n matchExpr = {\n \"ID\": new RegExp(\"^#(\" + identifier + \")\"),\n \"CLASS\": new RegExp(\"^\\\\.(\" + identifier + \")\"),\n \"TAG\": new RegExp(\"^(\" + identifier + \"|[*])\"),\n \"ATTR\": new RegExp(\"^\" + attributes),\n \"PSEUDO\": new RegExp(\"^\" + pseudos),\n \"CHILD\": new RegExp(\"^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\\\(\" + whitespace +\n \"*(even|odd|(([+-]|)(\\\\d*)n|)\" + whitespace + \"*(?:([+-]|)\" + whitespace +\n \"*(\\\\d+)|))\" + whitespace + \"*\\\\)|)\", \"i\"),\n \"bool\": new RegExp(\"^(?:\" + booleans + \")$\", \"i\"),\n // For use in libraries implementing .is()\n // We use this for POS matching in `select`\n \"needsContext\": new RegExp(\"^\" + whitespace + \"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\\\(\" +\n whitespace + \"*((?:-\\\\d)?\\\\d*)\" + whitespace + \"*\\\\)|)(?=[^-]|$)\", \"i\")\n },\n\n rinputs = /^(?:input|select|textarea|button)$/i,\n rheader = /^h\\d$/i,\n\n rnative = /^[^{]+\\{\\s*\\[native \\w/,\n\n // Easily-parseable/retrievable ID or TAG or CLASS selectors\n rquickExpr = /^(?:#([\\w-]+)|(\\w+)|\\.([\\w-]+))$/,\n\n rsibling = /[+~]/,\n\n // CSS escapes\n // http://www.w3.org/TR/CSS21/syndata.html#escaped-characters\n runescape = new RegExp(\"\\\\\\\\([\\\\da-f]{1,6}\" + whitespace + \"?|(\" + whitespace + \")|.)\", \"ig\"),\n funescape = function (_, escaped, escapedWhitespace) {\n var high = \"0x\" + escaped - 0x10000;\n // NaN means non-codepoint\n // Support: Firefox<24\n // Workaround erroneous numeric interpretation of +\"0x\"\n return high !== high || escapedWhitespace ?\n escaped :\n high < 0 ?\n // BMP codepoint\n String.fromCharCode(high + 0x10000) :\n // Supplemental Plane codepoint (surrogate pair)\n String.fromCharCode(high >> 10 | 0xD800, high & 0x3FF | 0xDC00);\n },\n\n // CSS string/identifier serialization\n // https://drafts.csswg.org/cssom/#common-serializing-idioms\n // eslint-disable-next-line no-control-regex\n rcssescape = /([\\0-\\x1f\\x7f]|^-?\\d)|^-$|[^\\0-\\x1f\\x7f-\\uFFFF\\w-]/g,\n fcssescape = function (ch, asCodePoint) {\n if (asCodePoint) {\n\n // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER\n if (ch === \"\\0\") {\n return \"\\uFFFD\";\n }\n\n // Control characters and (dependent upon position) numbers get escaped as code points\n return ch.slice(0, -1) + \"\\\\\" + ch.charCodeAt(ch.length - 1).toString(16) + \" \";\n }\n\n // Other potentially-special ASCII characters get backslash-escaped\n return \"\\\\\" + ch;\n },\n\n // Used for iframes\n // See setDocument()\n // Removing the function wrapper causes a \"Permission Denied\"\n // error in IE\n unloadHandler = function () {\n setDocument();\n },\n\n disabledAncestor = addCombinator(\n function (elem) {\n return elem.disabled === true && (\"form\" in elem || \"label\" in elem);\n },\n {dir: \"parentNode\", next: \"legend\"}\n );\n\n// Optimize for push.apply( _, NodeList )\n try {\n push.apply(\n (arr = slice.call(preferredDoc.childNodes)),\n preferredDoc.childNodes\n );\n // Support: Android<4.0\n // Detect silently failing push.apply\n arr[preferredDoc.childNodes.length].nodeType;\n } catch (e) {\n push = {\n apply: arr.length ?\n\n // Leverage slice if possible\n function (target, els) {\n push_native.apply(target, slice.call(els));\n } :\n\n // Support: IE<9\n // Otherwise append directly\n function (target, els) {\n var j = target.length,\n i = 0;\n // Can't trust NodeList.length\n while ((target[j++] = els[i++])) {\n }\n target.length = j - 1;\n }\n };\n }\n\n function Sizzle(selector, context, results, seed) {\n var m, i, elem, nid, match, groups, newSelector,\n newContext = context && context.ownerDocument,\n\n // nodeType defaults to 9, since context defaults to document\n nodeType = context ? context.nodeType : 9;\n\n results = results || [];\n\n // Return early from calls with invalid selector or context\n if (typeof selector !== \"string\" || !selector ||\n nodeType !== 1 && nodeType !== 9 && nodeType !== 11) {\n\n return results;\n }\n\n // Try to shortcut find operations (as opposed to filters) in HTML documents\n if (!seed) {\n\n if ((context ? context.ownerDocument || context : preferredDoc) !== document) {\n setDocument(context);\n }\n context = context || document;\n\n if (documentIsHTML) {\n\n // If the selector is sufficiently simple, try using a \"get*By*\" DOM method\n // (excepting DocumentFragment context, where the methods don't exist)\n if (nodeType !== 11 && (match = rquickExpr.exec(selector))) {\n\n // ID selector\n if ((m = match[1])) {\n\n // Document context\n if (nodeType === 9) {\n if ((elem = context.getElementById(m))) {\n\n // Support: IE, Opera, Webkit\n // TODO: identify versions\n // getElementById can match elements by name instead of ID\n if (elem.id === m) {\n results.push(elem);\n return results;\n }\n } else {\n return results;\n }\n\n // Element context\n } else {\n\n // Support: IE, Opera, Webkit\n // TODO: identify versions\n // getElementById can match elements by name instead of ID\n if (newContext && (elem = newContext.getElementById(m)) &&\n contains(context, elem) &&\n elem.id === m) {\n\n results.push(elem);\n return results;\n }\n }\n\n // Type selector\n } else if (match[2]) {\n push.apply(results, context.getElementsByTagName(selector));\n return results;\n\n // Class selector\n } else if ((m = match[3]) && support.getElementsByClassName &&\n context.getElementsByClassName) {\n\n push.apply(results, context.getElementsByClassName(m));\n return results;\n }\n }\n\n // Take advantage of querySelectorAll\n if (support.qsa &&\n !compilerCache[selector + \" \"] &&\n (!rbuggyQSA || !rbuggyQSA.test(selector))) {\n\n if (nodeType !== 1) {\n newContext = context;\n newSelector = selector;\n\n // qSA looks outside Element context, which is not what we want\n // Thanks to Andrew Dupont for this workaround technique\n // Support: IE <=8\n // Exclude object elements\n } else if (context.nodeName.toLowerCase() !== \"object\") {\n\n // Capture the context ID, setting it first if necessary\n if ((nid = context.getAttribute(\"id\"))) {\n nid = nid.replace(rcssescape, fcssescape);\n } else {\n context.setAttribute(\"id\", (nid = expando));\n }\n\n // Prefix every selector in the list\n groups = tokenize(selector);\n i = groups.length;\n while (i--) {\n groups[i] = \"#\" + nid + \" \" + toSelector(groups[i]);\n }\n newSelector = groups.join(\",\");\n\n // Expand context for sibling selectors\n newContext = rsibling.test(selector) && testContext(context.parentNode) ||\n context;\n }\n\n if (newSelector) {\n try {\n push.apply(results,\n newContext.querySelectorAll(newSelector)\n );\n return results;\n } catch (qsaError) {\n } finally {\n if (nid === expando) {\n context.removeAttribute(\"id\");\n }\n }\n }\n }\n }\n }\n\n // All others\n return select(selector.replace(rtrim, \"$1\"), context, results, seed);\n }\n\n /**\n * Create key-value caches of limited size\n * @returns {function(string, object)} Returns the Object data after storing it on itself with\n * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)\n * deleting the oldest entry\n */\n function createCache() {\n var keys = [];\n\n function cache(key, value) {\n // Use (key + \" \") to avoid collision with native prototype properties (see Issue #157)\n if (keys.push(key + \" \") > Expr.cacheLength) {\n // Only keep the most recent entries\n delete cache[keys.shift()];\n }\n return (cache[key + \" \"] = value);\n }\n\n return cache;\n }\n\n /**\n * Mark a function for special use by Sizzle\n * @param {Function} fn The function to mark\n */\n function markFunction(fn) {\n fn[expando] = true;\n return fn;\n }\n\n /**\n * Support testing using an element\n * @param {Function} fn Passed the created element and returns a boolean result\n */\n function assert(fn) {\n var el = document.createElement(\"fieldset\");\n\n try {\n return !!fn(el);\n } catch (e) {\n return false;\n } finally {\n // Remove from its parent by default\n if (el.parentNode) {\n el.parentNode.removeChild(el);\n }\n // release memory in IE\n el = null;\n }\n }\n\n /**\n * Checks document order of two siblings\n * @param {Element} a\n * @param {Element} b\n * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b\n */\n function siblingCheck(a, b) {\n var cur = b && a,\n diff = cur && a.nodeType === 1 && b.nodeType === 1 &&\n a.sourceIndex - b.sourceIndex;\n\n // Use IE sourceIndex if available on both nodes\n if (diff) {\n return diff;\n }\n\n // Check if b follows a\n if (cur) {\n while ((cur = cur.nextSibling)) {\n if (cur === b) {\n return -1;\n }\n }\n }\n\n return a ? 1 : -1;\n }\n\n /**\n * Returns a function to use in pseudos for input types\n * @param {String} type\n */\n function createInputPseudo(type) {\n return function (elem) {\n var name = elem.nodeName.toLowerCase();\n return name === \"input\" && elem.type === type;\n };\n }\n\n /**\n * Returns a function to use in pseudos for buttons\n * @param {String} type\n */\n function createButtonPseudo(type) {\n return function (elem) {\n var name = elem.nodeName.toLowerCase();\n return (name === \"input\" || name === \"button\") && elem.type === type;\n };\n }\n\n /**\n * Returns a function to use in pseudos for :enabled/:disabled\n * @param {Boolean} disabled true for :disabled; false for :enabled\n */\n function createDisabledPseudo(disabled) {\n\n // Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable\n return function (elem) {\n\n // Only certain elements can match :enabled or :disabled\n // https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled\n // https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled\n if (\"form\" in elem) {\n\n // Check for inherited disabledness on relevant non-disabled elements:\n // * listed form-associated elements in a disabled fieldset\n // https://html.spec.whatwg.org/multipage/forms.html#category-listed\n // https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled\n // * option elements in a disabled optgroup\n // https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled\n // All such elements have a \"form\" property.\n if (elem.parentNode && elem.disabled === false) {\n\n // Option elements defer to a parent optgroup if present\n if (\"label\" in elem) {\n if (\"label\" in elem.parentNode) {\n return elem.parentNode.disabled === disabled;\n } else {\n return elem.disabled === disabled;\n }\n }\n\n // Support: IE 6 - 11\n // Use the isDisabled shortcut property to check for disabled fieldset ancestors\n return elem.isDisabled === disabled ||\n\n // Where there is no isDisabled, check manually\n /* jshint -W018 */\n elem.isDisabled !== !disabled &&\n disabledAncestor(elem) === disabled;\n }\n\n return elem.disabled === disabled;\n\n // Try to winnow out elements that can't be disabled before trusting the disabled property.\n // Some victims get caught in our net (label, legend, menu, track), but it shouldn't\n // even exist on them, let alone have a boolean value.\n } else if (\"label\" in elem) {\n return elem.disabled === disabled;\n }\n\n // Remaining elements are neither :enabled nor :disabled\n return false;\n };\n }\n\n /**\n * Returns a function to use in pseudos for positionals\n * @param {Function} fn\n */\n function createPositionalPseudo(fn) {\n return markFunction(function (argument) {\n argument = +argument;\n return markFunction(function (seed, matches) {\n var j,\n matchIndexes = fn([], seed.length, argument),\n i = matchIndexes.length;\n\n // Match elements found at the specified indexes\n while (i--) {\n if (seed[(j = matchIndexes[i])]) {\n seed[j] = !(matches[j] = seed[j]);\n }\n }\n });\n });\n }\n\n /**\n * Checks a node for validity as a Sizzle context\n * @param {Element|Object=} context\n * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value\n */\n function testContext(context) {\n return context && typeof context.getElementsByTagName !== \"undefined\" && context;\n }\n\n// Expose support vars for convenience\n support = Sizzle.support = {};\n\n /**\n * Detects XML nodes\n * @param {Element|Object} elem An element or a document\n * @returns {Boolean} True iff elem is a non-HTML XML node\n */\n isXML = Sizzle.isXML = function (elem) {\n // documentElement is verified for cases where it doesn't yet exist\n // (such as loading iframes in IE - #4833)\n var documentElement = elem && (elem.ownerDocument || elem).documentElement;\n return documentElement ? documentElement.nodeName !== \"HTML\" : false;\n };\n\n /**\n * Sets document-related variables once based on the current document\n * @param {Element|Object} [doc] An element or document object to use to set the document\n * @returns {Object} Returns the current document\n */\n setDocument = Sizzle.setDocument = function (node) {\n var hasCompare, subWindow,\n doc = node ? node.ownerDocument || node : preferredDoc;\n\n // Return early if doc is invalid or already selected\n if (doc === document || doc.nodeType !== 9 || !doc.documentElement) {\n return document;\n }\n\n // Update global variables\n document = doc;\n docElem = document.documentElement;\n documentIsHTML = !isXML(document);\n\n // Support: IE 9-11, Edge\n // Accessing iframe documents after unload throws \"permission denied\" errors (jQuery #13936)\n if (preferredDoc !== document &&\n (subWindow = document.defaultView) && subWindow.top !== subWindow) {\n\n // Support: IE 11, Edge\n if (subWindow.addEventListener) {\n subWindow.addEventListener(\"unload\", unloadHandler, false);\n\n // Support: IE 9 - 10 only\n } else if (subWindow.attachEvent) {\n subWindow.attachEvent(\"onunload\", unloadHandler);\n }\n }\n\n /* Attributes\n\t---------------------------------------------------------------------- */\n\n // Support: IE<8\n // Verify that getAttribute really returns attributes and not properties\n // (excepting IE8 booleans)\n support.attributes = assert(function (el) {\n el.className = \"i\";\n return !el.getAttribute(\"className\");\n });\n\n /* getElement(s)By*\n\t---------------------------------------------------------------------- */\n\n // Check if getElementsByTagName(\"*\") returns only elements\n support.getElementsByTagName = assert(function (el) {\n el.appendChild(document.createComment(\"\"));\n return !el.getElementsByTagName(\"*\").length;\n });\n\n // Support: IE<9\n support.getElementsByClassName = rnative.test(document.getElementsByClassName);\n\n // Support: IE<10\n // Check if getElementById returns elements by name\n // The broken getElementById methods don't pick up programmatically-set names,\n // so use a roundabout getElementsByName test\n support.getById = assert(function (el) {\n docElem.appendChild(el).id = expando;\n return !document.getElementsByName || !document.getElementsByName(expando).length;\n });\n\n // ID filter and find\n if (support.getById) {\n Expr.filter[\"ID\"] = function (id) {\n var attrId = id.replace(runescape, funescape);\n return function (elem) {\n return elem.getAttribute(\"id\") === attrId;\n };\n };\n Expr.find[\"ID\"] = function (id, context) {\n if (typeof context.getElementById !== \"undefined\" && documentIsHTML) {\n var elem = context.getElementById(id);\n return elem ? [elem] : [];\n }\n };\n } else {\n Expr.filter[\"ID\"] = function (id) {\n var attrId = id.replace(runescape, funescape);\n return function (elem) {\n var node = typeof elem.getAttributeNode !== \"undefined\" &&\n elem.getAttributeNode(\"id\");\n return node && node.value === attrId;\n };\n };\n\n // Support: IE 6 - 7 only\n // getElementById is not reliable as a find shortcut\n Expr.find[\"ID\"] = function (id, context) {\n if (typeof context.getElementById !== \"undefined\" && documentIsHTML) {\n var node, i, elems,\n elem = context.getElementById(id);\n\n if (elem) {\n\n // Verify the id attribute\n node = elem.getAttributeNode(\"id\");\n if (node && node.value === id) {\n return [elem];\n }\n\n // Fall back on getElementsByName\n elems = context.getElementsByName(id);\n i = 0;\n while ((elem = elems[i++])) {\n node = elem.getAttributeNode(\"id\");\n if (node && node.value === id) {\n return [elem];\n }\n }\n }\n\n return [];\n }\n };\n }\n\n // Tag\n Expr.find[\"TAG\"] = support.getElementsByTagName ?\n function (tag, context) {\n if (typeof context.getElementsByTagName !== \"undefined\") {\n return context.getElementsByTagName(tag);\n\n // DocumentFragment nodes don't have gEBTN\n } else if (support.qsa) {\n return context.querySelectorAll(tag);\n }\n } :\n\n function (tag, context) {\n var elem,\n tmp = [],\n i = 0,\n // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too\n results = context.getElementsByTagName(tag);\n\n // Filter out possible comments\n if (tag === \"*\") {\n while ((elem = results[i++])) {\n if (elem.nodeType === 1) {\n tmp.push(elem);\n }\n }\n\n return tmp;\n }\n return results;\n };\n\n // Class\n Expr.find[\"CLASS\"] = support.getElementsByClassName && function (className, context) {\n if (typeof context.getElementsByClassName !== \"undefined\" && documentIsHTML) {\n return context.getElementsByClassName(className);\n }\n };\n\n /* QSA/matchesSelector\n\t---------------------------------------------------------------------- */\n\n // QSA and matchesSelector support\n\n // matchesSelector(:active) reports false when true (IE9/Opera 11.5)\n rbuggyMatches = [];\n\n // qSa(:focus) reports false when true (Chrome 21)\n // We allow this because of a bug in IE8/9 that throws an error\n // whenever `document.activeElement` is accessed on an iframe\n // So, we allow :focus to pass through QSA all the time to avoid the IE error\n // See https://bugs.jquery.com/ticket/13378\n rbuggyQSA = [];\n\n if ((support.qsa = rnative.test(document.querySelectorAll))) {\n // Build QSA regex\n // Regex strategy adopted from Diego Perini\n assert(function (el) {\n // Select is set to empty string on purpose\n // This is to test IE's treatment of not explicitly\n // setting a boolean content attribute,\n // since its presence should be enough\n // https://bugs.jquery.com/ticket/12359\n docElem.appendChild(el).innerHTML = \"\" +\n \"\";\n\n // Support: IE8, Opera 11-12.16\n // Nothing should be selected when empty strings follow ^= or $= or *=\n // The test attribute must be unknown in Opera but \"safe\" for WinRT\n // https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section\n if (el.querySelectorAll(\"[msallowcapture^='']\").length) {\n rbuggyQSA.push(\"[*^$]=\" + whitespace + \"*(?:''|\\\"\\\")\");\n }\n\n // Support: IE8\n // Boolean attributes and \"value\" are not treated correctly\n if (!el.querySelectorAll(\"[selected]\").length) {\n rbuggyQSA.push(\"\\\\[\" + whitespace + \"*(?:value|\" + booleans + \")\");\n }\n\n // Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+\n if (!el.querySelectorAll(\"[id~=\" + expando + \"-]\").length) {\n rbuggyQSA.push(\"~=\");\n }\n\n // Webkit/Opera - :checked should return selected option elements\n // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked\n // IE8 throws error here and will not see later tests\n if (!el.querySelectorAll(\":checked\").length) {\n rbuggyQSA.push(\":checked\");\n }\n\n // Support: Safari 8+, iOS 8+\n // https://bugs.webkit.org/show_bug.cgi?id=136851\n // In-page `selector#id sibling-combinator selector` fails\n if (!el.querySelectorAll(\"a#\" + expando + \"+*\").length) {\n rbuggyQSA.push(\".#.+[+~]\");\n }\n });\n\n assert(function (el) {\n el.innerHTML = \"\" +\n \"\";\n\n // Support: Windows 8 Native Apps\n // The type and name attributes are restricted during .innerHTML assignment\n var input = document.createElement(\"input\");\n input.setAttribute(\"type\", \"hidden\");\n el.appendChild(input).setAttribute(\"name\", \"D\");\n\n // Support: IE8\n // Enforce case-sensitivity of name attribute\n if (el.querySelectorAll(\"[name=d]\").length) {\n rbuggyQSA.push(\"name\" + whitespace + \"*[*^$|!~]?=\");\n }\n\n // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)\n // IE8 throws error here and will not see later tests\n if (el.querySelectorAll(\":enabled\").length !== 2) {\n rbuggyQSA.push(\":enabled\", \":disabled\");\n }\n\n // Support: IE9-11+\n // IE's :disabled selector does not pick up the children of disabled fieldsets\n docElem.appendChild(el).disabled = true;\n if (el.querySelectorAll(\":disabled\").length !== 2) {\n rbuggyQSA.push(\":enabled\", \":disabled\");\n }\n\n // Opera 10-11 does not throw on post-comma invalid pseudos\n el.querySelectorAll(\"*,:x\");\n rbuggyQSA.push(\",.*:\");\n });\n }\n\n if ((support.matchesSelector = rnative.test((matches = docElem.matches ||\n docElem.webkitMatchesSelector ||\n docElem.mozMatchesSelector ||\n docElem.oMatchesSelector ||\n docElem.msMatchesSelector)))) {\n\n assert(function (el) {\n // Check to see if it's possible to do matchesSelector\n // on a disconnected node (IE 9)\n support.disconnectedMatch = matches.call(el, \"*\");\n\n // This should fail with an exception\n // Gecko does not error, returns false instead\n matches.call(el, \"[s!='']:x\");\n rbuggyMatches.push(\"!=\", pseudos);\n });\n }\n\n rbuggyQSA = rbuggyQSA.length && new RegExp(rbuggyQSA.join(\"|\"));\n rbuggyMatches = rbuggyMatches.length && new RegExp(rbuggyMatches.join(\"|\"));\n\n /* Contains\n\t---------------------------------------------------------------------- */\n hasCompare = rnative.test(docElem.compareDocumentPosition);\n\n // Element contains another\n // Purposefully self-exclusive\n // As in, an element does not contain itself\n contains = hasCompare || rnative.test(docElem.contains) ?\n function (a, b) {\n var adown = a.nodeType === 9 ? a.documentElement : a,\n bup = b && b.parentNode;\n return a === bup || !!(bup && bup.nodeType === 1 && (\n adown.contains ?\n adown.contains(bup) :\n a.compareDocumentPosition && a.compareDocumentPosition(bup) & 16\n ));\n } :\n function (a, b) {\n if (b) {\n while ((b = b.parentNode)) {\n if (b === a) {\n return true;\n }\n }\n }\n return false;\n };\n\n /* Sorting\n\t---------------------------------------------------------------------- */\n\n // Document order sorting\n sortOrder = hasCompare ?\n function (a, b) {\n\n // Flag for duplicate removal\n if (a === b) {\n hasDuplicate = true;\n return 0;\n }\n\n // Sort on method existence if only one input has compareDocumentPosition\n var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;\n if (compare) {\n return compare;\n }\n\n // Calculate position if both inputs belong to the same document\n compare = (a.ownerDocument || a) === (b.ownerDocument || b) ?\n a.compareDocumentPosition(b) :\n\n // Otherwise we know they are disconnected\n 1;\n\n // Disconnected nodes\n if (compare & 1 ||\n (!support.sortDetached && b.compareDocumentPosition(a) === compare)) {\n\n // Choose the first element that is related to our preferred document\n if (a === document || a.ownerDocument === preferredDoc && contains(preferredDoc, a)) {\n return -1;\n }\n if (b === document || b.ownerDocument === preferredDoc && contains(preferredDoc, b)) {\n return 1;\n }\n\n // Maintain original order\n return sortInput ?\n (indexOf(sortInput, a) - indexOf(sortInput, b)) :\n 0;\n }\n\n return compare & 4 ? -1 : 1;\n } :\n function (a, b) {\n // Exit early if the nodes are identical\n if (a === b) {\n hasDuplicate = true;\n return 0;\n }\n\n var cur,\n i = 0,\n aup = a.parentNode,\n bup = b.parentNode,\n ap = [a],\n bp = [b];\n\n // Parentless nodes are either documents or disconnected\n if (!aup || !bup) {\n return a === document ? -1 :\n b === document ? 1 :\n aup ? -1 :\n bup ? 1 :\n sortInput ?\n (indexOf(sortInput, a) - indexOf(sortInput, b)) :\n 0;\n\n // If the nodes are siblings, we can do a quick check\n } else if (aup === bup) {\n return siblingCheck(a, b);\n }\n\n // Otherwise we need full lists of their ancestors for comparison\n cur = a;\n while ((cur = cur.parentNode)) {\n ap.unshift(cur);\n }\n cur = b;\n while ((cur = cur.parentNode)) {\n bp.unshift(cur);\n }\n\n // Walk down the tree looking for a discrepancy\n while (ap[i] === bp[i]) {\n i++;\n }\n\n return i ?\n // Do a sibling check if the nodes have a common ancestor\n siblingCheck(ap[i], bp[i]) :\n\n // Otherwise nodes in our document sort first\n ap[i] === preferredDoc ? -1 :\n bp[i] === preferredDoc ? 1 :\n 0;\n };\n\n return document;\n };\n\n Sizzle.matches = function (expr, elements) {\n return Sizzle(expr, null, null, elements);\n };\n\n Sizzle.matchesSelector = function (elem, expr) {\n // Set document vars if needed\n if ((elem.ownerDocument || elem) !== document) {\n setDocument(elem);\n }\n\n // Make sure that attribute selectors are quoted\n expr = expr.replace(rattributeQuotes, \"='$1']\");\n\n if (support.matchesSelector && documentIsHTML &&\n !compilerCache[expr + \" \"] &&\n (!rbuggyMatches || !rbuggyMatches.test(expr)) &&\n (!rbuggyQSA || !rbuggyQSA.test(expr))) {\n\n try {\n var ret = matches.call(elem, expr);\n\n // IE 9's matchesSelector returns false on disconnected nodes\n if (ret || support.disconnectedMatch ||\n // As well, disconnected nodes are said to be in a document\n // fragment in IE 9\n elem.document && elem.document.nodeType !== 11) {\n return ret;\n }\n } catch (e) {\n }\n }\n\n return Sizzle(expr, document, null, [elem]).length > 0;\n };\n\n Sizzle.contains = function (context, elem) {\n // Set document vars if needed\n if ((context.ownerDocument || context) !== document) {\n setDocument(context);\n }\n return contains(context, elem);\n };\n\n Sizzle.attr = function (elem, name) {\n // Set document vars if needed\n if ((elem.ownerDocument || elem) !== document) {\n setDocument(elem);\n }\n\n var fn = Expr.attrHandle[name.toLowerCase()],\n // Don't get fooled by Object.prototype properties (jQuery #13807)\n val = fn && hasOwn.call(Expr.attrHandle, name.toLowerCase()) ?\n fn(elem, name, !documentIsHTML) :\n undefined;\n\n return val !== undefined ?\n val :\n support.attributes || !documentIsHTML ?\n elem.getAttribute(name) :\n (val = elem.getAttributeNode(name)) && val.specified ?\n val.value :\n null;\n };\n\n Sizzle.escape = function (sel) {\n return (sel + \"\").replace(rcssescape, fcssescape);\n };\n\n Sizzle.error = function (msg) {\n throw new Error(\"Syntax error, unrecognized expression: \" + msg);\n };\n\n /**\n * Document sorting and removing duplicates\n * @param {ArrayLike} results\n */\n Sizzle.uniqueSort = function (results) {\n var elem,\n duplicates = [],\n j = 0,\n i = 0;\n\n // Unless we *know* we can detect duplicates, assume their presence\n hasDuplicate = !support.detectDuplicates;\n sortInput = !support.sortStable && results.slice(0);\n results.sort(sortOrder);\n\n if (hasDuplicate) {\n while ((elem = results[i++])) {\n if (elem === results[i]) {\n j = duplicates.push(i);\n }\n }\n while (j--) {\n results.splice(duplicates[j], 1);\n }\n }\n\n // Clear input after sorting to release objects\n // See https://github.com/jquery/sizzle/pull/225\n sortInput = null;\n\n return results;\n };\n\n /**\n * Utility function for retrieving the text value of an array of DOM nodes\n * @param {Array|Element} elem\n */\n getText = Sizzle.getText = function (elem) {\n var node,\n ret = \"\",\n i = 0,\n nodeType = elem.nodeType;\n\n if (!nodeType) {\n // If no nodeType, this is expected to be an array\n while ((node = elem[i++])) {\n // Do not traverse comment nodes\n ret += getText(node);\n }\n } else if (nodeType === 1 || nodeType === 9 || nodeType === 11) {\n // Use textContent for elements\n // innerText usage removed for consistency of new lines (jQuery #11153)\n if (typeof elem.textContent === \"string\") {\n return elem.textContent;\n } else {\n // Traverse its children\n for (elem = elem.firstChild; elem; elem = elem.nextSibling) {\n ret += getText(elem);\n }\n }\n } else if (nodeType === 3 || nodeType === 4) {\n return elem.nodeValue;\n }\n // Do not include comment or processing instruction nodes\n\n return ret;\n };\n\n Expr = Sizzle.selectors = {\n\n // Can be adjusted by the user\n cacheLength: 50,\n\n createPseudo: markFunction,\n\n match: matchExpr,\n\n attrHandle: {},\n\n find: {},\n\n relative: {\n \">\": {dir: \"parentNode\", first: true},\n \" \": {dir: \"parentNode\"},\n \"+\": {dir: \"previousSibling\", first: true},\n \"~\": {dir: \"previousSibling\"}\n },\n\n preFilter: {\n \"ATTR\": function (match) {\n match[1] = match[1].replace(runescape, funescape);\n\n // Move the given value to match[3] whether quoted or unquoted\n match[3] = (match[3] || match[4] || match[5] || \"\").replace(runescape, funescape);\n\n if (match[2] === \"~=\") {\n match[3] = \" \" + match[3] + \" \";\n }\n\n return match.slice(0, 4);\n },\n\n \"CHILD\": function (match) {\n /* matches from matchExpr[\"CHILD\"]\n\t\t\t\t1 type (only|nth|...)\n\t\t\t\t2 what (child|of-type)\n\t\t\t\t3 argument (even|odd|\\d*|\\d*n([+-]\\d+)?|...)\n\t\t\t\t4 xn-component of xn+y argument ([+-]?\\d*n|)\n\t\t\t\t5 sign of xn-component\n\t\t\t\t6 x of xn-component\n\t\t\t\t7 sign of y-component\n\t\t\t\t8 y of y-component\n\t\t\t*/\n match[1] = match[1].toLowerCase();\n\n if (match[1].slice(0, 3) === \"nth\") {\n // nth-* requires argument\n if (!match[3]) {\n Sizzle.error(match[0]);\n }\n\n // numeric x and y parameters for Expr.filter.CHILD\n // remember that false/true cast respectively to 0/1\n match[4] = +(match[4] ? match[5] + (match[6] || 1) : 2 * (match[3] === \"even\" || match[3] === \"odd\"));\n match[5] = +((match[7] + match[8]) || match[3] === \"odd\");\n\n // other types prohibit arguments\n } else if (match[3]) {\n Sizzle.error(match[0]);\n }\n\n return match;\n },\n\n \"PSEUDO\": function (match) {\n var excess,\n unquoted = !match[6] && match[2];\n\n if (matchExpr[\"CHILD\"].test(match[0])) {\n return null;\n }\n\n // Accept quoted arguments as-is\n if (match[3]) {\n match[2] = match[4] || match[5] || \"\";\n\n // Strip excess characters from unquoted arguments\n } else if (unquoted && rpseudo.test(unquoted) &&\n // Get excess from tokenize (recursively)\n (excess = tokenize(unquoted, true)) &&\n // advance to the next closing parenthesis\n (excess = unquoted.indexOf(\")\", unquoted.length - excess) - unquoted.length)) {\n\n // excess is a negative index\n match[0] = match[0].slice(0, excess);\n match[2] = unquoted.slice(0, excess);\n }\n\n // Return only captures needed by the pseudo filter method (type and argument)\n return match.slice(0, 3);\n }\n },\n\n filter: {\n\n \"TAG\": function (nodeNameSelector) {\n var nodeName = nodeNameSelector.replace(runescape, funescape).toLowerCase();\n return nodeNameSelector === \"*\" ?\n function () {\n return true;\n } :\n function (elem) {\n return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;\n };\n },\n\n \"CLASS\": function (className) {\n var pattern = classCache[className + \" \"];\n\n return pattern ||\n (pattern = new RegExp(\"(^|\" + whitespace + \")\" + className + \"(\" + whitespace + \"|$)\")) &&\n classCache(className, function (elem) {\n return pattern.test(typeof elem.className === \"string\" && elem.className || typeof elem.getAttribute !== \"undefined\" && elem.getAttribute(\"class\") || \"\");\n });\n },\n\n \"ATTR\": function (name, operator, check) {\n return function (elem) {\n var result = Sizzle.attr(elem, name);\n\n if (result == null) {\n return operator === \"!=\";\n }\n if (!operator) {\n return true;\n }\n\n result += \"\";\n\n return operator === \"=\" ? result === check :\n operator === \"!=\" ? result !== check :\n operator === \"^=\" ? check && result.indexOf(check) === 0 :\n operator === \"*=\" ? check && result.indexOf(check) > -1 :\n operator === \"$=\" ? check && result.slice(-check.length) === check :\n operator === \"~=\" ? (\" \" + result.replace(rwhitespace, \" \") + \" \").indexOf(check) > -1 :\n operator === \"|=\" ? result === check || result.slice(0, check.length + 1) === check + \"-\" :\n false;\n };\n },\n\n \"CHILD\": function (type, what, argument, first, last) {\n var simple = type.slice(0, 3) !== \"nth\",\n forward = type.slice(-4) !== \"last\",\n ofType = what === \"of-type\";\n\n return first === 1 && last === 0 ?\n\n // Shortcut for :nth-*(n)\n function (elem) {\n return !!elem.parentNode;\n } :\n\n function (elem, context, xml) {\n var cache, uniqueCache, outerCache, node, nodeIndex, start,\n dir = simple !== forward ? \"nextSibling\" : \"previousSibling\",\n parent = elem.parentNode,\n name = ofType && elem.nodeName.toLowerCase(),\n useCache = !xml && !ofType,\n diff = false;\n\n if (parent) {\n\n // :(first|last|only)-(child|of-type)\n if (simple) {\n while (dir) {\n node = elem;\n while ((node = node[dir])) {\n if (ofType ?\n node.nodeName.toLowerCase() === name :\n node.nodeType === 1) {\n\n return false;\n }\n }\n // Reverse direction for :only-* (if we haven't yet done so)\n start = dir = type === \"only\" && !start && \"nextSibling\";\n }\n return true;\n }\n\n start = [forward ? parent.firstChild : parent.lastChild];\n\n // non-xml :nth-child(...) stores cache data on `parent`\n if (forward && useCache) {\n\n // Seek `elem` from a previously-cached index\n\n // ...in a gzip-friendly way\n node = parent;\n outerCache = node[expando] || (node[expando] = {});\n\n // Support: IE <9 only\n // Defend against cloned attroperties (jQuery gh-1709)\n uniqueCache = outerCache[node.uniqueID] ||\n (outerCache[node.uniqueID] = {});\n\n cache = uniqueCache[type] || [];\n nodeIndex = cache[0] === dirruns && cache[1];\n diff = nodeIndex && cache[2];\n node = nodeIndex && parent.childNodes[nodeIndex];\n\n while ((node = ++nodeIndex && node && node[dir] ||\n\n // Fallback to seeking `elem` from the start\n (diff = nodeIndex = 0) || start.pop())) {\n\n // When found, cache indexes on `parent` and break\n if (node.nodeType === 1 && ++diff && node === elem) {\n uniqueCache[type] = [dirruns, nodeIndex, diff];\n break;\n }\n }\n\n } else {\n // Use previously-cached element index if available\n if (useCache) {\n // ...in a gzip-friendly way\n node = elem;\n outerCache = node[expando] || (node[expando] = {});\n\n // Support: IE <9 only\n // Defend against cloned attroperties (jQuery gh-1709)\n uniqueCache = outerCache[node.uniqueID] ||\n (outerCache[node.uniqueID] = {});\n\n cache = uniqueCache[type] || [];\n nodeIndex = cache[0] === dirruns && cache[1];\n diff = nodeIndex;\n }\n\n // xml :nth-child(...)\n // or :nth-last-child(...) or :nth(-last)?-of-type(...)\n if (diff === false) {\n // Use the same loop as above to seek `elem` from the start\n while ((node = ++nodeIndex && node && node[dir] ||\n (diff = nodeIndex = 0) || start.pop())) {\n\n if ((ofType ?\n node.nodeName.toLowerCase() === name :\n node.nodeType === 1) &&\n ++diff) {\n\n // Cache the index of each encountered element\n if (useCache) {\n outerCache = node[expando] || (node[expando] = {});\n\n // Support: IE <9 only\n // Defend against cloned attroperties (jQuery gh-1709)\n uniqueCache = outerCache[node.uniqueID] ||\n (outerCache[node.uniqueID] = {});\n\n uniqueCache[type] = [dirruns, diff];\n }\n\n if (node === elem) {\n break;\n }\n }\n }\n }\n }\n\n // Incorporate the offset, then check against cycle size\n diff -= last;\n return diff === first || (diff % first === 0 && diff / first >= 0);\n }\n };\n },\n\n \"PSEUDO\": function (pseudo, argument) {\n // pseudo-class names are case-insensitive\n // http://www.w3.org/TR/selectors/#pseudo-classes\n // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters\n // Remember that setFilters inherits from pseudos\n var args,\n fn = Expr.pseudos[pseudo] || Expr.setFilters[pseudo.toLowerCase()] ||\n Sizzle.error(\"unsupported pseudo: \" + pseudo);\n\n // The user may use createPseudo to indicate that\n // arguments are needed to create the filter function\n // just as Sizzle does\n if (fn[expando]) {\n return fn(argument);\n }\n\n // But maintain support for old signatures\n if (fn.length > 1) {\n args = [pseudo, pseudo, \"\", argument];\n return Expr.setFilters.hasOwnProperty(pseudo.toLowerCase()) ?\n markFunction(function (seed, matches) {\n var idx,\n matched = fn(seed, argument),\n i = matched.length;\n while (i--) {\n idx = indexOf(seed, matched[i]);\n seed[idx] = !(matches[idx] = matched[i]);\n }\n }) :\n function (elem) {\n return fn(elem, 0, args);\n };\n }\n\n return fn;\n }\n },\n\n pseudos: {\n // Potentially complex pseudos\n \"not\": markFunction(function (selector) {\n // Trim the selector passed to compile\n // to avoid treating leading and trailing\n // spaces as combinators\n var input = [],\n results = [],\n matcher = compile(selector.replace(rtrim, \"$1\"));\n\n return matcher[expando] ?\n markFunction(function (seed, matches, context, xml) {\n var elem,\n unmatched = matcher(seed, null, xml, []),\n i = seed.length;\n\n // Match elements unmatched by `matcher`\n while (i--) {\n if ((elem = unmatched[i])) {\n seed[i] = !(matches[i] = elem);\n }\n }\n }) :\n function (elem, context, xml) {\n input[0] = elem;\n matcher(input, null, xml, results);\n // Don't keep the element (issue #299)\n input[0] = null;\n return !results.pop();\n };\n }),\n\n \"has\": markFunction(function (selector) {\n return function (elem) {\n return Sizzle(selector, elem).length > 0;\n };\n }),\n\n \"contains\": markFunction(function (text) {\n text = text.replace(runescape, funescape);\n return function (elem) {\n return (elem.textContent || elem.innerText || getText(elem)).indexOf(text) > -1;\n };\n }),\n\n // \"Whether an element is represented by a :lang() selector\n // is based solely on the element's language value\n // being equal to the identifier C,\n // or beginning with the identifier C immediately followed by \"-\".\n // The matching of C against the element's language value is performed case-insensitively.\n // The identifier C does not have to be a valid language name.\"\n // http://www.w3.org/TR/selectors/#lang-pseudo\n \"lang\": markFunction(function (lang) {\n // lang value must be a valid identifier\n if (!ridentifier.test(lang || \"\")) {\n Sizzle.error(\"unsupported lang: \" + lang);\n }\n lang = lang.replace(runescape, funescape).toLowerCase();\n return function (elem) {\n var elemLang;\n do {\n if ((elemLang = documentIsHTML ?\n elem.lang :\n elem.getAttribute(\"xml:lang\") || elem.getAttribute(\"lang\"))) {\n\n elemLang = elemLang.toLowerCase();\n return elemLang === lang || elemLang.indexOf(lang + \"-\") === 0;\n }\n } while ((elem = elem.parentNode) && elem.nodeType === 1);\n return false;\n };\n }),\n\n // Miscellaneous\n \"target\": function (elem) {\n var hash = window.location && window.location.hash;\n return hash && hash.slice(1) === elem.id;\n },\n\n \"root\": function (elem) {\n return elem === docElem;\n },\n\n \"focus\": function (elem) {\n return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);\n },\n\n // Boolean properties\n \"enabled\": createDisabledPseudo(false),\n \"disabled\": createDisabledPseudo(true),\n\n \"checked\": function (elem) {\n // In CSS3, :checked should return both checked and selected elements\n // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked\n var nodeName = elem.nodeName.toLowerCase();\n return (nodeName === \"input\" && !!elem.checked) || (nodeName === \"option\" && !!elem.selected);\n },\n\n \"selected\": function (elem) {\n // Accessing this property makes selected-by-default\n // options in Safari work properly\n if (elem.parentNode) {\n elem.parentNode.selectedIndex;\n }\n\n return elem.selected === true;\n },\n\n // Contents\n \"empty\": function (elem) {\n // http://www.w3.org/TR/selectors/#empty-pseudo\n // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),\n // but not by others (comment: 8; processing instruction: 7; etc.)\n // nodeType < 6 works because attributes (2) do not appear as children\n for (elem = elem.firstChild; elem; elem = elem.nextSibling) {\n if (elem.nodeType < 6) {\n return false;\n }\n }\n return true;\n },\n\n \"parent\": function (elem) {\n return !Expr.pseudos[\"empty\"](elem);\n },\n\n // Element/input types\n \"header\": function (elem) {\n return rheader.test(elem.nodeName);\n },\n\n \"input\": function (elem) {\n return rinputs.test(elem.nodeName);\n },\n\n \"button\": function (elem) {\n var name = elem.nodeName.toLowerCase();\n return name === \"input\" && elem.type === \"button\" || name === \"button\";\n },\n\n \"text\": function (elem) {\n var attr;\n return elem.nodeName.toLowerCase() === \"input\" &&\n elem.type === \"text\" &&\n\n // Support: IE<8\n // New HTML5 attribute values (e.g., \"search\") appear with elem.type === \"text\"\n ((attr = elem.getAttribute(\"type\")) == null || attr.toLowerCase() === \"text\");\n },\n\n // Position-in-collection\n \"first\": createPositionalPseudo(function () {\n return [0];\n }),\n\n \"last\": createPositionalPseudo(function (matchIndexes, length) {\n return [length - 1];\n }),\n\n \"eq\": createPositionalPseudo(function (matchIndexes, length, argument) {\n return [argument < 0 ? argument + length : argument];\n }),\n\n \"even\": createPositionalPseudo(function (matchIndexes, length) {\n var i = 0;\n for (; i < length; i += 2) {\n matchIndexes.push(i);\n }\n return matchIndexes;\n }),\n\n \"odd\": createPositionalPseudo(function (matchIndexes, length) {\n var i = 1;\n for (; i < length; i += 2) {\n matchIndexes.push(i);\n }\n return matchIndexes;\n }),\n\n \"lt\": createPositionalPseudo(function (matchIndexes, length, argument) {\n var i = argument < 0 ? argument + length : argument;\n for (; --i >= 0;) {\n matchIndexes.push(i);\n }\n return matchIndexes;\n }),\n\n \"gt\": createPositionalPseudo(function (matchIndexes, length, argument) {\n var i = argument < 0 ? argument + length : argument;\n for (; ++i < length;) {\n matchIndexes.push(i);\n }\n return matchIndexes;\n })\n }\n };\n\n Expr.pseudos[\"nth\"] = Expr.pseudos[\"eq\"];\n\n// Add button/input type pseudos\n for (i in {radio: true, checkbox: true, file: true, password: true, image: true}) {\n Expr.pseudos[i] = createInputPseudo(i);\n }\n for (i in {submit: true, reset: true}) {\n Expr.pseudos[i] = createButtonPseudo(i);\n }\n\n// Easy API for creating new setFilters\n function setFilters() {\n }\n\n setFilters.prototype = Expr.filters = Expr.pseudos;\n Expr.setFilters = new setFilters();\n\n tokenize = Sizzle.tokenize = function (selector, parseOnly) {\n var matched, match, tokens, type,\n soFar, groups, preFilters,\n cached = tokenCache[selector + \" \"];\n\n if (cached) {\n return parseOnly ? 0 : cached.slice(0);\n }\n\n soFar = selector;\n groups = [];\n preFilters = Expr.preFilter;\n\n while (soFar) {\n\n // Comma and first run\n if (!matched || (match = rcomma.exec(soFar))) {\n if (match) {\n // Don't consume trailing commas as valid\n soFar = soFar.slice(match[0].length) || soFar;\n }\n groups.push((tokens = []));\n }\n\n matched = false;\n\n // Combinators\n if ((match = rcombinators.exec(soFar))) {\n matched = match.shift();\n tokens.push({\n value: matched,\n // Cast descendant combinators to space\n type: match[0].replace(rtrim, \" \")\n });\n soFar = soFar.slice(matched.length);\n }\n\n // Filters\n for (type in Expr.filter) {\n if ((match = matchExpr[type].exec(soFar)) && (!preFilters[type] ||\n (match = preFilters[type](match)))) {\n matched = match.shift();\n tokens.push({\n value: matched,\n type: type,\n matches: match\n });\n soFar = soFar.slice(matched.length);\n }\n }\n\n if (!matched) {\n break;\n }\n }\n\n // Return the length of the invalid excess\n // if we're just parsing\n // Otherwise, throw an error or return tokens\n return parseOnly ?\n soFar.length :\n soFar ?\n Sizzle.error(selector) :\n // Cache the tokens\n tokenCache(selector, groups).slice(0);\n };\n\n function toSelector(tokens) {\n var i = 0,\n len = tokens.length,\n selector = \"\";\n for (; i < len; i++) {\n selector += tokens[i].value;\n }\n return selector;\n }\n\n function addCombinator(matcher, combinator, base) {\n var dir = combinator.dir,\n skip = combinator.next,\n key = skip || dir,\n checkNonElements = base && key === \"parentNode\",\n doneName = done++;\n\n return combinator.first ?\n // Check against closest ancestor/preceding element\n function (elem, context, xml) {\n while ((elem = elem[dir])) {\n if (elem.nodeType === 1 || checkNonElements) {\n return matcher(elem, context, xml);\n }\n }\n return false;\n } :\n\n // Check against all ancestor/preceding elements\n function (elem, context, xml) {\n var oldCache, uniqueCache, outerCache,\n newCache = [dirruns, doneName];\n\n // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching\n if (xml) {\n while ((elem = elem[dir])) {\n if (elem.nodeType === 1 || checkNonElements) {\n if (matcher(elem, context, xml)) {\n return true;\n }\n }\n }\n } else {\n while ((elem = elem[dir])) {\n if (elem.nodeType === 1 || checkNonElements) {\n outerCache = elem[expando] || (elem[expando] = {});\n\n // Support: IE <9 only\n // Defend against cloned attroperties (jQuery gh-1709)\n uniqueCache = outerCache[elem.uniqueID] || (outerCache[elem.uniqueID] = {});\n\n if (skip && skip === elem.nodeName.toLowerCase()) {\n elem = elem[dir] || elem;\n } else if ((oldCache = uniqueCache[key]) &&\n oldCache[0] === dirruns && oldCache[1] === doneName) {\n\n // Assign to newCache so results back-propagate to previous elements\n return (newCache[2] = oldCache[2]);\n } else {\n // Reuse newcache so results back-propagate to previous elements\n uniqueCache[key] = newCache;\n\n // A match means we're done; a fail means we have to keep checking\n if ((newCache[2] = matcher(elem, context, xml))) {\n return true;\n }\n }\n }\n }\n }\n return false;\n };\n }\n\n function elementMatcher(matchers) {\n return matchers.length > 1 ?\n function (elem, context, xml) {\n var i = matchers.length;\n while (i--) {\n if (!matchers[i](elem, context, xml)) {\n return false;\n }\n }\n return true;\n } :\n matchers[0];\n }\n\n function multipleContexts(selector, contexts, results) {\n var i = 0,\n len = contexts.length;\n for (; i < len; i++) {\n Sizzle(selector, contexts[i], results);\n }\n return results;\n }\n\n function condense(unmatched, map, filter, context, xml) {\n var elem,\n newUnmatched = [],\n i = 0,\n len = unmatched.length,\n mapped = map != null;\n\n for (; i < len; i++) {\n if ((elem = unmatched[i])) {\n if (!filter || filter(elem, context, xml)) {\n newUnmatched.push(elem);\n if (mapped) {\n map.push(i);\n }\n }\n }\n }\n\n return newUnmatched;\n }\n\n function setMatcher(preFilter, selector, matcher, postFilter, postFinder, postSelector) {\n if (postFilter && !postFilter[expando]) {\n postFilter = setMatcher(postFilter);\n }\n if (postFinder && !postFinder[expando]) {\n postFinder = setMatcher(postFinder, postSelector);\n }\n return markFunction(function (seed, results, context, xml) {\n var temp, i, elem,\n preMap = [],\n postMap = [],\n preexisting = results.length,\n\n // Get initial elements from seed or context\n elems = seed || multipleContexts(selector || \"*\", context.nodeType ? [context] : context, []),\n\n // Prefilter to get matcher input, preserving a map for seed-results synchronization\n matcherIn = preFilter && (seed || !selector) ?\n condense(elems, preMap, preFilter, context, xml) :\n elems,\n\n matcherOut = matcher ?\n // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,\n postFinder || (seed ? preFilter : preexisting || postFilter) ?\n\n // ...intermediate processing is necessary\n [] :\n\n // ...otherwise use results directly\n results :\n matcherIn;\n\n // Find primary matches\n if (matcher) {\n matcher(matcherIn, matcherOut, context, xml);\n }\n\n // Apply postFilter\n if (postFilter) {\n temp = condense(matcherOut, postMap);\n postFilter(temp, [], context, xml);\n\n // Un-match failing elements by moving them back to matcherIn\n i = temp.length;\n while (i--) {\n if ((elem = temp[i])) {\n matcherOut[postMap[i]] = !(matcherIn[postMap[i]] = elem);\n }\n }\n }\n\n if (seed) {\n if (postFinder || preFilter) {\n if (postFinder) {\n // Get the final matcherOut by condensing this intermediate into postFinder contexts\n temp = [];\n i = matcherOut.length;\n while (i--) {\n if ((elem = matcherOut[i])) {\n // Restore matcherIn since elem is not yet a final match\n temp.push((matcherIn[i] = elem));\n }\n }\n postFinder(null, (matcherOut = []), temp, xml);\n }\n\n // Move matched elements from seed to results to keep them synchronized\n i = matcherOut.length;\n while (i--) {\n if ((elem = matcherOut[i]) &&\n (temp = postFinder ? indexOf(seed, elem) : preMap[i]) > -1) {\n\n seed[temp] = !(results[temp] = elem);\n }\n }\n }\n\n // Add elements to results, through postFinder if defined\n } else {\n matcherOut = condense(\n matcherOut === results ?\n matcherOut.splice(preexisting, matcherOut.length) :\n matcherOut\n );\n if (postFinder) {\n postFinder(null, results, matcherOut, xml);\n } else {\n push.apply(results, matcherOut);\n }\n }\n });\n }\n\n function matcherFromTokens(tokens) {\n var checkContext, matcher, j,\n len = tokens.length,\n leadingRelative = Expr.relative[tokens[0].type],\n implicitRelative = leadingRelative || Expr.relative[\" \"],\n i = leadingRelative ? 1 : 0,\n\n // The foundational matcher ensures that elements are reachable from top-level context(s)\n matchContext = addCombinator(function (elem) {\n return elem === checkContext;\n }, implicitRelative, true),\n matchAnyContext = addCombinator(function (elem) {\n return indexOf(checkContext, elem) > -1;\n }, implicitRelative, true),\n matchers = [function (elem, context, xml) {\n var ret = (!leadingRelative && (xml || context !== outermostContext)) || (\n (checkContext = context).nodeType ?\n matchContext(elem, context, xml) :\n matchAnyContext(elem, context, xml));\n // Avoid hanging onto element (issue #299)\n checkContext = null;\n return ret;\n }];\n\n for (; i < len; i++) {\n if ((matcher = Expr.relative[tokens[i].type])) {\n matchers = [addCombinator(elementMatcher(matchers), matcher)];\n } else {\n matcher = Expr.filter[tokens[i].type].apply(null, tokens[i].matches);\n\n // Return special upon seeing a positional matcher\n if (matcher[expando]) {\n // Find the next relative operator (if any) for proper handling\n j = ++i;\n for (; j < len; j++) {\n if (Expr.relative[tokens[j].type]) {\n break;\n }\n }\n return setMatcher(\n i > 1 && elementMatcher(matchers),\n i > 1 && toSelector(\n // If the preceding token was a descendant combinator, insert an implicit any-element `*`\n tokens.slice(0, i - 1).concat({value: tokens[i - 2].type === \" \" ? \"*\" : \"\"})\n ).replace(rtrim, \"$1\"),\n matcher,\n i < j && matcherFromTokens(tokens.slice(i, j)),\n j < len && matcherFromTokens((tokens = tokens.slice(j))),\n j < len && toSelector(tokens)\n );\n }\n matchers.push(matcher);\n }\n }\n\n return elementMatcher(matchers);\n }\n\n function matcherFromGroupMatchers(elementMatchers, setMatchers) {\n var bySet = setMatchers.length > 0,\n byElement = elementMatchers.length > 0,\n superMatcher = function (seed, context, xml, results, outermost) {\n var elem, j, matcher,\n matchedCount = 0,\n i = \"0\",\n unmatched = seed && [],\n setMatched = [],\n contextBackup = outermostContext,\n // We must always have either seed elements or outermost context\n elems = seed || byElement && Expr.find[\"TAG\"](\"*\", outermost),\n // Use integer dirruns iff this is the outermost matcher\n dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1),\n len = elems.length;\n\n if (outermost) {\n outermostContext = context === document || context || outermost;\n }\n\n // Add elements passing elementMatchers directly to results\n // Support: IE<9, Safari\n // Tolerate NodeList properties (IE: \"length\"; Safari: ) matching elements by id\n for (; i !== len && (elem = elems[i]) != null; i++) {\n if (byElement && elem) {\n j = 0;\n if (!context && elem.ownerDocument !== document) {\n setDocument(elem);\n xml = !documentIsHTML;\n }\n while ((matcher = elementMatchers[j++])) {\n if (matcher(elem, context || document, xml)) {\n results.push(elem);\n break;\n }\n }\n if (outermost) {\n dirruns = dirrunsUnique;\n }\n }\n\n // Track unmatched elements for set filters\n if (bySet) {\n // They will have gone through all possible matchers\n if ((elem = !matcher && elem)) {\n matchedCount--;\n }\n\n // Lengthen the array for every element, matched or not\n if (seed) {\n unmatched.push(elem);\n }\n }\n }\n\n // `i` is now the count of elements visited above, and adding it to `matchedCount`\n // makes the latter nonnegative.\n matchedCount += i;\n\n // Apply set filters to unmatched elements\n // NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount`\n // equals `i`), unless we didn't visit _any_ elements in the above loop because we have\n // no element matchers and no seed.\n // Incrementing an initially-string \"0\" `i` allows `i` to remain a string only in that\n // case, which will result in a \"00\" `matchedCount` that differs from `i` but is also\n // numerically zero.\n if (bySet && i !== matchedCount) {\n j = 0;\n while ((matcher = setMatchers[j++])) {\n matcher(unmatched, setMatched, context, xml);\n }\n\n if (seed) {\n // Reintegrate element matches to eliminate the need for sorting\n if (matchedCount > 0) {\n while (i--) {\n if (!(unmatched[i] || setMatched[i])) {\n setMatched[i] = pop.call(results);\n }\n }\n }\n\n // Discard index placeholder values to get only actual matches\n setMatched = condense(setMatched);\n }\n\n // Add matches to results\n push.apply(results, setMatched);\n\n // Seedless set matches succeeding multiple successful matchers stipulate sorting\n if (outermost && !seed && setMatched.length > 0 &&\n (matchedCount + setMatchers.length) > 1) {\n\n Sizzle.uniqueSort(results);\n }\n }\n\n // Override manipulation of globals by nested matchers\n if (outermost) {\n dirruns = dirrunsUnique;\n outermostContext = contextBackup;\n }\n\n return unmatched;\n };\n\n return bySet ?\n markFunction(superMatcher) :\n superMatcher;\n }\n\n compile = Sizzle.compile = function (selector, match /* Internal Use Only */) {\n var i,\n setMatchers = [],\n elementMatchers = [],\n cached = compilerCache[selector + \" \"];\n\n if (!cached) {\n // Generate a function of recursive functions that can be used to check each element\n if (!match) {\n match = tokenize(selector);\n }\n i = match.length;\n while (i--) {\n cached = matcherFromTokens(match[i]);\n if (cached[expando]) {\n setMatchers.push(cached);\n } else {\n elementMatchers.push(cached);\n }\n }\n\n // Cache the compiled function\n cached = compilerCache(selector, matcherFromGroupMatchers(elementMatchers, setMatchers));\n\n // Save selector and tokenization\n cached.selector = selector;\n }\n return cached;\n };\n\n /**\n * A low-level selection function that works with Sizzle's compiled\n * selector functions\n * @param {String|Function} selector A selector or a pre-compiled\n * selector function built with Sizzle.compile\n * @param {Element} context\n * @param {Array} [results]\n * @param {Array} [seed] A set of elements to match against\n */\n select = Sizzle.select = function (selector, context, results, seed) {\n var i, tokens, token, type, find,\n compiled = typeof selector === \"function\" && selector,\n match = !seed && tokenize((selector = compiled.selector || selector));\n\n results = results || [];\n\n // Try to minimize operations if there is only one selector in the list and no seed\n // (the latter of which guarantees us context)\n if (match.length === 1) {\n\n // Reduce context if the leading compound selector is an ID\n tokens = match[0] = match[0].slice(0);\n if (tokens.length > 2 && (token = tokens[0]).type === \"ID\" &&\n context.nodeType === 9 && documentIsHTML && Expr.relative[tokens[1].type]) {\n\n context = (Expr.find[\"ID\"](token.matches[0].replace(runescape, funescape), context) || [])[0];\n if (!context) {\n return results;\n\n // Precompiled matchers will still verify ancestry, so step up a level\n } else if (compiled) {\n context = context.parentNode;\n }\n\n selector = selector.slice(tokens.shift().value.length);\n }\n\n // Fetch a seed set for right-to-left matching\n i = matchExpr[\"needsContext\"].test(selector) ? 0 : tokens.length;\n while (i--) {\n token = tokens[i];\n\n // Abort if we hit a combinator\n if (Expr.relative[(type = token.type)]) {\n break;\n }\n if ((find = Expr.find[type])) {\n // Search, expanding context for leading sibling combinators\n if ((seed = find(\n token.matches[0].replace(runescape, funescape),\n rsibling.test(tokens[0].type) && testContext(context.parentNode) || context\n ))) {\n\n // If seed is empty or no tokens remain, we can return early\n tokens.splice(i, 1);\n selector = seed.length && toSelector(tokens);\n if (!selector) {\n push.apply(results, seed);\n return results;\n }\n\n break;\n }\n }\n }\n }\n\n // Compile and execute a filtering function if one is not provided\n // Provide `match` to avoid retokenization if we modified the selector above\n (compiled || compile(selector, match))(\n seed,\n context,\n !documentIsHTML,\n results,\n !context || rsibling.test(selector) && testContext(context.parentNode) || context\n );\n return results;\n };\n\n// One-time assignments\n\n// Sort stability\n support.sortStable = expando.split(\"\").sort(sortOrder).join(\"\") === expando;\n\n// Support: Chrome 14-35+\n// Always assume duplicates if they aren't passed to the comparison function\n support.detectDuplicates = !!hasDuplicate;\n\n// Initialize against the default document\n setDocument();\n \n return Sizzle;\n\n })(window);\n\n\njQuery.find = Sizzle;\njQuery.expr = Sizzle.selectors;\n\n// Deprecated\njQuery.expr[\":\"] = jQuery.expr.pseudos;\njQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort;\njQuery.text = Sizzle.getText;\njQuery.isXMLDoc = Sizzle.isXML;\njQuery.contains = Sizzle.contains;\njQuery.escapeSelector = Sizzle.escape;\n\n\nvar dir = function (elem, dir, until) {\n var matched = [],\n truncate = until !== undefined;\n\n while ((elem = elem[dir]) && elem.nodeType !== 9) {\n if (elem.nodeType === 1) {\n if (truncate && jQuery(elem).is(until)) {\n break;\n }\n matched.push(elem);\n }\n }\n return matched;\n};\n\n\nvar siblings = function (n, elem) {\n var matched = [];\n\n for (; n; n = n.nextSibling) {\n if (n.nodeType === 1 && n !== elem) {\n matched.push(n);\n }\n }\n\n return matched;\n};\n\n\nvar rneedsContext = jQuery.expr.match.needsContext;\n\n\nfunction nodeName(elem, name) {\n\n return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();\n\n}\nvar rsingleTag = (/^<([a-z][^\\/\\0>:\\x20\\t\\r\\n\\f]*)[\\x20\\t\\r\\n\\f]*\\/?>(?:<\\/\\1>|)$/i);\n\n\n// Implement the identical functionality for filter and not\nfunction winnow(elements, qualifier, not) {\n if (isFunction(qualifier)) {\n return jQuery.grep(elements, function (elem, i) {\n return !!qualifier.call(elem, i, elem) !== not;\n });\n }\n\n // Single element\n if (qualifier.nodeType) {\n return jQuery.grep(elements, function (elem) {\n return (elem === qualifier) !== not;\n });\n }\n\n // Arraylike of elements (jQuery, arguments, Array)\n if (typeof qualifier !== \"string\") {\n return jQuery.grep(elements, function (elem) {\n return (indexOf.call(qualifier, elem) > -1) !== not;\n });\n }\n\n // Filtered directly for both simple and complex selectors\n return jQuery.filter(qualifier, elements, not);\n}\n\njQuery.filter = function (expr, elems, not) {\n var elem = elems[0];\n\n if (not) {\n expr = \":not(\" + expr + \")\";\n }\n\n if (elems.length === 1 && elem.nodeType === 1) {\n return jQuery.find.matchesSelector(elem, expr) ? [elem] : [];\n }\n\n return jQuery.find.matches(expr, jQuery.grep(elems, function (elem) {\n return elem.nodeType === 1;\n }));\n};\n\njQuery.fn.extend({\n find: function (selector) {\n var i, ret,\n len = this.length,\n self = this;\n\n if (typeof selector !== \"string\") {\n return this.pushStack(jQuery(selector).filter(function () {\n for (i = 0; i < len; i++) {\n if (jQuery.contains(self[i], this)) {\n return true;\n }\n }\n }));\n }\n\n ret = this.pushStack([]);\n\n for (i = 0; i < len; i++) {\n jQuery.find(selector, self[i], ret);\n }\n\n return len > 1 ? jQuery.uniqueSort(ret) : ret;\n },\n filter: function (selector) {\n return this.pushStack(winnow(this, selector || [], false));\n },\n not: function (selector) {\n return this.pushStack(winnow(this, selector || [], true));\n },\n is: function (selector) {\n return !!winnow(\n this,\n\n // If this is a positional/relative selector, check membership in the returned set\n // so $(\"p:first\").is(\"p:last\") won't return true for a doc with two \"p\".\n typeof selector === \"string\" && rneedsContext.test(selector) ?\n jQuery(selector) :\n selector || [],\n false\n ).length;\n }\n});\n\n\n// Initialize a jQuery object\n\n\n// A central reference to the root jQuery(document)\nvar rootjQuery,\n\n // A simple way to check for HTML strings\n // Prioritize #id over to avoid XSS via location.hash (#9521)\n // Strict HTML recognition (#11290: must start with <)\n // Shortcut simple #id case for speed\n rquickExpr = /^(?:\\s*(<[\\w\\W]+>)[^>]*|#([\\w-]+))$/,\n\n init$2 = jQuery.fn.init = function (selector, context, root) {\n var match, elem;\n\n // HANDLE: $(\"\"), $(null), $(undefined), $(false)\n if (!selector) {\n return this;\n }\n\n // Method init() accepts an alternate rootjQuery\n // so migrate can support jQuery.sub (gh-2101)\n root = root || rootjQuery;\n\n // Handle HTML strings\n if (typeof selector === \"string\") {\n if (selector[0] === \"<\" &&\n selector[selector.length - 1] === \">\" &&\n selector.length >= 3) {\n\n // Assume that strings that start and end with <> are HTML and skip the regex check\n match = [null, selector, null];\n\n } else {\n match = rquickExpr.exec(selector);\n }\n\n // Match html or make sure no context is specified for #id\n if (match && (match[1] || !context)) {\n\n // HANDLE: $(html) -> $(array)\n if (match[1]) {\n context = context instanceof jQuery ? context[0] : context;\n\n // Option to run scripts is true for back-compat\n // Intentionally let the error be thrown if parseHTML is not present\n jQuery.merge(this, jQuery.parseHTML(\n match[1],\n context && context.nodeType ? context.ownerDocument || context : document$1,\n true\n ));\n\n // HANDLE: $(html, props)\n if (rsingleTag.test(match[1]) && jQuery.isPlainObject(context)) {\n for (match in context) {\n\n // Properties of context are called as methods if possible\n if (isFunction(this[match])) {\n this[match](context[match]);\n\n // ...and otherwise set as attributes\n } else {\n this.attr(match, context[match]);\n }\n }\n }\n\n return this;\n\n // HANDLE: $(#id)\n } else {\n elem = document$1.getElementById(match[2]);\n\n if (elem) {\n\n // Inject the element directly into the jQuery object\n this[0] = elem;\n this.length = 1;\n }\n return this;\n }\n\n // HANDLE: $(expr, $(...))\n } else if (!context || context.jquery) {\n return (context || root).find(selector);\n\n // HANDLE: $(expr, context)\n // (which is just equivalent to: $(context).find(expr)\n } else {\n return this.constructor(context).find(selector);\n }\n\n // HANDLE: $(DOMElement)\n } else if (selector.nodeType) {\n this[0] = selector;\n this.length = 1;\n return this;\n\n // HANDLE: $(function)\n // Shortcut for document ready\n } else if (isFunction(selector)) {\n return root.ready !== undefined ?\n root.ready(selector) :\n\n // Execute immediately if ready is not present\n selector(jQuery);\n }\n\n return jQuery.makeArray(selector, this);\n };\n\n// Give the init function the jQuery prototype for later instantiation\ninit$2.prototype = jQuery.fn;\n\n// Initialize central reference\nrootjQuery = jQuery(document$1);\n\n\nvar rparentsprev = /^(?:parents|prev(?:Until|All))/,\n\n // Methods guaranteed to produce a unique set when starting from a unique set\n guaranteedUnique = {\n children: true,\n contents: true,\n next: true,\n prev: true\n };\n\njQuery.fn.extend({\n has: function (target) {\n var targets = jQuery(target, this),\n l = targets.length;\n\n return this.filter(function () {\n var i = 0;\n for (; i < l; i++) {\n if (jQuery.contains(this, targets[i])) {\n return true;\n }\n }\n });\n },\n\n closest: function (selectors, context) {\n var cur,\n i = 0,\n l = this.length,\n matched = [],\n targets = typeof selectors !== \"string\" && jQuery(selectors);\n\n // Positional selectors never match, since there's no _selection_ context\n if (!rneedsContext.test(selectors)) {\n for (; i < l; i++) {\n for (cur = this[i]; cur && cur !== context; cur = cur.parentNode) {\n\n // Always skip document fragments\n if (cur.nodeType < 11 && (targets ?\n targets.index(cur) > -1 :\n\n // Don't pass non-elements to Sizzle\n cur.nodeType === 1 &&\n jQuery.find.matchesSelector(cur, selectors))) {\n\n matched.push(cur);\n break;\n }\n }\n }\n }\n\n return this.pushStack(matched.length > 1 ? jQuery.uniqueSort(matched) : matched);\n },\n\n // Determine the position of an element within the set\n index: function (elem) {\n\n // No argument, return index in parent\n if (!elem) {\n return (this[0] && this[0].parentNode) ? this.first().prevAll().length : -1;\n }\n\n // Index in selector\n if (typeof elem === \"string\") {\n return indexOf.call(jQuery(elem), this[0]);\n }\n\n // Locate the position of the desired element\n return indexOf.call(this,\n\n // If it receives a jQuery object, the first element is used\n elem.jquery ? elem[0] : elem\n );\n },\n\n add: function (selector, context) {\n return this.pushStack(\n jQuery.uniqueSort(\n jQuery.merge(this.get(), jQuery(selector, context))\n )\n );\n },\n\n addBack: function (selector) {\n return this.add(selector == null ?\n this.prevObject : this.prevObject.filter(selector)\n );\n }\n});\n\nfunction sibling(cur, dir) {\n while ((cur = cur[dir]) && cur.nodeType !== 1) {\n }\n return cur;\n}\n\njQuery.each({\n parent: function (elem) {\n var parent = elem.parentNode;\n return parent && parent.nodeType !== 11 ? parent : null;\n },\n parents: function (elem) {\n return dir(elem, \"parentNode\");\n },\n parentsUntil: function (elem, i, until) {\n return dir(elem, \"parentNode\", until);\n },\n next: function (elem) {\n return sibling(elem, \"nextSibling\");\n },\n prev: function (elem) {\n return sibling(elem, \"previousSibling\");\n },\n nextAll: function (elem) {\n return dir(elem, \"nextSibling\");\n },\n prevAll: function (elem) {\n return dir(elem, \"previousSibling\");\n },\n nextUntil: function (elem, i, until) {\n return dir(elem, \"nextSibling\", until);\n },\n prevUntil: function (elem, i, until) {\n return dir(elem, \"previousSibling\", until);\n },\n siblings: function (elem) {\n return siblings((elem.parentNode || {}).firstChild, elem);\n },\n children: function (elem) {\n return siblings(elem.firstChild);\n },\n contents: function (elem) {\n if (nodeName(elem, \"iframe\")) {\n return elem.contentDocument;\n }\n\n // Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only\n // Treat the template element as a regular one in browsers that\n // don't support it.\n if (nodeName(elem, \"template\")) {\n elem = elem.content || elem;\n }\n\n return jQuery.merge([], elem.childNodes);\n }\n}, function (name, fn) {\n jQuery.fn[name] = function (until, selector) {\n var matched = jQuery.map(this, fn, until);\n\n if (name.slice(-5) !== \"Until\") {\n selector = until;\n }\n\n if (selector && typeof selector === \"string\") {\n matched = jQuery.filter(selector, matched);\n }\n\n if (this.length > 1) {\n\n // Remove duplicates\n if (!guaranteedUnique[name]) {\n jQuery.uniqueSort(matched);\n }\n\n // Reverse order for parents* and prev-derivatives\n if (rparentsprev.test(name)) {\n matched.reverse();\n }\n }\n\n return this.pushStack(matched);\n };\n});\nvar rnothtmlwhite = (/[^\\x20\\t\\r\\n\\f]+/g);\n\n\n// Convert String-formatted options into Object-formatted ones\nfunction createOptions(options) {\n var object = {};\n jQuery.each(options.match(rnothtmlwhite) || [], function (_, flag) {\n object[flag] = true;\n });\n return object;\n}\n\n/*\n * Create a callback list using the following parameters:\n *\n *\toptions: an optional list of space-separated options that will change how\n *\t\t\tthe callback list behaves or a more traditional option object\n *\n * By default a callback list will act like an event callback list and can be\n * \"fired\" multiple times.\n *\n * Possible options:\n *\n *\tonce:\t\t\twill ensure the callback list can only be fired once (like a Deferred)\n *\n *\tmemory:\t\t\twill keep track of previous values and will call any callback added\n *\t\t\t\t\tafter the list has been fired right away with the latest \"memorized\"\n *\t\t\t\t\tvalues (like a Deferred)\n *\n *\tunique:\t\t\twill ensure a callback can only be added once (no duplicate in the list)\n *\n *\tstopOnFalse:\tinterrupt callings when a callback returns false\n *\n */\njQuery.Callbacks = function (options) {\n\n // Convert options from String-formatted to Object-formatted if needed\n // (we check in cache first)\n options = typeof options === \"string\" ?\n createOptions(options) :\n jQuery.extend({}, options);\n\n var // Flag to know if list is currently firing\n firing,\n\n // Last fire value for non-forgettable lists\n memory,\n\n // Flag to know if list was already fired\n fired,\n\n // Flag to prevent firing\n locked,\n\n // Actual callback list\n list = [],\n\n // Queue of execution data for repeatable lists\n queue = [],\n\n // Index of currently firing callback (modified by add/remove as needed)\n firingIndex = -1,\n\n // Fire callbacks\n fire = function () {\n\n // Enforce single-firing\n locked = locked || options.once;\n\n // Execute callbacks for all pending executions,\n // respecting firingIndex overrides and runtime changes\n fired = firing = true;\n for (; queue.length; firingIndex = -1) {\n memory = queue.shift();\n while (++firingIndex < list.length) {\n\n // Run callback and check for early termination\n if (list[firingIndex].apply(memory[0], memory[1]) === false &&\n options.stopOnFalse) {\n\n // Jump to end and forget the data so .add doesn't re-fire\n firingIndex = list.length;\n memory = false;\n }\n }\n }\n\n // Forget the data if we're done with it\n if (!options.memory) {\n memory = false;\n }\n\n firing = false;\n\n // Clean up if we're done firing for good\n if (locked) {\n\n // Keep an empty list if we have data for future add calls\n if (memory) {\n list = [];\n\n // Otherwise, this object is spent\n } else {\n list = \"\";\n }\n }\n },\n\n // Actual Callbacks object\n self = {\n\n // Add a callback or a collection of callbacks to the list\n add: function () {\n if (list) {\n\n // If we have memory from a past run, we should fire after adding\n if (memory && !firing) {\n firingIndex = list.length - 1;\n queue.push(memory);\n }\n\n (function add(args) {\n jQuery.each(args, function (_, arg) {\n if (isFunction(arg)) {\n if (!options.unique || !self.has(arg)) {\n list.push(arg);\n }\n } else if (arg && arg.length && toType(arg) !== \"string\") {\n\n // Inspect recursively\n add(arg);\n }\n });\n })(arguments);\n\n if (memory && !firing) {\n fire();\n }\n }\n return this;\n },\n\n // Remove a callback from the list\n remove: function () {\n jQuery.each(arguments, function (_, arg) {\n var index;\n while ((index = jQuery.inArray(arg, list, index)) > -1) {\n list.splice(index, 1);\n\n // Handle firing indexes\n if (index <= firingIndex) {\n firingIndex--;\n }\n }\n });\n return this;\n },\n\n // Check if a given callback is in the list.\n // If no argument is given, return whether or not list has callbacks attached.\n has: function (fn) {\n return fn ?\n jQuery.inArray(fn, list) > -1 :\n list.length > 0;\n },\n\n // Remove all callbacks from the list\n empty: function () {\n if (list) {\n list = [];\n }\n return this;\n },\n\n // Disable .fire and .add\n // Abort any current/pending executions\n // Clear all callbacks and values\n disable: function () {\n locked = queue = [];\n list = memory = \"\";\n return this;\n },\n disabled: function () {\n return !list;\n },\n\n // Disable .fire\n // Also disable .add unless we have memory (since it would have no effect)\n // Abort any pending executions\n lock: function () {\n locked = queue = [];\n if (!memory && !firing) {\n list = memory = \"\";\n }\n return this;\n },\n locked: function () {\n return !!locked;\n },\n\n // Call all callbacks with the given context and arguments\n fireWith: function (context, args) {\n if (!locked) {\n args = args || [];\n args = [context, args.slice ? args.slice() : args];\n queue.push(args);\n if (!firing) {\n fire();\n }\n }\n return this;\n },\n\n // Call all the callbacks with the given arguments\n fire: function () {\n self.fireWith(this, arguments);\n return this;\n },\n\n // To know if the callbacks have already been called at least once\n fired: function () {\n return !!fired;\n }\n };\n\n return self;\n};\n\n\nfunction Identity(v) {\n return v;\n}\n\nfunction Thrower(ex) {\n throw ex;\n}\n\nfunction adoptValue(value, resolve, reject, noValue) {\n var method;\n\n try {\n\n // Check for promise aspect first to privilege synchronous behavior\n if (value && isFunction((method = value.promise))) {\n method.call(value).done(resolve).fail(reject);\n\n // Other thenables\n } else if (value && isFunction((method = value.then))) {\n method.call(value, resolve, reject);\n\n // Other non-thenables\n } else {\n\n // Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer:\n // * false: [ value ].slice( 0 ) => resolve( value )\n // * true: [ value ].slice( 1 ) => resolve()\n resolve.apply(undefined, [value].slice(noValue));\n }\n\n // For Promises/A+, convert exceptions into rejections\n // Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in\n // Deferred#then to conditionally suppress rejection.\n } catch (value) {\n\n // Support: Android 4.0 only\n // Strict mode functions invoked without .call/.apply get global-object context\n reject.apply(undefined, [value]);\n }\n}\n\njQuery.extend({\n\n Deferred: function (func) {\n var tuples = [\n\n // action, add listener, callbacks,\n // ... .then handlers, argument index, [final state]\n [\"notify\", \"progress\", jQuery.Callbacks(\"memory\"),\n jQuery.Callbacks(\"memory\"), 2],\n [\"resolve\", \"done\", jQuery.Callbacks(\"once memory\"),\n jQuery.Callbacks(\"once memory\"), 0, \"resolved\"],\n [\"reject\", \"fail\", jQuery.Callbacks(\"once memory\"),\n jQuery.Callbacks(\"once memory\"), 1, \"rejected\"]\n ],\n state = \"pending\",\n promise = {\n state: function () {\n return state;\n },\n always: function () {\n deferred.done(arguments).fail(arguments);\n return this;\n },\n \"catch\": function (fn) {\n return promise.then(null, fn);\n },\n\n // Keep pipe for back-compat\n pipe: function ( /* fnDone, fnFail, fnProgress */) {\n var fns = arguments;\n\n return jQuery.Deferred(function (newDefer) {\n jQuery.each(tuples, function (i, tuple) {\n\n // Map tuples (progress, done, fail) to arguments (done, fail, progress)\n var fn = isFunction(fns[tuple[4]]) && fns[tuple[4]];\n\n // deferred.progress(function() { bind to newDefer or newDefer.notify })\n // deferred.done(function() { bind to newDefer or newDefer.resolve })\n // deferred.fail(function() { bind to newDefer or newDefer.reject })\n deferred[tuple[1]](function () {\n var returned = fn && fn.apply(this, arguments);\n if (returned && isFunction(returned.promise)) {\n returned.promise()\n .progress(newDefer.notify)\n .done(newDefer.resolve)\n .fail(newDefer.reject);\n } else {\n newDefer[tuple[0] + \"With\"](\n this,\n fn ? [returned] : arguments\n );\n }\n });\n });\n fns = null;\n }).promise();\n },\n then: function (onFulfilled, onRejected, onProgress) {\n var maxDepth = 0;\n\n function resolve(depth, deferred, handler, special) {\n return function () {\n var that = this,\n args = arguments,\n mightThrow = function () {\n var returned, then;\n\n // Support: Promises/A+ section 2.3.3.3.3\n // https://promisesaplus.com/#point-59\n // Ignore double-resolution attempts\n if (depth < maxDepth) {\n return;\n }\n\n returned = handler.apply(that, args);\n\n // Support: Promises/A+ section 2.3.1\n // https://promisesaplus.com/#point-48\n if (returned === deferred.promise()) {\n throw new TypeError(\"Thenable self-resolution\");\n }\n\n // Support: Promises/A+ sections 2.3.3.1, 3.5\n // https://promisesaplus.com/#point-54\n // https://promisesaplus.com/#point-75\n // Retrieve `then` only once\n then = returned &&\n\n // Support: Promises/A+ section 2.3.4\n // https://promisesaplus.com/#point-64\n // Only check objects and functions for thenability\n (typeof returned === \"object\" ||\n typeof returned === \"function\") &&\n returned.then;\n\n // Handle a returned thenable\n if (isFunction(then)) {\n\n // Special processors (notify) just wait for resolution\n if (special) {\n then.call(\n returned,\n resolve(maxDepth, deferred, Identity, special),\n resolve(maxDepth, deferred, Thrower, special)\n );\n\n // Normal processors (resolve) also hook into progress\n } else {\n\n // ...and disregard older resolution values\n maxDepth++;\n\n then.call(\n returned,\n resolve(maxDepth, deferred, Identity, special),\n resolve(maxDepth, deferred, Thrower, special),\n resolve(maxDepth, deferred, Identity,\n deferred.notifyWith)\n );\n }\n\n // Handle all other returned values\n } else {\n\n // Only substitute handlers pass on context\n // and multiple values (non-spec behavior)\n if (handler !== Identity) {\n that = undefined;\n args = [returned];\n }\n\n // Process the value(s)\n // Default process is resolve\n (special || deferred.resolveWith)(that, args);\n }\n },\n\n // Only normal processors (resolve) catch and reject exceptions\n process = special ?\n mightThrow :\n function () {\n try {\n mightThrow();\n } catch (e) {\n\n if (jQuery.Deferred.exceptionHook) {\n jQuery.Deferred.exceptionHook(e,\n process.stackTrace);\n }\n\n // Support: Promises/A+ section 2.3.3.3.4.1\n // https://promisesaplus.com/#point-61\n // Ignore post-resolution exceptions\n if (depth + 1 >= maxDepth) {\n\n // Only substitute handlers pass on context\n // and multiple values (non-spec behavior)\n if (handler !== Thrower) {\n that = undefined;\n args = [e];\n }\n\n deferred.rejectWith(that, args);\n }\n }\n };\n\n // Support: Promises/A+ section 2.3.3.3.1\n // https://promisesaplus.com/#point-57\n // Re-resolve promises immediately to dodge false rejection from\n // subsequent errors\n if (depth) {\n process();\n } else {\n\n // Call an optional hook to record the stack, in case of exception\n // since it's otherwise lost when execution goes async\n if (jQuery.Deferred.getStackHook) {\n process.stackTrace = jQuery.Deferred.getStackHook();\n }\n window.setTimeout(process);\n }\n };\n }\n\n return jQuery.Deferred(function (newDefer) {\n\n // progress_handlers.add( ... )\n tuples[0][3].add(\n resolve(\n 0,\n newDefer,\n isFunction(onProgress) ?\n onProgress :\n Identity,\n newDefer.notifyWith\n )\n );\n\n // fulfilled_handlers.add( ... )\n tuples[1][3].add(\n resolve(\n 0,\n newDefer,\n isFunction(onFulfilled) ?\n onFulfilled :\n Identity\n )\n );\n\n // rejected_handlers.add( ... )\n tuples[2][3].add(\n resolve(\n 0,\n newDefer,\n isFunction(onRejected) ?\n onRejected :\n Thrower\n )\n );\n }).promise();\n },\n\n // Get a promise for this deferred\n // If obj is provided, the promise aspect is added to the object\n promise: function (obj) {\n return obj != null ? jQuery.extend(obj, promise) : promise;\n }\n },\n deferred = {};\n\n // Add list-specific methods\n jQuery.each(tuples, function (i, tuple) {\n var list = tuple[2],\n stateString = tuple[5];\n\n // promise.progress = list.add\n // promise.done = list.add\n // promise.fail = list.add\n promise[tuple[1]] = list.add;\n\n // Handle state\n if (stateString) {\n list.add(\n function () {\n\n // state = \"resolved\" (i.e., fulfilled)\n // state = \"rejected\"\n state = stateString;\n },\n\n // rejected_callbacks.disable\n // fulfilled_callbacks.disable\n tuples[3 - i][2].disable,\n\n // rejected_handlers.disable\n // fulfilled_handlers.disable\n tuples[3 - i][3].disable,\n\n // progress_callbacks.lock\n tuples[0][2].lock,\n\n // progress_handlers.lock\n tuples[0][3].lock\n );\n }\n\n // progress_handlers.fire\n // fulfilled_handlers.fire\n // rejected_handlers.fire\n list.add(tuple[3].fire);\n\n // deferred.notify = function() { deferred.notifyWith(...) }\n // deferred.resolve = function() { deferred.resolveWith(...) }\n // deferred.reject = function() { deferred.rejectWith(...) }\n deferred[tuple[0]] = function () {\n deferred[tuple[0] + \"With\"](this === deferred ? undefined : this, arguments);\n return this;\n };\n\n // deferred.notifyWith = list.fireWith\n // deferred.resolveWith = list.fireWith\n // deferred.rejectWith = list.fireWith\n deferred[tuple[0] + \"With\"] = list.fireWith;\n });\n\n // Make the deferred a promise\n promise.promise(deferred);\n\n // Call given func if any\n if (func) {\n func.call(deferred, deferred);\n }\n\n // All done!\n return deferred;\n },\n\n // Deferred helper\n when: function (singleValue) {\n var\n\n // count of uncompleted subordinates\n remaining = arguments.length,\n\n // count of unprocessed arguments\n i = remaining,\n\n // subordinate fulfillment data\n resolveContexts = Array(i),\n resolveValues = slice.call(arguments),\n\n // the master Deferred\n master = jQuery.Deferred(),\n\n // subordinate callback factory\n updateFunc = function (i) {\n return function (value) {\n resolveContexts[i] = this;\n resolveValues[i] = arguments.length > 1 ? slice.call(arguments) : value;\n if (!(--remaining)) {\n master.resolveWith(resolveContexts, resolveValues);\n }\n };\n };\n\n // Single- and empty arguments are adopted like Promise.resolve\n if (remaining <= 1) {\n adoptValue(singleValue, master.done(updateFunc(i)).resolve, master.reject,\n !remaining);\n\n // Use .then() to unwrap secondary thenables (cf. gh-3000)\n if (master.state() === \"pending\" ||\n isFunction(resolveValues[i] && resolveValues[i].then)) {\n\n return master.then();\n }\n }\n\n // Multiple arguments are aggregated like Promise.all array elements\n while (i--) {\n adoptValue(resolveValues[i], updateFunc(i), master.reject);\n }\n\n return master.promise();\n }\n});\n\n\n// These usually indicate a programmer mistake during development,\n// warn about them ASAP rather than swallowing them by default.\nvar rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;\n\njQuery.Deferred.exceptionHook = function (error, stack) {\n\n // Support: IE 8 - 9 only\n // Console exists when dev tools are open, which can happen at any time\n if (window.console && window.console.warn && error && rerrorNames.test(error.name)) {\n window.console.warn(\"jQuery.Deferred exception: \" + error.message, error.stack, stack);\n }\n};\n\n\njQuery.readyException = function (error) {\n window.setTimeout(function () {\n throw error;\n });\n};\n\n\n// The deferred used on DOM ready\nvar readyList = jQuery.Deferred();\n\njQuery.fn.ready = function (fn) {\n\n readyList\n .then(fn)\n\n // Wrap jQuery.readyException in a function so that the lookup\n // happens at the time of error handling instead of callback\n // registration.\n .catch(function (error) {\n jQuery.readyException(error);\n });\n\n return this;\n};\n\njQuery.extend({\n\n // Is the DOM ready to be used? Set to true once it occurs.\n isReady: false,\n\n // A counter to track how many items to wait for before\n // the ready event fires. See #6781\n readyWait: 1,\n\n // Handle when the DOM is ready\n ready: function (wait) {\n\n // Abort if there are pending holds or we're already ready\n if (wait === true ? --jQuery.readyWait : jQuery.isReady) {\n return;\n }\n\n // Remember that the DOM is ready\n jQuery.isReady = true;\n\n // If a normal DOM Ready event fired, decrement, and wait if need be\n if (wait !== true && --jQuery.readyWait > 0) {\n return;\n }\n\n // If there are functions bound, to execute\n readyList.resolveWith(document$1, [jQuery]);\n }\n});\n\njQuery.ready.then = readyList.then;\n\n// The ready event handler and self cleanup method\nfunction completed() {\n document$1.removeEventListener(\"DOMContentLoaded\", completed);\n window.removeEventListener(\"load\", completed);\n jQuery.ready();\n}\n\n// Catch cases where $(document).ready() is called\n// after the browser event has already occurred.\n// Support: IE <=9 - 10 only\n// Older IE sometimes signals \"interactive\" too soon\nif (document$1.readyState === \"complete\" ||\n (document$1.readyState !== \"loading\" && !document$1.documentElement.doScroll)) {\n\n // Handle it asynchronously to allow scripts the opportunity to delay ready\n window.setTimeout(jQuery.ready);\n\n} else {\n\n // Use the handy event callback\n document$1.addEventListener(\"DOMContentLoaded\", completed);\n\n // A fallback to window.onload, that will always work\n window.addEventListener(\"load\", completed);\n}\n\n\n// Multifunctional method to get and set values of a collection\n// The value/s can optionally be executed if it's a function\nvar access = function (elems, fn, key, value, chainable, emptyGet, raw) {\n var i = 0,\n len = elems.length,\n bulk = key == null;\n\n // Sets many values\n if (toType(key) === \"object\") {\n chainable = true;\n for (i in key) {\n access(elems, fn, i, key[i], true, emptyGet, raw);\n }\n\n // Sets one value\n } else if (value !== undefined) {\n chainable = true;\n\n if (!isFunction(value)) {\n raw = true;\n }\n\n if (bulk) {\n\n // Bulk operations run against the entire set\n if (raw) {\n fn.call(elems, value);\n fn = null;\n\n // ...except when executing function values\n } else {\n bulk = fn;\n fn = function (elem, key, value) {\n return bulk.call(jQuery(elem), value);\n };\n }\n }\n\n if (fn) {\n for (; i < len; i++) {\n fn(\n elems[i], key, raw ?\n value :\n value.call(elems[i], i, fn(elems[i], key))\n );\n }\n }\n }\n\n if (chainable) {\n return elems;\n }\n\n // Gets\n if (bulk) {\n return fn.call(elems);\n }\n\n return len ? fn(elems[0], key) : emptyGet;\n};\n\n\n// Matches dashed string for camelizing\nvar rmsPrefix = /^-ms-/,\n rdashAlpha = /-([a-z])/g;\n\n// Used by camelCase as callback to replace()\nfunction fcamelCase(all, letter) {\n return letter.toUpperCase();\n}\n\n// Convert dashed to camelCase; used by the css and data modules\n// Support: IE <=9 - 11, Edge 12 - 15\n// Microsoft forgot to hump their vendor prefix (#9572)\nfunction camelCase(string) {\n return string.replace(rmsPrefix, \"ms-\").replace(rdashAlpha, fcamelCase);\n}\n\nvar acceptData = function (owner) {\n\n // Accepts only:\n // - Node\n // - Node.ELEMENT_NODE\n // - Node.DOCUMENT_NODE\n // - Object\n // - Any\n return owner.nodeType === 1 || owner.nodeType === 9 || !(+owner.nodeType);\n};\n\n\nfunction Data() {\n this.expando = jQuery.expando + Data.uid++;\n}\n\nData.uid = 1;\n\nData.prototype = {\n\n cache: function (owner) {\n\n // Check if the owner object already has a cache\n var value = owner[this.expando];\n\n // If not, create one\n if (!value) {\n value = {};\n\n // We can accept data for non-element nodes in modern browsers,\n // but we should not, see #8335.\n // Always return an empty object.\n if (acceptData(owner)) {\n\n // If it is a node unlikely to be stringify-ed or looped over\n // use plain assignment\n if (owner.nodeType) {\n owner[this.expando] = value;\n\n // Otherwise secure it in a non-enumerable property\n // configurable must be true to allow the property to be\n // deleted when data is removed\n } else {\n Object.defineProperty(owner, this.expando, {\n value: value,\n configurable: true\n });\n }\n }\n }\n\n return value;\n },\n set: function (owner, data, value) {\n var prop,\n cache = this.cache(owner);\n\n // Handle: [ owner, key, value ] args\n // Always use camelCase key (gh-2257)\n if (typeof data === \"string\") {\n cache[camelCase(data)] = value;\n\n // Handle: [ owner, { properties } ] args\n } else {\n\n // Copy the properties one-by-one to the cache object\n for (prop in data) {\n cache[camelCase(prop)] = data[prop];\n }\n }\n return cache;\n },\n get: function (owner, key) {\n return key === undefined ?\n this.cache(owner) :\n\n // Always use camelCase key (gh-2257)\n owner[this.expando] && owner[this.expando][camelCase(key)];\n },\n access: function (owner, key, value) {\n\n // In cases where either:\n //\n // 1. No key was specified\n // 2. A string key was specified, but no value provided\n //\n // Take the \"read\" path and allow the get method to determine\n // which value to return, respectively either:\n //\n // 1. The entire cache object\n // 2. The data stored at the key\n //\n if (key === undefined ||\n ((key && typeof key === \"string\") && value === undefined)) {\n\n return this.get(owner, key);\n }\n\n // When the key is not a string, or both a key and value\n // are specified, set or extend (existing objects) with either:\n //\n // 1. An object of properties\n // 2. A key and value\n //\n this.set(owner, key, value);\n\n // Since the \"set\" path can have two possible entry points\n // return the expected data based on which path was taken[*]\n return value !== undefined ? value : key;\n },\n remove: function (owner, key) {\n var i,\n cache = owner[this.expando];\n\n if (cache === undefined) {\n return;\n }\n\n if (key !== undefined) {\n\n // Support array or space separated string of keys\n if (Array.isArray(key)) {\n\n // If key is an array of keys...\n // We always set camelCase keys, so remove that.\n key = key.map(camelCase);\n } else {\n key = camelCase(key);\n\n // If a key with the spaces exists, use it.\n // Otherwise, create an array by matching non-whitespace\n key = key in cache ?\n [key] :\n (key.match(rnothtmlwhite) || []);\n }\n\n i = key.length;\n\n while (i--) {\n delete cache[key[i]];\n }\n }\n\n // Remove the expando if there's no more data\n if (key === undefined || jQuery.isEmptyObject(cache)) {\n\n // Support: Chrome <=35 - 45\n // Webkit & Blink performance suffers when deleting properties\n // from DOM nodes, so set to undefined instead\n // https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted)\n if (owner.nodeType) {\n owner[this.expando] = undefined;\n } else {\n delete owner[this.expando];\n }\n }\n },\n hasData: function (owner) {\n var cache = owner[this.expando];\n return cache !== undefined && !jQuery.isEmptyObject(cache);\n }\n};\nvar dataPriv = new Data();\n\nvar dataUser = new Data();\n\n\n//\tImplementation Summary\n//\n//\t1. Enforce API surface and semantic compatibility with 1.9.x branch\n//\t2. Improve the module's maintainability by reducing the storage\n//\t\tpaths to a single mechanism.\n//\t3. Use the same single mechanism to support \"private\" and \"user\" data.\n//\t4. _Never_ expose \"private\" data to user code (TODO: Drop _data, _removeData)\n//\t5. Avoid exposing implementation details on user objects (eg. expando properties)\n//\t6. Provide a clear path for implementation upgrade to WeakMap in 2014\n\nvar rbrace = /^(?:\\{[\\w\\W]*\\}|\\[[\\w\\W]*\\])$/,\n rmultiDash = /[A-Z]/g;\n\nfunction getData(data) {\n if (data === \"true\") {\n return true;\n }\n\n if (data === \"false\") {\n return false;\n }\n\n if (data === \"null\") {\n return null;\n }\n\n // Only convert to a number if it doesn't change the string\n if (data === +data + \"\") {\n return +data;\n }\n\n if (rbrace.test(data)) {\n return JSON.parse(data);\n }\n\n return data;\n}\n\nfunction dataAttr(elem, key, data) {\n var name;\n\n // If nothing was found internally, try to fetch any\n // data from the HTML5 data-* attribute\n if (data === undefined && elem.nodeType === 1) {\n name = \"data-\" + key.replace(rmultiDash, \"-$&\").toLowerCase();\n data = elem.getAttribute(name);\n\n if (typeof data === \"string\") {\n try {\n data = getData(data);\n } catch (e) {\n }\n\n // Make sure we set the data so it isn't changed later\n dataUser.set(elem, key, data);\n } else {\n data = undefined;\n }\n }\n return data;\n}\n\njQuery.extend({\n hasData: function (elem) {\n return dataUser.hasData(elem) || dataPriv.hasData(elem);\n },\n\n data: function (elem, name, data) {\n return dataUser.access(elem, name, data);\n },\n\n removeData: function (elem, name) {\n dataUser.remove(elem, name);\n },\n\n // TODO: Now that all calls to _data and _removeData have been replaced\n // with direct calls to dataPriv methods, these can be deprecated.\n _data: function (elem, name, data) {\n return dataPriv.access(elem, name, data);\n },\n\n _removeData: function (elem, name) {\n dataPriv.remove(elem, name);\n }\n});\n\njQuery.fn.extend({\n data: function (key, value) {\n var i, name, data,\n elem = this[0],\n attrs = elem && elem.attributes;\n\n // Gets all values\n if (key === undefined) {\n if (this.length) {\n data = dataUser.get(elem);\n\n if (elem.nodeType === 1 && !dataPriv.get(elem, \"hasDataAttrs\")) {\n i = attrs.length;\n while (i--) {\n\n // Support: IE 11 only\n // The attrs elements can be null (#14894)\n if (attrs[i]) {\n name = attrs[i].name;\n if (name.indexOf(\"data-\") === 0) {\n name = camelCase(name.slice(5));\n dataAttr(elem, name, data[name]);\n }\n }\n }\n dataPriv.set(elem, \"hasDataAttrs\", true);\n }\n }\n\n return data;\n }\n\n // Sets multiple values\n if (typeof key === \"object\") {\n return this.each(function () {\n dataUser.set(this, key);\n });\n }\n\n return access(this, function (value) {\n var data;\n\n // The calling jQuery object (element matches) is not empty\n // (and therefore has an element appears at this[ 0 ]) and the\n // `value` parameter was not undefined. An empty jQuery object\n // will result in `undefined` for elem = this[ 0 ] which will\n // throw an exception if an attempt to read a data cache is made.\n if (elem && value === undefined) {\n\n // Attempt to get data from the cache\n // The key will always be camelCased in Data\n data = dataUser.get(elem, key);\n if (data !== undefined) {\n return data;\n }\n\n // Attempt to \"discover\" the data in\n // HTML5 custom data-* attrs\n data = dataAttr(elem, key);\n if (data !== undefined) {\n return data;\n }\n\n // We tried really hard, but the data doesn't exist.\n return;\n }\n\n // Set the data...\n this.each(function () {\n\n // We always store the camelCased key\n dataUser.set(this, key, value);\n });\n }, null, value, arguments.length > 1, null, true);\n },\n\n removeData: function (key) {\n return this.each(function () {\n dataUser.remove(this, key);\n });\n }\n});\n\n\njQuery.extend({\n queue: function (elem, type, data) {\n var queue;\n\n if (elem) {\n type = (type || \"fx\") + \"queue\";\n queue = dataPriv.get(elem, type);\n\n // Speed up dequeue by getting out quickly if this is just a lookup\n if (data) {\n if (!queue || Array.isArray(data)) {\n queue = dataPriv.access(elem, type, jQuery.makeArray(data));\n } else {\n queue.push(data);\n }\n }\n return queue || [];\n }\n },\n\n dequeue: function (elem, type) {\n type = type || \"fx\";\n\n var queue = jQuery.queue(elem, type),\n startLength = queue.length,\n fn = queue.shift(),\n hooks = jQuery._queueHooks(elem, type),\n next = function () {\n jQuery.dequeue(elem, type);\n };\n\n // If the fx queue is dequeued, always remove the progress sentinel\n if (fn === \"inprogress\") {\n fn = queue.shift();\n startLength--;\n }\n\n if (fn) {\n\n // Add a progress sentinel to prevent the fx queue from being\n // automatically dequeued\n if (type === \"fx\") {\n queue.unshift(\"inprogress\");\n }\n\n // Clear up the last queue stop function\n delete hooks.stop;\n fn.call(elem, next, hooks);\n }\n\n if (!startLength && hooks) {\n hooks.empty.fire();\n }\n },\n\n // Not public - generate a queueHooks object, or return the current one\n _queueHooks: function (elem, type) {\n var key = type + \"queueHooks\";\n return dataPriv.get(elem, key) || dataPriv.access(elem, key, {\n empty: jQuery.Callbacks(\"once memory\").add(function () {\n dataPriv.remove(elem, [type + \"queue\", key]);\n })\n });\n }\n});\n\njQuery.fn.extend({\n queue: function (type, data) {\n var setter = 2;\n\n if (typeof type !== \"string\") {\n data = type;\n type = \"fx\";\n setter--;\n }\n\n if (arguments.length < setter) {\n return jQuery.queue(this[0], type);\n }\n\n return data === undefined ?\n this :\n this.each(function () {\n var queue = jQuery.queue(this, type, data);\n\n // Ensure a hooks for this queue\n jQuery._queueHooks(this, type);\n\n if (type === \"fx\" && queue[0] !== \"inprogress\") {\n jQuery.dequeue(this, type);\n }\n });\n },\n dequeue: function (type) {\n return this.each(function () {\n jQuery.dequeue(this, type);\n });\n },\n clearQueue: function (type) {\n return this.queue(type || \"fx\", []);\n },\n\n // Get a promise resolved when queues of a certain type\n // are emptied (fx is the type by default)\n promise: function (type, obj) {\n var tmp,\n count = 1,\n defer = jQuery.Deferred(),\n elements = this,\n i = this.length,\n resolve = function () {\n if (!(--count)) {\n defer.resolveWith(elements, [elements]);\n }\n };\n\n if (typeof type !== \"string\") {\n obj = type;\n type = undefined;\n }\n type = type || \"fx\";\n\n while (i--) {\n tmp = dataPriv.get(elements[i], type + \"queueHooks\");\n if (tmp && tmp.empty) {\n count++;\n tmp.empty.add(resolve);\n }\n }\n resolve();\n return defer.promise(obj);\n }\n});\nvar pnum = (/[+-]?(?:\\d*\\.|)\\d+(?:[eE][+-]?\\d+|)/).source;\n\nvar rcssNum = new RegExp(\"^(?:([+-])=|)(\" + pnum + \")([a-z%]*)$\", \"i\");\n\n\nvar cssExpand = [\"Top\", \"Right\", \"Bottom\", \"Left\"];\n\nvar isHiddenWithinTree = function (elem, el) {\n\n // isHiddenWithinTree might be called from jQuery#filter function;\n // in that case, element will be second argument\n elem = el || elem;\n\n // Inline style trumps all\n return elem.style.display === \"none\" ||\n elem.style.display === \"\" &&\n\n // Otherwise, check computed style\n // Support: Firefox <=43 - 45\n // Disconnected elements can have computed display: none, so first confirm that elem is\n // in the document.\n jQuery.contains(elem.ownerDocument, elem) &&\n\n jQuery.css(elem, \"display\") === \"none\";\n};\n\nvar swap = function (elem, options, callback, args) {\n var ret, name,\n old = {};\n\n // Remember the old values, and insert the new ones\n for (name in options) {\n old[name] = elem.style[name];\n elem.style[name] = options[name];\n }\n\n ret = callback.apply(elem, args || []);\n\n // Revert the old values\n for (name in options) {\n elem.style[name] = old[name];\n }\n\n return ret;\n};\n\n\nfunction adjustCSS(elem, prop, valueParts, tween) {\n var adjusted, scale,\n maxIterations = 20,\n currentValue = tween ?\n function () {\n return tween.cur();\n } :\n function () {\n return jQuery.css(elem, prop, \"\");\n },\n initial = currentValue(),\n unit = valueParts && valueParts[3] || (jQuery.cssNumber[prop] ? \"\" : \"px\"),\n\n // Starting value computation is required for potential unit mismatches\n initialInUnit = (jQuery.cssNumber[prop] || unit !== \"px\" && +initial) &&\n rcssNum.exec(jQuery.css(elem, prop));\n\n if (initialInUnit && initialInUnit[3] !== unit) {\n\n // Support: Firefox <=54\n // Halve the iteration target value to prevent interference from CSS upper bounds (gh-2144)\n initial = initial / 2;\n\n // Trust units reported by jQuery.css\n unit = unit || initialInUnit[3];\n\n // Iteratively approximate from a nonzero starting point\n initialInUnit = +initial || 1;\n\n while (maxIterations--) {\n\n // Evaluate and update our best guess (doubling guesses that zero out).\n // Finish if the scale equals or crosses 1 (making the old*new product non-positive).\n jQuery.style(elem, prop, initialInUnit + unit);\n if ((1 - scale) * (1 - (scale = currentValue() / initial || 0.5)) <= 0) {\n maxIterations = 0;\n }\n initialInUnit = initialInUnit / scale;\n\n }\n\n initialInUnit = initialInUnit * 2;\n jQuery.style(elem, prop, initialInUnit + unit);\n\n // Make sure we update the tween properties later on\n valueParts = valueParts || [];\n }\n\n if (valueParts) {\n initialInUnit = +initialInUnit || +initial || 0;\n\n // Apply relative offset (+=/-=) if specified\n adjusted = valueParts[1] ?\n initialInUnit + (valueParts[1] + 1) * valueParts[2] :\n +valueParts[2];\n if (tween) {\n tween.unit = unit;\n tween.start = initialInUnit;\n tween.end = adjusted;\n }\n }\n return adjusted;\n}\n\n\nvar defaultDisplayMap = {};\n\nfunction getDefaultDisplay(elem) {\n var temp,\n doc = elem.ownerDocument,\n nodeName = elem.nodeName,\n display = defaultDisplayMap[nodeName];\n\n if (display) {\n return display;\n }\n\n temp = doc.body.appendChild(doc.createElement(nodeName));\n display = jQuery.css(temp, \"display\");\n\n temp.parentNode.removeChild(temp);\n\n if (display === \"none\") {\n display = \"block\";\n }\n defaultDisplayMap[nodeName] = display;\n\n return display;\n}\n\nfunction showHide(elements, show) {\n var display, elem,\n values = [],\n index = 0,\n length = elements.length;\n\n // Determine new display value for elements that need to change\n for (; index < length; index++) {\n elem = elements[index];\n if (!elem.style) {\n continue;\n }\n\n display = elem.style.display;\n if (show) {\n\n // Since we force visibility upon cascade-hidden elements, an immediate (and slow)\n // check is required in this first loop unless we have a nonempty display value (either\n // inline or about-to-be-restored)\n if (display === \"none\") {\n values[index] = dataPriv.get(elem, \"display\") || null;\n if (!values[index]) {\n elem.style.display = \"\";\n }\n }\n if (elem.style.display === \"\" && isHiddenWithinTree(elem)) {\n values[index] = getDefaultDisplay(elem);\n }\n } else {\n if (display !== \"none\") {\n values[index] = \"none\";\n\n // Remember what we're overwriting\n dataPriv.set(elem, \"display\", display);\n }\n }\n }\n\n // Set the display of the elements in a second loop to avoid constant reflow\n for (index = 0; index < length; index++) {\n if (values[index] != null) {\n elements[index].style.display = values[index];\n }\n }\n\n return elements;\n}\n\njQuery.fn.extend({\n show: function () {\n return showHide(this, true);\n },\n hide: function () {\n return showHide(this);\n },\n toggle: function (state) {\n if (typeof state === \"boolean\") {\n return state ? this.show() : this.hide();\n }\n\n return this.each(function () {\n if (isHiddenWithinTree(this)) {\n jQuery(this).show();\n } else {\n jQuery(this).hide();\n }\n });\n }\n});\nvar rcheckableType = (/^(?:checkbox|radio)$/i);\n\nvar rtagName = (/<([a-z][^\\/\\0>\\x20\\t\\r\\n\\f]+)/i);\n\nvar rscriptType = (/^$|^module$|\\/(?:java|ecma)script/i);\n\n\n// We have to close these tags to support XHTML (#13200)\nvar wrapMap = {\n\n // Support: IE <=9 only\n option: [1, \"\"],\n\n // XHTML parsers do not magically insert elements in the\n // same way that tag soup parsers do. So we cannot shorten\n // this by omitting or other required elements.\n thead: [1, \"\", \"
\"],\n col: [2, \"\", \"
\"],\n tr: [2, \"\", \"
\"],\n td: [3, \"\", \"
\"],\n\n _default: [0, \"\", \"\"]\n};\n\n// Support: IE <=9 only\nwrapMap.optgroup = wrapMap.option;\n\nwrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;\nwrapMap.th = wrapMap.td;\n\n\nfunction getAll(context, tag) {\n\n // Support: IE <=9 - 11 only\n // Use typeof to avoid zero-argument method invocation on host objects (#15151)\n var ret;\n\n if (typeof context.getElementsByTagName !== \"undefined\") {\n ret = context.getElementsByTagName(tag || \"*\");\n\n } else if (typeof context.querySelectorAll !== \"undefined\") {\n ret = context.querySelectorAll(tag || \"*\");\n\n } else {\n ret = [];\n }\n\n if (tag === undefined || tag && nodeName(context, tag)) {\n return jQuery.merge([context], ret);\n }\n\n return ret;\n}\n\n\n// Mark scripts as having already been evaluated\nfunction setGlobalEval(elems, refElements) {\n var i = 0,\n l = elems.length;\n\n for (; i < l; i++) {\n dataPriv.set(\n elems[i],\n \"globalEval\",\n !refElements || dataPriv.get(refElements[i], \"globalEval\")\n );\n }\n}\n\n\nvar rhtml = /<|&#?\\w+;/;\n\nfunction buildFragment(elems, context, scripts, selection, ignored) {\n var elem, tmp, tag, wrap, contains, j,\n fragment = context.createDocumentFragment(),\n nodes = [],\n i = 0,\n l = elems.length;\n\n for (; i < l; i++) {\n elem = elems[i];\n\n if (elem || elem === 0) {\n\n // Add nodes directly\n if (toType(elem) === \"object\") {\n\n // Support: Android <=4.0 only, PhantomJS 1 only\n // push.apply(_, arraylike) throws on ancient WebKit\n jQuery.merge(nodes, elem.nodeType ? [elem] : elem);\n\n // Convert non-html into a text node\n } else if (!rhtml.test(elem)) {\n nodes.push(context.createTextNode(elem));\n\n // Convert html into DOM nodes\n } else {\n tmp = tmp || fragment.appendChild(context.createElement(\"div\"));\n\n // Deserialize a standard representation\n tag = (rtagName.exec(elem) || [\"\", \"\"])[1].toLowerCase();\n wrap = wrapMap[tag] || wrapMap._default;\n tmp.innerHTML = wrap[1] + jQuery.htmlPrefilter(elem) + wrap[2];\n\n // Descend through wrappers to the right content\n j = wrap[0];\n while (j--) {\n tmp = tmp.lastChild;\n }\n\n // Support: Android <=4.0 only, PhantomJS 1 only\n // push.apply(_, arraylike) throws on ancient WebKit\n jQuery.merge(nodes, tmp.childNodes);\n\n // Remember the top-level container\n tmp = fragment.firstChild;\n\n // Ensure the created nodes are orphaned (#12392)\n tmp.textContent = \"\";\n }\n }\n }\n\n // Remove wrapper from fragment\n fragment.textContent = \"\";\n\n i = 0;\n while ((elem = nodes[i++])) {\n\n // Skip elements already in the context collection (trac-4087)\n if (selection && jQuery.inArray(elem, selection) > -1) {\n if (ignored) {\n ignored.push(elem);\n }\n continue;\n }\n\n contains = jQuery.contains(elem.ownerDocument, elem);\n\n // Append to fragment\n tmp = getAll(fragment.appendChild(elem), \"script\");\n\n // Preserve script evaluation history\n if (contains) {\n setGlobalEval(tmp);\n }\n\n // Capture executables\n if (scripts) {\n j = 0;\n while ((elem = tmp[j++])) {\n if (rscriptType.test(elem.type || \"\")) {\n scripts.push(elem);\n }\n }\n }\n }\n\n return fragment;\n}\n\n\n(function () {\n var fragment = document$1.createDocumentFragment(),\n div = fragment.appendChild(document$1.createElement(\"div\")),\n input = document$1.createElement(\"input\");\n\n // Support: Android 4.0 - 4.3 only\n // Check state lost if the name is set (#11217)\n // Support: Windows Web Apps (WWA)\n // `name` and `type` must use .setAttribute for WWA (#14901)\n input.setAttribute(\"type\", \"radio\");\n input.setAttribute(\"checked\", \"checked\");\n input.setAttribute(\"name\", \"t\");\n\n div.appendChild(input);\n\n // Support: Android <=4.1 only\n // Older WebKit doesn't clone checked state correctly in fragments\n support.checkClone = div.cloneNode(true).cloneNode(true).lastChild.checked;\n\n // Support: IE <=11 only\n // Make sure textarea (and checkbox) defaultValue is properly cloned\n div.innerHTML = \"\";\n support.noCloneChecked = !!div.cloneNode(true).lastChild.defaultValue;\n})();\nvar documentElement = document$1.documentElement;\n\n\nvar\n rkeyEvent = /^key/,\n rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/,\n rtypenamespace = /^([^.]*)(?:\\.(.+)|)/;\n\nfunction returnTrue() {\n return true;\n}\n\nfunction returnFalse() {\n return false;\n}\n\n// Support: IE <=9 only\n// See #13393 for more info\nfunction safeActiveElement() {\n try {\n return document$1.activeElement;\n } catch (err) {\n }\n}\n\nfunction on(elem, types, selector, data, fn, one) {\n var origFn, type;\n\n // Types can be a map of types/handlers\n if (typeof types === \"object\") {\n\n // ( types-Object, selector, data )\n if (typeof selector !== \"string\") {\n\n // ( types-Object, data )\n data = data || selector;\n selector = undefined;\n }\n for (type in types) {\n on(elem, type, selector, data, types[type], one);\n }\n return elem;\n }\n\n if (data == null && fn == null) {\n\n // ( types, fn )\n fn = selector;\n data = selector = undefined;\n } else if (fn == null) {\n if (typeof selector === \"string\") {\n\n // ( types, selector, fn )\n fn = data;\n data = undefined;\n } else {\n\n // ( types, data, fn )\n fn = data;\n data = selector;\n selector = undefined;\n }\n }\n if (fn === false) {\n fn = returnFalse;\n } else if (!fn) {\n return elem;\n }\n\n if (one === 1) {\n origFn = fn;\n fn = function (event) {\n\n // Can use an empty set, since event contains the info\n jQuery().off(event);\n return origFn.apply(this, arguments);\n };\n\n // Use same guid so caller can remove using origFn\n fn.guid = origFn.guid || (origFn.guid = jQuery.guid++);\n }\n return elem.each(function () {\n jQuery.event.add(this, types, fn, data, selector);\n });\n}\n\n/*\n * Helper functions for managing events -- not part of the public interface.\n * Props to Dean Edwards' addEvent library for many of the ideas.\n */\njQuery.event = {\n\n global: {},\n\n add: function (elem, types, handler, data, selector) {\n\n var handleObjIn, eventHandle, tmp,\n events, t, handleObj,\n special, handlers, type, namespaces, origType,\n elemData = dataPriv.get(elem);\n\n // Don't attach events to noData or text/comment nodes (but allow plain objects)\n if (!elemData) {\n return;\n }\n\n // Caller can pass in an object of custom data in lieu of the handler\n if (handler.handler) {\n handleObjIn = handler;\n handler = handleObjIn.handler;\n selector = handleObjIn.selector;\n }\n\n // Ensure that invalid selectors throw exceptions at attach time\n // Evaluate against documentElement in case elem is a non-element node (e.g., document)\n if (selector) {\n jQuery.find.matchesSelector(documentElement, selector);\n }\n\n // Make sure that the handler has a unique ID, used to find/remove it later\n if (!handler.guid) {\n handler.guid = jQuery.guid++;\n }\n\n // Init the element's event structure and main handler, if this is the first\n if (!(events = elemData.events)) {\n events = elemData.events = {};\n }\n if (!(eventHandle = elemData.handle)) {\n eventHandle = elemData.handle = function (e) {\n\n // Discard the second event of a jQuery.event.trigger() and\n // when an event is called after a page has unloaded\n return typeof jQuery !== \"undefined\" && jQuery.event.triggered !== e.type ?\n jQuery.event.dispatch.apply(elem, arguments) : undefined;\n };\n }\n\n // Handle multiple events separated by a space\n types = (types || \"\").match(rnothtmlwhite) || [\"\"];\n t = types.length;\n while (t--) {\n tmp = rtypenamespace.exec(types[t]) || [];\n type = origType = tmp[1];\n namespaces = (tmp[2] || \"\").split(\".\").sort();\n\n // There *must* be a type, no attaching namespace-only handlers\n if (!type) {\n continue;\n }\n\n // If event changes its type, use the special event handlers for the changed type\n special = jQuery.event.special[type] || {};\n\n // If selector defined, determine special event api type, otherwise given type\n type = (selector ? special.delegateType : special.bindType) || type;\n\n // Update special based on newly reset type\n special = jQuery.event.special[type] || {};\n\n // handleObj is passed to all event handlers\n handleObj = jQuery.extend({\n type: type,\n origType: origType,\n data: data,\n handler: handler,\n guid: handler.guid,\n selector: selector,\n needsContext: selector && jQuery.expr.match.needsContext.test(selector),\n namespace: namespaces.join(\".\")\n }, handleObjIn);\n\n // Init the event handler queue if we're the first\n if (!(handlers = events[type])) {\n handlers = events[type] = [];\n handlers.delegateCount = 0;\n\n // Only use addEventListener if the special events handler returns false\n if (!special.setup ||\n special.setup.call(elem, data, namespaces, eventHandle) === false) {\n\n if (elem.addEventListener) {\n elem.addEventListener(type, eventHandle);\n }\n }\n }\n\n if (special.add) {\n special.add.call(elem, handleObj);\n\n if (!handleObj.handler.guid) {\n handleObj.handler.guid = handler.guid;\n }\n }\n\n // Add to the element's handler list, delegates in front\n if (selector) {\n handlers.splice(handlers.delegateCount++, 0, handleObj);\n } else {\n handlers.push(handleObj);\n }\n\n // Keep track of which events have ever been used, for event optimization\n jQuery.event.global[type] = true;\n }\n\n },\n\n // Detach an event or set of events from an element\n remove: function (elem, types, handler, selector, mappedTypes) {\n\n var j, origCount, tmp,\n events, t, handleObj,\n special, handlers, type, namespaces, origType,\n elemData = dataPriv.hasData(elem) && dataPriv.get(elem);\n\n if (!elemData || !(events = elemData.events)) {\n return;\n }\n\n // Once for each type.namespace in types; type may be omitted\n types = (types || \"\").match(rnothtmlwhite) || [\"\"];\n t = types.length;\n while (t--) {\n tmp = rtypenamespace.exec(types[t]) || [];\n type = origType = tmp[1];\n namespaces = (tmp[2] || \"\").split(\".\").sort();\n\n // Unbind all events (on this namespace, if provided) for the element\n if (!type) {\n for (type in events) {\n jQuery.event.remove(elem, type + types[t], handler, selector, true);\n }\n continue;\n }\n\n special = jQuery.event.special[type] || {};\n type = (selector ? special.delegateType : special.bindType) || type;\n handlers = events[type] || [];\n tmp = tmp[2] &&\n new RegExp(\"(^|\\\\.)\" + namespaces.join(\"\\\\.(?:.*\\\\.|)\") + \"(\\\\.|$)\");\n\n // Remove matching events\n origCount = j = handlers.length;\n while (j--) {\n handleObj = handlers[j];\n\n if ((mappedTypes || origType === handleObj.origType) &&\n (!handler || handler.guid === handleObj.guid) &&\n (!tmp || tmp.test(handleObj.namespace)) &&\n (!selector || selector === handleObj.selector ||\n selector === \"**\" && handleObj.selector)) {\n handlers.splice(j, 1);\n\n if (handleObj.selector) {\n handlers.delegateCount--;\n }\n if (special.remove) {\n special.remove.call(elem, handleObj);\n }\n }\n }\n\n // Remove generic event handler if we removed something and no more handlers exist\n // (avoids potential for endless recursion during removal of special event handlers)\n if (origCount && !handlers.length) {\n if (!special.teardown ||\n special.teardown.call(elem, namespaces, elemData.handle) === false) {\n\n jQuery.removeEvent(elem, type, elemData.handle);\n }\n\n delete events[type];\n }\n }\n\n // Remove data and the expando if it's no longer used\n if (jQuery.isEmptyObject(events)) {\n dataPriv.remove(elem, \"handle events\");\n }\n },\n\n dispatch: function (nativeEvent) {\n\n // Make a writable jQuery.Event from the native event object\n var event = jQuery.event.fix(nativeEvent);\n\n var i, j, ret, matched, handleObj, handlerQueue,\n args = new Array(arguments.length),\n handlers = (dataPriv.get(this, \"events\") || {})[event.type] || [],\n special = jQuery.event.special[event.type] || {};\n\n // Use the fix-ed jQuery.Event rather than the (read-only) native event\n args[0] = event;\n\n for (i = 1; i < arguments.length; i++) {\n args[i] = arguments[i];\n }\n\n event.delegateTarget = this;\n\n // Call the preDispatch hook for the mapped type, and let it bail if desired\n if (special.preDispatch && special.preDispatch.call(this, event) === false) {\n return;\n }\n\n // Determine handlers\n handlerQueue = jQuery.event.handlers.call(this, event, handlers);\n\n // Run delegates first; they may want to stop propagation beneath us\n i = 0;\n while ((matched = handlerQueue[i++]) && !event.isPropagationStopped()) {\n event.currentTarget = matched.elem;\n\n j = 0;\n while ((handleObj = matched.handlers[j++]) &&\n !event.isImmediatePropagationStopped()) {\n\n // Triggered event must either 1) have no namespace, or 2) have namespace(s)\n // a subset or equal to those in the bound event (both can have no namespace).\n if (!event.rnamespace || event.rnamespace.test(handleObj.namespace)) {\n\n event.handleObj = handleObj;\n event.data = handleObj.data;\n\n ret = ((jQuery.event.special[handleObj.origType] || {}).handle ||\n handleObj.handler).apply(matched.elem, args);\n\n if (ret !== undefined) {\n if ((event.result = ret) === false) {\n event.preventDefault();\n event.stopPropagation();\n }\n }\n }\n }\n }\n\n // Call the postDispatch hook for the mapped type\n if (special.postDispatch) {\n special.postDispatch.call(this, event);\n }\n\n return event.result;\n },\n\n handlers: function (event, handlers) {\n var i, handleObj, sel, matchedHandlers, matchedSelectors,\n handlerQueue = [],\n delegateCount = handlers.delegateCount,\n cur = event.target;\n\n // Find delegate handlers\n if (delegateCount &&\n\n // Support: IE <=9\n // Black-hole SVG instance trees (trac-13180)\n cur.nodeType &&\n\n // Support: Firefox <=42\n // Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861)\n // https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click\n // Support: IE 11 only\n // ...but not arrow key \"clicks\" of radio inputs, which can have `button` -1 (gh-2343)\n !(event.type === \"click\" && event.button >= 1)) {\n\n for (; cur !== this; cur = cur.parentNode || this) {\n\n // Don't check non-elements (#13208)\n // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)\n if (cur.nodeType === 1 && !(event.type === \"click\" && cur.disabled === true)) {\n matchedHandlers = [];\n matchedSelectors = {};\n for (i = 0; i < delegateCount; i++) {\n handleObj = handlers[i];\n\n // Don't conflict with Object.prototype properties (#13203)\n sel = handleObj.selector + \" \";\n\n if (matchedSelectors[sel] === undefined) {\n matchedSelectors[sel] = handleObj.needsContext ?\n jQuery(sel, this).index(cur) > -1 :\n jQuery.find(sel, this, null, [cur]).length;\n }\n if (matchedSelectors[sel]) {\n matchedHandlers.push(handleObj);\n }\n }\n if (matchedHandlers.length) {\n handlerQueue.push({elem: cur, handlers: matchedHandlers});\n }\n }\n }\n }\n\n // Add the remaining (directly-bound) handlers\n cur = this;\n if (delegateCount < handlers.length) {\n handlerQueue.push({elem: cur, handlers: handlers.slice(delegateCount)});\n }\n\n return handlerQueue;\n },\n\n addProp: function (name, hook) {\n Object.defineProperty(jQuery.Event.prototype, name, {\n enumerable: true,\n configurable: true,\n\n get: isFunction(hook) ?\n function () {\n if (this.originalEvent) {\n return hook(this.originalEvent);\n }\n } :\n function () {\n if (this.originalEvent) {\n return this.originalEvent[name];\n }\n },\n\n set: function (value) {\n Object.defineProperty(this, name, {\n enumerable: true,\n configurable: true,\n writable: true,\n value: value\n });\n }\n });\n },\n\n fix: function (originalEvent) {\n return originalEvent[jQuery.expando] ?\n originalEvent :\n new jQuery.Event(originalEvent);\n },\n\n special: {\n load: {\n\n // Prevent triggered image.load events from bubbling to window.load\n noBubble: true\n },\n focus: {\n\n // Fire native event if possible so blur/focus sequence is correct\n trigger: function () {\n if (this !== safeActiveElement() && this.focus) {\n this.focus();\n return false;\n }\n },\n delegateType: \"focusin\"\n },\n blur: {\n trigger: function () {\n if (this === safeActiveElement() && this.blur) {\n this.blur();\n return false;\n }\n },\n delegateType: \"focusout\"\n },\n click: {\n\n // For checkbox, fire native event so checked state will be right\n trigger: function () {\n if (this.type === \"checkbox\" && this.click && nodeName(this, \"input\")) {\n this.click();\n return false;\n }\n },\n\n // For cross-browser consistency, don't fire native .click() on links\n _default: function (event) {\n return nodeName(event.target, \"a\");\n }\n },\n\n beforeunload: {\n postDispatch: function (event) {\n\n // Support: Firefox 20+\n // Firefox doesn't alert if the returnValue field is not set.\n if (event.result !== undefined && event.originalEvent) {\n event.originalEvent.returnValue = event.result;\n }\n }\n }\n }\n};\n\njQuery.removeEvent = function (elem, type, handle) {\n\n // This \"if\" is needed for plain objects\n if (elem.removeEventListener) {\n elem.removeEventListener(type, handle);\n }\n};\n\njQuery.Event = function (src, props) {\n\n // Allow instantiation without the 'new' keyword\n if (!(this instanceof jQuery.Event)) {\n return new jQuery.Event(src, props);\n }\n\n // Event object\n if (src && src.type) {\n this.originalEvent = src;\n this.type = src.type;\n\n // Events bubbling up the document may have been marked as prevented\n // by a handler lower down the tree; reflect the correct value.\n this.isDefaultPrevented = src.defaultPrevented ||\n src.defaultPrevented === undefined &&\n\n // Support: Android <=2.3 only\n src.returnValue === false ?\n returnTrue :\n returnFalse;\n\n // Create target properties\n // Support: Safari <=6 - 7 only\n // Target should not be a text node (#504, #13143)\n this.target = (src.target && src.target.nodeType === 3) ?\n src.target.parentNode :\n src.target;\n\n this.currentTarget = src.currentTarget;\n this.relatedTarget = src.relatedTarget;\n\n // Event type\n } else {\n this.type = src;\n }\n\n // Put explicitly provided properties onto the event object\n if (props) {\n jQuery.extend(this, props);\n }\n\n // Create a timestamp if incoming event doesn't have one\n this.timeStamp = src && src.timeStamp || Date.now();\n\n // Mark it as fixed\n this[jQuery.expando] = true;\n};\n\n// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding\n// https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html\njQuery.Event.prototype = {\n constructor: jQuery.Event,\n isDefaultPrevented: returnFalse,\n isPropagationStopped: returnFalse,\n isImmediatePropagationStopped: returnFalse,\n isSimulated: false,\n\n preventDefault: function () {\n var e = this.originalEvent;\n\n this.isDefaultPrevented = returnTrue;\n\n if (e && !this.isSimulated) {\n e.preventDefault();\n }\n },\n stopPropagation: function () {\n var e = this.originalEvent;\n\n this.isPropagationStopped = returnTrue;\n\n if (e && !this.isSimulated) {\n e.stopPropagation();\n }\n },\n stopImmediatePropagation: function () {\n var e = this.originalEvent;\n\n this.isImmediatePropagationStopped = returnTrue;\n\n if (e && !this.isSimulated) {\n e.stopImmediatePropagation();\n }\n\n this.stopPropagation();\n }\n};\n\n// Includes all common event props including KeyEvent and MouseEvent specific props\njQuery.each({\n altKey: true,\n bubbles: true,\n cancelable: true,\n changedTouches: true,\n ctrlKey: true,\n detail: true,\n eventPhase: true,\n metaKey: true,\n pageX: true,\n pageY: true,\n shiftKey: true,\n view: true,\n \"char\": true,\n charCode: true,\n key: true,\n keyCode: true,\n button: true,\n buttons: true,\n clientX: true,\n clientY: true,\n offsetX: true,\n offsetY: true,\n pointerId: true,\n pointerType: true,\n screenX: true,\n screenY: true,\n targetTouches: true,\n toElement: true,\n touches: true,\n\n which: function (event) {\n var button = event.button;\n\n // Add which for key events\n if (event.which == null && rkeyEvent.test(event.type)) {\n return event.charCode != null ? event.charCode : event.keyCode;\n }\n\n // Add which for click: 1 === left; 2 === middle; 3 === right\n if (!event.which && button !== undefined && rmouseEvent.test(event.type)) {\n if (button & 1) {\n return 1;\n }\n\n if (button & 2) {\n return 3;\n }\n\n if (button & 4) {\n return 2;\n }\n\n return 0;\n }\n\n return event.which;\n }\n}, jQuery.event.addProp);\n\n// Create mouseenter/leave events using mouseover/out and event-time checks\n// so that event delegation works in jQuery.\n// Do the same for pointerenter/pointerleave and pointerover/pointerout\n//\n// Support: Safari 7 only\n// Safari sends mouseenter too often; see:\n// https://bugs.chromium.org/p/chromium/issues/detail?id=470258\n// for the description of the bug (it existed in older Chrome versions as well).\njQuery.each({\n mouseenter: \"mouseover\",\n mouseleave: \"mouseout\",\n pointerenter: \"pointerover\",\n pointerleave: \"pointerout\"\n}, function (orig, fix) {\n jQuery.event.special[orig] = {\n delegateType: fix,\n bindType: fix,\n\n handle: function (event) {\n var ret,\n target = this,\n related = event.relatedTarget,\n handleObj = event.handleObj;\n\n // For mouseenter/leave call the handler if related is outside the target.\n // NB: No relatedTarget if the mouse left/entered the browser window\n if (!related || (related !== target && !jQuery.contains(target, related))) {\n event.type = handleObj.origType;\n ret = handleObj.handler.apply(this, arguments);\n event.type = fix;\n }\n return ret;\n }\n };\n});\n\njQuery.fn.extend({\n\n on: function (types, selector, data, fn) {\n return on(this, types, selector, data, fn);\n },\n one: function (types, selector, data, fn) {\n return on(this, types, selector, data, fn, 1);\n },\n off: function (types, selector, fn) {\n var handleObj, type;\n if (types && types.preventDefault && types.handleObj) {\n\n // ( event ) dispatched jQuery.Event\n handleObj = types.handleObj;\n jQuery(types.delegateTarget).off(\n handleObj.namespace ?\n handleObj.origType + \".\" + handleObj.namespace :\n handleObj.origType,\n handleObj.selector,\n handleObj.handler\n );\n return this;\n }\n if (typeof types === \"object\") {\n\n // ( types-object [, selector] )\n for (type in types) {\n this.off(type, selector, types[type]);\n }\n return this;\n }\n if (selector === false || typeof selector === \"function\") {\n\n // ( types [, fn] )\n fn = selector;\n selector = undefined;\n }\n if (fn === false) {\n fn = returnFalse;\n }\n return this.each(function () {\n jQuery.event.remove(this, types, fn, selector);\n });\n }\n});\n\n\nvar\n\n /* eslint-disable max-len */\n\n // See https://github.com/eslint/eslint/issues/3229\n rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\\/\\0>\\x20\\t\\r\\n\\f]*)[^>]*)\\/>/gi,\n\n /* eslint-enable */\n\n // Support: IE <=10 - 11, Edge 12 - 13 only\n // In IE/Edge using regex groups here causes severe slowdowns.\n // See https://connect.microsoft.com/IE/feedback/details/1736512/\n rnoInnerhtml = /\\s*$/g;\n\n// Prefer a tbody over its parent table for containing new rows\nfunction manipulationTarget(elem, content) {\n if (nodeName(elem, \"table\") &&\n nodeName(content.nodeType !== 11 ? content : content.firstChild, \"tr\")) {\n\n return jQuery(elem).children(\"tbody\")[0] || elem;\n }\n\n return elem;\n}\n\n// Replace/restore the type attribute of script elements for safe DOM manipulation\nfunction disableScript(elem) {\n elem.type = (elem.getAttribute(\"type\") !== null) + \"/\" + elem.type;\n return elem;\n}\n\nfunction restoreScript(elem) {\n if ((elem.type || \"\").slice(0, 5) === \"true/\") {\n elem.type = elem.type.slice(5);\n } else {\n elem.removeAttribute(\"type\");\n }\n\n return elem;\n}\n\nfunction cloneCopyEvent(src, dest) {\n var i, l, type, pdataOld, pdataCur, udataOld, udataCur, events;\n\n if (dest.nodeType !== 1) {\n return;\n }\n\n // 1. Copy private data: events, handlers, etc.\n if (dataPriv.hasData(src)) {\n pdataOld = dataPriv.access(src);\n pdataCur = dataPriv.set(dest, pdataOld);\n events = pdataOld.events;\n\n if (events) {\n delete pdataCur.handle;\n pdataCur.events = {};\n\n for (type in events) {\n for (i = 0, l = events[type].length; i < l; i++) {\n jQuery.event.add(dest, type, events[type][i]);\n }\n }\n }\n }\n\n // 2. Copy user data\n if (dataUser.hasData(src)) {\n udataOld = dataUser.access(src);\n udataCur = jQuery.extend({}, udataOld);\n\n dataUser.set(dest, udataCur);\n }\n}\n\n// Fix IE bugs, see support tests\nfunction fixInput(src, dest) {\n var nodeName = dest.nodeName.toLowerCase();\n\n // Fails to persist the checked state of a cloned checkbox or radio button.\n if (nodeName === \"input\" && rcheckableType.test(src.type)) {\n dest.checked = src.checked;\n\n // Fails to return the selected option to the default selected state when cloning options\n } else if (nodeName === \"input\" || nodeName === \"textarea\") {\n dest.defaultValue = src.defaultValue;\n }\n}\n\nfunction domManip(collection, args, callback, ignored) {\n\n // Flatten any nested arrays\n args = concat.apply([], args);\n\n var fragment, first, scripts, hasScripts, node, doc,\n i = 0,\n l = collection.length,\n iNoClone = l - 1,\n value = args[0],\n valueIsFunction = isFunction(value);\n\n // We can't cloneNode fragments that contain checked, in WebKit\n if (valueIsFunction ||\n (l > 1 && typeof value === \"string\" &&\n !support.checkClone && rchecked.test(value))) {\n return collection.each(function (index) {\n var self = collection.eq(index);\n if (valueIsFunction) {\n args[0] = value.call(this, index, self.html());\n }\n domManip(self, args, callback, ignored);\n });\n }\n\n if (l) {\n fragment = buildFragment(args, collection[0].ownerDocument, false, collection, ignored);\n first = fragment.firstChild;\n\n if (fragment.childNodes.length === 1) {\n fragment = first;\n }\n\n // Require either new content or an interest in ignored elements to invoke the callback\n if (first || ignored) {\n scripts = jQuery.map(getAll(fragment, \"script\"), disableScript);\n hasScripts = scripts.length;\n\n // Use the original fragment for the last item\n // instead of the first because it can end up\n // being emptied incorrectly in certain situations (#8070).\n for (; i < l; i++) {\n node = fragment;\n\n if (i !== iNoClone) {\n node = jQuery.clone(node, true, true);\n\n // Keep references to cloned scripts for later restoration\n if (hasScripts) {\n\n // Support: Android <=4.0 only, PhantomJS 1 only\n // push.apply(_, arraylike) throws on ancient WebKit\n jQuery.merge(scripts, getAll(node, \"script\"));\n }\n }\n\n callback.call(collection[i], node, i);\n }\n\n if (hasScripts) {\n doc = scripts[scripts.length - 1].ownerDocument;\n\n // Reenable scripts\n jQuery.map(scripts, restoreScript);\n\n // Evaluate executable scripts on first document insertion\n for (i = 0; i < hasScripts; i++) {\n node = scripts[i];\n if (rscriptType.test(node.type || \"\") &&\n !dataPriv.access(node, \"globalEval\") &&\n jQuery.contains(doc, node)) {\n\n if (node.src && (node.type || \"\").toLowerCase() !== \"module\") {\n\n // Optional AJAX dependency, but won't run scripts if not present\n if (jQuery._evalUrl) {\n jQuery._evalUrl(node.src);\n }\n } else {\n DOMEval(node.textContent.replace(rcleanScript, \"\"), doc, node);\n }\n }\n }\n }\n }\n }\n\n return collection;\n}\n\nfunction remove(elem, selector, keepData) {\n var node,\n nodes = selector ? jQuery.filter(selector, elem) : elem,\n i = 0;\n\n for (; (node = nodes[i]) != null; i++) {\n if (!keepData && node.nodeType === 1) {\n jQuery.cleanData(getAll(node));\n }\n\n if (node.parentNode) {\n if (keepData && jQuery.contains(node.ownerDocument, node)) {\n setGlobalEval(getAll(node, \"script\"));\n }\n node.parentNode.removeChild(node);\n }\n }\n\n return elem;\n}\n\njQuery.extend({\n htmlPrefilter: function (html) {\n return html.replace(rxhtmlTag, \"<$1>\");\n },\n\n clone: function (elem, dataAndEvents, deepDataAndEvents) {\n var i, l, srcElements, destElements,\n clone = elem.cloneNode(true),\n inPage = jQuery.contains(elem.ownerDocument, elem);\n\n // Fix IE cloning issues\n if (!support.noCloneChecked && (elem.nodeType === 1 || elem.nodeType === 11) &&\n !jQuery.isXMLDoc(elem)) {\n\n // We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/2\n destElements = getAll(clone);\n srcElements = getAll(elem);\n\n for (i = 0, l = srcElements.length; i < l; i++) {\n fixInput(srcElements[i], destElements[i]);\n }\n }\n\n // Copy the events from the original to the clone\n if (dataAndEvents) {\n if (deepDataAndEvents) {\n srcElements = srcElements || getAll(elem);\n destElements = destElements || getAll(clone);\n\n for (i = 0, l = srcElements.length; i < l; i++) {\n cloneCopyEvent(srcElements[i], destElements[i]);\n }\n } else {\n cloneCopyEvent(elem, clone);\n }\n }\n\n // Preserve script evaluation history\n destElements = getAll(clone, \"script\");\n if (destElements.length > 0) {\n setGlobalEval(destElements, !inPage && getAll(elem, \"script\"));\n }\n\n // Return the cloned set\n return clone;\n },\n\n cleanData: function (elems) {\n var data, elem, type,\n special = jQuery.event.special,\n i = 0;\n\n for (; (elem = elems[i]) !== undefined; i++) {\n if (acceptData(elem)) {\n if ((data = elem[dataPriv.expando])) {\n if (data.events) {\n for (type in data.events) {\n if (special[type]) {\n jQuery.event.remove(elem, type);\n\n // This is a shortcut to avoid jQuery.event.remove's overhead\n } else {\n jQuery.removeEvent(elem, type, data.handle);\n }\n }\n }\n\n // Support: Chrome <=35 - 45+\n // Assign undefined instead of using delete, see Data#remove\n elem[dataPriv.expando] = undefined;\n }\n if (elem[dataUser.expando]) {\n\n // Support: Chrome <=35 - 45+\n // Assign undefined instead of using delete, see Data#remove\n elem[dataUser.expando] = undefined;\n }\n }\n }\n }\n});\n\njQuery.fn.extend({\n detach: function (selector) {\n return remove(this, selector, true);\n },\n\n remove: function (selector) {\n return remove(this, selector);\n },\n\n text: function (value) {\n return access(this, function (value) {\n return value === undefined ?\n jQuery.text(this) :\n this.empty().each(function () {\n if (this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9) {\n this.textContent = value;\n }\n });\n }, null, value, arguments.length);\n },\n\n append: function () {\n return domManip(this, arguments, function (elem) {\n if (this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9) {\n var target = manipulationTarget(this, elem);\n target.appendChild(elem);\n }\n });\n },\n\n prepend: function () {\n return domManip(this, arguments, function (elem) {\n if (this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9) {\n var target = manipulationTarget(this, elem);\n target.insertBefore(elem, target.firstChild);\n }\n });\n },\n\n before: function () {\n return domManip(this, arguments, function (elem) {\n if (this.parentNode) {\n this.parentNode.insertBefore(elem, this);\n }\n });\n },\n\n after: function () {\n return domManip(this, arguments, function (elem) {\n if (this.parentNode) {\n this.parentNode.insertBefore(elem, this.nextSibling);\n }\n });\n },\n\n empty: function () {\n var elem,\n i = 0;\n\n for (; (elem = this[i]) != null; i++) {\n if (elem.nodeType === 1) {\n\n // Prevent memory leaks\n jQuery.cleanData(getAll(elem, false));\n\n // Remove any remaining nodes\n elem.textContent = \"\";\n }\n }\n\n return this;\n },\n\n clone: function (dataAndEvents, deepDataAndEvents) {\n dataAndEvents = dataAndEvents == null ? false : dataAndEvents;\n deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;\n\n return this.map(function () {\n return jQuery.clone(this, dataAndEvents, deepDataAndEvents);\n });\n },\n\n html: function (value) {\n return access(this, function (value) {\n var elem = this[0] || {},\n i = 0,\n l = this.length;\n\n if (value === undefined && elem.nodeType === 1) {\n return elem.innerHTML;\n }\n\n // See if we can take a shortcut and just use innerHTML\n if (typeof value === \"string\" && !rnoInnerhtml.test(value) &&\n !wrapMap[(rtagName.exec(value) || [\"\", \"\"])[1].toLowerCase()]) {\n\n value = jQuery.htmlPrefilter(value);\n\n try {\n for (; i < l; i++) {\n elem = this[i] || {};\n\n // Remove element nodes and prevent memory leaks\n if (elem.nodeType === 1) {\n jQuery.cleanData(getAll(elem, false));\n elem.innerHTML = value;\n }\n }\n\n elem = 0;\n\n // If using innerHTML throws an exception, use the fallback method\n } catch (e) {\n }\n }\n\n if (elem) {\n this.empty().append(value);\n }\n }, null, value, arguments.length);\n },\n\n replaceWith: function () {\n var ignored = [];\n\n // Make the changes, replacing each non-ignored context element with the new content\n return domManip(this, arguments, function (elem) {\n var parent = this.parentNode;\n\n if (jQuery.inArray(this, ignored) < 0) {\n jQuery.cleanData(getAll(this));\n if (parent) {\n parent.replaceChild(elem, this);\n }\n }\n\n // Force callback invocation\n }, ignored);\n }\n});\n\njQuery.each({\n appendTo: \"append\",\n prependTo: \"prepend\",\n insertBefore: \"before\",\n insertAfter: \"after\",\n replaceAll: \"replaceWith\"\n}, function (name, original) {\n jQuery.fn[name] = function (selector) {\n var elems,\n ret = [],\n insert = jQuery(selector),\n last = insert.length - 1,\n i = 0;\n\n for (; i <= last; i++) {\n elems = i === last ? this : this.clone(true);\n jQuery(insert[i])[original](elems);\n\n // Support: Android <=4.0 only, PhantomJS 1 only\n // .get() because push.apply(_, arraylike) throws on ancient WebKit\n push.apply(ret, elems.get());\n }\n\n return this.pushStack(ret);\n };\n});\nvar rnumnonpx = new RegExp(\"^(\" + pnum + \")(?!px)[a-z%]+$\", \"i\");\n\nvar getStyles = function (elem) {\n\n // Support: IE <=11 only, Firefox <=30 (#15098, #14150)\n // IE throws on elements created in popups\n // FF meanwhile throws on frame elements through \"defaultView.getComputedStyle\"\n var view = elem.ownerDocument.defaultView;\n\n if (!view || !view.opener) {\n view = window;\n }\n\n return view.getComputedStyle(elem);\n};\n\nvar rboxStyle = new RegExp(cssExpand.join(\"|\"), \"i\");\n\n\n(function () {\n\n // Executing both pixelPosition & boxSizingReliable tests require only one layout\n // so they're executed at the same time to save the second computation.\n function computeStyleTests() {\n\n // This is a singleton, we need to execute it only once\n if (!div) {\n return;\n }\n\n container.style.cssText = \"position:absolute;left:-11111px;width:60px;\" +\n \"margin-top:1px;padding:0;border:0\";\n div.style.cssText =\n \"position:relative;display:block;box-sizing:border-box;overflow:scroll;\" +\n \"margin:auto;border:1px;padding:1px;\" +\n \"width:60%;top:1%\";\n documentElement.appendChild(container).appendChild(div);\n\n var divStyle = window.getComputedStyle(div);\n pixelPositionVal = divStyle.top !== \"1%\";\n\n // Support: Android 4.0 - 4.3 only, Firefox <=3 - 44\n reliableMarginLeftVal = roundPixelMeasures(divStyle.marginLeft) === 12;\n\n // Support: Android 4.0 - 4.3 only, Safari <=9.1 - 10.1, iOS <=7.0 - 9.3\n // Some styles come back with percentage values, even though they shouldn't\n div.style.right = \"60%\";\n pixelBoxStylesVal = roundPixelMeasures(divStyle.right) === 36;\n\n // Support: IE 9 - 11 only\n // Detect misreporting of content dimensions for box-sizing:border-box elements\n boxSizingReliableVal = roundPixelMeasures(divStyle.width) === 36;\n\n // Support: IE 9 only\n // Detect overflow:scroll screwiness (gh-3699)\n div.style.position = \"absolute\";\n scrollboxSizeVal = div.offsetWidth === 36 || \"absolute\";\n\n documentElement.removeChild(container);\n\n // Nullify the div so it wouldn't be stored in the memory and\n // it will also be a sign that checks already performed\n div = null;\n }\n\n function roundPixelMeasures(measure) {\n return Math.round(parseFloat(measure));\n }\n\n var pixelPositionVal, boxSizingReliableVal, scrollboxSizeVal, pixelBoxStylesVal,\n reliableMarginLeftVal,\n container = document$1.createElement(\"div\"),\n div = document$1.createElement(\"div\");\n\n // Finish early in limited (non-browser) environments\n if (!div.style) {\n return;\n }\n\n // Support: IE <=9 - 11 only\n // Style of cloned element affects source element cloned (#8908)\n div.style.backgroundClip = \"content-box\";\n div.cloneNode(true).style.backgroundClip = \"\";\n support.clearCloneStyle = div.style.backgroundClip === \"content-box\";\n\n jQuery.extend(support, {\n boxSizingReliable: function () {\n computeStyleTests();\n return boxSizingReliableVal;\n },\n pixelBoxStyles: function () {\n computeStyleTests();\n return pixelBoxStylesVal;\n },\n pixelPosition: function () {\n computeStyleTests();\n return pixelPositionVal;\n },\n reliableMarginLeft: function () {\n computeStyleTests();\n return reliableMarginLeftVal;\n },\n scrollboxSize: function () {\n computeStyleTests();\n return scrollboxSizeVal;\n }\n });\n})();\n\n\nfunction curCSS(elem, name, computed) {\n var width, minWidth, maxWidth, ret,\n\n // Support: Firefox 51+\n // Retrieving style before computed somehow\n // fixes an issue with getting wrong values\n // on detached elements\n style = elem.style;\n\n computed = computed || getStyles(elem);\n\n // getPropertyValue is needed for:\n // .css('filter') (IE 9 only, #12537)\n // .css('--customProperty) (#3144)\n if (computed) {\n ret = computed.getPropertyValue(name) || computed[name];\n\n if (ret === \"\" && !jQuery.contains(elem.ownerDocument, elem)) {\n ret = jQuery.style(elem, name);\n }\n\n // A tribute to the \"awesome hack by Dean Edwards\"\n // Android Browser returns percentage for some values,\n // but width seems to be reliably pixels.\n // This is against the CSSOM draft spec:\n // https://drafts.csswg.org/cssom/#resolved-values\n if (!support.pixelBoxStyles() && rnumnonpx.test(ret) && rboxStyle.test(name)) {\n\n // Remember the original values\n width = style.width;\n minWidth = style.minWidth;\n maxWidth = style.maxWidth;\n\n // Put in the new values to get a computed value out\n style.minWidth = style.maxWidth = style.width = ret;\n ret = computed.width;\n\n // Revert the changed values\n style.width = width;\n style.minWidth = minWidth;\n style.maxWidth = maxWidth;\n }\n }\n\n return ret !== undefined ?\n\n // Support: IE <=9 - 11 only\n // IE returns zIndex value as an integer.\n ret + \"\" :\n ret;\n}\n\n\nfunction addGetHookIf(conditionFn, hookFn) {\n\n // Define the hook, we'll check on the first run if it's really needed.\n return {\n get: function () {\n if (conditionFn()) {\n\n // Hook not needed (or it's not possible to use it due\n // to missing dependency), remove it.\n delete this.get;\n return;\n }\n\n // Hook needed; redefine it so that the support test is not executed again.\n return (this.get = hookFn).apply(this, arguments);\n }\n };\n}\n\n\nvar\n\n // Swappable if display is none or starts with table\n // except \"table\", \"table-cell\", or \"table-caption\"\n // See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display\n rdisplayswap = /^(none|table(?!-c[ea]).+)/,\n rcustomProp = /^--/,\n cssShow = {position: \"absolute\", visibility: \"hidden\", display: \"block\"},\n cssNormalTransform = {\n letterSpacing: \"0\",\n fontWeight: \"400\"\n },\n\n cssPrefixes = [\"Webkit\", \"Moz\", \"ms\"],\n emptyStyle = document$1.createElement(\"div\").style;\n\n// Return a css property mapped to a potentially vendor prefixed property\nfunction vendorPropName(name) {\n\n // Shortcut for names that are not vendor prefixed\n if (name in emptyStyle) {\n return name;\n }\n\n // Check for vendor prefixed names\n var capName = name[0].toUpperCase() + name.slice(1),\n i = cssPrefixes.length;\n\n while (i--) {\n name = cssPrefixes[i] + capName;\n if (name in emptyStyle) {\n return name;\n }\n }\n}\n\n// Return a property mapped along what jQuery.cssProps suggests or to\n// a vendor prefixed property.\nfunction finalPropName(name) {\n var ret = jQuery.cssProps[name];\n if (!ret) {\n ret = jQuery.cssProps[name] = vendorPropName(name) || name;\n }\n return ret;\n}\n\nfunction setPositiveNumber(elem, value, subtract) {\n\n // Any relative (+/-) values have already been\n // normalized at this point\n var matches = rcssNum.exec(value);\n return matches ?\n\n // Guard against undefined \"subtract\", e.g., when used as in cssHooks\n Math.max(0, matches[2] - (subtract || 0)) + (matches[3] || \"px\") :\n value;\n}\n\nfunction boxModelAdjustment(elem, dimension, box, isBorderBox, styles, computedVal) {\n var i = dimension === \"width\" ? 1 : 0,\n extra = 0,\n delta = 0;\n\n // Adjustment may not be necessary\n if (box === (isBorderBox ? \"border\" : \"content\")) {\n return 0;\n }\n\n for (; i < 4; i += 2) {\n\n // Both box models exclude margin\n if (box === \"margin\") {\n delta += jQuery.css(elem, box + cssExpand[i], true, styles);\n }\n\n // If we get here with a content-box, we're seeking \"padding\" or \"border\" or \"margin\"\n if (!isBorderBox) {\n\n // Add padding\n delta += jQuery.css(elem, \"padding\" + cssExpand[i], true, styles);\n\n // For \"border\" or \"margin\", add border\n if (box !== \"padding\") {\n delta += jQuery.css(elem, \"border\" + cssExpand[i] + \"Width\", true, styles);\n\n // But still keep track of it otherwise\n } else {\n extra += jQuery.css(elem, \"border\" + cssExpand[i] + \"Width\", true, styles);\n }\n\n // If we get here with a border-box (content + padding + border), we're seeking \"content\" or\n // \"padding\" or \"margin\"\n } else {\n\n // For \"content\", subtract padding\n if (box === \"content\") {\n delta -= jQuery.css(elem, \"padding\" + cssExpand[i], true, styles);\n }\n\n // For \"content\" or \"padding\", subtract border\n if (box !== \"margin\") {\n delta -= jQuery.css(elem, \"border\" + cssExpand[i] + \"Width\", true, styles);\n }\n }\n }\n\n // Account for positive content-box scroll gutter when requested by providing computedVal\n if (!isBorderBox && computedVal >= 0) {\n\n // offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border\n // Assuming integer scroll gutter, subtract the rest and round down\n delta += Math.max(0, Math.ceil(\n elem[\"offset\" + dimension[0].toUpperCase() + dimension.slice(1)] -\n computedVal -\n delta -\n extra -\n 0.5\n ));\n }\n\n return delta;\n}\n\nfunction getWidthOrHeight(elem, dimension, extra) {\n\n // Start with computed style\n var styles = getStyles(elem),\n val = curCSS(elem, dimension, styles),\n isBorderBox = jQuery.css(elem, \"boxSizing\", false, styles) === \"border-box\",\n valueIsBorderBox = isBorderBox;\n\n // Support: Firefox <=54\n // Return a confounding non-pixel value or feign ignorance, as appropriate.\n if (rnumnonpx.test(val)) {\n if (!extra) {\n return val;\n }\n val = \"auto\";\n }\n\n // Check for style in case a browser which returns unreliable values\n // for getComputedStyle silently falls back to the reliable elem.style\n valueIsBorderBox = valueIsBorderBox &&\n (support.boxSizingReliable() || val === elem.style[dimension]);\n\n // Fall back to offsetWidth/offsetHeight when value is \"auto\"\n // This happens for inline elements with no explicit setting (gh-3571)\n // Support: Android <=4.1 - 4.3 only\n // Also use offsetWidth/offsetHeight for misreported inline dimensions (gh-3602)\n if (val === \"auto\" ||\n !parseFloat(val) && jQuery.css(elem, \"display\", false, styles) === \"inline\") {\n\n val = elem[\"offset\" + dimension[0].toUpperCase() + dimension.slice(1)];\n\n // offsetWidth/offsetHeight provide border-box values\n valueIsBorderBox = true;\n }\n\n // Normalize \"\" and auto\n val = parseFloat(val) || 0;\n\n // Adjust for the element's box model\n return (val +\n boxModelAdjustment(\n elem,\n dimension,\n extra || (isBorderBox ? \"border\" : \"content\"),\n valueIsBorderBox,\n styles,\n\n // Provide the current computed size to request scroll gutter calculation (gh-3589)\n val\n )\n ) + \"px\";\n}\n\njQuery.extend({\n\n // Add in style property hooks for overriding the default\n // behavior of getting and setting a style property\n cssHooks: {\n opacity: {\n get: function (elem, computed) {\n if (computed) {\n\n // We should always get a number back from opacity\n var ret = curCSS(elem, \"opacity\");\n return ret === \"\" ? \"1\" : ret;\n }\n }\n }\n },\n\n // Don't automatically add \"px\" to these possibly-unitless properties\n cssNumber: {\n \"animationIterationCount\": true,\n \"columnCount\": true,\n \"fillOpacity\": true,\n \"flexGrow\": true,\n \"flexShrink\": true,\n \"fontWeight\": true,\n \"lineHeight\": true,\n \"opacity\": true,\n \"order\": true,\n \"orphans\": true,\n \"widows\": true,\n \"zIndex\": true,\n \"zoom\": true\n },\n\n // Add in properties whose names you wish to fix before\n // setting or getting the value\n cssProps: {},\n\n // Get and set the style property on a DOM Node\n style: function (elem, name, value, extra) {\n\n // Don't set styles on text and comment nodes\n if (!elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style) {\n return;\n }\n\n // Make sure that we're working with the right name\n var ret, type, hooks,\n origName = camelCase(name),\n isCustomProp = rcustomProp.test(name),\n style = elem.style;\n\n // Make sure that we're working with the right name. We don't\n // want to query the value if it is a CSS custom property\n // since they are user-defined.\n if (!isCustomProp) {\n name = finalPropName(origName);\n }\n\n // Gets hook for the prefixed version, then unprefixed version\n hooks = jQuery.cssHooks[name] || jQuery.cssHooks[origName];\n\n // Check if we're setting a value\n if (value !== undefined) {\n type = typeof value;\n\n // Convert \"+=\" or \"-=\" to relative numbers (#7345)\n if (type === \"string\" && (ret = rcssNum.exec(value)) && ret[1]) {\n value = adjustCSS(elem, name, ret);\n\n // Fixes bug #9237\n type = \"number\";\n }\n\n // Make sure that null and NaN values aren't set (#7116)\n if (value == null || value !== value) {\n return;\n }\n\n // If a number was passed in, add the unit (except for certain CSS properties)\n if (type === \"number\") {\n value += ret && ret[3] || (jQuery.cssNumber[origName] ? \"\" : \"px\");\n }\n\n // background-* props affect original clone's values\n if (!support.clearCloneStyle && value === \"\" && name.indexOf(\"background\") === 0) {\n style[name] = \"inherit\";\n }\n\n // If a hook was provided, use that value, otherwise just set the specified value\n if (!hooks || !(\"set\" in hooks) ||\n (value = hooks.set(elem, value, extra)) !== undefined) {\n\n if (isCustomProp) {\n style.setProperty(name, value);\n } else {\n style[name] = value;\n }\n }\n\n } else {\n\n // If a hook was provided get the non-computed value from there\n if (hooks && \"get\" in hooks &&\n (ret = hooks.get(elem, false, extra)) !== undefined) {\n\n return ret;\n }\n\n // Otherwise just get the value from the style object\n return style[name];\n }\n },\n\n css: function (elem, name, extra, styles) {\n var val, num, hooks,\n origName = camelCase(name),\n isCustomProp = rcustomProp.test(name);\n\n // Make sure that we're working with the right name. We don't\n // want to modify the value if it is a CSS custom property\n // since they are user-defined.\n if (!isCustomProp) {\n name = finalPropName(origName);\n }\n\n // Try prefixed name followed by the unprefixed name\n hooks = jQuery.cssHooks[name] || jQuery.cssHooks[origName];\n\n // If a hook was provided get the computed value from there\n if (hooks && \"get\" in hooks) {\n val = hooks.get(elem, true, extra);\n }\n\n // Otherwise, if a way to get the computed value exists, use that\n if (val === undefined) {\n val = curCSS(elem, name, styles);\n }\n\n // Convert \"normal\" to computed value\n if (val === \"normal\" && name in cssNormalTransform) {\n val = cssNormalTransform[name];\n }\n\n // Make numeric if forced or a qualifier was provided and val looks numeric\n if (extra === \"\" || extra) {\n num = parseFloat(val);\n return extra === true || isFinite(num) ? num || 0 : val;\n }\n\n return val;\n }\n});\n\njQuery.each([\"height\", \"width\"], function (i, dimension) {\n jQuery.cssHooks[dimension] = {\n get: function (elem, computed, extra) {\n if (computed) {\n\n // Certain elements can have dimension info if we invisibly show them\n // but it must have a current display style that would benefit\n return rdisplayswap.test(jQuery.css(elem, \"display\")) &&\n\n // Support: Safari 8+\n // Table columns in Safari have non-zero offsetWidth & zero\n // getBoundingClientRect().width unless display is changed.\n // Support: IE <=11 only\n // Running getBoundingClientRect on a disconnected node\n // in IE throws an error.\n (!elem.getClientRects().length || !elem.getBoundingClientRect().width) ?\n swap(elem, cssShow, function () {\n return getWidthOrHeight(elem, dimension, extra);\n }) :\n getWidthOrHeight(elem, dimension, extra);\n }\n },\n\n set: function (elem, value, extra) {\n var matches,\n styles = getStyles(elem),\n isBorderBox = jQuery.css(elem, \"boxSizing\", false, styles) === \"border-box\",\n subtract = extra && boxModelAdjustment(\n elem,\n dimension,\n extra,\n isBorderBox,\n styles\n );\n\n // Account for unreliable border-box dimensions by comparing offset* to computed and\n // faking a content-box to get border and padding (gh-3699)\n if (isBorderBox && support.scrollboxSize() === styles.position) {\n subtract -= Math.ceil(\n elem[\"offset\" + dimension[0].toUpperCase() + dimension.slice(1)] -\n parseFloat(styles[dimension]) -\n boxModelAdjustment(elem, dimension, \"border\", false, styles) -\n 0.5\n );\n }\n\n // Convert to pixels if value adjustment is needed\n if (subtract && (matches = rcssNum.exec(value)) &&\n (matches[3] || \"px\") !== \"px\") {\n\n elem.style[dimension] = value;\n value = jQuery.css(elem, dimension);\n }\n\n return setPositiveNumber(elem, value, subtract);\n }\n };\n});\n\njQuery.cssHooks.marginLeft = addGetHookIf(support.reliableMarginLeft,\n function (elem, computed) {\n if (computed) {\n return (parseFloat(curCSS(elem, \"marginLeft\")) ||\n elem.getBoundingClientRect().left -\n swap(elem, {marginLeft: 0}, function () {\n return elem.getBoundingClientRect().left;\n })\n ) + \"px\";\n }\n }\n);\n\n// These hooks are used by animate to expand properties\njQuery.each({\n margin: \"\",\n padding: \"\",\n border: \"Width\"\n}, function (prefix, suffix) {\n jQuery.cssHooks[prefix + suffix] = {\n expand: function (value) {\n var i = 0,\n expanded = {},\n\n // Assumes a single number if not a string\n parts = typeof value === \"string\" ? value.split(\" \") : [value];\n\n for (; i < 4; i++) {\n expanded[prefix + cssExpand[i] + suffix] =\n parts[i] || parts[i - 2] || parts[0];\n }\n\n return expanded;\n }\n };\n\n if (prefix !== \"margin\") {\n jQuery.cssHooks[prefix + suffix].set = setPositiveNumber;\n }\n});\n\njQuery.fn.extend({\n css: function (name, value) {\n return access(this, function (elem, name, value) {\n var styles, len,\n map = {},\n i = 0;\n\n if (Array.isArray(name)) {\n styles = getStyles(elem);\n len = name.length;\n\n for (; i < len; i++) {\n map[name[i]] = jQuery.css(elem, name[i], false, styles);\n }\n\n return map;\n }\n\n return value !== undefined ?\n jQuery.style(elem, name, value) :\n jQuery.css(elem, name);\n }, name, value, arguments.length > 1);\n }\n});\n\n\n// Based off of the plugin by Clint Helfers, with permission.\n// https://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/\njQuery.fn.delay = function (time, type) {\n time = jQuery.fx ? jQuery.fx.speeds[time] || time : time;\n type = type || \"fx\";\n\n return this.queue(type, function (next, hooks) {\n var timeout = window.setTimeout(next, time);\n hooks.stop = function () {\n window.clearTimeout(timeout);\n };\n });\n};\n\n\n(function () {\n var input = document$1.createElement(\"input\"),\n select = document$1.createElement(\"select\"),\n opt = select.appendChild(document$1.createElement(\"option\"));\n\n input.type = \"checkbox\";\n\n // Support: Android <=4.3 only\n // Default value for a checkbox should be \"on\"\n support.checkOn = input.value !== \"\";\n\n // Support: IE <=11 only\n // Must access selectedIndex to make default options select\n support.optSelected = opt.selected;\n\n // Support: IE <=11 only\n // An input loses its value after becoming a radio\n input = document$1.createElement(\"input\");\n input.value = \"t\";\n input.type = \"radio\";\n support.radioValue = input.value === \"t\";\n})();\n\n\nvar boolHook,\n attrHandle = jQuery.expr.attrHandle;\n\njQuery.fn.extend({\n attr: function (name, value) {\n return access(this, jQuery.attr, name, value, arguments.length > 1);\n },\n\n removeAttr: function (name) {\n return this.each(function () {\n jQuery.removeAttr(this, name);\n });\n }\n});\n\njQuery.extend({\n attr: function (elem, name, value) {\n var ret, hooks,\n nType = elem.nodeType;\n\n // Don't get/set attributes on text, comment and attribute nodes\n if (nType === 3 || nType === 8 || nType === 2) {\n return;\n }\n\n // Fallback to prop when attributes are not supported\n if (typeof elem.getAttribute === \"undefined\") {\n return jQuery.prop(elem, name, value);\n }\n\n // Attribute hooks are determined by the lowercase version\n // Grab necessary hook if one is defined\n if (nType !== 1 || !jQuery.isXMLDoc(elem)) {\n hooks = jQuery.attrHooks[name.toLowerCase()] ||\n (jQuery.expr.match.bool.test(name) ? boolHook : undefined);\n }\n\n if (value !== undefined) {\n if (value === null) {\n jQuery.removeAttr(elem, name);\n return;\n }\n\n if (hooks && \"set\" in hooks &&\n (ret = hooks.set(elem, value, name)) !== undefined) {\n return ret;\n }\n\n elem.setAttribute(name, value + \"\");\n return value;\n }\n\n if (hooks && \"get\" in hooks && (ret = hooks.get(elem, name)) !== null) {\n return ret;\n }\n\n ret = jQuery.find.attr(elem, name);\n\n // Non-existent attributes return null, we normalize to undefined\n return ret == null ? undefined : ret;\n },\n\n attrHooks: {\n type: {\n set: function (elem, value) {\n if (!support.radioValue && value === \"radio\" &&\n nodeName(elem, \"input\")) {\n var val = elem.value;\n elem.setAttribute(\"type\", value);\n if (val) {\n elem.value = val;\n }\n return value;\n }\n }\n }\n },\n\n removeAttr: function (elem, value) {\n var name,\n i = 0,\n\n // Attribute names can contain non-HTML whitespace characters\n // https://html.spec.whatwg.org/multipage/syntax.html#attributes-2\n attrNames = value && value.match(rnothtmlwhite);\n\n if (attrNames && elem.nodeType === 1) {\n while ((name = attrNames[i++])) {\n elem.removeAttribute(name);\n }\n }\n }\n});\n\n// Hooks for boolean attributes\nboolHook = {\n set: function (elem, value, name) {\n if (value === false) {\n\n // Remove boolean attributes when set to false\n jQuery.removeAttr(elem, name);\n } else {\n elem.setAttribute(name, name);\n }\n return name;\n }\n};\n\njQuery.each(jQuery.expr.match.bool.source.match(/\\w+/g), function (i, name) {\n var getter = attrHandle[name] || jQuery.find.attr;\n\n attrHandle[name] = function (elem, name, isXML) {\n var ret, handle,\n lowercaseName = name.toLowerCase();\n\n if (!isXML) {\n\n // Avoid an infinite loop by temporarily removing this function from the getter\n handle = attrHandle[lowercaseName];\n attrHandle[lowercaseName] = ret;\n ret = getter(elem, name, isXML) != null ?\n lowercaseName :\n null;\n attrHandle[lowercaseName] = handle;\n }\n return ret;\n };\n});\n\n\nvar rfocusable = /^(?:input|select|textarea|button)$/i,\n rclickable = /^(?:a|area)$/i;\n\njQuery.fn.extend({\n prop: function (name, value) {\n return access(this, jQuery.prop, name, value, arguments.length > 1);\n },\n\n removeProp: function (name) {\n return this.each(function () {\n delete this[jQuery.propFix[name] || name];\n });\n }\n});\n\njQuery.extend({\n prop: function (elem, name, value) {\n var ret, hooks,\n nType = elem.nodeType;\n\n // Don't get/set properties on text, comment and attribute nodes\n if (nType === 3 || nType === 8 || nType === 2) {\n return;\n }\n\n if (nType !== 1 || !jQuery.isXMLDoc(elem)) {\n\n // Fix name and attach hooks\n name = jQuery.propFix[name] || name;\n hooks = jQuery.propHooks[name];\n }\n\n if (value !== undefined) {\n if (hooks && \"set\" in hooks &&\n (ret = hooks.set(elem, value, name)) !== undefined) {\n return ret;\n }\n\n return (elem[name] = value);\n }\n\n if (hooks && \"get\" in hooks && (ret = hooks.get(elem, name)) !== null) {\n return ret;\n }\n\n return elem[name];\n },\n\n propHooks: {\n tabIndex: {\n get: function (elem) {\n\n // Support: IE <=9 - 11 only\n // elem.tabIndex doesn't always return the\n // correct value when it hasn't been explicitly set\n // https://web.archive.org/web/20141116233347/http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/\n // Use proper attribute retrieval(#12072)\n var tabindex = jQuery.find.attr(elem, \"tabindex\");\n\n if (tabindex) {\n return parseInt(tabindex, 10);\n }\n\n if (\n rfocusable.test(elem.nodeName) ||\n rclickable.test(elem.nodeName) &&\n elem.href\n ) {\n return 0;\n }\n\n return -1;\n }\n }\n },\n\n propFix: {\n \"for\": \"htmlFor\",\n \"class\": \"className\"\n }\n});\n\n// Support: IE <=11 only\n// Accessing the selectedIndex property\n// forces the browser to respect setting selected\n// on the option\n// The getter ensures a default option is selected\n// when in an optgroup\n// eslint rule \"no-unused-expressions\" is disabled for this code\n// since it considers such accessions noop\nif (!support.optSelected) {\n jQuery.propHooks.selected = {\n get: function (elem) {\n\n /* eslint no-unused-expressions: \"off\" */\n\n var parent = elem.parentNode;\n if (parent && parent.parentNode) {\n parent.parentNode.selectedIndex;\n }\n return null;\n },\n set: function (elem) {\n\n /* eslint no-unused-expressions: \"off\" */\n\n var parent = elem.parentNode;\n if (parent) {\n parent.selectedIndex;\n\n if (parent.parentNode) {\n parent.parentNode.selectedIndex;\n }\n }\n }\n };\n}\n\njQuery.each([\n \"tabIndex\",\n \"readOnly\",\n \"maxLength\",\n \"cellSpacing\",\n \"cellPadding\",\n \"rowSpan\",\n \"colSpan\",\n \"useMap\",\n \"frameBorder\",\n \"contentEditable\"\n], function () {\n jQuery.propFix[this.toLowerCase()] = this;\n});\n\n\n// Strip and collapse whitespace according to HTML spec\n// https://infra.spec.whatwg.org/#strip-and-collapse-ascii-whitespace\nfunction stripAndCollapse(value) {\n var tokens = value.match(rnothtmlwhite) || [];\n return tokens.join(\" \");\n}\n\n\nfunction getClass(elem) {\n return elem.getAttribute && elem.getAttribute(\"class\") || \"\";\n}\n\nfunction classesToArray(value) {\n if (Array.isArray(value)) {\n return value;\n }\n if (typeof value === \"string\") {\n return value.match(rnothtmlwhite) || [];\n }\n return [];\n}\n\njQuery.fn.extend({\n addClass: function (value) {\n var classes, elem, cur, curValue, clazz, j, finalValue,\n i = 0;\n\n if (isFunction(value)) {\n return this.each(function (j) {\n jQuery(this).addClass(value.call(this, j, getClass(this)));\n });\n }\n\n classes = classesToArray(value);\n\n if (classes.length) {\n while ((elem = this[i++])) {\n curValue = getClass(elem);\n cur = elem.nodeType === 1 && (\" \" + stripAndCollapse(curValue) + \" \");\n\n if (cur) {\n j = 0;\n while ((clazz = classes[j++])) {\n if (cur.indexOf(\" \" + clazz + \" \") < 0) {\n cur += clazz + \" \";\n }\n }\n\n // Only assign if different to avoid unneeded rendering.\n finalValue = stripAndCollapse(cur);\n if (curValue !== finalValue) {\n elem.setAttribute(\"class\", finalValue);\n }\n }\n }\n }\n\n return this;\n },\n\n removeClass: function (value) {\n var classes, elem, cur, curValue, clazz, j, finalValue,\n i = 0;\n\n if (isFunction(value)) {\n return this.each(function (j) {\n jQuery(this).removeClass(value.call(this, j, getClass(this)));\n });\n }\n\n if (!arguments.length) {\n return this.attr(\"class\", \"\");\n }\n\n classes = classesToArray(value);\n\n if (classes.length) {\n while ((elem = this[i++])) {\n curValue = getClass(elem);\n\n // This expression is here for better compressibility (see addClass)\n cur = elem.nodeType === 1 && (\" \" + stripAndCollapse(curValue) + \" \");\n\n if (cur) {\n j = 0;\n while ((clazz = classes[j++])) {\n\n // Remove *all* instances\n while (cur.indexOf(\" \" + clazz + \" \") > -1) {\n cur = cur.replace(\" \" + clazz + \" \", \" \");\n }\n }\n\n // Only assign if different to avoid unneeded rendering.\n finalValue = stripAndCollapse(cur);\n if (curValue !== finalValue) {\n elem.setAttribute(\"class\", finalValue);\n }\n }\n }\n }\n\n return this;\n },\n\n toggleClass: function (value, stateVal) {\n var type = typeof value,\n isValidValue = type === \"string\" || Array.isArray(value);\n\n if (typeof stateVal === \"boolean\" && isValidValue) {\n return stateVal ? this.addClass(value) : this.removeClass(value);\n }\n\n if (isFunction(value)) {\n return this.each(function (i) {\n jQuery(this).toggleClass(\n value.call(this, i, getClass(this), stateVal),\n stateVal\n );\n });\n }\n\n return this.each(function () {\n var className, i, self, classNames;\n\n if (isValidValue) {\n\n // Toggle individual class names\n i = 0;\n self = jQuery(this);\n classNames = classesToArray(value);\n\n while ((className = classNames[i++])) {\n\n // Check each className given, space separated list\n if (self.hasClass(className)) {\n self.removeClass(className);\n } else {\n self.addClass(className);\n }\n }\n\n // Toggle whole class name\n } else if (value === undefined || type === \"boolean\") {\n className = getClass(this);\n if (className) {\n\n // Store className if set\n dataPriv.set(this, \"__className__\", className);\n }\n\n // If the element has a class name or if we're passed `false`,\n // then remove the whole classname (if there was one, the above saved it).\n // Otherwise bring back whatever was previously saved (if anything),\n // falling back to the empty string if nothing was stored.\n if (this.setAttribute) {\n this.setAttribute(\"class\",\n className || value === false ?\n \"\" :\n dataPriv.get(this, \"__className__\") || \"\"\n );\n }\n }\n });\n },\n\n hasClass: function (selector) {\n var className, elem,\n i = 0;\n\n className = \" \" + selector + \" \";\n while ((elem = this[i++])) {\n if (elem.nodeType === 1 &&\n (\" \" + stripAndCollapse(getClass(elem)) + \" \").indexOf(className) > -1) {\n return true;\n }\n }\n\n return false;\n }\n});\n\n\nvar rreturn = /\\r/g;\n\njQuery.fn.extend({\n val: function (value) {\n var hooks, ret, valueIsFunction,\n elem = this[0];\n\n if (!arguments.length) {\n if (elem) {\n hooks = jQuery.valHooks[elem.type] ||\n jQuery.valHooks[elem.nodeName.toLowerCase()];\n\n if (hooks &&\n \"get\" in hooks &&\n (ret = hooks.get(elem, \"value\")) !== undefined\n ) {\n return ret;\n }\n\n ret = elem.value;\n\n // Handle most common string cases\n if (typeof ret === \"string\") {\n return ret.replace(rreturn, \"\");\n }\n\n // Handle cases where value is null/undef or number\n return ret == null ? \"\" : ret;\n }\n\n return;\n }\n\n valueIsFunction = isFunction(value);\n\n return this.each(function (i) {\n var val;\n\n if (this.nodeType !== 1) {\n return;\n }\n\n if (valueIsFunction) {\n val = value.call(this, i, jQuery(this).val());\n } else {\n val = value;\n }\n\n // Treat null/undefined as \"\"; convert numbers to string\n if (val == null) {\n val = \"\";\n\n } else if (typeof val === \"number\") {\n val += \"\";\n\n } else if (Array.isArray(val)) {\n val = jQuery.map(val, function (value) {\n return value == null ? \"\" : value + \"\";\n });\n }\n\n hooks = jQuery.valHooks[this.type] || jQuery.valHooks[this.nodeName.toLowerCase()];\n\n // If set returns undefined, fall back to normal setting\n if (!hooks || !(\"set\" in hooks) || hooks.set(this, val, \"value\") === undefined) {\n this.value = val;\n }\n });\n }\n});\n\njQuery.extend({\n valHooks: {\n option: {\n get: function (elem) {\n\n var val = jQuery.find.attr(elem, \"value\");\n return val != null ?\n val :\n\n // Support: IE <=10 - 11 only\n // option.text throws exceptions (#14686, #14858)\n // Strip and collapse whitespace\n // https://html.spec.whatwg.org/#strip-and-collapse-whitespace\n stripAndCollapse(jQuery.text(elem));\n }\n },\n select: {\n get: function (elem) {\n var value, option, i,\n options = elem.options,\n index = elem.selectedIndex,\n one = elem.type === \"select-one\",\n values = one ? null : [],\n max = one ? index + 1 : options.length;\n\n if (index < 0) {\n i = max;\n\n } else {\n i = one ? index : 0;\n }\n\n // Loop through all the selected options\n for (; i < max; i++) {\n option = options[i];\n\n // Support: IE <=9 only\n // IE8-9 doesn't update selected after form reset (#2551)\n if ((option.selected || i === index) &&\n\n // Don't return options that are disabled or in a disabled optgroup\n !option.disabled &&\n (!option.parentNode.disabled ||\n !nodeName(option.parentNode, \"optgroup\"))) {\n\n // Get the specific value for the option\n value = jQuery(option).val();\n\n // We don't need an array for one selects\n if (one) {\n return value;\n }\n\n // Multi-Selects return an array\n values.push(value);\n }\n }\n\n return values;\n },\n\n set: function (elem, value) {\n var optionSet, option,\n options = elem.options,\n values = jQuery.makeArray(value),\n i = options.length;\n\n while (i--) {\n option = options[i];\n\n /* eslint-disable no-cond-assign */\n\n if (option.selected =\n jQuery.inArray(jQuery.valHooks.option.get(option), values) > -1\n ) {\n optionSet = true;\n }\n\n /* eslint-enable no-cond-assign */\n }\n\n // Force browsers to behave consistently when non-matching value is set\n if (!optionSet) {\n elem.selectedIndex = -1;\n }\n return values;\n }\n }\n }\n});\n\n// Radios and checkboxes getter/setter\njQuery.each([\"radio\", \"checkbox\"], function () {\n jQuery.valHooks[this] = {\n set: function (elem, value) {\n if (Array.isArray(value)) {\n return (elem.checked = jQuery.inArray(jQuery(elem).val(), value) > -1);\n }\n }\n };\n if (!support.checkOn) {\n jQuery.valHooks[this].get = function (elem) {\n return elem.getAttribute(\"value\") === null ? \"on\" : elem.value;\n };\n }\n});\n\n\n// Return jQuery for attributes-only inclusion\n\n\nsupport.focusin = \"onfocusin\" in window;\n\n\nvar rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,\n stopPropagationCallback = function (e) {\n e.stopPropagation();\n };\n\njQuery.extend(jQuery.event, {\n\n trigger: function (event, data, elem, onlyHandlers) {\n\n var i, cur, tmp, bubbleType, ontype, handle, special, lastElement,\n eventPath = [elem || document$1],\n type = hasOwn.call(event, \"type\") ? event.type : event,\n namespaces = hasOwn.call(event, \"namespace\") ? event.namespace.split(\".\") : [];\n\n cur = lastElement = tmp = elem = elem || document$1;\n\n // Don't do events on text and comment nodes\n if (elem.nodeType === 3 || elem.nodeType === 8) {\n return;\n }\n\n // focus/blur morphs to focusin/out; ensure we're not firing them right now\n if (rfocusMorph.test(type + jQuery.event.triggered)) {\n return;\n }\n\n if (type.indexOf(\".\") > -1) {\n\n // Namespaced trigger; create a regexp to match event type in handle()\n namespaces = type.split(\".\");\n type = namespaces.shift();\n namespaces.sort();\n }\n ontype = type.indexOf(\":\") < 0 && \"on\" + type;\n\n // Caller can pass in a jQuery.Event object, Object, or just an event type string\n event = event[jQuery.expando] ?\n event :\n new jQuery.Event(type, typeof event === \"object\" && event);\n\n // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)\n event.isTrigger = onlyHandlers ? 2 : 3;\n event.namespace = namespaces.join(\".\");\n event.rnamespace = event.namespace ?\n new RegExp(\"(^|\\\\.)\" + namespaces.join(\"\\\\.(?:.*\\\\.|)\") + \"(\\\\.|$)\") :\n null;\n\n // Clean up the event in case it is being reused\n event.result = undefined;\n if (!event.target) {\n event.target = elem;\n }\n\n // Clone any incoming data and prepend the event, creating the handler arg list\n data = data == null ?\n [event] :\n jQuery.makeArray(data, [event]);\n\n // Allow special events to draw outside the lines\n special = jQuery.event.special[type] || {};\n if (!onlyHandlers && special.trigger && special.trigger.apply(elem, data) === false) {\n return;\n }\n\n // Determine event propagation path in advance, per W3C events spec (#9951)\n // Bubble up to document, then to window; watch for a global ownerDocument var (#9724)\n if (!onlyHandlers && !special.noBubble && !isWindow(elem)) {\n\n bubbleType = special.delegateType || type;\n if (!rfocusMorph.test(bubbleType + type)) {\n cur = cur.parentNode;\n }\n for (; cur; cur = cur.parentNode) {\n eventPath.push(cur);\n tmp = cur;\n }\n\n // Only add window if we got to document (e.g., not plain obj or detached DOM)\n if (tmp === (elem.ownerDocument || document$1)) {\n eventPath.push(tmp.defaultView || tmp.parentWindow || window);\n }\n }\n\n // Fire handlers on the event path\n i = 0;\n while ((cur = eventPath[i++]) && !event.isPropagationStopped()) {\n lastElement = cur;\n event.type = i > 1 ?\n bubbleType :\n special.bindType || type;\n\n // jQuery handler\n handle = (dataPriv.get(cur, \"events\") || {})[event.type] &&\n dataPriv.get(cur, \"handle\");\n if (handle) {\n handle.apply(cur, data);\n }\n\n // Native handler\n handle = ontype && cur[ontype];\n if (handle && handle.apply && acceptData(cur)) {\n event.result = handle.apply(cur, data);\n if (event.result === false) {\n event.preventDefault();\n }\n }\n }\n event.type = type;\n\n // If nobody prevented the default action, do it now\n if (!onlyHandlers && !event.isDefaultPrevented()) {\n\n if ((!special._default ||\n special._default.apply(eventPath.pop(), data) === false) &&\n acceptData(elem)) {\n\n // Call a native DOM method on the target with the same name as the event.\n // Don't do default actions on window, that's where global variables be (#6170)\n if (ontype && isFunction(elem[type]) && !isWindow(elem)) {\n\n // Don't re-trigger an onFOO event when we call its FOO() method\n tmp = elem[ontype];\n\n if (tmp) {\n elem[ontype] = null;\n }\n\n // Prevent re-triggering of the same event, since we already bubbled it above\n jQuery.event.triggered = type;\n\n if (event.isPropagationStopped()) {\n lastElement.addEventListener(type, stopPropagationCallback);\n }\n\n elem[type]();\n\n if (event.isPropagationStopped()) {\n lastElement.removeEventListener(type, stopPropagationCallback);\n }\n\n jQuery.event.triggered = undefined;\n\n if (tmp) {\n elem[ontype] = tmp;\n }\n }\n }\n }\n\n return event.result;\n },\n\n // Piggyback on a donor event to simulate a different one\n // Used only for `focus(in | out)` events\n simulate: function (type, elem, event) {\n var e = jQuery.extend(\n new jQuery.Event(),\n event,\n {\n type: type,\n isSimulated: true\n }\n );\n\n jQuery.event.trigger(e, null, elem);\n }\n\n});\n\njQuery.fn.extend({\n\n trigger: function (type, data) {\n return this.each(function () {\n jQuery.event.trigger(type, data, this);\n });\n },\n triggerHandler: function (type, data) {\n var elem = this[0];\n if (elem) {\n return jQuery.event.trigger(type, data, elem, true);\n }\n }\n});\n\n\n// Support: Firefox <=44\n// Firefox doesn't have focus(in | out) events\n// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787\n//\n// Support: Chrome <=48 - 49, Safari <=9.0 - 9.1\n// focus(in | out) events fire after focus & blur events,\n// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order\n// Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857\nif (!support.focusin) {\n jQuery.each({focus: \"focusin\", blur: \"focusout\"}, function (orig, fix) {\n\n // Attach a single capturing handler on the document while someone wants focusin/focusout\n var handler = function (event) {\n jQuery.event.simulate(fix, event.target, jQuery.event.fix(event));\n };\n\n jQuery.event.special[fix] = {\n setup: function () {\n var doc = this.ownerDocument || this,\n attaches = dataPriv.access(doc, fix);\n\n if (!attaches) {\n doc.addEventListener(orig, handler, true);\n }\n dataPriv.access(doc, fix, (attaches || 0) + 1);\n },\n teardown: function () {\n var doc = this.ownerDocument || this,\n attaches = dataPriv.access(doc, fix) - 1;\n\n if (!attaches) {\n doc.removeEventListener(orig, handler, true);\n dataPriv.remove(doc, fix);\n\n } else {\n dataPriv.access(doc, fix, attaches);\n }\n }\n };\n });\n}\n\n\nvar\n rbracket = /\\[\\]$/,\n rCRLF = /\\r?\\n/g,\n rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,\n rsubmittable = /^(?:input|select|textarea|keygen)/i;\n\nfunction buildParams(prefix, obj, traditional, add) {\n var name;\n\n if (Array.isArray(obj)) {\n\n // Serialize array item.\n jQuery.each(obj, function (i, v) {\n if (traditional || rbracket.test(prefix)) {\n\n // Treat each array item as a scalar.\n add(prefix, v);\n\n } else {\n\n // Item is non-scalar (array or object), encode its numeric index.\n buildParams(\n prefix + \"[\" + (typeof v === \"object\" && v != null ? i : \"\") + \"]\",\n v,\n traditional,\n add\n );\n }\n });\n\n } else if (!traditional && toType(obj) === \"object\") {\n\n // Serialize object item.\n for (name in obj) {\n buildParams(prefix + \"[\" + name + \"]\", obj[name], traditional, add);\n }\n\n } else {\n\n // Serialize scalar item.\n add(prefix, obj);\n }\n}\n\n// Serialize an array of form elements or a set of\n// key/values into a query string\njQuery.param = function (a, traditional) {\n var prefix,\n s = [],\n add = function (key, valueOrFunction) {\n\n // If value is a function, invoke it and use its return value\n var value = isFunction(valueOrFunction) ?\n valueOrFunction() :\n valueOrFunction;\n\n s[s.length] = encodeURIComponent(key) + \"=\" +\n encodeURIComponent(value == null ? \"\" : value);\n };\n\n // If an array was passed in, assume that it is an array of form elements.\n if (Array.isArray(a) || (a.jquery && !jQuery.isPlainObject(a))) {\n\n // Serialize the form elements\n jQuery.each(a, function () {\n add(this.name, this.value);\n });\n\n } else {\n\n // If traditional, encode the \"old\" way (the way 1.3.2 or older\n // did it), otherwise encode params recursively.\n for (prefix in a) {\n buildParams(prefix, a[prefix], traditional, add);\n }\n }\n\n // Return the resulting serialization\n return s.join(\"&\");\n};\n\njQuery.fn.extend({\n serialize: function () {\n return jQuery.param(this.serializeArray());\n },\n serializeArray: function () {\n return this.map(function () {\n\n // Can add propHook for \"elements\" to filter or add form elements\n var elements = jQuery.prop(this, \"elements\");\n return elements ? jQuery.makeArray(elements) : this;\n })\n .filter(function () {\n var type = this.type;\n\n // Use .is( \":disabled\" ) so that fieldset[disabled] works\n return this.name && !jQuery(this).is(\":disabled\") &&\n rsubmittable.test(this.nodeName) && !rsubmitterTypes.test(type) &&\n (this.checked || !rcheckableType.test(type));\n })\n .map(function (i, elem) {\n var val = jQuery(this).val();\n\n if (val == null) {\n return null;\n }\n\n if (Array.isArray(val)) {\n return jQuery.map(val, function (val) {\n return {name: elem.name, value: val.replace(rCRLF, \"\\r\\n\")};\n });\n }\n\n return {name: elem.name, value: val.replace(rCRLF, \"\\r\\n\")};\n }).get();\n }\n});\n\n\njQuery.fn.extend({\n wrapAll: function (html) {\n var wrap;\n\n if (this[0]) {\n if (isFunction(html)) {\n html = html.call(this[0]);\n }\n\n // The elements to wrap the target around\n wrap = jQuery(html, this[0].ownerDocument).eq(0).clone(true);\n\n if (this[0].parentNode) {\n wrap.insertBefore(this[0]);\n }\n\n wrap.map(function () {\n var elem = this;\n\n while (elem.firstElementChild) {\n elem = elem.firstElementChild;\n }\n\n return elem;\n }).append(this);\n }\n\n return this;\n },\n\n wrapInner: function (html) {\n if (isFunction(html)) {\n return this.each(function (i) {\n jQuery(this).wrapInner(html.call(this, i));\n });\n }\n\n return this.each(function () {\n var self = jQuery(this),\n contents = self.contents();\n\n if (contents.length) {\n contents.wrapAll(html);\n\n } else {\n self.append(html);\n }\n });\n },\n\n wrap: function (html) {\n var htmlIsFunction = isFunction(html);\n\n return this.each(function (i) {\n jQuery(this).wrapAll(htmlIsFunction ? html.call(this, i) : html);\n });\n },\n\n unwrap: function (selector) {\n this.parent(selector).not(\"body\").each(function () {\n jQuery(this).replaceWith(this.childNodes);\n });\n return this;\n }\n});\n\n\njQuery.expr.pseudos.hidden = function (elem) {\n return !jQuery.expr.pseudos.visible(elem);\n};\njQuery.expr.pseudos.visible = function (elem) {\n return !!(elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length);\n};\n\n\n// Support: Safari 8 only\n// In Safari 8 documents created via document.implementation.createHTMLDocument\n// collapse sibling forms: the second one becomes a child of the first one.\n// Because of that, this security measure has to be disabled in Safari 8.\n// https://bugs.webkit.org/show_bug.cgi?id=137337\nsupport.createHTMLDocument = (function () {\n var body = document$1.implementation.createHTMLDocument(\"\").body;\n body.innerHTML = \"
\";\n return body.childNodes.length === 2;\n})();\n\n\n// Argument \"data\" should be string of html\n// context (optional): If specified, the fragment will be created in this context,\n// defaults to document\n// keepScripts (optional): If true, will include scripts passed in the html string\njQuery.parseHTML = function (data, context, keepScripts) {\n if (typeof data !== \"string\") {\n return [];\n }\n if (typeof context === \"boolean\") {\n keepScripts = context;\n context = false;\n }\n\n var base, parsed, scripts;\n\n if (!context) {\n\n // Stop scripts or inline event handlers from being executed immediately\n // by using document.implementation\n if (support.createHTMLDocument) {\n context = document$1.implementation.createHTMLDocument(\"\");\n\n // Set the base href for the created document\n // so any parsed elements with URLs\n // are based on the document's URL (gh-2965)\n base = context.createElement(\"base\");\n base.href = document$1.location.href;\n context.head.appendChild(base);\n } else {\n context = document$1;\n }\n }\n\n parsed = rsingleTag.exec(data);\n scripts = !keepScripts && [];\n\n // Single tag\n if (parsed) {\n return [context.createElement(parsed[1])];\n }\n\n parsed = buildFragment([data], context, scripts);\n\n if (scripts && scripts.length) {\n jQuery(scripts).remove();\n }\n\n return jQuery.merge([], parsed.childNodes);\n};\n\n\njQuery.offset = {\n setOffset: function (elem, options, i) {\n var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,\n position = jQuery.css(elem, \"position\"),\n curElem = jQuery(elem),\n props = {};\n\n // Set position first, in-case top/left are set even on static elem\n if (position === \"static\") {\n elem.style.position = \"relative\";\n }\n\n curOffset = curElem.offset();\n curCSSTop = jQuery.css(elem, \"top\");\n curCSSLeft = jQuery.css(elem, \"left\");\n calculatePosition = (position === \"absolute\" || position === \"fixed\") &&\n (curCSSTop + curCSSLeft).indexOf(\"auto\") > -1;\n\n // Need to be able to calculate position if either\n // top or left is auto and position is either absolute or fixed\n if (calculatePosition) {\n curPosition = curElem.position();\n curTop = curPosition.top;\n curLeft = curPosition.left;\n\n } else {\n curTop = parseFloat(curCSSTop) || 0;\n curLeft = parseFloat(curCSSLeft) || 0;\n }\n\n if (isFunction(options)) {\n\n // Use jQuery.extend here to allow modification of coordinates argument (gh-1848)\n options = options.call(elem, i, jQuery.extend({}, curOffset));\n }\n\n if (options.top != null) {\n props.top = (options.top - curOffset.top) + curTop;\n }\n if (options.left != null) {\n props.left = (options.left - curOffset.left) + curLeft;\n }\n\n if (\"using\" in options) {\n options.using.call(elem, props);\n\n } else {\n curElem.css(props);\n }\n }\n};\n\njQuery.fn.extend({\n\n // offset() relates an element's border box to the document origin\n offset: function (options) {\n\n // Preserve chaining for setter\n if (arguments.length) {\n return options === undefined ?\n this :\n this.each(function (i) {\n jQuery.offset.setOffset(this, options, i);\n });\n }\n\n var rect, win,\n elem = this[0];\n\n if (!elem) {\n return;\n }\n\n // Return zeros for disconnected and hidden (display: none) elements (gh-2310)\n // Support: IE <=11 only\n // Running getBoundingClientRect on a\n // disconnected node in IE throws an error\n if (!elem.getClientRects().length) {\n return {top: 0, left: 0};\n }\n\n // Get document-relative position by adding viewport scroll to viewport-relative gBCR\n rect = elem.getBoundingClientRect();\n win = elem.ownerDocument.defaultView;\n return {\n top: rect.top + win.pageYOffset,\n left: rect.left + win.pageXOffset\n };\n },\n\n // position() relates an element's margin box to its offset parent's padding box\n // This corresponds to the behavior of CSS absolute positioning\n position: function () {\n if (!this[0]) {\n return;\n }\n\n var offsetParent, offset, doc,\n elem = this[0],\n parentOffset = {top: 0, left: 0};\n\n // position:fixed elements are offset from the viewport, which itself always has zero offset\n if (jQuery.css(elem, \"position\") === \"fixed\") {\n\n // Assume position:fixed implies availability of getBoundingClientRect\n offset = elem.getBoundingClientRect();\n\n } else {\n offset = this.offset();\n\n // Account for the *real* offset parent, which can be the document or its root element\n // when a statically positioned element is identified\n doc = elem.ownerDocument;\n offsetParent = elem.offsetParent || doc.documentElement;\n while (offsetParent &&\n (offsetParent === doc.body || offsetParent === doc.documentElement) &&\n jQuery.css(offsetParent, \"position\") === \"static\") {\n\n offsetParent = offsetParent.parentNode;\n }\n if (offsetParent && offsetParent !== elem && offsetParent.nodeType === 1) {\n\n // Incorporate borders into its offset, since they are outside its content origin\n parentOffset = jQuery(offsetParent).offset();\n parentOffset.top += jQuery.css(offsetParent, \"borderTopWidth\", true);\n parentOffset.left += jQuery.css(offsetParent, \"borderLeftWidth\", true);\n }\n }\n\n // Subtract parent offsets and element margins\n return {\n top: offset.top - parentOffset.top - jQuery.css(elem, \"marginTop\", true),\n left: offset.left - parentOffset.left - jQuery.css(elem, \"marginLeft\", true)\n };\n },\n\n // This method will return documentElement in the following cases:\n // 1) For the element inside the iframe without offsetParent, this method will return\n // documentElement of the parent window\n // 2) For the hidden or detached element\n // 3) For body or html element, i.e. in case of the html node - it will return itself\n //\n // but those exceptions were never presented as a real life use-cases\n // and might be considered as more preferable results.\n //\n // This logic, however, is not guaranteed and can change at any point in the future\n offsetParent: function () {\n return this.map(function () {\n var offsetParent = this.offsetParent;\n\n while (offsetParent && jQuery.css(offsetParent, \"position\") === \"static\") {\n offsetParent = offsetParent.offsetParent;\n }\n\n return offsetParent || documentElement;\n });\n }\n});\n\n// Create scrollLeft and scrollTop methods\njQuery.each({scrollLeft: \"pageXOffset\", scrollTop: \"pageYOffset\"}, function (method, prop) {\n var top = \"pageYOffset\" === prop;\n\n jQuery.fn[method] = function (val) {\n return access(this, function (elem, method, val) {\n\n // Coalesce documents and windows\n var win;\n if (isWindow(elem)) {\n win = elem;\n } else if (elem.nodeType === 9) {\n win = elem.defaultView;\n }\n\n if (val === undefined) {\n return win ? win[prop] : elem[method];\n }\n\n if (win) {\n win.scrollTo(\n !top ? val : win.pageXOffset,\n top ? val : win.pageYOffset\n );\n\n } else {\n elem[method] = val;\n }\n }, method, val, arguments.length);\n };\n});\n\n// Support: Safari <=7 - 9.1, Chrome <=37 - 49\n// Add the top/left cssHooks using jQuery.fn.position\n// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084\n// Blink bug: https://bugs.chromium.org/p/chromium/issues/detail?id=589347\n// getComputedStyle returns percent when specified for top/left/bottom/right;\n// rather than make the css module depend on the offset module, just check for it here\njQuery.each([\"top\", \"left\"], function (i, prop) {\n jQuery.cssHooks[prop] = addGetHookIf(support.pixelPosition,\n function (elem, computed) {\n if (computed) {\n computed = curCSS(elem, prop);\n\n // If curCSS returns percentage, fallback to offset\n return rnumnonpx.test(computed) ?\n jQuery(elem).position()[prop] + \"px\" :\n computed;\n }\n }\n );\n});\n\n\n// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods\njQuery.each({Height: \"height\", Width: \"width\"}, function (name, type) {\n jQuery.each({padding: \"inner\" + name, content: type, \"\": \"outer\" + name},\n function (defaultExtra, funcName) {\n\n // Margin is only for outerHeight, outerWidth\n jQuery.fn[funcName] = function (margin, value) {\n var chainable = arguments.length && (defaultExtra || typeof margin !== \"boolean\"),\n extra = defaultExtra || (margin === true || value === true ? \"margin\" : \"border\");\n\n return access(this, function (elem, type, value) {\n var doc;\n\n if (isWindow(elem)) {\n\n // $( window ).outerWidth/Height return w/h including scrollbars (gh-1729)\n return funcName.indexOf(\"outer\") === 0 ?\n elem[\"inner\" + name] :\n elem.document.documentElement[\"client\" + name];\n }\n\n // Get document width or height\n if (elem.nodeType === 9) {\n doc = elem.documentElement;\n\n // Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height],\n // whichever is greatest\n return Math.max(\n elem.body[\"scroll\" + name], doc[\"scroll\" + name],\n elem.body[\"offset\" + name], doc[\"offset\" + name],\n doc[\"client\" + name]\n );\n }\n\n return value === undefined ?\n\n // Get width or height on the element, requesting but not forcing parseFloat\n jQuery.css(elem, type, extra) :\n\n // Set width or height on the element\n jQuery.style(elem, type, value, extra);\n }, type, chainable ? margin : undefined, chainable);\n };\n });\n});\n\n\njQuery.each((\"blur focus focusin focusout resize scroll click dblclick \" +\n \"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave \" +\n \"change select submit keydown keypress keyup contextmenu\").split(\" \"),\n function (i, name) {\n\n // Handle event binding\n jQuery.fn[name] = function (data, fn) {\n return arguments.length > 0 ?\n this.on(name, null, data, fn) :\n this.trigger(name);\n };\n });\n\njQuery.fn.extend({\n hover: function (fnOver, fnOut) {\n return this.mouseenter(fnOver).mouseleave(fnOut || fnOver);\n }\n});\n\n\njQuery.fn.extend({\n\n bind: function (types, data, fn) {\n return this.on(types, null, data, fn);\n },\n unbind: function (types, fn) {\n return this.off(types, null, fn);\n },\n\n delegate: function (selector, types, data, fn) {\n return this.on(types, selector, data, fn);\n },\n undelegate: function (selector, types, fn) {\n\n // ( namespace ) or ( selector, types [, fn] )\n return arguments.length === 1 ?\n this.off(selector, \"**\") :\n this.off(types, selector || \"**\", fn);\n }\n});\n\n// Bind a function to a context, optionally partially applying any\n// arguments.\n// jQuery.proxy is deprecated to promote standards (specifically Function#bind)\n// However, it is not slated for removal any time soon\njQuery.proxy = function (fn, context) {\n var tmp, args, proxy;\n\n if (typeof context === \"string\") {\n tmp = fn[context];\n context = fn;\n fn = tmp;\n }\n\n // Quick check to determine if target is callable, in the spec\n // this throws a TypeError, but we will just return undefined.\n if (!isFunction(fn)) {\n return undefined;\n }\n\n // Simulated bind\n args = slice.call(arguments, 2);\n proxy = function () {\n return fn.apply(context || this, args.concat(slice.call(arguments)));\n };\n\n // Set the guid of unique handler to the same of original handler, so it can be removed\n proxy.guid = fn.guid = fn.guid || jQuery.guid++;\n\n return proxy;\n};\n\njQuery.holdReady = function (hold) {\n if (hold) {\n jQuery.readyWait++;\n } else {\n jQuery.ready(true);\n }\n};\njQuery.isArray = Array.isArray;\njQuery.parseJSON = JSON.parse;\njQuery.nodeName = nodeName;\njQuery.isFunction = isFunction;\njQuery.isWindow = isWindow;\njQuery.camelCase = camelCase;\njQuery.type = toType;\n\njQuery.now = Date.now;\n\njQuery.isNumeric = function (obj) {\n\n // As of jQuery 3.0, isNumeric is limited to\n // strings and numbers (primitives or objects)\n // that can be coerced to finite numbers (gh-2662)\n var type = jQuery.type(obj);\n return (type === \"number\" || type === \"string\") &&\n\n // parseFloat NaNs numeric-cast false positives (\"\")\n // ...but misinterprets leading-number strings, particularly hex literals (\"0x...\")\n // subtraction forces infinities to NaN\n !isNaN(obj - parseFloat(obj));\n};\n\nconst $$1 = jQuery;\n\nfunction div(options) {\n return create$1(\"div\", options);\n}\n\nfunction create$1(tag, options) {\n const elem = document.createElement(tag);\n if (options) {\n if (options.class) {\n elem.classList.add(options.class);\n }\n if (options.id) {\n elem.id = options.id;\n }\n if(options.style) {\n applyStyle(elem, options.style);\n }\n }\n return elem;\n}\n\nfunction hide(elem) {\n const cssStyle = getComputedStyle(elem);\n if(cssStyle.display !== \"none\") {\n elem._initialDisplay = cssStyle.display;\n }\n elem.style.display = \"none\";\n}\n\nfunction show(elem) {\n const currentDisplay = getComputedStyle(elem).display;\n if (currentDisplay === \"none\") {\n const d = elem._initialDisplay || \"block\";\n elem.style.display = d;\n }\n}\n\nfunction hideAll(selector) {\n document.querySelectorAll(selector).forEach(elem => { hide(elem); });\n}\n\nfunction empty(elem) {\n while(elem.firstChild){\n elem.removeChild(elem.firstChild);\n }\n}\n\nfunction offset(elem) {\n // Return zeros for disconnected and hidden (display: none) elements (gh-2310)\n // Support: IE <=11 only\n // Running getBoundingClientRect on a\n // disconnected node in IE throws an error\n if (!elem.getClientRects().length) {\n return {top: 0, left: 0};\n }\n\n // Get document-relative position by adding viewport scroll to viewport-relative gBCR\n const rect = elem.getBoundingClientRect();\n const win = elem.ownerDocument.defaultView;\n return {\n top: rect.top + win.pageYOffset,\n left: rect.left + win.pageXOffset\n };\n}\n\nfunction pageCoordinates(e) {\n\n if (e.type.startsWith(\"touch\")) {\n const touch = e.touches[0];\n return {x: touch.pageX, y: touch.pageY};\n } else {\n return {x: e.pageX, y: e.pageY}\n }\n}\n\nconst relativeDOMBBox = (parentElement, childElement) => {\n const { x: x_p, y: y_p, width: width_p, height: height_p } = parentElement.getBoundingClientRect();\n const { x: x_c, y: y_c, width: width_c, height: height_c } = childElement.getBoundingClientRect();\n return { x: (x_c - x_p), y: (y_c - y_p), width: width_c, height:height_c };\n};\n\nfunction applyStyle(elem, style) {\n for (let key of Object.keys(style)) {\n elem.style[key] = style[key];\n }\n}\n\nfunction guid$2 () {\n return (\"0000\" + (Math.random() * Math.pow(36, 4) << 0).toString(36)).slice(-4);\n}\n\nlet getMouseXY = (domElement, { clientX, clientY }) => {\n\n // DOMRect object with eight properties: left, top, right, bottom, x, y, width, height\n const { left, top, width, height } = domElement.getBoundingClientRect();\n\n const x = clientX - left;\n const y = clientY - top;\n return { x, y, xNormalized: x/width, yNormalized: y/height, width, height };\n\n};\n\n/**\n * Translate the mouse coordinates for the event to the coordinates for the given target element\n * @param event\n * @param domElement\n * @returns {{x: number, y: number}}\n */\nfunction translateMouseCoordinates(event, domElement) {\n\n const { clientX, clientY } = event;\n return getMouseXY(domElement, { clientX, clientY });\n\n}\n\nvar domUtils = /*#__PURE__*/Object.freeze({\n __proto__: null,\n applyStyle: applyStyle,\n create: create$1,\n div: div,\n empty: empty,\n guid: guid$2,\n hide: hide,\n hideAll: hideAll,\n offset: offset,\n pageCoordinates: pageCoordinates,\n relativeDOMBBox: relativeDOMBBox,\n show: show,\n translateMouseCoordinates: translateMouseCoordinates\n});\n\n/*! @license DOMPurify 3.0.5 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/3.0.5/LICENSE */\n\nconst {\n entries,\n setPrototypeOf,\n isFrozen,\n getPrototypeOf,\n getOwnPropertyDescriptor\n} = Object;\nlet {\n freeze,\n seal,\n create\n} = Object; // eslint-disable-line import/no-mutable-exports\n\nlet {\n apply,\n construct\n} = typeof Reflect !== 'undefined' && Reflect;\n\nif (!apply) {\n apply = function apply(fun, thisValue, args) {\n return fun.apply(thisValue, args);\n };\n}\n\nif (!freeze) {\n freeze = function freeze(x) {\n return x;\n };\n}\n\nif (!seal) {\n seal = function seal(x) {\n return x;\n };\n}\n\nif (!construct) {\n construct = function construct(Func, args) {\n return new Func(...args);\n };\n}\n\nconst arrayForEach = unapply(Array.prototype.forEach);\nconst arrayPop = unapply(Array.prototype.pop);\nconst arrayPush = unapply(Array.prototype.push);\nconst stringToLowerCase = unapply(String.prototype.toLowerCase);\nconst stringToString = unapply(String.prototype.toString);\nconst stringMatch = unapply(String.prototype.match);\nconst stringReplace = unapply(String.prototype.replace);\nconst stringIndexOf = unapply(String.prototype.indexOf);\nconst stringTrim = unapply(String.prototype.trim);\nconst regExpTest = unapply(RegExp.prototype.test);\nconst typeErrorCreate = unconstruct(TypeError);\nfunction unapply(func) {\n return function (thisArg) {\n for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {\n args[_key - 1] = arguments[_key];\n }\n\n return apply(func, thisArg, args);\n };\n}\nfunction unconstruct(func) {\n return function () {\n for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {\n args[_key2] = arguments[_key2];\n }\n\n return construct(func, args);\n };\n}\n/* Add properties to a lookup table */\n\nfunction addToSet(set, array, transformCaseFunc) {\n var _transformCaseFunc;\n\n transformCaseFunc = (_transformCaseFunc = transformCaseFunc) !== null && _transformCaseFunc !== void 0 ? _transformCaseFunc : stringToLowerCase;\n\n if (setPrototypeOf) {\n // Make 'in' and truthy checks like Boolean(set.constructor)\n // independent of any properties defined on Object.prototype.\n // Prevent prototype setters from intercepting set as a this value.\n setPrototypeOf(set, null);\n }\n\n let l = array.length;\n\n while (l--) {\n let element = array[l];\n\n if (typeof element === 'string') {\n const lcElement = transformCaseFunc(element);\n\n if (lcElement !== element) {\n // Config presets (e.g. tags.js, attrs.js) are immutable.\n if (!isFrozen(array)) {\n array[l] = lcElement;\n }\n\n element = lcElement;\n }\n }\n\n set[element] = true;\n }\n\n return set;\n}\n/* Shallow clone an object */\n\nfunction clone(object) {\n const newObject = create(null);\n\n for (const [property, value] of entries(object)) {\n newObject[property] = value;\n }\n\n return newObject;\n}\n/* This method automatically checks if the prop is function\n * or getter and behaves accordingly. */\n\nfunction lookupGetter(object, prop) {\n while (object !== null) {\n const desc = getOwnPropertyDescriptor(object, prop);\n\n if (desc) {\n if (desc.get) {\n return unapply(desc.get);\n }\n\n if (typeof desc.value === 'function') {\n return unapply(desc.value);\n }\n }\n\n object = getPrototypeOf(object);\n }\n\n function fallbackValue(element) {\n console.warn('fallback value for', element);\n return null;\n }\n\n return fallbackValue;\n}\n\nconst html$1 = freeze(['a', 'abbr', 'acronym', 'address', 'area', 'article', 'aside', 'audio', 'b', 'bdi', 'bdo', 'big', 'blink', 'blockquote', 'body', 'br', 'button', 'canvas', 'caption', 'center', 'cite', 'code', 'col', 'colgroup', 'content', 'data', 'datalist', 'dd', 'decorator', 'del', 'details', 'dfn', 'dialog', 'dir', 'div', 'dl', 'dt', 'element', 'em', 'fieldset', 'figcaption', 'figure', 'font', 'footer', 'form', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'header', 'hgroup', 'hr', 'html', 'i', 'img', 'input', 'ins', 'kbd', 'label', 'legend', 'li', 'main', 'map', 'mark', 'marquee', 'menu', 'menuitem', 'meter', 'nav', 'nobr', 'ol', 'optgroup', 'option', 'output', 'p', 'picture', 'pre', 'progress', 'q', 'rp', 'rt', 'ruby', 's', 'samp', 'section', 'select', 'shadow', 'small', 'source', 'spacer', 'span', 'strike', 'strong', 'style', 'sub', 'summary', 'sup', 'table', 'tbody', 'td', 'template', 'textarea', 'tfoot', 'th', 'thead', 'time', 'tr', 'track', 'tt', 'u', 'ul', 'var', 'video', 'wbr']); // SVG\n\nconst svg$1 = freeze(['svg', 'a', 'altglyph', 'altglyphdef', 'altglyphitem', 'animatecolor', 'animatemotion', 'animatetransform', 'circle', 'clippath', 'defs', 'desc', 'ellipse', 'filter', 'font', 'g', 'glyph', 'glyphref', 'hkern', 'image', 'line', 'lineargradient', 'marker', 'mask', 'metadata', 'mpath', 'path', 'pattern', 'polygon', 'polyline', 'radialgradient', 'rect', 'stop', 'style', 'switch', 'symbol', 'text', 'textpath', 'title', 'tref', 'tspan', 'view', 'vkern']);\nconst svgFilters = freeze(['feBlend', 'feColorMatrix', 'feComponentTransfer', 'feComposite', 'feConvolveMatrix', 'feDiffuseLighting', 'feDisplacementMap', 'feDistantLight', 'feDropShadow', 'feFlood', 'feFuncA', 'feFuncB', 'feFuncG', 'feFuncR', 'feGaussianBlur', 'feImage', 'feMerge', 'feMergeNode', 'feMorphology', 'feOffset', 'fePointLight', 'feSpecularLighting', 'feSpotLight', 'feTile', 'feTurbulence']); // List of SVG elements that are disallowed by default.\n// We still need to know them so that we can do namespace\n// checks properly in case one wants to add them to\n// allow-list.\n\nconst svgDisallowed = freeze(['animate', 'color-profile', 'cursor', 'discard', 'font-face', 'font-face-format', 'font-face-name', 'font-face-src', 'font-face-uri', 'foreignobject', 'hatch', 'hatchpath', 'mesh', 'meshgradient', 'meshpatch', 'meshrow', 'missing-glyph', 'script', 'set', 'solidcolor', 'unknown', 'use']);\nconst mathMl$1 = freeze(['math', 'menclose', 'merror', 'mfenced', 'mfrac', 'mglyph', 'mi', 'mlabeledtr', 'mmultiscripts', 'mn', 'mo', 'mover', 'mpadded', 'mphantom', 'mroot', 'mrow', 'ms', 'mspace', 'msqrt', 'mstyle', 'msub', 'msup', 'msubsup', 'mtable', 'mtd', 'mtext', 'mtr', 'munder', 'munderover', 'mprescripts']); // Similarly to SVG, we want to know all MathML elements,\n// even those that we disallow by default.\n\nconst mathMlDisallowed = freeze(['maction', 'maligngroup', 'malignmark', 'mlongdiv', 'mscarries', 'mscarry', 'msgroup', 'mstack', 'msline', 'msrow', 'semantics', 'annotation', 'annotation-xml', 'mprescripts', 'none']);\nconst text = freeze(['#text']);\n\nconst html = freeze(['accept', 'action', 'align', 'alt', 'autocapitalize', 'autocomplete', 'autopictureinpicture', 'autoplay', 'background', 'bgcolor', 'border', 'capture', 'cellpadding', 'cellspacing', 'checked', 'cite', 'class', 'clear', 'color', 'cols', 'colspan', 'controls', 'controlslist', 'coords', 'crossorigin', 'datetime', 'decoding', 'default', 'dir', 'disabled', 'disablepictureinpicture', 'disableremoteplayback', 'download', 'draggable', 'enctype', 'enterkeyhint', 'face', 'for', 'headers', 'height', 'hidden', 'high', 'href', 'hreflang', 'id', 'inputmode', 'integrity', 'ismap', 'kind', 'label', 'lang', 'list', 'loading', 'loop', 'low', 'max', 'maxlength', 'media', 'method', 'min', 'minlength', 'multiple', 'muted', 'name', 'nonce', 'noshade', 'novalidate', 'nowrap', 'open', 'optimum', 'pattern', 'placeholder', 'playsinline', 'poster', 'preload', 'pubdate', 'radiogroup', 'readonly', 'rel', 'required', 'rev', 'reversed', 'role', 'rows', 'rowspan', 'spellcheck', 'scope', 'selected', 'shape', 'size', 'sizes', 'span', 'srclang', 'start', 'src', 'srcset', 'step', 'style', 'summary', 'tabindex', 'title', 'translate', 'type', 'usemap', 'valign', 'value', 'width', 'xmlns', 'slot']);\nconst svg = freeze(['accent-height', 'accumulate', 'additive', 'alignment-baseline', 'ascent', 'attributename', 'attributetype', 'azimuth', 'basefrequency', 'baseline-shift', 'begin', 'bias', 'by', 'class', 'clip', 'clippathunits', 'clip-path', 'clip-rule', 'color', 'color-interpolation', 'color-interpolation-filters', 'color-profile', 'color-rendering', 'cx', 'cy', 'd', 'dx', 'dy', 'diffuseconstant', 'direction', 'display', 'divisor', 'dur', 'edgemode', 'elevation', 'end', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'filterunits', 'flood-color', 'flood-opacity', 'font-family', 'font-size', 'font-size-adjust', 'font-stretch', 'font-style', 'font-variant', 'font-weight', 'fx', 'fy', 'g1', 'g2', 'glyph-name', 'glyphref', 'gradientunits', 'gradienttransform', 'height', 'href', 'id', 'image-rendering', 'in', 'in2', 'k', 'k1', 'k2', 'k3', 'k4', 'kerning', 'keypoints', 'keysplines', 'keytimes', 'lang', 'lengthadjust', 'letter-spacing', 'kernelmatrix', 'kernelunitlength', 'lighting-color', 'local', 'marker-end', 'marker-mid', 'marker-start', 'markerheight', 'markerunits', 'markerwidth', 'maskcontentunits', 'maskunits', 'max', 'mask', 'media', 'method', 'mode', 'min', 'name', 'numoctaves', 'offset', 'operator', 'opacity', 'order', 'orient', 'orientation', 'origin', 'overflow', 'paint-order', 'path', 'pathlength', 'patterncontentunits', 'patterntransform', 'patternunits', 'points', 'preservealpha', 'preserveaspectratio', 'primitiveunits', 'r', 'rx', 'ry', 'radius', 'refx', 'refy', 'repeatcount', 'repeatdur', 'restart', 'result', 'rotate', 'scale', 'seed', 'shape-rendering', 'specularconstant', 'specularexponent', 'spreadmethod', 'startoffset', 'stddeviation', 'stitchtiles', 'stop-color', 'stop-opacity', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke', 'stroke-width', 'style', 'surfacescale', 'systemlanguage', 'tabindex', 'targetx', 'targety', 'transform', 'transform-origin', 'text-anchor', 'text-decoration', 'text-rendering', 'textlength', 'type', 'u1', 'u2', 'unicode', 'values', 'viewbox', 'visibility', 'version', 'vert-adv-y', 'vert-origin-x', 'vert-origin-y', 'width', 'word-spacing', 'wrap', 'writing-mode', 'xchannelselector', 'ychannelselector', 'x', 'x1', 'x2', 'xmlns', 'y', 'y1', 'y2', 'z', 'zoomandpan']);\nconst mathMl = freeze(['accent', 'accentunder', 'align', 'bevelled', 'close', 'columnsalign', 'columnlines', 'columnspan', 'denomalign', 'depth', 'dir', 'display', 'displaystyle', 'encoding', 'fence', 'frame', 'height', 'href', 'id', 'largeop', 'length', 'linethickness', 'lspace', 'lquote', 'mathbackground', 'mathcolor', 'mathsize', 'mathvariant', 'maxsize', 'minsize', 'movablelimits', 'notation', 'numalign', 'open', 'rowalign', 'rowlines', 'rowspacing', 'rowspan', 'rspace', 'rquote', 'scriptlevel', 'scriptminsize', 'scriptsizemultiplier', 'selection', 'separator', 'separators', 'stretchy', 'subscriptshift', 'supscriptshift', 'symmetric', 'voffset', 'width', 'xmlns']);\nconst xml = freeze(['xlink:href', 'xml:id', 'xlink:title', 'xml:space', 'xmlns:xlink']);\n\nconst MUSTACHE_EXPR = seal(/\\{\\{[\\w\\W]*|[\\w\\W]*\\}\\}/gm); // Specify template detection regex for SAFE_FOR_TEMPLATES mode\n\nconst ERB_EXPR = seal(/<%[\\w\\W]*|[\\w\\W]*%>/gm);\nconst TMPLIT_EXPR = seal(/\\${[\\w\\W]*}/gm);\nconst DATA_ATTR = seal(/^data-[\\-\\w.\\u00B7-\\uFFFF]/); // eslint-disable-line no-useless-escape\n\nconst ARIA_ATTR = seal(/^aria-[\\-\\w]+$/); // eslint-disable-line no-useless-escape\n\nconst IS_ALLOWED_URI = seal(/^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp):|[^a-z]|[a-z+.\\-]+(?:[^a-z+.\\-:]|$))/i // eslint-disable-line no-useless-escape\n);\nconst IS_SCRIPT_OR_DATA = seal(/^(?:\\w+script|data):/i);\nconst ATTR_WHITESPACE = seal(/[\\u0000-\\u0020\\u00A0\\u1680\\u180E\\u2000-\\u2029\\u205F\\u3000]/g // eslint-disable-line no-control-regex\n);\nconst DOCTYPE_NAME = seal(/^html$/i);\n\nvar EXPRESSIONS = /*#__PURE__*/Object.freeze({\n __proto__: null,\n MUSTACHE_EXPR: MUSTACHE_EXPR,\n ERB_EXPR: ERB_EXPR,\n TMPLIT_EXPR: TMPLIT_EXPR,\n DATA_ATTR: DATA_ATTR,\n ARIA_ATTR: ARIA_ATTR,\n IS_ALLOWED_URI: IS_ALLOWED_URI,\n IS_SCRIPT_OR_DATA: IS_SCRIPT_OR_DATA,\n ATTR_WHITESPACE: ATTR_WHITESPACE,\n DOCTYPE_NAME: DOCTYPE_NAME\n});\n\nconst getGlobal = () => typeof window === 'undefined' ? null : window;\n/**\n * Creates a no-op policy for internal use only.\n * Don't export this function outside this module!\n * @param {?TrustedTypePolicyFactory} trustedTypes The policy factory.\n * @param {HTMLScriptElement} purifyHostElement The Script element used to load DOMPurify (to determine policy name suffix).\n * @return {?TrustedTypePolicy} The policy created (or null, if Trusted Types\n * are not supported or creating the policy failed).\n */\n\n\nconst _createTrustedTypesPolicy = function _createTrustedTypesPolicy(trustedTypes, purifyHostElement) {\n if (typeof trustedTypes !== 'object' || typeof trustedTypes.createPolicy !== 'function') {\n return null;\n } // Allow the callers to control the unique policy name\n // by adding a data-tt-policy-suffix to the script element with the DOMPurify.\n // Policy creation with duplicate names throws in Trusted Types.\n\n\n let suffix = null;\n const ATTR_NAME = 'data-tt-policy-suffix';\n\n if (purifyHostElement && purifyHostElement.hasAttribute(ATTR_NAME)) {\n suffix = purifyHostElement.getAttribute(ATTR_NAME);\n }\n\n const policyName = 'dompurify' + (suffix ? '#' + suffix : '');\n\n try {\n return trustedTypes.createPolicy(policyName, {\n createHTML(html) {\n return html;\n },\n\n createScriptURL(scriptUrl) {\n return scriptUrl;\n }\n\n });\n } catch (_) {\n // Policy creation failed (most likely another DOMPurify script has\n // already run). Skip creating the policy, as this will only cause errors\n // if TT are enforced.\n console.warn('TrustedTypes policy ' + policyName + ' could not be created.');\n return null;\n }\n};\n\nfunction createDOMPurify() {\n let window = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : getGlobal();\n\n const DOMPurify = root => createDOMPurify(root);\n /**\n * Version label, exposed for easier checks\n * if DOMPurify is up to date or not\n */\n\n\n DOMPurify.version = '3.0.5';\n /**\n * Array of elements that DOMPurify removed during sanitation.\n * Empty if nothing was removed.\n */\n\n DOMPurify.removed = [];\n\n if (!window || !window.document || window.document.nodeType !== 9) {\n // Not running in a browser, provide a factory function\n // so that you can pass your own Window\n DOMPurify.isSupported = false;\n return DOMPurify;\n }\n\n const originalDocument = window.document;\n const currentScript = originalDocument.currentScript;\n let {\n document\n } = window;\n const {\n DocumentFragment,\n HTMLTemplateElement,\n Node,\n Element,\n NodeFilter,\n NamedNodeMap = window.NamedNodeMap || window.MozNamedAttrMap,\n HTMLFormElement,\n DOMParser,\n trustedTypes\n } = window;\n const ElementPrototype = Element.prototype;\n const cloneNode = lookupGetter(ElementPrototype, 'cloneNode');\n const getNextSibling = lookupGetter(ElementPrototype, 'nextSibling');\n const getChildNodes = lookupGetter(ElementPrototype, 'childNodes');\n const getParentNode = lookupGetter(ElementPrototype, 'parentNode'); // As per issue #47, the web-components registry is inherited by a\n // new document created via createHTMLDocument. As per the spec\n // (http://w3c.github.io/webcomponents/spec/custom/#creating-and-passing-registries)\n // a new empty registry is used when creating a template contents owner\n // document, so we use that as our parent document to ensure nothing\n // is inherited.\n\n if (typeof HTMLTemplateElement === 'function') {\n const template = document.createElement('template');\n\n if (template.content && template.content.ownerDocument) {\n document = template.content.ownerDocument;\n }\n }\n\n let trustedTypesPolicy;\n let emptyHTML = '';\n const {\n implementation,\n createNodeIterator,\n createDocumentFragment,\n getElementsByTagName\n } = document;\n const {\n importNode\n } = originalDocument;\n let hooks = {};\n /**\n * Expose whether this browser supports running the full DOMPurify.\n */\n\n DOMPurify.isSupported = typeof entries === 'function' && typeof getParentNode === 'function' && implementation && implementation.createHTMLDocument !== undefined;\n const {\n MUSTACHE_EXPR,\n ERB_EXPR,\n TMPLIT_EXPR,\n DATA_ATTR,\n ARIA_ATTR,\n IS_SCRIPT_OR_DATA,\n ATTR_WHITESPACE\n } = EXPRESSIONS;\n let {\n IS_ALLOWED_URI: IS_ALLOWED_URI$1\n } = EXPRESSIONS;\n /**\n * We consider the elements and attributes below to be safe. Ideally\n * don't add any new ones but feel free to remove unwanted ones.\n */\n\n /* allowed element names */\n\n let ALLOWED_TAGS = null;\n const DEFAULT_ALLOWED_TAGS = addToSet({}, [...html$1, ...svg$1, ...svgFilters, ...mathMl$1, ...text]);\n /* Allowed attribute names */\n\n let ALLOWED_ATTR = null;\n const DEFAULT_ALLOWED_ATTR = addToSet({}, [...html, ...svg, ...mathMl, ...xml]);\n /*\n * Configure how DOMPUrify should handle custom elements and their attributes as well as customized built-in elements.\n * @property {RegExp|Function|null} tagNameCheck one of [null, regexPattern, predicate]. Default: `null` (disallow any custom elements)\n * @property {RegExp|Function|null} attributeNameCheck one of [null, regexPattern, predicate]. Default: `null` (disallow any attributes not on the allow list)\n * @property {boolean} allowCustomizedBuiltInElements allow custom elements derived from built-ins if they pass CUSTOM_ELEMENT_HANDLING.tagNameCheck. Default: `false`.\n */\n\n let CUSTOM_ELEMENT_HANDLING = Object.seal(Object.create(null, {\n tagNameCheck: {\n writable: true,\n configurable: false,\n enumerable: true,\n value: null\n },\n attributeNameCheck: {\n writable: true,\n configurable: false,\n enumerable: true,\n value: null\n },\n allowCustomizedBuiltInElements: {\n writable: true,\n configurable: false,\n enumerable: true,\n value: false\n }\n }));\n /* Explicitly forbidden tags (overrides ALLOWED_TAGS/ADD_TAGS) */\n\n let FORBID_TAGS = null;\n /* Explicitly forbidden attributes (overrides ALLOWED_ATTR/ADD_ATTR) */\n\n let FORBID_ATTR = null;\n /* Decide if ARIA attributes are okay */\n\n let ALLOW_ARIA_ATTR = true;\n /* Decide if custom data attributes are okay */\n\n let ALLOW_DATA_ATTR = true;\n /* Decide if unknown protocols are okay */\n\n let ALLOW_UNKNOWN_PROTOCOLS = false;\n /* Decide if self-closing tags in attributes are allowed.\n * Usually removed due to a mXSS issue in jQuery 3.0 */\n\n let ALLOW_SELF_CLOSE_IN_ATTR = true;\n /* Output should be safe for common template engines.\n * This means, DOMPurify removes data attributes, mustaches and ERB\n */\n\n let SAFE_FOR_TEMPLATES = false;\n /* Decide if document with ... should be returned */\n\n let WHOLE_DOCUMENT = false;\n /* Track whether config is already set on this instance of DOMPurify. */\n\n let SET_CONFIG = false;\n /* Decide if all elements (e.g. style, script) must be children of\n * document.body. By default, browsers might move them to document.head */\n\n let FORCE_BODY = false;\n /* Decide if a DOM `HTMLBodyElement` should be returned, instead of a html\n * string (or a TrustedHTML object if Trusted Types are supported).\n * If `WHOLE_DOCUMENT` is enabled a `HTMLHtmlElement` will be returned instead\n */\n\n let RETURN_DOM = false;\n /* Decide if a DOM `DocumentFragment` should be returned, instead of a html\n * string (or a TrustedHTML object if Trusted Types are supported) */\n\n let RETURN_DOM_FRAGMENT = false;\n /* Try to return a Trusted Type object instead of a string, return a string in\n * case Trusted Types are not supported */\n\n let RETURN_TRUSTED_TYPE = false;\n /* Output should be free from DOM clobbering attacks?\n * This sanitizes markups named with colliding, clobberable built-in DOM APIs.\n */\n\n let SANITIZE_DOM = true;\n /* Achieve full DOM Clobbering protection by isolating the namespace of named\n * properties and JS variables, mitigating attacks that abuse the HTML/DOM spec rules.\n *\n * HTML/DOM spec rules that enable DOM Clobbering:\n * - Named Access on Window (§7.3.3)\n * - DOM Tree Accessors (§3.1.5)\n * - Form Element Parent-Child Relations (§4.10.3)\n * - Iframe srcdoc / Nested WindowProxies (§4.8.5)\n * - HTMLCollection (§4.2.10.2)\n *\n * Namespace isolation is implemented by prefixing `id` and `name` attributes\n * with a constant string, i.e., `user-content-`\n */\n\n let SANITIZE_NAMED_PROPS = false;\n const SANITIZE_NAMED_PROPS_PREFIX = 'user-content-';\n /* Keep element content when removing element? */\n\n let KEEP_CONTENT = true;\n /* If a `Node` is passed to sanitize(), then performs sanitization in-place instead\n * of importing it into a new Document and returning a sanitized copy */\n\n let IN_PLACE = false;\n /* Allow usage of profiles like html, svg and mathMl */\n\n let USE_PROFILES = {};\n /* Tags to ignore content of when KEEP_CONTENT is true */\n\n let FORBID_CONTENTS = null;\n const DEFAULT_FORBID_CONTENTS = addToSet({}, ['annotation-xml', 'audio', 'colgroup', 'desc', 'foreignobject', 'head', 'iframe', 'math', 'mi', 'mn', 'mo', 'ms', 'mtext', 'noembed', 'noframes', 'noscript', 'plaintext', 'script', 'style', 'svg', 'template', 'thead', 'title', 'video', 'xmp']);\n /* Tags that are safe for data: URIs */\n\n let DATA_URI_TAGS = null;\n const DEFAULT_DATA_URI_TAGS = addToSet({}, ['audio', 'video', 'img', 'source', 'image', 'track']);\n /* Attributes safe for values like \"javascript:\" */\n\n let URI_SAFE_ATTRIBUTES = null;\n const DEFAULT_URI_SAFE_ATTRIBUTES = addToSet({}, ['alt', 'class', 'for', 'id', 'label', 'name', 'pattern', 'placeholder', 'role', 'summary', 'title', 'value', 'style', 'xmlns']);\n const MATHML_NAMESPACE = 'http://www.w3.org/1998/Math/MathML';\n const SVG_NAMESPACE = 'http://www.w3.org/2000/svg';\n const HTML_NAMESPACE = 'http://www.w3.org/1999/xhtml';\n /* Document namespace */\n\n let NAMESPACE = HTML_NAMESPACE;\n let IS_EMPTY_INPUT = false;\n /* Allowed XHTML+XML namespaces */\n\n let ALLOWED_NAMESPACES = null;\n const DEFAULT_ALLOWED_NAMESPACES = addToSet({}, [MATHML_NAMESPACE, SVG_NAMESPACE, HTML_NAMESPACE], stringToString);\n /* Parsing of strict XHTML documents */\n\n let PARSER_MEDIA_TYPE;\n const SUPPORTED_PARSER_MEDIA_TYPES = ['application/xhtml+xml', 'text/html'];\n const DEFAULT_PARSER_MEDIA_TYPE = 'text/html';\n let transformCaseFunc;\n /* Keep a reference to config to pass to hooks */\n\n let CONFIG = null;\n /* Ideally, do not touch anything below this line */\n\n /* ______________________________________________ */\n\n const formElement = document.createElement('form');\n\n const isRegexOrFunction = function isRegexOrFunction(testValue) {\n return testValue instanceof RegExp || testValue instanceof Function;\n };\n /**\n * _parseConfig\n *\n * @param {Object} cfg optional config literal\n */\n // eslint-disable-next-line complexity\n\n\n const _parseConfig = function _parseConfig(cfg) {\n if (CONFIG && CONFIG === cfg) {\n return;\n }\n /* Shield configuration object from tampering */\n\n\n if (!cfg || typeof cfg !== 'object') {\n cfg = {};\n }\n /* Shield configuration object from prototype pollution */\n\n\n cfg = clone(cfg);\n PARSER_MEDIA_TYPE = // eslint-disable-next-line unicorn/prefer-includes\n SUPPORTED_PARSER_MEDIA_TYPES.indexOf(cfg.PARSER_MEDIA_TYPE) === -1 ? PARSER_MEDIA_TYPE = DEFAULT_PARSER_MEDIA_TYPE : PARSER_MEDIA_TYPE = cfg.PARSER_MEDIA_TYPE; // HTML tags and attributes are not case-sensitive, converting to lowercase. Keeping XHTML as is.\n\n transformCaseFunc = PARSER_MEDIA_TYPE === 'application/xhtml+xml' ? stringToString : stringToLowerCase;\n /* Set configuration parameters */\n\n ALLOWED_TAGS = 'ALLOWED_TAGS' in cfg ? addToSet({}, cfg.ALLOWED_TAGS, transformCaseFunc) : DEFAULT_ALLOWED_TAGS;\n ALLOWED_ATTR = 'ALLOWED_ATTR' in cfg ? addToSet({}, cfg.ALLOWED_ATTR, transformCaseFunc) : DEFAULT_ALLOWED_ATTR;\n ALLOWED_NAMESPACES = 'ALLOWED_NAMESPACES' in cfg ? addToSet({}, cfg.ALLOWED_NAMESPACES, stringToString) : DEFAULT_ALLOWED_NAMESPACES;\n URI_SAFE_ATTRIBUTES = 'ADD_URI_SAFE_ATTR' in cfg ? addToSet(clone(DEFAULT_URI_SAFE_ATTRIBUTES), // eslint-disable-line indent\n cfg.ADD_URI_SAFE_ATTR, // eslint-disable-line indent\n transformCaseFunc // eslint-disable-line indent\n ) // eslint-disable-line indent\n : DEFAULT_URI_SAFE_ATTRIBUTES;\n DATA_URI_TAGS = 'ADD_DATA_URI_TAGS' in cfg ? addToSet(clone(DEFAULT_DATA_URI_TAGS), // eslint-disable-line indent\n cfg.ADD_DATA_URI_TAGS, // eslint-disable-line indent\n transformCaseFunc // eslint-disable-line indent\n ) // eslint-disable-line indent\n : DEFAULT_DATA_URI_TAGS;\n FORBID_CONTENTS = 'FORBID_CONTENTS' in cfg ? addToSet({}, cfg.FORBID_CONTENTS, transformCaseFunc) : DEFAULT_FORBID_CONTENTS;\n FORBID_TAGS = 'FORBID_TAGS' in cfg ? addToSet({}, cfg.FORBID_TAGS, transformCaseFunc) : {};\n FORBID_ATTR = 'FORBID_ATTR' in cfg ? addToSet({}, cfg.FORBID_ATTR, transformCaseFunc) : {};\n USE_PROFILES = 'USE_PROFILES' in cfg ? cfg.USE_PROFILES : false;\n ALLOW_ARIA_ATTR = cfg.ALLOW_ARIA_ATTR !== false; // Default true\n\n ALLOW_DATA_ATTR = cfg.ALLOW_DATA_ATTR !== false; // Default true\n\n ALLOW_UNKNOWN_PROTOCOLS = cfg.ALLOW_UNKNOWN_PROTOCOLS || false; // Default false\n\n ALLOW_SELF_CLOSE_IN_ATTR = cfg.ALLOW_SELF_CLOSE_IN_ATTR !== false; // Default true\n\n SAFE_FOR_TEMPLATES = cfg.SAFE_FOR_TEMPLATES || false; // Default false\n\n WHOLE_DOCUMENT = cfg.WHOLE_DOCUMENT || false; // Default false\n\n RETURN_DOM = cfg.RETURN_DOM || false; // Default false\n\n RETURN_DOM_FRAGMENT = cfg.RETURN_DOM_FRAGMENT || false; // Default false\n\n RETURN_TRUSTED_TYPE = cfg.RETURN_TRUSTED_TYPE || false; // Default false\n\n FORCE_BODY = cfg.FORCE_BODY || false; // Default false\n\n SANITIZE_DOM = cfg.SANITIZE_DOM !== false; // Default true\n\n SANITIZE_NAMED_PROPS = cfg.SANITIZE_NAMED_PROPS || false; // Default false\n\n KEEP_CONTENT = cfg.KEEP_CONTENT !== false; // Default true\n\n IN_PLACE = cfg.IN_PLACE || false; // Default false\n\n IS_ALLOWED_URI$1 = cfg.ALLOWED_URI_REGEXP || IS_ALLOWED_URI;\n NAMESPACE = cfg.NAMESPACE || HTML_NAMESPACE;\n CUSTOM_ELEMENT_HANDLING = cfg.CUSTOM_ELEMENT_HANDLING || {};\n\n if (cfg.CUSTOM_ELEMENT_HANDLING && isRegexOrFunction(cfg.CUSTOM_ELEMENT_HANDLING.tagNameCheck)) {\n CUSTOM_ELEMENT_HANDLING.tagNameCheck = cfg.CUSTOM_ELEMENT_HANDLING.tagNameCheck;\n }\n\n if (cfg.CUSTOM_ELEMENT_HANDLING && isRegexOrFunction(cfg.CUSTOM_ELEMENT_HANDLING.attributeNameCheck)) {\n CUSTOM_ELEMENT_HANDLING.attributeNameCheck = cfg.CUSTOM_ELEMENT_HANDLING.attributeNameCheck;\n }\n\n if (cfg.CUSTOM_ELEMENT_HANDLING && typeof cfg.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements === 'boolean') {\n CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements = cfg.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements;\n }\n\n if (SAFE_FOR_TEMPLATES) {\n ALLOW_DATA_ATTR = false;\n }\n\n if (RETURN_DOM_FRAGMENT) {\n RETURN_DOM = true;\n }\n /* Parse profile info */\n\n\n if (USE_PROFILES) {\n ALLOWED_TAGS = addToSet({}, [...text]);\n ALLOWED_ATTR = [];\n\n if (USE_PROFILES.html === true) {\n addToSet(ALLOWED_TAGS, html$1);\n addToSet(ALLOWED_ATTR, html);\n }\n\n if (USE_PROFILES.svg === true) {\n addToSet(ALLOWED_TAGS, svg$1);\n addToSet(ALLOWED_ATTR, svg);\n addToSet(ALLOWED_ATTR, xml);\n }\n\n if (USE_PROFILES.svgFilters === true) {\n addToSet(ALLOWED_TAGS, svgFilters);\n addToSet(ALLOWED_ATTR, svg);\n addToSet(ALLOWED_ATTR, xml);\n }\n\n if (USE_PROFILES.mathMl === true) {\n addToSet(ALLOWED_TAGS, mathMl$1);\n addToSet(ALLOWED_ATTR, mathMl);\n addToSet(ALLOWED_ATTR, xml);\n }\n }\n /* Merge configuration parameters */\n\n\n if (cfg.ADD_TAGS) {\n if (ALLOWED_TAGS === DEFAULT_ALLOWED_TAGS) {\n ALLOWED_TAGS = clone(ALLOWED_TAGS);\n }\n\n addToSet(ALLOWED_TAGS, cfg.ADD_TAGS, transformCaseFunc);\n }\n\n if (cfg.ADD_ATTR) {\n if (ALLOWED_ATTR === DEFAULT_ALLOWED_ATTR) {\n ALLOWED_ATTR = clone(ALLOWED_ATTR);\n }\n\n addToSet(ALLOWED_ATTR, cfg.ADD_ATTR, transformCaseFunc);\n }\n\n if (cfg.ADD_URI_SAFE_ATTR) {\n addToSet(URI_SAFE_ATTRIBUTES, cfg.ADD_URI_SAFE_ATTR, transformCaseFunc);\n }\n\n if (cfg.FORBID_CONTENTS) {\n if (FORBID_CONTENTS === DEFAULT_FORBID_CONTENTS) {\n FORBID_CONTENTS = clone(FORBID_CONTENTS);\n }\n\n addToSet(FORBID_CONTENTS, cfg.FORBID_CONTENTS, transformCaseFunc);\n }\n /* Add #text in case KEEP_CONTENT is set to true */\n\n\n if (KEEP_CONTENT) {\n ALLOWED_TAGS['#text'] = true;\n }\n /* Add html, head and body to ALLOWED_TAGS in case WHOLE_DOCUMENT is true */\n\n\n if (WHOLE_DOCUMENT) {\n addToSet(ALLOWED_TAGS, ['html', 'head', 'body']);\n }\n /* Add tbody to ALLOWED_TAGS in case tables are permitted, see #286, #365 */\n\n\n if (ALLOWED_TAGS.table) {\n addToSet(ALLOWED_TAGS, ['tbody']);\n delete FORBID_TAGS.tbody;\n }\n\n if (cfg.TRUSTED_TYPES_POLICY) {\n if (typeof cfg.TRUSTED_TYPES_POLICY.createHTML !== 'function') {\n throw typeErrorCreate('TRUSTED_TYPES_POLICY configuration option must provide a \"createHTML\" hook.');\n }\n\n if (typeof cfg.TRUSTED_TYPES_POLICY.createScriptURL !== 'function') {\n throw typeErrorCreate('TRUSTED_TYPES_POLICY configuration option must provide a \"createScriptURL\" hook.');\n } // Overwrite existing TrustedTypes policy.\n\n\n trustedTypesPolicy = cfg.TRUSTED_TYPES_POLICY; // Sign local variables required by `sanitize`.\n\n emptyHTML = trustedTypesPolicy.createHTML('');\n } else {\n // Uninitialized policy, attempt to initialize the internal dompurify policy.\n if (trustedTypesPolicy === undefined) {\n trustedTypesPolicy = _createTrustedTypesPolicy(trustedTypes, currentScript);\n } // If creating the internal policy succeeded sign internal variables.\n\n\n if (trustedTypesPolicy !== null && typeof emptyHTML === 'string') {\n emptyHTML = trustedTypesPolicy.createHTML('');\n }\n } // Prevent further manipulation of configuration.\n // Not available in IE8, Safari 5, etc.\n\n\n if (freeze) {\n freeze(cfg);\n }\n\n CONFIG = cfg;\n };\n\n const MATHML_TEXT_INTEGRATION_POINTS = addToSet({}, ['mi', 'mo', 'mn', 'ms', 'mtext']);\n const HTML_INTEGRATION_POINTS = addToSet({}, ['foreignobject', 'desc', 'title', 'annotation-xml']); // Certain elements are allowed in both SVG and HTML\n // namespace. We need to specify them explicitly\n // so that they don't get erroneously deleted from\n // HTML namespace.\n\n const COMMON_SVG_AND_HTML_ELEMENTS = addToSet({}, ['title', 'style', 'font', 'a', 'script']);\n /* Keep track of all possible SVG and MathML tags\n * so that we can perform the namespace checks\n * correctly. */\n\n const ALL_SVG_TAGS = addToSet({}, svg$1);\n addToSet(ALL_SVG_TAGS, svgFilters);\n addToSet(ALL_SVG_TAGS, svgDisallowed);\n const ALL_MATHML_TAGS = addToSet({}, mathMl$1);\n addToSet(ALL_MATHML_TAGS, mathMlDisallowed);\n /**\n *\n *\n * @param {Element} element a DOM element whose namespace is being checked\n * @returns {boolean} Return false if the element has a\n * namespace that a spec-compliant parser would never\n * return. Return true otherwise.\n */\n\n const _checkValidNamespace = function _checkValidNamespace(element) {\n let parent = getParentNode(element); // In JSDOM, if we're inside shadow DOM, then parentNode\n // can be null. We just simulate parent in this case.\n\n if (!parent || !parent.tagName) {\n parent = {\n namespaceURI: NAMESPACE,\n tagName: 'template'\n };\n }\n\n const tagName = stringToLowerCase(element.tagName);\n const parentTagName = stringToLowerCase(parent.tagName);\n\n if (!ALLOWED_NAMESPACES[element.namespaceURI]) {\n return false;\n }\n\n if (element.namespaceURI === SVG_NAMESPACE) {\n // The only way to switch from HTML namespace to SVG\n // is via . If it happens via any other tag, then\n // it should be killed.\n if (parent.namespaceURI === HTML_NAMESPACE) {\n return tagName === 'svg';\n } // The only way to switch from MathML to SVG is via`\n // svg if parent is either or MathML\n // text integration points.\n\n\n if (parent.namespaceURI === MATHML_NAMESPACE) {\n return tagName === 'svg' && (parentTagName === 'annotation-xml' || MATHML_TEXT_INTEGRATION_POINTS[parentTagName]);\n } // We only allow elements that are defined in SVG\n // spec. All others are disallowed in SVG namespace.\n\n\n return Boolean(ALL_SVG_TAGS[tagName]);\n }\n\n if (element.namespaceURI === MATHML_NAMESPACE) {\n // The only way to switch from HTML namespace to MathML\n // is via . If it happens via any other tag, then\n // it should be killed.\n if (parent.namespaceURI === HTML_NAMESPACE) {\n return tagName === 'math';\n } // The only way to switch from SVG to MathML is via\n // and HTML integration points\n\n\n if (parent.namespaceURI === SVG_NAMESPACE) {\n return tagName === 'math' && HTML_INTEGRATION_POINTS[parentTagName];\n } // We only allow elements that are defined in MathML\n // spec. All others are disallowed in MathML namespace.\n\n\n return Boolean(ALL_MATHML_TAGS[tagName]);\n }\n\n if (element.namespaceURI === HTML_NAMESPACE) {\n // The only way to switch from SVG to HTML is via\n // HTML integration points, and from MathML to HTML\n // is via MathML text integration points\n if (parent.namespaceURI === SVG_NAMESPACE && !HTML_INTEGRATION_POINTS[parentTagName]) {\n return false;\n }\n\n if (parent.namespaceURI === MATHML_NAMESPACE && !MATHML_TEXT_INTEGRATION_POINTS[parentTagName]) {\n return false;\n } // We disallow tags that are specific for MathML\n // or SVG and should never appear in HTML namespace\n\n\n return !ALL_MATHML_TAGS[tagName] && (COMMON_SVG_AND_HTML_ELEMENTS[tagName] || !ALL_SVG_TAGS[tagName]);\n } // For XHTML and XML documents that support custom namespaces\n\n\n if (PARSER_MEDIA_TYPE === 'application/xhtml+xml' && ALLOWED_NAMESPACES[element.namespaceURI]) {\n return true;\n } // The code should never reach this place (this means\n // that the element somehow got namespace that is not\n // HTML, SVG, MathML or allowed via ALLOWED_NAMESPACES).\n // Return false just in case.\n\n\n return false;\n };\n /**\n * _forceRemove\n *\n * @param {Node} node a DOM node\n */\n\n\n const _forceRemove = function _forceRemove(node) {\n arrayPush(DOMPurify.removed, {\n element: node\n });\n\n try {\n // eslint-disable-next-line unicorn/prefer-dom-node-remove\n node.parentNode.removeChild(node);\n } catch (_) {\n node.remove();\n }\n };\n /**\n * _removeAttribute\n *\n * @param {String} name an Attribute name\n * @param {Node} node a DOM node\n */\n\n\n const _removeAttribute = function _removeAttribute(name, node) {\n try {\n arrayPush(DOMPurify.removed, {\n attribute: node.getAttributeNode(name),\n from: node\n });\n } catch (_) {\n arrayPush(DOMPurify.removed, {\n attribute: null,\n from: node\n });\n }\n\n node.removeAttribute(name); // We void attribute values for unremovable \"is\"\" attributes\n\n if (name === 'is' && !ALLOWED_ATTR[name]) {\n if (RETURN_DOM || RETURN_DOM_FRAGMENT) {\n try {\n _forceRemove(node);\n } catch (_) {}\n } else {\n try {\n node.setAttribute(name, '');\n } catch (_) {}\n }\n }\n };\n /**\n * _initDocument\n *\n * @param {String} dirty a string of dirty markup\n * @return {Document} a DOM, filled with the dirty markup\n */\n\n\n const _initDocument = function _initDocument(dirty) {\n /* Create a HTML document */\n let doc;\n let leadingWhitespace;\n\n if (FORCE_BODY) {\n dirty = '' + dirty;\n } else {\n /* If FORCE_BODY isn't used, leading whitespace needs to be preserved manually */\n const matches = stringMatch(dirty, /^[\\r\\n\\t ]+/);\n leadingWhitespace = matches && matches[0];\n }\n\n if (PARSER_MEDIA_TYPE === 'application/xhtml+xml' && NAMESPACE === HTML_NAMESPACE) {\n // Root of XHTML doc must contain xmlns declaration (see https://www.w3.org/TR/xhtml1/normative.html#strict)\n dirty = '' + dirty + '';\n }\n\n const dirtyPayload = trustedTypesPolicy ? trustedTypesPolicy.createHTML(dirty) : dirty;\n /*\n * Use the DOMParser API by default, fallback later if needs be\n * DOMParser not work for svg when has multiple root element.\n */\n\n if (NAMESPACE === HTML_NAMESPACE) {\n try {\n doc = new DOMParser().parseFromString(dirtyPayload, PARSER_MEDIA_TYPE);\n } catch (_) {}\n }\n /* Use createHTMLDocument in case DOMParser is not available */\n\n\n if (!doc || !doc.documentElement) {\n doc = implementation.createDocument(NAMESPACE, 'template', null);\n\n try {\n doc.documentElement.innerHTML = IS_EMPTY_INPUT ? emptyHTML : dirtyPayload;\n } catch (_) {// Syntax error if dirtyPayload is invalid xml\n }\n }\n\n const body = doc.body || doc.documentElement;\n\n if (dirty && leadingWhitespace) {\n body.insertBefore(document.createTextNode(leadingWhitespace), body.childNodes[0] || null);\n }\n /* Work on whole document or just its body */\n\n\n if (NAMESPACE === HTML_NAMESPACE) {\n return getElementsByTagName.call(doc, WHOLE_DOCUMENT ? 'html' : 'body')[0];\n }\n\n return WHOLE_DOCUMENT ? doc.documentElement : body;\n };\n /**\n * _createIterator\n *\n * @param {Document} root document/fragment to create iterator for\n * @return {Iterator} iterator instance\n */\n\n\n const _createIterator = function _createIterator(root) {\n return createNodeIterator.call(root.ownerDocument || root, root, // eslint-disable-next-line no-bitwise\n NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_COMMENT | NodeFilter.SHOW_TEXT, null, false);\n };\n /**\n * _isClobbered\n *\n * @param {Node} elm element to check for clobbering attacks\n * @return {Boolean} true if clobbered, false if safe\n */\n\n\n const _isClobbered = function _isClobbered(elm) {\n return elm instanceof HTMLFormElement && (typeof elm.nodeName !== 'string' || typeof elm.textContent !== 'string' || typeof elm.removeChild !== 'function' || !(elm.attributes instanceof NamedNodeMap) || typeof elm.removeAttribute !== 'function' || typeof elm.setAttribute !== 'function' || typeof elm.namespaceURI !== 'string' || typeof elm.insertBefore !== 'function' || typeof elm.hasChildNodes !== 'function');\n };\n /**\n * _isNode\n *\n * @param {Node} obj object to check whether it's a DOM node\n * @return {Boolean} true is object is a DOM node\n */\n\n\n const _isNode = function _isNode(object) {\n return typeof Node === 'object' ? object instanceof Node : object && typeof object === 'object' && typeof object.nodeType === 'number' && typeof object.nodeName === 'string';\n };\n /**\n * _executeHook\n * Execute user configurable hooks\n *\n * @param {String} entryPoint Name of the hook's entry point\n * @param {Node} currentNode node to work on with the hook\n * @param {Object} data additional hook parameters\n */\n\n\n const _executeHook = function _executeHook(entryPoint, currentNode, data) {\n if (!hooks[entryPoint]) {\n return;\n }\n\n arrayForEach(hooks[entryPoint], hook => {\n hook.call(DOMPurify, currentNode, data, CONFIG);\n });\n };\n /**\n * _sanitizeElements\n *\n * @protect nodeName\n * @protect textContent\n * @protect removeChild\n *\n * @param {Node} currentNode to check for permission to exist\n * @return {Boolean} true if node was killed, false if left alive\n */\n\n\n const _sanitizeElements = function _sanitizeElements(currentNode) {\n let content;\n /* Execute a hook if present */\n\n _executeHook('beforeSanitizeElements', currentNode, null);\n /* Check if element is clobbered or can clobber */\n\n\n if (_isClobbered(currentNode)) {\n _forceRemove(currentNode);\n\n return true;\n }\n /* Now let's check the element's type and name */\n\n\n const tagName = transformCaseFunc(currentNode.nodeName);\n /* Execute a hook if present */\n\n _executeHook('uponSanitizeElement', currentNode, {\n tagName,\n allowedTags: ALLOWED_TAGS\n });\n /* Detect mXSS attempts abusing namespace confusion */\n\n\n if (currentNode.hasChildNodes() && !_isNode(currentNode.firstElementChild) && (!_isNode(currentNode.content) || !_isNode(currentNode.content.firstElementChild)) && regExpTest(/<[/\\w]/g, currentNode.innerHTML) && regExpTest(/<[/\\w]/g, currentNode.textContent)) {\n _forceRemove(currentNode);\n\n return true;\n }\n /* Remove element if anything forbids its presence */\n\n\n if (!ALLOWED_TAGS[tagName] || FORBID_TAGS[tagName]) {\n /* Check if we have a custom element to handle */\n if (!FORBID_TAGS[tagName] && _basicCustomElementTest(tagName)) {\n if (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, tagName)) return false;\n if (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(tagName)) return false;\n }\n /* Keep content except for bad-listed elements */\n\n\n if (KEEP_CONTENT && !FORBID_CONTENTS[tagName]) {\n const parentNode = getParentNode(currentNode) || currentNode.parentNode;\n const childNodes = getChildNodes(currentNode) || currentNode.childNodes;\n\n if (childNodes && parentNode) {\n const childCount = childNodes.length;\n\n for (let i = childCount - 1; i >= 0; --i) {\n parentNode.insertBefore(cloneNode(childNodes[i], true), getNextSibling(currentNode));\n }\n }\n }\n\n _forceRemove(currentNode);\n\n return true;\n }\n /* Check whether element has a valid namespace */\n\n\n if (currentNode instanceof Element && !_checkValidNamespace(currentNode)) {\n _forceRemove(currentNode);\n\n return true;\n }\n /* Make sure that older browsers don't get fallback-tag mXSS */\n\n\n if ((tagName === 'noscript' || tagName === 'noembed' || tagName === 'noframes') && regExpTest(/<\\/no(script|embed|frames)/i, currentNode.innerHTML)) {\n _forceRemove(currentNode);\n\n return true;\n }\n /* Sanitize element content to be template-safe */\n\n\n if (SAFE_FOR_TEMPLATES && currentNode.nodeType === 3) {\n /* Get the element's text content */\n content = currentNode.textContent;\n content = stringReplace(content, MUSTACHE_EXPR, ' ');\n content = stringReplace(content, ERB_EXPR, ' ');\n content = stringReplace(content, TMPLIT_EXPR, ' ');\n\n if (currentNode.textContent !== content) {\n arrayPush(DOMPurify.removed, {\n element: currentNode.cloneNode()\n });\n currentNode.textContent = content;\n }\n }\n /* Execute a hook if present */\n\n\n _executeHook('afterSanitizeElements', currentNode, null);\n\n return false;\n };\n /**\n * _isValidAttribute\n *\n * @param {string} lcTag Lowercase tag name of containing element.\n * @param {string} lcName Lowercase attribute name.\n * @param {string} value Attribute value.\n * @return {Boolean} Returns true if `value` is valid, otherwise false.\n */\n // eslint-disable-next-line complexity\n\n\n const _isValidAttribute = function _isValidAttribute(lcTag, lcName, value) {\n /* Make sure attribute cannot clobber */\n if (SANITIZE_DOM && (lcName === 'id' || lcName === 'name') && (value in document || value in formElement)) {\n return false;\n }\n /* Allow valid data-* attributes: At least one character after \"-\"\n (https://html.spec.whatwg.org/multipage/dom.html#embedding-custom-non-visible-data-with-the-data-*-attributes)\n XML-compatible (https://html.spec.whatwg.org/multipage/infrastructure.html#xml-compatible and http://www.w3.org/TR/xml/#d0e804)\n We don't need to check the value; it's always URI safe. */\n\n\n if (ALLOW_DATA_ATTR && !FORBID_ATTR[lcName] && regExpTest(DATA_ATTR, lcName)) ; else if (ALLOW_ARIA_ATTR && regExpTest(ARIA_ATTR, lcName)) ; else if (!ALLOWED_ATTR[lcName] || FORBID_ATTR[lcName]) {\n if ( // First condition does a very basic check if a) it's basically a valid custom element tagname AND\n // b) if the tagName passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.tagNameCheck\n // and c) if the attribute name passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.attributeNameCheck\n _basicCustomElementTest(lcTag) && (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, lcTag) || CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(lcTag)) && (CUSTOM_ELEMENT_HANDLING.attributeNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.attributeNameCheck, lcName) || CUSTOM_ELEMENT_HANDLING.attributeNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.attributeNameCheck(lcName)) || // Alternative, second condition checks if it's an `is`-attribute, AND\n // the value passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.tagNameCheck\n lcName === 'is' && CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements && (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, value) || CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(value))) ; else {\n return false;\n }\n /* Check value is safe. First, is attr inert? If so, is safe */\n\n } else if (URI_SAFE_ATTRIBUTES[lcName]) ; else if (regExpTest(IS_ALLOWED_URI$1, stringReplace(value, ATTR_WHITESPACE, ''))) ; else if ((lcName === 'src' || lcName === 'xlink:href' || lcName === 'href') && lcTag !== 'script' && stringIndexOf(value, 'data:') === 0 && DATA_URI_TAGS[lcTag]) ; else if (ALLOW_UNKNOWN_PROTOCOLS && !regExpTest(IS_SCRIPT_OR_DATA, stringReplace(value, ATTR_WHITESPACE, ''))) ; else if (value) {\n return false;\n } else ;\n\n return true;\n };\n /**\n * _basicCustomElementCheck\n * checks if at least one dash is included in tagName, and it's not the first char\n * for more sophisticated checking see https://github.com/sindresorhus/validate-element-name\n * @param {string} tagName name of the tag of the node to sanitize\n */\n\n\n const _basicCustomElementTest = function _basicCustomElementTest(tagName) {\n return tagName.indexOf('-') > 0;\n };\n /**\n * _sanitizeAttributes\n *\n * @protect attributes\n * @protect nodeName\n * @protect removeAttribute\n * @protect setAttribute\n *\n * @param {Node} currentNode to sanitize\n */\n\n\n const _sanitizeAttributes = function _sanitizeAttributes(currentNode) {\n let attr;\n let value;\n let lcName;\n let l;\n /* Execute a hook if present */\n\n _executeHook('beforeSanitizeAttributes', currentNode, null);\n\n const {\n attributes\n } = currentNode;\n /* Check if we have attributes; if not we might have a text node */\n\n if (!attributes) {\n return;\n }\n\n const hookEvent = {\n attrName: '',\n attrValue: '',\n keepAttr: true,\n allowedAttributes: ALLOWED_ATTR\n };\n l = attributes.length;\n /* Go backwards over all attributes; safely remove bad ones */\n\n while (l--) {\n attr = attributes[l];\n const {\n name,\n namespaceURI\n } = attr;\n value = name === 'value' ? attr.value : stringTrim(attr.value);\n lcName = transformCaseFunc(name);\n /* Execute a hook if present */\n\n hookEvent.attrName = lcName;\n hookEvent.attrValue = value;\n hookEvent.keepAttr = true;\n hookEvent.forceKeepAttr = undefined; // Allows developers to see this is a property they can set\n\n _executeHook('uponSanitizeAttribute', currentNode, hookEvent);\n\n value = hookEvent.attrValue;\n /* Did the hooks approve of the attribute? */\n\n if (hookEvent.forceKeepAttr) {\n continue;\n }\n /* Remove attribute */\n\n\n _removeAttribute(name, currentNode);\n /* Did the hooks approve of the attribute? */\n\n\n if (!hookEvent.keepAttr) {\n continue;\n }\n /* Work around a security issue in jQuery 3.0 */\n\n\n if (!ALLOW_SELF_CLOSE_IN_ATTR && regExpTest(/\\/>/i, value)) {\n _removeAttribute(name, currentNode);\n\n continue;\n }\n /* Sanitize attribute content to be template-safe */\n\n\n if (SAFE_FOR_TEMPLATES) {\n value = stringReplace(value, MUSTACHE_EXPR, ' ');\n value = stringReplace(value, ERB_EXPR, ' ');\n value = stringReplace(value, TMPLIT_EXPR, ' ');\n }\n /* Is `value` valid for this attribute? */\n\n\n const lcTag = transformCaseFunc(currentNode.nodeName);\n\n if (!_isValidAttribute(lcTag, lcName, value)) {\n continue;\n }\n /* Full DOM Clobbering protection via namespace isolation,\n * Prefix id and name attributes with `user-content-`\n */\n\n\n if (SANITIZE_NAMED_PROPS && (lcName === 'id' || lcName === 'name')) {\n // Remove the attribute with this value\n _removeAttribute(name, currentNode); // Prefix the value and later re-create the attribute with the sanitized value\n\n\n value = SANITIZE_NAMED_PROPS_PREFIX + value;\n }\n /* Handle attributes that require Trusted Types */\n\n\n if (trustedTypesPolicy && typeof trustedTypes === 'object' && typeof trustedTypes.getAttributeType === 'function') {\n if (namespaceURI) ; else {\n switch (trustedTypes.getAttributeType(lcTag, lcName)) {\n case 'TrustedHTML':\n {\n value = trustedTypesPolicy.createHTML(value);\n break;\n }\n\n case 'TrustedScriptURL':\n {\n value = trustedTypesPolicy.createScriptURL(value);\n break;\n }\n }\n }\n }\n /* Handle invalid data-* attribute set by try-catching it */\n\n\n try {\n if (namespaceURI) {\n currentNode.setAttributeNS(namespaceURI, name, value);\n } else {\n /* Fallback to setAttribute() for browser-unrecognized namespaces e.g. \"x-schema\". */\n currentNode.setAttribute(name, value);\n }\n\n arrayPop(DOMPurify.removed);\n } catch (_) {}\n }\n /* Execute a hook if present */\n\n\n _executeHook('afterSanitizeAttributes', currentNode, null);\n };\n /**\n * _sanitizeShadowDOM\n *\n * @param {DocumentFragment} fragment to iterate over recursively\n */\n\n\n const _sanitizeShadowDOM = function _sanitizeShadowDOM(fragment) {\n let shadowNode;\n\n const shadowIterator = _createIterator(fragment);\n /* Execute a hook if present */\n\n\n _executeHook('beforeSanitizeShadowDOM', fragment, null);\n\n while (shadowNode = shadowIterator.nextNode()) {\n /* Execute a hook if present */\n _executeHook('uponSanitizeShadowNode', shadowNode, null);\n /* Sanitize tags and elements */\n\n\n if (_sanitizeElements(shadowNode)) {\n continue;\n }\n /* Deep shadow DOM detected */\n\n\n if (shadowNode.content instanceof DocumentFragment) {\n _sanitizeShadowDOM(shadowNode.content);\n }\n /* Check attributes, sanitize if necessary */\n\n\n _sanitizeAttributes(shadowNode);\n }\n /* Execute a hook if present */\n\n\n _executeHook('afterSanitizeShadowDOM', fragment, null);\n };\n /**\n * Sanitize\n * Public method providing core sanitation functionality\n *\n * @param {String|Node} dirty string or DOM node\n * @param {Object} configuration object\n */\n // eslint-disable-next-line complexity\n\n\n DOMPurify.sanitize = function (dirty) {\n let cfg = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n let body;\n let importedNode;\n let currentNode;\n let returnNode;\n /* Make sure we have a string to sanitize.\n DO NOT return early, as this will return the wrong type if\n the user has requested a DOM object rather than a string */\n\n IS_EMPTY_INPUT = !dirty;\n\n if (IS_EMPTY_INPUT) {\n dirty = '';\n }\n /* Stringify, in case dirty is an object */\n\n\n if (typeof dirty !== 'string' && !_isNode(dirty)) {\n if (typeof dirty.toString === 'function') {\n dirty = dirty.toString();\n\n if (typeof dirty !== 'string') {\n throw typeErrorCreate('dirty is not a string, aborting');\n }\n } else {\n throw typeErrorCreate('toString is not a function');\n }\n }\n /* Return dirty HTML if DOMPurify cannot run */\n\n\n if (!DOMPurify.isSupported) {\n return dirty;\n }\n /* Assign config vars */\n\n\n if (!SET_CONFIG) {\n _parseConfig(cfg);\n }\n /* Clean up removed elements */\n\n\n DOMPurify.removed = [];\n /* Check if dirty is correctly typed for IN_PLACE */\n\n if (typeof dirty === 'string') {\n IN_PLACE = false;\n }\n\n if (IN_PLACE) {\n /* Do some early pre-sanitization to avoid unsafe root nodes */\n if (dirty.nodeName) {\n const tagName = transformCaseFunc(dirty.nodeName);\n\n if (!ALLOWED_TAGS[tagName] || FORBID_TAGS[tagName]) {\n throw typeErrorCreate('root node is forbidden and cannot be sanitized in-place');\n }\n }\n } else if (dirty instanceof Node) {\n /* If dirty is a DOM element, append to an empty document to avoid\n elements being stripped by the parser */\n body = _initDocument('');\n importedNode = body.ownerDocument.importNode(dirty, true);\n\n if (importedNode.nodeType === 1 && importedNode.nodeName === 'BODY') {\n /* Node is already a body, use as is */\n body = importedNode;\n } else if (importedNode.nodeName === 'HTML') {\n body = importedNode;\n } else {\n // eslint-disable-next-line unicorn/prefer-dom-node-append\n body.appendChild(importedNode);\n }\n } else {\n /* Exit directly if we have nothing to do */\n if (!RETURN_DOM && !SAFE_FOR_TEMPLATES && !WHOLE_DOCUMENT && // eslint-disable-next-line unicorn/prefer-includes\n dirty.indexOf('<') === -1) {\n return trustedTypesPolicy && RETURN_TRUSTED_TYPE ? trustedTypesPolicy.createHTML(dirty) : dirty;\n }\n /* Initialize the document to work on */\n\n\n body = _initDocument(dirty);\n /* Check we have a DOM node from the data */\n\n if (!body) {\n return RETURN_DOM ? null : RETURN_TRUSTED_TYPE ? emptyHTML : '';\n }\n }\n /* Remove first element node (ours) if FORCE_BODY is set */\n\n\n if (body && FORCE_BODY) {\n _forceRemove(body.firstChild);\n }\n /* Get node iterator */\n\n\n const nodeIterator = _createIterator(IN_PLACE ? dirty : body);\n /* Now start iterating over the created document */\n\n\n while (currentNode = nodeIterator.nextNode()) {\n /* Sanitize tags and elements */\n if (_sanitizeElements(currentNode)) {\n continue;\n }\n /* Shadow DOM detected, sanitize it */\n\n\n if (currentNode.content instanceof DocumentFragment) {\n _sanitizeShadowDOM(currentNode.content);\n }\n /* Check attributes, sanitize if necessary */\n\n\n _sanitizeAttributes(currentNode);\n }\n /* If we sanitized `dirty` in-place, return it. */\n\n\n if (IN_PLACE) {\n return dirty;\n }\n /* Return sanitized string or DOM */\n\n\n if (RETURN_DOM) {\n if (RETURN_DOM_FRAGMENT) {\n returnNode = createDocumentFragment.call(body.ownerDocument);\n\n while (body.firstChild) {\n // eslint-disable-next-line unicorn/prefer-dom-node-append\n returnNode.appendChild(body.firstChild);\n }\n } else {\n returnNode = body;\n }\n\n if (ALLOWED_ATTR.shadowroot || ALLOWED_ATTR.shadowrootmode) {\n /*\n AdoptNode() is not used because internal state is not reset\n (e.g. the past names map of a HTMLFormElement), this is safe\n in theory but we would rather not risk another attack vector.\n The state that is cloned by importNode() is explicitly defined\n by the specs.\n */\n returnNode = importNode.call(originalDocument, returnNode, true);\n }\n\n return returnNode;\n }\n\n let serializedHTML = WHOLE_DOCUMENT ? body.outerHTML : body.innerHTML;\n /* Serialize doctype if allowed */\n\n if (WHOLE_DOCUMENT && ALLOWED_TAGS['!doctype'] && body.ownerDocument && body.ownerDocument.doctype && body.ownerDocument.doctype.name && regExpTest(DOCTYPE_NAME, body.ownerDocument.doctype.name)) {\n serializedHTML = '\\n' + serializedHTML;\n }\n /* Sanitize final string template-safe */\n\n\n if (SAFE_FOR_TEMPLATES) {\n serializedHTML = stringReplace(serializedHTML, MUSTACHE_EXPR, ' ');\n serializedHTML = stringReplace(serializedHTML, ERB_EXPR, ' ');\n serializedHTML = stringReplace(serializedHTML, TMPLIT_EXPR, ' ');\n }\n\n return trustedTypesPolicy && RETURN_TRUSTED_TYPE ? trustedTypesPolicy.createHTML(serializedHTML) : serializedHTML;\n };\n /**\n * Public method to set the configuration once\n * setConfig\n *\n * @param {Object} cfg configuration object\n */\n\n\n DOMPurify.setConfig = function (cfg) {\n _parseConfig(cfg);\n\n SET_CONFIG = true;\n };\n /**\n * Public method to remove the configuration\n * clearConfig\n *\n */\n\n\n DOMPurify.clearConfig = function () {\n CONFIG = null;\n SET_CONFIG = false;\n };\n /**\n * Public method to check if an attribute value is valid.\n * Uses last set config, if any. Otherwise, uses config defaults.\n * isValidAttribute\n *\n * @param {string} tag Tag name of containing element.\n * @param {string} attr Attribute name.\n * @param {string} value Attribute value.\n * @return {Boolean} Returns true if `value` is valid. Otherwise, returns false.\n */\n\n\n DOMPurify.isValidAttribute = function (tag, attr, value) {\n /* Initialize shared config vars if necessary. */\n if (!CONFIG) {\n _parseConfig({});\n }\n\n const lcTag = transformCaseFunc(tag);\n const lcName = transformCaseFunc(attr);\n return _isValidAttribute(lcTag, lcName, value);\n };\n /**\n * AddHook\n * Public method to add DOMPurify hooks\n *\n * @param {String} entryPoint entry point for the hook to add\n * @param {Function} hookFunction function to execute\n */\n\n\n DOMPurify.addHook = function (entryPoint, hookFunction) {\n if (typeof hookFunction !== 'function') {\n return;\n }\n\n hooks[entryPoint] = hooks[entryPoint] || [];\n arrayPush(hooks[entryPoint], hookFunction);\n };\n /**\n * RemoveHook\n * Public method to remove a DOMPurify hook at a given entryPoint\n * (pops it from the stack of hooks if more are present)\n *\n * @param {String} entryPoint entry point for the hook to remove\n * @return {Function} removed(popped) hook\n */\n\n\n DOMPurify.removeHook = function (entryPoint) {\n if (hooks[entryPoint]) {\n return arrayPop(hooks[entryPoint]);\n }\n };\n /**\n * RemoveHooks\n * Public method to remove all DOMPurify hooks at a given entryPoint\n *\n * @param {String} entryPoint entry point for the hooks to remove\n */\n\n\n DOMPurify.removeHooks = function (entryPoint) {\n if (hooks[entryPoint]) {\n hooks[entryPoint] = [];\n }\n };\n /**\n * RemoveAllHooks\n * Public method to remove all DOMPurify hooks\n *\n */\n\n\n DOMPurify.removeAllHooks = function () {\n hooks = {};\n };\n\n return DOMPurify;\n}\n\nvar purify = createDOMPurify();\n\nfunction createCheckbox$1(name, initialState) {\n const container = div({class: 'igv-ui-trackgear-popover-check-container'});\n const svg = iconMarkup('check', (true === initialState ? '#444' : 'transparent'));\n svg.style.borderColor = 'gray';\n svg.style.borderWidth = '1px';\n svg.style.borderStyle = 'solid';\n\n container.appendChild(svg);\n let label = div(); //{ class: 'igv-some-label-class' });\n label.textContent = name;\n container.appendChild(label);\n\n return container;\n}\n\nfunction createIcon(name, color) {\n return iconMarkup(name, color);\n}\n\nfunction iconMarkup(name, color) {\n color = color || \"currentColor\";\n let icon = icons[name];\n if (!icon) {\n console.error(`No icon named: ${name}`);\n icon = icons[\"question\"];\n }\n\n const svg = document.createElementNS(\"http://www.w3.org/2000/svg\", \"svg\");\n svg.setAttributeNS(null,'viewBox', '0 0 ' + icon[0] + ' ' + icon[1]);\n const path = document.createElementNS(\"http://www.w3.org/2000/svg\", \"path\");\n path.setAttributeNS(null,'fill', color );\n path.setAttributeNS(null,'d', icon[4]);\n svg.appendChild(path);\n return svg;\n}\n\nconst icons = {\n \"check\": [512, 512, [], \"f00c\", \"M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z\"],\n \"cog\": [512, 512, [], \"f013\", \"M444.788 291.1l42.616 24.599c4.867 2.809 7.126 8.618 5.459 13.985-11.07 35.642-29.97 67.842-54.689 94.586a12.016 12.016 0 0 1-14.832 2.254l-42.584-24.595a191.577 191.577 0 0 1-60.759 35.13v49.182a12.01 12.01 0 0 1-9.377 11.718c-34.956 7.85-72.499 8.256-109.219.007-5.49-1.233-9.403-6.096-9.403-11.723v-49.184a191.555 191.555 0 0 1-60.759-35.13l-42.584 24.595a12.016 12.016 0 0 1-14.832-2.254c-24.718-26.744-43.619-58.944-54.689-94.586-1.667-5.366.592-11.175 5.459-13.985L67.212 291.1a193.48 193.48 0 0 1 0-70.199l-42.616-24.599c-4.867-2.809-7.126-8.618-5.459-13.985 11.07-35.642 29.97-67.842 54.689-94.586a12.016 12.016 0 0 1 14.832-2.254l42.584 24.595a191.577 191.577 0 0 1 60.759-35.13V25.759a12.01 12.01 0 0 1 9.377-11.718c34.956-7.85 72.499-8.256 109.219-.007 5.49 1.233 9.403 6.096 9.403 11.723v49.184a191.555 191.555 0 0 1 60.759 35.13l42.584-24.595a12.016 12.016 0 0 1 14.832 2.254c24.718 26.744 43.619 58.944 54.689 94.586 1.667 5.366-.592 11.175-5.459 13.985L444.788 220.9a193.485 193.485 0 0 1 0 70.2zM336 256c0-44.112-35.888-80-80-80s-80 35.888-80 80 35.888 80 80 80 80-35.888 80-80z\"],\n \"exclamation\": [192, 512, [], \"f12a\", \"M176 432c0 44.112-35.888 80-80 80s-80-35.888-80-80 35.888-80 80-80 80 35.888 80 80zM25.26 25.199l13.6 272C39.499 309.972 50.041 320 62.83 320h66.34c12.789 0 23.331-10.028 23.97-22.801l13.6-272C167.425 11.49 156.496 0 142.77 0H49.23C35.504 0 24.575 11.49 25.26 25.199z\"],\n \"exclamation-circle\": [512, 512, [], \"f06a\", \"M504 256c0 136.997-111.043 248-248 248S8 392.997 8 256C8 119.083 119.043 8 256 8s248 111.083 248 248zm-248 50c-25.405 0-46 20.595-46 46s20.595 46 46 46 46-20.595 46-46-20.595-46-46-46zm-43.673-165.346l7.418 136c.347 6.364 5.609 11.346 11.982 11.346h48.546c6.373 0 11.635-4.982 11.982-11.346l7.418-136c.375-6.874-5.098-12.654-11.982-12.654h-63.383c-6.884 0-12.356 5.78-11.981 12.654z\"],\n \"exclamation-triangle\": [576, 512, [], \"f071\", \"M569.517 440.013C587.975 472.007 564.806 512 527.94 512H48.054c-36.937 0-59.999-40.055-41.577-71.987L246.423 23.985c18.467-32.009 64.72-31.951 83.154 0l239.94 416.028zM288 354c-25.405 0-46 20.595-46 46s20.595 46 46 46 46-20.595 46-46-20.595-46-46-46zm-43.673-165.346l7.418 136c.347 6.364 5.609 11.346 11.982 11.346h48.546c6.373 0 11.635-4.982 11.982-11.346l7.418-136c.375-6.874-5.098-12.654-11.982-12.654h-63.383c-6.884 0-12.356 5.78-11.981 12.654z\"],\n \"minus\": [448, 512, [], \"f068\", \"M424 318.2c13.3 0 24-10.7 24-24v-76.4c0-13.3-10.7-24-24-24H24c-13.3 0-24 10.7-24 24v76.4c0 13.3 10.7 24 24 24h400z\"],\n \"minus-circle\": [512, 512, [], \"f056\", \"M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zM124 296c-6.6 0-12-5.4-12-12v-56c0-6.6 5.4-12 12-12h264c6.6 0 12 5.4 12 12v56c0 6.6-5.4 12-12 12H124z\"],\n \"minus-square\": [448, 512, [], \"f146\", \"M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM92 296c-6.6 0-12-5.4-12-12v-56c0-6.6 5.4-12 12-12h264c6.6 0 12 5.4 12 12v56c0 6.6-5.4 12-12 12H92z\"],\n \"plus\": [448, 512, [], \"f067\", \"M448 294.2v-76.4c0-13.3-10.7-24-24-24H286.2V56c0-13.3-10.7-24-24-24h-76.4c-13.3 0-24 10.7-24 24v137.8H24c-13.3 0-24 10.7-24 24v76.4c0 13.3 10.7 24 24 24h137.8V456c0 13.3 10.7 24 24 24h76.4c13.3 0 24-10.7 24-24V318.2H424c13.3 0 24-10.7 24-24z\"],\n \"plus-circle\": [512, 512, [], \"f055\", \"M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm144 276c0 6.6-5.4 12-12 12h-92v92c0 6.6-5.4 12-12 12h-56c-6.6 0-12-5.4-12-12v-92h-92c-6.6 0-12-5.4-12-12v-56c0-6.6 5.4-12 12-12h92v-92c0-6.6 5.4-12 12-12h56c6.6 0 12 5.4 12 12v92h92c6.6 0 12 5.4 12 12v56z\"],\n \"plus-square\": [448, 512, [], \"f0fe\", \"M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-32 252c0 6.6-5.4 12-12 12h-92v92c0 6.6-5.4 12-12 12h-56c-6.6 0-12-5.4-12-12v-92H92c-6.6 0-12-5.4-12-12v-56c0-6.6 5.4-12 12-12h92v-92c0-6.6 5.4-12 12-12h56c6.6 0 12 5.4 12 12v92h92c6.6 0 12 5.4 12 12v56z\"],\n \"question\": [384, 512, [], \"f128\", \"M202.021 0C122.202 0 70.503 32.703 29.914 91.026c-7.363 10.58-5.093 25.086 5.178 32.874l43.138 32.709c10.373 7.865 25.132 6.026 33.253-4.148 25.049-31.381 43.63-49.449 82.757-49.449 30.764 0 68.816 19.799 68.816 49.631 0 22.552-18.617 34.134-48.993 51.164-35.423 19.86-82.299 44.576-82.299 106.405V320c0 13.255 10.745 24 24 24h72.471c13.255 0 24-10.745 24-24v-5.773c0-42.86 125.268-44.645 125.268-160.627C377.504 66.256 286.902 0 202.021 0zM192 373.459c-38.196 0-69.271 31.075-69.271 69.271 0 38.195 31.075 69.27 69.271 69.27s69.271-31.075 69.271-69.271-31.075-69.27-69.271-69.27z\"],\n \"save\": [448, 512, [], \"f0c7\", \"M433.941 129.941l-83.882-83.882A48 48 0 0 0 316.118 32H48C21.49 32 0 53.49 0 80v352c0 26.51 21.49 48 48 48h352c26.51 0 48-21.49 48-48V163.882a48 48 0 0 0-14.059-33.941zM224 416c-35.346 0-64-28.654-64-64 0-35.346 28.654-64 64-64s64 28.654 64 64c0 35.346-28.654 64-64 64zm96-304.52V212c0 6.627-5.373 12-12 12H76c-6.627 0-12-5.373-12-12V108c0-6.627 5.373-12 12-12h228.52c3.183 0 6.235 1.264 8.485 3.515l3.48 3.48A11.996 11.996 0 0 1 320 111.48z\"],\n \"search\": [512, 512, [], \"f002\", \"M505 442.7L405.3 343c-4.5-4.5-10.6-7-17-7H372c27.6-35.3 44-79.7 44-128C416 93.1 322.9 0 208 0S0 93.1 0 208s93.1 208 208 208c48.3 0 92.7-16.4 128-44v16.3c0 6.4 2.5 12.5 7 17l99.7 99.7c9.4 9.4 24.6 9.4 33.9 0l28.3-28.3c9.4-9.4 9.4-24.6.1-34zM208 336c-70.7 0-128-57.2-128-128 0-70.7 57.2-128 128-128 70.7 0 128 57.2 128 128 0 70.7-57.2 128-128 128z\"],\n \"share\": [512, 512, [], \"f064\", \"M503.691 189.836L327.687 37.851C312.281 24.546 288 35.347 288 56.015v80.053C127.371 137.907 0 170.1 0 322.326c0 61.441 39.581 122.309 83.333 154.132 13.653 9.931 33.111-2.533 28.077-18.631C66.066 312.814 132.917 274.316 288 272.085V360c0 20.7 24.3 31.453 39.687 18.164l176.004-152c11.071-9.562 11.086-26.753 0-36.328z\"],\n \"spinner\": [512, 512, [], \"f110\", \"M304 48c0 26.51-21.49 48-48 48s-48-21.49-48-48 21.49-48 48-48 48 21.49 48 48zm-48 368c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48-21.49-48-48-48zm208-208c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48-21.49-48-48-48zM96 256c0-26.51-21.49-48-48-48S0 229.49 0 256s21.49 48 48 48 48-21.49 48-48zm12.922 99.078c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48c0-26.509-21.491-48-48-48zm294.156 0c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48c0-26.509-21.49-48-48-48zM108.922 60.922c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48-21.491-48-48-48z\"],\n \"square\": [448, 512, [], \"f0c8\", \"M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48z\"],\n \"square-full\": [512, 512, [], \"f45c\", \"M512 512H0V0h512v512z\"],\n \"times\": [384, 512, [], \"f00d\", \"M323.1 441l53.9-53.9c9.4-9.4 9.4-24.5 0-33.9L279.8 256l97.2-97.2c9.4-9.4 9.4-24.5 0-33.9L323.1 71c-9.4-9.4-24.5-9.4-33.9 0L192 168.2 94.8 71c-9.4-9.4-24.5-9.4-33.9 0L7 124.9c-9.4 9.4-9.4 24.5 0 33.9l97.2 97.2L7 353.2c-9.4 9.4-9.4 24.5 0 33.9L60.9 441c9.4 9.4 24.5 9.4 33.9 0l97.2-97.2 97.2 97.2c9.3 9.3 24.5 9.3 33.9 0z\"],\n \"times-circle\": [512, 512, [], \"f057\", \"M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm121.6 313.1c4.7 4.7 4.7 12.3 0 17L338 377.6c-4.7 4.7-12.3 4.7-17 0L256 312l-65.1 65.6c-4.7 4.7-12.3 4.7-17 0L134.4 338c-4.7-4.7-4.7-12.3 0-17l65.6-65-65.6-65.1c-4.7-4.7-4.7-12.3 0-17l39.6-39.6c4.7-4.7 12.3-4.7 17 0l65 65.7 65.1-65.6c4.7-4.7 12.3-4.7 17 0l39.6 39.6c4.7 4.7 4.7 12.3 0 17L312 256l65.6 65.1z\"],\n \"wrench\": [512, 512, [], \"f0ad\", \"M481.156 200c9.3 0 15.12 10.155 10.325 18.124C466.295 259.992 420.419 288 368 288c-79.222 0-143.501-63.974-143.997-143.079C223.505 65.469 288.548-.001 368.002 0c52.362.001 98.196 27.949 123.4 69.743C496.24 77.766 490.523 88 481.154 88H376l-40 56 40 56h105.156zm-171.649 93.003L109.255 493.255c-24.994 24.993-65.515 24.994-90.51 0-24.993-24.994-24.993-65.516 0-90.51L218.991 202.5c16.16 41.197 49.303 74.335 90.516 90.503zM104 432c0-13.255-10.745-24-24-24s-24 10.745-24 24 10.745 24 24 24 24-10.745 24-24z\"],\n};\n\nvar icons$1 = /*#__PURE__*/Object.freeze({\n __proto__: null,\n createCheckbox: createCheckbox$1,\n createIcon: createIcon\n});\n\nfunction attachDialogCloseHandlerWithParent(parent, closeHandler) {\n\n var container = document.createElement(\"div\");\n parent.appendChild(container);\n container.appendChild(createIcon(\"times\"));\n container.addEventListener('click', function (e) {\n e.preventDefault();\n e.stopPropagation();\n closeHandler();\n });\n}\n\nvar uiUtils = /*#__PURE__*/Object.freeze({\n __proto__: null,\n attachDialogCloseHandlerWithParent: attachDialogCloseHandlerWithParent\n});\n\n/**\n * Make the target element movable by clicking and dragging on the handle. This is not a general purprose function,\n * it makes several options specific to igv dialogs, the primary one being that the\n * target is absolutely positioned in pixel coordinates\n\n */\n\nlet dragData; // Its assumed we are only dragging one element at a time.\n\nfunction makeDraggable(target, handle, constraint) {\n\n handle.addEventListener('mousedown', dragStart.bind(target));\n\n function dragStart(event) {\n\n event.stopPropagation();\n event.preventDefault();\n\n const dragFunction = drag.bind(this);\n const dragEndFunction = dragEnd.bind(this);\n const computedStyle = getComputedStyle(this);\n\n dragData =\n {\n constraint,\n dragFunction,\n dragEndFunction,\n screenX: event.screenX,\n screenY: event.screenY,\n top: parseInt(computedStyle.top.replace(\"px\", \"\")),\n left: parseInt(computedStyle.left.replace(\"px\", \"\"))\n };\n\n document.addEventListener('mousemove', dragFunction);\n document.addEventListener('mouseup', dragEndFunction);\n document.addEventListener('mouseleave', dragEndFunction);\n document.addEventListener('mouseexit', dragEndFunction);\n }\n}\n\nfunction drag(event) {\n\n if (!dragData) {\n console.error(\"No drag data!\");\n return;\n }\n event.stopPropagation();\n event.preventDefault();\n const dx = event.screenX - dragData.screenX;\n const dy = event.screenY - dragData.screenY;\n\n const left = dragData.left + dx;\n const top = dragData.constraint ? Math.max(dragData.constraint.minY, dragData.top + dy) : dragData.top + dy;\n\n this.style.left = `${ left }px`;\n this.style.top = `${ top }px`;\n}\n\nfunction dragEnd(event) {\n\n if (!dragData) {\n console.error(\"No drag data!\");\n return;\n }\n event.stopPropagation();\n event.preventDefault();\n\n const dragFunction = dragData.dragFunction;\n const dragEndFunction = dragData.dragEndFunction;\n document.removeEventListener('mousemove', dragFunction);\n document.removeEventListener('mouseup', dragEndFunction);\n document.removeEventListener('mouseleave', dragEndFunction);\n document.removeEventListener('mouseexit', dragEndFunction);\n dragData = undefined;\n}\n\nconst httpMessages =\n {\n \"401\": \"Access unauthorized\",\n \"403\": \"Access forbidden\",\n \"404\": \"Not found\"\n };\n\n\nclass AlertDialog {\n /**\n * Initialize a new alert dialog\n * @param parent\n * @param alertProps - Optional - properties such as scroll to error\n */\n constructor(parent, alertProps) {\n this.alertProps = Object.assign({\n /** When an alert is presented - focus occur */\n shouldFocus: true,\n /** When focus occur - scroll into that element in the view */\n preventScroll: false\n }, alertProps);\n\n // container\n this.container = div({class: \"igv-ui-alert-dialog-container\"});\n parent.appendChild(this.container);\n this.container.setAttribute('tabIndex', '-1');\n\n // header\n const header = div();\n this.container.appendChild(header);\n\n this.errorHeadline = div();\n header.appendChild(this.errorHeadline);\n this.errorHeadline.textContent = '';\n\n // body container\n let bodyContainer = div({class: 'igv-ui-alert-dialog-body'});\n this.container.appendChild(bodyContainer);\n\n // body copy\n this.body = div({class: 'igv-ui-alert-dialog-body-copy'});\n bodyContainer.appendChild(this.body);\n\n // ok container\n let ok_container = div();\n this.container.appendChild(ok_container);\n\n // ok\n this.ok = div();\n ok_container.appendChild(this.ok);\n this.ok.textContent = 'OK';\n\n const okHandler = () => {\n\n if (typeof this.callback === 'function') {\n this.callback(\"OK\");\n this.callback = undefined;\n }\n this.body.innerHTML = '';\n hide(this.container);\n };\n\n this.ok.addEventListener('click', event => {\n\n event.stopPropagation();\n\n okHandler();\n });\n\n this.container.addEventListener('keypress', event => {\n\n event.stopPropagation();\n\n if ('Enter' === event.key) {\n okHandler();\n }\n });\n\n makeDraggable(this.container, header);\n\n hide(this.container);\n }\n\n present(alert, callback) {\n\n this.errorHeadline.textContent = alert.message ? 'ERROR' : '';\n let string = alert.message || alert;\n\n if (httpMessages.hasOwnProperty(string)) {\n string = httpMessages[string];\n }\n\n const clean = purify.sanitize(string);\n\n this.body.innerHTML = clean;\n this.callback = callback;\n show(this.container);\n if (this.alertProps.shouldFocus) {\n this.container.focus(\n { preventScroll: this.alertProps.preventScroll }\n );\n }\n }\n}\n\nclass InputDialog {\n\n constructor(parent) {\n\n this.parent = parent;\n\n // dialog container\n this.container = div({class: 'igv-ui-generic-dialog-container'});\n parent.appendChild(this.container);\n\n // const { x, y, width, height } = this.container.getBoundingClientRect();\n // console.log(`InputDialog - x ${ x } y ${ y } width ${ width } height ${ height }`)\n\n // dialog header\n const header = div({class: 'igv-ui-generic-dialog-header'});\n this.container.appendChild(header);\n\n // dialog label\n this.label = div({class: 'igv-ui-generic-dialog-one-liner'});\n this.container.appendChild(this.label);\n this.label.text = 'Unlabeled';\n\n // input container\n this.input_container = div({class: 'igv-ui-generic-dialog-input'});\n this.container.appendChild(this.input_container);\n //\n this.input = document.createElement(\"input\");\n this.input_container.appendChild(this.input);\n\n\n // ok | cancel\n const buttons = div({class: 'igv-ui-generic-dialog-ok-cancel'});\n this.container.appendChild(buttons);\n\n // ok\n this.ok = div();\n buttons.appendChild(this.ok);\n this.ok.textContent = 'OK';\n\n // cancel\n this.cancel = div();\n buttons.appendChild(this.cancel);\n this.cancel.textContent = 'Cancel';\n\n hide(this.container);\n\n this.input.addEventListener('keyup', e => {\n if (13 === e.keyCode) {\n if (typeof this.callback === 'function') {\n this.callback(this.input.value);\n this.callback = undefined;\n }\n this.input.value = undefined;\n hide(this.container);\n }\n });\n\n this.ok.addEventListener('click', () => {\n if (typeof this.callback === 'function') {\n this.callback(this.input.value);\n this.callback = undefined;\n }\n this.input.value = undefined;\n hide(this.container);\n });\n\n const cancel = () => {\n this.input.value = '';\n hide(this.container);\n };\n\n this.cancel.addEventListener('click', cancel);\n\n attachDialogCloseHandlerWithParent(header, cancel);\n makeDraggable(this.container, header);\n\n }\n\n get value() {\n return purify.sanitize(this.input.value)\n }\n\n present(options, e) {\n\n this.label.textContent = options.label;\n this.input.value = options.value;\n this.callback = options.callback || options.click;\n\n show(this.container);\n this.clampLocation(e.clientX, e.clientY);\n\n }\n\n clampLocation(clientX, clientY) {\n\n const {width: w, height: h} = this.container.getBoundingClientRect();\n const wh = window.innerHeight;\n const ww = window.innerWidth;\n\n const y = Math.min(wh - h, clientY);\n const x = Math.min(ww - w, clientX);\n this.container.style.left = `${x}px`;\n this.container.style.top = `${y}px`;\n\n }\n}\n\nconst appleCrayonPalette =\n {\n licorice: \"#000000\",\n lead: \"#1e1e1e\",\n tungsten: \"#3a3a3a\",\n iron: \"#545453\",\n steel: \"#6e6e6e\",\n tin: \"#878687\",\n nickel: \"#888787\",\n aluminum: \"#a09fa0\",\n magnesium: \"#b8b8b8\",\n silver: \"#d0d0d0\",\n mercury: \"#e8e8e8\",\n snow: \"#ffffff\",\n //\n cayenne: \"#891100\",\n mocha: \"#894800\",\n aspargus: \"#888501\",\n fern: \"#458401\",\n clover: \"#028401\",\n moss: \"#018448\",\n teal: \"#008688\",\n ocean: \"#004a88\",\n midnight: \"#001888\",\n eggplant: \"#491a88\",\n plum: \"#891e88\",\n maroon: \"#891648\",\n //\n maraschino: \"#ff2101\",\n tangerine: \"#ff8802\",\n lemon: \"#fffa03\",\n lime: \"#83f902\",\n spring: \"#05f802\",\n seam_foam: \"#03f987\",\n turquoise: \"#00fdff\",\n aqua: \"#008cff\",\n blueberry: \"#002eff\",\n grape: \"#8931ff\",\n magenta: \"#ff39ff\",\n strawberry: \"#ff2987\",\n //\n salmon: \"#ff726e\",\n cantaloupe: \"#ffce6e\",\n banana: \"#fffb6d\",\n honeydew: \"#cefa6e\",\n flora: \"#68f96e\",\n spindrift: \"#68fbd0\",\n ice: \"#68fdff\",\n sky: \"#6acfff\",\n orchid: \"#6e76ff\",\n lavender: \"#d278ff\",\n bubblegum: \"#ff7aff\",\n carnation: \"#ff7fd3\"\n };\n\nclass GenericContainer {\n\n constructor({parent, top, left, width, height, border, closeHandler}) {\n\n let container = div({class: 'igv-ui-generic-container'});\n parent.appendChild(container);\n hide(container);\n this.container = container;\n\n if(top !== undefined) {\n this.container.style.top = `${ top }px`;\n }\n if(left !== undefined) {\n this.container.style.left = `${ left }px`;\n }\n if (width !== undefined) {\n this.container.style.width = `${ width }px`;\n }\n if (height !== undefined) {\n this.container.style.height = `${ height }px`;\n }\n if(border) {\n this.container.style.border = border;\n }\n //\n // let bbox = parent.getBoundingClientRect();\n // this.origin = {x: bbox.x, y: bbox.y};\n // this.container.offset({left: this.origin.x, top: this.origin.y});\n\n // header\n const header = div();\n this.container.appendChild(header);\n\n // close button\n attachDialogCloseHandlerWithParent(header, (e) => {\n hide(this.container);\n if(typeof closeHandler === \"function\") {\n closeHandler(e);\n }\n });\n\n makeDraggable(this.container, header);\n }\n\n show() {\n show(this.container);\n }\n\n hide() {\n hide(this.container);\n }\n\n dispose() {\n if(this.container.parent) {\n this.container.parent.removeChild(this.container);\n }\n }\n}\n\nclass ColorPicker extends GenericContainer {\n\n constructor({parent, top, left, width, height, defaultColors, colorHandler}) {\n\n super({ parent, top, left, width, height, border: '1px solid gray'});\n\n createColorSwatchSelector(this.container, colorHandler, defaultColors);\n }\n\n}\n\nconst createColorSwatchSelector = (container, colorHandler, defaultColors) => {\n\n const hexColorStrings = Object.values(appleCrayonPalette);\n\n for (let hexColorString of hexColorStrings) {\n const swatch = div({ class: 'igv-ui-color-swatch' });\n container.appendChild(swatch);\n decorateSwatch(swatch, hexColorString, colorHandler);\n }\n\n if (defaultColors) {\n for (let hexColorString of defaultColors) {\n const swatch = div({ class: 'igv-ui-color-swatch' });\n container.appendChild(swatch);\n decorateSwatch(swatch, hexColorString, colorHandler);\n }\n }\n\n};\n\nconst decorateSwatch = (swatch, hexColorString, colorHandler) => {\n\n swatch.style.backgroundColor = hexColorString;\n\n swatch.addEventListener('mouseenter', e => swatch.style.borderColor = hexColorString);\n\n swatch.addEventListener('mouseleave', e => swatch.style.borderColor = 'white');\n\n swatch.addEventListener('click', event => {\n event.stopPropagation();\n colorHandler(hexColorString);\n });\n\n swatch.addEventListener('touchend', event => {\n event.stopPropagation();\n colorHandler(hexColorString);\n });\n\n};\n\nclass Popover {\n\n constructor(parent, title) {\n\n this.parent = parent;\n\n // popover\n this.popover = div({ class: \"igv-ui-popover\" });\n parent.appendChild(this.popover);\n\n // header\n const popoverHeader = div();\n this.popover.appendChild(popoverHeader);\n\n const titleElement = div();\n popoverHeader.appendChild(titleElement);\n if (title) {\n titleElement.textContent = title;\n }\n\n attachDialogCloseHandlerWithParent(popoverHeader, () => this.hide());\n makeDraggable(this.popover, popoverHeader);\n\n // content\n this.popoverContent = div();\n this.popover.appendChild(this.popoverContent);\n\n this.popover.style.display = 'none';\n\n\n }\n\n presentContentWithEvent(e, content) {\n\n this.popover.style.display = 'block';\n\n this.popoverContent.innerHTML = content;\n\n present$1(e, this.popover, this.popoverContent);\n\n }\n\n presentMenu(e, menuItems) {\n\n if (0 === menuItems.length) {\n return\n }\n\n this.popover.style.display = 'block';\n\n const menuElements = createMenuElements$1(menuItems, this.popover);\n for (let item of menuElements) {\n this.popoverContent.appendChild(item.object);\n }\n\n present$1(e, this.popover, this.popoverContent);\n }\n\n hide() {\n this.popover.style.display = 'none';\n this.dispose();\n }\n\n dispose() {\n\n if (this.popover) {\n this.popover.parentNode.removeChild(this.popover);\n }\n\n const keys = Object.keys(this);\n for (let key of keys) {\n this[ key ] = undefined;\n }\n }\n\n}\n\nfunction present$1(e, popover, popoverContent) {\n\n const { x, y, width } = translateMouseCoordinates(e, popover.parentNode);\n popover.style.top = `${ y }px`;\n\n const { width: w } = popover.getBoundingClientRect();\n\n const xmax = x + w;\n const delta = xmax - width;\n\n popover.style.left = `${ xmax > width ? (x - delta) : x }px`;\n popoverContent.style.maxWidth = `${ Math.min(w, width) }px`;\n\n\n}\n\nfunction createMenuElements$1(itemList, popover) {\n\n const list = itemList.map(function (item, i) {\n let elem;\n\n if (typeof item === 'string') {\n elem = div();\n elem.innerHTML = item;\n } else if (typeof item === 'Node') {\n elem = item;\n } else {\n if (typeof item.init === 'function') {\n item.init();\n }\n\n if (\"checkbox\" === item.type) {\n elem = createCheckbox$1(\"Show all bases\", item.value);\n } else if(\"color\" === item.type) {\n const colorPicker = new ColorPicker({\n parent: popover.parentElement,\n width: 364,\n //defaultColor: 'aqua',\n colorHandler: (color) => item.click(color)\n });\n elem = div();\n if (typeof item.label === 'string') {\n elem.innerHTML = item.label;\n }\n const clickHandler = e => {\n colorPicker.show();\n hide(popover);\n e.preventDefault();\n e.stopPropagation();\n };\n elem.addEventListener('click', clickHandler);\n elem.addEventListener('touchend', clickHandler);\n elem.addEventListener('mouseup', function (e) {\n e.preventDefault();\n e.stopPropagation();\n });\n }\n\n else {\n elem = div();\n if (typeof item.label === 'string') {\n elem.innerHTML = item.label;\n }\n }\n\n if (item.click && \"color\" !== item.type) {\n elem.addEventListener('click', handleClick);\n elem.addEventListener('touchend', handleClick);\n elem.addEventListener('mouseup', function (e) {\n e.preventDefault();\n e.stopPropagation();\n });\n\n // eslint-disable-next-line no-inner-declarations\n function handleClick(e) {\n item.click();\n hide(popover);\n e.preventDefault();\n e.stopPropagation();\n }\n }\n }\n\n\n return { object: elem, init: item.init };\n });\n\n return list;\n}\n\nclass GenericColorPicker extends GenericContainer {\n\n constructor({parent, width}) {\n super({parent, width, border: '1px solid gray'});\n }\n\n configure(defaultColors, colorHandlers) {\n\n this.colorHandlers = colorHandlers;\n\n // active color handler defaults to handler with 'color' as key\n this.setActiveColorHandler('color');\n\n this.createSwatches(defaultColors);\n\n }\n\n setActiveColorHandler(option) {\n this.activeColorHandler = this.colorHandlers[option];\n }\n\n createSwatches(defaultColors) {\n\n this.container.querySelectorAll('.igv-ui-color-swatch').forEach(swatch => swatch.remove());\n\n const hexColorStrings = Object.values(appleCrayonPalette);\n\n for (let hexColorString of hexColorStrings) {\n const swatch = div({class: 'igv-ui-color-swatch'});\n this.container.appendChild(swatch);\n this.decorateSwatch(swatch, hexColorString);\n }\n\n if (defaultColors) {\n for (let hexColorString of defaultColors) {\n const swatch = div({class: 'igv-ui-color-swatch'});\n this.container.appendChild(swatch);\n this.decorateSwatch(swatch, hexColorString);\n }\n }\n\n }\n\n decorateSwatch(swatch, hexColorString) {\n\n swatch.style.backgroundColor = hexColorString;\n\n swatch.addEventListener('mouseenter', () => swatch.style.borderColor = hexColorString);\n\n swatch.addEventListener('mouseleave', () => swatch.style.borderColor = 'white');\n\n swatch.addEventListener('click', event => {\n event.stopPropagation();\n this.activeColorHandler(hexColorString);\n });\n\n swatch.addEventListener('touchend', event => {\n event.stopPropagation();\n this.activeColorHandler(hexColorString);\n });\n\n }\n\n}\n\nfunction embedCSS$2() {\n const style = document.createElement('style');\n style.setAttribute('type', 'text/css');\n style.setAttribute('title', 'igv-ui.css');\n style.innerHTML = `.igv-ui-popover {\n cursor: default;\n position: absolute;\n z-index: 2048;\n border-color: #7F7F7F;\n border-radius: 4px;\n border-style: solid;\n border-width: 1px;\n font-family: \"Open Sans\", sans-serif;\n font-size: small;\n background-color: white;\n}\n.igv-ui-popover > div:first-child {\n display: flex;\n flex-direction: row;\n flex-wrap: nowrap;\n justify-content: space-between;\n align-items: center;\n width: 100%;\n height: 24px;\n cursor: move;\n border-top-left-radius: 4px;\n border-top-right-radius: 4px;\n border-bottom-color: #7F7F7F;\n border-bottom-style: solid;\n border-bottom-width: thin;\n background-color: #eee;\n}\n.igv-ui-popover > div:first-child > div:first-child {\n margin-left: 4px;\n}\n.igv-ui-popover > div:first-child > div:last-child {\n margin-right: 4px;\n height: 12px;\n width: 12px;\n color: #7F7F7F;\n}\n.igv-ui-popover > div:first-child > div:last-child:hover {\n cursor: pointer;\n color: #444;\n}\n.igv-ui-popover > div:last-child {\n overflow-y: auto;\n overflow-x: hidden;\n max-height: 400px;\n max-width: 800px;\n background-color: white;\n}\n.igv-ui-popover > div:last-child > div {\n user-select: all;\n margin-left: 4px;\n margin-right: 4px;\n min-width: 220px;\n overflow-x: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.igv-ui-popover > div:last-child > div > span {\n font-weight: bolder;\n}\n.igv-ui-popover > div:last-child hr {\n width: 100%;\n}\n\n.igv-ui-alert-dialog-container {\n box-sizing: content-box;\n position: absolute;\n z-index: 2048;\n top: 50%;\n left: 50%;\n width: 400px;\n height: 200px;\n border-color: #7F7F7F;\n border-radius: 4px;\n border-style: solid;\n border-width: thin;\n outline: none;\n font-family: \"Open Sans\", sans-serif;\n font-size: 15px;\n font-weight: 400;\n background-color: white;\n display: flex;\n flex-flow: column;\n flex-wrap: nowrap;\n justify-content: space-between;\n align-items: center;\n}\n.igv-ui-alert-dialog-container > div:first-child {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n width: 100%;\n height: 24px;\n cursor: move;\n border-top-left-radius: 4px;\n border-top-right-radius: 4px;\n border-bottom-color: #7F7F7F;\n border-bottom-style: solid;\n border-bottom-width: thin;\n background-color: #eee;\n}\n.igv-ui-alert-dialog-container > div:first-child div:first-child {\n padding-left: 8px;\n}\n.igv-ui-alert-dialog-container .igv-ui-alert-dialog-body {\n -webkit-user-select: text;\n -moz-user-select: text;\n -ms-user-select: text;\n user-select: text;\n color: #373737;\n width: 100%;\n height: calc(100% - 24px - 64px);\n overflow-y: scroll;\n}\n.igv-ui-alert-dialog-container .igv-ui-alert-dialog-body .igv-ui-alert-dialog-body-copy {\n margin: 16px;\n width: auto;\n height: auto;\n overflow-wrap: break-word;\n word-break: break-word;\n background-color: white;\n border: unset;\n}\n.igv-ui-alert-dialog-container > div:last-child {\n width: 100%;\n margin-bottom: 10px;\n background-color: white;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: center;\n align-items: center;\n}\n.igv-ui-alert-dialog-container > div:last-child div {\n margin: unset;\n width: 40px;\n height: 30px;\n line-height: 30px;\n text-align: center;\n color: white;\n font-family: \"Open Sans\", sans-serif;\n font-size: small;\n font-weight: 400;\n border-color: #2B81AF;\n border-style: solid;\n border-width: thin;\n border-radius: 4px;\n background-color: #2B81AF;\n}\n.igv-ui-alert-dialog-container > div:last-child div:hover {\n cursor: pointer;\n border-color: #25597f;\n background-color: #25597f;\n}\n\n.igv-ui-color-swatch {\n position: relative;\n box-sizing: content-box;\n display: flex;\n flex-flow: row;\n flex-wrap: wrap;\n justify-content: center;\n align-items: center;\n width: 32px;\n height: 32px;\n border-style: solid;\n border-width: 2px;\n border-color: white;\n border-radius: 4px;\n}\n\n.igv-ui-color-swatch:hover {\n border-color: dimgray;\n}\n\n.igv-ui-colorpicker-menu-close-button {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-end;\n align-items: center;\n width: 100%;\n height: 32px;\n margin-top: 4px;\n margin-bottom: 4px;\n padding-right: 8px;\n}\n.igv-ui-colorpicker-menu-close-button i.fa {\n display: block;\n margin-left: 4px;\n margin-right: 4px;\n color: #5f5f5f;\n}\n.igv-ui-colorpicker-menu-close-button i.fa:hover,\n.igv-ui-colorpicker-menu-close-button i.fa:focus,\n.igv-ui-colorpicker-menu-close-button i.fa:active {\n cursor: pointer;\n color: #0f0f0f;\n}\n\n.igv-ui-generic-dialog-container {\n box-sizing: content-box;\n position: fixed;\n top: 0;\n left: 0;\n width: 300px;\n height: 200px;\n border-color: #7F7F7F;\n border-radius: 4px;\n border-style: solid;\n border-width: thin;\n font-family: \"Open Sans\", sans-serif;\n font-size: medium;\n font-weight: 400;\n z-index: 2048;\n background-color: white;\n display: flex;\n flex-flow: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n}\n.igv-ui-generic-dialog-container .igv-ui-generic-dialog-header {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-end;\n align-items: center;\n width: 100%;\n height: 24px;\n cursor: move;\n border-top-left-radius: 4px;\n border-top-right-radius: 4px;\n border-bottom-color: #7F7F7F;\n border-bottom-style: solid;\n border-bottom-width: thin;\n background-color: #eee;\n}\n.igv-ui-generic-dialog-container .igv-ui-generic-dialog-header div {\n margin-right: 4px;\n margin-bottom: 2px;\n height: 12px;\n width: 12px;\n color: #7F7F7F;\n}\n.igv-ui-generic-dialog-container .igv-ui-generic-dialog-header div:hover {\n cursor: pointer;\n color: #444;\n}\n.igv-ui-generic-dialog-container .igv-ui-generic-dialog-one-liner {\n color: #373737;\n width: 95%;\n height: 24px;\n line-height: 24px;\n text-align: left;\n margin-top: 8px;\n padding-left: 8px;\n overflow-wrap: break-word;\n background-color: white;\n}\n.igv-ui-generic-dialog-container .igv-ui-generic-dialog-label-input {\n margin-top: 8px;\n width: 95%;\n height: 24px;\n color: #373737;\n line-height: 24px;\n padding-left: 8px;\n background-color: white;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n}\n.igv-ui-generic-dialog-container .igv-ui-generic-dialog-label-input div {\n width: 30%;\n height: 100%;\n font-size: 16px;\n text-align: right;\n padding-right: 8px;\n background-color: white;\n}\n.igv-ui-generic-dialog-container .igv-ui-generic-dialog-label-input input {\n display: block;\n height: 100%;\n width: 100%;\n padding-left: 4px;\n font-family: \"Open Sans\", sans-serif;\n font-weight: 400;\n color: #373737;\n text-align: left;\n outline: none;\n border-style: solid;\n border-width: thin;\n border-color: #7F7F7F;\n background-color: white;\n}\n.igv-ui-generic-dialog-container .igv-ui-generic-dialog-label-input input {\n width: 50%;\n font-size: 16px;\n}\n.igv-ui-generic-dialog-container .igv-ui-generic-dialog-input {\n margin-top: 8px;\n width: calc(100% - 16px);\n height: 24px;\n color: #373737;\n line-height: 24px;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-around;\n align-items: center;\n}\n.igv-ui-generic-dialog-container .igv-ui-generic-dialog-input input {\n display: block;\n height: 100%;\n width: 100%;\n padding-left: 4px;\n font-family: \"Open Sans\", sans-serif;\n font-weight: 400;\n color: #373737;\n text-align: left;\n outline: none;\n border-style: solid;\n border-width: thin;\n border-color: #7F7F7F;\n background-color: white;\n}\n.igv-ui-generic-dialog-container .igv-ui-generic-dialog-input input {\n font-size: 16px;\n}\n.igv-ui-generic-dialog-container .igv-ui-generic-dialog-ok-cancel {\n width: 100%;\n height: 28px;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-around;\n align-items: center;\n}\n.igv-ui-generic-dialog-container .igv-ui-generic-dialog-ok-cancel div {\n margin-top: 32px;\n color: white;\n font-family: \"Open Sans\", sans-serif;\n font-size: 14px;\n font-weight: 400;\n width: 75px;\n height: 28px;\n line-height: 28px;\n text-align: center;\n border-color: transparent;\n border-style: solid;\n border-width: thin;\n border-radius: 2px;\n}\n.igv-ui-generic-dialog-container .igv-ui-generic-dialog-ok-cancel div:first-child {\n margin-left: 32px;\n margin-right: 0;\n background-color: #5ea4e0;\n}\n.igv-ui-generic-dialog-container .igv-ui-generic-dialog-ok-cancel div:last-child {\n margin-left: 0;\n margin-right: 32px;\n background-color: #c4c4c4;\n}\n.igv-ui-generic-dialog-container .igv-ui-generic-dialog-ok-cancel div:first-child:hover {\n cursor: pointer;\n background-color: #3b5c7f;\n}\n.igv-ui-generic-dialog-container .igv-ui-generic-dialog-ok-cancel div:last-child:hover {\n cursor: pointer;\n background-color: #7f7f7f;\n}\n.igv-ui-generic-dialog-container .igv-ui-generic-dialog-ok {\n width: 100%;\n height: 36px;\n margin-top: 32px;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-around;\n align-items: center;\n}\n.igv-ui-generic-dialog-container .igv-ui-generic-dialog-ok div {\n width: 98px;\n height: 36px;\n line-height: 36px;\n text-align: center;\n color: white;\n font-family: \"Open Sans\", sans-serif;\n font-size: medium;\n font-weight: 400;\n border-color: white;\n border-style: solid;\n border-width: thin;\n border-radius: 4px;\n background-color: #2B81AF;\n}\n.igv-ui-generic-dialog-container .igv-ui-generic-dialog-ok div:hover {\n cursor: pointer;\n background-color: #25597f;\n}\n\n.igv-ui-generic-container {\n box-sizing: content-box;\n position: absolute;\n z-index: 2048;\n background-color: white;\n cursor: pointer;\n display: flex;\n flex-direction: row;\n flex-wrap: wrap;\n justify-content: flex-start;\n align-items: center;\n}\n.igv-ui-generic-container > div:first-child {\n cursor: move;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-end;\n align-items: center;\n height: 24px;\n width: 100%;\n background-color: #dddddd;\n}\n.igv-ui-generic-container > div:first-child > div {\n display: block;\n color: #5f5f5f;\n cursor: pointer;\n width: 14px;\n height: 14px;\n margin-right: 8px;\n margin-bottom: 4px;\n}\n\n.igv-ui-dialog {\n z-index: 2048;\n position: fixed;\n width: fit-content;\n height: fit-content;\n display: flex;\n flex-flow: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n background-color: white;\n border-color: #7F7F7F;\n border-radius: 4px;\n border-style: solid;\n border-width: thin;\n font-family: \"Open Sans\", sans-serif;\n font-size: medium;\n font-weight: 400;\n}\n.igv-ui-dialog .igv-ui-dialog-header {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-end;\n align-items: center;\n width: 100%;\n height: 24px;\n cursor: move;\n border-top-left-radius: 4px;\n border-top-right-radius: 4px;\n border-bottom-color: #7F7F7F;\n border-bottom-style: solid;\n border-bottom-width: thin;\n background-color: #eee;\n}\n.igv-ui-dialog .igv-ui-dialog-header div {\n margin-right: 4px;\n margin-bottom: 2px;\n height: 12px;\n width: 12px;\n color: #7F7F7F;\n}\n.igv-ui-dialog .igv-ui-dialog-header div:hover {\n cursor: pointer;\n color: #444;\n}\n.igv-ui-dialog .igv-ui-dialog-one-liner {\n width: 95%;\n height: 24px;\n line-height: 24px;\n text-align: left;\n margin: 8px;\n overflow-wrap: break-word;\n background-color: white;\n font-weight: bold;\n}\n.igv-ui-dialog .igv-ui-dialog-ok-cancel {\n width: 100%;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-around;\n align-items: center;\n}\n.igv-ui-dialog .igv-ui-dialog-ok-cancel div {\n margin: 16px;\n margin-top: 32px;\n color: white;\n font-family: \"Open Sans\", sans-serif;\n font-size: 14px;\n font-weight: 400;\n width: 75px;\n height: 28px;\n line-height: 28px;\n text-align: center;\n border-color: transparent;\n border-style: solid;\n border-width: thin;\n border-radius: 2px;\n}\n.igv-ui-dialog .igv-ui-dialog-ok-cancel div:first-child {\n background-color: #5ea4e0;\n}\n.igv-ui-dialog .igv-ui-dialog-ok-cancel div:last-child {\n background-color: #c4c4c4;\n}\n.igv-ui-dialog .igv-ui-dialog-ok-cancel div:first-child:hover {\n cursor: pointer;\n background-color: #3b5c7f;\n}\n.igv-ui-dialog .igv-ui-dialog-ok-cancel div:last-child:hover {\n cursor: pointer;\n background-color: #7f7f7f;\n}\n.igv-ui-dialog .igv-ui-dialog-ok {\n width: 100%;\n height: 36px;\n margin-top: 32px;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-around;\n align-items: center;\n}\n.igv-ui-dialog .igv-ui-dialog-ok div {\n width: 98px;\n height: 36px;\n line-height: 36px;\n text-align: center;\n color: white;\n font-family: \"Open Sans\", sans-serif;\n font-size: medium;\n font-weight: 400;\n border-color: white;\n border-style: solid;\n border-width: thin;\n border-radius: 4px;\n background-color: #2B81AF;\n}\n.igv-ui-dialog .igv-ui-dialog-ok div:hover {\n cursor: pointer;\n background-color: #25597f;\n}\n\n.igv-ui-panel, .igv-ui-panel-row, .igv-ui-panel-column {\n z-index: 2048;\n background-color: white;\n font-family: \"Open Sans\", sans-serif;\n font-size: medium;\n font-weight: 400;\n display: flex;\n justify-content: flex-start;\n align-items: flex-start;\n}\n\n.igv-ui-panel-column {\n display: flex;\n flex-direction: column;\n}\n\n.igv-ui-panel-row {\n display: flex;\n flex-direction: row;\n}\n\n.igv-ui-textbox {\n background-color: white;\n font-family: \"Open Sans\", sans-serif;\n font-size: medium;\n font-weight: 400;\n display: flex;\n justify-content: flex-start;\n align-items: flex-start;\n}\n\n.igv-ui-table {\n background-color: white;\n}\n\n.igv-ui-table thead {\n position: sticky;\n top: 0;\n}\n\n.igv-ui-table th {\n text-align: left;\n}\n\n.igv-ui-table td {\n padding-right: 20px;\n}\n\n.igv-ui-table tr:hover {\n background-color: lightblue;\n}\n\n/*# sourceMappingURL=igv-ui.css.map */\n`;\n document.head.append(style);\n}\n\nif (typeof document !== 'undefined') {\n\n if (!stylesheetExists(\"igv-ui.css\")) {\n embedCSS$2();\n }\n\n function stylesheetExists(stylesheetName) {\n for (let ss of document.styleSheets) {\n ss = ss.href ? ss.href.replace(/^.*[\\\\\\/]/, '') : '';\n if (ss === stylesheetName) {\n return true\n }\n }\n return false\n }\n}\n\nfunction createCheckbox(name, initialState) {\n\n const container = domUtils.div({class: 'igv-menu-popup-check-container'});\n\n const div = domUtils.div();\n container.appendChild(div);\n\n const svg = icons$1.createIcon('check', (true === initialState ? '#444' : 'transparent'));\n div.appendChild(svg);\n\n const label = domUtils.div();\n label.innerText = name;\n container.appendChild(label);\n\n return container\n}\n\n/**\n * Configure item list for track \"gear\" menu.\n * @param trackView\n */\nconst MenuUtils = {\n\n trackMenuItemList: function (trackView) {\n\n const vizWindowTypes = new Set(['alignment', 'annotation', 'variant', 'eqtl', 'snp']);\n\n const hasVizWindow = trackView.track.config && trackView.track.config.visibilityWindow !== undefined;\n\n let menuItems = [];\n\n if (trackView.track.config.type !== 'sequence') {\n menuItems.push(trackRenameMenuItem(trackView));\n menuItems.push(trackHeightMenuItem(trackView));\n }\n\n if (this.showColorPicker(trackView.track)) {\n menuItems.push('
');\n menuItems.push(colorPickerMenuItem({trackView, label: \"Set track color\", option: \"color\"}));\n menuItems.push(unsetColorMenuItem({trackView, label: \"Unset track color\"}));\n if(trackView.track.config.type === 'wig' || trackView.track.config.type === 'annotation') {\n menuItems.push(colorPickerMenuItem({trackView, label: \"Set alt color\", option: \"altColor\"}));\n menuItems.push(unsetAltColorMenuItem({trackView, label: \"Unset alt color\"}));\n }\n }\n\n if (trackView.track.menuItemList) {\n menuItems = menuItems.concat(trackView.track.menuItemList());\n }\n\n if (hasVizWindow || vizWindowTypes.has(trackView.track.type)) {\n menuItems.push('
');\n menuItems.push(visibilityWindowMenuItem(trackView));\n }\n\n if (trackView.track.removable !== false) {\n menuItems.push('
');\n menuItems.push(trackRemovalMenuItem(trackView));\n }\n\n return menuItems\n },\n\n numericDataMenuItems: function (trackView) {\n\n const menuItems = [];\n\n menuItems.push('
');\n\n // Data range\n const object = $$1('
');\n object.text('Set data range');\n\n const click = () => {\n trackView.browser.dataRangeDialog.configure(trackView);\n trackView.browser.dataRangeDialog.present($$1(trackView.browser.columnContainer));\n };\n menuItems.push({object, click});\n\n if (trackView.track.logScale !== undefined) {\n menuItems.push({\n object: $$1(createCheckbox(\"Log scale\", trackView.track.logScale)),\n click: () => {\n trackView.track.logScale = !trackView.track.logScale;\n trackView.repaintViews();\n }\n }\n );\n }\n\n menuItems.push({\n object: $$1(createCheckbox(\"Autoscale\", trackView.track.autoscale)),\n click: () => {\n trackView.track.autoscale = !trackView.track.autoscale;\n trackView.updateViews();\n }\n }\n );\n\n\n return menuItems\n },\n\n trackMenuItemListHelper: function (itemList, menuPopup) {\n\n var list = [];\n\n if (itemList.length > 0) {\n\n list = itemList.map(function (item, i) {\n var $e;\n\n // name and object fields checked for backward compatibility\n if (item.name) {\n $e = $$1('
');\n $e.text(item.name);\n } else if (item.object) {\n $e = item.object;\n } else if (typeof item.label === 'string') {\n $e = $$1('
');\n $e.html(item.label);\n } else if (typeof item === 'string') {\n\n if (item.startsWith(\"<\")) {\n $e = $$1(item);\n } else {\n $e = $$1(\"
\" + item + \"
\");\n }\n }\n\n if (0 === i) {\n $e.addClass('igv-track-menu-border-top');\n }\n\n if (item.click) {\n $e.on('click', handleClick);\n $e.on('touchend', function (e) {\n handleClick(e);\n });\n $e.on('mouseup', function (e) {\n e.preventDefault();\n e.stopPropagation();\n });\n\n // eslint-disable-next-line no-inner-declarations\n function handleClick(e) {\n item.click(e);\n menuPopup.hide();\n e.preventDefault();\n e.stopPropagation();\n }\n }\n\n return {object: $e, init: (item.init || undefined)}\n });\n }\n\n return list\n },\n\n showColorPicker(track) {\n return (\n undefined === track.type ||\n \"bedtype\" === track.type ||\n \"alignment\" === track.type ||\n \"annotation\" === track.type ||\n \"variant\" === track.type ||\n \"wig\" === track.type) ||\n 'interact' === track.type\n },\n\n createMenuItem(label, action) {\n const object = $$1('
');\n object.text(label);\n return {object, click: action}\n }\n};\n\n\nfunction visibilityWindowMenuItem(trackView) {\n\n const click = e => {\n\n const callback = () => {\n\n let value = trackView.browser.inputDialog.value;\n value = '' === value || undefined === value ? -1 : value.trim();\n\n trackView.track.visibilityWindow = Number.parseInt(value);\n trackView.track.config.visibilityWindow = Number.parseInt(value);\n\n trackView.updateViews();\n };\n\n const config =\n {\n label: 'Visibility Window',\n value: (trackView.track.visibilityWindow),\n callback\n };\n trackView.browser.inputDialog.present(config, e);\n\n };\n\n const object = $$1('
');\n object.text('Set visibility window');\n return {object, click}\n\n}\n\nfunction trackRemovalMenuItem(trackView) {\n\n const object = $$1('
');\n object.text('Remove track');\n\n return {object, click: () => trackView.browser.removeTrack(trackView.track)}\n\n}\n\nfunction colorPickerMenuItem({trackView, label, option}) {\n\n const $e = $$1('
');\n $e.text(label);\n\n return {\n object: $e,\n click: () => trackView.presentColorPicker(option)\n }\n}\n\nfunction unsetColorMenuItem({trackView, label}) {\n\n const $e = $$1('
');\n $e.text(label);\n\n return {\n object: $e,\n click: () => {\n trackView.track.color = undefined;\n trackView.repaintViews();\n }\n }\n}\n\nfunction unsetAltColorMenuItem({trackView, label}) {\n\n const $e = $$1('
');\n $e.text(label);\n\n return {\n object: $e,\n click: () => {\n trackView.track.altColor = undefined;\n trackView.repaintViews();\n }\n }\n}\n\nfunction trackRenameMenuItem(trackView) {\n\n const click = e => {\n\n const callback = function () {\n let value = trackView.browser.inputDialog.value;\n value = ('' === value || undefined === value) ? 'untitled' : value.trim();\n trackView.track.name = value;\n };\n\n const config =\n {\n label: 'Track Name',\n value: (getTrackLabelText(trackView.track) || 'unnamed'),\n callback\n };\n\n trackView.browser.inputDialog.present(config, e);\n\n };\n\n const object = $$1('
');\n object.text('Set track name');\n return {object, click}\n\n\n}\n\nfunction trackHeightMenuItem(trackView) {\n\n const click = e => {\n\n const callback = () => {\n\n const number = Number(trackView.browser.inputDialog.value, 10);\n\n if (undefined !== number) {\n\n // If explicitly setting the height adust min or max, if neccessary.\n if (trackView.track.minHeight !== undefined && trackView.track.minHeight > number) {\n trackView.track.minHeight = number;\n }\n if (trackView.track.maxHeight !== undefined && trackView.track.maxHeight < number) {\n trackView.track.minHeight = number;\n }\n trackView.setTrackHeight(number, true);\n\n trackView.checkContentHeight();\n trackView.repaintViews();\n\n\n // Explicitly setting track height turns off autoHeight\n trackView.track.autoHeight = false;\n }\n\n };\n\n const config =\n {\n label: 'Track Height',\n value: trackView.track.height,\n callback\n };\n\n trackView.browser.inputDialog.present(config, e);\n\n };\n\n const object = $$1('
');\n object.text('Set track height');\n return {object, click}\n\n\n}\n\nfunction getTrackLabelText(track) {\n var vp,\n txt;\n\n vp = track.trackView.viewports[0];\n txt = vp.$trackLabel.text();\n\n return txt\n}\n\nclass DataRangeDialog {\n\n constructor(browser, $parent, alert) {\n\n this.browser = browser;\n\n // dialog container\n this.$container = $$1(\"
\", {class: 'igv-generic-dialog-container'});\n $parent.append(this.$container);\n this.$container.offset({left: 0, top: 0});\n\n // dialog header\n const $header = $$1(\"
\", {class: 'igv-generic-dialog-header'});\n this.$container.append($header);\n uiUtils.attachDialogCloseHandlerWithParent($header[0], () => {\n this.$minimum_input.val(undefined);\n this.$maximum_input.val(undefined);\n this.$container.offset({left: 0, top: 0});\n this.$container.hide();\n });\n\n\n // minimun\n this.$minimum = $$1(\"
\", {class: 'igv-generic-dialog-label-input'});\n this.$container.append(this.$minimum);\n const $mindiv = $$1('
');\n $mindiv.text('Minimum');\n this.$minimum.append($mindiv);\n this.$minimum_input = $$1(\"\");\n this.$minimum.append(this.$minimum_input);\n\n\n // maximum\n this.$maximum = $$1(\"
\", {class: 'igv-generic-dialog-label-input'});\n this.$container.append(this.$maximum);\n const $maxdiv = $$1('
');\n $maxdiv.text('Maximum');\n this.$maximum.append($maxdiv);\n this.$maximum_input = $$1(\"\");\n this.$maximum.append(this.$maximum_input);\n\n // ok | cancel\n const $buttons = $$1(\"
\", {class: 'igv-generic-dialog-ok-cancel'});\n this.$container.append($buttons);\n\n // ok\n this.$ok = $$1(\"
\");\n $buttons.append(this.$ok);\n this.$ok.text('OK');\n\n // cancel\n this.$cancel = $$1(\"
\");\n $buttons.append(this.$cancel);\n this.$cancel.text('Cancel');\n\n this.$cancel.on('click', () => {\n this.$minimum_input.val(undefined);\n this.$maximum_input.val(undefined);\n this.$container.offset({left: 0, top: 0});\n this.$container.hide();\n });\n\n //this.$container.draggable({ handle:$header.get(0) });\n makeDraggable(this.$container.get(0), $header.get(0));\n\n this.$container.hide();\n }\n\n configure(trackView) {\n\n const dataRange = trackView.dataRange();\n let min;\n let max;\n if (dataRange) {\n min = dataRange.min;\n max = dataRange.max;\n } else {\n min = 0;\n max = 100;\n }\n\n this.$minimum_input.val(min);\n this.$maximum_input.val(max);\n\n this.$minimum_input.unbind();\n this.$minimum_input.on('keyup', (e) => {\n if (13 === e.keyCode) {\n this.processResults(trackView);\n }\n });\n\n this.$maximum_input.unbind();\n this.$maximum_input.on('keyup', (e) => {\n if (13 === e.keyCode) {\n this.processResults(trackView);\n }\n });\n\n this.$ok.unbind();\n this.$ok.on('click', (e) => {\n this.processResults(trackView);\n });\n }\n\n\n processResults(trackView) {\n\n const min = Number(this.$minimum_input.val());\n const max = Number(this.$maximum_input.val());\n if (isNaN(min) || isNaN(max)) {\n this.browser.alert.present(new Error('Must input numeric values'), undefined);\n } else {\n trackView.setDataRange(min, max);\n }\n\n this.$minimum_input.val(undefined);\n this.$maximum_input.val(undefined);\n this.$container.offset({left: 0, top: 0});\n this.$container.hide();\n }\n\n present($parent) {\n\n const offset_top = $parent.offset().top;\n const scroll_top = $$1('body').scrollTop();\n\n this.$container.offset({left: $parent.width() - this.$container.width(), top: (offset_top + scroll_top)});\n this.$container.show();\n }\n}\n\n/**\n * Covers string literals and String objects\n * @param x\n * @returns {boolean}\n */\nfunction isString$2(x) {\n return typeof x === \"string\" || x instanceof String\n}\n\n\n// StackOverflow: http://stackoverflow.com/a/10810674/116169\nfunction numberFormatter$1(rawNumber) {\n\n var dec = String(rawNumber).split(/[.,]/),\n sep = ',',\n decsep = '.';\n\n return dec[0].split('').reverse().reduce(function (prev, now, i) {\n return i % 3 === 0 ? prev + sep + now : prev + now;\n }).split('').reverse().join('') + (dec[1] ? decsep + dec[1] : '');\n}\n\nconst splitLines$5 = function (string) {\n return string.split(/\\n|\\r\\n|\\r/g);\n};\n\n\nfunction splitStringRespectingQuotes(string, delim) {\n\n var tokens = [],\n len = string.length,\n i,\n n = 0,\n quote = false,\n c;\n\n if (len > 0) {\n\n tokens[n] = string.charAt(0);\n for (i = 1; i < len; i++) {\n c = string.charAt(i);\n if (c === '\"') {\n quote = !quote;\n } else if (!quote && c === delim) {\n n++;\n tokens[n] = \"\";\n } else {\n tokens[n] += c;\n }\n }\n }\n return tokens;\n}\n\nfunction stripQuotes$1(str) {\n if(str === undefined) {\n return str;\n }\n if(str.startsWith(\"'\") || str.startsWith('\"')) {\n str = str.substring(1);\n }\n if (str.endsWith(\"'\") || str.endsWith('\"')) {\n str = str.substring(0, str.length - 1);\n }\n return str;\n}\n\nfunction capitalize(str) {\n return str.length > 0 ? str.charAt(0).toUpperCase() + str.slice(1) : str;\n}\n\n\n/**\n * Parse a locus string and return a range object. Locus string is of the form chr:start-end. End is optional\n *\n */\nfunction parseLocusString$1(string) {\n\n const t1 = string.split(\":\");\n const t2 = t1[1].split(\"-\");\n\n const range = {\n chr: t1[0],\n start: Number.parseInt(t2[0].replace(/,/g, '')) - 1\n };\n\n if (t2.length > 1) {\n range.end = Number.parseInt(t2[1].replace(/,/g, ''));\n } else {\n range.end = range.start + 1;\n }\n\n return range;\n}\n\n/**\n * Return the filename from the path. Example\n * https://foo.com/bar.bed?param=2 => bar.bed\n * @param urlOrFile\n */\n\nfunction getFilename$2(urlOrFile) {\n\n if (urlOrFile.name !== undefined) {\n return urlOrFile.name\n } else if (isString$2(urlOrFile)) {\n\n let index = urlOrFile.lastIndexOf(\"/\");\n let filename = index < 0 ? urlOrFile : urlOrFile.substr(index + 1);\n\n //Strip parameters -- handle local files later\n index = filename.indexOf(\"?\");\n if (index > 0) {\n filename = filename.substr(0, index);\n }\n return filename\n } else {\n throw Error(`Expected File or string, got ${typeof urlOrFile}`)\n }\n}\n\n\n/**\n * Test if object is a File or File-like object.\n *\n * @param object\n */\nfunction isFile(object) {\n if(!object) {\n return false;\n }\n return typeof object !== 'function' &&\n (object instanceof File ||\n (object.hasOwnProperty(\"name\") && typeof object.slice === 'function' && typeof object.arrayBuffer === 'function'))\n}\n\nfunction download(filename, data) {\n\n const element = document.createElement('a');\n element.setAttribute('href', data);\n element.setAttribute('download', filename);\n element.style.display = 'none';\n document.body.appendChild(element);\n element.click();\n document.body.removeChild(element);\n}\n\nif (typeof process === 'object' && typeof window === 'undefined') {\n global.atob = function (str) {\n return Buffer.from(str, 'base64').toString('binary');\n };\n}\n\n\nfunction parseUri(str) {\n\n var o = options,\n m = o.parser[\"loose\"].exec(str),\n uri = {},\n i = 14;\n\n while (i--) uri[o.key[i]] = m[i] || \"\";\n\n uri[o.q.name] = {};\n uri[o.key[12]].replace(o.q.parser, function ($0, $1, $2) {\n if ($1) uri[o.q.name][$1] = $2;\n });\n\n return uri;\n}\n\nconst options = {\n strictMode: false,\n key: [\"source\", \"protocol\", \"authority\", \"userInfo\", \"user\", \"password\", \"host\", \"port\", \"relative\", \"path\", \"directory\", \"file\", \"query\", \"anchor\"],\n q: {\n name: \"queryKey\",\n parser: /(?:^|&)([^&=]*)=?([^&]*)/g\n },\n parser: {\n strict: /^(?:([^:\\/?#]+):)?(?:\\/\\/((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\\/?#]*)(?::(\\d*))?))?((((?:[^?#\\/]*\\/)*)([^?#]*))(?:\\?([^#]*))?(?:#(.*))?)/,\n loose: /^(?:(?![^:@]+:[^:@\\/]*@)([^:\\/?#.]+):)?(?:\\/\\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\\/?#]*)(?::(\\d*))?)(((\\/(?:[^?#](?![^?#\\/]*\\.[^?#\\/.]+(?:[?#]|$)))*\\/?)?([^?#\\/]*))(?:\\?([^#]*))?(?:#(.*))?)/\n }\n};\n\n/**\n * Resolve a url, which might be a string, function (that returns a string or Promse), or Promise (that resolves to a string)\n *\n * @param url\n * @returns {Promise<*>}\n */\nasync function resolveURL(url) {\n return (typeof url === 'function') ? url() : url;\n}\n\n/*! pako 2.1.0 https://github.com/nodeca/pako @license (MIT AND Zlib) */\n// (C) 1995-2013 Jean-loup Gailly and Mark Adler\n// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin\n//\n// This software is provided 'as-is', without any express or implied\n// warranty. In no event will the authors be held liable for any damages\n// arising from the use of this software.\n//\n// Permission is granted to anyone to use this software for any purpose,\n// including commercial applications, and to alter it and redistribute it\n// freely, subject to the following restrictions:\n//\n// 1. The origin of this software must not be misrepresented; you must not\n// claim that you wrote the original software. If you use this software\n// in a product, an acknowledgment in the product documentation would be\n// appreciated but is not required.\n// 2. Altered source versions must be plainly marked as such, and must not be\n// misrepresented as being the original software.\n// 3. This notice may not be removed or altered from any source distribution.\n\n/* eslint-disable space-unary-ops */\n\n/* Public constants ==========================================================*/\n/* ===========================================================================*/\n\n\n//const Z_FILTERED = 1;\n//const Z_HUFFMAN_ONLY = 2;\n//const Z_RLE = 3;\nconst Z_FIXED$1 = 4;\n//const Z_DEFAULT_STRATEGY = 0;\n\n/* Possible values of the data_type field (though see inflate()) */\nconst Z_BINARY = 0;\nconst Z_TEXT = 1;\n//const Z_ASCII = 1; // = Z_TEXT\nconst Z_UNKNOWN$1 = 2;\n\n/*============================================================================*/\n\n\nfunction zero$1$1(buf) { let len = buf.length; while (--len >= 0) { buf[len] = 0; } }\n\n// From zutil.h\n\nconst STORED_BLOCK = 0;\nconst STATIC_TREES = 1;\nconst DYN_TREES = 2;\n/* The three kinds of block type */\n\nconst MIN_MATCH$1$1 = 3;\nconst MAX_MATCH$1$1 = 258;\n/* The minimum and maximum match lengths */\n\n// From deflate.h\n/* ===========================================================================\n * Internal compression state.\n */\n\nconst LENGTH_CODES$1$1 = 29;\n/* number of length codes, not counting the special END_BLOCK code */\n\nconst LITERALS$1$1 = 256;\n/* number of literal bytes 0..255 */\n\nconst L_CODES$1$1 = LITERALS$1$1 + 1 + LENGTH_CODES$1$1;\n/* number of Literal or Length codes, including the END_BLOCK code */\n\nconst D_CODES$1$1 = 30;\n/* number of distance codes */\n\nconst BL_CODES$1 = 19;\n/* number of codes used to transfer the bit lengths */\n\nconst HEAP_SIZE$1 = 2 * L_CODES$1$1 + 1;\n/* maximum heap size */\n\nconst MAX_BITS$1 = 15;\n/* All codes must not exceed MAX_BITS bits */\n\nconst Buf_size = 16;\n/* size of bit buffer in bi_buf */\n\n\n/* ===========================================================================\n * Constants\n */\n\nconst MAX_BL_BITS = 7;\n/* Bit length codes must not exceed MAX_BL_BITS bits */\n\nconst END_BLOCK = 256;\n/* end of block literal code */\n\nconst REP_3_6 = 16;\n/* repeat previous bit length 3-6 times (2 bits of repeat count) */\n\nconst REPZ_3_10 = 17;\n/* repeat a zero length 3-10 times (3 bits of repeat count) */\n\nconst REPZ_11_138 = 18;\n/* repeat a zero length 11-138 times (7 bits of repeat count) */\n\n/* eslint-disable comma-spacing,array-bracket-spacing */\nconst extra_lbits = /* extra bits for each length code */\n new Uint8Array([0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0]);\n\nconst extra_dbits = /* extra bits for each distance code */\n new Uint8Array([0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13]);\n\nconst extra_blbits = /* extra bits for each bit length code */\n new Uint8Array([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7]);\n\nconst bl_order =\n new Uint8Array([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]);\n/* eslint-enable comma-spacing,array-bracket-spacing */\n\n/* The lengths of the bit length codes are sent in order of decreasing\n * probability, to avoid transmitting the lengths for unused bit length codes.\n */\n\n/* ===========================================================================\n * Local data. These are initialized only once.\n */\n\n// We pre-fill arrays with 0 to avoid uninitialized gaps\n\nconst DIST_CODE_LEN$1 = 512; /* see definition of array dist_code below */\n\n// !!!! Use flat array instead of structure, Freq = i*2, Len = i*2+1\nconst static_ltree$1 = new Array((L_CODES$1$1 + 2) * 2);\nzero$1$1(static_ltree$1);\n/* The static literal tree. Since the bit lengths are imposed, there is no\n * need for the L_CODES extra codes used during heap construction. However\n * The codes 286 and 287 are needed to build a canonical tree (see _tr_init\n * below).\n */\n\nconst static_dtree$1 = new Array(D_CODES$1$1 * 2);\nzero$1$1(static_dtree$1);\n/* The static distance tree. (Actually a trivial tree since all codes use\n * 5 bits.)\n */\n\nconst _dist_code$1 = new Array(DIST_CODE_LEN$1);\nzero$1$1(_dist_code$1);\n/* Distance codes. The first 256 values correspond to the distances\n * 3 .. 258, the last 256 values correspond to the top 8 bits of\n * the 15 bit distances.\n */\n\nconst _length_code$1 = new Array(MAX_MATCH$1$1 - MIN_MATCH$1$1 + 1);\nzero$1$1(_length_code$1);\n/* length code for each normalized match length (0 == MIN_MATCH) */\n\nconst base_length$1 = new Array(LENGTH_CODES$1$1);\nzero$1$1(base_length$1);\n/* First normalized length for each code (0 = MIN_MATCH) */\n\nconst base_dist$1 = new Array(D_CODES$1$1);\nzero$1$1(base_dist$1);\n/* First normalized distance for each code (0 = distance of 1) */\n\n\nfunction StaticTreeDesc(static_tree, extra_bits, extra_base, elems, max_length) {\n\n this.static_tree = static_tree; /* static tree or NULL */\n this.extra_bits = extra_bits; /* extra bits for each code or NULL */\n this.extra_base = extra_base; /* base index for extra_bits */\n this.elems = elems; /* max number of elements in the tree */\n this.max_length = max_length; /* max bit length for the codes */\n\n // show if `static_tree` has data or dummy - needed for monomorphic objects\n this.has_stree = static_tree && static_tree.length;\n}\n\n\nlet static_l_desc;\nlet static_d_desc;\nlet static_bl_desc;\n\n\nfunction TreeDesc(dyn_tree, stat_desc) {\n this.dyn_tree = dyn_tree; /* the dynamic tree */\n this.max_code = 0; /* largest code with non zero frequency */\n this.stat_desc = stat_desc; /* the corresponding static tree */\n}\n\n\n\nconst d_code = (dist) => {\n\n return dist < 256 ? _dist_code$1[dist] : _dist_code$1[256 + (dist >>> 7)];\n};\n\n\n/* ===========================================================================\n * Output a short LSB first on the stream.\n * IN assertion: there is enough room in pendingBuf.\n */\nconst put_short = (s, w) => {\n// put_byte(s, (uch)((w) & 0xff));\n// put_byte(s, (uch)((ush)(w) >> 8));\n s.pending_buf[s.pending++] = (w) & 0xff;\n s.pending_buf[s.pending++] = (w >>> 8) & 0xff;\n};\n\n\n/* ===========================================================================\n * Send a value on a given number of bits.\n * IN assertion: length <= 16 and value fits in length bits.\n */\nconst send_bits = (s, value, length) => {\n\n if (s.bi_valid > (Buf_size - length)) {\n s.bi_buf |= (value << s.bi_valid) & 0xffff;\n put_short(s, s.bi_buf);\n s.bi_buf = value >> (Buf_size - s.bi_valid);\n s.bi_valid += length - Buf_size;\n } else {\n s.bi_buf |= (value << s.bi_valid) & 0xffff;\n s.bi_valid += length;\n }\n};\n\n\nconst send_code = (s, c, tree) => {\n\n send_bits(s, tree[c * 2]/*.Code*/, tree[c * 2 + 1]/*.Len*/);\n};\n\n\n/* ===========================================================================\n * Reverse the first len bits of a code, using straightforward code (a faster\n * method would use a table)\n * IN assertion: 1 <= len <= 15\n */\nconst bi_reverse = (code, len) => {\n\n let res = 0;\n do {\n res |= code & 1;\n code >>>= 1;\n res <<= 1;\n } while (--len > 0);\n return res >>> 1;\n};\n\n\n/* ===========================================================================\n * Flush the bit buffer, keeping at most 7 bits in it.\n */\nconst bi_flush = (s) => {\n\n if (s.bi_valid === 16) {\n put_short(s, s.bi_buf);\n s.bi_buf = 0;\n s.bi_valid = 0;\n\n } else if (s.bi_valid >= 8) {\n s.pending_buf[s.pending++] = s.bi_buf & 0xff;\n s.bi_buf >>= 8;\n s.bi_valid -= 8;\n }\n};\n\n\n/* ===========================================================================\n * Compute the optimal bit lengths for a tree and update the total bit length\n * for the current block.\n * IN assertion: the fields freq and dad are set, heap[heap_max] and\n * above are the tree nodes sorted by increasing frequency.\n * OUT assertions: the field len is set to the optimal bit length, the\n * array bl_count contains the frequencies for each bit length.\n * The length opt_len is updated; static_len is also updated if stree is\n * not null.\n */\nconst gen_bitlen = (s, desc) => {\n// deflate_state *s;\n// tree_desc *desc; /* the tree descriptor */\n\n const tree = desc.dyn_tree;\n const max_code = desc.max_code;\n const stree = desc.stat_desc.static_tree;\n const has_stree = desc.stat_desc.has_stree;\n const extra = desc.stat_desc.extra_bits;\n const base = desc.stat_desc.extra_base;\n const max_length = desc.stat_desc.max_length;\n let h; /* heap index */\n let n, m; /* iterate over the tree elements */\n let bits; /* bit length */\n let xbits; /* extra bits */\n let f; /* frequency */\n let overflow = 0; /* number of elements with bit length too large */\n\n for (bits = 0; bits <= MAX_BITS$1; bits++) {\n s.bl_count[bits] = 0;\n }\n\n /* In a first pass, compute the optimal bit lengths (which may\n * overflow in the case of the bit length tree).\n */\n tree[s.heap[s.heap_max] * 2 + 1]/*.Len*/ = 0; /* root of the heap */\n\n for (h = s.heap_max + 1; h < HEAP_SIZE$1; h++) {\n n = s.heap[h];\n bits = tree[tree[n * 2 + 1]/*.Dad*/ * 2 + 1]/*.Len*/ + 1;\n if (bits > max_length) {\n bits = max_length;\n overflow++;\n }\n tree[n * 2 + 1]/*.Len*/ = bits;\n /* We overwrite tree[n].Dad which is no longer needed */\n\n if (n > max_code) { continue; } /* not a leaf node */\n\n s.bl_count[bits]++;\n xbits = 0;\n if (n >= base) {\n xbits = extra[n - base];\n }\n f = tree[n * 2]/*.Freq*/;\n s.opt_len += f * (bits + xbits);\n if (has_stree) {\n s.static_len += f * (stree[n * 2 + 1]/*.Len*/ + xbits);\n }\n }\n if (overflow === 0) { return; }\n\n // Tracev((stderr,\"\\nbit length overflow\\n\"));\n /* This happens for example on obj2 and pic of the Calgary corpus */\n\n /* Find the first bit length which could increase: */\n do {\n bits = max_length - 1;\n while (s.bl_count[bits] === 0) { bits--; }\n s.bl_count[bits]--; /* move one leaf down the tree */\n s.bl_count[bits + 1] += 2; /* move one overflow item as its brother */\n s.bl_count[max_length]--;\n /* The brother of the overflow item also moves one step up,\n * but this does not affect bl_count[max_length]\n */\n overflow -= 2;\n } while (overflow > 0);\n\n /* Now recompute all bit lengths, scanning in increasing frequency.\n * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all\n * lengths instead of fixing only the wrong ones. This idea is taken\n * from 'ar' written by Haruhiko Okumura.)\n */\n for (bits = max_length; bits !== 0; bits--) {\n n = s.bl_count[bits];\n while (n !== 0) {\n m = s.heap[--h];\n if (m > max_code) { continue; }\n if (tree[m * 2 + 1]/*.Len*/ !== bits) {\n // Tracev((stderr,\"code %d bits %d->%d\\n\", m, tree[m].Len, bits));\n s.opt_len += (bits - tree[m * 2 + 1]/*.Len*/) * tree[m * 2]/*.Freq*/;\n tree[m * 2 + 1]/*.Len*/ = bits;\n }\n n--;\n }\n }\n};\n\n\n/* ===========================================================================\n * Generate the codes for a given tree and bit counts (which need not be\n * optimal).\n * IN assertion: the array bl_count contains the bit length statistics for\n * the given tree and the field len is set for all tree elements.\n * OUT assertion: the field code is set for all tree elements of non\n * zero code length.\n */\nconst gen_codes = (tree, max_code, bl_count) => {\n// ct_data *tree; /* the tree to decorate */\n// int max_code; /* largest code with non zero frequency */\n// ushf *bl_count; /* number of codes at each bit length */\n\n const next_code = new Array(MAX_BITS$1 + 1); /* next code value for each bit length */\n let code = 0; /* running code value */\n let bits; /* bit index */\n let n; /* code index */\n\n /* The distribution counts are first used to generate the code values\n * without bit reversal.\n */\n for (bits = 1; bits <= MAX_BITS$1; bits++) {\n code = (code + bl_count[bits - 1]) << 1;\n next_code[bits] = code;\n }\n /* Check that the bit counts in bl_count are consistent. The last code\n * must be all ones.\n */\n //Assert (code + bl_count[MAX_BITS]-1 == (1< {\n\n let n; /* iterates over tree elements */\n let bits; /* bit counter */\n let length; /* length value */\n let code; /* code value */\n let dist; /* distance index */\n const bl_count = new Array(MAX_BITS$1 + 1);\n /* number of codes at each bit length for an optimal tree */\n\n // do check in _tr_init()\n //if (static_init_done) return;\n\n /* For some embedded targets, global variables are not initialized: */\n/*#ifdef NO_INIT_GLOBAL_POINTERS\n static_l_desc.static_tree = static_ltree;\n static_l_desc.extra_bits = extra_lbits;\n static_d_desc.static_tree = static_dtree;\n static_d_desc.extra_bits = extra_dbits;\n static_bl_desc.extra_bits = extra_blbits;\n#endif*/\n\n /* Initialize the mapping length (0..255) -> length code (0..28) */\n length = 0;\n for (code = 0; code < LENGTH_CODES$1$1 - 1; code++) {\n base_length$1[code] = length;\n for (n = 0; n < (1 << extra_lbits[code]); n++) {\n _length_code$1[length++] = code;\n }\n }\n //Assert (length == 256, \"tr_static_init: length != 256\");\n /* Note that the length 255 (match length 258) can be represented\n * in two different ways: code 284 + 5 bits or code 285, so we\n * overwrite length_code[255] to use the best encoding:\n */\n _length_code$1[length - 1] = code;\n\n /* Initialize the mapping dist (0..32K) -> dist code (0..29) */\n dist = 0;\n for (code = 0; code < 16; code++) {\n base_dist$1[code] = dist;\n for (n = 0; n < (1 << extra_dbits[code]); n++) {\n _dist_code$1[dist++] = code;\n }\n }\n //Assert (dist == 256, \"tr_static_init: dist != 256\");\n dist >>= 7; /* from now on, all distances are divided by 128 */\n for (; code < D_CODES$1$1; code++) {\n base_dist$1[code] = dist << 7;\n for (n = 0; n < (1 << (extra_dbits[code] - 7)); n++) {\n _dist_code$1[256 + dist++] = code;\n }\n }\n //Assert (dist == 256, \"tr_static_init: 256+dist != 512\");\n\n /* Construct the codes of the static literal tree */\n for (bits = 0; bits <= MAX_BITS$1; bits++) {\n bl_count[bits] = 0;\n }\n\n n = 0;\n while (n <= 143) {\n static_ltree$1[n * 2 + 1]/*.Len*/ = 8;\n n++;\n bl_count[8]++;\n }\n while (n <= 255) {\n static_ltree$1[n * 2 + 1]/*.Len*/ = 9;\n n++;\n bl_count[9]++;\n }\n while (n <= 279) {\n static_ltree$1[n * 2 + 1]/*.Len*/ = 7;\n n++;\n bl_count[7]++;\n }\n while (n <= 287) {\n static_ltree$1[n * 2 + 1]/*.Len*/ = 8;\n n++;\n bl_count[8]++;\n }\n /* Codes 286 and 287 do not exist, but we must include them in the\n * tree construction to get a canonical Huffman tree (longest code\n * all ones)\n */\n gen_codes(static_ltree$1, L_CODES$1$1 + 1, bl_count);\n\n /* The static distance tree is trivial: */\n for (n = 0; n < D_CODES$1$1; n++) {\n static_dtree$1[n * 2 + 1]/*.Len*/ = 5;\n static_dtree$1[n * 2]/*.Code*/ = bi_reverse(n, 5);\n }\n\n // Now data ready and we can init static trees\n static_l_desc = new StaticTreeDesc(static_ltree$1, extra_lbits, LITERALS$1$1 + 1, L_CODES$1$1, MAX_BITS$1);\n static_d_desc = new StaticTreeDesc(static_dtree$1, extra_dbits, 0, D_CODES$1$1, MAX_BITS$1);\n static_bl_desc = new StaticTreeDesc(new Array(0), extra_blbits, 0, BL_CODES$1, MAX_BL_BITS);\n\n //static_init_done = true;\n};\n\n\n/* ===========================================================================\n * Initialize a new block.\n */\nconst init_block = (s) => {\n\n let n; /* iterates over tree elements */\n\n /* Initialize the trees. */\n for (n = 0; n < L_CODES$1$1; n++) { s.dyn_ltree[n * 2]/*.Freq*/ = 0; }\n for (n = 0; n < D_CODES$1$1; n++) { s.dyn_dtree[n * 2]/*.Freq*/ = 0; }\n for (n = 0; n < BL_CODES$1; n++) { s.bl_tree[n * 2]/*.Freq*/ = 0; }\n\n s.dyn_ltree[END_BLOCK * 2]/*.Freq*/ = 1;\n s.opt_len = s.static_len = 0;\n s.sym_next = s.matches = 0;\n};\n\n\n/* ===========================================================================\n * Flush the bit buffer and align the output on a byte boundary\n */\nconst bi_windup = (s) =>\n{\n if (s.bi_valid > 8) {\n put_short(s, s.bi_buf);\n } else if (s.bi_valid > 0) {\n //put_byte(s, (Byte)s->bi_buf);\n s.pending_buf[s.pending++] = s.bi_buf;\n }\n s.bi_buf = 0;\n s.bi_valid = 0;\n};\n\n/* ===========================================================================\n * Compares to subtrees, using the tree depth as tie breaker when\n * the subtrees have equal frequency. This minimizes the worst case length.\n */\nconst smaller = (tree, n, m, depth) => {\n\n const _n2 = n * 2;\n const _m2 = m * 2;\n return (tree[_n2]/*.Freq*/ < tree[_m2]/*.Freq*/ ||\n (tree[_n2]/*.Freq*/ === tree[_m2]/*.Freq*/ && depth[n] <= depth[m]));\n};\n\n/* ===========================================================================\n * Restore the heap property by moving down the tree starting at node k,\n * exchanging a node with the smallest of its two sons if necessary, stopping\n * when the heap property is re-established (each father smaller than its\n * two sons).\n */\nconst pqdownheap = (s, tree, k) => {\n// deflate_state *s;\n// ct_data *tree; /* the tree to restore */\n// int k; /* node to move down */\n\n const v = s.heap[k];\n let j = k << 1; /* left son of k */\n while (j <= s.heap_len) {\n /* Set j to the smallest of the two sons: */\n if (j < s.heap_len &&\n smaller(tree, s.heap[j + 1], s.heap[j], s.depth)) {\n j++;\n }\n /* Exit if v is smaller than both sons */\n if (smaller(tree, v, s.heap[j], s.depth)) { break; }\n\n /* Exchange v with the smallest son */\n s.heap[k] = s.heap[j];\n k = j;\n\n /* And continue down the tree, setting j to the left son of k */\n j <<= 1;\n }\n s.heap[k] = v;\n};\n\n\n// inlined manually\n// const SMALLEST = 1;\n\n/* ===========================================================================\n * Send the block data compressed using the given Huffman trees\n */\nconst compress_block = (s, ltree, dtree) => {\n// deflate_state *s;\n// const ct_data *ltree; /* literal tree */\n// const ct_data *dtree; /* distance tree */\n\n let dist; /* distance of matched string */\n let lc; /* match length or unmatched char (if dist == 0) */\n let sx = 0; /* running index in sym_buf */\n let code; /* the code to send */\n let extra; /* number of extra bits to send */\n\n if (s.sym_next !== 0) {\n do {\n dist = s.pending_buf[s.sym_buf + sx++] & 0xff;\n dist += (s.pending_buf[s.sym_buf + sx++] & 0xff) << 8;\n lc = s.pending_buf[s.sym_buf + sx++];\n if (dist === 0) {\n send_code(s, lc, ltree); /* send a literal byte */\n //Tracecv(isgraph(lc), (stderr,\" '%c' \", lc));\n } else {\n /* Here, lc is the match length - MIN_MATCH */\n code = _length_code$1[lc];\n send_code(s, code + LITERALS$1$1 + 1, ltree); /* send the length code */\n extra = extra_lbits[code];\n if (extra !== 0) {\n lc -= base_length$1[code];\n send_bits(s, lc, extra); /* send the extra length bits */\n }\n dist--; /* dist is now the match distance - 1 */\n code = d_code(dist);\n //Assert (code < D_CODES, \"bad d_code\");\n\n send_code(s, code, dtree); /* send the distance code */\n extra = extra_dbits[code];\n if (extra !== 0) {\n dist -= base_dist$1[code];\n send_bits(s, dist, extra); /* send the extra distance bits */\n }\n } /* literal or match pair ? */\n\n /* Check that the overlay between pending_buf and sym_buf is ok: */\n //Assert(s->pending < s->lit_bufsize + sx, \"pendingBuf overflow\");\n\n } while (sx < s.sym_next);\n }\n\n send_code(s, END_BLOCK, ltree);\n};\n\n\n/* ===========================================================================\n * Construct one Huffman tree and assigns the code bit strings and lengths.\n * Update the total bit length for the current block.\n * IN assertion: the field freq is set for all tree elements.\n * OUT assertions: the fields len and code are set to the optimal bit length\n * and corresponding code. The length opt_len is updated; static_len is\n * also updated if stree is not null. The field max_code is set.\n */\nconst build_tree = (s, desc) => {\n// deflate_state *s;\n// tree_desc *desc; /* the tree descriptor */\n\n const tree = desc.dyn_tree;\n const stree = desc.stat_desc.static_tree;\n const has_stree = desc.stat_desc.has_stree;\n const elems = desc.stat_desc.elems;\n let n, m; /* iterate over heap elements */\n let max_code = -1; /* largest code with non zero frequency */\n let node; /* new node being created */\n\n /* Construct the initial heap, with least frequent element in\n * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1].\n * heap[0] is not used.\n */\n s.heap_len = 0;\n s.heap_max = HEAP_SIZE$1;\n\n for (n = 0; n < elems; n++) {\n if (tree[n * 2]/*.Freq*/ !== 0) {\n s.heap[++s.heap_len] = max_code = n;\n s.depth[n] = 0;\n\n } else {\n tree[n * 2 + 1]/*.Len*/ = 0;\n }\n }\n\n /* The pkzip format requires that at least one distance code exists,\n * and that at least one bit should be sent even if there is only one\n * possible code. So to avoid special checks later on we force at least\n * two codes of non zero frequency.\n */\n while (s.heap_len < 2) {\n node = s.heap[++s.heap_len] = (max_code < 2 ? ++max_code : 0);\n tree[node * 2]/*.Freq*/ = 1;\n s.depth[node] = 0;\n s.opt_len--;\n\n if (has_stree) {\n s.static_len -= stree[node * 2 + 1]/*.Len*/;\n }\n /* node is 0 or 1 so it does not have extra bits */\n }\n desc.max_code = max_code;\n\n /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree,\n * establish sub-heaps of increasing lengths:\n */\n for (n = (s.heap_len >> 1/*int /2*/); n >= 1; n--) { pqdownheap(s, tree, n); }\n\n /* Construct the Huffman tree by repeatedly combining the least two\n * frequent nodes.\n */\n node = elems; /* next internal node of the tree */\n do {\n //pqremove(s, tree, n); /* n = node of least frequency */\n /*** pqremove ***/\n n = s.heap[1/*SMALLEST*/];\n s.heap[1/*SMALLEST*/] = s.heap[s.heap_len--];\n pqdownheap(s, tree, 1/*SMALLEST*/);\n /***/\n\n m = s.heap[1/*SMALLEST*/]; /* m = node of next least frequency */\n\n s.heap[--s.heap_max] = n; /* keep the nodes sorted by frequency */\n s.heap[--s.heap_max] = m;\n\n /* Create a new node father of n and m */\n tree[node * 2]/*.Freq*/ = tree[n * 2]/*.Freq*/ + tree[m * 2]/*.Freq*/;\n s.depth[node] = (s.depth[n] >= s.depth[m] ? s.depth[n] : s.depth[m]) + 1;\n tree[n * 2 + 1]/*.Dad*/ = tree[m * 2 + 1]/*.Dad*/ = node;\n\n /* and insert the new node in the heap */\n s.heap[1/*SMALLEST*/] = node++;\n pqdownheap(s, tree, 1/*SMALLEST*/);\n\n } while (s.heap_len >= 2);\n\n s.heap[--s.heap_max] = s.heap[1/*SMALLEST*/];\n\n /* At this point, the fields freq and dad are set. We can now\n * generate the bit lengths.\n */\n gen_bitlen(s, desc);\n\n /* The field len is now set, we can generate the bit codes */\n gen_codes(tree, max_code, s.bl_count);\n};\n\n\n/* ===========================================================================\n * Scan a literal or distance tree to determine the frequencies of the codes\n * in the bit length tree.\n */\nconst scan_tree = (s, tree, max_code) => {\n// deflate_state *s;\n// ct_data *tree; /* the tree to be scanned */\n// int max_code; /* and its largest code of non zero frequency */\n\n let n; /* iterates over all tree elements */\n let prevlen = -1; /* last emitted length */\n let curlen; /* length of current code */\n\n let nextlen = tree[0 * 2 + 1]/*.Len*/; /* length of next code */\n\n let count = 0; /* repeat count of the current code */\n let max_count = 7; /* max repeat count */\n let min_count = 4; /* min repeat count */\n\n if (nextlen === 0) {\n max_count = 138;\n min_count = 3;\n }\n tree[(max_code + 1) * 2 + 1]/*.Len*/ = 0xffff; /* guard */\n\n for (n = 0; n <= max_code; n++) {\n curlen = nextlen;\n nextlen = tree[(n + 1) * 2 + 1]/*.Len*/;\n\n if (++count < max_count && curlen === nextlen) {\n continue;\n\n } else if (count < min_count) {\n s.bl_tree[curlen * 2]/*.Freq*/ += count;\n\n } else if (curlen !== 0) {\n\n if (curlen !== prevlen) { s.bl_tree[curlen * 2]/*.Freq*/++; }\n s.bl_tree[REP_3_6 * 2]/*.Freq*/++;\n\n } else if (count <= 10) {\n s.bl_tree[REPZ_3_10 * 2]/*.Freq*/++;\n\n } else {\n s.bl_tree[REPZ_11_138 * 2]/*.Freq*/++;\n }\n\n count = 0;\n prevlen = curlen;\n\n if (nextlen === 0) {\n max_count = 138;\n min_count = 3;\n\n } else if (curlen === nextlen) {\n max_count = 6;\n min_count = 3;\n\n } else {\n max_count = 7;\n min_count = 4;\n }\n }\n};\n\n\n/* ===========================================================================\n * Send a literal or distance tree in compressed form, using the codes in\n * bl_tree.\n */\nconst send_tree = (s, tree, max_code) => {\n// deflate_state *s;\n// ct_data *tree; /* the tree to be scanned */\n// int max_code; /* and its largest code of non zero frequency */\n\n let n; /* iterates over all tree elements */\n let prevlen = -1; /* last emitted length */\n let curlen; /* length of current code */\n\n let nextlen = tree[0 * 2 + 1]/*.Len*/; /* length of next code */\n\n let count = 0; /* repeat count of the current code */\n let max_count = 7; /* max repeat count */\n let min_count = 4; /* min repeat count */\n\n /* tree[max_code+1].Len = -1; */ /* guard already set */\n if (nextlen === 0) {\n max_count = 138;\n min_count = 3;\n }\n\n for (n = 0; n <= max_code; n++) {\n curlen = nextlen;\n nextlen = tree[(n + 1) * 2 + 1]/*.Len*/;\n\n if (++count < max_count && curlen === nextlen) {\n continue;\n\n } else if (count < min_count) {\n do { send_code(s, curlen, s.bl_tree); } while (--count !== 0);\n\n } else if (curlen !== 0) {\n if (curlen !== prevlen) {\n send_code(s, curlen, s.bl_tree);\n count--;\n }\n //Assert(count >= 3 && count <= 6, \" 3_6?\");\n send_code(s, REP_3_6, s.bl_tree);\n send_bits(s, count - 3, 2);\n\n } else if (count <= 10) {\n send_code(s, REPZ_3_10, s.bl_tree);\n send_bits(s, count - 3, 3);\n\n } else {\n send_code(s, REPZ_11_138, s.bl_tree);\n send_bits(s, count - 11, 7);\n }\n\n count = 0;\n prevlen = curlen;\n if (nextlen === 0) {\n max_count = 138;\n min_count = 3;\n\n } else if (curlen === nextlen) {\n max_count = 6;\n min_count = 3;\n\n } else {\n max_count = 7;\n min_count = 4;\n }\n }\n};\n\n\n/* ===========================================================================\n * Construct the Huffman tree for the bit lengths and return the index in\n * bl_order of the last bit length code to send.\n */\nconst build_bl_tree = (s) => {\n\n let max_blindex; /* index of last bit length code of non zero freq */\n\n /* Determine the bit length frequencies for literal and distance trees */\n scan_tree(s, s.dyn_ltree, s.l_desc.max_code);\n scan_tree(s, s.dyn_dtree, s.d_desc.max_code);\n\n /* Build the bit length tree: */\n build_tree(s, s.bl_desc);\n /* opt_len now includes the length of the tree representations, except\n * the lengths of the bit lengths codes and the 5+5+4 bits for the counts.\n */\n\n /* Determine the number of bit length codes to send. The pkzip format\n * requires that at least 4 bit length codes be sent. (appnote.txt says\n * 3 but the actual value used is 4.)\n */\n for (max_blindex = BL_CODES$1 - 1; max_blindex >= 3; max_blindex--) {\n if (s.bl_tree[bl_order[max_blindex] * 2 + 1]/*.Len*/ !== 0) {\n break;\n }\n }\n /* Update opt_len to include the bit length tree and counts */\n s.opt_len += 3 * (max_blindex + 1) + 5 + 5 + 4;\n //Tracev((stderr, \"\\ndyn trees: dyn %ld, stat %ld\",\n // s->opt_len, s->static_len));\n\n return max_blindex;\n};\n\n\n/* ===========================================================================\n * Send the header for a block using dynamic Huffman trees: the counts, the\n * lengths of the bit length codes, the literal tree and the distance tree.\n * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4.\n */\nconst send_all_trees = (s, lcodes, dcodes, blcodes) => {\n// deflate_state *s;\n// int lcodes, dcodes, blcodes; /* number of codes for each tree */\n\n let rank; /* index in bl_order */\n\n //Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, \"not enough codes\");\n //Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES,\n // \"too many codes\");\n //Tracev((stderr, \"\\nbl counts: \"));\n send_bits(s, lcodes - 257, 5); /* not +255 as stated in appnote.txt */\n send_bits(s, dcodes - 1, 5);\n send_bits(s, blcodes - 4, 4); /* not -3 as stated in appnote.txt */\n for (rank = 0; rank < blcodes; rank++) {\n //Tracev((stderr, \"\\nbl code %2d \", bl_order[rank]));\n send_bits(s, s.bl_tree[bl_order[rank] * 2 + 1]/*.Len*/, 3);\n }\n //Tracev((stderr, \"\\nbl tree: sent %ld\", s->bits_sent));\n\n send_tree(s, s.dyn_ltree, lcodes - 1); /* literal tree */\n //Tracev((stderr, \"\\nlit tree: sent %ld\", s->bits_sent));\n\n send_tree(s, s.dyn_dtree, dcodes - 1); /* distance tree */\n //Tracev((stderr, \"\\ndist tree: sent %ld\", s->bits_sent));\n};\n\n\n/* ===========================================================================\n * Check if the data type is TEXT or BINARY, using the following algorithm:\n * - TEXT if the two conditions below are satisfied:\n * a) There are no non-portable control characters belonging to the\n * \"block list\" (0..6, 14..25, 28..31).\n * b) There is at least one printable character belonging to the\n * \"allow list\" (9 {TAB}, 10 {LF}, 13 {CR}, 32..255).\n * - BINARY otherwise.\n * - The following partially-portable control characters form a\n * \"gray list\" that is ignored in this detection algorithm:\n * (7 {BEL}, 8 {BS}, 11 {VT}, 12 {FF}, 26 {SUB}, 27 {ESC}).\n * IN assertion: the fields Freq of dyn_ltree are set.\n */\nconst detect_data_type = (s) => {\n /* block_mask is the bit mask of block-listed bytes\n * set bits 0..6, 14..25, and 28..31\n * 0xf3ffc07f = binary 11110011111111111100000001111111\n */\n let block_mask = 0xf3ffc07f;\n let n;\n\n /* Check for non-textual (\"block-listed\") bytes. */\n for (n = 0; n <= 31; n++, block_mask >>>= 1) {\n if ((block_mask & 1) && (s.dyn_ltree[n * 2]/*.Freq*/ !== 0)) {\n return Z_BINARY;\n }\n }\n\n /* Check for textual (\"allow-listed\") bytes. */\n if (s.dyn_ltree[9 * 2]/*.Freq*/ !== 0 || s.dyn_ltree[10 * 2]/*.Freq*/ !== 0 ||\n s.dyn_ltree[13 * 2]/*.Freq*/ !== 0) {\n return Z_TEXT;\n }\n for (n = 32; n < LITERALS$1$1; n++) {\n if (s.dyn_ltree[n * 2]/*.Freq*/ !== 0) {\n return Z_TEXT;\n }\n }\n\n /* There are no \"block-listed\" or \"allow-listed\" bytes:\n * this stream either is empty or has tolerated (\"gray-listed\") bytes only.\n */\n return Z_BINARY;\n};\n\n\nlet static_init_done = false;\n\n/* ===========================================================================\n * Initialize the tree data structures for a new zlib stream.\n */\nconst _tr_init$1 = (s) =>\n{\n\n if (!static_init_done) {\n tr_static_init();\n static_init_done = true;\n }\n\n s.l_desc = new TreeDesc(s.dyn_ltree, static_l_desc);\n s.d_desc = new TreeDesc(s.dyn_dtree, static_d_desc);\n s.bl_desc = new TreeDesc(s.bl_tree, static_bl_desc);\n\n s.bi_buf = 0;\n s.bi_valid = 0;\n\n /* Initialize the first block of the first file: */\n init_block(s);\n};\n\n\n/* ===========================================================================\n * Send a stored block\n */\nconst _tr_stored_block$1 = (s, buf, stored_len, last) => {\n//DeflateState *s;\n//charf *buf; /* input block */\n//ulg stored_len; /* length of input block */\n//int last; /* one if this is the last block for a file */\n\n send_bits(s, (STORED_BLOCK << 1) + (last ? 1 : 0), 3); /* send block type */\n bi_windup(s); /* align on byte boundary */\n put_short(s, stored_len);\n put_short(s, ~stored_len);\n if (stored_len) {\n s.pending_buf.set(s.window.subarray(buf, buf + stored_len), s.pending);\n }\n s.pending += stored_len;\n};\n\n\n/* ===========================================================================\n * Send one empty static block to give enough lookahead for inflate.\n * This takes 10 bits, of which 7 may remain in the bit buffer.\n */\nconst _tr_align$1 = (s) => {\n send_bits(s, STATIC_TREES << 1, 3);\n send_code(s, END_BLOCK, static_ltree$1);\n bi_flush(s);\n};\n\n\n/* ===========================================================================\n * Determine the best encoding for the current block: dynamic trees, static\n * trees or store, and write out the encoded block.\n */\nconst _tr_flush_block$1 = (s, buf, stored_len, last) => {\n//DeflateState *s;\n//charf *buf; /* input block, or NULL if too old */\n//ulg stored_len; /* length of input block */\n//int last; /* one if this is the last block for a file */\n\n let opt_lenb, static_lenb; /* opt_len and static_len in bytes */\n let max_blindex = 0; /* index of last bit length code of non zero freq */\n\n /* Build the Huffman trees unless a stored block is forced */\n if (s.level > 0) {\n\n /* Check if the file is binary or text */\n if (s.strm.data_type === Z_UNKNOWN$1) {\n s.strm.data_type = detect_data_type(s);\n }\n\n /* Construct the literal and distance trees */\n build_tree(s, s.l_desc);\n // Tracev((stderr, \"\\nlit data: dyn %ld, stat %ld\", s->opt_len,\n // s->static_len));\n\n build_tree(s, s.d_desc);\n // Tracev((stderr, \"\\ndist data: dyn %ld, stat %ld\", s->opt_len,\n // s->static_len));\n /* At this point, opt_len and static_len are the total bit lengths of\n * the compressed block data, excluding the tree representations.\n */\n\n /* Build the bit length tree for the above two trees, and get the index\n * in bl_order of the last bit length code to send.\n */\n max_blindex = build_bl_tree(s);\n\n /* Determine the best encoding. Compute the block lengths in bytes. */\n opt_lenb = (s.opt_len + 3 + 7) >>> 3;\n static_lenb = (s.static_len + 3 + 7) >>> 3;\n\n // Tracev((stderr, \"\\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u \",\n // opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len,\n // s->sym_next / 3));\n\n if (static_lenb <= opt_lenb) { opt_lenb = static_lenb; }\n\n } else {\n // Assert(buf != (char*)0, \"lost buf\");\n opt_lenb = static_lenb = stored_len + 5; /* force a stored block */\n }\n\n if ((stored_len + 4 <= opt_lenb) && (buf !== -1)) {\n /* 4: two words for the lengths */\n\n /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE.\n * Otherwise we can't have processed more than WSIZE input bytes since\n * the last block flush, because compression would have been\n * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to\n * transform a block into a stored block.\n */\n _tr_stored_block$1(s, buf, stored_len, last);\n\n } else if (s.strategy === Z_FIXED$1 || static_lenb === opt_lenb) {\n\n send_bits(s, (STATIC_TREES << 1) + (last ? 1 : 0), 3);\n compress_block(s, static_ltree$1, static_dtree$1);\n\n } else {\n send_bits(s, (DYN_TREES << 1) + (last ? 1 : 0), 3);\n send_all_trees(s, s.l_desc.max_code + 1, s.d_desc.max_code + 1, max_blindex + 1);\n compress_block(s, s.dyn_ltree, s.dyn_dtree);\n }\n // Assert (s->compressed_len == s->bits_sent, \"bad compressed size\");\n /* The above check is made mod 2^32, for files larger than 512 MB\n * and uLong implemented on 32 bits.\n */\n init_block(s);\n\n if (last) {\n bi_windup(s);\n }\n // Tracev((stderr,\"\\ncomprlen %lu(%lu) \", s->compressed_len>>3,\n // s->compressed_len-7*last));\n};\n\n/* ===========================================================================\n * Save the match info and tally the frequency counts. Return true if\n * the current block must be flushed.\n */\nconst _tr_tally$1 = (s, dist, lc) => {\n// deflate_state *s;\n// unsigned dist; /* distance of matched string */\n// unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */\n\n s.pending_buf[s.sym_buf + s.sym_next++] = dist;\n s.pending_buf[s.sym_buf + s.sym_next++] = dist >> 8;\n s.pending_buf[s.sym_buf + s.sym_next++] = lc;\n if (dist === 0) {\n /* lc is the unmatched char */\n s.dyn_ltree[lc * 2]/*.Freq*/++;\n } else {\n s.matches++;\n /* Here, lc is the match length - MIN_MATCH */\n dist--; /* dist = match distance - 1 */\n //Assert((ush)dist < (ush)MAX_DIST(s) &&\n // (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) &&\n // (ush)d_code(dist) < (ush)D_CODES, \"_tr_tally: bad match\");\n\n s.dyn_ltree[(_length_code$1[lc] + LITERALS$1$1 + 1) * 2]/*.Freq*/++;\n s.dyn_dtree[d_code(dist) * 2]/*.Freq*/++;\n }\n\n return (s.sym_next === s.sym_end);\n};\n\nvar _tr_init_1 = _tr_init$1;\nvar _tr_stored_block_1 = _tr_stored_block$1;\nvar _tr_flush_block_1 = _tr_flush_block$1;\nvar _tr_tally_1 = _tr_tally$1;\nvar _tr_align_1 = _tr_align$1;\n\nvar trees = {\n\t_tr_init: _tr_init_1,\n\t_tr_stored_block: _tr_stored_block_1,\n\t_tr_flush_block: _tr_flush_block_1,\n\t_tr_tally: _tr_tally_1,\n\t_tr_align: _tr_align_1\n};\n\n// Note: adler32 takes 12% for level 0 and 2% for level 6.\n// It isn't worth it to make additional optimizations as in original.\n// Small size is preferable.\n\n// (C) 1995-2013 Jean-loup Gailly and Mark Adler\n// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin\n//\n// This software is provided 'as-is', without any express or implied\n// warranty. In no event will the authors be held liable for any damages\n// arising from the use of this software.\n//\n// Permission is granted to anyone to use this software for any purpose,\n// including commercial applications, and to alter it and redistribute it\n// freely, subject to the following restrictions:\n//\n// 1. The origin of this software must not be misrepresented; you must not\n// claim that you wrote the original software. If you use this software\n// in a product, an acknowledgment in the product documentation would be\n// appreciated but is not required.\n// 2. Altered source versions must be plainly marked as such, and must not be\n// misrepresented as being the original software.\n// 3. This notice may not be removed or altered from any source distribution.\n\nconst adler32$1 = (adler, buf, len, pos) => {\n let s1 = (adler & 0xffff) |0,\n s2 = ((adler >>> 16) & 0xffff) |0,\n n = 0;\n\n while (len !== 0) {\n // Set limit ~ twice less than 5552, to keep\n // s2 in 31-bits, because we force signed ints.\n // in other case %= will fail.\n n = len > 2000 ? 2000 : len;\n len -= n;\n\n do {\n s1 = (s1 + buf[pos++]) |0;\n s2 = (s2 + s1) |0;\n } while (--n);\n\n s1 %= 65521;\n s2 %= 65521;\n }\n\n return (s1 | (s2 << 16)) |0;\n};\n\n\nvar adler32_1$1 = adler32$1;\n\n// Note: we can't get significant speed boost here.\n// So write code to minimize size - no pregenerated tables\n// and array tools dependencies.\n\n// (C) 1995-2013 Jean-loup Gailly and Mark Adler\n// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin\n//\n// This software is provided 'as-is', without any express or implied\n// warranty. In no event will the authors be held liable for any damages\n// arising from the use of this software.\n//\n// Permission is granted to anyone to use this software for any purpose,\n// including commercial applications, and to alter it and redistribute it\n// freely, subject to the following restrictions:\n//\n// 1. The origin of this software must not be misrepresented; you must not\n// claim that you wrote the original software. If you use this software\n// in a product, an acknowledgment in the product documentation would be\n// appreciated but is not required.\n// 2. Altered source versions must be plainly marked as such, and must not be\n// misrepresented as being the original software.\n// 3. This notice may not be removed or altered from any source distribution.\n\n// Use ordinary array, since untyped makes no boost here\nconst makeTable$1 = () => {\n let c, table = [];\n\n for (var n = 0; n < 256; n++) {\n c = n;\n for (var k = 0; k < 8; k++) {\n c = ((c & 1) ? (0xEDB88320 ^ (c >>> 1)) : (c >>> 1));\n }\n table[n] = c;\n }\n\n return table;\n};\n\n// Create table on load. Just 255 signed longs. Not a problem.\nconst crcTable$1 = new Uint32Array(makeTable$1());\n\n\nconst crc32$1 = (crc, buf, len, pos) => {\n const t = crcTable$1;\n const end = pos + len;\n\n crc ^= -1;\n\n for (let i = pos; i < end; i++) {\n crc = (crc >>> 8) ^ t[(crc ^ buf[i]) & 0xFF];\n }\n\n return (crc ^ (-1)); // >>> 0;\n};\n\n\nvar crc32_1$1 = crc32$1;\n\n// (C) 1995-2013 Jean-loup Gailly and Mark Adler\n// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin\n//\n// This software is provided 'as-is', without any express or implied\n// warranty. In no event will the authors be held liable for any damages\n// arising from the use of this software.\n//\n// Permission is granted to anyone to use this software for any purpose,\n// including commercial applications, and to alter it and redistribute it\n// freely, subject to the following restrictions:\n//\n// 1. The origin of this software must not be misrepresented; you must not\n// claim that you wrote the original software. If you use this software\n// in a product, an acknowledgment in the product documentation would be\n// appreciated but is not required.\n// 2. Altered source versions must be plainly marked as such, and must not be\n// misrepresented as being the original software.\n// 3. This notice may not be removed or altered from any source distribution.\n\nvar messages$1 = {\n 2: 'need dictionary', /* Z_NEED_DICT 2 */\n 1: 'stream end', /* Z_STREAM_END 1 */\n 0: '', /* Z_OK 0 */\n '-1': 'file error', /* Z_ERRNO (-1) */\n '-2': 'stream error', /* Z_STREAM_ERROR (-2) */\n '-3': 'data error', /* Z_DATA_ERROR (-3) */\n '-4': 'insufficient memory', /* Z_MEM_ERROR (-4) */\n '-5': 'buffer error', /* Z_BUF_ERROR (-5) */\n '-6': 'incompatible version' /* Z_VERSION_ERROR (-6) */\n};\n\n// (C) 1995-2013 Jean-loup Gailly and Mark Adler\n// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin\n//\n// This software is provided 'as-is', without any express or implied\n// warranty. In no event will the authors be held liable for any damages\n// arising from the use of this software.\n//\n// Permission is granted to anyone to use this software for any purpose,\n// including commercial applications, and to alter it and redistribute it\n// freely, subject to the following restrictions:\n//\n// 1. The origin of this software must not be misrepresented; you must not\n// claim that you wrote the original software. If you use this software\n// in a product, an acknowledgment in the product documentation would be\n// appreciated but is not required.\n// 2. Altered source versions must be plainly marked as such, and must not be\n// misrepresented as being the original software.\n// 3. This notice may not be removed or altered from any source distribution.\n\nvar constants$2$1 = {\n\n /* Allowed flush values; see deflate() and inflate() below for details */\n Z_NO_FLUSH: 0,\n Z_PARTIAL_FLUSH: 1,\n Z_SYNC_FLUSH: 2,\n Z_FULL_FLUSH: 3,\n Z_FINISH: 4,\n Z_BLOCK: 5,\n Z_TREES: 6,\n\n /* Return codes for the compression/decompression functions. Negative values\n * are errors, positive values are used for special but normal events.\n */\n Z_OK: 0,\n Z_STREAM_END: 1,\n Z_NEED_DICT: 2,\n Z_ERRNO: -1,\n Z_STREAM_ERROR: -2,\n Z_DATA_ERROR: -3,\n Z_MEM_ERROR: -4,\n Z_BUF_ERROR: -5,\n //Z_VERSION_ERROR: -6,\n\n /* compression levels */\n Z_NO_COMPRESSION: 0,\n Z_BEST_SPEED: 1,\n Z_BEST_COMPRESSION: 9,\n Z_DEFAULT_COMPRESSION: -1,\n\n\n Z_FILTERED: 1,\n Z_HUFFMAN_ONLY: 2,\n Z_RLE: 3,\n Z_FIXED: 4,\n Z_DEFAULT_STRATEGY: 0,\n\n /* Possible values of the data_type field (though see inflate()) */\n Z_BINARY: 0,\n Z_TEXT: 1,\n //Z_ASCII: 1, // = Z_TEXT (deprecated)\n Z_UNKNOWN: 2,\n\n /* The deflate compression method */\n Z_DEFLATED: 8\n //Z_NULL: null // Use -1 or null inline, depending on var type\n};\n\n// (C) 1995-2013 Jean-loup Gailly and Mark Adler\n// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin\n//\n// This software is provided 'as-is', without any express or implied\n// warranty. In no event will the authors be held liable for any damages\n// arising from the use of this software.\n//\n// Permission is granted to anyone to use this software for any purpose,\n// including commercial applications, and to alter it and redistribute it\n// freely, subject to the following restrictions:\n//\n// 1. The origin of this software must not be misrepresented; you must not\n// claim that you wrote the original software. If you use this software\n// in a product, an acknowledgment in the product documentation would be\n// appreciated but is not required.\n// 2. Altered source versions must be plainly marked as such, and must not be\n// misrepresented as being the original software.\n// 3. This notice may not be removed or altered from any source distribution.\n\nconst { _tr_init, _tr_stored_block, _tr_flush_block, _tr_tally, _tr_align } = trees;\n\n\n\n\n/* Public constants ==========================================================*/\n/* ===========================================================================*/\n\nconst {\n Z_NO_FLUSH: Z_NO_FLUSH$2, Z_PARTIAL_FLUSH, Z_FULL_FLUSH: Z_FULL_FLUSH$1, Z_FINISH: Z_FINISH$3, Z_BLOCK: Z_BLOCK$1,\n Z_OK: Z_OK$3, Z_STREAM_END: Z_STREAM_END$3, Z_STREAM_ERROR: Z_STREAM_ERROR$2, Z_DATA_ERROR: Z_DATA_ERROR$2, Z_BUF_ERROR: Z_BUF_ERROR$1,\n Z_DEFAULT_COMPRESSION: Z_DEFAULT_COMPRESSION$1,\n Z_FILTERED, Z_HUFFMAN_ONLY, Z_RLE, Z_FIXED, Z_DEFAULT_STRATEGY: Z_DEFAULT_STRATEGY$1,\n Z_UNKNOWN,\n Z_DEFLATED: Z_DEFLATED$2\n} = constants$2$1;\n\n/*============================================================================*/\n\n\nconst MAX_MEM_LEVEL = 9;\n/* Maximum value for memLevel in deflateInit2 */\nconst MAX_WBITS$1 = 15;\n/* 32K LZ77 window */\nconst DEF_MEM_LEVEL = 8;\n\n\nconst LENGTH_CODES = 29;\n/* number of length codes, not counting the special END_BLOCK code */\nconst LITERALS = 256;\n/* number of literal bytes 0..255 */\nconst L_CODES = LITERALS + 1 + LENGTH_CODES;\n/* number of Literal or Length codes, including the END_BLOCK code */\nconst D_CODES = 30;\n/* number of distance codes */\nconst BL_CODES = 19;\n/* number of codes used to transfer the bit lengths */\nconst HEAP_SIZE = 2 * L_CODES + 1;\n/* maximum heap size */\nconst MAX_BITS = 15;\n/* All codes must not exceed MAX_BITS bits */\n\nconst MIN_MATCH = 3;\nconst MAX_MATCH = 258;\nconst MIN_LOOKAHEAD = (MAX_MATCH + MIN_MATCH + 1);\n\nconst PRESET_DICT = 0x20;\n\nconst INIT_STATE = 42; /* zlib header -> BUSY_STATE */\n//#ifdef GZIP\nconst GZIP_STATE = 57; /* gzip header -> BUSY_STATE | EXTRA_STATE */\n//#endif\nconst EXTRA_STATE = 69; /* gzip extra block -> NAME_STATE */\nconst NAME_STATE = 73; /* gzip file name -> COMMENT_STATE */\nconst COMMENT_STATE = 91; /* gzip comment -> HCRC_STATE */\nconst HCRC_STATE = 103; /* gzip header CRC -> BUSY_STATE */\nconst BUSY_STATE = 113; /* deflate -> FINISH_STATE */\nconst FINISH_STATE = 666; /* stream complete */\n\nconst BS_NEED_MORE = 1; /* block not completed, need more input or more output */\nconst BS_BLOCK_DONE = 2; /* block flush performed */\nconst BS_FINISH_STARTED = 3; /* finish started, need only more output at next deflate */\nconst BS_FINISH_DONE = 4; /* finish done, accept no more input or output */\n\nconst OS_CODE = 0x03; // Unix :) . Don't detect, use this default.\n\nconst err = (strm, errorCode) => {\n strm.msg = messages$1[errorCode];\n return errorCode;\n};\n\nconst rank = (f) => {\n return ((f) * 2) - ((f) > 4 ? 9 : 0);\n};\n\nconst zero = (buf) => {\n let len = buf.length; while (--len >= 0) { buf[len] = 0; }\n};\n\n/* ===========================================================================\n * Slide the hash table when sliding the window down (could be avoided with 32\n * bit values at the expense of memory usage). We slide even when level == 0 to\n * keep the hash table consistent if we switch back to level > 0 later.\n */\nconst slide_hash = (s) => {\n let n, m;\n let p;\n let wsize = s.w_size;\n\n n = s.hash_size;\n p = n;\n do {\n m = s.head[--p];\n s.head[p] = (m >= wsize ? m - wsize : 0);\n } while (--n);\n n = wsize;\n//#ifndef FASTEST\n p = n;\n do {\n m = s.prev[--p];\n s.prev[p] = (m >= wsize ? m - wsize : 0);\n /* If n is not on any hash chain, prev[n] is garbage but\n * its value will never be used.\n */\n } while (--n);\n//#endif\n};\n\n/* eslint-disable new-cap */\nlet HASH_ZLIB = (s, prev, data) => ((prev << s.hash_shift) ^ data) & s.hash_mask;\n// This hash causes less collisions, https://github.com/nodeca/pako/issues/135\n// But breaks binary compatibility\n//let HASH_FAST = (s, prev, data) => ((prev << 8) + (prev >> 8) + (data << 4)) & s.hash_mask;\nlet HASH = HASH_ZLIB;\n\n\n/* =========================================================================\n * Flush as much pending output as possible. All deflate() output, except for\n * some deflate_stored() output, goes through this function so some\n * applications may wish to modify it to avoid allocating a large\n * strm->next_out buffer and copying into it. (See also read_buf()).\n */\nconst flush_pending = (strm) => {\n const s = strm.state;\n\n //_tr_flush_bits(s);\n let len = s.pending;\n if (len > strm.avail_out) {\n len = strm.avail_out;\n }\n if (len === 0) { return; }\n\n strm.output.set(s.pending_buf.subarray(s.pending_out, s.pending_out + len), strm.next_out);\n strm.next_out += len;\n s.pending_out += len;\n strm.total_out += len;\n strm.avail_out -= len;\n s.pending -= len;\n if (s.pending === 0) {\n s.pending_out = 0;\n }\n};\n\n\nconst flush_block_only = (s, last) => {\n _tr_flush_block(s, (s.block_start >= 0 ? s.block_start : -1), s.strstart - s.block_start, last);\n s.block_start = s.strstart;\n flush_pending(s.strm);\n};\n\n\nconst put_byte = (s, b) => {\n s.pending_buf[s.pending++] = b;\n};\n\n\n/* =========================================================================\n * Put a short in the pending buffer. The 16-bit value is put in MSB order.\n * IN assertion: the stream state is correct and there is enough room in\n * pending_buf.\n */\nconst putShortMSB = (s, b) => {\n\n // put_byte(s, (Byte)(b >> 8));\n// put_byte(s, (Byte)(b & 0xff));\n s.pending_buf[s.pending++] = (b >>> 8) & 0xff;\n s.pending_buf[s.pending++] = b & 0xff;\n};\n\n\n/* ===========================================================================\n * Read a new buffer from the current input stream, update the adler32\n * and total number of bytes read. All deflate() input goes through\n * this function so some applications may wish to modify it to avoid\n * allocating a large strm->input buffer and copying from it.\n * (See also flush_pending()).\n */\nconst read_buf = (strm, buf, start, size) => {\n\n let len = strm.avail_in;\n\n if (len > size) { len = size; }\n if (len === 0) { return 0; }\n\n strm.avail_in -= len;\n\n // zmemcpy(buf, strm->next_in, len);\n buf.set(strm.input.subarray(strm.next_in, strm.next_in + len), start);\n if (strm.state.wrap === 1) {\n strm.adler = adler32_1$1(strm.adler, buf, len, start);\n }\n\n else if (strm.state.wrap === 2) {\n strm.adler = crc32_1$1(strm.adler, buf, len, start);\n }\n\n strm.next_in += len;\n strm.total_in += len;\n\n return len;\n};\n\n\n/* ===========================================================================\n * Set match_start to the longest match starting at the given string and\n * return its length. Matches shorter or equal to prev_length are discarded,\n * in which case the result is equal to prev_length and match_start is\n * garbage.\n * IN assertions: cur_match is the head of the hash chain for the current\n * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1\n * OUT assertion: the match length is not greater than s->lookahead.\n */\nconst longest_match = (s, cur_match) => {\n\n let chain_length = s.max_chain_length; /* max hash chain length */\n let scan = s.strstart; /* current string */\n let match; /* matched string */\n let len; /* length of current match */\n let best_len = s.prev_length; /* best match length so far */\n let nice_match = s.nice_match; /* stop if match long enough */\n const limit = (s.strstart > (s.w_size - MIN_LOOKAHEAD)) ?\n s.strstart - (s.w_size - MIN_LOOKAHEAD) : 0/*NIL*/;\n\n const _win = s.window; // shortcut\n\n const wmask = s.w_mask;\n const prev = s.prev;\n\n /* Stop when cur_match becomes <= limit. To simplify the code,\n * we prevent matches with the string of window index 0.\n */\n\n const strend = s.strstart + MAX_MATCH;\n let scan_end1 = _win[scan + best_len - 1];\n let scan_end = _win[scan + best_len];\n\n /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.\n * It is easy to get rid of this optimization if necessary.\n */\n // Assert(s->hash_bits >= 8 && MAX_MATCH == 258, \"Code too clever\");\n\n /* Do not waste too much time if we already have a good match: */\n if (s.prev_length >= s.good_match) {\n chain_length >>= 2;\n }\n /* Do not look for matches beyond the end of the input. This is necessary\n * to make deflate deterministic.\n */\n if (nice_match > s.lookahead) { nice_match = s.lookahead; }\n\n // Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, \"need lookahead\");\n\n do {\n // Assert(cur_match < s->strstart, \"no future\");\n match = cur_match;\n\n /* Skip to next match if the match length cannot increase\n * or if the match length is less than 2. Note that the checks below\n * for insufficient lookahead only occur occasionally for performance\n * reasons. Therefore uninitialized memory will be accessed, and\n * conditional jumps will be made that depend on those values.\n * However the length of the match is limited to the lookahead, so\n * the output of deflate is not affected by the uninitialized values.\n */\n\n if (_win[match + best_len] !== scan_end ||\n _win[match + best_len - 1] !== scan_end1 ||\n _win[match] !== _win[scan] ||\n _win[++match] !== _win[scan + 1]) {\n continue;\n }\n\n /* The check at best_len-1 can be removed because it will be made\n * again later. (This heuristic is not always a win.)\n * It is not necessary to compare scan[2] and match[2] since they\n * are always equal when the other bytes match, given that\n * the hash keys are equal and that HASH_BITS >= 8.\n */\n scan += 2;\n match++;\n // Assert(*scan == *match, \"match[2]?\");\n\n /* We check for insufficient lookahead only every 8th comparison;\n * the 256th check will be made at strstart+258.\n */\n do {\n /*jshint noempty:false*/\n } while (_win[++scan] === _win[++match] && _win[++scan] === _win[++match] &&\n _win[++scan] === _win[++match] && _win[++scan] === _win[++match] &&\n _win[++scan] === _win[++match] && _win[++scan] === _win[++match] &&\n _win[++scan] === _win[++match] && _win[++scan] === _win[++match] &&\n scan < strend);\n\n // Assert(scan <= s->window+(unsigned)(s->window_size-1), \"wild scan\");\n\n len = MAX_MATCH - (strend - scan);\n scan = strend - MAX_MATCH;\n\n if (len > best_len) {\n s.match_start = cur_match;\n best_len = len;\n if (len >= nice_match) {\n break;\n }\n scan_end1 = _win[scan + best_len - 1];\n scan_end = _win[scan + best_len];\n }\n } while ((cur_match = prev[cur_match & wmask]) > limit && --chain_length !== 0);\n\n if (best_len <= s.lookahead) {\n return best_len;\n }\n return s.lookahead;\n};\n\n\n/* ===========================================================================\n * Fill the window when the lookahead becomes insufficient.\n * Updates strstart and lookahead.\n *\n * IN assertion: lookahead < MIN_LOOKAHEAD\n * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD\n * At least one byte has been read, or avail_in == 0; reads are\n * performed for at least two bytes (required for the zip translate_eol\n * option -- not supported here).\n */\nconst fill_window = (s) => {\n\n const _w_size = s.w_size;\n let n, more, str;\n\n //Assert(s->lookahead < MIN_LOOKAHEAD, \"already enough lookahead\");\n\n do {\n more = s.window_size - s.lookahead - s.strstart;\n\n // JS ints have 32 bit, block below not needed\n /* Deal with !@#$% 64K limit: */\n //if (sizeof(int) <= 2) {\n // if (more == 0 && s->strstart == 0 && s->lookahead == 0) {\n // more = wsize;\n //\n // } else if (more == (unsigned)(-1)) {\n // /* Very unlikely, but possible on 16 bit machine if\n // * strstart == 0 && lookahead == 1 (input done a byte at time)\n // */\n // more--;\n // }\n //}\n\n\n /* If the window is almost full and there is insufficient lookahead,\n * move the upper half to the lower one to make room in the upper half.\n */\n if (s.strstart >= _w_size + (_w_size - MIN_LOOKAHEAD)) {\n\n s.window.set(s.window.subarray(_w_size, _w_size + _w_size - more), 0);\n s.match_start -= _w_size;\n s.strstart -= _w_size;\n /* we now have strstart >= MAX_DIST */\n s.block_start -= _w_size;\n if (s.insert > s.strstart) {\n s.insert = s.strstart;\n }\n slide_hash(s);\n more += _w_size;\n }\n if (s.strm.avail_in === 0) {\n break;\n }\n\n /* If there was no sliding:\n * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 &&\n * more == window_size - lookahead - strstart\n * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1)\n * => more >= window_size - 2*WSIZE + 2\n * In the BIG_MEM or MMAP case (not yet supported),\n * window_size == input_size + MIN_LOOKAHEAD &&\n * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD.\n * Otherwise, window_size == 2*WSIZE so more >= 2.\n * If there was sliding, more >= WSIZE. So in all cases, more >= 2.\n */\n //Assert(more >= 2, \"more < 2\");\n n = read_buf(s.strm, s.window, s.strstart + s.lookahead, more);\n s.lookahead += n;\n\n /* Initialize the hash value now that we have some input: */\n if (s.lookahead + s.insert >= MIN_MATCH) {\n str = s.strstart - s.insert;\n s.ins_h = s.window[str];\n\n /* UPDATE_HASH(s, s->ins_h, s->window[str + 1]); */\n s.ins_h = HASH(s, s.ins_h, s.window[str + 1]);\n//#if MIN_MATCH != 3\n// Call update_hash() MIN_MATCH-3 more times\n//#endif\n while (s.insert) {\n /* UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); */\n s.ins_h = HASH(s, s.ins_h, s.window[str + MIN_MATCH - 1]);\n\n s.prev[str & s.w_mask] = s.head[s.ins_h];\n s.head[s.ins_h] = str;\n str++;\n s.insert--;\n if (s.lookahead + s.insert < MIN_MATCH) {\n break;\n }\n }\n }\n /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage,\n * but this is not important since only literal bytes will be emitted.\n */\n\n } while (s.lookahead < MIN_LOOKAHEAD && s.strm.avail_in !== 0);\n\n /* If the WIN_INIT bytes after the end of the current data have never been\n * written, then zero those bytes in order to avoid memory check reports of\n * the use of uninitialized (or uninitialised as Julian writes) bytes by\n * the longest match routines. Update the high water mark for the next\n * time through here. WIN_INIT is set to MAX_MATCH since the longest match\n * routines allow scanning to strstart + MAX_MATCH, ignoring lookahead.\n */\n// if (s.high_water < s.window_size) {\n// const curr = s.strstart + s.lookahead;\n// let init = 0;\n//\n// if (s.high_water < curr) {\n// /* Previous high water mark below current data -- zero WIN_INIT\n// * bytes or up to end of window, whichever is less.\n// */\n// init = s.window_size - curr;\n// if (init > WIN_INIT)\n// init = WIN_INIT;\n// zmemzero(s->window + curr, (unsigned)init);\n// s->high_water = curr + init;\n// }\n// else if (s->high_water < (ulg)curr + WIN_INIT) {\n// /* High water mark at or above current data, but below current data\n// * plus WIN_INIT -- zero out to current data plus WIN_INIT, or up\n// * to end of window, whichever is less.\n// */\n// init = (ulg)curr + WIN_INIT - s->high_water;\n// if (init > s->window_size - s->high_water)\n// init = s->window_size - s->high_water;\n// zmemzero(s->window + s->high_water, (unsigned)init);\n// s->high_water += init;\n// }\n// }\n//\n// Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD,\n// \"not enough room for search\");\n};\n\n/* ===========================================================================\n * Copy without compression as much as possible from the input stream, return\n * the current block state.\n *\n * In case deflateParams() is used to later switch to a non-zero compression\n * level, s->matches (otherwise unused when storing) keeps track of the number\n * of hash table slides to perform. If s->matches is 1, then one hash table\n * slide will be done when switching. If s->matches is 2, the maximum value\n * allowed here, then the hash table will be cleared, since two or more slides\n * is the same as a clear.\n *\n * deflate_stored() is written to minimize the number of times an input byte is\n * copied. It is most efficient with large input and output buffers, which\n * maximizes the opportunites to have a single copy from next_in to next_out.\n */\nconst deflate_stored = (s, flush) => {\n\n /* Smallest worthy block size when not flushing or finishing. By default\n * this is 32K. This can be as small as 507 bytes for memLevel == 1. For\n * large input and output buffers, the stored block size will be larger.\n */\n let min_block = s.pending_buf_size - 5 > s.w_size ? s.w_size : s.pending_buf_size - 5;\n\n /* Copy as many min_block or larger stored blocks directly to next_out as\n * possible. If flushing, copy the remaining available input to next_out as\n * stored blocks, if there is enough space.\n */\n let len, left, have, last = 0;\n let used = s.strm.avail_in;\n do {\n /* Set len to the maximum size block that we can copy directly with the\n * available input data and output space. Set left to how much of that\n * would be copied from what's left in the window.\n */\n len = 65535/* MAX_STORED */; /* maximum deflate stored block length */\n have = (s.bi_valid + 42) >> 3; /* number of header bytes */\n if (s.strm.avail_out < have) { /* need room for header */\n break;\n }\n /* maximum stored block length that will fit in avail_out: */\n have = s.strm.avail_out - have;\n left = s.strstart - s.block_start; /* bytes left in window */\n if (len > left + s.strm.avail_in) {\n len = left + s.strm.avail_in; /* limit len to the input */\n }\n if (len > have) {\n len = have; /* limit len to the output */\n }\n\n /* If the stored block would be less than min_block in length, or if\n * unable to copy all of the available input when flushing, then try\n * copying to the window and the pending buffer instead. Also don't\n * write an empty block when flushing -- deflate() does that.\n */\n if (len < min_block && ((len === 0 && flush !== Z_FINISH$3) ||\n flush === Z_NO_FLUSH$2 ||\n len !== left + s.strm.avail_in)) {\n break;\n }\n\n /* Make a dummy stored block in pending to get the header bytes,\n * including any pending bits. This also updates the debugging counts.\n */\n last = flush === Z_FINISH$3 && len === left + s.strm.avail_in ? 1 : 0;\n _tr_stored_block(s, 0, 0, last);\n\n /* Replace the lengths in the dummy stored block with len. */\n s.pending_buf[s.pending - 4] = len;\n s.pending_buf[s.pending - 3] = len >> 8;\n s.pending_buf[s.pending - 2] = ~len;\n s.pending_buf[s.pending - 1] = ~len >> 8;\n\n /* Write the stored block header bytes. */\n flush_pending(s.strm);\n\n//#ifdef ZLIB_DEBUG\n// /* Update debugging counts for the data about to be copied. */\n// s->compressed_len += len << 3;\n// s->bits_sent += len << 3;\n//#endif\n\n /* Copy uncompressed bytes from the window to next_out. */\n if (left) {\n if (left > len) {\n left = len;\n }\n //zmemcpy(s->strm->next_out, s->window + s->block_start, left);\n s.strm.output.set(s.window.subarray(s.block_start, s.block_start + left), s.strm.next_out);\n s.strm.next_out += left;\n s.strm.avail_out -= left;\n s.strm.total_out += left;\n s.block_start += left;\n len -= left;\n }\n\n /* Copy uncompressed bytes directly from next_in to next_out, updating\n * the check value.\n */\n if (len) {\n read_buf(s.strm, s.strm.output, s.strm.next_out, len);\n s.strm.next_out += len;\n s.strm.avail_out -= len;\n s.strm.total_out += len;\n }\n } while (last === 0);\n\n /* Update the sliding window with the last s->w_size bytes of the copied\n * data, or append all of the copied data to the existing window if less\n * than s->w_size bytes were copied. Also update the number of bytes to\n * insert in the hash tables, in the event that deflateParams() switches to\n * a non-zero compression level.\n */\n used -= s.strm.avail_in; /* number of input bytes directly copied */\n if (used) {\n /* If any input was used, then no unused input remains in the window,\n * therefore s->block_start == s->strstart.\n */\n if (used >= s.w_size) { /* supplant the previous history */\n s.matches = 2; /* clear hash */\n //zmemcpy(s->window, s->strm->next_in - s->w_size, s->w_size);\n s.window.set(s.strm.input.subarray(s.strm.next_in - s.w_size, s.strm.next_in), 0);\n s.strstart = s.w_size;\n s.insert = s.strstart;\n }\n else {\n if (s.window_size - s.strstart <= used) {\n /* Slide the window down. */\n s.strstart -= s.w_size;\n //zmemcpy(s->window, s->window + s->w_size, s->strstart);\n s.window.set(s.window.subarray(s.w_size, s.w_size + s.strstart), 0);\n if (s.matches < 2) {\n s.matches++; /* add a pending slide_hash() */\n }\n if (s.insert > s.strstart) {\n s.insert = s.strstart;\n }\n }\n //zmemcpy(s->window + s->strstart, s->strm->next_in - used, used);\n s.window.set(s.strm.input.subarray(s.strm.next_in - used, s.strm.next_in), s.strstart);\n s.strstart += used;\n s.insert += used > s.w_size - s.insert ? s.w_size - s.insert : used;\n }\n s.block_start = s.strstart;\n }\n if (s.high_water < s.strstart) {\n s.high_water = s.strstart;\n }\n\n /* If the last block was written to next_out, then done. */\n if (last) {\n return BS_FINISH_DONE;\n }\n\n /* If flushing and all input has been consumed, then done. */\n if (flush !== Z_NO_FLUSH$2 && flush !== Z_FINISH$3 &&\n s.strm.avail_in === 0 && s.strstart === s.block_start) {\n return BS_BLOCK_DONE;\n }\n\n /* Fill the window with any remaining input. */\n have = s.window_size - s.strstart;\n if (s.strm.avail_in > have && s.block_start >= s.w_size) {\n /* Slide the window down. */\n s.block_start -= s.w_size;\n s.strstart -= s.w_size;\n //zmemcpy(s->window, s->window + s->w_size, s->strstart);\n s.window.set(s.window.subarray(s.w_size, s.w_size + s.strstart), 0);\n if (s.matches < 2) {\n s.matches++; /* add a pending slide_hash() */\n }\n have += s.w_size; /* more space now */\n if (s.insert > s.strstart) {\n s.insert = s.strstart;\n }\n }\n if (have > s.strm.avail_in) {\n have = s.strm.avail_in;\n }\n if (have) {\n read_buf(s.strm, s.window, s.strstart, have);\n s.strstart += have;\n s.insert += have > s.w_size - s.insert ? s.w_size - s.insert : have;\n }\n if (s.high_water < s.strstart) {\n s.high_water = s.strstart;\n }\n\n /* There was not enough avail_out to write a complete worthy or flushed\n * stored block to next_out. Write a stored block to pending instead, if we\n * have enough input for a worthy block, or if flushing and there is enough\n * room for the remaining input as a stored block in the pending buffer.\n */\n have = (s.bi_valid + 42) >> 3; /* number of header bytes */\n /* maximum stored block length that will fit in pending: */\n have = s.pending_buf_size - have > 65535/* MAX_STORED */ ? 65535/* MAX_STORED */ : s.pending_buf_size - have;\n min_block = have > s.w_size ? s.w_size : have;\n left = s.strstart - s.block_start;\n if (left >= min_block ||\n ((left || flush === Z_FINISH$3) && flush !== Z_NO_FLUSH$2 &&\n s.strm.avail_in === 0 && left <= have)) {\n len = left > have ? have : left;\n last = flush === Z_FINISH$3 && s.strm.avail_in === 0 &&\n len === left ? 1 : 0;\n _tr_stored_block(s, s.block_start, len, last);\n s.block_start += len;\n flush_pending(s.strm);\n }\n\n /* We've done all we can with the available input and output. */\n return last ? BS_FINISH_STARTED : BS_NEED_MORE;\n};\n\n\n/* ===========================================================================\n * Compress as much as possible from the input stream, return the current\n * block state.\n * This function does not perform lazy evaluation of matches and inserts\n * new strings in the dictionary only for unmatched strings or for short\n * matches. It is used only for the fast compression options.\n */\nconst deflate_fast = (s, flush) => {\n\n let hash_head; /* head of the hash chain */\n let bflush; /* set if current block must be flushed */\n\n for (;;) {\n /* Make sure that we always have enough lookahead, except\n * at the end of the input file. We need MAX_MATCH bytes\n * for the next match, plus MIN_MATCH bytes to insert the\n * string following the next match.\n */\n if (s.lookahead < MIN_LOOKAHEAD) {\n fill_window(s);\n if (s.lookahead < MIN_LOOKAHEAD && flush === Z_NO_FLUSH$2) {\n return BS_NEED_MORE;\n }\n if (s.lookahead === 0) {\n break; /* flush the current block */\n }\n }\n\n /* Insert the string window[strstart .. strstart+2] in the\n * dictionary, and set hash_head to the head of the hash chain:\n */\n hash_head = 0/*NIL*/;\n if (s.lookahead >= MIN_MATCH) {\n /*** INSERT_STRING(s, s.strstart, hash_head); ***/\n s.ins_h = HASH(s, s.ins_h, s.window[s.strstart + MIN_MATCH - 1]);\n hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h];\n s.head[s.ins_h] = s.strstart;\n /***/\n }\n\n /* Find the longest match, discarding those <= prev_length.\n * At this point we have always match_length < MIN_MATCH\n */\n if (hash_head !== 0/*NIL*/ && ((s.strstart - hash_head) <= (s.w_size - MIN_LOOKAHEAD))) {\n /* To simplify the code, we prevent matches with the string\n * of window index 0 (in particular we have to avoid a match\n * of the string with itself at the start of the input file).\n */\n s.match_length = longest_match(s, hash_head);\n /* longest_match() sets match_start */\n }\n if (s.match_length >= MIN_MATCH) {\n // check_match(s, s.strstart, s.match_start, s.match_length); // for debug only\n\n /*** _tr_tally_dist(s, s.strstart - s.match_start,\n s.match_length - MIN_MATCH, bflush); ***/\n bflush = _tr_tally(s, s.strstart - s.match_start, s.match_length - MIN_MATCH);\n\n s.lookahead -= s.match_length;\n\n /* Insert new strings in the hash table only if the match length\n * is not too large. This saves time but degrades compression.\n */\n if (s.match_length <= s.max_lazy_match/*max_insert_length*/ && s.lookahead >= MIN_MATCH) {\n s.match_length--; /* string at strstart already in table */\n do {\n s.strstart++;\n /*** INSERT_STRING(s, s.strstart, hash_head); ***/\n s.ins_h = HASH(s, s.ins_h, s.window[s.strstart + MIN_MATCH - 1]);\n hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h];\n s.head[s.ins_h] = s.strstart;\n /***/\n /* strstart never exceeds WSIZE-MAX_MATCH, so there are\n * always MIN_MATCH bytes ahead.\n */\n } while (--s.match_length !== 0);\n s.strstart++;\n } else\n {\n s.strstart += s.match_length;\n s.match_length = 0;\n s.ins_h = s.window[s.strstart];\n /* UPDATE_HASH(s, s.ins_h, s.window[s.strstart+1]); */\n s.ins_h = HASH(s, s.ins_h, s.window[s.strstart + 1]);\n\n//#if MIN_MATCH != 3\n// Call UPDATE_HASH() MIN_MATCH-3 more times\n//#endif\n /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not\n * matter since it will be recomputed at next deflate call.\n */\n }\n } else {\n /* No match, output a literal byte */\n //Tracevv((stderr,\"%c\", s.window[s.strstart]));\n /*** _tr_tally_lit(s, s.window[s.strstart], bflush); ***/\n bflush = _tr_tally(s, 0, s.window[s.strstart]);\n\n s.lookahead--;\n s.strstart++;\n }\n if (bflush) {\n /*** FLUSH_BLOCK(s, 0); ***/\n flush_block_only(s, false);\n if (s.strm.avail_out === 0) {\n return BS_NEED_MORE;\n }\n /***/\n }\n }\n s.insert = ((s.strstart < (MIN_MATCH - 1)) ? s.strstart : MIN_MATCH - 1);\n if (flush === Z_FINISH$3) {\n /*** FLUSH_BLOCK(s, 1); ***/\n flush_block_only(s, true);\n if (s.strm.avail_out === 0) {\n return BS_FINISH_STARTED;\n }\n /***/\n return BS_FINISH_DONE;\n }\n if (s.sym_next) {\n /*** FLUSH_BLOCK(s, 0); ***/\n flush_block_only(s, false);\n if (s.strm.avail_out === 0) {\n return BS_NEED_MORE;\n }\n /***/\n }\n return BS_BLOCK_DONE;\n};\n\n/* ===========================================================================\n * Same as above, but achieves better compression. We use a lazy\n * evaluation for matches: a match is finally adopted only if there is\n * no better match at the next window position.\n */\nconst deflate_slow = (s, flush) => {\n\n let hash_head; /* head of hash chain */\n let bflush; /* set if current block must be flushed */\n\n let max_insert;\n\n /* Process the input block. */\n for (;;) {\n /* Make sure that we always have enough lookahead, except\n * at the end of the input file. We need MAX_MATCH bytes\n * for the next match, plus MIN_MATCH bytes to insert the\n * string following the next match.\n */\n if (s.lookahead < MIN_LOOKAHEAD) {\n fill_window(s);\n if (s.lookahead < MIN_LOOKAHEAD && flush === Z_NO_FLUSH$2) {\n return BS_NEED_MORE;\n }\n if (s.lookahead === 0) { break; } /* flush the current block */\n }\n\n /* Insert the string window[strstart .. strstart+2] in the\n * dictionary, and set hash_head to the head of the hash chain:\n */\n hash_head = 0/*NIL*/;\n if (s.lookahead >= MIN_MATCH) {\n /*** INSERT_STRING(s, s.strstart, hash_head); ***/\n s.ins_h = HASH(s, s.ins_h, s.window[s.strstart + MIN_MATCH - 1]);\n hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h];\n s.head[s.ins_h] = s.strstart;\n /***/\n }\n\n /* Find the longest match, discarding those <= prev_length.\n */\n s.prev_length = s.match_length;\n s.prev_match = s.match_start;\n s.match_length = MIN_MATCH - 1;\n\n if (hash_head !== 0/*NIL*/ && s.prev_length < s.max_lazy_match &&\n s.strstart - hash_head <= (s.w_size - MIN_LOOKAHEAD)/*MAX_DIST(s)*/) {\n /* To simplify the code, we prevent matches with the string\n * of window index 0 (in particular we have to avoid a match\n * of the string with itself at the start of the input file).\n */\n s.match_length = longest_match(s, hash_head);\n /* longest_match() sets match_start */\n\n if (s.match_length <= 5 &&\n (s.strategy === Z_FILTERED || (s.match_length === MIN_MATCH && s.strstart - s.match_start > 4096/*TOO_FAR*/))) {\n\n /* If prev_match is also MIN_MATCH, match_start is garbage\n * but we will ignore the current match anyway.\n */\n s.match_length = MIN_MATCH - 1;\n }\n }\n /* If there was a match at the previous step and the current\n * match is not better, output the previous match:\n */\n if (s.prev_length >= MIN_MATCH && s.match_length <= s.prev_length) {\n max_insert = s.strstart + s.lookahead - MIN_MATCH;\n /* Do not insert strings in hash table beyond this. */\n\n //check_match(s, s.strstart-1, s.prev_match, s.prev_length);\n\n /***_tr_tally_dist(s, s.strstart - 1 - s.prev_match,\n s.prev_length - MIN_MATCH, bflush);***/\n bflush = _tr_tally(s, s.strstart - 1 - s.prev_match, s.prev_length - MIN_MATCH);\n /* Insert in hash table all strings up to the end of the match.\n * strstart-1 and strstart are already inserted. If there is not\n * enough lookahead, the last two strings are not inserted in\n * the hash table.\n */\n s.lookahead -= s.prev_length - 1;\n s.prev_length -= 2;\n do {\n if (++s.strstart <= max_insert) {\n /*** INSERT_STRING(s, s.strstart, hash_head); ***/\n s.ins_h = HASH(s, s.ins_h, s.window[s.strstart + MIN_MATCH - 1]);\n hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h];\n s.head[s.ins_h] = s.strstart;\n /***/\n }\n } while (--s.prev_length !== 0);\n s.match_available = 0;\n s.match_length = MIN_MATCH - 1;\n s.strstart++;\n\n if (bflush) {\n /*** FLUSH_BLOCK(s, 0); ***/\n flush_block_only(s, false);\n if (s.strm.avail_out === 0) {\n return BS_NEED_MORE;\n }\n /***/\n }\n\n } else if (s.match_available) {\n /* If there was no match at the previous position, output a\n * single literal. If there was a match but the current match\n * is longer, truncate the previous match to a single literal.\n */\n //Tracevv((stderr,\"%c\", s->window[s->strstart-1]));\n /*** _tr_tally_lit(s, s.window[s.strstart-1], bflush); ***/\n bflush = _tr_tally(s, 0, s.window[s.strstart - 1]);\n\n if (bflush) {\n /*** FLUSH_BLOCK_ONLY(s, 0) ***/\n flush_block_only(s, false);\n /***/\n }\n s.strstart++;\n s.lookahead--;\n if (s.strm.avail_out === 0) {\n return BS_NEED_MORE;\n }\n } else {\n /* There is no previous match to compare with, wait for\n * the next step to decide.\n */\n s.match_available = 1;\n s.strstart++;\n s.lookahead--;\n }\n }\n //Assert (flush != Z_NO_FLUSH, \"no flush?\");\n if (s.match_available) {\n //Tracevv((stderr,\"%c\", s->window[s->strstart-1]));\n /*** _tr_tally_lit(s, s.window[s.strstart-1], bflush); ***/\n bflush = _tr_tally(s, 0, s.window[s.strstart - 1]);\n\n s.match_available = 0;\n }\n s.insert = s.strstart < MIN_MATCH - 1 ? s.strstart : MIN_MATCH - 1;\n if (flush === Z_FINISH$3) {\n /*** FLUSH_BLOCK(s, 1); ***/\n flush_block_only(s, true);\n if (s.strm.avail_out === 0) {\n return BS_FINISH_STARTED;\n }\n /***/\n return BS_FINISH_DONE;\n }\n if (s.sym_next) {\n /*** FLUSH_BLOCK(s, 0); ***/\n flush_block_only(s, false);\n if (s.strm.avail_out === 0) {\n return BS_NEED_MORE;\n }\n /***/\n }\n\n return BS_BLOCK_DONE;\n};\n\n\n/* ===========================================================================\n * For Z_RLE, simply look for runs of bytes, generate matches only of distance\n * one. Do not maintain a hash table. (It will be regenerated if this run of\n * deflate switches away from Z_RLE.)\n */\nconst deflate_rle = (s, flush) => {\n\n let bflush; /* set if current block must be flushed */\n let prev; /* byte at distance one to match */\n let scan, strend; /* scan goes up to strend for length of run */\n\n const _win = s.window;\n\n for (;;) {\n /* Make sure that we always have enough lookahead, except\n * at the end of the input file. We need MAX_MATCH bytes\n * for the longest run, plus one for the unrolled loop.\n */\n if (s.lookahead <= MAX_MATCH) {\n fill_window(s);\n if (s.lookahead <= MAX_MATCH && flush === Z_NO_FLUSH$2) {\n return BS_NEED_MORE;\n }\n if (s.lookahead === 0) { break; } /* flush the current block */\n }\n\n /* See how many times the previous byte repeats */\n s.match_length = 0;\n if (s.lookahead >= MIN_MATCH && s.strstart > 0) {\n scan = s.strstart - 1;\n prev = _win[scan];\n if (prev === _win[++scan] && prev === _win[++scan] && prev === _win[++scan]) {\n strend = s.strstart + MAX_MATCH;\n do {\n /*jshint noempty:false*/\n } while (prev === _win[++scan] && prev === _win[++scan] &&\n prev === _win[++scan] && prev === _win[++scan] &&\n prev === _win[++scan] && prev === _win[++scan] &&\n prev === _win[++scan] && prev === _win[++scan] &&\n scan < strend);\n s.match_length = MAX_MATCH - (strend - scan);\n if (s.match_length > s.lookahead) {\n s.match_length = s.lookahead;\n }\n }\n //Assert(scan <= s->window+(uInt)(s->window_size-1), \"wild scan\");\n }\n\n /* Emit match if have run of MIN_MATCH or longer, else emit literal */\n if (s.match_length >= MIN_MATCH) {\n //check_match(s, s.strstart, s.strstart - 1, s.match_length);\n\n /*** _tr_tally_dist(s, 1, s.match_length - MIN_MATCH, bflush); ***/\n bflush = _tr_tally(s, 1, s.match_length - MIN_MATCH);\n\n s.lookahead -= s.match_length;\n s.strstart += s.match_length;\n s.match_length = 0;\n } else {\n /* No match, output a literal byte */\n //Tracevv((stderr,\"%c\", s->window[s->strstart]));\n /*** _tr_tally_lit(s, s.window[s.strstart], bflush); ***/\n bflush = _tr_tally(s, 0, s.window[s.strstart]);\n\n s.lookahead--;\n s.strstart++;\n }\n if (bflush) {\n /*** FLUSH_BLOCK(s, 0); ***/\n flush_block_only(s, false);\n if (s.strm.avail_out === 0) {\n return BS_NEED_MORE;\n }\n /***/\n }\n }\n s.insert = 0;\n if (flush === Z_FINISH$3) {\n /*** FLUSH_BLOCK(s, 1); ***/\n flush_block_only(s, true);\n if (s.strm.avail_out === 0) {\n return BS_FINISH_STARTED;\n }\n /***/\n return BS_FINISH_DONE;\n }\n if (s.sym_next) {\n /*** FLUSH_BLOCK(s, 0); ***/\n flush_block_only(s, false);\n if (s.strm.avail_out === 0) {\n return BS_NEED_MORE;\n }\n /***/\n }\n return BS_BLOCK_DONE;\n};\n\n/* ===========================================================================\n * For Z_HUFFMAN_ONLY, do not look for matches. Do not maintain a hash table.\n * (It will be regenerated if this run of deflate switches away from Huffman.)\n */\nconst deflate_huff = (s, flush) => {\n\n let bflush; /* set if current block must be flushed */\n\n for (;;) {\n /* Make sure that we have a literal to write. */\n if (s.lookahead === 0) {\n fill_window(s);\n if (s.lookahead === 0) {\n if (flush === Z_NO_FLUSH$2) {\n return BS_NEED_MORE;\n }\n break; /* flush the current block */\n }\n }\n\n /* Output a literal byte */\n s.match_length = 0;\n //Tracevv((stderr,\"%c\", s->window[s->strstart]));\n /*** _tr_tally_lit(s, s.window[s.strstart], bflush); ***/\n bflush = _tr_tally(s, 0, s.window[s.strstart]);\n s.lookahead--;\n s.strstart++;\n if (bflush) {\n /*** FLUSH_BLOCK(s, 0); ***/\n flush_block_only(s, false);\n if (s.strm.avail_out === 0) {\n return BS_NEED_MORE;\n }\n /***/\n }\n }\n s.insert = 0;\n if (flush === Z_FINISH$3) {\n /*** FLUSH_BLOCK(s, 1); ***/\n flush_block_only(s, true);\n if (s.strm.avail_out === 0) {\n return BS_FINISH_STARTED;\n }\n /***/\n return BS_FINISH_DONE;\n }\n if (s.sym_next) {\n /*** FLUSH_BLOCK(s, 0); ***/\n flush_block_only(s, false);\n if (s.strm.avail_out === 0) {\n return BS_NEED_MORE;\n }\n /***/\n }\n return BS_BLOCK_DONE;\n};\n\n/* Values for max_lazy_match, good_match and max_chain_length, depending on\n * the desired pack level (0..9). The values given below have been tuned to\n * exclude worst case performance for pathological files. Better values may be\n * found for specific files.\n */\nfunction Config(good_length, max_lazy, nice_length, max_chain, func) {\n\n this.good_length = good_length;\n this.max_lazy = max_lazy;\n this.nice_length = nice_length;\n this.max_chain = max_chain;\n this.func = func;\n}\n\nconst configuration_table = [\n /* good lazy nice chain */\n new Config(0, 0, 0, 0, deflate_stored), /* 0 store only */\n new Config(4, 4, 8, 4, deflate_fast), /* 1 max speed, no lazy matches */\n new Config(4, 5, 16, 8, deflate_fast), /* 2 */\n new Config(4, 6, 32, 32, deflate_fast), /* 3 */\n\n new Config(4, 4, 16, 16, deflate_slow), /* 4 lazy matches */\n new Config(8, 16, 32, 32, deflate_slow), /* 5 */\n new Config(8, 16, 128, 128, deflate_slow), /* 6 */\n new Config(8, 32, 128, 256, deflate_slow), /* 7 */\n new Config(32, 128, 258, 1024, deflate_slow), /* 8 */\n new Config(32, 258, 258, 4096, deflate_slow) /* 9 max compression */\n];\n\n\n/* ===========================================================================\n * Initialize the \"longest match\" routines for a new zlib stream\n */\nconst lm_init = (s) => {\n\n s.window_size = 2 * s.w_size;\n\n /*** CLEAR_HASH(s); ***/\n zero(s.head); // Fill with NIL (= 0);\n\n /* Set the default configuration parameters:\n */\n s.max_lazy_match = configuration_table[s.level].max_lazy;\n s.good_match = configuration_table[s.level].good_length;\n s.nice_match = configuration_table[s.level].nice_length;\n s.max_chain_length = configuration_table[s.level].max_chain;\n\n s.strstart = 0;\n s.block_start = 0;\n s.lookahead = 0;\n s.insert = 0;\n s.match_length = s.prev_length = MIN_MATCH - 1;\n s.match_available = 0;\n s.ins_h = 0;\n};\n\n\nfunction DeflateState() {\n this.strm = null; /* pointer back to this zlib stream */\n this.status = 0; /* as the name implies */\n this.pending_buf = null; /* output still pending */\n this.pending_buf_size = 0; /* size of pending_buf */\n this.pending_out = 0; /* next pending byte to output to the stream */\n this.pending = 0; /* nb of bytes in the pending buffer */\n this.wrap = 0; /* bit 0 true for zlib, bit 1 true for gzip */\n this.gzhead = null; /* gzip header information to write */\n this.gzindex = 0; /* where in extra, name, or comment */\n this.method = Z_DEFLATED$2; /* can only be DEFLATED */\n this.last_flush = -1; /* value of flush param for previous deflate call */\n\n this.w_size = 0; /* LZ77 window size (32K by default) */\n this.w_bits = 0; /* log2(w_size) (8..16) */\n this.w_mask = 0; /* w_size - 1 */\n\n this.window = null;\n /* Sliding window. Input bytes are read into the second half of the window,\n * and move to the first half later to keep a dictionary of at least wSize\n * bytes. With this organization, matches are limited to a distance of\n * wSize-MAX_MATCH bytes, but this ensures that IO is always\n * performed with a length multiple of the block size.\n */\n\n this.window_size = 0;\n /* Actual size of window: 2*wSize, except when the user input buffer\n * is directly used as sliding window.\n */\n\n this.prev = null;\n /* Link to older string with same hash index. To limit the size of this\n * array to 64K, this link is maintained only for the last 32K strings.\n * An index in this array is thus a window index modulo 32K.\n */\n\n this.head = null; /* Heads of the hash chains or NIL. */\n\n this.ins_h = 0; /* hash index of string to be inserted */\n this.hash_size = 0; /* number of elements in hash table */\n this.hash_bits = 0; /* log2(hash_size) */\n this.hash_mask = 0; /* hash_size-1 */\n\n this.hash_shift = 0;\n /* Number of bits by which ins_h must be shifted at each input\n * step. It must be such that after MIN_MATCH steps, the oldest\n * byte no longer takes part in the hash key, that is:\n * hash_shift * MIN_MATCH >= hash_bits\n */\n\n this.block_start = 0;\n /* Window position at the beginning of the current output block. Gets\n * negative when the window is moved backwards.\n */\n\n this.match_length = 0; /* length of best match */\n this.prev_match = 0; /* previous match */\n this.match_available = 0; /* set if previous match exists */\n this.strstart = 0; /* start of string to insert */\n this.match_start = 0; /* start of matching string */\n this.lookahead = 0; /* number of valid bytes ahead in window */\n\n this.prev_length = 0;\n /* Length of the best match at previous step. Matches not greater than this\n * are discarded. This is used in the lazy match evaluation.\n */\n\n this.max_chain_length = 0;\n /* To speed up deflation, hash chains are never searched beyond this\n * length. A higher limit improves compression ratio but degrades the\n * speed.\n */\n\n this.max_lazy_match = 0;\n /* Attempt to find a better match only when the current match is strictly\n * smaller than this value. This mechanism is used only for compression\n * levels >= 4.\n */\n // That's alias to max_lazy_match, don't use directly\n //this.max_insert_length = 0;\n /* Insert new strings in the hash table only if the match length is not\n * greater than this length. This saves time but degrades compression.\n * max_insert_length is used only for compression levels <= 3.\n */\n\n this.level = 0; /* compression level (1..9) */\n this.strategy = 0; /* favor or force Huffman coding*/\n\n this.good_match = 0;\n /* Use a faster search when the previous match is longer than this */\n\n this.nice_match = 0; /* Stop searching when current match exceeds this */\n\n /* used by trees.c: */\n\n /* Didn't use ct_data typedef below to suppress compiler warning */\n\n // struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */\n // struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */\n // struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */\n\n // Use flat array of DOUBLE size, with interleaved fata,\n // because JS does not support effective\n this.dyn_ltree = new Uint16Array(HEAP_SIZE * 2);\n this.dyn_dtree = new Uint16Array((2 * D_CODES + 1) * 2);\n this.bl_tree = new Uint16Array((2 * BL_CODES + 1) * 2);\n zero(this.dyn_ltree);\n zero(this.dyn_dtree);\n zero(this.bl_tree);\n\n this.l_desc = null; /* desc. for literal tree */\n this.d_desc = null; /* desc. for distance tree */\n this.bl_desc = null; /* desc. for bit length tree */\n\n //ush bl_count[MAX_BITS+1];\n this.bl_count = new Uint16Array(MAX_BITS + 1);\n /* number of codes at each bit length for an optimal tree */\n\n //int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */\n this.heap = new Uint16Array(2 * L_CODES + 1); /* heap used to build the Huffman trees */\n zero(this.heap);\n\n this.heap_len = 0; /* number of elements in the heap */\n this.heap_max = 0; /* element of largest frequency */\n /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used.\n * The same heap array is used to build all trees.\n */\n\n this.depth = new Uint16Array(2 * L_CODES + 1); //uch depth[2*L_CODES+1];\n zero(this.depth);\n /* Depth of each subtree used as tie breaker for trees of equal frequency\n */\n\n this.sym_buf = 0; /* buffer for distances and literals/lengths */\n\n this.lit_bufsize = 0;\n /* Size of match buffer for literals/lengths. There are 4 reasons for\n * limiting lit_bufsize to 64K:\n * - frequencies can be kept in 16 bit counters\n * - if compression is not successful for the first block, all input\n * data is still in the window so we can still emit a stored block even\n * when input comes from standard input. (This can also be done for\n * all blocks if lit_bufsize is not greater than 32K.)\n * - if compression is not successful for a file smaller than 64K, we can\n * even emit a stored file instead of a stored block (saving 5 bytes).\n * This is applicable only for zip (not gzip or zlib).\n * - creating new Huffman trees less frequently may not provide fast\n * adaptation to changes in the input data statistics. (Take for\n * example a binary file with poorly compressible code followed by\n * a highly compressible string table.) Smaller buffer sizes give\n * fast adaptation but have of course the overhead of transmitting\n * trees more frequently.\n * - I can't count above 4\n */\n\n this.sym_next = 0; /* running index in sym_buf */\n this.sym_end = 0; /* symbol table full when sym_next reaches this */\n\n this.opt_len = 0; /* bit length of current block with optimal trees */\n this.static_len = 0; /* bit length of current block with static trees */\n this.matches = 0; /* number of string matches in current block */\n this.insert = 0; /* bytes at end of window left to insert */\n\n\n this.bi_buf = 0;\n /* Output buffer. bits are inserted starting at the bottom (least\n * significant bits).\n */\n this.bi_valid = 0;\n /* Number of valid bits in bi_buf. All bits above the last valid bit\n * are always zero.\n */\n\n // Used for window memory init. We safely ignore it for JS. That makes\n // sense only for pointers and memory check tools.\n //this.high_water = 0;\n /* High water mark offset in window for initialized bytes -- bytes above\n * this are set to zero in order to avoid memory check warnings when\n * longest match routines access bytes past the input. This is then\n * updated to the new high water mark.\n */\n}\n\n\n/* =========================================================================\n * Check for a valid deflate stream state. Return 0 if ok, 1 if not.\n */\nconst deflateStateCheck = (strm) => {\n\n if (!strm) {\n return 1;\n }\n const s = strm.state;\n if (!s || s.strm !== strm || (s.status !== INIT_STATE &&\n//#ifdef GZIP\n s.status !== GZIP_STATE &&\n//#endif\n s.status !== EXTRA_STATE &&\n s.status !== NAME_STATE &&\n s.status !== COMMENT_STATE &&\n s.status !== HCRC_STATE &&\n s.status !== BUSY_STATE &&\n s.status !== FINISH_STATE)) {\n return 1;\n }\n return 0;\n};\n\n\nconst deflateResetKeep = (strm) => {\n\n if (deflateStateCheck(strm)) {\n return err(strm, Z_STREAM_ERROR$2);\n }\n\n strm.total_in = strm.total_out = 0;\n strm.data_type = Z_UNKNOWN;\n\n const s = strm.state;\n s.pending = 0;\n s.pending_out = 0;\n\n if (s.wrap < 0) {\n s.wrap = -s.wrap;\n /* was made negative by deflate(..., Z_FINISH); */\n }\n s.status =\n//#ifdef GZIP\n s.wrap === 2 ? GZIP_STATE :\n//#endif\n s.wrap ? INIT_STATE : BUSY_STATE;\n strm.adler = (s.wrap === 2) ?\n 0 // crc32(0, Z_NULL, 0)\n :\n 1; // adler32(0, Z_NULL, 0)\n s.last_flush = -2;\n _tr_init(s);\n return Z_OK$3;\n};\n\n\nconst deflateReset = (strm) => {\n\n const ret = deflateResetKeep(strm);\n if (ret === Z_OK$3) {\n lm_init(strm.state);\n }\n return ret;\n};\n\n\nconst deflateSetHeader = (strm, head) => {\n\n if (deflateStateCheck(strm) || strm.state.wrap !== 2) {\n return Z_STREAM_ERROR$2;\n }\n strm.state.gzhead = head;\n return Z_OK$3;\n};\n\n\nconst deflateInit2 = (strm, level, method, windowBits, memLevel, strategy) => {\n\n if (!strm) { // === Z_NULL\n return Z_STREAM_ERROR$2;\n }\n let wrap = 1;\n\n if (level === Z_DEFAULT_COMPRESSION$1) {\n level = 6;\n }\n\n if (windowBits < 0) { /* suppress zlib wrapper */\n wrap = 0;\n windowBits = -windowBits;\n }\n\n else if (windowBits > 15) {\n wrap = 2; /* write gzip wrapper instead */\n windowBits -= 16;\n }\n\n\n if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method !== Z_DEFLATED$2 ||\n windowBits < 8 || windowBits > 15 || level < 0 || level > 9 ||\n strategy < 0 || strategy > Z_FIXED || (windowBits === 8 && wrap !== 1)) {\n return err(strm, Z_STREAM_ERROR$2);\n }\n\n\n if (windowBits === 8) {\n windowBits = 9;\n }\n /* until 256-byte window bug fixed */\n\n const s = new DeflateState();\n\n strm.state = s;\n s.strm = strm;\n s.status = INIT_STATE; /* to pass state test in deflateReset() */\n\n s.wrap = wrap;\n s.gzhead = null;\n s.w_bits = windowBits;\n s.w_size = 1 << s.w_bits;\n s.w_mask = s.w_size - 1;\n\n s.hash_bits = memLevel + 7;\n s.hash_size = 1 << s.hash_bits;\n s.hash_mask = s.hash_size - 1;\n s.hash_shift = ~~((s.hash_bits + MIN_MATCH - 1) / MIN_MATCH);\n\n s.window = new Uint8Array(s.w_size * 2);\n s.head = new Uint16Array(s.hash_size);\n s.prev = new Uint16Array(s.w_size);\n\n // Don't need mem init magic for JS.\n //s.high_water = 0; /* nothing written to s->window yet */\n\n s.lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */\n\n /* We overlay pending_buf and sym_buf. This works since the average size\n * for length/distance pairs over any compressed block is assured to be 31\n * bits or less.\n *\n * Analysis: The longest fixed codes are a length code of 8 bits plus 5\n * extra bits, for lengths 131 to 257. The longest fixed distance codes are\n * 5 bits plus 13 extra bits, for distances 16385 to 32768. The longest\n * possible fixed-codes length/distance pair is then 31 bits total.\n *\n * sym_buf starts one-fourth of the way into pending_buf. So there are\n * three bytes in sym_buf for every four bytes in pending_buf. Each symbol\n * in sym_buf is three bytes -- two for the distance and one for the\n * literal/length. As each symbol is consumed, the pointer to the next\n * sym_buf value to read moves forward three bytes. From that symbol, up to\n * 31 bits are written to pending_buf. The closest the written pending_buf\n * bits gets to the next sym_buf symbol to read is just before the last\n * code is written. At that time, 31*(n-2) bits have been written, just\n * after 24*(n-2) bits have been consumed from sym_buf. sym_buf starts at\n * 8*n bits into pending_buf. (Note that the symbol buffer fills when n-1\n * symbols are written.) The closest the writing gets to what is unread is\n * then n+14 bits. Here n is lit_bufsize, which is 16384 by default, and\n * can range from 128 to 32768.\n *\n * Therefore, at a minimum, there are 142 bits of space between what is\n * written and what is read in the overlain buffers, so the symbols cannot\n * be overwritten by the compressed data. That space is actually 139 bits,\n * due to the three-bit fixed-code block header.\n *\n * That covers the case where either Z_FIXED is specified, forcing fixed\n * codes, or when the use of fixed codes is chosen, because that choice\n * results in a smaller compressed block than dynamic codes. That latter\n * condition then assures that the above analysis also covers all dynamic\n * blocks. A dynamic-code block will only be chosen to be emitted if it has\n * fewer bits than a fixed-code block would for the same set of symbols.\n * Therefore its average symbol length is assured to be less than 31. So\n * the compressed data for a dynamic block also cannot overwrite the\n * symbols from which it is being constructed.\n */\n\n s.pending_buf_size = s.lit_bufsize * 4;\n s.pending_buf = new Uint8Array(s.pending_buf_size);\n\n // It is offset from `s.pending_buf` (size is `s.lit_bufsize * 2`)\n //s->sym_buf = s->pending_buf + s->lit_bufsize;\n s.sym_buf = s.lit_bufsize;\n\n //s->sym_end = (s->lit_bufsize - 1) * 3;\n s.sym_end = (s.lit_bufsize - 1) * 3;\n /* We avoid equality with lit_bufsize*3 because of wraparound at 64K\n * on 16 bit machines and because stored blocks are restricted to\n * 64K-1 bytes.\n */\n\n s.level = level;\n s.strategy = strategy;\n s.method = method;\n\n return deflateReset(strm);\n};\n\nconst deflateInit = (strm, level) => {\n\n return deflateInit2(strm, level, Z_DEFLATED$2, MAX_WBITS$1, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY$1);\n};\n\n\n/* ========================================================================= */\nconst deflate$2 = (strm, flush) => {\n\n if (deflateStateCheck(strm) || flush > Z_BLOCK$1 || flush < 0) {\n return strm ? err(strm, Z_STREAM_ERROR$2) : Z_STREAM_ERROR$2;\n }\n\n const s = strm.state;\n\n if (!strm.output ||\n (strm.avail_in !== 0 && !strm.input) ||\n (s.status === FINISH_STATE && flush !== Z_FINISH$3)) {\n return err(strm, (strm.avail_out === 0) ? Z_BUF_ERROR$1 : Z_STREAM_ERROR$2);\n }\n\n const old_flush = s.last_flush;\n s.last_flush = flush;\n\n /* Flush as much pending output as possible */\n if (s.pending !== 0) {\n flush_pending(strm);\n if (strm.avail_out === 0) {\n /* Since avail_out is 0, deflate will be called again with\n * more output space, but possibly with both pending and\n * avail_in equal to zero. There won't be anything to do,\n * but this is not an error situation so make sure we\n * return OK instead of BUF_ERROR at next call of deflate:\n */\n s.last_flush = -1;\n return Z_OK$3;\n }\n\n /* Make sure there is something to do and avoid duplicate consecutive\n * flushes. For repeated and useless calls with Z_FINISH, we keep\n * returning Z_STREAM_END instead of Z_BUF_ERROR.\n */\n } else if (strm.avail_in === 0 && rank(flush) <= rank(old_flush) &&\n flush !== Z_FINISH$3) {\n return err(strm, Z_BUF_ERROR$1);\n }\n\n /* User must not provide more input after the first FINISH: */\n if (s.status === FINISH_STATE && strm.avail_in !== 0) {\n return err(strm, Z_BUF_ERROR$1);\n }\n\n /* Write the header */\n if (s.status === INIT_STATE && s.wrap === 0) {\n s.status = BUSY_STATE;\n }\n if (s.status === INIT_STATE) {\n /* zlib header */\n let header = (Z_DEFLATED$2 + ((s.w_bits - 8) << 4)) << 8;\n let level_flags = -1;\n\n if (s.strategy >= Z_HUFFMAN_ONLY || s.level < 2) {\n level_flags = 0;\n } else if (s.level < 6) {\n level_flags = 1;\n } else if (s.level === 6) {\n level_flags = 2;\n } else {\n level_flags = 3;\n }\n header |= (level_flags << 6);\n if (s.strstart !== 0) { header |= PRESET_DICT; }\n header += 31 - (header % 31);\n\n putShortMSB(s, header);\n\n /* Save the adler32 of the preset dictionary: */\n if (s.strstart !== 0) {\n putShortMSB(s, strm.adler >>> 16);\n putShortMSB(s, strm.adler & 0xffff);\n }\n strm.adler = 1; // adler32(0L, Z_NULL, 0);\n s.status = BUSY_STATE;\n\n /* Compression must start with an empty pending buffer */\n flush_pending(strm);\n if (s.pending !== 0) {\n s.last_flush = -1;\n return Z_OK$3;\n }\n }\n//#ifdef GZIP\n if (s.status === GZIP_STATE) {\n /* gzip header */\n strm.adler = 0; //crc32(0L, Z_NULL, 0);\n put_byte(s, 31);\n put_byte(s, 139);\n put_byte(s, 8);\n if (!s.gzhead) { // s->gzhead == Z_NULL\n put_byte(s, 0);\n put_byte(s, 0);\n put_byte(s, 0);\n put_byte(s, 0);\n put_byte(s, 0);\n put_byte(s, s.level === 9 ? 2 :\n (s.strategy >= Z_HUFFMAN_ONLY || s.level < 2 ?\n 4 : 0));\n put_byte(s, OS_CODE);\n s.status = BUSY_STATE;\n\n /* Compression must start with an empty pending buffer */\n flush_pending(strm);\n if (s.pending !== 0) {\n s.last_flush = -1;\n return Z_OK$3;\n }\n }\n else {\n put_byte(s, (s.gzhead.text ? 1 : 0) +\n (s.gzhead.hcrc ? 2 : 0) +\n (!s.gzhead.extra ? 0 : 4) +\n (!s.gzhead.name ? 0 : 8) +\n (!s.gzhead.comment ? 0 : 16)\n );\n put_byte(s, s.gzhead.time & 0xff);\n put_byte(s, (s.gzhead.time >> 8) & 0xff);\n put_byte(s, (s.gzhead.time >> 16) & 0xff);\n put_byte(s, (s.gzhead.time >> 24) & 0xff);\n put_byte(s, s.level === 9 ? 2 :\n (s.strategy >= Z_HUFFMAN_ONLY || s.level < 2 ?\n 4 : 0));\n put_byte(s, s.gzhead.os & 0xff);\n if (s.gzhead.extra && s.gzhead.extra.length) {\n put_byte(s, s.gzhead.extra.length & 0xff);\n put_byte(s, (s.gzhead.extra.length >> 8) & 0xff);\n }\n if (s.gzhead.hcrc) {\n strm.adler = crc32_1$1(strm.adler, s.pending_buf, s.pending, 0);\n }\n s.gzindex = 0;\n s.status = EXTRA_STATE;\n }\n }\n if (s.status === EXTRA_STATE) {\n if (s.gzhead.extra/* != Z_NULL*/) {\n let beg = s.pending; /* start of bytes to update crc */\n let left = (s.gzhead.extra.length & 0xffff) - s.gzindex;\n while (s.pending + left > s.pending_buf_size) {\n let copy = s.pending_buf_size - s.pending;\n // zmemcpy(s.pending_buf + s.pending,\n // s.gzhead.extra + s.gzindex, copy);\n s.pending_buf.set(s.gzhead.extra.subarray(s.gzindex, s.gzindex + copy), s.pending);\n s.pending = s.pending_buf_size;\n //--- HCRC_UPDATE(beg) ---//\n if (s.gzhead.hcrc && s.pending > beg) {\n strm.adler = crc32_1$1(strm.adler, s.pending_buf, s.pending - beg, beg);\n }\n //---//\n s.gzindex += copy;\n flush_pending(strm);\n if (s.pending !== 0) {\n s.last_flush = -1;\n return Z_OK$3;\n }\n beg = 0;\n left -= copy;\n }\n // JS specific: s.gzhead.extra may be TypedArray or Array for backward compatibility\n // TypedArray.slice and TypedArray.from don't exist in IE10-IE11\n let gzhead_extra = new Uint8Array(s.gzhead.extra);\n // zmemcpy(s->pending_buf + s->pending,\n // s->gzhead->extra + s->gzindex, left);\n s.pending_buf.set(gzhead_extra.subarray(s.gzindex, s.gzindex + left), s.pending);\n s.pending += left;\n //--- HCRC_UPDATE(beg) ---//\n if (s.gzhead.hcrc && s.pending > beg) {\n strm.adler = crc32_1$1(strm.adler, s.pending_buf, s.pending - beg, beg);\n }\n //---//\n s.gzindex = 0;\n }\n s.status = NAME_STATE;\n }\n if (s.status === NAME_STATE) {\n if (s.gzhead.name/* != Z_NULL*/) {\n let beg = s.pending; /* start of bytes to update crc */\n let val;\n do {\n if (s.pending === s.pending_buf_size) {\n //--- HCRC_UPDATE(beg) ---//\n if (s.gzhead.hcrc && s.pending > beg) {\n strm.adler = crc32_1$1(strm.adler, s.pending_buf, s.pending - beg, beg);\n }\n //---//\n flush_pending(strm);\n if (s.pending !== 0) {\n s.last_flush = -1;\n return Z_OK$3;\n }\n beg = 0;\n }\n // JS specific: little magic to add zero terminator to end of string\n if (s.gzindex < s.gzhead.name.length) {\n val = s.gzhead.name.charCodeAt(s.gzindex++) & 0xff;\n } else {\n val = 0;\n }\n put_byte(s, val);\n } while (val !== 0);\n //--- HCRC_UPDATE(beg) ---//\n if (s.gzhead.hcrc && s.pending > beg) {\n strm.adler = crc32_1$1(strm.adler, s.pending_buf, s.pending - beg, beg);\n }\n //---//\n s.gzindex = 0;\n }\n s.status = COMMENT_STATE;\n }\n if (s.status === COMMENT_STATE) {\n if (s.gzhead.comment/* != Z_NULL*/) {\n let beg = s.pending; /* start of bytes to update crc */\n let val;\n do {\n if (s.pending === s.pending_buf_size) {\n //--- HCRC_UPDATE(beg) ---//\n if (s.gzhead.hcrc && s.pending > beg) {\n strm.adler = crc32_1$1(strm.adler, s.pending_buf, s.pending - beg, beg);\n }\n //---//\n flush_pending(strm);\n if (s.pending !== 0) {\n s.last_flush = -1;\n return Z_OK$3;\n }\n beg = 0;\n }\n // JS specific: little magic to add zero terminator to end of string\n if (s.gzindex < s.gzhead.comment.length) {\n val = s.gzhead.comment.charCodeAt(s.gzindex++) & 0xff;\n } else {\n val = 0;\n }\n put_byte(s, val);\n } while (val !== 0);\n //--- HCRC_UPDATE(beg) ---//\n if (s.gzhead.hcrc && s.pending > beg) {\n strm.adler = crc32_1$1(strm.adler, s.pending_buf, s.pending - beg, beg);\n }\n //---//\n }\n s.status = HCRC_STATE;\n }\n if (s.status === HCRC_STATE) {\n if (s.gzhead.hcrc) {\n if (s.pending + 2 > s.pending_buf_size) {\n flush_pending(strm);\n if (s.pending !== 0) {\n s.last_flush = -1;\n return Z_OK$3;\n }\n }\n put_byte(s, strm.adler & 0xff);\n put_byte(s, (strm.adler >> 8) & 0xff);\n strm.adler = 0; //crc32(0L, Z_NULL, 0);\n }\n s.status = BUSY_STATE;\n\n /* Compression must start with an empty pending buffer */\n flush_pending(strm);\n if (s.pending !== 0) {\n s.last_flush = -1;\n return Z_OK$3;\n }\n }\n//#endif\n\n /* Start a new block or continue the current one.\n */\n if (strm.avail_in !== 0 || s.lookahead !== 0 ||\n (flush !== Z_NO_FLUSH$2 && s.status !== FINISH_STATE)) {\n let bstate = s.level === 0 ? deflate_stored(s, flush) :\n s.strategy === Z_HUFFMAN_ONLY ? deflate_huff(s, flush) :\n s.strategy === Z_RLE ? deflate_rle(s, flush) :\n configuration_table[s.level].func(s, flush);\n\n if (bstate === BS_FINISH_STARTED || bstate === BS_FINISH_DONE) {\n s.status = FINISH_STATE;\n }\n if (bstate === BS_NEED_MORE || bstate === BS_FINISH_STARTED) {\n if (strm.avail_out === 0) {\n s.last_flush = -1;\n /* avoid BUF_ERROR next call, see above */\n }\n return Z_OK$3;\n /* If flush != Z_NO_FLUSH && avail_out == 0, the next call\n * of deflate should use the same flush parameter to make sure\n * that the flush is complete. So we don't have to output an\n * empty block here, this will be done at next call. This also\n * ensures that for a very small output buffer, we emit at most\n * one empty block.\n */\n }\n if (bstate === BS_BLOCK_DONE) {\n if (flush === Z_PARTIAL_FLUSH) {\n _tr_align(s);\n }\n else if (flush !== Z_BLOCK$1) { /* FULL_FLUSH or SYNC_FLUSH */\n\n _tr_stored_block(s, 0, 0, false);\n /* For a full flush, this empty block will be recognized\n * as a special marker by inflate_sync().\n */\n if (flush === Z_FULL_FLUSH$1) {\n /*** CLEAR_HASH(s); ***/ /* forget history */\n zero(s.head); // Fill with NIL (= 0);\n\n if (s.lookahead === 0) {\n s.strstart = 0;\n s.block_start = 0;\n s.insert = 0;\n }\n }\n }\n flush_pending(strm);\n if (strm.avail_out === 0) {\n s.last_flush = -1; /* avoid BUF_ERROR at next call, see above */\n return Z_OK$3;\n }\n }\n }\n\n if (flush !== Z_FINISH$3) { return Z_OK$3; }\n if (s.wrap <= 0) { return Z_STREAM_END$3; }\n\n /* Write the trailer */\n if (s.wrap === 2) {\n put_byte(s, strm.adler & 0xff);\n put_byte(s, (strm.adler >> 8) & 0xff);\n put_byte(s, (strm.adler >> 16) & 0xff);\n put_byte(s, (strm.adler >> 24) & 0xff);\n put_byte(s, strm.total_in & 0xff);\n put_byte(s, (strm.total_in >> 8) & 0xff);\n put_byte(s, (strm.total_in >> 16) & 0xff);\n put_byte(s, (strm.total_in >> 24) & 0xff);\n }\n else\n {\n putShortMSB(s, strm.adler >>> 16);\n putShortMSB(s, strm.adler & 0xffff);\n }\n\n flush_pending(strm);\n /* If avail_out is zero, the application will call deflate again\n * to flush the rest.\n */\n if (s.wrap > 0) { s.wrap = -s.wrap; }\n /* write the trailer only once! */\n return s.pending !== 0 ? Z_OK$3 : Z_STREAM_END$3;\n};\n\n\nconst deflateEnd = (strm) => {\n\n if (deflateStateCheck(strm)) {\n return Z_STREAM_ERROR$2;\n }\n\n const status = strm.state.status;\n\n strm.state = null;\n\n return status === BUSY_STATE ? err(strm, Z_DATA_ERROR$2) : Z_OK$3;\n};\n\n\n/* =========================================================================\n * Initializes the compression dictionary from the given byte\n * sequence without producing any compressed output.\n */\nconst deflateSetDictionary = (strm, dictionary) => {\n\n let dictLength = dictionary.length;\n\n if (deflateStateCheck(strm)) {\n return Z_STREAM_ERROR$2;\n }\n\n const s = strm.state;\n const wrap = s.wrap;\n\n if (wrap === 2 || (wrap === 1 && s.status !== INIT_STATE) || s.lookahead) {\n return Z_STREAM_ERROR$2;\n }\n\n /* when using zlib wrappers, compute Adler-32 for provided dictionary */\n if (wrap === 1) {\n /* adler32(strm->adler, dictionary, dictLength); */\n strm.adler = adler32_1$1(strm.adler, dictionary, dictLength, 0);\n }\n\n s.wrap = 0; /* avoid computing Adler-32 in read_buf */\n\n /* if dictionary would fill window, just replace the history */\n if (dictLength >= s.w_size) {\n if (wrap === 0) { /* already empty otherwise */\n /*** CLEAR_HASH(s); ***/\n zero(s.head); // Fill with NIL (= 0);\n s.strstart = 0;\n s.block_start = 0;\n s.insert = 0;\n }\n /* use the tail */\n // dictionary = dictionary.slice(dictLength - s.w_size);\n let tmpDict = new Uint8Array(s.w_size);\n tmpDict.set(dictionary.subarray(dictLength - s.w_size, dictLength), 0);\n dictionary = tmpDict;\n dictLength = s.w_size;\n }\n /* insert dictionary into window and hash */\n const avail = strm.avail_in;\n const next = strm.next_in;\n const input = strm.input;\n strm.avail_in = dictLength;\n strm.next_in = 0;\n strm.input = dictionary;\n fill_window(s);\n while (s.lookahead >= MIN_MATCH) {\n let str = s.strstart;\n let n = s.lookahead - (MIN_MATCH - 1);\n do {\n /* UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); */\n s.ins_h = HASH(s, s.ins_h, s.window[str + MIN_MATCH - 1]);\n\n s.prev[str & s.w_mask] = s.head[s.ins_h];\n\n s.head[s.ins_h] = str;\n str++;\n } while (--n);\n s.strstart = str;\n s.lookahead = MIN_MATCH - 1;\n fill_window(s);\n }\n s.strstart += s.lookahead;\n s.block_start = s.strstart;\n s.insert = s.lookahead;\n s.lookahead = 0;\n s.match_length = s.prev_length = MIN_MATCH - 1;\n s.match_available = 0;\n strm.next_in = next;\n strm.input = input;\n strm.avail_in = avail;\n s.wrap = wrap;\n return Z_OK$3;\n};\n\n\nvar deflateInit_1 = deflateInit;\nvar deflateInit2_1 = deflateInit2;\nvar deflateReset_1 = deflateReset;\nvar deflateResetKeep_1 = deflateResetKeep;\nvar deflateSetHeader_1 = deflateSetHeader;\nvar deflate_2$1 = deflate$2;\nvar deflateEnd_1 = deflateEnd;\nvar deflateSetDictionary_1 = deflateSetDictionary;\nvar deflateInfo = 'pako deflate (from Nodeca project)';\n\n/* Not implemented\nmodule.exports.deflateBound = deflateBound;\nmodule.exports.deflateCopy = deflateCopy;\nmodule.exports.deflateGetDictionary = deflateGetDictionary;\nmodule.exports.deflateParams = deflateParams;\nmodule.exports.deflatePending = deflatePending;\nmodule.exports.deflatePrime = deflatePrime;\nmodule.exports.deflateTune = deflateTune;\n*/\n\nvar deflate_1$2 = {\n\tdeflateInit: deflateInit_1,\n\tdeflateInit2: deflateInit2_1,\n\tdeflateReset: deflateReset_1,\n\tdeflateResetKeep: deflateResetKeep_1,\n\tdeflateSetHeader: deflateSetHeader_1,\n\tdeflate: deflate_2$1,\n\tdeflateEnd: deflateEnd_1,\n\tdeflateSetDictionary: deflateSetDictionary_1,\n\tdeflateInfo: deflateInfo\n};\n\nconst _has$1 = (obj, key) => {\n return Object.prototype.hasOwnProperty.call(obj, key);\n};\n\nvar assign$1 = function (obj /*from1, from2, from3, ...*/) {\n const sources = Array.prototype.slice.call(arguments, 1);\n while (sources.length) {\n const source = sources.shift();\n if (!source) { continue; }\n\n if (typeof source !== 'object') {\n throw new TypeError(source + 'must be non-object');\n }\n\n for (const p in source) {\n if (_has$1(source, p)) {\n obj[p] = source[p];\n }\n }\n }\n\n return obj;\n};\n\n\n// Join array of chunks to single array.\nvar flattenChunks$1 = (chunks) => {\n // calculate data length\n let len = 0;\n\n for (let i = 0, l = chunks.length; i < l; i++) {\n len += chunks[i].length;\n }\n\n // join chunks\n const result = new Uint8Array(len);\n\n for (let i = 0, pos = 0, l = chunks.length; i < l; i++) {\n let chunk = chunks[i];\n result.set(chunk, pos);\n pos += chunk.length;\n }\n\n return result;\n};\n\nvar common$1 = {\n\tassign: assign$1,\n\tflattenChunks: flattenChunks$1\n};\n\n// String encode/decode helpers\n\n\n// Quick check if we can use fast array to bin string conversion\n//\n// - apply(Array) can fail on Android 2.2\n// - apply(Uint8Array) can fail on iOS 5.1 Safari\n//\nlet STR_APPLY_UIA_OK$1 = true;\n\ntry { String.fromCharCode.apply(null, new Uint8Array(1)); } catch (__) { STR_APPLY_UIA_OK$1 = false; }\n\n\n// Table with utf8 lengths (calculated by first byte of sequence)\n// Note, that 5 & 6-byte values and some 4-byte values can not be represented in JS,\n// because max possible codepoint is 0x10ffff\nconst _utf8len$1 = new Uint8Array(256);\nfor (let q = 0; q < 256; q++) {\n _utf8len$1[q] = (q >= 252 ? 6 : q >= 248 ? 5 : q >= 240 ? 4 : q >= 224 ? 3 : q >= 192 ? 2 : 1);\n}\n_utf8len$1[254] = _utf8len$1[254] = 1; // Invalid sequence start\n\n\n// convert string to array (typed, when possible)\nvar string2buf$1 = (str) => {\n if (typeof TextEncoder === 'function' && TextEncoder.prototype.encode) {\n return new TextEncoder().encode(str);\n }\n\n let buf, c, c2, m_pos, i, str_len = str.length, buf_len = 0;\n\n // count binary size\n for (m_pos = 0; m_pos < str_len; m_pos++) {\n c = str.charCodeAt(m_pos);\n if ((c & 0xfc00) === 0xd800 && (m_pos + 1 < str_len)) {\n c2 = str.charCodeAt(m_pos + 1);\n if ((c2 & 0xfc00) === 0xdc00) {\n c = 0x10000 + ((c - 0xd800) << 10) + (c2 - 0xdc00);\n m_pos++;\n }\n }\n buf_len += c < 0x80 ? 1 : c < 0x800 ? 2 : c < 0x10000 ? 3 : 4;\n }\n\n // allocate buffer\n buf = new Uint8Array(buf_len);\n\n // convert\n for (i = 0, m_pos = 0; i < buf_len; m_pos++) {\n c = str.charCodeAt(m_pos);\n if ((c & 0xfc00) === 0xd800 && (m_pos + 1 < str_len)) {\n c2 = str.charCodeAt(m_pos + 1);\n if ((c2 & 0xfc00) === 0xdc00) {\n c = 0x10000 + ((c - 0xd800) << 10) + (c2 - 0xdc00);\n m_pos++;\n }\n }\n if (c < 0x80) {\n /* one byte */\n buf[i++] = c;\n } else if (c < 0x800) {\n /* two bytes */\n buf[i++] = 0xC0 | (c >>> 6);\n buf[i++] = 0x80 | (c & 0x3f);\n } else if (c < 0x10000) {\n /* three bytes */\n buf[i++] = 0xE0 | (c >>> 12);\n buf[i++] = 0x80 | (c >>> 6 & 0x3f);\n buf[i++] = 0x80 | (c & 0x3f);\n } else {\n /* four bytes */\n buf[i++] = 0xf0 | (c >>> 18);\n buf[i++] = 0x80 | (c >>> 12 & 0x3f);\n buf[i++] = 0x80 | (c >>> 6 & 0x3f);\n buf[i++] = 0x80 | (c & 0x3f);\n }\n }\n\n return buf;\n};\n\n// Helper\nconst buf2binstring$1 = (buf, len) => {\n // On Chrome, the arguments in a function call that are allowed is `65534`.\n // If the length of the buffer is smaller than that, we can use this optimization,\n // otherwise we will take a slower path.\n if (len < 65534) {\n if (buf.subarray && STR_APPLY_UIA_OK$1) {\n return String.fromCharCode.apply(null, buf.length === len ? buf : buf.subarray(0, len));\n }\n }\n\n let result = '';\n for (let i = 0; i < len; i++) {\n result += String.fromCharCode(buf[i]);\n }\n return result;\n};\n\n\n// convert array to string\nvar buf2string$1 = (buf, max) => {\n const len = max || buf.length;\n\n if (typeof TextDecoder === 'function' && TextDecoder.prototype.decode) {\n return new TextDecoder().decode(buf.subarray(0, max));\n }\n\n let i, out;\n\n // Reserve max possible length (2 words per char)\n // NB: by unknown reasons, Array is significantly faster for\n // String.fromCharCode.apply than Uint16Array.\n const utf16buf = new Array(len * 2);\n\n for (out = 0, i = 0; i < len;) {\n let c = buf[i++];\n // quick process ascii\n if (c < 0x80) { utf16buf[out++] = c; continue; }\n\n let c_len = _utf8len$1[c];\n // skip 5 & 6 byte codes\n if (c_len > 4) { utf16buf[out++] = 0xfffd; i += c_len - 1; continue; }\n\n // apply mask on first byte\n c &= c_len === 2 ? 0x1f : c_len === 3 ? 0x0f : 0x07;\n // join the rest\n while (c_len > 1 && i < len) {\n c = (c << 6) | (buf[i++] & 0x3f);\n c_len--;\n }\n\n // terminated by end of string?\n if (c_len > 1) { utf16buf[out++] = 0xfffd; continue; }\n\n if (c < 0x10000) {\n utf16buf[out++] = c;\n } else {\n c -= 0x10000;\n utf16buf[out++] = 0xd800 | ((c >> 10) & 0x3ff);\n utf16buf[out++] = 0xdc00 | (c & 0x3ff);\n }\n }\n\n return buf2binstring$1(utf16buf, out);\n};\n\n\n// Calculate max possible position in utf8 buffer,\n// that will not break sequence. If that's not possible\n// - (very small limits) return max size as is.\n//\n// buf[] - utf8 bytes array\n// max - length limit (mandatory);\nvar utf8border$1 = (buf, max) => {\n\n max = max || buf.length;\n if (max > buf.length) { max = buf.length; }\n\n // go back from last position, until start of sequence found\n let pos = max - 1;\n while (pos >= 0 && (buf[pos] & 0xC0) === 0x80) { pos--; }\n\n // Very small and broken sequence,\n // return max, because we should return something anyway.\n if (pos < 0) { return max; }\n\n // If we came to start of buffer - that means buffer is too small,\n // return max too.\n if (pos === 0) { return max; }\n\n return (pos + _utf8len$1[buf[pos]] > max) ? pos : max;\n};\n\nvar strings$1 = {\n\tstring2buf: string2buf$1,\n\tbuf2string: buf2string$1,\n\tutf8border: utf8border$1\n};\n\n// (C) 1995-2013 Jean-loup Gailly and Mark Adler\n// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin\n//\n// This software is provided 'as-is', without any express or implied\n// warranty. In no event will the authors be held liable for any damages\n// arising from the use of this software.\n//\n// Permission is granted to anyone to use this software for any purpose,\n// including commercial applications, and to alter it and redistribute it\n// freely, subject to the following restrictions:\n//\n// 1. The origin of this software must not be misrepresented; you must not\n// claim that you wrote the original software. If you use this software\n// in a product, an acknowledgment in the product documentation would be\n// appreciated but is not required.\n// 2. Altered source versions must be plainly marked as such, and must not be\n// misrepresented as being the original software.\n// 3. This notice may not be removed or altered from any source distribution.\n\nfunction ZStream$1() {\n /* next input byte */\n this.input = null; // JS specific, because we have no pointers\n this.next_in = 0;\n /* number of bytes available at input */\n this.avail_in = 0;\n /* total number of input bytes read so far */\n this.total_in = 0;\n /* next output byte should be put there */\n this.output = null; // JS specific, because we have no pointers\n this.next_out = 0;\n /* remaining free space at output */\n this.avail_out = 0;\n /* total number of bytes output so far */\n this.total_out = 0;\n /* last error message, NULL if no error */\n this.msg = ''/*Z_NULL*/;\n /* not visible by applications */\n this.state = null;\n /* best guess about the data type: binary or text */\n this.data_type = 2/*Z_UNKNOWN*/;\n /* adler32 value of the uncompressed data */\n this.adler = 0;\n}\n\nvar zstream$1 = ZStream$1;\n\nconst toString$1 = Object.prototype.toString;\n\n/* Public constants ==========================================================*/\n/* ===========================================================================*/\n\nconst {\n Z_NO_FLUSH: Z_NO_FLUSH$1, Z_SYNC_FLUSH, Z_FULL_FLUSH, Z_FINISH: Z_FINISH$2,\n Z_OK: Z_OK$2, Z_STREAM_END: Z_STREAM_END$2,\n Z_DEFAULT_COMPRESSION,\n Z_DEFAULT_STRATEGY,\n Z_DEFLATED: Z_DEFLATED$1\n} = constants$2$1;\n\n/* ===========================================================================*/\n\n\n/**\n * class Deflate\n *\n * Generic JS-style wrapper for zlib calls. If you don't need\n * streaming behaviour - use more simple functions: [[deflate]],\n * [[deflateRaw]] and [[gzip]].\n **/\n\n/* internal\n * Deflate.chunks -> Array\n *\n * Chunks of output data, if [[Deflate#onData]] not overridden.\n **/\n\n/**\n * Deflate.result -> Uint8Array\n *\n * Compressed result, generated by default [[Deflate#onData]]\n * and [[Deflate#onEnd]] handlers. Filled after you push last chunk\n * (call [[Deflate#push]] with `Z_FINISH` / `true` param).\n **/\n\n/**\n * Deflate.err -> Number\n *\n * Error code after deflate finished. 0 (Z_OK) on success.\n * You will not need it in real life, because deflate errors\n * are possible only on wrong options or bad `onData` / `onEnd`\n * custom handlers.\n **/\n\n/**\n * Deflate.msg -> String\n *\n * Error message, if [[Deflate.err]] != 0\n **/\n\n\n/**\n * new Deflate(options)\n * - options (Object): zlib deflate options.\n *\n * Creates new deflator instance with specified params. Throws exception\n * on bad params. Supported options:\n *\n * - `level`\n * - `windowBits`\n * - `memLevel`\n * - `strategy`\n * - `dictionary`\n *\n * [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced)\n * for more information on these.\n *\n * Additional options, for internal needs:\n *\n * - `chunkSize` - size of generated data chunks (16K by default)\n * - `raw` (Boolean) - do raw deflate\n * - `gzip` (Boolean) - create gzip wrapper\n * - `header` (Object) - custom header for gzip\n * - `text` (Boolean) - true if compressed data believed to be text\n * - `time` (Number) - modification time, unix timestamp\n * - `os` (Number) - operation system code\n * - `extra` (Array) - array of bytes with extra data (max 65536)\n * - `name` (String) - file name (binary string)\n * - `comment` (String) - comment (binary string)\n * - `hcrc` (Boolean) - true if header crc should be added\n *\n * ##### Example:\n *\n * ```javascript\n * const pako = require('pako')\n * , chunk1 = new Uint8Array([1,2,3,4,5,6,7,8,9])\n * , chunk2 = new Uint8Array([10,11,12,13,14,15,16,17,18,19]);\n *\n * const deflate = new pako.Deflate({ level: 3});\n *\n * deflate.push(chunk1, false);\n * deflate.push(chunk2, true); // true -> last chunk\n *\n * if (deflate.err) { throw new Error(deflate.err); }\n *\n * console.log(deflate.result);\n * ```\n **/\nfunction Deflate$1(options) {\n this.options = common$1.assign({\n level: Z_DEFAULT_COMPRESSION,\n method: Z_DEFLATED$1,\n chunkSize: 16384,\n windowBits: 15,\n memLevel: 8,\n strategy: Z_DEFAULT_STRATEGY\n }, options || {});\n\n let opt = this.options;\n\n if (opt.raw && (opt.windowBits > 0)) {\n opt.windowBits = -opt.windowBits;\n }\n\n else if (opt.gzip && (opt.windowBits > 0) && (opt.windowBits < 16)) {\n opt.windowBits += 16;\n }\n\n this.err = 0; // error code, if happens (0 = Z_OK)\n this.msg = ''; // error message\n this.ended = false; // used to avoid multiple onEnd() calls\n this.chunks = []; // chunks of compressed data\n\n this.strm = new zstream$1();\n this.strm.avail_out = 0;\n\n let status = deflate_1$2.deflateInit2(\n this.strm,\n opt.level,\n opt.method,\n opt.windowBits,\n opt.memLevel,\n opt.strategy\n );\n\n if (status !== Z_OK$2) {\n throw new Error(messages$1[status]);\n }\n\n if (opt.header) {\n deflate_1$2.deflateSetHeader(this.strm, opt.header);\n }\n\n if (opt.dictionary) {\n let dict;\n // Convert data if needed\n if (typeof opt.dictionary === 'string') {\n // If we need to compress text, change encoding to utf8.\n dict = strings$1.string2buf(opt.dictionary);\n } else if (toString$1.call(opt.dictionary) === '[object ArrayBuffer]') {\n dict = new Uint8Array(opt.dictionary);\n } else {\n dict = opt.dictionary;\n }\n\n status = deflate_1$2.deflateSetDictionary(this.strm, dict);\n\n if (status !== Z_OK$2) {\n throw new Error(messages$1[status]);\n }\n\n this._dict_set = true;\n }\n}\n\n/**\n * Deflate#push(data[, flush_mode]) -> Boolean\n * - data (Uint8Array|ArrayBuffer|String): input data. Strings will be\n * converted to utf8 byte sequence.\n * - flush_mode (Number|Boolean): 0..6 for corresponding Z_NO_FLUSH..Z_TREE modes.\n * See constants. Skipped or `false` means Z_NO_FLUSH, `true` means Z_FINISH.\n *\n * Sends input data to deflate pipe, generating [[Deflate#onData]] calls with\n * new compressed chunks. Returns `true` on success. The last data block must\n * have `flush_mode` Z_FINISH (or `true`). That will flush internal pending\n * buffers and call [[Deflate#onEnd]].\n *\n * On fail call [[Deflate#onEnd]] with error code and return false.\n *\n * ##### Example\n *\n * ```javascript\n * push(chunk, false); // push one of data chunks\n * ...\n * push(chunk, true); // push last chunk\n * ```\n **/\nDeflate$1.prototype.push = function (data, flush_mode) {\n const strm = this.strm;\n const chunkSize = this.options.chunkSize;\n let status, _flush_mode;\n\n if (this.ended) { return false; }\n\n if (flush_mode === ~~flush_mode) _flush_mode = flush_mode;\n else _flush_mode = flush_mode === true ? Z_FINISH$2 : Z_NO_FLUSH$1;\n\n // Convert data if needed\n if (typeof data === 'string') {\n // If we need to compress text, change encoding to utf8.\n strm.input = strings$1.string2buf(data);\n } else if (toString$1.call(data) === '[object ArrayBuffer]') {\n strm.input = new Uint8Array(data);\n } else {\n strm.input = data;\n }\n\n strm.next_in = 0;\n strm.avail_in = strm.input.length;\n\n for (;;) {\n if (strm.avail_out === 0) {\n strm.output = new Uint8Array(chunkSize);\n strm.next_out = 0;\n strm.avail_out = chunkSize;\n }\n\n // Make sure avail_out > 6 to avoid repeating markers\n if ((_flush_mode === Z_SYNC_FLUSH || _flush_mode === Z_FULL_FLUSH) && strm.avail_out <= 6) {\n this.onData(strm.output.subarray(0, strm.next_out));\n strm.avail_out = 0;\n continue;\n }\n\n status = deflate_1$2.deflate(strm, _flush_mode);\n\n // Ended => flush and finish\n if (status === Z_STREAM_END$2) {\n if (strm.next_out > 0) {\n this.onData(strm.output.subarray(0, strm.next_out));\n }\n status = deflate_1$2.deflateEnd(this.strm);\n this.onEnd(status);\n this.ended = true;\n return status === Z_OK$2;\n }\n\n // Flush if out buffer full\n if (strm.avail_out === 0) {\n this.onData(strm.output);\n continue;\n }\n\n // Flush if requested and has data\n if (_flush_mode > 0 && strm.next_out > 0) {\n this.onData(strm.output.subarray(0, strm.next_out));\n strm.avail_out = 0;\n continue;\n }\n\n if (strm.avail_in === 0) break;\n }\n\n return true;\n};\n\n\n/**\n * Deflate#onData(chunk) -> Void\n * - chunk (Uint8Array): output data.\n *\n * By default, stores data blocks in `chunks[]` property and glue\n * those in `onEnd`. Override this handler, if you need another behaviour.\n **/\nDeflate$1.prototype.onData = function (chunk) {\n this.chunks.push(chunk);\n};\n\n\n/**\n * Deflate#onEnd(status) -> Void\n * - status (Number): deflate status. 0 (Z_OK) on success,\n * other if not.\n *\n * Called once after you tell deflate that the input stream is\n * complete (Z_FINISH). By default - join collected chunks,\n * free memory and fill `results` / `err` properties.\n **/\nDeflate$1.prototype.onEnd = function (status) {\n // On success - join\n if (status === Z_OK$2) {\n this.result = common$1.flattenChunks(this.chunks);\n }\n this.chunks = [];\n this.err = status;\n this.msg = this.strm.msg;\n};\n\n\n/**\n * deflate(data[, options]) -> Uint8Array\n * - data (Uint8Array|ArrayBuffer|String): input data to compress.\n * - options (Object): zlib deflate options.\n *\n * Compress `data` with deflate algorithm and `options`.\n *\n * Supported options are:\n *\n * - level\n * - windowBits\n * - memLevel\n * - strategy\n * - dictionary\n *\n * [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced)\n * for more information on these.\n *\n * Sugar (options):\n *\n * - `raw` (Boolean) - say that we work with raw stream, if you don't wish to specify\n * negative windowBits implicitly.\n *\n * ##### Example:\n *\n * ```javascript\n * const pako = require('pako')\n * const data = new Uint8Array([1,2,3,4,5,6,7,8,9]);\n *\n * console.log(pako.deflate(data));\n * ```\n **/\nfunction deflate$1(input, options) {\n const deflator = new Deflate$1(options);\n\n deflator.push(input, true);\n\n // That will never happens, if you don't cheat with options :)\n if (deflator.err) { throw deflator.msg || messages$1[deflator.err]; }\n\n return deflator.result;\n}\n\n\n/**\n * deflateRaw(data[, options]) -> Uint8Array\n * - data (Uint8Array|ArrayBuffer|String): input data to compress.\n * - options (Object): zlib deflate options.\n *\n * The same as [[deflate]], but creates raw data, without wrapper\n * (header and adler32 crc).\n **/\nfunction deflateRaw$1(input, options) {\n options = options || {};\n options.raw = true;\n return deflate$1(input, options);\n}\n\n\n/**\n * gzip(data[, options]) -> Uint8Array\n * - data (Uint8Array|ArrayBuffer|String): input data to compress.\n * - options (Object): zlib deflate options.\n *\n * The same as [[deflate]], but create gzip wrapper instead of\n * deflate one.\n **/\nfunction gzip$1(input, options) {\n options = options || {};\n options.gzip = true;\n return deflate$1(input, options);\n}\n\n\nvar Deflate_1$1 = Deflate$1;\nvar deflate_2 = deflate$1;\nvar deflateRaw_1$1 = deflateRaw$1;\nvar gzip_1$1 = gzip$1;\nvar constants$1 = constants$2$1;\n\nvar deflate_1$1 = {\n\tDeflate: Deflate_1$1,\n\tdeflate: deflate_2,\n\tdeflateRaw: deflateRaw_1$1,\n\tgzip: gzip_1$1,\n\tconstants: constants$1\n};\n\n// (C) 1995-2013 Jean-loup Gailly and Mark Adler\n// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin\n//\n// This software is provided 'as-is', without any express or implied\n// warranty. In no event will the authors be held liable for any damages\n// arising from the use of this software.\n//\n// Permission is granted to anyone to use this software for any purpose,\n// including commercial applications, and to alter it and redistribute it\n// freely, subject to the following restrictions:\n//\n// 1. The origin of this software must not be misrepresented; you must not\n// claim that you wrote the original software. If you use this software\n// in a product, an acknowledgment in the product documentation would be\n// appreciated but is not required.\n// 2. Altered source versions must be plainly marked as such, and must not be\n// misrepresented as being the original software.\n// 3. This notice may not be removed or altered from any source distribution.\n\n// See state defs from inflate.js\nconst BAD$1$1 = 16209; /* got a data error -- remain here until reset */\nconst TYPE$1$1 = 16191; /* i: waiting for type bits, including last-flag bit */\n\n/*\n Decode literal, length, and distance codes and write out the resulting\n literal and match bytes until either not enough input or output is\n available, an end-of-block is encountered, or a data error is encountered.\n When large enough input and output buffers are supplied to inflate(), for\n example, a 16K input buffer and a 64K output buffer, more than 95% of the\n inflate execution time is spent in this routine.\n\n Entry assumptions:\n\n state.mode === LEN\n strm.avail_in >= 6\n strm.avail_out >= 258\n start >= strm.avail_out\n state.bits < 8\n\n On return, state.mode is one of:\n\n LEN -- ran out of enough output space or enough available input\n TYPE -- reached end of block code, inflate() to interpret next block\n BAD -- error in block data\n\n Notes:\n\n - The maximum input bits used by a length/distance pair is 15 bits for the\n length code, 5 bits for the length extra, 15 bits for the distance code,\n and 13 bits for the distance extra. This totals 48 bits, or six bytes.\n Therefore if strm.avail_in >= 6, then there is enough input to avoid\n checking for available input while decoding.\n\n - The maximum bytes that a single length/distance pair can output is 258\n bytes, which is the maximum length that can be coded. inflate_fast()\n requires strm.avail_out >= 258 for each loop to avoid checking for\n output space.\n */\nvar inffast$1 = function inflate_fast(strm, start) {\n let _in; /* local strm.input */\n let last; /* have enough input while in < last */\n let _out; /* local strm.output */\n let beg; /* inflate()'s initial strm.output */\n let end; /* while out < end, enough space available */\n//#ifdef INFLATE_STRICT\n let dmax; /* maximum distance from zlib header */\n//#endif\n let wsize; /* window size or zero if not using window */\n let whave; /* valid bytes in the window */\n let wnext; /* window write index */\n // Use `s_window` instead `window`, avoid conflict with instrumentation tools\n let s_window; /* allocated sliding window, if wsize != 0 */\n let hold; /* local strm.hold */\n let bits; /* local strm.bits */\n let lcode; /* local strm.lencode */\n let dcode; /* local strm.distcode */\n let lmask; /* mask for first level of length codes */\n let dmask; /* mask for first level of distance codes */\n let here; /* retrieved table entry */\n let op; /* code bits, operation, extra bits, or */\n /* window position, window bytes to copy */\n let len; /* match length, unused bytes */\n let dist; /* match distance */\n let from; /* where to copy match from */\n let from_source;\n\n\n let input, output; // JS specific, because we have no pointers\n\n /* copy state to local variables */\n const state = strm.state;\n //here = state.here;\n _in = strm.next_in;\n input = strm.input;\n last = _in + (strm.avail_in - 5);\n _out = strm.next_out;\n output = strm.output;\n beg = _out - (start - strm.avail_out);\n end = _out + (strm.avail_out - 257);\n//#ifdef INFLATE_STRICT\n dmax = state.dmax;\n//#endif\n wsize = state.wsize;\n whave = state.whave;\n wnext = state.wnext;\n s_window = state.window;\n hold = state.hold;\n bits = state.bits;\n lcode = state.lencode;\n dcode = state.distcode;\n lmask = (1 << state.lenbits) - 1;\n dmask = (1 << state.distbits) - 1;\n\n\n /* decode literals and length/distances until end-of-block or not enough\n input data or output space */\n\n top:\n do {\n if (bits < 15) {\n hold += input[_in++] << bits;\n bits += 8;\n hold += input[_in++] << bits;\n bits += 8;\n }\n\n here = lcode[hold & lmask];\n\n dolen:\n for (;;) { // Goto emulation\n op = here >>> 24/*here.bits*/;\n hold >>>= op;\n bits -= op;\n op = (here >>> 16) & 0xff/*here.op*/;\n if (op === 0) { /* literal */\n //Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?\n // \"inflate: literal '%c'\\n\" :\n // \"inflate: literal 0x%02x\\n\", here.val));\n output[_out++] = here & 0xffff/*here.val*/;\n }\n else if (op & 16) { /* length base */\n len = here & 0xffff/*here.val*/;\n op &= 15; /* number of extra bits */\n if (op) {\n if (bits < op) {\n hold += input[_in++] << bits;\n bits += 8;\n }\n len += hold & ((1 << op) - 1);\n hold >>>= op;\n bits -= op;\n }\n //Tracevv((stderr, \"inflate: length %u\\n\", len));\n if (bits < 15) {\n hold += input[_in++] << bits;\n bits += 8;\n hold += input[_in++] << bits;\n bits += 8;\n }\n here = dcode[hold & dmask];\n\n dodist:\n for (;;) { // goto emulation\n op = here >>> 24/*here.bits*/;\n hold >>>= op;\n bits -= op;\n op = (here >>> 16) & 0xff/*here.op*/;\n\n if (op & 16) { /* distance base */\n dist = here & 0xffff/*here.val*/;\n op &= 15; /* number of extra bits */\n if (bits < op) {\n hold += input[_in++] << bits;\n bits += 8;\n if (bits < op) {\n hold += input[_in++] << bits;\n bits += 8;\n }\n }\n dist += hold & ((1 << op) - 1);\n//#ifdef INFLATE_STRICT\n if (dist > dmax) {\n strm.msg = 'invalid distance too far back';\n state.mode = BAD$1$1;\n break top;\n }\n//#endif\n hold >>>= op;\n bits -= op;\n //Tracevv((stderr, \"inflate: distance %u\\n\", dist));\n op = _out - beg; /* max distance in output */\n if (dist > op) { /* see if copy from window */\n op = dist - op; /* distance back in window */\n if (op > whave) {\n if (state.sane) {\n strm.msg = 'invalid distance too far back';\n state.mode = BAD$1$1;\n break top;\n }\n\n// (!) This block is disabled in zlib defaults,\n// don't enable it for binary compatibility\n//#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR\n// if (len <= op - whave) {\n// do {\n// output[_out++] = 0;\n// } while (--len);\n// continue top;\n// }\n// len -= op - whave;\n// do {\n// output[_out++] = 0;\n// } while (--op > whave);\n// if (op === 0) {\n// from = _out - dist;\n// do {\n// output[_out++] = output[from++];\n// } while (--len);\n// continue top;\n// }\n//#endif\n }\n from = 0; // window index\n from_source = s_window;\n if (wnext === 0) { /* very common case */\n from += wsize - op;\n if (op < len) { /* some from window */\n len -= op;\n do {\n output[_out++] = s_window[from++];\n } while (--op);\n from = _out - dist; /* rest from output */\n from_source = output;\n }\n }\n else if (wnext < op) { /* wrap around window */\n from += wsize + wnext - op;\n op -= wnext;\n if (op < len) { /* some from end of window */\n len -= op;\n do {\n output[_out++] = s_window[from++];\n } while (--op);\n from = 0;\n if (wnext < len) { /* some from start of window */\n op = wnext;\n len -= op;\n do {\n output[_out++] = s_window[from++];\n } while (--op);\n from = _out - dist; /* rest from output */\n from_source = output;\n }\n }\n }\n else { /* contiguous in window */\n from += wnext - op;\n if (op < len) { /* some from window */\n len -= op;\n do {\n output[_out++] = s_window[from++];\n } while (--op);\n from = _out - dist; /* rest from output */\n from_source = output;\n }\n }\n while (len > 2) {\n output[_out++] = from_source[from++];\n output[_out++] = from_source[from++];\n output[_out++] = from_source[from++];\n len -= 3;\n }\n if (len) {\n output[_out++] = from_source[from++];\n if (len > 1) {\n output[_out++] = from_source[from++];\n }\n }\n }\n else {\n from = _out - dist; /* copy direct from output */\n do { /* minimum length is three */\n output[_out++] = output[from++];\n output[_out++] = output[from++];\n output[_out++] = output[from++];\n len -= 3;\n } while (len > 2);\n if (len) {\n output[_out++] = output[from++];\n if (len > 1) {\n output[_out++] = output[from++];\n }\n }\n }\n }\n else if ((op & 64) === 0) { /* 2nd level distance code */\n here = dcode[(here & 0xffff)/*here.val*/ + (hold & ((1 << op) - 1))];\n continue dodist;\n }\n else {\n strm.msg = 'invalid distance code';\n state.mode = BAD$1$1;\n break top;\n }\n\n break; // need to emulate goto via \"continue\"\n }\n }\n else if ((op & 64) === 0) { /* 2nd level length code */\n here = lcode[(here & 0xffff)/*here.val*/ + (hold & ((1 << op) - 1))];\n continue dolen;\n }\n else if (op & 32) { /* end-of-block */\n //Tracevv((stderr, \"inflate: end of block\\n\"));\n state.mode = TYPE$1$1;\n break top;\n }\n else {\n strm.msg = 'invalid literal/length code';\n state.mode = BAD$1$1;\n break top;\n }\n\n break; // need to emulate goto via \"continue\"\n }\n } while (_in < last && _out < end);\n\n /* return unused bytes (on entry, bits < 8, so in won't go too far back) */\n len = bits >> 3;\n _in -= len;\n bits -= len << 3;\n hold &= (1 << bits) - 1;\n\n /* update state and return */\n strm.next_in = _in;\n strm.next_out = _out;\n strm.avail_in = (_in < last ? 5 + (last - _in) : 5 - (_in - last));\n strm.avail_out = (_out < end ? 257 + (end - _out) : 257 - (_out - end));\n state.hold = hold;\n state.bits = bits;\n return;\n};\n\n// (C) 1995-2013 Jean-loup Gailly and Mark Adler\n// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin\n//\n// This software is provided 'as-is', without any express or implied\n// warranty. In no event will the authors be held liable for any damages\n// arising from the use of this software.\n//\n// Permission is granted to anyone to use this software for any purpose,\n// including commercial applications, and to alter it and redistribute it\n// freely, subject to the following restrictions:\n//\n// 1. The origin of this software must not be misrepresented; you must not\n// claim that you wrote the original software. If you use this software\n// in a product, an acknowledgment in the product documentation would be\n// appreciated but is not required.\n// 2. Altered source versions must be plainly marked as such, and must not be\n// misrepresented as being the original software.\n// 3. This notice may not be removed or altered from any source distribution.\n\nconst MAXBITS$1 = 15;\nconst ENOUGH_LENS$1$1 = 852;\nconst ENOUGH_DISTS$1$1 = 592;\n//const ENOUGH = (ENOUGH_LENS+ENOUGH_DISTS);\n\nconst CODES$1$1 = 0;\nconst LENS$1$1 = 1;\nconst DISTS$1$1 = 2;\n\nconst lbase$1 = new Uint16Array([ /* Length codes 257..285 base */\n 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,\n 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0\n]);\n\nconst lext$1 = new Uint8Array([ /* Length codes 257..285 extra */\n 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18,\n 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 72, 78\n]);\n\nconst dbase$1 = new Uint16Array([ /* Distance codes 0..29 base */\n 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,\n 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,\n 8193, 12289, 16385, 24577, 0, 0\n]);\n\nconst dext$1 = new Uint8Array([ /* Distance codes 0..29 extra */\n 16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22,\n 23, 23, 24, 24, 25, 25, 26, 26, 27, 27,\n 28, 28, 29, 29, 64, 64\n]);\n\nconst inflate_table$1 = (type, lens, lens_index, codes, table, table_index, work, opts) =>\n{\n const bits = opts.bits;\n //here = opts.here; /* table entry for duplication */\n\n let len = 0; /* a code's length in bits */\n let sym = 0; /* index of code symbols */\n let min = 0, max = 0; /* minimum and maximum code lengths */\n let root = 0; /* number of index bits for root table */\n let curr = 0; /* number of index bits for current table */\n let drop = 0; /* code bits to drop for sub-table */\n let left = 0; /* number of prefix codes available */\n let used = 0; /* code entries in table used */\n let huff = 0; /* Huffman code */\n let incr; /* for incrementing code, index */\n let fill; /* index for replicating entries */\n let low; /* low bits for current root entry */\n let mask; /* mask for low root bits */\n let next; /* next available space in table */\n let base = null; /* base value table to use */\n// let shoextra; /* extra bits table to use */\n let match; /* use base and extra for symbol >= match */\n const count = new Uint16Array(MAXBITS$1 + 1); //[MAXBITS+1]; /* number of codes of each length */\n const offs = new Uint16Array(MAXBITS$1 + 1); //[MAXBITS+1]; /* offsets in table for each length */\n let extra = null;\n\n let here_bits, here_op, here_val;\n\n /*\n Process a set of code lengths to create a canonical Huffman code. The\n code lengths are lens[0..codes-1]. Each length corresponds to the\n symbols 0..codes-1. The Huffman code is generated by first sorting the\n symbols by length from short to long, and retaining the symbol order\n for codes with equal lengths. Then the code starts with all zero bits\n for the first code of the shortest length, and the codes are integer\n increments for the same length, and zeros are appended as the length\n increases. For the deflate format, these bits are stored backwards\n from their more natural integer increment ordering, and so when the\n decoding tables are built in the large loop below, the integer codes\n are incremented backwards.\n\n This routine assumes, but does not check, that all of the entries in\n lens[] are in the range 0..MAXBITS. The caller must assure this.\n 1..MAXBITS is interpreted as that code length. zero means that that\n symbol does not occur in this code.\n\n The codes are sorted by computing a count of codes for each length,\n creating from that a table of starting indices for each length in the\n sorted table, and then entering the symbols in order in the sorted\n table. The sorted table is work[], with that space being provided by\n the caller.\n\n The length counts are used for other purposes as well, i.e. finding\n the minimum and maximum length codes, determining if there are any\n codes at all, checking for a valid set of lengths, and looking ahead\n at length counts to determine sub-table sizes when building the\n decoding tables.\n */\n\n /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */\n for (len = 0; len <= MAXBITS$1; len++) {\n count[len] = 0;\n }\n for (sym = 0; sym < codes; sym++) {\n count[lens[lens_index + sym]]++;\n }\n\n /* bound code lengths, force root to be within code lengths */\n root = bits;\n for (max = MAXBITS$1; max >= 1; max--) {\n if (count[max] !== 0) { break; }\n }\n if (root > max) {\n root = max;\n }\n if (max === 0) { /* no symbols to code at all */\n //table.op[opts.table_index] = 64; //here.op = (var char)64; /* invalid code marker */\n //table.bits[opts.table_index] = 1; //here.bits = (var char)1;\n //table.val[opts.table_index++] = 0; //here.val = (var short)0;\n table[table_index++] = (1 << 24) | (64 << 16) | 0;\n\n\n //table.op[opts.table_index] = 64;\n //table.bits[opts.table_index] = 1;\n //table.val[opts.table_index++] = 0;\n table[table_index++] = (1 << 24) | (64 << 16) | 0;\n\n opts.bits = 1;\n return 0; /* no symbols, but wait for decoding to report error */\n }\n for (min = 1; min < max; min++) {\n if (count[min] !== 0) { break; }\n }\n if (root < min) {\n root = min;\n }\n\n /* check for an over-subscribed or incomplete set of lengths */\n left = 1;\n for (len = 1; len <= MAXBITS$1; len++) {\n left <<= 1;\n left -= count[len];\n if (left < 0) {\n return -1;\n } /* over-subscribed */\n }\n if (left > 0 && (type === CODES$1$1 || max !== 1)) {\n return -1; /* incomplete set */\n }\n\n /* generate offsets into symbol table for each length for sorting */\n offs[1] = 0;\n for (len = 1; len < MAXBITS$1; len++) {\n offs[len + 1] = offs[len] + count[len];\n }\n\n /* sort symbols by length, by symbol order within each length */\n for (sym = 0; sym < codes; sym++) {\n if (lens[lens_index + sym] !== 0) {\n work[offs[lens[lens_index + sym]]++] = sym;\n }\n }\n\n /*\n Create and fill in decoding tables. In this loop, the table being\n filled is at next and has curr index bits. The code being used is huff\n with length len. That code is converted to an index by dropping drop\n bits off of the bottom. For codes where len is less than drop + curr,\n those top drop + curr - len bits are incremented through all values to\n fill the table with replicated entries.\n\n root is the number of index bits for the root table. When len exceeds\n root, sub-tables are created pointed to by the root entry with an index\n of the low root bits of huff. This is saved in low to check for when a\n new sub-table should be started. drop is zero when the root table is\n being filled, and drop is root when sub-tables are being filled.\n\n When a new sub-table is needed, it is necessary to look ahead in the\n code lengths to determine what size sub-table is needed. The length\n counts are used for this, and so count[] is decremented as codes are\n entered in the tables.\n\n used keeps track of how many table entries have been allocated from the\n provided *table space. It is checked for LENS and DIST tables against\n the constants ENOUGH_LENS and ENOUGH_DISTS to guard against changes in\n the initial root table size constants. See the comments in inftrees.h\n for more information.\n\n sym increments through all symbols, and the loop terminates when\n all codes of length max, i.e. all codes, have been processed. This\n routine permits incomplete codes, so another loop after this one fills\n in the rest of the decoding tables with invalid code markers.\n */\n\n /* set up for code type */\n // poor man optimization - use if-else instead of switch,\n // to avoid deopts in old v8\n if (type === CODES$1$1) {\n base = extra = work; /* dummy value--not used */\n match = 20;\n\n } else if (type === LENS$1$1) {\n base = lbase$1;\n extra = lext$1;\n match = 257;\n\n } else { /* DISTS */\n base = dbase$1;\n extra = dext$1;\n match = 0;\n }\n\n /* initialize opts for loop */\n huff = 0; /* starting code */\n sym = 0; /* starting code symbol */\n len = min; /* starting code length */\n next = table_index; /* current table to fill in */\n curr = root; /* current table index bits */\n drop = 0; /* current bits to drop from code for index */\n low = -1; /* trigger new sub-table when len > root */\n used = 1 << root; /* use root table entries */\n mask = used - 1; /* mask for comparing low */\n\n /* check available table space */\n if ((type === LENS$1$1 && used > ENOUGH_LENS$1$1) ||\n (type === DISTS$1$1 && used > ENOUGH_DISTS$1$1)) {\n return 1;\n }\n\n /* process all codes and make table entries */\n for (;;) {\n /* create table entry */\n here_bits = len - drop;\n if (work[sym] + 1 < match) {\n here_op = 0;\n here_val = work[sym];\n }\n else if (work[sym] >= match) {\n here_op = extra[work[sym] - match];\n here_val = base[work[sym] - match];\n }\n else {\n here_op = 32 + 64; /* end of block */\n here_val = 0;\n }\n\n /* replicate for those indices with low len bits equal to huff */\n incr = 1 << (len - drop);\n fill = 1 << curr;\n min = fill; /* save offset to next table */\n do {\n fill -= incr;\n table[next + (huff >> drop) + fill] = (here_bits << 24) | (here_op << 16) | here_val |0;\n } while (fill !== 0);\n\n /* backwards increment the len-bit code huff */\n incr = 1 << (len - 1);\n while (huff & incr) {\n incr >>= 1;\n }\n if (incr !== 0) {\n huff &= incr - 1;\n huff += incr;\n } else {\n huff = 0;\n }\n\n /* go to next symbol, update count, len */\n sym++;\n if (--count[len] === 0) {\n if (len === max) { break; }\n len = lens[lens_index + work[sym]];\n }\n\n /* create new sub-table if needed */\n if (len > root && (huff & mask) !== low) {\n /* if first time, transition to sub-tables */\n if (drop === 0) {\n drop = root;\n }\n\n /* increment past last table */\n next += min; /* here min is 1 << curr */\n\n /* determine length of next table */\n curr = len - drop;\n left = 1 << curr;\n while (curr + drop < max) {\n left -= count[curr + drop];\n if (left <= 0) { break; }\n curr++;\n left <<= 1;\n }\n\n /* check for enough space */\n used += 1 << curr;\n if ((type === LENS$1$1 && used > ENOUGH_LENS$1$1) ||\n (type === DISTS$1$1 && used > ENOUGH_DISTS$1$1)) {\n return 1;\n }\n\n /* point entry in root table to sub-table */\n low = huff & mask;\n /*table.op[low] = curr;\n table.bits[low] = root;\n table.val[low] = next - opts.table_index;*/\n table[low] = (root << 24) | (curr << 16) | (next - table_index) |0;\n }\n }\n\n /* fill in remaining table entry if code is incomplete (guaranteed to have\n at most one remaining entry, since if the code is incomplete, the\n maximum code length that was allowed to get this far is one bit) */\n if (huff !== 0) {\n //table.op[next + huff] = 64; /* invalid code marker */\n //table.bits[next + huff] = len - drop;\n //table.val[next + huff] = 0;\n table[next + huff] = ((len - drop) << 24) | (64 << 16) |0;\n }\n\n /* set return parameters */\n //opts.table_index += used;\n opts.bits = root;\n return 0;\n};\n\n\nvar inftrees$1 = inflate_table$1;\n\n// (C) 1995-2013 Jean-loup Gailly and Mark Adler\n// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin\n//\n// This software is provided 'as-is', without any express or implied\n// warranty. In no event will the authors be held liable for any damages\n// arising from the use of this software.\n//\n// Permission is granted to anyone to use this software for any purpose,\n// including commercial applications, and to alter it and redistribute it\n// freely, subject to the following restrictions:\n//\n// 1. The origin of this software must not be misrepresented; you must not\n// claim that you wrote the original software. If you use this software\n// in a product, an acknowledgment in the product documentation would be\n// appreciated but is not required.\n// 2. Altered source versions must be plainly marked as such, and must not be\n// misrepresented as being the original software.\n// 3. This notice may not be removed or altered from any source distribution.\n\n\n\n\n\n\nconst CODES$2 = 0;\nconst LENS$2 = 1;\nconst DISTS$2 = 2;\n\n/* Public constants ==========================================================*/\n/* ===========================================================================*/\n\nconst {\n Z_FINISH: Z_FINISH$1$1, Z_BLOCK: Z_BLOCK$2, Z_TREES: Z_TREES$1,\n Z_OK: Z_OK$1$1, Z_STREAM_END: Z_STREAM_END$1$1, Z_NEED_DICT: Z_NEED_DICT$1$1, Z_STREAM_ERROR: Z_STREAM_ERROR$1$1, Z_DATA_ERROR: Z_DATA_ERROR$1$1, Z_MEM_ERROR: Z_MEM_ERROR$1$1, Z_BUF_ERROR: Z_BUF_ERROR$2,\n Z_DEFLATED: Z_DEFLATED$3\n} = constants$2$1;\n\n\n/* STATES ====================================================================*/\n/* ===========================================================================*/\n\n\nconst HEAD$1 = 16180; /* i: waiting for magic header */\nconst FLAGS$1 = 16181; /* i: waiting for method and flags (gzip) */\nconst TIME$1 = 16182; /* i: waiting for modification time (gzip) */\nconst OS$1 = 16183; /* i: waiting for extra flags and operating system (gzip) */\nconst EXLEN$1 = 16184; /* i: waiting for extra length (gzip) */\nconst EXTRA$1 = 16185; /* i: waiting for extra bytes (gzip) */\nconst NAME$1 = 16186; /* i: waiting for end of file name (gzip) */\nconst COMMENT$1 = 16187; /* i: waiting for end of comment (gzip) */\nconst HCRC$1 = 16188; /* i: waiting for header crc (gzip) */\nconst DICTID$1 = 16189; /* i: waiting for dictionary check value */\nconst DICT$1 = 16190; /* waiting for inflateSetDictionary() call */\nconst TYPE$2 = 16191; /* i: waiting for type bits, including last-flag bit */\nconst TYPEDO$1 = 16192; /* i: same, but skip check to exit inflate on new block */\nconst STORED$1 = 16193; /* i: waiting for stored size (length and complement) */\nconst COPY_$1 = 16194; /* i/o: same as COPY below, but only first time in */\nconst COPY$1 = 16195; /* i/o: waiting for input or output to copy stored block */\nconst TABLE$1 = 16196; /* i: waiting for dynamic block table lengths */\nconst LENLENS$1 = 16197; /* i: waiting for code length code lengths */\nconst CODELENS$1 = 16198; /* i: waiting for length/lit and distance code lengths */\nconst LEN_$1 = 16199; /* i: same as LEN below, but only first time in */\nconst LEN$1 = 16200; /* i: waiting for length/lit/eob code */\nconst LENEXT$1 = 16201; /* i: waiting for length extra bits */\nconst DIST$1 = 16202; /* i: waiting for distance code */\nconst DISTEXT$1 = 16203; /* i: waiting for distance extra bits */\nconst MATCH$1 = 16204; /* o: waiting for output space to copy string */\nconst LIT$1 = 16205; /* o: waiting for output space to write literal */\nconst CHECK$1 = 16206; /* i: waiting for 32-bit check value */\nconst LENGTH$1 = 16207; /* i: waiting for 32-bit length (gzip) */\nconst DONE$1 = 16208; /* finished check, done -- remain here until reset */\nconst BAD$2 = 16209; /* got a data error -- remain here until reset */\nconst MEM$1 = 16210; /* got an inflate() memory error -- remain here until reset */\nconst SYNC$1 = 16211; /* looking for synchronization bytes to restart inflate() */\n\n/* ===========================================================================*/\n\n\n\nconst ENOUGH_LENS$2 = 852;\nconst ENOUGH_DISTS$2 = 592;\n//const ENOUGH = (ENOUGH_LENS+ENOUGH_DISTS);\n\nconst MAX_WBITS$2 = 15;\n/* 32K LZ77 window */\nconst DEF_WBITS$1 = MAX_WBITS$2;\n\n\nconst zswap32$1 = (q) => {\n\n return (((q >>> 24) & 0xff) +\n ((q >>> 8) & 0xff00) +\n ((q & 0xff00) << 8) +\n ((q & 0xff) << 24));\n};\n\n\nfunction InflateState$1() {\n this.strm = null; /* pointer back to this zlib stream */\n this.mode = 0; /* current inflate mode */\n this.last = false; /* true if processing last block */\n this.wrap = 0; /* bit 0 true for zlib, bit 1 true for gzip,\n bit 2 true to validate check value */\n this.havedict = false; /* true if dictionary provided */\n this.flags = 0; /* gzip header method and flags (0 if zlib), or\n -1 if raw or no header yet */\n this.dmax = 0; /* zlib header max distance (INFLATE_STRICT) */\n this.check = 0; /* protected copy of check value */\n this.total = 0; /* protected copy of output count */\n // TODO: may be {}\n this.head = null; /* where to save gzip header information */\n\n /* sliding window */\n this.wbits = 0; /* log base 2 of requested window size */\n this.wsize = 0; /* window size or zero if not using window */\n this.whave = 0; /* valid bytes in the window */\n this.wnext = 0; /* window write index */\n this.window = null; /* allocated sliding window, if needed */\n\n /* bit accumulator */\n this.hold = 0; /* input bit accumulator */\n this.bits = 0; /* number of bits in \"in\" */\n\n /* for string and stored block copying */\n this.length = 0; /* literal or length of data to copy */\n this.offset = 0; /* distance back to copy string from */\n\n /* for table and code decoding */\n this.extra = 0; /* extra bits needed */\n\n /* fixed and dynamic code tables */\n this.lencode = null; /* starting table for length/literal codes */\n this.distcode = null; /* starting table for distance codes */\n this.lenbits = 0; /* index bits for lencode */\n this.distbits = 0; /* index bits for distcode */\n\n /* dynamic table building */\n this.ncode = 0; /* number of code length code lengths */\n this.nlen = 0; /* number of length code lengths */\n this.ndist = 0; /* number of distance code lengths */\n this.have = 0; /* number of code lengths in lens[] */\n this.next = null; /* next available space in codes[] */\n\n this.lens = new Uint16Array(320); /* temporary storage for code lengths */\n this.work = new Uint16Array(288); /* work area for code table building */\n\n /*\n because we don't have pointers in js, we use lencode and distcode directly\n as buffers so we don't need codes\n */\n //this.codes = new Int32Array(ENOUGH); /* space for code tables */\n this.lendyn = null; /* dynamic table for length/literal codes (JS specific) */\n this.distdyn = null; /* dynamic table for distance codes (JS specific) */\n this.sane = 0; /* if false, allow invalid distance too far */\n this.back = 0; /* bits back of last unprocessed length/lit */\n this.was = 0; /* initial length of match */\n}\n\n\nconst inflateStateCheck = (strm) => {\n\n if (!strm) {\n return 1;\n }\n const state = strm.state;\n if (!state || state.strm !== strm ||\n state.mode < HEAD$1 || state.mode > SYNC$1) {\n return 1;\n }\n return 0;\n};\n\n\nconst inflateResetKeep$1 = (strm) => {\n\n if (inflateStateCheck(strm)) { return Z_STREAM_ERROR$1$1; }\n const state = strm.state;\n strm.total_in = strm.total_out = state.total = 0;\n strm.msg = ''; /*Z_NULL*/\n if (state.wrap) { /* to support ill-conceived Java test suite */\n strm.adler = state.wrap & 1;\n }\n state.mode = HEAD$1;\n state.last = 0;\n state.havedict = 0;\n state.flags = -1;\n state.dmax = 32768;\n state.head = null/*Z_NULL*/;\n state.hold = 0;\n state.bits = 0;\n //state.lencode = state.distcode = state.next = state.codes;\n state.lencode = state.lendyn = new Int32Array(ENOUGH_LENS$2);\n state.distcode = state.distdyn = new Int32Array(ENOUGH_DISTS$2);\n\n state.sane = 1;\n state.back = -1;\n //Tracev((stderr, \"inflate: reset\\n\"));\n return Z_OK$1$1;\n};\n\n\nconst inflateReset$1 = (strm) => {\n\n if (inflateStateCheck(strm)) { return Z_STREAM_ERROR$1$1; }\n const state = strm.state;\n state.wsize = 0;\n state.whave = 0;\n state.wnext = 0;\n return inflateResetKeep$1(strm);\n\n};\n\n\nconst inflateReset2$1 = (strm, windowBits) => {\n let wrap;\n\n /* get the state */\n if (inflateStateCheck(strm)) { return Z_STREAM_ERROR$1$1; }\n const state = strm.state;\n\n /* extract wrap request from windowBits parameter */\n if (windowBits < 0) {\n wrap = 0;\n windowBits = -windowBits;\n }\n else {\n wrap = (windowBits >> 4) + 5;\n if (windowBits < 48) {\n windowBits &= 15;\n }\n }\n\n /* set number of window bits, free window if different */\n if (windowBits && (windowBits < 8 || windowBits > 15)) {\n return Z_STREAM_ERROR$1$1;\n }\n if (state.window !== null && state.wbits !== windowBits) {\n state.window = null;\n }\n\n /* update state and reset the rest of it */\n state.wrap = wrap;\n state.wbits = windowBits;\n return inflateReset$1(strm);\n};\n\n\nconst inflateInit2$1 = (strm, windowBits) => {\n\n if (!strm) { return Z_STREAM_ERROR$1$1; }\n //strm.msg = Z_NULL; /* in case we return an error */\n\n const state = new InflateState$1();\n\n //if (state === Z_NULL) return Z_MEM_ERROR;\n //Tracev((stderr, \"inflate: allocated\\n\"));\n strm.state = state;\n state.strm = strm;\n state.window = null/*Z_NULL*/;\n state.mode = HEAD$1; /* to pass state test in inflateReset2() */\n const ret = inflateReset2$1(strm, windowBits);\n if (ret !== Z_OK$1$1) {\n strm.state = null/*Z_NULL*/;\n }\n return ret;\n};\n\n\nconst inflateInit$1 = (strm) => {\n\n return inflateInit2$1(strm, DEF_WBITS$1);\n};\n\n\n/*\n Return state with length and distance decoding tables and index sizes set to\n fixed code decoding. Normally this returns fixed tables from inffixed.h.\n If BUILDFIXED is defined, then instead this routine builds the tables the\n first time it's called, and returns those tables the first time and\n thereafter. This reduces the size of the code by about 2K bytes, in\n exchange for a little execution time. However, BUILDFIXED should not be\n used for threaded applications, since the rewriting of the tables and virgin\n may not be thread-safe.\n */\nlet virgin$1 = true;\n\nlet lenfix$1, distfix$1; // We have no pointers in JS, so keep tables separate\n\n\nconst fixedtables$1 = (state) => {\n\n /* build fixed huffman tables if first call (may not be thread safe) */\n if (virgin$1) {\n lenfix$1 = new Int32Array(512);\n distfix$1 = new Int32Array(32);\n\n /* literal/length table */\n let sym = 0;\n while (sym < 144) { state.lens[sym++] = 8; }\n while (sym < 256) { state.lens[sym++] = 9; }\n while (sym < 280) { state.lens[sym++] = 7; }\n while (sym < 288) { state.lens[sym++] = 8; }\n\n inftrees$1(LENS$2, state.lens, 0, 288, lenfix$1, 0, state.work, { bits: 9 });\n\n /* distance table */\n sym = 0;\n while (sym < 32) { state.lens[sym++] = 5; }\n\n inftrees$1(DISTS$2, state.lens, 0, 32, distfix$1, 0, state.work, { bits: 5 });\n\n /* do this just once */\n virgin$1 = false;\n }\n\n state.lencode = lenfix$1;\n state.lenbits = 9;\n state.distcode = distfix$1;\n state.distbits = 5;\n};\n\n\n/*\n Update the window with the last wsize (normally 32K) bytes written before\n returning. If window does not exist yet, create it. This is only called\n when a window is already in use, or when output has been written during this\n inflate call, but the end of the deflate stream has not been reached yet.\n It is also called to create a window for dictionary data when a dictionary\n is loaded.\n\n Providing output buffers larger than 32K to inflate() should provide a speed\n advantage, since only the last 32K of output is copied to the sliding window\n upon return from inflate(), and since all distances after the first 32K of\n output will fall in the output data, making match copies simpler and faster.\n The advantage may be dependent on the size of the processor's data caches.\n */\nconst updatewindow$1 = (strm, src, end, copy) => {\n\n let dist;\n const state = strm.state;\n\n /* if it hasn't been done already, allocate space for the window */\n if (state.window === null) {\n state.wsize = 1 << state.wbits;\n state.wnext = 0;\n state.whave = 0;\n\n state.window = new Uint8Array(state.wsize);\n }\n\n /* copy state->wsize or less output bytes into the circular window */\n if (copy >= state.wsize) {\n state.window.set(src.subarray(end - state.wsize, end), 0);\n state.wnext = 0;\n state.whave = state.wsize;\n }\n else {\n dist = state.wsize - state.wnext;\n if (dist > copy) {\n dist = copy;\n }\n //zmemcpy(state->window + state->wnext, end - copy, dist);\n state.window.set(src.subarray(end - copy, end - copy + dist), state.wnext);\n copy -= dist;\n if (copy) {\n //zmemcpy(state->window, end - copy, copy);\n state.window.set(src.subarray(end - copy, end), 0);\n state.wnext = copy;\n state.whave = state.wsize;\n }\n else {\n state.wnext += dist;\n if (state.wnext === state.wsize) { state.wnext = 0; }\n if (state.whave < state.wsize) { state.whave += dist; }\n }\n }\n return 0;\n};\n\n\nconst inflate$2$1 = (strm, flush) => {\n\n let state;\n let input, output; // input/output buffers\n let next; /* next input INDEX */\n let put; /* next output INDEX */\n let have, left; /* available input and output */\n let hold; /* bit buffer */\n let bits; /* bits in bit buffer */\n let _in, _out; /* save starting available input and output */\n let copy; /* number of stored or match bytes to copy */\n let from; /* where to copy match bytes from */\n let from_source;\n let here = 0; /* current decoding table entry */\n let here_bits, here_op, here_val; // paked \"here\" denormalized (JS specific)\n //let last; /* parent table entry */\n let last_bits, last_op, last_val; // paked \"last\" denormalized (JS specific)\n let len; /* length to copy for repeats, bits to drop */\n let ret; /* return code */\n const hbuf = new Uint8Array(4); /* buffer for gzip header crc calculation */\n let opts;\n\n let n; // temporary variable for NEED_BITS\n\n const order = /* permutation of code lengths */\n new Uint8Array([ 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 ]);\n\n\n if (inflateStateCheck(strm) || !strm.output ||\n (!strm.input && strm.avail_in !== 0)) {\n return Z_STREAM_ERROR$1$1;\n }\n\n state = strm.state;\n if (state.mode === TYPE$2) { state.mode = TYPEDO$1; } /* skip check */\n\n\n //--- LOAD() ---\n put = strm.next_out;\n output = strm.output;\n left = strm.avail_out;\n next = strm.next_in;\n input = strm.input;\n have = strm.avail_in;\n hold = state.hold;\n bits = state.bits;\n //---\n\n _in = have;\n _out = left;\n ret = Z_OK$1$1;\n\n inf_leave: // goto emulation\n for (;;) {\n switch (state.mode) {\n case HEAD$1:\n if (state.wrap === 0) {\n state.mode = TYPEDO$1;\n break;\n }\n //=== NEEDBITS(16);\n while (bits < 16) {\n if (have === 0) { break inf_leave; }\n have--;\n hold += input[next++] << bits;\n bits += 8;\n }\n //===//\n if ((state.wrap & 2) && hold === 0x8b1f) { /* gzip header */\n if (state.wbits === 0) {\n state.wbits = 15;\n }\n state.check = 0/*crc32(0L, Z_NULL, 0)*/;\n //=== CRC2(state.check, hold);\n hbuf[0] = hold & 0xff;\n hbuf[1] = (hold >>> 8) & 0xff;\n state.check = crc32_1$1(state.check, hbuf, 2, 0);\n //===//\n\n //=== INITBITS();\n hold = 0;\n bits = 0;\n //===//\n state.mode = FLAGS$1;\n break;\n }\n if (state.head) {\n state.head.done = false;\n }\n if (!(state.wrap & 1) || /* check if zlib header allowed */\n (((hold & 0xff)/*BITS(8)*/ << 8) + (hold >> 8)) % 31) {\n strm.msg = 'incorrect header check';\n state.mode = BAD$2;\n break;\n }\n if ((hold & 0x0f)/*BITS(4)*/ !== Z_DEFLATED$3) {\n strm.msg = 'unknown compression method';\n state.mode = BAD$2;\n break;\n }\n //--- DROPBITS(4) ---//\n hold >>>= 4;\n bits -= 4;\n //---//\n len = (hold & 0x0f)/*BITS(4)*/ + 8;\n if (state.wbits === 0) {\n state.wbits = len;\n }\n if (len > 15 || len > state.wbits) {\n strm.msg = 'invalid window size';\n state.mode = BAD$2;\n break;\n }\n\n // !!! pako patch. Force use `options.windowBits` if passed.\n // Required to always use max window size by default.\n state.dmax = 1 << state.wbits;\n //state.dmax = 1 << len;\n\n state.flags = 0; /* indicate zlib header */\n //Tracev((stderr, \"inflate: zlib header ok\\n\"));\n strm.adler = state.check = 1/*adler32(0L, Z_NULL, 0)*/;\n state.mode = hold & 0x200 ? DICTID$1 : TYPE$2;\n //=== INITBITS();\n hold = 0;\n bits = 0;\n //===//\n break;\n case FLAGS$1:\n //=== NEEDBITS(16); */\n while (bits < 16) {\n if (have === 0) { break inf_leave; }\n have--;\n hold += input[next++] << bits;\n bits += 8;\n }\n //===//\n state.flags = hold;\n if ((state.flags & 0xff) !== Z_DEFLATED$3) {\n strm.msg = 'unknown compression method';\n state.mode = BAD$2;\n break;\n }\n if (state.flags & 0xe000) {\n strm.msg = 'unknown header flags set';\n state.mode = BAD$2;\n break;\n }\n if (state.head) {\n state.head.text = ((hold >> 8) & 1);\n }\n if ((state.flags & 0x0200) && (state.wrap & 4)) {\n //=== CRC2(state.check, hold);\n hbuf[0] = hold & 0xff;\n hbuf[1] = (hold >>> 8) & 0xff;\n state.check = crc32_1$1(state.check, hbuf, 2, 0);\n //===//\n }\n //=== INITBITS();\n hold = 0;\n bits = 0;\n //===//\n state.mode = TIME$1;\n /* falls through */\n case TIME$1:\n //=== NEEDBITS(32); */\n while (bits < 32) {\n if (have === 0) { break inf_leave; }\n have--;\n hold += input[next++] << bits;\n bits += 8;\n }\n //===//\n if (state.head) {\n state.head.time = hold;\n }\n if ((state.flags & 0x0200) && (state.wrap & 4)) {\n //=== CRC4(state.check, hold)\n hbuf[0] = hold & 0xff;\n hbuf[1] = (hold >>> 8) & 0xff;\n hbuf[2] = (hold >>> 16) & 0xff;\n hbuf[3] = (hold >>> 24) & 0xff;\n state.check = crc32_1$1(state.check, hbuf, 4, 0);\n //===\n }\n //=== INITBITS();\n hold = 0;\n bits = 0;\n //===//\n state.mode = OS$1;\n /* falls through */\n case OS$1:\n //=== NEEDBITS(16); */\n while (bits < 16) {\n if (have === 0) { break inf_leave; }\n have--;\n hold += input[next++] << bits;\n bits += 8;\n }\n //===//\n if (state.head) {\n state.head.xflags = (hold & 0xff);\n state.head.os = (hold >> 8);\n }\n if ((state.flags & 0x0200) && (state.wrap & 4)) {\n //=== CRC2(state.check, hold);\n hbuf[0] = hold & 0xff;\n hbuf[1] = (hold >>> 8) & 0xff;\n state.check = crc32_1$1(state.check, hbuf, 2, 0);\n //===//\n }\n //=== INITBITS();\n hold = 0;\n bits = 0;\n //===//\n state.mode = EXLEN$1;\n /* falls through */\n case EXLEN$1:\n if (state.flags & 0x0400) {\n //=== NEEDBITS(16); */\n while (bits < 16) {\n if (have === 0) { break inf_leave; }\n have--;\n hold += input[next++] << bits;\n bits += 8;\n }\n //===//\n state.length = hold;\n if (state.head) {\n state.head.extra_len = hold;\n }\n if ((state.flags & 0x0200) && (state.wrap & 4)) {\n //=== CRC2(state.check, hold);\n hbuf[0] = hold & 0xff;\n hbuf[1] = (hold >>> 8) & 0xff;\n state.check = crc32_1$1(state.check, hbuf, 2, 0);\n //===//\n }\n //=== INITBITS();\n hold = 0;\n bits = 0;\n //===//\n }\n else if (state.head) {\n state.head.extra = null/*Z_NULL*/;\n }\n state.mode = EXTRA$1;\n /* falls through */\n case EXTRA$1:\n if (state.flags & 0x0400) {\n copy = state.length;\n if (copy > have) { copy = have; }\n if (copy) {\n if (state.head) {\n len = state.head.extra_len - state.length;\n if (!state.head.extra) {\n // Use untyped array for more convenient processing later\n state.head.extra = new Uint8Array(state.head.extra_len);\n }\n state.head.extra.set(\n input.subarray(\n next,\n // extra field is limited to 65536 bytes\n // - no need for additional size check\n next + copy\n ),\n /*len + copy > state.head.extra_max - len ? state.head.extra_max : copy,*/\n len\n );\n //zmemcpy(state.head.extra + len, next,\n // len + copy > state.head.extra_max ?\n // state.head.extra_max - len : copy);\n }\n if ((state.flags & 0x0200) && (state.wrap & 4)) {\n state.check = crc32_1$1(state.check, input, copy, next);\n }\n have -= copy;\n next += copy;\n state.length -= copy;\n }\n if (state.length) { break inf_leave; }\n }\n state.length = 0;\n state.mode = NAME$1;\n /* falls through */\n case NAME$1:\n if (state.flags & 0x0800) {\n if (have === 0) { break inf_leave; }\n copy = 0;\n do {\n // TODO: 2 or 1 bytes?\n len = input[next + copy++];\n /* use constant limit because in js we should not preallocate memory */\n if (state.head && len &&\n (state.length < 65536 /*state.head.name_max*/)) {\n state.head.name += String.fromCharCode(len);\n }\n } while (len && copy < have);\n\n if ((state.flags & 0x0200) && (state.wrap & 4)) {\n state.check = crc32_1$1(state.check, input, copy, next);\n }\n have -= copy;\n next += copy;\n if (len) { break inf_leave; }\n }\n else if (state.head) {\n state.head.name = null;\n }\n state.length = 0;\n state.mode = COMMENT$1;\n /* falls through */\n case COMMENT$1:\n if (state.flags & 0x1000) {\n if (have === 0) { break inf_leave; }\n copy = 0;\n do {\n len = input[next + copy++];\n /* use constant limit because in js we should not preallocate memory */\n if (state.head && len &&\n (state.length < 65536 /*state.head.comm_max*/)) {\n state.head.comment += String.fromCharCode(len);\n }\n } while (len && copy < have);\n if ((state.flags & 0x0200) && (state.wrap & 4)) {\n state.check = crc32_1$1(state.check, input, copy, next);\n }\n have -= copy;\n next += copy;\n if (len) { break inf_leave; }\n }\n else if (state.head) {\n state.head.comment = null;\n }\n state.mode = HCRC$1;\n /* falls through */\n case HCRC$1:\n if (state.flags & 0x0200) {\n //=== NEEDBITS(16); */\n while (bits < 16) {\n if (have === 0) { break inf_leave; }\n have--;\n hold += input[next++] << bits;\n bits += 8;\n }\n //===//\n if ((state.wrap & 4) && hold !== (state.check & 0xffff)) {\n strm.msg = 'header crc mismatch';\n state.mode = BAD$2;\n break;\n }\n //=== INITBITS();\n hold = 0;\n bits = 0;\n //===//\n }\n if (state.head) {\n state.head.hcrc = ((state.flags >> 9) & 1);\n state.head.done = true;\n }\n strm.adler = state.check = 0;\n state.mode = TYPE$2;\n break;\n case DICTID$1:\n //=== NEEDBITS(32); */\n while (bits < 32) {\n if (have === 0) { break inf_leave; }\n have--;\n hold += input[next++] << bits;\n bits += 8;\n }\n //===//\n strm.adler = state.check = zswap32$1(hold);\n //=== INITBITS();\n hold = 0;\n bits = 0;\n //===//\n state.mode = DICT$1;\n /* falls through */\n case DICT$1:\n if (state.havedict === 0) {\n //--- RESTORE() ---\n strm.next_out = put;\n strm.avail_out = left;\n strm.next_in = next;\n strm.avail_in = have;\n state.hold = hold;\n state.bits = bits;\n //---\n return Z_NEED_DICT$1$1;\n }\n strm.adler = state.check = 1/*adler32(0L, Z_NULL, 0)*/;\n state.mode = TYPE$2;\n /* falls through */\n case TYPE$2:\n if (flush === Z_BLOCK$2 || flush === Z_TREES$1) { break inf_leave; }\n /* falls through */\n case TYPEDO$1:\n if (state.last) {\n //--- BYTEBITS() ---//\n hold >>>= bits & 7;\n bits -= bits & 7;\n //---//\n state.mode = CHECK$1;\n break;\n }\n //=== NEEDBITS(3); */\n while (bits < 3) {\n if (have === 0) { break inf_leave; }\n have--;\n hold += input[next++] << bits;\n bits += 8;\n }\n //===//\n state.last = (hold & 0x01)/*BITS(1)*/;\n //--- DROPBITS(1) ---//\n hold >>>= 1;\n bits -= 1;\n //---//\n\n switch ((hold & 0x03)/*BITS(2)*/) {\n case 0: /* stored block */\n //Tracev((stderr, \"inflate: stored block%s\\n\",\n // state.last ? \" (last)\" : \"\"));\n state.mode = STORED$1;\n break;\n case 1: /* fixed block */\n fixedtables$1(state);\n //Tracev((stderr, \"inflate: fixed codes block%s\\n\",\n // state.last ? \" (last)\" : \"\"));\n state.mode = LEN_$1; /* decode codes */\n if (flush === Z_TREES$1) {\n //--- DROPBITS(2) ---//\n hold >>>= 2;\n bits -= 2;\n //---//\n break inf_leave;\n }\n break;\n case 2: /* dynamic block */\n //Tracev((stderr, \"inflate: dynamic codes block%s\\n\",\n // state.last ? \" (last)\" : \"\"));\n state.mode = TABLE$1;\n break;\n case 3:\n strm.msg = 'invalid block type';\n state.mode = BAD$2;\n }\n //--- DROPBITS(2) ---//\n hold >>>= 2;\n bits -= 2;\n //---//\n break;\n case STORED$1:\n //--- BYTEBITS() ---// /* go to byte boundary */\n hold >>>= bits & 7;\n bits -= bits & 7;\n //---//\n //=== NEEDBITS(32); */\n while (bits < 32) {\n if (have === 0) { break inf_leave; }\n have--;\n hold += input[next++] << bits;\n bits += 8;\n }\n //===//\n if ((hold & 0xffff) !== ((hold >>> 16) ^ 0xffff)) {\n strm.msg = 'invalid stored block lengths';\n state.mode = BAD$2;\n break;\n }\n state.length = hold & 0xffff;\n //Tracev((stderr, \"inflate: stored length %u\\n\",\n // state.length));\n //=== INITBITS();\n hold = 0;\n bits = 0;\n //===//\n state.mode = COPY_$1;\n if (flush === Z_TREES$1) { break inf_leave; }\n /* falls through */\n case COPY_$1:\n state.mode = COPY$1;\n /* falls through */\n case COPY$1:\n copy = state.length;\n if (copy) {\n if (copy > have) { copy = have; }\n if (copy > left) { copy = left; }\n if (copy === 0) { break inf_leave; }\n //--- zmemcpy(put, next, copy); ---\n output.set(input.subarray(next, next + copy), put);\n //---//\n have -= copy;\n next += copy;\n left -= copy;\n put += copy;\n state.length -= copy;\n break;\n }\n //Tracev((stderr, \"inflate: stored end\\n\"));\n state.mode = TYPE$2;\n break;\n case TABLE$1:\n //=== NEEDBITS(14); */\n while (bits < 14) {\n if (have === 0) { break inf_leave; }\n have--;\n hold += input[next++] << bits;\n bits += 8;\n }\n //===//\n state.nlen = (hold & 0x1f)/*BITS(5)*/ + 257;\n //--- DROPBITS(5) ---//\n hold >>>= 5;\n bits -= 5;\n //---//\n state.ndist = (hold & 0x1f)/*BITS(5)*/ + 1;\n //--- DROPBITS(5) ---//\n hold >>>= 5;\n bits -= 5;\n //---//\n state.ncode = (hold & 0x0f)/*BITS(4)*/ + 4;\n //--- DROPBITS(4) ---//\n hold >>>= 4;\n bits -= 4;\n //---//\n//#ifndef PKZIP_BUG_WORKAROUND\n if (state.nlen > 286 || state.ndist > 30) {\n strm.msg = 'too many length or distance symbols';\n state.mode = BAD$2;\n break;\n }\n//#endif\n //Tracev((stderr, \"inflate: table sizes ok\\n\"));\n state.have = 0;\n state.mode = LENLENS$1;\n /* falls through */\n case LENLENS$1:\n while (state.have < state.ncode) {\n //=== NEEDBITS(3);\n while (bits < 3) {\n if (have === 0) { break inf_leave; }\n have--;\n hold += input[next++] << bits;\n bits += 8;\n }\n //===//\n state.lens[order[state.have++]] = (hold & 0x07);//BITS(3);\n //--- DROPBITS(3) ---//\n hold >>>= 3;\n bits -= 3;\n //---//\n }\n while (state.have < 19) {\n state.lens[order[state.have++]] = 0;\n }\n // We have separate tables & no pointers. 2 commented lines below not needed.\n //state.next = state.codes;\n //state.lencode = state.next;\n // Switch to use dynamic table\n state.lencode = state.lendyn;\n state.lenbits = 7;\n\n opts = { bits: state.lenbits };\n ret = inftrees$1(CODES$2, state.lens, 0, 19, state.lencode, 0, state.work, opts);\n state.lenbits = opts.bits;\n\n if (ret) {\n strm.msg = 'invalid code lengths set';\n state.mode = BAD$2;\n break;\n }\n //Tracev((stderr, \"inflate: code lengths ok\\n\"));\n state.have = 0;\n state.mode = CODELENS$1;\n /* falls through */\n case CODELENS$1:\n while (state.have < state.nlen + state.ndist) {\n for (;;) {\n here = state.lencode[hold & ((1 << state.lenbits) - 1)];/*BITS(state.lenbits)*/\n here_bits = here >>> 24;\n here_op = (here >>> 16) & 0xff;\n here_val = here & 0xffff;\n\n if ((here_bits) <= bits) { break; }\n //--- PULLBYTE() ---//\n if (have === 0) { break inf_leave; }\n have--;\n hold += input[next++] << bits;\n bits += 8;\n //---//\n }\n if (here_val < 16) {\n //--- DROPBITS(here.bits) ---//\n hold >>>= here_bits;\n bits -= here_bits;\n //---//\n state.lens[state.have++] = here_val;\n }\n else {\n if (here_val === 16) {\n //=== NEEDBITS(here.bits + 2);\n n = here_bits + 2;\n while (bits < n) {\n if (have === 0) { break inf_leave; }\n have--;\n hold += input[next++] << bits;\n bits += 8;\n }\n //===//\n //--- DROPBITS(here.bits) ---//\n hold >>>= here_bits;\n bits -= here_bits;\n //---//\n if (state.have === 0) {\n strm.msg = 'invalid bit length repeat';\n state.mode = BAD$2;\n break;\n }\n len = state.lens[state.have - 1];\n copy = 3 + (hold & 0x03);//BITS(2);\n //--- DROPBITS(2) ---//\n hold >>>= 2;\n bits -= 2;\n //---//\n }\n else if (here_val === 17) {\n //=== NEEDBITS(here.bits + 3);\n n = here_bits + 3;\n while (bits < n) {\n if (have === 0) { break inf_leave; }\n have--;\n hold += input[next++] << bits;\n bits += 8;\n }\n //===//\n //--- DROPBITS(here.bits) ---//\n hold >>>= here_bits;\n bits -= here_bits;\n //---//\n len = 0;\n copy = 3 + (hold & 0x07);//BITS(3);\n //--- DROPBITS(3) ---//\n hold >>>= 3;\n bits -= 3;\n //---//\n }\n else {\n //=== NEEDBITS(here.bits + 7);\n n = here_bits + 7;\n while (bits < n) {\n if (have === 0) { break inf_leave; }\n have--;\n hold += input[next++] << bits;\n bits += 8;\n }\n //===//\n //--- DROPBITS(here.bits) ---//\n hold >>>= here_bits;\n bits -= here_bits;\n //---//\n len = 0;\n copy = 11 + (hold & 0x7f);//BITS(7);\n //--- DROPBITS(7) ---//\n hold >>>= 7;\n bits -= 7;\n //---//\n }\n if (state.have + copy > state.nlen + state.ndist) {\n strm.msg = 'invalid bit length repeat';\n state.mode = BAD$2;\n break;\n }\n while (copy--) {\n state.lens[state.have++] = len;\n }\n }\n }\n\n /* handle error breaks in while */\n if (state.mode === BAD$2) { break; }\n\n /* check for end-of-block code (better have one) */\n if (state.lens[256] === 0) {\n strm.msg = 'invalid code -- missing end-of-block';\n state.mode = BAD$2;\n break;\n }\n\n /* build code tables -- note: do not change the lenbits or distbits\n values here (9 and 6) without reading the comments in inftrees.h\n concerning the ENOUGH constants, which depend on those values */\n state.lenbits = 9;\n\n opts = { bits: state.lenbits };\n ret = inftrees$1(LENS$2, state.lens, 0, state.nlen, state.lencode, 0, state.work, opts);\n // We have separate tables & no pointers. 2 commented lines below not needed.\n // state.next_index = opts.table_index;\n state.lenbits = opts.bits;\n // state.lencode = state.next;\n\n if (ret) {\n strm.msg = 'invalid literal/lengths set';\n state.mode = BAD$2;\n break;\n }\n\n state.distbits = 6;\n //state.distcode.copy(state.codes);\n // Switch to use dynamic table\n state.distcode = state.distdyn;\n opts = { bits: state.distbits };\n ret = inftrees$1(DISTS$2, state.lens, state.nlen, state.ndist, state.distcode, 0, state.work, opts);\n // We have separate tables & no pointers. 2 commented lines below not needed.\n // state.next_index = opts.table_index;\n state.distbits = opts.bits;\n // state.distcode = state.next;\n\n if (ret) {\n strm.msg = 'invalid distances set';\n state.mode = BAD$2;\n break;\n }\n //Tracev((stderr, 'inflate: codes ok\\n'));\n state.mode = LEN_$1;\n if (flush === Z_TREES$1) { break inf_leave; }\n /* falls through */\n case LEN_$1:\n state.mode = LEN$1;\n /* falls through */\n case LEN$1:\n if (have >= 6 && left >= 258) {\n //--- RESTORE() ---\n strm.next_out = put;\n strm.avail_out = left;\n strm.next_in = next;\n strm.avail_in = have;\n state.hold = hold;\n state.bits = bits;\n //---\n inffast$1(strm, _out);\n //--- LOAD() ---\n put = strm.next_out;\n output = strm.output;\n left = strm.avail_out;\n next = strm.next_in;\n input = strm.input;\n have = strm.avail_in;\n hold = state.hold;\n bits = state.bits;\n //---\n\n if (state.mode === TYPE$2) {\n state.back = -1;\n }\n break;\n }\n state.back = 0;\n for (;;) {\n here = state.lencode[hold & ((1 << state.lenbits) - 1)]; /*BITS(state.lenbits)*/\n here_bits = here >>> 24;\n here_op = (here >>> 16) & 0xff;\n here_val = here & 0xffff;\n\n if (here_bits <= bits) { break; }\n //--- PULLBYTE() ---//\n if (have === 0) { break inf_leave; }\n have--;\n hold += input[next++] << bits;\n bits += 8;\n //---//\n }\n if (here_op && (here_op & 0xf0) === 0) {\n last_bits = here_bits;\n last_op = here_op;\n last_val = here_val;\n for (;;) {\n here = state.lencode[last_val +\n ((hold & ((1 << (last_bits + last_op)) - 1))/*BITS(last.bits + last.op)*/ >> last_bits)];\n here_bits = here >>> 24;\n here_op = (here >>> 16) & 0xff;\n here_val = here & 0xffff;\n\n if ((last_bits + here_bits) <= bits) { break; }\n //--- PULLBYTE() ---//\n if (have === 0) { break inf_leave; }\n have--;\n hold += input[next++] << bits;\n bits += 8;\n //---//\n }\n //--- DROPBITS(last.bits) ---//\n hold >>>= last_bits;\n bits -= last_bits;\n //---//\n state.back += last_bits;\n }\n //--- DROPBITS(here.bits) ---//\n hold >>>= here_bits;\n bits -= here_bits;\n //---//\n state.back += here_bits;\n state.length = here_val;\n if (here_op === 0) {\n //Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?\n // \"inflate: literal '%c'\\n\" :\n // \"inflate: literal 0x%02x\\n\", here.val));\n state.mode = LIT$1;\n break;\n }\n if (here_op & 32) {\n //Tracevv((stderr, \"inflate: end of block\\n\"));\n state.back = -1;\n state.mode = TYPE$2;\n break;\n }\n if (here_op & 64) {\n strm.msg = 'invalid literal/length code';\n state.mode = BAD$2;\n break;\n }\n state.extra = here_op & 15;\n state.mode = LENEXT$1;\n /* falls through */\n case LENEXT$1:\n if (state.extra) {\n //=== NEEDBITS(state.extra);\n n = state.extra;\n while (bits < n) {\n if (have === 0) { break inf_leave; }\n have--;\n hold += input[next++] << bits;\n bits += 8;\n }\n //===//\n state.length += hold & ((1 << state.extra) - 1)/*BITS(state.extra)*/;\n //--- DROPBITS(state.extra) ---//\n hold >>>= state.extra;\n bits -= state.extra;\n //---//\n state.back += state.extra;\n }\n //Tracevv((stderr, \"inflate: length %u\\n\", state.length));\n state.was = state.length;\n state.mode = DIST$1;\n /* falls through */\n case DIST$1:\n for (;;) {\n here = state.distcode[hold & ((1 << state.distbits) - 1)];/*BITS(state.distbits)*/\n here_bits = here >>> 24;\n here_op = (here >>> 16) & 0xff;\n here_val = here & 0xffff;\n\n if ((here_bits) <= bits) { break; }\n //--- PULLBYTE() ---//\n if (have === 0) { break inf_leave; }\n have--;\n hold += input[next++] << bits;\n bits += 8;\n //---//\n }\n if ((here_op & 0xf0) === 0) {\n last_bits = here_bits;\n last_op = here_op;\n last_val = here_val;\n for (;;) {\n here = state.distcode[last_val +\n ((hold & ((1 << (last_bits + last_op)) - 1))/*BITS(last.bits + last.op)*/ >> last_bits)];\n here_bits = here >>> 24;\n here_op = (here >>> 16) & 0xff;\n here_val = here & 0xffff;\n\n if ((last_bits + here_bits) <= bits) { break; }\n //--- PULLBYTE() ---//\n if (have === 0) { break inf_leave; }\n have--;\n hold += input[next++] << bits;\n bits += 8;\n //---//\n }\n //--- DROPBITS(last.bits) ---//\n hold >>>= last_bits;\n bits -= last_bits;\n //---//\n state.back += last_bits;\n }\n //--- DROPBITS(here.bits) ---//\n hold >>>= here_bits;\n bits -= here_bits;\n //---//\n state.back += here_bits;\n if (here_op & 64) {\n strm.msg = 'invalid distance code';\n state.mode = BAD$2;\n break;\n }\n state.offset = here_val;\n state.extra = (here_op) & 15;\n state.mode = DISTEXT$1;\n /* falls through */\n case DISTEXT$1:\n if (state.extra) {\n //=== NEEDBITS(state.extra);\n n = state.extra;\n while (bits < n) {\n if (have === 0) { break inf_leave; }\n have--;\n hold += input[next++] << bits;\n bits += 8;\n }\n //===//\n state.offset += hold & ((1 << state.extra) - 1)/*BITS(state.extra)*/;\n //--- DROPBITS(state.extra) ---//\n hold >>>= state.extra;\n bits -= state.extra;\n //---//\n state.back += state.extra;\n }\n//#ifdef INFLATE_STRICT\n if (state.offset > state.dmax) {\n strm.msg = 'invalid distance too far back';\n state.mode = BAD$2;\n break;\n }\n//#endif\n //Tracevv((stderr, \"inflate: distance %u\\n\", state.offset));\n state.mode = MATCH$1;\n /* falls through */\n case MATCH$1:\n if (left === 0) { break inf_leave; }\n copy = _out - left;\n if (state.offset > copy) { /* copy from window */\n copy = state.offset - copy;\n if (copy > state.whave) {\n if (state.sane) {\n strm.msg = 'invalid distance too far back';\n state.mode = BAD$2;\n break;\n }\n// (!) This block is disabled in zlib defaults,\n// don't enable it for binary compatibility\n//#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR\n// Trace((stderr, \"inflate.c too far\\n\"));\n// copy -= state.whave;\n// if (copy > state.length) { copy = state.length; }\n// if (copy > left) { copy = left; }\n// left -= copy;\n// state.length -= copy;\n// do {\n// output[put++] = 0;\n// } while (--copy);\n// if (state.length === 0) { state.mode = LEN; }\n// break;\n//#endif\n }\n if (copy > state.wnext) {\n copy -= state.wnext;\n from = state.wsize - copy;\n }\n else {\n from = state.wnext - copy;\n }\n if (copy > state.length) { copy = state.length; }\n from_source = state.window;\n }\n else { /* copy from output */\n from_source = output;\n from = put - state.offset;\n copy = state.length;\n }\n if (copy > left) { copy = left; }\n left -= copy;\n state.length -= copy;\n do {\n output[put++] = from_source[from++];\n } while (--copy);\n if (state.length === 0) { state.mode = LEN$1; }\n break;\n case LIT$1:\n if (left === 0) { break inf_leave; }\n output[put++] = state.length;\n left--;\n state.mode = LEN$1;\n break;\n case CHECK$1:\n if (state.wrap) {\n //=== NEEDBITS(32);\n while (bits < 32) {\n if (have === 0) { break inf_leave; }\n have--;\n // Use '|' instead of '+' to make sure that result is signed\n hold |= input[next++] << bits;\n bits += 8;\n }\n //===//\n _out -= left;\n strm.total_out += _out;\n state.total += _out;\n if ((state.wrap & 4) && _out) {\n strm.adler = state.check =\n /*UPDATE_CHECK(state.check, put - _out, _out);*/\n (state.flags ? crc32_1$1(state.check, output, _out, put - _out) : adler32_1$1(state.check, output, _out, put - _out));\n\n }\n _out = left;\n // NB: crc32 stored as signed 32-bit int, zswap32 returns signed too\n if ((state.wrap & 4) && (state.flags ? hold : zswap32$1(hold)) !== state.check) {\n strm.msg = 'incorrect data check';\n state.mode = BAD$2;\n break;\n }\n //=== INITBITS();\n hold = 0;\n bits = 0;\n //===//\n //Tracev((stderr, \"inflate: check matches trailer\\n\"));\n }\n state.mode = LENGTH$1;\n /* falls through */\n case LENGTH$1:\n if (state.wrap && state.flags) {\n //=== NEEDBITS(32);\n while (bits < 32) {\n if (have === 0) { break inf_leave; }\n have--;\n hold += input[next++] << bits;\n bits += 8;\n }\n //===//\n if ((state.wrap & 4) && hold !== (state.total & 0xffffffff)) {\n strm.msg = 'incorrect length check';\n state.mode = BAD$2;\n break;\n }\n //=== INITBITS();\n hold = 0;\n bits = 0;\n //===//\n //Tracev((stderr, \"inflate: length matches trailer\\n\"));\n }\n state.mode = DONE$1;\n /* falls through */\n case DONE$1:\n ret = Z_STREAM_END$1$1;\n break inf_leave;\n case BAD$2:\n ret = Z_DATA_ERROR$1$1;\n break inf_leave;\n case MEM$1:\n return Z_MEM_ERROR$1$1;\n case SYNC$1:\n /* falls through */\n default:\n return Z_STREAM_ERROR$1$1;\n }\n }\n\n // inf_leave <- here is real place for \"goto inf_leave\", emulated via \"break inf_leave\"\n\n /*\n Return from inflate(), updating the total counts and the check value.\n If there was no progress during the inflate() call, return a buffer\n error. Call updatewindow() to create and/or update the window state.\n Note: a memory error from inflate() is non-recoverable.\n */\n\n //--- RESTORE() ---\n strm.next_out = put;\n strm.avail_out = left;\n strm.next_in = next;\n strm.avail_in = have;\n state.hold = hold;\n state.bits = bits;\n //---\n\n if (state.wsize || (_out !== strm.avail_out && state.mode < BAD$2 &&\n (state.mode < CHECK$1 || flush !== Z_FINISH$1$1))) {\n if (updatewindow$1(strm, strm.output, strm.next_out, _out - strm.avail_out)) ;\n }\n _in -= strm.avail_in;\n _out -= strm.avail_out;\n strm.total_in += _in;\n strm.total_out += _out;\n state.total += _out;\n if ((state.wrap & 4) && _out) {\n strm.adler = state.check = /*UPDATE_CHECK(state.check, strm.next_out - _out, _out);*/\n (state.flags ? crc32_1$1(state.check, output, _out, strm.next_out - _out) : adler32_1$1(state.check, output, _out, strm.next_out - _out));\n }\n strm.data_type = state.bits + (state.last ? 64 : 0) +\n (state.mode === TYPE$2 ? 128 : 0) +\n (state.mode === LEN_$1 || state.mode === COPY_$1 ? 256 : 0);\n if (((_in === 0 && _out === 0) || flush === Z_FINISH$1$1) && ret === Z_OK$1$1) {\n ret = Z_BUF_ERROR$2;\n }\n return ret;\n};\n\n\nconst inflateEnd$1 = (strm) => {\n\n if (inflateStateCheck(strm)) {\n return Z_STREAM_ERROR$1$1;\n }\n\n let state = strm.state;\n if (state.window) {\n state.window = null;\n }\n strm.state = null;\n return Z_OK$1$1;\n};\n\n\nconst inflateGetHeader$1 = (strm, head) => {\n\n /* check state */\n if (inflateStateCheck(strm)) { return Z_STREAM_ERROR$1$1; }\n const state = strm.state;\n if ((state.wrap & 2) === 0) { return Z_STREAM_ERROR$1$1; }\n\n /* save header structure */\n state.head = head;\n head.done = false;\n return Z_OK$1$1;\n};\n\n\nconst inflateSetDictionary$1 = (strm, dictionary) => {\n const dictLength = dictionary.length;\n\n let state;\n let dictid;\n let ret;\n\n /* check state */\n if (inflateStateCheck(strm)) { return Z_STREAM_ERROR$1$1; }\n state = strm.state;\n\n if (state.wrap !== 0 && state.mode !== DICT$1) {\n return Z_STREAM_ERROR$1$1;\n }\n\n /* check for correct dictionary identifier */\n if (state.mode === DICT$1) {\n dictid = 1; /* adler32(0, null, 0)*/\n /* dictid = adler32(dictid, dictionary, dictLength); */\n dictid = adler32_1$1(dictid, dictionary, dictLength, 0);\n if (dictid !== state.check) {\n return Z_DATA_ERROR$1$1;\n }\n }\n /* copy dictionary to window using updatewindow(), which will amend the\n existing dictionary if appropriate */\n ret = updatewindow$1(strm, dictionary, dictLength, dictLength);\n if (ret) {\n state.mode = MEM$1;\n return Z_MEM_ERROR$1$1;\n }\n state.havedict = 1;\n // Tracev((stderr, \"inflate: dictionary set\\n\"));\n return Z_OK$1$1;\n};\n\n\nvar inflateReset_1$1 = inflateReset$1;\nvar inflateReset2_1$1 = inflateReset2$1;\nvar inflateResetKeep_1$1 = inflateResetKeep$1;\nvar inflateInit_1$1 = inflateInit$1;\nvar inflateInit2_1$1 = inflateInit2$1;\nvar inflate_2$1$1 = inflate$2$1;\nvar inflateEnd_1$1 = inflateEnd$1;\nvar inflateGetHeader_1$1 = inflateGetHeader$1;\nvar inflateSetDictionary_1$1 = inflateSetDictionary$1;\nvar inflateInfo$1 = 'pako inflate (from Nodeca project)';\n\n/* Not implemented\nmodule.exports.inflateCodesUsed = inflateCodesUsed;\nmodule.exports.inflateCopy = inflateCopy;\nmodule.exports.inflateGetDictionary = inflateGetDictionary;\nmodule.exports.inflateMark = inflateMark;\nmodule.exports.inflatePrime = inflatePrime;\nmodule.exports.inflateSync = inflateSync;\nmodule.exports.inflateSyncPoint = inflateSyncPoint;\nmodule.exports.inflateUndermine = inflateUndermine;\nmodule.exports.inflateValidate = inflateValidate;\n*/\n\nvar inflate_1$2$1 = {\n\tinflateReset: inflateReset_1$1,\n\tinflateReset2: inflateReset2_1$1,\n\tinflateResetKeep: inflateResetKeep_1$1,\n\tinflateInit: inflateInit_1$1,\n\tinflateInit2: inflateInit2_1$1,\n\tinflate: inflate_2$1$1,\n\tinflateEnd: inflateEnd_1$1,\n\tinflateGetHeader: inflateGetHeader_1$1,\n\tinflateSetDictionary: inflateSetDictionary_1$1,\n\tinflateInfo: inflateInfo$1\n};\n\n// (C) 1995-2013 Jean-loup Gailly and Mark Adler\n// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin\n//\n// This software is provided 'as-is', without any express or implied\n// warranty. In no event will the authors be held liable for any damages\n// arising from the use of this software.\n//\n// Permission is granted to anyone to use this software for any purpose,\n// including commercial applications, and to alter it and redistribute it\n// freely, subject to the following restrictions:\n//\n// 1. The origin of this software must not be misrepresented; you must not\n// claim that you wrote the original software. If you use this software\n// in a product, an acknowledgment in the product documentation would be\n// appreciated but is not required.\n// 2. Altered source versions must be plainly marked as such, and must not be\n// misrepresented as being the original software.\n// 3. This notice may not be removed or altered from any source distribution.\n\nfunction GZheader$1() {\n /* true if compressed data believed to be text */\n this.text = 0;\n /* modification time */\n this.time = 0;\n /* extra flags (not used when writing a gzip file) */\n this.xflags = 0;\n /* operating system */\n this.os = 0;\n /* pointer to extra field or Z_NULL if none */\n this.extra = null;\n /* extra field length (valid if extra != Z_NULL) */\n this.extra_len = 0; // Actually, we don't need it in JS,\n // but leave for few code modifications\n\n //\n // Setup limits is not necessary because in js we should not preallocate memory\n // for inflate use constant limit in 65536 bytes\n //\n\n /* space at extra (only when reading header) */\n // this.extra_max = 0;\n /* pointer to zero-terminated file name or Z_NULL */\n this.name = '';\n /* space at name (only when reading header) */\n // this.name_max = 0;\n /* pointer to zero-terminated comment or Z_NULL */\n this.comment = '';\n /* space at comment (only when reading header) */\n // this.comm_max = 0;\n /* true if there was or will be a header crc */\n this.hcrc = 0;\n /* true when done reading gzip header (not used when writing a gzip file) */\n this.done = false;\n}\n\nvar gzheader$1 = GZheader$1;\n\nconst toString$2 = Object.prototype.toString;\n\n/* Public constants ==========================================================*/\n/* ===========================================================================*/\n\nconst {\n Z_NO_FLUSH: Z_NO_FLUSH$3, Z_FINISH: Z_FINISH$4,\n Z_OK: Z_OK$4, Z_STREAM_END: Z_STREAM_END$4, Z_NEED_DICT: Z_NEED_DICT$2, Z_STREAM_ERROR: Z_STREAM_ERROR$3, Z_DATA_ERROR: Z_DATA_ERROR$3, Z_MEM_ERROR: Z_MEM_ERROR$2\n} = constants$2$1;\n\n/* ===========================================================================*/\n\n\n/**\n * class Inflate\n *\n * Generic JS-style wrapper for zlib calls. If you don't need\n * streaming behaviour - use more simple functions: [[inflate]]\n * and [[inflateRaw]].\n **/\n\n/* internal\n * inflate.chunks -> Array\n *\n * Chunks of output data, if [[Inflate#onData]] not overridden.\n **/\n\n/**\n * Inflate.result -> Uint8Array|String\n *\n * Uncompressed result, generated by default [[Inflate#onData]]\n * and [[Inflate#onEnd]] handlers. Filled after you push last chunk\n * (call [[Inflate#push]] with `Z_FINISH` / `true` param).\n **/\n\n/**\n * Inflate.err -> Number\n *\n * Error code after inflate finished. 0 (Z_OK) on success.\n * Should be checked if broken data possible.\n **/\n\n/**\n * Inflate.msg -> String\n *\n * Error message, if [[Inflate.err]] != 0\n **/\n\n\n/**\n * new Inflate(options)\n * - options (Object): zlib inflate options.\n *\n * Creates new inflator instance with specified params. Throws exception\n * on bad params. Supported options:\n *\n * - `windowBits`\n * - `dictionary`\n *\n * [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced)\n * for more information on these.\n *\n * Additional options, for internal needs:\n *\n * - `chunkSize` - size of generated data chunks (16K by default)\n * - `raw` (Boolean) - do raw inflate\n * - `to` (String) - if equal to 'string', then result will be converted\n * from utf8 to utf16 (javascript) string. When string output requested,\n * chunk length can differ from `chunkSize`, depending on content.\n *\n * By default, when no options set, autodetect deflate/gzip data format via\n * wrapper header.\n *\n * ##### Example:\n *\n * ```javascript\n * const pako = require('pako')\n * const chunk1 = new Uint8Array([1,2,3,4,5,6,7,8,9])\n * const chunk2 = new Uint8Array([10,11,12,13,14,15,16,17,18,19]);\n *\n * const inflate = new pako.Inflate({ level: 3});\n *\n * inflate.push(chunk1, false);\n * inflate.push(chunk2, true); // true -> last chunk\n *\n * if (inflate.err) { throw new Error(inflate.err); }\n *\n * console.log(inflate.result);\n * ```\n **/\nfunction Inflate$1$1(options) {\n this.options = common$1.assign({\n chunkSize: 1024 * 64,\n windowBits: 15,\n to: ''\n }, options || {});\n\n const opt = this.options;\n\n // Force window size for `raw` data, if not set directly,\n // because we have no header for autodetect.\n if (opt.raw && (opt.windowBits >= 0) && (opt.windowBits < 16)) {\n opt.windowBits = -opt.windowBits;\n if (opt.windowBits === 0) { opt.windowBits = -15; }\n }\n\n // If `windowBits` not defined (and mode not raw) - set autodetect flag for gzip/deflate\n if ((opt.windowBits >= 0) && (opt.windowBits < 16) &&\n !(options && options.windowBits)) {\n opt.windowBits += 32;\n }\n\n // Gzip header has no info about windows size, we can do autodetect only\n // for deflate. So, if window size not set, force it to max when gzip possible\n if ((opt.windowBits > 15) && (opt.windowBits < 48)) {\n // bit 3 (16) -> gzipped data\n // bit 4 (32) -> autodetect gzip/deflate\n if ((opt.windowBits & 15) === 0) {\n opt.windowBits |= 15;\n }\n }\n\n this.err = 0; // error code, if happens (0 = Z_OK)\n this.msg = ''; // error message\n this.ended = false; // used to avoid multiple onEnd() calls\n this.chunks = []; // chunks of compressed data\n\n this.strm = new zstream$1();\n this.strm.avail_out = 0;\n\n let status = inflate_1$2$1.inflateInit2(\n this.strm,\n opt.windowBits\n );\n\n if (status !== Z_OK$4) {\n throw new Error(messages$1[status]);\n }\n\n this.header = new gzheader$1();\n\n inflate_1$2$1.inflateGetHeader(this.strm, this.header);\n\n // Setup dictionary\n if (opt.dictionary) {\n // Convert data if needed\n if (typeof opt.dictionary === 'string') {\n opt.dictionary = strings$1.string2buf(opt.dictionary);\n } else if (toString$2.call(opt.dictionary) === '[object ArrayBuffer]') {\n opt.dictionary = new Uint8Array(opt.dictionary);\n }\n if (opt.raw) { //In raw mode we need to set the dictionary early\n status = inflate_1$2$1.inflateSetDictionary(this.strm, opt.dictionary);\n if (status !== Z_OK$4) {\n throw new Error(messages$1[status]);\n }\n }\n }\n}\n\n/**\n * Inflate#push(data[, flush_mode]) -> Boolean\n * - data (Uint8Array|ArrayBuffer): input data\n * - flush_mode (Number|Boolean): 0..6 for corresponding Z_NO_FLUSH..Z_TREE\n * flush modes. See constants. Skipped or `false` means Z_NO_FLUSH,\n * `true` means Z_FINISH.\n *\n * Sends input data to inflate pipe, generating [[Inflate#onData]] calls with\n * new output chunks. Returns `true` on success. If end of stream detected,\n * [[Inflate#onEnd]] will be called.\n *\n * `flush_mode` is not needed for normal operation, because end of stream\n * detected automatically. You may try to use it for advanced things, but\n * this functionality was not tested.\n *\n * On fail call [[Inflate#onEnd]] with error code and return false.\n *\n * ##### Example\n *\n * ```javascript\n * push(chunk, false); // push one of data chunks\n * ...\n * push(chunk, true); // push last chunk\n * ```\n **/\nInflate$1$1.prototype.push = function (data, flush_mode) {\n const strm = this.strm;\n const chunkSize = this.options.chunkSize;\n const dictionary = this.options.dictionary;\n let status, _flush_mode, last_avail_out;\n\n if (this.ended) return false;\n\n if (flush_mode === ~~flush_mode) _flush_mode = flush_mode;\n else _flush_mode = flush_mode === true ? Z_FINISH$4 : Z_NO_FLUSH$3;\n\n // Convert data if needed\n if (toString$2.call(data) === '[object ArrayBuffer]') {\n strm.input = new Uint8Array(data);\n } else {\n strm.input = data;\n }\n\n strm.next_in = 0;\n strm.avail_in = strm.input.length;\n\n for (;;) {\n if (strm.avail_out === 0) {\n strm.output = new Uint8Array(chunkSize);\n strm.next_out = 0;\n strm.avail_out = chunkSize;\n }\n\n status = inflate_1$2$1.inflate(strm, _flush_mode);\n\n if (status === Z_NEED_DICT$2 && dictionary) {\n status = inflate_1$2$1.inflateSetDictionary(strm, dictionary);\n\n if (status === Z_OK$4) {\n status = inflate_1$2$1.inflate(strm, _flush_mode);\n } else if (status === Z_DATA_ERROR$3) {\n // Replace code with more verbose\n status = Z_NEED_DICT$2;\n }\n }\n\n // Skip snyc markers if more data follows and not raw mode\n while (strm.avail_in > 0 &&\n status === Z_STREAM_END$4 &&\n strm.state.wrap > 0 &&\n data[strm.next_in] !== 0)\n {\n inflate_1$2$1.inflateReset(strm);\n status = inflate_1$2$1.inflate(strm, _flush_mode);\n }\n\n switch (status) {\n case Z_STREAM_ERROR$3:\n case Z_DATA_ERROR$3:\n case Z_NEED_DICT$2:\n case Z_MEM_ERROR$2:\n this.onEnd(status);\n this.ended = true;\n return false;\n }\n\n // Remember real `avail_out` value, because we may patch out buffer content\n // to align utf8 strings boundaries.\n last_avail_out = strm.avail_out;\n\n if (strm.next_out) {\n if (strm.avail_out === 0 || status === Z_STREAM_END$4) {\n\n if (this.options.to === 'string') {\n\n let next_out_utf8 = strings$1.utf8border(strm.output, strm.next_out);\n\n let tail = strm.next_out - next_out_utf8;\n let utf8str = strings$1.buf2string(strm.output, next_out_utf8);\n\n // move tail & realign counters\n strm.next_out = tail;\n strm.avail_out = chunkSize - tail;\n if (tail) strm.output.set(strm.output.subarray(next_out_utf8, next_out_utf8 + tail), 0);\n\n this.onData(utf8str);\n\n } else {\n this.onData(strm.output.length === strm.next_out ? strm.output : strm.output.subarray(0, strm.next_out));\n }\n }\n }\n\n // Must repeat iteration if out buffer is full\n if (status === Z_OK$4 && last_avail_out === 0) continue;\n\n // Finalize if end of stream reached.\n if (status === Z_STREAM_END$4) {\n status = inflate_1$2$1.inflateEnd(this.strm);\n this.onEnd(status);\n this.ended = true;\n return true;\n }\n\n if (strm.avail_in === 0) break;\n }\n\n return true;\n};\n\n\n/**\n * Inflate#onData(chunk) -> Void\n * - chunk (Uint8Array|String): output data. When string output requested,\n * each chunk will be string.\n *\n * By default, stores data blocks in `chunks[]` property and glue\n * those in `onEnd`. Override this handler, if you need another behaviour.\n **/\nInflate$1$1.prototype.onData = function (chunk) {\n this.chunks.push(chunk);\n};\n\n\n/**\n * Inflate#onEnd(status) -> Void\n * - status (Number): inflate status. 0 (Z_OK) on success,\n * other if not.\n *\n * Called either after you tell inflate that the input stream is\n * complete (Z_FINISH). By default - join collected chunks,\n * free memory and fill `results` / `err` properties.\n **/\nInflate$1$1.prototype.onEnd = function (status) {\n // On success - join\n if (status === Z_OK$4) {\n if (this.options.to === 'string') {\n this.result = this.chunks.join('');\n } else {\n this.result = common$1.flattenChunks(this.chunks);\n }\n }\n this.chunks = [];\n this.err = status;\n this.msg = this.strm.msg;\n};\n\n\n/**\n * inflate(data[, options]) -> Uint8Array|String\n * - data (Uint8Array|ArrayBuffer): input data to decompress.\n * - options (Object): zlib inflate options.\n *\n * Decompress `data` with inflate/ungzip and `options`. Autodetect\n * format via wrapper header by default. That's why we don't provide\n * separate `ungzip` method.\n *\n * Supported options are:\n *\n * - windowBits\n *\n * [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced)\n * for more information.\n *\n * Sugar (options):\n *\n * - `raw` (Boolean) - say that we work with raw stream, if you don't wish to specify\n * negative windowBits implicitly.\n * - `to` (String) - if equal to 'string', then result will be converted\n * from utf8 to utf16 (javascript) string. When string output requested,\n * chunk length can differ from `chunkSize`, depending on content.\n *\n *\n * ##### Example:\n *\n * ```javascript\n * const pako = require('pako');\n * const input = pako.deflate(new Uint8Array([1,2,3,4,5,6,7,8,9]));\n * let output;\n *\n * try {\n * output = pako.inflate(input);\n * } catch (err) {\n * console.log(err);\n * }\n * ```\n **/\nfunction inflate$1$1(input, options) {\n const inflator = new Inflate$1$1(options);\n\n inflator.push(input);\n\n // That will never happens, if you don't cheat with options :)\n if (inflator.err) throw inflator.msg || messages$1[inflator.err];\n\n return inflator.result;\n}\n\n\n/**\n * inflateRaw(data[, options]) -> Uint8Array|String\n * - data (Uint8Array|ArrayBuffer): input data to decompress.\n * - options (Object): zlib inflate options.\n *\n * The same as [[inflate]], but creates raw data, without wrapper\n * (header and adler32 crc).\n **/\nfunction inflateRaw$1$1(input, options) {\n options = options || {};\n options.raw = true;\n return inflate$1$1(input, options);\n}\n\n\n/**\n * ungzip(data[, options]) -> Uint8Array|String\n * - data (Uint8Array|ArrayBuffer): input data to decompress.\n * - options (Object): zlib inflate options.\n *\n * Just shortcut to [[inflate]], because it autodetects format\n * by header.content. Done for convenience.\n **/\n\n\nvar Inflate_1$1$1 = Inflate$1$1;\nvar inflate_2$2 = inflate$1$1;\nvar inflateRaw_1$1$1 = inflateRaw$1$1;\nvar ungzip$1$1 = inflate$1$1;\nvar constants$3 = constants$2$1;\n\nvar inflate_1$1$1 = {\n\tInflate: Inflate_1$1$1,\n\tinflate: inflate_2$2,\n\tinflateRaw: inflateRaw_1$1$1,\n\tungzip: ungzip$1$1,\n\tconstants: constants$3\n};\n\nconst { Deflate, deflate, deflateRaw, gzip } = deflate_1$1;\n\nconst { Inflate: Inflate$2, inflate: inflate$3, inflateRaw: inflateRaw$2, ungzip: ungzip$2 } = inflate_1$1$1;\nvar deflateRaw_1 = deflateRaw;\nvar inflate_1$3 = inflate$3;\nvar inflateRaw_1 = inflateRaw$2;\nvar ungzip_1$1 = ungzip$2;\n\nconst FEXTRA = 4; // gzip spec F.EXTRA flag\n\nfunction isgzipped(data) {\n const b = ArrayBuffer.isView(data) ? data : new Uint8Array(data);\n return b[0] ===31 && b[1] === 139;\n}\n\n/**\n * Pako does not properly ungzip block compressed files if > 1 block is present. Test for bgzip and use wrapper.\n */\nfunction ungzip_blocks(data) {\n const ba = ArrayBuffer.isView(data) ? data : new Uint8Array(data);\n const b = ba[3] & FEXTRA;\n if (b !== 0 && ba[12] === 66 && ba[13] === 67) {\n return unbgzf(ba.buffer);\n } else {\n return ungzip_1$1(ba);\n }\n}\n\n// Uncompress data, assumed to be series of bgzipped blocks\nfunction unbgzf(data, lim) {\n\n const oBlockList = [];\n let ptr = 0;\n let totalSize = 0;\n\n lim = lim || data.byteLength - 18;\n\n while (ptr < lim) {\n try {\n const ba = ArrayBuffer.isView(data) ? data : new Uint8Array(data, ptr, 18);\n const xlen = (ba[11] << 8) | (ba[10]);\n const flg = ba[3];\n const fextra = flg & FEXTRA;\n const si1 = ba[12];\n const si2 = ba[13];\n const slen = (ba[15] << 8) | (ba[14]);\n const bsize = ((ba[17] << 8) | (ba[16])) + 1;\n const start = 12 + xlen + ptr; // Start of CDATA\n const bytesLeft = data.byteLength - start;\n const cDataSize = bsize - xlen - 19;\n if (bytesLeft < cDataSize || cDataSize <= 0) break;\n\n const a = new Uint8Array(data, start, cDataSize);\n const unc = inflateRaw_1(a);\n\n // const inflate = new Zlib.RawInflate(a);\n // const unc = inflate.decompress();\n\n ptr += (cDataSize - 1) + 26; //inflate.ip + 26\n totalSize += unc.byteLength;\n oBlockList.push(unc);\n } catch (e) {\n console.error(e);\n break;\n }\n }\n\n // Concatenate decompressed blocks\n if (oBlockList.length === 1) {\n return oBlockList[0];\n } else {\n const out = new Uint8Array(totalSize);\n let cursor = 0;\n for (let i = 0; i < oBlockList.length; ++i) {\n var b = new Uint8Array(oBlockList[i]);\n arrayCopy(b, 0, out, cursor, b.length);\n cursor += b.length;\n }\n return out;\n }\n}\n\nfunction bgzBlockSize$1(data) {\n const ba = ArrayBuffer.isView(data) ? data : new Uint8Array(data);\n const bsize = (ba[17] << 8 | ba[16]) + 1;\n return bsize;\n}\n\n// From Thomas Down's zlib implementation\n\nconst testArray = new Uint8Array(1);\nconst hasSubarray = (typeof testArray.subarray === 'function');\n\nfunction arrayCopy(src, srcOffset, dest, destOffset, count) {\n if (count === 0) {\n return;\n }\n if (!src) {\n throw \"Undef src\";\n } else if (!dest) {\n throw \"Undef dest\";\n }\n if (srcOffset === 0 && count === src.length) {\n arrayCopy_fast(src, dest, destOffset);\n } else if (hasSubarray) {\n arrayCopy_fast(src.subarray(srcOffset, srcOffset + count), dest, destOffset);\n } else if (src.BYTES_PER_ELEMENT === 1 && count > 100) {\n arrayCopy_fast(new Uint8Array(src.buffer, src.byteOffset + srcOffset, count), dest, destOffset);\n } else {\n arrayCopy_slow(src, srcOffset, dest, destOffset, count);\n }\n}\n\nfunction arrayCopy_slow(src, srcOffset, dest, destOffset, count) {\n for (let i = 0; i < count; ++i) {\n dest[destOffset + i] = src[srcOffset + i];\n }\n}\n\nfunction arrayCopy_fast(src, dest, destOffset) {\n dest.set(src, destOffset);\n}\n\n\n/**\n * Compress string and encode in a url safe form\n * @param s\n */\nfunction compressString(str) {\n\n const bytes = new Uint8Array(str.length);\n for (var i = 0; i < str.length; i++) {\n bytes[i] = str.charCodeAt(i);\n }\n const compressedBytes = new deflateRaw_1(bytes); // UInt8Arry\n const compressedString = String.fromCharCode.apply(null, compressedBytes); // Convert to string\n let enc = btoa(compressedString);\n return enc.replace(/\\+/g, '.').replace(/\\//g, '_').replace(/=/g, '-'); // URL safe\n}\n\n/**\n * Uncompress the url-safe encoded compressed string, presumably created by compressString above\n *\n * @param enc\n * @returns {string}\n */\nfunction uncompressString(enc) {\n\n enc = enc.replace(/\\./g, '+').replace(/_/g, '/').replace(/-/g, '=');\n\n const compressedString = atob(enc);\n const compressedBytes = [];\n for (let i = 0; i < compressedString.length; i++) {\n compressedBytes.push(compressedString.charCodeAt(i));\n }\n //const bytes = new Zlib.RawInflate(compressedBytes).decompress();\n const bytes = inflateRaw_1(compressedBytes);\n\n let str = '';\n for (let b of bytes) {\n str += String.fromCharCode(b);\n }\n return str;\n}\n\n\n/**\n * @param dataURI\n * @returns {Array|Uint8Array}\n */\nfunction decodeDataURI$1(dataURI, gzip) {\n\n const split = dataURI.split(',');\n const info = split[0].split(':')[1];\n let dataString = split[1];\n\n if (info.indexOf('base64') >= 0) {\n dataString = atob(dataString);\n\n const bytes = new Uint8Array(dataString.length);\n for (let i = 0; i < dataString.length; i++) {\n bytes[i] = dataString.charCodeAt(i);\n }\n\n let plain;\n if (gzip || info.indexOf('gzip') > 0) {\n plain = ungzip_1$1(bytes);\n } else {\n plain = bytes;\n }\n return plain\n } else {\n return decodeURIComponent(dataString); // URL encoded string -- not currently used or tested\n }\n}\n\n/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2016-2017 The Regents of the University of California\n * Author: Jim Robinson\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\nconst IGVMath = {\n\n lerp: (v0, v1, t) => {\n return (1 - t) * v0 + t * v1;\n },\n\n mean: function (array) {\n\n var t = 0, n = 0,\n i;\n for (i = 0; i < array.length; i++) {\n if (!isNaN(array[i])) {\n t += array[i];\n n++;\n }\n }\n return n > 0 ? t / n : 0;\n },\n\n meanAndStdev: function (array) {\n\n var v, t = 0, t2 = 0, n = 0, i;\n\n for (i = 0; i < array.length; i++) {\n\n v = array[i];\n\n if (!isNaN(v)) {\n t += v;\n t2 += v * v;\n n++;\n }\n }\n return n > 0 ? {mean: t / n, stdev: Math.sqrt(t2 - t * t / n)} : {mean: 0, stdev: 0};\n },\n\n median: function (numbers) {\n // median of [3, 5, 4, 4, 1, 1, 2, 3] = 3\n var median = 0, numsLen = numbers.length;\n numbers.sort();\n\n if (\n numsLen % 2 === 0 // is even\n ) {\n // average of two middle numbers\n median = (numbers[numsLen / 2 - 1] + numbers[numsLen / 2]) / 2;\n } else { // is odd\n // middle number only\n median = numbers[(numsLen - 1) / 2];\n }\n\n return median;\n },\n\n // Fast percentile function for \"p\" near edges. This needs profiled for p in middle (e.g. median)\n percentile: function (array, p) {\n\n if (array.length === 0) return undefined;\n\n var k = Math.floor(array.length * ((100 - p) / 100));\n if (k === 0) {\n array.sort(function (a, b) {\n return b - a\n });\n return array[k];\n } else {\n return selectElement(array, k);\n }\n\n },\n\n\n clamp: function (value, min, max) {\n return Math.min(Math.max(value, min), max);\n },\n\n log2: function (x) {\n return Math.log(x) / Math.LN2;\n }\n\n};\n\nfunction selectElement(array, k) {\n\n // Credit Steve Hanov http://stevehanov.ca/blog/index.php?id=122\n var heap = new BinaryHeap(),\n i;\n\n for (i = 0; i < array.length; i++) {\n\n var item = array[i];\n\n // If we have not yet found k items, or the current item is larger than\n // the smallest item on the heap, add current item\n if (heap.content.length < k || item > heap.content[0]) {\n // If the heap is full, remove the smallest element on the heap.\n if (heap.content.length === k) {\n heap.pop();\n }\n heap.push(item);\n }\n }\n\n return heap.content[0];\n}\n\n\nfunction BinaryHeap() {\n this.content = [];\n}\n\nBinaryHeap.prototype = {\n push: function (element) {\n // Add the new element to the end of the array.\n this.content.push(element);\n // Allow it to bubble up.\n this.bubbleUp(this.content.length - 1);\n },\n\n pop: function () {\n // Store the first element so we can return it later.\n var result = this.content[0];\n // Get the element at the end of the array.\n var end = this.content.pop();\n // If there are any elements left, put the end element at the\n // start, and let it sink down.\n if (this.content.length > 0) {\n this.content[0] = end;\n this.sinkDown(0);\n }\n return result;\n },\n\n remove: function (node) {\n var length = this.content.length;\n // To remove a value, we must search through the array to find\n // it.\n for (var i = 0; i < length; i++) {\n if (this.content[i] !== node) continue;\n // When it is found, the process seen in 'pop' is repeated\n // to fill up the hole.\n var end = this.content.pop();\n // If the element we popped was the one we needed to remove,\n // we're done.\n if (i === length - 1) break;\n // Otherwise, we replace the removed element with the popped\n // one, and allow it to float up or sink down as appropriate.\n this.content[i] = end;\n this.bubbleUp(i);\n this.sinkDown(i);\n break;\n }\n },\n\n size: function () {\n return this.content.length;\n },\n\n bubbleUp: function (n) {\n // Fetch the element that has to be moved.\n var element = this.content[n], score = element;\n // When at 0, an element can not go up any further.\n while (n > 0) {\n // Compute the parent element's index, and fetch it.\n var parentN = Math.floor((n + 1) / 2) - 1,\n parent = this.content[parentN];\n // If the parent has a lesser score, things are in order and we\n // are done.\n if (score >= parent)\n break;\n\n // Otherwise, swap the parent with the current element and\n // continue.\n this.content[parentN] = element;\n this.content[n] = parent;\n n = parentN;\n }\n },\n\n sinkDown: function (n) {\n // Look up the target element and its score.\n var length = this.content.length,\n element = this.content[n],\n elemScore = element;\n\n while (true) {\n // Compute the indices of the child elements.\n var child2N = (n + 1) * 2, child1N = child2N - 1;\n // This is used to store the new position of the element,\n // if any.\n var swap = null;\n // If the first child exists (is inside the array)...\n if (child1N < length) {\n // Look it up and compute its score.\n var child1 = this.content[child1N],\n child1Score = child1;\n // If the score is less than our element's, we need to swap.\n if (child1Score < elemScore)\n swap = child1N;\n }\n // Do the same checks for the other child.\n if (child2N < length) {\n var child2 = this.content[child2N],\n child2Score = child2;\n if (child2Score < (swap == null ? elemScore : child1Score))\n swap = child2N;\n }\n\n // No need to swap further, we are done.\n if (swap == null) break;\n\n // Otherwise, swap and continue.\n this.content[n] = this.content[swap];\n this.content[swap] = element;\n n = swap;\n }\n }\n};\n\n/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2014 Broad Institute\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\nfunction _random(min, max) {\n return Math.random() * (max - min) + min\n}\n\nconst IGVColor = {\n\n rgbListFromHSV: () => {\n\n let s = 1;\n let accumulation = [];\n for (let v = 1; v >= 0.5; v -= .1) {\n for (let h = 0; h < 1; h += 1 / 28) {\n const r = \"rgb(\" + IGVColor.hsvToRgb(h, s, v).join(\",\") + \")\";\n accumulation.push(r);\n }\n }\n\n // add black\n accumulation.pop();\n accumulation.push(IGVColor.rgbColor(16, 16, 16));\n\n return accumulation\n },\n\n rgbToHex: function (rgb) {\n rgb = rgb.match(/^rgba?[\\s+]?\\([\\s+]?(\\d+)[\\s+]?,[\\s+]?(\\d+)[\\s+]?,[\\s+]?(\\d+)[\\s+]?/i);\n return (rgb && rgb.length === 4) ? \"#\" +\n (\"0\" + parseInt(rgb[1], 10).toString(16)).slice(-2) +\n (\"0\" + parseInt(rgb[2], 10).toString(16)).slice(-2) +\n (\"0\" + parseInt(rgb[3], 10).toString(16)).slice(-2) : ''\n },\n\n hexToRgb: function (hex) {\n\n var cooked = /^#?([a-f\\d]{2})([a-f\\d]{2})([a-f\\d]{2})$/i.exec(hex);\n\n if (null === cooked) {\n return undefined\n }\n\n return \"rgb(\" + parseInt(cooked[1], 16) + \",\" + parseInt(cooked[2], 16) + \",\" + parseInt(cooked[3], 16) + \")\"\n },\n\n /**\n * Converts an HSV color value to RGB. Conversion formula\n * adapted from http://en.wikipedia.org/wiki/HSV_color_space.\n * Assumes h, s, and v are contained in the set [0, 1] and\n * returns r, g, and b in the set [0, 255].\n *\n * Credit: https://gist.githubusercontent.com/mjackson/5311256\n *\n * @param h The hue\n * @param s The saturation\n * @param v The value\n * @return Array The RGB representation\n */\n hsvToRgb: function (h, s, v) {\n var r, g, b;\n\n var i = Math.floor(h * 6);\n var f = h * 6 - i;\n var p = v * (1 - s);\n var q = v * (1 - f * s);\n var t = v * (1 - (1 - f) * s);\n\n switch (i % 6) {\n case 0:\n r = v, g = t, b = p;\n break\n case 1:\n r = q, g = v, b = p;\n break\n case 2:\n r = p, g = v, b = t;\n break\n case 3:\n r = p, g = q, b = v;\n break\n case 4:\n r = t, g = p, b = v;\n break\n case 5:\n r = v, g = p, b = q;\n break\n }\n\n return [Math.floor(r * 255), Math.floor(g * 255), Math.floor(b * 255)]\n },\n\n /**\n * Converts an HSL color value to RGB. Conversion formula\n * adapted from http://en.wikipedia.org/wiki/HSL_color_space.\n * Assumes h, s, and l are contained in the set [0, 1] and\n * returns r, g, and b in the set [0, 255].\n *\n * Credit: https://gist.githubusercontent.com/mjackson/5311256\n *\n * @param h The hue\n * @param s The saturation\n * @param l The lightness\n * @return Array The RGB representation\n */\n hslToRgb: function (h, s, l) {\n var r, g, b;\n\n if (s === 0) {\n r = g = b = l; // achromatic\n } else {\n\n\n var q = l < 0.5 ? l * (1 + s) : l + s - l * s;\n var p = 2 * l - q;\n\n r = IGVColor.hue2rgb(p, q, h + 1 / 3);\n g = IGVColor.hue2rgb(p, q, h);\n b = IGVColor.hue2rgb(p, q, h - 1 / 3);\n }\n\n return [r * 255, g * 255, b * 255]\n },\n\n hue2rgb: (p, q, t) => {\n if (t < 0) t += 1;\n if (t > 1) t -= 1;\n if (t < 1 / 6) return p + (q - p) * 6 * t\n if (t < 1 / 2) return q\n if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6\n return p\n },\n\n rgbaColor: function (r, g, b, a) {\n\n r = IGVMath.clamp(r, 0, 255);\n g = IGVMath.clamp(g, 0, 255);\n b = IGVMath.clamp(b, 0, 255);\n a = IGVMath.clamp(a, 0.0, 1.0);\n\n return \"rgba(\" + r + \",\" + g + \",\" + b + \",\" + a + \")\"\n },\n\n rgbColor: function (r, g, b) {\n\n r = IGVMath.clamp(r, 0, 255);\n g = IGVMath.clamp(g, 0, 255);\n b = IGVMath.clamp(b, 0, 255);\n\n return \"rgb(\" + r + \",\" + g + \",\" + b + \")\"\n },\n\n greyScale: function (value) {\n\n var grey = IGVMath.clamp(value, 0, 255);\n\n return \"rgb(\" + grey + \",\" + grey + \",\" + grey + \")\"\n },\n\n randomGrey: function (min, max) {\n\n min = IGVMath.clamp(min, 0, 255);\n max = IGVMath.clamp(max, 0, 255);\n\n var g = Math.round(_random(min, max)).toString(10);\n\n return \"rgb(\" + g + \",\" + g + \",\" + g + \")\"\n },\n\n randomRGB: function (min, max) {\n\n min = IGVMath.clamp(min, 0, 255);\n max = IGVMath.clamp(max, 0, 255);\n\n var r = Math.round(_random(min, max)).toString(10);\n var g = Math.round(_random(min, max)).toString(10);\n var b = Math.round(_random(min, max)).toString(10);\n\n return \"rgb(\" + r + \",\" + g + \",\" + b + \")\"\n },\n\n randomRGBConstantAlpha: function (min, max, alpha) {\n\n min = IGVMath.clamp(min, 0, 255);\n max = IGVMath.clamp(max, 0, 255);\n\n var r = Math.round(_random(min, max)).toString(10);\n var g = Math.round(_random(min, max)).toString(10);\n var b = Math.round(_random(min, max)).toString(10);\n\n return \"rgba(\" + r + \",\" + g + \",\" + b + \",\" + alpha + \")\"\n },\n\n addAlpha: function (color, alpha) {\n\n if (color === \"0\" || color === \".\") {\n color = \"rgb(0,0,0)\";\n } else {\n const c = this.colorNameToHex(color);\n if (c) {\n color = c;\n }\n }\n\n var isHex = /(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(color);\n\n if (color.startsWith(\"rgba\")) {\n const idx = color.lastIndexOf(\",\");\n return color.substring(0, idx + 1) + alpha.toString() + \")\"\n }\n\n if (isHex) {\n color = IGVColor.hexToRgb(color);\n }\n\n if (color.startsWith(\"rgb\")) {\n return color.replace(\"rgb\", \"rgba\").replace(\")\", \", \" + alpha + \")\")\n } else {\n console.log(color + \" is not an rgb style string\");\n return color\n }\n },\n\n rgbComponents: function (color) {\n\n if (color === \"0\" || color === \".\") {\n return [0, 0, 0]\n }\n const isHex = /(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(color);\n if (isHex) {\n color = IGVColor.hexToRgb(color);\n } else {\n if (!color.startsWith(\"rgb\")) {\n const hex = this.colorNameToHex(color);\n color = this.hexToRgb(hex);\n }\n }\n\n if (color.startsWith(\"rgb(\")) {\n return color.substring(4, color.length - 1).split(\",\").map(s => Number.parseInt(s.trim()))\n } else if (color.startsWith(\"rgba(\")) {\n return color.substring(5, color.length - 1).split(\",\").map((s, i) => {\n s = s.trim();\n return i === 3 ? Number.parseFloat(s) : Number.parseInt(s)\n })\n } else {\n throw Error(\"Unrecognized color string: color\")\n }\n },\n\n /**\n *\n * @param dest RGB components as an array\n * @param src RGB components as an array\n * @param alpha alpha transparancy in the range 0-1\n * @returns {}\n */\n getCompositeColor: function (dest, src, alpha) {\n\n var r = Math.floor(alpha * src[0] + (1 - alpha) * dest[0]),\n g = Math.floor(alpha * src[1] + (1 - alpha) * dest[1]),\n b = Math.floor(alpha * src[2] + (1 - alpha) * dest[2]);\n\n return \"rgb(\" + r + \",\" + g + \",\" + b + \")\"\n\n },\n\n /**\n * Return a color represented by the string. If the string is not a recognized color format return the\n * string itself. This function exists for backward compatibility, createColorStringSafe is preferredz\n * @param str\n */\n createColorString: function (str) {\n // Excel will quote color strings, strip all quotes\n const color = this.createColorStringSafe(str);\n return color ? color : str\n },\n\n /**\n * If str is a recognized color format return a string encoding the color\n * @param str\n */\n createColorStringSafe: function (str) {\n // Excel will quote color strings, strip all quotes\n str = stripQuotes$1(str);\n\n if (str.startsWith('rgb(') && str.endsWith(')')) {\n return str\n }\n if (str.startsWith('#') && str.length < 8) {\n return str\n }\n\n // See if string is a recognized web color\n const hex = this.colorNameToHex(str);\n if (hex) {\n return hex\n }\n\n // UCSC format (e.g. 0,0,255)\n const tokens = str.split(\",\");\n if (tokens.length === 3 && isColorComponent(tokens[0]) && isColorComponent(tokens[1]) && isColorComponent(tokens[2])) {\n return `rgb(${str})`\n }\n },\n\n darkenLighten: function (color, amt) {\n\n let src;\n let hexColor = this.colorNameToHex(color);\n if (hexColor) {\n src = IGVColor.hexToRgb(hexColor);\n } else {\n src = color.startsWith('rgb(') ? color : IGVColor.hexToRgb(color);\n }\n\n const components = src.replace(\")\", \"\").substring(4).split(\",\");\n\n const r = Math.max(0, Math.min(255, Number.parseInt(components[0].trim()) + amt));\n const g = Math.max(0, Math.min(255, Number.parseInt(components[1].trim()) + amt));\n const b = Math.max(0, Math.min(255, Number.parseInt(components[2].trim()) + amt));\n\n return 'rgb(' + r.toString() + ',' + g.toString() + ',' + b.toString() + ')'\n\n },\n\n /**\n * Convert html/css color name to hex value. Adapted from https://gist.github.com/mxfh/4719348\n * @param colorName\n * @returns {*}\n */\n colorNameToHex: function (colorName) { // color list from http://stackoverflow.com/q/1573053/731179 with added gray/gray\n const definedColorNames = {\n \"aliceblue\": \"#f0f8ff\",\n \"antiquewhite\": \"#faebd7\",\n \"aqua\": \"#00ffff\",\n \"aquamarine\": \"#7fffd4\",\n \"azure\": \"#f0ffff\",\n \"beige\": \"#f5f5dc\",\n \"bisque\": \"#ffe4c4\",\n \"black\": \"#000000\",\n \"blanchedalmond\": \"#ffebcd\",\n \"blue\": \"#0000ff\",\n \"blueviolet\": \"#8a2be2\",\n \"brown\": \"#a52a2a\",\n \"burlywood\": \"#deb887\",\n \"cadetblue\": \"#5f9ea0\",\n \"chartreuse\": \"#7fff00\",\n \"chocolate\": \"#d2691e\",\n \"coral\": \"#ff7f50\",\n \"cornflowerblue\": \"#6495ed\",\n \"cornsilk\": \"#fff8dc\",\n \"crimson\": \"#dc143c\",\n \"cyan\": \"#00ffff\",\n \"darkblue\": \"#00008b\",\n \"darkcyan\": \"#008b8b\",\n \"darkgoldenrod\": \"#b8860b\",\n \"darkgray\": \"#a9a9a9\",\n \"darkgreen\": \"#006400\",\n \"darkkhaki\": \"#bdb76b\",\n \"darkmagenta\": \"#8b008b\",\n \"darkolivegreen\": \"#556b2f\",\n \"darkorange\": \"#ff8c00\",\n \"darkorchid\": \"#9932cc\",\n \"darkred\": \"#8b0000\",\n \"darksalmon\": \"#e9967a\",\n \"darkseagreen\": \"#8fbc8f\",\n \"darkslateblue\": \"#483d8b\",\n \"darkslategray\": \"#2f4f4f\",\n \"darkturquoise\": \"#00ced1\",\n \"darkviolet\": \"#9400d3\",\n \"deeppink\": \"#ff1493\",\n \"deepskyblue\": \"#00bfff\",\n \"dimgray\": \"#696969\",\n \"dodgerblue\": \"#1e90ff\",\n \"firebrick\": \"#b22222\",\n \"floralwhite\": \"#fffaf0\",\n \"forestgreen\": \"#228b22\",\n \"fuchsia\": \"#ff00ff\",\n \"gainsboro\": \"#dcdcdc\",\n \"ghostwhite\": \"#f8f8ff\",\n \"gold\": \"#ffd700\",\n \"goldenrod\": \"#daa520\",\n \"gray\": \"#808080\",\n \"green\": \"#008000\",\n \"greenyellow\": \"#adff2f\",\n \"honeydew\": \"#f0fff0\",\n \"hotpink\": \"#ff69b4\",\n \"indianred \": \"#cd5c5c\",\n \"indigo \": \"#4b0082\",\n \"ivory\": \"#fffff0\",\n \"khaki\": \"#f0e68c\",\n \"lavender\": \"#e6e6fa\",\n \"lavenderblush\": \"#fff0f5\",\n \"lawngreen\": \"#7cfc00\",\n \"lemonchiffon\": \"#fffacd\",\n \"lightblue\": \"#add8e6\",\n \"lightcoral\": \"#f08080\",\n \"lightcyan\": \"#e0ffff\",\n \"lightgoldenrodyellow\": \"#fafad2\",\n \"lightgrey\": \"#d3d3d3\",\n \"lightgreen\": \"#90ee90\",\n \"lightpink\": \"#ffb6c1\",\n \"lightsalmon\": \"#ffa07a\",\n \"lightseagreen\": \"#20b2aa\",\n \"lightskyblue\": \"#87cefa\",\n \"lightslategray\": \"#778899\",\n \"lightsteelblue\": \"#b0c4de\",\n \"lightyellow\": \"#ffffe0\",\n \"lime\": \"#00ff00\",\n \"limegreen\": \"#32cd32\",\n \"linen\": \"#faf0e6\",\n \"magenta\": \"#ff00ff\",\n \"maroon\": \"#800000\",\n \"mediumaquamarine\": \"#66cdaa\",\n \"mediumblue\": \"#0000cd\",\n \"mediumorchid\": \"#ba55d3\",\n \"mediumpurple\": \"#9370d8\",\n \"mediumseagreen\": \"#3cb371\",\n \"mediumslateblue\": \"#7b68ee\",\n \"mediumspringgreen\": \"#00fa9a\",\n \"mediumturquoise\": \"#48d1cc\",\n \"mediumvioletred\": \"#c71585\",\n \"midnightblue\": \"#191970\",\n \"mintcream\": \"#f5fffa\",\n \"mistyrose\": \"#ffe4e1\",\n \"moccasin\": \"#ffe4b5\",\n \"navajowhite\": \"#ffdead\",\n \"navy\": \"#000080\",\n \"oldlace\": \"#fdf5e6\",\n \"olive\": \"#808000\",\n \"olivedrab\": \"#6b8e23\",\n \"orange\": \"#ffa500\",\n \"orangered\": \"#ff4500\",\n \"orchid\": \"#da70d6\",\n \"palegoldenrod\": \"#eee8aa\",\n \"palegreen\": \"#98fb98\",\n \"paleturquoise\": \"#afeeee\",\n \"palevioletred\": \"#d87093\",\n \"papayawhip\": \"#ffefd5\",\n \"peachpuff\": \"#ffdab9\",\n \"peru\": \"#cd853f\",\n \"pink\": \"#ffc0cb\",\n \"plum\": \"#dda0dd\",\n \"powderblue\": \"#b0e0e6\",\n \"purple\": \"#800080\",\n \"red\": \"#ff0000\",\n \"rosybrown\": \"#bc8f8f\",\n \"royalblue\": \"#4169e1\",\n \"saddlebrown\": \"#8b4513\",\n \"salmon\": \"#fa8072\",\n \"sandybrown\": \"#f4a460\",\n \"seagreen\": \"#2e8b57\",\n \"seashell\": \"#fff5ee\",\n \"sienna\": \"#a0522d\",\n \"silver\": \"#c0c0c0\",\n \"skyblue\": \"#87ceeb\",\n \"slateblue\": \"#6a5acd\",\n \"slategray\": \"#708090\",\n \"snow\": \"#fffafa\",\n \"springgreen\": \"#00ff7f\",\n \"steelblue\": \"#4682b4\",\n \"tan\": \"#d2b48c\",\n \"teal\": \"#008080\",\n \"thistle\": \"#d8bfd8\",\n \"tomato\": \"#ff6347\",\n \"turquoise\": \"#40e0d0\",\n \"violet\": \"#ee82ee\",\n \"wheat\": \"#f5deb3\",\n \"white\": \"#ffffff\",\n \"whitesmoke\": \"#f5f5f5\",\n \"yellow\": \"#ffff00\",\n \"yellowgreen\": \"#9acd32\",\n \"darkgrey\": \"#a9a9a9\",\n \"darkslategrey\": \"#2f4f4f\",\n \"dimgrey\": \"#696969\",\n \"grey\": \"#808080\",\n \"lightgray\": \"#d3d3d3\",\n \"lightslategrey\": \"#778899\",\n \"slategrey\": \"#708090\"\n };\n return definedColorNames[colorName]\n }\n};\n\nfunction isColorComponent(str) {\n const num = Number.parseInt(str);\n return !Number.isNaN(num) && num >= 0 && num <= 255\n}\n\n// Support for oauth token based authorization\n// This class supports explicit setting of an oauth token either globally or for specific hosts.\n//\n// The variable oauth.google.access_token, which becomes igv.oauth.google.access_token on ES5 conversion is\n// supported for backward compatibility\n\nconst DEFAULT_HOST = \"googleapis\";\n\nclass Oauth {\n\n constructor() {\n this.oauthTokens = {};\n }\n\n\n setToken(token, host) {\n host = host || DEFAULT_HOST;\n this.oauthTokens[host] = token;\n }\n\n getToken(host) {\n host = host || DEFAULT_HOST;\n let token;\n for (let key of Object.keys(this.oauthTokens)) {\n const regex = wildcardToRegExp(key);\n if (regex.test(host)) {\n token = this.oauthTokens[key];\n break\n }\n }\n return token\n }\n\n removeToken(host) {\n host = host || DEFAULT_HOST;\n for (let key of Object.keys(this.oauthTokens)) {\n const regex = wildcardToRegExp(key);\n if (regex.test(host)) {\n this.oauthTokens[key] = undefined;\n }\n }\n }\n\n // Special object for google -- legacy support\n // google: {\n // setToken: function (token) {\n // oauth.setToken(token);\n // }\n // }\n}\n\n\n/**\n * Creates a RegExp from the given string, converting asterisks to .* expressions,\n * and escaping all other characters.\n *\n * credit https://gist.github.com/donmccurdy/6d073ce2c6f3951312dfa45da14a420f\n */\nfunction wildcardToRegExp(s) {\n return new RegExp('^' + s.split(/\\*+/).map(regExpEscape).join('.*') + '$')\n}\n\n/**\n * RegExp-escapes all characters in the given string.\n *\n * credit https://gist.github.com/donmccurdy/6d073ce2c6f3951312dfa45da14a420f\n */\nfunction regExpEscape(s) {\n return s.replace(/[|\\\\{}()[\\]^$+*?.]/g, '\\\\$&')\n}\n\nfunction isGoogleURL(url) {\n return (url.includes(\"googleapis\") && !url.includes(\"urlshortener\")) ||\n isGoogleStorageURL(url) ||\n isGoogleDriveURL(url)\n}\n\nfunction isGoogleStorageURL(url) {\n return url.startsWith(\"gs://\") ||\n url.startsWith(\"https://www.googleapis.com/storage\") ||\n url.startsWith(\"https://storage.cloud.google.com\") ||\n url.startsWith(\"https://storage.googleapis.com\");\n}\n\nfunction isGoogleDriveURL(url) {\n return url.indexOf(\"drive.google.com\") >= 0 || url.indexOf(\"www.googleapis.com/drive\") > 0\n}\n\n/**\n * Translate gs:// urls to https\n * See https://cloud.google.com/storage/docs/json_api/v1\n * @param gsUrl\n * @returns {string|*}\n */\nfunction translateGoogleCloudURL(gsUrl) {\n\n let {bucket, object} = parseBucketName(gsUrl);\n object = encode(object);\n\n const qIdx = gsUrl.indexOf('?');\n const paramString = (qIdx > 0) ? gsUrl.substring(qIdx) + \"&alt=media\" : \"?alt=media\";\n\n return `https://storage.googleapis.com/storage/v1/b/${bucket}/o/${object}${paramString}`\n}\n\n/**\n * Parse a google bucket and object name from a google storage URL. Known forms include\n *\n * gs://BUCKET_NAME/OBJECT_NAME\n * https://storage.googleapis.com/BUCKET_NAME/OBJECT_NAME\n * https://storage.googleapis.com/storage/v1/b/BUCKET_NAME/o/OBJECT_NAME\n * https://www.googleapis.com/storage/v1/b/BUCKET_NAME/o/OBJECT_NAME\"\n * https://storage.googleapis.com/download/storage/v1/b/BUCKET_NAME/o/OBJECT_NAME\n *\n * @param url\n */\nfunction parseBucketName(url) {\n\n let bucket;\n let object;\n\n if (url.startsWith(\"gs://\")) {\n const i = url.indexOf('/', 5);\n if (i >= 0) {\n bucket = url.substring(5, i);\n const qIdx = url.indexOf('?');\n object = (qIdx < 0) ? url.substring(i + 1) : url.substring(i + 1, qIdx);\n }\n\n } else if (url.startsWith(\"https://storage.googleapis.com\") || url.startsWith(\"https://storage.cloud.google.com\")) {\n const bucketIdx = url.indexOf(\"/v1/b/\", 8);\n if (bucketIdx > 0) {\n const objIdx = url.indexOf(\"/o/\", bucketIdx);\n if (objIdx > 0) {\n const queryIdx = url.indexOf(\"?\", objIdx);\n bucket = url.substring(bucketIdx + 6, objIdx);\n object = queryIdx > 0 ? url.substring(objIdx + 3, queryIdx) : url.substring(objIdx + 3);\n }\n\n } else {\n const idx1 = url.indexOf(\"/\", 8);\n const idx2 = url.indexOf(\"/\", idx1+1);\n const idx3 = url.indexOf(\"?\", idx2);\n if (idx2 > 0) {\n bucket = url.substring(idx1+1, idx2);\n object = idx3 < 0 ? url.substring(idx2+1) : url.substring(idx2+1, idx3);\n }\n }\n\n } else if (url.startsWith(\"https://www.googleapis.com/storage/v1/b\")) {\n const bucketIdx = url.indexOf(\"/v1/b/\", 8);\n const objIdx = url.indexOf(\"/o/\", bucketIdx);\n if (objIdx > 0) {\n const queryIdx = url.indexOf(\"?\", objIdx);\n bucket = url.substring(bucketIdx + 6, objIdx);\n object = queryIdx > 0 ? url.substring(objIdx + 3, queryIdx) : url.substring(objIdx + 3);\n }\n }\n\n if (bucket && object) {\n return {\n bucket, object\n }\n } else {\n throw Error(`Unrecognized Google Storage URI: ${url}`)\n }\n\n}\n\n/**\n * Percent a GCS object name. See https://cloud.google.com/storage/docs/request-endpoints\n * Specific characters to encode:\n * !, #, $, &, ', (, ), *, +, ,, /, :, ;, =, ?, @, [, ], and space characters.\n * @param obj\n */\n\nfunction encode(objectName) {\n\n let result = '';\n objectName.split('').forEach(function(letter) {\n if(encodings$1.has(letter)) {\n result += encodings$1.get(letter);\n } else {\n result += letter;\n }\n });\n return result;\n}\n\n//\t%23\t%24\t%25\t%26\t%27\t%28\t%29\t%2A\t%2B\t%2C\t%2F\t%3A\t%3B\t%3D\t%3F\t%40\t%5B\t%5D\nconst encodings$1 = new Map();\nencodings$1.set(\"!\", \"%21\");\nencodings$1.set(\"#\", \"%23\");\nencodings$1.set(\"$\", \"%24\");\nencodings$1.set(\"%\", \"%25\");\nencodings$1.set(\"&\", \"%26\");\nencodings$1.set(\"'\", \"%27\");\nencodings$1.set(\"(\", \"%28\");\nencodings$1.set(\")\", \"%29\");\nencodings$1.set(\"*\", \"%2A\");\nencodings$1.set(\"+\", \"%2B\");\nencodings$1.set(\",\", \"%2C\");\nencodings$1.set(\"/\", \"%2F\");\nencodings$1.set(\":\", \"%3A\");\nencodings$1.set(\";\", \"%3B\");\nencodings$1.set(\"=\", \"%3D\");\nencodings$1.set(\"?\", \"%3F\");\nencodings$1.set(\"@\", \"%40\");\nencodings$1.set(\"[\", \"%5B\");\nencodings$1.set(\"]\", \"%5D\");\nencodings$1.set(\" \", \"%20\");\n\n// Convenience functions for the gapi oAuth library.\n\nasync function init$1(config) {\n\n if (!(google.accounts.oauth2.initTokenClient)) {\n throw new Error(\"Google accounts token client not loaded (https://accounts.google.com/gsi/client)\")\n }\n\n if (isInitialized()) {\n throw new Error(\"Google client is already initialized\")\n }\n\n // Note: callback is added when accessToken is requested\n const codeClientConfig = {\n client_id: config.client_id || config.clientId,\n scope: config.scope || 'https://www.googleapis.com/auth/userinfo.profile',\n state: config.state || 'igv',\n error: (err) => {\n throw new Error(err.type)\n },\n hint: config.hint, // Optional\n hosted_domain: config.hosted_domain // Optional\n };\n\n const tokenClient = google.accounts.oauth2.initTokenClient(codeClientConfig);\n\n // Attach an object to keep igv state\n google.igv = {\n tokenClient: tokenClient,\n apiKey: config.apiKey\n };\n}\n\nfunction isInitialized() {\n return window.google && window.google.igv\n}\n\n/**\n * Return the current access token if the user is signed in, or undefined otherwise. This function does not\n * attempt a signIn or request any specfic scopes.\n *\n * @returns access_token || undefined\n */\nfunction getCurrentAccessToken() {\n return (isInitialized() && google.igv.tokenResponse && Date.now() < google.igv.tokenExpiresAt) ?\n google.igv.tokenResponse.access_token :\n undefined\n}\n\n\n/**\n * Return a promise for an access token for the given scope. If the user hasn't authorized the scope request it\n *\n * @param scope\n * @returns {Promise}\n */\nasync function getAccessToken(scope) {\n\n if (!isInitialized()) {\n throw Error(\"Google oAuth has not been initialized\")\n }\n\n if (google.igv.tokenResponse &&\n Date.now() < google.igv.tokenExpiresAt &&\n google.accounts.oauth2.hasGrantedAllScopes(google.igv.tokenResponse, scope)) {\n return google.igv.tokenResponse.access_token\n } else {\n const tokenClient = google.igv.tokenClient;\n return new Promise((resolve, reject) => {\n try {\n // Settle this promise in the response callback for requestAccessToken()\n tokenClient.callback = (tokenResponse) => {\n if (tokenResponse.error !== undefined) {\n reject(tokenResponse);\n }\n google.igv.tokenResponse = tokenResponse;\n google.igv.tokenExpiresAt = Date.now() + tokenResponse.expires_in * 1000;\n resolve(tokenResponse.access_token);\n };\n tokenClient.requestAccessToken({scope});\n } catch (err) {\n console.log(err);\n }\n })\n }\n}\n\n// gapi.auth2.getAuthInstance().isSignedIn.listen(status => {\n// const user = gapi.auth2.getAuthInstance().currentUser.get()\n// queryGoogleAuthenticationStatus(user, status)\n// })\n\nfunction getScopeForURL(url) {\n if (isGoogleDriveURL(url)) {\n return \"https://www.googleapis.com/auth/drive.file\"\n } else if (isGoogleStorageURL(url)) {\n return \"https://www.googleapis.com/auth/devstorage.read_only\"\n } else {\n return 'https://www.googleapis.com/auth/userinfo.profile'\n }\n}\n\nfunction getApiKey() {\n return google.igv.apiKey\n}\n\n/**\n * Return information about a specific google drive URL\n *\n * @param googleDriveURL\n * @returns {Promise}\n */\nasync function getDriveFileInfo(googleDriveURL) {\n\n const id = getGoogleDriveFileID(googleDriveURL);\n let endPoint = \"https://www.googleapis.com/drive/v3/files/\" + id + \"?supportsTeamDrives=true\";\n const apiKey = getApiKey();\n if (apiKey) {\n endPoint += \"&key=\" + apiKey;\n }\n const response = await fetch(endPoint);\n let json = await response.json();\n if (json.error && json.error.code === 404) {\n let scope = \"https://www.googleapis.com/auth/drive.readonly\";\n const access_token = await getAccessToken(scope);\n if (access_token) {\n const response = await fetch(endPoint, {\n headers: {\n 'Authorization': `Bearer ${access_token}`\n }\n });\n json = await response.json();\n if (json.error) {\n throw Error(json.error);\n }\n } else {\n throw Error(json.error);\n }\n }\n return json;\n}\n\n\nfunction getDriveDownloadURL(link) {\n // Return a google drive download url for the sharable link\n //https://drive.google.com/open?id=0B-lleX9c2pZFbDJ4VVRxakJzVGM\n //https://drive.google.com/file/d/1_FC4kCeO8E3V4dJ1yIW7A0sn1yURKIX-/view?usp=sharing\n var id = getGoogleDriveFileID(link);\n return id ? \"https://www.googleapis.com/drive/v3/files/\" + id + \"?alt=media&supportsTeamDrives=true\" : link;\n}\n\nfunction getGoogleDriveFileID(link) {\n\n //https://drive.google.com/file/d/1_FC4kCeO8E3V4dJ1yIW7A0sn1yURKIX-/view?usp=sharing\n //https://www.googleapis.com/drive/v3/files/1w-tvo6p1SH4p1OaQSVxpkV_EJgGIstWF?alt=media&supportsTeamDrives=true\"\n\n if (link.includes(\"/open?id=\")) {\n const i1 = link.indexOf(\"/open?id=\") + 9;\n const i2 = link.indexOf(\"&\");\n if (i1 > 0 && i2 > i1) {\n return link.substring(i1, i2)\n } else if (i1 > 0) {\n return link.substring(i1);\n }\n\n } else if (link.includes(\"/file/d/\")) {\n const i1 = link.indexOf(\"/file/d/\") + 8;\n const i2 = link.lastIndexOf(\"/\");\n return link.substring(i1, i2);\n\n } else if (link.startsWith(\"https://www.googleapis.com/drive\")) {\n let i1 = link.indexOf(\"/files/\");\n const i2 = link.indexOf(\"?\");\n if (i1 > 0) {\n i1 += 7;\n return i2 > 0 ?\n link.substring(i1, i2) :\n link.substring(i1)\n }\n }\n\n throw Error(\"Unknown Google Drive url format: \" + link);\n\n\n}\n\n// The MIT License (MIT)\n\n/**\n * @constructor\n * @param {Object} options A set op options to pass to the throttle function\n * @param {number} requestsPerSecond The amount of requests per second\n * the library will limit to\n */\nclass Throttle {\n constructor(options) {\n this.requestsPerSecond = options.requestsPerSecond || 10;\n this.lastStartTime = 0;\n this.queued = [];\n }\n\n /**\n * Adds a promise\n * @param {Function} async function to be executed\n * @param {Object} options A set of options.\n * @return {Promise} A promise\n */\n add(asyncFunction, options) {\n\n var self = this;\n return new Promise(function (resolve, reject) {\n self.queued.push({\n resolve: resolve,\n reject: reject,\n asyncFunction: asyncFunction,\n });\n self.dequeue();\n });\n }\n\n /**\n * Adds all the promises passed as parameters\n * @param {Function} promises An array of functions that return a promise\n * @param {Object} options A set of options.\n * @param {number} options.signal An AbortSignal object that can be used to abort the returned promise\n * @param {number} options.weight A \"weight\" of each operation resolving by array of promises\n * @return {Promise} A promise that succeeds when all the promises passed as options do\n */\n addAll(promises, options) {\n var addedPromises = promises.map(function (promise) {\n return this.add(promise, options);\n }.bind(this));\n\n return Promise.all(addedPromises);\n };\n\n /**\n * Dequeues a promise\n * @return {void}\n */\n dequeue() {\n if (this.queued.length > 0) {\n var now = new Date(),\n inc = (1000 / this.requestsPerSecond) + 1,\n elapsed = now - this.lastStartTime;\n\n if (elapsed >= inc) {\n this._execute();\n } else {\n // we have reached the limit, schedule a dequeue operation\n setTimeout(function () {\n this.dequeue();\n }.bind(this), inc - elapsed);\n }\n }\n }\n\n /**\n * Executes the promise\n * @private\n * @return {void}\n */\n async _execute() {\n this.lastStartTime = new Date();\n var candidate = this.queued.shift();\n const f = candidate.asyncFunction;\n try {\n const r = await f();\n candidate.resolve(r);\n } catch (e) {\n candidate.reject(e);\n }\n\n }\n\n\n}\n\n/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2014 Broad Institute\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\nclass IGVXhr {\n\n constructor() {\n this.apiKey = undefined;\n this.googleThrottle = new Throttle({\n requestsPerSecond: 8\n });\n this.RANGE_WARNING_GIVEN = false;\n this.oauth = new Oauth();\n }\n\n setApiKey(key) {\n this.apiKey = key;\n }\n\n async loadArrayBuffer(url, options) {\n options = options || {};\n if (!options.responseType) {\n options.responseType = \"arraybuffer\";\n }\n if (isFile(url)) {\n return this._loadFileSlice(url, options)\n } else {\n return this.load(url, options)\n }\n }\n\n /**\n * A wrapper around loadArrayBuffer that inflates gzipped data\n * @param url\n * @param options\n * @returns {Promise}\n */\n async loadByteArray(url, options) {\n const arraybuffer = await this.loadArrayBuffer(url, options);\n let plain;\n if (isgzipped(arraybuffer)) {\n plain = ungzip_blocks(arraybuffer);\n } else {\n plain = new Uint8Array(arraybuffer);\n }\n return plain\n }\n\n\n async loadJson(url, options) {\n options = options || {};\n const method = options.method || (options.sendData ? \"POST\" : \"GET\");\n if (method === \"POST\") {\n options.contentType = \"application/json\";\n }\n const result = await this.loadString(url, options);\n if (result) {\n return JSON.parse(result)\n } else {\n return result\n }\n }\n\n async loadString(path, options) {\n options = options || {};\n if (path instanceof File) {\n return this._loadStringFromFile(path, options)\n } else {\n return this._loadStringFromUrl(path, options)\n }\n }\n\n async load(url, options) {\n\n options = options || {};\n const urlType = typeof url;\n\n // Resolve functions, promises, and functions that return promises\n url = await (typeof url === 'function' ? url() : url);\n\n if (isFile(url)) {\n return this._loadFileSlice(url, options)\n } else if (typeof url.startsWith === 'function') { // Test for string\n if (url.startsWith(\"data:\")) {\n const buffer = decodeDataURI$1(url).buffer;\n if (options.range) {\n const rangeEnd = options.range.size ? options.range.start + options.range.size : buffer.byteLength;\n return buffer.slice(options.range.start, rangeEnd)\n } else {\n return buffer\n }\n } else {\n if (url.startsWith(\"https://drive.google.com\")) {\n url = getDriveDownloadURL(url);\n }\n if (isGoogleDriveURL(url) || url.startsWith(\"https://www.dropbox.com\")) {\n return this.googleThrottle.add(async () => {\n return this._loadURL(url, options)\n })\n } else {\n return this._loadURL(url, options)\n }\n }\n } else {\n throw Error(`url must be either a 'File', 'string', 'function', or 'Promise'. Actual type: ${urlType}`)\n }\n }\n\n async _loadURL(url, options) {\n\n const self = this;\n const _url = url; // The unmodified URL, needed in case of an oAuth retry\n\n url = mapUrl$1(url);\n\n options = options || {};\n\n let oauthToken = options.oauthToken || this.getOauthToken(url);\n if (oauthToken) {\n oauthToken = await (typeof oauthToken === 'function' ? oauthToken() : oauthToken);\n }\n\n return new Promise(function (resolve, reject) {\n\n // Various Google tansformations\n if (isGoogleURL(url) && !isGoogleStorageSigned(url)) {\n if (isGoogleStorageURL(url)) {\n url = translateGoogleCloudURL(url);\n }\n url = addApiKey(url);\n\n if (isGoogleDriveURL(url)) {\n addTeamDrive(url);\n }\n\n // If we have an access token try it, but don't force a signIn or request for scopes yet\n if (!oauthToken) {\n oauthToken = getCurrentGoogleAccessToken();\n }\n }\n\n const headers = options.headers || {};\n if (oauthToken) {\n addOauthHeaders(headers, oauthToken);\n }\n const range = options.range;\n\n\n const xhr = new XMLHttpRequest();\n const sendData = options.sendData || options.body;\n const method = options.method || (sendData ? \"POST\" : \"GET\");\n const responseType = options.responseType;\n const contentType = options.contentType;\n const mimeType = options.mimeType;\n\n xhr.open(method, url);\n\n if (options.timeout) {\n xhr.timeout = options.timeout;\n }\n\n if (range) {\n let rangeEnd = \"\";\n if (range.size) {\n rangeEnd = range.start + range.size - 1;\n }\n xhr.setRequestHeader(\"Range\", \"bytes=\" + range.start + \"-\" + rangeEnd);\n // xhr.setRequestHeader(\"Cache-Control\", \"no-cache\"); <= This can cause CORS issues, disabled for now\n }\n if (contentType) {\n xhr.setRequestHeader(\"Content-Type\", contentType);\n }\n if (mimeType) {\n xhr.overrideMimeType(mimeType);\n }\n if (responseType) {\n xhr.responseType = responseType;\n }\n if (headers) {\n for (let key of Object.keys(headers)) {\n const value = headers[key];\n xhr.setRequestHeader(key, value);\n }\n }\n\n // NOTE: using withCredentials with servers that return \"*\" for access-allowed-origin will fail\n if (options.withCredentials === true) {\n xhr.withCredentials = true;\n }\n\n xhr.onload = async function (event) {\n\n // when the url points to a local file, the status is 0\n if (xhr.status === 0 || (xhr.status >= 200 && xhr.status <= 300)) {\n if (\"HEAD\" === options.method) {\n // Support fetching specific headers. Attempting to fetch all headers can be problematic with CORS\n const headers = options.requestedHeaders || ['content-length'];\n const headerMap = {};\n for (let h of headers) {\n headerMap[h] = xhr.getResponseHeader(h);\n }\n resolve(headerMap);\n } else {\n // Assume \"GET\" or \"POST\"\n if (range && xhr.status !== 206 && range.start !== 0) {\n\n // For small files a range starting at 0 can return the whole file => 200\n // Provide just the slice we asked for, throw out the rest quietly\n // If file is large warn user\n if (xhr.response.length > 100000 && !self.RANGE_WARNING_GIVEN) {\n alert(`Warning: Range header ignored for URL: ${url}. This can have severe performance impacts.`);\n }\n resolve(xhr.response.slice(range.start, range.start + range.size));\n } else {\n resolve(xhr.response);\n }\n }\n } else if (xhr.status === 416) {\n handleError(Error(`416 Unsatisfiable Range`));\n } else if (isInitialized() &&\n ((xhr.status === 404 || xhr.status === 401 || xhr.status === 403) &&\n isGoogleURL(url)) &&\n !options.retries) {\n tryGoogleAuth();\n\n } else {\n if (xhr.status === 403) {\n handleError(\"Access forbidden: \" + url);\n } else {\n handleError(xhr.status);\n }\n }\n };\n\n\n xhr.onerror = function (event) {\n if (isGoogleURL(url) && !options.retries) {\n tryGoogleAuth();\n } else {\n handleError(\"Error accessing resource: \" + url + \" Status: \" + xhr.status);\n }\n };\n\n xhr.ontimeout = function (event) {\n handleError(\"Timed out\");\n };\n\n xhr.onabort = function (event) {\n console.log(\"Aborted\");\n reject(event);\n };\n\n try {\n xhr.send(sendData);\n } catch (e) {\n if (isGoogleURL(url) && !options.retries) {\n tryGoogleAuth();\n } else {\n handleError(e);\n }\n }\n\n\n function handleError(error) {\n if (reject) {\n reject(error);\n } else {\n throw error\n }\n }\n\n async function tryGoogleAuth() {\n try {\n const accessToken = await fetchGoogleAccessToken(_url);\n options.retries = 1;\n options.oauthToken = accessToken;\n const response = await self.load(_url, options);\n resolve(response);\n } catch (e) {\n if (e.error) {\n const msg = e.error.startsWith(\"popup_blocked\") ?\n \"Google login popup blocked by browser.\" :\n e.error;\n alert(msg);\n } else {\n handleError(e);\n }\n }\n }\n })\n\n }\n\n async _loadFileSlice(localfile, options) {\n\n let blob = (options && options.range) ?\n localfile.slice(options.range.start, options.range.start + options.range.size) :\n localfile;\n\n const arrayBuffer = await blob.arrayBuffer();\n\n if (\"arraybuffer\" === options.responseType) {\n return arrayBuffer\n } else {\n return arrayBufferToString(arrayBuffer)\n }\n }\n\n async _loadStringFromFile(localfile, options) {\n\n const blob = options.range ? localfile.slice(options.range.start, options.range.start + options.range.size) : localfile;\n const arrayBuffer = await blob.arrayBuffer();\n return arrayBufferToString(arrayBuffer)\n }\n\n async _loadStringFromUrl(url, options) {\n\n options = options || {};\n options.responseType = \"arraybuffer\";\n const data = await this.load(url, options);\n return arrayBufferToString(data)\n }\n\n /**\n * Explicity set an oAuth token for use with given host. If host is undefined token is used for google api access*\n * @param token\n * @param host\n */\n setOauthToken(token, host) {\n this.oauth.setToken(token, host);\n }\n\n /**\n * Return an oauth token for the URL if we have one. This method does not force sign-in, and the token may\n * or may not be valid. Sign-in is triggered on request failure.\n * *\n * @param url\n * @returns {*}\n */\n getOauthToken(url) {\n\n // Google is the default provider, don't try to parse host for google URLs\n const host = isGoogleURL(url) ?\n undefined :\n parseUri(url).host;\n\n // First check the explicit settings (i.e. token set through the API)\n let token = this.oauth.getToken(host);\n if (token) {\n return token\n } else if (host === undefined) {\n // Now try Google oauth tokens previously obtained. This will return undefined if google oauth is not\n // configured.\n const googleToken = getCurrentGoogleAccessToken();\n if (googleToken && googleToken.expires_at > Date.now()) {\n return googleToken.access_token\n }\n }\n }\n\n /**\n * This method should only be called when it is known the server supports HEAD requests. It is used to recover\n * from 416 errors from out-of-spec WRT range request servers. Notably Globus.\n * * *\n * @param url\n * @param options\n * @returns {Promise}\n */\n async getContentLength(url, options) {\n options = options || {};\n options.method = 'HEAD';\n options.requestedHeaders = ['content-length'];\n const headerMap = await this._loadURL(url, options);\n const contentLengthString = headerMap['content-length'];\n return contentLengthString ? Number.parseInt(contentLengthString) : 0\n }\n\n}\n\nfunction isGoogleStorageSigned(url) {\n return url.indexOf(\"X-Goog-Signature\") > -1\n}\n\n\n/**\n * Return a Google oAuth token, triggering a sign in if required. This method should not be called until we know\n * a token is required, that is until we've tried the url and received a 401, 403, or 404.\n *\n * @param url\n * @returns the oauth token\n */\nasync function fetchGoogleAccessToken(url) {\n if (isInitialized()) {\n const scope = getScopeForURL(url);\n const access_token = await getAccessToken(scope);\n return access_token\n } else {\n throw Error(\n `Authorization is required, but Google oAuth has not been initalized. Contact your site administrator for assistance.`)\n }\n}\n\n/**\n * Return the current google access token, if one exists. Do not triger signOn or request additional scopes.\n * @returns {undefined|access_token}\n */\nfunction getCurrentGoogleAccessToken() {\n if (isInitialized()) {\n const access_token = getCurrentAccessToken();\n return access_token\n } else {\n return undefined\n }\n}\n\nfunction addOauthHeaders(headers, acToken) {\n if (acToken) {\n headers[\"Cache-Control\"] = \"no-cache\";\n headers[\"Authorization\"] = \"Bearer \" + acToken;\n }\n return headers\n}\n\n\nfunction addApiKey(url) {\n let apiKey = igvxhr.apiKey;\n if (!apiKey && typeof gapi !== \"undefined\") {\n apiKey = gapi.apiKey;\n }\n if (apiKey !== undefined && !url.includes(\"key=\")) {\n const paramSeparator = url.includes(\"?\") ? \"&\" : \"?\";\n url = url + paramSeparator + \"key=\" + apiKey;\n }\n return url\n}\n\nfunction addTeamDrive(url) {\n if (url.includes(\"supportsTeamDrive\")) {\n return url\n } else {\n const paramSeparator = url.includes(\"?\") ? \"&\" : \"?\";\n url = url + paramSeparator + \"supportsTeamDrive=true\";\n }\n}\n\n/**\n * Perform some well-known url mappings.\n * @param url\n */\nfunction mapUrl$1(url) {\n\n if (url.startsWith(\"https://www.dropbox.com\")) {\n return url.replace(\"//www.dropbox.com\", \"//dl.dropboxusercontent.com\")\n } else if (url.startsWith(\"https://drive.google.com\")) {\n return getDriveDownloadURL(url)\n } else if (url.includes(\"//www.broadinstitute.org/igvdata\")) {\n return url.replace(\"//www.broadinstitute.org/igvdata\", \"//data.broadinstitute.org/igvdata\")\n } else if (url.includes(\"//igvdata.broadinstitute.org\")) {\n return url.replace(\"//igvdata.broadinstitute.org\", \"//s3.amazonaws.com/igv.broadinstitute.org\")\n } else if (url.includes(\"//igv.genepattern.org\")) {\n return url.replace(\"//igv.genepattern.org\", \"//igv-genepattern-org.s3.amazonaws.com\")\n } else if (url.startsWith(\"ftp://ftp.ncbi.nlm.nih.gov/geo\")) {\n return url.replace(\"ftp://\", \"https://\")\n } else {\n return url\n }\n}\n\n\nfunction arrayBufferToString(arraybuffer) {\n\n let plain;\n if (isgzipped(arraybuffer)) {\n plain = ungzip_blocks(arraybuffer);\n } else {\n plain = new Uint8Array(arraybuffer);\n }\n\n if ('TextDecoder' in getGlobalObject()) {\n return new TextDecoder().decode(plain)\n } else {\n return decodeUTF8(plain)\n }\n}\n\n/**\n * Use when TextDecoder is not available (primarily IE).\n *\n * From: https://gist.github.com/Yaffle/5458286\n *\n * @param octets\n * @returns {string}\n */\nfunction decodeUTF8(octets) {\n var string = \"\";\n var i = 0;\n while (i < octets.length) {\n var octet = octets[i];\n var bytesNeeded = 0;\n var codePoint = 0;\n if (octet <= 0x7F) {\n bytesNeeded = 0;\n codePoint = octet & 0xFF;\n } else if (octet <= 0xDF) {\n bytesNeeded = 1;\n codePoint = octet & 0x1F;\n } else if (octet <= 0xEF) {\n bytesNeeded = 2;\n codePoint = octet & 0x0F;\n } else if (octet <= 0xF4) {\n bytesNeeded = 3;\n codePoint = octet & 0x07;\n }\n if (octets.length - i - bytesNeeded > 0) {\n var k = 0;\n while (k < bytesNeeded) {\n octet = octets[i + k + 1];\n codePoint = (codePoint << 6) | (octet & 0x3F);\n k += 1;\n }\n } else {\n codePoint = 0xFFFD;\n bytesNeeded = octets.length - i;\n }\n string += String.fromCodePoint(codePoint);\n i += bytesNeeded + 1;\n }\n return string\n}\n\n\nfunction getGlobalObject() {\n if (typeof self !== 'undefined') {\n return self\n }\n if (typeof global !== 'undefined') {\n return global\n } else {\n return window\n }\n}\n\n\nconst igvxhr = new IGVXhr();\n\n/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2014 Broad Institute\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\n/** An implementation of an interval tree, following the explanation.\n * from CLR.\n *\n * Public interface:\n * Constructor IntervalTree\n * Insertion insert\n * Search findOverlapping\n */\n\nvar BLACK = 1;\nvar RED = 2;\n\nvar NIL = {};\nNIL.color = BLACK;\nNIL.parent = NIL;\nNIL.left = NIL;\nNIL.right = NIL;\n\n\nclass IntervalTree {\n\n constructor() {\n this.root = NIL;\n }\n\n insert(start, end, value) {\n\n var interval = new Interval(start, end, value);\n var x = new Node(interval);\n this.treeInsert(x);\n x.color = RED;\n while (x !== this.root && x.parent.color === RED) {\n if (x.parent === x.parent.parent.left) {\n let y = x.parent.parent.right;\n if (y.color === RED) {\n x.parent.color = BLACK;\n y.color = BLACK;\n x.parent.parent.color = RED;\n x = x.parent.parent;\n } else {\n if (x === x.parent.right) {\n x = x.parent;\n leftRotate.call(this, x);\n }\n x.parent.color = BLACK;\n x.parent.parent.color = RED;\n rightRotate.call(this, x.parent.parent);\n }\n } else {\n let y = x.parent.parent.left;\n if (y.color === RED) {\n x.parent.color = BLACK;\n y.color = BLACK;\n x.parent.parent.color = RED;\n x = x.parent.parent;\n } else {\n if (x === x.parent.left) {\n x = x.parent;\n rightRotate.call(this, x);\n }\n x.parent.color = BLACK;\n x.parent.parent.color = RED;\n leftRotate.call(this, x.parent.parent);\n }\n }\n }\n this.root.color = BLACK;\n }\n\n /**\n *\n * @param start - query interval\n * @param end - query interval\n * @returns Array of all intervals overlapping the query region\n */\n findOverlapping(start, end) {\n\n\n var searchInterval = new Interval(start, end, 0);\n\n if (this.root === NIL) return [];\n\n var intervals = searchAll.call(this, searchInterval, this.root, []);\n\n if (intervals.length > 1) {\n intervals.sort(function (i1, i2) {\n return i1.low - i2.low;\n });\n }\n\n return intervals;\n }\n\n /**\n * Dump info on intervals to console. For debugging.\n */\n logIntervals() {\n\n logNode(this.root, 0);\n\n function logNode(node, indent) {\n\n var space = \"\";\n for (var i = 0; i < indent; i++) space += \" \";\n console.log(space + node.interval.low + \" \" + node.interval.high); // + \" \" + (node.interval.value ? node.interval.value : \" null\"));\n\n indent += 5;\n\n if (node.left !== NIL) logNode(node.left, indent);\n if (node.right !== NIL) logNode(node.right, indent);\n }\n\n }\n\n mapIntervals(func) {\n\n applyInterval(this.root);\n\n function applyInterval(node) {\n\n func(node.interval);\n\n if (node.left !== NIL) applyInterval(node.left);\n if (node.right !== NIL) applyInterval(node.right);\n }\n }\n\n\n /**\n * Note: Does not maintain RB constraints, this is done post insert\n *\n * @param x a Node\n */\n treeInsert(x) {\n var node = this.root;\n var y = NIL;\n while (node !== NIL) {\n y = node;\n if (x.interval.low <= node.interval.low) {\n node = node.left;\n } else {\n node = node.right;\n }\n }\n x.parent = y;\n\n if (y === NIL) {\n this.root = x;\n x.left = x.right = NIL;\n } else {\n if (x.interval.low <= y.interval.low) {\n y.left = x;\n } else {\n y.right = x;\n }\n }\n\n applyUpdate.call(this, x);\n }\n}\n\nfunction searchAll(interval, node, results) {\n\n if (node.interval.overlaps(interval)) {\n results.push(node.interval);\n }\n\n if (node.left !== NIL && node.left.max >= interval.low) {\n searchAll.call(this, interval, node.left, results);\n }\n\n if (node.right !== NIL && node.right.min <= interval.high) {\n searchAll.call(this, interval, node.right, results);\n }\n\n return results;\n}\n\nfunction leftRotate(x) {\n var y = x.right;\n x.right = y.left;\n if (y.left !== NIL) {\n y.left.parent = x;\n }\n y.parent = x.parent;\n if (x.parent === NIL) {\n this.root = y;\n } else {\n if (x.parent.left === x) {\n x.parent.left = y;\n } else {\n x.parent.right = y;\n }\n }\n y.left = x;\n x.parent = y;\n\n applyUpdate.call(this, x);\n // no need to apply update on y, since it'll y is an ancestor\n // of x, and will be touched by applyUpdate().\n}\n\n\nfunction rightRotate(x) {\n var y = x.left;\n x.left = y.right;\n if (y.right !== NIL) {\n y.right.parent = x;\n }\n y.parent = x.parent;\n if (x.parent === NIL) {\n this.root = y;\n } else {\n if (x.parent.right === x) {\n x.parent.right = y;\n } else {\n x.parent.left = y;\n }\n }\n y.right = x;\n x.parent = y;\n\n\n applyUpdate.call(this, x);\n // no need to apply update on y, since it'll y is an ancestor\n // of x, and will be touched by applyUpdate().\n}\n\n\n// Applies the statistic update on the node and its ancestors.\nfunction applyUpdate(node) {\n while (node !== NIL) {\n var nodeMax = node.left.max > node.right.max ? node.left.max : node.right.max;\n var intervalHigh = node.interval.high;\n node.max = nodeMax > intervalHigh ? nodeMax : intervalHigh;\n\n var nodeMin = node.left.min < node.right.min ? node.left.min : node.right.min;\n var intervalLow = node.interval.low;\n node.min = nodeMin < intervalLow ? nodeMin : intervalLow;\n\n node = node.parent;\n }\n}\n\n\nclass Interval {\n constructor(low, high, value) {\n this.low = low;\n this.high = high;\n this.value = value;\n }\n\n equals(other) {\n if (!other) {\n return false;\n }\n if (this === other) {\n return true;\n }\n return (this.low === other.low &&\n this.high === other.high);\n\n }\n\n compareTo(other) {\n if (this.low < other.low)\n return -1;\n if (this.low > other.low)\n return 1;\n\n if (this.high < other.high)\n return -1;\n if (this.high > other.high)\n return 1;\n\n return 0;\n }\n\n /**\n * Returns true if this interval overlaps the other.\n */\n overlaps(other) {\n return (this.low <= other.high && other.low <= this.high);\n }\n}\n\nfunction Node(interval) {\n this.parent = NIL;\n this.left = NIL;\n this.right = NIL;\n this.interval = interval;\n this.color = RED;\n}\n\n/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2014 Broad Institute\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\n/**\n * Object for caching lists of features. Supports effecient queries for sub-range (chr, start, end)\n *\n * @param featureList\n * @param The genomic range spanned by featureList (optional)\n * @constructor\n */\n\nclass FeatureCache$1 {\n\n constructor(featureList, genome, range) {\n\n featureList = featureList || [];\n this.treeMap = this.buildTreeMap(featureList, genome);\n this.range = range;\n this.count = featureList.length;\n }\n\n containsRange(genomicRange) {\n // No range means cache contains all features\n return (this.range === undefined || this.range.contains(genomicRange.chr, genomicRange.start, genomicRange.end));\n }\n\n queryFeatures(chr, start, end) {\n\n const tree = this.treeMap[chr];\n\n if (!tree) return [];\n\n const intervals = tree.findOverlapping(start, end);\n\n if (intervals.length === 0) {\n return [];\n } else {\n // Trim the list of features in the intervals to those\n // overlapping the requested range.\n // Assumption: features are sorted by start position\n\n const featureList = [];\n const all = this.allFeatures[chr];\n if (all) {\n for (let interval of intervals) {\n const indexRange = interval.value;\n for (let i = indexRange.start; i < indexRange.end; i++) {\n let feature = all[i];\n if (feature.start > end) break;\n else if (feature.end >= start) {\n featureList.push(feature);\n }\n }\n }\n featureList.sort(function (a, b) {\n return a.start - b.start;\n });\n }\n return featureList;\n }\n };\n\n /**\n * Returns all features, unsorted.\n *\n * @returns {Array}\n */\n getAllFeatures() {\n return this.allFeatures;\n }\n\n buildTreeMap(featureList, genome) {\n\n const treeMap = {};\n const chromosomes = [];\n this.allFeatures = {};\n\n if (featureList) {\n for (let feature of featureList) {\n\n let chr = feature.chr;\n // Translate to \"official\" name\n if (genome) {\n chr = genome.getChromosomeName(chr);\n }\n\n let geneList = this.allFeatures[chr];\n if (!geneList) {\n chromosomes.push(chr);\n geneList = [];\n this.allFeatures[chr] = geneList;\n }\n geneList.push(feature);\n }\n\n\n // Now build interval tree for each chromosome\n for (let chr of chromosomes) {\n const chrFeatures = this.allFeatures[chr];\n chrFeatures.sort(function (f1, f2) {\n return (f1.start === f2.start ? 0 : (f1.start > f2.start ? 1 : -1));\n });\n treeMap[chr] = buildIntervalTree$1(chrFeatures);\n }\n }\n\n return treeMap;\n }\n}\n\n/**\n * Build an interval tree from the feature list for fast interval based queries. We lump features in groups\n * of 10, or total size / 100, to reduce size of the tree.\n *\n * @param featureList\n */\nfunction buildIntervalTree$1(featureList) {\n\n const tree = new IntervalTree();\n const len = featureList.length;\n const chunkSize = Math.max(10, Math.round(len / 10));\n\n for (let i = 0; i < len; i += chunkSize) {\n const e = Math.min(len, i + chunkSize);\n const subArray = new IndexRange(i, e); //featureList.slice(i, e);\n const iStart = featureList[i].start;\n //\n let iEnd = iStart;\n for (let j = i; j < e; j++) {\n iEnd = Math.max(iEnd, featureList[j].end);\n }\n tree.insert(iStart, iEnd, subArray);\n }\n\n return tree;\n}\n\n\nclass IndexRange {\n constructor(start, end) {\n this.start = start;\n this.end = end;\n }\n}\n\n/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2016-2017 The Regents of the University of California\n * Author: Jim Robinson\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\nconst FeatureUtils = {\n\n packFeatures: function (features, maxRows, sorted) {\n\n var start;\n var end;\n\n if (!features) return;\n\n maxRows = maxRows || 10000;\n\n if (!sorted) {\n features.sort(function (a, b) {\n return a.start - b.start;\n });\n }\n\n\n if (features.length === 0) {\n return [];\n\n } else {\n\n var bucketList = [],\n allocatedCount = 0,\n lastAllocatedCount = 0,\n nextStart,\n row,\n index,\n bucket,\n feature,\n gap = 2,\n bucketStart;\n\n start = features[0].start;\n end = features[features.length - 1].start;\n\n bucketStart = Math.max(start, features[0].start);\n nextStart = bucketStart;\n\n features.forEach(function (alignment) {\n\n var buckListIndex = Math.max(0, alignment.start - bucketStart);\n if (bucketList[buckListIndex] === undefined) {\n bucketList[buckListIndex] = [];\n }\n bucketList[buckListIndex].push(alignment);\n });\n\n\n row = 0;\n\n\n while (allocatedCount < features.length && row <= maxRows) {\n\n\n while (nextStart <= end) {\n\n bucket = undefined;\n\n while (!bucket && nextStart <= end) {\n\n index = nextStart - bucketStart;\n if (bucketList[index] === undefined) {\n ++nextStart; // No buckets at this index\n } else {\n bucket = bucketList[index];\n }\n\n } // while (bucket)\n\n if (!bucket) {\n break;\n }\n feature = bucket.pop();\n if (0 === bucket.length) {\n bucketList[index] = undefined;\n }\n\n feature.row = row;\n\n nextStart = feature.end + gap;\n ++allocatedCount;\n\n } // while (nextStart)\n\n row++;\n nextStart = bucketStart;\n\n if (allocatedCount === lastAllocatedCount) break; // Protect from infinite loops\n\n lastAllocatedCount = allocatedCount;\n\n } // while (allocatedCount)\n\n }\n },\n\n\n /**\n * Find features overlapping the given interval. It is assumed that all features share the same chromosome.\n *\n * TODO -- significant overlap with FeatureCache, refactor to combine\n *\n * @param featureList\n * @param start\n * @param end\n */\n findOverlapping: function (featureList, start, end) {\n\n if (!featureList || featureList.length === 0) {\n return [];\n } else {\n const tree = buildIntervalTree(featureList);\n const intervals = tree.findOverlapping(start, end);\n\n if (intervals.length === 0) {\n return [];\n } else {\n // Trim the list of features in the intervals to those\n // overlapping the requested range.\n // Assumption: features are sorted by start position\n\n featureList = [];\n\n intervals.forEach(function (interval) {\n const intervalFeatures = interval.value;\n const len = intervalFeatures.length;\n for (let i = 0; i < len; i++) {\n const feature = intervalFeatures[i];\n if (feature.start > end) break;\n else if (feature.end > start) {\n featureList.push(feature);\n }\n }\n });\n\n featureList.sort(function (a, b) {\n return a.start - b.start;\n });\n\n return featureList;\n }\n }\n\n }\n};\n\n\n/**\n * Build an interval tree from the feature list for fast interval based queries. We lump features in groups\n * of 10, or total size / 100, to reduce size of the tree.\n *\n * @param featureList\n */\nfunction buildIntervalTree(featureList) {\n\n const tree = new IntervalTree();\n const len = featureList.length;\n const chunkSize = Math.max(10, Math.round(len / 100));\n\n featureList.sort(function (f1, f2) {\n return (f1.start === f2.start ? 0 : (f1.start > f2.start ? 1 : -1));\n });\n\n for (let i = 0; i < len; i += chunkSize) {\n const e = Math.min(len, i + chunkSize);\n const subArray = featureList.slice(i, e);\n const iStart = subArray[0].start;\n let iEnd = iStart;\n subArray.forEach(function (feature) {\n iEnd = Math.max(iEnd, feature.end);\n });\n tree.insert(iStart, iEnd, subArray);\n }\n\n return tree;\n}\n\nconst appleCrayonRGBPalette =\n {\n cantaloupe: {r: 255, g: 206, b: 110},\n honeydew: {r: 206, g: 250, b: 110},\n spindrift: {r: 104, g: 251, b: 208},\n sky: {r: 106, g: 207, b: 255},\n lavender: {r: 210, g: 120, b: 255},\n carnation: {r: 255, g: 127, b: 211},\n licorice: {r: 0, g: 0, b: 0},\n snow: {r: 255, g: 255, b: 255},\n salmon: {r: 255, g: 114, b: 110},\n banana: {r: 255, g: 251, b: 109},\n flora: {r: 104, g: 249, b: 110},\n ice: {r: 104, g: 253, b: 255},\n orchid: {r: 110, g: 118, b: 255},\n bubblegum: {r: 255, g: 122, b: 255},\n lead: {r: 30, g: 30, b: 30},\n mercury: {r: 232, g: 232, b: 232},\n tangerine: {r: 255, g: 136, b: 2},\n lime: {r: 131, g: 249, b: 2},\n sea_foam: {r: 3, g: 249, b: 135},\n aqua: {r: 0, g: 140, b: 255},\n grape: {r: 137, g: 49, b: 255},\n strawberry: {r: 255, g: 41, b: 135},\n tungsten: {r: 58, g: 58, b: 58},\n silver: {r: 208, g: 208, b: 208},\n maraschino: {r: 255, g: 33, b: 1},\n lemon: {r: 255, g: 250, b: 3},\n spring: {r: 5, g: 248, b: 2},\n turquoise: {r: 0, g: 253, b: 255},\n blueberry: {r: 0, g: 46, b: 255},\n magenta: {r: 255, g: 57, b: 255},\n iron: {r: 84, g: 84, b: 83},\n magnesium: {r: 184, g: 184, b: 184},\n mocha: {r: 137, g: 72, b: 0},\n fern: {r: 69, g: 132, b: 1},\n moss: {r: 1, g: 132, b: 72},\n ocean: {r: 0, g: 74, b: 136},\n eggplant: {r: 73, g: 26, b: 136},\n maroon: {r: 137, g: 22, b: 72},\n steel: {r: 110, g: 110, b: 110},\n aluminum: {r: 160, g: 159, b: 160},\n cayenne: {r: 137, g: 17, b: 0},\n aspargus: {r: 136, g: 133, b: 1},\n clover: {r: 2, g: 132, b: 1},\n teal: {r: 0, g: 134, b: 136},\n midnight: {r: 0, g: 24, b: 136},\n plum: {r: 137, g: 30, b: 136},\n tin: {r: 135, g: 134, b: 135},\n nickel: {r: 136, g: 135, b: 135}\n };\n\nfunction appleCrayonRGB(name) {\n const {r, g, b} = appleCrayonRGBPalette[name];\n return `rgb(${r},${g},${b})`\n}\n\nfunction appleCrayonRGBA(name, alpha) {\n const {r, g, b} = appleCrayonRGBPalette[name];\n return `rgba(${r},${g},${b},${alpha})`\n}\n\nconst colorPalettes = {\n\n Set1:\n [\n \"rgb(228,26,28)\",\n \"rgb(55,126,184)\",\n \"rgb(77,175,74)\",\n \"rgb(166,86,40)\",\n \"rgb(152,78,163)\",\n \"rgb(255,127,0)\",\n \"rgb(247,129,191)\",\n \"rgb(153,153,153)\",\n \"rgb(255,255,51)\"\n ],\n\n Dark2:\n [\n \"rgb(27,158,119)\",\n \"rgb(217,95,2)\",\n \"rgb(117,112,179)\",\n \"rgb(231,41,138)\",\n \"rgb(102,166,30)\",\n \"rgb(230,171,2)\",\n \"rgb(166,118,29)\",\n \"rgb(102,102,102)\"\n ],\n\n Set2:\n [\n \"rgb(102, 194,165)\",\n \"rgb(252,141,98)\",\n \"rgb(141,160,203)\",\n \"rgb(231,138,195)\",\n \"rgb(166,216,84)\",\n \"rgb(255,217,47)\",\n \"rgb(229,196,148)\",\n \"rgb(179,179,179)\"\n ],\n\n Set3:\n [\n \"rgb(141,211,199)\",\n \"rgb(255,255,179)\",\n \"rgb(190,186,218)\",\n \"rgb(251,128,114)\",\n \"rgb(128,177,211)\",\n \"rgb(253,180,98)\",\n \"rgb(179,222,105)\",\n \"rgb(252,205,229)\",\n \"rgb(217,217,217)\",\n \"rgb(188,128,189)\",\n \"rgb(204,235,197)\",\n \"rgb(255,237,111)\"\n ],\n\n Pastel1:\n [\n \"rgb(251,180,174)\",\n \"rgb(179,205,227)\",\n \"rgb(204,235,197)\",\n \"rgb(222,203,228)\",\n \"rgb(254,217,166)\",\n \"rgb(255,255,204)\",\n \"rgb(229,216,189)\",\n \"rgb(253,218,236)\"\n ],\n\n Pastel2:\n [\n \"rgb(173,226,207)\",\n \"rgb(253,205,172)\",\n \"rgb(203,213,232)\",\n \"rgb(244,202,228)\",\n \"rgb(230,245,201)\",\n \"rgb(255,242,174)\",\n \"rgb(243,225,206)\"\n ],\n\n Accent:\n [\n \"rgb(127,201,127)\",\n \"rgb(190,174,212)\",\n \"rgb(253,192,134)\",\n \"rgb(255,255,153)\",\n \"rgb(56,108,176)\",\n \"rgb(240,2,127)\",\n \"rgb(191,91,23)\"\n ]\n};\n\nclass PaletteColorTable {\n\n constructor(palette) {\n this.colors = colorPalettes[palette];\n if (!Array.isArray(this.colors)) this.colors = [];\n this.colorTable = {};\n this.nextIdx = 0;\n this.colorGenerator = new RandomColorGenerator();\n }\n\n getColor(key) {\n if (!this.colorTable.hasOwnProperty(key)) {\n if (this.nextIdx < this.colors.length) {\n this.colorTable[key] = this.colors[this.nextIdx];\n } else {\n this.colorTable[key] = this.colorGenerator.get();\n }\n this.nextIdx++;\n }\n return this.colorTable[key]\n }\n}\n\nclass ColorTable {\n constructor(colors) {\n this.colorTable = colors || {};\n this.nextIdx = 0;\n this.colorGenerator = new RandomColorGenerator();\n }\n\n getColor(key) {\n if (!this.colorTable.hasOwnProperty(key)) {\n if (this.colorTable.hasOwnProperty(\"*\")) {\n return this.colorTable[\"*\"]\n }\n this.colorTable[key] = this.colorGenerator.get();\n }\n return this.colorTable[key]\n }\n}\n\n// Random color generator from https://github.com/sterlingwes/RandomColor/blob/master/rcolor.js\n// Free to use & distribute under the MIT license\n// Wes Johnson (@SterlingWes)\n//\n// inspired by http://martin.ankerl.com/2009/12/09/how-to-create-random-colors-programmatically/\nfunction RandomColorGenerator() {\n this.hue = Math.random();\n this.goldenRatio = 0.618033988749895;\n this.hexwidth = 2;\n}\n\nRandomColorGenerator.prototype.hsvToRgb = function (h, s, v) {\n var h_i = Math.floor(h * 6),\n f = h * 6 - h_i,\n p = v * (1 - s),\n q = v * (1 - f * s),\n t = v * (1 - (1 - f) * s),\n r = 255,\n g = 255,\n b = 255;\n switch (h_i) {\n case 0:\n r = v, g = t, b = p;\n break\n case 1:\n r = q, g = v, b = p;\n break\n case 2:\n r = p, g = v, b = t;\n break\n case 3:\n r = p, g = q, b = v;\n break\n case 4:\n r = t, g = p, b = v;\n break\n case 5:\n r = v, g = p, b = q;\n break\n }\n return [Math.floor(r * 256), Math.floor(g * 256), Math.floor(b * 256)]\n};\n\nRandomColorGenerator.prototype.padHex = function (str) {\n if (str.length > this.hexwidth) return str\n return new Array(this.hexwidth - str.length + 1).join('0') + str\n};\n\nRandomColorGenerator.prototype.get = function (saturation, value) {\n this.hue += this.goldenRatio;\n this.hue %= 1;\n if (typeof saturation !== \"number\") saturation = 0.5;\n if (typeof value !== \"number\") value = 0.95;\n var rgb = this.hsvToRgb(this.hue, saturation, value);\n\n return \"#\" + this.padHex(rgb[0].toString(16))\n + this.padHex(rgb[1].toString(16))\n + this.padHex(rgb[2].toString(16))\n\n};\n\nnew RandomColorGenerator();\n\nfunction randomRGB$1(min, max) {\n\n min = IGVMath.clamp(min, 0, 255);\n max = IGVMath.clamp(max, 0, 255);\n\n const r = Math.round(Math.random() * (max - min) + min).toString(10);\n const g = Math.round(Math.random() * (max - min) + min).toString(10);\n const b = Math.round(Math.random() * (max - min) + min).toString(10);\n return `rgb(${r},${g},${b})`\n\n}\n\n/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2014 Broad Institute\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of ctx software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and ctx permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\n\nconst IGVGraphics = {\n\n configureHighDPICanvas: function (ctx, w, h) {\n\n const scaleFactor = window.devicePixelRatio;\n // const scaleFactor = 1\n\n ctx.canvas.style.width = (`${w}px`);\n ctx.canvas.width = Math.floor(scaleFactor * w);\n\n ctx.canvas.style.height = (`${h}px`);\n ctx.canvas.height = Math.floor(scaleFactor * h);\n\n ctx.scale(scaleFactor, scaleFactor);\n\n },\n\n setProperties: function (ctx, properties) {\n\n for (var key in properties) {\n if (properties.hasOwnProperty(key)) {\n var value = properties[key];\n ctx[key] = value;\n }\n }\n },\n\n strokeLine: function (ctx, x1, y1, x2, y2, properties) {\n\n x1 = Math.floor(x1) + 0.5;\n y1 = Math.floor(y1) + 0.5;\n x2 = Math.floor(x2) + 0.5;\n y2 = Math.floor(y2) + 0.5;\n\n if (properties) {\n ctx.save();\n IGVGraphics.setProperties(ctx, properties);\n }\n\n ctx.beginPath();\n ctx.moveTo(x1, y1);\n ctx.lineTo(x2, y2);\n ctx.stroke();\n\n if (properties) ctx.restore();\n },\n\n fillRect: function (ctx, x, y, w, h, properties) {\n x = Math.round(x);\n y = Math.round(y);\n\n if (properties) {\n ctx.save();\n IGVGraphics.setProperties(ctx, properties);\n }\n\n ctx.fillRect(x, y, w, h);\n\n if (properties) ctx.restore();\n },\n\n fillPolygon: function (ctx, x, y, properties) {\n if (properties) {\n ctx.save();\n IGVGraphics.setProperties(ctx, properties);\n }\n doPath(ctx, x, y);\n ctx.fill();\n if (properties) ctx.restore();\n },\n\n strokePolygon: function (ctx, x, y, properties) {\n if (properties) {\n ctx.save();\n IGVGraphics.setProperties(ctx, properties);\n }\n doPath(ctx, x, y);\n ctx.stroke();\n if (properties) ctx.restore();\n },\n\n fillText: function (ctx, text, x, y, properties, transforms) {\n\n if (properties || transforms) {\n ctx.save();\n }\n\n if (properties) {\n IGVGraphics.setProperties(ctx, properties);\n }\n\n if (transforms) {\n // Slow path with context saving and extra translate\n ctx.translate(x, y);\n\n for (var transform in transforms) {\n var value = transforms[transform];\n\n // TODO: Add error checking for robustness\n if (transform === 'translate') {\n ctx.translate(value['x'], value['y']);\n }\n if (transform === 'rotate') {\n ctx.rotate(value['angle'] * Math.PI / 180);\n }\n }\n\n ctx.fillText(text, 0, 0);\n } else {\n ctx.fillText(text, x, y);\n }\n\n if (properties || transforms) ctx.restore();\n },\n\n strokeText: function (ctx, text, x, y, properties, transforms) {\n\n\n if (properties || transforms) {\n ctx.save();\n }\n\n if (properties) {\n IGVGraphics.setProperties(ctx, properties);\n }\n\n if (transforms) {\n ctx.translate(x, y);\n\n for (var transform in transforms) {\n var value = transforms[transform];\n\n // TODO: Add error checking for robustness\n if (transform === 'translate') {\n ctx.translate(value['x'], value['y']);\n }\n if (transform === 'rotate') {\n ctx.rotate(value['angle'] * Math.PI / 180);\n }\n }\n\n ctx.strokeText(text, 0, 0);\n } else {\n ctx.strokeText(text, x, y);\n }\n\n if (properties || transforms) ctx.restore();\n },\n\n strokeCircle: function (ctx, x, y, radius, properties) {\n if (properties) {\n ctx.save();\n IGVGraphics.setProperties(ctx, properties);\n }\n ctx.beginPath();\n ctx.arc(x, y, radius, 0, 2 * Math.PI);\n ctx.stroke();\n if (properties) ctx.restore();\n },\n\n fillCircle: function (ctx, x, y, radius, properties) {\n if (properties) {\n ctx.save();\n IGVGraphics.setProperties(ctx, properties);\n }\n ctx.beginPath();\n ctx.arc(x, y, radius, 0, 2 * Math.PI);\n ctx.fill();\n if (properties) ctx.restore();\n },\n\n drawArrowhead: function (ctx, x, y, size, lineWidth) {\n\n ctx.save();\n if (!size) {\n size = 5;\n }\n if (lineWidth) {\n ctx.lineWidth = lineWidth;\n }\n ctx.beginPath();\n ctx.moveTo(x, y - size / 2);\n ctx.lineTo(x, y + size / 2);\n ctx.lineTo(x + size, y);\n ctx.lineTo(x, y - size / 2);\n ctx.closePath();\n ctx.fill();\n ctx.restore();\n },\n\n dashedLine: function (ctx, x1, y1, x2, y2, dashLen, properties = {}) {\n if (dashLen === undefined) dashLen = 2;\n ctx.setLineDash([dashLen, dashLen]);\n IGVGraphics.strokeLine(ctx, x1, y1, x2, y2, properties);\n ctx.setLineDash([]);\n },\n\n roundRect: function (ctx, x, y, width, height, radius, fill, stroke) {\n\n if (typeof stroke == \"undefined\") {\n stroke = true;\n }\n if (typeof radius === \"undefined\") {\n radius = 5;\n }\n ctx.beginPath();\n ctx.moveTo(x + radius, y);\n ctx.lineTo(x + width - radius, y);\n ctx.quadraticCurveTo(x + width, y, x + width, y + radius);\n ctx.lineTo(x + width, y + height - radius);\n ctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height);\n ctx.lineTo(x + radius, y + height);\n ctx.quadraticCurveTo(x, y + height, x, y + height - radius);\n ctx.lineTo(x, y + radius);\n ctx.quadraticCurveTo(x, y, x + radius, y);\n ctx.closePath();\n if (stroke) {\n ctx.stroke();\n }\n if (fill) {\n ctx.fill();\n }\n },\n polygon: function (ctx, x, y, fill, stroke) {\n\n if (typeof stroke == \"undefined\") {\n stroke = true;\n }\n\n ctx.beginPath();\n var len = x.length;\n ctx.moveTo(x[0], y[0]);\n for (var i = 1; i < len; i++) {\n ctx.lineTo(x[i], y[i]);\n // this.moveTo(x[i], y[i]);\n }\n\n ctx.closePath();\n if (stroke) {\n ctx.stroke();\n }\n if (fill) {\n ctx.fill();\n }\n },\n\n drawRandomColorVerticalLines: ctx => {\n for (let x = 0; x < ctx.canvas.width; x++) {\n IGVGraphics.fillRect(ctx, x, 0, 1, ctx.canvas.height, { fillStyle: randomRGB$1(100, 250) });\n }\n },\n\n labelTransformWithContext: (ctx, exe) => {\n ctx.translate(exe, 0);\n ctx.scale(-1, 1);\n ctx.translate(-exe, 0);\n }\n\n};\n\nfunction doPath(ctx, x, y) {\n\n\n var i, len = x.length;\n for (i = 0; i < len; i++) {\n x[i] = Math.round(x[i]);\n y[i] = Math.round(y[i]);\n }\n\n ctx.beginPath();\n ctx.moveTo(x[0], y[0]);\n for (i = 1; i < len; i++) {\n ctx.lineTo(x[i], y[i]);\n }\n ctx.closePath();\n}\n\nclass Alert {\n constructor(parent) {\n this.dialog = new AlertDialog(parent);\n\n }\n\n present(alert, callback) {\n this.dialog.present(alert, callback);\n }\n}\n\nconst FileFormats = {\n\n gwascatalog: {\n fields: [\n 'bin',\n 'chr',\n 'start',\n 'end',\n 'name',\n 'pubMedID',\n 'author',\n 'pubDate',\n 'journal',\n 'title',\n 'trait',\n 'initSample',\n 'replSample',\n 'region',\n 'genes',\n 'riskAllele',\n 'riskAlFreq',\n 'pValue',\n 'pValueDesc',\n 'orOrBeta',\n 'ci95',\n 'platform',\n 'cnv'\n ]\n },\n\n wgrna: {\n fields:\n [\n 'bin',\n 'chr',\n 'start',\n 'end',\n 'name',\n 'score',\n 'strand',\n 'thickStart',\n 'thickEnd',\n 'type'\n ]\n },\n\n cpgislandext: {\n fields:\n\n [\n 'bin',\n 'chr',\n 'start',\n 'end',\n 'name',\n 'length',\n 'cpgNum',\n 'gcNum',\n 'perCpg',\n 'perGc',\n 'obsExp'\n ]\n },\n\n clinVarMain: {\n fields: [\n 'chr1',\n 'start',\n 'end',\n 'name',\n 'score',\n 'strand',\n 'thickStart',\n 'thickEnd',\n 'reserved',\n 'blockCount', // Number of blocks\n 'blockSizes', // Comma separated list of block sizes\n 'chromStarts', // Start positions relative to chromStart\n 'origName', // NM_198053.2(CD247):c.462C>T (p.Asp154=)\tClinVar Variation Report\n 'clinSign', // Likely benign\tClinical significance\n 'reviewStatus', // \tbased on: criteria provided,single submitter\tReview Status\n 'type', // single nucleotide variant\tType of Variant\n 'geneId', \t // CD247\tGene Symbol\n 'snpId', //\t181656780\tdbSNP ID\n 'nsvId', //\t\tdbVar ID\n 'rcvAcc', //\tRCV000642347\tClinVar Allele Submission\n 'testedInGtr', //\tN\tGenetic Testing Registry\n 'phenotypeList', //\tImmunodeficiency due to defect in cd3-zeta\tPhenotypes\n 'phenotype', //\tMedGen:C1857798, OMIM:610163\tPhenotype identifiers\n 'origin', //\tgermline\tData origin\n 'assembly', //\tGRCh37\tGenome assembly\n 'cytogenetic', //\t1q24.2\tCytogenetic status\n 'hgvsCod', //\tNM_198053.2:c.462C>T\tNucleotide HGVS\n 'hgvsProt', //\tNP_932170.1:p.Asp154=\tProtein HGVS\n 'numSubmit', //\t1\tNumber of submitters\n 'lastEval', //\tDec 19,2017\tLast evaluation\n 'guidelines', //\t\tGuidelines\n 'otherIds'\n ]\n }\n};\n\n/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2014 Broad Institute\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\n/**\n * Test if the given value is a string or number. Not using typeof as it fails on boxed primitives.\n *\n * @param value\n * @returns boolean\n */\n\nfunction isSimpleType(value) {\n const simpleTypes = new Set([\"boolean\", \"number\", \"string\", \"symbol\"]);\n const valueType = typeof value;\n return (value !== undefined && (simpleTypes.has(valueType) || value.substring || value.toFixed))\n}\n\nfunction buildOptions(config, options) {\n\n var defaultOptions = {\n oauthToken: config.oauthToken,\n headers: config.headers,\n withCredentials: config.withCredentials,\n filename: config.filename\n };\n\n return Object.assign(defaultOptions, options)\n}\n\n/**\n * isMobile test from http://detectmobilebrowsers.com\n * TODO -- improve UI design so this isn't neccessary\n * @returns {boolean}\n */\n\n// igv.isMobile = function () {\n//\n// const a = (navigator.userAgent || navigator.vendor || window.opera);\n// return (/(android|bb\\d+|meego).+mobile|avantgo|bada\\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(a) ||\n// /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\\-(n|u)|c55\\/|capi|ccwa|cdm\\-|cell|chtm|cldc|cmd\\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\\-s|devi|dica|dmob|do(c|p)o|ds(12|\\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\\-|_)|g1 u|g560|gene|gf\\-5|g\\-mo|go(\\.w|od)|gr(ad|un)|haie|hcit|hd\\-(m|p|t)|hei\\-|hi(pt|ta)|hp( i|ip)|hs\\-c|ht(c(\\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\\-(20|go|ma)|i230|iac( |\\-|\\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\\/)|klon|kpt |kwc\\-|kyo(c|k)|le(no|xi)|lg( g|\\/(k|l|u)|50|54|\\-[a-w])|libw|lynx|m1\\-w|m3ga|m50\\/|ma(te|ui|xo)|mc(01|21|ca)|m\\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\\-2|po(ck|rt|se)|prox|psio|pt\\-g|qa\\-a|qc(07|12|21|32|60|\\-[2-7]|i\\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\\-|oo|p\\-)|sdk\\/|se(c(\\-|0|1)|47|mc|nd|ri)|sgh\\-|shar|sie(\\-|m)|sk\\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\\-|v\\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\\-|tdg\\-|tel(i|m)|tim\\-|t\\-mo|to(pl|sh)|ts(70|m\\-|m3|m5)|tx\\-9|up(\\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\\-|your|zeto|zte\\-/i.test(a.substr(0, 4)))\n//\n// }\n\nconst doAutoscale = function (features) {\n var min, max;\n\n if (features && features.length > 0) {\n min = Number.MAX_VALUE;\n max = -Number.MAX_VALUE;\n\n for(let f of features) {\n if (!Number.isNaN(f.value)) {\n min = Math.min(min, f.value);\n max = Math.max(max, f.value);\n }\n }\n\n // Insure we have a zero baseline\n if (max > 0) min = Math.min(0, min);\n if (max < 0) max = 0;\n } else {\n // No features -- default\n min = 0;\n max = 100;\n }\n\n return {min: min, max: max}\n};\n\nconst validateGenomicExtent = function (chromosomeLengthBP, genomicExtent, minimumBP) {\n\n let ss = genomicExtent.start;\n let ee = genomicExtent.end;\n\n if (undefined === ee) {\n\n ss -= minimumBP / 2;\n ee = ss + minimumBP;\n\n if (ee > chromosomeLengthBP) {\n ee = chromosomeLengthBP;\n ss = ee - minimumBP;\n } else if (ss < 0) {\n ss = 0;\n ee = minimumBP;\n }\n\n } else if (ee - ss < minimumBP) {\n\n const center = (ee + ss) / 2;\n\n if (center - minimumBP / 2 < 0) {\n ss = 0;\n ee = ss + minimumBP;\n } else if (center + minimumBP / 2 > chromosomeLengthBP) {\n ee = chromosomeLengthBP;\n ss = ee - minimumBP;\n } else {\n ss = center - minimumBP / 2;\n ee = ss + minimumBP;\n }\n }\n\n genomicExtent.start = Math.ceil(ss);\n genomicExtent.end = Math.floor(ee);\n};\n\n/*!\n * is-number \n *\n * Copyright (c) 2014-present, Jon Schlinkert.\n * Released under the MIT License.\n */\n\nconst isNumber = function (num) {\n if (typeof num === 'number') {\n return num - num === 0\n }\n if (typeof num === 'string' && num.trim() !== '') {\n return Number.isFinite ? Number.isFinite(+num) : isFinite(+num)\n }\n return false\n};\n\nasync function getFilename$1(url) {\n if (isString$2(url) && url.startsWith(\"https://drive.google.com\")) {\n // This will fail if Google API key is not defined\n if (getApiKey() === undefined) {\n throw Error(\"Google drive is referenced, but API key is not defined. An API key is required for Google Drive access\")\n }\n const json = await getDriveFileInfo(url);\n return json.originalFileName || json.name\n } else {\n return getFilename$2(url)\n }\n}\n\nfunction prettyBasePairNumber(raw) {\n\n var denom,\n units,\n value,\n floored;\n\n if (raw > 1e7) {\n denom = 1e6;\n units = \" mb\";\n } else if (raw > 1e4) {\n\n denom = 1e3;\n units = \" kb\";\n\n value = raw / denom;\n floored = Math.floor(value);\n return numberFormatter$1(floored) + units\n } else {\n return numberFormatter$1(raw) + \" bp\"\n }\n\n value = raw / denom;\n floored = Math.floor(value);\n\n return floored.toString() + units\n}\n\n\nfunction isDataURL(obj) {\n return (isString$2(obj) && obj.startsWith(\"data:\"))\n}\n\nfunction createColumn(columnContainer, className) {\n const column = domUtils.div({class: className});\n columnContainer.appendChild(column);\n}\n\n\nfunction insertElementBefore(element, referenceNode) {\n referenceNode.parentNode.insertBefore(element, referenceNode);\n}\n\nfunction insertElementAfter(element, referenceNode) {\n referenceNode.parentNode.insertBefore(element, referenceNode.nextSibling);\n}\n\n/**\n * Test to see if page is loaded in a secure context, that is by https or is localhost.\n */\nfunction isSecureContext() {\n return window.location.protocol === \"https:\" || window.location.hostname === \"localhost\"\n}\n\n// reference: https://pretagteam.com/question/find-element-height-including-margin\nfunction getElementAbsoluteHeight(element) {\n\n // Get the DOM Node if you pass in a string\n element = (typeof element === 'string') ? document.querySelector(element) : element;\n\n const styles = window.getComputedStyle(element);\n const margin = parseFloat(styles['marginTop']) + parseFloat(styles['marginBottom']);\n const height = element.offsetHeight;\n\n return Math.ceil(margin + height);\n}\n\n/**\n * Decoder for bedpe records.\n *\n * Bedpe format was created by Aaron Quinlan et al as part of the bedtools project.\n * The spec is here: https://bedtools.readthedocs.io/en/latest/content/general-usage.html,\n *\n * 1 2 3 4 5 6 7 8 9 10 11-\n * chrom1 start1 end1 chrom2 start2 end2 name score strand1 strand2 \n *\n * However there are off spec variants, an important one being a 7 column format with score in place of the standard\n * name column.\n *\n * A common variant is a \"hiccups\" output file, which is standard bedpe with the exception of a header line\n * of the form\n *\n * chr1 x1 x2 chr2 y1 y2 name score strand1 strand2 color observed expectedBL expectedDonut expectedH expectedV fdrBL fdrDonut fdrH fdrV\n *\n * The \"hiccups\" output is apparently not standardized as this is found at ENCODE, with a non-helpful \"tsv\" extension\n *\n * chr1 x1 x2 chr2 y1 y2 color observed expectedBL expectedDonut expectedH expectedV fdrBL fdrDonut fdrH fdrV numCollapsed centroid1 centroid2 radius\n * chr9 136790000 136795000 chr9 136990000 136995000 0,255,255 101.0 31.100368 38.40316 56.948116 34.040756 1.1876738E-13 1.05936405E-13 2.5148233E-4 1.7220993E-13 1 136792500 136992500 25590\n *\n * The \"hiccups\" documentation specfies yet another set of column headers\n * chromosome1 x1 x2 chromosome2 y1 y2 color observed expected_bottom_left expected_donut expected_horizontal expected_vertical fdr_bottom_left fdr_donut fdr_horizontal fdr_vertical number_collapsed centroid1 centroid2 radius\n *\n * @param tokens\n * @param ignore\n * @returns {{start1: number, end2: number, end1: number, chr1: *, chr2: *, start2: number}|undefined}\n */\n\nfunction decodeBedpe(tokens, header) {\n\n if (tokens.length < 6) {\n console.log(\"Skipping line: \" + tokens.join(' '));\n return undefined\n }\n\n var feature = {\n chr1: tokens[0],\n start1: Number.parseInt(tokens[1]),\n end1: Number.parseInt(tokens[2]),\n chr2: tokens[3],\n start2: Number.parseInt(tokens[4]),\n end2: Number.parseInt(tokens[5])\n };\n\n if (isNaN(feature.start1) || isNaN(feature.end1) || isNaN(feature.start2) || isNaN(feature.end2)) {\n //throw Error(`Error parsing line: ${tokens.join('\\t')}`);\n return undefined\n }\n\n // Determine if this is a \"hiccups\" file. Store result on \"header\" so it doesn't need repeated for every feature\n if(header && header.hiccups === undefined) {\n header.hiccups = header.columnNames ? isHiccups(header.columnNames) : false;\n }\n const hiccups = header && header.hiccups;\n const stdColumns = hiccups ? 6 : 10;\n\n if(!hiccups) {\n if (tokens.length > 6 && tokens[6] !== \".\") {\n feature.name = tokens[6];\n }\n\n if (tokens.length > 7 && tokens[7] !== \".\") {\n feature.score = Number(tokens[7]);\n }\n\n if (tokens.length > 8 && tokens[8] !== \".\") {\n feature.strand1 = tokens[8];\n }\n\n if (tokens.length > 9 && tokens[9] !== \".\") {\n feature.strand2 = tokens[9];\n }\n }\n\n // Optional extra columns\n if (header) {\n const colorColumn = header.colorColumn;\n if (colorColumn && colorColumn < tokens.length) {\n feature.color = IGVColor.createColorString(tokens[colorColumn]);\n }\n const thicknessColumn = header.thicknessColumn;\n if (thicknessColumn && thicknessColumn < tokens.length) {\n feature.thickness = tokens[thicknessColumn];\n }\n\n if (tokens.length > stdColumns && header.columnNames && header.columnNames.length === tokens.length) {\n feature.extras = tokens.slice(stdColumns);\n }\n }\n\n\n // Set total extent of feature\n if (feature.chr1 === feature.chr2) {\n feature.chr = feature.chr1;\n feature.start = Math.min(feature.start1, feature.start2);\n feature.end = Math.max(feature.end1, feature.end2);\n\n }\n return feature\n}\n\n/**\n * Hack for non-standard bedPE formats, where numeric score can be in column 7 (name field from spec)\n * @param features\n */\nfunction fixBedPE(features) {\n\n if (features.length == 0) return\n\n // Assume all features have same properties\n const firstFeature = features[0];\n if (firstFeature.score === undefined && firstFeature.name !== undefined) {\n // Name field (col 7) is sometimes used for score.\n for (let f of features) {\n if (!(isNumber(f.name) || f.name === '.')) return\n }\n for (let f of features) {\n f.score = Number(f.name);\n delete f.name;\n }\n }\n\n // Make copies of inter-chr features, one for each chromosome\n const interChrFeatures = features.filter(f => f.chr1 !== f.chr2);\n for (let f1 of interChrFeatures) {\n const f2 = Object.assign({}, f1);\n f2.dup = true;\n features.push(f2);\n\n f1.chr = f1.chr1;\n f1.start = f1.start1;\n f1.end = f1.end1;\n\n f2.chr = f2.chr2;\n f2.start = f2.start2;\n f2.end = f2.end2;\n }\n}\n\n\n/**\n * Special decoder for Hic Domain files. In these files feature1 == feature2, they are really bed records.\n * @param tokens\n * @param ignore\n * @returns {*}\n */\nfunction decodeBedpeDomain(tokens, header) {\n\n if (tokens.length < 8) return undefined\n\n return {\n chr: tokens[0],\n start: Number.parseInt(tokens[1]),\n end: Number.parseInt(tokens[2]),\n color: IGVColor.createColorString(tokens[6]),\n value: Number(tokens[7])\n }\n}\n\nfunction isHiccups(columns) {\n return columns && (columns.includes(\"fdrDonut\") || columns.includes(\"fdr_donut\"))\n}\n\n/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2014 Broad Institute\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\nconst knownFileExtensions = new Set([\n\n \"narrowpeak\",\n \"broadpeak\",\n \"regionpeak\",\n \"peaks\",\n \"bedgraph\",\n \"wig\",\n \"gff3\",\n \"gff\",\n \"gtf\",\n \"fusionjuncspan\",\n \"refflat\",\n \"seg\",\n \"aed\",\n \"bed\",\n \"vcf\",\n \"bb\",\n \"bigbed\",\n \"biginteract\",\n \"biggenepred\",\n \"bignarrowpeak\",\n \"bw\",\n \"bigwig\",\n \"bam\",\n \"tdf\",\n \"refgene\",\n \"genepred\",\n \"genepredext\",\n \"bedpe\",\n \"bp\",\n \"snp\",\n \"rmsk\",\n \"cram\",\n \"gwas\",\n \"maf\",\n \"mut\",\n \"tsv\",\n \"hiccups\",\n \"fasta\",\n \"fa\",\n \"fna\",\n \"pytor\"\n]);\n\n/**\n * Return a custom format object with the given name.\n * @param name\n * @returns {*}\n */\nfunction getFormat(name) {\n\n if (FileFormats && FileFormats[name]) {\n return expandFormat(FileFormats[name])\n } else {\n return undefined\n }\n\n function expandFormat(format) {\n\n const fields = format.fields;\n const keys = ['chr', 'start', 'end'];\n\n for (let i = 0; i < fields.length; i++) {\n for (let key of keys) {\n if (key === fields[i]) {\n format[key] = i;\n }\n }\n }\n\n return format\n }\n}\n\nfunction inferFileFormat(fn) {\n\n var idx, ext;\n\n fn = fn.toLowerCase();\n\n // Special case -- UCSC refgene files\n if (fn.endsWith(\"refgene.txt.gz\") ||\n fn.endsWith(\"refgene.txt.bgz\") ||\n fn.endsWith(\"refgene.txt\") ||\n fn.endsWith(\"refgene.sorted.txt.gz\") ||\n fn.endsWith(\"refgene.sorted.txt.bgz\")) {\n return \"refgene\"\n }\n\n\n //Strip parameters -- handle local files later\n idx = fn.indexOf(\"?\");\n if (idx > 0) {\n fn = fn.substr(0, idx);\n }\n\n //Strip aux extensions .gz, .tab, and .txt\n if (fn.endsWith(\".gz\")) {\n fn = fn.substr(0, fn.length - 3);\n }\n\n if (fn.endsWith(\".txt\") || fn.endsWith(\".tab\") || fn.endsWith(\".bgz\")) {\n fn = fn.substr(0, fn.length - 4);\n }\n\n\n idx = fn.lastIndexOf(\".\");\n ext = idx < 0 ? fn : fn.substr(idx + 1);\n\n switch (ext) {\n case \"bw\":\n return \"bigwig\"\n case \"bb\":\n return \"bigbed\"\n case \"fasta\":\n case \"fa\":\n case \"fna\":\n return \"fasta\"\n default:\n if (knownFileExtensions.has(ext)) {\n return ext\n } else {\n return undefined\n }\n\n }\n\n}\n\nfunction inferIndexPath(url, extension) {\n\n if (isString$2(url)) {\n if (url.includes(\"?\")) {\n const idx = url.indexOf(\"?\");\n return url.substring(0, idx) + \".\" + extension + url.substring(idx)\n } else {\n return url + \".\" + extension\n }\n } else {\n return undefined\n }\n}\n\n\nfunction inferTrackType(config) {\n\n translateDeprecatedTypes(config);\n\n if (config.type) {\n return config.type\n }\n\n if (config.format) {\n const format = config.format.toLowerCase();\n switch (format) {\n case \"bw\":\n case \"bigwig\":\n case \"wig\":\n case \"bedgraph\":\n case \"tdf\":\n return \"wig\"\n case \"vcf\":\n return \"variant\"\n case \"seg\":\n return \"seg\"\n case \"mut\":\n case \"maf\":\n return \"mut\"\n case \"bam\":\n case \"cram\":\n return \"alignment\"\n case \"hiccups\":\n case \"bedpe\":\n case \"bedpe-loop\":\n case \"biginteract\":\n return \"interact\"\n case \"bp\":\n return \"arc\"\n case \"gwas\":\n return \"gwas\"\n case \"bed\":\n case \"bigbed\":\n case \"bb\":\n case \"biggenepred\":\n case \"bignarrowpeak\":\n return \"bedtype\"\n case \"fasta\":\n return \"sequence\"\n case \"pytor\":\n return \"cnvpytor\"\n default:\n return \"annotation\"\n }\n }\n}\n\nfunction translateDeprecatedTypes(config) {\n\n if (config.featureType) { // Translate deprecated \"feature\" type\n config.type = config.type || config.featureType;\n config.featureType = undefined;\n }\n if (\"junctions\" === config.type) {\n config.type = \"junction\";\n } else if (\"bed\" === config.type) {\n config.type = \"annotation\";\n config.format = config.format || \"bed\";\n } else if (\"annotations\" === config.type) {\n config.type = \"annotation\";\n } else if (\"alignments\" === config.type) {\n config.type = \"alignment\";\n } else if (\"bam\" === config.type) {\n config.type = \"alignment\";\n config.format = \"bam\";\n } else if (\"vcf\" === config.type) {\n config.type = \"variant\";\n config.format = \"vcf\";\n } else if (\"t2d\" === config.type) {\n config.type = \"gwas\";\n } else if (\"FusionJuncSpan\" === config.type && !config.format) {\n config.format = \"fusionjuncspan\";\n } else if (\"aed\" === config.type) {\n config.type = \"annotation\";\n config.format = config.format || \"aed\";\n }\n}\n\n/**\n * Attempt to infer the file format by reading a few lines from the header. Currently this only supports \"tsv\" extensions,\n * it was added specifically for \"hiccups\" type tsv files in ENCODE. Might be expanded in the future.\n *\n * @param url\n * @returns {Promise}\n */\nasync function inferFileFormatFromHeader(config) {\n\n if (config.url) {\n const firstBytes = await igvxhr.loadString(config.url, buildOptions(config, {range: {start: 0, size: 1000}}));\n if(firstBytes) {\n const columnNames = firstBytes.split('\\n')[0].split('\\t');\n if(isHiccups(columnNames)) {\n return \"hiccups\"\n }\n }\n }\n\n return undefined\n\n}\n\nfunction registerFileFormats(name, fields) {\n FileFormats[name] = {fields: fields};\n}\n\nvar TrackUtils = /*#__PURE__*/Object.freeze({\n __proto__: null,\n knownFileExtensions: knownFileExtensions,\n getFormat: getFormat,\n inferFileFormat: inferFileFormat,\n inferFileFormatFromHeader: inferFileFormatFromHeader,\n inferTrackType: inferTrackType,\n inferIndexPath: inferIndexPath,\n registerFileFormats: registerFileFormats\n});\n\nconst pairs =\n [\n ['A', 'T'],\n ['G', 'C'],\n ['Y', 'R'],\n ['W', 'S'],\n ['K', 'M'],\n ['D', 'H'],\n ['B', 'V']\n ];\n\nconst complements = new Map();\nfor (let p of pairs) {\n const p1 = p[0];\n const p2 = p[1];\n complements.set(p1, p2);\n complements.set(p2, p1);\n complements.set(p1.toLowerCase(), p2.toLowerCase());\n complements.set(p2.toLowerCase(), p1.toLowerCase());\n}\n\nfunction reverseComplementSequence(sequence) {\n\n let comp = '';\n let idx = sequence.length;\n while (idx-- > 0) {\n const base = sequence[idx];\n comp += complements.has(base) ? complements.get(base) : base;\n }\n return comp\n}\n\nclass Chromosome {\n constructor(name, order, bpLength) {\n this.name = name;\n this.order = order;\n this.bpLength = bpLength;\n }\n}\n\n/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2014 Broad Institute\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\nconst splitLines$4 = splitLines$5;\n\nconst reservedProperties$1 = new Set(['fastaURL', 'indexURL', 'cytobandURL', 'indexed']);\n\nclass NonIndexedFasta {\n\n\n constructor(reference) {\n\n this.fastaURL = reference.fastaURL;\n this.withCredentials = reference.withCredentials;\n this.chromosomeNames = [];\n this.chromosomes = {};\n this.sequences = new Map();\n\n // Build a track-like config object from the referenceObject\n const config = {};\n for (let key in reference) {\n if (reference.hasOwnProperty(key) && !reservedProperties$1.has(key)) {\n config[key] = reference[key];\n }\n }\n this.config = config;\n }\n\n\n async init() {\n return this.loadAll()\n }\n\n async getSequence(chr, start, end) {\n\n if (!this.sequences.has(chr)) {\n return undefined\n }\n\n let seqSlice = this.sequences.get(chr).find(ss => ss.contains(start, end));\n if (!seqSlice) {\n seqSlice = this.sequences.get(chr).find(ss => ss.overlaps(start, end));\n if (!seqSlice) {\n return undefined\n }\n }\n\n start -= seqSlice.offset;\n end -= seqSlice.offset;\n\n let prefix = \"\";\n if (start < 0) {\n for (let i = start; i < Math.min(end, 0); i++) {\n prefix += \"*\";\n }\n }\n\n if (end <= 0) {\n return Promise.resolve(prefix)\n }\n\n const seq = seqSlice.sequence;\n const seqEnd = Math.min(end, seq.length);\n return prefix + seq.substring(start, seqEnd)\n }\n\n async loadAll() {\n\n let data;\n if (isDataURL(this.fastaURL)) {\n let bytes = decodeDataURI$1(this.fastaURL);\n data = \"\";\n for (let b of bytes) {\n data += String.fromCharCode(b);\n }\n } else {\n data = await igvxhr.load(this.fastaURL, buildOptions(this.config));\n }\n\n const chrNameSet = new Set();\n const lines = splitLines$4(data);\n const len = lines.length;\n let lineNo = 0;\n let order = 0;\n let nextLine;\n let current = {};\n while (lineNo < len) {\n nextLine = lines[lineNo++].trim();\n if (nextLine.startsWith(\"#\") || nextLine.length === 0) ; else if (nextLine.startsWith(\">\")) {\n // Start the next sequence\n if(current && current.seq) {\n pushChromosome.call(this, current, order++);\n }\n\n const parts = nextLine.substr(1).split(/\\s+/);\n\n // Check for samtools style locus string. This is not perfect, and could fail on weird sequence names\n const nameParts = parts[0].split(':');\n current.chr = nameParts[0];\n current.seq = \"\";\n current.offset = 0;\n if (nameParts.length > 1 && nameParts[1].indexOf('-') > 0) {\n const locusParts = nameParts[1].split('-');\n if (locusParts.length === 2 &&\n /^[0-9]+$/.test(locusParts[0]) &&\n /^[0-9]+$/.test(locusParts[1])) ;\n const from = Number.parseInt(locusParts[0]);\n const to = Number.parseInt(locusParts[1]);\n if (to > from) { // TODO this should be an error\n current.offset = from - 1;\n }\n\n // Check for chromosome length token\n if (parts.length > 1 && parts[1].startsWith(\"@len=\")) {\n try {\n current.length = parseInt(parts[1].trim().substring(5));\n } catch (e) {\n current.length = undefined;\n console.error(`Error parsing sequence length for ${nextLine}`);\n }\n } else {\n current.length = undefined;\n }\n }\n } else {\n current.seq += nextLine;\n }\n // add last seq\n if (current && current.seq) {\n pushChromosome.call(this, current, order);\n }\n }\n\n function pushChromosome(current, order) {\n const length = current.length || (current.offset + current.seq.length);\n if (!chrNameSet.has(current.chr)) {\n this.chromosomeNames.push(current.chr);\n this.sequences.set(current.chr, []);\n this.chromosomes[current.chr] = new Chromosome(current.chr, order, length);\n chrNameSet.add(current.chr);\n } else {\n const c = this.chromosomes[current.chr];\n c.bpLength = Math.max(c.bpLength, length);\n }\n this.sequences.get(current.chr).push(new SequenceSlice(current.offset, current.seq));\n }\n }\n}\n\nclass SequenceSlice {\n\n constructor(offset, sequence) {\n this.offset = offset;\n this.sequence = sequence;\n }\n\n contains(start, end) {\n return this.offset <= start && this.end >= end\n }\n\n overlaps(start, end) {\n return this.offset < end && this.end > start\n }\n\n get end() {\n return this.offset + this.sequence.length\n }\n\n}\n\nconst GenomicInterval = function (chr, start, end, features) {\n this.chr = chr;\n this.start = start;\n this.end = end;\n this.features = features;\n};\n\nGenomicInterval.prototype.contains = function (chr, start, end) {\n return this.chr === chr &&\n this.start <= start &&\n this.end >= end\n};\n\nGenomicInterval.prototype.containsRange = function (range) {\n return this.chr === range.chr &&\n this.start <= range.start &&\n this.end >= range.end\n};\n\n/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2014 Broad Institute\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\nconst splitLines$3 = splitLines$5;\n\nconst reservedProperties = new Set(['fastaURL', 'indexURL', 'compressedIndexURL', 'cytobandURL', 'indexed']);\n\nclass FastaSequence {\n\n constructor(reference) {\n\n this.file = reference.fastaURL;\n this.indexFile = reference.indexURL || reference.indexFile || this.file + \".fai\";\n this.compressedIndexFile = reference.compressedIndexURL || false;\n this.withCredentials = reference.withCredentials;\n this.chromosomeNames = [];\n this.chromosomes = {};\n this.sequences = {};\n this.offsets = {};\n\n // Build a track-like config object from the referenceObject\n const config = {};\n for (let key in reference) {\n if (reference.hasOwnProperty(key) && !reservedProperties.has(key)) {\n config[key] = reference[key];\n }\n }\n this.config = config;\n }\n\n\n async init() {\n return this.getIndex()\n }\n\n async getSequence(chr, start, end) {\n\n const hasCachedSquence = this.interval && this.interval.contains(chr, start, end);\n\n if (!hasCachedSquence) {\n\n // Expand query, to minimum of 50kb\n let qstart = start;\n let qend = end;\n if ((end - start) < 50000) {\n const w = (end - start);\n const center = Math.round(start + w / 2);\n qstart = Math.max(0, center - 25000);\n qend = center + 25000;\n }\n\n const seqBytes = await this.readSequence(chr, qstart, qend);\n this.interval = new GenomicInterval(chr, qstart, qend, seqBytes);\n }\n\n const offset = start - this.interval.start;\n const n = end - start;\n const seq = this.interval.features ? this.interval.features.substr(offset, n) : null;\n return seq\n }\n\n async getIndex() {\n\n if (this.index) {\n return this.index\n } else {\n const data = await igvxhr.load(this.indexFile, buildOptions(this.config));\n const lines = splitLines$3(data);\n const len = lines.length;\n let lineNo = 0;\n let order = 0;\n this.index = {};\n\n while (lineNo < len) {\n const tokens = lines[lineNo++].split(\"\\t\");\n const nTokens = tokens.length;\n\n if (nTokens === 5) {\n // Parse the index line.\n const chr = tokens[0];\n const size = parseInt(tokens[1]);\n const position = parseInt(tokens[2]);\n const basesPerLine = parseInt(tokens[3]);\n const bytesPerLine = parseInt(tokens[4]);\n\n const indexEntry = {\n size: size,\n position: position,\n basesPerLine: basesPerLine,\n bytesPerLine: bytesPerLine\n };\n\n this.chromosomeNames.push(chr);\n this.index[chr] = indexEntry;\n this.chromosomes[chr] = new Chromosome(chr, order++, size);\n }\n }\n return this.index\n }\n }\n\n\n //Code is losely based on https://github.com/GMOD/bgzf-filehandle\n //Reworked however in orde to work with the igvxhr interface for loading files\n //Additionally, replaced calls to the Long.js interface with standard JS calls for ArrayBuffers and the associated views\n //\n //The compressed index is an array of blocks, with each block being a pair: compressed-position & uncompressed-position (both in bytes)\n async getCompressedIndex() {\n const GZI_NUM_BYTES_OFFSET = 8;\n const GZI_NUM_BYTES_BLOCK = 8;\n if (this.compressedIndex) {\n return this.compressedIndex\n }\n if (!this.compressedIndexFile) {\n this.compressedIndex = [];\n return this.compressedIndex\n }\n //In contrast to the 'normal' reference (for which the index is chromosome based), this index is block-based\n //As such there is not need to make it a hash. An array is sufficient.\n this.compressedIndex = [];\n const gziData = await igvxhr.loadArrayBuffer(this.compressedIndexFile, buildOptions(this.config));\n const givenFileSize = gziData.byteLength;\n if (givenFileSize < GZI_NUM_BYTES_OFFSET) {\n console.log(\"Cannot parse GZI index file: length (\" + givenFileSize + \" bytes) is insufficient to determine content of index.\");\n return this.compressedIndex\n }\n //First 8 bytes are a little endian unsigned bigint (64bit), indicating the number of blocks in the index.\n const numBlocksBuffer = gziData.slice(0, GZI_NUM_BYTES_OFFSET);\n const numBlocks = Number((new DataView(numBlocksBuffer)).getBigUint64(0, true));\n //The remainder of the gzi content are pairs of little endian unsigned bigint (64bit) numbers.\n //The first of the pair is the compressed position of a block\n //The second of the pair is the uncompressed position of a block\n\n //Sanity check:\n //Is the size of the array-buffer (of the entire file) correct with regards to the number of blocks detailled by the first 8 bytes of the file?\n //Total file-size should be:\n // 8 + 2*(num_entries*8) bytes, with the first 8 bytes indicating the number of entries\n const expectedFileSize = GZI_NUM_BYTES_OFFSET + numBlocks * 2 * GZI_NUM_BYTES_BLOCK;\n if (givenFileSize != expectedFileSize) {\n console.log(\"Incorrect file size of reference genome index. Expected : \" + expectedFileSize + \". Received : \" + givenFileSize);\n return this.compressedIndex\n }\n\n //Push the first block to the index: the first block always has positions 0 for both the compressed and uncompressed file\n this.compressedIndex.push([0, 0]);\n\n //Further process all the blocks of the GZI index, and keep them in memory\n for (let blockNumber = 0; blockNumber < numBlocks; blockNumber++) {\n const bufferBlockStart = GZI_NUM_BYTES_OFFSET + blockNumber * 2 * GZI_NUM_BYTES_BLOCK;\n const bufferBlockEnd = GZI_NUM_BYTES_OFFSET + blockNumber * 2 * GZI_NUM_BYTES_BLOCK + 2 * GZI_NUM_BYTES_BLOCK;\n const bufferBlock = gziData.slice(bufferBlockStart, bufferBlockEnd);\n const viewBlock = new DataView(bufferBlock);\n const compressedPosition = Number(viewBlock.getBigUint64(0, true)); //First 8 bytes\n const uncompressedPosition = Number(viewBlock.getBigUint64(GZI_NUM_BYTES_BLOCK, true)); //Last 8 bytes\n this.compressedIndex.push([compressedPosition, uncompressedPosition]);\n }\n return this.compressedIndex\n }\n\n //The Fasta-index gives a byte-position of the chromosomal sequences within the FASTA file.\n //These locations need to be remapped to the locations within the zipped reference genome, using the GZI index\n //This function provides this functionality by \n //1) taking the indicated start/stop byte locations within the UNCOMPRESSED FASTA file\n //2) remapping these byte locations to the correct blocks (and associated positions) within the COMPRESSED FASTA file\n //Subsequently, the calling method can then extract the correct blocks from the compressed FASTA files and uncompressed the data\n async getRelevantCompressedBlockNumbers(queryPositionStart, queryPositionEnd) {\n const UNCOMPRESSED_POSITION = 1;\n //Fallback for impossible values\n if (queryPositionStart < 0 || queryPositionEnd < 0 || queryPositionEnd < queryPositionStart) {\n console.log(\"Incompatible query positions for reference-genome. Start:\" + queryPositionStart + \" | End:\" + queryPositionEnd);\n return []\n }\n //Ensure compressed index is loaded\n await this.getCompressedIndex();\n let result = [];\n //Now search for the correct block-numbers (going from 0 to length(compressed-index)) which overlap with the provided byte-positions\n const lowestBlockNumber = 0;\n const highestBlockNumber = this.compressedIndex.length - 1;\n //Failsafe if for some reason the compressed index wasn't loaded or doesn't contain any data\n if (this.compressedIndex.length == 0) {\n console.log(\"Compressed index does not contain any content\");\n return []\n }\n //Failsafe: if the queryPositionStart is greater than the uncompressed-position of the final block,\n //then this final block is the only possible result\n if (queryPositionStart > (this.compressedIndex)[highestBlockNumber][UNCOMPRESSED_POSITION]) {\n return [highestBlockNumber]\n }\n\n //Rather than doing a linear search over all blocks, a binary search is done for speed considerations\n //We are searching for the highest block number for which its position is smaller than the query start position\n //Afterwards we will simply expand the blocks until the entire query range is covered\n let searchLow = lowestBlockNumber;\n let searchHigh = highestBlockNumber;\n let searchPosition = Math.floor(this.compressedIndex.length / 2);\n let maxIterations = this.compressedIndex.length + 1;\n let solutionFound = false;\n //instead of doing a while(true), this for-loop prevents eternal loops in case of issues\n for (let iteration = 0; iteration < maxIterations; iteration++) {\n const searchUncompressedPosition = (this.compressedIndex)[searchPosition][UNCOMPRESSED_POSITION];\n const nextSearchUncompressedPosition = (searchPosition < (this.compressedIndex.length - 1)) ? (this.compressedIndex)[searchPosition + 1][UNCOMPRESSED_POSITION] : Infinity;\n //The query position lies within the current search block\n if (searchUncompressedPosition <= queryPositionStart && nextSearchUncompressedPosition > queryPositionStart) {\n solutionFound = true;\n break //searchPosition is the correct block number index\n }\n //Current block lies before the query position\n else if (searchUncompressedPosition < queryPositionStart) {\n searchLow = searchPosition + 1;\n }\n //Current block lies after the query position\n else {\n searchHigh = searchPosition - 1;\n }\n searchPosition = Math.ceil((searchHigh - searchLow) / 2) + searchLow;\n }\n //If for some reason the binary search did not reveal a correct block index, then we return the empty result\n if (!solutionFound) {\n console.log(\"No blocks within compressed index found that correspond with query positions \" + queryPositionStart + \",\" + queryPositionEnd);\n console.log(this.compressedIndex);\n return []\n }\n\n //Now extend the result by adding additional blocks until the entire query range is covered\n result.push(searchPosition);\n for (let blockIndex = searchPosition + 1; blockIndex < this.compressedIndex.length; blockIndex++) {\n result.push(blockIndex);\n const blockUncompressedPosition = (this.compressedIndex)[blockIndex][UNCOMPRESSED_POSITION];\n if (blockUncompressedPosition >= queryPositionEnd) {\n break\n }\n }\n\n //It is possible that the query end position lies AFTER the start of the final block\n //If this is the case, we add a 'fake' negative index which will be interpreted by the loadAndUncompressBlocks method as an indicator\n //to read until the end of the file \n const finalRelevantBlock = result[result.length - 1];\n const finalIndexBlock = this.compressedIndex.length - 1;\n if (finalRelevantBlock === finalIndexBlock && (this.compressedIndex)[finalRelevantBlock][UNCOMPRESSED_POSITION] < queryPositionEnd) {\n result.push(-1);\n }\n\n return result\n }\n\n\n //Load the content from the blockIndices.\n //This is done on a per-block basis\n //Content of the first block will be trimmed in order to match the expected offset\n async loadAndUncompressBlocks(blockIndices, startByte) {\n const COMPRESSED_POSITION = 0;\n const UNCOMPRESSED_POSITION = 1;\n //Normally the compressed index should already exist, we're just makeing sure here\n await this.getCompressedIndex();\n\n if (blockIndices.length == 0) {\n return \"\"\n }\n\n //Storing data in seperate array with indices in order to assert order due to async behaviour of loops\n let resultCache = Array(blockIndices.length - 1);\n for (let i = 0; i < blockIndices.length - 1; i++) {\n const currentBlockNumber = blockIndices[i];\n const currentBlockInfo = (this.compressedIndex)[currentBlockNumber];\n const currentBlockCompressedPosition = currentBlockInfo[COMPRESSED_POSITION];\n\n const nextBlockNumber = blockIndices[i + 1];\n let compressedBytes = [];\n if (nextBlockNumber != -1) { //default : read current entire block only\n const nextBlockInfo = (this.compressedIndex)[nextBlockNumber];\n const nextBlockCompressedPosition = nextBlockInfo[COMPRESSED_POSITION];\n const compressedLength = nextBlockCompressedPosition - currentBlockCompressedPosition;\n compressedBytes = await igvxhr.loadArrayBuffer(this.file, buildOptions(this.config, {\n range: {\n start: currentBlockCompressedPosition,\n size: compressedLength\n }\n }));\n } else { // special case for query within final block: read until the end of the file\n compressedBytes = await igvxhr.loadArrayBuffer(this.file, buildOptions(this.config, {\n range: {\n start: currentBlockCompressedPosition\n }\n }));\n }\n //now unzip the compressed bytes, and store them in the resultCache\n const uncompressedBytes = await unbgzf(compressedBytes);\n resultCache[i] = uncompressedBytes;\n }\n\n //Iterate over the result cache, create sequences from the data, and create a full sequence string from the data\n let result = \"\";\n for (let i = 0; i < resultCache.length; i++) {\n for (let j = 0; j < resultCache[i].length; j++) {\n const c = String.fromCharCode(resultCache[i][j]);\n result = result + c;\n }\n }\n\n //postprocess this data: because entire blocks are read we need to remove the first N bases of the first used block, \n //which are not included in the original query positions\n const firstBlockInfo = (this.compressedIndex)[blockIndices[0]];\n const offset = startByte - firstBlockInfo[UNCOMPRESSED_POSITION];\n result = result.substring(offset);\n\n return result\n }\n\n\n async readSequence(chr, qstart, qend) {\n\n await this.getIndex();\n await this.getCompressedIndex(); //This will work even if no compressed index file is set\n\n const idxEntry = this.index[chr];\n if (!idxEntry) {\n console.log(\"No index entry for chr: \" + chr);\n // Tag interval with null so we don't try again\n this.interval = new GenomicInterval(chr, qstart, qend, null);\n return null\n }\n\n const start = Math.max(0, qstart); // qstart should never be < 0\n const end = Math.min(idxEntry.size, qend);\n const bytesPerLine = idxEntry.bytesPerLine;\n const basesPerLine = idxEntry.basesPerLine;\n const position = idxEntry.position;\n const nEndBytes = bytesPerLine - basesPerLine;\n const startLine = Math.floor(start / basesPerLine);\n const endLine = Math.floor(end / basesPerLine);\n const base0 = startLine * basesPerLine; // Base at beginning of start line\n const offset = start - base0;\n const startByte = position + startLine * bytesPerLine + offset;\n const base1 = endLine * basesPerLine;\n const offset1 = end - base1;\n const endByte = position + endLine * bytesPerLine + offset1 - 1;\n const byteCount = endByte - startByte + 1;\n\n if (byteCount <= 0) {\n console.error(\"No sequence for \" + chr + \":\" + qstart + \"-\" + qend);\n return null\n }\n\n //If the compressed index file is set, then we are dealing with a compressed genome sequence\n //The selection of startByte/endByte is done for the non-compressed genome sequence.\n //These need to be 'converted' to the correct byte positions in the compressed genome sequence,\n //by making use of the compressed index (GZI file)\n let allBytes;\n if (!this.compressedIndexFile) {\n allBytes = await igvxhr.load(this.file, buildOptions(this.config, {\n range: {\n start: startByte,\n size: byteCount\n }\n }));\n } else {\n let relevantBlockIndices = await this.getRelevantCompressedBlockNumbers(startByte, endByte);\n if (relevantBlockIndices.length === 0) {\n console.log(\"No blocks in the compressed index that correspond with the requested byte positions (\" + startByte + \",\" + endByte + \")\");\n return null\n }\n allBytes = await this.loadAndUncompressBlocks(relevantBlockIndices, startByte);\n }\n\n if (!allBytes) {\n return null\n }\n\n let nBases,\n seqBytes = \"\",\n srcPos = 0,\n allBytesLength = allBytes.length;\n\n if (offset > 0) {\n nBases = Math.min(end - start, basesPerLine - offset);\n seqBytes += allBytes.substr(srcPos, nBases);\n srcPos += (nBases + nEndBytes);\n }\n\n while (srcPos < allBytesLength) {\n nBases = Math.min(basesPerLine, allBytesLength - srcPos);\n seqBytes += allBytes.substr(srcPos, nBases);\n srcPos += (nBases + nEndBytes);\n }\n\n return seqBytes\n\n }\n}\n\n/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2014 Broad Institute\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\nconst splitLines$2 = splitLines$5;\n\nclass ChromSizes {\n\n\n constructor(url) {\n this.url = url;\n this.chromosomeNames = [];\n this.chromosomes = {};\n }\n\n\n async init() {\n return this.loadAll()\n }\n\n async getSequence(chr, start, end) {\n\n return undefined // TODO -- return array of \"N\"s?\n }\n\n async loadAll() {\n\n let data;\n if (isDataURL(this.url)) {\n let bytes = decodeDataURI$1(this.fastaURL);\n data = \"\";\n for (let b of bytes) {\n data += String.fromCharCode(b);\n }\n } else {\n data = await igvxhr.load(this.url, {});\n }\n\n\n this.chromosomeNames = [];\n this.chromosomes = {};\n\n const lines = splitLines$2(data);\n let order = 0;\n for (let nextLine of lines) {\n const tokens = nextLine.split('\\t');\n this.chromosomeNames.push(tokens[0]);\n const chrLength = Number.parseInt(tokens[1]);\n const chromosome = new Chromosome(tokens[0], order++, chrLength);\n this.chromosomes[tokens[0]] = chromosome;\n\n }\n }\n\n}\n\nasync function loadFasta(reference) {\n\n let fasta;\n if (\"chromsizes\" === reference.format) {\n fasta = new ChromSizes(reference.fastaURL);\n } else if (isDataURL(reference.fastaURL) || reference.indexed === false) {\n fasta = new NonIndexedFasta(reference);\n } else {\n fasta = new FastaSequence(reference);\n }\n await fasta.init();\n return fasta\n}\n\nconst defaultNucleotideColors = {\n \"A\": \"rgb( 0, 200, 0)\",\n \"C\": \"rgb( 0,0,200)\",\n \"T\": \"rgb(255,0,0)\",\n \"G\": \"rgb(209,113, 5)\",\n \"N\": \"rgb(80,80,80)\"\n};\n\n/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2014 Broad Institute\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\nconst defaultSequenceTrackOrder = Number.MIN_SAFE_INTEGER;\n\nconst translationDict = {\n 'TTT': 'F',\n 'TTC': 'F',\n 'TTA': 'L',\n 'TTG': 'L',\n 'CTT': 'L',\n 'CTC': 'L',\n 'CTA': 'L',\n 'CTG': 'L',\n 'ATT': 'I',\n 'ATC': 'I',\n 'ATA': 'I',\n 'ATG': 'M',\n 'GTT': 'V',\n 'GTC': 'V',\n 'GTA': 'V',\n 'GTG': 'V',\n 'TCT': 'S',\n 'TCC': 'S',\n 'TCA': 'S',\n 'TCG': 'S',\n 'CCT': 'P',\n 'CCC': 'P',\n 'CCA': 'P',\n 'CCG': 'P',\n 'ACT': 'T',\n 'ACC': 'T',\n 'ACA': 'T',\n 'ACG': 'T',\n 'GCT': 'A',\n 'GCC': 'A',\n 'GCA': 'A',\n 'GCG': 'A',\n 'TAT': 'Y',\n 'TAC': 'Y',\n 'TAA': 'STOP',\n 'TAG': 'STOP',\n 'CAT': 'H',\n 'CAC': 'H',\n 'CAA': 'Q',\n 'CAG': 'Q',\n 'AAT': 'N',\n 'AAC': 'N',\n 'AAA': 'K',\n 'AAG': 'K',\n 'GAT': 'D',\n 'GAC': 'D',\n 'GAA': 'E',\n 'GAG': 'E',\n 'TGT': 'C',\n 'TGC': 'C',\n 'TGA': 'STOP',\n 'TGG': 'W',\n 'CGT': 'R',\n 'CGC': 'R',\n 'CGA': 'R',\n 'CGG': 'R',\n 'AGT': 'S',\n 'AGC': 'S',\n 'AGA': 'R',\n 'AGG': 'R',\n 'GGT': 'G',\n 'GGC': 'G',\n 'GGA': 'G',\n 'GGG': 'G'\n};\n\nconst complement = {};\nconst t1 = ['A', 'G', 'C', 'T', 'Y', 'R', 'W', 'S', 'K', 'M', 'D', 'V', 'H', 'B', 'N', 'X'];\nconst t2 = ['T', 'C', 'G', 'A', 'R', 'Y', 'W', 'S', 'M', 'K', 'H', 'B', 'D', 'V', 'N', 'X'];\nfor (let i = 0; i < t1.length; i++) {\n complement[t1[i]] = t2[i];\n complement[t1[i].toLowerCase()] = t2[i].toLowerCase();\n}\n\nconst DEFAULT_HEIGHT = 25;\nconst TRANSLATED_HEIGHT = 115;\nconst SEQUENCE_HEIGHT = 15;\nconst FRAME_HEIGHT = 25;\nconst FRAME_BORDER = 5;\nconst BP_PER_PIXEL_THRESHOLD = 1 / 10;\n\nconst bppFeatureFetchThreshold = 10;\n\nclass SequenceTrack {\n\n constructor(config, browser) {\n\n this.config = config;\n this.browser = browser;\n this.type = \"sequence\";\n this.removable = config.removable === undefined ? true : config.removable; // Defaults to true\n this.name = config.name;\n this.id = config.id;\n this.sequenceType = config.sequenceType || \"dna\"; // dna | rna | prot\n this.disableButtons = false;\n this.order = config.order || defaultSequenceTrackOrder;\n this.ignoreTrackMenu = false;\n\n this.reversed = config.reversed === true;\n this.frameTranslate = config.frameTranslate === true;\n this.height = this.frameTranslate ? TRANSLATED_HEIGHT : DEFAULT_HEIGHT;\n\n // Hack for backward compatibility\n if(config.url) {\n config.fastaURL = config.url;\n }\n\n if(!config.fastaURL) {\n // Mark this as the genome reference sequence ==> backward compatibility convention\n this.id = config.id || \"sequence\";\n }\n\n }\n\n menuItemList() {\n return [\n {\n name: this.reversed ? \"Forward\" : \"Reverse\",\n click: () => {\n this.reversed = !this.reversed;\n this.trackView.repaintViews();\n }\n },\n {\n name: this.frameTranslate ? \"Close Translation\" : \"Three-frame Translate\",\n click: () => {\n this.frameTranslate = !this.frameTranslate;\n if (this.frameTranslate) {\n for (let vp of this.trackView.viewports) {\n vp.setContentHeight(TRANSLATED_HEIGHT);\n }\n this.trackView.setTrackHeight(TRANSLATED_HEIGHT);\n } else {\n for (let vp of this.trackView.viewports) {\n vp.setContentHeight(DEFAULT_HEIGHT);\n }\n this.trackView.setTrackHeight(DEFAULT_HEIGHT);\n }\n this.trackView.repaintViews();\n\n }\n }\n ]\n }\n\n contextMenuItemList(clickState) {\n const viewport = clickState.viewport;\n if (viewport.referenceFrame.bpPerPixel <= 1) {\n const pixelWidth = viewport.getWidth();\n const bpWindow = pixelWidth * viewport.referenceFrame.bpPerPixel;\n const chr = viewport.referenceFrame.chr;\n const start = Math.floor(viewport.referenceFrame.start);\n const end = Math.ceil(start + bpWindow);\n const items = [\n {\n label: this.reversed ? 'View visible sequence (reversed)...' : 'View visible sequence...',\n click: async () => {\n let seq = await this.browser.genome.sequence.getSequence(chr, start, end);\n if (!seq) {\n seq = \"Unknown sequence\";\n } else if (this.reversed) {\n seq = reverseComplementSequence(seq);\n }\n this.browser.alert.present(seq);\n }\n }\n ];\n if (isSecureContext()) {\n items.push({\n label: 'Copy visible sequence',\n click: async () => {\n let seq = await this.browser.genome.sequence.getSequence(chr, start, end);\n if (!seq) {\n seq = \"Unknown sequence\";\n } else if (this.reversed) {\n seq = reverseComplementSequence(seq);\n }\n try {\n await navigator.clipboard.writeText(seq);\n } catch (e) {\n console.error(e);\n this.browser.alert.present(`error copying sequence to clipboard ${e}`);\n }\n }\n\n });\n }\n items.push('
');\n\n return items\n } else {\n return undefined\n }\n }\n\n translateSequence(seq) {\n\n const threeFrame = [[], [], []];\n\n for (let fNum of [0, 1, 2]) {\n let idx = fNum;\n\n while ((seq.length - idx) >= 3) {\n let st = seq.slice(idx, idx + 3);\n if (this.reversed) {\n st = st.split('').reverse().join('');\n }\n\n const aa = translationDict[st.toUpperCase()] || \"\";\n threeFrame[fNum].push({\n codons: st,\n aminoA: aa\n });\n idx += 3;\n }\n }\n\n return threeFrame\n }\n\n /**\n * Return the source for sequence. If an explicit fasta url is defined, use it, otherwise fetch sequence\n * from the current genome\n * *\n * @returns {Promise}\n */\n async getSequenceSource() {\n if(this.config.fastaURL) {\n if(!this.fasta) {\n this.fasta = new WrappedFasta(this.config, this.browser.genome);\n await this.fasta.init();\n }\n return this.fasta\n } else {\n return this.browser.genome.sequence\n }\n }\n\n async getFeatures(chr, start, end, bpPerPixel) {\n\n start = Math.floor(start);\n end = Math.floor(end);\n\n if (bpPerPixel && bpPerPixel > bppFeatureFetchThreshold) {\n return null\n } else {\n const sequenceSource = await this.getSequenceSource();\n const sequence = await sequenceSource.getSequence(chr, start, end);\n return {\n bpStart: start,\n sequence: sequence\n }\n }\n }\n\n draw(options) {\n\n const ctx = options.context;\n\n if (options.features) {\n\n let sequence = options.features.sequence;\n if(!sequence) {\n return\n }\n\n if (this.reversed) {\n sequence = sequence.split('').map(function (cv) {\n return complement[cv]\n }).join('');\n }\n\n const sequenceBpStart = options.features.bpStart; // genomic position at start of sequence\n const bpEnd = 1 + options.bpStart + (options.pixelWidth * options.bpPerPixel);\n\n for (let bp = Math.floor(options.bpStart); bp <= bpEnd; bp++) {\n\n const seqIdx = Math.floor(bp - sequenceBpStart);\n\n if (seqIdx >= 0 && seqIdx < sequence.length) {\n\n const offsetBP = bp - options.bpStart;\n const aPixel = offsetBP / options.bpPerPixel;\n const pixelWidth = 1 / options.bpPerPixel;\n const baseLetter = sequence[seqIdx];\n const color = this.fillColor(baseLetter.toUpperCase());\n\n if (options.bpPerPixel > BP_PER_PIXEL_THRESHOLD) {\n IGVGraphics.fillRect(ctx, aPixel, FRAME_BORDER, pixelWidth, SEQUENCE_HEIGHT - FRAME_BORDER, {fillStyle: color});\n } else {\n const textPixel = aPixel + 0.5 * (pixelWidth - ctx.measureText(baseLetter).width);\n\n\n\n\n if ('y' === options.axis) {\n ctx.save();\n IGVGraphics.labelTransformWithContext(ctx, textPixel);\n IGVGraphics.strokeText(ctx, baseLetter, textPixel, SEQUENCE_HEIGHT, {strokeStyle: color});\n ctx.restore();\n } else {\n IGVGraphics.strokeText(ctx, baseLetter, textPixel, SEQUENCE_HEIGHT, {strokeStyle: color});\n }\n\n }\n }\n }\n\n if (this.frameTranslate) {\n\n let y = SEQUENCE_HEIGHT + 2 * FRAME_BORDER;\n const translatedSequence = this.translateSequence(sequence);\n\n for (let fNum = 0; fNum < translatedSequence.length; fNum++) { // == 3, 1 for each frame\n\n const aaSequence = translatedSequence[fNum]; // AA sequence for this frame\n\n for (let idx = 0; idx < aaSequence.length; idx++) {\n\n let color = 0 === idx % 2 ? 'rgb(160,160,160)' : 'rgb(224,224,224)';\n const cv = aaSequence[idx];\n\n const bpPos = sequenceBpStart + fNum + (idx * 3);\n const bpOffset = bpPos - options.bpStart;\n const p0 = Math.floor(bpOffset / options.bpPerPixel);\n const p1 = Math.floor((bpOffset + 3) / options.bpPerPixel);\n const pc = Math.round((p0 + p1) / 2);\n\n if (p1 < 0) {\n continue // off left edge\n } else if (p0 > options.pixelWidth) {\n break // off right edge\n }\n\n let aaLabel = cv.aminoA;\n if (cv.aminoA.indexOf('STOP') > -1) {\n color = 'rgb(255, 0, 0)';\n aaLabel = 'STOP'; //Color blind accessible\n } else if (cv.aminoA === 'M') {\n color = 'rgb(0, 153, 0)';\n aaLabel = 'START'; //Color blind accessible\n }\n\n IGVGraphics.fillRect(ctx, p0, y, p1 - p0, FRAME_HEIGHT, {fillStyle: color});\n\n if (options.bpPerPixel <= 1 / 10) {\n IGVGraphics.strokeText(ctx, aaLabel, pc - (ctx.measureText(aaLabel).width / 2), y + 15);\n }\n }\n y += (FRAME_HEIGHT + FRAME_BORDER);\n }\n }\n }\n }\n\n get supportsWholeGenome() {\n return false\n }\n\n computePixelHeight(ignore) {\n this.height = this.frameTranslate ? TRANSLATED_HEIGHT : DEFAULT_HEIGHT;\n return this.height\n }\n\n fillColor(index) {\n\n if (this.color) {\n return this.color\n } else if (\"dna\" === this.sequenceType) {\n // return this.browser.nucleotideColors[index] || 'gray'\n return defaultNucleotideColors[index] || 'gray'\n } else {\n return 'rgb(0, 0, 150)'\n }\n }\n\n /**\n * Return the current state of the track. Used to create sessions and bookmarks.\n *\n * @returns {*|{}}\n */\n getState() {\n const config = {\n type: \"sequence\"\n };\n if (this.order !== defaultSequenceTrackOrder) {\n config.order = this.order;\n }\n if (this.reversed) {\n config.revealed = true;\n }\n return config\n }\n\n}\n\n/**\n * Wrapper for a Fasta object that does chr name alias translation. This is not neccessary for the genome fasta,\n * as it defines the reference name, but can be neccessary if loading an additional fasta as a track\n *\n */\nclass WrappedFasta {\n\n constructor(config, genome) {\n this.config = config;\n this.genome = genome;\n }\n\n async init() {\n this.fasta = await loadFasta(this.config);\n this.chrNameMap = new Map();\n for(let name of this.fasta.chromosomeNames) {\n this.chrNameMap.set(this.genome.getChromosomeName(name), name);\n }\n }\n\n async getSequence(chr, start, end) {\n const chrName = this.chrNameMap.has(chr) ? this.chrNameMap.get(chr) : chr;\n return this.fasta.getSequence(chrName, start, end)\n }\n\n}\n\n/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2014 Broad Institute\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\nclass Viewport {\n\n constructor(trackView, viewportColumn, referenceFrame, width) {\n\n this.guid = domUtils.guid();\n this.trackView = trackView;\n this.referenceFrame = referenceFrame;\n\n this.browser = trackView.browser;\n\n this.$viewport = $$1('
');\n viewportColumn.appendChild(this.$viewport.get(0));\n\n if (trackView.track.height) {\n this.$viewport.get(0).style.height = `${trackView.track.height}px`;\n }\n\n // Create an alert dialog for the sequence track to copy ref sequence to.\n if (trackView.track instanceof SequenceTrack) {\n this.alert = new AlertDialog(this.$viewport.get(0));\n }\n\n this.contentTop = 0;\n this.contentHeight = this.$viewport.height();\n\n\n this.$viewport.width(width);\n\n this.initializationHelper();\n\n }\n\n initializationHelper() {\n\n }\n\n showMessage(message) {\n if (!this.messageDiv) {\n this.messageDiv = document.createElement('div');\n this.messageDiv.className = 'igv-viewport-message';\n //this.contentDiv.append(this.messageDiv)\n this.$viewport.append($$1(this.messageDiv));\n }\n this.messageDiv.textContent = message;\n this.messageDiv.style.display = 'inline-block';\n }\n\n hideMessage(message) {\n if (this.messageDiv)\n this.messageDiv.style.display = 'none';\n }\n\n setTrackLabel(label) {\n }\n\n startSpinner() {\n }\n\n stopSpinner() {\n }\n\n checkZoomIn() {\n return true\n }\n\n shift() {\n }\n\n setTop(contentTop) {\n\n this.contentTop = contentTop;\n this.$viewport.height();\n\n //this.$content.css('top', `${contentTop}px`)\n //\n // if (undefined === this.canvasVerticalRange || this.canvasVerticalRange.bottom < viewBottom || this.canvasVerticalRange.top > viewTop) {\n // console.log(\"Repaint \" + this.canvasVerticalRange)\n // this.repaint()\n // }\n\n }\n\n async loadFeatures() {\n return undefined\n }\n\n clearCache() {\n\n }\n\n async repaint() {\n }\n\n draw(drawConfiguration, features, roiFeatures) {\n console.log('Viewport - draw(drawConfiguration, features, roiFeatures)');\n }\n\n checkContentHeight(features) {\n\n let track = this.trackView.track;\n features = features || this.cachedFeatures;\n if (\"FILL\" === track.displayMode) {\n this.setContentHeight(this.$viewport.height());\n } else if (typeof track.computePixelHeight === 'function') {\n if (features && features.length > 0) {\n let requiredContentHeight = track.computePixelHeight(features);\n //let currentContentHeight = this.$content.height()\n let currentContentHeight = this.contentHeight;\n if (requiredContentHeight !== currentContentHeight) {\n this.setContentHeight(requiredContentHeight);\n }\n }\n }\n }\n\n getContentHeight() {\n //return this.$content.height()\n return this.contentHeight\n }\n\n setContentHeight(contentHeight) {\n this.contentHeight = contentHeight;\n }\n\n isLoading() {\n return false\n }\n\n saveSVG() {\n\n }\n\n isVisible() {\n return this.$viewport.width()\n }\n\n setWidth(width) {\n this.$viewport.width(width);\n }\n\n getWidth() {\n return this.$viewport.width()\n }\n\n getContentTop() {\n return this.contentTop\n }\n\n containsPosition(chr, position) {\n console.log('Viewport - containsPosition(chr, position)');\n }\n\n addMouseHandlers() {\n }\n\n removeMouseHandlers() {\n }\n\n /**\n * Called when the associated track is removed. Do any needed cleanup here.\n */\n dispose() {\n\n if (this.popover) {\n this.popover.dispose();\n }\n\n this.$viewport.get(0).remove();\n\n // Null out all properties -- this should not be neccessary, but just in case there is a\n // reference to self somewhere we want to free memory.\n for (let key of Object.keys(this)) {\n this[key] = undefined;\n }\n }\n\n}\n\n/*!!\n * Canvas 2 Svg v1.0.19\n * A low level canvas to SVG converter. Uses a mock canvas context to build an SVG document.\n *\n * Licensed under the MIT license:\n * http://www.opensource.org/licenses/mit-license.php\n *\n * Author:\n * Kerry Liu\n *\n * Copyright (c) 2014 Gliffy Inc.\n */\n\n//helper function to format a string\nfunction format(str, args) {\n var keys = Object.keys(args), i;\n for (i = 0; i < keys.length; i++) {\n str = str.replace(new RegExp(\"\\\\{\" + keys[i] + \"\\\\}\", \"gi\"), args[keys[i]]);\n }\n return str\n}\n\n//helper function that generates a random string\nfunction randomString(holder) {\n var chars, randomstring, i;\n if (!holder) {\n throw new Error(\"cannot create a random attribute name for an undefined object\")\n }\n chars = \"ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz\";\n randomstring = \"\";\n do {\n randomstring = \"\";\n for (i = 0; i < 12; i++) {\n randomstring += chars[Math.floor(Math.random() * chars.length)];\n }\n } while (holder[randomstring])\n return randomstring\n}\n\n//helper function to map named to numbered entities\nfunction createNamedToNumberedLookup(items, radix) {\n var i, entity, lookup = {}, base10;\n items = items.split(',');\n radix = radix || 10;\n // Map from named to numbered entities.\n for (i = 0; i < items.length; i += 2) {\n entity = '&' + items[i + 1] + ';';\n base10 = parseInt(items[i], radix);\n lookup[entity] = '&#' + base10 + ';';\n }\n //FF and IE need to create a regex from hex values ie   == \\xa0\n lookup[\"\\\\xa0\"] = ' ';\n return lookup\n}\n\n//helper function to map canvas-textAlign to svg-textAnchor\nfunction getTextAnchor(textAlign) {\n //TODO: support rtl languages\n var mapping = {\"left\": \"start\", \"right\": \"end\", \"center\": \"middle\", \"start\": \"start\", \"end\": \"end\"};\n return mapping[textAlign] || mapping.start\n}\n\n//helper function to map canvas-textBaseline to svg-dominantBaseline\nfunction getDominantBaseline(textBaseline) {\n //INFO: not supported in all browsers\n var mapping = {\n \"alphabetic\": \"alphabetic\",\n \"hanging\": \"hanging\",\n \"top\": \"text-before-edge\",\n \"bottom\": \"text-after-edge\",\n \"middle\": \"central\"\n };\n return mapping[textBaseline] || mapping.alphabetic\n}\n\n\n/**\n * Return a new normalized vector of given vector\n */\nfunction normalize(vector) {\n var len = Math.sqrt(vector[0] * vector[0] + vector[1] * vector[1]);\n return [vector[0] / len, vector[1] / len]\n}\n\n\nfunction intersectRect(rect1, rect2) {\n return (rect1.x < rect2.x + rect2.width &&\n rect1.x + rect1.width > rect2.x &&\n rect1.y < rect2.y + rect2.height &&\n rect1.y + rect1.height > rect2.y)\n}\n\n\n// Unpack entities lookup where the numbers are in radix 32 to reduce the size\n// entity mapping courtesy of tinymce\nconst namedEntities = createNamedToNumberedLookup(\n '50,nbsp,51,iexcl,52,cent,53,pound,54,curren,55,yen,56,brvbar,57,sect,58,uml,59,copy,' +\n '5a,ordf,5b,laquo,5c,not,5d,shy,5e,reg,5f,macr,5g,deg,5h,plusmn,5i,sup2,5j,sup3,5k,acute,' +\n '5l,micro,5m,para,5n,middot,5o,cedil,5p,sup1,5q,ordm,5r,raquo,5s,frac14,5t,frac12,5u,frac34,' +\n '5v,iquest,60,Agrave,61,Aacute,62,Acirc,63,Atilde,64,Auml,65,Aring,66,AElig,67,Ccedil,' +\n '68,Egrave,69,Eacute,6a,Ecirc,6b,Euml,6c,Igrave,6d,Iacute,6e,Icirc,6f,Iuml,6g,ETH,6h,Ntilde,' +\n '6i,Ograve,6j,Oacute,6k,Ocirc,6l,Otilde,6m,Ouml,6n,times,6o,Oslash,6p,Ugrave,6q,Uacute,' +\n '6r,Ucirc,6s,Uuml,6t,Yacute,6u,THORN,6v,szlig,70,agrave,71,aacute,72,acirc,73,atilde,74,auml,' +\n '75,aring,76,aelig,77,ccedil,78,egrave,79,eacute,7a,ecirc,7b,euml,7c,igrave,7d,iacute,7e,icirc,' +\n '7f,iuml,7g,eth,7h,ntilde,7i,ograve,7j,oacute,7k,ocirc,7l,otilde,7m,ouml,7n,divide,7o,oslash,' +\n '7p,ugrave,7q,uacute,7r,ucirc,7s,uuml,7t,yacute,7u,thorn,7v,yuml,ci,fnof,sh,Alpha,si,Beta,' +\n 'sj,Gamma,sk,Delta,sl,Epsilon,sm,Zeta,sn,Eta,so,Theta,sp,Iota,sq,Kappa,sr,Lambda,ss,Mu,' +\n 'st,Nu,su,Xi,sv,Omicron,t0,Pi,t1,Rho,t3,Sigma,t4,Tau,t5,Upsilon,t6,Phi,t7,Chi,t8,Psi,' +\n 't9,Omega,th,alpha,ti,beta,tj,gamma,tk,delta,tl,epsilon,tm,zeta,tn,eta,to,theta,tp,iota,' +\n 'tq,kappa,tr,lambda,ts,mu,tt,nu,tu,xi,tv,omicron,u0,pi,u1,rho,u2,sigmaf,u3,sigma,u4,tau,' +\n 'u5,upsilon,u6,phi,u7,chi,u8,psi,u9,omega,uh,thetasym,ui,upsih,um,piv,812,bull,816,hellip,' +\n '81i,prime,81j,Prime,81u,oline,824,frasl,88o,weierp,88h,image,88s,real,892,trade,89l,alefsym,' +\n '8cg,larr,8ch,uarr,8ci,rarr,8cj,darr,8ck,harr,8dl,crarr,8eg,lArr,8eh,uArr,8ei,rArr,8ej,dArr,' +\n '8ek,hArr,8g0,forall,8g2,part,8g3,exist,8g5,empty,8g7,nabla,8g8,isin,8g9,notin,8gb,ni,8gf,prod,' +\n '8gh,sum,8gi,minus,8gn,lowast,8gq,radic,8gt,prop,8gu,infin,8h0,ang,8h7,and,8h8,or,8h9,cap,8ha,cup,' +\n '8hb,int,8hk,there4,8hs,sim,8i5,cong,8i8,asymp,8j0,ne,8j1,equiv,8j4,le,8j5,ge,8k2,sub,8k3,sup,8k4,' +\n 'nsub,8k6,sube,8k7,supe,8kl,oplus,8kn,otimes,8l5,perp,8m5,sdot,8o8,lceil,8o9,rceil,8oa,lfloor,8ob,' +\n 'rfloor,8p9,lang,8pa,rang,9ea,loz,9j0,spades,9j3,clubs,9j5,hearts,9j6,diams,ai,OElig,aj,oelig,b0,' +\n 'Scaron,b1,scaron,bo,Yuml,m6,circ,ms,tilde,802,ensp,803,emsp,809,thinsp,80c,zwnj,80d,zwj,80e,lrm,' +\n '80f,rlm,80j,ndash,80k,mdash,80o,lsquo,80p,rsquo,80q,sbquo,80s,ldquo,80t,rdquo,80u,bdquo,810,dagger,' +\n '811,Dagger,81g,permil,81p,lsaquo,81q,rsaquo,85c,euro', 32);\n\n\n//Some basic mappings for attributes and default values.\nconst STYLES = {\n \"strokeStyle\": {\n svgAttr: \"stroke\", //corresponding svg attribute\n canvas: \"#000000\", //canvas default\n svg: \"none\", //svg default\n apply: \"stroke\" //apply on stroke() or fill()\n },\n \"fillStyle\": {\n svgAttr: \"fill\",\n canvas: \"#000000\",\n svg: null, //svg default is black, but we need to special case this to handle canvas stroke without fill\n apply: \"fill\"\n },\n \"lineCap\": {\n svgAttr: \"stroke-linecap\",\n canvas: \"butt\",\n svg: \"butt\",\n apply: \"stroke\"\n },\n \"lineJoin\": {\n svgAttr: \"stroke-linejoin\",\n canvas: \"miter\",\n svg: \"miter\",\n apply: \"stroke\"\n },\n \"miterLimit\": {\n svgAttr: \"stroke-miterlimit\",\n canvas: 10,\n svg: 4,\n apply: \"stroke\"\n },\n \"lineWidth\": {\n svgAttr: \"stroke-width\",\n canvas: 1,\n svg: 1,\n apply: \"stroke\"\n },\n \"globalAlpha\": {\n svgAttr: \"opacity\",\n canvas: 1,\n svg: 1,\n apply: \"fill stroke\"\n },\n \"font\": {\n //font converts to multiple svg attributes, there is custom logic for this\n canvas: \"10px sans-serif\"\n },\n \"shadowColor\": {\n canvas: \"#000000\"\n },\n \"shadowOffsetX\": {\n canvas: 0\n },\n \"shadowOffsetY\": {\n canvas: 0\n },\n \"shadowBlur\": {\n canvas: 0\n },\n \"textAlign\": {\n canvas: \"start\"\n },\n \"textBaseline\": {\n canvas: \"alphabetic\"\n },\n \"lineDash\": {\n svgAttr: \"stroke-dasharray\",\n canvas: [],\n svg: null,\n apply: \"stroke\"\n }\n};\n\n/**\n *\n * @param gradientNode - reference to the gradient\n * @constructor\n */\nclass CanvasGradient {\n constructor(gradientNode, ctx) {\n this.__root = gradientNode;\n this.__ctx = ctx;\n }\n\n /**\n * Adds a color stop to the gradient root\n */\n addColorStop(offset, color) {\n var stop = this.__ctx.__createElement(\"stop\"), regex, matches;\n stop.setAttribute(\"offset\", offset);\n if (color && color.indexOf(\"rgba\") !== -1) {\n //separate alpha value, since webkit can't handle it\n regex = /rgba\\(\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d?\\.?\\d*)\\s*\\)/gi;\n matches = regex.exec(color);\n stop.setAttribute(\"stop-color\", format(\"rgb({r},{g},{b})\", {r: matches[1], g: matches[2], b: matches[3]}));\n stop.setAttribute(\"stop-opacity\", matches[4]);\n } else {\n stop.setAttribute(\"stop-color\", color);\n }\n this.__root.appendChild(stop);\n }\n}\n\nclass CanvasPattern {\n constructor(pattern, ctx) {\n this.__root = pattern;\n this.__ctx = ctx;\n }\n}\n\n/**\n * The mock canvas context\n * @param config - options include:\n * ctx - existing Context2D to wrap around\n * width - width of your canvas (defaults to 500)\n * height - height of your canvas (defaults to 500)\n * enableMirroring - enables canvas mirroring (get image data) (defaults to false)\n * document - the document object (defaults to the current document)\n */\nclass ctx {\n constructor(config) {\n\n if (!(this instanceof ctx)) {\n //did someone call this without new?\n return new ctx(config)\n }\n\n // clone config\n this.config = config;\n\n //setup options\n this.width = config.width;\n this.height = config.height;\n this.enableMirroring = config.enableMirroring || false;\n\n this.canvas = this; ///point back to this instance!\n this.__document = document;\n\n // allow passing in an existing context to wrap around\n // if a context is passed in, we know a canvas already exist\n if (config.ctx) {\n this.__ctx = config.ctx;\n } else {\n this.__canvas = this.__document.createElement(\"canvas\");\n this.__ctx = this.__canvas.getContext(\"2d\");\n }\n\n // give this canvas a type\n this.isSVG = true;\n\n this.__setDefaultStyles();\n this.__stack = [this.__getStyleState()];\n this.__groupStack = [];\n\n // root svg element\n this.__root = this.__createElement(\"svg\");\n this.__root.setAttribute(\"width\", this.width);\n this.__root.setAttribute(\"height\", this.height);\n\n // allow contents to overflow svg bbox\n this.__root.setAttribute('overflow', 'visible');\n\n // viewbox\n if (config.viewbox) {\n const str = config.viewbox.x + ' ' + config.viewbox.y + ' ' + config.viewbox.width + ' ' + config.viewbox.height;\n this.__root.setAttribute(\"viewBox\", str);\n\n this.viewbox = config.viewbox;\n }\n\n // make sure we don't generate the same ids in defs\n this.__ids = {};\n\n // defs\n this.__defs = this.__createElement(\"defs\");\n this.__root.appendChild(this.__defs);\n\n this.multiLocusGap = config.multiLocusGap;\n\n // svg background color\n let backdropConfig =\n {\n id: 'svg_output_backdrop',\n width: '100%',\n height: '100%',\n fill: config.backdropColor || 'white'\n };\n\n let backdropRect = this.__createElement('rect', backdropConfig);\n this.__root.appendChild(backdropRect);\n\n // root group\n this.__rootGroup = this.__createElement('g', {id: 'root-group'});\n this.__root.appendChild(this.__rootGroup);\n\n // point current element to root group\n this.__currentElement = this.__rootGroup;\n }\n\n setWidth(width) {\n\n this.width = width;\n this.__root.setAttribute(\"width\", this.width);\n\n const str = this.config.viewbox.x + ' ' + this.config.viewbox.y + ' ' + width + ' ' + this.config.viewbox.height;\n this.__root.setAttribute(\"viewBox\", str);\n\n };\n\n setHeight(height) {\n\n this.height = height;\n this.__root.setAttribute(\"height\", this.height);\n\n const str = this.config.viewbox.x + ' ' + this.config.viewbox.y + ' ' + this.config.viewbox.width + ' ' + height;\n this.__root.setAttribute(\"viewBox\", str);\n\n };\n\n /**\n * Creates the specified svg element\n * @private\n */\n __createElement(elementName, properties, resetFill) {\n\n if (typeof properties === \"undefined\") {\n properties = {};\n }\n\n let element = this.__document.createElementNS(\"http://www.w3.org/2000/svg\", elementName);\n\n if (resetFill) {\n //if fill or stroke is not specified, the svg element should not display. By default SVG's fill is black.\n element.setAttribute(\"fill\", \"none\");\n element.setAttribute(\"stroke\", \"none\");\n }\n\n for (let key of Object.keys(properties)) {\n element.setAttribute(key, properties[key]);\n }\n\n return element\n };\n\n /**\n * Applies default canvas styles to the context\n * @private\n */\n __setDefaultStyles() {\n //default 2d canvas context properties see:http://www.w3.org/TR/2dcontext/\n var keys = Object.keys(STYLES), i, key;\n for (i = 0; i < keys.length; i++) {\n key = keys[i];\n this[key] = STYLES[key].canvas;\n }\n };\n\n /**\n * Applies styles on restore\n * @param styleState\n * @private\n */\n __applyStyleState(styleState) {\n var keys = Object.keys(styleState), i, key;\n for (i = 0; i < keys.length; i++) {\n key = keys[i];\n this[key] = styleState[key];\n }\n };\n\n /**\n * Gets the current style state\n * @return {Object}\n * @private\n */\n __getStyleState() {\n var i, styleState = {}, keys = Object.keys(STYLES), key;\n for (i = 0; i < keys.length; i++) {\n key = keys[i];\n styleState[key] = this[key];\n }\n return styleState\n };\n\n /**\n * Apples the current styles to the current SVG element. On \"ctx.fill\" or \"ctx.stroke\"\n * @param type\n * @private\n */\n __applyStyleToCurrentElement(type) {\n var currentElement = this.__currentElement;\n var currentStyleGroup = this.__currentElementsToStyle;\n if (currentStyleGroup) {\n currentElement.setAttribute(type, \"\");\n currentElement = currentStyleGroup.element;\n currentStyleGroup.children.forEach(function (node) {\n node.setAttribute(type, \"\");\n });\n }\n\n var keys = Object.keys(STYLES), i, style, value, id, regex, matches;\n for (i = 0; i < keys.length; i++) {\n style = STYLES[keys[i]];\n value = this[keys[i]];\n if (style.apply) {\n //is this a gradient or pattern?\n if (value instanceof CanvasPattern) {\n //pattern\n if (value.__ctx) {\n //copy over defs\n while (value.__ctx.__defs.childNodes.length) {\n id = value.__ctx.__defs.childNodes[0].getAttribute(\"id\");\n this.__ids[id] = id;\n this.__defs.appendChild(value.__ctx.__defs.childNodes[0]);\n }\n }\n currentElement.setAttribute(style.apply, format(\"url(#{id})\", {id: value.__root.getAttribute(\"id\")}));\n } else if (value instanceof CanvasGradient) {\n //gradient\n currentElement.setAttribute(style.apply, format(\"url(#{id})\", {id: value.__root.getAttribute(\"id\")}));\n } else if (style && style.apply.indexOf(type) !== -1 && style.svg !== value) {\n if ((style.svgAttr === \"stroke\" || style.svgAttr === \"fill\") && value && value.indexOf(\"rgba\") !== -1) {\n //separate alpha value, since illustrator can't handle it\n regex = /rgba\\(\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d?\\.?\\d*)\\s*\\)/gi;\n matches = regex.exec(value);\n currentElement.setAttribute(style.svgAttr, format(\"rgb({r},{g},{b})\", {\n r: matches[1],\n g: matches[2],\n b: matches[3]\n }));\n //should take globalAlpha here\n var opacity = matches[4];\n var globalAlpha = this.globalAlpha;\n if (globalAlpha != null) {\n opacity *= globalAlpha;\n }\n currentElement.setAttribute(style.svgAttr + \"-opacity\", opacity);\n } else {\n var attr = style.svgAttr;\n if (keys[i] === 'globalAlpha') {\n attr = type + '-' + style.svgAttr;\n if (currentElement.getAttribute(attr)) {\n //fill-opacity or stroke-opacity has already been set by stroke or fill.\n continue\n }\n }\n //otherwise only update attribute if right type, and not svg default\n currentElement.setAttribute(attr, value);\n }\n }\n }\n }\n };\n\n /**\n * Will return the closest group or svg node. May return the current element.\n * @private\n */\n __closestGroupOrSvg(node) {\n node = node || this.__currentElement;\n if (node.nodeName === \"g\" || node.nodeName === \"svg\") {\n return node\n } else {\n return this.__closestGroupOrSvg(node.parentNode)\n }\n };\n\n /**\n * Returns the serialized value of the svg so far\n * @param fixNamedEntities - Standalone SVG doesn't support named entities, which document.createTextNode encodes.\n * If true, we attempt to find all named entities and encode it as a numeric entity.\n * @return serialized svg\n */\n getSerializedSvg(fixNamedEntities) {\n var serialized = new XMLSerializer().serializeToString(this.__root),\n keys, i, key, value, regexp;\n\n //IE search for a duplicate xmnls because they didn't implement setAttributeNS correctly\n // xmlns = /xmlns=\"http:\\/\\/www\\.w3\\.org\\/2000\\/svg\".+xmlns=\"http:\\/\\/www\\.w3\\.org\\/2000\\/svg/gi;\n // if (xmlns.test(serialized)) {\n // serialized = serialized.replace('xmlns=\"http://www.w3.org/2000/svg','xmlns:xlink=\"http://www.w3.org/1999/xlink');\n // }\n\n if (fixNamedEntities) {\n keys = Object.keys(namedEntities);\n //loop over each named entity and replace with the proper equivalent.\n for (i = 0; i < keys.length; i++) {\n key = keys[i];\n value = namedEntities[key];\n regexp = new RegExp(key, \"gi\");\n if (regexp.test(serialized)) {\n serialized = serialized.replace(regexp, value);\n }\n }\n }\n\n return serialized\n };\n\n\n /**\n * Returns the root svg\n * @return\n */\n getSvg() {\n return this.__root\n };\n\n /**\n * Will generate a group tag.\n */\n saveWithTranslationAndClipRect(id, tx, ty, width, height, clipYOffset) {\n\n // clip rect\n const clip_id = `${id}_clip_rect`;\n let clipPath = this.__createElement('clipPath', {id: clip_id});\n\n this.__defs.appendChild(clipPath);\n\n const config =\n {\n x: '0',\n y: clipYOffset.toString(),\n width: width.toString(),\n height: height.toString()\n };\n\n clipPath.appendChild(this.__createElement('rect', config));\n\n const group = this.__createElement(\"g\");\n group.setAttribute('transform', format('translate({x},{y})', {x: tx, y: ty}));\n group.setAttribute('clip-path', format('url(#{id})', {id: clip_id}));\n\n const parent = this.__closestGroupOrSvg();\n parent.appendChild(group);\n this.__groupStack.push(parent);\n\n this.__currentElement = group;\n this.__stack.push(this.__getStyleState());\n };\n\n save() {\n var group = this.__createElement(\"g\");\n var parent = this.__closestGroupOrSvg();\n this.__groupStack.push(parent);\n parent.appendChild(group);\n this.__currentElement = group;\n this.__stack.push(this.__getStyleState());\n };\n\n /**\n * Sets current element to parent, or just root if already root\n */\n restore() {\n this.__currentElement = this.__groupStack.pop();\n this.__currentElementsToStyle = null;\n //Clearing canvas will make the poped group invalid, currentElement is set to the root group node.\n if (!this.__currentElement) {\n this.__currentElement = this.__root.childNodes[1];\n }\n var state = this.__stack.pop();\n this.__applyStyleState(state);\n };\n\n /**\n * Helper method to add transform\n * @private\n */\n __addTransform(t) {\n //if the current element has siblings, add another group\n var parent = this.__closestGroupOrSvg();\n if (parent.childNodes.length > 0) {\n if (this.__currentElement.nodeName === \"path\") {\n if (!this.__currentElementsToStyle) this.__currentElementsToStyle = {element: parent, children: []};\n this.__currentElementsToStyle.children.push(this.__currentElement);\n this.__applyCurrentDefaultPath();\n }\n\n var group = this.__createElement(\"g\");\n parent.appendChild(group);\n this.__currentElement = group;\n }\n\n var transform = this.__currentElement.getAttribute(\"transform\");\n if (transform) {\n transform += \" \";\n } else {\n transform = \"\";\n }\n transform += t;\n this.__currentElement.setAttribute(\"transform\", transform);\n };\n\n addTrackGroupWithTranslationAndClipRect(id, tx, ty, width, height, clipYOffset) {\n\n // clip rect\n const clip_id = id + '_clip_rect';\n let clipPath = this.__createElement('clipPath', {id: clip_id});\n\n this.__defs.appendChild(clipPath);\n clipPath.appendChild(this.__createElement('rect', {\n x: '0',\n y: clipYOffset.toString(),\n width: width.toString(),\n height: height.toString()\n }));\n\n let group = this.__createElement('g');\n this.__rootGroup.appendChild(group);\n\n group.setAttribute('transform', format('translate({x},{y})', {x: tx, y: ty}));\n group.setAttribute('id', (id + '_group'));\n\n // add clip rect\n group.setAttribute('clip-path', format('url(#{id})', {id: clip_id}));\n\n this.__currentElement = group;\n };\n\n /**\n * scales the current element\n */\n scale(x, y) {\n if (y === undefined) {\n y = x;\n }\n this.__addTransform(format(\"scale({x},{y})\", {x: x, y: y}));\n };\n\n /**\n * rotates the current element\n */\n rotate(angle) {\n var degrees = (angle * 180 / Math.PI);\n this.__addTransform(format(\"rotate({angle},{cx},{cy})\", {angle: degrees, cx: 0, cy: 0}));\n };\n\n /**\n * translates the current element\n */\n translate(x, y) {\n this.__addTransform(format(\"translate({x},{y})\", {x: x, y: y}));\n };\n\n /**\n * applies a transform to the current element\n */\n transform(a, b, c, d, e, f) {\n this.__addTransform(format(\"matrix({a},{b},{c},{d},{e},{f})\", {a: a, b: b, c: c, d: d, e: e, f: f}));\n };\n\n /**\n * Create a new Path Element\n */\n beginPath() {\n var path, parent;\n\n // Note that there is only one current default path, it is not part of the drawing state.\n // See also: https://html.spec.whatwg.org/multipage/scripting.html#current-default-path\n this.__currentDefaultPath = \"\";\n this.__currentPosition = {};\n\n path = this.__createElement(\"path\", {}, true);\n parent = this.__closestGroupOrSvg();\n parent.appendChild(path);\n this.__currentElement = path;\n };\n\n /**\n * Helper function to apply currentDefaultPath to current path element\n * @private\n */\n __applyCurrentDefaultPath() {\n var currentElement = this.__currentElement;\n if (currentElement.nodeName === \"path\") {\n currentElement.setAttribute(\"d\", this.__currentDefaultPath);\n } else {\n console.error(\"Attempted to apply path command to node\", currentElement.nodeName);\n }\n };\n\n /**\n * Helper function to add path command\n * @private\n */\n __addPathCommand(command) {\n this.__currentDefaultPath += \" \";\n this.__currentDefaultPath += command;\n };\n\n /**\n * Adds the move command to the current path element,\n * if the currentPathElement is not empty create a new path element\n */\n moveTo(x, y) {\n if (this.__currentElement.nodeName !== \"path\") {\n this.beginPath();\n }\n\n // creates a new subpath with the given point\n this.__currentPosition = {x: x, y: y};\n this.__addPathCommand(format(\"M {x} {y}\", {x: x, y: y}));\n };\n\n /**\n * Closes the current path\n */\n closePath() {\n if (this.__currentDefaultPath) {\n this.__addPathCommand(\"Z\");\n }\n };\n\n /**\n * Adds a line to command\n */\n lineTo(x, y) {\n this.__currentPosition = {x: x, y: y};\n if (this.__currentDefaultPath && this.__currentDefaultPath.indexOf('M') > -1) {\n this.__addPathCommand(format(\"L {x} {y}\", {x: x, y: y}));\n } else {\n this.__addPathCommand(format(\"M {x} {y}\", {x: x, y: y}));\n }\n };\n\n /**\n * Add a bezier command\n */\n bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y) {\n this.__currentPosition = {x: x, y: y};\n this.__addPathCommand(format(\"C {cp1x} {cp1y} {cp2x} {cp2y} {x} {y}\",\n {cp1x: cp1x, cp1y: cp1y, cp2x: cp2x, cp2y: cp2y, x: x, y: y}));\n };\n\n /**\n * Adds a quadratic curve to command\n */\n quadraticCurveTo(cpx, cpy, x, y) {\n this.__currentPosition = {x: x, y: y};\n this.__addPathCommand(format(\"Q {cpx} {cpy} {x} {y}\", {cpx: cpx, cpy: cpy, x: x, y: y}));\n };\n\n /**\n * Adds the arcTo to the current path\n *\n * @see http://www.w3.org/TR/2015/WD-2dcontext-20150514/#dom-context-2d-arcto\n */\n arcTo(x1, y1, x2, y2, radius) {\n // Let the point (x0, y0) be the last point in the subpath.\n var x0 = this.__currentPosition && this.__currentPosition.x;\n var y0 = this.__currentPosition && this.__currentPosition.y;\n\n // First ensure there is a subpath for (x1, y1).\n if (typeof x0 == \"undefined\" || typeof y0 == \"undefined\") {\n return\n }\n\n // Negative values for radius must cause the implementation to throw an IndexSizeError exception.\n if (radius < 0) {\n throw new Error(\"IndexSizeError: The radius provided (\" + radius + \") is negative.\")\n }\n\n // If the point (x0, y0) is equal to the point (x1, y1),\n // or if the point (x1, y1) is equal to the point (x2, y2),\n // or if the radius radius is zero,\n // then the method must add the point (x1, y1) to the subpath,\n // and connect that point to the previous point (x0, y0) by a straight line.\n if (((x0 === x1) && (y0 === y1))\n || ((x1 === x2) && (y1 === y2))\n || (radius === 0)) {\n this.lineTo(x1, y1);\n return\n }\n\n // Otherwise, if the points (x0, y0), (x1, y1), and (x2, y2) all lie on a single straight line,\n // then the method must add the point (x1, y1) to the subpath,\n // and connect that point to the previous point (x0, y0) by a straight line.\n var unit_vec_p1_p0 = normalize([x0 - x1, y0 - y1]);\n var unit_vec_p1_p2 = normalize([x2 - x1, y2 - y1]);\n if (unit_vec_p1_p0[0] * unit_vec_p1_p2[1] === unit_vec_p1_p0[1] * unit_vec_p1_p2[0]) {\n this.lineTo(x1, y1);\n return\n }\n\n // Otherwise, let The Arc be the shortest arc given by circumference of the circle that has radius radius,\n // and that has one point tangent to the half-infinite line that crosses the point (x0, y0) and ends at the point (x1, y1),\n // and that has a different point tangent to the half-infinite line that ends at the point (x1, y1), and crosses the point (x2, y2).\n // The points at which this circle touches these two lines are called the start and end tangent points respectively.\n\n // note that both vectors are unit vectors, so the length is 1\n var cos = (unit_vec_p1_p0[0] * unit_vec_p1_p2[0] + unit_vec_p1_p0[1] * unit_vec_p1_p2[1]);\n var theta = Math.acos(Math.abs(cos));\n\n // Calculate origin\n var unit_vec_p1_origin = normalize([\n unit_vec_p1_p0[0] + unit_vec_p1_p2[0],\n unit_vec_p1_p0[1] + unit_vec_p1_p2[1]\n ]);\n var len_p1_origin = radius / Math.sin(theta / 2);\n var x = x1 + len_p1_origin * unit_vec_p1_origin[0];\n var y = y1 + len_p1_origin * unit_vec_p1_origin[1];\n\n // Calculate start angle and end angle\n // rotate 90deg clockwise (note that y axis points to its down)\n var unit_vec_origin_start_tangent = [\n -unit_vec_p1_p0[1],\n unit_vec_p1_p0[0]\n ];\n // rotate 90deg counter clockwise (note that y axis points to its down)\n var unit_vec_origin_end_tangent = [\n unit_vec_p1_p2[1],\n -unit_vec_p1_p2[0]\n ];\n var getAngle = function (vector) {\n // get angle (clockwise) between vector and (1, 0)\n var x = vector[0];\n var y = vector[1];\n if (y >= 0) { // note that y axis points to its down\n return Math.acos(x)\n } else {\n return -Math.acos(x)\n }\n };\n var startAngle = getAngle(unit_vec_origin_start_tangent);\n var endAngle = getAngle(unit_vec_origin_end_tangent);\n\n // Connect the point (x0, y0) to the start tangent point by a straight line\n this.lineTo(x + unit_vec_origin_start_tangent[0] * radius,\n y + unit_vec_origin_start_tangent[1] * radius);\n\n // Connect the start tangent point to the end tangent point by arc\n // and adding the end tangent point to the subpath.\n this.arc(x, y, radius, startAngle, endAngle);\n };\n\n /**\n * Sets the stroke property on the current element\n */\n stroke() {\n if (this.__currentElement.nodeName === \"path\") {\n this.__currentElement.setAttribute(\"paint-order\", \"fill stroke markers\");\n }\n this.__applyCurrentDefaultPath();\n this.__applyStyleToCurrentElement(\"stroke\");\n };\n\n /**\n * Sets fill properties on the current element\n */\n fill() {\n if (this.__currentElement.nodeName === \"path\") {\n this.__currentElement.setAttribute(\"paint-order\", \"stroke fill markers\");\n }\n this.__applyCurrentDefaultPath();\n this.__applyStyleToCurrentElement(\"fill\");\n };\n\n /**\n * Adds a rectangle to the path.\n */\n rect(x, y, width, height) {\n if (this.__currentElement.nodeName !== \"path\") {\n this.beginPath();\n }\n this.moveTo(x, y);\n this.lineTo(x + width, y);\n this.lineTo(x + width, y + height);\n this.lineTo(x, y + height);\n this.lineTo(x, y);\n this.closePath();\n };\n\n\n /**\n * adds a rectangle element\n */\n fillRect(x, y, width, height) {\n\n if (height < 0) {\n y += height;\n height = -height;\n }\n if (width < 0) {\n x += width;\n width = -width;\n }\n // See if rect intersects current viewbox\n var r2 = {\n x: x,\n y: y,\n width: width,\n height: height\n };\n\n if (this.viewbox) {\n if (!intersectRect(this.viewbox, r2)) {\n return\n }\n }\n\n var rect, parent;\n rect = this.__createElement(\"rect\", r2, true);\n parent = this.__closestGroupOrSvg();\n parent.appendChild(rect);\n this.__currentElement = rect;\n this.__applyStyleToCurrentElement(\"fill\");\n };\n\n /**\n * Draws a rectangle with no fill\n * @param x\n * @param y\n * @param width\n * @param height\n */\n strokeRect(x, y, width, height) {\n var rect, parent;\n rect = this.__createElement(\"rect\", {\n x: x,\n y: y,\n width: width,\n height: height\n }, true);\n parent = this.__closestGroupOrSvg();\n parent.appendChild(rect);\n this.__currentElement = rect;\n this.__applyStyleToCurrentElement(\"stroke\");\n };\n\n // stroke ellipse\n strokeEllipse(cx, cy, rx, ry, rotation, startAngle, endAngle, isCCW) {\n this.__ellipse(cx, cy, rx, ry, rotation, startAngle, endAngle, isCCW, 'stroke');\n }\n\n // fill ellipse\n fillEllipse(cx, cy, rx, ry, rotation, startAngle, endAngle, isCCW) {\n this.__ellipse(cx, cy, rx, ry, rotation, startAngle, endAngle, isCCW, 'fill');\n }\n\n // ellipse helper\n __ellipse(cx, cy, rx, ry, rotation, startAngle, endAngle, isCCW, style) {\n\n const config =\n {\n cx,\n cy,\n rx,\n ry\n };\n const element = this.__createElement('ellipse', config, true);\n const parent = this.__closestGroupOrSvg();\n parent.appendChild(element);\n this.__currentElement = element;\n this.__applyStyleToCurrentElement(style);\n }\n\n /**\n * Clear entire canvas:\n * 1. save current transforms\n * 2. remove all the childNodes of the root g element\n */\n __clearCanvas() {\n var current = this.__closestGroupOrSvg(),\n transform = current.getAttribute(\"transform\");\n var rootGroup = this.__root.childNodes[1];\n var childNodes = rootGroup.childNodes;\n for (var i = childNodes.length - 1; i >= 0; i--) {\n if (childNodes[i]) {\n rootGroup.removeChild(childNodes[i]);\n }\n }\n this.__currentElement = rootGroup;\n //reset __groupStack as all the child group nodes are all removed.\n this.__groupStack = [];\n if (transform) {\n this.__addTransform(transform);\n }\n };\n\n /**\n * \"Clears\" a canvas by just drawing a white rectangle in the current group.\n */\n clearRect(x, y, width, height) {\n //clear entire canvas\n if (x === 0 && y === 0 && width === this.width && height === this.height) {\n this.__clearCanvas();\n return\n }\n var rect, parent = this.__closestGroupOrSvg();\n rect = this.__createElement(\"rect\", {\n x: x,\n y: y,\n width: width,\n height: height,\n fill: \"#FFFFFF\"\n }, true);\n parent.appendChild(rect);\n };\n\n /**\n * Adds a linear gradient to a defs tag.\n * Returns a canvas gradient object that has a reference to it's parent def\n */\n createLinearGradient(x1, y1, x2, y2) {\n var grad = this.__createElement(\"linearGradient\", {\n id: randomString(this.__ids),\n x1: x1 + \"px\",\n x2: x2 + \"px\",\n y1: y1 + \"px\",\n y2: y2 + \"px\",\n \"gradientUnits\": \"userSpaceOnUse\"\n }, false);\n this.__defs.appendChild(grad);\n return new CanvasGradient(grad, this)\n };\n\n /**\n * Adds a radial gradient to a defs tag.\n * Returns a canvas gradient object that has a reference to it's parent def\n */\n createRadialGradient(x0, y0, r0, x1, y1, r1) {\n var grad = this.__createElement(\"radialGradient\", {\n id: randomString(this.__ids),\n cx: x1 + \"px\",\n cy: y1 + \"px\",\n r: r1 + \"px\",\n fx: x0 + \"px\",\n fy: y0 + \"px\",\n \"gradientUnits\": \"userSpaceOnUse\"\n }, false);\n this.__defs.appendChild(grad);\n return new CanvasGradient(grad, this)\n\n };\n\n /**\n * Parses the font string and returns svg mapping\n * @private\n */\n __parseFont() {\n var regex = /^\\s*(?=(?:(?:[-a-z]+\\s*){0,2}(italic|oblique))?)(?=(?:(?:[-a-z]+\\s*){0,2}(small-caps))?)(?=(?:(?:[-a-z]+\\s*){0,2}(bold(?:er)?|lighter|[1-9]00))?)(?:(?:normal|\\1|\\2|\\3)\\s*){0,3}((?:xx?-)?(?:small|large)|medium|smaller|larger|[.\\d]+(?:\\%|in|[cem]m|ex|p[ctx]))(?:\\s*\\/\\s*(normal|[.\\d]+(?:\\%|in|[cem]m|ex|p[ctx])))?\\s*([-,\\'\\\"\\sa-z0-9]+?)\\s*$/i;\n var fontPart = regex.exec(this.font);\n var data = {\n style: fontPart[1] || 'normal',\n size: fontPart[4] || '10px',\n family: fontPart[6] || 'sans-serif',\n weight: fontPart[3] || 'normal',\n decoration: fontPart[2] || 'normal',\n href: null\n };\n\n //canvas doesn't support underline natively, but we can pass this attribute\n if (this.__fontUnderline === \"underline\") {\n data.decoration = \"underline\";\n }\n\n //canvas also doesn't support linking, but we can pass this as well\n if (this.__fontHref) {\n data.href = this.__fontHref;\n }\n\n return data\n };\n\n /**\n * Helper to link text fragments\n * @param font\n * @param element\n * @return {*}\n * @private\n */\n __wrapTextLink(font, element) {\n if (font.href) {\n var a = this.__createElement(\"a\");\n a.setAttributeNS(\"http://www.w3.org/1999/xlink\", \"xlink:href\", font.href);\n a.appendChild(element);\n return a\n }\n return element\n };\n\n /**\n * Fills or strokes text\n * @param text\n * @param x\n * @param y\n * @param action - stroke or fill\n * @private\n */\n __applyText(text, x, y, action) {\n var font = this.__parseFont(),\n parent = this.__closestGroupOrSvg(),\n textElement = this.__createElement(\"text\", {\n \"font-family\": font.family,\n \"font-size\": font.size,\n \"font-style\": font.style,\n \"font-weight\": font.weight,\n \"text-decoration\": font.decoration,\n \"x\": x,\n \"y\": y,\n \"text-anchor\": getTextAnchor(this.textAlign),\n \"dominant-baseline\": getDominantBaseline(this.textBaseline)\n }, true);\n\n textElement.appendChild(this.__document.createTextNode(text));\n this.__currentElement = textElement;\n this.__applyStyleToCurrentElement(action);\n parent.appendChild(this.__wrapTextLink(font, textElement));\n };\n\n /**\n * Creates a text element\n * @param text\n * @param x\n * @param y\n */\n fillText(text, x, y) {\n this.__applyText(text, x, y, \"fill\");\n };\n\n /**\n * Strokes text\n * @param text\n * @param x\n * @param y\n */\n strokeText(text, x, y) {\n this.__applyText(text, x, y, \"stroke\");\n };\n\n /**\n * No need to implement this for svg.\n * @param text\n * @return {TextMetrics}\n */\n measureText(text) {\n this.__ctx.font = this.font;\n return this.__ctx.measureText(text)\n };\n\n /**\n * Arc command!\n */\n arc(x, y, radius, startAngle, endAngle, counterClockwise) {\n // in canvas no circle is drawn if no angle is provided.\n if (startAngle === endAngle) {\n return\n }\n startAngle = startAngle % (2 * Math.PI);\n endAngle = endAngle % (2 * Math.PI);\n if (startAngle === endAngle) {\n //circle time! subtract some of the angle so svg is happy (svg elliptical arc can't draw a full circle)\n endAngle = ((endAngle + (2 * Math.PI)) - 0.001 * (counterClockwise ? -1 : 1)) % (2 * Math.PI);\n }\n var endX = x + radius * Math.cos(endAngle),\n endY = y + radius * Math.sin(endAngle),\n startX = x + radius * Math.cos(startAngle),\n startY = y + radius * Math.sin(startAngle),\n sweepFlag = counterClockwise ? 0 : 1,\n largeArcFlag = 0,\n diff = endAngle - startAngle;\n\n // https://github.com/gliffy/canvas2svg/issues/4\n if (diff < 0) {\n diff += 2 * Math.PI;\n }\n\n if (counterClockwise) {\n largeArcFlag = diff > Math.PI ? 0 : 1;\n } else {\n largeArcFlag = diff > Math.PI ? 1 : 0;\n }\n\n this.lineTo(startX, startY);\n this.__addPathCommand(format(\"A {rx} {ry} {xAxisRotation} {largeArcFlag} {sweepFlag} {endX} {endY}\",\n {\n rx: radius,\n ry: radius,\n xAxisRotation: 0,\n largeArcFlag: largeArcFlag,\n sweepFlag: sweepFlag,\n endX: endX,\n endY: endY\n }));\n\n this.__currentPosition = {x: endX, y: endY};\n };\n\n /**\n * The ellipse() method creates an elliptical arc centered at (x, y) with the radii radiusX and radiusY. The path\n * starts at startAngle and ends at endAngle, and travels in the direction given by counterclockwise (defaulting to clockwise).\n */\n// ellipse (x, y, radiusX, radiusY, rotation, startAngle, endAngle, counterclockwise) {\n// // TODO -- implement\n// }\n\n /**\n * Generates a ClipPath from the clip command.\n */\n clip() {\n var group = this.__closestGroupOrSvg(),\n clipPath = this.__createElement(\"clipPath\"),\n id = randomString(this.__ids),\n newGroup = this.__createElement(\"g\");\n\n this.__applyCurrentDefaultPath();\n group.removeChild(this.__currentElement);\n clipPath.setAttribute(\"id\", id);\n clipPath.appendChild(this.__currentElement);\n\n this.__defs.appendChild(clipPath);\n\n //set the clip path to this group\n group.setAttribute(\"clip-path\", format(\"url(#{id})\", {id: id}));\n\n //clip paths can be scaled and transformed, we need to add another wrapper group to avoid later transformations\n // to this path\n group.appendChild(newGroup);\n\n this.__currentElement = newGroup;\n\n };\n\n /**\n * Draws a canvas, image or mock context to this canvas.\n * Note that all svg dom manipulation uses node.childNodes rather than node.children for IE support.\n * http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-drawimage\n */\n drawImage() {\n //convert arguments to a real array\n var args = Array.prototype.slice.call(arguments),\n image = args[0],\n dx, dy, dw, dh, sx = 0, sy = 0, sw, sh, parent, svg, defs, group,\n svgImage, canvas, context, id;\n\n if (args.length === 3) {\n dx = args[1];\n dy = args[2];\n sw = image.width;\n sh = image.height;\n dw = sw;\n dh = sh;\n } else if (args.length === 5) {\n dx = args[1];\n dy = args[2];\n dw = args[3];\n dh = args[4];\n sw = image.width;\n sh = image.height;\n } else if (args.length === 9) {\n sx = args[1];\n sy = args[2];\n sw = args[3];\n sh = args[4];\n dx = args[5];\n dy = args[6];\n dw = args[7];\n dh = args[8];\n } else {\n throw new Error(\"Invalid number of arguments passed to drawImage: \" + arguments.length)\n }\n\n parent = this.__closestGroupOrSvg();\n this.__currentElement;\n var translateDirective = \"translate(\" + dx + \", \" + dy + \")\";\n if (image instanceof ctx) {\n //canvas2svg mock canvas context. In the future we may want to clone nodes instead.\n //also I'm currently ignoring dw, dh, sw, sh, sx, sy for a mock context.\n svg = image.getSvg().cloneNode(true);\n if (svg.childNodes && svg.childNodes.length > 1) {\n defs = svg.childNodes[0];\n while (defs.childNodes.length) {\n id = defs.childNodes[0].getAttribute(\"id\");\n this.__ids[id] = id;\n this.__defs.appendChild(defs.childNodes[0]);\n }\n group = svg.childNodes[1];\n if (group) {\n //save original transform\n var originTransform = group.getAttribute(\"transform\");\n var transformDirective;\n if (originTransform) {\n transformDirective = originTransform + \" \" + translateDirective;\n } else {\n transformDirective = translateDirective;\n }\n group.setAttribute(\"transform\", transformDirective);\n parent.appendChild(group);\n }\n }\n } else if (image.nodeName === \"CANVAS\" || image.nodeName === \"IMG\") {\n //canvas or image\n svgImage = this.__createElement(\"image\");\n svgImage.setAttribute(\"width\", dw);\n svgImage.setAttribute(\"height\", dh);\n svgImage.setAttribute(\"preserveAspectRatio\", \"none\");\n\n if (sx || sy || sw !== image.width || sh !== image.height) {\n //crop the image using a temporary canvas\n canvas = this.__document.createElement(\"canvas\");\n canvas.width = dw;\n canvas.height = dh;\n context = canvas.getContext(\"2d\");\n context.drawImage(image, sx, sy, sw, sh, 0, 0, dw, dh);\n image = canvas;\n }\n svgImage.setAttribute(\"transform\", translateDirective);\n svgImage.setAttributeNS(\"http://www.w3.org/1999/xlink\", \"xlink:href\",\n image.nodeName === \"CANVAS\" ? image.toDataURL() : image.getAttribute(\"src\"));\n parent.appendChild(svgImage);\n }\n };\n\n /**\n * Generates a pattern tag\n */\n createPattern(image, repetition) {\n\n let pattern = this.__document.__createElement(\"pattern\");\n let id = randomString(this.__ids);\n let img;\n\n pattern.setAttribute(\"id\", id);\n pattern.setAttribute(\"width\", image.width);\n pattern.setAttribute(\"height\", image.height);\n if (image.nodeName === \"CANVAS\" || image.nodeName === \"IMG\") {\n img = this.__createElement(\"image\");\n img.setAttribute(\"width\", image.width);\n img.setAttribute(\"height\", image.height);\n img.setAttributeNS(\"http://www.w3.org/1999/xlink\", \"xlink:href\",\n image.nodeName === \"CANVAS\" ? image.toDataURL() : image.getAttribute(\"src\"));\n pattern.appendChild(img);\n this.__defs.appendChild(pattern);\n } else if (image instanceof ctx) {\n pattern.appendChild(image.__root.childNodes[1]);\n this.__defs.appendChild(pattern);\n }\n return new CanvasPattern(pattern, this)\n };\n\n setLineDash(dashArray) {\n if (dashArray && dashArray.length > 0) {\n this.lineDash = dashArray.join(\",\");\n } else {\n this.lineDash = null;\n }\n };\n\n /**\n * Not yet implemented\n */\n drawFocusRing() {\n };\n\n createImageData() {\n };\n\n getImageData() {\n };\n\n putImageData() {\n };\n\n globalCompositeOperation() {\n };\n\n setTransform() {\n };\n}\n\nconst Cytoband = function (start, end, name, typestain) {\n this.start = start;\n this.end = end;\n this.name = name;\n this.stain = 0;\n\n // Set the type, either p, n, or c\n if (typestain === 'acen') {\n this.type = 'c';\n } else {\n this.type = typestain.charAt(1);\n if (this.type === 'p') {\n this.stain = parseInt(typestain.substring(4));\n }\n }\n};\n\nconst _version = \"2.15.13\";\nfunction version() {\n return _version\n}\n\n/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2014 Broad Institute\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\nconst DEFAULT_GENOMES_URL = \"https://igv.org/genomes/genomes.json\";\nconst BACKUP_GENOMES_URL = \"https://s3.amazonaws.com/igv.org.genomes/genomes.json\";\n\nconst splitLines$1 = splitLines$5;\n\nconst GenomeUtils = {\n\n loadGenome: async function (options) {\n\n const cytobandUrl = options.cytobandURL;\n const aliasURL = options.aliasURL;\n const sequence = await loadFasta(options);\n\n let aliases;\n if (aliasURL) {\n aliases = await loadAliases(aliasURL, sequence.config);\n }\n\n const genome = new Genome(options, sequence, aliases);\n\n // Delay loading cytbands untils after genome initialization to use chromosome aliases (1 vs chr1, etc).\n if (cytobandUrl) {\n genome.cytobands = await loadCytobands(cytobandUrl, sequence.config, genome);\n }\n\n return genome\n },\n\n initializeGenomes: async function (config) {\n\n if (!GenomeUtils.KNOWN_GENOMES) {\n\n const table = {};\n\n // Get default genomes\n if (config.loadDefaultGenomes !== false) {\n try {\n const url = DEFAULT_GENOMES_URL + `?randomSeed=${Math.random().toString(36)}&version=${version()}`; // prevent caching\n const jsonArray = await igvxhr.loadJson(url, {timeout: 5000});\n processJson(jsonArray);\n } catch (e) {\n console.error(e);\n try {\n const url = BACKUP_GENOMES_URL + `?randomSeed=${Math.random().toString(36)}&version=${version()}`; // prevent caching\n const jsonArray = await igvxhr.loadJson(url, {});\n processJson(jsonArray);\n } catch (e) {\n console.error(e);\n console.warn(\"Errors loading default genome definitions.\");\n }\n }\n }\n\n // Add user-defined genomes\n const genomeList = config.genomeList || config.genomes;\n if (genomeList) {\n if (typeof genomeList === 'string') {\n const jsonArray = await igvxhr.loadJson(genomeList, {});\n processJson(jsonArray);\n } else {\n processJson(genomeList);\n }\n }\n\n GenomeUtils.KNOWN_GENOMES = table;\n\n function processJson(jsonArray) {\n jsonArray.forEach(function (json) {\n table[json.id] = json;\n });\n return table\n }\n }\n },\n\n isWholeGenomeView: function (chr) {\n return 'all' === chr.toLowerCase()\n },\n\n // Expand a genome id to a reference object, if needed\n expandReference: function (alert, idOrConfig) {\n\n // idOrConfig might be json\n if (isString$2(idOrConfig) && idOrConfig.startsWith(\"{\")) {\n try {\n idOrConfig = JSON.parse(idOrConfig);\n } catch (e) {\n // Apparently its not json, could be an ID starting with \"{\". Unusual but legal.\n }\n }\n\n let genomeID;\n if (isString$2(idOrConfig)) {\n genomeID = idOrConfig;\n } else if (idOrConfig.genome) {\n genomeID = idOrConfig.genome;\n } else if (idOrConfig.id !== undefined && idOrConfig.fastaURL === undefined) {\n // Backward compatibility\n genomeID = idOrConfig.id;\n }\n\n if (genomeID) {\n const knownGenomes = GenomeUtils.KNOWN_GENOMES;\n const reference = knownGenomes[genomeID];\n if (!reference) {\n alert.present(new Error(`Unknown genome id: ${genomeID}`), undefined);\n }\n return reference\n } else {\n return idOrConfig\n }\n }\n};\n\n\nclass Genome {\n\n constructor(config, sequence, aliases) {\n\n this.config = config;\n this.id = config.id || generateGenomeID(config);\n this.sequence = sequence;\n this.chromosomeNames = sequence.chromosomeNames;\n this.chromosomes = sequence.chromosomes; // An object (functions as a dictionary)\n this.featureDB = new Map(); // Hash of name -> feature, used for search function.\n\n this.wholeGenomeView = config.wholeGenomeView === undefined || config.wholeGenomeView;\n if (this.wholeGenomeView && Object.keys(sequence.chromosomes).length > 1) {\n constructWG(this, config);\n } else {\n this.wgChromosomeNames = sequence.chromosomeNames;\n }\n\n /**\n * Return the official chromosome name for the (possibly) alias. Deals with\n * 1 <-> chr1, chrM <-> MT, IV <-> chr4, etc.\n * @param str\n */\n var chrAliasTable = {},\n self = this;\n\n\n // The standard mappings\n chrAliasTable[\"all\"] = \"all\";\n this.chromosomeNames.forEach(function (name) {\n var alias = name.startsWith(\"chr\") ? name.substring(3) : \"chr\" + name;\n chrAliasTable[alias.toLowerCase()] = name;\n if (name === \"chrM\") chrAliasTable[\"mt\"] = \"chrM\";\n if (name === \"MT\") chrAliasTable[\"chrm\"] = \"MT\";\n chrAliasTable[name.toLowerCase()] = name;\n });\n\n // Custom mappings\n if (aliases) {\n aliases.forEach(function (array) {\n // Find the official chr name\n var defName, i;\n\n for (i = 0; i < array.length; i++) {\n if (self.chromosomes[array[i]]) {\n defName = array[i];\n break\n }\n }\n\n if (defName) {\n array.forEach(function (alias) {\n if (alias !== defName) {\n chrAliasTable[alias.toLowerCase()] = defName;\n chrAliasTable[alias] = defName; // Should not be needed\n }\n });\n }\n\n });\n }\n\n this.chrAliasTable = chrAliasTable;\n\n }\n\n showWholeGenomeView() {\n return this.config.wholeGenomeView !== false\n }\n\n toJSON() {\n return Object.assign({}, this.config, {tracks: undefined})\n }\n\n getInitialLocus() {\n\n }\n\n getHomeChromosomeName() {\n if (this.showWholeGenomeView() && this.chromosomes.hasOwnProperty(\"all\")) {\n return \"all\"\n } else {\n return this.chromosomeNames[0]\n\n }\n }\n\n getChromosomeName(str) {\n const chr = str ? this.chrAliasTable[str.toLowerCase()] : str;\n return chr ? chr : str\n }\n\n getChromosome(chr) {\n chr = this.getChromosomeName(chr);\n return this.chromosomes[chr]\n }\n\n getCytobands(chr) {\n return this.cytobands ? this.cytobands[chr] : null\n }\n\n getLongestChromosome() {\n\n var longestChr,\n chromosomes = this.chromosomes;\n for (let key in chromosomes) {\n if (chromosomes.hasOwnProperty(key)) {\n var chr = chromosomes[key];\n if (longestChr === undefined || chr.bpLength > longestChr.bpLength) {\n longestChr = chr;\n }\n }\n return longestChr\n }\n }\n\n getChromosomes() {\n return this.chromosomes\n }\n\n /**\n * Return the genome coordinate in kb for the give chromosome and position.\n * NOTE: This might return undefined if the chr is filtered from whole genome view.\n */\n getGenomeCoordinate(chr, bp) {\n\n var offset = this.getCumulativeOffset(chr);\n if (offset === undefined) return undefined\n\n return offset + bp\n }\n\n /**\n * Return the chromosome and coordinate in bp for the given genome coordinate\n */\n getChromosomeCoordinate(genomeCoordinate) {\n\n if (this.cumulativeOffsets === undefined) {\n this.cumulativeOffsets = computeCumulativeOffsets.call(this);\n }\n\n let lastChr = undefined;\n let lastCoord = 0;\n for (let name of this.wgChromosomeNames) {\n\n const cumulativeOffset = this.cumulativeOffsets[name];\n if (cumulativeOffset > genomeCoordinate) {\n const position = genomeCoordinate - lastCoord;\n return {chr: lastChr, position: position}\n }\n lastChr = name;\n lastCoord = cumulativeOffset;\n }\n\n // If we get here off the end\n return {chr: this.wgChromosomeNames[this.wgChromosomeNames.length - 1], position: 0}\n\n };\n\n\n /**\n * Return the offset in genome coordinates (kb) of the start of the given chromosome\n * NOTE: This might return undefined if the chromosome is filtered from whole genome view.\n */\n getCumulativeOffset(chr) {\n\n if (this.cumulativeOffsets === undefined) {\n this.cumulativeOffsets = computeCumulativeOffsets.call(this);\n }\n\n const queryChr = this.getChromosomeName(chr);\n return this.cumulativeOffsets[queryChr]\n\n function computeCumulativeOffsets() {\n\n let self = this;\n let acc = {};\n let offset = 0;\n for (let name of self.wgChromosomeNames) {\n\n acc[name] = Math.floor(offset);\n\n const chromosome = self.getChromosome(name);\n\n offset += chromosome.bpLength;\n }\n\n return acc\n }\n }\n\n /**\n * Return the nominal genome length, this is the length of the main chromosomes (no scaffolds, etc).\n */\n getGenomeLength() {\n\n let self = this;\n\n if (!this.bpLength) {\n let bpLength = 0;\n self.wgChromosomeNames.forEach(function (cname) {\n let c = self.chromosomes[cname];\n bpLength += c.bpLength;\n });\n this.bpLength = bpLength;\n }\n return this.bpLength\n }\n\n async getSequence(chr, start, end) {\n chr = this.getChromosomeName(chr);\n return this.sequence.getSequence(chr, start, end)\n }\n\n addFeaturesToDB(featureList, config) {\n\n const insertFeature = (name, feature) => {\n const current = this.featureDB.get(name);\n if (current) {\n feature = (feature.end - feature.start) > (current.end - current.start) ? feature : current;\n\n }\n this.featureDB.set(name, feature);\n };\n\n for (let feature of featureList) {\n if (feature.name) {\n insertFeature(feature.name.toUpperCase(), feature);\n }\n if (feature.gene && feature.gene.name) {\n insertFeature(feature.gene.name.toUpperCase(), feature);\n }\n\n if (config.searchableFields) {\n for (let f of config.searchableFields) {\n const value = feature.getAttributeValue(f);\n if (value) {\n if (value.indexOf(\" \") > 0) {\n insertFeature(value.replaceAll(\" \", \"+\").toUpperCase(), feature);\n } else {\n insertFeature(value.toUpperCase(), feature);\n }\n }\n }\n }\n }\n }\n}\n\nasync function loadCytobands(cytobandUrl, config, genome) {\n\n let data;\n if (isDataURL(cytobandUrl)) {\n const plain = decodeDataURI$1(cytobandUrl);\n data = \"\";\n const len = plain.length;\n for (let i = 0; i < len; i++) {\n data += String.fromCharCode(plain[i]);\n }\n } else {\n data = await igvxhr.loadString(cytobandUrl, buildOptions(config));\n }\n\n // var bands = [],\n // lastChr,\n // n = 0,\n // c = 1,\n //\n // len = lines.length,\n const cytobands = {};\n let lastChr;\n let bands = [];\n const lines = splitLines$1(data);\n for (let line of lines) {\n var tokens = line.split(\"\\t\");\n var chr = genome.getChromosomeName(tokens[0]);\n if (!lastChr) lastChr = chr;\n\n if (chr !== lastChr) {\n cytobands[lastChr] = bands;\n bands = [];\n lastChr = chr;\n }\n\n if (tokens.length === 5) {\n //10\t0\t3000000\tp15.3\tgneg\n var start = parseInt(tokens[1]);\n var end = parseInt(tokens[2]);\n var name = tokens[3];\n var stain = tokens[4];\n bands.push(new Cytoband(start, end, name, stain));\n }\n }\n\n return cytobands\n}\n\nfunction loadAliases(aliasURL, config) {\n\n return igvxhr.loadString(aliasURL, buildOptions(config))\n\n .then(function (data) {\n\n var lines = splitLines$1(data),\n aliases = [];\n\n lines.forEach(function (line) {\n if (!line.startsWith(\"#\") && line.length > 0) aliases.push(line.split(\"\\t\"));\n });\n\n return aliases\n })\n\n}\n\nfunction constructWG(genome, config) {\n\n let wgChromosomes;\n if (config.chromosomeOrder) {\n if (Array.isArray(config.chromosomeOrder)) {\n genome.wgChromosomeNames = config.chromosomeOrder;\n } else {\n genome.wgChromosomeNames = config.chromosomeOrder.split(',').map(nm => nm.trim());\n }\n wgChromosomes = genome.wgChromosomeNames.map(nm => genome.chromosomes[nm]).filter(chr => chr !== undefined);\n\n } else {\n\n // Trim small chromosomes.\n const lengths = Object.keys(genome.chromosomes).map(key => genome.chromosomes[key].bpLength);\n const median = lengths.reduce((a, b) => Math.max(a, b));\n const threshold = median / 50;\n wgChromosomes = Object.values(genome.chromosomes).filter(chr => chr.bpLength > threshold);\n\n // Sort chromosomes. First segregate numeric and alpha names, sort numeric, leave alpha as is\n const numericChromosomes = wgChromosomes.filter(chr => isDigit(chr.name.replace('chr', '')));\n const alphaChromosomes = wgChromosomes.filter(chr => !isDigit(chr.name.replace('chr', '')));\n numericChromosomes.sort((a, b) => Number.parseInt(a.name.replace('chr', '')) - Number.parseInt(b.name.replace('chr', '')));\n\n const wgChromosomeNames = numericChromosomes.map(chr => chr.name);\n for (let chr of alphaChromosomes) {\n wgChromosomeNames.push(chr.name);\n }\n genome.wgChromosomeNames = wgChromosomeNames;\n }\n\n\n // Compute psuedo-chromosome \"all\"\n const l = wgChromosomes.reduce((accumulator, currentValue) => accumulator += currentValue.bpLength, 0);\n genome.chromosomes[\"all\"] = {\n name: \"all\",\n bpLength: l\n };\n\n function isDigit(val) {\n return /^\\d+$/.test(val)\n }\n\n}\n\nfunction generateGenomeID(config) {\n if (config.id !== undefined) {\n return config.id\n } else if (config.fastaURL && isString$2(config.fastaURL)) {\n return config.fastaURL\n } else if (config.fastaURL && config.fastaURL.name) {\n return config.fastaURL.name\n } else {\n return (\"0000\" + (Math.random() * Math.pow(36, 4) << 0).toString(36)).slice(-4)\n }\n}\n\n/**\n * Created by dat on 9/16/16.\n */\n\nconst NOT_LOADED_MESSAGE = 'Error loading track data';\nlet lastClickTime = 0;\nlet lastHoverUpdateTime = 0;\nlet popupTimerID;\n\nclass TrackViewport extends Viewport {\n\n constructor(trackView, viewportColumn, referenceFrame, width) {\n super(trackView, viewportColumn, referenceFrame, width);\n }\n\n initializationHelper() {\n\n this.$spinner = $$1('
', {class: 'igv-loading-spinner-container'});\n this.$viewport.append(this.$spinner);\n this.$spinner.append($$1('
'));\n\n const track = this.trackView.track;\n if ('sequence' !== track.type) {\n this.$zoomInNotice = this.createZoomInNotice(this.$viewport);\n }\n\n if (track.name && \"sequence\" !== track.id) {\n this.$trackLabel = $$1('
');\n this.$viewport.append(this.$trackLabel);\n this.setTrackLabel(track.name);\n if (false === this.browser.trackLabelsVisible) {\n this.$trackLabel.hide();\n }\n }\n\n this.stopSpinner();\n this.addMouseHandlers();\n }\n\n setContentHeight(contentHeight) {\n super.setContentHeight(contentHeight);\n if (this.featureCache) this.featureCache.redraw = true;\n }\n\n setTrackLabel(label) {\n\n this.$trackLabel.empty();\n this.$trackLabel.html(label);\n\n const txt = this.$trackLabel.text();\n this.$trackLabel.attr('title', txt);\n }\n\n startSpinner() {\n this.$spinner.show();\n }\n\n stopSpinner() {\n if (this.$spinner) {\n this.$spinner.hide();\n }\n }\n\n /**\n * Test to determine if we are zoomed in far enough to see features. Applicable to tracks with visibility windows.\n *\n * As a side effect the viewports canvas is removed if zoomed out.\n *\n * @returns {boolean} true if we are zoomed in past visibility window, false otherwise\n */\n checkZoomIn() {\n\n const zoomedOutOfWindow = () => {\n if (this.referenceFrame.chr.toLowerCase() === \"all\" && !this.trackView.track.supportsWholeGenome) {\n return true\n } else {\n const visibilityWindow = this.trackView.track.visibilityWindow;\n return (\n visibilityWindow !== undefined && visibilityWindow > 0 &&\n (this.referenceFrame.bpPerPixel * this.$viewport.width() > visibilityWindow))\n }\n };\n\n if (this.trackView.track && \"sequence\" === this.trackView.track.type && this.referenceFrame.bpPerPixel > bppFeatureFetchThreshold) {\n $$1(this.canvas).remove();\n this.canvas = undefined;\n //this.featureCache = undefined\n return false\n }\n\n if (!(this.viewIsReady())) {\n return false\n }\n\n\n if (zoomedOutOfWindow()) {\n\n // Out of visibility window\n if (this.canvas) {\n $$1(this.canvas).remove();\n this.canvas = undefined;\n //this.featureCache = undefined\n }\n if (this.trackView.track.autoHeight) {\n const minHeight = this.trackView.minHeight || 0;\n this.setContentHeight(minHeight);\n }\n if (this.$zoomInNotice) {\n this.$zoomInNotice.show();\n }\n return false\n } else {\n if (this.$zoomInNotice) {\n this.$zoomInNotice.hide();\n }\n return true\n }\n\n }\n\n /**\n * Adjust the canvas to the current genomic state.\n */\n shift() {\n const referenceFrame = this.referenceFrame;\n if (this.canvas &&\n this.canvas._data &&\n this.canvas._data.referenceFrame.chr === this.referenceFrame.chr &&\n this.canvas._data.bpPerPixel === referenceFrame.bpPerPixel) {\n const pixelOffset = Math.round((this.canvas._data.bpStart - referenceFrame.start) / referenceFrame.bpPerPixel);\n this.canvas.style.left = pixelOffset + \"px\";\n }\n }\n\n /**\n * Set the content top of the current view. This is triggered by scrolling. If the current canvas extent is not\n * sufficient to cover the new vertical range repaint.\n *\n * @param contentTop - the \"top\" property of the virtual content div, 0 unless track is scrolled vertically\n *\n *\n */\n setTop(contentTop) {\n\n super.setTop(contentTop);\n\n if (!this.canvas) {\n this.repaint();\n } else {\n // See if currently painted canvas covers the vertical range of the viewport. If not repaint\n const h = this.$viewport.height();\n const vt = contentTop + this.canvas._data.pixelTop;\n const vb = vt + this.canvas._data.pixelHeight;\n if (vt > 0 || vb < h) {\n this.repaint();\n }\n }\n\n // Now offset backing canvas to align with the contentTop visual offset.\n let offset = contentTop + this.canvas._data.pixelTop;\n this.canvas.style.top = `${offset}px`;\n }\n\n async loadFeatures() {\n\n const referenceFrame = this.referenceFrame;\n const chr = referenceFrame.chr;\n\n // Expand the requested range so we can pan a bit without reloading. But not beyond chromosome bounds\n const chrLength = this.browser.genome.getChromosome(chr).bpLength;\n const pixelWidth = this.$viewport.width();// * 3;\n const bpWidth = pixelWidth * referenceFrame.bpPerPixel;\n const bpStart = Math.floor(Math.max(0, referenceFrame.start - bpWidth));\n const bpEnd = Math.ceil(Math.min(chrLength, referenceFrame.start + bpWidth + bpWidth)); // Add one screen width to end\n\n if (this.loading && this.loading.start === bpStart && this.loading.end === bpEnd) {\n return undefined\n }\n this.loading = {start: bpStart, end: bpEnd};\n this.startSpinner();\n\n try {\n const track = this.trackView.track;\n const features = await this.getFeatures(track, chr, bpStart, bpEnd, referenceFrame.bpPerPixel);\n if (features) {\n let roiFeatures = [];\n if (track.roiSets && track.roiSets.length > 0) {\n for (let roiSet of track.roiSets) {\n const features = await roiSet.getFeatures(chr, bpStart, bpEnd, referenceFrame.bpPerPixel);\n roiFeatures.push({track: roiSet, features});\n }\n }\n\n const mr = track && (\"wig\" === track.type || \"merged\" === track.type); // wig tracks are potentially multiresolution (e.g. bigwig)\n this.featureCache = new FeatureCache(chr, bpStart, bpEnd, referenceFrame.bpPerPixel, features, roiFeatures, mr);\n this.loading = false;\n this.hideMessage();\n this.stopSpinner();\n return this.featureCache\n }\n } catch (error) {\n // Track might have been removed during load\n if (this.trackView && this.trackView.disposed !== true) {\n this.showMessage(NOT_LOADED_MESSAGE);\n this.browser.alert.present(error);\n console.error(error);\n }\n } finally {\n this.loading = false;\n this.stopSpinner();\n }\n }\n\n /**\n * Compute the genomic extent and needed pixelWidth to repaint the canvas for the current genomic state.\n * Normally the canvas is size 3X the width of the viewport, however there is no left-right panning for WGV so\n * canvas width is viewport width.\n * @returns {{bpEnd: *, pixelWidth: (*|number), bpStart: number}}\n */\n repaintDimensions() {\n const isWGV = GenomeUtils.isWholeGenomeView(this.referenceFrame.chr);\n const pixelWidth = isWGV ? this.$viewport.width() : 3 * this.$viewport.width();\n const bpPerPixel = this.referenceFrame.bpPerPixel;\n const bpStart = this.referenceFrame.start - (isWGV ? 0 : pixelWidth / 3 * bpPerPixel);\n const bpEnd = this.referenceFrame.end + (isWGV ? 0 : pixelWidth / 3 * bpPerPixel);\n return {\n bpStart, bpEnd, pixelWidth\n }\n }\n\n /**\n * Repaint the canvas using the cached features\n *\n */\n repaint() {\n\n if (undefined === this.featureCache) {\n return\n }\n\n const {features, roiFeatures} = this.featureCache;\n\n // Canvas dimensions.\n // For deep tracks we paint a canvas == 3*viewportHeight centered on the current vertical scroll position\n const {bpStart, bpEnd, pixelWidth} = this.repaintDimensions();\n const viewportHeight = this.$viewport.height();\n const contentHeight = this.getContentHeight();\n const maxHeight = roiFeatures ? Math.max(contentHeight, viewportHeight) : contentHeight; // Need to fill viewport for ROIs.\n const pixelHeight = Math.min(maxHeight, 3 * viewportHeight);\n if (0 === pixelWidth || 0 === pixelHeight) {\n if (this.canvas) {\n $$1(this.canvas).remove();\n }\n return\n }\n const pixelTop = Math.max(0, -this.contentTop - Math.floor(pixelHeight / 3));\n\n const bpPerPixel = this.referenceFrame.bpPerPixel;\n const pixelXOffset = Math.round((bpStart - this.referenceFrame.start) / bpPerPixel);\n const canvasTop = (this.contentTop || 0) + pixelTop;\n const newCanvas = document.createElement('canvas');// $('').get(0)\n newCanvas.style.position = 'relative';\n newCanvas.style.display = 'block';\n newCanvas.style.width = pixelWidth + \"px\";\n newCanvas.style.height = pixelHeight + \"px\";\n newCanvas.style.left = pixelXOffset + \"px\";\n newCanvas.style.top = canvasTop + \"px\";\n\n // Always use high DPI if in \"FILL\" display mode, otherwise use track setting;\n const devicePixelRatio = (\"FILL\" === this.trackView.track.displayMode || this.trackView.track.supportHiDPI !== false) ?\n window.devicePixelRatio : 1;\n newCanvas.width = devicePixelRatio * pixelWidth;\n newCanvas.height = devicePixelRatio * pixelHeight;\n\n const ctx = newCanvas.getContext(\"2d\");\n ctx.scale(devicePixelRatio, devicePixelRatio);\n ctx.translate(0, -pixelTop);\n\n const drawConfiguration =\n {\n context: ctx,\n pixelXOffset,\n pixelWidth,\n pixelHeight,\n pixelTop,\n bpStart,\n bpEnd: bpEnd,\n bpPerPixel,\n referenceFrame: this.referenceFrame,\n selection: this.selection,\n viewport: this,\n viewportWidth: this.$viewport.width()\n };\n\n this.draw(drawConfiguration, features, roiFeatures);\n\n if (this.canvas) {\n $$1(this.canvas).remove();\n }\n newCanvas._data = drawConfiguration;\n this.canvas = newCanvas;\n this.$viewport.append($$1(newCanvas));\n\n }\n\n refresh() {\n if (!(this.canvas && this.featureCache)) return\n\n const drawConfiguration = this.canvas._data;\n drawConfiguration.context.clearRect(0, 0, this.canvas.width, this.canvas.height);\n const {features, roiFeatures} = this.featureCache;\n this.draw(drawConfiguration, features, roiFeatures);\n }\n\n /**\n * Draw the associated track.\n *\n * @param drawConfiguration\n * @param features\n * @param roiFeatures\n */\n draw(drawConfiguration, features, roiFeatures) {\n\n if (features) {\n drawConfiguration.features = features;\n this.trackView.track.draw(drawConfiguration);\n }\n if (roiFeatures && roiFeatures.length > 0) {\n for (let r of roiFeatures) {\n drawConfiguration.features = r.features;\n r.track.draw(drawConfiguration);\n }\n }\n }\n\n containsPosition(chr, position) {\n if (this.referenceFrame.chr === chr && position >= this.referenceFrame.start) {\n return position <= this.referenceFrame.calculateEnd(this.getWidth())\n } else {\n return false\n }\n }\n\n isLoading() {\n return this.loading\n }\n\n savePNG() {\n\n if (!this.canvas) return\n\n const canvasMetadata = this.canvas._data;\n const canvasTop = canvasMetadata ? canvasMetadata.pixelTop : 0;\n const devicePixelRatio = window.devicePixelRatio;\n const w = this.$viewport.width() * devicePixelRatio;\n const h = this.$viewport.height() * devicePixelRatio;\n const x = -$$1(this.canvas).position().left * devicePixelRatio;\n const y = (-this.contentTop - canvasTop) * devicePixelRatio;\n\n const ctx = this.canvas.getContext(\"2d\");\n const imageData = ctx.getImageData(x, y, w, h);\n const exportCanvas = document.createElement('canvas');\n const exportCtx = exportCanvas.getContext('2d');\n exportCanvas.width = imageData.width;\n exportCanvas.height = imageData.height;\n exportCtx.putImageData(imageData, 0, 0);\n\n // filename = this.trackView.track.name + \".png\";\n const filename = (this.$trackLabel.text() ? this.$trackLabel.text() : \"image\") + \".png\";\n const data = exportCanvas.toDataURL(\"image/png\");\n download(filename, data);\n }\n\n saveSVG() {\n\n const marginTop = 32;\n const marginLeft = 32;\n\n let {width, height} = this.browser.columnContainer.getBoundingClientRect();\n\n const h_render = 8000;\n\n const config =\n {\n\n width,\n height: h_render,\n\n backdropColor: 'white',\n\n multiLocusGap: 0,\n\n viewbox:\n {\n x: 0,\n y: 0,\n width,\n height: h_render\n }\n\n };\n\n const context = new ctx(config);\n\n const delta =\n {\n deltaX: marginLeft,\n deltaY: marginTop\n };\n\n this.renderViewportToSVG(context, delta);\n\n // reset height to trim away unneeded svg canvas real estate. Yes, a bit of a hack.\n context.setHeight(height);\n\n const str = (this.trackView.track.name || this.trackView.track.id).replace(/\\W/g, '');\n const index = this.browser.referenceFrameList.indexOf(this.referenceFrame);\n\n const svg = context.getSerializedSvg(true);\n const data = URL.createObjectURL(new Blob([svg], {type: \"application/octet-stream\"}));\n\n const id = `${str}_referenceFrame_${index}_guid_${domUtils.guid()}`;\n download(`${id}.svg`, data);\n\n }\n\n // called by trackView.renderSVGContext() when rendering\n // entire browser as SVG\n\n renderViewportToSVG(context, {deltaX, deltaY}) {\n\n if (this.$zoomInNotice && this.$zoomInNotice.is(\":visible\")) {\n return\n }\n\n const {width, height} = this.$viewport.get(0).getBoundingClientRect();\n\n const str = (this.trackView.track.name || this.trackView.track.id).replace(/\\W/g, '');\n const index = this.browser.referenceFrameList.indexOf(this.referenceFrame);\n const id = `${str}_referenceFrame_${index}_guid_${domUtils.guid()}`;\n this.drawSVGWithContext(context, width, height, id, deltaX, deltaY + this.contentTop, -this.contentTop);\n\n }\n\n renderSVGContext(context, {deltaX, deltaY}) {\n\n this.renderViewportToSVG(context, {deltaX, deltaY});\n\n if (this.$zoomInNotice && this.$zoomInNotice.is(\":visible\")) {\n return\n }\n\n if (this.$trackLabel && true === this.browser.trackLabelsVisible) {\n const {x, y, width, height} = domUtils.relativeDOMBBox(this.$viewport.get(0), this.$trackLabel.get(0));\n this.renderTrackLabelSVG(context, deltaX + x, deltaY + y, width, height);\n }\n\n }\n\n // render track label element called from renderSVGContext()\n renderTrackLabelSVG(context, tx, ty, width, height) {\n\n const str = (this.trackView.track.name || this.trackView.track.id).replace(/\\W/g, '');\n const id = `${str}_track_label_guid_${domUtils.guid()}`;\n\n context.saveWithTranslationAndClipRect(id, tx, ty, width, height, 0);\n\n context.fillStyle = \"white\";\n context.fillRect(0, 0, width, height);\n\n context.font = \"12px Arial\";\n context.fillStyle = 'rgb(68, 68, 68)';\n\n const {width: stringWidth} = context.measureText(this.$trackLabel.text());\n const dx = 0.25 * (width - stringWidth);\n const dy = 0.7 * (height - 12);\n context.fillText(this.$trackLabel.text(), dx, height - dy);\n\n context.strokeStyle = 'rgb(68, 68, 68)';\n context.strokeRect(0, 0, width, height);\n\n context.restore();\n\n }\n\n // called by renderSVGContext()\n drawSVGWithContext(context, width, height, id, x, y, yClipOffset) {\n\n context.saveWithTranslationAndClipRect(id, x, y, width, height, yClipOffset);\n\n let {start, bpPerPixel} = this.referenceFrame;\n\n const config =\n {\n context,\n viewport: this,\n referenceFrame: this.referenceFrame,\n top: yClipOffset,\n pixelTop: yClipOffset,\n pixelWidth: width,\n pixelHeight: height,\n bpStart: start,\n bpEnd: start + (width * bpPerPixel),\n bpPerPixel,\n viewportWidth: width,\n selection: this.selection\n };\n\n const features = this.featureCache ? this.featureCache.features : undefined;\n const roiFeatures = this.featureCache ? this.featureCache.roiFeatures : undefined;\n this.draw(config, features, roiFeatures);\n\n context.restore();\n\n }\n\n get cachedFeatures() {\n return this.featureCache ? this.featureCache.features : []\n }\n\n clearCache() {\n this.featureCache = undefined;\n if (this.canvas) this.canvas._data = undefined;\n }\n\n async getFeatures(track, chr, start, end, bpPerPixel) {\n if (this.featureCache && this.featureCache.containsRange(chr, start, end, bpPerPixel)) {\n return this.featureCache.features\n } else if (typeof track.getFeatures === \"function\") {\n const features = await track.getFeatures(chr, start, end, bpPerPixel, this);\n this.checkContentHeight(features);\n return features\n } else {\n return undefined\n }\n }\n\n needsRepaint() {\n\n if (!this.canvas) return true\n\n const data = this.canvas._data;\n return !data ||\n this.referenceFrame.start < data.bpStart ||\n this.referenceFrame.end > data.bpEnd ||\n this.referenceFrame.chr !== data.referenceFrame.chr ||\n this.referenceFrame.bpPerPixel != data.bpPerPixel\n }\n\n needsReload() {\n if (!this.featureCache) return true\n const {chr, bpPerPixel} = this.referenceFrame;\n const {bpStart, bpEnd} = this.repaintDimensions();\n return (!this.featureCache.containsRange(chr, bpStart, bpEnd, bpPerPixel))\n }\n\n createZoomInNotice($parent) {\n\n const $container = $$1('
', {class: 'igv-zoom-in-notice-container'});\n $parent.append($container);\n\n const $e = $$1('
');\n $container.append($e);\n\n $e.text('Zoom in to see features');\n\n $container.hide();\n\n return $container\n }\n\n viewIsReady() {\n return this.browser && this.browser.referenceFrameList && this.referenceFrame\n }\n\n addMouseHandlers() {\n\n const viewport = this.$viewport.get(0);\n\n this.addViewportContextMenuHandler(viewport);\n\n // Mouse down\n const md = (event) => {\n this.enableClick = true;\n this.browser.mouseDownOnViewport(event, this);\n domUtils.pageCoordinates(event);\n };\n viewport.addEventListener('mousedown', md);\n viewport.addEventListener('touchstart', md);\n\n // Mouse up\n const mu = (event) => {\n // Any mouse up cancels drag and scrolling\n if (this.browser.dragObject || this.browser.isScrolling) {\n this.browser.cancelTrackPan();\n // event.preventDefault();\n // event.stopPropagation();\n this.enableClick = false; // Until next mouse down\n } else {\n this.browser.cancelTrackPan();\n this.browser.endTrackDrag();\n }\n };\n viewport.addEventListener('mouseup', mu);\n viewport.addEventListener('touchend', mu);\n\n // Mouse move\n if (typeof this.trackView.track.hoverText === 'function') {\n viewport.addEventListener('mousemove', (event => {\n if (event.buttons === 0 && (Date.now() - lastHoverUpdateTime > 100)) {\n lastHoverUpdateTime = Date.now();\n const clickState = this.createClickState(event);\n if (clickState) {\n const tooltip = this.trackView.track.hoverText(clickState);\n if (tooltip) {\n this.$viewport[0].setAttribute(\"title\", tooltip);\n } else {\n this.$viewport[0].removeAttribute(\"title\");\n }\n }\n }\n }));\n }\n\n this.addViewportClickHandler(this.$viewport.get(0));\n\n if (this.trackView.track.name && \"sequence\" !== this.trackView.track.config.type) {\n this.addTrackLabelClickHandler(this.$trackLabel.get(0));\n }\n\n }\n\n addViewportContextMenuHandler(viewport) {\n\n viewport.addEventListener('contextmenu', (event) => {\n\n // Ignore if we are doing a drag. This can happen with touch events.\n if (this.browser.dragObject) {\n return false\n }\n\n const clickState = this.createClickState(event);\n\n if (undefined === clickState) {\n return false\n }\n\n event.preventDefault();\n\n // Track specific items\n let menuItems = [];\n if (typeof this.trackView.track.contextMenuItemList === \"function\") {\n const trackMenuItems = this.trackView.track.contextMenuItemList(clickState);\n if (trackMenuItems) {\n menuItems = trackMenuItems;\n }\n }\n\n // Add items common to all tracks\n if (menuItems.length > 0) {\n menuItems.push({label: $$1('
')});\n }\n\n menuItems.push({label: 'Save Image (PNG)', click: () => this.savePNG()});\n menuItems.push({label: 'Save Image (SVG)', click: () => this.saveSVG()});\n\n this.browser.menuPopup.presentTrackContextMenu(event, menuItems);\n });\n\n }\n\n\n addViewportClickHandler(viewport) {\n\n viewport.addEventListener('click', (event) => {\n\n if (this.enableClick && this.canvas) {\n if (3 === event.which || event.ctrlKey) {\n return\n }\n\n // Close any currently open popups\n $$1('.igv-popover').hide();\n\n\n if (this.browser.dragObject || this.browser.isScrolling) {\n return\n }\n\n // Treat as a mouse click, its either a single or double click.\n // Handle here and stop propogation / default\n event.preventDefault();\n\n const mouseX = domUtils.translateMouseCoordinates(event, this.$viewport.get(0)).x;\n const mouseXCanvas = domUtils.translateMouseCoordinates(event, this.canvas).x;\n const referenceFrame = this.referenceFrame;\n const xBP = Math.floor((referenceFrame.start) + referenceFrame.toBP(mouseXCanvas));\n\n const time = Date.now();\n\n if (time - lastClickTime < this.browser.constants.doubleClickDelay) {\n\n // double-click\n if (popupTimerID) {\n window.clearTimeout(popupTimerID);\n popupTimerID = undefined;\n }\n\n const centerBP = Math.round(referenceFrame.start + referenceFrame.toBP(mouseX));\n\n let string;\n\n if ('all' === this.referenceFrame.chr.toLowerCase()) {\n\n const chr = this.browser.genome.getChromosomeCoordinate(centerBP).chr;\n\n if (1 === this.browser.referenceFrameList.length) {\n string = chr;\n } else {\n const loci = this.browser.referenceFrameList.map(({locusSearchString}) => locusSearchString);\n const index = this.browser.referenceFrameList.indexOf(this.referenceFrame);\n loci[index] = chr;\n string = loci.join(' ');\n }\n\n this.browser.search(string);\n\n } else {\n this.browser.zoomWithScaleFactor(0.5, centerBP, this.referenceFrame);\n }\n\n\n } else {\n // single-click\n\n if (event.shiftKey && typeof this.trackView.track.shiftClick === \"function\") {\n\n this.trackView.track.shiftClick(xBP, event);\n\n } else if (typeof this.trackView.track.popupData === \"function\") {\n\n popupTimerID = setTimeout(() => {\n\n const content = this.getPopupContent(event);\n if (content) {\n if (this.popover) this.popover.dispose();\n this.popover = new Popover(this.browser.columnContainer);\n this.popover.presentContentWithEvent(event, content);\n }\n window.clearTimeout(popupTimerID);\n popupTimerID = undefined;\n },\n this.browser.constants.doubleClickDelay);\n }\n }\n\n lastClickTime = time;\n\n }\n });\n }\n\n addTrackLabelClickHandler(trackLabel) {\n\n trackLabel.addEventListener('click', (event) => {\n\n event.stopPropagation();\n\n const {track} = this.trackView;\n\n let str;\n if (typeof track.description === 'function') {\n str = track.description();\n } else if (track.description) {\n str = `
${track.description}
`;\n }\n\n if (str) {\n if (this.popover) {\n this.popover.dispose();\n }\n this.popover = new Popover(this.browser.columnContainer, (track.name || ''));\n this.popover.presentContentWithEvent(event, str);\n }\n });\n }\n\n createClickState(event) {\n\n if (!this.canvas) return // Can happen during initialization\n\n const referenceFrame = this.referenceFrame;\n const viewportCoords = domUtils.translateMouseCoordinates(event, this.$viewport.get(0));\n const canvasCoords = domUtils.translateMouseCoordinates(event, this.canvas);\n const genomicLocation = ((referenceFrame.start) + referenceFrame.toBP(viewportCoords.x));\n\n return {\n event,\n viewport: this,\n referenceFrame,\n genomicLocation,\n y: viewportCoords.y - this.contentTop,\n canvasX: canvasCoords.x,\n canvasY: canvasCoords.y\n }\n\n }\n\n getPopupContent(event) {\n\n const clickState = this.createClickState(event);\n\n if (undefined === clickState) {\n return\n }\n\n let track = this.trackView.track;\n const dataList = track.popupData(clickState);\n\n const popupClickHandlerResult = this.browser.fireEvent('trackclick', [track, dataList]);\n\n let content;\n if (undefined === popupClickHandlerResult || true === popupClickHandlerResult) {\n // Indicates handler did not handle the result, or the handler wishes default behavior to occur\n if (dataList && dataList.length > 0) {\n content = formatPopoverText(dataList);\n }\n\n } else if (typeof popupClickHandlerResult === 'string') {\n content = popupClickHandlerResult;\n }\n\n return content\n }\n\n\n}\n\n\nfunction formatPopoverText(nameValues) {\n\n const rows = nameValues.map(nameValue => {\n\n if (nameValue.name) {\n const str = `${nameValue.name}   ${nameValue.value}`;\n return `
${str}
`\n } else if ('
' === nameValue) { // this can be retired if nameValue.html is allowed.\n return nameValue\n } else if (nameValue.html) {\n return nameValue.html\n } else {\n return `
${nameValue}
`\n }\n\n });\n\n return rows.join('')\n}\n\nclass FeatureCache {\n\n constructor(chr, tileStart, tileEnd, bpPerPixel, features, roiFeatures, multiresolution) {\n this.chr = chr;\n this.bpStart = tileStart;\n this.bpEnd = tileEnd;\n this.bpPerPixel = bpPerPixel;\n this.features = features;\n this.roiFeatures = roiFeatures;\n this.multiresolution = multiresolution;\n }\n\n containsRange(chr, start, end, bpPerPixel) {\n\n // For multi-resolution tracks allow for a 2X change in bpPerPixel\n const r = this.multiresolution ? this.bpPerPixel / bpPerPixel : 1;\n\n return start >= this.bpStart && end <= this.bpEnd && chr === this.chr && r > 0.5 && r < 2\n }\n\n overlapsRange(chr, start, end) {\n return this.chr === chr && end >= this.bpStart && start <= this.bpEnd\n }\n}\n\n/**\n * Decode UCSC \"interact\" files. See https://genome.ucsc.edu/goldenpath/help/interact.html\n *\n 0 string chrom; \"Chromosome (or contig, scaffold, etc.). For interchromosomal, use 2 records\"\n 1 uint chromStart; \"Start position of lower region. For interchromosomal, set to chromStart of this region\"\n 2 uint chromEnd; \"End position of upper region. For interchromosomal, set to chromEnd of this region\"\n 3 string name; \"Name of item, for display. Usually 'sourceName/targetName/exp' or empty\"\n 4 uint score; \"Score (0-1000)\"\n 5 double value; \"Strength of interaction or other data value. Typically basis for score\"\n 6 string exp; \"Experiment name (metadata for filtering). Use . if not applicable\"\n 7 string color; \"Item color. Specified as r,g,b or hexadecimal #RRGGBB or html color name, as in //www.w3.org/TR/css3-color/#html4. Use 0 and spectrum setting to shade by score\"\n 8 string sourceChrom; \"Chromosome of source region (directional) or lower region. For non-directional interchromosomal, chrom of this region.\"\n 9 uint sourceStart; \"Start position in chromosome of source/lower/this region\"\n 10 uint sourceEnd; \"End position in chromosome of source/lower/this region\"\n 11 string sourceName; \"Identifier of source/lower/this region\"\n 12 string sourceStrand; \"Orientation of source/lower/this region: + or -. Use . if not applicable\"\n 13 string targetChrom; \"Chromosome of target region (directional) or upper region. For non-directional interchromosomal, chrom of other region\"\n 14 uint targetStart; \"Start position in chromosome of target/upper/this region\"\n 15 uint targetEnd; \"End position in chromosome of target/upper/this region\"\n 16 string targetName; \"Identifier of target/upper/this region\"\n 17 string targetStrand; \"Orientation of target/upper/this region: + or -. Use . if not applicable\"\n *\n * @param tokens\n * @param ignore\n * @returns {*}\n */\nfunction decodeInteract(tokens, header) {\n\n if (tokens.length < 6) {\n console.log(\"Skipping line: \" + tokens.join(' '));\n return undefined\n }\n\n var feature = {\n chr: tokens[0],\n start: tokens[1],\n end: tokens[2],\n\n chr1: tokens[8],\n start1: Number.parseInt(tokens[9]),\n end1: Number.parseInt(tokens[10]),\n\n chr2: tokens[13],\n start2: Number.parseInt(tokens[14]),\n end2: Number.parseInt(tokens[15]),\n\n name: tokens[3],\n score: Number(tokens[4]),\n value: Number(tokens[5]),\n color: tokens[7] === '.' ? undefined : tokens[7] === \"0\" ? \"rgb(0,0,0)\" : tokens[7],\n\n };\n\n return feature\n}\n\n/**\n * Some interpretations of the sequence ontology needed to assemble GFF transcripts.\n *\n */\n\nconst transcriptTypes = new Set(['transcript', 'primary_transcript', 'processed_transcript', 'mRNA', 'mrna',\n 'lnc_RNA', 'miRNA', 'ncRNA', 'rRNA', 'scRNA', 'snRNA', 'snoRNA', 'tRNA']);\nconst cdsTypes = new Set(['CDS', 'cds']);\nconst codonTypes = new Set(['start_codon', 'stop_codon']);\nconst utrTypes = new Set(['5UTR', '3UTR', 'UTR', 'five_prime_UTR', 'three_prime_UTR', \"3'-UTR\", \"5'-UTR\"]);\nconst exonTypes = new Set(['exon', 'coding-exon']);\n\nconst transcriptPartTypes = new Set();\nfor (let cltn of [cdsTypes, codonTypes, utrTypes, exonTypes]) {\n for (let t of cltn) {\n transcriptPartTypes.add(t);\n }\n}\n\nfunction isExon(type) {\n return exonTypes.has(type)\n}\n\nfunction isIntron(type) {\n return type.includes(\"intron\")\n}\n\nfunction isCoding(type) {\n return cdsTypes.has(type) || codonTypes.has(type)\n}\n\nfunction isUTR(type) {\n return utrTypes.has(type)\n}\n\nfunction isTranscript(type) {\n return transcriptTypes.has(type) || type.endsWith(\"RNA\") || type.endsWith(\"transcript\")\n}\n\nfunction isTranscriptPart(type) {\n return transcriptPartTypes.has(type) || type.endsWith(\"RNA\") || isIntron(type)\n}\n\nconst filterPopupProperties = new Set([\"id\", \"parent\", \"name\"]);\n\nclass GFFFeature {\n\n constructor(properties) {\n Object.assign(this, properties);\n }\n\n popupData(genomicLocation) {\n\n const pd = this.geneObject ? this.geneObject.popupData() : [];\n\n if (this.geneObject) {\n pd.push('
');\n }\n\n if (this.name) {\n pd.push({name: 'Name', value: this.name});\n }\n\n pd.push({name: 'Type', value: this.type});\n pd.push({name: 'Source', value: this.source});\n if (this.score !== undefined) {\n pd.push({name: 'Score', value: this.score});\n }\n\n if (this.attributeString) {\n const atts = parseAttributeString(this.attributeString, this.delim);\n for (let [key, value] of atts) {\n if (value !== undefined && value.length > 0 && !filterPopupProperties.has(key.toLowerCase())) {\n pd.push({name: key + \":\", value: value});\n }\n }\n }\n pd.push({\n name: 'Location',\n value: `${this.chr}:${numberFormatter$1(this.start + 1)}-${numberFormatter$1(this.end)}`\n });\n return pd\n }\n\n getAttributeValue(attributeName) {\n if (this.hasOwnProperty(attributeName)) {\n return this[attributeName]\n } else {\n // TODO -- fetch from attribute string and cache\n if (!this._attributeCache) {\n this._attributeCache = new Map();\n }\n if (this._attributeCache.has(attributeName)) {\n return this._attributeCache.get(attributeName)\n } else {\n const atts = parseAttributeString(this.attributeString, this.delim);\n let v;\n for (let [key, value] of atts) {\n if (key === attributeName) {\n v = value;\n break\n }\n }\n this._attributeCache.set(attributeName, v);\n return v\n }\n }\n }\n}\n\nclass GFFTranscript extends GFFFeature {\n\n constructor(feature) {\n super(feature);\n this.exons = [];\n this.parts = [];\n }\n\n addExon(feature) {\n\n this.exons.push(feature);\n\n // Expand feature -- for transcripts not explicitly represented in the file (gtf)\n this.start = Math.min(this.start, feature.start);\n this.end = Math.max(this.end, feature.end);\n }\n\n addPart(feature) {\n this.parts.push(feature);\n }\n\n assembleParts() {\n\n if (this.parts.length === 0) return\n\n this.parts.sort(function (a, b) {\n return a.start - b.start\n });\n\n // Create exons, if neccessary\n let lastStart = this.parts[0].start;\n let lastEnd = this.parts[0].end;\n for (let i = 1; i < this.parts.length; i++) {\n const part = this.parts[i];\n if (isIntron(part.type)) {\n continue\n }\n if (part.start <= lastEnd) {\n lastEnd = Math.max(lastEnd, part.end);\n } else {\n let exon = this.findExonContaining({start: lastStart, end: lastEnd});\n if (!exon) {\n this.exons.push({start: lastStart, end: lastEnd, psuedo: true});\n }\n lastStart = part.start;\n lastEnd = part.end;\n }\n }\n let exon = this.findExonContaining({start: lastStart, end: lastEnd});\n if (!exon) {\n this.exons.push({start: lastStart, end: lastEnd, psuedo: true});\n this.start = Math.min(this.start, lastStart);\n this.end = Math.max(this.end, lastEnd);\n }\n\n\n for (let part of this.parts) {\n const type = part.type;\n if (isCoding(type)) {\n this.addCDS(part);\n } else if (isUTR(type)) {\n this.addUTR(part);\n }\n }\n }\n\n findExonContaining({start, end}) {\n for (let exon of this.exons) {\n if (exon.end >= end && exon.start <= start) {\n return exon\n }\n }\n return undefined\n }\n\n addCDS(cds) {\n\n let exon;\n const exons = this.exons;\n\n for (let e of exons) {\n if (e.start <= cds.start && e.end >= cds.end) {\n exon = e;\n break\n }\n }\n\n if (exon) {\n exon.cdStart = exon.cdStart ? Math.min(cds.start, exon.cdStart) : cds.start;\n exon.cdEnd = exon.cdEnd ? Math.max(cds.end, exon.cdEnd) : cds.end;\n } else {\n // cds.cdStart = cds.start\n // cds.cdEnd = cds.end\n // exons.push(cds)\n console.error(\"No exon found spanning \" + cds.start + \"-\" + cds.end);\n }\n\n // Expand feature -- for transcripts not explicitly represented in the file (gtf files)\n // this.start = Math.min(this.start, cds.start);\n // this.end = Math.max(this.end, cds.end);\n\n this.cdStart = this.cdStart ? Math.min(cds.start, this.cdStart) : cds.start;\n this.cdEnd = this.cdEnd ? Math.max(cds.end, this.cdEnd) : cds.end;\n }\n\n addUTR(utr) {\n\n let exon;\n const exons = this.exons;\n\n // Find exon containing CDS\n for (let i = 0; i < exons.length; i++) {\n if (exons[i].start <= utr.start && exons[i].end >= utr.end) {\n exon = exons[i];\n break\n }\n }\n\n if (exon) {\n if (utr.start === exon.start && utr.end === exon.end) {\n exon.utr = true;\n } else {\n if (utr.end < exon.end) {\n exon.cdStart = utr.end;\n }\n if (utr.start > exon.start) {\n exon.cdEnd = utr.start;\n }\n }\n\n } else {\n // utr.utr = true\n // exons.push(utr)\n console.error(\"No exon found spanning \" + cds.start + \"-\" + cds.end);\n }\n\n // Expand feature -- for transcripts not explicitly represented in the file\n // this.start = Math.min(this.start, utr.start);\n // this.end = Math.max(this.end, utr.end);\n\n }\n\n finish() {\n\n this.assembleParts();\n\n var cdStart = this.cdStart;\n var cdEnd = this.cdEnd;\n\n this.exons.sort(function (a, b) {\n return a.start - b.start\n });\n\n // Search for UTR exons that were not explicitly tagged\n if (cdStart) {\n this.exons.forEach(function (exon) {\n if (exon.end < cdStart || exon.start > cdEnd) exon.utr = true;\n });\n }\n }\n\n popupData(genomicLocation) {\n\n const pd = super.popupData(genomicLocation);\n\n // If clicked over an exon add its attributes\n for (let exon of this.exons) {\n if (exon.pseudo) continue // An implicit exon\n if (genomicLocation >= exon.start && genomicLocation < exon.end && typeof exon.popupData === 'function') {\n pd.push('
');\n const exonData = exon.popupData(genomicLocation);\n for (let att of exonData) {\n pd.push(att);\n }\n }\n }\n\n for (let part of this.parts) {\n if (genomicLocation >= part.start && genomicLocation < part.end && typeof part.popupData === 'function') {\n pd.push('
');\n const partData = part.popupData(genomicLocation);\n for (let att of partData) {\n pd.push(att);\n }\n }\n }\n\n\n return pd\n }\n}\n\nfunction decode(tokens, header) {\n\n const format = header.format;\n if (tokens.length < 9) {\n return undefined // Not a valid gff record\n }\n\n const delim = ('gff3' === format) ? '=' : ' ';\n return new GFFFeature({\n source: decodeGFFAttribute(tokens[1]),\n type: tokens[2],\n chr: tokens[0],\n start: parseInt(tokens[3]) - 1,\n end: parseInt(tokens[4]),\n score: \".\" === tokens[5] ? undefined : Number(tokens[5]),\n strand: tokens[6],\n phase: \".\" === tokens[7] ? 0 : parseInt(tokens[7]),\n attributeString: tokens[8],\n delim: delim\n })\n}\n\n\n/**\n * Decode a single gff record (1 line in file). Aggregations such as gene models are constructed at a higher level.\n * ctg123 . mRNA 1050 9000 . + . ID=mRNA00001;Parent=gene00001\n * @param tokens\n * @param ignore\n * @returns {*}\n */\nfunction decodeGFF3(tokens, header) {\n\n const feature = decode(tokens, header);\n\n if (!feature) {\n return\n }\n\n const attributes = parseAttributeString(feature.attributeString, feature.delim);\n\n // Search for color value as case insenstivie key\n for (let [key, value] of attributes) {\n const keyLower = key.toLowerCase();\n if (\"color\" === keyLower || \"colour\" === keyLower) {\n feature.color = IGVColor.createColorString(value);\n } else if (key === \"ID\") {\n feature.id = value;\n } else if (key === \"Parent\") {\n feature.parent = value;\n }\n }\n return feature\n}\n\n/**\n * GTF format example:\n NC_000008.11 BestRefSeq gene 127735434 127742951 . + . gene_id \"MYC\"; transcript_id \"\"; db_xref \"GeneID:4609\"; db_xref \"HGNC:HGNC:7553\"; db_xref \"MIM:190080\"; description \"MYC proto-oncogene, bHLH transcription factor\"; gbkey \"Gene\"; gene \"MYC\"; gene_biotype \"protein_coding\"; gene_synonym \"bHLHe39\"; gene_synonym \"c-Myc\"; gene_synonym \"MRTL\"; gene_synonym \"MYCC\";\n NC_000008.11 BestRefSeq transcript 127735434 127742951 . + . gene_id \"MYC\"; transcript_id \"NM_001354870.1\"; db_xref \"GeneID:4609\"; gbkey \"mRNA\"; gene \"MYC\"; product \"MYC proto-oncogene, bHLH transcription factor, transcript variant 2\"; transcript_biotype \"mRNA\";\n NC_000008.11 BestRefSeq exon 127735434 127736623 . + . gene_id \"MYC\"; transcript_id \"NM_001354870.1\"; db_xref \"GeneID:4609\"; gene \"MYC\"; product \"MYC proto-oncogene, bHLH transcription factor, transcript variant 2\"; transcript_biotype \"mRNA\"; exon_number \"1\";\n *\n * @param tokens\n * @param ignore\n * @returns {*}\n */\nfunction decodeGTF(tokens, header) {\n\n const feature = decode(tokens, header);\n\n if (!feature) {\n return\n }\n\n const attributes = parseAttributeString(feature.attributeString, feature.delim);\n\n // GTF files specify neither ID nor parent fields, but they can be inferred from common conventions\n let idField;\n let parentField;\n switch (feature.type) {\n case \"gene\":\n idField = \"gene_id\";\n break\n case \"transcript\":\n idField = \"transcript_id\";\n parentField = \"gene_id\";\n break\n default:\n parentField = \"transcript_id\";\n }\n\n for (let [key, value] of attributes) {\n const keyLower = key.toLowerCase();\n if (\"color\" === keyLower || \"colour\" === keyLower) {\n feature.color = IGVColor.createColorString(value);\n } else if (key === idField) {\n feature.id = value;\n } else if (key === parentField) {\n feature.parent = value;\n }\n }\n return feature\n\n}\n\n\n/**\n * Parse the attribute string, returning an array of key-value pairs. An array is used rather than a map as attribute\n * keys are not required to be unique.\n *\n * @param attributeString\n * @param keyValueDelim\n * @returns {[]}\n */\nfunction parseAttributeString(attributeString, keyValueDelim, relaxed = false) {\n // parse 'attributes' string (see column 9 docs in https://github.com/The-Sequence-Ontology/Specifications/blob/master/gff3.md)\n var attributes = [];\n for (let kv of attributeString.split(';')) {\n kv = kv.trim();\n const idx = kv.indexOf(keyValueDelim);\n if (idx > 0 && idx < kv.length - 1) {\n const key = stripQuotes(decodeGFFAttribute(kv.substring(0, idx).trim(), relaxed));\n let value = stripQuotes(decodeGFFAttribute(kv.substring(idx + 1).trim(), relaxed));\n attributes.push([key, value]);\n }\n }\n return attributes\n}\n\nfunction stripQuotes(value) {\n if (value.startsWith('\"') && value.endsWith('\"')) {\n value = value.substr(1, value.length - 2);\n }\n return value\n}\n\n// GFF3 attributes have specific percent encoding rules, the list below are required, all others are forbidden\n/*\ntab (%09)\nnewline (%0A)\ncarriage return (%0D)\n% percent (%25)\ncontrol characters (%00 through %1F, %7F)\nIn addition, the following characters have reserved meanings in column 9 and must be escaped when used in other contexts:\n; semicolon (%3B)\n= equals (%3D)\n& ampersand (%26)\n, comma (%2C)\n */\n\nconst encodings = new Map([\n [\"%09\", \"\\t\"],\n [\"%0A\", \"\\n\"],\n [\"%0D\", \"\\r\"],\n [\"%25\", \"%\"],\n [\"%3B\", \";\"],\n [\"%3D\", \"=\"],\n [\"%26\", \"&\"],\n [\"%2C\", \",\"]\n]);\n\nfunction decodeGFFAttribute(str, relaxed = false) {\n\n if (!str.includes(\"%\")) {\n return str\n }\n if (relaxed) {\n return decodeURIComponent(str);\n }\n let decoded = \"\";\n for (let i = 0; i < str.length; i++) {\n\n if (str.charCodeAt(i) === 37 && i < str.length - 2) {\n const key = str.substring(i, i + 3);\n if (encodings.has(key)) {\n decoded += encodings.get(key);\n } else {\n decoded += key;\n }\n i += 2;\n } else {\n decoded += str.charAt(i);\n }\n }\n return decoded\n\n}\n\n/**\n * Wrapper class to record a decoding error.\n */\n\nclass DecodeError {\n constructor(message) {\n this.message = message;\n }\n}\n\n/**\n * Decode the UCSC bed format. Only the first 3 columns (chr, start, end) are required. The remaining columns\n * must follow standard bed order, but we will tolerate deviations after column 3.\n *\n * @param tokens\n * @param ignore\n * @returns decoded feature, or null if this is not a valid record\n */\nfunction decodeBed(tokens, header) {\n\n\n if (tokens.length < 3) return undefined\n\n header && header.gffTags;\n\n const chr = tokens[0];\n const start = parseInt(tokens[1]);\n const end = tokens.length > 2 ? parseInt(tokens[2]) : start + 1;\n if (isNaN(start) || isNaN(end)) {\n return new DecodeError(`Unparsable bed record.`)\n }\n const feature = new UCSCBedFeature({chr: chr, start: start, end: end, score: 1000});\n\n try {\n if (tokens.length > 3) {\n\n // Potentially parse name field as GFF column 9 style streng.\n if (tokens[3].indexOf(';') > 0 && tokens[3].indexOf('=') > 0) {\n const attributeKVs = parseAttributeString(tokens[3], '=', true);\n feature.attributes = {};\n for (let kv of attributeKVs) {\n feature.attributes[kv[0]] = kv[1];\n if (header.nameField != undefined && kv[0] === header.nameField) {\n feature.name = kv[1];\n }\n }\n }\n if (!feature.name) {\n feature.name = tokens[3] === '.' ? '' : tokens[3];\n }\n }\n\n if (tokens.length > 4) {\n feature.score = tokens[4] === '.' ? 0 : Number(tokens[4]);\n if (isNaN(feature.score)) {\n return feature\n }\n }\n\n if (tokens.length > 5) {\n feature.strand = tokens[5];\n if (!(feature.strand === '.' || feature.strand === '+' || feature.strand === '-')) {\n return feature\n }\n }\n\n if (tokens.length > 6) {\n feature.cdStart = parseInt(tokens[6]);\n if (isNaN(feature.cdStart)) {\n return feature\n }\n }\n\n if (tokens.length > 7) {\n feature.cdEnd = parseInt(tokens[7]);\n if (isNaN(feature.cdEnd)) {\n return feature\n }\n }\n\n if (tokens.length > 8) {\n if (tokens[8] !== \".\" && tokens[8] !== \"0\")\n feature.color = IGVColor.createColorString(tokens[8]);\n }\n\n if (tokens.length > 11) {\n const exonCount = parseInt(tokens[9]);\n // Some basic validation\n if (exonCount > 1000) {\n // unlikely\n return feature\n }\n\n const exonSizes = tokens[10].replace(/,$/, '').split(',');\n const exonStarts = tokens[11].replace(/,$/, '').split(',');\n if (!(exonSizes.length === exonStarts.length && exonCount === exonSizes.length)) {\n return feature\n }\n\n const exons = [];\n for (let i = 0; i < exonCount; i++) {\n const eStart = start + parseInt(exonStarts[i]);\n const eEnd = eStart + parseInt(exonSizes[i]);\n exons.push({start: eStart, end: eEnd});\n }\n if (exons.length > 0) {\n findUTRs$1(exons, feature.cdStart, feature.cdEnd);\n feature.exons = exons;\n }\n }\n\n // Optional extra columns\n if (header) {\n let thicknessColumn = header.thicknessColumn;\n let colorColumn = header.colorColumn;\n if (colorColumn && colorColumn < tokens.length) {\n feature.color = IGVColor.createColorString(tokens[colorColumn]);\n }\n if (thicknessColumn && thicknessColumn < tokens.length) {\n feature.thickness = tokens[thicknessColumn];\n }\n }\n } catch\n (e) {\n\n }\n\n return feature\n}\n\n/**\n * Decode a UCSC repeat masker record.\n */\nfunction decodeRepeatMasker(tokens, header) {\n\n /**\n * Columns, from UCSC documentation\n *\n * 0 bin 585 smallint(5) unsigned Indexing field to speed chromosome range queries.\n * 1 swScore 1504 int(10) unsigned Smith Waterman alignment score\n * 2 milliDiv 13 int(10) unsigned Base mismatches in parts per thousand\n * 3 milliDel 4 int(10) unsigned Bases deleted in parts per thousand\n * 4 milliIns 13 int(10) unsigned Bases inserted in parts per thousand\n * 5 genoName chr1 varchar(255) Genomic sequence name\n * 6 genoStart 10000 int(10) unsigned Start in genomic sequence\n * 7 genoEnd 10468 int(10) unsigned End in genomic sequence\n * 8 genoLeft -249240153 int(11) -#bases after match in genomic sequence\n * 9 strand + char(1) Relative orientation + or -\n * 10 repName (CCCTAA)n varchar(255) Name of repeat\n * 11 repClass Simple_repeat varchar(255) Class of repeat\n * 12 repFamily Simple_repeat varchar(255) Family of repeat\n * 13 repStart 1 int(11) Start (if strand is +) or -#bases after match (if strand is -) in repeat sequence\n * 14 repEnd 463 int(11) End in repeat sequence\n * 15 repLeft 0 int(11) -#bases after match (if strand is +) or start (if strand is -) in repeat sequence\n * 16 id 1 char(1) First digit of id field in RepeatMasker .out file. Best ignored.\n */\n if (tokens.length <= 15) return undefined\n\n const feature = {\n swScore: Number.parseInt(tokens[1]),\n milliDiv: Number.parseInt(tokens[2]),\n milliDel: Number.parseInt(tokens[3]),\n milliIns: Number.parseInt(tokens[4]),\n chr: tokens[5],\n start: Number.parseInt(tokens[6]),\n end: Number.parseInt(tokens[7]),\n //genoLeft: tokens[8],\n strand: tokens[9],\n repName: tokens[10],\n repClass: tokens[11],\n repFamily: tokens[12],\n repStart: Number.parseInt(tokens[13]),\n repEnd: Number.parseInt(tokens[14]),\n repLeft: Number.parseInt(tokens[15])\n };\n\n return feature\n\n}\n\n/**\n * Decode a UCSC \"genePred\" record.\n *\n * @param tokens\n * @param ignore\n * @returns {*}\n */\nfunction decodeGenePred(tokens, header) {\n\n var shift = header.shift === undefined ? 0 : 1;\n\n if (tokens.length <= 9 + shift) return undefined\n\n const cdStart = parseInt(tokens[5 + shift]);\n const cdEnd = parseInt(tokens[6 + shift]);\n var feature = {\n name: tokens[0 + shift],\n chr: tokens[1 + shift],\n strand: tokens[2 + shift],\n start: parseInt(tokens[3 + shift]),\n end: parseInt(tokens[4 + shift]),\n cdStart: cdStart,\n cdEnd: cdEnd,\n id: tokens[0 + shift]\n };\n const exons = decodeExons(parseInt(tokens[7 + shift]), tokens[8 + shift], tokens[9 + shift]);\n findUTRs$1(exons, cdStart, cdEnd);\n\n feature.exons = exons;\n\n return feature\n\n}\n\n/**\n * Decode a UCSC \"genePredExt\" record. refGene files are in this format.\n *\n * @param tokens\n * @param ignore\n * @returns {*}\n */\nfunction decodeGenePredExt(tokens, header) {\n\n var shift = header.shift === undefined ? 0 : 1;\n\n if (tokens.length <= 11 + shift) return undefined\n\n const cdStart = parseInt(tokens[5 + shift]);\n const cdEnd = parseInt(tokens[6 + shift]);\n const feature = {\n name: tokens[11 + shift],\n chr: tokens[1 + shift],\n strand: tokens[2 + shift],\n start: parseInt(tokens[3 + shift]),\n end: parseInt(tokens[4 + shift]),\n cdStart: cdStart,\n cdEnd: cdEnd,\n id: tokens[0 + shift]\n };\n\n const exons = decodeExons(parseInt(tokens[7 + shift]), tokens[8 + shift], tokens[9 + shift]);\n findUTRs$1(exons, cdStart, cdEnd);\n\n feature.exons = exons;\n\n return feature\n}\n\n/**\n * Decode a UCSC \"refFlat\" record\n * @param tokens\n * @param ignore\n * @returns {*}\n */\nfunction decodeReflat(tokens, header) {\n\n var shift = header.shift === undefined ? 0 : 1;\n\n if (tokens.length <= 10 + shift) return undefined\n\n const cdStart = parseInt(tokens[6 + shift]);\n const cdEnd = parseInt(tokens[7 + shift]);\n var feature = {\n name: tokens[0 + shift],\n id: tokens[1 + shift],\n chr: tokens[2 + shift],\n strand: tokens[3 + shift],\n start: parseInt(tokens[4 + shift]),\n end: parseInt(tokens[5 + shift]),\n cdStart: cdStart,\n cdEnd: cdEnd\n };\n\n const exons = decodeExons(parseInt(tokens[8 + shift]), tokens[9 + shift], tokens[10 + shift]);\n findUTRs$1(exons, cdStart, cdEnd);\n feature.exons = exons;\n\n return feature\n}\n\n/**\n * Decode a UCS PSL record *\n * @param tokens\n * @param header\n * @returns {DecodeError|UCSCBedFeature|undefined}\n */\nfunction decodePSL(tokens, header) {\n\n /*\n * 0 matches - Number of bases that match that aren't repeats\n * 1 misMatches - Number of bases that don't match\n * 2 repMatches - Number of bases that match but are part of repeats\n * 3 nCount - Number of \"N\" bases\n * 4 qNumInsert - Number of inserts in query\n * 5 qBaseInsert - Number of bases inserted in query\n * 6 tNumInsert - Number of inserts in target\n * 7 tBaseInsert - Number of bases inserted in target\n * 8 strand - \"+\" or \"-\" for query strand. For translated alignments, second \"+\"or \"-\" is for target genomic strand.\n * 9 qName - Query sequence name\n * 10 qSize - Query sequence size.\n * 11 qStart - Alignment start position in query\n * 12 qEnd - Alignment end position in query\n * 13 tName - Target sequence name\n * 14 tSize - Target sequence size\n * 15 tStart - Alignment start position in target\n * 16 tEnd - Alignment end position in target\n * 17 blockCount - Number of blocks in the alignment (a block contains no gaps)\n * 18 blockSizes - Comma-separated list of sizes of each block. If the query is a protein and the target the genome, blockSizes are in amino acids. See below for more information on protein query PSLs.\n * 19 qStarts - Comma-separated list of starting positions of each block in query\n * 20 tStarts - Comma-separated list of starting positions of each block in target\n */\n\n\n if (tokens.length < 21) return undefined\n\n const chr = tokens[13];\n const start = parseInt(tokens[15]);\n const end = parseInt(tokens[16]);\n const strand = tokens[8].charAt(0);\n const exonCount = parseInt(tokens[17]);\n const exons = [];\n const exonStarts = tokens[20].replace(/,$/, '').split(',');\n const exonSizes = tokens[18].replace(/,$/, '').split(',');\n\n for (let i = 0; i < exonCount; i++) {\n const start = parseInt(exonStarts[i]);\n const end = start + parseInt(exonSizes[i]);\n exons.push({start: start, end: end});\n }\n\n return new PSLFeature({chr, start, end, strand, exons, tokens})\n}\n\n\nfunction decodeExons(exonCountToken, exonStartsToken, exonEndsToken) {\n\n const exonCount = parseInt(exonCountToken);\n const exonStarts = exonStartsToken.replace(/,$/, '').split(',');\n const exonEnds = exonEndsToken.replace(/,$/, '').split(',');\n const exons = [];\n for (let i = 0; i < exonCount; i++) {\n const start = parseInt(exonStarts[i]);\n const end = parseInt(exonEnds[i]);\n exons.push({start: start, end: end});\n }\n return exons\n\n}\n\nfunction findUTRs$1(exons, cdStart, cdEnd) {\n\n for (let exon of exons) {\n const end = exon.end;\n const start = exon.start;\n if (end < cdStart || start > cdEnd) {\n exon.utr = true;\n } else {\n if (cdStart >= start && cdStart <= end) {\n exon.cdStart = cdStart;\n }\n if (cdEnd >= start && cdEnd <= end) {\n exon.cdEnd = cdEnd;\n }\n }\n }\n\n}\n\nfunction decodePeak(tokens, header) {\n\n var tokenCount, chr, start, end, strand, name, score, qValue, signal, pValue;\n\n tokenCount = tokens.length;\n if (tokenCount < 9) {\n return undefined\n }\n\n chr = tokens[0];\n start = parseInt(tokens[1]);\n end = parseInt(tokens[2]);\n name = tokens[3];\n score = Number(tokens[4]);\n strand = tokens[5].trim();\n signal = Number(tokens[6]);\n pValue = Number(tokens[7]);\n qValue = Number(tokens[8]);\n\n if (score === 0) score = signal;\n\n return {\n chr: chr, start: start, end: end, name: name, score: score, strand: strand, signal: signal,\n pValue: pValue, qValue: qValue\n }\n}\n\nfunction decodeBedGraph(tokens, header) {\n\n var chr, start, end, value;\n\n if (tokens.length <= 3) return undefined\n\n chr = tokens[0];\n start = parseInt(tokens[1]);\n end = parseInt(tokens[2]);\n value = Number(tokens[3]);\n const feature = {chr: chr, start: start, end: end, value: value};\n\n // Optional extra columns\n if (header) {\n let colorColumn = header.colorColumn;\n if (colorColumn && colorColumn < tokens.length) {\n feature.color = IGVColor.createColorString(tokens[colorColumn]);\n }\n }\n\n return feature\n}\n\nfunction decodeWig(tokens, header) {\n\n const wig = header.wig;\n\n if (wig && wig.format === \"fixedStep\") {\n const ss = (wig.index * wig.step) + wig.start;\n const ee = ss + wig.span;\n const value = Number(tokens[0]);\n ++(wig.index);\n return isNaN(value) ? null : {chr: wig.chrom, start: ss, end: ee, value: value}\n } else if (wig && wig.format === \"variableStep\") {\n\n if (tokens.length < 2) return null\n const ss = parseInt(tokens[0], 10) - 1;\n const ee = ss + wig.span;\n const value = Number(tokens[1]);\n return isNaN(value) ? null : {chr: wig.chrom, start: ss, end: ee, value: value}\n\n } else {\n return decodeBedGraph(tokens)\n }\n}\n\nfunction decodeSNP(tokens, header) {\n\n if (tokens.length < 6) return undefined\n\n const autoSql = [\n 'bin',\n 'chr',\n 'start',\n 'end',\n 'name',\n 'score',\n 'strand',\n 'refNCBI',\n 'refUCSC',\n 'observed',\n 'molType',\n 'class',\n 'valid',\n 'avHet',\n 'avHetSE',\n 'func',\n 'locType',\n 'weight',\n 'exceptions',\n 'submitterCount',\n 'submitters',\n 'alleleFreqCount',\n 'alleles',\n 'alleleNs',\n 'alleleFreqs',\n 'bitfields'\n ];\n\n\n const feature = {\n chr: tokens[1],\n start: Number.parseInt(tokens[2]),\n end: Number.parseInt(tokens[3]),\n name: tokens[4],\n score: Number.parseInt(tokens[5])\n };\n\n const n = Math.min(tokens.length, autoSql.length);\n for (let i = 6; i < n; i++) {\n feature[autoSql[i]] = tokens[i];\n }\n return feature\n\n}\n\nclass UCSCBedFeature {\n\n constructor(properties) {\n Object.assign(this, properties);\n }\n\n getAttributeValue(attributeName) {\n if (this.hasOwnProperty(attributeName)) {\n return this[attributeName]\n } else if (this.attributes) {\n return this.attributes[attributeName]\n }\n }\n}\n\n/*\n* 0 matches - Number of bases that match that aren't repeats\n* 1 misMatches - Number of bases that don't match\n* 2 repMatches - Number of bases that match but are part of repeats\n* 3 nCount - Number of \"N\" bases\n* 4 qNumInsert - Number of inserts in query\n* 5 qBaseInsert - Number of bases inserted in query\n* 6 tNumInsert - Number of inserts in target\n* 7 tBaseInsert - Number of bases inserted in target\n* 8 strand - \"+\" or \"-\" for query strand. For translated alignments, second \"+\"or \"-\" is for target genomic strand.\n* 9 qName - Query sequence name\n* 10 qSize - Query sequence size.\n* 11 qStart - Alignment start position in query\n* 12 qEnd - Alignment end position in query\n* 13 tName - Target sequence name\n* 14 tSize - Target sequence size\n* 15 tStart - Alignment start position in target\n* 16 tEnd - Alignment end position in target\n* 17 blockCount - Number of blocks in the alignment (a block contains no gaps)\n* 18 blockSizes - Comma-separated list of sizes of each block. If the query is a protein and the target the genome, blockSizes are in amino acids. See below for more information on protein query PSLs.\n* 19 qStarts - Comma-separated list of starting positions of each block in query\n* 20 tStarts - Comma-separated list of starting positions of each block in target\n */\n\nclass PSLFeature {\n\n\n constructor(properties) {\n Object.assign(this, properties);\n }\n\n get score() {\n const tokens = this.tokens;\n const match = parseInt(tokens[0]);\n const repMatch = parseInt(tokens[2]);\n const misMatch = parseInt(tokens[1]);\n const qGapCount = parseInt(tokens[4]);\n const tGapCount = parseInt(tokens[6]);\n const qSize = parseInt(tokens[10]);\n return Math.floor((1000 * (match + repMatch - misMatch - qGapCount - tGapCount)) / qSize)\n }\n\n get matches() {\n return this.tokens[0]\n }\n\n get misMatches() {\n return this.tokens[1]\n }\n\n get repMatches() {\n return this.tokens[2]\n }\n\n get nCount() {\n return this.tokens[3]\n }\n\n get qNumInsert() {\n return this.tokens[4]\n }\n\n get qBaseInsert() {\n return this.tokens[5]\n }\n\n get tNumInsert() {\n return this.tokens[6]\n }\n\n get tBaseInsert() {\n return this.tokens[7]\n\n }\n\n popupData() {\n return [\n {name: 'chr', value: this.chr},\n {name: 'start', value: this.start + 1},\n {name: 'end', value: this.end},\n {name: 'strand', value: this.strand},\n {name: 'score', value: this.score},\n {name: 'match', value: this.matches},\n {name: \"mis-match\", value: this.misMatches},\n {name: \"rep. match\", value: this.repMatches},\n {name: \"N's\", value: this.nCount},\n {name: 'Q gap count', value: this.qNumInsert},\n {name: 'Q gap bases', value: this.qBaseInsert},\n {name: 'T gap count', value: this.tNumInsert},\n {name: 'T gap bases', value: this.tBaseInsert},\n ]\n }\n\n}\n\nfunction decodeFusionJuncSpan(tokens, header) {\n\n /*\n Format:\n\n 0 #scaffold\n 1 fusion_break_name\n 2 break_left\n 3 break_right\n 4 num_junction_reads\n 5 num_spanning_frags\n 6 spanning_frag_coords\n\n 0 B3GNT1--NPSR1\n 1 B3GNT1--NPSR1|2203-10182\n 2 2203\n 3 10182\n 4 189\n 5 1138\n 6 1860-13757,1798-13819,1391-18127,1443-17174,...\n\n */\n\n\n if (tokens.length < 7) return undefined\n\n var chr = tokens[0];\n var fusion_name = tokens[1];\n var junction_left = parseInt(tokens[2]);\n var junction_right = parseInt(tokens[3]);\n var num_junction_reads = parseInt(tokens[4]);\n var num_spanning_frags = parseInt(tokens[5]);\n\n var spanning_frag_coords_text = tokens[6];\n\n var feature = {\n chr: chr,\n name: fusion_name,\n junction_left: junction_left,\n junction_right: junction_right,\n num_junction_reads: num_junction_reads,\n num_spanning_frags: num_spanning_frags,\n spanning_frag_coords: [],\n\n start: -1,\n end: -1\n }; // set start and end later based on min/max of span coords\n\n var min_coord = junction_left;\n var max_coord = junction_right;\n\n if (num_spanning_frags > 0) {\n\n var coord_pairs = spanning_frag_coords_text.split(',');\n\n for (var i = 0; i < coord_pairs.length; i++) {\n var split_coords = coord_pairs[i].split('-');\n\n var span_left = split_coords[0];\n var span_right = split_coords[1];\n\n if (span_left < min_coord) {\n min_coord = span_left;\n }\n if (span_right > max_coord) {\n max_coord = span_right;\n }\n feature.spanning_frag_coords.push({left: span_left, right: span_right});\n\n }\n }\n\n feature.start = min_coord;\n feature.end = max_coord;\n\n\n return feature\n\n}\n\nfunction decodeGtexGWAS(tokens, header) {\n //chrom\tchromStart\tchromEnd\tStrongest SNP-risk allele\tDisease/Phenotype\tP-value\tOdds ratio or beta\tPUBMEDID\n //1\t1247493\t1247494\trs12103-A\tInflammatory bowel disease\t8.00E-13\t1.1\t23128233\n\n const tokenCount = tokens.length;\n if (tokenCount < 7) {\n return null\n }\n const feature = {\n chr: tokens[0],\n start: parseInt(tokens[1]) - 1,\n end: parseInt(tokens[2]),\n 'Strongest SNP-risk allele': tokens[3],\n 'Disease/Phenotype': tokens[4],\n 'P-value': tokens[5],\n 'Odds ratio or beta': tokens[6],\n };\n if (tokens.length > 6) {\n feature['PUBMEDID'] = `${tokens[7]}`;\n }\n return feature\n}\n\n/**\n * Decode a custom columnar format. Required columns are 'chr' and 'start'\n *\n * @param tokens\n * @param ignore\n * @returns decoded feature, or null if this is not a valid record\n */\nfunction decodeCustom(tokens, header) {\n\n const format = header.customFormat;\n\n if (tokens.length < format.fields.length) return undefined\n\n const coords = format.coords || 0;\n\n const chr = tokens[format.chr];\n const start = parseInt(tokens[format.start]) - coords;\n const end = format.end !== undefined ? parseInt(tokens[format.end]) : start + 1;\n\n const feature = {chr: chr, start: start, end: end};\n\n if (format.fields) {\n format.fields.forEach(function (field, index) {\n\n if (index !== format.chr &&\n index !== format.start &&\n index !== format.end) {\n\n feature[field] = tokens[index];\n }\n });\n }\n\n return feature\n\n}\n\n/**\n * Decode a gcnv record, a bed style format encoding copy number variation\n *\n * @param tokens\n * @param header\n */\n\nfunction decodeGcnv(tokens, header) {\n\n const columnNames = header.columnNames;\n if (!columnNames) {\n throw Error(\"Sample names are not defined. Missing column headers?\")\n }\n const sampleCount = columnNames.length - 3;\n\n const chr = tokens[0];\n const start = parseInt(tokens[1]);\n const end = parseInt(tokens[2]);\n const values = tokens.slice(3).map(Number);\n\n if (values.length == sampleCount) {\n return {\n chr: chr,\n start: start,\n end: end,\n values: values,\n }\n } else {\n // TODO Throw error?\n console.warn(`${chr}:${start}-${end} row contains ${values.length} sample columns instead of the expected ${sampleCount} columns. Skipping...`);\n return undefined\n }\n}\n\n/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2014 Broad Institute\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\n/**\n * Parser for column style (tab delimited, etc) text file formats (bed, gff, vcf, etc).\n *\n *\n */\n\n\n/**\n * Return a parser for the given file format.\n */\nclass FeatureParser {\n\n constructor(config) {\n\n this.config = config;\n this.header = {};\n if (config.nameField) {\n this.header.nameField = config.nameField;\n }\n\n this.skipRows = 0; // The number of fixed header rows to skip. Override for specific types as needed\n\n if (config.decode) {\n this.decode = config.decode;\n this.delimiter = config.delimiter || \"\\t\";\n } else if (config.format) {\n this.header.format = config.format.toLowerCase();\n this.setDecoder(this.header.format);\n }\n\n if (!this.delimiter) {\n this.delimiter = \"\\t\";\n }\n }\n\n /**\n * Parse metadata from the file. A variety of conventions are in use to supply metadata about file contents\n * through header lines (e.g. 'track') and # directives. This method unifies metadata as properties of a\n * 'header' object.\n *\n * @param data\n * @returns {{}}\n */\n async parseHeader(dataWrapper) {\n\n let header = this.header;\n let columnNames;\n let line;\n while ((line = await dataWrapper.nextLine()) !== undefined) {\n if (line.startsWith(\"track\") || line.startsWith(\"#track\")) {\n let h = parseTrackLine$1(line);\n Object.assign(header, h);\n } else if (line.startsWith(\"browser\")) ; else if (line.startsWith(\"#columns\")) {\n let h = parseColumnsDirective$1(line);\n Object.assign(header, h);\n } else if (line.startsWith(\"##gff-version 3\")) {\n header.format = \"gff3\";\n } else if (line.startsWith(\"#gffTags\")) {\n header.gffTags = true;\n } else if (line.startsWith(\"fixedStep\") || line.startsWith(\"variableStep\")) {\n // Wig directives -- we are in the data section\n break\n } else if (line.startsWith(\"#\")) {\n const tokens = line.split(this.delimiter || \"\\t\");\n if (tokens.length > 1) {\n columnNames = tokens; // Possible column names\n }\n } else {\n // All directives that could change the format, and thus decoder, should have been read by now.\n this.setDecoder(header.format);\n\n // If the line can be parsed as a feature assume we are beyond the header, if any\n const tokens = line.split(this.delimiter || \"\\t\");\n try {\n const tmpHeader = Object.assign({columnNames}, header);\n if (this.decode(tokens, tmpHeader)) {\n break\n } else {\n if (tokens.length > 1) {\n columnNames = tokens; // possible column names\n }\n }\n } catch (e) {\n // Not a feature\n if (tokens.length > 1) {\n columnNames = tokens; // possible column names\n }\n }\n }\n }\n\n if (columnNames) {\n header.columnNames = columnNames;\n for (let n = 0; n < columnNames.length; n++) {\n if (columnNames[n] === \"color\" || columnNames[n] === \"colour\") {\n header.colorColumn = n;\n } else if (columnNames[n] === \"thickness\") {\n header.thicknessColumn = n;\n }\n }\n }\n\n this.header = header; // Directives might be needed for parsing lines\n return header\n }\n\n async parseFeatures(dataWrapper) {\n\n const allFeatures = [];\n const decode = this.decode;\n const format = this.header.format;\n const delimiter = this.delimiter || \"\\t\";\n let i = 0;\n let errorCount = 0;\n let line;\n while ((line = await dataWrapper.nextLine()) !== undefined) {\n i++;\n if (i <= this.skipRows) continue\n\n if (!line || line.startsWith(\"track\") || line.startsWith(\"#\") || line.startsWith(\"browser\")) {\n continue\n } else if (format === \"wig\" && line.startsWith(\"fixedStep\")) {\n this.header.wig = parseFixedStep(line);\n continue\n } else if (format === \"wig\" && line.startsWith(\"variableStep\")) {\n this.header.wig = parseVariableStep(line);\n continue\n }\n\n const tokens = line.split(delimiter);\n if (tokens.length < 1) {\n continue\n }\n\n const feature = decode(tokens, this.header);\n\n if (feature instanceof DecodeError) {\n errorCount++;\n if (errorCount > 0) {\n console.error(`Error parsing line '${line}': ${feature.message}`);\n }\n continue\n }\n\n if (feature) {\n allFeatures.push(feature);\n }\n }\n\n // Special hack for bedPE\n if (decode === decodeBedpe) {\n fixBedPE(allFeatures);\n }\n\n return allFeatures\n\n }\n\n setDecoder(format) {\n\n switch (format) {\n case \"narrowpeak\":\n case \"broadpeak\":\n case \"regionpeak\":\n case \"peaks\":\n this.decode = decodePeak;\n this.delimiter = this.config.delimiter || /\\s+/;\n break\n case \"bedgraph\":\n this.decode = decodeBedGraph;\n this.delimiter = /\\s+/;\n break\n case \"wig\":\n this.decode = decodeWig;\n this.delimiter = this.config.delimiter || /\\s+/;\n break\n case \"gff3\" :\n case \"gff\":\n this.decode = decodeGFF3;\n this.delimiter = \"\\t\";\n break\n case \"gtf\" :\n this.decode = decodeGTF;\n this.delimiter = \"\\t\";\n break\n case \"fusionjuncspan\":\n // bhaas, needed for FusionInspector view\n this.decode = decodeFusionJuncSpan;\n this.delimiter = this.config.delimiter || /\\s+/;\n break\n case \"gtexgwas\":\n this.skipRows = 1;\n this.decode = decodeGtexGWAS;\n this.delimiter = \"\\t\";\n break\n case \"refflat\":\n this.decode = decodeReflat;\n this.delimiter = this.config.delimiter || /\\s+/;\n break\n case \"genepred\":\n this.decode = decodeGenePred;\n this.delimiter = this.config.delimiter || /\\s+/;\n break\n case \"genepredext\":\n this.decode = decodeGenePredExt;\n this.delimiter = this.config.delimiter || /\\s+/;\n break\n case \"ensgene\":\n this.decode = decodeGenePred;\n this.header.shift = 1;\n this.delimiter = this.config.delimiter || /\\s+/;\n break\n case \"refgene\":\n this.decode = decodeGenePredExt;\n this.delimiter = this.config.delimiter || /\\s+/;\n this.header.shift = 1;\n break\n case \"bed\":\n this.decode = decodeBed;\n this.delimiter = this.config.delimiter || /\\s+/;\n break\n case \"bedpe\":\n case \"hiccups\":\n this.decode = decodeBedpe;\n this.delimiter = this.config.delimiter || \"\\t\";\n break\n case \"bedpe-domain\":\n this.decode = decodeBedpeDomain;\n this.headerLine = true;\n this.delimiter = this.config.delimiter || \"\\t\";\n break\n case \"bedpe-loop\":\n this.decode = decodeBedpe;\n this.delimiter = this.config.delimiter || \"\\t\";\n this.header = {colorColumn: 7};\n break\n case \"interact\":\n this.decode = decodeInteract;\n this.delimiter = this.config.delimiter || /\\s+/;\n break\n case \"snp\":\n this.decode = decodeSNP;\n this.delimiter = \"\\t\";\n break\n case \"rmsk\":\n this.decode = decodeRepeatMasker;\n this.delimiter = \"\\t\";\n break\n case \"gcnv\":\n this.decode = decodeGcnv;\n this.delimiter = \"\\t\";\n break\n default:\n const customFormat = getFormat(format);\n if (customFormat !== undefined) {\n this.decode = decodeCustom;\n this.header.customFormat = customFormat;\n this.delimiter = customFormat.delimiter || \"\\t\";\n } else {\n this.decode = decodeBed;\n this.delimiter = this.config.delimiter || /\\s+/;\n }\n }\n\n }\n}\n\nfunction parseTrackLine$1(line) {\n\n const properties = {};\n const tokens = line.split(/(?:\")([^\"]+)(?:\")|([^\\s\"]+)(?=\\s+|$)/g);\n\n // Clean up tokens array\n let curr;\n const tmp = [];\n for (let tk of tokens) {\n if (!tk || tk.trim().length === 0) continue\n if (tk.endsWith(\"=\")) {\n curr = tk;\n } else if (curr) {\n tmp.push(curr + tk);\n curr = undefined;\n } else {\n tmp.push(tk);\n }\n }\n\n for (let str of tmp) {\n if (!str) return\n var kv = str.split('=', 2);\n if (kv.length === 2) {\n const key = kv[0].trim();\n const value = kv[1].trim();\n if (properties.hasOwnProperty(key)) {\n let currentValue = properties[key];\n if (Array.isArray(currentValue)) {\n currentValue.push(value);\n } else {\n properties[key] = [currentValue, value];\n }\n } else {\n properties[key] = value;\n }\n }\n }\n if (\"interact\" == properties[\"type\"]) {\n properties[\"format\"] = \"interact\";\n } else if (\"gcnv\" === properties[\"type\"]) {\n properties[\"format\"] = \"gcnv\";\n }\n return properties\n}\n\nfunction parseColumnsDirective$1(line) {\n\n let properties = {};\n let t1 = line.split(/\\s+/);\n\n if (t1.length === 2) {\n let t2 = t1[1].split(\";\");\n t2.forEach(function (keyValue) {\n let t = keyValue.split(\"=\");\n if (t[0] === \"color\") {\n properties.colorColumn = Number.parseInt(t[1]) - 1;\n } else if (t[0] === \"thickness\") {\n properties.thicknessColumn = Number.parseInt(t[1]) - 1;\n }\n });\n }\n\n return properties\n}\n\nfunction parseFixedStep(line) {\n const tokens = line.split(/\\s+/);\n const chrom = tokens[1].split(\"=\")[1];\n const start = parseInt(tokens[2].split(\"=\")[1], 10) - 1;\n const step = parseInt(tokens[3].split(\"=\")[1], 10);\n const span = (tokens.length > 4) ? parseInt(tokens[4].split(\"=\")[1], 10) : 1;\n return {format: \"fixedStep\", chrom, start, step, span, index: 0}\n}\n\nfunction parseVariableStep(line) {\n const tokens = line.split(/\\s+/);\n const chrom = tokens[1].split(\"=\")[1];\n const span = tokens.length > 2 ? parseInt(tokens[2].split(\"=\")[1], 10) : 1;\n return {format: \"variableStep\", chrom, span}\n}\n\n/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2018 Regents of the University of California\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\nconst fixColor = (colorString) => {\n if (isString$2(colorString)) {\n return (colorString.indexOf(\",\") > 0 && !(colorString.startsWith(\"rgb(\") || colorString.startsWith(\"rgba(\"))) ?\n `rgb(${colorString})` : colorString\n } else {\n return colorString\n }\n};\n\n/**\n * A collection of properties and methods shared by all (or most) track types.\n *\n * @param config\n * @param browser\n * @constructor\n */\nclass TrackBase {\n\n static defaults = {\n height: 50,\n autoHeight: false,\n visibilityWindow: undefined, // Identifies property that should be copied from config\n color: undefined, // Identifies property that should be copied from config\n altColor: undefined, // Identifies property that should be copied from config\n supportHiDPI: true\n }\n\n constructor(config, browser) {\n this.browser = browser;\n this.init(config);\n }\n\n /**\n * Initialize track properties from the config object. This method is typically overriden in subclasses, which\n * will call this implementation as super.init(config).\n *\n * @param config\n */\n init(config) {\n\n this.config = config;\n\n if (config.displayMode) {\n config.displayMode = config.displayMode.toUpperCase();\n }\n\n // Set default properties\n const defaults = Object.assign({}, TrackBase.defaults);\n if(this.constructor.defaults) {\n for(let key of Object.keys(this.constructor.defaults)) {\n defaults[key] = this.constructor.defaults[key];\n }\n }\n for(let key of Object.keys(defaults)) {\n this[key] = config.hasOwnProperty(key) ? config[key] : defaults[key];\n if(key === 'color' || key === 'altColor') {\n this[key] = fixColor(this[key]);\n }\n }\n\n if (config.name || config.label) {\n this.name = config.name || config.label;\n } else if (isFile(config.url)) {\n this.name = config.url.name;\n } else if (isString$2(config.url) && !config.url.startsWith(\"data:\")) {\n this.name = getFilename$2(config.url);\n }\n\n this.url = config.url;\n if(this.config.type) this.type = this.config.type;\n this.id = this.config.id === undefined ? this.name : this.config.id;\n this.order = config.order;\n this.autoscaleGroup = config.autoscaleGroup;\n this.removable = config.removable === undefined ? true : config.removable; // Defaults to true\n this.minHeight = config.minHeight || Math.min(25, this.height);\n this.maxHeight = config.maxHeight || Math.max(1000, this.height);\n\n if (config.onclick) {\n this.onclick = config.onclick;\n config.onclick = undefined; // functions cannot be saved in sessions, clear it here.\n }\n\n if (config.description) {\n // Override description -- displayed when clicking on track label. Convert to function if neccessary\n if (typeof config.description === 'function') {\n this.description = config.description;\n } else {\n this.description = () => config.description;\n }\n }\n\n // Support for mouse hover text. This can be expensive, off by default.\n // this.hoverText = function(clickState) => return tool tip text\n if (config.hoverTextFields) {\n this.hoverText = hoverText.bind(this);\n } else if (typeof this.config.hoverText === 'function') {\n this.hoverText = this.config.hoverText;\n }\n }\n\n get name() {\n return this._name\n }\n\n set name(name) {\n this._name = name;\n if (this.trackView) {\n this.trackView.setTrackLabelName(name);\n }\n }\n\n /**\n * Update track properties from the config object.\n *\n * @param config\n */\n updateConfig(config) {\n this.init(config);\n }\n\n clearCachedFeatures() {\n if (this.trackView) {\n this.trackView.clearCachedFeatures();\n }\n }\n\n updateViews() {\n if (this.trackView) {\n this.trackView.updateViews();\n }\n }\n\n /**\n * Used to create session object for bookmarking, sharing. Only simple property values (string, number, boolean)\n * are saved.\n */\n getState() {\n\n const jsonable = (v) => !(v === undefined || typeof v === 'function' || v instanceof File || v instanceof Promise);\n\n // Create copy of config, minus transient properties (convention is name starts with '_'). Also, all\n // function properties are transient as they cannot be saved in json\n const state = {};\n for (let key of Object.keys(this.config)) {\n if (!key.startsWith(\"_\") && jsonable(this.config[key])) {\n state[key] = this.config[key];\n }\n }\n\n // Update original config values with any changes\n for (let key of Object.keys(state)) {\n if (key.startsWith(\"_\")) continue // transient property\n const value = this[key];\n if (value && (isSimpleType(value) || typeof value === \"boolean\" || key === \"metadata\")) {\n state[key] = value;\n }\n }\n\n // If user has changed other properties from defaults update state.\n const defs = TrackBase.defaults;\n if (this.constructor.defaults) {\n for (let key of Object.keys(this.constructor.defaults)) {\n defs[key] = this.constructor.defaults[key];\n }\n }\n for (let key of Object.keys(defs)) {\n if (undefined !== this[key] && defs[key] !== this[key]) {\n state[key] = this[key];\n }\n }\n\n // Flatten dataRange if present\n if (!this.autoscale && this.dataRange) {\n state.min = this.dataRange.min;\n state.max = this.dataRange.max;\n }\n\n return state\n }\n\n get supportsWholeGenome() {\n return this.config.supportsWholeGenome === true\n }\n\n /**\n * Does the track support sample names. Current sample aware tracks include VCF (with genotypes), MUT, MAF, and SEG\n * @returns {boolean}\n */\n hasSamples() {\n return false\n }\n\n getGenomeId() {\n return this.browser.genome ? this.browser.genome.id : undefined\n }\n\n /**\n * Set certain track properties, usually from a \"track\" line. Not all UCSC properties are supported.\n *\n * Track configuration settings have precendence over track line properties, so if both are present ignore the\n * track line.\n *\n * @param properties\n */\n setTrackProperties(properties) {\n\n if (this.disposed) return // This track was removed during async load\n\n const tracklineConfg = {};\n let tokens;\n for (let key of Object.keys(properties)) {\n switch (key.toLowerCase()) {\n case \"usescore\":\n tracklineConfg.useScore = (\n properties[key] === 1 || properties[key] === \"1\" || properties[key] === \"on\" || properties[key] === true);\n break\n case \"visibility\":\n //0 - hide, 1 - dense, 2 - full, 3 - pack, and 4 - squish\n switch (properties[key]) {\n case \"2\":\n case \"3\":\n case \"pack\":\n case \"full\":\n tracklineConfg.displayMode = \"EXPANDED\";\n break\n case \"4\":\n case \"squish\":\n tracklineConfg.displayMode = \"SQUISHED\";\n break\n case \"1\":\n case \"dense\":\n tracklineConfg.displayMode = \"COLLAPSED\";\n }\n break\n case \"color\":\n case \"altcolor\":\n tracklineConfg[key] = properties[key].startsWith(\"rgb(\") ? properties[key] : \"rgb(\" + properties[key] + \")\";\n break\n case \"featurevisiblitywindow\":\n case \"visibilitywindow\":\n tracklineConfg.visibilityWindow = Number.parseInt(properties[key]);\n break\n case \"maxheightpixels\":\n tokens = properties[key].split(\":\");\n if (tokens.length === 3) {\n tracklineConfg.minHeight = Number.parseInt(tokens[2]);\n tracklineConfg.height = Number.parseInt(tokens[1]);\n tracklineConfg.maxHeight = Number.parseInt(tokens[0]);\n }\n break\n case \"viewlimits\":\n if (!this.config.autoscale) { // autoscale in the config has precedence\n tokens = properties[key].split(\":\");\n let min = 0;\n let max;\n if (tokens.length == 1) {\n max = Number(tokens[0]);\n } else if (tokens.length == 2) {\n min = Number(tokens[0]);\n max = Number(tokens[1]);\n }\n tracklineConfg.autoscale = false;\n tracklineConfg.dataRange = {min, max};\n this.viewLimitMin = min;\n this.viewLimitMax = max;\n }\n case \"name\":\n tracklineConfg[key] = properties[key];\n break\n case \"url\":\n tracklineConfg[\"infoURL\"] = properties[key];\n break\n case \"type\":\n const v = properties[key];\n if (UCSCTypeMappings.has(v)) {\n tracklineConfg[key] = UCSCTypeMappings.get(v);\n } else {\n tracklineConfg[key] = v;\n }\n break\n case \"graphtype\":\n tracklineConfg[\"graphType\"] = properties[key];\n break\n default:\n tracklineConfg[key] = properties[key];\n }\n }\n\n // Track configuration objects have precedence over track line properties in general. The \"name\" property\n // is an exception if it was derived and not explicitly entered (that is derived from the web app from filename).\n for (let key of Object.keys(tracklineConfg)) {\n\n if (!this.config.hasOwnProperty(key) || (key === \"name\" && this.config._derivedName)) {\n let value = tracklineConfg[key];\n if (\"true\" === value) value = true;\n if (\"false\" === value) value = false;\n\n this[key] = value;\n if (key === \"height\" && this.trackView) {\n try {\n const h = Number.parseInt(value);\n this.trackView.setTrackHeight(h);\n } catch (e) {\n console.error(e);\n }\n }\n }\n }\n }\n\n /**\n * Return the features clicked over. Default implementation assumes an array of features and only considers\n * the genomic location. Overriden by most subclasses.\n *\n * @param clickState\n * @param features\n * @returns {[]|*[]}\n */\n clickedFeatures(clickState) {\n\n // We use the cached features rather than method to avoid async load. If the\n // feature is not already loaded this won't work, but the user wouldn't be mousing over it either.\n const features = clickState.viewport.cachedFeatures;\n\n if (!features || !Array.isArray(features) || features.length === 0) {\n return []\n }\n\n const genomicLocation = clickState.genomicLocation;\n\n // When zoomed out we need some tolerance around genomicLocation\n const tolerance = (clickState.referenceFrame.bpPerPixel > 0.2) ? 3 * clickState.referenceFrame.bpPerPixel : 0.2;\n const ss = genomicLocation - tolerance;\n const ee = genomicLocation + tolerance;\n return (FeatureUtils.findOverlapping(features, ss, ee))\n }\n\n /**\n * Default popup text function -- just extracts string and number properties in random order.\n * @param feature\n * @returns {Array}\n */\n extractPopupData(feature, genomeId) {\n\n const filteredProperties = new Set(['row', 'color', 'chr', 'start', 'end', 'cdStart', 'cdEnd', 'strand', 'alpha']);\n const data = [];\n\n let alleles, alleleFreqs;\n for (let property in feature) {\n\n if (feature.hasOwnProperty(property) &&\n !filteredProperties.has(property) &&\n isSimpleType(feature[property])) {\n\n let value = feature[property];\n data.push({name: capitalize(property), value: value});\n\n if (property === \"alleles\") {\n alleles = feature[property];\n } else if (property === \"alleleFreqs\") {\n alleleFreqs = feature[property];\n }\n }\n }\n\n if (alleles && alleleFreqs) {\n\n if (alleles.endsWith(\",\")) {\n alleles = alleles.substr(0, alleles.length - 1);\n }\n if (alleleFreqs.endsWith(\",\")) {\n alleleFreqs = alleleFreqs.substr(0, alleleFreqs.length - 1);\n }\n\n let a = alleles.split(\",\");\n let af = alleleFreqs.split(\",\");\n if (af.length > 1) {\n let b = [];\n for (let i = 0; i < af.length; i++) {\n b.push({a: a[i], af: Number(af[i])});\n }\n b.sort(function (x, y) {\n return x.af - y.af\n });\n\n let ref = b[b.length - 1].a;\n if (ref.length === 1) {\n for (let i = b.length - 2; i >= 0; i--) {\n let alt = b[i].a;\n if (alt.length === 1) {\n if (!genomeId) genomeId = this.getGenomeId();\n const cravatLink = TrackBase.getCravatLink(feature.chr, feature.start + 1, ref, alt, genomeId);\n console.log(cravatLink);\n if (cravatLink) {\n data.push('
');\n data.push({html: cravatLink});\n data.push('
');\n }\n }\n }\n }\n }\n }\n\n if (feature.attributes) {\n for (let key of Object.keys(feature.attributes)) {\n data.push({name: key, value: feature.attributes[key]});\n }\n }\n\n // final chr position\n let posString = `${feature.chr}:${numberFormatter$1(feature.start + 1)}-${numberFormatter$1(feature.end)}`;\n if (feature.strand) {\n posString += ` (${feature.strand})`;\n }\n\n data.push({name: 'Location', value: posString});\n\n return data\n\n }\n\n\n /**\n * Default track description -- displayed on click of track label. This can be overriden in the track\n * configuration, or in subclasses.\n */\n description() {\n\n const wrapKeyValue = (k, v) => `
${k}: ${v}
`;\n\n let str = '
';\n if (this.url) {\n if (isFile(this.url)) {\n str += wrapKeyValue('Filename', this.url.name);\n } else {\n str += wrapKeyValue('URL', this.url);\n }\n } else {\n str = this.name;\n }\n if (this.config) {\n if (this.config.metadata) {\n for (let key of Object.keys(this.config.metadata)) {\n const value = this.config.metadata[key];\n str += wrapKeyValue(key, value);\n }\n }\n\n // Add any config properties that are capitalized\n for (let key of Object.keys(this.config)) {\n if (key.startsWith(\"_\")) continue // transient property\n let first = key.substr(0, 1);\n if (first !== first.toLowerCase()) {\n const value = this.config[key];\n if (value && isSimpleType(value)) {\n str += wrapKeyValue(key, value);\n }\n }\n }\n\n }\n str += '
';\n return str\n }\n\n /**\n * Return color for a specific feature of this track. This default implementation is overriden by subclasses*\n * @param f\n * @returns {*|string|string}\n */\n getColorForFeature(f) {\n return (typeof this.color === \"function\") ? this.color(feature) : this.color\n }\n\n /**\n * Track has been permanently removed. Release resources and other cleanup\n */\n dispose() {\n\n this.disposed = true;\n\n // This should not be neccessary, but in case there is some unknown reference holding onto this track object,\n // for example in client code, release any resources here.\n for (let key of Object.keys(this)) {\n this[key] = undefined;\n }\n }\n\n static getCravatLink(chr, position, ref, alt, genomeID) {\n\n if (\"hg38\" === genomeID || \"GRCh38\" === genomeID) {\n\n const cravatChr = chr.startsWith(\"chr\") ? chr : \"chr\" + chr;\n return `Cravat ${ref}->${alt}`\n\n } else {\n return undefined\n }\n }\n}\n\nfunction hoverText(clickState) {\n\n if (!this.hoverTextFields) return\n\n const features = this.clickedFeatures(clickState);\n\n if (features && features.length > 0) {\n let str = \"\";\n for (let i = 0; i < features.length; i++) {\n if (i === 10) {\n str += \"; ...\";\n break\n }\n if (!features[i]) continue\n\n const f = features[i]._f || features[i];\n if (str.length > 0) str += \"\\n\";\n\n str = \"\";\n for (let field of this.hoverTextFields) {\n if (str.length > 0) str += \"\\n\";\n if (f.hasOwnProperty(field)) {\n str += f[field];\n } else if (typeof f.getAttribute === \"function\") {\n str += f.getAttribute(field);\n }\n }\n\n }\n return str\n }\n}\n\n/**\n * Map UCSC track line \"type\" setting to file format. In igv.js \"type\" refers to the track type, not the input file format\n * @type {Map}\n */\nconst UCSCTypeMappings = new Map([\n [\"wiggle_0\", \"wig\"],\n [\"bed\", \"bed\"],\n [\"bigBed\", \"bigBed\"],\n [\"bigWig\", \"bigWig\"]\n]);\n\n/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2014 Broad Institute\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\n\n/**\n * Define parser for seg files (.bed, .gff, .vcf, etc). A parser should implement 2 methods\n *\n * parseHeader(data) - return an object representing a header. Details are format specific\n *\n * parseFeatures(data) - return a list of features\n *\n */\n\n\nclass SegParser {\n\n constructor(type) {\n this.type = type || 'seg'; // One of seg, mut, or maf\n\n switch (this.type) {\n case 'mut':\n this.sampleColumn = 3;\n this.chrColumn = 0;\n this.startColumn = 1;\n this.endColumn = 2;\n this.dataColumn = 4;\n break\n case 'maf':\n this.sampleColumn = 15;\n this.chrColumn = 4;\n this.startColumn = 5;\n this.endColumn = 6;\n this.dataColumn = 8;\n break\n default:\n this.sampleColumn = 0;\n this.chrColumn = 1;\n this.startColumn = 2;\n this.endColumn = 3;\n // Data column determined after reading header\n }\n }\n\n async parseHeader(dataWrapper) {\n let line;\n while ((line = await dataWrapper.nextLine()) !== undefined) {\n if (line.startsWith(\"#\")) ; else {\n const tokens = line.split(\"\\t\");\n this.header = {headings: tokens};\n break\n }\n }\n return this.header\n }\n\n async parseFeatures(dataWrapper) {\n\n const allFeatures = [];\n let extraHeaders;\n if (!this.header) {\n this.header = await this.parseHeader(dataWrapper); // This will only work for non-indexed files\n }\n if ('seg' === this.type) {\n this.dataColumn = this.header.headings.length - 1;\n }\n if (this.header.headings.length > 5) {\n extraHeaders = this.extractExtraColumns(this.header.headings);\n }\n const valueColumnName = this.header.headings[this.dataColumn];\n\n let line;\n while ((line = await dataWrapper.nextLine()) !== undefined) {\n const tokens = line.split(\"\\t\");\n const value = ('seg' === this.type) ? Number(tokens[this.dataColumn]) : tokens[this.dataColumn];\n if (tokens.length > this.dataColumn) {\n const feature = new SegFeature({\n sample: tokens[this.sampleColumn],\n chr: tokens[this.chrColumn],\n start: parseInt(tokens[this.startColumn]) - 1,\n end: parseInt(tokens[this.endColumn]),\n value,\n valueColumnName\n });\n if (extraHeaders) {\n const extraValues = this.extractExtraColumns(tokens);\n feature.setAttributes({names: extraHeaders, values: extraValues});\n }\n allFeatures.push(feature);\n }\n }\n return allFeatures\n }\n\n extractExtraColumns(tokens) {\n const extras = [];\n for (let i = 0; i < tokens.length; i++) {\n if (i !== this.chrColumn && i !== this.startColumn && i !== this.endColumn && i !== this.sampleColumn) {\n extras.push(tokens[i]);\n }\n }\n return extras\n }\n\n}\n\nclass SegFeature {\n\n constructor({sample, chr, start, end, value, valueColumnName}) {\n this.sample = sample;\n this.chr = chr;\n this.start = start;\n this.end = end;\n this.value = value;\n this.valueColumnName = valueColumnName;\n }\n\n setAttributes({names, values}) {\n this.attributeNames = names;\n this.attributeValues = values;\n }\n\n getAttribute(name) {\n if (this.attributeNames) {\n const idx = this.attributeNames.indexOf(name);\n if (idx >= 0) {\n return this.attributeValues[idx]\n }\n }\n return undefined\n }\n\n\n popupData(type, genomeID) {\n const filteredProperties = new Set(['chr', 'start', 'end', 'sample', 'value', 'row', 'color', 'sampleKey',\n 'uniqueSampleKey', 'sampleId', 'chromosome', 'uniquePatientKey']);\n const locationString = (this.chr + \":\" +\n numberFormatter$1(this.start + 1) + \"-\" +\n numberFormatter$1(this.end));\n const pd = [\n {name: \"Sample\", value: this.sample},\n {name: \"Location\", value: locationString},\n {name: this.valueColumnName ? capitalize(this.valueColumnName) : \"Value\", value: this.value}\n ];\n\n // TODO -- the Cravat stuff should probably be in the track (SegTrack)\n if (\"mut\" === type && \"hg38\" === genomeID) {\n const l = this.extractCravatLink(genomeID);\n if (l) {\n pd.push('
');\n pd.push({html: l});\n pd.push('
');\n }\n }\n\n if (this.attributeNames && this.attributeNames.length > 0) {\n for (let i = 0; i < this.attributeNames.length; i++) {\n if (!filteredProperties.has(this.attributeNames[i]) & this.valueColumnName !== this.attributeNames[i]) {\n pd.push({name: capitalize(this.attributeNames[i]), value: this.attributeValues[i]});\n }\n }\n }\n return pd\n }\n\n extractCravatLink(genomeId) {\n\n let ref, alt;\n if (this.attributeNames && this.attributeNames.length > 0) {\n for (let i = 0; i < this.attributeNames.length; i++) {\n if (!ref && \"Reference_Allele\" === this.attributeNames[i]) {\n ref = this.attributeValues[i];\n }\n if (!alt && this.attributeNames[i].startsWith(\"Tumor_Seq_Allele\") && this.attributeValues[i] !== ref) {\n alt = this.attributeValues[i];\n }\n if (ref && alt) {\n return TrackBase.getCravatLink(this.chr, this.start + 1, ref, alt, genomeId)\n }\n }\n }\n\n }\n}\n\n/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2014 Broad Institute\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\n/**\n * Create a variant from an array of tokens representing a line in a \"VCF\" file\n * @param tokens\n */\nfunction createVCFVariant(tokens) {\n const variant = new Variant();\n variant.chr = tokens[0]; // TODO -- use genome aliases\n variant.pos = parseInt(tokens[1]);\n variant.names = tokens[2]; // id in VCF\n variant.referenceBases = tokens[3];\n variant.alternateBases = tokens[4];\n variant.quality = tokens[5];\n variant.filter = tokens[6];\n variant.info = {};\n const infoStr = tokens[7];\n if (infoStr) {\n for (let elem of infoStr.split(';')) {\n var element = elem.split('=');\n variant.info[element[0]] = element[1];\n }\n }\n variant.init();\n return variant\n}\n\n\n/**\n * @deprecated - the GA4GH API has been deprecated. This code no longer maintained.\n * @param json\n * @returns {Variant}\n */\nfunction createGAVariant(json) {\n\n var variant = new Variant();\n\n variant.chr = json.referenceName;\n variant.start = parseInt(json.start); // Might get overriden below\n variant.end = parseInt(json.end); // Might get overriden below\n variant.pos = variant.start + 1; // GA4GH is 0 based.\n variant.names = arrayToString(json.names, \"; \");\n variant.referenceBases = json.referenceBases;\n variant.alternateBases = arrayToString(json.alternateBases);\n variant.quality = json.quality;\n variant.filter = arrayToString(json.filter);\n\n\n // Flatten GA4GH attributes array\n variant.info = {};\n if (json.info) {\n Object.keys(json.info).forEach(function (key) {\n var value,\n valueArray = json.info[key];\n\n if (Array.isArray(valueArray)) {\n value = valueArray.join(\",\");\n } else {\n value = valueArray;\n }\n variant.info[key] = value;\n });\n }\n\n\n // Need to build a hash of calls for fast lookup\n // Note from the GA4GH spec on call ID:\n //\n // The ID of the call set this variant call belongs to. If this field is not present,\n // the ordering of the call sets from a SearchCallSetsRequest over this GAVariantSet\n // is guaranteed to match the ordering of the calls on this GAVariant.\n // The number of results will also be the same.\n variant.calls = {};\n var id;\n if (json.calls) {\n json.calls.forEach(function (call) {\n id = call.callSetId;\n variant.calls[id] = call;\n\n });\n }\n\n init(variant);\n\n return variant\n\n}\n\n\nclass Variant {\n\n init() {\n\n const ref = this.referenceBases;\n const altBases = this.alternateBases;\n\n if (this.info) {\n if (this.info[\"VT\"]) {\n this.type = this.info[\"VT\"];\n } else if (this.info[\"SVTYPE\"]) {\n this.type = \"SV\";\n } else if (this.info[\"PERIOD\"]) {\n this.type = \"STR\";\n }\n }\n if (this.type === undefined) {\n this.type = determineType(ref, altBases);\n }\n if (this.type === \"NONVARIANT\") {\n this.heterozygosity = 0;\n }\n\n // Determine start/end coordinates -- these are the coordinates representing the actual variant,\n // not the leading or trailing reference\n if (this.info[\"END\"]) {\n this.start = this.pos - 1;\n if (this.info[\"CHR2\"] && this.info[\"CHR2\"] !== this.chr) {\n this.end = this.start + 1;\n } else {\n this.end = Number.parseInt(this.info[\"END\"]);\n }\n } else {\n if (this.type === \"NONVARIANT\") {\n this.start = this.pos - 1; // convert to 0-based coordinate convention\n this.end = this.start + ref.length;\n } else {\n\n const altTokens = altBases.split(\",\").filter(token => token.length > 0);\n this.alleles = [];\n this.start = undefined;\n this.end = undefined;\n\n for (let alt of altTokens) {\n\n this.alleles.push(alt);\n\n // We don't yet handle SV and other special alt representations\n if (\"SV\" !== this.type && isKnownAlt(alt)) {\n\n let altLength = alt.length;\n let lengthOnRef = ref.length;\n const lmin = Math.min(altLength, lengthOnRef);\n\n // Trim off matching bases. Try first match, then right -> left, then any remaining left -> right\n let s = 0;\n\n while (s < lmin && (ref.charCodeAt(s) === alt.charCodeAt(s))) {\n s++;\n altLength--;\n lengthOnRef--;\n }\n\n // right -> left from end\n while (altLength > 0 && lengthOnRef > 0) {\n const altIdx = s + altLength - 1;\n const refIdx = s + lengthOnRef - 1;\n if (alt.charCodeAt(altIdx) === ref.charCodeAt(refIdx)) {\n altLength--;\n lengthOnRef--;\n } else {\n break\n }\n }\n\n // if any remaining, left -> right\n while (altLength > 0 && lengthOnRef > 0) {\n const altIdx = s;\n const refIdx = s;\n if (alt.charCodeAt(altIdx) === ref.charCodeAt(refIdx)) {\n s++;\n altLength--;\n lengthOnRef--;\n } else {\n break\n }\n }\n\n const alleleStart = this.pos + s - 1; // -1 for zero based coordinates\n const alleleEnd = alleleStart + lengthOnRef;\n this.start = this.start === undefined ? alleleStart : Math.min(this.start, alleleStart);\n this.end = this.end === undefined ? alleleEnd : Math.max(this.end, alleleEnd);\n }\n }\n\n // Default to single base representation @ position for variant types not otherwise handled\n if (this.start === undefined) {\n this.start = this.pos - 1;\n this.end = this.pos;\n }\n }\n }\n }\n\n popupData(genomicLocation, genomeId) {\n\n const posString = `${numberFormatter$1(this.pos)}`;\n const locString = this.start === this.end ?\n `${numberFormatter$1(this.start)} | ${numberFormatter$1(this.start + 1)}` :\n `${numberFormatter$1(this.start + 1)}-${numberFormatter$1(this.end)}`;\n const fields = [\n {name: \"Chr\", value: this.chr},\n {name: \"Pos\", value: posString},\n {name: \"Loc\", value: locString},\n {name: \"ID\", value: this.names ? this.names : \"\"},\n {name: \"Ref\", value: this.referenceBases},\n {name: \"Alt\", value: this.alternateBases.replace(\"<\", \"<\")},\n {name: \"Qual\", value: this.quality},\n {name: \"Filter\", value: this.filter}\n ];\n\n if (\"SNP\" === this.type) {\n let ref = this.referenceBases;\n if (ref.length === 1) {\n let altArray = this.alternateBases.split(\",\");\n for (let alt of altArray) {\n if (alt.length === 1) {\n let l = TrackBase.getCravatLink(this.chr, this.pos, ref, alt, genomeId);\n if (l) {\n fields.push('
');\n fields.push({html: l});\n }\n }\n }\n }\n }\n\n if (this.hasOwnProperty(\"heterozygosity\")) {\n fields.push({name: \"Heterozygosity\", value: this.heterozygosity});\n }\n\n if (this.info) {\n fields.push({html: '
'});\n for (let key of Object.keys(this.info)) {\n fields.push({name: key, value: arrayToString(decodeURIComponent(this.info[key]))});\n }\n }\n\n return fields\n }\n\n getInfo(tag) {\n return this.info ? this.info[tag] : undefined;\n }\n\n isRefBlock() {\n return \"NONVARIANT\" === this.type\n }\n\n}\n\nconst knownAltBases = new Set([\"A\", \"C\", \"T\", \"G\"].map(c => c.charCodeAt(0)));\n\nfunction isKnownAlt(alt) {\n for (let i = 0; i < alt.length; i++) {\n if (!knownAltBases.has(alt.charCodeAt(i))) {\n return false\n }\n }\n return true\n}\n\n\nfunction determineType(ref, altAlleles) {\n const refLength = ref.length;\n if (altAlleles === undefined) {\n return \"UNKNOWN\"\n } else if (altAlleles.trim().length === 0 ||\n altAlleles === \"\" ||\n altAlleles === \"<*>\" ||\n altAlleles === \".\") {\n return \"NONVARIANT\"\n } else {\n const alleles = altAlleles.split(\",\");\n const types = alleles.map(function (a) {\n if (refLength === 1 && a.length === 1) {\n return \"SNP\"\n } else {\n return \"\" === a ? \"NONVARIANT\" : \"OTHER\"\n }\n });\n let type = types[0];\n for (let t of types) {\n if (t !== type) {\n return \"MIXED\"\n }\n }\n return type\n }\n}\n\nfunction arrayToString(value, delim) {\n\n if (delim === undefined) delim = \",\";\n\n if (!(Array.isArray(value))) {\n return value\n }\n return value.join(delim)\n}\n\n/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2014 Broad Institute\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\n/**\n * Parser for VCF files.\n */\n\nclass VcfParser {\n\n construtor() {\n }\n\n async parseHeader(dataWrapper, genome) {\n\n const header = {};\n\n header.chrAliasTable = new Map();\n\n // First line must be file format\n let line = await dataWrapper.nextLine();\n if (line.startsWith(\"##fileformat\")) {\n header.version = line.substr(13);\n } else {\n throw new Error(\"Invalid VCF file: missing fileformat line\")\n }\n\n while ((line = await dataWrapper.nextLine()) !== undefined) {\n\n if (line.startsWith(\"#\")) {\n\n let id;\n const values = {};\n\n if (line.startsWith(\"##\")) {\n\n if (line.startsWith(\"##INFO\") || line.startsWith(\"##FILTER\") || line.startsWith(\"##FORMAT\")) {\n\n const ltIdx = line.indexOf(\"<\");\n const gtIdx = line.lastIndexOf(\">\");\n\n if (!(ltIdx > 2 && gtIdx > 0)) {\n console.log(\"Malformed VCF header line: \" + line);\n continue\n }\n\n const type = line.substring(2, ltIdx - 1);\n if (!header[type]) header[type] = {};\n\n //##INFO=\n // ##FILTER=\n // ##FORMAT=\n\n const tokens = splitStringRespectingQuotes(line.substring(ltIdx + 1, gtIdx - 1), \",\");\n\n for (let token of tokens) {\n var kv = token.split(\"=\");\n if (kv.length > 1) {\n if (kv[0] === \"ID\") {\n id = kv[1];\n } else {\n values[kv[0]] = kv[1];\n }\n }\n }\n\n if (id) {\n header[type][id] = values;\n }\n } else if (line.startsWith(\"##contig\") && genome) {\n const idx1 = line.indexOf(\"\", idx1);\n }\n const chr = line.substring(idx1 + 4, idx2);\n const canonicalChromosome = genome.getChromosomeName(chr);\n header.chrAliasTable.set(canonicalChromosome, chr);\n } else ;\n } else if (line.startsWith(\"#CHROM\")) {\n const tokens = line.split(\"\\t\");\n\n if (tokens.length > 8) {\n\n // call set names -- use column index for id\n header.callSets = [];\n for (let j = 9; j < tokens.length; j++) {\n header.callSets.push({id: j, name: tokens[j]});\n }\n }\n }\n\n } else {\n break\n }\n\n }\n\n this.header = header; // Will need to intrepret genotypes and info field\n\n return header\n }\n\n\n /**\n * Parse data as a collection of Variant objects.\n *\n * @param data\n * @returns {Array}\n */\n async parseFeatures(dataWrapper) {\n\n const allFeatures = [];\n const callSets = this.header.callSets;\n const nExpectedColumns = 8 + (callSets ? callSets.length + 1 : 0);\n let line;\n while ((line = await dataWrapper.nextLine()) !== undefined) {\n if (line && !line.startsWith(\"#\")) {\n\n const tokens = line.split(\"\\t\");\n if (tokens.length === nExpectedColumns) {\n const variant = createVCFVariant(tokens);\n variant.header = this.header; // Keep a pointer to the header to interpret fields for popup text\n //variant.line = line // Uncomment for debugging\n allFeatures.push(variant);\n\n if (tokens.length > 9) {\n\n // Format\n const callFields = extractCallFields(tokens[8].split(\":\"));\n\n variant.calls = {};\n for (let index = 9; index < tokens.length; index++) {\n\n const token = tokens[index];\n\n const callSet = callSets[index - 9];\n const call = {\n callSetName: callSet.name,\n info: {}\n };\n\n variant.calls[callSet.id] = call;\n\n token.split(\":\").forEach(function (callToken, idx) {\n\n switch (idx) {\n case callFields.genotypeIndex:\n call.genotype = [];\n callToken.split(/[\\|\\/]/).forEach(function (s) {\n call.genotype.push('.' === s ? s : parseInt(s));\n });\n break\n\n default:\n call.info[callFields.fields[idx]] = callToken;\n }\n });\n }\n }\n\n // If this is a structural variant create a complement of this variant for the other end\n // The test for \"SV\" is not comprehensive, there is not yet a standard for this\n if (variant.info && variant.info.CHR2 && variant.info.END) {\n allFeatures.push(svComplement(variant));\n }\n }\n }\n }\n\n return allFeatures\n }\n}\n\nfunction extractCallFields(tokens) {\n\n const callFields = {\n genotypeIndex: -1,\n fields: tokens\n };\n for (let i = 0; i < tokens.length; i++) {\n if (\"GT\" === tokens[i]) {\n callFields.genotypeIndex = i;\n }\n }\n return callFields\n}\n\nfunction svComplement(v) {\n\n const chr2 = v.info.CHR2;\n const pos2 = Number.parseInt(v.info.END);\n return {\n chr: chr2,\n start: pos2 - 1,\n end: pos2,\n _f: v\n }\n\n}\n\n/**\n * Parser for IGV desktop GWAS files. See http://software.broadinstitute.org/software/igv/GWAS\n */\nclass GWASParser {\n\n constructor(config) {\n // Defaults - can be overriden by header\n this.config = config;\n if (config.columns) {\n if (config.columns.chromosome === undefined ||\n config.columns.position === undefined ||\n config.columns.value === undefined) {\n throw Error(\"columns property must define chrCol, posCol, and valueCol\")\n }\n this.posCol = config.columns.position - 1;\n this.chrCol = config.columns.chromosome - 1;\n this.valueCol = config.columns.value - 1;\n } else {\n // Defaults -- can be overriden in header\n this.posCol = 2;\n this.chrCol = 1;\n this.valueCol = 3;\n }\n }\n\n async parseHeader(dataWrapper) {\n const headerLine = await dataWrapper.nextLine();\n return this.parseHeaderLine(headerLine)\n }\n\n parseHeaderLine(headerLine) {\n this.columns = headerLine.split(/\\t/);\n if (!this.config.columns) {\n for (let i = 0; i < this.columns.length; i++) {\n const c = this.columns[i].toLowerCase();\n switch (c) {\n case 'chr':\n case 'chromosome':\n case 'chr_id':\n this.chrCol = i;\n break\n case 'bp':\n case 'pos':\n case 'position':\n case 'chr_pos':\n this.posCol = i;\n break\n case 'p':\n case 'pval':\n case 'pvalue':\n case 'p-value':\n case 'p.value':\n this.valueCol = i;\n break\n }\n }\n }\n return this.columns\n }\n\n async parseFeatures(dataWrapper) {\n\n const allFeatures = [];\n const headerLine = dataWrapper.nextLine();\n if (!this.columns) {\n this.parseHeaderLine(headerLine);\n }\n let line;\n while ((line = dataWrapper.nextLine()) !== undefined) {\n const tokens = line.split(/\\t/);\n if (tokens.length === this.columns.length) {\n const chr = tokens[this.chrCol];\n const start = parseInt(tokens[this.posCol]) - 1;\n const end = start + 1;\n const value = Number(tokens[this.valueCol]);\n allFeatures.push(new GWASFeature({\n chr: chr,\n start: start,\n end: end,\n value: value,\n line: line,\n columns: this.columns\n }));\n }\n }\n return allFeatures\n }\n}\n\nclass GWASFeature {\n\n constructor({chr, start, end, value, line, columns}) {\n this.chr = chr;\n this.start = start;\n this.end = end;\n this.value = value;\n this.line = line;\n this.columns = columns;\n }\n\n popupData() {\n const tokens = this.line.split(/\\t/);\n return this.columns.map(function (c, index) {\n return {name: c, value: tokens[index]}\n })\n }\n\n getAttribute(attrName) {\n const tokens = this.line.split(/\\t/);\n for (let i = 0; i < this.columns.length; i++) {\n if (this.columns[i] === attrName) {\n return tokens[i]\n }\n }\n return undefined\n }\n\n}\n\n/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2014 Broad Institute\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\n/**\n * Define parsers for bed-like files (.bed, .gff, .vcf, etc). A parser should implement 2 methods\n *\n * parseHeader(data) - return an object representing a header or metadata. Details are format specific\n *\n * parseFeatures(data) - return an array of features\n *\n */\n\nvar aedRegexpNoNamespace = new RegExp(\"([^:]*)\\\\(([^)]*)\\\\)\"); // name(type) for AED parsing (namespace undefined)\nvar aedRegexpNamespace = new RegExp(\"([^:]*):([^(]*)\\\\(([^)]*)\\\\)\"); // namespace:name(type) for AED parsing\n\n\nclass AEDParser {\n\n constructor(config) {\n const decode = config ? config.decode : undefined;\n this.nameField = config ? config.nameField : undefined;\n this.skipRows = 0; // The number of fixed header rows to skip. Override for specific types as needed\n if (decode) {\n this.decode = decode;\n } else {\n this.decode = decodeAed;\n }\n this.delimiter = \"\\t\";\n }\n\n async parseHeader(dataWrapper) {\n let line;\n let header;\n while (line = await dataWrapper.nextLine()) {\n if (line.startsWith(\"track\") || line.startsWith(\"#\") || line.startsWith(\"browser\")) {\n if (line.startsWith(\"track\") || line.startsWith(\"#track\")) {\n let h = parseTrackLine(line);\n if (header) {\n Object.assign(header, h);\n } else {\n header = h;\n }\n } else if (line.startsWith(\"#columns\")) {\n let h = parseColumnsDirective(line);\n if (header) {\n Object.assign(header, h);\n } else {\n header = h;\n }\n } else if (line.startsWith(\"##gff-version 3\")) {\n this.format = \"gff3\";\n if (!header) header = {};\n header[\"format\"] = \"gff3\";\n }\n } else {\n break\n }\n }\n this.header = header; // Directives might be needed for parsing lines\n return header\n }\n\n async parseFeatures(dataWrapper) {\n\n const allFeatures = [];\n const decode = this.decode;\n const delimiter = this.delimiter || \"\\t\";\n let i = 0;\n let line;\n let wig;\n\n while ((line = dataWrapper.nextLine()) !== undefined) {\n i++;\n if (i <= this.skipRows || line.startsWith(\"track\") || line.startsWith(\"#\") || line.startsWith(\"browser\")) {\n continue\n }\n\n let tokens = readTokensAed();\n if (tokens.length < 1) {\n continue\n }\n\n if (!this.aed) {\n // Store information about the aed header in the parser itself\n // This is done only once - on the first row\n this.aed = parseAedHeaderRow(tokens);\n continue\n }\n\n const feature = decode.call(this, tokens, wig);\n if (feature) {\n allFeatures.push(feature);\n }\n }\n\n return allFeatures\n\n // Double quoted strings can contain newlines in AED\n // \"\" is an escape for a \".\n // Parse all this, clean it up, split into tokens in a custom way\n function readTokensAed() {\n var tokens = [],\n token = \"\",\n quotedString = false,\n n,\n c;\n\n while (line || line === '') {\n for (n = 0; n < line.length; n++) {\n c = line.charAt(n);\n if (c === delimiter) {\n if (!quotedString) {\n tokens.push(token);\n token = \"\";\n } else {\n token += c;\n }\n } else if (c === \"\\\"\") {\n // Look ahead to the next character\n if (n + 1 < line.length && line.charAt(n + 1) === \"\\\"\") {\n if (quotedString) {\n // Turn \"\" into a single \" in the output string\n token += \"\\\"\";\n }\n // Skip the next double quote\n n++;\n } else {\n // We know the next character is NOT a double quote, flip our state\n quotedString = !quotedString;\n }\n } else {\n token += c;\n }\n }\n // We are at the end of the line\n if (quotedString) {\n token += '\\n'; // Add newline to the token\n line = nextLine(); // Keep going\n } else {\n // We can end the loop\n break\n }\n }\n // Push the last token\n tokens.push(token);\n return tokens\n }\n }\n}\n\n\nfunction parseAedToken(value) {\n // Example: refseq:accessionNumber(aed:String)\n // refseq - namespace, will be declared later\n // accessionNumber - name of the field\n // aed:String - type of the field\n // The namespace part may be missing\n var match = aedRegexpNamespace.exec(value);\n if (match) {\n return {\n namespace: match[1],\n name: match[2],\n type: match[3]\n }\n }\n\n match = aedRegexpNoNamespace.exec(value);\n if (match) {\n return {\n namespace: '?',\n name: match[1],\n type: match[2]\n }\n } else {\n throw new Error(\"Error parsing the header row of AED file - column not in ns:name(ns:type) format\")\n }\n}\n\nfunction parseAedHeaderRow(tokens) {\n // First row of AED file defines column names\n // Each header item is an aed token - see parseAedToken\n var aed,\n k,\n token,\n aedToken;\n\n // Initialize aed section to be filled in\n aed = {\n columns: [ // Information about the namespace, name and type of each column\n // Example entry:\n // { namespace: 'bio', name: 'start', type: 'aed:Integer' }\n ],\n metadata: { // Metadata about the entire AED file\n // Example:\n // {\n // aed: {\n // application: { value: \"CHaS Browser 3.3.0.139 (r10838)\", type: \"aed:String\" },\n // created: { value: \"2018-01-02T10:20:30.123+01:00\", type: \"aed:DateTime\" },\n // modified: { value: \"2018-03-04T11:22:33.456+01:00\", type: \"aed:DateTime\" },\n // }\n // affx: {\n // ucscGenomeVersion: { value: \"hg19\", type: \"aed:String\" }\n // },\n // namespace: {\n // omim: { value: \"http://affymetrix.com/ontology/www.ncbi.nlm.nih.gov/omim/\", type: \"aed:URI\" },\n // affx: { value: \"http://affymetrix.com/ontology/\", type: \"aed:URI\" },\n // refseq: { value: \"http://affymetrix.com/ontology/www.ncbi.nlm.nih.gov/RefSeq/\", type: \"aed:URI\" }\n // }\n // }\n }\n };\n for (k = 0; k < tokens.length; k++) {\n token = tokens[k];\n aedToken = parseAedToken(token);\n aed.columns.push(aedToken);\n }\n\n return aed\n}\n\nfunction parseTrackLine(line) {\n\n const properties = {};\n const tokens = line.split(/(?:\")([^\"]+)(?:\")|([^\\s\"]+)(?=\\s+|$)/g);\n\n\n // Clean up tokens array\n let curr;\n const tmp = [];\n for (let tk of tokens) {\n if (!tk || tk.trim().length === 0) continue\n if (tk.endsWith(\"=\") > 0) {\n curr = tk;\n } else if (curr) {\n tmp.push(curr + tk);\n curr = undefined;\n } else {\n tmp.push(tk);\n }\n }\n for (let str of tmp) {\n if (!str) return\n var kv = str.split('=', 2);\n if (kv.length === 2) {\n const key = kv[0].trim();\n const value = kv[1].trim();\n properties[key] = value;\n }\n\n }\n\n return properties\n}\n\nfunction parseColumnsDirective(line) {\n\n let properties = {};\n let t1 = line.split(/\\s+/);\n\n if (t1.length === 2) {\n\n let t2 = t1[1].split(\";\");\n\n t2.forEach(function (keyValue) {\n\n let t = keyValue.split(\"=\");\n\n if (t[0] === \"color\") {\n properties.colorColumn = Number.parseInt(t[1]) - 1;\n } else if (t[0] === \"thickness\") {\n properties.thicknessColumn = Number.parseInt(t[1]) - 1;\n }\n });\n }\n\n return properties\n}\n\n/**\n * AED file feature.\n *\n * @param aed link to the AED file object containing file-level metadata and column descriptors\n * @param allColumns All columns as parsed from the AED\n *\n * Other values are parsed one by one\n */\nfunction AedFeature(aed, allColumns) {\n var token, aedColumn, aedColumns = aed.columns;\n\n // Link to AED file (for metadata)\n this.aed = aed;\n\n // Unparsed columns from AED file\n this.allColumns = allColumns;\n\n // Prepare space for the parsed values\n this.chr = null;\n this.start = null;\n this.end = null;\n this.score = 1000;\n this.strand = '.';\n this.cdStart = null;\n this.cdEnd = null;\n this.name = null;\n this.color = null;\n\n for (let i = 0; i < allColumns.length; i++) {\n token = allColumns[i];\n if (!token) {\n // Skip empty fields\n continue\n }\n aedColumn = aedColumns[i];\n if (aedColumn.type === 'aed:Integer') {\n token = parseInt(token);\n }\n var arr = [];\n if (aedColumn.namespace.length > 0) {\n for (let j = 0; j < aedColumn.namespace.length; j++) {\n arr.push(aedColumn.namespace.charCodeAt(j));\n }\n }\n if (aedColumn.namespace.trim() === 'bio') {\n if (aedColumn.name === 'sequence') {\n this.chr = token;\n } else if (aedColumn.name === 'start') {\n this.start = token;\n } else if (aedColumn.name === 'end') {\n this.end = token;\n } else if (aedColumn.name === 'cdsMin') {\n this.cdStart = token;\n } else if (aedColumn.name === 'cdsMax') {\n this.cdEnd = token;\n } else if (aedColumn.name === 'strand') {\n this.strand = token;\n }\n } else if (aedColumn.namespace === 'aed') {\n if (aedColumn.name === 'name') {\n this.name = token;\n }\n } else if (aedColumn.namespace === 'style') {\n if (aedColumn.name === 'color') {\n this.color = IGVColor.createColorString(token);\n }\n }\n }\n}\n\nAedFeature.prototype.popupData = function () {\n var data = [],\n aed = this.aed;\n // Just dump everything we have for now\n for (var i = 0; i < this.allColumns.length; i++) {\n var featureValue = this.allColumns[i];\n var name = aed.columns[i].name;\n // Skip columns that are not interesting - you know the sequence, and you can see color\n if (name !== 'sequence' && name !== 'color') {\n if (featureValue) {\n data.push({name: name, value: featureValue});\n }\n }\n }\n return data\n};\n\n/**\n * Decode the AED file format\n * @param tokens\n * @param ignore\n * @returns decoded feature, or null if this is not a valid record\n */\nfunction decodeAed(tokens, ignore) {\n var name, value, token,\n nonEmptyTokens = 0,\n aedColumns = this.aed.columns,\n aedColumn,\n aedKey,\n i;\n\n // Each aed row must match the exact number of columns or we skip it\n if (tokens.length !== aedColumns.length) {\n console.log('Corrupted AED file row: ' + tokens.join(','));\n return undefined\n }\n\n for (i = 0; i < tokens.length; i++) {\n aedColumn = aedColumns[i];\n token = tokens[i];\n if (token !== '') {\n nonEmptyTokens++;\n }\n if (aedColumn.name === 'name' && aedColumn.namespace === 'aed') {\n name = token;\n } else if (aedColumn.name === 'value' && aedColumn.namespace === 'aed') {\n value = token;\n }\n }\n\n if (nonEmptyTokens === 2 && name && value) {\n // Special row that defines metadata for the entire file\n aedKey = parseAedToken(name);\n // Store in the metadata section\n if (!this.aed.metadata[aedKey.namespace]) {\n this.aed.metadata[aedKey.namespace] = {};\n }\n if (!this.aed.metadata[aedKey.namespace][aedKey.name]) {\n this.aed.metadata[aedKey.namespace][aedKey.name] = {\n type: aedKey.type,\n value: value\n };\n }\n // Ignore this value\n return undefined\n }\n\n var feature = new AedFeature(this.aed, tokens);\n\n if (!feature.chr || (!feature.start && feature.start !== 0) || !feature.end) {\n console.log('Cannot parse feature: ' + tokens.join(','));\n return undefined\n }\n\n return feature\n}\n\n/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2014 Broad Institute\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\n\n// TODO -- big endian?\n\nclass BinaryParser {\n constructor(dataView, littleEndian) {\n\n this.littleEndian = littleEndian !== undefined ? littleEndian : true;\n this.position = 0;\n this.view = dataView;\n this.length = dataView.byteLength;\n }\n\n available() {\n return this.length - this.position\n }\n\n remLength() {\n return this.length - this.position\n }\n\n hasNext() {\n return this.position < this.length - 1\n }\n\n getByte() {\n var retValue = this.view.getUint8(this.position, this.littleEndian);\n this.position++;\n return retValue\n }\n\n getShort() {\n\n var retValue = this.view.getInt16(this.position, this.littleEndian);\n this.position += 2;\n return retValue\n }\n\n getUShort() {\n\n // var byte1 = this.getByte(),\n // byte2 = this.getByte(),\n // retValue = ((byte2 << 24 >>> 16) + (byte1 << 24 >>> 24));\n // return retValue;\n\n //\n var retValue = this.view.getUint16(this.position, this.littleEndian);\n this.position += 2;\n return retValue\n }\n\n\n getInt() {\n\n var retValue = this.view.getInt32(this.position, this.littleEndian);\n this.position += 4;\n return retValue\n }\n\n\n getUInt() {\n var retValue = this.view.getUint32(this.position, this.littleEndian);\n this.position += 4;\n return retValue\n }\n\n getLong() {\n\n // DataView doesn't support long. So we'll try manually\n\n var b = [];\n b[0] = this.view.getUint8(this.position);\n b[1] = this.view.getUint8(this.position + 1);\n b[2] = this.view.getUint8(this.position + 2);\n b[3] = this.view.getUint8(this.position + 3);\n b[4] = this.view.getUint8(this.position + 4);\n b[5] = this.view.getUint8(this.position + 5);\n b[6] = this.view.getUint8(this.position + 6);\n b[7] = this.view.getUint8(this.position + 7);\n\n var value = 0;\n if (this.littleEndian) {\n for (let i = b.length - 1; i >= 0; i--) {\n value = (value * 256) + b[i];\n }\n } else {\n for (let i = 0; i < b.length; i++) {\n value = (value * 256) + b[i];\n }\n }\n\n\n this.position += 8;\n return value\n }\n\n getString(len) {\n\n var s = \"\";\n var c;\n while ((c = this.view.getUint8(this.position++)) !== 0) {\n s += String.fromCharCode(c);\n if (len && s.length === len) break\n }\n return s\n }\n\n getFixedLengthString(len) {\n\n var s = \"\";\n var i;\n var c;\n for (i = 0; i < len; i++) {\n c = this.view.getUint8(this.position++);\n if (c > 0) {\n s += String.fromCharCode(c);\n }\n }\n return s\n }\n\n getFixedLengthTrimmedString(len) {\n\n var s = \"\";\n var i;\n var c;\n for (i = 0; i < len; i++) {\n c = this.view.getUint8(this.position++);\n if (c > 32) {\n s += String.fromCharCode(c);\n }\n }\n return s\n }\n\n getFloat() {\n\n var retValue = this.view.getFloat32(this.position, this.littleEndian);\n this.position += 4;\n return retValue\n\n\n }\n\n getDouble() {\n\n var retValue = this.view.getFloat64(this.position, this.littleEndian);\n this.position += 8;\n return retValue\n }\n\n skip(n) {\n\n this.position += n;\n return this.position\n }\n\n\n /**\n * Return a BGZip (bam and tabix) virtual pointer\n * TODO -- why isn't 8th byte used ?\n * @returns {*}\n */\n getVPointer() {\n\n var position = this.position,\n offset = (this.view.getUint8(position + 1) << 8) | (this.view.getUint8(position)),\n byte6 = ((this.view.getUint8(position + 6) & 0xff) * 0x100000000),\n byte5 = ((this.view.getUint8(position + 5) & 0xff) * 0x1000000),\n byte4 = ((this.view.getUint8(position + 4) & 0xff) * 0x10000),\n byte3 = ((this.view.getUint8(position + 3) & 0xff) * 0x100),\n byte2 = ((this.view.getUint8(position + 2) & 0xff)),\n block = byte6 + byte5 + byte4 + byte3 + byte2;\n this.position += 8;\n\n // if (block == 0 && offset == 0) {\n // return null;\n // } else {\n return new VPointer(block, offset)\n // }\n }\n}\n\nclass VPointer {\n constructor(block, offset) {\n this.block = block;\n this.offset = offset;\n }\n\n isLessThan(vp) {\n return this.block < vp.block ||\n (this.block === vp.block && this.offset < vp.offset)\n }\n\n isGreaterThan(vp) {\n return this.block > vp.block ||\n (this.block === vp.block && this.offset > vp.offset)\n }\n\n isEqualTo(vp) {\n return this.block === vp.block && this.offset === vp.offset\n }\n\n print() {\n return \"\" + this.block + \":\" + this.offset\n }\n}\n\nfunction optimizeChunks(chunks, lowest) {\n\n if (chunks.length === 0) return chunks\n\n chunks.sort(function (c0, c1) {\n\n const dif = c0.minv.block - c1.minv.block;\n if (dif !== 0) {\n return dif\n } else {\n return c0.minv.offset - c1.minv.offset\n }\n });\n\n if(chunks.length <= 1) {\n return chunks\n }\n\n // console.log(\"Before trimming \" + chunks.length)\n // for (let c of chunks) {\n // console.log(`${c.minv.block} ${c.minv.offset} - ${c.maxv.block} ${c.maxv.offset}`)\n // }\n\n if (lowest) {\n chunks = chunks.filter(c => c.maxv.isGreaterThan(lowest));\n }\n\n // console.log(\"Before merging \" + chunks.length)\n // for (let c of chunks) {\n // console.log(`${c.minv.block} ${c.minv.offset} - ${c.maxv.block} ${c.maxv.offset}`)\n // }\n\n const mergedChunks = [];\n let lastChunk;\n for (let chunk of chunks) {\n\n if (!lastChunk) {\n mergedChunks.push(chunk);\n lastChunk = chunk;\n } else {\n if (canMerge(lastChunk, chunk)) {\n if (chunk.maxv.isGreaterThan(lastChunk.maxv)) {\n lastChunk.maxv = chunk.maxv;\n }\n } else {\n mergedChunks.push(chunk);\n lastChunk = chunk;\n }\n }\n }\n\n // console.log(\"After merging \" + mergedChunks.length)\n // for (let c of mergedChunks) {\n // console.log(`${c.minv.block} ${c.minv.offset} - ${c.maxv.block} ${c.maxv.offset}`)\n // }\n\n return mergedChunks\n}\n\n\n/**\n * Merge 2 blocks if the file position gap between them is < 16 kb, and the total size is < ~5 mb\n * @param chunk1\n * @param chunk2\n * @returns {boolean|boolean}\n */\nfunction canMerge(chunk1, chunk2) {\n chunk2.minv.block - chunk1.maxv.block;\n const sizeEstimate = chunk1.maxv.block - chunk1.minv.block;\n return sizeEstimate < 5000000\n}\n\n// Represents a CSI Bam or Tabix index\n\nconst CSI1_MAGIC$1 = 21582659; // CSI\\1\nconst CSI2_MAGIC$1 = 38359875; // CSI\\2\n\nasync function parseCsiIndex(arrayBuffer, genome) {\n\n const idx = new CSIIndex();\n idx.parse(arrayBuffer, genome);\n return idx\n}\n\nclass CSIIndex {\n\n constructor(tabix) {\n this.tabix = true; // Means whatever is indexed is BGZipped\n }\n\n parse(arrayBuffer, genome) {\n const parser = new BinaryParser(new DataView(arrayBuffer));\n\n const magic = parser.getInt();\n\n if (magic !== CSI1_MAGIC$1) {\n if (magic === CSI2_MAGIC$1) {\n throw Error(\"CSI version 2 is not supported. Please enter an issue at https://github.com/igvteam/igv.js\")\n } else {\n throw Error(\"Not a CSI index\")\n }\n }\n\n this.indices = [];\n this.blockMin = Number.MAX_SAFE_INTEGER;\n this.lastBlockPosition = [];\n this.sequenceIndexMap = {};\n\n this.minShift = parser.getInt();\n this.depth = parser.getInt();\n const lAux = parser.getInt();\n const seqNames = [];\n let bmax = 0;\n\n if (lAux >= 28) {\n // Tabix header parameters aren't used, but they must be read to advance the pointer\n parser.getInt();\n parser.getInt();\n parser.getInt();\n parser.getInt();\n parser.getInt();\n parser.getInt();\n const l_nm = parser.getInt();\n const nameEndPos = parser.position + l_nm;\n let i = 0;\n while (parser.position < nameEndPos) {\n let seq_name = parser.getString();\n // Translate to \"official\" chr name.\n if (genome) {\n seq_name = genome.getChromosomeName(seq_name);\n }\n this.sequenceIndexMap[seq_name] = i;\n seqNames[i] = seq_name;\n i++;\n }\n }\n\n const MAX_BIN = this.bin_limit() + 1;\n const nref = parser.getInt();\n for (let ref = 0; ref < nref; ref++) {\n const binIndex = [];\n const loffset = [];\n const nbin = parser.getInt();\n for (let b = 0; b < nbin; b++) {\n\n const binNumber = parser.getInt();\n loffset[binNumber] = parser.getVPointer();\n\n if (binNumber > MAX_BIN) {\n // This is a psuedo bin, not used but we have to consume the bytes\n parser.getInt(); // # of chunks for this bin\n parser.getVPointer(); // unmapped beg\n parser.getVPointer(); // unmapped end\n parser.getLong();\n parser.getLong();\n\n } else {\n\n binIndex[binNumber] = [];\n const nchnk = parser.getInt(); // # of chunks for this bin\n\n for (let i = 0; i < nchnk; i++) {\n const cs = parser.getVPointer(); //chunk_beg\n const ce = parser.getVPointer(); //chunk_end\n if (cs && ce) {\n if (cs.block < this.blockMin) {\n this.blockMin = cs.block; // Block containing first alignment\n }\n if (ce.block > bmax) {\n bmax = ce.block;\n }\n binIndex[binNumber].push([cs, ce]);\n }\n }\n }\n }\n\n if (nbin > 0) {\n this.indices[ref] = {\n binIndex: binIndex,\n loffset: loffset\n };\n }\n }\n this.lastBlockPosition = bmax;\n }\n\n get chromosomeNames() {\n return Object.keys(this.sequenceIndexMap)\n }\n\n /**\n * Fetch blocks for a particular genomic range. This method is public so it can be unit-tested.\n *\n * @param refId the sequence dictionary index of the chromosome\n * @param min genomic start position\n * @param max genomic end position\n * @param return an array of {minv: {filePointer, offset}, {maxv: {filePointer, offset}}\n */\n chunksForRange(refId, min, max) {\n\n const ba = this.indices[refId];\n if (!ba) {\n return []\n } else {\n const overlappingBins = this.reg2bins(min, max); // List of bin #s that overlap min, max\n if (overlappingBins.length == 0) return []\n\n const chunks = [];\n // Find chunks in overlapping bins. Leaf bins (< 4681) are not pruned\n for (let binRange of overlappingBins) {\n for (let bin = binRange[0]; bin <= binRange[1]; bin++) {\n if (ba.binIndex[bin]) {\n const binChunks = ba.binIndex[bin];\n for (let c of binChunks) {\n const cs = c[0];\n const ce = c[1];\n chunks.push({minv: cs, maxv: ce, bin: bin});\n }\n }\n }\n }\n\n const lowestOffset = ba.loffset[overlappingBins[0]];\n\n return optimizeChunks(chunks, lowestOffset)\n }\n\n }\n\n // reg2bins implementation adapted from GMOD/tabix-js https://github.com/GMOD/tabix-js/blob/master/src/csi.ts\n reg2bins(beg, end) {\n beg -= 1; // < convert to 1-based closed\n if (beg < 1) beg = 1;\n if (end > 2 ** 34) end = 2 ** 34; // 17 GiB ought to be enough for anybody\n end -= 1;\n let l = 0;\n let t = 0;\n let s = this.minShift + this.depth * 3;\n const bins = [];\n for (; l <= this.depth; s -= 3, t += (1 << l * 3), l += 1) {\n const b = t + (beg >> s);\n const e = t + (end >> s);\n //\n // ITS NOT CLEAR WHERE THIS TEST CAME FROM, but maxBinNumber is never set, and its not clear what it represents.\n // if (e - b + bins.length > this.maxBinNumber)\n // throw new Error(\n // `query ${beg}-${end} is too large for current binning scheme (shift ${this.minShift}, depth ${this.depth}), try a smaller query or a coarser index binning scheme`,\n // )\n //\n bins.push([b, e]);\n }\n return bins\n }\n\n\n bin_limit() {\n return ((1 << (this.depth + 1) * 3) - 1) / 7\n }\n\n}\n\n// Represents a BAM or Tabix index.\n\nconst BAI_MAGIC$1 = 21578050;\nconst TABIX_MAGIC$1 = 21578324;\n\n\nasync function parseBamIndex(arrayBuffer, genome) {\n const index = new BamIndex();\n await index.parse(arrayBuffer, false, genome);\n return index\n}\n\nasync function parseTabixIndex(arrayBuffer, genome) {\n const index = new BamIndex();\n await index.parse(arrayBuffer, true, genome);\n return index\n}\n\nclass BamIndex {\n\n constructor() {\n\n }\n\n async parse(arrayBuffer, tabix, genome) {\n\n const indices = [];\n let blockMin = Number.MAX_SAFE_INTEGER;\n let blockMax = 0;\n\n const parser = new BinaryParser(new DataView(arrayBuffer));\n const magic = parser.getInt();\n const sequenceIndexMap = {};\n if (magic === BAI_MAGIC$1 || (tabix && magic === TABIX_MAGIC$1)) {\n\n const nref = parser.getInt();\n if (tabix) {\n // Tabix header parameters aren't used, but they must be read to advance the pointer\n parser.getInt();\n parser.getInt();\n parser.getInt();\n parser.getInt();\n parser.getInt();\n parser.getInt();\n parser.getInt();\n\n for (let i = 0; i < nref; i++) {\n let seq_name = parser.getString();\n // Translate to \"official\" chr name.\n if (genome) {\n seq_name = genome.getChromosomeName(seq_name);\n }\n sequenceIndexMap[seq_name] = i;\n }\n }\n\n // Loop through sequences\n for (let ref = 0; ref < nref; ref++) {\n\n const binIndex = {};\n const linearIndex = [];\n const nbin = parser.getInt();\n\n for (let b = 0; b < nbin; b++) {\n const binNumber = parser.getInt();\n if (binNumber === 37450) {\n // This is a psuedo bin, not used but we have to consume the bytes\n parser.getInt(); // # of chunks for this bin\n parser.getVPointer(); // unmapped beg\n parser.getVPointer(); // unmapped end\n parser.getLong();\n parser.getLong();\n\n } else {\n\n binIndex[binNumber] = [];\n const nchnk = parser.getInt(); // # of chunks for this bin\n\n for (let i = 0; i < nchnk; i++) {\n const cs = parser.getVPointer(); //chunk_beg\n const ce = parser.getVPointer(); //chunk_end\n if (cs && ce) {\n if (cs.block < blockMin) {\n blockMin = cs.block; // Block containing first alignment\n }\n if (ce.block > blockMax) {\n blockMax = ce.block;\n }\n binIndex[binNumber].push([cs, ce]);\n }\n }\n }\n }\n\n const nintv = parser.getInt();\n for (let i = 0; i < nintv; i++) {\n const cs = parser.getVPointer();\n linearIndex.push(cs); // Might be null\n }\n\n if (nbin > 0) {\n indices[ref] = {\n binIndex: binIndex,\n linearIndex: linearIndex\n };\n }\n }\n\n this.firstBlockPosition = blockMin;\n this.lastBlockPosition = blockMax;\n this.indices = indices;\n this.sequenceIndexMap = sequenceIndexMap;\n this.tabix = tabix;\n\n } else {\n throw new Error(indexURL + \" is not a \" + (tabix ? \"tabix\" : \"bai\") + \" file\")\n }\n\n\n }\n\n get chromosomeNames() {\n return Object.keys(this.sequenceIndexMap)\n }\n\n /**\n * Fetch chunks for a particular genomic range. This method is public so it can be unit-tested.\n *\n * @param refId the sequence dictionary index of the chromosome\n * @param min genomic start position\n * @param max genomic end position\n * @param return an array of objects representing chunks (file spans) {minv: {block, offset}, {maxv: {block, offset}}\n */\n chunksForRange(refId, min, max) {\n\n const bam = this;\n const ba = bam.indices[refId];\n\n if (!ba) {\n return []\n } else {\n const overlappingBins = reg2bins(min, max); // List of bin #s that overlap min, max\n\n //console.log(\"bin ranges\")\n //for(let b of overlappingBins) {\n // console.log(`${b[0]} - ${b[1]}`)\n //}\n\n const chunks = [];\n // Find chunks in overlapping bins. Leaf bins (< 4681) are not pruned\n for (let binRange of overlappingBins) {\n for (let bin = binRange[0]; bin <= binRange[1]; bin++) {\n if (ba.binIndex[bin]) {\n const binChunks = ba.binIndex[bin];\n for (let c of binChunks) {\n const cs = c[0];\n const ce = c[1];\n chunks.push({minv: cs, maxv: ce});\n }\n }\n }\n }\n\n // Use the linear index to find minimum file position of chunks that could contain alignments in the region\n const nintv = ba.linearIndex.length;\n\n let lowest;\n const minLin = Math.min(min >> 14, nintv - 1); // i.e. min / 16384\n const maxLin = Math.min(max >> 14, nintv - 1);\n for (let i = minLin; i <= maxLin; i++) {\n const vp = ba.linearIndex[i];\n if (vp) {\n lowest = vp; // lowest file offset that contains alignments overlapping (min, max)\n break\n }\n }\n\n return optimizeChunks(chunks, lowest)\n }\n }\n}\n\n\n\n/**\n * Calculate the list of bins that overlap with region [beg, end]\n *\n */\nfunction reg2bins(beg, end) {\n const list = [];\n if (end >= 1 << 29) end = 1 << 29;\n --end;\n list.push([0, 0]);\n list.push([1 + (beg >> 26), 1 + (end >> 26)]);\n list.push([9 + (beg >> 23), 9 + (end >> 23)]);\n list.push([73 + (beg >> 20), 73 + (end >> 20)]);\n list.push([585 + (beg >> 17), 585 + (end >> 17)]);\n list.push([4681 + (beg >> 14), 4681 + (end >> 14)]);\n\n // for (k = 1 + (beg >> 26); k <= 1 + (end >> 26); ++k) list.push(k);\n // for (k = 9 + (beg >> 23); k <= 9 + (end >> 23); ++k) list.push(k);\n // for (k = 73 + (beg >> 20); k <= 73 + (end >> 20); ++k) list.push(k);\n // for (k = 585 + (beg >> 17); k <= 585 + (end >> 17); ++k) list.push(k);\n // for (k = 4681 + (beg >> 14); k <= 4681 + (end >> 14); ++k) list.push(k);\n return list\n}\n\n/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2014 Broad Institute\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\nasync function parseTribbleIndex(arrayBuffer, genome) {\n\n const index = new TribbleIndex();\n index.parse(arrayBuffer, genome);\n return index\n}\n\nclass TribbleIndex {\n\n constructor() {\n\n }\n\n async parse(arrayBuffer, genome) {\n\n let blockMax = 0;\n this.chrIndex = {};\n this.lastBlockPosition = [];\n const parser = new BinaryParser(new DataView(arrayBuffer));\n readHeader(parser);\n\n let nChrs = parser.getInt();\n while (nChrs-- > 0) {\n\n // todo -- support interval tree index, we're assuming its a linear index\n\n let chr = parser.getString();\n if (genome) chr = genome.getChromosomeName(chr); // Translate to canonical name\n\n const binWidth = parser.getInt();\n const nBins = parser.getInt();\n const longestFeature = parser.getInt();\n parser.getInt() > 0;\n parser.getInt();\n\n // note the code below accounts for > 60% of the total time to read an index\n let pos = parser.getLong();\n const blocks = [];\n for (let binNumber = 0; binNumber < nBins; binNumber++) {\n const nextPos = parser.getLong();\n blocks.push({min: pos, max: nextPos}); // {position: pos, size: size});\n pos = nextPos;\n if (nextPos > blockMax) {\n blockMax = nextPos;\n }\n }\n this.chrIndex[chr] = {chr: chr, blocks: blocks, longestFeature: longestFeature, binWidth: binWidth};\n }\n\n this.lastBlockPosition = blockMax;\n\n\n /**\n * Read the header . Data here is not used in igv.js but we need to read it to advance the pointer.\n * @param parser\n */\n function readHeader(parser) {\n\n parser.getInt(); // view._getInt32(offset += 32, true);\n parser.getInt();\n const version = parser.getInt();\n parser.getString();\n parser.getLong();\n parser.getLong();\n parser.getString();\n parser.getInt();\n if (version >= 3) {\n let nProperties = parser.getInt();\n while (nProperties-- > 0) {\n parser.getString();\n parser.getString();\n }\n }\n }\n }\n\n get chromosomeNames() {\n return Object.keys(this.chrIndex)\n }\n\n\n /**\n * Fetch blocks for a particular genomic range.\n *\n * @param queryChr the sequence dictionary index of the chromosome\n * @param min genomic start position\n * @param max genomic end position\n */\n chunksForRange(queryChr, min, max) { //function (refId, min, max) {\n const chrIdx = this.chrIndex[queryChr];\n\n if (chrIdx) {\n const blocks = chrIdx.blocks;\n const longestFeature = chrIdx.longestFeature;\n const binWidth = chrIdx.binWidth;\n const adjustedPosition = Math.max(min - longestFeature, 0);\n const startBinNumber = Math.floor(adjustedPosition / binWidth);\n\n if (startBinNumber >= blocks.length) // are we off the end of the bin list, so return nothing\n return []\n else {\n const endBinNumber = Math.min(Math.floor((max - 1) / binWidth), blocks.length - 1);\n\n // By definition blocks are adjacent in the file for the liner index. Combine them into one merged block\n const startPos = blocks[startBinNumber].min;\n const endPos = blocks[endBinNumber].max;\n const size = endPos - startPos;\n if (size === 0) {\n return []\n } else {\n const mergedBlock = {minv: {block: startPos, offset: 0}, maxv: {block: endPos, offset: 0}};\n return [mergedBlock]\n }\n }\n } else {\n return undefined\n }\n }\n}\n\nconst CSI1_MAGIC = 21582659; // CSI\\1\nconst CSI2_MAGIC = 38359875; // CSI\\2\nconst BAI_MAGIC = 21578050;\nconst TABIX_MAGIC = 21578324;\nconst TRIBBLE_MAGIC = 1480870228; // byte[]{'T', 'I', 'D', 'X'};\n\n/**\n * @param indexURL\n * @param config\n * @param tabix\n *\n */\nasync function loadIndex(indexURL, config, genome) {\n\n let arrayBuffer = await igvxhr.loadArrayBuffer(indexURL, buildOptions(config));\n let dv = new DataView(arrayBuffer);\n\n // Some indexs are bgzipped, specifically tabix, and csi. Bam (bai) are not. Tribble is usually not.\n // Check first 2 bytes of file for gzip magic number, and inflate if neccessary\n if (dv.getUint8(0) === 0x1f && dv.getUint8(1) === 0x8b) { // gzipped\n const inflate = unbgzf(arrayBuffer);\n arrayBuffer = inflate.buffer;\n dv = new DataView(arrayBuffer);\n }\n\n const magic = dv.getInt32(0, true);\n switch (magic) {\n case BAI_MAGIC:\n return parseBamIndex(arrayBuffer, genome)\n case TABIX_MAGIC:\n return parseTabixIndex(arrayBuffer, genome)\n case CSI1_MAGIC:\n return parseCsiIndex(arrayBuffer, genome)\n case TRIBBLE_MAGIC:\n return parseTribbleIndex(arrayBuffer, genome)\n case CSI2_MAGIC:\n throw Error(\"CSI version 2 is not supported.\")\n default:\n throw Error(`Unrecognized index type: ${indexURL}`)\n }\n}\n\n/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2016-2017 The Regents of the University of California\n * Author: Jim Robinson\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\nfunction getDataWrapper(data) {\n\n if (typeof (data) == 'string' || data instanceof String) {\n return new StringDataWrapper(data)\n } else {\n return new ByteArrayDataWrapper(data)\n }\n}\n\n\n// Data might be a string, or an UInt8Array\nclass StringDataWrapper {\n\n constructor(string) {\n this.data = string;\n this.ptr = 0;\n }\n\n nextLine() {\n var start = this.ptr,\n idx = this.data.indexOf('\\n', start),\n data = this.data;\n\n if (idx > 0) {\n this.ptr = idx + 1; // Advance pointer for next line\n if (idx > start && data.charAt(idx - 1) === '\\r') {\n // Trim CR manually in CR/LF sequence\n return data.substring(start, idx - 1)\n }\n return data.substring(start, idx)\n } else {\n var length = data.length;\n this.ptr = length;\n // Return undefined only at the very end of the data\n return (start >= length) ? undefined : data.substring(start)\n }\n }\n}\n\nclass ByteArrayDataWrapper {\n\n constructor(array) {\n this.data = array;\n this.length = this.data.length;\n this.ptr = 0;\n }\n\n nextLine() {\n\n var c, result;\n result = \"\";\n\n if (this.ptr >= this.length) return undefined\n\n for (var i = this.ptr; i < this.length; i++) {\n c = String.fromCharCode(this.data[i]);\n if (c === '\\r') continue\n if (c === '\\n') break\n result = result + c;\n }\n\n this.ptr = i + 1;\n return result\n }\n\n}\n\n/**\n * Class to iterate line-by-line over a BGZipped text file. This class is useful for iterating from the start of\n * the file. Not useful for indexed queries.\n */\n\nclass BGZLineReader {\n\n constructor(config) {\n this.config = config;\n this.filePtr = 0;\n this.bufferPtr = 0;\n this.buffer;\n }\n\n async nextLine() {\n\n let result = undefined;\n\n try {\n while (true) {\n const length = this.buffer ? this.buffer.length : 0;\n while (this.bufferPtr < length) {\n const c = String.fromCharCode(this.buffer[this.bufferPtr++]);\n if (c === '\\r') continue\n if (c === '\\n') {\n return result\n }\n result = result ? result + c : c;\n }\n if (this.eof) {\n return result\n } else {\n await this.readNextBlock();\n }\n }\n } catch (e) {\n console.warn(e);\n this.eof = true;\n return result\n }\n }\n\n async readNextBlock() {\n\n const bsizeOptions = buildOptions(this.config, {\n range: {\n start: this.filePtr,\n size: 26\n }\n });\n const abuffer = await igvxhr.loadArrayBuffer(this.config.url, bsizeOptions);\n const bufferSize = bgzBlockSize$1(abuffer);\n\n if (bufferSize === 0) {\n this.eof = true;\n this.buffer = undefined;\n } else {\n\n const options = buildOptions(this.config, {range: {start: this.filePtr, size: bufferSize}});\n const data = await igvxhr.loadArrayBuffer(this.config.url, options);\n if (data.byteLength < bufferSize) {\n this.eof = true; // Assumption\n }\n this.buffer = unbgzf(data);\n if(this.buffer.byteLength == 0) {\n this.eof = true;\n }\n this.bufferPtr = 0;\n this.filePtr += data.byteLength; //data.byteLength;\n }\n }\n\n}\n\nfunction concatenateArrayBuffers(arrayBuffers) {\n\n if (arrayBuffers.length === 1) {\n return arrayBuffers[0]\n }\n\n let len = 0;\n for (const b of arrayBuffers) {\n len += b.byteLength;\n }\n const c = new Uint8Array(len);\n let offset = 0;\n for (const b of arrayBuffers) {\n c.set(new Uint8Array(b), offset);\n offset += b.byteLength;\n }\n return c.buffer\n}\n\n/**\n * Return the block size for the data buffer.\n * @param data\n * @returns {number}\n */\nconst bgzBlockSize = (data) => {\n const ba = ArrayBuffer.isView(data) ? data : new Uint8Array(data);\n const bsize = (ba[17] << 8 | ba[16]) + 1;\n return bsize\n};\n\nclass BGZBlockLoader {\n\n constructor(config) {\n this.config = config;\n this.cacheBlocks = false != config.cacheBlocks; // Default to true\n this.cache = undefined;\n }\n\n /**\n * Return inflated data from startBlock through endBlock as an UInt8Array\n *\n * @param minv minimum virtual pointer {block, offset}\n * @param maxv maximum virtual pointer {block, offset}\n * @returns {Promise}\n */\n async getData(minv, maxv) {\n\n const startBlock = minv.block;\n const endBlock = maxv.block;\n const skipEnd = maxv.offset === 0;\n\n const blocks = await this.getInflatedBlocks(startBlock, endBlock, skipEnd);\n if (blocks.length === 1) {\n return blocks[0]\n }\n\n let len = 0;\n for (const b of blocks) {\n len += b.byteLength;\n }\n const c = new Uint8Array(len);\n let offset = 0;\n for (const b of blocks) {\n c.set(b, offset);\n offset += b.byteLength;\n }\n return c\n }\n\n /**\n * Return the inflated data for the specified blocks as an array of Uint8Arrays. This method is public so\n * it can be unit tested. *\n * @param startBlock\n * @param endBlock\n * @returns {Promise<*[Uint8Array]>}\n */\n async getInflatedBlocks(startBlock, endBlock, skipEnd) {\n\n if (!this.cacheBlocks) {\n const buffer = await this.loadBLockData(startBlock, endBlock, {skipEnd});\n return inflateBlocks(buffer)\n } else {\n\n const c = this.cache;\n if (c &&\n c.startBlock <= startBlock &&\n (c.endBlock >= endBlock || skipEnd && c.nextEndBlock === endBlock)) {\n //console.log(\"Complete overlap\")\n const startOffset = startBlock - c.startBlock;\n const endOffset = endBlock - c.startBlock;\n return inflateBlocks(c.buffer, startOffset, endOffset)\n // Don't update cache, still valid\n } else {\n\n let buffer;\n if (!c || (c.startBlock > endBlock || c.endBlock < startBlock)) {\n // no overlap with cache\n buffer = await this.loadBLockData(startBlock, endBlock, {skipEnd});\n } else {\n\n //console.log(\"Some overlap\")\n const arrayBuffers = [];\n\n // Load blocks preceding cache start, if any\n if (startBlock < c.startBlock) {\n // load first blocks\n const startBuffer = await this.loadBLockData(startBlock, c.startBlock, {skipEnd: true});\n arrayBuffers.push(startBuffer);\n }\n\n // Slice cached buffer as needed\n let cachedBuffer;\n if (startBlock <= c.startBlock && endBlock >= c.endBlock) {\n cachedBuffer = c.buffer;\n } else {\n const start = Math.max(0, startBlock - c.startBlock);\n let end;\n if (endBlock >= c.endBlock) {\n end = c.buffer.byteLength;\n } else {\n // We need to find the byte position of the end of \"endBlock\"\n const boundaries = findBlockBoundaries(c.buffer);\n for (let i = 0; i < boundaries.length - 1; i++) {\n if (c.startBlock + boundaries[i] === endBlock) {\n end = boundaries[i + 1];\n break\n }\n }\n // Do something if end not found\n }\n cachedBuffer = c.buffer.slice(start, end);\n }\n arrayBuffers.push(cachedBuffer);\n\n // Load end blocks, if any\n if (endBlock > c.endBlock) {\n const endBuffer = await this.loadBLockData(c.endBlock, endBlock, {skipStart: true, skipEnd});\n arrayBuffers.push(endBuffer);\n }\n\n buffer = concatenateArrayBuffers(arrayBuffers);\n }\n\n // If skipEnd === true we need to find boundary of last block in cache\n let nextEndBlock = endBlock;\n if(skipEnd) {\n const boundaries = findBlockBoundaries(buffer);\n endBlock = boundaries[boundaries.length - 1];\n }\n\n this.cache = {startBlock, endBlock, nextEndBlock, buffer};\n return inflateBlocks(buffer)\n }\n }\n }\n\n async loadBLockData(startBlock, endBlock, options) {\n\n const config = this.config;\n const skipStart = options && options.skipStart;\n const skipEnd = options && options.skipEnd;\n\n // Get size of last block if not skipped\n let lastBlockSize = 0;\n if (!skipEnd) {\n const bsizeOptions = buildOptions(config, {range: {start: endBlock, size: 26}});\n const abuffer = await igvxhr.loadArrayBuffer(config.url, bsizeOptions);\n lastBlockSize = bgzBlockSize(abuffer);\n }\n\n if (skipStart) {\n const bsizeOptions = buildOptions(config, {range: {start: startBlock, size: 26}});\n const abuffer = await igvxhr.loadArrayBuffer(config.url, bsizeOptions);\n startBlock += bgzBlockSize(abuffer);\n }\n\n // Load data for all blocks\n const loadOptions = buildOptions(config, {\n range: {\n start: startBlock,\n size: endBlock + lastBlockSize - startBlock\n }\n });\n\n //console.log(`${this.config.name} Loaded ${startBlock} - ${endBlock + lastBlockSize} (${(endBlock + lastBlockSize - startBlock) / 1000} kb)`)\n\n return igvxhr.loadArrayBuffer(config.url, loadOptions)\n }\n}\n\nfunction findBlockBoundaries(arrayBuffer) {\n\n const byteLengh = arrayBuffer.byteLength;\n let offset = 0;\n const blockBoundaries = [0];\n while (offset < byteLengh) {\n //console.log(\"Cache block \" + offset)\n const ba = new Uint8Array(arrayBuffer, offset);\n const bsize = (ba[17] << 8 | ba[16]) + 1;\n offset += bsize;\n if (offset < byteLengh) {\n blockBoundaries.push(offset);\n }\n }\n return blockBoundaries\n}\n\n\n/**\n * Inflate compressed blocks within the data buffer*\n * @param data\n * @param startBlock - optional file location for start block. Default == 0\n * @param endBlock - optional file location for last block to decompress.\n * @returns {*[]}\n */\nfunction inflateBlocks(data, startBlock, endBlock) {\n\n startBlock = startBlock || 0;\n\n const oBlockList = [];\n let ptr = startBlock;\n\n const lim = data.byteLength - 18;\n while (ptr < lim) {\n try {\n //console.log(113873 + ptr)\n const header = new Uint8Array(data, ptr, 18);\n const xlen = (header[11] << 8) | (header[10]);\n const bsize = ((header[17] << 8) | (header[16])); // Total block size, including header, minus 1\n const start = 12 + xlen + ptr; // Start of CDATA\n const bytesLeft = data.byteLength - start;\n const cDataSize = bsize - xlen - 18;\n\n if (bytesLeft < cDataSize || cDataSize <= 0) {\n // This is unexpected. Throw error?\n break\n }\n\n const cdata = new Uint8Array(data, start, cDataSize);\n const unc = inflateRaw_1(cdata);\n oBlockList.push(unc);\n\n if (endBlock === ptr) {\n break\n } else {\n // Advance to next block\n ptr += bsize + 1;\n }\n\n } catch (e) {\n console.error(e);\n break\n }\n }\n return oBlockList\n}\n\n/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2014 Broad Institute\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\n/**\n * Reader for \"bed like\" files (tab delimited files with 1 feature per line: bed, gff, vcf, etc)\n *\n * @param config\n * @constructor\n */\nclass FeatureFileReader {\n\n constructor(config, genome) {\n\n var uriParts;\n\n this.config = config || {};\n this.genome = genome;\n this.indexURL = config.indexURL;\n this.indexed = config.indexed || this.indexURL !== undefined;\n this.queryable = this.indexed;\n\n if (isFile(this.config.url)) {\n this.filename = this.config.url.name;\n } else if (isDataURL(this.config.url)) {\n this.indexed = false; // by definition\n this.dataURI = config.url;\n } else {\n uriParts = parseUri(this.config.url);\n this.filename = config.filename || uriParts.file;\n }\n\n this.parser = this.getParser(this.config);\n\n if (this.config.format === \"vcf\" && !this.config.indexURL) {\n console.warn(\"Warning: index file not specified. The entire vcf file will be loaded.\");\n }\n\n }\n\n async defaultVisibilityWindow() {\n if (this.config.indexURL) {\n const index = await this.getIndex();\n if (index && index.lastBlockPosition) {\n let gl = 0;\n const s = 10000;\n for (let c of index.chromosomeNames) {\n const chromosome = this.genome.getChromosome(c);\n if (chromosome) {\n gl += chromosome.bpLength;\n }\n }\n return Math.round((gl / index.lastBlockPosition) * s)\n }\n }\n }\n\n /**\n * Return a promise to load features for the genomic interval\n * @param chr\n * @param start\n * @param end\n */\n async readFeatures(chr, start, end) {\n\n const index = await this.getIndex();\n if (index) {\n this.indexed = true;\n return this.loadFeaturesWithIndex(chr, start, end)\n } else if (this.dataURI) {\n this.indexed = false;\n return this.loadFeaturesFromDataURI()\n } else {\n this.indexed = false;\n return this.loadFeaturesNoIndex()\n }\n\n }\n\n async readHeader() {\n\n if (this.dataURI) {\n await this.loadFeaturesFromDataURI(this.dataURI);\n return this.header\n } else {\n\n if (this.config.indexURL) {\n const index = await this.getIndex();\n if (!index) {\n // Note - it should be impossible to get here\n throw new Error(\"Unable to load index: \" + this.config.indexURL)\n }\n\n let dataWrapper;\n if (index.tabix) {\n this._blockLoader = new BGZBlockLoader(this.config);\n dataWrapper = new BGZLineReader(this.config);\n } else {\n // Tribble\n const maxSize = Object.values(index.chrIndex)\n .flatMap(chr => chr.blocks)\n .map(block => block.max)\n .reduce((previous, current) =>\n Math.min(previous, current), Number.MAX_SAFE_INTEGER);\n\n const options = buildOptions(this.config, {bgz: index.tabix, range: {start: 0, size: maxSize}});\n const data = await igvxhr.loadString(this.config.url, options);\n dataWrapper = getDataWrapper(data);\n }\n\n\n this.header = await this.parser.parseHeader(dataWrapper); // Cache header, might be needed to parse features\n return this.header\n\n } else {\n // If this is a non-indexed file we will load all features in advance\n const options = buildOptions(this.config);\n const data = await igvxhr.loadString(this.config.url, options);\n let dataWrapper = getDataWrapper(data);\n this.header = await this.parser.parseHeader(dataWrapper);\n\n // Reset data wrapper and parse features\n dataWrapper = getDataWrapper(data);\n this.features = await this.parser.parseFeatures(dataWrapper); // cache features\n return this.header\n }\n }\n }\n\n\n getParser(config) {\n\n switch (config.format) {\n case \"vcf\":\n return new VcfParser(config)\n case \"seg\" :\n return new SegParser(\"seg\")\n case \"mut\":\n return new SegParser(\"mut\")\n case \"maf\":\n return new SegParser(\"maf\")\n case \"gwas\" :\n return new GWASParser(config)\n case \"aed\" :\n return new AEDParser(config)\n default:\n return new FeatureParser(config)\n }\n }\n\n async loadFeaturesNoIndex() {\n\n if (this.features) {\n // An optimization hack for non-indexed files, features are temporarily cached when header is read.\n const tmp = this.features;\n delete this.features;\n return tmp\n } else {\n const options = buildOptions(this.config); // Add oauth token, if any\n const data = await igvxhr.loadString(this.config.url, options);\n if (!this.header) {\n const dataWrapper = getDataWrapper(data);\n this.header = await this.parser.parseHeader(dataWrapper);\n }\n const dataWrapper = getDataWrapper(data);\n const features = await this.parser.parseFeatures(dataWrapper); // <= PARSING DONE HERE\n return features\n }\n }\n\n async loadFeaturesWithIndex(chr, start, end) {\n\n // insure that header has been loaded -- tabix _blockLoader is initialized as side effect\n if(!this.dataURI && !this.header) {\n await this.readHeader();\n }\n\n //console.log(\"Using index\"\n const config = this.config;\n const parser = this.parser;\n const tabix = this.index.tabix;\n const refId = tabix ? this.index.sequenceIndexMap[chr] : chr;\n if (refId === undefined) {\n return []\n }\n\n const genome = this.genome;\n const chunks = this.index.chunksForRange(refId, start, end);\n if (!chunks || chunks.length === 0) {\n return []\n } else {\n const allFeatures = [];\n for (let chunk of chunks) {\n\n let inflated;\n if (tabix) {\n inflated = await this._blockLoader.getData(chunk.minv, chunk.maxv);\n } else {\n const options = buildOptions(config, {\n range: {\n start: chunk.minv.block,\n size: chunk.maxv.block - chunk.minv.block + 1\n }\n });\n inflated = await igvxhr.loadString(config.url, options);\n }\n\n const slicedData = chunk.minv.offset ? inflated.slice(chunk.minv.offset) : inflated;\n const dataWrapper = getDataWrapper(slicedData);\n let slicedFeatures = await parser.parseFeatures(dataWrapper);\n\n // Filter psuedo-features (e.g. created mates for VCF SV records)\n slicedFeatures = slicedFeatures.filter(f => f._f === undefined);\n\n // Filter features not in requested range.\n let inInterval = false;\n for (let i = 0; i < slicedFeatures.length; i++) {\n const f = slicedFeatures[i];\n\n const canonicalChromosome = genome ? genome.getChromosomeName(f.chr) : f.chr;\n if (canonicalChromosome !== chr) {\n if (allFeatures.length === 0) {\n continue //adjacent chr to the left\n } else {\n break //adjacent chr to the right\n }\n }\n if (f.start > end) {\n allFeatures.push(f); // First feature beyond interval\n break\n }\n if (f.end >= start && f.start <= end) {\n if (!inInterval) {\n inInterval = true;\n if (i > 0) {\n allFeatures.push(slicedFeatures[i - 1]);\n }\n }\n allFeatures.push(f);\n }\n }\n\n }\n allFeatures.sort(function (a, b) {\n return a.start - b.start\n });\n\n return allFeatures\n }\n }\n\n async getIndex() {\n if (this.index) {\n return this.index\n } else if (this.config.indexURL) {\n this.index = await this.loadIndex();\n return this.index\n }\n }\n\n /**\n * Return a Promise for the async loaded index\n */\n async loadIndex() {\n const indexURL = this.config.indexURL;\n return loadIndex(indexURL, this.config, this.genome)\n }\n\n async loadFeaturesFromDataURI() {\n\n if (this.features) {\n // An optimization hack for non-indexed files, features are temporarily cached when header is read.\n const tmp = this.features;\n delete this.features;\n return tmp\n } else {\n const plain = decodeDataURI$1(this.dataURI);\n let dataWrapper = getDataWrapper(plain);\n this.header = await this.parser.parseHeader(dataWrapper);\n if (this.header instanceof String && this.header.startsWith(\"##gff-version 3\")) {\n this.format = 'gff3';\n }\n\n dataWrapper = getDataWrapper(plain);\n this.features = await this.parser.parseFeatures(dataWrapper);\n return this.features\n }\n }\n\n}\n\n/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2016 University of California San Diego\n * Author: Jim Robinson\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\nconst isString$1 = isString$2;\n\n\nclass CustomServiceReader {\n constructor(config) {\n this.config = config;\n }\n\n async readFeatures(chr, start, end) {\n\n let url;\n if (typeof this.config.url === 'function') {\n url = this.config.url({chr, start, end});\n } else {\n url = this.config.url\n .replace(\"$CHR\", chr)\n .replace(\"$START\", start)\n .replace(\"$END\", end);\n }\n\n let config = Object.assign({}, this.config);\n if (this.config.body !== undefined) {\n if (typeof this.config.body === 'function') {\n config.body = this.config.body({chr, start, end});\n } else {\n config.body =\n this.config.body\n .replace(\"$CHR\", chr)\n .replace(\"$START\", start)\n .replace(\"$END\", end);\n }\n }\n\n\n let features;\n const data = await igvxhr.load(url, config);\n if (data) {\n if (typeof this.config.parser === \"function\") {\n features = this.config.parser(data);\n } else if (isString$1(data)) {\n features = JSON.parse(data);\n } else {\n features = data;\n }\n }\n if (this.config.mappings) {\n let mappingKeys = Object.keys(this.config.mappings);\n for (let f of features) {\n for (let key of mappingKeys) {\n f[key] = f[this.config.mappings[key]];\n }\n }\n }\n return features\n }\n}\n\n/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2016-2017 The Regents of the University of California\n * Author: Jim Robinson\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\nconst UCSCServiceReader = function (config, genome) {\n this.config = config;\n this.genome = genome;\n this.expandQueryInterval = false;\n};\n\nUCSCServiceReader.prototype.readFeatures = function (chr, start, end) {\n\n const s = Math.max(0, Math.floor(start));\n let e = Math.ceil(end);\n\n if (this.genome) {\n const c = this.genome.getChromosome(chr);\n if (c && e > c.bpLength) {\n e = c.bpLength;\n }\n }\n\n\n const url = this.config.url + '?db=' + this.config.db + '&table=' + this.config.tableName + '&chr=' + chr + '&start=' + s + '&end=' + e;\n\n return igvxhr.loadJson(url, this.config)\n .then(function (data) {\n if (data) {\n data.forEach(function (sample) {\n if (sample.hasOwnProperty('exonStarts') &&\n sample.hasOwnProperty('exonEnds') &&\n sample.hasOwnProperty('exonCount') &&\n sample.hasOwnProperty('cdsStart') &&\n sample.hasOwnProperty('cdsEnd')) {\n addExons(sample);\n }\n });\n return data\n } else {\n return null\n }\n })\n};\n\nfunction addExons(sample) {\n var exonCount, exonStarts, exonEnds, exons, eStart, eEnd;\n exonCount = sample['exonCount'];\n exonStarts = sample['exonStarts'].split(',');\n exonEnds = sample['exonEnds'].split(',');\n exons = [];\n\n for (var i = 0; i < exonCount; i++) {\n eStart = parseInt(exonStarts[i]);\n eEnd = parseInt(exonEnds[i]);\n var exon = {start: eStart, end: eEnd};\n\n if (sample.cdsStart > eEnd || sample.cdsEnd < sample.cdsStart) exon.utr = true; // Entire exon is UTR\n if (sample.cdsStart >= eStart && sample.cdsStart <= eEnd) exon.cdStart = sample.cdsStart;\n if (sample.cdsEnd >= eStart && sample.cdsEnd <= eEnd) exon.cdEnd = sample.cdsEnd;\n\n exons.push(exon);\n }\n\n sample.exons = exons;\n}\n\n/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2021 University of California San Diego\n * Author: Jim Robinson\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\nconst gffNameFields = [\"Name\", \"gene_name\", \"gene\", \"gene_id\", \"alias\", \"locus\", \"name\"];\n\nclass GFFHelper {\n\n constructor(options) {\n this.format = options.format;\n this.nameField = options.nameField;\n this.filterTypes = options.filterTypes === undefined ?\n new Set(['chromosome']) :\n new Set(options.filterTypes);\n }\n\n combineFeatures(features, genomicInterval) {\n\n let combinedFeatures;\n\n const filterTypes = this.filterTypes;\n features = features.filter(f => filterTypes === undefined || !filterTypes.has(f.type));\n\n if (\"gff3\" === this.format) {\n const tmp = this.combineFeaturesById(features);\n combinedFeatures = this.combineFeaturesByType(tmp);\n } else {\n combinedFeatures = this.combineFeaturesByType(features);\n }\n combinedFeatures.sort(function (a, b) {\n return a.start - b.start\n });\n this.numberExons(combinedFeatures, genomicInterval);\n this.nameFeatures(combinedFeatures);\n return combinedFeatures\n }\n\n /**\n * Combine multiple non-transcript model features with the same ID on the same chromosome into a single feature.\n * Features that are part of the transcript model (e.g. exon, mRNA, etc) are combined later.\n *\n * @param features\n * @returns {[]}\n */\n combineFeaturesById(features) {\n\n const chrIdMap = new Map();\n const combinedFeatures = [];\n\n for (let f of features) {\n if (isTranscriptPart(f.type) || isTranscript(f.type) || !f.id) {\n combinedFeatures.push(f);\n } else {\n let idMap = chrIdMap.get(f.chr);\n if (!idMap) {\n idMap = new Map();\n chrIdMap.set(f.chr, idMap);\n }\n\n let featureArray = idMap.get(f.id);\n if (featureArray) {\n featureArray.push(f);\n } else {\n idMap.set(f.id, [f]);\n }\n }\n }\n\n for (let idMap of chrIdMap.values()) {\n for (let featureArray of idMap.values()) {\n if (featureArray.length > 1) {\n // Use the first feature as prototypical (for column 9 attributes), and adjust start/end\n // Parts are represented as \"exons\", as that is how they are presented visually\n const cf = featureArray[0];\n cf.exons = [];\n for (let f of featureArray) {\n cf.start = Math.min(cf.start, f.start);\n cf.end = Math.max(cf.end, f.end);\n cf.exons.push({\n start: f.start,\n end: f.end\n });\n }\n combinedFeatures.push(cf);\n } else {\n combinedFeatures.push(featureArray[0]);\n }\n }\n }\n\n return combinedFeatures\n }\n\n combineFeaturesByType(features) {\n\n // Build dictionary of genes\n const genes = features.filter(f => \"gene\" === f.type || f.type.endsWith(\"_gene\"));\n const geneMap = Object.create(null);\n for (let g of genes) {\n geneMap[g.id] = g;\n }\n\n // 1. Build dictionary of transcripts\n const transcripts = Object.create(null);\n const combinedFeatures = [];\n const consumedFeatures = new Set();\n const filterTypes = this.filterTypes;\n\n features = features.filter(f => filterTypes === undefined || !filterTypes.has(f.type));\n\n for (let f of features) {\n\n if (f.type === \"biological_region\") {\n console.log();\n }\n\n if (isTranscript(f.type)) {\n const transcriptId = f.id; // getAttribute(f.attributeString, \"transcript_id\", /\\s+/);\n if (undefined !== transcriptId) {\n const gffTranscript = new GFFTranscript(f);\n transcripts[transcriptId] = gffTranscript;\n combinedFeatures.push(gffTranscript);\n consumedFeatures.add(f);\n const g = geneMap[f.parent];\n if (g) {\n gffTranscript.geneObject = g;\n consumedFeatures.add(g);\n }\n }\n }\n }\n\n // Add exons and transcript parts\n for (let f of features) {\n if (isTranscriptPart(f.type)) {\n const parents = getParents(f);\n if (parents) {\n for (let id of parents) {\n\n let transcript = transcripts[id];\n if (!transcript && this.format === \"gtf\") {\n // GTF does not require explicit transcript record, start one with this feature.\n const psuedoTranscript = Object.assign({}, f);\n psuedoTranscript.type = \"transcript\";\n transcript = new GFFTranscript(psuedoTranscript);\n transcripts[id] = transcript;\n combinedFeatures.push(transcript);\n }\n if (transcript !== undefined) {\n\n if (isExon(f.type)) {\n if (parents.length > 1) {\n // Make a copy as exon can be modified differently by CDS, etc, for each transcript\n const e2 = new GFFFeature(f);\n transcript.addExon(e2);\n } else {\n transcript.addExon(f);\n }\n } else {\n transcript.addPart(f);\n }\n consumedFeatures.add(f);\n }\n }\n }\n }\n }\n\n // Finish transcripts\n combinedFeatures.forEach(function (f) {\n if (typeof f.finish === \"function\") {\n f.finish();\n }\n });\n\n // Add other features\n const others = features.filter(f => !consumedFeatures.has(f));\n for (let f of others) {\n combinedFeatures.push(f);\n }\n\n return combinedFeatures\n\n function getParents(f) {\n if (f.parent && f.parent.trim() !== \"\") {\n return f.parent.trim().split(\",\")\n } else {\n return null\n }\n }\n }\n\n numberExons(features, genomicInterval) {\n\n for (let f of features) {\n if (f.exons &&\n (!genomicInterval ||\n (f.end <= genomicInterval.end && f.start > genomicInterval.start))) {\n for (let i = 0; i < f.exons.length; i++) {\n const exon = f.exons[i];\n exon.number = f.strand === \"-\" ? f.exons.length - i : i + 1;\n }\n }\n }\n }\n\n nameFeatures(features) {\n // Find name (label) property\n for (let f of features) {\n if (f.attributeString) {\n const delim = ('gff3' === this.format) ? '=' : ' ';\n const attributes = parseAttributeString(f.attributeString, delim);\n const attributesMap = new Map(attributes);\n if (this.nameField) {\n f.name = attributesMap.get(this.nameField);\n } else {\n for (let nameField of gffNameFields) {\n if (attributesMap.has(nameField)) {\n f.name = attributesMap.get(nameField);\n break\n }\n }\n }\n }\n }\n }\n}\n\n/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2015 UC San Diego\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\nconst GtexReader = function (config) {\n\n this.config = config;\n this.url = config.url;\n this.tissueId = config.tissueSiteDetailId;\n this.indexed = true;\n this.datasetId = config.datasetId || \"gtex_v8\";\n};\n\nGtexReader.prototype.readFeatures = async function (chr, bpStart, bpEnd) {\n\n\n let self = this,\n queryChr = chr.startsWith(\"chr\") ? chr : \"chr\" + chr,\n queryStart = Math.floor(bpStart),\n queryEnd = Math.ceil(bpEnd),\n datasetId = this.datasetId,\n queryURL = this.url + \"?chromosome=\" + queryChr + \"&start=\" + queryStart + \"&end=\" + queryEnd +\n \"&tissueSiteDetailId=\" + this.tissueId + \"&datasetId=\" + datasetId;\n\n const json = await igvxhr.loadJson(queryURL, {\n withCredentials: self.config.withCredentials\n });\n if (json && json.singleTissueEqtl) {\n //variants = json.variants;\n //variants.sort(function (a, b) {\n // return a.POS - b.POS;\n //});\n //source.cache = new FeatureCache(chr, queryStart, queryEnd, variants);\n\n json.singleTissueEqtl.forEach(function (eqtl) {\n eqtl.chr = eqtl.chromosome;\n eqtl.position = eqtl.pos;\n eqtl.start = eqtl.pos - 1;\n eqtl.end = eqtl.start + 1;\n eqtl.snp = eqtl.snpId;\n eqtl.geneName = eqtl.geneSymbol;\n eqtl.geneId = eqtl.gencodeId;\n\n });\n\n return json.singleTissueEqtl\n } else {\n return undefined\n }\n};\n\n/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2014 Broad Institute\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\n// Experimental class for fetching features from an mpg webservice.\n// http://immvar.broadinstitute.org:3000/load_data?chromosome=&start=&end=&categories=\n\nconst ImmVarReader = function (config) {\n\n this.config = config;\n this.url = config.url;\n this.cellConditionId = config.cellConditionId;\n this.valueThreshold = config.valueThreshold ? config.valueThreshold : 5E-2;\n\n};\n\nImmVarReader.prototype.readFeatures = function (queryChr, queryStart, queryEnd) {\n\n var self = this,\n queryURL = this.url + \"?chromosome=\" + queryChr + \"&start=\" + queryStart + \"&end=\" + queryEnd +\n \"&cell_condition_id=\" + this.cellConditionId;\n\n return new Promise(function (fulfill, reject) {\n igvxhr.loadJson(queryURL, {\n withCredentials: self.config.withCredentials\n }).then(function (json) {\n\n if (json) {\n //variants = json.variants;\n //variants.sort(function (a, b) {\n // return a.POS - b.POS;\n //});\n //source.cache = new FeatureCache(chr, queryStart, queryEnd, variants);\n\n json.eqtls.forEach(function (eqtl) {\n eqtl.chr = eqtl.chromosome;\n eqtl.start = eqtl.position;\n eqtl.end = eqtl.position + 1;\n });\n\n fulfill(json.eqtls);\n } else {\n fulfill(null);\n }\n\n }).catch(function (error) {\n reject(error);\n });\n\n })\n};\n\n/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2014 Broad Institute\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\nconst apiKey = igvxhr.apiKey;\n\nfunction ga4ghGet(options) {\n var url = options.url + \"/\" + options.entity + \"/\" + options.entityId;\n options.headers = ga4ghHeaders();\n return igvxhr.loadJson(url, options) // Returns a promise\n}\n\nfunction ga4ghSearch(options) {\n\n return new Promise(function (fulfill, reject) {\n var results = options.results ? options.results : [],\n url = options.url,\n body = options.body,\n decode = options.decode,\n paramSeparator = \"?\",\n fields = options.fields; // Partial response\n\n\n if (apiKey) {\n url = url + paramSeparator + \"key=\" + apiKey;\n paramSeparator = \"&\";\n }\n\n if (fields) {\n url = url + paramSeparator + \"fields=\" + fields;\n }\n\n\n // Start the recursive load cycle. Data is fetched in chunks, if more data is available a \"nextPageToken\" is returned.\n return loadChunk()\n\n function loadChunk(pageToken) {\n\n if (pageToken) {\n body.pageToken = pageToken;\n } else {\n if (body.pageToken !== undefined) delete body.pageToken; // Remove previous page token, if any\n }\n\n var sendData = JSON.stringify(body);\n\n igvxhr.loadJson(url, {\n sendData: sendData,\n contentType: \"application/json\",\n headers: ga4ghHeaders(),\n // oauthToken: ga4ghToken()\n })\n .then(function (json) {\n var nextPageToken, tmp;\n\n if (json) {\n\n tmp = decode ? decode(json) : json;\n\n if (tmp) {\n\n tmp.forEach(function (a) {\n {\n results.push(a);\n }\n });\n }\n\n\n nextPageToken = json[\"nextPageToken\"];\n\n if (nextPageToken) {\n loadChunk(nextPageToken);\n } else {\n fulfill(results);\n }\n } else {\n fulfill(results);\n }\n\n })\n .catch(function (error) {\n reject(error);\n });\n }\n\n })\n\n\n}\n\nfunction ga4ghHeaders() {\n return {\n \"Cache-Control\": \"no-cache\"\n }\n}\n\n/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2014 Broad Institute\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\nconst Ga4ghVariantReader = function (config, genome) {\n\n this.config = config;\n this.genome = genome;\n this.url = config.url;\n this.variantSetId = config.variantSetId;\n this.callSetIds = config.callSetIds;\n this.includeCalls = (config.includeCalls === undefined ? true : config.includeCalls);\n\n};\n\n// Simulate a VCF file header\nGa4ghVariantReader.prototype.readHeader = function () {\n\n var self = this;\n\n\n if (self.header) {\n return Promise.resolve(self.header)\n } else {\n\n self.header = {};\n\n if (self.includeCalls === false) {\n return Promise.resolve(self.header)\n } else {\n\n var readURL = self.url + \"/callsets/search\";\n\n return ga4ghSearch({\n url: readURL,\n fields: \"nextPageToken,callSets(id,name)\",\n body: {\n \"variantSetIds\": (Array.isArray(self.variantSetId) ? self.variantSetId : [self.variantSetId]),\n \"pageSize\": \"10000\"\n },\n decode: function (json) {\n // If specific callSetIds are specified filter to those\n if (self.callSetIds) {\n var callSets = [],\n csIdSet = new Set();\n\n self.callSetIds.forEach(function (csid) {\n csIdSet.add(csid);\n });\n\n json.callSets.forEach(function (cs) {\n if (csIdSet.has(cs.id)) {\n callSets.push(cs);\n }\n });\n return callSets\n } else {\n return json.callSets\n }\n }\n })\n .then(function (callSets) {\n self.header.callSets = callSets;\n return self.header\n })\n }\n }\n};\n\n\nGa4ghVariantReader.prototype.readFeatures = function (chr, bpStart, bpEnd) {\n\n const self = this;\n const genome = this.genome;\n\n return self.readHeader()\n\n .then(function (header) {\n return getChrAliasTable()\n })\n\n .then(function (chrAliasTable) {\n\n var queryChr = chrAliasTable.hasOwnProperty(chr) ? chrAliasTable[chr] : chr,\n readURL = self.url + \"/variants/search\";\n\n return ga4ghSearch({\n url: readURL,\n fields: (self.includeCalls ? undefined : \"nextPageToken,variants(id,variantSetId,names,referenceName,start,end,referenceBases,alternateBases,quality,filter,info)\"),\n body: {\n \"variantSetIds\": (Array.isArray(self.variantSetId) ? self.variantSetId : [self.variantSetId]),\n \"callSetIds\": (self.callSetIds ? self.callSetIds : undefined),\n \"referenceName\": queryChr,\n \"start\": bpStart.toString(),\n \"end\": bpEnd.toString(),\n \"pageSize\": \"10000\"\n },\n decode: function (json) {\n\n var v;\n\n var variants = [];\n\n json.variants.forEach(function (json) {\n\n v = createGAVariant(json);\n\n if (!v.isRefBlock()) {\n variants.push(v);\n }\n });\n\n return variants\n }\n })\n })\n\n\n function getChrAliasTable() {\n\n return new Promise(function (fulfill, reject) {\n\n if (self.chrAliasTable) {\n fulfill(self.chrAliasTable);\n } else {\n self.readMetadata().then(function (json) {\n\n self.metadata = json.metadata;\n self.chrAliasTable = {};\n\n if (json.referenceBounds && genome) {\n\n json.referenceBounds.forEach(function (rb) {\n var refName = rb.referenceName,\n alias = genome.getChromosomeName(refName);\n self.chrAliasTable[alias] = refName;\n\n });\n }\n fulfill(self.chrAliasTable);\n\n });\n }\n\n })\n }\n\n};\n\n\nGa4ghVariantReader.prototype.readMetadata = function () {\n\n return ga4ghGet({\n url: this.url,\n entity: \"variantsets\",\n entityId: this.variantSetId\n })\n};\n\nclass CivicReader {\n\n constructor(config) {\n this.config = config;\n }\n\n async readFeatures(chr, start, end) {\n\n const json = await igvxhr.loadJson(this.config.url + \"/variants/?count=50000\");\n const records = json.records;\n const features = [];\n\n for (let record of records) {\n\n if (record.coordinates) {\n\n record.id;\n const coordinates = record.coordinates;\n\n if (coordinates.chromosome) {\n features.push(\n new CivicVariant(\n coordinates.chromosome,\n coordinates.start - 1, // UCSC 0 convention\n coordinates.stop,\n record\n ));\n }\n\n if (coordinates.chromosome2) {\n features.push(\n new CivicVariant(\n coordinates.chromosome2,\n coordinates.start2 - 1, // UCSC 0 convention\n coordinates.stop2,\n record\n ));\n }\n }\n\n }\n return features\n\n }\n}\n\nclass CivicVariant {\n\n constructor(chr, start, end, record) {\n this.chr = chr;\n this.start = start;\n this.end = end;\n this.id = record.id;\n this.entrezName = record.entrez_name;\n this.name = record.name;\n this.actionabilityScore = record.civic_actionability_score;\n\n if (record.coordinates.reference_bases) {\n this.refBases = record.coordinates.reference_bases;\n }\n if (record.coordinates.variant_bases) {\n this.altBases = record.coordinates.variant_bases;\n }\n if (record.variant_types) {\n this.variant_types = record.variant_types;\n }\n\n this.locationString = (this.chr + \":\" +\n numberFormatter$1(this.start + 1) + \"-\" +\n numberFormatter$1(this.end));\n\n // Color based on actionability score\n if (this.actionabilityScore !== undefined) {\n let alpha;\n if (this.actionabilityScore <= 10) {\n alpha = 0.2;\n } else {\n const v = Math.min(30, this.actionabilityScore);\n alpha = 0.2 + 0.8 * Math.log10((v - 10) / 2);\n }\n this.alpha = alpha;\n }\n\n\n }\n\n popupData() {\n\n\n const link = createLink(\"CIViC\", \"https://civicdb.org/links/variants/\" + this.id);\n this.refBases !== this.altBases &&\n this.refBases && this.refBases.length === 1 &&\n this.altBases && this.altBases.length === 1;\n\n\n const pd = [link];\n pd.push({\n name: \"Entrez\",\n value: createLink(this.entrezName, \"https://ghr.nlm.nih.gov/gene/\" + this.entrezName)\n });\n pd.push({name: \"Name\", value: this.name});\n\n if (this.variant_types && this.variant_types.length > 0) {\n\n const name = this.variant_types.length === 1 ? \"Type\" : \"Types\";\n let typeString;\n for (let vt of this.variant_types) {\n if (!typeString) typeString = vt.display_name;\n else typeString += \", \" + vt.display_name;\n }\n\n pd.push({name: name, value: typeString});\n }\n\n pd.push({name: \"Actionability\", value: this.actionabilityScore});\n\n\n pd.push({name: \"Location\", value: this.locationString});\n\n return pd\n\n\n function createLink(text, href) {\n return \"\" + text + \"\"\n }\n\n }\n}\n\n/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2016-2017 The Regents of the University of California\n * Author: Jim Robinson\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\nclass HtsgetReader {\n\n constructor(config, genome) {\n this.config = config;\n this.genome = genome;\n this.format = config.format ? config.format.toUpperCase() : \"BAM\"; // Backward compatibility\n if (!(this.format === \"BAM\" || this.format === \"VCF\")) {\n throw Error(`htsget format ${config.format} is not supported`)\n }\n }\n\n async readHeaderData() {\n const url = `${getUrl(this.config)}?class=header&format=${this.format}`;\n const ticket = await igvxhr.loadJson(url, buildOptions(this.config));\n return await this.loadUrls(ticket.htsget.urls)\n }\n\n async readData(chr, start, end) {\n const url = `${getUrl(this.config)}?format=${this.format}&referenceName=${chr}&start=${Math.floor(start)}&end=${Math.ceil(end)}`;\n const ticket = await igvxhr.loadJson(url, buildOptions(this.config));\n return this.loadUrls(ticket.htsget.urls)\n }\n\n async loadUrls(urls) {\n\n const promiseArray = [];\n for (let urlData of urls) {\n\n if (urlData.url.startsWith('data:')) {\n // this is a data-uri\n promiseArray.push(Promise.resolve(dataUriToBytes(urlData.url)));\n\n } else {\n\n const options = buildOptions(this.config || {});\n\n if (urlData.headers) {\n options.headers = Object.assign(options.headers || {}, urlData.headers);\n }\n\n promiseArray.push(igvxhr.loadArrayBuffer(urlData.url, options));\n }\n }\n const arrayBuffers = await Promise.all(promiseArray);\n return concatArrays(arrayBuffers)\n }\n\n\n static async inferFormat(config) {\n try {\n const url = getUrl(config);\n const headerURL = `${url}${url.includes(\"?\") ? \"&\" : \"?\"}class=header`;\n const ticket = await igvxhr.loadJson(headerURL, buildOptions(config));\n if (ticket.htsget) {\n const format = ticket.htsget.format;\n if (!(format === \"BAM\" || format === \"VCF\")) {\n throw Error(`htsget format ${format} is not supported`)\n }\n config.format = format.toLowerCase();\n config.sourceType = \"htsget\";\n if (!config.name) {\n config.name = await getFilename$1(config.url);\n }\n }\n } catch (e) {\n // Errors => this is not an htsget source, not an application error. Ignore\n }\n }\n}\n\n/**\n * Extract the full url from the config. Striving for backward compatibility, \"endpoint\" and \"id\" are deprecated.\n *\n * @param config\n */\nfunction getUrl(config) {\n if (config.url && config.endpoint && config.id) {\n return config.url + config.endpoint + config.id // Deprecated\n } else if (config.endpoint && config.id) {\n return config.endpoint + config.id // Deprecated\n } else if (config.url) {\n if (config.url.startsWith(\"htsget://\")) {\n return config.url.replace(\"htsget://\", \"https://\") // htsget -> http not supported\n } else {\n return config.url\n }\n } else {\n throw Error(\"Must specify either 'url', or 'endpoint' and 'id\")\n }\n\n\n}\n\n/**\n * Concatenate a list of array buffers, returning an UInt8Array\n * @param arrayBuffers\n */\nfunction concatArrays(arrayBuffers) {\n\n let len = 0;\n for (let a of arrayBuffers) {\n len += a.byteLength;\n }\n\n let offset = 0;\n const newArray = new Uint8Array(len);\n for (let buf of arrayBuffers) {\n const a = new Uint8Array(buf);\n newArray.set(a, offset);\n offset += a.length;\n }\n\n return newArray\n}\n\nfunction dataUriToBytes(dataUri) {\n\n const split = dataUri.split(',');\n const info = split[0].split(':')[1];\n let dataString = split[1];\n\n if (info.indexOf('base64') >= 0) {\n dataString = atob(dataString);\n } else {\n dataString = decodeURI(dataString);\n }\n\n const bytes = new Uint8Array(dataString.length);\n for (var i = 0; i < dataString.length; i++) {\n bytes[i] = dataString.charCodeAt(i);\n }\n\n return bytes\n}\n\n/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2016-2017 The Regents of the University of California\n * Author: Jim Robinson\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\nclass HtsgetVariantReader extends HtsgetReader {\n\n constructor(config, genome) {\n super(config, genome);\n this.parser = new VcfParser();\n }\n\n async readHeader() {\n if (!this.header) {\n const data = await this.readHeaderData();\n const dataWrapper = getDataWrapper(data);\n this.header = await this.parser.parseHeader(dataWrapper, this.genome);\n this.chrAliasTable = this.header.chrAliasTable;\n }\n return this.header\n }\n\n async readFeatures(chr, start, end) {\n\n if (this.config.format && this.config.format.toUpperCase() !== \"VCF\") {\n throw Error(`htsget format ${this.config.format} is not supported`)\n }\n\n if (!this.chrAliasTable) {\n await this.readHeader();\n }\n\n let queryChr = this.chrAliasTable.has(chr) ? this.chrAliasTable.get(chr) : chr;\n\n const data = await this.readData(queryChr, start, end);\n\n const dataWrapper = getDataWrapper(data);\n\n return this.parser.parseFeatures(dataWrapper)\n\n // return dataWrapper;\n\n }\n\n}\n\n// Assigns a row # to each feature. If the feature does not fit in any row and #rows == maxRows no\n// row number is assigned.\nfunction pack(featureList, maxRows) {\n\n maxRows = maxRows || Number.MAX_SAFE_INTEGER;\n const rows = [];\n featureList.sort(function (a, b) {\n return a.start - b.start\n });\n rows.push(-1000);\n\n for (let feature of featureList) {\n let r = 0;\n const len = Math.min(rows.length, maxRows);\n for (r = 0; r < len; r++) {\n if (feature.start >= rows[r]) {\n feature.row = r;\n rows[r] = feature.end;\n break\n }\n }\n feature.row = r;\n rows[r] = feature.end;\n }\n}\n\nconst DEFAULT_MAX_WG_COUNT$1 = 10000;\n\n/**\n * Return a collection of \"whole genome\" features wrapping the supplied features, possibly downsampled. The purpose\n * is to support painting features in \"whole genome view\".\n *\n * @param allFeatures - dictionary (object), keys are chromosome names, values are lists of features\n * @param genome\n * @param maxWGCount - optional, maximum # of whole genome features to computer\n * @returns {*[]}\n */\nfunction computeWGFeatures(allFeatures, genome, maxWGCount) {\n\n const max = maxWGCount || DEFAULT_MAX_WG_COUNT$1;\n\n const makeWGFeature = (f) => {\n const wg = Object.assign({}, f);\n wg.chr = \"all\";\n wg.start = genome.getGenomeCoordinate(f.chr, f.start);\n wg.end = genome.getGenomeCoordinate(f.chr, f.end);\n wg._f = f;\n // Don't draw exons in whole genome view\n if (wg[\"exons\"]) delete wg[\"exons\"];\n return wg\n };\n\n const wgChromosomeNames = new Set(genome.wgChromosomeNames);\n const wgFeatures = [];\n let count = 0;\n for (let c of genome.wgChromosomeNames) {\n\n if(Array.isArray(allFeatures)) {\n const featureDict = {};\n for(let f of allFeatures) {\n const chr = genome.getChromosomeName(f.chr);\n if(!featureDict.hasOwnProperty(chr)) {\n featureDict[chr] = [];\n }\n featureDict[chr].push(f);\n }\n allFeatures = featureDict;\n }\n\n const features = allFeatures[c];\n\n if (features) {\n for (let f of features) {\n let queryChr = genome.getChromosomeName(f.chr);\n if (wgChromosomeNames.has(queryChr)) {\n if (wgFeatures.length < max) {\n wgFeatures.push(makeWGFeature(f));\n } else {\n //Reservoir sampling\n const samplingProb = max / (count + 1);\n if (Math.random() < samplingProb) {\n const idx = Math.floor(Math.random() * (max - 1));\n wgFeatures[idx] = makeWGFeature(f);\n }\n }\n }\n count++;\n }\n }\n }\n\n wgFeatures.sort(function (a, b) {\n return a.start - b.start\n });\n\n return wgFeatures\n}\n\nfunction packFeatures(features, maxRows) {\n\n maxRows = maxRows || 1000;\n if (features == null || features.length === 0) {\n return\n }\n // Segregate by chromosome\n const chrFeatureMap = {};\n const chrs = [];\n for (let feature of features) {\n const chr = feature.chr;\n let flist = chrFeatureMap[chr];\n if (!flist) {\n flist = [];\n chrFeatureMap[chr] = flist;\n chrs.push(chr);\n }\n flist.push(feature);\n }\n\n // Loop through chrosomosomes and pack features;\n for (let chr of chrs) {\n pack(chrFeatureMap[chr], maxRows);\n }\n}\n\n/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2014-2015 Broad Institute\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\nconst DEFAULT_MAX_WG_COUNT = 10000;\n\n/**\n * feature source for \"bed like\" files (tab or whitespace delimited files with 1 feature per line: bed, gff, vcf, etc)\n *\n * @param config\n * @constructor\n */\nclass TextFeatureSource {\n\n constructor(config, genome) {\n\n this.config = config || {};\n this.genome = genome;\n this.sourceType = (config.sourceType === undefined ? \"file\" : config.sourceType);\n this.maxWGCount = config.maxWGCount || DEFAULT_MAX_WG_COUNT;\n\n const queryableFormats = new Set([\"bigwig\", \"bw\", \"bigbed\", \"bb\", \"biginteract\", \"biggenepred\", \"bignarrowpeak\", \"tdf\"]);\n\n this.queryable = config.indexURL || config.queryable === true; // False by default, unless explicitly set\n if (config.reader) {\n // Explicit reader implementation\n this.reader = config.reader;\n this.queryable = config.queryable !== false;\n } else if (config.sourceType === \"ga4gh\") {\n this.reader = new Ga4ghVariantReader(config, genome);\n this.queryable = true;\n } else if (config.sourceType === \"immvar\") {\n this.reader = new ImmVarReader(config);\n this.queryable = true;\n } else if (config.type === \"eqtl\" && config.sourceType === \"gtex-ws\") {\n this.reader = new GtexReader(config);\n this.queryable = true;\n } else if (\"htsget\" === config.sourceType) {\n this.reader = new HtsgetVariantReader(config, genome);\n this.queryable = true;\n } else if (config.sourceType === 'ucscservice') {\n this.reader = new UCSCServiceReader(config.source);\n this.queryable = true;\n } else if (config.sourceType === 'custom') {\n this.reader = new CustomServiceReader(config.source);\n this.queryable = false !== config.source.queryable;\n } else if (\"civic-ws\" === config.sourceType) {\n this.reader = new CivicReader(config);\n this.queryable = false;\n } else {\n // File of some type (i.e. not a webservice)\n this.reader = new FeatureFileReader(config, genome);\n if (config.queryable !== undefined) {\n this.queryable = config.queryable;\n } else if (queryableFormats.has(config.format) || this.reader.indexed) {\n this.queryable = true;\n } else ;\n }\n\n // Set searchable unless explicitly turned off, or track uses in indexed or otherwise queryable\n // feature source. queryable => features loaded on demand (by query)\n this.searchable = config.searchable === true || config.searchableFields || (config.searchable !== false && !this.queryable);\n\n }\n\n async defaultVisibilityWindow() {\n if (this.reader && typeof this.reader.defaultVisibilityWindow === 'function') {\n return this.reader.defaultVisibilityWindow()\n }\n }\n\n async trackType() {\n const header = await this.getHeader();\n if (header) {\n return header.type\n } else {\n return undefined // Convention for unknown or unspecified\n }\n }\n\n async getHeader() {\n if (!this.header) {\n\n if (this.reader && typeof this.reader.readHeader === \"function\") {\n const header = await this.reader.readHeader();\n if (header) {\n this.header = header;\n if (header.format) {\n this.config.format = header.format;\n }\n } else {\n this.header = {};\n }\n } else {\n this.header = {};\n }\n }\n return this.header\n }\n\n /**\n * Required function for all data source objects. Fetches features for the\n * range requested.\n *\n * This function is quite complex due to the variety of reader types backing it, some indexed, some queryable,\n * some not.\n *\n * @param chr\n * @param start\n * @param end\n * @param bpPerPixel\n */\n async getFeatures({chr, start, end, bpPerPixel, visibilityWindow}) {\n\n const genome = this.genome;\n const queryChr = genome ? genome.getChromosomeName(chr) : chr;\n const isWholeGenome = (\"all\" === queryChr.toLowerCase());\n\n // Various conditions that can require a feature load\n // * view is \"whole genome\" but no features are loaded\n // * cache is disabled\n // * cache does not contain requested range\n // const containsRange = this.featureCache.containsRange(new GenomicInterval(queryChr, start, end))\n if ((isWholeGenome && !this.wgFeatures && this.supportsWholeGenome()) ||\n this.config.disableCache ||\n !this.featureCache ||\n !this.featureCache.containsRange(new GenomicInterval(queryChr, start, end))) {\n await this.loadFeatures(queryChr, start, end, visibilityWindow);\n }\n\n if (isWholeGenome) {\n if (!this.wgFeatures) {\n if (this.supportsWholeGenome()) {\n this.wgFeatures = computeWGFeatures(this.featureCache.getAllFeatures(), this.genome, this.maxWGCount);\n } else {\n this.wgFeatures = [];\n }\n }\n return this.wgFeatures\n } else {\n return this.featureCache.queryFeatures(queryChr, start, end)\n }\n }\n\n supportsWholeGenome() {\n return !this.queryable // queryable (indexed, web services) sources don't support whole genome view\n }\n\n // TODO -- experimental, will only work for non-indexed sources\n getAllFeatures() {\n if (this.queryable || !this.featureCache) { // queryable sources don't support all features\n return []\n } else {\n return this.featureCache.getAllFeatures()\n }\n }\n\n\n async loadFeatures(queryChr, start, end, visibilityWindow) {\n\n const reader = this.reader;\n let intervalStart = start;\n let intervalEnd = end;\n\n // Use visibility window to potentially expand query interval.\n // This can save re-queries as we zoom out. Visibility window <= 0 is a special case\n // indicating whole chromosome should be read at once.\n if ((!visibilityWindow || visibilityWindow <= 0) && this.config.expandQuery !== false) {\n // Whole chromosome\n const chromosome = this.genome ? this.genome.getChromosome(queryChr) : undefined;\n intervalStart = 0;\n intervalEnd = Math.max(chromosome ? chromosome.bpLength : Number.MAX_SAFE_INTEGER, end);\n } else if (visibilityWindow > (end - start) && this.config.expandQuery !== false) {\n const expansionWindow = Math.min(4.1 * (end - start), visibilityWindow);\n intervalStart = Math.max(0, (start + end) / 2 - expansionWindow);\n intervalEnd = start + expansionWindow;\n }\n\n let features = await reader.readFeatures(queryChr, intervalStart, intervalEnd);\n if (this.queryable === undefined) {\n this.queryable = reader.indexed;\n }\n\n const genomicInterval = this.queryable ?\n new GenomicInterval(queryChr, intervalStart, intervalEnd) :\n undefined;\n\n if (features) {\n\n if (this.config.assembleGFF !== false &&\n (\"gtf\" === this.config.format || \"gff3\" === this.config.format || \"gff\" === this.config.format)) {\n features = (new GFFHelper(this.config)).combineFeatures(features, genomicInterval);\n }\n\n // Assign overlapping features to rows\n if (this.config.format !== \"wig\" && this.config.type !== \"junctions\") {\n const maxRows = this.config.maxRows || Number.MAX_SAFE_INTEGER;\n packFeatures(features, maxRows);\n }\n\n // Note - replacing previous cache with new one. genomicInterval is optional (might be undefined => includes all features)\n this.featureCache = new FeatureCache$1(features, this.genome, genomicInterval);\n\n // If track is marked \"searchable\"< cache features by name -- use this with caution, memory intensive\n if (this.searchable) {\n this.genome.addFeaturesToDB(features, this.config);\n }\n } else {\n this.featureCache = new FeatureCache$1([], genomicInterval); // Empty cache\n }\n }\n}\n\n/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2014 Broad Institute\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\nclass BufferedReader {\n\n constructor(config, contentLength, bufferSize) {\n this.path = config.url;\n this.bufferSize = bufferSize ? bufferSize : 512000;\n this.range = {start: -1, size: -1};\n this.config = config;\n }\n\n /**\n *\n * @param requestedRange - byte rangeas {start, size}\n * @param fulfill - function to receive result\n * @param asUint8 - optional flag to return result as an UInt8Array\n */\n async dataViewForRange(requestedRange, asUint8, retries = 0) {\n try {\n\n const hasData = (this.data && (this.range.start <= requestedRange.start) &&\n ((this.range.start + this.range.size) >= (requestedRange.start + requestedRange.size)));\n\n if (!hasData) {\n let bufferSize;\n // If requested range size is specified, potentially expand buffer size\n if (requestedRange.size) {\n bufferSize = Math.max(this.bufferSize, requestedRange.size);\n } else {\n bufferSize = this.bufferSize;\n }\n if (this.contentLength) {\n bufferSize = Math.min(bufferSize, this.contentLength - requestedRange.start);\n }\n const loadRange = {start: requestedRange.start, size: bufferSize};\n const arrayBuffer = await igvxhr.loadArrayBuffer(this.path, buildOptions(this.config, {range: loadRange}));\n this.data = arrayBuffer;\n this.range = loadRange;\n }\n\n const len = this.data.byteLength;\n const bufferStart = requestedRange.start - this.range.start;\n return asUint8 ?\n new Uint8Array(this.data, bufferStart, len - bufferStart) :\n new DataView(this.data, bufferStart, len - bufferStart)\n } catch (e) {\n if (retries === 0 && e.message && e.message.startsWith(\"416\")) {\n try {\n this.contentLength = await igvxhr.getContentLength(this.path, buildOptions(this.config));\n return this.dataViewForRange(requestedRange, asUint8, ++retries)\n } catch (e1) {\n console.error(e1);\n }\n throw e\n }\n }\n }\n}\n\nfunction getDecoder(definedFieldCount, fieldCount, autoSql, format) {\n\n if (\"biginteract\" === format || (autoSql && ('chromatinInteract' === autoSql.table) || 'interact' === autoSql.table)) {\n return decodeInteract\n } else {\n const standardFieldCount = definedFieldCount - 3;\n return function (feature, tokens) {\n\n if (standardFieldCount > 0) {\n feature.name = tokens[0];\n }\n if (standardFieldCount > 1) {\n feature.score = Number(tokens[1]);\n }\n if (standardFieldCount > 2) {\n feature.strand = tokens[2];\n }\n if (standardFieldCount > 3) {\n feature.cdStart = parseInt(tokens[3]);\n }\n if (standardFieldCount > 4) {\n feature.cdEnd = parseInt(tokens[4]);\n }\n if (standardFieldCount > 5) {\n if (tokens[5] !== \".\" && tokens[5] !== \"0\" && tokens[5] !== \"-1\") {\n const c = IGVColor.createColorString(tokens[5]);\n feature.color = c.startsWith(\"rgb\") ? c : undefined;\n }\n }\n if (standardFieldCount > 8) {\n const exonCount = parseInt(tokens[6]);\n const exonSizes = tokens[7].split(',');\n const exonStarts = tokens[8].split(',');\n const exons = [];\n for (let i = 0; i < exonCount; i++) {\n const eStart = feature.start + parseInt(exonStarts[i]);\n const eEnd = eStart + parseInt(exonSizes[i]);\n exons.push({start: eStart, end: eEnd});\n }\n findUTRs(exons, feature.cdStart, feature.cdEnd);\n feature.exons = exons;\n }\n\n if (autoSql) {\n // TODO -- these should be equal, validate? fieldCount-definedFieldCount, as.fields.length, tokens.length-3\n const extraStart = definedFieldCount;\n for (let i = extraStart; i < fieldCount; i++) {\n if (i < autoSql.fields.length) {\n const name = autoSql.fields[i].name;\n const value = tokens[i - 3];\n feature[name] = value;\n }\n }\n }\n }\n }\n\n //table chromatinInteract\n// \"Chromatin interaction between two regions\"\n// (\n// string chrom; \"Chromosome (or contig, scaffold, etc.). For interchromosomal, use 2 records\"\n// uint chromStart; \"Start position of lower region. For interchromosomal, set to chromStart of this region\"\n// uint chromEnd; \"End position of upper region. For interchromosomal, set to chromEnd of this region\"\n// string name; \"Name of item, for display\"\n// uint score; \"Score from 0-1000\"\n// double value; \"Strength of interaction or other data value. Typically basis for score\"\n// string exp; \"Experiment name (metadata for filtering). Use . if not applicable\"\n// string color; \"Item color. Specified as r,g,b or hexadecimal #RRGGBB or html color name, as in //www.w3.org/TR/css3-color/#html4.\"\n// string region1Chrom; \"Chromosome of lower region. For non-directional interchromosomal, chrom of this region.\"\n// uint region1Start; \"Start position of lower/this region\"\n// uint region1End; \"End position in chromosome of lower/this region\"\n// string region1Name; \"Identifier of lower/this region\"\n// string region1Strand; \"Orientation of lower/this region: + or -. Use . if not applicable\"\n// string region2Chrom; \"Chromosome of upper region. For non-directional interchromosomal, chrom of other region\"\n// uint region2Start; \"Start position in chromosome of upper/this region\"\n// uint region2End; \"End position in chromosome of upper/this region\"\n// string region2Name; \"Identifier of upper/this region\"\n// string region2Strand; \"Orientation of upper/this region: + or -. Use . if not applicable\"\n// )\n function decodeInteract(feature, tokens) {\n\n feature.chr1 = tokens[5];\n feature.start1 = Number.parseInt(tokens[6]);\n feature.end1 = Number.parseInt(tokens[7]);\n\n feature.chr2 = tokens[10];\n feature.start2 = Number.parseInt(tokens[11]);\n feature.end2 = Number.parseInt(tokens[12]);\n\n feature.name = tokens[0];\n feature.score = Number(tokens[1]);\n feature.value = Number(tokens[2]);\n feature.color = tokens[4] === '.' ? undefined : tokens[4] === \"0\" ? \"rgb(0,0,0)\" : tokens[4];\n\n return feature\n }\n}\n\nfunction findUTRs(exons, cdStart, cdEnd) {\n\n for (let exon of exons) {\n const end = exon.end;\n const start = exon.start;\n if (end < cdStart || start > cdEnd) {\n exon.utr = true;\n } else {\n if (cdStart >= start && cdStart <= end) {\n exon.cdStart = cdStart;\n }\n if (cdEnd >= start && cdEnd <= end) {\n exon.cdEnd = cdEnd;\n }\n }\n }\n}\n\nfunction scoreShade(score, color) {\n const alpha = Math.min(1, 0.11 + 0.89 * (score / 779));\n return alpha.toString()\n}\n\nfunction parseAutoSQL(str) {\n\n let table;\n const fields = [];\n let startDecoding = false;\n const lines = str.trim().split(/\\s*[\\r\\n]+\\s*/g);\n for (let line of lines) {\n if (line.startsWith('table')) {\n table = line.split(/\\s+/)[1].trim();\n } else if (line.startsWith('(')) {\n startDecoding = true;\n } else if (line.startsWith(')')) ; else if (startDecoding) {\n if (line.length > 0) {\n const idx = line.indexOf(';');\n const tokens = line.substr(0, idx).split(/\\s+/);\n const description = line.substr(idx + 1).replace(/\"/g, '').trim();\n fields.push({\n type: tokens[0],\n name: tokens[1],\n description: description\n });\n }\n }\n }\n return {\n table: table,\n fields: fields\n }\n}\n\n/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2014 Broad Institute\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\nlet BIGWIG_MAGIC_LTH = 0x888FFC26; // BigWig Magic Low to High\nlet BIGWIG_MAGIC_HTL = 0x26FC8F66; // BigWig Magic High to Low\nlet BIGBED_MAGIC_LTH = 0x8789F2EB; // BigBed Magic Low to High\nlet BIGBED_MAGIC_HTL = 0xEBF28987; // BigBed Magic High to Low\nlet BBFILE_HEADER_SIZE = 64;\nlet RPTREE_HEADER_SIZE = 48;\nlet RPTREE_NODE_LEAF_ITEM_SIZE = 32; // leaf item size\nlet RPTREE_NODE_CHILD_ITEM_SIZE = 24; // child item size\nlet BUFFER_SIZE = 512000; // buffer\n\nclass BWReader {\n\n constructor(config, genome) {\n this.path = config.url;\n this.format = config.format || \"bigwig\";\n this.genome = genome;\n this.rpTreeCache = {};\n this.config = config;\n this.loader = isDataURL(this.path) ? new DataBuffer(this.path) : igvxhr;\n }\n\n async readWGFeatures(bpPerPixel, windowFunction) {\n await this.loadHeader();\n const chrIdx1 = 0;\n const chrIdx2 = this.chromTree.idToChrom.length - 1;\n const chr1 = this.chromTree.idToChrom[chrIdx1];\n const chr2 = this.chromTree.idToChrom[chrIdx2];\n return this.readFeatures(chr1, 0, chr2, Number.MAX_VALUE, bpPerPixel, windowFunction)\n }\n\n async readFeatures(chr1, bpStart, chr2, bpEnd, bpPerPixel, windowFunction) {\n\n await this.loadHeader();\n const chrIdx1 = this.chromTree.chromToID[chr1];\n const chrIdx2 = this.chromTree.chromToID[chr2];\n if (chrIdx1 === undefined || chrIdx2 === undefined) {\n return []\n }\n\n let treeOffset;\n let decodeFunction;\n if (this.type === \"bigwig\") {\n // Select a biwig \"zoom level\" appropriate for the current resolution.\n const zoomLevelHeaders = await this.getZoomHeaders();\n let zoomLevelHeader = bpPerPixel ? zoomLevelForScale$1(bpPerPixel, zoomLevelHeaders) : undefined;\n if (zoomLevelHeader) {\n treeOffset = zoomLevelHeader.indexOffset;\n decodeFunction = decodeZoomData;\n } else {\n treeOffset = this.header.fullIndexOffset;\n decodeFunction = decodeWigData;\n }\n } else {\n // bigbed, zoom data is not currently used in igv for bed type features\n treeOffset = this.header.fullIndexOffset;\n decodeFunction = getBedDataDecoder.call(this);\n }\n\n\n // Load the R Tree and fine leaf items\n const rpTree = await this.loadRPTree(treeOffset);\n const leafItems = await rpTree.findLeafItemsOverlapping(chrIdx1, bpStart, chrIdx2, bpEnd);\n if (!leafItems || leafItems.length === 0) {\n return []\n } else {\n\n // Consolidate leaf items and get all data at once\n let start = Number.MAX_VALUE;\n let end = 0;\n for (let item of leafItems) {\n start = Math.min(start, item.dataOffset);\n end = Math.max(end, item.dataOffset + item.dataSize);\n }\n const size = end - start;\n const arrayBuffer = await this.loader.loadArrayBuffer(this.config.url, buildOptions(this.config, {\n range: {\n start: start,\n size: size\n }\n }));\n\n // Parse data and return features\n const allFeatures = [];\n for (let item of leafItems) {\n const uint8Array = new Uint8Array(arrayBuffer, item.dataOffset - start, item.dataSize);\n let plain;\n const isCompressed = this.header.uncompressBuffSize > 0;\n if (isCompressed) {\n plain = inflate_1$3(uint8Array);\n } else {\n plain = uint8Array;\n }\n decodeFunction.call(this, new DataView(plain.buffer), chrIdx1, bpStart, chrIdx2, bpEnd, allFeatures, this.chromTree.idToChrom, windowFunction);\n }\n\n allFeatures.sort(function (a, b) {\n return a.start - b.start\n });\n\n return allFeatures\n }\n }\n\n async getZoomHeaders() {\n if (this.zoomLevelHeaders) {\n return this.zoomLevelHeaders\n } else {\n await this.loadHeader();\n return this.zoomLevelHeaders\n }\n }\n\n async loadHeader() {\n\n if (this.header) {\n return this.header\n } else {\n let data = await this.loader.loadArrayBuffer(this.path, buildOptions(this.config, {\n range: {\n start: 0,\n size: BBFILE_HEADER_SIZE\n }\n }));\n\n let header;\n\n // Assume low-to-high unless proven otherwise\n this.littleEndian = true;\n\n let binaryParser = new BinaryParser(new DataView(data));\n let magic = binaryParser.getUInt();\n if (magic === BIGWIG_MAGIC_LTH) {\n this.type = \"bigwig\";\n } else if (magic === BIGBED_MAGIC_LTH) {\n this.type = \"bigbed\";\n } else {\n //Try big endian order\n this.littleEndian = false;\n\n binaryParser.littleEndian = false;\n binaryParser.position = 0;\n let magic = binaryParser.getUInt();\n\n if (magic === BIGWIG_MAGIC_HTL) {\n this.type = \"bigwig\";\n } else if (magic === BIGBED_MAGIC_HTL) {\n this.type = \"bigbed\";\n } else ;\n }\n // Table 5 \"Common header for bigwig and bigbed files\"\n header = {\n bwVersion: binaryParser.getUShort(),\n nZoomLevels: binaryParser.getUShort(),\n chromTreeOffset: binaryParser.getLong(),\n fullDataOffset: binaryParser.getLong(),\n fullIndexOffset: binaryParser.getLong(),\n fieldCount: binaryParser.getUShort(),\n definedFieldCount: binaryParser.getUShort(),\n autoSqlOffset: binaryParser.getLong(),\n totalSummaryOffset: binaryParser.getLong(),\n uncompressBuffSize: binaryParser.getInt(),\n extensionOffset: binaryParser.getLong()\n };\n\n ///////////\n\n const startOffset = BBFILE_HEADER_SIZE;\n let range = {start: startOffset, size: (header.fullDataOffset - startOffset + 5)};\n data = await this.loader.loadArrayBuffer(this.path, buildOptions(this.config, {range: range}));\n\n const nZooms = header.nZoomLevels;\n binaryParser = new BinaryParser(new DataView(data));\n\n this.zoomLevelHeaders = [];\n this.firstZoomDataOffset = Number.MAX_SAFE_INTEGER;\n for (let i = 1; i <= nZooms; i++) {\n const zoomNumber = nZooms - i;\n const zlh = new ZoomLevelHeader(zoomNumber, binaryParser);\n this.firstZoomDataOffset = Math.min(zlh.dataOffset, this.firstZoomDataOffset);\n this.zoomLevelHeaders[zoomNumber] = zlh;\n }\n\n // Autosql\n if (header.autoSqlOffset > 0) {\n binaryParser.position = header.autoSqlOffset - startOffset;\n const autoSqlString = binaryParser.getString();\n if (autoSqlString) {\n this.autoSql = parseAutoSQL(autoSqlString);\n }\n }\n\n // Total summary\n if (header.totalSummaryOffset > 0) {\n binaryParser.position = header.totalSummaryOffset - startOffset;\n this.totalSummary = new BWTotalSummary(binaryParser);\n }\n\n // Chrom data index\n if (header.chromTreeOffset > 0) {\n binaryParser.position = header.chromTreeOffset - startOffset;\n this.chromTree = new BPTree(binaryParser, startOffset, this.genome);\n } else {\n // TODO -- this is an error, not expected\n throw \"BigWig chromosome tree offset <= 0\"\n }\n\n //Finally total data count\n binaryParser.position = header.fullDataOffset - startOffset;\n header.dataCount = binaryParser.getInt();\n ///////////\n\n this.setDefaultVisibilityWindow(header);\n\n this.header = header;\n return this.header\n\n }\n }\n\n async loadRPTree(offset) {\n\n let rpTree = this.rpTreeCache[offset];\n if (rpTree) {\n return rpTree\n } else {\n rpTree = new RPTree(offset, this.config, this.littleEndian, this.loader);\n await rpTree.load();\n this.rpTreeCache[offset] = rpTree;\n return rpTree\n }\n }\n\n async getType() {\n await this.loadHeader();\n return this.type\n }\n\n async getTrackType() {\n await this.loadHeader();\n if (this.type === \"bigwig\") {\n return \"wig\"\n } else {\n return this.autoSql && this.autoSql.table === \"chromatinInteract\" ? \"interact\" : \"annotation\"\n }\n }\n\n setDefaultVisibilityWindow(header) {\n if (this.type === \"bigwig\") {\n this.visibilityWindow = -1;\n } else {\n // bigbed\n let genomeSize = this.genome ? this.genome.getGenomeLength() : 3088286401;\n // Estimate window size to return ~ 1,000 features, assuming even distribution across the genome\n this.visibilityWindow = header.dataCount < 1000 ? -1 : 1000 * (genomeSize / header.dataCount);\n\n }\n }\n}\n\n\nclass ZoomLevelHeader {\n constructor(index, byteBuffer) {\n this.index = index;\n this.reductionLevel = byteBuffer.getInt();\n this.reserved = byteBuffer.getInt();\n this.dataOffset = byteBuffer.getLong();\n this.indexOffset = byteBuffer.getLong();\n }\n}\n\nclass RPTree {\n\n constructor(fileOffset, config, littleEndian, loader) {\n\n this.config = config;\n this.loader = loader;\n this.fileOffset = fileOffset; // File offset to beginning of tree\n this.path = config.url;\n this.littleEndian = littleEndian;\n }\n\n async load() {\n const rootNodeOffset = this.fileOffset + RPTREE_HEADER_SIZE;\n const bufferedReader = isDataURL(this.path) ?\n this.loader :\n new BufferedReader(this.config, BUFFER_SIZE);\n this.rootNode = await this.readNode(rootNodeOffset, bufferedReader);\n return this\n }\n\n async readNode(filePosition, bufferedReader) {\n\n let dataView = await bufferedReader.dataViewForRange({start: filePosition, size: 4}, false);\n let binaryParser = new BinaryParser(dataView, this.littleEndian);\n const type = binaryParser.getByte();\n const isLeaf = (type === 1);\n binaryParser.getByte();\n const count = binaryParser.getUShort();\n filePosition += 4;\n\n let bytesRequired = count * (isLeaf ? RPTREE_NODE_LEAF_ITEM_SIZE : RPTREE_NODE_CHILD_ITEM_SIZE);\n let range2 = {start: filePosition, size: bytesRequired};\n dataView = await bufferedReader.dataViewForRange(range2, false);\n const items = new Array(count);\n binaryParser = new BinaryParser(dataView);\n\n if (isLeaf) {\n for (let i = 0; i < count; i++) {\n let item = {\n isLeaf: true,\n startChrom: binaryParser.getInt(),\n startBase: binaryParser.getInt(),\n endChrom: binaryParser.getInt(),\n endBase: binaryParser.getInt(),\n dataOffset: binaryParser.getLong(),\n dataSize: binaryParser.getLong()\n };\n items[i] = item;\n\n }\n return new RPTreeNode(items)\n } else { // non-leaf\n for (let i = 0; i < count; i++) {\n\n let item = {\n isLeaf: false,\n startChrom: binaryParser.getInt(),\n startBase: binaryParser.getInt(),\n endChrom: binaryParser.getInt(),\n endBase: binaryParser.getInt(),\n childOffset: binaryParser.getLong()\n };\n items[i] = item;\n }\n\n return new RPTreeNode(items)\n }\n\n }\n\n async findLeafItemsOverlapping(chrIdx1, startBase, chrIdx2, endBase) {\n\n let self = this;\n\n return new Promise(function (fulfill, reject) {\n\n let leafItems = [],\n processing = new Set(),\n bufferedReader = isDataURL(self.path) ?\n self.loader :\n new BufferedReader(self.config, BUFFER_SIZE);\n\n processing.add(0); // Zero represents the root node\n findLeafItems(self.rootNode, 0);\n\n function findLeafItems(node, nodeId) {\n\n if (overlaps(node, chrIdx1, startBase, chrIdx2, endBase)) {\n\n let items = node.items;\n\n items.forEach(function (item) {\n\n if (overlaps(item, chrIdx1, startBase, chrIdx2, endBase)) {\n\n if (item.isLeaf) {\n leafItems.push(item);\n } else {\n if (item.childNode) {\n findLeafItems(item.childNode);\n } else {\n processing.add(item.childOffset); // Represent node to-be-loaded by its file position\n\n self.readNode(item.childOffset, bufferedReader)\n .then(function (node) {\n item.childNode = node;\n findLeafItems(node, item.childOffset);\n })\n .catch(reject);\n }\n }\n }\n });\n\n }\n\n if (nodeId !== undefined) processing.delete(nodeId);\n\n // Wait until all nodes are processed\n if (processing.size === 0) {\n fulfill(leafItems);\n }\n }\n })\n }\n}\n\nclass RPTreeNode {\n\n constructor(items) {\n\n this.items = items;\n\n let minChromId = Number.MAX_SAFE_INTEGER,\n maxChromId = 0,\n minStartBase = Number.MAX_SAFE_INTEGER,\n maxEndBase = 0,\n i,\n item;\n\n for (i = 0; i < items.length; i++) {\n item = items[i];\n minChromId = Math.min(minChromId, item.startChrom);\n maxChromId = Math.max(maxChromId, item.endChrom);\n minStartBase = Math.min(minStartBase, item.startBase);\n maxEndBase = Math.max(maxEndBase, item.endBase);\n }\n\n this.startChrom = minChromId;\n this.endChrom = maxChromId;\n this.startBase = minStartBase;\n this.endBase = maxEndBase;\n }\n}\n\nclass BPTree {\n\n constructor(binaryParser, startOffset, genome) {\n\n let magic = binaryParser.getInt();\n let blockSize = binaryParser.getInt();\n let keySize = binaryParser.getInt();\n let valSize = binaryParser.getInt();\n let itemCount = binaryParser.getLong();\n let reserved = binaryParser.getLong();\n let chromToId = {};\n let idToChrom = [];\n\n this.header = {\n magic: magic,\n blockSize: blockSize,\n keySize: keySize,\n valSize: valSize,\n itemCount: itemCount,\n reserved: reserved\n };\n this.chromToID = chromToId;\n this.idToChrom = idToChrom;\n\n // Recursively walk tree to populate dictionary\n readTreeNode(binaryParser, -1);\n\n\n function readTreeNode(byteBuffer, offset) {\n\n if (offset >= 0) byteBuffer.position = offset;\n\n let type = byteBuffer.getByte();\n byteBuffer.getByte();\n let count = byteBuffer.getUShort(),\n i,\n key,\n chromId,\n childOffset,\n bufferOffset,\n currOffset;\n\n\n if (type === 1) {\n\n for (i = 0; i < count; i++) {\n\n key = byteBuffer.getFixedLengthTrimmedString(keySize);\n chromId = byteBuffer.getInt();\n byteBuffer.getInt();\n\n if (genome) key = genome.getChromosomeName(key); // Translate to canonical chr name\n chromToId[key] = chromId;\n idToChrom[chromId] = key;\n\n }\n } else { // non-leaf\n\n for (i = 0; i < count; i++) {\n\n key = byteBuffer.getFixedLengthTrimmedString(keySize);\n childOffset = byteBuffer.getLong();\n bufferOffset = childOffset - startOffset;\n currOffset = byteBuffer.position;\n readTreeNode(byteBuffer, bufferOffset);\n byteBuffer.position = currOffset;\n }\n }\n\n }\n }\n}\n\n/**\n * Return true if {chrIdx1:startBase-chrIdx2:endBase} overlaps item's interval\n * @returns {boolean}\n */\nfunction overlaps(item, chrIdx1, startBase, chrIdx2, endBase) {\n\n if (!item) {\n console.log(\"null item for \" + chrIdx1 + \" \" + startBase + \" \" + endBase);\n return false\n }\n\n return ((chrIdx2 > item.startChrom) || (chrIdx2 === item.startChrom && endBase >= item.startBase)) &&\n ((chrIdx1 < item.endChrom) || (chrIdx1 === item.endChrom && startBase <= item.endBase))\n\n\n}\n\nclass BWTotalSummary {\n\n constructor(byteBuffer) {\n if (byteBuffer) {\n this.basesCovered = byteBuffer.getLong();\n this.minVal = byteBuffer.getDouble();\n this.maxVal = byteBuffer.getDouble();\n this.sumData = byteBuffer.getDouble();\n this.sumSquares = byteBuffer.getDouble();\n computeStats.call(this);\n } else {\n this.basesCovered = 0;\n this.minVal = 0;\n this.maxVal = 0;\n this.sumData = 0;\n this.sumSquares = 0;\n this.mean = 0;\n this.stddev = 0;\n }\n }\n}\n\nfunction computeStats() {\n let n = this.basesCovered;\n if (n > 0) {\n this.mean = this.sumData / n;\n this.stddev = Math.sqrt(this.sumSquares / (n - 1));\n\n let min = this.minVal < 0 ? this.mean - 2 * this.stddev : 0,\n max = this.maxVal > 0 ? this.mean + 2 * this.stddev : 0;\n\n this.defaultRange = {\n min: min,\n max: max\n };\n }\n}\n\nfunction zoomLevelForScale$1(bpPerPixel, zoomLevelHeaders) {\n let level;\n for (let i = 0; i < zoomLevelHeaders.length; i++) {\n const zl = zoomLevelHeaders[i];\n if (zl.reductionLevel < bpPerPixel) {\n level = zl;\n break\n }\n }\n return level\n}\n\n\nfunction decodeWigData(data, chrIdx1, bpStart, chrIdx2, bpEnd, featureArray, chrDict) {\n\n const binaryParser = new BinaryParser(data);\n const chromId = binaryParser.getInt();\n const blockStart = binaryParser.getInt();\n let chromStart = blockStart;\n let chromEnd = binaryParser.getInt();\n const itemStep = binaryParser.getInt();\n const itemSpan = binaryParser.getInt();\n const type = binaryParser.getByte();\n binaryParser.getByte();\n let itemCount = binaryParser.getUShort();\n\n if (chromId >= chrIdx1 && chromId <= chrIdx2) {\n\n let idx = 0;\n while (itemCount-- > 0) {\n let value;\n switch (type) {\n case 1:\n chromStart = binaryParser.getInt();\n chromEnd = binaryParser.getInt();\n value = binaryParser.getFloat();\n break\n case 2:\n chromStart = binaryParser.getInt();\n value = binaryParser.getFloat();\n chromEnd = chromStart + itemSpan;\n break\n case 3: // Fixed step\n value = binaryParser.getFloat();\n chromStart = blockStart + idx * itemStep;\n chromEnd = chromStart + itemSpan;\n idx++;\n break\n }\n\n if (chromId < chrIdx1 || (chromId === chrIdx1 && chromEnd < bpStart)) continue\n else if (chromId > chrIdx2 || (chromId === chrIdx2 && chromStart >= bpEnd)) break\n\n if (Number.isFinite(value)) {\n const chr = chrDict[chromId];\n featureArray.push({chr: chr, start: chromStart, end: chromEnd, value: value});\n }\n\n }\n }\n}\n\nfunction getBedDataDecoder() {\n\n const minSize = 3 * 4 + 1; // Minimum # of bytes required for a bed record\n const decoder = getDecoder(this.header.definedFieldCount, this.header.fieldCount, this.autoSql, this.format);\n return function (data, chrIdx1, bpStart, chrIdx2, bpEnd, featureArray, chrDict) {\n const binaryParser = new BinaryParser(data);\n while (binaryParser.remLength() >= minSize) {\n\n const chromId = binaryParser.getInt();\n const chr = chrDict[chromId];\n const chromStart = binaryParser.getInt();\n const chromEnd = binaryParser.getInt();\n const rest = binaryParser.getString();\n if (chromId < chrIdx1 || (chromId === chrIdx1 && chromEnd < bpStart)) continue\n else if (chromId > chrIdx2 || (chromId === chrIdx2 && chromStart >= bpEnd)) break\n\n if (chromEnd > 0) {\n const feature = {chr: chr, start: chromStart, end: chromEnd};\n featureArray.push(feature);\n const tokens = rest.split(\"\\t\");\n decoder(feature, tokens);\n }\n }\n }\n}\n\n\nfunction decodeZoomData(data, chrIdx1, bpStart, chrIdx2, bpEnd, featureArray, chrDict, windowFunction) {\n\n const binaryParser = new BinaryParser(data);\n const minSize = 8 * 4; // Minimum # of bytes required for a zoom record\n\n\n while (binaryParser.remLength() >= minSize) {\n const chromId = binaryParser.getInt();\n const chr = chrDict[chromId];\n const chromStart = binaryParser.getInt();\n const chromEnd = binaryParser.getInt();\n const validCount = binaryParser.getInt();\n const minVal = binaryParser.getFloat();\n const maxVal = binaryParser.getFloat();\n const sumData = binaryParser.getFloat();\n binaryParser.getFloat();\n let value;\n switch (windowFunction) {\n case \"min\":\n value = minVal;\n break\n case \"max\":\n value = maxVal;\n break\n default:\n value = validCount === 0 ? 0 : sumData / validCount;\n }\n\n if (chromId < chrIdx1 || (chromId === chrIdx1 && chromEnd < bpStart)) continue\n else if (chromId > chrIdx2 || (chromId === chrIdx2 && chromStart >= bpEnd)) break\n\n\n if (Number.isFinite(value)) {\n featureArray.push({chr: chr, start: chromStart, end: chromEnd, value: value});\n\n\n }\n }\n}\n\nclass DataBuffer {\n\n constructor(dataURI) {\n this.data = decodeDataURI$1(dataURI).buffer;\n }\n\n /**\n * igvxhr interface\n * @param ignore\n * @param options\n * @returns {any}\n */\n loadArrayBuffer(ignore, options) {\n const range = options.range;\n return range ? this.data.slice(range.start, range.start + range.size) : this.data\n }\n\n /**\n * BufferedReader interface\n *\n * @param requestedRange - byte rangeas {start, size}\n * @param fulfill - function to receive result\n * @param asUint8 - optional flag to return result as an UInt8Array\n */\n async dataViewForRange(requestedRange, asUint8) {\n const len = Math.min(this.data.byteLength - requestedRange.start, requestedRange.size);\n return asUint8 ?\n new Uint8Array(this.data, requestedRange.start, len) :\n new DataView(this.data, requestedRange.start, len)\n }\n}\n\n/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2014 Broad Institute\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\nclass BWSource {\n\n constructor(config, genome) {\n this.reader = new BWReader(config, genome);\n this.genome = genome;\n this.format = config.format || \"bigwig\";\n this.wgValues = {};\n this.queryable = true;\n }\n\n async getFeatures({chr, start, end, bpPerPixel, windowFunction}) {\n\n const isBigWig = this.reader.type === \"bigwig\";\n\n const features = (chr.toLowerCase() === \"all\") ?\n (isBigWig ? await this.getWGValues(windowFunction) : []) :\n await this.reader.readFeatures(chr, start, chr, end, bpPerPixel, windowFunction);\n\n if (!isBigWig) {\n pack(features);\n }\n return features\n }\n\n async getHeader() {\n return this.reader.loadHeader()\n }\n\n getDefaultRange() {\n if (this.reader.totalSummary !== undefined) {\n return this.reader.totalSummary.defaultRange\n } else {\n return undefined\n }\n }\n\n async defaultVisibilityWindow() {\n return this.reader.defaultVisibilityWindow\n }\n\n async getWGValues(windowFunction) {\n\n const nominalScreenWidth = 1000; // This doesn't need to be precise\n const genome = this.genome;\n\n if (this.wgValues[windowFunction]) {\n return this.wgValues[windowFunction]\n } else {\n\n const bpPerPixel = genome.getGenomeLength() / nominalScreenWidth;\n const features = await this.reader.readWGFeatures(bpPerPixel, windowFunction);\n let wgValues = [];\n for (let f of features) {\n const chr = f.chr;\n const offset = genome.getCumulativeOffset(chr);\n const wgFeature = Object.assign({}, f);\n wgFeature.chr = \"all\";\n wgFeature.start = offset + f.start;\n wgFeature.end = offset + f.end;\n wgValues.push(wgFeature);\n }\n this.wgValues[windowFunction] = wgValues;\n return wgValues\n }\n }\n\n supportsWholeGenome() {\n return this.reader.type === \"bigwig\"\n }\n\n async trackType() {\n return this.reader.getTrackType()\n }\n}\n\n/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2016 University of California San Diego\n * Author: Jim Robinson\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\nconst GZIP_FLAG = 0x1;\n\nclass TDFReader {\n\n constructor(config, genome) {\n this.config = config;\n this.genome = genome;\n this.path = config.url;\n this.groupCache = {};\n this.datasetCache = {};\n }\n\n\n async readHeader() {\n\n if (this.magic !== undefined) {\n return this // Already read\n }\n\n let data = await igvxhr.loadArrayBuffer(this.path, buildOptions(this.config, {range: {start: 0, size: 64000}}));\n let binaryParser = new BinaryParser(new DataView(data));\n this.magic = binaryParser.getInt();\n this.version = binaryParser.getInt();\n this.indexPos = binaryParser.getLong();\n this.indexSize = binaryParser.getInt();\n binaryParser.getInt();\n\n\n if (this.version >= 2) {\n let nWindowFunctions = binaryParser.getInt();\n this.windowFunctions = [];\n while (nWindowFunctions-- > 0) {\n this.windowFunctions.push(binaryParser.getString());\n }\n }\n\n this.trackType = binaryParser.getString();\n this.trackLine = binaryParser.getString();\n\n let nTracks = binaryParser.getInt();\n this.trackNames = [];\n while (nTracks-- > 0) {\n this.trackNames.push(binaryParser.getString());\n }\n this.genomeID = binaryParser.getString();\n this.flags = binaryParser.getInt();\n this.compressed = (this.flags & GZIP_FLAG) !== 0;\n\n // Now read index\n data = await igvxhr.loadArrayBuffer(this.path, buildOptions(this.config, {\n range: {\n start: this.indexPos,\n size: this.indexSize\n }\n }));\n binaryParser = new BinaryParser(new DataView(data));\n this.datasetIndex = {};\n let nEntries = binaryParser.getInt();\n while (nEntries-- > 0) {\n const name = binaryParser.getString();\n const pos = binaryParser.getLong();\n const size = binaryParser.getInt();\n this.datasetIndex[name] = {position: pos, size: size};\n }\n\n this.groupIndex = {};\n nEntries = binaryParser.getInt();\n while (nEntries-- > 0) {\n const name = binaryParser.getString();\n const pos = binaryParser.getLong();\n const size = binaryParser.getInt();\n this.groupIndex[name] = {position: pos, size: size};\n }\n\n return this\n }\n\n async readDataset(chr, windowFunction, zoom) {\n\n const key = chr + \"_\" + windowFunction + \"_\" + zoom;\n\n if (this.datasetCache[key]) {\n return this.datasetCache[key]\n\n } else {\n await this.readHeader();\n const wf = (this.version < 2) ? \"\" : \"/\" + windowFunction;\n const zoomString = (chr.toLowerCase() === \"all\" || zoom === undefined) ? \"0\" : zoom.toString();\n\n let dsName;\n if (windowFunction === \"raw\") {\n dsName = \"/\" + chr + \"/raw\";\n } else {\n dsName = \"/\" + chr + \"/z\" + zoomString + wf;\n }\n const indexEntry = this.datasetIndex[dsName];\n\n if (indexEntry === undefined) {\n return undefined\n }\n\n const data = await igvxhr.loadArrayBuffer(this.path, buildOptions(this.config, {\n range: {\n start: indexEntry.position,\n size: indexEntry.size\n }\n }));\n\n if (!data) {\n return undefined\n }\n\n const binaryParser = new BinaryParser(new DataView(data));\n let nAttributes = binaryParser.getInt();\n const attributes = {};\n while (nAttributes-- > 0) {\n attributes[binaryParser.getString()] = binaryParser.getString();\n }\n const dataType = binaryParser.getString();\n const tileWidth = binaryParser.getFloat();\n let nTiles = binaryParser.getInt();\n const tiles = [];\n while (nTiles-- > 0) {\n tiles.push({position: binaryParser.getLong(), size: binaryParser.getInt()});\n }\n\n const dataset = {\n name: dsName,\n attributes: attributes,\n dataType: dataType,\n tileWidth: tileWidth,\n tiles: tiles\n };\n\n this.datasetCache[key] = dataset;\n return dataset\n }\n }\n\n async readRootGroup() {\n\n const genome = this.genome;\n const rootGroup = this.groupCache[\"/\"];\n if (rootGroup) {\n return rootGroup\n } else {\n\n const group = await this.readGroup(\"/\");\n const names = group[\"chromosomes\"];\n const maxZoomString = group[\"maxZoom\"];\n\n // Now parse out interesting attributes.\n if (maxZoomString) {\n this.maxZoom = Number(maxZoomString);\n }\n\n const totalCountString = group[\"totalCount\"];\n if (totalCountString) {\n group.totalCount = Number(totalCountString);\n }\n\n // Chromosome names\n const chrAliasTable = {};\n if (names) {\n names.split(\",\").forEach(function (chr) {\n const canonicalName = genome.getChromosomeName(chr);\n chrAliasTable[canonicalName] = chr;\n });\n }\n this.chrAliasTable = chrAliasTable;\n\n this.groupCache[\"/\"] = group;\n return group\n }\n }\n\n async readGroup(name) {\n\n const group = this.groupCache[name];\n if (group) {\n return group\n } else {\n\n await this.readHeader();\n const indexEntry = this.groupIndex[name];\n if (indexEntry === undefined) {\n return undefined\n }\n\n const data = await igvxhr.loadArrayBuffer(this.path, buildOptions(this.config, {\n range: {\n start: indexEntry.position,\n size: indexEntry.size\n }\n }));\n\n if (!data) {\n return undefined\n }\n\n const binaryParser = new BinaryParser(new DataView(data));\n const group = {name: name};\n let nAttributes = binaryParser.getInt();\n while (nAttributes-- > 0) {\n const key = binaryParser.getString();\n const value = binaryParser.getString();\n group[key] = value;\n }\n this.groupCache[name] = group;\n return group\n }\n }\n\n\n async readTiles(tileIndeces, nTracks) {\n\n tileIndeces.sort(function (a, b) {\n return a.position - b.position\n });\n\n tileIndeces = tileIndeces.filter(function (idx) {\n return idx.size > 0\n });\n\n if (tileIndeces.length === 0) {\n return Promise.resolve([])\n }\n\n const firstEntry = tileIndeces[0];\n const lastEntry = tileIndeces[tileIndeces.length - 1];\n const position = firstEntry.position;\n const size = (lastEntry.position + lastEntry.size) - position;\n const data = await igvxhr.loadArrayBuffer(this.path, buildOptions(this.config, {\n range: {\n start: position,\n size: size\n }\n }));\n\n const tiles = [];\n\n // Loop through and decode tiles\n for (let indexEntry of tileIndeces) {\n const start = indexEntry.position - position;\n const size = indexEntry.size;\n if (size > 0) {\n let tileData;\n if (this.compressed) {\n const plain = inflate_1$3(data.slice(start, start + size));\n tileData = plain.buffer;\n } else {\n tileData = data.slice(start, start + size);\n }\n\n const binaryParser = new BinaryParser(new DataView(tileData));\n const type = binaryParser.getString();\n let tile;\n switch (type) {\n case \"fixedStep\":\n tile = createFixedStep(binaryParser, nTracks);\n break\n case \"variableStep\":\n tile = createVariableStep(binaryParser, nTracks);\n break\n case \"bed\":\n case \"bedWithName\":\n tile = createBed(binaryParser, nTracks, type);\n break\n default:\n throw \"Unknown tile type: \" + type\n }\n tiles.push(tile);\n }\n }\n return tiles\n }\n\n async readTile(indexEntry, nTracks) {\n\n let data = await igvxhr.loadArrayBuffer(this.path, buildOptions(this.config, {\n range: {\n start: indexEntry.position,\n size: indexEntry.size\n }\n }));\n\n if (this.compressed) {\n const plain = inflate_1$3(data);\n data = plain.buffer;\n }\n\n const binaryParser = new BinaryParser(new DataView(data));\n const type = binaryParser.getString();\n switch (type) {\n case \"fixedStep\":\n return createFixedStep(binaryParser, nTracks)\n case \"variableStep\":\n return createVariableStep(binaryParser, nTracks)\n case \"bed\":\n case \"bedWithName\":\n return createBed(binaryParser, nTracks, type)\n default:\n throw \"Unknown tile type: \" + type\n }\n }\n\n}\n\nfunction createFixedStep(binaryParser, nTracks) {\n const nPositions = binaryParser.getInt();\n const start = binaryParser.getInt();\n const span = binaryParser.getFloat();\n\n const data = [];\n let nt = nTracks;\n while (nt-- > 0) {\n let np = nPositions;\n const dtrack = [];\n while (np-- > 0) {\n dtrack.push(binaryParser.getFloat());\n }\n data.push(dtrack);\n }\n\n return {\n type: \"fixedStep\",\n start: start,\n span: span,\n data: data,\n nTracks: nTracks,\n nPositions: nPositions\n }\n}\n\nfunction createVariableStep(binaryParser, nTracks) {\n\n const tileStart = binaryParser.getInt();\n const span = binaryParser.getFloat();\n const nPositions = binaryParser.getInt();\n const start = [];\n\n let np = nPositions;\n while (np-- > 0) {\n start.push(binaryParser.getInt());\n }\n binaryParser.getInt(); // # of samples, ignored but should === nTracks\n\n const data = [];\n let nt = nTracks;\n while (nt-- > 0) {\n np = nPositions;\n const dtrack = [];\n while (np-- > 0) {\n dtrack.push(binaryParser.getFloat());\n }\n data.push(dtrack);\n }\n\n return {\n type: \"variableStep\",\n tileStart: tileStart,\n span: span,\n start: start,\n data: data,\n nTracks: nTracks,\n nPositions: nPositions\n }\n}\n\nfunction createBed(binaryParser, nTracks, type) {\n\n const nPositions = binaryParser.getInt();\n\n let n = nPositions;\n const start = [];\n while (n-- > 0) {\n start.push(binaryParser.getInt());\n }\n\n n = nPositions;\n const end = [];\n while (n-- > 0) {\n end.push(binaryParser.getInt());\n }\n\n binaryParser.getInt(); // # of samples, ignored but should === nTracks\n const data = [];\n let nt = nTracks;\n while (nt-- > 0) {\n let np = nPositions;\n const dtrack = [];\n while (np-- > 0) {\n dtrack.push(binaryParser.getFloat());\n }\n data.push(dtrack);\n }\n\n if (type === \"bedWithName\") {\n n = nPositions;\n const name = [];\n while (n-- > 0) {\n name.push(binaryParser.getString());\n }\n }\n\n return {\n type: type,\n start: start,\n end: end,\n data: data,\n nTracks: nTracks,\n nPositions: nPositions\n }\n\n}\n\n/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2016 University of California San Diego\n * Author: Jim Robinson\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\nclass TDFSource {\n\n constructor(config, genome) {\n this.genome = genome;\n this.windowFunction = config.windowFunction || \"mean\";\n this.reader = new TDFReader(config, genome);\n this.queryable = true;\n }\n\n async getFeatures({chr, start, end, bpPerPixel}) {\n\n if (chr.toLowerCase() === \"all\") {\n const wgFeatures = [];\n const genome = this.genome;\n const chrNames = this.genome.wgChromosomeNames;\n if (chrNames) {\n for (let c of genome.wgChromosomeNames) {\n const len = genome.getChromosome(c).bpLength;\n bpPerPixel = len / 1000;\n const chrFeatures = await this._getFeatures(c, 0, len, bpPerPixel);\n if (chrFeatures) {\n for (let f of chrFeatures) {\n const wg = Object.assign({}, f);\n wg.chr = \"all\";\n wg.start = genome.getGenomeCoordinate(f.chr, f.start);\n wg.end = genome.getGenomeCoordinate(f.chr, f.end);\n wg._f = f;\n wgFeatures.push(wg);\n }\n }\n }\n }\n return wgFeatures\n\n } else {\n return this._getFeatures(chr, start, end, bpPerPixel)\n }\n }\n\n async _getFeatures(chr, start, end, bpPerPixel) {\n const genomicInterval = new GenomicInterval(chr, start, end);\n const genome = this.genome;\n\n\n if (!this.rootGroup) {\n this.rootGroup = await this.reader.readRootGroup();\n if (!this.normalizationFactor) {\n const totalCount = this.rootGroup.totalCount;\n if (totalCount) {\n this.normalizationFactor = 1.0e6 / totalCount;\n }\n }\n }\n\n genomicInterval.bpPerPixel = bpPerPixel;\n const zoom = zoomLevelForScale(chr, bpPerPixel, genome);\n let queryChr = this.reader.chrAliasTable[chr];\n let maxZoom = this.reader.maxZoom;\n if (queryChr === undefined) queryChr = chr;\n if (maxZoom === undefined) maxZoom = -1;\n\n const wf = zoom > maxZoom ? \"raw\" : this.windowFunction;\n const dataset = await this.reader.readDataset(queryChr, wf, zoom);\n if (dataset == null) {\n return []\n }\n\n const tileWidth = dataset.tileWidth;\n const startTile = Math.floor(start / tileWidth);\n const endTile = Math.floor(end / tileWidth);\n const NTRACKS = 1; // TODO read this\n const tiles = await this.reader.readTiles(dataset.tiles.slice(startTile, endTile + 1), NTRACKS);\n const features = [];\n for (let tile of tiles) {\n switch (tile.type) {\n case \"bed\":\n decodeBedTile(tile, chr, start, end, bpPerPixel, features);\n break\n case \"variableStep\":\n decodeVaryTile(tile, chr, start, end, bpPerPixel, features);\n break\n case \"fixedStep\":\n decodeFixedTile(tile, chr, start, end, bpPerPixel, features);\n break\n default:\n throw (\"Unknown tile type: \" + tile.type)\n }\n }\n features.sort(function (a, b) {\n return a.start - b.start\n });\n\n return features\n }\n\n get supportsWholeGenome() {\n return true\n }\n}\n\nfunction decodeBedTile(tile, chr, bpStart, bpEnd, bpPerPixel, features) {\n\n const nPositions = tile.nPositions;\n const starts = tile.start;\n const ends = tile.end;\n const data = tile.data[0]; // Single track for now\n for (let i = 0; i < nPositions; i++) {\n const s = starts[i];\n const e = ends[i];\n if (e < bpStart) continue\n if (s > bpEnd) break\n features.push({\n chr: chr,\n start: s,\n end: e,\n value: data[i]\n });\n }\n}\n\nfunction decodeVaryTile(tile, chr, bpStart, bpEnd, bpPerPixel, features) {\n\n const nPositions = tile.nPositions;\n const starts = tile.start;\n const span = tile.span;\n const data = tile.data[0]; // Single track for now\n for (let i = 0; i < nPositions; i++) {\n const s = starts[i];\n const e = s + span;\n if (e < bpStart) continue\n if (s > bpEnd) break\n features.push({\n chr: chr,\n start: s,\n end: e,\n value: data[i]\n });\n }\n}\n\nfunction decodeFixedTile(tile, chr, bpStart, bpEnd, bpPerPixel, features) {\n\n const nPositions = tile.nPositions;\n let s = tile.start;\n const span = tile.span;\n const data = tile.data[0]; // Single track for now\n\n for (let i = 0; i < nPositions; i++) {\n const e = s + span;\n if (s > bpEnd) break\n if (e >= bpStart) {\n if (!Number.isNaN(data[i])) {\n features.push({\n chr: chr,\n start: s,\n end: e,\n value: data[i]\n });\n }\n }\n s = e;\n }\n}\n\n\nvar log2 = Math.log(2);\n\nfunction zoomLevelForScale(chr, bpPerPixel, genome) {\n\n // Convert bpPerPixel to IGV \"zoom\" level. This is a bit convoluted, IGV computes zoom levels assuming\n // display in a 700 pixel window. The fully zoomed out view of a chromosome is zoom level \"0\".\n // Zoom level 1 is magnified 2X, and so forth\n\n var chrSize = genome.getChromosome(chr).bpLength;\n\n return Math.ceil(Math.log(Math.max(0, (chrSize / (bpPerPixel * 700)))) / log2)\n}\n\n/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2014-2015 Broad Institute\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\n/**\n * feature source for features supplied directly, as opposed to reading and parsing from a file or webservice\n *\n * @param config\n * @constructor\n */\nclass StaticFeatureSource {\n\n constructor(config, genome) {\n\n this.config = config;\n this.genome = genome;\n this.queryable = false;\n this.searchable = config.searchable !== false; // searchable by default\n this.updateFeatures(config.features);\n }\n\n updateFeatures(features) {\n features = fixFeatures(features, this.genome);\n packFeatures(features);\n if (this.config.mappings) {\n mapProperties(features, this.config.mappings);\n }\n this.featureCache = new FeatureCache$1(features, this.genome);\n\n if (this.searchable || this.config.searchableFields) {\n this.genome.addFeaturesToDB(features, this.config);\n }\n }\n\n /**\n * Required function for all data source objects. Fetches features for the\n * range requested.\n *\n * This function is complex due to the variety of reader types backing it, some indexed, some queryable,\n * some not.\n *\n * @param chr\n * @param start\n * @param end\n * @param bpPerPixel\n */\n async getFeatures({chr, start, end, bpPerPixel, visibilityWindow}) {\n\n const genome = this.genome;\n const queryChr = genome ? genome.getChromosomeName(chr) : chr;\n const isWholeGenome = (\"all\" === queryChr.toLowerCase());\n\n // Various conditions that can require a feature load\n // * view is \"whole genome\" but no features are loaded\n // * cache is disabled\n // * cache does not contain requested range\n if (isWholeGenome) {\n return computeWGFeatures(this.featureCache.getAllFeatures(), this.genome, this.maxWGCount)\n } else {\n return this.featureCache.queryFeatures(queryChr, start, end)\n }\n }\n\n //\n // supportsWholeGenome() {\n // return true\n // }\n\n getAllFeatures() {\n return this.featureCache.getAllFeatures()\n }\n\n supportsWholeGenome() {\n return true\n }\n\n\n}\n\n\n/**\n * This function is used to apply properties normally added during parsing to features supplied directly in the\n * config as an array of objects. At the moment the only application is bedpe type features.\n * @param features\n */\nfunction fixFeatures(features, genome) {\n\n if (genome) {\n for (let feature of features) {\n feature.chr = genome.getChromosomeName(feature.chr);\n }\n }\n\n return features\n}\n\n\n\nfunction mapProperties(features, mappings) {\n let mappingKeys = Object.keys(mappings);\n features.forEach(function (f) {\n mappingKeys.forEach(function (key) {\n f[key] = f[mappings[key]];\n });\n });\n}\n\n/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2014-2015 Broad Institute\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\nconst bbFormats = new Set(['bigwig', 'bw', 'bigbed', 'bb', 'biginteract', 'biggenepred', 'bignarrowpeak']);\n\nfunction FeatureSource(config, genome) {\n\n const format = config.format ? config.format.toLowerCase() : undefined;\n\n if (config.features) {\n return new StaticFeatureSource(config, genome)\n } else if (bbFormats.has(format)) {\n return new BWSource(config, genome)\n } else if (\"tdf\" === format) {\n return new TDFSource(config, genome)\n } else {\n return new TextFeatureSource(config, genome)\n }\n}\n\nconst appleCrayonColorName = 'nickel';\n\nconst ROI_DEFAULT_ALPHA = 2 / 16;\n\nconst ROI_DEFAULT_COLOR = appleCrayonRGBA(appleCrayonColorName, ROI_DEFAULT_ALPHA);\nconst ROI_DEFAULT_HEADER_COLOR = 'rgb(190,190,190)';\n\nconst ROI_USER_HEADER_DEFINED_COLOR = 'rgba(155,185,129)';\nconst ROI_USER_DEFINED_COLOR = ROI_DEFAULT_COLOR;\n\nclass ROISet {\n\n constructor(config, genome) {\n\n this.url = config.url;\n\n if (config.name) {\n this.name = config.name;\n } else if (config.url && isFile(config.url)) {\n this.name = config.url.name;\n } else if (config.url && isString$2(config.url) && !config.url.startsWith(\"data:\")) {\n this.name = getFilename$2(config.url);\n }\n\n this.isUserDefined = config.isUserDefined;\n\n if (config.features) {\n this.featureSource = new DynamicFeatureSource(config.features, genome);\n } else {\n if (config.format) {\n config.format = config.format.toLowerCase();\n } else {\n const filename = getFilename$2(config.url);\n config.format = inferFileFormat(filename);\n }\n this.featureSource = config.featureSource || FeatureSource(config, genome);\n }\n\n if (true === this.isUserDefined) {\n this.color = config.color || ROI_USER_DEFINED_COLOR;\n this.headerColor = ROI_USER_HEADER_DEFINED_COLOR;\n\n } else {\n\n this.color = config.color || ROI_DEFAULT_COLOR;\n this.headerColor = ROI_DEFAULT_HEADER_COLOR;\n\n // Use body color with alpha pinned to 1\n // const [ r, g, b, discard ] = rgbaStringTokens(this.color)\n // this.headerColor = `rgba(${ r },${ g },${ b },${ 1.0 })`\n\n }\n }\n\n async getFeatures(chr, start, end) {\n return this.featureSource.getFeatures({chr, start, end})\n }\n\n async getAllFeatures() {\n return typeof this.featureSource.getAllFeatures === 'function' ? await this.featureSource.getAllFeatures() : {}\n }\n\n addFeature(feature) {\n if (this.isUserDefined) {\n this.featureSource.addFeature(feature);\n } else {\n console.error(\"Attempt to add ROI to non user-defined set\");\n }\n }\n\n removeFeature(feature) {\n if (this.isUserDefined) {\n this.featureSource.removeFeature(feature);\n } else {\n console.error(\"Attempt to remove ROI from non user-defined set\");\n }\n }\n\n toJSON() {\n if (this.url) {\n return {name: this.name, color: this.color, url: this.url, isUserDefined: this.isUserDefined}\n } else {\n const featureMap = this.featureSource.getAllFeatures();\n const features = [];\n for (let chr of Object.keys(featureMap)) {\n for (let f of featureMap[chr]) {\n features.push(f);\n }\n }\n return {name: this.name, color: this.color, features: features, isUserDefined: this.isUserDefined}\n }\n }\n\n dispose() {\n for (let key of Object.keys(this)) {\n this[key] = undefined;\n }\n }\n\n}\n\nconst SCREEN_COORDS_WIDTH_THRESHOLD = 3;\n\nfunction screenCoordinates(regionStartBP, regionEndBP, bpStart, bpp) {\n\n let xStart = Math.round((regionStartBP - bpStart) / bpp);\n const xEnd = Math.round((regionEndBP - bpStart) / bpp);\n\n let width = xEnd - xStart;\n\n if (width < SCREEN_COORDS_WIDTH_THRESHOLD) {\n width = SCREEN_COORDS_WIDTH_THRESHOLD;\n xStart -= 1;\n }\n\n return {x: xStart, width}\n}\n\n\n/**\n * Special feature source that allows addition of features dynamically\n */\nclass DynamicFeatureSource {\n\n constructor(features, genome) {\n this.featureMap = {};\n this.genome = genome;\n\n for (let feature of features) {\n\n // Store as canonical chr name (i.e. translate aliases)\n const chrKey = genome ? genome.getChromosomeName(feature.chr) : feature.chr;\n\n let featureList = this.featureMap[chrKey];\n if (!featureList) {\n featureList = [];\n this.featureMap[chrKey] = featureList;\n }\n featureList.push(feature);\n }\n\n for (let key of Object.keys(this.featureMap)) {\n this.featureMap[key].sort((a, b) => a.start - b.start);\n }\n }\n\n getFeatures({chr, start, end}) {\n if (chr.toLowerCase() === 'all') {\n return computeWGFeatures(this.featureMap, this.genome)\n } else {\n // TODO -- this use of filter is O(N), and might not scale well for large feature lists.\n const featureList = this.featureMap[chr];\n return featureList ? featureList.filter(feature => feature.end > start && feature.start < end) : []\n }\n }\n\n getAllFeatures() {\n return this.featureMap\n }\n\n supportsWholeGenome() {\n return true\n }\n\n addFeature(feature) {\n let featureList = this.featureMap[feature.chr];\n if (!featureList) {\n featureList = [];\n this.featureMap[feature.chr] = featureList;\n }\n featureList.push(feature);\n featureList.sort((a, b) => a.start - b.start);\n }\n\n removeFeature({chr, start, end}) {\n\n if (this.featureMap[chr]) {\n const match = `${chr}-${start}-${end}`;\n this.featureMap[chr] = this.featureMap[chr].filter(feature => match !== `${feature.chr}-${feature.start}-${feature.end}`);\n }\n }\n}\n\n/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2016-2017 The Regents of the University of California\n * Author: Jim Robinson\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\nconst RULER_SWEEPER_COLOR = 'rgba(68, 134, 247, 0.25)';\n\nclass RulerSweeper {\n\n constructor(rulerViewport, column, browser, referenceFrame) {\n\n this.rulerViewport = rulerViewport;\n\n this.rulerSweeper = domUtils.div({class: 'igv-ruler-sweeper'});\n column.appendChild(this.rulerSweeper);\n\n this.browser = browser;\n this.referenceFrame = referenceFrame;\n\n this.isMouseHandlers = undefined;\n\n this.addBrowserObserver();\n }\n\n addBrowserObserver() {\n\n const observerHandler = () => {\n if (this.referenceFrame) {\n GenomeUtils.isWholeGenomeView(this.referenceFrame.chr) ? this.removeMouseHandlers() : this.addMouseHandlers();\n }\n };\n\n // Viewport Content\n this.boundObserverHandler = observerHandler.bind(this);\n this.browser.on('locuschange', this.boundObserverHandler);\n\n }\n\n removeBrowserObserver() {\n this.browser.off('locuschange', this.boundObserverHandler);\n }\n\n addMouseHandlers() {\n\n if (true === this.isMouseHandlers) {\n return\n }\n\n const threshold = 1;\n\n let isMouseDown;\n let isMouseIn;\n let mouseDownX;\n let left;\n let width;\n let dx;\n\n // Viewport Content\n this.boundContentMouseDownHandler = contentMouseDownHandler.bind(this);\n this.rulerViewport.contentDiv.addEventListener('mousedown', this.boundContentMouseDownHandler);\n\n function contentMouseDownHandler(event) {\n\n isMouseDown = true;\n isMouseIn = true;\n\n const {x} = domUtils.translateMouseCoordinates(event, this.rulerViewport.contentDiv);\n left = mouseDownX = x;\n\n width = threshold;\n\n\n this.rulerSweeper.style.display = 'block';\n this.rulerSweeper.style.backgroundColor = true === event.shiftKey ? ROI_USER_DEFINED_COLOR : RULER_SWEEPER_COLOR;\n\n this.rulerSweeper.style.left = `${left}px`;\n this.rulerSweeper.style.width = `${width}px`;\n\n }\n\n // Document\n this.boundDocumentMouseMoveHandler = documentMouseMoveHandler.bind(this);\n document.addEventListener('mousemove', this.boundDocumentMouseMoveHandler);\n\n function documentMouseMoveHandler(event) {\n\n let mouseCurrentX;\n\n if (isMouseDown && isMouseIn) {\n\n const {x} = domUtils.translateMouseCoordinates(event, this.rulerViewport.contentDiv);\n mouseCurrentX = Math.max(Math.min(x, this.rulerViewport.contentDiv.clientWidth), 0);\n\n dx = mouseCurrentX - mouseDownX;\n\n width = Math.abs(dx);\n this.rulerSweeper.style.width = `${width}px`;\n\n if (dx < 0) {\n left = mouseDownX + dx;\n this.rulerSweeper.style.left = `${left}px`;\n }\n\n }\n\n }\n\n this.boundDocumentMouseUpHandler = documentMouseUpHandler.bind(this);\n document.addEventListener('mouseup', this.boundDocumentMouseUpHandler);\n\n function documentMouseUpHandler(event) {\n\n let genomicExtent;\n\n if (true === isMouseDown && true === isMouseIn) {\n\n isMouseDown = isMouseIn = undefined;\n\n this.rulerSweeper.style.display = 'none';\n\n if (width > threshold) {\n\n genomicExtent =\n {\n start: Math.floor(this.referenceFrame.calculateEnd(left)),\n end: Math.floor(this.referenceFrame.calculateEnd(left + width)),\n };\n\n\n const shiftKeyPressed = event.shiftKey;\n\n if (true === shiftKeyPressed) {\n this.browser.roiManager.updateUserDefinedROISet(Object.assign({chr: this.referenceFrame.chr}, genomicExtent));\n } else {\n\n validateGenomicExtent(this.browser.genome.getChromosome(this.referenceFrame.chr).bpLength, genomicExtent, this.browser.minimumBases());\n updateReferenceFrame(this.referenceFrame, genomicExtent, this.rulerViewport.contentDiv.clientWidth);\n this.browser.updateViews(this.referenceFrame);\n\n }\n\n }\n\n }\n\n }\n\n this.isMouseHandlers = true;\n }\n\n removeMouseHandlers() {\n this.rulerViewport.contentDiv.removeEventListener('mousedown', this.boundContentMouseDownHandler);\n document.removeEventListener('mousemove', this.boundDocumentMouseMoveHandler);\n document.removeEventListener('mouseup', this.boundDocumentMouseUpHandler);\n this.isMouseHandlers = false;\n }\n\n dispose() {\n this.removeBrowserObserver();\n this.removeMouseHandlers();\n this.rulerSweeper.remove();\n }\n\n}\n\nfunction updateReferenceFrame(referenceFrame, genomicExtent, pixelWidth) {\n referenceFrame.start = Math.round(genomicExtent.start);\n referenceFrame.end = Math.round(genomicExtent.end);\n referenceFrame.bpPerPixel = (referenceFrame.end - referenceFrame.start) / pixelWidth;\n}\n\n/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2016 University of California San Diego\n * Author: Jim Robinson\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\n\nclass PairedAlignment {\n\n constructor(firstAlignment) {\n\n this.paired = true;\n this.firstAlignment = firstAlignment;\n this.chr = firstAlignment.chr;\n this.readName = firstAlignment.readName;\n\n if (firstAlignment.start < firstAlignment.mate.position) {\n this.start = firstAlignment.start;\n this.scStart = firstAlignment.scStart;\n this.connectingStart = firstAlignment.start + firstAlignment.lengthOnRef;\n this.connectingEnd = firstAlignment.mate.position;\n } else {\n this.start = firstAlignment.mate.position;\n this.scStart = this.start;\n this.connectingStart = firstAlignment.mate.position;\n this.connectingEnd = firstAlignment.start;\n }\n\n this.end = Math.max(firstAlignment.mate.position, firstAlignment.start + firstAlignment.lengthOnRef); // Approximate\n this.lengthOnRef = this.end - this.start;\n\n let scEnd = Math.max(this.end, firstAlignment.scStart + firstAlignment.scLengthOnRef);\n this.scLengthOnRef = scEnd - this.scStart;\n\n }\n\n setSecondAlignment(secondAlignment) {\n\n // TODO -- check the chrs are equal, error otherwise\n this.secondAlignment = secondAlignment;\n const firstAlignment = this.firstAlignment;\n\n if (secondAlignment.start > firstAlignment.start) {\n this.connectingEnd = secondAlignment.start;\n } else {\n this.connectingStart = secondAlignment.start + secondAlignment.lengthOnRef;\n }\n\n this.start = Math.min(firstAlignment.start, secondAlignment.start);\n this.end = Math.max(firstAlignment.start + firstAlignment.lengthOnRef, secondAlignment.start + secondAlignment.lengthOnRef);\n this.lengthOnRef = this.end - this.start;\n\n this.scStart = Math.min(firstAlignment.scStart, secondAlignment.scStart);\n const scEnd = Math.max(firstAlignment.scStart + firstAlignment.scLengthOnRef, secondAlignment.scStart + secondAlignment.scLengthOnRef);\n this.scLengthOnRef = scEnd - this.scStart;\n\n }\n\n containsLocation(genomicLocation, showSoftClips) {\n const s = showSoftClips ? this.scStart : this.start;\n const l = showSoftClips ? this.scLengthOnRef : this.lengthOnRef;\n return (genomicLocation >= s && genomicLocation <= (s + l))\n }\n\n alignmentContaining(genomicLocation, showSoftClips) {\n if (this.firstAlignment.containsLocation(genomicLocation, showSoftClips)) {\n return this.firstAlignment\n } else if (this.secondAlignment && this.secondAlignment.containsLocation(genomicLocation, showSoftClips)) {\n return this.secondAlignment\n } else {\n return undefined\n }\n }\n\n popupData(genomicLocation) {\n\n let nameValues = this.firstAlignment.popupData(genomicLocation);\n\n if (this.secondAlignment) {\n nameValues.push(\"-------------------------------\");\n nameValues = nameValues.concat(this.secondAlignment.popupData(genomicLocation));\n }\n return nameValues\n }\n\n isPaired() {\n return true // By definition\n }\n\n isMateMapped() {\n return true // By definition\n }\n\n isProperPair() {\n return this.firstAlignment.isProperPair()\n }\n\n get fragmentLength() {\n return Math.abs(this.firstAlignment.fragmentLength)\n }\n\n firstOfPairStrand() {\n\n if (this.firstAlignment.isFirstOfPair()) {\n return this.firstAlignment.strand\n } else if (this.secondAlignment && this.secondAlignment.isFirstOfPair()) {\n return this.secondAlignment.strand\n } else {\n return this.firstAlignment.mate.strand // Assumption is mate is first-of-pair\n }\n }\n\n hasTag(str) {\n return this.firstAlignment.hasTag(str) || (this.secondAlignment && this.secondAlignment.hasTag(str))\n }\n}\n\n/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2014 Broad Institute\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\nclass BamAlignmentRow {\n\n constructor() {\n\n this.alignments = [];\n this.score = undefined;\n }\n\n findAlignment(genomicLocation) {\n\n const alignmentContains = (a, genomicLocation) => {\n return genomicLocation >= a.start && genomicLocation < a.start + a.lengthOnRef\n };\n\n // find single alignment that overlaps sort location\n let centerAlignment;\n for (let i = 0; i < this.alignments.length; i++) {\n const a = this.alignments[i];\n if (genomicLocation >= a.start && genomicLocation < a.start + a.lengthOnRef) {\n if (a.paired) {\n if (a.firstAlignment && alignmentContains(a.firstAlignment, genomicLocation)) {\n centerAlignment = a.firstAlignment;\n } else if (a.secondAlignment && alignmentContains(a.secondAlignment, genomicLocation)) {\n centerAlignment = a.secondAlignment;\n }\n } else {\n centerAlignment = a;\n }\n break\n }\n }\n\n return centerAlignment\n\n }\n\n getSortValue({position, option, tag}, alignmentContainer) {\n\n if (!option) option = \"BASE\";\n\n const alignment = this.findAlignment(position);\n if (undefined === alignment) { // This condition should never occur\n return Number.MAX_VALUE\n }\n\n switch (option) {\n case \"NUCLEOTIDE\":\n case \"BASE\": {\n return calculateBaseScore(alignment, alignmentContainer, position)\n }\n case \"STRAND\":\n return alignment.strand ? 1 : -1\n case \"START\":\n return alignment.start\n case \"TAG\": {\n return alignment.tags()[tag]\n }\n case \"READ_NAME\":\n return alignment.readName\n case \"INSERT_SIZE\":\n return -Math.abs(alignment.fragmentLength)\n case \"GAP_SIZE\":\n return -alignment.gapSizeAt(position)\n case \"MATE_CHR\":\n return alignment.mate\n case \"MQ\":\n return alignment.mq === undefined ? Number.MAX_VALUE : -alignment.mq\n case \"ALIGNED_READ_LENGTH\":\n return -alignment.lengthOnRef\n default:\n return Number.MAX_VALUE\n }\n\n\n function calculateBaseScore(alignment, alignmentContainer, genomicLocation) {\n\n let reference;\n const idx = Math.floor(genomicLocation) - alignmentContainer.start;\n if (idx < alignmentContainer.sequence.length) {\n reference = alignmentContainer.sequence.charAt(idx);\n }\n if (!reference) {\n return 0\n }\n const base = alignment.readBaseAt(genomicLocation);\n const quality = alignment.readBaseQualityAt(genomicLocation);\n\n const coverageMap = alignmentContainer.coverageMap;\n const coverageMapIndex = Math.floor(genomicLocation - coverageMap.bpStart);\n const coverage = coverageMap.coverage[coverageMapIndex];\n\n // Insertions. These are additive with base scores as they occur between bases, so you can have a\n // base mismatch AND an insertion\n let baseScore = 0;\n if (alignment.insertions) {\n for (let ins of alignment.insertions) {\n if (ins.start === genomicLocation) {\n baseScore = -coverage.ins;\n }\n }\n }\n\n\n if (!base) {\n // Either deletion or skipped (splice junction)\n const delCount = coverage.del;\n if (delCount > 0) {\n baseScore -= delCount;\n } else if (baseScore === 0) { // Don't modify insertion score, if any\n baseScore = 1;\n }\n } else {\n reference = reference.toUpperCase();\n if ('N' === base && baseScore === 0) {\n baseScore = 2;\n } else if ((reference === base || '=' === base) && baseScore === 0) {\n baseScore = 4 - quality / 1000;\n } else if (\"X\" === base || reference !== base) {\n const count = coverage[\"pos\" + base] + coverage[\"neg\" + base];\n baseScore -= (count + (quality / 1000));\n }\n }\n\n\n return baseScore\n }\n }\n\n\n}\n\nconst alignmentSpace = 2;\n\nfunction canBePaired(alignment) {\n return alignment.isPaired() &&\n alignment.mate &&\n alignment.isMateMapped() &&\n alignment.chr === alignment.mate.chr &&\n (alignment.isFirstOfPair() || alignment.isSecondOfPair()) && !(alignment.isSecondary() || alignment.isSupplementary())\n}\n\n\nfunction pairAlignments(rows) {\n\n const pairCache = {};\n const result = [];\n\n for (let row of rows) {\n for (let alignment of row.alignments) {\n if (canBePaired(alignment)) {\n let pairedAlignment = pairCache[alignment.readName];\n if (pairedAlignment) {\n pairedAlignment.setSecondAlignment(alignment);\n pairCache[alignment.readName] = undefined; // Don't need to track this anymore.\n } else {\n pairedAlignment = new PairedAlignment(alignment);\n pairCache[alignment.readName] = pairedAlignment;\n result.push(pairedAlignment);\n }\n } else {\n result.push(alignment);\n }\n }\n }\n return result\n}\n\nfunction unpairAlignments(rows) {\n const result = [];\n for (let row of rows) {\n for (let alignment of row.alignments) {\n if (alignment instanceof PairedAlignment) {\n if (alignment.firstAlignment) result.push(alignment.firstAlignment); // shouldn't need the null test\n if (alignment.secondAlignment) result.push(alignment.secondAlignment);\n } else {\n result.push(alignment);\n }\n }\n }\n return result\n}\n\nfunction packAlignmentRows(alignments, start, end, showSoftClips) {\n\n //console.log(`packAlignmentRows ${start} ${end}`)\n //const t0 = Date.now()\n\n if (!alignments) {\n return undefined\n } else if (alignments.length === 0) {\n return []\n } else {\n alignments.sort(function (a, b) {\n return showSoftClips ? a.scStart - b.scStart : a.start - b.start\n });\n\n const packedAlignmentRows = [];\n let alignmentRow;\n let nextStart = 0;\n let nextIDX = 0;\n const allocated = new Set();\n const startNewRow = () => {\n alignmentRow = new BamAlignmentRow();\n packedAlignmentRows.push(alignmentRow);\n nextStart = 0;\n nextIDX = 0;\n allocated.clear();\n };\n startNewRow();\n\n while (alignments.length > 0) {\n if (nextIDX >= 0 && nextIDX < alignments.length) {\n const alignment = alignments[nextIDX];\n allocated.add(alignment);\n alignmentRow.alignments.push(alignment);\n nextStart = showSoftClips ?\n alignment.scStart + alignment.scLengthOnRef + alignmentSpace :\n alignment.start + alignment.lengthOnRef + alignmentSpace;\n nextIDX = binarySearch$1(alignments, (a) => (showSoftClips ? a.scStart : a.start) > nextStart, nextIDX);\n } else {\n // Remove allocated alignments and start new row\n alignments = alignments.filter(a => !allocated.has(a));\n startNewRow();\n }\n }\n //console.log(`Done in ${Date.now() - t0} ms`)\n return packedAlignmentRows\n }\n}\n\n\n/**\n * Return 0 <= i <= array.length such that !pred(array[i - 1]) && pred(array[i]).\n *\n * returns an index 0 ≤ i ≤ array.length such that the given predicate is false for array[i - 1] and true for array[i]* *\n */\nfunction binarySearch$1(array, pred, min) {\n let lo = min - 1, hi = array.length;\n while (1 + lo < hi) {\n const mi = lo + ((hi - lo) >> 1);\n if (pred(array[mi])) {\n hi = mi;\n } else {\n lo = mi;\n }\n }\n return hi\n}\n\n/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2016 University of California San Diego\n * Author: Jim Robinson\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\n\nclass AlignmentContainer {\n\n // this.config.samplingWindowSize, this.config.samplingDepth,\n // this.config.pairsSupported, this.config.alleleFreqThreshold)\n constructor(chr, start, end, {samplingWindowSize, samplingDepth, pairsSupported, alleleFreqThreshold}) {\n\n this.chr = chr;\n this.start = Math.floor(start);\n this.end = Math.ceil(end);\n this.length = (end - start);\n\n this.alleleFreqThreshold = alleleFreqThreshold === undefined ? 0.2 : alleleFreqThreshold;\n\n this.coverageMap = new CoverageMap(chr, start, end, this.alleleFreqThreshold);\n this.alignments = [];\n this.downsampledIntervals = [];\n\n this.samplingWindowSize = samplingWindowSize === undefined ? 100 : samplingWindowSize;\n this.samplingDepth = samplingDepth === undefined ? 1000 : samplingDepth;\n\n this.pairsSupported = pairsSupported === undefined ? true : pairsSupported;\n this.paired = false; // false until proven otherwise\n this.pairsCache = {}; // working cache of paired alignments by read name\n\n this.downsampledReads = new Set();\n\n this.currentBucket = new DownsampleBucket(this.start, this.start + this.samplingWindowSize, this);\n\n this.filter = function filter(alignment) { // TODO -- pass this in\n return alignment.isMapped() && !alignment.isFailsVendorQualityCheck()\n };\n\n }\n\n push(alignment) {\n\n if (this.filter(alignment) === false) return\n\n this.coverageMap.incCounts(alignment); // Count coverage before any downsampling\n\n if (this.pairsSupported && this.downsampledReads.has(alignment.readName)) {\n return // Mate already downsampled -- pairs are treated as a single alignment for downsampling\n }\n\n if (alignment.start >= this.currentBucket.end) {\n this.finishBucket();\n this.currentBucket = new DownsampleBucket(alignment.start, alignment.start + this.samplingWindowSize, this);\n }\n\n this.currentBucket.addAlignment(alignment);\n\n }\n\n forEach(callback) {\n this.alignments.forEach(callback);\n }\n\n finish() {\n\n if (this.currentBucket !== undefined) {\n this.finishBucket();\n }\n\n this.alignments.sort(function (a, b) {\n return a.start - b.start\n });\n\n this.pairsCache = undefined;\n this.downsampledReads = undefined;\n }\n\n contains(chr, start, end) {\n return this.chr === chr &&\n this.start <= start &&\n this.end >= end\n }\n\n hasDownsampledIntervals() {\n return this.downsampledIntervals && this.downsampledIntervals.length > 0\n }\n\n finishBucket() {\n this.alignments = this.alignments.concat(this.currentBucket.alignments);\n if (this.currentBucket.downsampledCount > 0) {\n this.downsampledIntervals.push(new DownsampledInterval(\n this.currentBucket.start,\n this.currentBucket.end,\n this.currentBucket.downsampledCount));\n }\n this.paired = this.paired || this.currentBucket.paired;\n }\n\n setViewAsPairs(bool) {\n let alignments;\n if (bool) {\n alignments = pairAlignments(this.packedAlignmentRows);\n } else {\n alignments = unpairAlignments(this.packedAlignmentRows);\n }\n this.packedAlignmentRows = packAlignmentRows(alignments, this.start, this.end);\n }\n\n setShowSoftClips(bool) {\n const alignments = this.allAlignments();\n this.packedAlignmentRows = packAlignmentRows(alignments, this.start, this.end, bool);\n }\n\n repack(bpPerPixel, showSoftClips) {\n const alignments = this.allAlignments();\n this.packedAlignmentRows = packAlignmentRows(alignments, this.start, this.end, showSoftClips);\n\n }\n\n allAlignments() {\n const alignments = [];\n for (let row of this.packedAlignmentRows) {\n for (let alignment of row.alignments) {\n alignments.push(alignment);\n }\n }\n return alignments\n }\n\n getMax(start, end) {\n return this.coverageMap.getMax(start, end)\n }\n\n sortRows(options) {\n\n const newRows = [];\n const undefinedRow = [];\n for (let row of this.packedAlignmentRows) {\n const alignment = row.findAlignment(options.position);\n if (undefined !== alignment) {\n newRows.push(row);\n } else {\n undefinedRow.push(row);\n }\n }\n\n newRows.sort((rowA, rowB) => {\n const direction = options.direction;\n const rowAValue = rowA.getSortValue(options, this);\n const rowBValue = rowB.getSortValue(options, this);\n\n if (rowBValue === undefined && rowBValue !== undefined) return 1\n else if (rowAValue !== undefined && rowBValue === undefined) return -1\n\n const i = rowAValue > rowBValue ? 1 : (rowAValue < rowBValue ? -1 : 0);\n return true === direction ? i : -i\n });\n\n for (let row of undefinedRow) {\n newRows.push(row);\n }\n\n this.packedAlignmentRows = newRows;\n }\n\n}\n\n\nclass DownsampleBucket {\n\n constructor(start, end, alignmentContainer) {\n\n this.start = start;\n this.end = end;\n this.alignments = [];\n this.downsampledCount = 0;\n this.samplingDepth = alignmentContainer.samplingDepth;\n this.pairsSupported = alignmentContainer.pairsSupported;\n this.downsampledReads = alignmentContainer.downsampledReads;\n this.pairsCache = alignmentContainer.pairsCache;\n }\n\n addAlignment(alignment) {\n\n var idx, replacedAlignment, pairedAlignment;\n\n if (this.pairsSupported && canBePaired(alignment)) {\n pairedAlignment = this.pairsCache[alignment.readName];\n if (pairedAlignment) {\n // Not subject to downsampling, just update the existing alignment\n pairedAlignment.setSecondAlignment(alignment);\n this.pairsCache[alignment.readName] = undefined; // Don't need to track this anymore. NOTE: Don't \"delete\", causes runtime performance issues\n return\n }\n }\n\n if (this.alignments.length < this.samplingDepth) {\n\n if (this.pairsSupported && canBePaired(alignment)) {\n\n // First alignment in a pair\n pairedAlignment = new PairedAlignment(alignment);\n this.paired = true;\n this.pairsCache[alignment.readName] = pairedAlignment;\n this.alignments.push(pairedAlignment);\n\n } else {\n this.alignments.push(alignment);\n }\n\n } else {\n\n idx = Math.floor(Math.random() * (this.samplingDepth + this.downsampledCount - 1));\n\n if (idx < this.samplingDepth) {\n\n // Keep the new item\n // idx = Math.floor(Math.random() * (this.alignments.length - 1));\n replacedAlignment = this.alignments[idx]; // To be replaced\n\n if (this.pairsSupported && canBePaired(alignment)) {\n\n if (this.pairsCache[replacedAlignment.readName] !== undefined) {\n this.pairsCache[replacedAlignment.readName] = undefined;\n }\n\n pairedAlignment = new PairedAlignment(alignment);\n this.paired = true;\n this.pairsCache[alignment.readName] = pairedAlignment;\n this.alignments[idx] = pairedAlignment;\n\n } else {\n this.alignments[idx] = alignment;\n }\n this.downsampledReads.add(replacedAlignment.readName);\n\n } else {\n this.downsampledReads.add(alignment.readName);\n }\n\n this.downsampledCount++;\n }\n\n\n }\n}\n\nclass CoverageMap {\n\n constructor(chr, start, end, alleleFreqThreshold) {\n\n this.chr = chr;\n this.bpStart = start;\n this.length = (end - start);\n\n this.coverage = new Array(this.length);\n this.maximum = 0;\n\n this.threshold = alleleFreqThreshold;\n this.qualityWeight = true;\n }\n\n /**\n * Return the maximum coverage value between start and end. This is used for autoscaling.\n * @param start\n * @param end\n */\n getMax(start, end) {\n let max = 0;\n const len = this.coverage.length;\n for (let i = 0; i < len; i++) {\n const pos = this.bpStart + i;\n if (pos > end) break\n const cov = this.coverage[i];\n if (pos >= start && cov) {\n max = Math.max(max, cov.total);\n }\n }\n return max\n }\n\n incCounts(alignment) {\n\n var self = this;\n\n if (alignment.blocks === undefined) {\n incBlockCount(alignment);\n } else {\n alignment.blocks.forEach(function (block) {\n incBlockCount(block);\n });\n }\n\n if (alignment.gaps) {\n for (let del of alignment.gaps) {\n if (del.type === 'D') {\n const offset = del.start - self.bpStart;\n for (let i = offset; i < offset + del.len; i++) {\n if (i < 0) continue\n if (!this.coverage[i]) {\n this.coverage[i] = new Coverage(self.threshold);\n }\n this.coverage[i].del++;\n }\n }\n }\n }\n\n if (alignment.insertions) {\n for (let del of alignment.insertions) {\n const i = del.start - this.bpStart;\n if (i < 0) continue\n if (!this.coverage[i]) {\n this.coverage[i] = new Coverage(self.threshold);\n }\n this.coverage[i].ins++;\n }\n }\n\n function incBlockCount(block) {\n\n if ('S' === block.type) return\n\n const seq = alignment.seq;\n const qual = alignment.qual;\n const seqOffset = block.seqOffset;\n\n for (let i = block.start - self.bpStart, j = 0; j < block.len; i++, j++) {\n\n if (!self.coverage[i]) {\n self.coverage[i] = new Coverage(self.threshold);\n }\n\n const base = (seq == undefined) ? \"N\" : seq.charAt(seqOffset + j);\n const key = (alignment.strand) ? \"pos\" + base : \"neg\" + base;\n const q = qual && seqOffset + j < qual.length ? qual[seqOffset + j] : 30;\n\n self.coverage[i][key] += 1;\n self.coverage[i][\"qual\" + base] += q;\n\n self.coverage[i].total += 1;\n self.coverage[i].qual += q;\n\n self.maximum = Math.max(self.coverage[i].total, self.maximum);\n\n }\n }\n }\n}\n\n\nclass Coverage {\n\n constructor(alleleThreshold) {\n\n this.qualityWeight = true;\n\n this.posA = 0;\n this.negA = 0;\n\n this.posT = 0;\n this.negT = 0;\n\n this.posC = 0;\n this.negC = 0;\n this.posG = 0;\n\n this.negG = 0;\n\n this.posN = 0;\n this.negN = 0;\n\n this.pos = 0;\n this.neg = 0;\n\n this.qualA = 0;\n this.qualT = 0;\n this.qualC = 0;\n this.qualG = 0;\n this.qualN = 0;\n\n this.qual = 0;\n\n this.total = 0;\n this.del = 0;\n this.ins = 0;\n\n this.threshold = alleleThreshold;\n }\n\n hoverText() {\n const pos = this.posA + this.posT + this.posC + this.posG + this.posN;\n const neg = this.negA + this.negT + this.negC + this.negG + this.negN;\n return `${this.total} (${pos}+, ${neg}-)`\n }\n\n isMismatch(refBase) {\n const threshold = this.threshold * ((this.qualityWeight && this.qual) ? this.qual : this.total);\n let mismatchQualitySum = 0;\n for (let base of [\"A\", \"T\", \"C\", \"G\"]) {\n if (base !== refBase) {\n mismatchQualitySum += ((this.qualityWeight && this.qual) ? this[\"qual\" + base] : (this[\"pos\" + base] + this[\"neg\" + base]));\n }\n }\n return mismatchQualitySum >= threshold\n }\n}\n\nclass DownsampledInterval {\n\n constructor(start, end, counts) {\n this.start = start;\n this.end = end;\n this.counts = counts;\n }\n\n popupData(genomicLocation) {\n return [\n {name: \"start\", value: this.start + 1},\n {name: \"end\", value: this.end},\n {name: \"# downsampled:\", value: this.counts}]\n }\n}\n\nclass SupplementaryAlignment {\n\n constructor(rec) {\n const tokens = rec.split(',');\n this.chr = tokens[0];\n this.start = parseInt(tokens[1]);\n this.strand = tokens[2].charAt(0);\n this.mapQ = parseInt(tokens[4]);\n this.numMismatches = parseInt(tokens[5]);\n this.lenOnRef = BamUtils.computeLengthOnReference(tokens[3]);\n }\n\n printString() {\n return this.chr + \":\" + numberFormatter$1(this.start) + \"-\" + numberFormatter$1(this.start + this.lenOnRef)\n + \" (\" + this.strand + \") = \" + numberFormatter$1(this.lenOnRef) + \"bp @MAPQ: \" + this.mapQ + \" NM: \" + this.numMismatches\n }\n}\n\nfunction createSupplementaryAlignments(str) {\n const tokens = str.split(';');\n return tokens.filter(t => t.length > 0).map(str => new SupplementaryAlignment(str))\n}\n\n/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2014 Broad Institute\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\nconst READ_PAIRED_FLAG = 0x1;\nconst PROPER_PAIR_FLAG = 0x2;\nconst READ_UNMAPPED_FLAG = 0x4;\nconst MATE_UNMAPPED_FLAG = 0x8;\nconst READ_STRAND_FLAG$2 = 0x10;\nconst MATE_STRAND_FLAG$2 = 0x20;\nconst FIRST_OF_PAIR_FLAG = 0x40;\nconst SECOND_OF_PAIR_FLAG = 0x80;\nconst SECONDARY_ALIGNMNET_FLAG = 0x100;\nconst READ_FAILS_VENDOR_QUALITY_CHECK_FLAG = 0x200;\nconst DUPLICATE_READ_FLAG = 0x400;\nconst SUPPLEMENTARY_ALIGNMENT_FLAG = 0x800;\nconst ELEMENT_SIZE = {\n c: 1,\n C: 1,\n s: 2,\n S: 2,\n i: 4,\n I: 4,\n f: 4\n};\n\nconst MAX_CIGAR = 50;\n\n/**\n * readName\n * chr\n * cigar\n * lengthOnRef\n * start\n * seq\n * qual\n * mq\n * strand\n * blocks\n */\n\nclass BamAlignment {\n\n constructor() {\n this.hidden = false;\n }\n\n isMapped() {\n return (this.flags & READ_UNMAPPED_FLAG) === 0\n }\n\n isPaired() {\n return (this.flags & READ_PAIRED_FLAG) !== 0\n }\n\n isProperPair() {\n return (this.flags & PROPER_PAIR_FLAG) !== 0\n }\n\n isFirstOfPair() {\n return (this.flags & FIRST_OF_PAIR_FLAG) !== 0\n }\n\n isSecondOfPair() {\n return (this.flags & SECOND_OF_PAIR_FLAG) !== 0\n }\n\n isSecondary() {\n return (this.flags & SECONDARY_ALIGNMNET_FLAG) !== 0\n }\n\n isSupplementary() {\n return (this.flags & SUPPLEMENTARY_ALIGNMENT_FLAG) !== 0\n }\n\n isFailsVendorQualityCheck() {\n return (this.flags & READ_FAILS_VENDOR_QUALITY_CHECK_FLAG) !== 0\n }\n\n isDuplicate() {\n return (this.flags & DUPLICATE_READ_FLAG) !== 0\n }\n\n isMateMapped() {\n return (this.flags & MATE_UNMAPPED_FLAG) === 0\n }\n\n isNegativeStrand() {\n return (this.flags & READ_STRAND_FLAG$2) !== 0\n }\n\n isMateNegativeStrand() {\n return (this.flags & MATE_STRAND_FLAG$2) !== 0\n }\n\n hasTag(tag) {\n const tmpTags = this.tagDict || decodeTags(this.tagBA);\n return tmpTags.hasOwnProperty(tag)\n }\n\n tags() {\n if (!this.tagDict) {\n if (this.tagBA) {\n this.tagDict = decodeTags(this.tagBA);\n this.tagBA = undefined;\n } else {\n this.tagDict = {}; // Mark so we don't try again. The record has no tags\n }\n }\n return this.tagDict\n }\n\n /**\n * Does alignment (or alignment extended by soft clips) contain the genomic location?\n *\n * @param genomicLocation\n * @param showSoftClips\n * @returns {boolean|boolean}\n */\n containsLocation(genomicLocation, showSoftClips) {\n const s = showSoftClips ? this.scStart : this.start;\n const l = showSoftClips ? this.scLengthOnRef : this.lengthOnRef;\n return (genomicLocation >= s && genomicLocation <= (s + l))\n }\n\n popupData(genomicLocation) {\n\n // if the user clicks on a base next to an insertion, show just the\n // inserted bases in a popup (like in desktop IGV).\n const nameValues = [];\n\n // Consert genomic location to int\n genomicLocation = Math.floor(genomicLocation);\n\n if (this.insertions) {\n\n const seq = this.seq;\n\n for (let insertion of this.insertions) {\n var ins_start = insertion.start;\n if (genomicLocation === ins_start || genomicLocation === ins_start - 1) {\n nameValues.push({name: 'Insertion', value: seq.substr(insertion.seqOffset, insertion.len)});\n nameValues.push({name: 'Location', value: ins_start});\n return nameValues\n }\n }\n }\n\n nameValues.push({name: 'Read Name', value: this.readName});\n\n // Sample\n // Read group\n nameValues.push('
');\n\n // Add 1 to genomic location to map from 0-based computer units to user-based units\n nameValues.push({name: 'Alignment Start', value: numberFormatter$1(1 + this.start), borderTop: true});\n nameValues.push({name: 'Read Strand', value: (true === this.strand ? '(+)' : '(-)'), borderTop: true});\n\n // Abbreviate long cigar strings, keeping the beginning and end to show cliping\n let cigar = this.cigar;\n if (cigar && cigar.length > MAX_CIGAR) {\n const half = MAX_CIGAR / 2;\n cigar = `${cigar.substring(0, half - 2)} ... ${cigar.substring(cigar.length - half + 2)}`;\n }\n nameValues.push({name: 'Cigar', value: cigar});\n\n nameValues.push({name: 'Mapping Quality', value: this.mq});\n nameValues.push({name: 'Secondary', value: yesNo(this.isSecondary())});\n nameValues.push({name: 'Supplementary', value: yesNo(this.isSupplementary())});\n nameValues.push({name: 'Duplicate', value: yesNo(this.isDuplicate())});\n nameValues.push({name: 'Failed QC', value: yesNo(this.isFailsVendorQualityCheck())});\n\n if (this.isPaired()) {\n nameValues.push('
');\n nameValues.push({name: 'First in Pair', value: !this.isSecondOfPair(), borderTop: true});\n nameValues.push({name: 'Mate is Mapped', value: yesNo(this.isMateMapped())});\n if (this.pairOrientation) {\n nameValues.push({name: 'Pair Orientation', value: this.pairOrientation});\n }\n if (this.isMateMapped()) {\n nameValues.push({name: 'Mate Chromosome', value: this.mate.chr});\n nameValues.push({name: 'Mate Start', value: (this.mate.position + 1)});\n nameValues.push({name: 'Mate Strand', value: (true === this.mate.strand ? '(+)' : '(-)')});\n nameValues.push({name: 'Insert Size', value: this.fragmentLength});\n // Mate Start\n // Mate Strand\n // Insert Size\n }\n // First in Pair\n // Pair Orientation\n\n }\n\n const tagDict = this.tags();\n\n if (tagDict.hasOwnProperty('SA')) {\n nameValues.push('
');\n nameValues.push({name: 'Supplementary Alignments', value: ''});\n const sa = createSupplementaryAlignments(tagDict['SA']);\n if (sa) {\n nameValues.push('
    ');\n for (let s of sa) {\n nameValues.push(`
  • ${s.printString()}
  • `);\n }\n nameValues.push('
');\n }\n }\n\n const hiddenTags = new Set(['SA', 'MD']);\n nameValues.push('
');\n for (let key in tagDict) {\n if (!hiddenTags.has(key)) {\n nameValues.push({name: key, value: tagDict[key]});\n }\n }\n\n nameValues.push({name: 'Hidden Tags', value: 'SA, MD'});\n\n nameValues.push('
');\n nameValues.push({name: 'Genomic Location: ', value: numberFormatter$1(1 + genomicLocation)});\n nameValues.push({name: 'Read Base:', value: this.readBaseAt(genomicLocation)});\n nameValues.push({name: 'Base Quality:', value: this.readBaseQualityAt(genomicLocation)});\n\n return nameValues\n\n\n function yesNo(bool) {\n return bool ? 'Yes' : 'No'\n }\n }\n\n readBaseAt(genomicLocation) {\n\n const block = blockAtGenomicLocation(this.blocks, genomicLocation);\n if (block) {\n if (\"*\" === this.seq) {\n return \"*\"\n } else {\n const idx = block.seqIndexAt(genomicLocation);\n // if (idx >= 0 && idx < this.seq.length) {\n return this.seq[idx]\n // }\n }\n } else {\n return undefined\n }\n }\n\n readBaseQualityAt(genomicLocation) {\n\n const block = blockAtGenomicLocation(this.blocks, genomicLocation);\n if (block) {\n if (\"*\" === this.qual) {\n return 30\n } else {\n const idx = block.seqIndexAt(genomicLocation);\n if (idx >= 0 && this.qual && idx < this.qual.length) {\n return this.qual[idx]\n } else {\n return 30\n }\n }\n } else {\n return undefined\n }\n }\n\n gapSizeAt(genomicLocation) {\n if (this.gaps) {\n for (let gap of this.gaps) {\n if (genomicLocation >= gap.start && genomicLocation < gap.start + gap.len) {\n return gap.len\n }\n }\n }\n return 0\n }\n\n /**\n * Return soft clipped blocks, if they exist, keyed by alignment end (left or right)\n */\n softClippedBlocks() {\n let left;\n let right;\n let interiorSeen;\n for(let b of this.blocks) {\n if('S' === b.type) {\n if(interiorSeen) {\n right = b;\n } else {\n left = b;\n }\n } else if('H' !== b.type) {\n interiorSeen = true;\n }\n }\n return {left, right}\n }\n\n}\n\nfunction blockAtGenomicLocation(blocks, genomicLocation) {\n\n for (let i = 0; i < blocks.length; i++) {\n const block = blocks[i];\n if (genomicLocation >= block.start && genomicLocation < block.start + block.len) {\n return block\n }\n }\n return undefined\n}\n\nfunction decodeTags(ba) {\n\n let p = 0;\n const len = ba.length;\n const tags = {};\n\n while (p < len) {\n const tag = String.fromCharCode(ba[p]) + String.fromCharCode(ba[p + 1]);\n p += 2;\n\n const type = String.fromCharCode(ba[p++]);\n let value;\n if (type === 'A') {\n value = String.fromCharCode(ba[p]);\n p++;\n } else if (type === 'i' || type === 'I') {\n value = readInt$1(ba, p);\n p += 4;\n } else if (type === 'c') {\n value = readInt8(ba, p);\n p++;\n } else if (type === 'C') {\n value = readUInt8(ba, p);\n p++;\n } else if (type === 's' || type === 'S') {\n value = readShort(ba, p);\n p += 2;\n } else if (type === 'f') {\n value = readFloat(ba, p);\n p += 4;\n } else if (type === 'Z') {\n value = '';\n for (; ;) {\n var cc = ba[p++];\n if (cc === 0) {\n break\n } else {\n value += String.fromCharCode(cc);\n }\n }\n } else if (type === 'B') {\n const elementType = String.fromCharCode(ba[p++]);\n let elementSize = ELEMENT_SIZE[elementType];\n if (elementSize === undefined) {\n tags[tag] = `Error: unknown element type '${elementType}'`;\n break\n }\n const numElements = readInt$1(ba, p);\n p += (4 + numElements * elementSize);\n value = '[not shown]';\n } else {\n //'Unknown type ' + type;\n value = 'Error unknown type: ' + type;\n tags[tag] = value;\n break\n }\n tags[tag] = value;\n }\n return tags\n}\n\n\nfunction readInt$1(ba, offset) {\n return (ba[offset + 3] << 24) | (ba[offset + 2] << 16) | (ba[offset + 1] << 8) | (ba[offset])\n}\n\nfunction readShort(ba, offset) {\n return (ba[offset + 1] << 8) | (ba[offset])\n}\n\nfunction readFloat(ba, offset) {\n const dataView = new DataView(ba.buffer);\n return dataView.getFloat32(offset)\n}\n\nfunction readInt8(ba, offset) {\n const dataView = new DataView(ba.buffer);\n return dataView.getInt8(offset)\n}\n\nfunction readUInt8(ba, offset) {\n const dataView = new DataView(ba.buffer);\n return dataView.getUint8(offset)\n}\n\n/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2016-2017 The Regents of the University of California\n * Author: Jim Robinson\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\n/**\n * Created by jrobinso on 4/5/18.\n */\n\n\nclass AlignmentBlock {\n constructor(b) {\n if (b) {\n Object.assign(this, b);\n }\n }\n\n seqIndexAt(genomicLocation) {\n return Math.floor(genomicLocation) - this.start + this.seqOffset\n }\n}\n\nclass BamFilter {\n constructor(options) {\n if (!options) options = {};\n this.vendorFailed = options.vendorFailed === undefined ? true : options.vendorFailed;\n this.duplicates = options.duplicates === undefined ? true : options.duplicates;\n this.secondary = options.secondary || false;\n this.supplementary = options.supplementary || false;\n this.mqThreshold = options.mqThreshold === undefined ? 0 : options.mqThreshold;\n if (options.readgroups) {\n this.readgroups = new Set(options.readgroups);\n }\n }\n\n pass(alignment) {\n if (this.vendorFailed && alignment.isFailsVendorQualityCheck()) return false\n if (this.duplicates && alignment.isDuplicate()) return false\n if (this.secondary && alignment.isSecondary()) return false\n if (this.supplementary && alignment.isSupplementary()) return false\n if (alignment.mq < this.mqThreshold) return false\n if (this.readgroups) {\n var rg = alignment.tags()['RG'];\n return this.readgroups.has(rg)\n }\n return true\n }\n}\n\n/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2016-2017 The Regents of the University of California\n * Author: Jim Robinson\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\n\n/**\n * This code is based on the Biodalliance BAM reader by Thomas Down, 2011\n *\n * https://github.com/dasmoth/dalliance/blob/master/js/bam.js\n */\n\nconst SEQ_DECODER = ['=', 'A', 'C', 'x', 'G', 'x', 'x', 'x', 'T', 'x', 'x', 'x', 'x', 'x', 'x', 'N'];\nconst CIGAR_DECODER = ['M', 'I', 'D', 'N', 'S', 'H', 'P', '=', 'X', '?', '?', '?', '?', '?', '?', '?'];\nconst READ_STRAND_FLAG$1 = 0x10;\nconst MATE_STRAND_FLAG$1 = 0x20;\n\nconst BAM1_MAGIC_BYTES = new Uint8Array([0x42, 0x41, 0x4d, 0x01]); // BAM\\1\nconst BAM1_MAGIC_NUMBER = readInt(BAM1_MAGIC_BYTES, 0);\n\nconst DEFAULT_ALLELE_FREQ_THRESHOLD = 0.2;\nconst DEFAULT_SAMPLING_WINDOW_SIZE = 100;\nconst DEFAULT_SAMPLING_DEPTH = 500;\nconst MAXIMUM_SAMPLING_DEPTH = 10000;\n\nconst BamUtils = {\n\n readHeader: function (url, options, genome) {\n\n return igvxhr.loadArrayBuffer(url, options)\n\n .then(function (compressedBuffer) {\n\n var header, unc, uncba;\n\n unc = unbgzf(compressedBuffer);\n uncba = unc;\n\n header = BamUtils.decodeBamHeader(uncba, genome);\n\n return header\n\n })\n\n },\n\n /**\n *\n * @param ba bytes to decode as a UInt8Array\n * @param genome optional igv genome object\n * @returns {{ magicNumer: number, size: number, chrNames: Array, chrToIndex: ({}|*), chrAliasTable: ({}|*) }}\n */\n decodeBamHeader: function (ba, genome) {\n\n var magic, samHeaderLen, samHeader, chrToIndex, chrNames, chrAliasTable, alias;\n\n magic = readInt(ba, 0);\n if (magic !== BAM1_MAGIC_NUMBER) {\n throw new Error('BAM header errror: bad magic number. This could be caused by either a corrupt or missing file.')\n }\n\n samHeaderLen = readInt(ba, 4);\n samHeader = '';\n\n for (var i = 0; i < samHeaderLen; ++i) {\n samHeader += String.fromCharCode(ba[i + 8]);\n }\n\n var nRef = readInt(ba, samHeaderLen + 8);\n var p = samHeaderLen + 12;\n\n chrToIndex = {};\n chrNames = [];\n chrAliasTable = {};\n\n for (i = 0; i < nRef; ++i) {\n var lName = readInt(ba, p);\n var name = '';\n for (var j = 0; j < lName - 1; ++j) {\n name += String.fromCharCode(ba[p + 4 + j]);\n }\n readInt(ba, p + lName + 4);\n //dlog(name + ': ' + lRef);\n\n chrToIndex[name] = i;\n chrNames[i] = name;\n\n if (genome) {\n alias = genome.getChromosomeName(name);\n chrAliasTable[alias] = name;\n }\n\n p = p + 8 + lName;\n }\n\n return {\n magicNumber: magic,\n size: p,\n chrNames: chrNames,\n chrToIndex: chrToIndex,\n chrAliasTable: chrAliasTable\n }\n\n },\n\n bam_tag2cigar: function (ba, block_end, seq_offset, lseq, al, cigarArray) {\n\n function type2size(x) {\n if (x === 'C' || x === 'c' || x === 'A') return 1\n else if (x === 'S' || x === 's') return 2\n else if (x === 'I' || x === 'i' || x === 'f') return 4\n else return 0\n }\n\n // test if the real CIGAR is encoded in a CG:B,I tag\n if (cigarArray.length !== 1 || al.start < 0) return false\n var p = seq_offset + ((lseq + 1) >> 1) + lseq;\n while (p + 4 < block_end) {\n var tag = String.fromCharCode(ba[p]) + String.fromCharCode(ba[p + 1]);\n if (tag === 'CG') break\n var type = String.fromCharCode(ba[p + 2]);\n if (type === 'B') { // the binary array type\n type = String.fromCharCode(ba[p + 3]);\n var size = type2size(type);\n var len = readInt(ba, p + 4);\n p += 8 + size * len;\n } else if (type === 'Z' || type === 'H') { // 0-terminated string\n p += 3;\n while (ba[p++] !== 0) {\n }\n } else { // other atomic types\n p += 3 + type2size(type);\n }\n }\n if (p >= block_end) return false // no CG tag\n if (String.fromCharCode(ba[p + 2]) !== 'B' || String.fromCharCode(ba[p + 3]) !== 'I') return false // not of type B,I\n\n // now we know the real CIGAR length and its offset in the binary array\n var cigar_len = readInt(ba, p + 4);\n var cigar_offset = p + 8; // 4 for \"CGBI\" and 4 for length\n if (cigar_offset + cigar_len * 4 > block_end) return false // out of bound\n\n // decode CIGAR\n var cigar = '';\n var lengthOnRef = 0;\n cigarArray.length = 0; // empty the old array\n p = cigar_offset;\n for (var k = 0; k < cigar_len; ++k, p += 4) {\n var cigop = readInt(ba, p);\n var opLen = (cigop >> 4);\n var opLtr = CIGAR_DECODER[cigop & 0xf];\n if (opLtr === 'M' || opLtr === 'EQ' || opLtr === 'X' || opLtr === 'D' || opLtr === 'N' || opLtr === '=')\n lengthOnRef += opLen;\n cigar = cigar + opLen + opLtr;\n cigarArray.push({len: opLen, ltr: opLtr});\n }\n\n // update alignment record. We are not updating bin, as apparently it is not used.\n al.cigar = cigar;\n al.lengthOnRef = lengthOnRef;\n return true\n },\n\n /**\n *\n * @param ba bytes to decode as an UInt8Array\n * @param offset offset position of ba array to start decoding\n * @param alignmentContainer container to receive the decoded alignments\n * @param min minimum genomic position\n * @param max maximum genomic position\n * @param chrIdx chromosome index\n * @param chrNames array of chromosome names\n * @param filter a BamFilter object\n *\n * @return true if we have moved beyond the right end of the genomic range.\n */\n decodeBamRecords: function (ba, offset, alignmentContainer, chrNames, chrIdx, min, max, filter) {\n\n while (offset < ba.length) {\n\n const blockSize = readInt(ba, offset);\n const blockEnd = offset + blockSize + 4;\n const alignment = new BamAlignment();\n const refID = readInt(ba, offset + 4);\n const pos = readInt(ba, offset + 8);\n\n if (blockEnd > ba.length) {\n return\n }\n if (refID < 0) {\n offset = blockEnd;\n continue // unmapped read\n } else if (chrIdx !== undefined && (refID > chrIdx || pos > max)) {\n return true // off right edge, we're done\n } else if (chrIdx !== undefined && (refID < chrIdx)) {\n offset = blockEnd;\n continue // ref ID to left of start, not sure this is possible\n }\n\n const bin_mq_nl = readInt(ba, offset + 12);\n const mq = (bin_mq_nl & 0xff00) >> 8;\n const nl = bin_mq_nl & 0xff;\n\n const flag_nc = readInt(ba, offset + 16);\n const flag = (flag_nc & 0xffff0000) >> 16;\n const nc = flag_nc & 0xffff;\n\n const lseq = readInt(ba, offset + 20);\n const mateChrIdx = readInt(ba, offset + 24);\n const matePos = readInt(ba, offset + 28);\n const fragmentLength = readInt(ba, offset + 32);\n\n let readName = [];\n for (let j = 0; j < nl - 1; ++j) {\n readName.push(String.fromCharCode(ba[offset + 36 + j]));\n }\n readName = readName.join('');\n\n let lengthOnRef = 0;\n let cigar = '';\n let p = offset + 36 + nl;\n const cigarArray = [];\n // concatenate M,=,EQ,and X\n\n let lastCigRecord;\n for (let c = 0; c < nc; ++c) {\n var cigop = readInt(ba, p);\n var opLen = (cigop >> 4);\n var opLtr = CIGAR_DECODER[cigop & 0xf];\n if (opLtr === 'M' || opLtr === 'EQ' || opLtr === 'X' || opLtr === 'D' || opLtr === 'N' || opLtr === '=')\n lengthOnRef += opLen;\n cigar = cigar + opLen + opLtr;\n p += 4;\n\n // if(mOperators.has(opLtr) && mOperators.has(lastCigRecord.ltr)) {\n // lastCigRecord.len += opLen;\n // lastCigRecord.ltr = 'M'\n // }\n // else {\n lastCigRecord = {len: opLen, ltr: opLtr};\n cigarArray.push(lastCigRecord);\n //}\n }\n\n alignment.chr = chrNames[refID];\n alignment.start = pos;\n alignment.flags = flag;\n alignment.strand = !(flag & READ_STRAND_FLAG$1);\n alignment.readName = readName;\n alignment.cigar = cigar;\n alignment.lengthOnRef = lengthOnRef;\n alignment.fragmentLength = fragmentLength;\n alignment.mq = mq;\n\n BamUtils.bam_tag2cigar(ba, blockEnd, p, lseq, alignment, cigarArray);\n\n alignment.end = alignment.start + alignment.lengthOnRef;\n\n if (alignment.end < min) {\n offset = blockEnd;\n continue\n } // Record out-of-range \"to the left\", skip to next one\n\n\n let seq = [];\n const seqBytes = (lseq + 1) >> 1;\n for (let j = 0; j < seqBytes; ++j) {\n var sb = ba[p + j];\n seq.push(SEQ_DECODER[(sb & 0xf0) >> 4]);\n seq.push(SEQ_DECODER[(sb & 0x0f)]);\n }\n seq = seq.slice(0, lseq).join(''); // seq might have one extra character (if lseq is an odd number)\n p += seqBytes;\n\n\n const qualArray = [];\n for (let j = 0; j < lseq; ++j) {\n qualArray.push(ba[p + j]);\n }\n p += lseq;\n\n if (mateChrIdx >= 0) {\n alignment.mate = {\n chr: chrNames[mateChrIdx],\n position: matePos,\n strand: !(flag & MATE_STRAND_FLAG$1)\n };\n }\n\n alignment.seq = seq;\n alignment.qual = qualArray;\n alignment.tagBA = new Uint8Array(ba.buffer.slice(p, blockEnd)); // decode these on demand\n\n this.setPairOrientation(alignment);\n\n if ((undefined === filter || filter.pass(alignment))) {\n makeBlocks(alignment, cigarArray);\n alignmentContainer.push(alignment);\n }\n offset = blockEnd;\n }\n },\n\n decodeSamRecords: function (sam, alignmentContainer, chr, min, max, filter) {\n\n var lines, i, j, len, tokens, qualString, rnext, lengthOnRef,\n alignment, cigarArray, started;\n\n lines = splitLines$5(sam);\n len = lines.length;\n started = false;\n\n for (i = 0; i < len; i++) {\n\n tokens = lines[i].split('\\t');\n\n alignment = new BamAlignment();\n\n alignment.chr = tokens[2];\n alignment.start = Number.parseInt(tokens[3]) - 1;\n alignment.flags = Number.parseInt(tokens[1]);\n alignment.readName = tokens[0];\n alignment.strand = !(alignment.flags & READ_STRAND_FLAG$1);\n alignment.mq = Number.parseInt(tokens[4]);\n alignment.cigar = tokens[5];\n alignment.fragmentLength = Number.parseInt(tokens[8]);\n alignment.seq = tokens[9];\n\n if (alignment.chr === '*' || !alignment.isMapped()) continue // Unmapped\n\n if (alignment.chr !== chr) {\n if (started) break // Off the right edge, we're done\n else continue // Possibly to the left, skip but keep looping\n } else if (alignment.start > max) {\n break // off right edge, we're done\n }\n\n lengthOnRef = 0;\n cigarArray = buildOperators(alignment.cigar);\n cigarArray.forEach(function (op) {\n var opLen = op.len;\n var opLtr = op.ltr;\n if (opLtr === 'M' || opLtr === 'EQ' || opLtr === 'X' || opLtr === 'D' || opLtr === 'N' || opLtr === '=')\n lengthOnRef += opLen;\n });\n alignment.lengthOnRef = lengthOnRef;\n // TODO for lh3: parse the CG:B,I tag in SAM here\n\n if (alignment.start + lengthOnRef < min) {\n continue // To the left, skip and continue\n }\n\n\n qualString = tokens[10];\n alignment.qual = [];\n for (j = 0; j < qualString.length; j++) {\n alignment.qual[j] = qualString.charCodeAt(j) - 33;\n }\n alignment.tagDict = tokens.length < 11 ? {} : decodeSamTags(tokens.slice(11));\n\n if (alignment.isMateMapped()) {\n rnext = tokens[6];\n alignment.mate = {\n chr: (rnext === '=') ? alignment.chr : rnext,\n position: Number.parseInt(tokens[7]),\n strand: !(alignment.flags & MATE_STRAND_FLAG$1)\n };\n }\n\n this.setPairOrientation(alignment);\n\n if (undefined === filter || filter.pass(alignment)) {\n makeBlocks(alignment, cigarArray);\n alignmentContainer.push(alignment);\n }\n }\n },\n\n setReaderDefaults: function (reader, config) {\n\n reader.filter = new BamFilter(config.filter);\n\n if (config.readgroup) {\n reader.filter.readgroups = new Set([config.readgroup]);\n }\n\n reader.alleleFreqThreshold = config.alleleFreqThreshold === undefined ? DEFAULT_ALLELE_FREQ_THRESHOLD : config.alleleFreqThreshold;\n\n reader.samplingWindowSize = config.samplingWindowSize === undefined ? DEFAULT_SAMPLING_WINDOW_SIZE : config.samplingWindowSize;\n reader.samplingDepth = config.samplingDepth === undefined ? DEFAULT_SAMPLING_DEPTH : config.samplingDepth;\n\n if (reader.samplingDepth > MAXIMUM_SAMPLING_DEPTH) {\n console.log(\"Warning: attempt to set sampling depth > maximum value of \" + MAXIMUM_SAMPLING_DEPTH);\n reader.samplingDepth = MAXIMUM_SAMPLING_DEPTH;\n }\n\n if (config.viewAsPairs) {\n reader.pairsSupported = true;\n } else {\n reader.pairsSupported = config.pairsSupported === undefined ? true : config.pairsSupported;\n }\n },\n\n setPairOrientation: function (alignment) {\n\n if (alignment.isMapped() && alignment.mate && alignment.isMateMapped() && alignment.mate.chr === alignment.chr) {\n var s1 = alignment.strand ? 'F' : 'R';\n\n var mate = alignment.mate;\n var s2 = mate.strand ? 'F' : 'R';\n var o1 = ' ';\n var o2 = ' ';\n if (alignment.isFirstOfPair()) {\n o1 = '1';\n o2 = '2';\n } else if (alignment.isSecondOfPair()) {\n o1 = '2';\n o2 = '1';\n }\n\n var tmp = [];\n var isize = alignment.fragmentLength;\n var estReadLen = alignment.end - alignment.start;\n if (isize === 0) {\n //isize not recorded. Need to estimate. This calculation was validated against an Illumina\n // -> <- library bam.\n var estMateEnd = alignment.start < mate.position ?\n mate.position + estReadLen : mate.position - estReadLen;\n isize = estMateEnd - alignment.start;\n }\n\n //if (isize > estReadLen) {\n if (isize > 0) {\n tmp[0] = s1;\n tmp[1] = o1;\n tmp[2] = s2;\n tmp[3] = o2;\n\n } else {\n tmp[2] = s1;\n tmp[3] = o1;\n tmp[0] = s2;\n tmp[1] = o2;\n }\n // }\n alignment.pairOrientation = tmp.join('');\n }\n },\n\n computeLengthOnReference: function (cigarString) {\n\n let len = 0;\n let buf = '';\n\n for (let i = 0; i < cigarString.length; i++) {\n const c = cigarString.charCodeAt(i);\n if (c > 47 && c < 58) {\n buf += cigarString.charAt(i);\n } else {\n switch (c) {\n case 78: // N\n case 68: // D\n case 77: // M\n case 61: // =\n case 88: // X\n len += parseInt(buf.toString());\n }\n buf = '';\n }\n }\n return len\n }\n};\n\n\n/**\n * Split the alignment record into blocks as specified in the cigarArray. Each aligned block contains\n * its portion of the read sequence and base quality strings. A read sequence or base quality string\n * of \"*\" indicates the value is not recorded. In all other cases the length of the block sequence (block.seq)\n * and quality string (block.qual) must == the block length.\n *\n * @param alignment\n * @param cigarArray\n * @returns array of blocks\n */\nfunction makeBlocks(alignment, cigarArray) {\n\n const blocks = [];\n\n let insertions;\n let gaps;\n let seqOffset = 0;\n let pos = alignment.start;\n\n alignment.scStart = alignment.start;\n alignment.scLengthOnRef = alignment.lengthOnRef;\n\n for (let c of cigarArray) {\n\n let scPos;\n switch (c.ltr) {\n case 'H' :\n break // ignore hard clips\n case 'P' :\n break // ignore pads\n case 'S' :\n\n scPos = pos;\n alignment.scLengthOnRef += c.len;\n if (blocks.length === 0) {\n alignment.scStart -= c.len;\n scPos -= c.len;\n }\n blocks.push(new AlignmentBlock({\n start: scPos,\n seqOffset: seqOffset,\n len: c.len,\n type: 'S'\n }));\n seqOffset += c.len;\n break // soft clip read bases\n case 'N' :\n case 'D':\n if (gaps === undefined) {\n gaps = [];\n }\n gaps.push({\n start: pos,\n len: c.len,\n type: c.ltr\n });\n pos += c.len;\n break\n case 'I' :\n\n if (insertions === undefined) {\n insertions = [];\n }\n insertions.push(new AlignmentBlock({\n start: pos,\n len: c.len,\n seqOffset: seqOffset,\n type: 'I'\n }));\n seqOffset += c.len;\n break\n case 'M' :\n case 'EQ' :\n case '=' :\n case 'X' :\n blocks.push(new AlignmentBlock({\n start: pos,\n seqOffset: seqOffset,\n len: c.len,\n type: 'M'\n }));\n seqOffset += c.len;\n pos += c.len;\n\n break\n\n default :\n console.log('Error processing cigar element: ' + c.len + c.ltr);\n }\n }\n\n alignment.blocks = blocks;\n alignment.insertions = insertions;\n alignment.gaps = gaps;\n\n}\n\nfunction readInt(ba, offset) {\n return (ba[offset + 3] << 24) | (ba[offset + 2] << 16) | (ba[offset + 1] << 8) | (ba[offset])\n}\n\n/**\n * Build a list of cigar operators from a cigarString. Removes padding operators and concatenates consecutive\n * operators of the same type\n *\n * @param cigarString\n * @return\n */\nfunction buildOperators(cigarString) {\n\n var operators, buffer, i, len, prevOp, next, op, nBases;\n\n operators = [];\n buffer = [];\n\n // Create list of cigar operators\n prevOp = null;\n len = cigarString.length;\n for (i = 0; i < len; i++) {\n next = cigarString.charAt(i);\n if (isDigit(next)) {\n buffer.push(next);\n } else {\n op = next;\n nBases = Number.parseInt(buffer.join(''));\n buffer = [];\n\n if (prevOp !== null && prevOp.ltr === op) {\n prevOp.len += nBases;\n } else {\n prevOp = {len: nBases, ltr: op};\n operators.push(prevOp);\n }\n }\n }\n return operators\n\n}\n\nfunction isDigit(a) {\n var charCode = a.charCodeAt(0);\n return (charCode >= 48 && charCode <= 57) // 0-9\n}\n\nfunction decodeSamTags(tags) {\n\n var tagDict = {};\n tags.forEach(function (tag) {\n var tokens = tag.split(':');\n tagDict[tokens[0]] = tokens[2];\n });\n\n return tagDict\n}\n\n/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2016-2017 The Regents of the University of California\n * Author: Jim Robinson\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\n/**\n * Class for reading a bam file\n *\n * @param config\n * @constructor\n */\nclass BamReaderNonIndexed {\n\n constructor(config, genome) {\n this.config = config;\n this.genome = genome;\n this.bamPath = config.url;\n this.isDataUri = isDataURL(config.url);\n BamUtils.setReaderDefaults(this, config);\n }\n\n // Return an alignment container\n async readAlignments(chr, bpStart, bpEnd) {\n\n if (this.alignmentCache) {\n const header = this.header;\n const queryChr = header.chrAliasTable.hasOwnProperty(chr) ? header.chrAliasTable[chr] : chr;\n const qAlignments = this.alignmentCache.queryFeatures(queryChr, bpStart, bpEnd);\n const alignmentContainer = new AlignmentContainer(chr, bpStart, bpEnd, this.config);\n for (let a of qAlignments) {\n alignmentContainer.push(a);\n }\n alignmentContainer.finish();\n return alignmentContainer\n\n } else {\n if (this.isDataUri) {\n const data = decodeDataURI(this.bamPath);\n const unc = unbgzf(data.buffer);\n this.parseAlignments(unc);\n return this.fetchAlignments(chr, bpStart, bpEnd)\n } else {\n const arrayBuffer = await igvxhr.loadArrayBuffer(this.bamPath, buildOptions(this.config));\n const unc = unbgzf(arrayBuffer);\n this.parseAlignments(unc);\n return this.fetchAlignments(chr, bpStart, bpEnd)\n }\n }\n\n }\n\n parseAlignments(data) {\n const alignments = [];\n this.header = BamUtils.decodeBamHeader(data);\n BamUtils.decodeBamRecords(data, this.header.size, alignments, this.header.chrNames);\n this.alignmentCache = new FeatureCache$1(alignments, this.genome);\n }\n\n fetchAlignments(chr, bpStart, bpEnd) {\n const queryChr = this.header.chrAliasTable.hasOwnProperty(chr) ? this.header.chrAliasTable[chr] : chr;\n const features = this.alignmentCache.queryFeatures(queryChr, bpStart, bpEnd);\n const alignmentContainer = new AlignmentContainer(chr, bpStart, bpEnd, this.config);\n for (let feature of features) {\n alignmentContainer.push(feature);\n }\n alignmentContainer.finish();\n return alignmentContainer\n }\n\n}\n\nfunction decodeDataURI(dataURI) {\n\n const split = dataURI.split(',');\n const info = split[0].split(':')[1];\n let dataString = split[1];\n\n if (info.indexOf('base64') >= 0) {\n dataString = atob(dataString);\n } else {\n dataString = decodeURI(dataString);\n }\n\n const bytes = new Uint8Array(dataString.length);\n for (var i = 0; i < dataString.length; i++) {\n bytes[i] = dataString.charCodeAt(i);\n }\n return bytes\n}\n\n/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2016-2017 The Regents of the University of California\n * Author: Jim Robinson\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\n/**\n * Class for reading a bam file\n *\n * @param config\n * @constructor\n */\nclass BamReader {\n\n constructor(config, genome) {\n this.config = config;\n this.genome = genome;\n this.bamPath = config.url;\n this.baiPath = config.indexURL;\n BamUtils.setReaderDefaults(this, config);\n\n this._blockLoader = new BGZBlockLoader(config);\n }\n\n async readAlignments(chr, bpStart, bpEnd) {\n\n const chrToIndex = await this.getChrIndex();\n const queryChr = this.chrAliasTable.hasOwnProperty(chr) ? this.chrAliasTable[chr] : chr;\n const chrId = chrToIndex[queryChr];\n const alignmentContainer = new AlignmentContainer(chr, bpStart, bpEnd, this.config);\n\n if (chrId === undefined) {\n return alignmentContainer\n\n } else {\n\n const bamIndex = await this.getIndex();\n const chunks = bamIndex.chunksForRange(chrId, bpStart, bpEnd);\n\n if (!chunks || chunks.length === 0) {\n return alignmentContainer\n }\n\n for (let c of chunks) {\n const ba = await this._blockLoader.getData(c.minv, c.maxv);\n const done = BamUtils.decodeBamRecords(ba, c.minv.offset, alignmentContainer, this.indexToChr, chrId, bpStart, bpEnd, this.filter);\n if (done) {\n break\n }\n }\n alignmentContainer.finish();\n return alignmentContainer\n }\n }\n\n async getHeader() {\n if (!this.header) {\n const genome = this.genome;\n const index = await this.getIndex();\n let len;\n if (index.firstBlockPosition) {\n const bsizeOptions = buildOptions(this.config, {range: {start: index.firstBlockPosition, size: 26}});\n const abuffer = await igvxhr.loadArrayBuffer(this.bamPath, bsizeOptions);\n const bsize = bgzBlockSize$1(abuffer);\n len = index.firstBlockPosition + bsize; // Insure we get the complete compressed block containing the header\n } else {\n len = 64000;\n }\n\n const options = buildOptions(this.config, {range: {start: 0, size: len}});\n this.header = await BamUtils.readHeader(this.bamPath, options, genome);\n }\n return this.header\n }\n\n async getIndex() {\n const genome = this.genome;\n if (!this.index) {\n this.index = await loadIndex(this.baiPath, this.config, genome);\n }\n return this.index\n }\n\n async getChrIndex() {\n if (this.chrToIndex) {\n return this.chrToIndex\n } else {\n const header = await this.getHeader();\n this.chrToIndex = header.chrToIndex;\n this.indexToChr = header.chrNames;\n this.chrAliasTable = header.chrAliasTable;\n return this.chrToIndex\n\n }\n }\n}\n\n/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2016-2017 The Regents of the University of California\n * Author: Jim Robinson\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\nclass ShardedBamReader {\n\n constructor(config, genome) {\n\n this.config = config;\n this.genome = genome;\n\n const bamReaders = {};\n\n config.sources.sequences.forEach(function (chr) {\n const queryChr = genome ? genome.getChromosomeName(chr) : chr;\n bamReaders[queryChr] = getReader(config, genome, chr);\n });\n\n this.bamReaders = bamReaders;\n\n BamUtils.setReaderDefaults(this, config);\n }\n\n async readAlignments(chr, start, end) {\n\n if (!this.bamReaders.hasOwnProperty(chr)) {\n return new AlignmentContainer(chr, start, end, this.config)\n } else {\n\n let reader = this.bamReaders[chr];\n const a = await reader.readAlignments(chr, start, end);\n return a\n }\n }\n}\n\nfunction getReader(config, genome, chr) {\n const tmp = {\n url: config.sources.url.replace(\"$CHR\", chr)\n };\n if (config.sources.indexURL) {\n tmp.indexURL = config.sources.indexURL.replace(\"$CHR\", chr);\n }\n const bamConfig = Object.assign(config, tmp);\n\n // TODO -- support non-indexed, htsget, etc\n return new BamReader(bamConfig, genome)\n}\n\n/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2016-2017 The Regents of the University of California\n * Author: Jim Robinson\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\n/**\n * Class for reading bam records from an igv.js-flask server backed by pysam. Deprecated.\n *\n * @param config\n * @constructor\n */\nconst BamWebserviceReader = function (config, genome) {\n\n this.config = config;\n this.genome = genome;\n BamUtils.setReaderDefaults(this, config);\n\n};\n\n// Example http://localhost:5000/alignments/?reference=/Users/jrobinso/hg19mini.fa&file=/Users/jrobinso/cram_with_crai_index.cram®ion=1:100-2000\n\nBamWebserviceReader.prototype.readAlignments = function (chr, bpStart, bpEnd) {\n\n var self = this;\n\n return getHeader.call(self)\n\n .then(function (header) {\n\n var queryChr, url;\n\n queryChr = header.chrAliasTable.hasOwnProperty(chr) ? header.chrAliasTable[chr] : chr;\n\n url = self.config.url +\n \"?reference=\" + self.config.referenceFile +\n \"&file=\" + self.config.alignmentFile + \"\" +\n \"®ion=\" + queryChr + \":\" + bpStart + \"-\" + bpEnd;\n\n\n return igvxhr.loadString(url, buildOptions(self.config))\n\n .then(function (sam) {\n\n var alignmentContainer;\n\n header.chrToIndex[queryChr];\n\n alignmentContainer = new AlignmentContainer(chr, bpStart, bpEnd, self.config);\n\n BamUtils.decodeSamRecords(sam, alignmentContainer, queryChr, bpStart, bpEnd, self.filter);\n\n return alignmentContainer\n\n })\n\n })\n};\n\n\n// Example http://localhost:5000/alignments/?reference=/Users/jrobinso/hg19mini.fa&file=/Users/jrobinso/cram_with_crai_index.cram&options=-b%20-H\nfunction getHeader() {\n\n const self = this;\n const genome = this.genome;\n\n if (this.header) {\n\n return Promise.resolve(this.header)\n\n } else {\n\n const url = this.config.url + \"?file=\" + this.config.alignmentFile + \"&options=-b,-H\";\n const options = buildOptions(this.config);\n\n return BamUtils.readHeader(url, options, genome)\n\n .then(function (header) {\n\n self.header = header;\n return header\n\n })\n }\n\n}\n\n/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2016-2017 The Regents of the University of California\n * Author: Jim Robinson\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\nclass HtsgetBamReader extends HtsgetReader {\n\n constructor(config, genome) {\n super(config, genome);\n BamUtils.setReaderDefaults(this, config);\n }\n\n\n async readAlignments(chr, start, end) {\n\n if (!this.header) {\n const compressedData = await this.readHeaderData();\n const ba = unbgzf(compressedData.buffer);\n this.header = BamUtils.decodeBamHeader(ba, this.genome);\n this.chrAliasTable = new Map();\n for (let key of Object.keys(this.header.chrAliasTable)) {\n this.chrAliasTable.set(key, this.header.chrAliasTable[key]);\n }\n }\n\n let queryChr = this.chrAliasTable.has(chr) ? this.chrAliasTable.get(chr) : chr;\n\n const compressedData = await this.readData(queryChr, start, end);\n\n // BAM decoding\n const ba = unbgzf(compressedData.buffer);\n\n const chrIdx = this.header.chrToIndex[chr];\n const alignmentContainer = new AlignmentContainer(chr, start, end, this.config);\n BamUtils.decodeBamRecords(ba, this.header.size, alignmentContainer, this.header.chrNames, chrIdx, start, end);\n alignmentContainer.finish();\n\n return alignmentContainer\n\n }\n\n}\n\n/*! For license information please see cram-bundle.js.LICENSE.txt */\nconst fn = ()=>{var e={368:function(e,t,r){var n=this&&this.__awaiter||function(e,t,r,n){return new(r||(r=Promise))((function(i,o){function s(e){try{f(n.next(e));}catch(e){o(e);}}function a(e){try{f(n.throw(e));}catch(e){o(e);}}function f(e){var t;e.done?i(e.value):(t=e.value,t instanceof r?t:new r((function(e){e(t);}))).then(s,a);}f((n=n.apply(e,t||[])).next());}))},i=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,\"__esModule\",{value:!0});const o=i(r(4105)),s=i(r(1269)),a=r(597),f=r(3427),h=r(8577);function l(e,t){if(t.some((e=>void 0===e)))throw new h.CramMalformedError(\"invalid .crai index file\");const[r,n,i,o,s,a]=t;e[r]||(e[r]=[]),e[r].push({start:n,span:i,containerStart:o,sliceStart:s,sliceBytes:a});}t.default=class{constructor(e){this.filehandle=(0, f.open)(e.url,e.path,e.filehandle),this._parseCache=new o.default({cache:new s.default({maxSize:1}),fill:(e,t)=>this.parseIndex()});}parseIndex(){const e={};return this.filehandle.readFile().then((e=>31===e[0]&&139===e[1]?(0, a.unzip)(e):e)).then((t=>{if(t.length>4&&21578050===t.readUInt32LE(0))throw new h.CramMalformedError(\"invalid .crai index file. note: file appears to be a .bai index. this is technically legal but please open a github issue if you need support\");let r=[],n=\"\";for(let i=0;i=48&&o<=57||!n&&45===o)n+=String.fromCharCode(o);else if(9===o)r.push(Number.parseInt(n,10)),n=\"\";else if(10===o)r.push(Number.parseInt(n,10)),n=\"\",l(e,r),r=[];else if(13!==o&&32!==o)throw new h.CramMalformedError(\"invalid .crai index file\")}return n&&r.push(Number.parseInt(n,10)),6===r.length&&l(e,r),Object.entries(e).forEach((([t,r])=>{e[t]=r.sort(((e,t)=>e.start-t.start||e.span-t.span));})),e}))}getIndex(e={}){return this._parseCache.get(\"index\",null,e.signal)}hasDataForReferenceSequence(e){return n(this,void 0,void 0,(function*(){return !!(yield this.getIndex())[e]}))}getEntriesForRange(e,t,r){return n(this,void 0,void 0,(function*(){const n=(yield this.getIndex())[e];if(!n)return [];const i=e=>{const n=e.start,i=e.start+e.span;return n>r?-1:i<=t?1:0},o=[];for(let e=0;e{Object.defineProperty(t,\"__esModule\",{value:!0}),t.default=class{constructor(e,t){this.parameters=e,this.dataType=t;}};},4863:function(e,t,r){var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,\"__esModule\",{value:!0});const i=r(8577),o=n(r(1050)),s=r(1074);class a extends o.default{constructor(e,t){if(super(e,t),\"int\"!==this.dataType)throw new i.CramUnimplementedError(`${this.dataType} decoding not yet implemented by BETA codec`)}decode(e,t,r,n){return (0, s.getBits)(t.content,n.coreBlock,this.parameters.length)-this.parameters.offset}}t.default=a;},1738:function(e,t,r){var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,\"__esModule\",{value:!0});const i=r(9488),o=n(r(1050));class s extends o.default{constructor(e,t,r){if(super(e,t),this.instantiateCodec=r,\"byteArray\"!==t)throw new TypeError(`byteArrayLength does not support data type ${t}`)}decode(e,t,r,n){const i=this._getLengthCodec().decode(e,t,r,n),o=this._getDataCodec(),s=new Uint8Array(i);for(let a=0;a(0, i.tinyMemoize)(s,e)));},1405:function(e,t,r){var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,\"__esModule\",{value:!0});const i=r(8577),o=n(r(1050)),s=r(1074);class a extends o.default{constructor(e,t){if(super(e,t),\"byteArray\"!==t)throw new TypeError(`byteArrayStop codec does not support data type ${t}`)}decode(e,t,r,n){const{blockContentId:o}=this.parameters,s=r[o];if(!s)throw new i.CramMalformedError(`no block found with content ID ${o}`);const a=n.externalBlocks.getCursor(o);return this._decodeByteArray(s,a)}_decodeByteArray(e,t){const r=e.content,{stopByte:n}=this.parameters,i=t.bytePosition;let o=t.bytePosition;for(;r[o]!==n&&o=e.content.length)throw new a.CramBufferOverrunError(\"attempted to read beyond end of block. this file seems truncated.\");return e.content[t.bytePosition++]}}t.default=f;},4229:function(e,t,r){var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,\"__esModule\",{value:!0});const i=r(8577),o=n(r(1050)),s=r(1074);class a extends o.default{constructor(e,t){if(super(e,t),\"int\"!==this.dataType)throw new i.CramUnimplementedError(`${this.dataType} decoding not yet implemented by GAMMA codec`)}decode(e,t,r,n){let i=1;for(;0===(0, s.getBits)(t.content,n.coreBlock,1);)i+=1;return ((0, s.getBits)(t.content,n.coreBlock,i-1)|1<{Object.defineProperty(t,\"__esModule\",{value:!0}),t.getBits=t.CramBufferOverrunError=void 0;class r extends Error{}t.CramBufferOverrunError=r,t.getBits=function(e,t,n){let i=0;if(t.bytePosition+(7-t.bitPosition+n)/8>e.length)throw new r(\"read error during decoding. the file seems to be truncated.\");for(let r=n;r;r--)i<<=1,i|=e[t.bytePosition]>>t.bitPosition&1,t.bitPosition-=1,t.bitPosition<0&&(t.bytePosition+=1),t.bitPosition&=7;return i};},2082:function(e,t,r){var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,\"__esModule\",{value:!0});const i=r(8577),o=n(r(1050)),s=r(1074);class a extends o.default{constructor(e,t){if(super(e,t),this.codes={},this.codeBook={},this.sortedByValue=[],this.sortedCodes=[],this.sortedValuesByBitCode=[],this.sortedBitCodes=[],this.sortedBitLengthsByBitCode=[],this.bitCodeToValue=[],![\"byte\",\"int\"].includes(this.dataType))throw new TypeError(`${this.dataType} decoding not yet implemented by HUFFMAN_INT codec`);this.buildCodeBook(),this.buildCodes(),this.buildCaches(),0===this.sortedCodes[0].bitLength&&(this._decode=this._decodeZeroLengthCode);}buildCodeBook(){let e=new Array(this.parameters.numCodes);for(let t=0;te.bitLength-t.bitLength||e.symbol-t.symbol)),this.codeBook={},e.forEach((e=>{this.codeBook[e.bitLength]||(this.codeBook[e.bitLength]=[]),this.codeBook[e.bitLength].push(e.symbol);}));}buildCodes(){this.codes={};let e=0,t=-1;Object.entries(this.codeBook).forEach((([r,n])=>{const o=parseInt(r,10);n.forEach((r=>{const n={bitLength:o,value:r,bitCode:0};t+=1;const s=o-e;if(t<<=s,n.bitCode=t,e+=s,function(e){let t=e-(e>>1)&1431655765;return t=(858993459&t)+(t>>2&858993459),16843009*(t+(t>>4)&252645135)>>24}(t)>o)throw new i.CramMalformedError(\"Symbol out of range\");this.codes[r]=n;}));}));}buildCaches(){this.sortedCodes=Object.values(this.codes).sort(((e,t)=>e.bitLength-t.bitLength||e.bitCode-t.bitCode)),this.sortedByValue=Object.values(this.codes).sort(((e,t)=>e.value-t.value)),this.sortedValuesByBitCode=this.sortedCodes.map((e=>e.value)),this.sortedBitCodes=this.sortedCodes.map((e=>e.bitCode)),this.sortedBitLengthsByBitCode=this.sortedCodes.map((e=>e.bitLength));const e=Math.max(...this.sortedBitCodes);this.bitCodeToValue=new Array(e+1).fill(-1);for(let e=0;e-1&&this.sortedBitLengthsByBitCode[r]===t)return this.sortedValuesByBitCode[r];for(let r=e;this.sortedCodes[r+1].bitLength===t&&r{Object.defineProperty(t,\"__esModule\",{value:!0}),t.default={CRAM_FLAG_PRESERVE_QUAL_SCORES:1,CRAM_FLAG_DETACHED:2,CRAM_FLAG_MATE_DOWNSTREAM:4,CRAM_FLAG_NO_SEQ:8,CRAM_FLAG_MASK:15,CRAM_M_REVERSE:1,CRAM_M_UNMAP:2,BAM_FPAIRED:1,BAM_FPROPER_PAIR:2,BAM_FUNMAP:4,BAM_FMUNMAP:8,BAM_FREVERSE:16,BAM_FMREVERSE:32,BAM_FREAD1:64,BAM_FREAD2:128,BAM_FSECONDARY:256,BAM_FQCFAIL:512,BAM_FDUP:1024,BAM_FSUPPLEMENTARY:2048,BAM_CMATCH:0,BAM_CINS:1,BAM_CDEL:2,BAM_CREF_SKIP:3,BAM_CSOFT_CLIP:4,BAM_CHARD_CLIP:5,BAM_CPAD:6,BAM_CEQUAL:7,BAM_CDIFF:8,BAM_CBACK:9,BAM_CIGAR_STR:\"MIDNSHP:XB\",BAM_CIGAR_SHIFT:4,BAM_CIGAR_MASK:15,BAM_CIGAR_TYPE:246183};},8543:(e,t,r)=>{Object.defineProperty(t,\"__esModule\",{value:!0});const n=r(8772),i=r(8577),o={BF:\"int\",CF:\"int\",RI:\"int\",RL:\"int\",AP:\"int\",RG:\"int\",MF:\"int\",NS:\"int\",NP:\"int\",TS:\"int\",NF:\"int\",TC:\"byte\",TN:\"int\",FN:\"int\",FC:\"byte\",FP:\"int\",BS:\"byte\",IN:\"byteArray\",SC:\"byteArray\",DL:\"int\",BA:\"byte\",BB:\"byteArray\",RS:\"int\",PD:\"int\",HC:\"int\",MQ:\"int\",RN:\"byteArray\",QS:\"byte\",QQ:\"byteArray\",TL:\"int\"};t.default=class{constructor(e){this.dataSeriesCodecCache={},this.tagCodecCache={},this.tagEncoding={},this.readNamesIncluded=e.preservation.RN,this.APdelta=e.preservation.AP,this.referenceRequired=!!e.preservation.RR,this.tagIdsDictionary=e.preservation.TD,this.substitutionMatrix=function(e){const t=new Array(5);for(let e=0;e<5;e+=1)t[e]=new Array(4);return t[0][e[0]>>6&3]=\"C\",t[0][e[0]>>4&3]=\"G\",t[0][e[0]>>2&3]=\"T\",t[0][e[0]>>0&3]=\"N\",t[1][e[1]>>6&3]=\"A\",t[1][e[1]>>4&3]=\"G\",t[1][e[1]>>2&3]=\"T\",t[1][e[1]>>0&3]=\"N\",t[2][e[2]>>6&3]=\"A\",t[2][e[2]>>4&3]=\"C\",t[2][e[2]>>2&3]=\"T\",t[2][e[2]>>0&3]=\"N\",t[3][e[3]>>6&3]=\"A\",t[3][e[3]>>4&3]=\"C\",t[3][e[3]>>2&3]=\"G\",t[3][e[3]>>0&3]=\"N\",t[4][e[4]>>6&3]=\"A\",t[4][e[4]>>4&3]=\"C\",t[4][e[4]>>2&3]=\"G\",t[4][e[4]>>0&3]=\"T\",t}(e.preservation.SM),this.dataSeriesEncoding=e.dataSeriesEncoding,this.tagEncoding=e.tagEncoding,this.preservation=e.preservation,this._size=e._size,this._endPosition=e._endPosition;}getCodecForTag(e){if(!this.tagCodecCache[e]){const t=this.tagEncoding[e];t&&(this.tagCodecCache[e]=(0, n.instantiateCodec)(t,\"byteArray\"));}return this.tagCodecCache[e]}getTagNames(e){return this.tagIdsDictionary[e]}getCodecForDataSeries(e){let t=this.dataSeriesCodecCache[e];if(void 0===t){const r=this.dataSeriesEncoding[e];if(r){const s=o[e];if(!s)throw new i.CramMalformedError(`data series name ${e} not defined in file compression header`);t=(0, n.instantiateCodec)(r,s),this.dataSeriesCodecCache[e]=t;}}return t}toJSON(){const e={};return Object.keys(this).forEach((t=>{/Cache$/.test(t)||(e[t]=this[t]);})),e}};},6284:function(e,t,r){var n=this&&this.__awaiter||function(e,t,r,n){return new(r||(r=Promise))((function(i,o){function s(e){try{f(n.next(e));}catch(e){o(e);}}function a(e){try{f(n.throw(e));}catch(e){o(e);}}function f(e){var t;e.done?i(e.value):(t=e.value,t instanceof r?t:new r((function(e){e(t);}))).then(s,a);}f((n=n.apply(e,t||[])).next());}))},i=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,\"__esModule\",{value:!0});const o=r(8577),s=r(9488),a=i(r(6601)),f=i(r(8543));class h{constructor(e,t){this.file=e,this.filePosition=t;}getHeader(){return this._readContainerHeader(this.filePosition)}getCompressionHeaderBlock(){return n(this,void 0,void 0,(function*(){if(!(yield this.getHeader()).numRecords)return null;const e=yield this.file.getSectionParsers(),t=yield this.getFirstBlock();if(void 0===t)return;if(\"COMPRESSION_HEADER\"!==t.contentType)throw new o.CramMalformedError(`invalid content type ${t.contentType} in what is supposed to be the compression header block`);const r=(0, s.parseItem)(t.content,e.cramCompressionHeader.parser,0,t.contentPosition);return Object.assign(Object.assign({},t),{parsedContent:r})}))}getFirstBlock(){return n(this,void 0,void 0,(function*(){const e=yield this.getHeader();return this.file.readBlock(e._endPosition)}))}getCompressionScheme(){return n(this,void 0,void 0,(function*(){const e=yield this.getCompressionHeaderBlock();if(e)return new f.default(e.parsedContent)}))}getSlice(e,t){return new a.default(this,e,t)}_readContainerHeader(e){return n(this,void 0,void 0,(function*(){const t=yield this.file.getSectionParsers(),{cramContainerHeader1:r,cramContainerHeader2:n}=t,{size:i}=yield this.file.stat();if(e>=i)return;const o=Buffer.allocUnsafe(r.maxLength);yield this.file.read(o,0,r.maxLength,e);const a=(0, s.parseItem)(o,r.parser),f=(0, s.itf8Size)(a.numLandmarks);if(e+a.length>=i)return void console.warn(`${this.file}: container header at ${e} indicates that the container has length ${a.length}, which extends beyond the length of the file. Skipping this container.`);const h=Buffer.allocUnsafe(n.maxLength(a.numLandmarks));yield this.file.read(h,0,n.maxLength(a.numLandmarks),e+a._size-f);const l=(0, s.parseItem)(h,n.parser);return this.file.validateChecksums&&void 0!==l.crc32&&(yield this.file.checkCrc32(e,a._size+l._size-f-4,l.crc32,`container header beginning at position ${e}`)),Object.assign(a,l,{_size:a._size+l._size-f,_endPosition:a._size+l._size-f+e})}))}}t.default=h,\"getHeader getCompressionHeaderBlock getCompressionScheme\".split(\" \").forEach((e=>(0, s.tinyMemoize)(h,e)));},5457:function(e,t,r){var n=this&&this.__awaiter||function(e,t,r,n){return new(r||(r=Promise))((function(i,o){function s(e){try{f(n.next(e));}catch(e){o(e);}}function a(e){try{f(n.throw(e));}catch(e){o(e);}}function f(e){var t;e.done?i(e.value):(t=e.value,t instanceof r?t:new r((function(e){e(t);}))).then(s,a);}f((n=n.apply(e,t||[])).next());}))},i=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,\"__esModule\",{value:!0});const o=r(597),s=i(r(2779)),a=i(r(1269)),f=r(8577),h=i(r(9675)),l=r(6141),u=i(r(3498)),c=i(r(6284)),d=r(3427),p=r(9488),g=r(7578);class m{constructor(e){var t;if(this.file=(0, d.open)(e.url,e.path,e.filehandle),this.validateChecksums=!0,this.fetchReferenceSequenceCallback=e.seqFetch,this.options={checkSequenceMD5:e.checkSequenceMD5,cacheSize:null!==(t=e.cacheSize)&&void 0!==t?t:2e4},this.featureCache=new a.default({maxSize:this.options.cacheSize}),function(){const e=new Uint32Array([287454020]),t=new Uint8Array(e.buffer);return 68===t[0]?0:17===t[0]?1:2}()>0)throw new Error(\"Detected big-endian machine, may be unable to run\")}read(e,t,r,n){return this.file.read(e,t,r,n)}stat(){return this.file.stat()}getDefinition(){return n(this,void 0,void 0,(function*(){const e=Buffer.allocUnsafe(l.cramFileDefinition.maxLength);yield this.file.read(e,0,l.cramFileDefinition.maxLength,0);const t=l.cramFileDefinition.parser.parse(e).result;if(2!==t.majorVersion&&3!==t.majorVersion)throw new f.CramUnimplementedError(`CRAM version ${t.majorVersion} not supported`);return t}))}getSamHeader(){return n(this,void 0,void 0,(function*(){const e=yield this.getContainerById(0);if(!e)throw new f.CramMalformedError(\"file contains no containers\");const t=yield e.getFirstBlock();if(void 0===t)return (0, g.parseHeaderText)(\"\");const r=t.content,n=r.readInt32LE(0),i=r.toString(\"utf8\",4,4+n);return this.header=i,(0, g.parseHeaderText)(i)}))}getHeaderText(){return n(this,void 0,void 0,(function*(){return yield this.getSamHeader(),this.header}))}getSectionParsers(){return n(this,void 0,void 0,(function*(){const{majorVersion:e}=yield this.getDefinition();return (0, l.getSectionParsers)(e)}))}getContainerById(e){return n(this,void 0,void 0,(function*(){const t=yield this.getSectionParsers();let r=t.cramFileDefinition.maxLength;const{size:n}=yield this.file.stat(),{cramContainerHeader1:i}=t;let o;for(let t=0;t<=e;t+=1){if(r+i.maxLength+8>=n)return;o=this.getContainerAtPosition(r);const s=yield o.getHeader();if(!s)throw new f.CramMalformedError(`container ${e} not found in file`);if(0===t){r=s._endPosition;for(let e=0;e=n)return;const i=Buffer.allocUnsafe(r.maxLength);return yield this.file.read(i,0,r.maxLength,e),(0, p.parseItem)(i,r.parser,0,e)}))}_parseSection(e,t,r=e.maxLength,i){return n(this,void 0,void 0,(function*(){let n;if(i)n=i;else {const{size:e}=yield this.file.stat();if(t+r>=e)return;n=Buffer.allocUnsafe(r),yield this.file.read(n,0,r,t);}const o=(0, p.parseItem)(n,e.parser,0,t);if(o._size!==r)throw new f.CramMalformedError(`section read error: requested size ${r} does not equal parsed size ${o._size}`);return o}))}_uncompress(e,t,r){if(\"gzip\"===e)(0, o.unzip)(t).copy(r);else if(\"bzip2\"===e){const e=bzip2.array(t);let n,i=bzip2.header(e),o=0;do{n=bzip2.decompress(e,i),-1!=n&&(Buffer.from(n).copy(r,o),o+=n.length,i-=n.length);}while(-1!=n)}else if(\"rans\"===e)(0, h.default)(t,r);else if(\"rans4x16\"===e)u.default.r4x16_uncompress(t,r);else if(\"arith\"===e)u.default.arith_uncompress(t,r);else if(\"fqzcomp\"===e)u.default.fqzcomp_uncompress(t,r);else {if(\"tok3\"!==e)throw new f.CramUnimplementedError(`${e} decompression not yet implemented`);u.default.tok3_uncompress(t,r);}}readBlock(e){return n(this,void 0,void 0,(function*(){const{majorVersion:t}=yield this.getDefinition(),r=yield this.getSectionParsers(),n=yield this.readBlockHeader(e);if(void 0===n)return;const i=n._endPosition,o=Buffer.allocUnsafe(n.uncompressedSize),s=Object.assign(Object.assign({},n),{_endPosition:i,contentPosition:i,content:o});if(\"raw\"!==n.compressionMethod){const e=Buffer.allocUnsafe(n.compressedSize);yield this.read(e,0,n.compressedSize,i),this._uncompress(n.compressionMethod,e,o);}else yield this.read(o,0,n.uncompressedSize,i);if(t>=3){const t=yield this._parseSection(r.cramBlockCrc32,i+n.compressedSize);if(void 0===t)return;s.crc32=t.crc32,this.validateChecksums&&(yield this.checkCrc32(e,n._size+n.compressedSize,t.crc32,\"block data\")),s._endPosition=t._endPosition,s._size=s.compressedSize+r.cramBlockCrc32.maxLength;}else s._endPosition=i+s.compressedSize,s._size=s.compressedSize;return s}))}}t.default=m,\"getDefinition getSectionParsers getSamHeader\".split(\" \").forEach((e=>(0, p.tinyMemoize)(m,e)));},8222:function(e,t,r){var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,\"__esModule\",{value:!0}),t.CramRecord=void 0;const i=n(r(5457));var o=r(8631);Object.defineProperty(t,\"CramRecord\",{enumerable:!0,get:function(){return n(o).default}}),t.default=i.default;},8631:function(e,t,r){var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,\"__esModule\",{value:!0}),t.MateFlagsDecoder=t.CramFlagsDecoder=t.BamFlagsDecoder=t.MateFlags=t.CramFlags=t.BamFlags=void 0;const i=n(r(2615)),o={a:0,A:0,c:1,C:1,g:2,G:2,t:3,T:3,n:4,N:4};function s(e){const t={};for(const[r,n]of e)t[\"is\"+n]=e=>!!(e&r),t[\"set\"+n]=e=>e|r;return t}t.BamFlags=[[1,\"Paired\"],[2,\"ProperlyPaired\"],[4,\"SegmentUnmapped\"],[8,\"MateUnmapped\"],[16,\"ReverseComplemented\"],[32,\"MateReverseComplemented\"],[64,\"Read1\"],[128,\"Read2\"],[256,\"Secondary\"],[512,\"FailedQc\"],[1024,\"Duplicate\"],[2048,\"Supplementary\"]],t.CramFlags=[[1,\"PreservingQualityScores\"],[2,\"Detached\"],[4,\"WithMateDownstream\"],[8,\"DecodeSequenceAsStar\"]],t.MateFlags=[[1,\"OnNegativeStrand\"],[2,\"Unmapped\"]],t.BamFlagsDecoder=s(t.BamFlags),t.CramFlagsDecoder=s(t.CramFlags),t.MateFlagsDecoder=s(t.MateFlags),t.default=class{constructor({flags:e,cramFlags:t,readLength:r,mappingQuality:n,lengthOnRef:i,qualityScores:o,mateRecordNumber:s,readBases:a,readFeatures:f,mateToUse:h,readGroupId:l,readName:u,sequenceId:c,uniqueId:d,templateSize:p,alignmentStart:g,tags:m}){this.flags=e,this.cramFlags=t,this.readLength=r,this.mappingQuality=n,this.lengthOnRef=i,this.qualityScores=o,a&&(this.readBases=a),this.readGroupId=l,this.readName=u,this.sequenceId=c,this.uniqueId=d,this.templateSize=p,this.alignmentStart=g,this.tags=m,f&&(this.readFeatures=f),h&&(this.mate={flags:h.mateFlags,readName:h.mateReadName,sequenceId:h.mateSequenceId,alignmentStart:h.mateAlignmentStart}),s&&(this.mateRecordNumber=s);}isPaired(){return !!(this.flags&i.default.BAM_FPAIRED)}isProperlyPaired(){return !!(this.flags&i.default.BAM_FPROPER_PAIR)}isSegmentUnmapped(){return !!(this.flags&i.default.BAM_FUNMAP)}isMateUnmapped(){return !!(this.flags&i.default.BAM_FMUNMAP)}isReverseComplemented(){return !!(this.flags&i.default.BAM_FREVERSE)}isMateReverseComplemented(){return !!(this.flags&i.default.BAM_FMREVERSE)}isRead1(){return !!(this.flags&i.default.BAM_FREAD1)}isRead2(){return !!(this.flags&i.default.BAM_FREAD2)}isSecondary(){return !!(this.flags&i.default.BAM_FSECONDARY)}isFailedQc(){return !!(this.flags&i.default.BAM_FQCFAIL)}isDuplicate(){return !!(this.flags&i.default.BAM_FDUP)}isSupplementary(){return !!(this.flags&i.default.BAM_FSUPPLEMENTARY)}isDetached(){return !!(this.cramFlags&i.default.CRAM_FLAG_DETACHED)}hasMateDownStream(){return !!(this.cramFlags&i.default.CRAM_FLAG_MATE_DOWNSTREAM)}isPreservingQualityScores(){return !!(this.cramFlags&i.default.CRAM_FLAG_PRESERVE_QUAL_SCORES)}isUnknownBases(){return !!(this.cramFlags&i.default.CRAM_FLAG_NO_SEQ)}getReadBases(){if(!this.readBases&&this._refRegion){const e=function(e,t){if(!e.lengthOnRef&&!e.readLength)return null;if(e.isUnknownBases())return null;const r=e.alignmentStart-t.start;if(!e.readFeatures)return t.seq.substr(r,e.lengthOnRef).toUpperCase();let n=\"\",i=r,o=0;for(;n.lengththis.mate.alignmentStart&&o>0&&(o=-o),o>0?(i[0]=e,i[1]=r,i[2]=t,i[3]=n):(i[2]=e,i[3]=r,i[0]=t,i[1]=n),i.join(\"\")}return null}addReferenceSequence(e,t){this.readFeatures&&this.readFeatures.forEach((r=>{\"X\"===r.code&&function(e,t,r,n){if(!t)return;const i=n.refPos-t.start,s=t.seq.charAt(i);s&&(n.ref=s);let a=o[s];void 0===a&&(a=4);const f=r.substitutionMatrix[a][n.data];f&&(n.sub=f);}(0,e,t,r);})),!this.readBases&&e.start<=this.alignmentStart&&e.end>=this.alignmentStart+(this.lengthOnRef||this.readLength)-1&&(this._refRegion=e);}toJSON(){const e={};return Object.keys(this).forEach((t=>{\"_\"!==t.charAt(0)&&(e[t]=this[t]);})),e.readBases=this.getReadBases(),e}};},6141:(e,t,r)=>{Object.defineProperty(t,\"__esModule\",{value:!0}),t.getSectionParsers=t.cramFileDefinition=t.isMappedSliceHeader=void 0;const n=r(9996),i=(new n.Parser).itf8(),o={parser:(new n.Parser).string(\"magic\",{length:4}).uint8(\"majorVersion\").uint8(\"minorVersion\").string(\"fileId\",{length:20,stripNull:!0}),maxLength:26};t.cramFileDefinition=o;const s={parser:(new n.Parser).uint8(\"compressionMethod\",{formatter:e=>{const t=[\"raw\",\"gzip\",\"bzip2\",\"lzma\",\"rans\",\"rans4x16\",\"arith\",\"fqzcomp\",\"tok3\"][e];if(!t)throw new Error(`compression method number ${e} not implemented`);return t}}).uint8(\"contentType\",{formatter:e=>{const t=[\"FILE_HEADER\",\"COMPRESSION_HEADER\",\"MAPPED_SLICE_HEADER\",\"UNMAPPED_SLICE_HEADER\",\"EXTERNAL_DATA\",\"CORE_DATA\"][e];if(!t)throw new Error(`invalid block content type id ${e}`);return t}}).itf8(\"contentId\").itf8(\"compressedSize\").itf8(\"uncompressedSize\"),maxLength:17},a={parser:(new n.Parser).uint32(\"crc32\"),maxLength:4},f=(new n.Parser).itf8(\"size\").buffer(\"ents\",{length:\"size\",formatter:e=>{function t(t,r){const n=e.toString(\"utf8\",t,r),i=[];for(let e=0;ei&&n.push(t(i,r)),n}}),h=(new n.Parser).uint8(null,{formatter:e=>!!e}),l=(new n.Parser).itf8(\"mapSize\").itf8(\"mapCount\").array(\"ents\",{length:\"mapCount\",type:(new n.Parser).string(\"key\",{length:2,stripNull:!1}).choice(\"value\",{tag:\"key\",choices:{MI:h,UI:h,PI:h,RN:h,AP:h,RR:h,SM:(new n.Parser).array(null,{type:\"uint8\",length:5}),TD:(new n.Parser).nest(null,{type:f,formatter:e=>e.ents})}})});function u(e){const t={};for(let r=0;r=3?(r=r.ltf8(\"recordCounter\"),t+=9):2===e&&(r=r.itf8(\"recordCounter\"),t+=5),r=r.itf8(\"numBlocks\").itf8(\"numContentIds\").array(\"contentIds\",{type:i,length:\"numContentIds\"}),t+=10,e>=2&&(r=r.array(\"md5\",{type:\"uint8\",length:16}),t+=16),{parser:r,maxLength:e=>t+5*e}},cramMappedSliceHeader(e){let t=(new n.Parser).itf8(\"refSeqId\").itf8(\"refSeqStart\").itf8(\"refSeqSpan\").itf8(\"numRecords\"),r=20;return e>=3?(t=t.ltf8(\"recordCounter\"),r+=9):2===e&&(t=t.itf8(\"recordCounter\"),r+=5),t=t.itf8(\"numBlocks\").itf8(\"numContentIds\").array(\"contentIds\",{type:i,length:\"numContentIds\"}).itf8(\"refBaseBlockId\"),r+=15,e>=2&&(t=t.array(\"md5\",{type:\"uint8\",length:16}),r+=16),{parser:t,maxLength:e=>r+5*e}},cramEncoding:e=>({parser:(new n.Parser).namely(\"cramEncoding\").itf8(\"codecId\").itf8(\"parametersBytes\").choice(\"parameters\",{tag:\"codecId\",choices:{0:new n.Parser,1:(new n.Parser).itf8(\"blockContentId\"),2:(new n.Parser).itf8(\"offset\").itf8(\"M\"),3:n.Parser.start().itf8(\"numCodes\").array(\"symbols\",{length:\"numCodes\",type:i}).itf8(\"numLengths\").array(\"bitLengths\",{length:\"numLengths\",type:i}),4:n.Parser.start().nest(\"lengthsEncoding\",{type:\"cramEncoding\"}).nest(\"valuesEncoding\",{type:\"cramEncoding\"}),5:(new n.Parser).uint8(\"stopByte\").itf8(\"blockContentId\"),6:(new n.Parser).itf8(\"offset\").itf8(\"length\"),7:(new n.Parser).itf8(\"offset\").itf8(\"K\"),8:(new n.Parser).itf8(\"offset\").itf8(\"log2m\"),9:(new n.Parser).itf8(\"offset\")}})}),cramDataSeriesEncodingMap(e){return (new n.Parser).itf8(\"mapSize\").itf8(\"mapCount\").array(\"ents\",{length:\"mapCount\",type:(new n.Parser).string(\"key\",{length:2,stripNull:!1}).nest(\"value\",{type:this.cramEncoding(e).parser})})},cramTagEncodingMap(e){return (new n.Parser).itf8(\"mapSize\").itf8(\"mapCount\").array(\"ents\",{length:\"mapCount\",type:(new n.Parser).itf8(\"key\",{formatter:e=>String.fromCharCode(e>>16&255)+String.fromCharCode(e>>8&255)+String.fromCharCode(255&e)}).nest(\"value\",{type:this.cramEncoding(e).parser})})},cramCompressionHeader(e){let t=new n.Parser;return t=t.nest(\"preservation\",{type:l,formatter:u}).nest(\"dataSeriesEncoding\",{type:this.cramDataSeriesEncodingMap(e),formatter:u}).nest(\"tagEncoding\",{type:this.cramTagEncodingMap(e),formatter:u}),{parser:t}},cramContainerHeader1(e){let t=(new n.Parser).int32(\"length\").itf8(\"refSeqId\").itf8(\"refSeqStart\").itf8(\"alignmentSpan\").itf8(\"numRecords\"),r=24;return e>=3?(t=t.ltf8(\"recordCounter\"),r+=9):2===e&&(t=t.itf8(\"recordCounter\"),r+=5),e>1&&(t=t.ltf8(\"numBases\"),r+=9),t=t.itf8(\"numBlocks\").itf8(\"numLandmarks\"),r+=10,{parser:t,maxLength:r}},cramContainerHeader2(e){let t=(new n.Parser).itf8(\"numLandmarks\").array(\"landmarks\",{type:(new n.Parser).itf8(),length:\"numLandmarks\"}),r=0;return e>=3&&(t=t.uint32(\"crc32\"),r=4),{parser:t,maxLength:e=>5+5*e+r}}};t.getSectionParsers=function(e){const t=Object.assign({},c);return Object.keys(d).forEach((r=>{t[r]=d[r](e);})),t};},3757:function(e,t,r){var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,\"__esModule\",{value:!0});const i=n(r(3720)),o=r(8577),s=r(8631),a=r(6141);function f(e){let t=\"\";for(let r=0;r1&&-2===n.parsedContent.refSeqId?t(\"RI\"):n.parsedContent.refSeqId;const y=t(\"RL\");let b=t(\"AP\");r.APdelta&&(b+=u.lastAlignmentStart),u.lastAlignmentStart=b;const v=t(\"RG\");let w,_,B,E;if(r.readNamesIncluded&&(w=f(t(\"RN\"))),s.CramFlagsDecoder.isDetached(g)){const e=t(\"MF\");let n;r.readNamesIncluded||(n=f(t(\"RN\")),w=n);const i=t(\"NS\"),o=t(\"NP\");(e||i>-1)&&(_={mateFlags:e,mateSequenceId:i,mateAlignmentStart:o,mateReadName:n}),B=t(\"TS\"),s.MateFlagsDecoder.isUnmapped(e)&&(p=s.BamFlagsDecoder.setMateUnmapped(p)),s.MateFlagsDecoder.isOnNegativeStrand(e)&&(p=s.BamFlagsDecoder.setMateReverseComplemented(p));}else s.CramFlagsDecoder.isWithMateDownstream(g)&&(E=t(\"NF\")+d+1);const S=t(\"TL\");if(S<0)throw new o.CramMalformedError(\"invalid TL index\");const A={},C=r.getTagNames(S),R=C.length;for(let t=0;t1?\"SC\":\"IN\"],X:[\"number\",\"BS\"],D:[\"number\",\"DL\"],I:[\"string\",\"IN\"],i:[\"character\",\"BA\"],b:[\"string\",\"BB\"],q:[\"numArray\",\"QQ\"],Q:[\"number\",\"QS\"],H:[\"number\",\"HC\"],P:[\"number\",\"PD\"],N:[\"number\",\"RS\"]}[t];if(!l)throw new o.CramMalformedError(`invalid read feature code \"${t}\"`);let u=h(l);const c={B:[\"number\",\"QS\"]}[t];c&&(u=[u,h(c)]),s+=n;const d=s;a+=n;const p=a;\"D\"===t||\"N\"===t?a+=u:\"I\"===t||\"S\"===t?a-=u.length:\"i\"===t&&(a-=1),f[e]={code:t,pos:d,refPos:p,data:u};}return f}(b,e,t,0,c)),x=y,k)for(const{code:e,data:t}of k)\"D\"===e||\"N\"===e?x+=t:\"I\"===e||\"S\"===e?x-=t.length:\"i\"===e&&(x-=1);if(Number.isNaN(x)&&(console.warn(`${w||`${m}:${b}`} record has invalid read features`),x=y),I=t(\"MQ\"),s.CramFlagsDecoder.isPreservingQualityScores(g)){M=new Array(y);for(let e=0;e=0){const i=e[r.mateRecordNumber];if(!i)throw new o.CramMalformedError(\"intra-slice mate record not found, this file seems malformed\");n.push(...t(i));}return n}(r),i=n.map((e=>e.alignmentStart)),s=n.map((e=>e.alignmentStart+e.readLength-1)),a=Math.max(...s)-Math.min(...i)+1;a>=0&&n.forEach((e=>{if(void 0!==e.templateLength)throw new o.CramMalformedError(\"mate pair group has some members that have template lengths already, this file seems malformed\");e.templateLength=a;}));}(e,0,r):function(e,t){const r=Math.min(e.alignmentStart,t.alignmentStart),n=Math.max(e.alignmentStart+e.readLength-1,t.alignmentStart+t.readLength-1)-r+1;e.templateLength=n,t.templateLength=n;}(r,n)),delete r.mateRecordNumber;}class d{constructor(e,t,r){this.container=e,this.containerPosition=t,this.file=e.file;}getHeader(){return n(this,void 0,void 0,(function*(){const e=yield this.file.getSectionParsers(),t=yield this.container.getHeader(),r=yield this.file.readBlock(t._endPosition+this.containerPosition);if(void 0===r)throw new Error;if(\"MAPPED_SLICE_HEADER\"===r.contentType){const n=(0, s.parseItem)(r.content,e.cramMappedSliceHeader.parser,0,t._endPosition);return Object.assign(Object.assign({},r),{parsedContent:n})}if(\"UNMAPPED_SLICE_HEADER\"===r.contentType){const n=(0, s.parseItem)(r.content,e.cramUnmappedSliceHeader.parser,0,t._endPosition);return Object.assign(Object.assign({},r),{parsedContent:n})}throw new o.CramMalformedError(`error reading slice header block, invalid content type ${r.contentType}`)}))}getBlocks(){return n(this,void 0,void 0,(function*(){const e=yield this.getHeader();let t=e._endPosition;const r=new Array(e.parsedContent.numBlocks);for(let e=0;e{\"EXTERNAL_DATA\"===e.contentType&&(t[e.contentId]=e);})),t}))}getBlockByContentId(e){return n(this,void 0,void 0,(function*(){return (yield this._getBlocksContentIdIndex())[e]}))}getReferenceRegion(){return n(this,void 0,void 0,(function*(){const e=(yield this.getHeader()).parsedContent;if(!(0, l.isMappedSliceHeader)(e))throw new Error;if(e.refSeqId<0)return;const t=yield this.container.getCompressionScheme();if(void 0===t)throw new Error;if(e.refBaseBlockId>=0){const t=yield this.getBlockByContentId(e.refBaseBlockId);if(!t)throw new o.CramMalformedError(\"embedded reference specified, but reference block does not exist\");return {seq:t.data.toString(\"utf8\"),start:e.refSeqStart,end:e.refSeqStart+e.refSeqSpan-1,span:e.refSeqSpan}}if(t.referenceRequired||this.file.fetchReferenceSequenceCallback){if(!this.file.fetchReferenceSequenceCallback)throw new Error(\"reference sequence not embedded, and seqFetch callback not provided, cannot fetch reference sequence\");const t=yield this.file.fetchReferenceSequenceCallback(e.refSeqId,e.refSeqStart,e.refSeqStart+e.refSeqSpan-1);if(t.length!==e.refSeqSpan)throw new o.CramArgumentError(\"seqFetch callback returned a reference sequence of the wrong length\");return {seq:t,start:e.refSeqStart,end:e.refSeqStart+e.refSeqSpan-1,span:e.refSeqSpan}}}))}getAllRecords(){return this.getRecords((()=>!0))}_fetchRecords(){return n(this,void 0,void 0,(function*(){const{majorVersion:e}=yield this.file.getDefinition(),t=yield this.container.getCompressionScheme();if(void 0===t)throw new Error;const r=yield this.getHeader();if(void 0===r)throw new Error;const n=yield this._getBlocksContentIdIndex();if(e>1&&this.file.options.checkSequenceMD5&&(0, l.isMappedSliceHeader)(r.parsedContent)&&r.parsedContent.refSeqId>=0&&\"0000000000000000\"!==r.parsedContent.md5.join(\"\")){const e=yield this.getReferenceRegion();if(e){const{seq:t,start:n,end:i}=e,a=(0, s.sequenceMD5)(t),f=r.parsedContent.md5.map((e=>(e<16?\"0\":\"\")+e.toString(16))).join(\"\");if(a!==f)throw new o.CramMalformedError(`MD5 checksum reference mismatch for ref ${r.parsedContent.refSeqId} pos ${n}..${i}. recorded MD5: ${f}, calculated MD5: ${a}`)}}const i=yield this.getCoreDataBlock(),a={lastAlignmentStart:(0, l.isMappedSliceHeader)(r.parsedContent)?r.parsedContent.refSeqStart:0,coreBlock:{bitPosition:7,bytePosition:0},externalBlocks:{map:new Map,getCursor(e){let t=this.map.get(e);return void 0===t&&(t={bitPosition:7,bytePosition:0},this.map.set(e,t)),t}}},d=e=>{const r=t.getCodecForDataSeries(e);if(!r)throw new o.CramMalformedError(`no codec defined for ${e} data series`);return r.decode(this,i,n,a)};let p=new Array(r.parsedContent.numRecords);for(let o=0;o!!e));break}throw e}for(let e=0;e=0&&c(p,e,p[e],p[t]);}return p}))}getRecords(e){return n(this,void 0,void 0,(function*(){const t=this.container.filePosition+this.containerPosition;let r=this.file.featureCache.get(t.toString());r||(r=this._fetchRecords(),this.file.featureCache.set(t.toString(),r));const i=(yield r).filter(e);if(i.length&&this.file.fetchReferenceSequenceCallback){const e=yield this.getHeader();if((0, l.isMappedSliceHeader)(e.parsedContent)&&(e.parsedContent.refSeqId>=0||-2===e.parsedContent.refSeqId)){const t=e.parsedContent.refSeqId>=0?e.parsedContent.refSeqId:void 0,r=yield this.container.getCompressionScheme();if(void 0===r)throw new Error;const o={};for(let e=0;en.end&&(n.end=s),i[e].alignmentStartn(this,void 0,void 0,(function*(){-1!==e.id&&e.start<=e.end&&(e.seq=yield this.file.fetchReferenceSequenceCallback(e.id,e.start,e.end));})))));for(let e=0;e(0, s.tinyMemoize)(d,e)));},9488:function(e,t,r){var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,\"__esModule\",{value:!0}),t.sequenceMD5=t.tinyMemoize=t.parseItem=t.parseItf8=t.itf8Size=void 0;const i=n(r(2568)),o=r(1074);t.itf8Size=function(e){return -128&e?-16384&e?-2097152&e?-268435456&e?5:4:3:2:1},t.parseItf8=function(e,t){let r=t;const n=e[r];let i;if(n<128?(i=n,r+=1):n<192?(i=16383&(n<<8|e[r+1]),r+=2):n<224?(i=2097151&(n<<16|e[r+1]<<8|e[r+2]),r+=3):n<240?(i=268435455&(n<<24|e[r+1]<<16|e[r+2]<<8|e[r+3]),r+=4):(i=(15&n)<<28|e[r+1]<<20|e[r+2]<<12|e[r+3]<<4|15&e[r+4],r+=5),r>e.length)throw new o.CramBufferOverrunError(\"Attempted to read beyond end of buffer; this file seems truncated.\");return [i,r-t]},t.parseItem=function(e,t,r=0,n=0){const{offset:i,result:o}=t.parse(e);return Object.assign(Object.assign({},o),{_endPosition:i+n,_size:i-r})},t.tinyMemoize=function(e,t){const r=e.prototype[t],n=`_memo_${t}`;e.prototype[t]=function(){if(!(n in this)){const e=r.call(this);this[n]=e,Promise.resolve(e).catch((()=>{delete this[n];}));}return this[n]};},t.sequenceMD5=function(e){return (0, i.default)(e.toUpperCase().replace(/[^\\x21-\\x7e]/g,\"\"))};},8577:(e,t)=>{Object.defineProperty(t,\"__esModule\",{value:!0}),t.CramArgumentError=t.CramSizeLimitError=t.CramMalformedError=t.CramUnimplementedError=t.CramError=void 0;class r extends Error{}t.CramError=r;class n extends Error{}t.CramUnimplementedError=n,t.CramMalformedError=class extends r{},t.CramSizeLimitError=class extends r{},t.CramArgumentError=class extends r{};},5590:function(e,t,r){var n=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r);var i=Object.getOwnPropertyDescriptor(t,r);i&&!(\"get\"in i?!t.__esModule:i.writable||i.configurable)||(i={enumerable:!0,get:function(){return t[r]}}),Object.defineProperty(e,n,i);}:function(e,t,r,n){void 0===n&&(n=r),e[n]=t[r];}),i=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,\"default\",{enumerable:!0,value:t});}:function(e,t){e.default=t;}),o=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var r in e)\"default\"!==r&&Object.prototype.hasOwnProperty.call(e,r)&&n(t,e,r);return i(t,e),t},s=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,\"__esModule\",{value:!0}),t.CramRecord=t.CraiIndex=t.IndexedCramFile=t.CramFile=void 0;const a=o(r(8222));t.CramFile=a.default,Object.defineProperty(t,\"CramRecord\",{enumerable:!0,get:function(){return a.CramRecord}});const f=s(r(946));t.IndexedCramFile=f.default;const h=s(r(368));t.CraiIndex=h.default;},946:function(e,t,r){var n=this&&this.__awaiter||function(e,t,r,n){return new(r||(r=Promise))((function(i,o){function s(e){try{f(n.next(e));}catch(e){o(e);}}function a(e){try{f(n.throw(e));}catch(e){o(e);}}function f(e){var t;e.done?i(e.value):(t=e.value,t instanceof r?t:new r((function(e){e(t);}))).then(s,a);}f((n=n.apply(e,t||[])).next());}))},i=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,\"__esModule\",{value:!0});const o=r(8577),s=i(r(8222));t.default=class{constructor(e){if(e.cram?this.cram=e.cram:this.cram=new s.default({url:e.cramUrl,path:e.cramPath,filehandle:e.cramFilehandle,seqFetch:e.seqFetch,checkSequenceMD5:e.checkSequenceMD5,cacheSize:e.cacheSize}),!(this.cram instanceof s.default))throw new Error(\"invalid arguments: no cramfile\");if(this.index=e.index,!this.index.getEntriesForRange)throw new Error(\"invalid arguments: not an index\");this.fetchSizeLimit=e.fetchSizeLimit||3e6;}getRecordsForRange(e,t,r,i={}){return n(this,void 0,void 0,(function*(){if(i.viewAsPairs=i.viewAsPairs||!1,i.pairAcrossChr=i.pairAcrossChr||!1,i.maxInsertSize=i.maxInsertSize||2e5,\"string\"==typeof e)throw new o.CramUnimplementedError(\"string sequence names not yet supported\");const n=e,s=yield this.index.getEntriesForRange(n,t,r),a=s.map((e=>e.sliceBytes)).reduce(((e,t)=>e+t),0);if(a>this.fetchSizeLimit)throw new o.CramSizeLimitError(`data size of ${a.toLocaleString()} bytes exceeded fetch size limit of ${this.fetchSizeLimit.toLocaleString()} bytes`);const f=n=>n.sequenceId===e&&n.alignmentStart<=r&&void 0!==n.lengthOnRef&&n.alignmentStart+n.lengthOnRef-1>=t,h=yield Promise.all(s.map((e=>this.getRecordsInSlice(e,f))));let l=Array.prototype.concat(...h);if(i.viewAsPairs){const e={},t={};for(let r=0;r{1===t&&(r[e]=!0);}));const o=[];for(let e=0;ee.toString().localeCompare(t.toString()))).filter(((e,t,r)=>!t||e.toString()!==r[t-1].toString()));const h=[],u=a.map((e=>e.sliceBytes)).reduce(((e,t)=>e+t),0);if(u>this.fetchSizeLimit)throw new Error(`mate data size of ${u.toLocaleString()} bytes exceeded fetch size limit of ${this.fetchSizeLimit.toLocaleString()} bytes`);a.forEach((e=>{let n=this.cram.featureCache.get(e.toString());n||(n=this.getRecordsInSlice(e,(()=>!0)),this.cram.featureCache.set(e.toString(),n));const i=n.then((e=>{const n=[];for(let i=0;ie.concat(t)));l=l.concat(e);}}return l}))}getRecordsInSlice({containerStart:e,sliceStart:t,sliceBytes:r},n){return this.cram.getContainerAtPosition(e).getSlice(t,r).getRecords(n)}hasDataForReferenceSequence(e){return this.index.hasDataForReferenceSequence(e)}};},3427:function(e,t,r){var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,\"__esModule\",{value:!0}),t.open=t.fromUrl=t.RemoteFile=t.LocalFile=void 0;const i=n(r(8575)),o=r(4319),s=r(2949);function a(e){const{protocol:t,pathname:r}=i.default.parse(e);return \"file:\"===t?new s.LocalFile(unescape((0, o.ensureNotNullish)(r))):new s.RemoteFile(e)}Object.defineProperty(t,\"LocalFile\",{enumerable:!0,get:function(){return s.LocalFile}}),Object.defineProperty(t,\"RemoteFile\",{enumerable:!0,get:function(){return s.RemoteFile}}),t.fromUrl=a,t.open=function(e,t,r){if(r)return r;if(e)return a(e);if(t)return new s.LocalFile(t);throw new Error(\"no url, path, or filehandle provided, cannot open\")};},5702:(e,t)=>{Object.defineProperty(t,\"__esModule\",{value:!0}),t.RANS_BYTE_L=t.TOTFREQ=t.TF_SHIFT=void 0,t.TF_SHIFT=12,t.TOTFREQ=4096,t.RANS_BYTE_L=1<<23;},6484:function(e,t,r){var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,\"__esModule\",{value:!0});const i=r(8577),o=r(5702),s=n(r(7634));t.default=function(e,t,r,n){let a=e.getInt(),f=e.getInt(),h=e.getInt(),l=e.getInt();const u=n.remaining(),c=-4&u;for(let i=0;i>2;let c=0,d=u,p=2*u,g=3*u,m=0,y=0,b=0,v=0;for(;c{Object.defineProperty(t,\"__esModule\",{value:!0});const n=r(8577),i=r(5702);class o{constructor(){this.F=void 0,this.C=void 0;}}function s(e,t,r,n){return r*(e>>n)+(e&(1<>o)+(e&(1<=128&&(t.fc[f].F&=-129,t.fc[f].F=(127&t.fc[f].F)<<8|255&e.get()),t.fc[f].C=i,s.default.symbolInit(r[f],t.fc[f].C,t.fc[f].F),t.R||(t.R=new Array(o.TOTFREQ)),t.R.fill(f,i,i+t.fc[f].F),i+=t.fc[f].F,0===n&&f+1===(255&e.getByteAt(e.position()))?(f=255&e.get(),n=255&e.get()):0!==n?(n-=1,f+=1):f=255&e.get();}while(0!==f);a(i=128&&(t[i].fc[l].F&=-129,t[i].fc[l].F=(127&t[i].fc[l].F)<<8|255&e.get()),t[i].fc[l].C=h,0===t[i].fc[l].F&&(t[i].fc[l].F=o.TOTFREQ),null==r[i][l]&&(r[i][l]=new s.default.RansDecSymbol),s.default.symbolInit(r[i][l],t[i].fc[l].C,t[i].fc[l].F),null==t[i].R&&(t[i].R=new Array(o.TOTFREQ)),t[i].R.fill(l,h,h+t[i].fc[l].F),h+=t[i].fc[l].F,a(h<=o.TOTFREQ),0===f&&l+1===(255&e.getByteAt(e.position()))?(l=255&e.get(),f=255&e.get()):0!==f?(f-=1,l+=1):l=255&e.get();}while(0!==l);0===n&&i+1===(255&e.getByteAt(e.position()))?(i=255&e.get(),n=255&e.get()):0!==n?(n-=1,i+=1):i=255&e.get();}while(0!==i)};},9675:function(e,t,r){var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,\"__esModule\",{value:!0});const i=r(8577),o=n(r(7634)),s=r(696),a=n(r(6484)),f=n(r(7121));class h{constructor(e,t=0){this._buffer=e,this._position=t,this.length=e.length;}get(){const e=this._buffer[this._position];return this._position+=1,e}getByte(){return this.get()}getByteAt(e){return this._buffer[e]}position(){return this._position}put(e){return this._buffer[this._position]=e,this._position+=1,e}putAt(e,t){return this._buffer[e]=t,t}setPosition(e){return this._position=e,e}getInt(){const e=this._buffer.readInt32LE(this._position);return this._position+=4,e}remaining(){return this._buffer.length-this._position}}t.default=function(e,t,r=0){if(0===e.length)return t.fill(0),t;const n=new h(e,r),l=n.get();if(0!==l&&1!==l)throw new i.CramMalformedError(`Invalid rANS order ${l}`);if(n.getInt()!==n.remaining()-4)throw new i.CramMalformedError(\"Incorrect input length.\");const u=n.getInt(),c=new h(t||Buffer.allocUnsafe(u));if(c.length{Object.defineProperty(t,\"__esModule\",{value:!0}),t.parseHeaderText=void 0,t.parseHeaderText=function(e){const t=e.split(/\\r?\\n/),r=[];return t.forEach((e=>{const[t,...n]=e.split(/\\t/),i=n.map((e=>{const[t,r]=e.split(\":\",2);return {tag:t,value:r}}));t&&r.push({tag:t.substr(1),data:i});})),r};},4319:(e,t)=>{Object.defineProperty(t,\"__esModule\",{value:!0}),t.ensureNotNullish=void 0,t.ensureNotNullish=function(e){if(null==e)throw new Error(\"Value must not be nullish.\");return e};},597:(e,t,r)=>{Object.defineProperty(t,\"__esModule\",{value:!0}),t.unzip=void 0;const n=r(9591);t.unzip=function(e){return Buffer.from((0, n.inflate)(e))};},9996:(e,t,r)=>{function n(e){return n=\"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},n(e)}var i=r(8764).Buffer,o=r(22),s=r(2961)._,a=r(3720);\"undefined\"!=typeof window&&(window.Buffer=i),\"undefined\"!=typeof self&&(self.Buffer=i);var f={UInt8:1,UInt16LE:2,UInt16BE:2,UInt32LE:4,UInt32BE:4,Int8:1,Int16LE:2,Int16BE:2,Int32LE:4,Int32BE:4,FloatLE:4,FloatBE:4,DoubleLE:8,DoubleBE:8,UInt64:8,Int64:8},h={},l=\"___parser_\",u=[];!function(){var e;for(e=1;e<=32;e++)u.push(e);}();var c={};Object.keys(f).concat(Object.keys({String:null,Buffer:null,Array:null,Skip:null,Choice:null,Nest:null,Bit:null,Itf8:null,Ltf8:null})).forEach((function(e){c[e.toLowerCase()]=e;}));var d=function(){this.varName=\"\",this.type=\"\",this.options={},this.next=null,this.head=null,this.compiled=null,this.endian=\"le\",this.constructorFn=null,this.alias=null;};d.start=function(){return new d},Object.keys(f).forEach((function(e){d.prototype[e.toLowerCase()]=function(t,r){return this.setNextParser(e.toLowerCase(),t,r)};var t=e.replace(/BE|LE/,\"\").toLowerCase();t in d.prototype||(d.prototype[t]=function(e,r){return this[t+this.endian](e,r)});})),u.forEach((function(e){d.prototype[\"bit\".concat(e.toString())]=function(t,r){return r||(r={}),r.length=e,this.setNextParser(\"bit\",t,r)};})),d.prototype.namely=function(e){return h[e]=this,this.alias=e,this},d.prototype.skip=function(e,t){if(t&&t.assert)throw new Error(\"assert option on skip is not allowed.\");return this.setNextParser(\"skip\",\"\",{length:e})},d.prototype.string=function(e,t){if(!t.zeroTerminated&&!t.length&&!t.greedy)throw new Error(\"Neither length, zeroTerminated, nor greedy is defined for string.\");if((t.zeroTerminated||t.length)&&t.greedy)throw new Error(\"greedy is mutually exclusive with length and zeroTerminated for string.\");if(t.stripNull&&!t.length&&!t.greedy)throw new Error(\"Length or greedy must be defined if stripNull is defined.\");return t.encoding=t.encoding||\"utf8\",this.setNextParser(\"string\",e,t)},d.prototype.buffer=function(e,t){if(!t.length&&!t.readUntil)throw new Error(\"Length nor readUntil is defined in buffer parser\");return this.setNextParser(\"buffer\",e,t)},d.prototype.array=function(e,t){if(!t.readUntil&&!t.length&&!t.lengthInBytes)throw new Error(\"Length option of array is not defined.\");if(!t.type)throw new Error(\"Type option of array is not defined.\");if(\"string\"==typeof t.type&&!h[t.type]&&Object.keys(f).indexOf(c[t.type])<0)throw new Error('Specified primitive type \"'.concat(t.type,'\" is not supported.'));return this.setNextParser(\"array\",e,t)},d.prototype.choice=function(e,t){if(1===arguments.length&&\"object\"===n(e)&&(t=e,e=null),!t.tag)throw new Error(\"Tag option of array is not defined.\");if(!t.choices)throw new Error(\"Choices option of array is not defined.\");return Object.keys(t.choices).forEach((function(r){if(!t.choices[r])throw new Error(\"Choice Case \".concat(r,\" of \").concat(e,\" is not valid.\"));if(\"string\"==typeof t.choices[r]&&!h[t.choices[r]]&&Object.keys(f).indexOf(c[t.choices[r]])<0)throw new Error('Specified primitive type \"'.concat(t.choices[r],'\" is not supported.'))}),this),this.setNextParser(\"choice\",e,t)},d.prototype.nest=function(e,t){if(1===arguments.length&&\"object\"===n(e)&&(t=e,e=null),!t.type)throw new Error(\"Type option of nest is not defined.\");if(!(t.type instanceof d||h[t.type]))throw new Error(\"Type option of nest must be a Parser object.\");if(!(t.type instanceof d||e))throw new Error(\"options.type must be a object if variable name is omitted.\");return this.setNextParser(\"nest\",e,t)},d.prototype.endianess=function(e){switch(e.toLowerCase()){case\"little\":this.endian=\"le\";break;case\"big\":this.endian=\"be\";break;default:throw new Error(\"Invalid endianess: \".concat(e))}return this},d.prototype.create=function(e){if(!(e instanceof Function))throw new Error(\"Constructor must be a Function object.\");return this.constructorFn=e,this},d.prototype.getCode=function(){var e=new s;return e.pushCode(\"if (!Buffer.isBuffer(buffer)) {\"),e.generateError('\"argument buffer is not a Buffer object\"'),e.pushCode(\"}\"),this.alias?this.addAliasedCode(e):this.addRawCode(e),this.alias?e.pushCode(\"return {0}(0)\",l+this.alias):e.pushCode(\"return { offset: offset, result: vars };\"),e.code},d.prototype.addRawCode=function(e){e.pushCode(\"var offset = 0;\"),this.constructorFn?e.pushCode(\"var vars = new constructorFn();\"):e.pushCode(\"var vars = {};\"),this.generate(e),this.resolveReferences(e),e.pushCode(\"return { offset: offset, result: vars };\");},d.prototype.addAliasedCode=function(e){return e.pushCode(\"function {0}(offset) {\",l+this.alias),this.constructorFn?e.pushCode(\"var vars = new constructorFn();\"):e.pushCode(\"var vars = {};\"),this.generate(e),e.markResolved(this.alias),this.resolveReferences(e),e.pushCode(\"return { offset: offset, result: vars };\"),e.pushCode(\"}\"),e},d.prototype.resolveReferences=function(e){var t=e.getUnresolvedReferences();e.markRequested(t),t.forEach((function(t){h[t].addAliasedCode(e);}));},d.prototype.compile=function(){var e=\"(function(buffer, constructorFn, Long) { \".concat(this.getCode(),\" })\");this.compiled=o.runInThisContext(e);},d.prototype.sizeOf=function(){var e=NaN;if(Object.keys(f).indexOf(this.type)>=0)e=f[this.type];else if(\"String\"===this.type&&\"number\"==typeof this.options.length)e=this.options.length;else if(\"Buffer\"===this.type&&\"number\"==typeof this.options.length)e=this.options.length;else if(\"Array\"===this.type&&\"number\"==typeof this.options.length){var t=NaN;\"string\"==typeof this.options.type?t=f[c[this.options.type]]:this.options.type instanceof d&&(t=this.options.type.sizeOf()),e=this.options.length*t;}else \"Skip\"===this.type?e=this.options.length:\"Nest\"===this.type?e=this.options.type.sizeOf():this.type||(e=0);return this.next&&(e+=this.next.sizeOf()),e},d.prototype.parse=function(e){return this.compiled||this.compile(),this.compiled(e,this.constructorFn,a)},d.prototype.setNextParser=function(e,t,r){var n=new d;return n.type=c[e],n.varName=t,n.options=r||n.options,n.endian=this.endian,this.head?this.head.next=n:this.next=n,this.head=n,this},d.prototype.generate=function(e){this.type&&(this[\"generate\".concat(this.type)](e),this.generateAssert(e));var t=e.generateVariable(this.varName);return this.options.formatter&&this.generateFormatter(e,t,this.options.formatter),this.generateNext(e)},d.prototype.generateAssert=function(e){if(this.options.assert){var t=e.generateVariable(this.varName);switch(n(this.options.assert)){case\"function\":e.pushCode(\"if (!({0}).call(vars, {1})) {\",this.options.assert,t);break;case\"number\":e.pushCode(\"if ({0} !== {1}) {\",this.options.assert,t);break;case\"string\":e.pushCode('if (\"{0}\" !== {1}) {',this.options.assert,t);break;default:throw new Error(\"Assert option supports only strings, numbers and assert functions.\")}e.generateError('\"Assert error: {0} is \" + {0}',t),e.pushCode(\"}\");}},d.prototype.generateNext=function(e){return this.next&&(e=this.next.generate(e)),e},Object.keys(f).forEach((function(e){d.prototype[\"generate\".concat(e)]=function(t){\"UInt64\"===e?t.pushCode(\"{0} = Long.fromBytes(buffer.slice(offset,offset+8), true, this.endian === 'le').toNumber();\",t.generateVariable(this.varName),e):\"Int64\"===e?t.pushCode(\"{0} = Long.fromBytes(buffer.slice(offset,offset+8), false, this.endian === 'le').toNumber();\",t.generateVariable(this.varName),e):t.pushCode(\"{0} = buffer.read{1}(offset);\",t.generateVariable(this.varName),e),t.pushCode(\"offset += {0};\",f[e]);};})),d.prototype.generateBit=function(e){var t=JSON.parse(JSON.stringify(this));if(t.varName=e.generateVariable(t.varName),e.bitFields.push(t),!this.next||this.next&&[\"Bit\",\"Nest\"].indexOf(this.next.type)<0){var r=0;e.bitFields.forEach((function(e){r+=e.options.length;}));var n=e.generateTmpVariable();if(r<=8)e.pushCode(\"var {0} = buffer.readUInt8(offset);\",n),r=8;else if(r<=16)e.pushCode(\"var {0} = buffer.readUInt16BE(offset);\",n),r=16;else if(r<=24){var i=e.generateTmpVariable(),o=e.generateTmpVariable();e.pushCode(\"var {0} = buffer.readUInt16BE(offset);\",i),e.pushCode(\"var {0} = buffer.readUInt8(offset + 2);\",o),e.pushCode(\"var {2} = ({0} << 8) | {1};\",i,o,n),r=24;}else {if(!(r<=32))throw new Error(\"Currently, bit field sequence longer than 4-bytes is not supported.\");e.pushCode(\"var {0} = buffer.readUInt32BE(offset);\",n),r=32;}e.pushCode(\"offset += {0};\",r/8);var s=0,a=\"be\"===this.endian;e.bitFields.forEach((function(t){e.pushCode(\"{0} = {1} >> {2} & {3};\",t.varName,n,a?r-s-t.options.length:s,(1< offset++);\"),e.pushCode(\"{0} = buffer.toString('{1}', {2}, offset);\",t,this.options.encoding,r)),this.options.stripNull&&e.pushCode(\"{0} = {0}.replace(/\\\\x00+$/g, '')\",t);},d.prototype.generateBuffer=function(e){\"eof\"===this.options.readUntil?e.pushCode(\"{0} = buffer.slice(offset);\",e.generateVariable(this.varName)):(e.pushCode(\"{0} = buffer.slice(offset, offset + {1});\",e.generateVariable(this.varName),e.generateOption(this.options.length)),e.pushCode(\"offset += {0};\",e.generateOption(this.options.length))),this.options.clone&&e.pushCode(\"{0} = Buffer.from({0});\",e.generateVariable(this.varName));},d.prototype.generateArray=function(e){var t=e.generateOption(this.options.length),r=e.generateOption(this.options.lengthInBytes),n=this.options.type,i=e.generateTmpVariable(),o=e.generateVariable(this.varName),s=e.generateTmpVariable(),a=this.options.key,u=\"string\"==typeof a;if(u?e.pushCode(\"{0} = {};\",o):e.pushCode(\"{0} = [];\",o),\"function\"==typeof this.options.readUntil?e.pushCode(\"do {\"):\"eof\"===this.options.readUntil?e.pushCode(\"for (var {0} = 0; offset < buffer.length; {0}++) {\",i):void 0!==r?e.pushCode(\"for (var {0} = offset; offset - {0} < {1}; ) {\",i,r):e.pushCode(\"for (var {0} = 0; {0} < {1}; {0}++) {\",i,t),\"string\"==typeof n)if(h[n]){var p=e.generateTmpVariable();e.pushCode(\"var {0} = {1}(offset);\",p,l+n),e.pushCode(\"var {0} = {1}.result; offset = {1}.offset;\",s,p),n!==this.alias&&e.addReference(n);}else e.pushCode(\"var {0} = buffer.read{1}(offset);\",s,c[n]),e.pushCode(\"offset += {0};\",f[c[n]]);else n instanceof d&&(e.pushCode(\"var {0} = {};\",s),e.pushScope(s),n.generate(e),e.popScope());u?e.pushCode(\"{0}[{2}.{1}] = {2};\",o,a,s):e.pushCode(\"{0}.push({1});\",o,s),e.pushCode(\"}\"),\"function\"==typeof this.options.readUntil&&e.pushCode(\" while (!({0}).call(this, {1}, buffer.slice(offset)));\",this.options.readUntil,s);},d.prototype.generateChoiceCase=function(e,t,r){if(\"string\"==typeof r)if(h[r]){var n=e.generateTmpVariable();e.pushCode(\"var {0} = {1}(offset);\",n,l+r),e.pushCode(\"{0} = {1}.result; offset = {1}.offset;\",e.generateVariable(this.varName),n),r!==this.alias&&e.addReference(r);}else e.pushCode(\"{0} = buffer.read{1}(offset);\",e.generateVariable(this.varName),c[r]),e.pushCode(\"offset += {0};\",f[c[r]]);else r instanceof d&&(e.pushPath(t),r.generate(e),e.popPath(t));},d.prototype.generateChoice=function(e){var t=e.generateOption(this.options.tag);this.varName&&e.pushCode(\"{0} = {};\",e.generateVariable(this.varName)),e.pushCode(\"switch({0}) {\",t),Object.keys(this.options.choices).forEach((function(t){var r=this.options.choices[t];Number.isNaN(parseInt(t,10))?e.pushCode(\"case '{0}':\",t):e.pushCode(\"case {0}:\",t),this.generateChoiceCase(e,this.varName,r),e.pushCode(\"break;\");}),this),e.pushCode(\"default:\"),this.options.defaultChoice?this.generateChoiceCase(e,this.varName,this.options.defaultChoice):e.generateError('\"Met undefined tag value \" + {0} + \" at choice\"',t),e.pushCode(\"}\");},d.prototype.generateNest=function(e){var t=e.generateVariable(this.varName);if(this.options.type instanceof d)this.varName&&e.pushCode(\"{0} = {};\",t),e.pushPath(this.varName),this.options.type.generate(e),e.popPath(this.varName);else if(h[this.options.type]){var r=e.generateTmpVariable();e.pushCode(\"var {0} = {1}(offset);\",r,l+this.options.type),e.pushCode(\"{0} = {1}.result; offset = {1}.offset;\",t,r),this.options.type!==this.alias&&e.addReference(this.options.type);}},d.prototype.generateFormatter=function(e,t,r){\"function\"==typeof r&&e.pushCode(\"{0} = ({1}).call(this, {0});\",t,r);},d.prototype.isInteger=function(){return !!this.type.match(/U?Int[8|16|32][BE|LE]?|Bit\\d+/)},d.prototype.itf8=function(e,t){return this.setNextParser(\"itf8\",e,t)},d.prototype.itf8=function(e,t){return this.setNextParser(\"itf8\",e,t)},d.prototype.generateItf8=function(e){var t=e.generateVariable(this.varName),r=e.generateTmpVariable();e.pushCode(\"\\n var \".concat(r,\" = buffer[offset];\\n if (\").concat(r,\" < 0x80) {\\n \").concat(t,\" = \").concat(r,\";\\n offset += 1;\\n } else if (\").concat(r,\" < 0xc0) {\\n \").concat(t,\" = ((\").concat(r,\"<<8) | buffer[offset+1]) & 0x3fff;\\n offset += 2;\\n } else if (\").concat(r,\" < 0xe0) {\\n \").concat(t,\" = ((\").concat(r,\"<<16) | (buffer[offset+1]<< 8) | buffer[offset+2]) & 0x1fffff;\\n offset += 3;\\n } else if (\").concat(r,\" < 0xf0) {\\n \").concat(t,\" = ((\").concat(r,\"<<24) | (buffer[offset+1]<<16) | (buffer[offset+2]<<8) | buffer[offset+3]) & 0x0fffffff;\\n offset += 4\\n } else {\\n \").concat(t,\" = ((\").concat(r,\" & 0x0f)<<28) | (buffer[offset+1]<<20) | (buffer[offset+2]<<12) | (buffer[offset+3]<<4) | (buffer[offset+4] & 0x0f);\\n // x=((0xff & 0x0f)<<28) | (0xff<<20) | (0xff<<12) | (0xff<<4) | (0x0f & 0x0f);\\n // TODO *val_p = uv < 0x80000000UL ? uv : -((int32_t) (0xffffffffUL - uv)) - 1;\\n offset += 5\\n }\\n \"));},d.prototype.ltf8=function(e,t){return this.setNextParser(\"ltf8\",e,t)},d.prototype.generateLtf8=function(e){var t=e.generateVariable(this.varName),r=e.generateTmpVariable();e.pushCode(\"\\n var \".concat(r,\" = buffer[offset];\\n if (\").concat(r,\" < 0x80) {\\n \").concat(t,\" = \").concat(r,\";\\n offset += 1;\\n } else if (\").concat(r,\" < 0xc0) {\\n \").concat(t,\" = ((buffer[offset]<<8) | buffer[offset+1]) & 0x3fff;\\n offset += 2;\\n } else if (\").concat(r,\" < 0xe0) {\\n \").concat(t,\" = ((buffer[offset]<<16) | (buffer[offset+1]<<8) | buffer[offset+2]) & 0x1fffff;\\n \").concat(t,\" = (((\").concat(r,\" & 63) << 16) | buffer.readUInt16LE(offset + 1));\\n offset += 3;\\n } else if (\").concat(r,\" < 0xf0) {\\n \").concat(t,\" = ((buffer[offset]<<24) | (buffer[offset+1]<<16) | (buffer[offset+2]<<8) | buffer[offset+3]) & 0x0fffffff;\\n offset += 4;\\n } else if (\").concat(r,\" < 0xf8) {\\n \").concat(t,\" = (((buffer[offset] & 15) * Math.pow(2,32))) +\\n (buffer[offset+1]<<24) | (buffer[offset+2]<<16 | buffer[offset+3]<<8 | buffer[offset+4])\\n // TODO *val_p = uv < 0x80000000UL ? uv : -((int32_t) (0xffffffffUL - uv)) - 1;\\n offset += 5;\\n } else if (\").concat(r,\" < 0xfc) {\\n \").concat(t,\" = ((((buffer[offset] & 7) << 8) | buffer[offset+1] )) * Math.pow(2,32) +\\n (buffer[offset+2]<<24) | (buffer[offset+3]<<16 | buffer[offset+4]<<8 | buffer[offset+5])\\n offset += 6;\\n } else if (\").concat(r,\" < 0xfe) {\\n \").concat(t,\" = ((((buffer[offset] & 3) << 16) | buffer[offset+1]<<8 | buffer[offset+2])) * Math.pow(2,32) +\\n (buffer[offset+3]<<24) | (buffer[offset+4]<<16 | buffer[offset+5]<<8 | buffer[offset+6])\\n offset += 7;\\n } else if (\").concat(r,\" < 0xff) {\\n \").concat(t,\" = Long.fromBytesBE(buffer.slice(offset+1,offset+8));\\n if (\").concat(t,\".greaterThan(Number.MAX_SAFE_INTEGER) || \").concat(t,\".lessThan(Number.MIN_SAFE_INTEGER))\\n throw new Error('integer overflow')\\n \").concat(t,\" = \").concat(t,\".toNumber()\\n offset += 8;\\n } else {\\n \").concat(t,\" = Long.fromBytesBE(buffer.slice(offset+1,offset+9));\\n if (\").concat(t,\".greaterThan(Number.MAX_SAFE_INTEGER) || \").concat(t,\".lessThan(Number.MIN_SAFE_INTEGER))\\n throw new Error('integer overflow')\\n \").concat(t,\" = \").concat(t,\".toNumber()\\n offset += 9;\\n }\\n \"));},t.Parser=d;},2961:(e,t)=>{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},r(e)}var n=function(){this.code=\"\",this.scopes=[[\"vars\"]],this.isAsync=!1,this.bitFields=[],this.tmpVariableCount=0,this.references={};};n.prototype.generateVariable=function(e){var t=[];for(Array.prototype.push.apply(t,this.scopes[this.scopes.length-1]);/^\\$parent\\./.test(e);)t.pop(),e=e.replace(/^\\$parent\\./,\"\");return e&&t.push(e),t.join(\".\")},n.prototype.generateOption=function(e){switch(r(e)){case\"number\":return e.toString();case\"string\":return this.generateVariable(e);case\"function\":return \"(\".concat(e,\").call(\").concat(this.generateVariable(),\", vars)\");default:return}},n.prototype.generateError=function(){var e=Array.prototype.slice.call(arguments),t=n.interpolate.apply(this,e);this.isAsync?this.pushCode(\"return process.nextTick(function() { callback(new Error(\".concat(t,\"), vars); });\")):this.pushCode(\"throw new Error(\".concat(t,\");\"));},n.prototype.generateTmpVariable=function(){return \"$tmp\".concat(this.tmpVariableCount++)},n.prototype.pushCode=function(){var e=Array.prototype.slice.call(arguments);this.code+=\"\".concat(n.interpolate.apply(this,e),\"\\n\");},n.prototype.pushPath=function(e){e&&this.scopes[this.scopes.length-1].push(e);},n.prototype.popPath=function(e){e&&this.scopes[this.scopes.length-1].pop();},n.prototype.pushScope=function(e){this.scopes.push([e]);},n.prototype.popScope=function(){this.scopes.pop();},n.prototype.addReference=function(e){this.references[e]||(this.references[e]={resolved:!1,requested:!1});},n.prototype.markResolved=function(e){this.references[e].resolved=!0;},n.prototype.markRequested=function(e){e.forEach(function(e){this.references[e].requested=!0;}.bind(this));},n.prototype.getUnresolvedReferences=function(){var e=this.references;return Object.keys(this.references).filter((function(t){return !e[t].resolved&&!e[t].requested}))},n.interpolate=function(e){var t=/{\\d+}/g,r=e.match(t),n=Array.prototype.slice.call(arguments,1);return r&&r.forEach((function(t){var r=parseInt(t.substr(1,t.length-2),10);e=e.replace(t,n[r].toString());})),e},t._=n;},22:e=>{e.exports.runInThisContext=function(e){return new Function(\"code\",\"return eval(code);\").call(globalThis,e)};},445:(e,t,r)=>{const n=r(7381),i=r(9260),o=r(576),s=r(4693),a=128;e.exports=class{decode(e){return this.stream=new i(e),this.decodeStream(this.stream)}decodeStream(e,t=0){var r=this.stream.ReadByte();16&r||(t=this.stream.ReadUint7());var n,i=t,o=1&r;if(8&r)return this.decodeStripe(this.stream,t);if(r&a&&([n,i]=this.decodePackMeta(this.stream)),32&r)var s=this.decodeCat(this.stream,i);else s=4&r?this.decodeExt(this.stream,i):64&r?o?this.decodeRLE1(this.stream,i):this.decodeRLE0(this.stream,i):o?this.decode1(this.stream,i):this.decode0(this.stream,i);return r&a&&(s=this.decodePack(s,n,t)),s}encode(e,t){if(this.stream=new i(\"\",0,1.1*e.length+100),this.stream.WriteByte(t),16&t||this.stream.WriteUint7(e.length),8&t)return Buffer.concat([this.stream.buf.slice(0,this.stream.pos),this.encodeStripe(this.stream,e,t>>8)]);var r,n=1&t,o=e.length;return t&a&&([r,e,o]=this.encodePack(e)),t&a&&this.stream.WriteStream(r),64&t?n?this.encodeRLE1(e,o,this.stream):this.encodeRLE0(e,o,this.stream):n?this.encode1(e,o,this.stream):this.encode0(e,o,this.stream)}decode0(e,t){var r=new Buffer.allocUnsafe(t),i=e.ReadByte();0==i&&(i=256);var s=new o(i),a=new n(e);a.RangeStartDecode(e);for(var f=0;f=3?3:l;for(f[u].ModelEncode(r,h,c),l-=c,u=256;3==c;)c=l>=3?3:l,f[u].ModelEncode(r,h,c),u=257,l-=c;}return h.RangeFinishEncode(r),r.buf.slice(0,r.pos)}decodeRLE1(e,t){var r=new Buffer.allocUnsafe(t),i=e.ReadByte();0==i&&(i=256);for(var s=new Array(i),a=0;a=3?3:u;for(f[c].ModelEncode(r,h,d),u-=d,c=256;3==d;)d=u>=3?3:u,f[c].ModelEncode(r,h,d),c=257,u-=d;}return h.RangeFinishEncode(r),r.buf.slice(0,r.pos)}decodePackMeta(e){this.nsym=e.ReadByte();for(var t=new Array(this.nsym),r=0;r>=1;}}else if(this.nsym<=4)for(i=0,o=0;i>=2;else {if(!(this.nsym<=16))return e;for(i=0,o=0;i>=4;}return n}packMeta(e){for(var t=new i(\"\",0,1024),r=new Array(256),n=0;ns),n[s]=new Array(o[s]);for(var a=0,f=0;fo),s[o]=this.decodeStream(e,i[o]);var a=new Buffer.allocUnsafe(t);for(o=0;o{e.exports=class{constructor(e){this.low=0,this.range=4294967295,this.code=0,this.FFnum=0,this.carry=0,this.cache=0;}RangeStartDecode(e){for(var t=0;t<5;t++)this.code=(this.code<<8)+e.ReadByte();this.code&=4294967295,this.code>>>=0;}RangeGetFrequency(e){return this.range=Math.floor(this.range/e),Math.floor(this.code/this.range)}RangeDecode(e,t,r,n){for(this.code-=t*this.range,this.range*=r;this.range<1<<24;)this.range*=256,this.code=256*this.code+e.ReadByte();}RangeShiftLow(e){if(this.low<4278190080|this.carry){for(e.WriteByte(this.cache+this.carry);this.FFnum;)e.WriteByte(this.carry-1),this.FFnum--;this.cache=this.low>>>24,this.carry=0;}else this.FFnum++;this.low<<=8,this.low>>>=0;}RangeEncode(e,t,r,n){var i=this.low;for(this.range=Math.floor(this.range/n),this.low+=t*this.range,this.low>>>=0,this.range*=r,this.low{e.exports=class{constructor(e=256){this.total_freq=e,this.max_sym=e-1,this.S=new Array,this.F=new Array;for(var t=0;t<=this.max_sym;t++)this.S[t]=t,this.F[t]=1;}ModelDecode(e,t){for(var r=t.RangeGetFrequency(this.total_freq),n=0,i=0;n+this.F[i]<=r;)n+=this.F[i++];t.RangeDecode(e,n,this.F[i],this.total_freq),this.F[i]+=16,this.total_freq+=16,this.total_freq>65519&&this.ModelRenormalise();var o=this.S[i];if(i>0&&this.F[i]>this.F[i-1]){var s=this.F[i];this.F[i]=this.F[i-1],this.F[i-1]=s,s=this.S[i],this.S[i]=this.S[i-1],this.S[i-1]=s;}return o}ModelRenormalise(){this.total_freq=0;for(var e=0;e<=this.max_sym;e++)this.F[e]-=Math.floor(this.F[e]/2),this.total_freq+=this.F[e];}ModelEncode(e,t,r){for(var n=0,i=0;this.S[i]!=r;i++)n+=this.F[i];if(t.RangeEncode(e,n,this.F[i],this.total_freq),this.F[i]+=16,this.total_freq+=16,this.total_freq>65519&&this.ModelRenormalise(),r=this.S[i],i>0&&this.F[i]>this.F[i-1]){var o=this.F[i];this.F[i]=this.F[i-1],this.F[i-1]=o,o=this.S[i],this.S[i]=this.S[i-1],this.S[i-1]=o;}}};},5260:(e,t,r)=>{const n=r(9260),i=r(576),o=r(7381);function s(e,t,r){for(var n=0,i=0,o=-1,s=new Array(1024);i>4,t.qshift=15&r,r=e.ReadByte(),t.qloc=r>>4,t.sloc=15&r,r=e.ReadByte(),t.ploc=r>>4,t.dloc=15&r,t.qmap=new Array(256),16&t.pflags)for(var n=0;n0&&128&t.pflags)s(e,t.qtab,256);else for(n=0;n<256;n++)t.qtab[n]=n;return t.ptab=new Array(1024),32&t.pflags&&s(e,t.ptab,1024),t.dtab=new Array(256),64&t.pflags&&s(e,t.dtab,256),t}function h(e,t,r,n,i,o){r.max_sel>0?i.s=n.sel.ModelDecode(e,t):i.s=0,i.x=r.stab[i.s];var s=r.params[i.x];if(s.fixed_len>=0){var a=n.len[0].ModelDecode(e,t);a|=n.len[1].ModelDecode(e,t)<<8,a|=n.len[2].ModelDecode(e,t)<<16,a|=n.len[3].ModelDecode(e,t)<<24,s.fixed_len>0&&(s.fixed_len=-a);}else a=-s.fixed_len;i.len=a,r.do_rev&&(o[i.rec]=n.rev.ModelDecode(e,t)),i.is_dup=0,2&s.pflags&&n.dup.ModelDecode(e,t)&&(i.is_dup=1),i.p=a,i.delta=0,i.qctx=0,i.prevq=0,i.rec++;}function l(e,t,r){for(var n=0,i=0,o=new Array(2*r),s=0;n1?r.nparam-1:0,o=new Array(256);if(2&r)i=e.ReadByte(),s(e,o,256);else {for(var a=0;a0&&(t.sel=new i(e.max_sel+1)),t}(n),d=new o(e);d.RangeStartDecode(e);for(var p=new Buffer.allocUnsafe(r),g={qctx:0,prevq:0,delta:0,p:0,s:0,x:0,len:0,is_dup:0,rec:0},m=0;m0&&c.dup.ModelDecode(e,d)){for(var y=0;y4),qshift:u,qloc:7,pbits:7,pshift:t[0]>128?1:0,ploc:0,dbits:u>4?0:1,dshift:3,dloc:15,sbits:0,sloc:15,do_stab:0,context:0,max_sym:f,nsym:a,do_qmap:c,do_dedup:0,fixed_len:1==t.length?1:0,do_sel:0,do_rev:0,do_pos:1,do_delta:u<=4?1:0,do_qtab:0,qbits:8+(u>4)-(0==s),sbits:1,sloc:15-(u<=4),do_stab:1,do_sel:1}]}(e,t,r,s),p=function(e,t,r,n,i,o,s){for(var a=[0,1,1,1,2,2,2,2,2,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7],f=0;f1?1:0)|(t[0].do_stab?2:0);if(e.WriteByte(h),1&h&&e.WriteByte(t.length),2&h){var u=1<0&&u--,e.WriteByte(u),l(e,s,256);}for(var c=0;c0){for(f=0;f<256;f++)n[c][f]=f;t[c].do_qtab&&l(e,n[c],256);}if(t[c].pbits>0){for(f=0;f<1024;f++)i[c][f]=Math.min((1<>t[c].pshift);l(e,i[c],1024);}if(t[c].dbits>0){for(f=0;f<256;f++)a[f]>(1<>t[c].dshift)];l(e,o[c],256);}}return e}(p,d,s,a,f,h,u);return function(e,t,r,n,s,a,f,h,l,u){var c=1<0&&c--;for(var d=t.length,p=0,g=0;g0&&v.ModelEncode(e,w,B);var E=u[B],S=r[Math.min(r.length-1,_++)];s[E].fixed_len?s[E].fixed_len>0&&(b[0].ModelEncode(e,w,255&S),b[1].ModelEncode(e,w,S>>8&255),b[2].ModelEncode(e,w,S>>16&255),b[3].ModelEncode(e,w,S>>24&255),s[E].fixed_len=-1):(b[0].ModelEncode(e,w,255&S),b[1].ModelEncode(e,w,S>>8&255),b[2].ModelEncode(e,w,S>>16&255),b[3].ModelEncode(e,w,S>>24&255)),s[E].do_dedup&&process.exit(1),g=S;var A=0,C=s[E].context,R=0,k=0;}var x=t[y++],I=a[E][x];m[C].ModelEncode(e,w,I),R=(R<0&&(C+=h[E][Math.min(g,1023)]<0&&(C+=l[E][Math.min(A,255)]<{var n=r(4459),i=r(594),o=r(445),s=r(5260),a=r(2881);e.exports={r4x8_uncompress:function(e,t){n.decode(e).copy(t,0,0);},r4x16_uncompress:function(e,t){i.decode(e).copy(t,0,0);},arith_uncompress:function(e,t){o.decode(e).copy(t,0,0);},fqzcomp_uncompress:function(e,t){var r=new Array;s.decode(e,r).copy(t,0,0);},tok3_uncompress:function(e,t){var r=a.decode(e,0,\"\\0\");Buffer.from(r,\"binary\").copy(t,0,0);}};},9260:e=>{e.exports=class{constructor(e,t=0,r=0){0!=r?(this.buf=Buffer.allocUnsafe(r),this.length=r):(this.buf=e,this.length=e.length),this.pos=t;}EOF(){return this.pos>=this.length}ReadData(e){var t=this.buf.slice(this.pos,this.pos+e);return this.pos+=e,t}ReadByte(){const e=this.buf[this.pos];return this.pos++,e}ReadChar(){const e=this.buf[this.pos];return this.pos++,String.fromCharCode(e)}ReadUint16(){return this.ReadByte()|this.ReadByte()<<8}ReadUint32(){const e=this.buf.readInt32LE(this.pos);return this.pos+=4,e}ReadString(){var e=\"\";do{var t=this.buf[this.pos++];t&&(e+=String.fromCharCode(t));}while(t);return e}ReadUint7(){var e=0;do{var t=this.ReadByte();e=e<<7|127&t;}while(128&t);return e}ReadITF8(){var e=this.buf[this.pos];return this.pos++,e>=240?(e=(15&e)<<28,e+=(this.buf[this.pos+0]<<20)+(this.buf[this.pos+1]<<12)+(this.buf[this.pos+2]<<4)+(this.buf[this.pos+3]>>4),this.pos+=4):e>=224?(e=(15&e)<<24,e+=(this.buf[this.pos+0]<<16)+(this.buf[this.pos+1]<<8)+(this.buf[this.pos+2]<<0),this.pos+=3):e>=192?(e=(31&e)<<16,e+=(this.buf[this.pos+0]<<8)+(this.buf[this.pos+1]<<0),this.pos+=2):e>=128&&(e=(63&e)<<8,e+=this.buf[this.pos],this.pos++),e}WriteByte(e){this.buf[this.pos++]=e;}WriteChar(e){this.buf[this.pos++]=e.charCodeAt(0);}WriteString(e){for(var t=0;t>8&255);}WriteUint32(e){this.buf.writeInt32LE(e,this.pos),this.pos+=4;}WriteUint7(e){var t=0,r=e;do{t+=7,r>>=7;}while(r>0);do{t-=7,this.WriteByte((e>>t&127)+((t>0)<<7));}while(t>0)}WriteITF8(e){e<0&&(e=1+e),e<=127?this.buf[this.pos++]=e:e<=16383?(this.buf[this.pos++]=128|Math.floor(e/256),this.buf[this.pos++]=255&e):e<131071?(this.buf[this.pos++]=192|Math.floor(e/65536),this.buf[this.pos++]=255&Math.floor(e/256),this.buf[this.pos++]=255&e):e<268435455?(this.buf[this.pos++]=224|Math.floor(e/16777216),this.buf[this.pos++]=255&Math.floor(e/65536),this.buf[this.pos++]=255&Math.floor(e/256),this.buf[this.pos++]=255&e):(this.buf[this.pos++]=240|Math.floor(e/268435456),this.buf[this.pos++]=255&Math.floor(e/1048576),this.buf[this.pos++]=255&Math.floor(e/4096),this.buf[this.pos++]=255&Math.floor(e/4),this.buf[this.pos++]=15&e);}WriteByteNeg(e){this.buf[--this.pos]=e;}};},4459:(e,t,r)=>{const n=r(9260);function i(e){return 4095&e}function o(e,t){for(var r=0;t>=e[r+1];)r++;return r}function s(e){for(var t=new Array(4096),r=0,n=0;n<4096;n++){for(;n>=e[r+1];)r++;t[n]=r;}return t}function a(e,t,r){return r*(e>>12)+(4095&e)-t}function f(e,t){for(;t<1<<23;)t=(t<<8)+e.ReadByte();return t}function h(e,t){t.WriteByteNeg(e>>24&255),t.WriteByteNeg(e>>16&255),t.WriteByteNeg(e>>8&255),t.WriteByteNeg(e>>0&255);}function l(e,t,r,n,i){return e=function(e,t,r,n){for(var i=(1<<23>>n<<8)*r;e>=i;)t.WriteByteNeg(255&e),e>>=8;return e}(e,t,n,i),(Math.floor(e/n)<0?(s--,i++):(i=e.ReadByte())==o+1&&(s=e.ReadByte()),o=i;}while(0!=i);for(r[0]=0,n=0;n<=255;n++)r[n+1]=r[n]+t[n];}function c(e){for(var t=0,r=0;r<256;r++)t+=e[r];const n=4096;var i=n/t;do{var o=0,s=0,a=0;for(t=0,r=0;r<256;r++)0!=e[r]&&(o2?e[s]-=t-n:t!=n&&(i*=.99,a=1);}while(a)}function d(e,t){for(var r=0,n=0;n<256;n++)if(t[n]){if(r>0)r--;else if(e.WriteByte(n),n>0&&t[n-1]>0){for(r=n+1;r<256&&t[r];r++);r-=n+1,e.WriteByte(r);}e.WriteITF8(t[n]);}e.WriteByte(0);}e.exports={decode:function(e){var t=new n(e),r=t.ReadByte(),h=(t.ReadUint32(),t.ReadUint32());return 0==r?function(e,t){var r=new Array(256),n=new Array(256);u(e,r,n);for(var o=s(n),h=new Array(4),l=0;l<4;l++)h[l]=e.ReadUint32();var c=new Buffer.allocUnsafe(t);for(l=0;l0?(a--,o++):(o=e.ReadByte())==s+1&&(a=e.ReadByte()),s=o;}while(0!=o)}(e,r,n);for(var h=new Array(256),l=0;l<256;l++)h[l]=s(n[l]);for(var c=new Array(4),d=new Array(4),p=0;p<4;p++)c[p]=e.ReadUint32(),d[p]=0;var g=new Buffer.allocUnsafe(t),m=Math.floor(t/4);for(l=0;l=0;s--)a[s%4]=l(a[s%4],u,o[e[s]],i[e[s]],12);for(s=3;s>=0;s--)h(a[s],u);var p=r.pos;return r.buf.writeInt32LE(p-9+(u.length-u.pos),1),r.buf.writeInt32LE(t,5),Buffer.concat([r.buf.slice(0,r.pos),u.buf.slice(u.pos,u.length)],r.pos+u.length-u.pos)}(e):function(e){const t=e.length;var r=new n(\"\",0,198156);r.WriteByte(1),r.WriteUint32(0),r.WriteUint32(0);for(var i=new Array(256),o=new Array(256),s=new Array(256),a=0;a<256;a++)o[a]=new Array(256),s[a]=new Array(256);for(function(e,t,r){for(var n=0;n<256;n++){r[n]=0;for(var i=0;i<256;i++)t[n][i]=0;}var o=0;for(n=0;n>2)]]++,t[0][e[2*(e.length>>2)]]++,t[0][e[3*(e.length>>2)]]++,r[0]+=3;}(e,o,i),function(e,t){for(var r=0;r<256;r++)t[r]&&c(e[r]);}(o,i),function(e,t,r){for(var n=0,i=0;i<256;i++)if(r[i]){if(n>0)n--;else if(e.WriteByte(i),i>0&&r[i-1]>0){for(n=i+1;n<256&&r[n];n++);n-=i+1,e.WriteByte(n);}d(e,t[i]);}e.WriteByte(0);}(r,o,i),a=0;a<256;a++)if(i[a]){s[a][0]=0;for(var f=1;f<256;f++)s[a][f]=s[a][f-1]+o[a][f-1];}var u=new Array(4),p=new Array(4);for(f=0;f<4;f++)u[f]=1<<23,p[f]=0;var g=new n(\"\",t,t),m=Math.floor(t/4),y=new Array(4),b=new Array(4);for(f=0;f<4;f++)y[f]=(f+1)*m-2,b[f]=e[y[f]+1];for(b[3]=e[t-1],a=t-2;a>4*m-2;a--)u[3]=l(u[3],g,s[e[a]][b[3]],o[e[a]][b[3]],12),b[3]=e[a];for(;y[0]>=0;)for(f=3;f>=0;f--){var v=e[y[f]];u[f]=l(u[f],g,s[v][b[f]],o[v][b[f]],12),b[f]=v,y[f]--;}for(f=3;f>=0;f--)u[f]=l(u[f],g,s[0][b[f]],o[0][b[f]],12);for(a=3;a>=0;a--)h(u[a],g);var w=r.pos;return r.buf.writeInt32LE(w-9+(g.length-g.pos),1),r.buf.writeInt32LE(t,5),Buffer.concat([r.buf.slice(0,r.pos),g.buf.slice(g.pos,g.length)],r.pos+g.length-g.pos)}(e)}};},594:(e,t,r)=>{const n=r(9260);function i(e,t){return e&(1<=e[r+1];)r++;return r}function s(e,t){for(var r=1<=e[i+1];)i++;n[o]=i;}return n}function a(e,t,r,n){return r*(e>>n)+(e&(1<>24&255),t.WriteByteNeg(e>>16&255),t.WriteByteNeg(e>>8&255),t.WriteByteNeg(e>>0&255);}function l(e,t,r,n,i){return e=function(e,t,r,n){for(var i=(1<<31-n)*r;e>=i;)t.WriteByteNeg(e>>8&255),t.WriteByteNeg(255&e),e>>=16;return e}(e,t,n,i),(Math.floor(e/n)<s),i[s]=new Array(o[s]);for(var a=0,f=0;fo),s[o]=c(e,i[o]);var a=new Buffer.allocUnsafe(t);for(o=0;o>4,h=e;if(1&c){var l=e.ReadUint7(),u=e.ReadUint7(),c=new n(e.ReadData(u));h=new n(g(c,l));}var d=new Array(256),m=new Array(256);!function(e,t,r,n){for(var i=0;i<256;i++){t[i]=new Array(256),r[i]=new Array(256);for(var o=0;o<256;o++)t[i][o]=0;}var s=p(e);for(i=0;i<256;i++)if(s[i]){var a=0;for(o=0;o<256;o++)s[o]&&(a>0?a--:(t[i][o]=e.ReadUint7(),0==t[i][o]&&(a=e.ReadByte())));for(y(t[i],n),r[i][0]=0,o=0;o<256;o++)r[i][o+1]=r[i][o]+t[i][o];}}(h,d,m,r);for(var b=new Array(256),v=0;v<256;v++)b[v]=s(m[v],r);for(var w=new Array(4),_=new Array(4),B=0;B<4;B++)w[B]=e.ReadUint32(),_[B]=0;var E=new Buffer.allocUnsafe(t),S=Math.floor(t/4);for(v=0;v>=1;}else if(r<=4)for(s=0;s>=2;else if(r<=16)for(s=0;s>=4;return i}(S,v,w,b)),S}function d(e,t){var r=new n(\"\",0,10);r.WriteByte(t);var i=1&t,o=8&t,s=32&t,a=64&t,f=128&t,c=t>>8;if(16&t||r.WriteUint7(e.length),o)return Buffer.concat([r.buf.slice(0,r.pos),u(0,e,c)]);var d=new Buffer.alloc(0);f&&([d,e]=function(e){for(var t=new Array(256),r=0;r<256;r++)t[r]=0;for(r=0;r0&&(i[r]=o++);if(!(o>16)){if(o<=1)var s=new Buffer.allocUnsafe(0);else if(o<=2){s=new Buffer.allocUnsafe(Math.ceil(e.length/8));var a=-1;for(r=0;r0&&(t[r]=a++,f.WriteByte(r));return f.WriteUint7(s.length),[f.buf.slice(0,f.pos),s]}}(e));var p=new Buffer.alloc(0);if(a&&([p,e]=function(e){for(var t=new Array(256),r=0;r<256;r++)t[r]=0;var i=-1;for(r=0;r0&&o++;for(o||(o=1,t[0]=1),(h=new n(\"\",0,o+1+e.length)).WriteByte(o),r=0;r<256;r++)t[r]>0&&h.WriteByte(r);var s=new Buffer.allocUnsafe(e.length),a=0;for(r=0;r0){i=e[r];for(var f=0;r+f+1>2)]]++,t[0][e[2*(e.length>>2)]]++,t[0][e[3*(e.length>>2)]]++,r[0]+=3;}))(e,o,i),function(e,t,r){for(var n=0;n<256;n++)if(t[n]){var i=Math.ceil(Math.log2(t[n]));i>12&&(i=12),m(e[n],i);}}(o,i);var u=new n(\"\",0,198156);!function(e,t,r){b(e,r);for(var n=0;n<256;n++)if(r[n])for(var i=0,o=0;o<256;o++)if(r[o])if(i)i--;else if(e.WriteUint7(t[n][o]),!t[n][o]){for(var s=o+1;s<256;s++)if(r[s]){if(0!=t[n][s])break;i++;}e.WriteByte(i);}}(u,o,i);var c=v(u.buf.slice(0,u.pos));for(c.length>0,1.05*t+100>>0),_=Math.floor(t/4),B=new Array(4),E=new Array(4);for(d=0;d<4;d++)B[d]=(d+1)*_-2,E[d]=e[B[d]+1];for(E[3]=e[t-1],a=t-2;a>4*_-2;a--)p[3]=l(p[3],w,s[e[a]][E[3]],o[e[a]][E[3]],f),E[3]=e[a];for(;B[0]>=0;)for(d=3;d>=0;d--){var S=e[B[d]];p[d]=l(p[d],w,s[S][E[d]],o[S][E[d]],f),E[d]=S,B[d]--;}for(d=3;d>=0;d--)p[d]=l(p[d],w,s[0][E[d]],o[0][E[d]],f);for(a=3;a>=0;a--)h(p[a],w);return Buffer.concat([r.buf.slice(0,r.pos),w.buf.slice(w.pos,w.length)],r.pos+w.length-w.pos)}(e);return Buffer.concat([r.buf.slice(0,r.pos),d,p,g])}function p(e){for(var t=new Array(256),r=0;r<256;r++)t[r]=0;var n=0,i=e.ReadByte(),o=i;do{t[i]=1,n>0?(n--,i++):(i=e.ReadByte())==o+1&&(n=e.ReadByte()),o=i;}while(0!=i);return t}function g(e,t){var r=new Array(256),n=new Array(256);!function(e,t,r){for(var n=0;n<256;n++)t[n]=0;var i=p(e);for(n=0;n<256;n++)i[n]>0&&(t[n]=e.ReadUint7());for(y(t,12),r[0]=0,n=0;n<=255;n++)r[n+1]=r[n]+t[n];}(e,r,n);for(var o=s(n,12),h=new Array(4),l=0;l<4;l++)h[l]=e.ReadUint32();var u=new Buffer.allocUnsafe(t);for(l=0;l2?e[a]-=r-i:r!=i&&(o=i/r,f=1);}while(f)}function y(e,t){for(var r=0,n=0;n<256;n++)r+=e[n];if(0!=r&&r!=1<0)r--;else if(e.WriteByte(n),n>0&&t[n-1]>0){for(r=n+1;r<256&&t[r];r++);r-=n+1,e.WriteByte(r);}e.WriteByte(0);}function v(e){const t=e.length;var r=new n(\"\",0,780),i=new Array(256);!function(e,t){for(var r=0;r<256;r++)t[r]=0;for(r=0;r12&&(o=12),m(i,o),function(e,t){b(e,t);for(var r=0;r<256;r++)t[r]&&e.WriteUint7(t[r]);}(r,i),m(i,12);var s=new Array(256);s[0]=0;for(var a=1;a<256;a++)s[a]=s[a-1]+i[a-1];var f=new Array(4);for(a=0;a<4;a++)f[a]=32768;var u=new n(\"\",1.05*t+100>>0,1.05*t+100>>0);for(a=t-1;a>=0;a--)f[a%4]=l(f[a%4],u,s[e[a]],i[e[a]],12);for(a=3;a>=0;a--)h(f[a],u);return Buffer.concat([r.buf.slice(0,r.pos),u.buf.slice(u.pos,u.length)],r.pos+u.length-u.pos)}e.exports={decode:function(e){return c(new n(e),0)},encode:d};},2881:(e,t,r)=>{const n=r(9260),i=r(594);var o=new(r(445));function s(e,t){for(var r=e+\"\";r.length>0)+e[a][8].ReadByte();break;case 9:f=(r[o][a]>>0)+e[a][9].ReadByte(),h=r[o][a].length,r[n][a]=s(f,h);break;case 10:r[n][a]=r[o][a];break;default:r[n][a]=\"\";}t[n]+=r[n][a++];}while(12!=i);return t[n]}function f(e,t,r,n,i,o){for(var s=0;s0&&5==t[s][0].type)&&t[s][r])switch(e[0].WriteByte(t[s][r].type),t[s][r].type){case 6:e[6].WriteUint32(t[s][r].val);break;case 5:e[5].WriteUint32(t[s][r].val);break;case 1:e[1].WriteString(t[s][r].val);break;case 2:e[2].WriteChar(t[s][r].val);break;case 7:e[7].WriteUint32(t[s][r].val);break;case 3:e[3].WriteUint32(t[s][r].val),e[4].WriteByte(t[s][r].val.length);break;case 8:case 9:e[t[s][r].type].WriteByte(t[s][r].val);}}function h(e,t,r,n){for(var i=0;i<=12;i++)if(!(e[i].pos<=0)){n.WriteByte(i+(0==i?128:0)),e[i]=e[i].buf.slice(0,e[i].pos);var o=l(e[i],r);n.WriteUint7(o.length),n.WriteData(o,o.length);}}function l(e,t){var r,n=1<<30,s=[0,1,64,65,128,129,201];for(var a in s){var f=s[a];if(!(1&f&&e.length<100||8&f&&e.length%4!=0)){try{var h=t?o.encode(e,f):i.encode(e,f);}catch(e){h=0;}h&&n>h.length&&(n=h.length,r=h);}}return r}function u(e,t,r,n,i){var o=0,s=i-1;e[i]=new Array(256),t[n]?e[i][0]={type:5,val:i-t[n]}:e[i][0]={type:6,val:0==i?0:1},t[n]=i;for(var a=n.match(/([a-zA-Z0-9]{1,9})|([^a-zA-Z0-9]+)/g),f=0;f=0&&e[s][h])if(e[s][h].str==a[f])l=10,u=\"\";else if(7==e[s][h].type||8==e[s][h].type){var c=u-e[s][h].str;r[h]++,c>=0&&c<256&&r[h]>i/2&&(l=8,u=c);}else 3!=e[s][h].type&&9!=e[s][h].type||e[s][h].str.length!=u.length||(c=u-e[s][h].str,r[h]++,c>=0&&c<256&&r[h]>i/2&&(l=9,u=c));e[i][h]={str:a[f],val:u,type:l},o{a.callback(e);})),settled:!1,statusReporter:a,get aborted(){return this.aborter.signal.aborted}};f.aborter.addSignal(r),f.aborter.signal.addEventListener(\"abort\",(()=>{f.settled||this.evict(e,f);})),f.promise.then((()=>{f.settled=!0;}),(()=>{f.settled=!0,this.evict(e,f);})).catch((e=>{throw console.error(e),e})),this.cache.set(e,f);}static checkSinglePromise(e,t){function r(){if(t&&t.aborted)throw Object.assign(new Error(\"aborted\"),{code:\"ERR_ABORTED\"})}return e.then((e=>(r(),e)),(e=>{throw r(),e}))}has(e){return this.cache.has(e)}get(e,t,r,n){if(!r&&t instanceof i.AbortSignal)throw new TypeError(\"second get argument appears to be an AbortSignal, perhaps you meant to pass `null` for the fill data?\");const o=this.cache.get(e);return o?o.aborted&&!o.settled?(this.evict(e,o),this.get(e,t,r,n)):o.settled?o.promise:(o.aborter.addSignal(r),o.statusReporter.addCallback(n),a.checkSinglePromise(o.promise,r)):(this.fill(e,t,r,n),a.checkSinglePromise(this.cache.get(e).promise,r))}delete(e){const t=this.cache.get(e);t&&(t.settled||t.aborter.abort(),this.cache.delete(e));}clear(){const e=this.cache.keys();let t=0;for(let r=e.next();!r.done;r=e.next())this.delete(r.value),t+=1;return t}}t.default=a;},9049:(e,t,r)=>{Object.defineProperty(t,\"__esModule\",{value:!0});const n=r(8904);class i{}t.default=class{constructor(){this.signals=new Set,this.abortController=new n.AbortController;}addSignal(e=new i){if(this.signal.aborted)throw new Error(\"cannot add a signal, already aborted!\");this.signals.add(e),e.aborted?this.handleAborted(e):\"function\"==typeof e.addEventListener&&e.addEventListener(\"abort\",(()=>{this.handleAborted(e);}));}handleAborted(e){this.signals.delete(e),0===this.signals.size&&this.abortController.abort();}get signal(){return this.abortController.signal}abort(){this.abortController.abort();}};},450:(e,t)=>{Object.defineProperty(t,\"__esModule\",{value:!0}),t.default=class{constructor(){this.callbacks=new Set;}addCallback(e=(()=>{})){this.callbacks.add(e),e(this.currentMessage);}callback(e){this.currentMessage=e,this.callbacks.forEach((t=>{t(e);}));}};},8904:(e,t,r)=>{Object.defineProperty(t,\"__esModule\",{value:!0}),t.AbortSignal=t.AbortController=void 0;const n=r(5988);var i=function(){if(\"undefined\"!=typeof self)return self;if(\"undefined\"!=typeof window)return window;if(void 0!==r.g)return r.g;throw new Error(\"unable to locate global object\")};let o=void 0===i().AbortController?n.AbortController:i().AbortController;t.AbortController=o;let s=void 0===i().AbortController?n.AbortSignal:i().AbortSignal;t.AbortSignal=s;},4105:function(e,t,r){var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,\"__esModule\",{value:!0});const i=n(r(1422));t.default=i.default;},5988:(e,t)=>{function r(e,t){if(!(e instanceof t))throw new TypeError(\"Cannot call a class as a function\")}function n(e,t){for(var r=0;r{t.byteLength=function(e){var t=f(e),r=t[0],n=t[1];return 3*(r+n)/4-n},t.toByteArray=function(e){var t,r,o=f(e),s=o[0],a=o[1],h=new i(function(e,t,r){return 3*(t+r)/4-r}(0,s,a)),l=0,u=a>0?s-4:s;for(r=0;r>16&255,h[l++]=t>>8&255,h[l++]=255&t;return 2===a&&(t=n[e.charCodeAt(r)]<<2|n[e.charCodeAt(r+1)]>>4,h[l++]=255&t),1===a&&(t=n[e.charCodeAt(r)]<<10|n[e.charCodeAt(r+1)]<<4|n[e.charCodeAt(r+2)]>>2,h[l++]=t>>8&255,h[l++]=255&t),h},t.fromByteArray=function(e){for(var t,n=e.length,i=n%3,o=[],s=16383,a=0,f=n-i;af?f:a+s));return 1===i?(t=e[n-1],o.push(r[t>>2]+r[t<<4&63]+\"==\")):2===i&&(t=(e[n-2]<<8)+e[n-1],o.push(r[t>>10]+r[t>>4&63]+r[t<<2&63]+\"=\")),o.join(\"\")};for(var r=[],n=[],i=\"undefined\"!=typeof Uint8Array?Uint8Array:Array,o=\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\",s=0,a=o.length;s0)throw new Error(\"Invalid string. Length must be a multiple of 4\");var r=e.indexOf(\"=\");return -1===r&&(r=t),[r,r===t?0:4-r%4]}function h(e,t,n){for(var i,o,s=[],a=t;a>18&63]+r[o>>12&63]+r[o>>6&63]+r[63&o]);return s.join(\"\")}n[\"-\".charCodeAt(0)]=62,n[\"_\".charCodeAt(0)]=63;},2779:(e,t,r)=>{var n=r(8764).Buffer,i=[0,1996959894,3993919788,2567524794,124634137,1886057615,3915621685,2657392035,249268274,2044508324,3772115230,2547177864,162941995,2125561021,3887607047,2428444049,498536548,1789927666,4089016648,2227061214,450548861,1843258603,4107580753,2211677639,325883990,1684777152,4251122042,2321926636,335633487,1661365465,4195302755,2366115317,997073096,1281953886,3579855332,2724688242,1006888145,1258607687,3524101629,2768942443,901097722,1119000684,3686517206,2898065728,853044451,1172266101,3705015759,2882616665,651767980,1373503546,3369554304,3218104598,565507253,1454621731,3485111705,3099436303,671266974,1594198024,3322730930,2970347812,795835527,1483230225,3244367275,3060149565,1994146192,31158534,2563907772,4023717930,1907459465,112637215,2680153253,3904427059,2013776290,251722036,2517215374,3775830040,2137656763,141376813,2439277719,3865271297,1802195444,476864866,2238001368,4066508878,1812370925,453092731,2181625025,4111451223,1706088902,314042704,2344532202,4240017532,1658658271,366619977,2362670323,4224994405,1303535960,984961486,2747007092,3569037538,1256170817,1037604311,2765210733,3554079995,1131014506,879679996,2909243462,3663771856,1141124467,855842277,2852801631,3708648649,1342533948,654459306,3188396048,3373015174,1466479909,544179635,3110523913,3462522015,1591671054,702138776,2966460450,3352799412,1504918807,783551873,3082640443,3233442989,3988292384,2596254646,62317068,1957810842,3939845945,2647816111,81470997,1943803523,3814918930,2489596804,225274430,2053790376,3826175755,2466906013,167816743,2097651377,4027552580,2265490386,503444072,1762050814,4150417245,2154129355,426522225,1852507879,4275313526,2312317920,282753626,1742555852,4189708143,2394877945,397917763,1622183637,3604390888,2714866558,953729732,1340076626,3518719985,2797360999,1068828381,1219638859,3624741850,2936675148,906185462,1090812512,3747672003,2825379669,829329135,1181335161,3412177804,3160834842,628085408,1382605366,3423369109,3138078467,570562233,1426400815,3317316542,2998733608,733239954,1555261956,3268935591,3050360625,752459403,1541320221,2607071920,3965973030,1969922972,40735498,2617837225,3943577151,1913087877,83908371,2512341634,3803740692,2075208622,213261112,2463272603,3855990285,2094854071,198958881,2262029012,4057260610,1759359992,534414190,2176718541,4139329115,1873836001,414664567,2282248934,4279200368,1711684554,285281116,2405801727,4167216745,1634467795,376229701,2685067896,3608007406,1308918612,956543938,2808555105,3495958263,1231636301,1047427035,2932959818,3654703836,1088359270,936918e3,2847714899,3736837829,1202900863,817233897,3183342108,3401237130,1404277552,615818150,3134207493,3453421203,1423857449,601450431,3009837614,3294710456,1567103746,711928724,3020668471,3272380065,1510334235,755167117];function o(e){if(n.isBuffer(e))return e;var t=\"function\"==typeof n.alloc&&\"function\"==typeof n.from;if(\"number\"==typeof e)return t?n.alloc(e):new n(e);if(\"string\"==typeof e)return t?n.from(e):new n(e);throw new Error(\"input must be buffer, number, or string, received \"+typeof e)}function s(e){var t=o(4);return t.writeInt32BE(e,0),t}function a(e,t){e=o(e),n.isBuffer(t)&&(t=t.readUInt32BE(0));for(var r=-1^~~t,s=0;s>>8;return -1^r}function f(){return s(a.apply(null,arguments))}\"undefined\"!=typeof Int32Array&&(i=new Int32Array(i)),f.signed=function(){return a.apply(null,arguments)},f.unsigned=function(){return a.apply(null,arguments)>>>0},e.exports=f;},8764:(e,t,r)=>{const n=r(9742),i=r(645),o=\"function\"==typeof Symbol&&\"function\"==typeof Symbol.for?Symbol.for(\"nodejs.util.inspect.custom\"):null;t.Buffer=f,t.SlowBuffer=function(e){return +e!=e&&(e=0),f.alloc(+e)},t.INSPECT_MAX_BYTES=50;const s=2147483647;function a(e){if(e>s)throw new RangeError('The value \"'+e+'\" is invalid for option \"size\"');const t=new Uint8Array(e);return Object.setPrototypeOf(t,f.prototype),t}function f(e,t,r){if(\"number\"==typeof e){if(\"string\"==typeof t)throw new TypeError('The \"string\" argument must be of type string. Received type number');return u(e)}return h(e,t,r)}function h(e,t,r){if(\"string\"==typeof e)return function(e,t){if(\"string\"==typeof t&&\"\"!==t||(t=\"utf8\"),!f.isEncoding(t))throw new TypeError(\"Unknown encoding: \"+t);const r=0|g(e,t);let n=a(r);const i=n.write(e,t);return i!==r&&(n=n.slice(0,i)),n}(e,t);if(ArrayBuffer.isView(e))return function(e){if(Q(e,Uint8Array)){const t=new Uint8Array(e);return d(t.buffer,t.byteOffset,t.byteLength)}return c(e)}(e);if(null==e)throw new TypeError(\"The first argument must be one of type string, Buffer, ArrayBuffer, Array, or Array-like Object. Received type \"+typeof e);if(Q(e,ArrayBuffer)||e&&Q(e.buffer,ArrayBuffer))return d(e,t,r);if(\"undefined\"!=typeof SharedArrayBuffer&&(Q(e,SharedArrayBuffer)||e&&Q(e.buffer,SharedArrayBuffer)))return d(e,t,r);if(\"number\"==typeof e)throw new TypeError('The \"value\" argument must not be of type number. Received type number');const n=e.valueOf&&e.valueOf();if(null!=n&&n!==e)return f.from(n,t,r);const i=function(e){if(f.isBuffer(e)){const t=0|p(e.length),r=a(t);return 0===r.length||e.copy(r,0,0,t),r}return void 0!==e.length?\"number\"!=typeof e.length||Y(e.length)?a(0):c(e):\"Buffer\"===e.type&&Array.isArray(e.data)?c(e.data):void 0}(e);if(i)return i;if(\"undefined\"!=typeof Symbol&&null!=Symbol.toPrimitive&&\"function\"==typeof e[Symbol.toPrimitive])return f.from(e[Symbol.toPrimitive](\"string\"),t,r);throw new TypeError(\"The first argument must be one of type string, Buffer, ArrayBuffer, Array, or Array-like Object. Received type \"+typeof e)}function l(e){if(\"number\"!=typeof e)throw new TypeError('\"size\" argument must be of type number');if(e<0)throw new RangeError('The value \"'+e+'\" is invalid for option \"size\"')}function u(e){return l(e),a(e<0?0:0|p(e))}function c(e){const t=e.length<0?0:0|p(e.length),r=a(t);for(let n=0;n=s)throw new RangeError(\"Attempt to allocate Buffer larger than maximum size: 0x\"+s.toString(16)+\" bytes\");return 0|e}function g(e,t){if(f.isBuffer(e))return e.length;if(ArrayBuffer.isView(e)||Q(e,ArrayBuffer))return e.byteLength;if(\"string\"!=typeof e)throw new TypeError('The \"string\" argument must be one of type string, Buffer, or ArrayBuffer. Received type '+typeof e);const r=e.length,n=arguments.length>2&&!0===arguments[2];if(!n&&0===r)return 0;let i=!1;for(;;)switch(t){case\"ascii\":case\"latin1\":case\"binary\":return r;case\"utf8\":case\"utf-8\":return V(e).length;case\"ucs2\":case\"ucs-2\":case\"utf16le\":case\"utf-16le\":return 2*r;case\"hex\":return r>>>1;case\"base64\":return Z(e).length;default:if(i)return n?-1:V(e).length;t=(\"\"+t).toLowerCase(),i=!0;}}function m(e,t,r){let n=!1;if((void 0===t||t<0)&&(t=0),t>this.length)return \"\";if((void 0===r||r>this.length)&&(r=this.length),r<=0)return \"\";if((r>>>=0)<=(t>>>=0))return \"\";for(e||(e=\"utf8\");;)switch(e){case\"hex\":return I(this,t,r);case\"utf8\":case\"utf-8\":return C(this,t,r);case\"ascii\":return k(this,t,r);case\"latin1\":case\"binary\":return x(this,t,r);case\"base64\":return A(this,t,r);case\"ucs2\":case\"ucs-2\":case\"utf16le\":case\"utf-16le\":return M(this,t,r);default:if(n)throw new TypeError(\"Unknown encoding: \"+e);e=(e+\"\").toLowerCase(),n=!0;}}function y(e,t,r){const n=e[t];e[t]=e[r],e[r]=n;}function b(e,t,r,n,i){if(0===e.length)return -1;if(\"string\"==typeof r?(n=r,r=0):r>2147483647?r=2147483647:r<-2147483648&&(r=-2147483648),Y(r=+r)&&(r=i?0:e.length-1),r<0&&(r=e.length+r),r>=e.length){if(i)return -1;r=e.length-1;}else if(r<0){if(!i)return -1;r=0;}if(\"string\"==typeof t&&(t=f.from(t,n)),f.isBuffer(t))return 0===t.length?-1:v(e,t,r,n,i);if(\"number\"==typeof t)return t&=255,\"function\"==typeof Uint8Array.prototype.indexOf?i?Uint8Array.prototype.indexOf.call(e,t,r):Uint8Array.prototype.lastIndexOf.call(e,t,r):v(e,[t],r,n,i);throw new TypeError(\"val must be string, number or Buffer\")}function v(e,t,r,n,i){let o,s=1,a=e.length,f=t.length;if(void 0!==n&&(\"ucs2\"===(n=String(n).toLowerCase())||\"ucs-2\"===n||\"utf16le\"===n||\"utf-16le\"===n)){if(e.length<2||t.length<2)return -1;s=2,a/=2,f/=2,r/=2;}function h(e,t){return 1===s?e[t]:e.readUInt16BE(t*s)}if(i){let n=-1;for(o=r;oa&&(r=a-f),o=r;o>=0;o--){let r=!0;for(let n=0;ni&&(n=i):n=i;const o=t.length;let s;for(n>o/2&&(n=o/2),s=0;s>8,i=r%256,o.push(i),o.push(n);return o}(t,e.length-r),e,r,n)}function A(e,t,r){return 0===t&&r===e.length?n.fromByteArray(e):n.fromByteArray(e.slice(t,r))}function C(e,t,r){r=Math.min(e.length,r);const n=[];let i=t;for(;i239?4:t>223?3:t>191?2:1;if(i+s<=r){let r,n,a,f;switch(s){case 1:t<128&&(o=t);break;case 2:r=e[i+1],128==(192&r)&&(f=(31&t)<<6|63&r,f>127&&(o=f));break;case 3:r=e[i+1],n=e[i+2],128==(192&r)&&128==(192&n)&&(f=(15&t)<<12|(63&r)<<6|63&n,f>2047&&(f<55296||f>57343)&&(o=f));break;case 4:r=e[i+1],n=e[i+2],a=e[i+3],128==(192&r)&&128==(192&n)&&128==(192&a)&&(f=(15&t)<<18|(63&r)<<12|(63&n)<<6|63&a,f>65535&&f<1114112&&(o=f));}}null===o?(o=65533,s=1):o>65535&&(o-=65536,n.push(o>>>10&1023|55296),o=56320|1023&o),n.push(o),i+=s;}return function(e){const t=e.length;if(t<=R)return String.fromCharCode.apply(String,e);let r=\"\",n=0;for(;nn.length?(f.isBuffer(t)||(t=f.from(t)),t.copy(n,i)):Uint8Array.prototype.set.call(n,t,i);else {if(!f.isBuffer(t))throw new TypeError('\"list\" argument must be an Array of Buffers');t.copy(n,i);}i+=t.length;}return n},f.byteLength=g,f.prototype._isBuffer=!0,f.prototype.swap16=function(){const e=this.length;if(e%2!=0)throw new RangeError(\"Buffer size must be a multiple of 16-bits\");for(let t=0;tr&&(e+=\" ... \"),\"\"},o&&(f.prototype[o]=f.prototype.inspect),f.prototype.compare=function(e,t,r,n,i){if(Q(e,Uint8Array)&&(e=f.from(e,e.offset,e.byteLength)),!f.isBuffer(e))throw new TypeError('The \"target\" argument must be one of type Buffer or Uint8Array. Received type '+typeof e);if(void 0===t&&(t=0),void 0===r&&(r=e?e.length:0),void 0===n&&(n=0),void 0===i&&(i=this.length),t<0||r>e.length||n<0||i>this.length)throw new RangeError(\"out of range index\");if(n>=i&&t>=r)return 0;if(n>=i)return -1;if(t>=r)return 1;if(this===e)return 0;let o=(i>>>=0)-(n>>>=0),s=(r>>>=0)-(t>>>=0);const a=Math.min(o,s),h=this.slice(n,i),l=e.slice(t,r);for(let e=0;e>>=0,isFinite(r)?(r>>>=0,void 0===n&&(n=\"utf8\")):(n=r,r=void 0);}const i=this.length-t;if((void 0===r||r>i)&&(r=i),e.length>0&&(r<0||t<0)||t>this.length)throw new RangeError(\"Attempt to write outside buffer bounds\");n||(n=\"utf8\");let o=!1;for(;;)switch(n){case\"hex\":return w(this,e,t,r);case\"utf8\":case\"utf-8\":return _(this,e,t,r);case\"ascii\":case\"latin1\":case\"binary\":return B(this,e,t,r);case\"base64\":return E(this,e,t,r);case\"ucs2\":case\"ucs-2\":case\"utf16le\":case\"utf-16le\":return S(this,e,t,r);default:if(o)throw new TypeError(\"Unknown encoding: \"+n);n=(\"\"+n).toLowerCase(),o=!0;}},f.prototype.toJSON=function(){return {type:\"Buffer\",data:Array.prototype.slice.call(this._arr||this,0)}};const R=4096;function k(e,t,r){let n=\"\";r=Math.min(e.length,r);for(let i=t;in)&&(r=n);let i=\"\";for(let n=t;nr)throw new RangeError(\"Trying to access beyond buffer length\")}function O(e,t,r,n,i,o){if(!f.isBuffer(e))throw new TypeError('\"buffer\" argument must be a Buffer instance');if(t>i||te.length)throw new RangeError(\"Index out of range\")}function T(e,t,r,n,i){j(t,n,i,e,r,7);let o=Number(t&BigInt(4294967295));e[r++]=o,o>>=8,e[r++]=o,o>>=8,e[r++]=o,o>>=8,e[r++]=o;let s=Number(t>>BigInt(32)&BigInt(4294967295));return e[r++]=s,s>>=8,e[r++]=s,s>>=8,e[r++]=s,s>>=8,e[r++]=s,r}function U(e,t,r,n,i){j(t,n,i,e,r,7);let o=Number(t&BigInt(4294967295));e[r+7]=o,o>>=8,e[r+6]=o,o>>=8,e[r+5]=o,o>>=8,e[r+4]=o;let s=Number(t>>BigInt(32)&BigInt(4294967295));return e[r+3]=s,s>>=8,e[r+2]=s,s>>=8,e[r+1]=s,s>>=8,e[r]=s,r+8}function P(e,t,r,n,i,o){if(r+n>e.length)throw new RangeError(\"Index out of range\");if(r<0)throw new RangeError(\"Index out of range\")}function N(e,t,r,n,o){return t=+t,r>>>=0,o||P(e,0,r,4),i.write(e,t,r,n,23,4),r+4}function L(e,t,r,n,o){return t=+t,r>>>=0,o||P(e,0,r,8),i.write(e,t,r,n,52,8),r+8}f.prototype.slice=function(e,t){const r=this.length;(e=~~e)<0?(e+=r)<0&&(e=0):e>r&&(e=r),(t=void 0===t?r:~~t)<0?(t+=r)<0&&(t=0):t>r&&(t=r),t>>=0,t>>>=0,r||F(e,t,this.length);let n=this[e],i=1,o=0;for(;++o>>=0,t>>>=0,r||F(e,t,this.length);let n=this[e+--t],i=1;for(;t>0&&(i*=256);)n+=this[e+--t]*i;return n},f.prototype.readUint8=f.prototype.readUInt8=function(e,t){return e>>>=0,t||F(e,1,this.length),this[e]},f.prototype.readUint16LE=f.prototype.readUInt16LE=function(e,t){return e>>>=0,t||F(e,2,this.length),this[e]|this[e+1]<<8},f.prototype.readUint16BE=f.prototype.readUInt16BE=function(e,t){return e>>>=0,t||F(e,2,this.length),this[e]<<8|this[e+1]},f.prototype.readUint32LE=f.prototype.readUInt32LE=function(e,t){return e>>>=0,t||F(e,4,this.length),(this[e]|this[e+1]<<8|this[e+2]<<16)+16777216*this[e+3]},f.prototype.readUint32BE=f.prototype.readUInt32BE=function(e,t){return e>>>=0,t||F(e,4,this.length),16777216*this[e]+(this[e+1]<<16|this[e+2]<<8|this[e+3])},f.prototype.readBigUInt64LE=X((function(e){H(e>>>=0,\"offset\");const t=this[e],r=this[e+7];void 0!==t&&void 0!==r||W(e,this.length-8);const n=t+256*this[++e]+65536*this[++e]+this[++e]*2**24,i=this[++e]+256*this[++e]+65536*this[++e]+r*2**24;return BigInt(n)+(BigInt(i)<>>=0,\"offset\");const t=this[e],r=this[e+7];void 0!==t&&void 0!==r||W(e,this.length-8);const n=t*2**24+65536*this[++e]+256*this[++e]+this[++e],i=this[++e]*2**24+65536*this[++e]+256*this[++e]+r;return (BigInt(n)<>>=0,t>>>=0,r||F(e,t,this.length);let n=this[e],i=1,o=0;for(;++o=i&&(n-=Math.pow(2,8*t)),n},f.prototype.readIntBE=function(e,t,r){e>>>=0,t>>>=0,r||F(e,t,this.length);let n=t,i=1,o=this[e+--n];for(;n>0&&(i*=256);)o+=this[e+--n]*i;return i*=128,o>=i&&(o-=Math.pow(2,8*t)),o},f.prototype.readInt8=function(e,t){return e>>>=0,t||F(e,1,this.length),128&this[e]?-1*(255-this[e]+1):this[e]},f.prototype.readInt16LE=function(e,t){e>>>=0,t||F(e,2,this.length);const r=this[e]|this[e+1]<<8;return 32768&r?4294901760|r:r},f.prototype.readInt16BE=function(e,t){e>>>=0,t||F(e,2,this.length);const r=this[e+1]|this[e]<<8;return 32768&r?4294901760|r:r},f.prototype.readInt32LE=function(e,t){return e>>>=0,t||F(e,4,this.length),this[e]|this[e+1]<<8|this[e+2]<<16|this[e+3]<<24},f.prototype.readInt32BE=function(e,t){return e>>>=0,t||F(e,4,this.length),this[e]<<24|this[e+1]<<16|this[e+2]<<8|this[e+3]},f.prototype.readBigInt64LE=X((function(e){H(e>>>=0,\"offset\");const t=this[e],r=this[e+7];void 0!==t&&void 0!==r||W(e,this.length-8);const n=this[e+4]+256*this[e+5]+65536*this[e+6]+(r<<24);return (BigInt(n)<>>=0,\"offset\");const t=this[e],r=this[e+7];void 0!==t&&void 0!==r||W(e,this.length-8);const n=(t<<24)+65536*this[++e]+256*this[++e]+this[++e];return (BigInt(n)<>>=0,t||F(e,4,this.length),i.read(this,e,!0,23,4)},f.prototype.readFloatBE=function(e,t){return e>>>=0,t||F(e,4,this.length),i.read(this,e,!1,23,4)},f.prototype.readDoubleLE=function(e,t){return e>>>=0,t||F(e,8,this.length),i.read(this,e,!0,52,8)},f.prototype.readDoubleBE=function(e,t){return e>>>=0,t||F(e,8,this.length),i.read(this,e,!1,52,8)},f.prototype.writeUintLE=f.prototype.writeUIntLE=function(e,t,r,n){e=+e,t>>>=0,r>>>=0,n||O(this,e,t,r,Math.pow(2,8*r)-1,0);let i=1,o=0;for(this[t]=255&e;++o>>=0,r>>>=0,n||O(this,e,t,r,Math.pow(2,8*r)-1,0);let i=r-1,o=1;for(this[t+i]=255&e;--i>=0&&(o*=256);)this[t+i]=e/o&255;return t+r},f.prototype.writeUint8=f.prototype.writeUInt8=function(e,t,r){return e=+e,t>>>=0,r||O(this,e,t,1,255,0),this[t]=255&e,t+1},f.prototype.writeUint16LE=f.prototype.writeUInt16LE=function(e,t,r){return e=+e,t>>>=0,r||O(this,e,t,2,65535,0),this[t]=255&e,this[t+1]=e>>>8,t+2},f.prototype.writeUint16BE=f.prototype.writeUInt16BE=function(e,t,r){return e=+e,t>>>=0,r||O(this,e,t,2,65535,0),this[t]=e>>>8,this[t+1]=255&e,t+2},f.prototype.writeUint32LE=f.prototype.writeUInt32LE=function(e,t,r){return e=+e,t>>>=0,r||O(this,e,t,4,4294967295,0),this[t+3]=e>>>24,this[t+2]=e>>>16,this[t+1]=e>>>8,this[t]=255&e,t+4},f.prototype.writeUint32BE=f.prototype.writeUInt32BE=function(e,t,r){return e=+e,t>>>=0,r||O(this,e,t,4,4294967295,0),this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e,t+4},f.prototype.writeBigUInt64LE=X((function(e,t=0){return T(this,e,t,BigInt(0),BigInt(\"0xffffffffffffffff\"))})),f.prototype.writeBigUInt64BE=X((function(e,t=0){return U(this,e,t,BigInt(0),BigInt(\"0xffffffffffffffff\"))})),f.prototype.writeIntLE=function(e,t,r,n){if(e=+e,t>>>=0,!n){const n=Math.pow(2,8*r-1);O(this,e,t,r,n-1,-n);}let i=0,o=1,s=0;for(this[t]=255&e;++i>0)-s&255;return t+r},f.prototype.writeIntBE=function(e,t,r,n){if(e=+e,t>>>=0,!n){const n=Math.pow(2,8*r-1);O(this,e,t,r,n-1,-n);}let i=r-1,o=1,s=0;for(this[t+i]=255&e;--i>=0&&(o*=256);)e<0&&0===s&&0!==this[t+i+1]&&(s=1),this[t+i]=(e/o>>0)-s&255;return t+r},f.prototype.writeInt8=function(e,t,r){return e=+e,t>>>=0,r||O(this,e,t,1,127,-128),e<0&&(e=255+e+1),this[t]=255&e,t+1},f.prototype.writeInt16LE=function(e,t,r){return e=+e,t>>>=0,r||O(this,e,t,2,32767,-32768),this[t]=255&e,this[t+1]=e>>>8,t+2},f.prototype.writeInt16BE=function(e,t,r){return e=+e,t>>>=0,r||O(this,e,t,2,32767,-32768),this[t]=e>>>8,this[t+1]=255&e,t+2},f.prototype.writeInt32LE=function(e,t,r){return e=+e,t>>>=0,r||O(this,e,t,4,2147483647,-2147483648),this[t]=255&e,this[t+1]=e>>>8,this[t+2]=e>>>16,this[t+3]=e>>>24,t+4},f.prototype.writeInt32BE=function(e,t,r){return e=+e,t>>>=0,r||O(this,e,t,4,2147483647,-2147483648),e<0&&(e=4294967295+e+1),this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e,t+4},f.prototype.writeBigInt64LE=X((function(e,t=0){return T(this,e,t,-BigInt(\"0x8000000000000000\"),BigInt(\"0x7fffffffffffffff\"))})),f.prototype.writeBigInt64BE=X((function(e,t=0){return U(this,e,t,-BigInt(\"0x8000000000000000\"),BigInt(\"0x7fffffffffffffff\"))})),f.prototype.writeFloatLE=function(e,t,r){return N(this,e,t,!0,r)},f.prototype.writeFloatBE=function(e,t,r){return N(this,e,t,!1,r)},f.prototype.writeDoubleLE=function(e,t,r){return L(this,e,t,!0,r)},f.prototype.writeDoubleBE=function(e,t,r){return L(this,e,t,!1,r)},f.prototype.copy=function(e,t,r,n){if(!f.isBuffer(e))throw new TypeError(\"argument should be a Buffer\");if(r||(r=0),n||0===n||(n=this.length),t>=e.length&&(t=e.length),t||(t=0),n>0&&n=this.length)throw new RangeError(\"Index out of range\");if(n<0)throw new RangeError(\"sourceEnd out of bounds\");n>this.length&&(n=this.length),e.length-t>>=0,r=void 0===r?this.length:r>>>0,e||(e=0),\"number\"==typeof e)for(i=t;i=n+4;r-=3)t=`_${e.slice(r-3,r)}${t}`;return `${e.slice(0,r)}${t}`}function j(e,t,r,n,i,o){if(e>r||e3?0===t||t===BigInt(0)?`>= 0${n} and < 2${n} ** ${8*(o+1)}${n}`:`>= -(2${n} ** ${8*(o+1)-1}${n}) and < 2 ** ${8*(o+1)-1}${n}`:`>= ${t}${n} and <= ${r}${n}`,new z.ERR_OUT_OF_RANGE(\"value\",i,e)}!function(e,t,r){H(t,\"offset\"),void 0!==e[t]&&void 0!==e[t+r]||W(t,e.length-(r+1));}(n,i,o);}function H(e,t){if(\"number\"!=typeof e)throw new z.ERR_INVALID_ARG_TYPE(t,\"number\",e)}function W(e,t,r){if(Math.floor(e)!==e)throw H(e,r),new z.ERR_OUT_OF_RANGE(r||\"offset\",\"an integer\",e);if(t<0)throw new z.ERR_BUFFER_OUT_OF_BOUNDS;throw new z.ERR_OUT_OF_RANGE(r||\"offset\",`>= ${r?1:0} and <= ${t}`,e)}D(\"ERR_BUFFER_OUT_OF_BOUNDS\",(function(e){return e?`${e} is outside of buffer bounds`:\"Attempt to access memory outside buffer bounds\"}),RangeError),D(\"ERR_INVALID_ARG_TYPE\",(function(e,t){return `The \"${e}\" argument must be of type number. Received type ${typeof t}`}),TypeError),D(\"ERR_OUT_OF_RANGE\",(function(e,t,r){let n=`The value of \"${e}\" is out of range.`,i=r;return Number.isInteger(r)&&Math.abs(r)>2**32?i=q(String(r)):\"bigint\"==typeof r&&(i=String(r),(r>BigInt(2)**BigInt(32)||r<-(BigInt(2)**BigInt(32)))&&(i=q(i)),i+=\"n\"),n+=` It must be ${t}. Received ${i}`,n}),RangeError);const $=/[^+/0-9A-Za-z-_]/g;function V(e,t){let r;t=t||1/0;const n=e.length;let i=null;const o=[];for(let s=0;s55295&&r<57344){if(!i){if(r>56319){(t-=3)>-1&&o.push(239,191,189);continue}if(s+1===n){(t-=3)>-1&&o.push(239,191,189);continue}i=r;continue}if(r<56320){(t-=3)>-1&&o.push(239,191,189),i=r;continue}r=65536+(i-55296<<10|r-56320);}else i&&(t-=3)>-1&&o.push(239,191,189);if(i=null,r<128){if((t-=1)<0)break;o.push(r);}else if(r<2048){if((t-=2)<0)break;o.push(r>>6|192,63&r|128);}else if(r<65536){if((t-=3)<0)break;o.push(r>>12|224,r>>6&63|128,63&r|128);}else {if(!(r<1114112))throw new Error(\"Invalid code point\");if((t-=4)<0)break;o.push(r>>18|240,r>>12&63|128,r>>6&63|128,63&r|128);}}return o}function Z(e){return n.toByteArray(function(e){if((e=(e=e.split(\"=\")[0]).trim().replace($,\"\")).length<2)return \"\";for(;e.length%4!=0;)e+=\"=\";return e}(e))}function G(e,t,r,n){let i;for(i=0;i=t.length||i>=e.length);++i)t[i+r]=e[i];return i}function Q(e,t){return e instanceof t||null!=e&&null!=e.constructor&&null!=e.constructor.name&&e.constructor.name===t.name}function Y(e){return e!=e}const K=function(){const e=\"0123456789abcdef\",t=new Array(256);for(let r=0;r<16;++r){const n=16*r;for(let i=0;i<16;++i)t[n+i]=e[r]+e[i];}return t}();function X(e){return \"undefined\"==typeof BigInt?J:e}function J(){throw new Error(\"BigInt not supported\")}},4693:e=>{var t={array:function(e){var t=0,r=0,n=[0,1,3,7,15,31,63,127,255];return function(i){for(var o=0;i>0;){var s=8-t;i>=s?(o<<=s,o|=n[s]&e[r++],t=0,i-=s):(o<<=i,o|=(e[r]&n[i]<<8-i-t)>>8-i-t,t+=i,i=0);}return o}},simple:function(e){var r,n,i=t.header(e),o=[],s=0;do{-1!=(n=t.decompress(e,i))&&(o.push(n),s+=n.byteLength);}while(-1!=n);r=new Uint8Array(s),s=0;for(var a=0;a9)throw \"Not a BZIP archive\";return t},decompress:function(e,t,r){for(var n=9e5,i=\"\",o=0;o<6;o++)i+=e(8).toString(16);if(\"177245385090\"==i)return -1;if(\"314159265359\"!=i)throw \"eek not valid bzip data\";if(e(32),e(1))throw \"unsupported obsolete version\";var s=e(24);if(s>n)throw \"Initial position larger than buffer size\";var a=e(16),f=new Uint8Array(256),h=0;for(o=0;o<16;o++)if(a&1<<15-o){var l=e(16);for(g=0;g<16;g++)l&1<<15-g&&(f[h++]=16*o+g);}var u=e(3);if(u<2||u>6)throw \"another error\";var c=e(15);if(0==c)throw \"meh\";var d=[];for(o=0;o=u)throw \"whoops another error\";var m=d[g];d.splice(g,1),d.splice(0,0,m),p[o]=m;}var y=h+2,b=[];for(g=0;g20)throw \"I gave up a while ago on writing error messages\";if(!e(1))break;e(1)?a--:a++;}B[o]=a;}for(v=w=B[0],o=1;ow?w=B[o]:B[o]=c)throw \"meow i'm a kitty, that's an error\";S=(_=b[p[x++]]).base.subarray(1),A=_.limit.subarray(1);}for(g=e(o=_.minLen);;){if(o>_.maxLen)throw \"rawr i'm a dinosaur\";if(g<=A[o])break;o++,g=g<<1|e(1);}if((g-=S[o])<0||g>=258)throw \"moo i'm a cow\";var F=_.permute[g];if(0!=F&&1!=F){if(R){if(R=0,k+a>=n)throw \"Boom.\";for(I[m=f[d[0]]]+=a;a--;)M[k++]=m;}if(F>h)break;if(k>=n)throw \"I can't think of anything. Error\";m=d[o=F-1],d.splice(o,1),d.splice(0,0,m),I[m=f[m]]++,M[k++]=m;}else R||(R=1,a=0),a+=0==F?R:2*R,R<<=1;}if(s<0||s>=k)throw \"I'm a monkey and I'm throwing something at someone, namely you\";for(g=0,o=0;o<256;o++)l=g+I[o],I[o]=g,g=l;for(o=0;o>=8,U=-1);var P,N,L,z=new Uint8Array(n),D=0;for(r||(r=1/0);k;){for(k--,N=T,T=255&(O=M[O]),O>>=8,3==U++?(P=T,L=N,T=-1):(P=1,L=T);P--;)if(z[D++]=L,!--r)return z;T!=N&&(U=0);}return z.subarray(0,D)}};e.exports=t;},487:e=>{var t={utf8:{stringToBytes:function(e){return t.bin.stringToBytes(unescape(encodeURIComponent(e)))},bytesToString:function(e){return decodeURIComponent(escape(t.bin.bytesToString(e)))}},bin:{stringToBytes:function(e){for(var t=[],r=0;r{var t,r;t=\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\",r={rotl:function(e,t){return e<>>32-t},rotr:function(e,t){return e<<32-t|e>>>t},endian:function(e){if(e.constructor==Number)return 16711935&r.rotl(e,8)|4278255360&r.rotl(e,24);for(var t=0;t0;e--)t.push(Math.floor(256*Math.random()));return t},bytesToWords:function(e){for(var t=[],r=0,n=0;r>>5]|=e[r]<<24-n%32;return t},wordsToBytes:function(e){for(var t=[],r=0;r<32*e.length;r+=8)t.push(e[r>>>5]>>>24-r%32&255);return t},bytesToHex:function(e){for(var t=[],r=0;r>>4).toString(16)),t.push((15&e[r]).toString(16));return t.join(\"\")},hexToBytes:function(e){for(var t=[],r=0;r>>6*(3-o)&63)):r.push(\"=\");return r.join(\"\")},base64ToBytes:function(e){e=e.replace(/[^A-Z0-9+\\/]/gi,\"\");for(var r=[],n=0,i=0;n>>6-2*i);return r}},e.exports=r;},2949:(e,t,r)=>{r.r(t),r.d(t,{BlobFile:()=>h,LocalFile:()=>i(),RemoteFile:()=>a,fromUrl:()=>l,open:()=>u});var n=r(7067),i=r.n(n),o=r(8764);const s=\"undefined\"!=typeof window?window:\"undefined\"!=typeof self?self:{fetch:void 0};class a{constructor(e,t={}){this.baseOverrides={},this.url=e;const r=t.fetch||s.fetch&&s.fetch.bind(s);if(!r)throw new TypeError(\"no fetch function supplied, and none found in global environment\");t.overrides&&(this.baseOverrides=t.overrides),this.fetchImplementation=r;}async getBufferFromResponse(e){if(\"function\"==typeof e.buffer)return e.buffer();if(\"function\"==typeof e.arrayBuffer){const t=await e.arrayBuffer();return o.Buffer.from(t)}throw new TypeError(\"invalid HTTP response object, has no buffer method, and no arrayBuffer method\")}async fetch(e,t){let r;try{r=await this.fetchImplementation(e,t);}catch(n){if(!`${n}`.includes(\"Failed to fetch\"))throw n;console.warn(`generic-filehandle: refetching ${e} to attempt to work around chrome CORS header caching bug`),r=await this.fetchImplementation(e,{...t,cache:\"reload\"});}return r}async read(e,t=0,r,n=0,i={}){const{headers:o={},signal:s,overrides:a={}}=i;r<1/0?o.range=`bytes=${n}-${n+r}`:r===1/0&&0!==n&&(o.range=`bytes=${n}-`);const f={...this.baseOverrides,...a,headers:{...o,...a.headers,...this.baseOverrides.headers},method:\"GET\",redirect:\"follow\",mode:\"cors\",signal:s},h=await this.fetch(this.url,f);if(!h.ok)throw new Error(`HTTP ${h.status} ${h.statusText} ${this.url}`);if(200===h.status&&0===n||206===h.status){const n=await this.getBufferFromResponse(h),i=n.copy(e,t,0,Math.min(r,n.length)),o=h.headers.get(\"content-range\"),s=/\\/(\\d+)$/.exec(o||\"\");return s&&s[1]&&(this._stat={size:parseInt(s[1],10)}),{bytesRead:i,buffer:e}}if(200===h.status)throw new Error(\"${this.url} fetch returned status 200, expected 206\");throw new Error(`HTTP ${h.status} fetching ${this.url}`)}async readFile(e={}){let t,r;\"string\"==typeof e?(t=e,r={}):(t=e.encoding,r=e,delete r.encoding);const{headers:n={},signal:i,overrides:o={}}=r,s={headers:n,method:\"GET\",redirect:\"follow\",mode:\"cors\",signal:i,...this.baseOverrides,...o},a=await this.fetch(this.url,s);if(!a)throw new Error(\"generic-filehandle failed to fetch\");if(200!==a.status)throw Object.assign(new Error(`HTTP ${a.status} fetching ${this.url}`),{status:a.status});if(\"utf8\"===t)return a.text();if(t)throw new Error(`unsupported encoding: ${t}`);return this.getBufferFromResponse(a)}async stat(){if(!this._stat){const e=o.Buffer.allocUnsafe(10);if(await this.read(e,0,10,0),!this._stat)throw new Error(`unable to determine size of file at ${this.url}`)}return this._stat}async close(){}}function f(e){const t=new FileReader;return new Promise(((r,n)=>{t.onerror=()=>{t.abort(),n(new Error(\"problem reading blob\"));},t.onabort=()=>{n(new Error(\"blob reading was aborted\"));},t.onload=()=>{t.result&&\"string\"!=typeof t.result?r(t.result):n(new Error(\"unknown error reading blob\"));},t.readAsArrayBuffer(e);}))}class h{constructor(e){this.blob=e,this.size=e.size;}async read(e,t=0,r,n=0){if(!r)return {bytesRead:0,buffer:e};const i=n,s=i+r,a=await f(this.blob.slice(i,s)),h=o.Buffer.from(a);return {bytesRead:h.copy(e,t),buffer:h}}async readFile(e){let t;if(t=\"string\"==typeof e?e:e&&e.encoding,\"utf8\"===t)return function(e){const t=new FileReader;return new Promise(((r,n)=>{t.onerror=()=>{t.abort(),n(new Error(\"problem reading blob\"));},t.onabort=()=>{n(new Error(\"blob reading was aborted\"));},t.onload=()=>{t.result&&\"string\"==typeof t.result?r(t.result):n(new Error(\"unknown error reading blob\"));},t.readAsText(e);}))}(this.blob);if(t)throw new Error(`unsupported encoding: ${t}`);const r=await f(this.blob);return o.Buffer.from(r)}async stat(){return {size:this.size}}async close(){}}function l(e,t={}){return new a(e,t)}function u(e,t,r,n={}){if(void 0!==r)return r;if(void 0!==e)return l(e,n);if(void 0!==t)return new(i())(t,n);throw new Error(\"no url, path, or filehandle provided, cannot open\")}},645:(e,t)=>{t.read=function(e,t,r,n,i){var o,s,a=8*i-n-1,f=(1<>1,l=-7,u=r?i-1:0,c=r?-1:1,d=e[t+u];for(u+=c,o=d&(1<<-l)-1,d>>=-l,l+=a;l>0;o=256*o+e[t+u],u+=c,l-=8);for(s=o&(1<<-l)-1,o>>=-l,l+=n;l>0;s=256*s+e[t+u],u+=c,l-=8);if(0===o)o=1-h;else {if(o===f)return s?NaN:1/0*(d?-1:1);s+=Math.pow(2,n),o-=h;}return (d?-1:1)*s*Math.pow(2,o-n)},t.write=function(e,t,r,n,i,o){var s,a,f,h=8*o-i-1,l=(1<>1,c=23===i?Math.pow(2,-24)-Math.pow(2,-77):0,d=n?0:o-1,p=n?1:-1,g=t<0||0===t&&1/t<0?1:0;for(t=Math.abs(t),isNaN(t)||t===1/0?(a=isNaN(t)?1:0,s=l):(s=Math.floor(Math.log(t)/Math.LN2),t*(f=Math.pow(2,-s))<1&&(s--,f*=2),(t+=s+u>=1?c/f:c*Math.pow(2,1-u))*f>=2&&(s++,f/=2),s+u>=l?(a=0,s=l):s+u>=1?(a=(t*f-1)*Math.pow(2,i),s+=u):(a=t*Math.pow(2,u-1)*Math.pow(2,i),s=0));i>=8;e[r+d]=255&a,d+=p,a/=256,i-=8);for(s=s<0;e[r+d]=255&s,d+=p,s/=256,h-=8);e[r+d-p]|=128*g;};},8738:e=>{function t(e){return !!e.constructor&&\"function\"==typeof e.constructor.isBuffer&&e.constructor.isBuffer(e)}e.exports=function(e){return null!=e&&(t(e)||function(e){return \"function\"==typeof e.readFloatLE&&\"function\"==typeof e.slice&&t(e.slice(0,0))}(e)||!!e._isBuffer)};},3720:e=>{e.exports=r;var t=null;try{t=new WebAssembly.Instance(new WebAssembly.Module(new Uint8Array([0,97,115,109,1,0,0,0,1,13,2,96,0,1,127,96,4,127,127,127,127,1,127,3,7,6,0,1,1,1,1,1,6,6,1,127,1,65,0,11,7,50,6,3,109,117,108,0,1,5,100,105,118,95,115,0,2,5,100,105,118,95,117,0,3,5,114,101,109,95,115,0,4,5,114,101,109,95,117,0,5,8,103,101,116,95,104,105,103,104,0,0,10,191,1,6,4,0,35,0,11,36,1,1,126,32,0,173,32,1,173,66,32,134,132,32,2,173,32,3,173,66,32,134,132,126,34,4,66,32,135,167,36,0,32,4,167,11,36,1,1,126,32,0,173,32,1,173,66,32,134,132,32,2,173,32,3,173,66,32,134,132,127,34,4,66,32,135,167,36,0,32,4,167,11,36,1,1,126,32,0,173,32,1,173,66,32,134,132,32,2,173,32,3,173,66,32,134,132,128,34,4,66,32,135,167,36,0,32,4,167,11,36,1,1,126,32,0,173,32,1,173,66,32,134,132,32,2,173,32,3,173,66,32,134,132,129,34,4,66,32,135,167,36,0,32,4,167,11,36,1,1,126,32,0,173,32,1,173,66,32,134,132,32,2,173,32,3,173,66,32,134,132,130,34,4,66,32,135,167,36,0,32,4,167,11])),{}).exports;}catch(e){}function r(e,t,r){this.low=0|e,this.high=0|t,this.unsigned=!!r;}function n(e){return !0===(e&&e.__isLong__)}r.prototype.__isLong__,Object.defineProperty(r.prototype,\"__isLong__\",{value:!0}),r.isLong=n;var i={},o={};function s(e,t){var r,n,s;return t?(s=0<=(e>>>=0)&&e<256)&&(n=o[e])?n:(r=f(e,(0|e)<0?-1:0,!0),s&&(o[e]=r),r):(s=-128<=(e|=0)&&e<128)&&(n=i[e])?n:(r=f(e,e<0?-1:0,!1),s&&(i[e]=r),r)}function a(e,t){if(isNaN(e))return t?y:m;if(t){if(e<0)return y;if(e>=d)return B}else {if(e<=-p)return E;if(e+1>=p)return _}return e<0?a(-e,t).neg():f(e%c|0,e/c|0,t)}function f(e,t,n){return new r(e,t,n)}r.fromInt=s,r.fromNumber=a,r.fromBits=f;var h=Math.pow;function l(e,t,r){if(0===e.length)throw Error(\"empty string\");if(\"NaN\"===e||\"Infinity\"===e||\"+Infinity\"===e||\"-Infinity\"===e)return m;if(\"number\"==typeof t?(r=t,t=!1):t=!!t,(r=r||10)<2||360)throw Error(\"interior hyphen\");if(0===n)return l(e.substring(1),t,r).neg();for(var i=a(h(r,8)),o=m,s=0;s>>0:this.low},S.toNumber=function(){return this.unsigned?(this.high>>>0)*c+(this.low>>>0):this.high*c+(this.low>>>0)},S.toString=function(e){if((e=e||10)<2||36>>0).toString(e);if((o=f).isZero())return l+s;for(;l.length<6;)l=\"0\"+l;s=\"\"+l+s;}},S.getHighBits=function(){return this.high},S.getHighBitsUnsigned=function(){return this.high>>>0},S.getLowBits=function(){return this.low},S.getLowBitsUnsigned=function(){return this.low>>>0},S.getNumBitsAbs=function(){if(this.isNegative())return this.eq(E)?64:this.neg().getNumBitsAbs();for(var e=0!=this.high?this.high:this.low,t=31;t>0&&0==(e&1<=0},S.isOdd=function(){return 1==(1&this.low)},S.isEven=function(){return 0==(1&this.low)},S.equals=function(e){return n(e)||(e=u(e)),(this.unsigned===e.unsigned||this.high>>>31!=1||e.high>>>31!=1)&&this.high===e.high&&this.low===e.low},S.eq=S.equals,S.notEquals=function(e){return !this.eq(e)},S.neq=S.notEquals,S.ne=S.notEquals,S.lessThan=function(e){return this.comp(e)<0},S.lt=S.lessThan,S.lessThanOrEqual=function(e){return this.comp(e)<=0},S.lte=S.lessThanOrEqual,S.le=S.lessThanOrEqual,S.greaterThan=function(e){return this.comp(e)>0},S.gt=S.greaterThan,S.greaterThanOrEqual=function(e){return this.comp(e)>=0},S.gte=S.greaterThanOrEqual,S.ge=S.greaterThanOrEqual,S.compare=function(e){if(n(e)||(e=u(e)),this.eq(e))return 0;var t=this.isNegative(),r=e.isNegative();return t&&!r?-1:!t&&r?1:this.unsigned?e.high>>>0>this.high>>>0||e.high===this.high&&e.low>>>0>this.low>>>0?-1:1:this.sub(e).isNegative()?-1:1},S.comp=S.compare,S.negate=function(){return !this.unsigned&&this.eq(E)?E:this.not().add(b)},S.neg=S.negate,S.add=function(e){n(e)||(e=u(e));var t=this.high>>>16,r=65535&this.high,i=this.low>>>16,o=65535&this.low,s=e.high>>>16,a=65535&e.high,h=e.low>>>16,l=0,c=0,d=0,p=0;return d+=(p+=o+(65535&e.low))>>>16,c+=(d+=i+h)>>>16,l+=(c+=r+a)>>>16,l+=t+s,f((d&=65535)<<16|(p&=65535),(l&=65535)<<16|(c&=65535),this.unsigned)},S.subtract=function(e){return n(e)||(e=u(e)),this.add(e.neg())},S.sub=S.subtract,S.multiply=function(e){if(this.isZero())return m;if(n(e)||(e=u(e)),t)return f(t.mul(this.low,this.high,e.low,e.high),t.get_high(),this.unsigned);if(e.isZero())return m;if(this.eq(E))return e.isOdd()?E:m;if(e.eq(E))return this.isOdd()?E:m;if(this.isNegative())return e.isNegative()?this.neg().mul(e.neg()):this.neg().mul(e).neg();if(e.isNegative())return this.mul(e.neg()).neg();if(this.lt(g)&&e.lt(g))return a(this.toNumber()*e.toNumber(),this.unsigned);var r=this.high>>>16,i=65535&this.high,o=this.low>>>16,s=65535&this.low,h=e.high>>>16,l=65535&e.high,c=e.low>>>16,d=65535&e.low,p=0,y=0,b=0,v=0;return b+=(v+=s*d)>>>16,y+=(b+=o*d)>>>16,b&=65535,y+=(b+=s*c)>>>16,p+=(y+=i*d)>>>16,y&=65535,p+=(y+=o*c)>>>16,y&=65535,p+=(y+=s*l)>>>16,p+=r*d+i*c+o*l+s*h,f((b&=65535)<<16|(v&=65535),(p&=65535)<<16|(y&=65535),this.unsigned)},S.mul=S.multiply,S.divide=function(e){if(n(e)||(e=u(e)),e.isZero())throw Error(\"division by zero\");var r,i,o;if(t)return this.unsigned||-2147483648!==this.high||-1!==e.low||-1!==e.high?f((this.unsigned?t.div_u:t.div_s)(this.low,this.high,e.low,e.high),t.get_high(),this.unsigned):this;if(this.isZero())return this.unsigned?y:m;if(this.unsigned){if(e.unsigned||(e=e.toUnsigned()),e.gt(this))return y;if(e.gt(this.shru(1)))return v;o=y;}else {if(this.eq(E))return e.eq(b)||e.eq(w)?E:e.eq(E)?b:(r=this.shr(1).div(e).shl(1)).eq(m)?e.isNegative()?b:w:(i=this.sub(e.mul(r)),o=r.add(i.div(e)));if(e.eq(E))return this.unsigned?y:m;if(this.isNegative())return e.isNegative()?this.neg().div(e.neg()):this.neg().div(e).neg();if(e.isNegative())return this.div(e.neg()).neg();o=m;}for(i=this;i.gte(e);){r=Math.max(1,Math.floor(i.toNumber()/e.toNumber()));for(var s=Math.ceil(Math.log(r)/Math.LN2),l=s<=48?1:h(2,s-48),c=a(r),d=c.mul(e);d.isNegative()||d.gt(i);)d=(c=a(r-=l,this.unsigned)).mul(e);c.isZero()&&(c=b),o=o.add(c),i=i.sub(d);}return o},S.div=S.divide,S.modulo=function(e){return n(e)||(e=u(e)),t?f((this.unsigned?t.rem_u:t.rem_s)(this.low,this.high,e.low,e.high),t.get_high(),this.unsigned):this.sub(this.div(e).mul(e))},S.mod=S.modulo,S.rem=S.modulo,S.not=function(){return f(~this.low,~this.high,this.unsigned)},S.and=function(e){return n(e)||(e=u(e)),f(this.low&e.low,this.high&e.high,this.unsigned)},S.or=function(e){return n(e)||(e=u(e)),f(this.low|e.low,this.high|e.high,this.unsigned)},S.xor=function(e){return n(e)||(e=u(e)),f(this.low^e.low,this.high^e.high,this.unsigned)},S.shiftLeft=function(e){return n(e)&&(e=e.toInt()),0==(e&=63)?this:e<32?f(this.low<>>32-e,this.unsigned):f(0,this.low<>>e|this.high<<32-e,this.high>>e,this.unsigned):f(this.high>>e-32,this.high>=0?0:-1,this.unsigned)},S.shr=S.shiftRight,S.shiftRightUnsigned=function(e){if(n(e)&&(e=e.toInt()),0==(e&=63))return this;var t=this.high;return e<32?f(this.low>>>e|t<<32-e,t>>>e,this.unsigned):f(32===e?t:t>>>e-32,0,this.unsigned)},S.shru=S.shiftRightUnsigned,S.shr_u=S.shiftRightUnsigned,S.toSigned=function(){return this.unsigned?f(this.low,this.high,!1):this},S.toUnsigned=function(){return this.unsigned?this:f(this.low,this.high,!0)},S.toBytes=function(e){return e?this.toBytesLE():this.toBytesBE()},S.toBytesLE=function(){var e=this.high,t=this.low;return [255&t,t>>>8&255,t>>>16&255,t>>>24,255&e,e>>>8&255,e>>>16&255,e>>>24]},S.toBytesBE=function(){var e=this.high,t=this.low;return [e>>>24,e>>>16&255,e>>>8&255,255&e,t>>>24,t>>>16&255,t>>>8&255,255&t]},r.fromBytes=function(e,t,n){return n?r.fromBytesLE(e,t):r.fromBytesBE(e,t)},r.fromBytesLE=function(e,t){return new r(e[0]|e[1]<<8|e[2]<<16|e[3]<<24,e[4]|e[5]<<8|e[6]<<16|e[7]<<24,t)},r.fromBytesBE=function(e,t){return new r(e[4]<<24|e[5]<<16|e[6]<<8|e[7],e[0]<<24|e[1]<<16|e[2]<<8|e[3],t)};},2568:(e,t,r)=>{var n,i,o,s,a;n=r(1012),i=r(487).utf8,o=r(8738),s=r(487).bin,(a=function(e,t){e.constructor==String?e=t&&\"binary\"===t.encoding?s.stringToBytes(e):i.stringToBytes(e):o(e)?e=Array.prototype.slice.call(e,0):Array.isArray(e)||e.constructor===Uint8Array||(e=e.toString());for(var r=n.bytesToWords(e),f=8*e.length,h=1732584193,l=-271733879,u=-1732584194,c=271733878,d=0;d>>24)|4278255360&(r[d]<<24|r[d]>>>8);r[f>>>5]|=128<>>9<<4)]=f;var p=a._ff,g=a._gg,m=a._hh,y=a._ii;for(d=0;d>>0,l=l+v>>>0,u=u+w>>>0,c=c+_>>>0;}return n.endian([h,l,u,c])})._ff=function(e,t,r,n,i,o,s){var a=e+(t&r|~t&n)+(i>>>0)+s;return (a<>>32-o)+t},a._gg=function(e,t,r,n,i,o,s){var a=e+(t&n|r&~n)+(i>>>0)+s;return (a<>>32-o)+t},a._hh=function(e,t,r,n,i,o,s){var a=e+(t^r^n)+(i>>>0)+s;return (a<>>32-o)+t},a._ii=function(e,t,r,n,i,o,s){var a=e+(r^(t|~n))+(i>>>0)+s;return (a<>>32-o)+t},a._blocksize=16,a._digestsize=16,e.exports=function(e,t){if(null==e)throw new Error(\"Illegal argument \"+e);var r=n.wordsToBytes(a(e,t));return t&&t.asBytes?r:t&&t.asString?s.bytesToString(r):n.bytesToHex(r)};},9591:(e,t,r)=>{var n={};(0, r(4236).assign)(n,r(4555),r(8843),r(1619)),e.exports=n;},4555:(e,t,r)=>{var n=r(405),i=r(4236),o=r(9373),s=r(8898),a=r(2292),f=Object.prototype.toString;function h(e){if(!(this instanceof h))return new h(e);this.options=i.assign({level:-1,method:8,chunkSize:16384,windowBits:15,memLevel:8,strategy:0,to:\"\"},e||{});var t=this.options;t.raw&&t.windowBits>0?t.windowBits=-t.windowBits:t.gzip&&t.windowBits>0&&t.windowBits<16&&(t.windowBits+=16),this.err=0,this.msg=\"\",this.ended=!1,this.chunks=[],this.strm=new a,this.strm.avail_out=0;var r=n.deflateInit2(this.strm,t.level,t.method,t.windowBits,t.memLevel,t.strategy);if(0!==r)throw new Error(s[r]);if(t.header&&n.deflateSetHeader(this.strm,t.header),t.dictionary){var l;if(l=\"string\"==typeof t.dictionary?o.string2buf(t.dictionary):\"[object ArrayBuffer]\"===f.call(t.dictionary)?new Uint8Array(t.dictionary):t.dictionary,0!==(r=n.deflateSetDictionary(this.strm,l)))throw new Error(s[r]);this._dict_set=!0;}}function l(e,t){var r=new h(t);if(r.push(e,!0),r.err)throw r.msg||s[r.err];return r.result}h.prototype.push=function(e,t){var r,s,a=this.strm,h=this.options.chunkSize;if(this.ended)return !1;s=t===~~t?t:!0===t?4:0,\"string\"==typeof e?a.input=o.string2buf(e):\"[object ArrayBuffer]\"===f.call(e)?a.input=new Uint8Array(e):a.input=e,a.next_in=0,a.avail_in=a.input.length;do{if(0===a.avail_out&&(a.output=new i.Buf8(h),a.next_out=0,a.avail_out=h),1!==(r=n.deflate(a,s))&&0!==r)return this.onEnd(r),this.ended=!0,!1;0!==a.avail_out&&(0!==a.avail_in||4!==s&&2!==s)||(\"string\"===this.options.to?this.onData(o.buf2binstring(i.shrinkBuf(a.output,a.next_out))):this.onData(i.shrinkBuf(a.output,a.next_out)));}while((a.avail_in>0||0===a.avail_out)&&1!==r);return 4===s?(r=n.deflateEnd(this.strm),this.onEnd(r),this.ended=!0,0===r):2!==s||(this.onEnd(0),a.avail_out=0,!0)},h.prototype.onData=function(e){this.chunks.push(e);},h.prototype.onEnd=function(e){0===e&&(\"string\"===this.options.to?this.result=this.chunks.join(\"\"):this.result=i.flattenChunks(this.chunks)),this.chunks=[],this.err=e,this.msg=this.strm.msg;},t.Deflate=h,t.deflate=l,t.deflateRaw=function(e,t){return (t=t||{}).raw=!0,l(e,t)},t.gzip=function(e,t){return (t=t||{}).gzip=!0,l(e,t)};},8843:(e,t,r)=>{var n=r(7948),i=r(4236),o=r(9373),s=r(1619),a=r(8898),f=r(2292),h=r(2401),l=Object.prototype.toString;function u(e){if(!(this instanceof u))return new u(e);this.options=i.assign({chunkSize:16384,windowBits:0,to:\"\"},e||{});var t=this.options;t.raw&&t.windowBits>=0&&t.windowBits<16&&(t.windowBits=-t.windowBits,0===t.windowBits&&(t.windowBits=-15)),!(t.windowBits>=0&&t.windowBits<16)||e&&e.windowBits||(t.windowBits+=32),t.windowBits>15&&t.windowBits<48&&0==(15&t.windowBits)&&(t.windowBits|=15),this.err=0,this.msg=\"\",this.ended=!1,this.chunks=[],this.strm=new f,this.strm.avail_out=0;var r=n.inflateInit2(this.strm,t.windowBits);if(r!==s.Z_OK)throw new Error(a[r]);if(this.header=new h,n.inflateGetHeader(this.strm,this.header),t.dictionary&&(\"string\"==typeof t.dictionary?t.dictionary=o.string2buf(t.dictionary):\"[object ArrayBuffer]\"===l.call(t.dictionary)&&(t.dictionary=new Uint8Array(t.dictionary)),t.raw&&(r=n.inflateSetDictionary(this.strm,t.dictionary))!==s.Z_OK))throw new Error(a[r])}function c(e,t){var r=new u(t);if(r.push(e,!0),r.err)throw r.msg||a[r.err];return r.result}u.prototype.push=function(e,t){var r,a,f,h,u,c=this.strm,d=this.options.chunkSize,p=this.options.dictionary,g=!1;if(this.ended)return !1;a=t===~~t?t:!0===t?s.Z_FINISH:s.Z_NO_FLUSH,\"string\"==typeof e?c.input=o.binstring2buf(e):\"[object ArrayBuffer]\"===l.call(e)?c.input=new Uint8Array(e):c.input=e,c.next_in=0,c.avail_in=c.input.length;do{if(0===c.avail_out&&(c.output=new i.Buf8(d),c.next_out=0,c.avail_out=d),(r=n.inflate(c,s.Z_NO_FLUSH))===s.Z_NEED_DICT&&p&&(r=n.inflateSetDictionary(this.strm,p)),r===s.Z_BUF_ERROR&&!0===g&&(r=s.Z_OK,g=!1),r!==s.Z_STREAM_END&&r!==s.Z_OK)return this.onEnd(r),this.ended=!0,!1;c.next_out&&(0!==c.avail_out&&r!==s.Z_STREAM_END&&(0!==c.avail_in||a!==s.Z_FINISH&&a!==s.Z_SYNC_FLUSH)||(\"string\"===this.options.to?(f=o.utf8border(c.output,c.next_out),h=c.next_out-f,u=o.buf2string(c.output,f),c.next_out=h,c.avail_out=d-h,h&&i.arraySet(c.output,c.output,f,h,0),this.onData(u)):this.onData(i.shrinkBuf(c.output,c.next_out)))),0===c.avail_in&&0===c.avail_out&&(g=!0);}while((c.avail_in>0||0===c.avail_out)&&r!==s.Z_STREAM_END);return r===s.Z_STREAM_END&&(a=s.Z_FINISH),a===s.Z_FINISH?(r=n.inflateEnd(this.strm),this.onEnd(r),this.ended=!0,r===s.Z_OK):a!==s.Z_SYNC_FLUSH||(this.onEnd(s.Z_OK),c.avail_out=0,!0)},u.prototype.onData=function(e){this.chunks.push(e);},u.prototype.onEnd=function(e){e===s.Z_OK&&(\"string\"===this.options.to?this.result=this.chunks.join(\"\"):this.result=i.flattenChunks(this.chunks)),this.chunks=[],this.err=e,this.msg=this.strm.msg;},t.Inflate=u,t.inflate=c,t.inflateRaw=function(e,t){return (t=t||{}).raw=!0,c(e,t)},t.ungzip=c;},4236:(e,t)=>{var r=\"undefined\"!=typeof Uint8Array&&\"undefined\"!=typeof Uint16Array&&\"undefined\"!=typeof Int32Array;function n(e,t){return Object.prototype.hasOwnProperty.call(e,t)}t.assign=function(e){for(var t=Array.prototype.slice.call(arguments,1);t.length;){var r=t.shift();if(r){if(\"object\"!=typeof r)throw new TypeError(r+\"must be non-object\");for(var i in r)n(r,i)&&(e[i]=r[i]);}}return e},t.shrinkBuf=function(e,t){return e.length===t?e:e.subarray?e.subarray(0,t):(e.length=t,e)};var i={arraySet:function(e,t,r,n,i){if(t.subarray&&e.subarray)e.set(t.subarray(r,r+n),i);else for(var o=0;o{var n=r(4236),i=!0,o=!0;try{String.fromCharCode.apply(null,[0]);}catch(e){i=!1;}try{String.fromCharCode.apply(null,new Uint8Array(1));}catch(e){o=!1;}for(var s=new n.Buf8(256),a=0;a<256;a++)s[a]=a>=252?6:a>=248?5:a>=240?4:a>=224?3:a>=192?2:1;function f(e,t){if(t<65534&&(e.subarray&&o||!e.subarray&&i))return String.fromCharCode.apply(null,n.shrinkBuf(e,t));for(var r=\"\",s=0;s>>6,t[s++]=128|63&r):r<65536?(t[s++]=224|r>>>12,t[s++]=128|r>>>6&63,t[s++]=128|63&r):(t[s++]=240|r>>>18,t[s++]=128|r>>>12&63,t[s++]=128|r>>>6&63,t[s++]=128|63&r);return t},t.buf2binstring=function(e){return f(e,e.length)},t.binstring2buf=function(e){for(var t=new n.Buf8(e.length),r=0,i=t.length;r4)h[n++]=65533,r+=o-1;else {for(i&=2===o?31:3===o?15:7;o>1&&r1?h[n++]=65533:i<65536?h[n++]=i:(i-=65536,h[n++]=55296|i>>10&1023,h[n++]=56320|1023&i);}return f(h,n)},t.utf8border=function(e,t){var r;for((t=t||e.length)>e.length&&(t=e.length),r=t-1;r>=0&&128==(192&e[r]);)r--;return r<0||0===r?t:r+s[e[r]]>t?r:t};},6069:e=>{e.exports=function(e,t,r,n){for(var i=65535&e|0,o=e>>>16&65535|0,s=0;0!==r;){r-=s=r>2e3?2e3:r;do{o=o+(i=i+t[n++]|0)|0;}while(--s);i%=65521,o%=65521;}return i|o<<16|0};},1619:e=>{e.exports={Z_NO_FLUSH:0,Z_PARTIAL_FLUSH:1,Z_SYNC_FLUSH:2,Z_FULL_FLUSH:3,Z_FINISH:4,Z_BLOCK:5,Z_TREES:6,Z_OK:0,Z_STREAM_END:1,Z_NEED_DICT:2,Z_ERRNO:-1,Z_STREAM_ERROR:-2,Z_DATA_ERROR:-3,Z_BUF_ERROR:-5,Z_NO_COMPRESSION:0,Z_BEST_SPEED:1,Z_BEST_COMPRESSION:9,Z_DEFAULT_COMPRESSION:-1,Z_FILTERED:1,Z_HUFFMAN_ONLY:2,Z_RLE:3,Z_FIXED:4,Z_DEFAULT_STRATEGY:0,Z_BINARY:0,Z_TEXT:1,Z_UNKNOWN:2,Z_DEFLATED:8};},2869:e=>{var t=function(){for(var e,t=[],r=0;r<256;r++){e=r;for(var n=0;n<8;n++)e=1&e?3988292384^e>>>1:e>>>1;t[r]=e;}return t}();e.exports=function(e,r,n,i){var o=t,s=i+n;e^=-1;for(var a=i;a>>8^o[255&(e^r[a])];return -1^e};},405:(e,t,r)=>{var n,i=r(4236),o=r(342),s=r(6069),a=r(2869),f=r(8898),h=-2,l=258,u=262,c=103,d=113,p=666;function g(e,t){return e.msg=f[t],t}function m(e){return (e<<1)-(e>4?9:0)}function y(e){for(var t=e.length;--t>=0;)e[t]=0;}function b(e){var t=e.state,r=t.pending;r>e.avail_out&&(r=e.avail_out),0!==r&&(i.arraySet(e.output,t.pending_buf,t.pending_out,r,e.next_out),e.next_out+=r,t.pending_out+=r,e.total_out+=r,e.avail_out-=r,t.pending-=r,0===t.pending&&(t.pending_out=0));}function v(e,t){o._tr_flush_block(e,e.block_start>=0?e.block_start:-1,e.strstart-e.block_start,t),e.block_start=e.strstart,b(e.strm);}function w(e,t){e.pending_buf[e.pending++]=t;}function _(e,t){e.pending_buf[e.pending++]=t>>>8&255,e.pending_buf[e.pending++]=255&t;}function B(e,t,r,n){var o=e.avail_in;return o>n&&(o=n),0===o?0:(e.avail_in-=o,i.arraySet(t,e.input,e.next_in,o,r),1===e.state.wrap?e.adler=s(e.adler,t,o,r):2===e.state.wrap&&(e.adler=a(e.adler,t,o,r)),e.next_in+=o,e.total_in+=o,o)}function E(e,t){var r,n,i=e.max_chain_length,o=e.strstart,s=e.prev_length,a=e.nice_match,f=e.strstart>e.w_size-u?e.strstart-(e.w_size-u):0,h=e.window,c=e.w_mask,d=e.prev,p=e.strstart+l,g=h[o+s-1],m=h[o+s];e.prev_length>=e.good_match&&(i>>=2),a>e.lookahead&&(a=e.lookahead);do{if(h[(r=t)+s]===m&&h[r+s-1]===g&&h[r]===h[o]&&h[++r]===h[o+1]){o+=2,r++;do{}while(h[++o]===h[++r]&&h[++o]===h[++r]&&h[++o]===h[++r]&&h[++o]===h[++r]&&h[++o]===h[++r]&&h[++o]===h[++r]&&h[++o]===h[++r]&&h[++o]===h[++r]&&os){if(e.match_start=t,s=n,n>=a)break;g=h[o+s-1],m=h[o+s];}}}while((t=d[t&c])>f&&0!=--i);return s<=e.lookahead?s:e.lookahead}function S(e){var t,r,n,o,s,a=e.w_size;do{if(o=e.window_size-e.lookahead-e.strstart,e.strstart>=a+(a-u)){i.arraySet(e.window,e.window,a,a,0),e.match_start-=a,e.strstart-=a,e.block_start-=a,t=r=e.hash_size;do{n=e.head[--t],e.head[t]=n>=a?n-a:0;}while(--r);t=r=a;do{n=e.prev[--t],e.prev[t]=n>=a?n-a:0;}while(--r);o+=a;}if(0===e.strm.avail_in)break;if(r=B(e.strm,e.window,e.strstart+e.lookahead,o),e.lookahead+=r,e.lookahead+e.insert>=3)for(s=e.strstart-e.insert,e.ins_h=e.window[s],e.ins_h=(e.ins_h<=3&&(e.ins_h=(e.ins_h<=3)if(n=o._tr_tally(e,e.strstart-e.match_start,e.match_length-3),e.lookahead-=e.match_length,e.match_length<=e.max_lazy_match&&e.lookahead>=3){e.match_length--;do{e.strstart++,e.ins_h=(e.ins_h<=3&&(e.ins_h=(e.ins_h<4096)&&(e.match_length=2)),e.prev_length>=3&&e.match_length<=e.prev_length){i=e.strstart+e.lookahead-3,n=o._tr_tally(e,e.strstart-1-e.prev_match,e.prev_length-3),e.lookahead-=e.prev_length-1,e.prev_length-=2;do{++e.strstart<=i&&(e.ins_h=(e.ins_h<15&&(a=2,n-=16),o<1||o>9||8!==r||n<8||n>15||t<0||t>9||s<0||s>4)return g(e,h);8===n&&(n=9);var f=new k;return e.state=f,f.strm=e,f.wrap=a,f.gzhead=null,f.w_bits=n,f.w_size=1<e.pending_buf_size-5&&(r=e.pending_buf_size-5);;){if(e.lookahead<=1){if(S(e),0===e.lookahead&&0===t)return 1;if(0===e.lookahead)break}e.strstart+=e.lookahead,e.lookahead=0;var n=e.block_start+r;if((0===e.strstart||e.strstart>=n)&&(e.lookahead=e.strstart-n,e.strstart=n,v(e,!1),0===e.strm.avail_out))return 1;if(e.strstart-e.block_start>=e.w_size-u&&(v(e,!1),0===e.strm.avail_out))return 1}return e.insert=0,4===t?(v(e,!0),0===e.strm.avail_out?3:4):(e.strstart>e.block_start&&(v(e,!1),e.strm.avail_out),1)})),new R(4,4,8,4,A),new R(4,5,16,8,A),new R(4,6,32,32,A),new R(4,4,16,16,C),new R(8,16,32,32,C),new R(8,16,128,128,C),new R(8,32,128,256,C),new R(32,128,258,1024,C),new R(32,258,258,4096,C)],t.deflateInit=function(e,t){return M(e,t,8,15,8,0)},t.deflateInit2=M,t.deflateReset=I,t.deflateResetKeep=x,t.deflateSetHeader=function(e,t){return e&&e.state?2!==e.state.wrap?h:(e.state.gzhead=t,0):h},t.deflate=function(e,t){var r,i,s,f;if(!e||!e.state||t>5||t<0)return e?g(e,h):h;if(i=e.state,!e.output||!e.input&&0!==e.avail_in||i.status===p&&4!==t)return g(e,0===e.avail_out?-5:h);if(i.strm=e,r=i.last_flush,i.last_flush=t,42===i.status)if(2===i.wrap)e.adler=0,w(i,31),w(i,139),w(i,8),i.gzhead?(w(i,(i.gzhead.text?1:0)+(i.gzhead.hcrc?2:0)+(i.gzhead.extra?4:0)+(i.gzhead.name?8:0)+(i.gzhead.comment?16:0)),w(i,255&i.gzhead.time),w(i,i.gzhead.time>>8&255),w(i,i.gzhead.time>>16&255),w(i,i.gzhead.time>>24&255),w(i,9===i.level?2:i.strategy>=2||i.level<2?4:0),w(i,255&i.gzhead.os),i.gzhead.extra&&i.gzhead.extra.length&&(w(i,255&i.gzhead.extra.length),w(i,i.gzhead.extra.length>>8&255)),i.gzhead.hcrc&&(e.adler=a(e.adler,i.pending_buf,i.pending,0)),i.gzindex=0,i.status=69):(w(i,0),w(i,0),w(i,0),w(i,0),w(i,0),w(i,9===i.level?2:i.strategy>=2||i.level<2?4:0),w(i,3),i.status=d);else {var u=8+(i.w_bits-8<<4)<<8;u|=(i.strategy>=2||i.level<2?0:i.level<6?1:6===i.level?2:3)<<6,0!==i.strstart&&(u|=32),u+=31-u%31,i.status=d,_(i,u),0!==i.strstart&&(_(i,e.adler>>>16),_(i,65535&e.adler)),e.adler=1;}if(69===i.status)if(i.gzhead.extra){for(s=i.pending;i.gzindex<(65535&i.gzhead.extra.length)&&(i.pending!==i.pending_buf_size||(i.gzhead.hcrc&&i.pending>s&&(e.adler=a(e.adler,i.pending_buf,i.pending-s,s)),b(e),s=i.pending,i.pending!==i.pending_buf_size));)w(i,255&i.gzhead.extra[i.gzindex]),i.gzindex++;i.gzhead.hcrc&&i.pending>s&&(e.adler=a(e.adler,i.pending_buf,i.pending-s,s)),i.gzindex===i.gzhead.extra.length&&(i.gzindex=0,i.status=73);}else i.status=73;if(73===i.status)if(i.gzhead.name){s=i.pending;do{if(i.pending===i.pending_buf_size&&(i.gzhead.hcrc&&i.pending>s&&(e.adler=a(e.adler,i.pending_buf,i.pending-s,s)),b(e),s=i.pending,i.pending===i.pending_buf_size)){f=1;break}f=i.gzindexs&&(e.adler=a(e.adler,i.pending_buf,i.pending-s,s)),0===f&&(i.gzindex=0,i.status=91);}else i.status=91;if(91===i.status)if(i.gzhead.comment){s=i.pending;do{if(i.pending===i.pending_buf_size&&(i.gzhead.hcrc&&i.pending>s&&(e.adler=a(e.adler,i.pending_buf,i.pending-s,s)),b(e),s=i.pending,i.pending===i.pending_buf_size)){f=1;break}f=i.gzindexs&&(e.adler=a(e.adler,i.pending_buf,i.pending-s,s)),0===f&&(i.status=c);}else i.status=c;if(i.status===c&&(i.gzhead.hcrc?(i.pending+2>i.pending_buf_size&&b(e),i.pending+2<=i.pending_buf_size&&(w(i,255&e.adler),w(i,e.adler>>8&255),e.adler=0,i.status=d)):i.status=d),0!==i.pending){if(b(e),0===e.avail_out)return i.last_flush=-1,0}else if(0===e.avail_in&&m(t)<=m(r)&&4!==t)return g(e,-5);if(i.status===p&&0!==e.avail_in)return g(e,-5);if(0!==e.avail_in||0!==i.lookahead||0!==t&&i.status!==p){var B=2===i.strategy?function(e,t){for(var r;;){if(0===e.lookahead&&(S(e),0===e.lookahead)){if(0===t)return 1;break}if(e.match_length=0,r=o._tr_tally(e,0,e.window[e.strstart]),e.lookahead--,e.strstart++,r&&(v(e,!1),0===e.strm.avail_out))return 1}return e.insert=0,4===t?(v(e,!0),0===e.strm.avail_out?3:4):e.last_lit&&(v(e,!1),0===e.strm.avail_out)?1:2}(i,t):3===i.strategy?function(e,t){for(var r,n,i,s,a=e.window;;){if(e.lookahead<=l){if(S(e),e.lookahead<=l&&0===t)return 1;if(0===e.lookahead)break}if(e.match_length=0,e.lookahead>=3&&e.strstart>0&&(n=a[i=e.strstart-1])===a[++i]&&n===a[++i]&&n===a[++i]){s=e.strstart+l;do{}while(n===a[++i]&&n===a[++i]&&n===a[++i]&&n===a[++i]&&n===a[++i]&&n===a[++i]&&n===a[++i]&&n===a[++i]&&ie.lookahead&&(e.match_length=e.lookahead);}if(e.match_length>=3?(r=o._tr_tally(e,1,e.match_length-3),e.lookahead-=e.match_length,e.strstart+=e.match_length,e.match_length=0):(r=o._tr_tally(e,0,e.window[e.strstart]),e.lookahead--,e.strstart++),r&&(v(e,!1),0===e.strm.avail_out))return 1}return e.insert=0,4===t?(v(e,!0),0===e.strm.avail_out?3:4):e.last_lit&&(v(e,!1),0===e.strm.avail_out)?1:2}(i,t):n[i.level].func(i,t);if(3!==B&&4!==B||(i.status=p),1===B||3===B)return 0===e.avail_out&&(i.last_flush=-1),0;if(2===B&&(1===t?o._tr_align(i):5!==t&&(o._tr_stored_block(i,0,0,!1),3===t&&(y(i.head),0===i.lookahead&&(i.strstart=0,i.block_start=0,i.insert=0))),b(e),0===e.avail_out))return i.last_flush=-1,0}return 4!==t?0:i.wrap<=0?1:(2===i.wrap?(w(i,255&e.adler),w(i,e.adler>>8&255),w(i,e.adler>>16&255),w(i,e.adler>>24&255),w(i,255&e.total_in),w(i,e.total_in>>8&255),w(i,e.total_in>>16&255),w(i,e.total_in>>24&255)):(_(i,e.adler>>>16),_(i,65535&e.adler)),b(e),i.wrap>0&&(i.wrap=-i.wrap),0!==i.pending?0:1)},t.deflateEnd=function(e){var t;return e&&e.state?42!==(t=e.state.status)&&69!==t&&73!==t&&91!==t&&t!==c&&t!==d&&t!==p?g(e,h):(e.state=null,t===d?g(e,-3):0):h},t.deflateSetDictionary=function(e,t){var r,n,o,a,f,l,u,c,d=t.length;if(!e||!e.state)return h;if(2===(a=(r=e.state).wrap)||1===a&&42!==r.status||r.lookahead)return h;for(1===a&&(e.adler=s(e.adler,t,d,0)),r.wrap=0,d>=r.w_size&&(0===a&&(y(r.head),r.strstart=0,r.block_start=0,r.insert=0),c=new i.Buf8(r.w_size),i.arraySet(c,t,d-r.w_size,r.w_size,0),t=c,d=r.w_size),f=e.avail_in,l=e.next_in,u=e.input,e.avail_in=d,e.next_in=0,e.input=t,S(r);r.lookahead>=3;){n=r.strstart,o=r.lookahead-2;do{r.ins_h=(r.ins_h<{e.exports=function(){this.text=0,this.time=0,this.xflags=0,this.os=0,this.extra=null,this.extra_len=0,this.name=\"\",this.comment=\"\",this.hcrc=0,this.done=!1;};},4264:e=>{e.exports=function(e,t){var r,n,i,o,s,a,f,h,l,u,c,d,p,g,m,y,b,v,w,_,B,E,S,A,C;r=e.state,n=e.next_in,A=e.input,i=n+(e.avail_in-5),o=e.next_out,C=e.output,s=o-(t-e.avail_out),a=o+(e.avail_out-257),f=r.dmax,h=r.wsize,l=r.whave,u=r.wnext,c=r.window,d=r.hold,p=r.bits,g=r.lencode,m=r.distcode,y=(1<>>=w=v>>>24,p-=w,0==(w=v>>>16&255))C[o++]=65535&v;else {if(!(16&w)){if(0==(64&w)){v=g[(65535&v)+(d&(1<>>=w,p-=w),p<15&&(d+=A[n++]<>>=w=v>>>24,p-=w,!(16&(w=v>>>16&255))){if(0==(64&w)){v=m[(65535&v)+(d&(1<f){e.msg=\"invalid distance too far back\",r.mode=30;break e}if(d>>>=w,p-=w,B>(w=o-s)){if((w=B-w)>l&&r.sane){e.msg=\"invalid distance too far back\",r.mode=30;break e}if(E=0,S=c,0===u){if(E+=h-w,w<_){_-=w;do{C[o++]=c[E++];}while(--w);E=o-B,S=C;}}else if(u2;)C[o++]=S[E++],C[o++]=S[E++],C[o++]=S[E++],_-=3;_&&(C[o++]=S[E++],_>1&&(C[o++]=S[E++]));}else {E=o-B;do{C[o++]=C[E++],C[o++]=C[E++],C[o++]=C[E++],_-=3;}while(_>2);_&&(C[o++]=C[E++],_>1&&(C[o++]=C[E++]));}break}}break}}while(n>3,d&=(1<<(p-=_<<3))-1,e.next_in=n,e.next_out=o,e.avail_in=n{var n=r(4236),i=r(6069),o=r(2869),s=r(4264),a=r(9241),f=-2,h=12,l=30;function u(e){return (e>>>24&255)+(e>>>8&65280)+((65280&e)<<8)+((255&e)<<24)}function c(){this.mode=0,this.last=!1,this.wrap=0,this.havedict=!1,this.flags=0,this.dmax=0,this.check=0,this.total=0,this.head=null,this.wbits=0,this.wsize=0,this.whave=0,this.wnext=0,this.window=null,this.hold=0,this.bits=0,this.length=0,this.offset=0,this.extra=0,this.lencode=null,this.distcode=null,this.lenbits=0,this.distbits=0,this.ncode=0,this.nlen=0,this.ndist=0,this.have=0,this.next=null,this.lens=new n.Buf16(320),this.work=new n.Buf16(288),this.lendyn=null,this.distdyn=null,this.sane=0,this.back=0,this.was=0;}function d(e){var t;return e&&e.state?(t=e.state,e.total_in=e.total_out=t.total=0,e.msg=\"\",t.wrap&&(e.adler=1&t.wrap),t.mode=1,t.last=0,t.havedict=0,t.dmax=32768,t.head=null,t.hold=0,t.bits=0,t.lencode=t.lendyn=new n.Buf32(852),t.distcode=t.distdyn=new n.Buf32(592),t.sane=1,t.back=-1,0):f}function p(e){var t;return e&&e.state?((t=e.state).wsize=0,t.whave=0,t.wnext=0,d(e)):f}function g(e,t){var r,n;return e&&e.state?(n=e.state,t<0?(r=0,t=-t):(r=1+(t>>4),t<48&&(t&=15)),t&&(t<8||t>15)?f:(null!==n.window&&n.wbits!==t&&(n.window=null),n.wrap=r,n.wbits=t,p(e))):f}function m(e,t){var r,n;return e?(n=new c,e.state=n,n.window=null,0!==(r=g(e,t))&&(e.state=null),r):f}var y,b,v=!0;function w(e){if(v){var t;for(y=new n.Buf32(512),b=new n.Buf32(32),t=0;t<144;)e.lens[t++]=8;for(;t<256;)e.lens[t++]=9;for(;t<280;)e.lens[t++]=7;for(;t<288;)e.lens[t++]=8;for(a(1,e.lens,0,288,y,0,e.work,{bits:9}),t=0;t<32;)e.lens[t++]=5;a(2,e.lens,0,32,b,0,e.work,{bits:5}),v=!1;}e.lencode=y,e.lenbits=9,e.distcode=b,e.distbits=5;}function _(e,t,r,i){var o,s=e.state;return null===s.window&&(s.wsize=1<=s.wsize?(n.arraySet(s.window,t,r-s.wsize,s.wsize,0),s.wnext=0,s.whave=s.wsize):((o=s.wsize-s.wnext)>i&&(o=i),n.arraySet(s.window,t,r-i,o,s.wnext),(i-=o)?(n.arraySet(s.window,t,r-i,i,0),s.wnext=i,s.whave=s.wsize):(s.wnext+=o,s.wnext===s.wsize&&(s.wnext=0),s.whave>>8&255,r.check=o(r.check,L,2,0),b=0,v=0,r.mode=2;break}if(r.flags=0,r.head&&(r.head.done=!1),!(1&r.wrap)||(((255&b)<<8)+(b>>8))%31){e.msg=\"incorrect header check\",r.mode=l;break}if(8!=(15&b)){e.msg=\"unknown compression method\",r.mode=l;break}if(v-=4,O=8+(15&(b>>>=4)),0===r.wbits)r.wbits=O;else if(O>r.wbits){e.msg=\"invalid window size\",r.mode=l;break}r.dmax=1<>8&1),512&r.flags&&(L[0]=255&b,L[1]=b>>>8&255,r.check=o(r.check,L,2,0)),b=0,v=0,r.mode=3;case 3:for(;v<32;){if(0===m)break e;m--,b+=c[p++]<>>8&255,L[2]=b>>>16&255,L[3]=b>>>24&255,r.check=o(r.check,L,4,0)),b=0,v=0,r.mode=4;case 4:for(;v<16;){if(0===m)break e;m--,b+=c[p++]<>8),512&r.flags&&(L[0]=255&b,L[1]=b>>>8&255,r.check=o(r.check,L,2,0)),b=0,v=0,r.mode=5;case 5:if(1024&r.flags){for(;v<16;){if(0===m)break e;m--,b+=c[p++]<>>8&255,r.check=o(r.check,L,2,0)),b=0,v=0;}else r.head&&(r.head.extra=null);r.mode=6;case 6:if(1024&r.flags&&((S=r.length)>m&&(S=m),S&&(r.head&&(O=r.head.extra_len-r.length,r.head.extra||(r.head.extra=new Array(r.head.extra_len)),n.arraySet(r.head.extra,c,p,S,O)),512&r.flags&&(r.check=o(r.check,c,S,p)),m-=S,p+=S,r.length-=S),r.length))break e;r.length=0,r.mode=7;case 7:if(2048&r.flags){if(0===m)break e;S=0;do{O=c[p+S++],r.head&&O&&r.length<65536&&(r.head.name+=String.fromCharCode(O));}while(O&&S>9&1,r.head.done=!0),e.adler=r.check=0,r.mode=h;break;case 10:for(;v<32;){if(0===m)break e;m--,b+=c[p++]<>>=7&v,v-=7&v,r.mode=27;break}for(;v<3;){if(0===m)break e;m--,b+=c[p++]<>>=1)){case 0:r.mode=14;break;case 1:if(w(r),r.mode=20,6===t){b>>>=2,v-=2;break e}break;case 2:r.mode=17;break;case 3:e.msg=\"invalid block type\",r.mode=l;}b>>>=2,v-=2;break;case 14:for(b>>>=7&v,v-=7&v;v<32;){if(0===m)break e;m--,b+=c[p++]<>>16^65535)){e.msg=\"invalid stored block lengths\",r.mode=l;break}if(r.length=65535&b,b=0,v=0,r.mode=15,6===t)break e;case 15:r.mode=16;case 16:if(S=r.length){if(S>m&&(S=m),S>y&&(S=y),0===S)break e;n.arraySet(d,c,p,S,g),m-=S,p+=S,y-=S,g+=S,r.length-=S;break}r.mode=h;break;case 17:for(;v<14;){if(0===m)break e;m--,b+=c[p++]<>>=5,v-=5,r.ndist=1+(31&b),b>>>=5,v-=5,r.ncode=4+(15&b),b>>>=4,v-=4,r.nlen>286||r.ndist>30){e.msg=\"too many length or distance symbols\",r.mode=l;break}r.have=0,r.mode=18;case 18:for(;r.have>>=3,v-=3;}for(;r.have<19;)r.lens[z[r.have++]]=0;if(r.lencode=r.lendyn,r.lenbits=7,U={bits:r.lenbits},T=a(0,r.lens,0,19,r.lencode,0,r.work,U),r.lenbits=U.bits,T){e.msg=\"invalid code lengths set\",r.mode=l;break}r.have=0,r.mode=19;case 19:for(;r.have>>16&255,x=65535&N,!((R=N>>>24)<=v);){if(0===m)break e;m--,b+=c[p++]<>>=R,v-=R,r.lens[r.have++]=x;else {if(16===x){for(P=R+2;v>>=R,v-=R,0===r.have){e.msg=\"invalid bit length repeat\",r.mode=l;break}O=r.lens[r.have-1],S=3+(3&b),b>>>=2,v-=2;}else if(17===x){for(P=R+3;v>>=R)),b>>>=3,v-=3;}else {for(P=R+7;v>>=R)),b>>>=7,v-=7;}if(r.have+S>r.nlen+r.ndist){e.msg=\"invalid bit length repeat\",r.mode=l;break}for(;S--;)r.lens[r.have++]=O;}}if(r.mode===l)break;if(0===r.lens[256]){e.msg=\"invalid code -- missing end-of-block\",r.mode=l;break}if(r.lenbits=9,U={bits:r.lenbits},T=a(1,r.lens,0,r.nlen,r.lencode,0,r.work,U),r.lenbits=U.bits,T){e.msg=\"invalid literal/lengths set\",r.mode=l;break}if(r.distbits=6,r.distcode=r.distdyn,U={bits:r.distbits},T=a(2,r.lens,r.nlen,r.ndist,r.distcode,0,r.work,U),r.distbits=U.bits,T){e.msg=\"invalid distances set\",r.mode=l;break}if(r.mode=20,6===t)break e;case 20:r.mode=21;case 21:if(m>=6&&y>=258){e.next_out=g,e.avail_out=y,e.next_in=p,e.avail_in=m,r.hold=b,r.bits=v,s(e,E),g=e.next_out,d=e.output,y=e.avail_out,p=e.next_in,c=e.input,m=e.avail_in,b=r.hold,v=r.bits,r.mode===h&&(r.back=-1);break}for(r.back=0;k=(N=r.lencode[b&(1<>>16&255,x=65535&N,!((R=N>>>24)<=v);){if(0===m)break e;m--,b+=c[p++]<>I)])>>>16&255,x=65535&N,!(I+(R=N>>>24)<=v);){if(0===m)break e;m--,b+=c[p++]<>>=I,v-=I,r.back+=I;}if(b>>>=R,v-=R,r.back+=R,r.length=x,0===k){r.mode=26;break}if(32&k){r.back=-1,r.mode=h;break}if(64&k){e.msg=\"invalid literal/length code\",r.mode=l;break}r.extra=15&k,r.mode=22;case 22:if(r.extra){for(P=r.extra;v>>=r.extra,v-=r.extra,r.back+=r.extra;}r.was=r.length,r.mode=23;case 23:for(;k=(N=r.distcode[b&(1<>>16&255,x=65535&N,!((R=N>>>24)<=v);){if(0===m)break e;m--,b+=c[p++]<>I)])>>>16&255,x=65535&N,!(I+(R=N>>>24)<=v);){if(0===m)break e;m--,b+=c[p++]<>>=I,v-=I,r.back+=I;}if(b>>>=R,v-=R,r.back+=R,64&k){e.msg=\"invalid distance code\",r.mode=l;break}r.offset=x,r.extra=15&k,r.mode=24;case 24:if(r.extra){for(P=r.extra;v>>=r.extra,v-=r.extra,r.back+=r.extra;}if(r.offset>r.dmax){e.msg=\"invalid distance too far back\",r.mode=l;break}r.mode=25;case 25:if(0===y)break e;if(S=E-y,r.offset>S){if((S=r.offset-S)>r.whave&&r.sane){e.msg=\"invalid distance too far back\",r.mode=l;break}S>r.wnext?(S-=r.wnext,A=r.wsize-S):A=r.wnext-S,S>r.length&&(S=r.length),C=r.window;}else C=d,A=g-r.offset,S=r.length;S>y&&(S=y),y-=S,r.length-=S;do{d[g++]=C[A++];}while(--S);0===r.length&&(r.mode=21);break;case 26:if(0===y)break e;d[g++]=r.length,y--,r.mode=21;break;case 27:if(r.wrap){for(;v<32;){if(0===m)break e;m--,b|=c[p++]<{var n=r(4236),i=[3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258,0,0],o=[16,16,16,16,16,16,16,16,17,17,17,17,18,18,18,18,19,19,19,19,20,20,20,20,21,21,21,21,16,72,78],s=[1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,0,0],a=[16,16,16,16,17,17,18,18,19,19,20,20,21,21,22,22,23,23,24,24,25,25,26,26,27,27,28,28,29,29,64,64];e.exports=function(e,t,r,f,h,l,u,c){var d,p,g,m,y,b,v,w,_,B=c.bits,E=0,S=0,A=0,C=0,R=0,k=0,x=0,I=0,M=0,F=0,O=null,T=0,U=new n.Buf16(16),P=new n.Buf16(16),N=null,L=0;for(E=0;E<=15;E++)U[E]=0;for(S=0;S=1&&0===U[C];C--);if(R>C&&(R=C),0===C)return h[l++]=20971520,h[l++]=20971520,c.bits=1,0;for(A=1;A0&&(0===e||1!==C))return -1;for(P[1]=0,E=1;E<15;E++)P[E+1]=P[E]+U[E];for(S=0;S852||2===e&&M>592)return 1;for(;;){v=E-x,u[S]b?(w=N[L+u[S]],_=O[T+u[S]]):(w=96,_=0),d=1<>x)+(p-=d)]=v<<24|w<<16|_|0;}while(0!==p);for(d=1<>=1;if(0!==d?(F&=d-1,F+=d):F=0,S++,0==--U[E]){if(E===C)break;E=t[r+u[S]];}if(E>R&&(F&m)!==g){for(0===x&&(x=R),y+=A,I=1<<(k=E-x);k+x852||2===e&&M>592)return 1;h[g=F&m]=R<<24|k<<16|y-l|0;}}return 0!==F&&(h[y+F]=E-x<<24|64<<16|0),c.bits=R,0};},8898:e=>{e.exports={2:\"need dictionary\",1:\"stream end\",0:\"\",\"-1\":\"file error\",\"-2\":\"stream error\",\"-3\":\"data error\",\"-4\":\"insufficient memory\",\"-5\":\"buffer error\",\"-6\":\"incompatible version\"};},342:(e,t,r)=>{var n=r(4236);function i(e){for(var t=e.length;--t>=0;)e[t]=0;}var o=[0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0],s=[0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13],a=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7],f=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15],h=new Array(576);i(h);var l=new Array(60);i(l);var u=new Array(512);i(u);var c=new Array(256);i(c);var d=new Array(29);i(d);var p,g,m,y=new Array(30);function b(e,t,r,n,i){this.static_tree=e,this.extra_bits=t,this.extra_base=r,this.elems=n,this.max_length=i,this.has_stree=e&&e.length;}function v(e,t){this.dyn_tree=e,this.max_code=0,this.stat_desc=t;}function w(e){return e<256?u[e]:u[256+(e>>>7)]}function _(e,t){e.pending_buf[e.pending++]=255&t,e.pending_buf[e.pending++]=t>>>8&255;}function B(e,t,r){e.bi_valid>16-r?(e.bi_buf|=t<>16-e.bi_valid,e.bi_valid+=r-16):(e.bi_buf|=t<>>=1,r<<=1;}while(--t>0);return r>>>1}function A(e,t,r){var n,i,o=new Array(16),s=0;for(n=1;n<=15;n++)o[n]=s=s+r[n-1]<<1;for(i=0;i<=t;i++){var a=e[2*i+1];0!==a&&(e[2*i]=S(o[a]++,a));}}function C(e){var t;for(t=0;t<286;t++)e.dyn_ltree[2*t]=0;for(t=0;t<30;t++)e.dyn_dtree[2*t]=0;for(t=0;t<19;t++)e.bl_tree[2*t]=0;e.dyn_ltree[512]=1,e.opt_len=e.static_len=0,e.last_lit=e.matches=0;}function R(e){e.bi_valid>8?_(e,e.bi_buf):e.bi_valid>0&&(e.pending_buf[e.pending++]=e.bi_buf),e.bi_buf=0,e.bi_valid=0;}function k(e,t,r,n){var i=2*t,o=2*r;return e[i]>1;r>=1;r--)x(e,o,r);i=f;do{r=e.heap[1],e.heap[1]=e.heap[e.heap_len--],x(e,o,1),n=e.heap[1],e.heap[--e.heap_max]=r,e.heap[--e.heap_max]=n,o[2*i]=o[2*r]+o[2*n],e.depth[i]=(e.depth[r]>=e.depth[n]?e.depth[r]:e.depth[n])+1,o[2*r+1]=o[2*n+1]=i,e.heap[1]=i++,x(e,o,1);}while(e.heap_len>=2);e.heap[--e.heap_max]=e.heap[1],function(e,t){var r,n,i,o,s,a,f=t.dyn_tree,h=t.max_code,l=t.stat_desc.static_tree,u=t.stat_desc.has_stree,c=t.stat_desc.extra_bits,d=t.stat_desc.extra_base,p=t.stat_desc.max_length,g=0;for(o=0;o<=15;o++)e.bl_count[o]=0;for(f[2*e.heap[e.heap_max]+1]=0,r=e.heap_max+1;r<573;r++)(o=f[2*f[2*(n=e.heap[r])+1]+1]+1)>p&&(o=p,g++),f[2*n+1]=o,n>h||(e.bl_count[o]++,s=0,n>=d&&(s=c[n-d]),a=f[2*n],e.opt_len+=a*(o+s),u&&(e.static_len+=a*(l[2*n+1]+s)));if(0!==g){do{for(o=p-1;0===e.bl_count[o];)o--;e.bl_count[o]--,e.bl_count[o+1]+=2,e.bl_count[p]--,g-=2;}while(g>0);for(o=p;0!==o;o--)for(n=e.bl_count[o];0!==n;)(i=e.heap[--r])>h||(f[2*i+1]!==o&&(e.opt_len+=(o-f[2*i+1])*f[2*i],f[2*i+1]=o),n--);}}(e,t),A(o,h,e.bl_count);}function F(e,t,r){var n,i,o=-1,s=t[1],a=0,f=7,h=4;for(0===s&&(f=138,h=3),t[2*(r+1)+1]=65535,n=0;n<=r;n++)i=s,s=t[2*(n+1)+1],++a>=7;n<30;n++)for(y[n]=i<<7,e=0;e<1<0?(2===e.strm.data_type&&(e.strm.data_type=function(e){var t,r=4093624447;for(t=0;t<=31;t++,r>>>=1)if(1&r&&0!==e.dyn_ltree[2*t])return 0;if(0!==e.dyn_ltree[18]||0!==e.dyn_ltree[20]||0!==e.dyn_ltree[26])return 1;for(t=32;t<256;t++)if(0!==e.dyn_ltree[2*t])return 1;return 0}(e)),M(e,e.l_desc),M(e,e.d_desc),s=function(e){var t;for(F(e,e.dyn_ltree,e.l_desc.max_code),F(e,e.dyn_dtree,e.d_desc.max_code),M(e,e.bl_desc),t=18;t>=3&&0===e.bl_tree[2*f[t]+1];t--);return e.opt_len+=3*(t+1)+5+5+4,t}(e),i=e.opt_len+3+7>>>3,(o=e.static_len+3+7>>>3)<=i&&(i=o)):i=o=r+5,r+4<=i&&-1!==t?U(e,t,r,n):4===e.strategy||o===i?(B(e,2+(n?1:0),3),I(e,h,l)):(B(e,4+(n?1:0),3),function(e,t,r,n){var i;for(B(e,t-257,5),B(e,r-1,5),B(e,n-4,4),i=0;i>>8&255,e.pending_buf[e.d_buf+2*e.last_lit+1]=255&t,e.pending_buf[e.l_buf+e.last_lit]=255&r,e.last_lit++,0===t?e.dyn_ltree[2*r]++:(e.matches++,t--,e.dyn_ltree[2*(c[r]+256+1)]++,e.dyn_dtree[2*w(t)]++),e.last_lit===e.lit_bufsize-1},t._tr_align=function(e){B(e,2,3),E(e,256,h),function(e){16===e.bi_valid?(_(e,e.bi_buf),e.bi_buf=0,e.bi_valid=0):e.bi_valid>=8&&(e.pending_buf[e.pending++]=255&e.bi_buf,e.bi_buf>>=8,e.bi_valid-=8);}(e);};},2292:e=>{e.exports=function(){this.input=null,this.next_in=0,this.avail_in=0,this.total_in=0,this.output=null,this.next_out=0,this.avail_out=0,this.total_out=0,this.msg=\"\",this.state=null,this.data_type=2,this.adler=0;};},2587:e=>{function t(e,t){return Object.prototype.hasOwnProperty.call(e,t)}e.exports=function(e,r,n,i){r=r||\"&\",n=n||\"=\";var o={};if(\"string\"!=typeof e||0===e.length)return o;var s=/\\+/g;e=e.split(r);var a=1e3;i&&\"number\"==typeof i.maxKeys&&(a=i.maxKeys);var f=e.length;a>0&&f>a&&(f=a);for(var h=0;h=0?(l=p.substr(0,g),u=p.substr(g+1)):(l=p,u=\"\"),c=decodeURIComponent(l),d=decodeURIComponent(u),t(o,c)?Array.isArray(o[c])?o[c].push(d):o[c]=[o[c],d]:o[c]=d;}return o};},2361:e=>{var t=function(e){switch(typeof e){case\"string\":return e;case\"boolean\":return e?\"true\":\"false\";case\"number\":return isFinite(e)?e:\"\";default:return \"\"}};e.exports=function(e,r,n,i){return r=r||\"&\",n=n||\"=\",null===e&&(e=void 0),\"object\"==typeof e?Object.keys(e).map((function(i){var o=encodeURIComponent(t(i))+n;return Array.isArray(e[i])?e[i].map((function(e){return o+encodeURIComponent(t(e))})).join(r):o+encodeURIComponent(t(e[i]))})).join(r):i?encodeURIComponent(t(i))+n+encodeURIComponent(t(e)):\"\"};},7673:(e,t,r)=>{t.decode=t.parse=r(2587),t.encode=t.stringify=r(2361);},1269:e=>{class t{constructor(e={}){if(!(e.maxSize&&e.maxSize>0))throw new TypeError(\"`maxSize` must be a number greater than 0\");this.maxSize=e.maxSize,this.cache=new Map,this.oldCache=new Map,this._size=0;}_set(e,t){this.cache.set(e,t),this._size++,this._size>=this.maxSize&&(this._size=0,this.oldCache=this.cache,this.cache=new Map);}get(e){if(this.cache.has(e))return this.cache.get(e);if(this.oldCache.has(e)){const t=this.oldCache.get(e);return this.oldCache.delete(e),this._set(e,t),t}}set(e,t){return this.cache.has(e)?this.cache.set(e,t):this._set(e,t),this}has(e){return this.cache.has(e)||this.oldCache.has(e)}peek(e){return this.cache.has(e)?this.cache.get(e):this.oldCache.has(e)?this.oldCache.get(e):void 0}delete(e){const t=this.cache.delete(e);return t&&this._size--,this.oldCache.delete(e)||t}clear(){this.cache.clear(),this.oldCache.clear(),this._size=0;}*keys(){for(const[e]of this)yield e;}*values(){for(const[,e]of this)yield e;}*[Symbol.iterator](){for(const e of this.cache)yield e;for(const e of this.oldCache){const[t]=e;this.cache.has(t)||(yield e);}}get size(){let e=0;for(const t of this.oldCache.keys())this.cache.has(t)||e++;return this._size+e}}e.exports=t;},2511:function(e,t,r){var n;e=r.nmd(e),function(i){t&&t.nodeType,e&&e.nodeType;var o=\"object\"==typeof r.g&&r.g;o.global!==o&&o.window!==o&&o.self;var s,a=2147483647,f=36,h=/^xn--/,l=/[^\\x20-\\x7E]/,u=/[\\x2E\\u3002\\uFF0E\\uFF61]/g,c={overflow:\"Overflow: input needs wider integers to process\",\"not-basic\":\"Illegal input >= 0x80 (not a basic code point)\",\"invalid-input\":\"Invalid input\"},d=Math.floor,p=String.fromCharCode;function g(e){throw RangeError(c[e])}function m(e,t){for(var r=e.length,n=[];r--;)n[r]=t(e[r]);return n}function y(e,t){var r=e.split(\"@\"),n=\"\";return r.length>1&&(n=r[0]+\"@\",e=r[1]),n+m((e=e.replace(u,\".\")).split(\".\"),t).join(\".\")}function b(e){for(var t,r,n=[],i=0,o=e.length;i=55296&&t<=56319&&i65535&&(t+=p((e-=65536)>>>10&1023|55296),e=56320|1023&e),t+p(e)})).join(\"\")}function w(e,t){return e+22+75*(e<26)-((0!=t)<<5)}function _(e,t,r){var n=0;for(e=r?d(e/700):e>>1,e+=d(e/t);e>455;n+=f)e=d(e/35);return d(n+36*e/(e+38))}function B(e){var t,r,n,i,o,s,h,l,u,c,p,m=[],y=e.length,b=0,w=128,B=72;for((r=e.lastIndexOf(\"-\"))<0&&(r=0),n=0;n=128&&g(\"not-basic\"),m.push(e.charCodeAt(n));for(i=r>0?r+1:0;i=y&&g(\"invalid-input\"),((l=(p=e.charCodeAt(i++))-48<10?p-22:p-65<26?p-65:p-97<26?p-97:f)>=f||l>d((a-b)/s))&&g(\"overflow\"),b+=l*s,!(l<(u=h<=B?1:h>=B+26?26:h-B));h+=f)s>d(a/(c=f-u))&&g(\"overflow\"),s*=c;B=_(b-o,t=m.length+1,0==o),d(b/t)>a-w&&g(\"overflow\"),w+=d(b/t),b%=t,m.splice(b++,0,w);}return v(m)}function E(e){var t,r,n,i,o,s,h,l,u,c,m,y,v,B,E,S=[];for(y=(e=b(e)).length,t=128,r=0,o=72,s=0;s=t&&md((a-r)/(v=n+1))&&g(\"overflow\"),r+=(h-t)*v,t=h,s=0;sa&&g(\"overflow\"),m==t){for(l=r,u=f;!(l<(c=u<=o?1:u>=o+26?26:u-o));u+=f)E=l-c,B=f-c,S.push(p(w(c+E%B,0))),l=d(E/B);S.push(p(w(l,0))),o=_(r,v,n==i),r=0,++n;}++r,++t;}return S.join(\"\")}s={version:\"1.3.2\",ucs2:{decode:b,encode:v},decode:B,encode:E,toASCII:function(e){return y(e,(function(e){return l.test(e)?\"xn--\"+E(e):e}))},toUnicode:function(e){return y(e,(function(e){return h.test(e)?B(e.slice(4).toLowerCase()):e}))}},void 0===(n=function(){return s}.call(t,r,t,e))||(e.exports=n);}();},8575:(e,t,r)=>{var n=r(2511),i=r(2502);function o(){this.protocol=null,this.slashes=null,this.auth=null,this.host=null,this.port=null,this.hostname=null,this.hash=null,this.search=null,this.query=null,this.pathname=null,this.path=null,this.href=null;}t.parse=v,t.resolve=function(e,t){return v(e,!1,!0).resolve(t)},t.resolveObject=function(e,t){return e?v(e,!1,!0).resolveObject(t):t},t.format=function(e){return i.isString(e)&&(e=v(e)),e instanceof o?e.format():o.prototype.format.call(e)},t.Url=o;var s=/^([a-z0-9.+-]+:)/i,a=/:[0-9]*$/,f=/^(\\/\\/?(?!\\/)[^\\?\\s]*)(\\?[^\\s]*)?$/,h=[\"{\",\"}\",\"|\",\"\\\\\",\"^\",\"`\"].concat([\"<\",\">\",'\"',\"`\",\" \",\"\\r\",\"\\n\",\"\\t\"]),l=[\"'\"].concat(h),u=[\"%\",\"/\",\"?\",\";\",\"#\"].concat(l),c=[\"/\",\"?\",\"#\"],d=/^[+a-z0-9A-Z_-]{0,63}$/,p=/^([+a-z0-9A-Z_-]{0,63})(.*)$/,g={javascript:!0,\"javascript:\":!0},m={javascript:!0,\"javascript:\":!0},y={http:!0,https:!0,ftp:!0,gopher:!0,file:!0,\"http:\":!0,\"https:\":!0,\"ftp:\":!0,\"gopher:\":!0,\"file:\":!0},b=r(7673);function v(e,t,r){if(e&&i.isObject(e)&&e instanceof o)return e;var n=new o;return n.parse(e,t,r),n}o.prototype.parse=function(e,t,r){if(!i.isString(e))throw new TypeError(\"Parameter 'url' must be a string, not \"+typeof e);var o=e.indexOf(\"?\"),a=-1!==o&&o127?O+=\"x\":O+=F[T];if(!O.match(d)){var P=I.slice(0,R),N=I.slice(R+1),L=F.match(p);L&&(P.push(L[1]),N.unshift(L[2])),N.length&&(v=\"/\"+N.join(\".\")+v),this.hostname=P.join(\".\");break}}}this.hostname.length>255?this.hostname=\"\":this.hostname=this.hostname.toLowerCase(),x||(this.hostname=n.toASCII(this.hostname));var z=this.port?\":\"+this.port:\"\",D=this.hostname||\"\";this.host=D+z,this.href+=this.host,x&&(this.hostname=this.hostname.substr(1,this.hostname.length-2),\"/\"!==v[0]&&(v=\"/\"+v));}if(!g[B])for(R=0,M=l.length;R0)&&r.host.split(\"@\"))&&(r.auth=x.shift(),r.host=r.hostname=x.shift())),r.search=e.search,r.query=e.query,i.isNull(r.pathname)&&i.isNull(r.search)||(r.path=(r.pathname?r.pathname:\"\")+(r.search?r.search:\"\")),r.href=r.format(),r;if(!E.length)return r.pathname=null,r.search?r.path=\"/\"+r.search:r.path=null,r.href=r.format(),r;for(var A=E.slice(-1)[0],C=(r.host||e.host||E.length>1)&&(\".\"===A||\"..\"===A)||\"\"===A,R=0,k=E.length;k>=0;k--)\".\"===(A=E[k])?E.splice(k,1):\"..\"===A?(E.splice(k,1),R++):R&&(E.splice(k,1),R--);if(!_&&!B)for(;R--;R)E.unshift(\"..\");!_||\"\"===E[0]||E[0]&&\"/\"===E[0].charAt(0)||E.unshift(\"\"),C&&\"/\"!==E.join(\"/\").substr(-1)&&E.push(\"\");var x,I=\"\"===E[0]||E[0]&&\"/\"===E[0].charAt(0);return S&&(r.hostname=r.host=I?\"\":E.length?E.shift():\"\",(x=!!(r.host&&r.host.indexOf(\"@\")>0)&&r.host.split(\"@\"))&&(r.auth=x.shift(),r.host=r.hostname=x.shift())),(_=_||r.host&&E.length)&&!I&&E.unshift(\"\"),E.length?r.pathname=E.join(\"/\"):(r.pathname=null,r.path=null),i.isNull(r.pathname)&&i.isNull(r.search)||(r.path=(r.pathname?r.pathname:\"\")+(r.search?r.search:\"\")),r.auth=e.auth||r.auth,r.slashes=r.slashes||e.slashes,r.href=r.format(),r},o.prototype.parseHost=function(){var e=this.host,t=a.exec(e);t&&(\":\"!==(t=t[0])&&(this.port=t.substr(1)),e=e.substr(0,e.length-t.length)),e&&(this.hostname=e);};},2502:e=>{e.exports={isString:function(e){return \"string\"==typeof e},isObject:function(e){return \"object\"==typeof e&&null!==e},isNull:function(e){return null===e},isNullOrUndefined:function(e){return null==e}};},7067:()=>{}},t={};function r(n){var i=t[n];if(void 0!==i)return i.exports;var o=t[n]={id:n,loaded:!1,exports:{}};return e[n].call(o.exports,o,o.exports,r),o.loaded=!0,o.exports}r.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return r.d(t,{a:t}),t},r.d=(e,t)=>{for(var n in t)r.o(t,n)&&!r.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]});},r.g=function(){if(\"object\"==typeof globalThis)return globalThis;try{return this||new Function(\"return this\")()}catch(e){if(\"object\"==typeof window)return window}}(),r.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),r.r=e=>{\"undefined\"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:\"Module\"}),Object.defineProperty(e,\"__esModule\",{value:!0});},r.nmd=e=>(e.paths=[],e.children||(e.children=[]),e);var n=r(5590);\n //window.gmodCRAM=n\n return n;\n};\n\nconst gmodCRAM = fn();\n\n/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2018 The Regents of the University of California\n * Author: Jim Robinson\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\nconst READ_STRAND_FLAG = 0x10;\nconst MATE_STRAND_FLAG = 0x20;\n\nconst CRAM_MATE_STRAND_FLAG = 0x1;\n\n/**\n * Class for reading a cram file. Wraps the gMOD Cram package.\n *\n * @param config\n * @constructor\n */\nclass CramReader {\n\n constructor(config, genome, browser) {\n\n this.config = config;\n this.browser = browser;\n this.genome = genome;\n\n this.cramFile = new gmodCRAM.CramFile({\n filehandle: new FileHandler(config.url, config),\n seqFetch: config.seqFetch || seqFetch.bind(this),\n checkSequenceMD5: config.checkSequenceMD5 !== undefined ? config.checkSequenceMD5 : true\n });\n\n const indexFileHandle = new FileHandler(config.indexURL, config);\n this.indexedCramFile = new gmodCRAM.IndexedCramFile({\n cram: this.cramFile,\n index: new gmodCRAM.CraiIndex({\n filehandle: indexFileHandle\n }),\n fetchSizeLimit: 30000000\n });\n\n BamUtils.setReaderDefaults(this, config);\n\n function seqFetch(seqID, start, end) {\n\n const sequence = this.genome.sequence;\n const genome = this.genome;\n\n return this.getHeader()\n .then(function (header) {\n const chr = genome.getChromosomeName(header.chrNames[seqID]);\n return sequence.getSequence(chr, start - 1, end)\n })\n }\n }\n\n\n /**\n * Parse the sequence dictionary from the SAM header and build chr name tables. This function\n * is public so it can be unit tested.\n *\n * @returns {PromiseLike}\n */\n\n async getHeader() {\n\n if (!this.header) {\n const genome = this.genome;\n const samHeader = await this.cramFile.getSamHeader();\n const chrToIndex = {};\n const chrNames = [];\n const chrAliasTable = {};\n const readGroups = [];\n\n for (let line of samHeader) {\n if ('SQ' === line.tag) {\n for (let d of line.data) {\n if (d.tag === \"SN\") {\n const seq = d.value;\n chrToIndex[seq] = chrNames.length;\n chrNames.push(seq);\n if (genome) {\n const alias = genome.getChromosomeName(seq);\n chrAliasTable[alias] = seq;\n }\n break\n }\n }\n } else if ('RG' === line.tag) {\n readGroups.push(line.data);\n }\n }\n\n this.header = {\n chrNames: chrNames,\n chrToIndex: chrToIndex,\n chrAliasTable: chrAliasTable,\n readGroups: readGroups\n };\n }\n\n return this.header\n }\n\n async readAlignments(chr, bpStart, bpEnd) {\n\n this.browser;\n const header = await this.getHeader();\n const queryChr = header.chrAliasTable.hasOwnProperty(chr) ? header.chrAliasTable[chr] : chr;\n const chrIdx = header.chrToIndex[queryChr];\n const alignmentContainer = new AlignmentContainer(chr, bpStart, bpEnd, this.config);\n\n if (chrIdx === undefined) {\n return alignmentContainer\n\n } else {\n\n try {\n const records = await this.indexedCramFile.getRecordsForRange(chrIdx, bpStart, bpEnd);\n\n for (let record of records) {\n\n const refID = record.sequenceId;\n const pos = record.alignmentStart;\n const alignmentEnd = pos + record.lengthOnRef;\n\n if (refID < 0) {\n continue // unmapped read\n } else if (refID > chrIdx || pos > bpEnd) {\n return // off right edge, we're done\n } else if (refID < chrIdx) {\n continue // Sequence to left of start, not sure this is possible\n }\n if (alignmentEnd < bpStart) {\n continue\n } // Record out-of-range \"to the left\", skip to next one\n\n const alignment = decodeCramRecord(record, header.chrNames);\n\n if (this.filter.pass(alignment)) {\n alignmentContainer.push(alignment);\n }\n }\n\n alignmentContainer.finish();\n return alignmentContainer\n } catch (error) {\n let message = error.message;\n if (message && message.indexOf(\"MD5\") >= 0) {\n message = \"Sequence mismatch. Is this the correct genome for the loaded CRAM?\";\n }\n this.browser.alert.present(new Error(message));\n throw error\n }\n }\n\n function decodeCramRecord(record, chrNames) {\n\n const alignment = new BamAlignment();\n\n alignment.chr = chrNames[record.sequenceId];\n alignment.start = record.alignmentStart - 1;\n alignment.lengthOnRef = record.lengthOnRef;\n alignment.flags = record.flags;\n alignment.strand = !(record.flags & READ_STRAND_FLAG);\n alignment.fragmentLength = record.templateLength || record.templateSize;\n alignment.mq = record.mappingQuality;\n alignment.end = record.alignmentStart + record.lengthOnRef;\n alignment.readGroupId = record.readGroupId;\n\n if (record.mate && record.mate.sequenceId !== undefined) {\n const strand = record.mate.flags !== undefined ?\n !(record.mate.flags & CRAM_MATE_STRAND_FLAG) :\n !(record.flags & MATE_STRAND_FLAG);\n\n alignment.mate = {\n chr: chrNames[record.mate.sequenceId],\n position: record.mate.alignmentStart,\n strand: strand\n };\n }\n\n alignment.seq = record.getReadBases();\n alignment.qual = record.qualityScores;\n alignment.tagDict = record.tags;\n alignment.readName = record.readName;\n\n // TODO -- cigar encoded in tag?\n // BamUtils.bam_tag2cigar(ba, blockEnd, p, lseq, alignment, cigarArray);\n\n makeBlocks(record, alignment);\n\n if (alignment.mate && alignment.start > alignment.mate.position && alignment.fragmentLength > 0) {\n alignment.fragmentLength = -alignment.fragmentLength;\n }\n\n BamUtils.setPairOrientation(alignment);\n\n return alignment\n\n }\n\n function makeBlocks(cramRecord, alignment) {\n\n const blocks = [];\n let insertions;\n let gaps;\n let basesUsed = 0;\n let cigarString = '';\n\n alignment.scStart = alignment.start;\n alignment.scLengthOnRef = alignment.lengthOnRef;\n\n if (cramRecord.readFeatures) {\n\n for (let feature of cramRecord.readFeatures) {\n\n const code = feature.code;\n const data = feature.data;\n const readPos = feature.pos - 1;\n const refPos = feature.refPos - 1;\n\n switch (code) {\n case 'S' :\n case 'I':\n case 'i':\n case 'N':\n case 'D':\n if (readPos > basesUsed) {\n const len = readPos - basesUsed;\n blocks.push(new AlignmentBlock({\n start: refPos - len,\n seqOffset: basesUsed,\n len: len,\n type: 'M'\n }));\n basesUsed += len;\n cigarString += len + 'M';\n }\n\n if ('S' === code) {\n let scPos = refPos;\n alignment.scLengthOnRef += data.length;\n if (readPos === 0) {\n alignment.scStart -= data.length;\n scPos -= data.length;\n }\n const len = data.length;\n blocks.push(new AlignmentBlock({\n start: scPos,\n seqOffset: basesUsed,\n len: len,\n type: 'S'\n }));\n basesUsed += len;\n cigarString += len + code;\n } else if ('I' === code || 'i' === code) {\n if (insertions === undefined) {\n insertions = [];\n }\n const len = 'i' === code ? 1 : data.length;\n insertions.push(new AlignmentBlock({\n start: refPos,\n len: len,\n seqOffset: basesUsed,\n type: 'I'\n }));\n basesUsed += len;\n cigarString += len + code;\n } else if ('D' === code || 'N' === code) {\n if (!gaps) {\n gaps = [];\n }\n gaps.push({\n start: refPos,\n len: data,\n type: code\n });\n cigarString += data + code;\n }\n break\n\n case 'H':\n case 'P':\n cigarString += data + code;\n break\n // Ignore\n }\n }\n }\n\n // Last block\n const len = cramRecord.readLength - basesUsed;\n if (len > 0) {\n blocks.push(new AlignmentBlock({\n start: cramRecord.alignmentStart + cramRecord.lengthOnRef - len - 1,\n seqOffset: basesUsed,\n len: len,\n type: 'M'\n }));\n\n cigarString += len + 'M';\n }\n\n alignment.blocks = blocks;\n alignment.insertions = insertions;\n alignment.gaps = gaps;\n alignment.cigar = cigarString;\n\n }\n\n }\n}\n\nclass FileHandler {\n\n constructor(source, config) {\n this.position = 0;\n this.url = source;\n this.config = config;\n this.cache = new BufferCache({\n fetch: (start, length) => this._fetch(start, length),\n });\n }\n\n async _fetch(position, length) {\n\n const loadRange = {start: position, size: length};\n this._stat = {size: undefined};\n const arrayBuffer = await igvxhr.loadArrayBuffer(this.url, buildOptions(this.config, {range: loadRange}));\n return Buffer.from(arrayBuffer)\n }\n\n async read(buffer, offset = 0, length = Infinity, position = 0) {\n let readPosition = position;\n if (readPosition === null) {\n readPosition = this.position;\n this.position += length;\n }\n return this.cache.get(buffer, offset, length, position)\n }\n\n async readFile() {\n const arrayBuffer = await igvxhr.loadArrayBuffer(this.url, buildOptions(this.config));\n return Buffer.from(arrayBuffer)\n }\n\n async stat() {\n if (!this._stat) {\n const buf = Buffer.allocUnsafe(10);\n await this.read(buf, 0, 10, 0);\n if (!this._stat)\n throw new Error(`unable to determine size of file at ${this.url}`)\n }\n return this._stat\n }\n}\n\nclass BufferCache {\n\n constructor({fetch, size = 10000000, chunkSize = 32768}) {\n\n this.fetch = fetch;\n this.chunkSize = chunkSize;\n this.lruCache = new QuickLRU({maxSize: Math.floor(size / chunkSize)});\n }\n\n async get(outputBuffer, offset, length, position) {\n if (outputBuffer.length < offset + length)\n throw new Error('output buffer not big enough for request')\n\n // calculate the list of chunks involved in this fetch\n const firstChunk = Math.floor(position / this.chunkSize);\n const lastChunk = Math.floor((position + length) / this.chunkSize);\n\n // fetch them all as necessary\n const fetches = new Array(lastChunk - firstChunk + 1);\n for (let chunk = firstChunk; chunk <= lastChunk; chunk += 1) {\n fetches[chunk - firstChunk] = this._getChunk(chunk).then(data => ({\n data,\n chunkNumber: chunk,\n }));\n }\n\n // stitch together the response buffer using them\n const chunks = await Promise.all(fetches);\n const chunksOffset = position - chunks[0].chunkNumber * this.chunkSize;\n chunks.forEach(({data, chunkNumber}) => {\n const chunkPositionStart = chunkNumber * this.chunkSize;\n let copyStart = 0;\n let copyEnd = this.chunkSize;\n let copyOffset =\n offset + (chunkNumber - firstChunk) * this.chunkSize - chunksOffset;\n\n if (chunkNumber === firstChunk) {\n copyOffset = offset;\n copyStart = chunksOffset;\n }\n if (chunkNumber === lastChunk) {\n copyEnd = position + length - chunkPositionStart;\n }\n\n data.copy(outputBuffer, copyOffset, copyStart, copyEnd);\n });\n }\n\n _getChunk(chunkNumber) {\n const cachedPromise = this.lruCache.get(chunkNumber);\n if (cachedPromise) return cachedPromise\n\n const freshPromise = this.fetch(\n chunkNumber * this.chunkSize,\n this.chunkSize,\n );\n this.lruCache.set(chunkNumber, freshPromise);\n return freshPromise\n }\n}\n\nclass QuickLRU {\n constructor(options = {}) {\n if (!(options.maxSize && options.maxSize > 0)) {\n throw new TypeError('`maxSize` must be a number greater than 0')\n }\n\n this.maxSize = options.maxSize;\n this.cache = new Map();\n this.oldCache = new Map();\n this._size = 0;\n }\n\n _set(key, value) {\n this.cache.set(key, value);\n this._size++;\n\n if (this._size >= this.maxSize) {\n this._size = 0;\n this.oldCache = this.cache;\n this.cache = new Map();\n }\n }\n\n get(key) {\n if (this.cache.has(key)) {\n return this.cache.get(key)\n }\n\n if (this.oldCache.has(key)) {\n const value = this.oldCache.get(key);\n this._set(key, value);\n return value\n }\n }\n\n set(key, value) {\n if (this.cache.has(key)) {\n this.cache.set(key, value);\n } else {\n this._set(key, value);\n }\n\n return this\n }\n\n has(key) {\n return this.cache.has(key) || this.oldCache.has(key)\n }\n\n peek(key) {\n if (this.cache.has(key)) {\n return this.cache.get(key)\n }\n\n if (this.oldCache.has(key)) {\n return this.oldCache.get(key)\n }\n }\n\n delete(key) {\n const deleted = this.cache.delete(key);\n if (deleted) {\n this._size--;\n }\n\n return this.oldCache.delete(key) || deleted\n }\n\n clear() {\n this.cache.clear();\n this.oldCache.clear();\n this._size = 0;\n }\n\n * keys() {\n for (const [key] of this) {\n yield key;\n }\n }\n\n * values() {\n for (const [, value] of this) {\n yield value;\n }\n }\n\n * [Symbol.iterator]() {\n for (const item of this.cache) {\n yield item;\n }\n\n for (const item of this.oldCache) {\n const [key] = item;\n if (!this.cache.has(key)) {\n yield item;\n }\n }\n }\n\n get size() {\n let oldCacheSize = 0;\n for (const key of this.oldCache.keys()) {\n if (!this.cache.has(key)) {\n oldCacheSize++;\n }\n }\n\n return this._size + oldCacheSize\n }\n}\n\n/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2014 Broad Institute\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\nvar CigarOperationTable = {\n \"ALIGNMENT_MATCH\": \"M\",\n \"INSERT\": \"I\",\n \"DELETE\": \"D\",\n \"SKIP\": \"N\",\n \"CLIP_SOFT\": \"S\",\n \"CLIP_HARD\": \"H\",\n \"PAD\": \"P\",\n \"SEQUENCE_MATCH\": \"=\",\n \"SEQUENCE_MISMATCH\": \"X\"\n};\n\nconst Ga4ghAlignmentReader = function (config, genome) {\n\n this.config = config;\n this.genome = genome;\n this.url = config.url;\n this.filter = new BamFilter(config.filter);\n this.readGroupSetIds = config.readGroupSetIds;\n this.authKey = config.authKey; // Might be undefined or nill\n\n this.samplingWindowSize = config.samplingWindowSize === undefined ? 100 : config.samplingWindowSize;\n this.samplingDepth = config.samplingDepth === undefined ? 1000 : config.samplingDepth;\n if (config.viewAsPairs) {\n this.pairsSupported = true;\n } else {\n this.pairsSupported = config.pairsSupported === undefined ? true : config.pairsSupported;\n }\n};\n\n\nGa4ghAlignmentReader.prototype.readAlignments = function (chr, bpStart, bpEnd) {\n\n const genome = this.genome;\n const self = this;\n\n return getChrAliasTable()\n\n .then(function (chrAliasTable) {\n\n var queryChr = chrAliasTable.hasOwnProperty(chr) ? chrAliasTable[chr] : chr,\n readURL = self.url + \"/reads/search\";\n\n return ga4ghSearch({\n url: readURL,\n body: {\n \"readGroupSetIds\": [self.readGroupSetIds],\n \"referenceName\": queryChr,\n \"start\": bpStart,\n \"end\": bpEnd,\n \"pageSize\": \"10000\"\n },\n decode: decodeGa4ghReads,\n results: new AlignmentContainer(chr, bpStart, bpEnd, self.config)\n })\n })\n\n\n function getChrAliasTable() {\n\n if (self.chrAliasTable) {\n\n return Promise.resolve(self.chrAliasTable)\n\n } else {\n\n return self.readMetadata()\n\n .then(function (json) {\n\n self.chrAliasTable = {};\n\n if (genome && json.readGroups && json.readGroups.length > 0) {\n\n var referenceSetId = json.readGroups[0].referenceSetId;\n\n if (referenceSetId) {\n\n // Query for reference names to build an alias table (map of genome ref names -> dataset ref names)\n var readURL = self.url + \"/references/search\";\n\n return ga4ghSearch({\n url: readURL,\n body: {\n \"referenceSetId\": referenceSetId\n },\n decode: function (j) {\n return j.references\n }\n })\n .then(function (references) {\n\n\n references.forEach(function (ref) {\n var refName = ref.name,\n alias = genome.getChromosomeName(refName);\n self.chrAliasTable[alias] = refName;\n });\n\n\n return self.chrAliasTable\n\n })\n } else {\n\n // Try hardcoded constants -- workaround for non-compliant data at Google\n populateChrAliasTable(self.chrAliasTable, self.config.datasetId);\n\n return self.chrAliasTable\n }\n } else {\n // No browser object, can't build map. This can occur when run from unit tests\n return self.chrAliasTable\n }\n })\n }\n }\n\n /**\n * Decode an array of ga4gh read records\n *\n\n */\n function decodeGa4ghReads(j) {\n\n var i,\n jsonRecords = j.alignments,\n len = jsonRecords.length,\n alignment,\n jsonAlignment,\n cigarDecoded,\n alignments = [],\n mate,\n blocks;\n\n for (i = 0; i < len; i++) {\n\n let record = jsonRecords[i];\n\n alignment = new BamAlignment();\n\n alignment.readName = record.fragmentName;\n alignment.properPlacement = record.properPlacement;\n alignment.duplicateFragment = record.duplicateFragment;\n alignment.numberReads = record.numberReads;\n alignment.fragmentLength = record.fragmentLength;\n alignment.readNumber = record.readNumber;\n alignment.failedVendorQualityChecks = record.failedVendorQualityChecks;\n alignment.secondaryAlignment = record.secondaryAlignment;\n alignment.supplementaryAlignment = record.supplementaryAlignment;\n alignment.seq = record.alignedSequence;\n alignment.qual = record.alignedQuality;\n alignment.matePos = record.nextMatePosition;\n alignment.tagDict = record.info;\n alignment.flags = encodeFlags();\n\n\n jsonAlignment = record.alignment;\n if (jsonAlignment) {\n alignment.mapped = true;\n\n alignment.chr = record.alignment.position.referenceName;\n if (genome) alignment.chr = genome.getChromosomeName(alignment.chr);\n\n alignment.start = parseInt(record.alignment.position.position);\n alignment.strand = !(record.alignment.position.reverseStrand);\n alignment.mq = record.alignment.mappingQuality;\n alignment.cigar = encodeCigar(record.alignment.cigar);\n cigarDecoded = translateCigar(record.alignment.cigar);\n\n alignment.lengthOnRef = cigarDecoded.lengthOnRef;\n\n blocks = makeBlocks(alignment, cigarDecoded.array);\n alignment.blocks = blocks.blocks;\n alignment.insertions = blocks.insertions;\n\n } else {\n alignment.mapped = false;\n }\n\n mate = record.nextMatePosition;\n if (mate) {\n alignment.mate = {\n chr: mate.referenceFrame,\n position: parseInt(mate.position),\n strand: !mate.reverseStrand\n };\n }\n\n if (self.filter.pass(alignment)) {\n alignments.push(alignment);\n }\n\n\n }\n\n return alignments\n\n\n // Encode a cigar string -- used for popup text\n function encodeCigar(cigarArray) {\n\n var cigarString = \"\";\n cigarArray.forEach(function (cigarUnit) {\n var op = CigarOperationTable[cigarUnit.operation],\n len = cigarUnit.operationLength;\n cigarString = cigarString + (len + op);\n });\n\n return cigarString\n }\n\n // TODO -- implement me\n function encodeFlags(json) {\n return 0\n }\n\n function translateCigar(cigar) {\n\n var cigarUnit, opLen, opLtr,\n lengthOnRef = 0,\n cigarArray = [],\n i;\n\n for (i = 0; i < cigar.length; i++) {\n\n cigarUnit = cigar[i];\n\n opLtr = CigarOperationTable[cigarUnit.operation];\n opLen = parseInt(cigarUnit.operationLength); // Google represents long as a String\n\n if (opLtr === 'M' || opLtr === 'EQ' || opLtr === 'X' || opLtr === 'D' || opLtr === 'N' || opLtr === '=')\n lengthOnRef += opLen;\n\n cigarArray.push({len: opLen, ltr: opLtr});\n\n }\n\n return {lengthOnRef: lengthOnRef, array: cigarArray}\n }\n\n\n /**\n * Split the alignment record into blocks as specified in the cigarArray. Each aligned block contains\n * its portion of the read sequence and base quality strings. A read sequence or base quality string\n * of \"*\" indicates the value is not recorded. In all other cases the length of the block sequence (block.seq)\n * and quality string (block.qual) must == the block length.\n *\n * NOTE: Insertions are not yet treated // TODO\n *\n * @param record\n * @param cigarArray\n * @returns array of blocks\n */\n function makeBlocks(record, cigarArray) {\n\n\n var blocks = [],\n gaps,\n insertions,\n seqOffset = 0,\n pos = record.start,\n len = cigarArray.length,\n gapType;\n\n for (var i = 0; i < len; i++) {\n\n var c = cigarArray[i];\n\n switch (c.ltr) {\n case 'H' :\n break // ignore hard clips\n case 'P' :\n break // ignore pads\n case 'S' :\n seqOffset += c.len;\n gapType = 'S';\n break // soft clip read bases\n case 'N' :\n case 'D' :\n if (gaps === undefined) {\n gaps = [];\n }\n gaps.push({\n start: pos,\n len: c.len,\n type: c.ltr\n });\n pos += c.len;\n break\n case 'I' :\n if (insertions === undefined) insertions = [];\n insertions.push(new AlignmentBlock({\n start: pos,\n len: c.len,\n seqOffset: seqOffset\n }));\n seqOffset += c.len;\n break\n case 'M' :\n case 'EQ' :\n case '=' :\n case 'X' :\n blocks.push(\n new AlignmentBlock({\n start: pos,\n len: c.len,\n seqOffset: seqOffset,\n gapType: gapType\n }));\n seqOffset += c.len;\n pos += c.len;\n\n break\n\n default :\n console.log(\"Error processing cigar element: \" + c.len + c.ltr);\n }\n }\n\n return {blocks: blocks, insertions: insertions, gaps: gaps}\n }\n }\n};\n\n\nGa4ghAlignmentReader.prototype.readMetadata = function () {\n\n return ga4ghGet({\n url: this.url,\n entity: \"readgroupsets\",\n entityId: this.readGroupSetIds\n })\n};\n\n/**\n * Hardcoded hack to work around some non-compliant google datasets\n *\n * @param chrAliasTable\n * @param datasetId\n */\nfunction populateChrAliasTable(chrAliasTable, datasetId) {\n var i;\n if (\"461916304629\" === datasetId || \"337315832689\" === datasetId) {\n for (i = 1; i < 23; i++) {\n chrAliasTable[\"chr\" + i] = i;\n }\n chrAliasTable[\"chrX\"] = \"X\";\n chrAliasTable[\"chrY\"] = \"Y\";\n chrAliasTable[\"chrM\"] = \"MT\";\n }\n}\n\n/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2014 Broad Institute\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\nclass BamSource {\n\n constructor(config, browser) {\n\n const genome = browser.genome;\n\n this.config = config;\n this.genome = genome;\n\n if (isDataURL(config.url)) {\n this.config.indexed = false;\n }\n\n if (\"ga4gh\" === config.sourceType) {\n this.bamReader = new Ga4ghAlignmentReader(config, genome);\n } else if (\"pysam\" === config.sourceType) {\n this.bamReader = new BamWebserviceReader(config, genome);\n } else if (\"htsget\" === config.sourceType) {\n this.bamReader = new HtsgetBamReader(config, genome);\n } else if (\"shardedBam\" === config.sourceType) {\n this.bamReader = new ShardedBamReader(config, genome);\n } else if (\"cram\" === config.format) {\n this.bamReader = new CramReader(config, genome, browser);\n } else {\n if (!this.config.indexURL && config.indexed !== false) {\n if (isString$2(this.config.url)) {\n const inferIndexPath$1 = inferIndexPath(this.config.url, \"bai\");\n if (inferIndexPath$1) {\n console.error(`Warning: no indexURL specified for ${this.config.url}. Guessing ${this.baiPath}`);\n this.config.indexURL = inferIndexPath$1;\n } else {\n console.error(`Warning: no indexURL specified for ${this.config.url}.`);\n this.config.indexed = false;\n }\n } else {\n console.error(`Warning: no indexURL specified for ${this.config.name}.`);\n this.config.indexed = false;\n }\n }\n\n if (this.config.indexed !== false) { // && this.config.indexURL) {\n this.bamReader = new BamReader(config, genome);\n } else {\n this.bamReader = new BamReaderNonIndexed(config, genome);\n }\n }\n\n this.viewAsPairs = config.viewAsPairs;\n this.showSoftClips = config.showSoftClips;\n }\n\n setViewAsPairs(bool) {\n this.viewAsPairs = bool;\n }\n\n setShowSoftClips(bool) {\n this.showSoftClips = bool;\n }\n\n async getAlignments(chr, bpStart, bpEnd) {\n\n const genome = this.genome;\n const showSoftClips = this.showSoftClips;\n\n const alignmentContainer = await this.bamReader.readAlignments(chr, bpStart, bpEnd);\n let alignments = alignmentContainer.alignments;\n if (!this.viewAsPairs) {\n alignments = unpairAlignments([{alignments: alignments}]);\n }\n const hasAlignments = alignments.length > 0;\n alignmentContainer.packedAlignmentRows = packAlignmentRows(alignments, alignmentContainer.start, alignmentContainer.end, showSoftClips);\n\n this.alignmentContainer = alignmentContainer;\n\n if (hasAlignments) {\n const sequence = await genome.sequence.getSequence(chr, alignmentContainer.start, alignmentContainer.end);\n if (sequence) {\n alignmentContainer.coverageMap.refSeq = sequence; // TODO -- fix this\n alignmentContainer.sequence = sequence; // TODO -- fix this\n return alignmentContainer\n } else {\n console.error(\"No sequence for: \" + chr + \":\" + alignmentContainer.start + \"-\" + alignmentContainer.end);\n }\n }\n return alignmentContainer\n\n }\n}\n\nfunction paintAxis(ctx, pixelWidth, pixelHeight) {\n\n var x1,\n x2,\n y1,\n y2,\n a,\n b,\n reference,\n shim,\n font = {\n 'font': 'normal 10px Arial',\n 'textAlign': 'right',\n 'strokeStyle': \"black\"\n };\n\n if (undefined === this.dataRange || undefined === this.dataRange.max || undefined === this.dataRange.min) {\n return\n }\n\n let flipAxis = (undefined === this.flipAxis) ? false : this.flipAxis;\n\n IGVGraphics.fillRect(ctx, 0, 0, pixelWidth, pixelHeight, {'fillStyle': \"rgb(255, 255, 255)\"});\n\n reference = 0.95 * pixelWidth;\n x1 = reference - 8;\n x2 = reference;\n\n //shim = 0.5 * 0.125;\n shim = .01;\n y1 = y2 = shim * pixelHeight;\n\n a = {x: x2, y: y1};\n\n // tick\n IGVGraphics.strokeLine(ctx, x1, y1, x2, y2, font);\n IGVGraphics.fillText(ctx, prettyPrint(flipAxis ? this.dataRange.min : this.dataRange.max), x1 + 4, y1 + 12, font);\n\n //shim = 0.25 * 0.125;\n y1 = y2 = (1.0 - shim) * pixelHeight;\n\n b = {x: x2, y: y1};\n\n // tick\n IGVGraphics.strokeLine(ctx, x1, y1, x2, y2, font);\n IGVGraphics.fillText(ctx, prettyPrint(flipAxis ? this.dataRange.max : this.dataRange.min), x1 + 4, y1 - 4, font);\n\n IGVGraphics.strokeLine(ctx, a.x, a.y, b.x, b.y, font);\n\n function prettyPrint(number) {\n // if number >= 100, show whole number\n // if >= 1 show 1 significant digits\n // if < 1 show 2 significant digits\n\n if (number === 0) {\n return \"0\"\n } else if (Math.abs(number) >= 10) {\n return number.toFixed()\n } else if (Math.abs(number) >= 1) {\n return number.toFixed(1)\n } else {\n return number.toFixed(2)\n }\n }\n}\n\nclass Locus {\n\n constructor({chr, start, end}) {\n this.chr = chr;\n this.start = start;\n this.end = end;\n }\n\n\n contains(locus) {\n return locus.chr === this.chr && locus.start >= this.start && locus.end <= this.end\n }\n\n overlaps(locus) {\n return locus.chr === this.chr && !(locus.end < this.start || locus.start > this.end)\n }\n\n extend(l) {\n if (l.chr !== this.chr) return\n this.start = Math.min(l.start, this.start);\n this.end = Math.max(l.end, this.end);\n }\n\n getLocusString() {\n if ('all' === this.chr) {\n return 'all'\n } else {\n const ss = numberFormatter$1(Math.floor(this.start) + 1);\n const ee = numberFormatter$1(Math.round(this.end));\n return `${this.chr}:${ss}-${ee}`\n }\n }\n\n static fromLocusString(str) {\n if ('all' === str) {\n return new Locus({chr: 'all'})\n }\n const parts = str.split(':');\n const chr = parts[0];\n const se = parts[1].split(\"-\");\n const start = Number.parseInt(se[0].replace(/,/g, \"\")) - 1;\n const end = Number.parseInt(se[1].replace(/,/g, \"\"));\n return new Locus({chr, start, end})\n }\n}\n\n/*!\n * vanilla-picker v2.12.1\n * https://vanilla-picker.js.org\n *\n * Copyright 2017-2021 Andreas Borgen (https://github.com/Sphinxxxx), Adam Brooks (https://github.com/dissimulate)\n * Released under the ISC license.\n */\nvar classCallCheck = function (instance, Constructor) {\n if (!(instance instanceof Constructor)) {\n throw new TypeError(\"Cannot call a class as a function\");\n }\n};\n\nvar createClass = function () {\n function defineProperties(target, props) {\n for (var i = 0; i < props.length; i++) {\n var descriptor = props[i];\n descriptor.enumerable = descriptor.enumerable || false;\n descriptor.configurable = true;\n if (\"value\" in descriptor) descriptor.writable = true;\n Object.defineProperty(target, descriptor.key, descriptor);\n }\n }\n\n return function (Constructor, protoProps, staticProps) {\n if (protoProps) defineProperties(Constructor.prototype, protoProps);\n if (staticProps) defineProperties(Constructor, staticProps);\n return Constructor;\n };\n}();\n\nvar slicedToArray = function () {\n function sliceIterator(arr, i) {\n var _arr = [];\n var _n = true;\n var _d = false;\n var _e = undefined;\n\n try {\n for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) {\n _arr.push(_s.value);\n\n if (i && _arr.length === i) break;\n }\n } catch (err) {\n _d = true;\n _e = err;\n } finally {\n try {\n if (!_n && _i[\"return\"]) _i[\"return\"]();\n } finally {\n if (_d) throw _e;\n }\n }\n\n return _arr;\n }\n\n return function (arr, i) {\n if (Array.isArray(arr)) {\n return arr;\n } else if (Symbol.iterator in Object(arr)) {\n return sliceIterator(arr, i);\n } else {\n throw new TypeError(\"Invalid attempt to destructure non-iterable instance\");\n }\n };\n}();\n\nString.prototype.startsWith = String.prototype.startsWith || function (needle) {\n return this.indexOf(needle) === 0;\n};\nString.prototype.padStart = String.prototype.padStart || function (len, pad) {\n var str = this;while (str.length < len) {\n str = pad + str;\n }return str;\n};\n\nvar colorNames = { cb: '0f8ff', tqw: 'aebd7', q: '-ffff', qmrn: '7fffd4', zr: '0ffff', bg: '5f5dc', bsq: 'e4c4', bck: '---', nch: 'ebcd', b: '--ff', bvt: '8a2be2', brwn: 'a52a2a', brw: 'deb887', ctb: '5f9ea0', hrt: '7fff-', chcT: 'd2691e', cr: '7f50', rnw: '6495ed', crns: '8dc', crms: 'dc143c', cn: '-ffff', Db: '--8b', Dcn: '-8b8b', Dgnr: 'b8860b', Dgr: 'a9a9a9', Dgrn: '-64-', Dkhk: 'bdb76b', Dmgn: '8b-8b', Dvgr: '556b2f', Drng: '8c-', Drch: '9932cc', Dr: '8b--', Dsmn: 'e9967a', Dsgr: '8fbc8f', DsTb: '483d8b', DsTg: '2f4f4f', Dtrq: '-ced1', Dvt: '94-d3', ppnk: '1493', pskb: '-bfff', mgr: '696969', grb: '1e90ff', rbrc: 'b22222', rwht: 'af0', stg: '228b22', chs: '-ff', gnsb: 'dcdcdc', st: '8f8ff', g: 'd7-', gnr: 'daa520', gr: '808080', grn: '-8-0', grnw: 'adff2f', hnw: '0fff0', htpn: '69b4', nnr: 'cd5c5c', ng: '4b-82', vr: '0', khk: '0e68c', vnr: 'e6e6fa', nrb: '0f5', wngr: '7cfc-', mnch: 'acd', Lb: 'add8e6', Lcr: '08080', Lcn: 'e0ffff', Lgnr: 'afad2', Lgr: 'd3d3d3', Lgrn: '90ee90', Lpnk: 'b6c1', Lsmn: 'a07a', Lsgr: '20b2aa', Lskb: '87cefa', LsTg: '778899', Lstb: 'b0c4de', Lw: 'e0', m: '-ff-', mgrn: '32cd32', nn: 'af0e6', mgnt: '-ff', mrn: '8--0', mqm: '66cdaa', mmb: '--cd', mmrc: 'ba55d3', mmpr: '9370db', msg: '3cb371', mmsT: '7b68ee', '': '-fa9a', mtr: '48d1cc', mmvt: 'c71585', mnLb: '191970', ntc: '5fffa', mstr: 'e4e1', mccs: 'e4b5', vjw: 'dead', nv: '--80', c: 'df5e6', v: '808-0', vrb: '6b8e23', rng: 'a5-', rngr: '45-', rch: 'da70d6', pgnr: 'eee8aa', pgrn: '98fb98', ptrq: 'afeeee', pvtr: 'db7093', ppwh: 'efd5', pchp: 'dab9', pr: 'cd853f', pnk: 'c0cb', pm: 'dda0dd', pwrb: 'b0e0e6', prp: '8-080', cc: '663399', r: '--', sbr: 'bc8f8f', rb: '4169e1', sbrw: '8b4513', smn: 'a8072', nbr: '4a460', sgrn: '2e8b57', ssh: '5ee', snn: 'a0522d', svr: 'c0c0c0', skb: '87ceeb', sTb: '6a5acd', sTgr: '708090', snw: 'afa', n: '-ff7f', stb: '4682b4', tn: 'd2b48c', t: '-8080', thst: 'd8bfd8', tmT: '6347', trqs: '40e0d0', vt: 'ee82ee', whT: '5deb3', wht: '', hts: '5f5f5', w: '-', wgrn: '9acd32' };\n\nfunction printNum(num) {\n var decs = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1;\n\n var str = decs > 0 ? num.toFixed(decs).replace(/0+$/, '').replace(/\\.$/, '') : num.toString();\n return str || '0';\n}\n\nvar Color = function () {\n function Color(r, g, b, a) {\n classCallCheck(this, Color);\n\n\n var that = this;\n function parseString(input) {\n\n if (input.startsWith('hsl')) {\n var _input$match$map = input.match(/([\\-\\d\\.e]+)/g).map(Number),\n _input$match$map2 = slicedToArray(_input$match$map, 4),\n h = _input$match$map2[0],\n s = _input$match$map2[1],\n l = _input$match$map2[2],\n _a = _input$match$map2[3];\n\n if (_a === undefined) {\n _a = 1;\n }\n\n h /= 360;\n s /= 100;\n l /= 100;\n that.hsla = [h, s, l, _a];\n } else if (input.startsWith('rgb')) {\n var _input$match$map3 = input.match(/([\\-\\d\\.e]+)/g).map(Number),\n _input$match$map4 = slicedToArray(_input$match$map3, 4),\n _r = _input$match$map4[0],\n _g = _input$match$map4[1],\n _b = _input$match$map4[2],\n _a2 = _input$match$map4[3];\n\n if (_a2 === undefined) {\n _a2 = 1;\n }\n\n that.rgba = [_r, _g, _b, _a2];\n } else {\n if (input.startsWith('#')) {\n that.rgba = Color.hexToRgb(input);\n } else {\n that.rgba = Color.nameToRgb(input) || Color.hexToRgb(input);\n }\n }\n }\n\n if (r === undefined) ; else if (Array.isArray(r)) {\n this.rgba = r;\n } else if (b === undefined) {\n var color = r && '' + r;\n if (color) {\n parseString(color.toLowerCase());\n }\n } else {\n this.rgba = [r, g, b, a === undefined ? 1 : a];\n }\n }\n\n createClass(Color, [{\n key: 'printRGB',\n value: function printRGB(alpha) {\n var rgb = alpha ? this.rgba : this.rgba.slice(0, 3),\n vals = rgb.map(function (x, i) {\n return printNum(x, i === 3 ? 3 : 0);\n });\n\n return alpha ? 'rgba(' + vals + ')' : 'rgb(' + vals + ')';\n }\n }, {\n key: 'printHSL',\n value: function printHSL(alpha) {\n var mults = [360, 100, 100, 1],\n suff = ['', '%', '%', ''];\n\n var hsl = alpha ? this.hsla : this.hsla.slice(0, 3),\n vals = hsl.map(function (x, i) {\n return printNum(x * mults[i], i === 3 ? 3 : 1) + suff[i];\n });\n\n return alpha ? 'hsla(' + vals + ')' : 'hsl(' + vals + ')';\n }\n }, {\n key: 'printHex',\n value: function printHex(alpha) {\n var hex = this.hex;\n return alpha ? hex : hex.substring(0, 7);\n }\n }, {\n key: 'rgba',\n get: function get() {\n if (this._rgba) {\n return this._rgba;\n }\n if (!this._hsla) {\n throw new Error('No color is set');\n }\n\n return this._rgba = Color.hslToRgb(this._hsla);\n },\n set: function set(rgb) {\n if (rgb.length === 3) {\n rgb[3] = 1;\n }\n\n this._rgba = rgb;\n this._hsla = null;\n }\n }, {\n key: 'rgbString',\n get: function get() {\n return this.printRGB();\n }\n }, {\n key: 'rgbaString',\n get: function get() {\n return this.printRGB(true);\n }\n }, {\n key: 'hsla',\n get: function get() {\n if (this._hsla) {\n return this._hsla;\n }\n if (!this._rgba) {\n throw new Error('No color is set');\n }\n\n return this._hsla = Color.rgbToHsl(this._rgba);\n },\n set: function set(hsl) {\n if (hsl.length === 3) {\n hsl[3] = 1;\n }\n\n this._hsla = hsl;\n this._rgba = null;\n }\n }, {\n key: 'hslString',\n get: function get() {\n return this.printHSL();\n }\n }, {\n key: 'hslaString',\n get: function get() {\n return this.printHSL(true);\n }\n }, {\n key: 'hex',\n get: function get() {\n var rgb = this.rgba,\n hex = rgb.map(function (x, i) {\n return i < 3 ? x.toString(16) : Math.round(x * 255).toString(16);\n });\n\n return '#' + hex.map(function (x) {\n return x.padStart(2, '0');\n }).join('');\n },\n set: function set(hex) {\n this.rgba = Color.hexToRgb(hex);\n }\n }], [{\n key: 'hexToRgb',\n value: function hexToRgb(input) {\n\n var hex = (input.startsWith('#') ? input.slice(1) : input).replace(/^(\\w{3})$/, '$1F').replace(/^(\\w)(\\w)(\\w)(\\w)$/, '$1$1$2$2$3$3$4$4').replace(/^(\\w{6})$/, '$1FF');\n\n if (!hex.match(/^([0-9a-fA-F]{8})$/)) {\n throw new Error('Unknown hex color; ' + input);\n }\n\n var rgba = hex.match(/^(\\w\\w)(\\w\\w)(\\w\\w)(\\w\\w)$/).slice(1).map(function (x) {\n return parseInt(x, 16);\n });\n\n rgba[3] = rgba[3] / 255;\n return rgba;\n }\n }, {\n key: 'nameToRgb',\n value: function nameToRgb(input) {\n\n var hash = input.toLowerCase().replace('at', 'T').replace(/[aeiouyldf]/g, '').replace('ght', 'L').replace('rk', 'D').slice(-5, 4),\n hex = colorNames[hash];\n return hex === undefined ? hex : Color.hexToRgb(hex.replace(/\\-/g, '00').padStart(6, 'f'));\n }\n }, {\n key: 'rgbToHsl',\n value: function rgbToHsl(_ref) {\n var _ref2 = slicedToArray(_ref, 4),\n r = _ref2[0],\n g = _ref2[1],\n b = _ref2[2],\n a = _ref2[3];\n\n r /= 255;\n g /= 255;\n b /= 255;\n\n var max = Math.max(r, g, b),\n min = Math.min(r, g, b);\n var h = void 0,\n s = void 0,\n l = (max + min) / 2;\n\n if (max === min) {\n h = s = 0;\n } else {\n var d = max - min;\n s = l > 0.5 ? d / (2 - max - min) : d / (max + min);\n switch (max) {\n case r:\n h = (g - b) / d + (g < b ? 6 : 0);break;\n case g:\n h = (b - r) / d + 2;break;\n case b:\n h = (r - g) / d + 4;break;\n }\n\n h /= 6;\n }\n\n return [h, s, l, a];\n }\n }, {\n key: 'hslToRgb',\n value: function hslToRgb(_ref3) {\n var _ref4 = slicedToArray(_ref3, 4),\n h = _ref4[0],\n s = _ref4[1],\n l = _ref4[2],\n a = _ref4[3];\n\n var r = void 0,\n g = void 0,\n b = void 0;\n\n if (s === 0) {\n r = g = b = l;\n } else {\n var hue2rgb = function hue2rgb(p, q, t) {\n if (t < 0) t += 1;\n if (t > 1) t -= 1;\n if (t < 1 / 6) return p + (q - p) * 6 * t;\n if (t < 1 / 2) return q;\n if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;\n return p;\n };\n\n var q = l < 0.5 ? l * (1 + s) : l + s - l * s,\n p = 2 * l - q;\n\n r = hue2rgb(p, q, h + 1 / 3);\n g = hue2rgb(p, q, h);\n b = hue2rgb(p, q, h - 1 / 3);\n }\n\n var rgba = [r * 255, g * 255, b * 255].map(Math.round);\n rgba[3] = a;\n\n return rgba;\n }\n }]);\n return Color;\n}();\n\nvar EventBucket = function () {\n function EventBucket() {\n classCallCheck(this, EventBucket);\n\n this._events = [];\n }\n\n createClass(EventBucket, [{\n key: 'add',\n value: function add(target, type, handler) {\n target.addEventListener(type, handler, false);\n this._events.push({\n target: target,\n type: type,\n handler: handler\n });\n }\n }, {\n key: 'remove',\n value: function remove(target, type, handler) {\n this._events = this._events.filter(function (e) {\n var isMatch = true;\n if (target && target !== e.target) {\n isMatch = false;\n }\n if (type && type !== e.type) {\n isMatch = false;\n }\n if (handler && handler !== e.handler) {\n isMatch = false;\n }\n\n if (isMatch) {\n EventBucket._doRemove(e.target, e.type, e.handler);\n }\n return !isMatch;\n });\n }\n }, {\n key: 'destroy',\n value: function destroy() {\n this._events.forEach(function (e) {\n return EventBucket._doRemove(e.target, e.type, e.handler);\n });\n this._events = [];\n }\n }], [{\n key: '_doRemove',\n value: function _doRemove(target, type, handler) {\n target.removeEventListener(type, handler, false);\n }\n }]);\n return EventBucket;\n}();\n\nfunction parseHTML(htmlString) {\n\n var div = document.createElement('div');\n div.innerHTML = htmlString;\n return div.firstElementChild;\n}\n\nfunction dragTrack(eventBucket, area, callback) {\n var dragging = false;\n\n function clamp(val, min, max) {\n return Math.max(min, Math.min(val, max));\n }\n\n function onMove(e, info, starting) {\n if (starting) {\n dragging = true;\n }\n if (!dragging) {\n return;\n }\n\n e.preventDefault();\n\n var bounds = area.getBoundingClientRect(),\n w = bounds.width,\n h = bounds.height,\n x = info.clientX,\n y = info.clientY;\n\n var relX = clamp(x - bounds.left, 0, w),\n relY = clamp(y - bounds.top, 0, h);\n\n callback(relX / w, relY / h);\n }\n\n function onMouse(e, starting) {\n var button = e.buttons === undefined ? e.which : e.buttons;\n if (button === 1) {\n onMove(e, e, starting);\n } else {\n dragging = false;\n }\n }\n\n function onTouch(e, starting) {\n if (e.touches.length === 1) {\n onMove(e, e.touches[0], starting);\n } else {\n dragging = false;\n }\n }\n\n eventBucket.add(area, 'mousedown', function (e) {\n onMouse(e, true);\n });\n eventBucket.add(area, 'touchstart', function (e) {\n onTouch(e, true);\n });\n eventBucket.add(window, 'mousemove', onMouse);\n eventBucket.add(area, 'touchmove', onTouch);\n eventBucket.add(window, 'mouseup', function (e) {\n dragging = false;\n });\n eventBucket.add(area, 'touchend', function (e) {\n dragging = false;\n });\n eventBucket.add(area, 'touchcancel', function (e) {\n dragging = false;\n });\n}\n\nvar BG_TRANSP = 'linear-gradient(45deg, lightgrey 25%, transparent 25%, transparent 75%, lightgrey 75%) 0 0 / 2em 2em,\\n linear-gradient(45deg, lightgrey 25%, white 25%, white 75%, lightgrey 75%) 1em 1em / 2em 2em';\nvar HUES = 360;\n\nvar EVENT_KEY = 'keydown',\n EVENT_CLICK_OUTSIDE = 'mousedown',\n EVENT_TAB_MOVE = 'focusin';\n\nfunction $(selector, context) {\n return (context || document).querySelector(selector);\n}\n\nfunction stopEvent(e) {\n\n e.preventDefault();\n e.stopPropagation();\n}\nfunction onKey(bucket, target, keys, handler, stop) {\n bucket.add(target, EVENT_KEY, function (e) {\n if (keys.indexOf(e.key) >= 0) {\n if (stop) {\n stopEvent(e);\n }\n handler(e);\n }\n });\n}\n\nvar Picker = function () {\n function Picker(options) {\n classCallCheck(this, Picker);\n\n\n this.settings = {\n\n popup: 'right',\n layout: 'default',\n alpha: true,\n editor: true,\n editorFormat: 'hex',\n cancelButton: false,\n defaultColor: '#0cf'\n };\n\n this._events = new EventBucket();\n\n this.onChange = null;\n\n this.onDone = null;\n\n this.onOpen = null;\n\n this.onClose = null;\n\n this.setOptions(options);\n }\n\n createClass(Picker, [{\n key: 'setOptions',\n value: function setOptions(options) {\n var _this = this;\n\n if (!options) {\n return;\n }\n var settings = this.settings;\n\n function transfer(source, target, skipKeys) {\n for (var key in source) {\n if (skipKeys && skipKeys.indexOf(key) >= 0) {\n continue;\n }\n\n target[key] = source[key];\n }\n }\n\n if (options instanceof HTMLElement) {\n settings.parent = options;\n } else {\n\n if (settings.parent && options.parent && settings.parent !== options.parent) {\n this._events.remove(settings.parent);\n this._popupInited = false;\n }\n\n transfer(options, settings);\n\n if (options.onChange) {\n this.onChange = options.onChange;\n }\n if (options.onDone) {\n this.onDone = options.onDone;\n }\n if (options.onOpen) {\n this.onOpen = options.onOpen;\n }\n if (options.onClose) {\n this.onClose = options.onClose;\n }\n\n var col = options.color || options.colour;\n if (col) {\n this._setColor(col);\n }\n }\n\n var parent = settings.parent;\n if (parent && settings.popup && !this._popupInited) {\n\n var openProxy = function openProxy(e) {\n return _this.openHandler(e);\n };\n\n this._events.add(parent, 'click', openProxy);\n\n onKey(this._events, parent, [' ', 'Spacebar', 'Enter'], openProxy);\n\n this._popupInited = true;\n } else if (options.parent && !settings.popup) {\n this.show();\n }\n }\n }, {\n key: 'openHandler',\n value: function openHandler(e) {\n if (this.show()) {\n\n e && e.preventDefault();\n\n this.settings.parent.style.pointerEvents = 'none';\n\n var toFocus = e && e.type === EVENT_KEY ? this._domEdit : this.domElement;\n setTimeout(function () {\n return toFocus.focus();\n }, 100);\n\n if (this.onOpen) {\n this.onOpen(this.colour);\n }\n }\n }\n }, {\n key: 'closeHandler',\n value: function closeHandler(e) {\n var event = e && e.type;\n var doHide = false;\n\n if (!e) {\n doHide = true;\n } else if (event === EVENT_CLICK_OUTSIDE || event === EVENT_TAB_MOVE) {\n\n var knownTime = (this.__containedEvent || 0) + 100;\n if (e.timeStamp > knownTime) {\n doHide = true;\n }\n } else {\n\n stopEvent(e);\n\n doHide = true;\n }\n\n if (doHide && this.hide()) {\n this.settings.parent.style.pointerEvents = '';\n\n if (event !== EVENT_CLICK_OUTSIDE) {\n this.settings.parent.focus();\n }\n\n if (this.onClose) {\n this.onClose(this.colour);\n }\n }\n }\n }, {\n key: 'movePopup',\n value: function movePopup(options, open) {\n\n this.closeHandler();\n\n this.setOptions(options);\n if (open) {\n this.openHandler();\n }\n }\n }, {\n key: 'setColor',\n value: function setColor(color, silent) {\n this._setColor(color, { silent: silent });\n }\n }, {\n key: '_setColor',\n value: function _setColor(color, flags) {\n if (typeof color === 'string') {\n color = color.trim();\n }\n if (!color) {\n return;\n }\n\n flags = flags || {};\n var c = void 0;\n try {\n\n c = new Color(color);\n } catch (ex) {\n if (flags.failSilently) {\n return;\n }\n throw ex;\n }\n\n if (!this.settings.alpha) {\n var hsla = c.hsla;\n hsla[3] = 1;\n c.hsla = hsla;\n }\n this.colour = this.color = c;\n this._setHSLA(null, null, null, null, flags);\n }\n }, {\n key: 'setColour',\n value: function setColour(colour, silent) {\n this.setColor(colour, silent);\n }\n }, {\n key: 'show',\n value: function show() {\n var parent = this.settings.parent;\n if (!parent) {\n return false;\n }\n\n if (this.domElement) {\n var toggled = this._toggleDOM(true);\n\n this._setPosition();\n\n return toggled;\n }\n\n var html = this.settings.template || '
';\n var wrapper = parseHTML(html);\n\n this.domElement = wrapper;\n this._domH = $('.picker_hue', wrapper);\n this._domSL = $('.picker_sl', wrapper);\n this._domA = $('.picker_alpha', wrapper);\n this._domEdit = $('.picker_editor input', wrapper);\n this._domSample = $('.picker_sample', wrapper);\n this._domOkay = $('.picker_done button', wrapper);\n this._domCancel = $('.picker_cancel button', wrapper);\n\n wrapper.classList.add('layout_' + this.settings.layout);\n if (!this.settings.alpha) {\n wrapper.classList.add('no_alpha');\n }\n if (!this.settings.editor) {\n wrapper.classList.add('no_editor');\n }\n if (!this.settings.cancelButton) {\n wrapper.classList.add('no_cancel');\n }\n this._ifPopup(function () {\n return wrapper.classList.add('popup');\n });\n\n this._setPosition();\n\n if (this.colour) {\n this._updateUI();\n } else {\n this._setColor(this.settings.defaultColor);\n }\n this._bindEvents();\n\n return true;\n }\n }, {\n key: 'hide',\n value: function hide() {\n return this._toggleDOM(false);\n }\n }, {\n key: 'destroy',\n value: function destroy() {\n this._events.destroy();\n if (this.domElement) {\n this.settings.parent.removeChild(this.domElement);\n }\n }\n }, {\n key: '_bindEvents',\n value: function _bindEvents() {\n var _this2 = this;\n\n var that = this,\n dom = this.domElement,\n events = this._events;\n\n function addEvent(target, type, handler) {\n events.add(target, type, handler);\n }\n\n addEvent(dom, 'click', function (e) {\n return e.preventDefault();\n });\n\n dragTrack(events, this._domH, function (x, y) {\n return that._setHSLA(x);\n });\n\n dragTrack(events, this._domSL, function (x, y) {\n return that._setHSLA(null, x, 1 - y);\n });\n\n if (this.settings.alpha) {\n dragTrack(events, this._domA, function (x, y) {\n return that._setHSLA(null, null, null, 1 - y);\n });\n }\n\n var editInput = this._domEdit;\n {\n addEvent(editInput, 'input', function (e) {\n that._setColor(this.value, { fromEditor: true, failSilently: true });\n });\n\n addEvent(editInput, 'focus', function (e) {\n var input = this;\n\n if (input.selectionStart === input.selectionEnd) {\n input.select();\n }\n });\n }\n\n this._ifPopup(function () {\n\n var popupCloseProxy = function popupCloseProxy(e) {\n return _this2.closeHandler(e);\n };\n\n addEvent(window, EVENT_CLICK_OUTSIDE, popupCloseProxy);\n addEvent(window, EVENT_TAB_MOVE, popupCloseProxy);\n onKey(events, dom, ['Esc', 'Escape'], popupCloseProxy);\n\n var timeKeeper = function timeKeeper(e) {\n _this2.__containedEvent = e.timeStamp;\n };\n addEvent(dom, EVENT_CLICK_OUTSIDE, timeKeeper);\n\n addEvent(dom, EVENT_TAB_MOVE, timeKeeper);\n\n addEvent(_this2._domCancel, 'click', popupCloseProxy);\n });\n\n var onDoneProxy = function onDoneProxy(e) {\n _this2._ifPopup(function () {\n return _this2.closeHandler(e);\n });\n if (_this2.onDone) {\n _this2.onDone(_this2.colour);\n }\n };\n addEvent(this._domOkay, 'click', onDoneProxy);\n onKey(events, dom, ['Enter'], onDoneProxy);\n }\n }, {\n key: '_setPosition',\n value: function _setPosition() {\n var parent = this.settings.parent,\n elm = this.domElement;\n\n if (parent !== elm.parentNode) {\n parent.appendChild(elm);\n }\n\n this._ifPopup(function (popup) {\n\n if (getComputedStyle(parent).position === 'static') {\n parent.style.position = 'relative';\n }\n\n var cssClass = popup === true ? 'popup_right' : 'popup_' + popup;\n\n ['popup_top', 'popup_bottom', 'popup_left', 'popup_right'].forEach(function (c) {\n\n if (c === cssClass) {\n elm.classList.add(c);\n } else {\n elm.classList.remove(c);\n }\n });\n\n elm.classList.add(cssClass);\n });\n }\n }, {\n key: '_setHSLA',\n value: function _setHSLA(h, s, l, a, flags) {\n flags = flags || {};\n\n var col = this.colour,\n hsla = col.hsla;\n\n [h, s, l, a].forEach(function (x, i) {\n if (x || x === 0) {\n hsla[i] = x;\n }\n });\n col.hsla = hsla;\n\n this._updateUI(flags);\n\n if (this.onChange && !flags.silent) {\n this.onChange(col);\n }\n }\n }, {\n key: '_updateUI',\n value: function _updateUI(flags) {\n if (!this.domElement) {\n return;\n }\n flags = flags || {};\n\n var col = this.colour,\n hsl = col.hsla,\n cssHue = 'hsl(' + hsl[0] * HUES + ', 100%, 50%)',\n cssHSL = col.hslString,\n cssHSLA = col.hslaString;\n\n var uiH = this._domH,\n uiSL = this._domSL,\n uiA = this._domA,\n thumbH = $('.picker_selector', uiH),\n thumbSL = $('.picker_selector', uiSL),\n thumbA = $('.picker_selector', uiA);\n\n function posX(parent, child, relX) {\n child.style.left = relX * 100 + '%';\n }\n function posY(parent, child, relY) {\n child.style.top = relY * 100 + '%';\n }\n\n posX(uiH, thumbH, hsl[0]);\n\n this._domSL.style.backgroundColor = this._domH.style.color = cssHue;\n\n posX(uiSL, thumbSL, hsl[1]);\n posY(uiSL, thumbSL, 1 - hsl[2]);\n\n uiSL.style.color = cssHSL;\n\n posY(uiA, thumbA, 1 - hsl[3]);\n\n var opaque = cssHSL,\n transp = opaque.replace('hsl', 'hsla').replace(')', ', 0)'),\n bg = 'linear-gradient(' + [opaque, transp] + ')';\n\n this._domA.style.background = bg + ', ' + BG_TRANSP;\n\n if (!flags.fromEditor) {\n var format = this.settings.editorFormat,\n alpha = this.settings.alpha;\n\n var value = void 0;\n switch (format) {\n case 'rgb':\n value = col.printRGB(alpha);break;\n case 'hsl':\n value = col.printHSL(alpha);break;\n default:\n value = col.printHex(alpha);\n }\n this._domEdit.value = value;\n }\n\n this._domSample.style.color = cssHSLA;\n }\n }, {\n key: '_ifPopup',\n value: function _ifPopup(actionIf, actionElse) {\n if (this.settings.parent && this.settings.popup) {\n actionIf && actionIf(this.settings.popup);\n } else {\n actionElse && actionElse();\n }\n }\n }, {\n key: '_toggleDOM',\n value: function _toggleDOM(toVisible) {\n var dom = this.domElement;\n if (!dom) {\n return false;\n }\n\n var displayStyle = toVisible ? '' : 'none',\n toggle = dom.style.display !== displayStyle;\n\n if (toggle) {\n dom.style.display = displayStyle;\n }\n return toggle;\n }\n }]);\n return Picker;\n}();\n\n{\n var style = document.createElement('style');\n style.textContent = '.picker_wrapper.no_alpha .picker_alpha{display:none}.picker_wrapper.no_editor .picker_editor{position:absolute;z-index:-1;opacity:0}.picker_wrapper.no_cancel .picker_cancel{display:none}.layout_default.picker_wrapper{display:flex;flex-flow:row wrap;justify-content:space-between;align-items:stretch;font-size:10px;width:25em;padding:.5em}.layout_default.picker_wrapper input,.layout_default.picker_wrapper button{font-size:1rem}.layout_default.picker_wrapper>*{margin:.5em}.layout_default.picker_wrapper::before{content:\"\";display:block;width:100%;height:0;order:1}.layout_default .picker_slider,.layout_default .picker_selector{padding:1em}.layout_default .picker_hue{width:100%}.layout_default .picker_sl{flex:1 1 auto}.layout_default .picker_sl::before{content:\"\";display:block;padding-bottom:100%}.layout_default .picker_editor{order:1;width:6.5rem}.layout_default .picker_editor input{width:100%;height:100%}.layout_default .picker_sample{order:1;flex:1 1 auto}.layout_default .picker_done,.layout_default .picker_cancel{order:1}.picker_wrapper{box-sizing:border-box;background:#f2f2f2;box-shadow:0 0 0 1px silver;cursor:default;font-family:sans-serif;color:#444;pointer-events:auto}.picker_wrapper:focus{outline:none}.picker_wrapper button,.picker_wrapper input{box-sizing:border-box;border:none;box-shadow:0 0 0 1px silver;outline:none}.picker_wrapper button:focus,.picker_wrapper button:active,.picker_wrapper input:focus,.picker_wrapper input:active{box-shadow:0 0 2px 1px #1e90ff}.picker_wrapper button{padding:.4em .6em;cursor:pointer;background-color:#f5f5f5;background-image:linear-gradient(0deg, gainsboro, transparent)}.picker_wrapper button:active{background-image:linear-gradient(0deg, transparent, gainsboro)}.picker_wrapper button:hover{background-color:#fff}.picker_selector{position:absolute;z-index:1;display:block;-webkit-transform:translate(-50%, -50%);transform:translate(-50%, -50%);border:2px solid #fff;border-radius:100%;box-shadow:0 0 3px 1px #67b9ff;background:currentColor;cursor:pointer}.picker_slider .picker_selector{border-radius:2px}.picker_hue{position:relative;background-image:linear-gradient(90deg, red, yellow, lime, cyan, blue, magenta, red);box-shadow:0 0 0 1px silver}.picker_sl{position:relative;box-shadow:0 0 0 1px silver;background-image:linear-gradient(180deg, white, rgba(255, 255, 255, 0) 50%),linear-gradient(0deg, black, rgba(0, 0, 0, 0) 50%),linear-gradient(90deg, #808080, rgba(128, 128, 128, 0))}.picker_alpha,.picker_sample{position:relative;background:linear-gradient(45deg, lightgrey 25%, transparent 25%, transparent 75%, lightgrey 75%) 0 0/2em 2em,linear-gradient(45deg, lightgrey 25%, white 25%, white 75%, lightgrey 75%) 1em 1em/2em 2em;box-shadow:0 0 0 1px silver}.picker_alpha .picker_selector,.picker_sample .picker_selector{background:none}.picker_editor input{font-family:monospace;padding:.2em .4em}.picker_sample::before{content:\"\";position:absolute;display:block;width:100%;height:100%;background:currentColor}.picker_arrow{position:absolute;z-index:-1}.picker_wrapper.popup{position:absolute;z-index:2;margin:1.5em}.picker_wrapper.popup,.picker_wrapper.popup .picker_arrow::before,.picker_wrapper.popup .picker_arrow::after{background:#f2f2f2;box-shadow:0 0 10px 1px rgba(0,0,0,.4)}.picker_wrapper.popup .picker_arrow{width:3em;height:3em;margin:0}.picker_wrapper.popup .picker_arrow::before,.picker_wrapper.popup .picker_arrow::after{content:\"\";display:block;position:absolute;top:0;left:0;z-index:-99}.picker_wrapper.popup .picker_arrow::before{width:100%;height:100%;-webkit-transform:skew(45deg);transform:skew(45deg);-webkit-transform-origin:0 100%;transform-origin:0 100%}.picker_wrapper.popup .picker_arrow::after{width:150%;height:150%;box-shadow:none}.popup.popup_top{bottom:100%;left:0}.popup.popup_top .picker_arrow{bottom:0;left:0;-webkit-transform:rotate(-90deg);transform:rotate(-90deg)}.popup.popup_bottom{top:100%;left:0}.popup.popup_bottom .picker_arrow{top:0;left:0;-webkit-transform:rotate(90deg) scale(1, -1);transform:rotate(90deg) scale(1, -1)}.popup.popup_left{top:0;right:100%}.popup.popup_left .picker_arrow{top:0;right:0;-webkit-transform:scale(-1, 1);transform:scale(-1, 1)}.popup.popup_right{top:0;left:100%}.popup.popup_right .picker_arrow{top:0;left:0}';\n document.documentElement.firstElementChild.appendChild(style);\n\n Picker.StyleElement = style;\n}\n\nfunction getChrColor$1(chr) {\n if (chrColorMap$1[chr]) {\n return chrColorMap$1[chr];\n } else if (chrColorMap$1[\"chr\" + chr]) {\n const color = chrColorMap$1[\"chr\" + chr];\n chrColorMap$1[chr] = color;\n return color;\n } else {\n const color = randomRGB();\n chrColorMap$1[chr] = color;\n return color;\n }\n}\n\nfunction randomRGB (min, max) {\n\n var r = Math.round(Math.random() * 255).toString(10);\n var g = Math.round(Math.random() * 255).toString(10);\n var b = Math.round(Math.random() * 255).toString(10);\n return \"rgb(\" + r + \",\" + g + \",\" + b + \")\";\n}\n\nconst chrColorMap$1 = {\n \"chrX\": \"rgb(204, 153, 0)\",\n \"chrY\": \"rgb(153, 204, 0\",\n \"chrUn\": \"rgb(50, 50, 50)\",\n \"chr1\": \"rgb(80, 80, 255)\",\n \"chrI\": \"rgb(139, 155, 187)\",\n \"chr2\": \"rgb(206, 61, 50)\",\n \"chrII\": \"rgb(206, 61, 50)\",\n \"chr2a\": \"rgb(216, 71, 60)\",\n \"chr2b\": \"rgb(226, 81, 70)\",\n \"chr3\": \"rgb(116, 155, 88)\",\n \"chrIII\": \"rgb(116, 155, 88)\",\n \"chr4\": \"rgb(240, 230, 133)\",\n \"chrIV\": \"rgb(240, 230, 133)\",\n \"chr5\": \"rgb(70, 105, 131)\",\n \"chr6\": \"rgb(186, 99, 56)\",\n \"chr7\": \"rgb(93, 177, 221)\",\n \"chr8\": \"rgb(128, 34, 104)\",\n \"chr9\": \"rgb(107, 215, 107)\",\n \"chr10\": \"rgb(213, 149, 167)\",\n \"chr11\": \"rgb(146, 72, 34)\",\n \"chr12\": \"rgb(131, 123, 141)\",\n \"chr13\": \"rgb(199, 81, 39)\",\n \"chr14\": \"rgb(213, 143, 92)\",\n \"chr15\": \"rgb(122, 101, 165)\",\n \"chr16\": \"rgb(228, 175, 105)\",\n \"chr17\": \"rgb(59, 27, 83)\",\n \"chr18\": \"rgb(205, 222, 183)\",\n \"chr19\": \"rgb(97, 42, 121)\",\n \"chr20\": \"rgb(174, 31, 99)\",\n \"chr21\": \"rgb(231, 199, 111)\",\n \"chr22\": \"rgb(90, 101, 94)\",\n \"chr23\": \"rgb(204, 153, 0)\",\n \"chr24\": \"rgb(153, 204, 0)\",\n \"chr25\": \"rgb(51, 204, 0)\",\n \"chr26\": \"rgb(0, 204, 51)\",\n \"chr27\": \"rgb(0, 204, 153)\",\n \"chr28\": \"rgb(0, 153, 204)\",\n \"chr29\": \"rgb(10, 71, 255)\",\n \"chr30\": \"rgb(71, 117, 255)\",\n \"chr31\": \"rgb(255, 194, 10)\",\n \"chr32\": \"rgb(255, 209, 71)\",\n \"chr33\": \"rgb(153, 0, 51)\",\n \"chr34\": \"rgb(153, 26, 0)\",\n \"chr35\": \"rgb(153, 102, 0)\",\n \"chr36\": \"rgb(128, 153, 0)\",\n \"chr37\": \"rgb(51, 153, 0)\",\n \"chr38\": \"rgb(0, 153, 26)\",\n \"chr39\": \"rgb(0, 153, 102)\",\n \"chr40\": \"rgb(0, 128, 153)\",\n \"chr41\": \"rgb(0, 51, 153)\",\n \"chr42\": \"rgb(26, 0, 153)\",\n \"chr43\": \"rgb(102, 0, 153)\",\n \"chr44\": \"rgb(153, 0, 128)\",\n \"chr45\": \"rgb(214, 0, 71)\",\n \"chr46\": \"rgb(255, 20, 99)\",\n \"chr47\": \"rgb(0, 214, 143)\",\n \"chr48\": \"rgb(20, 255, 177)\",\n};\n\nclass ChordSetManager {\n\n constructor(config) {\n this.tracks = [];\n this.chordSets = [];\n }\n\n addChordSet(chordSet) {\n\n // If a chord set with this name exists replace it (same track, same region)\n this.chordSets = this.chordSets.filter(g => g.name !== chordSet.name);\n this.chordSets.push(chordSet);\n\n let track = this.tracks.find(t => chordSet.trackName === t.name);\n if (track) {\n track.chordSets = track.chordSets.filter(cs => cs.name !== chordSet.name);\n track.chordSets.push(chordSet);\n }\n if (!track) {\n track = new IGVTrack(chordSet);\n this.tracks.push(track);\n }\n }\n\n clearChords() {\n this.tracks = [];\n this.chordSets = [];\n }\n\n getTrack(name) {\n return this.tracks.find(t => name === t.name)\n }\n\n getChordSet(name) {\n return this.chordSets.find(cs => name === cs.name)\n }\n\n}\n\nclass IGVTrack {\n constructor(chordSet) {\n this.name = chordSet.trackName;\n this.color = chordSet.trackColor;\n this.visible = true;\n this.chordSets = [chordSet];\n this.id = guid$1();\n }\n\n get chords() {\n if (this.chordSets.length === 1) {\n return this.chordSets[0].chords\n }\n const chords = [];\n for (let cs of this.chordSets) {\n for (let c of cs.chords) {\n chords.push(c);\n }\n }\n return chords\n }\n}\n\n\nfunction guid$1() {\n return (\"0000\" + (Math.random() * Math.pow(36, 4) << 0).toString(36)).slice(-4)\n}\n\nconst EXP5 = Math.exp(5);\n\nclass CircularView {\n\n static isInstalled() {\n return window[\"JBrowseReactCircularGenomeView\"] !== undefined && window[\"React\"] !== undefined && window[\"ReactDOM\"] !== undefined\n }\n\n /**\n * Create a new CircularView\n *\n * @param parent\n * @param config - configuration options\n * {\n * assembly: {name: string, id: string, chromosomes: [{name: string, bpLength: integer, color: string}]\n * onChordClick: function called upon chord click with chord feature as argument\n * }\n */\n constructor(parent, config) {\n\n config = config || {};\n this.config = config;\n\n if (CircularView.isInstalled()) {\n\n this.parent = parent;\n this.groupByTrack = config.groupByTrack === true;\n this.chordManager = new ChordSetManager(config);\n\n // wrapper for toolbar and circular-view container\n const wrapper = document.createElement('div');\n wrapper.className = 'igv-circview-container';\n parent.appendChild(wrapper);\n\n // toolbar\n this.createControls(wrapper);\n this.resetControlPanel();\n\n // circular view container\n const element = document.createElement('div');\n element.className = 'igv-circview-circular-genome-view';\n wrapper.appendChild(element);\n this.container = element;\n\n if (config.assembly) {\n this.setAssembly(config.assembly);\n }\n\n this.width = config.width || 500;\n this.height = config.height || 500;\n this.setSize(this.width, this.height);\n\n } else {\n console.error(\"JBrowse circular view is not installed\");\n }\n }\n\n createControls(parent) {\n\n // toolbar\n const toolbarDiv = document.createElement('div');\n toolbarDiv.className = 'igv-circview-toolbar';\n parent.appendChild(toolbarDiv);\n this.toolbar = toolbarDiv;\n\n // control panel\n const controlPanelDiv = document.createElement('div');\n controlPanelDiv.className = 'igv-circview-track-panel';\n parent.appendChild(controlPanelDiv);\n this.controlPanel = controlPanelDiv;\n this.controlPanel.style.display = 'none';\n\n\n // toolbar button container - Track Options - Clear All\n const buttonContainer = document.createElement('div');\n buttonContainer.className = 'igv-circview-toolbar-button-container';\n this.toolbar.appendChild(buttonContainer);\n\n // Show Controls\n this.showControlsButton = document.createElement('div');\n this.showControlsButton.className = 'igv-circview-button';\n buttonContainer.appendChild(this.showControlsButton);\n this.showControlsButton.innerText = 'none' === this.controlPanel.style.display ? 'Show Controls' : 'Hide Controls';\n this.showControlsButton.addEventListener('click', (event) => {\n const panelRows = this.controlPanel.querySelectorAll('div');\n if (panelRows.length > 0) {\n if ('none' === this.controlPanel.style.display) {\n this.controlPanel.style.display = 'flex';\n event.target.innerText = 'Hide Controls';\n } else {\n this.controlPanel.style.display = 'none';\n event.target.innerText = 'Show Controls';\n }\n }\n });\n\n // Clear All\n let button = document.createElement('div');\n button.className = 'igv-circview-button';\n buttonContainer.appendChild(button);\n button.innerText = 'Clear All';\n button.addEventListener('click', () => {\n this.clearChords();\n });\n\n // Close\n if (false !== this.config.showCloseButton) {\n button = document.createElement('div');\n button.className = 'igv-circview-button';\n buttonContainer.appendChild(button);\n button.innerText = 'Close';\n button.addEventListener('click', () => {\n this.visible = false;\n });\n }\n }\n\n resetControlPanel() {\n this.controlPanel.innerHTML = '';\n this.controlPanel.appendChild(this.createGroupByCB());\n const chordSets = this.groupByTrack ? this.chordManager.tracks : this.chordManager.chordSets;\n for(let cs of chordSets) {\n this.addToControlPanel(cs);\n }\n }\n\n createGroupByCB() {\n const groupByCB = document.createElement('input');\n groupByCB.type = 'checkbox';\n groupByCB.id = 'groupByCB';\n groupByCB.style.width = '1.4em';\n groupByCB.style.height = '1.4em';\n groupByCB.checked = this.groupByTrack;\n\n groupByCB.onclick = (evt) => {\n this.groupByTrack = evt.target.checked;\n this.resetControlPanel();\n this.render();\n };\n\n const groupByLabel = document.createElement('label');\n groupByLabel.for = 'groupByCB';\n groupByLabel.innerText = 'Group by track';\n groupByLabel.style.color = 'black';\n groupByLabel.style.paddingLeft = '10px';\n const trackPanelRow = document.createElement('div');\n trackPanelRow.style.width = '100%';\n trackPanelRow.style.paddingTop = '5px';\n trackPanelRow.style.paddingBottom = '5px';\n trackPanelRow.style.background = 'rgb(216, 230, 234)';\n trackPanelRow.appendChild(groupByCB);\n trackPanelRow.appendChild(groupByLabel);\n return trackPanelRow\n }\n\n addToControlPanel(chordSet) {\n\n // single track row - container for hide-button | color-picker-swatch | track-name\n const row = document.createElement('div');\n this.controlPanel.appendChild(row);\n\n\n // track hide|show\n const hideShowButton = document.createElement('div');\n hideShowButton.className = 'igv-circview-button';\n row.appendChild(hideShowButton);\n hideShowButton.innerText = true === chordSet.visible ? 'Hide' : 'Show';\n hideShowButton.addEventListener('click', event => {\n if (true === chordSet.visible) {\n this.hideChordSet(chordSet.name);\n event.target.innerText = \"Show\";\n } else {\n this.showChordSet(chordSet.name);\n event.target.innerText = \"Hide\";\n }\n });\n\n // The alpha range slider. Create this here so we can reference it from the color picker\n const alphaSlider = document.createElement('input');\n const valueToAlpha = (value) => Math.exp(value / 200) / EXP5;\n const alphaToValue = (alpha) => 200 * Math.log(alpha * EXP5);\n\n // color\n const colorPickerButton = document.createElement('div');\n colorPickerButton.className = 'igv-circview-button';\n colorPickerButton.innerHTML = '    '; // <- important for button to size properly\n row.appendChild(colorPickerButton);\n colorPickerButton.style.backgroundColor = setAlpha(chordSet.color, 1);\n const pickerConfig =\n {\n parent: colorPickerButton,\n popup: 'right',\n editorFormat: 'rgb',\n color: chordSet.color,\n onChange: ({rgbaString}) => {\n colorPickerButton.style.backgroundColor = setAlpha(rgbaString, 1);\n this.setColor(chordSet.name, rgbaString);\n alphaSlider.value = alphaToValue(getAlpha(chordSet.color));\n }\n };\n const picker = new Picker(pickerConfig);\n\n // alpha transparency\n alphaSlider.setAttribute('title', 'Adjust transparency of arcs');\n alphaSlider.type = 'range';\n //alphaSlider.className = 'igv-circview-alpha-slider'\n alphaSlider.style.width = '100px';\n alphaSlider.style.marginRight = '10px';\n alphaSlider.setAttribute('class', 'range');\n alphaSlider.setAttribute('min', '0');\n alphaSlider.setAttribute('max', '1000');\n alphaSlider.value = alphaToValue(getAlpha(chordSet.color));\n alphaSlider.oninput = () => {\n const v = valueToAlpha(alphaSlider.value);\n this.setColor(chordSet.name, setAlpha(chordSet.color, v));\n picker.setColor(chordSet.color);\n };\n row.appendChild(alphaSlider);\n\n // track name\n const trackNameDive = document.createElement('div');\n trackNameDive.style.color = 'black';\n row.appendChild(trackNameDive);\n trackNameDive.innerText = trackNameDive.title = chordSet.name;\n\n }\n\n /**\n * Reset view with a new set of chromosomes.\n *\n * @param igvGenome {name: string, id: string, chromosomes: [{name: string, bpLength: integer, color: string}\n */\n setAssembly(igvGenome) {\n\n const id = this.genomeId || guid();\n\n if (this.genomeId === id) {\n return\n }\n this.chordManager.clearChords();\n this.genomeId = id;\n this.chrNames = new Set(igvGenome.chromosomes.map(chr => shortChrName$1(chr.name)));\n\n const regions = [];\n const colors = [];\n for (let chr of igvGenome.chromosomes) {\n const shortName = shortChrName$1(chr.name);\n colors.push(chr.color || getChrColor$1(shortName));\n regions.push(\n {\n refName: shortName,\n uniqueId: shortName,\n start: 0,\n end: chr.bpLength\n }\n );\n }\n\n this.assembly = {\n name: igvGenome.name,\n sequence: {\n trackId: id,\n type: 'ReferenceSequenceTrack',\n adapter: {\n type: 'FromConfigSequenceAdapter',\n features: regions,\n },\n },\n refNameColors: colors\n };\n\n this.render();\n\n }\n\n /**\n * Append or replace current set of chords to the global set or a specific track.\n *\n * @param newChords array of chord feature objects. Example:\n * [\n * {\n * \"uniqueId\": \"chr1:129763372-129763376_chr1:129806775-129806790\",\n * \"color\": \"rgba(0, 0, 255, 0.1)\",\n * \"refName\": \"1\",\n * \"start\": 129763372,\n * \"end\": 129763376,\n * \"mate\": {\n * \"refName\": \"2\",\n * \"start\": 129806775,\n * \"end\": 129806790\n * }\n * }\n * ]\n * @param options {\n * name: string, // Track name\n * color: string, // Track color\n * append: boolean // Replace or append chords to current set. Default is append (true)\n * }\n */\n\n addChords(newChords, options = {}) {\n\n const tmp = options.name || options.track || \"*\";\n const trackName = tmp.split(' ')[0].replaceAll(\"%20\", \" \");\n const chordSetName = tmp.replaceAll(\"%20\", \" \");\n\n const chordSet = {\n name: chordSetName,\n trackName: trackName,\n chords: newChords,\n color: options.color || \"black\",\n trackColor: options.trackColor || options.color || \"black\",\n visible: true,\n id: options.id || guid()\n };\n\n this.chordManager.addChordSet(chordSet);\n\n this.resetControlPanel();\n\n this.render();\n }\n\n /**\n * Set the nominal size of the view in pixels. Size is reduced some aribtrary amount to account for borders and margins\n */\n setSize(width, height) {\n\n height = height || width;\n\n this.width = width;\n this.height = height;\n if (this.viewState) {\n const view = this.viewState.session.view;\n view.setWidth(width);\n view.setHeight(height /* this is the height of the area inside the border in pixels */);\n view.setBpPerPx(view.minBpPerPx);\n }\n }\n\n getSize() {\n return Math.min(this.width, this.height)\n }\n\n clearChords() {\n //this.tracks = []\n this.chordManager.clearChords();\n this.resetControlPanel();\n this.render();\n }\n\n clearSelection() {\n this.viewState.pluginManager.rootModel.session.clearSelection();\n }\n\n /**\n * Deprecated, use \"visible\" property\n */\n show() {\n this.parent.style.display = 'block';\n }\n\n /**\n * Deprecated, use \"visible\" property\n */\n hide() {\n this.parent.style.display = 'none';\n }\n\n get visible() {\n return this.parent.style.display !== 'none'\n }\n\n set visible(isVisible) {\n this.parent.style.display = isVisible ? 'block' : 'none';\n }\n\n hideChordSet(trackName) {\n let cs = this.getChordSet(trackName);\n if (cs) {\n cs.visible = false;\n this.render();\n } else {\n console.warn(`No track with name: ${name}`);\n }\n }\n\n showChordSet(name) {\n let cs = this.getChordSet(name);\n if (cs) {\n cs.visible = true;\n this.render();\n } else {\n console.warn(`No track with name: ${name}`);\n }\n }\n\n // showTrack(trackID) {\n // let idx = this.tracks.findIndex(t => trackID === t.id)\n // if (idx >= 0) {\n // const track = this.tracks[idx]\n // track.visible = true\n // this.tracks.splice(idx, 1) // Change z-order\n // this.tracks.push(track)\n // this.render()\n // } else {\n // console.warn(`No track with name: ${name}`)\n // }\n // }\n\n // TODO -- remove corresponding row from track panel\n deleteTrack(trackID) {\n let idx = this.tracks.findIndex(t => trackID === t.name);\n if (idx >= 0) {\n this.tracks.splice(idx, 1);\n }\n this.render();\n }\n\n getChordSet(name) {\n return this.groupByTrack ? this.chordManager.getTrack(name) : this.chordManager.getChordSet(name)\n }\n\n setColor(name, color) {\n const t = this.getChordSet(name);\n if (t) {\n t.color = color;\n const trackID = t.id;\n for (let jbrowseTrack of this.viewState.config.tracks) {\n if (trackID === jbrowseTrack.trackId) {\n jbrowseTrack.displays[0].renderer.strokeColor.set(color);\n break\n }\n }\n }\n }\n\n /**\n * The main render function. Render here means build the React DOM. Trying to change react state dynamically\n * has been buggy, so we completely rebuild the DOM (\"render\") on any state change.\n */\n render() {\n\n const {\n createViewState,\n JBrowseCircularGenomeView,\n } = JBrowseReactCircularGenomeView;\n\n // Remove all children from possible previous renders. React might do this for us when we render, but just in case.\n ReactDOM.unmountComponentAtNode(this.container);\n\n const visibleChordSets =\n (this.groupByTrack ? this.chordManager.tracks : this.chordManager.chordSets).filter(t => t.visible);\n\n const jbrowseTracks = [];\n const colors = [];\n\n for (let chordSet of visibleChordSets) {\n\n jbrowseTracks.push({\n trackId: chordSet.id,\n name: chordSet.name,\n assemblyNames: ['forIGV'],\n type: 'VariantTrack',\n adapter: {\n type: 'FromConfigAdapter',\n features: chordSet.chords,\n }\n });\n colors.push(chordSet.color);\n }\n\n this.viewState = createViewState({\n assembly: this.assembly,\n tracks: jbrowseTracks,\n });\n\n // Set view colors\n for (let i = 0; i < visibleChordSets.length; i++) {\n this.viewState.config.tracks[i].displays[0].renderer.strokeColor.set(colors[i]);\n //this.viewState.config.tracks[i].displays[0].renderer.strokeColor.set(\"jexl:get(feature, 'color') || 'black'\");\n //this.viewState.config.tracks[i].displays[0].renderer.strokeColorSelected.set(\"jexl:get(feature, 'highlightColor') || 'red'\");\n }\n\n this.element = React.createElement(JBrowseCircularGenomeView, {viewState: this.viewState});\n this.setSize(this.width, this.height);\n\n ReactDOM.render(this.element, this.container);\n\n const onChordClick = this.config.onChordClick || defaultOnChordClick;\n for (let i = 0; i < visibleChordSets.length; i++) {\n this.viewState.session.view.showTrack(this.viewState.config.tracks[i].trackId);\n if (onChordClick) {\n this.viewState.pluginManager.jexl.addFunction('onChordClick', onChordClick);\n this.viewState.config.tracks[i].displays[0].onChordClick.set(\n 'jexl:onChordClick(feature, track, pluginManager)'\n );\n }\n }\n }\n}\n\nfunction setAlpha(rgba, alpha) {\n const [a, b, c, ignore] = rgba.split(','); // rgba(r g b alpha)\n return `${a},${b},${c},${alpha})`\n}\n\nfunction getAlpha(rgba) {\n if (rgba.startsWith(\"rgba(\")) {\n return Number(rgba.split(',')[3].replace(')', ''))\n } else {\n return 1\n }\n}\n\nfunction shortChrName$1(chrName) {\n return chrName.startsWith(\"chr\") ? chrName.substring(3) : chrName\n}\n\nfunction defaultOnChordClick(feature, chordTrack, pluginManager) {\n console.log(feature);\n}\n\nfunction guid() {\n return (\"0000\" + (Math.random() * Math.pow(36, 4) << 0).toString(36)).slice(-4)\n}\n\nfunction embedCSS$1() {\n\n const css = '.igv-circview-container {\\n width: fit-content;\\n height: fit-content;\\n box-sizing: content-box;\\n color: dimgray;\\n font-family: \\\"Open Sans\\\", sans-serif;\\n font-size: 12px;\\n background-color: white;\\n border-color: dimgray;\\n border-style: solid;\\n border-width: thin;\\n display: flex;\\n flex-direction: column;\\n flex-wrap: nowrap;\\n justify-content: flex-start;\\n align-items: flex-start;\\n}\\n\\n.igv-circview-toolbar {\\n position: relative;\\n width: 100%;\\n height: 32px;\\n background-color: lightgrey;\\n border-bottom-style: solid;\\n border-bottom-color: dimgray;\\n border-bottom-width: thin;\\n display: flex;\\n flex-flow: row;\\n flex-wrap: nowrap;\\n justify-content: space-between;\\n align-items: center;\\n}\\n\\n.igv-circview-toolbar-button-container {\\n height: 100%;\\n width: fit-content;\\n display: flex;\\n flex-flow: row;\\n flex-wrap: nowrap;\\n justify-content: flex-start;\\n align-items: center;\\n}\\n.igv-circview-toolbar-button-container > div {\\n margin: 4px;\\n}\\n\\n.igv-circview-track-panel {\\n z-index: 1024;\\n position: absolute;\\n top: 33px;\\n left: 0;\\n width: 100%;\\n height: fit-content;\\n border-bottom-style: solid;\\n border-bottom-color: dimgray;\\n border-bottom-width: thin;\\n background-color: white;\\n display: flex;\\n flex-flow: column;\\n flex-wrap: nowrap;\\n justify-content: flex-start;\\n align-items: flex-start;\\n}\\n.igv-circview-track-panel > div {\\n display: flex;\\n flex-flow: row;\\n flex-wrap: nowrap;\\n justify-content: flex-start;\\n align-items: center;\\n}\\n.igv-circview-track-panel > div > div {\\n margin: 4px;\\n}\\n\\n.igv-circview-swatch-button {\\n cursor: pointer;\\n padding: 5px;\\n width: 8px;\\n height: 8px;\\n border: 1px solid #8d8b8b;\\n border-radius: 16px;\\n}\\n\\n.igv-circview-button {\\n cursor: pointer;\\n padding: 5px;\\n color: #444;\\n vertical-align: middle;\\n text-align: center;\\n font-family: \\\"Open Sans\\\", sans-serif;\\n font-size: 12px;\\n border: 1px solid #8d8b8b;\\n border-radius: 4px;\\n background: #efefef;\\n box-shadow: 0 0 5px -1px rgba(0, 0, 0, 0.2);\\n}\\n\\n.igv-circview-button:hover {\\n background: #efefef;\\n box-shadow: 0 0 5px -1px rgba(0, 0, 0, 0.6);\\n}\\n\\n.igv-circview-button:active {\\n color: #007bff;\\n box-shadow: 0 0 5px -1px rgba(0, 0, 0, 0.6);\\n}\\n\\n/*# sourceMappingURL=circular-view.css.map */\\n';\n\n const style = document.createElement('style');\n style.setAttribute('type', 'text/css');\n style.innerHTML = css;\n document.head.insertBefore(style, document.head.childNodes[ document.head.childNodes.length - 1 ]);\n}\n\nif(typeof document !== 'undefined') {\n\n if (!stylesheetExists(\"circular-view.css\")) {\n embedCSS$1();\n }\n\n function stylesheetExists(stylesheetName) {\n for (let ss of document.styleSheets) {\n ss = ss.href ? ss.href.replace(/^.*[\\\\\\/]/, '') : '';\n if (ss === stylesheetName) {\n return true;\n }\n }\n return false;\n }\n}\n\n/**\n * The minimum length for a VCF structural variant. VCF records < this length are ignored in the circular view\n * @type {number}\n */\nconst MINIMUM_SV_LENGTH = 1000000;\n\nconst shortChrName = (chrName) => {\n return chrName.startsWith(\"chr\") ? chrName.substring(3) : chrName\n};\n\nconst makePairedAlignmentChords = (alignments) => {\n\n const chords = [];\n for (let a of alignments) {\n\n if(a.paired) {\n if(a.firstAlignment && a.secondAlignment) {\n chords.push({\n uniqueId: a.readName,\n refName: shortChrName(a.firstAlignment.chr),\n start: a.firstAlignment.start,\n end: a.firstAlignment.end,\n mate: {\n refName: shortChrName(a.secondAlignment.chr),\n start: a.secondAlignment.start,\n end: a.secondAlignment.end,\n }\n });\n }\n }\n else {\n const mate = a.mate;\n if (mate && mate.chr && mate.position) {\n chords.push({\n uniqueId: a.readName,\n refName: shortChrName(a.chr),\n start: a.start,\n end: a.end,\n mate: {\n refName: shortChrName(mate.chr),\n start: mate.position - 1,\n end: mate.position,\n }\n });\n }\n }\n }\n return chords\n};\n\nconst makeSupplementalAlignmentChords = (alignments) => {\n\n const makeChords = (a) => {\n const sa = a.tags()['SA'];\n const supAl = createSupplementaryAlignments(sa);\n let n = 0;\n for (let s of supAl) {\n if (s.start !== a.start) {\n chords.push({\n uniqueId: `${a.readName}_${n++}`,\n refName: shortChrName(a.chr),\n start: a.start,\n end: a.end,\n mate: {\n refName: shortChrName(s.chr),\n start: s.start,\n end: s.start + s.lenOnRef\n }\n });\n }\n }\n };\n\n const chords = [];\n for (let a of alignments) {\n if(a.paired) {\n makeChords(a.firstAlignment);\n if(a.secondAlignment) {\n makeChords(a.secondAlignment);\n }\n } else {\n makeChords(a);\n }\n }\n return chords\n};\n\nconst makeBedPEChords = (features) => {\n\n return features.map(v => {\n\n // If v is a whole-genome feature, get the true underlying variant.\n const f = v._f || v;\n\n return {\n uniqueId: `${f.chr1}:${f.start1}-${f.end1}_${f.chr2}:${f.start2}-${f.end2}`,\n refName: shortChrName(f.chr1),\n start: f.start1,\n end: f.end1,\n mate: {\n refName: shortChrName(f.chr2),\n start: f.start2,\n end: f.end2,\n }\n }\n })\n};\n\n\nconst makeVCFChords = (features) => {\n\n const svFeatures = features.filter(v => {\n const f = v._f || v;\n const isLargeEnough = f.info && f.info.CHR2 && f.info.END &&\n (f.info.CHR2 !== f.chr || Math.abs(Number.parseInt(f.info.END) - f.pos) > MINIMUM_SV_LENGTH);\n return isLargeEnough\n });\n return svFeatures.map(v => {\n\n // If v is a whole-genome feature, get the true underlying variant.\n const f = v._f || v;\n\n const pos2 = Number.parseInt(f.info.END);\n const start2 = pos2 - 100;\n const end2 = pos2 + 100;\n\n return {\n uniqueId: `${f.chr}:${f.start}-${f.end}_${f.info.CHR2}:${f.info.END}`,\n refName: shortChrName(f.chr),\n start: f.start,\n end: f.end,\n mate: {\n refName: shortChrName(f.info.CHR2),\n start: start2,\n end: end2\n }\n }\n })\n};\n\nfunction makeCircViewChromosomes(genome) {\n const regions = [];\n const colors = [];\n for (let chrName of genome.wgChromosomeNames) {\n const chr = genome.getChromosome(chrName);\n colors.push(getChrColor(chr.name));\n regions.push(\n {\n name: chr.name,\n bpLength: chr.bpLength\n }\n );\n }\n return regions\n}\n\nfunction sendChords(chords, track, refFrame, alpha) {\n\n const baseColor = track.color || 'rgb(0,0,255)';\n\n const chordSetColor = IGVColor.addAlpha(\"all\" === refFrame.chr ? baseColor : getChrColor(refFrame.chr), alpha);\n const trackColor = IGVColor.addAlpha(baseColor, alpha);\n\n // name the chord set to include locus and filtering information\n const encodedName = track.name.replaceAll(' ', '%20');\n const chordSetName = \"all\" === refFrame.chr ? encodedName :\n `${encodedName} ${refFrame.chr}:${refFrame.start}-${refFrame.end}`;\n track.browser.circularView.addChords(chords, {track: chordSetName, color: chordSetColor, trackColor: trackColor});\n\n // show circular view if hidden\n if(!track.browser.circularViewVisible) track.browser.circularViewVisible = true;\n\n}\n\n\nfunction createCircularView(el, browser) {\n\n const circularView = new CircularView(el, {\n\n onChordClick: (feature, chordTrack, pluginManager) => {\n\n const f1 = feature.data;\n const f2 = f1.mate;\n addFrameForFeature(f1);\n addFrameForFeature(f2);\n\n function addFrameForFeature(feature) {\n\n feature.chr = browser.genome.getChromosomeName(feature.refName);\n let frameFound = false;\n for (let referenceFrame of browser.referenceFrameList) {\n const l = Locus.fromLocusString(referenceFrame.getLocusString());\n if (l.contains(feature)) {\n frameFound = true;\n break\n } else if (l.overlaps(feature)) {\n referenceFrame.extend(feature);\n frameFound = true;\n break\n }\n }\n if (!frameFound) {\n const flanking = 2000;\n const center = (feature.start + feature.end) / 2;\n browser.addMultiLocusPanel(feature.chr, center - flanking, center + flanking);\n\n }\n }\n }\n });\n\n return circularView\n}\n\nclass PairedEndStats {\n\n constructor(alignments, {minTLENPercentile, maxTLENPercentile}) {\n this.totalCount = 0;\n this.frCount = 0;\n this.rfCount = 0;\n this.ffCount = 0;\n this.sumF = 0;\n this.sumF2 = 0;\n this.lp = minTLENPercentile === undefined ? 0.1 : minTLENPercentile;\n this.up = maxTLENPercentile === undefined ? 99.5 : maxTLENPercentile;\n this.isizes = [];\n this.compute(alignments);\n }\n\n compute(alignments) {\n\n for (let alignment of alignments) {\n if (alignment.isProperPair()) {\n var tlen = Math.abs(alignment.fragmentLength);\n this.sumF += tlen;\n this.sumF2 += tlen * tlen;\n this.isizes.push(tlen);\n\n var po = alignment.pairOrientation;\n\n if (typeof po === \"string\" && po.length === 4) {\n var tmp = '' + po.charAt(0) + po.charAt(2);\n switch (tmp) {\n case 'FF':\n case 'RR':\n this.ffCount++;\n break\n case \"FR\":\n this.frCount++;\n break\n case\"RF\":\n this.rfCount++;\n }\n }\n this.totalCount++;\n }\n }\n\n if (this.ffCount / this.totalCount > 0.9) this.orienation = \"ff\";\n else if (this.frCount / this.totalCount > 0.9) this.orienation = \"fr\";\n else if (this.rfCount / this.totalCount > 0.9) this.orienation = \"rf\";\n\n this.minTLEN = this.lp === 0 ? 0 : percentile(this.isizes, this.lp);\n this.maxTLEN = percentile(this.isizes, this.up);\n\n // var fMean = this.sumF / this.totalCount\n // var stdDev = Math.sqrt((this.totalCount * this.sumF2 - this.sumF * this.sumF) / (this.totalCount * this.totalCount))\n // this.minTLEN = fMean - 3 * stdDev\n // this.maxTLEN = fMean + 3 * stdDev\n\n }\n}\n\nfunction percentile(array, p) {\n\n if (array.length === 0) return undefined\n var k = Math.floor(array.length * (p / 100));\n array.sort(function (a, b) {\n return a - b\n });\n return array[k]\n\n}\n\nconst GtexUtils = {\n\n getTissueInfo: function (datasetId, baseURL) {\n datasetId = datasetId || 'gtex_v8';\n baseURL = baseURL || 'https://gtexportal.org/rest/v1';\n let url = baseURL + '/dataset/tissueInfo?datasetId=' + datasetId;\n return igvxhr.loadJson(url, {})\n },\n\n //https://gtexportal.org/rest/v1/association/singleTissueEqtlByLocation?chromosome=7&start=98358766&end=101523798&tissueName=Liver&datasetId=gtex_v7\n //https://gtexportal.org/rest/v1/association/singleTissueEqtlByLocation?chromosome=7&start=98358766&end=101523798&tissueSiteDetailId=Liver&datasetId=gtex_v8\n trackConfiguration: function (tissueSummary, baseURL) {\n baseURL = baseURL || 'https://gtexportal.org/rest/v1';\n return {\n type: \"eqtl\",\n sourceType: \"gtex-ws\",\n url: baseURL + '/association/singleTissueEqtlByLocation',\n tissueSiteDetailId: tissueSummary.tissueSiteDetailId,\n name: (tissueSummary.tissueSiteDetailId.split('_').join(' ')),\n visibilityWindow: 250000\n }\n }\n};\n\n/**\n * @param feature\n * @param bpStart genomic location of the left edge of the current canvas\n * @param xScale scale in base-pairs per pixel\n * @returns {{px: number, px1: number, pw: number, h: number, py: number}}\n */\nfunction calculateFeatureCoordinates(feature, bpStart, xScale) {\n let px = (feature.start - bpStart) / xScale;\n let px1 = (feature.end - bpStart) / xScale;\n //px = Math.round((feature.start - bpStart) / xScale),\n //px1 = Math.round((feature.end - bpStart) / xScale),\n let pw = px1 - px;\n\n if (pw < 3) {\n pw = 3;\n px -= 1.5;\n }\n\n return {\n px: px,\n px1: px1,\n pw: pw\n }\n}\n\n/**\n *\n * @param feature\n * @param bpStart genomic location of the left edge of the current canvas\n * @param xScale scale in base-pairs per pixel\n * @param pixelHeight pixel height of the current canvas\n * @param ctx the canvas 2d context\n * @param options genomic state\n */\nfunction renderFeature(feature, bpStart, xScale, pixelHeight, ctx, options) {\n\n try {\n ctx.save();\n\n // Set ctx color to a known valid color. If getColorForFeature returns an invalid color string it is ignored, and\n // this default will be used.\n ctx.fillStyle = this.color;\n ctx.strokeStyle = this.color;\n\n const color = this.getColorForFeature(feature);\n ctx.fillStyle = color;\n ctx.strokeStyle = color;\n\n let h;\n let py;\n if (this.displayMode === \"SQUISHED\" && feature.row !== undefined) {\n h = this.featureHeight / 2;\n py = this.margin + this.squishedRowHeight * feature.row;\n } else if (this.displayMode === \"EXPANDED\" && feature.row !== undefined) {\n h = this.featureHeight;\n py = this.margin + this.expandedRowHeight * feature.row;\n } else { // collapsed\n h = this.featureHeight;\n py = this.margin;\n }\n\n const pixelWidth = options.pixelWidth; // typical 3*viewportWidth\n\n const cy = py + h / 2;\n const h2 = h / 2;\n const py2 = cy - h2 / 2;\n\n const exonCount = feature.exons ? feature.exons.length : 0;\n const coord = calculateFeatureCoordinates(feature, bpStart, xScale);\n const step = this.arrowSpacing;\n const direction = feature.strand === '+' ? 1 : feature.strand === '-' ? -1 : 0;\n\n if (exonCount === 0) {\n // single-exon transcript\n const xLeft = Math.max(0, coord.px);\n const xRight = Math.min(pixelWidth, coord.px1);\n const width = xRight - xLeft;\n ctx.fillRect(xLeft, py, width, h);\n\n // Arrows\n // Do not draw if strand is not +/-\n if (direction !== 0) {\n ctx.fillStyle = \"white\";\n ctx.strokeStyle = \"white\";\n for (let x = xLeft + step / 2; x < xRight; x += step) {\n // draw arrowheads along central line indicating transcribed orientation\n IGVGraphics.strokeLine(ctx, x - direction * 2, cy - 2, x, cy);\n IGVGraphics.strokeLine(ctx, x - direction * 2, cy + 2, x, cy);\n }\n ctx.fillStyle = color;\n ctx.strokeStyle = color;\n }\n } else {\n // multi-exon transcript\n IGVGraphics.strokeLine(ctx, coord.px + 1, cy, coord.px1 - 1, cy); // center line for introns\n\n\n const xLeft = Math.max(0, coord.px) + step / 2;\n const xRight = Math.min(pixelWidth, coord.px1);\n for (let x = xLeft; x < xRight; x += step) {\n // draw arrowheads along central line indicating transcribed orientation\n IGVGraphics.strokeLine(ctx, x - direction * 2, cy - 2, x, cy);\n IGVGraphics.strokeLine(ctx, x - direction * 2, cy + 2, x, cy);\n }\n for (let e = 0; e < exonCount; e++) {\n // draw the exons\n const exon = feature.exons[e];\n let ePx = Math.round((exon.start - bpStart) / xScale);\n let ePx1 = Math.round((exon.end - bpStart) / xScale);\n let ePw = Math.max(1, ePx1 - ePx);\n let ePxU;\n\n if (ePx + ePw < 0) {\n continue // Off the left edge\n }\n if (ePx > pixelWidth) {\n break // Off the right edge\n }\n\n if (exon.utr) {\n ctx.fillRect(ePx, py2, ePw, h2); // Entire exon is UTR\n } else {\n if (exon.cdStart) {\n ePxU = Math.round((exon.cdStart - bpStart) / xScale);\n ctx.fillRect(ePx, py2, ePxU - ePx, h2); // start is UTR\n ePw -= (ePxU - ePx);\n ePx = ePxU;\n\n }\n if (exon.cdEnd) {\n ePxU = Math.round((exon.cdEnd - bpStart) / xScale);\n ctx.fillRect(ePxU, py2, ePx1 - ePxU, h2); // start is UTR\n ePw -= (ePx1 - ePxU);\n ePx1 = ePxU;\n }\n\n ePw = Math.max(ePw, 1);\n ctx.fillRect(ePx, py, ePw, h);\n\n // Arrows\n if (ePw > step + 5 && direction !== 0) {\n ctx.fillStyle = \"white\";\n ctx.strokeStyle = \"white\";\n for (let x = ePx + step / 2; x < ePx1; x += step) {\n // draw arrowheads along central line indicating transcribed orientation\n IGVGraphics.strokeLine(ctx, x - direction * 2, cy - 2, x, cy);\n IGVGraphics.strokeLine(ctx, x - direction * 2, cy + 2, x, cy);\n }\n ctx.fillStyle = color;\n ctx.strokeStyle = color;\n\n }\n }\n }\n }\n\n if (options.drawLabel && this.displayMode !== \"SQUISHED\") {\n renderFeatureLabel.call(this, ctx, feature, coord.px, coord.px1, py, options.referenceFrame, options);\n }\n } finally {\n ctx.restore();\n }\n}\n\n/**\n * @param ctx the canvas 2d context\n * @param feature\n * @param featureX feature start in pixel coordinates\n * @param featureX1 feature end in pixel coordinates\n * @param featureY feature y-coordinate\n * @param windowX visible window start x-coordinate\n * @param windowX1 visible window end x-coordinate\n * @param referenceFrame genomic state\n * @param options options\n */\nfunction renderFeatureLabel(ctx, feature, featureX, featureX1, featureY, referenceFrame, options) {\n\n try {\n ctx.save();\n\n let name = feature.name;\n if (name === undefined && feature.gene) name = feature.gene.name;\n if (name === undefined) name = feature.id || feature.ID;\n if (!name || name === '.') return\n\n let centerX = (featureX + featureX1) / 2;\n\n let transform;\n if (this.displayMode === \"COLLAPSED\" && this.labelDisplayMode === \"SLANT\") {\n transform = {rotate: {angle: 45}};\n }\n const labelY = getFeatureLabelY(featureY, transform);\n\n let color = this.getColorForFeature(feature);\n let geneColor;\n let gtexSelection = false;\n if (referenceFrame.selection && GtexUtils.gtexLoaded) {\n // TODO -- for gtex, figure out a better way to do this\n gtexSelection = true;\n geneColor = referenceFrame.selection.colorForGene(name);\n }\n\n const geneFontStyle = {\n textAlign: \"SLANT\" === this.labelDisplayMode ? undefined : 'center',\n fillStyle: geneColor || color,\n strokeStyle: geneColor || color\n };\n\n const textBox = ctx.measureText(name);\n const xleft = centerX - textBox.width / 2;\n const xright = centerX + textBox.width / 2;\n const lastLabelX = options.rowLastLabelX[feature.row] || -Number.MAX_SAFE_INTEGER;\n if (options.labelAllFeatures || xleft > lastLabelX || gtexSelection) {\n options.rowLastLabelX[feature.row] = xright;\n\n if ('y' === options.axis) {\n ctx.save();\n IGVGraphics.labelTransformWithContext(ctx, centerX);\n IGVGraphics.fillText(ctx, name, centerX, labelY, geneFontStyle, transform);\n ctx.restore();\n } else {\n IGVGraphics.fillText(ctx, name, centerX, labelY, geneFontStyle, transform);\n }\n }\n\n } finally {\n ctx.restore();\n }\n}\n\nfunction getFeatureLabelY(featureY, transform) {\n return transform ? featureY + 20 : featureY + 25\n}\n\n// SNP constants\n\nconst codingNonSynonSet = new Set(['nonsense', 'missense', 'stop-loss', 'frameshift', 'cds-indel']);\nconst codingSynonSet = new Set(['coding-synon']);\nconst spliceSiteSet = new Set(['splice-3', 'splice-5']);\nconst untranslatedSet = new Set(['untranslated-5', 'untranslated-3']);\n\n\n/**\n * Renderer for a UCSC snp track\n *\n * @param snp\n * @param bpStart genomic location of the left edge of the current canvas\n * @param xScale scale in base-pairs per pixel\n * @param pixelHeight pixel height of the current canvas\n * @param ctx the canvas 2d context\n */\nfunction renderSnp(snp, bpStart, xScale, pixelHeight, ctx) {\n\n var coord = calculateFeatureCoordinates(snp, bpStart, xScale),\n py = this.margin,\n h,\n colorArrLength = this.snpColors.length,\n colorPriority;\n\n h = this.displayMode === \"squished\" ? this.squishedRowHeight : this.expandedRowHeight;\n\n switch (this.colorBy) {\n case 'function':\n colorPriority = colorByFunc(snp.func);\n break\n case 'class':\n colorPriority = colorByClass(snp['class']);\n }\n\n ctx.fillStyle = this.snpColors[colorPriority];\n ctx.fillRect(coord.px, py, coord.pw, h);\n\n // Coloring functions, convert a value to a priority\n\n function colorByFunc(theFunc) {\n var priorities;\n var funcArray = theFunc.split(',');\n // possible func values\n\n\n priorities = funcArray.map(function (func) {\n if (codingNonSynonSet.has(func) || spliceSiteSet.has(func)) {\n return colorArrLength - 1\n } else if (codingSynonSet.has(func)) {\n return colorArrLength - 2\n } else if (untranslatedSet.has(func)) {\n return colorArrLength - 3\n } else { // locusSet.has(func) || intronSet.has(func)\n return 0\n }\n });\n\n return priorities.reduce(function (a, b) {\n return Math.max(a, b)\n })\n }\n\n function colorByClass(cls) {\n if (cls === 'deletion') {\n return colorArrLength - 1\n } else if (cls === 'mnp') {\n return colorArrLength - 2\n } else if (cls === 'microsatellite' || cls === 'named') {\n return colorArrLength - 3\n } else { // cls === 'single' || cls === 'in-del' || cls === 'insertion'\n return 0\n }\n }\n}\n\n/**\n *\n * @param feature\n * @param bpStart genomic location of the left edge of the current canvas\n * @param xScale scale in base-pairs per pixel\n * @param pixelHeight pixel height of the current canvas\n * @param ctx the canvas 2d context\n */\nfunction renderFusionJuncSpan(feature, bpStart, xScale, pixelHeight, ctx) {\n\n const rowHeight = (this.displayMode === \"EXPANDED\") ? this.expandedRowHeight : this.squishedRowHeight;\n let py = this.margin;\n if (this.displayMode !== \"COLLAPSED\" && feature.row !== undefined) {\n py += feature.row * rowHeight;\n }\n\n const cy = py + 0.5 * rowHeight;\n const topY = cy - 0.5 * rowHeight;\n const bottomY = cy + 0.5 * rowHeight;\n\n // draw the junction arc\n const junctionLeftPx = Math.round((feature.junction_left - bpStart) / xScale);\n const junctionRightPx = Math.round((feature.junction_right - bpStart) / xScale);\n\n ctx.beginPath();\n ctx.moveTo(junctionLeftPx, cy);\n ctx.bezierCurveTo(junctionLeftPx, topY, junctionRightPx, topY, junctionRightPx, cy);\n\n ctx.lineWidth = 1 + Math.log(feature.num_junction_reads) / Math.log(2);\n ctx.strokeStyle = 'blue';\n ctx.stroke();\n\n // draw the spanning arcs\n const spanningCoords = feature.spanning_frag_coords;\n for (let i = 0; i < spanningCoords.length; i++) {\n\n const spanningInfo = spanningCoords[i];\n const spanLeftPx = Math.round((spanningInfo.left - bpStart) / xScale);\n const spanRightPx = Math.round((spanningInfo.right - bpStart) / xScale);\n\n ctx.beginPath();\n ctx.moveTo(spanLeftPx, cy);\n ctx.bezierCurveTo(spanLeftPx, bottomY, spanRightPx, bottomY, spanRightPx, cy);\n\n ctx.lineWidth = 1;\n ctx.strokeStyle = 'purple';\n ctx.stroke();\n }\n}\n\nconst DEFAULT_COLOR$2 = 'rgb(0, 0, 150)';\n\n\nclass FeatureTrack extends TrackBase {\n\n static defaults = {\n type: \"annotation\",\n maxRows: 1000, // protects against pathological feature packing cases (# of rows of overlapping feaures)\n displayMode: \"EXPANDED\", // COLLAPSED | EXPANDED | SQUISHED\n margin: 10,\n featureHeight: 14,\n autoHeight: false,\n useScore: false\n }\n\n\n constructor(config, browser) {\n super(config, browser);\n }\n\n init(config) {\n super.init(config);\n\n\n // Obscure option, not common or supoorted, included for backward compatibility\n this.labelDisplayMode = config.labelDisplayMode;\n\n if (config._featureSource) {\n this.featureSource = config._featureSource;\n delete config._featureSource;\n } else {\n this.featureSource = config.featureSource ?\n config.featureSource :\n FeatureSource(config, this.browser.genome);\n }\n\n if (\"FusionJuncSpan\" === config.type) {\n this.render = config.render || renderFusionJuncSpan;\n this.squishedRowHeight = config.squishedRowHeight || 50;\n this.expandedRowHeight = config.expandedRowHeight || 50;\n this.height = config.height || this.margin + 2 * this.expandedRowHeight;\n } else if ('snp' === config.type) {\n this.render = config.render || renderSnp;\n // colors ordered based on priority least to greatest\n this.snpColors = ['rgb(0,0,0)', 'rgb(0,0,255)', 'rgb(0,255,0)', 'rgb(255,0,0)'];\n this.colorBy = 'function';\n this.expandedRowHeight = config.expandedRowHeight || 10;\n this.squishedRowHeight = config.squishedRowHeight || 5;\n this.height = config.height || 30;\n } else {\n this.render = config.render || renderFeature;\n this.arrowSpacing = 30;\n // adjust label positions to make sure they're always visible\n monitorTrackDrag(this);\n this.squishedRowHeight = config.squishedRowHeight || 15;\n this.expandedRowHeight = config.expandedRowHeight || 30;\n this.height = config.height || this.margin + 2 * this.expandedRowHeight;\n\n // Set colorBy fields considering legacy options for backward compatibility\n if (config.colorBy) {\n if (config.colorBy.field) {\n config.colorTable = config.colorBy.pallete || config.colorBy.palette;\n config.colorBy = config.colorBy.field;\n }\n this.colorBy = config.colorBy; // Can be undefined => default\n if (config.colorTable) {\n this.colorTable = new ColorTable(config.colorTable);\n } else {\n this.colorTable = new PaletteColorTable(\"Set1\");\n }\n }\n }\n }\n\n async postInit() {\n\n if (typeof this.featureSource.getHeader === \"function\") {\n this.header = await this.featureSource.getHeader();\n if (this.disposed) return // This track was removed during async load\n }\n\n // Set properties from track line\n if (this.header) {\n this.setTrackProperties(this.header);\n }\n\n if (this.visibilityWindow === undefined && typeof this.featureSource.defaultVisibilityWindow === 'function') {\n this.visibilityWindow = await this.featureSource.defaultVisibilityWindow();\n }\n\n return this\n\n }\n\n get supportsWholeGenome() {\n if (this.config.supportsWholeGenome !== undefined) {\n return this.config.supportsWholeGenome\n } else if (this.featureSource && typeof this.featureSource.supportsWholeGenome === 'function') {\n return this.featureSource.supportsWholeGenome()\n } else {\n if (this.visibilityWindow === undefined && (this.config.indexed === false || !this.config.indexURL)) {\n return true\n }\n }\n }\n\n async getFeatures(chr, start, end, bpPerPixel) {\n const visibilityWindow = this.visibilityWindow;\n return this.featureSource.getFeatures({chr, start, end, bpPerPixel, visibilityWindow})\n };\n\n\n /**\n * The required height in pixels required for the track content. This is not the visible track height, which\n * can be smaller (with a scrollbar) or larger.\n *\n * @param features\n * @returns {*}\n */\n computePixelHeight(features) {\n\n if (this.displayMode === \"COLLAPSED\") {\n return this.margin + this.expandedRowHeight\n } else {\n let maxRow = 0;\n if (features && (typeof features.forEach === \"function\")) {\n for (let feature of features) {\n if (feature.row && feature.row > maxRow) {\n maxRow = feature.row;\n }\n }\n }\n\n const height = this.margin + (maxRow + 1) * (\"SQUISHED\" === this.displayMode ? this.squishedRowHeight : this.expandedRowHeight);\n return height\n\n }\n };\n\n draw(options) {\n\n const featureList = options.features;\n const ctx = options.context;\n const bpPerPixel = options.bpPerPixel;\n const bpStart = options.bpStart;\n const pixelWidth = options.pixelWidth;\n const pixelHeight = options.pixelHeight;\n const bpEnd = bpStart + pixelWidth * bpPerPixel + 1;\n\n\n if (!this.config.isMergedTrack) {\n IGVGraphics.fillRect(ctx, 0, options.pixelTop, pixelWidth, pixelHeight, {'fillStyle': \"rgb(255, 255, 255)\"});\n }\n\n if (featureList) {\n\n const rowFeatureCount = [];\n options.rowLastX = [];\n options.rowLastLabelX = [];\n for (let feature of featureList) {\n if (feature.start > bpStart && feature.end < bpEnd) {\n const row = this.displayMode === \"COLLAPSED\" ? 0 : feature.row || 0;\n if (rowFeatureCount[row] === undefined) {\n rowFeatureCount[row] = 1;\n } else {\n rowFeatureCount[row]++;\n }\n options.rowLastX[row] = -Number.MAX_SAFE_INTEGER;\n options.rowLastLabelX[row] = -Number.MAX_SAFE_INTEGER;\n }\n }\n const maxFeatureCount = Math.max(1, Math.max(...rowFeatureCount));\n const pixelsPerFeature = pixelWidth / maxFeatureCount;\n\n let lastPxEnd = [];\n for (let feature of featureList) {\n if (feature.end < bpStart) continue\n if (feature.start > bpEnd) break\n const row = this.displayMode === 'COLLAPSED' ? 0 : feature.row;\n options.drawLabel = options.labelAllFeatures || pixelsPerFeature > 10;\n const pxEnd = Math.ceil((feature.end - bpStart) / bpPerPixel);\n const last = lastPxEnd[row];\n if (!last || pxEnd > last) {\n this.render.call(this, feature, bpStart, bpPerPixel, pixelHeight, ctx, options);\n\n // Ensure a visible gap between features\n const pxStart = Math.floor((feature.start - bpStart) / bpPerPixel);\n if (last && pxStart - last <= 0) {\n ctx.globalAlpha = 0.5;\n IGVGraphics.strokeLine(ctx, pxStart, 0, pxStart, pixelHeight, {'strokeStyle': \"rgb(255, 255, 255)\"});\n ctx.globalAlpha = 1.0;\n }\n lastPxEnd[row] = pxEnd;\n }\n }\n\n } else {\n console.log(\"No feature list\");\n }\n\n };\n\n clickedFeatures(clickState) {\n\n const y = clickState.y - this.margin;\n const allFeatures = super.clickedFeatures(clickState);\n\n let row;\n switch (this.displayMode) {\n case 'SQUISHED':\n row = Math.floor(y / this.squishedRowHeight);\n break\n case 'EXPANDED':\n row = Math.floor(y / this.expandedRowHeight);\n break\n default:\n row = undefined;\n }\n\n return allFeatures.filter(function (feature) {\n return (row === undefined || feature.row === undefined || row === feature.row)\n })\n }\n\n /**\n * Return \"popup data\" for feature @ genomic location. Data is an array of key-value pairs\n */\n popupData(clickState, features) {\n\n if (features === undefined) features = this.clickedFeatures(clickState);\n const genomicLocation = clickState.genomicLocation;\n const data = [];\n for (let feature of features) {\n\n // Whole genome hack, whole-genome psuedo features store the \"real\" feature in an _f field\n const f = feature._f || feature;\n\n const featureData = (typeof f.popupData === \"function\") ?\n f.popupData(genomicLocation) :\n this.extractPopupData(f);\n\n if (featureData) {\n\n if (data.length > 0) {\n data.push(\"

\");\n }\n\n // If we have an infoURL, find the name property and create the link. We do this at this level\n // to catch name properties in both custom popupData functions and the generic extractPopupData function\n\n const infoURL = this.infoURL || this.config.infoURL;\n for (let fd of featureData) {\n data.push(fd);\n if (infoURL &&\n fd.name &&\n fd.name.toLowerCase() === \"name\" &&\n fd.value &&\n isString$2(fd.value) &&\n !fd.value.startsWith(\"<\")) {\n const href = infoURL.replace(\"$$\", feature.name);\n fd.value = `${fd.value}`;\n }\n }\n\n\n //Array.prototype.push.apply(data, featureData);\n\n // If we have clicked over an exon number it.\n // Disabled for GFF and GTF files if the visibility window is < the feature length since we don't know if we have all exons\n const isGFF = \"gff\" === this.config.format || \"gff3\" === this.config.format || \"gtf\" === this.config.format;\n if (f.exons) {\n for (let i = 0; i < f.exons.length; i++) {\n const exon = f.exons[i];\n if (genomicLocation >= exon.start && genomicLocation <= exon.end) {\n const exonNumber = isGFF ?\n exon.number :\n f.strand === \"-\" ? f.exons.length - i : i + 1;\n if (exonNumber) {\n data.push('
');\n data.push({name: \"Exon Number\", value: exonNumber});\n }\n break\n }\n }\n }\n }\n }\n\n return data\n\n }\n\n menuItemList() {\n\n const menuItems = [];\n\n if (this.render === renderSnp) {\n menuItems.push('
');\n for (let colorScheme of [\"function\", \"class\"]) {\n menuItems.push({\n object: $$1(createCheckbox('Color by ' + colorScheme, colorScheme === this.colorBy)),\n click: () => {\n this.colorBy = colorScheme;\n this.trackView.repaintViews();\n }\n });\n }\n }\n\n menuItems.push('
');\n for (let displayMode of [\"COLLAPSED\", \"SQUISHED\", \"EXPANDED\"]) {\n const lut =\n {\n \"COLLAPSED\": \"Collapse\",\n \"SQUISHED\": \"Squish\",\n \"EXPANDED\": \"Expand\"\n };\n\n menuItems.push(\n {\n object: $$1(createCheckbox(lut[displayMode], displayMode === this.displayMode)),\n click: () => {\n this.displayMode = displayMode;\n this.config.displayMode = displayMode;\n this.trackView.checkContentHeight();\n this.trackView.repaintViews();\n }\n });\n }\n\n return menuItems\n\n };\n\n\n contextMenuItemList(clickState) {\n\n const features = this.clickedFeatures(clickState);\n\n if (undefined === features || 0 === features.length) {\n return undefined\n }\n\n if (features.length > 1) {\n features.sort((a, b) => (b.end - b.start) - (a.end - a.start));\n }\n const f = features[0]; // The shortest clicked feature\n\n if ((f.end - f.start) <= 1000000) {\n const list = [{\n label: 'View feature sequence',\n click: async () => {\n let seq = await this.browser.genome.getSequence(f.chr, f.start, f.end);\n if (!seq) {\n seq = \"Unknown sequence\";\n } else if (f.strand === '-') {\n seq = reverseComplementSequence(seq);\n }\n this.browser.alert.present(seq);\n\n }\n }];\n\n if (isSecureContext() && navigator.clipboard !== undefined) {\n list.push(\n {\n label: 'Copy feature sequence',\n click: async () => {\n let seq = await this.browser.genome.getSequence(f.chr, f.start, f.end);\n if (!seq) {\n seq = \"Unknown sequence\";\n } else if (f.strand === '-') {\n seq = reverseComplementSequence(seq);\n }\n try {\n await navigator.clipboard.writeText(seq);\n } catch (e) {\n console.error(e);\n this.browser.alert.present(`error copying sequence to clipboard ${e}`);\n }\n }\n }\n );\n }\n list.push('
');\n return list\n } else {\n return undefined\n }\n }\n\n description() {\n\n // if('snp' === this.type) {\n if (renderSnp === this.render) {\n let desc = \"\" + this.name + '
';\n desc += 'Color By Function:
';\n desc += 'Red: Coding-Non-Synonymous, Splice Site
';\n desc += 'Green: Coding-Synonymous
';\n desc += 'Blue: Untranslated
';\n desc += 'Black: Intron, Locus, Unknown

';\n desc += 'Color By Class:
';\n desc += 'Red: Deletion
';\n desc += 'Green: MNP
';\n desc += 'Blue: Microsatellite, Named
';\n desc += 'Black: Indel, Insertion, SNP';\n desc += \"\";\n return desc\n } else {\n return super.description()\n }\n\n };\n\n /**\n * Return color for feature.\n * @param feature\n * @returns {string}\n */\n\n getColorForFeature(feature) {\n\n let color;\n if (this.altColor && \"-\" === feature.strand) {\n color = (typeof this.altColor === \"function\") ? this.altColor(feature) : this.altColor;\n } else if (this.color) {\n color = (typeof this.color === \"function\") ? this.color(feature) : this.color; // Explicit setting via menu, or possibly track line if !config.color\n } else if (this.colorBy) {\n const value = feature.getAttributeValue ?\n feature.getAttributeValue(this.colorBy) :\n feature[this.colorBy];\n color = this.colorTable.getColor(value);\n } else if (feature.color) {\n color = feature.color; // Explicit color for feature\n }\n\n // If no explicit setting use the default\n if (!color) {\n color = DEFAULT_COLOR$2; // Track default\n }\n\n if (feature.alpha && feature.alpha !== 1) {\n color = IGVColor.addAlpha(color, feature.alpha);\n } else if (this.useScore && feature.score && !Number.isNaN(feature.score)) {\n // UCSC useScore option, for scores between 0-1000. See https://genome.ucsc.edu/goldenPath/help/customTrack.html#TRACK\n const min = this.config.min ? this.config.min : this.viewLimitMin ? this.viewLimitMin : 0;\n const max = this.config.max ? this.config.max : this.viewLimitMax ? this.viewLimitMax : 1000;\n const alpha = getAlpha(min, max, feature.score);\n feature.alpha = alpha; // Avoid computing again\n color = IGVColor.addAlpha(color, alpha);\n }\n\n\n function getAlpha(min, max, score) {\n const binWidth = (max - min) / 9;\n const binNumber = Math.floor((score - min) / binWidth);\n return Math.min(1.0, 0.2 + (binNumber * 0.8) / 9)\n }\n\n return color\n }\n\n\n /**\n * Called when the track is removed. Do any needed cleanup here\n */\n dispose() {\n this.trackView = undefined;\n }\n}\n\n/**\n * Monitors track drag events, updates label position to ensure that they're always visible.\n * @param track\n */\nfunction monitorTrackDrag(track) {\n\n if (track.browser.on) {\n track.browser.on('trackdragend', onDragEnd);\n track.browser.on('trackremoved', unSubscribe);\n }\n\n function onDragEnd() {\n if (track.trackView && track.displayMode !== \"SQUISHED\") {\n track.trackView.updateViews(); // TODO -- refine this to the viewport that was dragged after DOM refactor\n }\n }\n\n function unSubscribe(removedTrack) {\n if (track.browser.un && track === removedTrack) {\n track.browser.un('trackdragend', onDragEnd);\n track.browser.un('trackremoved', unSubscribe);\n }\n }\n\n}\n\nclass RegionTableBase {\n constructor(config) {\n\n this.config = config;\n\n this.browser = config.browser;\n\n this.columnFormat = config.columnFormat;\n\n this.tableRowSelectionList = [];\n\n this.tableDOM = domUtils.div({ class: 'igv-roi-table' });\n // if(config.width) {\n // let [ w ] = config.width.split('px')\n // w = parseInt(w, 10)\n // this.tableDOM.style.width = `${Math.min(w, 1600)}px`\n //\n // }\n\n config.parent.appendChild(this.tableDOM);\n\n this.headerDOM = config;\n\n this.tableColumnTitles = this.tableDOM;\n\n this.tableRowContainer = this.tableDOM;\n\n this.footerDOM = config.gotoButtonHandler;\n\n }\n\n set headerDOM({ browser, parent, headerTitle, dismissHandler }) {\n\n // header\n const dom = domUtils.div();\n this.tableDOM.appendChild(dom);\n\n // header title\n const div = domUtils.div();\n dom.appendChild(div);\n div.innerHTML = headerTitle;\n\n // table dismiss button\n const dismiss = domUtils.div();\n dom.appendChild(dismiss);\n dismiss.appendChild(icons$1.createIcon('times'));\n\n this.boundDismissHandler = mouseClickHandler.bind(this);\n\n dismiss.addEventListener('click', this.boundDismissHandler);\n\n function mouseClickHandler (event) {\n event.stopPropagation();\n dismissHandler();\n }\n\n const { y:y_root } = browser.root.getBoundingClientRect();\n const { y:y_parent } = parent.getBoundingClientRect();\n const constraint = -(y_parent - y_root);\n makeDraggable(this.tableDOM, dom, { minX:0, minY:constraint });\n\n this.tableDOM.style.display = 'none';\n\n this._headerDOM = dom;\n\n }\n\n set tableColumnTitles(tableDOM) {\n\n const tblColumnTitles = domUtils.div({ class: 'igv-roi-table-column-titles' });\n tableDOM.appendChild(tblColumnTitles);\n\n for (const { label, width } of this.columnFormat) {\n const col = domUtils.div();\n tblColumnTitles.appendChild(col);\n col.style.width = width;\n col.innerText = label;\n }\n\n this._tableColumnTitlesDOM = tblColumnTitles;\n\n }\n\n get tableColumnTitles() {\n return this._tableColumnTitlesDOM\n }\n\n set tableRowContainer(container) {\n\n const tblRowContainer = domUtils.div({ class: 'igv-roi-table-row-container' });\n container.appendChild(tblRowContainer);\n\n this._tableRowContainerDOM = tblRowContainer;\n\n }\n\n get tableRowContainer() {\n return this._tableRowContainerDOM\n }\n\n set footerDOM(gotoButtonHandler) {\n\n const dom = domUtils.div();\n this.tableDOM.appendChild(dom);\n\n // Go To Button\n const gotoButton = domUtils.div({class: 'igv-roi-table-button'});\n dom.appendChild(gotoButton);\n\n gotoButton.id = 'igv-roi-table-view-button';\n gotoButton.textContent = 'Go To';\n gotoButton.style.pointerEvents = 'none';\n\n this._footerDOM = dom;\n\n this.gotoButton = gotoButton;\n\n this.boundGotoButtonHandler = gotoButtonHandler.bind(this);\n\n this.gotoButton.addEventListener('click', this.boundGotoButtonHandler);\n\n }\n\n tableRowDOMHelper(dom) {\n\n dom.addEventListener('mousedown', event => {\n event.stopPropagation();\n\n dom.classList.toggle('igv-roi-table-row-selected');\n dom.classList.contains('igv-roi-table-row-selected') ? dom.classList.remove('igv-roi-table-row-hover') : dom.classList.add('igv-roi-table-row-hover');\n\n this.setTableRowSelectionState(dom.classList.contains('igv-roi-table-row-selected'));\n });\n\n dom.addEventListener('mouseover', e => {\n dom.classList.contains('igv-roi-table-row-selected') ? dom.classList.remove('igv-roi-table-row-hover') : dom.classList.add('igv-roi-table-row-hover');\n });\n\n dom.addEventListener('mouseout', e => {\n dom.classList.remove('igv-roi-table-row-hover');\n });\n\n }\n\n clearTable() {\n const elements = this.tableRowContainer.querySelectorAll('.igv-roi-table-row');\n for (let el of elements) {\n el.remove();\n }\n }\n\n setTableRowSelectionState(isTableRowSelected) {\n isTableRowSelected ? this.tableRowSelectionList.push(1) : this.tableRowSelectionList.pop();\n this.gotoButton.style.pointerEvents = this.tableRowSelectionList.length > 0 ? 'auto' : 'none';\n }\n\n present() {\n this.tableDOM.style.left = `${ 0 }px`;\n\n const { y:y_root } = this.browser.root.getBoundingClientRect();\n const { y:y_parent } = this.config.parent.getBoundingClientRect();\n\n this.tableDOM.style.top = `${ y_root - y_parent }px`;\n this.tableDOM.style.display = 'flex';\n }\n\n dismiss() {\n this.tableDOM.style.display = 'none';\n }\n\n dispose() {\n\n this.tableDOM.innerHTML = '';\n this.tableDOM.remove();\n\n for (const key of Object.keys(this)) {\n this[key] = undefined;\n }\n\n document.removeEventListener('click', this.boundDismissHandler);\n\n }\n\n}\n\nclass BlatTable extends RegionTableBase {\n\n constructor(config) {\n\n const cooked = Object.assign({ 'width':'1024px' }, config);\n super(cooked);\n\n this.descriptionDOM = config;\n\n }\n\n set descriptionDOM(config) {\n\n if (config.description) {\n\n let dom;\n\n // BLAT result for query sequence\n dom = domUtils.div({ class: 'igv-roi-table-description' });\n this.tableDOM.insertBefore(dom, this.tableColumnTitles);\n dom.style.height = 'auto';\n dom.innerHTML = `BLAT result for query sequence:`;\n\n // CTAATCAtctacactggtttctactg ...\n dom = domUtils.div({ class: 'igv-roi-table-description' });\n this.tableDOM.insertBefore(dom, this.tableColumnTitles);\n dom.style.height = 'auto';\n dom.style.maxHeight = '128px';\n dom.innerHTML = config.description;\n\n // Select one or more rows ...\n dom = domUtils.div({ class: 'igv-roi-table-goto-explainer' });\n this.tableDOM.insertBefore(dom, this.tableColumnTitles);\n dom.innerHTML = `Select one or more rows and click Go To to view the regions`;\n\n }\n\n }\n\n tableRowDOM(record) {\n\n const dom = domUtils.div({ class: 'igv-roi-table-row' });\n\n const pretty = record.map(item => isFinite(item) ? numberFormatter$1(item) : item);\n\n for (let i = 0; i < pretty.length; i++) {\n\n const el = domUtils.div();\n dom.appendChild(el);\n\n const format = this.columnFormat[ i ];\n el.style.width = format.width || 'fit-content';\n el.innerText = pretty[ i ];\n }\n\n this.tableRowDOMHelper(dom);\n\n return dom\n }\n\n renderTable(records) {\n\n Array.from(this.tableRowContainer.querySelectorAll('.igv-roi-table-row')).forEach(el => el.remove());\n\n if (records.length > 0) {\n\n for (let record of records) {\n const row = this.tableRowDOM(record);\n this.tableRowContainer.appendChild(row);\n }\n\n }\n\n }\n\n static getColumnFormatConfiguration() {\n\n /*\n return [\n { label: 'chr', width: '60px' },\n { label: 'start', width: '100px' },\n { label: 'end', width: '100px' },\n { label: 'strand', width: '50px' },\n { label: 'score', width: '50px' },\n { label: 'match', width: '50px' },\n { label: \"mis-match\", width: '70px' },\n { label: \"rep. match\", width: '70px' },\n { label: \"N's\", width: '32px' },\n { label: 'Q gap count', width: '90px' },\n { label: 'Q gap bases', width: '90px' },\n { label: 'T gap count', width: '90px' },\n { label: 'T gap bases', width: '90px' },\n ]\n */\n\n return [\n { label: 'chr', width: '7%' },\n { label: 'start', width: '12%' },\n { label: 'end', width: '12%' },\n { label: 'strand', width: '5%' },\n { label: 'score', width: '5%' },\n { label: 'match', width: '5%' },\n { label: \"mis-match\", width: '7%' },\n { label: \"rep. match\", width: '7%' },\n { label: \"N's\", width: '3%' },\n { label: 'Q gap count', width: '9%' },\n { label: 'Q gap bases', width: '9%' },\n { label: 'T gap count', width: '9%' },\n { label: 'T gap bases', width: '9%' },\n ]\n }\n\n static gotoButtonHandler (event) {\n\n event.stopPropagation();\n\n const selectedRows = this.tableDOM.querySelectorAll('.igv-roi-table-row-selected');\n\n const loci = [];\n for (const row of selectedRows) {\n\n const record = [];\n row.querySelectorAll('div').forEach(el => record.push(el.innerText));\n\n const [ chr, start, end ] = record;\n loci.push(`${ chr }:${ start }-${ end }`);\n }\n\n for (const el of this.tableDOM.querySelectorAll('.igv-roi-table-row')) {\n el.classList.remove('igv-roi-table-row-selected');\n }\n\n this.setTableRowSelectionState(false);\n\n this.browser.search(loci.join(' '));\n\n // console.log(`browser search( ${loci.join(' ')} )`)\n\n }\n\n}\n\n/*\nhttp://genome.ucsc.edu/cgi-bin/hgBlat\n?userSeq=CTAATCAtctacactggtttctactgaaatgtctgttgtcatagacttaattgtgtcttcagatacagcagttctgttatttctgagttttacctggggcaagagaatctttagcaagtttaaaggcacctatatctggaatcacccctccctccagatgaatatcacagactctcccattaaaggtcttgccTTCCTTGATAGCATCATCACTCCA\n&type=DNA\n&db=hg38\n&output=json\n */\n\n//const blatServer = \"https://genome.ucsc.edu/cgi-bin/hgBlat\"\nconst defaultBlatServer = \"https://igv.org/services/blatUCSC.php\";\n//const blatServer = \"http://localhost:8000/blatUCSC.php\"\n\n\nasync function blat({url, userSeq, db}) {\n\n url = url || defaultBlatServer;\n\n const results = await postData(url, userSeq, db);\n\n results.fields;\n\n const features = results.blat.map(decodePSL);\n\n return features\n}\n\nasync function postData(url = \"\", userSeq, db) {\n\n const data = new URLSearchParams();\n data.append(\"userSeq\", userSeq);\n data.append(\"db\", db);\n\n const response = await fetch(url, { method: \"post\", body: data });\n return response.json(); // parses JSON response into native JavaScript objects\n}\n\nconst maxSequenceSize = 25000;\n\nclass BlatTrack extends FeatureTrack {\n\n constructor(config, browser) {\n super(config, browser);\n if (!this.name) {\n this.name = 'Blat Results';\n }\n this.sequence = config.sequence;\n this.table = undefined;\n }\n\n openTableView() {\n\n if (undefined === this.table) {\n\n const rows = this.config.features.map(f => [\n f.chr,\n (f.start + 1),\n f.end,\n f.strand,\n f.score,\n f.matches,\n f.misMatches,\n f.repMatches,\n f.nCount,\n f.qNumInsert,\n f.qBaseInsert,\n f.tNumInsert,\n f.tBaseInsert\n ]);\n\n const config =\n {\n browser: this.browser,\n parent: this.browser.parent,\n headerTitle: this.config.title,\n description: this.sequence,\n dismissHandler: () => {\n this.table.dismiss();\n this.table.dispose();\n this.table = undefined;\n },\n columnFormat: BlatTable.getColumnFormatConfiguration(),\n gotoButtonHandler: BlatTable.gotoButtonHandler\n };\n\n this.table = new BlatTable(config);\n this.table.renderTable(rows);\n }\n\n this.table.present();\n\n }\n\n menuItemList() {\n\n const menuItems = super.menuItemList();\n\n menuItems.push('
');\n menuItems.push({\n label: 'Open table view',\n click: () => this.openTableView()\n });\n return menuItems\n }\n\n\n /**\n * Track has been permanently removed. Release resources and other cleanup\n */\n dispose() {\n super.dispose();\n // Release DOM element for table\n if (this.table) {\n this.table.popover.parentElement.removeChild(this.table.popover);\n\n }\n\n\n }\n}\n\n\nasync function createBlatTrack({sequence, browser, name, title}) {\n\n if (sequence.length > maxSequenceSize) {\n browser.alert.present(`Sequence size exceeds maximum allowed length (${sequence.length} > ${maxSequenceSize})`);\n return\n }\n\n const db = browser.genome.id; // TODO -- blat specific property\n\n const url = browser.config[\"blatServerURL\"];\n\n try {\n\n const features = await blat({url, userSeq: sequence, db});\n const trackConfig = {\n type: 'blat',\n name: name || 'blat results',\n title: title || 'blat results',\n sequence: sequence,\n altColor: 'rgb(176, 176, 236)',\n color: 'rgb(236, 176, 176)',\n features: features\n };\n\n const track = await browser.loadTrack(trackConfig);\n track.openTableView();\n\n } catch (e) {\n browser.alert.present(`Error performing blat search: ${e}`);\n }\n\n}\n\n/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2014 Broad Institute\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\nconst alignmentStartGap = 5;\nconst downsampleRowHeight = 5;\nconst DEFAULT_ALIGNMENT_COLOR = \"rgb(185, 185, 185)\";\nconst DEFAULT_COVERAGE_COLOR = \"rgb(150, 150, 150)\";\nconst DEFAULT_CONNECTOR_COLOR = \"rgb(200, 200, 200)\";\nconst MINIMUM_BLAT_LENGTH = 20;\n\nclass BAMTrack extends TrackBase {\n\n static defaults = {\n alleleFreqThreshold: 0.2,\n visibilityWindow: 30000,\n showCoverage: true,\n showAlignments: true,\n viewAsPairs: false,\n pairsSupported: true,\n showSoftClips: false,\n showAllBases: false,\n showInsertions: true,\n showMismatches: true,\n height: 300,\n coverageTrackHeight: 50\n }\n\n constructor(config, browser) {\n super(config, browser);\n }\n\n init(config) {\n\n this.type = \"alignment\";\n this.featureSource = new BamSource(config, this.browser);\n this.coverageTrack = new CoverageTrack(config, this);\n this.alignmentTrack = new AlignmentTrack(config, this);\n\n super.init(config);\n\n this.alignmentTrack.setTop(this.coverageTrack, this.showCoverage);\n\n if(!this.showAlignments) {\n this._height = this.coverageTrackHeight;\n }\n\n // The sort object can be an array in the case of multi-locus view, however if multiple sort positions\n // are present for a given reference frame the last one will take precedence\n if (config.sort) {\n if (Array.isArray(config.sort)) {\n // Legacy support\n this.assignSort(config.sort[0]);\n } else {\n this.assignSort(config.sort);\n }\n }\n\n }\n\n set height(h) {\n this._height = h;\n if (this.showAlignments) {\n this.alignmentTrack.height = this.showCoverage ? h - this.coverageTrackHeight : h;\n }\n }\n\n get height() {\n return this._height\n }\n\n get minTemplateLength() {\n const configMinTLEN = this.config.minTLEN !== undefined ? this.config.minTLEN : this.config.minFragmentLength;\n return (configMinTLEN !== undefined) ? configMinTLEN :\n this._pairedEndStats ? this._pairedEndStats.minTLEN : 0\n }\n\n get maxTemplateLength() {\n const configMaxTLEN = this.config.maxTLEN !== undefined ? this.config.maxTLEN : this.config.maxFragmentLength;\n return (configMaxTLEN !== undefined) ? configMaxTLEN :\n this._pairedEndStats ? this._pairedEndStats.maxTLEN : 1000\n }\n\n sort(options) {\n options = this.assignSort(options);\n\n for (let vp of this.trackView.viewports) {\n if (vp.containsPosition(options.chr, options.position)) {\n const alignmentContainer = vp.cachedFeatures;\n if (alignmentContainer) {\n alignmentContainer.sortRows(options);\n vp.repaint();\n }\n }\n }\n }\n\n /**\n * Fix syntax problems for sort options.\n * @param options\n */\n assignSort(options) {\n // convert old syntax\n if (options.locus) {\n const range = parseLocusString$1(options.locus);\n options.chr = range.chr;\n options.position = range.start;\n } else {\n options.position--;\n }\n options.direction = options.direction === \"ASC\" || options.direction === true;\n\n // chr aliasing\n options.chr = this.browser.genome.getChromosomeName(options.chr);\n this.sortObject = options;\n\n return this.sortObject\n }\n\n async getFeatures(chr, bpStart, bpEnd, bpPerPixel, viewport) {\n\n const alignmentContainer = await this.featureSource.getAlignments(chr, bpStart, bpEnd);\n\n if (alignmentContainer.paired && !this._pairedEndStats && !this.config.maxFragmentLength) {\n const pairedEndStats = new PairedEndStats(alignmentContainer.alignments, this.config);\n if (pairedEndStats.totalCount > 99) {\n this._pairedEndStats = pairedEndStats;\n }\n }\n alignmentContainer.alignments = undefined; // Don't need to hold onto these anymore\n\n const sort = this.sortObject;\n if (sort) {\n if (sort.chr === chr && sort.position >= bpStart && sort.position <= bpEnd) {\n alignmentContainer.sortRows(sort);\n }\n }\n\n return alignmentContainer\n }\n\n\n /**\n * Compute the pixel height required to display all content. This is not the same as the viewport height\n * (track.height) which might include a scrollbar.\n *\n * @param alignmentContainer\n * @returns {number}\n */\n computePixelHeight(alignmentContainer) {\n return (this.showCoverage ? this.coverageTrackHeight : 0) +\n (this.showAlignments ? this.alignmentTrack.computePixelHeight(alignmentContainer) : 0)\n }\n\n draw(options) {\n\n IGVGraphics.fillRect(options.context, 0, options.pixelTop, options.pixelWidth, options.pixelHeight, {'fillStyle': \"rgb(255, 255, 255)\"});\n\n if (true === this.showCoverage && this.coverageTrackHeight > 0) {\n this.trackView.axisCanvas.style.display = 'block';\n this.coverageTrack.draw(options);\n } else {\n this.trackView.axisCanvas.style.display = 'none';\n }\n\n if (true === this.showAlignments) {\n this.alignmentTrack.setTop(this.coverageTrack, this.showCoverage);\n this.alignmentTrack.draw(options);\n }\n }\n\n paintAxis(ctx, pixelWidth, pixelHeight) {\n\n this.coverageTrack.paintAxis(ctx, pixelWidth, this.coverageTrackHeight);\n\n // if (this.browser.isMultiLocusMode()) {\n // ctx.clearRect(0, 0, pixelWidth, pixelHeight);\n // } else {\n // this.coverageTrack.paintAxis(ctx, pixelWidth, this.coverageTrackHeight);\n // }\n }\n\n contextMenuItemList(config) {\n return this.alignmentTrack.contextMenuItemList(config)\n }\n\n popupData(clickState) {\n if (true === this.showCoverage && clickState.y >= this.coverageTrack.top && clickState.y < this.coverageTrackHeight) {\n return this.coverageTrack.popupData(clickState)\n } else {\n return this.alignmentTrack.popupData(clickState)\n }\n }\n\n /**\n * Return the features (alignment, coverage, downsampled interval) clicked on. Needed for \"onclick\" event.\n * @param clickState\n * @param features\n */\n clickedFeatures(clickState) {\n\n let clickedObject;\n if (true === this.showCoverage && clickState.y >= this.coverageTrack.top && clickState.y < this.coverageTrackHeight) {\n clickedObject = this.coverageTrack.getClickedObject(clickState);\n } else {\n clickedObject = this.alignmentTrack.getClickedObject(clickState);\n }\n return clickedObject ? [clickedObject] : undefined\n }\n\n hoverText(clickState) {\n if (true === this.showCoverage && clickState.y >= this.coverageTrack.top && clickState.y < this.coverageTrackHeight) {\n const clickedObject = this.coverageTrack.getClickedObject(clickState);\n if (clickedObject) {\n return clickedObject.hoverText()\n }\n }\n\n }\n\n menuItemList() {\n\n\n // Start with overage track items\n let menuItems = [];\n\n menuItems = menuItems.concat(MenuUtils.numericDataMenuItems(this.trackView));\n\n // Color by items\n menuItems.push('
');\n const $e = $$1('
');\n $e.text('Color by:');\n menuItems.push({name: undefined, object: $e, click: undefined, init: undefined});\n\n const colorByMenuItems = [{key: 'strand', label: 'read strand'}];\n if (this.alignmentTrack.hasPairs) {\n colorByMenuItems.push({key: 'firstOfPairStrand', label: 'first-of-pair strand'});\n colorByMenuItems.push({key: 'pairOrientation', label: 'pair orientation'});\n colorByMenuItems.push({key: 'tlen', label: 'insert size (TLEN)'});\n colorByMenuItems.push({key: 'unexpectedPair', label: 'pair orientation & insert size (TLEN)'});\n }\n const tagLabel = 'tag' + (this.alignmentTrack.colorByTag ? ' (' + this.alignmentTrack.colorByTag + ')' : '');\n colorByMenuItems.push({key: 'tag', label: tagLabel});\n for (let item of colorByMenuItems) {\n const selected = (this.alignmentTrack.colorBy === item.key);\n menuItems.push(this.colorByCB(item, selected));\n }\n\n // Show coverage / alignment options\n const adjustTrackHeight = () => {\n if (!this.autoHeight) {\n const h =\n (this.showCoverage ? this.coverageTrackHeight : 0) +\n (this.showAlignments ? this.alignmentTrack.height : 0);\n this.trackView.setTrackHeight(h);\n }\n };\n\n menuItems.push('
');\n menuItems.push({\n object: $$1(createCheckbox(\"Show Coverage\", this.showCoverage)),\n click: () => {\n this.showCoverage = !this.showCoverage;\n adjustTrackHeight();\n this.trackView.checkContentHeight();\n this.trackView.repaintViews();\n }\n });\n menuItems.push({\n object: $$1(createCheckbox(\"Show Alignments\", this.showAlignments)),\n click: () => {\n this.showAlignments = !this.showAlignments;\n adjustTrackHeight();\n this.trackView.checkContentHeight();\n this.trackView.repaintViews();\n }\n });\n\n // Show all bases\n menuItems.push('
');\n menuItems.push({\n object: $$1(createCheckbox(\"Show all bases\", this.showAllBases)),\n click: () => {\n this.showAllBases = !this.showAllBases;\n this.config.showAllBases = this.showAllBases;\n this.trackView.repaintViews();\n }\n });\n\n // Show mismatches\n menuItems.push('
');\n menuItems.push({\n object: $$1(createCheckbox(\"Show mismatches\", this.showMismatches)),\n click: () => {\n this.showMismatches = !this.showMismatches;\n this.config.showMismatches = this.showMismatches;\n this.trackView.repaintViews();\n }\n });\n\n // Insertions\n menuItems.push({\n object: $$1(createCheckbox(\"Show insertions\", this.showInsertions)),\n click: () => {\n this.showInsertions = !this.showInsertions;\n this.config.showInsertions = this.showInsertions;\n this.getCachedAlignmentContainers();\n this.trackView.repaintViews();\n }\n });\n\n // Soft clips\n menuItems.push({\n object: $$1(createCheckbox(\"Show soft clips\", this.showSoftClips)),\n click: () => {\n this.showSoftClips = !this.showSoftClips;\n this.config.showSoftClips = this.showSoftClips;\n this.featureSource.setShowSoftClips(this.showSoftClips);\n const alignmentContainers = this.getCachedAlignmentContainers();\n for (let ac of alignmentContainers) {\n ac.setShowSoftClips(this.showSoftClips);\n }\n this.trackView.repaintViews();\n }\n });\n\n // View as pairs\n if (this.pairsSupported && this.alignmentTrack.hasPairs) {\n menuItems.push('
');\n menuItems.push({\n object: $$1(createCheckbox(\"View as pairs\", this.viewAsPairs)),\n click: () => {\n this.viewAsPairs = !this.viewAsPairs;\n this.config.viewAsPairs = this.viewAsPairs;\n this.featureSource.setViewAsPairs(this.viewAsPairs);\n const alignmentContainers = this.getCachedAlignmentContainers();\n for (let ac of alignmentContainers) {\n ac.setViewAsPairs(this.viewAsPairs);\n }\n this.trackView.repaintViews();\n }\n });\n }\n\n // Add chords to JBrowse circular view, if present\n if (this.browser.circularView &&\n (this.alignmentTrack.hasPairs || this.alignmentTrack.hasSupplemental)) {\n menuItems.push('
');\n if (this.alignmentTrack.hasPairs) {\n menuItems.push({\n label: 'Add discordant pairs to circular view',\n click: () => {\n for (let viewport of this.trackView.viewports) {\n this.addPairedChordsForViewport(viewport);\n }\n }\n });\n }\n if (this.alignmentTrack.hasSupplemental) {\n menuItems.push({\n label: 'Add split reads to circular view',\n click: () => {\n for (let viewport of this.trackView.viewports) {\n this.addSplitChordsForViewport(viewport);\n }\n }\n });\n }\n }\n\n\n // Display mode\n menuItems.push('
');\n const $dml = $$1('
');\n $dml.text('Display mode:');\n menuItems.push({name: undefined, object: $dml, click: undefined, init: undefined});\n\n menuItems.push({\n object: $$1(createCheckbox(\"expand\", this.alignmentTrack.displayMode === \"EXPANDED\")),\n click: () => {\n this.alignmentTrack.displayMode = \"EXPANDED\";\n this.config.displayMode = \"EXPANDED\";\n this.trackView.checkContentHeight();\n this.trackView.repaintViews();\n }\n });\n\n menuItems.push({\n object: $$1(createCheckbox(\"squish\", this.alignmentTrack.displayMode === \"SQUISHED\")),\n click: () => {\n this.alignmentTrack.displayMode = \"SQUISHED\";\n this.config.displayMode = \"SQUISHED\";\n this.trackView.checkContentHeight();\n this.trackView.repaintViews();\n }\n });\n\n return menuItems\n }\n\n\n /**\n * Create a \"color by\" checkbox menu item, optionally initially checked\n * @param menuItem\n * @param showCheck\n * @returns {{init: undefined, name: undefined, click: clickHandler, object: (jQuery|HTMLElement|jQuery.fn.init)}}\n */\n colorByCB(menuItem, showCheck) {\n const $e = $$1(createCheckbox(menuItem.label, showCheck));\n const clickHandler = (ev) => {\n\n if (menuItem.key !== 'tag') {\n if (menuItem.key === this.alignmentTrack.colorBy) {\n this.alignmentTrack.colorBy = 'none';\n this.config.colorBy = 'none';\n this.trackView.repaintViews();\n } else {\n this.alignmentTrack.colorBy = menuItem.key;\n this.config.colorBy = menuItem.key;\n this.trackView.repaintViews();\n }\n } else {\n this.browser.inputDialog.present({\n label: 'Tag Name',\n value: this.alignmentTrack.colorByTag ? this.alignmentTrack.colorByTag : '',\n callback: (tag) => {\n if (tag) {\n this.alignmentTrack.colorBy = 'tag';\n this.alignmentTrack.colorByTag = tag;\n if (!this.alignmentTrack.tagColors) {\n this.alignmentTrack.tagColors = new PaletteColorTable(\"Set1\");\n }\n } else {\n this.alignmentTrack.colorBy = 'none';\n this.alignmentTrack.colorByTag = '';\n }\n this.trackView.repaintViews();\n }\n }, ev);\n\n }\n\n };\n\n return {name: undefined, object: $e, click: clickHandler, init: undefined}\n }\n\n /**\n * Return the current state of the track. Used to create sessions and bookmarks.\n *\n * @returns {*|{}}\n */\n getState() {\n\n const config = super.getState();\n\n if (this.sortObject) {\n config.sort = {\n chr: this.sortObject.chr,\n position: this.sortObject.position + 1,\n option: this.sortObject.option,\n direction: this.sortObject.direction ? \"ASC\" : \"DESC\"\n };\n }\n\n return config\n }\n\n getCachedAlignmentContainers() {\n return this.trackView.viewports.map(vp => vp.cachedFeatures)\n }\n\n get dataRange() {\n return this.coverageTrack.dataRange\n }\n\n set dataRange(dataRange) {\n this.coverageTrack.dataRange = dataRange;\n }\n\n get logScale() {\n return this.coverageTrack.logScale\n }\n\n set logScale(logScale) {\n this.coverageTrack.logScale = logScale;\n }\n\n get autoscale() {\n return this.coverageTrack.autoscale\n }\n\n set autoscale(autoscale) {\n this.coverageTrack.autoscale = autoscale;\n }\n\n /**\n * Add chords to the circular view for the given viewport, represented by its reference frame\n * @param refFrame\n */\n addPairedChordsForViewport(viewport) {\n\n const maxTemplateLength = this.maxTemplateLength;\n const inView = [];\n const refFrame = viewport.referenceFrame;\n for (let a of viewport.cachedFeatures.allAlignments()) {\n if (a.end >= refFrame.start\n && a.start <= refFrame.end) {\n if (a.paired) {\n if (a.end - a.start > maxTemplateLength) {\n inView.push(a);\n }\n } else {\n if (a.mate\n && a.mate.chr\n && (a.mate.chr !== a.chr || Math.max(a.fragmentLength) > maxTemplateLength)) {\n inView.push(a);\n }\n }\n }\n }\n const chords = makePairedAlignmentChords(inView);\n sendChords(chords, this, refFrame, 0.02);\n }\n\n addSplitChordsForViewport(viewport) {\n\n const inView = [];\n const refFrame = viewport.referenceFrame;\n for (let a of viewport.cachedFeatures.allAlignments()) {\n\n const sa = a.hasTag('SA');\n if (a.end >= refFrame.start && a.start <= refFrame.end && sa) {\n inView.push(a);\n }\n }\n\n const chords = makeSupplementalAlignmentChords(inView);\n sendChords(chords, this, refFrame, 0.02);\n }\n}\n\n\nclass CoverageTrack {\n\n constructor(config, parent) {\n this.parent = parent;\n this.featureSource = parent.featureSource;\n\n this.paintAxis = paintAxis;\n this.top = 0;\n\n this.autoscale = config.autoscale || config.max === undefined;\n if (!this.autoscale) {\n this.dataRange = {\n min: config.min || 0,\n max: config.max\n };\n }\n\n }\n\n get height() {\n return this.parent.coverageTrackHeight\n }\n\n draw(options) {\n\n const pixelTop = options.pixelTop;\n pixelTop + options.pixelHeight;\n const nucleotideColors = this.parent.browser.nucleotideColors;\n\n if (pixelTop > this.height) {\n return //scrolled out of view\n }\n\n const ctx = options.context;\n const alignmentContainer = options.features;\n const coverageMap = alignmentContainer.coverageMap;\n\n let sequence;\n if (coverageMap.refSeq) {\n sequence = coverageMap.refSeq.toUpperCase();\n }\n\n const bpPerPixel = options.bpPerPixel;\n const bpStart = options.bpStart;\n const pixelWidth = options.pixelWidth;\n const bpEnd = bpStart + pixelWidth * bpPerPixel + 1;\n\n // paint for all coverage buckets\n // If alignment track color is != default, use it\n let color;\n if (this.parent.coverageColor) {\n color = this.parent.coverageColor;\n } else if (this.parent.color && typeof this.parent.color !== \"function\") {\n color = IGVColor.darkenLighten(this.parent.color, -35);\n } else {\n color = DEFAULT_COVERAGE_COLOR;\n }\n IGVGraphics.setProperties(ctx, {\n fillStyle: color,\n strokeStyle: color\n });\n\n const w = Math.max(1, Math.ceil(1.0 / bpPerPixel));\n for (let i = 0, len = coverageMap.coverage.length; i < len; i++) {\n\n const bp = (coverageMap.bpStart + i);\n if (bp < bpStart) continue\n if (bp > bpEnd) break\n\n const item = coverageMap.coverage[i];\n if (!item) continue\n\n const h = Math.round((item.total / this.dataRange.max) * this.height);\n const y = this.height - h;\n const x = Math.floor((bp - bpStart) / bpPerPixel);\n\n\n // IGVGraphics.setProperties(ctx, {fillStyle: \"rgba(0, 200, 0, 0.25)\", strokeStyle: \"rgba(0, 200, 0, 0.25)\" });\n IGVGraphics.fillRect(ctx, x, y, w, h);\n }\n\n // coverage mismatch coloring -- don't try to do this in above loop, color bar will be overwritten when w<1\n if (sequence) {\n for (let i = 0, len = coverageMap.coverage.length; i < len; i++) {\n\n const bp = (coverageMap.bpStart + i);\n if (bp < bpStart) continue\n if (bp > bpEnd) break\n\n const item = coverageMap.coverage[i];\n if (!item) continue\n\n const h = (item.total / this.dataRange.max) * this.height;\n let y = this.height - h;\n const x = Math.floor((bp - bpStart) / bpPerPixel);\n\n const refBase = sequence[i];\n if (item.isMismatch(refBase)) {\n IGVGraphics.setProperties(ctx, {fillStyle: nucleotideColors[refBase]});\n IGVGraphics.fillRect(ctx, x, y, w, h);\n\n let accumulatedHeight = 0.0;\n for (let nucleotide of [\"A\", \"C\", \"T\", \"G\"]) {\n\n const count = item[\"pos\" + nucleotide] + item[\"neg\" + nucleotide];\n\n // non-logoritmic\n const hh = (count / this.dataRange.max) * this.height;\n y = (this.height - hh) - accumulatedHeight;\n accumulatedHeight += hh;\n IGVGraphics.setProperties(ctx, {fillStyle: nucleotideColors[nucleotide]});\n IGVGraphics.fillRect(ctx, x, y, w, hh);\n }\n }\n }\n }\n }\n\n getClickedObject(clickState) {\n\n let features = clickState.viewport.cachedFeatures;\n if (!features || features.length === 0) return\n\n const genomicLocation = Math.floor(clickState.genomicLocation);\n const coverageMap = features.coverageMap;\n const coverageMapIndex = Math.floor(genomicLocation - coverageMap.bpStart);\n return coverageMap.coverage[coverageMapIndex]\n }\n\n popupData(clickState) {\n\n const nameValues = [];\n\n const coverage = this.getClickedObject(clickState);\n if (coverage) {\n const genomicLocation = Math.floor(clickState.genomicLocation);\n const referenceFrame = clickState.viewport.referenceFrame;\n\n nameValues.push(referenceFrame.chr + \":\" + numberFormatter$1(1 + genomicLocation));\n\n nameValues.push({name: 'Total Count', value: coverage.total});\n\n // A\n let tmp = coverage.posA + coverage.negA;\n if (tmp > 0) tmp = tmp.toString() + \" (\" + Math.round((tmp / coverage.total) * 100.0) + \"%, \" + coverage.posA + \"+, \" + coverage.negA + \"- )\";\n nameValues.push({name: 'A', value: tmp});\n\n // C\n tmp = coverage.posC + coverage.negC;\n if (tmp > 0) tmp = tmp.toString() + \" (\" + Math.round((tmp / coverage.total) * 100.0) + \"%, \" + coverage.posC + \"+, \" + coverage.negC + \"- )\";\n nameValues.push({name: 'C', value: tmp});\n\n // G\n tmp = coverage.posG + coverage.negG;\n if (tmp > 0) tmp = tmp.toString() + \" (\" + Math.round((tmp / coverage.total) * 100.0) + \"%, \" + coverage.posG + \"+, \" + coverage.negG + \"- )\";\n nameValues.push({name: 'G', value: tmp});\n\n // T\n tmp = coverage.posT + coverage.negT;\n if (tmp > 0) tmp = tmp.toString() + \" (\" + Math.round((tmp / coverage.total) * 100.0) + \"%, \" + coverage.posT + \"+, \" + coverage.negT + \"- )\";\n nameValues.push({name: 'T', value: tmp});\n\n // N\n tmp = coverage.posN + coverage.negN;\n if (tmp > 0) tmp = tmp.toString() + \" (\" + Math.round((tmp / coverage.total) * 100.0) + \"%, \" + coverage.posN + \"+, \" + coverage.negN + \"- )\";\n nameValues.push({name: 'N', value: tmp});\n\n nameValues.push('
');\n nameValues.push({name: 'DEL', value: coverage.del.toString()});\n nameValues.push({name: 'INS', value: coverage.ins.toString()});\n }\n\n return nameValues\n\n }\n\n}\n\nclass AlignmentTrack {\n\n constructor(config, parent) {\n\n this.parent = parent;\n this.browser = parent.browser;\n this.featureSource = parent.featureSource;\n this.top = 0 === config.coverageTrackHeight ? 0 : config.coverageTrackHeight + 5;\n this.displayMode = config.displayMode || \"EXPANDED\";\n this.alignmentRowHeight = config.alignmentRowHeight || 14;\n this.squishedRowHeight = config.squishedRowHeight || 3;\n\n this.negStrandColor = config.negStrandColor || \"rgba(150, 150, 230, 0.75)\";\n this.posStrandColor = config.posStrandColor || \"rgba(230, 150, 150, 0.75)\";\n this.insertionColor = config.insertionColor || \"rgb(138, 94, 161)\";\n this.insertionTextColor = config.insertionTextColor || \"white\";\n this.showInsertionText = config.showInsertionText === undefined ? false : !!config.showInsertionText;\n this.deletionColor = config.deletionColor || \"black\";\n this.deletionTextColor = config.deletionTextColor || \"black\";\n this.showDeletionText = config.showDeletionText === undefined ? false : !!config.showDeletionText;\n this.skippedColor = config.skippedColor || \"rgb(150, 170, 170)\";\n this.pairConnectorColor = config.pairConnectorColor;\n\n this.smallTLENColor = config.smallTLENColor || config.smallFragmentLengthColor || \"rgb(0, 0, 150)\";\n this.largeTLENColor = config.largeTLENColor || config.largeFragmentLengthColor || \"rgb(200, 0, 0)\";\n\n this.pairOrientation = config.pairOrienation || 'fr';\n this.pairColors = {};\n this.pairColors[\"RL\"] = config.rlColor || \"rgb(0, 150, 0)\";\n this.pairColors[\"RR\"] = config.rrColor || \"rgb(20, 50, 200)\";\n this.pairColors[\"LL\"] = config.llColor || \"rgb(0, 150, 150)\";\n\n this.colorBy = config.colorBy || \"unexpectedPair\";\n this.colorByTag = config.colorByTag ? config.colorByTag.toUpperCase() : undefined;\n this.bamColorTag = config.bamColorTag === undefined ? \"YC\" : config.bamColorTag;\n\n this.hideSmallIndels = config.hideSmallIndels;\n this.indelSizeThreshold = config.indelSizeThreshold || 1;\n\n this.hasPairs = false; // Until proven otherwise\n this.hasSupplemental = false;\n }\n\n setTop(coverageTrack, showCoverage) {\n this.top = (0 === coverageTrack.height || false === showCoverage) ? 0 : (5 + coverageTrack.height);\n }\n\n /**\n * Compute the pixel height required to display all content.\n *\n * @param alignmentContainer\n * @returns {number|*}\n */\n computePixelHeight(alignmentContainer) {\n\n if (alignmentContainer.packedAlignmentRows) {\n const h = alignmentContainer.hasDownsampledIntervals() ? downsampleRowHeight + alignmentStartGap : 0;\n const alignmentRowHeight = this.displayMode === \"SQUISHED\" ?\n this.squishedRowHeight :\n this.alignmentRowHeight;\n return h + (alignmentRowHeight * alignmentContainer.packedAlignmentRows.length) + 5\n } else {\n return 0\n }\n }\n\n draw(options) {\n\n const alignmentContainer = options.features;\n const ctx = options.context;\n const bpPerPixel = options.bpPerPixel;\n const bpStart = options.bpStart;\n const pixelWidth = options.pixelWidth;\n const bpEnd = bpStart + pixelWidth * bpPerPixel + 1;\n const showSoftClips = this.parent.showSoftClips;\n const showAllBases = this.parent.showAllBases;\n const nucleotideColors = this.browser.nucleotideColors;\n\n //alignmentContainer.repack(bpPerPixel, showSoftClips);\n const packedAlignmentRows = alignmentContainer.packedAlignmentRows;\n\n\n ctx.save();\n\n let referenceSequence = alignmentContainer.sequence;\n if (referenceSequence) {\n referenceSequence = referenceSequence.toUpperCase();\n }\n let alignmentRowYInset = 0;\n\n let pixelTop = options.pixelTop;\n if (this.top) {\n ctx.translate(0, this.top);\n }\n const pixelBottom = pixelTop + options.pixelHeight;\n\n if (alignmentContainer.hasDownsampledIntervals()) {\n alignmentRowYInset = downsampleRowHeight + alignmentStartGap;\n\n alignmentContainer.downsampledIntervals.forEach(function (interval) {\n var xBlockStart = (interval.start - bpStart) / bpPerPixel,\n xBlockEnd = (interval.end - bpStart) / bpPerPixel;\n\n if (xBlockEnd - xBlockStart > 5) {\n xBlockStart += 1;\n xBlockEnd -= 1;\n }\n IGVGraphics.fillRect(ctx, xBlockStart, 2, (xBlockEnd - xBlockStart), downsampleRowHeight - 2, {fillStyle: \"black\"});\n });\n\n } else {\n alignmentRowYInset = 0;\n }\n\n // Transient variable -- rewritten on every draw, used for click object selection\n this.alignmentsYOffset = alignmentRowYInset;\n const alignmentRowHeight = this.displayMode === \"SQUISHED\" ?\n this.squishedRowHeight :\n this.alignmentRowHeight;\n\n if (packedAlignmentRows) {\n\n const nRows = packedAlignmentRows.length;\n\n for (let rowIndex = 0; rowIndex < nRows; rowIndex++) {\n\n const alignmentRow = packedAlignmentRows[rowIndex];\n const alignmentY = alignmentRowYInset + (alignmentRowHeight * rowIndex);\n const alignmentHeight = alignmentRowHeight <= 4 ? alignmentRowHeight : alignmentRowHeight - 2;\n\n if (alignmentY > pixelBottom) {\n break\n } else if (alignmentY + alignmentHeight < pixelTop) {\n continue\n }\n\n for (let alignment of alignmentRow.alignments) {\n\n this.hasPairs = this.hasPairs || alignment.isPaired();\n if (this.browser.circularView) {\n // This is an expensive check, only do it if needed\n this.hasSupplemental = this.hasSupplemental || alignment.hasTag('SA');\n }\n\n if ((alignment.start + alignment.lengthOnRef) < bpStart) continue\n if (alignment.start > bpEnd) break\n if (true === alignment.hidden) {\n continue\n }\n\n if (alignment instanceof PairedAlignment) {\n\n drawPairConnector.call(this, alignment, alignmentY, alignmentHeight);\n\n drawSingleAlignment.call(this, alignment.firstAlignment, alignmentY, alignmentHeight);\n\n if (alignment.secondAlignment) {\n drawSingleAlignment.call(this, alignment.secondAlignment, alignmentY, alignmentHeight);\n }\n\n } else {\n drawSingleAlignment.call(this, alignment, alignmentY, alignmentHeight);\n }\n\n }\n }\n }\n ctx.restore();\n\n // alignment is a PairedAlignment\n function drawPairConnector(alignment, yRect, alignmentHeight) {\n\n var connectorColor = this.getConnectorColor(alignment.firstAlignment),\n xBlockStart = (alignment.connectingStart - bpStart) / bpPerPixel,\n xBlockEnd = (alignment.connectingEnd - bpStart) / bpPerPixel,\n yStrokedLine = yRect + alignmentHeight / 2;\n\n if ((alignment.connectingEnd) < bpStart || alignment.connectingStart > bpEnd) {\n return\n }\n if (alignment.mq <= 0) {\n connectorColor = IGVColor.addAlpha(connectorColor, 0.15);\n }\n IGVGraphics.setProperties(ctx, {fillStyle: connectorColor, strokeStyle: connectorColor});\n IGVGraphics.strokeLine(ctx, xBlockStart, yStrokedLine, xBlockEnd, yStrokedLine);\n\n }\n\n function drawSingleAlignment(alignment, yRect, alignmentHeight) {\n\n\n if ((alignment.start + alignment.lengthOnRef) < bpStart || alignment.start > bpEnd) {\n return\n }\n\n const blocks = showSoftClips ? alignment.blocks : alignment.blocks.filter(b => 'S' !== b.type);\n\n let alignmentColor = this.getAlignmentColor(alignment);\n const outlineColor = alignmentColor;\n if (alignment.mq <= 0) {\n alignmentColor = IGVColor.addAlpha(alignmentColor, 0.15);\n }\n IGVGraphics.setProperties(ctx, {fillStyle: alignmentColor, strokeStyle: outlineColor});\n\n // Save bases to draw into an array for later drawing, so they can be overlaid on insertion blocks,\n // which is relevant if we have insertions with size label\n const basesToDraw = [];\n\n for (let b = 0; b < blocks.length; b++) { // Can't use forEach here -- we need ability to break\n\n const block = blocks[b];\n\n // Somewhat complex test, neccessary to insure gaps are drawn.\n // If this is not the last block, and the next block starts before the orign (off screen to left) then skip.\n if ((b !== blocks.length - 1) && blocks[b + 1].start < bpStart) continue\n\n // drawBlock returns bases to draw, which are drawn on top of insertion blocks (if they're wider than\n // the space between two bases) like in Java IGV\n basesToDraw.push(...drawBlock.call(this, block, b));\n\n if ((block.start + block.len) > bpEnd) {\n // Do this after drawBlock to insure gaps are drawn\n break\n }\n }\n\n if (alignment.gaps) {\n const yStrokedLine = yRect + alignmentHeight / 2;\n for (let gap of alignment.gaps) {\n const sPixel = (gap.start - bpStart) / bpPerPixel;\n const ePixel = ((gap.start + gap.len) - bpStart) / bpPerPixel;\n const lineWidth = ePixel - sPixel;\n const gapLenText = gap.len.toString();\n const gapTextWidth = gapLenText.length * 6;\n const gapCenter = sPixel + (lineWidth / 2);\n\n const color = (\"D\" === gap.type) ? this.deletionColor : this.skippedColor;\n\n IGVGraphics.strokeLine(ctx, sPixel, yStrokedLine, ePixel, yStrokedLine, {\n strokeStyle: color,\n lineWidth: 2,\n });\n\n // Add gap width as text like Java IGV if it fits nicely and is a multi-base gap\n if (this.showDeletionText && gap.len > 1 && lineWidth >= gapTextWidth + 8) {\n const textStart = gapCenter - (gapTextWidth / 2);\n IGVGraphics.fillRect(ctx, textStart - 1, yRect - 1, gapTextWidth + 2, 12, {fillStyle: \"white\"});\n IGVGraphics.fillText(ctx, gapLenText, textStart, yRect + 10, {\n 'font': 'normal 10px monospace',\n 'fillStyle': this.deletionTextColor,\n });\n }\n }\n }\n\n if (alignment.insertions && this.parent.showInsertions) {\n let lastXBlockStart = -1;\n for (let insertionBlock of alignment.insertions) {\n if (this.hideSmallIndels && insertionBlock.len <= this.indelSizeThreshold) {\n continue\n }\n if (insertionBlock.start < bpStart) {\n continue\n }\n if (insertionBlock.start > bpEnd) {\n break\n }\n\n const refOffset = insertionBlock.start - bpStart;\n const insertLenText = insertionBlock.len.toString();\n\n const textPixelWidth = 2 + (insertLenText.length * 6);\n const basePixelWidth = (!this.showInsertionText || insertionBlock.len === 1)\n ? 2\n : Math.round(insertionBlock.len / bpPerPixel);\n const widthBlock = Math.max(Math.min(textPixelWidth, basePixelWidth), 2);\n\n const xBlockStart = (refOffset / bpPerPixel) - (widthBlock / 2);\n if ((xBlockStart - lastXBlockStart) > 2) {\n const props = {fillStyle: this.insertionColor};\n\n // Draw decorations like Java IGV to make an 'I' shape\n IGVGraphics.fillRect(ctx, xBlockStart - 2, yRect, widthBlock + 4, 2, props);\n IGVGraphics.fillRect(ctx, xBlockStart, yRect + 2, widthBlock, alignmentHeight - 4, props);\n IGVGraphics.fillRect(ctx, xBlockStart - 2, yRect + alignmentHeight - 2, widthBlock + 4, 2, props);\n\n // Show # of inserted bases as text if it's a multi-base insertion and the insertion block\n // is wide enough to hold text (its size is capped at the text label size, but can be smaller\n // if the browser is zoomed out and the insertion is small)\n if (this.showInsertionText && insertionBlock.len > 1 && basePixelWidth > textPixelWidth) {\n IGVGraphics.fillText(ctx, insertLenText, xBlockStart + 1, yRect + 10, {\n 'font': 'normal 10px monospace',\n 'fillStyle': this.insertionTextColor,\n });\n }\n lastXBlockStart = xBlockStart;\n }\n }\n }\n\n basesToDraw.forEach(({bbox, baseColor, readChar}) => {\n renderBlockOrReadChar(ctx, bpPerPixel, bbox, baseColor, readChar);\n });\n\n\n function drawBlock(block, b) {\n // Collect bases to draw for later rendering\n const blockBasesToDraw = [];\n\n const offsetBP = block.start - alignmentContainer.start;\n const blockStartPixel = (block.start - bpStart) / bpPerPixel;\n const blockEndPixel = ((block.start + block.len) - bpStart) / bpPerPixel;\n const blockWidthPixel = Math.max(1, blockEndPixel - blockStartPixel);\n\n //const arrowHeadWidthPixel = alignmentRowHeight / 2.0;\n const nomPixelWidthOnRef = 100 / bpPerPixel;\n const arrowHeadWidthPixel = Math.min(alignmentRowHeight / 2.0, nomPixelWidthOnRef / 6);\n\n const isSoftClip = 'S' === block.type;\n\n const strokeOutline =\n alignment.mq <= 0 ||\n this.highlightedAlignmentReadNamed === alignment.readName ||\n isSoftClip;\n\n let blockOutlineColor = outlineColor;\n if (this.highlightedAlignmentReadNamed === alignment.readName) blockOutlineColor = 'red';\n else if (isSoftClip) blockOutlineColor = 'rgb(50,50,50)';\n\n const lastBlockPositiveStrand = (true === alignment.strand && b === blocks.length - 1);\n const lastBlockReverseStrand = (false === alignment.strand && b === 0);\n const lastBlock = lastBlockPositiveStrand | lastBlockReverseStrand;\n\n if (lastBlock) {\n let xListPixel;\n let yListPixel;\n if (lastBlockPositiveStrand) {\n xListPixel = [\n blockStartPixel,\n blockEndPixel,\n blockEndPixel + arrowHeadWidthPixel,\n blockEndPixel,\n blockStartPixel,\n blockStartPixel];\n yListPixel = [\n yRect,\n yRect,\n yRect + (alignmentHeight / 2.0),\n yRect + alignmentHeight,\n yRect + alignmentHeight,\n yRect];\n\n }\n\n // Last block on - strand ?\n else if (lastBlockReverseStrand) {\n xListPixel = [\n blockEndPixel,\n blockStartPixel,\n blockStartPixel - arrowHeadWidthPixel,\n blockStartPixel,\n blockEndPixel,\n blockEndPixel];\n yListPixel = [\n yRect,\n yRect,\n yRect + (alignmentHeight / 2.0),\n yRect + alignmentHeight,\n yRect + alignmentHeight,\n yRect];\n\n }\n IGVGraphics.fillPolygon(ctx, xListPixel, yListPixel, {fillStyle: alignmentColor});\n\n if (strokeOutline) {\n IGVGraphics.strokePolygon(ctx, xListPixel, yListPixel, {strokeStyle: blockOutlineColor});\n }\n }\n\n // Internal block\n else {\n IGVGraphics.fillRect(ctx, blockStartPixel, yRect, blockWidthPixel, alignmentHeight, {fillStyle: alignmentColor});\n\n if (strokeOutline) {\n ctx.save();\n ctx.strokeStyle = blockOutlineColor;\n ctx.strokeRect(blockStartPixel, yRect, blockWidthPixel, alignmentHeight);\n ctx.restore();\n }\n }\n\n\n // Read base coloring\n\n if (isSoftClip ||\n showAllBases ||\n this.parent.showMismatches && (referenceSequence && alignment.seq && alignment.seq !== \"*\")) {\n\n const seq = alignment.seq ? alignment.seq.toUpperCase() : undefined;\n const qual = alignment.qual;\n const seqOffset = block.seqOffset;\n const widthPixel = Math.max(1, 1 / bpPerPixel);\n\n\n for (let i = 0, len = block.len; i < len; i++) {\n\n const xPixel = ((block.start + i) - bpStart) / bpPerPixel;\n\n if (xPixel + widthPixel < 0) continue // Off left edge\n if (xPixel > pixelWidth) break // Off right edge\n\n let readChar = seq ? seq.charAt(seqOffset + i) : '';\n const refChar = offsetBP + i >= 0 ? referenceSequence.charAt(offsetBP + i) : '';\n\n if (readChar === \"=\") {\n readChar = refChar;\n }\n if (readChar === \"X\" || refChar !== readChar || isSoftClip || showAllBases) {\n\n let baseColor;\n if (!isSoftClip && qual !== undefined && qual.length > seqOffset + i) {\n const readQual = qual[seqOffset + i];\n baseColor = shadedBaseColor(readQual, nucleotideColors[readChar]);\n } else {\n baseColor = nucleotideColors[readChar];\n }\n if (baseColor) {\n blockBasesToDraw.push({\n bbox: {\n x: xPixel,\n y: yRect,\n width: widthPixel,\n height: alignmentHeight\n },\n baseColor,\n readChar,\n });\n }\n }\n }\n }\n\n return blockBasesToDraw\n }\n\n function renderBlockOrReadChar(context, bpp, bbox, color, char) {\n var threshold,\n center;\n\n threshold = 1.0 / 10.0;\n if (bpp <= threshold && bbox.height >= 8) {\n\n // render letter\n const fontHeight = Math.min(10, bbox.height);\n context.font = '' + fontHeight + 'px sans-serif';\n center = bbox.x + (bbox.width / 2.0);\n IGVGraphics.strokeText(context, char, center - (context.measureText(char).width / 2), fontHeight - 1 + bbox.y, {strokeStyle: color});\n } else {\n\n // render colored block\n IGVGraphics.fillRect(context, bbox.x, bbox.y, bbox.width, bbox.height, {fillStyle: color});\n }\n }\n }\n\n };\n\n popupData(clickState) {\n const clickedObject = this.getClickedObject(clickState);\n return clickedObject ? clickedObject.popupData(clickState.genomicLocation) : undefined\n };\n\n contextMenuItemList(clickState) {\n\n const viewport = clickState.viewport;\n const list = [];\n\n const sortByOption = (option) => {\n const cs = this.parent.sortObject;\n const direction = (cs && cs.position === Math.floor(clickState.genomicLocation)) ? !cs.direction : true;\n const newSortObject = {\n chr: viewport.referenceFrame.chr,\n position: Math.floor(clickState.genomicLocation),\n option: option,\n direction: direction\n };\n this.parent.sortObject = newSortObject;\n viewport.cachedFeatures.sortRows(newSortObject);\n viewport.repaint();\n };\n list.push('Sort by...');\n list.push({label: '  base', click: () => sortByOption(\"BASE\")});\n list.push({label: '  read strand', click: () => sortByOption(\"STRAND\")});\n list.push({label: '  insert size', click: () => sortByOption(\"INSERT_SIZE\")});\n list.push({label: '  gap size', click: () => sortByOption(\"GAP_SIZE\")});\n list.push({label: '  chromosome of mate', click: () => sortByOption(\"MATE_CHR\")});\n list.push({label: '  mapping quality', click: () => sortByOption(\"MQ\")});\n list.push({label: '  read name', click: () => sortByOption(\"READ_NAME\")});\n list.push({label: '  aligned read length', click: () => sortByOption(\"ALIGNED_READ_LENGTH\")});\n list.push({\n label: '  tag', click: () => {\n const cs = this.parent.sortObject;\n const direction = (cs && cs.position === Math.floor(clickState.genomicLocation)) ? !cs.direction : true;\n const config =\n {\n label: 'Tag Name',\n value: this.sortByTag ? this.sortByTag : '',\n callback: (tag) => {\n if (tag) {\n const newSortObject = {\n chr: viewport.referenceFrame.chr,\n position: Math.floor(clickState.genomicLocation),\n option: \"TAG\",\n tag: tag,\n direction: direction\n };\n this.sortByTag = tag;\n this.parent.sortObject = newSortObject;\n viewport.cachedFeatures.sortRows(newSortObject);\n viewport.repaint();\n }\n }\n };\n this.browser.inputDialog.present(config, clickState.event);\n }\n });\n list.push('
');\n\n const clickedObject = this.getClickedObject(clickState);\n\n if (clickedObject) {\n\n const showSoftClips = this.parent.showSoftClips;\n const clickedAlignment = (typeof clickedObject.alignmentContaining === 'function') ?\n clickedObject.alignmentContaining(clickState.genomicLocation, showSoftClips) :\n clickedObject;\n if (clickedAlignment) {\n if (clickedAlignment.isPaired() && clickedAlignment.isMateMapped()) {\n list.push({\n label: 'View mate in split screen',\n click: () => {\n if (clickedAlignment.mate) {\n const referenceFrame = clickState.viewport.referenceFrame;\n if (this.browser.genome.getChromosome(clickedAlignment.mate.chr)) {\n this.highlightedAlignmentReadNamed = clickedAlignment.readName;\n //this.browser.presentMultiLocusPanel(clickedAlignment, referenceFrame)\n const bpWidth = referenceFrame.end - referenceFrame.start;\n const frameStart = clickedAlignment.mate.position - bpWidth / 2;\n const frameEnd = clickedAlignment.mate.position + bpWidth / 2;\n this.browser.addMultiLocusPanel(clickedAlignment.mate.chr, frameStart, frameEnd, referenceFrame);\n } else {\n this.browser.alert.present(`Reference does not contain chromosome: ${clickedAlignment.mate.chr}`);\n }\n }\n },\n init: undefined\n });\n }\n\n list.push({\n label: 'View read sequence',\n click: () => {\n const seqstring = clickedAlignment.seq; //.map(b => String.fromCharCode(b)).join(\"\");\n if (!seqstring || \"*\" === seqstring) {\n this.browser.alert.present(\"Read sequence: *\");\n } else {\n this.browser.alert.present(seqstring);\n }\n }\n });\n\n if (isSecureContext()) {\n list.push({\n label: 'Copy read sequence',\n click: async () => {\n const seq = clickedAlignment.seq; //.map(b => String.fromCharCode(b)).join(\"\");\n try {\n //console.log(`seq: ${seq}`)\n await navigator.clipboard.writeText(seq);\n } catch (e) {\n console.error(e);\n this.browser.alert.present(`error copying sequence to clipboard ${e}`);\n }\n\n }\n });\n }\n\n // TODO if genome supports blat\n const seqstring = clickedAlignment.seq;\n if (seqstring && \"*\" != seqstring) {\n\n if (seqstring.length < maxSequenceSize) {\n list.push({\n label: 'BLAT read sequence',\n click: () => {\n const sequence = clickedAlignment.isNegativeStrand() ? reverseComplementSequence(seqstring) : seqstring;\n const name = `${clickedAlignment.readName} - blat`;\n const title = `${this.parent.name} - ${name}`;\n createBlatTrack({sequence, browser: this.browser, name, title});\n }\n });\n }\n\n const softClips = clickedAlignment.softClippedBlocks();\n if (softClips.left && softClips.left.len > MINIMUM_BLAT_LENGTH && softClips.left.len < maxSequenceSize) {\n list.push({\n label: 'BLAT left soft-clipped sequence',\n click: () => {\n const clippedSequence = seqstring.substr(softClips.left.seqOffset, softClips.left.len);\n const sequence = clickedAlignment.isNegativeStrand() ? reverseComplementSequence(clippedSequence) : clippedSequence;\n const name = `${clickedAlignment.readName} - blat left clip`;\n const title = `${this.parent.name} - ${name}`;\n createBlatTrack({sequence, browser: this.browser, name, title});\n }\n });\n }\n if (softClips.right && softClips.right.len > MINIMUM_BLAT_LENGTH && softClips.right.len < maxSequenceSize) {\n list.push({\n label: 'BLAT right soft-clipped sequence',\n click: () => {\n const clippedSequence = seqstring.substr(softClips.right.seqOffset, softClips.right.len);\n const sequence = clickedAlignment.isNegativeStrand() ? reverseComplementSequence(clippedSequence) : clippedSequence;\n const name = `${clickedAlignment.readName} - blat right clip`;\n const title = `${this.parent.name} - ${name}`;\n createBlatTrack({sequence, browser: this.browser, name, title});\n }\n });\n }\n }\n\n list.push('
');\n }\n }\n\n // Experimental JBrowse feature\n if (this.browser.circularView && (this.hasPairs || this.hasSupplemental)) {\n if (this.hasPairs) {\n list.push({\n label: 'Add discordant pairs to circular view',\n click: () => {\n this.parent.addPairedChordsForViewport(viewport);\n }\n });\n }\n if (this.hasSupplemental) {\n list.push({\n label: 'Add split reads to circular view',\n click: () => {\n this.parent.addSplitChordsForViewport(viewport);\n }\n });\n }\n list.push('
');\n }\n\n return list\n\n }\n\n getClickedObject(clickState) {\n\n const viewport = clickState.viewport;\n const y = clickState.y;\n const genomicLocation = clickState.genomicLocation;\n\n const showSoftClips = this.parent.showSoftClips;\n\n let features = viewport.cachedFeatures;\n if (!features || features.length === 0) return\n\n let packedAlignmentRows = features.packedAlignmentRows;\n let downsampledIntervals = features.downsampledIntervals;\n const alignmentRowHeight = this.displayMode === \"SQUISHED\" ?\n this.squishedRowHeight :\n this.alignmentRowHeight;\n\n let packedAlignmentsIndex = Math.floor((y - this.top - this.alignmentsYOffset) / alignmentRowHeight);\n\n if (packedAlignmentsIndex < 0) {\n for (let i = 0; i < downsampledIntervals.length; i++) {\n if (downsampledIntervals[i].start <= genomicLocation && (downsampledIntervals[i].end >= genomicLocation)) {\n return downsampledIntervals[i]\n }\n }\n } else if (packedAlignmentsIndex < packedAlignmentRows.length) {\n const alignmentRow = packedAlignmentRows[packedAlignmentsIndex];\n const clicked = alignmentRow.alignments.filter(alignment => alignment.containsLocation(genomicLocation, showSoftClips));\n if (clicked.length > 0) return clicked[0]\n }\n\n return undefined\n\n };\n\n /**\n * Return the color for connectors in paired alignment view. If explicitly set return that, otherwise return\n * the alignment color, unless the color option can result in split colors (separte color for each mate).\n *\n * @param alignment\n * @returns {string}\n */\n getConnectorColor(alignment) {\n\n if (this.pairConnectorColor) {\n return this.pairConnectorColor\n }\n\n switch (this.colorBy) {\n case \"strand\":\n case \"firstOfPairStrand\":\n case \"pairOrientation\":\n case \"tag\":\n if (this.parent.color) {\n return (typeof this.parent.color === \"function\") ? this.parent.color(alignment) : this.parent.color\n } else {\n return DEFAULT_CONNECTOR_COLOR\n }\n default:\n return this.getAlignmentColor(alignment)\n\n }\n }\n\n getAlignmentColor(alignment) {\n\n let color = DEFAULT_ALIGNMENT_COLOR; // The default color if nothing else applies\n if (this.parent.color) {\n color = (typeof this.parent.color === \"function\") ? this.parent.color(alignment) : this.parent.color;\n } else {\n color = DEFAULT_ALIGNMENT_COLOR;\n }\n const option = this.colorBy;\n switch (option) {\n case \"strand\":\n color = alignment.strand ? this.posStrandColor : this.negStrandColor;\n break\n\n case \"firstOfPairStrand\":\n\n if (alignment instanceof PairedAlignment) {\n color = alignment.firstOfPairStrand() ? this.posStrandColor : this.negStrandColor;\n } else if (alignment.isPaired()) {\n\n if (alignment.isFirstOfPair()) {\n color = alignment.strand ? this.posStrandColor : this.negStrandColor;\n } else if (alignment.isSecondOfPair()) {\n color = alignment.strand ? this.negStrandColor : this.posStrandColor;\n } else {\n console.error(\"ERROR. Paired alignments are either first or second.\");\n }\n }\n break\n\n case \"unexpectedPair\":\n case \"pairOrientation\":\n\n if (this.pairOrientation && alignment.pairOrientation) {\n const oTypes = orientationTypes[this.pairOrientation];\n if (oTypes) {\n const pairColor = this.pairColors[oTypes[alignment.pairOrientation]];\n if (pairColor) {\n color = pairColor;\n break\n }\n }\n }\n if (\"pairOrientation\" === option) {\n break\n }\n\n case \"tlen\":\n case \"fragmentLength\":\n\n if (alignment.mate && alignment.isMateMapped()) {\n if (alignment.mate.chr !== alignment.chr) {\n color = getChrColor(alignment.mate.chr);\n } else if (this.parent.minTemplateLength && Math.abs(alignment.fragmentLength) < this.parent.minTemplateLength) {\n color = this.smallTLENColor;\n } else if (this.parent.maxTemplateLength && Math.abs(alignment.fragmentLength) > this.parent.maxTemplateLength) {\n color = this.largeTLENColor;\n }\n }\n break\n\n case \"tag\":\n const tagValue = alignment.tags()[this.colorByTag];\n if (tagValue !== undefined) {\n if (this.bamColorTag === this.colorByTag) {\n // UCSC style color option\n color = \"rgb(\" + tagValue + \")\";\n } else {\n\n if (!this.tagColors) {\n this.tagColors = new PaletteColorTable(\"Set1\");\n }\n color = this.tagColors.getColor(tagValue);\n }\n }\n break\n }\n\n return color\n\n }\n}\n\nfunction shadedBaseColor(qual, baseColor) {\n\n const minQ = 5; //prefs.getAsInt(PreferenceManager.SAM_BASE_QUALITY_MIN),\n const maxQ = 20; //prefs.getAsInt(PreferenceManager.SAM_BASE_QUALITY_MAX);\n\n let alpha;\n if (qual < minQ) {\n alpha = 0.1;\n } else {\n alpha = Math.max(0.1, Math.min(1.0, 0.1 + 0.9 * (qual - minQ) / (maxQ - minQ)));\n }\n // Round alpha to nearest 0.1\n alpha = Math.round(alpha * 10) / 10.0;\n\n if (alpha < 1) {\n baseColor = IGVColor.addAlpha(baseColor, alpha);\n }\n return baseColor\n}\n\nconst orientationTypes = {\n\n \"fr\": {\n \"F1R2\": \"LR\",\n \"F2R1\": \"LR\",\n \"F1F2\": \"LL\",\n \"F2F1\": \"LL\",\n \"R1R2\": \"RR\",\n \"R2R1\": \"RR\",\n \"R1F2\": \"RL\",\n \"R2F1\": \"RL\"\n },\n\n \"rf\": {\n \"R1F2\": \"LR\",\n \"R2F1\": \"LR\",\n \"R1R2\": \"LL\",\n \"R2R1\": \"LL\",\n \"F1F2\": \"RR\",\n \"F2F1\": \"RR\",\n \"F1R2\": \"RL\",\n \"F2R1\": \"RL\"\n },\n\n \"ff\": {\n \"F2F1\": \"LR\",\n \"R1R2\": \"LR\",\n \"F2R1\": \"LL\",\n \"R1F2\": \"LL\",\n \"R2F1\": \"RR\",\n \"F1R2\": \"RR\",\n \"R2R1\": \"RL\",\n \"F1F2\": \"RL\"\n }\n};\n\nfunction getChrColor(chr) {\n if (chrColorMap[chr]) {\n return chrColorMap[chr]\n } else if (chrColorMap[\"chr\" + chr]) {\n const color = chrColorMap[\"chr\" + chr];\n chrColorMap[chr] = color;\n return color\n } else {\n const color = IGVColor.randomRGB(0, 255);\n chrColorMap[chr] = color;\n return color\n }\n}\n\nconst chrColorMap = {\n \"chrX\": \"rgb(204, 153, 0)\",\n \"chrY\": \"rgb(153, 204, 0)\",\n \"chrUn\": \"rgb(50, 50, 50)\",\n \"chr1\": \"rgb(80, 80, 255)\",\n \"chrI\": \"rgb(139, 155, 187)\",\n \"chr2\": \"rgb(206, 61, 50)\",\n \"chrII\": \"rgb(206, 61, 50)\",\n \"chr2a\": \"rgb(216, 71, 60)\",\n \"chr2b\": \"rgb(226, 81, 70)\",\n \"chr3\": \"rgb(116, 155, 88)\",\n \"chrIII\": \"rgb(116, 155, 88)\",\n \"chr4\": \"rgb(240, 230, 133)\",\n \"chrIV\": \"rgb(240, 230, 133)\",\n \"chr5\": \"rgb(70, 105, 131)\",\n \"chr6\": \"rgb(186, 99, 56)\",\n \"chr7\": \"rgb(93, 177, 221)\",\n \"chr8\": \"rgb(128, 34, 104)\",\n \"chr9\": \"rgb(107, 215, 107)\",\n \"chr10\": \"rgb(213, 149, 167)\",\n \"chr11\": \"rgb(146, 72, 34)\",\n \"chr12\": \"rgb(131, 123, 141)\",\n \"chr13\": \"rgb(199, 81, 39)\",\n \"chr14\": \"rgb(213, 143, 92)\",\n \"chr15\": \"rgb(122, 101, 165)\",\n \"chr16\": \"rgb(228, 175, 105)\",\n \"chr17\": \"rgb(59, 27, 83)\",\n \"chr18\": \"rgb(205, 222, 183)\",\n \"chr19\": \"rgb(97, 42, 121)\",\n \"chr20\": \"rgb(174, 31, 99)\",\n \"chr21\": \"rgb(231, 199, 111)\",\n \"chr22\": \"rgb(90, 101, 94)\",\n \"chr23\": \"rgb(204, 153, 0)\",\n \"chr24\": \"rgb(153, 204, 0)\",\n \"chr25\": \"rgb(51, 204, 0)\",\n \"chr26\": \"rgb(0, 204, 51)\",\n \"chr27\": \"rgb(0, 204, 153)\",\n \"chr28\": \"rgb(0, 153, 204)\",\n \"chr29\": \"rgb(10, 71, 255)\",\n \"chr30\": \"rgb(71, 117, 255)\",\n \"chr31\": \"rgb(255, 194, 10)\",\n \"chr32\": \"rgb(255, 209, 71)\",\n \"chr33\": \"rgb(153, 0, 51)\",\n \"chr34\": \"rgb(153, 26, 0)\",\n \"chr35\": \"rgb(153, 102, 0)\",\n \"chr36\": \"rgb(128, 153, 0)\",\n \"chr37\": \"rgb(51, 153, 0)\",\n \"chr38\": \"rgb(0, 153, 26)\",\n \"chr39\": \"rgb(0, 153, 102)\",\n \"chr40\": \"rgb(0, 128, 153)\",\n \"chr41\": \"rgb(0, 51, 153)\",\n \"chr42\": \"rgb(26, 0, 153)\",\n \"chr43\": \"rgb(102, 0, 153)\",\n \"chr44\": \"rgb(153, 0, 128)\",\n \"chr45\": \"rgb(214, 0, 71)\",\n \"chr46\": \"rgb(255, 20, 99)\",\n \"chr47\": \"rgb(0, 214, 143)\",\n \"chr48\": \"rgb(20, 255, 177)\",\n};\n\nlet timer;\nlet currentViewport = undefined;\nconst toolTipTimeout = 1e4;\n\nclass RulerViewport extends TrackViewport {\n\n constructor(trackView, $viewportColumn, referenceFrame, width) {\n super(trackView, $viewportColumn, referenceFrame, width);\n }\n\n get contentDiv() {\n return this.$viewport.get(0)\n }\n\n initializationHelper() {\n\n this.$multiLocusCloseButton = $$1('
', {class: 'igv-multi-locus-close-button'});\n this.$viewport.append(this.$multiLocusCloseButton);\n this.$multiLocusCloseButton.get(0).appendChild(icons$1.createIcon(\"times-circle\"));\n\n this.$multiLocusCloseButton.click(() => {\n this.browser.removeMultiLocusPanel(this.referenceFrame);\n });\n\n this.$rulerLabel = $$1('
', {class: 'igv-multi-locus-ruler-label'});\n this.$viewport.append(this.$rulerLabel);\n\n let div;\n div = document.createElement('div');\n this.$rulerLabel.append($$1(div));\n\n this.$rulerLabel.get(0).addEventListener('click', async event => {\n event.stopPropagation();\n await this.browser.gotoMultilocusPanel(this.referenceFrame);\n });\n\n this.$tooltip = $$1('
', {class: 'igv-ruler-tooltip'});\n this.$tooltip.height(this.$viewport.height());\n\n this.$viewport.append(this.$tooltip);\n\n this.$tooltipContent = $$1('
');\n this.$tooltip.append(this.$tooltipContent);\n\n this.rulerSweeper = new RulerSweeper(this, this.$viewport.get(0).parentElement, this.browser, this.referenceFrame);\n\n this.attachMouseHandlers(GenomeUtils.isWholeGenomeView(this.referenceFrame.chr));\n\n this.$tooltip.hide();\n\n this.dismissLocusLabel();\n }\n\n presentLocusLabel(viewportWidth) {\n\n this.$multiLocusCloseButton.show();\n\n this.$rulerLabel.show();\n this.$rulerLabel.get(0).style.backgroundColor = getChrColor(this.referenceFrame.chr);\n\n const textDiv = this.$rulerLabel.get(0).querySelector('div');\n\n const { width } = this.$rulerLabel.get(0).getBoundingClientRect();\n\n textDiv.innerHTML = `${ this.referenceFrame.getMultiLocusLabel(viewportWidth) }`;\n const { width:textDivWidth } = textDiv.getBoundingClientRect();\n\n if (textDivWidth/width > 0.5) {\n textDiv.innerHTML = `${ this.referenceFrame.getMultiLocusLabelBPLengthOnly(viewportWidth) }`;\n }\n\n //console.log(`${ Date.now() } textDiv ${ StringUtils.numberFormatter(Math.floor(textDivWidth)) }`)\n\n }\n\n // Use in conjuction with .igv-multi-locus-ruler-label-square-dot css class (_dom-misc.scss)\n dismissLocusLabel() {\n this.$rulerLabel.hide();\n this.$multiLocusCloseButton.hide();\n }\n\n attachMouseHandlers(isWholeGenomeView) {\n\n this.namespace = `.ruler_track_viewport_${this.browser.referenceFrameList.indexOf(this.referenceFrame)}`;\n\n this.$viewport.off(this.namespace);\n\n if (true === isWholeGenomeView) {\n\n const index = this.browser.referenceFrameList.indexOf(this.referenceFrame);\n\n const click = `click${this.namespace}`;\n this.$viewport.on(click, (e) => {\n\n const {x: pixel} = domUtils.translateMouseCoordinates(e, this.$viewport.get(0));\n const bp = Math.round(this.referenceFrame.start + this.referenceFrame.toBP(pixel));\n\n let searchString;\n\n const {chr} = this.browser.genome.getChromosomeCoordinate(bp);\n\n if (1 === this.browser.referenceFrameList.length) {\n searchString = chr;\n } else {\n\n let loci = this.browser.referenceFrameList.map(({locusSearchString}) => locusSearchString);\n\n loci[index] = chr;\n\n searchString = loci.join(' ');\n }\n\n this.browser.search(searchString);\n });\n\n this.$viewport.get(0).style.cursor = 'pointer';\n } else {\n this.$viewport.get(0).style.cursor = 'default';\n }\n\n }\n\n mouseMove(event) {\n\n if (true === this.browser.cursorGuideVisible) {\n\n if (undefined === currentViewport) {\n currentViewport = this;\n this.$tooltip.show();\n } else if (currentViewport.guid !== this.guid) {\n if (currentViewport.$tooltip) {\n currentViewport.$tooltip.hide();\n }\n this.$tooltip.show();\n currentViewport = this;\n } else {\n this.$tooltip.show();\n }\n\n const isWholeGenome = (this.browser.isMultiLocusWholeGenomeView() || GenomeUtils.isWholeGenomeView(this.referenceFrame.chr));\n\n if (isWholeGenome) {\n this.$tooltip.hide();\n return\n }\n\n const {x} = domUtils.translateMouseCoordinates(event, this.$viewport.get(0));\n const {start, bpPerPixel} = this.referenceFrame;\n const bp = Math.round(0.5 + start + Math.max(0, x) * bpPerPixel);\n\n this.$tooltipContent.text(numberFormatter$1(bp));\n\n const {width: ww} = this.$tooltipContent.get(0).getBoundingClientRect();\n const {width: w} = this.$viewport.get(0).getBoundingClientRect();\n\n this.$tooltip.css({left: `${IGVMath.clamp(x, 0, w - ww)}px`});\n\n // hide tooltip when movement stops\n clearTimeout(timer);\n timer = setTimeout(() => {\n if (this.$tooltip) this.$tooltip.hide();\n }, toolTipTimeout);\n\n }\n\n }\n\n startSpinner() {\n }\n\n stopSpinner() {\n }\n\n dispose() {\n this.rulerSweeper.dispose();\n super.dispose();\n }\n\n}\n\n/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2014 Broad Institute\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\nclass IdeogramViewport extends TrackViewport {\n\n constructor(trackView, viewportColumn, referenceFrame, width) {\n super(trackView, viewportColumn, referenceFrame, width);\n }\n\n initializationHelper() {\n\n this.canvas = document.createElement('canvas');\n this.canvas.className = 'igv-ideogram-canvas';\n //this.$content.append($(this.canvas))\n this.$viewport.append($$1(this.canvas));\n this.ideogram_ctx = this.canvas.getContext('2d');\n\n this.addMouseHandlers();\n }\n\n addMouseHandlers() {\n this.addViewportClickHandler(this.$viewport.get(0));\n }\n\n addViewportClickHandler(viewport) {\n\n this.boundClickHandler = clickHandler.bind(this);\n viewport.addEventListener('click', this.boundClickHandler);\n\n function clickHandler(event) {\n\n const {xNormalized, width} = domUtils.translateMouseCoordinates(event, this.ideogram_ctx.canvas);\n const {bpLength} = this.browser.genome.getChromosome(this.referenceFrame.chr);\n const locusLength = this.referenceFrame.bpPerPixel * width;\n const chrCoveragePercentage = locusLength / bpLength;\n\n let xPercentage = xNormalized;\n if (xPercentage - (chrCoveragePercentage / 2.0) < 0) {\n xPercentage = chrCoveragePercentage / 2.0;\n }\n\n if (xPercentage + (chrCoveragePercentage / 2.0) > 1.0) {\n xPercentage = 1.0 - chrCoveragePercentage / 2.0;\n }\n\n const ss = Math.round((xPercentage - (chrCoveragePercentage / 2.0)) * bpLength);\n const ee = Math.round((xPercentage + (chrCoveragePercentage / 2.0)) * bpLength);\n\n this.referenceFrame.start = ss;\n this.referenceFrame.end = ee;\n this.referenceFrame.bpPerPixel = (ee - ss) / width;\n\n this.browser.updateViews(this.referenceFrame, this.browser.trackViews, true);\n\n }\n\n }\n\n setWidth(width) {\n this.$viewport.width(width);\n }\n\n drawSVGWithContext(context, width, height, id, x, y, yClipOffset) {\n\n context.saveWithTranslationAndClipRect(id, x, y, width, height, yClipOffset);\n\n this.trackView.track.draw({\n context,\n referenceFrame: this.referenceFrame,\n pixelWidth: width,\n pixelHeight: height\n });\n\n context.restore();\n }\n\n repaint() {\n this.draw({referenceFrame: this.referenceFrame});\n }\n\n draw({referenceFrame}) {\n\n IGVGraphics.configureHighDPICanvas(this.ideogram_ctx, this.$viewport.width(), this.$viewport.height());\n\n this.trackView.track.draw({\n context: this.ideogram_ctx,\n referenceFrame,\n pixelWidth: this.$viewport.width(),\n pixelHeight: this.$viewport.height()\n });\n }\n\n startSpinner() {\n }\n\n stopSpinner() {\n }\n\n}\n\n/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2014 Broad Institute\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\n\nfunction createViewport(trackView, column, referenceFrame, width) {\n\n if ('ruler' === trackView.track.type) {\n return new RulerViewport(trackView, column, referenceFrame, width)\n } else if ('ideogram' === trackView.track.id) {\n return new IdeogramViewport(trackView, column, referenceFrame, width)\n } else {\n const viewportObject = new TrackViewport(trackView, column, referenceFrame, width);\n\n // if ('sequence' === trackView.track.type) {\n // viewportObject.$viewport.get(0).style.marginTop = '0px'\n // }\n\n return viewportObject\n }\n}\n\nconst maxFontSize = 10;\n\nconst fontConfigureTemplate =\n {\n // font: '2pt sans-serif',\n textAlign: 'start',\n textBaseline: 'bottom',\n strokeStyle: 'black',\n fillStyle: 'black'\n };\n\nclass SampleNameViewport {\n\n constructor(trackView, column, unused, width) {\n\n this.guid = domUtils.guid();\n this.trackView = trackView;\n\n this.browser = trackView.browser;\n\n this.viewport = domUtils.div({class: 'igv-viewport'});\n\n column.appendChild(this.viewport);\n\n if (trackView.track.height) {\n this.viewport.style.height = `${trackView.track.height}px`;\n }\n\n this.canvas = document.createElement('canvas');\n this.viewport.appendChild(this.canvas);\n this.ctx = this.canvas.getContext(\"2d\");\n\n this.trackScrollDelta = 0;\n\n this.contentTop = 0;\n\n this.setWidth(width);\n\n if (false === this.browser.showSampleNames) {\n this.hide();\n }\n\n this.addMouseHandlers();\n }\n\n checkCanvas() {\n\n const dpi = window.devicePixelRatio;\n const requiredHeight = this.viewport.clientHeight;\n const requiredWidth = this.browser.sampleNameViewportWidth;\n\n if (this.canvas.width !== requiredWidth * dpi || this.canvas.height !== requiredHeight * dpi) {\n const canvas = this.canvas;\n canvas.width = requiredWidth * dpi;\n canvas.height = requiredHeight * dpi;\n canvas.style.width = `${requiredWidth}px`;\n canvas.style.height = `${requiredHeight}px`;\n this.ctx = this.canvas.getContext(\"2d\");\n this.ctx.scale(dpi, dpi);\n }\n\n }\n\n setTop(contentTop) {\n\n if (typeof this.trackView.track.getSamples === 'function') {\n this.contentTop = contentTop;\n const samples = this.trackView.track.getSamples();\n this.repaint(samples);\n }\n\n }\n\n setWidth(width) {\n this.viewport.innerWidth = width;\n this.checkCanvas();\n }\n\n show() {\n this.viewport.style.display = 'block';\n }\n\n hide() {\n this.viewport.style.display = 'none';\n }\n\n async repaint(samples) {\n\n this.checkCanvas();\n this.draw({context: this.ctx, samples});\n }\n\n draw({context, samples}) {\n\n if (!samples || samples.names.length === 0/* || samples.height < 1*/) {\n return\n }\n\n configureFont(context, fontConfigureTemplate, samples.height);\n const sampleNameXShim = 4;\n\n context.clearRect(0, 0, context.canvas.width, context.canvas.height);\n\n context.fillStyle = appleCrayonRGB('lead');\n\n const viewportHeight = this.viewport.getBoundingClientRect().height;\n let y = (samples.yOffset || 0) + this.contentTop; // contentTop will always be a negative number (top relative to viewport)\n\n for (let name of samples.names) {\n if (y > viewportHeight) {\n break\n }\n if (y + samples.height > 0) {\n const text = name;\n const yFont = getYFont(context, text, y, samples.height);\n context.fillText(text, sampleNameXShim, yFont);\n\n }\n y += samples.height;\n }\n }\n\n renderSVGContext(context, {deltaX, deltaY}) {\n\n if (typeof this.trackView.track.getSamples === 'function') {\n\n const samples = this.trackView.track.getSamples();\n\n const yScrollDelta = 0; // This is not relevant, scrolling is handled in \"draw\"\n\n const {width, height} = this.viewport.getBoundingClientRect();\n\n const str = (this.trackView.track.name || this.trackView.track.id).replace(/\\W/g, '');\n const id = `${str}_sample_names_guid_${domUtils.guid()}`;\n\n context.saveWithTranslationAndClipRect(id, deltaX, deltaY + yScrollDelta, width, height, -yScrollDelta);\n\n this.draw({context, samples});\n\n context.restore();\n }\n }\n\n addMouseHandlers() {\n this.addViewportContextMenuHandler(this.viewport);\n }\n\n removeMouseHandlers() {\n this.removeViewportContextMenuHandler(this.viewport);\n }\n\n addViewportContextMenuHandler(viewport) {\n this.boundContextMenuHandler = contextMenuHandler.bind(this);\n viewport.addEventListener('contextmenu', this.boundContextMenuHandler);\n\n function contextMenuHandler(event) {\n\n event.preventDefault();\n event.stopPropagation();\n\n const config =\n {\n label: 'Name Panel Width',\n value: this.browser.sampleNameViewportWidth,\n callback: newWidth => {\n this.browser.sampleNameViewportWidth = parseInt(newWidth);\n for (let {sampleNameViewport} of this.browser.trackViews) {\n sampleNameViewport.setWidth(this.browser.sampleNameViewportWidth);\n }\n this.browser.layoutChange();\n }\n };\n\n this.browser.inputDialog.present(config, event);\n }\n\n }\n\n removeViewportContextMenuHandler(viewport) {\n viewport.removeEventListener('contextmenu', this.boundContextMenuHandler);\n }\n\n dispose() {\n this.removeMouseHandlers();\n this.viewport.remove();\n }\n}\n\nfunction getYFont(context, text, y, height) {\n return y + height - getSampleNameYShim(context, text, height)\n}\n\nfunction getSampleNameYShim(context, text, h) {\n const {actualBoundingBoxAscent, actualBoundingBoxDescent} = context.measureText(text);\n return (h - (actualBoundingBoxAscent + actualBoundingBoxDescent)) / 2\n}\n\nfunction configureFont(ctx, {textAlign, textBaseline, strokeStyle, fillStyle}, sampleHeight) {\n const pixels = Math.min(sampleHeight, maxFontSize);\n ctx.font = `${pixels}px sans-serif`;\n ctx.textAlign = textAlign;\n ctx.textBaseline = textBaseline;\n ctx.fillStyle = fillStyle;\n}\n\nconst MenuPopup = function (parent) {\n\n this.popover = domUtils.div({class: 'igv-menu-popup'});\n parent.appendChild(this.popover);\n\n const header = domUtils.div({class: 'igv-menu-popup-header'});\n this.popover.appendChild(header);\n\n uiUtils.attachDialogCloseHandlerWithParent(header, () => this.hide());\n\n this.popoverContent = domUtils.div();\n this.popover.appendChild(this.popoverContent);\n\n makeDraggable(this.popover, header);\n\n header.addEventListener('click', e => {\n e.stopPropagation();\n e.preventDefault();\n // absorb click to prevent it leaking through to parent DOM element\n });\n\n this.hide();\n\n};\n\nMenuPopup.prototype.hide = function () {\n this.popover.style.display = 'none';\n};\n\nMenuPopup.prototype.presentMenuList = function (menuList) {\n\n hideAllMenuPopups();\n\n if (menuList.length > 0) {\n\n this.popoverContent.innerHTML = '';\n\n menuList = MenuUtils.trackMenuItemListHelper(menuList, this);\n\n for (let item of menuList) {\n\n if (item.init) {\n item.init();\n }\n\n let $e = item.object;\n if (0 === menuList.indexOf(item)) {\n $e.removeClass('igv-track-menu-border-top');\n }\n\n if ($e.hasClass('igv-track-menu-border-top') || $e.hasClass('igv-menu-popup-check-container')) ; else if ($e.is('div')) {\n $e.addClass('igv-menu-popup-shim');\n }\n\n this.popoverContent.appendChild($e.get(0));\n\n }\n\n // NOTE: style.display most NOT be 'none' when calculating width. a display = 'none' will always\n // yield a width of zero (0).\n this.popover.style.display = 'flex';\n\n const {width} = this.popover.getBoundingClientRect();\n\n this.popover.style.left = `${-width}px`;\n this.popover.style.top = `${0}px`;\n\n }\n};\n\nMenuPopup.prototype.presentTrackContextMenu = function (e, menuItems) {\n\n this.popoverContent.innerHTML = '';\n\n const menuElements = createMenuElements(menuItems, this.popover);\n for (let {el} of menuElements) {\n this.popoverContent.appendChild(el);\n }\n\n present(e, this.popover);\n\n};\n\nMenuPopup.prototype.dispose = function () {\n\n this.popoverContent.innerHTML = '';\n this.popover.innerHTML = '';\n\n Object.keys(this).forEach(function (key) {\n this[key] = undefined;\n });\n};\n\nfunction createMenuElements(itemList, popover) {\n\n return itemList.map(item => {\n\n let el;\n\n if (typeof item === 'string' && '
' === item) {\n el = document.createElement('hr');\n } else if (typeof item === 'string') {\n el = domUtils.div({class: 'context-menu'});\n el.innerHTML = item;\n } else if (typeof item === 'Node') {\n el = item;\n } else {\n if (typeof item.init === 'function') {\n item.init();\n }\n\n if (\"checkbox\" === item.type) {\n el = createCheckbox(\"Show all bases\", item.value);\n } else if (\"color\" === item.type) {\n\n const colorPicker = new GenericColorPicker({parent: popover.parentElement, width: 364});\n colorPicker.configure(undefined, {color: color => item.click(color)});\n\n el = domUtils.div({class: 'context-menu'});\n if (typeof item.label === 'string') {\n el.innerHTML = item.label;\n }\n const clickHandler = e => {\n colorPicker.show();\n domUtils.hide(popover);\n e.preventDefault();\n e.stopPropagation();\n };\n el.addEventListener('click', clickHandler);\n el.addEventListener('touchend', clickHandler);\n el.addEventListener('mouseup', function (e) {\n e.preventDefault();\n e.stopPropagation();\n });\n } else {\n el = domUtils.div({class: 'context-menu'});\n if (typeof item.label === 'string') {\n el.innerHTML = item.label;\n }\n }\n\n if (item.click && \"color\" !== item.type) {\n el.addEventListener('click', handleClick);\n el.addEventListener('touchend', handleClick);\n el.addEventListener('mouseup', function (e) {\n e.preventDefault();\n e.stopPropagation();\n });\n\n // eslint-disable-next-line no-inner-declarations\n function handleClick(e) {\n item.click();\n domUtils.hide(popover);\n e.preventDefault();\n e.stopPropagation();\n }\n }\n }\n\n return {el, init: item.init}\n })\n\n}\n\nfunction present(e, popover) {\n\n // NOTE: style.display most NOT be 'none' when calculating width. a display = 'none' will always\n // yield a width of zero (0).\n popover.style.display = 'flex';\n\n const {x, y} = domUtils.translateMouseCoordinates(e, popover.parentNode);\n const {width} = popover.getBoundingClientRect();\n const xmax = x + width;\n\n const {width: parentWidth} = popover.parentNode.getBoundingClientRect();\n\n popover.style.left = `${xmax > parentWidth ? (x - (xmax - parentWidth)) : x}px`;\n popover.style.top = `${y}px`;\n\n}\n\nconst hideAllMenuPopups = () => {\n\n const menus = document.querySelectorAll('.igv-menu-popup');\n for (let i = 0; i < menus.length; i++) {\n menus[i].style.display = 'none';\n }\n\n};\n\n/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2014 Broad Institute\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\nconst igv_axis_column_width = 50;\nconst scrollbarExclusionTypes = new Set(['ruler', 'ideogram']);\nconst colorPickerExclusionTypes = new Set(['ruler', 'sequence', 'ideogram']);\n\nclass TrackView {\n\n constructor(browser, columnContainer, track) {\n this.browser = browser;\n this.track = track;\n track.trackView = this;\n this.addDOMToColumnContainer(browser, columnContainer, browser.referenceFrameList);\n }\n\n /**\n * Start a spinner for the track on any of its viewports. In practice this is called during initialization\n * when there is only one.\n */\n startSpinner() {\n if (this.viewports && this.viewports.length > 0) {\n this.viewports[0].startSpinner();\n }\n }\n\n stopSpinner() {\n if (this.viewports && this.viewports.length > 0) {\n this.viewports[0].stopSpinner();\n }\n }\n\n addDOMToColumnContainer(browser, columnContainer, referenceFrameList) {\n\n // Axis\n this.axis = this.createAxis(browser, this.track);\n\n // Create a viewport for each reference frame\n this.viewports = [];\n const viewportWidth = browser.calculateViewportWidth(referenceFrameList.length);\n const viewportColumns = columnContainer.querySelectorAll('.igv-column');\n for (let i = 0; i < viewportColumns.length; i++) {\n const viewport = createViewport(this, viewportColumns[i], referenceFrameList[i], viewportWidth);\n this.viewports.push(viewport);\n }\n\n // SampleName Viewport\n this.sampleNameViewport = new SampleNameViewport(this, browser.columnContainer.querySelector('.igv-sample-name-column'), undefined, browser.sampleNameViewportWidth);\n\n // Track Scrollbar\n this.createTrackScrollbar(browser);\n\n // Track Drag\n this.createTrackDragHandle(browser);\n\n // Track Gear\n this.createTrackGearPopup(browser);\n\n }\n\n createAxis(browser, track) {\n\n const axis = domUtils.div();\n browser.columnContainer.querySelector('.igv-axis-column').appendChild(axis);\n\n axis.style.height = `${track.height}px`;\n\n if (typeof track.paintAxis === 'function') {\n if (track.dataRange) {\n axis.addEventListener('click', () => {\n browser.dataRangeDialog.configure(this);\n browser.dataRangeDialog.present($$1(browser.columnContainer));\n });\n }\n\n\n const {width, height} = axis.getBoundingClientRect();\n this.axisCanvas = document.createElement('canvas');\n this.axisCanvas.style.width = `${width}px`;\n this.axisCanvas.style.height = `${height}px`;\n axis.appendChild(this.axisCanvas);\n }\n\n return axis\n\n }\n\n resizeAxisCanvas(width, height) {\n\n this.axis.style.width = `${width}px`;\n this.axis.style.height = `${height}px`;\n\n if (typeof this.track.paintAxis === 'function') {\n // Size the canvas in CSS (logical) pixels. The buffer size will be set when painted.\n this.axisCanvas.style.width = `${width}px`;\n this.axisCanvas.style.height = `${height}px`;\n\n }\n }\n\n removeDOMFromColumnContainer() {\n\n // Axis\n if (this.boundAxisClickHander) {\n this.removeAxisEventListener(this.axis);\n }\n this.axis.remove();\n\n // Track Viewports\n for (let viewport of this.viewports) {\n viewport.$viewport.remove();\n }\n\n // SampleName Viewport\n this.sampleNameViewport.dispose();\n\n // empty trackScrollbar Column\n this.removeTrackScrollMouseHandlers();\n this.outerScroll.remove();\n\n // empty trackDrag Column\n this.removeTrackDragMouseHandlers();\n this.dragHandle.remove();\n\n // empty trackGear Column\n this.removeTrackGearMouseHandlers();\n this.gearContainer.remove();\n\n }\n\n renderSVGContext(context, {deltaX, deltaY}) {\n\n renderSVGAxis(context, this.track, this.axisCanvas, deltaX, deltaY);\n\n const {width: axisWidth} = this.axis.getBoundingClientRect();\n\n const {y} = this.viewports[0].$viewport.get(0).getBoundingClientRect();\n\n let delta =\n {\n deltaX: axisWidth + deltaX,\n deltaY: y + deltaY\n };\n\n for (let viewport of this.viewports) {\n viewport.renderSVGContext(context, delta);\n const {width} = viewport.$viewport.get(0).getBoundingClientRect();\n delta.deltaX += width;\n }\n \n if (true === this.browser.showSampleNames) {\n this.sampleNameViewport.renderSVGContext(context, delta);\n }\n }\n\n dataRange() {\n return this.track.dataRange ? this.track.dataRange : undefined\n }\n\n setDataRange(min, max) {\n if (min !== undefined) {\n this.track.dataRange.min = min;\n }\n if (max !== undefined) {\n this.track.dataRange.max = max;\n }\n this.track.autoscale = false;\n this.repaintViews();\n }\n\n presentColorPicker(key) {\n\n if (false === colorPickerExclusionTypes.has(this.track.type)) {\n\n const trackColors = [];\n const color = this.track.color || this.track.defaultColor;\n if (isString$2(color)) {\n trackColors.push(color);\n }\n if (this.track.altColor && isString$2(this.track.altColor)) {\n trackColors.push(this.track.altColor);\n }\n const defaultColors = trackColors.map(c => c.startsWith(\"#\") ? c : c.startsWith(\"rgb(\") ? IGVColor.rgbToHex(c) : IGVColor.colorNameToHex(c));\n const colorHandlers =\n {\n color: color => {\n this.track.color = color;\n this.repaintViews();\n },\n altColor: color => {\n this.track.altColor = color;\n this.repaintViews();\n }\n\n };\n this.browser.genericColorPicker.configure(defaultColors, colorHandlers);\n this.browser.genericColorPicker.setActiveColorHandler(key);\n this.browser.genericColorPicker.show();\n }\n\n }\n\n setTrackHeight(newHeight, force) {\n\n if (!force) {\n if (this.track.minHeight) {\n newHeight = Math.max(this.track.minHeight, newHeight);\n }\n if (this.track.maxHeight) {\n newHeight = Math.min(this.track.maxHeight, newHeight);\n }\n }\n\n this.track.height = newHeight;\n\n this.resizeAxisCanvas(this.axis.clientWidth, this.track.height);\n\n if (typeof this.track.paintAxis === 'function') {\n this.paintAxis();\n }\n\n for (let {$viewport} of this.viewports) {\n $viewport.height(newHeight);\n }\n\n this.sampleNameViewport.viewport.style.height = `${newHeight}px`;\n\n // If the track does not manage its own content height set it equal to the viewport height here\n if (typeof this.track.computePixelHeight !== \"function\") {\n for (let vp of this.viewports) {\n vp.setContentHeight(newHeight);\n }\n }\n\n this.repaintViews();\n\n if (false === scrollbarExclusionTypes.has(this.track.type)) {\n this.updateScrollbar();\n }\n\n this.dragHandle.style.height = `${newHeight}px`;\n this.gearContainer.style.height = `${newHeight}px`;\n\n }\n\n updateScrollbar() {\n\n const viewportHeight = this.viewports[0].$viewport.height();\n this.outerScroll.style.height = `${viewportHeight}px`;\n\n const viewportContentHeight = this.maxViewportContentHeight();\n const innerScrollHeight = Math.round((viewportHeight / viewportContentHeight) * viewportHeight);\n\n if (viewportContentHeight > viewportHeight) {\n this.innerScroll.style.display = 'block';\n this.innerScroll.style.height = `${innerScrollHeight}px`;\n } else {\n this.innerScroll.style.display = 'none';\n }\n }\n\n moveScroller(delta) {\n\n const y = $$1(this.innerScroll).position().top + delta;\n const top = Math.min(Math.max(0, y), this.outerScroll.clientHeight - this.innerScroll.clientHeight);\n $$1(this.innerScroll).css('top', `${top}px`);\n\n const contentHeight = this.maxViewportContentHeight();\n const contentTop = -Math.round(top * (contentHeight / this.viewports[0].$viewport.height()));\n\n for (let viewport of this.viewports) {\n viewport.setTop(contentTop);\n }\n\n this.sampleNameViewport.trackScrollDelta = delta;\n this.sampleNameViewport.setTop(contentTop);\n\n }\n\n isLoading() {\n for (let viewport of this.viewports) {\n if (viewport.isLoading()) return true\n }\n }\n\n /**\n * Repaint all viewports without loading any new data. Use this for events that change visual aspect of data,\n * e.g. color, sort order, etc, but do not change the genomic state.\n */\n repaintViews() {\n\n for (let viewport of this.viewports) {\n if (viewport.isVisible()) {\n viewport.repaint();\n }\n }\n\n if (typeof this.track.paintAxis === 'function') {\n this.paintAxis();\n }\n\n // Repaint sample names last\n this.repaintSamples();\n }\n\n repaintSamples() {\n\n if (typeof this.track.getSamples === 'function') {\n const samples = this.track.getSamples();\n this.sampleNameViewport.repaint(samples);\n }\n }\n\n // track labels\n setTrackLabelName(name) {\n this.viewports.forEach(viewport => viewport.setTrackLabel(name));\n }\n\n /**\n * Called in response to a window resize event, change in # of multilocus panels, or other event that changes\n * the width of the track view.\n *\n * @param viewportWidth The width of each viewport in this track view.\n */\n resize(viewportWidth) {\n for (let viewport of this.viewports) {\n viewport.setWidth(viewportWidth);\n }\n }\n\n /**\n * Update viewports to reflect current genomic state, possibly loading additional data.\n *\n * @param force - if true, force a repaint even if no new data is loaded\n * @returns {Promise}\n */\n async updateViews() {\n\n if (!(this.browser && this.browser.referenceFrameList)) return\n\n const visibleViewports = this.viewports.filter(viewport => viewport.isVisible());\n\n // Shift viewports left/right to current genomic state (pans canvas)\n visibleViewports.forEach(viewport => viewport.shift());\n\n // If dragging (panning) return\n if (this.browser.dragObject) {\n return\n }\n\n // Filter zoomed out views. This has the side effect or turning off or no the zoomed out notice\n const viewportsToRepaint = visibleViewports.filter(vp => vp.needsRepaint()).filter(viewport => viewport.checkZoomIn());\n\n // Get viewports that require a data load\n const viewportsToReload = viewportsToRepaint.filter(viewport => viewport.needsReload());\n\n // Trigger viewport to load features needed to cover current genomic range\n // NOTE: these must be loaded synchronously, do not user Promise.all, not all file readers are thread safe\n for (let viewport of viewportsToReload) {\n await viewport.loadFeatures();\n }\n\n if (this.disposed) return // Track was removed during load\n\n // Special case for variant tracks in multilocus view. The # of rows to allocate to the variant (site)\n // section depends on data from all the views. We only need to adjust this however if any data was loaded\n // (i.e. reloadableViewports.length > 0)\n if (this.track && typeof this.track.variantRowCount === 'function' && viewportsToReload.length > 0) {\n let maxRow = 0;\n for (let viewport of this.viewports) {\n if (viewport.featureCache && viewport.featureCache.features) {\n maxRow = Math.max(maxRow, viewport.featureCache.features.reduce((a, f) => Math.max(a, f.row || 0), 0));\n }\n }\n const current = this.track.nVariantRows;\n if (current !== maxRow + 1) {\n this.track.variantRowCount(maxRow + 1);\n for (let viewport of this.viewports) {\n viewport.checkContentHeight();\n }\n }\n }\n\n if (this.track.autoscale) {\n let allFeatures = [];\n for (let visibleViewport of visibleViewports) {\n const referenceFrame = visibleViewport.referenceFrame;\n const start = referenceFrame.start;\n const end = start + referenceFrame.toBP(visibleViewport.getWidth());\n if (visibleViewport.featureCache && visibleViewport.featureCache.features) {\n // If the \"features\" object has a getMax function use it. Currently only alignmentContainer implements this, for coverage.\n if (typeof visibleViewport.featureCache.features.getMax === 'function') {\n const max = visibleViewport.featureCache.features.getMax(start, end);\n allFeatures.push({value: max});\n } else {\n const viewFeatures = FeatureUtils.findOverlapping(visibleViewport.featureCache.features, start, end);\n for (let f of viewFeatures) {\n allFeatures.push(f);\n }\n }\n }\n }\n if (typeof this.track.doAutoscale === 'function') {\n this.track.dataRange = this.track.doAutoscale(allFeatures);\n } else {\n this.track.dataRange = doAutoscale(allFeatures);\n }\n }\n\n const refreshView = (this.track.autoscale || this.track.autoscaleGroup || this.track.type === 'ruler');\n for (let vp of visibleViewports) {\n if (viewportsToRepaint.includes(vp)) {\n vp.repaint();\n } else if (refreshView) {\n vp.refresh();\n }\n }\n\n this.adjustTrackHeight();\n\n // Repaint sample names last\n this.repaintSamples();\n\n this.updateRulerViewportLabels();\n }\n\n clearCachedFeatures() {\n for (let viewport of this.viewports) {\n viewport.clearCache();\n }\n }\n\n updateRulerViewportLabels() {\n\n const viewportWidth = this.browser.calculateViewportWidth(this.viewports.length);\n\n for (let viewport of this.viewports) {\n if ('ruler' === this.track.type) {\n if (this.viewports.length > 1) {\n viewport.presentLocusLabel(viewportWidth);\n } else {\n viewport.dismissLocusLabel();\n }\n }\n }\n\n }\n\n /**\n * Return a promise to get all in-view features across all viewports. Used for group autoscaling.\n */\n async getInViewFeatures() {\n\n if (!(this.browser && this.browser.referenceFrameList)) {\n return []\n }\n\n let allFeatures = [];\n const visibleViewports = this.viewports.filter(viewport => viewport.isVisible());\n for (let vp of visibleViewports) {\n\n const referenceFrame = vp.referenceFrame;\n const {chr, start, bpPerPixel} = vp.referenceFrame;\n const end = start + referenceFrame.toBP(vp.getWidth());\n const needsReload = !vp.featureCache || !vp.featureCache.containsRange(chr, start, end, bpPerPixel);\n\n if (needsReload) {\n await vp.loadFeatures();\n }\n if (vp.featureCache && vp.featureCache.features) {\n\n if (typeof vp.featureCache.features.getMax === 'function') {\n const max = vp.featureCache.features.getMax(start, end);\n allFeatures.push({value: max});\n } else {\n const vpFeatures = typeof vp.featureCache.queryFeatures === 'function' ?\n vp.featureCache.queryFeatures(chr, start, end) :\n FeatureUtils.findOverlapping(vp.featureCache.features, start, end);\n allFeatures = allFeatures.concat(vpFeatures);\n }\n }\n }\n return allFeatures\n }\n\n checkContentHeight() {\n\n for (let viewport of this.viewports) {\n viewport.checkContentHeight();\n }\n this.adjustTrackHeight();\n\n }\n\n adjustTrackHeight() {\n\n var contentHeight = this.maxViewportContentHeight();\n if (this.track.autoHeight) {\n this.setTrackHeight(contentHeight, false);\n } else if (this.track.paintAxis) { // Avoid duplication, paintAxis is already called in setTrackHeight\n this.paintAxis();\n }\n\n if (false === scrollbarExclusionTypes.has(this.track.type)) {\n\n // Adjust scrollbar, if needed, to insure content is in view\n const currentTop = this.viewports[0].getContentTop();\n const viewportHeight = this.viewports[0].$viewport.height();\n const minTop = Math.min(0, viewportHeight - contentHeight);\n if(currentTop < minTop) {\n for (let viewport of this.viewports) {\n viewport.setTop(minTop);\n }\n }\n this.updateScrollbar();\n }\n }\n\n createTrackScrollbar(browser) {\n\n const outerScroll = domUtils.div();\n browser.columnContainer.querySelector('.igv-scrollbar-column').appendChild(outerScroll);\n outerScroll.style.height = `${this.track.height}px`;\n this.outerScroll = outerScroll;\n\n if (false === scrollbarExclusionTypes.has(this.track.type)) {\n const innerScroll = domUtils.div();\n outerScroll.appendChild(innerScroll);\n this.innerScroll = innerScroll;\n\n this.addTrackScrollMouseHandlers(browser);\n }\n\n }\n\n createTrackDragHandle(browser) {\n\n const className = 'ideogram' === this.track.type || 'ruler' === this.track.type ? 'igv-track-drag-shim' : 'igv-track-drag-handle';\n this.dragHandle = domUtils.div({class: className});\n browser.columnContainer.querySelector('.igv-track-drag-column').appendChild(this.dragHandle);\n this.dragHandle.style.height = `${this.track.height}px`;\n\n this.addTrackDragMouseHandlers(browser);\n\n }\n\n createTrackGearPopup(browser) {\n\n this.gearContainer = domUtils.div();\n browser.columnContainer.querySelector('.igv-gear-menu-column').appendChild(this.gearContainer);\n this.gearContainer.style.height = `${this.track.height}px`;\n\n if (true === this.track.ignoreTrackMenu) ; else {\n\n this.gear = domUtils.div();\n this.gearContainer.appendChild(this.gear);\n this.gear.appendChild(icons$1.createIcon('cog'));\n\n this.trackGearPopup = new MenuPopup(this.gear);\n\n this.addTrackGearMouseHandlers();\n }\n\n }\n\n addAxisEventListener(axis) {\n\n this.boundAxisClickHander = axisClickHandler.bind(this);\n axis.addEventListener('click', this.boundAxisClickHander);\n\n function axisClickHandler(event) {\n this.browser.dataRangeDialog.configure(this);\n this.browser.dataRangeDialog.present($$1(this.browser.columnContainer));\n }\n\n }\n\n removeAxisEventListener(axis) {\n axis.removeEventListener('click', this.boundAxisClickHander);\n }\n\n addTrackScrollMouseHandlers(browser) {\n\n // Mouse Down\n this.boundTrackScrollMouseDownHandler = trackScrollMouseDownHandler.bind(this);\n this.innerScroll.addEventListener('mousedown', this.boundTrackScrollMouseDownHandler);\n\n function trackScrollMouseDownHandler(event) {\n\n event.stopPropagation();\n\n const {y} = domUtils.pageCoordinates(event);\n\n $$1(this.innerScroll).data('yDown', y.toString());\n\n this.boundColumnContainerMouseMoveHandler = columnContainerMouseMoveHandler.bind(this);\n browser.columnContainer.addEventListener('mousemove', this.boundColumnContainerMouseMoveHandler);\n\n function columnContainerMouseMoveHandler(event) {\n\n event.stopPropagation();\n\n const {y} = domUtils.pageCoordinates(event);\n\n this.moveScroller(y - parseInt($$1(this.innerScroll).data('yDown')));\n\n $$1(this.innerScroll).data('yDown', y.toString());\n\n }\n }\n\n this.boundColumnContainerMouseUpHandler = columnContainerMouseUpHandler.bind(this);\n browser.columnContainer.addEventListener('mouseup', this.boundColumnContainerMouseUpHandler);\n\n function columnContainerMouseUpHandler(event) {\n browser.columnContainer.removeEventListener('mousemove', this.boundColumnContainerMouseMoveHandler);\n }\n\n }\n\n removeTrackScrollMouseHandlers() {\n if (false === scrollbarExclusionTypes.has(this.track.type)) {\n this.innerScroll.removeEventListener('mousedown', this.boundTrackScrollMouseDownHandler);\n this.browser.columnContainer.removeEventListener('mouseup', this.boundColumnContainerMouseUpHandler);\n this.browser.columnContainer.removeEventListener('mousemove', this.boundColumnContainerMouseMoveHandler);\n }\n }\n\n addTrackDragMouseHandlers(browser) {\n\n if ('ideogram' === this.track.id || 'ruler' === this.track.id) ; else {\n\n let currentDragHandle = undefined;\n\n // Mouse Down\n this.boundTrackDragMouseDownHandler = trackDragMouseDownHandler.bind(this);\n this.dragHandle.addEventListener('mousedown', this.boundTrackDragMouseDownHandler);\n\n function trackDragMouseDownHandler(event) {\n\n event.preventDefault();\n\n currentDragHandle = event.target;\n currentDragHandle.classList.add('igv-track-drag-handle-hover');\n\n browser.startTrackDrag(this);\n\n }\n\n // Mouse Up\n this.boundDocumentTrackDragMouseUpHandler = documentTrackDragMouseUpHandler.bind(this);\n document.addEventListener('mouseup', this.boundDocumentTrackDragMouseUpHandler);\n\n function documentTrackDragMouseUpHandler(event) {\n\n browser.endTrackDrag();\n\n if (currentDragHandle && event.target !== currentDragHandle) {\n currentDragHandle.classList.remove('igv-track-drag-handle-hover');\n }\n\n currentDragHandle = undefined;\n }\n\n // Mouse Enter\n this.boundTrackDragMouseEnterHandler = trackDragMouseEnterHandler.bind(this);\n this.dragHandle.addEventListener('mouseenter', this.boundTrackDragMouseEnterHandler);\n\n function trackDragMouseEnterHandler(event) {\n event.preventDefault();\n\n if (undefined === currentDragHandle) {\n event.target.classList.add('igv-track-drag-handle-hover');\n }\n\n browser.updateTrackDrag(this);\n\n }\n\n // Mouse Out\n this.dragHandle.addEventListener('mouseout', e => {\n e.preventDefault();\n\n if (undefined === currentDragHandle) {\n e.target.classList.remove('igv-track-drag-handle-hover');\n }\n });\n\n this.boundTrackDragMouseOutHandler = trackDragMouseOutHandler.bind(this);\n this.dragHandle.addEventListener('mouseout', this.boundTrackDragMouseOutHandler);\n\n function trackDragMouseOutHandler(event) {\n event.preventDefault();\n\n if (undefined === currentDragHandle) {\n event.target.classList.remove('igv-track-drag-handle-hover');\n }\n }\n\n }\n\n }\n\n removeTrackDragMouseHandlers() {\n\n if ('ideogram' === this.track.id || 'ruler' === this.track.id) ; else {\n this.dragHandle.removeEventListener('mousedown', this.boundTrackDragMouseDownHandler);\n document.removeEventListener('mouseup', this.boundDocumentTrackDragMouseUpHandler);\n this.dragHandle.removeEventListener('mouseup', this.boundTrackDragMouseEnterHandler);\n this.dragHandle.removeEventListener('mouseout', this.boundTrackDragMouseOutHandler);\n }\n\n }\n\n addTrackGearMouseHandlers() {\n if (true === this.track.ignoreTrackMenu) ; else {\n\n this.boundTrackGearClickHandler = trackGearClickHandler.bind(this);\n this.gear.addEventListener('click', this.boundTrackGearClickHandler);\n\n function trackGearClickHandler(event) {\n event.preventDefault();\n event.stopPropagation();\n this.trackGearPopup.presentMenuList(MenuUtils.trackMenuItemList(this));\n }\n\n }\n\n }\n\n removeTrackGearMouseHandlers() {\n if (true === this.track.ignoreTrackMenu) ; else {\n this.gear.removeEventListener('click', this.boundTrackGearClickHandler);\n }\n\n }\n\n /**\n * Do any cleanup here\n */\n dispose() {\n\n this.removeAxisEventListener(this.axis);\n this.axis.remove();\n\n for (let viewport of this.viewports) {\n viewport.dispose();\n }\n\n this.sampleNameViewport.dispose();\n\n this.removeTrackScrollMouseHandlers();\n this.outerScroll.remove();\n\n this.removeTrackDragMouseHandlers();\n this.dragHandle.remove();\n\n this.removeTrackGearMouseHandlers();\n this.gearContainer.remove();\n\n if (typeof this.track.dispose === \"function\") {\n this.track.dispose();\n }\n\n for (let key of Object.keys(this)) {\n this[key] = undefined;\n }\n\n if (this.alert) {\n this.alert.container.remove(); // This is quite obviously a hack, need a \"dispose\" method on AlertDialog\n }\n\n this.disposed = true;\n }\n\n paintAxis() {\n\n if (typeof this.track.paintAxis === 'function') {\n\n // Set the canvas buffer size, this is the resolution it is drawn at. This is done here in case the browser\n // has been drug between screens at different dpi resolutions since the last repaint\n const {width, height} = this.axisCanvas.getBoundingClientRect();\n const dpi = window.devicePixelRatio || 1;\n this.axisCanvas.height = dpi * height;\n this.axisCanvas.width = dpi * width;\n\n // Get a scaled context to draw aon\n const axisCanvasContext = this.axisCanvas.getContext('2d');\n axisCanvasContext.scale(dpi, dpi);\n\n this.track.paintAxis(axisCanvasContext, width, height);\n }\n }\n\n maxViewportContentHeight() {\n return Math.max(this.viewports.map(viewport => viewport.getContentHeight()))\n }\n\n}\n\nfunction renderSVGAxis(context, track, axisCanvas, deltaX, deltaY) {\n\n if (typeof track.paintAxis === 'function') {\n\n const {y, width, height} = axisCanvas.getBoundingClientRect();\n\n const str = (track.name || track.id).replace(/\\W/g, '');\n const id = `${str}_axis_guid_${domUtils.guid()}`;\n\n context.saveWithTranslationAndClipRect(id, deltaX, y + deltaY, width, height, 0);\n\n track.paintAxis(context, width, height);\n\n context.restore();\n }\n\n}\n\n/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2014 Broad Institute\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\nconst DEFAULT_COLOR$1 = 'rgb(150, 150, 150)';\n\nclass WigTrack extends TrackBase {\n\n static defaults = {\n height: 50,\n flipAxis: false,\n logScale: false,\n windowFunction: 'mean',\n graphType: 'bar',\n autoscale: true,\n normalize: undefined,\n scaleFactor: undefined\n }\n\n constructor(config, browser) {\n super(config, browser);\n }\n\n init(config) {\n\n super.init(config);\n\n this.type = \"wig\";\n this.featureType = 'numeric';\n this.paintAxis = paintAxis;\n\n const format = config.format ? config.format.toLowerCase() : config.format;\n if (config.featureSource) {\n this.featureSource = config.featureSource;\n delete config.featureSource;\n } else if (\"bigwig\" === format) {\n this.featureSource = new BWSource(config, this.browser.genome);\n } else if (\"tdf\" === format) {\n this.featureSource = new TDFSource(config, this.browser.genome);\n } else {\n this.featureSource = FeatureSource(config, this.browser.genome);\n }\n\n\n // Override autoscale default\n if(config.max === undefined || config.autoscale === true) {\n this.autoscale = true;\n } else {\n this.dataRange = {\n min: config.min || 0,\n max: config.max\n };\n }\n }\n\n async postInit() {\n const header = await this.getHeader();\n if (this.disposed) return // This track was removed during async load\n if (header) this.setTrackProperties(header);\n }\n\n async getFeatures(chr, start, end, bpPerPixel) {\n const features = await this.featureSource.getFeatures({\n chr,\n start,\n end,\n bpPerPixel,\n visibilityWindow: this.visibilityWindow,\n windowFunction: this.windowFunction\n });\n if (this.normalize && this.featureSource.normalizationFactor) {\n const scaleFactor = this.featureSource.normalizationFactor;\n for (let f of features) {\n f.value *= scaleFactor;\n }\n }\n if (this.scaleFactor) {\n const scaleFactor = this.scaleFactor;\n for (let f of features) {\n f.value *= scaleFactor;\n }\n }\n return features\n }\n\n menuItemList() {\n let items = [];\n\n if (this.flipAxis !== undefined) {\n items.push('
');\n items.push({\n label: \"Flip y-axis\",\n click: () => {\n this.flipAxis = !this.flipAxis;\n this.trackView.repaintViews();\n }\n });\n }\n\n items = items.concat(MenuUtils.numericDataMenuItems(this.trackView));\n\n return items\n }\n\n async getHeader() {\n\n if (typeof this.featureSource.getHeader === \"function\") {\n this.header = await this.featureSource.getHeader();\n }\n return this.header\n }\n\n // TODO: refactor to igvUtils.js\n getScaleFactor(min, max, height, logScale) {\n const scale = logScale ? height / (Math.log10(max + 1) - (min <= 0 ? 0 : Math.log10(min + 1))) : height / (max - min);\n return scale\n }\n\n computeYPixelValue(yValue, yScaleFactor) {\n return (this.flipAxis ? (yValue - this.dataRange.min) : (this.dataRange.max - yValue)) * yScaleFactor\n }\n\n computeYPixelValueInLogScale(yValue, yScaleFactor) {\n let maxValue = this.dataRange.max;\n let minValue = this.dataRange.min;\n if (maxValue <= 0) return 0 // TODO:\n if (minValue <= -1) minValue = 0;\n minValue = (minValue <= 0) ? 0 : Math.log10(minValue + 1);\n maxValue = Math.log10(maxValue + 1);\n yValue = Math.log10(yValue + 1);\n return ((this.flipAxis ? (yValue - minValue) : (maxValue - yValue)) * yScaleFactor)\n }\n\n draw(options) {\n\n const features = options.features;\n const ctx = options.context;\n const bpPerPixel = options.bpPerPixel;\n const bpStart = options.bpStart;\n const pixelWidth = options.pixelWidth;\n options.pixelHeight;\n const bpEnd = bpStart + pixelWidth * bpPerPixel + 1;\n const posColor = this.color || DEFAULT_COLOR$1;\n\n let baselineColor;\n if (typeof posColor === \"string\" && posColor.startsWith(\"rgb(\")) {\n baselineColor = IGVColor.addAlpha(posColor, 0.1);\n }\n const scaleFactor = this.getScaleFactor(this.dataRange.min, this.dataRange.max, options.pixelHeight, this.logScale);\n const yScale = (yValue) => this.logScale\n ? this.computeYPixelValueInLogScale(yValue, scaleFactor)\n : this.computeYPixelValue(yValue, scaleFactor);\n\n if (features && features.length > 0) {\n\n if (this.dataRange.min === undefined) this.dataRange.min = 0;\n\n // Max can be less than min if config.min is set but max left to autoscale. If that's the case there is\n // nothing to paint.\n if (this.dataRange.max > this.dataRange.min) {\n\n let lastPixelEnd = -1;\n let lastY;\n const y0 = yScale(0);\n for (let f of features) {\n\n if (f.end < bpStart) continue\n if (f.start > bpEnd) break\n\n const x = Math.floor((f.start - bpStart) / bpPerPixel);\n if (isNaN(x)) continue\n\n let y = yScale(f.value);\n\n const rectEnd = Math.ceil((f.end - bpStart) / bpPerPixel);\n const width = Math.max(1, rectEnd - x);\n\n const color = this.getColorForFeature(f);\n\n if (this.graphType === \"points\") {\n const pointSize = this.config.pointSize || 3;\n const px = x + width / 2;\n IGVGraphics.fillCircle(ctx, px, y, pointSize / 2, {\"fillStyle\": color, \"strokeStyle\": color});\n\n } else if (this.graphType === \"line\") {\n if (lastY != undefined) {\n IGVGraphics.strokeLine(ctx, lastPixelEnd, lastY, x, y, {\n \"fillStyle\": color,\n \"strokeStyle\": color\n });\n }\n IGVGraphics.strokeLine(ctx, x, y, x + width, y, {\"fillStyle\": color, \"strokeStyle\": color});\n } else {\n const height = y - y0;\n IGVGraphics.fillRect(ctx, x, y0, width, height, {fillStyle: color});\n\n }\n lastPixelEnd = x + width;\n lastY = y;\n }\n\n // If the track includes negative values draw a baseline\n if (this.dataRange.min < 0) {\n const basepx = (this.dataRange.max / (this.dataRange.max - this.dataRange.min)) * options.pixelHeight;\n IGVGraphics.strokeLine(ctx, 0, basepx, options.pixelWidth, basepx, {strokeStyle: baselineColor});\n }\n }\n }\n\n // Draw guidelines\n if (this.config.hasOwnProperty('guideLines')) {\n for (let line of this.config.guideLines) {\n if (line.hasOwnProperty('color') && line.hasOwnProperty('y') && line.hasOwnProperty('dotted')) {\n let y = yScale(line.y);\n let props = {\n 'strokeStyle': line['color'],\n 'strokeWidth': 2\n };\n if (line['dotted']) IGVGraphics.dashedLine(options.context, 0, y, options.pixelWidth, y, 5, props);\n else IGVGraphics.strokeLine(options.context, 0, y, options.pixelWidth, y, props);\n }\n }\n }\n }\n\n popupData(clickState, features) {\n\n if (features === undefined) features = this.clickedFeatures(clickState);\n\n if (features && features.length > 0) {\n\n const genomicLocation = clickState.genomicLocation;\n const popupData = [];\n\n // Sort features based on distance from click\n features.sort(function (a, b) {\n const distA = Math.abs((a.start + a.end) / 2 - genomicLocation);\n const distB = Math.abs((b.start + b.end) / 2 - genomicLocation);\n return distA - distB\n });\n\n // Display closest 10\n const displayFeatures = features.length > 10 ? features.slice(0, 10) : features;\n\n // Resort in ascending order\n displayFeatures.sort(function (a, b) {\n return a.start - b.start\n });\n\n for (let selectedFeature of displayFeatures) {\n if (selectedFeature) {\n if (popupData.length > 0) {\n popupData.push('
');\n }\n let posString = (selectedFeature.end - selectedFeature.start) === 1 ?\n numberFormatter$1(selectedFeature.start + 1)\n : numberFormatter$1(selectedFeature.start + 1) + \"-\" + numberFormatter$1(selectedFeature.end);\n popupData.push({name: \"Position:\", value: posString});\n popupData.push({\n name: \"Value:     \",\n value: numberFormatter$1(selectedFeature.value)\n });\n }\n }\n if (displayFeatures.length < features.length) {\n popupData.push(\"
...\");\n }\n\n return popupData\n\n } else {\n return []\n }\n }\n\n get supportsWholeGenome() {\n return !this.config.indexURL && this.config.supportsWholeGenome !== false\n }\n\n /**\n * Return color for feature.\n * @param feature\n * @returns {string}\n */\n\n getColorForFeature(f) {\n let c = (f.value < 0 && this.altColor) ? this.altColor : this.color || DEFAULT_COLOR$1;\n return (typeof c === \"function\") ? c(f.value) : c\n }\n\n /**\n * Called when the track is removed. Do any needed cleanup here\n */\n dispose() {\n this.trackView = undefined;\n }\n\n}\n\n/**\n *\n * @param cs - object containing\n * 1) array of threshold values defining bin boundaries in ascending order\n * 2) array of colors for bins (length == thresholds.length + 1)\n * @constructor\n */\nfunction BinnedColorScale(cs) {\n this.thresholds = cs.thresholds;\n this.colors = cs.colors;\n}\n\nBinnedColorScale.prototype.getColor = function (value) {\n\n for (let threshold of this.thresholds) {\n if (value < threshold) {\n return this.colors[this.thresholds.indexOf(threshold)]\n }\n }\n\n return this.colors[this.colors.length - 1]\n\n};\n\n/**\n *\n * @param scale - object with the following properties\n * low\n * lowR\n * lowG\n * lowB\n * high\n * highR\n * highG\n * highB\n *\n * @constructor\n */\nfunction GradientColorScale(scale) {\n\n this.scale = scale;\n this.lowColor = \"rgb(\" + scale.lowR + \",\" + scale.lowG + \",\" + scale.lowB + \")\";\n this.highColor = \"rgb(\" + scale.highR + \",\" + scale.highG + \",\" + scale.highB + \")\";\n this.diff = scale.high - scale.low;\n\n}\n\nGradientColorScale.prototype.getColor = function (value) {\n\n var scale = this.scale, r, g, b, frac;\n\n if (value <= scale.low) return this.lowColor\n else if (value >= scale.high) return this.highColor\n\n frac = (value - scale.low) / this.diff;\n r = Math.floor(scale.lowR + frac * (scale.highR - scale.lowR));\n g = Math.floor(scale.lowG + frac * (scale.highG - scale.lowG));\n b = Math.floor(scale.lowB + frac * (scale.highB - scale.lowB));\n\n return \"rgb(\" + r + \",\" + g + \",\" + b + \")\"\n};\n\nclass ConstantColorScale {\n constructor(color) {\n this.color = color;\n }\n\n getColor() {\n return this.color\n }\n}\n\n/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2014 Broad Institute\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\nclass SegTrack extends TrackBase {\n\n constructor(config, browser) {\n super(config, browser);\n }\n\n init(config) {\n super.init(config);\n\n this.type = config.type || \"seg\";\n if (this.type === 'maf') this.type = 'mut';\n this.isLog = config.isLog;\n this.displayMode = config.displayMode || \"EXPANDED\"; // EXPANDED | SQUISHED\n this.height = config.height || 300;\n this.maxHeight = config.maxHeight || 500;\n this.squishedRowHeight = config.sampleSquishHeight || config.squishedRowHeight || 2;\n this.expandedRowHeight = config.sampleExpandHeight || config.expandedRowHeight || 13;\n this.sampleHeight = this.squishedRowHeight; // Initial value, will get overwritten when rendered\n\n if (config.color) {\n this.color = config.color;\n } else {\n // Color scales for \"seg\" (copy number) tracks.\n this.posColorScale = config.posColorScale ||\n new GradientColorScale({\n low: 0.1,\n lowR: 255,\n lowG: 255,\n lowB: 255,\n high: 1.5,\n highR: 255,\n highG: 0,\n highB: 0\n });\n this.negColorScale = config.negColorScale ||\n new GradientColorScale({\n low: -1.5,\n lowR: 0,\n lowG: 0,\n lowB: 255,\n high: -0.1,\n highR: 255,\n highG: 255,\n highB: 255\n });\n\n // Default color table for mutation (mut and maf) tracks\n if (this.type === \"mut\") {\n this.colorTable = new ColorTable(config.colorTable || MUT_COLORS);\n }\n }\n\n this.sampleKeys = [];\n this.sampleNames = new Map();\n if (config.samples) {\n // Explicit setting, keys == names\n for (let s of config.samples) {\n this.sampleKeys.push(s);\n this.sampleNames.set(s, s);\n }\n this.explicitSamples = true;\n }\n\n // this.featureSource = config.sourceType === \"bigquery\" ?\n // new igv.BigQueryFeatureSource(this.config) :\n\n // Disable whole genome downsampling unless explicitly.\n const configCopy = Object.assign({}, this.config);\n configCopy.maxWGCount = configCopy.maxWGCount || Number.MAX_SAFE_INTEGER;\n this.featureSource = FeatureSource(configCopy, this.browser.genome);\n\n this.initialSort = config.sort;\n }\n\n async postInit() {\n if (typeof this.featureSource.getHeader === \"function\") {\n this.header = await this.featureSource.getHeader();\n if(this.disposed) return; // This track was removed during async load\n }\n // Set properties from track line\n if (this.header) {\n this.setTrackProperties(this.header);\n }\n }\n\n\n menuItemList() {\n\n const menuItems = [];\n const lut =\n {\n \"SQUISHED\": \"Squish\",\n \"EXPANDED\": \"Expand\",\n \"FILL\": \"Fill\"\n };\n\n menuItems.push('
');\n menuItems.push(\"DisplayMode:\");\n\n const displayOptions = this.type === 'seg' ? [\"SQUISHED\", \"EXPANDED\", \"FILL\"] : [\"SQUISHED\", \"EXPANDED\"];\n\n for (let displayMode of displayOptions) {\n\n const checkBox = createCheckbox(lut[displayMode], displayMode === this.displayMode);\n menuItems.push(\n {\n object: $$1(checkBox),\n click: () => {\n this.displayMode = displayMode;\n this.config.displayMode = displayMode;\n this.trackView.checkContentHeight();\n this.trackView.repaintViews();\n this.trackView.moveScroller(this.trackView.sampleNameViewport.trackScrollDelta);\n }\n });\n }\n\n return menuItems\n\n }\n\n hasSamples() {\n return true // SEG, MUT, and MAF tracks have samples by definition\n }\n\n getSamples() {\n return {\n names: this.sampleKeys.map(key => this.sampleNames.get(key)),\n height: this.sampleHeight,\n yOffset: 0\n }\n }\n\n async getFeatures(chr, start, end) {\n const features = await this.featureSource.getFeatures({chr, start, end});\n if (this.initialSort) {\n const sort = this.initialSort;\n this.sortSamples(sort.chr, sort.start, sort.end, sort.direction, features);\n this.initialSort = undefined; // Sample order is sorted,\n }\n return features\n }\n\n\n draw({context, renderSVG, pixelTop, pixelWidth, pixelHeight, features, bpPerPixel, bpStart}) {\n\n IGVGraphics.fillRect(context, 0, pixelTop, pixelWidth, pixelHeight, {'fillStyle': \"rgb(255, 255, 255)\"});\n\n if (features && features.length > 0) {\n\n this.checkForLog(features);\n\n // New segments could conceivably add new samples\n this.updateSampleKeys(features);\n\n // Create a map for fast id -> row lookup\n const samples = {};\n this.sampleKeys.forEach(function (id, index) {\n samples[id] = index;\n });\n\n let border;\n switch (this.displayMode) {\n case \"FILL\":\n this.sampleHeight = pixelHeight / this.sampleKeys.length;\n border = 0;\n break\n\n case \"SQUISHED\":\n this.sampleHeight = this.squishedRowHeight;\n border = 0;\n break\n default: // EXPANDED\n this.sampleHeight = this.expandedRowHeight;\n border = 1;\n }\n const rowHeight = this.sampleHeight;\n\n\n // this.featureMap = new Map()\n\n for (let segment of features) {\n segment.pixelRect = undefined; // !important, reset this in case segment is not drawn\n }\n\n const pixelBottom = pixelTop + pixelHeight;\n const bpEnd = bpStart + pixelWidth * bpPerPixel + 1;\n const xScale = bpPerPixel;\n\n this.sampleYStart = undefined;\n for (let f of features) {\n\n if (f.end < bpStart) continue\n if (f.start > bpEnd) break\n\n const sampleKey = f.sampleKey || f.sample;\n f.row = samples[sampleKey];\n const y = f.row * rowHeight + border;\n\n if (undefined === this.sampleYStart) {\n this.sampleYStart = y;\n }\n\n const bottom = y + rowHeight;\n\n if (bottom < pixelTop || y > pixelBottom) {\n continue\n }\n\n const segmentStart = Math.max(f.start, bpStart);\n // const segmentStart = segment.start;\n let x = Math.round((segmentStart - bpStart) / xScale);\n\n const segmentEnd = Math.min(f.end, bpEnd);\n // const segmentEnd = segment.end;\n const x1 = Math.round((segmentEnd - bpStart) / xScale);\n let w = Math.max(1, x1 - x);\n\n let color;\n if (this.color) {\n if (typeof this.color === \"function\") {\n color = this.color(f);\n } else {\n color = this.color;\n }\n } else if (this.colorTable) {\n color = this.colorTable.getColor(f.value.toLowerCase());\n }\n\n let h;\n if (\"mut\" === this.type) {\n h = rowHeight - 2 * border;\n if (w < 3) {\n w = 3;\n x -= 1;\n }\n } else {\n // Assume seg track\n let value = f.value;\n if (!this.isLog) {\n value = IGVMath.log2(value / 2);\n }\n if (value < -0.1) {\n color = this.negColorScale.getColor(value);\n } else if (value > 0.1) {\n color = this.posColorScale.getColor(value);\n } else {\n color = \"white\";\n }\n\n let sh = rowHeight;\n if (rowHeight < 0.25) {\n const f = 0.1 + 2 * Math.abs(value);\n sh = Math.min(1, f * rowHeight);\n }\n h = sh - 2 * border;\n }\n\n\n f.pixelRect = {x, y, w, h};\n\n // Use for diagnostic rendering\n // context.fillStyle = randomRGB(180, 240)\n // context.fillStyle = randomGrey(200, 255)\n context.fillStyle = color;\n context.fillRect(x, y, w, h);\n }\n\n }\n\n }\n\n\n checkForLog(features) {\n if (this.isLog === undefined) {\n this.isLog = false;\n for (let feature of features) {\n if (feature.value < 0) {\n this.isLog = true;\n return\n }\n }\n }\n }\n\n /**\n * Optional method to compute pixel height to accomodate the list of features. The implementation below\n * has side effects (modifiying the samples hash). This is unfortunate, but harmless.\n *\n * Note displayMode \"FILL\" is handled by the viewport\n *\n * @param features\n * @returns {number}\n */\n computePixelHeight(features) {\n if (!features) return 0\n const sampleHeight = (\"SQUISHED\" === this.displayMode) ? this.squishedRowHeight : this.expandedRowHeight;\n this.updateSampleKeys(features);\n return this.sampleKeys.length * sampleHeight\n }\n\n /**\n * Sort samples by the average value over the genomic range in the direction indicated (1 = ascending, -1 descending)\n */\n async sortSamples(chr, start, end, direction, featureList) {\n\n if (!featureList) {\n featureList = await this.featureSource.getFeatures({chr, start, end});\n }\n if (!featureList) return\n\n this.updateSampleKeys(featureList);\n\n const scores = {};\n const d2 = (direction === \"ASC\" ? 1 : -1);\n\n const sortSeg = () => {\n // Compute weighted average score for each sample\n const bpLength = end - start + 1;\n for (let segment of featureList) {\n if (segment.end < start) continue\n if (segment.start > end) break\n const min = Math.max(start, segment.start);\n const max = Math.min(end, segment.end);\n const f = (max - min) / bpLength;\n const sampleKey = segment.sampleKey || segment.sample;\n const s = scores[sampleKey] || 0;\n scores[sampleKey] = s + f * segment.value;\n }\n\n // Now sort sample names by score\n this.sampleKeys.sort(function (a, b) {\n let s1 = scores[a];\n let s2 = scores[b];\n if (!s1) s1 = d2 * Number.MAX_VALUE;\n if (!s2) s2 = d2 * Number.MAX_VALUE;\n if (s1 === s2) return 0\n else if (s1 > s2) return d2\n else return d2 * -1\n });\n };\n\n const sortMut = () => {\n // Compute weighted average score for each sample\n for (let segment of featureList) {\n if (segment.end < start) continue\n if (segment.start > end) break\n const sampleKey = segment.sampleKey || segment.sample;\n if (!scores.hasOwnProperty(sampleKey) || segment.value.localeCompare(scores[sampleKey]) > 0) {\n scores[sampleKey] = segment.value;\n }\n }\n // Now sort sample names by score\n this.sampleKeys.sort(function (a, b) {\n let sa = scores[a] || \"\";\n let sb = scores[b] || \"\";\n return d2 * (sa.localeCompare(sb))\n });\n };\n\n if (\"mut\" === this.type) {\n sortMut();\n } else {\n sortSeg();\n }\n\n this.trackView.repaintViews();\n\n }\n\n clickedFeatures(clickState) {\n\n const allFeatures = super.clickedFeatures(clickState);\n const y = clickState.y;\n return allFeatures.filter(function (feature) {\n const rect = feature.pixelRect;\n return rect && y >= rect.y && y <= (rect.y + rect.h)\n })\n\n }\n\n hoverText(clickState) {\n const features = this.clickedFeatures(clickState);\n if(features && features.length > 0) {\n return `${features[0].sample}: ${features[0].value}`\n }\n }\n\n popupData(clickState, featureList) {\n\n if(featureList === undefined) featureList = this.clickedFeatures(clickState);\n\n const items = [];\n\n for (let feature of featureList) {\n\n // Double line divider between features\n if (items.length > 0) {\n items.push('
');\n items.push('
');\n }\n\n // hack for whole genome features, which save the original feature as \"_f\"\n const f = feature._f || feature;\n\n const data = (typeof f.popupData === 'function') ?\n f.popupData(this.type, this.browser.genome.id) :\n this.extractPopupData(f);\n Array.prototype.push.apply(items, data);\n\n }\n\n return items\n }\n\n contextMenuItemList(clickState) {\n\n const referenceFrame = clickState.viewport.referenceFrame;\n const genomicLocation = clickState.genomicLocation;\n\n // Define a region 5 \"pixels\" wide in genomic coordinates\n const sortDirection = this.config.sort ?\n (this.config.sort.direction === \"ASC\" ? \"DESC\" : \"ASC\") : // Toggle from previous sort\n \"DESC\";\n const bpWidth = referenceFrame.toBP(2.5);\n\n const sortHandler = (sort) => {\n const viewport = clickState.viewport;\n const features = viewport.cachedFeatures;\n this.sortSamples(sort.chr, sort.start, sort.end, sort.direction, features);\n };\n\n const sortLabel = this.type === 'seg' ? 'Sort by value' : 'Sort by type';\n\n return [\n {\n label: sortLabel, click: (e) => {\n\n\n const sort = {\n direction: sortDirection,\n chr: clickState.viewport.referenceFrame.chr,\n start: genomicLocation - bpWidth,\n end: genomicLocation + bpWidth\n\n };\n\n sortHandler(sort);\n\n this.config.sort = sort;\n\n }\n }]\n\n }\n\n get supportsWholeGenome() {\n return (this.config.indexed === false || !this.config.indexURL) && this.config.supportsWholeGenome !== false\n }\n\n updateSampleKeys(featureList) {\n\n if (this.explicitSamples) return\n\n for (let feature of featureList) {\n const sampleKey = feature.sampleKey || feature.sample;\n if (!this.sampleNames.has(sampleKey)) {\n this.sampleNames.set(sampleKey, feature.sample);\n this.sampleKeys.push(sampleKey);\n }\n }\n }\n}\n\n// Mut and MAF file default color table\n\nconst MUT_COLORS = {\n\n \"indel\": \"rgb(0,200,0)\",\n \"targeted region\": \"rgb(236,155,43)\",\n \"truncating\": \"rgb(\t150,0,0)\",\n \"non-coding transcript\": \"rgb(0,0,150)\",\n\n // Colors from https://www.nature.com/articles/nature11404\n \"synonymous\": \"rgb(109,165,95)\",\n \"silent\": \"rgb(109,135,80)\",\n \"missense_mutation\": \"rgb(72,130,187)\",\n \"missense\": \"rgb(72,130,187)\",\n \"splice site\": \"rgb(143,83,155)\",\n \"splice_region\": \"rgb(143,83,155)\",\n \"nonsense\": \"rgb(216, 57,81)\",\n \"nonsense_mutation\": \"rgb(216, 57,81)\",\n \"frame_shift_del\": \"rgb(226,135,65)\",\n \"frame_shift_ins\": \"rgb(226,135,65)\",\n \"in_frame_del\": \"rgb(247,235,94)\",\n \"in_frame_ins\": \"rgb(247,235,94)\",\n \"*other*\": \"rgb(159,91,50)\"\n //\n // 3'Flank\n // 3'UTR\n // 5'Flank\n // 5'UTR\n // Frame_Shift_Del\n // Frame_Shift_Ins\n // IGR\n // In_Frame_Del\n // In_Frame_Ins\n // Intron\n // Missense_Mutation\n // Nonsense_Mutation\n // Nonstop_Mutation\n // RNA\n // Silent\n // Splice_Region\n // Splice_Site\n // Translation_Start_Site\n // Variant_Classification\n\n};\n\n/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2016-2017 The Regents of the University of California\n * Author: Jim Robinson\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\n\n/**\n * Represents 2 or more wig tracks overlaid on a common viewport.\n */\nclass MergedTrack extends TrackBase {\n\n constructor(config, browser) {\n super(config, browser);\n this.type = \"merged\";\n this.featureType = 'numeric';\n this.paintAxis = paintAxis;\n this.graphType = config.graphType;\n }\n\n init(config) {\n if (!config.tracks) {\n throw Error(\"Error: no tracks defined for merged track\" + config)\n }\n\n super.init(config);\n }\n\n async postInit() {\n\n this.tracks = [];\n const p = [];\n for (let tconf of this.config.tracks) {\n tconf.isMergedTrack = true;\n const t = await this.browser.createTrack(tconf);\n if (t) {\n t.autoscale = false; // Scaling done from merged track\n this.tracks.push(t);\n } else {\n console.warn(\"Could not create track \" + tconf);\n }\n\n if (typeof t.postInit === 'function') {\n p.push(t.postInit());\n }\n }\n\n this.flipAxis = this.config.flipAxis ? this.config.flipAxis : false;\n this.logScale = this.config.logScale ? this.config.logScale : false;\n this.autoscale = this.config.autoscale || this.config.max === undefined;\n if (!this.autoscale) {\n this.dataRange = {\n min: this.config.min || 0,\n max: this.config.max\n };\n }\n for (let t of this.tracks) {\n t.autoscale = false;\n t.dataRange = this.dataRange;\n }\n\n this.height = this.config.height || 50;\n\n return Promise.all(p)\n }\n\n get height() {\n return this._height\n }\n\n set height(h) {\n this._height = h;\n if (this.tracks) {\n for (let t of this.tracks) {\n t.height = h;\n t.config.height = h;\n }\n }\n }\n\n menuItemList() {\n let items = [];\n if (this.flipAxis !== undefined) {\n items.push({\n label: \"Flip y-axis\",\n click: () => {\n this.flipAxis = !this.flipAxis;\n this.trackView.repaintViews();\n }\n });\n }\n\n items = items.concat(MenuUtils.numericDataMenuItems(this.trackView));\n\n return items\n }\n\n /**\n * Returns a MergedFeatureCollection containing an array of features for the specified range, 1 for each track.\n */\n async getFeatures(chr, bpStart, bpEnd, bpPerPixel) {\n\n const promises = this.tracks.map((t) => t.getFeatures(chr, bpStart, bpEnd, bpPerPixel));\n const featureArrays = await Promise.all(promises);\n return new MergedFeatureCollection(featureArrays)\n }\n\n draw(options) {\n\n const mergedFeatures = options.features; // A MergedFeatureCollection\n\n for (let i = 0, len = this.tracks.length; i < len; i++) {\n const trackOptions = Object.assign({}, options);\n trackOptions.features = mergedFeatures.featureArrays[i];\n this.tracks[i].dataRange = this.dataRange;\n this.tracks[i].flipAxis = this.flipAxis;\n this.tracks[i].logScale = this.logScale;\n if (this.graphType) {\n this.tracks[i].graphType = this.graphType;\n }\n this.tracks[i].draw(trackOptions);\n }\n }\n\n popupData(clickState) {\n\n if(clickState.viewport && clickState.viewport.cachedFeatures) {\n\n const featuresArray = clickState.viewport.cachedFeatures.featureArrays;\n\n if (featuresArray && featuresArray.length === this.tracks.length) {\n // Array of feature arrays, 1 for each track\n const popupData = [];\n for (let i = 0; i < this.tracks.length; i++) {\n if (i > 0) popupData.push('
');\n popupData.push(`
${this.tracks[i].name}
`);\n const trackPopupData = this.tracks[i].popupData(clickState, featuresArray[i]);\n popupData.push(...trackPopupData);\n\n }\n return popupData\n }\n }\n }\n\n clickedFeatures(clickState) {\n\n\n // We use the cached features rather than method to avoid async load. If the\n // feature is not already loaded this won't work, but the user wouldn't be mousing over it either.\n const mergedFeaturesCollection = clickState.viewport.cachedFeatures;\n\n if(!mergedFeaturesCollection) {\n return [];\n }\n\n const genomicLocation = clickState.genomicLocation;\n const clickedFeatures = [];\n for(let features of mergedFeaturesCollection.featureArrays) {\n // When zoomed out we need some tolerance around genomicLocation\n const tolerance = (clickState.referenceFrame.bpPerPixel > 0.2) ? 3 * clickState.referenceFrame.bpPerPixel : 0.2;\n const ss = genomicLocation - tolerance;\n const ee = genomicLocation + tolerance;\n const tmp = (FeatureUtils.findOverlapping(features, ss, ee));\n for(let f of tmp) {\n clickedFeatures.push(f);\n }\n }\n return clickedFeatures;\n }\n\n\n get supportsWholeGenome() {\n return this.tracks.every(track => track.supportsWholeGenome)\n }\n}\n\n\nclass MergedFeatureCollection {\n\n constructor(featureArrays) {\n this.featureArrays = featureArrays;\n }\n\n getMax(start, end) {\n let max = -Number.MAX_VALUE;\n for (let a of this.featureArrays) {\n for (let f of a) {\n if (typeof f.value !== 'undefined' && !Number.isNaN(f.value)) {\n if (f.end < start) {\n continue\n }\n if (f.start > end) {\n break\n }\n max = Math.max(max, f.value);\n }\n }\n }\n return max\n }\n\n}\n\n/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2016-2018 The Regents of the University of California\n * Author: Jim Robinson\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\nfunction getArcType(config) {\n if (!config.arcType) {\n return \"nested\"\n }\n switch (config.arcType) {\n case \"chiapet\":\n return \"inView\"\n case \"chiapetoutbound\":\n return \"partialInView\"\n default:\n return config.arcType\n }\n}\n\nconst DEFAULT_ARC_COLOR = \"rgb(180,25,137)\";\n\nclass InteractionTrack extends TrackBase {\n\n static defaults = {\n height: 250,\n theta: Math.PI / 4,\n arcOrientation: true,\n showBlocks: true,\n blockHeight: 3,\n thickness: 1,\n alpha: 0.02,\n logScale: true,\n }\n\n constructor(config, browser) {\n super(config, browser);\n }\n\n init(config) {\n\n super.init(config);\n\n this.sinTheta = Math.sin(this.theta);\n this.cosTheta = Math.cos(this.theta);\n this.arcType = getArcType(config); // nested | proportional | inView | partialInView\n this.alpha = config.alpha || 0.02; // was: 0.15\n this.painter = {flipAxis: !this.arcOrientation, dataRange: this.dataRange, paintAxis: paintAxis};\n\n if (config.valueColumn) {\n this.valueColumn = config.valueColumn;\n this.hasValue = true;\n } else if (config.useScore) {\n this.hasValue = true;\n this.valueColumn = \"score\";\n }\n\n if (config.max) {\n this.dataRange = {\n min: config.min || 0,\n max: config.max\n };\n this.autoscale = false;\n } else {\n this.autoscale = true;\n }\n\n // Create the FeatureSource and override the default whole genome method\n if (config.featureSource) {\n this.featureSource = config.featureSource;\n delete config._featureSource;\n } else {\n this.featureSource = FeatureSource(config, this.browser.genome);\n this.featureSource.getWGFeatures = getWGFeatures;\n }\n }\n\n async postInit() {\n\n if (typeof this.featureSource.getHeader === \"function\") {\n this.header = await this.featureSource.getHeader();\n if (this.disposed) return; // This track was removed during async load\n }\n\n // Set properties from track line\n if (this.header) {\n this.setTrackProperties(this.header);\n }\n\n if (this.visibilityWindow === undefined && typeof this.featureSource.defaultVisibilityWindow === 'function') {\n this.visibilityWindow = await this.featureSource.defaultVisibilityWindow();\n this.featureSource.visibilityWindow = this.visibilityWindow; // <- this looks odd\n }\n\n return this\n }\n\n get supportsWholeGenome() {\n return true\n }\n\n async getFeatures(chr, start, end) {\n const visibilityWindow = this.visibilityWindow;\n const features = await this.featureSource.getFeatures({chr, start, end, visibilityWindow});\n\n // Check for score or value\n if (this.hasValue === undefined && features && features.length > 0) {\n this.hasValue = features[0].score !== undefined;\n }\n\n return features\n }\n\n draw(options) {\n\n if (this.arcType === \"proportional\") {\n this.drawProportional(options);\n } else if (this.arcType === \"inView\" || this.arcType === \"partialInView\") {\n this.drawProportional(options);\n } else {\n this.drawNested(options);\n }\n }\n\n drawNested(options) {\n\n const ctx = options.context;\n const pixelWidth = options.pixelWidth;\n const pixelHeight = options.pixelHeight;\n const viewportWidth = options.viewportWidth;\n const bpPerPixel = options.bpPerPixel;\n const bpStart = options.bpStart;\n const xScale = bpPerPixel;\n\n IGVGraphics.fillRect(ctx, 0, options.pixelTop, pixelWidth, pixelHeight, {'fillStyle': \"rgb(255, 255, 255)\"});\n\n const featureList = options.features;\n\n if (featureList) {\n\n // Autoscale theta\n autoscaleNested.call(this);\n const y = this.arcOrientation ? options.pixelHeight : 0;\n const direction = this.arcOrientation;\n\n ctx.font = \"8px sans-serif\";\n ctx.textAlign = \"center\";\n\n for (let feature of featureList) {\n\n // Reset transient property drawState. An undefined value => feature has not been drawn.\n feature.drawState = undefined;\n\n let color;\n if (typeof this.color === 'function') {\n color = this.color(feature);\n } else {\n color = this.color || feature.color || DEFAULT_ARC_COLOR;\n if (color && this.config.useScore) {\n color = getAlphaColor(color, scoreShade(feature.score));\n }\n }\n\n ctx.lineWidth = feature.thickness || this.thickness || 1;\n\n if (feature.chr1 === feature.chr2 || feature.chr === 'all') {\n\n const {m1, m2} = getMidpoints(feature, this.browser.genome);\n\n let pixelStart = Math.round((m1 - bpStart) / xScale);\n let pixelEnd = Math.round((m2 - bpStart) / xScale);\n if (pixelEnd < 0 || pixelStart > pixelWidth) continue\n\n let w = (pixelEnd - pixelStart);\n if (w < 3) {\n w = 3;\n pixelStart--;\n }\n\n const a = w / 2;\n const r = a / this.sinTheta;\n const b = this.cosTheta * r;\n const xc = pixelStart + a;\n\n let yc, startAngle, endAngle;\n if (direction) { // UP\n yc = this.height + b;\n startAngle = Math.PI + Math.PI / 2 - this.theta;\n endAngle = Math.PI + Math.PI / 2 + this.theta;\n } else { // DOWN\n yc = -b;\n startAngle = Math.PI / 2 - this.theta;\n endAngle = Math.PI / 2 + this.theta;\n }\n\n if (this.showBlocks && feature.chr !== 'all') {\n const s1 = (feature.start1 - bpStart) / xScale;\n const e1 = (feature.end1 - bpStart) / xScale;\n const s2 = (feature.start2 - bpStart) / xScale;\n const e2 = (feature.end2 - bpStart) / xScale;\n const hb = this.arcOrientation ? -this.blockHeight : this.blockHeight;\n ctx.fillRect(s1, y, e1 - s1, hb);\n ctx.fillRect(s2, y, e2 - s2, hb);\n }\n\n // Alpha shade (de-emphasize) arcs that extend beyond viewport, unless alpha shading is used for score.\n if (color && !this.config.useScore && w > viewportWidth) {\n color = getAlphaColor(color, this.alpha);\n }\n ctx.strokeStyle = color;\n ctx.fillStyle = color;\n ctx.beginPath();\n ctx.arc(xc, yc, r, startAngle, endAngle, false);\n ctx.stroke();\n feature.drawState = {xc, yc, r};\n } else {\n\n let pixelStart = Math.round((feature.start - bpStart) / xScale);\n let pixelEnd = Math.round((feature.end - bpStart) / xScale);\n if (pixelEnd < 0 || pixelStart > pixelWidth) continue\n\n let w = (pixelEnd - pixelStart);\n if (w < 3) {\n w = 3;\n pixelStart--;\n }\n const otherChr = feature.chr === feature.chr1 ? feature.chr2 : feature.chr1;\n ctx.strokeStyle = color;\n // get a sense of trans \"spread\"\n ctx.fillStyle = getAlphaColor(getChrColor(otherChr), 0.5);\n // ctx.fillStyle = color\n\n if (direction) {\n // UP\n ctx.fillRect(pixelStart, this.height / 2, w, this.height / 2);\n ctx.fillText(otherChr, pixelStart + w / 2, this.height / 2 - 5);\n feature.drawState = {x: pixelStart, y: this.height / 2, w: w, h: this.height / 2};\n } else {\n ctx.fillRect(pixelStart, 0, w, this.height / 2);\n ctx.fillText(otherChr, pixelStart + w / 2, this.height / 2 + 13);\n feature.drawState = {x: pixelStart, y: 0, w: w, h: this.height / 2};\n }\n }\n }\n }\n\n function autoscaleNested() {\n let max = 0;\n for (let feature of featureList) {\n let pixelStart = (feature.start - bpStart) / xScale;\n let pixelEnd = (feature.end - bpStart) / xScale;\n if (pixelStart >= 0 && pixelEnd <= pixelWidth) {\n max = Math.max(max, pixelEnd - pixelStart);\n }\n }\n let a = Math.min(viewportWidth, max) / 2;\n if (max > 0) {\n let coa = (pixelHeight - 10) / a;\n this.theta = estimateTheta(coa);\n this.sinTheta = Math.sin(this.theta);\n this.cosTheta = Math.cos(this.theta);\n }\n }\n }\n\n getScaleFactor(min, max, height, logScale) {\n const scale = logScale ? height / (Math.log10(max + 1) - (min <= 0 ? 0 : Math.log10(min + 1))) : height / (max - min);\n return scale\n }\n\n drawProportional(options) {\n\n const ctx = options.context;\n const pixelWidth = options.pixelWidth;\n const pixelHeight = options.pixelHeight;\n const bpPerPixel = options.bpPerPixel;\n const bpStart = options.bpStart;\n const xScale = bpPerPixel;\n const refStart = options.referenceFrame.start;\n const refEnd = options.referenceFrame.end;\n\n\n IGVGraphics.fillRect(ctx, 0, options.pixelTop, pixelWidth, pixelHeight, {'fillStyle': \"rgb(255, 255, 255)\"});\n\n const featureList = options.features;\n\n if (featureList && featureList.length > 0) {\n\n // we use the min as a filter but not moving the axis\n const effectiveMin = 0;\n const yScale = this.getScaleFactor(effectiveMin, this.dataRange.max, options.pixelHeight - 1, this.logScale);\n const y = this.arcOrientation ? options.pixelHeight : 0;\n\n for (let feature of featureList) {\n\n // Reset transient property drawState. An undefined value => feature has not been drawn.\n feature.drawState = undefined;\n\n const value = this.valueColumn ? feature[this.valueColumn] : feature.score;\n if (value === undefined || Number.isNaN(value)) continue\n\n const radiusY = Math.round((this.logScale ? Math.log10(value + 1) : value) * yScale);\n\n if (feature.chr1 === feature.chr2 || feature.chr === 'all') {\n\n const {m1, m2} = getMidpoints(feature, this.browser.genome);\n\n let pixelStart = Math.round((m1 - bpStart) / xScale);\n let pixelEnd = Math.round((m2 - bpStart) / xScale);\n let w = (pixelEnd - pixelStart);\n if (w < 3) {\n w = 3;\n pixelStart--;\n }\n\n // Various filters\n if (value < this.dataRange.min || value > this.dataRange.max) continue\n if (\"proportional\" !== this.arcType) {\n const showOutbound = (this.arcType === \"partialInView\");\n const within = (m1 >= refStart && m2 <= refEnd);\n let outBound = false;\n let inBound = false;\n if (!within && showOutbound) {\n outBound = (refStart <= m1 && m1 <= refEnd);\n if (!outBound) inBound = (refStart <= m2 && m2 <= refEnd);\n }\n if (!(within || outBound || inBound)) continue\n }\n\n\n const radiusX = w / 2;\n const xc = pixelStart + w / 2;\n feature.drawState = {xc, yc: y, radiusX, radiusY};\n\n // const arcKey = ((pixelStart << 16) | pixelEnd)\n // let arc = arcCaches.get(arcKey)\n // if (arc !== undefined) {\n // if (arc.has(radiusY)) {\n // continue\n // }\n // arc.add(radiusY)\n // } else {\n // let arcHeights = new Set()\n // arcHeights.add(radiusY)\n // arcCaches.set(arcKey, arcHeights)\n // }\n\n const counterClockwise = this.arcOrientation ? true : false;\n const color = feature.color || this.color;\n ctx.strokeStyle = color;\n ctx.lineWidth = feature.thickness || this.thickness || 1;\n\n if (true === ctx.isSVG) {\n ctx.strokeEllipse(xc, y, radiusX, radiusY, 0, 0, Math.PI, counterClockwise);\n } else {\n ctx.beginPath();\n ctx.ellipse(xc, y, radiusX, radiusY, 0, 0, Math.PI, counterClockwise);\n ctx.stroke();\n }\n\n if (this.alpha) {\n ctx.fillStyle = getAlphaColor(color, this.alpha);\n if (true === ctx.isSVG) {\n ctx.fillEllipse(xc, y, radiusX, radiusY, 0, 0, Math.PI, counterClockwise);\n } else {\n ctx.fill();\n }\n }\n\n if (this.showBlocks && feature.chr !== 'all') {\n ctx.fillStyle = color;\n const s1 = (feature.start1 - bpStart) / xScale;\n const e1 = (feature.end1 - bpStart) / xScale;\n const s2 = (feature.start2 - bpStart) / xScale;\n const e2 = (feature.end2 - bpStart) / xScale;\n const hb = this.arcOrientation ? -this.blockHeight : this.blockHeight;\n ctx.fillRect(s1, y, e1 - s1, hb);\n ctx.fillRect(s2, y, e2 - s2, hb);\n }\n\n } else {\n // Inter chromosome\n let pixelStart = Math.round((feature.start - bpStart) / xScale);\n let pixelEnd = Math.round((feature.end - bpStart) / xScale);\n if (pixelEnd < 0 || pixelStart > pixelWidth || value < this.dataRange.min || value > this.dataRange.max) continue\n\n const h = Math.min(radiusY, this.height - 13); // Leave room for text\n let w = (pixelEnd - pixelStart);\n if (w < 3) {\n w = 3;\n pixelStart--;\n }\n const otherChr = feature.chr === feature.chr1 ? feature.chr2 : feature.chr1;\n ctx.font = \"8px sans-serif\";\n ctx.textAlign = \"center\";\n // get a sense of trans \"spread\"\n ctx.fillStyle = getAlphaColor(getChrColor(otherChr), 0.5);\n if (this.arcOrientation) {\n // UP\n const y = this.height - h;\n ctx.fillRect(pixelStart, y, w, h);\n ctx.fillText(otherChr, pixelStart + w / 2, y - 5);\n feature.drawState = {x: pixelStart, y, w, h};\n } else {\n ctx.fillRect(pixelStart, 0, w, h);\n ctx.fillText(otherChr, pixelStart + w / 2, h + 13);\n feature.drawState = {x: pixelStart, y: 0, w, h};\n }\n }\n }\n }\n }\n\n clearAxis(ctx, pixelWidth, pixelHeight) {\n IGVGraphics.fillRect(ctx, 0, 0, pixelWidth, pixelHeight, {'fillStyle': \"rgb(255, 255, 255)\"});\n }\n\n paintAxis(ctx, pixelWidth, pixelHeight) {\n // dataRane is interpreted differently for interactino tracks -- all arcs are drawn from \"zero\", irrespective of dataRange.min\n const axisRange = {min: 0, max: this.dataRange.max};\n if (this.arcType === \"proportional\") {\n this.painter.flipAxis = !this.arcOrientation;\n this.painter.dataRange = axisRange;\n this.painter.paintAxis(ctx, pixelWidth, pixelHeight);\n } else if (this.arcType === \"inView\" || this.arcType === \"partialInView\") {\n this.painter.flipAxis = !this.arcOrientation;\n this.painter.dataRange = axisRange;\n this.painter.paintAxis(ctx, pixelWidth, pixelHeight);\n } else {\n this.clearAxis(ctx, pixelWidth, pixelHeight);\n }\n }\n\n menuItemList() {\n\n let items = [];\n\n if (this.hasValue) {\n items.push(\"
\");\n const lut =\n {\n \"nested\": \"Nested\",\n \"proportional\": \"Proportional - All\",\n \"inView\": \"Proportional - Both Ends in View\",\n \"partialInView\": \"Proportional - One End in View\"\n };\n items.push(\"Arc Type\");\n for (let arcType of [\"nested\", \"proportional\", \"inView\", \"partialInView\"]) {\n items.push(\n {\n object: $$1(createCheckbox(lut[arcType], arcType === this.arcType)),\n click: () => {\n this.arcType = arcType;\n this.trackView.repaintViews();\n }\n });\n }\n }\n items.push(\"
\");\n\n items.push({\n name: \"Toggle arc direction\",\n click: () => {\n this.arcOrientation = !this.arcOrientation;\n this.trackView.repaintViews();\n }\n });\n items.push({\n name: this.showBlocks ? \"Hide Blocks\" : \"Show Blocks\",\n click: () => {\n this.showBlocks = !this.showBlocks;\n this.trackView.repaintViews();\n }\n });\n\n\n if (this.arcType === \"proportional\" || this.arcType === \"inView\" || this.arcType === \"partialInView\") {\n // MenuUtils.numericDataMenuItems(this.trackView).forEach(item => items.push(item))\n items = items.concat(MenuUtils.numericDataMenuItems(this.trackView));\n }\n\n if (this.browser.circularView) {\n items.push('
');\n items.push({\n label: 'Add interactions to circular view',\n click: () => {\n for (let viewport of this.trackView.viewports) {\n this.addChordsForViewport(viewport.referenceFrame);\n }\n }\n });\n }\n\n return items\n }\n\n contextMenuItemList(clickState) {\n\n // Experimental JBrowse feature\n if (this.browser.circularView) {\n const viewport = clickState.viewport;\n const list = [];\n\n list.push({\n label: 'Add interactions to circular view',\n click: () => {\n const refFrame = viewport.referenceFrame;\n // first pass: to get all the relevant features\n this.addChordsForViewport(refFrame);\n }\n });\n\n list.push('
');\n return list\n }\n }\n\n /**\n * Add chords to the circular view for the given viewport, represented by its reference frame\n * @param refFrame\n */\n addChordsForViewport(refFrame) {\n const cachedFeatures = \"all\" === refFrame.chr ?\n this.featureSource.getAllFeatures() :\n this.featureSource.featureCache.queryFeatures(refFrame.chr, refFrame.start, refFrame.end);\n\n // inView features are simply features that have been drawn, i.e. have a drawState\n const inView = cachedFeatures.filter(f => f.drawState);\n if (inView.length === 0) return;\n\n const chords = makeBedPEChords(inView);\n sendChords(chords, this, refFrame, 0.5);\n //\n //\n // // for filtered set, distinguishing the chromosomes is more critical than tracks\n // const chordSetColor = IGVColor.addAlpha(\"all\" === refFrame.chr ? this.color : getChrColor(refFrame.chr), 0.5)\n // const trackColor = IGVColor.addAlpha(this.color, 0.5)\n //\n // // name the chord set to include locus and filtering information\n // const encodedName = this.name.replaceAll(' ', '%20')\n // const chordSetName = \"all\" === refFrame.chr ?\n // encodedName :\n // `${encodedName} (${refFrame.chr}:${refFrame.start}-${refFrame.end} ; range:${this.dataRange.min}-${this.dataRange.max})`\n // this.browser.circularView.addChords(chords, {track: chordSetName, color: chordSetColor, trackColor: trackColor})\n }\n\n doAutoscale(features) {\n\n // if (\"proportional\" === this.arcType) {\n let max = 0;\n if (features) {\n for (let f of features) {\n const v = this.valueColumn ? f[this.valueColumn] : f.score;\n if (!Number.isNaN(v)) {\n max = Math.max(max, v);\n }\n }\n }\n return {min: 0, max: max}\n // }\n }\n\n popupData(clickState, features) {\n\n if (features === undefined) features = this.clickedFeatures(clickState);\n\n const data = [];\n for (let feature of features) {\n\n const f = feature._ || feature; // For \"whole genome\" features, which keeps a pointer to the original\n\n data.push({name: \"Region 1\", value: positionString(f.chr1, f.start1, f.end1, f.strand1)});\n data.push({name: \"Region 2\", value: positionString(f.chr2, f.start2, f.end2, f.strand2)});\n if (f.name) {\n data.push({name: \"Name\", value: f.name});\n }\n if (f.value !== undefined) {\n data.push({name: \"Value\", value: f.value});\n }\n if (f.score !== undefined) {\n data.push({name: \"Score\", value: f.score});\n }\n\n\n if (f.extras && this.header && this.header.columnNames) {\n const columnNames = this.header.columnNames;\n const stdColumns = this.header.hiccups ? 6 : 10;\n for (let i = stdColumns; i < columnNames.length; i++) {\n if (this.header.colorColumn === i) continue;\n if (columnNames[i] === 'info') {\n extractInfoColumn(data, f.extras[i - stdColumns]);\n } else {\n data.push({name: columnNames[i], value: f.extras[i - stdColumns]});\n }\n }\n }\n // For now just return the top hit\n break\n\n //if (data.length > 0) {\n // data.push(\"
\");\n // }\n }\n return data\n }\n\n clickedFeatures(clickState) {\n\n // We use the cached features rather than method to avoid async load. If the\n // feature is not already loaded this won't work, but the user wouldn't be mousing over it either.\n const featureList = clickState.viewport.cachedFeatures;\n const candidates = [];\n if (featureList) {\n const proportional = (this.arcType === \"proportional\" || this.arcType === \"inView\" || this.arcType === \"partialInView\");\n\n for (let feature of featureList) {\n\n if (!feature.drawState) continue\n\n if (feature.chr1 === feature.chr2 || feature.chr === 'all') {\n if (proportional) {\n //(x-xc)^2/radiusX^2 + (y-yc)^2/radiusY^2 <= 1\n const {xc, yc, radiusX, radiusY} = feature.drawState;\n const dx = clickState.canvasX - xc;\n const dy = clickState.canvasY - yc;\n const score = (dx / radiusX) * (dx / radiusX) + (dy / radiusY) * (dy / radiusY);\n if (score <= 1) {\n candidates.push({score: 1 / score, feature});\n }\n } else {\n const {xc, yc, r} = feature.drawState;\n const dx = clickState.canvasX - xc;\n const dy = clickState.canvasY - yc;\n const score = Math.abs(Math.sqrt(dx * dx + dy * dy) - r);\n if (score < 5) {\n candidates.push({score, feature});\n }\n }\n } else {\n const {x, y, w, h} = feature.drawState;\n const tolerance = 5;\n if (clickState.canvasX >= x - tolerance && clickState.canvasX <= x + w + tolerance &&\n clickState.canvasY >= y && clickState.canvasY <= y + h) {\n const score = -Math.abs(clickState.canvasX - (x + w / 2));\n candidates.push({score, feature});\n break\n }\n }\n }\n }\n\n if (candidates.length > 1) {\n candidates.sort((a, b) => a.score - b.score);\n }\n return candidates.map((c) => c.feature)\n }\n}\n\nfunction getMidpoints(feature, genome) {\n let m1 = (feature.start1 + feature.end1) / 2;\n let m2 = (feature.start2 + feature.end2) / 2;\n if (feature.chr === 'all') {\n m1 = genome.getGenomeCoordinate(feature.chr1, m1);\n m2 = genome.getGenomeCoordinate(feature.chr2, m2);\n }\n if (m1 > m2) {\n const tmp = m1;\n m1 = m2;\n m2 = tmp;\n }\n return {m1, m2}\n}\n\nfunction positionString(chr, start, end, strand) {\n\n return strand && strand !== '.' ?\n `${chr}:${numberFormatter$1(start + 1)}-${numberFormatter$1(end)} (${strand})` :\n `${chr}:${numberFormatter$1(start + 1)}-${numberFormatter$1(end)}`\n}\n\n/**\n * Estimate theta given the ratio of track height to 1/2 the feature width (coa). This relationship is approximately linear.\n */\nfunction estimateTheta(x) {\n let coa = [0.01570925532366355, 0.15838444032453644, 0.3249196962329063, 0.5095254494944288, 0.7265425280053609, 0.9999999999999999];\n let theta = [0.031415926535897934, 0.3141592653589793, 0.6283185307179586, 0.9424777960769379, 1.2566370614359172, 1.5707963267948966];\n let idx;\n\n for (idx = 0; idx < coa.length; idx++) {\n if (coa[idx] > x) {\n break\n }\n }\n\n let left = idx === 0 ? 0 : coa[idx - 1];\n let right = idx < coa.length ? coa[idx] : 1;\n let r = (x - left) / (right - left);\n\n let thetaLeft = idx === 0 ? 0 : theta[idx - 1];\n let thetaRight = idx < theta.length ? theta[idx] : Math.PI / 2;\n\n return Math.min(Math.PI/2, (thetaLeft + r * (thetaRight - thetaLeft)))\n\n}\n\nconst colorAlphaCache = new Map();\n\nfunction getAlphaColor(color, alpha) {\n const key = `${color}_${alpha}`;\n let c = colorAlphaCache.get(key);\n if (!c) {\n c = IGVColor.addAlpha(color, alpha);\n colorAlphaCache.set(key, c);\n }\n return c\n}\n\n\n/**\n * Called in the context of FeatureSource (i.e. this == the feature source (a TextFeatureSource) for the track\n *\n * @param allFeatures\n * @returns {[]}\n */\nfunction getWGFeatures(allFeatures) {\n\n const makeWGFeature = (f) => {\n const wg = Object.assign({}, f);\n wg.chr = \"all\";\n wg.start = genome.getGenomeCoordinate(f.chr1, f.start1);\n wg.end = genome.getGenomeCoordinate(f.chr2, f.end2);\n return wg\n };\n\n const genome = this.genome;\n\n // First pass -- find the max score feature\n let maxScoreFeature;\n let totalFeatureCount = 0;\n for (let c of genome.wgChromosomeNames) {\n let chrFeatures = allFeatures[c];\n if (chrFeatures) {\n for (let f of chrFeatures) {\n if (!f.dup) {\n totalFeatureCount++;\n if (f.score && (!maxScoreFeature || f.score > maxScoreFeature.score)) {\n maxScoreFeature = f;\n }\n }\n }\n }\n }\n\n const maxCount = this.maxWGCount;\n const nBins = maxScoreFeature && maxScoreFeature.score > 0 && totalFeatureCount > maxCount ? 5 : 1; // TODO make a function of total # of features & maxCount?\n const featuresPerBin = Math.floor(maxCount / nBins);\n const binSize = maxScoreFeature && maxScoreFeature.score > 0 ? Math.log(maxScoreFeature.score) / nBins : Number.MAX_SAFE_INTEGER;\n\n let binnedFeatures = [];\n let counts = [];\n for (let i = 0; i < nBins; i++) {\n counts.push([0]);\n binnedFeatures.push([]);\n }\n\n for (let c of genome.wgChromosomeNames) {\n let chrFeatures = allFeatures[c];\n if (chrFeatures) {\n for (let f of chrFeatures) {\n if (!f.dup) {\n const bin = f.score ? Math.max(0, Math.min(nBins - 1, Math.floor(Math.log(f.score) / binSize))) : 0;\n if (binnedFeatures[bin].length < featuresPerBin) {\n binnedFeatures[bin].push(makeWGFeature(f));\n } else {\n //Reservoir sampling\n const samplingProb = featuresPerBin / (counts[bin] + 1);\n if (Math.random() < samplingProb) {\n const idx = Math.floor(Math.random() * (featuresPerBin - 1));\n binnedFeatures[bin][idx] = makeWGFeature(f);\n }\n }\n counts[bin]++;\n }\n }\n }\n }\n\n let wgFeatures;\n if (nBins === 1) {\n wgFeatures = binnedFeatures[0];\n } else {\n wgFeatures = [];\n for (let bf of binnedFeatures) {\n for (let f of bf) wgFeatures.push(f);\n }\n // Keep the feature with max score\n if (maxScoreFeature) {\n wgFeatures.push(makeWGFeature(maxScoreFeature));\n }\n wgFeatures.sort(function (a, b) {\n return a.start - b.start\n });\n console.log(wgFeatures.length);\n }\n\n\n return wgFeatures\n}\n\n/**\n * Extract a gff style info column for popup text. This convention used by 10X for bedpe files\n * ALLELIC_FRAC=0.0375670840787;BLACK1=.;BLACK2=.;...\n * @param data\n * @param str\n */\nfunction extractInfoColumn(data, str) {\n const kvs = str.split(';');\n for (let t of kvs) {\n const kv = t.split('=');\n if (kv.length === 2) {\n data.push({name: kv[0], value: kv[1]});\n }\n }\n\n}\n\n/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2016 University of California San Diego\n * Author: Jim Robinson\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\nconst isString = isString$2;\n\nconst DEFAULT_COLOR = \"rgb(0,0,150)\";\nconst DEFAULT_VISIBILITY_WINDOW = 1000000;\nconst TOP_MARGIN = 10;\nconst STANDARD_FIELDS = new Map([[\"REF\", \"referenceBases\"], [\"ALT\", \"alternateBases\"], [\"QUAL\", \"quality\"], [\"FILTER\", \"filter\"]]);\n\n\nclass VariantTrack extends TrackBase {\n\n static defaults = {\n displayMode: \"EXPANDED\",\n sortDirection: \"ASC\",\n showGenotypes: true,\n squishedVariantHeight: 2,\n squishedCallHeight: 1,\n expandedCallHeight: 10,\n expandedVGap: 2,\n squishedVGap: 1,\n expandedGroupGap: 10,\n squishedGroupGap: 5,\n featureHeight: 14,\n noGenotypeColor: \"rgb(200,180,180)\",\n noCallColor: \"rgb(225, 225, 225)\",\n nonRefColor: \"rgb(200, 200, 215)\",\n mixedColor: \"rgb(200, 220, 200)\",\n homrefColor: \"rgb(200, 200, 200)\",\n homvarColor: \"rgb(17,248,254)\",\n hetvarColor: \"rgb(34,12,253)\",\n colorBy: undefined,\n visibilityWindow: undefined,\n labelDisplayMode: undefined,\n type: \"variant\"\n }\n\n constructor(config, browser) {\n super(config, browser);\n }\n\n init(config) {\n\n super.init(config);\n\n this.expandedVariantHeight = config.expandedVariantHeight || config.variantHeight || 10;\n\n this.featureSource = FeatureSource(config, this.browser.genome);\n\n this._initColorBy = config.colorBy;\n if (config.colorTable) {\n this.colorTables = new Map();\n this.colorTables.set(config.colorBy, new ColorTable(config.colorTable));\n }\n this._color = config.color;\n this._strokecolor = config.strokecolor;\n this._context_hook = config.context_hook;\n\n\n // The number of variant rows are computed dynamically, but start with \"1\" by default\n this.variantRowCount(1);\n\n }\n\n async postInit() {\n\n this.header = await this.getHeader(); // cricital, don't remove'\n if (this.disposed) return // This track was removed during async load\n if (undefined === this.visibilityWindow && this.config.indexed !== false) {\n const fn = isFile(this.config.url) ? this.config.url.name : this.config.url;\n if (isString(fn) && fn.toLowerCase().includes(\"gnomad\")) {\n this.visibilityWindow = 1000; // these are known to be very dense\n } else if (typeof this.featureSource.defaultVisibilityWindow === 'function') {\n this.visibilityWindow = await this.featureSource.defaultVisibilityWindow();\n } else {\n this.visibilityWindow = DEFAULT_VISIBILITY_WINDOW;\n }\n }\n return this\n\n }\n\n get supportsWholeGenome() {\n return this.config.indexed === false || this.config.supportsWholeGenome === true\n }\n\n get color() {\n return this._color || DEFAULT_COLOR\n }\n\n set color(c) {\n this._color = c;\n this.colorBy = undefined;\n }\n\n async getHeader() {\n\n if (!this.header) {\n if (typeof this.featureSource.getHeader === \"function\") {\n const header = await this.featureSource.getHeader();\n if (header) {\n this.callSets = header.callSets || [];\n }\n this.header = header;\n }\n this.sampleNames = this.callSets ? this.callSets.map(cs => cs.name) : [];\n }\n\n return this.header\n }\n\n getCallsetsLength() {\n return this.callSets ? this.callSets.length : 0\n }\n\n async getFeatures(chr, start, end, bpPerPixel) {\n\n if (this.header === undefined) {\n this.header = await this.getHeader();\n }\n return this.featureSource.getFeatures({chr, start, end, bpPerPixel, visibilityWindow: this.visibilityWindow})\n }\n\n hasSamples() {\n return this.getCallsetsLength() > 0\n }\n\n getSamples() {\n return {\n yOffset: this.sampleYOffset,\n names: this.sampleNames,\n height: this.sampleHeight\n }\n }\n\n /**\n * The required height in pixels required for the track content. This is not the visible track height, which\n * can be smaller (with a scrollbar) or larger.\n *\n * @param features\n * @returns {*}\n */\n computePixelHeight(features) {\n\n if (!features || features.length == 0) return TOP_MARGIN\n\n const nVariantRows = (this.displayMode === \"COLLAPSED\") ? 1 : this.nVariantRows;\n const vGap = (this.displayMode === \"SQUISHED\") ? this.squishedVGap : this.expandedVGap;\n const variantHeight = (this.displayMode === \"SQUISHED\") ? this.squishedVariantHeight : this.expandedVariantHeight;\n const callHeight = (this.displayMode === \"SQUISHED\") ? this.squishedCallHeight : this.expandedCallHeight;\n const nCalls = this.showGenotypes === false ? 0 : this.getCallsetsLength() * nVariantRows;\n const h = TOP_MARGIN + nVariantRows * (variantHeight + vGap);\n return h + vGap + (nCalls + 1) * (callHeight + vGap)\n\n }\n\n variantRowCount(count) {\n this.nVariantRows = count;\n }\n\n draw({context, pixelWidth, pixelHeight, bpPerPixel, bpStart, pixelTop, features}) {\n\n IGVGraphics.fillRect(context, 0, pixelTop, pixelWidth, pixelHeight, {'fillStyle': \"rgb(255, 255, 255)\"});\n\n const vGap = (\"SQUISHED\" === this.displayMode) ? this.squishedVGap : this.expandedVGap;\n const rowCount = (\"COLLAPSED\" === this.displayMode) ? 1 : this.nVariantRows;\n const variantHeight = (\"SQUISHED\" === this.displayMode) ? this.squishedVariantHeight : this.expandedVariantHeight;\n this.variantBandHeight = TOP_MARGIN + rowCount * (variantHeight + vGap);\n\n let callSets = this.callSets;\n if (!callSets && this._f) {\n callSets = this._f.callSets; // \"Complementary\" variant for structural variants\n }\n const nCalls = this.getCallsetsLength();\n if (callSets && nCalls > 0 && this.showGenotypes !== false) {\n IGVGraphics.strokeLine(context, 0, this.variantBandHeight, pixelWidth, this.variantBandHeight, {strokeStyle: 'rgb(224,224,224) '});\n }\n\n if (features) {\n\n const callHeight = (\"SQUISHED\" === this.displayMode) ? this.squishedCallHeight : this.expandedCallHeight;\n const vGap = (\"SQUISHED\" === this.displayMode) ? this.squishedVGap : this.expandedVGap;\n const bpEnd = bpStart + pixelWidth * bpPerPixel + 1;\n\n // Loop through variants. A variant == a row in a VCF file\n for (let variant of features) {\n\n if (variant.end < bpStart) continue\n if (variant.start > bpEnd) break\n\n const variantHeight = (\"SQUISHED\" === this.displayMode) ? this.squishedVariantHeight : this.expandedVariantHeight;\n const y = TOP_MARGIN + (\"COLLAPSED\" === this.displayMode ? 0 : variant.row * (variantHeight + vGap));\n const h = variantHeight;\n\n // Compute pixel width. Minimum width is 3 pixels, if > 5 pixels create gap between variants\n let x = Math.round((variant.start - bpStart) / bpPerPixel);\n let x1 = Math.round((variant.end - bpStart) / bpPerPixel);\n let w = Math.max(1, x1 - x);\n if (w < 3) {\n w = 3;\n x -= 1;\n } else if (w > 5) {\n x += 1;\n w -= 2;\n }\n context.fillStyle = this.getColorForFeature(variant);\n context.fillRect(x, y, w, h);\n\n //only paint stroke if a color is defined\n let strokecolor = this.getVariantStrokecolor(variant);\n if (strokecolor) {\n context.strokeStyle = strokecolor;\n context.strokeRect(x, y, w, h);\n }\n\n // call hook if _context_hook fn is defined\n this.callContextHook(variant, context, x, y, w, h);\n\n variant.pixelRect = {x, y, w, h};\n\n // Loop though the calls for this variant. There will potentially be a call for each sample.\n if (nCalls > 0 && this.showGenotypes !== false) {\n\n const nVariantRows = \"COLLAPSED\" === this.displayMode ? 1 : this.nVariantRows;\n this.sampleYOffset = this.variantBandHeight + vGap;\n this.sampleHeight = nVariantRows * (callHeight + vGap); // For each sample, there is a call for each variant at this position\n\n let sampleNumber = 0;\n if (callSets && variant.calls) {\n for (let callSet of callSets) {\n const call = variant.calls[callSet.id];\n if (call) {\n const row = \"COLLAPSED\" === this.displayMode ? 0 : variant.row;\n const py = this.sampleYOffset + sampleNumber * this.sampleHeight + row * (callHeight + vGap);\n let allVar = true; // until proven otherwise\n let allRef = true;\n let noCall = false;\n\n if (call.genotype) {\n for (let g of call.genotype) {\n if ('.' === g) {\n noCall = true;\n break\n } else {\n if (g !== 0) allRef = false;\n if (g === 0) allVar = false;\n }\n }\n }\n\n if (!call.genotype) {\n context.fillStyle = this.noGenotypeColor;\n } else if (noCall) {\n context.fillStyle = this.noCallColor;\n } else if (allRef) {\n context.fillStyle = this.homrefColor;\n } else if (allVar) {\n context.fillStyle = this.homvarColor;\n } else {\n context.fillStyle = this.hetvarColor;\n }\n\n context.fillRect(x, py, w, callHeight);\n\n callSet.pixelRect = {x, y: py, w, h: callHeight};\n }\n sampleNumber++;\n }\n }\n }\n }\n\n } else {\n console.log(\"No feature list\");\n }\n };\n\n\n getColorForFeature(variant) {\n\n const v = variant._f || variant;\n let variantColor;\n\n if (this.colorBy) {\n const colorBy = this.colorBy;\n let value;\n if (v.info.hasOwnProperty(colorBy)) {\n value = v.info[colorBy];\n } else if (STANDARD_FIELDS.has(colorBy)) {\n const key = STANDARD_FIELDS.get(colorBy);\n value = v[key];\n }\n variantColor = this.getVariantColorTable(colorBy).getColor(value);\n if (!variantColor) {\n variantColor = \"gray\";\n }\n\n } else if (this._color) {\n variantColor = (typeof this._color === \"function\") ? this._color(variant) : this._color;\n } else if (\"NONVARIANT\" === v.type) {\n variantColor = this.nonRefColor;\n } else if (\"MIXED\" === v.type) {\n variantColor = this.mixedColor;\n } else {\n variantColor = this.color;\n }\n return variantColor\n }\n\n\n getVariantStrokecolor(variant) {\n\n const v = variant._f || variant;\n let variantStrokeColor;\n\n if (this._strokecolor) {\n variantStrokeColor = (typeof this._strokecolor === \"function\") ? this._strokecolor(v) : this._strokecolor;\n } else {\n variantStrokeColor = undefined;\n }\n return variantStrokeColor\n }\n\n callContextHook(variant, context, x, y, w, h) {\n if (this._context_hook) {\n if (typeof this._context_hook === \"function\") {\n const v = variant._f || variant;\n\n context.save();\n this._context_hook(v, context, x, y, w, h);\n context.restore();\n }\n }\n }\n\n clickedFeatures(clickState) {\n\n let featureList = super.clickedFeatures(clickState);\n\n const vGap = (this.displayMode === 'EXPANDED') ? this.expandedVGap : this.squishedVGap;\n const callHeight = vGap + (\"SQUISHED\" === this.displayMode ? this.squishedCallHeight : this.expandedCallHeight);\n // Find the variant row (i.e. row assigned during feature packing)\n const yOffset = clickState.y;\n if (yOffset <= this.variantBandHeight) {\n // Variant\n const variantHeight = (\"SQUISHED\" === this.displayMode) ? this.squishedVariantHeight : this.expandedVariantHeight;\n const variantRow = Math.floor((yOffset - TOP_MARGIN) / (variantHeight + vGap));\n if (\"COLLAPSED\" !== this.displayMode) {\n featureList = featureList.filter(f => f.row === variantRow);\n }\n } else if (this.callSets) {\n const callSets = this.callSets;\n const sampleY = yOffset - this.variantBandHeight;\n const sampleRow = Math.floor(sampleY / this.sampleHeight);\n if (sampleRow >= 0 && sampleRow < callSets.length) {\n const variantRow = Math.floor((sampleY - sampleRow * this.sampleHeight) / callHeight);\n const variants = \"COLLAPSED\" === this.displayMode ? featureList : featureList.filter(f => f.row === variantRow);\n const cs = callSets[sampleRow];\n featureList = variants.map(v => {\n const call = v.calls[cs.id];\n expandGenotype(call, v);\n return call\n });\n }\n }\n\n return featureList\n }\n\n\n /**\n * Return \"popup data\" for feature @ genomic location. Data is an array of key-value pairs\n */\n popupData(clickState, featureList) {\n\n if (featureList === undefined) featureList = this.clickedFeatures(clickState);\n const genomicLocation = clickState.genomicLocation;\n const genomeID = this.browser.genome.id;\n const sampleInformation = this.browser.sampleInformation;\n\n let popupData = [];\n for (let v of featureList) {\n\n const f = v._f || v; // Get real variant from psuedo-variant, e.g. whole genome or SV mate\n\n if (popupData.length > 0) {\n popupData.push({html: '
'});\n }\n\n if (typeof f.popupData === 'function') {\n const v = f.popupData(genomicLocation, genomeID);\n Array.prototype.push.apply(popupData, v);\n } else {\n // Assume this is a call (genotype)\n const call = f;\n\n if (call.callSetName !== undefined) {\n popupData.push({name: 'Name', value: call.callSetName});\n }\n\n if (call.genotypeName) {\n popupData.push({name: 'Genotype', value: call.genotypeName});\n }\n\n if (call.phaseset !== undefined) {\n popupData.push({name: 'Phase set', value: call.phaseset});\n }\n if (call.genotypeLikelihood !== undefined) {\n popupData.push({name: 'genotypeLikelihood', value: call.genotypeLikelihood.toString()});\n }\n\n if (sampleInformation) {\n var attr = sampleInformation.getAttributes(call.callSetName);\n if (attr) {\n Object.keys(attr).forEach(function (attrName) {\n var displayText = attrName.replace(/([A-Z])/g, \" $1\");\n displayText = displayText.charAt(0).toUpperCase() + displayText.slice(1);\n popupData.push({name: displayText, value: attr[attrName]});\n });\n }\n }\n\n var infoKeys = Object.keys(call.info);\n if (infoKeys.length) {\n popupData.push('
');\n }\n infoKeys.forEach(function (key) {\n popupData.push({name: key, value: decodeURIComponent(call.info[key])});\n });\n }\n }\n return popupData\n\n }\n\n\n// VariantTrack.prototype.contextMenuItemList = function (clickState) {\n//\n// const self = this;\n// const menuItems = [];\n//\n// const featureList = this.clickedFeatures(clickState);\n//\n// if (this.callSets && featureList && featureList.length > 0) {\n//\n// featureList.forEach(function (variant) {\n//\n// if ('str' === variant.type) {\n//\n// menuItems.push({\n// label: 'Sort by allele length',\n// click: function () {\n// sortCallSetsByAlleleLength(self.callSets, variant, self.sortDirection);\n// self.sortDirection = (self.sortDirection === \"ASC\") ? \"DESC\" : \"ASC\";\n// self.trackView.repaintViews();\n// }\n// });\n//\n// }\n//\n// });\n// }\n//\n//\n// function sortCallSetsByAlleleLength(callSets, variant, direction) {\n// var d = (direction === \"DESC\") ? 1 : -1;\n// Object.keys(callSets).forEach(function (property) {\n// callSets[property].sort(function (a, b) {\n// var aNan = isNaN(variant.calls[a.id].genotype[0]);\n// var bNan = isNaN(variant.calls[b.id].genotype[0]);\n// if (aNan && bNan) {\n// return 0;\n// } else if (aNan) {\n// return 1;\n// } else if (bNan) {\n// return -1;\n// } else {\n// var a0 = getAlleleString(variant.calls[a.id], variant, 0);\n// var a1 = getAlleleString(variant.calls[a.id], variant, 1);\n// var b0 = getAlleleString(variant.calls[b.id], variant, 0);\n// var b1 = getAlleleString(variant.calls[b.id], variant, 1);\n// var result = Math.max(b0.length, b1.length) - Math.max(a0.length, a1.length);\n// if (result === 0) {\n// result = Math.min(b0.length, b1.length) - Math.min(a0.length, a1.length);\n// }\n// return d * result;\n// }\n// });\n// });\n// }\n//\n//\n// return menuItems;\n//\n// };\n\n menuItemList() {\n\n const menuItems = [];\n\n // color-by INFO attribute\n if (this.header.INFO) {\n //Code below will present checkboxes for all info fields of type \"String\". Wait until this is requested\n //const stringInfoKeys = Object.keys(this.header.INFO).filter(key => \"String\" === this.header.INFO[key].Type);\n\n // For now stick to explicit info fields (well, exactly 1 for starters)\n if (this.header.INFO) {\n //const stringInfoKeys = Object.keys(this.header.INFO).filter(key => this.header.INFO[key].Type === \"String\")\n const stringInfoKeys = this.header.INFO.SVTYPE ? ['SVTYPE'] : [];\n if (this._initColorBy && this._initColorBy !== 'SVTYPE') {\n stringInfoKeys.push(this._initColorBy);\n }\n if (stringInfoKeys.length > 0) {\n menuItems.push('
');\n const $e = $$1('
');\n $e.text('Color by:');\n menuItems.push({name: undefined, object: $e, click: undefined, init: undefined});\n stringInfoKeys.sort();\n for (let item of stringInfoKeys) {\n const selected = (this.colorBy === item);\n const label = item ? item : 'None';\n menuItems.push(this.colorByCB({key: item, label: label}, selected));\n }\n menuItems.push(this.colorByCB({key: undefined, label: 'None'}, this.colorBy === undefined));\n menuItems.push('
');\n }\n }\n }\n\n if (this.getCallsetsLength() > 0) {\n menuItems.push({object: $$1('
')});\n menuItems.push({\n object: $$1(createCheckbox(\"Show Genotypes\", this.showGenotypes)),\n click: () => {\n this.showGenotypes = !this.showGenotypes;\n //adjustTrackHeight();\n this.trackView.checkContentHeight();\n this.trackView.repaintViews();\n }\n });\n }\n\n menuItems.push({object: $$1('
')});\n for (let displayMode of [\"COLLAPSED\", \"SQUISHED\", \"EXPANDED\"]) {\n var lut =\n {\n \"COLLAPSED\": \"Collapse\",\n \"SQUISHED\": \"Squish\",\n \"EXPANDED\": \"Expand\"\n };\n\n menuItems.push(\n {\n object: $$1(createCheckbox(lut[displayMode], displayMode === this.displayMode)),\n click: () => {\n this.displayMode = displayMode;\n this.trackView.checkContentHeight();\n this.trackView.repaintViews();\n }\n });\n }\n\n // Experimental JBrowse circular view integration\n if (this.browser.circularView) {\n\n menuItems.push('
');\n menuItems.push({\n label: 'Add SVs to circular view',\n click: () => {\n for (let viewport of this.trackView.viewports) {\n this.sendChordsForViewport(viewport);\n }\n }\n });\n }\n\n return menuItems\n }\n\n\n contextMenuItemList(clickState) {\n\n // Experimental JBrowse circular view integration\n if (this.browser.circularView) {\n const viewport = clickState.viewport;\n const list = [];\n\n list.push({\n label: 'Add SVs to Circular View',\n click: () => {\n this.sendChordsForViewport(viewport);\n }\n });\n\n list.push('
');\n return list\n }\n }\n\n\n sendChordsForViewport(viewport) {\n const refFrame = viewport.referenceFrame;\n let inView;\n if (\"all\" === refFrame.chr) {\n const all = this.featureSource.getAllFeatures();\n const arrays = Object.keys(all).map(k => all[k]);\n inView = [].concat(...arrays);\n } else {\n inView = this.featureSource.featureCache.queryFeatures(refFrame.chr, refFrame.start, refFrame.end);\n\n }\n\n const chords = makeVCFChords(inView);\n sendChords(chords, this, refFrame, 0.5);\n }\n\n /**\n * Create a \"color by\" checkbox menu item, optionally initially checked\n * @param menuItem\n * @param showCheck\n * @returns {{init: undefined, name: undefined, click: clickHandler, object: (jQuery|HTMLElement|jQuery.fn.init)}}\n */\n colorByCB(menuItem, showCheck) {\n\n const $e = $$1(createCheckbox(menuItem.label, showCheck));\n const clickHandler = () => {\n\n if (menuItem.key === this.colorBy) {\n this.colorBy = undefined;\n delete this.config.colorBy;\n this.trackView.repaintViews();\n } else {\n this.colorBy = menuItem.key;\n this.config.colorBy = menuItem.key;\n this.trackView.repaintViews();\n }\n\n };\n\n return {name: undefined, object: $e, click: clickHandler, init: undefined}\n }\n\n getState() {\n\n const config = super.getState();\n if (this._color && typeof this._color !== \"function\") {\n config.color = this._color;\n }\n return config\n\n }\n\n getVariantColorTable(key) {\n\n if (!this.colorTables) {\n this.colorTables = new Map();\n }\n\n if (!this.colorTables.has(key)) {\n let tbl;\n switch (key) {\n case \"SVTYPE\" :\n tbl = SV_COLOR_TABLE;\n break\n default:\n tbl = new PaletteColorTable(\"Set1\");\n }\n this.colorTables.set(key, tbl);\n }\n return this.colorTables.get(key)\n }\n}\n\n\nfunction expandGenotype(call, variant) {\n\n if (call.genotype) {\n let gt = '';\n if (variant.alternateBases === \".\") {\n gt = \"No Call\";\n } else {\n const altArray = variant.alternateBases.split(\",\");\n for (let allele of call.genotype) {\n if (gt.length > 0) {\n gt += \"|\";\n }\n if ('.' === allele) {\n gt += '.';\n } else if (allele === 0) {\n gt += variant.referenceBases;\n } else {\n let alt = altArray[allele - 1].replace(\"<\", \"<\");\n gt += alt;\n }\n }\n }\n call.genotypeName = gt;\n }\n}\n\n\nconst SV_COLOR_TABLE = new ColorTable({\n 'DEL': '#ff2101',\n 'INS': '#001888',\n 'DUP': '#028401',\n 'INV': '#008688',\n 'CNV': '#8931ff',\n 'BND': '#891100',\n '*': '#002eff'\n});\n\n/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2014 Broad Institute\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\nclass EqtlTrack extends TrackBase {\n\n constructor(config, browser) {\n\n super(config, browser);\n }\n\n init(config) {\n super.init(config);\n\n this.name = config.name;\n this.pValueField = config.pValueField || \"pValue\";\n this.geneField = config.geneField || \"geneSymbol\";\n this.snpField = config.snpField || \"snp\";\n\n const min = config.minLogP || config.min;\n const max = config.maxLogP || config.max;\n this.dataRange = {\n min: min || 3.5,\n max: max || 25\n };\n if (!max) {\n this.autoscale = true;\n } else {\n this.autoscale = config.autoscale;\n }\n this.autoscalePercentile = (config.autoscalePercentile === undefined ? 98 : config.autoscalePercentile);\n\n\n this.background = config.background; // No default\n this.divider = config.divider || \"rgb(225,225,225)\";\n this.dotSize = config.dotSize || 2;\n this.height = config.height || 100;\n this.autoHeight = false;\n this.disableButtons = config.disableButtons;\n\n // Limit visibility window to 2 mb, gtex server gets flaky beyond that\n this.visibilityWindow = config.visibilityWindow === undefined ?\n 2000000 : config.visibilityWindow >= 0 ? Math.min(2000000, config.visibilityWindow) : 2000000;\n\n this.featureSource = FeatureSource(config, this.browser.genome);\n\n GtexUtils.gtexLoaded = true;\n }\n\n paintAxis(ctx, pixelWidth, pixelHeight) {\n\n const yScale = (this.dataRange.max - this.dataRange.min) / pixelHeight;\n\n const font = {\n 'font': 'normal 10px Arial',\n 'textAlign': 'right',\n 'strokeStyle': \"black\"\n };\n\n IGVGraphics.fillRect(ctx, 0, 0, pixelWidth, pixelHeight, {'fillStyle': \"rgb(255, 255, 255)\"});\n\n // Determine a tick spacing such that there is at least 10 pixels between ticks\n\n const n = Math.ceil((this.dataRange.max - this.dataRange.min) * 10 / pixelHeight);\n\n for (let p = 4; p <= this.dataRange.max; p += n) {\n\n // TODO: Dashes may not actually line up with correct scale. Ask Jim about this\n\n const ref = 0.85 * pixelWidth;\n const x1 = ref - 5;\n const x2 = ref;\n const y = pixelHeight - (p - this.dataRange.min) / yScale;\n\n IGVGraphics.strokeLine(ctx, x1, y, x2, y, font); // Offset dashes up by 2 pixel\n\n if (y > 8) {\n IGVGraphics.fillText(ctx, p, x1 - 1, y + 2, font);\n } // Offset numbers down by 2 pixels;\n }\n\n font['textAlign'] = 'center';\n\n IGVGraphics.fillText(ctx, \"-log10(pvalue)\", pixelWidth / 4, pixelHeight / 2, font, {rotate: {angle: -90}});\n\n };\n\n async getFeatures(chr, start, end) {\n\n const pValueField = this.pValueField;\n const visibilityWindow = this.visibilityWindow;\n const features = await this.featureSource.getFeatures({chr, start, end, visibilityWindow});\n features.forEach(function (f) {\n f.value = f[pValueField];\n });\n return features\n }\n\n draw(options) {\n\n const ctx = options.context;\n\n const pixelWidth = options.pixelWidth;\n const pixelHeight = options.pixelHeight;\n\n if (this.background) {\n IGVGraphics.fillRect(ctx, 0, 0, pixelWidth, pixelHeight, {'fillStyle': this.background});\n }\n IGVGraphics.strokeLine(ctx, 0, pixelHeight - 1, pixelWidth, pixelHeight - 1, {'strokeStyle': this.divider});\n\n const drawEqtls = (drawSelected) => {\n\n const radius = drawSelected ? 2 * this.dotSize : this.dotSize;\n const bpStart = options.bpStart;\n const yScale = (this.dataRange.max - this.dataRange.min) / pixelHeight;\n const selection = options.referenceFrame.selection;\n\n for (let eqtl of options.features) {\n\n const px = (eqtl.start - bpStart + 0.5) / options.bpPerPixel;\n if (px < 0) continue\n else if (px > pixelWidth) break\n\n const snp = eqtl.snp.toUpperCase();\n const geneName = eqtl[this.geneField].toUpperCase();\n\n const isSelected = selection &&\n (selection.snp === snp || selection.gene === geneName);\n\n if (!drawSelected || isSelected) {\n\n // Add eqtl's gene to the selection if this is the selected snp.\n // TODO -- this should not be done here in the rendering code.\n if (selection && selection.snp === snp) {\n selection.addGene(geneName);\n }\n\n var mLogP = -Math.log(eqtl[this.pValueField]) / Math.LN10;\n if (mLogP >= this.dataRange.min) {\n let capped;\n if (mLogP > this.dataRange.max) {\n mLogP = this.dataRange.max;\n capped = true;\n } else {\n capped = false;\n\n }\n\n const py = Math.max(0 + radius, pixelHeight - Math.round((mLogP - this.dataRange.min) / yScale));\n eqtl.px = px;\n eqtl.py = py;\n eqtl.radius = radius;\n\n let color;\n if (drawSelected && selection) {\n color = selection.colorForGene(geneName);\n IGVGraphics.setProperties(ctx, {fillStyle: color, strokeStyle: \"black\"});\n } else {\n color = capped ? \"rgb(150, 150, 150)\" : \"rgb(180, 180, 180)\";\n IGVGraphics.setProperties(ctx, {fillStyle: color, strokeStyle: color});\n }\n\n IGVGraphics.fillCircle(ctx, px, py, radius);\n IGVGraphics.strokeCircle(ctx, px, py, radius);\n }\n }\n }\n };\n\n // Draw in two passes, with \"selected\" eqtls drawn last\n drawEqtls(false);\n drawEqtls(true);\n\n }\n\n /**\n * Return \"popup data\" for feature @ genomic location. Data is an array of key-value pairs\n */\n popupData(clickState, features) {\n\n if(features === undefined) features = clickState.viewport.cachedFeatures;\n if (!features || features.length === 0) return []\n\n const tolerance = 3;\n const tissue = this.name;\n const popupData = [];\n\n for (let feature of features) {\n // Hit test --use square vs circle for efficiency (no sqrt)\n if (Math.abs(feature.px - clickState.canvasX) < (feature.radius + tolerance) &&\n Math.abs(feature.py - clickState.canvasY) < (feature.radius + tolerance)) {\n\n if (popupData.length > 0) {\n popupData.push('
');\n }\n popupData.push(\n {name: \"snp id\", value: feature.snp},\n {name: \"gene id\", value: feature.geneId},\n {name: \"gene name\", value: feature.geneName},\n {name: \"p value\", value: feature.pValue},\n {name: \"tissue\", value: tissue});\n\n }\n }\n\n return popupData\n }\n\n menuItemList() {\n return MenuUtils.numericDataMenuItems(this.trackView)\n }\n\n doAutoscale(featureList) {\n\n if (featureList.length > 0) {\n\n var values = featureList\n .map(function (eqtl) {\n return -Math.log(eqtl.value) / Math.LN10\n });\n\n this.dataRange.max = IGVMath.percentile(values, this.autoscalePercentile);\n } else {\n // No features -- default\n const max = this.config.maxLogP || this.config.max;\n this.dataRange.max = max || 25;\n }\n\n return this.dataRange\n }\n\n}\n\n/**\n * Colors used for coding omosomes\n */\n\nconst GWASColors = {\n \"X\": \"rgb(204, 153, 0)\",\n \"Y\": \"rgb(153, 204, 0)\",\n \"Un\": \"darkGray)\",\n \"1\": \"rgb(80, 80, 255)\",\n \"2\": \"rgb(206, 61, 50)\",\n \"2a\": \"rgb(210, 65, 55)\",\n \"2b\": \"rgb(215, 70, 60)\",\n \"3\": \"rgb(116, 155, 88)\",\n \"4\": \"rgb(240, 230, 133)\",\n \"5\": \"rgb(70, 105, 131)\",\n \"6\": \"rgb(186, 99, 56)\",\n \"7\": \"rgb(93, 177, 221)\",\n \"8\": \"rgb(128, 34, 104)\",\n \"9\": \"rgb(107, 215, 107)\",\n \"10\": \"rgb(213, 149, 167)\",\n \"11\": \"rgb(146, 72, 34)\",\n \"12\": \"rgb(131, 123, 141)\",\n \"13\": \"rgb(199, 81, 39)\",\n \"14\": \"rgb(213, 143, 92)\",\n \"15\": \"rgb(122, 101, 165)\",\n \"16\": \"rgb(228, 175, 105)\",\n \"17\": \"rgb(59, 27, 83)\",\n \"18\": \"rgb(205, 222, 183)\",\n \"19\": \"rgb(97, 42, 121)\",\n \"20\": \"rgb(174, 31, 99)\",\n \"21\": \"rgb(231, 199, 111)\",\n \"22\": \"rgb(90, 101, 94)\",\n \"23\": \"rgb(204, 153, 0)\",\n \"24\": \"rgb(153, 204, 0)\",\n \"25\": \"rgb(51, 204, 0)\",\n \"26\": \"rgb(0, 204, 51)\",\n \"27\": \"rgb(0, 204, 153)\",\n \"28\": \"rgb(0, 153, 204)\",\n \"29\": \"rgb(10, 71, 255)\",\n \"30\": \"rgb(71, 117, 255)\",\n \"31\": \"rgb(255, 194, 10)\",\n \"32\": \"rgb(255, 209, 71)\",\n \"33\": \"rgb(153, 0, 51)\",\n \"34\": \"rgb(153, 26, 0)\",\n \"35\": \"rgb(153, 102, 0)\",\n \"36\": \"rgb(128, 153, 0)\",\n \"37\": \"rgb(51, 153, 0)\",\n \"38\": \"rgb(0, 153, 26)\",\n \"39\": \"rgb(0, 153, 102)\",\n \"40\": \"rgb(0, 128, 153)\",\n \"41\": \"rgb(0, 51, 153)\",\n \"42\": \"rgb(26, 0, 153)\",\n \"43\": \"rgb(102, 0, 153)\",\n \"44\": \"rgb(153, 0, 128)\",\n \"45\": \"rgb(214, 0, 71)\",\n \"46\": \"rgb(255, 20, 99)\",\n \"47\": \"rgb(0, 214, 143)\",\n \"48\": \"rgb(20, 255, 177)\"\n};\n\n// aliasing\nfor (let key of Object.keys(GWASColors)) {\n const altName = \"chr\" + key;\n GWASColors[altName] = GWASColors[key];\n}\n\n// romanizing\nfor(let a = 1; a <= 48; a++) {\n if(a === 10) continue // Don't overide \"X\"\n const roman = romanize(a);\n GWASColors[roman] = GWASColors[a.toString()];\n}\n\n\nfunction romanize (num) {\n if (!+num) return false;\n var digits = String(+num).split('');\n var key = ['','C','CC','CCC','CD','D','DC','DCC','DCCC','CM',\n '','X','XX','XXX','XL','L','LX','LXX','LXXX','XC',\n '','I','II','III','IV','V','VI','VII','VIII','IX'];\n var roman = '', i = 3;\n while (i--) roman = (key[+digits.pop() + (i * 10)] || '') + roman;\n return Array(+digits.join('') + 1).join('M') + roman;\n}\n\n/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2014 Broad Institute\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\nconst DEFAULT_POPOVER_WINDOW = 100000000;\n\n//const type = \"gwas\";\n\nclass GWASTrack extends TrackBase {\n\n constructor(config, browser) {\n\n super(config, browser);\n }\n\n init(config) {\n\n super.init(config);\n\n this.useChrColors = config.useChrColors === undefined ? true : config.useChrColors;\n this.trait = config.trait;\n this.posteriorProbability = config.posteriorProbability;\n this.valueProperty = \"bed\" === config.format ? \"score\" : \"value\";\n this.height = config.height || 100; // The preferred height\n this.autoscale = config.autoscale;\n this.autoscalePercentile = config.autoscalePercentile === undefined ? 98 : config.autoscalePercentile;\n this.background = config.background; // No default\n this.divider = config.divider || \"rgb(225,225,225)\";\n this.dotSize = config.dotSize || 3;\n this.popoverWindow = (config.popoverWindow === undefined ? DEFAULT_POPOVER_WINDOW : config.popoverWindow);\n\n // Color settings\n if (this.useChrColors) {\n this.colorScale = new ColorTable(config.colorTable || GWASColors);\n } else if (config.color) {\n this.colorScale = new ConstantColorScale(config.color);\n } else {\n this.colorScale =\n new BinnedColorScale(config.colorScale ||\n {\n thresholds: [5e-8, 5e-4, 0.5],\n colors: [\"rgb(255,50,50)\", \"rgb(251,100,100)\", \"rgb(251,170,170)\", \"rgb(227,238,249)\"],\n });\n }\n\n this.featureSource = FeatureSource(config, this.browser.genome);\n }\n\n async postInit() {\n\n if (typeof this.featureSource.getHeader === \"function\") {\n this.header = await this.featureSource.getHeader();\n if (this.disposed) return // This track was removed during async load\n }\n\n // Set properties from track line\n if (this.header) {\n this.setTrackProperties(this.header); // setTrackProperties defined in TrackBase\n }\n\n // Set initial range if specfied, unless autoscale == true\n if (!this.autoscale) {\n if (this.posteriorProbability) {\n this.dataRange = {\n min: this.config.min === undefined ? 0 : this.config.min,\n max: this.config.max === undefined ? 1 : this.config.max\n };\n } else {\n this.dataRange = {\n min: this.config.min === undefined ? 0 : this.config.min,\n max: this.config.max === undefined ? 25 : this.config.max\n };\n }\n }\n\n return this\n\n }\n\n\n get supportsWholeGenome() {\n return true\n }\n\n async getFeatures(chr, start, end) {\n const visibilityWindow = this.visibilityWindow;\n return this.featureSource.getFeatures({chr, start, end, visibilityWindow})\n }\n\n draw(options) {\n\n const featureList = options.features;\n const ctx = options.context;\n const pixelWidth = options.pixelWidth;\n const pixelHeight = options.pixelHeight;\n if (this.background) {\n IGVGraphics.fillRect(ctx, 0, 0, pixelWidth, pixelHeight, {'fillStyle': this.background});\n }\n IGVGraphics.strokeLine(ctx, 0, pixelHeight - 1, pixelWidth, pixelHeight - 1, {'strokeStyle': this.divider});\n\n if (featureList) {\n\n const bpPerPixel = options.bpPerPixel;\n const bpStart = options.bpStart;\n const bpEnd = bpStart + pixelWidth * bpPerPixel + 1;\n for (let variant of featureList) {\n const pos = variant.start;\n if (pos < bpStart) continue\n if (pos > bpEnd) break\n\n let val;\n if (this.posteriorProbability) {\n val = variant[this.valueProperty];\n } else {\n const pvalue = variant[this.valueProperty];\n if (!pvalue) continue\n val = -Math.log10(pvalue);\n }\n\n const colorKey = this.useChrColors ?\n variant._f ? variant._f.chr : variant.chr :\n val;\n\n const color = this.colorScale.getColor(colorKey);\n const yScale = (this.dataRange.max - this.dataRange.min) / pixelHeight;\n const px = Math.round((pos - bpStart) / bpPerPixel);\n const py = Math.max(this.dotSize, pixelHeight - Math.round((val - this.dataRange.min) / yScale));\n\n if (color) {\n IGVGraphics.setProperties(ctx, {fillStyle: color, strokeStyle: \"black\"});\n }\n IGVGraphics.fillCircle(ctx, px, py, this.dotSize);\n variant.px = px;\n variant.py = py;\n }\n }\n }\n\n paintAxis(ctx, pixelWidth, pixelHeight) {\n\n IGVGraphics.fillRect(ctx, 0, 0, pixelWidth, pixelHeight, {'fillStyle': \"rgb(255, 255, 255)\"});\n var font = {\n 'font': 'normal 10px Arial',\n 'textAlign': 'right',\n 'strokeStyle': \"black\"\n };\n\n const yScale = (this.dataRange.max - this.dataRange.min) / pixelHeight;\n if (this.posteriorProbability) {\n const n = 0.1;\n for (let p = this.dataRange.min; p < this.dataRange.max; p += n) {\n const yp = pixelHeight - Math.round((p - this.dataRange.min) / yScale);\n IGVGraphics.strokeLine(ctx, 45, yp - 2, 50, yp - 2, font); // Offset dashes up by 2 pixel\n IGVGraphics.fillText(ctx, p.toFixed(1), 44, yp + 2, font); // Offset numbers down by 2 pixels;\n }\n } else {\n const n = Math.ceil((this.dataRange.max - this.dataRange.min) * 10 / pixelHeight);\n for (let p = this.dataRange.min; p < this.dataRange.max; p += n) {\n const yp = pixelHeight - Math.round((p - this.dataRange.min) / yScale);\n IGVGraphics.strokeLine(ctx, 45, yp, 50, yp, font); // Offset dashes up by 2 pixel\n IGVGraphics.fillText(ctx, Math.floor(p), 44, yp + 4, font); // Offset numbers down by 2 pixels;\n }\n }\n\n font['textAlign'] = 'center';\n if (this.posteriorProbability) {\n IGVGraphics.fillText(ctx, \"PPA\", pixelWidth / 2, pixelHeight / 2, font, {rotate: {angle: -90}});\n } else {\n IGVGraphics.fillText(ctx, \"-log10(pvalue)\", pixelWidth / 2, pixelHeight / 2, font, {rotate: {angle: -90}});\n }\n }\n\n popupData(clickState, features) {\n\n if (features === undefined) features = clickState.viewport.cachedFeatures;\n\n let data = [];\n const track = clickState.viewport.trackView.track;\n\n if (features) {\n let count = 0;\n for (let f of features) {\n const xDelta = Math.abs(clickState.canvasX - f.px);\n const yDelta = Math.abs(clickState.canvasY - f.py);\n const value = f[this.valueProperty];\n if (xDelta < this.dotSize && yDelta < this.dotSize) {\n if (count > 0) {\n data.push(\"
\");\n }\n if (count == 5) {\n data.push(\"...\");\n break\n }\n if (typeof f.popupData === 'function') {\n data = data.concat(f.popupData());\n } else {\n const chr = f.realChr || f.chr;\n const pos = (f.realStart || f.start) + 1;\n data.push({name: 'chromosome', value: chr});\n data.push({name: 'position', value: pos});\n data.push({name: 'name', value: f.name});\n if (track.posteriorProbability) {\n data.push({name: 'posterior probability', value: value});\n } else {\n data.push({name: 'pValue', value: value});\n }\n }\n count++;\n }\n }\n }\n\n return data\n }\n\n menuItemList() {\n return MenuUtils.numericDataMenuItems(this.trackView)\n }\n\n doAutoscale(featureList) {\n\n if (featureList.length > 0) {\n // posterior probabilities are treated without modification, but we need to take a negative logarithm of P values\n const valueProperty = this.valueProperty;\n const posterior = this.posteriorProbability;\n const features =\n featureList.map(function (feature) {\n const v = feature[valueProperty];\n return {value: posterior ? v : -Math.log(v) / Math.LN10}\n });\n this.dataRange = doAutoscale(features);\n\n } else {\n // No features -- pick something reasonable for PPAs and p-values\n if (this.posteriorProbability) {\n this.dataRange = {min: this.config.min || 0, max: this.config.max || 1};\n } else {\n this.dataRange = {min: this.config.max || 25, max: this.config.min || 0};\n }\n }\n\n return this.dataRange\n }\n\n}\n\nconst X_PIXEL_DIFF_THRESHOLD = 1;\n\nclass GCNVTrack extends TrackBase {\n\n constructor(config, browser) {\n super(config, browser);\n }\n\n init(config) {\n super.init(config);\n\n this.autoscale = config.autoscale || config.max === undefined;\n this.dataRange = {\n min: config.min || 0,\n max: config.max\n };\n\n this.windowFunction = config.windowFunction || \"mean\";\n this.paintAxis = paintAxis;\n this.graphType = config.graphType || \"bar\";\n\n //hack to avoid creating feature source multiple times. If config.type is not set the file must be read\n //to determine type, which results in creation of a feature source.\n if (config._featureSource) {\n this.featureSource = config._featureSource;\n delete config._featureSource;\n } else {\n this.featureSource = FeatureSource(this.config, this.browser.genome);\n }\n\n // Visibility window hardcoded to -1 (== whole chromosome). Draw method needs feature beyond current view,\n // when/if this is resolved visibilityWindow can be used.\n this.visibilityWindow = -1;\n this.featureSource.visibilityWindow = this.visibilityWindow;\n }\n\n async postInit() {\n\n if (typeof this.featureSource.getHeader === \"function\") {\n this.header = await this.featureSource.getHeader();\n if(this.disposed) return; // This track was removed during async load\n this.sampleNames = this.header.columnNames.slice(3);\n\n // Set generic properties from track line\n this.setTrackProperties(this.header); // setTrackProperties defined in TrackBase\n\n // set option to highlight sample track line on click\n if (this.header.hasOwnProperty(\"clickToHighlight\")) {\n let colour = this.header[\"clickToHighlight\"];\n this.config.clickToHighlight = colour;\n this.config.samplesClickedToHighlight = {};\n }\n\n // Special track line properties\n if (this.header.hasOwnProperty(\"highlight\")) {\n this.config.highlightSamples = {};\n let v = this.header[\"highlight\"];\n if (!Array.isArray(v)) v = [v];\n for (let h of v) {\n const tokens = h.split(\";\");\n if (tokens.length === 2) {\n this.config.highlightSamples[tokens[0]] = tokens[1];\n }\n\n }\n }\n }\n }\n\n menuItemList() {\n return MenuUtils.numericDataMenuItems(this.trackView)\n }\n\n async getFeatures(chr, start, end) {\n const chrFeatures = await this.featureSource.getFeatures({\n chr,\n start: 0,\n end: Number.MAX_SAFE_INTEGER,\n visibilityWindow: this.visibilityWindow\n });\n let prevIndex = undefined;\n let nextIndex = undefined;\n for (let i = 1; i < chrFeatures.length - 1; i++) {\n if (prevIndex === undefined && chrFeatures[i].end > start) {\n prevIndex = i - 1;\n }\n if (nextIndex === undefined && chrFeatures[i].start > end) {\n nextIndex = i + 1;\n break\n }\n }\n if (prevIndex === undefined) prevIndex = 0;\n if (nextIndex === undefined) nextIndex = chrFeatures.length;\n return chrFeatures.slice(prevIndex, nextIndex)\n }\n\n draw(options) {\n\n const {features, context, bpPerPixel, bpStart, pixelWidth, pixelHeight} = options;\n\n ///let baselineColor;\n //if (typeof self.color === \"string\" && self.color.startsWith(\"rgb(\")) {\n // baselineColor = IGVColor.addAlpha(self.color, 0.1);\n //}\n\n const yScale = (yValue) => {\n return ((this.dataRange.max - yValue) / (this.dataRange.max - this.dataRange.min)) * pixelHeight\n };\n\n const getX = function (bpPosition) {\n let x = Math.floor((bpPosition - bpStart) / bpPerPixel);\n if (isNaN(x)) console.warn('isNaN(x). feature start ' + numberFormatter$1(bpPosition) +\n ' bp start ' + numberFormatter$1(bpStart));\n return x\n };\n\n const drawGuideLines = (options) => {\n if (this.config.hasOwnProperty('guideLines')) {\n for (let line of this.config.guideLines) {\n if (line.hasOwnProperty('color') && line.hasOwnProperty('y') && line.hasOwnProperty('dotted')) {\n let y = yScale(line.y);\n let props = {\n 'strokeStyle': line['color'],\n 'strokeWidth': 2\n };\n if (line['dotted']) IGVGraphics.dashedLine(options.context, 0, y, options.pixelWidth, y, 5, props);\n else IGVGraphics.strokeLine(options.context, 0, y, options.pixelWidth, y, props);\n }\n }\n }\n };\n\n if (features && features.length > 0) {\n\n if (this.dataRange.min === undefined) this.dataRange.min = 0;\n\n // Max can be less than min if config.min is set but max left to autoscale. If that's the case there is\n // nothing to paint.\n if (this.dataRange.max > this.dataRange.min) {\n const highlightSamples = this.config.highlightSamples;\n const onlyHandleClicksForHighlightedSamples = this.config.onlyHandleClicksForHighlightedSamples;\n const clickToHighlight = this.config.clickToHighlight;\n\n let previousEnd = -1;\n let previousValues = {};\n\n let highlightConnectorLines = [];\n let highlightFeatureLines = [];\n\n // clickDetectorCache allows fast retrieval of whether a mouse click hits a rendered line segment\n // by storing lists of rendered line segments, keyed by their right x coordinate in canvas pixel space.\n // this cache is regenerated on every draw.\n this.clickDetectorCache = {};\n\n for (let feature of features) {\n const x1 = getX(feature.start);\n const x2 = getX(feature.end);\n const previousX = previousEnd >= 0 ? getX(previousEnd) : x1;\n\n if (isNaN(x1) || isNaN(x2)) continue\n // if ((x1 - previousX < X_PIXEL_DIFF_THRESHOLD) && (x2 - x1 < X_PIXEL_DIFF_THRESHOLD)) continue;\n\n this.clickDetectorCache[x1] = [];\n this.clickDetectorCache[x2] = [];\n for (let i = 0; i < feature.values.length; i++) {\n const sampleName = this.sampleNames[i];\n const value = feature.values[i];\n const y = yScale(value);\n if (x1 - previousX >= X_PIXEL_DIFF_THRESHOLD) {\n const previousValue = previousValues[sampleName];\n const previousY = yScale(previousValue);\n const highlightColor = highlightSamples && highlightSamples[sampleName];\n\n\n if (highlightColor) {\n highlightConnectorLines.push([previousX, previousY, x1, y, highlightColor]);\n } else if (clickToHighlight && sampleName in this.config.samplesClickedToHighlight) {\n highlightConnectorLines.push([previousX, previousY, x1, y, this.config.samplesClickedToHighlight[sampleName]]);\n } else {\n IGVGraphics.strokeLine(context, previousX, previousY, x1, y, {strokeStyle: '#D9D9D9'});\n }\n if (!onlyHandleClicksForHighlightedSamples || sampleName in highlightSamples) {\n this.clickDetectorCache[x1].push([previousX, previousY, x1, y, sampleName, highlightColor || 'gray']);\n }\n }\n\n if (x2 - x1 >= X_PIXEL_DIFF_THRESHOLD) {\n const highlightColor = highlightSamples && highlightSamples[sampleName];\n if (highlightColor) {\n highlightFeatureLines.push([x1, y, x2, y, highlightColor]);\n } else if (clickToHighlight && sampleName in this.config.samplesClickedToHighlight) {\n highlightFeatureLines.push([x1, y, x2, y, this.config.samplesClickedToHighlight[sampleName]]);\n } else {\n IGVGraphics.strokeLine(context, x1, y, x2, y, {strokeStyle: 'gray'});\n }\n if (!onlyHandleClicksForHighlightedSamples || sampleName in highlightSamples) {\n this.clickDetectorCache[x2].push([x1, y, x2, y, sampleName, highlightColor || 'gray']);\n }\n }\n\n previousValues[sampleName] = value;\n\n //IGVGraphics.fillCircle(ctx, px, y, pointSize / 2, {\"fillStyle\": color, \"strokeStyle\": color});\n //IGVGraphics.fillRect(ctx, x, y, width, height, {fillStyle: color});\n }\n previousEnd = feature.end;\n }\n\n for (let f of highlightConnectorLines) {\n IGVGraphics.strokeLine(context, f[0], f[1], f[2], f[3], {strokeStyle: f[4], lineWidth: 1.3});\n }\n for (let f of highlightFeatureLines) {\n IGVGraphics.strokeLine(context, f[0], f[1], f[2], f[3], {strokeStyle: f[4], lineWidth: 2});\n }\n\n /*\n // If the track includes negative values draw a baseline\n if (this.dataRange.min < 0) {\n const basepx = (self.dataRange.max / (this.dataRange.max - this.dataRange.min)) * options.pixelHeight;\n IGVGraphics.strokeLine(context, 0, basepx, options.pixelWidth, basepx, {strokeStyle: baselineColor});\n }\n */\n }\n }\n\n drawGuideLines(options);\n }\n\n doAutoscale(features) {\n\n let min, max;\n if (features.length > 0) {\n min = Number.MAX_VALUE;\n max = -Number.MAX_VALUE;\n\n features.forEach(function (feature) {\n min = Math.min(min, ...feature.values);\n max = Math.max(max, ...feature.values);\n });\n\n min -= 0.01;\n max += 0.01;\n } else {\n // No features -- default\n min = 0;\n max = 100;\n }\n\n return {min: min, max: max}\n }\n\n clickedFeatures(clickState) {\n //console.warn('click', clickState.canvasX, clickState.canvasY, clickState)\n\n const BOUNDING_BOX_PADDING = 10;\n const MIN_DISTANCE_TO_SEGMENT = 5;\n\n const clickX = clickState.canvasX;\n const clickY = clickState.canvasY;\n\n let key = null;\n for (key of Object.keys(this.clickDetectorCache)) {\n key = parseInt(key);\n if (key >= clickX) {\n break\n }\n }\n\n\n if (key) {\n let closestDistanceSoFar = Number.MAX_VALUE;\n let closestResult = [];\n const segments = this.clickDetectorCache[key];\n for (let segment of segments) {\n const x1 = segment[0];\n const x2 = segment[2];\n if (clickX < x1 || clickX > x2) return []\n\n const y1 = segment[1];\n const y2 = segment[3];\n\n if ((clickY < Math.min(y1, y2) - BOUNDING_BOX_PADDING) || (clickY > Math.max(y1, y2) + BOUNDING_BOX_PADDING)) continue\n\n const distance = distanceToLine(clickX, clickY, x1, y1, x2, y2);\n if (distance < closestDistanceSoFar) {\n closestResult = [{'name': segment[4], 'color': segment[5]}];\n closestDistanceSoFar = distance;\n //console.warn('closest:', 'name', segment[4], 'color', segment[5], distance);\n }\n }\n\n if (closestDistanceSoFar < MIN_DISTANCE_TO_SEGMENT) {\n // clickToHighlight set, add sample to dict of clicked lines\n if (this.config.clickToHighlight) {\n if (closestResult[0]['name'] in this.config.samplesClickedToHighlight) {\n // clicked sample already highlighted => remove if clicked again\n delete this.config.samplesClickedToHighlight[closestResult[0]['name']];\n } else if (this.config.clickToHighlight === 'any') {\n var colourList = [\n 'red', 'darkblue', 'green', 'teal', 'olivedrab',\n 'orange', 'maroon', 'purple', 'blue', 'gold',\n ];\n var colour = colourList[Math.floor(Math.random() * (colourList.length + 1))];\n this.config.samplesClickedToHighlight[closestResult[0]['name']] = colour;\n } else {\n this.config.samplesClickedToHighlight[closestResult[0]['name']] = this.config.clickToHighlight;\n }\n this.trackView.repaintViews(); // prompt redraw to change colour of clicked sample\n }\n return closestResult\n }\n }\n\n return []\n }\n\n popupData(clickState, features) {\n\n if(features === undefined) features = this.clickedFeatures(clickState);\n\n const items = [];\n features.forEach(function (f) {\n for (let property of Object.keys(f)) {\n if (isSimpleType(f[property])) {\n items.push({name: property, value: f[property]});\n }\n }\n });\n\n return items\n }\n\n get supportsWholeGenome() {\n return false\n }\n}\n\n\nfunction distanceToLine(x, y, ax, ay, bx, by) {\n /*\n Finds distance between point (x, y) and line defined by points (ax, ay) (bx, by)\n based on http://mathworld.wolfram.com/Point-LineDistance2-Dimensional.html\n */\n\n const bx_minus_ax = bx - ax;\n const by_minus_ay = by - ay;\n const v = Math.abs(bx_minus_ax * (ay - y) - (ax - x) * by_minus_ay);\n const r = Math.sqrt(bx_minus_ax * bx_minus_ax + by_minus_ay * by_minus_ay);\n\n const distance = r > 0 ? v / r : 0;\n //console.warn('Check if', x, y, 'is within', ax, ay, bx, by, '. Distance from line: ', distance);\n\n return distance\n}\n\n/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2014 Broad Institute\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\nclass RnaStructTrack extends TrackBase {\n\n constructor(config, browser) {\n\n super(config, browser);\n\n // Set defaults\n if (!config.height) {\n this.height = 300;\n }\n\n this.arcOrientation = false;\n\n this.theta = Math.PI / 2;\n\n if (\"bp\" === config.format) {\n this.featureSource = new RNAFeatureSource(config, browser.genome);\n } else {\n this.featureSource = new TextFeatureSource(config, browser.genome);\n }\n }\n\n async getFeatures(chr, start, end) {\n const visibilityWindow = this.visibilityWindow;\n return this.featureSource.getFeatures({chr, start, end, visibilityWindow})\n }\n\n draw(options) {\n\n const ctx = options.context;\n\n const theta = Math.PI / 2;\n const pixelWidth = options.pixelWidth;\n const pixelHeight = options.pixelHeight;\n options.viewportWidth;\n const bpPerPixel = options.bpPerPixel;\n const bpStart = options.bpStart;\n const xScale = bpPerPixel;\n const orienation = this.arcOrientation;\n\n IGVGraphics.fillRect(ctx, 0, options.pixelTop, pixelWidth, pixelHeight, {'fillStyle': \"rgb(255, 255, 255)\"});\n\n const featureList = options.features;\n\n if (featureList) {\n\n // Sort by score -- draw lowest scored features first\n sortByScore(featureList, 1);\n\n for (let feature of featureList) {\n\n if (feature.startLeft) {\n\n let sl = Math.round((feature.startLeft - bpStart) / xScale);\n let sr = Math.round((feature.startRight - bpStart) / xScale);\n let el = Math.round((feature.endLeft - bpStart) / xScale);\n let er = Math.round((feature.endRight - bpStart) / xScale);\n\n ctx.fillStyle = feature.color;\n ctx.strokeStyle = feature.color;\n ctx.beginPath();\n\n // First arc\n let x1 = (sl + er) / 2;\n let r1 = (er - sl) / 2;\n let y1 = this.height;\n let sa = Math.PI + (Math.PI / 2 - theta);\n let ea = 2 * Math.PI - (Math.PI / 2 - theta);\n\n if (orienation) {\n y1 = 0;\n ctx.arc(x1, y1, r1, ea, sa);\n ctx.lineTo(er, y1);\n } else {\n ctx.arc(x1, y1, r1, sa, ea);\n ctx.lineTo(el, y1);\n }\n\n // Second arc\n const x2 = (sr + el) / 2;\n const r2 = (el - sr) / 2;\n const y2 = y1; // Only for theta == pi/2\n\n if (orienation) {\n ctx.arc(x2, y2, r2, sa, ea, true);\n ctx.lineTo(el, y2);\n } else {\n ctx.arc(x2, y2, r2, ea, sa, true);\n ctx.lineTo(sl, y2);\n }\n\n ctx.stroke();\n ctx.fill();\n\n feature.drawState = {x1: x1, y1: y1, r1: r1, x2: x2, y2: y2, r2: r2, sa: sa, ea: ea};\n } else {\n let s = Math.round((feature.start - bpStart) / xScale);\n let e = Math.round((feature.end - bpStart) / xScale);\n\n ctx.strokeStyle = feature.color;\n\n ctx.beginPath();\n\n // First arc\n let x = (s + e) / 2;\n let r = (e - s) / 2;\n let y = this.height;\n let sa = Math.PI + (Math.PI / 2 - theta);\n let ea = 2 * Math.PI - (Math.PI / 2 - theta);\n\n if (orienation) {\n y = 0;\n ctx.arc(x, y, r, ea, sa);\n } else {\n ctx.arc(x, y, r, sa, ea);\n }\n\n ctx.stroke();\n\n feature.drawState = {x1: x, y1: y, r1: r, sa: sa, ea: ea};\n\n }\n\n }\n }\n }\n\n clickedFeatures(clickState) {\n\n const features = super.clickedFeatures(clickState);\n\n const clicked = [];\n\n // Sort by score in descending order (opposite order than drawn)\n sortByScore(features, -1);\n\n for (let f of features) {\n const ds = f.drawState;\n\n // Distance from arc radius, or outer arc for type \".bp\"\n const dx1 = (clickState.canvasX - ds.x1);\n const dy1 = (clickState.canvasY - ds.y1);\n const d1 = Math.sqrt(dx1 * dx1 + dy1 * dy1);\n const outerLim = ds.r1 + 3;\n\n\n let d2;\n let innerLim;\n if (ds.x2 === undefined) {\n d2 = d1;\n innerLim = ds.r1 - 3;\n\n } else {\n const dx2 = (clickState.canvasX - ds.x2);\n const dy2 = (clickState.canvasY - ds.y2);\n d2 = Math.sqrt(dx2 * dx2 + dy2 * dy2);\n innerLim = ds.r2 - 3;\n }\n\n\n // Between outer and inner arcs, with some tolerance\n if (d1 < outerLim && d2 > innerLim) {\n clicked.push(f);\n break\n }\n }\n return clicked\n }\n\n popupData(clickState, features) {\n\n if(features === undefined) features = this.clickedFeatures(clickState);\n\n if (features && features.length > 0) {\n\n return this.extractPopupData(features[0], this.getGenomeId())\n\n }\n }\n\n menuItemList() {\n\n var self = this;\n\n return [\n {\n name: \"Toggle arc direction\",\n click: function () {\n self.arcOrientation = !self.arcOrientation;\n self.trackView.repaintViews();\n }\n }\n ]\n\n };\n\n\n}\n\nfunction sortByScore(featureList, direction) {\n\n featureList.sort(function (a, b) {\n const s1 = a.score === undefined ? -Number.MAX_VALUE : a.score;\n const s2 = b.score === undefined ? -Number.MAX_VALUE : b.score;\n const d = direction === undefined ? 1 : direction;\n\n return d * (s1 - s2)\n });\n}\n\n\nclass RNAFeatureSource {\n\n constructor(config, genome) {\n this.config = config;\n this.genome = genome;\n }\n\n async getFeatures({chr, start, end, bpPerPixel, visibilityWindow}) {\n\n\n const genome = this.genome;\n\n if (!this.featureCache) {\n\n const options = buildOptions(this.config);\n\n const data = await igvxhr.loadString(this.config.url, options);\n\n this.featureCache = new FeatureCache$1(parseBP(data), genome);\n\n return this.featureCache.queryFeatures(chr, start, end)\n\n } else {\n return this.featureCache.queryFeatures(chr, start, end)\n }\n\n function parseBP(data) {\n\n if (!data) return null\n\n const dataWrapper = getDataWrapper(data);\n\n let header = true;\n let line;\n const colors = [];\n const descriptors = [];\n const features = [];\n\n while ((line = dataWrapper.nextLine()) !== undefined) {\n\n const tokens = line.split('\\t');\n\n if (header && line.startsWith(\"color:\")) {\n const color = \"rgb(\" + tokens[1] + \",\" + tokens[2] + \",\" + tokens[3] + \")\";\n colors.push(color);\n if (tokens.length > 4) {\n descriptors.push(tokens[4]);\n }\n // TODO - use label\n } else {\n header = false;\n\n const chr = tokens[0];\n const startLeftNuc = Number.parseInt(tokens[1]) - 1;\n const startRightNuc = Number.parseInt(tokens[2]) - 1;\n const endLeftNuc = Number.parseInt(tokens[3]);\n const endRightNuc = Number.parseInt(tokens[4]);\n var colorIdx = Number.parseInt(tokens[5]);\n const color = colors[colorIdx];\n\n\n let feature;\n if (startLeftNuc <= endRightNuc) {\n feature = {\n chr: chr,\n startLeft: Math.min(startLeftNuc, startRightNuc),\n startRight: Math.max(startLeftNuc, startRightNuc),\n endLeft: Math.min(endLeftNuc, endRightNuc),\n endRight: Math.max(endLeftNuc, endRightNuc),\n color: color,\n score: colorIdx\n };\n } else {\n feature = {\n chr: chr,\n startLeft: Math.min(endLeftNuc, endRightNuc),\n startRight: Math.max(endLeftNuc, endRightNuc),\n endLeft: Math.min(startLeftNuc, startRightNuc),\n endRight: Math.max(startLeftNuc, startRightNuc),\n color: color,\n score: colorIdx\n };\n }\n\n feature.start = feature.startLeft;\n feature.end = feature.endRight;\n\n if (descriptors.length > colorIdx) {\n feature.description = descriptors[colorIdx];\n }\n\n features.push(feature);\n }\n }\n\n return features\n }\n }\n}\n\n/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2014 Broad Institute\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\n/**\n * Class represents an ideogram of a chromsome cytobands. It is used for the header of a track panel.\n *\n */\nclass IdeogramTrack {\n constructor(browser) {\n this.browser = browser;\n this.type = 'ideogram';\n this.height = 16;\n this.order = Number.MIN_SAFE_INTEGER;\n this.disableButtons = true;\n this.ignoreTrackMenu = true;\n }\n\n async getFeatures(chr, start, end) {\n return []\n }\n\n computePixelHeight(ignore) {\n return this.height\n }\n\n draw({context, referenceFrame, pixelWidth, pixelHeight}) {\n\n const chr = referenceFrame.chr;\n const chromosome = referenceFrame.genome.getChromosome(chr);\n\n if (undefined === chromosome || pixelWidth <= 0 || pixelHeight <= 0 || 'all' === chr.toLowerCase()) {\n return\n }\n\n const stainColors = [];\n\n drawIdeogram({\n ctx: context,\n chr,\n referenceFrame,\n genome: referenceFrame.genome,\n width: pixelWidth,\n height: pixelHeight,\n stainColors\n });\n\n const widthBP = Math.round(referenceFrame.bpPerPixel * pixelWidth);\n const xBP = referenceFrame.start;\n\n // Total chromosome length can be > chromosome.bpLength for partial fastas.\n let chrLength = chromosome.bpLength;\n const cytobands = referenceFrame.genome.getCytobands(chr);\n if (cytobands && cytobands.length > 0 && cytobands[cytobands.length - 1].end) {\n chrLength = Math.max(chrLength, cytobands[cytobands.length - 1].end);\n chromosome.bpLength = chrLength; // Correct bp length, bit of a hack\n }\n\n if (widthBP < chrLength) {\n\n const percentWidth = widthBP / chrLength;\n const percentX = xBP / chrLength;\n\n let x = Math.floor(percentX * pixelWidth);\n let ww = Math.floor(percentWidth * pixelWidth);\n\n x = Math.max(0, x);\n x = Math.min(pixelWidth - ww, x);\n\n // Push current context\n context.save();\n\n // Draw red box\n context.strokeStyle = \"red\";\n context.lineWidth = (ww < 2) ? 1 : 2;\n\n const xx = x + (context.lineWidth) / 2;\n ww = (ww < 2) ? 1 : ww - context.lineWidth;\n\n const yy = context.lineWidth / 2;\n const hh = pixelHeight - context.lineWidth;\n\n context.strokeRect(xx, yy, ww, hh);\n\n // Pop current context\n context.restore();\n }\n\n }\n\n dispose() {\n this.trackView = undefined;\n }\n}\n\nfunction drawIdeogram({ctx, chr, referenceFrame, genome, width, height, stainColors}) {\n\n const shim = 1;\n const shim2 = 0.5 * shim;\n const ideogramTop = 0;\n\n if (undefined === genome) {\n return\n }\n\n IGVGraphics.fillRect(ctx, 0, 0, width, height, {fillStyle: IGVColor.greyScale(255)});\n\n const cytobands = genome.getCytobands(chr);\n if (cytobands) {\n\n const center = (ideogramTop + height / 2);\n\n const xC = [];\n const yC = [];\n\n if (0 === cytobands.length) {\n return\n }\n\n // Get chrLength from the cytobands -- chromsome.bpLength might not work for igv-reports fasta files, which\n // contain only a portion of the chromosome sequence\n // *DOESNT WORK* const chrLength = referenceFrame.genome.getChromosome(chr).bpLength;\n\n const chrLength = cytobands[cytobands.length - 1].end;\n const scale = width / chrLength;\n\n // round rect clipping path\n ctx.beginPath();\n IGVGraphics.roundRect(ctx, shim2, shim2 + ideogramTop, width - 2 * shim2, height - 2 * shim2, (height - 2 * shim2) / 2, 0, 1);\n ctx.clip();\n\n for (let i = 0; i < cytobands.length; i++) {\n\n const cytoband = cytobands[i];\n const start = scale * cytoband.start;\n const end = scale * cytoband.end;\n\n if (cytoband.type === 'c') {\n\n if (cytoband.name.charAt(0) === 'p') {\n xC[0] = start;\n yC[0] = height + ideogramTop;\n xC[1] = start;\n yC[1] = ideogramTop;\n xC[2] = end;\n yC[2] = center;\n } else {\n xC[0] = end;\n yC[0] = height + ideogramTop;\n xC[1] = end;\n yC[1] = ideogramTop;\n xC[2] = start;\n yC[2] = center;\n }\n\n ctx.fillStyle = \"rgb(150, 0, 0)\";\n ctx.strokeStyle = \"rgb(150, 0, 0)\";\n IGVGraphics.polygon(ctx, xC, yC, 1, 0);\n } else {\n\n ctx.fillStyle = getCytobandColor(stainColors, cytoband);\n IGVGraphics.fillRect(ctx, start, shim + ideogramTop, (end - start), height - 2 * shim);\n }\n }\n }\n\n // round rect border\n ctx.strokeStyle = IGVColor.greyScale(41);\n IGVGraphics.roundRect(ctx, shim2, shim2 + ideogramTop, width - 2 * shim2, height - 2 * shim2, (height - 2 * shim2) / 2, 0, 1);\n}\n\nfunction getCytobandColor(colors, data) {\n\n if (data.type === 'c') { // centermere: \"acen\"\n return \"rgb(150, 10, 10)\"\n } else {\n var stain = data.stain; // + 4;\n\n var shade = 230;\n if (data.type === 'p') {\n shade = Math.floor(230 - stain / 100.0 * 230);\n }\n var c = colors[shade];\n if (!c) {\n c = \"rgb(\" + shade + \",\" + shade + \",\" + shade + \")\";\n colors[shade] = c;\n }\n return c\n\n }\n}\n\n/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2014 Broad Institute\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\nlet JUNCTION_MOTIF_PALETTE = new PaletteColorTable(\"Dark2\");\n\n// Lock in color-to-motif mapping so it's independent of data loading order. This list may not include all possible\n// motif values as this varies depending on the RNA-seq pipeline. The current list is based on STAR v2.4 docs.\nconst someMotifValues = ['GT/AG', 'CT/AC', 'GC/AG', 'CT/GC', 'AT/AC', 'GT/AT', 'non-canonical'];\nsomeMotifValues.forEach(motif => {\n JUNCTION_MOTIF_PALETTE.getColor(motif);\n});\n\n// rendering context with values that only need to be computed once per render, rather than for each splice junction\nconst junctionRenderingContext = {};\n\nclass SpliceJunctionTrack extends TrackBase {\n\n constructor(config, browser) {\n super(config, browser);\n }\n\n\n init(config) {\n\n super.init(config);\n\n this.type = config.type || 'junctions';\n\n if (config._featureSource) {\n this.featureSource = config._featureSource;\n delete config._featureSource;\n } else {\n this.featureSource = config.featureSource ?\n config.featureSource :\n FeatureSource(config, this.browser.genome);\n }\n\n this.margin = config.margin === undefined ? 10 : config.margin;\n\n if (!this.height) {\n this.height = 100;\n }\n\n //set defaults\n if (config.colorByNumReadsThreshold === undefined) {\n config.colorByNumReadsThreshold = 5;\n }\n }\n\n async postInit() {\n\n if (typeof this.featureSource.getHeader === \"function\") {\n this.header = await this.featureSource.getHeader();\n if (this.disposed) return // This track was removed during async load\n }\n\n // Set properties from track line\n if (this.header) {\n this.setTrackProperties(this.header);\n }\n\n if (this.visibilityWindow === undefined && typeof this.featureSource.defaultVisibilityWindow === 'function') {\n this.visibilityWindow = await this.featureSource.defaultVisibilityWindow();\n }\n\n return this\n\n }\n\n get supportsWholeGenome() {\n return false\n }\n\n async getFeatures(chr, start, end, bpPerPixel) {\n const visibilityWindow = this.visibilityWindow;\n return this.featureSource.getFeatures({chr, start, end, bpPerPixel, visibilityWindow})\n };\n\n\n /**\n * The required height in pixels required for the track content. This is not the visible track height, which\n * can be smaller (with a scrollbar) or larger.\n *\n * @param features\n * @returns {*}\n */\n computePixelHeight(features) {\n return this.height\n };\n\n draw(options) {\n\n const featureList = options.features;\n const ctx = options.context;\n const bpPerPixel = options.bpPerPixel;\n const bpStart = options.bpStart;\n const pixelWidth = options.pixelWidth;\n const pixelHeight = options.pixelHeight;\n const bpEnd = bpStart + pixelWidth * bpPerPixel + 1;\n\n\n if (!this.config.isMergedTrack) {\n IGVGraphics.fillRect(ctx, 0, options.pixelTop, pixelWidth, pixelHeight, {'fillStyle': \"rgb(255, 255, 255)\"});\n }\n\n if (featureList) {\n\n\n junctionRenderingContext.referenceFrame = options.viewport.referenceFrame;\n junctionRenderingContext.referenceFrameStart = junctionRenderingContext.referenceFrame.start;\n junctionRenderingContext.referenceFrameEnd = junctionRenderingContext.referenceFrameStart +\n junctionRenderingContext.referenceFrame.toBP(options.viewport.getWidth());\n\n // For a given viewport, records where features that are < 2px in width have been rendered already.\n // This prevents wasteful rendering of multiple such features onto the same pixels.\n junctionRenderingContext.featureZoomOutTracker = {};\n\n for (let feature of featureList) {\n if (feature.end < bpStart) continue\n if (feature.start > bpEnd) break\n this.renderJunction(feature, bpStart, bpPerPixel, pixelHeight, ctx);\n }\n\n } else {\n console.log(\"No feature list\");\n }\n\n };\n\n /**\n *\n * @param feature\n * @param bpStart genomic location of the left edge of the current canvas\n * @param xScale scale in base-pairs per pixel\n * @param pixelHeight pixel height of the current canvas\n * @param ctx the canvas 2d context\n */\n renderJunction(feature, bpStart, xScale, pixelHeight, ctx) {\n // cache whether this junction is rendered or filtered out. Use later to exclude non-rendered junctions from click detection.\n feature.isVisible = false;\n\n const junctionLeftPx = Math.round((feature.start - bpStart) / xScale);\n const junctionRightPx = Math.round((feature.end - bpStart) / xScale);\n const junctionMiddlePx = (junctionLeftPx + junctionRightPx) / 2;\n if (junctionRightPx - junctionLeftPx <= 3) {\n if (junctionMiddlePx in junctionRenderingContext.featureZoomOutTracker) {\n return\n }\n junctionRenderingContext.featureZoomOutTracker[junctionMiddlePx] = true;\n }\n\n // TODO: cache filter and pixel calculations by doing them earlier when features are initially parsed?\n if (this.config.hideAnnotatedJunctions && feature.attributes.annotated_junction === \"true\") {\n return\n }\n if (this.config.hideUnannotatedJunctions && feature.attributes.annotated_junction === \"false\") {\n return\n }\n if (this.config.hideMotifs && this.config.hideMotifs.includes(feature.attributes.motif)) {\n return\n }\n if (this.config.hideStrand === feature.strand) {\n return\n }\n\n // check if splice junction is inside viewport\n if (this.config.minJunctionEndsVisible) {\n let numJunctionEndsVisible = 0;\n if (feature.start >= junctionRenderingContext.referenceFrameStart && feature.start <= junctionRenderingContext.referenceFrameEnd) {\n numJunctionEndsVisible += 1;\n }\n if (feature.end >= junctionRenderingContext.referenceFrameStart && feature.end <= junctionRenderingContext.referenceFrameEnd) {\n numJunctionEndsVisible += 1;\n }\n if (numJunctionEndsVisible < this.config.minJunctionEndsVisible) {\n return\n }\n }\n\n let uniquelyMappedReadCount;\n let multiMappedReadCount;\n let totalReadCount;\n if (feature.attributes.uniquely_mapped) {\n uniquelyMappedReadCount = parseInt(feature.attributes.uniquely_mapped);\n if (uniquelyMappedReadCount < this.config.minUniquelyMappedReads) {\n return\n }\n multiMappedReadCount = parseInt(feature.attributes.multi_mapped);\n totalReadCount = uniquelyMappedReadCount + multiMappedReadCount;\n if (totalReadCount < this.config.minTotalReads) {\n return\n }\n if (totalReadCount > 0 && multiMappedReadCount / totalReadCount > this.config.maxFractionMultiMappedReads) {\n return\n }\n if (feature.attributes.maximum_spliced_alignment_overhang && parseInt(feature.attributes.maximum_spliced_alignment_overhang) < this.config.minSplicedAlignmentOverhang) {\n return\n }\n }\n\n let numSamplesWithThisJunction;\n if (feature.attributes.num_samples_with_this_junction) {\n numSamplesWithThisJunction = parseInt(feature.attributes.num_samples_with_this_junction);\n if (this.config.minSamplesWithThisJunction && numSamplesWithThisJunction < this.config.minSamplesWithThisJunction) {\n return\n }\n if (this.config.maxSamplesWithThisJunction && numSamplesWithThisJunction > this.config.maxSamplesWithThisJunction) {\n return\n }\n if (feature.attributes.num_samples_total) {\n feature.attributes.percent_samples_with_this_junction = 100 * numSamplesWithThisJunction / Number(feature.attributes.num_samples_total);\n if (this.config.minPercentSamplesWithThisJunction) {\n if (feature.attributes.percent_samples_with_this_junction < this.config.minPercentSamplesWithThisJunction ||\n feature.attributes.percent_samples_with_this_junction > this.config.maxPercentSamplesWithThisJunction) {\n return\n }\n }\n }\n }\n\n const py = this.margin;\n const rowHeight = this.height;\n\n const cy = py + 0.5 * rowHeight;\n let topY = py;\n const bottomY = py + rowHeight;\n const bezierBottomY = bottomY - 10;\n\n // draw the junction arc\n const bezierControlLeftPx = (junctionLeftPx + junctionMiddlePx) / 2;\n const bezierControlRightPx = (junctionMiddlePx + junctionRightPx) / 2;\n\n let lineWidth = 1;\n if (feature.attributes.line_width) {\n lineWidth = Number(feature.attributes.line_width);\n } else {\n if (this.config.thicknessBasedOn === undefined || this.config.thicknessBasedOn === 'numUniqueReads') {\n lineWidth = uniquelyMappedReadCount;\n } else if (this.config.thicknessBasedOn === 'numReads') {\n lineWidth = totalReadCount;\n } else if (this.config.thicknessBasedOn === 'numSamplesWithThisJunction') {\n if (numSamplesWithThisJunction !== undefined) {\n lineWidth = numSamplesWithThisJunction;\n }\n }\n lineWidth = 1 + Math.log(lineWidth + 1) / Math.log(12);\n }\n\n let bounceHeight;\n if (this.config.bounceHeightBasedOn === undefined || this.config.bounceHeightBasedOn === 'random') {\n // randomly but deterministically stagger topY coordinates to reduce overlap\n bounceHeight = (feature.start + feature.end) % 7;\n } else if (this.config.bounceHeightBasedOn === 'distance') {\n bounceHeight = 6 * (feature.end - feature.start) / (junctionRenderingContext.referenceFrameEnd - junctionRenderingContext.referenceFrameStart);\n } else if (this.config.bounceHeightBasedOn === 'thickness') {\n bounceHeight = 2 * lineWidth;\n }\n topY += rowHeight * Math.max(7 - bounceHeight, 0) / 10;\n\n let color;\n if (feature.attributes.color) {\n color = feature.attributes.color; // Explicit setting\n } else if (this.config.colorBy === undefined || this.config.colorBy === 'numUniqueReads') {\n color = uniquelyMappedReadCount > this.config.colorByNumReadsThreshold ? 'blue' : '#AAAAAA'; // color gradient?\n } else if (this.config.colorBy === 'numReads') {\n color = totalReadCount > this.config.colorByNumReadsThreshold ? 'blue' : '#AAAAAA';\n } else if (this.config.colorBy === 'isAnnotatedJunction') {\n color = feature.attributes.annotated_junction === \"true\" ? '#b0b0ec' : 'orange';\n } else if (this.config.colorBy === 'strand') {\n color = feature.strand === \"+\" ? '#b0b0ec' : '#ecb0b0';\n } else if (this.config.colorBy === 'motif') {\n color = JUNCTION_MOTIF_PALETTE.getColor(feature.attributes.motif);\n } else {\n color = '#AAAAAA';\n }\n\n let label = \"\";\n if (feature.attributes.label) {\n label = feature.attributes.label.replace(/_/g, \" \");\n } else if (this.config.labelWith === undefined || this.config.labelWith === 'uniqueReadCount') {\n //default label\n label = uniquelyMappedReadCount;\n } else if (this.config.labelWith === 'totalReadCount') {\n label = totalReadCount;\n } else if (this.config.labelWith === 'numSamplesWithThisJunction') {\n if (numSamplesWithThisJunction !== undefined) {\n label = numSamplesWithThisJunction;\n }\n } else if (this.config.labelWith === 'percentSamplesWithThisJunction') {\n if (feature.attributes.percent_samples_with_this_junction !== undefined) {\n label = feature.attributes.percent_samples_with_this_junction.toFixed(0) + '%';\n }\n } else if (this.config.labelWith === 'motif') {\n if (feature.attributes.motif !== undefined) {\n label += feature.attributes.motif;\n }\n }\n\n if (this.config.labelWithInParen === 'uniqueReadCount') {\n label += ' (' + uniquelyMappedReadCount + ')';\n } else if (this.config.labelWithInParen === 'totalReadCount') {\n label += ' (' + totalReadCount + ')';\n } else if (this.config.labelWithInParen === 'multiMappedReadCount') {\n if (multiMappedReadCount > 0) {\n label += ' (+' + multiMappedReadCount + ')';\n }\n } else if (this.config.labelWithInParen === 'numSamplesWithThisJunction') {\n if (numSamplesWithThisJunction !== undefined) {\n label += ' (' + numSamplesWithThisJunction + ')';\n }\n } else if (this.config.labelWithInParen === 'percentSamplesWithThisJunction') {\n if (feature.attributes.percent_samples_with_this_junction !== undefined) {\n label += ' (' + feature.attributes.percent_samples_with_this_junction.toFixed(0) + '%)';\n }\n } else if (this.config.labelWithInParen === 'motif') {\n if (feature.attributes.motif !== undefined) {\n label += ` ${feature.attributes.motif}`;\n }\n }\n\n // data source: STAR splice junctions (eg. SJ.out.tab file converted to bed).\n // .bed \"name\" field used to store unique + multi-mapped read counts, so:\n // feature.score: unique spanning read counts\n // feature.name: unique + multi-mapped spanning read counts\n //example feature: { chr: \"chr17\", start: 39662344, end: 39662803, name: \"59\", row: 0, score: 38, strand: \"+\"}\n feature.isVisible = true;\n ctx.beginPath();\n ctx.moveTo(junctionLeftPx, bezierBottomY);\n ctx.bezierCurveTo(bezierControlLeftPx, topY, bezierControlRightPx, topY, junctionRightPx, bezierBottomY);\n\n ctx.lineWidth = lineWidth;\n ctx.strokeStyle = color;\n ctx.stroke();\n\n const drawArrowhead = (ctx, x, y, size) => {\n //TODO draw better arrow heads: https://stackoverflow.com/questions/21052972/curved-thick-arrows-on-canvas\n ctx.beginPath();\n ctx.moveTo(x, y);\n ctx.lineTo(x - size / 2, y - size);\n ctx.lineTo(x + size / 2, y - size);\n ctx.lineTo(x, y);\n ctx.closePath();\n ctx.fill();\n };\n\n if (feature.attributes.left_shape || feature.attributes.right_shape) {\n ctx.fillStyle = color;\n const arrowSize = ctx.lineWidth > 2 ? 10 : 7;\n if (feature.attributes.left_shape) {\n drawArrowhead(ctx, junctionLeftPx, bezierBottomY, arrowSize);\n }\n if (feature.attributes.right_shape) {\n drawArrowhead(ctx, junctionRightPx, bezierBottomY, arrowSize);\n }\n }\n\n ctx.fillText(label, junctionMiddlePx - ctx.measureText(label).width / 2, (7 * topY + cy) / 8);\n }\n\n clickedFeatures(clickState) {\n\n const allFeatures = super.clickedFeatures(clickState);\n\n return allFeatures.filter(function (feature) {\n return (feature.isVisible && feature.attributes)\n })\n }\n\n /**\n * Return \"popup data\" for feature @ genomic location. Data is an array of key-value pairs\n */\n popupData(clickState, features) {\n\n if (features === undefined) features = this.clickedFeatures(clickState);\n const genomicLocation = clickState.genomicLocation;\n\n const data = [];\n for (let feature of features) {\n\n const featureData = (typeof feature.popupData === \"function\") ?\n feature.popupData(genomicLocation) :\n this.extractPopupData(feature._f || feature, this.getGenomeId());\n\n if (featureData) {\n if (data.length > 0) {\n data.push(\"

\");\n }\n\n Array.prototype.push.apply(data, featureData);\n }\n }\n\n return data\n }\n\n /**\n * Called when the track is removed. Do any needed cleanup here\n */\n dispose() {\n this.trackView = undefined;\n }\n}\n\nclass RemoteFile {\n\n constructor(args) {\n this.config = args;\n this.url = mapUrl(args.path || args.url);\n }\n\n\n async read(position, length) {\n\n //console.log(`${position} - ${position + length} (${length})`)\n\n const headers = this.config.headers || {};\n\n if (position !== undefined && length) {\n const rangeString = \"bytes=\" + position + \"-\" + (position + length - 1);\n headers['Range'] = rangeString;\n }\n\n let url = this.url.slice(); // slice => copy\n if (this.config.oauthToken) {\n const token = resolveToken(this.config.oauthToken);\n headers['Authorization'] = `Bearer ${token}`;\n }\n\n if (this.config.apiKey) {\n url = addParameter(url, \"key\", this.config.apiKey);\n }\n\n const response = await fetch(url, {\n method: 'GET',\n headers: headers,\n redirect: 'follow',\n mode: 'cors',\n });\n\n const status = response.status;\n\n if (status >= 400) {\n const err = Error(response.statusText);\n err.code = status;\n throw err\n } else {\n return response.arrayBuffer()\n }\n\n /**\n * token can be a string, a function that returns a string, or a function that returns a Promise for a string\n * @param token\n * @returns {Promise<*>}\n */\n async function resolveToken(token) {\n if (typeof token === 'function') {\n return await Promise.resolve(token()) // Normalize the result to a promise, since we don't know what the function returns\n } else {\n return token\n }\n }\n\n }\n}\n\n\nfunction mapUrl(url) {\n\n if (url.includes(\"//www.dropbox.com\")) {\n return url.replace(\"//www.dropbox.com\", \"//dl.dropboxusercontent.com\")\n } else if (url.startsWith(\"ftp://ftp.ncbi.nlm.nih.gov\")) {\n return url.replace(\"ftp://\", \"https://\")\n } else {\n return url\n }\n}\n\n\nfunction addParameter(url, name, value) {\n const paramSeparator = url.includes(\"?\") ? \"&\" : \"?\";\n return url + paramSeparator + name + \"=\" + value\n}\n\nclass BufferedFile {\n\n constructor(args) {\n this.file = args.file;\n this.fetchSize = args.fetchSize || 16000;\n this.maxSize = args.maxSize || 1000000;\n this.buffers = [];\n }\n\n async read(position, length) {\n\n\n let overlappingBuffers = this.buffers.filter( b => b.overlaps(position, position + length));\n\n // See if any buffers completely contain request, if so we're done\n for(let buffer of overlappingBuffers) {\n if(buffer.contains(position, position + length)) {\n return buffer.slice(position, position + length)\n }\n }\n\n\n if(overlappingBuffers.length === 0) {\n\n // No overlap with any existing buffer\n let size = Math.max(length, this.fetchSize);\n\n // Find index of first buffer to the right, if any, to potentially limit size\n this.buffers.sort((a, b) => a.start - b.start);\n const idx = binarySearch(this.buffers, (b) => b.start > position, 0);\n if(idx < this.buffers.length) {\n size = Math.min(size, this.buffers[idx].start - position);\n }\n\n const bufferStart = position;\n const bufferData = await this.file.read(bufferStart, size);\n const buffer = new Buffer$1(bufferStart, bufferData);\n this.addBuffer(buffer);\n\n return buffer.slice(position, position + length)\n } else {\n\n // console.log(\"Cache hit\")\n // Some overlap. Fill gaps\n overlappingBuffers.sort((a, b) => a.start - b.start);\n const allBuffers = [];\n let currentEnd = position;\n for (let ob of overlappingBuffers) {\n if (currentEnd < ob.start) {\n const bufferStart = currentEnd;\n const bufferSize = ob.start - currentEnd;\n const bufferData = await this.file.read(bufferStart, bufferSize);\n const buffer = new Buffer$1(bufferStart, bufferData);\n allBuffers.push(buffer);\n }\n allBuffers.push(ob);\n currentEnd = ob.end;\n }\n\n // Check end\n const requestedEnd = position + length;\n if (requestedEnd > currentEnd) {\n const bufferStart = currentEnd;\n const bufferSize = requestedEnd - bufferStart;\n const bufferData = await this.file.read(bufferStart, bufferSize);\n const buffer = new Buffer$1(bufferStart, bufferData);\n allBuffers.push(buffer);\n }\n\n const newStart = allBuffers[0].start;\n const newArrayBuffer = concatArrayBuffers(allBuffers.map(b => b.buffer));\n const newBuffer = new Buffer$1(newStart, newArrayBuffer);\n\n // Replace the overlapping buffers with the new composite one\n const tmp = new Set(overlappingBuffers);\n this.buffers = this.buffers.filter(b => !tmp.has(b));\n this.addBuffer(newBuffer);\n\n return newBuffer.slice(position, position + length)\n }\n\n }\n\n addBuffer(buffer) {\n\n const size = this.buffers.reduce((a,b) => a + b.size, 0) + buffer.size;\n if(size > this.maxSize) {\n // console.log(`max buffer size exceeded`)\n const overage = size - this.maxSize;\n this.buffers.sort((a,b) => a.creationTime - b.creationTime);\n let sum = 0;\n let i;\n for(i=0; i overage) {\n break\n }\n }\n // console.log('removing buffers')\n // for(let j=0; j this.buffer.byteLength) {\n throw Error(\"buffer bounds error\")\n }\n return this.buffer.slice(start - this.start, end - this.start)\n }\n\n get end() {\n return this.start + this.buffer.byteLength\n }\n\n get size() {\n return this.buffer.byteLength\n }\n\n contains(start, end) {\n return start >= this.start && end <= this.end\n }\n\n overlaps(start, end) {\n return (start > this.start && start < this.end) || (end > this.start && end < this.end)\n }\n\n toString() {\n return `Buffer ${this.creationTime} ${this.start} - ${this.end}`\n }\n\n}\n\n/**\n * concatenates 2 array buffers.\n * Credit: https://gist.github.com/72lions/4528834\n *\n * @private\n * @param {ArrayBuffers} buffer1 The first buffer.\n * @param {ArrayBuffers} buffer2 The second buffer.\n * @return {ArrayBuffers} The new ArrayBuffer created out of the two.\n */\nfunction concatArrayBuffers(buffers) {\n const size = buffers.reduce((a,b) => a + b.byteLength, 0);\n const tmp = new Uint8Array(size);\n let offset = 0;\n for(let b of buffers) {\n tmp.set(new Uint8Array(b), offset);\n offset += b.byteLength;\n }\n return tmp.buffer\n}\n\n/**\n * Return 0 <= i <= array.length such that !pred(array[i - 1]) && pred(array[i]).\n *\n * returns an index 0 ≤ i ≤ array.length such that the given predicate is false for array[i - 1] and true for array[i]* *\n */\nfunction binarySearch(array, pred, min) {\n let lo = min - 1, hi = array.length;\n while (1 + lo < hi) {\n const mi = lo + ((hi - lo) >> 1);\n if (pred(array[mi])) {\n hi = mi;\n } else {\n lo = mi;\n }\n }\n return hi\n}\n\nclass BlobFile {\n\n constructor(blob) {\n this.file = blob;\n }\n\n async read(position, length) {\n\n if(length === 0) {\n return new ArrayBuffer()\n }\n\n const blob = (position != undefined && length) ?\n this.file.slice(position, position + length) :\n this.file;\n\n return blob.arrayBuffer()\n }\n}\n\nvar __defProp = Object.defineProperty;\nvar __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;\nvar __publicField = (obj, key, value) => {\n __defNormalProp(obj, typeof key !== \"symbol\" ? key + \"\" : key, value);\n return value;\n};\n\n// esm/core.js\nasync function _unpack_struct_from_async(structure, async_buf, offset = 0) {\n var output = /* @__PURE__ */ new Map();\n for (let [key, fmt] of structure.entries()) {\n let value = await struct.unpack_from_async(\"<\" + fmt, async_buf, offset);\n offset += struct.calcsize(fmt);\n if (value.length == 1) {\n value = value[0];\n }\n output.set(key, value);\n }\n return output;\n}\nfunction _unpack_struct_from(structure, buf, offset = 0) {\n var output = /* @__PURE__ */ new Map();\n for (let [key, fmt] of structure.entries()) {\n let value = struct.unpack_from(\"<\" + fmt, buf, offset);\n offset += struct.calcsize(fmt);\n if (value.length == 1) {\n value = value[0];\n }\n output.set(key, value);\n }\n return output;\n}\nfunction assert(thing) {\n if (!thing) {\n thing();\n }\n}\nfunction _structure_size(structure) {\n var fmt = \"<\" + Array.from(structure.values()).join(\"\");\n return struct.calcsize(fmt);\n}\nfunction _padded_size(size, padding_multiple = 8) {\n return Math.ceil(size / padding_multiple) * padding_multiple;\n}\nvar dtype_to_format = {\n \"u\": \"Uint\",\n \"i\": \"Int\",\n \"f\": \"Float\"\n};\nfunction dtype_getter(dtype_str) {\n var big_endian = struct._is_big_endian(dtype_str);\n var getter, nbytes;\n if (/S/.test(dtype_str)) {\n getter = \"getString\";\n nbytes = ((dtype_str.match(/S(\\d*)/) || [])[1] || 1) | 0;\n } else {\n let [_, fstr, bytestr] = dtype_str.match(/[<>=!@]?(i|u|f)(\\d*)/);\n nbytes = parseInt(bytestr || 4, 10);\n let nbits = nbytes * 8;\n getter = \"get\" + dtype_to_format[fstr] + nbits.toFixed();\n }\n return [getter, big_endian, nbytes];\n}\nvar Struct = class {\n constructor() {\n this.big_endian = isBigEndian();\n this.getters = {\n \"s\": \"getUint8\",\n \"b\": \"getInt8\",\n \"B\": \"getUint8\",\n \"h\": \"getInt16\",\n \"H\": \"getUint16\",\n \"i\": \"getInt32\",\n \"I\": \"getUint32\",\n \"l\": \"getInt32\",\n \"L\": \"getUint32\",\n \"q\": \"getInt64\",\n \"Q\": \"getUint64\",\n \"f\": \"getFloat32\",\n \"d\": \"getFloat64\"\n };\n this.byte_lengths = {\n \"s\": 1,\n \"b\": 1,\n \"B\": 1,\n \"h\": 2,\n \"H\": 2,\n \"i\": 4,\n \"I\": 4,\n \"l\": 4,\n \"L\": 4,\n \"q\": 8,\n \"Q\": 8,\n \"f\": 4,\n \"d\": 8\n };\n let all_formats = Object.keys(this.byte_lengths).join(\"\");\n this.fmt_size_regex = \"(\\\\d*)([\" + all_formats + \"])\";\n }\n calcsize(fmt) {\n var size = 0;\n var match;\n var regex = new RegExp(this.fmt_size_regex, \"g\");\n while ((match = regex.exec(fmt)) !== null) {\n let n = parseInt(match[1] || 1, 10);\n let f = match[2];\n let subsize = this.byte_lengths[f];\n size += n * subsize;\n }\n return size;\n }\n _is_big_endian(fmt) {\n var big_endian;\n if (/^)/.test(fmt)) {\n big_endian = true;\n } else {\n big_endian = this.big_endian;\n }\n return big_endian;\n }\n async unpack_from_async(fmt, async_buf, offset) {\n offset = Number.parseInt(offset || 0);\n const total_size = this.calcsize(fmt);\n const local_buffer = await async_buf.slice(offset, offset + total_size);\n let local_offset = 0;\n var view = new DataView64(local_buffer);\n var output = [];\n var big_endian = this._is_big_endian(fmt);\n var match;\n var regex = new RegExp(this.fmt_size_regex, \"g\");\n while ((match = regex.exec(fmt)) !== null) {\n let n = parseInt(match[1] || 1, 10);\n let f = match[2];\n let getter = this.getters[f];\n let size = this.byte_lengths[f];\n if (f == \"s\") {\n output.push(new TextDecoder().decode(local_buffer.slice(local_offset, local_offset + n)));\n local_offset += n;\n } else {\n for (var i = 0; i < n; i++) {\n output.push(view[getter](local_offset, !big_endian));\n local_offset += size;\n }\n }\n }\n return output;\n }\n unpack_from(fmt, buffer, offset) {\n offset = Number.parseInt(offset || 0);\n const total_size = this.calcsize(fmt);\n const local_buffer = buffer.slice(offset, offset + total_size);\n let local_offset = 0;\n var view = new DataView64(local_buffer);\n var output = [];\n var big_endian = this._is_big_endian(fmt);\n var match;\n var regex = new RegExp(this.fmt_size_regex, \"g\");\n while ((match = regex.exec(fmt)) !== null) {\n let n = parseInt(match[1] || 1, 10);\n let f = match[2];\n let getter = this.getters[f];\n let size = this.byte_lengths[f];\n if (f == \"s\") {\n output.push(new TextDecoder().decode(local_buffer.slice(local_offset, local_offset + n)));\n local_offset += n;\n } else {\n for (var i = 0; i < n; i++) {\n output.push(view[getter](local_offset, !big_endian));\n local_offset += size;\n }\n }\n }\n return output;\n }\n};\nvar struct = new Struct();\nfunction isBigEndian() {\n const array = new Uint8Array(4);\n const view = new Uint32Array(array.buffer);\n return !((view[0] = 1) & array[0]);\n}\nvar DataView64 = class extends DataView {\n getUint64(byteOffset, littleEndian) {\n const left = BigInt(this.getUint32(byteOffset, littleEndian));\n const right = BigInt(this.getUint32(byteOffset + 4, littleEndian));\n let combined = littleEndian ? left + (right << 32n) : (left << 32n) + right;\n return Number.parseInt(combined);\n }\n getInt64(byteOffset, littleEndian) {\n var low, high;\n if (littleEndian) {\n low = this.getUint32(byteOffset, true);\n high = this.getInt32(byteOffset + 4, true);\n } else {\n high = this.getInt32(byteOffset, false);\n low = this.getUint32(byteOffset + 4, false);\n }\n let combined = BigInt(low) + (BigInt(high) << 32n);\n return Number.parseInt(combined);\n }\n getString(byteOffset, littleEndian, length) {\n const str_buffer = this.buffer.slice(byteOffset, byteOffset + length);\n const decoder = new TextDecoder();\n return decoder.decode(str_buffer);\n }\n getVLENStruct(byteOffset, littleEndian, length) {\n let item_size = this.getUint32(byteOffset, littleEndian);\n let collection_address = this.getUint64(byteOffset + 4, littleEndian);\n let object_index = this.getUint32(byteOffset + 12, littleEndian);\n return [item_size, collection_address, object_index];\n }\n};\nfunction bitSize(integer) {\n return integer.toString(2).length;\n}\nfunction _unpack_integer(nbytes, buf, offset = 0, littleEndian = true) {\n const local_buffer = buf.slice(offset, offset + nbytes);\n let bytes = new Uint8Array(local_buffer);\n if (!littleEndian) {\n bytes.reverse();\n }\n let integer = bytes.reduce((accumulator, currentValue, index) => accumulator + (currentValue << index * 8), 0);\n return integer;\n}\n\n// esm/datatype-msg.js\nvar DatatypeMessage = class {\n constructor(buf, offset) {\n this.buf = buf;\n this.offset = offset;\n this.dtype = this.determine_dtype();\n }\n async determine_dtype() {\n let datatype_msg = await _unpack_struct_from_async(DATATYPE_MSG, this.buf, this.offset);\n this.offset += DATATYPE_MSG_SIZE;\n let datatype_class = datatype_msg.get(\"class_and_version\") & 15;\n if (datatype_class == DATATYPE_FIXED_POINT) {\n return this._determine_dtype_fixed_point(datatype_msg);\n } else if (datatype_class == DATATYPE_FLOATING_POINT) {\n return this._determine_dtype_floating_point(datatype_msg);\n } else if (datatype_class == DATATYPE_TIME) {\n throw \"Time datatype class not supported.\";\n } else if (datatype_class == DATATYPE_STRING) {\n return this._determine_dtype_string(datatype_msg);\n } else if (datatype_class == DATATYPE_BITFIELD) {\n throw \"Bitfield datatype class not supported.\";\n } else if (datatype_class == DATATYPE_OPAQUE) {\n return {\n datatype_class: DATATYPE_OPAQUE,\n size: datatype_msg.get(\"size\")\n };\n } else if (datatype_class == DATATYPE_COMPOUND) {\n return this._determine_dtype_compound(datatype_msg);\n } else if (datatype_class == DATATYPE_REFERENCE) {\n return [\"REFERENCE\", datatype_msg.get(\"size\")];\n } else if (datatype_class == DATATYPE_ENUMERATED) {\n return this.determine_dtype();\n } else if (datatype_class == DATATYPE_ARRAY) {\n throw \"Array datatype class not supported.\";\n } else if (datatype_class == DATATYPE_VARIABLE_LENGTH) {\n let vlen_type = this._determine_dtype_vlen(datatype_msg);\n if (vlen_type[0] == \"VLEN_SEQUENCE\") {\n let base_type = this.determine_dtype();\n vlen_type = [\"VLEN_SEQUENCE\", base_type];\n }\n return vlen_type;\n } else {\n throw \"Invalid datatype class \" + datatype_class;\n }\n }\n _determine_dtype_fixed_point(datatype_msg) {\n let length_in_bytes = datatype_msg.get(\"size\");\n if (![1, 2, 4, 8].includes(length_in_bytes)) {\n throw \"Unsupported datatype size\";\n }\n let signed = datatype_msg.get(\"class_bit_field_0\") & 8;\n var dtype_char;\n if (signed > 0) {\n dtype_char = \"i\";\n } else {\n dtype_char = \"u\";\n }\n let byte_order = datatype_msg.get(\"class_bit_field_0\") & 1;\n var byte_order_char;\n if (byte_order == 0) {\n byte_order_char = \"<\";\n } else {\n byte_order_char = \">\";\n }\n this.offset += 4;\n return byte_order_char + dtype_char + length_in_bytes.toFixed();\n }\n _determine_dtype_floating_point(datatype_msg) {\n let length_in_bytes = datatype_msg.get(\"size\");\n if (![1, 2, 4, 8].includes(length_in_bytes)) {\n throw \"Unsupported datatype size\";\n }\n let dtype_char = \"f\";\n let byte_order = datatype_msg.get(\"class_bit_field_0\") & 1;\n var byte_order_char;\n if (byte_order == 0) {\n byte_order_char = \"<\";\n } else {\n byte_order_char = \">\";\n }\n this.offset += 12;\n return byte_order_char + dtype_char + length_in_bytes.toFixed();\n }\n _determine_dtype_string(datatype_msg) {\n return \"S\" + datatype_msg.get(\"size\").toFixed();\n }\n _determine_dtype_vlen(datatype_msg) {\n let vlen_type = datatype_msg.get(\"class_bit_field_0\") & 1;\n if (vlen_type != 1) {\n return [\"VLEN_SEQUENCE\", 0, 0];\n }\n let padding_type = datatype_msg.get(\"class_bit_field_0\") >> 4;\n let character_set = datatype_msg.get(\"class_bit_field_1\") & 1;\n return [\"VLEN_STRING\", padding_type, character_set];\n }\n _determine_dtype_compound(datatype_msg) {\n throw \"Compound type not yet implemented!\";\n }\n};\nvar DATATYPE_MSG = /* @__PURE__ */ new Map([\n [\"class_and_version\", \"B\"],\n [\"class_bit_field_0\", \"B\"],\n [\"class_bit_field_1\", \"B\"],\n [\"class_bit_field_2\", \"B\"],\n [\"size\", \"I\"]\n]);\nvar DATATYPE_MSG_SIZE = _structure_size(DATATYPE_MSG);\nvar COMPOUND_PROP_DESC_V1 = /* @__PURE__ */ new Map([\n [\"offset\", \"I\"],\n [\"dimensionality\", \"B\"],\n [\"reserved_0\", \"B\"],\n [\"reserved_1\", \"B\"],\n [\"reserved_2\", \"B\"],\n [\"permutation\", \"I\"],\n [\"reserved_3\", \"I\"],\n [\"dim_size_1\", \"I\"],\n [\"dim_size_2\", \"I\"],\n [\"dim_size_3\", \"I\"],\n [\"dim_size_4\", \"I\"]\n]);\n_structure_size(COMPOUND_PROP_DESC_V1);\nvar DATATYPE_FIXED_POINT = 0;\nvar DATATYPE_FLOATING_POINT = 1;\nvar DATATYPE_TIME = 2;\nvar DATATYPE_STRING = 3;\nvar DATATYPE_BITFIELD = 4;\nvar DATATYPE_OPAQUE = 5;\nvar DATATYPE_COMPOUND = 6;\nvar DATATYPE_REFERENCE = 7;\nvar DATATYPE_ENUMERATED = 8;\nvar DATATYPE_VARIABLE_LENGTH = 9;\nvar DATATYPE_ARRAY = 10;\nfunction zero$1(buf) {\n let len = buf.length;\n while (--len >= 0) {\n buf[len] = 0;\n }\n}\nvar MIN_MATCH$1 = 3;\nvar MAX_MATCH$1 = 258;\nvar LENGTH_CODES$1 = 29;\nvar LITERALS$1 = 256;\nvar L_CODES$1 = LITERALS$1 + 1 + LENGTH_CODES$1;\nvar D_CODES$1 = 30;\nvar DIST_CODE_LEN = 512;\nvar static_ltree = new Array((L_CODES$1 + 2) * 2);\nzero$1(static_ltree);\nvar static_dtree = new Array(D_CODES$1 * 2);\nzero$1(static_dtree);\nvar _dist_code = new Array(DIST_CODE_LEN);\nzero$1(_dist_code);\nvar _length_code = new Array(MAX_MATCH$1 - MIN_MATCH$1 + 1);\nzero$1(_length_code);\nvar base_length = new Array(LENGTH_CODES$1);\nzero$1(base_length);\nvar base_dist = new Array(D_CODES$1);\nzero$1(base_dist);\nvar adler32 = (adler, buf, len, pos) => {\n let s1 = adler & 65535 | 0, s2 = adler >>> 16 & 65535 | 0, n = 0;\n while (len !== 0) {\n n = len > 2e3 ? 2e3 : len;\n len -= n;\n do {\n s1 = s1 + buf[pos++] | 0;\n s2 = s2 + s1 | 0;\n } while (--n);\n s1 %= 65521;\n s2 %= 65521;\n }\n return s1 | s2 << 16 | 0;\n};\nvar adler32_1 = adler32;\nvar makeTable = () => {\n let c, table = [];\n for (var n = 0; n < 256; n++) {\n c = n;\n for (var k = 0; k < 8; k++) {\n c = c & 1 ? 3988292384 ^ c >>> 1 : c >>> 1;\n }\n table[n] = c;\n }\n return table;\n};\nvar crcTable = new Uint32Array(makeTable());\nvar crc32 = (crc, buf, len, pos) => {\n const t = crcTable;\n const end = pos + len;\n crc ^= -1;\n for (let i = pos; i < end; i++) {\n crc = crc >>> 8 ^ t[(crc ^ buf[i]) & 255];\n }\n return crc ^ -1;\n};\nvar crc32_1 = crc32;\nvar messages = {\n 2: \"need dictionary\",\n 1: \"stream end\",\n 0: \"\",\n \"-1\": \"file error\",\n \"-2\": \"stream error\",\n \"-3\": \"data error\",\n \"-4\": \"insufficient memory\",\n \"-5\": \"buffer error\",\n \"-6\": \"incompatible version\"\n};\nvar constants$2 = {\n Z_NO_FLUSH: 0,\n Z_PARTIAL_FLUSH: 1,\n Z_SYNC_FLUSH: 2,\n Z_FULL_FLUSH: 3,\n Z_FINISH: 4,\n Z_BLOCK: 5,\n Z_TREES: 6,\n Z_OK: 0,\n Z_STREAM_END: 1,\n Z_NEED_DICT: 2,\n Z_ERRNO: -1,\n Z_STREAM_ERROR: -2,\n Z_DATA_ERROR: -3,\n Z_MEM_ERROR: -4,\n Z_BUF_ERROR: -5,\n Z_NO_COMPRESSION: 0,\n Z_BEST_SPEED: 1,\n Z_BEST_COMPRESSION: 9,\n Z_DEFAULT_COMPRESSION: -1,\n Z_FILTERED: 1,\n Z_HUFFMAN_ONLY: 2,\n Z_RLE: 3,\n Z_FIXED: 4,\n Z_DEFAULT_STRATEGY: 0,\n Z_BINARY: 0,\n Z_TEXT: 1,\n Z_UNKNOWN: 2,\n Z_DEFLATED: 8\n};\nvar _has = (obj, key) => {\n return Object.prototype.hasOwnProperty.call(obj, key);\n};\nvar assign = function(obj) {\n const sources = Array.prototype.slice.call(arguments, 1);\n while (sources.length) {\n const source = sources.shift();\n if (!source) {\n continue;\n }\n if (typeof source !== \"object\") {\n throw new TypeError(source + \"must be non-object\");\n }\n for (const p in source) {\n if (_has(source, p)) {\n obj[p] = source[p];\n }\n }\n }\n return obj;\n};\nvar flattenChunks = (chunks) => {\n let len = 0;\n for (let i = 0, l = chunks.length; i < l; i++) {\n len += chunks[i].length;\n }\n const result = new Uint8Array(len);\n for (let i = 0, pos = 0, l = chunks.length; i < l; i++) {\n let chunk = chunks[i];\n result.set(chunk, pos);\n pos += chunk.length;\n }\n return result;\n};\nvar common = {\n assign,\n flattenChunks\n};\nvar STR_APPLY_UIA_OK = true;\ntry {\n String.fromCharCode.apply(null, new Uint8Array(1));\n} catch (__) {\n STR_APPLY_UIA_OK = false;\n}\nvar _utf8len = new Uint8Array(256);\nfor (let q = 0; q < 256; q++) {\n _utf8len[q] = q >= 252 ? 6 : q >= 248 ? 5 : q >= 240 ? 4 : q >= 224 ? 3 : q >= 192 ? 2 : 1;\n}\n_utf8len[254] = _utf8len[254] = 1;\nvar string2buf = (str) => {\n if (typeof TextEncoder === \"function\" && TextEncoder.prototype.encode) {\n return new TextEncoder().encode(str);\n }\n let buf, c, c2, m_pos, i, str_len = str.length, buf_len = 0;\n for (m_pos = 0; m_pos < str_len; m_pos++) {\n c = str.charCodeAt(m_pos);\n if ((c & 64512) === 55296 && m_pos + 1 < str_len) {\n c2 = str.charCodeAt(m_pos + 1);\n if ((c2 & 64512) === 56320) {\n c = 65536 + (c - 55296 << 10) + (c2 - 56320);\n m_pos++;\n }\n }\n buf_len += c < 128 ? 1 : c < 2048 ? 2 : c < 65536 ? 3 : 4;\n }\n buf = new Uint8Array(buf_len);\n for (i = 0, m_pos = 0; i < buf_len; m_pos++) {\n c = str.charCodeAt(m_pos);\n if ((c & 64512) === 55296 && m_pos + 1 < str_len) {\n c2 = str.charCodeAt(m_pos + 1);\n if ((c2 & 64512) === 56320) {\n c = 65536 + (c - 55296 << 10) + (c2 - 56320);\n m_pos++;\n }\n }\n if (c < 128) {\n buf[i++] = c;\n } else if (c < 2048) {\n buf[i++] = 192 | c >>> 6;\n buf[i++] = 128 | c & 63;\n } else if (c < 65536) {\n buf[i++] = 224 | c >>> 12;\n buf[i++] = 128 | c >>> 6 & 63;\n buf[i++] = 128 | c & 63;\n } else {\n buf[i++] = 240 | c >>> 18;\n buf[i++] = 128 | c >>> 12 & 63;\n buf[i++] = 128 | c >>> 6 & 63;\n buf[i++] = 128 | c & 63;\n }\n }\n return buf;\n};\nvar buf2binstring = (buf, len) => {\n if (len < 65534) {\n if (buf.subarray && STR_APPLY_UIA_OK) {\n return String.fromCharCode.apply(null, buf.length === len ? buf : buf.subarray(0, len));\n }\n }\n let result = \"\";\n for (let i = 0; i < len; i++) {\n result += String.fromCharCode(buf[i]);\n }\n return result;\n};\nvar buf2string = (buf, max) => {\n const len = max || buf.length;\n if (typeof TextDecoder === \"function\" && TextDecoder.prototype.decode) {\n return new TextDecoder().decode(buf.subarray(0, max));\n }\n let i, out;\n const utf16buf = new Array(len * 2);\n for (out = 0, i = 0; i < len; ) {\n let c = buf[i++];\n if (c < 128) {\n utf16buf[out++] = c;\n continue;\n }\n let c_len = _utf8len[c];\n if (c_len > 4) {\n utf16buf[out++] = 65533;\n i += c_len - 1;\n continue;\n }\n c &= c_len === 2 ? 31 : c_len === 3 ? 15 : 7;\n while (c_len > 1 && i < len) {\n c = c << 6 | buf[i++] & 63;\n c_len--;\n }\n if (c_len > 1) {\n utf16buf[out++] = 65533;\n continue;\n }\n if (c < 65536) {\n utf16buf[out++] = c;\n } else {\n c -= 65536;\n utf16buf[out++] = 55296 | c >> 10 & 1023;\n utf16buf[out++] = 56320 | c & 1023;\n }\n }\n return buf2binstring(utf16buf, out);\n};\nvar utf8border = (buf, max) => {\n max = max || buf.length;\n if (max > buf.length) {\n max = buf.length;\n }\n let pos = max - 1;\n while (pos >= 0 && (buf[pos] & 192) === 128) {\n pos--;\n }\n if (pos < 0) {\n return max;\n }\n if (pos === 0) {\n return max;\n }\n return pos + _utf8len[buf[pos]] > max ? pos : max;\n};\nvar strings = {\n string2buf,\n buf2string,\n utf8border\n};\nfunction ZStream() {\n this.input = null;\n this.next_in = 0;\n this.avail_in = 0;\n this.total_in = 0;\n this.output = null;\n this.next_out = 0;\n this.avail_out = 0;\n this.total_out = 0;\n this.msg = \"\";\n this.state = null;\n this.data_type = 2;\n this.adler = 0;\n}\nvar zstream = ZStream;\nvar BAD$1 = 30;\nvar TYPE$1 = 12;\nvar inffast = function inflate_fast(strm, start) {\n let _in;\n let last;\n let _out;\n let beg;\n let end;\n let dmax;\n let wsize;\n let whave;\n let wnext;\n let s_window;\n let hold;\n let bits;\n let lcode;\n let dcode;\n let lmask;\n let dmask;\n let here;\n let op;\n let len;\n let dist;\n let from;\n let from_source;\n let input, output;\n const state = strm.state;\n _in = strm.next_in;\n input = strm.input;\n last = _in + (strm.avail_in - 5);\n _out = strm.next_out;\n output = strm.output;\n beg = _out - (start - strm.avail_out);\n end = _out + (strm.avail_out - 257);\n dmax = state.dmax;\n wsize = state.wsize;\n whave = state.whave;\n wnext = state.wnext;\n s_window = state.window;\n hold = state.hold;\n bits = state.bits;\n lcode = state.lencode;\n dcode = state.distcode;\n lmask = (1 << state.lenbits) - 1;\n dmask = (1 << state.distbits) - 1;\n top:\n do {\n if (bits < 15) {\n hold += input[_in++] << bits;\n bits += 8;\n hold += input[_in++] << bits;\n bits += 8;\n }\n here = lcode[hold & lmask];\n dolen:\n for (; ; ) {\n op = here >>> 24;\n hold >>>= op;\n bits -= op;\n op = here >>> 16 & 255;\n if (op === 0) {\n output[_out++] = here & 65535;\n } else if (op & 16) {\n len = here & 65535;\n op &= 15;\n if (op) {\n if (bits < op) {\n hold += input[_in++] << bits;\n bits += 8;\n }\n len += hold & (1 << op) - 1;\n hold >>>= op;\n bits -= op;\n }\n if (bits < 15) {\n hold += input[_in++] << bits;\n bits += 8;\n hold += input[_in++] << bits;\n bits += 8;\n }\n here = dcode[hold & dmask];\n dodist:\n for (; ; ) {\n op = here >>> 24;\n hold >>>= op;\n bits -= op;\n op = here >>> 16 & 255;\n if (op & 16) {\n dist = here & 65535;\n op &= 15;\n if (bits < op) {\n hold += input[_in++] << bits;\n bits += 8;\n if (bits < op) {\n hold += input[_in++] << bits;\n bits += 8;\n }\n }\n dist += hold & (1 << op) - 1;\n if (dist > dmax) {\n strm.msg = \"invalid distance too far back\";\n state.mode = BAD$1;\n break top;\n }\n hold >>>= op;\n bits -= op;\n op = _out - beg;\n if (dist > op) {\n op = dist - op;\n if (op > whave) {\n if (state.sane) {\n strm.msg = \"invalid distance too far back\";\n state.mode = BAD$1;\n break top;\n }\n }\n from = 0;\n from_source = s_window;\n if (wnext === 0) {\n from += wsize - op;\n if (op < len) {\n len -= op;\n do {\n output[_out++] = s_window[from++];\n } while (--op);\n from = _out - dist;\n from_source = output;\n }\n } else if (wnext < op) {\n from += wsize + wnext - op;\n op -= wnext;\n if (op < len) {\n len -= op;\n do {\n output[_out++] = s_window[from++];\n } while (--op);\n from = 0;\n if (wnext < len) {\n op = wnext;\n len -= op;\n do {\n output[_out++] = s_window[from++];\n } while (--op);\n from = _out - dist;\n from_source = output;\n }\n }\n } else {\n from += wnext - op;\n if (op < len) {\n len -= op;\n do {\n output[_out++] = s_window[from++];\n } while (--op);\n from = _out - dist;\n from_source = output;\n }\n }\n while (len > 2) {\n output[_out++] = from_source[from++];\n output[_out++] = from_source[from++];\n output[_out++] = from_source[from++];\n len -= 3;\n }\n if (len) {\n output[_out++] = from_source[from++];\n if (len > 1) {\n output[_out++] = from_source[from++];\n }\n }\n } else {\n from = _out - dist;\n do {\n output[_out++] = output[from++];\n output[_out++] = output[from++];\n output[_out++] = output[from++];\n len -= 3;\n } while (len > 2);\n if (len) {\n output[_out++] = output[from++];\n if (len > 1) {\n output[_out++] = output[from++];\n }\n }\n }\n } else if ((op & 64) === 0) {\n here = dcode[(here & 65535) + (hold & (1 << op) - 1)];\n continue dodist;\n } else {\n strm.msg = \"invalid distance code\";\n state.mode = BAD$1;\n break top;\n }\n break;\n }\n } else if ((op & 64) === 0) {\n here = lcode[(here & 65535) + (hold & (1 << op) - 1)];\n continue dolen;\n } else if (op & 32) {\n state.mode = TYPE$1;\n break top;\n } else {\n strm.msg = \"invalid literal/length code\";\n state.mode = BAD$1;\n break top;\n }\n break;\n }\n } while (_in < last && _out < end);\n len = bits >> 3;\n _in -= len;\n bits -= len << 3;\n hold &= (1 << bits) - 1;\n strm.next_in = _in;\n strm.next_out = _out;\n strm.avail_in = _in < last ? 5 + (last - _in) : 5 - (_in - last);\n strm.avail_out = _out < end ? 257 + (end - _out) : 257 - (_out - end);\n state.hold = hold;\n state.bits = bits;\n return;\n};\nvar MAXBITS = 15;\nvar ENOUGH_LENS$1 = 852;\nvar ENOUGH_DISTS$1 = 592;\nvar CODES$1 = 0;\nvar LENS$1 = 1;\nvar DISTS$1 = 2;\nvar lbase = new Uint16Array([\n 3,\n 4,\n 5,\n 6,\n 7,\n 8,\n 9,\n 10,\n 11,\n 13,\n 15,\n 17,\n 19,\n 23,\n 27,\n 31,\n 35,\n 43,\n 51,\n 59,\n 67,\n 83,\n 99,\n 115,\n 131,\n 163,\n 195,\n 227,\n 258,\n 0,\n 0\n]);\nvar lext = new Uint8Array([\n 16,\n 16,\n 16,\n 16,\n 16,\n 16,\n 16,\n 16,\n 17,\n 17,\n 17,\n 17,\n 18,\n 18,\n 18,\n 18,\n 19,\n 19,\n 19,\n 19,\n 20,\n 20,\n 20,\n 20,\n 21,\n 21,\n 21,\n 21,\n 16,\n 72,\n 78\n]);\nvar dbase = new Uint16Array([\n 1,\n 2,\n 3,\n 4,\n 5,\n 7,\n 9,\n 13,\n 17,\n 25,\n 33,\n 49,\n 65,\n 97,\n 129,\n 193,\n 257,\n 385,\n 513,\n 769,\n 1025,\n 1537,\n 2049,\n 3073,\n 4097,\n 6145,\n 8193,\n 12289,\n 16385,\n 24577,\n 0,\n 0\n]);\nvar dext = new Uint8Array([\n 16,\n 16,\n 16,\n 16,\n 17,\n 17,\n 18,\n 18,\n 19,\n 19,\n 20,\n 20,\n 21,\n 21,\n 22,\n 22,\n 23,\n 23,\n 24,\n 24,\n 25,\n 25,\n 26,\n 26,\n 27,\n 27,\n 28,\n 28,\n 29,\n 29,\n 64,\n 64\n]);\nvar inflate_table = (type, lens, lens_index, codes, table, table_index, work, opts) => {\n const bits = opts.bits;\n let len = 0;\n let sym = 0;\n let min = 0, max = 0;\n let root = 0;\n let curr = 0;\n let drop = 0;\n let left = 0;\n let used = 0;\n let huff = 0;\n let incr;\n let fill;\n let low;\n let mask;\n let next;\n let base = null;\n let base_index = 0;\n let end;\n const count = new Uint16Array(MAXBITS + 1);\n const offs = new Uint16Array(MAXBITS + 1);\n let extra = null;\n let extra_index = 0;\n let here_bits, here_op, here_val;\n for (len = 0; len <= MAXBITS; len++) {\n count[len] = 0;\n }\n for (sym = 0; sym < codes; sym++) {\n count[lens[lens_index + sym]]++;\n }\n root = bits;\n for (max = MAXBITS; max >= 1; max--) {\n if (count[max] !== 0) {\n break;\n }\n }\n if (root > max) {\n root = max;\n }\n if (max === 0) {\n table[table_index++] = 1 << 24 | 64 << 16 | 0;\n table[table_index++] = 1 << 24 | 64 << 16 | 0;\n opts.bits = 1;\n return 0;\n }\n for (min = 1; min < max; min++) {\n if (count[min] !== 0) {\n break;\n }\n }\n if (root < min) {\n root = min;\n }\n left = 1;\n for (len = 1; len <= MAXBITS; len++) {\n left <<= 1;\n left -= count[len];\n if (left < 0) {\n return -1;\n }\n }\n if (left > 0 && (type === CODES$1 || max !== 1)) {\n return -1;\n }\n offs[1] = 0;\n for (len = 1; len < MAXBITS; len++) {\n offs[len + 1] = offs[len] + count[len];\n }\n for (sym = 0; sym < codes; sym++) {\n if (lens[lens_index + sym] !== 0) {\n work[offs[lens[lens_index + sym]]++] = sym;\n }\n }\n if (type === CODES$1) {\n base = extra = work;\n end = 19;\n } else if (type === LENS$1) {\n base = lbase;\n base_index -= 257;\n extra = lext;\n extra_index -= 257;\n end = 256;\n } else {\n base = dbase;\n extra = dext;\n end = -1;\n }\n huff = 0;\n sym = 0;\n len = min;\n next = table_index;\n curr = root;\n drop = 0;\n low = -1;\n used = 1 << root;\n mask = used - 1;\n if (type === LENS$1 && used > ENOUGH_LENS$1 || type === DISTS$1 && used > ENOUGH_DISTS$1) {\n return 1;\n }\n for (; ; ) {\n here_bits = len - drop;\n if (work[sym] < end) {\n here_op = 0;\n here_val = work[sym];\n } else if (work[sym] > end) {\n here_op = extra[extra_index + work[sym]];\n here_val = base[base_index + work[sym]];\n } else {\n here_op = 32 + 64;\n here_val = 0;\n }\n incr = 1 << len - drop;\n fill = 1 << curr;\n min = fill;\n do {\n fill -= incr;\n table[next + (huff >> drop) + fill] = here_bits << 24 | here_op << 16 | here_val | 0;\n } while (fill !== 0);\n incr = 1 << len - 1;\n while (huff & incr) {\n incr >>= 1;\n }\n if (incr !== 0) {\n huff &= incr - 1;\n huff += incr;\n } else {\n huff = 0;\n }\n sym++;\n if (--count[len] === 0) {\n if (len === max) {\n break;\n }\n len = lens[lens_index + work[sym]];\n }\n if (len > root && (huff & mask) !== low) {\n if (drop === 0) {\n drop = root;\n }\n next += min;\n curr = len - drop;\n left = 1 << curr;\n while (curr + drop < max) {\n left -= count[curr + drop];\n if (left <= 0) {\n break;\n }\n curr++;\n left <<= 1;\n }\n used += 1 << curr;\n if (type === LENS$1 && used > ENOUGH_LENS$1 || type === DISTS$1 && used > ENOUGH_DISTS$1) {\n return 1;\n }\n low = huff & mask;\n table[low] = root << 24 | curr << 16 | next - table_index | 0;\n }\n }\n if (huff !== 0) {\n table[next + huff] = len - drop << 24 | 64 << 16 | 0;\n }\n opts.bits = root;\n return 0;\n};\nvar inftrees = inflate_table;\nvar CODES = 0;\nvar LENS = 1;\nvar DISTS = 2;\nvar {\n Z_FINISH: Z_FINISH$1,\n Z_BLOCK,\n Z_TREES,\n Z_OK: Z_OK$1,\n Z_STREAM_END: Z_STREAM_END$1,\n Z_NEED_DICT: Z_NEED_DICT$1,\n Z_STREAM_ERROR: Z_STREAM_ERROR$1,\n Z_DATA_ERROR: Z_DATA_ERROR$1,\n Z_MEM_ERROR: Z_MEM_ERROR$1,\n Z_BUF_ERROR,\n Z_DEFLATED\n} = constants$2;\nvar HEAD = 1;\nvar FLAGS = 2;\nvar TIME = 3;\nvar OS = 4;\nvar EXLEN = 5;\nvar EXTRA = 6;\nvar NAME = 7;\nvar COMMENT = 8;\nvar HCRC = 9;\nvar DICTID = 10;\nvar DICT = 11;\nvar TYPE = 12;\nvar TYPEDO = 13;\nvar STORED = 14;\nvar COPY_ = 15;\nvar COPY = 16;\nvar TABLE = 17;\nvar LENLENS = 18;\nvar CODELENS = 19;\nvar LEN_ = 20;\nvar LEN = 21;\nvar LENEXT = 22;\nvar DIST = 23;\nvar DISTEXT = 24;\nvar MATCH = 25;\nvar LIT = 26;\nvar CHECK = 27;\nvar LENGTH = 28;\nvar DONE = 29;\nvar BAD = 30;\nvar MEM = 31;\nvar SYNC = 32;\nvar ENOUGH_LENS = 852;\nvar ENOUGH_DISTS = 592;\nvar MAX_WBITS = 15;\nvar DEF_WBITS = MAX_WBITS;\nvar zswap32 = (q) => {\n return (q >>> 24 & 255) + (q >>> 8 & 65280) + ((q & 65280) << 8) + ((q & 255) << 24);\n};\nfunction InflateState() {\n this.mode = 0;\n this.last = false;\n this.wrap = 0;\n this.havedict = false;\n this.flags = 0;\n this.dmax = 0;\n this.check = 0;\n this.total = 0;\n this.head = null;\n this.wbits = 0;\n this.wsize = 0;\n this.whave = 0;\n this.wnext = 0;\n this.window = null;\n this.hold = 0;\n this.bits = 0;\n this.length = 0;\n this.offset = 0;\n this.extra = 0;\n this.lencode = null;\n this.distcode = null;\n this.lenbits = 0;\n this.distbits = 0;\n this.ncode = 0;\n this.nlen = 0;\n this.ndist = 0;\n this.have = 0;\n this.next = null;\n this.lens = new Uint16Array(320);\n this.work = new Uint16Array(288);\n this.lendyn = null;\n this.distdyn = null;\n this.sane = 0;\n this.back = 0;\n this.was = 0;\n}\nvar inflateResetKeep = (strm) => {\n if (!strm || !strm.state) {\n return Z_STREAM_ERROR$1;\n }\n const state = strm.state;\n strm.total_in = strm.total_out = state.total = 0;\n strm.msg = \"\";\n if (state.wrap) {\n strm.adler = state.wrap & 1;\n }\n state.mode = HEAD;\n state.last = 0;\n state.havedict = 0;\n state.dmax = 32768;\n state.head = null;\n state.hold = 0;\n state.bits = 0;\n state.lencode = state.lendyn = new Int32Array(ENOUGH_LENS);\n state.distcode = state.distdyn = new Int32Array(ENOUGH_DISTS);\n state.sane = 1;\n state.back = -1;\n return Z_OK$1;\n};\nvar inflateReset = (strm) => {\n if (!strm || !strm.state) {\n return Z_STREAM_ERROR$1;\n }\n const state = strm.state;\n state.wsize = 0;\n state.whave = 0;\n state.wnext = 0;\n return inflateResetKeep(strm);\n};\nvar inflateReset2 = (strm, windowBits) => {\n let wrap;\n if (!strm || !strm.state) {\n return Z_STREAM_ERROR$1;\n }\n const state = strm.state;\n if (windowBits < 0) {\n wrap = 0;\n windowBits = -windowBits;\n } else {\n wrap = (windowBits >> 4) + 1;\n if (windowBits < 48) {\n windowBits &= 15;\n }\n }\n if (windowBits && (windowBits < 8 || windowBits > 15)) {\n return Z_STREAM_ERROR$1;\n }\n if (state.window !== null && state.wbits !== windowBits) {\n state.window = null;\n }\n state.wrap = wrap;\n state.wbits = windowBits;\n return inflateReset(strm);\n};\nvar inflateInit2 = (strm, windowBits) => {\n if (!strm) {\n return Z_STREAM_ERROR$1;\n }\n const state = new InflateState();\n strm.state = state;\n state.window = null;\n const ret = inflateReset2(strm, windowBits);\n if (ret !== Z_OK$1) {\n strm.state = null;\n }\n return ret;\n};\nvar inflateInit = (strm) => {\n return inflateInit2(strm, DEF_WBITS);\n};\nvar virgin = true;\nvar lenfix;\nvar distfix;\nvar fixedtables = (state) => {\n if (virgin) {\n lenfix = new Int32Array(512);\n distfix = new Int32Array(32);\n let sym = 0;\n while (sym < 144) {\n state.lens[sym++] = 8;\n }\n while (sym < 256) {\n state.lens[sym++] = 9;\n }\n while (sym < 280) {\n state.lens[sym++] = 7;\n }\n while (sym < 288) {\n state.lens[sym++] = 8;\n }\n inftrees(LENS, state.lens, 0, 288, lenfix, 0, state.work, { bits: 9 });\n sym = 0;\n while (sym < 32) {\n state.lens[sym++] = 5;\n }\n inftrees(DISTS, state.lens, 0, 32, distfix, 0, state.work, { bits: 5 });\n virgin = false;\n }\n state.lencode = lenfix;\n state.lenbits = 9;\n state.distcode = distfix;\n state.distbits = 5;\n};\nvar updatewindow = (strm, src, end, copy) => {\n let dist;\n const state = strm.state;\n if (state.window === null) {\n state.wsize = 1 << state.wbits;\n state.wnext = 0;\n state.whave = 0;\n state.window = new Uint8Array(state.wsize);\n }\n if (copy >= state.wsize) {\n state.window.set(src.subarray(end - state.wsize, end), 0);\n state.wnext = 0;\n state.whave = state.wsize;\n } else {\n dist = state.wsize - state.wnext;\n if (dist > copy) {\n dist = copy;\n }\n state.window.set(src.subarray(end - copy, end - copy + dist), state.wnext);\n copy -= dist;\n if (copy) {\n state.window.set(src.subarray(end - copy, end), 0);\n state.wnext = copy;\n state.whave = state.wsize;\n } else {\n state.wnext += dist;\n if (state.wnext === state.wsize) {\n state.wnext = 0;\n }\n if (state.whave < state.wsize) {\n state.whave += dist;\n }\n }\n }\n return 0;\n};\nvar inflate$2 = (strm, flush) => {\n let state;\n let input, output;\n let next;\n let put;\n let have, left;\n let hold;\n let bits;\n let _in, _out;\n let copy;\n let from;\n let from_source;\n let here = 0;\n let here_bits, here_op, here_val;\n let last_bits, last_op, last_val;\n let len;\n let ret;\n const hbuf = new Uint8Array(4);\n let opts;\n let n;\n const order = new Uint8Array([16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15]);\n if (!strm || !strm.state || !strm.output || !strm.input && strm.avail_in !== 0) {\n return Z_STREAM_ERROR$1;\n }\n state = strm.state;\n if (state.mode === TYPE) {\n state.mode = TYPEDO;\n }\n put = strm.next_out;\n output = strm.output;\n left = strm.avail_out;\n next = strm.next_in;\n input = strm.input;\n have = strm.avail_in;\n hold = state.hold;\n bits = state.bits;\n _in = have;\n _out = left;\n ret = Z_OK$1;\n inf_leave:\n for (; ; ) {\n switch (state.mode) {\n case HEAD:\n if (state.wrap === 0) {\n state.mode = TYPEDO;\n break;\n }\n while (bits < 16) {\n if (have === 0) {\n break inf_leave;\n }\n have--;\n hold += input[next++] << bits;\n bits += 8;\n }\n if (state.wrap & 2 && hold === 35615) {\n state.check = 0;\n hbuf[0] = hold & 255;\n hbuf[1] = hold >>> 8 & 255;\n state.check = crc32_1(state.check, hbuf, 2, 0);\n hold = 0;\n bits = 0;\n state.mode = FLAGS;\n break;\n }\n state.flags = 0;\n if (state.head) {\n state.head.done = false;\n }\n if (!(state.wrap & 1) || (((hold & 255) << 8) + (hold >> 8)) % 31) {\n strm.msg = \"incorrect header check\";\n state.mode = BAD;\n break;\n }\n if ((hold & 15) !== Z_DEFLATED) {\n strm.msg = \"unknown compression method\";\n state.mode = BAD;\n break;\n }\n hold >>>= 4;\n bits -= 4;\n len = (hold & 15) + 8;\n if (state.wbits === 0) {\n state.wbits = len;\n } else if (len > state.wbits) {\n strm.msg = \"invalid window size\";\n state.mode = BAD;\n break;\n }\n state.dmax = 1 << state.wbits;\n strm.adler = state.check = 1;\n state.mode = hold & 512 ? DICTID : TYPE;\n hold = 0;\n bits = 0;\n break;\n case FLAGS:\n while (bits < 16) {\n if (have === 0) {\n break inf_leave;\n }\n have--;\n hold += input[next++] << bits;\n bits += 8;\n }\n state.flags = hold;\n if ((state.flags & 255) !== Z_DEFLATED) {\n strm.msg = \"unknown compression method\";\n state.mode = BAD;\n break;\n }\n if (state.flags & 57344) {\n strm.msg = \"unknown header flags set\";\n state.mode = BAD;\n break;\n }\n if (state.head) {\n state.head.text = hold >> 8 & 1;\n }\n if (state.flags & 512) {\n hbuf[0] = hold & 255;\n hbuf[1] = hold >>> 8 & 255;\n state.check = crc32_1(state.check, hbuf, 2, 0);\n }\n hold = 0;\n bits = 0;\n state.mode = TIME;\n case TIME:\n while (bits < 32) {\n if (have === 0) {\n break inf_leave;\n }\n have--;\n hold += input[next++] << bits;\n bits += 8;\n }\n if (state.head) {\n state.head.time = hold;\n }\n if (state.flags & 512) {\n hbuf[0] = hold & 255;\n hbuf[1] = hold >>> 8 & 255;\n hbuf[2] = hold >>> 16 & 255;\n hbuf[3] = hold >>> 24 & 255;\n state.check = crc32_1(state.check, hbuf, 4, 0);\n }\n hold = 0;\n bits = 0;\n state.mode = OS;\n case OS:\n while (bits < 16) {\n if (have === 0) {\n break inf_leave;\n }\n have--;\n hold += input[next++] << bits;\n bits += 8;\n }\n if (state.head) {\n state.head.xflags = hold & 255;\n state.head.os = hold >> 8;\n }\n if (state.flags & 512) {\n hbuf[0] = hold & 255;\n hbuf[1] = hold >>> 8 & 255;\n state.check = crc32_1(state.check, hbuf, 2, 0);\n }\n hold = 0;\n bits = 0;\n state.mode = EXLEN;\n case EXLEN:\n if (state.flags & 1024) {\n while (bits < 16) {\n if (have === 0) {\n break inf_leave;\n }\n have--;\n hold += input[next++] << bits;\n bits += 8;\n }\n state.length = hold;\n if (state.head) {\n state.head.extra_len = hold;\n }\n if (state.flags & 512) {\n hbuf[0] = hold & 255;\n hbuf[1] = hold >>> 8 & 255;\n state.check = crc32_1(state.check, hbuf, 2, 0);\n }\n hold = 0;\n bits = 0;\n } else if (state.head) {\n state.head.extra = null;\n }\n state.mode = EXTRA;\n case EXTRA:\n if (state.flags & 1024) {\n copy = state.length;\n if (copy > have) {\n copy = have;\n }\n if (copy) {\n if (state.head) {\n len = state.head.extra_len - state.length;\n if (!state.head.extra) {\n state.head.extra = new Uint8Array(state.head.extra_len);\n }\n state.head.extra.set(input.subarray(next, next + copy), len);\n }\n if (state.flags & 512) {\n state.check = crc32_1(state.check, input, copy, next);\n }\n have -= copy;\n next += copy;\n state.length -= copy;\n }\n if (state.length) {\n break inf_leave;\n }\n }\n state.length = 0;\n state.mode = NAME;\n case NAME:\n if (state.flags & 2048) {\n if (have === 0) {\n break inf_leave;\n }\n copy = 0;\n do {\n len = input[next + copy++];\n if (state.head && len && state.length < 65536) {\n state.head.name += String.fromCharCode(len);\n }\n } while (len && copy < have);\n if (state.flags & 512) {\n state.check = crc32_1(state.check, input, copy, next);\n }\n have -= copy;\n next += copy;\n if (len) {\n break inf_leave;\n }\n } else if (state.head) {\n state.head.name = null;\n }\n state.length = 0;\n state.mode = COMMENT;\n case COMMENT:\n if (state.flags & 4096) {\n if (have === 0) {\n break inf_leave;\n }\n copy = 0;\n do {\n len = input[next + copy++];\n if (state.head && len && state.length < 65536) {\n state.head.comment += String.fromCharCode(len);\n }\n } while (len && copy < have);\n if (state.flags & 512) {\n state.check = crc32_1(state.check, input, copy, next);\n }\n have -= copy;\n next += copy;\n if (len) {\n break inf_leave;\n }\n } else if (state.head) {\n state.head.comment = null;\n }\n state.mode = HCRC;\n case HCRC:\n if (state.flags & 512) {\n while (bits < 16) {\n if (have === 0) {\n break inf_leave;\n }\n have--;\n hold += input[next++] << bits;\n bits += 8;\n }\n if (hold !== (state.check & 65535)) {\n strm.msg = \"header crc mismatch\";\n state.mode = BAD;\n break;\n }\n hold = 0;\n bits = 0;\n }\n if (state.head) {\n state.head.hcrc = state.flags >> 9 & 1;\n state.head.done = true;\n }\n strm.adler = state.check = 0;\n state.mode = TYPE;\n break;\n case DICTID:\n while (bits < 32) {\n if (have === 0) {\n break inf_leave;\n }\n have--;\n hold += input[next++] << bits;\n bits += 8;\n }\n strm.adler = state.check = zswap32(hold);\n hold = 0;\n bits = 0;\n state.mode = DICT;\n case DICT:\n if (state.havedict === 0) {\n strm.next_out = put;\n strm.avail_out = left;\n strm.next_in = next;\n strm.avail_in = have;\n state.hold = hold;\n state.bits = bits;\n return Z_NEED_DICT$1;\n }\n strm.adler = state.check = 1;\n state.mode = TYPE;\n case TYPE:\n if (flush === Z_BLOCK || flush === Z_TREES) {\n break inf_leave;\n }\n case TYPEDO:\n if (state.last) {\n hold >>>= bits & 7;\n bits -= bits & 7;\n state.mode = CHECK;\n break;\n }\n while (bits < 3) {\n if (have === 0) {\n break inf_leave;\n }\n have--;\n hold += input[next++] << bits;\n bits += 8;\n }\n state.last = hold & 1;\n hold >>>= 1;\n bits -= 1;\n switch (hold & 3) {\n case 0:\n state.mode = STORED;\n break;\n case 1:\n fixedtables(state);\n state.mode = LEN_;\n if (flush === Z_TREES) {\n hold >>>= 2;\n bits -= 2;\n break inf_leave;\n }\n break;\n case 2:\n state.mode = TABLE;\n break;\n case 3:\n strm.msg = \"invalid block type\";\n state.mode = BAD;\n }\n hold >>>= 2;\n bits -= 2;\n break;\n case STORED:\n hold >>>= bits & 7;\n bits -= bits & 7;\n while (bits < 32) {\n if (have === 0) {\n break inf_leave;\n }\n have--;\n hold += input[next++] << bits;\n bits += 8;\n }\n if ((hold & 65535) !== (hold >>> 16 ^ 65535)) {\n strm.msg = \"invalid stored block lengths\";\n state.mode = BAD;\n break;\n }\n state.length = hold & 65535;\n hold = 0;\n bits = 0;\n state.mode = COPY_;\n if (flush === Z_TREES) {\n break inf_leave;\n }\n case COPY_:\n state.mode = COPY;\n case COPY:\n copy = state.length;\n if (copy) {\n if (copy > have) {\n copy = have;\n }\n if (copy > left) {\n copy = left;\n }\n if (copy === 0) {\n break inf_leave;\n }\n output.set(input.subarray(next, next + copy), put);\n have -= copy;\n next += copy;\n left -= copy;\n put += copy;\n state.length -= copy;\n break;\n }\n state.mode = TYPE;\n break;\n case TABLE:\n while (bits < 14) {\n if (have === 0) {\n break inf_leave;\n }\n have--;\n hold += input[next++] << bits;\n bits += 8;\n }\n state.nlen = (hold & 31) + 257;\n hold >>>= 5;\n bits -= 5;\n state.ndist = (hold & 31) + 1;\n hold >>>= 5;\n bits -= 5;\n state.ncode = (hold & 15) + 4;\n hold >>>= 4;\n bits -= 4;\n if (state.nlen > 286 || state.ndist > 30) {\n strm.msg = \"too many length or distance symbols\";\n state.mode = BAD;\n break;\n }\n state.have = 0;\n state.mode = LENLENS;\n case LENLENS:\n while (state.have < state.ncode) {\n while (bits < 3) {\n if (have === 0) {\n break inf_leave;\n }\n have--;\n hold += input[next++] << bits;\n bits += 8;\n }\n state.lens[order[state.have++]] = hold & 7;\n hold >>>= 3;\n bits -= 3;\n }\n while (state.have < 19) {\n state.lens[order[state.have++]] = 0;\n }\n state.lencode = state.lendyn;\n state.lenbits = 7;\n opts = { bits: state.lenbits };\n ret = inftrees(CODES, state.lens, 0, 19, state.lencode, 0, state.work, opts);\n state.lenbits = opts.bits;\n if (ret) {\n strm.msg = \"invalid code lengths set\";\n state.mode = BAD;\n break;\n }\n state.have = 0;\n state.mode = CODELENS;\n case CODELENS:\n while (state.have < state.nlen + state.ndist) {\n for (; ; ) {\n here = state.lencode[hold & (1 << state.lenbits) - 1];\n here_bits = here >>> 24;\n here_op = here >>> 16 & 255;\n here_val = here & 65535;\n if (here_bits <= bits) {\n break;\n }\n if (have === 0) {\n break inf_leave;\n }\n have--;\n hold += input[next++] << bits;\n bits += 8;\n }\n if (here_val < 16) {\n hold >>>= here_bits;\n bits -= here_bits;\n state.lens[state.have++] = here_val;\n } else {\n if (here_val === 16) {\n n = here_bits + 2;\n while (bits < n) {\n if (have === 0) {\n break inf_leave;\n }\n have--;\n hold += input[next++] << bits;\n bits += 8;\n }\n hold >>>= here_bits;\n bits -= here_bits;\n if (state.have === 0) {\n strm.msg = \"invalid bit length repeat\";\n state.mode = BAD;\n break;\n }\n len = state.lens[state.have - 1];\n copy = 3 + (hold & 3);\n hold >>>= 2;\n bits -= 2;\n } else if (here_val === 17) {\n n = here_bits + 3;\n while (bits < n) {\n if (have === 0) {\n break inf_leave;\n }\n have--;\n hold += input[next++] << bits;\n bits += 8;\n }\n hold >>>= here_bits;\n bits -= here_bits;\n len = 0;\n copy = 3 + (hold & 7);\n hold >>>= 3;\n bits -= 3;\n } else {\n n = here_bits + 7;\n while (bits < n) {\n if (have === 0) {\n break inf_leave;\n }\n have--;\n hold += input[next++] << bits;\n bits += 8;\n }\n hold >>>= here_bits;\n bits -= here_bits;\n len = 0;\n copy = 11 + (hold & 127);\n hold >>>= 7;\n bits -= 7;\n }\n if (state.have + copy > state.nlen + state.ndist) {\n strm.msg = \"invalid bit length repeat\";\n state.mode = BAD;\n break;\n }\n while (copy--) {\n state.lens[state.have++] = len;\n }\n }\n }\n if (state.mode === BAD) {\n break;\n }\n if (state.lens[256] === 0) {\n strm.msg = \"invalid code -- missing end-of-block\";\n state.mode = BAD;\n break;\n }\n state.lenbits = 9;\n opts = { bits: state.lenbits };\n ret = inftrees(LENS, state.lens, 0, state.nlen, state.lencode, 0, state.work, opts);\n state.lenbits = opts.bits;\n if (ret) {\n strm.msg = \"invalid literal/lengths set\";\n state.mode = BAD;\n break;\n }\n state.distbits = 6;\n state.distcode = state.distdyn;\n opts = { bits: state.distbits };\n ret = inftrees(DISTS, state.lens, state.nlen, state.ndist, state.distcode, 0, state.work, opts);\n state.distbits = opts.bits;\n if (ret) {\n strm.msg = \"invalid distances set\";\n state.mode = BAD;\n break;\n }\n state.mode = LEN_;\n if (flush === Z_TREES) {\n break inf_leave;\n }\n case LEN_:\n state.mode = LEN;\n case LEN:\n if (have >= 6 && left >= 258) {\n strm.next_out = put;\n strm.avail_out = left;\n strm.next_in = next;\n strm.avail_in = have;\n state.hold = hold;\n state.bits = bits;\n inffast(strm, _out);\n put = strm.next_out;\n output = strm.output;\n left = strm.avail_out;\n next = strm.next_in;\n input = strm.input;\n have = strm.avail_in;\n hold = state.hold;\n bits = state.bits;\n if (state.mode === TYPE) {\n state.back = -1;\n }\n break;\n }\n state.back = 0;\n for (; ; ) {\n here = state.lencode[hold & (1 << state.lenbits) - 1];\n here_bits = here >>> 24;\n here_op = here >>> 16 & 255;\n here_val = here & 65535;\n if (here_bits <= bits) {\n break;\n }\n if (have === 0) {\n break inf_leave;\n }\n have--;\n hold += input[next++] << bits;\n bits += 8;\n }\n if (here_op && (here_op & 240) === 0) {\n last_bits = here_bits;\n last_op = here_op;\n last_val = here_val;\n for (; ; ) {\n here = state.lencode[last_val + ((hold & (1 << last_bits + last_op) - 1) >> last_bits)];\n here_bits = here >>> 24;\n here_op = here >>> 16 & 255;\n here_val = here & 65535;\n if (last_bits + here_bits <= bits) {\n break;\n }\n if (have === 0) {\n break inf_leave;\n }\n have--;\n hold += input[next++] << bits;\n bits += 8;\n }\n hold >>>= last_bits;\n bits -= last_bits;\n state.back += last_bits;\n }\n hold >>>= here_bits;\n bits -= here_bits;\n state.back += here_bits;\n state.length = here_val;\n if (here_op === 0) {\n state.mode = LIT;\n break;\n }\n if (here_op & 32) {\n state.back = -1;\n state.mode = TYPE;\n break;\n }\n if (here_op & 64) {\n strm.msg = \"invalid literal/length code\";\n state.mode = BAD;\n break;\n }\n state.extra = here_op & 15;\n state.mode = LENEXT;\n case LENEXT:\n if (state.extra) {\n n = state.extra;\n while (bits < n) {\n if (have === 0) {\n break inf_leave;\n }\n have--;\n hold += input[next++] << bits;\n bits += 8;\n }\n state.length += hold & (1 << state.extra) - 1;\n hold >>>= state.extra;\n bits -= state.extra;\n state.back += state.extra;\n }\n state.was = state.length;\n state.mode = DIST;\n case DIST:\n for (; ; ) {\n here = state.distcode[hold & (1 << state.distbits) - 1];\n here_bits = here >>> 24;\n here_op = here >>> 16 & 255;\n here_val = here & 65535;\n if (here_bits <= bits) {\n break;\n }\n if (have === 0) {\n break inf_leave;\n }\n have--;\n hold += input[next++] << bits;\n bits += 8;\n }\n if ((here_op & 240) === 0) {\n last_bits = here_bits;\n last_op = here_op;\n last_val = here_val;\n for (; ; ) {\n here = state.distcode[last_val + ((hold & (1 << last_bits + last_op) - 1) >> last_bits)];\n here_bits = here >>> 24;\n here_op = here >>> 16 & 255;\n here_val = here & 65535;\n if (last_bits + here_bits <= bits) {\n break;\n }\n if (have === 0) {\n break inf_leave;\n }\n have--;\n hold += input[next++] << bits;\n bits += 8;\n }\n hold >>>= last_bits;\n bits -= last_bits;\n state.back += last_bits;\n }\n hold >>>= here_bits;\n bits -= here_bits;\n state.back += here_bits;\n if (here_op & 64) {\n strm.msg = \"invalid distance code\";\n state.mode = BAD;\n break;\n }\n state.offset = here_val;\n state.extra = here_op & 15;\n state.mode = DISTEXT;\n case DISTEXT:\n if (state.extra) {\n n = state.extra;\n while (bits < n) {\n if (have === 0) {\n break inf_leave;\n }\n have--;\n hold += input[next++] << bits;\n bits += 8;\n }\n state.offset += hold & (1 << state.extra) - 1;\n hold >>>= state.extra;\n bits -= state.extra;\n state.back += state.extra;\n }\n if (state.offset > state.dmax) {\n strm.msg = \"invalid distance too far back\";\n state.mode = BAD;\n break;\n }\n state.mode = MATCH;\n case MATCH:\n if (left === 0) {\n break inf_leave;\n }\n copy = _out - left;\n if (state.offset > copy) {\n copy = state.offset - copy;\n if (copy > state.whave) {\n if (state.sane) {\n strm.msg = \"invalid distance too far back\";\n state.mode = BAD;\n break;\n }\n }\n if (copy > state.wnext) {\n copy -= state.wnext;\n from = state.wsize - copy;\n } else {\n from = state.wnext - copy;\n }\n if (copy > state.length) {\n copy = state.length;\n }\n from_source = state.window;\n } else {\n from_source = output;\n from = put - state.offset;\n copy = state.length;\n }\n if (copy > left) {\n copy = left;\n }\n left -= copy;\n state.length -= copy;\n do {\n output[put++] = from_source[from++];\n } while (--copy);\n if (state.length === 0) {\n state.mode = LEN;\n }\n break;\n case LIT:\n if (left === 0) {\n break inf_leave;\n }\n output[put++] = state.length;\n left--;\n state.mode = LEN;\n break;\n case CHECK:\n if (state.wrap) {\n while (bits < 32) {\n if (have === 0) {\n break inf_leave;\n }\n have--;\n hold |= input[next++] << bits;\n bits += 8;\n }\n _out -= left;\n strm.total_out += _out;\n state.total += _out;\n if (_out) {\n strm.adler = state.check = state.flags ? crc32_1(state.check, output, _out, put - _out) : adler32_1(state.check, output, _out, put - _out);\n }\n _out = left;\n if ((state.flags ? hold : zswap32(hold)) !== state.check) {\n strm.msg = \"incorrect data check\";\n state.mode = BAD;\n break;\n }\n hold = 0;\n bits = 0;\n }\n state.mode = LENGTH;\n case LENGTH:\n if (state.wrap && state.flags) {\n while (bits < 32) {\n if (have === 0) {\n break inf_leave;\n }\n have--;\n hold += input[next++] << bits;\n bits += 8;\n }\n if (hold !== (state.total & 4294967295)) {\n strm.msg = \"incorrect length check\";\n state.mode = BAD;\n break;\n }\n hold = 0;\n bits = 0;\n }\n state.mode = DONE;\n case DONE:\n ret = Z_STREAM_END$1;\n break inf_leave;\n case BAD:\n ret = Z_DATA_ERROR$1;\n break inf_leave;\n case MEM:\n return Z_MEM_ERROR$1;\n case SYNC:\n default:\n return Z_STREAM_ERROR$1;\n }\n }\n strm.next_out = put;\n strm.avail_out = left;\n strm.next_in = next;\n strm.avail_in = have;\n state.hold = hold;\n state.bits = bits;\n if (state.wsize || _out !== strm.avail_out && state.mode < BAD && (state.mode < CHECK || flush !== Z_FINISH$1)) {\n if (updatewindow(strm, strm.output, strm.next_out, _out - strm.avail_out))\n ;\n }\n _in -= strm.avail_in;\n _out -= strm.avail_out;\n strm.total_in += _in;\n strm.total_out += _out;\n state.total += _out;\n if (state.wrap && _out) {\n strm.adler = state.check = state.flags ? crc32_1(state.check, output, _out, strm.next_out - _out) : adler32_1(state.check, output, _out, strm.next_out - _out);\n }\n strm.data_type = state.bits + (state.last ? 64 : 0) + (state.mode === TYPE ? 128 : 0) + (state.mode === LEN_ || state.mode === COPY_ ? 256 : 0);\n if ((_in === 0 && _out === 0 || flush === Z_FINISH$1) && ret === Z_OK$1) {\n ret = Z_BUF_ERROR;\n }\n return ret;\n};\nvar inflateEnd = (strm) => {\n if (!strm || !strm.state) {\n return Z_STREAM_ERROR$1;\n }\n let state = strm.state;\n if (state.window) {\n state.window = null;\n }\n strm.state = null;\n return Z_OK$1;\n};\nvar inflateGetHeader = (strm, head) => {\n if (!strm || !strm.state) {\n return Z_STREAM_ERROR$1;\n }\n const state = strm.state;\n if ((state.wrap & 2) === 0) {\n return Z_STREAM_ERROR$1;\n }\n state.head = head;\n head.done = false;\n return Z_OK$1;\n};\nvar inflateSetDictionary = (strm, dictionary) => {\n const dictLength = dictionary.length;\n let state;\n let dictid;\n let ret;\n if (!strm || !strm.state) {\n return Z_STREAM_ERROR$1;\n }\n state = strm.state;\n if (state.wrap !== 0 && state.mode !== DICT) {\n return Z_STREAM_ERROR$1;\n }\n if (state.mode === DICT) {\n dictid = 1;\n dictid = adler32_1(dictid, dictionary, dictLength, 0);\n if (dictid !== state.check) {\n return Z_DATA_ERROR$1;\n }\n }\n ret = updatewindow(strm, dictionary, dictLength, dictLength);\n if (ret) {\n state.mode = MEM;\n return Z_MEM_ERROR$1;\n }\n state.havedict = 1;\n return Z_OK$1;\n};\nvar inflateReset_1 = inflateReset;\nvar inflateReset2_1 = inflateReset2;\nvar inflateResetKeep_1 = inflateResetKeep;\nvar inflateInit_1 = inflateInit;\nvar inflateInit2_1 = inflateInit2;\nvar inflate_2$1 = inflate$2;\nvar inflateEnd_1 = inflateEnd;\nvar inflateGetHeader_1 = inflateGetHeader;\nvar inflateSetDictionary_1 = inflateSetDictionary;\nvar inflateInfo = \"pako inflate (from Nodeca project)\";\nvar inflate_1$2 = {\n inflateReset: inflateReset_1,\n inflateReset2: inflateReset2_1,\n inflateResetKeep: inflateResetKeep_1,\n inflateInit: inflateInit_1,\n inflateInit2: inflateInit2_1,\n inflate: inflate_2$1,\n inflateEnd: inflateEnd_1,\n inflateGetHeader: inflateGetHeader_1,\n inflateSetDictionary: inflateSetDictionary_1,\n inflateInfo\n};\nfunction GZheader() {\n this.text = 0;\n this.time = 0;\n this.xflags = 0;\n this.os = 0;\n this.extra = null;\n this.extra_len = 0;\n this.name = \"\";\n this.comment = \"\";\n this.hcrc = 0;\n this.done = false;\n}\nvar gzheader = GZheader;\nvar toString = Object.prototype.toString;\nvar {\n Z_NO_FLUSH,\n Z_FINISH,\n Z_OK,\n Z_STREAM_END,\n Z_NEED_DICT,\n Z_STREAM_ERROR,\n Z_DATA_ERROR,\n Z_MEM_ERROR\n} = constants$2;\nfunction Inflate$1(options) {\n this.options = common.assign({\n chunkSize: 1024 * 64,\n windowBits: 15,\n to: \"\"\n }, options || {});\n const opt = this.options;\n if (opt.raw && opt.windowBits >= 0 && opt.windowBits < 16) {\n opt.windowBits = -opt.windowBits;\n if (opt.windowBits === 0) {\n opt.windowBits = -15;\n }\n }\n if (opt.windowBits >= 0 && opt.windowBits < 16 && !(options && options.windowBits)) {\n opt.windowBits += 32;\n }\n if (opt.windowBits > 15 && opt.windowBits < 48) {\n if ((opt.windowBits & 15) === 0) {\n opt.windowBits |= 15;\n }\n }\n this.err = 0;\n this.msg = \"\";\n this.ended = false;\n this.chunks = [];\n this.strm = new zstream();\n this.strm.avail_out = 0;\n let status = inflate_1$2.inflateInit2(this.strm, opt.windowBits);\n if (status !== Z_OK) {\n throw new Error(messages[status]);\n }\n this.header = new gzheader();\n inflate_1$2.inflateGetHeader(this.strm, this.header);\n if (opt.dictionary) {\n if (typeof opt.dictionary === \"string\") {\n opt.dictionary = strings.string2buf(opt.dictionary);\n } else if (toString.call(opt.dictionary) === \"[object ArrayBuffer]\") {\n opt.dictionary = new Uint8Array(opt.dictionary);\n }\n if (opt.raw) {\n status = inflate_1$2.inflateSetDictionary(this.strm, opt.dictionary);\n if (status !== Z_OK) {\n throw new Error(messages[status]);\n }\n }\n }\n}\nInflate$1.prototype.push = function(data, flush_mode) {\n const strm = this.strm;\n const chunkSize = this.options.chunkSize;\n const dictionary = this.options.dictionary;\n let status, _flush_mode, last_avail_out;\n if (this.ended)\n return false;\n if (flush_mode === ~~flush_mode)\n _flush_mode = flush_mode;\n else\n _flush_mode = flush_mode === true ? Z_FINISH : Z_NO_FLUSH;\n if (toString.call(data) === \"[object ArrayBuffer]\") {\n strm.input = new Uint8Array(data);\n } else {\n strm.input = data;\n }\n strm.next_in = 0;\n strm.avail_in = strm.input.length;\n for (; ; ) {\n if (strm.avail_out === 0) {\n strm.output = new Uint8Array(chunkSize);\n strm.next_out = 0;\n strm.avail_out = chunkSize;\n }\n status = inflate_1$2.inflate(strm, _flush_mode);\n if (status === Z_NEED_DICT && dictionary) {\n status = inflate_1$2.inflateSetDictionary(strm, dictionary);\n if (status === Z_OK) {\n status = inflate_1$2.inflate(strm, _flush_mode);\n } else if (status === Z_DATA_ERROR) {\n status = Z_NEED_DICT;\n }\n }\n while (strm.avail_in > 0 && status === Z_STREAM_END && strm.state.wrap > 0 && data[strm.next_in] !== 0) {\n inflate_1$2.inflateReset(strm);\n status = inflate_1$2.inflate(strm, _flush_mode);\n }\n switch (status) {\n case Z_STREAM_ERROR:\n case Z_DATA_ERROR:\n case Z_NEED_DICT:\n case Z_MEM_ERROR:\n this.onEnd(status);\n this.ended = true;\n return false;\n }\n last_avail_out = strm.avail_out;\n if (strm.next_out) {\n if (strm.avail_out === 0 || status === Z_STREAM_END) {\n if (this.options.to === \"string\") {\n let next_out_utf8 = strings.utf8border(strm.output, strm.next_out);\n let tail = strm.next_out - next_out_utf8;\n let utf8str = strings.buf2string(strm.output, next_out_utf8);\n strm.next_out = tail;\n strm.avail_out = chunkSize - tail;\n if (tail)\n strm.output.set(strm.output.subarray(next_out_utf8, next_out_utf8 + tail), 0);\n this.onData(utf8str);\n } else {\n this.onData(strm.output.length === strm.next_out ? strm.output : strm.output.subarray(0, strm.next_out));\n }\n }\n }\n if (status === Z_OK && last_avail_out === 0)\n continue;\n if (status === Z_STREAM_END) {\n status = inflate_1$2.inflateEnd(this.strm);\n this.onEnd(status);\n this.ended = true;\n return true;\n }\n if (strm.avail_in === 0)\n break;\n }\n return true;\n};\nInflate$1.prototype.onData = function(chunk) {\n this.chunks.push(chunk);\n};\nInflate$1.prototype.onEnd = function(status) {\n if (status === Z_OK) {\n if (this.options.to === \"string\") {\n this.result = this.chunks.join(\"\");\n } else {\n this.result = common.flattenChunks(this.chunks);\n }\n }\n this.chunks = [];\n this.err = status;\n this.msg = this.strm.msg;\n};\nfunction inflate$1(input, options) {\n const inflator = new Inflate$1(options);\n inflator.push(input);\n if (inflator.err)\n throw inflator.msg || messages[inflator.err];\n return inflator.result;\n}\nfunction inflateRaw$1(input, options) {\n options = options || {};\n options.raw = true;\n return inflate$1(input, options);\n}\nvar Inflate_1$1 = Inflate$1;\nvar inflate_2 = inflate$1;\nvar inflateRaw_1$1 = inflateRaw$1;\nvar ungzip$1 = inflate$1;\nvar constants = constants$2;\nvar inflate_1$1 = {\n Inflate: Inflate_1$1,\n inflate: inflate_2,\n inflateRaw: inflateRaw_1$1,\n ungzip: ungzip$1,\n constants\n};\nvar { Inflate, inflate, inflateRaw, ungzip } = inflate_1$1;\nvar inflate_1 = inflate;\nvar ungzip_1 = ungzip;\n\n// esm/filters.js\nvar zlib_decompress = function(buf, itemsize) {\n let input_array = new Uint8Array(buf);\n return inflate_1(input_array).buffer;\n};\nvar unshuffle = function(buf, itemsize) {\n let buffer_size = buf.byteLength;\n let unshuffled_view = new Uint8Array(buffer_size);\n let step = Math.floor(buffer_size / itemsize);\n let shuffled_view = new DataView(buf);\n for (var j = 0; j < itemsize; j++) {\n for (var i = 0; i < step; i++) {\n unshuffled_view[j + i * itemsize] = shuffled_view.getUint8(j * step + i);\n }\n }\n return unshuffled_view.buffer;\n};\nvar fletch32 = function(buf, itemsize) {\n _verify_fletcher32(buf);\n return buf.slice(0, -4);\n};\nfunction _verify_fletcher32(chunk_buffer) {\n var odd_chunk_buffer = chunk_buffer.byteLength % 2 != 0;\n var data_length = chunk_buffer.byteLength - 4;\n var view = new DataView(chunk_buffer);\n var sum1 = 0;\n var sum2 = 0;\n for (var offset = 0; offset < data_length - 1; offset += 2) {\n let datum = view.getUint16(offset, true);\n sum1 = (sum1 + datum) % 65535;\n sum2 = (sum2 + sum1) % 65535;\n }\n if (odd_chunk_buffer) {\n let datum = view.getUint8(data_length - 1);\n sum1 = (sum1 + datum) % 65535;\n sum2 = (sum2 + sum1) % 65535;\n }\n var [ref_sum1, ref_sum2] = struct.unpack_from(\">HH\", chunk_buffer, data_length);\n ref_sum1 = ref_sum1 % 65535;\n ref_sum2 = ref_sum2 % 65535;\n if (sum1 != ref_sum1 || sum2 != ref_sum2) {\n throw 'ValueError(\"fletcher32 checksum invalid\")';\n }\n return true;\n}\nvar GZIP_DEFLATE_FILTER = 1;\nvar SHUFFLE_FILTER = 2;\nvar FLETCH32_FILTER = 3;\nvar Filters = /* @__PURE__ */ new Map([\n [GZIP_DEFLATE_FILTER, zlib_decompress],\n [SHUFFLE_FILTER, unshuffle],\n [FLETCH32_FILTER, fletch32]\n]);\n\n// esm/btree.js\nvar AbstractBTree = class {\n constructor(fh, offset) {\n this.fh = fh;\n this.offset = offset;\n this.depth = null;\n }\n async init() {\n this.all_nodes = /* @__PURE__ */ new Map();\n await this._read_root_node();\n await this._read_children();\n }\n async _read_children() {\n let node_level = this.depth;\n while (node_level > 0) {\n for (var parent_node of this.all_nodes.get(node_level)) {\n for (var child_addr of parent_node.get(\"addresses\")) {\n this._add_node(await this._read_node(child_addr, node_level - 1));\n }\n }\n node_level--;\n }\n }\n async _read_root_node() {\n let root_node = await this._read_node(this.offset, null);\n this._add_node(root_node);\n this.depth = root_node.get(\"node_level\");\n }\n _add_node(node) {\n let node_level = node.get(\"node_level\");\n if (this.all_nodes.has(node_level)) {\n this.all_nodes.get(node_level).push(node);\n } else {\n this.all_nodes.set(node_level, [node]);\n }\n }\n async _read_node(offset, node_level) {\n let node = await this._read_node_header(offset, node_level);\n node.set(\"keys\", []);\n node.set(\"addresses\", []);\n return node;\n }\n async _read_node_header(offset) {\n throw \"NotImplementedError: must define _read_node_header in implementation class\";\n }\n};\nvar BTreeV1 = class extends AbstractBTree {\n constructor() {\n super(...arguments);\n __publicField(this, \"B_LINK_NODE\", /* @__PURE__ */ new Map([\n [\"signature\", \"4s\"],\n [\"node_type\", \"B\"],\n [\"node_level\", \"B\"],\n [\"entries_used\", \"H\"],\n [\"left_sibling\", \"Q\"],\n [\"right_sibling\", \"Q\"]\n ]));\n }\n async _read_node_header(offset, node_level) {\n let node = await _unpack_struct_from_async(this.B_LINK_NODE, this.fh, offset);\n if (node_level != null) {\n if (node.get(\"node_level\") != node_level) {\n throw \"node level does not match\";\n }\n }\n return node;\n }\n};\nvar BTreeV1Groups = class extends BTreeV1 {\n constructor(fh, offset) {\n super(fh, offset);\n __publicField(this, \"NODE_TYPE\", 0);\n this.ready = this.init();\n }\n async _read_node(offset, node_level) {\n let node = await this._read_node_header(offset, node_level);\n offset += _structure_size(this.B_LINK_NODE);\n let keys = [];\n let addresses = [];\n let entries_used = node.get(\"entries_used\");\n for (var i = 0; i < entries_used; i++) {\n let key = (await struct.unpack_from_async(\"= 0; d--) {\n if (cpos[d] >= chunk_shape[d]) {\n cpos[d] = 0;\n apos[d] = chunk_offset[d];\n if (d > 0) {\n cpos[d - 1] += 1;\n apos[d - 1] += 1;\n }\n } else {\n break;\n }\n }\n let inbounds = apos.slice(0, -1).every(function(p, d2) {\n return p < data_shape[d2];\n });\n if (inbounds) {\n let cb_offset = ci * item_size;\n let datum = cview[item_getter](cb_offset, !item_big_endian, item_size);\n let ai = apos.slice(0, -1).reduce(function(prev, curr, index) {\n return curr * data_strides[index] + prev;\n }, 0);\n data[ai] = datum;\n }\n cpos[dims - 1] += 1;\n apos[dims - 1] += 1;\n }\n }\n }\n return data;\n }\n _filter_chunk(chunk_buffer, filter_mask, filter_pipeline, itemsize) {\n let num_filters = filter_pipeline.length;\n let buf = chunk_buffer.slice();\n for (var filter_index = num_filters - 1; filter_index >= 0; filter_index--) {\n if (filter_mask & 1 << filter_index) {\n continue;\n }\n let pipeline_entry = filter_pipeline[filter_index];\n let filter_id = pipeline_entry.get(\"filter_id\");\n let client_data = pipeline_entry.get(\"client_data\");\n if (Filters.has(filter_id)) {\n buf = Filters.get(filter_id)(buf, itemsize, client_data);\n } else {\n throw 'NotImplementedError(\"Filter with id:' + filter_id.toFixed() + ' not supported\")';\n }\n }\n return buf;\n }\n};\nvar BTreeV2 = class extends AbstractBTree {\n constructor(fh, offset) {\n super(fh, offset);\n __publicField(this, \"B_TREE_HEADER\", /* @__PURE__ */ new Map([\n [\"signature\", \"4s\"],\n [\"version\", \"B\"],\n [\"node_type\", \"B\"],\n [\"node_size\", \"I\"],\n [\"record_size\", \"H\"],\n [\"depth\", \"H\"],\n [\"split_percent\", \"B\"],\n [\"merge_percent\", \"B\"],\n [\"root_address\", \"Q\"],\n [\"root_nrecords\", \"H\"],\n [\"total_nrecords\", \"Q\"]\n ]));\n __publicField(this, \"B_LINK_NODE\", /* @__PURE__ */ new Map([\n [\"signature\", \"4s\"],\n [\"version\", \"B\"],\n [\"node_type\", \"B\"]\n ]));\n this.ready = this.init();\n }\n async _read_root_node() {\n let h = await this._read_tree_header(this.offset);\n this.address_formats = this._calculate_address_formats(h);\n this.header = h;\n this.depth = h.get(\"depth\");\n let address = [h.get(\"root_address\"), h.get(\"root_nrecords\"), h.get(\"total_nrecords\")];\n let root_node = await this._read_node(address, this.depth);\n this._add_node(root_node);\n }\n async _read_tree_header(offset) {\n let header = await _unpack_struct_from_async(this.B_TREE_HEADER, this.fh, this.offset);\n return header;\n }\n _calculate_address_formats(header) {\n let node_size = header.get(\"node_size\");\n let record_size = header.get(\"record_size\");\n let nrecords_max = 0;\n let ntotalrecords_max = 0;\n let address_formats = /* @__PURE__ */ new Map();\n let max_depth = header.get(\"depth\");\n for (var node_level = 0; node_level <= max_depth; node_level++) {\n let offset_fmt = \"\";\n let num1_fmt = \"\";\n let num2_fmt = \"\";\n let offset_size, num1_size, num2_size;\n if (node_level == 0) {\n offset_size = 0;\n num1_size = 0;\n num2_size = 0;\n } else if (node_level == 1) {\n offset_size = 8;\n offset_fmt = \" 0) {\n ntotalrecords_max *= nrecords_max;\n } else {\n ntotalrecords_max = nrecords_max;\n }\n }\n }\n return address_formats;\n }\n _nrecords_max(node_size, record_size, addr_size) {\n return Math.floor((node_size - 10 - addr_size) / (record_size + addr_size));\n }\n _required_bytes(integer) {\n return Math.ceil(bitSize(integer) / 8);\n }\n _int_format(bytelength) {\n return [\" 0) {\n num2 = (await struct.unpack_from_async(num2_fmt, this.fh, offset))[0];\n offset += num2_size;\n }\n addresses.push([address_offset, num1, num2]);\n }\n }\n node.set(\"keys\", keys);\n node.set(\"addresses\", addresses);\n return node;\n }\n async _read_node_header(offset, node_level) {\n let node = await _unpack_struct_from_async(this.B_LINK_NODE, this.fh, offset);\n node.set(\"node_level\", node_level);\n return node;\n }\n *iter_records() {\n for (let nodelist of this.all_nodes.values()) {\n for (let node of nodelist) {\n for (let key of node.get(\"keys\")) {\n yield key;\n }\n }\n }\n }\n _parse_record(record) {\n throw \"NotImplementedError\";\n }\n};\nvar BTreeV2GroupNames = class extends BTreeV2 {\n constructor() {\n super(...arguments);\n __publicField(this, \"NODE_TYPE\", 5);\n }\n async _parse_record(buf, offset, size) {\n let namehash = (await struct.unpack_from_async(\" 0) {\n throw \"Filter info size not supported on FractalHeap\";\n }\n if (header.get(\"btree_address_huge_objects\") == UNDEFINED_ADDRESS) {\n header.set(\"btree_address_huge_objects\", null);\n } else {\n throw \"Huge objects not implemented in FractalHeap\";\n }\n if (header.get(\"root_block_address\") == UNDEFINED_ADDRESS) {\n header.set(\"root_block_address\", null);\n }\n let nbits = header.get(\"log2_maximum_heap_size\");\n let block_offset_size = this._min_size_nbits(nbits);\n let h = /* @__PURE__ */ new Map([\n [\"signature\", \"4s\"],\n [\"version\", \"B\"],\n [\"heap_header_adddress\", \"Q\"],\n [\"block_offset\", `${block_offset_size}B`]\n ]);\n this.indirect_block_header = new Map(h);\n this.indirect_block_header_size = _structure_size(h);\n if ((header.get(\"flags\") & 2) == 2) {\n h.set(\"checksum\", \"I\");\n }\n this.direct_block_header = h;\n this.direct_block_header_size = _structure_size(h);\n let maximum_dblock_size = header.get(\"maximum_direct_block_size\");\n this._managed_object_offset_size = this._min_size_nbits(nbits);\n let value = Math.min(maximum_dblock_size, header.get(\"max_managed_object_size\"));\n this._managed_object_length_size = this._min_size_integer(value);\n let start_block_size = header.get(\"starting_block_size\");\n let table_width = header.get(\"table_width\");\n if (!(start_block_size > 0)) {\n throw \"Starting block size == 0 not implemented\";\n }\n let log2_maximum_dblock_size = Number(Math.floor(Math.log2(maximum_dblock_size)));\n assert(1n << BigInt(log2_maximum_dblock_size) == maximum_dblock_size);\n let log2_start_block_size = Number(Math.floor(Math.log2(start_block_size)));\n assert(1n << BigInt(log2_start_block_size) == start_block_size);\n this._max_direct_nrows = log2_maximum_dblock_size - log2_start_block_size + 2;\n let log2_table_width = Math.floor(Math.log2(table_width));\n assert(1 << log2_table_width == table_width);\n this._indirect_nrows_sub = log2_table_width + log2_start_block_size - 1;\n this.header = header;\n this.nobjects = header.get(\"managed_object_count\") + header.get(\"huge_object_count\") + header.get(\"tiny_object_count\");\n let managed = [];\n let root_address = header.get(\"root_block_address\");\n let nrows = 0;\n if (root_address != null) {\n nrows = header.get(\"indirect_current_rows_count\");\n }\n if (nrows > 0) {\n for await (let data of this._iter_indirect_block(this.fh, root_address, nrows)) {\n managed.push(data);\n }\n } else {\n let data = await this._read_direct_block(this.fh, root_address, start_block_size);\n managed.push(data);\n }\n let data_size = managed.reduce((p, c) => p + c.byteLength, 0);\n let combined = new Uint8Array(data_size);\n let moffset = 0;\n managed.forEach((m) => {\n combined.set(new Uint8Array(m), moffset);\n moffset += m.byteLength;\n });\n this.managed = combined.buffer;\n }\n async _read_direct_block(fh, offset, block_size) {\n let data = await fh.slice(offset, offset + block_size);\n let header = _unpack_struct_from(this.direct_block_header, data);\n assert(header.get(\"signature\") == \"FHDB\");\n return data;\n }\n get_data(heapid) {\n let firstbyte = struct.unpack_from(\"> 4 & 3;\n let version = firstbyte >> 6;\n let data_offset = 1;\n if (idtype == 0) {\n assert(version == 0);\n let nbytes = this._managed_object_offset_size;\n let offset = _unpack_integer(nbytes, heapid, data_offset);\n data_offset += nbytes;\n nbytes = this._managed_object_length_size;\n let size = _unpack_integer(nbytes, heapid, data_offset);\n return this.managed.slice(offset, offset + size);\n } else if (idtype == 1) {\n throw \"tiny objectID not supported in FractalHeap\";\n } else if (idtype == 2) {\n throw \"huge objectID not supported in FractalHeap\";\n } else {\n throw \"unknown objectID type in FractalHeap\";\n }\n }\n _min_size_integer(integer) {\n return this._min_size_nbits(bitSize(integer));\n }\n _min_size_nbits(nbits) {\n return Math.ceil(nbits / 8);\n }\n async *_iter_indirect_block(fh, offset, nrows) {\n let header = await _unpack_struct_from_async(this.indirect_block_header, fh, offset);\n offset += this.indirect_block_header_size;\n assert(header.get(\"signature\") == \"FHIB\");\n let block_offset_bytes = header.get(\"block_offset\");\n let block_offset = block_offset_bytes.reduce((p, c, i) => p + (c << i * 8), 0);\n header.set(\"block_offset\", block_offset);\n let [ndirect, nindirect] = this._indirect_info(nrows);\n let direct_blocks = [];\n for (let i = 0; i < ndirect; i++) {\n let address = (await struct.unpack_from_async(\" {\n return this._chunks;\n });\n }\n get shape() {\n let msg = this.find_msg_type(DATASPACE_MSG_TYPE)[0];\n let msg_offset = msg.get(\"offset_to_message\");\n return determine_data_shape(this.fh, msg_offset);\n }\n async get_filter_pipeline() {\n if (this._filter_pipeline != null) {\n return this._filter_pipeline;\n }\n let filter_msgs = this.find_msg_type(DATA_STORAGE_FILTER_PIPELINE_MSG_TYPE);\n if (!filter_msgs.length) {\n this._filter_pipeline = null;\n return this._filter_pipeline;\n }\n var offset = filter_msgs[0].get(\"offset_to_message\");\n let [version, nfilters] = await struct.unpack_from_async(\" 255) {\n name_length = (await struct.unpack_from_async(\" 0;\n filter_info.set(\"optional\", optional);\n let num_client_values = (await struct.unpack_from_async(\" 0) {\n name = (await struct.unpack_from_async(`${name_length}s`, buf, offset))[0];\n offset += name_length;\n }\n filter_info.set(\"name\", name);\n let client_values = await struct.unpack_from_async(`<${num_client_values}i`, buf, offset);\n offset += 4 * num_client_values;\n filter_info.set(\"client_data_values\", client_values);\n filters.push(filter_info);\n }\n } else {\n throw `version ${version} is not supported`;\n }\n this._filter_pipeline = filters;\n return this._filter_pipeline;\n }\n find_msg_type(msg_type) {\n return this.msgs.filter(function(m) {\n return m.get(\"type\") == msg_type;\n });\n }\n async get_attributes() {\n let attrs = {};\n let attr_msgs = this.find_msg_type(ATTRIBUTE_MSG_TYPE);\n for (let msg of attr_msgs) {\n let offset = msg.get(\"offset_to_message\");\n let [name, value] = await this.unpack_attribute(offset);\n attrs[name] = value;\n }\n return attrs;\n }\n async get_fillvalue() {\n let msg = this.find_msg_type(FILLVALUE_MSG_TYPE)[0];\n var offset = msg.get(\"offset_to_message\");\n var is_defined;\n let version = (await struct.unpack_from_async(\"= block_size) {\n [block_offset, block_size] = object_header_blocks[++current_block];\n local_offset = 0;\n }\n let msg = await _unpack_struct_from_async(HEADER_MSG_INFO_V1, fh, block_offset + local_offset);\n let offset_to_message = block_offset + local_offset + HEADER_MSG_INFO_V1_SIZE;\n msg.set(\"offset_to_message\", offset_to_message);\n if (msg.get(\"type\") == OBJECT_CONTINUATION_MSG_TYPE) {\n var [fh_off, size] = await struct.unpack_from_async(\"= block_size - HEADER_MSG_INFO_V2_SIZE) {\n let next_block = object_header_blocks[++current_block];\n if (next_block == null) {\n break;\n }\n [block_offset, block_size] = next_block;\n local_offset = 0;\n }\n let msg = await _unpack_struct_from_async(HEADER_MSG_INFO_V2, buf, block_offset + local_offset);\n let offset_to_message = block_offset + local_offset + HEADER_MSG_INFO_V2_SIZE + creation_order_size;\n msg.set(\"offset_to_message\", offset_to_message);\n if (msg.get(\"type\") == OBJECT_CONTINUATION_MSG_TYPE) {\n var [fh_off, size] = await struct.unpack_from_async(\" 0;\n let link_name_character_set_field_present = (flags & 2 ** 4) > 0;\n let ordered = (flags & 2 ** 2) > 0;\n let link_type;\n if (link_type_field_present) {\n link_type = (await struct.unpack_from_async(\" 0) {\n offset += 8;\n }\n let fmt = (flags & 2) > 0 ? LINK_INFO_MSG2 : LINK_INFO_MSG1;\n let link_info = await _unpack_struct_from_async(fmt, data, offset);\n let output = /* @__PURE__ */ new Map();\n for (let [k, v] of link_info.entries()) {\n output.set(k, v == UNDEFINED_ADDRESS2 ? null : v);\n }\n return output;\n }\n get is_dataset() {\n return this.find_msg_type(DATASPACE_MSG_TYPE).length > 0;\n }\n async get_data() {\n let msg = this.find_msg_type(DATA_STORAGE_MSG_TYPE)[0];\n let msg_offset = msg.get(\"offset_to_message\");\n var [version, dims, layout_class, property_offset] = await this._get_data_message_properties(msg_offset);\n if (layout_class == 0) {\n throw \"Compact storage of DataObject not implemented\";\n } else if (layout_class == 1) {\n return this._get_contiguous_data(property_offset);\n } else if (layout_class == 2) {\n return this._get_chunked_data(msg_offset);\n }\n }\n async _get_data_message_properties(msg_offset) {\n let dims, layout_class, property_offset;\n let [version, arg1, arg2] = await struct.unpack_from_async(\"= 1 && version <= 4);\n return [version, dims, layout_class, property_offset];\n }\n async _get_contiguous_data(property_offset) {\n let [data_offset] = await struct.unpack_from_async(\"=!@\\|]?(i|u|f|S)(\\d*)/.test(dtype)) {\n let [item_getter, item_is_big_endian, item_size] = dtype_getter(dtype);\n let output = new Array(fullsize);\n const local_buffer = await this.fh.slice(data_offset, data_offset + item_size * fullsize);\n let view = new DataView64(local_buffer);\n for (var i = 0; i < fullsize; i++) {\n output[i] = view[item_getter](i * item_size, !item_is_big_endian, item_size);\n }\n return output;\n } else if (dtype.datatype_class === 5) {\n return this.fh.slice(data_offset, data_offset + dtype.size);\n } else {\n throw \"not Implemented - no proper dtype defined\";\n }\n } else {\n let dtype_class = dtype[0];\n if (dtype_class == \"REFERENCE\") {\n let size = dtype[1];\n if (size != 8) {\n throw \"NotImplementedError('Unsupported Reference type')\";\n }\n let ref_addresses = await this.fh.slice(data_offset, data_offset + fullsize);\n return ref_addresses;\n } else if (dtype_class == \"VLEN_STRING\") {\n let character_set = dtype[2];\n const encoding = character_set == 0 ? \"ascii\" : \"utf-8\";\n const decoder = new TextDecoder(encoding);\n var value = [];\n for (var i = 0; i < fullsize; i++) {\n const [vlen, vlen_data] = await this._vlen_size_and_data(this.fh, data_offset);\n value[i] = decoder.decode(vlen_data);\n data_offset += 16;\n }\n return value;\n } else {\n throw \"NotImplementedError('datatype not implemented')\";\n }\n }\n }\n async _get_chunked_data(offset) {\n await this._get_chunk_params();\n if (this._chunk_address == UNDEFINED_ADDRESS2) {\n return [];\n }\n var chunk_btree = new BTreeV1RawDataChunks(this.fh, this._chunk_address, this._chunk_dims);\n await chunk_btree.ready;\n const dtype = await this.dtype;\n const shape = await this.shape;\n const chunks = await this.chunks;\n const filter_pipeline = await this.get_filter_pipeline();\n let data = await chunk_btree.construct_data_from_chunks(chunks, shape, dtype, filter_pipeline);\n if (dtype instanceof Array && /^VLEN/.test(dtype[0])) {\n let dtype_class = dtype[0];\n for (var i = 0; i < data.length; i++) {\n let [item_size, gheap_address, object_index] = data[i];\n var gheap;\n if (!(gheap_address in this._global_heaps)) {\n gheap = new GlobalHeap(this.fh, gheap_address);\n await gheap.ready;\n this._global_heaps[gheap_address] = gheap;\n } else {\n gheap = this._global_heaps[gheap_address];\n }\n let vlen_data = gheap.objects.get(object_index);\n if (dtype_class == \"VLEN_STRING\") {\n let character_set = dtype[2];\n const encoding = character_set == 0 ? \"ascii\" : \"utf-8\";\n const decoder = new TextDecoder(encoding);\n data[i] = decoder.decode(vlen_data);\n }\n }\n }\n return data;\n }\n async _get_chunk_params() {\n if (this._chunk_params_set) {\n return;\n }\n this._chunk_params_set = true;\n var msg = this.find_msg_type(DATA_STORAGE_MSG_TYPE)[0];\n var offset = msg.get(\"offset_to_message\");\n var [version, dims, layout_class, property_offset] = await this._get_data_message_properties(offset);\n if (layout_class != 2) {\n return;\n }\n var data_offset;\n if (version == 1 || version == 2) {\n var address = (await struct.unpack_from_async(\"= 1 && version <= 3);\n var fmt = \"<\" + (dims - 1).toFixed() + \"I\";\n var chunk_shape = await struct.unpack_from_async(fmt, this.fh, data_offset);\n this._chunks = chunk_shape;\n this._chunk_dims = dims;\n this._chunk_address = address;\n return;\n }\n};\nasync function determine_data_shape(buf, offset) {\n let version = (await struct.unpack_from_async(\" this.get(k));\n }\n length() {\n return this.keys.length;\n }\n _dereference(ref) {\n if (!ref) {\n throw \"cannot deference null reference\";\n }\n let obj = this.file._get_object_by_address(ref);\n if (obj == null) {\n throw \"reference not found in file\";\n }\n return obj;\n }\n async get(y) {\n if (typeof y == \"number\") {\n return this._dereference(y);\n }\n var path = normpath(y);\n if (path == \"/\") {\n return this.file;\n }\n if (path == \".\") {\n return this;\n }\n if (/^\\//.test(path)) {\n return this.file.get(path.slice(1));\n }\n if (posix_dirname(path) != \"\") {\n var [next_obj, additional_obj] = path.split(/\\/(.*)/);\n } else {\n var next_obj = path;\n var additional_obj = \".\";\n }\n if (!(next_obj in this._links)) {\n throw next_obj + \" not found in group\";\n }\n var obj_name = normpath(this.name + \"/\" + next_obj);\n let link_target = this._links[next_obj];\n if (typeof link_target == \"string\") {\n try {\n return this.get(link_target);\n } catch (error) {\n return null;\n }\n }\n var dataobjs = new DataObjects(this.file._fh, link_target);\n await dataobjs.ready;\n if (dataobjs.is_dataset) {\n if (additional_obj != \".\") {\n throw obj_name + \" is a dataset, not a group\";\n }\n return new Dataset(obj_name, dataobjs, this);\n } else {\n var new_group = new Group(obj_name, this);\n await new_group.init(dataobjs);\n return new_group.get(additional_obj);\n }\n }\n visit(func) {\n return this.visititems((name, obj) => func(name));\n }\n visititems(func) {\n var root_name_length = this.name.length;\n if (!/\\/$/.test(this.name)) {\n root_name_length += 1;\n }\n var queue = this.values.slice();\n while (queue) {\n let obj = queue.shift();\n if (queue.length == 1)\n console.log(obj);\n let name = obj.name.slice(root_name_length);\n let ret = func(name, obj);\n if (ret != null) {\n return ret;\n }\n if (obj instanceof Group) {\n queue = queue.concat(obj.values);\n }\n }\n return null;\n }\n get attrs() {\n if (this._attrs == null) {\n this._attrs = this._dataobjects.get_attributes();\n }\n return this._attrs;\n }\n};\nvar File$1 = class extends Group {\n constructor(fh, filename, options) {\n super(\"/\", null);\n this.ready = this.init(fh, filename, options);\n }\n async init(fh, filename, options) {\n var superblock = new SuperBlock(fh, 0);\n await superblock.ready;\n var offset = await superblock.get_offset_to_dataobjects();\n var dataobjects = new DataObjects(fh, offset);\n await dataobjects.ready;\n this.parent = this;\n this.file = this;\n this.name = \"/\";\n this._dataobjects = dataobjects;\n this._attrs = null;\n this._keys = null;\n this._fh = fh;\n this.filename = filename || \"\";\n this.mode = \"r\";\n this.userblock_size = 0;\n if (options && options.index) {\n this.index = options.index;\n } else {\n let index_offset;\n if (options && options.indexOffset) {\n index_offset = options.indexOffset;\n } else {\n const attrs = await this.attrs;\n if (attrs.hasOwnProperty(\"_index_offset\")) {\n index_offset = attrs[\"_index_offset\"];\n } else {\n const indexName = this.indexName || \"_index\";\n const index_link = await dataobjects.find_link(indexName);\n if (index_link) {\n index_offset = index_link[1];\n }\n }\n }\n if (index_offset) {\n try {\n const dataobject = new DataObjects(fh, index_offset);\n await dataobject.ready;\n const comp_index_data = await dataobject.get_data();\n const inflated = ungzip_1(comp_index_data);\n const json = new TextDecoder().decode(inflated);\n this.index = JSON.parse(json);\n } catch (e) {\n console.error(`Error loading index by offset ${e}`);\n }\n }\n }\n if (this.index && this.name in this.index) {\n this._links = this.index[this.name];\n } else {\n this._links = await dataobjects.get_links();\n }\n }\n _get_object_by_address(obj_addr) {\n if (this._dataobjects.offset == obj_addr) {\n return this;\n }\n return this.visititems((y) => {\n y._dataobjects.offset == obj_addr ? y : null;\n });\n }\n};\nvar Dataset = class extends Array {\n constructor(name, dataobjects, parent) {\n super();\n this.parent = parent;\n this.file = parent.file;\n this.name = name;\n this._dataobjects = dataobjects;\n this._attrs = null;\n this._astype = null;\n }\n get value() {\n var data = this._dataobjects.get_data();\n if (this._astype == null) {\n return this.getValue(data);\n }\n return data.astype(this._astype);\n }\n get shape() {\n return this._dataobjects.shape;\n }\n get attrs() {\n return this._dataobjects.get_attributes();\n }\n get dtype() {\n return this._dataobjects.dtype;\n }\n get fillvalue() {\n return this._dataobjects.get_fillvalue();\n }\n async to_array() {\n const value = await this.value;\n const shape = await this.shape;\n return create_nested_array(value, shape);\n }\n async getValue(data) {\n const dtype = await this.dtype;\n if ((typeof dtype === \"string\" || dtype instanceof String) && dtype.startsWith(\"S\")) {\n return (await data).map((s) => {\n let idx = s.indexOf(\"\\0\");\n return idx >= 0 ? s.substring(0, idx) : s;\n });\n } else {\n return data;\n }\n }\n};\nfunction posix_dirname(p) {\n let sep = \"/\";\n let i = p.lastIndexOf(sep) + 1;\n let head = p.slice(0, i);\n let all_sep = new RegExp(\"^\" + sep + \"+$\");\n let end_sep = new RegExp(sep + \"$\");\n if (head && !all_sep.test(head)) {\n head = head.replace(end_sep, \"\");\n }\n return head;\n}\nfunction normpath(path) {\n return path.replace(/\\/(\\/)+/g, \"/\");\n}\nfunction create_nested_array(value, shape) {\n const total_length = value.length;\n const dims_product = shape.reduce((previous, current) => previous * current, 1);\n if (total_length !== dims_product) {\n console.warn(`shape product: ${dims_product} does not match length of flattened array: ${total_length}`);\n }\n let output = value;\n const subdims = shape.slice(1).reverse();\n for (let dim of subdims) {\n const new_output = [];\n const { length } = output;\n let cursor = 0;\n while (cursor < length) {\n new_output.push(output.slice(cursor, cursor += dim));\n }\n output = new_output;\n }\n return output;\n}\n/*! pako 2.0.4 https://github.com/nodeca/pako @license (MIT AND Zlib) */\n\nasync function openH5File(options) {\n\n // Some clients (notably igv-webapp) pass a File reference in the url field. Fix this\n if(options.url && isBlobLike(options.url)) {\n options.file = options.url;\n options.url = undefined;\n }\n\n const isRemote = options.url !== undefined;\n let fileReader = options.reader ? options.reader : getReaderFor(options);\n\n // Set default options appropriate for spacewalk\n const fetchSize = options.fetchSize || 2000;\n const maxSize = options.maxSize || 200000;\n\n if (isRemote) {\n fileReader = new BufferedFile({file: fileReader, fetchSize, maxSize});\n }\n const asyncBuffer = new AsyncBuffer(fileReader);\n\n // Optional external index -- this is not common\n const index = await readExternalIndex(options);\n const indexOffset = options.indexOffset;\n\n // Create HDF5 file\n const filename = getFilenameFor(options);\n const hdfFile = new File$1(asyncBuffer, filename, {index, indexOffset});\n await hdfFile.ready;\n return hdfFile\n}\n\nasync function readExternalIndex(options) {\n\n let indexReader;\n if(options.indexReader) {\n indexReader = options.indexReader;\n }\n else if(options.index) {\n return options.index\n } else if (options.indexURL) {\n indexReader = new RemoteFile({url: options.indexURL});\n } else if (options.indexPath) {\n indexReader = new NodeLocalFile({path: options.indexPath});\n } else if (options.indexFile) {\n indexReader = new BlobFile({file: options.indexFile});\n }\n if (indexReader) {\n const indexFileContents = await indexReader.read();\n const indexFileJson = new TextDecoder().decode(indexFileContents);\n return JSON.parse(indexFileJson)\n } else {\n return undefined\n }\n}\n\n\nfunction getReaderFor(options) {\n if (options.url) { // An absolute or relative URL\n return new RemoteFile(options)\n } else if (options.path) { // A file path\n return new NodeLocalFile(options)\n } else if (options.file) { // A Browser file blob\n return new BlobFile(options.file)\n } else {\n throw Error(\"One of 'url', 'path (node only)', or 'file (browser only)' must be specified\")\n }\n}\n\nfunction getFilenameFor(options) {\n if (options.url) {\n return getFilename(options.url)\n } else if (options.path) {\n return getFilename(options.path)\n } else if (options.file) {\n return options.file.name\n }\n}\n\n/**\n * Wraps an io.Reader in an interface jsfive-async expects*\n */\nclass AsyncBuffer {\n constructor(fileReader) {\n this.fileReader = fileReader;\n }\n\n async slice(start, end) {\n return this.fileReader.read(start, end - start)\n }\n}\n\nfunction getFilename(pathOrURL) {\n const idx = pathOrURL.lastIndexOf(\"/\");\n return idx > 0 ? pathOrURL.substring(idx + 1) : pathOrURL\n}\n\nfunction isBlobLike(obj) {\n return typeof obj.slice === 'function' && typeof obj.arrayBuffer === 'function'\n}\n\nclass HDF5Reader {\n \n constructor(h5_file, bin_size=100000){\n\n this.h5_file = h5_file;\n this.bin_size = bin_size;\n this.h5_obj = undefined;\n }\n \n async fetch(){\n\n if(!this.h5_obj) {\n this.h5_obj = await openH5File({\n url: this.h5_file,\n fetchSize: 1000000,\n maxSize: 200000000\n });\n }\n return this.h5_obj\n }\n\n async get_keys(){\n /* returns a list of keys of the pytor file*/\n let h5_obj = await this.fetch();\n\n return h5_obj.keys\n }\n\n async get_rd_signal(bin_size=this.bin_size){\n\n let h5_obj = await this.fetch();\n let h5_obj_keys = h5_obj.keys;\n\n // console.log(h5_obj_keys)\n let signal_bin = new ParseSignals(h5_obj_keys);\n let rd_bins = signal_bin.get_rd_bins();\n let snp_bins = signal_bin.get_snp_bins();\n this.available_bins = [...new Set(rd_bins, snp_bins)];\n\n // let bin_size = this.bin_size\n if(! this.available_bins.includes(bin_size)){\n bin_size = this.available_bins.at(-1); \n }\n\n const chr_ds = await h5_obj.get(\"rd_chromosomes\");\n await chr_ds.dtype;\n let rd_chromosomes = await chr_ds.value;\n //console.log(`get_rd_signal rd_chromosomes ${Date.now() - t0}`)\n //rd_chromosomes = fixString(rd_chromosomes)\n let rd_flag = \"\";\n\n // get rd stat\n let rd_stat = await this.rd_stat(h5_obj, h5_obj_keys, bin_size);\n \n var wigFeatures = [];\n var wigFeatures_gc = [];\n var wigFeatures_rd_call_meanshift = [];\n var wigFeatures_rd_call_combined = [];\n var wigFeatures_baf1 = [];\n var wigFeatures_baf2 = [];\n\n for (let chrom of rd_chromosomes) {\n // for normal rd signal\n var signal_rd = `his_rd_p_${chrom}_${bin_size}${rd_flag}`;\n let chr_wig = await this.get_chr_signal(h5_obj, h5_obj_keys, chrom, bin_size, signal_rd, rd_stat);\n wigFeatures = wigFeatures.concat(chr_wig);\n \n // rd gc corrected\n var signal_rd_gc = `his_rd_p_${chrom}_${bin_size}_GC`;\n let chr_wig_gc = await this.get_chr_signal(h5_obj, h5_obj_keys, chrom, bin_size, signal_rd_gc, rd_stat);\n wigFeatures_gc = wigFeatures_gc.concat(chr_wig_gc);\n\n // rd call MeanShift\n \n let signal_rd_call = `his_rd_p_${chrom}_${bin_size}_partition_GC_merge`;\n let chr_wig_rd_call_meanshift = await this.get_chr_signal(h5_obj, h5_obj_keys, chrom, bin_size, signal_rd_call, rd_stat);\n wigFeatures_rd_call_meanshift = wigFeatures_rd_call_meanshift.concat(chr_wig_rd_call_meanshift);\n \n let chr_wig_rd_call = await this.rd_call_combined(h5_obj, h5_obj_keys, chrom, bin_size, rd_stat);\n wigFeatures_rd_call_combined = wigFeatures_rd_call_combined.concat(chr_wig_rd_call);\n\n // baf likelihood\n let signal_baf_1 = `snp_likelihood_${chrom}_${bin_size}_mask`;\n let chr_wig_bafs = await this.get_baf_signals(h5_obj, h5_obj_keys, chrom, bin_size, signal_baf_1);\n\n // let signal_baf_1 = `snp_i1_${chrom}_${bin_size}_mask`\n // let chr_wig_bafs = await this.get_baf_signals_v2(h5_obj, h5_obj_keys, chrom, bin_size, signal_baf_1)\n\n wigFeatures_baf1 = wigFeatures_baf1.concat(chr_wig_bafs[0]);\n wigFeatures_baf2 = wigFeatures_baf2.concat(chr_wig_bafs[1]);\n // this.rd_call_combined(h5_obj, h5_obj_keys, chrom, bin_size, rd_stat)\n }\n this.callers = [];\n if (wigFeatures_rd_call_combined.length != 0){\n this.callers.push('ReadDepth');\n }\n if (wigFeatures_rd_call_combined.length != 0){\n this.callers.push('2D');\n }\n\n var obj = {};\n var signal_obj = {\n \"RD_Raw\": wigFeatures,\n \"RD_Raw_gc_coor\" : wigFeatures_gc,\n \"ReadDepth\": wigFeatures_rd_call_meanshift,\n \"2D\": wigFeatures_rd_call_combined,\n \"BAF1\": wigFeatures_baf1,\n \"BAF2\": wigFeatures_baf2\n };\n obj[bin_size] = signal_obj;\n return obj\n }\n\n decode_segments(segments_arr){\n let max = 2 ** 32 - 1;\n let segments = [];\n let l = [];\n for (let x of segments_arr){\n if(x == max){\n segments.push(l);\n l = [];\n } else {\n l.push(x);\n }\n }\n return segments\n }\n\n async rd_call_combined(h5_obj, h5_obj_keys, chrom, bin_size, rd_stat){\n let chr_wig = [];\n \n let segments;\n let mosaic_call_segments = `his_rd_p_${chrom}_${bin_size}_partition_GC_mosaic_segments_2d`;\n if (h5_obj_keys.includes(mosaic_call_segments)){\n const chrom_dataset = await h5_obj.get(mosaic_call_segments);\n let chrom_data = await chrom_dataset.value;\n //console.log(`rd_call_combined ${mosaic_call_segments} ${Date.now() - t0}`)\n segments = this.decode_segments(chrom_data);\n \n }\n\n let mosaic_calls = `his_rd_p_${chrom}_${bin_size}_partition_GC_mosaic_call_2d`;\n if (h5_obj_keys.includes(mosaic_calls)){\n const segments_call_dataset = await h5_obj.get(mosaic_calls);\n let segments_call = await segments_call_dataset.to_array(); //create_nested_array(value, shape)\n segments.forEach((ind_segment, segment_idx) => {\n ind_segment.forEach((bin_value, bin_idx) =>{\n chr_wig.push({chr:chrom, start: bin_value*bin_size, end: (bin_value+1) * bin_size, value: (segments_call[0][segment_idx]/rd_stat[4]) *2});\n });\n });\n }\n\n return chr_wig\n \n }\n\n async rd_stat(h5_obj, h5_obj_keys, bin_size){\n /* \n returns a list for rd statistics information \n paramter\n ---------\n h5_obj: cnvpytor read object\n h5_obj_keys: a list of available signal names\n bin_size: bin size\n \n */\n \n let rd_stat_signal = `rd_stat_${bin_size}_auto`;\n let rd_stat;\n if (h5_obj_keys.includes(rd_stat_signal)){\n const rd_stat_dataset = await h5_obj.get(rd_stat_signal);\n rd_stat = await rd_stat_dataset.value;\n //console.log(`rd_stat_signal ${rd_stat_signal} ${Date.now() - t0}`)\n }\n return rd_stat\n }\n\n \n async get_chr_signal(h5_obj, h5_obj_keys, chrom, bin_size, signal_name, rd_stat){\n /* return a list of dictionary for a chromosome */\n let chr_wig = [];\n \n if (h5_obj_keys.includes(signal_name)){\n const chrom_dataset = await h5_obj.get(signal_name);\n let chrom_data = await chrom_dataset.value;\n //console.log(`chr_signal ${signal_name} ${Date.now() - t0}`)\n chrom_data.forEach((bin_value, bin_idx) => {\n chr_wig.push({chr:chrom, start: bin_idx*bin_size, end: (bin_idx+1) * bin_size, value: (bin_value/rd_stat[4]) *2});\n });\n }\n return chr_wig\n }\n\n async get_baf_signals(h5_obj, h5_obj_keys, chrom, bin_size, signal_name){\n /* return two list of dictionary*/\n let chr_wig_1 = [];\n let chr_wig_2 = [];\n if (h5_obj_keys.includes(signal_name)){\n let chrom_dataset = await h5_obj.get(signal_name);\n let chrom_data = await chrom_dataset.to_array(); //create_nested_array(value, shape)\n chrom_data.forEach((bin_value, bin_idx) => {\n let max_value = Math.max(...bin_value);\n const res = bin_value.indexOf(max_value);\n let lh = Math.max(res / 200, 1 - res / 200);\n chr_wig_1.push({chr:chrom, start: bin_idx*bin_size, end: (bin_idx+1) * bin_size, value: -2 * lh});\n if(lh != 0.5){\n chr_wig_2.push({chr:chrom, start: bin_idx*bin_size, end: (bin_idx+1) * bin_size, value: -2 *(1-lh)});\n }\n });\n }\n return [chr_wig_1, chr_wig_2]\n }\n\n async get_baf_signals_v2(h5_obj, h5_obj_keys, chrom, bin_size, signal_name){\n \n /* return two list of dictionary*/\n let chr_wig_1 = [];\n let chr_wig_2 = [];\n if (h5_obj_keys.includes(signal_name)){\n let chrom_dataset = await h5_obj.get(signal_name);\n let chrom_data = await chrom_dataset.to_array(); //create_nested_array(value, shape)\n chrom_data.forEach((lh, bin_idx) => {\n if (!isNaN(lh)){\n chr_wig_1.push({chr:chrom, start: bin_idx*bin_size, end: (bin_idx+1) * bin_size, value: -2 * ( 0.5 - lh )});\n if(lh != 0.5){\n chr_wig_2.push({chr:chrom, start: bin_idx*bin_size, end: (bin_idx+1) * bin_size, value: -2 * ( 0.5 + lh )});\n }\n }\n });\n }\n console.log(chrom, chr_wig_1, chr_wig_2);\n return [chr_wig_1, chr_wig_2]\n\n }\n}\n\nclass ParseSignals{\n\n constructor(signals){\n /*\n Parse a signal names\n\n parameter\n ---------\n signals: List of keys in pytor files\n */\n this.signals = signals;\n }\n\n get_rd_bins(){\n /* return list of rd bins */\n let rd_keys = [];\n this.signals.forEach( val => {\n let match = val.match(/^his_rd_p_(.*)_(\\d+)$/);\n if(match){\n rd_keys.push({chr:match[1], bin_size:match[2]});\n }});\n const rd_bins = [...new Set(rd_keys.map(item => Number(item.bin_size)))];\n return rd_bins\n }\n\n get_snp_bins(){\n /* return list of snp bins */\n let slected_signals = [];\n this.signals.forEach( val => {\n let match = val.match(/^snp_likelihood_(.*)_(\\d+)_mask$/);\n if(match){\n slected_signals.push({chr:match[1], bin_size:match[2]});\n }});\n const bins = [...new Set(slected_signals.map(item => Number(item.bin_size)))];\n return bins\n }\n}\n\nclass GetFit {\n constructor(allBins) {\n this.allBins = allBins;\n }\n getValues() {\n const bins = Object.values(this.allBins).reduce(\n (binResult, bin) => { return binResult.concat(bin.filter(a => a.binScore > 0).map(a => a.binScore)) }, []);\n return bins\n }\n getMean(data) {\n return (data.reduce(function (a, b) { return a + b; }) / data.length);\n }\n fit_data() {\n let rd_list = this.getValues();\n let distParmas = getDistParams(rd_list);\n return distParmas\n }\n\n histogram(data, bins) {\n const step = bins[1] - bins[0];\n const hist_bins = [];\n\n data.forEach((value, index) => {\n bins.forEach((bin_value, bin_index) => {\n if (!hist_bins[bin_value]) {\n hist_bins[bin_value] = { count: 0 };\n }\n if (bin_value <= value && value < bin_value + step) {\n hist_bins[bin_value].count++;\n return false;\n }\n });\n });\n const dist_p = [];\n hist_bins.forEach((bin, index) => { dist_p.push(bin.count); });\n return dist_p\n }\n\n}\n\nfunction range_function(start, stop, step) {\n const data_array = Array(Math.ceil((stop - start) / step))\n .fill(start)\n .map((x, y) => x + y * step);\n return data_array;\n}\n\nfunction filterOutliers(someArray) {\n\n if (someArray.length < 4)\n return someArray;\n\n let values, q1, q3, iqr, maxValue, minValue;\n\n values = someArray.slice().sort((a, b) => a - b); //copy array fast and sort\n\n if ((values.length / 4) % 1 === 0) { //find quartiles\n q1 = 1 / 2 * (values[(values.length / 4)] + values[(values.length / 4) + 1]);\n q3 = 1 / 2 * (values[(values.length * (3 / 4))] + values[(values.length * (3 / 4)) + 1]);\n } else {\n q1 = values[Math.floor(values.length / 4 + 1)];\n q3 = values[Math.ceil(values.length * (3 / 4) + 1)];\n }\n\n iqr = q3 - q1;\n maxValue = q3 + iqr * 1.5;\n minValue = q1 - iqr * 1.5;\n\n return values.filter((x) => (x >= minValue) && (x <= maxValue));\n}\n\nfunction getDistParams(bins) {\n let filteredBins = filterOutliers(bins);\n const n = filteredBins.length;\n const mean = filteredBins.reduce((a, b) => a + b) / n;\n const std = Math.sqrt(filteredBins.map(x => Math.pow(x - mean, 2)).reduce((a, b) => a + b) / n);\n return [mean, std]\n}\n\nfunction linspace(a, b, n) {\n if (typeof n === \"undefined\") n = Math.max(Math.round(b - a) + 1, 1);\n if (n < 2) {\n return n === 1 ? [a] : [];\n }\n var ret = Array(n);\n n--;\n for (let i = n; i >= 0; i--) {\n ret[i] = (i * b + (n - i) * a) / n;\n }\n return ret;\n}\n\nvar g_utils = { range_function, getDistParams, linspace, GetFit};\n\n/** \n* Evaluates the cumulative distribution function (CDF) for a Student's t distribution with degrees of freedom `v` at a value `t`.\n*\n* @params {number} t - value for the t test\n* @params {PositiveNumber} v - degree of freedom\n* @returns {Probability} evaluated CDF\n*/\nfunction TdistributionCDF(t, v){\n if (isNaN( t ) || isNaN( v ) || v <= 0.0) {\n\t\treturn NaN;\n\t}\n\tif ( t === 0.0 ) {\n\t\treturn 0.5;\n\t}\n return 1/2 + (1/2 * (incompbeta(1/2*v, 1/2, 1) - incompbeta(1/2*v, 1/2, v/(v+t*t)))) * Math.sign( t)\n\n}\n\n\n/** \n* incompbeta(a,b,x) evaluates incomplete beta function, here a, b > 0 and 0 <= x <= 1. This function requires contfractbeta(a,b,x, ITMAX = 200) \n* code translated from https://malishoaib.wordpress.com/2014/04/15/the-beautiful-beta-functions-in-raw-python/\n*\n* @params\n* @params\n* @params\n* @returns \n*/\nfunction incompbeta(a, b, x){\n \n if(x == 0){\n return 0;\n }\n else if (x == 1){\n return 1;\n }else\n {\n let lbeta = lgamma(a+b) - lgamma(a) - lgamma(b) + a * Math.log(x) + b * Math.log(1-x);\n if (x < (a+1) / (a+b+2)){\n return Math.exp(lbeta) * contfractbeta(a, b, x) / a;\n }\n else {\n return 1 - Math.exp(lbeta) * contfractbeta(b, a, 1-x) / b;\n }\n }\n}\n\n/**\n * contfractbeta() evaluates the continued fraction form of the incomplete Beta function; incompbeta(). \n * (Code translated from: Numerical Recipes in C.)\n * \n * @param {*} a \n * @param {*} b \n * @param {*} x \n * @param {*} ITMAX \n * @returns \n */\nfunction contfractbeta(a,b,x, ITMAX = 1000){\n \n let EPS = 3.0e-7;\n let az = 1.0;\n let am = 1.0;\n let bm = 1.0;\n let qab = a + b;\n let qap = a + 1.0;\n let qam = a-1.0;\n let bz = 1.0 - qab*x/qap;\n \n //for i in range(ITMAX):\n for(let i =0; i<= ITMAX; i++){\n let em = parseFloat(i+1);\n let tem = em + em;\n let d = em*(b-em)*x/((qam+tem)*(a+tem));\n let ap = az + d*am;\n let bp = bz+d*bm;\n d = -(a+em)*(qab+em)*x/((qap+tem)*(a+tem));\n let app = ap+d*az;\n let bpp = bp+d*bz;\n let aold = az;\n am = ap/bpp;\n bm = bp/bpp;\n az = app/bpp;\n bz = 1.0;\n if (Math.abs(az-aold)<(EPS * Math.abs(az))){\n return az\n }\n }\n}\n\n/**\n * Evaluates factorial of a number\n * \n * @param {Number} xf - Integer number \n * @returns factorial of the number\n */\nfunction factorial(xf) {\n if ((xf == 0) || (xf == 1)) return 1;\n else {\n let result = (xf * factorial(xf - 1));\n return result\n }\n}\n\n/**\n * Evalues factorial for an integer or fraction using either either factorial or gamma function\n * \n * @param {Number} a - integar or fraction number\n * @returns value of a gamma function\n */\nfunction gamma(a){\n let gamma;\n \n var qc = [75122.6331530, 80916.6278952, 36308.2951477, 8687.24529705, 1168.92649479, 83.8676043424, 2.50662827511];\n \n var sum1 = 0;\n var prod1 = 1;\n if (a == 0) { \n gamma = 1e99; \n }else {\n if ((a % 1) == 0) {//if integer\n gamma = factorial(a - 1);\n }\n else { //not integer\n for (let j = 0; j < qc.length; j++) {\n sum1 = sum1 + qc[j] * Math.pow(a, j);\n prod1 = prod1 * (a + j);\n }\n gamma = (sum1 * Math.pow((a + 5.5), (a + 0.5))) * Math.exp(-(a + 5.5)) / prod1;\n }\n }\n \n return gamma\n}\n\n/**\n * \n * @param {Number} xg - integar or fraction number\n * @returns natural log of gamma function\n */\n\nfunction lgamma(xg){\n return Math.log(gamma(xg))\n}\n\nfunction t_test_1_sample$1(mean, m, s, n) {\n if (s == 0) s = 1;\n var t = ((mean - m) / s) * Math.sqrt(n);\n var p = 1.0 - TdistributionCDF(Math.abs(t), (n - 1));\n return p\n}\n\nfunction t_test_2_samples$1(m1, s1, n1, m2, s2, n2) {\n if (s1 == 0) s1 = 1;\n if (s2 == 0) s2 = 1;\n var t = (m1 - m2) / Math.sqrt(s1 ** 2 / n1 + s2 ** 2 / n2);\n var df = ((s1 ** 2 / n1 + s2 ** 2 / n2) ** 2 * (n1 - 1) * (n2 - 1)) /\n ((s1 ** 4 * (n2 - 1)) / n1 ** 2 + (s2 ** 4 * (n1 - 1)) / n2 ** 2);\n\n var p = 1.0 - TdistributionCDF(Math.abs(t), parseInt(df + 0.5));\n\n return p\n}\n\nvar t_dist = {TdistributionCDF, gamma, t_test_1_sample: t_test_1_sample$1, t_test_2_samples: t_test_2_samples$1};\n\nclass CombinedCaller{\n constructor(wigFeatures, binSize) {\n this.wigFeatures = wigFeatures;\n this.binSize = binSize;\n // let fit_obj = this.get_fit()\n // this.globalMean = fit_obj.globalMean\n // this.globalStd = fit_obj.globalStd\n }\n get_fit(){\n var fit_info = new g_utils.GetFit(this.wigFeatures);\n var [globalMean, globalStd] = fit_info.fit_data();\n\n return {globalMean:globalMean, globalStd:globalStd}\n \n }\n async call_2d(omin=null, mcount=null, event_type=\"both\", max_distance=0.1, baf_threshold=0, max_copy_number=10, min_cell_fraction=0.0){\n \n let fit_obj = this.get_fit();\n this.globalMean = fit_obj.globalMean;\n this.globalStd = fit_obj.globalStd;\n \n let overlap_min = omin==null ? 0.05 * this.binSize / 3e9: omin ;\n let min_count = mcount == null ? parseInt(this.binSize / 10000) : mcount ;\n\n let gstat_rd0 = [];\n let gstat_rd_all = [];\n let gstat_rd = [];\n let gstat_error = [];\n let gstat_lh = [];\n let gstat_n = [];\n \n for (const [chr, wig] of Object.entries(this.wigFeatures)) {\n let segments = [];\n let levels = [];\n let likelihoods = [];\n \n wig.forEach((bin, bin_idx) => {\n if (bin.hets_count > 4 ){\n \n if( bin.dp_count > min_count ){\n segments.push([bin_idx]);\n levels.push(bin.binScore);\n likelihoods.push(bin.likelihood_score);\n delete bin.likelihood_score;\n \n }\n }\n });\n\n let diff_level = [];\n for(let i=1; i {return Math.sqrt(Math.sqrt(x) ** 2 + this.globalStd ** 2 + Math.pow(min_flank[x_idx]/2, 2));});\n \n let overlaps = [];\n \n for(let i=0; i< segments.length-1; i++){\n \n let lh_overlap = 0;\n try{\n lh_overlap = likelihood_overlap(likelihoods[i], likelihoods[i+1]);\n }catch{\n console.log(\"Overlap failed: \", i, likelihoods[i], segments[i+1], likelihoods[i+1]);\n }\n \n let rd_overlap = normal_overlap_approx(levels[i], error[i], levels[i+1], error[i+1]);\n overlaps.push(rd_overlap * lh_overlap);\n \n }\n \n while(overlaps.length >0) {\n overlaps = overlaps.filter(num => typeof num === \"number\");\n \n let max_overlap = arrayMax(overlaps);\n if(isNaN(max_overlap)){\n console.log('NaN value', overlaps);\n }\n if(max_overlap < overlap_min){\n // console.log(\"maxoverlap \",max_overlap, \"is smaller than overlap min\")\n break\n }\n let i = overlaps.indexOf(max_overlap);\n \n let merge_level = normal_merge(levels[i], error[i], levels[i + 1], error[i + 1]);\n \n let nlh;\n let nlh_sum;\n try{\n nlh = likelihoods[i].map((l_value, l_idx) => { return l_value * likelihoods[i+1][l_idx]});\n \n nlh_sum = nlh.reduce((a, c_value) => {return a + c_value});\n \n }catch{\n console.log(likelihoods);\n console.log('max_overlap:', max_overlap, i, overlaps.length);\n console.log('likelihood: ', i ,likelihoods[i], likelihoods[i+1]);\n console.log('nlh: ', nlh_sum);\n }\n // nlh_sum = nlh.reduce((a, c_value) => {return a + c_value});\n\n levels[i] = merge_level.nl;\n error[i] = merge_level.ne;\n \n likelihoods[i] = nlh.map(function(item) { return item/nlh_sum } );\n \n segments[i].push(...segments[i+1]);\n\n levels.splice(i + 1, 1);\n error.splice(i + 1, 1);\n segments.splice(i + 1, 1);\n likelihoods.splice(i + 1, 1);\n overlaps.splice(i, 1);\n \n if(i < overlaps.length){\n \n let rd_overlap = normal_overlap_approx(levels[i], error[i], levels[i+1], error[i+1]);\n let new_overlap = rd_overlap * likelihood_overlap(likelihoods[i], likelihoods[i + 1]);\n \n overlaps[i] = new_overlap;\n }\n if(i > 0){\n let new_overlap = normal_overlap_approx(levels[i - 1], error[i - 1], levels[i], error[i]) \n * likelihood_overlap(likelihoods[i - 1], likelihoods[i]);\n overlaps[i - 1] = new_overlap;\n }\n\n }\n let ons = -1;\n while(true){\n overlaps = [];\n for(let i=0; i< levels.length; i++){\n for(let j=i; j { return l_value * likelihoods[i+1][l_idx]});\n let nlh_sum = nlh.reduce((a, c_value) => {return a + c_value});\n likelihoods[i] = nlh.map(function(item) { return item/nlh_sum } );\n\n \n segments[i].push(...segments[i+1]);\n segments[i] = segments[i].sort((a,b) => a-b);\n\n levels.splice(j, 1);\n error.splice(j, 1);\n segments.splice(j, 1);\n likelihoods.splice(j, 1);\n \n if(j >= segments.length){\n i += 1;\n j = i + 1;\n }\n\n }else {\n j += 1;\n if(j >= segments.length){\n i += 1;\n j = i + 1;\n }\n }\n }\n if(ons == segments.length){\n break\n }\n ons = segments.length;\n }\n // console.log('final segments', segments)\n \n segments.forEach((seg_value, seg_idx) => {\n let baf_info = likelihood_baf_pval(likelihoods[seg_idx]);\n if(seg_value.length > 1){\n\n seg_value.forEach((bin, bin_idx) =>{\n gstat_rd_all.push(wig[bin]);\n if(baf_info.mean <= baf_threshold){\n gstat_rd0.push(wig[bin]);\n }\n wig[bin].segment_score = levels[seg_idx];\n });\n gstat_rd.push(levels[seg_idx]);\n gstat_error.push(error[seg_idx]);\n gstat_lh.push(likelihoods[seg_idx]);\n\n }\n\n });\n\n continue\n }\n \n // Third stage for call\n \n // let data = gstat_rd0.lengthn == 0 ? gstat_rd_all: gstat_rd0 ;\n \n let points = parseInt(1000 * (1 - min_cell_fraction));\n if(points == 0){\n points = 1;\n }\n let x = g_utils.linspace(min_cell_fraction, 1, points);\n let master_lh = {};\n let germline_lh = {};\n for(let cn=10; cn > -1; cn--){\n for(let h1=0; h1 < (cn/2+1); h1++){\n let h2 = cn - h1;\n let mrd = x.map((v, idx) => {return 1-v +v*cn/2});\n let g_mrd = cn / 2;\n let g_mbaf;\n let mbaf;\n if(cn > 0){\n g_mbaf = 0.5 - (h1 / (h1 + h2));\n mbaf = x.map((v, idx) => {return 0.5 - (1 - v + v * h1) / (2 - 2 * v + (h1 + h2) * v)});\n \n }else {\n g_mbaf = 0;\n mbaf = x.map((v, idx) => {return 0*v});\n }\n \n for( let ei=0; ei < gstat_rd.length; ei++){\n \n let g_lh = normal(g_mrd * this.globalMean, 1, gstat_rd[ei], gstat_error[ei]) * likelihood_of_baf(gstat_lh[ei], 0.5 + g_mbaf);\n if(ei in germline_lh){\n germline_lh[ei].push([cn, h1, h2, g_lh, 1.0]);\n }else {\n germline_lh[ei] = [cn, h1, h2, g_lh, 1.0];\n }\n let slh = 0;\n let max_lh = 0;\n let max_x = 0;\n mrd.forEach((mi, idx) => {\n if(!isNaN(mbaf[idx])){\n let tmpl = normal(mi * this.globalMean, 1, gstat_rd[ei], gstat_error[ei]) * likelihood_of_baf(gstat_lh[ei], 0.5 + mbaf[idx]);\n slh += tmpl;\n if(tmpl > max_lh){\n max_lh = tmpl;\n max_x = x[idx];\n }\n }\n });\n if(ei in master_lh){\n master_lh[ei].push([cn, h1, h2, slh / x.length, max_x]);\n }else {\n master_lh[ei] = [cn, h1, h2, slh / x.length, max_x];\n }\n }\n \n for( let ei=0; ei < gstat_rd.length; ei++){\n if(event_type == \"germline\"){\n master_lh[ei].sort((a, b) => a[3] - b[3]);\n }\n else {\n master_lh[ei].sort((a, b) => a[3] - b[3]);\n if(event_type == \"both\"){\n \n germline_lh[ei].sort((a, b) => a[3] - b[3]);\n if(germline_lh[ei][0][3] > master_lh[ei][0][3]){\n //let tmp_list = list(filter( lambda x: x[0] != germline_lh[ei][0][0] and x[1] != germline_lh[ei][0][1], master_lh[ei]))\n let tmp_list = master_lh[ei].filter((x) => (x[0] != germline_lh[ei][0][0]) && (x[1] <= germline_lh[ei][0][1]));\n // console.log('tmp_list', tmp_list)\n // master_lh[ei] = [germline_lh[ei][0]] + tmp_list\n master_lh[ei] = [germline_lh[ei][0]].push(...tmp_list);\n }\n }\n }\n }\n for( let ei=0; ei < gstat_rd.length; ei++){\n if(master_lh[ei][0][0] > 2);\n if(master_lh[ei][0][0] < 2);\n gstat_rd[ei] / this.globalMean;\n t_dist.t_test_1_sample(this.globalMean, gstat_rd[ei], gstat_error[ei], gstat_n[ei]);\n // console.log(etype)\n\n }\n \n\n // break\n }\n \n }\n \n var rawbinScore = this.formatDataStructure(this.wigFeatures, 'binScore', this.globalMean);\n var callScore = this.formatDataStructure(this.wigFeatures, 'segment_score', this.globalMean);\n \n return {binScore: rawbinScore, segment_score: callScore}\n \n }\n\n formatDataStructure(wigFeatures, feature_column, scaling_factor = 1) {\n const results = [];\n for (const [chr, wig] of Object.entries(wigFeatures)) {\n\n wig.forEach(sample => {\n var new_sample = { ...sample };\n if (scaling_factor != 1) {\n new_sample.value = sample[feature_column] / scaling_factor * 2;\n }\n results.push(new_sample);\n });\n }\n\n return results\n }\n\n formatDataStructure_BAF(feature_column, scaling_factor = 2) {\n const baf1 = [];\n const baf2 = [];\n for (const [chr, wig] of Object.entries(this.wigFeatures)) {\n\n wig.forEach(sample => {\n \n var baf1_value = { ...sample };\n var baf2_value = { ...sample };\n \n let value = sample[feature_column];\n if (value != 0.5){\n baf2_value.value = -2 * (1 - value);\n baf2.push(baf2_value);\n }\n baf1_value.value = -2 * value;\n baf1.push(baf1_value);\n \n });\n }\n \n\n return [baf1, baf2]\n }\n}\n\nfunction arrayMax(arr) {\n return arr.reduce(function (p, v) {\n return ( p > v ? p : v );\n });\n }\n\n/**\n * Normal distribution.\n * \n * @param {float} x - Variable.\n * @param {float} a - area\n * @param {float} x0 - Mean value\n * @param {float} sigma - Sigma\n * @returns {float} - Value of distribution in x.\n */\nfunction normal(x, a, x0, sigma){\n \n return a * Math.exp(-1* (x - x0) ** 2 / (2 * sigma ** 2)) / Math.sqrt(2 * Math.PI) / sigma\n\n}\n\n/**\n * Calculates two normal distributions overlap area.\n * \n * @param {float} m1 - Mean value of the first distribution\n * @param {float} s1 - Sigma of the first distribution\n * @param {float} m2 - Mean value for second distribution\n * @param {float} s2 - Sigma of the second distribution\n * \n * @returns {float} area - Area of overlap\n */\nfunction normal_overlap_approx(m1, s1, m2, s2){\n \n return Math.exp(-1* (m1-m2)**2/ (s1**2+s2**2))\n}\n\n\n/**\n * Returns overlap area of two likelihood functions.\n * \n * @param {*} lk1 - First likelihood function.\n * @param {*} lk2 - Second likelihood function.\n * \n * @returns {float} - Overlap area.\n */\nfunction likelihood_overlap(likelihood_1, likelihood_2){\n let sum;\n try{\n sum = likelihood_1.reduce((accumulator, currentValue, currentIndex) => {return accumulator + Math.min(currentValue, likelihood_2[currentIndex])});\n }catch{\n console.log(\"Failed to find likelihood overlap: \", likelihood_1, likelihood_2);\n return 0\n }\n\n return sum\n}\n\n/**\n * Calculates normal distribution that is product of two given normal distributions.\n * \n * @param {float} m1 - Mean value of the first distribution\n * @param {float} s1 - Sigma of the first distribution\n * @param {float} m2 - Mean value for second distribution\n * @param {float} s2 - Sigma of the second distribution\n * @returns {Object} An object representing the first distribution\n * @property {float} nl - Mean value of the first distribution\n * @property {float} ne - Sigma of the first distribution\n */\nfunction normal_merge(m1, s1, m2, s2){\n \n if((s1 == 0) && (s2 == 0)){\n return {nl: 0.5 * (m1 + m2), ne: 0}\n }\n else {\n return {nl: (m1 * s2 * s2 + m2 * s1 * s1) / (s1 * s1 + s2 * s2), ne: Math.sqrt(s1 * s1 * s2 * s2 / (s1 * s1 + s2 * s2))}\n }\n}\n\n/**\n * Calculates likelihood for given baf\n * @param {*} likelihood \n * @param {*} baf \n * @returns {float} likelihood value\n */\nfunction likelihood_of_baf(likelihood, baf){\n \n let bin = parseInt(baf * (likelihood.length - 1));\n let fr = baf * (likelihood.length - 1) - bin;\n if(bin < likelihood.length - 1){\n return likelihood[bin] * (1 - fr) + likelihood[bin + 1] * fr\n }\n else {\n return likelihood[bin]\n }\n}\n\n/**\n * \n * Calculates baf level and p-value for given likelihood function.\n * \n * @param {*} likelihood \n * @returns {Object} An object representing BAF\n * @property {float} mean BAF level (difference from 1/2)\n * @property {float} p p-value for event different than 1/2\n */\nfunction likelihood_baf_pval(likelihood) {\n const res = likelihood.length;\n const max_lh = Math.max(...likelihood);\n let ix = likelihood.indexOf(max_lh);\n if (ix > Math.floor(res / 2)) {\n ix = res - 1 - ix;\n }\n const b = (res / 2 - ix) / (res + 1);\n \n const ix1 = Math.floor((res / 2 + ix) / 2);\n const ix2 = res - 1 - ix1;\n let p = likelihood.slice(ix1, ix2 + 1).reduce((acc, val) => acc + val, 0) / likelihood.reduce((acc, val) => acc + val, 0);\n if (ix === Math.floor(res / 2)) {\n p = 1.0;\n }\n return {mean:b, p:p};\n }\n\n var combined_caller = {CombinedCaller};\n\nfunction erf(x) {\n var m = 1.0, s = 1.0, sum = x * 1.0;\n for (var i = 1; i < 50; i++) {\n m *= i;\n s *= -1;\n sum += (s * Math.pow(x, 2.0 * i + 1.0)) / (m * (2.0 * i + 1.0));\n }\n return (2 * sum) / Math.sqrt(3.14159265358979)\n}\n\nfunction getEValue(mean, sigma, rd, start, end) {\n var arr = new DataStat(rd.slice(start, end));\n if (arr.std == 0) {\n if (sigma > 0) { arr.std = (sigma * arr.mean) / mean; }\n else { arr.std = 1; }\n }\n var p_val = t_test_1_sample(mean, arr.mean, arr.std, end - start) / (end - start);\n return p_val\n}\n\nfunction gaussianEValue(mean, sigma, rd, start, end) {\n var arr = new DataStat(rd.slice(start, end));\n\n if (arr.mean < mean) {\n var x = (arr.max - arr.mean) / (sigma * Math.sqrt(2));\n return Math.pow(0.5 * (1 + erf(x)), end - start)\n }\n var x = (arr.min - arr.mean) / (sigma * Math.sqrt(2));\n return Math.pow(0.5 * (1 - erf(x)), end - start)\n}\n\nfunction adjustToEvalue(mean, sigma, rd, start, end, pval, max_steps = 1000) {\n var val = getEValue(mean, sigma, rd, start, end);\n var step = 0, done = false;\n while ((val > pval) & !done & (step < max_steps)) {\n done = true;\n step += 1;\n var [v1, v2, v3, v4] = [1e10, 1e10, 1e10, 1e10];\n if (start > 0) v1 = getEValue(mean, sigma, rd, start - 1, end);\n if (end - start > 2) {\n var v2 = getEValue(mean, sigma, rd, start + 1, end);\n var v3 = getEValue(mean, sigma, rd, start, end - 1);\n }\n if (end < rd.length) { var v4 = getEValue(mean, sigma, rd, start, end + 1); }\n if (Math.min[(v4)] < val) {\n done = false;\n if (v1 == Math.min[(v4)]) {\n start -= 1;\n val = v1;\n }\n elif(v2 == Math.min[(v4)]); {\n start += 1;\n val = v2;\n }\n elif(v3 == Math.min[(v4)]); {\n end -= 1;\n val = v3;\n }\n elif(v4 == Math.min[(v4)]); {\n end += 1;\n val = v4;\n }\n }\n }\n if (val <= pval) { return end }\n return 0;\n}\n\nclass DataStat {\n constructor(data_array) {\n this.data = data_array;\n this.mean = data_array.reduce((acc, n) => acc + n) / data_array.length;\n this.std = Math.sqrt(data_array.reduce((acc, n) => (n - this.mean) ** 2) / data_array.length);\n }\n}\n\nfunction t_test_1_sample(mean, m, s, n) {\n if (s == 0) s = 1;\n var t = ((mean - m) / s) * Math.sqrt(n);\n var p = 1.0 - t_dist.TdistributionCDF(Math.abs(t), (n - 1));\n return p\n}\n\nfunction t_test_2_samples(m1, s1, n1, m2, s2, n2) {\n if (s1 == 0) s1 = 1;\n if (s2 == 0) s2 = 1;\n var t = (m1 - m2) / Math.sqrt(s1 ** 2 / n1 + s2 ** 2 / n2);\n var df = ((s1 ** 2 / n1 + s2 ** 2 / n2) ** 2 * (n1 - 1) * (n2 - 1)) /\n ((s1 ** 4 * (n2 - 1)) / n1 ** 2 + (s2 ** 4 * (n1 - 1)) / n2 ** 2);\n\n var p = 1.0 - t_dist.TdistributionCDF(Math.abs(t), parseInt(df + 0.5));\n\n return p\n}\n\nclass Partition {\n\n constructor(rd, mean, std) {\n this.rd = rd;\n this.mean = mean;\n this.std = std;\n this.bin_bands = [2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, 64, 80, 96, 112, 128];\n }\n\n get_rd_signal_bandwidth(data_array) {\n var new_array = [];\n\n data_array.forEach((value, index) => {\n var tmp_value = 0;\n if (value > this.mean / 4) {\n tmp_value = this.mean / (this.std ** 2 * value);\n } else {\n tmp_value = 4 / this.std ** 2;\n }\n new_array.push(tmp_value);\n });\n return new_array\n }\n\n meanShiftCaller(repeats = 3) {\n var ChrLevels = {};\n \n Object.entries(this.rd).forEach(([chr, chr_rd]) => {\n var masked = new Array(chr_rd.length).fill(false);\n\n // set the level\n var levels = new Array(chr_rd.length);\n\n for (let b = 0; b < chr_rd.length; b++) {\n if (!masked[b]) { levels[b] = chr_rd[b]; }\n }\n\n this.bin_bands.forEach((bin_band, bin_band_index) => {\n // not masked levels at current bin\n // get boolean values\n var not_masked = masked.map((value, index) => { return !value; });\n\n // not masked level at current bin\n var nm_levels = [];\n\n Object.entries(chr_rd).forEach(([k, v]) => { nm_levels.push(v.binScore); });\n \n // set the mask border\n var mask_borders = [0];\n var count = 0;\n\n for (let i = 0; i < masked.length; i++) {\n if (masked[i]) {\n if (count > 0) {\n mask_borders.push(mask_borders[mask_borders.length - 1] + count - 1);\n count = 0;\n }\n } else { count += 1; }\n }\n\n mask_borders.shift();\n\n // repeating steps\n for (let step = 0; step < repeats; step++) {\n var isig = this.get_rd_signal_bandwidth(nm_levels);\n var grad = new Array(nm_levels.length).fill(0);\n\n for (let i = 0; i < nm_levels.length; i++) {\n for (let j = i - 3 * bin_band; j <= i + 3 * bin_band + 1; j++) {\n if (j < 0 || j >= nm_levels.length) continue;\n if (Math.abs(i - j) >= nm_levels.length) continue;\n\n var g_value = (j - i) * Math.exp((-0.5 * (j - i) ** 2) / bin_band ** 2) *\n Math.exp(-0.5 * (nm_levels[i] - nm_levels[j]) ** 2 * isig[i]);\n\n grad[i] += g_value;\n }\n }\n \n // get the border\n var border = new Array();\n for (var i = 0; i < grad.length - 1; i++) {\n if ((grad[i] < 0) & (grad[i + 1] >= 0)) border.push(i);\n }\n\n border.push(grad.length - 1);\n border = border.concat(mask_borders).sort((a, b) => a - b);\n border = Array.from(new Set(border));\n\n var pb = 0;\n for (var i = 0; i < border.length; i++) {\n var range_array = nm_levels.slice(pb, border[i] + 1);\n var range_mean = range_array.reduce((acc, n) => acc + n) / range_array.length;\n\n nm_levels.fill(range_mean, pb, border[i] + 1);\n pb = border[i] + 1;\n }\n }\n\n for (var i = 0, j = 0; i < levels.length; i++) {\n if (not_masked[i]) {\n levels[i] = nm_levels[j];\n j++;\n }\n }\n\n //get the border\n var border = new Array();\n for (var i = 0; i < levels.length - 1; i++) {\n //if(i == levels.length -1) continue;\n var diff = Math.abs(levels[i + 1] - levels[i]);\n\n if (diff > 0.01) border.push(i + 1);\n }\n\n border.unshift(0);\n border.push(levels.length);\n\n // reset the mask\n masked = new Array(this.rd.length).fill(false);\n\n // check the borders\n for (var i = 1; i < border.length; i++) {\n var seg = [border[i - 1], border[i]];\n var seg_left = [border[i - 1], border[i - 1]];\n if (i > 1) { seg_left[0] = border[i - 2]; } else continue;\n\n var seg_right = [border[i], border[i]];\n if (i < border.length - 1) { seg_right[1] = border[i + 1]; } else continue;\n\n var n = seg[1] - seg[0];\n var n_left = seg_left[1] - seg_left[0];\n var n_right = seg_right[1] - seg_right[0];\n if (n <= 1) continue;\n var seg_array = new DataStat(levels.slice(seg[0], seg[1]));\n\n if (n_right <= 15 || n_left <= 15 || n <= 15) {\n var ns = 1.8 * Math.sqrt(levels[seg_left[0]] / this.mean) * this.std;\n if (Math.abs(levels[seg_left[0]] - levels[seg[0]]) < ns) { continue }\n\n ns = 1.8 * Math.sqrt(levels[seg_right[0]] / this.mean) * this.std;\n if (Math.abs(levels[seg_right[0]] - levels[seg[0]]) < ns) { continue }\n } else {\n var seg_left_array = levels.slice(seg_left[0], seg_left[1]);\n var seg_left_1 = new DataStat(seg_left_array);\n\n var seg_right_array = levels.slice(seg_right[0], seg_right[1]);\n var seg_right_1 = new DataStat(seg_right_array);\n\n var ttest_2sample_1 = t_test_2_samples(seg_array.mean, seg_array.std, seg_array.data.length,\n seg_left_1.mean, seg_left_1.std, seg_left_1.data.length);\n if (ttest_2sample_1 > (0.01 / genome_size) * bin_size * (n + n_left)) { continue }\n\n var ttest_2sample_2 = t_test_2_samples(seg_array.mean, seg_array.std, seg_array.data.length,\n seg_right_1.mean, seg_right_1.std, seg_right_1.data.length);\n if (ttest_2sample_2 > (0.01 / genome_size) * bin_size * (n + n_right)) { continue }\n }\n\n var ttest_1sample_1 = t_test_1_sample(this.mean, seg_array.mean, seg_array.std, seg_array.data.length);\n if (ttest_1sample_1 > 0.05) { continue }\n let segments_rd = nm_levels.slice(seg[0], seg[1]);\n var raw_seg_data = new DataStat(segments_rd);\n\n masked.fill(true, seg[0], seg[1]);\n levels.fill(raw_seg_data.mean, seg[0], seg[1]);\n }\n });\n\n ChrLevels[chr] = levels;\n\n });\n return ChrLevels\n }\n call_mean_shift(repeats = 3) {\n const bin_size = 1000;\n // const genome_size = bin_size * this.rd.length;\n const genome_size = 2871000000;\n var masked = new Array(this.rd.length).fill(false);\n\n // set the level\n var levels = new Array(this.rd.length);\n for (var b = 0; b < this.rd.length; b++) {\n if (!masked[b]) {\n levels[b] = this.rd[b];\n }\n }\n this.bin_bands.forEach((bin_band, bin_band_index) => {\n // not masked levels at current bin\n // get boolean values\n var not_masked = masked.map((value, index) => {\n return !value;\n });\n\n // not masked level at current bin\n // var nm_levels = not_masked.map((value, index) => {if(value) return this.rd[index]});\n var nm_levels = [];\n not_masked.forEach((value, index) => {\n if (value) nm_levels.push(this.rd[index]);\n });\n\n // console.log(bin_band, nm_levels);\n\n // set the mask border\n var mask_borders = [0];\n var count = 0;\n\n for (var i = 0; i < masked.length; i++) {\n if (masked[i]) {\n if (count > 0) {\n mask_borders.push(\n mask_borders[mask_borders.length - 1] + count - 1,\n );\n count = 0;\n }\n } else {\n count += 1;\n }\n }\n\n mask_borders.shift();\n // repeating steps\n for (var step = 0; step < repeats; step++) {\n var isig = this.get_rd_signal_bandwidth(nm_levels);\n // console.log(isig);\n var grad = new Array(nm_levels.length).fill(0);\n\n for (var i = 0; i < nm_levels.length; i++) {\n for (var j = i - 3 * bin_band; j <= i + 3 * bin_band + 1; j++) {\n if (j < 0 || j >= nm_levels.length) continue;\n if (Math.abs(i - j) >= nm_levels.length) continue;\n\n var g_value =\n (j - i) *\n Math.exp((-0.5 * (j - i) ** 2) / bin_band ** 2) *\n Math.exp(-0.5 * (nm_levels[i] - nm_levels[j]) ** 2 * isig[i]);\n // console.log(g_value);\n grad[i] += g_value;\n }\n }\n // console.log(grad);\n\n // get the border\n var border = new Array();\n for (var i = 0; i < grad.length - 1; i++) {\n if ((grad[i] < 0) & (grad[i + 1] >= 0)) border.push(i);\n }\n\n border.push(grad.length - 1);\n border = border.concat(mask_borders).sort((a, b) => a - b);\n border = Array.from(new Set(border));\n\n var pb = 0;\n for (var i = 0; i < border.length; i++) {\n var range_array = nm_levels.slice(pb, border[i] + 1);\n var range_mean =\n range_array.reduce((acc, n) => acc + n) / range_array.length;\n\n nm_levels.fill(range_mean, pb, border[i] + 1);\n pb = border[i] + 1;\n }\n }\n\n for (var i = 0, j = 0; i < levels.length; i++) {\n if (not_masked[i]) {\n levels[i] = nm_levels[j];\n j++;\n }\n }\n\n //get the border\n var border = new Array();\n for (var i = 0; i < levels.length - 1; i++) {\n //if(i == levels.length -1) continue;\n var diff = Math.abs(levels[i + 1] - levels[i]);\n\n if (diff > 0.01) border.push(i + 1);\n }\n\n border.unshift(0);\n border.push(levels.length);\n\n // reset the mask\n masked = new Array(this.rd.length).fill(false);\n\n // check the borders\n for (var i = 1; i < border.length; i++) {\n var seg = [border[i - 1], border[i]];\n var seg_left = [border[i - 1], border[i - 1]];\n if (i > 1) {\n seg_left[0] = border[i - 2];\n } else continue;\n\n var seg_right = [border[i], border[i]];\n if (i < border.length - 1) {\n seg_right[1] = border[i + 1];\n } else continue;\n\n var n = seg[1] - seg[0];\n var n_left = seg_left[1] - seg_left[0];\n var n_right = seg_right[1] - seg_right[0];\n if (n <= 1) continue;\n var seg_array = new DataStat(levels.slice(seg[0], seg[1]));\n\n if (n_right <= 15 || n_left <= 15 || n <= 15) {\n var ns = 1.8 * Math.sqrt(levels[seg_left[0]] / this.mean) * this.std;\n if (Math.abs(levels[seg_left[0]] - levels[seg[0]]) < ns) {\n continue;\n }\n\n ns = 1.8 * Math.sqrt(levels[seg_right[0]] / this.mean) * this.std;\n if (Math.abs(levels[seg_right[0]] - levels[seg[0]]) < ns) {\n continue;\n }\n } else {\n var seg_left_array = levels.slice(seg_left[0], seg_left[1]);\n var seg_left_1 = new DataStat(seg_left_array);\n\n var seg_right_array = levels.slice(seg_right[0], seg_right[1]);\n var seg_right_1 = new DataStat(seg_right_array);\n\n var ttest_2sample_1 = t_test_2_samples(\n seg_array.mean,\n seg_array.std,\n seg_array.data.length,\n seg_left_1.mean,\n seg_left_1.std,\n seg_left_1.data.length,\n );\n if (\n ttest_2sample_1 >\n (0.01 / genome_size) * bin_size * (n + n_left)\n ) {\n continue;\n }\n\n var ttest_2sample_2 = t_test_2_samples(\n seg_array.mean,\n seg_array.std,\n seg_array.data.length,\n seg_right_1.mean,\n seg_right_1.std,\n seg_right_1.data.length,\n );\n if (\n ttest_2sample_2 >\n (0.01 / genome_size) * bin_size * (n + n_right)\n ) {\n continue;\n }\n }\n\n var ttest_1sample_1 = t_test_1_sample(\n this.mean,\n seg_array.mean,\n seg_array.std,\n seg_array.data.length,\n );\n if (ttest_1sample_1 > 0.05) {\n continue;\n }\n var raw_seg_data = new DataStat(this.rd.slice(seg[0], seg[1]));\n\n masked.fill(true, seg[0], seg[1]);\n levels.fill(raw_seg_data.mean, seg[0], seg[1]);\n }\n });\n return levels;\n }\n\n cnv_calling(bin_size = 100000) {\n var delta = 0.25;\n var delta = delta * this.mean;\n\n var min = this.mean - delta, max = this.mean + delta;\n // console.log('min: ', min, ', Max: ', max)\n\n // console.log('delta', delta)\n var normal_genome_size = 2971000000;\n\n var levels = this.meanShiftCaller();\n\n \n var merged_level = {};\n var cnv_levels = [];\n // var t_value = cdf(Math.abs(10), (5)) \n // console.log('Testing student t test:', t_value)\n\n Object.entries(levels).forEach(([chr, chr_levels]) => {\n \n var done = false;\n while (!done) {\n done = true;\n\n //\n // get the borders\n //\n var borders = new Array(1).fill(0);\n for (let i = 0; i < chr_levels.length - 1; i++) {\n var diff = Math.abs(chr_levels[i + 1] - chr_levels[i]);\n if (diff > 0.01) borders.push(i + 1);\n }\n borders.push(chr_levels.length);\n\n for (let ix = 0; ix < borders.length - 2; ix++) {\n var v1 = Math.abs(chr_levels[borders[ix]] - chr_levels[borders[ix + 1]]);\n // console.log(ix, v1);\n if (v1 < delta) {\n var v2 = v1 + 1, v3 = v1 + 1;\n\n if (ix > 0) { v2 = Math.abs(chr_levels[borders[ix]] - chr_levels[borders[ix - 1]]); }\n if (ix < borders.length - 3) { v3 = Math.abs(levels[borders[ix + 1]] - chr_levels[borders[ix + 2]]); }\n\n if (v1 < v2 && v1 < v3) {\n done = false;\n\n var tmp_array = new DataStat(chr_levels.slice(borders[ix], borders[ix + 2]));\n chr_levels.fill(tmp_array.mean, borders[ix], borders[ix + 2]);\n borders.splice(ix + 1, ix + 1);\n }\n }\n }\n }\n // console.log('updated levels', chr_levels)\n\n // var chr_rd = this.rd[chr]\n var chr_rd = [];\n Object.entries(this.rd[chr]).forEach(([bin, binDict]) => { chr_rd.push(binDict.binScore); });\n // console.log('cnv_calling', chr_rd)\n\n //\n // Calling Segments\n //\n\n //var flags = [\"\"] * levels.length;\n var flags = new Array(chr_levels.length).fill(\"\");\n\n // console.log('default levels', chr, chr_levels)\n var b = 0;\n var pval = (0.05 * bin_size) / normal_genome_size;\n while (b < chr_levels.length) {\n var b0 = b, border_start = b;\n while ((b < chr_levels.length) & (chr_levels[b] < min)) {\n b += 1;\n }\n var border_end = b;\n\n if (border_end > border_start + 1) {\n // console.log('border min', border_start, border_end)\n var adj = adjustToEvalue(this.mean, this.std, chr_rd, border_start, border_end, pval);\n // console.log(adj)\n if (adj) {\n var border_start, border_end = adj;\n flags.fill(\"D\", border_start, border_end);\n }\n }\n border_start = b;\n while ((b < chr_levels.length) & (chr_levels[b] > max)) { b += 1; }\n border_end = b;\n\n if (border_end > border_start + 1) {\n adj = adjustToEvalue(this.mean, this.std, chr_rd, border_start, border_end, pval);\n // console.log(adj)\n if (adj) {\n (border_end = adj);\n // flags[bs:be] = [\"A\"] * (be - bs)\n flags.fill(\"A\", border_start, border_end);\n }\n }\n if (b == b0) b += 1;\n }\n\n //console.log(chr, 'segments', segments)\n //\n // Calling additional deletions\n //\n b = 0;\n while (b < chr_levels.length) {\n while ((b < chr_levels.length) & (flags[b] != \"\")) b += 1;\n border_start = b;\n while ((b < chr_levels.length) & (chr_levels[b] < min)) b += 1;\n border_end = b;\n if (border_end > border_start + 1) {\n if (gaussianEValue(this.mean, this.std, chr_rd, border_start, border_end) < 0.05 / normal_genome_size) {\n flags.fill([\"d\"] * (border_end - border_start), border_start, border_end);\n }\n b -= 1;\n }\n b += 1;\n }\n\n b = 0;\n var cf;\n if (b < chr_levels.length) cf = flags[b];\n\n border_start = 0;\n\n //var merge = [...this.rd]\n var merge = [...chr_rd];\n // console.log('initial merge', merge)\n while (b < chr_levels.length) {\n while (flags[b] == cf) {\n b += 1;\n if (b >= flags.length) break;\n }\n if (b > border_start) {\n var merge_arr = new DataStat(merge.slice(border_start, b));\n merge.fill(merge_arr.mean, border_start, b);\n }\n if (b < chr_levels.length) cf = flags[b];\n border_start = b;\n }\n\n merged_level[chr] = merge;\n\n\n //\n // calculate calls\n // \n b = 0;\n while (b < chr_levels.length) {\n cf = flags[b];\n if (cf == \"\") {\n b += 1;\n continue\n }\n border_start = b;\n while (b < chr_levels.length & cf == flags[b]) { b += 1; }\n var border_arr = new DataStat(merge.slice(border_start, b));\n let cnv = border_arr.mean / this.mean;\n let event_type;\n if (cf == \"D\") {\n event_type = \"deletion\";\n } else {\n event_type = \"duplication\";\n }\n let cnv_dict = {\n chr: chr,\n start: bin_size * border_start + 1,\n end: bin_size * b,\n size: bin_size * (b - border_start + 1),\n value: cnv * 2,\n event_type: event_type\n };\n cnv_levels.push(cnv_dict);\n\n }\n });\n\n return [merged_level, cnv_levels]\n }\n}\n\n\n\nvar read_depth_caller = { Partition };\n\nclass CNVpytorVCF {\n constructor(allVariants, binSize) {\n this.allVariants = allVariants;\n this.rowBinSize = 10000;\n this.binSize = binSize;\n this.binFactor = binSize / this.rowBinSize;\n\n }\n\n async computeDepthFeatures() {\n\n const chromosomes = Object.keys(this.allVariants);\n const wigFeatures = [];\n\n for (let chr of chromosomes) {\n const variants = this.allVariants[chr];\n if (variants.length === 0) continue\n\n const firstSnp = variants[0];\n\n let sum = 0;\n let count = 0;\n let binStart = firstSnp.start = firstSnp.start % this.binSize; // Place start at integer multiple of binSize\n let binEnd = binStart + this.binSize;\n let featureBin = 0;\n\n for (let snp of variants) {\n const position = snp.start + 1; // Convert from 0-base to 1-base coords\n featureBin = Math.max(Math.floor((snp.start - 1) / this.binSize), 0);\n if (position > binEnd) {\n\n if (count > 0) {\n wigFeatures.push({ chr, start: binStart, end: binEnd, value: sum, bin: featureBin, count: count });\n }\n\n // Start new bin\n sum = 0;\n //count = 0\n binStart = snp.start - snp.start % this.binSize;\n binEnd = binStart + this.binSize;\n }\n\n const dpValue = snp.calls[9].info[\"DP\"];\n // const dpValue = snp.getInfo(\"DP\")\n\n if (dpValue) {\n sum += Number.parseInt(dpValue);\n count++;\n }\n }\n\n // final bin\n if (count > 0) {\n wigFeatures.push({ chr, start: binStart, end: binEnd, value: sum, bin: featureBin, count: count });\n }\n }\n\n return wigFeatures\n }\n\n // for for read depth calculation\n async computeReadDepth() {\n const chromosomes = Object.keys(this.allVariants);\n var wigFeatures = {};\n\n for (let chr of chromosomes) {\n const variants = this.allVariants[chr];\n var featureBin;\n if (variants.length === 0) continue\n for (let snp of variants) {\n featureBin = Math.max(Math.floor(snp.start / this.rowBinSize), 0);\n if (!wigFeatures[chr]) { wigFeatures[chr] = []; }\n if (!wigFeatures[chr][featureBin]) {\n\n wigFeatures[chr][featureBin] = {\n chr,\n start: featureBin * this.rowBinSize,\n end: (featureBin + 1) * this.rowBinSize,\n value: 0,\n sum_score: 0,\n count: 0,\n };\n }\n const dpValue = snp.calls[9].info[\"DP\"];\n if (dpValue) {\n // sum += Number.parseInt(dpValue)\n wigFeatures[chr][featureBin].sum_score += Number.parseInt(dpValue);\n wigFeatures[chr][featureBin].count++;\n }\n\n }\n // for last bin\n //let last_bin = wigFeatures[chr][featureBin]\n //last_bin.value = parseInt(last_bin.sum_score / last_bin.count) * 100\n }\n\n // adjust the bin values to actual bin size\n var avgbin = {};\n for (let chr of chromosomes) {\n if (!avgbin[chr]) { avgbin[chr] = []; }\n for (let k = 0; k < wigFeatures[chr].length / this.binFactor; k++) {\n const featureBin = k;\n if (!avgbin[chr][k]) {\n avgbin[chr][k] = {\n chr,\n binScore: 0,\n start: featureBin * this.binSize,\n end: (featureBin + 1) * this.binSize,\n };\n }\n\n for (var j = k * 10; j < 10 * k + 10; j++) {\n if (wigFeatures[chr][j]) {\n var tmp_score = parseInt(wigFeatures[chr][j].sum_score / wigFeatures[chr][j].count) * 100;\n avgbin[chr][k].binScore += tmp_score;\n }\n }\n }\n }\n\n var finalFeatureSet = this.readDepthMeanshift(avgbin);\n return finalFeatureSet\n\n }\n readDepthMeanshift(wigFeatures) {\n\n // Get global mean and standrad deviation\n var fit_info = new g_utils.GetFit(wigFeatures);\n var [globamMean, globalStd] = fit_info.fit_data();\n\n // Apply partition method\n var partition = new read_depth_caller.Partition(wigFeatures, globamMean, globalStd);\n var partition_array = partition.meanShiftCaller();\n var caller_array = partition.cnv_calling();\n\n // Assign the partition values to each bin\n Object.entries(wigFeatures).forEach(([chr, chr_rd]) => {\n chr_rd.forEach((bin, index) => {\n bin.partition_level = parseInt(partition_array[chr][index]);\n bin.partition_call = parseInt(caller_array[0][chr][index]);\n });\n });\n\n var rawbinScore = this.formatDataStructure(wigFeatures, 'binScore', globamMean);\n var partition_levels = this.formatDataStructure(wigFeatures, 'partition_level', globamMean);\n var partition_call = this.formatDataStructure(wigFeatures, 'partition_call', globamMean);\n\n return [rawbinScore, partition_levels, partition_call, caller_array[1]]\n\n }\n formatDataStructure(wigFeatures, feature_column, scaling_factor = 1) {\n const results = [];\n for (const [chr, wig] of Object.entries(wigFeatures)) {\n\n wig.forEach(sample => {\n var new_sample = { ...sample };\n if (scaling_factor != 1) {\n new_sample.value = sample[feature_column] / scaling_factor * 2;\n }\n results.push(new_sample);\n });\n }\n\n return results\n }\n\n async computeBAF_v2() {\n\n const chromosomes = Object.keys(this.allVariants);\n const wigFeatures = {};\n const baf1 = [], baf2 = [];\n\n for (let chr of chromosomes) {\n const variants = this.allVariants[chr];\n if (variants.length === 0) continue\n var featureBin;\n for (let snp of variants) {\n featureBin = Math.max(Math.floor(snp.start / this.binSize), 0);\n\n if (!wigFeatures[chr]) {\n wigFeatures[chr] = [];\n }\n if (!wigFeatures[chr][featureBin]) {\n if (featureBin > 0) {\n // calculating the BAF likelihood for previous bin\n let previous_featureBin = featureBin - 1;\n if (wigFeatures[chr][previous_featureBin]) {\n\n const updated_bin = this.get_max_min_score(wigFeatures[chr][previous_featureBin]);\n\n if (updated_bin.value != 0.5) {\n let baf_wig = Object.assign({}, updated_bin);\n baf_wig.value = -2 * (1 - updated_bin.value);\n baf2.push(baf_wig);\n }\n updated_bin.value = - 2 * updated_bin.value;\n wigFeatures[chr][previous_featureBin] = updated_bin;\n\n baf1.push(wigFeatures[chr][previous_featureBin]);\n\n }\n }\n wigFeatures[chr][featureBin] = {\n chr,\n start: featureBin * this.binSize,\n end: (featureBin + 1) * this.binSize,\n value: 0,\n count: 0,\n likelihood_score: [],\n min_score: 0,\n };\n }\n const calls = snp.calls[9];\n let genotype = calls.genotype;\n let ad_score = calls.info[\"AD\"].split(',');\n let ad_a = ad_score[0], ad_b = ad_score[1];\n\n if ((genotype[0] == 0 && genotype[1] == 1) || (genotype[0] == 1 && genotype[1] == 0)) {\n //apply the beta function\n if (wigFeatures[chr][featureBin].likelihood_score.length == 0) {\n wigFeatures[chr][featureBin].likelihood_score = g_utils.linspace(0, 1, 100).map((value, index) => {\n return beta(ad_a, ad_b, value);\n });\n } else {\n var sum = 0;\n\n wigFeatures[chr][featureBin].likelihood_score = g_utils.linspace(0, 1, 100).map((value, index) => {\n var likelihood_value = wigFeatures[chr][featureBin].likelihood_score[index] * beta(ad_a, ad_b, value);\n sum = sum + likelihood_value;\n return likelihood_value;\n });\n\n wigFeatures[chr][featureBin].likelihood_score = g_utils.linspace(0, 1, 100).map((value, index) => {\n return wigFeatures[chr][featureBin].likelihood_score[index] / sum;\n });\n }\n wigFeatures[chr][featureBin].count++;\n }\n }\n\n // last feature bin\n const updated_bin = this.get_max_min_score(wigFeatures[chr][featureBin]);\n\n if (updated_bin.value != 0.5) {\n let baf_wig = Object.assign({}, updated_bin);\n baf_wig.value = -2 * (1 - updated_bin.value);\n baf2.push(baf_wig);\n }\n updated_bin.value = -2 * updated_bin.value;\n wigFeatures[chr][featureBin] = updated_bin;\n baf1.push(wigFeatures[chr][featureBin]);\n }\n\n return [baf1, baf2]\n\n }\n\n\n format_BAF_likelihood(wigFeatures) {\n const results = [];\n\n for (const [chr, wig] of Object.entries(wigFeatures)) {\n wig.forEach(sample => {\n var new_sample = { ...sample };\n if (sample.value != 0.5) {\n new_sample.value = 1 - sample.value;\n results.push(new_sample);\n }\n });\n }\n return results\n }\n\n get_max_min_score(sample) {\n\n if (sample.likelihood_score.length > 0) {\n const max = Math.max(...sample.likelihood_score);\n const res = sample.likelihood_score.indexOf(max);\n sample.value = Math.max(res / 100, 1 - res / 100);\n sample.min_score = Math.min(res / 100, 1 - res / 100);\n\n } else {\n sample.score = 0;\n }\n\n return sample\n }\n\n async getAllbins() {\n const bins = await this.computeDepthFeatures();\n\n //console.log('getAllbins', bins[\"value\"])\n\n const fitter = new g_utils.GetFit(bins);\n\n fitter.fit_data();\n // dconsole.log('rd list', distParams)\n\n return bins\n }\n\n async read_rd_baf(caller='ReadDepth'){\n \n const chromosomes = Object.keys(this.allVariants);\n var wigFeatures = {};\n\n for (let chr of chromosomes) {\n const variants = this.allVariants[chr];\n var featureBin;\n if (variants.length === 0) continue\n for (let snp of variants) {\n featureBin = Math.max(Math.floor(snp.start / this.rowBinSize), 0);\n if (!wigFeatures[chr]) { wigFeatures[chr] = []; }\n if (!wigFeatures[chr][featureBin]) {\n\n wigFeatures[chr][featureBin] = {\n chr,\n start: featureBin * this.rowBinSize,\n end: (featureBin + 1) * this.rowBinSize,\n // value: 0,\n dp_sum_score: 0,\n dp_count: 0,\n hets_count:0,\n hets: [],\n //likelihood_score: [],\n };\n }\n const calls = snp.calls[9];\n const dpValue = calls.info[\"DP\"];\n if (dpValue) {\n \n wigFeatures[chr][featureBin].dp_sum_score += Number.parseInt(dpValue);\n wigFeatures[chr][featureBin].dp_count++;\n }\n \n let ad_score = calls.info[\"AD\"].split(',');\n let genotype = calls.genotype;\n if ((genotype[0] == 0 && genotype[1] == 1) || (genotype[0] == 1 && genotype[1] == 0)) {\n //apply the beta function\n wigFeatures[chr][featureBin].hets_count++;\n let ad_a = parseInt(ad_score[0]), ad_b = parseInt(ad_score[1]);\n wigFeatures[chr][featureBin].hets.push({ref:ad_a, alt:ad_b});\n }\n \n }\n \n }\n \n var avgbin = this.adjust_bin_size(wigFeatures);\n var finalFeatureSet;\n if(caller == 'ReadDepth'){\n finalFeatureSet = this.readDepthMeanshift(avgbin);\n var baf = this.formatDataStructure_BAF(avgbin, 'max_likelihood');\n }else if(caller=='2D'){\n \n let caller_obj = new combined_caller.CombinedCaller(avgbin, this.binSize); \n let processed_bins = await caller_obj.call_2d();\n \n finalFeatureSet = [processed_bins.binScore, [], processed_bins.segment_score];\n \n var baf = caller_obj.formatDataStructure_BAF('max_likelihood');\n }\n \n\n return [finalFeatureSet, baf]\n }\n\n formatDataStructure_BAF(wigFeatures, feature_column, scaling_factor = 2) {\n const baf1 = [];\n const baf2 = [];\n for (const [chr, wig] of Object.entries(wigFeatures)) {\n\n wig.forEach(sample => {\n delete sample.likelihood_score;\n var baf1_value = { ...sample };\n var baf2_value = { ...sample };\n \n let value = sample[feature_column];\n if (value != 0.5){\n baf2_value.value = -2 * (1 - value);\n baf2.push(baf2_value);\n }\n baf1_value.value = -2 * value;\n baf1.push(baf1_value);\n \n });\n }\n \n\n return [baf1, baf2]\n }\n \n adjust_bin_size(wigFeatures){\n const chromosomes = Object.keys(this.allVariants);\n // adjust the bin values to actual bin size\n var avgbin = {};\n for (let chr of chromosomes) {\n if (!avgbin[chr]) { avgbin[chr] = []; }\n for (let k = 0; k < wigFeatures[chr].length / this.binFactor; k++) {\n const featureBin = k;\n if (!avgbin[chr][k]) {\n avgbin[chr][k] = {\n chr,\n start: featureBin * this.binSize,\n end: (featureBin + 1) * this.binSize,\n dp_count: 0,\n hets_count: 0,\n binScore: 0,\n likelihood_score: [],\n };\n }\n\n for (var j = k * 10; j < 10 * k + 10; j++) {\n \n if (wigFeatures[chr][j]) {\n var tmp_score = parseInt(wigFeatures[chr][j].dp_sum_score / wigFeatures[chr][j].dp_count) * 100;\n avgbin[chr][k].binScore += tmp_score;\n avgbin[chr][k].dp_count += wigFeatures[chr][j].dp_count;\n avgbin[chr][k].hets_count += wigFeatures[chr][j].hets_count;\n\n if (wigFeatures[chr][j].hets.length != 0){\n \n \n wigFeatures[chr][j].hets.forEach((hets, hets_idx) => {\n if(avgbin[chr][k].likelihood_score.length == 0){\n avgbin[chr][k].likelihood_score = g_utils.linspace(0, 1, 100).map((value, index) => {\n return beta(hets.ref, hets.alt, value);\n });\n }\n else {\n var likelihood_sum = 0;\n avgbin[chr][k].likelihood_score = g_utils.linspace(0, 1, 100).map((value, index) => {\n var likelihood_value = avgbin[chr][k].likelihood_score[index] * beta(hets.ref, hets.alt, value);\n likelihood_sum += likelihood_value;\n return likelihood_value;\n });\n\n avgbin[chr][k].likelihood_score = g_utils.linspace(0, 1, 100).map((value, index) => {\n return avgbin[chr][k].likelihood_score[index] / likelihood_sum;\n });\n \n }\n });\n \n // avgbin[chr][k].likelihood_score *= wigFeatures[chr][j].likelihood_score\n }\n }\n }\n\n const updated_bin = this.get_max_min_score(avgbin[chr][k]);\n avgbin[chr][k].max_likelihood = updated_bin.value;\n }\n }\n return avgbin\n }\n\n}\n\nfunction beta(a, b, p, phased = true) {\n return p ** a * (1 - p) ** b + p ** b * (1 - p) ** a;\n}\n\n/*\n* The MIT License (MIT)\n*\n* Copyright (c) 2016-2017 The Regents of the University of California\n* Author: Arijit Panda\n*\n* Permission is hereby granted, free of charge, to any person obtaining a copy\n* of this software and associated documentation files (the \"Software\"), to deal\n* in the Software without restriction, including without limitation the rights\n* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n* copies of the Software, and to permit persons to whom the Software is\n* furnished to do so, subject to the following conditions:\n*\n* The above copyright notice and this permission notice shall be included in\n* all copies or substantial portions of the Software.\n*\n*\n* THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n* THE SOFTWARE.\n*/\n\n\n/**\n * Represents 2 or more wig tracks overlaid on a common viewport.\n */\n\nconst DEFAULT_TRACK_HEIGHT = 250;\n\nclass CNVPytorTrack extends TrackBase {\n\n constructor(config, browser) {\n super(config, browser);\n this.featureType = 'numeric';\n this.paintAxis = paintAxis;\n \n if (!config.max) {\n this.defaultScale = true;\n this.autoscale = false;\n }\n\n // Invoke height setter last to allocated to coverage and alignment tracks\n this.height = (config.height !== undefined ? config.height : DEFAULT_TRACK_HEIGHT);\n }\n\n async init(config) {\n\n this.type = \"cnvpytor\";\n this.graphType = config.graphType || \"points\";\n this.bin_size = config.bin_size || 100000;\n this.signal_name = config.signal_name || \"rd_snp\";\n this.cnv_caller = config.cnv_caller || '2D';\n this.colors = config.colors || ['gray', 'black', 'green', 'blue'];\n super.init(config);\n\n }\n\n get supportsWholeGenome() {\n return true\n }\n\n get_signals() {\n let signals = [];\n\n if (this.signal_name == 'rd_snp') {\n signals = [\"RD_Raw\", \"RD_Raw_gc_coor\", this.cnv_caller, \"BAF1\", \"BAF2\"];\n\n } else if (this.signal_name == 'rd') {\n signals = [\"RD_Raw\", \"RD_Raw_gc_coor\", this.cnv_caller];\n\n } else if (this.signal_name == 'snp') {\n signals = [\"BAF1\", \"BAF2\"];\n\n } else if (this.signal_name == 'cnh') {\n signals = [this.cnv_caller];\n }\n return signals\n }\n\n get_signal_colors() {\n \n let signal_colors = [\n { singal_name: 'RD_Raw', color: this.colors[0] },\n { singal_name: 'RD_Raw_gc_coor', color: this.colors[1] },\n { singal_name: 'ReadDepth', color: this.colors[2] },\n { singal_name: '2D', color: this.colors[2] },\n { singal_name: 'BAF1', color: this.colors[3] },\n { singal_name: 'BAF2', color: this.colors[3] },\n ];\n return signal_colors\n }\n\n async postInit() {\n\n if (this.config.format == 'vcf') {\n this.featureSource = FeatureSource(this.config, this.browser.genome);\n this.header = await this.getHeader();\n\n\n var allVariants = this.featureSource.reader.features.reduce(function (r, a) {\n r[a.chr] = r[a.chr] || [];\n r[a.chr].push(a);\n return r\n }, Object.create(null));\n\n const cnvpytor_obj = new CNVpytorVCF(allVariants, this.bin_size);\n \n let wigFeatures;\n let bafFeatures;\n this.wigFeatures_obj = {};\n this.wigFeatures_obj[this.bin_size] = {};\n\n let dataWigs;\n if(this.config.cnv_caller == '2D'){\n \n dataWigs = await cnvpytor_obj.read_rd_baf('2D');\n\n wigFeatures = dataWigs[0];\n bafFeatures = dataWigs[1];\n this.wigFeatures_obj[this.bin_size]['2D'] = wigFeatures[2];\n\n this.available_callers = ['2D'];\n }else {\n dataWigs = await cnvpytor_obj.read_rd_baf();\n wigFeatures = dataWigs[0];\n bafFeatures = dataWigs[1];\n this.wigFeatures_obj[this.bin_size]['ReadDepth'] = wigFeatures[2];\n this.available_callers = ['ReadDepth'];\n }\n \n this.wigFeatures_obj[this.bin_size]['RD_Raw'] = wigFeatures[0];\n this.wigFeatures_obj[this.bin_size]['RD_Raw_gc_coor'] = wigFeatures[1];\n this.wigFeatures_obj[this.bin_size]['BAF1'] = bafFeatures[0];\n this.wigFeatures_obj[this.bin_size]['BAF2'] = bafFeatures[1];\n \n this.available_bins = [this.bin_size];\n \n this.set_available_callers();\n\n } else {\n this.cnvpytor_obj = new HDF5Reader(this.config.url, this.bin_size);\n this.wigFeatures_obj = await this.cnvpytor_obj.get_rd_signal(this.bin_size);\n this.available_bins = this.cnvpytor_obj.available_bins;\n this.available_callers = this.cnvpytor_obj.callers;\n this.set_available_callers();\n }\n\n this.tracks = [];\n const p = [];\n\n this.signals = this.get_signals();\n this.signal_colors = this.get_signal_colors();\n\n for (let bin_size in this.wigFeatures_obj) {\n\n for (const [signal_name, wig] of Object.entries(this.wigFeatures_obj[bin_size])) {\n\n if (this.signals.includes(signal_name)) {\n let tconf = {};\n tconf.type = \"wig\";\n tconf.isMergedTrack = true;\n tconf.features = wig;\n tconf.name = signal_name;\n tconf.color = this.signal_colors.filter(x => x.singal_name === signal_name).map(x => x.color);\n const t = await this.browser.createTrack(tconf);\n if (t) {\n t.autoscale = false; // Scaling done from merged track\n this.tracks.push(t);\n } else {\n console.warn(\"Could not create track \" + tconf);\n }\n\n if (typeof t.postInit === 'function') {\n p.push(t.postInit());\n }\n }\n }\n\n }\n\n\n this.flipAxis = this.config.flipAxis ? this.config.flipAxis : false;\n this.logScale = this.config.logScale ? this.config.logScale : false;\n this.autoscale = this.config.autoscale;\n if (!this.autoscale) {\n this.dataRange = {\n min: this.config.min || 0,\n max: this.config.max\n };\n }\n for (let t of this.tracks) {\n t.autoscale = false;\n t.dataRange = this.dataRange;\n }\n\n return Promise.all(p)\n }\n\n set_available_callers() {\n if (!this.available_callers.includes(this.cnv_caller)) {\n if (this.available_callers.length > 0) {\n this.cnv_caller = this.available_callers[0];\n } else {\n this.cnv_caller = null;\n }\n }\n }\n\n async getHeader() {\n\n if (!this.header) {\n if (typeof this.featureSource.getHeader === \"function\") {\n const header = await this.featureSource.getHeader();\n if (header) {\n this.callSets = header.callSets || [];\n }\n this.header = header;\n }\n this.sampleNames = this.callSets ? this.callSets.map(cs => cs.name) : [];\n }\n\n return this.header\n }\n\n get height() {\n return this._height\n }\n\n set height(h) {\n this._height = h;\n if (this.tracks) {\n for (let t of this.tracks) {\n t.height = h;\n t.config.height = h;\n }\n }\n }\n\n menuItemList() {\n let items = [];\n\n if (this.flipAxis !== undefined) {\n items.push({\n label: \"Flip y-axis\",\n click: () => {\n this.flipAxis = !this.flipAxis;\n this.trackView.repaintViews();\n }\n });\n }\n\n items = items.concat(MenuUtils.numericDataMenuItems(this.trackView));\n\n items.push('
');\n items.push(\"Bin Sizes\");\n for (let rd_bin of this.available_bins) {\n const checkBox = createCheckbox(rd_bin, rd_bin === this.bin_size);\n items.push({\n object: $$1(checkBox),\n click: async () => {\n this.bin_size = rd_bin;\n\n await this.recreate_tracks(rd_bin);\n this.clearCachedFeatures();\n this.trackView.updateViews();\n this.trackView.repaintViews();\n }\n });\n }\n items.push('
');\n items.push(\"Signal Type\");\n\n let signal_dct = {\"rd_snp\": \"RD and BAF Likelihood\", \"rd\": \"RD Signal\", \"snp\": \"BAF Likelihood\"};\n for (let signal_name in signal_dct) {\n const checkBox = createCheckbox(signal_dct[signal_name], signal_name === this.signal_name);\n items.push({\n object: $$1(checkBox),\n click: async () => {\n this.signal_name = signal_name;\n await this.recreate_tracks(this.bin_size);\n this.clearCachedFeatures();\n this.trackView.updateViews();\n this.trackView.repaintViews();\n\n }\n });\n }\n\n // cnv caller setting\n items.push('
');\n items.push(\"CNV caller\");\n for (let cnv_caller of this.available_callers) {\n const checkBox = createCheckbox(cnv_caller, cnv_caller === this.cnv_caller);\n items.push({\n object: $$1(checkBox),\n click: async () => {\n this.cnv_caller = cnv_caller;\n await this.recreate_tracks(this.bin_size);\n this.clearCachedFeatures();\n this.trackView.updateViews();\n this.trackView.repaintViews();\n }\n });\n }\n\n return items\n }\n\n async recreate_tracks(bin_size) {\n this.tracks = [];\n const p = [];\n\n if (!(bin_size in this.wigFeatures_obj)) {\n this.wigFeatures_obj = {...this.wigFeatures_obj, ...await this.cnvpytor_obj.get_rd_signal(bin_size)};\n }\n\n this.signals = this.get_signals();\n this.signal_colors = this.get_signal_colors();\n\n for (const [signal_name, wig] of Object.entries(this.wigFeatures_obj[bin_size])) {\n if (this.signals.includes(signal_name)) {\n let tconf = {};\n tconf.type = \"wig\";\n tconf.isMergedTrack = true;\n tconf.features = wig;\n tconf.name = signal_name;\n tconf.color = this.signal_colors.filter(x => x.singal_name === signal_name).map(x => x.color); \n const t = await this.browser.createTrack(tconf);\n if (t) {\n t.autoscale = false; // Scaling done from merged track\n this.tracks.push(t);\n } else {\n console.warn(\"Could not create track \" + tconf);\n }\n\n if (typeof t.postInit === 'function') {\n p.push(t.postInit());\n }\n }\n\n }\n\n\n this.flipAxis = this.config.flipAxis ? this.config.flipAxis : false;\n this.logScale = this.config.logScale ? this.config.logScale : false;\n this.autoscale = this.config.autoscale;\n if (!this.autoscale) {\n this.dataRange = {\n min: this.config.min || 0,\n max: this.config.max\n };\n }\n for (let t of this.tracks) {\n t.autoscale = false;\n t.dataRange = this.dataRange;\n }\n return Promise.all(p)\n }\n\n async getFeatures(chr, bpStart, bpEnd, bpPerPixel) {\n\n if(this.tracks) {\n const promises = this.tracks.map((t) => t.getFeatures(chr, bpStart, bpEnd, bpPerPixel));\n return Promise.all(promises)\n } else {\n return undefined // This can happen if a redraw is triggered before the track has initialized.\n }\n }\n\n // TODO: refactor to igvUtils.js\n getScaleFactor(min, max, height, logScale) {\n const scale = logScale ? height / (Math.log10(max + 1) - (min <= 0 ? 0 : Math.log10(min + 1))) : height / (max - min);\n return scale\n }\n\n computeYPixelValue(yValue, yScaleFactor) {\n return (this.flipAxis ? (yValue - this.dataRange.min) : (this.dataRange.max - yValue)) * yScaleFactor\n }\n\n computeYPixelValueInLogScale(yValue, yScaleFactor) {\n let maxValue = this.dataRange.max;\n let minValue = this.dataRange.min;\n if (maxValue <= 0) return 0 // TODO:\n if (minValue <= -1) minValue = 0;\n minValue = (minValue <= 0) ? 0 : Math.log10(minValue + 1);\n maxValue = Math.log10(maxValue + 1);\n yValue = Math.log10(yValue + 1);\n return ((this.flipAxis ? (yValue - minValue) : (maxValue - yValue)) * yScaleFactor)\n }\n\n draw(options) {\n\n // const mergedFeatures = options.features // Array of feature arrays, 1 for each track\n const mergedFeatures = options.features;\n if(!mergedFeatures) return\n\n if (this.defaultScale) {\n if (this.signal_name == 'rd_snp') {\n this.dataRange = {\n min: this.config.min || this.dataRange.min || -2,\n max: this.config.max || this.dataRange.max || 6\n };\n } else if (this.signal_name == 'rd') {\n this.dataRange = {\n min: this.config.min || this.dataRange.min || 0,\n max: this.config.max || this.dataRange.max || 6\n };\n } else if (this.signal_name == 'snp') {\n this.dataRange = {\n min: this.config.min || this.dataRange.min || -2,\n max: this.config.max || this.dataRange.max || 0\n };\n }\n }\n\n if (this.autoscale) {\n this.dataRange = autoscale(options.referenceFrame.chr, mergedFeatures);\n }\n\n if(this.tracks) {\n for (let i = 0, len = this.tracks.length; i < len; i++) {\n const trackOptions = Object.assign({}, options);\n trackOptions.features = mergedFeatures[i];\n this.tracks[i].dataRange = this.dataRange;\n this.tracks[i].flipAxis = this.flipAxis;\n this.tracks[i].logScale = this.logScale;\n if (this.graphType) {\n this.tracks[i].graphType = this.graphType;\n }\n this.tracks[i].draw(trackOptions);\n }\n }\n\n // guides lines\n const scaleFactor = this.getScaleFactor(this.dataRange.min, this.dataRange.max, options.pixelHeight, this.logScale);\n const yScale = (yValue) => this.logScale\n ? this.computeYPixelValueInLogScale(yValue, scaleFactor)\n : this.computeYPixelValue(yValue, scaleFactor);\n\n // Draw guidelines\n if (this.config.hasOwnProperty('guideLines')) {\n for (let line of this.config.guideLines) {\n if (line.hasOwnProperty('color') && line.hasOwnProperty('y') && line.hasOwnProperty('dotted')) {\n let y = yScale(line.y);\n let props = {\n 'strokeStyle': line['color'],\n 'strokeWidth': 1\n };\n if (line['dotted']) IGVGraphics.dashedLine(options.context, 0, y, options.pixelWidth, y, 5, props);\n else IGVGraphics.strokeLine(options.context, 0, y, options.pixelWidth, y, props);\n }\n }\n }\n }\n\n popupData(clickState, features) {\n\n const featuresArray = features || clickState.viewport.cachedFeatures;\n\n if (featuresArray && featuresArray.length === this.tracks.length) {\n // Array of feature arrays, 1 for each track\n const popupData = [];\n for (let i = 0; i < this.tracks.length; i++) {\n if (i > 0) popupData.push('
');\n popupData.push(`
${this.tracks[i].name}
`);\n const trackPopupData = this.tracks[i].popupData(clickState, featuresArray[i]);\n popupData.push(...trackPopupData);\n\n }\n return popupData\n }\n }\n\n}\n\nfunction autoscale(chr, featureArrays) {\n\n let min = 0;\n let max = -Number.MAX_VALUE;\n for (let features of featureArrays) {\n for (let f of features) {\n if (typeof f.value !== 'undefined' && !Number.isNaN(f.value)) {\n min = Math.min(min, f.value);\n max = Math.max(max, f.value);\n }\n }\n }\n return {min: min, max: max}\n}\n\n//import CNVPytorTrack from \"./CNVpytor/cnvpytorTrack.js\"\n\n\nconst trackFunctions =\n new Map([\n ['ideogram', (config, browser) => new IdeogramTrack(config, browser)],\n ['sequence', (config, browser) => new SequenceTrack(config, browser)],\n ['feature', (config, browser) => new FeatureTrack(config, browser)],\n ['seg', (config, browser) => new SegTrack(config, browser)],\n ['mut', (config, browser) => new SegTrack(config, browser)],\n ['maf', (config, browser) => new SegTrack(config, browser)],\n ['wig', (config, browser) => new WigTrack(config, browser)],\n ['merged', (config, browser) => new MergedTrack(config, browser)],\n ['alignment', (config, browser) => new BAMTrack(config, browser)],\n ['interaction', (config, browser) => new InteractionTrack(config, browser)],\n ['interact', (config, browser) => new InteractionTrack(config, browser)],\n ['variant', (config, browser) => new VariantTrack(config, browser)],\n ['eqtl', (config, browser) => new EqtlTrack(config, browser)],\n ['gwas', (config, browser) => new GWASTrack(config, browser)],\n ['arc', (config, browser) => new RnaStructTrack(config, browser)],\n ['gcnv', (config, browser) => new GCNVTrack(config, browser)],\n ['junction', (config, browser) => new SpliceJunctionTrack(config, browser)],\n ['blat', (config, browser) => new BlatTrack(config, browser)],\n ['cnvpytor', (config, browser) => new CNVPytorTrack(config, browser)]\n ]);\n\n\n/**\n * Add a track constructor the the factory lookup table.\n *\n * @param type\n * @param track\n */\nconst addTrackCreatorFunction = function (type, track) {\n trackFunctions.set(type, track);\n};\n\nconst getTrack = function (type, config, browser) {\n\n let trackKey;\n switch (type) {\n case \"annotation\":\n case \"genes\":\n case \"fusionjuncspan\":\n case \"snp\":\n trackKey = \"feature\";\n break\n case 'seg':\n case 'maf':\n case 'mut':\n trackKey = 'seg';\n break\n case 'junctions':\n case 'splicejunctions':\n trackKey = 'junction';\n break\n default:\n trackKey = type;\n }\n\n return trackFunctions.has(trackKey) ?\n trackFunctions.get(trackKey)(config, browser) :\n undefined\n};\n\nvar TrackFactory = {\n tracks: trackFunctions,\n addTrack: addTrackCreatorFunction,\n trackFunctions,\n addTrackCreatorFunction,\n getTrack\n};\n\n/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2016-2017 The Regents of the University of California\n * Author: Jim Robinson\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\n\n/**\n * Minimal support for the legacy IGV desktop session format.\n */\n\nclass XMLSession {\n\n constructor(xmlString, knownGenomes) {\n\n const parser = new DOMParser();\n const xmlDoc = parser.parseFromString(xmlString, \"text/xml\");\n\n this.processRootNode(xmlDoc, knownGenomes);\n\n const resourceElements = xmlDoc.getElementsByTagName(\"Resource\");\n const trackElements = xmlDoc.getElementsByTagName(\"Track\");\n const hasTrackElements = trackElements && trackElements.length > 0;\n\n const tracks = [];\n this.tracks = tracks;\n\n const resourceMap = new Map();\n Array.from(resourceElements).forEach(function (r, idx) {\n var config = {\n url: r.getAttribute(\"path\"),\n indexURL: r.getAttribute(\"index\"),\n order: idx\n };\n resourceMap.set(config.url, config);\n if (!hasTrackElements) {\n tracks.push(config);\n }\n });\n\n // Check for optional Track section\n if (hasTrackElements) {\n\n Array.from(trackElements).forEach(function (track) {\n\n const subtracks = track.getElementsByTagName(\"Track\");\n\n if (subtracks && subtracks.length > 0) {\n\n const mergedTrack = {\n type: 'merged',\n tracks: []\n };\n extractTrackAttributes(track, mergedTrack);\n\n tracks.push(mergedTrack);\n\n Array.from(subtracks).forEach(function (t) {\n t.processed = true;\n const id = t.getAttribute(\"id\");\n const config = resourceMap.get(id);\n if (config) {\n mergedTrack.tracks.push(config);\n extractTrackAttributes(t, config);\n config.autoscale = false;\n mergedTrack.height = config.height;\n\n // Add alpha for merged track colors. Alpha is not recorded by IGV desktop in XML session\n //const color = t.getAttribute(\"color\");\n //if (color) {\n // config.color = \"rgba(\" + color + \",0.5)\";\n //}\n }\n });\n } else if (!track.processed) {\n\n const id = track.getAttribute(\"id\");\n const res = resourceMap.get(id);\n if (res) {\n tracks.push(res);\n extractTrackAttributes(track, res);\n }\n\n }\n });\n }\n }\n\n processRootNode(xmlDoc, knownGenomes) {\n\n const elements = xmlDoc.getElementsByTagName(\"Session\");\n if (!elements || elements.length === 0) ;\n const session = elements.item(0);\n const genome = session.getAttribute(\"genome\");\n const locus = session.getAttribute(\"locus\");\n const ucscID = session.getAttribute(\"ucscID\");\n\n if (knownGenomes && knownGenomes.hasOwnProperty(genome)) {\n this.genome = genome;\n\n } else {\n this.reference = {\n fastaURL: genome\n };\n if (ucscID) {\n this.reference.id = ucscID;\n }\n }\n if (locus) {\n this.locus = locus;\n }\n }\n\n}\n\n\nfunction extractTrackAttributes(track, config) {\n\n\n config.name = track.getAttribute(\"name\");\n\n const color = track.getAttribute(\"color\");\n if (color) {\n config.color = \"rgb(\" + color + \")\";\n }\n\n const altColor = track.getAttribute(\"altColor\");\n if (color) {\n config.altColor = \"rgb(\" + altColor + \")\";\n }\n\n const height = track.getAttribute(\"height\");\n if (height) {\n config.height = parseInt(height);\n }\n\n const autoScale = track.getAttribute(\"autoScale\");\n if (autoScale) {\n config.autoscale = (autoScale === \"true\");\n }\n\n const autoscaleGroup = track.getAttribute(\"autoscaleGroup\");\n if (autoscaleGroup) {\n config.autoscaleGroup = autoscaleGroup;\n }\n\n const windowFunction = track.getAttribute(\"windowFunction\");\n if (windowFunction) {\n config.windowFunction = windowFunction;\n }\n const visWindow = track.getAttribute(\"visibilityWindow\") || track.getAttribute(\"featureVisibilityWindow\");\n if (visWindow) {\n config.visibilityWindow = visWindow;\n }\n\n const indexed = track.getAttribute(\"indexed\");\n if (indexed) {\n config.indexed = (indexed === \"true\");\n }\n\n const normalize = track.getAttribute(\"normalize\");\n if (normalize) {\n config.normalize = normalize === \"true\";\n }\n\n const dataRangeCltn = track.getElementsByTagName(\"DataRange\");\n if (dataRangeCltn.length > 0) {\n const dataRange = dataRangeCltn.item(0);\n config.min = Number(dataRange.getAttribute(\"minimum\"));\n config.max = Number(dataRange.getAttribute(\"maximum\"));\n config.logScale = dataRange.getAttribute(\"type\") === \"LOG\";\n }\n}\n\n/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2014-2015 Broad Institute\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\nconst splitLines = splitLines$5;\n\nclass SampleInformation {\n constructor() {\n this.attributes = {};\n this.plinkLoaded = false;\n }\n\n async loadPlinkFile(url, config) {\n\n if (!config) config = {};\n\n var options = buildOptions(config); // Add oauth token, if any\n const data = await igvxhr.loadString(url, options);\n var lines = splitLines(data);\n\n for (let line of lines) {\n var line_arr = line.split(' ');\n this.attributes[line_arr[1]] = {\n familyId: line_arr[0],\n fatherId: line_arr[2],\n motherId: line_arr[3],\n sex: line_arr[4],\n phenotype: line_arr[5]\n };\n }\n this.plinkLoaded = true;\n return this\n }\n\n /**\n * Return the attributes for the given sample as a map-like object (key-value pairs)\n * @param sample\n */\n getAttributes(sample) {\n return this.attributes[sample]\n };\n\n getAttributeNames() {\n\n if (this.hasAttributes()) {\n return Object.keys(this.attributes[Object.keys(this.attributes)[0]])\n } else return []\n };\n\n hasAttributes() {\n return Object.keys(this.attributes).length > 0\n }\n}\n\nfunction loadPlinkFile(url, config) {\n const si = new SampleInformation();\n return si.loadPlinkFile(url, config)\n}\n\n/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2014 Broad Institute\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\nclass GtexSelection {\n\n constructor(gene, snp) {\n this.geneColors = {};\n this.gene = null;\n this.snp = null;\n this.genesCount = 0;\n\n if (gene) {\n this.gene = gene.toUpperCase();\n this.geneColors[this.gene] = brewer[this.genesCount++];\n\n }\n if (snp) {\n this.snp = snp.toUpperCase();\n }\n }\n\n addGene(geneName) {\n if (!this.geneColors[geneName.toUpperCase()]) {\n this.geneColors[geneName.toUpperCase()] = brewer[this.genesCount++];\n }\n }\n\n colorForGene(geneName) {\n return this.geneColors[geneName.toUpperCase()]\n }\n}\n\nvar brewer = [];\n// Set +!\nbrewer.push(\"rgb(228,26,28)\");\nbrewer.push(\"rgb(55,126,184)\");\nbrewer.push(\"rgb(77,175,74)\");\nbrewer.push(\"rgb(166,86,40)\");\nbrewer.push(\"rgb(152,78,163)\");\nbrewer.push(\"rgb(255,127,0)\");\nbrewer.push(\"rgb(247,129,191)\");\nbrewer.push(\"rgb(153,153,153)\");\nbrewer.push(\"rgb(255,255,51)\");\n\n// #Set 2\nbrewer.push(\"rgb(102, 194, 165\");\nbrewer.push(\"rgb(252, 141, 98\");\nbrewer.push(\"rgb(141, 160, 203\");\nbrewer.push(\"rgb(231, 138, 195\");\nbrewer.push(\"rgb(166, 216, 84\");\nbrewer.push(\"rgb(255, 217, 47\");\nbrewer.push(\"rgb(229, 196, 148\");\nbrewer.push(\"rgb(179, 179, 179\");\n\n//#Set 3\nbrewer.push(\"rgb( 141, 211, 199\");\nbrewer.push(\"rgb(255, 255, 179\");\nbrewer.push(\"rgb(190, 186, 218\");\nbrewer.push(\"rgb(251, 128, 114\");\nbrewer.push(\"rgb(128, 177, 211\");\nbrewer.push(\"rgb(253, 180, 98\");\nbrewer.push(\"rgb(179, 222, 105\");\nbrewer.push(\"rgb(252, 205, 229\");\nbrewer.push(\"rgb(217, 217, 217\");\nbrewer.push(\"rgb(188, 128, 189\");\nbrewer.push(\"rgb(204, 235, 197\");\nbrewer.push(\"rgb(255, 237, 111\");\n\n/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2014 Broad Institute\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\n// Reference frame classes. Converts domain coordinates (usually genomic) to pixel coordinates\n\nclass ReferenceFrame {\n\n constructor(genome, chr, start, end, bpPerPixel) {\n this.genome = genome;\n this.chr = chr;\n\n this.start = start;\n\n // TODO WARNING THIS IS NOT UPDATED !!!\n this.end = end;\n\n this.bpPerPixel = bpPerPixel;\n this.id = domUtils.guid();\n }\n\n /**\n * Extend this frame to accomodate the given locus. Used th CircularView methods to merge 2 frames.\n * @param locus\n */\n extend(locus) {\n const newStart = Math.min(locus.start, this.start);\n const newEnd = Math.max(locus.end, this.end);\n const ratio = (newEnd - newStart) / (this.end - this.start);\n this.start = newStart;\n this.end = newEnd;\n this.bpPerPixel *= ratio;\n }\n\n calculateEnd(pixels) {\n return this.start + this.bpPerPixel * pixels\n }\n\n calculateBPP(end, pixels) {\n return (end - this.start) / pixels\n }\n\n set(json) {\n this.chr = json.chr;\n this.start = json.start;\n this.bpPerPixel = json.bpPerPixel;\n }\n\n toPixels(bp) {\n return bp / this.bpPerPixel\n }\n\n toBP(pixels) {\n return this.bpPerPixel * pixels\n }\n\n /**\n * Shift frame by stated pixels. Return true if view changed, false if not.\n *\n * @param pixels\n * @param clamp -- if true \"clamp\" shift to prevent panning off edge of chromosome. This is disabled if \"show soft clipping\" is on\n * @param viewportWidth\n */\n shiftPixels(pixels, viewportWidth, clamp) {\n\n const currentStart = this.start;\n const deltaBP = pixels * this.bpPerPixel;\n\n this.start += deltaBP;\n\n if(clamp) {\n this.clampStart(viewportWidth);\n }\n\n this.end = this.start + viewportWidth * this.bpPerPixel;\n\n return currentStart !== this.start\n }\n\n clampStart(viewportWidth) {\n // clamp left\n const min = (this.genome.getChromosome(this.chr).bpStart || 0);\n this.start = Math.max(min, this.start);\n\n // clamp right\n if (viewportWidth) {\n\n const {bpLength} = this.genome.getChromosome(this.chr);\n const maxStart = bpLength - (viewportWidth * this.bpPerPixel);\n\n if (this.start > maxStart) {\n this.start = maxStart;\n }\n }\n }\n\n async zoomWithScaleFactor(browser, scaleFactor, viewportWidth, centerBPOrUndefined) {\n\n const centerBP = undefined === centerBPOrUndefined ? (this.start + this.toBP(viewportWidth / 2.0)) : centerBPOrUndefined;\n\n // save initial start and bpp\n const {start, bpPerPixel} = this.start;\n\n const {bpLength} = this.getChromosome();\n const bppThreshold = scaleFactor < 1.0 ? browser.minimumBases() / viewportWidth : bpLength / viewportWidth;\n\n // update bpp\n if (scaleFactor < 1.0) {\n this.bpPerPixel = Math.max(this.bpPerPixel * scaleFactor, bppThreshold);\n } else {\n this.bpPerPixel = Math.min(this.bpPerPixel * scaleFactor, bppThreshold);\n }\n\n // update start and end\n const widthBP = this.bpPerPixel * viewportWidth;\n this.start = centerBP - 0.5 * widthBP;\n this.clampStart(viewportWidth);\n\n this.end = this.start + widthBP;\n\n const viewChanged = start !== this.start || bpPerPixel !== this.bpPerPixel;\n if (viewChanged) {\n await browser.updateViews(true);\n }\n\n }\n\n getChromosome() {\n return this.genome.getChromosome(this.chr)\n }\n\n getMultiLocusLabelBPLengthOnly(pixels) {\n const margin = ' ';\n const ss = Math.floor(this.start) + 1;\n const ee = Math.round(this.start + this.bpPerPixel * pixels);\n return `${margin}${this.chr}${margin}${prettyBasePairNumber(ee - ss)}${margin}`\n }\n\n getMultiLocusLabelLocusOnly(pixels) {\n const margin = ' ';\n const {chr, start, end } = this.getPresentationLocusComponents(pixels);\n return `${margin}${chr}:${start}-${end}${margin}`\n }\n\n getMultiLocusLabel(pixels) {\n const margin = ' ';\n const {chr, start, end } = this.getPresentationLocusComponents(pixels);\n const ss = Math.floor(this.start) + 1;\n const ee = Math.round(this.start + this.bpPerPixel * pixels);\n return `${margin}${chr}:${start}-${end}${margin}${margin}(${prettyBasePairNumber(ee - ss)})${margin}`\n }\n\n getPresentationLocusComponents(pixels) {\n\n if ('all' === this.chr) {\n return {chr: this.chr}\n } else {\n const ss = numberFormatter$1(Math.floor(this.start) + 1);\n const ee = numberFormatter$1(Math.round(this.start + this.bpPerPixel * pixels));\n\n return {chr: this.chr, start: ss, end: ee}\n }\n\n }\n\n getLocusString() {\n if ('all' === this.chr) {\n return 'all'\n } else {\n const ss = numberFormatter$1(Math.floor(this.start) + 1);\n const ee = numberFormatter$1(Math.round(this.end));\n return `${this.chr}:${ss}-${ee}`\n }\n }\n\n description(blurb) {\n console.log(` ${blurb || ''} referenceFrame - ${this.chr} bpp ${this.bpPerPixel.toFixed(3)} start ${numberFormatter$1(Math.round(this.start))} end ${numberFormatter$1(Math.round(this.end))} `);\n }\n}\n\nfunction createReferenceFrameList(loci, genome, browserFlanking, minimumBases, viewportWidth, isSoftclipped) {\n\n return loci.map(locus => {\n\n // If a flanking region is defined, and the search object is a symbol (\"gene\") type, adjust start and end\n if (browserFlanking && locus.gene) {\n locus.start = Math.max(0, locus.start - browserFlanking);\n locus.end += browserFlanking;\n }\n\n // Validate the range. This potentionally modifies start & end of locus.\n if(!isSoftclipped) {\n const chromosome = genome.getChromosome(locus.chr);\n validateGenomicExtent(chromosome.bpLength, locus, minimumBases);\n }\n\n const referenceFrame = new ReferenceFrame(genome,\n locus.chr,\n locus.start,\n locus.end,\n (locus.end - locus.start) / viewportWidth);\n\n referenceFrame.locusSearchString = locus.locusSearchString;\n\n // GTEX hack\n if (locus.gene || locus.snp) {\n referenceFrame.selection = new GtexSelection(locus.gene, locus.snp);\n }\n\n return referenceFrame\n })\n}\n\nconst DEFAULT_SEARCH_CONFIG = {\n timeout: 5000,\n type: \"plain\", // Legacy plain text support -- deprecated\n url: 'https://igv.org/genomes/locus.php?genome=$GENOME$&name=$FEATURE$',\n coords: 0,\n chromosomeField: \"chromosome\",\n startField: \"start\",\n endField: \"end\",\n geneField: \"gene\",\n snpField: \"snp\"\n};\n\n/**\n * Return an object representing the locus of the given string. Object is of the form\n * {\n * chr,\n * start,\n * end,\n * locusSearchString,\n * gene,\n * snp\n * }\n * @param browser\n * @param string\n * @returns {Promise<*>}\n */\nasync function search(browser, string) {\n\n if (undefined === string || '' === string.trim()) {\n return\n }\n\n if (string && string.trim().toLowerCase() === \"all\" || string === \"*\") {\n string = \"all\";\n }\n\n const loci = string.split(' ');\n\n let searchConfig = browser.searchConfig || DEFAULT_SEARCH_CONFIG;\n let list = [];\n\n const searchLocus = async (locus) => {\n let locusObject = parseLocusString(browser, locus);\n\n if (!locusObject) {\n const feature = browser.genome.featureDB.get(locus.toUpperCase());\n if (feature) {\n locusObject = {\n chr: feature.chr,\n start: feature.start,\n end: feature.end,\n gene: feature.name,\n locusSearchString: string\n };\n }\n }\n\n if (!locusObject && (browser.config && false !== browser.config.search)) {\n try {\n locusObject = await searchWebService(browser, locus, searchConfig);\n } catch (error) {\n console.error(error);\n throw Error(\"Search service currently unavailable.\")\n }\n }\n return locusObject\n };\n\n for (let locus of loci) {\n const locusObject = await searchLocus(locus);\n if (locusObject) {\n locusObject.locusSearchString = locus;\n list.push(locusObject);\n }\n }\n\n // If nothing is found, consider possibility that loci name itself has spaces\n if (list.length === 0) {\n const locusObject = await searchLocus(string);\n if (locusObject) {\n locusObject.locusSearchString = string;\n list.push(locusObject);\n }\n }\n\n\n return 0 === list.length ? undefined : list\n}\n\nfunction parseLocusString(browser, locus) {\n\n // Check for tab delimited locus string\n const tabTokens = locus.split('\\t');\n if (tabTokens.length >= 3) {\n // Possibly a tab-delimited locus\n try {\n const chr = browser.genome.getChromosomeName(tabTokens[0]);\n const start = parseInt(tabTokens[1].replace(/,/g, ''), 10) - 1;\n const end = parseInt(tabTokens[2].replace(/,/g, ''), 10);\n if (!isNaN(start) && !isNaN(end)) {\n return {chr, start, end}\n }\n } catch (e) {\n // Not a tab delimited locus, apparently, but not really an error as that was a guess\n }\n\n }\n\n const a = locus.split(':');\n const chr = a[0];\n if ('all' === chr && browser.genome.getChromosome(chr)) {\n return {chr, start: 0, end: browser.genome.getChromosome(chr).bpLength}\n\n } else if (undefined === browser.genome.getChromosome(chr)) {\n return undefined\n\n } else {\n const queryChr = browser.genome.getChromosomeName(chr);\n const extent = {\n chr: queryChr,\n start: 0,\n end: browser.genome.getChromosome(chr).bpLength\n };\n\n if (a.length > 1) {\n\n let b = a[1].split('-');\n if (b.length > 2) {\n // Allow for negative coordinates, which is possible if showing alignment soft clips\n if (a[1].startsWith('-')) {\n const i = a[1].indexOf('-', 1);\n if (i > 0) {\n const t1 = a[1].substring(0, i);\n const t2 = a[1].substring(i + 1);\n b = [t1, t2];\n }\n } else {\n return undefined\n }\n\n }\n\n let numeric;\n numeric = b[0].replace(/,/g, '');\n if (isNaN(numeric)) {\n return undefined\n }\n\n extent.start = parseInt(numeric, 10) - 1;\n extent.end = extent.start + 1;\n\n if (1 === b.length) {\n // Don't clamp coordinates if single coordinate is supplied.\n extent.start -= 20;\n extent.end += 20;\n }\n\n if (2 === b.length) {\n numeric = b[1].replace(/,/g, '');\n if (isNaN(numeric)) {\n return undefined\n } else {\n extent.end = parseInt(numeric, 10);\n }\n\n // Allow negative coordinates only if browser is softclipped, i.e. there is at least alignment track with softclipping on\n if (extent.start < 0 && !browser.isSoftclipped()) {\n const delta = -extent.start;\n extent.start += delta;\n extent.end += delta;\n }\n }\n }\n\n return extent\n }\n}\n\nasync function searchWebService(browser, locus, searchConfig) {\n\n let path = searchConfig.url.replace(\"$FEATURE$\", locus.toUpperCase());\n if (path.indexOf(\"$GENOME$\") > -1) {\n path = path.replace(\"$GENOME$\", (browser.genome.id ? browser.genome.id : \"hg19\"));\n }\n const options = searchConfig.timeout ? {timeout: searchConfig.timeout} : undefined;\n const result = await igvxhr.loadString(path, options);\n\n const locusObject = processSearchResult(browser, result, searchConfig);\n if (locusObject) {\n locusObject.locusSearchString = locus;\n }\n return locusObject\n}\n\nfunction processSearchResult(browser, result, searchConfig) {\n\n let results;\n\n if ('plain' === searchConfig.type) {\n results = parseSearchResults(browser, result);\n } else {\n results = JSON.parse(result);\n }\n\n if (searchConfig.resultsField) {\n results = results[searchConfig.resultsField];\n }\n\n if (!results || 0 === results.length) {\n return undefined\n\n } else {\n\n const chromosomeField = searchConfig.chromosomeField || \"chromosome\";\n const startField = searchConfig.startField || \"start\";\n const endField = searchConfig.endField || \"end\";\n const coords = searchConfig.coords || 1;\n\n\n let result;\n if (Array.isArray(results)) {\n // Ignoring all but first result for now\n // TODO -- present all and let user select if results.length > 1\n result = results[0];\n } else {\n // When processing search results from Ensembl REST API\n // Example: https://rest.ensembl.org/lookup/symbol/macaca_fascicularis/BRCA2?content-type=application/json\n result = results;\n }\n\n if (!(result.hasOwnProperty(chromosomeField) && (result.hasOwnProperty(startField)))) {\n console.error(\"Search service results must include chromosome and start fields: \" + result);\n }\n\n const chrResult = result[chromosomeField];\n const chromosome = browser.genome.getChromosome(chrResult);\n if (!chromosome) {\n return undefined\n }\n const chr = chromosome.name;\n\n let start = result[startField] - coords;\n let end = result[endField];\n if (undefined === end) {\n end = start + 1;\n }\n\n const locusObject = {chr, start, end};\n\n // Some GTEX hacks\n const type = result.type ? result.type : \"gene\";\n if (searchConfig.geneField && type === \"gene\") {\n locusObject.gene = result[searchConfig.geneField];\n }\n if (searchConfig.snpField && type === \"snp\") {\n locusObject.snp = result[searchConfig.snpField];\n }\n\n return locusObject\n }\n}\n\n/**\n * Parse the igv line-oriented (non json) search results.\n * Example\n * EGFR chr7:55,086,724-55,275,031 refseq\n *\n */\nfunction parseSearchResults(browser, data) {\n\n const linesTrimmed = [];\n const results = [];\n const lines = splitLines$5(data);\n\n lines.forEach(function (item) {\n if (\"\" === item) ; else {\n linesTrimmed.push(item);\n }\n });\n\n linesTrimmed.forEach(function (line) {\n\n var tokens = line.split(\"\\t\"),\n source,\n locusTokens,\n rangeTokens,\n obj;\n\n if (tokens.length >= 3) {\n\n locusTokens = tokens[1].split(\":\");\n rangeTokens = locusTokens[1].split(\"-\");\n source = tokens[2].trim();\n\n obj =\n {\n gene: tokens[0],\n chromosome: browser.genome.getChromosomeName(locusTokens[0].trim()),\n start: parseInt(rangeTokens[0].replace(/,/g, '')),\n end: parseInt(rangeTokens[1].replace(/,/g, '')),\n type: (\"gtex\" === source ? \"snp\" : \"gene\")\n };\n\n results.push(obj);\n\n }\n\n });\n\n return results\n\n}\n\n/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2014 Broad Institute\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\nclass NavbarManager {\n\n constructor(browser) {\n this.browser = browser;\n }\n\n navbarDidResize(width) {\n this.updateNavbar(this.createResponsiveClassSchedule(width));\n }\n\n updateNavbar(responsiveClassSchedule) {\n\n this.browser.$toggle_button_container.removeClass();\n this.browser.$toggle_button_container.addClass(responsiveClassSchedule.$toggle_button_container);\n\n $$1(this.browser.zoomWidget.zoomContainer).removeClass();\n $$1(this.browser.zoomWidget.zoomContainer).addClass(responsiveClassSchedule.zoomContainer);\n }\n\n createResponsiveClassSchedule(navbarWidth) {\n\n let candidates = {};\n\n const isWGV = this.browser.isMultiLocusWholeGenomeView() ||\n (this.browser.referenceFrameList &&\n GenomeUtils.isWholeGenomeView(this.browser.referenceFrameList[0].chr));\n\n\n if (isWGV) {\n this.browser.windowSizePanel.hide();\n } else {\n this.browser.windowSizePanel.show();\n }\n\n if (navbarWidth > 990) {\n candidates.$toggle_button_container = 'igv-navbar-toggle-button-container';\n candidates.zoomContainer = 'igv-zoom-widget';\n } else if (navbarWidth > 860) {\n candidates.$toggle_button_container = 'igv-navbar-toggle-button-container';\n candidates.zoomContainer = 'igv-zoom-widget-900';\n } else if (navbarWidth > 540) {\n candidates.$toggle_button_container = 'igv-navbar-toggle-button-container-750';\n candidates.zoomContainer = 'igv-zoom-widget-900';\n } else {\n candidates.$toggle_button_container = 'igv-navbar-toggle-button-container-750';\n candidates.zoomContainer = 'igv-zoom-widget-900';\n this.browser.windowSizePanel.hide();\n }\n\n if (isWGV) {\n candidates['zoomContainer'] = 'igv-zoom-widget-hidden';\n }\n\n return candidates\n }\n}\n\n/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2016-2017 The Regents of the University of California\n * Author: Jim Robinson\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\nconst ChromosomeSelectWidget = function (browser, parent) {\n\n this.container = domUtils.div({class: 'igv-chromosome-select-widget-container'});\n parent.appendChild(this.container);\n\n this.select = document.createElement('select');\n this.select.setAttribute('name', 'chromosome-select-widget');\n this.container.appendChild(this.select);\n\n this.select.addEventListener('change', () => {\n this.select.blur();\n if (this.select.value !== '') {\n browser.search(this.select.value);\n }\n });\n\n this.showAllChromosomes = browser.config.showAllChromosomes !== false; // i.e. default to true\n\n};\n\nChromosomeSelectWidget.prototype.show = function () {\n this.container.style.display = 'flex';\n};\n\nChromosomeSelectWidget.prototype.hide = function () {\n this.container.style.display = 'none';\n};\n\nChromosomeSelectWidget.prototype.update = function (genome) {\n\n const list = this.showAllChromosomes ? genome.chromosomeNames.slice() : genome.wgChromosomeNames.slice();\n // console.log(`${ this.showAllChromosomes ? 'Do' : 'Do not'} show all chromosomes. List ${ list }`)\n\n if (genome.showWholeGenomeView()) {\n list.unshift('all');\n list.unshift('');\n }\n\n this.select.innerHTML = '';\n\n for (let name of list) {\n const option = document.createElement('option');\n option.setAttribute('value', name);\n option.innerText = name;\n this.select.appendChild(option);\n }\n\n};\n\n/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2014 Broad Institute\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\nclass WindowSizePanel {\n constructor(parent, browser) {\n\n this.container = domUtils.div({class: 'igv-windowsize-panel-container'});\n parent.appendChild(this.container);\n\n browser.on('locuschange', (referenceFrameList) => {\n this.updatePanel(referenceFrameList);\n });\n\n this.browser = browser;\n\n }\n\n show() {\n this.container.style.display = 'block';\n }\n\n hide() {\n this.container.style.display = 'none';\n }\n\n updatePanel(referenceFrameList) {\n const width = this.browser.calculateViewportWidth(this.browser.referenceFrameList.length);\n this.container.innerText = 1 === referenceFrameList.length ? prettyBasePairNumber(Math.round(width * referenceFrameList[0].bpPerPixel)) : '';\n }\n}\n\nclass CursorGuide {\n\n constructor(columnContainer, browser) {\n this.browser = browser;\n this.columnContainer = columnContainer;\n\n this.horizontalGuide = domUtils.div({class: 'igv-cursor-guide-horizontal'});\n columnContainer.appendChild(this.horizontalGuide);\n\n this.verticalGuide = domUtils.div({class: 'igv-cursor-guide-vertical'});\n columnContainer.appendChild(this.verticalGuide);\n\n this.addMouseHandler(browser);\n\n this.setVisibility(browser.config.showCursorGuide);\n\n }\n\n addMouseHandler(browser) {\n\n this.boundMouseMoveHandler = mouseMoveHandler.bind(this);\n this.columnContainer.addEventListener('mousemove', this.boundMouseMoveHandler);\n\n function mouseMoveHandler(event) {\n\n const {x, y} = domUtils.translateMouseCoordinates(event, this.columnContainer);\n this.horizontalGuide.style.top = `${y}px`;\n\n const target = document.elementFromPoint(event.clientX, event.clientY);\n\n const viewport = findAncestorOfClass(target, 'igv-viewport');\n\n if (viewport && browser.getRulerTrackView()) {\n\n this.verticalGuide.style.left = `${x}px`;\n\n const columns = browser.root.querySelectorAll('.igv-column');\n let index = undefined;\n const viewportParent = viewport.parentElement;\n for (let i = 0; i < columns.length; i++) {\n if (undefined === index && viewportParent === columns[i]) {\n index = i;\n }\n }\n\n const rulerViewport = browser.getRulerTrackView().viewports[index];\n const result = rulerViewport.mouseMove(event);\n\n if (result) {\n\n const {start, bp, end} = result;\n const interpolant = (bp - start) / (end - start);\n\n if (this.customMouseHandler) {\n this.customMouseHandler({start, bp, end, interpolant});\n }\n }\n }\n\n }\n }\n\n removeMouseHandler() {\n this.columnContainer.removeEventListener('mousemove', this.boundMouseMoveHandler);\n }\n\n setVisibility(showCursorGuide) {\n if (true === showCursorGuide) {\n this.show();\n } else {\n this.hide();\n }\n }\n\n show() {\n this.verticalGuide.style.display = 'block';\n this.horizontalGuide.style.display = 'block';\n\n }\n\n hide() {\n\n this.verticalGuide.style.display = 'none';\n this.horizontalGuide.style.display = 'none';\n\n if (this.browser.getRulerTrackView()) {\n for (let viewport of this.browser.getRulerTrackView().viewports) {\n viewport.$tooltip.hide();\n }\n }\n\n }\n\n}\n\n/**\n * Walk up the tree until a parent is found with the given classname. If no ancestor is found return undefined.\n * @param target\n * @param classname\n * @returns {*}\n */\nfunction findAncestorOfClass(target, classname) {\n\n while (target.parentElement) {\n if (target.parentElement.classList.contains(classname)) {\n return target.parentElement\n } else {\n target = target.parentElement;\n }\n }\n return undefined\n\n}\n\n/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2016 University of California San Diego\n * Author: Jim Robinson\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\nclass CursorGuideButton {\n\n constructor(browser, parent) {\n\n this.browser = browser;\n\n this.button = domUtils.div({class: 'igv-navbar-button'});\n parent.appendChild(this.button);\n\n this.button.textContent = 'cursor guide';\n\n this.button.addEventListener('click', () => {\n browser.cursorGuideVisible = !browser.cursorGuideVisible;\n browser.setCursorGuideVisibility(browser.cursorGuideVisible);\n this.setButtonState(browser.cursorGuideVisible);\n });\n\n this.setButtonState(browser.cursorGuideVisible);\n\n if (browser.config.showCursorTrackingGuideButton) {\n this.show();\n } else {\n this.hide();\n }\n\n }\n\n setButtonState(cursorGuideVisible) {\n if (true === cursorGuideVisible) {\n this.button.classList.add('igv-navbar-button-clicked');\n } else {\n this.button.classList.remove('igv-navbar-button-clicked');\n }\n }\n\n show() {\n this.button.style.display = 'block';\n this.setButtonState(this.browser.cursorGuideVisible);\n }\n\n hide() {\n this.button.style.display = 'none';\n }\n}\n\nclass CenterLineButton {\n\n constructor(browser, parent) {\n\n this.browser = browser;\n\n this.button = domUtils.div({class: 'igv-navbar-button'});\n parent.appendChild(this.button);\n\n this.button.textContent = 'center line';\n\n this.button.addEventListener('click', () => {\n browser.isCenterLineVisible = !browser.isCenterLineVisible;\n browser.setCenterLineVisibility(browser.isCenterLineVisible);\n this.setButtonState(browser.isCenterLineVisible);\n });\n\n this.setButtonState(browser.isCenterLineVisible);\n\n if (browser.config.showCenterGuideButton) {\n this.show();\n } else {\n this.hide();\n }\n }\n\n setButtonState(isCenterLineVisible) {\n if (true === isCenterLineVisible) {\n this.button.classList.add('igv-navbar-button-clicked');\n } else {\n this.button.classList.remove('igv-navbar-button-clicked');\n }\n }\n\n show() {\n this.isVisible = true;\n this.button.style.display = 'block';\n this.setButtonState(this.browser.isCenterLineVisible);\n }\n\n hide() {\n this.isVisible = false;\n this.button.style.display = 'none';\n }\n}\n\n/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2016 University of California San Diego\n * Author: Jim Robinson\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\nclass TrackLabelControl {\n\n constructor(parent, browser) {\n\n this.button = domUtils.div({class: 'igv-navbar-button'});\n parent.appendChild(this.button);\n this.button.textContent = 'track labels';\n\n this.button.addEventListener('click', () => {\n browser.trackLabelsVisible = !browser.trackLabelsVisible;\n this.setState(browser.trackLabelsVisible);\n browser.setTrackLabelVisibility(browser.trackLabelsVisible);\n });\n\n this.browser = browser;\n\n this.setVisibility(browser.config.showTrackLabelButton);\n\n this.setState(browser.trackLabelsVisible);\n }\n\n setVisibility(showTrackLabelButton) {\n if (true === showTrackLabelButton) {\n this.show();\n } else {\n this.hide();\n }\n }\n\n setState(trackLabelsVisible) {\n if (true === trackLabelsVisible) {\n this.button.classList.add('igv-navbar-button-clicked');\n } else {\n this.button.classList.remove('igv-navbar-button-clicked');\n }\n }\n\n show() {\n this.button.style.display = 'block';\n this.setState(this.browser.trackLabelsVisible);\n }\n\n hide() {\n this.button.style.display = 'none';\n }\n}\n\n/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2016 University of California San Diego\n * Author: Jim Robinson\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\nclass SampleNameControl {\n\n constructor(parent, browser) {\n\n this.button = domUtils.div({class: 'igv-navbar-button'});\n parent.appendChild(this.button);\n\n this.button.innerText = 'Sample Names';\n\n this.setState(browser.showSampleNames);\n\n this.setVisibility(browser.showSampleNameButton);\n\n this.button.addEventListener('click', () => {\n\n browser.showSampleNames = !browser.showSampleNames;\n\n this.setState(browser.showSampleNames);\n\n for (let {sampleNameViewport} of browser.trackViews) {\n if (false === browser.showSampleNames) {\n sampleNameViewport.hide();\n } else {\n sampleNameViewport.show();\n }\n }\n\n browser.layoutChange();\n\n\n });\n\n }\n\n setVisibility(showSampleNameButton) {\n\n if (true === showSampleNameButton) {\n this.show();\n } else {\n this.hide();\n }\n }\n\n setState(showSampleNames) {\n if (true === showSampleNames) {\n this.button.classList.add('igv-navbar-button-clicked');\n } else {\n this.button.classList.remove('igv-navbar-button-clicked');\n }\n }\n\n hide() {\n this.button.style.display = 'none';\n }\n\n show() {\n this.button.style.display = 'block';\n }\n\n}\n\nconst sliderMin = 0;\nlet sliderMax = 23;\nlet sliderValueRaw = 0;\n\nconst ZoomWidget = function (browser, parent) {\n\n this.browser = browser;\n\n this.zoomContainer = domUtils.div({class: 'igv-zoom-widget'});\n parent.appendChild(this.zoomContainer);\n\n // zoom out\n this.zoomOutButton = domUtils.div();\n this.zoomContainer.appendChild(this.zoomOutButton);\n this.zoomOutButton.appendChild(icons$1.createIcon('minus-circle'));\n this.zoomOutButton.addEventListener('click', () => {\n // browser.zoomWithScaleFactor(2.0)\n browser.zoomOut();\n });\n\n // Range slider\n const el = domUtils.div();\n this.zoomContainer.appendChild(el);\n this.slider = document.createElement('input');\n this.slider.type = 'range';\n\n this.slider.min = `${sliderMin}`;\n this.slider.max = `${sliderMax}`;\n\n el.appendChild(this.slider);\n\n this.slider.addEventListener('change', e => {\n\n e.preventDefault();\n e.stopPropagation();\n\n const referenceFrame = browser.referenceFrameList[0];\n const {bpLength} = referenceFrame.genome.getChromosome(referenceFrame.chr);\n const {end, start} = referenceFrame;\n\n const extent = end - start;\n\n // bpLength/(end - start)\n const scaleFactor = Math.pow(2, e.target.valueAsNumber);\n\n // (end - start) = bpLength/scaleFactor\n const zoomedExtent = bpLength / scaleFactor;\n\n // console.log(`zoom-widget - slider ${ e.target.value } scaleFactor ${ scaleFactor } extent-zoomed ${ StringUtils.numberFormatter(Math.round(zoomedExtent)) }`)\n\n browser.zoomWithScaleFactor(zoomedExtent / extent);\n\n });\n\n // zoom in\n this.zoomInButton = domUtils.div();\n this.zoomContainer.appendChild(this.zoomInButton);\n this.zoomInButton.appendChild(icons$1.createIcon('plus-circle'));\n this.zoomInButton.addEventListener('click', () => {\n // browser.zoomWithScaleFactor(0.5)\n browser.zoomIn();\n });\n\n browser.on('locuschange', (referenceFrameList) => {\n\n if (this.browser.isMultiLocusMode()) {\n this.disable();\n } else {\n this.enable();\n this.update(referenceFrameList);\n }\n\n });\n\n};\n\nZoomWidget.prototype.update = function (referenceFrameList) {\n\n const referenceFrame = referenceFrameList[0];\n const {bpLength} = referenceFrame.genome.getChromosome(referenceFrame.chr);\n const {start, end} = referenceFrame;\n\n sliderMax = Math.ceil(Math.log2(bpLength / this.browser.minimumBases()));\n\n this.slider.max = `${sliderMax}`;\n\n const scaleFactor = bpLength / (end - start);\n sliderValueRaw = Math.log2(scaleFactor);\n this.slider.value = `${Math.round(sliderValueRaw)}`;\n\n // referenceFrame.description('zoom.update')\n\n // console.log(`${ Date.now() } update - slider ${ this.slider.value } scaleFactor ${ Math.round(scaleFactor) } extent ${ StringUtils.numberFormatter(Math.round(extent)) }`)\n\n // console.log(`update - sliderMin ${ sliderMin } sliderValue ${ this.slider.value } sliderMax ${ sliderMax } scaleFactor ${ scaleFactor.toFixed(3) } derived-scaleFactor ${ derivedScalefactor.toFixed(3) }`)\n\n};\n\nZoomWidget.prototype.enable = function () {\n\n // this.zoomInButton.style.color = appleCrayonPalette[ 'steel' ];\n // this.zoomInButton.style.pointerEvents = 'auto';\n //\n // this.zoomOutButton.style.color = appleCrayonPalette[ 'steel' ];\n // this.zoomOutButton.style.pointerEvents = 'auto';\n\n this.slider.disabled = false;\n};\n\nZoomWidget.prototype.disable = function () {\n\n // this.zoomInButton.style.color = appleCrayonPalette[ 'silver' ];\n // this.zoomInButton.style.pointerEvents = 'none';\n //\n // this.zoomOutButton.style.color = appleCrayonPalette[ 'silver' ];\n // this.zoomOutButton.style.pointerEvents = 'none';\n\n this.slider.disabled = true;\n};\n\nZoomWidget.prototype.hide = function () {\n this.zoomContainer.style.display = 'none';\n};\n\nZoomWidget.prototype.show = function () {\n this.zoomContainer.style.display = 'block';\n};\n\nZoomWidget.prototype.hideSlider = function () {\n this.slider.style.display = 'none';\n};\n\nZoomWidget.prototype.showSlider = function () {\n this.slider.style.display = 'block';\n};\n\n/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2016 University of California San Diego\n * Author: Jim Robinson\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\nconst SVGSaveControl = function (parent, browser) {\n const button = domUtils.div({class: 'igv-navbar-button'});\n parent.append(button);\n\n button.textContent = 'Save SVG';\n button.addEventListener('click', () => browser.saveSVGtoFile({}));\n};\n\nconst viewportColumnManager =\n {\n createColumns: (columnContainer, count) => {\n\n for (let i = 0; i < count; i++) {\n if (0 === i) {\n createColumn(columnContainer, 'igv-column');\n } else {\n columnContainer.appendChild(domUtils.div({class: 'igv-column-shim'}));\n createColumn(columnContainer, 'igv-column');\n }\n }\n\n },\n\n removeColumnAtIndex: (i, column) => {\n const shim = 0 === i ? column.nextElementSibling : column.previousElementSibling;\n column.remove();\n shim.remove();\n },\n\n insertAfter: referenceElement => {\n\n const shim = domUtils.div({class: 'igv-column-shim'});\n insertElementAfter(shim, referenceElement);\n\n const column = domUtils.div({class: 'igv-column'});\n insertElementAfter(column, shim);\n\n return column\n },\n\n insertBefore: (referenceElement, count) => {\n\n for (let i = 0; i < count; i++) {\n\n const column = domUtils.div({class: 'igv-column'});\n insertElementBefore(column, referenceElement);\n\n if (count > 1 && i > 0) {\n const columnShim = domUtils.div({class: 'igv-column-shim'});\n insertElementBefore(columnShim, column);\n }\n\n }\n\n },\n\n indexOfColumn: (columnContainer, column) => {\n\n const allColumns = columnContainer.querySelectorAll('.igv-column');\n\n for (let i = 0; i < allColumns.length; i++) {\n const c = allColumns[ i ];\n if (c === column) {\n return i\n }\n }\n\n return undefined\n },\n };\n\n/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2016 University of California San Diego\n * Author: Jim Robinson\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\nclass ViewportCenterLine {\n\n constructor(browser, referenceFrame, column) {\n\n this.browser = browser;\n this.referenceFrame = referenceFrame;\n this.column = column;\n\n this.container = domUtils.div({class: 'igv-center-line'});\n column.appendChild(this.container);\n\n if (browser.isCenterLineVisible) {\n this.show();\n } else {\n this.hide();\n }\n }\n\n repaint() {\n\n if (this.referenceFrame) {\n\n const ppb = 1.0 / this.referenceFrame.bpPerPixel;\n if (ppb > 1) {\n const width = Math.floor(this.referenceFrame.toPixels(1));\n this.container.style.width = `${width}px`;\n this.container.classList.remove('igv-center-line-thin');\n this.container.classList.add('igv-center-line-wide');\n } else {\n this.container.style.width = '1px';\n this.container.classList.remove('igv-center-line-wide');\n this.container.classList.add('igv-center-line-thin');\n }\n }\n }\n\n show() {\n this.isVisible = true;\n this.container.style.display = 'block';\n this.repaint();\n }\n\n hide() {\n this.isVisible = false;\n this.container.style.display = 'none';\n }\n\n resize() {\n this.repaint();\n }\n}\n\n/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2014 Broad Institute\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\nconst numberFormatter = numberFormatter$1;\n\nclass RulerTrack {\n constructor(browser) {\n\n this.browser = browser;\n this.height = 40;\n this.name = \"\";\n this.id = \"ruler\";\n this.disableButtons = true;\n this.ignoreTrackMenu = true;\n this.order = Number.MIN_SAFE_INTEGER * 1e-2;\n this.removable = false;\n this.type = 'ruler';\n }\n\n async getFeatures(chr, start, end) {\n return []\n };\n\n computePixelHeight(ignore) {\n return this.height\n };\n\n draw({context, referenceFrame, pixelWidth, pixelHeight, bpPerPixel, bpStart}) {\n\n if (GenomeUtils.isWholeGenomeView(referenceFrame.chr)) {\n this.drawWholeGenome({context, pixelWidth, pixelHeight, bpPerPixel});\n } else {\n this.doDraw({context, referenceFrame, pixelWidth, pixelHeight, bpStart});\n }\n }\n\n drawWholeGenome({context, pixelWidth, pixelHeight, bpPerPixel}) {\n\n context.save();\n\n IGVGraphics.fillRect(context, 0, 0, pixelWidth, pixelHeight, {'fillStyle': 'white'});\n\n for (let name of this.browser.genome.wgChromosomeNames) {\n\n let xBP = this.browser.genome.getCumulativeOffset(name);\n let wBP = this.browser.genome.getChromosome(name).bpLength;\n\n let x = Math.round(xBP / bpPerPixel);\n let w = Math.round(wBP / bpPerPixel);\n\n this.renderChromosomeRect(context, x, 0, w, pixelHeight, name);\n }\n\n context.restore();\n\n }\n\n doDraw({context, referenceFrame, pixelWidth, pixelHeight, bpStart}) {\n\n context.clearRect(0, 0, pixelWidth, pixelHeight);\n\n const tickHeight = 6;\n const shim = 2;\n\n const bpLength = Math.floor(referenceFrame.toBP(pixelWidth));\n const tick = findSpacing(bpLength, context.isSVG);\n\n let nTick = Math.floor(bpStart / tick.majorTick) - 1;\n\n const {tickDelta, labelLength} = calculateDeltas(context, referenceFrame, bpStart, nTick, tick);\n\n this.browser.referenceFrameList.indexOf(referenceFrame);\n // console.log(`ruler(${ index }) label-length ${ labelLength > tickDelta ? 'clobbers' : 'less than' } tick-delta ${ StringUtils.numberFormatter(tickDelta)} `)\n\n let xTick;\n let bp;\n let accumulatedTickDelta = tickDelta;\n const labelLengthShim = 0.25 * labelLength;\n do {\n\n bp = Math.floor(nTick * tick.majorTick);\n const rulerLabel = `${numberFormatter$1(Math.floor(bp / tick.unitMultiplier))} ${tick.majorUnit}`;\n\n xTick = Math.round(referenceFrame.toPixels((bp - 1) - bpStart + 0.5));\n const xLabel = Math.round(xTick - context.measureText(rulerLabel).width / 2);\n\n if (xLabel > 0 && (labelLengthShim + labelLength) <= accumulatedTickDelta) {\n IGVGraphics.fillText(context, rulerLabel, xLabel, this.height - (tickHeight / 0.75));\n accumulatedTickDelta = 0;\n }\n\n if (xTick > 0) {\n IGVGraphics.strokeLine(context, xTick, this.height - tickHeight, xTick, this.height - shim);\n }\n\n bp = Math.floor((1 + nTick) * tick.majorTick);\n let pixel = Math.round(referenceFrame.toPixels((bp - 1) - bpStart + 0.5));\n let delta = (pixel - xTick) / 2;\n let xx = xTick + delta;\n if (xx > 0) {\n IGVGraphics.strokeLine(context, xx, this.height - tickHeight, xx, this.height - shim);\n }\n\n ++nTick;\n accumulatedTickDelta += tickDelta;\n\n } while (xTick < pixelWidth)\n\n IGVGraphics.strokeLine(context, 0, this.height - shim, pixelWidth, this.height - shim);\n\n }\n\n renderChromosomeRect(ctx, x, y, w, h, name) {\n\n ctx.textAlign = 'center';\n ctx.textBaseline = 'middle';\n ctx.font = '12px sans-serif';\n\n IGVGraphics.strokeLine(ctx, x + w, y, x + w, y + h, {strokeStyle: IGVColor.greyScale(191)});\n\n const shortName = (name.startsWith(\"chr\")) ? name.substring(3) : name;\n\n if (w > ctx.measureText(shortName).width) {\n IGVGraphics.fillText(ctx, shortName, (x + (w / 2)), (y + (h / 2)), {fillStyle: IGVColor.greyScale(68)});\n }\n }\n\n get supportsWholeGenome() {\n return true\n };\n\n dispose() {\n // do stuff\n }\n}\n\nfunction findSpacing(bpLength, isSVG) {\n\n if (bpLength < 10) {\n return new Tick(1, 'bp', 1)\n }\n\n const nZeroes = Math.floor(Math.log10(bpLength));\n\n let majorUnit = 'bp';\n let unitMultiplier = 1;\n\n if (nZeroes > 9) {\n majorUnit = 'gb';\n unitMultiplier = 1e9;\n } else if (nZeroes > 6) {\n majorUnit = 'mb';\n unitMultiplier = 1e6;\n } else if (nZeroes > 3) {\n majorUnit = 'kb';\n unitMultiplier = 1e3;\n }\n\n const denom = Math.pow(10, nZeroes - 1);\n const nMajorTicks = bpLength / denom;\n\n // const threshold = 25\n const threshold = 3 * 25;\n\n const belowThresholdTick = Math.pow(10, nZeroes - 1);\n const aboveThresholdTick = Math.pow(10, nZeroes) / 2;\n\n // console.log(`zeros ${ nZeroes } tick-threshold ${ threshold } ticks ${ nMajorTicks } belowTick ${ StringUtils.numberFormatter(belowThresholdTick) } aboveTick ${ StringUtils.numberFormatter(aboveThresholdTick) }`)\n\n const majorTick = (nMajorTicks < threshold && isSVG !== true) ? belowThresholdTick : aboveThresholdTick;\n\n return new Tick(majorTick, majorUnit, unitMultiplier)\n}\n\nfunction calculateDeltas(context, referenceFrame, bpStart, nTick, tick) {\n\n const tickDelta = getX(referenceFrame, getBP(1 + nTick, tick), bpStart) - getX(referenceFrame, getBP(nTick, tick), bpStart);\n\n const label = `${numberFormatter$1(Math.floor(getBP(nTick, tick) / tick.unitMultiplier))} ${tick.majorUnit}`;\n const labelLength = Math.floor(context.measureText(label).width);\n\n return {tickDelta, labelLength}\n\n function getBP(nTick, tick) {\n return Math.floor(nTick * tick.majorTick)\n }\n\n function getX(referenceFrame, bp, bpStart) {\n return Math.round(referenceFrame.toPixels((bp - 1) - bpStart + 0.5))\n }\n}\n\nclass Tick {\n\n constructor(majorTick, majorUnit, unitMultiplier) {\n this.majorTick = majorTick;\n this.minorTick = majorTick / 10.0;\n this.majorUnit = majorUnit;\n this.unitMultiplier = unitMultiplier;\n }\n\n description(blurb) {\n console.log((blurb || '') + ' tick ' + numberFormatter(this.majorTick) + ' label width ' + numberFormatter(this.labelWidthBP) + ' multiplier ' + this.unitMultiplier);\n }\n}\n\n/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2016 University of California San Diego\n * Author: Jim Robinson\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\nconst CircularViewControl = function (parent, browser) {\n\n this.button = domUtils.div({class: 'igv-navbar-button'});\n parent.appendChild(this.button);\n this.button.textContent = 'circular view';\n\n this.button.addEventListener('click', () => {\n browser.circularViewVisible = !browser.circularViewVisible;\n //this.setState(browser.circularViewVisible)\n });\n\n this.browser = browser;\n\n this.setVisibility(browser.config.showCircularViewButton);\n\n this.setState(browser.circularViewVisible);\n\n};\n\nCircularViewControl.prototype.setVisibility = function (showCircularViewButton) {\n if (true === showCircularViewButton) {\n this.show();\n } else {\n this.hide();\n }\n};\n\nCircularViewControl.prototype.setState = function (circularViewVisible) {\n if (true === circularViewVisible) {\n this.button.classList.add('igv-navbar-button-clicked');\n } else {\n this.button.classList.remove('igv-navbar-button-clicked');\n }\n};\n\nCircularViewControl.prototype.show = function () {\n this.button.style.display = 'block';\n this.setState(this.browser.circularViewVisible);\n};\n\nCircularViewControl.prototype.hide = function () {\n this.button.style.display = 'none';\n};\n\n/**\n * User supplied button for the navbar\n */\n\nconst CustomButton = function (parent, browser, b) {\n\n const button = domUtils.div({class: 'igv-navbar-button'});\n parent.append(button);\n button.textContent = b.label;\n button.addEventListener('click', () => b.callback(browser));\n};\n\nclass ROIManager {\n\n constructor(browser, roiMenu, roiTable, top, roiSets) {\n\n this.browser = browser;\n this.roiMenu = roiMenu;\n this.roiTable = roiTable;\n this.top = top;\n this.roiSets = roiSets || [];\n this.boundLocusChangeHandler = locusChangeHandler.bind(this);\n browser.on('locuschange', this.boundLocusChangeHandler);\n\n }\n\n async initialize() {\n\n if (this.roiSets.length > 0) {\n this.browser.showROITableButton = true;\n this.browser.roiTableControl.setVisibility(this.browser.showROITableButton);\n }\n\n const promises = this.roiSets.map(roiSet => this.renderROISet({\n browser: this.browser,\n pixelTop: this.top,\n roiSet\n }));\n\n if (promises.length > 0) {\n await Promise.all(promises);\n }\n\n const records = await this.getTableRecords();\n this.roiTable.renderTable(records);\n\n }\n\n async loadROI(config, genome) {\n\n const configs = Array.isArray(config) ? config : [config];\n\n for (let c of configs) {\n this.roiSets.push(new ROISet(c, genome));\n }\n\n await this.initialize();\n\n }\n\n clearROIs() {\n\n this.roiTable.clearTable();\n\n const elements = this.browser.columnContainer.querySelectorAll('.igv-roi-region');\n for (let el of elements) {\n el.remove();\n }\n\n for (let roiSet of this.roiSets) {\n roiSet.dispose();\n }\n\n this.roiSets = [];\n\n }\n\n async getTableRecords() {\n\n const records = [];\n\n for (let roiSet of this.roiSets) {\n const setName = roiSet.isUserDefined ? '' : (roiSet.name || '');\n const allFeatures = await roiSet.getAllFeatures();\n for (let chr of Object.keys(allFeatures)) {\n for (let feature of allFeatures[chr]) {\n records.push({setName, feature});\n }\n }\n }\n\n return records\n }\n\n presentTable() {\n this.roiTable.present();\n }\n\n async repaintTable() {\n const records = await this.getTableRecords();\n this.roiTable.renderTable(records);\n }\n\n dismissTable() {\n this.roiTable.dismiss();\n }\n\n async updateUserDefinedROISet(feature) {\n\n let userDefinedROISet = await this.getUserDefinedROISet();\n\n if (undefined === userDefinedROISet) {\n userDefinedROISet = this.initializeUserDefinedROISet();\n }\n\n userDefinedROISet.addFeature(feature);\n\n if (false === this.browser.showROITableButton) {\n this.setROITableButtonVisibility(true);\n }\n\n await this.renderROISet({browser: this.browser, pixelTop: this.top, roiSet: userDefinedROISet});\n\n const records = await this.getTableRecords();\n this.roiTable.renderTable(records);\n }\n\n setROITableButtonVisibility(isVisible) {\n this.browser.showROITableButton = isVisible;\n this.browser.roiTableControl.setVisibility(this.browser.showROITableButton);\n }\n\n async renderAllROISets() {\n\n for (let roiSet of this.roiSets) {\n await this.renderROISet({browser: this.browser, pixelTop: this.top, roiSet});\n }\n }\n\n async renderROISet({browser, pixelTop, roiSet}) {\n\n const columns = browser.columnContainer.querySelectorAll('.igv-column');\n\n for (let i = 0; i < columns.length; i++) {\n\n let {chr, start: viewStart, end: viewEnd, bpPerPixel} = browser.referenceFrameList[i];\n\n const elements = columns[i].querySelectorAll('.igv-roi-region');\n for (let el of elements) {\n const regionKey = el.dataset.region;\n const {chr: regionChr, start: regionStart, end: regionEnd} = parseRegionKey(regionKey);\n if (regionChr !== chr || regionEnd < viewStart || regionStart > viewEnd) {\n el.remove();\n }\n }\n\n const features = await roiSet.getFeatures(chr, viewStart, viewEnd);\n\n if (features) {\n\n for (let feature of features) {\n\n const regionKey = createRegionKey(chr, feature.start, feature.end);\n\n const {\n x: pixelX,\n width: pixelWidth\n } = screenCoordinates(Math.max(viewStart, feature.start), Math.min(viewEnd, feature.end), viewStart, bpPerPixel);\n\n\n const el = columns[i].querySelector(createSelector(regionKey));\n\n if (el) {\n el.style.left = `${pixelX}px`;\n el.style.width = `${pixelWidth}px`;\n\n } else {\n const element = this.createRegionElement(browser.columnContainer, pixelTop, pixelX, pixelWidth, roiSet, regionKey, feature.name);\n columns[i].appendChild(element);\n }\n }\n }\n }\n }\n\n createRegionElement(columnContainer, pixelTop, pixelX, pixelWidth, roiSet, regionKey, name) {\n\n const regionElement = domUtils.div({class: 'igv-roi-region'});\n\n regionElement.style.top = `${pixelTop}px`;\n regionElement.style.left = `${pixelX}px`;\n regionElement.style.width = `${pixelWidth}px`;\n regionElement.style.backgroundColor = roiSet.color;\n regionElement.dataset.region = regionKey;\n\n const header = domUtils.div();\n regionElement.appendChild(header);\n\n header.style.backgroundColor = roiSet.headerColor;\n\n if (true === roiSet.isUserDefined) {\n header.addEventListener('click', event => {\n event.preventDefault();\n event.stopPropagation();\n\n const {x, y} = domUtils.translateMouseCoordinates(event, columnContainer);\n this.roiMenu.present(x, y, this, columnContainer, regionElement);\n });\n } else if (name) {\n header.addEventListener('click', event => {\n event.preventDefault();\n event.stopPropagation();\n if (this.popover) {\n this.popover.dispose();\n }\n this.popover = new Popover(columnContainer, roiSet.name);\n this.popover.presentContentWithEvent(event, name);\n });\n } else {\n header.style.pointerEvents = 'none';\n }\n\n return regionElement\n }\n\n renderSVGContext(context, {deltaX, deltaY}) {\n\n for (const regionElement of document.querySelectorAll('.igv-roi-region')) {\n\n // body\n const { x, y, width, height } = regionElement.getBoundingClientRect();\n context.fillStyle = regionElement.style.backgroundColor;\n context.fillRect(x+deltaX, y+deltaY, width, height);\n\n // header\n const header = regionElement.querySelector('div');\n const { x:xx, y:yy, width:ww, height:hh } = header.getBoundingClientRect();\n context.fillStyle = header.style.backgroundColor;\n context.fillRect(xx+deltaX, yy+deltaY, ww, hh);\n }\n }\n\n async getUserDefinedROISet() {\n return this.roiSets.find(roiSet => true === roiSet.isUserDefined)\n }\n\n initializeUserDefinedROISet() {\n\n const config =\n {\n isUserDefined: true,\n features: []\n };\n const userDefinedROISet = new ROISet(config, this.browser.genome);\n this.roiSets.push(userDefinedROISet);\n\n return userDefinedROISet\n }\n\n async deleteUserDefinedRegionWithKey(regionKey, columnContainer) {\n\n columnContainer.querySelectorAll(createSelector(regionKey)).forEach(node => node.remove());\n\n const feature = await this.findUserDefinedRegionWithKey(regionKey);\n\n const set = await this.getUserDefinedROISet();\n\n if (set) {\n set.removeFeature(feature);\n }\n\n const records = await this.getTableRecords();\n\n if (0 === records.length) {\n this.browser.roiTableControl.buttonHandler(false);\n this.setROITableButtonVisibility(false);\n }\n\n }\n\n async findUserDefinedRegionWithKey(regionKey) {\n\n const {chr, start, end} = parseRegionKey(regionKey);\n const set = await this.getUserDefinedROISet();\n\n if (set) {\n const features = await set.getFeatures(chr, start, end);\n\n for (let feature of features) {\n if (feature.chr === chr && feature.start >= start && feature.end <= end) {\n return feature\n }\n }\n }\n\n return undefined\n }\n\n toJSON() {\n return this.roiSets.map(roiSet => roiSet.toJSON())\n }\n\n dispose() {\n\n this.browser.off('locuschange', this.boundLocusChangeHandler);\n\n const removable = this.browser.columnContainer.querySelectorAll('.igv-roi-region');\n\n for (let el of removable) {\n el.remove();\n }\n\n if (this.roiMenu) {\n this.roiMenu.dispose();\n }\n\n if (this.roiTable) {\n this.roiTable.dispose();\n }\n\n for (let roiSet of this.roiSets) {\n roiSet.dispose();\n }\n\n for (let key of Object.keys(this)) {\n this[key] = undefined;\n }\n\n }\n}\n\nfunction locusChangeHandler() {\n this.renderAllROISets();\n}\n\nfunction createRegionKey(chr, start, end) {\n return `${chr}-${start}-${end}`\n}\n\nfunction createSelector(regionKey) {\n return `[data-region=\"${regionKey}\"]`\n}\n\nfunction parseRegionKey(regionKey) {\n let [chr, ss, ee] = regionKey.split('-');\n ss = parseInt(ss);\n ee = parseInt(ee);\n\n return {chr, start: ss, end: ee, locus: `${chr}:${ss}-${ee}`, bedRecord: `${chr}\\t${ss}\\t${ee}`}\n}\n\nclass ROITable extends RegionTableBase {\n constructor(config) {\n\n const cooked = Object.assign({ 'width':'512px' }, config);\n super(cooked);\n }\n\n tableRowDOM(record) {\n\n const dom = domUtils.div({ class: 'igv-roi-table-row' });\n\n const { setName, feature } = record;\n dom.dataset.region = createRegionKey(feature.chr, feature.start, feature.end);\n\n let strings =\n [\n feature.chr,\n numberFormatter$1(feature.start),\n numberFormatter$1(feature.end),\n feature.name || '',\n setName\n ];\n\n if (4 === this.columnFormat.length) {\n strings = strings.slice(0, 4);\n }\n\n for (let i = 0; i < strings.length; i++) {\n const el = domUtils.div();\n dom.appendChild(el);\n el.style.width = this.columnFormat[ i ].width;\n el.innerText = strings[ i ];\n }\n\n this.tableRowDOMHelper(dom);\n\n return dom\n }\n\n renderTable(records) {\n\n Array.from(this.tableRowContainer.querySelectorAll('.igv-roi-table-row')).forEach(el => el.remove());\n\n if (records.length > 0) {\n\n const sortedRecords = records.sort((a, b) => (a.feature.chr.localeCompare(b.feature.chr) || a.feature.start - b.feature.start || a.feature.end - b.feature.end));\n\n for (let record of sortedRecords) {\n const row = this.tableRowDOM(record);\n this.tableRowContainer.appendChild(row);\n }\n\n }\n }\n\n dispose() {\n\n document.removeEventListener('click', this.boundGotoButtonHandler);\n\n this.browser.roiTableControl.buttonHandler(false);\n super.dispose();\n }\n\n static getColumnFormatConfiguration(doIncludeROISetNames) {\n\n if (true === doIncludeROISetNames) {\n\n return [\n { label: 'Chr', width: '20%' },\n { label: 'Start', width: '15%' },\n { label: 'End', width: '15%' },\n { label: 'Description', width: '30%' },\n { label: 'ROI Set', width: '20%' }\n ]\n } else {\n return [\n { label: 'Chr', width: '25%' },\n { label: 'Start', width: '20%' },\n { label: 'End', width: '20%' },\n { label: 'Description', width: '35%' }\n ]\n }\n\n }\n\n static gotoButtonHandler (event) {\n\n event.stopPropagation();\n\n const selected = this.tableDOM.querySelectorAll('.igv-roi-table-row-selected');\n const loci = [];\n for (let el of selected) {\n const { locus } = parseRegionKey(el.dataset.region);\n loci.push(locus);\n }\n\n for (let el of this.tableDOM.querySelectorAll('.igv-roi-table-row')) {\n el.classList.remove('igv-roi-table-row-selected');\n }\n\n this.setTableRowSelectionState(false);\n\n if (loci.length > 0) {\n this.browser.search(loci.join(' '));\n }\n\n }\n\n}\n\nclass ROIMenu {\n constructor(browser, parent) {\n\n this.browser = browser;\n\n // container\n this.container = domUtils.div({ class: 'igv-roi-menu-next-gen' });\n parent.appendChild(this.container);\n\n // header\n const header = domUtils.div();\n this.container.appendChild(header);\n\n uiUtils.attachDialogCloseHandlerWithParent(header, () => this.container.style.display = 'none');\n\n // body\n this.body = domUtils.div();\n this.container.appendChild(this.body);\n\n this.container.style.display = 'none';\n\n }\n\n async present(x, y, roiManager, columnContainer, regionElement) {\n\n removeAllChildNodes(this.body);\n\n const feature = await this.browser.roiManager.findUserDefinedRegionWithKey(regionElement.dataset.region);\n\n // Description Copy\n const _description_copy_ = domUtils.div();\n this.body.appendChild(_description_copy_);\n\n const placeholder = 'Description';\n const str = (feature.name || placeholder);\n\n _description_copy_.innerText = str;\n _description_copy_.setAttribute('title', str);\n placeholder === str ? _description_copy_.classList.add('igv-roi-placeholder') : _description_copy_.classList.remove('igv-roi-placeholder');\n\n\n // Set Description\n const description = domUtils.div();\n this.body.appendChild(description);\n description.innerText = 'Set Description';\n\n description.addEventListener('click', event => {\n\n event.stopPropagation();\n\n this.container.style.display = 'none';\n\n const callback = () => {\n\n const value = this.browser.inputDialog.value || '';\n feature.name = value.trim();\n\n this.container.style.display = 'none';\n\n this.browser.roiManager.repaintTable();\n };\n\n const config =\n {\n label: 'Description',\n value: (feature.name || ''),\n callback\n };\n\n this.browser.inputDialog.present(config, event);\n\n });\n\n\n // Delete Region\n const _delete_ = domUtils.div();\n this.body.appendChild(_delete_);\n _delete_.innerText = 'Delete Region';\n\n _delete_.addEventListener('click', event => {\n event.stopPropagation();\n this.container.style.display = 'none';\n this.browser.roiManager.deleteUserDefinedRegionWithKey(regionElement.dataset.region, this.browser.columnContainer);\n });\n\n\n\n\n\n\n\n // columnContainer.addEventListener('click', event => {\n // event.stopPropagation()\n // this.container.style.display = 'none'\n // })\n\n this.container.style.left = `${ x }px`;\n this.container.style.top = `${ y }px`;\n this.container.style.display = 'flex';\n\n }\n\n async __present(x, y, roiManager, columnContainer, regionElement) {\n\n removeAllChildNodes(this.container);\n\n const feature = await this.browser.roiManager.findUserDefinedRegionWithKey(regionElement.dataset.region);\n\n let row;\n\n // Go To\n // row = DOMUtils.div({ class: 'igv-roi-menu-row' })\n // row.innerText = 'Go To'\n // this.container.appendChild(row)\n //\n // row.addEventListener('click', event => {\n // event.stopPropagation()\n // this.container.style.display = 'none'\n //\n // const { locus } = parseRegionKey(regionElement.dataset.region)\n // this.browser.search(locus)\n // })\n\n // Description:\n row = domUtils.div({ class: 'igv-roi-menu-row-edit-description' });\n this.container.appendChild(row);\n\n row.addEventListener('click', e => {\n e.stopPropagation();\n });\n\n const str = 'description-input';\n\n const label = document.createElement('label');\n row.appendChild(label);\n\n label.setAttribute('for', str);\n label.innerText = 'Description:';\n\n const input = document.createElement('input');\n row.appendChild(input);\n\n input.setAttribute('type', 'text');\n input.setAttribute('name', str);\n // input.setAttribute('placeholder', feature.name || 'Edit Description')\n input.setAttribute('placeholder', '');\n input.value = feature.name || '';\n\n input.addEventListener('change', async e => {\n\n e.stopPropagation();\n\n const feature = await this.browser.roiManager.findUserDefinedRegionWithKey(regionElement.dataset.region);\n feature.name = input.value;\n\n input.blur();\n this.container.style.display = 'none';\n\n await this.browser.roiManager.repaintTable();\n });\n\n\n // Delete\n row = domUtils.div({ class: 'igv-roi-menu-row' });\n row.innerText = 'Delete region';\n this.container.appendChild(row);\n\n row.addEventListener('click', event => {\n event.stopPropagation();\n this.container.style.display = 'none';\n this.browser.roiManager.deleteUserDefinedRegionWithKey(regionElement.dataset.region, this.browser.columnContainer);\n });\n\n this.container.style.left = `${ x }px`;\n this.container.style.top = `${ y }px`;\n this.container.style.display = 'flex';\n\n columnContainer.addEventListener('click', event => {\n event.stopPropagation();\n this.container.style.display = 'none';\n });\n\n }\n\n dispose() {\n this.container.innerHTML = '';\n }\n\n}\n\nfunction removeAllChildNodes(parent) {\n while (parent.firstChild) {\n parent.removeChild(parent.firstChild);\n }\n}\n\nclass TrackROISet {\n\n constructor(config, genome) {\n this.name = config.name;\n this.featureSource = config.featureSource || FeatureSource(config, genome);\n this.color = config.color || ROI_DEFAULT_COLOR;\n }\n\n async getFeatures(chr, start, end) {\n return this.featureSource.getFeatures({chr, start, end})\n }\n\n draw(drawConfiguration) {\n\n const { context, bpPerPixel, bpStart, pixelTop, pixelHeight, pixelWidth, features, } = drawConfiguration;\n\n if (!features) {\n return\n }\n\n const bpEnd = bpStart + (pixelWidth * bpPerPixel) + 1;\n for (let { start:regionStartBP, end:regionEndBP } of features) {\n\n if (regionEndBP < bpStart) {\n continue\n }\n\n if (regionStartBP > bpEnd) {\n break\n }\n\n const { x, width } = screenCoordinates(regionStartBP, regionEndBP, bpStart, bpPerPixel);\n IGVGraphics.fillRect(context, x, pixelTop, width, pixelHeight, { fillStyle: this.color });\n }\n }\n}\n\n/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2016 University of California San Diego\n * Author: Jim Robinson\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\nclass ROITableControl {\n\n constructor(parent, browser) {\n this.browser = browser;\n this.button = domUtils.div({class: 'igv-navbar-button'});\n parent.appendChild(this.button);\n this.button.textContent = 'ROI Table';\n\n this.button.addEventListener('click', () => {\n this.buttonHandler(!browser.roiTableVisible);\n });\n\n this.browser = browser;\n\n this.setVisibility(browser.showROITableButton);\n\n this.setState(browser.roiTableVisible);\n }\n\n buttonHandler(status) {\n this.browser.roiTableVisible = status;\n this.setState(this.browser.roiTableVisible);\n this.browser.setROITableVisibility(this.browser.roiTableVisible);\n }\n\n setVisibility(doShowROITablelButton) {\n if (true === doShowROITablelButton) {\n this.show();\n } else {\n this.hide();\n }\n }\n\n setState(roiTableVisible) {\n if (true === roiTableVisible) {\n this.button.classList.add('igv-navbar-button-clicked');\n } else {\n this.button.classList.remove('igv-navbar-button-clicked');\n }\n }\n\n show() {\n this.button.style.display = 'block';\n this.setState(this.browser.roiTableVisible);\n }\n\n hide() {\n this.button.style.display = 'none';\n }\n}\n\n// css - $igv-scrollbar-outer-width: 14px;\nconst igv_scrollbar_outer_width = 14;\n\n// css - $igv-track-drag-column-width: 12px;\nconst igv_track_manipulation_handle_width = 12;\n\n// css - $igv-track-gear-menu-column-width: 28px;\nconst igv_track_gear_menu_column_width = 28;\n\n// $igv-column-shim-width: 1px;\n// $igv-column-shim-margin: 2px;\nconst column_multi_locus_shim_width = 2 + 1 + 2;\n\nconst defaultSampleNameViewportWidth = 200;\n\nclass Browser {\n\n constructor(config, parentDiv) {\n\n this.config = config;\n this.guid = domUtils.guid();\n this.namespace = '.browser_' + this.guid;\n\n this.parent = parentDiv;\n\n this.root = domUtils.div({class: 'igv-container'});\n parentDiv.appendChild(this.root);\n\n this.alert = new Alert(this.root);\n\n this.columnContainer = domUtils.div({class: 'igv-column-container'});\n this.root.appendChild(this.columnContainer);\n\n this.menuPopup = new MenuPopup(this.columnContainer);\n\n this.initialize(config);\n\n this.trackViews = [];\n\n this.constants = {\n dragThreshold: 3,\n scrollThreshold: 5,\n defaultColor: \"rgb(0,0,150)\",\n doubleClickDelay: config.doubleClickDelay || 500\n };\n\n // Map of event name -> [ handlerFn, ... ]\n this.eventHandlers = {};\n\n this.addMouseHandlers();\n\n this.setControls(config);\n }\n\n initialize(config) {\n\n if (config.gtex) {\n GtexUtils.gtexLoaded = true;\n }\n this.flanking = config.flanking;\n this.crossDomainProxy = config.crossDomainProxy;\n this.formats = config.formats;\n this.trackDefaults = config.trackDefaults;\n this.nucleotideColors = config.nucleotideColors || defaultNucleotideColors;\n for (let key of Object.keys(this.nucleotideColors)) {\n this.nucleotideColors[key.toLowerCase()] = this.nucleotideColors[key];\n }\n\n this.trackLabelsVisible = config.showTrackLabels;\n\n this.roiTableVisible = config.showROITable;\n this.showROITableButton = config.showROITableButton;\n\n this.isCenterLineVisible = config.showCenterGuide;\n\n this.cursorGuideVisible = config.showCursorGuide;\n\n this.showSampleNames = config.showSampleNames;\n this.showSampleNameButton = config.showSampleNameButton;\n this.sampleNameViewportWidth = config.sampleNameViewportWidth || defaultSampleNameViewportWidth;\n\n if (config.search) {\n this.searchConfig = {\n type: \"json\",\n url: config.search.url,\n coords: config.search.coords === undefined ? 1 : config.search.coords,\n chromosomeField: config.search.chromosomeField || \"chromosome\",\n startField: config.search.startField || \"start\",\n endField: config.search.endField || \"end\",\n geneField: config.search.geneField || \"gene\",\n snpField: config.search.snpField || \"snp\",\n resultsField: config.search.resultsField\n };\n }\n }\n\n setControls(config) {\n\n const $navBar = this.createStandardControls(config);\n $navBar.insertBefore($$1(this.columnContainer));\n this.$navigation = $navBar;\n\n if (false === config.showControls) {\n $navBar.hide();\n }\n\n }\n\n createStandardControls(config) {\n\n this.navbarManager = new NavbarManager(this);\n\n const $navBar = $$1('
', {class: 'igv-navbar'});\n this.$navigation = $navBar;\n\n const $navbarLeftContainer = $$1('
', {class: 'igv-navbar-left-container'});\n $navBar.append($navbarLeftContainer);\n\n // IGV logo\n const $logo = $$1('
', {class: 'igv-logo'});\n $navbarLeftContainer.append($logo);\n\n const logoSvg = logo();\n logoSvg.css(\"width\", \"34px\");\n logoSvg.css(\"height\", \"32px\");\n $logo.append(logoSvg);\n\n this.$current_genome = $$1('
', {class: 'igv-current-genome'});\n $navbarLeftContainer.append(this.$current_genome);\n this.$current_genome.text('');\n\n const $genomicLocation = $$1('
', {class: 'igv-navbar-genomic-location'});\n $navbarLeftContainer.append($genomicLocation);\n\n // chromosome select widget\n this.chromosomeSelectWidget = new ChromosomeSelectWidget(this, $genomicLocation.get(0));\n if (undefined === config.showChromosomeWidget) {\n config.showChromosomeWidget = true; // Default to true\n }\n if (true === config.showChromosomeWidget) {\n this.chromosomeSelectWidget.show();\n } else {\n this.chromosomeSelectWidget.hide();\n }\n\n const $locusSizeGroup = $$1('
', {class: 'igv-locus-size-group'});\n $genomicLocation.append($locusSizeGroup);\n\n const $searchContainer = $$1('
', {class: 'igv-search-container'});\n $locusSizeGroup.append($searchContainer);\n\n // browser.$searchInput = $('');\n this.$searchInput = $$1('', {class: 'igv-search-input', type: 'text', placeholder: 'Locus Search'});\n $searchContainer.append(this.$searchInput);\n\n this.$searchInput.change(() => this.doSearch(this.$searchInput.val()));\n\n const searchIconContainer = domUtils.div({class: 'igv-search-icon-container'});\n $searchContainer.append($$1(searchIconContainer));\n\n searchIconContainer.appendChild(icons$1.createIcon(\"search\"));\n\n searchIconContainer.addEventListener('click', () => this.doSearch(this.$searchInput.val()));\n\n this.windowSizePanel = new WindowSizePanel($locusSizeGroup.get(0), this);\n\n const $navbarRightContainer = $$1('
', {class: 'igv-navbar-right-container'});\n $navBar.append($navbarRightContainer);\n\n const $toggle_button_container = $$1('
');\n $navbarRightContainer.append($toggle_button_container);\n this.$toggle_button_container = $toggle_button_container;\n\n this.cursorGuide = new CursorGuide(this.columnContainer, this);\n\n this.cursorGuideButton = new CursorGuideButton(this, $toggle_button_container.get(0));\n\n this.centerLineButton = new CenterLineButton(this, $toggle_button_container.get(0));\n\n this.setTrackLabelVisibility(config.showTrackLabels);\n this.trackLabelControl = new TrackLabelControl($toggle_button_container.get(0), this);\n\n // ROI Control\n this.roiTableControl = new ROITableControl($toggle_button_container.get(0), this);\n\n this.sampleNameControl = new SampleNameControl($toggle_button_container.get(0), this);\n\n if (true === config.showSVGButton) {\n this.svgSaveControl = new SVGSaveControl($toggle_button_container.get(0), this);\n }\n\n if (config.customButtons) {\n for (let b of config.customButtons) {\n new CustomButton($toggle_button_container.get(0), this, b);\n }\n }\n\n this.zoomWidget = new ZoomWidget(this, $navbarRightContainer.get(0));\n\n if (false === config.showNavigation) {\n this.$navigation.hide();\n }\n\n this.inputDialog = new InputDialog(this.root);\n this.inputDialog.container.id = `igv-input-dialog-${domUtils.guid()}`;\n\n this.dataRangeDialog = new DataRangeDialog(this, $$1(this.root));\n this.dataRangeDialog.$container.get(0).id = `igv-data-range-dialog-${domUtils.guid()}`;\n\n this.genericColorPicker = new GenericColorPicker({parent: this.columnContainer, width: 432});\n this.genericColorPicker.container.id = `igv-track-color-picker-${domUtils.guid()}`;\n\n return $navBar\n\n }\n\n getSampleNameViewportWidth() {\n return false === this.showSampleNames ? 0 : this.sampleNameViewportWidth\n }\n\n isMultiLocusMode() {\n return this.referenceFrameList && this.referenceFrameList.length > 1\n };\n\n addTrackToFactory(name, track) {\n TrackFactory.addTrack(name, track);\n }\n\n isMultiLocusWholeGenomeView() {\n\n if (undefined === this.referenceFrameList || 1 === this.referenceFrameList.length) {\n return false\n }\n\n for (let referenceFrame of this.referenceFrameList) {\n if ('all' === referenceFrame.chr.toLowerCase()) {\n return true\n }\n }\n\n return false\n };\n\n /**\n * PUBLIC API FUNCTION\n *\n * Return the current genomic region as a locus string, or array of locus strings if in multi-locus view\n * @returns {string|*[]|*}\n */\n currentLoci() {\n const noCommaLocusString = (rf) => `${rf.chr}:${rf.start + 1}-${rf.end}`;\n if (undefined === this.referenceFrameList || 0 === this.referenceFrameList.length) {\n return \"\"\n } else if (1 === this.referenceFrameList.length) {\n return noCommaLocusString(this.referenceFrameList[0])\n } else {\n return this.referenceFrameList.map(rf => noCommaLocusString(rf))\n }\n }\n\n /**\n * Render browse display as SVG\n * @returns {string}\n */\n toSVG() {\n\n const {y, width, height} = this.columnContainer.getBoundingClientRect();\n\n const h_render = 8000;\n\n const config =\n {\n\n width,\n height: h_render,\n\n backdropColor: 'white',\n\n multiLocusGap: 0,\n\n viewbox:\n {\n x: 0,\n y: 0,\n width,\n height: h_render\n }\n\n };\n\n const context = new ctx(config);\n\n // tracks -> SVG\n const delta = {deltaX: 0, deltaY: -y};\n for (let trackView of this.trackViews) {\n trackView.renderSVGContext(context, delta);\n }\n\n this.roiManager.renderSVGContext(context, delta);\n\n // reset height to trim away unneeded svg canvas real estate. Yes, a bit of a hack.\n context.setHeight(height);\n\n return context.getSerializedSvg(true)\n\n }\n\n renderSVG($container) {\n const svg = this.toSVG();\n $container.empty();\n $container.append(svg);\n\n return svg\n }\n\n saveSVGtoFile(config) {\n\n let svg = this.toSVG();\n\n if (config.$container) {\n config.$container.empty();\n config.$container.append(svg);\n }\n\n const path = config.filename || 'igvjs.svg';\n const data = URL.createObjectURL(new Blob([svg], {type: \"application/octet-stream\"}));\n download(path, data);\n }\n\n /**\n * Initialize a session from an object, json, or by loading from a file.\n *\n * TODO Really should be split into at least 2 functions, load from file and load from object/json\n *\n * @param options\n * @returns {*}\n */\n async loadSession(options) {\n\n // TODO: depricated\n this.roiSets = [];\n\n let session;\n if (options.url || options.file) {\n session = await loadSessionFile(options);\n } else {\n session = options;\n }\n return this.loadSessionObject(session)\n\n\n async function loadSessionFile(options) {\n\n const urlOrFile = options.url || options.file;\n\n if (options.url && (options.url.startsWith(\"blob:\") || options.url.startsWith(\"data:\"))) {\n const json = Browser.uncompressSession(options.url);\n return JSON.parse(json)\n\n } else {\n let filename = options.filename;\n if (!filename) {\n filename = (options.url ? await getFilename$1(options.url) : options.file.name);\n }\n\n if (filename.endsWith(\".xml\")) {\n\n const knownGenomes = GenomeUtils.KNOWN_GENOMES;\n const string = await igvxhr.loadString(urlOrFile);\n return new XMLSession(string, knownGenomes)\n\n } else if (filename.endsWith(\".json\")) {\n return igvxhr.loadJson(urlOrFile)\n } else {\n return undefined\n }\n }\n }\n }\n\n\n /**\n * Note: public API function\n * @param session\n * @returns {Promise}\n */\n async loadSessionObject(session) {\n\n // prepare to load a new session, discarding DOM and state\n this.cleanHouseForSession();\n\n this.showSampleNames = session.showSampleNames || false;\n this.sampleNameControl.setState(this.showSampleNames === true);\n\n if (session.sampleNameViewportWidth) {\n this.sampleNameViewportWidth = session.sampleNameViewportWidth;\n }\n\n // axis column\n createColumn(this.columnContainer, 'igv-axis-column');\n\n // SampleName column\n createColumn(this.columnContainer, 'igv-sample-name-column');\n\n // Track scrollbar column\n createColumn(this.columnContainer, 'igv-scrollbar-column');\n\n // Track drag/reorder column\n createColumn(this.columnContainer, 'igv-track-drag-column');\n\n // Track gear column\n createColumn(this.columnContainer, 'igv-gear-menu-column');\n\n const genomeOrReference = session.reference || session.genome;\n if(!genomeOrReference) {\n console.warn(\"No genome or reference object specified\");\n return;\n }\n const genomeConfig = await GenomeUtils.expandReference(this.alert, genomeOrReference);\n\n\n await this.loadReference(genomeConfig, session.locus);\n\n this.centerLineList = this.createCenterLineList(this.columnContainer);\n\n // Create ideogram and ruler track. Really this belongs in browser initialization, but creation is\n // deferred because ideogram and ruler are treated as \"tracks\", and tracks require a reference frame\n let ideogramHeight = 0;\n if (false !== session.showIdeogram) {\n\n const track = new IdeogramTrack(this);\n track.id = 'ideogram';\n\n const trackView = new TrackView(this, this.columnContainer, track);\n const {$viewport} = trackView.viewports[0];\n ideogramHeight = getElementAbsoluteHeight($viewport.get(0));\n\n this.trackViews.push(trackView);\n }\n\n if (false !== session.showRuler) {\n this.trackViews.push(new TrackView(this, this.columnContainer, new RulerTrack(this)));\n }\n\n // Restore gtex selections.\n if (session.gtexSelections) {\n for (let referenceFrame of this.referenceFrameList) {\n for (let s of Object.keys(session.gtexSelections)) {\n const gene = session.gtexSelections[s].gene;\n const snp = session.gtexSelections[s].snp;\n referenceFrame.selection = new GtexSelection(gene, snp);\n }\n }\n }\n\n if (this.roiManager) {\n this.roiManager.dispose();\n }\n\n const roiMenu = new ROIMenu(this, this.columnContainer);\n const roiTableConfig =\n {\n browser: this,\n parent: this.columnContainer,\n headerTitle: 'Regions of Interest',\n dismissHandler: () => this.roiTableControl.buttonHandler(false),\n gotoButtonHandler: ROITable.gotoButtonHandler\n };\n if (session.roi) {\n\n const roiSetList = session.roi.map(c => new ROISet(c, this.genome));\n\n const named = roiSetList.filter(({name}) => name !== undefined && name.length > 0);\n\n roiTableConfig.columnFormat = ROITable.getColumnFormatConfiguration(named.length > 0);\n\n const roiTable = new ROITable(roiTableConfig);\n\n this.roiManager = new ROIManager(this, roiMenu, roiTable, ideogramHeight, roiSetList);\n } else {\n\n roiTableConfig.columnFormat = ROITable.getColumnFormatConfiguration(false);\n\n const roiTable = new ROITable(roiTableConfig);\n\n this.roiManager = new ROIManager(this, roiMenu, roiTable, ideogramHeight, undefined);\n }\n\n await this.roiManager.initialize();\n\n // Tracks. Start with genome tracks, if any, then append session tracks\n const genomeTracks = genomeConfig.tracks || [];\n const trackConfigurations = session.tracks ? genomeTracks.concat(session.tracks) : genomeTracks;\n\n // Ensure that we always have a sequence track with no explicit URL (=> the reference genome sequence track)\n const pushSequenceTrack = trackConfigurations.filter(track => 'sequence' === track.type && !track.url && !track.fastaURL).length === 0;\n if (pushSequenceTrack /*&& false !== this.config.showSequence*/) {\n trackConfigurations.push({type: \"sequence\", order: defaultSequenceTrackOrder});\n }\n\n // Maintain track order unless explicitly set\n let trackOrder = 1;\n for (let t of trackConfigurations) {\n if (undefined === t.order) {\n t.order = trackOrder++;\n }\n }\n\n await this.loadTrackList(trackConfigurations);\n\n // The ruler and ideogram tracks are not explicitly loaded, but needs updated nonetheless.\n for (let rtv of this.trackViews.filter((tv) => tv.track.type === 'ruler' || tv.track.type === 'ideogram')) {\n rtv.updateViews();\n }\n\n this.updateUIWithReferenceFrameList();\n\n }\n\n createCenterLineList(columnContainer) {\n\n const centerLines = columnContainer.querySelectorAll('.igv-center-line');\n for (let i = 0; i < centerLines.length; i++) {\n centerLines[i].remove();\n }\n\n const centerLineList = [];\n const viewportColumns = columnContainer.querySelectorAll('.igv-column');\n for (let i = 0; i < viewportColumns.length; i++) {\n centerLineList.push(new ViewportCenterLine(this, this.referenceFrameList[i], viewportColumns[i]));\n }\n\n return centerLineList\n }\n\n /**\n * Load a reference genome object. This includes the fasta, and optional cytoband, but no tracks. This method\n * is used by loadGenome and loadSession.\n *\n * @param genomeConfig\n * @param initialLocus\n */\n async loadReference(genomeConfig, initialLocus) {\n\n const genome = await GenomeUtils.loadGenome(genomeConfig);\n\n const genomeChange = undefined === this.genome || (this.genome.id !== genome.id);\n\n this.genome = genome;\n\n this.updateNavbarDOMWithGenome(genome);\n\n if (genomeChange) {\n this.removeAllTracks();\n }\n\n let locus = getInitialLocus(initialLocus, genome);\n const locusFound = await this.search(locus, true);\n if (!locusFound) {\n console.log(\"Initial locus not found: \" + locus);\n locus = genome.getHomeChromosomeName();\n const locusFound = await this.search(locus, true);\n if (!locusFound) {\n throw new Error(\"Cannot set initial locus\")\n }\n }\n\n if (genomeChange && this.circularView) {\n this.circularView.setAssembly({\n name: this.genome.id,\n id: this.genome.id,\n chromosomes: makeCircViewChromosomes(this.genome)\n });\n }\n }\n\n cleanHouseForSession() {\n\n for (let trackView of this.trackViews) {\n // empty axis column, viewport columns, sampleName column, scroll column, drag column, gear column\n trackView.removeDOMFromColumnContainer();\n }\n\n // discard all columns\n const elements = this.columnContainer.querySelectorAll('.igv-axis-column, .igv-column-shim, .igv-column, .igv-sample-name-column, .igv-scrollbar-column, .igv-track-drag-column, .igv-gear-menu-column');\n elements.forEach(column => column.remove());\n\n this.trackViews = [];\n\n if (this.circularView) {\n this.circularView.clearChords();\n }\n\n }\n\n updateNavbarDOMWithGenome(genome) {\n\n // If the genome is defined directly from a fasta file or data url the \"id\" will be the full url. Don't display\n // this.\n let genomeLabel = (genome.id && genome.id.length < 10 ? genome.id : '');\n this.$current_genome.text(genomeLabel);\n this.$current_genome.attr('title', genome.id || '');\n this.chromosomeSelectWidget.update(genome);\n }\n\n /**\n * Load a genome, defined by a string ID or a json-like configuration object. This includes a fasta reference\n * as well as optional cytoband and annotation tracks.\n *\n * @param idOrConfig\n * @returns genome\n */\n async loadGenome(idOrConfig) {\n\n const genomeConfig = await GenomeUtils.expandReference(this.alert, idOrConfig);\n await this.loadReference(genomeConfig, undefined);\n\n const tracks = genomeConfig.tracks || [];\n\n // Insure that we always have a sequence track\n const pushSequenceTrack = tracks.filter(track => track.type === 'sequence').length === 0;\n if (pushSequenceTrack) {\n tracks.push({type: \"sequence\", order: defaultSequenceTrackOrder});\n }\n\n await this.loadTrackList(tracks);\n\n await this.updateViews();\n\n return this.genome\n }\n\n /**\n * Called after a session load, search, pan (horizontal drag), or resize\n *\n * @param referenceFrameList\n */\n updateUIWithReferenceFrameList() {\n\n const referenceFrameList = this.referenceFrameList;\n\n this.updateLocusSearchWidget();\n\n const isWGV = (this.isMultiLocusWholeGenomeView() || GenomeUtils.isWholeGenomeView(referenceFrameList[0].chr));\n\n this.navbarManager.navbarDidResize(this.$navigation.width(), isWGV);\n\n toggleTrackLabels(this.trackViews, this.trackLabelsVisible);\n\n this.setCenterLineAndCenterLineButtonVisibility(!GenomeUtils.isWholeGenomeView(referenceFrameList[0].chr));\n\n }\n\n setTrackLabelVisibility(isVisible) {\n toggleTrackLabels(this.trackViews, isVisible);\n }\n\n setROITableVisibility(isVisible) {\n true === isVisible ? this.roiManager.presentTable() : this.roiManager.dismissTable();\n }\n\n // cursor guide\n setCursorGuideVisibility(cursorGuideVisible) {\n\n if (cursorGuideVisible) {\n this.cursorGuide.show();\n } else {\n this.cursorGuide.hide();\n }\n }\n\n setCustomCursorGuideMouseHandler(mouseHandler) {\n this.cursorGuide.customMouseHandler = mouseHandler;\n }\n\n // center line\n setCenterLineVisibility(isCenterLineVisible) {\n for (let centerLine of this.centerLineList) {\n if (true === isCenterLineVisible) {\n centerLine.show();\n centerLine.repaint();\n } else {\n centerLine.hide();\n }\n }\n }\n\n setCenterLineAndCenterLineButtonVisibility(isCenterLineVisible) {\n\n for (let centerLine of this.centerLineList) {\n const isShown = isCenterLineVisible && centerLine.isVisible;\n isShown ? centerLine.show() : centerLine.container.style.display = 'none';\n }\n\n const isShown = isCenterLineVisible && this.centerLineButton.isVisible;\n isShown ? this.centerLineButton.show() : this.centerLineButton.button.style.display = 'none';\n\n }\n\n /**\n * Public API function. Load a list of tracks.\n *\n * @param configList Array of track configurations\n * @returns {Promise<*>} Promise for track objects\n */\n async loadTrackList(configList) {\n\n const promises = [];\n for (let config of configList) {\n promises.push(this._loadTrack(config));\n }\n\n const loadedTracks = await Promise.all(promises);\n const groupAutoscaleViews = this.trackViews.filter(function (trackView) {\n return trackView.track.autoscaleGroup\n });\n if (groupAutoscaleViews.length > 0) {\n this.updateViews();\n }\n return loadedTracks\n }\n\n /**\n * Public API function\n *\n * Load an individual track. If part of an autoscale group force a general update\n *\n * @param config A track configuration\n * @returns {Promise<*>} Promise for track object\n */\n async loadTrack(config) {\n\n const newTrack = this._loadTrack(config);\n\n if (config.autoscaleGroup) {\n // Await newTrack load and update all views\n await newTrack;\n this.updateViews();\n }\n\n return newTrack\n }\n\n /**\n * Return a promise to load a track. Private function used by loadTrack() and loadTrackList()\n *\n * @param config\n * @returns {*}\n */\n\n async _loadTrack(config) {\n\n // config might be json\n if (isString$2(config)) {\n config = JSON.parse(config);\n }\n\n try {\n\n const newTrack = await this.createTrack(config);\n\n if (undefined === newTrack) {\n return\n }\n\n // Set order field of track here. Otherwise track order might get shuffled during asynchronous load\n if (undefined === newTrack.order) {\n newTrack.order = this.trackViews.length;\n }\n\n const trackView = new TrackView(this, this.columnContainer, newTrack);\n this.trackViews.push(trackView);\n toggleTrackLabels(this.trackViews, this.trackLabelsVisible);\n this.reorderTracks();\n this.fireEvent('trackorderchanged', [this.getTrackOrder()]);\n\n if (typeof newTrack.postInit === 'function') {\n try {\n trackView.startSpinner();\n await newTrack.postInit();\n } finally {\n trackView.stopSpinner();\n }\n }\n\n if (!newTrack.autoscaleGroup) {\n // Group autoscale will get updated later (as a group)\n if (config.sync) {\n await trackView.updateViews();\n } else {\n trackView.updateViews();\n }\n }\n\n if (typeof newTrack.hasSamples === 'function' && newTrack.hasSamples()) {\n if (this.config.showSampleNameButton !== false) {\n this.sampleNameControl.show(); // If not explicitly set\n }\n }\n\n return newTrack\n\n } catch (error) {\n const httpMessages =\n {\n \"401\": \"Access unauthorized\",\n \"403\": \"Access forbidden\",\n \"404\": \"Not found\"\n };\n console.error(error);\n let msg = error.message || error.error || error.toString();\n if (httpMessages.hasOwnProperty(msg)) {\n msg = httpMessages[msg];\n }\n msg += (\": \" + config.url);\n this.alert.present(new Error(msg), undefined);\n }\n }\n\n /**\n * Public API function - load a region of interest\n *\n * @param config A \"track\" configuration object, or array of objects, of type == \"annotation\" (bed, gff, etc)\n *\n * @returns {Promise}\n */\n async loadROI(config) {\n await this.roiManager.loadROI(config, this.genome);\n }\n\n /**\n * Public API function - clear all regions of interest (ROI), including preloaded and user-defined ROIs\n */\n clearROIs() {\n this.roiManager.clearROIs();\n }\n\n /**\n * Public API function. Return a promise for the list of user-defined regions-of-interest\n */\n async getUserDefinedROIs() {\n\n if (this.roiManager) {\n\n const set = await this.roiManager.getUserDefinedROISet();\n if (undefined === set) {\n return []\n }\n\n const featureHash = await set.getAllFeatures();\n const featureList = [];\n for (let value of Object.values(featureHash)) {\n featureList.push(...value);\n }\n\n return featureList\n\n } else {\n return []\n }\n }\n\n getRulerTrackView() {\n const list = this.trackViews.filter(({track}) => 'ruler' === track.id);\n return list.length > 0 ? list[0] : undefined\n }\n\n /**\n * Create a Track object.\n * @param config\n * @returns {Promise<*>}\n */\n async createTrack(config) {\n\n // Resolve function and promise urls\n let url = await resolveURL(config.url || config.fastaURL);\n if (isString$2(url)) {\n url = url.trim();\n }\n\n if (url) {\n if (config.format) {\n config.format = config.format.toLowerCase();\n } else if (config.fastaURL) {\n config.format = \"fasta\"; // by definition\n } else {\n let filename = config.filename;\n if (!filename) {\n filename = await getFilename$1(url);\n }\n\n const format = inferFileFormat(filename);\n\n if (\"tsv\" === format) {\n config.format = await inferFileFormatFromHeader(config);\n } else if (format) {\n config.format = format;\n } else {\n if (config.sourceType === \"htsget\") {\n // Check for htsget URL. This is a longshot\n await HtsgetReader.inferFormat(config);\n }\n }\n }\n }\n\n\n let type = config.type ? config.type.toLowerCase() : undefined;\n\n if (!type) {\n type = inferTrackType(config);\n if (\"bedtype\" === type) {\n // Bed files must be read to determine track type\n const featureSource = FeatureSource(config, this.genome);\n config._featureSource = featureSource; // This is a temp variable, bit of a hack\n const trackType = await featureSource.trackType();\n if (trackType) {\n type = trackType;\n } else {\n type = \"annotation\";\n }\n }\n // Record in config to make type persistent in session\n config.type = type;\n }\n\n // Set defaults if specified\n if (this.trackDefaults && type) {\n const settings = this.trackDefaults[type];\n if (settings) {\n for (let property in settings) {\n if (settings.hasOwnProperty(property) && config[property] === undefined) {\n config[property] = settings[property];\n }\n }\n }\n }\n\n const track = TrackFactory.getTrack(type, config, this);\n if (undefined === track) {\n this.alert.present(new Error(`Error creating track. Could not determine track type for file: ${config.url || config}`), undefined);\n } else {\n\n if (config.roi && config.roi.length > 0) {\n track.roiSets = config.roi.map(r => new TrackROISet(r, this.genome));\n }\n\n return track\n }\n }\n\n\n reorderTracks() {\n\n this.trackViews.sort(function (a, b) {\n\n const firstSortOrder = tv => {\n return 'ideogram' === tv.track.id ? 1 :\n 'ruler' === tv.track.id ? 2 :\n 3\n };\n\n const aOrder1 = firstSortOrder(a);\n const bOrder1 = firstSortOrder(b);\n if (aOrder1 === bOrder1) {\n const aOrder2 = a.track.order || 0;\n const bOrder2 = b.track.order || 0;\n return aOrder2 - bOrder2\n } else {\n return aOrder1 - bOrder1\n }\n });\n\n // discard current track order\n for (let {axis, viewports, sampleNameViewport, outerScroll, dragHandle, gearContainer} of this.trackViews) {\n\n axis.remove();\n\n for (let {$viewport} of viewports) {\n $viewport.detach();\n }\n\n sampleNameViewport.viewport.remove();\n\n outerScroll.remove();\n dragHandle.remove();\n gearContainer.remove();\n }\n\n // Reattach the divs to the dom in the correct order\n const viewportColumns = this.columnContainer.querySelectorAll('.igv-column');\n\n for (let {axis, viewports, sampleNameViewport, outerScroll, dragHandle, gearContainer} of this.trackViews) {\n\n this.columnContainer.querySelector('.igv-axis-column').appendChild(axis);\n\n for (let i = 0; i < viewportColumns.length; i++) {\n const {$viewport} = viewports[i];\n viewportColumns[i].appendChild($viewport.get(0));\n }\n\n this.columnContainer.querySelector('.igv-sample-name-column').appendChild(sampleNameViewport.viewport);\n\n this.columnContainer.querySelector('.igv-scrollbar-column').appendChild(outerScroll);\n\n this.columnContainer.querySelector('.igv-track-drag-column').appendChild(dragHandle);\n\n this.columnContainer.querySelector('.igv-gear-menu-column').appendChild(gearContainer);\n }\n\n }\n\n getTrackOrder() {\n return this.trackViews.filter(tv => tv.track && tv.track.name).map(tv => tv.track.name)\n }\n\n /**\n * NOTE: Public API function\n *\n * Remove all tracks matching the given name. Usually this will be a single track, but there is no\n * guarantee names are unique\n *\n * @param name\n */\n removeTrackByName(name) {\n const copy = this.trackViews.slice();\n for (let trackView of copy) {\n if (name === trackView.track.name) {\n this.removeTrack(trackView.track);\n }\n }\n }\n\n /**\n * NOTE: Public API function\n *\n * Remove the given track. If it has already been removed this is a no-op.\n *\n * @param track\n */\n removeTrack(track) {\n for (let trackView of this.trackViews) {\n if (track === trackView.track) {\n this._removeTrack(trackView.track);\n break\n }\n }\n }\n\n _removeTrack(track) {\n if (track.disposed) return\n this.trackViews.splice(this.trackViews.indexOf(track.trackView), 1);\n this.fireEvent('trackremoved', [track]);\n this.fireEvent('trackorderchanged', [this.getTrackOrder()]);\n if (track.trackView) {\n track.trackView.dispose();\n }\n }\n\n /**\n * API function\n */\n removeAllTracks() {\n\n const remainingTrackViews = [];\n\n for (let trackView of this.trackViews) {\n\n if (trackView.track.id !== 'ruler' && trackView.track.id !== 'ideogram') {\n this.fireEvent('trackremoved', [trackView.track]);\n trackView.dispose();\n } else {\n remainingTrackViews.push(trackView);\n }\n }\n\n this.trackViews = remainingTrackViews;\n }\n\n /**\n *\n * @param property\n * @param value\n * @returns {Array} tracks with given property value. e.g. findTracks(\"type\", \"annotation\")\n */\n findTracks(property, value) {\n\n let f = typeof property === 'function' ?\n trackView => property(trackView.track) :\n trackView => value === trackView.track[property];\n\n return this.trackViews.filter(f).map(tv => tv.track)\n }\n\n /**\n * Set the track height globally for all tracks. (Note: Its not clear why this is useful).\n * @param newHeight\n */\n setTrackHeight(newHeight) {\n\n this.trackHeight = newHeight;\n\n this.trackViews.forEach(function (trackView) {\n trackView.setTrackHeight(newHeight);\n });\n\n }\n\n /**\n * API function to signal that this browser visibility has changed, e.g. from hiding/showing in a tab interface.\n *\n * @returns {Promise}\n */\n async visibilityChange() {\n this.layoutChange();\n }\n\n async layoutChange() {\n\n const status = this.referenceFrameList.find(referenceFrame => referenceFrame.bpPerPixel < 0);\n\n if (status) {\n const viewportWidth = this.calculateViewportWidth(this.referenceFrameList.length);\n for (let referenceFrame of this.referenceFrameList) {\n referenceFrame.bpPerPixel = (referenceFrame.end - referenceFrame.start) / viewportWidth;\n }\n }\n\n if (this.referenceFrameList) {\n const isWGV = this.isMultiLocusWholeGenomeView() || GenomeUtils.isWholeGenomeView(this.referenceFrameList[0].chr);\n this.navbarManager.navbarDidResize(this.$navigation.width(), isWGV);\n }\n\n resize.call(this);\n await this.updateViews();\n }\n\n async updateViews() {\n\n const trackViews = this.trackViews;\n\n this.updateLocusSearchWidget();\n\n for (let centerGuide of this.centerLineList) {\n centerGuide.repaint();\n }\n\n // Don't autoscale while dragging.\n if (this.dragObject) {\n for (let trackView of trackViews) {\n await trackView.updateViews();\n }\n } else {\n // Group autoscale\n const groupAutoscaleTracks = {};\n const otherTracks = [];\n for (let trackView of trackViews) {\n const group = trackView.track.autoscaleGroup;\n if (group) {\n var l = groupAutoscaleTracks[group];\n if (!l) {\n l = [];\n groupAutoscaleTracks[group] = l;\n }\n l.push(trackView);\n } else {\n otherTracks.push(trackView);\n }\n }\n\n if (Object.entries(groupAutoscaleTracks).length > 0) {\n\n const keys = Object.keys(groupAutoscaleTracks);\n for (let group of keys) {\n\n const groupTrackViews = groupAutoscaleTracks[group];\n const promises = [];\n\n for (let trackView of groupTrackViews) {\n promises.push(trackView.getInViewFeatures());\n }\n\n const featureArray = await Promise.all(promises);\n\n var allFeatures = [], dataRange;\n\n for (let features of featureArray) {\n allFeatures = allFeatures.concat(features);\n }\n dataRange = doAutoscale(allFeatures);\n\n const p = [];\n for (let trackView of groupTrackViews) {\n trackView.track.dataRange = dataRange;\n trackView.track.autoscale = false;\n p.push(trackView.updateViews());\n }\n await Promise.all(p);\n }\n\n }\n\n await Promise.all(otherTracks.map(tv => tv.updateViews()));\n // for (let trackView of otherTracks) {\n // await trackView.updateViews(force);\n // }\n }\n\n }\n\n repaintViews() {\n for (let trackView of this.trackViews) {\n trackView.repaintViews();\n }\n }\n\n updateLocusSearchWidget() {\n\n if(!this.referenceFrameList) return\n const referenceFrameList = this.referenceFrameList;\n\n // Update end position of reference frames based on pixel widths. This is hacky, but its been done here\n // for a long time, although indirectly.\n const width = this.calculateViewportWidth(this.referenceFrameList.length);\n for (let referenceFrame of referenceFrameList) {\n referenceFrame.end = referenceFrame.start + referenceFrame.bpPerPixel * width;\n }\n\n this.chromosomeSelectWidget.select.value = referenceFrameList.length === 1 ? this.referenceFrameList[0].chr : '';\n\n const loc = this.referenceFrameList.map(rf => rf.getLocusString()).join(' ');\n //const loc = this.referenceFrameList.length === 1 ? this.referenceFrameList[0].getLocusString() : '';\n this.$searchInput.val(loc);\n\n this.fireEvent('locuschange', [this.referenceFrameList]);\n }\n\n calculateViewportWidth(columnCount) {\n\n let {width} = this.columnContainer.getBoundingClientRect();\n\n const sampleNameViewportWidth = this.getSampleNameViewportWidth();\n\n width -= igv_axis_column_width + sampleNameViewportWidth + igv_scrollbar_outer_width + igv_track_manipulation_handle_width + igv_track_gear_menu_column_width;\n\n width -= column_multi_locus_shim_width * (columnCount - 1);\n\n return Math.floor(width / columnCount)\n }\n\n getCenterLineXOffset() {\n let {width: columnContainerWidth} = this.columnContainer.getBoundingClientRect();\n columnContainerWidth -= igv_axis_column_width + this.getSampleNameViewportWidth() + igv_scrollbar_outer_width + igv_track_manipulation_handle_width + igv_track_gear_menu_column_width;\n return Math.floor(columnContainerWidth / 2 + igv_axis_column_width)\n }\n\n minimumBases() {\n return this.config.minimumBases\n }\n\n // Zoom in by a factor of 2, keeping the same center location\n zoomIn() {\n this.zoomWithScaleFactor(0.5);\n };\n\n // Zoom out by a factor of 2, keeping the same center location if possible\n zoomOut() {\n this.zoomWithScaleFactor(2.0);\n };\n\n async zoomWithScaleFactor(scaleFactor, centerBPOrUndefined, referenceFrameOrUndefined) {\n\n if(!this.referenceFrameList) return\n\n const viewportWidth = this.calculateViewportWidth(this.referenceFrameList.length);\n\n let referenceFrames = referenceFrameOrUndefined ? [referenceFrameOrUndefined] : this.referenceFrameList;\n\n for (let referenceFrame of referenceFrames) {\n referenceFrame.zoomWithScaleFactor(this, scaleFactor, viewportWidth, centerBPOrUndefined);\n }\n }\n\n /**\n * Add a new multi-locus panel for the specified region\n * @param chr\n * @param start\n * @param end\n * @param referenceFrameLeft - optional, if supplied new panel should be placed to the immediate right\n */\n async addMultiLocusPanel(chr, start, end, referenceFrameLeft) {\n\n if(!this.referenceFrameList) return\n\n // account for reduced viewport width as a result of adding right mate pair panel\n const viewportWidth = this.calculateViewportWidth(1 + this.referenceFrameList.length);\n const scaleFactor = this.calculateViewportWidth(this.referenceFrameList.length) / this.calculateViewportWidth(1 + this.referenceFrameList.length);\n for (let refFrame of this.referenceFrameList) {\n refFrame.bpPerPixel *= scaleFactor;\n }\n\n const bpp = (end - start) / viewportWidth;\n const newReferenceFrame = new ReferenceFrame(this.genome, chr, start, end, bpp);\n const indexLeft = referenceFrameLeft ? this.referenceFrameList.indexOf(referenceFrameLeft) : this.referenceFrameList.length - 1;\n const indexRight = 1 + indexLeft;\n\n // TODO -- this is really ugly\n const {$viewport} = this.trackViews[0].viewports[indexLeft];\n const viewportColumn = viewportColumnManager.insertAfter($viewport.get(0).parentElement);\n\n if (indexRight === this.referenceFrameList.length) {\n this.referenceFrameList.push(newReferenceFrame);\n for (let trackView of this.trackViews) {\n const viewport = createViewport(trackView, viewportColumn, newReferenceFrame);\n trackView.viewports.push(viewport);\n }\n } else {\n this.referenceFrameList.splice(indexRight, 0, newReferenceFrame);\n for (let trackView of this.trackViews) {\n const viewport = createViewport(trackView, viewportColumn, newReferenceFrame);\n trackView.viewports.splice(indexRight, 0, viewport);\n }\n }\n\n\n this.centerLineList = this.createCenterLineList(this.columnContainer);\n\n resize.call(this);\n await this.updateViews(true);\n }\n\n async removeMultiLocusPanel(referenceFrame) {\n\n // find the $column corresponding to this referenceFrame and remove it\n const index = this.referenceFrameList.indexOf(referenceFrame);\n const {$viewport} = this.trackViews[0].viewports[index];\n viewportColumnManager.removeColumnAtIndex(index, $viewport.parent().get(0));\n\n for (let {viewports} of this.trackViews) {\n viewports[index].dispose();\n viewports.splice(index, 1);\n }\n\n this.referenceFrameList.splice(index, 1);\n\n if (1 === this.referenceFrameList.length && this.getRulerTrackView()) {\n for (let rulerViewport of this.getRulerTrackView().viewports) {\n rulerViewport.dismissLocusLabel();\n }\n }\n\n const scaleFactor = this.calculateViewportWidth(1 + this.referenceFrameList.length) / this.calculateViewportWidth(this.referenceFrameList.length);\n\n await this.rescaleForMultiLocus(scaleFactor);\n\n }\n\n /**\n * Goto the locus represented by the selected referenceFrame, discarding all other panels\n *\n * @param referenceFrame\n * @returns {Promise}\n */\n async gotoMultilocusPanel(referenceFrame) {\n\n const referenceFrameIndex = this.referenceFrameList.indexOf(referenceFrame);\n\n // Remove columns for unselected panels\n this.columnContainer.querySelectorAll('.igv-column').forEach((column, c) => {\n if (c === referenceFrameIndex) ; else {\n column.remove();\n }\n });\n\n // Remove all column shims\n this.columnContainer.querySelectorAll('.igv-column-shim').forEach(shim => shim.remove());\n\n // Discard viewports\n for (let trackView of this.trackViews) {\n const retain = trackView.viewports[referenceFrameIndex];\n trackView.viewports.filter((viewport, i) => i !== referenceFrameIndex).forEach(viewport => viewport.dispose());\n trackView.viewports = [retain];\n }\n\n const viewportWidth = this.calculateViewportWidth(1);\n referenceFrame.bpPerPixel = (referenceFrame.end - referenceFrame.start) / viewportWidth;\n this.referenceFrameList = [referenceFrame];\n\n this.trackViews.forEach(({viewports}) => viewports.forEach(viewport => viewport.setWidth(viewportWidth)));\n\n this.centerLineList = this.createCenterLineList(this.columnContainer);\n\n this.updateUIWithReferenceFrameList();\n\n await this.updateViews(true);\n\n }\n\n async rescaleForMultiLocus(scaleFactor) {\n\n const viewportWidth = this.calculateViewportWidth(this.referenceFrameList.length);\n\n for (let referenceFrame of this.referenceFrameList) {\n referenceFrame.bpPerPixel *= scaleFactor;\n }\n\n for (let {viewports} of this.trackViews) {\n\n for (let viewport of viewports) {\n viewport.setWidth(viewportWidth);\n }\n }\n\n this.centerLineList = this.createCenterLineList(this.columnContainer);\n\n this.updateUIWithReferenceFrameList();\n\n await this.updateViews();\n\n }\n\n /**\n * @deprecated This is a deprecated method with no known usages. To be removed in a future release.\n */\n async goto(chr, start, end) {\n await this.search(chr + \":\" + start + \"-\" + end);\n }\n\n /**\n\n * Search for the locus string -- this function is called from various igv.js GUI elements, and is not part of the\n * API. Wraps ```search``` and presents an error dialog if false.\n *\n * @param string\n * @param init\n * @returns {Promise}\n */\n async doSearch(string, init) {\n const success = await this.search(string, init);\n if (!success) {\n this.alert.present(new Error(`Unrecognized locus: ${string} `));\n }\n return success\n }\n\n\n /**\n * Search for the locus string\n * NOTE: This is part of the API\n * @param string\n * @param init true if called during browser initialization\n * @returns {Promise} true if found, false if not\n */\n async search(string, init) {\n\n const loci = await search(this, string);\n\n if (loci && loci.length > 0) {\n\n // create reference frame list based on search loci\n this.referenceFrameList = createReferenceFrameList(loci, this.genome, this.flanking, this.minimumBases(), this.calculateViewportWidth(loci.length), this.isSoftclipped());\n\n // discard viewport DOM elements\n for (let trackView of this.trackViews) {\n // empty axis column, viewport columns, sampleName column, scroll column, drag column, gear column\n trackView.removeDOMFromColumnContainer();\n }\n\n // discard ONLY viewport columns\n this.columnContainer.querySelectorAll('.igv-column-shim, .igv-column').forEach(el => el.remove());\n\n // Insert viewport columns preceding the sample-name column\n viewportColumnManager.insertBefore(this.columnContainer.querySelector('.igv-sample-name-column'), this.referenceFrameList.length);\n\n this.centerLineList = this.createCenterLineList(this.columnContainer);\n\n // Populate the columns\n for (let trackView of this.trackViews) {\n trackView.addDOMToColumnContainer(this, this.columnContainer, this.referenceFrameList);\n }\n\n this.updateUIWithReferenceFrameList();\n\n if (!init) {\n await this.updateViews();\n }\n return true\n } else {\n return false\n }\n }\n\n async loadSampleInformation(url) {\n var name = url;\n if (isFile(url)) {\n name = url.name;\n }\n var ext = name.substr(name.lastIndexOf('.') + 1);\n if (ext === 'fam') {\n this.sampleInformation = await loadPlinkFile(url);\n }\n };\n\n// EVENTS\n\n on(eventName, fn) {\n if (!this.eventHandlers[eventName]) {\n this.eventHandlers[eventName] = [];\n }\n this.eventHandlers[eventName].push(fn);\n };\n\n /**\n * @deprecated use off()\n * @param eventName\n * @param fn\n */\n un(eventName, fn) {\n this.off(eventName, fn);\n };\n\n off(eventName, fn) {\n\n if (!eventName) {\n this.eventHandlers = {}; // Remove all event handlers\n } else if (!fn) {\n this.eventHandlers[eventName] = []; // Remove all eventhandlers matching name\n } else {\n // Remove specific event handler\n const handlers = this.eventHandlers[eventName];\n if (!handlers || handlers.length === 0) {\n console.warn(\"No handlers to remove for event: \" + eventName);\n } else {\n const callbackIndex = handlers.indexOf(fn);\n if (callbackIndex !== -1) {\n this.eventHandlers[eventName].splice(callbackIndex, 1);\n }\n }\n }\n }\n\n fireEvent(eventName, args, thisObj) {\n\n const handlers = this.eventHandlers[eventName];\n if (undefined === handlers || handlers.length === 0) {\n return undefined\n }\n\n const scope = thisObj || window;\n const results = handlers.map(function (event) {\n return event.apply(scope, args)\n });\n\n return results[0]\n }\n\n dispose() {\n this.removeMouseHandlers();\n for (let trackView of this.trackViews) {\n trackView.dispose();\n }\n }\n\n /**\n * Return a json-like object (note not a json string) representing the current state.\n *\n */\n toJSON() {\n\n const json = {\n \"version\": version()\n };\n\n if (this.showSampleNames !== undefined) {\n json['showSampleNames'] = this.showSampleNames;\n }\n if (this.sampleNameViewportWidth !== defaultSampleNameViewportWidth) {\n json['sampleNameViewportWidth'] = this.sampleNameViewportWidth;\n }\n\n json[\"reference\"] = this.genome.toJSON();\n if (json.reference.fastaURL instanceof File) { // Test specifically for File. Other types of File-like objects might be savable) {\n throw new Error(`Error. Sessions cannot include local file references ${json.reference.fastaURL.name}.`)\n } else if (json.reference.indexURL instanceof File) { // Test specifically for File. Other types of File-like objects might be savable) {\n throw new Error(`Error. Sessions cannot include local file references ${json.reference.indexURL.name}.`)\n }\n\n // Build locus array (multi-locus view). Use the first track to extract the loci, any track could be used.\n const locus = [];\n const gtexSelections = {};\n let hasGtexSelections = false;\n let anyTrackView = this.trackViews[0];\n for (let {referenceFrame} of anyTrackView.viewports) {\n const locusString = referenceFrame.getLocusString();\n locus.push(locusString);\n if (referenceFrame.selection) {\n const selection = {\n gene: referenceFrame.selection.gene,\n snp: referenceFrame.selection.snp\n };\n gtexSelections[locusString] = selection;\n hasGtexSelections = true;\n }\n }\n json[\"locus\"] = locus.length === 1 ? locus[0] : locus;\n if (hasGtexSelections) {\n json[\"gtexSelections\"] = gtexSelections;\n }\n\n json[\"roi\"] = this.roiManager.toJSON();\n\n const trackJson = [];\n const errors = [];\n for (let {track} of this.trackViews) {\n try {\n let config;\n if (typeof track.getState === \"function\") {\n config = track.getState();\n } else {\n config = track.config;\n }\n\n if (config) {\n // null backpointer to browser\n if (config.browser) {\n delete config.browser;\n }\n config.order = track.order; //order++;\n trackJson.push(config);\n }\n } catch (e) {\n console.error(`Track: ${track.name}: ${e}`);\n errors.push(`Track: ${track.name}: ${e}`);\n }\n }\n\n if (errors.length > 0) {\n let n = 1;\n let message = 'Errors encountered saving session:
';\n for (let e of errors) {\n message += ` (${n++}) ${e.toString()}
`;\n }\n throw Error(message)\n }\n\n\n json[\"tracks\"] = trackJson;\n\n return json // This is an object, not a json string\n\n }\n\n compressedSession() {\n const json = JSON.stringify(this.toJSON());\n return compressString(json)\n }\n\n sessionURL() {\n const path = window.location.href.slice();\n const idx = path.indexOf(\"?\");\n const surl = (idx > 0 ? path.substring(0, idx) : path) + \"?sessionURL=blob:\" + this.compressedSession();\n return surl\n }\n\n /**\n * Record a mouse click on a specific viewport. This might be the start of a drag operation. Dragging\n * (panning) is handled here so that the mouse can move out of a specific viewport (e.g. stray into another\n * track) without halting the drag.\n *\n * @param e\n * @param viewport\n */\n mouseDownOnViewport(e, viewport) {\n\n var coords;\n coords = domUtils.pageCoordinates(e);\n this.vpMouseDown = {\n viewport,\n lastMouseX: coords.x,\n mouseDownX: coords.x,\n lastMouseY: coords.y,\n mouseDownY: coords.y,\n referenceFrame: viewport.referenceFrame\n };\n };\n\n cancelTrackPan() {\n\n const dragObject = this.dragObject;\n this.dragObject = undefined;\n this.isScrolling = false;\n this.vpMouseDown = undefined;\n\n if (dragObject && dragObject.viewport.referenceFrame.start !== dragObject.start) {\n this.updateViews();\n this.fireEvent('trackdragend');\n }\n }\n\n isTrackPanning() {\n return this.dragObject\n }\n\n isSoftclipped() {\n const result = this.trackViews.find(tv => tv.track.showSoftClips === true);\n return result !== undefined\n }\n\n\n /**\n * Track drag here refers to vertical dragging to reorder tracks, not horizontal panning.\n *\n * @param trackView\n */\n startTrackDrag(trackView) {\n\n this.dragTrack = trackView;\n\n }\n\n /**\n * Track drag here refers to vertical dragging to reorder tracks, not horizontal panning.\n *\n * @param dragDestination\n */\n updateTrackDrag(dragDestination) {\n\n if (dragDestination && this.dragTrack) {\n\n const dragged = this.dragTrack;\n const indexDestination = this.trackViews.indexOf(dragDestination);\n const indexDragged = this.trackViews.indexOf(dragged);\n const trackViews = this.trackViews;\n\n trackViews[indexDestination] = dragged;\n trackViews[indexDragged] = dragDestination;\n\n const newOrder = this.trackViews[indexDestination].track.order;\n this.trackViews[indexDragged].track.order = newOrder;\n\n const nTracks = trackViews.length;\n let lastOrder = newOrder;\n\n if (indexDestination < indexDragged) {\n // Displace tracks below\n\n for (let i = indexDestination + 1; i < nTracks; i++) {\n const track = trackViews[i].track;\n if (track.order <= lastOrder) {\n track.order = Math.min(Number.MAX_SAFE_INTEGER, lastOrder + 1);\n lastOrder = track.order;\n } else {\n break\n }\n }\n } else {\n // Displace tracks above. First track (index 0) is \"ruler\"\n for (let i = indexDestination - 1; i > 0; i--) {\n const track = trackViews[i].track;\n if (track.order >= lastOrder) {\n track.order = Math.max(-Number.MAX_SAFE_INTEGER, lastOrder - 1);\n lastOrder = track.order;\n } else {\n break\n }\n }\n }\n this.reorderTracks();\n }\n }\n\n /**\n * End vertical dragging of tracks (i.e. track re-order, not horizontal panning of data)\n */\n endTrackDrag() {\n if (this.dragTrack) {\n // this.dragTrack.$trackDragScrim.hide();\n this.dragTrack = undefined;\n this.fireEvent('trackorderchanged', [this.getTrackOrder()]);\n } else {\n this.dragTrack = undefined;\n }\n }\n\n /**\n * Mouse handlers to support drag (pan)\n */\n addMouseHandlers() {\n this.addWindowResizeHandler();\n this.addRootMouseUpHandler();\n this.addRootMouseLeaveHandler();\n this.addColumnContainerEventHandlers();\n }\n\n removeMouseHandlers() {\n this.removeWindowResizeHandler();\n this.removeRootMouseUpHandler();\n this.removeRootMouseLeaveHandler();\n this.removeColumnContainerEventHandlers();\n }\n\n addWindowResizeHandler() {\n // Create a copy of the prototype \"resize\" function bound to this instance. Neccessary to support removing.\n this.boundWindowResizeHandler = resize.bind(this);\n window.addEventListener('resize', this.boundWindowResizeHandler);\n }\n\n removeWindowResizeHandler() {\n window.removeEventListener('resize', this.boundWindowResizeHandler);\n }\n\n addRootMouseUpHandler() {\n this.boundRootMouseUpHandler = mouseUpOrLeave.bind(this);\n this.root.addEventListener('mouseup', this.boundRootMouseUpHandler);\n }\n\n removeRootMouseUpHandler() {\n this.root.removeEventListener('mouseup', this.boundRootMouseUpHandler);\n }\n\n addRootMouseLeaveHandler() {\n this.boundRootMouseLeaveHandler = mouseUpOrLeave.bind(this);\n this.root.addEventListener('mouseleave', this.boundRootMouseLeaveHandler);\n }\n\n removeRootMouseLeaveHandler() {\n this.root.removeEventListener('mouseleave', this.boundRootMouseLeaveHandler);\n }\n\n addColumnContainerEventHandlers() {\n this.boundColumnContainerMouseMoveHandler = handleMouseMove.bind(this);\n this.boundColumnContainerTouchMoveHandler = handleMouseMove.bind(this);\n this.boundColumnContainerMouseLeaveHandler = mouseUpOrLeave.bind(this);\n this.boundColumnContainerMouseUpHandler = mouseUpOrLeave.bind(this);\n this.boundColumnContainerTouchEndHandler = mouseUpOrLeave.bind(this);\n\n this.columnContainer.addEventListener('mousemove', this.boundColumnContainerMouseMoveHandler);\n this.columnContainer.addEventListener('touchmove', this.boundColumnContainerTouchMoveHandler);\n\n this.columnContainer.addEventListener('mouseleave', this.boundColumnContainerMouseLeaveHandler);\n\n this.columnContainer.addEventListener('mouseup', this.boundColumnContainerMouseUpHandler);\n this.columnContainer.addEventListener('touchend', this.boundColumnContainerTouchEndHandler);\n }\n\n removeColumnContainerEventHandlers() {\n this.columnContainer.removeEventListener('mousemove', this.boundColumnContainerMouseMoveHandler);\n this.columnContainer.removeEventListener('touchmove', this.boundColumnContainerTouchMoveHandler);\n\n this.columnContainer.removeEventListener('mouseleave', this.boundColumnContainerMouseLeaveHandler);\n\n this.columnContainer.removeEventListener('mouseup', this.boundColumnContainerMouseUpHandler);\n this.columnContainer.removeEventListener('touchend', this.boundColumnContainerTouchEndHandler);\n }\n\n static uncompressSession(url) {\n\n let bytes;\n if (url.indexOf('/gzip;base64') > 0) {\n //Proper dataURI\n bytes = decodeDataURI$1(url);\n let json = '';\n for (let b of bytes) {\n json += String.fromCharCode(b);\n }\n return json\n } else {\n\n let enc = url.substring(5);\n return uncompressString(enc)\n }\n }\n\n createCircularView(container, show) {\n show = show === true; // convert undefined to boolean\n this.circularView = createCircularView(container, this);\n this.circularViewControl = new CircularViewControl(this.$toggle_button_container.get(0), this);\n this.circularView.setAssembly({\n name: this.genome.id,\n id: this.genome.id,\n chromosomes: makeCircViewChromosomes(this.genome)\n });\n this.circularViewVisible = show;\n return this.circularView\n }\n\n get circularViewVisible() {\n return this.circularView !== undefined && this.circularView.visible\n }\n\n set circularViewVisible(isVisible) {\n if (this.circularView) {\n this.circularView.visible = isVisible;\n this.circularViewControl.setState(isVisible);\n }\n }\n}\n\n/**\n * Function called win window is resized, or visibility changed (e.g. \"show\" from a tab). This is a function rather\n * than class method because it needs to be copied and bound to specific instances of browser to support listener\n * removal\n *\n * @returns {Promise}\n */\nasync function resize() {\n\n if(!this.referenceFrameList) return\n\n const viewportWidth = this.calculateViewportWidth(this.referenceFrameList.length);\n\n for (let referenceFrame of this.referenceFrameList) {\n\n const index = this.referenceFrameList.indexOf(referenceFrame);\n\n const {chr, genome} = referenceFrame;\n\n const {bpLength} = genome.getChromosome(referenceFrame.chr);\n\n const viewportWidthBP = referenceFrame.toBP(viewportWidth);\n\n // viewportWidthBP > bpLength occurs when locus is full chromosome and user widens browser\n if (GenomeUtils.isWholeGenomeView(chr) || viewportWidthBP > bpLength) {\n // console.log(`${ Date.now() } Recalc referenceFrame(${ index }) bpp. viewport ${ StringUtils.numberFormatter(viewportWidthBP) } > ${ StringUtils.numberFormatter(bpLength) }.`)\n referenceFrame.bpPerPixel = bpLength / viewportWidth;\n } else {\n // console.log(`${ Date.now() } Recalc referenceFrame(${ index }) end.`)\n referenceFrame.end = referenceFrame.start + referenceFrame.toBP(viewportWidth);\n }\n\n for (let {viewports} of this.trackViews) {\n viewports[index].setWidth(viewportWidth);\n }\n\n }\n\n this.updateUIWithReferenceFrameList();\n\n //TODO -- update view only if needed. Reducing size never needed. Increasing size maybe\n\n await this.updateViews(true);\n}\n\n\nfunction handleMouseMove(e) {\n\n e.preventDefault();\n\n const {x, y} = domUtils.pageCoordinates(e);\n\n if (this.vpMouseDown) {\n\n const {viewport, referenceFrame} = this.vpMouseDown;\n\n // Determine direction, true == horizontal\n const horizontal = Math.abs((x - this.vpMouseDown.mouseDownX)) > Math.abs((y - this.vpMouseDown.mouseDownY));\n\n if (!this.dragObject && !this.isScrolling) {\n if (horizontal) {\n if (this.vpMouseDown.mouseDownX && Math.abs(x - this.vpMouseDown.mouseDownX) > this.constants.dragThreshold) {\n this.dragObject = {viewport, start: referenceFrame.start};\n }\n } else {\n if (this.vpMouseDown.mouseDownY &&\n Math.abs(y - this.vpMouseDown.mouseDownY) > this.constants.scrollThreshold) {\n // Scrolling => dragging track vertically\n this.isScrolling = true;\n const viewportHeight = viewport.$viewport.height();\n const contentHeight = viewport.trackView.maxViewportContentHeight();\n this.vpMouseDown.r = viewportHeight / contentHeight;\n }\n }\n }\n\n if (this.dragObject) {\n const clampDrag = !this.isSoftclipped();\n let deltaX = this.vpMouseDown.lastMouseX - x;\n const viewChanged = referenceFrame.shiftPixels(deltaX, viewport.$viewport.width(), clampDrag);\n if (viewChanged) {\n this.updateViews();\n }\n this.fireEvent('trackdrag');\n }\n\n\n if (this.isScrolling) {\n const delta = this.vpMouseDown.r * (this.vpMouseDown.lastMouseY - y);\n viewport.trackView.moveScroller(delta);\n }\n\n\n this.vpMouseDown.lastMouseX = x;\n this.vpMouseDown.lastMouseY = y;\n }\n}\n\nfunction mouseUpOrLeave(e) {\n this.cancelTrackPan();\n this.endTrackDrag();\n}\n\n\nfunction getInitialLocus(locus, genome) {\n if (locus) {\n return Array.isArray(locus) ? locus.join(' ') : locus\n } else {\n return genome.getHomeChromosomeName()\n }\n}\n\nfunction logo() {\n\n return $$1(\n '' +\n 'IGV' +\n '' +\n '' +\n '' +\n ';' +\n '' +\n ' '\n )\n}\n\nfunction toggleTrackLabels(trackViews, isVisible) {\n\n for (let {viewports} of trackViews) {\n for (let viewport of viewports) {\n if (viewport.$trackLabel) {\n if (0 === viewports.indexOf(viewport) && true === isVisible) {\n viewport.$trackLabel.show();\n } else {\n viewport.$trackLabel.hide();\n }\n }\n }\n }\n}\n\n/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2014 Broad Institute\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\nlet allBrowsers = [];\n\n/**\n * Create an igv.browser instance. This object defines the public API for interacting with the genome browser.\n *\n * @param parentDiv - DOM tree root\n * @param config - configuration options.\n *\n */\nasync function createBrowser(parentDiv, config) {\n\n if (undefined === config) config = {};\n\n // Initialize pre-defined genomes. The genome list is shared among all browser instances\n if (!GenomeUtils.KNOWN_GENOMES) {\n await GenomeUtils.initializeGenomes(config);\n }\n\n setDefaults(config);\n\n if (config.queryParametersSupported) {\n extractQuery(config);\n }\n if (config.apiKey) {\n igvxhr.setApiKey(config.apiKey);\n }\n if (config.oauthToken) {\n igvxhr.setOauthToken(config.oauthToken);\n }\n if (config.clientId && (!isInitialized())) {\n await init$1({\n clientId: config.clientId,\n apiKey: config.apiKey,\n scope: 'https://www.googleapis.com/auth/userinfo.profile'\n });\n }\n\n // Create browser\n const browser = new Browser(config, parentDiv);\n allBrowsers.push(browser);\n\n // Load initial session\n if (config.sessionURL) {\n await browser.loadSession({\n url: config.sessionURL\n });\n } else {\n await browser.loadSessionObject(config);\n }\n\n browser.navbarManager.navbarDidResize(browser.$navigation.width());\n\n return browser\n\n}\n\nfunction removeBrowser(browser) {\n browser.dispose();\n browser.root.remove();\n allBrowsers = allBrowsers.filter(item => item !== browser);\n}\n\nfunction removeAllBrowsers() {\n for (let browser of allBrowsers) {\n browser.dispose();\n browser.root.remove();\n }\n allBrowsers = [];\n}\n\n/**\n * This function provided so clients can inform igv of a visibility change, typically when an igv instance is\n * made visible from a tab, accordion, or similar widget.\n */\nasync function visibilityChange() {\n for (let browser of allBrowsers) {\n await browser.visibilityChange();\n }\n}\n\nfunction setDefaults(config) {\n\n if (undefined === config.minimumBases) {\n config.minimumBases = 40;\n }\n\n if (undefined === config.showIdeogram) {\n config.showIdeogram = true;\n }\n\n if (undefined === config.showCircularView) {\n config.showCircularView = false;\n }\n\n if (undefined === config.showCircularViewButton) {\n config.showCircularViewButton = false;\n }\n\n if (undefined === config.showTrackLabelButton) {\n config.showTrackLabelButton = true;\n }\n\n if (undefined === config.showTrackLabels) {\n config.showTrackLabels = true;\n }\n\n if (undefined === config.showROITableButton) {\n config.showROITableButton = false;\n }\n\n if (undefined === config.showROITable) {\n config.showROITable = false;\n }\n\n if (undefined === config.showCursorTrackingGuideButton) {\n config.showCursorTrackingGuideButton = true;\n }\n\n\n if (undefined === config.showCursorGuide) {\n config.showCursorGuide = config.showCursorTrackingGuide || false; // showCursorTrackingGuide is a synonym\n }\n\n if (undefined === config.showCenterGuideButton) {\n config.showCenterGuideButton = true;\n }\n\n if (undefined === config.showCenterGuide) {\n config.showCenterGuide = false;\n }\n\n if (undefined === config.showSampleNames) {\n config.showSampleNames = false;\n }\n\n if (undefined === config.showSVGButton) {\n config.showSVGButton = true;\n }\n\n if (config.showControls === undefined) {\n config.showControls = true;\n }\n\n if (config.showNavigation === undefined) {\n config.showNavigation = true;\n }\n\n if (config.showRuler === undefined) {\n config.showRuler = true;\n }\n\n if (config.flanking === undefined) {\n config.flanking = 1000;\n }\n\n if (config.pairsSupported === undefined) {\n config.pairsSupported = true;\n }\n\n if (!config.tracks) {\n config.tracks = [];\n }\n\n}\n\n\nfunction extractQuery(config) {\n\n var i1, i2, i, j, s, query, tokens, uri, key, value;\n\n uri = window.location.href;\n\n query = {};\n i1 = uri.indexOf(\"?\");\n i2 = uri.lastIndexOf(\"#\");\n\n let files;\n let indexURLs;\n let names;\n if (i1 >= 0) {\n if (i2 < 0) i2 = uri.length;\n for (i = i1 + 1; i < i2;) {\n j = uri.indexOf(\"&\", i);\n if (j < 0) j = i2;\n\n s = uri.substring(i, j);\n tokens = s.split(\"=\", 2);\n\n if (tokens.length === 2) {\n key = tokens[0];\n value = decodeURIComponent(tokens[1]);\n\n if ('file' === key) {\n // IGV desktop style file parameter\n files = value.split(',');\n } else if ('index' === key) {\n // IGV desktop style index parameter\n indexURLs = value.split(',');\n } else if ('name' === key) {\n // IGV desktop style index parameter\n names = value.split(',');\n } else if ('genome' === key && ((value.startsWith(\"https://\") || value.startsWith(\"http://\")) && !value.endsWith(\".json\"))) {\n // IGV desktop compatibility -- assuming url to fasta\n config['reference'] = {\n fastaURL: value,\n indexURL: value + \".fai\"\n };\n } else {\n config[key] = value;\n }\n i = j + 1;\n } else {\n i++;\n }\n }\n }\n\n if (files) {\n\n if (!config.tracks)\n config.tracks = [];\n for (let i = 0; i < files.length; i++) {\n\n if (files[i].endsWith(\".xml\") || files[i].endsWith(\".json\")) {\n config.sessionURL = files[i];\n break\n }\n\n const trackConfig = {url: files[i]};\n if (indexURLs && indexURLs.length > i) {\n trackConfig.indexURL = indexURLs[i];\n }\n if (names && names.length > i) {\n trackConfig.name = names[i];\n }\n config.tracks.push(trackConfig);\n }\n }\n\n return query\n}\n\n\nasync function createTrack(config, browser) {\n return await Browser.prototype.createTrack.call(browser, config)\n}\n\nfunction embedCSS() {\n\n var css = '.igv-navbar {\\n display: flex;\\n flex-flow: row;\\n flex-wrap: nowrap;\\n justify-content: space-between;\\n align-items: center;\\n box-sizing: border-box;\\n width: 100%;\\n color: #444;\\n font-size: 12px;\\n font-family: \\\"Open Sans\\\", sans-serif;\\n font-weight: 400;\\n line-height: 32px;\\n padding-left: 8px;\\n padding-right: 8px;\\n margin-top: 2px;\\n margin-bottom: 6px;\\n height: 32px;\\n border-style: solid;\\n border-radius: 3px;\\n border-width: thin;\\n border-color: #bfbfbf;\\n background-color: #f3f3f3;\\n}\\n.igv-navbar .igv-navbar-left-container {\\n display: flex;\\n flex-flow: row;\\n flex-wrap: nowrap;\\n justify-content: space-between;\\n align-items: center;\\n height: 32px;\\n line-height: 32px;\\n}\\n.igv-navbar .igv-navbar-left-container .igv-logo {\\n width: 34px;\\n height: 32px;\\n margin-right: 8px;\\n}\\n.igv-navbar .igv-navbar-left-container .igv-current-genome {\\n height: 32px;\\n margin-left: 4px;\\n margin-right: 4px;\\n user-select: none;\\n line-height: 32px;\\n vertical-align: middle;\\n text-align: center;\\n}\\n.igv-navbar .igv-navbar-left-container .igv-navbar-genomic-location {\\n display: flex;\\n flex-flow: row;\\n flex-wrap: nowrap;\\n justify-content: space-between;\\n align-items: center;\\n height: 100%;\\n}\\n.igv-navbar .igv-navbar-left-container .igv-navbar-genomic-location .igv-chromosome-select-widget-container {\\n display: flex;\\n flex-flow: column;\\n flex-wrap: nowrap;\\n justify-content: space-around;\\n align-items: center;\\n height: 100%;\\n width: 125px;\\n margin-right: 4px;\\n}\\n.igv-navbar .igv-navbar-left-container .igv-navbar-genomic-location .igv-chromosome-select-widget-container select {\\n display: block;\\n cursor: pointer;\\n width: 100px;\\n height: 75%;\\n outline: none;\\n font-size: 12px;\\n font-family: \\\"Open Sans\\\", sans-serif;\\n font-weight: 400;\\n}\\n.igv-navbar .igv-navbar-left-container .igv-navbar-genomic-location .igv-locus-size-group {\\n display: flex;\\n flex-flow: row;\\n flex-wrap: nowrap;\\n justify-content: space-between;\\n align-items: center;\\n margin-left: 8px;\\n height: 22px;\\n}\\n.igv-navbar .igv-navbar-left-container .igv-navbar-genomic-location .igv-locus-size-group .igv-search-container {\\n display: flex;\\n flex-flow: row;\\n flex-wrap: nowrap;\\n justify-content: flex-start;\\n align-items: center;\\n width: 210px;\\n height: 22px;\\n line-height: 22px;\\n}\\n.igv-navbar .igv-navbar-left-container .igv-navbar-genomic-location .igv-locus-size-group .igv-search-container input.igv-search-input {\\n cursor: text;\\n width: 85%;\\n height: 22px;\\n line-height: 22px;\\n font-size: 12px;\\n font-family: \\\"Open Sans\\\", sans-serif;\\n font-weight: 400;\\n text-align: left;\\n padding-left: 8px;\\n margin-right: 8px;\\n outline: none;\\n border-style: solid;\\n border-radius: 3px;\\n border-width: thin;\\n border-color: #bfbfbf;\\n background-color: white;\\n}\\n.igv-navbar .igv-navbar-left-container .igv-navbar-genomic-location .igv-locus-size-group .igv-search-container .igv-search-icon-container {\\n cursor: pointer;\\n height: 16px;\\n width: 16px;\\n}\\n.igv-navbar .igv-navbar-left-container .igv-navbar-genomic-location .igv-locus-size-group .igv-windowsize-panel-container {\\n margin-left: 4px;\\n user-select: none;\\n}\\n.igv-navbar .igv-navbar-right-container {\\n display: flex;\\n flex-flow: row;\\n flex-wrap: nowrap;\\n justify-content: space-between;\\n align-items: center;\\n height: 32px;\\n line-height: 32px;\\n}\\n.igv-navbar .igv-navbar-right-container .igv-navbar-toggle-button-container {\\n display: flex;\\n flex-flow: row;\\n flex-wrap: nowrap;\\n justify-content: space-between;\\n align-items: center;\\n height: 100%;\\n}\\n.igv-navbar .igv-navbar-right-container .igv-navbar-toggle-button-container div {\\n margin-left: 0;\\n margin-right: 4px;\\n}\\n.igv-navbar .igv-navbar-right-container .igv-navbar-toggle-button-container div:last-child {\\n margin-left: 0;\\n margin-right: 0;\\n}\\n.igv-navbar .igv-navbar-right-container .igv-navbar-toggle-button-container-750 {\\n display: none;\\n}\\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget {\\n color: #737373;\\n font-size: 18px;\\n height: 32px;\\n line-height: 32px;\\n margin-left: 8px;\\n user-select: none;\\n display: flex;\\n flex-flow: row;\\n flex-wrap: nowrap;\\n justify-content: flex-end;\\n align-items: center;\\n}\\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget div {\\n cursor: pointer;\\n margin-left: unset;\\n margin-right: unset;\\n}\\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget div:first-child {\\n height: 24px;\\n width: 24px;\\n margin-left: unset;\\n margin-right: 8px;\\n}\\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget div:last-child {\\n height: 24px;\\n width: 24px;\\n margin-left: 8px;\\n margin-right: unset;\\n}\\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget div:nth-child(even) {\\n display: block;\\n height: fit-content;\\n}\\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget input {\\n display: block;\\n width: 125px;\\n}\\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget svg {\\n display: block;\\n}\\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget-900 {\\n color: #737373;\\n font-size: 18px;\\n height: 32px;\\n line-height: 32px;\\n margin-left: 8px;\\n user-select: none;\\n display: flex;\\n flex-flow: row;\\n flex-wrap: nowrap;\\n justify-content: flex-end;\\n align-items: center;\\n}\\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget-900 div {\\n cursor: pointer;\\n margin-left: unset;\\n margin-right: unset;\\n}\\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget-900 div:first-child {\\n height: 24px;\\n width: 24px;\\n margin-left: unset;\\n margin-right: 8px;\\n}\\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget-900 div:last-child {\\n height: 24px;\\n width: 24px;\\n margin-left: 8px;\\n margin-right: unset;\\n}\\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget-900 div:nth-child(even) {\\n width: 0;\\n height: 0;\\n display: none;\\n}\\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget-900 input {\\n width: 0;\\n height: 0;\\n display: none;\\n}\\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget-900 svg {\\n display: block;\\n}\\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget-hidden {\\n display: none;\\n}\\n\\n.igv-navbar-button {\\n display: block;\\n box-sizing: unset;\\n padding-left: 6px;\\n padding-right: 6px;\\n height: 18px;\\n text-transform: capitalize;\\n user-select: none;\\n line-height: 18px;\\n text-align: center;\\n vertical-align: middle;\\n font-family: \\\"Open Sans\\\", sans-serif;\\n font-size: 11px;\\n font-weight: 200;\\n color: #737373;\\n background-color: #f3f3f3;\\n border-color: #737373;\\n border-style: solid;\\n border-width: thin;\\n border-radius: 6px;\\n}\\n\\n.igv-navbar-button-clicked {\\n color: white;\\n background-color: #737373;\\n}\\n\\n.igv-navbar-button:hover {\\n cursor: pointer;\\n}\\n\\n.igv-zoom-in-notice-container {\\n z-index: 1024;\\n position: absolute;\\n top: 8px;\\n left: 50%;\\n transform: translate(-50%, 0%);\\n display: flex;\\n flex-direction: row;\\n flex-wrap: nowrap;\\n justify-content: center;\\n align-items: center;\\n background-color: white;\\n}\\n.igv-zoom-in-notice-container > div {\\n padding-left: 4px;\\n padding-right: 4px;\\n padding-top: 2px;\\n padding-bottom: 2px;\\n width: 100%;\\n height: 100%;\\n font-family: \\\"Open Sans\\\", sans-serif;\\n font-size: 14px;\\n font-weight: 400;\\n color: #3f3f3f;\\n}\\n\\n.igv-zoom-in-notice {\\n position: absolute;\\n top: 10px;\\n left: 50%;\\n}\\n.igv-zoom-in-notice div {\\n position: relative;\\n left: -50%;\\n font-family: \\\"Open Sans\\\", sans-serif;\\n font-size: medium;\\n font-weight: 400;\\n color: #3f3f3f;\\n background-color: rgba(255, 255, 255, 0.51);\\n z-index: 64;\\n}\\n\\n.igv-container-spinner {\\n position: absolute;\\n top: 90%;\\n left: 50%;\\n transform: translate(-50%, -50%);\\n z-index: 1024;\\n width: 24px;\\n height: 24px;\\n pointer-events: none;\\n color: #737373;\\n}\\n\\n.igv-multi-locus-close-button {\\n position: absolute;\\n top: 2px;\\n right: 0;\\n padding-left: 2px;\\n padding-right: 2px;\\n width: 12px;\\n height: 12px;\\n color: #666666;\\n background-color: white;\\n z-index: 1000;\\n}\\n.igv-multi-locus-close-button > svg {\\n vertical-align: top;\\n}\\n\\n.igv-multi-locus-close-button:hover {\\n cursor: pointer;\\n color: #434343;\\n}\\n\\n.igv-multi-locus-ruler-label {\\n z-index: 64;\\n position: absolute;\\n top: 2px;\\n left: 0;\\n width: 100%;\\n height: 12px;\\n display: flex;\\n flex-flow: row;\\n flex-wrap: nowrap;\\n justify-content: center;\\n align-items: center;\\n}\\n.igv-multi-locus-ruler-label > div {\\n font-family: \\\"Open Sans\\\", sans-serif;\\n font-size: 12px;\\n color: rgb(16, 16, 16);\\n background-color: white;\\n}\\n.igv-multi-locus-ruler-label > div {\\n cursor: pointer;\\n}\\n\\n.igv-multi-locus-ruler-label-square-dot {\\n z-index: 64;\\n position: absolute;\\n left: 50%;\\n top: 5%;\\n transform: translate(-50%, 0%);\\n background-color: white;\\n display: flex;\\n flex-flow: row;\\n flex-wrap: nowrap;\\n justify-content: flex-start;\\n align-items: center;\\n}\\n.igv-multi-locus-ruler-label-square-dot > div:first-child {\\n width: 14px;\\n height: 14px;\\n}\\n.igv-multi-locus-ruler-label-square-dot > div:last-child {\\n margin-left: 16px;\\n font-family: \\\"Open Sans\\\", sans-serif;\\n font-size: 14px;\\n font-weight: 400;\\n color: rgb(16, 16, 16);\\n}\\n\\n.igv-ruler-sweeper {\\n display: none;\\n pointer-events: none;\\n position: absolute;\\n top: 26px;\\n bottom: 0;\\n left: 0;\\n width: 0;\\n z-index: 99999;\\n background-color: rgba(68, 134, 247, 0.25);\\n}\\n\\n.igv-ruler-tooltip {\\n pointer-events: none;\\n z-index: 128;\\n position: absolute;\\n top: 0;\\n left: 0;\\n width: 1px;\\n height: 32px;\\n background-color: transparent;\\n display: flex;\\n flex-flow: row;\\n flex-wrap: nowrap;\\n justify-content: flex-start;\\n align-items: center;\\n}\\n.igv-ruler-tooltip > div {\\n pointer-events: none;\\n width: 128px;\\n height: auto;\\n padding: 1px;\\n color: #373737;\\n font-size: 10px;\\n font-family: \\\"Open Sans\\\", sans-serif;\\n font-weight: 400;\\n background-color: white;\\n border-style: solid;\\n border-width: thin;\\n border-color: #373737;\\n}\\n\\n.igv-track-label {\\n position: absolute;\\n left: 8px;\\n top: 8px;\\n width: auto;\\n height: auto;\\n max-width: 50%;\\n padding-left: 4px;\\n padding-right: 4px;\\n white-space: nowrap;\\n overflow: hidden;\\n text-overflow: ellipsis;\\n font-family: \\\"Open Sans\\\", sans-serif;\\n font-size: small;\\n font-weight: 400;\\n text-align: center;\\n user-select: none;\\n -moz-user-select: none;\\n -webkit-user-select: none;\\n border-color: #444;\\n border-radius: 2px;\\n border-style: solid;\\n border-width: thin;\\n background-color: white;\\n z-index: 128;\\n cursor: pointer;\\n}\\n\\n.igv-track-label:hover,\\n.igv-track-label:focus,\\n.igv-track-label:active {\\n background-color: #e8e8e8;\\n}\\n\\n.igv-track-label-popup-shim {\\n padding-left: 8px;\\n padding-right: 8px;\\n padding-top: 4px;\\n}\\n\\n.igv-center-line {\\n display: none;\\n pointer-events: none;\\n position: absolute;\\n top: 0;\\n bottom: 0;\\n left: 50%;\\n transform: translateX(-50%);\\n z-index: 8;\\n user-select: none;\\n -moz-user-select: none;\\n -webkit-user-select: none;\\n border-left-style: dashed;\\n border-left-width: thin;\\n border-right-style: dashed;\\n border-right-width: thin;\\n}\\n\\n.igv-center-line-wide {\\n background-color: rgba(0, 0, 0, 0);\\n border-left-color: rgba(127, 127, 127, 0.51);\\n border-right-color: rgba(127, 127, 127, 0.51);\\n}\\n\\n.igv-center-line-thin {\\n background-color: rgba(0, 0, 0, 0);\\n border-left-color: rgba(127, 127, 127, 0.51);\\n border-right-color: rgba(0, 0, 0, 0);\\n}\\n\\n.igv-cursor-guide-horizontal {\\n display: none;\\n pointer-events: none;\\n user-select: none;\\n -moz-user-select: none;\\n -webkit-user-select: none;\\n position: absolute;\\n left: 0;\\n right: 0;\\n top: 50%;\\n height: 1px;\\n z-index: 1;\\n margin-left: 50px;\\n margin-right: 54px;\\n border-top-style: dotted;\\n border-top-width: thin;\\n border-top-color: rgba(127, 127, 127, 0.76);\\n}\\n\\n.igv-cursor-guide-vertical {\\n pointer-events: none;\\n user-select: none;\\n -moz-user-select: none;\\n -webkit-user-select: none;\\n position: absolute;\\n top: 0;\\n bottom: 0;\\n left: 50%;\\n width: 1px;\\n z-index: 1;\\n border-left-style: dotted;\\n border-left-width: thin;\\n border-left-color: rgba(127, 127, 127, 0.76);\\n display: none;\\n}\\n\\n.igv-user-feedback {\\n position: fixed;\\n top: 50%;\\n left: 50%;\\n transform: translate(-50%, -50%);\\n width: 512px;\\n height: 360px;\\n z-index: 2048;\\n background-color: white;\\n border-color: #a2a2a2;\\n border-style: solid;\\n border-width: thin;\\n font-family: \\\"Open Sans\\\", sans-serif;\\n font-size: medium;\\n font-weight: 400;\\n color: #444;\\n display: flex;\\n flex-direction: column;\\n flex-wrap: nowrap;\\n justify-content: flex-start;\\n align-items: center;\\n}\\n.igv-user-feedback div:first-child {\\n position: relative;\\n height: 24px;\\n width: 100%;\\n background-color: white;\\n border-bottom-color: #a2a2a2;\\n border-bottom-style: solid;\\n border-bottom-width: thin;\\n}\\n.igv-user-feedback div:first-child div {\\n position: absolute;\\n top: 2px;\\n width: 16px;\\n height: 16px;\\n background-color: transparent;\\n}\\n.igv-user-feedback div:first-child div:first-child {\\n left: 8px;\\n}\\n.igv-user-feedback div:first-child div:last-child {\\n cursor: pointer;\\n right: 8px;\\n}\\n.igv-user-feedback div:last-child {\\n width: 100%;\\n height: calc(100% - 24px);\\n border-width: 0;\\n}\\n.igv-user-feedback div:last-child div {\\n width: auto;\\n height: auto;\\n margin: 8px;\\n}\\n\\n.igv-generic-dialog-container {\\n position: absolute;\\n top: 0;\\n left: 0;\\n width: 300px;\\n height: 200px;\\n border-color: #7F7F7F;\\n border-radius: 4px;\\n border-style: solid;\\n border-width: thin;\\n font-family: \\\"Open Sans\\\", sans-serif;\\n font-size: medium;\\n font-weight: 400;\\n z-index: 2048;\\n background-color: white;\\n display: flex;\\n flex-flow: column;\\n flex-wrap: nowrap;\\n justify-content: flex-start;\\n align-items: center;\\n}\\n.igv-generic-dialog-container .igv-generic-dialog-header {\\n display: flex;\\n flex-flow: row;\\n flex-wrap: nowrap;\\n justify-content: flex-end;\\n align-items: center;\\n width: 100%;\\n height: 24px;\\n cursor: move;\\n border-top-left-radius: 4px;\\n border-top-right-radius: 4px;\\n border-bottom-color: #7F7F7F;\\n border-bottom-style: solid;\\n border-bottom-width: thin;\\n background-color: #eee;\\n}\\n.igv-generic-dialog-container .igv-generic-dialog-header div {\\n margin-right: 4px;\\n margin-bottom: 2px;\\n height: 12px;\\n width: 12px;\\n color: #7F7F7F;\\n}\\n.igv-generic-dialog-container .igv-generic-dialog-header div:hover {\\n cursor: pointer;\\n color: #444;\\n}\\n.igv-generic-dialog-container .igv-generic-dialog-one-liner {\\n color: #373737;\\n width: 95%;\\n height: 24px;\\n line-height: 24px;\\n text-align: left;\\n margin-top: 8px;\\n padding-left: 8px;\\n overflow-wrap: break-word;\\n background-color: white;\\n}\\n.igv-generic-dialog-container .igv-generic-dialog-label-input {\\n margin-top: 8px;\\n width: 95%;\\n height: 24px;\\n color: #373737;\\n line-height: 24px;\\n padding-left: 8px;\\n background-color: white;\\n display: flex;\\n flex-flow: row;\\n flex-wrap: nowrap;\\n justify-content: flex-start;\\n align-items: center;\\n}\\n.igv-generic-dialog-container .igv-generic-dialog-label-input div {\\n width: 30%;\\n height: 100%;\\n font-size: 16px;\\n text-align: right;\\n padding-right: 8px;\\n background-color: white;\\n}\\n.igv-generic-dialog-container .igv-generic-dialog-label-input input {\\n display: block;\\n height: 100%;\\n width: 100%;\\n padding-left: 4px;\\n font-family: \\\"Open Sans\\\", sans-serif;\\n font-weight: 400;\\n color: #373737;\\n text-align: left;\\n outline: none;\\n border-style: solid;\\n border-width: thin;\\n border-color: #7F7F7F;\\n background-color: white;\\n}\\n.igv-generic-dialog-container .igv-generic-dialog-label-input input {\\n width: 50%;\\n font-size: 16px;\\n}\\n.igv-generic-dialog-container .igv-generic-dialog-input {\\n margin-top: 8px;\\n width: calc(100% - 16px);\\n height: 24px;\\n color: #373737;\\n line-height: 24px;\\n display: flex;\\n flex-flow: row;\\n flex-wrap: nowrap;\\n justify-content: space-around;\\n align-items: center;\\n}\\n.igv-generic-dialog-container .igv-generic-dialog-input input {\\n display: block;\\n height: 100%;\\n width: 100%;\\n padding-left: 4px;\\n font-family: \\\"Open Sans\\\", sans-serif;\\n font-weight: 400;\\n color: #373737;\\n text-align: left;\\n outline: none;\\n border-style: solid;\\n border-width: thin;\\n border-color: #7F7F7F;\\n background-color: white;\\n}\\n.igv-generic-dialog-container .igv-generic-dialog-input input {\\n font-size: 16px;\\n}\\n.igv-generic-dialog-container .igv-generic-dialog-ok-cancel {\\n width: 100%;\\n height: 28px;\\n display: flex;\\n flex-flow: row;\\n flex-wrap: nowrap;\\n justify-content: space-around;\\n align-items: center;\\n}\\n.igv-generic-dialog-container .igv-generic-dialog-ok-cancel div {\\n margin-top: 32px;\\n color: white;\\n font-family: \\\"Open Sans\\\", sans-serif;\\n font-size: 14px;\\n font-weight: 400;\\n width: 75px;\\n height: 28px;\\n line-height: 28px;\\n text-align: center;\\n border-color: transparent;\\n border-style: solid;\\n border-width: thin;\\n border-radius: 2px;\\n}\\n.igv-generic-dialog-container .igv-generic-dialog-ok-cancel div:first-child {\\n margin-left: 32px;\\n margin-right: 0;\\n background-color: #5ea4e0;\\n}\\n.igv-generic-dialog-container .igv-generic-dialog-ok-cancel div:last-child {\\n margin-left: 0;\\n margin-right: 32px;\\n background-color: #c4c4c4;\\n}\\n.igv-generic-dialog-container .igv-generic-dialog-ok-cancel div:first-child:hover {\\n cursor: pointer;\\n background-color: #3b5c7f;\\n}\\n.igv-generic-dialog-container .igv-generic-dialog-ok-cancel div:last-child:hover {\\n cursor: pointer;\\n background-color: #7f7f7f;\\n}\\n.igv-generic-dialog-container .igv-generic-dialog-ok {\\n width: 100%;\\n height: 36px;\\n margin-top: 32px;\\n display: flex;\\n flex-flow: row;\\n flex-wrap: nowrap;\\n justify-content: space-around;\\n align-items: center;\\n}\\n.igv-generic-dialog-container .igv-generic-dialog-ok div {\\n width: 98px;\\n height: 36px;\\n line-height: 36px;\\n text-align: center;\\n color: white;\\n font-family: \\\"Open Sans\\\", sans-serif;\\n font-size: medium;\\n font-weight: 400;\\n border-color: white;\\n border-style: solid;\\n border-width: thin;\\n border-radius: 4px;\\n background-color: #2B81AF;\\n}\\n.igv-generic-dialog-container .igv-generic-dialog-ok div:hover {\\n cursor: pointer;\\n background-color: #25597f;\\n}\\n\\n.igv-generic-container {\\n position: absolute;\\n top: 0;\\n left: 0;\\n z-index: 2048;\\n background-color: white;\\n cursor: pointer;\\n display: flex;\\n flex-direction: row;\\n flex-wrap: wrap;\\n justify-content: flex-start;\\n align-items: center;\\n}\\n.igv-generic-container div:first-child {\\n cursor: move;\\n display: flex;\\n flex-flow: row;\\n flex-wrap: nowrap;\\n justify-content: flex-end;\\n align-items: center;\\n height: 24px;\\n width: 100%;\\n background-color: #dddddd;\\n}\\n.igv-generic-container div:first-child i {\\n display: block;\\n color: #5f5f5f;\\n cursor: pointer;\\n width: 14px;\\n height: 14px;\\n margin-right: 8px;\\n margin-bottom: 4px;\\n}\\n\\n.igv-menu-popup {\\n position: absolute;\\n top: 0;\\n left: 0;\\n width: max-content;\\n z-index: 4096;\\n cursor: pointer;\\n font-family: \\\"Open Sans\\\", sans-serif;\\n font-size: small;\\n font-weight: 400;\\n color: #4b4b4b;\\n background: white;\\n border-radius: 4px;\\n border-color: #7F7F7F;\\n border-style: solid;\\n border-width: thin;\\n display: flex;\\n flex-flow: column;\\n flex-wrap: nowrap;\\n justify-content: flex-start;\\n align-items: flex-end;\\n text-align: left;\\n}\\n.igv-menu-popup > div:not(:first-child) {\\n width: 100%;\\n}\\n.igv-menu-popup > div:not(:first-child) > div {\\n background: white;\\n}\\n.igv-menu-popup > div:not(:first-child) > div.context-menu {\\n padding-left: 4px;\\n padding-right: 4px;\\n}\\n.igv-menu-popup > div:not(:first-child) > div:last-child {\\n border-bottom-left-radius: 4px;\\n border-bottom-right-radius: 4px;\\n border-bottom-color: transparent;\\n border-bottom-style: solid;\\n border-bottom-width: thin;\\n}\\n.igv-menu-popup > div:not(:first-child) > div:hover {\\n background: #efefef;\\n}\\n\\n.igv-menu-popup-shim {\\n padding-left: 8px;\\n padding-right: 8px;\\n padding-bottom: 1px;\\n padding-top: 1px;\\n}\\n\\n.igv-menu-popup-header {\\n position: relative;\\n width: 100%;\\n height: 24px;\\n cursor: move;\\n border-top-color: transparent;\\n border-top-left-radius: 4px;\\n border-top-right-radius: 4px;\\n border-bottom-color: #7F7F7F;\\n border-bottom-style: solid;\\n border-bottom-width: thin;\\n background-color: #eee;\\n display: flex;\\n flex-flow: row;\\n flex-wrap: nowrap;\\n justify-content: flex-end;\\n align-items: center;\\n}\\n.igv-menu-popup-header div {\\n margin-right: 4px;\\n height: 12px;\\n width: 12px;\\n color: #7F7F7F;\\n}\\n.igv-menu-popup-header div:hover {\\n cursor: pointer;\\n color: #444;\\n}\\n\\n.igv-menu-popup-check-container {\\n display: flex;\\n flex-flow: row;\\n flex-wrap: nowrap;\\n justify-content: flex-start;\\n align-items: center;\\n width: 100%;\\n height: 20px;\\n margin-right: 4px;\\n background-color: transparent;\\n}\\n.igv-menu-popup-check-container div {\\n padding-top: 2px;\\n padding-left: 8px;\\n}\\n.igv-menu-popup-check-container div:first-child {\\n position: relative;\\n width: 12px;\\n height: 12px;\\n}\\n.igv-menu-popup-check-container div:first-child svg {\\n position: absolute;\\n width: 12px;\\n height: 12px;\\n}\\n\\n.igv-user-feedback {\\n position: fixed;\\n top: 50%;\\n left: 50%;\\n transform: translate(-50%, -50%);\\n width: 512px;\\n height: 360px;\\n z-index: 2048;\\n background-color: white;\\n border-color: #a2a2a2;\\n border-style: solid;\\n border-width: thin;\\n font-family: \\\"Open Sans\\\", sans-serif;\\n font-size: medium;\\n font-weight: 400;\\n color: #444;\\n display: flex;\\n flex-direction: column;\\n flex-wrap: nowrap;\\n justify-content: flex-start;\\n align-items: center;\\n}\\n.igv-user-feedback div:first-child {\\n position: relative;\\n height: 24px;\\n width: 100%;\\n background-color: white;\\n border-bottom-color: #a2a2a2;\\n border-bottom-style: solid;\\n border-bottom-width: thin;\\n}\\n.igv-user-feedback div:first-child div {\\n position: absolute;\\n top: 2px;\\n width: 16px;\\n height: 16px;\\n background-color: transparent;\\n}\\n.igv-user-feedback div:first-child div:first-child {\\n left: 8px;\\n}\\n.igv-user-feedback div:first-child div:last-child {\\n cursor: pointer;\\n right: 8px;\\n}\\n.igv-user-feedback div:last-child {\\n width: 100%;\\n height: calc(100% - 24px);\\n border-width: 0;\\n}\\n.igv-user-feedback div:last-child div {\\n width: auto;\\n height: auto;\\n margin: 8px;\\n}\\n\\n.igv-loading-spinner-container {\\n z-index: 1024;\\n position: absolute;\\n top: 50%;\\n left: 50%;\\n transform: translate(-50%, -50%);\\n width: 32px;\\n height: 32px;\\n display: flex;\\n flex-direction: row;\\n flex-wrap: nowrap;\\n justify-content: center;\\n align-items: center;\\n}\\n.igv-loading-spinner-container > div {\\n box-sizing: border-box;\\n width: 100%;\\n height: 100%;\\n border-radius: 50%;\\n border: 4px solid rgba(128, 128, 128, 0.5);\\n border-top-color: rgb(255, 255, 255);\\n animation: spin 1s ease-in-out infinite;\\n -webkit-animation: spin 1s ease-in-out infinite;\\n}\\n\\n@keyframes spin {\\n to {\\n -webkit-transform: rotate(360deg);\\n transform: rotate(360deg);\\n }\\n}\\n@-webkit-keyframes spin {\\n to {\\n -webkit-transform: rotate(360deg);\\n transform: rotate(360deg);\\n }\\n}\\n.igv-roi-menu-next-gen {\\n position: absolute;\\n z-index: 512;\\n font-family: \\\"Open Sans\\\", sans-serif;\\n font-size: small;\\n font-weight: 400;\\n color: #4b4b4b;\\n background-color: white;\\n width: 192px;\\n border-radius: 4px;\\n border-color: #7F7F7F;\\n border-style: solid;\\n border-width: thin;\\n display: flex;\\n flex-direction: column;\\n flex-wrap: nowrap;\\n justify-content: flex-start;\\n align-items: stretch;\\n}\\n.igv-roi-menu-next-gen > div:first-child {\\n height: 24px;\\n border-top-color: transparent;\\n border-top-left-radius: 4px;\\n border-top-right-radius: 4px;\\n border-bottom-color: #7F7F7F;\\n border-bottom-style: solid;\\n border-bottom-width: thin;\\n background-color: #eee;\\n display: flex;\\n flex-flow: row;\\n flex-wrap: nowrap;\\n justify-content: flex-end;\\n align-items: center;\\n}\\n.igv-roi-menu-next-gen > div:first-child > div {\\n margin-right: 4px;\\n height: 12px;\\n width: 12px;\\n color: #7F7F7F;\\n}\\n.igv-roi-menu-next-gen > div:first-child > div:hover {\\n cursor: pointer;\\n color: #444;\\n}\\n.igv-roi-menu-next-gen > div:last-child {\\n background-color: white;\\n border-bottom-left-radius: 4px;\\n border-bottom-right-radius: 4px;\\n border-bottom-color: transparent;\\n border-bottom-style: solid;\\n border-bottom-width: 0;\\n display: flex;\\n flex-direction: column;\\n flex-wrap: nowrap;\\n justify-content: flex-start;\\n align-items: stretch;\\n text-align: start;\\n vertical-align: middle;\\n}\\n.igv-roi-menu-next-gen > div:last-child > div {\\n height: 24px;\\n padding-left: 4px;\\n border-bottom-style: solid;\\n border-bottom-width: thin;\\n border-bottom-color: #7f7f7f;\\n}\\n.igv-roi-menu-next-gen > div:last-child > div:not(:first-child):hover {\\n background-color: rgba(127, 127, 127, 0.1);\\n}\\n.igv-roi-menu-next-gen > div:last-child div:first-child {\\n font-style: italic;\\n text-align: center;\\n padding-right: 4px;\\n white-space: nowrap;\\n overflow: hidden;\\n text-overflow: ellipsis;\\n}\\n.igv-roi-menu-next-gen > div:last-child > div:last-child {\\n border-bottom-width: 0;\\n border-bottom-color: transparent;\\n}\\n\\n.igv-roi-placeholder {\\n font-style: normal;\\n color: rgba(75, 75, 75, 0.6);\\n}\\n\\n.igv-roi-table {\\n position: absolute;\\n z-index: 1024;\\n width: min-content;\\n max-width: 1600px;\\n border-color: #7f7f7f;\\n border-radius: 4px;\\n border-style: solid;\\n border-width: thin;\\n font-family: \\\"Open Sans\\\", sans-serif;\\n font-size: 12px;\\n font-weight: 400;\\n background-color: white;\\n display: flex;\\n flex-flow: column;\\n flex-wrap: nowrap;\\n justify-content: flex-start;\\n align-items: stretch;\\n cursor: default;\\n}\\n.igv-roi-table > div {\\n height: 24px;\\n font-size: 14px;\\n text-align: start;\\n vertical-align: middle;\\n line-height: 24px;\\n}\\n.igv-roi-table > div:first-child {\\n border-color: transparent;\\n border-top-left-radius: 4px;\\n border-top-right-radius: 4px;\\n border-top-width: 0;\\n border-bottom-color: #7f7f7f;\\n border-bottom-style: solid;\\n border-bottom-width: thin;\\n background-color: #eee;\\n cursor: move;\\n display: flex;\\n flex-flow: row;\\n flex-wrap: nowrap;\\n justify-content: space-between;\\n align-items: center;\\n}\\n.igv-roi-table > div:first-child > div:first-child {\\n text-align: center;\\n white-space: nowrap;\\n text-overflow: ellipsis;\\n overflow: hidden;\\n margin-left: 4px;\\n margin-right: 4px;\\n width: calc(100% - 4px - 12px);\\n}\\n.igv-roi-table > div:first-child > div:last-child {\\n margin-right: 4px;\\n margin-bottom: 2px;\\n height: 12px;\\n width: 12px;\\n color: #7f7f7f;\\n}\\n.igv-roi-table > div:first-child > div:last-child > svg {\\n display: block;\\n}\\n.igv-roi-table > div:first-child > div:last-child:hover {\\n cursor: pointer;\\n color: #444;\\n}\\n.igv-roi-table > .igv-roi-table-description {\\n padding: 4px;\\n margin-left: 4px;\\n word-break: break-all;\\n overflow-y: auto;\\n display: flex;\\n flex-flow: row;\\n flex-wrap: nowrap;\\n background-color: transparent;\\n}\\n.igv-roi-table > .igv-roi-table-goto-explainer {\\n margin-top: 5px;\\n margin-left: 4px;\\n color: #7F7F7F;\\n font-style: italic;\\n height: 24px;\\n border-top: solid lightgray;\\n background-color: transparent;\\n}\\n.igv-roi-table > .igv-roi-table-column-titles {\\n height: 24px;\\n display: flex;\\n flex-flow: row;\\n flex-wrap: nowrap;\\n justify-content: stretch;\\n align-items: stretch;\\n padding-right: 16px;\\n background-color: white;\\n border-top-color: #7f7f7f;\\n border-top-style: solid;\\n border-top-width: thin;\\n border-bottom-color: #7f7f7f;\\n border-bottom-style: solid;\\n border-bottom-width: thin;\\n}\\n.igv-roi-table > .igv-roi-table-column-titles > div {\\n font-size: 14px;\\n vertical-align: middle;\\n line-height: 24px;\\n text-align: left;\\n margin-left: 4px;\\n height: 24px;\\n overflow: hidden;\\n text-overflow: ellipsis;\\n border-right-color: #7f7f7f;\\n border-right-style: solid;\\n border-right-width: thin;\\n}\\n.igv-roi-table > .igv-roi-table-column-titles > div:last-child {\\n border-right: unset;\\n}\\n.igv-roi-table > .igv-roi-table-row-container {\\n overflow: auto;\\n resize: both;\\n max-width: 1600px;\\n height: 360px;\\n background-color: transparent;\\n display: flex;\\n flex-flow: column;\\n flex-wrap: nowrap;\\n justify-content: flex-start;\\n align-items: stretch;\\n}\\n.igv-roi-table > .igv-roi-table-row-container > .igv-roi-table-row {\\n height: 24px;\\n display: flex;\\n flex-flow: row;\\n flex-wrap: nowrap;\\n justify-content: stretch;\\n align-items: stretch;\\n}\\n.igv-roi-table > .igv-roi-table-row-container > .igv-roi-table-row > div {\\n font-size: 14px;\\n vertical-align: middle;\\n line-height: 24px;\\n text-align: left;\\n margin-left: 4px;\\n height: 24px;\\n white-space: nowrap;\\n overflow: hidden;\\n text-overflow: ellipsis;\\n border-right-color: transparent;\\n border-right-style: solid;\\n border-right-width: thin;\\n}\\n.igv-roi-table > .igv-roi-table-row-container > .igv-roi-table-row > div:last-child {\\n border-right: unset;\\n}\\n.igv-roi-table > .igv-roi-table-row-container > .igv-roi-table-row-hover {\\n background-color: rgba(0, 0, 0, 0.04);\\n}\\n.igv-roi-table > div:last-child {\\n height: 32px;\\n line-height: 32px;\\n border-top-color: #7f7f7f;\\n border-top-style: solid;\\n border-top-width: thin;\\n border-bottom-color: transparent;\\n border-bottom-left-radius: 4px;\\n border-bottom-right-radius: 4px;\\n border-bottom-width: 0;\\n background-color: #eee;\\n display: flex;\\n flex-flow: row;\\n flex-wrap: nowrap;\\n justify-content: space-around;\\n align-items: center;\\n}\\n\\n.igv-roi-table-row-selected {\\n background-color: rgba(0, 0, 0, 0.125);\\n}\\n\\n.igv-roi-table-button {\\n cursor: pointer;\\n height: 20px;\\n user-select: none;\\n line-height: 20px;\\n text-align: center;\\n vertical-align: middle;\\n font-family: \\\"Open Sans\\\", sans-serif;\\n font-size: 13px;\\n font-weight: 400;\\n color: black;\\n padding-left: 6px;\\n padding-right: 6px;\\n background-color: rgb(239, 239, 239);\\n border-color: black;\\n border-style: solid;\\n border-width: thin;\\n border-radius: 3px;\\n}\\n\\n.igv-roi-table-button:hover {\\n font-weight: 400;\\n background-color: rgba(0, 0, 0, 0.13);\\n}\\n\\n.igv-roi-region {\\n z-index: 64;\\n position: absolute;\\n top: 0;\\n bottom: 0;\\n pointer-events: none;\\n overflow: visible;\\n margin-top: 44px;\\n display: flex;\\n flex-direction: column;\\n flex-wrap: nowrap;\\n justify-content: flex-start;\\n align-items: stretch;\\n}\\n.igv-roi-region > div {\\n position: relative;\\n width: 100%;\\n height: 8px;\\n pointer-events: auto;\\n}\\n\\n.igv-roi-menu {\\n position: absolute;\\n z-index: 1024;\\n width: 144px;\\n border-color: #7f7f7f;\\n border-radius: 4px;\\n border-style: solid;\\n border-width: thin;\\n font-family: \\\"Open Sans\\\", sans-serif;\\n background-color: white;\\n display: flex;\\n flex-flow: column;\\n flex-wrap: nowrap;\\n justify-content: flex-start;\\n align-items: stretch;\\n}\\n.igv-roi-menu > div:not(:last-child) {\\n border-bottom-color: rgba(128, 128, 128, 0.5);\\n border-bottom-style: solid;\\n border-bottom-width: thin;\\n}\\n.igv-roi-menu > div:first-child {\\n border-top-left-radius: 4px;\\n border-top-right-radius: 4px;\\n border-top-color: transparent;\\n border-top-style: solid;\\n border-top-width: 0;\\n}\\n.igv-roi-menu > div:last-child {\\n border-bottom-left-radius: 4px;\\n border-bottom-right-radius: 4px;\\n border-bottom-color: transparent;\\n border-bottom-style: solid;\\n border-bottom-width: 0;\\n}\\n\\n.igv-roi-menu-row {\\n height: 24px;\\n padding-left: 8px;\\n font-size: small;\\n text-align: start;\\n vertical-align: middle;\\n line-height: 24px;\\n background-color: white;\\n}\\n\\n.igv-roi-menu-row-edit-description {\\n width: -webkit-fill-available;\\n font-size: small;\\n text-align: start;\\n vertical-align: middle;\\n background-color: white;\\n padding-left: 4px;\\n padding-right: 4px;\\n padding-bottom: 4px;\\n display: flex;\\n flex-direction: column;\\n flex-wrap: nowrap;\\n justify-content: stretch;\\n align-items: stretch;\\n}\\n.igv-roi-menu-row-edit-description > label {\\n margin-left: 2px;\\n margin-bottom: 0;\\n display: block;\\n width: -webkit-fill-available;\\n}\\n.igv-roi-menu-row-edit-description > input {\\n display: block;\\n margin-left: 2px;\\n margin-right: 2px;\\n margin-bottom: 1px;\\n width: -webkit-fill-available;\\n}\\n\\n.igv-container {\\n position: relative;\\n display: flex;\\n flex-direction: column;\\n flex-wrap: nowrap;\\n justify-content: flex-start;\\n align-items: flex-start;\\n padding-top: 4px;\\n user-select: none;\\n -webkit-user-select: none;\\n -ms-user-select: none;\\n}\\n\\n.igv-viewport {\\n position: relative;\\n margin-top: 5px;\\n line-height: 1;\\n overflow-x: hidden;\\n overflow-y: hidden;\\n}\\n\\n.igv-viewport-content {\\n position: relative;\\n width: 100%;\\n}\\n.igv-viewport-content > canvas {\\n position: relative;\\n display: block;\\n}\\n\\n.igv-column-container {\\n position: relative;\\n display: flex;\\n flex-direction: row;\\n flex-wrap: nowrap;\\n justify-content: flex-start;\\n align-items: stretch;\\n width: 100%;\\n}\\n\\n.igv-column-shim {\\n width: 1px;\\n margin-left: 2px;\\n margin-right: 2px;\\n background-color: #545453;\\n}\\n\\n.igv-column {\\n position: relative;\\n position: relative;\\n display: flex;\\n flex-direction: column;\\n flex-wrap: nowrap;\\n justify-content: flex-start;\\n align-items: flex-start;\\n box-sizing: border-box;\\n height: 100%;\\n}\\n\\n.igv-axis-column {\\n position: relative;\\n display: flex;\\n flex-direction: column;\\n flex-wrap: nowrap;\\n justify-content: flex-start;\\n align-items: flex-start;\\n box-sizing: border-box;\\n height: 100%;\\n width: 50px;\\n}\\n.igv-axis-column > div {\\n margin-top: 5px;\\n width: 100%;\\n}\\n\\n.igv-sample-name-column {\\n position: relative;\\n display: flex;\\n flex-direction: column;\\n flex-wrap: nowrap;\\n justify-content: flex-start;\\n align-items: flex-start;\\n box-sizing: border-box;\\n height: 100%;\\n}\\n\\n.igv-scrollbar-column {\\n position: relative;\\n display: flex;\\n flex-direction: column;\\n flex-wrap: nowrap;\\n justify-content: flex-start;\\n align-items: flex-start;\\n box-sizing: border-box;\\n height: 100%;\\n width: 14px;\\n}\\n.igv-scrollbar-column > div {\\n position: relative;\\n margin-top: 5px;\\n width: 14px;\\n}\\n.igv-scrollbar-column > div > div {\\n cursor: pointer;\\n position: absolute;\\n top: 0;\\n left: 2px;\\n width: 8px;\\n border-width: 1px;\\n border-style: solid;\\n border-color: #c4c4c4;\\n border-top-left-radius: 4px;\\n border-top-right-radius: 4px;\\n border-bottom-left-radius: 4px;\\n border-bottom-right-radius: 4px;\\n}\\n.igv-scrollbar-column > div > div:hover {\\n background-color: #c4c4c4;\\n}\\n\\n.igv-track-drag-column {\\n position: relative;\\n display: flex;\\n flex-direction: column;\\n flex-wrap: nowrap;\\n justify-content: flex-start;\\n align-items: flex-start;\\n box-sizing: border-box;\\n height: 100%;\\n width: 12px;\\n background-color: white;\\n}\\n.igv-track-drag-column > .igv-track-drag-handle {\\n z-index: 512;\\n position: relative;\\n cursor: pointer;\\n margin-top: 5px;\\n width: 100%;\\n border-style: solid;\\n border-width: 0;\\n border-top-right-radius: 6px;\\n border-bottom-right-radius: 6px;\\n background-color: #c4c4c4;\\n}\\n.igv-track-drag-column .igv-track-drag-handle-hover {\\n background-color: #787878;\\n}\\n.igv-track-drag-column > .igv-track-drag-shim {\\n position: relative;\\n margin-top: 5px;\\n width: 100%;\\n border-style: solid;\\n border-width: 0;\\n}\\n\\n.igv-gear-menu-column {\\n position: relative;\\n display: flex;\\n flex-direction: column;\\n flex-wrap: nowrap;\\n justify-content: flex-start;\\n align-items: flex-start;\\n box-sizing: border-box;\\n height: 100%;\\n width: 28px;\\n}\\n.igv-gear-menu-column > div {\\n display: flex;\\n flex-direction: column;\\n flex-wrap: nowrap;\\n justify-content: flex-start;\\n align-items: center;\\n margin-top: 5px;\\n width: 100%;\\n background: white;\\n}\\n.igv-gear-menu-column > div > div {\\n position: relative;\\n margin-top: 4px;\\n width: 16px;\\n height: 16px;\\n color: #7F7F7F;\\n}\\n.igv-gear-menu-column > div > div:hover {\\n cursor: pointer;\\n color: #444;\\n}\\n\\n/*# sourceMappingURL=dom.css.map */\\n';\n\n var style = document.createElement('style');\n style.setAttribute('type', 'text/css');\n style.innerHTML = css;\n\n document.head.append(style);\n\n}\n\n// Defines the top-level API for the igv module\n\nconst setApiKey = igvxhr.setApiKey;\n\nembedCSS();\n\nfunction setGoogleOauthToken(accessToken) {\n return igvxhr.setOauthToken(accessToken)\n}\n\nfunction setOauthToken(accessToken, host) {\n return igvxhr.setOauthToken(accessToken, host)\n}\n\n// Backward compatibility\nconst oauth = igvxhr.oauth;\n\nvar index = {\n TrackUtils,\n IGVGraphics,\n MenuUtils,\n DataRangeDialog,\n createTrack,\n createBrowser,\n removeBrowser,\n removeAllBrowsers,\n visibilityChange,\n setGoogleOauthToken,\n setOauthToken,\n oauth,\n version,\n setApiKey,\n registerFileFormats\n};\n\nexport { index as default };\n","function div(options) {\n return create(\"div\", options);\n}\n\nfunction create(tag, options) {\n const elem = document.createElement(tag);\n if (options) {\n if (options.class) {\n elem.classList.add(options.class);\n }\n if (options.id) {\n elem.id = options.id;\n }\n if(options.style) {\n applyStyle(elem, options.style);\n }\n }\n return elem;\n}\n\nfunction hide(elem) {\n const cssStyle = getComputedStyle(elem);\n if(cssStyle.display !== \"none\") {\n elem._initialDisplay = cssStyle.display;\n }\n elem.style.display = \"none\";\n}\n\nfunction show(elem) {\n const currentDisplay = getComputedStyle(elem).display;\n if (currentDisplay === \"none\") {\n const d = elem._initialDisplay || \"block\";\n elem.style.display = d;\n }\n}\n\nfunction hideAll(selector) {\n document.querySelectorAll(selector).forEach(elem => { hide(elem); });\n}\n\nfunction empty(elem) {\n while(elem.firstChild){\n elem.removeChild(elem.firstChild);\n }\n}\n\nfunction offset(elem) {\n // Return zeros for disconnected and hidden (display: none) elements (gh-2310)\n // Support: IE <=11 only\n // Running getBoundingClientRect on a\n // disconnected node in IE throws an error\n if (!elem.getClientRects().length) {\n return {top: 0, left: 0};\n }\n\n // Get document-relative position by adding viewport scroll to viewport-relative gBCR\n const rect = elem.getBoundingClientRect();\n const win = elem.ownerDocument.defaultView;\n return {\n top: rect.top + win.pageYOffset,\n left: rect.left + win.pageXOffset\n };\n}\n\nfunction pageCoordinates(e) {\n\n if (e.type.startsWith(\"touch\")) {\n const touch = e.touches[0];\n return {x: touch.pageX, y: touch.pageY};\n } else {\n return {x: e.pageX, y: e.pageY}\n }\n}\n\nconst relativeDOMBBox = (parentElement, childElement) => {\n const { x: x_p, y: y_p, width: width_p, height: height_p } = parentElement.getBoundingClientRect();\n const { x: x_c, y: y_c, width: width_c, height: height_c } = childElement.getBoundingClientRect();\n return { x: (x_c - x_p), y: (y_c - y_p), width: width_c, height:height_c };\n};\n\nfunction applyStyle(elem, style) {\n for (let key of Object.keys(style)) {\n elem.style[key] = style[key];\n }\n}\n\nfunction guid () {\n return (\"0000\" + (Math.random() * Math.pow(36, 4) << 0).toString(36)).slice(-4);\n}\n\nlet getMouseXY = (domElement, { clientX, clientY }) => {\n\n // DOMRect object with eight properties: left, top, right, bottom, x, y, width, height\n const { left, top, width, height } = domElement.getBoundingClientRect();\n\n const x = clientX - left;\n const y = clientY - top;\n return { x, y, xNormalized: x/width, yNormalized: y/height, width, height };\n\n};\n\n/**\n * Translate the mouse coordinates for the event to the coordinates for the given target element\n * @param event\n * @param domElement\n * @returns {{x: number, y: number}}\n */\nfunction translateMouseCoordinates(event, domElement) {\n\n const { clientX, clientY } = event;\n return getMouseXY(domElement, { clientX, clientY });\n\n}\n\nvar domUtils = /*#__PURE__*/Object.freeze({\n __proto__: null,\n applyStyle: applyStyle,\n create: create,\n div: div,\n empty: empty,\n guid: guid,\n hide: hide,\n hideAll: hideAll,\n offset: offset,\n pageCoordinates: pageCoordinates,\n relativeDOMBBox: relativeDOMBBox,\n show: show,\n translateMouseCoordinates: translateMouseCoordinates\n});\n\nclass Textbox {\n\n constructor({value, label, onchange}) {\n\n this.elem = div({class: 'igv-ui-generic-dialog-label-input'});\n\n if(label) {\n const div$1 = div();\n div$1.innerHTML = label;\n this.elem.appendChild(div$1);\n }\n\n this.textBox = create('input');\n if(value) {\n this.textBox.value = value;\n }\n this.elem.appendChild(this.textBox);\n\n if(onchange) {\n this.textBox.addEventListener('change', (e) => onchange(this.textBox.value));\n }\n }\n\n get value() {\n return this.textBox.value;\n }\n\n set value(v) {\n this.textBox.value = v;\n }\n}\n\n/**\n * Generic container for UI components\n */\nclass Panel {\n\n constructor() {\n\n this.elem = create('div', {\n class: 'igv-ui-panel-column'\n });\n }\n\n add(component) {\n\n if(component instanceof Node) {\n this.elem.append(component);\n }\n else if(typeof component === 'object') {\n this.elem.append(component.elem);\n }\n else {\n // Assuming a string, possibly html\n const wrapper = div();\n wrapper.innerHTML = component;\n this.elem.append(wrapper);\n }\n }\n\n\n}\n\nfunction createCheckbox(name, initialState) {\n const container = div({class: 'igv-ui-trackgear-popover-check-container'});\n const svg = iconMarkup('check', (true === initialState ? '#444' : 'transparent'));\n svg.style.borderColor = 'gray';\n svg.style.borderWidth = '1px';\n svg.style.borderStyle = 'solid';\n\n container.appendChild(svg);\n let label = div(); //{ class: 'igv-some-label-class' });\n label.textContent = name;\n container.appendChild(label);\n\n return container;\n}\n\nfunction createIcon(name, color) {\n return iconMarkup(name, color);\n}\n\nfunction iconMarkup(name, color) {\n color = color || \"currentColor\";\n let icon = icons[name];\n if (!icon) {\n console.error(`No icon named: ${name}`);\n icon = icons[\"question\"];\n }\n\n const svg = document.createElementNS(\"http://www.w3.org/2000/svg\", \"svg\");\n svg.setAttributeNS(null,'viewBox', '0 0 ' + icon[0] + ' ' + icon[1]);\n const path = document.createElementNS(\"http://www.w3.org/2000/svg\", \"path\");\n path.setAttributeNS(null,'fill', color );\n path.setAttributeNS(null,'d', icon[4]);\n svg.appendChild(path);\n return svg;\n}\n\nconst icons = {\n \"check\": [512, 512, [], \"f00c\", \"M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z\"],\n \"cog\": [512, 512, [], \"f013\", \"M444.788 291.1l42.616 24.599c4.867 2.809 7.126 8.618 5.459 13.985-11.07 35.642-29.97 67.842-54.689 94.586a12.016 12.016 0 0 1-14.832 2.254l-42.584-24.595a191.577 191.577 0 0 1-60.759 35.13v49.182a12.01 12.01 0 0 1-9.377 11.718c-34.956 7.85-72.499 8.256-109.219.007-5.49-1.233-9.403-6.096-9.403-11.723v-49.184a191.555 191.555 0 0 1-60.759-35.13l-42.584 24.595a12.016 12.016 0 0 1-14.832-2.254c-24.718-26.744-43.619-58.944-54.689-94.586-1.667-5.366.592-11.175 5.459-13.985L67.212 291.1a193.48 193.48 0 0 1 0-70.199l-42.616-24.599c-4.867-2.809-7.126-8.618-5.459-13.985 11.07-35.642 29.97-67.842 54.689-94.586a12.016 12.016 0 0 1 14.832-2.254l42.584 24.595a191.577 191.577 0 0 1 60.759-35.13V25.759a12.01 12.01 0 0 1 9.377-11.718c34.956-7.85 72.499-8.256 109.219-.007 5.49 1.233 9.403 6.096 9.403 11.723v49.184a191.555 191.555 0 0 1 60.759 35.13l42.584-24.595a12.016 12.016 0 0 1 14.832 2.254c24.718 26.744 43.619 58.944 54.689 94.586 1.667 5.366-.592 11.175-5.459 13.985L444.788 220.9a193.485 193.485 0 0 1 0 70.2zM336 256c0-44.112-35.888-80-80-80s-80 35.888-80 80 35.888 80 80 80 80-35.888 80-80z\"],\n \"exclamation\": [192, 512, [], \"f12a\", \"M176 432c0 44.112-35.888 80-80 80s-80-35.888-80-80 35.888-80 80-80 80 35.888 80 80zM25.26 25.199l13.6 272C39.499 309.972 50.041 320 62.83 320h66.34c12.789 0 23.331-10.028 23.97-22.801l13.6-272C167.425 11.49 156.496 0 142.77 0H49.23C35.504 0 24.575 11.49 25.26 25.199z\"],\n \"exclamation-circle\": [512, 512, [], \"f06a\", \"M504 256c0 136.997-111.043 248-248 248S8 392.997 8 256C8 119.083 119.043 8 256 8s248 111.083 248 248zm-248 50c-25.405 0-46 20.595-46 46s20.595 46 46 46 46-20.595 46-46-20.595-46-46-46zm-43.673-165.346l7.418 136c.347 6.364 5.609 11.346 11.982 11.346h48.546c6.373 0 11.635-4.982 11.982-11.346l7.418-136c.375-6.874-5.098-12.654-11.982-12.654h-63.383c-6.884 0-12.356 5.78-11.981 12.654z\"],\n \"exclamation-triangle\": [576, 512, [], \"f071\", \"M569.517 440.013C587.975 472.007 564.806 512 527.94 512H48.054c-36.937 0-59.999-40.055-41.577-71.987L246.423 23.985c18.467-32.009 64.72-31.951 83.154 0l239.94 416.028zM288 354c-25.405 0-46 20.595-46 46s20.595 46 46 46 46-20.595 46-46-20.595-46-46-46zm-43.673-165.346l7.418 136c.347 6.364 5.609 11.346 11.982 11.346h48.546c6.373 0 11.635-4.982 11.982-11.346l7.418-136c.375-6.874-5.098-12.654-11.982-12.654h-63.383c-6.884 0-12.356 5.78-11.981 12.654z\"],\n \"minus\": [448, 512, [], \"f068\", \"M424 318.2c13.3 0 24-10.7 24-24v-76.4c0-13.3-10.7-24-24-24H24c-13.3 0-24 10.7-24 24v76.4c0 13.3 10.7 24 24 24h400z\"],\n \"minus-circle\": [512, 512, [], \"f056\", \"M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zM124 296c-6.6 0-12-5.4-12-12v-56c0-6.6 5.4-12 12-12h264c6.6 0 12 5.4 12 12v56c0 6.6-5.4 12-12 12H124z\"],\n \"minus-square\": [448, 512, [], \"f146\", \"M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM92 296c-6.6 0-12-5.4-12-12v-56c0-6.6 5.4-12 12-12h264c6.6 0 12 5.4 12 12v56c0 6.6-5.4 12-12 12H92z\"],\n \"plus\": [448, 512, [], \"f067\", \"M448 294.2v-76.4c0-13.3-10.7-24-24-24H286.2V56c0-13.3-10.7-24-24-24h-76.4c-13.3 0-24 10.7-24 24v137.8H24c-13.3 0-24 10.7-24 24v76.4c0 13.3 10.7 24 24 24h137.8V456c0 13.3 10.7 24 24 24h76.4c13.3 0 24-10.7 24-24V318.2H424c13.3 0 24-10.7 24-24z\"],\n \"plus-circle\": [512, 512, [], \"f055\", \"M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm144 276c0 6.6-5.4 12-12 12h-92v92c0 6.6-5.4 12-12 12h-56c-6.6 0-12-5.4-12-12v-92h-92c-6.6 0-12-5.4-12-12v-56c0-6.6 5.4-12 12-12h92v-92c0-6.6 5.4-12 12-12h56c6.6 0 12 5.4 12 12v92h92c6.6 0 12 5.4 12 12v56z\"],\n \"plus-square\": [448, 512, [], \"f0fe\", \"M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-32 252c0 6.6-5.4 12-12 12h-92v92c0 6.6-5.4 12-12 12h-56c-6.6 0-12-5.4-12-12v-92H92c-6.6 0-12-5.4-12-12v-56c0-6.6 5.4-12 12-12h92v-92c0-6.6 5.4-12 12-12h56c6.6 0 12 5.4 12 12v92h92c6.6 0 12 5.4 12 12v56z\"],\n \"question\": [384, 512, [], \"f128\", \"M202.021 0C122.202 0 70.503 32.703 29.914 91.026c-7.363 10.58-5.093 25.086 5.178 32.874l43.138 32.709c10.373 7.865 25.132 6.026 33.253-4.148 25.049-31.381 43.63-49.449 82.757-49.449 30.764 0 68.816 19.799 68.816 49.631 0 22.552-18.617 34.134-48.993 51.164-35.423 19.86-82.299 44.576-82.299 106.405V320c0 13.255 10.745 24 24 24h72.471c13.255 0 24-10.745 24-24v-5.773c0-42.86 125.268-44.645 125.268-160.627C377.504 66.256 286.902 0 202.021 0zM192 373.459c-38.196 0-69.271 31.075-69.271 69.271 0 38.195 31.075 69.27 69.271 69.27s69.271-31.075 69.271-69.271-31.075-69.27-69.271-69.27z\"],\n \"save\": [448, 512, [], \"f0c7\", \"M433.941 129.941l-83.882-83.882A48 48 0 0 0 316.118 32H48C21.49 32 0 53.49 0 80v352c0 26.51 21.49 48 48 48h352c26.51 0 48-21.49 48-48V163.882a48 48 0 0 0-14.059-33.941zM224 416c-35.346 0-64-28.654-64-64 0-35.346 28.654-64 64-64s64 28.654 64 64c0 35.346-28.654 64-64 64zm96-304.52V212c0 6.627-5.373 12-12 12H76c-6.627 0-12-5.373-12-12V108c0-6.627 5.373-12 12-12h228.52c3.183 0 6.235 1.264 8.485 3.515l3.48 3.48A11.996 11.996 0 0 1 320 111.48z\"],\n \"search\": [512, 512, [], \"f002\", \"M505 442.7L405.3 343c-4.5-4.5-10.6-7-17-7H372c27.6-35.3 44-79.7 44-128C416 93.1 322.9 0 208 0S0 93.1 0 208s93.1 208 208 208c48.3 0 92.7-16.4 128-44v16.3c0 6.4 2.5 12.5 7 17l99.7 99.7c9.4 9.4 24.6 9.4 33.9 0l28.3-28.3c9.4-9.4 9.4-24.6.1-34zM208 336c-70.7 0-128-57.2-128-128 0-70.7 57.2-128 128-128 70.7 0 128 57.2 128 128 0 70.7-57.2 128-128 128z\"],\n \"share\": [512, 512, [], \"f064\", \"M503.691 189.836L327.687 37.851C312.281 24.546 288 35.347 288 56.015v80.053C127.371 137.907 0 170.1 0 322.326c0 61.441 39.581 122.309 83.333 154.132 13.653 9.931 33.111-2.533 28.077-18.631C66.066 312.814 132.917 274.316 288 272.085V360c0 20.7 24.3 31.453 39.687 18.164l176.004-152c11.071-9.562 11.086-26.753 0-36.328z\"],\n \"spinner\": [512, 512, [], \"f110\", \"M304 48c0 26.51-21.49 48-48 48s-48-21.49-48-48 21.49-48 48-48 48 21.49 48 48zm-48 368c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48-21.49-48-48-48zm208-208c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48-21.49-48-48-48zM96 256c0-26.51-21.49-48-48-48S0 229.49 0 256s21.49 48 48 48 48-21.49 48-48zm12.922 99.078c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48c0-26.509-21.491-48-48-48zm294.156 0c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48c0-26.509-21.49-48-48-48zM108.922 60.922c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48-21.491-48-48-48z\"],\n \"square\": [448, 512, [], \"f0c8\", \"M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48z\"],\n \"square-full\": [512, 512, [], \"f45c\", \"M512 512H0V0h512v512z\"],\n \"times\": [384, 512, [], \"f00d\", \"M323.1 441l53.9-53.9c9.4-9.4 9.4-24.5 0-33.9L279.8 256l97.2-97.2c9.4-9.4 9.4-24.5 0-33.9L323.1 71c-9.4-9.4-24.5-9.4-33.9 0L192 168.2 94.8 71c-9.4-9.4-24.5-9.4-33.9 0L7 124.9c-9.4 9.4-9.4 24.5 0 33.9l97.2 97.2L7 353.2c-9.4 9.4-9.4 24.5 0 33.9L60.9 441c9.4 9.4 24.5 9.4 33.9 0l97.2-97.2 97.2 97.2c9.3 9.3 24.5 9.3 33.9 0z\"],\n \"times-circle\": [512, 512, [], \"f057\", \"M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm121.6 313.1c4.7 4.7 4.7 12.3 0 17L338 377.6c-4.7 4.7-12.3 4.7-17 0L256 312l-65.1 65.6c-4.7 4.7-12.3 4.7-17 0L134.4 338c-4.7-4.7-4.7-12.3 0-17l65.6-65-65.6-65.1c-4.7-4.7-4.7-12.3 0-17l39.6-39.6c4.7-4.7 12.3-4.7 17 0l65 65.7 65.1-65.6c4.7-4.7 12.3-4.7 17 0l39.6 39.6c4.7 4.7 4.7 12.3 0 17L312 256l65.6 65.1z\"],\n \"wrench\": [512, 512, [], \"f0ad\", \"M481.156 200c9.3 0 15.12 10.155 10.325 18.124C466.295 259.992 420.419 288 368 288c-79.222 0-143.501-63.974-143.997-143.079C223.505 65.469 288.548-.001 368.002 0c52.362.001 98.196 27.949 123.4 69.743C496.24 77.766 490.523 88 481.154 88H376l-40 56 40 56h105.156zm-171.649 93.003L109.255 493.255c-24.994 24.993-65.515 24.994-90.51 0-24.993-24.994-24.993-65.516 0-90.51L218.991 202.5c16.16 41.197 49.303 74.335 90.516 90.503zM104 432c0-13.255-10.745-24-24-24s-24 10.745-24 24 10.745 24 24 24 24-10.745 24-24z\"],\n};\n\nvar icons$1 = /*#__PURE__*/Object.freeze({\n __proto__: null,\n createCheckbox: createCheckbox,\n createIcon: createIcon\n});\n\nfunction attachDialogCloseHandlerWithParent(parent, closeHandler) {\n\n var container = document.createElement(\"div\");\n parent.appendChild(container);\n container.appendChild(createIcon(\"times\"));\n container.addEventListener('click', function (e) {\n e.preventDefault();\n e.stopPropagation();\n closeHandler();\n });\n}\n\nvar uiUtils = /*#__PURE__*/Object.freeze({\n __proto__: null,\n attachDialogCloseHandlerWithParent: attachDialogCloseHandlerWithParent\n});\n\n/**\n * Make the target element movable by clicking and dragging on the handle. This is not a general purprose function,\n * it makes several options specific to igv dialogs, the primary one being that the\n * target is absolutely positioned in pixel coordinates\n\n */\n\nlet dragData; // Its assumed we are only dragging one element at a time.\n\nfunction makeDraggable(target, handle, constraint) {\n\n handle.addEventListener('mousedown', dragStart.bind(target));\n\n function dragStart(event) {\n\n event.stopPropagation();\n event.preventDefault();\n\n const dragFunction = drag.bind(this);\n const dragEndFunction = dragEnd.bind(this);\n const computedStyle = getComputedStyle(this);\n\n dragData =\n {\n constraint,\n dragFunction,\n dragEndFunction,\n screenX: event.screenX,\n screenY: event.screenY,\n top: parseInt(computedStyle.top.replace(\"px\", \"\")),\n left: parseInt(computedStyle.left.replace(\"px\", \"\"))\n };\n\n document.addEventListener('mousemove', dragFunction);\n document.addEventListener('mouseup', dragEndFunction);\n document.addEventListener('mouseleave', dragEndFunction);\n document.addEventListener('mouseexit', dragEndFunction);\n }\n}\n\nfunction drag(event) {\n\n if (!dragData) {\n console.error(\"No drag data!\");\n return;\n }\n event.stopPropagation();\n event.preventDefault();\n const dx = event.screenX - dragData.screenX;\n const dy = event.screenY - dragData.screenY;\n\n const left = dragData.left + dx;\n const top = dragData.constraint ? Math.max(dragData.constraint.minY, dragData.top + dy) : dragData.top + dy;\n\n this.style.left = `${ left }px`;\n this.style.top = `${ top }px`;\n}\n\nfunction dragEnd(event) {\n\n if (!dragData) {\n console.error(\"No drag data!\");\n return;\n }\n event.stopPropagation();\n event.preventDefault();\n\n const dragFunction = dragData.dragFunction;\n const dragEndFunction = dragData.dragEndFunction;\n document.removeEventListener('mousemove', dragFunction);\n document.removeEventListener('mouseup', dragEndFunction);\n document.removeEventListener('mouseleave', dragEndFunction);\n document.removeEventListener('mouseexit', dragEndFunction);\n dragData = undefined;\n}\n\nclass Dialog {\n\n constructor({label, content, okHandler, cancelHandler}) {\n\n const cancel = () => {\n hide(this.elem);\n if (typeof cancelHandler === 'function') {\n cancelHandler(this);\n }\n };\n\n // dialog container\n this.elem = div({class: 'igv-ui-generic-dialog-container'});\n\n // dialog header\n const header = div({class: 'igv-ui-generic-dialog-header'});\n this.elem.appendChild(header);\n\n attachDialogCloseHandlerWithParent(header, cancel);\n\n // dialog label\n if(label) {\n const labelDiv = div({class: 'igv-ui-dialog-one-liner'});\n this.elem.appendChild(labelDiv);\n labelDiv.innerHTML = label;\n }\n\n // input container\n content.elem.style.margin = '8px';\n this.elem.appendChild(content.elem);\n\n // ok | cancel\n const buttons = div({class: 'igv-ui-generic-dialog-ok-cancel'});\n this.elem.appendChild(buttons);\n\n // ok\n this.ok = div();\n buttons.appendChild(this.ok);\n this.ok.textContent = 'OK';\n\n // cancel\n this.cancel = div();\n buttons.appendChild(this.cancel);\n this.cancel.textContent = 'Cancel';\n\n this.ok.addEventListener('click', (e) => {\n hide(this.elem);\n if (typeof okHandler === 'function') {\n okHandler(this);\n }\n });\n\n this.cancel.addEventListener('click', cancel);\n\n makeDraggable(this.elem, header);\n\n\n // Consume all clicks in component\n this.elem.addEventListener('click', (e) => {\n e.preventDefault();\n e.stopPropagation();\n });\n\n }\n\n present(options, e) {\n\n this.label.textContent = options.label;\n this.input.value = options.value;\n this.callback = options.callback;\n\n const page = pageCoordinates(e);\n this.clampLocation(page.x, page.y);\n\n show(this.elem);\n }\n\n clampLocation(pageX, pageY) {\n\n let popoverRect = this.elem.getBoundingClientRect();\n let parentRect = this.parent.getBoundingClientRect();\n const y = Math.min(Math.max(pageY, parentRect.y), parentRect.y + parentRect.height - popoverRect.height);\n const x = Math.min(Math.max(pageX, parentRect.x), parentRect.x + parentRect.width - popoverRect.width);\n this.elem.style.left = x + \"px\";\n this.elem.style.top = y + \"px\";\n }\n}\n\nclass DataRangeDialog {\n\n constructor(parent, okHandler) {\n\n const panel = new Panel();\n this.minbox = new Textbox({label: \"Minimum\", value: \"0\"});\n panel.add(this.minbox);\n\n this.maxbox = new Textbox({label: \"Maximum\", value: \"0\"});\n panel.add(this.maxbox);\n\n let callback;\n if (okHandler) {\n callback = (e) => {\n okHandler(Number.parseFloat(this.minbox.value), Number.parseFloat(this.maxbox.value));\n };\n } else {\n callback = (d) => {\n console.log(`Minimum: ${this.minbox.value}`);\n console.log(`Maximum: ${this.maxbox.value}`);\n };\n }\n\n this.dialog = new Dialog({\n //label: 'Multi-select',\n content: panel,\n okHandler: callback\n });\n\n // Overide some css styles -- TODO redesign this.\n this.dialog.elem.style.position = \"absolute\";\n\n hide(this.dialog.elem);\n parent.appendChild(this.dialog.elem);\n }\n\n show({min, max}) {\n if (min !== undefined) this.minbox.value = min.toString();\n if (max !== undefined) this.maxbox.value = max.toString();\n show(this.dialog.elem);\n }\n}\n\nconst httpMessages =\n {\n \"401\": \"Access unauthorized\",\n \"403\": \"Access forbidden\",\n \"404\": \"Not found\"\n };\n\n\nclass AlertDialog {\n /**\n * Initialize a new alert dialog\n * @param parent\n * @param alertProps - Optional - properties such as scroll to error\n */\n constructor(parent, alertProps) {\n this.alertProps = Object.assign({\n /** When an alert is presented - focus occur */\n shouldFocus: true,\n /** When focus occur - scroll into that element in the view */\n preventScroll: false\n }, alertProps);\n\n // container\n this.container = div({class: \"igv-ui-alert-dialog-container\"});\n parent.appendChild(this.container);\n this.container.setAttribute('tabIndex', '-1');\n\n // header\n const header = div();\n this.container.appendChild(header);\n\n this.errorHeadline = div();\n header.appendChild(this.errorHeadline);\n this.errorHeadline.textContent = '';\n\n // body container\n let bodyContainer = div({class: 'igv-ui-alert-dialog-body'});\n this.container.appendChild(bodyContainer);\n\n // body copy\n this.body = div({class: 'igv-ui-alert-dialog-body-copy'});\n bodyContainer.appendChild(this.body);\n\n // ok container\n let ok_container = div();\n this.container.appendChild(ok_container);\n\n // ok\n this.ok = div();\n ok_container.appendChild(this.ok);\n this.ok.textContent = 'OK';\n\n const okHandler = () => {\n\n if (typeof this.callback === 'function') {\n this.callback(\"OK\");\n this.callback = undefined;\n }\n this.body.innerHTML = '';\n hide(this.container);\n };\n\n this.ok.addEventListener('click', event => {\n\n event.stopPropagation();\n\n okHandler();\n });\n\n this.container.addEventListener('keypress', event => {\n\n event.stopPropagation();\n\n if ('Enter' === event.key) {\n okHandler();\n }\n });\n\n makeDraggable(this.container, header);\n\n hide(this.container);\n }\n\n present(alert, callback) {\n\n this.errorHeadline.textContent = alert.message ? 'ERROR' : '';\n let string = alert.message || alert;\n\n if (httpMessages.hasOwnProperty(string)) {\n string = httpMessages[string];\n }\n\n this.body.innerHTML = string;\n this.callback = callback;\n show(this.container);\n if (this.alertProps.shouldFocus) {\n this.container.focus(\n { preventScroll: this.alertProps.preventScroll }\n );\n }\n }\n}\n\nclass AlertSingleton {\n constructor(root) {\n\n if (root) {\n this.alertDialog = undefined;\n }\n }\n\n init(root) {\n this.alertDialog = new AlertDialog(root);\n }\n\n present(alert, callback) {\n this.alertDialog.present(alert, callback);\n }\n\n}\n\nvar alertSingleton = new AlertSingleton();\n\n// The global Alert dialog\n\nlet alertDialog;\n\nconst Alert = {\n\n init(root, config={}) {\n\t alertDialog = new AlertDialog(root, config);\n },\n\n presentAlert (alert, callback) {\n if(!alertDialog) {\n this.init(document.body);\n }\n alertDialog.present(alert, callback);\n },\n};\n\nclass InputDialog {\n\n constructor(parent) {\n\n this.parent = parent;\n\n // dialog container\n this.container = div({class: 'igv-ui-generic-dialog-container'});\n parent.appendChild(this.container);\n\n // const { x, y, width, height } = this.container.getBoundingClientRect();\n // console.log(`InputDialog - x ${ x } y ${ y } width ${ width } height ${ height }`)\n\n // dialog header\n const header = div({class: 'igv-ui-generic-dialog-header'});\n this.container.appendChild(header);\n\n // dialog label\n this.label = div({class: 'igv-ui-generic-dialog-one-liner'});\n this.container.appendChild(this.label);\n this.label.text = 'Unlabeled';\n\n // input container\n this.input_container = div({class: 'igv-ui-generic-dialog-input'});\n this.container.appendChild(this.input_container);\n //\n this.input = document.createElement(\"input\");\n this.input_container.appendChild(this.input);\n\n\n // ok | cancel\n const buttons = div({class: 'igv-ui-generic-dialog-ok-cancel'});\n this.container.appendChild(buttons);\n\n // ok\n this.ok = div();\n buttons.appendChild(this.ok);\n this.ok.textContent = 'OK';\n\n // cancel\n this.cancel = div();\n buttons.appendChild(this.cancel);\n this.cancel.textContent = 'Cancel';\n\n hide(this.container);\n\n this.input.addEventListener('keyup', e => {\n if (13 === e.keyCode) {\n if (typeof this.callback === 'function') {\n this.callback(this.input.value);\n this.callback = undefined;\n }\n this.input.value = undefined;\n hide(this.container);\n }\n });\n\n this.ok.addEventListener('click', () => {\n if (typeof this.callback === 'function') {\n this.callback(this.input.value);\n this.callback = undefined;\n }\n this.input.value = undefined;\n hide(this.container);\n });\n\n const cancel = () => {\n this.input.value = '';\n hide(this.container);\n };\n\n this.cancel.addEventListener('click', cancel);\n\n attachDialogCloseHandlerWithParent(header, cancel);\n makeDraggable(this.container, header);\n\n }\n\n present(options, e) {\n\n this.label.textContent = options.label;\n this.input.value = options.value;\n this.callback = options.callback || options.click;\n\n show(this.container);\n this.clampLocation(e.clientX, e.clientY);\n\n }\n\n clampLocation(clientX, clientY) {\n\n const { width:w, height:h } = this.container.getBoundingClientRect();\n const wh = window.innerHeight;\n const ww = window.innerWidth;\n\n const y = Math.min(wh - h, clientY);\n const x = Math.min(ww - w, clientX);\n this.container.style.left = `${ x }px`;\n this.container.style.top = `${ y }px`;\n\n }\n}\n\nconst appleCrayonPalette =\n {\n licorice: \"#000000\",\n lead: \"#1e1e1e\",\n tungsten: \"#3a3a3a\",\n iron: \"#545453\",\n steel: \"#6e6e6e\",\n tin: \"#878687\",\n nickel: \"#888787\",\n aluminum: \"#a09fa0\",\n magnesium: \"#b8b8b8\",\n silver: \"#d0d0d0\",\n mercury: \"#e8e8e8\",\n snow: \"#ffffff\",\n //\n cayenne: \"#891100\",\n mocha: \"#894800\",\n aspargus: \"#888501\",\n fern: \"#458401\",\n clover: \"#028401\",\n moss: \"#018448\",\n teal: \"#008688\",\n ocean: \"#004a88\",\n midnight: \"#001888\",\n eggplant: \"#491a88\",\n plum: \"#891e88\",\n maroon: \"#891648\",\n //\n maraschino: \"#ff2101\",\n tangerine: \"#ff8802\",\n lemon: \"#fffa03\",\n lime: \"#83f902\",\n spring: \"#05f802\",\n seam_foam: \"#03f987\",\n turquoise: \"#00fdff\",\n aqua: \"#008cff\",\n blueberry: \"#002eff\",\n grape: \"#8931ff\",\n magenta: \"#ff39ff\",\n strawberry: \"#ff2987\",\n //\n salmon: \"#ff726e\",\n cantaloupe: \"#ffce6e\",\n banana: \"#fffb6d\",\n honeydew: \"#cefa6e\",\n flora: \"#68f96e\",\n spindrift: \"#68fbd0\",\n ice: \"#68fdff\",\n sky: \"#6acfff\",\n orchid: \"#6e76ff\",\n lavender: \"#d278ff\",\n bubblegum: \"#ff7aff\",\n carnation: \"#ff7fd3\"\n };\n\nconst nucleotideColorComponents = {\n \"A\": [0, 200, 0],\n \"C\": [0, 0, 200],\n \"T\": [255, 0, 0],\n \"G\": [209, 113, 5],\n \"a\": [0, 200, 0],\n \"c\": [0, 0, 200],\n \"t\": [255, 0, 0],\n \"g\": [209, 113, 5],\n \"N\": [80, 80, 80]\n};\n\nconst nucleotideColors = {\n \"A\": \"rgb( 0, 200, 0)\",\n \"C\": \"rgb( 0, 0, 200)\",\n \"T\": \"rgb(255, 0, 0)\",\n \"G\": \"rgb(209, 113, 5)\",\n \"a\": \"rgb( 0, 200, 0)\",\n \"c\": \"rgb( 0, 0, 200)\",\n \"t\": \"rgb(255, 0, 0)\",\n \"g\": \"rgb(209, 113, 5)\",\n \"N\": \"rgb(80, 80, 80)\"\n};\n\nconst colorPalettes = {\n\n Set1:\n [\n \"rgb(228,26,28)\",\n \"rgb(55,126,184)\",\n \"rgb(77,175,74)\",\n \"rgb(166,86,40)\",\n \"rgb(152,78,163)\",\n \"rgb(255,127,0)\",\n \"rgb(247,129,191)\",\n \"rgb(153,153,153)\",\n \"rgb(255,255,51)\"\n ],\n\n Dark2:\n [\n \"rgb(27,158,119)\",\n \"rgb(217,95,2)\",\n \"rgb(117,112,179)\",\n \"rgb(231,41,138)\",\n \"rgb(102,166,30)\",\n \"rgb(230,171,2)\",\n \"rgb(166,118,29)\",\n \"rgb(102,102,102)\"\n ],\n\n Set2:\n [\n \"rgb(102, 194,165)\",\n \"rgb(252,141,98)\",\n \"rgb(141,160,203)\",\n \"rgb(231,138,195)\",\n \"rgb(166,216,84)\",\n \"rgb(255,217,47)\",\n \"rgb(229,196,148)\",\n \"rgb(179,179,179)\"\n ],\n\n Set3:\n [\n \"rgb(141,211,199)\",\n \"rgb(255,255,179)\",\n \"rgb(190,186,218)\",\n \"rgb(251,128,114)\",\n \"rgb(128,177,211)\",\n \"rgb(253,180,98)\",\n \"rgb(179,222,105)\",\n \"rgb(252,205,229)\",\n \"rgb(217,217,217)\",\n \"rgb(188,128,189)\",\n \"rgb(204,235,197)\",\n \"rgb(255,237,111)\"\n ],\n\n Pastel1:\n [\n \"rgb(251,180,174)\",\n \"rgb(179,205,227)\",\n \"rgb(204,235,197)\",\n \"rgb(222,203,228)\",\n \"rgb(254,217,166)\",\n \"rgb(255,255,204)\",\n \"rgb(229,216,189)\",\n \"rgb(253,218,236)\"\n ],\n\n Pastel2:\n [\n \"rgb(173,226,207)\",\n \"rgb(253,205,172)\",\n \"rgb(203,213,232)\",\n \"rgb(244,202,228)\",\n \"rgb(230,245,201)\",\n \"rgb(255,242,174)\",\n \"rgb(243,225,206)\"\n ],\n\n Accent:\n [\n \"rgb(127,201,127)\",\n \"rgb(190,174,212)\",\n \"rgb(253,192,134)\",\n \"rgb(255,255,153)\",\n \"rgb(56,108,176)\",\n \"rgb(240,2,127)\",\n \"rgb(191,91,23)\"\n ]\n};\n\nfunction PaletteColorTable (palette) {\n\n this.colors = colorPalettes[palette];\n\n if (!Array.isArray(this.colors)) this.colors = [];\n this.colorTable = {};\n this.nextIdx = 0;\n this.colorGenerator = new RandomColorGenerator();\n\n}\n\nPaletteColorTable.prototype.getColor = function (key) {\n\n if (!this.colorTable.hasOwnProperty(key)) {\n if (this.nextIdx < this.colors.length) {\n this.colorTable[key] = this.colors[this.nextIdx];\n } else {\n this.colorTable[key] = this.colorGenerator.get();\n }\n this.nextIdx++;\n }\n return this.colorTable[key];\n};\n\n// Random color generator from https://github.com/sterlingwes/RandomColor/blob/master/rcolor.js\n// Free to use & distribute under the MIT license\n// Wes Johnson (@SterlingWes)\n//\n// inspired by http://martin.ankerl.com/2009/12/09/how-to-create-random-colors-programmatically/\nfunction RandomColorGenerator() {\n this.hue = Math.random();\n this.goldenRatio = 0.618033988749895;\n this.hexwidth = 2;\n}\n\nRandomColorGenerator.prototype.hsvToRgb = function (h, s, v) {\n var h_i = Math.floor(h * 6),\n f = h * 6 - h_i,\n p = v * (1 - s),\n q = v * (1 - f * s),\n t = v * (1 - (1 - f) * s),\n r = 255,\n g = 255,\n b = 255;\n switch (h_i) {\n case 0:\n r = v, g = t, b = p;\n break;\n case 1:\n r = q, g = v, b = p;\n break;\n case 2:\n r = p, g = v, b = t;\n break;\n case 3:\n r = p, g = q, b = v;\n break;\n case 4:\n r = t, g = p, b = v;\n break;\n case 5:\n r = v, g = p, b = q;\n break;\n }\n return [Math.floor(r * 256), Math.floor(g * 256), Math.floor(b * 256)];\n};\n\nRandomColorGenerator.prototype.padHex = function (str) {\n if (str.length > this.hexwidth) return str;\n return new Array(this.hexwidth - str.length + 1).join('0') + str;\n};\n\nRandomColorGenerator.prototype.get = function (saturation, value) {\n this.hue += this.goldenRatio;\n this.hue %= 1;\n if (typeof saturation !== \"number\") saturation = 0.5;\n if (typeof value !== \"number\") value = 0.95;\n var rgb = this.hsvToRgb(this.hue, saturation, value);\n\n return \"#\" + this.padHex(rgb[0].toString(16))\n + this.padHex(rgb[1].toString(16))\n + this.padHex(rgb[2].toString(16));\n\n};\n\nclass GenericContainer {\n\n constructor({parent, top, left, width, height, border, closeHandler}) {\n\n let container = div({class: 'igv-ui-generic-container'});\n parent.appendChild(container);\n hide(container);\n this.container = container;\n\n if(top !== undefined) {\n this.container.style.top = `${ top }px`;\n }\n if(left !== undefined) {\n this.container.style.left = `${ left }px`;\n }\n if (width !== undefined) {\n this.container.style.width = `${ width }px`;\n }\n if (height !== undefined) {\n this.container.style.height = `${ height }px`;\n }\n if(border) {\n this.container.style.border = border;\n }\n //\n // let bbox = parent.getBoundingClientRect();\n // this.origin = {x: bbox.x, y: bbox.y};\n // this.container.offset({left: this.origin.x, top: this.origin.y});\n\n // header\n const header = div();\n this.container.appendChild(header);\n\n // close button\n attachDialogCloseHandlerWithParent(header, (e) => {\n hide(this.container);\n if(typeof closeHandler === \"function\") {\n closeHandler(e);\n }\n });\n\n makeDraggable(this.container, header);\n }\n\n show() {\n show(this.container);\n }\n\n hide() {\n hide(this.container);\n }\n\n dispose() {\n if(this.container.parent) {\n this.container.parent.removeChild(this.container);\n }\n }\n}\n\nclass ColorPicker extends GenericContainer {\n\n constructor({parent, top, left, width, height, defaultColors, colorHandler}) {\n\n super({ parent, top, left, width, height, border: '1px solid gray'});\n\n createColorSwatchSelector(this.container, colorHandler, defaultColors);\n }\n\n}\n\nconst createColorSwatchSelector = (container, colorHandler, defaultColors) => {\n\n const hexColorStrings = Object.values(appleCrayonPalette);\n\n for (let hexColorString of hexColorStrings) {\n const swatch = div({ class: 'igv-ui-color-swatch' });\n container.appendChild(swatch);\n decorateSwatch(swatch, hexColorString, colorHandler);\n }\n\n if (defaultColors) {\n for (let hexColorString of defaultColors) {\n const swatch = div({ class: 'igv-ui-color-swatch' });\n container.appendChild(swatch);\n decorateSwatch(swatch, hexColorString, colorHandler);\n }\n }\n\n};\n\nconst decorateSwatch = (swatch, hexColorString, colorHandler) => {\n\n swatch.style.backgroundColor = hexColorString;\n\n swatch.addEventListener('mouseenter', e => swatch.style.borderColor = hexColorString);\n\n swatch.addEventListener('mouseleave', e => swatch.style.borderColor = 'white');\n\n swatch.addEventListener('click', event => {\n event.stopPropagation();\n colorHandler(hexColorString);\n });\n\n swatch.addEventListener('touchend', event => {\n event.stopPropagation();\n colorHandler(hexColorString);\n });\n\n};\n\nclass Popover {\n\n constructor(parent, title) {\n\n this.parent = parent;\n\n // popover\n this.popover = div({ class: \"igv-ui-popover\" });\n parent.appendChild(this.popover);\n\n // header\n const popoverHeader = div();\n this.popover.appendChild(popoverHeader);\n\n const titleElement = div();\n popoverHeader.appendChild(titleElement);\n if (title) {\n titleElement.textContent = title;\n }\n\n attachDialogCloseHandlerWithParent(popoverHeader, () => this.hide());\n makeDraggable(this.popover, popoverHeader);\n\n // content\n this.popoverContent = div();\n this.popover.appendChild(this.popoverContent);\n\n this.popover.style.display = 'none';\n\n\n }\n\n presentContentWithEvent(e, content) {\n\n this.popover.style.display = 'block';\n\n this.popoverContent.innerHTML = content;\n\n present(e, this.popover, this.popoverContent);\n\n }\n\n presentMenu(e, menuItems) {\n\n if (0 === menuItems.length) {\n return\n }\n\n this.popover.style.display = 'block';\n\n const menuElements = createMenuElements(menuItems, this.popover);\n for (let item of menuElements) {\n this.popoverContent.appendChild(item.object);\n }\n\n present(e, this.popover, this.popoverContent);\n }\n\n hide() {\n this.popover.style.display = 'none';\n this.dispose();\n }\n\n dispose() {\n\n if (this.popover) {\n this.popover.parentNode.removeChild(this.popover);\n }\n\n const keys = Object.keys(this);\n for (let key of keys) {\n this[ key ] = undefined;\n }\n }\n\n}\n\nfunction present(e, popover, popoverContent) {\n\n const { x, y, width } = translateMouseCoordinates(e, popover.parentNode);\n popover.style.top = `${ y }px`;\n\n const { width: w } = popover.getBoundingClientRect();\n\n const xmax = x + w;\n const delta = xmax - width;\n\n popover.style.left = `${ xmax > width ? (x - delta) : x }px`;\n popoverContent.style.maxWidth = `${ Math.min(w, width) }px`;\n\n\n}\n\nfunction createMenuElements(itemList, popover) {\n\n const list = itemList.map(function (item, i) {\n let elem;\n\n if (typeof item === 'string') {\n elem = div();\n elem.innerHTML = item;\n } else if (typeof item === 'Node') {\n elem = item;\n } else {\n if (typeof item.init === 'function') {\n item.init();\n }\n\n if (\"checkbox\" === item.type) {\n elem = createCheckbox(\"Show all bases\", item.value);\n } else if(\"color\" === item.type) {\n const colorPicker = new ColorPicker({\n parent: popover.parentElement,\n width: 364,\n //defaultColor: 'aqua',\n colorHandler: (color) => item.click(color)\n });\n elem = div();\n if (typeof item.label === 'string') {\n elem.innerHTML = item.label;\n }\n const clickHandler = e => {\n colorPicker.show();\n hide(popover);\n e.preventDefault();\n e.stopPropagation();\n };\n elem.addEventListener('click', clickHandler);\n elem.addEventListener('touchend', clickHandler);\n elem.addEventListener('mouseup', function (e) {\n e.preventDefault();\n e.stopPropagation();\n });\n }\n\n else {\n elem = div();\n if (typeof item.label === 'string') {\n elem.innerHTML = item.label;\n }\n }\n\n if (item.click && \"color\" !== item.type) {\n elem.addEventListener('click', handleClick);\n elem.addEventListener('touchend', handleClick);\n elem.addEventListener('mouseup', function (e) {\n e.preventDefault();\n e.stopPropagation();\n });\n\n // eslint-disable-next-line no-inner-declarations\n function handleClick(e) {\n item.click();\n hide(popover);\n e.preventDefault();\n e.stopPropagation();\n }\n }\n }\n\n\n return { object: elem, init: item.init };\n });\n\n return list;\n}\n\nconst style = {\n display: 'flex',\n flexDirection: 'row',\n alignItems: 'center',\n backgroundColor: 'transparent',\n};\n\nclass Checkbox {\n\n constructor({selected, label, onchange}) {\n\n this.state = selected;\n this.onchange = onchange;\n this.elem = div({style: style});\n\n const svgDiv = div({\n style: {\n width: '14px',\n height: '14px',\n borderColor: 'gray',\n borderWidth: '1px',\n borderStyle: 'solid'\n }\n });\n this.svg = createIcon('check', (true === selected ? '#444' : 'transparent'));\n this.svg.style.width = '12px';\n this.svg.style.height = '12px';\n svgDiv.appendChild(this.svg);\n this.elem.appendChild(svgDiv);\n\n if (label) {\n const d = div({style: {marginLeft: '5px'}}); //{ class: 'igv-some-label-class' });\n d.textContent = label;\n this.elem.appendChild(d);\n }\n\n const handleClick = (e) => {\n e.preventDefault();\n e.stopPropagation();\n const newState = !this.state;\n this.selected = newState;\n if (typeof this.onchange === 'function') {\n this.onchange(newState);\n }\n };\n this.elem.addEventListener('click', handleClick);\n this.elem.addEventListener('touchend', handleClick);\n }\n\n set selected(selected) {\n this.state = selected;\n const p = this.svg.querySelector('path');\n p.setAttributeNS(null, 'fill', (true === selected ? '#444' : 'transparent'));\n }\n\n get selected() {\n return this.state;\n }\n\n onchange(handler) {\n this.onchange = handler;\n }\n\n\n}\n\nclass GenericColorPicker extends GenericContainer {\n\n constructor({parent, width}) {\n super({parent, width, border: '1px solid gray'});\n }\n\n configure(defaultColors, colorHandlers) {\n\n this.colorHandlers = colorHandlers;\n\n // active color handler defaults to handler with 'color' as key\n this.setActiveColorHandler('color');\n\n this.createSwatches(defaultColors);\n\n }\n\n setActiveColorHandler(option) {\n this.activeColorHandler = this.colorHandlers[option];\n }\n\n createSwatches(defaultColors) {\n\n this.container.querySelectorAll('.igv-ui-color-swatch').forEach(swatch => swatch.remove());\n\n const hexColorStrings = Object.values(appleCrayonPalette);\n\n for (let hexColorString of hexColorStrings) {\n const swatch = div({class: 'igv-ui-color-swatch'});\n this.container.appendChild(swatch);\n this.decorateSwatch(swatch, hexColorString);\n }\n\n if (defaultColors) {\n for (let hexColorString of defaultColors) {\n const swatch = div({class: 'igv-ui-color-swatch'});\n this.container.appendChild(swatch);\n this.decorateSwatch(swatch, hexColorString);\n }\n }\n\n }\n\n decorateSwatch(swatch, hexColorString) {\n\n swatch.style.backgroundColor = hexColorString;\n\n swatch.addEventListener('mouseenter', () => swatch.style.borderColor = hexColorString);\n\n swatch.addEventListener('mouseleave', () => swatch.style.borderColor = 'white');\n\n swatch.addEventListener('click', event => {\n event.stopPropagation();\n this.activeColorHandler(hexColorString);\n });\n\n swatch.addEventListener('touchend', event => {\n event.stopPropagation();\n this.activeColorHandler(hexColorString);\n });\n\n }\n\n}\n\n/**\n * Create a table with an optional row click handler *\n *\n * @param tableConfig {\n * headers: column headers (strings)\n * rows: row data (array of arrays, 1 for ecah row)\n * rowClickHandler: Optional click handler for a row. Supplied function will receive a row's data as an array\n * }\n * @returns {HTMLTableElement}\n */\nfunction createTable(tableConfig) {\n\n const table = document.createElement(\"table\");\n table.classList.add(\"igv-ui-table\");\n table.id = \"variant_table\";\n\n const thead = document.createElement('thead');\n table.appendChild(thead);\n const headerRow = thead.insertRow(0);\n\n const headers = tableConfig.headers;\n for (let j = 0; j < headers.length; j++) {\n var cell = document.createElement(\"th\");\n headerRow.appendChild(cell);\n cell.innerHTML = headers[j];\n }\n\n const tbody = document.createElement('tbody');\n table.appendChild(tbody);\n const tableRows = tableConfig.rows;\n for (let rowData of tableRows) {\n\n const row = document.createElement(\"tr\");\n tbody.appendChild(row);\n\n for (let j = 0; j < headers.length; j++) {\n var value = rowData[j];\n cell = document.createElement(\"td\");\n row.appendChild(cell);\n cell.innerHTML = value;\n }\n\n if (tableConfig.rowClickHandler) {\n row.onclick = (event) => {\n tableConfig.rowClickHandler(rowData);\n };\n }\n }\n\n return table\n\n}\n\n/**\n * Wraps a simple table (see components/table.js) in a popup component with drag bar and close control. The table\n * is initially hidden (display == none)\n *\n */\n\nclass IGVTable {\n\n /**\n *\n * @param parent - parent element for the popup's html element\n * @param tableConfig - see components/table.js\n */\n constructor(parent, tableConfig) {\n\n this.parent = parent;\n\n // popover\n this.popover = div({class: \"igv-ui-popover\"});\n parent.appendChild(this.popover);\n\n // header\n const popoverHeader = div();\n this.popover.appendChild(popoverHeader);\n\n const titleElement = div();\n popoverHeader.appendChild(titleElement);\n if (tableConfig.title) {\n titleElement.innerHTML = tableConfig.title;\n }\n\n attachDialogCloseHandlerWithParent(popoverHeader, () => this.hide());\n makeDraggable(this.popover, popoverHeader);\n\n const tableContainer = document.createElement(\"div\");\n tableContainer.style.maxHeight = tableConfig.maxHeight ? tableConfig.maxHeight + \"px\" : \"800px\";\n tableContainer.style.overflow = \"auto\";\n this.popover.appendChild(tableContainer);\n\n // TODO -- this will be passed as an argument\n\n const table = createTable(tableConfig);\n tableContainer.appendChild(table);\n\n this.popover.style.display = 'none';\n\n }\n\n show() {\n this.popover.style.display = 'block';\n }\n\n hide() {\n this.popover.style.display = 'none';\n }\n\n dispose() {\n\n if (this.popover) {\n this.popover.parentNode.removeChild(this.popover);\n }\n }\n\n}\n\nfunction embedCSS() {\n const style = document.createElement('style');\n style.setAttribute('type', 'text/css');\n style.setAttribute('title', 'igv-ui.css');\n style.innerHTML = `.igv-ui-popover {\n cursor: default;\n position: absolute;\n z-index: 2048;\n border-color: #7F7F7F;\n border-radius: 4px;\n border-style: solid;\n border-width: 1px;\n font-family: \"Open Sans\", sans-serif;\n font-size: small;\n background-color: white;\n}\n.igv-ui-popover > div:first-child {\n display: flex;\n flex-direction: row;\n flex-wrap: nowrap;\n justify-content: space-between;\n align-items: center;\n width: 100%;\n height: 24px;\n cursor: move;\n border-top-left-radius: 4px;\n border-top-right-radius: 4px;\n border-bottom-color: #7F7F7F;\n border-bottom-style: solid;\n border-bottom-width: thin;\n background-color: #eee;\n}\n.igv-ui-popover > div:first-child > div:first-child {\n margin-left: 4px;\n}\n.igv-ui-popover > div:first-child > div:last-child {\n margin-right: 4px;\n height: 12px;\n width: 12px;\n color: #7F7F7F;\n}\n.igv-ui-popover > div:first-child > div:last-child:hover {\n cursor: pointer;\n color: #444;\n}\n.igv-ui-popover > div:last-child {\n overflow-y: auto;\n overflow-x: hidden;\n max-height: 400px;\n max-width: 800px;\n background-color: white;\n}\n.igv-ui-popover > div:last-child > div {\n -webkit-user-select: text;\n -moz-user-select: text;\n -ms-user-select: text;\n user-select: text;\n margin-left: 4px;\n margin-right: 4px;\n min-width: 220px;\n overflow-x: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.igv-ui-popover > div:last-child > div > span {\n font-weight: bolder;\n}\n.igv-ui-popover > div:last-child hr {\n width: 100%;\n}\n\n.igv-ui-alert-dialog-container {\n box-sizing: content-box;\n position: absolute;\n z-index: 2048;\n top: 50%;\n left: 50%;\n width: 400px;\n height: 200px;\n border-color: #7F7F7F;\n border-radius: 4px;\n border-style: solid;\n border-width: thin;\n outline: none;\n font-family: \"Open Sans\", sans-serif;\n font-size: 15px;\n font-weight: 400;\n background-color: white;\n display: flex;\n flex-flow: column;\n flex-wrap: nowrap;\n justify-content: space-between;\n align-items: center;\n}\n.igv-ui-alert-dialog-container > div:first-child {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n width: 100%;\n height: 24px;\n cursor: move;\n border-top-left-radius: 4px;\n border-top-right-radius: 4px;\n border-bottom-color: #7F7F7F;\n border-bottom-style: solid;\n border-bottom-width: thin;\n background-color: #eee;\n}\n.igv-ui-alert-dialog-container > div:first-child div:first-child {\n padding-left: 8px;\n}\n.igv-ui-alert-dialog-container .igv-ui-alert-dialog-body {\n -webkit-user-select: text;\n -moz-user-select: text;\n -ms-user-select: text;\n user-select: text;\n color: #373737;\n width: 100%;\n height: calc(100% - 24px - 64px);\n overflow-y: scroll;\n}\n.igv-ui-alert-dialog-container .igv-ui-alert-dialog-body .igv-ui-alert-dialog-body-copy {\n margin: 16px;\n width: auto;\n height: auto;\n overflow-wrap: break-word;\n word-break: break-word;\n background-color: white;\n border: unset;\n}\n.igv-ui-alert-dialog-container > div:last-child {\n width: 100%;\n margin-bottom: 10px;\n background-color: white;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: center;\n align-items: center;\n}\n.igv-ui-alert-dialog-container > div:last-child div {\n margin: unset;\n width: 40px;\n height: 30px;\n line-height: 30px;\n text-align: center;\n color: white;\n font-family: \"Open Sans\", sans-serif;\n font-size: small;\n font-weight: 400;\n border-color: #2B81AF;\n border-style: solid;\n border-width: thin;\n border-radius: 4px;\n background-color: #2B81AF;\n}\n.igv-ui-alert-dialog-container > div:last-child div:hover {\n cursor: pointer;\n border-color: #25597f;\n background-color: #25597f;\n}\n\n.igv-ui-color-swatch {\n position: relative;\n box-sizing: content-box;\n display: flex;\n flex-flow: row;\n flex-wrap: wrap;\n justify-content: center;\n align-items: center;\n width: 32px;\n height: 32px;\n border-style: solid;\n border-width: 2px;\n border-color: white;\n border-radius: 4px;\n}\n\n.igv-ui-color-swatch:hover {\n border-color: dimgray;\n}\n\n.igv-ui-colorpicker-menu-close-button {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-end;\n align-items: center;\n width: 100%;\n height: 32px;\n margin-top: 4px;\n margin-bottom: 4px;\n padding-right: 8px;\n}\n.igv-ui-colorpicker-menu-close-button i.fa {\n display: block;\n margin-left: 4px;\n margin-right: 4px;\n color: #5f5f5f;\n}\n.igv-ui-colorpicker-menu-close-button i.fa:hover,\n.igv-ui-colorpicker-menu-close-button i.fa:focus,\n.igv-ui-colorpicker-menu-close-button i.fa:active {\n cursor: pointer;\n color: #0f0f0f;\n}\n\n.igv-ui-generic-dialog-container {\n box-sizing: content-box;\n position: fixed;\n top: 0;\n left: 0;\n width: 300px;\n height: 200px;\n border-color: #7F7F7F;\n border-radius: 4px;\n border-style: solid;\n border-width: thin;\n font-family: \"Open Sans\", sans-serif;\n font-size: medium;\n font-weight: 400;\n z-index: 2048;\n background-color: white;\n display: flex;\n flex-flow: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n}\n.igv-ui-generic-dialog-container .igv-ui-generic-dialog-header {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-end;\n align-items: center;\n width: 100%;\n height: 24px;\n cursor: move;\n border-top-left-radius: 4px;\n border-top-right-radius: 4px;\n border-bottom-color: #7F7F7F;\n border-bottom-style: solid;\n border-bottom-width: thin;\n background-color: #eee;\n}\n.igv-ui-generic-dialog-container .igv-ui-generic-dialog-header div {\n margin-right: 4px;\n margin-bottom: 2px;\n height: 12px;\n width: 12px;\n color: #7F7F7F;\n}\n.igv-ui-generic-dialog-container .igv-ui-generic-dialog-header div:hover {\n cursor: pointer;\n color: #444;\n}\n.igv-ui-generic-dialog-container .igv-ui-generic-dialog-one-liner {\n color: #373737;\n width: 95%;\n height: 24px;\n line-height: 24px;\n text-align: left;\n margin-top: 8px;\n padding-left: 8px;\n overflow-wrap: break-word;\n background-color: white;\n}\n.igv-ui-generic-dialog-container .igv-ui-generic-dialog-label-input {\n margin-top: 8px;\n width: 95%;\n height: 24px;\n color: #373737;\n line-height: 24px;\n padding-left: 8px;\n background-color: white;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n}\n.igv-ui-generic-dialog-container .igv-ui-generic-dialog-label-input div {\n width: 30%;\n height: 100%;\n font-size: 16px;\n text-align: right;\n padding-right: 8px;\n background-color: white;\n}\n.igv-ui-generic-dialog-container .igv-ui-generic-dialog-label-input input {\n display: block;\n height: 100%;\n width: 100%;\n padding-left: 4px;\n font-family: \"Open Sans\", sans-serif;\n font-weight: 400;\n color: #373737;\n text-align: left;\n outline: none;\n border-style: solid;\n border-width: thin;\n border-color: #7F7F7F;\n background-color: white;\n}\n.igv-ui-generic-dialog-container .igv-ui-generic-dialog-label-input input {\n width: 50%;\n font-size: 16px;\n}\n.igv-ui-generic-dialog-container .igv-ui-generic-dialog-input {\n margin-top: 8px;\n width: calc(100% - 16px);\n height: 24px;\n color: #373737;\n line-height: 24px;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-around;\n align-items: center;\n}\n.igv-ui-generic-dialog-container .igv-ui-generic-dialog-input input {\n display: block;\n height: 100%;\n width: 100%;\n padding-left: 4px;\n font-family: \"Open Sans\", sans-serif;\n font-weight: 400;\n color: #373737;\n text-align: left;\n outline: none;\n border-style: solid;\n border-width: thin;\n border-color: #7F7F7F;\n background-color: white;\n}\n.igv-ui-generic-dialog-container .igv-ui-generic-dialog-input input {\n font-size: 16px;\n}\n.igv-ui-generic-dialog-container .igv-ui-generic-dialog-ok-cancel {\n width: 100%;\n height: 28px;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-around;\n align-items: center;\n}\n.igv-ui-generic-dialog-container .igv-ui-generic-dialog-ok-cancel div {\n margin-top: 32px;\n color: white;\n font-family: \"Open Sans\", sans-serif;\n font-size: 14px;\n font-weight: 400;\n width: 75px;\n height: 28px;\n line-height: 28px;\n text-align: center;\n border-color: transparent;\n border-style: solid;\n border-width: thin;\n border-radius: 2px;\n}\n.igv-ui-generic-dialog-container .igv-ui-generic-dialog-ok-cancel div:first-child {\n margin-left: 32px;\n margin-right: 0;\n background-color: #5ea4e0;\n}\n.igv-ui-generic-dialog-container .igv-ui-generic-dialog-ok-cancel div:last-child {\n margin-left: 0;\n margin-right: 32px;\n background-color: #c4c4c4;\n}\n.igv-ui-generic-dialog-container .igv-ui-generic-dialog-ok-cancel div:first-child:hover {\n cursor: pointer;\n background-color: #3b5c7f;\n}\n.igv-ui-generic-dialog-container .igv-ui-generic-dialog-ok-cancel div:last-child:hover {\n cursor: pointer;\n background-color: #7f7f7f;\n}\n.igv-ui-generic-dialog-container .igv-ui-generic-dialog-ok {\n width: 100%;\n height: 36px;\n margin-top: 32px;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-around;\n align-items: center;\n}\n.igv-ui-generic-dialog-container .igv-ui-generic-dialog-ok div {\n width: 98px;\n height: 36px;\n line-height: 36px;\n text-align: center;\n color: white;\n font-family: \"Open Sans\", sans-serif;\n font-size: medium;\n font-weight: 400;\n border-color: white;\n border-style: solid;\n border-width: thin;\n border-radius: 4px;\n background-color: #2B81AF;\n}\n.igv-ui-generic-dialog-container .igv-ui-generic-dialog-ok div:hover {\n cursor: pointer;\n background-color: #25597f;\n}\n\n.igv-ui-generic-container {\n box-sizing: content-box;\n position: absolute;\n z-index: 2048;\n background-color: white;\n cursor: pointer;\n display: flex;\n flex-direction: row;\n flex-wrap: wrap;\n justify-content: flex-start;\n align-items: center;\n}\n.igv-ui-generic-container > div:first-child {\n cursor: move;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-end;\n align-items: center;\n height: 24px;\n width: 100%;\n background-color: #dddddd;\n}\n.igv-ui-generic-container > div:first-child > div {\n display: block;\n color: #5f5f5f;\n cursor: pointer;\n width: 14px;\n height: 14px;\n margin-right: 8px;\n margin-bottom: 4px;\n}\n\n.igv-ui-dialog {\n z-index: 2048;\n position: fixed;\n width: fit-content;\n height: fit-content;\n display: flex;\n flex-flow: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n background-color: white;\n border-color: #7F7F7F;\n border-radius: 4px;\n border-style: solid;\n border-width: thin;\n font-family: \"Open Sans\", sans-serif;\n font-size: medium;\n font-weight: 400;\n}\n.igv-ui-dialog .igv-ui-dialog-header {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-end;\n align-items: center;\n width: 100%;\n height: 24px;\n cursor: move;\n border-top-left-radius: 4px;\n border-top-right-radius: 4px;\n border-bottom-color: #7F7F7F;\n border-bottom-style: solid;\n border-bottom-width: thin;\n background-color: #eee;\n}\n.igv-ui-dialog .igv-ui-dialog-header div {\n margin-right: 4px;\n margin-bottom: 2px;\n height: 12px;\n width: 12px;\n color: #7F7F7F;\n}\n.igv-ui-dialog .igv-ui-dialog-header div:hover {\n cursor: pointer;\n color: #444;\n}\n.igv-ui-dialog .igv-ui-dialog-one-liner {\n width: 95%;\n height: 24px;\n line-height: 24px;\n text-align: left;\n margin: 8px;\n overflow-wrap: break-word;\n background-color: white;\n font-weight: bold;\n}\n.igv-ui-dialog .igv-ui-dialog-ok-cancel {\n width: 100%;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-around;\n align-items: center;\n}\n.igv-ui-dialog .igv-ui-dialog-ok-cancel div {\n margin: 16px;\n margin-top: 32px;\n color: white;\n font-family: \"Open Sans\", sans-serif;\n font-size: 14px;\n font-weight: 400;\n width: 75px;\n height: 28px;\n line-height: 28px;\n text-align: center;\n border-color: transparent;\n border-style: solid;\n border-width: thin;\n border-radius: 2px;\n}\n.igv-ui-dialog .igv-ui-dialog-ok-cancel div:first-child {\n background-color: #5ea4e0;\n}\n.igv-ui-dialog .igv-ui-dialog-ok-cancel div:last-child {\n background-color: #c4c4c4;\n}\n.igv-ui-dialog .igv-ui-dialog-ok-cancel div:first-child:hover {\n cursor: pointer;\n background-color: #3b5c7f;\n}\n.igv-ui-dialog .igv-ui-dialog-ok-cancel div:last-child:hover {\n cursor: pointer;\n background-color: #7f7f7f;\n}\n.igv-ui-dialog .igv-ui-dialog-ok {\n width: 100%;\n height: 36px;\n margin-top: 32px;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-around;\n align-items: center;\n}\n.igv-ui-dialog .igv-ui-dialog-ok div {\n width: 98px;\n height: 36px;\n line-height: 36px;\n text-align: center;\n color: white;\n font-family: \"Open Sans\", sans-serif;\n font-size: medium;\n font-weight: 400;\n border-color: white;\n border-style: solid;\n border-width: thin;\n border-radius: 4px;\n background-color: #2B81AF;\n}\n.igv-ui-dialog .igv-ui-dialog-ok div:hover {\n cursor: pointer;\n background-color: #25597f;\n}\n\n.igv-ui-panel, .igv-ui-panel-row, .igv-ui-panel-column {\n z-index: 2048;\n background-color: white;\n font-family: \"Open Sans\", sans-serif;\n font-size: medium;\n font-weight: 400;\n display: flex;\n justify-content: flex-start;\n align-items: flex-start;\n}\n\n.igv-ui-panel-column {\n display: flex;\n flex-direction: column;\n}\n\n.igv-ui-panel-row {\n display: flex;\n flex-direction: row;\n}\n\n.igv-ui-textbox {\n background-color: white;\n font-family: \"Open Sans\", sans-serif;\n font-size: medium;\n font-weight: 400;\n display: flex;\n justify-content: flex-start;\n align-items: flex-start;\n}\n\n.igv-ui-table {\n background-color: white;\n}\n\n.igv-ui-table thead {\n position: sticky;\n top: 0;\n}\n\n.igv-ui-table th {\n text-align: left;\n}\n\n.igv-ui-table td {\n padding-right: 20px;\n}\n\n.igv-ui-table tr:hover {\n background-color: lightblue;\n}\n\n/*# sourceMappingURL=igv-ui.css.map */\n`;\n document.head.append(style);\n}\n\nif (typeof document !== 'undefined') {\n\n if (!stylesheetExists(\"igv-ui.css\")) {\n embedCSS();\n }\n\n function stylesheetExists(stylesheetName) {\n for (let ss of document.styleSheets) {\n ss = ss.href ? ss.href.replace(/^.*[\\\\\\/]/, '') : '';\n if (ss === stylesheetName) {\n return true\n }\n }\n return false\n }\n}\n\nexport { Alert, AlertDialog, alertSingleton as AlertSingleton, Checkbox, ColorPicker, domUtils as DOMUtils, DataRangeDialog, Dialog, GenericColorPicker, GenericContainer, IGVTable, icons$1 as Icon, InputDialog, PaletteColorTable, Panel, Popover, Textbox, uiUtils as UIUtils, appleCrayonPalette, createColorSwatchSelector, makeDraggable, nucleotideColorComponents, nucleotideColors };\n","/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2016-2017 The Regents of the University of California\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and\n * associated documentation files (the \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the\n * following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all copies or substantial\n * portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING\n * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n *\n */\n\nimport {FileUtils} from '../node_modules/igv-utils/src/index.js'\n\nfunction isMobile() {\n return (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent));\n}\n\nfunction throttle(fn, threshhold, scope) {\n var last,\n deferTimer;\n\n threshhold || (threshhold = 200);\n\n return function () {\n var context,\n now,\n args;\n\n context = scope || this;\n now = +new Date;\n args = arguments;\n\n if (last && now < last + threshhold) {\n // hold on to it\n clearTimeout(deferTimer);\n deferTimer = setTimeout(function () {\n last = now;\n fn.apply(context, args);\n }, threshhold);\n } else {\n last = now;\n fn.apply(context, args);\n }\n }\n}\n\nfunction getExtension(url) {\n\n if (undefined === url) {\n return undefined\n }\n\n let path = (FileUtils.isFile(url) || url.google_url) ? url.name : url\n let filename = path.toLowerCase()\n\n //Strip parameters -- handle local files later\n let index = filename.indexOf(\"?\")\n if (index > 0) {\n filename = filename.substr(0, index)\n }\n\n //Strip aux extensions .gz, .tab, and .txt\n if (filename.endsWith(\".gz\")) {\n filename = filename.substr(0, filename.length - 3)\n } else if (filename.endsWith(\".txt\") || filename.endsWith(\".tab\") || filename.endsWith(\".bgz\")) {\n filename = filename.substr(0, filename.length - 4)\n }\n\n index = filename.lastIndexOf(\".\")\n\n return index < 0 ? filename : filename.substr(1 + index)\n}\n\n\nexport { isMobile, throttle, getExtension }\n","const Globals = {}\n\nexport {Globals}\n","/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2016-2017 The Regents of the University of California\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and\n * associated documentation files (the \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the\n * following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all copies or substantial\n * portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING\n * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n *\n */\n\n\n/**\n * @author Jim Robinson\n */\n\n\n/**\n * Barebones event bus.\n */\n\nclass EventBus {\n\n constructor() {\n\n // Map eventType -> list of subscribers\n this.subscribers = {};\n\n this.stack = []\n }\n\n subscribe(eventType, object) {\n\n var subscriberList = this.subscribers[eventType];\n if (subscriberList == undefined) {\n subscriberList = [];\n this.subscribers[eventType] = subscriberList;\n }\n subscriberList.push(object);\n\n }\n\n post(event) {\n\n const eventType = event.type\n\n if (this._hold) {\n this.stack.push(event)\n } else {\n const subscriberList = this.subscribers[eventType];\n\n if (subscriberList) {\n for (let subscriber of subscriberList) {\n\n if (\"function\" === typeof subscriber.receiveEvent) {\n subscriber.receiveEvent(event);\n } else if (\"function\" === typeof subscriber) {\n subscriber(event);\n }\n }\n }\n }\n }\n\n hold() {\n this._hold = true;\n }\n\n release() {\n this._hold = false;\n for (let event of this.stack) {\n this.post(event)\n }\n this.stack = []\n }\n}\n\n// The global event bus\n\nEventBus.globalBus = new EventBus()\n\nexport default EventBus\n","import {igvxhr, StringUtils} from '../node_modules/igv-utils/src/index.js'\n\nclass Track2D {\n\n static DisplayModes = {\n lower: 0b01,\n upper: 0b10,\n both: 0b01 | 0b10,\n }\n\n constructor(config, features) {\n\n this.config = config\n this.name = config.name\n\n if (config.color && validateColor(config.color)) {\n this.color = this.color = config.color // If specified, this will override colors of individual records.\n }\n\n this.displayMode = config.displayMode // Can be undefined => both\n\n this.isVisible = undefined === config.isVisible ? true : config.isVisible\n\n this.repColor = features.length > 0 ? features[0].color : \"black\"\n\n this.featureMap = {}\n this.featureCount = 0\n for (let f of features) {\n this.featureCount++\n const key = getKey(f.chr1, f.chr2)\n let list = this.featureMap[key]\n if (!list) {\n list = []\n this.featureMap[key] = list\n }\n list.push(f)\n }\n }\n\n static async loadTrack2D(config, genome) {\n\n const data = await igvxhr.loadString(config.url, buildOptions(config))\n const features = parseData(data, isBedPE(config), genome)\n return new Track2D(config, features)\n }\n\n getColor() {\n return this.color || this.repColor\n }\n\n getFeatures(chr1, chr2) {\n const key = getKey(chr1, chr2)\n return this.featureMap[key]\n }\n\n toJSON() {\n const json =\n {\n url: this.config.url\n }\n if (this.name) {\n json.name = this.name\n }\n if (this.color) {\n json.color = this.color\n }\n if (this.displayMode) {\n json.displayMode = this.displayMode\n }\n if (!this.isVisible) {\n json.isVisible = this.isVisible\n }\n\n return json\n\n }\n\n}\n\n\nfunction isBedPE(config) {\n\n if (typeof config.url === \"string\") {\n return config.url.toLowerCase().indexOf(\".bedpe\") > 0\n } else if (typeof config.name === \"string\") {\n return config.name.toLowerCase().indexOf(\".bedpe\") > 0\n } else {\n return true // Default\n }\n}\n\nfunction parseData(data, isBedPE, genome) {\n\n if (!data) return null\n\n const lines = StringUtils.splitLines(data)\n const allFeatures = []\n const delimiter = \"\\t\"\n const start = isBedPE ? 0 : 1\n const colorColumn = isBedPE ? 10 : 6\n\n let errorCount = 0\n for (let line of lines) {\n line = line.trim()\n if (line.startsWith(\"#\") || line.startsWith(\"track\") || line.startsWith(\"browser\") || line.length === 0) {\n continue\n }\n const tokens = line.split(delimiter)\n if (tokens.length < 6 && errorCount <= 5) {\n if (errorCount === 5) {\n console.error(\"...\")\n } else {\n console.error(\"Could not parse line: \" + line)\n }\n errorCount++\n continue\n }\n\n const feature = {\n chr1: genome ? genome.getChromosomeName(tokens[0]) : tokens[0],\n x1: parseInt(tokens[1]),\n x2: parseInt(tokens[2]),\n chr2: genome ? genome.getChromosomeName(tokens[3]) : tokens[3],\n y1: parseInt(tokens[4]),\n y2: parseInt(tokens[5])\n }\n\n if (tokens.length > colorColumn) {\n feature.color = \"rgb(\" + tokens[colorColumn] + \")\"\n }\n\n if (!Number.isNaN(feature.x1)) {\n allFeatures.push(feature)\n }\n }\n\n return allFeatures\n}\n\nfunction getKey(chr1, chr2) {\n return chr1 > chr2 ? chr2 + \"_\" + chr1 : chr1 + \"_\" + chr2\n}\n\nfunction validateColor(str) {\n var div = document.createElement(\"div\")\n div.style.borderColor = str\n return div.style.borderColor !== \"\"\n}\n\nfunction isString(x) {\n return typeof x === \"string\" || x instanceof String\n}\n\nfunction buildOptions(config, options) {\n const defaultOptions = {\n oauthToken: config.oauthToken,\n headers: config.headers,\n withCredentials: config.withCredentials,\n filename: config.filename\n }\n\n return Object.assign(defaultOptions, options)\n}\n\nexport default Track2D\n","/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2016-2017 The Regents of the University of California\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and\n * associated documentation files (the \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the\n * following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all copies or substantial\n * portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING\n * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n *\n */\n\n\n/**\n * @author Jim Robinson\n */\n\nimport {IGVColor, IGVMath} from '../node_modules/igv-utils/src/index.js'\nimport igv from '../node_modules/igv/dist/igv.esm.js'\n\nclass Ruler {\n\n constructor(browser, parentElement, axis) {\n this.browser = browser;\n this.axis = axis;\n\n this.axisElement = parentElement.querySelector(`div[id$='-axis']`);\n\n this.canvasElement = parentElement.querySelector(\"canvas\");\n\n this.ctx = this.canvasElement.getContext(\"2d\");\n this.ctx.canvas.width = this.axisElement.offsetWidth;\n this.ctx.canvas.height = this.axisElement.offsetHeight;\n\n this.wholeGenomeContainerElement = parentElement.querySelector(\"div[id$='-axis-whole-genome-container']\");\n\n this.setAxisTransform(axis);\n\n browser.eventBus.subscribe('MapLoad', this);\n browser.eventBus.subscribe(\"UpdateContactMapMousePosition\", this);\n }\n\n wholeGenomeLayout(axisElement, wholeGenomeContainerElement, axisName, dataset) {\n\n const decorate = (div) => {\n div.addEventListener('click', () => {\n this.browser.parseGotoInput(div.textContent);\n this.unhighlightWholeChromosome();\n this.otherRuler.unhighlightWholeChromosome();\n });\n\n div.addEventListener('mouseenter', () => {\n hoverHandler.call(this, div, true);\n });\n\n div.addEventListener('mouseleave', () => {\n hoverHandler.call(this, div, false);\n });\n };\n\n const hoverHandler = (element, doHover) => {\n const targetLabel = element.dataset.label;\n\n Array.from(this.otherRuler.wholeGenomeContainerElement.children).forEach(child => {\n if (child.dataset.label === targetLabel) {\n if (doHover) {\n element.classList.add('hic-whole-genome-chromosome-highlight');\n child.classList.add('hic-whole-genome-chromosome-highlight');\n } else {\n element.classList.remove('hic-whole-genome-chromosome-highlight');\n child.classList.remove('hic-whole-genome-chromosome-highlight');\n }\n }\n });\n };\n\n\n const self = this;\n let list, dimen, extent, scraps, divElement, firstDivElement;\n\n // discard current tiles\n wholeGenomeContainerElement.innerHTML = '';\n\n list = dataset.chromosomes.filter(chromosome => chromosome.name.toLowerCase() !== 'all');\n\n extent = list.reduce((sum, chromosome) => sum + chromosome.size, 0);\n\n dimen = axisName === 'x' ? axisElement.offsetWidth : axisElement.offsetHeight;\n\n scraps = 0;\n this.bboxes = [];\n firstDivElement = undefined;\n\n for (const chr of list) {\n const percentage = chr.bpLength / extent;\n\n if (percentage * dimen < 1.0) {\n scraps += percentage;\n } else {\n const divElement = document.createElement('div');\n divElement.className = `${this.axis}-axis-whole-genome-chromosome-container`;\n divElement.dataset.label = chr.name;\n wholeGenomeContainerElement.appendChild(divElement);\n\n if (!firstDivElement) {\n firstDivElement = divElement;\n }\n\n const size = Math.round(percentage * dimen);\n if (axisName === 'x') {\n divElement.style.width = `${size}px`;\n } else {\n divElement.style.height = `${size}px`;\n }\n\n // Border\n const borderElement = document.createElement('div');\n divElement.appendChild(borderElement);\n\n // Label\n const labelElement = document.createElement('div');\n borderElement.appendChild(labelElement);\n\n labelElement.textContent = divElement.dataset.label;\n labelElement.title = divElement.dataset.label;\n\n decorate(divElement);\n }\n }\n\n scraps = Math.floor(scraps * dimen);\n if (scraps >= 1) {\n\n const divElement = document.createElement('div')\n wholeGenomeContainerElement.appendChild(divElement)\n\n divElement.className = `${this.axis}-axis-whole-genome-chromosome-container`\n divElement.dataset.label = '-';\n divElement.style.width = `${scraps}px`;\n\n decorate(divElement);\n }\n\n for (const child of wholeGenomeContainerElement.children) {\n this.bboxes.push(bbox(axisName, child, firstDivElement));\n }\n\n this.hideWholeGenome();\n\n }\n\n hideWholeGenome() {\n this.wholeGenomeContainerElement.style.display = 'none';\n this.canvasElement.style.display = 'block';\n }\n\n showWholeGenome() {\n this.canvasElement.style.display = 'none';\n this.wholeGenomeContainerElement.style.display = 'flex';\n }\n\n setAxisTransform(axis) {\n\n this.canvasTransform = ('y' === axis) ? canvasTransformWithContext : identityTransformWithContext\n this.labelTransform = ('y' === axis) ? labelTransformWithContext : noopTransformWithContext\n\n }\n\n unhighlightWholeChromosome() {\n for (const child of this.wholeGenomeContainerElement.children) {\n child.classList.remove('hic-whole-genome-chromosome-highlight');\n }\n }\n\n receiveEvent(event) {\n let offset, element;\n\n if (event.type === 'MapLoad') {\n this.wholeGenomeLayout(this.axisElement, this.wholeGenomeContainerElement, this.axis, event.data);\n this.update();\n } else if (event.type === 'UpdateContactMapMousePosition') {\n if (this.bboxes) {\n this.unhighlightWholeChromosome();\n offset = this.axis === 'x' ? event.data.x : event.data.y;\n element = hitTest(this.bboxes, offset);\n if (element) {\n element.classList.add('hic-whole-genome-chromosome-highlight');\n }\n }\n }\n }\n\n locusChange(event) {\n\n this.update();\n\n }\n\n updateWidthWithCalculation(calc) {\n this.axisElement.style.width = calc;\n\n const axisWidth = this.axisElement.offsetWidth;\n this.canvasElement.width = axisWidth;\n this.canvasElement.setAttribute('width', axisWidth);\n\n this.wholeGenomeLayout(this.axisElement, this.wholeGenomeContainerElement, this.axis, this.browser.dataset);\n this.update();\n }\n\n updateHeight(height) {\n this.canvasElement.height = height;\n this.canvasElement.setAttribute('height', height);\n\n this.wholeGenomeLayout(this.axisElement, this.wholeGenomeContainerElement, this.axis, this.browser.dataset);\n this.update();\n }\n\n update() {\n const browser = this.browser;\n const config = {};\n\n if (browser.dataset.isWholeGenome(browser.state.chr1)) {\n this.showWholeGenome();\n return;\n }\n\n this.hideWholeGenome();\n\n identityTransformWithContext(this.ctx);\n igv.IGVGraphics.fillRect(\n this.ctx,\n 0,\n 0,\n this.canvasElement.width,\n this.canvasElement.height,\n { fillStyle: IGVColor.rgbColor(255, 255, 255) }\n );\n\n this.canvasTransform(this.ctx);\n\n const width = this.axis === 'x' ? this.canvasElement.width : this.canvasElement.height;\n const height = this.axis === 'x' ? this.canvasElement.height : this.canvasElement.width;\n\n igv.IGVGraphics.fillRect(\n this.ctx,\n 0,\n 0,\n width,\n height,\n { fillStyle: IGVColor.rgbColor(255, 255, 255) }\n );\n\n config.bpPerPixel = browser.dataset.bpResolutions[browser.state.zoom] / browser.state.pixelSize;\n const bin = this.axis === 'x' ? browser.state.x : browser.state.y;\n config.bpStart = bin * browser.dataset.bpResolutions[browser.state.zoom];\n\n config.rulerTickMarkReferencePixels = Math.max(\n this.canvasElement.width,\n this.canvasElement.height,\n this.otherRulerCanvas.width,\n this.otherRulerCanvas.height\n );\n\n config.rulerLengthPixels = width;\n config.rulerHeightPixels = height;\n\n config.height = Math.min(this.canvasElement.width, this.canvasElement.height);\n\n this.draw(config);\n }\n\n draw(options) {\n const {\n rulerLengthPixels,\n rulerHeightPixels,\n rulerTickMarkReferencePixels,\n bpPerPixel,\n bpStart,\n chrName\n } = options;\n\n const { chromosomes } = this.browser.dataset;\n const { state } = this.browser;\n const axisIsX = this.axis === 'x';\n const chr = axisIsX ? chromosomes[state.chr1] : chromosomes[state.chr2];\n const { name: chrNameSelected, size: chrSize } = chr;\n\n if (chrName !== \"all\") {\n // Clear the ruler area\n igv.IGVGraphics.fillRect(this.ctx, 0, 0, rulerLengthPixels, rulerHeightPixels, {\n fillStyle: IGVColor.rgbColor(255, 255, 255)\n });\n\n const fontStyle = {\n textAlign: 'center',\n font: '9px PT Sans',\n fillStyle: \"rgba(64, 64, 64, 1)\",\n strokeStyle: \"rgba(64, 64, 64, 1)\"\n };\n\n const tickSpec = findSpacing(Math.floor(rulerTickMarkReferencePixels * bpPerPixel));\n const majorTickSpacing = tickSpec.majorTick;\n\n let nTick = Math.floor(bpStart / majorTickSpacing) - 1;\n let pixel = 0;\n let pixelLast = 0;\n\n igv.IGVGraphics.setProperties(this.ctx, fontStyle);\n this.ctx.lineWidth = 1.0;\n\n const yShim = 1;\n const tickHeight = 8;\n\n while (pixel < rulerLengthPixels) {\n const l = Math.floor(nTick * majorTickSpacing);\n pixel = Math.round(((l - 1) - bpStart + 0.5) / bpPerPixel);\n\n const rulerLabel = `${formatNumber(l / tickSpec.unitMultiplier, 0)} ${tickSpec.majorUnit}`;\n const tickSpacingPixels = Math.abs(pixel - pixelLast);\n const labelWidthPixels = this.ctx.measureText(rulerLabel).width;\n\n const modulo = labelWidthPixels > tickSpacingPixels\n ? (tickSpacingPixels < 32 ? 4 : 2)\n : 1;\n\n if (nTick % modulo === 0) {\n if (Math.floor((pixel * bpPerPixel) + bpStart) < chrSize) {\n this.ctx.save();\n this.labelTransform(this.ctx, pixel);\n igv.IGVGraphics.fillText(this.ctx, rulerLabel, pixel, options.height - (tickHeight / 0.75));\n this.ctx.restore();\n }\n }\n\n if (Math.floor((pixel * bpPerPixel) + bpStart) < chrSize) {\n igv.IGVGraphics.strokeLine(\n this.ctx,\n pixel, options.height - tickHeight,\n pixel, options.height - yShim\n );\n }\n\n pixelLast = pixel;\n nTick++;\n }\n\n // Draw the baseline\n igv.IGVGraphics.strokeLine(this.ctx, 0, options.height - yShim, rulerLengthPixels, options.height - yShim);\n }\n }\n}\n\nconst formatNumber = (num, decimal = 0) => {\n // Ensure decimal is between 0 and 3\n const precision = Math.min(Math.max(decimal, 0), 3);\n\n // Round the number to the desired decimal places\n const roundedNum = Math.abs(num).toFixed(precision);\n\n // Split the integer and decimal parts\n let [integerPart, decimalPart] = roundedNum.split(\".\");\n\n // Add commas to the integer part\n integerPart = parseInt(integerPart, 10).toLocaleString();\n\n // Pad the decimal part with zeros if necessary\n if (precision > 0) {\n decimalPart = decimalPart.padEnd(precision, \"0\");\n }\n\n // Combine integer and decimal parts\n let formattedNum = precision > 0 ? `${integerPart}.${decimalPart}` : integerPart;\n\n // Wrap in parentheses if the original number was negative\n if (num < 0) {\n formattedNum = `(${formattedNum})`;\n }\n\n // Optionally, prepend a dollar sign\n // formattedNum = `$${formattedNum}`;\n\n return formattedNum;\n}\n\nfunction bbox(axis, childElement, firstChildElement) {\n const offset = axis === 'x'\n ? childElement.getBoundingClientRect().left\n : childElement.getBoundingClientRect().top;\n\n const firstOffset = axis === 'x'\n ? firstChildElement.getBoundingClientRect().left\n : firstChildElement.getBoundingClientRect().top;\n\n const delta = offset - firstOffset;\n const size = axis === 'x'\n ? childElement.offsetWidth\n : childElement.offsetHeight;\n\n return { element: childElement, a: delta, b: delta + size };\n}\n\nfunction hitTest(bboxes, value) {\n\n let hitElement = undefined;\n\n for (const bbox of bboxes) {\n if (value >= bbox.a && value <= bbox.b) {\n hitElement = bbox.element;\n break;\n }\n }\n\n return hitElement;\n}\n\nfunction TickSpacing(majorTick, majorUnit, unitMultiplier) {\n this.majorTick = majorTick;\n this.majorUnit = majorUnit;\n this.unitMultiplier = unitMultiplier;\n}\n\nfunction findSpacing(rulerLengthBP) {\n\n if (rulerLengthBP < 10) {\n return new TickSpacing(1, \"\", 1);\n }\n\n\n // How many zeroes?\n var nZeroes = Math.floor(log10(rulerLengthBP));\n var majorUnit = \"\";\n var unitMultiplier = 1;\n if (nZeroes > 9) {\n majorUnit = \"gb\";\n unitMultiplier = 1000000000;\n }\n if (nZeroes > 6) {\n majorUnit = \"mb\";\n unitMultiplier = 1000000;\n } else if (nZeroes > 3) {\n majorUnit = \"kb\";\n unitMultiplier = 1000;\n }\n\n var nMajorTicks = rulerLengthBP / Math.pow(10, nZeroes - 1);\n if (nMajorTicks < 25) {\n return new TickSpacing(Math.pow(10, nZeroes - 1), majorUnit, unitMultiplier);\n } else {\n return new TickSpacing(Math.pow(10, nZeroes) / 2, majorUnit, unitMultiplier);\n }\n\n function log10(x) {\n var dn = Math.log(10);\n return Math.log(x) / dn;\n }\n}\n\nfunction canvasTransformWithContext(ctx) {\n ctx.setTransform(0, 1, 1, 0, 0, 0)\n}\n\nfunction labelTransformWithContext(context, exe) {\n context.translate(exe, 0);\n context.scale(-1, 1);\n context.translate(-exe, 0);\n}\n\nfunction identityTransformWithContext(context) {\n // 3x2 matrix. column major. (sx 0 0 sy tx ty).\n context.setTransform(1, 0, 0, 1, 0, 0);\n}\n\nfunction noopTransformWithContext(ctx) {\n\n}\n\nexport default Ruler;\n","/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2016-2017 The Regents of the University of California\n * Author: Jim Robinson\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n *\n *\n * This class uses icons from Font Awesome\n * Font Awesome Free 5.0.8 by @fontawesome - https://fontawesome.com\n * License - https://fontawesome.com/license (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)\n */\n\nconst createCheckbox = (name, initialState) => {\n // Create the container div\n const container = document.createElement('div');\n container.className = 'jb-igv-menu-popup-check-container';\n\n // Create the inner div\n const div = document.createElement('div');\n container.appendChild(div);\n\n // Create the check icon using the existing iconMarkup function\n const svg = iconMarkup('check', initialState === true ? '#444' : 'transparent');\n div.appendChild(svg);\n\n // Create the label div\n const label = document.createElement('div');\n label.textContent = name;\n // Optional: Add a class to the label if needed\n // label.className = 'igv-some-label-class';\n\n container.appendChild(label);\n\n return container;\n};\n\nfunction createIcon(name, color) {\n return iconMarkup(name, color);\n}\n\nconst iconMarkup = (name, color = \"currentColor\") => {\n const icon = icons[name] ?? icons[\"question\"];\n\n if (!icons[name]) {\n console.error(`No icon named: ${name}`);\n }\n\n const [width, height, , , pathData] = icon;\n\n // Create the SVG element with the correct namespace\n const svgNS = \"http://www.w3.org/2000/svg\";\n const svg = document.createElementNS(svgNS, \"svg\");\n\n // Set SVG attributes\n svg.setAttribute(\"viewBox\", `0 0 ${width} ${height}`);\n svg.setAttribute(\"xmlns\", svgNS);\n svg.setAttribute(\"aria-label\", `${name} icon`);\n svg.setAttribute(\"role\", \"img\");\n\n // Create the path element\n const path = document.createElementNS(svgNS, \"path\");\n path.setAttribute(\"fill\", color);\n path.setAttribute(\"d\", pathData);\n\n // Append the path to the SVG\n svg.appendChild(path);\n\n return svg;\n}\n\nconst icons = {\n \"check\": [512, 512, [], \"f00c\", \"M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z\"],\n \"cog\": [512, 512, [], \"f013\", \"M444.788 291.1l42.616 24.599c4.867 2.809 7.126 8.618 5.459 13.985-11.07 35.642-29.97 67.842-54.689 94.586a12.016 12.016 0 0 1-14.832 2.254l-42.584-24.595a191.577 191.577 0 0 1-60.759 35.13v49.182a12.01 12.01 0 0 1-9.377 11.718c-34.956 7.85-72.499 8.256-109.219.007-5.49-1.233-9.403-6.096-9.403-11.723v-49.184a191.555 191.555 0 0 1-60.759-35.13l-42.584 24.595a12.016 12.016 0 0 1-14.832-2.254c-24.718-26.744-43.619-58.944-54.689-94.586-1.667-5.366.592-11.175 5.459-13.985L67.212 291.1a193.48 193.48 0 0 1 0-70.199l-42.616-24.599c-4.867-2.809-7.126-8.618-5.459-13.985 11.07-35.642 29.97-67.842 54.689-94.586a12.016 12.016 0 0 1 14.832-2.254l42.584 24.595a191.577 191.577 0 0 1 60.759-35.13V25.759a12.01 12.01 0 0 1 9.377-11.718c34.956-7.85 72.499-8.256 109.219-.007 5.49 1.233 9.403 6.096 9.403 11.723v49.184a191.555 191.555 0 0 1 60.759 35.13l42.584-24.595a12.016 12.016 0 0 1 14.832 2.254c24.718 26.744 43.619 58.944 54.689 94.586 1.667 5.366-.592 11.175-5.459 13.985L444.788 220.9a193.485 193.485 0 0 1 0 70.2zM336 256c0-44.112-35.888-80-80-80s-80 35.888-80 80 35.888 80 80 80 80-35.888 80-80z\"],\n \"exclamation\": [192, 512, [], \"f12a\", \"M176 432c0 44.112-35.888 80-80 80s-80-35.888-80-80 35.888-80 80-80 80 35.888 80 80zM25.26 25.199l13.6 272C39.499 309.972 50.041 320 62.83 320h66.34c12.789 0 23.331-10.028 23.97-22.801l13.6-272C167.425 11.49 156.496 0 142.77 0H49.23C35.504 0 24.575 11.49 25.26 25.199z\"],\n \"exclamation-circle\": [512, 512, [], \"f06a\", \"M504 256c0 136.997-111.043 248-248 248S8 392.997 8 256C8 119.083 119.043 8 256 8s248 111.083 248 248zm-248 50c-25.405 0-46 20.595-46 46s20.595 46 46 46 46-20.595 46-46-20.595-46-46-46zm-43.673-165.346l7.418 136c.347 6.364 5.609 11.346 11.982 11.346h48.546c6.373 0 11.635-4.982 11.982-11.346l7.418-136c.375-6.874-5.098-12.654-11.982-12.654h-63.383c-6.884 0-12.356 5.78-11.981 12.654z\"],\n \"exclamation-triangle\": [576, 512, [], \"f071\", \"M569.517 440.013C587.975 472.007 564.806 512 527.94 512H48.054c-36.937 0-59.999-40.055-41.577-71.987L246.423 23.985c18.467-32.009 64.72-31.951 83.154 0l239.94 416.028zM288 354c-25.405 0-46 20.595-46 46s20.595 46 46 46 46-20.595 46-46-20.595-46-46-46zm-43.673-165.346l7.418 136c.347 6.364 5.609 11.346 11.982 11.346h48.546c6.373 0 11.635-4.982 11.982-11.346l7.418-136c.375-6.874-5.098-12.654-11.982-12.654h-63.383c-6.884 0-12.356 5.78-11.981 12.654z\"],\n \"minus\": [448, 512, [], \"f068\", \"M424 318.2c13.3 0 24-10.7 24-24v-76.4c0-13.3-10.7-24-24-24H24c-13.3 0-24 10.7-24 24v76.4c0 13.3 10.7 24 24 24h400z\"],\n \"minus-circle\": [512, 512, [], \"f056\", \"M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zM124 296c-6.6 0-12-5.4-12-12v-56c0-6.6 5.4-12 12-12h264c6.6 0 12 5.4 12 12v56c0 6.6-5.4 12-12 12H124z\"],\n \"minus-square\": [448, 512, [], \"f146\", \"M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM92 296c-6.6 0-12-5.4-12-12v-56c0-6.6 5.4-12 12-12h264c6.6 0 12 5.4 12 12v56c0 6.6-5.4 12-12 12H92z\"],\n \"plus\": [448, 512, [], \"f067\", \"M448 294.2v-76.4c0-13.3-10.7-24-24-24H286.2V56c0-13.3-10.7-24-24-24h-76.4c-13.3 0-24 10.7-24 24v137.8H24c-13.3 0-24 10.7-24 24v76.4c0 13.3 10.7 24 24 24h137.8V456c0 13.3 10.7 24 24 24h76.4c13.3 0 24-10.7 24-24V318.2H424c13.3 0 24-10.7 24-24z\"],\n \"plus-circle\": [512, 512, [], \"f055\", \"M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm144 276c0 6.6-5.4 12-12 12h-92v92c0 6.6-5.4 12-12 12h-56c-6.6 0-12-5.4-12-12v-92h-92c-6.6 0-12-5.4-12-12v-56c0-6.6 5.4-12 12-12h92v-92c0-6.6 5.4-12 12-12h56c6.6 0 12 5.4 12 12v92h92c6.6 0 12 5.4 12 12v56z\"],\n \"plus-square\": [448, 512, [], \"f0fe\", \"M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-32 252c0 6.6-5.4 12-12 12h-92v92c0 6.6-5.4 12-12 12h-56c-6.6 0-12-5.4-12-12v-92H92c-6.6 0-12-5.4-12-12v-56c0-6.6 5.4-12 12-12h92v-92c0-6.6 5.4-12 12-12h56c6.6 0 12 5.4 12 12v92h92c6.6 0 12 5.4 12 12v56z\"],\n \"question\": [384, 512, [], \"f128\", \"M202.021 0C122.202 0 70.503 32.703 29.914 91.026c-7.363 10.58-5.093 25.086 5.178 32.874l43.138 32.709c10.373 7.865 25.132 6.026 33.253-4.148 25.049-31.381 43.63-49.449 82.757-49.449 30.764 0 68.816 19.799 68.816 49.631 0 22.552-18.617 34.134-48.993 51.164-35.423 19.86-82.299 44.576-82.299 106.405V320c0 13.255 10.745 24 24 24h72.471c13.255 0 24-10.745 24-24v-5.773c0-42.86 125.268-44.645 125.268-160.627C377.504 66.256 286.902 0 202.021 0zM192 373.459c-38.196 0-69.271 31.075-69.271 69.271 0 38.195 31.075 69.27 69.271 69.27s69.271-31.075 69.271-69.271-31.075-69.27-69.271-69.27z\"],\n \"save\": [448, 512, [], \"f0c7\", \"M433.941 129.941l-83.882-83.882A48 48 0 0 0 316.118 32H48C21.49 32 0 53.49 0 80v352c0 26.51 21.49 48 48 48h352c26.51 0 48-21.49 48-48V163.882a48 48 0 0 0-14.059-33.941zM224 416c-35.346 0-64-28.654-64-64 0-35.346 28.654-64 64-64s64 28.654 64 64c0 35.346-28.654 64-64 64zm96-304.52V212c0 6.627-5.373 12-12 12H76c-6.627 0-12-5.373-12-12V108c0-6.627 5.373-12 12-12h228.52c3.183 0 6.235 1.264 8.485 3.515l3.48 3.48A11.996 11.996 0 0 1 320 111.48z\"],\n \"search\": [512, 512, [], \"f002\", \"M505 442.7L405.3 343c-4.5-4.5-10.6-7-17-7H372c27.6-35.3 44-79.7 44-128C416 93.1 322.9 0 208 0S0 93.1 0 208s93.1 208 208 208c48.3 0 92.7-16.4 128-44v16.3c0 6.4 2.5 12.5 7 17l99.7 99.7c9.4 9.4 24.6 9.4 33.9 0l28.3-28.3c9.4-9.4 9.4-24.6.1-34zM208 336c-70.7 0-128-57.2-128-128 0-70.7 57.2-128 128-128 70.7 0 128 57.2 128 128 0 70.7-57.2 128-128 128z\"],\n \"share\": [512, 512, [], \"f064\", \"M503.691 189.836L327.687 37.851C312.281 24.546 288 35.347 288 56.015v80.053C127.371 137.907 0 170.1 0 322.326c0 61.441 39.581 122.309 83.333 154.132 13.653 9.931 33.111-2.533 28.077-18.631C66.066 312.814 132.917 274.316 288 272.085V360c0 20.7 24.3 31.453 39.687 18.164l176.004-152c11.071-9.562 11.086-26.753 0-36.328z\"],\n \"spinner\": [512, 512, [], \"f110\", \"M304 48c0 26.51-21.49 48-48 48s-48-21.49-48-48 21.49-48 48-48 48 21.49 48 48zm-48 368c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48-21.49-48-48-48zm208-208c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48-21.49-48-48-48zM96 256c0-26.51-21.49-48-48-48S0 229.49 0 256s21.49 48 48 48 48-21.49 48-48zm12.922 99.078c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48c0-26.509-21.491-48-48-48zm294.156 0c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48c0-26.509-21.49-48-48-48zM108.922 60.922c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48-21.491-48-48-48z\"],\n \"square\": [448, 512, [], \"f0c8\", \"M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48z\"],\n \"square-full\": [512, 512, [], \"f45c\", \"M512 512H0V0h512v512z\"],\n \"times\": [384, 512, [], \"f00d\", \"M323.1 441l53.9-53.9c9.4-9.4 9.4-24.5 0-33.9L279.8 256l97.2-97.2c9.4-9.4 9.4-24.5 0-33.9L323.1 71c-9.4-9.4-24.5-9.4-33.9 0L192 168.2 94.8 71c-9.4-9.4-24.5-9.4-33.9 0L7 124.9c-9.4 9.4-9.4 24.5 0 33.9l97.2 97.2L7 353.2c-9.4 9.4-9.4 24.5 0 33.9L60.9 441c9.4 9.4 24.5 9.4 33.9 0l97.2-97.2 97.2 97.2c9.3 9.3 24.5 9.3 33.9 0z\"],\n \"times-circle\": [512, 512, [], \"f057\", \"M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm121.6 313.1c4.7 4.7 4.7 12.3 0 17L338 377.6c-4.7 4.7-12.3 4.7-17 0L256 312l-65.1 65.6c-4.7 4.7-12.3 4.7-17 0L134.4 338c-4.7-4.7-4.7-12.3 0-17l65.6-65-65.6-65.1c-4.7-4.7-4.7-12.3 0-17l39.6-39.6c4.7-4.7 12.3-4.7 17 0l65 65.7 65.1-65.6c4.7-4.7 12.3-4.7 17 0l39.6 39.6c4.7 4.7 4.7 12.3 0 17L312 256l65.6 65.1z\"],\n \"wrench\": [512, 512, [], \"f0ad\", \"M481.156 200c9.3 0 15.12 10.155 10.325 18.124C466.295 259.992 420.419 288 368 288c-79.222 0-143.501-63.974-143.997-143.079C223.505 65.469 288.548-.001 368.002 0c52.362.001 98.196 27.949 123.4 69.743C496.24 77.766 490.523 88 481.154 88H376l-40 56 40 56h105.156zm-171.649 93.003L109.255 493.255c-24.994 24.993-65.515 24.994-90.51 0-24.993-24.994-24.993-65.516 0-90.51L218.991 202.5c16.16 41.197 49.303 74.335 90.516 90.503zM104 432c0-13.255-10.745-24-24-24s-24 10.745-24 24 10.745 24 24 24 24-10.745 24-24z\"],\n};\n\nexport {createIcon, createCheckbox};\n\n\n","import {createCheckbox} from \"./igv-icons.js\"\n\n/**\n * Configure item list for track \"gear\" menu.\n * @param trackRenderer\n */\nconst MenuUtils = {\n\n trackMenuItemList: trackPair => {\n\n const menuItems = []\n\n menuItems.push(trackRenameMenuItem(trackPair))\n menuItems.push(\"
\")\n\n menuItems.push(colorPickerMenuItem({ trackPair, label: \"Set color\", option: \"color\" }))\n menuItems.push(unsetColorMenuItem({ trackPair, label: \"Unset color\" }))\n\n if (trackPair.track.removable !== false) {\n menuItems.push('
');\n menuItems.push(trackRemovalMenuItem(trackPair))\n }\n\n return menuItems\n },\n\n numericDataMenuItems: trackPair => {\n const menuItems = [];\n\n // Data range\n const element = document.createElement('div');\n element.textContent = 'Set data range';\n\n const click = () => {\n const { min, max } = trackPair.track.dataRange;\n trackPair.dataRangeDialog.show({ min: min || 0, max });\n };\n\n menuItems.push({ element, click });\n\n if (trackPair.track.logScale !== undefined) {\n menuItems.push({\n element: createCheckbox(\"Log scale\", trackPair.track.logScale),\n click: () => {\n trackPair.track.logScale = !trackPair.track.logScale;\n trackPair.repaintViews();\n }\n });\n }\n\n menuItems.push({\n element: createCheckbox(\"Autoscale\", trackPair.track.autoscale),\n click: () => {\n trackPair.track.autoscale = !trackPair.track.autoscale;\n trackPair.repaintViews();\n }\n });\n\n return menuItems;\n },\n\n nucleotideColorChartMenuItems: trackPair => {\n const menuItems = [];\n menuItems.push(document.createElement('hr'));\n\n const element = document.createElement('div');\n element.className = 'jb-igv-menu-popup-chart';\n element.innerHTML = `\n
A
\n
C
\n
T
\n
G
\n `;\n\n const click = e => {\n e.preventDefault();\n e.stopPropagation();\n };\n\n menuItems.push({ element, click });\n\n return menuItems;\n }\n\n}\n\nfunction trackRemovalMenuItem(trackPair) {\n const element = document.createElement('div');\n element.textContent = 'Remove track';\n\n const click = () => trackPair.browser.layoutController.removeTrackXYPair(trackPair);\n\n return { element, click };\n}\n\nfunction colorPickerMenuItem({ trackPair, label, option }) {\n const element = document.createElement('div');\n element.textContent = label;\n\n const click = () => trackPair.colorPicker.show();\n\n return { element, click };\n}\n\nfunction unsetColorMenuItem({ trackPair, label }) {\n const element = document.createElement('div');\n element.textContent = label;\n\n const click = () => {\n trackPair.track.color = undefined;\n trackPair.repaintViews();\n };\n\n return { element, click };\n}\n\nfunction trackRenameMenuItem(trackPair) {\n const element = document.createElement('div');\n element.textContent = 'Set track name';\n\n const click = e => {\n const callback = value => {\n let name;\n if (value === '' || value === undefined) {\n name = '';\n } else {\n name = value.trim();\n }\n trackPair.track.name = name;\n };\n\n const value = trackPair.track.name || '';\n trackPair.browser.inputDialog.present({ label: 'Track Name', value, callback }, e);\n };\n\n return { element, click };\n}\n\nexport default MenuUtils\n","/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2014 Broad Institute\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\nimport {makeDraggable, UIUtils} from '../node_modules/igv-ui/dist/igv-ui.js'\n\nclass TrackGearPopup {\n\n constructor(parentElement) {\n // Popover container\n this.popoverElement = document.createElement('div');\n this.popoverElement.className = 'jb-igv-menu-popup';\n parentElement.appendChild(this.popoverElement);\n\n // Popover header\n const popoverHeaderElement = document.createElement('div');\n popoverHeaderElement.className = 'jb-igv-menu-popup-header';\n this.popoverElement.appendChild(popoverHeaderElement);\n\n // Attach close handler\n UIUtils.attachDialogCloseHandlerWithParent(popoverHeaderElement, () => {\n this.popoverElement.style.display = 'none';\n });\n\n // Popover content\n this.popoverContentElement = document.createElement('div');\n this.popoverElement.appendChild(this.popoverContentElement);\n\n // Make draggable\n makeDraggable(this.popoverElement, popoverHeaderElement);\n\n // Prevent click propagation\n popoverHeaderElement.addEventListener('click', (e) => {\n e.stopPropagation();\n e.preventDefault();\n });\n }\n\n presentMenuList(dx, dy, list) {\n TrackGearPopup.hideAllMenuPopups();\n\n if (list.length > 0) {\n // Clear popover content\n this.popoverContentElement.innerHTML = '';\n\n const updatedList = trackMenuItemListHelper(list, this.popoverElement);\n\n for (const item of updatedList) {\n if (item.init) {\n item.init();\n }\n\n\n // Remove the border-top class from the first item\n if (updatedList.indexOf(item) === 0) {\n item.element.classList.remove('igv-track-menu-border-top');\n }\n\n // Add 'jb-igv-menu-popup-shim' if applicable\n if (\n !item.element.classList.contains('igv-track-menu-border-top') &&\n !item.element.classList.contains('jb-igv-menu-popup-check-container') &&\n item.element.tagName === 'DIV'\n ) {\n item.element.classList.add('jb-igv-menu-popup-shim');\n }\n\n // Append element to the popover content\n this.popoverContentElement.appendChild(item.element);\n }\n\n // Position and display the popover\n this.popoverElement.style.left = `${dx}px`;\n this.popoverElement.style.top = `${dy}px`;\n this.popoverElement.style.display = 'block';\n }\n }\n\n dispose() {\n this.popoverElement.innerHTML = '';\n this.popoverContentElement.innerHTML = '';\n\n for (let key of Object.keys(this)) {\n this[key] = undefined;\n }\n }\n\n static hideAllMenuPopups() {\n const popups = document.querySelectorAll('.jb-igv-menu-popup');\n for (let popup of popups) {\n popup.style.display = 'none';\n }\n }\n\n}\n\nfunction trackMenuItemListHelper(itemList, popoverElement) {\n\n let results = []\n\n if (itemList.length > 0) {\n\n results = itemList.map((item, i) => {\n let element;\n \n if (item.name) {\n element = document.createElement('div');\n element.textContent = item.name;\n } else if (item.element) {\n element = item.element instanceof HTMLElement ? item.element.cloneNode(true) : item.element;\n } else if (typeof item.label === 'string') {\n element = document.createElement('div');\n element.innerHTML = item.label;\n } else if (typeof item === 'string') {\n if (item.startsWith(\"<\")) {\n const tempDiv = document.createElement('div');\n tempDiv.innerHTML = item;\n element = tempDiv.firstElementChild;\n } else {\n element = document.createElement('div');\n element.textContent = item;\n }\n }\n\n // Add top border class to the first item\n if (i === 0 && element) {\n element.classList.add('igv-track-menu-border-top');\n }\n\n // Add click, touchend, and mouseup event listeners if item has a click handler\n if (item.click && element) {\n const eventHandler = e => {\n e.preventDefault();\n e.stopPropagation();\n item.click(e);\n popoverElement.style.display = 'none';\n };\n\n element.addEventListener('click', eventHandler);\n element.addEventListener('touchend', eventHandler);\n element.addEventListener('mouseup', e => {\n e.preventDefault();\n e.stopPropagation();\n });\n }\n\n return { element, init: item.init || undefined };\n });\n }\n\n return results;\n}\n\nexport default TrackGearPopup\n\n","\nclass Tile {\n\n constructor(chr, startBP, endBP, bpp, buffer, features) {\n this.chr = chr;\n this.startBP = startBP;\n this.endBP = endBP;\n this.bpp = bpp;\n this.buffer = buffer;\n this.features = features;\n }\n\n containsRange(chr, startBP, endBP, bpp) {\n return chr === this.chr && this.bpp === bpp && this.startBP <= startBP && this.endBP >= endBP;\n }\n}\n\nexport default Tile\n","/**\n * Created by dat on 4/5/17.\n */\n\nimport igv from '../node_modules/igv/dist/igv.esm.js'\nimport {ColorPicker, DataRangeDialog} from '../node_modules/igv-ui/dist/igv-ui.js'\nimport MenuUtils from \"./trackMenuUtils.js\"\nimport TrackGearPopup from \"./trackGearPopup.js\"\nimport {createIcon} from \"./igv-icons.js\"\nimport Tile from \"./tile.js\";\n\nclass TrackPair {\n\n constructor(browser, track) {\n this.browser = browser\n this.track = track\n this.x = undefined\n this.y = undefined\n }\n\n init() {\n this.colorPicker = new ColorPicker({\n parent: this.x.viewportElement,\n width: 456,\n height: undefined,\n colorHandler: color => this.setColor(color)\n });\n this.colorPicker.hide();\n\n this.dataRangeDialog = new DataRangeDialog(this.x.viewportElement, (min, max) => this.setDataRange(min, max));\n\n this.appendRightHandGutter(this.x.viewportElement);\n\n for (const el of this.x.trackReorderHandleElement.querySelectorAll('.fa')) {\n el.addEventListener('click', e => {\n e.preventDefault();\n e.stopPropagation();\n\n const direction = e.target.classList.contains('fa-arrow-up') ? -1 : 1;\n\n let order = parseInt(this.x.viewportElement.style.order);\n\n if (order === 0 && direction === -1) {\n return;\n } else if (this.browser.trackPairs.length - 1 === order && direction === 1) {\n return;\n }\n\n const newOrder = direction === -1 ? order - 1 : order + 1;\n\n const targetTrackPair = this.browser.trackPairs.find(\n trackPair => newOrder === parseInt(trackPair.x.viewportElement.style.order)\n );\n\n if (targetTrackPair) {\n targetTrackPair.x.viewportElement.style.order = `${order}`;\n targetTrackPair.y.viewportElement.style.order = `${order}`;\n }\n\n this.x.viewportElement.style.order = `${newOrder}`;\n this.y.viewportElement.style.order = `${newOrder}`;\n\n const a = this.browser.trackPairs;\n [a[order], a[newOrder]] = [a[newOrder], a[order]];\n\n setTrackReorderArrowColors(this.browser.trackPairs);\n });\n }\n\n // igvjs compatibility\n this.track.trackView = this;\n this.track.trackView.trackDiv = this.x.viewportElement;\n }\n\n presentColorPicker() {\n const bbox = this.x.trackDiv.getBoundingClientRect();\n this.colorPicker.origin = { x: bbox.x, y: 0 };\n\n // Set the position of the colorPicker container\n this.colorPicker.containerElement.style.left = `${this.colorPicker.origin.x}px`;\n this.colorPicker.containerElement.style.top = `${this.colorPicker.origin.y}px`;\n\n // Show the colorPicker container\n this.colorPicker.containerElement.style.display = 'block';\n }\n\n setTrackLabelName(name) {\n this.x.labelElement.textContent = name;\n this.x.labelElement.title = name;\n }\n\n setColor(color) {\n this.y.tile = undefined;\n this.x.tile = undefined;\n this.track.color = color;\n this.repaintViews();\n }\n\n dataRange() {\n return this.track.dataRange ? this.track.dataRange : undefined;\n }\n\n setDataRange(min, max) {\n if (min !== undefined) {\n this.track.dataRange.min = min;\n this.track.config.min = min;\n }\n if (max !== undefined) {\n this.track.dataRange.max = max;\n this.track.config.max = max;\n }\n this.track.autoscale = false;\n this.track.config.autoScale = false\n this.y.tile = undefined;\n this.x.tile = undefined;\n this.repaintViews();\n }\n\n appendRightHandGutter(parentElement) {\n const div = document.createElement('div');\n div.className = 'hic-igv-right-hand-gutter';\n parentElement.appendChild(div);\n this.createTrackGearPopup(div);\n }\n\n createTrackGearPopup(parentElement) {\n const container = document.createElement('div');\n container.className = 'igv-trackgear-container';\n parentElement.appendChild(container);\n\n container.appendChild(createIcon('cog'));\n\n this.trackGearPopup = new TrackGearPopup(parentElement);\n this.trackGearPopup.popoverElement.style.display = 'none';\n\n container.addEventListener('click', e => {\n e.preventDefault();\n e.stopPropagation();\n\n const { trackMenuItemList, numericDataMenuItems, nucleotideColorChartMenuItems } = MenuUtils;\n\n const list = [...trackMenuItemList(this)];\n\n if (this.track.type === 'wig') {\n list.push(...numericDataMenuItems(this));\n }\n\n if (this.track.type === 'sequence') {\n list.push(...nucleotideColorChartMenuItems(this));\n }\n\n const width = this.trackGearPopup.popoverElement.getBoundingClientRect().width;\n\n this.trackGearPopup.presentMenuList(-width, 0, list);\n });\n }\n\n async updateViews() {\n\n if (this.updating) {\n this.pending = true;\n } else {\n try {\n this.updating = true;\n const genomicStateX = this.browser.genomicState(this.x.axis);\n let imageTileX = await this.getTileX(genomicStateX);\n if (imageTileX) {\n this.x.drawTile(imageTileX, genomicStateX);\n }\n\n const genomicStateY = this.browser.genomicState(this.y.axis);\n let imageTileY = await this.getTileY(genomicStateY);\n if (imageTileY) {\n this.y.drawTile(imageTileY, genomicStateY);\n }\n } finally {\n this.updating = false;\n if (this.pending) {\n this.pending = false;\n this.updateViews();\n }\n }\n }\n }\n\n /**\n * Repaint current tiles with cached features (due to color, scale, or other visual attribute change)\n * @returns {Promise}\n */\n async repaintViews() {\n\n const genomicStateX = this.browser.genomicState(this.x.axis);\n if (this.tileX) {\n this.tileX = await this.createImageTile({ axis: 'x', ...genomicStateX }, this.tileX.features)\n this.x.drawTile(this.tileX, genomicStateX);\n }\n\n const genomicStateY = this.browser.genomicState(this.y.axis);\n if (this.tileY) {\n this.tileY = await this.createImageTile({ axis: 'y', ...genomicStateY }, this.tileY.features)\n this.y.drawTile(this.tileY, genomicStateY)\n }\n }\n\n async getTileX(genomicState) {\n\n const { chromosome, bpp } = genomicState\n\n if (!(this.tileX && this.tileX.containsRange(chromosome.name, genomicState.startBP, genomicState.endBP, bpp))) {\n this.tileX = await this.createImageTile({ axis: 'x', ...genomicState })\n }\n\n return this.tileX\n }\n\n async getTileY(genomicState) {\n\n const { chromosome, bpp } = genomicState\n\n if (!(this.tileY && this.tileY.containsRange(chromosome.name, genomicState.startBP, genomicState.endBP, bpp))) {\n this.tileY = await this.createImageTile({ axis: 'y', ...genomicState })\n }\n\n return this.tileY\n }\n\n async createImageTile(genomicState, tileFeatures) {\n if (\n this.track.visibilityWindow > 0 &&\n genomicState.bpp * Math.max(this.x.canvasElement.width, this.x.canvasElement.height) > this.track.visibilityWindow\n ) {\n // TODO -- return zoom in message\n } else {\n // Expand the requested range so we can pan a bit without reloading\n const pixelWidth = 3 * this.x.canvasElement.width;\n const lengthBP = Math.round(genomicState.bpp * pixelWidth);\n const bpStart = Math.max(0, Math.round(genomicState.startBP - lengthBP / 3));\n const bpEnd = bpStart + lengthBP;\n\n const features = tileFeatures || await this.track.getFeatures(\n genomicState.chromosome.name,\n bpStart,\n bpEnd,\n genomicState.bpp\n );\n\n const canvas = document.createElement('canvas');\n canvas.width = pixelWidth;\n canvas.height = this.x.canvasElement.height;\n\n const context = canvas.getContext('2d');\n\n if (features) {\n const drawConfiguration = {\n axis: genomicState.axis,\n features,\n context,\n pixelWidth,\n bpStart,\n bpEnd,\n bpPerPixel: genomicState.bpp,\n genomicState,\n pixelHeight: Math.min(canvas.width, canvas.height),\n viewportContainerX: (genomicState.startBP - bpStart) / genomicState.bpp,\n viewportContainerWidth: pixelWidth,\n viewportWidth: pixelWidth,\n referenceFrame: {},\n };\n\n if (this.track.autoscale || !this.track.dataRange) {\n if (typeof this.track.doAutoscale === 'function') {\n this.track.doAutoscale(features);\n } else {\n this.track.dataRange = doAutoscale(features);\n }\n }\n\n this.track.draw(drawConfiguration);\n } else {\n const wye = canvas.height - canvas.height / 4;\n igv.IGVGraphics.fillRect(context, 0, wye, canvas.width, 2, { fillStyle: 'rgba(0,0,0,0.1)' });\n }\n\n this.tile = new Tile(genomicState.chromosome.name, bpStart, bpEnd, genomicState.bpp, canvas, features);\n return this.tile;\n }\n }\n\n dispose() {\n this.x.dispose()\n this.y.dispose()\n }\n}\n\nfunction doAutoscale (features = []) {\n let min = Number.MAX_VALUE;\n let max = -Number.MAX_VALUE;\n\n if (features.length > 0) {\n for (const { value } of features) {\n if (!Number.isNaN(value)) {\n min = Math.min(min, value);\n max = Math.max(max, value);\n }\n }\n\n // Ensure we have a zero baseline\n if (max > 0) min = Math.min(0, min);\n if (max < 0) max = 0;\n } else {\n // No features -- default\n min = 0;\n max = 100;\n }\n\n return { min, max };\n}\n\nfunction setTrackReorderArrowColors(trackPairs) {\n\n for (const trackPair of trackPairs) {\n const el = trackPair.x.viewportElement;\n const order = parseInt(el.style.order);\n\n const arrowUp = el.querySelector('.fa-arrow-up');\n const arrowDown = el.querySelector('.fa-arrow-down');\n\n if (order === 0) {\n arrowUp.style.color = 'rgba(0, 0, 0, 0)';\n arrowDown.style.color = '#7F7F7F';\n } else if (order === trackPairs.length - 1) {\n arrowUp.style.color = '#7F7F7F';\n arrowDown.style.color = 'rgba(0, 0, 0, 0)';\n } else {\n arrowUp.style.color = '#7F7F7F';\n arrowDown.style.color = '#7F7F7F';\n }\n }\n\n}\n\nexport { setTrackReorderArrowColors }\nexport default TrackPair\n","import { DOMUtils } from '../node_modules/igv-ui/dist/igv-ui.js';\n\nclass TrackRenderer {\n\n constructor(browser, track, axis) {\n this.browser = browser;\n this.track = track;\n this.axis = axis;\n this.id = `trackRender_${DOMUtils.guid()}`;\n }\n\n init(containerElement, size, order) {\n this.viewportElement = document.createElement('div');\n this.viewportElement.className = (this.axis === 'x') ? 'x-track-canvas-container' : 'y-track-canvas-container';\n containerElement.appendChild(this.viewportElement);\n\n if (this.axis === 'x') {\n this.viewportElement.style.height = `${size}px`;\n } else {\n this.viewportElement.style.width = `${size}px`;\n }\n this.viewportElement.style.order = `${order}`;\n\n this.canvasElement = document.createElement('canvas');\n this.viewportElement.appendChild(this.canvasElement);\n this.ctx = this.canvasElement.getContext(\"2d\");\n\n if (this.axis === 'x') {\n this.trackReorderHandleElement = document.createElement('div');\n this.trackReorderHandleElement.className = 'x-track-reorder-handle';\n this.viewportElement.appendChild(this.trackReorderHandleElement);\n\n this.trackReorderHandleElement.innerHTML = '';\n\n this.labelElement = document.createElement('div');\n this.labelElement.className = 'x-track-label';\n this.viewportElement.appendChild(this.labelElement);\n\n const labelText = this.track.name || '';\n this.labelElement.textContent = labelText;\n this.labelElement.title = labelText;\n\n this.labelElement.style.display = this.browser.showTrackLabelAndGutter ? 'block' : 'none';\n\n this.viewportElement.addEventListener('click', (e) => {\n e.preventDefault();\n e.stopPropagation();\n this.browser.toggleTrackLabelAndGutterState();\n const displayState = this.browser.showTrackLabelAndGutter ? 'block' : 'none';\n document.querySelectorAll('.x-track-label, .hic-igv-right-hand-gutter').forEach(el => {\n el.style.display = displayState;\n });\n });\n }\n\n this.spinnerElement = document.createElement('div');\n this.spinnerElement.className = (this.axis === 'x') ? 'x-track-spinner' : 'y-track-spinner';\n this.viewportElement.appendChild(this.spinnerElement);\n this.stopSpinner();\n }\n\n dispose() {\n this.tile = undefined;\n this.viewportElement.remove();\n }\n\n syncCanvas() {\n this.canvasElement.width = this.viewportElement.offsetWidth;\n this.canvasElement.height = this.viewportElement.offsetHeight;\n }\n\n drawTile(tile, genomicState) {\n if (tile) {\n\n let w\n let h\n if (this.axis === 'x') {\n w = this.canvasElement.width\n h = this.canvasElement.height\n } else {\n h = this.canvasElement.width\n w = this.canvasElement.height\n this.ctx.setTransform(0, 1, 1, 0, 0, 0);\n }\n\n this.ctx.clearRect(0, 0, w, h);\n\n this.offsetPixel = Math.round((tile.startBP - genomicState.startBP) / genomicState.bpp);\n this.ctx.drawImage(tile.buffer, this.offsetPixel, 0);\n\n }\n }\n\n startSpinner() {\n this.browser.startSpinner();\n }\n\n stopSpinner() {\n this.browser.stopSpinner();\n }\n\n isLoading() {\n return this.loading !== undefined;\n }\n}\n\nexport default TrackRenderer;\n","/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2016-2017 The Regents of the University of California\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and\n * associated documentation files (the \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the\n * following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all copies or substantial\n * portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING\n * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n *\n */\n\n\nfunction HICEvent (type, data, propogate) {\n return {\n type: type,\n data: data || {},\n propogate: propogate !== undefined ? propogate : true // Default to true\n }\n};\n\n\nexport default HICEvent\n","\n/**\n * Test if object is a File or File-like object.\n *\n * Copied from igv-utils.FileUtils version 1.3.8\n *\n * @param object\n */\nfunction isFile(object) {\n if(!object) {\n return false;\n }\n return typeof object !== 'function' &&\n (object instanceof File ||\n (object.name !== undefined && typeof object.slice === 'function' && typeof object.arrayBuffer === 'function'))\n}\n\nexport {isFile}\n","import {Alert} from '../node_modules/igv-ui/dist/igv-ui.js'\nimport {isFile} from \"./fileUtils.js\"\n\nfunction createDOMFromHTMLString(string) {\n const template = document.createElement('template');\n template.innerHTML = string.trim(); // Removes whitespace to avoid unintended text nodes\n return template.content.firstElementChild;\n}\n\nfunction getOffset(element) {\n const { top, left } = element.getBoundingClientRect();\n return { top: top + window.scrollY, left: left + window.scrollX };\n}\n\nfunction parseRgbString(rgbString) {\n\n // Use a regular expression to extract the numbers from the string\n const match = rgbString.match(/^rgb\\((\\d+),\\s*(\\d+),\\s*(\\d+)\\)$/);\n\n // Check if the match is successful\n if (!match) {\n throw new Error(\"Invalid RGB string format\");\n }\n\n // Convert the matched strings into integers and return them as an array\n return match.slice(1, 4).map(Number);\n}\n\nfunction prettyPrint(number) {\n\n if (typeof number !== \"number\") {\n console.error(`${ number } must be a number`)\n return\n }\n\n const integerPart = Math.trunc(number)\n return integerPart.toLocaleString()\n}\n\nfunction extractName(config) {\n if (config.name === undefined) {\n const urlOrFile = config.url\n if (isFile(urlOrFile)) {\n return urlOrFile.name\n } else {\n const str = urlOrFile.split('?').shift()\n const idx = urlOrFile.lastIndexOf(\"/\")\n return idx > 0 ? str.substring(idx + 1) : str\n }\n } else {\n return config.name\n }\n}\n\nfunction presentError(prefix, error) {\n const httpMessages =\n {\n 401: \"Access unauthorized\",\n 403: \"Access forbidden\",\n 404: \"Not found\"\n };\n\n const msg = httpMessages[error.message] || error.message;\n Alert.presentAlert(`${prefix}: ${msg}`);\n}\n\nexport { createDOMFromHTMLString, getOffset, parseRgbString, prettyPrint, extractName, presentError }\n","/**\n * Created by dat on 4/4/17.\n */\nimport Ruler from './ruler.js'\nimport TrackPair, {setTrackReorderArrowColors} from './trackPair.js'\nimport TrackRenderer from './trackRenderer.js';\nimport {deleteBrowser, setCurrentBrowser} from './createBrowser.js'\nimport HICEvent from \"./hicEvent.js\";\nimport EventBus from \"./eventBus.js\";\nimport { createDOMFromHTMLString } from \"./utils.js\"\n\nclass LayoutController {\n\n constructor(browser, rootElement) {\n this.browser = browser;\n createNavBar(browser, rootElement);\n this.createAllContainers(browser, rootElement);\n }\n\n createAllContainers(browser, root) {\n const htmlXTrackContainer = createDOMFromHTMLString(`\n
\n
\n
\n
\n
\n
`);\n\n root.appendChild(htmlXTrackContainer);\n\n this.xTrackContainer = root.querySelector(`div[id$='x-track-container']`);\n this.trackShim = this.xTrackContainer.querySelector(`div[id$='track-shim']`);\n this.xTracks = this.xTrackContainer.querySelector(`div[id$='x-tracks']`);\n this.yTrackGuideElement = this.xTrackContainer.querySelector(`div[id$='y-track-guide']`);\n\n this.contentContainer = createDOMFromHTMLString(`
`);\n root.appendChild(this.contentContainer);\n\n const htmlXAxisContainer = createDOMFromHTMLString(`\n
\n
\n \n
\n
\n
`);\n\n this.contentContainer.appendChild(htmlXAxisContainer);\n const xAxisContainer = this.contentContainer.querySelector(`div[id$='x-axis-container']`);\n\n this.xAxisRuler = new Ruler(browser, xAxisContainer, 'x');\n\n const htmlYTracksYAxisViewportYScrollbar = createDOMFromHTMLString(`\n
\n
\n
\n
\n
\n \n
\n
\n
`);\n\n this.contentContainer.appendChild(htmlYTracksYAxisViewportYScrollbar);\n const yTracksYAxisViewportYScrollbar = this.contentContainer.querySelector(`div[id$='-y-tracks-y-axis-viewport-y-scrollbar']`);\n\n this.yTracks = yTracksYAxisViewportYScrollbar.querySelector(`div[id$='-y-tracks']`);\n this.xTrackGuideElement = this.yTracks.querySelector(`div[id$='-x-track-guide']`);\n\n this.yAxisRuler = new Ruler(browser, yTracksYAxisViewportYScrollbar, 'y');\n\n this.xAxisRuler.otherRulerCanvas = this.yAxisRuler.canvasElement;\n this.xAxisRuler.otherRuler = this.yAxisRuler;\n\n this.yAxisRuler.otherRulerCanvas = this.xAxisRuler.canvasElement;\n this.yAxisRuler.otherRuler = this.xAxisRuler;\n\n const htmlViewport = createDOMFromHTMLString(`\n
\n \n \n
\n
\n
\n
`);\n\n yTracksYAxisViewportYScrollbar.appendChild(htmlViewport);\n\n const htmlYAxisScrollbarContainer = createDOMFromHTMLString(`\n
\n
\n
\n
\n
`);\n\n yTracksYAxisViewportYScrollbar.appendChild(htmlYAxisScrollbarContainer);\n\n const htmlXAxisScrollbarContainer = createDOMFromHTMLString(`\n
\n
\n
\n
\n
\n
\n
`);\n\n this.contentContainer.appendChild(htmlXAxisScrollbarContainer);\n }\n\n getContactMatrixViewport() {\n const parent = this.contentContainer.querySelector(\"div[id$='-y-tracks-y-axis-viewport-y-scrollbar']\");\n return parent ? parent.querySelector(\"div[id$='-viewport']\") : null;\n }\n\n getYAxisScrollbarContainer() {\n const parent = this.contentContainer.querySelector(\"div[id$='-y-tracks-y-axis-viewport-y-scrollbar']\");\n return parent ? parent.querySelector(\"div[id$='-y-axis-scrollbar-container']\") : null;\n }\n\n getXAxisScrollbarContainer() {\n return this.contentContainer.querySelector(\"div[id$='-x-axis-scrollbar-container']\");\n }\n\n updateLayoutWithTracks(tracks) {\n\n const { trackHeight } = getLayoutDimensions()\n\n this.resizeLayoutWithTrackXYPairCount(tracks.length + this.browser.trackPairs.length)\n\n for (const track of tracks) {\n\n const trackPair = new TrackPair(this.browser, track)\n this.browser.trackPairs.unshift(trackPair)\n\n trackPair.x = new TrackRenderer(this.browser, track, 'x')\n trackPair.x.init(this.xTracks, trackHeight, this.browser.trackPairs.indexOf(trackPair))\n\n trackPair.y = new TrackRenderer(this.browser, track, 'y')\n trackPair.y.init(this.yTracks, trackHeight, this.browser.trackPairs.indexOf(trackPair))\n\n trackPair.init()\n\n EventBus.globalBus.post(HICEvent(\"TrackXYPairLoad\", trackPair))\n }\n\n for (const trackPair of this.browser.trackPairs) {\n const order = `${ this.browser.trackPairs.indexOf(trackPair) }`\n trackPair.x.viewportElement.style.order = order\n trackPair.y.viewportElement.style.order = order\n }\n\n setTrackReorderArrowColors(this.browser.trackPairs)\n\n }\n\n removeAllTrackXYPairs() {\n\n if (this.browser.trackPairs.length === 0 ) {\n return;\n }\n\n for(let trackPair of this.browser.trackPairs) {\n // discard DOM element's\n trackPair.dispose();\n }\n this.browser.trackPairs = []\n this.browser.updateLayout();\n this.resizeLayoutWithTrackXYPairCount(0)\n\n }\n\n removeTrackXYPair(trackXYPair) {\n\n if (this.browser.trackPairs.length > 0) {\n\n // remove DOM element\n trackXYPair.x.viewportElement.remove();\n trackXYPair.y.viewportElement.remove();\n\n // remove from trackPairs list\n const index = this.browser.trackPairs.indexOf(trackXYPair);\n this.browser.trackPairs.splice(index, 1);\n\n this.resizeLayoutWithTrackXYPairCount(this.browser.trackPairs.length);\n\n this.browser.updateLayout();\n\n EventBus.globalBus.post(HICEvent(\"TrackXYPairRemoval\", trackXYPair));\n }\n }\n\n resizeLayoutWithTrackXYPairCount(trackXYPairCount) {\n const { trackHeight, trackMargin, axisHeight, scrollbarHeight } = getLayoutDimensions();\n const trackAggregateHeight = (trackXYPairCount === 0) ? 0 : trackXYPairCount * (trackHeight + trackMargin);\n\n let tokens = [getNavbarHeight(), trackAggregateHeight].map(number => `${number}px`);\n const heightCalc = `calc(100% - (${tokens.join(' + ')}))`;\n\n tokens = [trackAggregateHeight, axisHeight, scrollbarHeight].map(number => `${number}px`);\n const widthCalc = `calc(100% - (${tokens.join(' + ')}))`;\n\n // x-track container\n this.xTrackContainer.style.height = `${trackAggregateHeight}px`;\n\n // track labels\n this.trackShim.style.width = `${trackAggregateHeight}px`;\n\n // x-tracks\n this.xTracks.style.width = widthCalc;\n\n // content container\n this.contentContainer.style.height = heightCalc;\n\n // x-axis - repaint canvas\n this.xAxisRuler.updateWidthWithCalculation(widthCalc);\n\n // y-tracks\n this.yTracks.style.width = `${trackAggregateHeight}px`;\n\n // y-axis - repaint canvas\n this.yAxisRuler.updateHeight(this.yAxisRuler.axisElement.offsetHeight);\n\n // viewport\n this.browser.contactMatrixView.viewportElement.style.width = widthCalc;\n\n // x-scrollbar\n this.browser.contactMatrixView.scrollbarWidget.xAxisScrollbarContainerElement.style.width = widthCalc;\n }\n\n}\n\nfunction getNavbarContainer(browser) {\n return browser.rootElement.querySelector('.hic-navbar-container');\n}\n\nfunction getNavbarHeight() {\n const { navBarLabelHeight, navBarWidgetContainerHeight, navBarWidgetContainerMargin } = getLayoutDimensions();\n return 2 * (navBarLabelHeight + navBarWidgetContainerHeight + (2 * navBarWidgetContainerMargin));\n}\n\nfunction getCSSVariable(name) {\n return parseInt(getComputedStyle(document.documentElement).getPropertyValue(name));\n}\n\nfunction setCSSVariable(name, value) {\n document.documentElement.style.setProperty(name, `${value}px`);\n}\n\nfunction getLayoutDimensions() {\n return {\n navBarLabelHeight: getCSSVariable('--nav-bar-label-height'),\n navBarWidgetContainerHeight: getCSSVariable('--nav-bar-widget-container-height'),\n navBarWidgetContainerMargin: getCSSVariable('--nav-bar-widget-container-margin'),\n scrollbarHeight: getCSSVariable('--hic-scrollbar-height'),\n axisHeight: getCSSVariable('--hic-axis-height'),\n trackMargin: getCSSVariable('--track-margin'),\n trackHeight: getCSSVariable('--track-height')\n };\n}\n\nfunction setViewportSize(width, height) {\n setCSSVariable('--hic-viewport-width', width);\n setCSSVariable('--hic-viewport-height', height);\n}\n\nfunction createNavBar(browser, root) {\n\n const hicNavbarContainer = document.createElement('div');\n hicNavbarContainer.className = 'hic-navbar-container';\n root.appendChild(hicNavbarContainer);\n\n hicNavbarContainer.addEventListener('click', e => {\n e.stopPropagation();\n e.preventDefault();\n setCurrentBrowser(browser);\n });\n\n const htmlContactMapHicNavBarMapContainer =\n `
\n
\n
\n \n \n
\n
`;\n\n hicNavbarContainer.appendChild(createDOMFromHTMLString(htmlContactMapHicNavBarMapContainer));\n\n browser.contactMapLabel = hicNavbarContainer.querySelector(`div[id$='contact-map-hic-nav-bar-map-label']`);\n browser.menuPresentDismiss = hicNavbarContainer.querySelector('.fa-bars');\n browser.menuPresentDismiss.addEventListener('click', e => browser.toggleMenu());\n\n browser.browserPanelDeleteButton = hicNavbarContainer.querySelector('.fa-minus-circle');\n browser.browserPanelDeleteButton.addEventListener('click', e => deleteBrowser(browser));\n\n // Delete button is only visible if there is more than one browser\n browser.browserPanelDeleteButton.style.display = 'none';\n\n const htmlControlMapHicNavBarMapContainer =\n `
\n
\n
`;\n\n hicNavbarContainer.appendChild(createDOMFromHTMLString(htmlControlMapHicNavBarMapContainer));\n\n browser.controlMapLabel = hicNavbarContainer.querySelector(`div[id$='control-map-hic-nav-bar-map-label']`);\n\n const htmlUpperHicNavBarWidgetContainer = `
`;\n hicNavbarContainer.appendChild(createDOMFromHTMLString(htmlUpperHicNavBarWidgetContainer));\n\n const htmlLowerHicNavBarWidgetContainer = `
`;\n hicNavbarContainer.appendChild(createDOMFromHTMLString(htmlLowerHicNavBarWidgetContainer));\n}\n\nexport {getNavbarHeight, getNavbarContainer, getLayoutDimensions, setViewportSize};\n\nexport default LayoutController;\n","/*\n * @author Jim Robinson Dec-2020\n */\n\nimport { StringUtils } from '../node_modules/igv-utils/src/index.js';\nimport HICBrowser from './hicBrowser.js';\nimport ColorScale from './colorScale.js';\nimport ContactMatrixView from \"./contactMatrixView.js\";\nimport HICEvent from \"./hicEvent.js\";\nimport EventBus from \"./eventBus.js\";\n\nconst defaultSize = { width: 640, height: 640 };\n\nlet allBrowsers = [];\nlet currentBrowser;\n\nasync function createBrowser(hicContainer, config, callback) {\n setDefaults(config);\n\n if (StringUtils.isString(config.colorScale)) config.colorScale = ColorScale.parse(config.colorScale);\n if (StringUtils.isString(config.backgroundColor)) config.backgroundColor = ContactMatrixView.parseBackgroundColor(config.backgroundColor);\n\n const browser = new HICBrowser(hicContainer, config);\n await browser.init(config);\n\n if (typeof callback === \"function\") callback();\n\n allBrowsers.push(browser);\n setCurrentBrowser(browser);\n\n if (allBrowsers.length > 1) {\n allBrowsers.forEach(b => b.browserPanelDeleteButton.style.display = 'block');\n }\n\n return browser;\n}\n\nasync function createBrowserList(hicContainer, session) {\n const configList = session.browsers || [session];\n allBrowsers = [];\n const initPromises = [];\n\n for (const config of configList) {\n\n setDefaults(config)\n\n if (StringUtils.isString(config.colorScale)) {\n config.colorScale = ColorScale.parse(config.colorScale);\n }\n if (StringUtils.isString(config.backgroundColor)) {\n config.backgroundColor = ContactMatrixView.parseBackgroundColor(config.backgroundColor);\n }\n if (session.syncDatasets === false) {\n config.synchable = false;\n }\n\n const browser = new HICBrowser(hicContainer, config);\n allBrowsers.push(browser);\n initPromises.push(browser.init(config));\n }\n await Promise.all(initPromises);\n setCurrentBrowser(allBrowsers[0]);\n\n if (allBrowsers.length > 1) {\n allBrowsers.forEach(b => b.browserPanelDeleteButton.style.display = 'block');\n }\n}\n\nasync function updateAllBrowsers() {\n for (let b of allBrowsers) {\n await b.update();\n }\n}\n\nfunction deleteAllBrowsers() {\n for (let b of allBrowsers) {\n b.rootElement.remove();\n }\n allBrowsers = [];\n}\n\nfunction setCurrentBrowser(browser) {\n if (browser === undefined) {\n currentBrowser?.rootElement.classList.remove('hic-root-selected');\n currentBrowser = browser;\n return;\n }\n\n if (browser !== currentBrowser) {\n currentBrowser?.rootElement.classList.remove('hic-root-selected');\n browser.rootElement.classList.add('hic-root-selected');\n currentBrowser = browser;\n EventBus.globalBus.post(HICEvent(\"BrowserSelect\", browser));\n }\n}\n\nfunction deleteBrowser(browser) {\n browser.unsyncSelf();\n browser.rootElement.remove();\n allBrowsers = allBrowsers.filter(b => b !== browser);\n if (allBrowsers.length <= 1) {\n allBrowsers.forEach(b => b.browserPanelDeleteButton.style.display = 'none');\n }\n}\n\nfunction getCurrentBrowser() {\n return currentBrowser;\n}\n\nfunction syncBrowsers(browsers) {\n const synchableBrowsers = (browsers || allBrowsers).filter(b => b.synchable !== false && b.dataset !== undefined);\n\n synchableBrowsers.forEach(b1 => {\n synchableBrowsers.forEach(b2 => {\n if (b1 !== b2 && b1.dataset.isCompatible(b2.dataset)) {\n b1.synchedBrowsers.add(b2);\n b2.synchedBrowsers.add(b1);\n }\n });\n });\n}\n\nfunction getAllBrowsers() {\n return allBrowsers;\n}\n\nfunction setDefaults(config) {\n\n if (config.figureMode === true) {\n config.showLocusGoto = false;\n config.showHicContactMapLabel = false;\n config.showChromosomeSelector = false;\n } else {\n\n\n config.showLocusGoto = config.showLocusGoto ?? true;\n config.showHicContactMapLabel = config.showHicContactMapLabel ?? true;\n config.showChromosomeSelector = config.showChromosomeSelector ?? true;\n }\n}\n\nexport {\n defaultSize,\n createBrowser,\n createBrowserList,\n deleteBrowser,\n setCurrentBrowser,\n getCurrentBrowser,\n syncBrowsers,\n deleteAllBrowsers,\n getAllBrowsers\n};\n","// from https://github.com/imaya/zlib.js\n\n/**\n * @fileoverview Zlib namespace. Zlib の仕様に準拠した圧縮は Zlib.Deflate で実装\n * されている. これは Inflate との共存を考慮している為.\n */\n\nvar USE_TYPEDARRAY = true;\n\nvar Zlib = {\n Huffman: {},\n Util: {},\n CRC32: {}\n};\n\n\n/**\n * Compression Method\n * @enum {number}\n */\nZlib.CompressionMethod = {\n DEFLATE: 8,\n RESERVED: 15\n};\n\n\n\n\n/**\n * @param {Object=} opt_params options.\n * @constructor\n */\nZlib.Zip = function(opt_params) {\n opt_params = opt_params || {};\n /** @type {Array.<{\n * buffer: !(Array.|Uint8Array),\n * option: Object,\n * compressed: boolean,\n * encrypted: boolean,\n * size: number,\n * crc32: number\n * }>} */\n this.files = [];\n /** @type {(Array.|Uint8Array)} */\n this.comment = opt_params['comment'];\n /** @type {(Array.|Uint8Array)} */\n this.password;\n};\n\n\n/**\n * @enum {number}\n */\nZlib.Zip.CompressionMethod = {\n STORE: 0,\n DEFLATE: 8\n};\n\n/**\n * @enum {number}\n */\nZlib.Zip.OperatingSystem = {\n MSDOS: 0,\n UNIX: 3,\n MACINTOSH: 7\n};\n\n/**\n * @enum {number}\n */\nZlib.Zip.Flags = {\n ENCRYPT: 0x0001,\n DESCRIPTOR: 0x0008,\n UTF8: 0x0800\n};\n\n/**\n * @type {Array.}\n * @const\n */\nZlib.Zip.FileHeaderSignature = [0x50, 0x4b, 0x01, 0x02];\n\n/**\n * @type {Array.}\n * @const\n */\nZlib.Zip.LocalFileHeaderSignature = [0x50, 0x4b, 0x03, 0x04];\n\n/**\n * @type {Array.}\n * @const\n */\nZlib.Zip.CentralDirectorySignature = [0x50, 0x4b, 0x05, 0x06];\n\n/**\n * @param {Array.|Uint8Array} input\n * @param {Object=} opt_params options.\n */\nZlib.Zip.prototype.addFile = function(input, opt_params) {\n opt_params = opt_params || {};\n /** @type {string} */\n var filename = '' || opt_params['filename'];\n /** @type {boolean} */\n var compressed;\n /** @type {number} */\n var size = input.length;\n /** @type {number} */\n var crc32 = 0;\n\n if (USE_TYPEDARRAY && input instanceof Array) {\n input = new Uint8Array(input);\n }\n\n // default\n if (typeof opt_params['compressionMethod'] !== 'number') {\n opt_params['compressionMethod'] = Zlib.Zip.CompressionMethod.DEFLATE;\n }\n\n // その場で圧縮する場合\n if (opt_params['compress']) {\n switch (opt_params['compressionMethod']) {\n case Zlib.Zip.CompressionMethod.STORE:\n break;\n case Zlib.Zip.CompressionMethod.DEFLATE:\n crc32 = Zlib.CRC32.calc(input);\n input = this.deflateWithOption(input, opt_params);\n compressed = true;\n break;\n default:\n throw new Error('unknown compression method:' + opt_params['compressionMethod']);\n }\n }\n\n this.files.push({\n buffer: input,\n option: opt_params,\n compressed: compressed,\n encrypted: false,\n size: size,\n crc32: crc32\n });\n};\n\n/**\n * @param {(Array.|Uint8Array)} password\n */\nZlib.Zip.prototype.setPassword = function(password) {\n this.password = password;\n};\n\nZlib.Zip.prototype.compress = function() {\n /** @type {Array.<{\n * buffer: !(Array.|Uint8Array),\n * option: Object,\n * compressed: boolean,\n * encrypted: boolean,\n * size: number,\n * crc32: number\n * }>} */\n var files = this.files;\n /** @type {{\n * buffer: !(Array.|Uint8Array),\n * option: Object,\n * compressed: boolean,\n * encrypted: boolean,\n * size: number,\n * crc32: number\n * }} */\n var file;\n /** @type {!(Array.|Uint8Array)} */\n var output;\n /** @type {number} */\n var op1;\n /** @type {number} */\n var op2;\n /** @type {number} */\n var op3;\n /** @type {number} */\n var localFileSize = 0;\n /** @type {number} */\n var centralDirectorySize = 0;\n /** @type {number} */\n var endOfCentralDirectorySize;\n /** @type {number} */\n var offset;\n /** @type {number} */\n var needVersion;\n /** @type {number} */\n var flags;\n /** @type {Zlib.Zip.CompressionMethod} */\n var compressionMethod;\n /** @type {Date} */\n var date;\n /** @type {number} */\n var crc32;\n /** @type {number} */\n var size;\n /** @type {number} */\n var plainSize;\n /** @type {number} */\n var filenameLength;\n /** @type {number} */\n var extraFieldLength;\n /** @type {number} */\n var commentLength;\n /** @type {(Array.|Uint8Array)} */\n var filename;\n /** @type {(Array.|Uint8Array)} */\n var extraField;\n /** @type {(Array.|Uint8Array)} */\n var comment;\n /** @type {(Array.|Uint8Array)} */\n var buffer;\n /** @type {*} */\n var tmp;\n /** @type {Array.|Uint32Array|Object} */\n var key;\n /** @type {number} */\n var i;\n /** @type {number} */\n var il;\n /** @type {number} */\n var j;\n /** @type {number} */\n var jl;\n\n // ファイルの圧縮\n for (i = 0, il = files.length; i < il; ++i) {\n file = files[i];\n filenameLength =\n (file.option['filename']) ? file.option['filename'].length : 0;\n extraFieldLength =\n (file.option['extraField']) ? file.option['extraField'].length : 0;\n commentLength =\n (file.option['comment']) ? file.option['comment'].length : 0;\n\n // 圧縮されていなかったら圧縮\n if (!file.compressed) {\n // 圧縮前に CRC32 の計算をしておく\n file.crc32 = Zlib.CRC32.calc(file.buffer);\n\n switch (file.option['compressionMethod']) {\n case Zlib.Zip.CompressionMethod.STORE:\n break;\n case Zlib.Zip.CompressionMethod.DEFLATE:\n file.buffer = this.deflateWithOption(file.buffer, file.option);\n file.compressed = true;\n break;\n default:\n throw new Error('unknown compression method:' + file.option['compressionMethod']);\n }\n }\n\n // encryption\n if (file.option['password'] !== void 0|| this.password !== void 0) {\n // init encryption\n key = this.createEncryptionKey(file.option['password'] || this.password);\n\n // add header\n buffer = file.buffer;\n if (USE_TYPEDARRAY) {\n tmp = new Uint8Array(buffer.length + 12);\n tmp.set(buffer, 12);\n buffer = tmp;\n } else {\n buffer.unshift(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);\n }\n\n for (j = 0; j < 12; ++j) {\n buffer[j] = this.encode(\n key,\n i === 11 ? (file.crc32 & 0xff) : (Math.random() * 256 | 0)\n );\n }\n\n // data encryption\n for (jl = buffer.length; j < jl; ++j) {\n buffer[j] = this.encode(key, buffer[j]);\n }\n file.buffer = buffer;\n }\n\n // 必要バッファサイズの計算\n localFileSize +=\n // local file header\n 30 + filenameLength +\n // file data\n file.buffer.length;\n\n centralDirectorySize +=\n // file header\n 46 + filenameLength + commentLength;\n }\n\n // end of central directory\n endOfCentralDirectorySize = 22 + (this.comment ? this.comment.length : 0);\n output = new (USE_TYPEDARRAY ? Uint8Array : Array)(\n localFileSize + centralDirectorySize + endOfCentralDirectorySize\n );\n op1 = 0;\n op2 = localFileSize;\n op3 = op2 + centralDirectorySize;\n\n // ファイルの圧縮\n for (i = 0, il = files.length; i < il; ++i) {\n file = files[i];\n filenameLength =\n file.option['filename'] ? file.option['filename'].length : 0;\n extraFieldLength = 0; // TODO\n commentLength =\n file.option['comment'] ? file.option['comment'].length : 0;\n\n //-------------------------------------------------------------------------\n // local file header & file header\n //-------------------------------------------------------------------------\n\n offset = op1;\n\n // signature\n // local file header\n output[op1++] = Zlib.Zip.LocalFileHeaderSignature[0];\n output[op1++] = Zlib.Zip.LocalFileHeaderSignature[1];\n output[op1++] = Zlib.Zip.LocalFileHeaderSignature[2];\n output[op1++] = Zlib.Zip.LocalFileHeaderSignature[3];\n // file header\n output[op2++] = Zlib.Zip.FileHeaderSignature[0];\n output[op2++] = Zlib.Zip.FileHeaderSignature[1];\n output[op2++] = Zlib.Zip.FileHeaderSignature[2];\n output[op2++] = Zlib.Zip.FileHeaderSignature[3];\n\n // compressor info\n needVersion = 20;\n output[op2++] = needVersion & 0xff;\n output[op2++] =\n /** @type {Zlib.Zip.OperatingSystem} */\n (file.option['os']) ||\n Zlib.Zip.OperatingSystem.MSDOS;\n\n // need version\n output[op1++] = output[op2++] = needVersion & 0xff;\n output[op1++] = output[op2++] = (needVersion >> 8) & 0xff;\n\n // general purpose bit flag\n flags = 0;\n if (file.option['password'] || this.password) {\n flags |= Zlib.Zip.Flags.ENCRYPT;\n }\n output[op1++] = output[op2++] = flags & 0xff;\n output[op1++] = output[op2++] = (flags >> 8) & 0xff;\n\n // compression method\n compressionMethod =\n /** @type {Zlib.Zip.CompressionMethod} */\n (file.option['compressionMethod']);\n output[op1++] = output[op2++] = compressionMethod & 0xff;\n output[op1++] = output[op2++] = (compressionMethod >> 8) & 0xff;\n\n // date\n date = /** @type {(Date|undefined)} */(file.option['date']) || new Date();\n output[op1++] = output[op2++] =\n ((date.getMinutes() & 0x7) << 5) |\n (date.getSeconds() / 2 | 0);\n output[op1++] = output[op2++] =\n (date.getHours() << 3) |\n (date.getMinutes() >> 3);\n //\n output[op1++] = output[op2++] =\n ((date.getMonth() + 1 & 0x7) << 5) |\n (date.getDate());\n output[op1++] = output[op2++] =\n ((date.getFullYear() - 1980 & 0x7f) << 1) |\n (date.getMonth() + 1 >> 3);\n\n // CRC-32\n crc32 = file.crc32;\n output[op1++] = output[op2++] = crc32 & 0xff;\n output[op1++] = output[op2++] = (crc32 >> 8) & 0xff;\n output[op1++] = output[op2++] = (crc32 >> 16) & 0xff;\n output[op1++] = output[op2++] = (crc32 >> 24) & 0xff;\n\n // compressed size\n size = file.buffer.length;\n output[op1++] = output[op2++] = size & 0xff;\n output[op1++] = output[op2++] = (size >> 8) & 0xff;\n output[op1++] = output[op2++] = (size >> 16) & 0xff;\n output[op1++] = output[op2++] = (size >> 24) & 0xff;\n\n // uncompressed size\n plainSize = file.size;\n output[op1++] = output[op2++] = plainSize & 0xff;\n output[op1++] = output[op2++] = (plainSize >> 8) & 0xff;\n output[op1++] = output[op2++] = (plainSize >> 16) & 0xff;\n output[op1++] = output[op2++] = (plainSize >> 24) & 0xff;\n\n // filename length\n output[op1++] = output[op2++] = filenameLength & 0xff;\n output[op1++] = output[op2++] = (filenameLength >> 8) & 0xff;\n\n // extra field length\n output[op1++] = output[op2++] = extraFieldLength & 0xff;\n output[op1++] = output[op2++] = (extraFieldLength >> 8) & 0xff;\n\n // file comment length\n output[op2++] = commentLength & 0xff;\n output[op2++] = (commentLength >> 8) & 0xff;\n\n // disk number start\n output[op2++] = 0;\n output[op2++] = 0;\n\n // internal file attributes\n output[op2++] = 0;\n output[op2++] = 0;\n\n // external file attributes\n output[op2++] = 0;\n output[op2++] = 0;\n output[op2++] = 0;\n output[op2++] = 0;\n\n // relative offset of local header\n output[op2++] = offset & 0xff;\n output[op2++] = (offset >> 8) & 0xff;\n output[op2++] = (offset >> 16) & 0xff;\n output[op2++] = (offset >> 24) & 0xff;\n\n // filename\n filename = file.option['filename'];\n if (filename) {\n if (USE_TYPEDARRAY) {\n output.set(filename, op1);\n output.set(filename, op2);\n op1 += filenameLength;\n op2 += filenameLength;\n } else {\n for (j = 0; j < filenameLength; ++j) {\n output[op1++] = output[op2++] = filename[j];\n }\n }\n }\n\n // extra field\n extraField = file.option['extraField'];\n if (extraField) {\n if (USE_TYPEDARRAY) {\n output.set(extraField, op1);\n output.set(extraField, op2);\n op1 += extraFieldLength;\n op2 += extraFieldLength;\n } else {\n for (j = 0; j < commentLength; ++j) {\n output[op1++] = output[op2++] = extraField[j];\n }\n }\n }\n\n // comment\n comment = file.option['comment'];\n if (comment) {\n if (USE_TYPEDARRAY) {\n output.set(comment, op2);\n op2 += commentLength;\n } else {\n for (j = 0; j < commentLength; ++j) {\n output[op2++] = comment[j];\n }\n }\n }\n\n //-------------------------------------------------------------------------\n // file data\n //-------------------------------------------------------------------------\n\n if (USE_TYPEDARRAY) {\n output.set(file.buffer, op1);\n op1 += file.buffer.length;\n } else {\n for (j = 0, jl = file.buffer.length; j < jl; ++j) {\n output[op1++] = file.buffer[j];\n }\n }\n }\n\n //-------------------------------------------------------------------------\n // end of central directory\n //-------------------------------------------------------------------------\n\n // signature\n output[op3++] = Zlib.Zip.CentralDirectorySignature[0];\n output[op3++] = Zlib.Zip.CentralDirectorySignature[1];\n output[op3++] = Zlib.Zip.CentralDirectorySignature[2];\n output[op3++] = Zlib.Zip.CentralDirectorySignature[3];\n\n // number of this disk\n output[op3++] = 0;\n output[op3++] = 0;\n\n // number of the disk with the start of the central directory\n output[op3++] = 0;\n output[op3++] = 0;\n\n // total number of entries in the central directory on this disk\n output[op3++] = il & 0xff;\n output[op3++] = (il >> 8) & 0xff;\n\n // total number of entries in the central directory\n output[op3++] = il & 0xff;\n output[op3++] = (il >> 8) & 0xff;\n\n // size of the central directory\n output[op3++] = centralDirectorySize & 0xff;\n output[op3++] = (centralDirectorySize >> 8) & 0xff;\n output[op3++] = (centralDirectorySize >> 16) & 0xff;\n output[op3++] = (centralDirectorySize >> 24) & 0xff;\n\n // offset of start of central directory with respect to the starting disk number\n output[op3++] = localFileSize & 0xff;\n output[op3++] = (localFileSize >> 8) & 0xff;\n output[op3++] = (localFileSize >> 16) & 0xff;\n output[op3++] = (localFileSize >> 24) & 0xff;\n\n // .ZIP file comment length\n commentLength = this.comment ? this.comment.length : 0;\n output[op3++] = commentLength & 0xff;\n output[op3++] = (commentLength >> 8) & 0xff;\n\n // .ZIP file comment\n if (this.comment) {\n if (USE_TYPEDARRAY) {\n output.set(this.comment, op3);\n op3 += commentLength;\n } else {\n for (j = 0, jl = commentLength; j < jl; ++j) {\n output[op3++] = this.comment[j];\n }\n }\n }\n\n return output;\n};\n\n/**\n * @param {!(Array.|Uint8Array)} input\n * @param {Object=} opt_params options.\n * @return {!(Array.|Uint8Array)}\n */\nZlib.Zip.prototype.deflateWithOption = function(input, opt_params) {\n /** @type {Zlib.RawDeflate} */\n var deflator = new Zlib.RawDeflate(input, opt_params['deflateOption']);\n\n return deflator.compress();\n};\n\n/**\n * @param {(Array.|Uint32Array)} key\n * @return {number}\n */\nZlib.Zip.prototype.getByte = function(key) {\n /** @type {number} */\n var tmp = ((key[2] & 0xffff) | 2);\n\n return ((tmp * (tmp ^ 1)) >> 8) & 0xff;\n};\n\n/**\n * @param {(Array.|Uint32Array|Object)} key\n * @param {number} n\n * @return {number}\n */\nZlib.Zip.prototype.encode = function(key, n) {\n /** @type {number} */\n var tmp = this.getByte(/** @type {(Array.|Uint32Array)} */(key));\n\n this.updateKeys(/** @type {(Array.|Uint32Array)} */(key), n);\n\n return tmp ^ n;\n};\n\n/**\n * @param {(Array.|Uint32Array)} key\n * @param {number} n\n */\nZlib.Zip.prototype.updateKeys = function(key, n) {\n key[0] = Zlib.CRC32.single(key[0], n);\n key[1] =\n (((((key[1] + (key[0] & 0xff)) * 20173 >>> 0) * 6681) >>> 0) + 1) >>> 0;\n key[2] = Zlib.CRC32.single(key[2], key[1] >>> 24);\n};\n\n/**\n * @param {(Array.|Uint8Array)} password\n * @return {!(Array.|Uint32Array|Object)}\n */\nZlib.Zip.prototype.createEncryptionKey = function(password) {\n /** @type {!(Array.|Uint32Array)} */\n var key = [305419896, 591751049, 878082192];\n /** @type {number} */\n var i;\n /** @type {number} */\n var il;\n\n if (USE_TYPEDARRAY) {\n key = new Uint32Array(key);\n }\n\n for (i = 0, il = password.length; i < il; ++i) {\n this.updateKeys(key, password[i] & 0xff);\n }\n\n return key;\n};\n\n\n\n/**\n * build huffman table from length list.\n * @param {!(Array.|Uint8Array)} lengths length list.\n * @return {!Array} huffman table.\n */\nZlib.Huffman.buildHuffmanTable = function(lengths) {\n /** @type {number} length list size. */\n var listSize = lengths.length;\n /** @type {number} max code length for table size. */\n var maxCodeLength = 0;\n /** @type {number} min code length for table size. */\n var minCodeLength = Number.POSITIVE_INFINITY;\n /** @type {number} table size. */\n var size;\n /** @type {!(Array|Uint8Array)} huffman code table. */\n var table;\n /** @type {number} bit length. */\n var bitLength;\n /** @type {number} huffman code. */\n var code;\n /**\n * サイズが 2^maxlength 個のテーブルを埋めるためのスキップ長.\n * @type {number} skip length for table filling.\n */\n var skip;\n /** @type {number} reversed code. */\n var reversed;\n /** @type {number} reverse temp. */\n var rtemp;\n /** @type {number} loop counter. */\n var i;\n /** @type {number} loop limit. */\n var il;\n /** @type {number} loop counter. */\n var j;\n /** @type {number} table value. */\n var value;\n\n // Math.max は遅いので最長の値は for-loop で取得する\n for (i = 0, il = listSize; i < il; ++i) {\n if (lengths[i] > maxCodeLength) {\n maxCodeLength = lengths[i];\n }\n if (lengths[i] < minCodeLength) {\n minCodeLength = lengths[i];\n }\n }\n\n size = 1 << maxCodeLength;\n table = new (USE_TYPEDARRAY ? Uint32Array : Array)(size);\n\n // ビット長の短い順からハフマン符号を割り当てる\n for (bitLength = 1, code = 0, skip = 2; bitLength <= maxCodeLength;) {\n for (i = 0; i < listSize; ++i) {\n if (lengths[i] === bitLength) {\n // ビットオーダーが逆になるためビット長分並びを反転する\n for (reversed = 0, rtemp = code, j = 0; j < bitLength; ++j) {\n reversed = (reversed << 1) | (rtemp & 1);\n rtemp >>= 1;\n }\n\n // 最大ビット長をもとにテーブルを作るため、\n // 最大ビット長以外では 0 / 1 どちらでも良い箇所ができる\n // そのどちらでも良い場所は同じ値で埋めることで\n // 本来のビット長以上のビット数取得しても問題が起こらないようにする\n value = (bitLength << 16) | i;\n for (j = reversed; j < size; j += skip) {\n table[j] = value;\n }\n\n ++code;\n }\n }\n\n // 次のビット長へ\n ++bitLength;\n code <<= 1;\n skip <<= 1;\n }\n\n return [table, maxCodeLength, minCodeLength];\n};\n\n\n\n\n//-----------------------------------------------------------------------------\n\n/** @define {number} buffer block size. */\nvar ZLIB_RAW_INFLATE_BUFFER_SIZE = 0x8000; // [ 0x8000 >= ZLIB_BUFFER_BLOCK_SIZE ]\n\n//-----------------------------------------------------------------------------\n\n\nvar buildHuffmanTable = Zlib.Huffman.buildHuffmanTable;\n\n/**\n * @constructor\n * @param {!(Uint8Array|Array.)} input input buffer.\n * @param {Object} opt_params option parameter.\n *\n * opt_params は以下のプロパティを指定する事ができます。\n * - index: input buffer の deflate コンテナの開始位置.\n * - blockSize: バッファのブロックサイズ.\n * - bufferType: Zlib.RawInflate.BufferType の値によってバッファの管理方法を指定する.\n * - resize: 確保したバッファが実際の大きさより大きかった場合に切り詰める.\n */\nZlib.RawInflate = function(input, opt_params) {\n /** @type {!(Array.|Uint8Array)} inflated buffer */\n this.buffer;\n /** @type {!Array.<(Array.|Uint8Array)>} */\n this.blocks = [];\n /** @type {number} block size. */\n this.bufferSize = ZLIB_RAW_INFLATE_BUFFER_SIZE;\n /** @type {!number} total output buffer pointer. */\n this.totalpos = 0;\n /** @type {!number} input buffer pointer. */\n this.ip = 0;\n /** @type {!number} bit stream reader buffer. */\n this.bitsbuf = 0;\n /** @type {!number} bit stream reader buffer size. */\n this.bitsbuflen = 0;\n /** @type {!(Array.|Uint8Array)} input buffer. */\n this.input = USE_TYPEDARRAY ? new Uint8Array(input) : input;\n /** @type {!(Uint8Array|Array.)} output buffer. */\n this.output;\n /** @type {!number} output buffer pointer. */\n this.op;\n /** @type {boolean} is final block flag. */\n this.bfinal = false;\n /** @type {Zlib.RawInflate.BufferType} buffer management. */\n this.bufferType = Zlib.RawInflate.BufferType.ADAPTIVE;\n /** @type {boolean} resize flag for memory size optimization. */\n this.resize = false;\n\n // option parameters\n if (opt_params || !(opt_params = {})) {\n if (opt_params['index']) {\n this.ip = opt_params['index'];\n }\n if (opt_params['bufferSize']) {\n this.bufferSize = opt_params['bufferSize'];\n }\n if (opt_params['bufferType']) {\n this.bufferType = opt_params['bufferType'];\n }\n if (opt_params['resize']) {\n this.resize = opt_params['resize'];\n }\n }\n\n // initialize\n switch (this.bufferType) {\n case Zlib.RawInflate.BufferType.BLOCK:\n this.op = Zlib.RawInflate.MaxBackwardLength;\n this.output =\n new (USE_TYPEDARRAY ? Uint8Array : Array)(\n Zlib.RawInflate.MaxBackwardLength +\n this.bufferSize +\n Zlib.RawInflate.MaxCopyLength\n );\n break;\n case Zlib.RawInflate.BufferType.ADAPTIVE:\n this.op = 0;\n this.output = new (USE_TYPEDARRAY ? Uint8Array : Array)(this.bufferSize);\n break;\n default:\n throw new Error('invalid inflate mode');\n }\n};\n\n/**\n * @enum {number}\n */\nZlib.RawInflate.BufferType = {\n BLOCK: 0,\n ADAPTIVE: 1\n};\n\n/**\n * decompress.\n * @return {!(Uint8Array|Array.)} inflated buffer.\n */\nZlib.RawInflate.prototype.decompress = function() {\n while (!this.bfinal) {\n this.parseBlock();\n }\n\n switch (this.bufferType) {\n case Zlib.RawInflate.BufferType.BLOCK:\n return this.concatBufferBlock();\n case Zlib.RawInflate.BufferType.ADAPTIVE:\n return this.concatBufferDynamic();\n default:\n throw new Error('invalid inflate mode');\n }\n};\n\n/**\n * @const\n * @type {number} max backward length for LZ77.\n */\nZlib.RawInflate.MaxBackwardLength = 32768;\n\n/**\n * @const\n * @type {number} max copy length for LZ77.\n */\nZlib.RawInflate.MaxCopyLength = 258;\n\n/**\n * huffman order\n * @const\n * @type {!(Array.|Uint8Array)}\n */\nZlib.RawInflate.Order = (function(table) {\n return USE_TYPEDARRAY ? new Uint16Array(table) : table;\n})([16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15]);\n\n/**\n * huffman length code table.\n * @const\n * @type {!(Array.|Uint16Array)}\n */\nZlib.RawInflate.LengthCodeTable = (function(table) {\n return USE_TYPEDARRAY ? new Uint16Array(table) : table;\n})([\n 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b,\n 0x000d, 0x000f, 0x0011, 0x0013, 0x0017, 0x001b, 0x001f, 0x0023, 0x002b,\n 0x0033, 0x003b, 0x0043, 0x0053, 0x0063, 0x0073, 0x0083, 0x00a3, 0x00c3,\n 0x00e3, 0x0102, 0x0102, 0x0102\n]);\n\n/**\n * huffman length extra-bits table.\n * @const\n * @type {!(Array.|Uint8Array)}\n */\nZlib.RawInflate.LengthExtraTable = (function(table) {\n return USE_TYPEDARRAY ? new Uint8Array(table) : table;\n})([\n 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5,\n 5, 5, 0, 0, 0\n]);\n\n/**\n * huffman dist code table.\n * @const\n * @type {!(Array.|Uint16Array)}\n */\nZlib.RawInflate.DistCodeTable = (function(table) {\n return USE_TYPEDARRAY ? new Uint16Array(table) : table;\n})([\n 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0007, 0x0009, 0x000d, 0x0011,\n 0x0019, 0x0021, 0x0031, 0x0041, 0x0061, 0x0081, 0x00c1, 0x0101, 0x0181,\n 0x0201, 0x0301, 0x0401, 0x0601, 0x0801, 0x0c01, 0x1001, 0x1801, 0x2001,\n 0x3001, 0x4001, 0x6001\n]);\n\n/**\n * huffman dist extra-bits table.\n * @const\n * @type {!(Array.|Uint8Array)}\n */\nZlib.RawInflate.DistExtraTable = (function(table) {\n return USE_TYPEDARRAY ? new Uint8Array(table) : table;\n})([\n 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11,\n 11, 12, 12, 13, 13\n]);\n\n/**\n * fixed huffman length code table\n * @const\n * @type {!Array}\n */\nZlib.RawInflate.FixedLiteralLengthTable = (function(table) {\n return table;\n})((function() {\n var lengths = new (USE_TYPEDARRAY ? Uint8Array : Array)(288);\n var i, il;\n\n for (i = 0, il = lengths.length; i < il; ++i) {\n lengths[i] =\n (i <= 143) ? 8 :\n (i <= 255) ? 9 :\n (i <= 279) ? 7 :\n 8;\n }\n\n return buildHuffmanTable(lengths);\n})());\n\n/**\n * fixed huffman distance code table\n * @const\n * @type {!Array}\n */\nZlib.RawInflate.FixedDistanceTable = (function(table) {\n return table;\n})((function() {\n var lengths = new (USE_TYPEDARRAY ? Uint8Array : Array)(30);\n var i, il;\n\n for (i = 0, il = lengths.length; i < il; ++i) {\n lengths[i] = 5;\n }\n\n return buildHuffmanTable(lengths);\n})());\n\n/**\n * parse deflated block.\n */\nZlib.RawInflate.prototype.parseBlock = function() {\n /** @type {number} header */\n var hdr = this.readBits(3);\n\n // BFINAL\n if (hdr & 0x1) {\n this.bfinal = true;\n }\n\n // BTYPE\n hdr >>>= 1;\n switch (hdr) {\n // uncompressed\n case 0:\n this.parseUncompressedBlock();\n break;\n // fixed huffman\n case 1:\n this.parseFixedHuffmanBlock();\n break;\n // dynamic huffman\n case 2:\n this.parseDynamicHuffmanBlock();\n break;\n // reserved or other\n default:\n throw new Error('unknown BTYPE: ' + hdr);\n }\n};\n\n/**\n * read inflate bits\n * @param {number} length bits length.\n * @return {number} read bits.\n */\nZlib.RawInflate.prototype.readBits = function(length) {\n var bitsbuf = this.bitsbuf;\n var bitsbuflen = this.bitsbuflen;\n var input = this.input;\n var ip = this.ip;\n\n /** @type {number} */\n var inputLength = input.length;\n /** @type {number} input and output byte. */\n var octet;\n\n // input byte\n if (ip + ((length - bitsbuflen + 7) >> 3) >= inputLength) {\n throw new Error('input buffer is broken');\n }\n\n // not enough buffer\n while (bitsbuflen < length) {\n bitsbuf |= input[ip++] << bitsbuflen;\n bitsbuflen += 8;\n }\n\n // output byte\n octet = bitsbuf & /* MASK */ ((1 << length) - 1);\n bitsbuf >>>= length;\n bitsbuflen -= length;\n\n this.bitsbuf = bitsbuf;\n this.bitsbuflen = bitsbuflen;\n this.ip = ip;\n\n return octet;\n};\n\n/**\n * read huffman code using table\n * @param {!(Array.|Uint8Array|Uint16Array)} table huffman code table.\n * @return {number} huffman code.\n */\nZlib.RawInflate.prototype.readCodeByTable = function(table) {\n var bitsbuf = this.bitsbuf;\n var bitsbuflen = this.bitsbuflen;\n var input = this.input;\n var ip = this.ip;\n\n /** @type {number} */\n var inputLength = input.length;\n /** @type {!(Array.|Uint8Array)} huffman code table */\n var codeTable = table[0];\n /** @type {number} */\n var maxCodeLength = table[1];\n /** @type {number} code length & code (16bit, 16bit) */\n var codeWithLength;\n /** @type {number} code bits length */\n var codeLength;\n\n // not enough buffer\n while (bitsbuflen < maxCodeLength) {\n if (ip >= inputLength) {\n break;\n }\n bitsbuf |= input[ip++] << bitsbuflen;\n bitsbuflen += 8;\n }\n\n // read max length\n codeWithLength = codeTable[bitsbuf & ((1 << maxCodeLength) - 1)];\n codeLength = codeWithLength >>> 16;\n\n if (codeLength > bitsbuflen) {\n throw new Error('invalid code length: ' + codeLength);\n }\n\n this.bitsbuf = bitsbuf >> codeLength;\n this.bitsbuflen = bitsbuflen - codeLength;\n this.ip = ip;\n\n return codeWithLength & 0xffff;\n};\n\n/**\n * parse uncompressed block.\n */\nZlib.RawInflate.prototype.parseUncompressedBlock = function() {\n var input = this.input;\n var ip = this.ip;\n var output = this.output;\n var op = this.op;\n\n /** @type {number} */\n var inputLength = input.length;\n /** @type {number} block length */\n var len;\n /** @type {number} number for check block length */\n var nlen;\n /** @type {number} output buffer length */\n var olength = output.length;\n /** @type {number} copy counter */\n var preCopy;\n\n // skip buffered header bits\n this.bitsbuf = 0;\n this.bitsbuflen = 0;\n\n // len\n if (ip + 1 >= inputLength) {\n throw new Error('invalid uncompressed block header: LEN');\n }\n len = input[ip++] | (input[ip++] << 8);\n\n // nlen\n if (ip + 1 >= inputLength) {\n throw new Error('invalid uncompressed block header: NLEN');\n }\n nlen = input[ip++] | (input[ip++] << 8);\n\n // check len & nlen\n if (len === ~nlen) {\n throw new Error('invalid uncompressed block header: length verify');\n }\n\n // check size\n if (ip + len > input.length) { throw new Error('input buffer is broken'); }\n\n // expand buffer\n switch (this.bufferType) {\n case Zlib.RawInflate.BufferType.BLOCK:\n // pre copy\n while (op + len > output.length) {\n preCopy = olength - op;\n len -= preCopy;\n if (USE_TYPEDARRAY) {\n output.set(input.subarray(ip, ip + preCopy), op);\n op += preCopy;\n ip += preCopy;\n } else {\n while (preCopy--) {\n output[op++] = input[ip++];\n }\n }\n this.op = op;\n output = this.expandBufferBlock();\n op = this.op;\n }\n break;\n case Zlib.RawInflate.BufferType.ADAPTIVE:\n while (op + len > output.length) {\n output = this.expandBufferAdaptive({fixRatio: 2});\n }\n break;\n default:\n throw new Error('invalid inflate mode');\n }\n\n // copy\n if (USE_TYPEDARRAY) {\n output.set(input.subarray(ip, ip + len), op);\n op += len;\n ip += len;\n } else {\n while (len--) {\n output[op++] = input[ip++];\n }\n }\n\n this.ip = ip;\n this.op = op;\n this.output = output;\n};\n\n/**\n * parse fixed huffman block.\n */\nZlib.RawInflate.prototype.parseFixedHuffmanBlock = function() {\n switch (this.bufferType) {\n case Zlib.RawInflate.BufferType.ADAPTIVE:\n this.decodeHuffmanAdaptive(\n Zlib.RawInflate.FixedLiteralLengthTable,\n Zlib.RawInflate.FixedDistanceTable\n );\n break;\n case Zlib.RawInflate.BufferType.BLOCK:\n this.decodeHuffmanBlock(\n Zlib.RawInflate.FixedLiteralLengthTable,\n Zlib.RawInflate.FixedDistanceTable\n );\n break;\n default:\n throw new Error('invalid inflate mode');\n }\n};\n\n/**\n * parse dynamic huffman block.\n */\nZlib.RawInflate.prototype.parseDynamicHuffmanBlock = function() {\n /** @type {number} number of literal and length codes. */\n var hlit = this.readBits(5) + 257;\n /** @type {number} number of distance codes. */\n var hdist = this.readBits(5) + 1;\n /** @type {number} number of code lengths. */\n var hclen = this.readBits(4) + 4;\n /** @type {!(Uint8Array|Array.)} code lengths. */\n var codeLengths =\n new (USE_TYPEDARRAY ? Uint8Array : Array)(Zlib.RawInflate.Order.length);\n /** @type {!Array} code lengths table. */\n var codeLengthsTable;\n /** @type {!(Uint8Array|Array.)} literal and length code table. */\n var litlenTable;\n /** @type {!(Uint8Array|Array.)} distance code table. */\n var distTable;\n /** @type {!(Uint8Array|Array.)} code length table. */\n var lengthTable;\n /** @type {number} */\n var code;\n /** @type {number} */\n var prev;\n /** @type {number} */\n var repeat;\n /** @type {number} loop counter. */\n var i;\n /** @type {number} loop limit. */\n var il;\n\n // decode code lengths\n for (i = 0; i < hclen; ++i) {\n codeLengths[Zlib.RawInflate.Order[i]] = this.readBits(3);\n }\n if (!USE_TYPEDARRAY) {\n for (i = hclen, hclen = codeLengths.length; i < hclen; ++i) {\n codeLengths[Zlib.RawInflate.Order[i]] = 0;\n }\n }\n\n // decode length table\n codeLengthsTable = buildHuffmanTable(codeLengths);\n lengthTable = new (USE_TYPEDARRAY ? Uint8Array : Array)(hlit + hdist);\n for (i = 0, il = hlit + hdist; i < il;) {\n code = this.readCodeByTable(codeLengthsTable);\n switch (code) {\n case 16:\n repeat = 3 + this.readBits(2);\n while (repeat--) { lengthTable[i++] = prev; }\n break;\n case 17:\n repeat = 3 + this.readBits(3);\n while (repeat--) { lengthTable[i++] = 0; }\n prev = 0;\n break;\n case 18:\n repeat = 11 + this.readBits(7);\n while (repeat--) { lengthTable[i++] = 0; }\n prev = 0;\n break;\n default:\n lengthTable[i++] = code;\n prev = code;\n break;\n }\n }\n\n litlenTable = USE_TYPEDARRAY\n ? buildHuffmanTable(lengthTable.subarray(0, hlit))\n : buildHuffmanTable(lengthTable.slice(0, hlit));\n distTable = USE_TYPEDARRAY\n ? buildHuffmanTable(lengthTable.subarray(hlit))\n : buildHuffmanTable(lengthTable.slice(hlit));\n\n switch (this.bufferType) {\n case Zlib.RawInflate.BufferType.ADAPTIVE:\n this.decodeHuffmanAdaptive(litlenTable, distTable);\n break;\n case Zlib.RawInflate.BufferType.BLOCK:\n this.decodeHuffmanBlock(litlenTable, distTable);\n break;\n default:\n throw new Error('invalid inflate mode');\n }\n};\n\n/**\n * decode huffman code\n * @param {!(Array.|Uint16Array)} litlen literal and length code table.\n * @param {!(Array.|Uint8Array)} dist distination code table.\n */\nZlib.RawInflate.prototype.decodeHuffmanBlock = function(litlen, dist) {\n var output = this.output;\n var op = this.op;\n\n this.currentLitlenTable = litlen;\n\n /** @type {number} output position limit. */\n var olength = output.length - Zlib.RawInflate.MaxCopyLength;\n /** @type {number} huffman code. */\n var code;\n /** @type {number} table index. */\n var ti;\n /** @type {number} huffman code distination. */\n var codeDist;\n /** @type {number} huffman code length. */\n var codeLength;\n\n var lengthCodeTable = Zlib.RawInflate.LengthCodeTable;\n var lengthExtraTable = Zlib.RawInflate.LengthExtraTable;\n var distCodeTable = Zlib.RawInflate.DistCodeTable;\n var distExtraTable = Zlib.RawInflate.DistExtraTable;\n\n while ((code = this.readCodeByTable(litlen)) !== 256) {\n // literal\n if (code < 256) {\n if (op >= olength) {\n this.op = op;\n output = this.expandBufferBlock();\n op = this.op;\n }\n output[op++] = code;\n\n continue;\n }\n\n // length code\n ti = code - 257;\n codeLength = lengthCodeTable[ti];\n if (lengthExtraTable[ti] > 0) {\n codeLength += this.readBits(lengthExtraTable[ti]);\n }\n\n // dist code\n code = this.readCodeByTable(dist);\n codeDist = distCodeTable[code];\n if (distExtraTable[code] > 0) {\n codeDist += this.readBits(distExtraTable[code]);\n }\n\n // lz77 decode\n if (op >= olength) {\n this.op = op;\n output = this.expandBufferBlock();\n op = this.op;\n }\n while (codeLength--) {\n output[op] = output[(op++) - codeDist];\n }\n }\n\n while (this.bitsbuflen >= 8) {\n this.bitsbuflen -= 8;\n this.ip--;\n }\n this.op = op;\n};\n\n/**\n * decode huffman code (adaptive)\n * @param {!(Array.|Uint16Array)} litlen literal and length code table.\n * @param {!(Array.|Uint8Array)} dist distination code table.\n */\nZlib.RawInflate.prototype.decodeHuffmanAdaptive = function(litlen, dist) {\n var output = this.output;\n var op = this.op;\n\n this.currentLitlenTable = litlen;\n\n /** @type {number} output position limit. */\n var olength = output.length;\n /** @type {number} huffman code. */\n var code;\n /** @type {number} table index. */\n var ti;\n /** @type {number} huffman code distination. */\n var codeDist;\n /** @type {number} huffman code length. */\n var codeLength;\n\n var lengthCodeTable = Zlib.RawInflate.LengthCodeTable;\n var lengthExtraTable = Zlib.RawInflate.LengthExtraTable;\n var distCodeTable = Zlib.RawInflate.DistCodeTable;\n var distExtraTable = Zlib.RawInflate.DistExtraTable;\n\n while ((code = this.readCodeByTable(litlen)) !== 256) {\n // literal\n if (code < 256) {\n if (op >= olength) {\n output = this.expandBufferAdaptive();\n olength = output.length;\n }\n output[op++] = code;\n\n continue;\n }\n\n // length code\n ti = code - 257;\n codeLength = lengthCodeTable[ti];\n if (lengthExtraTable[ti] > 0) {\n codeLength += this.readBits(lengthExtraTable[ti]);\n }\n\n // dist code\n code = this.readCodeByTable(dist);\n codeDist = distCodeTable[code];\n if (distExtraTable[code] > 0) {\n codeDist += this.readBits(distExtraTable[code]);\n }\n\n // lz77 decode\n if (op + codeLength > olength) {\n output = this.expandBufferAdaptive();\n olength = output.length;\n }\n while (codeLength--) {\n output[op] = output[(op++) - codeDist];\n }\n }\n\n while (this.bitsbuflen >= 8) {\n this.bitsbuflen -= 8;\n this.ip--;\n }\n this.op = op;\n};\n\n/**\n * expand output buffer.\n * @param {Object=} opt_param option parameters.\n * @return {!(Array.|Uint8Array)} output buffer.\n */\nZlib.RawInflate.prototype.expandBufferBlock = function(opt_param) {\n /** @type {!(Array.|Uint8Array)} store buffer. */\n var buffer =\n new (USE_TYPEDARRAY ? Uint8Array : Array)(\n this.op - Zlib.RawInflate.MaxBackwardLength\n );\n /** @type {number} backward base point */\n var backward = this.op - Zlib.RawInflate.MaxBackwardLength;\n /** @type {number} copy index. */\n var i;\n /** @type {number} copy limit */\n var il;\n\n var output = this.output;\n\n // copy to output buffer\n if (USE_TYPEDARRAY) {\n buffer.set(output.subarray(Zlib.RawInflate.MaxBackwardLength, buffer.length));\n } else {\n for (i = 0, il = buffer.length; i < il; ++i) {\n buffer[i] = output[i + Zlib.RawInflate.MaxBackwardLength];\n }\n }\n\n this.blocks.push(buffer);\n this.totalpos += buffer.length;\n\n // copy to backward buffer\n if (USE_TYPEDARRAY) {\n output.set(\n output.subarray(backward, backward + Zlib.RawInflate.MaxBackwardLength)\n );\n } else {\n for (i = 0; i < Zlib.RawInflate.MaxBackwardLength; ++i) {\n output[i] = output[backward + i];\n }\n }\n\n this.op = Zlib.RawInflate.MaxBackwardLength;\n\n return output;\n};\n\n/**\n * expand output buffer. (adaptive)\n * @param {Object=} opt_param option parameters.\n * @return {!(Array.|Uint8Array)} output buffer pointer.\n */\nZlib.RawInflate.prototype.expandBufferAdaptive = function(opt_param) {\n /** @type {!(Array.|Uint8Array)} store buffer. */\n var buffer;\n /** @type {number} expantion ratio. */\n var ratio = (this.input.length / this.ip + 1) | 0;\n /** @type {number} maximum number of huffman code. */\n var maxHuffCode;\n /** @type {number} new output buffer size. */\n var newSize;\n /** @type {number} max inflate size. */\n var maxInflateSize;\n\n var input = this.input;\n var output = this.output;\n\n if (opt_param) {\n if (typeof opt_param.fixRatio === 'number') {\n ratio = opt_param.fixRatio;\n }\n if (typeof opt_param.addRatio === 'number') {\n ratio += opt_param.addRatio;\n }\n }\n\n // calculate new buffer size\n if (ratio < 2) {\n maxHuffCode =\n (input.length - this.ip) / this.currentLitlenTable[2];\n maxInflateSize = (maxHuffCode / 2 * 258) | 0;\n newSize = maxInflateSize < output.length ?\n output.length + maxInflateSize :\n output.length << 1;\n } else {\n newSize = output.length * ratio;\n }\n\n // buffer expantion\n if (USE_TYPEDARRAY) {\n buffer = new Uint8Array(newSize);\n buffer.set(output);\n } else {\n buffer = output;\n }\n\n this.output = buffer;\n\n return this.output;\n};\n\n/**\n * concat output buffer.\n * @return {!(Array.|Uint8Array)} output buffer.\n */\nZlib.RawInflate.prototype.concatBufferBlock = function() {\n /** @type {number} buffer pointer. */\n var pos = 0;\n /** @type {number} buffer pointer. */\n var limit = this.totalpos + (this.op - Zlib.RawInflate.MaxBackwardLength);\n /** @type {!(Array.|Uint8Array)} output block array. */\n var output = this.output;\n /** @type {!Array} blocks array. */\n var blocks = this.blocks;\n /** @type {!(Array.|Uint8Array)} output block array. */\n var block;\n /** @type {!(Array.|Uint8Array)} output buffer. */\n var buffer = new (USE_TYPEDARRAY ? Uint8Array : Array)(limit);\n /** @type {number} loop counter. */\n var i;\n /** @type {number} loop limiter. */\n var il;\n /** @type {number} loop counter. */\n var j;\n /** @type {number} loop limiter. */\n var jl;\n\n // single buffer\n if (blocks.length === 0) {\n return USE_TYPEDARRAY ?\n this.output.subarray(Zlib.RawInflate.MaxBackwardLength, this.op) :\n this.output.slice(Zlib.RawInflate.MaxBackwardLength, this.op);\n }\n\n // copy to buffer\n for (i = 0, il = blocks.length; i < il; ++i) {\n block = blocks[i];\n for (j = 0, jl = block.length; j < jl; ++j) {\n buffer[pos++] = block[j];\n }\n }\n\n // current buffer\n for (i = Zlib.RawInflate.MaxBackwardLength, il = this.op; i < il; ++i) {\n buffer[pos++] = output[i];\n }\n\n this.blocks = [];\n this.buffer = buffer;\n\n return this.buffer;\n};\n\n/**\n * concat output buffer. (dynamic)\n * @return {!(Array.|Uint8Array)} output buffer.\n */\nZlib.RawInflate.prototype.concatBufferDynamic = function() {\n /** @type {Array.|Uint8Array} output buffer. */\n var buffer;\n var op = this.op;\n\n if (USE_TYPEDARRAY) {\n if (this.resize) {\n buffer = new Uint8Array(op);\n buffer.set(this.output.subarray(0, op));\n } else {\n buffer = this.output.subarray(0, op);\n }\n } else {\n if (this.output.length > op) {\n this.output.length = op;\n }\n buffer = this.output;\n }\n\n this.buffer = buffer;\n\n return this.buffer;\n};\n\n\n\n\nvar buildHuffmanTable = Zlib.Huffman.buildHuffmanTable;\n\n/**\n * @param {!(Uint8Array|Array.)} input input buffer.\n * @param {number} ip input buffer pointer.\n * @param {number=} opt_buffersize buffer block size.\n * @constructor\n */\nZlib.RawInflateStream = function(input, ip, opt_buffersize) {\n /** @type {!Array.<(Array|Uint8Array)>} */\n this.blocks = [];\n /** @type {number} block size. */\n this.bufferSize =\n opt_buffersize ? opt_buffersize : ZLIB_STREAM_RAW_INFLATE_BUFFER_SIZE;\n /** @type {!number} total output buffer pointer. */\n this.totalpos = 0;\n /** @type {!number} input buffer pointer. */\n this.ip = ip === void 0 ? 0 : ip;\n /** @type {!number} bit stream reader buffer. */\n this.bitsbuf = 0;\n /** @type {!number} bit stream reader buffer size. */\n this.bitsbuflen = 0;\n /** @type {!(Array|Uint8Array)} input buffer. */\n this.input = USE_TYPEDARRAY ? new Uint8Array(input) : input;\n /** @type {!(Uint8Array|Array)} output buffer. */\n this.output = new (USE_TYPEDARRAY ? Uint8Array : Array)(this.bufferSize);\n /** @type {!number} output buffer pointer. */\n this.op = 0;\n /** @type {boolean} is final block flag. */\n this.bfinal = false;\n /** @type {number} uncompressed block length. */\n this.blockLength;\n /** @type {boolean} resize flag for memory size optimization. */\n this.resize = false;\n /** @type {Array} */\n this.litlenTable;\n /** @type {Array} */\n this.distTable;\n /** @type {number} */\n this.sp = 0; // stream pointer\n /** @type {Zlib.RawInflateStream.Status} */\n this.status = Zlib.RawInflateStream.Status.INITIALIZED;\n\n //\n // backup\n //\n /** @type {!number} */\n this.ip_;\n /** @type {!number} */\n this.bitsbuflen_;\n /** @type {!number} */\n this.bitsbuf_;\n};\n\n/**\n * @enum {number}\n */\nZlib.RawInflateStream.BlockType = {\n UNCOMPRESSED: 0,\n FIXED: 1,\n DYNAMIC: 2\n};\n\n/**\n * @enum {number}\n */\nZlib.RawInflateStream.Status = {\n INITIALIZED: 0,\n BLOCK_HEADER_START: 1,\n BLOCK_HEADER_END: 2,\n BLOCK_BODY_START: 3,\n BLOCK_BODY_END: 4,\n DECODE_BLOCK_START: 5,\n DECODE_BLOCK_END: 6\n};\n\n/**\n * decompress.\n * @return {!(Uint8Array|Array)} inflated buffer.\n */\nZlib.RawInflateStream.prototype.decompress = function(newInput, ip) {\n /** @type {boolean} */\n var stop = false;\n\n if (newInput !== void 0) {\n this.input = newInput;\n }\n\n if (ip !== void 0) {\n this.ip = ip;\n }\n\n // decompress\n while (!stop) {\n switch (this.status) {\n // block header\n case Zlib.RawInflateStream.Status.INITIALIZED:\n case Zlib.RawInflateStream.Status.BLOCK_HEADER_START:\n if (this.readBlockHeader() < 0) {\n stop = true;\n }\n break;\n // block body\n case Zlib.RawInflateStream.Status.BLOCK_HEADER_END: /* FALLTHROUGH */\n case Zlib.RawInflateStream.Status.BLOCK_BODY_START:\n switch(this.currentBlockType) {\n case Zlib.RawInflateStream.BlockType.UNCOMPRESSED:\n if (this.readUncompressedBlockHeader() < 0) {\n stop = true;\n }\n break;\n case Zlib.RawInflateStream.BlockType.FIXED:\n if (this.parseFixedHuffmanBlock() < 0) {\n stop = true;\n }\n break;\n case Zlib.RawInflateStream.BlockType.DYNAMIC:\n if (this.parseDynamicHuffmanBlock() < 0) {\n stop = true;\n }\n break;\n }\n break;\n // decode data\n case Zlib.RawInflateStream.Status.BLOCK_BODY_END:\n case Zlib.RawInflateStream.Status.DECODE_BLOCK_START:\n switch(this.currentBlockType) {\n case Zlib.RawInflateStream.BlockType.UNCOMPRESSED:\n if (this.parseUncompressedBlock() < 0) {\n stop = true;\n }\n break;\n case Zlib.RawInflateStream.BlockType.FIXED: /* FALLTHROUGH */\n case Zlib.RawInflateStream.BlockType.DYNAMIC:\n if (this.decodeHuffman() < 0) {\n stop = true;\n }\n break;\n }\n break;\n case Zlib.RawInflateStream.Status.DECODE_BLOCK_END:\n if (this.bfinal) {\n stop = true;\n } else {\n this.status = Zlib.RawInflateStream.Status.INITIALIZED;\n }\n break;\n }\n }\n\n return this.concatBuffer();\n};\n\n/**\n * @const\n * @type {number} max backward length for LZ77.\n */\nZlib.RawInflateStream.MaxBackwardLength = 32768;\n\n/**\n * @const\n * @type {number} max copy length for LZ77.\n */\nZlib.RawInflateStream.MaxCopyLength = 258;\n\n/**\n * huffman order\n * @const\n * @type {!(Array.|Uint8Array)}\n */\nZlib.RawInflateStream.Order = (function(table) {\n return USE_TYPEDARRAY ? new Uint16Array(table) : table;\n})([16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15]);\n\n/**\n * huffman length code table.\n * @const\n * @type {!(Array.|Uint16Array)}\n */\nZlib.RawInflateStream.LengthCodeTable = (function(table) {\n return USE_TYPEDARRAY ? new Uint16Array(table) : table;\n})([\n 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b,\n 0x000d, 0x000f, 0x0011, 0x0013, 0x0017, 0x001b, 0x001f, 0x0023, 0x002b,\n 0x0033, 0x003b, 0x0043, 0x0053, 0x0063, 0x0073, 0x0083, 0x00a3, 0x00c3,\n 0x00e3, 0x0102, 0x0102, 0x0102\n]);\n\n/**\n * huffman length extra-bits table.\n * @const\n * @type {!(Array.|Uint8Array)}\n */\nZlib.RawInflateStream.LengthExtraTable = (function(table) {\n return USE_TYPEDARRAY ? new Uint8Array(table) : table;\n})([\n 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5,\n 5, 5, 0, 0, 0\n]);\n\n/**\n * huffman dist code table.\n * @const\n * @type {!(Array.|Uint16Array)}\n */\nZlib.RawInflateStream.DistCodeTable = (function(table) {\n return USE_TYPEDARRAY ? new Uint16Array(table) : table;\n})([\n 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0007, 0x0009, 0x000d, 0x0011,\n 0x0019, 0x0021, 0x0031, 0x0041, 0x0061, 0x0081, 0x00c1, 0x0101, 0x0181,\n 0x0201, 0x0301, 0x0401, 0x0601, 0x0801, 0x0c01, 0x1001, 0x1801, 0x2001,\n 0x3001, 0x4001, 0x6001\n]);\n\n/**\n * huffman dist extra-bits table.\n * @const\n * @type {!(Array.|Uint8Array)}\n */\nZlib.RawInflateStream.DistExtraTable = (function(table) {\n return USE_TYPEDARRAY ? new Uint8Array(table) : table;\n})([\n 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11,\n 11, 12, 12, 13, 13\n]);\n\n/**\n * fixed huffman length code table\n * @const\n * @type {!Array}\n */\nZlib.RawInflateStream.FixedLiteralLengthTable = (function(table) {\n return table;\n})((function() {\n var lengths = new (USE_TYPEDARRAY ? Uint8Array : Array)(288);\n var i, il;\n\n for (i = 0, il = lengths.length; i < il; ++i) {\n lengths[i] =\n (i <= 143) ? 8 :\n (i <= 255) ? 9 :\n (i <= 279) ? 7 :\n 8;\n }\n\n return buildHuffmanTable(lengths);\n})());\n\n/**\n * fixed huffman distance code table\n * @const\n * @type {!Array}\n */\nZlib.RawInflateStream.FixedDistanceTable = (function(table) {\n return table;\n})((function() {\n var lengths = new (USE_TYPEDARRAY ? Uint8Array : Array)(30);\n var i, il;\n\n for (i = 0, il = lengths.length; i < il; ++i) {\n lengths[i] = 5;\n }\n\n return buildHuffmanTable(lengths);\n})());\n\n/**\n * parse deflated block.\n */\nZlib.RawInflateStream.prototype.readBlockHeader = function() {\n /** @type {number} header */\n var hdr;\n\n this.status = Zlib.RawInflateStream.Status.BLOCK_HEADER_START;\n\n this.save_();\n if ((hdr = this.readBits(3)) < 0) {\n this.restore_();\n return -1;\n }\n\n // BFINAL\n if (hdr & 0x1) {\n this.bfinal = true;\n }\n\n // BTYPE\n hdr >>>= 1;\n switch (hdr) {\n case 0: // uncompressed\n this.currentBlockType = Zlib.RawInflateStream.BlockType.UNCOMPRESSED;\n break;\n case 1: // fixed huffman\n this.currentBlockType = Zlib.RawInflateStream.BlockType.FIXED;\n break;\n case 2: // dynamic huffman\n this.currentBlockType = Zlib.RawInflateStream.BlockType.DYNAMIC;\n break;\n default: // reserved or other\n throw new Error('unknown BTYPE: ' + hdr);\n }\n\n this.status = Zlib.RawInflateStream.Status.BLOCK_HEADER_END;\n};\n\n/**\n * read inflate bits\n * @param {number} length bits length.\n * @return {number} read bits.\n */\nZlib.RawInflateStream.prototype.readBits = function(length) {\n var bitsbuf = this.bitsbuf;\n var bitsbuflen = this.bitsbuflen;\n var input = this.input;\n var ip = this.ip;\n\n /** @type {number} input and output byte. */\n var octet;\n\n // not enough buffer\n while (bitsbuflen < length) {\n // input byte\n if (input.length <= ip) {\n return -1;\n }\n octet = input[ip++];\n\n // concat octet\n bitsbuf |= octet << bitsbuflen;\n bitsbuflen += 8;\n }\n\n // output byte\n octet = bitsbuf & /* MASK */ ((1 << length) - 1);\n bitsbuf >>>= length;\n bitsbuflen -= length;\n\n this.bitsbuf = bitsbuf;\n this.bitsbuflen = bitsbuflen;\n this.ip = ip;\n\n return octet;\n};\n\n/**\n * read huffman code using table\n * @param {Array} table huffman code table.\n * @return {number} huffman code.\n */\nZlib.RawInflateStream.prototype.readCodeByTable = function(table) {\n var bitsbuf = this.bitsbuf;\n var bitsbuflen = this.bitsbuflen;\n var input = this.input;\n var ip = this.ip;\n\n /** @type {!(Array|Uint8Array)} huffman code table */\n var codeTable = table[0];\n /** @type {number} */\n var maxCodeLength = table[1];\n /** @type {number} input byte */\n var octet;\n /** @type {number} code length & code (16bit, 16bit) */\n var codeWithLength;\n /** @type {number} code bits length */\n var codeLength;\n\n // not enough buffer\n while (bitsbuflen < maxCodeLength) {\n if (input.length <= ip) {\n return -1;\n }\n octet = input[ip++];\n bitsbuf |= octet << bitsbuflen;\n bitsbuflen += 8;\n }\n\n // read max length\n codeWithLength = codeTable[bitsbuf & ((1 << maxCodeLength) - 1)];\n codeLength = codeWithLength >>> 16;\n\n if (codeLength > bitsbuflen) {\n throw new Error('invalid code length: ' + codeLength);\n }\n\n this.bitsbuf = bitsbuf >> codeLength;\n this.bitsbuflen = bitsbuflen - codeLength;\n this.ip = ip;\n\n return codeWithLength & 0xffff;\n};\n\n/**\n * read uncompressed block header\n */\nZlib.RawInflateStream.prototype.readUncompressedBlockHeader = function() {\n /** @type {number} block length */\n var len;\n /** @type {number} number for check block length */\n var nlen;\n\n var input = this.input;\n var ip = this.ip;\n\n this.status = Zlib.RawInflateStream.Status.BLOCK_BODY_START;\n\n if (ip + 4 >= input.length) {\n return -1;\n }\n\n len = input[ip++] | (input[ip++] << 8);\n nlen = input[ip++] | (input[ip++] << 8);\n\n // check len & nlen\n if (len === ~nlen) {\n throw new Error('invalid uncompressed block header: length verify');\n }\n\n // skip buffered header bits\n this.bitsbuf = 0;\n this.bitsbuflen = 0;\n\n this.ip = ip;\n this.blockLength = len;\n this.status = Zlib.RawInflateStream.Status.BLOCK_BODY_END;\n};\n\n/**\n * parse uncompressed block.\n */\nZlib.RawInflateStream.prototype.parseUncompressedBlock = function() {\n var input = this.input;\n var ip = this.ip;\n var output = this.output;\n var op = this.op;\n var len = this.blockLength;\n\n this.status = Zlib.RawInflateStream.Status.DECODE_BLOCK_START;\n\n // copy\n // XXX: とりあえず素直にコピー\n while (len--) {\n if (op === output.length) {\n output = this.expandBuffer({fixRatio: 2});\n }\n\n // not enough input buffer\n if (ip >= input.length) {\n this.ip = ip;\n this.op = op;\n this.blockLength = len + 1; // コピーしてないので戻す\n return -1;\n }\n\n output[op++] = input[ip++];\n }\n\n if (len < 0) {\n this.status = Zlib.RawInflateStream.Status.DECODE_BLOCK_END;\n }\n\n this.ip = ip;\n this.op = op;\n\n return 0;\n};\n\n/**\n * parse fixed huffman block.\n */\nZlib.RawInflateStream.prototype.parseFixedHuffmanBlock = function() {\n this.status = Zlib.RawInflateStream.Status.BLOCK_BODY_START;\n\n this.litlenTable = Zlib.RawInflateStream.FixedLiteralLengthTable;\n this.distTable = Zlib.RawInflateStream.FixedDistanceTable;\n\n this.status = Zlib.RawInflateStream.Status.BLOCK_BODY_END;\n\n return 0;\n};\n\n/**\n * オブジェクトのコンテキストを別のプロパティに退避する.\n * @private\n */\nZlib.RawInflateStream.prototype.save_ = function() {\n this.ip_ = this.ip;\n this.bitsbuflen_ = this.bitsbuflen;\n this.bitsbuf_ = this.bitsbuf;\n};\n\n/**\n * 別のプロパティに退避したコンテキストを復元する.\n * @private\n */\nZlib.RawInflateStream.prototype.restore_ = function() {\n this.ip = this.ip_;\n this.bitsbuflen = this.bitsbuflen_;\n this.bitsbuf = this.bitsbuf_;\n};\n\n/**\n * parse dynamic huffman block.\n */\nZlib.RawInflateStream.prototype.parseDynamicHuffmanBlock = function() {\n /** @type {number} number of literal and length codes. */\n var hlit;\n /** @type {number} number of distance codes. */\n var hdist;\n /** @type {number} number of code lengths. */\n var hclen;\n /** @type {!(Uint8Array|Array)} code lengths. */\n var codeLengths =\n new (USE_TYPEDARRAY ? Uint8Array : Array)(Zlib.RawInflateStream.Order.length);\n /** @type {!Array} code lengths table. */\n var codeLengthsTable;\n /** @type {!(Uint32Array|Array)} literal and length code lengths. */\n var litlenLengths;\n /** @type {!(Uint32Array|Array)} distance code lengths. */\n var distLengths;\n\n this.status = Zlib.RawInflateStream.Status.BLOCK_BODY_START;\n\n this.save_();\n hlit = this.readBits(5) + 257;\n hdist = this.readBits(5) + 1;\n hclen = this.readBits(4) + 4;\n if (hlit < 0 || hdist < 0 || hclen < 0) {\n this.restore_();\n return -1;\n }\n\n try {\n parseDynamicHuffmanBlockImpl.call(this);\n } catch(e) {\n this.restore_();\n return -1;\n }\n\n function parseDynamicHuffmanBlockImpl() {\n /** @type {number} */\n var bits;\n var code;\n var prev = 0;\n var repeat;\n /** @type {!(Uint8Array|Array.)} code length table. */\n var lengthTable;\n /** @type {number} loop counter. */\n var i;\n /** @type {number} loop limit. */\n var il;\n\n // decode code lengths\n for (i = 0; i < hclen; ++i) {\n if ((bits = this.readBits(3)) < 0) {\n throw new Error('not enough input');\n }\n codeLengths[Zlib.RawInflateStream.Order[i]] = bits;\n }\n\n // decode length table\n codeLengthsTable = buildHuffmanTable(codeLengths);\n lengthTable = new (USE_TYPEDARRAY ? Uint8Array : Array)(hlit + hdist);\n for (i = 0, il = hlit + hdist; i < il;) {\n code = this.readCodeByTable(codeLengthsTable);\n if (code < 0) {\n throw new Error('not enough input');\n }\n switch (code) {\n case 16:\n if ((bits = this.readBits(2)) < 0) {\n throw new Error('not enough input');\n }\n repeat = 3 + bits;\n while (repeat--) { lengthTable[i++] = prev; }\n break;\n case 17:\n if ((bits = this.readBits(3)) < 0) {\n throw new Error('not enough input');\n }\n repeat = 3 + bits;\n while (repeat--) { lengthTable[i++] = 0; }\n prev = 0;\n break;\n case 18:\n if ((bits = this.readBits(7)) < 0) {\n throw new Error('not enough input');\n }\n repeat = 11 + bits;\n while (repeat--) { lengthTable[i++] = 0; }\n prev = 0;\n break;\n default:\n lengthTable[i++] = code;\n prev = code;\n break;\n }\n }\n\n // literal and length code\n litlenLengths = new (USE_TYPEDARRAY ? Uint8Array : Array)(hlit);\n\n // distance code\n distLengths = new (USE_TYPEDARRAY ? Uint8Array : Array)(hdist);\n\n this.litlenTable = USE_TYPEDARRAY\n ? buildHuffmanTable(lengthTable.subarray(0, hlit))\n : buildHuffmanTable(lengthTable.slice(0, hlit));\n this.distTable = USE_TYPEDARRAY\n ? buildHuffmanTable(lengthTable.subarray(hlit))\n : buildHuffmanTable(lengthTable.slice(hlit));\n }\n\n this.status = Zlib.RawInflateStream.Status.BLOCK_BODY_END;\n\n return 0;\n};\n\n/**\n * decode huffman code (dynamic)\n * @return {(number|undefined)} -1 is error.\n */\nZlib.RawInflateStream.prototype.decodeHuffman = function() {\n var output = this.output;\n var op = this.op;\n\n /** @type {number} huffman code. */\n var code;\n /** @type {number} table index. */\n var ti;\n /** @type {number} huffman code distination. */\n var codeDist;\n /** @type {number} huffman code length. */\n var codeLength;\n\n var litlen = this.litlenTable;\n var dist = this.distTable;\n\n var olength = output.length;\n var bits;\n\n this.status = Zlib.RawInflateStream.Status.DECODE_BLOCK_START;\n\n while (true) {\n this.save_();\n\n code = this.readCodeByTable(litlen);\n if (code < 0) {\n this.op = op;\n this.restore_();\n return -1;\n }\n\n if (code === 256) {\n break;\n }\n\n // literal\n if (code < 256) {\n if (op === olength) {\n output = this.expandBuffer();\n olength = output.length;\n }\n output[op++] = code;\n\n continue;\n }\n\n // length code\n ti = code - 257;\n codeLength = Zlib.RawInflateStream.LengthCodeTable[ti];\n if (Zlib.RawInflateStream.LengthExtraTable[ti] > 0) {\n bits = this.readBits(Zlib.RawInflateStream.LengthExtraTable[ti]);\n if (bits < 0) {\n this.op = op;\n this.restore_();\n return -1;\n }\n codeLength += bits;\n }\n\n // dist code\n code = this.readCodeByTable(dist);\n if (code < 0) {\n this.op = op;\n this.restore_();\n return -1;\n }\n codeDist = Zlib.RawInflateStream.DistCodeTable[code];\n if (Zlib.RawInflateStream.DistExtraTable[code] > 0) {\n bits = this.readBits(Zlib.RawInflateStream.DistExtraTable[code]);\n if (bits < 0) {\n this.op = op;\n this.restore_();\n return -1;\n }\n codeDist += bits;\n }\n\n // lz77 decode\n if (op + codeLength >= olength) {\n output = this.expandBuffer();\n olength = output.length;\n }\n\n while (codeLength--) {\n output[op] = output[(op++) - codeDist];\n }\n\n // break\n if (this.ip === this.input.length) {\n this.op = op;\n return -1;\n }\n }\n\n while (this.bitsbuflen >= 8) {\n this.bitsbuflen -= 8;\n this.ip--;\n }\n\n this.op = op;\n this.status = Zlib.RawInflateStream.Status.DECODE_BLOCK_END;\n};\n\n/**\n * expand output buffer. (dynamic)\n * @param {Object=} opt_param option parameters.\n * @return {!(Array|Uint8Array)} output buffer pointer.\n */\nZlib.RawInflateStream.prototype.expandBuffer = function(opt_param) {\n /** @type {!(Array|Uint8Array)} store buffer. */\n var buffer;\n /** @type {number} expantion ratio. */\n var ratio = (this.input.length / this.ip + 1) | 0;\n /** @type {number} maximum number of huffman code. */\n var maxHuffCode;\n /** @type {number} new output buffer size. */\n var newSize;\n /** @type {number} max inflate size. */\n var maxInflateSize;\n\n var input = this.input;\n var output = this.output;\n\n if (opt_param) {\n if (typeof opt_param.fixRatio === 'number') {\n ratio = opt_param.fixRatio;\n }\n if (typeof opt_param.addRatio === 'number') {\n ratio += opt_param.addRatio;\n }\n }\n\n // calculate new buffer size\n if (ratio < 2) {\n maxHuffCode =\n (input.length - this.ip) / this.litlenTable[2];\n maxInflateSize = (maxHuffCode / 2 * 258) | 0;\n newSize = maxInflateSize < output.length ?\n output.length + maxInflateSize :\n output.length << 1;\n } else {\n newSize = output.length * ratio;\n }\n\n // buffer expantion\n if (USE_TYPEDARRAY) {\n buffer = new Uint8Array(newSize);\n buffer.set(output);\n } else {\n buffer = output;\n }\n\n this.output = buffer;\n\n return this.output;\n};\n\n/**\n * concat output buffer. (dynamic)\n * @return {!(Array|Uint8Array)} output buffer.\n */\nZlib.RawInflateStream.prototype.concatBuffer = function() {\n /** @type {!(Array|Uint8Array)} output buffer. */\n var buffer;\n /** @type {number} */\n var op = this.op;\n /** @type {Uint8Array} */\n var tmp;\n\n if (this.resize) {\n if (USE_TYPEDARRAY) {\n buffer = new Uint8Array(this.output.subarray(this.sp, op));\n } else {\n buffer = this.output.slice(this.sp, op);\n }\n } else {\n buffer =\n USE_TYPEDARRAY ? this.output.subarray(this.sp, op) : this.output.slice(this.sp, op);\n }\n\n this.sp = op;\n\n // compaction\n if (op > Zlib.RawInflateStream.MaxBackwardLength + this.bufferSize) {\n this.op = this.sp = Zlib.RawInflateStream.MaxBackwardLength;\n if (USE_TYPEDARRAY) {\n tmp = /** @type {Uint8Array} */(this.output);\n this.output = new Uint8Array(this.bufferSize + Zlib.RawInflateStream.MaxBackwardLength);\n this.output.set(tmp.subarray(op - Zlib.RawInflateStream.MaxBackwardLength, op));\n } else {\n this.output = this.output.slice(op - Zlib.RawInflateStream.MaxBackwardLength);\n }\n }\n\n return buffer;\n};\n\n\n/**\n * @constructor\n * @param {!(Uint8Array|Array)} input deflated buffer.\n * @param {Object=} opt_params option parameters.\n *\n * opt_params は以下のプロパティを指定する事ができます。\n * - index: input buffer の deflate コンテナの開始位置.\n * - blockSize: バッファのブロックサイズ.\n * - verify: 伸張が終わった後 adler-32 checksum の検証を行うか.\n * - bufferType: Zlib.Inflate.BufferType の値によってバッファの管理方法を指定する.\n * Zlib.Inflate.BufferType は Zlib.RawInflate.BufferType のエイリアス.\n */\nZlib.Inflate = function(input, opt_params) {\n /** @type {number} */\n var bufferSize;\n /** @type {Zlib.Inflate.BufferType} */\n var bufferType;\n /** @type {number} */\n var cmf;\n /** @type {number} */\n var flg;\n\n /** @type {!(Uint8Array|Array)} */\n this.input = input;\n /** @type {number} */\n this.ip = 0;\n /** @type {Zlib.RawInflate} */\n this.rawinflate;\n /** @type {(boolean|undefined)} verify flag. */\n this.verify;\n\n // option parameters\n if (opt_params || !(opt_params = {})) {\n if (opt_params['index']) {\n this.ip = opt_params['index'];\n }\n if (opt_params['verify']) {\n this.verify = opt_params['verify'];\n }\n }\n\n // Compression Method and Flags\n cmf = input[this.ip++];\n flg = input[this.ip++];\n\n // compression method\n switch (cmf & 0x0f) {\n case Zlib.CompressionMethod.DEFLATE:\n this.method = Zlib.CompressionMethod.DEFLATE;\n break;\n default:\n throw new Error('unsupported compression method');\n }\n\n // fcheck\n if (((cmf << 8) + flg) % 31 !== 0) {\n throw new Error('invalid fcheck flag:' + ((cmf << 8) + flg) % 31);\n }\n\n // fdict (not supported)\n if (flg & 0x20) {\n throw new Error('fdict flag is not supported');\n }\n\n // RawInflate\n this.rawinflate = new Zlib.RawInflate(input, {\n 'index': this.ip,\n 'bufferSize': opt_params['bufferSize'],\n 'bufferType': opt_params['bufferType'],\n 'resize': opt_params['resize']\n });\n}\n\n/**\n * @enum {number}\n */\nZlib.Inflate.BufferType = Zlib.RawInflate.BufferType;\n\n/**\n * decompress.\n * @return {!(Uint8Array|Array)} inflated buffer.\n */\nZlib.Inflate.prototype.decompress = function() {\n /** @type {!(Array|Uint8Array)} input buffer. */\n var input = this.input;\n /** @type {!(Uint8Array|Array)} inflated buffer. */\n var buffer;\n /** @type {number} adler-32 checksum */\n var adler32;\n\n buffer = this.rawinflate.decompress();\n this.ip = this.rawinflate.ip;\n\n // verify adler-32\n if (this.verify) {\n adler32 = (\n input[this.ip++] << 24 | input[this.ip++] << 16 |\n input[this.ip++] << 8 | input[this.ip++]\n ) >>> 0;\n\n if (adler32 !== Zlib.Adler32(buffer)) {\n throw new Error('invalid adler-32 checksum');\n }\n }\n\n return buffer;\n};\n\n\n/* vim:set expandtab ts=2 sw=2 tw=80: */\n\n\n/**\n * @param {!(Uint8Array|Array)} input deflated buffer.\n * @constructor\n */\nZlib.InflateStream = function(input) {\n /** @type {!(Uint8Array|Array)} */\n this.input = input === void 0 ? new (USE_TYPEDARRAY ? Uint8Array : Array)() : input;\n /** @type {number} */\n this.ip = 0;\n /** @type {Zlib.RawInflateStream} */\n this.rawinflate = new Zlib.RawInflateStream(this.input, this.ip);\n /** @type {Zlib.CompressionMethod} */\n this.method;\n /** @type {!(Array|Uint8Array)} */\n this.output = this.rawinflate.output;\n};\n\n/**\n * decompress.\n * @return {!(Uint8Array|Array)} inflated buffer.\n */\nZlib.InflateStream.prototype.decompress = function(input) {\n /** @type {!(Uint8Array|Array)} inflated buffer. */\n var buffer;\n /** @type {number} adler-32 checksum */\n var adler32;\n\n // 新しい入力を入力バッファに結合する\n // XXX Array, Uint8Array のチェックを行うか確認する\n if (input !== void 0) {\n if (USE_TYPEDARRAY) {\n var tmp = new Uint8Array(this.input.length + input.length);\n tmp.set(this.input, 0);\n tmp.set(input, this.input.length);\n this.input = tmp;\n } else {\n this.input = this.input.concat(input);\n }\n }\n\n if (this.method === void 0) {\n if(this.readHeader() < 0) {\n return new (USE_TYPEDARRAY ? Uint8Array : Array)();\n }\n }\n\n buffer = this.rawinflate.decompress(this.input, this.ip);\n if (this.rawinflate.ip !== 0) {\n this.input = USE_TYPEDARRAY ?\n this.input.subarray(this.rawinflate.ip) :\n this.input.slice(this.rawinflate.ip);\n this.ip = 0;\n }\n\n // verify adler-32\n /*\n if (this.verify) {\n adler32 =\n input[this.ip++] << 24 | input[this.ip++] << 16 |\n input[this.ip++] << 8 | input[this.ip++];\n\n if (adler32 !== Zlib.Adler32(buffer)) {\n throw new Error('invalid adler-32 checksum');\n }\n }\n */\n\n return buffer;\n};\n\nZlib.InflateStream.prototype.readHeader = function() {\n var ip = this.ip;\n var input = this.input;\n\n // Compression Method and Flags\n var cmf = input[ip++];\n var flg = input[ip++];\n\n if (cmf === void 0 || flg === void 0) {\n return -1;\n }\n\n // compression method\n switch (cmf & 0x0f) {\n case Zlib.CompressionMethod.DEFLATE:\n this.method = Zlib.CompressionMethod.DEFLATE;\n break;\n default:\n throw new Error('unsupported compression method');\n }\n\n // fcheck\n if (((cmf << 8) + flg) % 31 !== 0) {\n throw new Error('invalid fcheck flag:' + ((cmf << 8) + flg) % 31);\n }\n\n // fdict (not supported)\n if (flg & 0x20) {\n throw new Error('fdict flag is not supported');\n }\n\n this.ip = ip;\n};\n\n\n/**\n * @fileoverview GZIP (RFC1952) 展開コンテナ実装.\n */\n\n/**\n * @constructor\n * @param {!(Array|Uint8Array)} input input buffer.\n * @param {Object=} opt_params option parameters.\n */\nZlib.Gunzip = function(input, opt_params) {\n /** @type {!(Array.|Uint8Array)} input buffer. */\n this.input = input;\n /** @type {number} input buffer pointer. */\n this.ip = 0;\n /** @type {Array.} */\n this.member = [];\n /** @type {boolean} */\n this.decompressed = false;\n};\n\n/**\n * @return {Array.}\n */\nZlib.Gunzip.prototype.getMembers = function() {\n if (!this.decompressed) {\n this.decompress();\n }\n\n return this.member.slice();\n};\n\n/**\n * inflate gzip data.\n * @return {!(Array.|Uint8Array)} inflated buffer.\n */\nZlib.Gunzip.prototype.decompress = function() {\n /** @type {number} input length. */\n var il = this.input.length;\n\n while (this.ip < il) {\n this.decodeMember();\n }\n\n this.decompressed = true;\n\n return this.concatMember();\n};\n\n/**\n * decode gzip member.\n */\nZlib.Gunzip.prototype.decodeMember = function() {\n /** @type {Zlib.GunzipMember} */\n var member = new Zlib.GunzipMember();\n /** @type {number} */\n var isize;\n /** @type {Zlib.RawInflate} RawInflate implementation. */\n var rawinflate;\n /** @type {!(Array.|Uint8Array)} inflated data. */\n var inflated;\n /** @type {number} inflate size */\n var inflen;\n /** @type {number} character code */\n var c;\n /** @type {number} character index in string. */\n var ci;\n /** @type {Array.} character array. */\n var str;\n /** @type {number} modification time. */\n var mtime;\n /** @type {number} */\n var crc32;\n\n var input = this.input;\n var ip = this.ip;\n\n member.id1 = input[ip++];\n member.id2 = input[ip++];\n\n // check signature\n if (member.id1 !== 0x1f || member.id2 !== 0x8b) {\n throw new Error('invalid file signature:' + member.id1 + ',' + member.id2);\n }\n\n // check compression method\n member.cm = input[ip++];\n switch (member.cm) {\n case 8: /* XXX: use Zlib const */\n break;\n default:\n throw new Error('unknown compression method: ' + member.cm);\n }\n\n // flags\n member.flg = input[ip++];\n\n // modification time\n mtime = (input[ip++]) |\n (input[ip++] << 8) |\n (input[ip++] << 16) |\n (input[ip++] << 24);\n member.mtime = new Date(mtime * 1000);\n\n // extra flags\n member.xfl = input[ip++];\n\n // operating system\n member.os = input[ip++];\n\n // extra\n if ((member.flg & Zlib.Gzip.FlagsMask.FEXTRA) > 0) {\n member.xlen = input[ip++] | (input[ip++] << 8);\n ip = this.decodeSubField(ip, member.xlen);\n }\n\n // fname\n if ((member.flg & Zlib.Gzip.FlagsMask.FNAME) > 0) {\n for(str = [], ci = 0; (c = input[ip++]) > 0;) {\n str[ci++] = String.fromCharCode(c);\n }\n member.name = str.join('');\n }\n\n // fcomment\n if ((member.flg & Zlib.Gzip.FlagsMask.FCOMMENT) > 0) {\n for(str = [], ci = 0; (c = input[ip++]) > 0;) {\n str[ci++] = String.fromCharCode(c);\n }\n member.comment = str.join('');\n }\n\n // fhcrc\n if ((member.flg & Zlib.Gzip.FlagsMask.FHCRC) > 0) {\n member.crc16 = Zlib.CRC32.calc(input, 0, ip) & 0xffff;\n if (member.crc16 !== (input[ip++] | (input[ip++] << 8))) {\n throw new Error('invalid header crc16');\n }\n }\n\n // isize を事前に取得すると展開後のサイズが分かるため、\n // inflate処理のバッファサイズが事前に分かり、高速になる\n isize = (input[input.length - 4]) | (input[input.length - 3] << 8) |\n (input[input.length - 2] << 16) | (input[input.length - 1] << 24);\n\n // isize の妥当性チェック\n // ハフマン符号では最小 2-bit のため、最大で 1/4 になる\n // LZ77 符号では 長さと距離 2-Byte で最大 258-Byte を表現できるため、\n // 1/128 になるとする\n // ここから入力バッファの残りが isize の 512 倍以上だったら\n // サイズ指定のバッファ確保は行わない事とする\n if (input.length - ip - /* CRC-32 */4 - /* ISIZE */4 < isize * 512) {\n inflen = isize;\n }\n\n // compressed block\n rawinflate = new Zlib.RawInflate(input, {'index': ip, 'bufferSize': inflen});\n member.data = inflated = rawinflate.decompress();\n ip = rawinflate.ip;\n\n // crc32\n member.crc32 = crc32 =\n ((input[ip++]) | (input[ip++] << 8) |\n (input[ip++] << 16) | (input[ip++] << 24)) >>> 0;\n if (Zlib.CRC32.calc(inflated) !== crc32) {\n throw new Error('invalid CRC-32 checksum: 0x' +\n Zlib.CRC32.calc(inflated).toString(16) + ' / 0x' + crc32.toString(16));\n }\n\n // input size\n member.isize = isize =\n ((input[ip++]) | (input[ip++] << 8) |\n (input[ip++] << 16) | (input[ip++] << 24)) >>> 0;\n if ((inflated.length & 0xffffffff) !== isize) {\n throw new Error('invalid input size: ' +\n (inflated.length & 0xffffffff) + ' / ' + isize);\n }\n\n this.member.push(member);\n this.ip = ip;\n};\n\n/**\n * サブフィールドのデコード\n * XXX: 現在は何もせずスキップする\n */\nZlib.Gunzip.prototype.decodeSubField = function(ip, length) {\n return ip + length;\n};\n\n/**\n * @return {!(Array.|Uint8Array)}\n */\nZlib.Gunzip.prototype.concatMember = function() {\n /** @type {Array.} */\n var member = this.member;\n /** @type {number} */\n var i;\n /** @type {number} */\n var il;\n /** @type {number} */\n var p = 0;\n /** @type {number} */\n var size = 0;\n /** @type {!(Array.|Uint8Array)} */\n var buffer;\n\n for (i = 0, il = member.length; i < il; ++i) {\n size += member[i].data.length;\n }\n\n if (USE_TYPEDARRAY) {\n buffer = new Uint8Array(size);\n for (i = 0; i < il; ++i) {\n buffer.set(member[i].data, p);\n p += member[i].data.length;\n }\n } else {\n buffer = [];\n for (i = 0; i < il; ++i) {\n buffer[i] = member[i].data;\n }\n buffer = Array.prototype.concat.apply([], buffer);\n }\n\n return buffer;\n};\n\n\n\n/**\n * @constructor\n */\nZlib.GunzipMember = function() {\n /** @type {number} signature first byte. */\n this.id1;\n /** @type {number} signature second byte. */\n this.id2;\n /** @type {number} compression method. */\n this.cm;\n /** @type {number} flags. */\n this.flg;\n /** @type {Date} modification time. */\n this.mtime;\n /** @type {number} extra flags. */\n this.xfl;\n /** @type {number} operating system number. */\n this.os;\n /** @type {number} CRC-16 value for FHCRC flag. */\n this.crc16;\n /** @type {number} extra length. */\n this.xlen;\n /** @type {number} CRC-32 value for verification. */\n this.crc32;\n /** @type {number} input size modulo 32 value. */\n this.isize;\n /** @type {string} filename. */\n this.name;\n /** @type {string} comment. */\n this.comment;\n /** @type {!(Uint8Array|Array.)} */\n this.data;\n};\n\nZlib.GunzipMember.prototype.getName = function() {\n return this.name;\n};\n\nZlib.GunzipMember.prototype.getData = function() {\n return this.data;\n};\n\nZlib.GunzipMember.prototype.getMtime = function() {\n return this.mtime;\n}\n\n/**\n * @fileoverview GZIP (RFC1952) 実装.\n */\n\n/**\n * @constructor\n * @param {!(Array|Uint8Array)} input input buffer.\n * @param {Object=} opt_params option parameters.\n */\nZlib.Gzip = function(input, opt_params) {\n /** @type {!(Array.|Uint8Array)} input buffer. */\n this.input = input;\n /** @type {number} input buffer pointer. */\n this.ip = 0;\n /** @type {!(Array.|Uint8Array)} output buffer. */\n this.output;\n /** @type {number} output buffer. */\n this.op = 0;\n /** @type {!Object} flags option flags. */\n this.flags = {};\n /** @type {!string} filename. */\n this.filename;\n /** @type {!string} comment. */\n this.comment;\n /** @type {!Object} deflate options. */\n this.deflateOptions;\n\n // option parameters\n if (opt_params) {\n if (opt_params['flags']) {\n this.flags = opt_params['flags'];\n }\n if (typeof opt_params['filename'] === 'string') {\n this.filename = opt_params['filename'];\n }\n if (typeof opt_params['comment'] === 'string') {\n this.comment = opt_params['comment'];\n }\n if (opt_params['deflateOptions']) {\n this.deflateOptions = opt_params['deflateOptions'];\n }\n }\n\n if (!this.deflateOptions) {\n this.deflateOptions = {};\n }\n};\n\n/**\n * @type {number}\n * @const\n */\nZlib.Gzip.DefaultBufferSize = 0x8000;\n\n/**\n * encode gzip members.\n * @return {!(Array|Uint8Array)} gzip binary array.\n */\nZlib.Gzip.prototype.compress = function() {\n /** @type {number} flags. */\n var flg;\n /** @type {number} modification time. */\n var mtime;\n /** @type {number} CRC-16 value for FHCRC flag. */\n var crc16;\n /** @type {number} CRC-32 value for verification. */\n var crc32;\n /** @type {!Zlib.RawDeflate} raw deflate object. */\n var rawdeflate;\n /** @type {number} character code */\n var c;\n /** @type {number} loop counter. */\n var i;\n /** @type {number} loop limiter. */\n var il;\n /** @type {!(Array|Uint8Array)} output buffer. */\n var output =\n new (USE_TYPEDARRAY ? Uint8Array : Array)(Zlib.Gzip.DefaultBufferSize);\n /** @type {number} output buffer pointer. */\n var op = 0;\n\n var input = this.input;\n var ip = this.ip;\n var filename = this.filename;\n var comment = this.comment;\n\n // check signature\n output[op++] = 0x1f;\n output[op++] = 0x8b;\n\n // check compression method\n output[op++] = 8; /* XXX: use Zlib const */\n\n // flags\n flg = 0;\n if (this.flags['fname']) flg |= Zlib.Gzip.FlagsMask.FNAME;\n if (this.flags['fcomment']) flg |= Zlib.Gzip.FlagsMask.FCOMMENT;\n if (this.flags['fhcrc']) flg |= Zlib.Gzip.FlagsMask.FHCRC;\n // XXX: FTEXT\n // XXX: FEXTRA\n output[op++] = flg;\n\n // modification time\n mtime = (Date.now ? Date.now() : +new Date()) / 1000 | 0;\n output[op++] = mtime & 0xff;\n output[op++] = mtime >>> 8 & 0xff;\n output[op++] = mtime >>> 16 & 0xff;\n output[op++] = mtime >>> 24 & 0xff;\n\n // extra flags\n output[op++] = 0;\n\n // operating system\n output[op++] = Zlib.Gzip.OperatingSystem.UNKNOWN;\n\n // extra\n /* NOP */\n\n // fname\n if (this.flags['fname'] !== void 0) {\n for (i = 0, il = filename.length; i < il; ++i) {\n c = filename.charCodeAt(i);\n if (c > 0xff) { output[op++] = (c >>> 8) & 0xff; }\n output[op++] = c & 0xff;\n }\n output[op++] = 0; // null termination\n }\n\n // fcomment\n if (this.flags['comment']) {\n for (i = 0, il = comment.length; i < il; ++i) {\n c = comment.charCodeAt(i);\n if (c > 0xff) { output[op++] = (c >>> 8) & 0xff; }\n output[op++] = c & 0xff;\n }\n output[op++] = 0; // null termination\n }\n\n // fhcrc\n if (this.flags['fhcrc']) {\n crc16 = Zlib.CRC32.calc(output, 0, op) & 0xffff;\n output[op++] = (crc16 ) & 0xff;\n output[op++] = (crc16 >>> 8) & 0xff;\n }\n\n // add compress option\n this.deflateOptions['outputBuffer'] = output;\n this.deflateOptions['outputIndex'] = op;\n\n // compress\n rawdeflate = new Zlib.RawDeflate(input, this.deflateOptions);\n output = rawdeflate.compress();\n op = rawdeflate.op;\n\n // expand buffer\n if (USE_TYPEDARRAY) {\n if (op + 8 > output.buffer.byteLength) {\n this.output = new Uint8Array(op + 8);\n this.output.set(new Uint8Array(output.buffer));\n output = this.output;\n } else {\n output = new Uint8Array(output.buffer);\n }\n }\n\n // crc32\n crc32 = Zlib.CRC32.calc(input);\n output[op++] = (crc32 ) & 0xff;\n output[op++] = (crc32 >>> 8) & 0xff;\n output[op++] = (crc32 >>> 16) & 0xff;\n output[op++] = (crc32 >>> 24) & 0xff;\n\n // input size\n il = input.length;\n output[op++] = (il ) & 0xff;\n output[op++] = (il >>> 8) & 0xff;\n output[op++] = (il >>> 16) & 0xff;\n output[op++] = (il >>> 24) & 0xff;\n\n this.ip = ip;\n\n if (USE_TYPEDARRAY && op < output.length) {\n this.output = output = output.subarray(0, op);\n }\n\n return output;\n};\n\n/** @enum {number} */\nZlib.Gzip.OperatingSystem = {\n FAT: 0,\n AMIGA: 1,\n VMS: 2,\n UNIX: 3,\n VM_CMS: 4,\n ATARI_TOS: 5,\n HPFS: 6,\n MACINTOSH: 7,\n Z_SYSTEM: 8,\n CP_M: 9,\n TOPS_20: 10,\n NTFS: 11,\n QDOS: 12,\n ACORN_RISCOS: 13,\n UNKNOWN: 255\n};\n\n/** @enum {number} */\nZlib.Gzip.FlagsMask = {\n FTEXT: 0x01,\n FHCRC: 0x02,\n FEXTRA: 0x04,\n FNAME: 0x08,\n FCOMMENT: 0x10\n};\n\n\n/**\n * @fileoverview Heap Sort 実装. ハフマン符号化で使用する.\n */\n\n/**\n * カスタムハフマン符号で使用するヒープ実装\n * @param {number} length ヒープサイズ.\n * @constructor\n */\nZlib.Heap = function(length) {\n this.buffer = new (USE_TYPEDARRAY ? Uint16Array : Array)(length * 2);\n this.length = 0;\n};\n\n/**\n * 親ノードの index 取得\n * @param {number} index 子ノードの index.\n * @return {number} 親ノードの index.\n *\n */\nZlib.Heap.prototype.getParent = function(index) {\n return ((index - 2) / 4 | 0) * 2;\n};\n\n/**\n * 子ノードの index 取得\n * @param {number} index 親ノードの index.\n * @return {number} 子ノードの index.\n */\nZlib.Heap.prototype.getChild = function(index) {\n return 2 * index + 2;\n};\n\n/**\n * Heap に値を追加する\n * @param {number} index キー index.\n * @param {number} value 値.\n * @return {number} 現在のヒープ長.\n */\nZlib.Heap.prototype.push = function(index, value) {\n var current, parent,\n heap = this.buffer,\n swap;\n\n current = this.length;\n heap[this.length++] = value;\n heap[this.length++] = index;\n\n // ルートノードにたどり着くまで入れ替えを試みる\n while (current > 0) {\n parent = this.getParent(current);\n\n // 親ノードと比較して親の方が小さければ入れ替える\n if (heap[current] > heap[parent]) {\n swap = heap[current];\n heap[current] = heap[parent];\n heap[parent] = swap;\n\n swap = heap[current + 1];\n heap[current + 1] = heap[parent + 1];\n heap[parent + 1] = swap;\n\n current = parent;\n // 入れ替えが必要なくなったらそこで抜ける\n } else {\n break;\n }\n }\n\n return this.length;\n};\n\n/**\n * Heapから一番大きい値を返す\n * @return {{index: number, value: number, length: number}} {index: キーindex,\n * value: 値, length: ヒープ長} の Object.\n */\nZlib.Heap.prototype.pop = function() {\n var index, value,\n heap = this.buffer, swap,\n current, parent;\n\n value = heap[0];\n index = heap[1];\n\n // 後ろから値を取る\n this.length -= 2;\n heap[0] = heap[this.length];\n heap[1] = heap[this.length + 1];\n\n parent = 0;\n // ルートノードから下がっていく\n while (true) {\n current = this.getChild(parent);\n\n // 範囲チェック\n if (current >= this.length) {\n break;\n }\n\n // 隣のノードと比較して、隣の方が値が大きければ隣を現在ノードとして選択\n if (current + 2 < this.length && heap[current + 2] > heap[current]) {\n current += 2;\n }\n\n // 親ノードと比較して親の方が小さい場合は入れ替える\n if (heap[current] > heap[parent]) {\n swap = heap[parent];\n heap[parent] = heap[current];\n heap[current] = swap;\n\n swap = heap[parent + 1];\n heap[parent + 1] = heap[current + 1];\n heap[current + 1] = swap;\n } else {\n break;\n }\n\n parent = current;\n }\n\n return {index: index, value: value, length: this.length};\n};\n\n\n/* vim:set expandtab ts=2 sw=2 tw=80: */\n\n/**\n * @fileoverview Deflate (RFC1951) 符号化アルゴリズム実装.\n */\n\n\n/**\n * Raw Deflate 実装\n *\n * @constructor\n * @param {!(Array.|Uint8Array)} input 符号化する対象のバッファ.\n * @param {Object=} opt_params option parameters.\n *\n * typed array が使用可能なとき、outputBuffer が Array は自動的に Uint8Array に\n * 変換されます.\n * 別のオブジェクトになるため出力バッファを参照している変数などは\n * 更新する必要があります.\n */\nZlib.RawDeflate = function(input, opt_params) {\n /** @type {Zlib.RawDeflate.CompressionType} */\n this.compressionType = Zlib.RawDeflate.CompressionType.DYNAMIC;\n /** @type {number} */\n this.lazy = 0;\n /** @type {!(Array.|Uint32Array)} */\n this.freqsLitLen;\n /** @type {!(Array.|Uint32Array)} */\n this.freqsDist;\n /** @type {!(Array.|Uint8Array)} */\n this.input =\n (USE_TYPEDARRAY && input instanceof Array) ? new Uint8Array(input) : input;\n /** @type {!(Array.|Uint8Array)} output output buffer. */\n this.output;\n /** @type {number} pos output buffer position. */\n this.op = 0;\n\n // option parameters\n if (opt_params) {\n if (opt_params['lazy']) {\n this.lazy = opt_params['lazy'];\n }\n if (typeof opt_params['compressionType'] === 'number') {\n this.compressionType = opt_params['compressionType'];\n }\n if (opt_params['outputBuffer']) {\n this.output =\n (USE_TYPEDARRAY && opt_params['outputBuffer'] instanceof Array) ?\n new Uint8Array(opt_params['outputBuffer']) : opt_params['outputBuffer'];\n }\n if (typeof opt_params['outputIndex'] === 'number') {\n this.op = opt_params['outputIndex'];\n }\n }\n\n if (!this.output) {\n this.output = new (USE_TYPEDARRAY ? Uint8Array : Array)(0x8000);\n }\n};\n\n/**\n * @enum {number}\n */\nZlib.RawDeflate.CompressionType = {\n NONE: 0,\n FIXED: 1,\n DYNAMIC: 2,\n RESERVED: 3\n};\n\n\n/**\n * LZ77 の最小マッチ長\n * @const\n * @type {number}\n */\nZlib.RawDeflate.Lz77MinLength = 3;\n\n/**\n * LZ77 の最大マッチ長\n * @const\n * @type {number}\n */\nZlib.RawDeflate.Lz77MaxLength = 258;\n\n/**\n * LZ77 のウィンドウサイズ\n * @const\n * @type {number}\n */\nZlib.RawDeflate.WindowSize = 0x8000;\n\n/**\n * 最長の符号長\n * @const\n * @type {number}\n */\nZlib.RawDeflate.MaxCodeLength = 16;\n\n/**\n * ハフマン符号の最大数値\n * @const\n * @type {number}\n */\nZlib.RawDeflate.HUFMAX = 286;\n\n/**\n * 固定ハフマン符号の符号化テーブル\n * @const\n * @type {Array.>}\n */\nZlib.RawDeflate.FixedHuffmanTable = (function() {\n var table = [], i;\n\n for (i = 0; i < 288; i++) {\n switch (true) {\n case (i <= 143): table.push([i + 0x030, 8]); break;\n case (i <= 255): table.push([i - 144 + 0x190, 9]); break;\n case (i <= 279): table.push([i - 256 + 0x000, 7]); break;\n case (i <= 287): table.push([i - 280 + 0x0C0, 8]); break;\n default:\n throw 'invalid literal: ' + i;\n }\n }\n\n return table;\n})();\n\n/**\n * DEFLATE ブロックの作成\n * @return {!(Array.|Uint8Array)} 圧縮済み byte array.\n */\nZlib.RawDeflate.prototype.compress = function() {\n /** @type {!(Array.|Uint8Array)} */\n var blockArray;\n /** @type {number} */\n var position;\n /** @type {number} */\n var length;\n\n var input = this.input;\n\n // compression\n switch (this.compressionType) {\n case Zlib.RawDeflate.CompressionType.NONE:\n // each 65535-Byte (length header: 16-bit)\n for (position = 0, length = input.length; position < length;) {\n blockArray = USE_TYPEDARRAY ?\n input.subarray(position, position + 0xffff) :\n input.slice(position, position + 0xffff);\n position += blockArray.length;\n this.makeNocompressBlock(blockArray, (position === length));\n }\n break;\n case Zlib.RawDeflate.CompressionType.FIXED:\n this.output = this.makeFixedHuffmanBlock(input, true);\n this.op = this.output.length;\n break;\n case Zlib.RawDeflate.CompressionType.DYNAMIC:\n this.output = this.makeDynamicHuffmanBlock(input, true);\n this.op = this.output.length;\n break;\n default:\n throw 'invalid compression type';\n }\n\n return this.output;\n};\n\n/**\n * 非圧縮ブロックの作成\n * @param {!(Array.|Uint8Array)} blockArray ブロックデータ byte array.\n * @param {!boolean} isFinalBlock 最後のブロックならばtrue.\n * @return {!(Array.|Uint8Array)} 非圧縮ブロック byte array.\n */\nZlib.RawDeflate.prototype.makeNocompressBlock =\nfunction(blockArray, isFinalBlock) {\n /** @type {number} */\n var bfinal;\n /** @type {Zlib.RawDeflate.CompressionType} */\n var btype;\n /** @type {number} */\n var len;\n /** @type {number} */\n var nlen;\n /** @type {number} */\n var i;\n /** @type {number} */\n var il;\n\n var output = this.output;\n var op = this.op;\n\n // expand buffer\n if (USE_TYPEDARRAY) {\n output = new Uint8Array(this.output.buffer);\n while (output.length <= op + blockArray.length + 5) {\n output = new Uint8Array(output.length << 1);\n }\n output.set(this.output);\n }\n\n // header\n bfinal = isFinalBlock ? 1 : 0;\n btype = Zlib.RawDeflate.CompressionType.NONE;\n output[op++] = (bfinal) | (btype << 1);\n\n // length\n len = blockArray.length;\n nlen = (~len + 0x10000) & 0xffff;\n output[op++] = len & 0xff;\n output[op++] = (len >>> 8) & 0xff;\n output[op++] = nlen & 0xff;\n output[op++] = (nlen >>> 8) & 0xff;\n\n // copy buffer\n if (USE_TYPEDARRAY) {\n output.set(blockArray, op);\n op += blockArray.length;\n output = output.subarray(0, op);\n } else {\n for (i = 0, il = blockArray.length; i < il; ++i) {\n output[op++] = blockArray[i];\n }\n output.length = op;\n }\n\n this.op = op;\n this.output = output;\n\n return output;\n};\n\n/**\n * 固定ハフマンブロックの作成\n * @param {!(Array.|Uint8Array)} blockArray ブロックデータ byte array.\n * @param {!boolean} isFinalBlock 最後のブロックならばtrue.\n * @return {!(Array.|Uint8Array)} 固定ハフマン符号化ブロック byte array.\n */\nZlib.RawDeflate.prototype.makeFixedHuffmanBlock =\nfunction(blockArray, isFinalBlock) {\n /** @type {Zlib.BitStream} */\n var stream = new Zlib.BitStream(USE_TYPEDARRAY ?\n new Uint8Array(this.output.buffer) : this.output, this.op);\n /** @type {number} */\n var bfinal;\n /** @type {Zlib.RawDeflate.CompressionType} */\n var btype;\n /** @type {!(Array.|Uint16Array)} */\n var data;\n\n // header\n bfinal = isFinalBlock ? 1 : 0;\n btype = Zlib.RawDeflate.CompressionType.FIXED;\n\n stream.writeBits(bfinal, 1, true);\n stream.writeBits(btype, 2, true);\n\n data = this.lz77(blockArray);\n this.fixedHuffman(data, stream);\n\n return stream.finish();\n};\n\n/**\n * 動的ハフマンブロックの作成\n * @param {!(Array.|Uint8Array)} blockArray ブロックデータ byte array.\n * @param {!boolean} isFinalBlock 最後のブロックならばtrue.\n * @return {!(Array.|Uint8Array)} 動的ハフマン符号ブロック byte array.\n */\nZlib.RawDeflate.prototype.makeDynamicHuffmanBlock =\nfunction(blockArray, isFinalBlock) {\n /** @type {Zlib.BitStream} */\n var stream = new Zlib.BitStream(USE_TYPEDARRAY ?\n new Uint8Array(this.output.buffer) : this.output, this.op);\n /** @type {number} */\n var bfinal;\n /** @type {Zlib.RawDeflate.CompressionType} */\n var btype;\n /** @type {!(Array.|Uint16Array)} */\n var data;\n /** @type {number} */\n var hlit;\n /** @type {number} */\n var hdist;\n /** @type {number} */\n var hclen;\n /** @const @type {Array.} */\n var hclenOrder =\n [16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15];\n /** @type {!(Array.|Uint8Array)} */\n var litLenLengths;\n /** @type {!(Array.|Uint16Array)} */\n var litLenCodes;\n /** @type {!(Array.|Uint8Array)} */\n var distLengths;\n /** @type {!(Array.|Uint16Array)} */\n var distCodes;\n /** @type {{\n * codes: !(Array.|Uint32Array),\n * freqs: !(Array.|Uint8Array)\n * }} */\n var treeSymbols;\n /** @type {!(Array.|Uint8Array)} */\n var treeLengths;\n /** @type {Array} */\n var transLengths = new Array(19);\n /** @type {!(Array.|Uint16Array)} */\n var treeCodes;\n /** @type {number} */\n var code;\n /** @type {number} */\n var bitlen;\n /** @type {number} */\n var i;\n /** @type {number} */\n var il;\n\n // header\n bfinal = isFinalBlock ? 1 : 0;\n btype = Zlib.RawDeflate.CompressionType.DYNAMIC;\n\n stream.writeBits(bfinal, 1, true);\n stream.writeBits(btype, 2, true);\n\n data = this.lz77(blockArray);\n\n // リテラル・長さ, 距離のハフマン符号と符号長の算出\n litLenLengths = this.getLengths_(this.freqsLitLen, 15);\n litLenCodes = this.getCodesFromLengths_(litLenLengths);\n distLengths = this.getLengths_(this.freqsDist, 7);\n distCodes = this.getCodesFromLengths_(distLengths);\n\n // HLIT, HDIST の決定\n for (hlit = 286; hlit > 257 && litLenLengths[hlit - 1] === 0; hlit--) {}\n for (hdist = 30; hdist > 1 && distLengths[hdist - 1] === 0; hdist--) {}\n\n // HCLEN\n treeSymbols =\n this.getTreeSymbols_(hlit, litLenLengths, hdist, distLengths);\n treeLengths = this.getLengths_(treeSymbols.freqs, 7);\n for (i = 0; i < 19; i++) {\n transLengths[i] = treeLengths[hclenOrder[i]];\n }\n for (hclen = 19; hclen > 4 && transLengths[hclen - 1] === 0; hclen--) {}\n\n treeCodes = this.getCodesFromLengths_(treeLengths);\n\n // 出力\n stream.writeBits(hlit - 257, 5, true);\n stream.writeBits(hdist - 1, 5, true);\n stream.writeBits(hclen - 4, 4, true);\n for (i = 0; i < hclen; i++) {\n stream.writeBits(transLengths[i], 3, true);\n }\n\n // ツリーの出力\n for (i = 0, il = treeSymbols.codes.length; i < il; i++) {\n code = treeSymbols.codes[i];\n\n stream.writeBits(treeCodes[code], treeLengths[code], true);\n\n // extra bits\n if (code >= 16) {\n i++;\n switch (code) {\n case 16: bitlen = 2; break;\n case 17: bitlen = 3; break;\n case 18: bitlen = 7; break;\n default:\n throw 'invalid code: ' + code;\n }\n\n stream.writeBits(treeSymbols.codes[i], bitlen, true);\n }\n }\n\n this.dynamicHuffman(\n data,\n [litLenCodes, litLenLengths],\n [distCodes, distLengths],\n stream\n );\n\n return stream.finish();\n};\n\n\n/**\n * 動的ハフマン符号化(カスタムハフマンテーブル)\n * @param {!(Array.|Uint16Array)} dataArray LZ77 符号化済み byte array.\n * @param {!Zlib.BitStream} stream 書き込み用ビットストリーム.\n * @return {!Zlib.BitStream} ハフマン符号化済みビットストリームオブジェクト.\n */\nZlib.RawDeflate.prototype.dynamicHuffman =\nfunction(dataArray, litLen, dist, stream) {\n /** @type {number} */\n var index;\n /** @type {number} */\n var length;\n /** @type {number} */\n var literal;\n /** @type {number} */\n var code;\n /** @type {number} */\n var litLenCodes;\n /** @type {number} */\n var litLenLengths;\n /** @type {number} */\n var distCodes;\n /** @type {number} */\n var distLengths;\n\n litLenCodes = litLen[0];\n litLenLengths = litLen[1];\n distCodes = dist[0];\n distLengths = dist[1];\n\n // 符号を BitStream に書き込んでいく\n for (index = 0, length = dataArray.length; index < length; ++index) {\n literal = dataArray[index];\n\n // literal or length\n stream.writeBits(litLenCodes[literal], litLenLengths[literal], true);\n\n // 長さ・距離符号\n if (literal > 256) {\n // length extra\n stream.writeBits(dataArray[++index], dataArray[++index], true);\n // distance\n code = dataArray[++index];\n stream.writeBits(distCodes[code], distLengths[code], true);\n // distance extra\n stream.writeBits(dataArray[++index], dataArray[++index], true);\n // 終端\n } else if (literal === 256) {\n break;\n }\n }\n\n return stream;\n};\n\n/**\n * 固定ハフマン符号化\n * @param {!(Array.|Uint16Array)} dataArray LZ77 符号化済み byte array.\n * @param {!Zlib.BitStream} stream 書き込み用ビットストリーム.\n * @return {!Zlib.BitStream} ハフマン符号化済みビットストリームオブジェクト.\n */\nZlib.RawDeflate.prototype.fixedHuffman = function(dataArray, stream) {\n /** @type {number} */\n var index;\n /** @type {number} */\n var length;\n /** @type {number} */\n var literal;\n\n // 符号を BitStream に書き込んでいく\n for (index = 0, length = dataArray.length; index < length; index++) {\n literal = dataArray[index];\n\n // 符号の書き込み\n Zlib.BitStream.prototype.writeBits.apply(\n stream,\n Zlib.RawDeflate.FixedHuffmanTable[literal]\n );\n\n // 長さ・距離符号\n if (literal > 0x100) {\n // length extra\n stream.writeBits(dataArray[++index], dataArray[++index], true);\n // distance\n stream.writeBits(dataArray[++index], 5);\n // distance extra\n stream.writeBits(dataArray[++index], dataArray[++index], true);\n // 終端\n } else if (literal === 0x100) {\n break;\n }\n }\n\n return stream;\n};\n\n/**\n * マッチ情報\n * @param {!number} length マッチした長さ.\n * @param {!number} backwardDistance マッチ位置との距離.\n * @constructor\n */\nZlib.RawDeflate.Lz77Match = function(length, backwardDistance) {\n /** @type {number} match length. */\n this.length = length;\n /** @type {number} backward distance. */\n this.backwardDistance = backwardDistance;\n};\n\n/**\n * 長さ符号テーブル.\n * [コード, 拡張ビット, 拡張ビット長] の配列となっている.\n * @const\n * @type {!(Array.|Uint32Array)}\n */\nZlib.RawDeflate.Lz77Match.LengthCodeTable = (function(table) {\n return USE_TYPEDARRAY ? new Uint32Array(table) : table;\n})((function() {\n /** @type {!Array} */\n var table = [];\n /** @type {number} */\n var i;\n /** @type {!Array.} */\n var c;\n\n for (i = 3; i <= 258; i++) {\n c = code(i);\n table[i] = (c[2] << 24) | (c[1] << 16) | c[0];\n }\n\n /**\n * @param {number} length lz77 length.\n * @return {!Array.} lz77 codes.\n */\n function code(length) {\n switch (true) {\n case (length === 3): return [257, length - 3, 0]; break;\n case (length === 4): return [258, length - 4, 0]; break;\n case (length === 5): return [259, length - 5, 0]; break;\n case (length === 6): return [260, length - 6, 0]; break;\n case (length === 7): return [261, length - 7, 0]; break;\n case (length === 8): return [262, length - 8, 0]; break;\n case (length === 9): return [263, length - 9, 0]; break;\n case (length === 10): return [264, length - 10, 0]; break;\n case (length <= 12): return [265, length - 11, 1]; break;\n case (length <= 14): return [266, length - 13, 1]; break;\n case (length <= 16): return [267, length - 15, 1]; break;\n case (length <= 18): return [268, length - 17, 1]; break;\n case (length <= 22): return [269, length - 19, 2]; break;\n case (length <= 26): return [270, length - 23, 2]; break;\n case (length <= 30): return [271, length - 27, 2]; break;\n case (length <= 34): return [272, length - 31, 2]; break;\n case (length <= 42): return [273, length - 35, 3]; break;\n case (length <= 50): return [274, length - 43, 3]; break;\n case (length <= 58): return [275, length - 51, 3]; break;\n case (length <= 66): return [276, length - 59, 3]; break;\n case (length <= 82): return [277, length - 67, 4]; break;\n case (length <= 98): return [278, length - 83, 4]; break;\n case (length <= 114): return [279, length - 99, 4]; break;\n case (length <= 130): return [280, length - 115, 4]; break;\n case (length <= 162): return [281, length - 131, 5]; break;\n case (length <= 194): return [282, length - 163, 5]; break;\n case (length <= 226): return [283, length - 195, 5]; break;\n case (length <= 257): return [284, length - 227, 5]; break;\n case (length === 258): return [285, length - 258, 0]; break;\n default: throw 'invalid length: ' + length;\n }\n }\n\n return table;\n})());\n\n/**\n * 距離符号テーブル\n * @param {!number} dist 距離.\n * @return {!Array.} コード、拡張ビット、拡張ビット長の配列.\n * @private\n */\nZlib.RawDeflate.Lz77Match.prototype.getDistanceCode_ = function(dist) {\n /** @type {!Array.} distance code table. */\n var r;\n\n switch (true) {\n case (dist === 1): r = [0, dist - 1, 0]; break;\n case (dist === 2): r = [1, dist - 2, 0]; break;\n case (dist === 3): r = [2, dist - 3, 0]; break;\n case (dist === 4): r = [3, dist - 4, 0]; break;\n case (dist <= 6): r = [4, dist - 5, 1]; break;\n case (dist <= 8): r = [5, dist - 7, 1]; break;\n case (dist <= 12): r = [6, dist - 9, 2]; break;\n case (dist <= 16): r = [7, dist - 13, 2]; break;\n case (dist <= 24): r = [8, dist - 17, 3]; break;\n case (dist <= 32): r = [9, dist - 25, 3]; break;\n case (dist <= 48): r = [10, dist - 33, 4]; break;\n case (dist <= 64): r = [11, dist - 49, 4]; break;\n case (dist <= 96): r = [12, dist - 65, 5]; break;\n case (dist <= 128): r = [13, dist - 97, 5]; break;\n case (dist <= 192): r = [14, dist - 129, 6]; break;\n case (dist <= 256): r = [15, dist - 193, 6]; break;\n case (dist <= 384): r = [16, dist - 257, 7]; break;\n case (dist <= 512): r = [17, dist - 385, 7]; break;\n case (dist <= 768): r = [18, dist - 513, 8]; break;\n case (dist <= 1024): r = [19, dist - 769, 8]; break;\n case (dist <= 1536): r = [20, dist - 1025, 9]; break;\n case (dist <= 2048): r = [21, dist - 1537, 9]; break;\n case (dist <= 3072): r = [22, dist - 2049, 10]; break;\n case (dist <= 4096): r = [23, dist - 3073, 10]; break;\n case (dist <= 6144): r = [24, dist - 4097, 11]; break;\n case (dist <= 8192): r = [25, dist - 6145, 11]; break;\n case (dist <= 12288): r = [26, dist - 8193, 12]; break;\n case (dist <= 16384): r = [27, dist - 12289, 12]; break;\n case (dist <= 24576): r = [28, dist - 16385, 13]; break;\n case (dist <= 32768): r = [29, dist - 24577, 13]; break;\n default: throw 'invalid distance';\n }\n\n return r;\n};\n\n/**\n * マッチ情報を LZ77 符号化配列で返す.\n * なお、ここでは以下の内部仕様で符号化している\n * [ CODE, EXTRA-BIT-LEN, EXTRA, CODE, EXTRA-BIT-LEN, EXTRA ]\n * @return {!Array.} LZ77 符号化 byte array.\n */\nZlib.RawDeflate.Lz77Match.prototype.toLz77Array = function() {\n /** @type {number} */\n var length = this.length;\n /** @type {number} */\n var dist = this.backwardDistance;\n /** @type {Array} */\n var codeArray = [];\n /** @type {number} */\n var pos = 0;\n /** @type {!Array.} */\n var code;\n\n // length\n code = Zlib.RawDeflate.Lz77Match.LengthCodeTable[length];\n codeArray[pos++] = code & 0xffff;\n codeArray[pos++] = (code >> 16) & 0xff;\n codeArray[pos++] = code >> 24;\n\n // distance\n code = this.getDistanceCode_(dist);\n codeArray[pos++] = code[0];\n codeArray[pos++] = code[1];\n codeArray[pos++] = code[2];\n\n return codeArray;\n};\n\n/**\n * LZ77 実装\n * @param {!(Array.|Uint8Array)} dataArray LZ77 符号化するバイト配列.\n * @return {!(Array.|Uint16Array)} LZ77 符号化した配列.\n */\nZlib.RawDeflate.prototype.lz77 = function(dataArray) {\n /** @type {number} input position */\n var position;\n /** @type {number} input length */\n var length;\n /** @type {number} loop counter */\n var i;\n /** @type {number} loop limiter */\n var il;\n /** @type {number} chained-hash-table key */\n var matchKey;\n /** @type {Object.>} chained-hash-table */\n var table = {};\n /** @const @type {number} */\n var windowSize = Zlib.RawDeflate.WindowSize;\n /** @type {Array.} match list */\n var matchList;\n /** @type {Zlib.RawDeflate.Lz77Match} longest match */\n var longestMatch;\n /** @type {Zlib.RawDeflate.Lz77Match} previous longest match */\n var prevMatch;\n /** @type {!(Array.|Uint16Array)} lz77 buffer */\n var lz77buf = USE_TYPEDARRAY ?\n new Uint16Array(dataArray.length * 2) : [];\n /** @type {number} lz77 output buffer pointer */\n var pos = 0;\n /** @type {number} lz77 skip length */\n var skipLength = 0;\n /** @type {!(Array.|Uint32Array)} */\n var freqsLitLen = new (USE_TYPEDARRAY ? Uint32Array : Array)(286);\n /** @type {!(Array.|Uint32Array)} */\n var freqsDist = new (USE_TYPEDARRAY ? Uint32Array : Array)(30);\n /** @type {number} */\n var lazy = this.lazy;\n /** @type {*} temporary variable */\n var tmp;\n\n // 初期化\n if (!USE_TYPEDARRAY) {\n for (i = 0; i <= 285;) { freqsLitLen[i++] = 0; }\n for (i = 0; i <= 29;) { freqsDist[i++] = 0; }\n }\n freqsLitLen[256] = 1; // EOB の最低出現回数は 1\n\n /**\n * マッチデータの書き込み\n * @param {Zlib.RawDeflate.Lz77Match} match LZ77 Match data.\n * @param {!number} offset スキップ開始位置(相対指定).\n * @private\n */\n function writeMatch(match, offset) {\n /** @type {Array.} */\n var lz77Array = match.toLz77Array();\n /** @type {number} */\n var i;\n /** @type {number} */\n var il;\n\n for (i = 0, il = lz77Array.length; i < il; ++i) {\n lz77buf[pos++] = lz77Array[i];\n }\n freqsLitLen[lz77Array[0]]++;\n freqsDist[lz77Array[3]]++;\n skipLength = match.length + offset - 1;\n prevMatch = null;\n }\n\n // LZ77 符号化\n for (position = 0, length = dataArray.length; position < length; ++position) {\n // ハッシュキーの作成\n for (matchKey = 0, i = 0, il = Zlib.RawDeflate.Lz77MinLength; i < il; ++i) {\n if (position + i === length) {\n break;\n }\n matchKey = (matchKey << 8) | dataArray[position + i];\n }\n\n // テーブルが未定義だったら作成する\n if (table[matchKey] === void 0) { table[matchKey] = []; }\n matchList = table[matchKey];\n\n // skip\n if (skipLength-- > 0) {\n matchList.push(position);\n continue;\n }\n\n // マッチテーブルの更新 (最大戻り距離を超えているものを削除する)\n while (matchList.length > 0 && position - matchList[0] > windowSize) {\n matchList.shift();\n }\n\n // データ末尾でマッチしようがない場合はそのまま流しこむ\n if (position + Zlib.RawDeflate.Lz77MinLength >= length) {\n if (prevMatch) {\n writeMatch(prevMatch, -1);\n }\n\n for (i = 0, il = length - position; i < il; ++i) {\n tmp = dataArray[position + i];\n lz77buf[pos++] = tmp;\n ++freqsLitLen[tmp];\n }\n break;\n }\n\n // マッチ候補から最長のものを探す\n if (matchList.length > 0) {\n longestMatch = this.searchLongestMatch_(dataArray, position, matchList);\n\n if (prevMatch) {\n // 現在のマッチの方が前回のマッチよりも長い\n if (prevMatch.length < longestMatch.length) {\n // write previous literal\n tmp = dataArray[position - 1];\n lz77buf[pos++] = tmp;\n ++freqsLitLen[tmp];\n\n // write current match\n writeMatch(longestMatch, 0);\n } else {\n // write previous match\n writeMatch(prevMatch, -1);\n }\n } else if (longestMatch.length < lazy) {\n prevMatch = longestMatch;\n } else {\n writeMatch(longestMatch, 0);\n }\n // 前回マッチしていて今回マッチがなかったら前回のを採用\n } else if (prevMatch) {\n writeMatch(prevMatch, -1);\n } else {\n tmp = dataArray[position];\n lz77buf[pos++] = tmp;\n ++freqsLitLen[tmp];\n }\n\n matchList.push(position); // マッチテーブルに現在の位置を保存\n }\n\n // 終端処理\n lz77buf[pos++] = 256;\n freqsLitLen[256]++;\n this.freqsLitLen = freqsLitLen;\n this.freqsDist = freqsDist;\n\n return /** @type {!(Uint16Array|Array.)} */ (\n USE_TYPEDARRAY ? lz77buf.subarray(0, pos) : lz77buf\n );\n};\n\n/**\n * マッチした候補の中から最長一致を探す\n * @param {!Object} data plain data byte array.\n * @param {!number} position plain data byte array position.\n * @param {!Array.} matchList 候補となる位置の配列.\n * @return {!Zlib.RawDeflate.Lz77Match} 最長かつ最短距離のマッチオブジェクト.\n * @private\n */\nZlib.RawDeflate.prototype.searchLongestMatch_ =\nfunction(data, position, matchList) {\n var match,\n currentMatch,\n matchMax = 0, matchLength,\n i, j, l, dl = data.length;\n\n // 候補を後ろから 1 つずつ絞り込んでゆく\n permatch:\n for (i = 0, l = matchList.length; i < l; i++) {\n match = matchList[l - i - 1];\n matchLength = Zlib.RawDeflate.Lz77MinLength;\n\n // 前回までの最長一致を末尾から一致検索する\n if (matchMax > Zlib.RawDeflate.Lz77MinLength) {\n for (j = matchMax; j > Zlib.RawDeflate.Lz77MinLength; j--) {\n if (data[match + j - 1] !== data[position + j - 1]) {\n continue permatch;\n }\n }\n matchLength = matchMax;\n }\n\n // 最長一致探索\n while (matchLength < Zlib.RawDeflate.Lz77MaxLength &&\n position + matchLength < dl &&\n data[match + matchLength] === data[position + matchLength]) {\n ++matchLength;\n }\n\n // マッチ長が同じ場合は後方を優先\n if (matchLength > matchMax) {\n currentMatch = match;\n matchMax = matchLength;\n }\n\n // 最長が確定したら後の処理は省略\n if (matchLength === Zlib.RawDeflate.Lz77MaxLength) {\n break;\n }\n }\n\n return new Zlib.RawDeflate.Lz77Match(matchMax, position - currentMatch);\n};\n\n/**\n * Tree-Transmit Symbols の算出\n * reference: PuTTY Deflate implementation\n * @param {number} hlit HLIT.\n * @param {!(Array.|Uint8Array)} litlenLengths リテラルと長さ符号の符号長配列.\n * @param {number} hdist HDIST.\n * @param {!(Array.|Uint8Array)} distLengths 距離符号の符号長配列.\n * @return {{\n * codes: !(Array.|Uint32Array),\n * freqs: !(Array.|Uint8Array)\n * }} Tree-Transmit Symbols.\n */\nZlib.RawDeflate.prototype.getTreeSymbols_ =\nfunction(hlit, litlenLengths, hdist, distLengths) {\n var src = new (USE_TYPEDARRAY ? Uint32Array : Array)(hlit + hdist),\n i, j, runLength, l,\n result = new (USE_TYPEDARRAY ? Uint32Array : Array)(286 + 30),\n nResult,\n rpt,\n freqs = new (USE_TYPEDARRAY ? Uint8Array : Array)(19);\n\n j = 0;\n for (i = 0; i < hlit; i++) {\n src[j++] = litlenLengths[i];\n }\n for (i = 0; i < hdist; i++) {\n src[j++] = distLengths[i];\n }\n\n // 初期化\n if (!USE_TYPEDARRAY) {\n for (i = 0, l = freqs.length; i < l; ++i) {\n freqs[i] = 0;\n }\n }\n\n // 符号化\n nResult = 0;\n for (i = 0, l = src.length; i < l; i += j) {\n // Run Length Encoding\n for (j = 1; i + j < l && src[i + j] === src[i]; ++j) {}\n\n runLength = j;\n\n if (src[i] === 0) {\n // 0 の繰り返しが 3 回未満ならばそのまま\n if (runLength < 3) {\n while (runLength-- > 0) {\n result[nResult++] = 0;\n freqs[0]++;\n }\n } else {\n while (runLength > 0) {\n // 繰り返しは最大 138 までなので切り詰める\n rpt = (runLength < 138 ? runLength : 138);\n\n if (rpt > runLength - 3 && rpt < runLength) {\n rpt = runLength - 3;\n }\n\n // 3-10 回 -> 17\n if (rpt <= 10) {\n result[nResult++] = 17;\n result[nResult++] = rpt - 3;\n freqs[17]++;\n // 11-138 回 -> 18\n } else {\n result[nResult++] = 18;\n result[nResult++] = rpt - 11;\n freqs[18]++;\n }\n\n runLength -= rpt;\n }\n }\n } else {\n result[nResult++] = src[i];\n freqs[src[i]]++;\n runLength--;\n\n // 繰り返し回数が3回未満ならばランレングス符号は要らない\n if (runLength < 3) {\n while (runLength-- > 0) {\n result[nResult++] = src[i];\n freqs[src[i]]++;\n }\n // 3 回以上ならばランレングス符号化\n } else {\n while (runLength > 0) {\n // runLengthを 3-6 で分割\n rpt = (runLength < 6 ? runLength : 6);\n\n if (rpt > runLength - 3 && rpt < runLength) {\n rpt = runLength - 3;\n }\n\n result[nResult++] = 16;\n result[nResult++] = rpt - 3;\n freqs[16]++;\n\n runLength -= rpt;\n }\n }\n }\n }\n\n return {\n codes:\n USE_TYPEDARRAY ? result.subarray(0, nResult) : result.slice(0, nResult),\n freqs: freqs\n };\n};\n\n/**\n * ハフマン符号の長さを取得する\n * @param {!(Array.|Uint8Array|Uint32Array)} freqs 出現カウント.\n * @param {number} limit 符号長の制限.\n * @return {!(Array.|Uint8Array)} 符号長配列.\n * @private\n */\nZlib.RawDeflate.prototype.getLengths_ = function(freqs, limit) {\n /** @type {number} */\n var nSymbols = freqs.length;\n /** @type {Zlib.Heap} */\n var heap = new Zlib.Heap(2 * Zlib.RawDeflate.HUFMAX);\n /** @type {!(Array.|Uint8Array)} */\n var length = new (USE_TYPEDARRAY ? Uint8Array : Array)(nSymbols);\n /** @type {Array} */\n var nodes;\n /** @type {!(Array.|Uint32Array)} */\n var values;\n /** @type {!(Array.|Uint8Array)} */\n var codeLength;\n /** @type {number} */\n var i;\n /** @type {number} */\n var il;\n\n // 配列の初期化\n if (!USE_TYPEDARRAY) {\n for (i = 0; i < nSymbols; i++) {\n length[i] = 0;\n }\n }\n\n // ヒープの構築\n for (i = 0; i < nSymbols; ++i) {\n if (freqs[i] > 0) {\n heap.push(i, freqs[i]);\n }\n }\n nodes = new Array(heap.length / 2);\n values = new (USE_TYPEDARRAY ? Uint32Array : Array)(heap.length / 2);\n\n // 非 0 の要素が一つだけだった場合は、そのシンボルに符号長 1 を割り当てて終了\n if (nodes.length === 1) {\n length[heap.pop().index] = 1;\n return length;\n }\n\n // Reverse Package Merge Algorithm による Canonical Huffman Code の符号長決定\n for (i = 0, il = heap.length / 2; i < il; ++i) {\n nodes[i] = heap.pop();\n values[i] = nodes[i].value;\n }\n codeLength = this.reversePackageMerge_(values, values.length, limit);\n\n for (i = 0, il = nodes.length; i < il; ++i) {\n length[nodes[i].index] = codeLength[i];\n }\n\n return length;\n};\n\n/**\n * Reverse Package Merge Algorithm.\n * @param {!(Array.|Uint32Array)} freqs sorted probability.\n * @param {number} symbols number of symbols.\n * @param {number} limit code length limit.\n * @return {!(Array.|Uint8Array)} code lengths.\n */\nZlib.RawDeflate.prototype.reversePackageMerge_ = function(freqs, symbols, limit) {\n /** @type {!(Array.|Uint16Array)} */\n var minimumCost = new (USE_TYPEDARRAY ? Uint16Array : Array)(limit);\n /** @type {!(Array.|Uint8Array)} */\n var flag = new (USE_TYPEDARRAY ? Uint8Array : Array)(limit);\n /** @type {!(Array.|Uint8Array)} */\n var codeLength = new (USE_TYPEDARRAY ? Uint8Array : Array)(symbols);\n /** @type {Array} */\n var value = new Array(limit);\n /** @type {Array} */\n var type = new Array(limit);\n /** @type {Array.} */\n var currentPosition = new Array(limit);\n /** @type {number} */\n var excess = (1 << limit) - symbols;\n /** @type {number} */\n var half = (1 << (limit - 1));\n /** @type {number} */\n var i;\n /** @type {number} */\n var j;\n /** @type {number} */\n var t;\n /** @type {number} */\n var weight;\n /** @type {number} */\n var next;\n\n /**\n * @param {number} j\n */\n function takePackage(j) {\n /** @type {number} */\n var x = type[j][currentPosition[j]];\n\n if (x === symbols) {\n takePackage(j+1);\n takePackage(j+1);\n } else {\n --codeLength[x];\n }\n\n ++currentPosition[j];\n }\n\n minimumCost[limit-1] = symbols;\n\n for (j = 0; j < limit; ++j) {\n if (excess < half) {\n flag[j] = 0;\n } else {\n flag[j] = 1;\n excess -= half;\n }\n excess <<= 1;\n minimumCost[limit-2-j] = (minimumCost[limit-1-j] / 2 | 0) + symbols;\n }\n minimumCost[0] = flag[0];\n\n value[0] = new Array(minimumCost[0]);\n type[0] = new Array(minimumCost[0]);\n for (j = 1; j < limit; ++j) {\n if (minimumCost[j] > 2 * minimumCost[j-1] + flag[j]) {\n minimumCost[j] = 2 * minimumCost[j-1] + flag[j];\n }\n value[j] = new Array(minimumCost[j]);\n type[j] = new Array(minimumCost[j]);\n }\n\n for (i = 0; i < symbols; ++i) {\n codeLength[i] = limit;\n }\n\n for (t = 0; t < minimumCost[limit-1]; ++t) {\n value[limit-1][t] = freqs[t];\n type[limit-1][t] = t;\n }\n\n for (i = 0; i < limit; ++i) {\n currentPosition[i] = 0;\n }\n if (flag[limit-1] === 1) {\n --codeLength[0];\n ++currentPosition[limit-1];\n }\n\n for (j = limit-2; j >= 0; --j) {\n i = 0;\n weight = 0;\n next = currentPosition[j+1];\n\n for (t = 0; t < minimumCost[j]; t++) {\n weight = value[j+1][next] + value[j+1][next+1];\n\n if (weight > freqs[i]) {\n value[j][t] = weight;\n type[j][t] = symbols;\n next += 2;\n } else {\n value[j][t] = freqs[i];\n type[j][t] = i;\n ++i;\n }\n }\n\n currentPosition[j] = 0;\n if (flag[j] === 1) {\n takePackage(j);\n }\n }\n\n return codeLength;\n};\n\n/**\n * 符号長配列からハフマン符号を取得する\n * reference: PuTTY Deflate implementation\n * @param {!(Array.|Uint8Array)} lengths 符号長配列.\n * @return {!(Array.|Uint16Array)} ハフマン符号配列.\n * @private\n */\nZlib.RawDeflate.prototype.getCodesFromLengths_ = function(lengths) {\n var codes = new (USE_TYPEDARRAY ? Uint16Array : Array)(lengths.length),\n count = [],\n startCode = [],\n code = 0, i, il, j, m;\n\n // Count the codes of each length.\n for (i = 0, il = lengths.length; i < il; i++) {\n count[lengths[i]] = (count[lengths[i]] | 0) + 1;\n }\n\n // Determine the starting code for each length block.\n for (i = 1, il = Zlib.RawDeflate.MaxCodeLength; i <= il; i++) {\n startCode[i] = code;\n code += count[i] | 0;\n code <<= 1;\n }\n\n // Determine the code for each symbol. Mirrored, of course.\n for (i = 0, il = lengths.length; i < il; i++) {\n code = startCode[lengths[i]];\n startCode[lengths[i]] += 1;\n codes[i] = 0;\n\n for (j = 0, m = lengths[i]; j < m; j++) {\n codes[i] = (codes[i] << 1) | (code & 1);\n code >>>= 1;\n }\n }\n\n return codes;\n};\n\n\n/**\n * @param {!(Array.|Uint8Array)} input input buffer.\n * @param {Object=} opt_params options.\n * @constructor\n */\nZlib.Unzip = function(input, opt_params) {\n opt_params = opt_params || {};\n /** @type {!(Array.|Uint8Array)} */\n this.input =\n (USE_TYPEDARRAY && (input instanceof Array)) ?\n new Uint8Array(input) : input;\n /** @type {number} */\n this.ip = 0;\n /** @type {number} */\n this.eocdrOffset;\n /** @type {number} */\n this.numberOfThisDisk;\n /** @type {number} */\n this.startDisk;\n /** @type {number} */\n this.totalEntriesThisDisk;\n /** @type {number} */\n this.totalEntries;\n /** @type {number} */\n this.centralDirectorySize;\n /** @type {number} */\n this.centralDirectoryOffset;\n /** @type {number} */\n this.commentLength;\n /** @type {(Array.|Uint8Array)} */\n this.comment;\n /** @type {Array.} */\n this.fileHeaderList;\n /** @type {Object.} */\n this.filenameToIndex;\n /** @type {boolean} */\n this.verify = opt_params['verify'] || false;\n /** @type {(Array.|Uint8Array)} */\n this.password = opt_params['password'];\n};\n\nZlib.Unzip.CompressionMethod = Zlib.Zip.CompressionMethod;\n\n/**\n * @type {Array.}\n * @const\n */\nZlib.Unzip.FileHeaderSignature = Zlib.Zip.FileHeaderSignature;\n\n/**\n * @type {Array.}\n * @const\n */\nZlib.Unzip.LocalFileHeaderSignature = Zlib.Zip.LocalFileHeaderSignature;\n\n/**\n * @type {Array.}\n * @const\n */\nZlib.Unzip.CentralDirectorySignature = Zlib.Zip.CentralDirectorySignature;\n\n/**\n * @param {!(Array.|Uint8Array)} input input buffer.\n * @param {number} ip input position.\n * @constructor\n */\nZlib.Unzip.FileHeader = function(input, ip) {\n /** @type {!(Array.|Uint8Array)} */\n this.input = input;\n /** @type {number} */\n this.offset = ip;\n /** @type {number} */\n this.length;\n /** @type {number} */\n this.version;\n /** @type {number} */\n this.os;\n /** @type {number} */\n this.needVersion;\n /** @type {number} */\n this.flags;\n /** @type {number} */\n this.compression;\n /** @type {number} */\n this.time;\n /** @type {number} */\n this.date;\n /** @type {number} */\n this.crc32;\n /** @type {number} */\n this.compressedSize;\n /** @type {number} */\n this.plainSize;\n /** @type {number} */\n this.fileNameLength;\n /** @type {number} */\n this.extraFieldLength;\n /** @type {number} */\n this.fileCommentLength;\n /** @type {number} */\n this.diskNumberStart;\n /** @type {number} */\n this.internalFileAttributes;\n /** @type {number} */\n this.externalFileAttributes;\n /** @type {number} */\n this.relativeOffset;\n /** @type {string} */\n this.filename;\n /** @type {!(Array.|Uint8Array)} */\n this.extraField;\n /** @type {!(Array.|Uint8Array)} */\n this.comment;\n};\n\nZlib.Unzip.FileHeader.prototype.parse = function() {\n /** @type {!(Array.|Uint8Array)} */\n var input = this.input;\n /** @type {number} */\n var ip = this.offset;\n\n // central file header signature\n if (input[ip++] !== Zlib.Unzip.FileHeaderSignature[0] ||\n input[ip++] !== Zlib.Unzip.FileHeaderSignature[1] ||\n input[ip++] !== Zlib.Unzip.FileHeaderSignature[2] ||\n input[ip++] !== Zlib.Unzip.FileHeaderSignature[3]) {\n throw new Error('invalid file header signature');\n }\n\n // version made by\n this.version = input[ip++];\n this.os = input[ip++];\n\n // version needed to extract\n this.needVersion = input[ip++] | (input[ip++] << 8);\n\n // general purpose bit flag\n this.flags = input[ip++] | (input[ip++] << 8);\n\n // compression method\n this.compression = input[ip++] | (input[ip++] << 8);\n\n // last mod file time\n this.time = input[ip++] | (input[ip++] << 8);\n\n //last mod file date\n this.date = input[ip++] | (input[ip++] << 8);\n\n // crc-32\n this.crc32 = (\n (input[ip++] ) | (input[ip++] << 8) |\n (input[ip++] << 16) | (input[ip++] << 24)\n ) >>> 0;\n\n // compressed size\n this.compressedSize = (\n (input[ip++] ) | (input[ip++] << 8) |\n (input[ip++] << 16) | (input[ip++] << 24)\n ) >>> 0;\n\n // uncompressed size\n this.plainSize = (\n (input[ip++] ) | (input[ip++] << 8) |\n (input[ip++] << 16) | (input[ip++] << 24)\n ) >>> 0;\n\n // file name length\n this.fileNameLength = input[ip++] | (input[ip++] << 8);\n\n // extra field length\n this.extraFieldLength = input[ip++] | (input[ip++] << 8);\n\n // file comment length\n this.fileCommentLength = input[ip++] | (input[ip++] << 8);\n\n // disk number start\n this.diskNumberStart = input[ip++] | (input[ip++] << 8);\n\n // internal file attributes\n this.internalFileAttributes = input[ip++] | (input[ip++] << 8);\n\n // external file attributes\n this.externalFileAttributes =\n (input[ip++] ) | (input[ip++] << 8) |\n (input[ip++] << 16) | (input[ip++] << 24);\n\n // relative offset of local header\n this.relativeOffset = (\n (input[ip++] ) | (input[ip++] << 8) |\n (input[ip++] << 16) | (input[ip++] << 24)\n ) >>> 0;\n\n // file name\n this.filename = String.fromCharCode.apply(null, USE_TYPEDARRAY ?\n input.subarray(ip, ip += this.fileNameLength) :\n input.slice(ip, ip += this.fileNameLength)\n );\n\n // extra field\n this.extraField = USE_TYPEDARRAY ?\n input.subarray(ip, ip += this.extraFieldLength) :\n input.slice(ip, ip += this.extraFieldLength);\n\n // file comment\n this.comment = USE_TYPEDARRAY ?\n input.subarray(ip, ip + this.fileCommentLength) :\n input.slice(ip, ip + this.fileCommentLength);\n\n this.length = ip - this.offset;\n};\n\n/**\n * @param {!(Array.|Uint8Array)} input input buffer.\n * @param {number} ip input position.\n * @constructor\n */\nZlib.Unzip.LocalFileHeader = function(input, ip) {\n /** @type {!(Array.|Uint8Array)} */\n this.input = input;\n /** @type {number} */\n this.offset = ip;\n /** @type {number} */\n this.length;\n /** @type {number} */\n this.needVersion;\n /** @type {number} */\n this.flags;\n /** @type {number} */\n this.compression;\n /** @type {number} */\n this.time;\n /** @type {number} */\n this.date;\n /** @type {number} */\n this.crc32;\n /** @type {number} */\n this.compressedSize;\n /** @type {number} */\n this.plainSize;\n /** @type {number} */\n this.fileNameLength;\n /** @type {number} */\n this.extraFieldLength;\n /** @type {string} */\n this.filename;\n /** @type {!(Array.|Uint8Array)} */\n this.extraField;\n};\n\nZlib.Unzip.LocalFileHeader.Flags = Zlib.Zip.Flags;\n\nZlib.Unzip.LocalFileHeader.prototype.parse = function() {\n /** @type {!(Array.|Uint8Array)} */\n var input = this.input;\n /** @type {number} */\n var ip = this.offset;\n\n // local file header signature\n if (input[ip++] !== Zlib.Unzip.LocalFileHeaderSignature[0] ||\n input[ip++] !== Zlib.Unzip.LocalFileHeaderSignature[1] ||\n input[ip++] !== Zlib.Unzip.LocalFileHeaderSignature[2] ||\n input[ip++] !== Zlib.Unzip.LocalFileHeaderSignature[3]) {\n throw new Error('invalid local file header signature');\n }\n\n // version needed to extract\n this.needVersion = input[ip++] | (input[ip++] << 8);\n\n // general purpose bit flag\n this.flags = input[ip++] | (input[ip++] << 8);\n\n // compression method\n this.compression = input[ip++] | (input[ip++] << 8);\n\n // last mod file time\n this.time = input[ip++] | (input[ip++] << 8);\n\n //last mod file date\n this.date = input[ip++] | (input[ip++] << 8);\n\n // crc-32\n this.crc32 = (\n (input[ip++] ) | (input[ip++] << 8) |\n (input[ip++] << 16) | (input[ip++] << 24)\n ) >>> 0;\n\n // compressed size\n this.compressedSize = (\n (input[ip++] ) | (input[ip++] << 8) |\n (input[ip++] << 16) | (input[ip++] << 24)\n ) >>> 0;\n\n // uncompressed size\n this.plainSize = (\n (input[ip++] ) | (input[ip++] << 8) |\n (input[ip++] << 16) | (input[ip++] << 24)\n ) >>> 0;\n\n // file name length\n this.fileNameLength = input[ip++] | (input[ip++] << 8);\n\n // extra field length\n this.extraFieldLength = input[ip++] | (input[ip++] << 8);\n\n // file name\n this.filename = String.fromCharCode.apply(null, USE_TYPEDARRAY ?\n input.subarray(ip, ip += this.fileNameLength) :\n input.slice(ip, ip += this.fileNameLength)\n );\n\n // extra field\n this.extraField = USE_TYPEDARRAY ?\n input.subarray(ip, ip += this.extraFieldLength) :\n input.slice(ip, ip += this.extraFieldLength);\n\n this.length = ip - this.offset;\n};\n\n\nZlib.Unzip.prototype.searchEndOfCentralDirectoryRecord = function() {\n /** @type {!(Array.|Uint8Array)} */\n var input = this.input;\n /** @type {number} */\n var ip;\n\n for (ip = input.length - 12; ip > 0; --ip) {\n if (input[ip ] === Zlib.Unzip.CentralDirectorySignature[0] &&\n input[ip+1] === Zlib.Unzip.CentralDirectorySignature[1] &&\n input[ip+2] === Zlib.Unzip.CentralDirectorySignature[2] &&\n input[ip+3] === Zlib.Unzip.CentralDirectorySignature[3]) {\n this.eocdrOffset = ip;\n return;\n }\n }\n\n throw new Error('End of Central Directory Record not found');\n};\n\nZlib.Unzip.prototype.parseEndOfCentralDirectoryRecord = function() {\n /** @type {!(Array.|Uint8Array)} */\n var input = this.input;\n /** @type {number} */\n var ip;\n\n if (!this.eocdrOffset) {\n this.searchEndOfCentralDirectoryRecord();\n }\n ip = this.eocdrOffset;\n\n // signature\n if (input[ip++] !== Zlib.Unzip.CentralDirectorySignature[0] ||\n input[ip++] !== Zlib.Unzip.CentralDirectorySignature[1] ||\n input[ip++] !== Zlib.Unzip.CentralDirectorySignature[2] ||\n input[ip++] !== Zlib.Unzip.CentralDirectorySignature[3]) {\n throw new Error('invalid signature');\n }\n\n // number of this disk\n this.numberOfThisDisk = input[ip++] | (input[ip++] << 8);\n\n // number of the disk with the start of the central directory\n this.startDisk = input[ip++] | (input[ip++] << 8);\n\n // total number of entries in the central directory on this disk\n this.totalEntriesThisDisk = input[ip++] | (input[ip++] << 8);\n\n // total number of entries in the central directory\n this.totalEntries = input[ip++] | (input[ip++] << 8);\n\n // size of the central directory\n this.centralDirectorySize = (\n (input[ip++] ) | (input[ip++] << 8) |\n (input[ip++] << 16) | (input[ip++] << 24)\n ) >>> 0;\n\n // offset of start of central directory with respect to the starting disk number\n this.centralDirectoryOffset = (\n (input[ip++] ) | (input[ip++] << 8) |\n (input[ip++] << 16) | (input[ip++] << 24)\n ) >>> 0;\n\n // .ZIP file comment length\n this.commentLength = input[ip++] | (input[ip++] << 8);\n\n // .ZIP file comment\n this.comment = USE_TYPEDARRAY ?\n input.subarray(ip, ip + this.commentLength) :\n input.slice(ip, ip + this.commentLength);\n};\n\nZlib.Unzip.prototype.parseFileHeader = function() {\n /** @type {Array.} */\n var filelist = [];\n /** @type {Object.} */\n var filetable = {};\n /** @type {number} */\n var ip;\n /** @type {Zlib.Unzip.FileHeader} */\n var fileHeader;\n /*: @type {number} */\n var i;\n /*: @type {number} */\n var il;\n\n if (this.fileHeaderList) {\n return;\n }\n\n if (this.centralDirectoryOffset === void 0) {\n this.parseEndOfCentralDirectoryRecord();\n }\n ip = this.centralDirectoryOffset;\n\n for (i = 0, il = this.totalEntries; i < il; ++i) {\n fileHeader = new Zlib.Unzip.FileHeader(this.input, ip);\n fileHeader.parse();\n ip += fileHeader.length;\n filelist[i] = fileHeader;\n filetable[fileHeader.filename] = i;\n }\n\n if (this.centralDirectorySize < ip - this.centralDirectoryOffset) {\n throw new Error('invalid file header size');\n }\n\n this.fileHeaderList = filelist;\n this.filenameToIndex = filetable;\n};\n\n/**\n * @param {number} index file header index.\n * @param {Object=} opt_params\n * @return {!(Array.|Uint8Array)} file data.\n */\nZlib.Unzip.prototype.getFileData = function(index, opt_params) {\n opt_params = opt_params || {};\n /** @type {!(Array.|Uint8Array)} */\n var input = this.input;\n /** @type {Array.} */\n var fileHeaderList = this.fileHeaderList;\n /** @type {Zlib.Unzip.LocalFileHeader} */\n var localFileHeader;\n /** @type {number} */\n var offset;\n /** @type {number} */\n var length;\n /** @type {!(Array.|Uint8Array)} */\n var buffer;\n /** @type {number} */\n var crc32;\n /** @type {Array.|Uint32Array|Object} */\n var key;\n /** @type {number} */\n var i;\n /** @type {number} */\n var il;\n\n if (!fileHeaderList) {\n this.parseFileHeader();\n }\n\n if (fileHeaderList[index] === void 0) {\n throw new Error('wrong index');\n }\n\n offset = fileHeaderList[index].relativeOffset;\n localFileHeader = new Zlib.Unzip.LocalFileHeader(this.input, offset);\n localFileHeader.parse();\n offset += localFileHeader.length;\n length = localFileHeader.compressedSize;\n\n // decryption\n if ((localFileHeader.flags & Zlib.Unzip.LocalFileHeader.Flags.ENCRYPT) !== 0) {\n if (!(opt_params['password'] || this.password)) {\n throw new Error('please set password');\n }\n key = this.createDecryptionKey(opt_params['password'] || this.password);\n\n // encryption header\n for(i = offset, il = offset + 12; i < il; ++i) {\n this.decode(key, input[i]);\n }\n offset += 12;\n length -= 12;\n\n // decryption\n for (i = offset, il = offset + length; i < il; ++i) {\n input[i] = this.decode(key, input[i]);\n }\n }\n\n switch (localFileHeader.compression) {\n case Zlib.Unzip.CompressionMethod.STORE:\n buffer = USE_TYPEDARRAY ?\n this.input.subarray(offset, offset + length) :\n this.input.slice(offset, offset + length);\n break;\n case Zlib.Unzip.CompressionMethod.DEFLATE:\n buffer = new Zlib.RawInflate(this.input, {\n 'index': offset,\n 'bufferSize': localFileHeader.plainSize\n }).decompress();\n break;\n default:\n throw new Error('unknown compression type');\n }\n\n if (this.verify) {\n crc32 = Zlib.CRC32.calc(buffer);\n if (localFileHeader.crc32 !== crc32) {\n throw new Error(\n 'wrong crc: file=0x' + localFileHeader.crc32.toString(16) +\n ', data=0x' + crc32.toString(16)\n );\n }\n }\n\n return buffer;\n};\n\n/**\n * @return {Array.}\n */\nZlib.Unzip.prototype.getFilenames = function() {\n /** @type {Array.} */\n var filenameList = [];\n /** @type {number} */\n var i;\n /** @type {number} */\n var il;\n /** @type {Array.} */\n var fileHeaderList;\n\n if (!this.fileHeaderList) {\n this.parseFileHeader();\n }\n fileHeaderList = this.fileHeaderList;\n\n for (i = 0, il = fileHeaderList.length; i < il; ++i) {\n filenameList[i] = fileHeaderList[i].filename;\n }\n\n return filenameList;\n};\n\n/**\n * @param {string} filename extract filename.\n * @param {Object=} opt_params\n * @return {!(Array.|Uint8Array)} decompressed data.\n */\nZlib.Unzip.prototype.decompress = function(filename, opt_params) {\n /** @type {number} */\n var index;\n\n if (!this.filenameToIndex) {\n this.parseFileHeader();\n }\n index = this.filenameToIndex[filename];\n\n if (index === void 0) {\n throw new Error(filename + ' not found');\n }\n\n return this.getFileData(index, opt_params);\n};\n\n/**\n * @param {(Array.|Uint8Array)} password\n */\nZlib.Unzip.prototype.setPassword = function(password) {\n this.password = password;\n};\n\n/**\n * @param {(Array.|Uint32Array|Object)} key\n * @param {number} n\n * @return {number}\n */\nZlib.Unzip.prototype.decode = function(key, n) {\n n ^= this.getByte(/** @type {(Array.|Uint32Array)} */(key));\n this.updateKeys(/** @type {(Array.|Uint32Array)} */(key), n);\n\n return n;\n};\n\n// common method\nZlib.Unzip.prototype.updateKeys = Zlib.Zip.prototype.updateKeys;\nZlib.Unzip.prototype.createDecryptionKey = Zlib.Zip.prototype.createEncryptionKey;\nZlib.Unzip.prototype.getByte = Zlib.Zip.prototype.getByte;\n\n/**\n * @fileoverview 雑多な関数群をまとめたモジュール実装.\n */\n\n\n/**\n * Byte String から Byte Array に変換.\n * @param {!string} str byte string.\n * @return {!Array.} byte array.\n */\nZlib.Util.stringToByteArray = function(str) {\n /** @type {!Array.<(string|number)>} */\n var tmp = str.split('');\n /** @type {number} */\n var i;\n /** @type {number} */\n var il;\n\n for (i = 0, il = tmp.length; i < il; i++) {\n tmp[i] = (tmp[i].charCodeAt(0) & 0xff) >>> 0;\n }\n\n return tmp;\n};\n\n\n/**\n * @fileoverview Adler32 checksum 実装.\n */\n\n\n/**\n * Adler32 ハッシュ値の作成\n * @param {!(Array|Uint8Array|string)} array 算出に使用する byte array.\n * @return {number} Adler32 ハッシュ値.\n */\nZlib.Adler32 = function(array) {\n if (typeof(array) === 'string') {\n array = Zlib.Util.stringToByteArray(array);\n }\n return Zlib.Adler32.update(1, array);\n};\n\n/**\n * Adler32 ハッシュ値の更新\n * @param {number} adler 現在のハッシュ値.\n * @param {!(Array|Uint8Array)} array 更新に使用する byte array.\n * @return {number} Adler32 ハッシュ値.\n */\nZlib.Adler32.update = function(adler, array) {\n /** @type {number} */\n var s1 = adler & 0xffff;\n /** @type {number} */\n var s2 = (adler >>> 16) & 0xffff;\n /** @type {number} array length */\n var len = array.length;\n /** @type {number} loop length (don't overflow) */\n var tlen;\n /** @type {number} array index */\n var i = 0;\n\n while (len > 0) {\n tlen = len > Zlib.Adler32.OptimizationParameter ?\n Zlib.Adler32.OptimizationParameter : len;\n len -= tlen;\n do {\n s1 += array[i++];\n s2 += s1;\n } while (--tlen);\n\n s1 %= 65521;\n s2 %= 65521;\n }\n\n return ((s2 << 16) | s1) >>> 0;\n};\n\n/**\n * Adler32 最適化パラメータ\n * 現状では 1024 程度が最適.\n * @see http://jsperf.com/adler-32-simple-vs-optimized/3\n * @define {number}\n */\nZlib.Adler32.OptimizationParameter = 1024;\n\n\n\n\n/**\n * ビットストリーム\n * @constructor\n * @param {!(Array|Uint8Array)=} buffer output buffer.\n * @param {number=} bufferPosition start buffer pointer.\n */\nZlib.BitStream = function(buffer, bufferPosition) {\n /** @type {number} buffer index. */\n this.index = typeof bufferPosition === 'number' ? bufferPosition : 0;\n /** @type {number} bit index. */\n this.bitindex = 0;\n /** @type {!(Array|Uint8Array)} bit-stream output buffer. */\n this.buffer = buffer instanceof (USE_TYPEDARRAY ? Uint8Array : Array) ?\n buffer :\n new (USE_TYPEDARRAY ? Uint8Array : Array)(Zlib.BitStream.DefaultBlockSize);\n\n // 入力された index が足りなかったら拡張するが、倍にしてもダメなら不正とする\n if (this.buffer.length * 2 <= this.index) {\n throw new Error(\"invalid index\");\n } else if (this.buffer.length <= this.index) {\n this.expandBuffer();\n }\n};\n\n/**\n * デフォルトブロックサイズ.\n * @const\n * @type {number}\n */\nZlib.BitStream.DefaultBlockSize = 0x8000;\n\n/**\n * expand buffer.\n * @return {!(Array|Uint8Array)} new buffer.\n */\nZlib.BitStream.prototype.expandBuffer = function() {\n /** @type {!(Array|Uint8Array)} old buffer. */\n var oldbuf = this.buffer;\n /** @type {number} loop counter. */\n var i;\n /** @type {number} loop limiter. */\n var il = oldbuf.length;\n /** @type {!(Array|Uint8Array)} new buffer. */\n var buffer =\n new (USE_TYPEDARRAY ? Uint8Array : Array)(il << 1);\n\n // copy buffer\n if (USE_TYPEDARRAY) {\n buffer.set(oldbuf);\n } else {\n // XXX: loop unrolling\n for (i = 0; i < il; ++i) {\n buffer[i] = oldbuf[i];\n }\n }\n\n return (this.buffer = buffer);\n};\n\n\n/**\n * 数値をビットで指定した数だけ書き込む.\n * @param {number} number 書き込む数値.\n * @param {number} n 書き込むビット数.\n * @param {boolean=} reverse 逆順に書き込むならば true.\n */\nZlib.BitStream.prototype.writeBits = function(number, n, reverse) {\n var buffer = this.buffer;\n var index = this.index;\n var bitindex = this.bitindex;\n\n /** @type {number} current octet. */\n var current = buffer[index];\n /** @type {number} loop counter. */\n var i;\n\n /**\n * 32-bit 整数のビット順を逆にする\n * @param {number} n 32-bit integer.\n * @return {number} reversed 32-bit integer.\n * @private\n */\n function rev32_(n) {\n return (Zlib.BitStream.ReverseTable[n & 0xFF] << 24) |\n (Zlib.BitStream.ReverseTable[n >>> 8 & 0xFF] << 16) |\n (Zlib.BitStream.ReverseTable[n >>> 16 & 0xFF] << 8) |\n Zlib.BitStream.ReverseTable[n >>> 24 & 0xFF];\n }\n\n if (reverse && n > 1) {\n number = n > 8 ?\n rev32_(number) >> (32 - n) :\n Zlib.BitStream.ReverseTable[number] >> (8 - n);\n }\n\n // Byte 境界を超えないとき\n if (n + bitindex < 8) {\n current = (current << n) | number;\n bitindex += n;\n // Byte 境界を超えるとき\n } else {\n for (i = 0; i < n; ++i) {\n current = (current << 1) | ((number >> n - i - 1) & 1);\n\n // next byte\n if (++bitindex === 8) {\n bitindex = 0;\n buffer[index++] = Zlib.BitStream.ReverseTable[current];\n current = 0;\n\n // expand\n if (index === buffer.length) {\n buffer = this.expandBuffer();\n }\n }\n }\n }\n buffer[index] = current;\n\n this.buffer = buffer;\n this.bitindex = bitindex;\n this.index = index;\n};\n\n\n/**\n * ストリームの終端処理を行う\n * @return {!(Array|Uint8Array)} 終端処理後のバッファを byte array で返す.\n */\nZlib.BitStream.prototype.finish = function() {\n var buffer = this.buffer;\n var index = this.index;\n\n /** @type {!(Array|Uint8Array)} output buffer. */\n var output;\n\n // bitindex が 0 の時は余分に index が進んでいる状態\n if (this.bitindex > 0) {\n buffer[index] <<= 8 - this.bitindex;\n buffer[index] = Zlib.BitStream.ReverseTable[buffer[index]];\n index++;\n }\n\n // array truncation\n if (USE_TYPEDARRAY) {\n output = buffer.subarray(0, index);\n } else {\n buffer.length = index;\n output = buffer;\n }\n\n return output;\n};\n\n/**\n * 0-255 のビット順を反転したテーブル\n * @const\n * @type {!(Uint8Array|Array.)}\n */\nZlib.BitStream.ReverseTable = (function(table) {\n return table;\n})((function() {\n /** @type {!(Array|Uint8Array)} reverse table. */\n var table = new (USE_TYPEDARRAY ? Uint8Array : Array)(256);\n /** @type {number} loop counter. */\n var i;\n\n // generate\n for (i = 0; i < 256; ++i) {\n table[i] = (function(n) {\n var r = n;\n var s = 7;\n\n for (n >>>= 1; n; n >>>= 1) {\n r <<= 1;\n r |= n & 1;\n --s;\n }\n\n return (r << s & 0xff) >>> 0;\n })(i);\n }\n\n return table;\n})());\n\n\n/**\n * @fileoverview CRC32 実装.\n */\n\n\n/** @define {boolean} */\nvar ZLIB_CRC32_COMPACT = false;\n\n/**\n * CRC32 ハッシュ値を取得\n * @param {!(Array.|Uint8Array)} data data byte array.\n * @param {number=} pos data position.\n * @param {number=} length data length.\n * @return {number} CRC32.\n */\nZlib.CRC32.calc = function(data, pos, length) {\n return Zlib.CRC32.update(data, 0, pos, length);\n};\n\n/**\n * CRC32ハッシュ値を更新\n * @param {!(Array.|Uint8Array)} data data byte array.\n * @param {number} crc CRC32.\n * @param {number=} pos data position.\n * @param {number=} length data length.\n * @return {number} CRC32.\n */\nZlib.CRC32.update = function(data, crc, pos, length) {\n var table = Zlib.CRC32.Table;\n var i = (typeof pos === 'number') ? pos : (pos = 0);\n var il = (typeof length === 'number') ? length : data.length;\n\n crc ^= 0xffffffff;\n\n // loop unrolling for performance\n for (i = il & 7; i--; ++pos) {\n crc = (crc >>> 8) ^ table[(crc ^ data[pos]) & 0xff];\n }\n for (i = il >> 3; i--; pos += 8) {\n crc = (crc >>> 8) ^ table[(crc ^ data[pos ]) & 0xff];\n crc = (crc >>> 8) ^ table[(crc ^ data[pos + 1]) & 0xff];\n crc = (crc >>> 8) ^ table[(crc ^ data[pos + 2]) & 0xff];\n crc = (crc >>> 8) ^ table[(crc ^ data[pos + 3]) & 0xff];\n crc = (crc >>> 8) ^ table[(crc ^ data[pos + 4]) & 0xff];\n crc = (crc >>> 8) ^ table[(crc ^ data[pos + 5]) & 0xff];\n crc = (crc >>> 8) ^ table[(crc ^ data[pos + 6]) & 0xff];\n crc = (crc >>> 8) ^ table[(crc ^ data[pos + 7]) & 0xff];\n }\n\n return (crc ^ 0xffffffff) >>> 0;\n};\n\n/**\n * @param {number} num\n * @param {number} crc\n * @returns {number}\n */\nZlib.CRC32.single = function(num, crc) {\n return (Zlib.CRC32.Table[(num ^ crc) & 0xff] ^ (num >>> 8)) >>> 0;\n};\n\n/**\n * @type {Array.}\n * @const\n * @private\n */\nZlib.CRC32.Table_ = [\n 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,\n 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,\n 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,\n 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,\n 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,\n 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,\n 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,\n 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,\n 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,\n 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,\n 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,\n 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,\n 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,\n 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,\n 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,\n 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,\n 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,\n 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,\n 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,\n 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,\n 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,\n 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,\n 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,\n 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,\n 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,\n 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,\n 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,\n 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,\n 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,\n 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,\n 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,\n 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,\n 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,\n 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,\n 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,\n 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,\n 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,\n 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,\n 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,\n 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,\n 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,\n 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,\n 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d\n];\n\n/**\n * @type {!(Array.|Uint32Array)} CRC-32 Table.\n * @const\n */\nZlib.CRC32.Table = ZLIB_CRC32_COMPACT ? (function() {\n /** @type {!(Array.|Uint32Array)} */\n var table = new (USE_TYPEDARRAY ? Uint32Array : Array)(256);\n /** @type {number} */\n var c;\n /** @type {number} */\n var i;\n /** @type {number} */\n var j;\n\n for (i = 0; i < 256; ++i) {\n c = i;\n for (j = 0; j < 8; ++j) {\n c = (c & 1) ? (0xedB88320 ^ (c >>> 1)) : (c >>> 1);\n }\n table[i] = c >>> 0;\n }\n\n return table;\n})() : USE_TYPEDARRAY ? new Uint32Array(Zlib.CRC32.Table_) : Zlib.CRC32.Table_;\n\n/**\n * @fileoverview Deflate (RFC1951) 実装.\n * Deflateアルゴリズム本体は Zlib.RawDeflate で実装されている.\n */\n\n/**\n * Zlib Deflate\n * @constructor\n * @param {!(Array|Uint8Array)} input 符号化する対象の byte array.\n * @param {Object=} opt_params option parameters.\n */\nZlib.Deflate = function(input, opt_params) {\n /** @type {!(Array|Uint8Array)} */\n this.input = input;\n /** @type {!(Array|Uint8Array)} */\n this.output =\n new (USE_TYPEDARRAY ? Uint8Array : Array)(Zlib.Deflate.DefaultBufferSize);\n /** @type {Zlib.Deflate.CompressionType} */\n this.compressionType = Zlib.Deflate.CompressionType.DYNAMIC;\n /** @type {Zlib.RawDeflate} */\n this.rawDeflate;\n /** @type {Object} */\n var rawDeflateOption = {};\n /** @type {string} */\n var prop;\n\n // option parameters\n if (opt_params || !(opt_params = {})) {\n if (typeof opt_params['compressionType'] === 'number') {\n this.compressionType = opt_params['compressionType'];\n }\n }\n\n // copy options\n for (prop in opt_params) {\n rawDeflateOption[prop] = opt_params[prop];\n }\n\n // set raw-deflate output buffer\n rawDeflateOption['outputBuffer'] = this.output;\n\n this.rawDeflate = new Zlib.RawDeflate(this.input, rawDeflateOption);\n};\n\n/**\n * @const\n * @type {number} デフォルトバッファサイズ.\n */\nZlib.Deflate.DefaultBufferSize = 0x8000;\n\n/**\n * @enum {number}\n */\nZlib.Deflate.CompressionType = Zlib.RawDeflate.CompressionType;\n\n/**\n * 直接圧縮に掛ける.\n * @param {!(Array|Uint8Array)} input target buffer.\n * @param {Object=} opt_params option parameters.\n * @return {!(Array|Uint8Array)} compressed data byte array.\n */\nZlib.Deflate.compress = function(input, opt_params) {\n return (new Zlib.Deflate(input, opt_params)).compress();\n};\n\n/**\n * Deflate Compression.\n * @return {!(Array|Uint8Array)} compressed data byte array.\n */\nZlib.Deflate.prototype.compress = function() {\n /** @type {Zlib.CompressionMethod} */\n var cm;\n /** @type {number} */\n var cinfo;\n /** @type {number} */\n var cmf;\n /** @type {number} */\n var flg;\n /** @type {number} */\n var fcheck;\n /** @type {number} */\n var fdict;\n /** @type {number} */\n var flevel;\n /** @type {number} */\n var clevel;\n /** @type {number} */\n var adler;\n /** @type {boolean} */\n var error = false;\n /** @type {!(Array|Uint8Array)} */\n var output;\n /** @type {number} */\n var pos = 0;\n\n output = this.output;\n\n // Compression Method and Flags\n cm = Zlib.CompressionMethod.DEFLATE;\n switch (cm) {\n case Zlib.CompressionMethod.DEFLATE:\n cinfo = Math.LOG2E * Math.log(Zlib.RawDeflate.WindowSize) - 8;\n break;\n default:\n throw new Error('invalid compression method');\n }\n cmf = (cinfo << 4) | cm;\n output[pos++] = cmf;\n\n // Flags\n fdict = 0;\n switch (cm) {\n case Zlib.CompressionMethod.DEFLATE:\n switch (this.compressionType) {\n case Zlib.Deflate.CompressionType.NONE: flevel = 0; break;\n case Zlib.Deflate.CompressionType.FIXED: flevel = 1; break;\n case Zlib.Deflate.CompressionType.DYNAMIC: flevel = 2; break;\n default: throw new Error('unsupported compression type');\n }\n break;\n default:\n throw new Error('invalid compression method');\n }\n flg = (flevel << 6) | (fdict << 5);\n fcheck = 31 - (cmf * 256 + flg) % 31;\n flg |= fcheck;\n output[pos++] = flg;\n\n // Adler-32 checksum\n adler = Zlib.Adler32(this.input);\n\n this.rawDeflate.op = pos;\n output = this.rawDeflate.compress();\n pos = output.length;\n\n if (USE_TYPEDARRAY) {\n // subarray 分を元にもどす\n output = new Uint8Array(output.buffer);\n // expand buffer\n if (output.length <= pos + 4) {\n this.output = new Uint8Array(output.length + 4);\n this.output.set(output);\n output = this.output;\n }\n output = output.subarray(0, pos + 4);\n }\n\n // adler32\n output[pos++] = (adler >> 24) & 0xff;\n output[pos++] = (adler >> 16) & 0xff;\n output[pos++] = (adler >> 8) & 0xff;\n output[pos++] = (adler ) & 0xff;\n\n return output;\n};\n\nexport default Zlib;\n\n","class BrowserLocalFile {\n\n constructor(blob) {\n this.file = blob\n }\n\n async read(position, length) {\n const file = this.file\n if (position !== undefined) {\n return file.slice(position, position + length).arrayBuffer()\n\n } else {\n return file.arrayBuffer()\n\n }\n }\n}\n\nexport default BrowserLocalFile\n","const isNode = typeof process !== 'undefined' && process.versions != null && process.versions.node != null\n\nclass RemoteFile {\n\n constructor(args) {\n this.config = args\n this.url = mapUrl(args.path || args.url)\n }\n\n\n async read(position, length) {\n\n length = Math.ceil(length)\n const headers = this.config.headers || {}\n const rangeString = \"bytes=\" + position + \"-\" + (position + length - 1)\n headers['Range'] = rangeString\n\n let url = this.url.slice() // slice => copy\n // headers['User-Agent'] = 'straw'\n if (this.config.oauthToken) {\n const token = resolveToken(this.config.oauthToken)\n headers['Authorization'] = `Bearer ${token}`\n }\n if (this.config.apiKey) {\n url = addParameter(url, \"key\", this.config.apiKey)\n }\n\n const response = await fetch(url, {\n method: 'GET',\n headers: headers,\n redirect: 'follow',\n mode: 'cors',\n\n })\n\n const status = response.status\n\n if (status >= 400) {\n console.error(`${status} ${this.config.url}`)\n const err = Error(response.statusText)\n err.code = status\n throw err\n } else {\n return response.arrayBuffer()\n }\n\n /**\n * token can be a string, a function that returns a string, or a function that returns a Promise for a string\n * @param token\n * @returns {Promise<*>}\n */\n async function resolveToken(token) {\n if (typeof token === 'function') {\n return await Promise.resolve(token()) // Normalize the result to a promise, since we don't know what the function returns\n } else {\n return token\n }\n }\n\n }\n}\n\n\nfunction mapUrl(url) {\n\n if (url.includes(\"//www.dropbox.com\")) {\n return url.replace(\"//www.dropbox.com\", \"//dl.dropboxusercontent.com\")\n } else if (url.startsWith(\"ftp://ftp.ncbi.nlm.nih.gov\")) {\n return url.replace(\"ftp://\", \"https://\")\n } else {\n return url\n }\n}\n\n\nfunction addParameter(url, name, value) {\n const paramSeparator = url.includes(\"?\") ? \"&\" : \"?\"\n return url + paramSeparator + name + \"=\" + value\n}\n\n\nexport default RemoteFile\n","class ThrottledFile {\n\n constructor(file, rateLimiter) {\n this.file = file\n this.rateLimiter = rateLimiter\n }\n\n\n async read(position, length) {\n\n const file = this.file\n const rateLimiter = this.rateLimiter\n\n return new Promise(function (fulfill, reject) {\n rateLimiter.limiter(async function (f) {\n try {\n const result = await f.read(position, length)\n fulfill(result)\n } catch (e) {\n reject(e)\n }\n })(file)\n })\n }\n}\n\n\nexport default ThrottledFile;","class BufferedFile {\n\n constructor(args) {\n this.file = args.file\n this.size = args.size || 64000\n this.position = 0\n this.bufferStart = 0\n this.bufferLength = 0\n this.buffer = undefined\n }\n\n\n async read(position, length) {\n\n const start = position\n const end = position + length\n const bufferStart = this.bufferStart\n const bufferEnd = this.bufferStart + this.bufferLength\n\n\n if (length > this.size) {\n // Request larger than max buffer size, pass through to underlying file\n //console.log(\"0\")\n this.buffer = undefined\n this.bufferStart = 0\n this.bufferLength = 0\n return this.file.read(position, length)\n }\n\n if (start >= bufferStart && end <= bufferEnd) {\n // Request within buffer bounds\n //console.log(\"1\")\n const sliceStart = start - bufferStart\n const sliceEnd = sliceStart + length\n return this.buffer.slice(sliceStart, sliceEnd)\n }\n\n else if (start < bufferStart && end > bufferStart) {\n // Overlap left, here for completness but this is an unexpected case in straw. We don't adjust the buffer.\n //console.log(\"2\")\n const l1 = bufferStart - start\n const a1 = await this.file.read(position, l1)\n const l2 = length - l1\n if (l2 > 0) {\n //this.buffer = await this.file.read(bufferStart, this.size)\n const a2 = this.buffer.slice(0, l2)\n return concatBuffers(a1, a2)\n } else {\n return a1\n }\n\n }\n\n else if (start < bufferEnd && end > bufferEnd) {\n // Overlap right\n // console.log(\"3\")\n const l1 = bufferEnd - start\n const sliceStart = this.bufferLength - l1\n const a1 = this.buffer.slice(sliceStart, this.bufferLength)\n\n const l2 = length - l1\n if (l2 > 0) {\n try {\n this.buffer = await this.file.read(bufferEnd, this.size)\n this.bufferStart = bufferEnd\n this.bufferLength = this.buffer.byteLength\n const a2 = this.buffer.slice(0, l2)\n return concatBuffers(a1, a2)\n } catch (e) {\n // A \"unsatisfiable range\" error is expected here if we overlap past the end of file\n if (e.code && e.code === 416) {\n return a1\n }\n else {\n throw e\n }\n }\n\n } else {\n return a1\n }\n\n }\n\n else {\n // No overlap with buffer\n // console.log(\"4\")\n this.buffer = await this.file.read(position, this.size)\n this.bufferStart = position\n this.bufferLength = this.buffer.byteLength\n return this.buffer.slice(0, length)\n }\n\n }\n\n}\n\n/**\n * concatenates 2 array buffers.\n * Credit: https://gist.github.com/72lions/4528834\n *\n * @private\n * @param {ArrayBuffers} buffer1 The first buffer.\n * @param {ArrayBuffers} buffer2 The second buffer.\n * @return {ArrayBuffers} The new ArrayBuffer created out of the two.\n */\nvar concatBuffers = function (buffer1, buffer2) {\n var tmp = new Uint8Array(buffer1.byteLength + buffer2.byteLength);\n tmp.set(new Uint8Array(buffer1), 0);\n tmp.set(new Uint8Array(buffer2), buffer1.byteLength);\n return tmp.buffer;\n};\n\n\nexport default BufferedFile;","// TODO -- big endian\n\nconst BinaryParser = function (dataView, littleEndian) {\n\n this.littleEndian = littleEndian !== undefined ? littleEndian : true\n this.position = 0;\n this.view = dataView;\n this.length = dataView.byteLength;\n}\n\nBinaryParser.prototype.available = function () {\n return this.length - this.position;\n}\n\nBinaryParser.prototype.remLength = function () {\n return this.length - this.position;\n}\n\nBinaryParser.prototype.hasNext = function () {\n return this.position < this.length - 1;\n}\n\nBinaryParser.prototype.getByte = function () {\n var retValue = this.view.getUint8(this.position, this.littleEndian);\n this.position++;\n return retValue;\n}\n\nBinaryParser.prototype.getShort = function () {\n\n var retValue = this.view.getInt16(this.position, this.littleEndian);\n this.position += 2\n return retValue;\n}\n\nBinaryParser.prototype.getUShort = function () {\n\n // var byte1 = this.getByte(),\n // byte2 = this.getByte(),\n // retValue = ((byte2 << 24 >>> 16) + (byte1 << 24 >>> 24));\n // return retValue;\n\n //\n var retValue = this.view.getUint16(this.position, this.littleEndian);\n this.position += 2\n return retValue;\n}\n\n\nBinaryParser.prototype.getInt = function () {\n\n var retValue = this.view.getInt32(this.position, this.littleEndian);\n this.position += 4;\n return retValue;\n}\n\n\nBinaryParser.prototype.getUInt = function () {\n var retValue = this.view.getUint32(this.position, this.littleEndian);\n this.position += 4;\n return retValue;\n}\n\nBinaryParser.prototype.getLong = function () {\n\n // DataView doesn't support long. So we'll try manually\n\n var b = [];\n b[0] = this.view.getUint8(this.position);\n b[1] = this.view.getUint8(this.position + 1);\n b[2] = this.view.getUint8(this.position + 2);\n b[3] = this.view.getUint8(this.position + 3);\n b[4] = this.view.getUint8(this.position + 4);\n b[5] = this.view.getUint8(this.position + 5);\n b[6] = this.view.getUint8(this.position + 6);\n b[7] = this.view.getUint8(this.position + 7);\n\n var value = 0;\n if (this.littleEndian) {\n for (var i = b.length - 1; i >= 0; i--) {\n value = (value * 256) + b[i];\n }\n } else {\n for (var i = 0; i < b.length; i++) {\n value = (value * 256) + b[i];\n }\n }\n\n\n this.position += 8;\n return value;\n}\n\nBinaryParser.prototype.getString = function (len) {\n\n var s = \"\";\n var c;\n while ((c = this.view.getUint8(this.position++)) != 0) {\n s += String.fromCharCode(c);\n if (len && s.length == len) break;\n }\n return s;\n}\n\nBinaryParser.prototype.getFixedLengthString = function (len) {\n\n var s = \"\";\n var i;\n var c;\n for (i = 0; i < len; i++) {\n c = this.view.getUint8(this.position++);\n if (c > 0) {\n s += String.fromCharCode(c);\n }\n }\n return s;\n}\n\nBinaryParser.prototype.getFixedLengthTrimmedString = function (len) {\n\n var s = \"\";\n var i;\n var c;\n for (i = 0; i < len; i++) {\n c = this.view.getUint8(this.position++);\n if (c > 32) {\n s += String.fromCharCode(c);\n }\n }\n return s;\n}\n\nBinaryParser.prototype.getFloat = function () {\n\n var retValue = this.view.getFloat32(this.position, this.littleEndian);\n this.position += 4;\n return retValue;\n\n\n}\n\nBinaryParser.prototype.getDouble = function () {\n\n var retValue = this.view.getFloat64(this.position, this.littleEndian);\n this.position += 8;\n return retValue;\n}\n\nBinaryParser.prototype.skip = function (n) {\n\n this.position += n;\n return this.position;\n}\n\n\n/**\n * Return a bgzip (bam and tabix) virtual pointer\n * TODO -- why isn't 8th byte used ?\n * @returns {*}\n */\nBinaryParser.prototype.getVPointer = function () {\n\n var position = this.position,\n offset = (this.view.getUint8(position + 1) << 8) | (this.view.getUint8(position)),\n byte6 = ((this.view.getUint8(position + 6) & 0xff) * 0x100000000),\n byte5 = ((this.view.getUint8(position + 5) & 0xff) * 0x1000000),\n byte4 = ((this.view.getUint8(position + 4) & 0xff) * 0x10000),\n byte3 = ((this.view.getUint8(position + 3) & 0xff) * 0x100),\n byte2 = ((this.view.getUint8(position + 2) & 0xff)),\n block = byte6 + byte5 + byte4 + byte3 + byte2;\n this.position += 8;\n\n // if (block == 0 && offset == 0) {\n // return null;\n // } else {\n return new VPointer(block, offset);\n // }\n}\n\n\nfunction VPointer(block, offset) {\n this.block = block;\n this.offset = offset;\n}\n\nVPointer.prototype.isLessThan = function (vp) {\n return this.block < vp.block ||\n (this.block === vp.block && this.offset < vp.offset);\n}\n\nVPointer.prototype.isGreaterThan = function (vp) {\n return this.block > vp.block ||\n (this.block === vp.block && this.offset > vp.offset);\n}\n\nVPointer.prototype.print = function () {\n return \"\" + this.block + \":\" + this.offset;\n}\n\n\nexport default BinaryParser;","import BinaryParser from \"./binary.js\"\n\n\nclass MatrixZoomData {\n\n constructor(chr1, chr2) {\n\n this.chr1 = chr1; // chromosome index\n this.chr2 = chr2;\n }\n\n getKey () {\n return this.chr1.name + \"_\" + this.chr2.name + \"_\" + this.zoom.unit + \"_\" + this.zoom.binSize;\n }\n\n getBlockNumbers(region1, region2, version) {\n\n // Verify region chromosomes and swap if neccessary\n if(region1.chr == this.chr2 && region2.chr === this.chr1) {\n const tmp = region1;\n region1 = region2;\n region2 = tmp;\n }\n\n const sameChr = this.chr1 === this.chr2;\n const binsize = this.zoom.binSize;\n const blockBinCount = this.blockBinCount\n const blockColumnCount = this.blockColumnCount\n return (version < 9 || !sameChr) ? getBlockNumbersV8() : getBlockNumbersV9();\n\n function getBlockNumbersV8()\n {\n const x1 = region1.start / binsize\n const x2 = region1.end / binsize\n const y1 = region2.start / binsize\n const y2 = region2.end / binsize\n\n const col1 = Math.floor(x1 / blockBinCount)\n const col2 = Math.floor((x2 - 1) / blockBinCount)\n const row1 = Math.floor(y1 / blockBinCount)\n const row2 = Math.floor((y2 - 1) / blockBinCount)\n\n const blockNumbers = [];\n for (let row = row1; row <= row2; row++) {\n for (let column = col1; column <= col2; column++) {\n let blockNumber\n if (sameChr && row < column) {\n blockNumber = column * blockColumnCount + row;\n } else {\n blockNumber = row * blockColumnCount + column;\n }\n if (!blockNumbers.includes(blockNumber)) { // possible from transposition\n blockNumbers.push(blockNumber)\n }\n }\n }\n return blockNumbers\n }\n\n function getBlockNumbersV9()\n {\n\n const binX1 = region1.start / binsize\n const binX2 = region1.end / binsize\n const binY1 = region2.start / binsize\n const binY2 = region2.end / binsize\n\n // PAD = positionAlongDiagonal (~projected)\n // Depth is axis perpendicular to diagonal; nearer means closer to diagonal\n const translatedLowerPAD = Math.floor((binX1 + binY1) / 2 / blockBinCount);\n const translatedHigherPAD = Math.floor((binX2 + binY2) / 2 / blockBinCount);\n const translatedNearerDepth = Math.floor(Math.log2(1 + Math.abs(binX1 - binY2) / Math.sqrt(2) / blockBinCount));\n const translatedFurtherDepth = Math.floor(Math.log2(1 + Math.abs(binX2 - binY1) / Math.sqrt(2) / blockBinCount));\n\n // because code above assume above diagonal; but we could be below diagonal\n const containsDiagonal = (binX2 - binY1) * (binX1 - binY2) < 0; // i.e. sign of (x-y) opposite on 2 corners\n const nearerDepth = containsDiagonal ? 0 : Math.min(translatedNearerDepth, translatedFurtherDepth);\n const furtherDepth = Math.max(translatedNearerDepth, translatedFurtherDepth);\n\n const blockNumbers = [];\n for (let depth = nearerDepth; depth <= furtherDepth; depth++) {\n for (let pad = translatedLowerPAD; pad <= translatedHigherPAD; pad++) {\n const block_number = depth * blockColumnCount + pad;\n blockNumbers.push(block_number)\n }\n }\n return blockNumbers\n }\n }\n\n static parseMatrixZoomData(chr1, chr2, dis) {\n\n const zd = new MatrixZoomData(chr1, chr2);\n\n const unit = dis.getString();\n const zoomIndex = dis.getInt();\n const sumCounts = dis.getFloat();\n const occupiedCellCount = dis.getFloat();\n const stdDev = dis.getFloat();\n const percent95 = dis.getFloat();\n const binSize = dis.getInt();\n zd. blockBinCount = dis.getInt();\n zd. blockColumnCount = dis.getInt();\n const nBlocks = dis.getInt();\n\n zd. zoom = {index: zoomIndex, unit: unit, binSize: binSize};\n\n zd.blockIndex = new StaticBlockIndex(nBlocks, dis);\n\n const nBins1 = (chr1.size / binSize);\n const nBins2 = (chr2.size / binSize);\n const avgCount = (sumCounts / nBins1) / nBins2; // <= trying to avoid overflows\n\n zd.averageCount = avgCount;\n zd.sumCounts = sumCounts;\n zd.stdDev = stdDev;\n zd.occupiedCellCount = occupiedCellCount;\n zd.percent95 = percent95;\n\n return zd;\n }\n}\n\n\nclass StaticBlockIndex {\n\n constructor(nBlocks, dis) {\n this.blockIndex = {};\n while (nBlocks-- > 0) {\n const blockNumber = dis.getInt();\n const filePosition = dis.getLong();\n const size = dis.getInt();\n this.blockIndex[blockNumber] = {filePosition, size};\n }\n }\n\n getBlockIndexEntry(blockNumber) {\n return this.blockIndex[blockNumber];\n }\n}\n\n\n/**\n * The dynamic block index looks up entries on-the-fly using a bisecting algorithm. It was developed for 1bp max\n * resolution files when block grids were square for intra-chromosomes (format v8). The rotated non-square grid\n * used for v9 makes this obsolete.\n */\nclass DynamicBlockIndex {\n\n constructor({file, position, nBlocks, maxBlock}) {\n this.file = file;\n this.minPosition = position;\n this.maxPosition = position + nBlocks * 16;\n this.nBlocks = nBlocks;\n this.maxBlock = maxBlock;\n }\n\n async getBlockIndexEntry(blockNumber) {\n if (blockNumber > this.maxBlock) {\n return undefined;\n } else if (this.blockNumberRange && blockNumber >= this.blockNumberRange.first && blockNumber <= this.blockNumberRange.last) {\n return this.blockIndexMap[blockNumber];\n } else {\n let minPosition = this.minPosition;\n let maxPosition = this.maxPosition;\n if (this.blockNumberRange && this.mapFileBounds) {\n if (blockNumber < this.blockNumberRange.first) {\n maxPosition = this.mapFileBounds.min;\n } else if (blockNumber > this.blockNumberRange.last) {\n minPosition = this.mapFileBounds.max;\n }\n }\n if (maxPosition - minPosition < 16) {\n return undefined;\n } else {\n return this.searchForBlockIndexEntry(blockNumber, minPosition, maxPosition);\n }\n }\n }\n\n\n // Search entry for blockNumber between file positions boundsMin and boundsMax\n // boundsMin is guaranteed to start at the beginning of an entry, boundsMax at the end\n async searchForBlockIndexEntry(blockNumber, boundsMin, boundsMax) {\n\n// console.log(`${blockNumber} ${boundsMin} ${boundsMax}`)\n const chunkSize = 16 * 100000;\n if (boundsMax - boundsMin < chunkSize) {\n const data = await this.file.read(boundsMin, boundsMax - boundsMin);\n const dis = new BinaryParser(new DataView(data));\n const blockIndex = {};\n let ptr = boundsMin;\n let firstBlockNumber, lastBlockNumber;\n while (ptr < boundsMax) {\n const bn = dis.getInt();\n const filePosition = dis.getLong();\n const blockSizeInBytes = dis.getInt();\n blockIndex[bn] = {filePosition: filePosition, size: blockSizeInBytes};\n if (firstBlockNumber === undefined) firstBlockNumber = bn;\n lastBlockNumber = bn;\n ptr += 16;\n }\n this.mapFileBounds = {min: boundsMin, max: boundsMax};\n this.blockNumberRange = {first: firstBlockNumber, last: lastBlockNumber};\n this.blockIndexMap = blockIndex;\n return blockIndex[blockNumber];\n\n }\n // Midpoint in units of 16 byte chunks\n const nEntries = (boundsMax - boundsMin) / 16;\n const pos1 = boundsMin + Math.floor(nEntries / 2) * 16;\n const data = await this.file.read(pos1, 16);\n const dis = new BinaryParser(new DataView(data));\n const bn = dis.getInt();\n if (bn === blockNumber) {\n const filePosition = dis.getLong();\n const blockSizeInBytes = dis.getInt();\n return {filePosition: filePosition, size: blockSizeInBytes} // Extraordinarily lucky\n } else if (blockNumber > bn) {\n const bie = await this.searchForBlockIndexEntry(blockNumber, pos1 + 16, boundsMax);\n return bie;\n } else {\n const bie = await this.searchForBlockIndexEntry(blockNumber, boundsMin, pos1);\n return bie;\n }\n }\n}\n\n\n\nexport default MatrixZoomData;","import BinaryParser from \"./binary.js\"\nimport MatrixZoomData from \"./matrixZoomData.js\"\n\nclass Matrix {\n\n constructor(chr1, chr2, zoomDataList) {\n this.chr1 = chr1\n this.chr2 = chr2\n this.bpZoomData = []\n this.fragZoomData = []\n for (let zd of zoomDataList) {\n if (zd.zoom.unit === \"BP\") {\n this.bpZoomData.push(zd)\n } else {\n this.fragZoomData.push(zd)\n }\n }\n }\n\n /**\n * Find the best zoom level for the given bin size\n * @param binSize\n * @param unit\n * @returns {number}\n */\n findZoomForResolution(binSize, unit) {\n const zdArray = \"FRAG\" === unit ? this.fragZoomData : this.bpZoomData\n for (let i = 1; i < zdArray.length; i++) {\n var zd = zdArray[i]\n if (zd.zoom.binSize < binSize) {\n return i - 1\n }\n }\n return zdArray.length - 1\n }\n\n /**\n * Fetch zoom data by bin size. If no matching level exists return undefined.\n *\n * @param unit\n * @param binSize\n * @param zoom\n * @returns {undefined|*}\n */\n getZoomData(binSize, unit) {\n unit = unit || \"BP\"\n const zdArray = unit === \"BP\" ? this.bpZoomData : this.fragZoomData;\n for (let i = 0; i < zdArray.length; i++) {\n var zd = zdArray[i];\n if (binSize === zd.zoom.binSize) {\n return zd\n }\n }\n return undefined\n }\n\n /**\n * Return zoom data by resolution index.\n * @param index\n * @param unit\n * @returns {*}\n */\n getZoomDataByIndex(index, unit) {\n const zdArray = \"FRAG\" === unit ? this.fragZoomData : this.bpZoomData\n return zdArray[index]\n }\n\n static getKey(chrIdx1, chrIdx2) {\n if (chrIdx1 > chrIdx2) {\n const tmp = chrIdx1\n chrIdx1 = chrIdx2\n chrIdx2 = tmp\n }\n return `${chrIdx1}_${chrIdx2}`;\n }\n\n static parseMatrix(data, chromosomes) {\n\n const dis = new BinaryParser(new DataView(data));\n const c1 = dis.getInt(); // Should equal chrIdx1\n const c2 = dis.getInt(); // Should equal chrIdx2\n\n // TODO validate this\n const chr1 = chromosomes[c1];\n const chr2 = chromosomes[c2];\n\n // # of resolution levels (bp and frags)\n let nResolutions = dis.getInt();\n const zdList = [];\n\n while (nResolutions-- > 0) {\n const zd = MatrixZoomData.parseMatrixZoomData(chr1, chr2, dis);\n zdList.push(zd);\n }\n return new Matrix(c1, c2, zdList);\n }\n\n}\n\nexport default Matrix;","\nclass ContactRecord {\n\n constructor(bin1, bin2, counts) {\n this.bin1 = bin1;\n this.bin2 = bin2;\n this.counts = counts;\n };\n\n getKey() {\n return \"\" + this.bin1 + \"_\" + this.bin2;\n }\n}\n\nexport default ContactRecord;","class LRU {\n constructor(max = 10) {\n this.max = max;\n this.map = new Map();\n }\n\n get(key) {\n let item = this.map.get(key);\n if (item) {\n // refresh key\n this.map.delete(key);\n this.map.set(key, item);\n }\n return item;\n }\n\n set(key, val) {\n // refresh key\n if (this.map.has(key)) this.map.delete(key);\n // evict oldest\n else if (this.map.size === this.max) {\n this.map.delete(this.first());\n }\n this.map.set(key, val);\n }\n\n has(key) {\n return this.map.has(key);\n }\n\n clear() {\n this.map.clear();\n }\n\n first() {\n return this.map.keys().next().value;\n }\n}\n\n//ref https://stackoverflow.com/questions/996505/lru-cache-implementation-in-javascript\n\nexport default LRU\n","/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2016-2017 The Regents of the University of California\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and\n * associated documentation files (the \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the\n * following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all copies or substantial\n * portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING\n * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n *\n */\n\n\nimport BinaryParser from \"./binary.js\"\n\n/**\n * @author Jim Robinson\n */\n\nconst Short_MIN_VALUE = -32768;\nconst DOUBLE = 8\nconst FLOAT = 4\nconst LONG = 8;\nconst INT = 4;\n\nclass NormalizationVector {\n\n constructor(file, filePosition, nValues, dataType) {\n this.file = file;\n this.filePosition = filePosition;\n this.nValues = nValues;\n this.dataType = dataType;\n this.cache = undefined;\n }\n\n async getValues(start, end) {\n\n if(!this.cache || start < this.cache.start || end > this.cache.end) {\n const adjustedStart = Math.max(0, start - 1000);\n const adjustedEnd = Math.min(this.nValues, end + 1000);\n const startPosition = this.filePosition + adjustedStart * this.dataType;\n const n = adjustedEnd - adjustedStart;\n const sizeInBytes = n * this.dataType;\n const data = await this.file.read(startPosition, sizeInBytes);\n if (!data) {\n return undefined;\n }\n const parser = new BinaryParser(new DataView(data));\n\n const values = [];\n for (let i = 0; i < n; i++) {\n values[i] = this.dataType === DOUBLE ? parser.getDouble() : parser.getFloat();\n\n }\n this.cache = {\n start: adjustedStart,\n end: adjustedEnd,\n values: values\n }\n }\n\n const sliceStart = start - this.cache.start;\n const sliceEnd = sliceStart + (end - start);\n return this.cache.values.slice(sliceStart, sliceEnd);\n }\n\n getKey() {\n return NormalizationVector.getKey(this.type, this.chrIdx, this.unit, this.resolution);\n }\n\n\n static getNormalizationVectorKey(type, chrIdx, unit, resolution) {\n return type + \"_\" + chrIdx + \"_\" + unit + \"_\" + resolution;\n }\n}\n\n\n\nexport default NormalizationVector;\n","// Contains \"normalization vector index\" (nvi values) for legacy (v8) hosted files from aidenlab, ENCODE, and 4DN.\n// These values can speed up initialization by a few seconds.\nexport default {\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2Fcombined.hic\": \"54386046426,55860\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2Fprimary.hic\": \"33860030033,37504\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2Freplicate.hic\": \"30849652794,55832\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2Fmaternal.hic\": \"1380542661,17185\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2Fpaternal.hic\": \"1389001777,17185\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fimr90%2Fin-situ%2Fcombined.hic\": \"13433880319,35723\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC001.hic\": \"3409347253,35975\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC002.hic\": \"4529947083,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC003.hic\": \"6894962500,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC004.hic\": \"3395593338,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC005.hic\": \"5204128636,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC006.hic\": \"3278363811,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC007.hic\": \"3585547340,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC008.hic\": \"4134197273,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC009.hic\": \"2851728310,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC010.hic\": \"1754216102,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC011.hic\": \"1716829574,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC012.hic\": \"4367980375,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC013.hic\": \"2309654671,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC014.hic\": \"5324950266,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC015.hic\": \"3132333594,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC016.hic\": \"3159154704,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC017.hic\": \"3262554627,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC018.hic\": \"3014216364,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC019.hic\": \"5025753246,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC020.hic\": \"5861584507,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC021.hic\": \"3542263275,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC022.hic\": \"5061949378,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC023.hic\": \"4816423919,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC024.hic\": \"2683781104,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC025.hic\": \"6522701781,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC026.hic\": \"6748846520,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC027.hic\": \"5642693007,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC028.hic\": \"2098921691,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC029.hic\": \"3886454027,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fagar%2FHIC030.hic\": \"2288984204,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fagar%2FHIC031.hic\": \"2115342419,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fpellet%2FHIC032.hic\": \"2063314324,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fsupernatant%2FHIC033.hic\": \"1933908457,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fdilution%2FHIC034.hic\": \"13555514595,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fdilution%2FHIC035.hic\": \"6129650900,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fdilution%2FHIC036.hic\": \"4307445019,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fdilution%2FHIC037.hic\": \"9375139867,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fdilution%2Fcombined.hic\": \"11664249584,33929\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2Fcombined_DpnII.hic\": \"7003537290,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC038.hic\": \"2099825544,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC039.hic\": \"2096900138,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC040.hic\": \"2593642141,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC041.hic\": \"2263919098,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC042.hic\": \"2684774693,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2Fcombined_noXlink.hic\": \"5574807456,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC043.hic\": \"2986114347,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC044.hic\": \"1916378621,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC045.hic\": \"746463126,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC046.hic\": \"2338476164,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC047.hic\": \"1167496250,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC048.hic\": \"2231690794,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC049.hic\": \"2782308678,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fimr90%2Fin-situ%2FHIC050.hic\": \"3633531346,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fimr90%2Fin-situ%2FHIC051.hic\": \"4063486444,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fimr90%2Fin-situ%2FHIC052.hic\": \"929756278,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fimr90%2Fin-situ%2FHIC053.hic\": \"2489657204,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fimr90%2Fin-situ%2FHIC054.hic\": \"4036419444,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fimr90%2Fin-situ%2FHIC055.hic\": \"4284185549,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fimr90%2Fin-situ%2FHIC056.hic\": \"4410546240,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fimr90%2Fdilution%2FHIC057.hic\": \"1491998259,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fhmec%2Fin-situ%2Fcombined.hic\": \"7266425111,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fhmec%2Fin-situ%2FHIC058.hic\": \"6532635593,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fhmec%2Fin-situ%2FHIC059.hic\": \"400684530,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fhmec%2Fin-situ%2FHIC060.hic\": \"645352187,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fhmec%2Fin-situ%2FHIC061.hic\": \"736291871,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fhmec%2Fin-situ%2FHIC062.hic\": \"762731037,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fhmec%2Fin-situ%2FHIC063.hic\": \"682917431,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fhmec%2Fdilution%2FHIC064.hic\": \"4550171307,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fnhek%2Fin-situ%2Fcombined.hic\": \"11897184911,35789\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fnhek%2Fin-situ%2FHIC065.hic\": \"5425943567,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fnhek%2Fin-situ%2FHIC066.hic\": \"5942869818,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fnhek%2Fin-situ%2FHIC067.hic\": \"5191049261,35647\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fnhek%2Fdilution%2FHIC068.hic\": \"2713318801,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fk562%2Fin-situ%2Fcombined.hic\": \"12641555389,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fk562%2Fin-situ%2FHIC069.hic\": \"5630177461,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fk562%2Fin-situ%2FHIC070.hic\": \"5926611269,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fk562%2Fin-situ%2FHIC071.hic\": \"2486191351,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fk562%2Fin-situ%2FHIC072.hic\": \"2281343366,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fk562%2Fin-situ%2FHIC073.hic\": \"2173074239,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fk562%2Fin-situ%2FHIC074.hic\": \"2463700999,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fkbm7%2Fin-situ%2Fcombined.hic\": \"14661922519,35639\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fkbm7%2Fin-situ%2FHIC075.hic\": \"3685310515,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fkbm7%2Fin-situ%2FHIC076.hic\": \"5833658487,35891\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fkbm7%2Fin-situ%2FHIC077.hic\": \"2406346486,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fkbm7%2Fin-situ%2FHIC078.hic\": \"5241454987,35919\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fkbm7%2Fin-situ%2FHIC079.hic\": \"6297234263,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fhuvec%2Fin-situ%2Fcombined.hic\": \"9193858096,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fhuvec%2Fin-situ%2FHIC080.hic\": \"5171405536,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fhuvec%2Fin-situ%2FHIC081.hic\": \"3489767688,35891\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fhuvec%2Fin-situ%2FHIC082.hic\": \"4243339375,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fhuvec%2Fdilution%2FHIC083.hic\": \"1497495406,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fhela%2Fin-situ%2Fcombined.hic\": \"7923332224,35593\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fhela%2Fin-situ%2FHIC084.hic\": \"867699123,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fhela%2Fin-situ%2FHIC085.hic\": \"3669518514,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fhela%2Fin-situ%2FHIC086.hic\": \"5306474712,35595\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fhela%2Fin-situ%2FHIC087.hic\": \"1490963755,36397\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2Fcombined.hic\": \"8956382853,50248\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2FHIC088.hic\": \"1874185366,32102\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2FHIC089.hic\": \"1301165236,32102\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2FHIC090.hic\": \"1105246282,32102\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2FHIC091.hic\": \"1338325770,32102\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2FHIC092.hic\": \"1307918730,32102\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2FHIC093.hic\": \"755136918,32102\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2FHIC094.hic\": \"1606583694,32102\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2FHIC095.hic\": \"2039711245,32102\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2FHIC096.hic\": \"1909573053,32102\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2FHIC097.hic\": \"1826710712,32102\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2FHIC098.hic\": \"1998793575,32102\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2FHIC099.hic\": \"1007740962,32102\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2FHIC100.hic\": \"736464120,32102\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2FHIC101.hic\": \"980505082,32102\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2FHIC102.hic\": \"1116083646,32102\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fdilution%2FHIC103.hic\": \"1096994310,32102\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fdilution%2FHIC104.hic\": \"841063882,32102\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC105.hic\": \"107742864,36479\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC106.hic\": \"134295912,36479\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC107.hic\": \"110228014,36479\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC108.hic\": \"102761401,36479\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC109.hic\": \"100461491,36479\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC110.hic\": \"88828472,36479\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC111.hic\": \"81471064,36479\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC112.hic\": \"92297035,36479\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC113.hic\": \"65503916,36479\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC114.hic\": \"49181188,36479\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC115.hic\": \"46471102,36479\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC116.hic\": \"64284432,36479\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC117.hic\": \"60434076,36479\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC118.hic\": \"45248563,36479\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC119.hic\": \"60288782,36479\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC120.hic\": \"136888414,36479\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC121.hic\": \"125009003,33681\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC122.hic\": \"154011688,34127\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC123.hic\": \"177663372,35293\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC124.hic\": \"382186226,35245\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC125.hic\": \"158160717,35271\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC127.hic\": \"110261177,34659\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC128.hic\": \"246131875,35509\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC129.hic\": \"260160119,35667\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC130.hic\": \"117479562,34681\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC131.hic\": \"81508929,34673\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC132.hic\": \"105959102,34895\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC133.hic\": \"91504812,33451\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC134.hic\": \"52222546,33737\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC135.hic\": \"57763085,34159\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC136.hic\": \"50618489,33731\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC137.hic\": \"193163606,33363\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC138.hic\": \"229876152,33777\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC139.hic\": \"201783666,33571\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC140.hic\": \"281163862,34125\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC141.hic\": \"275969727,33935\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC142.hic\": \"275020431,34125\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC144.hic\": \"223834810,34177\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC145.hic\": \"296632653,33937\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC146.hic\": \"290945216,33961\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC147.hic\": \"234459964,34231\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC148.hic\": \"295457850,34039\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC149.hic\": \"113569632,35695\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC150.hic\": \"304381897,33963\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC151.hic\": \"289314545,33805\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC152.hic\": \"284320182,33803\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC153.hic\": \"401393947,34659\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC154.hic\": \"188065488,36479\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC155.hic\": \"299157119,33967\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC156.hic\": \"279289244,33787\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC157.hic\": \"254852119,33917\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC158.hic\": \"195969660,33477\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC159.hic\": \"185720388,36479\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC160.hic\": \"227709279,33599\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC161.hic\": \"157225076,33209\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC162.hic\": \"105703444,32033\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC163.hic\": \"122665658,32121\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC164.hic\": \"228048231,33761\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC165.hic\": \"114440819,32011\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC166.hic\": \"285147558,33891\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC167.hic\": \"363116754,33943\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC168.hic\": \"119592158,31937\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC169.hic\": \"236853872,33785\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC170.hic\": \"195187639,33395\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC171.hic\": \"208044058,33309\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC172.hic\": \"144645916,32877\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC173.hic\": \"119115941,32203\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC175.hic\": \"178030481,33525\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC176.hic\": \"117220136,32169\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC177.hic\": \"128586196,32659\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC178.hic\": \"191419141,33629\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC179.hic\": \"141556748,32959\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC180.hic\": \"199825102,33185\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC181.hic\": \"301022688,33783\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC182.hic\": \"185384453,33205\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC183.hic\": \"202189264,36367\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC184.hic\": \"37464475,36479\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC185.hic\": \"161938278,36099\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC186.hic\": \"133853166,36179\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC188.hic\": \"128068030,36237\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC189.hic\": \"148053886,36177\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC190.hic\": \"198946958,35803\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC191.hic\": \"226584564,36063\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC192.hic\": \"194412797,36341\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC193.hic\": \"176408194,36479\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC194.hic\": \"207215649,36055\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC195.hic\": \"175185530,36315\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC196.hic\": \"168969337,36479\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC197.hic\": \"121231252,36339\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC198.hic\": \"92713752,36479\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC199.hic\": \"105130500,36479\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC200.hic\": \"114526350,36479\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC201.hic\": \"122689717,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fhap1%2Fin-situ%2Fcombined.hic\": \"9614983328,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fexternal%2Fctbp_8_4_17%2Fall_intra_megabase_michrom.hic\": \"154205644,10960\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2Fdel-Xa-combined.hic\": \"8843305329,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FdelXa-chrX-diploid.hic\": \"11173520,1498\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FWT-combined.hic\": \"13365182403,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FWT-chrX-diploid.hic\": \"17343459,1498\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FHIC002.hic\": \"4279298739,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FHIC003.hic\": \"3027365532,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FHIC004.hic\": \"2896130835,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FHIC005.hic\": \"4717830071,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FHIC006.hic\": \"5066210154,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FHIC007.hic\": \"3069516128,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2Fdel-Xi-combined.hic\": \"14551096423,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FdelXi-chrX-diploid.hic\": \"17362477,1498\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FHIC008.hic\": \"2572386655,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FHIC009.hic\": \"2935931663,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FHIC010.hic\": \"2019085070,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FHIC011.hic\": \"6087610814,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FHIC012.hic\": \"2809618194,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FHIC013.hic\": \"2572386655,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fpatski%2FDarrowHuntley-2015%2Fcombined.hic\": \"6950423609,32102\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fpatski%2FDarrowHuntley-2015%2Fpaternal.hic\": \"220592749,15691\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fpatski%2FDarrowHuntley-2015%2Fmaternal.hic\": \"323233095,15691\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fpatski%2FDarrowHuntley-2015%2FHIC014.hic\": \"3183235800,32102\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fpatski%2FDarrowHuntley-2015%2FHIC015.hic\": \"1739539801,32102\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fpatski%2FDarrowHuntley-2015%2FHIC016.hic\": \"1105912758,32102\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fpatski%2FDarrowHuntley-2015%2FHIC017.hic\": \"1060773319,32102\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fpatski%2FDarrowHuntley-2015%2FHIC018.hic\": \"1203679874,32102\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fpatski%2FDarrowHuntley-2015%2FHIC019.hic\": \"3321955269,32102\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Frhesus%2FDarrowHuntley-2015%2FHIC020.hic\": \"7108980626,32102\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fcola%2FDarrowHuntley-2015%2FHIC021.hic\": \"3906448676,34955\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fassembly%2Faedes%2Fcombined.hic\": \"390780490,2245\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fassembly%2Fhs2-hic.hic\": \"1960284186,33561\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fassembly%2FCpipJ3.hic\": \"766279097,4381\",\n \"s3.amazonaws.com%2Fhicfiles%2Fexternal%2Fphanstiel%2Fupdated_O%2FSnyder_O.hic\": \"8046980555,18679\",\n \"s3.amazonaws.com%2Fhicfiles%2Fexternal%2Fphanstiel%2FA_inter.hic\": \"10986005145,18679\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Funtreated%2Funsynchronized%2Fcombined.hic\": \"30439217680,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftreated_6hr%2Funsynchronized%2Fcombined.hic\": \"33255540403,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2Fdeep%2F20min_withdraw_combined.hic\": \"11078436933,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2Fdeep%2F40min_withdraw_combined.hic\": \"11031830038,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2Fdeep%2F60min_withdraw_combined.hic\": \"10312725340,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2Fdeep%2F180min_withdraw_combined.hic\": \"10038610214,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Funtreated%2Funsynchronized%2FHIC001.hic\": \"8004335785,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Funtreated%2Funsynchronized%2FHIC002.hic\": \"8453215933,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Funtreated%2Funsynchronized%2FHIC003.hic\": \"9118406189,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Funtreated%2Funsynchronized%2FHIC004.hic\": \"5973342894,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Funtreated%2Funsynchronized%2FHIC005.hic\": \"6846576837,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Funtreated%2Funsynchronized%2FHIC006.hic\": \"6075148017,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Funtreated%2Funsynchronized%2FHIC007.hic\": \"8192366992,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftreated_6hr%2Funsynchronized%2FHIC008.hic\": \"6844159653,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftreated_6hr%2Funsynchronized%2FHIC009.hic\": \"7282063059,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftreated_6hr%2Funsynchronized%2FHIC010.hic\": \"10410578833,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftreated_6hr%2Funsynchronized%2FHIC011.hic\": \"8192366992,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftreated_6hr%2Funsynchronized%2FHIC012.hic\": \"7223422850,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftreated_6hr%2Funsynchronized%2FHIC013.hic\": \"7435986997,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftreated_6hr%2Funsynchronized%2FHIC014.hic\": \"9120113605,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Funtreated%2Fsynchronized%2Fcombined.hic\": \"4170577904,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Funtreated%2Fsynchronized%2FHIC015.hic\": \"1504084990,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Funtreated%2Fsynchronized%2FHIC016.hic\": \"1686244500,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Funtreated%2Fsynchronized%2FHIC017.hic\": \"1804802410,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Funtreated%2Fsynchronized%2FHIC018.hic\": \"1533942067,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftreated_6hr%2Fsynchronized%2Fcombined.hic\": \"4572390198,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftreated_6hr%2Fsynchronized%2FHIC019.hic\": \"1543609666,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftreated_6hr%2Fsynchronized%2FHIC020.hic\": \"1814133288,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftreated_6hr%2Fsynchronized%2FHIC021.hic\": \"1942698243,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftreated_6hr%2Fsynchronized%2FHIC022.hic\": \"1873587413,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2Funtreated%2FRao-2017-HIC049.hic\": \"405127557,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2Funtreated%2FRao-2017-HIC060.hic\": \"326681741,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2Funtreated%2FRao-2017-HIC061.hic\": \"300908673,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_20min%2FRao-2017-HIC050.hic\": \"481758242,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_20min%2FRao-2017-HIC051.hic\": \"417577401,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_40min%2FRao-2017-HIC052.hic\": \"419353227,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_40min%2FRao-2017-HIC053.hic\": \"411554953,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_60min%2FRao-2017-HIC054.hic\": \"386655891,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_60min%2FRao-2017-HIC055.hic\": \"402170701,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_240min%2FRao-2017-HIC057.hic\": \"735906308,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min%2FRao-2017-HIC058.hic\": \"443789827,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min%2FRao-2017-HIC059.hic\": \"491422615,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min%2FRao-2017-HIC062.hic\": \"320261375,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min%2FRao-2017-HIC063.hic\": \"306590499,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min_withdraw_20min%2FRao-2017-HIC032S.hic\": \"367051742,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min_withdraw_20min%2FRao-2017-HIC033S.hic\": \"344555339,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min_withdraw_40min%2FRao-2017-HIC036S.hic\": \"349392947,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min_withdraw_40min%2FRao-2017-HIC037S.hic\": \"317714554,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min_withdraw_60min%2FRao-2017-HIC040S.hic\": \"266786397,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min_withdraw_60min%2FRao-2017-HIC041S.hic\": \"279445530,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min_withdraw_180min%2FRao-2017-HIC044S.hic\": \"898418269,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min_withdraw_180min%2FRao-2017-HIC045S.hic\": \"961006347,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min_withdraw_360min%2FRao-2017-HIC064.hic\": \"833576408,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min_withdraw_360min%2FRao-2017-HIC065.hic\": \"840881418,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min_withdraw_1080min%2FRao-2017-HIC066.hic\": \"980958864,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min_withdraw_1080min%2FRao-2017-HIC067.hic\": \"882023129,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min_withdraw_1440min%2FRao-2017-HIC068.hic\": \"1110292630,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min_withdraw_1440min%2FRao-2017-HIC069.hic\": \"1001747023,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fexternal%2Frowley_nichols_mol_cell_2017%2FCP190_HiChIP.hic\": \"144107588,6976\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fexternal%2Frowley_nichols_mol_cell_2017%2FH3K27ac_HiChIP_combined.hic\": \"43171370,5233\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fexternal%2Frowley_nichols_mol_cell_2017%2FH3K27me3_HiChIP_combined.hic\": \"42906472,5233\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fexternal%2Frowley_nichols_mol_cell_2017%2FPol2_ChIAPET.hic\": \"41992430,6976\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fexternal%2Frowley_nichols_mol_cell_2017%2FPol2S2_HiChIP.hic\": \"145842743,6976\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fexternal%2Frowley_nichols_mol_cell_2017%2FArabidopsis_Wang2015_Liu2016.hic\": \"1134391078,4984\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fexternal%2Frowley_nichols_mol_cell_2017%2FElegans_Crane2015.hic\": \"387127568,8758\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fexternal%2Frowley_nichols_mol_cell_2017%2FNcrassa_Galazka2016.hic\": \"26555511,27725\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fexternal%2Frowley_nichols_mol_cell_2017%2FPfalciparum_trophozoite_Ay2014.hic\": \"15640893,13948\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fduan%2FE-Me-A.hic\": \"6897251,23348\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fduan%2FE-Me-B.hic\": \"4959088,23348\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fduan%2FE-Mp-A.hic\": \"5232286,23348\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fduan%2FE-Mp-B.hic\": \"5105292,23348\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fduan%2FH-Me-A.hic\": \"6900072,23348\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fduan%2FH-Me-B.hic\": \"8653258,23348\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fduan%2FH-Mp-A.hic\": \"7999058,23348\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fduan%2FH-Mp-B.hic\": \"8774657,23348\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fdekker%2F4dn%2Fh1hesc.hic\": \"23671753603,36479\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fdekker%2F4dn%2Fh1hesc_rep1.hic\": \"23671754721,36479\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fdekker%2F4dn%2Fh1hesc_rep2.hic\": \"22269909910,36479\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fdekker%2F4dn%2Fhffc6_rep1.hic\": \"19016661622,36479\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Flieberman_aiden_van_berkum%2FGM06990_NcoI.hic\": \"480725203,36479\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Flieberman_aiden_van_berkum%2F302NH.hic\": \"99948617,36479\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Flieberman_aiden_van_berkum%2FK562.hic\": \"470263605,36151\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Flieberman_aiden_van_berkum%2FGM06990_HindIII.hic\": \"293706559,36289\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Flieberman_aiden_van_berkum%2FGM06990_rep_HindIII.hic\": \"309673862,36087\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Frudan%2Fcanis-lupus-rep1.hic\": \"1531151371,56905\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Frudan%2Fcanis-lupus-rep2.hic\": \"2851437676,56905\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Frudan%2Fmouse-rep1.hic\": \"582052544,32102\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Frudan%2Fmacaque-rep1.hic\": \"698509182,32102\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Frudan%2Fmacaque-rep2.hic\": \"461410393,32102\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Frudan%2Frabbit-rep1.hic\": \"691045338,33561\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Frudan%2Frabbit-rep2.hic\": \"668888336,33561\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fsexton%2Fcombined.hic\": \"50650087,4486\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fkalhor%2Ftcc-hindiii.hic\": \"1071142023,16500\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fkalhor%2Ftcc-mboi.hic\": \"1508851093,16448\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fkalhor%2Fnon-tcc-hindiii.hic\": \"395179229,36093\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fkalhor%2Ftcc-combined.hic\": \"1050423847,36479\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fdixon%2Fmm9-hindiii%2Fsplit-read-run.hic\": \"9599984876,32102\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fdixon%2Fhesc-hindiii.hic\": \"1952555632,36479\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fdixon%2Fimr90-hindiii.hic\": \"9691260435,18679\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fdixon%2Fmm9-cortex.hic\": \"3712072953,32102\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fzhang%2Fatm-i-scei-chr18.hic\": \"2083350075,16438\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fzhang%2Fatm-i-scei-chr2.hic\": \"3362049644,16360\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fzhang%2Fatm-i-scei-chr7.hic\": \"1658399854,16438\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fzhang%2Fwt-i-scei-chr15.hic\": \"866691249,16438\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fzhang%2Fwt-i-scei-chr2.hic\": \"3304782795,16386\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fnagano%2Fcell-1.hic\": \"23673506,32102\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fnagano%2Fcell-2.hic\": \"26873280,30643\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fnagano%2Fcell-3.hic\": \"31066362,30643\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fnagano%2Fcell-4.hic\": \"16807724,30643\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fnagano%2Fcell-5.hic\": \"28665065,30643\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fnagano%2Fcell-6.hic\": \"13124158,30643\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fnagano%2Fcell-7.hic\": \"15118945,30643\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fnagano%2Fcell-8.hic\": \"68316814,32102\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fnagano%2Fcell-9.hic\": \"18965101,30643\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fnagano%2Fcell-10.hic\": \"17020666,30643\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fjin%2Fimr90%2Fcombined.hic\": \"6526601242,36427\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fjin%2Fimr90%2Frep1.hic\": \"1861562891,36401\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fjin%2Fimr90%2Frep2.hic\": \"3061013635,36479\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fjin%2Fimr90%2Frep3.hic\": \"1564588211,35969\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fjin%2Fimr90%2Frep4.hic\": \"1255543175,36153\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fjin%2Fimr90%2Frep5.hic\": \"974683253,36179\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fjin%2Fimr90%2Frep6.hic\": \"1040805629,36053\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fjin%2Fimr90-tnf-alpha%2Fcombined.hic\": \"8424080116,36401\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fjin%2Fimr90-tnf-alpha%2Frep1.hic\": \"2697976702,36295\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fjin%2Fimr90-tnf-alpha%2Frep3.hic\": \"1718610467,36159\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fjin%2Fimr90-tnf-alpha%2Frep4.hic\": \"2029519405,36101\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fjin%2Fimr90-tnf-alpha%2Frep5.hic\": \"985310855,36069\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fjin%2Fimr90-tnf-alpha%2Frep6.hic\": \"1418750480,35967\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fcheng%2Fmhh-call-4-cell-line.hic\": \"538380253,35351\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fcheng%2Fprimary-b-all.hic\": \"773764191,35793\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fcheng%2Fnormal-b-cell-line.hic\": \"336271459,35005\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fcheng%2Frl-cell-line.hic\": \"484807998,35351\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fhou%2Fkc167-biorep.hic\": \"135932435,8758\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fhou%2Fkc167-techrep1.hic\": \"160355961,8758\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fhou%2Fkc167-techrep2.hic\": \"188809887,8758\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Flin%2Fpre-prob-egs.hic\": \"2237792858,15483\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Flin%2Fprob-egs.hic\": \"5744720377,16438\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Flin%2Fprob-fa.hic\": \"2174866215,16438\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fli%2Fhct116-rnapii-pilot.hic\": \"396366166,35999\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fli%2Fhela-rnapii-pilot.hic\": \"882516759,35107\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fli%2Fk562-rnapii-pilot.hic\": \"1131576189,35969\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fli%2Fk562-rnapii-saturated.hic\": \"571583828,36291\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fli%2Fmcf7-rnapii-saturated.hic\": \"1282547841,36035\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fli%2Fnb4-rnapii-pilot.hic\": \"761614686,34861\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fjung%2Fmouse_sperm.hic\": \"1730231642,29184\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Ftang%2Fgm12878.hic\": \"1953518212,20505\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Frutledge%2FSRR1791299.hic\": \"5723484,11956\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Frutledge%2FSRR1791297.hic\": \"16534743,23348\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fzuin%2Fhek293t-rad21cv-hrv.hic\": \"5094525579,36289\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fzuin%2Fhek293t-rad21cv-hrv-rep1.hic\": \"2574358912,36373\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fzuin%2Fhek293t-rad21cv-hrv-rep2.hic\": \"3417099433,36243\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fzuin%2Fhek293t-rad21cv-tev.hic\": \"4785157552,36323\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fzuin%2Fhek293t-rad21cv-tev-rep1.hic\": \"2648268465,36321\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fzuin%2Fhek293t-rad21cv-tev-rep2.hic\": \"2994727980,36107\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fzuin%2Fhek293t-sirna-ctcf.hic\": \"5391791815,36063\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fzuin%2Fhek293t-sirna-ctcf-rep1.hic\": \"3325842095,36269\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fzuin%2Fhek293t-sirna-ctcf-rep2.hic\": \"3096215920,36167\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fzuin%2Fhek293t-sirna-ctrl.hic\": \"3830902383,36167\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fzuin%2Fhek293t-sirna-ctrl-rep1.hic\": \"1346712252,36079\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fzuin%2Fhek293t-sirna-ctrl_rep2.hic\": \"3098067367,36271\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fay%2Fp-falciparum-3d7-0h-hiseq.hic\": \"38174042,21889\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fay%2Fp-falciparum-3d7-18h-hiseq.hic\": \"26506099,21889\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fay%2Fp-falciparum-3d7-18h-hiseq-non-crosslinked_control.hic\": \"3545496,21889\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fay%2Fp-falciparum-3d7-36h-hiseq.hic\": \"70754194,21889\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fnaumova%2Fhelas3%2Fg1mid-r1.hic\": \"200863476,17185\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fnaumova%2Fhelas3%2Fm-r1.hic\": \"249021190,17185\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fnaumova%2Fhelas3%2Fm-r2.hic\": \"212341157,17185\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fnaumova%2Fhelas3ccl2p2%2Fg1-0-25fa.hic\": \"583572265,17185\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fnaumova%2Fhelas3ccl2p2%2Fg1-1fa.hic\": \"354502306,17185\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fnaumova%2Fhelas3ccl2p2%2Fm-0-25fa.hic\": \"149308791,17185\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fnaumova%2Fhelas3ccl2p2%2Fm-98percent.hic\": \"778175225,17185\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fnaumova%2Fhelas3ccl2p2%2Fm-1fa.hic\": \"158091047,17185\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fnaumova%2Fhff1%2Fcchic-hff1-ns-r1.hic\": \"801670039,17185\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fnaumova%2Fhff1%2Fcchic-hff1-m-r1.hic\": \"875922086,17185\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fnaumova%2Fk562%2Fm-r1.hic\": \"130959943,17185\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fnaumova%2Fk562%2Fm-r2.hic\": \"237861106,17185\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fsofueva%2FmAST-WT.hic\": \"496104039,30643\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fsofueva%2FmAST-WT-adv-cre.hic\": \"438608517,30643\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fsofueva%2FmAST-floxed-rep1.hic\": \"446205712,32102\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fsofueva%2FmAST-floxed-rep2.hic\": \"386354767,32102\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fsofueva%2FmAST-deleted-rep1.hic\": \"621998722,30643\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fsofueva%2FmAST-deleted-rep2.hic\": \"583840829,32102\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fsofueva%2FmNSC-floxed-rep1.hic\": \"801290988,30643\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fsofueva%2FmNSC-floxed-rep2.hic\": \"819406658,30643\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fsofueva%2FmNSC-deleted-rep1.hic\": \"792825269,32102\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fsofueva%2FmNSC-deleted-rep2.hic\": \"746189884,30643\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fsofueva%2FmNSC-WT.hic\": \"309353372,30643\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fsofueva%2FmNSC-WT-OHT.hic\": \"274229679,30643\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fseitan%2FTcell-Rad21KO-R1.hic\": \"1490362251,32102\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fseitan%2FTcell-Rad21KO-R3.hic\": \"2403664421,32102\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fseitan%2FTcell-Rad21WT-R1.hic\": \"1377124538,32102\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fseitan%2FTcell-Rad21WT-R3.hic\": \"2646201369,32102\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fmoissiard%2Fcrh6-mutant.hic\": \"105261071,10217\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fmoissiard%2FWT.hic\": \"127506388,10217\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fgrob%2FCol.hic\": \"153638500,10217\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fgrob%2Fcrwn1.hic\": \"211213220,10217\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fgrob%2Fcrwn4.hic\": \"134236837,10217\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fxie%2Fprimary.hic\": \"92936173,10217\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Ffeng%2F6wt-control6wt337.hic\": \"318737891,10217\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Ffeng%2F6wt-control6wt67.hic\": \"348123956,10217\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Ffeng%2F6wt337.hic\": \"251107279,10217\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Ffeng%2F6wt67.hic\": \"351840994,10217\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Ffeng%2FCol0.hic\": \"345969497,10217\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Ffeng%2Fclf28-swn7.hic\": \"299585025,10217\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Ffeng%2Fcmt3-11.hic\": \"253427706,10217\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Ffeng%2Fddm1-2.hic\": \"303626924,10217\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Ffeng%2Fmet1-3.hic\": \"347697973,10217\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Ffeng%2Fsuvh4-suvh5-suvh6.hic\": \"263122019,10217\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fma%2FDNase-HiC-WG-K562.hic\": \"892955840,18679\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fma%2FDNaseHiC-WG-H1.hic\": \"696922695,18679\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fma%2FtargetedDNaseHiC-lincRNA-K562-rep1.hic\": \"341917716,18679\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fma%2FtargeredDNaseHiC-lincRNA-K562-rep2.hic\": \"214841185,18679\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fma%2FtargetedDNaseHiC-lincRNA-H1-rep1.hic\": \"616326137,18679\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fma%2FtargetedDNaseHiC-lincRNA-H1-rep2.hic\": \"579654013,18679\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fma%2FtargetedDNaseHiC-pe-H1-rep1.hic\": \"519810544,18679\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fma%2FtargetedDNaseHiC-pe-K562-rep1.hic\": \"199553123,18679\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Frowley%2FKc167_DpnII.hic\": \"1319373594,6976\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Frowley%2FKc167_HinfI.hic\": \"1465493873,6976\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Frowley%2FKc167_DpnII_HinfI_combo.hic\": \"753062558,5814\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fbarutcu%2FMCF-10A.hic\": \"2784956115,36479\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fbarutcu%2FMCF-7.hic\": \"2700457411,36479\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fbatullin%2Fsperm.hic\": \"501052169,32102\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fminajigi%2FWT_hiC_rep1.hic\": \"1450697530,32102\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fminajigi%2FWT_hiC_rep2.hic\": \"1189371558,32102\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fminajigi%2Fcombined.hic\": \"2262007875,32102\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fminajigi%2Finactive.hic\": \"4444564,751\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fminajigi%2Factive.hic\": \"3993495,751\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fdeng%2Fpatski_rep1.hic\": \"1650838357,32102\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fdeng%2Fpatski_rep2.hic\": \"1258038606,32102\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fdeng%2Fpatski.hic\": \"499827296,16438\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fdeng%2Fpatski_active.hic\": \"79175714,15691\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fdeng%2Fpatski_inactive.hic\": \"98947881,15691\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fdeng%2Fbrain_dnase.hic\": \"4298088401,32102\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fdeng%2Fbrain_in_situ_dnase.hic\": \"609321852,32102\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fdeng%2Fbrain.hic\": \"1028196506,16438\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fdeng%2Fbrain_active.hic\": \"79175714,15691\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fdeng%2Fbrain_inactive.hic\": \"98947881,15691\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fle%2FBglII_rep1.hic\": \"1283306,1463\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fle%2FBglII_rep2.hic\": \"1263227,1463\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fle%2FNcoI_rep1.hic\": \"4380906,1463\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Feagen%2FGSE89112_Kc167combined.hic\": \"1829549643,25624\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Feagen%2FGSE89112_Kc167combined_randomized.hic\": \"1859742654,25624\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fmumbach%2FGSE80820_HiChIP_GM_cohesin.hic\": \"1231264781,17932\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fmumbach%2FGSE80820_HiChIP_mES_cohesin_all.hic\": \"1152008628,16438\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fmumbach%2FGSE80820_HiChIP_mES_Oct4.hic\": \"912828146,16438\",\n \"s3.amazonaws.com%2Fhicfiles%2Fexternal%2Fwapl_hic%2FSCC4KO.hic\": \"1767906138,18679\",\n \"s3.amazonaws.com%2Fhicfiles%2Fexternal%2Fwapl_hic%2FDKO.hic\": \"1487228787,18679\",\n \"s3.amazonaws.com%2Fhicfiles%2Fexternal%2Fwapl_hic%2FWaplKO_1.14.hic\": \"1189751862,18679\",\n \"s3.amazonaws.com%2Fhicfiles%2Fexternal%2Fwapl_hic%2FWaplKO_3.3.hic\": \"1155057696,18679\",\n \"s3.amazonaws.com%2Fhicfiles%2Fexternal%2Fwapl_hic%2FWT.hic\": \"1522401568,18679\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fskfuwi4fnsjkdf9jekrw2%2Fmega_Liverpool%2Fmega.hic\": \"2612171975,4381\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fskfuwi4fnsjkdf9jekrw2%2FHIC2836_Liverpool1%2FLiverpool1.hic\": \"191729195,2245\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fskfuwi4fnsjkdf9jekrw2%2FHIC2861_Liverpool2%2FLiverpool2.hic\": \"1637096030,4381\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fskfuwi4fnsjkdf9jekrw2%2FHIC2862_Liverpool3%2FLiverpool3.hic\": \"1160045602,4381\",\n \"s3.amazonaws.com%2Fhicfiles%2Fexternal%2Fgoodell%2FHSPC.hic\": \"11857786247,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fexternal%2Fgoodell%2FHSPC_CanyonDel.hic\": \"8139168836,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fexternal%2Fgoodell%2Ftcell.hic\": \"9871547081,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fexternal%2Fgoodell%2Fep.hic\": \"17479335373,36479\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fnagano%2FTh1_ensemble.hic\": \"1690592868,32102\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fbonev%2FES_mapq30.hic\": \"32930498831,32386\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fbonev%2FNPC_mapq30.hic\": \"55053730986,32386\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fbonev%2FCN_mapq30.hic\": \"53138031154,32386\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2FKieffer-Kwon_et_al_2017%2FMain_maps%2FKieffer-Kwon-2017-activated_B_cells_72_hours_WT.hic\": \"16492991184,32102\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2FKieffer-Kwon_et_al_2017%2FMain_maps%2FKieffer-Kwon-2017-resting_B_cells_WT.hic\": \"23057795398,32102\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2FKieffer-Kwon_et_al_2017%2FMain_maps%2FKieffer-Kwon-2017-activated_B_cells_24_hours_MYC_KO.hic\": \"21245554876,32102\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2FKieffer-Kwon_et_al_2017%2FMain_maps%2FKieffer-Kwon-2017-resting_B_cells_TSA.hic\": \"13933346059,32102\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2FKieffer-Kwon_et_al_2017%2FMain_maps%2FKieffer-Kwon-2017-activated_B_cells_24_hours_oligomycin.hic\": \"21902506832,32102\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2FKieffer-Kwon_et_al_2017%2FMain_maps%2FKieffer-Kwon-2017-mES_WT.hic\": \"9451969795,32102\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2FVian_et_al_2018%2FMain_maps%2FVian-2018-activated_B_cells_24_hours_WT.hic\": \"3600188564,16438\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2FVian_et_al_2018%2FMain_maps%2FVian-2018-activated_B_cells_30_hours_WT.hic\": \"1309503359,16438\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2FVian_et_al_2018%2FMain_maps%2FVian-2018-activated_B_cells_30_hours_HU_treated.hic\": \"1477252396,16438\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2FVian_et_al_2018%2FMain_maps%2FVian-2018-activated_B_cells_24_hours_flavopiridol.hic\": \"15711773490,32102\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fpgp%2FPGP1F_mega_090118%2FPGP1F_mega_090118_30.hic\": \"24786676166,36479\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fpgp%2FHIC7145%2FHIC7145_30.hic\": \"4554644616,36479\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fpgp%2FHIC7146%2FHIC7146_30.hic\": \"4174848944,36479\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fpgp%2FHIC7147%2FHIC7147_30.hic\": \"5062229182,36479\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fpgp%2FHIC7862%2FHIC7862_30.hic\": \"4520990620,36479\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fpgp%2FHIC7863%2FHIC7863_30.hic\": \"4330354773,36479\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fpgp%2FHIC7864%2FHIC7864_30.hic\": \"5880640268,36479\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fpgp%2FHIC7865%2FHIC7865_30.hic\": \"4431632469,36479\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fpgp%2FHIC7866%2FHIC7866_30.hic\": \"4686000222,36479\",\n \"encode-public.s3.amazonaws.com%2F2018%2F10%2F19%2Fb122542b-306c-4631-bdc3-2e155e89af55%2FENCFF718AWL.hic\": \"39544267907,58932\",\n \"encode-public.s3.amazonaws.com%2F2019%2F02%2F15%2F8e787cd8-e388-4bc2-a236-7a5e6f39e0c0%2FENCFF999YXX.hic\": \"9255069996,56883\",\n \"encode-public.s3.amazonaws.com%2F2019%2F02%2F08%2Ffc1d9d5d-8fa0-4e29-9080-3da674d9490d%2FENCFF543USQ.hic\": \"5005263062,36479\",\n \"s3.us-east-1.wasabisys.com%2Fhicfiles%2Finternal%2FLCL_mega_42B_500bp_30.hic\": \"106482584851,22829\",\n \"www.encodeproject.org%2Ffiles%2FENCFF925QIF%2F%40%40download%2FENCFF925QIF.hic\": \"51712684396,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF259YUS%2F%40%40download%2FENCFF259YUS.hic\": \"24640030444,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF783KQI%2F%40%40download%2FENCFF783KQI.hic\": \"27209249856,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF318JAP%2F%40%40download%2FENCFF318JAP.hic\": \"28636979242,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF512PQA%2F%40%40download%2FENCFF512PQA.hic\": \"28124104361,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF591MHA%2F%40%40download%2FENCFF591MHA.hic\": \"37373387202,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF197OWW%2F%40%40download%2FENCFF197OWW.hic\": \"41826180893,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF317OIA%2F%40%40download%2FENCFF317OIA.hic\": \"34741636038,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF522YLZ%2F%40%40download%2FENCFF522YLZ.hic\": \"24064692329,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF420JTA%2F%40%40download%2FENCFF420JTA.hic\": \"21202405177,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF871ZDJ%2F%40%40download%2FENCFF871ZDJ.hic\": \"10124815680,18679\",\n \"www.encodeproject.org%2Ffiles%2FENCFF349RZY%2F%40%40download%2FENCFF349RZY.hic\": \"4446702705,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF738YON%2F%40%40download%2FENCFF738YON.hic\": \"3338049584,35947\",\n \"www.encodeproject.org%2Ffiles%2FENCFF406KJN%2F%40%40download%2FENCFF406KJN.hic\": \"4132875306,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF081NPN%2F%40%40download%2FENCFF081NPN.hic\": \"34495587443,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF946RZW%2F%40%40download%2FENCFF946RZW.hic\": \"34571955193,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF602CHT%2F%40%40download%2FENCFF602CHT.hic\": \"30674798032,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF150DKS%2F%40%40download%2FENCFF150DKS.hic\": \"12618769864,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF614IPZ%2F%40%40download%2FENCFF614IPZ.hic\": \"42450060331,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF571ZQR%2F%40%40download%2FENCFF571ZQR.hic\": \"15230068871,47429\",\n \"www.encodeproject.org%2Ffiles%2FENCFF705MKK%2F%40%40download%2FENCFF705MKK.hic\": \"38686554702,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF658KTB%2F%40%40download%2FENCFF658KTB.hic\": \"13195884405,47429\",\n \"www.encodeproject.org%2Ffiles%2FENCFF435JYN%2F%40%40download%2FENCFF435JYN.hic\": \"17192139674,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF016JKX%2F%40%40download%2FENCFF016JKX.hic\": \"37266736642,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF294GFP%2F%40%40download%2FENCFF294GFP.hic\": \"36389843399,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF700CYI%2F%40%40download%2FENCFF700CYI.hic\": \"60482012152,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF962EDB%2F%40%40download%2FENCFF962EDB.hic\": \"39394328182,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF467OGP%2F%40%40download%2FENCFF467OGP.hic\": \"35572788855,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF556RLR%2F%40%40download%2FENCFF556RLR.hic\": \"34826921187,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF309UNV%2F%40%40download%2FENCFF309UNV.hic\": \"48510618174,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF653HCO%2F%40%40download%2FENCFF653HCO.hic\": \"41079007620,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF120DSV%2F%40%40download%2FENCFF120DSV.hic\": \"12790195576,47429\",\n \"www.encodeproject.org%2Ffiles%2FENCFF284OEA%2F%40%40download%2FENCFF284OEA.hic\": \"46007570339,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF035BLF%2F%40%40download%2FENCFF035BLF.hic\": \"63868871985,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF094KKX%2F%40%40download%2FENCFF094KKX.hic\": \"42151419971,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF965BPU%2F%40%40download%2FENCFF965BPU.hic\": \"42717376107,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF842DUO%2F%40%40download%2FENCFF842DUO.hic\": \"39553892515,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF417GBZ%2F%40%40download%2FENCFF417GBZ.hic\": \"45544785452,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF499BVX%2F%40%40download%2FENCFF499BVX.hic\": \"40900674170,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF136XCV%2F%40%40download%2FENCFF136XCV.hic\": \"47700392974,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF224HKR%2F%40%40download%2FENCFF224HKR.hic\": \"40426005932,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF711XSR%2F%40%40download%2FENCFF711XSR.hic\": \"41434581949,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF660JWA%2F%40%40download%2FENCFF660JWA.hic\": \"54201632697,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF081PMO%2F%40%40download%2FENCFF081PMO.hic\": \"53428285130,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF799QGA%2F%40%40download%2FENCFF799QGA.hic\": \"1228682189,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF473CAA%2F%40%40download%2FENCFF473CAA.hic\": \"1077514950,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF663FRL%2F%40%40download%2FENCFF663FRL.hic\": \"39843938245,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF341WOY%2F%40%40download%2FENCFF341WOY.hic\": \"34792598619,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF515ZBF%2F%40%40download%2FENCFF515ZBF.hic\": \"41779230923,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF545GBW%2F%40%40download%2FENCFF545GBW.hic\": \"38351980358,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF252ANV%2F%40%40download%2FENCFF252ANV.hic\": \"37668839771,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF912NDK%2F%40%40download%2FENCFF912NDK.hic\": \"21196851956,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF683PLM%2F%40%40download%2FENCFF683PLM.hic\": \"21849338763,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF355NFJ%2F%40%40download%2FENCFF355NFJ.hic\": \"47880627268,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF507WEW%2F%40%40download%2FENCFF507WEW.hic\": \"35777782924,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF241MSL%2F%40%40download%2FENCFF241MSL.hic\": \"22507408288,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF135MUT%2F%40%40download%2FENCFF135MUT.hic\": \"24168734040,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF459FRB%2F%40%40download%2FENCFF459FRB.hic\": \"37166770103,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF705YZH%2F%40%40download%2FENCFF705YZH.hic\": \"44679182442,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF395INO%2F%40%40download%2FENCFF395INO.hic\": \"56727346538,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF736ITL%2F%40%40download%2FENCFF736ITL.hic\": \"49036286185,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF546TZN%2F%40%40download%2FENCFF546TZN.hic\": \"33195126348,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF706SFK%2F%40%40download%2FENCFF706SFK.hic\": \"3271831702,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF922ERE%2F%40%40download%2FENCFF922ERE.hic\": \"12476647122,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF876OWE%2F%40%40download%2FENCFF876OWE.hic\": \"1538692704,47429\",\n \"www.encodeproject.org%2Ffiles%2FENCFF227XJZ%2F%40%40download%2FENCFF227XJZ.hic\": \"1925617685,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF053BXY%2F%40%40download%2FENCFF053BXY.hic\": \"1032237652,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF014VMM%2F%40%40download%2FENCFF014VMM.hic\": \"1564021703,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF563XES%2F%40%40download%2FENCFF563XES.hic\": \"1489180508,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF482LGO%2F%40%40download%2FENCFF482LGO.hic\": \"1208778887,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF216QQM%2F%40%40download%2FENCFF216QQM.hic\": \"6293163571,47429\",\n \"www.encodeproject.org%2Ffiles%2FENCFF256UOW%2F%40%40download%2FENCFF256UOW.hic\": \"6293163571,47429\",\n \"www.encodeproject.org%2Ffiles%2FENCFF791UZC%2F%40%40download%2FENCFF791UZC.hic\": \"37029615181,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF911AHQ%2F%40%40download%2FENCFF911AHQ.hic\": \"34246649165,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF491AOR%2F%40%40download%2FENCFF491AOR.hic\": \"558663570,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF307PDL%2F%40%40download%2FENCFF307PDL.hic\": \"525321519,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF773ITV%2F%40%40download%2FENCFF773ITV.hic\": \"295464771,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF198SSL%2F%40%40download%2FENCFF198SSL.hic\": \"500142476,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF251UEF%2F%40%40download%2FENCFF251UEF.hic\": \"567443575,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF942LTN%2F%40%40download%2FENCFF942LTN.hic\": \"4430960222,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF543USQ%2F%40%40download%2FENCFF543USQ.hic\": \"5005263062,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF434XQU%2F%40%40download%2FENCFF434XQU.hic\": \"25506511674,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF318GOM%2F%40%40download%2FENCFF318GOM.hic\": \"44750824314,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF004TKY%2F%40%40download%2FENCFF004TKY.hic\": \"20705661833,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF493YNC%2F%40%40download%2FENCFF493YNC.hic\": \"53407154984,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF334XXU%2F%40%40download%2FENCFF334XXU.hic\": \"14341194962,47429\",\n \"www.encodeproject.org%2Ffiles%2FENCFF569RJM%2F%40%40download%2FENCFF569RJM.hic\": \"1922066634,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF076LWH%2F%40%40download%2FENCFF076LWH.hic\": \"39406255845,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF977XWK%2F%40%40download%2FENCFF977XWK.hic\": \"20563512962,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF127TPS%2F%40%40download%2FENCFF127TPS.hic\": \"21032070512,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF480KLP%2F%40%40download%2FENCFF480KLP.hic\": \"33115569647,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF281ILS%2F%40%40download%2FENCFF281ILS.hic\": \"28236353584,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF129LMU%2F%40%40download%2FENCFF129LMU.hic\": \"35247096013,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF759YCW%2F%40%40download%2FENCFF759YCW.hic\": \"16058537743,32102\",\n \"www.encodeproject.org%2Ffiles%2FENCFF045YOM%2F%40%40download%2FENCFF045YOM.hic\": \"19775445828,32102\",\n \"www.encodeproject.org%2Ffiles%2FENCFF013TGD%2F%40%40download%2FENCFF013TGD.hic\": \"4208420532,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF929RPW%2F%40%40download%2FENCFF929RPW.hic\": \"1974260276,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF996XEO%2F%40%40download%2FENCFF996XEO.hic\": \"2072918865,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF097SKJ%2F%40%40download%2FENCFF097SKJ.hic\": \"1983524001,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF464KRA%2F%40%40download%2FENCFF464KRA.hic\": \"1957300131,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF406HHC%2F%40%40download%2FENCFF406HHC.hic\": \"3854527235,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF080DPJ%2F%40%40download%2FENCFF080DPJ.hic\": \"19953768024,47429\",\n \"www.encodeproject.org%2Ffiles%2FENCFF621AIY%2F%40%40download%2FENCFF621AIY.hic\": \"26781700010,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF366ERB%2F%40%40download%2FENCFF366ERB.hic\": \"1049184239,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF997RGL%2F%40%40download%2FENCFF997RGL.hic\": \"2521167549,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF029MPB%2F%40%40download%2FENCFF029MPB.hic\": \"1854711185,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF043EEE%2F%40%40download%2FENCFF043EEE.hic\": \"2924133032,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF920CJR%2F%40%40download%2FENCFF920CJR.hic\": \"3011577886,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF928NJV%2F%40%40download%2FENCFF928NJV.hic\": \"2778936244,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF894GLR%2F%40%40download%2FENCFF894GLR.hic\": \"2831733099,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF303PCK%2F%40%40download%2FENCFF303PCK.hic\": \"688704435,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF999YXX%2F%40%40download%2FENCFF999YXX.hic\": \"9255069996,56883\",\n \"www.encodeproject.org%2Ffiles%2FENCFF685BLG%2F%40%40download%2FENCFF685BLG.hic\": \"16797022992,47429\",\n \"www.encodeproject.org%2Ffiles%2FENCFF188SSH%2F%40%40download%2FENCFF188SSH.hic\": \"16797023050,47429\",\n \"www.encodeproject.org%2Ffiles%2FENCFF465ESX%2F%40%40download%2FENCFF465ESX.hic\": \"13489465953,32102\",\n \"www.encodeproject.org%2Ffiles%2FENCFF493SFI%2F%40%40download%2FENCFF493SFI.hic\": \"30033046818,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF235LCO%2F%40%40download%2FENCFF235LCO.hic\": \"38572174589,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF625VNK%2F%40%40download%2FENCFF625VNK.hic\": \"45202258438,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF304HMS%2F%40%40download%2FENCFF304HMS.hic\": \"36994445315,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF605CEN%2F%40%40download%2FENCFF605CEN.hic\": \"40358346301,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF086ORS%2F%40%40download%2FENCFF086ORS.hic\": \"22650781304,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF237UKR%2F%40%40download%2FENCFF237UKR.hic\": \"41516707246,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF004YZQ%2F%40%40download%2FENCFF004YZQ.hic\": \"71900665326,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF104THR%2F%40%40download%2FENCFF104THR.hic\": \"15172410632,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF807IRK%2F%40%40download%2FENCFF807IRK.hic\": \"17346637451,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF193CQL%2F%40%40download%2FENCFF193CQL.hic\": \"55726903245,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF700DEX%2F%40%40download%2FENCFF700DEX.hic\": \"20231399798,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF234MDO%2F%40%40download%2FENCFF234MDO.hic\": \"24635312640,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF181ROW%2F%40%40download%2FENCFF181ROW.hic\": \"26883606497,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF896OFN%2F%40%40download%2FENCFF896OFN.hic\": \"36952196833,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF573OPJ%2F%40%40download%2FENCFF573OPJ.hic\": \"36685546919,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF028RXH%2F%40%40download%2FENCFF028RXH.hic\": \"31053919206,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF156GGD%2F%40%40download%2FENCFF156GGD.hic\": \"35284134289,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF496GEU%2F%40%40download%2FENCFF496GEU.hic\": \"44659660933,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF945TUH%2F%40%40download%2FENCFF945TUH.hic\": \"3898570191,35639\",\n \"www.encodeproject.org%2Ffiles%2FENCFF698KFV%2F%40%40download%2FENCFF698KFV.hic\": \"4427896684,35751\",\n \"www.encodeproject.org%2Ffiles%2FENCFF239BHZ%2F%40%40download%2FENCFF239BHZ.hic\": \"1718552021,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF277LAN%2F%40%40download%2FENCFF277LAN.hic\": \"4542391336,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF397CMD%2F%40%40download%2FENCFF397CMD.hic\": \"2832016430,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF778OYA%2F%40%40download%2FENCFF778OYA.hic\": \"14067187484,47429\",\n \"www.encodeproject.org%2Ffiles%2FENCFF775VSU%2F%40%40download%2FENCFF775VSU.hic\": \"14067187484,47429\",\n \"www.encodeproject.org%2Ffiles%2FENCFF812THZ%2F%40%40download%2FENCFF812THZ.hic\": \"9667720429,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF777KBU%2F%40%40download%2FENCFF777KBU.hic\": \"5058284320,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF688KOY%2F%40%40download%2FENCFF688KOY.hic\": \"4198695833,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF223UBX%2F%40%40download%2FENCFF223UBX.hic\": \"1206064037,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF273XBU%2F%40%40download%2FENCFF273XBU.hic\": \"44085607579,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF952JZV%2F%40%40download%2FENCFF952JZV.hic\": \"44728845246,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF643NDM%2F%40%40download%2FENCFF643NDM.hic\": \"35877886780,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF586MQY%2F%40%40download%2FENCFF586MQY.hic\": \"71158037547,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF251VFA%2F%40%40download%2FENCFF251VFA.hic\": \"40089479399,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF033WGK%2F%40%40download%2FENCFF033WGK.hic\": \"30802023728,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF649OHR%2F%40%40download%2FENCFF649OHR.hic\": \"28203184265,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF782WVZ%2F%40%40download%2FENCFF782WVZ.hic\": \"37248221674,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF579CAR%2F%40%40download%2FENCFF579CAR.hic\": \"39662025395,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF514XWQ%2F%40%40download%2FENCFF514XWQ.hic\": \"1319613701,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF666USK%2F%40%40download%2FENCFF666USK.hic\": \"15051670107,32102\",\n \"www.encodeproject.org%2Ffiles%2FENCFF047SDP%2F%40%40download%2FENCFF047SDP.hic\": \"1357076705,16438\",\n \"www.encodeproject.org%2Ffiles%2FENCFF584LEP%2F%40%40download%2FENCFF584LEP.hic\": \"9314176858,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF671SOE%2F%40%40download%2FENCFF671SOE.hic\": \"3273732256,16438\",\n \"www.encodeproject.org%2Ffiles%2FENCFF702LAP%2F%40%40download%2FENCFF702LAP.hic\": \"1800427500,31682\",\n \"www.encodeproject.org%2Ffiles%2FENCFF339PON%2F%40%40download%2FENCFF339PON.hic\": \"5394351199,31514\",\n \"www.encodeproject.org%2Ffiles%2FENCFF741QPR%2F%40%40download%2FENCFF741QPR.hic\": \"4271510019,30139\",\n \"www.encodeproject.org%2Ffiles%2FENCFF103ANX%2F%40%40download%2FENCFF103ANX.hic\": \"4439745804,30083\",\n \"www.encodeproject.org%2Ffiles%2FENCFF395SBC%2F%40%40download%2FENCFF395SBC.hic\": \"1596732351,31850\",\n \"www.encodeproject.org%2Ffiles%2FENCFF289WNN%2F%40%40download%2FENCFF289WNN.hic\": \"8632980535,32102\",\n \"www.encodeproject.org%2Ffiles%2FENCFF381EAU%2F%40%40download%2FENCFF381EAU.hic\": \"1702476311,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF976FEY%2F%40%40download%2FENCFF976FEY.hic\": \"1448279040,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF485LVS%2F%40%40download%2FENCFF485LVS.hic\": \"1593610856,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF143VJV%2F%40%40download%2FENCFF143VJV.hic\": \"1422312076,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF588NHX%2F%40%40download%2FENCFF588NHX.hic\": \"3943637009,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF768UBD%2F%40%40download%2FENCFF768UBD.hic\": \"24786676166,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF965PEE%2F%40%40download%2FENCFF965PEE.hic\": \"29387092778,47429\",\n \"www.encodeproject.org%2Ffiles%2FENCFF702IFC%2F%40%40download%2FENCFF702IFC.hic\": \"29387092778,47429\",\n \"www.encodeproject.org%2Ffiles%2FENCFF288DNV%2F%40%40download%2FENCFF288DNV.hic\": \"10313429504,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF698HWZ%2F%40%40download%2FENCFF698HWZ.hic\": \"10962849269,47429\",\n \"www.encodeproject.org%2Ffiles%2FENCFF355OWW%2F%40%40download%2FENCFF355OWW.hic\": \"3219571601,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF177TYX%2F%40%40download%2FENCFF177TYX.hic\": \"10325679706,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF542BHD%2F%40%40download%2FENCFF542BHD.hic\": \"11085397879,47429\",\n \"www.encodeproject.org%2Ffiles%2FENCFF684IFW%2F%40%40download%2FENCFF684IFW.hic\": \"11085397879,47429\",\n \"www.encodeproject.org%2Ffiles%2FENCFF592UHE%2F%40%40download%2FENCFF592UHE.hic\": \"21363948089,32102\",\n \"www.encodeproject.org%2Ffiles%2FENCFF779XIS%2F%40%40download%2FENCFF779XIS.hic\": \"9517383271,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF518PSL%2F%40%40download%2FENCFF518PSL.hic\": \"7500581463,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF275GBB%2F%40%40download%2FENCFF275GBB.hic\": \"7889407162,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF634KXI%2F%40%40download%2FENCFF634KXI.hic\": \"6430702966,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF337QPM%2F%40%40download%2FENCFF337QPM.hic\": \"8529733887,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF162KMP%2F%40%40download%2FENCFF162KMP.hic\": \"5615896908,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF992VTE%2F%40%40download%2FENCFF992VTE.hic\": \"7328975027,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF464WXY%2F%40%40download%2FENCFF464WXY.hic\": \"5715339664,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF752EGH%2F%40%40download%2FENCFF752EGH.hic\": \"1733758743,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF474UJM%2F%40%40download%2FENCFF474UJM.hic\": \"222309548,18679\",\n \"www.encodeproject.org%2Ffiles%2FENCFF531UPZ%2F%40%40download%2FENCFF531UPZ.hic\": \"1827756846,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF022VHA%2F%40%40download%2FENCFF022VHA.hic\": \"244983451,18679\",\n \"www.encodeproject.org%2Ffiles%2FENCFF732NGR%2F%40%40download%2FENCFF732NGR.hic\": \"1679484567,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF513VSF%2F%40%40download%2FENCFF513VSF.hic\": \"28397932940,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF750AOC%2F%40%40download%2FENCFF750AOC.hic\": \"36471430712,47429\",\n \"www.encodeproject.org%2Ffiles%2FENCFF219YOB%2F%40%40download%2FENCFF219YOB.hic\": \"2859767211,26979\",\n \"www.encodeproject.org%2Ffiles%2FENCFF604YDD%2F%40%40download%2FENCFF604YDD.hic\": \"3549694085,26979\",\n \"www.encodeproject.org%2Ffiles%2FENCFF746AMV%2F%40%40download%2FENCFF746AMV.hic\": \"2954867135,26979\",\n \"www.encodeproject.org%2Ffiles%2FENCFF845ZEB%2F%40%40download%2FENCFF845ZEB.hic\": \"2763039282,26979\",\n \"www.encodeproject.org%2Ffiles%2FENCFF570LWS%2F%40%40download%2FENCFF570LWS.hic\": \"2861588289,26979\",\n \"www.encodeproject.org%2Ffiles%2FENCFF883YVR%2F%40%40download%2FENCFF883YVR.hic\": \"2433679887,26979\",\n \"www.encodeproject.org%2Ffiles%2FENCFF056VLK%2F%40%40download%2FENCFF056VLK.hic\": \"2502986910,26979\",\n \"www.encodeproject.org%2Ffiles%2FENCFF532DUQ%2F%40%40download%2FENCFF532DUQ.hic\": \"3172615899,26979\",\n \"www.encodeproject.org%2Ffiles%2FENCFF723PYJ%2F%40%40download%2FENCFF723PYJ.hic\": \"10292839095,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF991SGJ%2F%40%40download%2FENCFF991SGJ.hic\": \"13072407683,32102\",\n \"www.encodeproject.org%2Ffiles%2FENCFF885UZI%2F%40%40download%2FENCFF885UZI.hic\": \"1201881201,16438\",\n \"www.encodeproject.org%2Ffiles%2FENCFF287KXA%2F%40%40download%2FENCFF287KXA.hic\": \"14705801988,32102\",\n \"www.encodeproject.org%2Ffiles%2FENCFF335HYI%2F%40%40download%2FENCFF335HYI.hic\": \"20366756545,32102\",\n \"www.encodeproject.org%2Ffiles%2FENCFF121YPY%2F%40%40download%2FENCFF121YPY.hic\": \"2760104016,26979\",\n \"www.encodeproject.org%2Ffiles%2FENCFF675SJE%2F%40%40download%2FENCFF675SJE.hic\": \"3751779995,26979\",\n \"www.encodeproject.org%2Ffiles%2FENCFF876LAW%2F%40%40download%2FENCFF876LAW.hic\": \"4032376256,26979\",\n \"www.encodeproject.org%2Ffiles%2FENCFF740KVX%2F%40%40download%2FENCFF740KVX.hic\": \"3202490322,26979\",\n \"www.encodeproject.org%2Ffiles%2FENCFF977OQV%2F%40%40download%2FENCFF977OQV.hic\": \"2919735477,26979\",\n \"www.encodeproject.org%2Ffiles%2FENCFF525EFN%2F%40%40download%2FENCFF525EFN.hic\": \"2394748073,26979\",\n \"www.encodeproject.org%2Ffiles%2FENCFF690QRC%2F%40%40download%2FENCFF690QRC.hic\": \"3183023394,26979\",\n \"www.encodeproject.org%2Ffiles%2FENCFF452FWS%2F%40%40download%2FENCFF452FWS.hic\": \"2951805127,26979\",\n \"www.encodeproject.org%2Ffiles%2FENCFF089KBG%2F%40%40download%2FENCFF089KBG.hic\": \"2531936700,26979\",\n \"www.encodeproject.org%2Ffiles%2FENCFF939ARM%2F%40%40download%2FENCFF939ARM.hic\": \"3066385212,26979\",\n \"www.encodeproject.org%2Ffiles%2FENCFF401ZAN%2F%40%40download%2FENCFF401ZAN.hic\": \"3008677144,26979\",\n \"www.encodeproject.org%2Ffiles%2FENCFF378RZT%2F%40%40download%2FENCFF378RZT.hic\": \"2830232168,26979\",\n \"www.encodeproject.org%2Ffiles%2FENCFF304AVD%2F%40%40download%2FENCFF304AVD.hic\": \"6164439305,50358\",\n \"www.encodeproject.org%2Ffiles%2FENCFF453DBX%2F%40%40download%2FENCFF453DBX.hic\": \"6775246670,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF590VOM%2F%40%40download%2FENCFF590VOM.hic\": \"6443478922,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF246DOF%2F%40%40download%2FENCFF246DOF.hic\": \"6837914659,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF125FXX%2F%40%40download%2FENCFF125FXX.hic\": \"9736232550,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF241RAY%2F%40%40download%2FENCFF241RAY.hic\": \"7686758397,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF415XWQ%2F%40%40download%2FENCFF415XWQ.hic\": \"6973092068,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF374EBH%2F%40%40download%2FENCFF374EBH.hic\": \"8557459058,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF263YWR%2F%40%40download%2FENCFF263YWR.hic\": \"331586820,18679\",\n \"www.encodeproject.org%2Ffiles%2FENCFF280CGS%2F%40%40download%2FENCFF280CGS.hic\": \"1743569614,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF553ZNS%2F%40%40download%2FENCFF553ZNS.hic\": \"1717253636,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF451VOI%2F%40%40download%2FENCFF451VOI.hic\": \"1626927468,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF420MQO%2F%40%40download%2FENCFF420MQO.hic\": \"31055961677,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF301BWY%2F%40%40download%2FENCFF301BWY.hic\": \"38902429246,47429\",\n \"www.encodeproject.org%2Ffiles%2FENCFF606XNW%2F%40%40download%2FENCFF606XNW.hic\": \"1009699327,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF439ZOU%2F%40%40download%2FENCFF439ZOU.hic\": \"12381714313,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF499SYK%2F%40%40download%2FENCFF499SYK.hic\": \"13182654663,47429\",\n \"www.encodeproject.org%2Ffiles%2FENCFF532LFI%2F%40%40download%2FENCFF532LFI.hic\": \"8286030286,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF020DPP%2F%40%40download%2FENCFF020DPP.hic\": \"23521952420,47429\",\n \"www.encodeproject.org%2Ffiles%2FENCFF306VTV%2F%40%40download%2FENCFF306VTV.hic\": \"23521952480,47429\",\n \"www.encodeproject.org%2Ffiles%2FENCFF399IHE%2F%40%40download%2FENCFF399IHE.hic\": \"10216571232,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF944AII%2F%40%40download%2FENCFF944AII.hic\": \"12567308552,47429\",\n \"www.encodeproject.org%2Ffiles%2FENCFF230HVV%2F%40%40download%2FENCFF230HVV.hic\": \"8629849711,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF174LAF%2F%40%40download%2FENCFF174LAF.hic\": \"9446506633,47429\",\n \"www.encodeproject.org%2Ffiles%2FENCFF898HRO%2F%40%40download%2FENCFF898HRO.hic\": \"9446506633,47429\",\n \"www.encodeproject.org%2Ffiles%2FENCFF429MOR%2F%40%40download%2FENCFF429MOR.hic\": \"1455757398,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF061NXV%2F%40%40download%2FENCFF061NXV.hic\": \"1710915891,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF434PYS%2F%40%40download%2FENCFF434PYS.hic\": \"1832274903,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF704HHX%2F%40%40download%2FENCFF704HHX.hic\": \"1768142834,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF349DPM%2F%40%40download%2FENCFF349DPM.hic\": \"4316041260,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF718AWL%2F%40%40download%2FENCFF718AWL.hic\": \"39544267907,58932\",\n \"www.encodeproject.org%2Ffiles%2FENCFF065LSP%2F%40%40download%2FENCFF065LSP.hic\": \"24929805283,55874\",\n \"www.encodeproject.org%2Ffiles%2FENCFF632MFV%2F%40%40download%2FENCFF632MFV.hic\": \"22333105467,55798\",\n \"www.encodeproject.org%2Ffiles%2FENCFF179HVU%2F%40%40download%2FENCFF179HVU.hic\": \"2659219603,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF791SPZ%2F%40%40download%2FENCFF791SPZ.hic\": \"2537491657,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF211ZWF%2F%40%40download%2FENCFF211ZWF.hic\": \"3512141227,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF614BNU%2F%40%40download%2FENCFF614BNU.hic\": \"5252155462,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF891DLM%2F%40%40download%2FENCFF891DLM.hic\": \"2549095612,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF056EXT%2F%40%40download%2FENCFF056EXT.hic\": \"2219014704,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF776DSS%2F%40%40download%2FENCFF776DSS.hic\": \"3920308353,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF814LQF%2F%40%40download%2FENCFF814LQF.hic\": \"1349480197,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF513ZNA%2F%40%40download%2FENCFF513ZNA.hic\": \"2638868195,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF692IOL%2F%40%40download%2FENCFF692IOL.hic\": \"3106768498,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF294WZY%2F%40%40download%2FENCFF294WZY.hic\": \"2211089761,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF339UWS%2F%40%40download%2FENCFF339UWS.hic\": \"2142759055,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF835FSK%2F%40%40download%2FENCFF835FSK.hic\": \"3919821739,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF328BMB%2F%40%40download%2FENCFF328BMB.hic\": \"2550686152,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF897RTY%2F%40%40download%2FENCFF897RTY.hic\": \"1323294397,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF306MWH%2F%40%40download%2FENCFF306MWH.hic\": \"1665386199,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF039YUJ%2F%40%40download%2FENCFF039YUJ.hic\": \"2335679939,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF468QIN%2F%40%40download%2FENCFF468QIN.hic\": \"3352516594,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF364WXU%2F%40%40download%2FENCFF364WXU.hic\": \"3959043175,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF373MSH%2F%40%40download%2FENCFF373MSH.hic\": \"4429550624,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF959EGQ%2F%40%40download%2FENCFF959EGQ.hic\": \"2475218228,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF624XMK%2F%40%40download%2FENCFF624XMK.hic\": \"3527855681,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF445OKS%2F%40%40download%2FENCFF445OKS.hic\": \"3369125589,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF239QDV%2F%40%40download%2FENCFF239QDV.hic\": \"1960069888,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF645AVM%2F%40%40download%2FENCFF645AVM.hic\": \"4969006589,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF494IPI%2F%40%40download%2FENCFF494IPI.hic\": \"1565483792,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF753IXE%2F%40%40download%2FENCFF753IXE.hic\": \"2892400648,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF731GXX%2F%40%40download%2FENCFF731GXX.hic\": \"5131381303,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF369CAQ%2F%40%40download%2FENCFF369CAQ.hic\": \"4236629448,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF053VBX%2F%40%40download%2FENCFF053VBX.hic\": \"54305946375,47429\",\n \"www.encodeproject.org%2Ffiles%2FENCFF555ISR%2F%40%40download%2FENCFF555ISR.hic\": \"54305946434,47429\",\n \"www.encodeproject.org%2Ffiles%2FENCFF964RSP%2F%40%40download%2FENCFF964RSP.hic\": \"12065485229,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF234MZQ%2F%40%40download%2FENCFF234MZQ.hic\": \"17507142760,47429\",\n \"www.encodeproject.org%2Ffiles%2FENCFF994CEG%2F%40%40download%2FENCFF994CEG.hic\": \"17507142760,47429\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fb068e787-bbdd-49e2-9f6d-7a0e9f065d6e%2F4DNFIHSUIRFY.hic\": \"2701182442,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3768b89a-e124-40eb-8acd-94a4fdd35807%2F4DNFIXTAS6EE.hic\": \"3283740601,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F9c513602-5abb-4088-8415-c827c381ab0d%2F4DNFIC3JD6O2.hic\": \"4896075767,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fde954dad-1849-4c23-beb4-bf893b7d76c9%2F4DNFIGY85S4W.hic\": \"3364151996,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fe1befa6e-8067-4296-8db2-67d2a2458985%2F4DNFI2LTNXME.hic\": \"3699291418,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fbb3307fd-7162-477a-87c5-52f12d03befc%2F4DNFID162B9J.hic\": \"3576428773,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8597cdae-8319-42d9-9175-3f77aaee34e1%2F4DNFIQWS3632.hic\": \"4022561190,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F327f091d-6a63-47c4-9752-2dff303a13d9%2F4DNFI6GFHB6G.hic\": \"4239331168,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd70dc3b8-48a7-42c2-bd23-80bc44fc2266%2F4DNFIS5F6EBL.hic\": \"4404671861,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F77df7bf8-6a3d-407a-8968-4ca1e78d2269%2F4DNFIF2D3TL9.hic\": \"4793989394,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc8f7cc35-d2ef-4717-9009-c02154050fbf%2F4DNFI6EIFUZI.hic\": \"3370273763,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F98449d79-30d1-4e32-801d-07435819a42f%2F4DNFIRKGMZRQ.hic\": \"4669813207,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd4fe1844-2493-4722-8b98-34a93a4bb7d8%2F4DNFIQWD8ZYD.hic\": \"5379889057,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F1ee40499-1de4-47ff-b540-d9a65943c6b8%2F4DNFIX7H3CE2.hic\": \"4857679239,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fac016170-23a7-4111-8773-353d6c150f34%2F4DNFIO21YDCV.hic\": \"4695989644,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F1faea4e7-9a32-466e-a826-0bfdab6cd915%2F4DNFIUE5RAS6.hic\": \"4788044799,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fcbd396ed-11bb-404f-aed9-ef10abc258e6%2F4DNFIFI6NIKJ.hic\": \"2069414927,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Faf3f78db-ae92-4215-bcae-76d30c617e5d%2F4DNFIL5K3MA1.hic\": \"2585598247,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F66fc2893-224e-48b4-bdb0-25e022dedd03%2F4DNFIPV5KFMK.hic\": \"2060965679,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F2b39781d-aadc-434f-abe3-562d61308fdd%2F4DNFIW8TIFI5.hic\": \"1694424195,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fb6d28f7b-27d3-486f-b5ac-32567416560d%2F4DNFIA6NSSBJ.hic\": \"2219532611,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F08785616-722e-46bb-ade2-2fdd21324e11%2F4DNFIBKZK63V.hic\": \"2429136232,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F904b13d3-1203-42a4-812c-963e80c159b1%2F4DNFI3CFMRID.hic\": \"1233390166,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fb0ed4afe-5ecf-451d-bb1f-444697e3f558%2F4DNFIYIAUEPW.hic\": \"1753567534,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F4bb9a9b3-12a8-4d2f-8071-4722294c88ea%2F4DNFIC3HAU11.hic\": \"2271375254,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F5abf9c36-c1d1-44dc-8197-74d860d896c0%2F4DNFIM2BMJ33.hic\": \"1770471113,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fa68475db-7816-4cec-b2da-d4ce4a0c7a0e%2F4DNFIBY3UHJB.hic\": \"2095528423,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F07c40943-0d0b-4b3e-94a0-8583b0e00b47%2F4DNFIWZEN3FF.hic\": \"1558559508,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd8a39553-2718-4866-9b2a-45d8e9c5ac6f%2F4DNFIE5TEYK7.hic\": \"1323063102,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F294b61ef-5565-4f04-ade9-f921a6686cce%2F4DNFI7H4II2V.hic\": \"1436947982,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F87a70ad7-7d34-4302-9c03-eb824bd4e633%2F4DNFIAS8LV1C.hic\": \"1263105698,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F9db804c6-5a91-4cf5-8ae9-e054223afb77%2F4DNFIBXWIH8J.hic\": \"1587059951,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd1e55906-ec8f-444b-8ce1-2de22a431a76%2F4DNFIO2HBDAI.hic\": \"1666436393,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F7a4b9b37-8e38-470c-8190-fd4d513c0bbb%2F4DNFIXWCLD4M.hic\": \"1513511880,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F6c7615b2-5310-4bbf-a605-98761d3a3079%2F4DNFINASC4NQ.hic\": \"1420358914,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F20454014-49cd-4e2d-93da-f40ad52776d5%2F4DNFIZF1KI43.hic\": \"1377041630,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F5df04e86-ee2a-45f2-b878-bf1648e2cca5%2F4DNFIQBHR9XC.hic\": \"1179502734,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F9d1cc910-bb3f-4106-802a-73184c58d5ba%2F4DNFIQVMVRP6.hic\": \"1811976991,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fe431986b-0732-460f-92ff-0abd1694d2d0%2F4DNFIJ7OAIFQ.hic\": \"1685503856,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F56d0c575-4962-4ea3-92c3-55bd0e17c096%2F4DNFIE8E4ANZ.hic\": \"1598369564,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fdb1502fb-a989-4ef9-b800-7eaa7be172ae%2F4DNFIOUSETUP.hic\": \"1493294709,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Facc2f1c3-8c96-4d21-814a-3a8ba81e7741%2F4DNFIVJ3IIQL.hic\": \"1472376655,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F037fb4c3-8641-4953-a977-cc71f2137582%2F4DNFIHN2QSMX.hic\": \"1179632606,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F16d2c3c0-6d29-4815-b074-b142af90b615%2F4DNFIILDWK8M.hic\": \"2280059989,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F31789849-e4db-45d8-9730-66a048c02d8a%2F4DNFI6XD6JAQ.hic\": \"2253961696,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fff04947e-e6e8-4d62-8374-ef2ee4104809%2F4DNFIALNLR78.hic\": \"1914687914,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F53e6c1e7-9410-4158-84e6-57c2e683b095%2F4DNFIBT4EAKN.hic\": \"2296378356,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F0127900a-258f-4815-97d2-6fd2b043d853%2F4DNFIDJ2JZ7Q.hic\": \"2558945393,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F89f95693-3d28-44eb-9d45-14932f8e258c%2F4DNFI8JFOAJT.hic\": \"1726440253,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd803d818-b0d4-4796-8d61-a9f3943f3b10%2F4DNFIRZA6EV6.hic\": \"1805017504,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff9165fb1-0782-4757-a740-5b929e0252bb%2F4DNFIB7QTIMH.hic\": \"2541020707,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff8d916b2-b58e-4cdf-894c-ffcb3bf6ebd9%2F4DNFIJ5DQZVK.hic\": \"2445734043,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F14066a5b-e01a-43c2-a468-b18826174df3%2F4DNFISTWNV9C.hic\": \"2499319890,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd0692151-7f9a-4475-b059-f8802616dded%2F4DNFIBN9K4V9.hic\": \"1591570769,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F70a7ef36-a514-4e45-918f-47c4e9e30ef4%2F4DNFIR8OU6QJ.hic\": \"1689882108,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F180306cd-8593-413a-ae83-24f19209c5d2%2F4DNFIDSWKFF5.hic\": \"1596696630,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F6e7b9be7-f465-4434-8e9c-68d1e44a76af%2F4DNFIV239W4L.hic\": \"2345867406,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F55df948c-941d-4930-854c-6a07557a0c1d%2F4DNFIREVU1Z5.hic\": \"2254683002,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3f590cb7-df3a-498f-81c3-d5ed4179b8ad%2F4DNFIFHU75I5.hic\": \"2497670883,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8f064770-6008-4f74-bfca-268d4a22d745%2F4DNFIMROE6N4.hic\": \"9850583704,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fa93d0588-76b7-4ccf-933c-4325876b0a53%2F4DNFI5SUHCGZ.hic\": \"10364705187,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F2f5f0d6b-0b22-4936-93c9-0944d49c037b%2F4DNFII84FBKM.hic\": \"8836986129,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F12e90fc5-0b76-4e42-b346-58d267f9ad6e%2F4DNFI2J1ODWB.hic\": \"13410858286,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff2702a45-3e8b-4980-bcd5-6bb0e291614f%2F4DNFIJWBWE41.hic\": \"20515676755,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fa0859349-5f06-4ad3-b56f-b1166b34a9eb%2F4DNFIIMZB6Y9.hic\": \"15350325963,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F12685c57-d54a-46fa-9efb-acf34ed77574%2F4DNFICJECID5.hic\": \"1525002266,26979\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd101a58e-89aa-44fd-96c5-6bf1e2476272%2F4DNFIR6UW2QA.hic\": \"1264999913,26979\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3d8c73bf-1335-4af4-b124-e3622d48c5f6%2F4DNFIGOEKBUZ.hic\": \"1905947578,26979\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fcd2477cf-6ed0-4d7b-b4e9-88fb38b0df48%2F4DNFIMDNAEW4.hic\": \"996444147,26979\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F0f03953e-29da-4f2e-8c05-572d0edf4525%2F4DNFI5OSZ3JC.hic\": \"369361754,22829\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F29d95dbb-005a-4ae1-8b9c-0fec9ec0bbd0%2F4DNFI7KOUGFM.hic\": \"1227434049,26979\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fa441ab7b-afbe-437d-bf98-b6b916558642%2F4DNFIGKX4A32.hic\": \"883933242,26979\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F941b2f94-2fff-4d3c-aceb-fee4a5ae41a9%2F4DNFI1ORHOTA.hic\": \"1140970677,26979\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8720ede9-093f-4c00-912f-373283260a16%2F4DNFIWSVLZED.hic\": \"458091151,26979\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fe9e17155-2b62-4a68-afb2-31dfa674e169%2F4DNFI6H926RO.hic\": \"3552863515,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F22f22778-987a-4dc0-97bc-f26eae0156d9%2F4DNFIKTYSPOF.hic\": \"2939475400,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F40f40192-0acb-44cb-8778-8d21afe593fb%2F4DNFIZ4S52BV.hic\": \"3067438113,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd8767374-7018-4e11-9226-bf5612d39ebb%2F4DNFI3APMXHF.hic\": \"3258874744,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8c5140ec-a65a-4186-8c59-2927233eecaa%2F4DNFIQLIKDSD.hic\": \"2746398416,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8cdedda6-d7d8-4231-a85b-d56fcd962366%2F4DNFIKYXMF1E.hic\": \"14442148774,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Faa4d4497-7c6c-4dad-8040-be13ba07ea32%2F4DNFI9815EEJ.hic\": \"17960817603,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fe9b7b95f-190b-49fe-8047-ef4a8fc59746%2F4DNFIQ2687RT.hic\": \"15954277087,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F59863d3a-8d7c-49c7-9a41-7f2a58ad24d1%2F4DNFIYDBBSE3.hic\": \"16499534862,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3e80ca41-b3e0-4f4f-a05e-8f95fe96d938%2F4DNFIMOCN1YS.hic\": \"863725312,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F96f97a01-0020-4f09-93e8-fc8a9fd07218%2F4DNFI6558CM8.hic\": \"1597967345,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fce9e9334-ee0b-4549-a845-110470ba5986%2F4DNFIQZRKS7Y.hic\": \"907626411,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fdaac8209-1015-48da-9e31-2e252dfd8fe0%2F4DNFIX4DLXSE.hic\": \"1369766288,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F268b7d52-9655-474c-9467-8ba31bb2195c%2F4DNFII3JV8I1.hic\": \"856656441,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F9681f9b5-335a-4f56-afa1-15b58bbb41e8%2F4DNFI5IAH9H1.hic\": \"1495185175,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3e082eab-95aa-4677-88ed-9d7adcc1effb%2F4DNFIK5HY1GP.hic\": \"2135337789,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F31af1ead-4520-4669-957e-424b4b197c33%2F4DNFIFA89L5B.hic\": \"1975593640,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fcc2b78fd-52d4-4e0c-ac93-b84ee82daf7e%2F4DNFICXCFGEI.hic\": \"2628202920,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff54efece-280f-46ca-95e3-1f8a3cd18820%2F4DNFIK4CECUH.hic\": \"1901129375,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F1181c0c4-afb7-4b6a-9fdc-d868fb2253fc%2F4DNFI1EYIGOC.hic\": \"1947135384,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F1d3e2905-b9b9-4b91-bcb4-8d34746e78f6%2F4DNFI7TLEWUI.hic\": \"1185758726,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Faba3d42f-39cd-4a85-9d3f-835aefb5c803%2F4DNFIVCJKHMN.hic\": \"687240974,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F27f54fcb-54fe-41a4-b25a-2f8944c89044%2F4DNFIN8F14CS.hic\": \"1304082029,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fb75fedb5-88f4-4bc0-8e38-298df7847a7f%2F4DNFI5LCW273.hic\": \"12497258313,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F2f22b2a0-3712-496e-92d2-63775ec0e421%2F4DNFIVSCH2CH.hic\": \"12594733778,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F07e47261-5863-44f5-9198-76e263081bea%2F4DNFIZ268JGC.hic\": \"1499059135,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F682b1ae1-3ac3-40e4-a330-c49f63946952%2F4DNFIJ1P4HBI.hic\": \"1190211725,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F197e7c89-ea73-41de-8cb2-8c0b1e3bb945%2F4DNFITEGKBIW.hic\": \"2061501971,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F191f6928-c9a8-44b2-8516-ee4d6005f24b%2F4DNFIE1P6RVH.hic\": \"1711447310,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F94435086-3701-4b28-a6d0-4a59b24d7615%2F4DNFICJ6I4DO.hic\": \"1557899940,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Faa9ac173-d233-41c7-8985-ca91949664e4%2F4DNFIKUG8MEW.hic\": \"1339072088,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fba6d8ab6-ee18-4ba2-8da9-d631888dd50a%2F4DNFICFZGFAV.hic\": \"1261083478,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F87a3ab04-7094-4673-81e4-ac8c9add8eb5%2F4DNFIQXCZVVA.hic\": \"1084913802,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fbc1ff488-82af-4579-9424-959184edb139%2F4DNFIB6PJFJ3.hic\": \"1114571343,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F1f7026ee-987a-41e7-8a61-45510ee3f86b%2F4DNFIX97731O.hic\": \"1246860402,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F6186787c-2e72-4925-9729-02121e2e4597%2F4DNFIYQYZOTO.hic\": \"1212210849,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3b98a946-0109-4efa-a13e-cc7a36772125%2F4DNFIPXU7V25.hic\": \"1696288217,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fea17d041-c6ed-43a1-8047-535f3d19ad44%2F4DNFIL39PR76.hic\": \"1719284710,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F72774afe-f166-42ac-9849-4070b0dadf6d%2F4DNFIYLJ3R3B.hic\": \"1106419640,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F4a45e733-55f8-4a8e-be24-2ef34c976e25%2F4DNFIL51WBN6.hic\": \"1327651164,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F086c62b0-a26f-41ae-a5ff-88b8be2bd2aa%2F4DNFI6SFPUDA.hic\": \"1336964405,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F4d9b79c7-af62-4070-84a9-b953903f2732%2F4DNFI2KM22QR.hic\": \"953067310,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3c9889d1-f49e-4639-8e15-2d99d6cd22e7%2F4DNFIVF8Q45U.hic\": \"984193565,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fa080dd7b-b7bb-4eae-a275-572a8b45b2d0%2F4DNFI2RN3WFP.hic\": \"1046525527,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fb81860ca-c227-4b68-a298-1907fd32300a%2F4DNFI4TJTL7A.hic\": \"1160373401,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F74ab47dc-7b52-421c-845e-6feb33457adf%2F4DNFIYJ4TWB8.hic\": \"1268416204,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc6582128-a930-4bcc-941e-5c0733bdd4d5%2F4DNFIM6RGKPV.hic\": \"863347067,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F11a75514-4450-4295-9eda-18e3678a575a%2F4DNFIL2VWWL5.hic\": \"860731581,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F5eb52a8c-bf14-4225-bf34-14a0aa47c369%2F4DNFIX6ZXCA8.hic\": \"893462267,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F66aaa4c0-1f62-4040-8ecc-4e95da23cd18%2F4DNFIEVR81FS.hic\": \"879736207,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F821c6e7f-96f7-47de-b7d9-4970562b3c8e%2F4DNFIAUI6BBI.hic\": \"996313881,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F9252c362-31ab-413d-a47a-cc97bdbf243a%2F4DNFIAFEE9G2.hic\": \"1103265750,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc1a0bf52-2e65-4deb-871f-ede736babd41%2F4DNFIPZBEXCP.hic\": \"1081257762,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F729f5ce3-d7e0-466d-b781-d18049e63bfa%2F4DNFIWPKRZGU.hic\": \"973779283,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F80b769ee-a717-4825-9db0-dca86f913173%2F4DNFIMD9QNDX.hic\": \"1158688208,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F266290c0-2767-4158-85ab-7274368905b9%2F4DNFIATA1HD5.hic\": \"1073361089,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc46f18a8-eb24-4d35-b112-36db72bde2f5%2F4DNFIH9U4I7I.hic\": \"1111124316,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fec91a79e-7de7-49f7-9b3d-d28313aeddc8%2F4DNFIZ95S6TR.hic\": \"1242494051,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F9e9390b9-da20-43bb-a8f4-9830f354ddf9%2F4DNFI5ERM9J7.hic\": \"1271051397,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fee8ea82e-b9e4-41ad-bced-5f4fbdaa4fec%2F4DNFI15FPSQL.hic\": \"1216714120,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fbed7eb86-8990-42f2-b3ee-5992d6361f7c%2F4DNFIJ3DZPGM.hic\": \"1035089437,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fdaa8a324-3bf8-424c-8a86-b8ad325cc20d%2F4DNFINW9P6XF.hic\": \"1215712740,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F70631758-6bf8-47a0-92b6-132574886faa%2F4DNFITS16HW8.hic\": \"1105283847,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fe473304b-7bc8-49b8-bba1-ecb9f06914ee%2F4DNFIS3DIH4V.hic\": \"1036056660,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F10f9224a-111c-402a-ac25-e221ad0af9ef%2F4DNFIY3KDHP6.hic\": \"1071761024,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F17519b96-2bdd-4294-98f0-1535f1aef28e%2F4DNFIO8HVKOL.hic\": \"953793750,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ffb18f896-4730-4909-86a3-867fc8e76cd6%2F4DNFIMF6CFOM.hic\": \"708717889,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fcfee4d87-0873-40b0-b79f-35dcc8669c1c%2F4DNFIZZ77KD2.hic\": \"732668723,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fb8b5d909-8a1b-41bb-bcdd-d108a0bde762%2F4DNFIOLO226X.hic\": \"951271932,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F9ce81f6e-b9cf-4ec9-8bd3-517539e4b662%2F4DNFIJMS2ODT.hic\": \"932509067,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F506aa952-5d41-49ff-b658-916bcf88a395%2F4DNFI49F3LJ4.hic\": \"1208494817,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fe4dc392d-ca36-4bdf-a27d-173cae34f520%2F4DNFI65MQOIJ.hic\": \"854630155,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F149ef8d7-e0b4-4e4f-b7e5-7226e2603746%2F4DNFIM4KEPRD.hic\": \"882790622,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fa436f0a8-4f9a-4524-90ac-795c5b8491cf%2F4DNFIIXBIZFC.hic\": \"848244425,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fbc8a05dc-7449-4b01-8330-a55db37ca8e6%2F4DNFIWDOOBVE.hic\": \"1116239020,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Faef8b881-28fe-4694-9a95-1d31940e6726%2F4DNFIDT9EB5M.hic\": \"888289053,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff66f3162-a53d-46f2-8800-3752935d5400%2F4DNFIX2VUNV8.hic\": \"1226661451,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F36c782e6-2c48-4298-aa43-bd6624da003d%2F4DNFIEQHTV1R.hic\": \"804665819,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff15d571e-605d-4bcc-a359-0350b57a6815%2F4DNFIFW7GA64.hic\": \"901568712,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc2aa2e8b-ac7f-4acb-b4b5-ac5f845840fe%2F4DNFIXGXD67I.hic\": \"970995551,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F71b6fd7d-b249-4d65-a597-b80b95845399%2F4DNFIA7GB1NB.hic\": \"956785837,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F6cbb1418-34db-427f-9273-5174eac81529%2F4DNFIVOJGWNP.hic\": \"890415052,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc69c2ee7-b6c3-4a62-8d4f-913491c9dab8%2F4DNFIW22BNB5.hic\": \"1075499540,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fa268f28f-c6d9-4324-8989-75d2d317af1b%2F4DNFIIFBC8WN.hic\": \"1045459440,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F6c7361d4-60a6-440b-b5be-072cada98663%2F4DNFI9ZBEBJH.hic\": \"759395398,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fcceaad1a-e01e-4430-8bd6-24ffa6891802%2F4DNFID4SLU53.hic\": \"921288444,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F9eee5854-b33e-4d5a-9ba8-ceffd47e7488%2F4DNFIODI1NUJ.hic\": \"733159777,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F5e1089b0-42e8-441c-99bb-4be99bcec28b%2F4DNFIJL26LFN.hic\": \"723567970,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F298a429e-ea29-49d3-bfed-fa851e1e7c4c%2F4DNFI5KTF553.hic\": \"2213661745,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F965d29f0-e4a3-477c-8ae4-faf4a654e69a%2F4DNFIYSPGFGV.hic\": \"2274989349,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd88acbc1-37b9-4266-9f97-d8fed576d0f3%2F4DNFILOR6D2D.hic\": \"2595459358,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F7b6ddbce-0ed1-4272-b8ae-32793e4ea4e4%2F4DNFI1WMMPJQ.hic\": \"2262433890,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fedc0c8c4-97d8-4372-9a4f-5e0cdf09d7d0%2F4DNFI47P5978.hic\": \"2146314403,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F0edcc389-43a4-44d7-b946-fe3496f93d56%2F4DNFI7XGW6IH.hic\": \"2302805723,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F0a802926-e235-4c80-b521-83a1774dfb46%2F4DNFIK1EJG8I.hic\": \"2374943035,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3c36aedb-6a58-4aa2-9b11-bb440ec174f1%2F4DNFIDQ3THN9.hic\": \"2341188249,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F846123cd-8828-4e51-8b8a-27deaf293858%2F4DNFI3WPNFWT.hic\": \"775145629,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fbd06e3ad-0e37-48a3-8367-c7d5912cab03%2F4DNFI9DCUOQ1.hic\": \"870487824,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc2eaf9bf-9584-4cec-8685-bd74038a6c01%2F4DNFIU8AF5ZY.hic\": \"1276224366,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F219497b5-3f35-473b-9d4e-e1cf21c69561%2F4DNFIHW8NTQX.hic\": \"28864787856,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F4be13558-114a-4f2d-abca-7598e2ff4757%2F4DNFI4OUMWZ8.hic\": \"17061013588,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F49aed637-87a1-4d4d-ae68-e5da82aec05b%2F4DNFIEYQ5ZIR.hic\": \"13555272651,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fa2f48779-4eff-44a6-8a9d-96435aca1ddc%2F4DNFIDZT7PR8.hic\": \"13425047093,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fb6ec6b71-27b8-4891-b10a-ab06a5270468%2F4DNFIEJEFCAM.hic\": \"15394960208,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F68b9a7b5-8413-44fc-8c2d-59a67b1c4166%2F4DNFIJ8JKKWJ.hic\": \"17012681779,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F294d45a4-8b5e-456f-a9cb-1cbbbad3a7d2%2F4DNFINEQY95T.hic\": \"13966775978,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fbd7f3a48-b822-41e2-bd9c-f52b3aff7b6a%2F4DNFII6AN691.hic\": \"12367300362,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F7da44594-0dc8-4e74-8e10-a957aeaea51a%2F4DNFIDBIEXI7.hic\": \"2015474981,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F085a0453-3784-4eba-80b2-3556e53e2f52%2F4DNFIDKJFK2S.hic\": \"1983111659,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc370c78c-0a99-4c3f-a29b-2dfafc6a3e86%2F4DNFIPAF4PYT.hic\": \"3041434294,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F907ce45f-baa5-416d-92de-e86db4bacff1%2F4DNFIWIYYNQ5.hic\": \"7082321112,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff13afc6b-cf69-4c9d-881f-eed4dd3c28ee%2F4DNFIHMCILEN.hic\": \"1739157603,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F7575d891-0e3d-4a77-896a-3e1b3a8d330b%2F4DNFIJBJ6QVH.hic\": \"5213499748,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff0daa830-60d5-4c7c-a2e1-a4ee70b3fee7%2F4DNFIH2A7IKF.hic\": \"4099503507,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff4970a25-91d8-49a7-9a4a-fe0f12cb2b0f%2F4DNFIOL8KGQ2.hic\": \"2256042055,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F879f1850-d175-4a86-8a97-12658482e3d1%2F4DNFIWILLD6C.hic\": \"5476286356,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F787f538e-d619-4c8f-985b-78753fb7e57c%2F4DNFIZBXXJAF.hic\": \"5946467856,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fb8ee785f-1016-4989-9e64-78352621d32f%2F4DNFI8PZOJHN.hic\": \"8307204961,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3d8997fa-528c-4531-b25b-a412de6bd472%2F4DNFIGXAMSJY.hic\": \"6577588285,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F87aede55-7610-4283-af0e-c6840429a31e%2F4DNFIWNNO89O.hic\": \"2871061417,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F93b8e020-b337-4685-81dc-40cc8a12b5e9%2F4DNFIXU2KPNQ.hic\": \"3401717686,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ffb5cf1bd-59d6-46fe-857d-b86d9756029d%2F4DNFIHBGD6N6.hic\": \"840028421,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F2d1bc088-d838-49b8-85fc-fea78a7353c4%2F4DNFI7J8NI4A.hic\": \"675705256,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F21a27b63-fd67-401b-9aa2-2798e6588d21%2F4DNFISFM9VFK.hic\": \"800145922,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F656c0a9d-7058-4c4b-a3ce-701d929561c1%2F4DNFIJU5XBK7.hic\": \"966593603,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F2efacfbd-9c81-4e62-8df7-847d1ab774d5%2F4DNFIPKY8ED1.hic\": \"3401629450,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fa50b6a26-56b5-43f2-b525-fa219fd716f1%2F4DNFIQRTP7NM.hic\": \"5358852759,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff5dc7a59-b998-4490-8a76-afbf3b258a49%2F4DNFIBCIA62Q.hic\": \"5779049277,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F62b2b237-cb02-45f7-89d9-616cf9ffb678%2F4DNFIV56OFE3.hic\": \"5818844506,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8ac79b4f-cfbf-4b2a-9fc2-898ed6c3e5e1%2F4DNFILIM6FDL.hic\": \"19637469163,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F1cff8afa-5a13-4ad4-bcad-91fc3ced759c%2F4DNFIP71EWXC.hic\": \"17934647326,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F000789fe-9a22-4280-a71c-7ad228fd4cac%2F4DNFIM7ZVQOQ.hic\": \"700134697,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8d78457f-0c2b-4358-b08c-4d4ef4d9f59d%2F4DNFIS6EYHCX.hic\": \"628314484,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8ca3b4a0-2478-49c9-b4a2-a28430417a32%2F4DNFIKKCMS1Q.hic\": \"584050634,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff5041473-18ec-439d-92b1-8ad98c9b25c0%2F4DNFIBIV8OUN.hic\": \"522632731,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fcf474ec6-abd4-431e-a21c-252fcf5ee6b3%2F4DNFIAUMRM2S.hic\": \"313395531,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F2bb1c73e-fb0f-41c4-8620-a938cc8d24a0%2F4DNFI9ZUXG61.hic\": \"332217525,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F26dfa41e-7e4f-457a-a3ac-72daf8059f3c%2F4DNFIDBFENL7.hic\": \"359604894,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8ed2e68b-189e-4988-bb6d-94e63240a231%2F4DNFI7XAZNNQ.hic\": \"5312422266,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F6f2b1ce0-5205-4680-981e-d91b694dc3e4%2F4DNFISNGDB53.hic\": \"2008546759,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F73c8147f-bc7d-4d33-8a10-a9e7b413ecc6%2F4DNFI1CIGHYC.hic\": \"2221847625,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F526ae3e3-32cc-4670-970f-1faa9cfafd4d%2F4DNFIQD2DP2F.hic\": \"5295591503,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F6e803530-47f8-4c56-bb19-fbdcd578d2f0%2F4DNFINHT8P7C.hic\": \"3159499486,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ffe705f38-903f-47b7-9b38-f80ebd18a479%2F4DNFIGF8EM7M.hic\": \"3490552542,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Faa197328-d6da-4299-a0fd-409ac9892668%2F4DNFIUPG2ZBJ.hic\": \"5382003751,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ffe5d52c4-2be7-4812-bca0-cd4bb3025e6b%2F4DNFIH3OTR14.hic\": \"3224693110,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F21935f61-daa8-4df2-aa69-fcd27953b405%2F4DNFIUATRW3Z.hic\": \"3835865655,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F72147527-e3e8-4967-bc45-8251249d76c9%2F4DNFI6V7ZQAE.hic\": \"4382708138,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F589f0919-f54d-49ff-a482-e2f453ef7f34%2F4DNFICKMT1CY.hic\": \"4479068191,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F861946ca-bad8-4a87-96e1-b2eb20b9ef10%2F4DNFIF9BDCNI.hic\": \"3698151402,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff76346ac-97ec-4893-8984-2b75ce1cdc51%2F4DNFIG5O1OQS.hic\": \"5704288175,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fe8b43826-f049-4c3f-b83a-e75fa7aacc85%2F4DNFIHS2SVBQ.hic\": \"990025510,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F46316260-f555-4dd4-9e40-8ae06ca52822%2F4DNFIU95B69H.hic\": \"1275878544,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff62ef491-a3ae-4f66-ab33-c5673c9e0b65%2F4DNFIYRROFCR.hic\": \"1522530503,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F1cd617e1-fad4-4fdc-8b4e-cb277650123c%2F4DNFIF7JN3IU.hic\": \"1463443128,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fdb20fe2a-0078-4d4a-8a52-d76043d06f40%2F4DNFIB2RYULQ.hic\": \"1269529700,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3d386fcf-1d22-47de-a0d6-0c3a641ca174%2F4DNFIMVDK3SI.hic\": \"1185489599,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F00e470bd-c533-41b1-923a-4b471824da12%2F4DNFIRLOTXSC.hic\": \"978217499,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fb8774fb3-d0c5-43cc-a6c9-eb0ca39841fb%2F4DNFIZAPX6J8.hic\": \"1100356082,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fab3b826e-614c-448b-860f-a3ebef68a82f%2F4DNFIQD5VCSD.hic\": \"1322319877,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F66c78d2b-993a-4937-95ed-9e2d302ceb3e%2F4DNFIIF6VAGN.hic\": \"868885799,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F5d106fe1-2d80-466e-87aa-46b38ba142c5%2F4DNFI86IEZXH.hic\": \"751443267,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc99490b6-faf9-413f-9c38-3f53018089d6%2F4DNFIP881SR2.hic\": \"754427927,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F39c7e387-e710-4b1d-b757-357dec03f6ad%2F4DNFI42NNCW8.hic\": \"1166392978,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F4742a211-43b1-4325-af6f-82490aeb766b%2F4DNFIEV4PKP6.hic\": \"1102227476,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Feaa73842-1c86-4ad9-8a9e-c189c0b4c01d%2F4DNFIF1DUQHE.hic\": \"1206699207,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd25f24df-0298-4079-bb6f-1c8e1e32392b%2F4DNFIGW55EAY.hic\": \"1033358104,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc57a7ab5-2778-4fe2-9d64-9a4e95135f12%2F4DNFISZRU6I4.hic\": \"1539570262,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd89f494a-27ca-46b6-89be-7583f3f6d18c%2F4DNFIBKKDTAP.hic\": \"350372180,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F06725280-cb24-4f22-a267-18b434bfa79e%2F4DNFIJSRQW24.hic\": \"314361467,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8fe5c3c5-006f-425b-ac6d-ea475e29be78%2F4DNFI3REN89E.hic\": \"299665258,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc8b6ac5c-13b4-427e-9158-cec0b890b6d8%2F4DNFIF5XLHKM.hic\": \"235668364,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F01ff33fc-fc23-48aa-a6c6-b720d6fe0768%2F4DNFIB6Q538N.hic\": \"316494853,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F552978c8-abbc-424a-9187-3e34cf802a97%2F4DNFI3ST3F7Y.hic\": \"296298411,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F72e66520-5170-4f2e-844a-fbfd0e23b480%2F4DNFIQT4M6UI.hic\": \"307691265,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fb3eb3953-ffe8-4d5a-970c-a16f3b7b9ec3%2F4DNFIFNCC7M2.hic\": \"364160436,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F37d413fb-afab-41ff-99aa-1678830f7dde%2F4DNFITM9MDJL.hic\": \"252412426,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Faf5db92c-aaf1-4086-a0d2-79b28648f172%2F4DNFI3NTD7B3.hic\": \"227586640,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff6892f7b-1f8a-4d7d-9605-c67932cd5654%2F4DNFIBED48O1.hic\": \"328344868,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd64afb07-5ab1-4c4f-8438-2fee37afa86a%2F4DNFISATK9PF.hic\": \"379669025,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fad11bb63-8692-461c-b698-89c601451321%2F4DNFISRP84FE.hic\": \"298491537,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F63710ec5-35d2-47dd-bf9a-08d3daa83d67%2F4DNFI2LY7B73.hic\": \"303150299,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F76077d9e-ca75-4301-ab79-88aa49bda495%2F4DNFIXEB4UZO.hic\": \"711757090,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F34dd4c0e-3487-4fb4-b95f-c4bb66e0fa31%2F4DNFIQWWATGK.hic\": \"221304476,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F48a8cf86-3248-4a8e-8e85-472ec219d49c%2F4DNFI44JLUSL.hic\": \"284772724,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fee399fbf-2a9e-46e2-8364-457713bff508%2F4DNFIM7Q2FQQ.hic\": \"330729464,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F124d191a-c5c7-49b6-b84b-0d1bad8bef2b%2F4DNFIZK7W8GZ.hic\": \"293166018,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fe351f7cc-7a2c-4515-ae0b-3bb2f91c986a%2F4DNFIMIMLMD3.hic\": \"240094740,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ffd1ae249-57b1-41d6-81a6-16b21dcd8f12%2F4DNFI7QUSU5J.hic\": \"681762505,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F46c92c5c-9ad8-4d49-beba-f35c5cd99208%2F4DNFINXUOI5H.hic\": \"375594313,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd7350d40-4e9e-4131-9151-bb539d39b431%2F4DNFIIJR2296.hic\": \"331322302,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fbfacf37b-1665-45f3-a046-e29e1544e9b0%2F4DNFIJMZUTXR.hic\": \"361313244,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F234e18fb-9990-43bf-9a48-f72722cfa232%2F4DNFIZQPT9EL.hic\": \"540421873,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F4b35ab09-2e79-4876-b2bc-d3a8faa26257%2F4DNFIZIXSZ9J.hic\": \"545066813,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F2ae5118e-807a-46e0-8e92-143d4b282b3d%2F4DNFIDD9IF9T.hic\": \"237409149,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fb34d7f6f-73f7-4b6b-80c7-c8af0f991549%2F4DNFIVC8OQPG.hic\": \"355121712,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F9ab169fd-cbdd-4f60-8553-a4c6912ad89e%2F4DNFITUPI4HA.hic\": \"313085022,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F4e53712b-d0d9-40c5-afe1-ffa0fad71e59%2F4DNFI5IZNXIO.hic\": \"341863906,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F7a91477f-45eb-4a16-affb-fc131f9326b8%2F4DNFII16KXA7.hic\": \"248904495,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F153729de-0eca-43cc-9b61-61aa8d775b38%2F4DNFIAAH19VM.hic\": \"668047244,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F879fd78a-7165-43d9-a0de-ca158b53df30%2F4DNFIVKIY3KV.hic\": \"247571318,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F67f901a4-040b-4b04-9fff-94a1780423cd%2F4DNFIVVCWL6C.hic\": \"198355985,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd5b30c5a-654a-463c-9474-39bdc3ce4500%2F4DNFIJRF2273.hic\": \"343971277,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F7070280a-8f03-40d0-9fef-e9d9f4d3dae7%2F4DNFI6FCC9ZA.hic\": \"312013061,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F47049719-9407-4d76-9048-26231045f642%2F4DNFI1CPQ4O3.hic\": \"352923267,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F862c2b5f-44c2-4bd7-9264-b3ca032d3d8d%2F4DNFISXFEDE9.hic\": \"271745977,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Feffbe052-39ff-4217-9871-44199ed90818%2F4DNFIF9L6QEQ.hic\": \"668409334,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fa7791854-1b35-4258-90fb-603c55f24642%2F4DNFIPKASX1Q.hic\": \"312727920,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F79cccad6-a78e-4de9-9fe7-08f7e8df663d%2F4DNFIWXZ4JQZ.hic\": \"151808553,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F7e86e0cc-d6f1-4ce0-aba4-c36c6ebb3c4c%2F4DNFIEMQ1O8V.hic\": \"700533280,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F4a1b58d3-9ae6-43e4-91cf-49f1fcbbab33%2F4DNFIYWONU7A.hic\": \"729050356,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F67bff264-0b0c-4c5c-9d4d-ff5abef2bbe4%2F4DNFISNIE5FH.hic\": \"7987657997,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3a6a943f-2cc0-4433-a27d-c89f3fdd3309%2F4DNFIV8MLWJB.hic\": \"6646216171,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F9e235711-ba90-404d-b4ac-b15990ea8e33%2F4DNFIXSTDPHL.hic\": \"3146468238,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F0c89f4bc-e9fc-4ecf-b868-26108dbb7bb2%2F4DNFIQJNOH8U.hic\": \"2919703928,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F1856ff9e-de7a-4fa1-ae0b-3e04b837b5e1%2F4DNFI57XB4A8.hic\": \"13417594377,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F099bb5b9-6315-4650-8f78-d603f5a046b3%2F4DNFIQ7UKVZV.hic\": \"9016468637,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Faf3c7a30-0fc4-410d-8d41-247da3eb105d%2F4DNFIWJY8GHD.hic\": \"7921314766,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fda99f429-20ab-4d91-bbfe-f8bdea8ed7b1%2F4DNFIN8NKRNF.hic\": \"4247121358,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F0ca0f4e3-30ca-4332-b735-e32dce08e1a4%2F4DNFIZYGEHNZ.hic\": \"4910404663,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F243f48b0-6b59-4f37-ad39-a12e0986f530%2F4DNFIRPYGAV8.hic\": \"4220073636,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F49f1a890-d458-42a6-9c78-99c38b6c7a8f%2F4DNFI6MZTDM1.hic\": \"375035361,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F76bd4768-9343-44ba-a99d-5500e184e39d%2F4DNFIG3BCGPL.hic\": \"2422923206,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F9d1ed866-eaf6-4906-aa8c-9e39616dde38%2F4DNFIS9YPJ3L.hic\": \"1593271574,37769\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F1e7a5636-bdb6-45fb-85d8-87a7e908de43%2F4DNFIOWGA9AX.hic\": \"1632314387,37769\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F5ecc552a-0a6b-49a9-9aa5-9f3fd9b535fd%2F4DNFINKEDSBF.hic\": \"1458761024,37769\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F6c03f1d2-bb25-4c94-b5f5-d5cdd01c14b6%2F4DNFIVIXVUK7.hic\": \"1504818271,37769\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F1a4616ff-6d04-4a6a-9773-b80e81da2471%2F4DNFIANHFY16.hic\": \"1850724180,37769\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd2231870-a78d-4c8b-9cfd-084f2468acb1%2F4DNFIJ67ZFBI.hic\": \"1473864703,37769\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F859c2dd3-df8a-42b7-86ea-bf6524f75e80%2F4DNFIG3YQQ4V.hic\": \"1539822829,37769\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8bad667e-6003-4828-9a20-07585fa9c811%2F4DNFIOLKEOME.hic\": \"3036353747,37769\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F92ea551b-5779-4d31-a0f5-621e4bd0eb21%2F4DNFIVLN8WJE.hic\": \"2710426318,37769\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F61ee79fa-0617-4083-b121-f92ef3a8905c%2F4DNFI2111XQA.hic\": \"2589549183,37769\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F83ebb98d-e5db-403d-aa23-875293156c0e%2F4DNFI88HXX7D.hic\": \"2462367030,37769\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F6d63671a-8f1d-4159-82c0-931b43464772%2F4DNFIUBM6QK8.hic\": \"2486020469,37769\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fcccb9014-ce15-4032-81ac-222b3d621cb4%2F4DNFIVILEERC.hic\": \"2052537210,37769\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F21a07867-4007-4ca5-b066-25d3168208dc%2F4DNFIF7Q43N4.hic\": \"2091773428,37769\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff738de0f-358b-44bf-97dd-644c8d9b1b1c%2F4DNFID56VJGW.hic\": \"878913568,37769\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fda97c1d4-bb92-4a77-92a7-f7960f88b9dc%2F4DNFIYUR29KO.hic\": \"983915575,37769\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F54ea363a-99e7-4f55-861e-1644acab7939%2F4DNFIUDPGHO8.hic\": \"905253594,37769\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fdcd66a07-55ee-48d9-a157-419cf4ee3eef%2F4DNFISWC2N8T.hic\": \"1233576358,37769\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F40363837-7466-4a1d-b20d-a66d1670b700%2F4DNFICMPHDMI.hic\": \"516590777,37769\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F0b3fa4e6-caeb-40b4-8942-e9c0b03dfe4f%2F4DNFIKMKN736.hic\": \"634310295,37769\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fb6a34050-d52b-4880-91cf-d3fe4b0ce982%2F4DNFIN5NLS49.hic\": \"650451131,37769\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8e63a47b-9fd4-4772-8b0c-10ee589ffb16%2F4DNFI4P8UBRL.hic\": \"705655033,37769\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F7d92b666-30cc-4838-9d46-c1f11cee3d3c%2F4DNFISNC3LAI.hic\": \"176146197,37769\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F17f7dc63-a1bc-4970-b389-87d9ee93b753%2F4DNFIVBWPFD7.hic\": \"749678512,37769\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff8897333-4791-4a83-9444-a653e24aee13%2F4DNFITMQRXB7.hic\": \"254477361,37769\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8712bf31-33d0-4562-ab0b-a1e9cf4fd30c%2F4DNFIUYD3HBY.hic\": \"995625724,37769\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fbfaf6383-9cc6-4b5c-9b20-d3bf2e8c3495%2F4DNFIRRSC7P9.hic\": \"1149985362,37769\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fb0b70598-5d17-4e0a-8831-6cbe697e69e2%2F4DNFIWKR8FP6.hic\": \"1151628407,37769\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fccc094a8-23ce-4fd8-9c4a-41f07c045c8f%2F4DNFIQ74RSUY.hic\": \"931695969,37769\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8eda16f3-af5e-4f1f-b46d-c74df44b76aa%2F4DNFI9IIO5PW.hic\": \"1077740364,37769\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff283637b-cf2c-4412-ba00-0e3d7e279fad%2F4DNFI8WGJG19.hic\": \"812086456,37769\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F7ad8438f-d3d9-42d8-88bf-42845a0dc2d0%2F4DNFIQ5CCESJ.hic\": \"652559720,37769\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F70e3bdcc-caf4-4822-b9c5-85234873db7a%2F4DNFIWTZHB4H.hic\": \"760694196,37769\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F56ed767d-cd8a-4d38-8047-ed1e8bc8cd19%2F4DNFIENYQCDP.hic\": \"1159428005,37769\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fa912fff9-5f90-42b1-a3a6-cbb9eb2cf861%2F4DNFIFATZWPD.hic\": \"1033325746,37769\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F21338ea5-fdee-4ad8-b61c-608fc6cec4bc%2F4DNFI7YRXKEO.hic\": \"388142539,37769\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff0f88647-5631-437b-b48a-4603915e3714%2F4DNFIUY3J7EW.hic\": \"407344788,37769\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F16926af8-ac3b-4f32-97d5-6c0dc6f1596a%2F4DNFIRKUYKP4.hic\": \"893352368,37769\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F93e39aec-6cde-4c5b-bcdf-283faa3163a2%2F4DNFIAQDBJZP.hic\": \"489922022,37769\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F0dc0b1ba-5509-4464-9814-dfe103ff09a0%2F4DNFIC1CLPK7.hic\": \"565748333,37769\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fb50964c7-b025-49d9-b1ed-289bedb59678%2F4DNFI3A3VYWU.hic\": \"4597459343,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff4390cea-b330-4022-88c1-9ff8c0a786f7%2F4DNFI6JJQKFJ.hic\": \"3678393678,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F70c0f730-5da1-4863-9b7a-6cdd31066cff%2F4DNFIK61ILGM.hic\": \"3324300994,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F14b14ac4-ab59-4754-9c43-eacd9d0638e2%2F4DNFIYD8LO9Z.hic\": \"3227227120,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F7386f953-8da9-47b0-acb2-931cba810544%2F4DNFIOTPSS3L.hic\": \"253942497,7557\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff6b5d8bd-27dc-4415-a320-53405a16db85%2F4DNFI525PKU5.hic\": \"305089653,7557\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F1f922dbc-637b-4c43-b816-f604f0e79ad1%2F4DNFI8Y9SRP2.hic\": \"1438589609,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F6a36d686-716c-4ba8-a9c3-fa8311791d3c%2F4DNFIP25GZGA.hic\": \"1419100109,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F0e535542-2cf2-46e4-ba10-7a0b946a7fb2%2F4DNFITPO1WTY.hic\": \"3885296184,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F0c17d228-5052-4c83-880e-af05118e6929%2F4DNFIG4X5Z5F.hic\": \"2159245890,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc3977c00-525b-4556-9a27-061707f8cb76%2F4DNFIXLYR32S.hic\": \"587852728,21916\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3f856506-cbc5-4211-a29d-48a7530c622e%2F4DNFIWI3V5LI.hic\": \"2318237793,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F38f77979-5eb7-4b6f-9a60-c2451185db98%2F4DNFI2DGL7LH.hic\": \"2068150664,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fe0992a75-7727-405e-95ac-aa97141b51c1%2F4DNFI1VSO8JP.hic\": \"1807949651,21916\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fe925f1aa-2e7b-44e7-bfa8-2084a613ab13%2F4DNFIV5O2ZYO.hic\": \"2242134377,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F803a6d3c-3972-4939-8ff2-d195c5192090%2F4DNFIEWEWQ8D.hic\": \"2981341325,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F25104375-a588-46e6-a382-663cee6c332f%2F4DNFICSTCJQZ.hic\": \"14592996888,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F927aa8a5-24a5-43b7-807a-1e99ac321459%2F4DNFICEGAHRC.hic\": \"15431307603,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8c380474-12cd-41f4-b86f-2a29faf12eec%2F4DNFIY3XPKPO.hic\": \"2550999291,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F77da562e-d0ec-45a8-8764-14fa16d995a1%2F4DNFIK9PS9GM.hic\": \"3401011629,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F11b26222-d480-40a7-8d53-3ad8500396cb%2F4DNFIF4Y74JR.hic\": \"2127593378,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F93df02c6-1047-43f6-afae-d3598b61eeea%2F4DNFIBBKG9KD.hic\": \"5724446278,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F6cd4378a-8f51-4e65-99eb-15f5c80abf8d%2F4DNFIT4I5C6Z.hic\": \"5419655766,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F067881e5-563d-40de-a9e3-caccad887fbc%2F4DNFI2U38HCE.hic\": \"14749043471,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fcb3da9ad-7afe-4d0c-9c2d-261181e7a95c%2F4DNFIETP228R.hic\": \"9401474797,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F185b7bcc-7bb7-41b7-9ebe-92d4fe159431%2F4DNFIXKC48TK.hic\": \"11624295594,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F18459b84-dd43-4af6-a05f-bcb773096322%2F4DNFIFPGOWJ6.hic\": \"2843730862,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ffde1e48c-4a0d-4bb1-b84a-e0e45f9a0aa3%2F4DNFIIRMBE8Y.hic\": \"5820677927,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fbabed539-1f0f-4e87-8815-fde596e6024c%2F4DNFIVUGNDD7.hic\": \"5170782436,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F7d00531a-e616-469b-af52-5b028270e2ce%2F4DNFIFLJLIS5.hic\": \"18917549985,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F7a9dad53-b8af-4cb6-9ce3-5c38e4a855c7%2F4DNFIOX3BGNE.hic\": \"5482775936,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F82fd7b7e-5f47-48d5-bf0d-daaa48a4674d%2F4DNFISPUVQHA.hic\": \"2177864938,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F4c6680f3-9cf6-452f-9dc5-ecebf376775d%2F4DNFI8649RQJ.hic\": \"3288850368,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F2395f001-19d9-4000-9f00-dae3dea708d6%2F4DNFIE8T8JZ8.hic\": \"1383191843,21916\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F24464fa8-bf96-483c-8e9a-c2f626ad6e19%2F4DNFIBM714BP.hic\": \"1765204569,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F918fc048-fa27-41d2-a63a-d50c511fbb9a%2F4DNFI6CWNUFL.hic\": \"2431120602,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F7ff5a0d1-8e54-4cf0-9fe7-339f147c78da%2F4DNFIZ4F74QR.hic\": \"3211825957,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F355f0412-cb17-452a-b15c-aba16c5a742c%2F4DNFIOUVOX3R.hic\": \"5547401083,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3cac91c5-160a-4b91-a91e-edc309318dd5%2F4DNFIVTDXW6X.hic\": \"4797344498,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fe9ac9ec5-6221-4f39-951a-1c5054fc9f1c%2F4DNFICA8Y9TN.hic\": \"4277557869,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F46f62222-b50a-428b-938b-5444951600eb%2F4DNFIDWM3HN5.hic\": \"4374808431,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F50e4f2a1-9cb6-4192-8199-64d354bfdf96%2F4DNFIBK5TB3N.hic\": \"3757387253,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fe4cdd5a8-1a45-4c6a-906b-a9603260d4c8%2F4DNFI3JYF9VS.hic\": \"5260534916,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc8164e99-5778-427d-be26-f0e1b62400f0%2F4DNFIP1GNKUO.hic\": \"7589365689,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F0d72e78a-fc87-4716-8b8e-6dc5650ff2ef%2F4DNFIQYQWPF5.hic\": \"22022259901,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fac58fc15-48c2-4eec-a689-23b677b4b6e7%2F4DNFIW6H9U3S.hic\": \"6810897169,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F31811e40-e3ca-4456-8ba6-2ee66d6c7104%2F4DNFI7J8BQ4P.hic\": \"7188744676,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F62d81a52-d2cb-4bbd-8510-0fe120e786e0%2F4DNFIA3AKFSU.hic\": \"1763730692,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fae0b7513-d1a0-4f27-a9d3-348837f42cb6%2F4DNFID68JQY9.hic\": \"2422880133,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fae6a1a7e-1d2d-4fd2-a89f-1799abac8a9c%2F4DNFIL1FQDXE.hic\": \"1543814834,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F80d343c9-bd60-468a-803d-c3e351a958bc%2F4DNFITSIPCSK.hic\": \"2344682115,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff2d61195-a3a6-4d50-b928-546ca67546cb%2F4DNFIJ88LYHR.hic\": \"3362742962,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F31052aba-773a-4500-961b-e0a518245b0c%2F4DNFIJIPWD63.hic\": \"2529548812,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc93d0710-3fbf-40cc-b0eb-878e2aa659e4%2F4DNFIZUP2BBI.hic\": \"491996147,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8660baeb-5be1-4ba5-93e4-66499e9a4587%2F4DNFIEBC4AF3.hic\": \"2993048734,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff6d08fbc-b836-4776-82ad-8b1b277ae837%2F4DNFI5VO3E1W.hic\": \"1949322679,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3af004a2-a6fa-46dc-8be8-898b847a77be%2F4DNFIFDGVWLU.hic\": \"2456400803,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fbd613b4b-2422-492c-8d8f-8afba9c8a182%2F4DNFITVGFNYZ.hic\": \"1411204423,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc340694f-14f3-4638-b09b-98220c20039a%2F4DNFIOW9TTC1.hic\": \"2611370588,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3effa71b-6aa3-4265-87ba-f8d709d778d7%2F4DNFIOAA3ZEQ.hic\": \"3123195980,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fde75cf8b-9ce1-44fc-8b7b-ca0adea6bae9%2F4DNFIA5ID1S6.hic\": \"3496246968,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F714f775d-a5a4-4314-83f8-016b9d73200b%2F4DNFIZYU7V81.hic\": \"4245592042,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F5ca518af-6e1e-4777-b67b-0fe7f039ce58%2F4DNFIRV6PVUX.hic\": \"3981520466,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc29b57d5-c263-4372-b396-ab4f55682f5d%2F4DNFIMEANFBY.hic\": \"3999623376,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F4196d3ef-161a-4c18-a57e-005165c6b32a%2F4DNFIGLGQXLC.hic\": \"4105683321,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fe10828b5-9519-4ceb-81e7-7228bfd890de%2F4DNFILS2HLXC.hic\": \"3804942111,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Feaac88c7-9bdc-4b1e-aa9f-e675520dfffa%2F4DNFIQS8853L.hic\": \"5287726781,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Faab371b1-bc8d-4e83-998e-5bb977c443ca%2F4DNFIVBYCYGS.hic\": \"4657988157,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fdb116add-af8c-4a3b-b106-9f704ba0a175%2F4DNFIE4WWHMF.hic\": \"5116727268,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F033366e2-05a2-4381-9d48-90122892a9e0%2F4DNFIKDUUC3C.hic\": \"45638237,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F7284a446-442d-4a46-aae5-84987e75a7af%2F4DNFIJ5HIRA2.hic\": \"62201052,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F876649a3-6dd3-463a-8b17-5752a98a89c5%2F4DNFIXDFC7EM.hic\": \"69878143,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3cb4ce4d-d474-459f-8b8a-2159d8df8068%2F4DNFIO35EOVR.hic\": \"70153114,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F5c5612fa-18c2-47fb-8074-693b1054e254%2F4DNFI57QGL6U.hic\": \"54605055,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F70c1472d-cf3a-41d7-8682-cd03b7cc978d%2F4DNFI2AGEBE5.hic\": \"67930121,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F2bf4cce8-6e03-422b-a190-e51d4a07d501%2F4DNFI1E6NJQJ.hic\": \"4893181511,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F0eb3aa56-8a23-435d-a07b-8bb545e8d708%2F4DNFI2DNFM1A.hic\": \"60466977,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F1201682a-a223-482d-913d-3c3972b8eb65%2F4DNFIIRIHBR2.hic\": \"48961678,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F6aee7913-6356-43cf-affa-f2b60dd478f6%2F4DNFIKXNMT46.hic\": \"39095246,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F357139a3-c9a5-4343-b0a4-b41c45fd03fd%2F4DNFIRV7IRJP.hic\": \"70916718,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F76be3061-6259-42be-a917-19dcba41517b%2F4DNFIFX1XYKZ.hic\": \"229197441,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff60c348a-a62c-43c3-ac85-f6c28b5f823f%2F4DNFI64CJUZ5.hic\": \"112428610,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fbd0b0a14-9703-49af-bb36-2359f96d4d0e%2F4DNFIBPL2HL1.hic\": \"73972428,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F79ac278d-83f7-4c1f-91b2-05c8018c1426%2F4DNFIBRSIPE4.hic\": \"415430378,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F0c3b8141-8e67-4211-80dd-3bae88f9e537%2F4DNFIDLDVY14.hic\": \"112747303,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F2ae703d2-d85c-4ac4-9ce1-14d653927675%2F4DNFI4R1II4P.hic\": \"210565448,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F76e641af-90be-49f8-b126-12c20f856159%2F4DNFINMLRY95.hic\": \"1590865292,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3b416382-ae5d-469f-9e9a-85a3e2ce9793%2F4DNFI8KBXYNL.hic\": \"4626496956,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fa27589a6-86b2-43a2-8218-1f2232d551e6%2F4DNFI53R5IKA.hic\": \"1536016455,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fdd3999f5-b36e-4154-a6b9-446656959a3a%2F4DNFIAWVDQ8C.hic\": \"2210273411,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc377953b-0e61-426b-a905-abab2d5a3002%2F4DNFI9VXTBE2.hic\": \"3384365692,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F2dbe0377-1db2-4aae-af2b-d87dff728035%2F4DNFIT96Z365.hic\": \"7692311974,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fdcfcb009-f006-4ab8-a4c7-af72be58c12c%2F4DNFITUOMFUQ.hic\": \"6592120312,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F67f9073d-b2c5-474e-b3d5-7d72cde555cd%2F4DNFIHLQKDN8.hic\": \"2647703964,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F76968cc8-fb9f-485b-85b2-c9289067194b%2F4DNFIL9M97T2.hic\": \"6186798917,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F87d9330b-8d2c-4e9d-85bb-02e572de7a68%2F4DNFIDWGZLHX.hic\": \"4379708168,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ffc01b381-3665-4225-88ee-2e5e9ecb7324%2F4DNFIMEG1QIC.hic\": \"3587146533,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3144a03c-15c3-4bf9-95f8-ffad2640a1bf%2F4DNFIWSB66VX.hic\": \"1529739069,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd7d3aac0-ba66-494b-ba0c-147631084b98%2F4DNFIH7TH4MF.hic\": \"6896300679,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F4b13bd19-fbd1-4c68-8855-4f0158d1ce47%2F4DNFIHKWIZ9T.hic\": \"1954878455,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3d04e286-30d4-4add-a806-7a929d36419e%2F4DNFIZBBX795.hic\": \"1350142414,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Faa26f261-a88a-4cac-9118-ff8e90ab6f61%2F4DNFI9ZWZ5BS.hic\": \"3410552807,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F24e516ce-0b49-4476-b818-cc96471d8765%2F4DNFIPAI8XB5.hic\": \"4168518737,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fac3b06b5-46d4-4c1e-97e9-9a4f353473a7%2F4DNFI1OUWFSC.hic\": \"10766406904,21916\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F76c6aa27-895f-4e82-8ed8-7a85aca84490%2F4DNFIX4PJKXZ.hic\": \"1463157350,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fe6fbe03a-997b-4d72-a3cc-f1ed7bd88a92%2F4DNFIZGCA8AH.hic\": \"1597664180,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F61d99a87-4ec6-4116-be99-b483999641c4%2F4DNFI5CGQ46V.hic\": \"2870576870,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F271ea8cd-53b9-44c9-9fff-1bb5c444b54c%2F4DNFIOCW5AEM.hic\": \"2463600138,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fa98ca64a-861a-4a8c-92e9-586af457b1fb%2F4DNFI1UEG1HD.hic\": \"22480709268,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F5809b32e-0aea-4cf5-a174-cf162d591a35%2F4DNFI9YAVTI1.hic\": \"3141182061,25900\"\n}","import Zlib from \"./vendor/zlib_and_gzip.js\"\nimport BrowserLocalFile from './io/browserLocalFile.js';\nimport RemoteFile from './io/remoteFile.js';\nimport ThrottledFile from './io/throttledFile.js';\nimport RateLimiter from './io/rateLimiter.js';\nimport BufferedFile from './io/bufferedFile.js';\nimport BinaryParser from './binary.js';\nimport Matrix from './matrix.js';\nimport ContactRecord from './contactRecord.js';\nimport LRU from './lru.js';\nimport NormalizationVector from \"./normalizationVector.js\";\nimport nvi from './nvi.js'\n\nconst isNode = typeof process !== 'undefined' && process.versions != null && process.versions.node != null;\nconst Short_MIN_VALUE = -32768;\nconst DOUBLE = 8\nconst FLOAT = 4\nconst LONG = 8;\nconst INT = 4;\nconst GoogleRateLimiter = new RateLimiter(100)\n\n\nclass HicFile {\n\n constructor(args) {\n\n if (args.alert) {\n this.alert = args.alert\n }\n\n this.config = args\n\n this.loadFragData = args.loadFragData\n this.fragmentSitesCache = {}\n this.normVectorCache = new LRU(10)\n this.normalizationTypes = ['NONE'];\n this.matrixCache = new LRU(10);\n this.blockCache = new BlockCache();\n\n // args may specify an io.File object, a local path (Node only), or a url\n if (args.file) {\n this.file = args.file\n } else if (args.blob) {\n this.file = new BrowserLocalFile(args.blob)\n } else if (args.url || (args.path && !isNode)) {\n this.url = args.url || this.path;\n this.remote = true\n\n // Google drive must be rate limited. Perhaps all remote files should be rate limited?\n const remoteFile = new RemoteFile(args)\n if (isGoogleDrive(this.url)) {\n this.file = new ThrottledFile(remoteFile, GoogleRateLimiter)\n } else {\n this.file = remoteFile\n }\n } else if (args.path) {\n // path argument, assumed local file\n throw Error(`path property is deprecated, use NodeLocalFile`)\n } else {\n throw Error(\"Arguments must include file, blob, url, or path\")\n }\n }\n\n async init() {\n\n if (this.initialized) {\n return;\n } else {\n await this.readHeaderAndFooter()\n // Footer is read with header\n //await this.readFooter()\n this.initialized = true\n }\n }\n\n async getVersion() {\n if (this.version === undefined) {\n const data = await this.file.read(0, 128)\n if (!data) {\n return undefined;\n }\n const binaryParser = new BinaryParser(new DataView(data));\n this.magic = binaryParser.getString();\n this.version = binaryParser.getInt();\n return this.version\n } else {\n return this.version\n }\n }\n\n async getMetaData() {\n await this.init()\n return this.meta\n }\n\n async readHeaderAndFooter() {\n\n // Read initial fields magic, version, and footer position\n let data = await this.file.read(0, 16)\n if (!data || data.byteLength === 0) {\n throw Error(\"File content is empty\")\n }\n let binaryParser = new BinaryParser(new DataView(data));\n this.magic = binaryParser.getString();\n this.version = binaryParser.getInt();\n if (this.version < 5) {\n throw Error(\"Unsupported hic version: \" + this.version)\n }\n this.footerPosition = binaryParser.getLong();\n\n // Read footer and determine file position for body section (i.e. end of header)\n\n await this.readFooter();\n\n const bodyPostion = Object.values(this.masterIndex).reduce((min, currentValue) => {\n return Math.min(min, currentValue.start)\n }, Number.MAX_VALUE)\n\n const remainingSize = bodyPostion - 16;\n data = await this.file.read(16, remainingSize);\n binaryParser = new BinaryParser(new DataView(data));\n\n this.genomeId = binaryParser.getString();\n\n if (this.version >= 9) {\n this.normVectorIndexPosition = binaryParser.getLong();\n this.normVectorIndexSize = binaryParser.getLong();\n }\n\n this.attributes = {};\n let nAttributes = binaryParser.getInt();\n while (nAttributes-- > 0) {\n this.attributes[binaryParser.getString()] = binaryParser.getString();\n }\n\n this.chromosomes = [];\n this.chromosomeIndexMap = {}\n let nChrs = binaryParser.getInt();\n let i = 0\n while (nChrs-- > 0) {\n const chr = {\n index: i,\n name: binaryParser.getString(),\n size: this.version < 9 ? binaryParser.getInt() : binaryParser.getLong()\n };\n if (chr.name.toLowerCase() === \"all\") {\n this.wholeGenomeChromosome = chr;\n this.wholeGenomeResolution = Math.round(chr.size * (1000 / 500)); // Hardcoded in juicer\n }\n this.chromosomes.push(chr);\n this.chromosomeIndexMap[chr.name] = chr.index\n i++;\n }\n\n this.bpResolutions = [];\n let nBpResolutions = binaryParser.getInt();\n while (nBpResolutions-- > 0) {\n this.bpResolutions.push(binaryParser.getInt());\n }\n\n if (this.loadFragData) {\n this.fragResolutions = [];\n let nFragResolutions = binaryParser.getInt();\n if (nFragResolutions > 0) {\n while (nFragResolutions-- > 0) {\n this.fragResolutions.push(binaryParser.getInt());\n }\n\n // this.sites = [];\n // for(let i=0; i 0) {\n const key = binaryParser.getString()\n const pos = binaryParser.getLong()\n const size = binaryParser.getInt()\n this.masterIndex[key] = {start: pos, size: size}\n }\n\n this.expectedValueVectors = {}\n\n // Expected values\n // const nExpValues = binaryParser.readInt();\n // while (nExpValues-- > 0) {\n // type = \"NONE\";\n // unit = binaryParser.getString();\n // binSize = binaryParser.getInt();\n // nValues = binaryParser.getInt();\n // values = [];\n // while (nValues-- > 0) {\n // values.push(binaryParser.getDouble());\n // }\n //\n // nChrScaleFactors = binaryParser.getInt();\n // normFactors = {};\n // while (nChrScaleFactors-- > 0) {\n // normFactors[binaryParser.getInt()] = binaryParser.getDouble();\n // }\n //\n // // key = unit + \"_\" + binSize + \"_\" + type;\n // // NOT USED YET SO DON'T STORE\n // // dataset.expectedValueVectors[key] =\n // // new ExpectedValueFunction(type, unit, binSize, values, normFactors);\n // }\n\n // normalized expected values start after expected value. Add 4 for\n if (this.version > 5) {\n const skip = this.version < 9 ? 4 : 8;\n this.normExpectedValueVectorsPosition = this.footerPosition + skip + nBytes;\n }\n return this;\n };\n\n async printIndexStats() {\n\n let totalSize = 0;\n let maxSize = 0;\n let maxKey;\n await await this.init();\n for (let key of Object.keys(this.masterIndex)) {\n const entry = this.masterIndex[key];\n // console.log(`${key}\\t${entry.start}\\t${entry.size}`)\n totalSize += entry.size;\n if (entry.size > maxSize) {\n maxSize = entry.size;\n maxKey = key;\n }\n }\n // console.log(`Total size = ${totalSize}`);\n console.log(`${maxSize} ${maxKey} ${this.config.url}`)\n }\n\n async getMatrix(chrIdx1, chrIdx2) {\n const key = Matrix.getKey(chrIdx1, chrIdx2);\n if (this.matrixCache.has(key)) {\n return this.matrixCache.get(key);\n } else {\n const matrix = await this.readMatrix(chrIdx1, chrIdx2);\n this.matrixCache.set(key, matrix);\n return matrix;\n }\n }\n\n async readMatrix(chrIdx1, chrIdx2) {\n\n await this.init()\n\n if (chrIdx1 > chrIdx2) {\n const tmp = chrIdx1\n chrIdx1 = chrIdx2\n chrIdx2 = tmp\n }\n\n const key = Matrix.getKey(chrIdx1 , chrIdx2)\n const idx = this.masterIndex[key]\n if (!idx) {\n return undefined\n }\n const data = await this.file.read(idx.start, idx.size)\n if (!data) {\n return undefined\n }\n\n return Matrix.parseMatrix(data, this.chromosomes);\n\n }\n\n async getContactRecords(normalization, region1, region2, units, binsize, allRecords = false) {\n\n await this.init();\n\n const idx1 = this.chromosomeIndexMap[this.getFileChrName(region1.chr)];\n const idx2 = this.chromosomeIndexMap[this.getFileChrName(region2.chr)];\n\n const transpose = (idx1 > idx2) || (idx1 === idx2 && region1.start >= region2.end);\n if (transpose) {\n const tmp = region1\n region1 = region2;\n region2 = tmp;\n }\n\n const blocks = await this.getBlocks(region1, region2, units, binsize)\n if (!blocks || blocks.length === 0) {\n return []\n }\n\n const contactRecords = [];\n const x1 = region1.start / binsize\n const x2 = region1.end / binsize\n const y1 = region2.start / binsize\n const y2 = region2.end / binsize\n const nvX1 = Math.floor(x1);\n const nvX2 = Math.ceil(x2);\n const nvY1 = Math.floor(y1);\n const nvY2 = Math.ceil(y2);\n for (let block of blocks) {\n if (block) { // An undefined block is most likely caused by a base pair range outside the chromosome\n let normVector1;\n let normVector2;\n let isNorm = normalization && normalization !== \"NONE\";\n const chr1 = this.getFileChrName(region1.chr);\n const chr2 = this.getFileChrName(region2.chr);\n if (isNorm) {\n\n const nv1 = await this.getNormalizationVector(normalization, chr1, units, binsize);\n const nv2 = (chr1 === chr2) ? nv1 : await this.getNormalizationVector(normalization, chr2, units, binsize);\n\n if (nv1 && nv2) {\n normVector1 = await nv1.getValues(nvX1, nvX2);\n normVector2 = await nv2.getValues(nvY1, nvY2);\n } else {\n isNorm = false;\n // Raise message and switch pulldown\n }\n }\n\n for (let rec of block.records) {\n if (allRecords || (rec.bin1 >= x1 && rec.bin1 < x2 && rec.bin2 >= y1 && rec.bin2 < y2)) {\n if (isNorm) {\n const x = rec.bin1;\n const y = rec.bin2;\n const nvnv = normVector1[x - nvX1] * normVector2[y - nvY1];\n if (nvnv !== 0 && !isNaN(nvnv)) {\n const counts = rec.counts / nvnv;\n contactRecords.push(new ContactRecord(x, y, counts));\n }\n } else {\n contactRecords.push(rec);\n }\n }\n }\n }\n }\n\n return contactRecords;\n }\n\n async getBlocks(region1, region2, unit, binSize) {\n\n const blockKey = (blockNumber, zd) => `${zd.getKey()}_${blockNumber}`\n\n await this.init()\n const chr1 = this.getFileChrName(region1.chr)\n const chr2 = this.getFileChrName(region2.chr)\n const idx1 = this.chromosomeIndexMap[chr1]\n const idx2 = this.chromosomeIndexMap[chr2]\n\n if (idx1 === undefined) {\n console.log(\"No chromosome named: \" + region1.chr)\n return []\n }\n if (idx2 === undefined) {\n console.log(\"No chromosome named: \" + region2.chr)\n return []\n }\n\n const matrix = await this.getMatrix(idx1, idx2)\n if (!matrix) {\n console.log(\"No matrix for \" + region1.chr + \"-\" + region2.chr)\n return []\n }\n\n const zd = matrix.getZoomData(binSize, unit);\n if (!zd) {\n let msg = `No data avalailble for resolution: ${binSize} for map ${region1.chr}-${region2.chr}`\n throw new Error(msg)\n }\n\n const blockNumbers = zd.getBlockNumbers(region1, region2, this.version);\n\n const blocks = [];\n const blockNumbersToQuery = [];\n for (let num of blockNumbers) {\n const key = blockKey(num, zd)\n if (this.blockCache.has(binSize, key)) {\n blocks.push(this.blockCache.get(binSize, key));\n } else {\n blockNumbersToQuery.push(num);\n }\n }\n\n const promises = blockNumbersToQuery.map(blockNumber => this.readBlock(blockNumber, zd));\n const newBlocks = await Promise.all(promises);\n for (let block of newBlocks) {\n if (block) {\n this.blockCache.set(binSize, blockKey(block.blockNumber, zd), block);\n }\n }\n return blocks.concat(newBlocks);\n }\n\n async readBlock(blockNumber, zd) {\n\n const idx = await zd.blockIndex.getBlockIndexEntry(blockNumber);\n\n if (!idx) {\n return undefined\n } else {\n let data = await this.file.read(idx.filePosition, idx.size)\n if (!data) {\n return undefined;\n }\n\n const inflate = new Zlib.Inflate(new Uint8Array(data));\n const plain = inflate.decompress();\n //var plain = zlib.inflateSync(Buffer.from(data)) //.decompress();\n data = plain.buffer;\n\n const parser = new BinaryParser(new DataView(data));\n const nRecords = parser.getInt();\n const records = [];\n\n if (this.version < 7) {\n for (let i = 0; i < nRecords; i++) {\n const binX = parser.getInt();\n const binY = parser.getInt();\n const counts = parser.getFloat();\n records.push(new ContactRecord(binX, binY, counts));\n }\n } else {\n\n const binXOffset = parser.getInt();\n const binYOffset = parser.getInt();\n\n const useFloatContact = parser.getByte() === 1;\n const useIntXPos = this.version < 9 ? false : parser.getByte() == 1;\n const useIntYPos = this.version < 9 ? false : parser.getByte() == 1;\n const type = parser.getByte();\n\n if (type === 1) {\n // List-of-rows representation\n const rowCount = useIntYPos ? parser.getInt() : parser.getShort();\n for (let i = 0; i < rowCount; i++) {\n const dy = useIntYPos ? parser.getInt() : parser.getShort();\n const binY = binYOffset + dy;\n const colCount = useIntXPos ? parser.getInt() : parser.getShort();\n for (let j = 0; j < colCount; j++) {\n const dx = useIntXPos ? parser.getInt() : parser.getShort();\n const binX = binXOffset + dx;\n const counts = useFloatContact ? parser.getFloat() : parser.getShort();\n records.push(new ContactRecord(binX, binY, counts));\n }\n }\n } else if (type == 2) {\n\n const nPts = parser.getInt();\n const w = parser.getShort();\n\n for (let i = 0; i < nPts; i++) {\n //int idx = (p.y - binOffset2) * w + (p.x - binOffset1);\n const row = Math.floor(i / w);\n const col = i - row * w;\n const bin1 = binXOffset + col;\n const bin2 = binYOffset + row;\n\n if (useFloatContact) {\n const counts = parser.getFloat();\n if (!isNaN(counts)) {\n records.push(new ContactRecord(bin1, bin2, counts));\n }\n } else {\n const counts = parser.getShort();\n if (counts != Short_MIN_VALUE) {\n records.push(new ContactRecord(bin1, bin2, counts));\n }\n }\n }\n } else {\n throw new Error(\"Unknown block type: \" + type);\n }\n\n }\n\n return new Block(blockNumber, zd, records, idx);\n\n\n }\n };\n\n async hasNormalizationVector(type, chr, unit, binSize) {\n await this.init()\n let chrIdx\n if (Number.isInteger(chr)) {\n chrIdx = chr\n } else {\n const canonicalName = this.getFileChrName(chr)\n chrIdx = this.chromosomeIndexMap[canonicalName]\n }\n const key = getNormalizationVectorKey(type, chrIdx, unit.toString(), binSize);\n const normVectorIndex = await this.getNormVectorIndex()\n return normVectorIndex && normVectorIndex[key];\n }\n\n async isNormalizationValueAvailableAtResolution(normalization, chr, unit, resolution) {\n\n let chromosomeIndex\n if (Number.isInteger(chr)) {\n chromosomeIndex = chr\n } else {\n const canonicalName = this.getFileChrName(chr)\n chromosomeIndex = this.chromosomeIndexMap[canonicalName]\n }\n\n const normVectorIndex = await this.getNormVectorIndex()\n\n const key = getNormalizationVectorKey(normalization, chromosomeIndex, unit.toString(), resolution)\n\n const index = normVectorIndex[key]\n\n return undefined !== index\n\n }\n\n async getNormalizationVector(type, chr, unit, binSize) {\n\n await this.init()\n\n let chrIdx\n if (Number.isInteger(chr)) {\n chrIdx = chr\n } else {\n const canonicalName = this.getFileChrName(chr)\n chrIdx = this.chromosomeIndexMap[canonicalName]\n }\n\n const key = getNormalizationVectorKey(type, chrIdx, unit.toString(), binSize);\n\n if (this.normVectorCache.has(key)) {\n return this.normVectorCache.get(key);\n }\n\n const normVectorIndex = await this.getNormVectorIndex()\n\n if (!normVectorIndex) {\n console.log(\"Normalization vectors not present in this file\")\n return undefined\n }\n\n const status = await this.isNormalizationValueAvailableAtResolution(type, chr, unit, binSize)\n\n if (false === status) {\n\n const str = `Normalization option ${ type } not available at resolution ${ binSize }. Will use NONE.`\n console.log(str)\n\n if (this.alert) {\n this.alert(str)\n } \n return undefined\n }\n\n const idx = normVectorIndex[key];\n\n const data = await this.file.read(idx.filePosition, 8)\n\n if (!data) {\n return undefined;\n }\n\n const parser = new BinaryParser(new DataView(data));\n const nValues = this.version < 9 ? parser.getInt() : parser.getLong();\n const dataType = this.version < 9 ? DOUBLE : FLOAT;\n const filePosition = this.version < 9 ? idx.filePosition + 4 : idx.filePosition + 8;\n const nv = new NormalizationVector(this.file, filePosition, nValues, dataType);\n this.normVectorCache.set(key, nv);\n return nv;\n\n }\n\n async getNormVectorIndex() {\n\n if (this.version < 6) {\n return undefined;\n }\n\n if (!this.normVectorIndex) {\n\n // If nvi is not supplied, try reading from remote lambda service\n if (!this.config.nvi && this.remote && this.url) {\n const url = new URL(this.url)\n const key = encodeURIComponent(url.hostname + url.pathname)\n if(nvi.hasOwnProperty(key)) {\n this.config.nvi = nvi[key]\n }\n }\n\n if (this.config.nvi) {\n const nviArray = decodeURIComponent(this.config.nvi).split(\",\")\n const range = {start: parseInt(nviArray[0]), size: parseInt(nviArray[1])};\n return this.readNormVectorIndex(range)\n } else {\n try {\n await this.readNormExpectedValuesAndNormVectorIndex()\n return this.normVectorIndex\n } catch (e) {\n if (e.code === \"416\" || e.code === 416) {\n // This is expected if file does not contain norm vectors\n this.normExpectedValueVectorsPosition = undefined\n } else {\n console.error(e)\n }\n }\n }\n }\n\n return this.normVectorIndex\n }\n\n async getNormalizationOptions() {\n // Normalization options are computed as a side effect of loading the index. A bit\n // ugly but alternatives are worse.\n await this.getNormVectorIndex()\n return this.normalizationTypes;\n }\n\n /**\n * Return a promise to load the normalization vector index\n *\n * @param dataset\n * @param range -- file range {position, size}\n * @returns Promise for the normalization vector index\n */\n async readNormVectorIndex(range) {\n\n await this.init()\n\n this.normalizationVectorIndexRange = range;\n\n const data = await this.file.read(range.start, range.size)\n\n const binaryParser = new BinaryParser(new DataView(data));\n\n this.normVectorIndex = {};\n\n let nEntries = binaryParser.getInt();\n while (nEntries-- > 0) {\n this.parseNormVectorEntry(binaryParser)\n }\n\n return this.normVectorIndex;\n\n }\n\n /**\n * This function is used when the position of the norm vector index is unknown. We must read through the expected\n * values to find the index\n *\n * @param dataset\n * @returns {Promise}\n */\n async readNormExpectedValuesAndNormVectorIndex() {\n\n await this.init()\n\n if (this.normExpectedValueVectorsPosition === undefined) {\n return;\n }\n\n const nviStart = await this.skipExpectedValues(this.normExpectedValueVectorsPosition)\n let byteCount = INT;\n\n let data = await this.file.read(nviStart, INT);\n if (data.byteLength === 0) {\n // This is possible if there are no norm vectors. Its a legal v8 file, though uncommon\n return;\n }\n const binaryParser = new BinaryParser(new DataView(data));\n const nEntries = binaryParser.getInt();\n const sizeEstimate = nEntries * 30;\n const range = {start: nviStart + byteCount, size: sizeEstimate}\n\n data = await this.file.read(range.start, range.size)\n this.normalizedExpectedValueVectors = {};\n this.normVectorIndex = {};\n\n // Recursively process entries\n await processEntries.call(this, nEntries, data)\n\n this.config.nvi = nviStart.toString() + \",\" + byteCount\n\n async function processEntries(nEntries, data) {\n\n const binaryParser = new BinaryParser(new DataView(data));\n\n while (nEntries-- > 0) {\n\n if (binaryParser.available() < 100) {\n\n nEntries++; // Reset counter as entry is not processed\n\n byteCount += binaryParser.position;\n const sizeEstimate = Math.max(1000, nEntries * 30);\n const range = {start: nviStart + byteCount, size: sizeEstimate}\n const data = await this.file.read(range.start, range.size)\n return processEntries.call(this, nEntries, data);\n }\n\n this.parseNormVectorEntry(binaryParser)\n\n }\n byteCount += binaryParser.position;\n }\n }\n\n /**\n * This function is used when the position of the norm vector index is unknown. We must read through the\n * normalized expected values to find the index\n *\n * @param dataset\n * @returns {Promise}\n */\n async skipExpectedValues(start) {\n\n const version = this.version;\n const file = new BufferedFile({file: this.file, size: 256000})\n const range = {start: start, size: INT};\n const data = await file.read(range.start, range.size)\n const binaryParser = new BinaryParser(new DataView(data));\n const nEntries = binaryParser.getInt(); // Total # of expected value chunks\n if (nEntries === 0) {\n return start + INT;\n } else {\n return parseNext(start + INT, nEntries);\n } // Skip 4 bytes for int\n\n\n async function parseNext(start, nEntries) {\n\n let range = {start: start, size: 500}\n let chunkSize = 0\n let p0 = start;\n\n let data = await file.read(range.start, range.size)\n let binaryParser = new BinaryParser(new DataView(data));\n const type = binaryParser.getString(); // type\n const unit = binaryParser.getString(); // unit\n const binSize = binaryParser.getInt(); // binSize\n const nValues = version < 9 ? binaryParser.getInt() : binaryParser.getLong();\n\n chunkSize += binaryParser.position + nValues * (version < 9 ? DOUBLE : FLOAT);\n\n range = {start: start + chunkSize, size: INT};\n data = await file.read(range.start, range.size)\n binaryParser = new BinaryParser(new DataView(data));\n const nChrScaleFactors = binaryParser.getInt();\n chunkSize += (INT + nChrScaleFactors * (INT + (version < 9 ? DOUBLE : FLOAT)));\n\n\n nEntries--;\n if (nEntries === 0) {\n return p0 + chunkSize;\n } else {\n return parseNext(p0 + chunkSize, nEntries);\n }\n }\n }\n\n getZoomIndexForBinSize(binSize, unit) {\n\n unit = unit || \"BP\";\n\n let resolutionArray\n if (unit === \"BP\") {\n resolutionArray = this.bpResolutions;\n } else if (unit === \"FRAG\") {\n resolutionArray = this.fragResolutions;\n } else {\n throw new Error(\"Invalid unit: \" + unit);\n }\n\n for (let i = 0; i < resolutionArray.length; i++) {\n if (resolutionArray[i] === binSize) return i;\n }\n\n return -1;\n }\n\n parseNormVectorEntry(binaryParser) {\n const type = binaryParser.getString(); //15\n const chrIdx = binaryParser.getInt(); //4\n const unit = binaryParser.getString(); //3\n const binSize = binaryParser.getInt(); //4\n const filePosition = binaryParser.getLong(); //8\n const sizeInBytes = this.version < 9 ? binaryParser.getInt() : binaryParser.getLong(); //4:8\n const key = type + \"_\" + chrIdx + \"_\" + unit + \"_\" + binSize;\n // TODO -- why does this not work? NormalizationVector.getNormalizationVectorKey(type, chrIdx, unit, binSize);\n\n if (!this.normalizationTypes.includes(type)) {\n this.normalizationTypes.push(type);\n }\n this.normVectorIndex[key] = {filePosition: filePosition, size: sizeInBytes};\n }\n\n getFileChrName(chrAlias) {\n if (this.chrAliasTable.hasOwnProperty(chrAlias)) {\n return this.chrAliasTable[chrAlias]\n } else {\n return chrAlias\n }\n }\n\n\n // NOTE sties are not currently used\n // async getSites(chrName) {\n // let sites = this.fragmentSitesCache[chrName];\n // if (!sites) {\n // if (this.fragmentSitesIndex) {\n // const entry = self.fragmentSitesIndex[chrName];\n // if (entry && entry.nSites > 0) {\n // sites = await this.readSites(entry.position, entry.nSites)\n // this.fragmentSitesCache[chrName] = sites;\n // }\n // }\n // }\n // return sites;\n // }\n //\n\n}\n\n\nfunction getNormalizationVectorKey(type, chrIdx, unit, resolution) {\n return type + \"_\" + chrIdx + \"_\" + unit + \"_\" + resolution;\n}\n\nfunction isGoogleDrive(url) {\n return url.indexOf(\"drive.google.com\") >= 0 || url.indexOf(\"www.googleapis.com/drive\") > 0\n}\n\nclass Block {\n constructor(blockNumber, zoomData, records, idx) {\n this.blockNumber = blockNumber;\n this.zoomData = zoomData;\n this.records = records;\n this.idx = idx\n }\n}\n\n\nclass BlockCache {\n\n constructor() {\n this.resolution = undefined;\n this.map = new LRU(6);\n }\n\n set(resolution, key, value) {\n if (this.resolution !== resolution) {\n this.map.clear();\n }\n this.resolution = resolution;\n this.map.set(key, value);\n }\n\n get(resolution, key) {\n return this.resolution === resolution ? this.map.get(key) : undefined;\n }\n\n has(resolution, key) {\n return this.resolution === resolution && this.map.has(key);\n }\n}\n\n\nexport default HicFile;\n","class RateLimiter {\n\n constructor(wait) {\n this.wait = wait === undefined ? 100 : wait\n\n this.isCalled = false\n this.calls = [];\n }\n\n\n limiter(fn) {\n\n const self = this\n\n let caller = function () {\n\n if (self.calls.length && !self.isCalled) {\n self.isCalled = true;\n self.calls.shift().call();\n setTimeout(function () {\n self.isCalled = false;\n caller();\n }, self.wait);\n }\n };\n\n return function () {\n self.calls.push(fn.bind(this, ...arguments));\n caller();\n };\n }\n\n}\n\nexport default RateLimiter;","import HicFile from \"./hicFile.js\"\n\nclass Straw {\n\n constructor(config) {\n this.config = config;\n this.hicFile = new HicFile(config);\n }\n\n async getMetaData() {\n return await this.hicFile.getMetaData()\n }\n\n //straw [:x1:x2] [:y1:y2] \n async getContactRecords(normalization, region1, region2, units, binsize) {\n return this.hicFile.getContactRecords(normalization, region1, region2, units, binsize);\n }\n\n async getNormalizationOptions() {\n return this.hicFile.getNormalizationOptions()\n }\n\n async getNVI() {\n await this.hicFile.getNormVectorIndex()\n return this.hicFile.config.nvi;\n }\n\n async printIndexStats() {\n await this.hicFile.printIndexStats();\n }\n\n getFileChrName(chrAlias) {\n if (this.hicFile.chrAliasTable.hasOwnProperty(chrAlias)) {\n return this.hicFile.chrAliasTable[chrAlias]\n } else {\n return chrAlias\n }\n }\n}\n\n\nexport default Straw\n","function isGoogleURL(url) {\n return (url.includes(\"googleapis\") && !url.includes(\"urlshortener\")) ||\n isGoogleStorageURL(url) ||\n isGoogleDriveURL(url)\n}\n\nfunction isGoogleStorageURL(url) {\n return url.startsWith(\"gs://\") ||\n url.startsWith(\"https://www.googleapis.com/storage\") ||\n url.startsWith(\"https://storage.cloud.google.com\") ||\n url.startsWith(\"https://storage.googleapis.com\");\n}\n\nfunction isGoogleDriveURL(url) {\n return url.indexOf(\"drive.google.com\") >= 0 || url.indexOf(\"www.googleapis.com/drive\") > 0\n}\n\n/**\n * Translate gs:// urls to https\n * See https://cloud.google.com/storage/docs/json_api/v1\n * @param gsUrl\n * @returns {string|*}\n */\nfunction translateGoogleCloudURL(gsUrl) {\n\n let {bucket, object} = parseBucketName(gsUrl);\n object = encode(object);\n\n const qIdx = gsUrl.indexOf('?');\n const paramString = (qIdx > 0) ? gsUrl.substring(qIdx) + \"&alt=media\" : \"?alt=media\";\n\n return `https://storage.googleapis.com/storage/v1/b/${bucket}/o/${object}${paramString}`\n}\n\n/**\n * Parse a google bucket and object name from a google storage URL. Known forms include\n *\n * gs://BUCKET_NAME/OBJECT_NAME\n * https://storage.googleapis.com/BUCKET_NAME/OBJECT_NAME\n * https://storage.googleapis.com/storage/v1/b/BUCKET_NAME/o/OBJECT_NAME\n * https://www.googleapis.com/storage/v1/b/BUCKET_NAME/o/OBJECT_NAME\"\n * https://storage.googleapis.com/download/storage/v1/b/BUCKET_NAME/o/OBJECT_NAME\n *\n * @param url\n */\nfunction parseBucketName(url) {\n\n let bucket;\n let object;\n\n if (url.startsWith(\"gs://\")) {\n const i = url.indexOf('/', 5);\n if (i >= 0) {\n bucket = url.substring(5, i);\n const qIdx = url.indexOf('?');\n object = (qIdx < 0) ? url.substring(i + 1) : url.substring(i + 1, qIdx);\n }\n\n } else if (url.startsWith(\"https://storage.googleapis.com\") || url.startsWith(\"https://storage.cloud.google.com\")) {\n const bucketIdx = url.indexOf(\"/v1/b/\", 8)\n if (bucketIdx > 0) {\n const objIdx = url.indexOf(\"/o/\", bucketIdx);\n if (objIdx > 0) {\n const queryIdx = url.indexOf(\"?\", objIdx);\n bucket = url.substring(bucketIdx + 6, objIdx);\n object = queryIdx > 0 ? url.substring(objIdx + 3, queryIdx) : url.substring(objIdx + 3);\n }\n\n } else {\n const idx1 = url.indexOf(\"/\", 8);\n const idx2 = url.indexOf(\"/\", idx1+1);\n const idx3 = url.indexOf(\"?\", idx2);\n if (idx2 > 0) {\n bucket = url.substring(idx1+1, idx2);\n object = idx3 < 0 ? url.substring(idx2+1) : url.substring(idx2+1, idx3);\n }\n }\n\n } else if (url.startsWith(\"https://www.googleapis.com/storage/v1/b\")) {\n const bucketIdx = url.indexOf(\"/v1/b/\", 8);\n const objIdx = url.indexOf(\"/o/\", bucketIdx);\n if (objIdx > 0) {\n const queryIdx = url.indexOf(\"?\", objIdx);\n bucket = url.substring(bucketIdx + 6, objIdx);\n object = queryIdx > 0 ? url.substring(objIdx + 3, queryIdx) : url.substring(objIdx + 3);\n }\n }\n\n if (bucket && object) {\n return {\n bucket, object\n }\n } else {\n throw Error(`Unrecognized Google Storage URI: ${url}`)\n }\n\n}\n\n/**\n * Percent a GCS object name. See https://cloud.google.com/storage/docs/request-endpoints\n * Specific characters to encode:\n * !, #, $, &, ', (, ), *, +, ,, /, :, ;, =, ?, @, [, ], and space characters.\n * @param obj\n */\n\nfunction encode(objectName) {\n\n let result = '';\n objectName.split('').forEach(function(letter) {\n if(encodings.has(letter)) {\n result += encodings.get(letter);\n } else {\n result += letter;\n }\n })\n return result;\n}\n\n//\t%23\t%24\t%25\t%26\t%27\t%28\t%29\t%2A\t%2B\t%2C\t%2F\t%3A\t%3B\t%3D\t%3F\t%40\t%5B\t%5D\nconst encodings = new Map();\nencodings.set(\"!\", \"%21\");\nencodings.set(\"#\", \"%23\");\nencodings.set(\"$\", \"%24\");\nencodings.set(\"%\", \"%25\");\nencodings.set(\"&\", \"%26\");\nencodings.set(\"'\", \"%27\");\nencodings.set(\"(\", \"%28\");\nencodings.set(\")\", \"%29\");\nencodings.set(\"*\", \"%2A\");\nencodings.set(\"+\", \"%2B\");\nencodings.set(\",\", \"%2C\");\nencodings.set(\"/\", \"%2F\");\nencodings.set(\":\", \"%3A\");\nencodings.set(\";\", \"%3B\");\nencodings.set(\"=\", \"%3D\");\nencodings.set(\"?\", \"%3F\");\nencodings.set(\"@\", \"%40\");\nencodings.set(\"[\", \"%5B\");\nencodings.set(\"]\", \"%5D\");\nencodings.set(\" \", \"%20\");\n\n// For testing\n//for(let [key, value] of encodings) {\n// const v2 = encodeURIComponent(key);\n// console.log(value + \" \" + v2);\n//}\n\nexport {\n isGoogleURL, isGoogleDriveURL, isGoogleStorageURL, translateGoogleCloudURL, parseBucketName\n}\n\n\n\n","import {getAccessToken, getApiKey} from \"./googleAuth.js\"\n\n\n/**\n * Return information about a specific google drive URL\n *\n * @param googleDriveURL\n * @returns {Promise}\n */\nasync function getDriveFileInfo(googleDriveURL) {\n\n const id = getGoogleDriveFileID(googleDriveURL);\n let endPoint = \"https://www.googleapis.com/drive/v3/files/\" + id + \"?supportsTeamDrives=true\";\n const apiKey = getApiKey();\n if (apiKey) {\n endPoint += \"&key=\" + apiKey;\n }\n const response = await fetch(endPoint);\n let json = await response.json();\n if (json.error && json.error.code === 404) {\n let scope = \"https://www.googleapis.com/auth/drive.readonly\"\n const access_token = await getAccessToken(scope);\n if (access_token) {\n const response = await fetch(endPoint, {\n headers: {\n 'Authorization': `Bearer ${access_token}`\n }\n })\n json = await response.json();\n if (json.error) {\n throw Error(json.error);\n }\n } else {\n throw Error(json.error);\n }\n }\n return json;\n}\n\n/**\n * Return general Google Drive information for the currently logged in user*\n * *\n * @returns {Promise}\n */\nasync function getDriveInfo() {\n const access_token = await getAccessToken('https://www.googleapis.com/auth/drive.readonly')\n const endPoint = \"https://www.googleapis.com/drive/v3/about?fields=*\"\n const response = await fetch(endPoint, {\n headers: {\n 'Authorization': `Bearer ${access_token}`\n }\n })\n return response.json()\n}\n\n\nfunction getDriveDownloadURL(link) {\n // Return a google drive download url for the sharable link\n //https://drive.google.com/open?id=0B-lleX9c2pZFbDJ4VVRxakJzVGM\n //https://drive.google.com/file/d/1_FC4kCeO8E3V4dJ1yIW7A0sn1yURKIX-/view?usp=sharing\n var id = getGoogleDriveFileID(link);\n return id ? \"https://www.googleapis.com/drive/v3/files/\" + id + \"?alt=media&supportsTeamDrives=true\" : link;\n}\n\nfunction getGoogleDriveFileID(link) {\n\n //https://drive.google.com/file/d/1_FC4kCeO8E3V4dJ1yIW7A0sn1yURKIX-/view?usp=sharing\n //https://www.googleapis.com/drive/v3/files/1w-tvo6p1SH4p1OaQSVxpkV_EJgGIstWF?alt=media&supportsTeamDrives=true\"\n\n if (link.includes(\"/open?id=\")) {\n const i1 = link.indexOf(\"/open?id=\") + 9;\n const i2 = link.indexOf(\"&\");\n if (i1 > 0 && i2 > i1) {\n return link.substring(i1, i2)\n } else if (i1 > 0) {\n return link.substring(i1);\n }\n\n } else if (link.includes(\"/file/d/\")) {\n const i1 = link.indexOf(\"/file/d/\") + 8;\n const i2 = link.lastIndexOf(\"/\");\n return link.substring(i1, i2);\n\n } else if (link.startsWith(\"https://www.googleapis.com/drive\")) {\n let i1 = link.indexOf(\"/files/\")\n const i2 = link.indexOf(\"?\")\n if (i1 > 0) {\n i1 += 7;\n return i2 > 0 ?\n link.substring(i1, i2) :\n link.substring(i1)\n }\n }\n\n throw Error(\"Unknown Google Drive url format: \" + link);\n\n\n}\n\n\n\nexport {getDriveFileInfo, getDriveInfo, getDriveDownloadURL, getGoogleDriveFileID}","/*\n * @author Jim Robinson Dec-2020\n */\n\n/**\n * Implementation of \"RemoteFile\" for hic-straw that uses the igv.xhr object. This object is google aware, and handle\n * oAuth and apiKey automatically.\n */\n\nimport {igvxhr} from '../node_modules/igv-utils/src/index.js'\n\nclass IGVRemoteFile {\n\n\n constructor(args) {\n this.config = args\n this.url = args.path || args.url\n }\n\n\n async read(position, length) {\n\n const range = {start: position, size: length};\n\n return igvxhr.loadArrayBuffer(this.url, {range});\n\n }\n}\n\nexport default IGVRemoteFile\n","/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2016-2020 The Regents of the University of California\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and\n * associated documentation files (the \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the\n * following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all copies or substantial\n * portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING\n * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n *\n */\n\n\n/**\n * @author Jim Robinson\n */\n\nimport {isFile} from \"./fileUtils.js\"\nimport Straw from '../node_modules/hic-straw/src/straw.js'\nimport * as GoogleUtils from \"../node_modules/google-utils/src/googleUtils.js\"\nimport * as GoogleDrive from \"../node_modules/google-utils/src/googleDrive.js\"\n\nimport IGVRemoteFile from \"./igvRemoteFile.js\"\n\nconst knownGenomes = {\n\n \"hg19\": [249250621, 243199373, 198022430],\n \"hg38\": [248956422, 242193529, 198295559],\n \"mm10\": [195471971, 182113224, 160039680],\n \"mm9\": [197195432, 181748087, 159599783],\n \"dm6\": [23513712, 25286936, 28110227]\n\n}\n\nclass Dataset {\n\n constructor(config) {\n this.straw = new Straw(config)\n }\n\n async init() {\n\n this.hicFile = this.straw.hicFile;\n await this.hicFile.init();\n this.normalizationTypes = ['NONE'];\n\n this.genomeId = this.hicFile.genomeId\n this.chromosomes = this.hicFile.chromosomes\n this.bpResolutions = this.hicFile.bpResolutions\n this.wholeGenomeChromosome = this.hicFile.wholeGenomeChromosome\n this.wholeGenomeResolution = this.hicFile.wholeGenomeResolution\n\n // Attempt to determine genomeId if not recognized\n // if (!Object.keys(knownGenomes).includes(this.genomeId)) {\n const tmp = matchGenome(this.chromosomes);\n if (tmp) this.genomeId = tmp;\n // }\n }\n\n async getContactRecords(normalization, region1, region2, units, binsize) {\n return this.straw.getContactRecords(normalization, region1, region2, units, binsize)\n }\n\n async hasNormalizationVector(type, chr, unit, binSize) {\n return this.straw.hicFile.hasNormalizationVector(type, chr, unit, binSize);\n }\n\n clearCaches() {\n this.colorScaleCache = {};\n }\n\n async getMatrix(chr1, chr2) {\n return this.hicFile.getMatrix(chr1, chr2)\n }\n\n getZoomIndexForBinSize(binSize, unit) {\n var i,\n resolutionArray;\n\n unit = unit || \"BP\";\n\n if (unit === \"BP\") {\n resolutionArray = this.bpResolutions;\n } else if (unit === \"FRAG\") {\n resolutionArray = this.fragResolutions;\n } else {\n throw new Error(\"Invalid unit: \" + unit);\n }\n\n for (i = 0; i < resolutionArray.length; i++) {\n if (resolutionArray[i] === binSize) return i;\n }\n\n return -1;\n }\n\n getBinSizeForZoomIndex(zoomIndex, unit) {\n var i,\n resolutionArray;\n\n unit = unit || \"BP\";\n\n if (unit === \"BP\") {\n resolutionArray = this.bpResolutions;\n } else if (unit === \"FRAG\") {\n resolutionArray = this.fragResolutions;\n } else {\n throw new Error(\"Invalid unit: \" + unit);\n }\n\n return resolutionArray[zoomIndex];\n }\n\n getChrIndexFromName(chrName) {\n var i;\n for (i = 0; i < this.chromosomes.length; i++) {\n if (chrName === this.chromosomes[i].name) return i;\n }\n return undefined;\n }\n\n compareChromosomes(otherDataset) {\n const chrs = this.chromosomes;\n const otherChrs = otherDataset.chromosomes;\n if (chrs.length !== otherChrs.length) {\n return false;\n }\n for (let i = 0; i < chrs.length; i++) {\n if (chrs[i].size !== otherChrs[i].size) {\n return false;\n }\n }\n return true;\n }\n\n isWholeGenome(chrIndex) {\n return (this.wholeGenomeChromosome != null && this.wholeGenomeChromosome.index === chrIndex);\n }\n\n async getNormVectorIndex() {\n return this.hicFile.getNormVectorIndex()\n }\n\n async getNormalizationOptions() {\n return this.hicFile.getNormalizationOptions()\n }\n\n /**\n * Compare 2 datasets for compatibility. Compatibility is defined as from the same assembly, even if\n * different IDs are used (e.g. GRCh38 vs hg38).\n *\n * Trust the ID for well-known assemblies (hg19, etc). However, for others compare chromosome lengths\n * as its been observed that uniqueness of ID is not guaranteed.\n *\n * @param d1\n * @param d2\n */\n isCompatible(d2) {\n const id1 = this.genomeId;\n const id2 = d2.genomeId;\n return ((id1 === \"hg38\" || id1 === \"GRCh38\") && (id2 === \"hg38\" || id2 === \"GRCh38\")) ||\n ((id1 === \"hg19\" || id1 === \"GRCh37\") && (id2 === \"hg19\" || id2 === \"GRCh37\")) ||\n ((id1 === \"mm10\" || id1 === \"GRCm38\") && (id2 === \"mm10\" || id2 === \"GRCm38\")) ||\n this.compareChromosomes(d2)\n }\n\n static async loadDataset(config) {\n\n // If this is a local file, use the \"blob\" field for straw\n if (isFile(config.url)) {\n config.blob = config.url\n delete config.url\n } else {\n // If this is a google url, add api KEY\n if (GoogleUtils.isGoogleURL(config.url)) {\n if (GoogleUtils.isGoogleDriveURL(config.url)) {\n config.url = GoogleDrive.getDriveDownloadURL(config.url)\n }\n const copy = Object.assign({}, config);\n config.file = new IGVRemoteFile(copy);\n }\n }\n\n const dataset = new Dataset(config)\n await dataset.init();\n dataset.url = config.url\n return dataset\n }\n}\n\nfunction matchGenome(chromosomes) {\n\n if (chromosomes.length < 4) return undefined;\n\n const keys = Object.keys(knownGenomes);\n\n // Find a candidate\n let candidate;\n for (let chr of chromosomes) {\n for (let key of keys) {\n if (knownGenomes[key].includes(chr.size)) {\n candidate = key;\n break;\n }\n }\n }\n\n // Confirm candidate\n if (candidate) {\n const chrSizes = new Set(chromosomes.map((chr) => chr.size));\n for (let sz of knownGenomes[candidate]) {\n if (!chrSizes.has(sz)) {\n return undefined;\n }\n }\n return candidate;\n } else {\n return undefined;\n }\n\n\n}\n\nexport default Dataset\n","/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2016-2017 The Regents of the University of California\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and\n * associated documentation files (the \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the\n * following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all copies or substantial\n * portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING\n * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n *\n */\n\n\n/**\n * @author Jim Robinson\n */\n\n\n/**\n *\n * @param id\n * @param chromosomes -- an array of hic.Chromosome objects.\n * @constructor\n */\nclass Genome {\n constructor(id, chromosomes) {\n\n this.id = id;\n this.chromosomes = chromosomes\n\n this.wgChromosomeNames = [];\n this.chromosomeLookupTable = {};\n\n // Alias for size for igv compatibility\n this.genomeLength = 0;\n for (let c of this.chromosomes) {\n c.bpLength = c.size;\n if ('all' !== c.name.toLowerCase()) {\n this.genomeLength += c.size;\n this.wgChromosomeNames.push(c.name);\n }\n }\n\n /**\n * Maps chr aliases to the offical name. Deals with\n * 1 <-> chr1, chrM <-> MT, IV <-> chr4, etc.\n * @param str\n */\n var chrAliasTable = {};\n\n // The standard mappings\n for (let chromosome of chromosomes) {\n\n const name = chromosome.name\n if (name.startsWith(\"arm_\")) {\n //Special rule for aidenlab ad-hoc names for dMel\n const officialName = name.substring(4)\n chrAliasTable[officialName] = name\n chrAliasTable[\"chr\" + officialName] = name\n } else {\n const alias = name.startsWith(\"chr\") ? name.substring(3) : \"chr\" + name;\n chrAliasTable[alias] = name;\n if (name === \"chrM\") chrAliasTable[\"MT\"] = \"chrM\";\n if (name === \"MT\") chrAliasTable[\"chrmM\"] = \"MT\";\n }\n this.chromosomeLookupTable[name.toLowerCase()] = chromosome;\n }\n\n this.chrAliasTable = chrAliasTable;\n\n this.featureDB = new Map() // Hash of name -> feature, used for search function.\n\n }\n\n getChromosomeName(str) {\n var chr = this.chrAliasTable[str];\n return chr ? chr : str;\n };\n\n getChromosome(str) {\n var chrname = this.getChromosomeName(str).toLowerCase();\n return this.chromosomeLookupTable[chrname];\n };\n\n /**\n * Return the genome coordinate for the give chromosome and position.\n */\n getGenomeCoordinate(chr, bp) {\n return this.getCumulativeOffset(chr.name) + bp;\n };\n\n getChromosomeForCoordinate(bp) {\n var i = 0,\n offset = 0,\n l;\n\n for (i = 1; i < this.chromosomes.length; i++) {\n l = this.chromosomes[i].size;\n if (offset + l > bp) return this.chromosomes[i];\n offset += l;\n }\n return this.chromosomes[this.chromosomes.length - 1];\n }\n\n\n /**\n * Return the offset in genome coordinates (kb) of the start of the given chromosome\n */\n getCumulativeOffset(chr) {\n\n const queryChr = this.getChromosomeName(chr);\n\n if (this.cumulativeOffsets === undefined) {\n computeCumulativeOffsets.call(this);\n }\n return this.cumulativeOffsets[queryChr];\n }\n\n // Required for igv.js\n getGenomeLength() {\n return this.genomeLength;\n }\n\n // Required for igv.js\n addFeaturesToDB(featureList, config) {\n\n const insertFeature = (name, feature) => {\n const current = this.featureDB.get(name)\n if (current) {\n feature = (feature.end - feature.start) > (current.end - current.start) ? feature : current\n }\n this.featureDB.set(name, feature)\n }\n\n for (let feature of featureList) {\n if (feature.name) {\n insertFeature(feature.name.toUpperCase(), feature)\n }\n if (feature.gene && feature.gene.name) {\n insertFeature(feature.gene.name.toUpperCase(), feature)\n }\n }\n }\n}\nfunction computeCumulativeOffsets() {\n\n const cumulativeOffsets = {};\n let offset = 0;\n // Skip first chromosome (its chr all).\n for (let chromosome of this.chromosomes) {\n if(chromosome.name === 'all') continue;\n cumulativeOffsets[chromosome.name] = Math.floor(offset);\n offset += (chromosome.size);\n }\n this.cumulativeOffsets = cumulativeOffsets;\n}\n\n\nexport default Genome\n","/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2016-2017 The Regents of the University of California\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and\n * associated documentation files (the \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the\n * following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all copies or substantial\n * portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING\n * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n *\n */\n\n\n/**\n * @author Jim Robinson\n */\n\nimport { defaultSize } from './createBrowser.js'\nimport {DEFAULT_PIXEL_SIZE, MAX_PIXEL_SIZE} from \"./hicBrowser.js\"\n\nclass State {\n\n constructor(chr1, chr2, locus, zoom, x, y, pixelSize, normalization) {\n if (chr1 <= chr2) {\n this.chr1 = chr1;\n this['x'] = x;\n\n this.chr2 = chr2;\n this['y'] = y;\n } else {\n // Transpose\n this.chr1 = chr2;\n this['x'] = y;\n\n this.chr2 = chr1;\n this['y'] = x;\n }\n\n this.zoom = zoom;\n\n if (undefined === normalization) {\n console.warn(\"Normalization is undefined. Will use NONE\");\n normalization = 'NONE';\n }\n this.normalization = normalization;\n\n if (Number.isNaN(pixelSize)) {\n pixelSize = 1\n }\n this.pixelSize = pixelSize;\n\n this.locus = locus\n }\n\n // Getters and setters for width and height\n // get width() {\n // return this._width;\n // }\n //\n // set width(value) {\n // this._width = value;\n // }\n //\n // get height() {\n // return this._height;\n // }\n //\n // set height(value) {\n // this._height = value;\n // }\n\n clampXY(dataset, viewDimensions) {\n const { width, height } = viewDimensions\n const { chromosomes, bpResolutions } = dataset;\n\n const binSize = bpResolutions[this.zoom];\n const maxX = Math.max(0, chromosomes[this.chr1].size / binSize - width / this.pixelSize);\n const maxY = Math.max(0, chromosomes[this.chr2].size / binSize - height / this.pixelSize);\n\n this.x = Math.min(Math.max(0, this.x), maxX);\n this.y = Math.min(Math.max(0, this.y), maxY);\n }\n\n async panWithZoom(zoom, pixelSize, anchorPx, anchorPy, binSize, browser, dataset, viewDimensions, bpResolutions){\n\n const minPixelSize = await browser.minPixelSize(this.chr1, this.chr2, zoom)\n pixelSize = Math.max(pixelSize, minPixelSize)\n\n // Genomic anchor -- this position should remain at anchorPx, anchorPy after state change\n bpResolutions[this.zoom]\n const gx = (this.x + anchorPx / this.pixelSize) * bpResolutions[this.zoom].binSize\n const gy = (this.y + anchorPy / this.pixelSize) * bpResolutions[this.zoom].binSize\n\n this.x = gx / binSize - anchorPx / pixelSize\n this.y = gy / binSize - anchorPy / pixelSize\n\n this.zoom = zoom\n this.pixelSize = pixelSize\n\n this.clampXY(dataset, viewDimensions)\n\n }\n\n panShift(dx, dy, browser, dataset, viewDimensions) {\n\n this.x += (dx / this.pixelSize)\n this.y += (dy / this.pixelSize)\n this.clampXY(dataset, viewDimensions)\n\n this.configureLocus(browser, dataset, viewDimensions)\n\n }\n\n async setWithZoom(zoom, viewDimensions, browser, dataset){\n\n const {width, height} = viewDimensions\n\n // bin = bin + pixel * bin/pixel = bin\n const xCenter = this.x + (width/2) / this.pixelSize\n const yCenter = this.y + (height/2) / this.pixelSize\n\n const binSize = dataset.bpResolutions[this.zoom]\n const binSizeNew = dataset.bpResolutions[zoom]\n\n const scaleFactor = binSize / binSizeNew\n\n const xCenterNew = xCenter * scaleFactor\n const yCenterNew = yCenter * scaleFactor\n\n const minPixelSize = await browser.minPixelSize(this.chr1, this.chr2, zoom)\n\n this.pixelSize = Math.max(DEFAULT_PIXEL_SIZE, minPixelSize)\n\n const resolutionChanged = (this.zoom !== zoom)\n\n this.zoom = zoom\n this.x = Math.max(0, xCenterNew - width / (2 * this.pixelSize))\n this.y = Math.max(0, yCenterNew - height / (2 * this.pixelSize))\n\n this.clampXY(dataset, viewDimensions)\n\n this.configureLocus(browser, dataset, viewDimensions)\n\n return resolutionChanged\n }\n\n configureLocus(browser, dataset, viewDimensions){\n\n const bpPerBin = dataset.bpResolutions[this.zoom];\n\n const startBP1 = Math.round(this.x * bpPerBin);\n const startBP2 = Math.round(this.y * bpPerBin);\n\n const chr1 = dataset.chromosomes[this.chr1];\n const chr2 = dataset.chromosomes[this.chr2];\n const pixelsPerBin = this.pixelSize;\n const endBP1 = Math.min(chr1.size, Math.round(((viewDimensions.width / pixelsPerBin) * bpPerBin)) + startBP1);\n const endBP2 = Math.min(chr2.size, Math.round(((viewDimensions.height / pixelsPerBin) * bpPerBin)) + startBP2);\n\n const x = { chr:chr1.name, start:startBP1, end:endBP1 }\n const y = { chr:chr2.name, start:startBP2, end:endBP2 }\n\n this.locus = { x, y }\n }\n\n updateWithLoci(chr1Name, bpX, bpXMax, chr2Name, bpY, bpYMax, browser, width, height){\n\n const bpResolutions = browser.getResolutions()\n\n // bp/pixel\n let bpPerPixelTarget = Math.max((bpXMax - bpX) / width, (bpYMax - bpY) / height)\n let resolutionChanged\n let zoomNew\n if (true === browser.resolutionLocked) {\n resolutionChanged = false\n zoomNew = this.zoom\n } else {\n zoomNew = browser.findMatchingZoomIndex(bpPerPixelTarget, bpResolutions)\n resolutionChanged = (zoomNew !== this.zoom)\n }\n\n const { binSize:binSizeNew } = bpResolutions[zoomNew]\n const pixelSize = Math.min(MAX_PIXEL_SIZE, Math.max(1, binSizeNew / bpPerPixelTarget))\n const newXBin = bpX / binSizeNew\n const newYBin = bpY / binSizeNew\n\n const { index:chr1Index } = browser.genome.getChromosome( chr1Name )\n const { index:chr2Index } = browser.genome.getChromosome( chr2Name )\n\n const chrChanged = this.chr1 !== chr1Index || this.chr2 !== chr2Index\n\n this.chr1 = chr1Index\n this.chr2 = chr2Index\n this.zoom = zoomNew\n this.x = newXBin\n this.y = newYBin\n this.pixelSize = pixelSize\n this.locus =\n {\n x: { chr: chr1Name, start: bpX, end: bpXMax },\n y: { chr: chr2Name, start: bpY, end: bpYMax }\n };\n\n return { chrChanged, resolutionChanged }\n }\n\n sync(targetState, browser, genome, dataset){\n\n const chr1 = genome.getChromosome(targetState.chr1Name)\n const chr2 = genome.getChromosome(targetState.chr2Name)\n\n const bpPerPixelTarget = targetState.binSize/targetState.pixelSize\n\n const zoomNew = browser.findMatchingZoomIndex(bpPerPixelTarget, dataset.bpResolutions)\n const binSizeNew = dataset.bpResolutions[ zoomNew ]\n const pixelSizeNew = Math.min(MAX_PIXEL_SIZE, Math.max(1, binSizeNew / bpPerPixelTarget))\n\n const xBinNew = targetState.binX * (targetState.binSize/binSizeNew)\n const yBinNew = targetState.binY * (targetState.binSize/binSizeNew)\n\n const zoomChanged = (browser.state.zoom !== zoomNew)\n const chrChanged = (browser.state.chr1 !== chr1.index || browser.state.chr2 !== chr2.index)\n\n this.chr1 = chr1.index\n this.chr2 = chr2.index\n this.zoom = zoomNew\n this.x = xBinNew\n this.y = yBinNew\n this.pixelSize = pixelSizeNew\n\n this.configureLocus(browser, dataset, browser.contactMatrixView.getViewDimensions())\n\n return { zoomChanged, chrChanged }\n\n }\n\n stringify() {\n if (this.normalization) {\n return `${this.chr1},${this.chr2},${this.zoom},${this.x},${this.y},0,0,${this.pixelSize},${this.normalization}`\n } else {\n return `${this.chr1},${this.chr2},${this.zoom},${this.x},${this.y},0,0,${this.pixelSize}`\n }\n }\n\n clone() {\n return Object.assign(new State(), this);\n }\n\n equals(state) {\n const s1 = JSON.stringify(this);\n const s2 = JSON.stringify(state);\n return s1 === s2;\n }\n\n async sizeBP(dataset, zoomIndex, pixels){\n const matrix = await dataset.getMatrix(this.chr1, this.chr2)\n const { zoom } = matrix.getZoomDataByIndex(zoomIndex, 'BP')\n\n // bp = pixel * (bp/bin) * (bin/pixel) = pixel * bp/pixel = bp\n return pixels * (zoom.binSize/this.pixelSize)\n }\n\n static parse(string) {\n const tokens = string.split(\",\")\n\n if (tokens.length <= 7) {\n // Backwards compatibility\n return new State(\n parseInt(tokens[0]), // chr1\n parseInt(tokens[1]), // chr2\n undefined, // locus\n parseFloat(tokens[2]), // zoom\n parseFloat(tokens[3]), // x\n parseFloat(tokens[4]), // y\n parseFloat(tokens[5]), // pixelSize\n tokens.length > 6 ? tokens[6] : \"NONE\" // normalization\n )\n } else {\n return new State(\n parseInt(tokens[0]), // chr1\n parseInt(tokens[1]), // chr2\n undefined, // locus\n parseFloat(tokens[2]), // zoom\n parseFloat(tokens[3]), // x\n parseFloat(tokens[4]), // y\n parseFloat(tokens[7]), // pixelSize\n tokens.length > 8 ? tokens[8] : \"NONE\" // normalization\n )\n }\n }\n\n // Method 1: Convert the State object to a JSON object\n toJSON() {\n const json =\n {\n chr1: this.chr1,\n chr2: this.chr2,\n zoom: this.zoom,\n x: this.x,\n y: this.y,\n pixelSize: this.pixelSize,\n normalization: this.normalization || 'NONE'\n }\n\n if (this.locus) {\n json.locus = this.locus\n }\n\n return json\n }\n\n // Method 2: Parse a JSON object and create an instance of the State class\n static fromJSON(json) {\n return new State(\n json.chr1,\n json.chr2,\n json.locus,\n json.zoom,\n json.x,\n json.y,\n json.pixelSize,\n json.normalization\n );\n }\n\n static default(configOrUndefined) {\n const state = new State(0, 0, undefined, 0, 0, 1, \"NONE\")\n return state\n }\n\n}\n\nexport default State\n","/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2016-2017 The Regents of the University of California\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and\n * associated documentation files (the \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the\n * following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all copies or substantial\n * portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING\n * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n *\n */\n\n\n/**\n * @author Jim Robinson\n */\n\nimport {igvxhr, StringUtils} from '../node_modules/igv-utils/src/index.js'\n\nasync function geneSearch(genomeId, featureName) {\n const searchServiceURL = `https://portals.broadinstitute.org/webservices/igv/locus?genome=${genomeId}&name=${encodeURIComponent(featureName)}`;\n\n try {\n const data = await igvxhr.loadString(searchServiceURL);\n const results = parseSearchResults(data);\n\n return results.length ? results[0] : undefined;\n } catch (error) {\n console.error(`Error fetching gene data for \"${featureName}\":`, error);\n return undefined;\n }\n}\n\n\nfunction parseSearchResults(data) {\n const parsed = StringUtils.splitLines(data)\n .filter(line => line.trim() !== '').map(line => line.split('\\t'))\n .filter(tokens => tokens.length >= 3).map(tokens => tokens[1])\n\n return parsed\n}\n\nexport { geneSearch }\n","// Contains \"normalization vector index\" (nvi values) for legacy (v8) hosted files from aidenlab, ENCODE, and 4DN.\n// These values can speed up initialization by a few seconds.\nexport default {\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2Fcombined.hic\": \"54386046426,55860\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2Fprimary.hic\": \"33860030033,37504\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2Freplicate.hic\": \"30849652794,55832\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2Fmaternal.hic\": \"1380542661,17185\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2Fpaternal.hic\": \"1389001777,17185\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fimr90%2Fin-situ%2Fcombined.hic\": \"13433880319,35723\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC001.hic\": \"3409347253,35975\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC002.hic\": \"4529947083,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC003.hic\": \"6894962500,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC004.hic\": \"3395593338,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC005.hic\": \"5204128636,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC006.hic\": \"3278363811,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC007.hic\": \"3585547340,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC008.hic\": \"4134197273,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC009.hic\": \"2851728310,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC010.hic\": \"1754216102,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC011.hic\": \"1716829574,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC012.hic\": \"4367980375,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC013.hic\": \"2309654671,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC014.hic\": \"5324950266,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC015.hic\": \"3132333594,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC016.hic\": \"3159154704,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC017.hic\": \"3262554627,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC018.hic\": \"3014216364,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC019.hic\": \"5025753246,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC020.hic\": \"5861584507,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC021.hic\": \"3542263275,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC022.hic\": \"5061949378,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC023.hic\": \"4816423919,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC024.hic\": \"2683781104,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC025.hic\": \"6522701781,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC026.hic\": \"6748846520,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC027.hic\": \"5642693007,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC028.hic\": \"2098921691,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC029.hic\": \"3886454027,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fagar%2FHIC030.hic\": \"2288984204,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fagar%2FHIC031.hic\": \"2115342419,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fpellet%2FHIC032.hic\": \"2063314324,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fsupernatant%2FHIC033.hic\": \"1933908457,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fdilution%2FHIC034.hic\": \"13555514595,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fdilution%2FHIC035.hic\": \"6129650900,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fdilution%2FHIC036.hic\": \"4307445019,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fdilution%2FHIC037.hic\": \"9375139867,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fdilution%2Fcombined.hic\": \"11664249584,33929\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2Fcombined_DpnII.hic\": \"7003537290,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC038.hic\": \"2099825544,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC039.hic\": \"2096900138,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC040.hic\": \"2593642141,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC041.hic\": \"2263919098,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC042.hic\": \"2684774693,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2Fcombined_noXlink.hic\": \"5574807456,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC043.hic\": \"2986114347,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC044.hic\": \"1916378621,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC045.hic\": \"746463126,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC046.hic\": \"2338476164,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC047.hic\": \"1167496250,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC048.hic\": \"2231690794,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fin-situ%2FHIC049.hic\": \"2782308678,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fimr90%2Fin-situ%2FHIC050.hic\": \"3633531346,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fimr90%2Fin-situ%2FHIC051.hic\": \"4063486444,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fimr90%2Fin-situ%2FHIC052.hic\": \"929756278,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fimr90%2Fin-situ%2FHIC053.hic\": \"2489657204,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fimr90%2Fin-situ%2FHIC054.hic\": \"4036419444,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fimr90%2Fin-situ%2FHIC055.hic\": \"4284185549,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fimr90%2Fin-situ%2FHIC056.hic\": \"4410546240,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fimr90%2Fdilution%2FHIC057.hic\": \"1491998259,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fhmec%2Fin-situ%2Fcombined.hic\": \"7266425111,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fhmec%2Fin-situ%2FHIC058.hic\": \"6532635593,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fhmec%2Fin-situ%2FHIC059.hic\": \"400684530,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fhmec%2Fin-situ%2FHIC060.hic\": \"645352187,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fhmec%2Fin-situ%2FHIC061.hic\": \"736291871,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fhmec%2Fin-situ%2FHIC062.hic\": \"762731037,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fhmec%2Fin-situ%2FHIC063.hic\": \"682917431,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fhmec%2Fdilution%2FHIC064.hic\": \"4550171307,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fnhek%2Fin-situ%2Fcombined.hic\": \"11897184911,35789\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fnhek%2Fin-situ%2FHIC065.hic\": \"5425943567,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fnhek%2Fin-situ%2FHIC066.hic\": \"5942869818,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fnhek%2Fin-situ%2FHIC067.hic\": \"5191049261,35647\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fnhek%2Fdilution%2FHIC068.hic\": \"2713318801,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fk562%2Fin-situ%2Fcombined.hic\": \"12641555389,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fk562%2Fin-situ%2FHIC069.hic\": \"5630177461,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fk562%2Fin-situ%2FHIC070.hic\": \"5926611269,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fk562%2Fin-situ%2FHIC071.hic\": \"2486191351,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fk562%2Fin-situ%2FHIC072.hic\": \"2281343366,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fk562%2Fin-situ%2FHIC073.hic\": \"2173074239,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fk562%2Fin-situ%2FHIC074.hic\": \"2463700999,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fkbm7%2Fin-situ%2Fcombined.hic\": \"14661922519,35639\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fkbm7%2Fin-situ%2FHIC075.hic\": \"3685310515,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fkbm7%2Fin-situ%2FHIC076.hic\": \"5833658487,35891\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fkbm7%2Fin-situ%2FHIC077.hic\": \"2406346486,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fkbm7%2Fin-situ%2FHIC078.hic\": \"5241454987,35919\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fkbm7%2Fin-situ%2FHIC079.hic\": \"6297234263,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fhuvec%2Fin-situ%2Fcombined.hic\": \"9193858096,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fhuvec%2Fin-situ%2FHIC080.hic\": \"5171405536,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fhuvec%2Fin-situ%2FHIC081.hic\": \"3489767688,35891\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fhuvec%2Fin-situ%2FHIC082.hic\": \"4243339375,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fhuvec%2Fdilution%2FHIC083.hic\": \"1497495406,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fhela%2Fin-situ%2Fcombined.hic\": \"7923332224,35593\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fhela%2Fin-situ%2FHIC084.hic\": \"867699123,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fhela%2Fin-situ%2FHIC085.hic\": \"3669518514,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fhela%2Fin-situ%2FHIC086.hic\": \"5306474712,35595\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fhela%2Fin-situ%2FHIC087.hic\": \"1490963755,36397\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2Fcombined.hic\": \"8956382853,50248\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2FHIC088.hic\": \"1874185366,32102\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2FHIC089.hic\": \"1301165236,32102\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2FHIC090.hic\": \"1105246282,32102\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2FHIC091.hic\": \"1338325770,32102\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2FHIC092.hic\": \"1307918730,32102\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2FHIC093.hic\": \"755136918,32102\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2FHIC094.hic\": \"1606583694,32102\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2FHIC095.hic\": \"2039711245,32102\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2FHIC096.hic\": \"1909573053,32102\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2FHIC097.hic\": \"1826710712,32102\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2FHIC098.hic\": \"1998793575,32102\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2FHIC099.hic\": \"1007740962,32102\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2FHIC100.hic\": \"736464120,32102\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2FHIC101.hic\": \"980505082,32102\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fin-situ%2FHIC102.hic\": \"1116083646,32102\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fdilution%2FHIC103.hic\": \"1096994310,32102\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fch12-lx-b-lymphoblasts%2Fdilution%2FHIC104.hic\": \"841063882,32102\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC105.hic\": \"107742864,36479\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC106.hic\": \"134295912,36479\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC107.hic\": \"110228014,36479\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC108.hic\": \"102761401,36479\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC109.hic\": \"100461491,36479\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC110.hic\": \"88828472,36479\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC111.hic\": \"81471064,36479\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC112.hic\": \"92297035,36479\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC113.hic\": \"65503916,36479\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC114.hic\": \"49181188,36479\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC115.hic\": \"46471102,36479\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC116.hic\": \"64284432,36479\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC117.hic\": \"60434076,36479\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC118.hic\": \"45248563,36479\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC119.hic\": \"60288782,36479\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC120.hic\": \"136888414,36479\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC121.hic\": \"125009003,33681\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC122.hic\": \"154011688,34127\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC123.hic\": \"177663372,35293\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC124.hic\": \"382186226,35245\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC125.hic\": \"158160717,35271\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC127.hic\": \"110261177,34659\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC128.hic\": \"246131875,35509\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC129.hic\": \"260160119,35667\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC130.hic\": \"117479562,34681\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC131.hic\": \"81508929,34673\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC132.hic\": \"105959102,34895\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC133.hic\": \"91504812,33451\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC134.hic\": \"52222546,33737\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC135.hic\": \"57763085,34159\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC136.hic\": \"50618489,33731\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC137.hic\": \"193163606,33363\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC138.hic\": \"229876152,33777\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC139.hic\": \"201783666,33571\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC140.hic\": \"281163862,34125\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC141.hic\": \"275969727,33935\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC142.hic\": \"275020431,34125\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC144.hic\": \"223834810,34177\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC145.hic\": \"296632653,33937\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC146.hic\": \"290945216,33961\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC147.hic\": \"234459964,34231\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC148.hic\": \"295457850,34039\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC149.hic\": \"113569632,35695\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC150.hic\": \"304381897,33963\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC151.hic\": \"289314545,33805\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC152.hic\": \"284320182,33803\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC153.hic\": \"401393947,34659\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC154.hic\": \"188065488,36479\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC155.hic\": \"299157119,33967\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC156.hic\": \"279289244,33787\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC157.hic\": \"254852119,33917\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC158.hic\": \"195969660,33477\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC159.hic\": \"185720388,36479\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC160.hic\": \"227709279,33599\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC161.hic\": \"157225076,33209\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC162.hic\": \"105703444,32033\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC163.hic\": \"122665658,32121\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC164.hic\": \"228048231,33761\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC165.hic\": \"114440819,32011\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC166.hic\": \"285147558,33891\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC167.hic\": \"363116754,33943\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC168.hic\": \"119592158,31937\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC169.hic\": \"236853872,33785\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC170.hic\": \"195187639,33395\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC171.hic\": \"208044058,33309\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC172.hic\": \"144645916,32877\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC173.hic\": \"119115941,32203\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC175.hic\": \"178030481,33525\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC176.hic\": \"117220136,32169\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC177.hic\": \"128586196,32659\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC178.hic\": \"191419141,33629\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC179.hic\": \"141556748,32959\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC180.hic\": \"199825102,33185\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC181.hic\": \"301022688,33783\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC182.hic\": \"185384453,33205\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC183.hic\": \"202189264,36367\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC184.hic\": \"37464475,36479\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC185.hic\": \"161938278,36099\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC186.hic\": \"133853166,36179\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC188.hic\": \"128068030,36237\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC189.hic\": \"148053886,36177\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC190.hic\": \"198946958,35803\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC191.hic\": \"226584564,36063\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC192.hic\": \"194412797,36341\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC193.hic\": \"176408194,36479\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC194.hic\": \"207215649,36055\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC195.hic\": \"175185530,36315\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC196.hic\": \"168969337,36479\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC197.hic\": \"121231252,36339\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC198.hic\": \"92713752,36479\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC199.hic\": \"105130500,36479\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC200.hic\": \"114526350,36479\",\n \"hicfiles.s3.amazonaws.com%2Fmiseq%2Frh2014%2FHIC201.hic\": \"122689717,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fhap1%2Fin-situ%2Fcombined.hic\": \"9614983328,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fexternal%2Fctbp_8_4_17%2Fall_intra_megabase_michrom.hic\": \"154205644,10960\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2Fdel-Xa-combined.hic\": \"8843305329,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FdelXa-chrX-diploid.hic\": \"11173520,1498\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FWT-combined.hic\": \"13365182403,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FWT-chrX-diploid.hic\": \"17343459,1498\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FHIC002.hic\": \"4279298739,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FHIC003.hic\": \"3027365532,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FHIC004.hic\": \"2896130835,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FHIC005.hic\": \"4717830071,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FHIC006.hic\": \"5066210154,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FHIC007.hic\": \"3069516128,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2Fdel-Xi-combined.hic\": \"14551096423,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FdelXi-chrX-diploid.hic\": \"17362477,1498\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FHIC008.hic\": \"2572386655,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FHIC009.hic\": \"2935931663,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FHIC010.hic\": \"2019085070,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FHIC011.hic\": \"6087610814,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FHIC012.hic\": \"2809618194,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Frpe1%2FDarrowHuntley-2015%2FHIC013.hic\": \"2572386655,36479\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fpatski%2FDarrowHuntley-2015%2Fcombined.hic\": \"6950423609,32102\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fpatski%2FDarrowHuntley-2015%2Fpaternal.hic\": \"220592749,15691\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fpatski%2FDarrowHuntley-2015%2Fmaternal.hic\": \"323233095,15691\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fpatski%2FDarrowHuntley-2015%2FHIC014.hic\": \"3183235800,32102\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fpatski%2FDarrowHuntley-2015%2FHIC015.hic\": \"1739539801,32102\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fpatski%2FDarrowHuntley-2015%2FHIC016.hic\": \"1105912758,32102\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fpatski%2FDarrowHuntley-2015%2FHIC017.hic\": \"1060773319,32102\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fpatski%2FDarrowHuntley-2015%2FHIC018.hic\": \"1203679874,32102\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fpatski%2FDarrowHuntley-2015%2FHIC019.hic\": \"3321955269,32102\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Frhesus%2FDarrowHuntley-2015%2FHIC020.hic\": \"7108980626,32102\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fgm12878%2Fcola%2FDarrowHuntley-2015%2FHIC021.hic\": \"3906448676,34955\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fassembly%2Faedes%2Fcombined.hic\": \"390780490,2245\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fassembly%2Fhs2-hic.hic\": \"1960284186,33561\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2Fassembly%2FCpipJ3.hic\": \"766279097,4381\",\n \"s3.amazonaws.com%2Fhicfiles%2Fexternal%2Fphanstiel%2Fupdated_O%2FSnyder_O.hic\": \"8046980555,18679\",\n \"s3.amazonaws.com%2Fhicfiles%2Fexternal%2Fphanstiel%2FA_inter.hic\": \"10986005145,18679\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Funtreated%2Funsynchronized%2Fcombined.hic\": \"30439217680,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftreated_6hr%2Funsynchronized%2Fcombined.hic\": \"33255540403,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2Fdeep%2F20min_withdraw_combined.hic\": \"11078436933,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2Fdeep%2F40min_withdraw_combined.hic\": \"11031830038,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2Fdeep%2F60min_withdraw_combined.hic\": \"10312725340,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2Fdeep%2F180min_withdraw_combined.hic\": \"10038610214,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Funtreated%2Funsynchronized%2FHIC001.hic\": \"8004335785,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Funtreated%2Funsynchronized%2FHIC002.hic\": \"8453215933,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Funtreated%2Funsynchronized%2FHIC003.hic\": \"9118406189,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Funtreated%2Funsynchronized%2FHIC004.hic\": \"5973342894,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Funtreated%2Funsynchronized%2FHIC005.hic\": \"6846576837,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Funtreated%2Funsynchronized%2FHIC006.hic\": \"6075148017,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Funtreated%2Funsynchronized%2FHIC007.hic\": \"8192366992,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftreated_6hr%2Funsynchronized%2FHIC008.hic\": \"6844159653,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftreated_6hr%2Funsynchronized%2FHIC009.hic\": \"7282063059,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftreated_6hr%2Funsynchronized%2FHIC010.hic\": \"10410578833,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftreated_6hr%2Funsynchronized%2FHIC011.hic\": \"8192366992,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftreated_6hr%2Funsynchronized%2FHIC012.hic\": \"7223422850,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftreated_6hr%2Funsynchronized%2FHIC013.hic\": \"7435986997,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftreated_6hr%2Funsynchronized%2FHIC014.hic\": \"9120113605,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Funtreated%2Fsynchronized%2Fcombined.hic\": \"4170577904,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Funtreated%2Fsynchronized%2FHIC015.hic\": \"1504084990,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Funtreated%2Fsynchronized%2FHIC016.hic\": \"1686244500,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Funtreated%2Fsynchronized%2FHIC017.hic\": \"1804802410,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Funtreated%2Fsynchronized%2FHIC018.hic\": \"1533942067,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftreated_6hr%2Fsynchronized%2Fcombined.hic\": \"4572390198,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftreated_6hr%2Fsynchronized%2FHIC019.hic\": \"1543609666,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftreated_6hr%2Fsynchronized%2FHIC020.hic\": \"1814133288,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftreated_6hr%2Fsynchronized%2FHIC021.hic\": \"1942698243,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftreated_6hr%2Fsynchronized%2FHIC022.hic\": \"1873587413,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2Funtreated%2FRao-2017-HIC049.hic\": \"405127557,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2Funtreated%2FRao-2017-HIC060.hic\": \"326681741,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2Funtreated%2FRao-2017-HIC061.hic\": \"300908673,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_20min%2FRao-2017-HIC050.hic\": \"481758242,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_20min%2FRao-2017-HIC051.hic\": \"417577401,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_40min%2FRao-2017-HIC052.hic\": \"419353227,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_40min%2FRao-2017-HIC053.hic\": \"411554953,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_60min%2FRao-2017-HIC054.hic\": \"386655891,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_60min%2FRao-2017-HIC055.hic\": \"402170701,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_240min%2FRao-2017-HIC057.hic\": \"735906308,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min%2FRao-2017-HIC058.hic\": \"443789827,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min%2FRao-2017-HIC059.hic\": \"491422615,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min%2FRao-2017-HIC062.hic\": \"320261375,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min%2FRao-2017-HIC063.hic\": \"306590499,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min_withdraw_20min%2FRao-2017-HIC032S.hic\": \"367051742,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min_withdraw_20min%2FRao-2017-HIC033S.hic\": \"344555339,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min_withdraw_40min%2FRao-2017-HIC036S.hic\": \"349392947,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min_withdraw_40min%2FRao-2017-HIC037S.hic\": \"317714554,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min_withdraw_60min%2FRao-2017-HIC040S.hic\": \"266786397,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min_withdraw_60min%2FRao-2017-HIC041S.hic\": \"279445530,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min_withdraw_180min%2FRao-2017-HIC044S.hic\": \"898418269,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min_withdraw_180min%2FRao-2017-HIC045S.hic\": \"961006347,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min_withdraw_360min%2FRao-2017-HIC064.hic\": \"833576408,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min_withdraw_360min%2FRao-2017-HIC065.hic\": \"840881418,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min_withdraw_1080min%2FRao-2017-HIC066.hic\": \"980958864,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min_withdraw_1080min%2FRao-2017-HIC067.hic\": \"882023129,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min_withdraw_1440min%2FRao-2017-HIC068.hic\": \"1110292630,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fdegron%2Ftime_course%2FAuxin_treated_360min_withdraw_1440min%2FRao-2017-HIC069.hic\": \"1001747023,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fexternal%2Frowley_nichols_mol_cell_2017%2FCP190_HiChIP.hic\": \"144107588,6976\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fexternal%2Frowley_nichols_mol_cell_2017%2FH3K27ac_HiChIP_combined.hic\": \"43171370,5233\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fexternal%2Frowley_nichols_mol_cell_2017%2FH3K27me3_HiChIP_combined.hic\": \"42906472,5233\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fexternal%2Frowley_nichols_mol_cell_2017%2FPol2_ChIAPET.hic\": \"41992430,6976\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fexternal%2Frowley_nichols_mol_cell_2017%2FPol2S2_HiChIP.hic\": \"145842743,6976\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fexternal%2Frowley_nichols_mol_cell_2017%2FArabidopsis_Wang2015_Liu2016.hic\": \"1134391078,4984\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fexternal%2Frowley_nichols_mol_cell_2017%2FElegans_Crane2015.hic\": \"387127568,8758\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fexternal%2Frowley_nichols_mol_cell_2017%2FNcrassa_Galazka2016.hic\": \"26555511,27725\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fexternal%2Frowley_nichols_mol_cell_2017%2FPfalciparum_trophozoite_Ay2014.hic\": \"15640893,13948\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fduan%2FE-Me-A.hic\": \"6897251,23348\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fduan%2FE-Me-B.hic\": \"4959088,23348\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fduan%2FE-Mp-A.hic\": \"5232286,23348\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fduan%2FE-Mp-B.hic\": \"5105292,23348\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fduan%2FH-Me-A.hic\": \"6900072,23348\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fduan%2FH-Me-B.hic\": \"8653258,23348\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fduan%2FH-Mp-A.hic\": \"7999058,23348\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fduan%2FH-Mp-B.hic\": \"8774657,23348\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fdekker%2F4dn%2Fh1hesc.hic\": \"23671753603,36479\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fdekker%2F4dn%2Fh1hesc_rep1.hic\": \"23671754721,36479\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fdekker%2F4dn%2Fh1hesc_rep2.hic\": \"22269909910,36479\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fdekker%2F4dn%2Fhffc6_rep1.hic\": \"19016661622,36479\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Flieberman_aiden_van_berkum%2FGM06990_NcoI.hic\": \"480725203,36479\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Flieberman_aiden_van_berkum%2F302NH.hic\": \"99948617,36479\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Flieberman_aiden_van_berkum%2FK562.hic\": \"470263605,36151\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Flieberman_aiden_van_berkum%2FGM06990_HindIII.hic\": \"293706559,36289\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Flieberman_aiden_van_berkum%2FGM06990_rep_HindIII.hic\": \"309673862,36087\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Frudan%2Fcanis-lupus-rep1.hic\": \"1531151371,56905\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Frudan%2Fcanis-lupus-rep2.hic\": \"2851437676,56905\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Frudan%2Fmouse-rep1.hic\": \"582052544,32102\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Frudan%2Fmacaque-rep1.hic\": \"698509182,32102\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Frudan%2Fmacaque-rep2.hic\": \"461410393,32102\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Frudan%2Frabbit-rep1.hic\": \"691045338,33561\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Frudan%2Frabbit-rep2.hic\": \"668888336,33561\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fsexton%2Fcombined.hic\": \"50650087,4486\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fkalhor%2Ftcc-hindiii.hic\": \"1071142023,16500\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fkalhor%2Ftcc-mboi.hic\": \"1508851093,16448\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fkalhor%2Fnon-tcc-hindiii.hic\": \"395179229,36093\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fkalhor%2Ftcc-combined.hic\": \"1050423847,36479\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fdixon%2Fmm9-hindiii%2Fsplit-read-run.hic\": \"9599984876,32102\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fdixon%2Fhesc-hindiii.hic\": \"1952555632,36479\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fdixon%2Fimr90-hindiii.hic\": \"9691260435,18679\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fdixon%2Fmm9-cortex.hic\": \"3712072953,32102\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fzhang%2Fatm-i-scei-chr18.hic\": \"2083350075,16438\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fzhang%2Fatm-i-scei-chr2.hic\": \"3362049644,16360\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fzhang%2Fatm-i-scei-chr7.hic\": \"1658399854,16438\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fzhang%2Fwt-i-scei-chr15.hic\": \"866691249,16438\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fzhang%2Fwt-i-scei-chr2.hic\": \"3304782795,16386\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fnagano%2Fcell-1.hic\": \"23673506,32102\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fnagano%2Fcell-2.hic\": \"26873280,30643\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fnagano%2Fcell-3.hic\": \"31066362,30643\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fnagano%2Fcell-4.hic\": \"16807724,30643\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fnagano%2Fcell-5.hic\": \"28665065,30643\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fnagano%2Fcell-6.hic\": \"13124158,30643\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fnagano%2Fcell-7.hic\": \"15118945,30643\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fnagano%2Fcell-8.hic\": \"68316814,32102\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fnagano%2Fcell-9.hic\": \"18965101,30643\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fnagano%2Fcell-10.hic\": \"17020666,30643\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fjin%2Fimr90%2Fcombined.hic\": \"6526601242,36427\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fjin%2Fimr90%2Frep1.hic\": \"1861562891,36401\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fjin%2Fimr90%2Frep2.hic\": \"3061013635,36479\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fjin%2Fimr90%2Frep3.hic\": \"1564588211,35969\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fjin%2Fimr90%2Frep4.hic\": \"1255543175,36153\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fjin%2Fimr90%2Frep5.hic\": \"974683253,36179\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fjin%2Fimr90%2Frep6.hic\": \"1040805629,36053\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fjin%2Fimr90-tnf-alpha%2Fcombined.hic\": \"8424080116,36401\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fjin%2Fimr90-tnf-alpha%2Frep1.hic\": \"2697976702,36295\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fjin%2Fimr90-tnf-alpha%2Frep3.hic\": \"1718610467,36159\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fjin%2Fimr90-tnf-alpha%2Frep4.hic\": \"2029519405,36101\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fjin%2Fimr90-tnf-alpha%2Frep5.hic\": \"985310855,36069\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fjin%2Fimr90-tnf-alpha%2Frep6.hic\": \"1418750480,35967\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fcheng%2Fmhh-call-4-cell-line.hic\": \"538380253,35351\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fcheng%2Fprimary-b-all.hic\": \"773764191,35793\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fcheng%2Fnormal-b-cell-line.hic\": \"336271459,35005\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fcheng%2Frl-cell-line.hic\": \"484807998,35351\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fhou%2Fkc167-biorep.hic\": \"135932435,8758\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fhou%2Fkc167-techrep1.hic\": \"160355961,8758\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fhou%2Fkc167-techrep2.hic\": \"188809887,8758\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Flin%2Fpre-prob-egs.hic\": \"2237792858,15483\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Flin%2Fprob-egs.hic\": \"5744720377,16438\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Flin%2Fprob-fa.hic\": \"2174866215,16438\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fli%2Fhct116-rnapii-pilot.hic\": \"396366166,35999\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fli%2Fhela-rnapii-pilot.hic\": \"882516759,35107\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fli%2Fk562-rnapii-pilot.hic\": \"1131576189,35969\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fli%2Fk562-rnapii-saturated.hic\": \"571583828,36291\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fli%2Fmcf7-rnapii-saturated.hic\": \"1282547841,36035\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fli%2Fnb4-rnapii-pilot.hic\": \"761614686,34861\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fjung%2Fmouse_sperm.hic\": \"1730231642,29184\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Ftang%2Fgm12878.hic\": \"1953518212,20505\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Frutledge%2FSRR1791299.hic\": \"5723484,11956\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Frutledge%2FSRR1791297.hic\": \"16534743,23348\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fzuin%2Fhek293t-rad21cv-hrv.hic\": \"5094525579,36289\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fzuin%2Fhek293t-rad21cv-hrv-rep1.hic\": \"2574358912,36373\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fzuin%2Fhek293t-rad21cv-hrv-rep2.hic\": \"3417099433,36243\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fzuin%2Fhek293t-rad21cv-tev.hic\": \"4785157552,36323\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fzuin%2Fhek293t-rad21cv-tev-rep1.hic\": \"2648268465,36321\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fzuin%2Fhek293t-rad21cv-tev-rep2.hic\": \"2994727980,36107\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fzuin%2Fhek293t-sirna-ctcf.hic\": \"5391791815,36063\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fzuin%2Fhek293t-sirna-ctcf-rep1.hic\": \"3325842095,36269\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fzuin%2Fhek293t-sirna-ctcf-rep2.hic\": \"3096215920,36167\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fzuin%2Fhek293t-sirna-ctrl.hic\": \"3830902383,36167\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fzuin%2Fhek293t-sirna-ctrl-rep1.hic\": \"1346712252,36079\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fzuin%2Fhek293t-sirna-ctrl_rep2.hic\": \"3098067367,36271\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fay%2Fp-falciparum-3d7-0h-hiseq.hic\": \"38174042,21889\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fay%2Fp-falciparum-3d7-18h-hiseq.hic\": \"26506099,21889\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fay%2Fp-falciparum-3d7-18h-hiseq-non-crosslinked_control.hic\": \"3545496,21889\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fay%2Fp-falciparum-3d7-36h-hiseq.hic\": \"70754194,21889\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fnaumova%2Fhelas3%2Fg1mid-r1.hic\": \"200863476,17185\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fnaumova%2Fhelas3%2Fm-r1.hic\": \"249021190,17185\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fnaumova%2Fhelas3%2Fm-r2.hic\": \"212341157,17185\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fnaumova%2Fhelas3ccl2p2%2Fg1-0-25fa.hic\": \"583572265,17185\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fnaumova%2Fhelas3ccl2p2%2Fg1-1fa.hic\": \"354502306,17185\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fnaumova%2Fhelas3ccl2p2%2Fm-0-25fa.hic\": \"149308791,17185\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fnaumova%2Fhelas3ccl2p2%2Fm-98percent.hic\": \"778175225,17185\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fnaumova%2Fhelas3ccl2p2%2Fm-1fa.hic\": \"158091047,17185\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fnaumova%2Fhff1%2Fcchic-hff1-ns-r1.hic\": \"801670039,17185\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fnaumova%2Fhff1%2Fcchic-hff1-m-r1.hic\": \"875922086,17185\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fnaumova%2Fk562%2Fm-r1.hic\": \"130959943,17185\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fnaumova%2Fk562%2Fm-r2.hic\": \"237861106,17185\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fsofueva%2FmAST-WT.hic\": \"496104039,30643\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fsofueva%2FmAST-WT-adv-cre.hic\": \"438608517,30643\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fsofueva%2FmAST-floxed-rep1.hic\": \"446205712,32102\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fsofueva%2FmAST-floxed-rep2.hic\": \"386354767,32102\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fsofueva%2FmAST-deleted-rep1.hic\": \"621998722,30643\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fsofueva%2FmAST-deleted-rep2.hic\": \"583840829,32102\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fsofueva%2FmNSC-floxed-rep1.hic\": \"801290988,30643\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fsofueva%2FmNSC-floxed-rep2.hic\": \"819406658,30643\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fsofueva%2FmNSC-deleted-rep1.hic\": \"792825269,32102\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fsofueva%2FmNSC-deleted-rep2.hic\": \"746189884,30643\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fsofueva%2FmNSC-WT.hic\": \"309353372,30643\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fsofueva%2FmNSC-WT-OHT.hic\": \"274229679,30643\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fseitan%2FTcell-Rad21KO-R1.hic\": \"1490362251,32102\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fseitan%2FTcell-Rad21KO-R3.hic\": \"2403664421,32102\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fseitan%2FTcell-Rad21WT-R1.hic\": \"1377124538,32102\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fseitan%2FTcell-Rad21WT-R3.hic\": \"2646201369,32102\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fmoissiard%2Fcrh6-mutant.hic\": \"105261071,10217\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fmoissiard%2FWT.hic\": \"127506388,10217\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fgrob%2FCol.hic\": \"153638500,10217\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fgrob%2Fcrwn1.hic\": \"211213220,10217\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fgrob%2Fcrwn4.hic\": \"134236837,10217\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fxie%2Fprimary.hic\": \"92936173,10217\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Ffeng%2F6wt-control6wt337.hic\": \"318737891,10217\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Ffeng%2F6wt-control6wt67.hic\": \"348123956,10217\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Ffeng%2F6wt337.hic\": \"251107279,10217\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Ffeng%2F6wt67.hic\": \"351840994,10217\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Ffeng%2FCol0.hic\": \"345969497,10217\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Ffeng%2Fclf28-swn7.hic\": \"299585025,10217\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Ffeng%2Fcmt3-11.hic\": \"253427706,10217\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Ffeng%2Fddm1-2.hic\": \"303626924,10217\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Ffeng%2Fmet1-3.hic\": \"347697973,10217\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Ffeng%2Fsuvh4-suvh5-suvh6.hic\": \"263122019,10217\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fma%2FDNase-HiC-WG-K562.hic\": \"892955840,18679\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fma%2FDNaseHiC-WG-H1.hic\": \"696922695,18679\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fma%2FtargetedDNaseHiC-lincRNA-K562-rep1.hic\": \"341917716,18679\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fma%2FtargeredDNaseHiC-lincRNA-K562-rep2.hic\": \"214841185,18679\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fma%2FtargetedDNaseHiC-lincRNA-H1-rep1.hic\": \"616326137,18679\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fma%2FtargetedDNaseHiC-lincRNA-H1-rep2.hic\": \"579654013,18679\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fma%2FtargetedDNaseHiC-pe-H1-rep1.hic\": \"519810544,18679\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fma%2FtargetedDNaseHiC-pe-K562-rep1.hic\": \"199553123,18679\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Frowley%2FKc167_DpnII.hic\": \"1319373594,6976\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Frowley%2FKc167_HinfI.hic\": \"1465493873,6976\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Frowley%2FKc167_DpnII_HinfI_combo.hic\": \"753062558,5814\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fbarutcu%2FMCF-10A.hic\": \"2784956115,36479\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fbarutcu%2FMCF-7.hic\": \"2700457411,36479\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fbatullin%2Fsperm.hic\": \"501052169,32102\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fminajigi%2FWT_hiC_rep1.hic\": \"1450697530,32102\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fminajigi%2FWT_hiC_rep2.hic\": \"1189371558,32102\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fminajigi%2Fcombined.hic\": \"2262007875,32102\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fminajigi%2Finactive.hic\": \"4444564,751\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fminajigi%2Factive.hic\": \"3993495,751\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fdeng%2Fpatski_rep1.hic\": \"1650838357,32102\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fdeng%2Fpatski_rep2.hic\": \"1258038606,32102\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fdeng%2Fpatski.hic\": \"499827296,16438\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fdeng%2Fpatski_active.hic\": \"79175714,15691\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fdeng%2Fpatski_inactive.hic\": \"98947881,15691\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fdeng%2Fbrain_dnase.hic\": \"4298088401,32102\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fdeng%2Fbrain_in_situ_dnase.hic\": \"609321852,32102\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fdeng%2Fbrain.hic\": \"1028196506,16438\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fdeng%2Fbrain_active.hic\": \"79175714,15691\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fdeng%2Fbrain_inactive.hic\": \"98947881,15691\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fle%2FBglII_rep1.hic\": \"1283306,1463\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fle%2FBglII_rep2.hic\": \"1263227,1463\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fle%2FNcoI_rep1.hic\": \"4380906,1463\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Feagen%2FGSE89112_Kc167combined.hic\": \"1829549643,25624\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Feagen%2FGSE89112_Kc167combined_randomized.hic\": \"1859742654,25624\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fmumbach%2FGSE80820_HiChIP_GM_cohesin.hic\": \"1231264781,17932\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fmumbach%2FGSE80820_HiChIP_mES_cohesin_all.hic\": \"1152008628,16438\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fmumbach%2FGSE80820_HiChIP_mES_Oct4.hic\": \"912828146,16438\",\n \"s3.amazonaws.com%2Fhicfiles%2Fexternal%2Fwapl_hic%2FSCC4KO.hic\": \"1767906138,18679\",\n \"s3.amazonaws.com%2Fhicfiles%2Fexternal%2Fwapl_hic%2FDKO.hic\": \"1487228787,18679\",\n \"s3.amazonaws.com%2Fhicfiles%2Fexternal%2Fwapl_hic%2FWaplKO_1.14.hic\": \"1189751862,18679\",\n \"s3.amazonaws.com%2Fhicfiles%2Fexternal%2Fwapl_hic%2FWaplKO_3.3.hic\": \"1155057696,18679\",\n \"s3.amazonaws.com%2Fhicfiles%2Fexternal%2Fwapl_hic%2FWT.hic\": \"1522401568,18679\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fskfuwi4fnsjkdf9jekrw2%2Fmega_Liverpool%2Fmega.hic\": \"2612171975,4381\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fskfuwi4fnsjkdf9jekrw2%2FHIC2836_Liverpool1%2FLiverpool1.hic\": \"191729195,2245\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fskfuwi4fnsjkdf9jekrw2%2FHIC2861_Liverpool2%2FLiverpool2.hic\": \"1637096030,4381\",\n \"s3.amazonaws.com%2Fhicfiles%2Fhiseq%2Fskfuwi4fnsjkdf9jekrw2%2FHIC2862_Liverpool3%2FLiverpool3.hic\": \"1160045602,4381\",\n \"s3.amazonaws.com%2Fhicfiles%2Fexternal%2Fgoodell%2FHSPC.hic\": \"11857786247,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fexternal%2Fgoodell%2FHSPC_CanyonDel.hic\": \"8139168836,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fexternal%2Fgoodell%2Ftcell.hic\": \"9871547081,36479\",\n \"s3.amazonaws.com%2Fhicfiles%2Fexternal%2Fgoodell%2Fep.hic\": \"17479335373,36479\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fnagano%2FTh1_ensemble.hic\": \"1690592868,32102\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fbonev%2FES_mapq30.hic\": \"32930498831,32386\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fbonev%2FNPC_mapq30.hic\": \"55053730986,32386\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fbonev%2FCN_mapq30.hic\": \"53138031154,32386\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2FKieffer-Kwon_et_al_2017%2FMain_maps%2FKieffer-Kwon-2017-activated_B_cells_72_hours_WT.hic\": \"16492991184,32102\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2FKieffer-Kwon_et_al_2017%2FMain_maps%2FKieffer-Kwon-2017-resting_B_cells_WT.hic\": \"23057795398,32102\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2FKieffer-Kwon_et_al_2017%2FMain_maps%2FKieffer-Kwon-2017-activated_B_cells_24_hours_MYC_KO.hic\": \"21245554876,32102\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2FKieffer-Kwon_et_al_2017%2FMain_maps%2FKieffer-Kwon-2017-resting_B_cells_TSA.hic\": \"13933346059,32102\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2FKieffer-Kwon_et_al_2017%2FMain_maps%2FKieffer-Kwon-2017-activated_B_cells_24_hours_oligomycin.hic\": \"21902506832,32102\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2FKieffer-Kwon_et_al_2017%2FMain_maps%2FKieffer-Kwon-2017-mES_WT.hic\": \"9451969795,32102\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2FVian_et_al_2018%2FMain_maps%2FVian-2018-activated_B_cells_24_hours_WT.hic\": \"3600188564,16438\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2FVian_et_al_2018%2FMain_maps%2FVian-2018-activated_B_cells_30_hours_WT.hic\": \"1309503359,16438\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2FVian_et_al_2018%2FMain_maps%2FVian-2018-activated_B_cells_30_hours_HU_treated.hic\": \"1477252396,16438\",\n \"hicfiles.s3.amazonaws.com%2Fhiseq%2FVian_et_al_2018%2FMain_maps%2FVian-2018-activated_B_cells_24_hours_flavopiridol.hic\": \"15711773490,32102\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fpgp%2FPGP1F_mega_090118%2FPGP1F_mega_090118_30.hic\": \"24786676166,36479\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fpgp%2FHIC7145%2FHIC7145_30.hic\": \"4554644616,36479\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fpgp%2FHIC7146%2FHIC7146_30.hic\": \"4174848944,36479\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fpgp%2FHIC7147%2FHIC7147_30.hic\": \"5062229182,36479\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fpgp%2FHIC7862%2FHIC7862_30.hic\": \"4520990620,36479\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fpgp%2FHIC7863%2FHIC7863_30.hic\": \"4330354773,36479\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fpgp%2FHIC7864%2FHIC7864_30.hic\": \"5880640268,36479\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fpgp%2FHIC7865%2FHIC7865_30.hic\": \"4431632469,36479\",\n \"hicfiles.s3.amazonaws.com%2Fexternal%2Fpgp%2FHIC7866%2FHIC7866_30.hic\": \"4686000222,36479\",\n \"encode-public.s3.amazonaws.com%2F2018%2F10%2F19%2Fb122542b-306c-4631-bdc3-2e155e89af55%2FENCFF718AWL.hic\": \"39544267907,58932\",\n \"encode-public.s3.amazonaws.com%2F2019%2F02%2F15%2F8e787cd8-e388-4bc2-a236-7a5e6f39e0c0%2FENCFF999YXX.hic\": \"9255069996,56883\",\n \"encode-public.s3.amazonaws.com%2F2019%2F02%2F08%2Ffc1d9d5d-8fa0-4e29-9080-3da674d9490d%2FENCFF543USQ.hic\": \"5005263062,36479\",\n \"s3.us-east-1.wasabisys.com%2Fhicfiles%2Finternal%2FLCL_mega_42B_500bp_30.hic\": \"106482584851,22829\",\n \"www.encodeproject.org%2Ffiles%2FENCFF925QIF%2F%40%40download%2FENCFF925QIF.hic\": \"51712684396,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF259YUS%2F%40%40download%2FENCFF259YUS.hic\": \"24640030444,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF783KQI%2F%40%40download%2FENCFF783KQI.hic\": \"27209249856,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF318JAP%2F%40%40download%2FENCFF318JAP.hic\": \"28636979242,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF512PQA%2F%40%40download%2FENCFF512PQA.hic\": \"28124104361,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF591MHA%2F%40%40download%2FENCFF591MHA.hic\": \"37373387202,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF197OWW%2F%40%40download%2FENCFF197OWW.hic\": \"41826180893,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF317OIA%2F%40%40download%2FENCFF317OIA.hic\": \"34741636038,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF522YLZ%2F%40%40download%2FENCFF522YLZ.hic\": \"24064692329,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF420JTA%2F%40%40download%2FENCFF420JTA.hic\": \"21202405177,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF871ZDJ%2F%40%40download%2FENCFF871ZDJ.hic\": \"10124815680,18679\",\n \"www.encodeproject.org%2Ffiles%2FENCFF349RZY%2F%40%40download%2FENCFF349RZY.hic\": \"4446702705,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF738YON%2F%40%40download%2FENCFF738YON.hic\": \"3338049584,35947\",\n \"www.encodeproject.org%2Ffiles%2FENCFF406KJN%2F%40%40download%2FENCFF406KJN.hic\": \"4132875306,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF081NPN%2F%40%40download%2FENCFF081NPN.hic\": \"34495587443,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF946RZW%2F%40%40download%2FENCFF946RZW.hic\": \"34571955193,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF602CHT%2F%40%40download%2FENCFF602CHT.hic\": \"30674798032,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF150DKS%2F%40%40download%2FENCFF150DKS.hic\": \"12618769864,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF614IPZ%2F%40%40download%2FENCFF614IPZ.hic\": \"42450060331,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF571ZQR%2F%40%40download%2FENCFF571ZQR.hic\": \"15230068871,47429\",\n \"www.encodeproject.org%2Ffiles%2FENCFF705MKK%2F%40%40download%2FENCFF705MKK.hic\": \"38686554702,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF658KTB%2F%40%40download%2FENCFF658KTB.hic\": \"13195884405,47429\",\n \"www.encodeproject.org%2Ffiles%2FENCFF435JYN%2F%40%40download%2FENCFF435JYN.hic\": \"17192139674,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF016JKX%2F%40%40download%2FENCFF016JKX.hic\": \"37266736642,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF294GFP%2F%40%40download%2FENCFF294GFP.hic\": \"36389843399,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF700CYI%2F%40%40download%2FENCFF700CYI.hic\": \"60482012152,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF962EDB%2F%40%40download%2FENCFF962EDB.hic\": \"39394328182,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF467OGP%2F%40%40download%2FENCFF467OGP.hic\": \"35572788855,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF556RLR%2F%40%40download%2FENCFF556RLR.hic\": \"34826921187,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF309UNV%2F%40%40download%2FENCFF309UNV.hic\": \"48510618174,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF653HCO%2F%40%40download%2FENCFF653HCO.hic\": \"41079007620,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF120DSV%2F%40%40download%2FENCFF120DSV.hic\": \"12790195576,47429\",\n \"www.encodeproject.org%2Ffiles%2FENCFF284OEA%2F%40%40download%2FENCFF284OEA.hic\": \"46007570339,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF035BLF%2F%40%40download%2FENCFF035BLF.hic\": \"63868871985,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF094KKX%2F%40%40download%2FENCFF094KKX.hic\": \"42151419971,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF965BPU%2F%40%40download%2FENCFF965BPU.hic\": \"42717376107,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF842DUO%2F%40%40download%2FENCFF842DUO.hic\": \"39553892515,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF417GBZ%2F%40%40download%2FENCFF417GBZ.hic\": \"45544785452,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF499BVX%2F%40%40download%2FENCFF499BVX.hic\": \"40900674170,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF136XCV%2F%40%40download%2FENCFF136XCV.hic\": \"47700392974,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF224HKR%2F%40%40download%2FENCFF224HKR.hic\": \"40426005932,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF711XSR%2F%40%40download%2FENCFF711XSR.hic\": \"41434581949,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF660JWA%2F%40%40download%2FENCFF660JWA.hic\": \"54201632697,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF081PMO%2F%40%40download%2FENCFF081PMO.hic\": \"53428285130,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF799QGA%2F%40%40download%2FENCFF799QGA.hic\": \"1228682189,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF473CAA%2F%40%40download%2FENCFF473CAA.hic\": \"1077514950,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF663FRL%2F%40%40download%2FENCFF663FRL.hic\": \"39843938245,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF341WOY%2F%40%40download%2FENCFF341WOY.hic\": \"34792598619,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF515ZBF%2F%40%40download%2FENCFF515ZBF.hic\": \"41779230923,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF545GBW%2F%40%40download%2FENCFF545GBW.hic\": \"38351980358,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF252ANV%2F%40%40download%2FENCFF252ANV.hic\": \"37668839771,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF912NDK%2F%40%40download%2FENCFF912NDK.hic\": \"21196851956,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF683PLM%2F%40%40download%2FENCFF683PLM.hic\": \"21849338763,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF355NFJ%2F%40%40download%2FENCFF355NFJ.hic\": \"47880627268,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF507WEW%2F%40%40download%2FENCFF507WEW.hic\": \"35777782924,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF241MSL%2F%40%40download%2FENCFF241MSL.hic\": \"22507408288,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF135MUT%2F%40%40download%2FENCFF135MUT.hic\": \"24168734040,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF459FRB%2F%40%40download%2FENCFF459FRB.hic\": \"37166770103,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF705YZH%2F%40%40download%2FENCFF705YZH.hic\": \"44679182442,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF395INO%2F%40%40download%2FENCFF395INO.hic\": \"56727346538,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF736ITL%2F%40%40download%2FENCFF736ITL.hic\": \"49036286185,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF546TZN%2F%40%40download%2FENCFF546TZN.hic\": \"33195126348,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF706SFK%2F%40%40download%2FENCFF706SFK.hic\": \"3271831702,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF922ERE%2F%40%40download%2FENCFF922ERE.hic\": \"12476647122,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF876OWE%2F%40%40download%2FENCFF876OWE.hic\": \"1538692704,47429\",\n \"www.encodeproject.org%2Ffiles%2FENCFF227XJZ%2F%40%40download%2FENCFF227XJZ.hic\": \"1925617685,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF053BXY%2F%40%40download%2FENCFF053BXY.hic\": \"1032237652,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF014VMM%2F%40%40download%2FENCFF014VMM.hic\": \"1564021703,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF563XES%2F%40%40download%2FENCFF563XES.hic\": \"1489180508,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF482LGO%2F%40%40download%2FENCFF482LGO.hic\": \"1208778887,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF216QQM%2F%40%40download%2FENCFF216QQM.hic\": \"6293163571,47429\",\n \"www.encodeproject.org%2Ffiles%2FENCFF256UOW%2F%40%40download%2FENCFF256UOW.hic\": \"6293163571,47429\",\n \"www.encodeproject.org%2Ffiles%2FENCFF791UZC%2F%40%40download%2FENCFF791UZC.hic\": \"37029615181,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF911AHQ%2F%40%40download%2FENCFF911AHQ.hic\": \"34246649165,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF491AOR%2F%40%40download%2FENCFF491AOR.hic\": \"558663570,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF307PDL%2F%40%40download%2FENCFF307PDL.hic\": \"525321519,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF773ITV%2F%40%40download%2FENCFF773ITV.hic\": \"295464771,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF198SSL%2F%40%40download%2FENCFF198SSL.hic\": \"500142476,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF251UEF%2F%40%40download%2FENCFF251UEF.hic\": \"567443575,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF942LTN%2F%40%40download%2FENCFF942LTN.hic\": \"4430960222,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF543USQ%2F%40%40download%2FENCFF543USQ.hic\": \"5005263062,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF434XQU%2F%40%40download%2FENCFF434XQU.hic\": \"25506511674,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF318GOM%2F%40%40download%2FENCFF318GOM.hic\": \"44750824314,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF004TKY%2F%40%40download%2FENCFF004TKY.hic\": \"20705661833,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF493YNC%2F%40%40download%2FENCFF493YNC.hic\": \"53407154984,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF334XXU%2F%40%40download%2FENCFF334XXU.hic\": \"14341194962,47429\",\n \"www.encodeproject.org%2Ffiles%2FENCFF569RJM%2F%40%40download%2FENCFF569RJM.hic\": \"1922066634,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF076LWH%2F%40%40download%2FENCFF076LWH.hic\": \"39406255845,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF977XWK%2F%40%40download%2FENCFF977XWK.hic\": \"20563512962,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF127TPS%2F%40%40download%2FENCFF127TPS.hic\": \"21032070512,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF480KLP%2F%40%40download%2FENCFF480KLP.hic\": \"33115569647,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF281ILS%2F%40%40download%2FENCFF281ILS.hic\": \"28236353584,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF129LMU%2F%40%40download%2FENCFF129LMU.hic\": \"35247096013,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF759YCW%2F%40%40download%2FENCFF759YCW.hic\": \"16058537743,32102\",\n \"www.encodeproject.org%2Ffiles%2FENCFF045YOM%2F%40%40download%2FENCFF045YOM.hic\": \"19775445828,32102\",\n \"www.encodeproject.org%2Ffiles%2FENCFF013TGD%2F%40%40download%2FENCFF013TGD.hic\": \"4208420532,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF929RPW%2F%40%40download%2FENCFF929RPW.hic\": \"1974260276,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF996XEO%2F%40%40download%2FENCFF996XEO.hic\": \"2072918865,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF097SKJ%2F%40%40download%2FENCFF097SKJ.hic\": \"1983524001,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF464KRA%2F%40%40download%2FENCFF464KRA.hic\": \"1957300131,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF406HHC%2F%40%40download%2FENCFF406HHC.hic\": \"3854527235,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF080DPJ%2F%40%40download%2FENCFF080DPJ.hic\": \"19953768024,47429\",\n \"www.encodeproject.org%2Ffiles%2FENCFF621AIY%2F%40%40download%2FENCFF621AIY.hic\": \"26781700010,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF366ERB%2F%40%40download%2FENCFF366ERB.hic\": \"1049184239,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF997RGL%2F%40%40download%2FENCFF997RGL.hic\": \"2521167549,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF029MPB%2F%40%40download%2FENCFF029MPB.hic\": \"1854711185,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF043EEE%2F%40%40download%2FENCFF043EEE.hic\": \"2924133032,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF920CJR%2F%40%40download%2FENCFF920CJR.hic\": \"3011577886,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF928NJV%2F%40%40download%2FENCFF928NJV.hic\": \"2778936244,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF894GLR%2F%40%40download%2FENCFF894GLR.hic\": \"2831733099,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF303PCK%2F%40%40download%2FENCFF303PCK.hic\": \"688704435,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF999YXX%2F%40%40download%2FENCFF999YXX.hic\": \"9255069996,56883\",\n \"www.encodeproject.org%2Ffiles%2FENCFF685BLG%2F%40%40download%2FENCFF685BLG.hic\": \"16797022992,47429\",\n \"www.encodeproject.org%2Ffiles%2FENCFF188SSH%2F%40%40download%2FENCFF188SSH.hic\": \"16797023050,47429\",\n \"www.encodeproject.org%2Ffiles%2FENCFF465ESX%2F%40%40download%2FENCFF465ESX.hic\": \"13489465953,32102\",\n \"www.encodeproject.org%2Ffiles%2FENCFF493SFI%2F%40%40download%2FENCFF493SFI.hic\": \"30033046818,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF235LCO%2F%40%40download%2FENCFF235LCO.hic\": \"38572174589,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF625VNK%2F%40%40download%2FENCFF625VNK.hic\": \"45202258438,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF304HMS%2F%40%40download%2FENCFF304HMS.hic\": \"36994445315,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF605CEN%2F%40%40download%2FENCFF605CEN.hic\": \"40358346301,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF086ORS%2F%40%40download%2FENCFF086ORS.hic\": \"22650781304,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF237UKR%2F%40%40download%2FENCFF237UKR.hic\": \"41516707246,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF004YZQ%2F%40%40download%2FENCFF004YZQ.hic\": \"71900665326,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF104THR%2F%40%40download%2FENCFF104THR.hic\": \"15172410632,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF807IRK%2F%40%40download%2FENCFF807IRK.hic\": \"17346637451,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF193CQL%2F%40%40download%2FENCFF193CQL.hic\": \"55726903245,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF700DEX%2F%40%40download%2FENCFF700DEX.hic\": \"20231399798,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF234MDO%2F%40%40download%2FENCFF234MDO.hic\": \"24635312640,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF181ROW%2F%40%40download%2FENCFF181ROW.hic\": \"26883606497,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF896OFN%2F%40%40download%2FENCFF896OFN.hic\": \"36952196833,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF573OPJ%2F%40%40download%2FENCFF573OPJ.hic\": \"36685546919,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF028RXH%2F%40%40download%2FENCFF028RXH.hic\": \"31053919206,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF156GGD%2F%40%40download%2FENCFF156GGD.hic\": \"35284134289,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF496GEU%2F%40%40download%2FENCFF496GEU.hic\": \"44659660933,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF945TUH%2F%40%40download%2FENCFF945TUH.hic\": \"3898570191,35639\",\n \"www.encodeproject.org%2Ffiles%2FENCFF698KFV%2F%40%40download%2FENCFF698KFV.hic\": \"4427896684,35751\",\n \"www.encodeproject.org%2Ffiles%2FENCFF239BHZ%2F%40%40download%2FENCFF239BHZ.hic\": \"1718552021,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF277LAN%2F%40%40download%2FENCFF277LAN.hic\": \"4542391336,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF397CMD%2F%40%40download%2FENCFF397CMD.hic\": \"2832016430,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF778OYA%2F%40%40download%2FENCFF778OYA.hic\": \"14067187484,47429\",\n \"www.encodeproject.org%2Ffiles%2FENCFF775VSU%2F%40%40download%2FENCFF775VSU.hic\": \"14067187484,47429\",\n \"www.encodeproject.org%2Ffiles%2FENCFF812THZ%2F%40%40download%2FENCFF812THZ.hic\": \"9667720429,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF777KBU%2F%40%40download%2FENCFF777KBU.hic\": \"5058284320,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF688KOY%2F%40%40download%2FENCFF688KOY.hic\": \"4198695833,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF223UBX%2F%40%40download%2FENCFF223UBX.hic\": \"1206064037,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF273XBU%2F%40%40download%2FENCFF273XBU.hic\": \"44085607579,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF952JZV%2F%40%40download%2FENCFF952JZV.hic\": \"44728845246,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF643NDM%2F%40%40download%2FENCFF643NDM.hic\": \"35877886780,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF586MQY%2F%40%40download%2FENCFF586MQY.hic\": \"71158037547,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF251VFA%2F%40%40download%2FENCFF251VFA.hic\": \"40089479399,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF033WGK%2F%40%40download%2FENCFF033WGK.hic\": \"30802023728,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF649OHR%2F%40%40download%2FENCFF649OHR.hic\": \"28203184265,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF782WVZ%2F%40%40download%2FENCFF782WVZ.hic\": \"37248221674,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF579CAR%2F%40%40download%2FENCFF579CAR.hic\": \"39662025395,54779\",\n \"www.encodeproject.org%2Ffiles%2FENCFF514XWQ%2F%40%40download%2FENCFF514XWQ.hic\": \"1319613701,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF666USK%2F%40%40download%2FENCFF666USK.hic\": \"15051670107,32102\",\n \"www.encodeproject.org%2Ffiles%2FENCFF047SDP%2F%40%40download%2FENCFF047SDP.hic\": \"1357076705,16438\",\n \"www.encodeproject.org%2Ffiles%2FENCFF584LEP%2F%40%40download%2FENCFF584LEP.hic\": \"9314176858,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF671SOE%2F%40%40download%2FENCFF671SOE.hic\": \"3273732256,16438\",\n \"www.encodeproject.org%2Ffiles%2FENCFF702LAP%2F%40%40download%2FENCFF702LAP.hic\": \"1800427500,31682\",\n \"www.encodeproject.org%2Ffiles%2FENCFF339PON%2F%40%40download%2FENCFF339PON.hic\": \"5394351199,31514\",\n \"www.encodeproject.org%2Ffiles%2FENCFF741QPR%2F%40%40download%2FENCFF741QPR.hic\": \"4271510019,30139\",\n \"www.encodeproject.org%2Ffiles%2FENCFF103ANX%2F%40%40download%2FENCFF103ANX.hic\": \"4439745804,30083\",\n \"www.encodeproject.org%2Ffiles%2FENCFF395SBC%2F%40%40download%2FENCFF395SBC.hic\": \"1596732351,31850\",\n \"www.encodeproject.org%2Ffiles%2FENCFF289WNN%2F%40%40download%2FENCFF289WNN.hic\": \"8632980535,32102\",\n \"www.encodeproject.org%2Ffiles%2FENCFF381EAU%2F%40%40download%2FENCFF381EAU.hic\": \"1702476311,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF976FEY%2F%40%40download%2FENCFF976FEY.hic\": \"1448279040,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF485LVS%2F%40%40download%2FENCFF485LVS.hic\": \"1593610856,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF143VJV%2F%40%40download%2FENCFF143VJV.hic\": \"1422312076,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF588NHX%2F%40%40download%2FENCFF588NHX.hic\": \"3943637009,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF768UBD%2F%40%40download%2FENCFF768UBD.hic\": \"24786676166,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF965PEE%2F%40%40download%2FENCFF965PEE.hic\": \"29387092778,47429\",\n \"www.encodeproject.org%2Ffiles%2FENCFF702IFC%2F%40%40download%2FENCFF702IFC.hic\": \"29387092778,47429\",\n \"www.encodeproject.org%2Ffiles%2FENCFF288DNV%2F%40%40download%2FENCFF288DNV.hic\": \"10313429504,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF698HWZ%2F%40%40download%2FENCFF698HWZ.hic\": \"10962849269,47429\",\n \"www.encodeproject.org%2Ffiles%2FENCFF355OWW%2F%40%40download%2FENCFF355OWW.hic\": \"3219571601,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF177TYX%2F%40%40download%2FENCFF177TYX.hic\": \"10325679706,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF542BHD%2F%40%40download%2FENCFF542BHD.hic\": \"11085397879,47429\",\n \"www.encodeproject.org%2Ffiles%2FENCFF684IFW%2F%40%40download%2FENCFF684IFW.hic\": \"11085397879,47429\",\n \"www.encodeproject.org%2Ffiles%2FENCFF592UHE%2F%40%40download%2FENCFF592UHE.hic\": \"21363948089,32102\",\n \"www.encodeproject.org%2Ffiles%2FENCFF779XIS%2F%40%40download%2FENCFF779XIS.hic\": \"9517383271,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF518PSL%2F%40%40download%2FENCFF518PSL.hic\": \"7500581463,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF275GBB%2F%40%40download%2FENCFF275GBB.hic\": \"7889407162,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF634KXI%2F%40%40download%2FENCFF634KXI.hic\": \"6430702966,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF337QPM%2F%40%40download%2FENCFF337QPM.hic\": \"8529733887,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF162KMP%2F%40%40download%2FENCFF162KMP.hic\": \"5615896908,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF992VTE%2F%40%40download%2FENCFF992VTE.hic\": \"7328975027,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF464WXY%2F%40%40download%2FENCFF464WXY.hic\": \"5715339664,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF752EGH%2F%40%40download%2FENCFF752EGH.hic\": \"1733758743,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF474UJM%2F%40%40download%2FENCFF474UJM.hic\": \"222309548,18679\",\n \"www.encodeproject.org%2Ffiles%2FENCFF531UPZ%2F%40%40download%2FENCFF531UPZ.hic\": \"1827756846,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF022VHA%2F%40%40download%2FENCFF022VHA.hic\": \"244983451,18679\",\n \"www.encodeproject.org%2Ffiles%2FENCFF732NGR%2F%40%40download%2FENCFF732NGR.hic\": \"1679484567,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF513VSF%2F%40%40download%2FENCFF513VSF.hic\": \"28397932940,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF750AOC%2F%40%40download%2FENCFF750AOC.hic\": \"36471430712,47429\",\n \"www.encodeproject.org%2Ffiles%2FENCFF219YOB%2F%40%40download%2FENCFF219YOB.hic\": \"2859767211,26979\",\n \"www.encodeproject.org%2Ffiles%2FENCFF604YDD%2F%40%40download%2FENCFF604YDD.hic\": \"3549694085,26979\",\n \"www.encodeproject.org%2Ffiles%2FENCFF746AMV%2F%40%40download%2FENCFF746AMV.hic\": \"2954867135,26979\",\n \"www.encodeproject.org%2Ffiles%2FENCFF845ZEB%2F%40%40download%2FENCFF845ZEB.hic\": \"2763039282,26979\",\n \"www.encodeproject.org%2Ffiles%2FENCFF570LWS%2F%40%40download%2FENCFF570LWS.hic\": \"2861588289,26979\",\n \"www.encodeproject.org%2Ffiles%2FENCFF883YVR%2F%40%40download%2FENCFF883YVR.hic\": \"2433679887,26979\",\n \"www.encodeproject.org%2Ffiles%2FENCFF056VLK%2F%40%40download%2FENCFF056VLK.hic\": \"2502986910,26979\",\n \"www.encodeproject.org%2Ffiles%2FENCFF532DUQ%2F%40%40download%2FENCFF532DUQ.hic\": \"3172615899,26979\",\n \"www.encodeproject.org%2Ffiles%2FENCFF723PYJ%2F%40%40download%2FENCFF723PYJ.hic\": \"10292839095,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF991SGJ%2F%40%40download%2FENCFF991SGJ.hic\": \"13072407683,32102\",\n \"www.encodeproject.org%2Ffiles%2FENCFF885UZI%2F%40%40download%2FENCFF885UZI.hic\": \"1201881201,16438\",\n \"www.encodeproject.org%2Ffiles%2FENCFF287KXA%2F%40%40download%2FENCFF287KXA.hic\": \"14705801988,32102\",\n \"www.encodeproject.org%2Ffiles%2FENCFF335HYI%2F%40%40download%2FENCFF335HYI.hic\": \"20366756545,32102\",\n \"www.encodeproject.org%2Ffiles%2FENCFF121YPY%2F%40%40download%2FENCFF121YPY.hic\": \"2760104016,26979\",\n \"www.encodeproject.org%2Ffiles%2FENCFF675SJE%2F%40%40download%2FENCFF675SJE.hic\": \"3751779995,26979\",\n \"www.encodeproject.org%2Ffiles%2FENCFF876LAW%2F%40%40download%2FENCFF876LAW.hic\": \"4032376256,26979\",\n \"www.encodeproject.org%2Ffiles%2FENCFF740KVX%2F%40%40download%2FENCFF740KVX.hic\": \"3202490322,26979\",\n \"www.encodeproject.org%2Ffiles%2FENCFF977OQV%2F%40%40download%2FENCFF977OQV.hic\": \"2919735477,26979\",\n \"www.encodeproject.org%2Ffiles%2FENCFF525EFN%2F%40%40download%2FENCFF525EFN.hic\": \"2394748073,26979\",\n \"www.encodeproject.org%2Ffiles%2FENCFF690QRC%2F%40%40download%2FENCFF690QRC.hic\": \"3183023394,26979\",\n \"www.encodeproject.org%2Ffiles%2FENCFF452FWS%2F%40%40download%2FENCFF452FWS.hic\": \"2951805127,26979\",\n \"www.encodeproject.org%2Ffiles%2FENCFF089KBG%2F%40%40download%2FENCFF089KBG.hic\": \"2531936700,26979\",\n \"www.encodeproject.org%2Ffiles%2FENCFF939ARM%2F%40%40download%2FENCFF939ARM.hic\": \"3066385212,26979\",\n \"www.encodeproject.org%2Ffiles%2FENCFF401ZAN%2F%40%40download%2FENCFF401ZAN.hic\": \"3008677144,26979\",\n \"www.encodeproject.org%2Ffiles%2FENCFF378RZT%2F%40%40download%2FENCFF378RZT.hic\": \"2830232168,26979\",\n \"www.encodeproject.org%2Ffiles%2FENCFF304AVD%2F%40%40download%2FENCFF304AVD.hic\": \"6164439305,50358\",\n \"www.encodeproject.org%2Ffiles%2FENCFF453DBX%2F%40%40download%2FENCFF453DBX.hic\": \"6775246670,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF590VOM%2F%40%40download%2FENCFF590VOM.hic\": \"6443478922,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF246DOF%2F%40%40download%2FENCFF246DOF.hic\": \"6837914659,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF125FXX%2F%40%40download%2FENCFF125FXX.hic\": \"9736232550,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF241RAY%2F%40%40download%2FENCFF241RAY.hic\": \"7686758397,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF415XWQ%2F%40%40download%2FENCFF415XWQ.hic\": \"6973092068,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF374EBH%2F%40%40download%2FENCFF374EBH.hic\": \"8557459058,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF263YWR%2F%40%40download%2FENCFF263YWR.hic\": \"331586820,18679\",\n \"www.encodeproject.org%2Ffiles%2FENCFF280CGS%2F%40%40download%2FENCFF280CGS.hic\": \"1743569614,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF553ZNS%2F%40%40download%2FENCFF553ZNS.hic\": \"1717253636,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF451VOI%2F%40%40download%2FENCFF451VOI.hic\": \"1626927468,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF420MQO%2F%40%40download%2FENCFF420MQO.hic\": \"31055961677,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF301BWY%2F%40%40download%2FENCFF301BWY.hic\": \"38902429246,47429\",\n \"www.encodeproject.org%2Ffiles%2FENCFF606XNW%2F%40%40download%2FENCFF606XNW.hic\": \"1009699327,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF439ZOU%2F%40%40download%2FENCFF439ZOU.hic\": \"12381714313,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF499SYK%2F%40%40download%2FENCFF499SYK.hic\": \"13182654663,47429\",\n \"www.encodeproject.org%2Ffiles%2FENCFF532LFI%2F%40%40download%2FENCFF532LFI.hic\": \"8286030286,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF020DPP%2F%40%40download%2FENCFF020DPP.hic\": \"23521952420,47429\",\n \"www.encodeproject.org%2Ffiles%2FENCFF306VTV%2F%40%40download%2FENCFF306VTV.hic\": \"23521952480,47429\",\n \"www.encodeproject.org%2Ffiles%2FENCFF399IHE%2F%40%40download%2FENCFF399IHE.hic\": \"10216571232,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF944AII%2F%40%40download%2FENCFF944AII.hic\": \"12567308552,47429\",\n \"www.encodeproject.org%2Ffiles%2FENCFF230HVV%2F%40%40download%2FENCFF230HVV.hic\": \"8629849711,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF174LAF%2F%40%40download%2FENCFF174LAF.hic\": \"9446506633,47429\",\n \"www.encodeproject.org%2Ffiles%2FENCFF898HRO%2F%40%40download%2FENCFF898HRO.hic\": \"9446506633,47429\",\n \"www.encodeproject.org%2Ffiles%2FENCFF429MOR%2F%40%40download%2FENCFF429MOR.hic\": \"1455757398,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF061NXV%2F%40%40download%2FENCFF061NXV.hic\": \"1710915891,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF434PYS%2F%40%40download%2FENCFF434PYS.hic\": \"1832274903,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF704HHX%2F%40%40download%2FENCFF704HHX.hic\": \"1768142834,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF349DPM%2F%40%40download%2FENCFF349DPM.hic\": \"4316041260,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF718AWL%2F%40%40download%2FENCFF718AWL.hic\": \"39544267907,58932\",\n \"www.encodeproject.org%2Ffiles%2FENCFF065LSP%2F%40%40download%2FENCFF065LSP.hic\": \"24929805283,55874\",\n \"www.encodeproject.org%2Ffiles%2FENCFF632MFV%2F%40%40download%2FENCFF632MFV.hic\": \"22333105467,55798\",\n \"www.encodeproject.org%2Ffiles%2FENCFF179HVU%2F%40%40download%2FENCFF179HVU.hic\": \"2659219603,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF791SPZ%2F%40%40download%2FENCFF791SPZ.hic\": \"2537491657,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF211ZWF%2F%40%40download%2FENCFF211ZWF.hic\": \"3512141227,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF614BNU%2F%40%40download%2FENCFF614BNU.hic\": \"5252155462,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF891DLM%2F%40%40download%2FENCFF891DLM.hic\": \"2549095612,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF056EXT%2F%40%40download%2FENCFF056EXT.hic\": \"2219014704,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF776DSS%2F%40%40download%2FENCFF776DSS.hic\": \"3920308353,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF814LQF%2F%40%40download%2FENCFF814LQF.hic\": \"1349480197,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF513ZNA%2F%40%40download%2FENCFF513ZNA.hic\": \"2638868195,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF692IOL%2F%40%40download%2FENCFF692IOL.hic\": \"3106768498,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF294WZY%2F%40%40download%2FENCFF294WZY.hic\": \"2211089761,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF339UWS%2F%40%40download%2FENCFF339UWS.hic\": \"2142759055,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF835FSK%2F%40%40download%2FENCFF835FSK.hic\": \"3919821739,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF328BMB%2F%40%40download%2FENCFF328BMB.hic\": \"2550686152,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF897RTY%2F%40%40download%2FENCFF897RTY.hic\": \"1323294397,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF306MWH%2F%40%40download%2FENCFF306MWH.hic\": \"1665386199,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF039YUJ%2F%40%40download%2FENCFF039YUJ.hic\": \"2335679939,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF468QIN%2F%40%40download%2FENCFF468QIN.hic\": \"3352516594,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF364WXU%2F%40%40download%2FENCFF364WXU.hic\": \"3959043175,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF373MSH%2F%40%40download%2FENCFF373MSH.hic\": \"4429550624,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF959EGQ%2F%40%40download%2FENCFF959EGQ.hic\": \"2475218228,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF624XMK%2F%40%40download%2FENCFF624XMK.hic\": \"3527855681,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF445OKS%2F%40%40download%2FENCFF445OKS.hic\": \"3369125589,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF239QDV%2F%40%40download%2FENCFF239QDV.hic\": \"1960069888,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF645AVM%2F%40%40download%2FENCFF645AVM.hic\": \"4969006589,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF494IPI%2F%40%40download%2FENCFF494IPI.hic\": \"1565483792,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF753IXE%2F%40%40download%2FENCFF753IXE.hic\": \"2892400648,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF731GXX%2F%40%40download%2FENCFF731GXX.hic\": \"5131381303,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF369CAQ%2F%40%40download%2FENCFF369CAQ.hic\": \"4236629448,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF053VBX%2F%40%40download%2FENCFF053VBX.hic\": \"54305946375,47429\",\n \"www.encodeproject.org%2Ffiles%2FENCFF555ISR%2F%40%40download%2FENCFF555ISR.hic\": \"54305946434,47429\",\n \"www.encodeproject.org%2Ffiles%2FENCFF964RSP%2F%40%40download%2FENCFF964RSP.hic\": \"12065485229,36479\",\n \"www.encodeproject.org%2Ffiles%2FENCFF234MZQ%2F%40%40download%2FENCFF234MZQ.hic\": \"17507142760,47429\",\n \"www.encodeproject.org%2Ffiles%2FENCFF994CEG%2F%40%40download%2FENCFF994CEG.hic\": \"17507142760,47429\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fb068e787-bbdd-49e2-9f6d-7a0e9f065d6e%2F4DNFIHSUIRFY.hic\": \"2701182442,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3768b89a-e124-40eb-8acd-94a4fdd35807%2F4DNFIXTAS6EE.hic\": \"3283740601,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F9c513602-5abb-4088-8415-c827c381ab0d%2F4DNFIC3JD6O2.hic\": \"4896075767,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fde954dad-1849-4c23-beb4-bf893b7d76c9%2F4DNFIGY85S4W.hic\": \"3364151996,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fe1befa6e-8067-4296-8db2-67d2a2458985%2F4DNFI2LTNXME.hic\": \"3699291418,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fbb3307fd-7162-477a-87c5-52f12d03befc%2F4DNFID162B9J.hic\": \"3576428773,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8597cdae-8319-42d9-9175-3f77aaee34e1%2F4DNFIQWS3632.hic\": \"4022561190,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F327f091d-6a63-47c4-9752-2dff303a13d9%2F4DNFI6GFHB6G.hic\": \"4239331168,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd70dc3b8-48a7-42c2-bd23-80bc44fc2266%2F4DNFIS5F6EBL.hic\": \"4404671861,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F77df7bf8-6a3d-407a-8968-4ca1e78d2269%2F4DNFIF2D3TL9.hic\": \"4793989394,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc8f7cc35-d2ef-4717-9009-c02154050fbf%2F4DNFI6EIFUZI.hic\": \"3370273763,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F98449d79-30d1-4e32-801d-07435819a42f%2F4DNFIRKGMZRQ.hic\": \"4669813207,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd4fe1844-2493-4722-8b98-34a93a4bb7d8%2F4DNFIQWD8ZYD.hic\": \"5379889057,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F1ee40499-1de4-47ff-b540-d9a65943c6b8%2F4DNFIX7H3CE2.hic\": \"4857679239,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fac016170-23a7-4111-8773-353d6c150f34%2F4DNFIO21YDCV.hic\": \"4695989644,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F1faea4e7-9a32-466e-a826-0bfdab6cd915%2F4DNFIUE5RAS6.hic\": \"4788044799,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fcbd396ed-11bb-404f-aed9-ef10abc258e6%2F4DNFIFI6NIKJ.hic\": \"2069414927,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Faf3f78db-ae92-4215-bcae-76d30c617e5d%2F4DNFIL5K3MA1.hic\": \"2585598247,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F66fc2893-224e-48b4-bdb0-25e022dedd03%2F4DNFIPV5KFMK.hic\": \"2060965679,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F2b39781d-aadc-434f-abe3-562d61308fdd%2F4DNFIW8TIFI5.hic\": \"1694424195,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fb6d28f7b-27d3-486f-b5ac-32567416560d%2F4DNFIA6NSSBJ.hic\": \"2219532611,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F08785616-722e-46bb-ade2-2fdd21324e11%2F4DNFIBKZK63V.hic\": \"2429136232,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F904b13d3-1203-42a4-812c-963e80c159b1%2F4DNFI3CFMRID.hic\": \"1233390166,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fb0ed4afe-5ecf-451d-bb1f-444697e3f558%2F4DNFIYIAUEPW.hic\": \"1753567534,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F4bb9a9b3-12a8-4d2f-8071-4722294c88ea%2F4DNFIC3HAU11.hic\": \"2271375254,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F5abf9c36-c1d1-44dc-8197-74d860d896c0%2F4DNFIM2BMJ33.hic\": \"1770471113,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fa68475db-7816-4cec-b2da-d4ce4a0c7a0e%2F4DNFIBY3UHJB.hic\": \"2095528423,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F07c40943-0d0b-4b3e-94a0-8583b0e00b47%2F4DNFIWZEN3FF.hic\": \"1558559508,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd8a39553-2718-4866-9b2a-45d8e9c5ac6f%2F4DNFIE5TEYK7.hic\": \"1323063102,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F294b61ef-5565-4f04-ade9-f921a6686cce%2F4DNFI7H4II2V.hic\": \"1436947982,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F87a70ad7-7d34-4302-9c03-eb824bd4e633%2F4DNFIAS8LV1C.hic\": \"1263105698,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F9db804c6-5a91-4cf5-8ae9-e054223afb77%2F4DNFIBXWIH8J.hic\": \"1587059951,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd1e55906-ec8f-444b-8ce1-2de22a431a76%2F4DNFIO2HBDAI.hic\": \"1666436393,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F7a4b9b37-8e38-470c-8190-fd4d513c0bbb%2F4DNFIXWCLD4M.hic\": \"1513511880,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F6c7615b2-5310-4bbf-a605-98761d3a3079%2F4DNFINASC4NQ.hic\": \"1420358914,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F20454014-49cd-4e2d-93da-f40ad52776d5%2F4DNFIZF1KI43.hic\": \"1377041630,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F5df04e86-ee2a-45f2-b878-bf1648e2cca5%2F4DNFIQBHR9XC.hic\": \"1179502734,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F9d1cc910-bb3f-4106-802a-73184c58d5ba%2F4DNFIQVMVRP6.hic\": \"1811976991,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fe431986b-0732-460f-92ff-0abd1694d2d0%2F4DNFIJ7OAIFQ.hic\": \"1685503856,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F56d0c575-4962-4ea3-92c3-55bd0e17c096%2F4DNFIE8E4ANZ.hic\": \"1598369564,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fdb1502fb-a989-4ef9-b800-7eaa7be172ae%2F4DNFIOUSETUP.hic\": \"1493294709,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Facc2f1c3-8c96-4d21-814a-3a8ba81e7741%2F4DNFIVJ3IIQL.hic\": \"1472376655,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F037fb4c3-8641-4953-a977-cc71f2137582%2F4DNFIHN2QSMX.hic\": \"1179632606,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F16d2c3c0-6d29-4815-b074-b142af90b615%2F4DNFIILDWK8M.hic\": \"2280059989,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F31789849-e4db-45d8-9730-66a048c02d8a%2F4DNFI6XD6JAQ.hic\": \"2253961696,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fff04947e-e6e8-4d62-8374-ef2ee4104809%2F4DNFIALNLR78.hic\": \"1914687914,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F53e6c1e7-9410-4158-84e6-57c2e683b095%2F4DNFIBT4EAKN.hic\": \"2296378356,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F0127900a-258f-4815-97d2-6fd2b043d853%2F4DNFIDJ2JZ7Q.hic\": \"2558945393,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F89f95693-3d28-44eb-9d45-14932f8e258c%2F4DNFI8JFOAJT.hic\": \"1726440253,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd803d818-b0d4-4796-8d61-a9f3943f3b10%2F4DNFIRZA6EV6.hic\": \"1805017504,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff9165fb1-0782-4757-a740-5b929e0252bb%2F4DNFIB7QTIMH.hic\": \"2541020707,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff8d916b2-b58e-4cdf-894c-ffcb3bf6ebd9%2F4DNFIJ5DQZVK.hic\": \"2445734043,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F14066a5b-e01a-43c2-a468-b18826174df3%2F4DNFISTWNV9C.hic\": \"2499319890,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd0692151-7f9a-4475-b059-f8802616dded%2F4DNFIBN9K4V9.hic\": \"1591570769,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F70a7ef36-a514-4e45-918f-47c4e9e30ef4%2F4DNFIR8OU6QJ.hic\": \"1689882108,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F180306cd-8593-413a-ae83-24f19209c5d2%2F4DNFIDSWKFF5.hic\": \"1596696630,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F6e7b9be7-f465-4434-8e9c-68d1e44a76af%2F4DNFIV239W4L.hic\": \"2345867406,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F55df948c-941d-4930-854c-6a07557a0c1d%2F4DNFIREVU1Z5.hic\": \"2254683002,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3f590cb7-df3a-498f-81c3-d5ed4179b8ad%2F4DNFIFHU75I5.hic\": \"2497670883,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8f064770-6008-4f74-bfca-268d4a22d745%2F4DNFIMROE6N4.hic\": \"9850583704,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fa93d0588-76b7-4ccf-933c-4325876b0a53%2F4DNFI5SUHCGZ.hic\": \"10364705187,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F2f5f0d6b-0b22-4936-93c9-0944d49c037b%2F4DNFII84FBKM.hic\": \"8836986129,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F12e90fc5-0b76-4e42-b346-58d267f9ad6e%2F4DNFI2J1ODWB.hic\": \"13410858286,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff2702a45-3e8b-4980-bcd5-6bb0e291614f%2F4DNFIJWBWE41.hic\": \"20515676755,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fa0859349-5f06-4ad3-b56f-b1166b34a9eb%2F4DNFIIMZB6Y9.hic\": \"15350325963,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F12685c57-d54a-46fa-9efb-acf34ed77574%2F4DNFICJECID5.hic\": \"1525002266,26979\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd101a58e-89aa-44fd-96c5-6bf1e2476272%2F4DNFIR6UW2QA.hic\": \"1264999913,26979\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3d8c73bf-1335-4af4-b124-e3622d48c5f6%2F4DNFIGOEKBUZ.hic\": \"1905947578,26979\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fcd2477cf-6ed0-4d7b-b4e9-88fb38b0df48%2F4DNFIMDNAEW4.hic\": \"996444147,26979\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F0f03953e-29da-4f2e-8c05-572d0edf4525%2F4DNFI5OSZ3JC.hic\": \"369361754,22829\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F29d95dbb-005a-4ae1-8b9c-0fec9ec0bbd0%2F4DNFI7KOUGFM.hic\": \"1227434049,26979\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fa441ab7b-afbe-437d-bf98-b6b916558642%2F4DNFIGKX4A32.hic\": \"883933242,26979\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F941b2f94-2fff-4d3c-aceb-fee4a5ae41a9%2F4DNFI1ORHOTA.hic\": \"1140970677,26979\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8720ede9-093f-4c00-912f-373283260a16%2F4DNFIWSVLZED.hic\": \"458091151,26979\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fe9e17155-2b62-4a68-afb2-31dfa674e169%2F4DNFI6H926RO.hic\": \"3552863515,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F22f22778-987a-4dc0-97bc-f26eae0156d9%2F4DNFIKTYSPOF.hic\": \"2939475400,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F40f40192-0acb-44cb-8778-8d21afe593fb%2F4DNFIZ4S52BV.hic\": \"3067438113,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd8767374-7018-4e11-9226-bf5612d39ebb%2F4DNFI3APMXHF.hic\": \"3258874744,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8c5140ec-a65a-4186-8c59-2927233eecaa%2F4DNFIQLIKDSD.hic\": \"2746398416,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8cdedda6-d7d8-4231-a85b-d56fcd962366%2F4DNFIKYXMF1E.hic\": \"14442148774,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Faa4d4497-7c6c-4dad-8040-be13ba07ea32%2F4DNFI9815EEJ.hic\": \"17960817603,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fe9b7b95f-190b-49fe-8047-ef4a8fc59746%2F4DNFIQ2687RT.hic\": \"15954277087,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F59863d3a-8d7c-49c7-9a41-7f2a58ad24d1%2F4DNFIYDBBSE3.hic\": \"16499534862,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3e80ca41-b3e0-4f4f-a05e-8f95fe96d938%2F4DNFIMOCN1YS.hic\": \"863725312,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F96f97a01-0020-4f09-93e8-fc8a9fd07218%2F4DNFI6558CM8.hic\": \"1597967345,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fce9e9334-ee0b-4549-a845-110470ba5986%2F4DNFIQZRKS7Y.hic\": \"907626411,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fdaac8209-1015-48da-9e31-2e252dfd8fe0%2F4DNFIX4DLXSE.hic\": \"1369766288,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F268b7d52-9655-474c-9467-8ba31bb2195c%2F4DNFII3JV8I1.hic\": \"856656441,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F9681f9b5-335a-4f56-afa1-15b58bbb41e8%2F4DNFI5IAH9H1.hic\": \"1495185175,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3e082eab-95aa-4677-88ed-9d7adcc1effb%2F4DNFIK5HY1GP.hic\": \"2135337789,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F31af1ead-4520-4669-957e-424b4b197c33%2F4DNFIFA89L5B.hic\": \"1975593640,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fcc2b78fd-52d4-4e0c-ac93-b84ee82daf7e%2F4DNFICXCFGEI.hic\": \"2628202920,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff54efece-280f-46ca-95e3-1f8a3cd18820%2F4DNFIK4CECUH.hic\": \"1901129375,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F1181c0c4-afb7-4b6a-9fdc-d868fb2253fc%2F4DNFI1EYIGOC.hic\": \"1947135384,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F1d3e2905-b9b9-4b91-bcb4-8d34746e78f6%2F4DNFI7TLEWUI.hic\": \"1185758726,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Faba3d42f-39cd-4a85-9d3f-835aefb5c803%2F4DNFIVCJKHMN.hic\": \"687240974,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F27f54fcb-54fe-41a4-b25a-2f8944c89044%2F4DNFIN8F14CS.hic\": \"1304082029,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fb75fedb5-88f4-4bc0-8e38-298df7847a7f%2F4DNFI5LCW273.hic\": \"12497258313,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F2f22b2a0-3712-496e-92d2-63775ec0e421%2F4DNFIVSCH2CH.hic\": \"12594733778,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F07e47261-5863-44f5-9198-76e263081bea%2F4DNFIZ268JGC.hic\": \"1499059135,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F682b1ae1-3ac3-40e4-a330-c49f63946952%2F4DNFIJ1P4HBI.hic\": \"1190211725,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F197e7c89-ea73-41de-8cb2-8c0b1e3bb945%2F4DNFITEGKBIW.hic\": \"2061501971,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F191f6928-c9a8-44b2-8516-ee4d6005f24b%2F4DNFIE1P6RVH.hic\": \"1711447310,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F94435086-3701-4b28-a6d0-4a59b24d7615%2F4DNFICJ6I4DO.hic\": \"1557899940,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Faa9ac173-d233-41c7-8985-ca91949664e4%2F4DNFIKUG8MEW.hic\": \"1339072088,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fba6d8ab6-ee18-4ba2-8da9-d631888dd50a%2F4DNFICFZGFAV.hic\": \"1261083478,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F87a3ab04-7094-4673-81e4-ac8c9add8eb5%2F4DNFIQXCZVVA.hic\": \"1084913802,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fbc1ff488-82af-4579-9424-959184edb139%2F4DNFIB6PJFJ3.hic\": \"1114571343,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F1f7026ee-987a-41e7-8a61-45510ee3f86b%2F4DNFIX97731O.hic\": \"1246860402,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F6186787c-2e72-4925-9729-02121e2e4597%2F4DNFIYQYZOTO.hic\": \"1212210849,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3b98a946-0109-4efa-a13e-cc7a36772125%2F4DNFIPXU7V25.hic\": \"1696288217,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fea17d041-c6ed-43a1-8047-535f3d19ad44%2F4DNFIL39PR76.hic\": \"1719284710,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F72774afe-f166-42ac-9849-4070b0dadf6d%2F4DNFIYLJ3R3B.hic\": \"1106419640,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F4a45e733-55f8-4a8e-be24-2ef34c976e25%2F4DNFIL51WBN6.hic\": \"1327651164,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F086c62b0-a26f-41ae-a5ff-88b8be2bd2aa%2F4DNFI6SFPUDA.hic\": \"1336964405,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F4d9b79c7-af62-4070-84a9-b953903f2732%2F4DNFI2KM22QR.hic\": \"953067310,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3c9889d1-f49e-4639-8e15-2d99d6cd22e7%2F4DNFIVF8Q45U.hic\": \"984193565,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fa080dd7b-b7bb-4eae-a275-572a8b45b2d0%2F4DNFI2RN3WFP.hic\": \"1046525527,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fb81860ca-c227-4b68-a298-1907fd32300a%2F4DNFI4TJTL7A.hic\": \"1160373401,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F74ab47dc-7b52-421c-845e-6feb33457adf%2F4DNFIYJ4TWB8.hic\": \"1268416204,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc6582128-a930-4bcc-941e-5c0733bdd4d5%2F4DNFIM6RGKPV.hic\": \"863347067,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F11a75514-4450-4295-9eda-18e3678a575a%2F4DNFIL2VWWL5.hic\": \"860731581,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F5eb52a8c-bf14-4225-bf34-14a0aa47c369%2F4DNFIX6ZXCA8.hic\": \"893462267,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F66aaa4c0-1f62-4040-8ecc-4e95da23cd18%2F4DNFIEVR81FS.hic\": \"879736207,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F821c6e7f-96f7-47de-b7d9-4970562b3c8e%2F4DNFIAUI6BBI.hic\": \"996313881,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F9252c362-31ab-413d-a47a-cc97bdbf243a%2F4DNFIAFEE9G2.hic\": \"1103265750,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc1a0bf52-2e65-4deb-871f-ede736babd41%2F4DNFIPZBEXCP.hic\": \"1081257762,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F729f5ce3-d7e0-466d-b781-d18049e63bfa%2F4DNFIWPKRZGU.hic\": \"973779283,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F80b769ee-a717-4825-9db0-dca86f913173%2F4DNFIMD9QNDX.hic\": \"1158688208,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F266290c0-2767-4158-85ab-7274368905b9%2F4DNFIATA1HD5.hic\": \"1073361089,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc46f18a8-eb24-4d35-b112-36db72bde2f5%2F4DNFIH9U4I7I.hic\": \"1111124316,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fec91a79e-7de7-49f7-9b3d-d28313aeddc8%2F4DNFIZ95S6TR.hic\": \"1242494051,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F9e9390b9-da20-43bb-a8f4-9830f354ddf9%2F4DNFI5ERM9J7.hic\": \"1271051397,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fee8ea82e-b9e4-41ad-bced-5f4fbdaa4fec%2F4DNFI15FPSQL.hic\": \"1216714120,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fbed7eb86-8990-42f2-b3ee-5992d6361f7c%2F4DNFIJ3DZPGM.hic\": \"1035089437,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fdaa8a324-3bf8-424c-8a86-b8ad325cc20d%2F4DNFINW9P6XF.hic\": \"1215712740,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F70631758-6bf8-47a0-92b6-132574886faa%2F4DNFITS16HW8.hic\": \"1105283847,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fe473304b-7bc8-49b8-bba1-ecb9f06914ee%2F4DNFIS3DIH4V.hic\": \"1036056660,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F10f9224a-111c-402a-ac25-e221ad0af9ef%2F4DNFIY3KDHP6.hic\": \"1071761024,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F17519b96-2bdd-4294-98f0-1535f1aef28e%2F4DNFIO8HVKOL.hic\": \"953793750,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ffb18f896-4730-4909-86a3-867fc8e76cd6%2F4DNFIMF6CFOM.hic\": \"708717889,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fcfee4d87-0873-40b0-b79f-35dcc8669c1c%2F4DNFIZZ77KD2.hic\": \"732668723,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fb8b5d909-8a1b-41bb-bcdd-d108a0bde762%2F4DNFIOLO226X.hic\": \"951271932,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F9ce81f6e-b9cf-4ec9-8bd3-517539e4b662%2F4DNFIJMS2ODT.hic\": \"932509067,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F506aa952-5d41-49ff-b658-916bcf88a395%2F4DNFI49F3LJ4.hic\": \"1208494817,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fe4dc392d-ca36-4bdf-a27d-173cae34f520%2F4DNFI65MQOIJ.hic\": \"854630155,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F149ef8d7-e0b4-4e4f-b7e5-7226e2603746%2F4DNFIM4KEPRD.hic\": \"882790622,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fa436f0a8-4f9a-4524-90ac-795c5b8491cf%2F4DNFIIXBIZFC.hic\": \"848244425,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fbc8a05dc-7449-4b01-8330-a55db37ca8e6%2F4DNFIWDOOBVE.hic\": \"1116239020,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Faef8b881-28fe-4694-9a95-1d31940e6726%2F4DNFIDT9EB5M.hic\": \"888289053,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff66f3162-a53d-46f2-8800-3752935d5400%2F4DNFIX2VUNV8.hic\": \"1226661451,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F36c782e6-2c48-4298-aa43-bd6624da003d%2F4DNFIEQHTV1R.hic\": \"804665819,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff15d571e-605d-4bcc-a359-0350b57a6815%2F4DNFIFW7GA64.hic\": \"901568712,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc2aa2e8b-ac7f-4acb-b4b5-ac5f845840fe%2F4DNFIXGXD67I.hic\": \"970995551,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F71b6fd7d-b249-4d65-a597-b80b95845399%2F4DNFIA7GB1NB.hic\": \"956785837,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F6cbb1418-34db-427f-9273-5174eac81529%2F4DNFIVOJGWNP.hic\": \"890415052,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc69c2ee7-b6c3-4a62-8d4f-913491c9dab8%2F4DNFIW22BNB5.hic\": \"1075499540,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fa268f28f-c6d9-4324-8989-75d2d317af1b%2F4DNFIIFBC8WN.hic\": \"1045459440,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F6c7361d4-60a6-440b-b5be-072cada98663%2F4DNFI9ZBEBJH.hic\": \"759395398,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fcceaad1a-e01e-4430-8bd6-24ffa6891802%2F4DNFID4SLU53.hic\": \"921288444,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F9eee5854-b33e-4d5a-9ba8-ceffd47e7488%2F4DNFIODI1NUJ.hic\": \"733159777,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F5e1089b0-42e8-441c-99bb-4be99bcec28b%2F4DNFIJL26LFN.hic\": \"723567970,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F298a429e-ea29-49d3-bfed-fa851e1e7c4c%2F4DNFI5KTF553.hic\": \"2213661745,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F965d29f0-e4a3-477c-8ae4-faf4a654e69a%2F4DNFIYSPGFGV.hic\": \"2274989349,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd88acbc1-37b9-4266-9f97-d8fed576d0f3%2F4DNFILOR6D2D.hic\": \"2595459358,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F7b6ddbce-0ed1-4272-b8ae-32793e4ea4e4%2F4DNFI1WMMPJQ.hic\": \"2262433890,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fedc0c8c4-97d8-4372-9a4f-5e0cdf09d7d0%2F4DNFI47P5978.hic\": \"2146314403,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F0edcc389-43a4-44d7-b946-fe3496f93d56%2F4DNFI7XGW6IH.hic\": \"2302805723,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F0a802926-e235-4c80-b521-83a1774dfb46%2F4DNFIK1EJG8I.hic\": \"2374943035,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3c36aedb-6a58-4aa2-9b11-bb440ec174f1%2F4DNFIDQ3THN9.hic\": \"2341188249,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F846123cd-8828-4e51-8b8a-27deaf293858%2F4DNFI3WPNFWT.hic\": \"775145629,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fbd06e3ad-0e37-48a3-8367-c7d5912cab03%2F4DNFI9DCUOQ1.hic\": \"870487824,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc2eaf9bf-9584-4cec-8685-bd74038a6c01%2F4DNFIU8AF5ZY.hic\": \"1276224366,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F219497b5-3f35-473b-9d4e-e1cf21c69561%2F4DNFIHW8NTQX.hic\": \"28864787856,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F4be13558-114a-4f2d-abca-7598e2ff4757%2F4DNFI4OUMWZ8.hic\": \"17061013588,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F49aed637-87a1-4d4d-ae68-e5da82aec05b%2F4DNFIEYQ5ZIR.hic\": \"13555272651,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fa2f48779-4eff-44a6-8a9d-96435aca1ddc%2F4DNFIDZT7PR8.hic\": \"13425047093,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fb6ec6b71-27b8-4891-b10a-ab06a5270468%2F4DNFIEJEFCAM.hic\": \"15394960208,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F68b9a7b5-8413-44fc-8c2d-59a67b1c4166%2F4DNFIJ8JKKWJ.hic\": \"17012681779,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F294d45a4-8b5e-456f-a9cb-1cbbbad3a7d2%2F4DNFINEQY95T.hic\": \"13966775978,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fbd7f3a48-b822-41e2-bd9c-f52b3aff7b6a%2F4DNFII6AN691.hic\": \"12367300362,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F7da44594-0dc8-4e74-8e10-a957aeaea51a%2F4DNFIDBIEXI7.hic\": \"2015474981,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F085a0453-3784-4eba-80b2-3556e53e2f52%2F4DNFIDKJFK2S.hic\": \"1983111659,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc370c78c-0a99-4c3f-a29b-2dfafc6a3e86%2F4DNFIPAF4PYT.hic\": \"3041434294,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F907ce45f-baa5-416d-92de-e86db4bacff1%2F4DNFIWIYYNQ5.hic\": \"7082321112,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff13afc6b-cf69-4c9d-881f-eed4dd3c28ee%2F4DNFIHMCILEN.hic\": \"1739157603,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F7575d891-0e3d-4a77-896a-3e1b3a8d330b%2F4DNFIJBJ6QVH.hic\": \"5213499748,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff0daa830-60d5-4c7c-a2e1-a4ee70b3fee7%2F4DNFIH2A7IKF.hic\": \"4099503507,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff4970a25-91d8-49a7-9a4a-fe0f12cb2b0f%2F4DNFIOL8KGQ2.hic\": \"2256042055,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F879f1850-d175-4a86-8a97-12658482e3d1%2F4DNFIWILLD6C.hic\": \"5476286356,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F787f538e-d619-4c8f-985b-78753fb7e57c%2F4DNFIZBXXJAF.hic\": \"5946467856,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fb8ee785f-1016-4989-9e64-78352621d32f%2F4DNFI8PZOJHN.hic\": \"8307204961,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3d8997fa-528c-4531-b25b-a412de6bd472%2F4DNFIGXAMSJY.hic\": \"6577588285,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F87aede55-7610-4283-af0e-c6840429a31e%2F4DNFIWNNO89O.hic\": \"2871061417,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F93b8e020-b337-4685-81dc-40cc8a12b5e9%2F4DNFIXU2KPNQ.hic\": \"3401717686,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ffb5cf1bd-59d6-46fe-857d-b86d9756029d%2F4DNFIHBGD6N6.hic\": \"840028421,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F2d1bc088-d838-49b8-85fc-fea78a7353c4%2F4DNFI7J8NI4A.hic\": \"675705256,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F21a27b63-fd67-401b-9aa2-2798e6588d21%2F4DNFISFM9VFK.hic\": \"800145922,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F656c0a9d-7058-4c4b-a3ce-701d929561c1%2F4DNFIJU5XBK7.hic\": \"966593603,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F2efacfbd-9c81-4e62-8df7-847d1ab774d5%2F4DNFIPKY8ED1.hic\": \"3401629450,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fa50b6a26-56b5-43f2-b525-fa219fd716f1%2F4DNFIQRTP7NM.hic\": \"5358852759,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff5dc7a59-b998-4490-8a76-afbf3b258a49%2F4DNFIBCIA62Q.hic\": \"5779049277,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F62b2b237-cb02-45f7-89d9-616cf9ffb678%2F4DNFIV56OFE3.hic\": \"5818844506,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8ac79b4f-cfbf-4b2a-9fc2-898ed6c3e5e1%2F4DNFILIM6FDL.hic\": \"19637469163,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F1cff8afa-5a13-4ad4-bcad-91fc3ced759c%2F4DNFIP71EWXC.hic\": \"17934647326,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F000789fe-9a22-4280-a71c-7ad228fd4cac%2F4DNFIM7ZVQOQ.hic\": \"700134697,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8d78457f-0c2b-4358-b08c-4d4ef4d9f59d%2F4DNFIS6EYHCX.hic\": \"628314484,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8ca3b4a0-2478-49c9-b4a2-a28430417a32%2F4DNFIKKCMS1Q.hic\": \"584050634,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff5041473-18ec-439d-92b1-8ad98c9b25c0%2F4DNFIBIV8OUN.hic\": \"522632731,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fcf474ec6-abd4-431e-a21c-252fcf5ee6b3%2F4DNFIAUMRM2S.hic\": \"313395531,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F2bb1c73e-fb0f-41c4-8620-a938cc8d24a0%2F4DNFI9ZUXG61.hic\": \"332217525,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F26dfa41e-7e4f-457a-a3ac-72daf8059f3c%2F4DNFIDBFENL7.hic\": \"359604894,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8ed2e68b-189e-4988-bb6d-94e63240a231%2F4DNFI7XAZNNQ.hic\": \"5312422266,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F6f2b1ce0-5205-4680-981e-d91b694dc3e4%2F4DNFISNGDB53.hic\": \"2008546759,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F73c8147f-bc7d-4d33-8a10-a9e7b413ecc6%2F4DNFI1CIGHYC.hic\": \"2221847625,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F526ae3e3-32cc-4670-970f-1faa9cfafd4d%2F4DNFIQD2DP2F.hic\": \"5295591503,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F6e803530-47f8-4c56-bb19-fbdcd578d2f0%2F4DNFINHT8P7C.hic\": \"3159499486,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ffe705f38-903f-47b7-9b38-f80ebd18a479%2F4DNFIGF8EM7M.hic\": \"3490552542,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Faa197328-d6da-4299-a0fd-409ac9892668%2F4DNFIUPG2ZBJ.hic\": \"5382003751,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ffe5d52c4-2be7-4812-bca0-cd4bb3025e6b%2F4DNFIH3OTR14.hic\": \"3224693110,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F21935f61-daa8-4df2-aa69-fcd27953b405%2F4DNFIUATRW3Z.hic\": \"3835865655,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F72147527-e3e8-4967-bc45-8251249d76c9%2F4DNFI6V7ZQAE.hic\": \"4382708138,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F589f0919-f54d-49ff-a482-e2f453ef7f34%2F4DNFICKMT1CY.hic\": \"4479068191,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F861946ca-bad8-4a87-96e1-b2eb20b9ef10%2F4DNFIF9BDCNI.hic\": \"3698151402,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff76346ac-97ec-4893-8984-2b75ce1cdc51%2F4DNFIG5O1OQS.hic\": \"5704288175,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fe8b43826-f049-4c3f-b83a-e75fa7aacc85%2F4DNFIHS2SVBQ.hic\": \"990025510,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F46316260-f555-4dd4-9e40-8ae06ca52822%2F4DNFIU95B69H.hic\": \"1275878544,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff62ef491-a3ae-4f66-ab33-c5673c9e0b65%2F4DNFIYRROFCR.hic\": \"1522530503,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F1cd617e1-fad4-4fdc-8b4e-cb277650123c%2F4DNFIF7JN3IU.hic\": \"1463443128,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fdb20fe2a-0078-4d4a-8a52-d76043d06f40%2F4DNFIB2RYULQ.hic\": \"1269529700,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3d386fcf-1d22-47de-a0d6-0c3a641ca174%2F4DNFIMVDK3SI.hic\": \"1185489599,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F00e470bd-c533-41b1-923a-4b471824da12%2F4DNFIRLOTXSC.hic\": \"978217499,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fb8774fb3-d0c5-43cc-a6c9-eb0ca39841fb%2F4DNFIZAPX6J8.hic\": \"1100356082,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fab3b826e-614c-448b-860f-a3ebef68a82f%2F4DNFIQD5VCSD.hic\": \"1322319877,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F66c78d2b-993a-4937-95ed-9e2d302ceb3e%2F4DNFIIF6VAGN.hic\": \"868885799,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F5d106fe1-2d80-466e-87aa-46b38ba142c5%2F4DNFI86IEZXH.hic\": \"751443267,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc99490b6-faf9-413f-9c38-3f53018089d6%2F4DNFIP881SR2.hic\": \"754427927,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F39c7e387-e710-4b1d-b757-357dec03f6ad%2F4DNFI42NNCW8.hic\": \"1166392978,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F4742a211-43b1-4325-af6f-82490aeb766b%2F4DNFIEV4PKP6.hic\": \"1102227476,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Feaa73842-1c86-4ad9-8a9e-c189c0b4c01d%2F4DNFIF1DUQHE.hic\": \"1206699207,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd25f24df-0298-4079-bb6f-1c8e1e32392b%2F4DNFIGW55EAY.hic\": \"1033358104,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc57a7ab5-2778-4fe2-9d64-9a4e95135f12%2F4DNFISZRU6I4.hic\": \"1539570262,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd89f494a-27ca-46b6-89be-7583f3f6d18c%2F4DNFIBKKDTAP.hic\": \"350372180,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F06725280-cb24-4f22-a267-18b434bfa79e%2F4DNFIJSRQW24.hic\": \"314361467,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8fe5c3c5-006f-425b-ac6d-ea475e29be78%2F4DNFI3REN89E.hic\": \"299665258,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc8b6ac5c-13b4-427e-9158-cec0b890b6d8%2F4DNFIF5XLHKM.hic\": \"235668364,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F01ff33fc-fc23-48aa-a6c6-b720d6fe0768%2F4DNFIB6Q538N.hic\": \"316494853,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F552978c8-abbc-424a-9187-3e34cf802a97%2F4DNFI3ST3F7Y.hic\": \"296298411,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F72e66520-5170-4f2e-844a-fbfd0e23b480%2F4DNFIQT4M6UI.hic\": \"307691265,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fb3eb3953-ffe8-4d5a-970c-a16f3b7b9ec3%2F4DNFIFNCC7M2.hic\": \"364160436,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F37d413fb-afab-41ff-99aa-1678830f7dde%2F4DNFITM9MDJL.hic\": \"252412426,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Faf5db92c-aaf1-4086-a0d2-79b28648f172%2F4DNFI3NTD7B3.hic\": \"227586640,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff6892f7b-1f8a-4d7d-9605-c67932cd5654%2F4DNFIBED48O1.hic\": \"328344868,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd64afb07-5ab1-4c4f-8438-2fee37afa86a%2F4DNFISATK9PF.hic\": \"379669025,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fad11bb63-8692-461c-b698-89c601451321%2F4DNFISRP84FE.hic\": \"298491537,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F63710ec5-35d2-47dd-bf9a-08d3daa83d67%2F4DNFI2LY7B73.hic\": \"303150299,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F76077d9e-ca75-4301-ab79-88aa49bda495%2F4DNFIXEB4UZO.hic\": \"711757090,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F34dd4c0e-3487-4fb4-b95f-c4bb66e0fa31%2F4DNFIQWWATGK.hic\": \"221304476,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F48a8cf86-3248-4a8e-8e85-472ec219d49c%2F4DNFI44JLUSL.hic\": \"284772724,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fee399fbf-2a9e-46e2-8364-457713bff508%2F4DNFIM7Q2FQQ.hic\": \"330729464,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F124d191a-c5c7-49b6-b84b-0d1bad8bef2b%2F4DNFIZK7W8GZ.hic\": \"293166018,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fe351f7cc-7a2c-4515-ae0b-3bb2f91c986a%2F4DNFIMIMLMD3.hic\": \"240094740,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ffd1ae249-57b1-41d6-81a6-16b21dcd8f12%2F4DNFI7QUSU5J.hic\": \"681762505,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F46c92c5c-9ad8-4d49-beba-f35c5cd99208%2F4DNFINXUOI5H.hic\": \"375594313,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd7350d40-4e9e-4131-9151-bb539d39b431%2F4DNFIIJR2296.hic\": \"331322302,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fbfacf37b-1665-45f3-a046-e29e1544e9b0%2F4DNFIJMZUTXR.hic\": \"361313244,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F234e18fb-9990-43bf-9a48-f72722cfa232%2F4DNFIZQPT9EL.hic\": \"540421873,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F4b35ab09-2e79-4876-b2bc-d3a8faa26257%2F4DNFIZIXSZ9J.hic\": \"545066813,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F2ae5118e-807a-46e0-8e92-143d4b282b3d%2F4DNFIDD9IF9T.hic\": \"237409149,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fb34d7f6f-73f7-4b6b-80c7-c8af0f991549%2F4DNFIVC8OQPG.hic\": \"355121712,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F9ab169fd-cbdd-4f60-8553-a4c6912ad89e%2F4DNFITUPI4HA.hic\": \"313085022,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F4e53712b-d0d9-40c5-afe1-ffa0fad71e59%2F4DNFI5IZNXIO.hic\": \"341863906,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F7a91477f-45eb-4a16-affb-fc131f9326b8%2F4DNFII16KXA7.hic\": \"248904495,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F153729de-0eca-43cc-9b61-61aa8d775b38%2F4DNFIAAH19VM.hic\": \"668047244,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F879fd78a-7165-43d9-a0de-ca158b53df30%2F4DNFIVKIY3KV.hic\": \"247571318,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F67f901a4-040b-4b04-9fff-94a1780423cd%2F4DNFIVVCWL6C.hic\": \"198355985,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd5b30c5a-654a-463c-9474-39bdc3ce4500%2F4DNFIJRF2273.hic\": \"343971277,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F7070280a-8f03-40d0-9fef-e9d9f4d3dae7%2F4DNFI6FCC9ZA.hic\": \"312013061,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F47049719-9407-4d76-9048-26231045f642%2F4DNFI1CPQ4O3.hic\": \"352923267,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F862c2b5f-44c2-4bd7-9264-b3ca032d3d8d%2F4DNFISXFEDE9.hic\": \"271745977,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Feffbe052-39ff-4217-9871-44199ed90818%2F4DNFIF9L6QEQ.hic\": \"668409334,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fa7791854-1b35-4258-90fb-603c55f24642%2F4DNFIPKASX1Q.hic\": \"312727920,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F79cccad6-a78e-4de9-9fe7-08f7e8df663d%2F4DNFIWXZ4JQZ.hic\": \"151808553,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F7e86e0cc-d6f1-4ce0-aba4-c36c6ebb3c4c%2F4DNFIEMQ1O8V.hic\": \"700533280,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F4a1b58d3-9ae6-43e4-91cf-49f1fcbbab33%2F4DNFIYWONU7A.hic\": \"729050356,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F67bff264-0b0c-4c5c-9d4d-ff5abef2bbe4%2F4DNFISNIE5FH.hic\": \"7987657997,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3a6a943f-2cc0-4433-a27d-c89f3fdd3309%2F4DNFIV8MLWJB.hic\": \"6646216171,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F9e235711-ba90-404d-b4ac-b15990ea8e33%2F4DNFIXSTDPHL.hic\": \"3146468238,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F0c89f4bc-e9fc-4ecf-b868-26108dbb7bb2%2F4DNFIQJNOH8U.hic\": \"2919703928,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F1856ff9e-de7a-4fa1-ae0b-3e04b837b5e1%2F4DNFI57XB4A8.hic\": \"13417594377,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F099bb5b9-6315-4650-8f78-d603f5a046b3%2F4DNFIQ7UKVZV.hic\": \"9016468637,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Faf3c7a30-0fc4-410d-8d41-247da3eb105d%2F4DNFIWJY8GHD.hic\": \"7921314766,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fda99f429-20ab-4d91-bbfe-f8bdea8ed7b1%2F4DNFIN8NKRNF.hic\": \"4247121358,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F0ca0f4e3-30ca-4332-b735-e32dce08e1a4%2F4DNFIZYGEHNZ.hic\": \"4910404663,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F243f48b0-6b59-4f37-ad39-a12e0986f530%2F4DNFIRPYGAV8.hic\": \"4220073636,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F49f1a890-d458-42a6-9c78-99c38b6c7a8f%2F4DNFI6MZTDM1.hic\": \"375035361,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F76bd4768-9343-44ba-a99d-5500e184e39d%2F4DNFIG3BCGPL.hic\": \"2422923206,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F9d1ed866-eaf6-4906-aa8c-9e39616dde38%2F4DNFIS9YPJ3L.hic\": \"1593271574,37769\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F1e7a5636-bdb6-45fb-85d8-87a7e908de43%2F4DNFIOWGA9AX.hic\": \"1632314387,37769\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F5ecc552a-0a6b-49a9-9aa5-9f3fd9b535fd%2F4DNFINKEDSBF.hic\": \"1458761024,37769\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F6c03f1d2-bb25-4c94-b5f5-d5cdd01c14b6%2F4DNFIVIXVUK7.hic\": \"1504818271,37769\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F1a4616ff-6d04-4a6a-9773-b80e81da2471%2F4DNFIANHFY16.hic\": \"1850724180,37769\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd2231870-a78d-4c8b-9cfd-084f2468acb1%2F4DNFIJ67ZFBI.hic\": \"1473864703,37769\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F859c2dd3-df8a-42b7-86ea-bf6524f75e80%2F4DNFIG3YQQ4V.hic\": \"1539822829,37769\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8bad667e-6003-4828-9a20-07585fa9c811%2F4DNFIOLKEOME.hic\": \"3036353747,37769\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F92ea551b-5779-4d31-a0f5-621e4bd0eb21%2F4DNFIVLN8WJE.hic\": \"2710426318,37769\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F61ee79fa-0617-4083-b121-f92ef3a8905c%2F4DNFI2111XQA.hic\": \"2589549183,37769\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F83ebb98d-e5db-403d-aa23-875293156c0e%2F4DNFI88HXX7D.hic\": \"2462367030,37769\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F6d63671a-8f1d-4159-82c0-931b43464772%2F4DNFIUBM6QK8.hic\": \"2486020469,37769\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fcccb9014-ce15-4032-81ac-222b3d621cb4%2F4DNFIVILEERC.hic\": \"2052537210,37769\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F21a07867-4007-4ca5-b066-25d3168208dc%2F4DNFIF7Q43N4.hic\": \"2091773428,37769\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff738de0f-358b-44bf-97dd-644c8d9b1b1c%2F4DNFID56VJGW.hic\": \"878913568,37769\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fda97c1d4-bb92-4a77-92a7-f7960f88b9dc%2F4DNFIYUR29KO.hic\": \"983915575,37769\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F54ea363a-99e7-4f55-861e-1644acab7939%2F4DNFIUDPGHO8.hic\": \"905253594,37769\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fdcd66a07-55ee-48d9-a157-419cf4ee3eef%2F4DNFISWC2N8T.hic\": \"1233576358,37769\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F40363837-7466-4a1d-b20d-a66d1670b700%2F4DNFICMPHDMI.hic\": \"516590777,37769\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F0b3fa4e6-caeb-40b4-8942-e9c0b03dfe4f%2F4DNFIKMKN736.hic\": \"634310295,37769\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fb6a34050-d52b-4880-91cf-d3fe4b0ce982%2F4DNFIN5NLS49.hic\": \"650451131,37769\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8e63a47b-9fd4-4772-8b0c-10ee589ffb16%2F4DNFI4P8UBRL.hic\": \"705655033,37769\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F7d92b666-30cc-4838-9d46-c1f11cee3d3c%2F4DNFISNC3LAI.hic\": \"176146197,37769\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F17f7dc63-a1bc-4970-b389-87d9ee93b753%2F4DNFIVBWPFD7.hic\": \"749678512,37769\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff8897333-4791-4a83-9444-a653e24aee13%2F4DNFITMQRXB7.hic\": \"254477361,37769\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8712bf31-33d0-4562-ab0b-a1e9cf4fd30c%2F4DNFIUYD3HBY.hic\": \"995625724,37769\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fbfaf6383-9cc6-4b5c-9b20-d3bf2e8c3495%2F4DNFIRRSC7P9.hic\": \"1149985362,37769\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fb0b70598-5d17-4e0a-8831-6cbe697e69e2%2F4DNFIWKR8FP6.hic\": \"1151628407,37769\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fccc094a8-23ce-4fd8-9c4a-41f07c045c8f%2F4DNFIQ74RSUY.hic\": \"931695969,37769\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8eda16f3-af5e-4f1f-b46d-c74df44b76aa%2F4DNFI9IIO5PW.hic\": \"1077740364,37769\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff283637b-cf2c-4412-ba00-0e3d7e279fad%2F4DNFI8WGJG19.hic\": \"812086456,37769\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F7ad8438f-d3d9-42d8-88bf-42845a0dc2d0%2F4DNFIQ5CCESJ.hic\": \"652559720,37769\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F70e3bdcc-caf4-4822-b9c5-85234873db7a%2F4DNFIWTZHB4H.hic\": \"760694196,37769\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F56ed767d-cd8a-4d38-8047-ed1e8bc8cd19%2F4DNFIENYQCDP.hic\": \"1159428005,37769\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fa912fff9-5f90-42b1-a3a6-cbb9eb2cf861%2F4DNFIFATZWPD.hic\": \"1033325746,37769\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F21338ea5-fdee-4ad8-b61c-608fc6cec4bc%2F4DNFI7YRXKEO.hic\": \"388142539,37769\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff0f88647-5631-437b-b48a-4603915e3714%2F4DNFIUY3J7EW.hic\": \"407344788,37769\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F16926af8-ac3b-4f32-97d5-6c0dc6f1596a%2F4DNFIRKUYKP4.hic\": \"893352368,37769\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F93e39aec-6cde-4c5b-bcdf-283faa3163a2%2F4DNFIAQDBJZP.hic\": \"489922022,37769\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F0dc0b1ba-5509-4464-9814-dfe103ff09a0%2F4DNFIC1CLPK7.hic\": \"565748333,37769\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fb50964c7-b025-49d9-b1ed-289bedb59678%2F4DNFI3A3VYWU.hic\": \"4597459343,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff4390cea-b330-4022-88c1-9ff8c0a786f7%2F4DNFI6JJQKFJ.hic\": \"3678393678,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F70c0f730-5da1-4863-9b7a-6cdd31066cff%2F4DNFIK61ILGM.hic\": \"3324300994,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F14b14ac4-ab59-4754-9c43-eacd9d0638e2%2F4DNFIYD8LO9Z.hic\": \"3227227120,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F7386f953-8da9-47b0-acb2-931cba810544%2F4DNFIOTPSS3L.hic\": \"253942497,7557\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff6b5d8bd-27dc-4415-a320-53405a16db85%2F4DNFI525PKU5.hic\": \"305089653,7557\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F1f922dbc-637b-4c43-b816-f604f0e79ad1%2F4DNFI8Y9SRP2.hic\": \"1438589609,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F6a36d686-716c-4ba8-a9c3-fa8311791d3c%2F4DNFIP25GZGA.hic\": \"1419100109,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F0e535542-2cf2-46e4-ba10-7a0b946a7fb2%2F4DNFITPO1WTY.hic\": \"3885296184,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F0c17d228-5052-4c83-880e-af05118e6929%2F4DNFIG4X5Z5F.hic\": \"2159245890,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc3977c00-525b-4556-9a27-061707f8cb76%2F4DNFIXLYR32S.hic\": \"587852728,21916\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3f856506-cbc5-4211-a29d-48a7530c622e%2F4DNFIWI3V5LI.hic\": \"2318237793,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F38f77979-5eb7-4b6f-9a60-c2451185db98%2F4DNFI2DGL7LH.hic\": \"2068150664,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fe0992a75-7727-405e-95ac-aa97141b51c1%2F4DNFI1VSO8JP.hic\": \"1807949651,21916\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fe925f1aa-2e7b-44e7-bfa8-2084a613ab13%2F4DNFIV5O2ZYO.hic\": \"2242134377,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F803a6d3c-3972-4939-8ff2-d195c5192090%2F4DNFIEWEWQ8D.hic\": \"2981341325,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F25104375-a588-46e6-a382-663cee6c332f%2F4DNFICSTCJQZ.hic\": \"14592996888,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F927aa8a5-24a5-43b7-807a-1e99ac321459%2F4DNFICEGAHRC.hic\": \"15431307603,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8c380474-12cd-41f4-b86f-2a29faf12eec%2F4DNFIY3XPKPO.hic\": \"2550999291,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F77da562e-d0ec-45a8-8764-14fa16d995a1%2F4DNFIK9PS9GM.hic\": \"3401011629,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F11b26222-d480-40a7-8d53-3ad8500396cb%2F4DNFIF4Y74JR.hic\": \"2127593378,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F93df02c6-1047-43f6-afae-d3598b61eeea%2F4DNFIBBKG9KD.hic\": \"5724446278,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F6cd4378a-8f51-4e65-99eb-15f5c80abf8d%2F4DNFIT4I5C6Z.hic\": \"5419655766,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F067881e5-563d-40de-a9e3-caccad887fbc%2F4DNFI2U38HCE.hic\": \"14749043471,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fcb3da9ad-7afe-4d0c-9c2d-261181e7a95c%2F4DNFIETP228R.hic\": \"9401474797,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F185b7bcc-7bb7-41b7-9ebe-92d4fe159431%2F4DNFIXKC48TK.hic\": \"11624295594,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F18459b84-dd43-4af6-a05f-bcb773096322%2F4DNFIFPGOWJ6.hic\": \"2843730862,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ffde1e48c-4a0d-4bb1-b84a-e0e45f9a0aa3%2F4DNFIIRMBE8Y.hic\": \"5820677927,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fbabed539-1f0f-4e87-8815-fde596e6024c%2F4DNFIVUGNDD7.hic\": \"5170782436,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F7d00531a-e616-469b-af52-5b028270e2ce%2F4DNFIFLJLIS5.hic\": \"18917549985,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F7a9dad53-b8af-4cb6-9ce3-5c38e4a855c7%2F4DNFIOX3BGNE.hic\": \"5482775936,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F82fd7b7e-5f47-48d5-bf0d-daaa48a4674d%2F4DNFISPUVQHA.hic\": \"2177864938,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F4c6680f3-9cf6-452f-9dc5-ecebf376775d%2F4DNFI8649RQJ.hic\": \"3288850368,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F2395f001-19d9-4000-9f00-dae3dea708d6%2F4DNFIE8T8JZ8.hic\": \"1383191843,21916\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F24464fa8-bf96-483c-8e9a-c2f626ad6e19%2F4DNFIBM714BP.hic\": \"1765204569,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F918fc048-fa27-41d2-a63a-d50c511fbb9a%2F4DNFI6CWNUFL.hic\": \"2431120602,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F7ff5a0d1-8e54-4cf0-9fe7-339f147c78da%2F4DNFIZ4F74QR.hic\": \"3211825957,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F355f0412-cb17-452a-b15c-aba16c5a742c%2F4DNFIOUVOX3R.hic\": \"5547401083,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3cac91c5-160a-4b91-a91e-edc309318dd5%2F4DNFIVTDXW6X.hic\": \"4797344498,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fe9ac9ec5-6221-4f39-951a-1c5054fc9f1c%2F4DNFICA8Y9TN.hic\": \"4277557869,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F46f62222-b50a-428b-938b-5444951600eb%2F4DNFIDWM3HN5.hic\": \"4374808431,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F50e4f2a1-9cb6-4192-8199-64d354bfdf96%2F4DNFIBK5TB3N.hic\": \"3757387253,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fe4cdd5a8-1a45-4c6a-906b-a9603260d4c8%2F4DNFI3JYF9VS.hic\": \"5260534916,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc8164e99-5778-427d-be26-f0e1b62400f0%2F4DNFIP1GNKUO.hic\": \"7589365689,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F0d72e78a-fc87-4716-8b8e-6dc5650ff2ef%2F4DNFIQYQWPF5.hic\": \"22022259901,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fac58fc15-48c2-4eec-a689-23b677b4b6e7%2F4DNFIW6H9U3S.hic\": \"6810897169,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F31811e40-e3ca-4456-8ba6-2ee66d6c7104%2F4DNFI7J8BQ4P.hic\": \"7188744676,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F62d81a52-d2cb-4bbd-8510-0fe120e786e0%2F4DNFIA3AKFSU.hic\": \"1763730692,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fae0b7513-d1a0-4f27-a9d3-348837f42cb6%2F4DNFID68JQY9.hic\": \"2422880133,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fae6a1a7e-1d2d-4fd2-a89f-1799abac8a9c%2F4DNFIL1FQDXE.hic\": \"1543814834,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F80d343c9-bd60-468a-803d-c3e351a958bc%2F4DNFITSIPCSK.hic\": \"2344682115,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff2d61195-a3a6-4d50-b928-546ca67546cb%2F4DNFIJ88LYHR.hic\": \"3362742962,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F31052aba-773a-4500-961b-e0a518245b0c%2F4DNFIJIPWD63.hic\": \"2529548812,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc93d0710-3fbf-40cc-b0eb-878e2aa659e4%2F4DNFIZUP2BBI.hic\": \"491996147,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F8660baeb-5be1-4ba5-93e4-66499e9a4587%2F4DNFIEBC4AF3.hic\": \"2993048734,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff6d08fbc-b836-4776-82ad-8b1b277ae837%2F4DNFI5VO3E1W.hic\": \"1949322679,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3af004a2-a6fa-46dc-8be8-898b847a77be%2F4DNFIFDGVWLU.hic\": \"2456400803,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fbd613b4b-2422-492c-8d8f-8afba9c8a182%2F4DNFITVGFNYZ.hic\": \"1411204423,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc340694f-14f3-4638-b09b-98220c20039a%2F4DNFIOW9TTC1.hic\": \"2611370588,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3effa71b-6aa3-4265-87ba-f8d709d778d7%2F4DNFIOAA3ZEQ.hic\": \"3123195980,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fde75cf8b-9ce1-44fc-8b7b-ca0adea6bae9%2F4DNFIA5ID1S6.hic\": \"3496246968,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F714f775d-a5a4-4314-83f8-016b9d73200b%2F4DNFIZYU7V81.hic\": \"4245592042,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F5ca518af-6e1e-4777-b67b-0fe7f039ce58%2F4DNFIRV6PVUX.hic\": \"3981520466,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc29b57d5-c263-4372-b396-ab4f55682f5d%2F4DNFIMEANFBY.hic\": \"3999623376,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F4196d3ef-161a-4c18-a57e-005165c6b32a%2F4DNFIGLGQXLC.hic\": \"4105683321,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fe10828b5-9519-4ceb-81e7-7228bfd890de%2F4DNFILS2HLXC.hic\": \"3804942111,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Feaac88c7-9bdc-4b1e-aa9f-e675520dfffa%2F4DNFIQS8853L.hic\": \"5287726781,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Faab371b1-bc8d-4e83-998e-5bb977c443ca%2F4DNFIVBYCYGS.hic\": \"4657988157,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fdb116add-af8c-4a3b-b106-9f704ba0a175%2F4DNFIE4WWHMF.hic\": \"5116727268,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F033366e2-05a2-4381-9d48-90122892a9e0%2F4DNFIKDUUC3C.hic\": \"45638237,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F7284a446-442d-4a46-aae5-84987e75a7af%2F4DNFIJ5HIRA2.hic\": \"62201052,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F876649a3-6dd3-463a-8b17-5752a98a89c5%2F4DNFIXDFC7EM.hic\": \"69878143,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3cb4ce4d-d474-459f-8b8a-2159d8df8068%2F4DNFIO35EOVR.hic\": \"70153114,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F5c5612fa-18c2-47fb-8074-693b1054e254%2F4DNFI57QGL6U.hic\": \"54605055,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F70c1472d-cf3a-41d7-8682-cd03b7cc978d%2F4DNFI2AGEBE5.hic\": \"67930121,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F2bf4cce8-6e03-422b-a190-e51d4a07d501%2F4DNFI1E6NJQJ.hic\": \"4893181511,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F0eb3aa56-8a23-435d-a07b-8bb545e8d708%2F4DNFI2DNFM1A.hic\": \"60466977,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F1201682a-a223-482d-913d-3c3972b8eb65%2F4DNFIIRIHBR2.hic\": \"48961678,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F6aee7913-6356-43cf-affa-f2b60dd478f6%2F4DNFIKXNMT46.hic\": \"39095246,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F357139a3-c9a5-4343-b0a4-b41c45fd03fd%2F4DNFIRV7IRJP.hic\": \"70916718,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F76be3061-6259-42be-a917-19dcba41517b%2F4DNFIFX1XYKZ.hic\": \"229197441,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ff60c348a-a62c-43c3-ac85-f6c28b5f823f%2F4DNFI64CJUZ5.hic\": \"112428610,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fbd0b0a14-9703-49af-bb36-2359f96d4d0e%2F4DNFIBPL2HL1.hic\": \"73972428,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F79ac278d-83f7-4c1f-91b2-05c8018c1426%2F4DNFIBRSIPE4.hic\": \"415430378,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F0c3b8141-8e67-4211-80dd-3bae88f9e537%2F4DNFIDLDVY14.hic\": \"112747303,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F2ae703d2-d85c-4ac4-9ce1-14d653927675%2F4DNFI4R1II4P.hic\": \"210565448,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F76e641af-90be-49f8-b126-12c20f856159%2F4DNFINMLRY95.hic\": \"1590865292,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3b416382-ae5d-469f-9e9a-85a3e2ce9793%2F4DNFI8KBXYNL.hic\": \"4626496956,22663\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fa27589a6-86b2-43a2-8218-1f2232d551e6%2F4DNFI53R5IKA.hic\": \"1536016455,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fdd3999f5-b36e-4154-a6b9-446656959a3a%2F4DNFIAWVDQ8C.hic\": \"2210273411,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fc377953b-0e61-426b-a905-abab2d5a3002%2F4DNFI9VXTBE2.hic\": \"3384365692,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F2dbe0377-1db2-4aae-af2b-d87dff728035%2F4DNFIT96Z365.hic\": \"7692311974,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fdcfcb009-f006-4ab8-a4c7-af72be58c12c%2F4DNFITUOMFUQ.hic\": \"6592120312,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F67f9073d-b2c5-474e-b3d5-7d72cde555cd%2F4DNFIHLQKDN8.hic\": \"2647703964,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F76968cc8-fb9f-485b-85b2-c9289067194b%2F4DNFIL9M97T2.hic\": \"6186798917,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F87d9330b-8d2c-4e9d-85bb-02e572de7a68%2F4DNFIDWGZLHX.hic\": \"4379708168,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Ffc01b381-3665-4225-88ee-2e5e9ecb7324%2F4DNFIMEG1QIC.hic\": \"3587146533,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3144a03c-15c3-4bf9-95f8-ffad2640a1bf%2F4DNFIWSB66VX.hic\": \"1529739069,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fd7d3aac0-ba66-494b-ba0c-147631084b98%2F4DNFIH7TH4MF.hic\": \"6896300679,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F4b13bd19-fbd1-4c68-8855-4f0158d1ce47%2F4DNFIHKWIZ9T.hic\": \"1954878455,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F3d04e286-30d4-4add-a806-7a929d36419e%2F4DNFIZBBX795.hic\": \"1350142414,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Faa26f261-a88a-4cac-9118-ff8e90ab6f61%2F4DNFI9ZWZ5BS.hic\": \"3410552807,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F24e516ce-0b49-4476-b818-cc96471d8765%2F4DNFIPAI8XB5.hic\": \"4168518737,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fac3b06b5-46d4-4c1e-97e9-9a4f353473a7%2F4DNFI1OUWFSC.hic\": \"10766406904,21916\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F76c6aa27-895f-4e82-8ed8-7a85aca84490%2F4DNFIX4PJKXZ.hic\": \"1463157350,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fe6fbe03a-997b-4d72-a3cc-f1ed7bd88a92%2F4DNFIZGCA8AH.hic\": \"1597664180,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F61d99a87-4ec6-4116-be99-b483999641c4%2F4DNFI5CGQ46V.hic\": \"2870576870,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F271ea8cd-53b9-44c9-9fff-1bb5c444b54c%2F4DNFIOCW5AEM.hic\": \"2463600138,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2Fa98ca64a-861a-4a8c-92e9-586af457b1fb%2F4DNFI1UEG1HD.hic\": \"22480709268,25900\",\n \"4dn-open-data-public.s3.amazonaws.com%2Ffourfront-webprod%2Fwfoutput%2F5809b32e-0aea-4cf5-a174-cf162d591a35%2F4DNFI9YAVTI1.hic\": \"3141182061,25900\"\n}","/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2016-2017 The Regents of the University of California\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and\n * associated documentation files (the \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the\n * following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all copies or substantial\n * portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING\n * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n *\n */\n\n/**\n * Created by dat on 3/3/17.\n */\nimport {prettyPrint} from \"./utils.js\"\n\nclass LocusGoto {\n\n constructor(browser, hicNavbarContainer) {\n this.browser = browser;\n\n const parentElement = hicNavbarContainer.querySelector(\"div[id$='upper-hic-nav-bar-widget-container']\");\n\n this.containerElement = document.createElement('div');\n this.containerElement.className = 'hic-chromosome-goto-container';\n this.containerElement.title = 'Chromosome Goto';\n parentElement.appendChild(this.containerElement);\n\n this.resolutionSelectorElement = document.createElement('input');\n this.resolutionSelectorElement.type = 'text';\n this.resolutionSelectorElement.placeholder = 'chr-x-axis chr-y-axis';\n this.containerElement.appendChild(this.resolutionSelectorElement);\n\n this.resolutionSelectorElement.addEventListener('change', (e) => {\n this.browser.parseGotoInput(this.resolutionSelectorElement.value);\n this.resolutionSelectorElement.blur();\n });\n\n this.browser.eventBus.subscribe(\"LocusChange\", this);\n }\n\n receiveEvent(event) {\n if (event.type === \"LocusChange\") {\n let loci;\n const state = event.data.state || this.browser.state;\n const isWholeGenome = this.browser.dataset.isWholeGenome(state.chr1);\n if (isWholeGenome) {\n loci = 'All';\n } else {\n\n const { chr:chrX, start:sX, end:eX } = state.locus.x\n const strX = `${chrX}:${prettyPrint(1 + sX)}-${prettyPrint(eX)}`\n\n const { chr:chrY, start:sY, end:eY } = state.locus.y\n const strY = `${chrY}:${prettyPrint(1 + sY)}-${prettyPrint(eY)}`\n\n loci = `${strX} ${strY}`\n\n }\n this.resolutionSelectorElement.value = loci;\n }\n }\n}\n\nexport default LocusGoto;\n","/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2016-2017 The Regents of the University of California\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and\n * associated documentation files (the \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the\n * following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all copies or substantial\n * portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING\n * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n *\n */\n\n/**\n * Created by dat on 3/4/17.\n */\nimport { StringUtils } from '../node_modules/igv-utils/src/index.js';\n\nclass ResolutionSelector {\n\n constructor(browser, hicNavbarContainer) {\n this.browser = browser;\n\n const parentElement = hicNavbarContainer.querySelector(\"div[id$='upper-hic-nav-bar-widget-container']\");\n\n this.containerElement = document.createElement('div');\n this.containerElement.className = 'hic-resolution-selector-container';\n this.containerElement.title = 'Resolution';\n parentElement.appendChild(this.containerElement);\n\n // label container\n this.labelContainerElement = document.createElement('div');\n this.labelContainerElement.id = 'hic-resolution-label-container';\n this.containerElement.appendChild(this.labelContainerElement);\n\n // Resolution (kb)\n this.labelElement = document.createElement('div');\n this.labelElement.textContent = 'Resolution (kb)';\n this.labelElement.style.display = 'none';\n this.labelContainerElement.appendChild(this.labelElement);\n\n // lock/unlock\n this.resolutionLockElement = document.createElement('i');\n this.resolutionLockElement.id = 'hic-resolution-lock';\n this.resolutionLockElement.className = 'fa fa-unlock';\n this.resolutionLockElement.setAttribute('aria-hidden', 'true');\n this.labelContainerElement.appendChild(this.resolutionLockElement);\n this.labelContainerElement.addEventListener('click', () => {\n this.browser.resolutionLocked = !this.browser.resolutionLocked;\n this.setResolutionLock(this.browser.resolutionLocked);\n });\n\n this.resolutionSelectorElement = document.createElement('select');\n this.resolutionSelectorElement.name = 'resolution_selector';\n this.containerElement.appendChild(this.resolutionSelectorElement);\n\n this.resolutionSelectorElement.addEventListener('change', () => {\n const zoomIndex = parseInt(this.resolutionSelectorElement.value);\n this.browser.setZoom(zoomIndex);\n });\n\n this.browser.eventBus.subscribe(\"LocusChange\", this);\n this.browser.eventBus.subscribe(\"MapLoad\", this);\n this.browser.eventBus.subscribe(\"ControlMapLoad\", this);\n }\n\n setResolutionLock(resolutionLocked) {\n this.resolutionLockElement.classList.remove(resolutionLocked ? 'fa-unlock' : 'fa-lock');\n this.resolutionLockElement.classList.add(resolutionLocked ? 'fa-lock' : 'fa-unlock');\n }\n\n receiveEvent(event) {\n const browser = this.browser;\n\n if (event.type === \"LocusChange\") {\n if (event.data.resolutionChanged) {\n browser.resolutionLocked = false;\n this.setResolutionLock(browser.resolutionLocked);\n }\n\n if (event.data.chrChanged !== false) {\n const isWholeGenome = browser.dataset.isWholeGenome(event.data.state.chr1);\n this.labelElement.textContent = isWholeGenome ? 'Resolution (mb)' : 'Resolution (kb)';\n this.updateResolutions(browser.state.zoom);\n } else {\n const selectedIndex = browser.state.zoom;\n Array.from(this.resolutionSelectorElement.options).forEach((option, index) => {\n option.selected = index === selectedIndex;\n });\n }\n } else if (event.type === \"MapLoad\") {\n browser.resolutionLocked = false;\n this.setResolutionLock(false);\n this.updateResolutions(browser.state.zoom);\n } else if (event.type === \"ControlMapLoad\") {\n this.updateResolutions(browser.state.zoom);\n }\n }\n\n async updateResolutions(zoomIndex) {\n const browser = this.browser;\n const resolutions = browser.isWholeGenome() ?\n [{ index: 0, binSize: browser.dataset.wholeGenomeResolution }] :\n browser.getResolutions();\n this.resolutionSelectorElement.innerHTML = '';\n\n resolutions.forEach(resolution => {\n const binSize = resolution.binSize;\n const index = resolution.index;\n let divisor, unit;\n if (binSize >= 1e6) {\n divisor = 1e6;\n unit = 'mb';\n } else if (binSize >= 1e3) {\n divisor = 1e3;\n unit = 'kb';\n } else {\n divisor = 1;\n unit = 'bp';\n }\n\n const pretty = `${StringUtils.numberFormatter(Math.round(binSize / divisor))} ${unit}`;\n const option = document.createElement('option');\n option.dataset.resolution = binSize;\n option.value = index;\n option.textContent = pretty;\n if (zoomIndex === index) option.selected = true;\n this.resolutionSelectorElement.appendChild(option);\n });\n }\n}\n\nexport default ResolutionSelector;\n","/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2016-2017 The Regents of the University of California\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and\n * associated documentation files (the \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the\n * following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all copies or substantial\n * portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING\n * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n *\n */\n\nimport {IGVMath} from \"../node_modules/igv-utils/src/index.js\"\nimport RatioColorScale from \"./ratioColorScale.js\";\n\nconst defaultColorScaleConfig = {threshold: 2000, r: 255, g: 0, b: 0}\n\nclass ColorScale {\n\n constructor(scale) {\n this.threshold = scale.threshold;\n this.r = scale.r;\n this.g = scale.g;\n this.b = scale.b;\n this.cache = []\n this.nbins = 2000\n this.binsize = this.threshold / this.nbins\n }\n\n setThreshold(threshold) {\n this.threshold = threshold;\n this.cache = []\n this.binsize = this.threshold / this.nbins\n }\n\n getThreshold() {\n return this.threshold;\n }\n\n setColorComponents(components) {\n this.r = components.r;\n this.g = components.g;\n this.b = components.b;\n this.cache = []\n }\n\n getColorComponents() {\n return {\n r: this.r,\n g: this.g,\n b: this.b\n }\n }\n\n equals(cs) {\n return JSON.stringify(this) === JSON.stringify(cs);\n }\n\n getColor(value) {\n const low = 0;\n const bin = Math.floor(Math.min(this.threshold, value) / this.binsize)\n if (undefined === this.cache[bin]) {\n const alpha = Math.floor(255 * (IGVMath.clamp(value, low, this.threshold) - low) / (this.threshold - low))\n this.cache[bin] = {\n red: this.r,\n green: this.g,\n blue: this.b,\n alpha,\n rgbaString: `rgba(${this.r},${this.g},${this.b}, ${alpha})`\n }\n }\n return this.cache[bin]\n }\n\n stringify() {\n return \"\" + this.threshold + ',' + this.r + ',' + this.g + ',' + this.b;\n }\n\n static parse(string) {\n\n var pnstr, ratioCS;\n\n if (string.startsWith(\"R:\")) {\n pnstr = string.substring(2).split(\":\");\n ratioCS = new RatioColorScale(Number.parseFloat(pnstr[0]));\n ratioCS.positiveScale = foo(pnstr[1]);\n ratioCS.negativeScale = foo(pnstr[2]);\n return ratioCS;\n } else {\n return foo(string);\n }\n\n function foo(str) {\n var cs, tokens;\n\n tokens = str.split(\",\");\n\n cs = {\n threshold: tokens[0],\n r: tokens[1],\n g: tokens[2],\n b: tokens[3]\n };\n return new ColorScale(cs);\n }\n }\n}\n\nexport {defaultColorScaleConfig}\n\nexport default ColorScale\n","/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2016-2017 The Regents of the University of California\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and\n * associated documentation files (the \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the\n * following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all copies or substantial\n * portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING\n * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n *\n */\n\nimport ColorScale from './colorScale.js'\n\nconst defaultRatioColorScaleConfig = {threshold: 5, positive: {r: 255, g: 0, b: 0}, negative: {r: 0, g: 0, b: 255}}\n\nclass RatioColorScale {\n\n constructor(threshold) {\n\n this.threshold = threshold;\n\n this.positiveScale = new ColorScale({\n threshold: Math.log(threshold),\n r: 255,\n g: 0,\n b: 0\n });\n this.negativeScale = new ColorScale(\n {\n threshold: Math.log(threshold),\n r: 0,\n g: 0,\n b: 255\n })\n }\n\n setThreshold(threshold) {\n this.threshold = threshold;\n this.positiveScale.setThreshold(Math.log(threshold));\n this.negativeScale.setThreshold(Math.log(threshold));\n }\n\n getThreshold() {\n return this.threshold;\n }\n\n setColorComponents(components, plusOrMinus) {\n if ('-' === plusOrMinus) {\n return this.negativeScale.setColorComponents(components);\n } else {\n return this.positiveScale.setColorComponents(components);\n }\n }\n\n getColorComponents(plusOrMinus) {\n\n if ('-' === plusOrMinus) {\n return this.negativeScale.getColorComponents();\n } else {\n return this.positiveScale.getColorComponents();\n }\n }\n\n getColor(score) {\n\n var logScore = Math.log(score);\n\n if (logScore < 0) {\n return this.negativeScale.getColor(-logScore);\n } else {\n return this.positiveScale.getColor(logScore);\n }\n }\n\n stringify() {\n return \"R:\" + this.threshold + \":\" + this.positiveScale.stringify() + \":\" + this.negativeScale.stringify();\n }\n}\n\nexport {defaultRatioColorScaleConfig}\n\nexport default RatioColorScale\n","/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2016-2017 The Regents of the University of California\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and\n * associated documentation files (the \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the\n * following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all copies or substantial\n * portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING\n * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n *\n */\n\n/**\n * @author Jim Robinson\n */\n\nimport {IGVColor} from '../node_modules/igv-utils/src/index.js'\nimport ColorScale from './colorScale.js'\nimport HICEvent from './hicEvent.js'\nimport * as hicUtils from './hicUtils.js'\nimport {getLocus} from \"./genomicUtils.js\"\nimport {getOffset} from \"./utils.js\"\n\nconst DRAG_THRESHOLD = 2\nconst DOUBLE_TAP_DIST_THRESHOLD = 20\nconst DOUBLE_TAP_TIME_THRESHOLD = 300\n\nconst imageTileDimension = 685\n\nconst doLegacyTrack2DRendering = false\n\nclass ContactMatrixView {\n\n constructor(browser, viewportElement, sweepZoom, scrollbarWidget, colorScale, ratioColorScale, backgroundColor) {\n this.browser = browser;\n this.viewportElement = viewportElement;\n this.sweepZoom = sweepZoom;\n this.scrollbarWidget = scrollbarWidget;\n\n // Set initial color scales. These might be overridden/adjusted via parameters\n this.colorScale = colorScale;\n this.ratioColorScale = ratioColorScale;\n // this.diffColorScale = new RatioColorScale(100, false);\n\n this.backgroundColor = backgroundColor;\n this.backgroundRGBString = IGVColor.rgbColor(backgroundColor.r, backgroundColor.g, backgroundColor.b);\n\n this.canvasElement = viewportElement.querySelector('canvas');\n this.ctx = this.canvasElement.getContext('2d');\n\n this.faSpinnerElement = viewportElement.querySelector('.fa-spinner');\n this.spinnerCount = 0;\n\n this.xGuideElement = viewportElement.querySelector(\"div[id$='-x-guide']\");\n this.yGuideElement = viewportElement.querySelector(\"div[id$='-y-guide']\");\n\n this.displayMode = 'A';\n this.imageTileCache = {};\n this.imageTileCacheKeys = [];\n this.imageTileCacheLimit = 8; // 8 is the minimum number required to support A/B cycling\n this.colorScaleThresholdCache = {};\n\n this.browser.eventBus.subscribe(\"NormalizationChange\", this);\n this.browser.eventBus.subscribe(\"TrackLoad2D\", this);\n this.browser.eventBus.subscribe(\"TrackState2D\", this);\n this.browser.eventBus.subscribe(\"MapLoad\", this);\n this.browser.eventBus.subscribe(\"ControlMapLoad\", this);\n this.browser.eventBus.subscribe(\"ColorChange\", this);\n\n this.drawsInProgress = new Set();\n }\n\n setBackgroundColor(rgb) {\n this.backgroundColor = rgb\n this.backgroundRGBString = IGVColor.rgbColor(rgb.r, rgb.g, rgb.b)\n this.update()\n }\n\n stringifyBackgroundColor() {\n return `${this.backgroundColor.r},${this.backgroundColor.g},${this.backgroundColor.b}`\n }\n\n static parseBackgroundColor(rgbString) {\n const [r, g, b] = rgbString.split(\",\").map(str => parseInt(str))\n return {r, g, b}\n }\n\n setColorScale(colorScale) {\n\n switch (this.displayMode) {\n case 'AOB':\n case 'BOA':\n this.ratioColorScale = colorScale\n break\n case 'AMB':\n this.diffColorScale = colorScale\n break\n default:\n this.colorScale = colorScale\n }\n this.colorScaleThresholdCache[colorScaleKey(this.browser.state, this.displayMode)] = colorScale.threshold\n }\n\n async setColorScaleThreshold(threshold) {\n this.getColorScale().setThreshold(threshold)\n this.colorScaleThresholdCache[colorScaleKey(this.browser.state, this.displayMode)] = threshold\n this.imageTileCache = {}\n await this.update()\n }\n\n getColorScale() {\n switch (this.displayMode) {\n case 'AOB':\n case 'BOA':\n return this.ratioColorScale\n case 'AMB':\n return this.diffColorScale\n default:\n return this.colorScale\n }\n }\n\n async setDisplayMode(mode) {\n this.displayMode = mode\n this.clearImageCaches()\n await this.update()\n }\n\n clearImageCaches() {\n this.imageTileCache = {}\n this.imageTileCacheKeys = []\n }\n\n getViewDimensions() {\n return {\n width: this.viewportElement.offsetWidth,\n height: this.viewportElement.offsetHeight\n };\n }\n\n async receiveEvent(event) {\n if (event.type === \"MapLoad\" || event.type === \"ControlMapLoad\") {\n // Don't enable mouse actions until we have a dataset.\n if (!this.mouseHandlersEnabled) {\n this.addTouchHandlers(this.viewportElement);\n this.addMouseHandlers(this.viewportElement)\n this.mouseHandlersEnabled = true;\n }\n this.clearImageCaches();\n this.colorScaleThresholdCache = {};\n } else {\n if (event.type !== \"LocusChange\") {\n this.clearImageCaches();\n }\n this.update();\n }\n }\n\n async update() {\n\n if (this.disableUpdates) return // This flag is set during browser startup\n\n await this.repaint()\n\n if (this.browser.dataset && false === doLegacyTrack2DRendering){\n await this.render2DTracks(this.browser.tracks2D, this.browser.dataset, this.browser.state)\n }\n\n }\n\n async repaint() {\n if (!this.browser.dataset) return;\n\n const viewportWidth = this.viewportElement.offsetWidth;\n const viewportHeight = this.viewportElement.offsetHeight;\n const canvasWidth = this.canvasElement.width;\n const canvasHeight = this.canvasElement.height;\n\n if (canvasWidth !== viewportWidth || canvasHeight !== viewportHeight) {\n this.canvasElement.width = viewportWidth;\n this.canvasElement.height = viewportHeight;\n this.canvasElement.setAttribute('width', viewportWidth);\n this.canvasElement.setAttribute('height', viewportHeight);\n }\n\n const { state, dataset, controlDataset } = this.browser;\n let ds = dataset, dsControl = null, zdControl = null;\n let zoom = state.zoom, controlZoom;\n\n switch (this.displayMode) {\n case 'B':\n zoom = getBZoomIndex(state.zoom);\n ds = controlDataset;\n break;\n case 'AOB':\n case 'AMB':\n controlZoom = getBZoomIndex(state.zoom);\n dsControl = controlDataset;\n break;\n case 'BOA':\n zoom = getBZoomIndex(state.zoom);\n controlZoom = state.zoom;\n ds = controlDataset;\n dsControl = dataset;\n break;\n }\n\n const matrix = await ds.getMatrix(state.chr1, state.chr2);\n const zd = matrix.getZoomDataByIndex(zoom, \"BP\");\n\n if (dsControl) {\n const matrixControl = await dsControl.getMatrix(state.chr1, state.chr2);\n zdControl = matrixControl.getZoomDataByIndex(controlZoom, \"BP\");\n }\n\n const pixelSizeInt = Math.max(1, Math.floor(state.pixelSize));\n const widthInBins = viewportWidth / pixelSizeInt;\n const heightInBins = viewportHeight / pixelSizeInt;\n const blockCol1 = Math.floor(state.x / imageTileDimension);\n const blockCol2 = Math.floor((state.x + widthInBins) / imageTileDimension);\n const blockRow1 = Math.floor(state.y / imageTileDimension);\n const blockRow2 = Math.floor((state.y + heightInBins) / imageTileDimension);\n\n if (state.normalization !== \"NONE\") {\n if (!ds.hasNormalizationVector(state.normalization, zd.chr1.name, zd.zoom.unit, zd.zoom.binSize)) {\n Alert.presentAlert(`Normalization option ${state.normalization} unavailable at this resolution.`);\n this.browser.eventBus.post(new HICEvent(\"NormalizationExternalChange\", \"NONE\"));\n state.normalization = \"NONE\";\n }\n }\n\n await this.checkColorScale(ds, zd, blockRow1, blockRow2, blockCol1, blockCol2, state.normalization);\n\n this.ctx.clearRect(0, 0, viewportWidth, viewportHeight);\n for (let r = blockRow1; r <= blockRow2; r++) {\n for (let c = blockCol1; c <= blockCol2; c++) {\n const tile = await this.getImageTile(ds, dsControl, zd, zdControl, r, c, state);\n if (tile.image) this.paintTile(tile);\n }\n }\n\n this.genomicExtent = {\n chr1: state.chr1,\n chr2: state.chr2,\n x: state.x * zd.zoom.binSize,\n y: state.y * zd.zoom.binSize,\n w: viewportWidth * zd.zoom.binSize / state.pixelSize,\n h: viewportHeight * zd.zoom.binSize / state.pixelSize\n };\n\n function getBZoomIndex(zoom) {\n const binSize = dataset.getBinSizeForZoomIndex(zoom);\n if (!binSize) throw new Error(`Invalid zoom (resolution) index: ${zoom}`);\n\n const bZoom = controlDataset.getZoomIndexForBinSize(binSize);\n if (bZoom < 0) throw new Error(`Invalid binSize for \"B\" map: ${binSize}`);\n\n return bZoom;\n }\n }\n\n /**\n * This is where the image tile is actually drawn, if not in the cache\n *\n * @param ds\n * @param dsControl\n * @param zd\n * @param zdControl\n * @param row\n * @param column\n * @param state\n * @returns {Promise<{image: HTMLCanvasElement, column: *, row: *, blockBinCount}|{image, inProgress: boolean, column: *, row: *, blockBinCount}|*>}\n */\n async getImageTile(ds, dsControl, zd, zdControl, row, column, state) {\n\n const key = `${zd.chr1.name}_${zd.chr2.name}_${zd.zoom.binSize}_${zd.zoom.unit}_${row}_${column}_${state.normalization}_${this.displayMode}`\n\n if (this.imageTileCache.hasOwnProperty(key)) {\n return this.imageTileCache[key]\n\n } else {\n if (this.drawsInProgress.has(key)) {\n //console.log(\"In progress\")\n const imageSize = imageTileDimension\n const image = inProgressTile(imageSize)\n return {\n row: row,\n column: column,\n blockBinCount: imageTileDimension,\n image: image,\n inProgress: true\n } // TODO return an image at a coarser resolution if avaliable\n\n }\n this.drawsInProgress.add(key)\n\n try {\n this.startSpinner()\n const sameChr = zd.chr1.index === zd.chr2.index\n const transpose = sameChr && row < column\n const averageCount = zd.averageCount\n const ctrlAverageCount = zdControl ? zdControl.averageCount : 1\n const averageAcrossMapAndControl = (averageCount + ctrlAverageCount) / 2\n\n const imageSize = imageTileDimension\n const image = document.createElement('canvas')\n image.width = imageSize\n image.height = imageSize\n const ctx = image.getContext('2d')\n //ctx.clearRect(0, 0, image.width, image.height);\n\n // Get blocks\n const widthInBP = imageTileDimension * zd.zoom.binSize\n const x0bp = column * widthInBP\n const region1 = {chr: zd.chr1.name, start: x0bp, end: x0bp + widthInBP}\n const y0bp = row * widthInBP\n const region2 = {chr: zd.chr2.name, start: y0bp, end: y0bp + widthInBP}\n const records = await ds.getContactRecords(state.normalization, region1, region2, zd.zoom.unit, zd.zoom.binSize)\n let cRecords\n if (zdControl) {\n cRecords = await dsControl.getContactRecords(state.normalization, region1, region2, zdControl.zoom.unit, zdControl.zoom.binSize)\n }\n\n if (records.length > 0) {\n\n const controlRecords = {}\n if ('AOB' === this.displayMode || 'BOA' === this.displayMode || 'AMB' === this.displayMode) {\n for (let record of cRecords) {\n controlRecords[record.getKey()] = record\n }\n }\n\n let id = ctx.getImageData(0, 0, image.width, image.height)\n\n\n const x0 = transpose ? row * imageTileDimension : column * imageTileDimension\n const y0 = transpose ? column * imageTileDimension : row * imageTileDimension\n for (let i = 0; i < records.length; i++) {\n\n const rec = records[i]\n let x = Math.floor((rec.bin1 - x0))\n let y = Math.floor((rec.bin2 - y0))\n\n if (transpose) {\n const t = y\n y = x\n x = t\n }\n\n let rgba\n switch (this.displayMode) {\n\n case 'AOB':\n case 'BOA':\n let key = rec.getKey()\n let controlRec = controlRecords[key]\n if (!controlRec) {\n continue // Skip\n }\n let score = (rec.counts / averageCount) / (controlRec.counts / ctrlAverageCount)\n\n rgba = this.ratioColorScale.getColor(score)\n\n break\n\n case 'AMB':\n key = rec.getKey()\n controlRec = controlRecords[key]\n if (!controlRec) {\n continue // Skip\n }\n score = averageAcrossMapAndControl * ((rec.counts / averageCount) - (controlRec.counts / ctrlAverageCount))\n\n rgba = this.diffColorScale.getColor(score)\n\n break\n\n default: // Either 'A' or 'B'\n rgba = this.colorScale.getColor(rec.counts)\n }\n\n // TODO -- verify that this bitblting is faster than fillRect\n setPixel(id, x, y, rgba.red, rgba.green, rgba.blue, rgba.alpha)\n if (sameChr && row === column) {\n setPixel(id, y, x, rgba.red, rgba.green, rgba.blue, rgba.alpha)\n }\n\n }\n\n ctx.putImageData(id, 0, 0)\n }\n\n\n if (true === doLegacyTrack2DRendering) {\n\n //Draw 2D tracks\n ctx.save()\n ctx.lineWidth = 2\n\n const onDiagonalTile = sameChr && row === column\n\n for (let track2D of this.browser.tracks2D) {\n const skip =\n !track2D.isVisible ||\n (sameChr && \"lower\" === track2D.displayMode && row < column) ||\n (sameChr && \"upper\" === track2D.displayMode && row > column)\n\n if (!skip) {\n\n const chr1Name = zd.chr1.name\n const chr2Name = zd.chr2.name\n\n const features = track2D.getFeatures(chr1Name, chr2Name)\n\n if (features) {\n\n for (let {chr1, x1, x2, y1, y2, color} of features) {\n\n ctx.strokeStyle = track2D.color || color\n\n // Chr name order -- test for equality of zoom data chr1 and feature chr1\n const flip = chr1Name !== chr1\n\n //Note: transpose = sameChr && row < column\n const fx1 = transpose || flip ? y1 : x1\n const fx2 = transpose || flip ? y2 : x2\n const fy1 = transpose || flip ? x1 : y1\n const fy2 = transpose || flip ? x2 : y2\n\n let px1 = (fx1 - x0bp) / zd.zoom.binSize\n let px2 = (fx2 - x0bp) / zd.zoom.binSize\n let py1 = (fy1 - y0bp) / zd.zoom.binSize\n let py2 = (fy2 - y0bp) / zd.zoom.binSize\n let w = px2 - px1\n let h = py2 - py1\n\n const dim = Math.max(image.width, image.height)\n if (px2 > 0 && px1 < dim && py2 > 0 && py1 < dim) {\n\n\n if (!onDiagonalTile || \"upper\" !== track2D.displayMode) {\n ctx.strokeRect(px1, py1, w, h)\n }\n\n // By convention intra-chromosome data is always stored in lower diagonal coordinates.\n // If we are on a diagonal tile, draw the symmetrical reflection unless display mode is lower\n if (onDiagonalTile && \"lower\" !== track2D.displayMode) {\n ctx.strokeRect(py1, px1, h, w)\n }\n }\n }\n\n } // if (features)\n\n }\n }\n\n ctx.restore()\n\n } // if (true === doLegacyTrack2DRendering)\n\n // Uncomment to reveal tile boundaries for debugging.\n // ctx.strokeStyle = \"rgb(255,255,255)\"\n // ctx.strokeStyle = \"pink\"\n // ctx.strokeRect(0, 0, image.width - 1, image.height - 1)\n\n const imageTile = { row, column, blockBinCount: imageTileDimension, image }\n\n if (this.imageTileCacheLimit > 0) {\n if (this.imageTileCacheKeys.length > this.imageTileCacheLimit) {\n delete this.imageTileCache[this.imageTileCacheKeys[0]]\n this.imageTileCacheKeys.shift()\n }\n this.imageTileCache[key] = imageTile\n\n }\n\n return imageTile\n\n } finally {\n this.drawsInProgress.delete(key)\n this.stopSpinner()\n }\n }\n\n\n function setPixel(imageData, x, y, r, g, b, a) {\n const index = (x + y * imageData.width) * 4\n imageData.data[index + 0] = r\n imageData.data[index + 1] = g\n imageData.data[index + 2] = b\n imageData.data[index + 3] = a\n }\n\n }\n\n /**\n * Return a promise to adjust the color scale, if needed. This function might need to load the contact\n * data to computer scale.\n *\n * @param zd\n * @param row1\n * @param row2\n * @param col1\n * @param col2\n * @param normalization\n * @returns {*}\n */\n async checkColorScale(ds, zd, row1, row2, col1, col2, normalization) {\n\n const colorKey = colorScaleKey(this.browser.state, this.displayMode) // This doesn't feel right, state should be an argument\n if ('AOB' === this.displayMode || 'BOA' === this.displayMode) {\n return this.ratioColorScale // Don't adjust color scale for A/B.\n }\n\n if (this.colorScaleThresholdCache[colorKey]) {\n const changed = this.colorScale.threshold !== this.colorScaleThresholdCache[colorKey]\n this.colorScale.setThreshold(this.colorScaleThresholdCache[colorKey])\n if (changed) {\n this.browser.eventBus.post(HICEvent(\"ColorScale\", this.colorScale))\n }\n return this.colorScale\n } else {\n try {\n const widthInBP = imageTileDimension * zd.zoom.binSize\n const x0bp = col1 * widthInBP\n const xWidthInBP = (col2 - col1 + 1) * widthInBP\n const region1 = {chr: zd.chr1.name, start: x0bp, end: x0bp + xWidthInBP}\n const y0bp = row1 * widthInBP\n const yWidthInBp = (row2 - row1 + 1) * widthInBP\n const region2 = {chr: zd.chr2.name, start: y0bp, end: y0bp + yWidthInBp}\n const records = await ds.getContactRecords(normalization, region1, region2, zd.zoom.unit, zd.zoom.binSize, true)\n\n let s = computePercentile(records, 95)\n if (!isNaN(s)) { // Can return NaN if all blocks are empty\n if (0 === zd.chr1.index) s *= 4 // Heuristic for whole genome view\n this.colorScale = new ColorScale(this.colorScale)\n this.colorScale.setThreshold(s)\n this.computeColorScale = false\n this.browser.eventBus.post(HICEvent(\"ColorScale\", this.colorScale))\n this.colorScaleThresholdCache[colorKey] = s\n }\n\n return this.colorScale\n } finally {\n this.stopSpinner()\n }\n\n\n }\n\n }\n\n async zoomIn() {\n const state = this.browser.state;\n const viewportWidth = this.viewportElement.offsetWidth;\n const viewportHeight = this.viewportElement.offsetHeight;\n const matrices = await getMatrices.call(this, state.chr1, state.chr2);\n\n const matrix = matrices[0];\n\n if (matrix) {\n const unit = \"BP\";\n const zd = await matrix.getZoomDataByIndex(state.zoom, unit);\n const newGenomicExtent = {\n x: state.x * zd.zoom.binSize,\n y: state.y * zd.zoom.binSize,\n w: viewportWidth * zd.zoom.binSize / state.pixelSize,\n h: viewportHeight * zd.zoom.binSize / state.pixelSize\n };\n\n // Zoom out not supported\n if (newGenomicExtent.w > this.genomicExtent.w) return;\n\n const sx = ((newGenomicExtent.x - this.genomicExtent.x) / this.genomicExtent.w) * viewportWidth;\n const sy = ((newGenomicExtent.y - this.genomicExtent.y) / this.genomicExtent.w) * viewportHeight;\n const sWidth = (newGenomicExtent.w / this.genomicExtent.w) * viewportWidth;\n const sHeight = (newGenomicExtent.h / this.genomicExtent.h) * viewportHeight;\n const img = this.canvasElement;\n\n const backCanvas = document.createElement('canvas');\n backCanvas.width = img.width;\n backCanvas.height = img.height;\n const backCtx = backCanvas.getContext('2d');\n backCtx.drawImage(img, sx, sy, sWidth, sHeight, 0, 0, viewportWidth, viewportHeight);\n\n this.ctx.clearRect(0, 0, viewportWidth, viewportHeight);\n this.ctx.drawImage(backCanvas, 0, 0);\n }\n }\n\n paintTile({image, row, column, blockBinCount}) {\n\n const x0 = blockBinCount * column\n const y0 = blockBinCount * row\n\n const {x, y, pixelSize} = this.browser.state\n //const pixelSizeInt = Math.max(1, Math.floor(pixelSize))\n const offsetX = (x0 - x) * pixelSize\n const offsetY = (y0 - y) * pixelSize\n\n const scale = pixelSize // / pixelSizeInt\n const scaledWidth = image.width * scale\n const scaledHeight = image.height * scale\n\n if (offsetX <= this.viewportElement.offsetWidth && offsetX + scaledWidth >= 0 && offsetY <= this.viewportElement.offsetHeight && offsetY + scaledHeight >= 0) {\n this.ctx.fillStyle = this.backgroundRGBString\n this.ctx.fillRect(offsetX, offsetY, scaledWidth, scaledHeight)\n if (scale === 1) {\n this.ctx.drawImage(image, offsetX, offsetY)\n } else {\n this.ctx.drawImage(image, offsetX, offsetY, scaledWidth, scaledHeight)\n }\n // Debugging aid, uncomment to see tile boundaries\n //this.ctx.strokeRect(offsetX, offsetY, scaledWidth, scaledHeight)\n //this.ctx.strokeText(`${row} ${column}`, offsetX, offsetY);\n }\n }\n\n startSpinner() {\n if (this.browser.isLoadingHICFile && this.browser.userInteractionShield) {\n this.browser.userInteractionShield.style.display = 'block';\n }\n this.faSpinnerElement.style.display = 'inline-block';\n this.spinnerCount++;\n }\n\n stopSpinner() {\n this.spinnerCount--;\n if (this.spinnerCount === 0) {\n this.faSpinnerElement.style.display = 'none';\n }\n this.spinnerCount = Math.max(0, this.spinnerCount); // This should not be necessary\n }\n\n addMouseHandlers(viewportElement) {\n\n let startX = 0;\n let startY = 0;\n let currentX = 0;\n let currentY = 0;\n\n let isMouseDown = false;\n let isSweepZooming = false;\n let mouseDown\n let mouseLast\n let mouseOver;\n\n const panMouseUpOrMouseOut = () => {\n if (this.isDragging) {\n this.isDragging = false;\n this.browser.eventBus.post(HICEvent(\"DragStopped\"));\n }\n isMouseDown = false;\n mouseDown = mouseLast = undefined;\n };\n\n this.isDragging = false;\n\n if (!this.browser.isMobile) {\n\n viewportElement.addEventListener('mousedown', (e) => {\n e.preventDefault();\n e.stopPropagation();\n\n if (this.browser.menuElement?.style.display === 'block') {\n this.browser.hideMenu();\n }\n\n mouseLast = { x: e.offsetX, y: e.offsetY };\n mouseDown = { x: e.offsetX, y: e.offsetY };\n\n if (e.altKey) {\n isSweepZooming = true\n\n const { top, left } = viewportElement.getBoundingClientRect()\n startX = e.clientX - left\n startY = e.clientY - top\n\n this.sweepZoom.initialize(startX, startY);\n }\n\n isMouseDown = true;\n })\n\n viewportElement.addEventListener('mousemove', (e) => {\n\n e.preventDefault();\n e.stopPropagation();\n\n const coords =\n {\n x: e.offsetX,\n y: e.offsetY\n };\n\n const { top, left } = getOffset(viewportElement)\n\n const xy =\n {\n x: e.pageX - left,\n y: e.pageY - top\n };\n\n const { width, height } = viewportElement.getBoundingClientRect();\n xy.xNormalized = xy.x / width;\n xy.yNormalized = xy.y / height;\n\n this.browser.eventBus.post(HICEvent(\"UpdateContactMapMousePosition\", xy, false));\n\n if (this.willShowCrosshairs) {\n this.browser.updateCrosshairs(xy);\n this.browser.showCrosshairs();\n }\n\n if (isMouseDown) {\n if (isSweepZooming) {\n\n const { left, top } = viewportElement.getBoundingClientRect();\n currentX = e.clientX - left;\n currentY = e.clientY - top;\n const width = Math.abs(currentX - startX);\n const height = Math.abs(currentY - startY);\n\n const config =\n {\n left: `${Math.min(startX, currentX)}px`,\n top: `${Math.min(startY, currentY)}px`,\n width: `${width}px`,\n height: `${height}px`,\n }\n\n\n this.sweepZoom.update(config);\n\n } else if (mouseDown.x && Math.abs(coords.x - mouseDown.x) > DRAG_THRESHOLD) {\n this.isDragging = true;\n const dx = mouseLast.x - coords.x;\n const dy = mouseLast.y - coords.y;\n this.browser.shiftPixels(dx, dy);\n }\n mouseLast = coords;\n }\n })\n\n viewportElement.addEventListener('mouseup', panMouseUpOrMouseOut)\n\n viewportElement.addEventListener('dblclick', (e) => {\n e.preventDefault();\n e.stopPropagation();\n const mouseX = e.offsetX;\n const mouseY = e.offsetY;\n this.browser.zoomAndCenter(1, mouseX, mouseY);\n })\n\n viewportElement.addEventListener('mouseover', () => mouseOver = true)\n viewportElement.addEventListener('mouseout', () => mouseOver = undefined)\n\n\n viewportElement.addEventListener('mouseleave', () => {\n this.browser.layoutController.xAxisRuler.unhighlightWholeChromosome();\n this.browser.layoutController.yAxisRuler.unhighlightWholeChromosome();\n panMouseUpOrMouseOut();\n })\n\n document.addEventListener('keydown', (e) => {\n if (!this.willShowCrosshairs && mouseOver && e.shiftKey) {\n this.willShowCrosshairs = true;\n this.browser.eventBus.post(HICEvent('DidShowCrosshairs', 'DidShowCrosshairs', false));\n }\n })\n\n document.addEventListener('keyup', () => {\n this.browser.hideCrosshairs();\n this.willShowCrosshairs = undefined;\n this.browser.eventBus.post(HICEvent('DidHideCrosshairs', 'DidHideCrosshairs', false));\n })\n\n document.addEventListener('mouseup', (e) => {\n e.preventDefault();\n e.stopPropagation();\n\n if (isSweepZooming) {\n isSweepZooming = false;\n\n const sweepRect =\n {\n xPixel: Math.min(startX, currentX),\n yPixel: Math.min(startY, currentY),\n width: Math.abs(currentX - startX),\n height: Math.abs(currentY - startY)\n };\n\n this.sweepZoom.commit(sweepRect)\n }\n })\n }\n }\n\n /**\n * Add touch handlers. Touches are mapped to one of the following application level events\n * - double tap, equivalent to double click\n * - move\n * - pinch\n *\n * @param $viewport\n */\n\n addTouchHandlers(viewportElement) {\n let lastTouch, pinch;\n\n const translateTouchCoordinates = (e, target) => {\n const rect = target.getBoundingClientRect();\n return {\n x: e.pageX - rect.left,\n y: e.pageY - rect.top\n };\n };\n\n viewportElement.ontouchstart = (ev) => {\n ev.preventDefault();\n ev.stopPropagation();\n\n let touchCoords = translateTouchCoordinates(ev.targetTouches[0], viewportElement);\n let offsetX = touchCoords.x;\n let offsetY = touchCoords.y;\n const count = ev.targetTouches.length;\n const timeStamp = ev.timeStamp || Date.now();\n let resolved = false;\n\n if (count === 2) {\n touchCoords = translateTouchCoordinates(ev.targetTouches[1], viewportElement);\n offsetX = (offsetX + touchCoords.x) / 2;\n offsetY = (offsetY + touchCoords.y) / 2;\n }\n\n if (lastTouch && (timeStamp - lastTouch.timeStamp < DOUBLE_TAP_TIME_THRESHOLD) && count > 1 && lastTouch.count === 1) {\n lastTouch = { x: offsetX, y: offsetY, timeStamp, count };\n return;\n }\n\n if (lastTouch && (timeStamp - lastTouch.timeStamp < DOUBLE_TAP_TIME_THRESHOLD)) {\n const dx = lastTouch.x - offsetX;\n const dy = lastTouch.y - offsetY;\n const dist = Math.hypot(dx, dy);\n const direction = (lastTouch.count === 2 || count === 2) ? -1 : 1;\n\n if (dist < DOUBLE_TAP_DIST_THRESHOLD) {\n this.browser.zoomAndCenter(direction, offsetX, offsetY);\n lastTouch = undefined;\n resolved = true;\n }\n }\n\n if (!resolved) {\n lastTouch = { x: offsetX, y: offsetY, timeStamp, count };\n }\n };\n\n viewportElement.ontouchmove = hicUtils.throttle((ev) => {\n ev.preventDefault();\n ev.stopPropagation();\n\n if (ev.targetTouches.length === 2) {\n const touchCoords1 = translateTouchCoordinates(ev.targetTouches[0], viewportElement);\n const touchCoords2 = translateTouchCoordinates(ev.targetTouches[1], viewportElement);\n\n const t = {\n x1: touchCoords1.x,\n y1: touchCoords1.y,\n x2: touchCoords2.x,\n y2: touchCoords2.y\n };\n\n pinch ? (pinch.end = t) : (pinch = { start: t });\n } else {\n const touchCoords = translateTouchCoordinates(ev.targetTouches[0], viewportElement);\n const offsetX = touchCoords.x;\n const offsetY = touchCoords.y;\n\n if (lastTouch) {\n const dx = lastTouch.x - offsetX;\n const dy = lastTouch.y - offsetY;\n if (!isNaN(dx) && !isNaN(dy)) {\n this.isDragging = true;\n this.browser.shiftPixels(dx, dy);\n }\n }\n\n lastTouch = {\n x: offsetX,\n y: offsetY,\n timeStamp: ev.timeStamp || Date.now(),\n count: ev.targetTouches.length\n };\n }\n }, 50);\n\n viewportElement.ontouchend = (ev) => {\n ev.preventDefault();\n ev.stopPropagation();\n\n if (pinch && pinch.end) {\n const { start, end } = pinch;\n const dxStart = start.x2 - start.x1;\n const dyStart = start.y2 - start.y1;\n const dxEnd = end.x2 - end.x1;\n const dyEnd = end.y2 - end.y1;\n\n const distStart = Math.hypot(dxStart, dyStart);\n const distEnd = Math.hypot(dxEnd, dyEnd);\n const scale = distEnd / distStart;\n\n const anchorX = (start.x1 + start.x2) / 2;\n const anchorY = (start.y1 + start.y2) / 2;\n\n if (scale < 0.8 || scale > 1.2) {\n lastTouch = undefined;\n this.browser.pinchZoom(anchorX, anchorY, scale);\n }\n } else if (this.isDragging) {\n this.isDragging = false;\n this.browser.eventBus.post(HICEvent(\"DragStopped\"));\n }\n\n pinch = undefined;\n };\n }\n\n async render2DTracks(track2DList, dataset, state) {\n\n const matrix = await dataset.getMatrix(state.chr1, state.chr2)\n const zoomData = matrix.getZoomDataByIndex(state.zoom, 'BP')\n\n const { width, height } = this.getViewDimensions()\n const bpPerPixel = zoomData.zoom.binSize/state.pixelSize\n const { xStartBP, yStartBP, xEndBP, yEndBP } = getLocus(dataset, state, width, height, bpPerPixel)\n\n const chr1Name = zoomData.chr1.name\n const chr2Name = zoomData.chr2.name\n\n const sameChr = zoomData.chr1.index === zoomData.chr2.index\n\n this.ctx.save()\n this.ctx.lineWidth = 2\n\n const renderFeatures = (xS, xE, yS, yE) => {\n\n if (xE < xStartBP || xS > xEndBP || yE < yStartBP || yS > yEndBP) {\n // trivially reject\n } else {\n const w = Math.max(1, (xE - xS)/bpPerPixel)\n const h = Math.max(1, (yE - yS)/bpPerPixel)\n const x = Math.floor((xS - xStartBP)/bpPerPixel)\n const y = Math.floor((yS - yStartBP)/bpPerPixel)\n this.ctx.strokeRect(x, y, w, h)\n }\n\n }\n\n const renderLowerFeatures = (track2D, features) => {\n for (const { chr1, x1:xS, x2:xE, y1:yS, y2:yE, color } of features) {\n\n const flip = chr1Name !== chr1\n\n this.ctx.strokeStyle = track2D.color || color\n renderFeatures(xS, xE, yS, yE)\n }\n }\n\n const renderUpperFeatures = (track2D, features) => {\n for (const { chr1, x1:yS, x2:yE, y1:xS, y2:xE, color } of features) {\n\n const flip = chr1Name !== chr1\n\n this.ctx.strokeStyle = track2D.color || color\n renderFeatures(xS, xE, yS, yE)\n }\n }\n\n for (const track2D of track2DList) {\n\n if (false === track2D.isVisible) {\n continue\n }\n\n const features = track2D.getFeatures(zoomData.chr1.name, zoomData.chr1.name)\n\n if (features) {\n\n if ('COLLAPSED' === track2D.displayMode || undefined === track2D.displayMode) {\n renderLowerFeatures(track2D, features)\n renderUpperFeatures(track2D, features)\n } else if ('lower' === track2D.displayMode) {\n renderLowerFeatures(track2D, features)\n } else if ('upper' === track2D.displayMode) {\n renderUpperFeatures(track2D, features)\n }\n\n }\n\n\n }\n\n this.ctx.restore()\n\n }\n}\n\nContactMatrixView.defaultBackgroundColor = {r: 255, g: 255, b: 255}\n\nfunction colorScaleKey(state, displayMode) {\n return \"\" + state.chr1 + \"_\" + state.chr2 + \"_\" + state.zoom + \"_\" + state.normalization + \"_\" + displayMode\n}\n\n/**\n * Returns a promise for an image tile\n *\n * @param zd\n * @param row\n * @param column\n * @param state\n * @returns {*}\n */\n\nconst inProgressCache = {}\n\nfunction inProgressTile(imageSize) {\n\n let image = inProgressCache[imageSize]\n if (!image) {\n image = document.createElement('canvas')\n image.width = imageSize\n image.height = imageSize\n const ctx = image.getContext('2d')\n ctx.font = '24px sans-serif'\n ctx.fillStyle = 'rgb(230, 230, 230)'\n ctx.fillRect(0, 0, image.width, image.height)\n ctx.fillStyle = 'black'\n for (let i = 100; i < imageSize; i += 300) {\n for (let j = 100; j < imageSize; j += 300) {\n ctx.fillText('Loading...', i, j)\n }\n }\n inProgressCache[imageSize] = image\n }\n return image\n}\n\nfunction getMatrices(chr1, chr2) {\n\n var promises = []\n if ('B' === this.displayMode && this.browser.controlDataset) {\n promises.push(this.browser.controlDataset.getMatrix(chr1, chr2))\n } else {\n promises.push(this.browser.dataset.getMatrix(chr1, chr2))\n if (this.displayMode && 'A' !== this.displayMode && this.browser.controlDataset) {\n promises.push(this.browser.controlDataset.getMatrix(chr1, chr2))\n }\n }\n return Promise.all(promises)\n}\n\nfunction computePercentile(records, p) {\n const counts = records.map(r => r.counts)\n counts.sort(function (a, b) {\n return a - b\n })\n const idx = Math.floor((p / 100) * records.length)\n return counts[idx]\n\n // return HICMath.percentile(array, p);\n}\n\nexport default ContactMatrixView\n","function getLocus(dataset, state, width, height, bpPerPixel){\n\n // bp/bin = (bp/pixel) * (pixel/bin) = bp\n const bpPerBin = bpPerPixel * state.pixelSize\n\n // bp = bin * bp / bin = bp\n const xStartBP = 1 + Math.round(state.x * bpPerBin)\n const yStartBP = 1 + Math.round(state.y * bpPerBin)\n\n const chromosome1 = dataset.chromosomes[state.chr1]\n const chromosome2 = dataset.chromosomes[state.chr2]\n\n // bp = (pixel * bin/pixel) * (bp/bin)\n // bp = bin * bp/bin = bp\n const widthBP = Math.round(bpPerPixel * width)\n const heightBP = Math.round(bpPerPixel * height)\n\n // bp = bp\n const xEndBP = Math.min(chromosome1.size, widthBP + xStartBP - 1)\n const yEndBP = Math.min(chromosome2.size, heightBP + yStartBP - 1)\n\n return { xStartBP, yStartBP, xEndBP, yEndBP, chromosome1, chromosome2, pixelSize:state.pixelSize }\n\n}\n\nexport { getLocus }\n","/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2016-2017 The Regents of the University of California\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and\n * associated documentation files (the \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the\n * following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all copies or substantial\n * portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING\n * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n *\n */\n\n/**\n * Created by dat on 3/3/17.\n */\nimport { IGVColor, StringUtils } from '../node_modules/igv-utils/src/index.js';\nimport { DOMUtils, ColorPicker } from '../node_modules/igv-ui/dist/igv-ui.js';\nimport RatioColorScale, { defaultRatioColorScaleConfig } from './ratioColorScale.js';\nimport ContactMatrixView from \"./contactMatrixView.js\";\nimport ColorScale from \"./colorScale.js\";\nimport {parseRgbString} from \"./utils.js\"\n\nclass ColorScaleWidget {\n\n constructor(browser, hicNavbarContainer) {\n this.browser = browser;\n\n const container = hicNavbarContainer.querySelector(\"div[id$='lower-hic-nav-bar-widget-container']\");\n\n this.container = document.createElement('div');\n this.container.className = 'hic-colorscale-widget-container';\n container.appendChild(this.container);\n\n const { r: _r, g: _g, b: _b } = ContactMatrixView.defaultBackgroundColor;\n this.mapBackgroundColorpickerButton = colorSwatch(IGVColor.rgbColor(_r, _g, _b));\n this.container.appendChild(this.mapBackgroundColorpickerButton);\n this.backgroundColorpicker = createColorPicker(browser, this.mapBackgroundColorpickerButton);\n\n const { r: nr, g: ng, b: nb } = defaultRatioColorScaleConfig.negative;\n this.minusButton = colorSwatch(IGVColor.rgbColor(nr, ng, nb));\n this.container.appendChild(this.minusButton);\n this.minusColorPicker = createColorPicker(browser, this.minusButton, '-');\n this.minusButton.style.display = 'none';\n\n const { r, g, b } = defaultRatioColorScaleConfig.positive;\n this.plusButton = colorSwatch(IGVColor.rgbColor(r, g, b));\n this.container.appendChild(this.plusButton);\n this.plusColorPicker = createColorPicker(browser, this.plusButton, '+');\n\n this.minusButton.addEventListener('click', () => presentColorPicker(this.minusColorPicker, this.plusColorPicker, this.backgroundColorpicker));\n this.plusButton.addEventListener('click', () => presentColorPicker(this.plusColorPicker, this.minusColorPicker, this.backgroundColorpicker));\n this.mapBackgroundColorpickerButton.addEventListener('click', () => presentColorPicker(this.backgroundColorpicker, this.minusColorPicker, this.plusColorPicker));\n\n this.highColorscaleInput = document.createElement('input');\n this.highColorscaleInput.type = 'text';\n this.highColorscaleInput.title = 'color scale input';\n this.container.appendChild(this.highColorscaleInput);\n this.highColorscaleInput.addEventListener('change', (e) => {\n const numeric = StringUtils.numberUnFormatter(e.target.value);\n if (!isNaN(numeric)) {\n browser.setColorScaleThreshold(numeric);\n }\n });\n\n const minusIcon = createIconButton('fa-minus', 'negative threshold', () => this.highColorscaleInput.value = updateThreshold(browser, 0.5));\n this.container.appendChild(minusIcon);\n\n const plusIcon = createIconButton('fa-plus', 'positive threshold', () => this.highColorscaleInput.value = updateThreshold(browser, 2.0));\n this.container.appendChild(plusIcon);\n\n browser.eventBus.subscribe(\"ColorScale\", (event) => {\n if (event.data instanceof ColorScale) {\n this.highColorscaleInput.value = event.data.threshold;\n paintSwatch(this.plusButton, event.data);\n } else if (event.data instanceof RatioColorScale) {\n this.highColorscaleInput.value = event.data.threshold;\n paintSwatch(this.minusButton, event.data.negativeScale);\n paintSwatch(this.plusButton, event.data.positiveScale);\n }\n });\n\n browser.eventBus.subscribe(\"DisplayMode\", (event) => {\n if (event.data === \"AOB\" || event.data === \"BOA\") {\n this.minusButton.style.display = 'block';\n paintSwatch(this.minusButton, browser.contactMatrixView.ratioColorScale.negativeScale);\n paintSwatch(this.plusButton, browser.contactMatrixView.ratioColorScale.positiveScale);\n } else {\n this.minusButton.style.display = 'none';\n paintSwatch(this.plusButton, browser.contactMatrixView.colorScale);\n }\n });\n\n browser.eventBus.subscribe(\"MapLoad\", () => {\n paintSwatch(this.mapBackgroundColorpickerButton, browser.contactMatrixView.backgroundColor);\n });\n }\n}\n\nfunction paintSwatch(swatch, { r, g, b }) {\n swatch.style.backgroundColor = IGVColor.rgbToHex(IGVColor.rgbColor(r, g, b));\n}\n\nfunction updateThreshold(browser, scaleFactor) {\n const colorScale = browser.getColorScale();\n browser.setColorScaleThreshold(colorScale.getThreshold() * scaleFactor);\n return StringUtils.numberFormatter(colorScale.getThreshold());\n}\n\nfunction createColorPicker(browser, parent, type) {\n let defaultColors, colorHandler;\n if (!type) {\n const { r, g, b } = ContactMatrixView.defaultBackgroundColor;\n defaultColors = [IGVColor.rgbToHex(IGVColor.rgbColor(r, g, b))];\n colorHandler = (hex) => {\n parent.style.backgroundColor = hex;\n const rgbString = IGVColor.hexToRgb(hex)\n const [r, g, b] = parseRgbString(rgbString)\n browser.contactMatrixView.setBackgroundColor({ r, g, b });\n };\n } else {\n defaultColors = [defaultRatioColorScaleConfig.negative, defaultRatioColorScaleConfig.positive].map(({ r, g, b }) => IGVColor.rgbToHex(IGVColor.rgbColor(r, g, b)));\n colorHandler = (hex) => {\n parent.style.backgroundColor = hex;\n const rgbString = IGVColor.hexToRgb(hex)\n const [r, g, b] = parseRgbString(rgbString)\n browser.getColorScale().setColorComponents({ r, g, b }, type);\n browser.repaintMatrix();\n };\n }\n return new ColorPicker({ parent, top: 64, left: 64, width: 432, defaultColors, colorHandler });\n}\n\nfunction presentColorPicker(presentable, hideableA, hideableB) {\n hideableA.hide()\n hideableB.hide()\n presentable.show()\n}\n\nfunction colorSwatch(rgbString) {\n const swatch = DOMUtils.div({ class: 'igv-ui-color-swatch' });\n swatch.style.backgroundColor = IGVColor.rgbToHex(rgbString);\n return swatch;\n}\n\nfunction createIconButton(iconClass, title, onClick) {\n const icon = document.createElement('i');\n icon.className = `fa ${iconClass}`;\n icon.title = title;\n icon.addEventListener('click', onClick);\n return icon;\n}\n\nexport default ColorScaleWidget;\n","/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2016-2017 The Regents of the University of California\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and\n * associated documentation files (the \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the\n * following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all copies or substantial\n * portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING\n * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n *\n */\n\n/**\n * Created by dat on 3/21/17.\n */\n\nclass ControlMapWidget {\n\n constructor(browser, hicNavbarContainer) {\n this.browser = browser;\n\n const parent = hicNavbarContainer.querySelector(\"div[id$='lower-hic-nav-bar-widget-container']\");\n\n this.container = document.createElement('div');\n this.container.className = 'hic-control-map-selector-container';\n this.container.style.display = 'none';\n parent.appendChild(this.container);\n\n this.select = document.createElement('select');\n this.select.name = 'control_map_selector';\n this.container.appendChild(this.select);\n\n const toggleContainer = document.createElement('div');\n this.container.appendChild(toggleContainer);\n\n const cycleContainer = document.createElement('div');\n this.container.appendChild(cycleContainer);\n\n this.controlMapHash = new ControlMapHash(browser, this.select, toggleContainer, cycleContainer, toggleArrowsUp(), toggleArrowsDown());\n\n browser.eventBus.subscribe(\"ControlMapLoad\", () => {\n this.controlMapHash.updateOptions(browser.getDisplayMode());\n this.container.style.display = 'block';\n });\n\n browser.eventBus.subscribe(\"MapLoad\", () => {\n if (!browser.controlDataset) {\n this.container.style.display = 'none';\n }\n });\n\n browser.eventBus.subscribe(\"DisplayMode\", (event) => {\n this.controlMapHash.updateOptions(event.data);\n });\n }\n\n toggleDisplayMode() {\n this.controlMapHash.toggleDisplayMode();\n }\n\n toggleDisplayModeCycle() {\n this.controlMapHash.toggleDisplayModeCycle();\n }\n\n getDisplayModeCycle() {\n return this.controlMapHash.cycleID;\n }\n}\n\nclass ControlMapHash {\n\n constructor(browser, select, toggle, cycle, imgA, imgB) {\n this.browser = browser;\n this.select = select;\n this.toggle = toggle;\n this.cycle = cycle;\n\n this.imgA = imgA;\n this.toggle.appendChild(this.imgA);\n\n this.imgB = imgB;\n this.toggle.appendChild(this.imgB);\n\n this.hash = {\n 'A': { title: 'A', value: 'A', other: 'B', hidden: this.imgB, shown: this.imgA },\n 'B': { title: 'B', value: 'B', other: 'A', hidden: this.imgA, shown: this.imgB },\n 'AOB': { title: 'A/B', value: 'AOB', other: 'BOA', hidden: this.imgB, shown: this.imgA },\n 'BOA': { title: 'B/A', value: 'BOA', other: 'AOB', hidden: this.imgA, shown: this.imgB }\n };\n\n this.select.addEventListener('change', (e) => {\n this.disableDisplayModeCycle();\n this.setDisplayMode(e.target.value);\n });\n\n this.toggle.addEventListener('click', () => {\n this.disableDisplayModeCycle();\n this.toggleDisplayMode();\n });\n\n this.cycleOutline = cycleOutline();\n cycle.appendChild(this.cycleOutline);\n\n this.cycleSolid = cycleSolid();\n cycle.appendChild(this.cycleSolid);\n this.cycleSolid.style.display = 'none';\n\n cycle.addEventListener('click', () => {\n this.toggleDisplayModeCycle();\n });\n\n cycle.style.display = 'none';\n }\n\n disableDisplayModeCycle() {\n if (this.cycleID) {\n clearTimeout(this.cycleID);\n this.cycleID = undefined;\n this.cycleSolid.style.display = 'none';\n this.cycleOutline.style.display = 'block';\n }\n }\n\n toggleDisplayModeCycle() {\n if (this.cycleID) {\n this.disableDisplayModeCycle();\n } else {\n this.doToggle();\n this.cycleSolid.style.display = 'block';\n this.cycleOutline.style.display = 'none';\n }\n }\n\n async doToggle() {\n this.cycleID = setTimeout(async () => {\n await this.toggleDisplayMode();\n this.doToggle();\n }, 2500);\n }\n\n async toggleDisplayMode() {\n const oldMode = this.browser.getDisplayMode();\n const newMode = this.hash[oldMode].other;\n await this.browser.setDisplayMode(newMode);\n this.hash[newMode].hidden.style.display = 'none';\n this.hash[newMode].shown.style.display = 'block';\n this.select.value = newMode;\n }\n\n setDisplayMode(mode) {\n this.hash[mode].hidden.style.display = 'none';\n this.hash[mode].shown.style.display = 'block';\n this.browser.setDisplayMode(mode);\n }\n\n updateOptions(displayMode) {\n this.imgA.style.display = 'none';\n this.imgB.style.display = 'none';\n this.select.innerHTML = '';\n\n Object.keys(this.hash).forEach((key) => {\n const item = this.hash[key];\n const option = document.createElement('option');\n option.value = item.value;\n option.textContent = item.title;\n if (displayMode === item.value) {\n option.selected = true;\n item.shown.style.display = 'block';\n }\n this.select.appendChild(option);\n });\n }\n}\n\nfunction toggleArrowsUp() {\n const svg = document.createElement('div');\n svg.innerHTML = '...'; // Simplified for brevity\n return svg;\n}\n\nfunction toggleArrowsDown() {\n const svg = document.createElement('div');\n svg.innerHTML = '...'; // Simplified for brevity\n return svg;\n}\n\nfunction cycleOutline() {\n const svg = document.createElement('div');\n svg.innerHTML = '...'; // Simplified for brevity\n return svg;\n}\n\nfunction cycleSolid() {\n const svg = document.createElement('div');\n svg.innerHTML = '...'; // Simplified for brevity\n return svg;\n}\n\nexport default ControlMapWidget;\n","/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2016-2017 The Regents of the University of California\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and\n * associated documentation files (the \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the\n * following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all copies or substantial\n * portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING\n * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n *\n */\n\n/**\n * Created by dat on 3/21/17.\n */\nclass NormalizationWidget {\n\n constructor(browser, hicNavBarContainer) {\n this.browser = browser;\n\n const parent = hicNavBarContainer.querySelector(\"div[id$='lower-hic-nav-bar-widget-container']\");\n\n this.container = document.createElement('div');\n this.container.className = 'hic-normalization-selector-container';\n this.container.title = 'Normalization';\n parent.appendChild(this.container);\n\n let label = document.createElement('div');\n label.textContent = 'Norm';\n this.container.appendChild(label);\n\n this.normalizationSelector = document.createElement('select');\n this.normalizationSelector.name = 'normalization_selector';\n this.normalizationSelector.addEventListener('change', () => {\n this.browser.setNormalization(this.normalizationSelector.value);\n });\n this.container.appendChild(this.normalizationSelector);\n\n this.spinner = document.createElement('div');\n this.spinner.textContent = 'Loading ...';\n this.container.appendChild(this.spinner);\n this.spinner.style.display = 'none';\n\n this.browser.eventBus.subscribe(\"MapLoad\", this);\n this.browser.eventBus.subscribe(\"NormVectorIndexLoad\", this);\n this.browser.eventBus.subscribe(\"NormalizationFileLoad\", this);\n this.browser.eventBus.subscribe(\"NormalizationExternalChange\", this);\n }\n\n startNotReady() {\n this.normalizationSelector.style.display = 'none';\n this.spinner.style.display = 'block';\n }\n\n stopNotReady() {\n this.spinner.style.display = 'none';\n this.normalizationSelector.style.display = 'block';\n }\n\n receiveEvent(event) {\n if (\"NormVectorIndexLoad\" === event.type) {\n this.updateOptions();\n this.stopNotReady();\n } else if (\"NormalizationFileLoad\" === event.type) {\n if (event.data === \"start\") {\n this.startNotReady();\n } else {\n this.stopNotReady();\n }\n } else if (\"NormalizationExternalChange\" === event.type) {\n Array.from(this.normalizationSelector.options).forEach(option => {\n option.selected = option.value === event.data;\n });\n }\n }\n\n async updateOptions() {\n const labels = {\n NONE: 'None',\n VC: 'Coverage',\n VC_SQRT: 'Coverage - Sqrt',\n KR: 'Balanced',\n INTER_VC: 'Interchromosomal Coverage',\n INTER_VC_SQRT: 'Interchromosomal Coverage - Sqrt',\n INTER_KR: 'Interchromosomal Balanced',\n GW_VC: 'Genome-wide Coverage',\n GW_VC_SQRT: 'Genome-wide Coverage - Sqrt',\n GW_KR: 'Genome-wide Balanced'\n };\n\n const norm = this.browser.state.normalization;\n const normalizationTypes = await this.browser.getNormalizationOptions();\n if (normalizationTypes) {\n this.normalizationSelector.innerHTML = '';\n normalizationTypes.forEach(normalization => {\n const option = document.createElement('option');\n option.value = normalization;\n option.textContent = labels[normalization] || normalization;\n if (norm === normalization) {\n option.selected = true;\n }\n this.normalizationSelector.appendChild(option);\n });\n }\n }\n}\n\nexport default NormalizationWidget;\n","/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2016-2017 The Regents of the University of California\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and\n * associated documentation files (the \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the\n * following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all copies or substantial\n * portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING\n * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n *\n */\n\nclass SweepZoom {\n\n constructor(browser, targetElement) {\n this.browser = browser;\n this.targetElement = targetElement;\n\n this.rulerSweeperElement = targetElement.querySelector(\"div[id$='-sweep-zoom-container']\");\n this.rulerSweeperElement.style.display = 'none';\n\n this.sweepRect = {};\n }\n\n initialize(startX, startY) {\n this.rulerSweeperElement.style.left = `${startX}px`;\n this.rulerSweeperElement.style.top = `${startY}px`;\n this.rulerSweeperElement.style.width = '0px';\n this.rulerSweeperElement.style.height = '0px';\n this.rulerSweeperElement.style.display = 'block';\n }\n\n update({ left, top, width, height }) {\n this.rulerSweeperElement.style.width = width\n this.rulerSweeperElement.style.height = height\n this.rulerSweeperElement.style.left = left\n this.rulerSweeperElement.style.top = top\n }\n\n commit({ xPixel, yPixel, width, height }) {\n\n this.rulerSweeperElement.style.display = 'none';\n\n const { x, y, locus, zoom, pixelSize } = this.browser.state;\n\n // bp-per-bin\n const bpResolution = this.browser.dataset.bpResolutions[zoom];\n\n // bp = ((bin + pixel/pixel-per-bin) / bp-per-bin)\n const xBP = (x + (xPixel / pixelSize)) * bpResolution\n const yBP = (y + (yPixel / pixelSize)) * bpResolution\n\n const widthBP = ( width / pixelSize) * bpResolution;\n const heightBP = (height / pixelSize) * bpResolution;\n\n this.browser.goto(locus.x.chr, Math.round(xBP), Math.round(xBP + widthBP), locus.y.chr, Math.round(yBP), Math.round(yBP + heightBP));\n\n }\n}\n\nexport default SweepZoom\n","/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2016-2017 The Regents of the University of California\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and\n * associated documentation files (the \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the\n * following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all copies or substantial\n * portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING\n * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n *\n */\n\nclass ScrollbarWidget {\n\n constructor(browser, xAxisScrollbarContainerElement, yAxisScrollbarContainerElement) {\n this.browser = browser;\n this.isDragging = false;\n\n // x-axis\n this.xAxisScrollbarContainerElement = xAxisScrollbarContainerElement;\n this.xAxisScrollbarElement = xAxisScrollbarContainerElement.querySelector(\"div[id$='-x-axis-scrollbar']\");\n this.xLabelElement = this.xAxisScrollbarElement.querySelector('div');\n this.xLabelElement.textContent = '';\n\n // y-axis\n this.yAxisScrollbarContainerElement = yAxisScrollbarContainerElement;\n this.yAxisScrollbarElement = yAxisScrollbarContainerElement.querySelector(\"div[id$='-y-axis-scrollbar']\");\n this.yLabelElement = this.yAxisScrollbarElement.querySelector('.scrollbar-label-rotation-in-place');\n this.yLabelElement.textContent = '';\n\n this.browser.eventBus.subscribe(\"LocusChange\", this);\n }\n\n receiveEvent(event) {\n\n if (!this.isDragging && event.type === \"LocusChange\") {\n const { state } = event.data;\n const { dataset } = this.browser;\n\n if (state.chr1 === 0) {\n this.xAxisScrollbarElement.style.display = 'none';\n this.yAxisScrollbarElement.style.display = 'none';\n } else {\n this.xAxisScrollbarElement.style.display = 'block';\n this.yAxisScrollbarElement.style.display = 'block';\n\n this.xAxisScrollbarContainerElement.style.display = 'block';\n this.yAxisScrollbarContainerElement.style.display = 'block';\n\n const { chr1, chr2, zoom, pixelSize, x, y } = state;\n\n const chromosomeLengthsBin = [chr1, chr2].map(chr => dataset.chromosomes[chr].size / dataset.bpResolutions[zoom]);\n const chromosomeLengthsPixel = chromosomeLengthsBin.map(bin => bin * pixelSize);\n const { width, height } = this.browser.contactMatrixView.getViewDimensions();\n const pixels = [width, height];\n\n const bins = pixels.map(pixel => pixel / pixelSize);\n\n const percentages = bins.map((bin, i) => {\n const binPercentage = Math.min(bin, chromosomeLengthsBin[i]) / chromosomeLengthsBin[i];\n const pixelPercentage = Math.min(chromosomeLengthsPixel[i], pixels[i]) / pixels[i];\n return Math.max(1, Math.round(100 * binPercentage * pixelPercentage));\n });\n\n this.xAxisScrollbarElement.style.width = `${percentages[0]}%`;\n this.yAxisScrollbarElement.style.height = `${percentages[1]}%`;\n\n const xPercentage = Math.round(100 * x / chromosomeLengthsBin[0]);\n this.xAxisScrollbarElement.style.left = `${xPercentage}%`;\n\n const yPercentage = Math.round(100 * y / chromosomeLengthsBin[1]);\n this.yAxisScrollbarElement.style.top = `${yPercentage}%`;\n\n this.xLabelElement.textContent = dataset.chromosomes[chr1].name;\n this.yLabelElement.textContent = dataset.chromosomes[chr2].name;\n }\n }\n }\n\n}\n\nexport default ScrollbarWidget\n","/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2016-2017 The Regents of the University of California\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and\n * associated documentation files (the \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the\n * following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all copies or substantial\n * portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING\n * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n *\n */\n\n/**\n * Creates and manages the chromosome selector UI component\n */\nclass ChromosomeSelector {\n constructor(browser, container) {\n this.browser = browser;\n this.container = container;\n this.xAxisSelector = container.querySelector(\"select[name='x-axis-selector']\");\n this.yAxisSelector = container.querySelector(\"select[name='y-axis-selector']\");\n\n this.initialize();\n }\n\n initialize() {\n // Sync selectors when either changes\n this.xAxisSelector.addEventListener('change', () => this.syncSelectors(this.xAxisSelector, this.yAxisSelector));\n this.yAxisSelector.addEventListener('change', () => this.syncSelectors(this.yAxisSelector, this.xAxisSelector));\n\n // Handle chromosome swap button click\n const nextDiv = this.yAxisSelector.nextElementSibling;\n if (nextDiv) {\n nextDiv.addEventListener('click', async () => {\n const chrX = this.browser.dataset.chromosomes[parseInt(this.xAxisSelector.value, 10)];\n const chrY = this.browser.dataset.chromosomes[parseInt(this.yAxisSelector.value, 10)];\n\n const xLocus = this.browser.parseLocusString(chrX.name);\n const yLocus = this.browser.parseLocusString(chrY.name);\n\n await this.browser.setChromosomes(xLocus, yLocus);\n });\n }\n\n // Subscribe to browser events\n this.browser.eventBus.subscribe(\"MapLoad\", (event) => {\n this.respondToDataLoadWithDataset(event.data);\n });\n\n this.browser.eventBus.subscribe(\"LocusChange\", (event) => {\n this.respondToLocusChangeWithState(event.data.state);\n });\n }\n\n syncSelectors(sourceSelector, targetSelector) {\n const value = sourceSelector.value;\n if (parseInt(value, 10) === 0 || parseInt(targetSelector.value, 10) === 0) {\n targetSelector.value = value;\n }\n }\n\n respondToDataLoadWithDataset(dataset) {\n const { chromosomes } = dataset;\n const options = chromosomes.map(({ name }, index) => ``).join('');\n this.xAxisSelector.innerHTML = options;\n this.yAxisSelector.innerHTML = options;\n\n this.xAxisSelector.value = this.browser.state.chr1;\n this.yAxisSelector.value = this.browser.state.chr2;\n }\n\n respondToLocusChangeWithState(state) {\n if (!this.xAxisSelector.options.length || !this.yAxisSelector.options.length) return;\n\n this.xAxisSelector.value = state.chr1;\n this.yAxisSelector.value = state.chr2;\n }\n}\n\nexport default ChromosomeSelector; ","/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2016-2017 The Regents of the University of California\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and\n * associated documentation files (the \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the\n * following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all copies or substantial\n * portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING\n * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n *\n */\n\nimport { Alert, createColorSwatchSelector } from '../node_modules/igv-ui/dist/igv-ui.js';\nimport { makeDraggable } from '../node_modules/igv-ui/dist/igv-ui.js';\nimport HICEvent from './hicEvent.js';\nimport Track2D from './track2D.js';\n\nclass AnnotationWidget {\n constructor(browser, container, { title, alertMessage }, trackListRetrievalCallback) {\n this.browser = browser;\n this.trackListRetrievalCallback = trackListRetrievalCallback;\n\n this.annotationPresentationButton(container, alertMessage);\n this.annotationPanel(browser.rootElement, title);\n }\n\n updateBody(tracks) {\n\n this.annotationPanelElement.querySelectorAll('.hic-annotation-row-container').forEach(el => el.remove());\n\n if (tracks[0] instanceof Track2D) {\n for (let i = tracks.length - 1; i >= 0; i--) {\n this.annotationPanelRow(this.annotationPanelElement, tracks[i]);\n }\n } else {\n for (const trackRenderer of tracks) {\n this.annotationPanelRow(this.annotationPanelElement, trackRenderer);\n }\n }\n }\n\n annotationPresentationButton(parent, alertMessage) {\n const button = parent.querySelector('button');\n\n button.addEventListener('click', () => {\n const list = this.trackListRetrievalCallback();\n\n if (list.length > 0) {\n this.updateBody(this.trackListRetrievalCallback());\n this.annotationPanelElement.style.display =\n this.annotationPanelElement.style.display === 'none' ? 'flex' : 'none';\n } else {\n Alert.presentAlert(alertMessage);\n }\n\n this.browser.hideMenu();\n });\n }\n\n annotationPanel(parent, title) {\n this.annotationPanelElement = document.createElement('div');\n this.annotationPanelElement.className = 'hic-annotation-panel-container';\n parent.appendChild(this.annotationPanelElement);\n\n const panelHeader = document.createElement('div');\n panelHeader.className = 'hic-annotation-panel-header';\n this.annotationPanelElement.appendChild(panelHeader);\n\n const titleDiv = document.createElement('div');\n titleDiv.textContent = title;\n panelHeader.appendChild(titleDiv);\n\n const closeButtonDiv = document.createElement('div');\n closeButtonDiv.className = 'hic-menu-close-button';\n panelHeader.appendChild(closeButtonDiv);\n\n const closeIcon = document.createElement('i');\n closeIcon.className = 'fa fa-times';\n closeButtonDiv.appendChild(closeIcon);\n\n closeIcon.addEventListener('click', () => {\n this.annotationPanelElement.style.display =\n this.annotationPanelElement.style.display === 'none' ? 'flex' : 'none';\n });\n\n makeDraggable(this.annotationPanelElement, panelHeader);\n this.annotationPanelElement.style.display = 'none';\n }\n\n annotationPanelRow(container, track) {\n const isTrack2D = track instanceof Track2D;\n const trackList = this.trackListRetrievalCallback();\n\n let trackRenderer\n if (false === isTrack2D) {\n trackRenderer = track.x.track.trackView\n }\n\n const rowContainer = document.createElement('div');\n rowContainer.className = 'hic-annotation-row-container';\n container.appendChild(rowContainer);\n\n const row = document.createElement('div');\n row.className = 'hic-annotation-modal-row';\n rowContainer.appendChild(row);\n\n const trackName = document.createElement('div');\n trackName.textContent = isTrack2D ? track.config.name : track.x.track.config.name;\n row.appendChild(trackName);\n\n if (isTrack2D) {\n const visibilityIcon = document.createElement('i');\n visibilityIcon.className = track.isVisible ? 'fa fa-eye fa-lg' : 'fa fa-eye-slash fa-lg';\n row.appendChild(visibilityIcon);\n\n visibilityIcon.addEventListener('click', () => {\n track.isVisible = !track.isVisible;\n visibilityIcon.className = track.isVisible ? 'fa fa-eye fa-lg' : 'fa fa-eye-slash fa-lg';\n\n this.browser.contactMatrixView.clearImageCaches();\n this.browser.contactMatrixView.update();\n });\n }\n\n if (isTrack2D) {\n const displayModeIcon = document.createElement('div');\n displayModeIcon.className = 'matrix-diagonal-widget-container';\n\n switch (track.displayMode) {\n case 'lower':\n displayModeIcon.classList.add('matrix-diagonal-widget-lower');\n break;\n case 'upper':\n displayModeIcon.classList.add('matrix-diagonal-widget-upper');\n break;\n default:\n displayModeIcon.classList.add('matrix-diagonal-widget-all');\n }\n\n displayModeIcon.addEventListener('click', () => {\n this.displayModeHandler(displayModeIcon, track);\n this.browser.contactMatrixView.clearImageCaches();\n this.browser.contactMatrixView.update();\n });\n\n row.appendChild(displayModeIcon);\n }\n\n const colorpickerContainer = createAnnotationPanelColorpickerContainer(rowContainer, {width: (29 * 24 + 2)}, () => {\n const nextElement = row.nextElementSibling;\n if (nextElement && nextElement.classList.contains('hic-color-swatch-container')) {\n nextElement.style.display = nextElement.style.display === 'none' ? 'flex' : 'none';\n }\n });\n\n const colorpickerButton = this.annotationColorSwatch(isTrack2D ? track.getColor() : track.x.track.color);\n row.appendChild(colorpickerButton);\n\n colorpickerButton.addEventListener('click', () => {\n const nextElement = row.nextElementSibling;\n if (nextElement && nextElement.classList.contains('hic-color-swatch-container')) {\n nextElement.style.display = nextElement.style.display === 'none' ? 'flex' : 'none';\n }\n });\n\n colorpickerContainer.style.display = 'none';\n\n const colorHandler = color => {\n const swatch = row.querySelector('.fa-square');\n if (swatch) {\n swatch.style.color = color;\n }\n\n if (isTrack2D) {\n track.color = color;\n this.browser.eventBus.post(HICEvent('TrackState2D', track));\n } else {\n trackRenderer.setColor(color);\n }\n };\n\n createColorSwatchSelector(colorpickerContainer, colorHandler);\n\n // track up/down\n const upDownContainer = document.createElement('div');\n upDownContainer.className = 'up-down-arrow-container';\n row.appendChild(upDownContainer);\n\n const upTrack = document.createElement('i');\n upTrack.className = 'fa fa-arrow-up';\n upTrack.setAttribute('aria-hidden', 'true');\n upDownContainer.appendChild(upTrack);\n\n const downTrack = document.createElement('i');\n downTrack.className = 'fa fa-arrow-down';\n downTrack.setAttribute('aria-hidden', 'true');\n upDownContainer.appendChild(downTrack);\n\n const hiddenColor = '#f7f7f7'\n if (trackList.length === 1) {\n upTrack.style.color = hiddenColor;\n downTrack.style.color = hiddenColor;\n } else if (track === trackList[0]) {\n const arrow = isTrack2D ? downTrack : upTrack;\n arrow.style.color = hiddenColor;\n } else if (track === trackList[trackList.length - 1]) {\n const arrow = isTrack2D ? upTrack : downTrack;\n arrow.style.color = hiddenColor;\n }\n\n const index = trackList.indexOf(track);\n\n const moveUp = () => {\n const temp = trackList[index + 1];\n trackList[index + 1] = trackList[index];\n trackList[index] = temp;\n\n if (isTrack2D) {\n this.browser.eventBus.post(HICEvent('TrackState2D', trackList));\n this.updateBody(trackList);\n } else {\n this.browser.updateLayout();\n this.updateBody(trackList);\n }\n };\n\n const moveDown = () => {\n const temp = trackList[index - 1];\n trackList[index - 1] = trackList[index];\n trackList[index] = temp;\n\n if (isTrack2D) {\n this.browser.eventBus.post(HICEvent('TrackState2D', trackList));\n this.updateBody(trackList);\n } else {\n this.browser.updateLayout();\n this.updateBody(trackList);\n }\n };\n\n upTrack.addEventListener('click', isTrack2D ? moveUp : moveDown);\n downTrack.addEventListener('click', isTrack2D ? moveDown : moveUp);\n\n\n const deleteIcon = document.createElement('i');\n deleteIcon.className = 'fa fa-trash-o fa-lg';\n row.appendChild(deleteIcon);\n\n deleteIcon.addEventListener('click', () => {\n const index = trackList.indexOf(track);\n if (isTrack2D) {\n trackList.splice(index, 1);\n this.browser.contactMatrixView.clearImageCaches();\n this.browser.contactMatrixView.update();\n this.browser.eventBus.post(HICEvent('TrackLoad2D', trackList));\n } else {\n this.browser.layoutController.removeTrackXYPair(track.x.track.trackRenderPair);\n }\n\n this.updateBody(trackList);\n });\n }\n\n displayModeHandler(icon, track2D) {\n if (icon.classList.contains('matrix-diagonal-widget-all')) {\n icon.classList.replace('matrix-diagonal-widget-all', 'matrix-diagonal-widget-lower');\n track2D.displayMode = 'lower';\n } else if (icon.classList.contains('matrix-diagonal-widget-lower')) {\n icon.classList.replace('matrix-diagonal-widget-lower', 'matrix-diagonal-widget-upper');\n track2D.displayMode = 'upper';\n } else {\n icon.classList.replace('matrix-diagonal-widget-upper', 'matrix-diagonal-widget-all');\n track2D.displayMode = undefined;\n }\n }\n\n annotationColorSwatch(color) {\n const swatch = document.createElement('div');\n swatch.className = 'igv-color-swatch';\n\n const icon = document.createElement('i');\n icon.className = 'fa fa-square fa-lg';\n icon.style.color = color;\n swatch.appendChild(icon);\n\n return swatch;\n }\n}\n\nfunction createAnnotationPanelColorpickerContainer(parent, size, closeHandler) {\n\n const container = document.createElement('div');\n container.className = 'hic-color-swatch-container';\n parent.appendChild(container);\n\n // width\n if (size && size.width) {\n container.style.width = `${size.width}px`;\n }\n\n // height\n if (size && size.height) {\n container.style.height = `${size.height}px`;\n }\n\n // header\n const header = document.createElement('div');\n container.appendChild(header);\n\n // close button\n const closeButton = document.createElement('i');\n closeButton.className = 'fa fa-times';\n header.appendChild(closeButton);\n\n closeButton.addEventListener('click', () => {\n closeHandler();\n });\n\n return container;\n}\n\nexport default AnnotationWidget;\n","/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2016-2017 The Regents of the University of California\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and\n * associated documentation files (the \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the\n * following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all copies or substantial\n * portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING\n * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n *\n */\n\nimport LocusGoto from \"./hicLocusGoto.js\"\nimport ResolutionSelector from \"./hicResolutionSelector.js\"\nimport ColorScaleWidget from \"./hicColorScaleWidget.js\"\nimport ControlMapWidget from \"./controlMapWidget.js\"\nimport NormalizationWidget from \"./normalizationWidget.js\"\nimport {getNavbarContainer} from \"./layoutController.js\"\nimport SweepZoom from \"./sweepZoom.js\"\nimport ScrollbarWidget from \"./scrollbarWidget.js\"\nimport ColorScale, {defaultColorScaleConfig} from \"./colorScale.js\"\nimport RatioColorScale, {defaultRatioColorScaleConfig} from \"./ratioColorScale.js\"\nimport ContactMatrixView from \"./contactMatrixView.js\"\nimport ChromosomeSelector from \"./chromosomeSelector.js\"\nimport AnnotationWidget from \"./annotationWidget.js\"\n\nclass BrowserUIManager {\n constructor(browser) {\n this.browser = browser;\n this.components = new Map();\n this.initializeComponents();\n }\n\n initializeComponents() {\n const navContainer = getNavbarContainer(this.browser);\n\n // Navbar components\n this.components.set('locusGoto', new LocusGoto(this.browser, navContainer));\n\n this.components.set('resolutionSelector', new ResolutionSelector(this.browser, navContainer));\n this.getComponent('resolutionSelector').setResolutionLock(this.browser.resolutionLocked);\n\n this.components.set('colorScale', new ColorScaleWidget(this.browser, navContainer));\n\n this.components.set('controlMap', new ControlMapWidget(this.browser, navContainer));\n\n this.components.set('normalization', new NormalizationWidget(this.browser, navContainer));\n\n const chromosomeSelectorContainer = this.browser.menuElement.querySelector('.hic-chromosome-selector-widget-container');\n this.components.set('chromosomeSelector', new ChromosomeSelector(this.browser, chromosomeSelectorContainer));\n\n const annotationContainer = this.browser.menuElement.querySelector('.hic-annotation-presentation-button-container');\n const annotation2DWidgetConfig =\n {\n title: '2D Annotations',\n alertMessage: 'No 2D annotations currently loaded for this map'\n };\n this.components.set('annotationWidget', new AnnotationWidget(this.browser, annotationContainer, annotation2DWidgetConfig, () => this.browser.tracks2D));\n\n const sweepZoom = new SweepZoom(this.browser, this.browser.layoutController.getContactMatrixViewport());\n const scrollbarWidget = new ScrollbarWidget(\n this.browser,\n this.browser.layoutController.getXAxisScrollbarContainer(),\n this.browser.layoutController.getYAxisScrollbarContainer()\n );\n\n const colorScale = new ColorScale(defaultColorScaleConfig);\n const ratioColorScale = new RatioColorScale(defaultRatioColorScaleConfig.threshold);\n ratioColorScale.setColorComponents(defaultRatioColorScaleConfig.negative, '-');\n ratioColorScale.setColorComponents(defaultRatioColorScaleConfig.positive, '+');\n\n this.components.set('sweepZoom', sweepZoom);\n this.components.set('scrollbar', scrollbarWidget);\n this.components.set('colorScale', colorScale);\n this.components.set('ratioColorScale', ratioColorScale);\n\n // Initialize ContactMatrixView with the components\n const backgroundColor = this.browser.config.backgroundColor || ContactMatrixView.defaultBackgroundColor;\n this.components.set('contactMatrix', new ContactMatrixView(\n this.browser,\n this.browser.layoutController.getContactMatrixViewport(),\n sweepZoom,\n scrollbarWidget,\n colorScale,\n ratioColorScale,\n backgroundColor\n ));\n }\n\n getComponent(name) {\n return this.components.get(name);\n }\n\n}\n\nexport default BrowserUIManager;\n","/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2016-2017 The Regents of the University of California\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and\n * associated documentation files (the \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the\n * following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all copies or substantial\n * portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING\n * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n *\n */\n\n/**\n * @author Jim Robinson\n */\n\nimport igv from '../node_modules/igv/dist/igv.esm.js'\nimport {Alert, InputDialog, DOMUtils} from '../node_modules/igv-ui/dist/igv-ui.js'\nimport {FileUtils} from '../node_modules/igv-utils/src/index.js'\nimport * as hicUtils from './hicUtils.js'\nimport {Globals} from \"./globals.js\"\nimport EventBus from \"./eventBus.js\"\nimport Track2D from './track2D.js'\nimport LayoutController, {getLayoutDimensions, setViewportSize} from './layoutController.js'\nimport HICEvent from './hicEvent.js'\nimport Dataset from './hicDataset.js'\nimport Genome from './genome.js'\nimport State from './hicState.js'\nimport { geneSearch } from './geneSearch.js'\nimport {defaultSize, getAllBrowsers, syncBrowsers} from \"./createBrowser.js\"\nimport {isFile} from \"./fileUtils.js\"\nimport {setTrackReorderArrowColors} from \"./trackPair.js\"\nimport nvi from './nvi.js'\nimport {extractName, presentError} from \"./utils.js\"\nimport BrowserUIManager from \"./browserUIManager.js\"\n\nconst DEFAULT_PIXEL_SIZE = 1\nconst MAX_PIXEL_SIZE = 128\nconst DEFAULT_ANNOTATION_COLOR = \"rgb(22, 129, 198)\"\n\nclass HICBrowser {\n\n constructor(appContainer, config) {\n this.config = config;\n this.figureMode = config.figureMode || config.miniMode; // Mini mode for backward compatibility\n this.resolutionLocked = false;\n this.eventBus = new EventBus();\n\n this.showTrackLabelAndGutter = true;\n\n this.id = `browser_${DOMUtils.guid()}`;\n this.trackPairs = [];\n this.tracks2D = [];\n this.normVectorFiles = [];\n\n this.synchable = config.synchable !== false;\n this.synchedBrowsers = new Set();\n\n this.isMobile = hicUtils.isMobile();\n\n this.rootElement = document.createElement('div');\n this.rootElement.className = 'hic-root unselect';\n appContainer.appendChild(this.rootElement);\n\n\n if (config.width && config.height) {\n setViewportSize(config.width, config.height)\n }\n\n this.layoutController = new LayoutController(this, this.rootElement);\n\n this.inputDialog = new InputDialog(appContainer, this);\n\n this.menuElement = this.createMenu(this.rootElement);\n this.menuElement.style.display = 'none';\n\n // Initialize UI components through BrowserUIManager\n this.ui = new BrowserUIManager(this);\n\n // Get the contact matrix view from UI manager\n this.contactMatrixView = this.ui.getComponent('contactMatrix');\n\n // prevent user interaction during lengthy data loads\n this.userInteractionShield = document.createElement('div');\n this.userInteractionShield.className = 'hic-root-prevent-interaction';\n this.rootElement.appendChild(this.userInteractionShield);\n this.userInteractionShield.style.display = 'none';\n\n this.hideCrosshairs();\n }\n\n async init(config) {\n this.pending = new Map();\n this.eventBus.hold();\n this.contactMatrixView.disableUpdates = true;\n\n try {\n this.contactMatrixView.startSpinner();\n this.userInteractionShield.style.display = 'block';\n\n await this.loadHicFile(config, true);\n\n if (config.controlUrl) {\n await this.loadHicControlFile({\n url: config.controlUrl,\n name: config.controlName,\n nvi: config.controlNvi,\n isControl: true\n }, true);\n }\n\n if (config.cycle) {\n config.displayMode = \"A\";\n }\n\n if (config.displayMode) {\n this.contactMatrixView.displayMode = config.displayMode;\n this.eventBus.post({ type: \"DisplayMode\", data: config.displayMode });\n }\n\n if (config.colorScale) {\n if (config.normalization) {\n this.state.normalization = config.normalization;\n }\n this.contactMatrixView.setColorScale(config.colorScale);\n this.eventBus.post({ type: \"ColorScale\", data: this.contactMatrixView.getColorScale() });\n }\n\n const promises = [];\n\n if (config.tracks) {\n promises.push(this.loadTracks(config.tracks));\n }\n\n if (config.normVectorFiles) {\n config.normVectorFiles.forEach(nv => {\n promises.push(this.loadNormalizationFile(nv));\n });\n }\n\n await Promise.all(promises);\n\n if (config.normalization) {\n const normalizations = await this.getNormalizationOptions();\n const validNormalizations = new Set(normalizations);\n this.state.normalization = validNormalizations.has(config.normalization) ? config.normalization : 'NONE';\n }\n\n const tmp = this.contactMatrixView.colorScaleThresholdCache;\n this.eventBus.release();\n this.contactMatrixView.colorScaleThresholdCache = tmp;\n\n if (config.cycle) {\n this.ui.getComponent('controlMap').toggleDisplayModeCycle();\n } else {\n await this.update();\n }\n\n } finally {\n this.contactMatrixView.stopSpinner();\n this.userInteractionShield.style.display = 'none';\n this.contactMatrixView.disableUpdates = false;\n this.contactMatrixView.update();\n }\n }\n\n createMenu(rootElement) {\n const html = `\n
\n
\n \n
\n
\n
Chromosomes
\n
\n \n \n
\n
\n
\n
\n \n
\n
`;\n\n const template = document.createElement('template');\n template.innerHTML = html.trim();\n const menuElement = template.content.firstChild;\n\n rootElement.appendChild(menuElement);\n\n const closeButton = menuElement.querySelector(\".fa-times\");\n closeButton.addEventListener('click', () => this.toggleMenu());\n\n return menuElement;\n }\n\n toggleTrackLabelAndGutterState() {\n this.showTrackLabelAndGutter = !this.showTrackLabelAndGutter\n }\n\n toggleMenu() {\n if (this.menuElement.style.display === \"flex\") {\n this.hideMenu();\n } else {\n this.showMenu();\n }\n }\n\n showMenu() {\n this.menuElement.style.display = \"flex\";\n }\n\n hideMenu() {\n this.menuElement.style.display = \"none\";\n }\n\n startSpinner() {\n this.contactMatrixView.startSpinner()\n }\n\n stopSpinner() {\n this.contactMatrixView.stopSpinner()\n }\n\n async setDisplayMode(mode) {\n await this.contactMatrixView.setDisplayMode(mode)\n this.eventBus.post(HICEvent(\"DisplayMode\", mode))\n }\n\n getDisplayMode() {\n return this.contactMatrixView ? this.contactMatrixView.displayMode : undefined\n }\n\n async getNormalizationOptions() {\n\n if (!this.dataset) return []\n\n const baseOptions = await this.dataset.getNormalizationOptions()\n if (this.controlDataset) {\n let controlOptions = await this.controlDataset.getNormalizationOptions()\n controlOptions = new Set(controlOptions)\n return baseOptions.filter(base => controlOptions.has(base))\n } else {\n return baseOptions\n }\n }\n\n /**\n * Return usable resolutions, that is the union of resolutions between dataset and controlDataset.\n * @returns {{index: *, binSize: *}[]|Array}\n */\n getResolutions() {\n if (!this.dataset) return []\n\n const baseResolutions = this.dataset.bpResolutions.map(function (resolution, index) {\n return {index: index, binSize: resolution}\n })\n if (this.controlDataset) {\n let controlResolutions = new Set(this.controlDataset.bpResolutions)\n return baseResolutions.filter(base => controlResolutions.has(base.binSize))\n } else {\n return baseResolutions\n }\n }\n\n isWholeGenome() {\n return this.dataset && this.state && this.dataset.isWholeGenome(this.state.chr1)\n }\n\n getColorScale() {\n\n if (!this.contactMatrixView) return undefined\n\n switch (this.getDisplayMode()) {\n case 'AOB':\n case 'BOA':\n return this.contactMatrixView.ratioColorScale\n case 'AMB':\n return this.contactMatrixView.diffColorScale\n default:\n return this.contactMatrixView.colorScale\n }\n }\n\n setColorScaleThreshold(threshold) {\n this.contactMatrixView.setColorScaleThreshold(threshold)\n }\n\n updateCrosshairs({ x, y, xNormalized, yNormalized }) {\n\n const xGuide = y < 0 ? { left: '0px' } : { top: `${y}px`, left: '0px' };\n this.contactMatrixView.xGuideElement.style.left = xGuide.left;\n if (xGuide.top !== undefined) this.contactMatrixView.xGuideElement.style.top = xGuide.top;\n\n this.layoutController.xTrackGuideElement.style.left = xGuide.left;\n if (xGuide.top !== undefined) this.layoutController.xTrackGuideElement.style.top = xGuide.top;\n\n const yGuide = x < 0 ? { top: '0px' } : { top: '0px', left: `${x}px` };\n this.contactMatrixView.yGuideElement.style.top = yGuide.top;\n if (yGuide.left !== undefined) this.contactMatrixView.yGuideElement.style.left = yGuide.left;\n\n this.layoutController.yTrackGuideElement.style.top = yGuide.top;\n if (yGuide.left !== undefined) this.layoutController.yTrackGuideElement.style.left = yGuide.left;\n\n if (this.customCrosshairsHandler) {\n const { x: stateX, y: stateY, pixelSize } = this.state;\n const resolution = this.resolution();\n\n const xBP = (stateX + (x / pixelSize)) * resolution;\n const yBP = (stateY + (y / pixelSize)) * resolution;\n\n const { startBP: startXBP, endBP: endXBP } = this.genomicState('x');\n const { startBP: startYBP, endBP: endYBP } = this.genomicState('y');\n\n this.customCrosshairsHandler({\n xBP,\n yBP,\n startXBP,\n startYBP,\n endXBP,\n endYBP,\n interpolantX: xNormalized,\n interpolantY: yNormalized\n });\n }\n }\n\n setCustomCrosshairsHandler(crosshairsHandler) {\n this.customCrosshairsHandler = crosshairsHandler\n }\n\n hideCrosshairs() {\n this.contactMatrixView.xGuideElement.style.display = 'none';\n this.layoutController.xTrackGuideElement.style.display = 'none';\n\n this.contactMatrixView.yGuideElement.style.display = 'none';\n this.layoutController.yTrackGuideElement.style.display = 'none';\n }\n\n showCrosshairs() {\n this.contactMatrixView.xGuideElement.style.display = 'block';\n this.layoutController.xTrackGuideElement.style.display = 'block';\n\n this.contactMatrixView.yGuideElement.style.display = 'block';\n this.layoutController.yTrackGuideElement.style.display = 'block';\n }\n\n genomicState(axis) {\n\n let width = this.contactMatrixView.getViewDimensions().width\n let resolution = this.dataset.bpResolutions[this.state.zoom]\n const bpp =\n (this.dataset.chromosomes[this.state.chr1].name.toLowerCase() === \"all\") ?\n this.genome.getGenomeLength() / width :\n resolution / this.state.pixelSize\n\n const gs =\n {\n bpp\n }\n\n if (axis === \"x\") {\n gs.chromosome = this.dataset.chromosomes[this.state.chr1]\n gs.startBP = this.state.x * resolution\n gs.endBP = gs.startBP + bpp * width\n } else {\n gs.chromosome = this.dataset.chromosomes[this.state.chr2]\n gs.startBP = this.state.y * resolution\n gs.endBP = gs.startBP + bpp * this.contactMatrixView.getViewDimensions().height\n }\n return gs\n }\n\n /**\n * Load a list of 1D genome tracks (wig, etc).\n *\n * NOTE: public API function\n *\n * @param configs\n */\n async loadTracks(configs) {\n const errorPrefix = configs.length === 1 ? `Error loading track ${configs[0].name}` : \"Error loading tracks\";\n\n try {\n this.contactMatrixView.startSpinner();\n\n const tracks = [];\n const promises2D = [];\n\n for (let config of configs) {\n const fileName = isFile(config.url)\n ? config.url.name\n : config.filename || await FileUtils.getFilename(config.url);\n\n const extension = hicUtils.getExtension(fileName);\n\n if (['fasta', 'fa'].includes(extension)) {\n config.type = config.format = 'sequence';\n }\n\n if (!config.format) {\n config.format = igv.TrackUtils.inferFileFormat(fileName);\n }\n\n if (config.type === 'annotation') {\n config.displayMode = 'COLLAPSED';\n if (config.color === DEFAULT_ANNOTATION_COLOR) {\n delete config.color;\n }\n }\n\n if (config.max === undefined) {\n config.autoscale = true;\n }\n\n const { trackHeight } = getLayoutDimensions()\n config.height = trackHeight;\n\n if (config.format === undefined || ['bedpe', 'interact'].includes(config.format)) {\n promises2D.push(Track2D.loadTrack2D(config, this.genome));\n } else {\n const track = await igv.createTrack(config, this);\n\n if (typeof track.postInit === 'function') {\n await track.postInit();\n }\n\n tracks.push(track);\n }\n }\n\n if (tracks.length > 0) {\n this.layoutController.updateLayoutWithTracks(tracks);\n\n const gearContainer = document.querySelector('.hic-igv-right-hand-gutter');\n if (this.showTrackLabelAndGutter) {\n gearContainer.style.display = 'block';\n } else {\n gearContainer.style.display = 'none';\n }\n\n await this.updateLayout();\n }\n\n if (promises2D.length > 0) {\n const tracks2D = await Promise.all(promises2D);\n if (tracks2D && tracks2D.length > 0) {\n this.tracks2D = this.tracks2D.concat(tracks2D);\n this.eventBus.post(HICEvent(\"TrackLoad2D\", this.tracks2D));\n }\n }\n\n } catch (error) {\n presentError(errorPrefix, error);\n console.error(error);\n\n } finally {\n this.contactMatrixView.stopSpinner();\n }\n }\n\n async loadNormalizationFile(url) {\n\n if (!this.dataset) return\n this.eventBus.post(HICEvent(\"NormalizationFileLoad\", \"start\"))\n\n const normVectors = await this.dataset.hicFile.readNormalizationVectorFile(url, this.dataset.chromosomes)\n for (let type of normVectors['types']) {\n if (!this.dataset.normalizationTypes) {\n this.dataset.normalizationTypes = []\n }\n if (!this.dataset.normalizationTypes.includes(type)) {\n this.dataset.normalizationTypes.push(type)\n }\n this.eventBus.post(HICEvent(\"NormVectorIndexLoad\", this.dataset))\n }\n\n return normVectors\n }\n\n /**\n * Render the XY pair of tracks.\n *\n * @param xy\n */\n async renderTrackXY(xy) {\n\n try {\n this.startSpinner()\n await xy.updateViews()\n } finally {\n this.stopSpinner()\n }\n }\n\n reset() {\n this.layoutController.removeAllTrackXYPairs()\n this.contactMatrixView.clearImageCaches()\n this.tracks2D = []\n this.tracks = []\n this.contactMapLabel.textContent = \"\";\n this.contactMapLabel.title = \"\";\n this.controlMapLabel.textContent = \"\";\n this.controlMapLabel.title = \"\";\n this.dataset = undefined\n this.controlDataset = undefined\n this.unsyncSelf()\n }\n\n clearSession() {\n // Clear current datasets.\n this.dataset = undefined\n this.controlDataset = undefined\n this.setDisplayMode('A')\n this.unsyncSelf()\n }\n\n /**\n * Remove reference to self from all synchedBrowsers lists.\n */\n unsyncSelf() {\n const allBrowsers = getAllBrowsers()\n for (let b of allBrowsers) {\n b.unsync(this)\n }\n }\n\n /**\n * Remove the reference browser from this collection of synched browsers\n * @param browser\n */\n unsync(browser) {\n const list = [...this.synchedBrowsers]\n this.synchedBrowsers = new Set(list.filter(b => b !== browser))\n }\n\n /**\n * Load a .hic file\n *\n * NOTE: public API function\n *\n * @return a promise for a dataset\n * @param config\n * @param noUpdates\n */\n async loadHicFile(config, noUpdates) {\n\n if (!config.url) {\n console.log(\"No .hic url specified\")\n return undefined\n }\n\n this.clearSession()\n\n try {\n\n this.contactMatrixView.startSpinner()\n if (!noUpdates) {\n this.userInteractionShield.style.display = 'block';\n }\n\n const name = extractName(config)\n const prefix = this.controlDataset ? \"A: \" : \"\"\n this.contactMapLabel.textContent = prefix + name;\n this.contactMapLabel.title = name\n config.name = name\n\n const hicFileAlert = str => {\n this.eventBus.post(HICEvent('NormalizationExternalChange', 'NONE'))\n Alert.presentAlert(str)\n }\n\n this.dataset = await Dataset.loadDataset(Object.assign({alert: hicFileAlert}, config))\n this.dataset.name = name\n\n const previousGenomeId = this.genome ? this.genome.id : undefined\n this.genome = new Genome(this.dataset.genomeId, this.dataset.chromosomes)\n\n if (this.genome.id !== previousGenomeId) {\n EventBus.globalBus.post(HICEvent(\"GenomeChange\", this.genome.id))\n }\n\n if (config.locus) {\n this.state = State.default(config)\n await this.parseGotoInput(config.locus)\n } else if (config.state) {\n\n if (typeof config.state === 'string') {\n await this.setState( State.parse(config.state) )\n } else if (typeof config.state === 'object') {\n await this.setState( State.fromJSON(config.state) )\n } else {\n alert('config.state is of unknown type')\n console.error('config.state is of unknown type')\n }\n\n\n } else if (config.synchState && this.canBeSynched(config.synchState)) {\n await this.syncState(config.synchState)\n } else {\n await this.setState(State.default(config))\n }\n\n this.eventBus.post(HICEvent(\"MapLoad\", this.dataset))\n\n // Initiate loading of the norm vector index, but don't block if the \"nvi\" parameter is not available.\n // Let it load in the background\n\n // If nvi is not supplied, try lookup table of known values\n if (!config.nvi && typeof config.url === \"string\") {\n const url = new URL(config.url)\n const key = encodeURIComponent(url.hostname + url.pathname)\n if (nvi.hasOwnProperty(key)) {\n config.nvi = nvi[key]\n }\n }\n\n if (config.nvi) {\n await this.dataset.getNormVectorIndex(config)\n this.eventBus.post(HICEvent(\"NormVectorIndexLoad\", this.dataset))\n } else {\n\n this.dataset.getNormVectorIndex(config)\n .then(normVectorIndex => {\n if (!config.isControl) {\n this.eventBus.post(HICEvent(\"NormVectorIndexLoad\", this.dataset))\n }\n })\n }\n\n syncBrowsers()\n\n // Find a browser to sync with, if any\n const compatibleBrowsers = getAllBrowsers().filter(b => b !== this && b.dataset && b.dataset.isCompatible(this.dataset))\n if (compatibleBrowsers.length > 0) {\n await this.syncState(compatibleBrowsers[0].getSyncState())\n }\n\n } catch (error) {\n this.contactMapLabel.textContent = \"\";\n this.contactMapLabel.title = \"\";\n config.name = name\n throw error\n } finally {\n this.stopSpinner()\n if (!noUpdates) {\n this.userInteractionShield.style.display = 'none';\n }\n }\n }\n\n /**\n * Load a .hic file for a control map\n *\n * NOTE: public API function\n *\n * @return a promise for a dataset\n * @param config\n */\n async loadHicControlFile(config, noUpdates) {\n\n try {\n this.userInteractionShield.style.display = 'block';\n this.contactMatrixView.startSpinner()\n this.controlUrl = config.url\n const name = extractName(config)\n config.name = name\n\n const hicFileAlert = str => {\n this.eventBus.post(HICEvent('NormalizationExternalChange', 'NONE'))\n Alert.presentAlert(str)\n }\n\n const controlDataset = await Dataset.loadDataset(Object.assign({alert: hicFileAlert}, config))\n\n controlDataset.name = name\n\n if (!this.dataset || this.dataset.isCompatible(controlDataset)) {\n this.controlDataset = controlDataset\n if (this.dataset) {\n this.contactMapLabel.textContent = \"A: \" + this.dataset.name;\n }\n this.controlMapLabel.textContent = \"B: \" + controlDataset.name\n this.controlMapLabel.title = controlDataset.name\n\n //For the control dataset, block until the norm vector index is loaded\n await controlDataset.getNormVectorIndex(config)\n this.eventBus.post(HICEvent(\"ControlMapLoad\", this.controlDataset))\n\n if (!noUpdates) {\n this.update()\n }\n } else {\n Alert.presentAlert('\"B\" map genome (' + controlDataset.genomeId + ') does not match \"A\" map genome (' + this.genome.id + ')')\n }\n } finally {\n this.userInteractionShield.style.display = 'none';\n this.stopSpinner()\n }\n }\n\n async parseGotoInput(input) {\n const loci = input.trim().split(' ');\n\n let xLocus = this.parseLocusString(loci[0]) || await this.lookupFeatureOrGene(loci[0]);\n\n if (!xLocus) {\n console.error(`No feature found with name ${loci[ 0 ]}`)\n alert(`No feature found with name ${loci[ 0 ]}`)\n return;\n }\n\n let yLocus = loci[1] ? this.parseLocusString(loci[1]) : { ...xLocus }\n if (!yLocus) {\n yLocus = { ...xLocus }\n }\n\n if (xLocus.wholeChr && yLocus.wholeChr || 'All' === xLocus.chr && 'All' === yLocus.chr) {\n await this.setChromosomes(xLocus, yLocus)\n } else {\n this.goto(xLocus.chr, xLocus.start, xLocus.end, yLocus.chr, yLocus.start, yLocus.end)\n }\n }\n\n parseLocusString(locus) {\n const [chrName, range] = locus.trim().toLowerCase().split(':');\n const chromosome = this.genome.getChromosome(chrName);\n\n if (!chromosome) {\n return undefined;\n }\n\n const locusObject =\n {\n chr: chromosome.name,\n wholeChr: (undefined === range && 'All' !== chromosome.name)\n };\n\n if (true === locusObject.wholeChr || 'All' === chromosome.name) {\n // Chromosome name only or All: Set to whole range\n locusObject.start = 0;\n locusObject.end = chromosome.size\n } else {\n\n const [startStr, endStr] = range.split('-').map(part => part.replace(/,/g, ''));\n\n // Internally, loci are 0-based.\n locusObject.start = isNaN(startStr) ? undefined : parseInt(startStr, 10) - 1;\n locusObject.end = isNaN(endStr) ? undefined : parseInt(endStr, 10);\n\n }\n\n return locusObject;\n }\n\n async lookupFeatureOrGene(name) {\n\n const trimmedName = name.trim();\n const upperName = trimmedName.toUpperCase();\n\n if (this.genome.featureDB.has(upperName)) {\n Globals.selectedGene = trimmedName\n this.state.selectedGene = Globals.selectedGene\n const {chr, start, end } = this.genome.featureDB.get(upperName)\n\n // Internally, loci are 0-based. parseLocusString() assumes and user-provided locus which is 1-based\n return this.parseLocusString(`${chr}:${start + 1}-${end}`)\n }\n\n const geneResult = await geneSearch(this.genome.id, trimmedName);\n if (geneResult) {\n Globals.selectedGene = trimmedName;\n this.state.selectedGene = Globals.selectedGene;\n return this.parseLocusString(geneResult)\n }\n\n return undefined; // No match found\n }\n\n goto(chr1, bpX, bpXMax, chr2, bpY, bpYMax) {\n\n const { width, height } = this.contactMatrixView.getViewDimensions()\n const { chrChanged, resolutionChanged } = this.state.updateWithLoci(chr1, bpX, bpXMax, chr2, bpY, bpYMax, this, width, height)\n\n this.contactMatrixView.clearImageCaches()\n\n this.update(HICEvent(\"LocusChange\", { state: this.state, resolutionChanged, chrChanged }))\n\n }\n\n /**\n * Find the closest matching zoom index (index into the dataset resolutions array) for the target resolution.\n *\n * resolutionAraay can be either\n * (1) an array of bin sizes\n * (2) an array of objects with index and bin size\n * @param targetResolution\n * @param resolutionArray\n * @returns {number}\n */\n findMatchingZoomIndex(targetResolution, resolutionArray) {\n const isObject = resolutionArray.length > 0 && resolutionArray[0].index !== undefined\n for (let z = resolutionArray.length - 1; z > 0; z--) {\n const binSize = isObject ? resolutionArray[z].binSize : resolutionArray[z]\n const index = isObject ? resolutionArray[z].index : z\n if (binSize >= targetResolution) {\n return index\n }\n }\n return 0\n };\n\n /**\n * @param scaleFactor Values range from greater then 1 to decimal values less then one\n * Value > 1 are magnification (zoom in)\n * Decimal values (.9, .75, .25, etc.) are minification (zoom out)\n * @param anchorPx -- anchor position in pixels (should not move after transformation)\n * @param anchorPy\n */\n async pinchZoom(anchorPx, anchorPy, scaleFactor) {\n\n if (this.state.chr1 === 0) {\n await this.zoomAndCenter(1, anchorPx, anchorPy)\n } else {\n try {\n this.startSpinner()\n\n const bpResolutions = this.getResolutions()\n const currentResolution = bpResolutions[this.state.zoom]\n\n let newBinSize\n let newZoom\n let newPixelSize\n let resolutionChanged\n\n if (this.resolutionLocked ||\n (this.state.zoom === bpResolutions.length - 1 && scaleFactor > 1) ||\n (this.state.zoom === 0 && scaleFactor < 1)) {\n // Can't change resolution level, must adjust pixel size\n newBinSize = currentResolution.binSize\n newPixelSize = Math.min(MAX_PIXEL_SIZE, this.state.pixelSize * scaleFactor)\n newZoom = this.state.zoom\n resolutionChanged = false\n } else {\n const targetBinSize = (currentResolution.binSize / this.state.pixelSize) / scaleFactor\n newZoom = this.findMatchingZoomIndex(targetBinSize, bpResolutions)\n newBinSize = bpResolutions[newZoom].binSize\n resolutionChanged = newZoom !== this.state.zoom\n newPixelSize = Math.min(MAX_PIXEL_SIZE, newBinSize / targetBinSize)\n }\n const z = await this.minZoom(this.state.chr1, this.state.chr2)\n\n\n if (!this.resolutionLocked && scaleFactor < 1 && newZoom < z) {\n // Zoom out to whole genome\n const xLocus = this.parseLocusString('1')\n const yLocus = { xLocus }\n await this.setChromosomes(xLocus, yLocus)\n } else {\n\n await this.state.panWithZoom(newZoom, newPixelSize, anchorPx, anchorPy, newBinSize, this, this.dataset, this.contactMatrixView.getViewDimensions(), bpResolutions)\n\n await this.contactMatrixView.zoomIn(anchorPx, anchorPy, 1/scaleFactor)\n\n await this.update(HICEvent(\"LocusChange\", { state: this.state, resolutionChanged, chrChanged: false }))\n }\n } finally {\n this.stopSpinner()\n }\n }\n\n }\n\n // Zoom in response to a double-click\n /**\n * Zoom and center on bins at given screen coordinates. Supports double-click zoom, pinch zoom.\n * @param direction\n * @param centerPX screen coordinate to center on\n * @param centerPY screen coordinate to center on\n * @returns {Promise}\n */\n async zoomAndCenter(direction, centerPX, centerPY) {\n\n if (undefined === this.dataset) {\n console.warn('Dataset is undefined')\n return\n }\n\n if (this.dataset.isWholeGenome(this.state.chr1) && direction > 0) {\n // jump from whole genome to chromosome\n const genomeCoordX = centerPX * this.dataset.wholeGenomeResolution / this.state.pixelSize\n const genomeCoordY = centerPY * this.dataset.wholeGenomeResolution / this.state.pixelSize\n const chrX = this.genome.getChromosomeForCoordinate(genomeCoordX)\n const chrY = this.genome.getChromosomeForCoordinate(genomeCoordY)\n const xLocus = { chr: chrX.name, start: 0, end: chrX.size, wholeChr: true }\n const yLocus = { chr: chrY.name, start: 0, end: chrY.size, wholeChr: true }\n await this.setChromosomes(xLocus, yLocus)\n } else {\n\n const { width, height } = this.contactMatrixView.getViewDimensions()\n\n const dx = centerPX === undefined ? 0 : centerPX - width / 2\n this.state.x += (dx / this.state.pixelSize)\n\n const dy = centerPY === undefined ? 0 : centerPY - height / 2\n this.state.y += (dy / this.state.pixelSize)\n\n const resolutions = this.getResolutions()\n const directionPositive = direction > 0 && this.state.zoom === resolutions[resolutions.length - 1].index\n const directionNegative = direction < 0 && this.state.zoom === resolutions[0].index\n if (this.resolutionLocked || directionPositive || directionNegative) {\n\n const minPS = await this.minPixelSize(this.state.chr1, this.state.chr2, this.state.zoom)\n\n const newPixelSize = Math.max(Math.min(MAX_PIXEL_SIZE, this.state.pixelSize * (direction > 0 ? 2 : 0.5)), minPS)\n\n const shiftRatio = (newPixelSize - this.state.pixelSize) / newPixelSize\n\n this.state.pixelSize = newPixelSize\n\n\n this.state.x += shiftRatio * (width / this.state.pixelSize)\n this.state.y += shiftRatio * (height / this.state.pixelSize)\n\n this.state.clampXY(this.dataset, this.contactMatrixView.getViewDimensions())\n\n this.state.configureLocus(this, this.dataset, { width, height })\n\n this.update(HICEvent(\"LocusChange\", {state: this.state, resolutionChanged: false, chrChanged: false}))\n\n } else {\n let i\n for (i = 0; i < resolutions.length; i++) {\n if (this.state.zoom === resolutions[i].index) break\n }\n if (i) {\n const newZoom = resolutions[i + direction].index\n this.setZoom(newZoom)\n }\n }\n }\n }\n\n /**\n * Set the current zoom state and opctionally center over supplied coordinates.\n * @param zoom - index to the datasets resolution array (dataset.bpResolutions)\n * @returns {Promise}\n */\n async setZoom(zoom) {\n\n const resolutionChanged = await this.state.setWithZoom(zoom, this.contactMatrixView.getViewDimensions(), this, this.dataset)\n\n await this.contactMatrixView.zoomIn()\n\n this.update(HICEvent(\"LocusChange\", { state: this.state, resolutionChanged, chrChanged: false }))\n\n }\n\n async setChromosomes(xLocus, yLocus) {\n\n const { index:chr1Index } = this.genome.getChromosome(xLocus.chr)\n const { index:chr2Index } = this.genome.getChromosome(yLocus.chr)\n\n this.state.chr1 = Math.min(chr1Index, chr2Index)\n this.state.x = 0\n\n this.state.chr2 = Math.max(chr1Index, chr2Index)\n this.state.y = 0\n\n this.state.locus =\n {\n x: { chr: xLocus.chr, start: xLocus.start, end: xLocus.end },\n y: { chr: yLocus.chr, start: yLocus.start, end: yLocus.end }\n };\n\n if (xLocus.wholeChr && yLocus.wholeChr) {\n this.state.zoom = await this.minZoom(this.state.chr1, this.state.chr2)\n const minPS = await this.minPixelSize(this.state.chr1, this.state.chr2, this.state.zoom)\n this.state.pixelSize = Math.min(100, Math.max(DEFAULT_PIXEL_SIZE, minPS))\n } else {\n // Whole Genome\n this.state.zoom = 0\n const minPS = await this.minPixelSize(this.state.chr1, this.state.chr2, this.state.zoom)\n this.state.pixelSize = Math.max(this.state.pixelSize, minPS)\n\n }\n\n await this.update(HICEvent(\"LocusChange\", {state: this.state, resolutionChanged: true, chrChanged: true}))\n\n }\n\n /**\n * Called on loading tracks\n * @returns {Promise}\n */\n async updateLayout() {\n\n this.state.clampXY(this.dataset, this.contactMatrixView.getViewDimensions())\n\n for (const trackXYPair of this.trackPairs) {\n\n trackXYPair.x.viewportElement.style.order = `${this.trackPairs.indexOf(trackXYPair)}`\n trackXYPair.y.viewportElement.style.order = `${this.trackPairs.indexOf(trackXYPair)}`\n\n trackXYPair.x.syncCanvas()\n trackXYPair.y.syncCanvas()\n\n }\n\n this.layoutController.xAxisRuler.update()\n this.layoutController.yAxisRuler.update()\n\n setTrackReorderArrowColors(this.trackPairs)\n\n await this.update()\n\n }\n\n /**\n * Set the matrix state. Used to restore state from a bookmark\n * @param state browser state\n */\n async setState(state) {\n\n const chrChanged = !this.state || this.state.chr1 !== state.chr1 || this.state.chr2 !== state.chr2\n\n this.state = state.clone()\n\n // Possibly adjust pixel size\n const minPS = await this.minPixelSize(this.state.chr1, this.state.chr2, this.state.zoom)\n this.state.pixelSize = Math.max(state.pixelSize, minPS)\n\n // Derive locus if none is present in source state\n if (undefined === state.locus) {\n const viewDimensions = this.contactMatrixView.getViewDimensions();\n this.state.configureLocus(this, this.dataset, viewDimensions)\n }\n\n const hicEvent = new HICEvent(\"LocusChange\", { state: this.state, resolutionChanged: true, chrChanged })\n this.update(hicEvent)\n this.eventBus.post(hicEvent)\n }\n\n /**\n * Return a modified state object used for synching. Other datasets might have different chromosome ordering\n * and resolution arrays\n */\n getSyncState() {\n return {\n chr1Name: this.dataset.chromosomes[this.state.chr1].name,\n chr2Name: this.dataset.chromosomes[this.state.chr2].name,\n binSize: this.dataset.bpResolutions[this.state.zoom],\n binX: this.state.x, // TODO: translate to lower right corner\n binY: this.state.y,\n pixelSize: this.state.pixelSize\n }\n }\n\n /**\n * Return true if this browser can be synced to the given state\n * @param syncState\n */\n canBeSynched(syncState) {\n\n if (false === this.synchable) return false // Explicitly not synchable\n\n return this.dataset &&\n (this.dataset.getChrIndexFromName(syncState.chr1Name) !== undefined) &&\n (this.dataset.getChrIndexFromName(syncState.chr2Name) !== undefined)\n\n }\n\n async syncState(targetState) {\n\n if (!targetState || false === this.synchable) return\n\n if (!this.dataset) return\n\n const { zoomChanged, chrChanged } = this.state.sync(targetState, this, this.genome, this.dataset)\n\n const payload = { state: this.state, resolutionChanged: zoomChanged, chrChanged }\n this.update(HICEvent(\"LocusChange\", payload, false))\n\n }\n\n setNormalization(normalization) {\n\n this.state.normalization = normalization\n this.eventBus.post(HICEvent(\"NormalizationChange\", this.state.normalization))\n }\n\n shiftPixels(dx, dy) {\n\n if (undefined === this.dataset) {\n console.warn('dataset is undefined')\n return\n }\n\n this.state.panShift(dx, dy, this, this.dataset, this.contactMatrixView.getViewDimensions())\n\n const locusChangeEvent = HICEvent(\"LocusChange\", {\n state: this.state,\n resolutionChanged: false,\n dragging: true,\n chrChanged: false\n })\n locusChangeEvent.dragging = true\n\n this.update(locusChangeEvent)\n this.eventBus.post(locusChangeEvent)\n }\n\n /**\n * Update the maps and tracks. This method can be called from the browser event thread repeatedly, for example\n * while mouse dragging. If called while an update is in progress queue the event for processing later. It\n * is only neccessary to queue the most recent recently received event, so a simple instance variable will suffice\n * for the queue.\n *\n * @param event\n */\n async update(event) {\n\n if (this.updating) {\n const type = event ? event.type : \"NONE\"\n this.pending.set(type, event)\n } else {\n this.updating = true\n try {\n\n this.startSpinner()\n if (event !== undefined && \"LocusChange\" === event.type) {\n this.layoutController.xAxisRuler.locusChange(event)\n this.layoutController.yAxisRuler.locusChange(event)\n }\n\n const promises = []\n\n for (let xyTrackRenderPair of this.trackPairs) {\n promises.push(this.renderTrackXY(xyTrackRenderPair))\n }\n promises.push(this.contactMatrixView.update(event))\n await Promise.all(promises)\n\n if (event && event.propogate) {\n let syncState1 = this.getSyncState()\n for (const browser of [...this.synchedBrowsers]) {\n browser.syncState(syncState1)\n }\n }\n\n } finally {\n this.updating = false\n if (this.pending.size > 0) {\n const events = []\n for (let [k, v] of this.pending) {\n events.push(v)\n }\n this.pending.clear()\n for (let e of events) {\n this.update(e)\n }\n }\n if (event) {\n // possibly, unless update was called from an event post (infinite loop)\n this.eventBus.post(event)\n }\n this.stopSpinner()\n }\n }\n }\n\n repaintMatrix() {\n this.contactMatrixView.imageTileCache = {}\n this.contactMatrixView.initialImage = undefined\n this.contactMatrixView.update()\n }\n\n resolution() {\n return this.dataset.bpResolutions[this.state.zoom]\n };\n\n toJSON() {\n\n if (!(this.dataset && this.dataset.url)) return \"{}\" // URL is required\n\n const jsonOBJ = {}\n\n jsonOBJ.backgroundColor = this.contactMatrixView.stringifyBackgroundColor()\n jsonOBJ.url = this.dataset.url\n if (this.dataset.name) {\n jsonOBJ.name = this.dataset.name\n }\n\n jsonOBJ.state = this.state.toJSON()\n\n jsonOBJ.colorScale = this.contactMatrixView.getColorScale().stringify()\n if (Globals.selectedGene) {\n jsonOBJ.selectedGene = Globals.selectedGene\n }\n let nviString = this.dataset.hicFile.config.nvi\n if (nviString) {\n jsonOBJ.nvi = nviString\n }\n if (this.controlDataset) {\n jsonOBJ.controlUrl = this.controlUrl\n if (this.controlDataset.name) {\n jsonOBJ.controlName = this.controlDataset.name\n }\n const displayMode = this.getDisplayMode()\n if (displayMode) {\n jsonOBJ.displayMode = this.getDisplayMode()\n }\n nviString = this.controlDataset.hicFile.config.nvi\n if (nviString) {\n jsonOBJ.controlNvi = nviString\n }\n const controlMapWidget = this.ui.getComponent('controlMap');\n if (controlMapWidget.getDisplayModeCycle() !== undefined) {\n jsonOBJ.cycle = true\n }\n }\n\n if (this.trackPairs.length > 0 || this.tracks2D.length > 0) {\n let tracks = []\n jsonOBJ.tracks = tracks\n for (let trackRenderer of this.trackPairs) {\n\n const track = trackRenderer.x.track\n const config = track.config\n\n if (typeof config.url === \"string\") {\n\n const t = {url: config.url}\n\n if (config.type) {\n t.type = config.type\n }\n if (config.format) {\n t.format = config.format\n }\n if (track.name) {\n t.name = track.name\n }\n if (track.dataRange) {\n t.min = track.dataRange.min\n t.max = track.dataRange.max\n }\n if (track.color) {\n t.color = track.color\n }\n tracks.push(t)\n } else if ('sequence' === config.type) {\n tracks.push({type: 'sequence', format: 'sequence'})\n }\n\n }\n for (const track2D of this.tracks2D) {\n if (typeof track2D.config.url === \"string\") {\n tracks.push(track2D.toJSON())\n }\n }\n }\n\n return jsonOBJ\n }\n\n async minZoom(chr1, chr2) {\n\n const chromosome1 = this.dataset.chromosomes[chr1]\n const chromosome2 = this.dataset.chromosomes[chr2]\n\n const { width, height } = this.contactMatrixView.getViewDimensions()\n const binSize = Math.max(chromosome1.size / width, chromosome2.size / height)\n\n const matrix = await this.dataset.getMatrix(chr1, chr2)\n if (!matrix) {\n throw new Error(`Data not avaiable for chromosomes ${chromosome1.name} - ${chromosome2.name}`)\n }\n return matrix.findZoomForResolution(binSize)\n }\n\n async minPixelSize(chr1, chr2, zoomIndex) {\n\n // bp\n const chr1Length = this.dataset.chromosomes[chr1].size\n const chr2Length = this.dataset.chromosomes[chr2].size\n\n const matrix = await this.dataset.getMatrix(chr1, chr2)\n const { zoom } = matrix.getZoomDataByIndex(zoomIndex, \"BP\")\n\n // bin = bp * bin/bp = bin\n const nBins1 = chr1Length / zoom.binSize\n const nBins2 = chr2Length / zoom.binSize\n\n const { width, height } = this.contactMatrixView.getViewDimensions()\n\n // pixel/bin\n return Math.min(width / nBins1, height / nBins2)\n\n }\n}\n\nexport { MAX_PIXEL_SIZE, DEFAULT_PIXEL_SIZE }\nexport default HICBrowser\n\n","import {createBrowserList, deleteAllBrowsers, getAllBrowsers, syncBrowsers} from \"./createBrowser.js\"\nimport {Globals} from \"./globals.js\"\nimport {StringUtils, BGZip} from \"../node_modules/igv-utils/src/index.js\";\n\nfunction toJSON() {\n const jsonOBJ = {};\n const browserJson = [];\n const allBrowsers = getAllBrowsers();\n for (let browser of allBrowsers) {\n browserJson.push(browser.toJSON());\n }\n jsonOBJ.browsers = browserJson;\n\n if (Globals.selectedGene) {\n jsonOBJ[\"selectedGene\"] = Globals.selectedGene;\n }\n\n const captionDiv = document.getElementById('hic-caption');\n if (captionDiv) {\n var captionText = captionDiv.textContent;\n if (captionText) {\n captionText = captionText.trim();\n if (captionText) {\n jsonOBJ.caption = captionText;\n }\n }\n }\n\n return jsonOBJ;\n}\n\nfunction compressedSession() {\n const jsonString = JSON.stringify(toJSON());\n return `session=blob:${BGZip.compressString(jsonString)}`\n}\n\n\nasync function restoreSession(container, session) {\n\n deleteAllBrowsers();\n\n if (session.hasOwnProperty(\"selectedGene\")) {\n Globals.selectedGene = session.selectedGene;\n }\n if (session.hasOwnProperty(\"caption\")) {\n const captionText = session.caption;\n var captionDiv = document.getElementById(\"hic-caption\");\n if (captionDiv) {\n captionDiv.textContent = captionText;\n }\n }\n\n await createBrowserList(container, session);\n\n if (false !== session.syncDatasets) {\n syncBrowsers();\n }\n\n}\n\n\nexport {toJSON, restoreSession, compressedSession}","/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2016-2017 The Regents of the University of California\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and\n * associated documentation files (the \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the\n * following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all copies or substantial\n * portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING\n * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n *\n */\nimport State from './hicState.js';\nimport ColorScale from \"./colorScale.js\"\nimport {Globals} from \"./globals.js\";\nimport {StringUtils, BGZip} from '../node_modules/igv-utils/src/index.js'\n\nconst DEFAULT_ANNOTATION_COLOR = \"rgb(22, 129, 198)\";\n\nconst urlShortcuts = {\n \"*s3e/\": \"https://hicfiles.s3.amazonaws.com/external/\",\n \"*s3/\": \"https://hicfiles.s3.amazonaws.com/\",\n \"*s3e_/\": \"http://hicfiles.s3.amazonaws.com/external/\",\n \"*s3_/\": \"http://hicfiles.s3.amazonaws.com/\",\n \"*enc/\": \"https://www.encodeproject.org/files/\"\n}\n\nasync function extractConfig(queryString) {\n\n let query = extractQuery(queryString);\n let sessionConfig;\n\n if (query.hasOwnProperty(\"session\")) {\n if (query.session.startsWith(\"blob:\") || query.session.startsWith(\"data:\")) {\n sessionConfig = JSON.parse(BGZip.uncompressString(query.session.substr(5)));\n } else {\n // TODO - handle session url\n\n }\n }\n\n if (query.hasOwnProperty(\"juiceboxURL\")) {\n const jbURL = await expandURL(query[\"juiceboxURL\"]) // Legacy bitly urls\n query = extractQuery(jbURL);\n }\n\n if (query.hasOwnProperty(\"juicebox\") || query.hasOwnProperty(\"juiceboxData\")) {\n let q;\n if (query.hasOwnProperty(\"juiceboxData\")) {\n q = BGZip.uncompressString(query[\"juiceboxData\"])\n } else {\n q = query[\"juicebox\"];\n if (q.startsWith(\"%7B\")) {\n q = decodeURIComponent(q);\n }\n }\n\n q = q.substr(1, q.length - 2); // Strip leading and trailing bracket\n const parts = q.split(\"},{\");\n const browsers = [];\n for (let p of parts) {\n const qObj = extractQuery(decodeURIComponent(p));\n browsers.push(decodeQuery(qObj))\n }\n sessionConfig = {browsers};\n }\n\n // Try query parameter style\n const uriDecode = true;\n const queryConfig = decodeQuery(query, uriDecode);\n if (queryConfig.url) {\n sessionConfig = queryConfig;\n }\n\n // Fix certain defaults\n if (sessionConfig) {\n if (sessionConfig.browsers) {\n for (let b of sessionConfig.browsers) {\n fixDefaults(b);\n }\n } else {\n fixDefaults(sessionConfig);\n }\n }\n\n return sessionConfig;\n\n}\n\nfunction fixDefaults(browserConfig) {\n if (browserConfig.tracks) {\n for (let t of browserConfig.tracks) {\n if (t.color === DEFAULT_ANNOTATION_COLOR) {\n delete t.color;\n }\n if (t.min !== undefined && Number.isNaN(t.min)) {\n delete t.min;\n }\n if (t.max !== undefined && Number.isNaN(t.max)) {\n delete t.max;\n }\n t.displayMode = \"COLLAPSED\";\n }\n }\n}\n\n\n/**\n * Extend config properties with query parameters\n *\n * @param query\n * @param config\n */\nfunction decodeQuery(query, uriDecode) {\n\n const config = {};\n\n let hicUrl = query[\"hicUrl\"];\n const name = query[\"name\"];\n let stateString = query[\"state\"];\n let colorScale = query[\"colorScale\"];\n let trackString = query[\"tracks\"];\n const selectedGene = query[\"selectedGene\"];\n const nvi = query[\"nvi\"];\n\n let controlUrl = query[\"controlUrl\"];\n const controlName = query[\"controlName\"];\n const displayMode = query[\"displayMode\"];\n const controlNvi = query[\"controlNvi\"];\n const cycle = query[\"cycle\"];\n\n if (hicUrl) {\n hicUrl = paramDecode(hicUrl, uriDecode);\n Object.keys(urlShortcuts).forEach(function (key) {\n var value = urlShortcuts[key];\n if (hicUrl.startsWith(key)) hicUrl = hicUrl.replace(key, value);\n });\n config.url = hicUrl;\n\n }\n if (name) {\n config.name = paramDecode(name, uriDecode);\n }\n if (controlUrl) {\n controlUrl = paramDecode(controlUrl, uriDecode);\n Object.keys(urlShortcuts).forEach(function (key) {\n var value = urlShortcuts[key];\n if (controlUrl.startsWith(key)) controlUrl = controlUrl.replace(key, value);\n });\n config.controlUrl = controlUrl;\n }\n if (controlName) {\n config.controlName = paramDecode(controlName, uriDecode);\n }\n\n if (stateString) {\n stateString = paramDecode(stateString, uriDecode);\n config.state = State.parse(stateString);\n }\n if (colorScale) {\n colorScale = paramDecode(colorScale, uriDecode);\n config.colorScale = ColorScale.parse(colorScale);\n }\n\n if (displayMode) {\n config.displayMode = paramDecode(displayMode, uriDecode);\n }\n\n if (trackString) {\n trackString = paramDecode(trackString, uriDecode);\n config.tracks = destringifyTracksV0(trackString);\n\n // If an oAuth token is provided append it to track configs.\n if (config.tracks && config.oauthToken) {\n config.tracks.forEach(function (t) {\n t.oauthToken = config.oauthToken;\n })\n }\n }\n\n if (selectedGene) {\n Globals.selectedGene = selectedGene;\n }\n\n config.cycle = cycle;\n\n if (nvi) {\n config.nvi = paramDecode(nvi, uriDecode);\n }\n if (controlNvi) {\n config.controlNvi = paramDecode(controlNvi, uriDecode);\n }\n\n return config;\n\n function destringifyTracksV0(tracks) {\n\n const trackStringList = tracks.split(\"|||\");\n const configList = [];\n for (let trackString of trackStringList) {\n\n const tokens = trackString.split(\"|\");\n const color = tokens.pop();\n let url = tokens.length > 1 ? tokens[0] : trackString;\n if (url && url.trim().length > 0 && \"undefined\" !== url) {\n const keys = Object.keys(urlShortcuts);\n for (let key of keys) {\n var value = urlShortcuts[key];\n if (url.startsWith(key)) {\n url = url.replace(key, value);\n break;\n }\n }\n const trackConfig = {url: url};\n\n if (tokens.length > 1) {\n trackConfig.name = replaceAll(tokens[1], \"$\", \"|\");\n }\n\n if (tokens.length > 2) {\n const dataRangeString = tokens[2];\n if (dataRangeString.startsWith(\"-\")) {\n const r = dataRangeString.substring(1).split(\"-\");\n trackConfig.min = -parseFloat(r[0]);\n trackConfig.max = parseFloat(r[1]);\n } else {\n const r = dataRangeString.split(\"-\");\n trackConfig.min = parseFloat(r[0]);\n trackConfig.max = parseFloat(r[1]);\n }\n }\n\n if (color) {\n trackConfig.color = color;\n }\n\n configList.push(trackConfig);\n }\n }\n return configList;\n }\n\n}\n\n\nfunction paramDecode(str, uriDecode) {\n\n if (uriDecode) {\n return decodeURIComponent(str); // Still more backward compatibility\n } else {\n var s = replaceAll(str, '%26', '&');\n s = replaceAll(s, '%20', ' ');\n s = replaceAll(s, '+', ' ');\n s = replaceAll(s, \"%7C\", \"|\");\n s = replaceAll(s, \"%23\", \"#\");\n s = replaceAll(s, \"%3F\", \"?\");\n s = replaceAll(s, \"%3D\", \"=\");\n return s;\n }\n}\n\n\nfunction replaceAll(str, target, replacement) {\n return str.split(target).join(replacement);\n}\n\nfunction extractQuery(uri) {\n var i1, i2, i, j, s, query, tokens;\n\n query = {};\n i1 = uri.indexOf(\"?\");\n i2 = uri.lastIndexOf(\"#\");\n const i3 = uri.indexOf(\"=\");\n if (i1 > i3) i1 = -1;\n\n if (i2 < 0) i2 = uri.length;\n for (i = i1 + 1; i < i2;) {\n\n j = uri.indexOf(\"&\", i);\n if (j < 0) j = i2;\n\n s = uri.substring(i, j);\n tokens = s.split(\"=\", 2);\n if (tokens.length === 2) {\n query[tokens[0]] = tokens[1];\n }\n\n i = j + 1;\n\n }\n return query;\n}\n\n/**\n * Expand legacy bitly URLs\n * @param url\n * @returns {Promise<*>}\n */\nasync function expandURL(url) {\n\n const endpoint = `https://api-ssl.bitly.com/v4/expand`;\n const id = url.startsWith(\"http://\") ? url.substring(7) : url.substring(8);\n const message = {\n \"bitlink_id\": id\n }\n\n const response = await fetch(endpoint, {\n method: 'POST', // or 'PUT'\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${btoa(\"ëtá¾´ãÎtsß\u001aéÆºÙçµóf¸í¿9sn\u001déÝz\")}`\n },\n body: JSON.stringify(message),\n })\n\n if (!response.ok) {\n throw new Error(`Network error (${response.status}): ${response.statusText}`)\n }\n const json = await response.json();\n let longUrl = json.long_url;\n\n // Fix some Bitly \"normalization\"\n longUrl = longUrl.replace(\"{\", \"%7B\").replace(\"}\", \"%7D\");\n return longUrl;\n\n}\n\nexport {extractConfig}\n","/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2016-2017 The Regents of the University of California\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and\n * associated documentation files (the \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the\n * following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all copies or substantial\n * portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING\n * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n *\n */\n\nimport {igvxhr} from '../node_modules/igv-utils/src/index.js'\nimport {createBrowser, setCurrentBrowser, getAllBrowsers, getCurrentBrowser} from './createBrowser.js';\nimport {version} from \"./version.js\";\nimport {compressedSession, restoreSession, toJSON} from \"./session.js\";\nimport {init} from \"./init.js\"\nimport EventBus from \"./eventBus.js\"\n\nexport default {\n version,\n init,\n toJSON,\n restoreSession,\n compressedSession,\n createBrowser,\n getCurrentBrowser,\n setCurrentBrowser,\n getAllBrowsers,\n igvxhr,\n EventBus\n}\n","const version = \"2.5.2\"\nexport {version} //, commit}","/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2016-2017 The Regents of the University of California\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and\n * associated documentation files (the \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the\n * following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all copies or substantial\n * portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING\n * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n *\n */\n\nimport {extractConfig} from \"./urlUtils.js\"\nimport {getCurrentBrowser} from \"./createBrowser.js\"\nimport {getAllBrowsers} from \"./createBrowser.js\"\nimport {restoreSession} from \"./session.js\"\nimport {Alert} from \"../node_modules/igv-ui/dist/igv-ui.js\"\n\nasync function init(container, config) {\n\n Alert.init(container);\n\n if (false !== config.queryParametersSupported) {\n const queryConfig = await extractConfig(window.location.href);\n if(queryConfig) {\n config= queryConfig;\n }\n }\n\n await restoreSession(container, config);\n\n const allBrowsers = getAllBrowsers();\n\n return allBrowsers.length === 1 ? allBrowsers[0] : allBrowsers\n}\n\n\nexport {\n init\n}\n\n\n\n\n"],"names":["isString","x","String","numberFormatter","rawNumber","dec","split","reverse","reduce","prev","now","i","join","splitLines","string","getFilename","urlOrFile","undefined","name","index","lastIndexOf","filename","substr","indexOf","Error","isFile","object","File","hasOwnProperty","slice","arrayBuffer","process","window","global","atob","str","Buffer","from","toString","options","strictMode","key","q","parser","strict","loose","zero$1","buf","len","length","LITERALS$1","L_CODES$1","D_CODES$1","MAX_BITS$1","extra_lbits","Uint8Array","extra_dbits","extra_blbits","bl_order","static_ltree","Array","zero$1$2","static_dtree","_dist_code","_length_code","MAX_MATCH$1","base_length","base_dist","StaticTreeDesc","static_tree","extra_bits","extra_base","elems","max_length","this","has_stree","static_l_desc","static_d_desc","static_bl_desc","TreeDesc","dyn_tree","stat_desc","max_code","d_code","dist","put_short","s","w","pending_buf","pending","send_bits","value","bi_valid","bi_buf","send_code","c","tree","bi_reverse","code","res","gen_codes","bl_count","next_code","bits","n","init_block","dyn_ltree","dyn_dtree","bl_tree","END_BLOCK","opt_len","static_len","sym_next","matches","bi_windup","smaller","m","depth","_n2","_m2","pqdownheap","k","v","heap","j","heap_len","compress_block","ltree","dtree","lc","extra","sx","sym_buf","build_tree","desc","stree","node","heap_max","base","h","xbits","f","overflow","gen_bitlen","scan_tree","curlen","prevlen","nextlen","count","max_count","min_count","REP_3_6","REPZ_3_10","REPZ_11_138","send_tree","static_init_done","_tr_stored_block$1","stored_len","last","set","subarray","_tr_flush_block_1","opt_lenb","static_lenb","max_blindex","level","strm","data_type","block_mask","detect_data_type","l_desc","d_desc","bl_desc","BL_CODES$1","build_bl_tree","strategy","lcodes","dcodes","blcodes","rank","send_all_trees","trees","_tr_init","LENGTH_CODES$1","tr_static_init","_tr_stored_block","_tr_flush_block","_tr_tally","sym_end","_tr_align","STATIC_TREES","bi_flush","adler32_1","adler","pos","s1","s2","crcTable","Uint32Array","table","makeTable","crc32_1","crc","t","end","messages","constants$2","Z_NO_FLUSH","Z_PARTIAL_FLUSH","Z_SYNC_FLUSH","Z_FULL_FLUSH","Z_FINISH","Z_BLOCK","Z_TREES","Z_OK","Z_STREAM_END","Z_NEED_DICT","Z_ERRNO","Z_STREAM_ERROR","Z_DATA_ERROR","Z_MEM_ERROR","Z_BUF_ERROR","Z_NO_COMPRESSION","Z_BEST_SPEED","Z_BEST_COMPRESSION","Z_DEFAULT_COMPRESSION","Z_FILTERED","Z_HUFFMAN_ONLY","Z_RLE","Z_FIXED","Z_DEFAULT_STRATEGY","Z_BINARY","Z_TEXT","Z_UNKNOWN","Z_DEFLATED","Z_NO_FLUSH$2","Z_FULL_FLUSH$1","Z_FINISH$3","Z_BLOCK$1","Z_OK$3","Z_STREAM_END$3","Z_STREAM_ERROR$2","Z_DATA_ERROR$2","Z_BUF_ERROR$1","Z_DEFAULT_COMPRESSION$1","Z_DEFAULT_STRATEGY$1","Z_DEFLATED$2","MAX_MATCH","MIN_LOOKAHEAD","INIT_STATE","BUSY_STATE","FINISH_STATE","err","errorCode","msg","zero","slide_hash","p","wsize","w_size","hash_size","head","HASH","data","hash_shift","hash_mask","flush_pending","state","avail_out","output","pending_out","next_out","total_out","flush_block_only","block_start","strstart","put_byte","b","putShortMSB","read_buf","start","size","avail_in","input","next_in","wrap","total_in","longest_match","cur_match","match","chain_length","max_chain_length","scan","best_len","prev_length","nice_match","limit","_win","wmask","w_mask","strend","scan_end1","scan_end","good_match","lookahead","match_start","fill_window","_w_size","more","window_size","insert","ins_h","deflate_stored","flush","left","have","min_block","pending_buf_size","used","high_water","deflate_fast","hash_head","bflush","match_length","max_lazy_match","MIN_MATCH","deflate_slow","max_insert","prev_match","match_available","Config","good_length","max_lazy","nice_length","max_chain","func","configuration_table","DeflateState","status","gzhead","gzindex","method","last_flush","w_bits","hash_bits","Uint16Array","HEAP_SIZE","MAX_BITS","lit_bufsize","deflateStateCheck","deflateResetKeep","deflateReset","ret","deflateInit2","windowBits","memLevel","deflateSetDictionary_1","dictionary","dictLength","tmpDict","avail","next","deflate_1$2","deflateInit","deflateSetHeader","deflate","old_flush","header","level_flags","text","hcrc","comment","time","os","beg","copy","gzhead_extra","val","charCodeAt","bstate","deflate_huff","deflate_rle","deflateEnd","deflateSetDictionary","deflateInfo","_has","obj","Object","prototype","call","common","sources","arguments","source","shift","TypeError","chunks","l","result","chunk","STR_APPLY_UIA_OK","fromCharCode","apply","__","_utf8len","_utf8len$2","strings","TextEncoder","encode","c2","m_pos","str_len","buf_len","max","TextDecoder","decode","out","utf16buf","c_len","buf2binstring","zstream","toString$1","Z_NO_FLUSH$1","Z_FINISH$2","Z_OK$2","Z_STREAM_END$2","Z_DEFLATED$1","Deflate$1","chunkSize","opt","raw","gzip","ended","dict","_dict_set","deflate$1","deflator","push","Deflate$1$1","flush_mode","_flush_mode","onData","onEnd","deflateRaw_1$1","gzip_1$1","deflate_1$1","Deflate","deflateRaw","constants","BAD$1","inffast","_in","_out","dmax","whave","wnext","s_window","hold","lcode","dcode","lmask","dmask","here","op","from_source","lencode","distcode","lenbits","distbits","top","dolen","mode","sane","MAXBITS","lbase","lext","dbase","dext","inftrees","type","lens","lens_index","codes","table_index","work","opts","incr","fill","low","mask","sym","min","root","curr","drop","huff","offs","here_bits","here_op","here_val","Z_FINISH$1","Z_OK$1","Z_STREAM_END$1","Z_NEED_DICT$1","Z_STREAM_ERROR$1","Z_DATA_ERROR$1","Z_MEM_ERROR$1","HEAD","DICT","TYPE","TYPEDO","COPY_","LEN_","LEN","CHECK","BAD","zswap32","InflateState","havedict","flags","check","total","wbits","offset","ncode","nlen","ndist","lendyn","distdyn","back","was","inflateStateCheck","inflateResetKeep","Int32Array","inflateReset","inflateReset2","inflateInit2","lenfix","distfix","virgin","fixedtables","updatewindow","src","inflate_2$1","put","last_bits","last_op","last_val","hbuf","order","inf_leave","done","xflags","extra_len","inflate_1$2","inflateInit","inflate","inflateEnd","inflateGetHeader","inflateSetDictionary","dictid","inflateInfo","gzheader","Inflate$1","to","inflate$1","inflator","Inflate$1$2","last_avail_out","next_out_utf8","tail","utf8str","inflateRaw_1$1","inflate_1$1","Inflate","inflateRaw","ungzip","deflateRaw_1","inflateRaw_1","ungzip_1","ungzip_blocks","ba","ArrayBuffer","isView","lim","oBlockList","ptr","totalSize","byteLength","xlen","bsize","bytesLeft","cDataSize","a","unc","e","console","error","cursor","arrayCopy","unbgzf","buffer","hasSubarray","srcOffset","dest","destOffset","arrayCopy_fast","BYTES_PER_ELEMENT","byteOffset","arrayCopy_slow","uncompressString","enc","replace","compressedString","compressedBytes","bytes","IGVMath","Math","BinaryHeap","content","_random","random","BinaryHeap$1","element","bubbleUp","pop","sinkDown","remove","score","parentN","floor","parent","elemScore","child2N","child1N","swap","child1","child1Score","IGVColor","rgbListFromHSV","accumulation","r","hsvToRgb","rgbColor","rgbToHex","rgb","parseInt","hexToRgb","hex","cooked","exec","g","hslToRgb","hue2rgb","rgbaColor","greyScale","grey","randomGrey","round","randomRGB","randomRGBConstantAlpha","alpha","addAlpha","color","colorNameToHex","isHex","test","startsWith","idx","substring","log","rgbComponents","map","Number","trim","parseFloat","getCompositeColor","createColorString","endsWith","stripQuotes","includes","darkenLighten","amt","hexColor","components","colorName","aliceblue","antiquewhite","aqua","aquamarine","azure","beige","bisque","black","blanchedalmond","blue","blueviolet","brown","burlywood","cadetblue","chartreuse","chocolate","coral","cornflowerblue","cornsilk","crimson","cyan","darkblue","darkcyan","darkgoldenrod","darkgray","darkgreen","darkkhaki","darkmagenta","darkolivegreen","darkorange","darkorchid","darkred","darksalmon","darkseagreen","darkslateblue","darkslategray","darkturquoise","darkviolet","deeppink","deepskyblue","dimgray","dodgerblue","firebrick","floralwhite","forestgreen","fuchsia","gainsboro","ghostwhite","gold","goldenrod","gray","green","greenyellow","honeydew","hotpink","ivory","khaki","lavender","lavenderblush","lawngreen","lemonchiffon","lightblue","lightcoral","lightcyan","lightgoldenrodyellow","lightgrey","lightgreen","lightpink","lightsalmon","lightseagreen","lightskyblue","lightslategray","lightsteelblue","lightyellow","lime","limegreen","linen","magenta","maroon","mediumaquamarine","mediumblue","mediumorchid","mediumpurple","mediumseagreen","mediumslateblue","mediumspringgreen","mediumturquoise","mediumvioletred","midnightblue","mintcream","mistyrose","moccasin","navajowhite","navy","oldlace","olive","olivedrab","orange","orangered","orchid","palegoldenrod","palegreen","paleturquoise","palevioletred","papayawhip","peachpuff","peru","pink","plum","powderblue","purple","red","rosybrown","royalblue","saddlebrown","salmon","sandybrown","seagreen","seashell","sienna","silver","skyblue","slateblue","slategray","snow","springgreen","steelblue","tan","teal","thistle","tomato","turquoise","violet","wheat","white","whitesmoke","yellow","yellowgreen","darkgrey","darkslategrey","dimgrey","lightgray","lightslategrey","slategrey","DEFAULT_HOST","Oauth","constructor","oauthTokens","setToken","token","host","getToken","keys","wildcardToRegExp","removeToken","RegExp","regExpEscape","isGoogleURL","url","isGoogleStorageURL","isGoogleDriveURL","translateGoogleCloudURL","gsUrl","bucket","qIdx","bucketIdx","objIdx","queryIdx","idx1","idx2","idx3","parseBucketName","objectName","forEach","letter","encodings","has","get","Map","isInitialized","google","igv","getDriveDownloadURL","link","id","i1","i2","getGoogleDriveFileID","Throttle","requestsPerSecond","lastStartTime","queued","add","asyncFunction","self","Promise","resolve","reject","dequeue","addAll","promises","addedPromises","promise","bind","all","Date","inc","elapsed","_execute","setTimeout","candidate","isGoogleStorageSigned","getCurrentGoogleAccessToken","GoogleAuth.isInitialized","tokenResponse","tokenExpiresAt","access_token","arrayBufferToString","arraybuffer","plain","isgzipped","getGlobalObject","octets","octet","bytesNeeded","codePoint","fromCodePoint","decodeUTF8","igvxhr","apiKey","googleThrottle","RANGE_WARNING_GIVEN","oauth","contentLengthMap","setApiKey","loadArrayBuffer","responseType","_loadFileSlice","load","loadJson","sendData","contentType","loadString","JSON","parse","path","_loadStringFromFile","_loadStringFromUrl","urlType","dataURI","info","dataString","decodeURIComponent","decodeDataURI","range","rangeEnd","GoogleDrive.getDriveDownloadURL","GoogleUtils.isGoogleDriveURL","async","_loadURL","getContentLength","GET_CONTENT_LENGTH","contentLengthString","contentLength","mapUrl","oauthToken","getOauthToken","isAmazonV4Signed","GoogleUtils.isGoogleURL","GoogleUtils.isGoogleStorageURL","GoogleUtils.translateGoogleCloudURL","gapi","paramSeparator","addApiKey","addTeamDrive","headers","acToken","addOauthHeaders","xhr","XMLHttpRequest","body","mimeType","open","timeout","setRequestHeader","overrideMimeType","withCredentials","onload","event","getResponseHeader","response","alert","retries","handleError","tryGoogleAuth","onerror","ontimeout","onabort","send","accessToken","scope","GoogleAuth.getScopeForURL","accounts","oauth2","hasGrantedAllScopes","tokenClient","callback","expires_in","requestAccessToken","GoogleAuth.getAccessToken","fetchGoogleAccessToken","localfile","blob","setOauthToken","o","uri","$0","$1","$2","parseUri","googleToken","expires_at","NIL","NIL$1","right","arr","document$1","document","getProto","getPrototypeOf","concat","class2type","toString$3","hasOwn","fnToString","ObjectFunctionString","support","isFunction","nodeType","isWindow","preservedScriptAttributes","noModule","DOMEval","doc","script","createElement","appendChild","parentNode","removeChild","toType","version$1","jQuery","selector","context","fn","init","rtrim","isArrayLike","jquery","toArray","num","pushStack","merge","prevObject","each","elem","first","eq","sort","splice","extend","copyIsArray","clone","target","deep","isPlainObject","isArray","expando","isReady","noop","proto","Ctor","isEmptyObject","globalEval","makeArray","results","inArray","second","grep","invert","callbackExpect","arg","guid","Symbol","iterator","toLowerCase","Sizzle","Expr","getText","isXML","tokenize","compile","select","outermostContext","sortInput","hasDuplicate","setDocument","docElem","documentIsHTML","rbuggyQSA","rbuggyMatches","contains","preferredDoc","dirruns","classCache","createCache","tokenCache","compilerCache","sortOrder","push_native","list","booleans","whitespace","identifier","attributes","pseudos","rwhitespace","rcomma","rcombinators","rattributeQuotes","rpseudo","ridentifier","matchExpr","ID","CLASS","TAG","ATTR","PSEUDO","CHILD","bool","needsContext","rinputs","rheader","rnative","rquickExpr","rsibling","runescape","funescape","_","escaped","escapedWhitespace","high","rcssescape","fcssescape","ch","asCodePoint","unloadHandler","disabledAncestor","addCombinator","disabled","dir","childNodes","els","seed","nid","groups","newSelector","newContext","ownerDocument","getElementById","getElementsByTagName","getElementsByClassName","qsa","nodeName","getAttribute","setAttribute","toSelector","testContext","querySelectorAll","qsaError","removeAttribute","cache","cacheLength","markFunction","assert","el","siblingCheck","cur","diff","sourceIndex","nextSibling","createInputPseudo","createButtonPseudo","createDisabledPseudo","isDisabled","createPositionalPseudo","argument","matchIndexes","documentElement","hasCompare","subWindow","defaultView","addEventListener","attachEvent","className","createComment","getById","getElementsByName","filter","attrId","find","getAttributeNode","tag","tmp","innerHTML","matchesSelector","webkitMatchesSelector","mozMatchesSelector","oMatchesSelector","msMatchesSelector","disconnectedMatch","compareDocumentPosition","adown","bup","compare","sortDetached","aup","ap","bp","unshift","expr","elements","attr","attrHandle","specified","escape","sel","uniqueSort","duplicates","detectDuplicates","sortStable","textContent","firstChild","nodeValue","selectors","createPseudo","relative","preFilter","excess","unquoted","nodeNameSelector","pattern","operator","what","simple","forward","ofType","xml","uniqueCache","outerCache","nodeIndex","useCache","lastChild","uniqueID","pseudo","args","setFilters","matched","not","matcher","unmatched","innerText","lang","elemLang","hash","location","focus","activeElement","hasFocus","href","tabIndex","enabled","checked","selected","selectedIndex","empty","button","even","odd","lt","gt","radio","checkbox","file","password","image","submit","reset","tokens","combinator","skip","checkNonElements","doneName","oldCache","newCache","elementMatcher","matchers","condense","newUnmatched","mapped","setMatcher","postFilter","postFinder","postSelector","temp","preMap","postMap","preexisting","contexts","multipleContexts","matcherIn","matcherOut","matcherFromTokens","checkContext","leadingRelative","implicitRelative","matchContext","matchAnyContext","filters","parseOnly","soFar","preFilters","cached","setMatchers","elementMatchers","bySet","byElement","superMatcher","outermost","matchedCount","setMatched","contextBackup","dirrunsUnique","matcherFromGroupMatchers","compiled","unique","isXMLDoc","escapeSelector","until","truncate","is","siblings","rneedsContext","rsingleTag","winnow","qualifier","rootjQuery","parseHTML","ready","rparentsprev","guaranteedUnique","children","contents","sibling","targets","closest","prevAll","addBack","parents","parentsUntil","nextAll","nextUntil","prevUntil","contentDocument","rnothtmlwhite","Identity","Thrower","ex","adoptValue","noValue","fail","then","Callbacks","flag","createOptions","firing","memory","fired","locked","queue","firingIndex","fire","once","stopOnFalse","disable","lock","fireWith","Deferred","tuples","always","deferred","catch","pipe","fns","newDefer","tuple","returned","progress","notify","onFulfilled","onRejected","onProgress","maxDepth","handler","special","that","mightThrow","notifyWith","resolveWith","exceptionHook","stackTrace","rejectWith","getStackHook","stateString","when","singleValue","remaining","resolveContexts","resolveValues","master","updateFunc","rerrorNames","stack","warn","message","readyException","readyList","completed","removeEventListener","readyWait","wait","readyState","doScroll","access","chainable","emptyGet","bulk","rmsPrefix","rdashAlpha","fcamelCase","toUpperCase","camelCase","acceptData","owner","Data","uid","defineProperty","configurable","prop","hasData","dataPriv","dataUser","rbrace","rmultiDash","dataAttr","getData","removeData","_data","_removeData","attrs","startLength","hooks","_queueHooks","stop","setter","clearQueue","defer","pnum","rcssNum","cssExpand","isHiddenWithinTree","style","display","css","old","defaultDisplayMap","getDefaultDisplay","showHide","show","values","hide","toggle","rcheckableType","rtagName","rscriptType","wrapMap","option","thead","col","tr","td","_default","getAll","setGlobalEval","refElements","optgroup","tbody","tfoot","colgroup","caption","th","rhtml","buildFragment","scripts","selection","ignored","fragment","createDocumentFragment","nodes","htmlPrefilter","createTextNode","div","checkClone","cloneNode","noCloneChecked","defaultValue","rkeyEvent","rmouseEvent","rtypenamespace","returnTrue","returnFalse","safeActiveElement","on","types","one","origFn","off","handleObjIn","eventHandle","events","handleObj","handlers","namespaces","origType","elemData","handle","triggered","dispatch","delegateType","bindType","namespace","delegateCount","setup","mappedTypes","origCount","teardown","removeEvent","nativeEvent","handlerQueue","fix","delegateTarget","preDispatch","isPropagationStopped","currentTarget","isImmediatePropagationStopped","rnamespace","preventDefault","stopPropagation","postDispatch","matchedHandlers","matchedSelectors","addProp","hook","Event","enumerable","originalEvent","writable","noBubble","trigger","blur","click","beforeunload","returnValue","props","isDefaultPrevented","defaultPrevented","relatedTarget","timeStamp","isSimulated","stopImmediatePropagation","altKey","bubbles","cancelable","changedTouches","ctrlKey","detail","eventPhase","metaKey","pageX","pageY","shiftKey","view","char","charCode","keyCode","buttons","clientX","clientY","offsetX","offsetY","pointerId","pointerType","screenX","screenY","targetTouches","toElement","touches","which","mouseenter","mouseleave","pointerenter","pointerleave","orig","related","rxhtmlTag","rnoInnerhtml","rchecked","rcleanScript","manipulationTarget","disableScript","restoreScript","cloneCopyEvent","pdataOld","pdataCur","udataOld","udataCur","fixInput","domManip","collection","hasScripts","iNoClone","valueIsFunction","html","_evalUrl","keepData","cleanData","dataAndEvents","deepDataAndEvents","srcElements","destElements","inPage","detach","append","prepend","insertBefore","before","after","replaceWith","replaceChild","appendTo","prependTo","insertAfter","replaceAll","original","rnumnonpx","getStyles","opener","getComputedStyle","rboxStyle","curCSS","computed","width","minWidth","maxWidth","getPropertyValue","pixelBoxStyles","addGetHookIf","conditionFn","hookFn","computeStyleTests","container","cssText","divStyle","pixelPositionVal","reliableMarginLeftVal","roundPixelMeasures","marginLeft","pixelBoxStylesVal","boxSizingReliableVal","position","scrollboxSizeVal","offsetWidth","measure","backgroundClip","clearCloneStyle","boxSizingReliable","pixelPosition","reliableMarginLeft","scrollboxSize","rdisplayswap","rcustomProp","cssShow","visibility","cssNormalTransform","letterSpacing","fontWeight","cssPrefixes","emptyStyle","finalPropName","cssProps","capName","vendorPropName","setPositiveNumber","subtract","boxModelAdjustment","dimension","box","isBorderBox","styles","computedVal","delta","ceil","getWidthOrHeight","valueIsBorderBox","cssHooks","opacity","cssNumber","animationIterationCount","columnCount","fillOpacity","flexGrow","flexShrink","lineHeight","orphans","widows","zIndex","zoom","origName","isCustomProp","valueParts","tween","adjusted","scale","maxIterations","currentValue","initial","unit","initialInUnit","adjustCSS","setProperty","isFinite","getClientRects","getBoundingClientRect","margin","padding","border","prefix","suffix","expand","expanded","parts","delay","fx","speeds","clearTimeout","checkOn","optSelected","radioValue","boolHook","removeAttr","nType","attrHooks","attrNames","getter","lowercaseName","rfocusable","rclickable","stripAndCollapse","getClass","classesToArray","removeProp","propFix","propHooks","tabindex","for","class","addClass","classes","curValue","clazz","finalValue","removeClass","toggleClass","stateVal","isValidValue","classNames","hasClass","rreturn","valHooks","optionSet","focusin","rfocusMorph","stopPropagationCallback","onlyHandlers","bubbleType","ontype","lastElement","eventPath","isTrigger","parentWindow","simulate","triggerHandler","attaches","rbracket","rCRLF","rsubmitterTypes","rsubmittable","buildParams","traditional","param","valueOrFunction","encodeURIComponent","serialize","serializeArray","wrapAll","firstElementChild","wrapInner","htmlIsFunction","unwrap","hidden","visible","offsetHeight","createHTMLDocument","implementation","keepScripts","parsed","setOffset","curPosition","curLeft","curCSSTop","curTop","curOffset","curCSSLeft","curElem","using","rect","win","pageYOffset","pageXOffset","offsetParent","parentOffset","scrollLeft","scrollTop","scrollTo","Height","Width","defaultExtra","funcName","hover","fnOver","fnOut","unbind","delegate","undelegate","proxy","holdReady","parseJSON","isNumeric","isNaN","$$1","create$1","classList","applyStyle","cssStyle","_initialDisplay","d","translateMouseCoordinates","domElement","height","y","xNormalized","yNormalized","getMouseXY","domUtils","freeze","__proto__","create","pow","hideAll","pageCoordinates","touch","relativeDOMBBox","parentElement","childElement","x_p","y_p","width_p","height_p","x_c","y_c","width_c","height_c","entries","setPrototypeOf","isFrozen","getOwnPropertyDescriptor","seal","construct","Reflect","fun","thisValue","Func","arrayForEach","unapply","arrayPop","arrayPush","stringToLowerCase","stringToString","stringMatch","stringReplace","stringIndexOf","stringTrim","regExpTest","typeErrorCreate","_len2","_key2","thisArg","_len","_key","addToSet","array","transformCaseFunc","_transformCaseFunc","lcElement","newObject","property","lookupGetter","html$1","svg$1","svgFilters","svgDisallowed","mathMl$1","mathMlDisallowed","svg","mathMl","MUSTACHE_EXPR","ERB_EXPR","TMPLIT_EXPR","DATA_ATTR","ARIA_ATTR","IS_ALLOWED_URI","IS_SCRIPT_OR_DATA","ATTR_WHITESPACE","DOCTYPE_NAME","EXPRESSIONS","getGlobal","purify","createDOMPurify","DOMPurify","version","removed","isSupported","originalDocument","currentScript","DocumentFragment","HTMLTemplateElement","Node","Element","NodeFilter","NamedNodeMap","MozNamedAttrMap","HTMLFormElement","DOMParser","trustedTypes","ElementPrototype","getNextSibling","getChildNodes","getParentNode","template","trustedTypesPolicy","emptyHTML","createNodeIterator","importNode","IS_ALLOWED_URI$1","ALLOWED_TAGS","DEFAULT_ALLOWED_TAGS","ALLOWED_ATTR","DEFAULT_ALLOWED_ATTR","CUSTOM_ELEMENT_HANDLING","tagNameCheck","attributeNameCheck","allowCustomizedBuiltInElements","FORBID_TAGS","FORBID_ATTR","ALLOW_ARIA_ATTR","ALLOW_DATA_ATTR","ALLOW_UNKNOWN_PROTOCOLS","ALLOW_SELF_CLOSE_IN_ATTR","SAFE_FOR_TEMPLATES","WHOLE_DOCUMENT","SET_CONFIG","FORCE_BODY","RETURN_DOM","RETURN_DOM_FRAGMENT","RETURN_TRUSTED_TYPE","SANITIZE_DOM","SANITIZE_NAMED_PROPS","KEEP_CONTENT","IN_PLACE","USE_PROFILES","FORBID_CONTENTS","DEFAULT_FORBID_CONTENTS","DATA_URI_TAGS","DEFAULT_DATA_URI_TAGS","URI_SAFE_ATTRIBUTES","DEFAULT_URI_SAFE_ATTRIBUTES","MATHML_NAMESPACE","SVG_NAMESPACE","HTML_NAMESPACE","NAMESPACE","IS_EMPTY_INPUT","ALLOWED_NAMESPACES","DEFAULT_ALLOWED_NAMESPACES","PARSER_MEDIA_TYPE","SUPPORTED_PARSER_MEDIA_TYPES","CONFIG","formElement","isRegexOrFunction","testValue","Function","_parseConfig","cfg","ADD_URI_SAFE_ATTR","ADD_DATA_URI_TAGS","ALLOWED_URI_REGEXP","ADD_TAGS","ADD_ATTR","TRUSTED_TYPES_POLICY","createHTML","createScriptURL","purifyHostElement","createPolicy","ATTR_NAME","hasAttribute","policyName","scriptUrl","_createTrustedTypesPolicy","MATHML_TEXT_INTEGRATION_POINTS","HTML_INTEGRATION_POINTS","COMMON_SVG_AND_HTML_ELEMENTS","ALL_SVG_TAGS","ALL_MATHML_TAGS","_forceRemove","_removeAttribute","attribute","_initDocument","dirty","leadingWhitespace","dirtyPayload","parseFromString","createDocument","_createIterator","SHOW_ELEMENT","SHOW_COMMENT","SHOW_TEXT","_isNode","_executeHook","entryPoint","currentNode","_sanitizeElements","elm","namespaceURI","hasChildNodes","tagName","allowedTags","_basicCustomElementTest","parentTagName","Boolean","_checkValidNamespace","_isValidAttribute","lcTag","lcName","_sanitizeAttributes","hookEvent","attrName","attrValue","keepAttr","allowedAttributes","forceKeepAttr","getAttributeType","setAttributeNS","_sanitizeShadowDOM","shadowNode","shadowIterator","nextNode","sanitize","importedNode","returnNode","nodeIterator","shadowroot","shadowrootmode","serializedHTML","outerHTML","doctype","setConfig","clearConfig","isValidAttribute","addHook","hookFunction","removeHook","removeHooks","removeAllHooks","createCheckbox$1","initialState","iconMarkup","borderColor","borderWidth","borderStyle","label","createIcon","icon","icons","createElementNS","cog","exclamation","minus","plus","question","save","search","share","spinner","square","times","wrench","icons$1","createCheckbox","attachDialogCloseHandlerWithParent","closeHandler","uiUtils","dragData","makeDraggable","constraint","dragFunction","drag","dragEndFunction","dragEnd","computedStyle","dx","dy","minY","httpMessages","AlertDialog","alertProps","assign","shouldFocus","preventScroll","errorHeadline","bodyContainer","ok_container","ok","okHandler","present","clean","InputDialog","input_container","cancel","clampLocation","wh","innerHeight","ww","innerWidth","appleCrayonPalette","licorice","lead","tungsten","iron","steel","tin","nickel","aluminum","magnesium","mercury","cayenne","mocha","aspargus","fern","clover","moss","ocean","midnight","eggplant","maraschino","tangerine","lemon","spring","seam_foam","blueberry","grape","strawberry","cantaloupe","banana","flora","spindrift","ice","sky","bubblegum","carnation","GenericContainer","dispose","ColorPicker","defaultColors","colorHandler","super","createColorSwatchSelector","hexColorStrings","hexColorString","swatch","decorateSwatch","backgroundColor","Popover","title","popover","popoverHeader","titleElement","popoverContent","presentContentWithEvent","present$1","presentMenu","menuItems","menuElements","itemList","item","colorPicker","clickHandler","handleClick","createMenuElements$1","xmax","GenericColorPicker","configure","colorHandlers","setActiveColorHandler","createSwatches","activeColorHandler","stylesheetExists","stylesheetName","ss","styleSheets","embedCSS$2","MenuUtils","trackMenuItemList","trackView","vizWindowTypes","Set","hasVizWindow","track","config","visibilityWindow","browser","inputDialog","getTrackLabelText","trackRenameMenuItem","number","minHeight","maxHeight","setTrackHeight","checkContentHeight","repaintViews","autoHeight","trackHeightMenuItem","showColorPicker","colorPickerMenuItem","$e","unsetColorMenuItem","altColor","unsetAltColorMenuItem","menuItemList","updateViews","visibilityWindowMenuItem","removable","removeTrack","trackRemovalMenuItem","numericDataMenuItems","dataRangeDialog","columnContainer","logScale","autoscale","trackMenuItemListHelper","menuPopup","createMenuItem","action","presentColorPicker","viewports","$trackLabel","DataRangeDialog","$parent","$container","$header","$minimum_input","$maximum_input","$minimum","$mindiv","$maximum","$maxdiv","$buttons","$ok","$cancel","dataRange","processResults","setDataRange","offset_top","scroll_top","isString$2","numberFormatter$1","splitLines$5","splitStringRespectingQuotes","delim","quote","charAt","capitalize","getFilename$2","download","zero$1$1","LITERALS$1$1","L_CODES$1$1","D_CODES$1$1","static_ltree$1","static_dtree$1","_dist_code$1","_length_code$1","MAX_MATCH$1$1","base_length$1","base_dist$1","LENGTH_CODES$1$1","adler32_1$1","crcTable$1","makeTable$1","crc32_1$1","messages$1","constants$2$1","_has$1","common$1","STR_APPLY_UIA_OK$1","_utf8len$1","strings$1","buf2binstring$1","zstream$1","BAD$1$1","inffast$1","MAXBITS$1","lbase$1","lext$1","dbase$1","dext$1","inftrees$1","Z_FINISH$1$1","Z_BLOCK$2","Z_TREES$1","Z_OK$1$1","Z_STREAM_END$1$1","Z_NEED_DICT$1$1","Z_STREAM_ERROR$1$1","Z_DATA_ERROR$1$1","Z_MEM_ERROR$1$1","Z_BUF_ERROR$2","Z_DEFLATED$3","HEAD$1","DICT$1","TYPE$2","TYPEDO$1","COPY_$1","LEN_$1","LEN$1","CHECK$1","BAD$2","zswap32$1","InflateState$1","inflateResetKeep$1","inflateReset$1","inflateReset2$1","inflateInit2$1","lenfix$1","distfix$1","virgin$1","fixedtables$1","updatewindow$1","inflate_2$1$1","inflate_1$2$1","gzheader$1","toString$2","Z_NO_FLUSH$3","Z_FINISH$4","Z_OK$4","Z_STREAM_END$4","Z_NEED_DICT$2","Z_STREAM_ERROR$3","Z_DATA_ERROR$3","Z_MEM_ERROR$2","Inflate$1$1","inflate$1$1","inflateRaw_1$1$1","inflate_1$1$1","Inflate$2","inflate$3","inflateRaw$2","ungzip$2","inflate_1$3","ungzip_1$1","bgzBlockSize$1","decodeDataURI$1","selectElement","LN2","createColorStringSafe","stripQuotes$1","isColorComponent","encodings$1","getAccessToken","getApiKey","loadByteArray","_url","mapUrl$1","requestedHeaders","headerMap","getScopeForURL","IntervalTree","Interval","treeInsert","leftRotate","rightRotate","findOverlapping","searchInterval","intervals","searchAll","logIntervals","logNode","indent","space","interval","mapIntervals","applyInterval","applyUpdate","overlaps","nodeMax","intervalHigh","nodeMin","intervalLow","equals","other","compareTo","FeatureCache$1","featureList","genome","treeMap","buildTreeMap","containsRange","genomicRange","chr","queryFeatures","allFeatures","indexRange","feature","getAllFeatures","chromosomes","getChromosomeName","geneList","chrFeatures","f1","f2","buildIntervalTree$1","subArray","IndexRange","iStart","iEnd","FeatureUtils","buildIntervalTree","intervalFeatures","appleCrayonRGBPalette","sea_foam","colorPalettes","Set1","Dark2","Set2","Set3","Pastel1","Pastel2","Accent","PaletteColorTable","palette","colors","colorTable","nextIdx","colorGenerator","RandomColorGenerator","getColor","ColorTable","hue","goldenRatio","hexwidth","randomRGB$1","h_i","padHex","saturation","IGVGraphics","configureHighDPICanvas","ctx","scaleFactor","devicePixelRatio","canvas","setProperties","properties","strokeLine","x1","y1","x2","y2","beginPath","moveTo","lineTo","stroke","restore","fillRect","fillPolygon","doPath","strokePolygon","fillText","transforms","transform","translate","rotate","PI","strokeText","strokeCircle","radius","arc","fillCircle","drawArrowhead","lineWidth","closePath","dashedLine","dashLen","setLineDash","roundRect","quadraticCurveTo","polygon","drawRandomColorVerticalLines","fillStyle","labelTransformWithContext","exe","Alert","dialog","FileFormats","gwascatalog","fields","wgrna","cpgislandext","clinVarMain","isSimpleType","simpleTypes","valueType","toFixed","buildOptions","defaultOptions","doAutoscale","features","MAX_VALUE","validateGenomicExtent","chromosomeLengthBP","genomicExtent","minimumBP","ee","center","getFilename$1","json","googleDriveURL","endPoint","fetch","Authorization","getDriveFileInfo","originalFileName","prettyBasePairNumber","units","isDataURL","createColumn","column","insertElementBefore","referenceNode","insertElementAfter","isSecureContext","protocol","hostname","decodeBedpe","chr1","start1","end1","chr2","start2","end2","hiccups","columnNames","isHiccups","stdColumns","strand1","strand2","colorColumn","thicknessColumn","thickness","extras","decodeBedpeDomain","columns","knownFileExtensions","getFormat","format","expandFormat","inferFileFormat","ext","inferIndexPath","extension","inferTrackType","featureType","translateDeprecatedTypes","inferFileFormatFromHeader","firstBytes","registerFileFormats","TrackUtils","pairs","complements","p1","p2","reverseComplementSequence","sequence","comp","Chromosome","bpLength","splitLines$4","reservedProperties$1","NonIndexedFasta","reference","fastaURL","chromosomeNames","sequences","loadAll","getSequence","seqSlice","seq","seqEnd","chrNameSet","lines","nextLine","lineNo","current","pushChromosome","nameParts","locusParts","SequenceSlice","GenomicInterval","splitLines$3","reservedProperties","FastaSequence","indexFile","indexURL","compressedIndexFile","compressedIndexURL","offsets","getIndex","qstart","qend","seqBytes","readSequence","indexEntry","basesPerLine","bytesPerLine","getCompressedIndex","compressedIndex","gziData","givenFileSize","numBlocksBuffer","numBlocks","DataView","getBigUint64","expectedFileSize","blockNumber","bufferBlockStart","bufferBlockEnd","bufferBlock","viewBlock","compressedPosition","uncompressedPosition","getRelevantCompressedBlockNumbers","queryPositionStart","queryPositionEnd","highestBlockNumber","searchLow","searchHigh","searchPosition","solutionFound","iteration","searchUncompressedPosition","nextSearchUncompressedPosition","Infinity","blockIndex","finalRelevantBlock","loadAndUncompressBlocks","blockIndices","startByte","resultCache","currentBlockNumber","currentBlockCompressedPosition","nextBlockNumber","compressedLength","uncompressedBytes","idxEntry","nEndBytes","startLine","endLine","endByte","byteCount","allBytes","relevantBlockIndices","nBases","srcPos","allBytesLength","splitLines$2","ChromSizes","chrLength","chromosome","loadFasta","fasta","indexed","defaultNucleotideColors","A","C","T","G","N","defaultSequenceTrackOrder","MIN_SAFE_INTEGER","translationDict","TTT","TTC","TTA","TTG","CTT","CTC","CTA","CTG","ATT","ATC","ATA","ATG","GTT","GTC","GTA","GTG","TCT","TCC","TCA","TCG","CCT","CCC","CCA","CCG","ACT","ACC","ACA","ACG","GCT","GCC","GCA","GCG","TAT","TAC","TAA","CAT","CAC","CAA","CAG","AAT","AAC","AAA","AAG","GAT","GAC","GAA","GAG","TGT","TGC","TGA","TGG","CGT","CGC","CGA","CGG","AGT","AGC","AGA","AGG","GGT","GGC","GGA","GGG","complement","t1","t2","TRANSLATED_HEIGHT","SequenceTrack","sequenceType","disableButtons","ignoreTrackMenu","reversed","frameTranslate","vp","setContentHeight","contextMenuItemList","clickState","viewport","referenceFrame","bpPerPixel","bpWindow","getWidth","items","navigator","clipboard","writeText","translateSequence","threeFrame","fNum","st","aa","codons","aminoA","getSequenceSource","WrappedFasta","getFeatures","sequenceSource","bpStart","draw","cv","sequenceBpStart","bpEnd","pixelWidth","seqIdx","aPixel","baseLetter","fillColor","SEQUENCE_HEIGHT","textPixel","measureText","axis","strokeStyle","translatedSequence","aaSequence","bpOffset","p0","pc","aaLabel","supportsWholeGenome","computePixelHeight","ignore","getState","revealed","chrNameMap","chrName","Viewport","viewportColumn","$viewport","contentTop","contentHeight","initializationHelper","showMessage","messageDiv","hideMessage","setTrackLabel","startSpinner","stopSpinner","checkZoomIn","setTop","loadFeatures","clearCache","repaint","drawConfiguration","roiFeatures","cachedFeatures","displayMode","requiredContentHeight","getContentHeight","isLoading","saveSVG","isVisible","setWidth","getContentTop","containsPosition","addMouseHandlers","removeMouseHandlers","randomString","holder","chars","randomstring","getDominantBaseline","textBaseline","mapping","alphabetic","hanging","bottom","middle","normalize","vector","sqrt","namedEntities","radix","entity","base10","lookup","createNamedToNumberedLookup","STYLES","svgAttr","lineCap","lineJoin","miterLimit","globalAlpha","font","shadowColor","shadowOffsetX","shadowOffsetY","shadowBlur","textAlign","lineDash","CanvasGradient","gradientNode","__root","__ctx","addColorStop","__createElement","CanvasPattern","enableMirroring","__document","__canvas","getContext","isSVG","__setDefaultStyles","__stack","__getStyleState","__groupStack","viewbox","__ids","__defs","multiLocusGap","backdropConfig","backdropColor","backdropRect","__rootGroup","__currentElement","setHeight","elementName","resetFill","__applyStyleState","styleState","__applyStyleToCurrentElement","currentElement","currentStyleGroup","__currentElementsToStyle","__closestGroupOrSvg","getSerializedSvg","fixNamedEntities","regexp","serialized","XMLSerializer","serializeToString","getSvg","saveWithTranslationAndClipRect","tx","ty","clipYOffset","clip_id","clipPath","group","__addTransform","__applyCurrentDefaultPath","addTrackGroupWithTranslationAndClipRect","angle","degrees","cx","cy","__currentDefaultPath","__currentPosition","__addPathCommand","command","bezierCurveTo","cp1x","cp1y","cp2x","cp2y","cpx","cpy","arcTo","x0","y0","unit_vec_p1_p0","unit_vec_p1_p2","cos","theta","acos","abs","unit_vec_p1_origin","len_p1_origin","sin","unit_vec_origin_start_tangent","unit_vec_origin_end_tangent","getAngle","startAngle","endAngle","rect1","rect2","r2","strokeRect","strokeEllipse","rx","ry","rotation","isCCW","__ellipse","fillEllipse","__clearCanvas","rootGroup","clearRect","createLinearGradient","grad","gradientUnits","createRadialGradient","r0","r1","fy","__parseFont","fontPart","family","weight","decoration","__fontUnderline","__fontHref","__wrapTextLink","__applyText","textElement","counterClockwise","endX","endY","startX","startY","sweepFlag","largeArcFlag","xAxisRotation","clip","newGroup","drawImage","dw","dh","sw","sh","defs","svgImage","sy","translateDirective","transformDirective","originTransform","toDataURL","createPattern","repetition","img","dashArray","drawFocusRing","createImageData","getImageData","putImageData","globalCompositeOperation","setTransform","Cytoband","typestain","stain","splitLines$1","GenomeUtils","loadGenome","cytobandUrl","cytobandURL","aliasURL","aliases","line","loadAliases","Genome","cytobands","lastChr","bands","loadCytobands","initializeGenomes","KNOWN_GENOMES","loadDefaultGenomes","processJson","genomeList","genomes","jsonArray","isWholeGenomeView","expandReference","idOrConfig","genomeID","generateGenomeID","featureDB","wholeGenomeView","wgChromosomes","chromosomeOrder","wgChromosomeNames","nm","threshold","numericChromosomes","isDigit","alphaChromosomes","accumulator","constructWG","chrAliasTable","alias","defName","showWholeGenomeView","toJSON","tracks","getInitialLocus","getHomeChromosomeName","getChromosome","getCytobands","getLongestChromosome","longestChr","getChromosomes","getGenomeCoordinate","getCumulativeOffset","getChromosomeCoordinate","genomeCoordinate","cumulativeOffsets","computeCumulativeOffsets","lastCoord","cumulativeOffset","acc","queryChr","getGenomeLength","cname","addFeaturesToDB","insertFeature","gene","searchableFields","getAttributeValue","popupTimerID","lastClickTime","lastHoverUpdateTime","TrackViewport","$spinner","$zoomInNotice","createZoomInNotice","trackLabelsVisible","featureCache","redraw","txt","viewIsReady","zoomedOutOfWindow","pixelOffset","vt","pixelTop","vb","pixelHeight","bpWidth","loading","roiSets","roiSet","mr","FeatureCache","disposed","repaintDimensions","isWGV","viewportHeight","pixelXOffset","canvasTop","newCanvas","supportHiDPI","viewportWidth","refresh","calculateEnd","savePNG","canvasMetadata","imageData","exportCanvas","exportCtx","deltaX","deltaY","renderViewportToSVG","referenceFrameList","URL","createObjectURL","Blob","drawSVGWithContext","renderSVGContext","renderTrackLabelSVG","stringWidth","yClipOffset","needsRepaint","needsReload","addViewportContextMenuHandler","md","enableClick","mouseDownOnViewport","mu","dragObject","isScrolling","cancelTrackPan","endTrackDrag","hoverText","createClickState","tooltip","addViewportClickHandler","addTrackLabelClickHandler","trackMenuItems","presentTrackContextMenu","mouseX","mouseXCanvas","xBP","toBP","doubleClickDelay","centerBP","loci","locusSearchString","zoomWithScaleFactor","shiftClick","popupData","getPopupContent","trackLabel","description","viewportCoords","canvasCoords","genomicLocation","canvasX","canvasY","dataList","popupClickHandlerResult","fireEvent","nameValue","tileStart","tileEnd","multiresolution","overlapsRange","decodeInteract","transcriptTypes","cdsTypes","codonTypes","utrTypes","exonTypes","transcriptPartTypes","cltn","isIntron","isCoding","isUTR","isTranscript","isTranscriptPart","filterPopupProperties","GFFFeature","pd","geneObject","attributeString","atts","parseAttributeString","attributeName","_attributeCache","GFFTranscript","exons","addExon","addPart","assembleParts","lastStart","lastEnd","part","findExonContaining","psuedo","addCDS","addUTR","exon","cds","cdStart","cdEnd","utr","finish","exonData","att","partData","decodeGFFAttribute","strand","phase","decodeGFF3","keyLower","decodeGTF","idField","parentField","keyValueDelim","relaxed","kv","decoded","DecodeError","decodeBed","gffTags","UCSCBedFeature","attributeKVs","nameField","exonCount","exonSizes","exonStarts","eStart","eEnd","findUTRs$1","decodeRepeatMasker","swScore","milliDiv","milliDel","milliIns","repName","repClass","repFamily","repStart","repEnd","repLeft","decodeGenePred","decodeExons","decodeGenePredExt","decodeReflat","decodePSL","PSLFeature","exonCountToken","exonStartsToken","exonEndsToken","exonEnds","decodePeak","signal","pValue","qValue","decodeBedGraph","decodeWig","wig","step","span","chrom","decodeSNP","autoSql","repMatch","misMatch","qGapCount","tGapCount","qSize","misMatches","repMatches","nCount","qNumInsert","qBaseInsert","tNumInsert","tBaseInsert","decodeFusionJuncSpan","fusion_name","junction_left","junction_right","num_junction_reads","num_spanning_frags","spanning_frag_coords_text","spanning_frag_coords","min_coord","max_coord","coord_pairs","split_coords","span_left","span_right","decodeGtexGWAS","decodeCustom","customFormat","coords","field","decodeGcnv","sampleCount","FeatureParser","skipRows","delimiter","setDecoder","parseHeader","dataWrapper","parseTrackLine$1","parseColumnsDirective$1","tmpHeader","parseFeatures","errorCount","parseFixedStep","parseVariableStep","firstFeature","interChrFeatures","dup","fixBedPE","headerLine","tk","keyValue","TrackBase","static","defaults","colorString","autoscaleGroup","onclick","hoverTextFields","_name","setTrackLabelName","updateConfig","clearCachedFeatures","hasSamples","getGenomeId","setTrackProperties","tracklineConfg","useScore","viewLimitMin","viewLimitMax","UCSCTypeMappings","_derivedName","clickedFeatures","tolerance","extractPopupData","genomeId","filteredProperties","alleles","alleleFreqs","af","ref","alt","cravatLink","getCravatLink","posString","wrapKeyValue","metadata","getColorForFeature","_f","SegParser","sampleColumn","chrColumn","startColumn","endColumn","dataColumn","headings","extraHeaders","extractExtraColumns","valueColumnName","SegFeature","sample","extraValues","setAttributes","names","attributeNames","attributeValues","locationString","extractCravatLink","createVCFVariant","variant","Variant","referenceBases","alternateBases","quality","infoStr","altBases","altAlleles","refLength","determineType","heterozygosity","altTokens","isKnownAlt","altLength","lengthOnRef","lmin","altIdx","refIdx","alleleStart","alleleEnd","locString","altArray","arrayToString","getInfo","isRefBlock","knownAltBases","VcfParser","construtor","ltIdx","gtIdx","canonicalChromosome","callSets","nExpectedColumns","callFields","extractCallFields","calls","callSet","callSetName","callToken","genotypeIndex","genotype","CHR2","END","svComplement","pos2","GWASParser","posCol","chrCol","valueCol","parseHeaderLine","GWASFeature","aedRegexpNoNamespace","aedRegexpNamespace","AEDParser","decodeAed","parseTrackLine","parseColumnsDirective","readTokensAed","aed","parseAedHeaderRow","quotedString","parseAedToken","aedToken","AedFeature","allColumns","aedColumn","aedColumns","aedKey","nonEmptyTokens","featureValue","BinaryParser","dataView","littleEndian","available","remLength","hasNext","getByte","retValue","getUint8","getShort","getInt16","getUShort","getUint16","getInt","getInt32","getUInt","getUint32","getLong","getString","getFixedLengthString","getFixedLengthTrimmedString","getFloat","getFloat32","getDouble","getFloat64","getVPointer","block","VPointer","isLessThan","isGreaterThan","isEqualTo","print","optimizeChunks","lowest","c0","c1","dif","minv","maxv","mergedChunks","lastChunk","canMerge","chunk1","chunk2","CSIIndex","tabix","magic","indices","blockMin","MAX_SAFE_INTEGER","lastBlockPosition","sequenceIndexMap","minShift","seqNames","bmax","l_nm","nameEndPos","seq_name","MAX_BIN","bin_limit","nref","binIndex","loffset","nbin","binNumber","nchnk","cs","ce","chunksForRange","refId","overlappingBins","reg2bins","binRange","bin","binChunks","bins","BamIndex","blockMax","linearIndex","nintv","firstBlockPosition","minLin","maxLin","TribbleIndex","chrIndex","nProperties","readHeader","nChrs","binWidth","nBins","longestFeature","blocks","nextPos","chrIdx","adjustedPosition","startBinNumber","endBinNumber","startPos","endPos","loadIndex","dv","parseBamIndex","parseTabixIndex","parseCsiIndex","parseTribbleIndex","getDataWrapper","StringDataWrapper","ByteArrayDataWrapper","BGZLineReader","filePtr","bufferPtr","eof","readNextBlock","bsizeOptions","bufferSize","bgzBlockSize","BGZBlockLoader","cacheBlocks","startBlock","endBlock","skipEnd","getInflatedBlocks","nextEndBlock","startOffset","endOffset","inflateBlocks","loadBLockData","arrayBuffers","startBuffer","cachedBuffer","boundaries","findBlockBoundaries","endBuffer","skipStart","concatenateArrayBuffers","lastBlockSize","abuffer","loadOptions","byteLengh","blockBoundaries","cdata","FeatureFileReader","uriParts","queryable","getParser","defaultVisibilityWindow","gl","readFeatures","loadFeaturesWithIndex","loadFeaturesFromDataURI","loadFeaturesNoIndex","_blockLoader","maxSize","flatMap","previous","bgz","inflated","slicedFeatures","inInterval","isString$1","CustomServiceReader","mappings","mappingKeys","UCSCServiceReader","expandQueryInterval","db","tableName","cdsStart","cdsEnd","addExons","gffNameFields","GFFHelper","filterTypes","combineFeatures","genomicInterval","combinedFeatures","combineFeaturesById","combineFeaturesByType","numberExons","nameFeatures","chrIdMap","idMap","featureArray","cf","genes","geneMap","transcripts","consumedFeatures","transcriptId","gffTranscript","getParents","transcript","psuedoTranscript","e2","others","attributesMap","GtexReader","tissueId","tissueSiteDetailId","datasetId","queryStart","queryEnd","queryURL","singleTissueEqtl","eqtl","snp","snpId","geneName","geneSymbol","geneId","gencodeId","ImmVarReader","cellConditionId","valueThreshold","fulfill","eqtls","ga4ghGet","entityId","ga4ghSearch","loadChunk","pageToken","stringify","nextPageToken","Ga4ghVariantReader","variantSetId","callSetIds","includeCalls","variantSetIds","pageSize","csIdSet","csid","readMetadata","referenceBounds","rb","refName","referenceName","variants","valueArray","callSetId","createGAVariant","CivicReader","records","record","coordinates","CivicVariant","chromosome2","stop2","entrezName","entrez_name","actionabilityScore","civic_actionability_score","reference_bases","refBases","variant_bases","variant_types","log10","createLink","typeString","display_name","HtsgetReader","readHeaderData","getUrl","ticket","loadUrls","htsget","urls","readData","promiseArray","urlData","dataUriToBytes","newArray","concatArrays","inferFormat","headerURL","sourceType","endpoint","dataUri","decodeURI","HtsgetVariantReader","pack","maxRows","rows","row","computeWGFeatures","maxWGCount","makeWGFeature","wg","wgFeatures","featureDict","samplingProb","packFeatures","chrFeatureMap","chrs","flist","TextFeatureSource","queryableFormats","reader","searchable","trackType","getHeader","isWholeGenome","disableCache","intervalStart","intervalEnd","expandQuery","expansionWindow","assembleGFF","BufferedReader","dataViewForRange","requestedRange","asUint8","loadRange","bufferStart","e1","BUFFER_SIZE","BWReader","rpTreeCache","loader","DataBuffer","readWGFeatures","windowFunction","loadHeader","chrIdx2","chromTree","idToChrom","chrIdx1","chromToID","treeOffset","decodeFunction","zoomLevelHeaders","getZoomHeaders","zoomLevelHeader","zl","reductionLevel","zoomLevelForScale$1","indexOffset","decodeZoomData","fullIndexOffset","decodeWigData","getBedDataDecoder","rpTree","loadRPTree","leafItems","findLeafItemsOverlapping","dataOffset","dataSize","uint8Array","uncompressBuffSize","binaryParser","bwVersion","nZoomLevels","chromTreeOffset","fullDataOffset","fieldCount","definedFieldCount","autoSqlOffset","totalSummaryOffset","extensionOffset","nZooms","firstZoomDataOffset","zoomNumber","zlh","ZoomLevelHeader","autoSqlString","startDecoding","parseAutoSQL","totalSummary","BWTotalSummary","BPTree","dataCount","setDefaultVisibilityWindow","RPTree","getType","getTrackType","genomeSize","byteBuffer","reserved","fileOffset","rootNodeOffset","bufferedReader","rootNode","readNode","filePosition","isLeaf","range2","startChrom","startBase","endChrom","endBase","RPTreeNode","childOffset","processing","findLeafItems","nodeId","childNode","delete","minChromId","maxChromId","minStartBase","maxEndBase","blockSize","keySize","valSize","itemCount","chromToId","readTreeNode","chromId","bufferOffset","currOffset","basesCovered","minVal","maxVal","sumData","sumSquares","computeStats","mean","stddev","defaultRange","chrDict","blockStart","chromStart","chromEnd","itemStep","itemSpan","decoder","standardFieldCount","findUTRs","getDecoder","rest","validCount","BWSource","wgValues","isBigWig","getWGValues","getDefaultRange","wgFeature","TDFReader","groupCache","datasetCache","indexPos","indexSize","nWindowFunctions","windowFunctions","trackLine","nTracks","trackNames","compressed","datasetIndex","nEntries","groupIndex","readDataset","wf","zoomString","dsName","nAttributes","dataType","tileWidth","nTiles","tiles","dataset","readRootGroup","readGroup","maxZoomString","maxZoom","totalCountString","totalCount","canonicalName","readTiles","tileIndeces","firstEntry","lastEntry","tileData","tile","createFixedStep","createVariableStep","createBed","readTile","nPositions","nt","np","dtrack","TDFSource","_getFeatures","normalizationFactor","chrSize","log2","zoomLevelForScale","startTile","endTile","decodeBedTile","decodeVaryTile","decodeFixedTile","starts","ends","StaticFeatureSource","updateFeatures","fixFeatures","mapProperties","bbFormats","FeatureSource","ROI_DEFAULT_COLOR","appleCrayonRGBA","ROI_USER_DEFINED_COLOR","ROISet","isUserDefined","featureSource","DynamicFeatureSource","headerColor","addFeature","removeFeature","featureMap","screenCoordinates","regionStartBP","regionEndBP","bpp","xStart","chrKey","RulerSweeper","rulerViewport","rulerSweeper","isMouseHandlers","addBrowserObserver","boundObserverHandler","removeBrowserObserver","isMouseDown","isMouseIn","mouseDownX","boundContentMouseDownHandler","contentDiv","boundDocumentMouseMoveHandler","mouseCurrentX","clientWidth","boundDocumentMouseUpHandler","roiManager","updateUserDefinedROISet","minimumBases","updateReferenceFrame","PairedAlignment","firstAlignment","paired","readName","mate","scStart","connectingStart","connectingEnd","scEnd","scLengthOnRef","setSecondAlignment","secondAlignment","containsLocation","showSoftClips","alignmentContaining","nameValues","isPaired","isMateMapped","isProperPair","fragmentLength","firstOfPairStrand","isFirstOfPair","hasTag","BamAlignmentRow","alignments","findAlignment","alignmentContains","centerAlignment","getSortValue","alignmentContainer","alignment","readBaseAt","readBaseQualityAt","coverageMap","coverageMapIndex","coverage","baseScore","insertions","ins","delCount","del","calculateBaseScore","tags","gapSizeAt","mq","canBePaired","isSecondOfPair","isSecondary","isSupplementary","unpairAlignments","packAlignmentRows","packedAlignmentRows","alignmentRow","nextStart","nextIDX","allocated","startNewRow","clear","binarySearch$1","pred","lo","hi","mi","AlignmentContainer","samplingWindowSize","samplingDepth","pairsSupported","alleleFreqThreshold","CoverageMap","downsampledIntervals","pairsCache","downsampledReads","currentBucket","DownsampleBucket","isMapped","isFailsVendorQualityCheck","incCounts","finishBucket","addAlignment","hasDownsampledIntervals","downsampledCount","DownsampledInterval","setViewAsPairs","pairCache","pairedAlignment","pairAlignments","setShowSoftClips","allAlignments","repack","getMax","sortRows","newRows","undefinedRow","rowA","rowB","direction","rowAValue","rowBValue","replacedAlignment","maximum","qualityWeight","cov","incBlockCount","gaps","Coverage","qual","seqOffset","alleleThreshold","posA","negA","posT","negT","posC","negC","posG","negG","posN","negN","neg","qualA","qualT","qualC","qualG","qualN","isMismatch","refBase","mismatchQualitySum","counts","SupplementaryAlignment","rec","mapQ","numMismatches","lenOnRef","BamUtils","computeLengthOnReference","printString","createSupplementaryAlignments","ELEMENT_SIZE","S","I","BamAlignment","isDuplicate","isNegativeStrand","isMateNegativeStrand","tagDict","decodeTags","tagBA","insertion","ins_start","borderTop","cigar","half","MAX_CIGAR","yesNo","pairOrientation","sa","hiddenTags","blockAtGenomicLocation","seqIndexAt","gap","softClippedBlocks","interiorSeen","readInt$1","readInt8","readUInt8","readShort","readFloat","cc","elementType","elementSize","getInt8","AlignmentBlock","BamFilter","vendorFailed","secondary","supplementary","mqThreshold","readgroups","pass","rg","SEQ_DECODER","CIGAR_DECODER","BAM1_MAGIC_NUMBER","readInt","MAXIMUM_SAMPLING_DEPTH","compressedBuffer","uncba","decodeBamHeader","samHeaderLen","chrToIndex","chrNames","nRef","lName","magicNumber","bam_tag2cigar","block_end","seq_offset","lseq","al","cigarArray","type2size","cigar_len","cigar_offset","cigop","opLen","opLtr","ltr","decodeBamRecords","blockEnd","refID","bin_mq_nl","nl","flag_nc","nc","mateChrIdx","matePos","lastCigRecord","sb","qualArray","setPairOrientation","makeBlocks","decodeSamRecords","sam","qualString","rnext","buildOperators","decodeSamTags","setReaderDefaults","readgroup","viewAsPairs","o1","o2","isize","estReadLen","cigarString","scPos","operators","prevOp","BamReaderNonIndexed","bamPath","isDataUri","readAlignments","alignmentCache","qAlignments","parseAlignments","fetchAlignments","BamReader","baiPath","chrId","getChrIndex","indexToChr","ShardedBamReader","bamReaders","bamConfig","getReader","BamWebserviceReader","alignmentFile","referenceFile","HtsgetBamReader","gmodCRAM","__awaiter","throw","__importDefault","__esModule","default","some","CramMalformedError","containerStart","sliceStart","sliceBytes","filehandle","_parseCache","parseIndex","readFile","unzip","readUInt32LE","hasDataForReferenceSequence","getEntriesForRange","parameters","CramUnimplementedError","getBits","coreBlock","instantiateCodec","_getLengthCodec","_getDataCodec","lengthsEncoding","valuesEncoding","tinyMemoize","blockContentId","externalBlocks","getCursor","_decodeByteArray","stopByte","bytePosition","CramBufferOverrunError","_decodeData","_decodeInt","_decodeByte","parseItf8","bitPosition","codeBook","sortedByValue","sortedCodes","sortedValuesByBitCode","sortedBitCodes","sortedBitLengthsByBitCode","bitCodeToValue","buildCodeBook","buildCodes","buildCaches","bitLength","_decode","_decodeZeroLengthCode","numCodes","symbol","symbols","bitLengths","bitCode","u","codecId","K","CRAM_FLAG_PRESERVE_QUAL_SCORES","CRAM_FLAG_DETACHED","CRAM_FLAG_MATE_DOWNSTREAM","CRAM_FLAG_NO_SEQ","CRAM_FLAG_MASK","CRAM_M_REVERSE","CRAM_M_UNMAP","BAM_FPAIRED","BAM_FPROPER_PAIR","BAM_FUNMAP","BAM_FMUNMAP","BAM_FREVERSE","BAM_FMREVERSE","BAM_FREAD1","BAM_FREAD2","BAM_FSECONDARY","BAM_FQCFAIL","BAM_FDUP","BAM_FSUPPLEMENTARY","BAM_CMATCH","BAM_CINS","BAM_CDEL","BAM_CREF_SKIP","BAM_CSOFT_CLIP","BAM_CHARD_CLIP","BAM_CPAD","BAM_CEQUAL","BAM_CDIFF","BAM_CBACK","BAM_CIGAR_STR","BAM_CIGAR_SHIFT","BAM_CIGAR_MASK","BAM_CIGAR_TYPE","BF","CF","RI","RL","AP","RG","MF","NS","NP","TS","NF","TC","TN","FN","FC","FP","BS","IN","SC","DL","BA","BB","RS","PD","HC","MQ","RN","QS","QQ","TL","dataSeriesCodecCache","tagCodecCache","tagEncoding","readNamesIncluded","preservation","APdelta","referenceRequired","RR","tagIdsDictionary","TD","substitutionMatrix","SM","dataSeriesEncoding","_size","_endPosition","getCodecForTag","getTagNames","getCodecForDataSeries","_readContainerHeader","getCompressionHeaderBlock","numRecords","getSectionParsers","getFirstBlock","parseItem","cramCompressionHeader","contentPosition","parsedContent","readBlock","getCompressionScheme","getSlice","cramContainerHeader1","cramContainerHeader2","stat","allocUnsafe","maxLength","read","itf8Size","numLandmarks","validateChecksums","crc32","checkCrc32","fetchReferenceSequenceCallback","seqFetch","checkSequenceMD5","cacheSize","getDefinition","cramFileDefinition","majorVersion","getSamHeader","getContainerById","parseHeaderText","readInt32LE","getHeaderText","getContainerAtPosition","unsigned","containerCount","readBlockHeader","cramBlockHeader","_parseSection","_uncompress","bzip2","decompress","r4x16_uncompress","arith_uncompress","fqzcomp_uncompress","tok3_uncompress","uncompressedSize","compressionMethod","compressedSize","cramBlockCrc32","CramRecord","MateFlagsDecoder","CramFlagsDecoder","BamFlagsDecoder","MateFlags","CramFlags","BamFlags","cramFlags","readLength","mappingQuality","qualityScores","mateRecordNumber","readBases","mateToUse","readGroupId","sequenceId","uniqueId","templateSize","alignmentStart","mateFlags","mateReadName","mateSequenceId","mateAlignmentStart","isProperlyPaired","isSegmentUnmapped","isMateUnmapped","isReverseComplemented","isMateReverseComplemented","isRead1","isRead2","isFailedQc","isDetached","hasMateDownStream","isPreservingQualityScores","isUnknownBases","getReadBases","_refRegion","sub","getPairOrientation","templateLength","addReferenceSequence","refPos","isMappedSliceHeader","Parser","itf8","uint8","stripNull","formatter","uint32","choice","choices","MI","UI","nest","ents","refSeqId","cramUnmappedSliceHeader","ltf8","cramMappedSliceHeader","cramEncoding","namely","cramDataSeriesEncodingMap","cramTagEncodingMap","int32","fromBytesLE","toNumber","Int16Array","Int8Array","Float32Array","lastAlignmentStart","B","E","isUnmapped","setMateUnmapped","isOnNegativeStrand","setMateReverseComplemented","isWithMateDownstream","R","M","F","isDecodeSequenceAsStar","X","D","Q","H","P","containerPosition","getBlocks","getCoreDataBlock","_getBlocksContentIdIndex","contentId","getBlockByContentId","getReferenceRegion","refBaseBlockId","refSeqStart","refSeqSpan","CramArgumentError","getAllRecords","getRecords","_fetchRecords","md5","sequenceMD5","recordCounter","CramSizeLimitError","CramError","__createBinding","__setModuleDefault","__importStar","CraiIndex","IndexedCramFile","CramFile","cram","cramUrl","cramPath","cramFilehandle","fetchSizeLimit","getRecordsForRange","pairAcrossChr","maxInsertSize","toLocaleString","getRecordsInSlice","localeCompare","fromUrl","RemoteFile","LocalFile","pathname","unescape","ensureNotNullish","RANS_BYTE_L","TOTFREQ","TF_SHIFT","putAt","advanceSymbolStep","renormalize","setPosition","advanceSymbol","AriDecoder","fc","freq","symbolInit","advanceStep","readStatsO1","readStatsO0","getByteAt","RansDecSymbol","_buffer","_position","UInt8","UInt16LE","UInt16BE","UInt32LE","UInt32BE","Int8","Int16LE","Int16BE","Int32LE","Int32BE","FloatLE","FloatBE","DoubleLE","DoubleBE","UInt64","Int64","Skip","Choice","Nest","Bit","Itf8","Ltf8","varName","endian","constructorFn","setNextParser","zeroTerminated","greedy","encoding","readUntil","lengthInBytes","endianess","getCode","pushCode","generateError","addAliasedCode","addRawCode","generate","resolveReferences","markResolved","getUnresolvedReferences","markRequested","runInThisContext","sizeOf","NaN","generateAssert","generateVariable","generateFormatter","generateNext","generateBit","bitFields","generateTmpVariable","generateSkip","generateOption","generateString","generateBuffer","generateArray","addReference","pushScope","popScope","generateChoiceCase","pushPath","popPath","generateChoice","defaultChoice","generateNest","isInteger","generateItf8","generateLtf8","scopes","isAsync","tmpVariableCount","references","interpolate","resolved","requested","exports","globalThis","stream","decodeStream","ReadByte","ReadUint7","decodeStripe","decodePackMeta","decodeCat","decodeExt","decodeRLE1","decodeRLE0","decode1","decode0","decodePack","WriteByte","WriteUint7","encodeStripe","encodePack","WriteStream","encodeRLE1","encodeRLE0","encode1","encode0","RangeStartDecode","ModelDecode","ModelEncode","RangeFinishEncode","encodeExt","nsym","packMeta","WriteData","FFnum","carry","RangeGetFrequency","RangeDecode","RangeShiftLow","RangeEncode","total_freq","max_sym","ModelRenormalise","qctx","qshift","qtab","qbits","qloc","do_pos","ptab","ploc","do_delta","dtab","dloc","prevq","do_sel","sloc","ReadUint16","pflags","do_dedup","fixed_len","do_qmap","do_qtab","qmap","max_sel","stab","params","do_rev","rev","is_dup","nparam","pbits","pshift","dbits","dshift","sbits","do_stab","WriteUint16","exit","r4x8_uncompress","EOF","ReadData","ReadChar","ReadUint32","ReadString","ReadITF8","WriteChar","WriteString","WriteUint32","writeInt32LE","WriteITF8","WriteByteNeg","alloc","fillCallback","isAbortException","evict","addCallback","aborter","settled","statusReporter","aborted","addSignal","checkSinglePromise","AbortSignal","abort","signals","abortController","AbortController","handleAborted","callbacks","currentMessage","ReferenceError","listeners","sham","Proxy","valueOf","createEvent","initEvent","createEventObject","DOMException","reason","dispatchEvent","toStringTag","abortableFetch","Request","__FORCE_INSTALL_ABORTCONTROLLER_POLYFILL","isPrototypeOf","race","toByteArray","fromByteArray","isBuffer","readUInt32BE","writeInt32BE","signed","SlowBuffer","INSPECT_MAX_BYTES","RangeError","isEncoding","write","SharedArrayBuffer","Y","toPrimitive","V","Z","readUInt16BE","kMaxLength","TYPED_ARRAY_SUPPORT","foo","poolSize","allocUnsafeSlow","_isBuffer","swap16","swap32","swap64","inspect","_arr","O","BigInt","U","L","readUintLE","readUIntLE","readUintBE","readUIntBE","readUint8","readUint16LE","readUInt16LE","readUint16BE","readUint32LE","readUint32BE","readBigUInt64LE","W","readBigUInt64BE","readIntLE","readIntBE","readInt16LE","readInt16BE","readInt32BE","readBigInt64LE","readBigInt64BE","readFloatLE","readFloatBE","readDoubleLE","readDoubleBE","writeUintLE","writeUIntLE","writeUintBE","writeUIntBE","writeUint8","writeUInt8","writeUint16LE","writeUInt16LE","writeUint16BE","writeUInt16BE","writeUint32LE","writeUInt32LE","writeUint32BE","writeUInt32BE","writeBigUInt64LE","writeBigUInt64BE","writeIntLE","writeIntBE","writeInt8","writeInt16LE","writeInt16BE","writeBigInt64LE","writeBigInt64BE","writeFloatLE","writeFloatBE","writeDoubleLE","writeDoubleBE","copyWithin","z","ERR_OUT_OF_RANGE","ERR_INVALID_ARG_TYPE","ERR_BUFFER_OUT_OF_BOUNDS","$","J","permute","minLen","maxLen","utf8","stringToBytes","bytesToString","rotl","rotr","randomBytes","bytesToWords","wordsToBytes","bytesToHex","hexToBytes","bytesToBase64","base64ToBytes","BlobFile","baseOverrides","overrides","fetchImplementation","getBufferFromResponse","redirect","statusText","_stat","bytesRead","close","FileReader","readAsArrayBuffer","readAsText","WebAssembly","Instance","Module","__isLong__","isLong","fromInt","fromNumber","fromBits","mul","fromString","fromValue","ZERO","UZERO","ONE","UONE","NEG_ONE","MAX_UNSIGNED_VALUE","MIN_VALUE","toInt","isZero","isNegative","getHighBits","getHighBitsUnsigned","getLowBits","getLowBitsUnsigned","getNumBitsAbs","eqz","isPositive","isOdd","isEven","notEquals","neq","ne","lessThan","lessThanOrEqual","lte","le","greaterThan","greaterThanOrEqual","gte","ge","negate","multiply","get_high","divide","div_u","div_s","toUnsigned","shru","shr","shl","modulo","rem_u","rem_s","mod","rem","and","or","xor","shiftLeft","shiftRight","shiftRightUnsigned","shr_u","toSigned","toBytes","toBytesLE","toBytesBE","fromBytes","fromBytesBE","_ff","_gg","_hh","_ii","_blocksize","_digestsize","asBytes","asString","string2buf","Buf8","shrinkBuf","flattenChunks","binstring2buf","utf8border","buf2string","arraySet","setTyped","Buf16","Buf32","last_lit","l_buf","d_buf","maxKeys","_set","peek","nmd","ucs2","toASCII","toUnicode","slashes","auth","port","query","resolveObject","Url","javascript","http","https","ftp","gopher","isObject","parseHost","isNullOrUndefined","isNull","loaded","paths","CramReader","cramFile","FileHandler","seqID","indexFileHandle","indexedCramFile","samHeader","readGroups","alignmentEnd","decodeCramRecord","cramRecord","basesUsed","readPos","BufferCache","_fetch","readPosition","lruCache","QuickLRU","outputBuffer","firstChunk","fetches","_getChunk","chunkNumber","chunksOffset","chunkPositionStart","copyStart","copyEnd","copyOffset","cachedPromise","freshPromise","deleted","oldCacheSize","CigarOperationTable","ALIGNMENT_MATCH","INSERT","DELETE","SKIP","CLIP_SOFT","CLIP_HARD","PAD","SEQUENCE_MATCH","SEQUENCE_MISMATCH","Ga4ghAlignmentReader","readGroupSetIds","authKey","referenceSetId","populateChrAliasTable","decodeGa4ghReads","cigarDecoded","jsonRecords","fragmentName","properPlacement","duplicateFragment","numberReads","readNumber","failedVendorQualityChecks","secondaryAlignment","supplementaryAlignment","alignedSequence","alignedQuality","nextMatePosition","encodeCigar","translateCigar","reverseStrand","cigarUnit","operation","operationLength","gapType","BamSource","bamReader","inferIndexPath$1","getAlignments","hasAlignments","refSeq","paintAxis","flipAxis","prettyPrint","Locus","locus","getLocusString","fromLocusString","se","classCallCheck","instance","Constructor","createClass","defineProperties","descriptor","protoProps","staticProps","slicedToArray","_n","_d","_e","_s","_i","sliceIterator","needle","padStart","pad","colorNames","cb","tqw","qmrn","zr","bg","bsq","bck","nch","bvt","brwn","brw","ctb","hrt","chcT","cr","rnw","crns","crms","cn","Db","Dcn","Dgnr","Dgr","Dgrn","Dkhk","Dmgn","Dvgr","Drng","Drch","Dr","Dsmn","Dsgr","DsTb","DsTg","Dtrq","Dvt","ppnk","pskb","mgr","grb","rbrc","rwht","stg","chs","gnsb","gnr","gr","grn","grnw","hnw","htpn","nnr","ng","vr","khk","vnr","nrb","wngr","mnch","Lb","Lcr","Lcn","Lgnr","Lgr","Lgrn","Lpnk","Lsmn","Lsgr","Lskb","LsTg","Lstb","Lw","mgrn","nn","mgnt","mrn","mqm","mmb","mmrc","mmpr","mmsT","mtr","mmvt","mnLb","ntc","mstr","mccs","vjw","nv","vrb","rng","rngr","rch","pgnr","pgrn","ptrq","pvtr","ppwh","pchp","pr","pnk","pm","pwrb","prp","sbr","sbrw","smn","nbr","sgrn","ssh","snn","svr","skb","sTb","sTgr","snw","stb","tn","thst","tmT","trqs","whT","wht","hts","wgrn","printNum","decs","Color","rgba","_input$match$map","_input$match$map2","_a","hsla","_input$match$map3","_input$match$map4","_r","_g","_b","_a2","nameToRgb","parseString","vals","mults","suff","_rgba","_hsla","printRGB","rgbToHsl","hsl","printHSL","_ref","_ref2","_ref3","_ref4","EventBucket","_events","isMatch","_doRemove","dragTrack","eventBucket","area","dragging","clamp","onMove","starting","bounds","relX","relY","onMouse","onTouch","EVENT_KEY","EVENT_CLICK_OUTSIDE","EVENT_TAB_MOVE","querySelector","stopEvent","onKey","Picker","settings","popup","layout","editor","editorFormat","cancelButton","defaultColor","onChange","onDone","onOpen","onClose","setOptions","_this","HTMLElement","_popupInited","skipKeys","transfer","colour","_setColor","openProxy","openHandler","pointerEvents","toFocus","_domEdit","doHide","knownTime","__containedEvent","silent","failSilently","_setHSLA","setColor","toggled","_toggleDOM","_setPosition","wrapper","htmlString","_domH","_domSL","_domA","_domSample","_domOkay","_domCancel","_ifPopup","_updateUI","_bindEvents","destroy","_this2","dom","addEvent","editInput","fromEditor","selectionStart","selectionEnd","popupCloseProxy","timeKeeper","onDoneProxy","cssClass","cssHue","cssHSL","hslString","cssHSLA","hslaString","uiH","uiSL","uiA","thumbH","thumbSL","thumbA","posX","posY","opaque","transp","background","printHex","child","actionIf","actionElse","toVisible","displayStyle","getChrColor$1","chrColorMap$1","StyleElement","chrX","chrY","chrUn","chrI","chrII","chr2a","chr2b","chr3","chrIII","chr4","chrIV","chr5","chr6","chr7","chr8","chr9","chr10","chr11","chr12","chr13","chr14","chr15","chr16","chr17","chr18","chr19","chr20","chr21","chr22","chr23","chr24","chr25","chr26","chr27","chr28","chr29","chr30","chr31","chr32","chr33","chr34","chr35","chr36","chr37","chr38","chr39","chr40","chr41","chr42","chr43","chr44","chr45","chr46","chr47","chr48","ChordSetManager","chordSets","addChordSet","chordSet","trackName","IGVTrack","clearChords","getTrack","getChordSet","trackColor","chords","EXP5","exp","CircularView","isInstalled","groupByTrack","chordManager","createControls","resetControlPanel","assembly","setAssembly","setSize","toolbarDiv","toolbar","controlPanelDiv","controlPanel","buttonContainer","showControlsButton","showCloseButton","createGroupByCB","addToControlPanel","groupByCB","evt","render","groupByLabel","paddingLeft","trackPanelRow","paddingTop","paddingBottom","hideShowButton","hideChordSet","showChordSet","alphaSlider","alphaToValue","colorPickerButton","setAlpha","pickerConfig","rgbaString","getAlpha","picker","marginRight","oninput","trackNameDive","igvGenome","shortChrName$1","regions","shortName","trackId","adapter","refNameColors","addChords","newChords","viewState","session","setBpPerPx","minBpPerPx","getSize","clearSelection","pluginManager","rootModel","deleteTrack","trackID","findIndex","jbrowseTrack","displays","renderer","strokeColor","createViewState","JBrowseCircularGenomeView","JBrowseReactCircularGenomeView","ReactDOM","unmountComponentAtNode","visibleChordSets","jbrowseTracks","assemblyNames","React","onChordClick","defaultOnChordClick","showTrack","jexl","addFunction","chordTrack","embedCSS$1","shortChrName","makeCircViewChromosomes","getChrColor","sendChords","refFrame","baseColor","chordSetColor","encodedName","chordSetName","circularView","circularViewVisible","PairedEndStats","minTLENPercentile","maxTLENPercentile","frCount","rfCount","ffCount","sumF","sumF2","lp","up","isizes","compute","tlen","po","orienation","minTLEN","percentile","maxTLEN","GtexUtils","getTissueInfo","baseURL","trackConfiguration","tissueSummary","calculateFeatureCoordinates","xScale","px","px1","pw","renderFeature","py","featureHeight","squishedRowHeight","expandedRowHeight","h2","py2","coord","arrowSpacing","xLeft","xRight","ePxU","ePx","ePx1","ePw","drawLabel","renderFeatureLabel","featureX","featureX1","featureY","centerX","labelDisplayMode","labelY","getFeatureLabelY","geneColor","gtexSelection","gtexLoaded","colorForGene","geneFontStyle","textBox","xleft","xright","lastLabelX","rowLastLabelX","labelAllFeatures","codingNonSynonSet","codingSynonSet","spliceSiteSet","untranslatedSet","renderSnp","colorPriority","cls","theFunc","priorities","funcArray","colorArrLength","snpColors","colorBy","renderFusionJuncSpan","rowHeight","topY","bottomY","junctionLeftPx","junctionRightPx","spanningCoords","spanningInfo","spanLeftPx","spanRightPx","FeatureTrack","_featureSource","onDragEnd","unSubscribe","removedTrack","un","monitorTrackDrag","pallete","postInit","maxRow","isMergedTrack","rowFeatureCount","rowLastX","pixelsPerFeature","lastPxEnd","pxEnd","pxStart","featureData","infoURL","fd","isGFF","exonNumber","colorScheme","lut","COLLAPSED","SQUISHED","EXPANDED","RegionTableBase","columnFormat","tableRowSelectionList","tableDOM","headerDOM","tableColumnTitles","tableRowContainer","footerDOM","gotoButtonHandler","headerTitle","dismissHandler","dismiss","boundDismissHandler","y_root","y_parent","minX","_headerDOM","tblColumnTitles","_tableColumnTitlesDOM","tblRowContainer","_tableRowContainerDOM","gotoButton","_footerDOM","boundGotoButtonHandler","tableRowDOMHelper","setTableRowSelectionState","clearTable","isTableRowSelected","BlatTable","descriptionDOM","tableRowDOM","pretty","renderTable","getColumnFormatConfiguration","selectedRows","blat","userSeq","URLSearchParams","postData","maxSequenceSize","BlatTrack","openTableView","createBlatTrack","trackConfig","loadTrack","DEFAULT_ALIGNMENT_COLOR","BAMTrack","showCoverage","showAlignments","showAllBases","showInsertions","showMismatches","coverageTrackHeight","coverageTrack","CoverageTrack","alignmentTrack","AlignmentTrack","_height","assignSort","minTemplateLength","configMinTLEN","minFragmentLength","_pairedEndStats","maxTemplateLength","configMaxTLEN","maxFragmentLength","parseLocusString$1","sortObject","pairedEndStats","axisCanvas","clickedObject","getClickedObject","colorByMenuItems","hasPairs","tagLabel","colorByTag","colorByCB","adjustTrackHeight","getCachedAlignmentContainers","alignmentContainers","ac","hasSupplemental","addPairedChordsForViewport","addSplitChordsForViewport","$dml","menuItem","showCheck","ev","tagColors","inView","makePairedAlignmentChords","makeChords","supAl","makeSupplementalAlignmentChords","nucleotideColors","coverageColor","accumulatedHeight","nucleotide","hh","alignmentRowHeight","negStrandColor","posStrandColor","insertionColor","insertionTextColor","showInsertionText","deletionColor","deletionTextColor","showDeletionText","skippedColor","pairConnectorColor","smallTLENColor","smallFragmentLengthColor","largeTLENColor","largeFragmentLengthColor","pairOrienation","pairColors","rlColor","rrColor","llColor","bamColorTag","hideSmallIndels","indelSizeThreshold","downsampleRowHeight","referenceSequence","alignmentRowYInset","pixelBottom","xBlockStart","xBlockEnd","alignmentsYOffset","nRows","rowIndex","alignmentY","alignmentHeight","drawPairConnector","drawSingleAlignment","yRect","connectorColor","getConnectorColor","yStrokedLine","alignmentColor","getAlignmentColor","outlineColor","basesToDraw","drawBlock","sPixel","ePixel","gapLenText","gapTextWidth","gapCenter","textStart","lastXBlockStart","insertionBlock","refOffset","insertLenText","textPixelWidth","basePixelWidth","widthBlock","blockBasesToDraw","offsetBP","blockStartPixel","blockEndPixel","blockWidthPixel","nomPixelWidthOnRef","arrowHeadWidthPixel","isSoftClip","strokeOutline","highlightedAlignmentReadNamed","blockOutlineColor","lastBlockPositiveStrand","lastBlockReverseStrand","xListPixel","yListPixel","widthPixel","xPixel","readChar","refChar","shadedBaseColor","bbox","fontHeight","renderBlockOrReadChar","sortByOption","newSortObject","sortByTag","clickedAlignment","frameStart","frameEnd","addMultiLocusPanel","seqstring","softClips","clippedSequence","packedAlignmentsIndex","clicked","oTypes","orientationTypes","pairColor","tagValue","fr","F1R2","F2R1","F1F2","F2F1","R1R2","R2R1","R1F2","R2F1","rf","ff","chrColorMap","timer","currentViewport","RulerViewport","$viewportColumn","$multiLocusCloseButton","removeMultiLocusPanel","$rulerLabel","gotoMultilocusPanel","$tooltip","$tooltipContent","attachMouseHandlers","dismissLocusLabel","presentLocusLabel","textDiv","getMultiLocusLabel","textDivWidth","getMultiLocusLabelBPLengthOnly","pixel","searchString","mouseMove","cursorGuideVisible","isMultiLocusWholeGenomeView","IdeogramViewport","ideogram_ctx","boundClickHandler","chrCoveragePercentage","xPercentage","trackViews","createViewport","fontConfigureTemplate","SampleNameViewport","unused","trackScrollDelta","showSampleNames","checkCanvas","dpi","requiredHeight","clientHeight","requiredWidth","sampleNameViewportWidth","getSamples","samples","sampleHeight","pixels","configureFont","appleCrayonRGB","yOffset","yFont","getYFont","yScrollDelta","removeViewportContextMenuHandler","boundContextMenuHandler","newWidth","sampleNameViewport","layoutChange","actualBoundingBoxAscent","actualBoundingBoxDescent","getSampleNameYShim","MenuPopup","presentMenuList","menuList","hideAllMenuPopups","parentWidth","menus","scrollbarExclusionTypes","colorPickerExclusionTypes","TrackView","addDOMToColumnContainer","createAxis","calculateViewportWidth","viewportColumns","createTrackScrollbar","createTrackDragHandle","createTrackGearPopup","resizeAxisCanvas","removeDOMFromColumnContainer","boundAxisClickHander","removeAxisEventListener","removeTrackScrollMouseHandlers","outerScroll","removeTrackDragMouseHandlers","dragHandle","removeTrackGearMouseHandlers","gearContainer","renderSVGAxis","axisWidth","trackColors","genericColorPicker","newHeight","force","updateScrollbar","viewportContentHeight","maxViewportContentHeight","innerScrollHeight","innerScroll","moveScroller","repaintSamples","resize","visibleViewports","viewportsToRepaint","viewportsToReload","variantRowCount","nVariantRows","visibleViewport","viewFeatures","refreshView","updateRulerViewportLabels","getInViewFeatures","vpFeatures","currentTop","minTop","addTrackScrollMouseHandlers","addTrackDragMouseHandlers","gear","trackGearPopup","addTrackGearMouseHandlers","addAxisEventListener","boundTrackScrollMouseDownHandler","boundColumnContainerMouseMoveHandler","boundColumnContainerMouseUpHandler","currentDragHandle","trackDragMouseDownHandler","startTrackDrag","documentTrackDragMouseUpHandler","trackDragMouseEnterHandler","updateTrackDrag","trackDragMouseOutHandler","boundTrackDragMouseDownHandler","boundDocumentTrackDragMouseUpHandler","boundTrackDragMouseEnterHandler","boundTrackDragMouseOutHandler","trackGearClickHandler","boundTrackGearClickHandler","axisCanvasContext","DEFAULT_COLOR$1","WigTrack","graphType","getScaleFactor","computeYPixelValue","yValue","yScaleFactor","computeYPixelValueInLogScale","maxValue","minValue","posColor","baselineColor","yScale","lastY","lastPixelEnd","rectEnd","pointSize","basepx","guideLines","strokeWidth","displayFeatures","selectedFeature","BinnedColorScale","thresholds","GradientColorScale","lowColor","lowR","lowG","lowB","highColor","highR","highG","highB","frac","ConstantColorScale","SegTrack","isLog","sampleSquishHeight","sampleExpandHeight","posColorScale","negColorScale","MUT_COLORS","sampleKeys","sampleNames","explicitSamples","configCopy","initialSort","FILL","displayOptions","checkBox","sortSamples","renderSVG","checkForLog","updateSampleKeys","segment","pixelRect","sampleYStart","sampleKey","segmentStart","segmentEnd","scores","d2","sortSeg","sortMut","sortDirection","sortHandler","indel","truncating","synonymous","missense_mutation","missense","splice_region","nonsense","nonsense_mutation","frame_shift_del","frame_shift_ins","in_frame_del","in_frame_ins","MergedTrack","tconf","createTrack","featureArrays","MergedFeatureCollection","mergedFeatures","trackOptions","featuresArray","trackPopupData","mergedFeaturesCollection","every","InteractionTrack","arcOrientation","showBlocks","blockHeight","sinTheta","cosTheta","arcType","getArcType","painter","valueColumn","hasValue","getWGFeatures","drawProportional","drawNested","pixelStart","pixelEnd","coa","thetaLeft","thetaRight","estimateTheta","drawState","getAlphaColor","m1","m2","getMidpoints","xc","yc","hb","otherChr","refStart","refEnd","effectiveMin","radiusY","showOutbound","within","outBound","inBound","radiusX","ellipse","clearAxis","axisRange","nested","proportional","partialInView","addChordsForViewport","positionString","extractInfoColumn","candidates","colorAlphaCache","maxScoreFeature","totalFeatureCount","maxCount","featuresPerBin","binSize","binnedFeatures","bf","kvs","STANDARD_FIELDS","VariantTrack","showGenotypes","squishedVariantHeight","squishedCallHeight","expandedCallHeight","expandedVGap","squishedVGap","expandedGroupGap","squishedGroupGap","noGenotypeColor","noCallColor","nonRefColor","mixedColor","homrefColor","homvarColor","hetvarColor","expandedVariantHeight","variantHeight","_initColorBy","colorTables","_color","_strokecolor","strokecolor","_context_hook","context_hook","getCallsetsLength","sampleYOffset","vGap","callHeight","rowCount","variantBandHeight","nCalls","getVariantStrokecolor","callContextHook","sampleNumber","allVar","allRef","noCall","variantColor","getVariantColorTable","variantStrokeColor","variantRow","sampleY","sampleRow","allele","genotypeName","expandGenotype","sampleInformation","phaseset","genotypeLikelihood","getAttributes","displayText","infoKeys","INFO","stringInfoKeys","SVTYPE","sendChordsForViewport","arrays","isLargeEnough","tbl","SV_COLOR_TABLE","DEL","INS","DUP","INV","CNV","BND","EqtlTrack","pValueField","geneField","snpField","minLogP","maxLogP","autoscalePercentile","divider","dotSize","drawEqtls","drawSelected","isSelected","addGene","mLogP","LN10","capped","tissue","GWASColors","Un","roman","romanize","digits","GWASTrack","useChrColors","trait","posteriorProbability","valueProperty","popoverWindow","colorScale","pvalue","colorKey","yp","xDelta","yDelta","realChr","realStart","posterior","GCNVTrack","clickToHighlight","samplesClickedToHighlight","highlightSamples","prevIndex","nextIndex","getX","bpPosition","onlyHandleClicksForHighlightedSamples","previousEnd","previousValues","highlightConnectorLines","highlightFeatureLines","clickDetectorCache","previousX","sampleName","previousValue","previousY","highlightColor","drawGuideLines","clickX","clickY","closestDistanceSoFar","closestResult","segments","distance","distanceToLine","colourList","ax","ay","bx","by","bx_minus_ax","by_minus_ay","RnaStructTrack","RNAFeatureSource","sortByScore","startLeft","sl","sr","startRight","endLeft","er","endRight","ea","ds","dx1","dy1","d1","outerLim","innerLim","dx2","dy2","descriptors","startLeftNuc","startRightNuc","endLeftNuc","endRightNuc","colorIdx","parseBP","IdeogramTrack","stainColors","shim","shim2","ideogramTop","xC","yC","cytoband","getCytobandColor","drawIdeogram","widthBP","percentWidth","percentX","xx","yy","shade","JUNCTION_MOTIF_PALETTE","motif","junctionRenderingContext","SpliceJunctionTrack","colorByNumReadsThreshold","referenceFrameStart","referenceFrameEnd","featureZoomOutTracker","renderJunction","junctionMiddlePx","hideAnnotatedJunctions","annotated_junction","hideUnannotatedJunctions","hideMotifs","hideStrand","minJunctionEndsVisible","numJunctionEndsVisible","uniquelyMappedReadCount","multiMappedReadCount","totalReadCount","numSamplesWithThisJunction","uniquely_mapped","minUniquelyMappedReads","multi_mapped","minTotalReads","maxFractionMultiMappedReads","maximum_spliced_alignment_overhang","minSplicedAlignmentOverhang","num_samples_with_this_junction","minSamplesWithThisJunction","maxSamplesWithThisJunction","num_samples_total","percent_samples_with_this_junction","minPercentSamplesWithThisJunction","maxPercentSamplesWithThisJunction","bezierBottomY","bezierControlLeftPx","bezierControlRightPx","bounceHeight","line_width","thicknessBasedOn","bounceHeightBasedOn","labelWith","labelWithInParen","left_shape","right_shape","arrowSize","rangeString","resolveToken","addParameter","BufferedFile","fetchSize","buffers","overlappingBuffers","binarySearch","bufferData","Buffer$1","addBuffer","allBuffers","currentEnd","ob","requestedEnd","newStart","newArrayBuffer","concatArrayBuffers","newBuffer","overage","creationTime","sum","__defProp","__publicField","__defNormalProp","_unpack_struct_from_async","structure","async_buf","fmt","struct","unpack_from_async","calcsize","_unpack_struct_from","unpack_from","thing","_structure_size","_padded_size","padding_multiple","dtype_to_format","dtype_getter","dtype_str","nbytes","big_endian","_is_big_endian","fstr","bytestr","isBigEndian","getters","byte_lengths","all_formats","fmt_size_regex","regex","total_size","local_buffer","local_offset","DataView64","getUint64","combined","getInt64","str_buffer","getVLENStruct","bitSize","integer","_unpack_integer","DatatypeMessage","dtype","determine_dtype","datatype_msg","DATATYPE_MSG","DATATYPE_MSG_SIZE","datatype_class","DATATYPE_FIXED_POINT","_determine_dtype_fixed_point","DATATYPE_FLOATING_POINT","_determine_dtype_floating_point","DATATYPE_TIME","DATATYPE_STRING","_determine_dtype_string","DATATYPE_BITFIELD","DATATYPE_OPAQUE","DATATYPE_COMPOUND","_determine_dtype_compound","DATATYPE_REFERENCE","DATATYPE_ENUMERATED","DATATYPE_ARRAY","DATATYPE_VARIABLE_LENGTH","vlen_type","_determine_dtype_vlen","length_in_bytes","dtype_char","byte_order_char","base_index","extra_index","inflate_1","Filters","itemsize","input_array","buffer_size","unshuffled_view","shuffled_view","chunk_buffer","odd_chunk_buffer","data_length","sum1","sum2","ref_sum1","ref_sum2","_verify_fletcher32","AbstractBTree","fh","all_nodes","_read_root_node","_read_children","node_level","parent_node","child_addr","_add_node","_read_node","root_node","_read_node_header","BTreeV1","B_LINK_NODE","BTreeV1Groups","addresses","entries_used","address","symbol_table_addresses","all_address","root_nodes","BTreeV1RawDataChunks","dims","chunk_size","filter_mask","fmt_size","chunk_offset","chunk_address","construct_data_from_chunks","chunk_shape","data_shape","filter_pipeline","item_getter","item_big_endian","item_size","dtype_class","data_size","current_stride","data_strides","chunk_buffer_size","node_keys","node_addresses","nkeys","ik","node_key","addr","_filter_chunk","apos","cpos","cview","ci","cb_offset","datum","ai","num_filters","filter_index","pipeline_entry","filter_id","client_data","BTreeV2","_read_tree_header","address_formats","_calculate_address_formats","B_TREE_HEADER","node_size","record_size","nrecords_max","ntotalrecords_max","max_depth","offset_size","num1_size","num2_size","offset_fmt","num1_fmt","num2_fmt","_required_bytes","_int_format","addr_size","_nrecords_max","bytelength","nrecords","ntotalrecords","_parse_record","fmts","address_offset","num1","num2","iter_records","nodelist","BTreeV2GroupNames","namehash","heapid","BTreeV2GroupOrders","creationorder","SuperBlock","version_hint","SUPERBLOCK_V0","_end_of_sblock","SUPERBLOCK_V0_SIZE","SUPERBLOCK_V2_V3","SUPERBLOCK_V2_V3_SIZE","FORMAT_SIGNATURE","_contents","_root_symbol_table","_fh","get_offset_to_dataobjects","sym_table","SymbolTable","group_offset","Heap","local_heap","LOCAL_HEAP","data_offset","heap_data","get_object_name","name_size","SYMBOL_TABLE_NODE","SYMBOL_TABLE_NODE_SIZE","n_symbols","SYMBOL_TABLE_ENTRY","SYMBOL_TABLE_ENTRY_SIZE","assign_name","entry","link_name","get_links","links","cache_type","scratch","bufView","GlobalHeap","GLOBAL_HEAP_HEADER","GLOBAL_HEAP_HEADER_SIZE","heap_data_size","_header","_objects","objects","GLOBAL_HEAP_OBJECT_SIZE","GLOBAL_HEAP_OBJECT","obj_data","FractalHeap","FRACTAL_HEAP_HEADER","UNDEFINED_ADDRESS","nbits","block_offset_size","_min_size_nbits","indirect_block_header","indirect_block_header_size","direct_block_header","direct_block_header_size","maximum_dblock_size","_managed_object_offset_size","_managed_object_length_size","_min_size_integer","start_block_size","table_width","log2_maximum_dblock_size","log2_start_block_size","_max_direct_nrows","log2_table_width","_indirect_nrows_sub","nobjects","managed","root_address","nrows","_iter_indirect_block","_read_direct_block","moffset","block_size","get_data","firstbyte","idtype","block_offset","ndirect","nindirect","_indirect_info","direct_blocks","_calc_block_size","indirect_blocks","nrows2","_iblock_nrows_from_block_size","iblock","log2_block_size","ndirect_max","DataObjects","msgs","msg_data","_parse_v1_objects","_parse_v2_objects","_global_heaps","_filter_pipeline","_chunk_params_set","_chunks","_chunk_dims","_chunk_address","msg_offset","find_msg_type","DATATYPE_MSG_TYPE","_get_chunk_params","shape","DATASPACE_MSG_TYPE","DATASPACE_MSG_HEADER_V1","DATASPACE_MSG_HEADER_V1_SIZE","DATASPACE_MSG_HEADER_V2","DATASPACE_MSG_HEADER_V2_SIZE","ndims","dim_sizes","determine_data_shape","get_filter_pipeline","filter_msgs","DATA_STORAGE_FILTER_PIPELINE_MSG_TYPE","nfilters","filter_info","FILTER_PIPELINE_DESCR_V1","FILTER_PIPELINE_DESCR_V1_SIZE","padded_name_length","filter_name","nf","name_length","optional","num_client_values","client_values","msg_type","get_attributes","attr_msgs","ATTRIBUTE_MSG_TYPE","unpack_attribute","get_fillvalue","is_defined","FILLVALUE_MSG_TYPE","fillvalue","FILLVAL_MSG_V1V2","FILLVAL_MSG_V1V2_SIZE","FILLVAL_MSG_V3","FILLVAL_MSG_V3_SIZE","size2","attr_map","ATTR_MSG_HEADER_V1","ATTR_MSG_HEADER_V1_SIZE","ATTR_MSG_HEADER_V3","ATTR_MSG_HEADER_V3_SIZE","_attr_value","character_set","vlen","vlen_data","_vlen_size_and_data","base_dtype","vlen_size","gheap_id","GLOBAL_HEAP_ID","gheap_address","gheap","OBJECT_HEADER_V1","total_header_messages","object_header_blocks","current_block","HEADER_MSG_INFO_V1","offset_to_message","HEADER_MSG_INFO_V1_SIZE","OBJECT_CONTINUATION_MSG_TYPE","fh_off","creation_order_size","_parse_v2_header","HEADER_MSG_INFO_V2_SIZE","next_block","HEADER_MSG_INFO_V2","OBJECT_HEADER_V2","chunk_fmt","find_link","_links","link2","iter_links","fromEntries","SYMBOL_TABLE_MSG_TYPE","_iter_links_from_symbol_tables","LINK_MSG_TYPE","_get_link_from_link_msg","LINK_INFO_MSG_TYPE","_iter_link_from_link_info_msg","sym_tbl_msg","SYMBOL_TABLE_MSG","_iter_links_btree_v1","btree_address","heap_address","btree","symbol_table_address","link_msg","_decode_link_msg","link_type","size_of_length_of_link_name","link_name_character_set_field_present","ordered","link_name_character_set","name_size_fmt","length_of_soft_link_value","info_msg","_decode_link_info_msg","name_btree_address","order_btree_address","_iter_links_btree_v2","sorted_keys","LINK_INFO_MSG2","LINK_INFO_MSG1","link_info","UNDEFINED_ADDRESS2","is_dataset","DATA_STORAGE_MSG_TYPE","layout_class","property_offset","_get_data_message_properties","_get_contiguous_data","_get_chunked_data","arg1","arg2","fullsize","item_is_big_endian","chunk_btree","object_index","Group","dataobjects","_dataobjects","_attrs","_keys","_dereference","_get_object_by_address","normpath","sep","all_sep","end_sep","posix_dirname","next_obj","additional_obj","obj_name","link_target","dataobjs","Dataset","new_group","visit","visititems","root_name_length","File$1","superblock","userblock_size","index_offset","indexName","index_link","dataobject","comp_index_data","obj_addr","_astype","getValue","astype","to_array","total_length","dims_product","subdims","dim","new_output","create_nested_array","openH5File","isRemote","fileReader","NodeLocalFile","getReaderFor","asyncBuffer","AsyncBuffer","indexReader","indexPath","indexFileContents","indexFileJson","readExternalIndex","getFilenameFor","hdfFile","pathOrURL","HDF5Reader","h5_file","bin_size","h5_obj","get_keys","get_rd_signal","h5_obj_keys","signal_bin","ParseSignals","rd_bins","get_rd_bins","snp_bins","get_snp_bins","available_bins","at","chr_ds","rd_chromosomes","rd_stat","wigFeatures","wigFeatures_gc","wigFeatures_rd_call_meanshift","wigFeatures_rd_call_combined","wigFeatures_baf1","wigFeatures_baf2","signal_rd","chr_wig","get_chr_signal","signal_rd_gc","chr_wig_gc","signal_rd_call","chr_wig_rd_call_meanshift","chr_wig_rd_call","rd_call_combined","signal_baf_1","chr_wig_bafs","get_baf_signals","callers","signal_obj","RD_Raw","RD_Raw_gc_coor","ReadDepth","BAF1","BAF2","decode_segments","segments_arr","mosaic_call_segments","chrom_dataset","chrom_data","mosaic_calls","segments_call_dataset","segments_call","ind_segment","segment_idx","bin_value","bin_idx","rd_stat_signal","rd_stat_dataset","signal_name","chr_wig_1","chr_wig_2","max_value","lh","get_baf_signals_v2","rd_keys","slected_signals","getDistParams","filteredBins","someArray","q1","q3","iqr","filterOutliers","std","g_utils","range_function","linspace","GetFit","allBins","getValues","binResult","binScore","getMean","fit_data","histogram","hist_bins","bin_index","dist_p","TdistributionCDF","incompbeta","sign","lbeta","lgamma","contfractbeta","ITMAX","az","am","bm","qab","qap","qam","bz","em","tem","aold","factorial","xf","gamma","qc","prod1","xg","t_dist","t_test_1_sample","t_test_2_samples","n1","n2","df","arrayMax","normal","sigma","normal_overlap_approx","likelihood_overlap","likelihood_1","likelihood_2","currentIndex","normal_merge","likelihood_of_baf","likelihood","baf","likelihood_baf_pval","max_lh","ix","ix1","ix2","combined_caller","get_fit","fit_info","globalMean","globalStd","call_2d","omin","mcount","event_type","max_distance","baf_threshold","max_copy_number","min_cell_fraction","fit_obj","overlap_min","gstat_rd0","gstat_rd_all","gstat_rd","gstat_error","gstat_lh","gstat_n","levels","likelihoods","hets_count","dp_count","likelihood_score","diff_level","min_flank","x_idx","lh_overlap","rd_overlap","max_overlap","nlh","nlh_sum","merge_level","l_value","l_idx","c_value","new_overlap","ons","overlap_value","seg_value","seg_idx","baf_info","segment_score","points","master_lh","germline_lh","h1","g_mbaf","mbaf","mrd","g_mrd","ei","g_lh","slh","max_x","tmpl","tmp_list","formatDataStructure","feature_column","scaling_factor","new_sample","formatDataStructure_BAF","baf1","baf2","baf1_value","baf2_value","erf","getEValue","rd","DataStat","gaussianEValue","adjustToEvalue","pval","max_steps","v1","v2","v3","v4","elif","data_array","read_depth_caller","bin_bands","get_rd_signal_bandwidth","new_array","tmp_value","meanShiftCaller","repeats","ChrLevels","chr_rd","masked","bin_band","bin_band_index","not_masked","nm_levels","mask_borders","isig","g_value","pb","range_array","range_mean","seg","seg_left","seg_right","n_left","n_right","seg_array","ns","seg_left_array","seg_left_1","seg_right_array","seg_right_1","genome_size","segments_rd","raw_seg_data","call_mean_shift","cnv_calling","normal_genome_size","merged_level","cnv_levels","chr_levels","borders","tmp_array","binDict","b0","border_start","border_end","adj","merge_arr","cnv","cnv_dict","CNVpytorVCF","allVariants","rowBinSize","binFactor","computeDepthFeatures","firstSnp","binStart","binEnd","featureBin","dpValue","computeReadDepth","sum_score","avgbin","tmp_score","readDepthMeanshift","globamMean","partition","partition_array","caller_array","partition_level","partition_call","computeBAF_v2","previous_featureBin","updated_bin","get_max_min_score","baf_wig","min_score","ad_score","ad_a","ad_b","beta","likelihood_value","format_BAF_likelihood","getAllbins","read_rd_baf","caller","dp_sum_score","hets","finalFeatureSet","adjust_bin_size","caller_obj","processed_bins","hets_idx","likelihood_sum","max_likelihood","phased","CNVPytorTrack","defaultScale","cnv_caller","get_signals","get_signal_colors","singal_name","cnvpytor_obj","bafFeatures","dataWigs","wigFeatures_obj","available_callers","set_available_callers","signal_colors","rd_bin","recreate_tracks","signal_dct","rd_snp","trackFunctions","addTrackCreatorFunction","TrackFactory","trackKey","XMLSession","xmlString","knownGenomes","xmlDoc","processRootNode","resourceElements","trackElements","hasTrackElements","resourceMap","subtracks","mergedTrack","extractTrackAttributes","processed","ucscID","autoScale","visWindow","dataRangeCltn","SampleInformation","plinkLoaded","loadPlinkFile","line_arr","familyId","fatherId","motherId","sex","phenotype","getAttributeNames","hasAttributes","GtexSelection","geneColors","genesCount","brewer","ReferenceFrame","newEnd","ratio","calculateBPP","toPixels","shiftPixels","currentStart","deltaBP","clampStart","maxStart","centerBPOrUndefined","bppThreshold","getMultiLocusLabelLocusOnly","getPresentationLocusComponents","blurb","DEFAULT_SEARCH_CONFIG","chromosomeField","startField","endField","searchConfig","searchLocus","locusObject","tabTokens","extent","numeric","isSoftclipped","parseLocusString","linesTrimmed","locusTokens","rangeTokens","parseSearchResults","resultsField","chrResult","processSearchResult","searchWebService","NavbarManager","navbarDidResize","updateNavbar","createResponsiveClassSchedule","responsiveClassSchedule","$toggle_button_container","zoomWidget","zoomContainer","navbarWidth","windowSizePanel","ChromosomeSelectWidget","showAllChromosomes","update","WindowSizePanel","updatePanel","CursorGuide","horizontalGuide","verticalGuide","addMouseHandler","setVisibility","showCursorGuide","boundMouseMoveHandler","classname","findAncestorOfClass","elementFromPoint","getRulerTrackView","viewportParent","interpolant","customMouseHandler","removeMouseHandler","CursorGuideButton","setCursorGuideVisibility","setButtonState","showCursorTrackingGuideButton","CenterLineButton","isCenterLineVisible","setCenterLineVisibility","showCenterGuideButton","TrackLabelControl","setState","setTrackLabelVisibility","showTrackLabelButton","SampleNameControl","showSampleNameButton","sliderMax","sliderValueRaw","ZoomWidget","zoomOutButton","zoomOut","slider","zoomedExtent","valueAsNumber","zoomInButton","zoomIn","isMultiLocusMode","enable","hideSlider","showSlider","SVGSaveControl","saveSVGtoFile","viewportColumnManager","nextElementSibling","previousElementSibling","referenceElement","ViewportCenterLine","RulerTrack","drawWholeGenome","doDraw","wBP","renderChromosomeRect","tick","Tick","nZeroes","majorUnit","unitMultiplier","denom","nMajorTicks","belowThresholdTick","aboveThresholdTick","findSpacing","nTick","majorTick","tickDelta","labelLength","getBP","calculateDeltas","xTick","accumulatedTickDelta","labelLengthShim","rulerLabel","xLabel","minorTick","labelWidthBP","CircularViewControl","showCircularViewButton","CustomButton","ROIManager","roiMenu","roiTable","boundLocusChangeHandler","locusChangeHandler","initialize","showROITableButton","roiTableControl","renderROISet","getTableRecords","loadROI","configs","clearROIs","setName","presentTable","repaintTable","dismissTable","userDefinedROISet","getUserDefinedROISet","initializeUserDefinedROISet","setROITableButtonVisibility","renderAllROISets","viewStart","viewEnd","regionKey","region","regionChr","regionStart","regionEnd","parseRegionKey","createRegionKey","pixelX","createSelector","createRegionElement","regionElement","deleteUserDefinedRegionWithKey","findUserDefinedRegionWithKey","buttonHandler","bedRecord","ROITable","sortedRecords","doIncludeROISetNames","ROIMenu","removeAllChildNodes","_description_copy_","placeholder","_delete_","__present","TrackROISet","ROITableControl","roiTableVisible","setROITableVisibility","doShowROITablelButton","Browser","parentDiv","dragThreshold","scrollThreshold","eventHandlers","setControls","gtex","flanking","crossDomainProxy","formats","trackDefaults","showTrackLabels","showROITable","showCenterGuide","$navBar","createStandardControls","$navigation","showControls","navbarManager","$navbarLeftContainer","$logo","logoSvg","$current_genome","$genomicLocation","chromosomeSelectWidget","showChromosomeWidget","$locusSizeGroup","$searchContainer","$searchInput","change","doSearch","searchIconContainer","$navbarRightContainer","cursorGuide","cursorGuideButton","centerLineButton","trackLabelControl","sampleNameControl","showSVGButton","svgSaveControl","customButtons","showNavigation","getSampleNameViewportWidth","addTrackToFactory","currentLoci","noCommaLocusString","toSVG","loadSession","uncompressSession","loadSessionFile","loadSessionObject","cleanHouseForSession","genomeOrReference","genomeConfig","loadReference","centerLineList","createCenterLineList","ideogramHeight","showIdeogram","getElementAbsoluteHeight","showRuler","gtexSelections","roiTableConfig","roi","roiSetList","named","genomeTracks","trackConfigurations","trackOrder","loadTrackList","rtv","tv","updateUIWithReferenceFrameList","centerLines","initialLocus","genomeChange","updateNavbarDOMWithGenome","removeAllTracks","genomeLabel","updateLocusSearchWidget","toggleTrackLabels","setCenterLineAndCenterLineButtonVisibility","setCustomCursorGuideMouseHandler","mouseHandler","centerLine","configList","_loadTrack","loadedTracks","newTrack","reorderTracks","getTrackOrder","sync","getUserDefinedROIs","featureHash","resolveURL","firstSortOrder","aOrder1","bOrder1","removeTrackByName","_removeTrack","remainingTrackViews","findTracks","trackHeight","visibilityChange","centerGuide","groupAutoscaleTracks","otherTracks","groupTrackViews","loc","getCenterLineXOffset","columnContainerWidth","referenceFrameOrUndefined","referenceFrames","referenceFrameLeft","newReferenceFrame","indexLeft","indexRight","rescaleForMultiLocus","referenceFrameIndex","retain","goto","success","browserFlanking","createReferenceFrameList","loadSampleInformation","eventName","callbackIndex","thisObj","hasGtexSelections","anyTrackView","locusString","trackJson","errors","compressedSession","btoa","compressString","sessionURL","vpMouseDown","lastMouseX","lastMouseY","mouseDownY","isTrackPanning","dragDestination","dragged","indexDestination","indexDragged","newOrder","lastOrder","addWindowResizeHandler","addRootMouseUpHandler","addRootMouseLeaveHandler","addColumnContainerEventHandlers","removeWindowResizeHandler","removeRootMouseUpHandler","removeRootMouseLeaveHandler","removeColumnContainerEventHandlers","boundWindowResizeHandler","boundRootMouseUpHandler","mouseUpOrLeave","boundRootMouseLeaveHandler","handleMouseMove","boundColumnContainerTouchMoveHandler","boundColumnContainerMouseLeaveHandler","boundColumnContainerTouchEndHandler","createCircularView","addFrameForFeature","frameFound","circularViewControl","viewportWidthBP","horizontal","clampDrag","allBrowsers","embedCSS","createBrowser","showCircularView","showCursorTrackingGuide","setDefaults","queryParametersSupported","files","indexURLs","extractQuery","clientId","codeClientConfig","client_id","hint","hosted_domain","initTokenClient","init$1","removeBrowser","removeAllBrowsers","setGoogleOauthToken","Textbox","onchange","div$1","Panel","component","Dialog","cancelHandler","labelDiv","page","popoverRect","parentRect","panel","minbox","maxbox","alertDialog","presentAlert","getExtension","FileUtils.isFile","google_url","Globals","EventBus","subscribers","subscribe","eventType","subscriberList","post","_hold","subscriber","receiveEvent","release","globalBus","Track2D","lower","upper","both","validateColor","repColor","featureCount","getKey","loadTrack2D","isBedPE","StringUtils.splitLines","parseData","Ruler","axisElement","canvasElement","wholeGenomeContainerElement","setAxisTransform","eventBus","wholeGenomeLayout","axisName","decorate","parseGotoInput","unhighlightWholeChromosome","otherRuler","hoverHandler","doHover","targetLabel","dimen","scraps","firstDivElement","bboxes","percentage","divElement","borderElement","labelElement","hideWholeGenome","showWholeGenome","canvasTransform","canvasTransformWithContext","identityTransformWithContext","labelTransform","noopTransformWithContext","hitElement","hitTest","locusChange","updateWidthWithCalculation","calc","updateHeight","bpResolutions","pixelSize","rulerTickMarkReferencePixels","otherRulerCanvas","rulerLengthPixels","rulerHeightPixels","chrNameSelected","fontStyle","tickSpec","rulerLengthBP","TickSpacing","dn","majorTickSpacing","pixelLast","yShim","tickHeight","formatNumber","tickSpacingPixels","decimal","precision","roundedNum","integerPart","decimalPart","padEnd","formattedNum","firstChildElement","pathData","svgNS","trackPair","layoutController","removeTrackXYPair","nucleotideColorChartMenuItems","TrackGearPopup","popoverElement","popoverHeaderElement","UIUtils","popoverContentElement","updatedList","tempDiv","eventHandler","popups","Tile","startBP","endBP","TrackPair","viewportElement","appendRightHandGutter","trackReorderHandleElement","trackPairs","targetTrackPair","setTrackReorderArrowColors","trackDiv","origin","containerElement","updating","genomicStateX","genomicState","imageTileX","getTileX","drawTile","genomicStateY","imageTileY","getTileY","tileX","createImageTile","tileY","tileFeatures","lengthBP","viewportContainerX","viewportContainerWidth","wye","arrowUp","arrowDown","TrackRenderer","DOMUtils","labelText","showTrackLabelAndGutter","toggleTrackLabelAndGutterState","displayState","spinnerElement","syncCanvas","offsetPixel","HICEvent","propogate","createDOMFromHTMLString","parseRgbString","rgbString","trunc","extractName","LayoutController","rootElement","hicNavbarContainer","setCurrentBrowser","htmlContactMapHicNavBarMapContainer","contactMapLabel","menuPresentDismiss","toggleMenu","browserPanelDeleteButton","unsyncSelf","deleteBrowser","htmlControlMapHicNavBarMapContainer","controlMapLabel","htmlUpperHicNavBarWidgetContainer","htmlLowerHicNavBarWidgetContainer","createNavBar","createAllContainers","htmlXTrackContainer","xTrackContainer","trackShim","xTracks","yTrackGuideElement","contentContainer","htmlXAxisContainer","xAxisContainer","xAxisRuler","htmlYTracksYAxisViewportYScrollbar","yTracksYAxisViewportYScrollbar","yTracks","xTrackGuideElement","yAxisRuler","htmlViewport","htmlYAxisScrollbarContainer","htmlXAxisScrollbarContainer","getContactMatrixViewport","getYAxisScrollbarContainer","getXAxisScrollbarContainer","updateLayoutWithTracks","getLayoutDimensions","resizeLayoutWithTrackXYPairCount","removeAllTrackXYPairs","updateLayout","trackXYPair","trackXYPairCount","trackMargin","axisHeight","scrollbarHeight","trackAggregateHeight","getNavbarHeight","heightCalc","widthCalc","contactMatrixView","scrollbarWidget","xAxisScrollbarContainerElement","navBarLabelHeight","navBarWidgetContainerHeight","navBarWidgetContainerMargin","getCSSVariable","setCSSVariable","Zlib","Huffman","Util","CRC32","DEFLATE","RESERVED","opt_params","Zip","CompressionMethod","STORE","OperatingSystem","MSDOS","UNIX","MACINTOSH","Flags","ENCRYPT","DESCRIPTOR","UTF8","FileHeaderSignature","LocalFileHeaderSignature","CentralDirectorySignature","addFile","deflateWithOption","encrypted","setPassword","compress","op1","op2","op3","endOfCentralDirectorySize","date","plainSize","filenameLength","extraFieldLength","commentLength","extraField","il","jl","localFileSize","centralDirectorySize","createEncryptionKey","needVersion","getMinutes","getSeconds","getHours","getMonth","getDate","getFullYear","RawDeflate","updateKeys","single","buildHuffmanTable","lengths","rtemp","listSize","maxCodeLength","minCodeLength","POSITIVE_INFINITY","RawInflate","totalpos","ip","bitsbuf","bitsbuflen","bfinal","bufferType","BufferType","ADAPTIVE","BLOCK","MaxBackwardLength","MaxCopyLength","parseBlock","concatBufferBlock","concatBufferDynamic","Order","LengthCodeTable","LengthExtraTable","DistCodeTable","DistExtraTable","FixedLiteralLengthTable","FixedDistanceTable","hdr","readBits","parseUncompressedBlock","parseFixedHuffmanBlock","parseDynamicHuffmanBlock","readCodeByTable","codeWithLength","codeLength","inputLength","codeTable","preCopy","olength","expandBufferBlock","expandBufferAdaptive","fixRatio","decodeHuffmanAdaptive","decodeHuffmanBlock","codeLengthsTable","litlenTable","distTable","lengthTable","repeat","hlit","hdist","hclen","codeLengths","litlen","currentLitlenTable","ti","codeDist","lengthCodeTable","lengthExtraTable","distCodeTable","distExtraTable","opt_param","backward","newSize","maxInflateSize","addRatio","RawInflateStream","opt_buffersize","ZLIB_STREAM_RAW_INFLATE_BUFFER_SIZE","blockLength","sp","Status","INITIALIZED","ip_","bitsbuflen_","bitsbuf_","BlockType","UNCOMPRESSED","FIXED","DYNAMIC","BLOCK_HEADER_START","BLOCK_HEADER_END","BLOCK_BODY_START","BLOCK_BODY_END","DECODE_BLOCK_START","DECODE_BLOCK_END","newInput","currentBlockType","readUncompressedBlockHeader","decodeHuffman","concatBuffer","save_","restore_","expandBuffer","cmf","flg","rawinflate","verify","Adler32","InflateStream","Gunzip","member","decompressed","getMembers","decodeMember","concatMember","inflen","mtime","GunzipMember","id1","id2","cm","xfl","Gzip","FlagsMask","FEXTRA","decodeSubField","FNAME","FCOMMENT","FHCRC","crc16","getName","getMtime","deflateOptions","DefaultBufferSize","rawdeflate","UNKNOWN","FAT","AMIGA","VMS","VM_CMS","ATARI_TOS","HPFS","Z_SYSTEM","CP_M","TOPS_20","NTFS","QDOS","ACORN_RISCOS","FTEXT","getParent","getChild","compressionType","CompressionType","lazy","freqsLitLen","freqsDist","NONE","Lz77MinLength","Lz77MaxLength","WindowSize","MaxCodeLength","HUFMAX","FixedHuffmanTable","blockArray","makeNocompressBlock","makeFixedHuffmanBlock","makeDynamicHuffmanBlock","isFinalBlock","btype","BitStream","writeBits","lz77","fixedHuffman","litLenLengths","litLenCodes","distLengths","distCodes","treeSymbols","treeLengths","treeCodes","bitlen","hclenOrder","transLengths","getLengths_","getCodesFromLengths_","getTreeSymbols_","freqs","dynamicHuffman","dataArray","litLen","literal","Lz77Match","backwardDistance","getDistanceCode_","toLz77Array","codeArray","matchKey","matchList","longestMatch","prevMatch","windowSize","lz77buf","skipLength","writeMatch","lz77Array","searchLongestMatch_","currentMatch","matchLength","matchMax","dl","permatch","litlenLengths","runLength","nResult","rpt","nSymbols","reversePackageMerge_","minimumCost","currentPosition","takePackage","startCode","Unzip","eocdrOffset","numberOfThisDisk","startDisk","totalEntriesThisDisk","totalEntries","centralDirectoryOffset","fileHeaderList","filenameToIndex","FileHeader","compression","fileNameLength","fileCommentLength","diskNumberStart","internalFileAttributes","externalFileAttributes","relativeOffset","LocalFileHeader","searchEndOfCentralDirectoryRecord","parseEndOfCentralDirectoryRecord","parseFileHeader","fileHeader","filelist","filetable","getFileData","localFileHeader","createDecryptionKey","getFilenames","filenameList","stringToByteArray","OptimizationParameter","bufferPosition","bitindex","DefaultBlockSize","oldbuf","ReverseTable","rev32_","Table","Table_","rawDeflate","rawDeflateOption","flevel","LOG2E","BrowserLocalFile","versions","ThrottledFile","rateLimiter","limiter","bufferLength","bufferEnd","sliceEnd","l1","a1","l2","a2","concatBuffers","buffer1","buffer2","MatrixZoomData","getBlockNumbers","region1","region2","sameChr","binsize","blockBinCount","blockColumnCount","col1","col2","row1","row2","blockNumbers","getBlockNumbersV8","binX1","binX2","binY1","binY2","translatedLowerPAD","translatedHigherPAD","translatedNearerDepth","translatedFurtherDepth","nearerDepth","furtherDepth","block_number","getBlockNumbersV9","parseMatrixZoomData","dis","zd","zoomIndex","sumCounts","occupiedCellCount","stdDev","percent95","nBlocks","StaticBlockIndex","avgCount","averageCount","getBlockIndexEntry","Matrix","zoomDataList","bpZoomData","fragZoomData","findZoomForResolution","zdArray","getZoomData","getZoomDataByIndex","parseMatrix","nResolutions","zdList","ContactRecord","bin1","bin2","LRU","NormalizationVector","nValues","adjustedStart","adjustedEnd","startPosition","sizeInBytes","resolution","getNormalizationVectorKey","nvi$1","isNode","GoogleRateLimiter","isCalled","HicFile","loadFragData","fragmentSitesCache","normVectorCache","normalizationTypes","matrixCache","blockCache","BlockCache","remote","remoteFile","initialized","readHeaderAndFooter","getVersion","getMetaData","meta","footerPosition","readFooter","remainingSize","masterIndex","normVectorIndexPosition","normVectorIndexSize","chromosomeIndexMap","wholeGenomeChromosome","wholeGenomeResolution","nBpResolutions","fragResolutions","nFragResolutions","resolutions","nBytes","miSize","expectedValueVectors","normExpectedValueVectorsPosition","printIndexStats","maxKey","getMatrix","matrix","readMatrix","getContactRecords","normalization","allRecords","getFileChrName","contactRecords","nvX1","nvX2","nvY1","nvY2","normVector1","normVector2","isNorm","nv1","getNormalizationVector","nv2","nvnv","blockKey","blockNumbersToQuery","newBlocks","nRecords","binX","binY","binXOffset","binYOffset","useFloatContact","useIntXPos","useIntYPos","colCount","nPts","Block","hasNormalizationVector","normVectorIndex","getNormVectorIndex","isNormalizationValueAvailableAtResolution","chromosomeIndex","nvi","nviArray","readNormVectorIndex","readNormExpectedValuesAndNormVectorIndex","getNormalizationOptions","normalizationVectorIndexRange","parseNormVectorEntry","nviStart","skipExpectedValues","normalizedExpectedValueVectors","processEntries","sizeEstimate","parseNext","nChrScaleFactors","getZoomIndexForBinSize","resolutionArray","chrAlias","zoomData","Straw","hicFile","getNVI","IGVRemoteFile","hg19","hg38","mm10","mm9","dm6","straw","chrSizes","sz","matchGenome","clearCaches","colorScaleCache","getBinSizeForZoomIndex","getChrIndexFromName","compareChromosomes","otherDataset","otherChrs","isCompatible","loadDataset","chromosomeLookupTable","genomeLength","officialName","chrname","getChromosomeForCoordinate","State","clampXY","viewDimensions","maxX","maxY","panWithZoom","anchorPx","anchorPy","minPixelSize","gx","gy","panShift","configureLocus","setWithZoom","xCenter","yCenter","xCenterNew","yCenterNew","DEFAULT_PIXEL_SIZE","resolutionChanged","bpPerBin","startBP1","startBP2","pixelsPerBin","endBP1","endBP2","updateWithLoci","chr1Name","bpX","bpXMax","chr2Name","bpY","bpYMax","getResolutions","zoomNew","bpPerPixelTarget","resolutionLocked","findMatchingZoomIndex","binSizeNew","MAX_PIXEL_SIZE","newXBin","newYBin","chr1Index","chr2Index","chrChanged","targetState","pixelSizeNew","xBinNew","yBinNew","zoomChanged","getViewDimensions","sizeBP","fromJSON","configOrUndefined","geneSearch","featureName","searchServiceURL","LocusGoto","resolutionSelectorElement","sX","eX","strX","sY","eY","ResolutionSelector","labelContainerElement","resolutionLockElement","setResolutionLock","setZoom","updateResolutions","divisor","StringUtils.numberFormatter","defaultColorScaleConfig","ColorScale","nbins","setThreshold","getThreshold","setColorComponents","getColorComponents","pnstr","ratioCS","RatioColorScale","positiveScale","negativeScale","defaultRatioColorScaleConfig","positive","negative","plusOrMinus","logScore","imageTileDimension","ContactMatrixView","sweepZoom","ratioColorScale","backgroundRGBString","faSpinnerElement","spinnerCount","xGuideElement","yGuideElement","imageTileCache","imageTileCacheKeys","imageTileCacheLimit","colorScaleThresholdCache","drawsInProgress","setBackgroundColor","stringifyBackgroundColor","parseBackgroundColor","setColorScale","diffColorScale","colorScaleKey","setColorScaleThreshold","getColorScale","setDisplayMode","clearImageCaches","mouseHandlersEnabled","addTouchHandlers","disableUpdates","render2DTracks","tracks2D","canvasWidth","canvasHeight","controlDataset","controlZoom","dsControl","zdControl","getBZoomIndex","pixelSizeInt","widthInBins","heightInBins","blockCol1","blockCol2","blockRow1","blockRow2","checkColorScale","getImageTile","paintTile","bZoom","imageSize","inProgressCache","inProgressTile","inProgress","transpose","ctrlAverageCount","averageAcrossMapAndControl","widthInBP","x0bp","y0bp","cRecords","controlRecords","controlRec","setPixel","imageTile","changed","xWidthInBP","yWidthInBp","computePercentile","computeColorScale","getMatrices","newGenomicExtent","sWidth","sHeight","backCanvas","scaledWidth","scaledHeight","isLoadingHICFile","userInteractionShield","mouseDown","mouseLast","mouseOver","currentX","currentY","isSweepZooming","panMouseUpOrMouseOut","isDragging","isMobile","menuElement","hideMenu","scrollY","scrollX","getOffset","xy","willShowCrosshairs","updateCrosshairs","showCrosshairs","mouseY","zoomAndCenter","hideCrosshairs","sweepRect","yPixel","commit","lastTouch","pinch","translateTouchCoordinates","ontouchstart","touchCoords","hypot","ontouchmove","threshhold","deferTimer","hicUtils.throttle","touchCoords1","touchCoords2","ontouchend","dxStart","dyStart","dxEnd","dyEnd","distStart","anchorX","anchorY","pinchZoom","track2DList","xStartBP","yStartBP","xEndBP","yEndBP","chromosome1","heightBP","getLocus","renderFeatures","xS","xE","yS","yE","renderLowerFeatures","track2D","renderUpperFeatures","defaultBackgroundColor","ColorScaleWidget","mapBackgroundColorpickerButton","colorSwatch","backgroundColorpicker","createColorPicker","nr","nb","minusButton","minusColorPicker","plusButton","plusColorPicker","highColorscaleInput","minusIcon","createIconButton","updateThreshold","plusIcon","paintSwatch","repaintMatrix","presentable","hideableA","hideableB","iconClass","onClick","ControlMapWidget","toggleContainer","cycleContainer","controlMapHash","ControlMapHash","toggleArrowsUp","toggleArrowsDown","updateOptions","getDisplayMode","toggleDisplayMode","toggleDisplayModeCycle","getDisplayModeCycle","cycleID","cycle","imgA","imgB","shown","AOB","BOA","disableDisplayModeCycle","cycleOutline","cycleSolid","doToggle","oldMode","newMode","NormalizationWidget","hicNavBarContainer","normalizationSelector","setNormalization","startNotReady","stopNotReady","labels","VC","VC_SQRT","KR","INTER_VC","INTER_VC_SQRT","INTER_KR","GW_VC","GW_VC_SQRT","GW_KR","norm","SweepZoom","targetElement","rulerSweeperElement","bpResolution","yBP","ScrollbarWidget","yAxisScrollbarContainerElement","xAxisScrollbarElement","xLabelElement","yAxisScrollbarElement","yLabelElement","chromosomeLengthsBin","chromosomeLengthsPixel","percentages","binPercentage","pixelPercentage","yPercentage","ChromosomeSelector","xAxisSelector","yAxisSelector","syncSelectors","nextDiv","xLocus","yLocus","setChromosomes","respondToDataLoadWithDataset","respondToLocusChangeWithState","sourceSelector","targetSelector","AnnotationWidget","alertMessage","trackListRetrievalCallback","annotationPresentationButton","annotationPanel","updateBody","annotationPanelElement","annotationPanelRow","trackRenderer","panelHeader","titleDiv","closeButtonDiv","closeIcon","isTrack2D","trackList","rowContainer","visibilityIcon","displayModeIcon","displayModeHandler","colorpickerContainer","closeButton","createAnnotationPanelColorpickerContainer","nextElement","colorpickerButton","annotationColorSwatch","upDownContainer","upTrack","downTrack","hiddenColor","moveUp","moveDown","deleteIcon","trackRenderPair","BrowserUIManager","initializeComponents","navContainer","getComponent","chromosomeSelectorContainer","annotationContainer","HICBrowser","appContainer","figureMode","miniMode","normVectorFiles","synchable","synchedBrowsers","userAgent","createMenu","ui","loadHicFile","controlUrl","loadHicControlFile","controlName","controlNvi","isControl","loadTracks","loadNormalizationFile","normalizations","validNormalizations","showMenu","baseOptions","controlOptions","baseResolutions","controlResolutions","xGuide","yGuide","customCrosshairsHandler","stateX","stateY","startXBP","endXBP","startYBP","endYBP","interpolantX","interpolantY","setCustomCrosshairsHandler","crosshairsHandler","gs","errorPrefix","promises2D","fileName","FileUtils.getFilename","hicUtils.getExtension","presentError","normVectors","readNormalizationVectorFile","renderTrackXY","clearSession","getAllBrowsers","unsync","noUpdates","hicFileAlert","previousGenomeId","synchState","canBeSynched","syncState","syncBrowsers","compatibleBrowsers","getSyncState","lookupFeatureOrGene","wholeChr","startStr","endStr","trimmedName","upperName","selectedGene","geneResult","targetResolution","currentResolution","newBinSize","newZoom","newPixelSize","targetBinSize","minZoom","centerPX","centerPY","genomeCoordX","genomeCoordY","directionPositive","directionNegative","minPS","shiftRatio","hicEvent","payload","locusChangeEvent","xyTrackRenderPair","syncState1","initialImage","jsonOBJ","nviString","chr1Length","chr2Length","nBins1","nBins2","currentBrowser","browsers","synchableBrowsers","b1","b2","showLocusGoto","showHicContactMapLabel","showChromosomeSelector","browserJson","captionDiv","captionText","restoreSession","deleteAllBrowsers","hicContainer","initPromises","StringUtils.isString","syncDatasets","createBrowserList","urlShortcuts","extractConfig","queryString","sessionConfig","BGZip.uncompressString","bitlink_id","longUrl","long_url","expandURL","qObj","decodeQuery","queryConfig","fixDefaults","browserConfig","uriDecode","hicUrl","trackString","paramDecode","trackStringList","dataRangeString","destringifyTracksV0","replacement","BGZip.compressString","getCurrentBrowser"],"mappings":"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,KAAOA,CAEf,EACIkX,GAAU,GAMVC,GAAQ,IAAIjI,YAAY,CAC1B,EACA,EACA,EACA,EACA,EACA,EACA,EACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,IACA,IACA,IACA,IACA,IACA,IACA,EACA,IAEEkI,GAAO,IAAIpa,WAAW,CACxB,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,KAEEqa,GAAQ,IAAInI,YAAY,CAC1B,EACA,EACA,EACA,EACA,EACA,EACA,EACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,IACA,IACA,IACA,IACA,IACA,IACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,MACA,MACA,MACA,EACA,IAEEoI,GAAO,IAAIta,WAAW,CACxB,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,KAsKEua,GApKgB,CAACC,EAAMC,EAAMC,EAAYC,EAAO3R,EAAO4R,EAAaC,EAAMC,KAC5E,MAAM9X,EAAO8X,EAAK9X,KAClB,IASI+X,EACAC,EACAC,EACAC,EACAhI,EAGA7J,EAhBA5J,EAAM,EACN0b,EAAM,EACNC,EAAM,EAAG9E,EAAM,EACf+E,EAAO,EACPC,EAAO,EACPC,EAAO,EACPpL,EAAO,EACPI,EAAO,EACPiL,EAAO,EAMPrW,EAAO,KACP6uM,EAAa,EAEjB,MAAMnuM,EAAQ,IAAIqM,YAAYgI,IACxBuB,EAAO,IAAIvJ,YAAYgI,IAC7B,IAEIwB,EAAWC,EAASC,EAFpBjX,EAAQ,KACRsvM,EAAc,EAElB,IAAKx0M,EAAM,EAAGA,GAAOya,GAASza,IAC5BoG,EAAMpG,GAA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AY,UAAY,WAAY,WAAY,WAC5D,UAAY,WAAY,WAAY,WAAY,UAAY,WAC5D,WAAY,WAAY,UAAY,WAAY,WAAY,WAC5D,WAAY,WAAY,WAAY,WAAY,UAAY,WAC5D,WAAY,WAAY,UAAY,WAAY,WAAY,WAC5D,UAAY,WAAY,WAAY,WAAY,UAAY,WAC5D,WAAY,WAAY,UAAY,WAAY,WAAY,WAC5D,UAAY,WAAY,WAAY,WAAY,WAAY,SAC5D,WAAY,WAAY,WAAY,UAAY,WAAY,WAC5D,WAAY,UAAY,WAAY,WAAY,WAAY,UAC5D,WAAY,WAAY,WAAY,UAAY,WAAY,WAC5D,WAAY,UAAY,WAAY,WAAY,WAAY,UAC5D,WAAY,WAAY,WAAY,UAAY,WAAY,WAC5D,WAAY,UAAY,WAAY,WAAY,WAAY,WAC5D,WAAY,WAAY,WAAY,UAAY,WAAY,WAC5D,WAAY,UAAY,WAAY,WAAY,WAAY,UAC5D,WAAY,WAAY,WAAY,UAAY,WAAY,WAC5D,WAAY,UAAY,WAAY,WAAY,WAAY,UAC5D,WAAY,WAAY,WAAY,WAAY,SAAY,WAC5D,WAAY,WAAY,SAAY,WAAY,WAAY,WAC5D,UAAY,WAAY,WAAY,WAAY,UAAY,WAC5D,WAAY,WAAY,UAAY,WAAY,WAAY,WAC5D,UAAY,WAAY,WAAY,WAAY,UAAY,WAC5D,WAAY,WAAY,UAAY,WAAY,WAAY,WAC5D,UAAY,WAAY,WAAY,WAAY,WAAY,WAC5D,WAAY,WAAY,UAAY,WAAY,WAAY,WAC5D,UAAY,WAAY,WAAY,WAAY,UAAY,WAC5D,WAAY,WAAY,UAAY,WAAY,WAAY,WAC5D,UAAY,WAAY,WAAY,WAAY,UAAY,WAC5D,WAAY,WAAY,WAAY,SAAY,WAAY,WAC5D,WAAY,SAAY,WAAY,WAAY,WAAY,UAC5D,WAAY,WAAY,WAAY,UAAY,WAAY,WAC5D,WAAY,UAAY,WAAY,WAAY,WAAY,UAC5D,WAAY,WAAY,WAAY,UAAY,WAAY,WAC5D,WAAY,UAAY,WAAY,WAAY,WAAY,UAC5D,WAAY,WAAY,WAAY,WAAY,WAAY,WAC5D,WAAY,SAAY,WAAY,WAAY,WAAY,UAC5D,WAAY,WAAY,WAAY,UAAY,WAAY,WAC5D,WAAY,UAAY,WAAY,WAAY,WAAY,UAC5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BAC3D,0DAA2D,iBAC3D,0DAA2D,iBAC3D,0DAA2D,iBAC3D,0DAA2D,iBAC3D,0DAA2D,iBAC3D,0DAA2D,iBAC3D,0DAA2D,iBAC3D,0DAA2D,iBAC3D,0DAA2D,iBAC3D,0DAA2D,iBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,iBAC3D,0DAA2D,kBAC3D,0DAA2D,iBAC3D,0DAA2D,iBAC3D,0DAA2D,iBAC3D,0DAA2D,iBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,iBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,iBAC3D,0DAA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oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,mBAClF,iFAAkF,oBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,kBAClF,iFAAkF,kBAClF,iFAAkF,kBAClF,iFAAkF,kBAClF,iFAAkF,kBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,mBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,kBAClF,iFAAkF,mBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,mBAClF,iFAAkF,oBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,mBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,kBAClF,iFAAkF,mBAClF,iFAAkF,kBAClF,iFAAkF,mBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,mBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,kBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,mBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,mBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,oBAClI,iIAAkI,mBAClI,iIAAkI,oBAClI,iIAAkI,oBAClI,iIAAkI,oBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,mBAClI,iIAAkI,kBAClI,iIAAkI,mBAClI,iIAAkI,kBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,oBAClI,iIAAkI,oBAClI,iIAAkI,oBAClI,iIAAkI,oBAClI,iIAAkI,kBAClI,iIAAkI,mBAClI,iIAAkI,kBAClI,iIAAkI,mBAClI,iIAAkI,kBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,kBAClI,iIAAkI,mBAClI,iIAAkI,oBAClI,iIAAkI,oBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,kBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,mBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,mBAClI,iIAAkI,kBAClI,iIAAkI,mBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,mBAClI,iIAAkI,oBAClI,iIAAkI,oBAClI,iIAAkI,oBAClI,iIAAkI,oBAClI,iIAAkI,oBAClI,iIAAkI,oBAClI,iIAAkI,oBAClI,iIAAkI,oBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,oBAClI,iIAAkI,oBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,kBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,kBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,oBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,kBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,mBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,kBAClI,iIAAkI,mBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,iBAClI,iIAAkI,iBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,kBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,oBAClI,iIAAkI,oBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,oBAClI,iIAAkI,mBAClI,iIAAkI,oBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,oBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,oBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,kBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,iBAClI,iIAAkI,iBAClI,iIAAkI,iBAClI,iIAAkI,iBAClI,iIAAkI,iBAClI,iIAAkI,iBAClI,iIAAkI,mBAClI,iIAAkI,iBAClI,iIAAkI,iBAClI,iIAAkI,iBAClI,iIAAkI,iBAClI,iIAAkI,kBAClI,iIA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oFAAqF,mBACrF,oFAAqF,mBACrF,oFAAqF,kBACrF,oFAAqF,kBACrF,oFAAqF,mBACrF,qFAAsF,mBACtF,qFAAsF,kBACtF,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,iBAC3D,0DAA2D,iBAC3D,0DAA2D,iBAC3D,0DAA2D,iBAC3D,0DAA2D,iBAC3D,0DAA2D,iBAC3D,0DAA2D,iBAC3D,0DAA2D,iBAC3D,0DAA2D,iBAC3D,0DAA2D,iBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,iBAC3D,0DAA2D,kBAC3D,0DAA2D,iBAC3D,0DAA2D,iBAC3D,0DAA2D,iBAC3D,0DAA2D,iBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,kBAC3D,0DAA2D,iBAC3D,0DAA2D,kBAC3D,0DAA2D,kBA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,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,mBAClF,iFAAkF,oBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,kBAClF,iFAAkF,kBAClF,iFAAkF,kBAClF,iFAAkF,kBAClF,iFAAkF,kBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,mBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,kBAClF,iFAAkF,mBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,mBAClF,iFAAkF,oBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,mBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,kBAClF,iFAAkF,mBAClF,iFAAkF,kBAClF,iFAAkF,mBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,mBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,kBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,mBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,mBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,mBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iFAAkF,oBAClF,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,oBAClI,iIAAkI,mBAClI,iIAAkI,oBAClI,iIAAkI,oBAClI,iIAAkI,oBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,mBAClI,iIAAkI,kBAClI,iIAAkI,mBAClI,iIAAkI,kBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,oBAClI,iIAAkI,oBAClI,iIAAkI,oBAClI,iIAAkI,oBAClI,iIAAkI,kBAClI,iIAAkI,mBAClI,iIAAkI,kBAClI,iIAAkI,mBAClI,iIAAkI,kBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,kBAClI,iIAAkI,mBAClI,iIAAkI,oBAClI,iIAAkI,oBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,kBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,mBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,mBAClI,iIAAkI,kBAClI,iIAAkI,mBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,mBAClI,iIAAkI,oBAClI,iIAAkI,oBAClI,iIAAkI,oBAClI,iIAAkI,oBAClI,iIAAkI,oBAClI,iIAAkI,oBAClI,iIAAkI,oBAClI,iIAAkI,oBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,oBAClI,iIAAkI,oBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,kBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,kBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,oBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,kBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,mBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,kBAClI,iIAAkI,mBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,kBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,iBAClI,iIAAkI,iBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,kBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,oBAClI,iIAAkI,oBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,oBAClI,iIAAkI,mBAClI,iIAAkI,oBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,oBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,oBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,kBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,mBAClI,iIAAkI,iB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"} \ No newline at end of file diff --git a/examples/juicebox-api.html b/examples/juicebox-api.html index fa678787..dd11dcb8 100644 --- a/examples/juicebox-api.html +++ b/examples/juicebox-api.html @@ -9,10 +9,11 @@ - + + - + @@ -48,6 +49,8 @@

Step 2: Select a track